widl: Use for_each_iface in get_size_procformatstring.
[wine.git] / dlls / webservices / error.c
blob03f71a6489f205ada3ec03c9336162d14815262a
1 /*
2 * Copyright 2015, 2016 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
21 #include "windef.h"
22 #include "winbase.h"
23 #include "winnls.h"
24 #include "webservices.h"
26 #include "wine/debug.h"
27 #include "wine/heap.h"
28 #include "wine/list.h"
29 #include "webservices_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(webservices);
33 static const struct prop_desc error_props[] =
35 { sizeof(ULONG), TRUE }, /* WS_ERROR_PROPERTY_STRING_COUNT */
36 { sizeof(ULONG), FALSE }, /* WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE */
37 { sizeof(LANGID), FALSE } /* WS_ERROR_PROPERTY_LANGID */
40 struct error
42 ULONG magic;
43 CRITICAL_SECTION cs;
44 ULONG prop_count;
45 struct prop prop[ARRAY_SIZE( error_props )];
48 #define ERROR_MAGIC (('E' << 24) | ('R' << 16) | ('R' << 8) | 'O')
50 static struct error *alloc_error(void)
52 static const ULONG count = ARRAY_SIZE( error_props );
53 struct error *ret;
54 ULONG size = sizeof(*ret) + prop_size( error_props, count );
56 if (!(ret = heap_alloc_zero( size ))) return NULL;
58 ret->magic = ERROR_MAGIC;
59 InitializeCriticalSection( &ret->cs );
60 #ifndef __MINGW32__
61 ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": error.cs");
62 #endif
64 prop_init( error_props, count, ret->prop, &ret[1] );
65 ret->prop_count = count;
66 return ret;
69 static void free_error( struct error *error )
71 #ifndef __MINGW32__
72 error->cs.DebugInfo->Spare[0] = 0;
73 #endif
74 DeleteCriticalSection( &error->cs );
75 heap_free( error );
78 /**************************************************************************
79 * WsCreateError [webservices.@]
81 HRESULT WINAPI WsCreateError( const WS_ERROR_PROPERTY *properties, ULONG count, WS_ERROR **handle )
83 struct error *error;
84 LANGID langid = GetUserDefaultUILanguage();
85 HRESULT hr;
86 ULONG i;
88 TRACE( "%p %u %p\n", properties, count, handle );
90 if (!handle) return E_INVALIDARG;
91 if (!(error = alloc_error())) return E_OUTOFMEMORY;
93 prop_set( error->prop, error->prop_count, WS_ERROR_PROPERTY_LANGID, &langid, sizeof(langid) );
94 for (i = 0; i < count; i++)
96 if (properties[i].id == WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE)
98 free_error( error );
99 return E_INVALIDARG;
101 hr = prop_set( error->prop, error->prop_count, properties[i].id, properties[i].value,
102 properties[i].valueSize );
103 if (hr != S_OK)
105 free_error( error );
106 return hr;
110 TRACE( "created %p\n", error );
111 *handle = (WS_ERROR *)error;
112 return S_OK;
115 static void reset_error( struct error *error )
117 ULONG code = 0;
118 /* FIXME: release strings added with WsAddErrorString when it's implemented, reset string count */
119 prop_set( error->prop, error->prop_count, WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE, &code, sizeof(code) );
122 /**************************************************************************
123 * WsFreeError [webservices.@]
125 void WINAPI WsFreeError( WS_ERROR *handle )
127 struct error *error = (struct error *)handle;
129 TRACE( "%p\n", handle );
131 if (!error) return;
133 EnterCriticalSection( &error->cs );
135 if (error->magic != ERROR_MAGIC)
137 LeaveCriticalSection( &error->cs );
138 return;
141 reset_error( error );
142 error->magic = 0;
144 LeaveCriticalSection( &error->cs );
145 free_error( error );
148 /**************************************************************************
149 * WsResetError [webservices.@]
151 HRESULT WINAPI WsResetError( WS_ERROR *handle )
153 struct error *error = (struct error *)handle;
154 HRESULT hr = S_OK;
156 TRACE( "%p\n", handle );
158 if (!error) return E_INVALIDARG;
160 EnterCriticalSection( &error->cs );
162 if (error->magic != ERROR_MAGIC)
164 LeaveCriticalSection( &error->cs );
165 return E_INVALIDARG;
168 reset_error( error );
170 LeaveCriticalSection( &error->cs );
171 TRACE( "returning %08x\n", hr );
172 return hr;
175 /**************************************************************************
176 * WsGetErrorProperty [webservices.@]
178 HRESULT WINAPI WsGetErrorProperty( WS_ERROR *handle, WS_ERROR_PROPERTY_ID id, void *buf,
179 ULONG size )
181 struct error *error = (struct error *)handle;
182 HRESULT hr;
184 TRACE( "%p %u %p %u\n", handle, id, buf, size );
186 if (!error) return E_INVALIDARG;
188 EnterCriticalSection( &error->cs );
190 if (error->magic != ERROR_MAGIC)
192 LeaveCriticalSection( &error->cs );
193 return E_INVALIDARG;
196 hr = prop_get( error->prop, error->prop_count, id, buf, size );
198 LeaveCriticalSection( &error->cs );
199 TRACE( "returning %08x\n", hr );
200 return hr;
203 /**************************************************************************
204 * WsGetErrorString [webservices.@]
206 HRESULT WINAPI WsGetErrorString( WS_ERROR *handle, ULONG index, WS_STRING *str )
208 FIXME( "%p %u %p: stub\n", handle, index, str );
209 return E_NOTIMPL;
212 /**************************************************************************
213 * WsSetErrorProperty [webservices.@]
215 HRESULT WINAPI WsSetErrorProperty( WS_ERROR *handle, WS_ERROR_PROPERTY_ID id, const void *value,
216 ULONG size )
218 struct error *error = (struct error *)handle;
219 HRESULT hr;
221 TRACE( "%p %u %p %u\n", handle, id, value, size );
223 if (!error) return E_INVALIDARG;
225 EnterCriticalSection( &error->cs );
227 if (error->magic != ERROR_MAGIC)
229 LeaveCriticalSection( &error->cs );
230 return E_INVALIDARG;
233 if (id == WS_ERROR_PROPERTY_LANGID) hr = WS_E_INVALID_OPERATION;
234 else hr = prop_set( error->prop, error->prop_count, id, value, size );
236 LeaveCriticalSection( &error->cs );
237 TRACE( "returning %08x\n", hr );
238 return hr;