winemac: Make show_window() and hide_window() tolerate being called when there's...
[wine.git] / dlls / wbemprox / reg.c
blob7544c3c35a8d7e77b72631b2369ea9bc89da1e90
1 /*
2 * StdRegProv implementation
4 * Copyright 2012 Hans Leidekker for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include "config.h"
24 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wbemcli.h"
30 #include "wine/debug.h"
31 #include "wbemprox_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
35 static HRESULT to_bstr_array( BSTR *strings, DWORD count, VARIANT *var )
37 SAFEARRAY *sa;
38 HRESULT hr;
39 LONG i;
41 if (!(sa = SafeArrayCreateVector( VT_BSTR, 0, count ))) return E_OUTOFMEMORY;
42 for (i = 0; i < count; i++)
44 if ((hr = SafeArrayPutElement( sa, &i, strings[i] )) != S_OK)
46 SafeArrayDestroy( sa );
47 return hr;
50 set_variant( VT_BSTR|VT_ARRAY, 0, sa, var );
51 return S_OK;
54 static void free_bstr_array( BSTR *strings, DWORD count )
56 while (count--)
57 SysFreeString( *(strings++) );
60 static HRESULT to_i4_array( DWORD *values, DWORD count, VARIANT *var )
62 SAFEARRAY *sa;
63 HRESULT hr;
64 LONG i;
66 if (!(sa = SafeArrayCreateVector( VT_I4, 0, count ))) return E_OUTOFMEMORY;
67 for (i = 0; i < count; i++)
69 if ((hr = SafeArrayPutElement( sa, &i, &values[i] )) != S_OK)
71 SafeArrayDestroy( sa );
72 return hr;
75 set_variant( VT_I4|VT_ARRAY, 0, sa, var );
76 return S_OK;
79 static HRESULT enum_key( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *retval )
81 HKEY hkey;
82 HRESULT hr = S_OK;
83 WCHAR buf[256];
84 BSTR *strings, *tmp;
85 DWORD count = 2, len = sizeof(buf)/sizeof(buf[0]);
86 LONG res, i = 0;
88 TRACE("%p, %s\n", root, debugstr_w(subkey));
90 if (!(strings = heap_alloc( count * sizeof(BSTR) ))) return E_OUTOFMEMORY;
91 if ((res = RegOpenKeyExW( root, subkey, 0, KEY_ENUMERATE_SUB_KEYS, &hkey )))
93 set_variant( VT_UI4, res, NULL, retval );
94 heap_free( strings );
95 return S_OK;
97 for (;;)
99 if (i >= count)
101 count *= 2;
102 if (!(tmp = heap_realloc( strings, count * sizeof(BSTR) )))
104 RegCloseKey( hkey );
105 return E_OUTOFMEMORY;
107 strings = tmp;
109 if ((res = RegEnumKeyW( hkey, i, buf, len )) == ERROR_NO_MORE_ITEMS)
111 if (i) res = ERROR_SUCCESS;
112 break;
114 if (res) break;
115 if (!(strings[i] = SysAllocString( buf )))
117 for (i--; i >= 0; i--) SysFreeString( strings[i] );
118 hr = ERROR_OUTOFMEMORY;
119 break;
121 i++;
123 if (hr == S_OK && !res)
125 hr = to_bstr_array( strings, i, names );
126 free_bstr_array( strings, i );
128 set_variant( VT_UI4, res, NULL, retval );
129 RegCloseKey( hkey );
130 heap_free( strings );
131 return hr;
134 HRESULT reg_enum_key( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
136 VARIANT defkey, subkey, names, retval;
137 IWbemClassObject *sig, *out_params = NULL;
138 HRESULT hr;
140 TRACE("%p, %p\n", in, out);
142 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
143 if (hr != S_OK) return hr;
144 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
145 if (hr != S_OK) return hr;
147 hr = create_signature( class_stdregprovW, method_enumkeyW, PARAM_OUT, &sig );
148 if (hr != S_OK)
150 VariantClear( &subkey );
151 return hr;
153 if (out)
155 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
156 if (hr != S_OK)
158 VariantClear( &subkey );
159 IWbemClassObject_Release( sig );
160 return hr;
163 VariantInit( &names );
164 hr = enum_key( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &retval );
165 if (hr != S_OK) goto done;
166 if (out_params)
168 if (!V_UI4( &retval ))
170 hr = IWbemClassObject_Put( out_params, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY );
171 if (hr != S_OK) goto done;
173 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
176 done:
177 VariantClear( &names );
178 VariantClear( &subkey );
179 IWbemClassObject_Release( sig );
180 if (hr == S_OK && out)
182 *out = out_params;
183 IWbemClassObject_AddRef( out_params );
185 if (out_params) IWbemClassObject_Release( out_params );
186 return hr;
189 static HRESULT enum_values( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *types, VARIANT *retval )
191 HKEY hkey = NULL;
192 HRESULT hr = S_OK;
193 BSTR *value_names = NULL;
194 DWORD count, buflen, len, *value_types = NULL;
195 LONG res, i = 0;
196 WCHAR *buf = NULL;
198 TRACE("%p, %s\n", root, debugstr_w(subkey));
200 if ((res = RegOpenKeyExW( root, subkey, 0, KEY_QUERY_VALUE, &hkey ))) goto done;
201 if ((res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, NULL, &count, &buflen, NULL, NULL, NULL )))
202 goto done;
204 hr = E_OUTOFMEMORY;
205 if (!(buf = heap_alloc( (buflen + 1) * sizeof(WCHAR) ))) goto done;
206 if (!(value_names = heap_alloc( count * sizeof(BSTR) ))) goto done;
207 if (!(value_types = heap_alloc( count * sizeof(DWORD) ))) goto done;
209 hr = S_OK;
210 for (;;)
212 len = buflen + 1;
213 res = RegEnumValueW( hkey, i, buf, &len, NULL, &value_types[i], NULL, NULL );
214 if (res == ERROR_NO_MORE_ITEMS)
216 if (i) res = ERROR_SUCCESS;
217 break;
219 if (res) break;
220 if (!(value_names[i] = SysAllocString( buf )))
222 for (i--; i >= 0; i--) SysFreeString( value_names[i] );
223 hr = ERROR_OUTOFMEMORY;
224 break;
226 i++;
228 if (hr == S_OK && !res)
230 hr = to_bstr_array( value_names, i, names );
231 free_bstr_array( value_names, i );
232 if (hr == S_OK) hr = to_i4_array( value_types, i, types );
235 done:
236 set_variant( VT_UI4, res, NULL, retval );
237 RegCloseKey( hkey );
238 heap_free( value_names );
239 heap_free( value_types );
240 heap_free( buf );
241 return hr;
244 HRESULT reg_enum_values( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
246 VARIANT defkey, subkey, names, types, retval;
247 IWbemClassObject *sig, *out_params = NULL;
248 HRESULT hr;
250 TRACE("%p, %p\n", in, out);
252 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
253 if (hr != S_OK) return hr;
254 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
255 if (hr != S_OK) return hr;
257 hr = create_signature( class_stdregprovW, method_enumvaluesW, PARAM_OUT, &sig );
258 if (hr != S_OK)
260 VariantClear( &subkey );
261 return hr;
263 if (out)
265 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
266 if (hr != S_OK)
268 VariantClear( &subkey );
269 IWbemClassObject_Release( sig );
270 return hr;
273 VariantInit( &names );
274 VariantInit( &types );
275 hr = enum_values( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &types, &retval );
276 if (hr != S_OK) goto done;
277 if (out_params)
279 if (!V_UI4( &retval ))
281 hr = IWbemClassObject_Put( out_params, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY );
282 if (hr != S_OK) goto done;
283 hr = IWbemClassObject_Put( out_params, param_typesW, 0, &types, CIM_SINT32|CIM_FLAG_ARRAY );
284 if (hr != S_OK) goto done;
286 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
289 done:
290 VariantClear( &types );
291 VariantClear( &names );
292 VariantClear( &subkey );
293 IWbemClassObject_Release( sig );
294 if (hr == S_OK && out)
296 *out = out_params;
297 IWbemClassObject_AddRef( out_params );
299 if (out_params) IWbemClassObject_Release( out_params );
300 return hr;
303 static HRESULT get_stringvalue( HKEY root, const WCHAR *subkey, const WCHAR *name, VARIANT *value, VARIANT *retval )
305 HRESULT hr = S_OK;
306 BSTR str = NULL;
307 DWORD size;
308 LONG res;
310 TRACE("%p, %s, %s\n", root, debugstr_w(subkey), debugstr_w(name));
312 if ((res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, NULL, &size ))) goto done;
313 if (!(str = SysAllocStringLen( NULL, size / sizeof(WCHAR) - 1 )))
315 hr = E_OUTOFMEMORY;
316 goto done;
318 if (!(res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, str, &size )))
319 set_variant( VT_BSTR, 0, str, value );
321 done:
322 set_variant( VT_UI4, res, NULL, retval );
323 if (res) SysFreeString( str );
324 return hr;
327 HRESULT reg_get_stringvalue( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
329 VARIANT defkey, subkey, name, value, retval;
330 IWbemClassObject *sig, *out_params = NULL;
331 HRESULT hr;
333 TRACE("%p, %p\n", in, out);
335 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
336 if (hr != S_OK) return hr;
337 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
338 if (hr != S_OK) return hr;
339 hr = IWbemClassObject_Get( in, param_valuenameW, 0, &name, NULL, NULL );
340 if (hr != S_OK) return hr;
342 hr = create_signature( class_stdregprovW, method_getstringvalueW, PARAM_OUT, &sig );
343 if (hr != S_OK)
345 VariantClear( &name );
346 VariantClear( &subkey );
347 return hr;
349 if (out)
351 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
352 if (hr != S_OK)
354 VariantClear( &name );
355 VariantClear( &subkey );
356 IWbemClassObject_Release( sig );
357 return hr;
360 VariantInit( &value );
361 hr = get_stringvalue( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), V_BSTR(&name), &value, &retval );
362 if (hr != S_OK) goto done;
363 if (out_params)
365 if (!V_UI4( &retval ))
367 hr = IWbemClassObject_Put( out_params, param_valueW, 0, &value, CIM_STRING );
368 if (hr != S_OK) goto done;
370 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
373 done:
374 VariantClear( &name );
375 VariantClear( &subkey );
376 IWbemClassObject_Release( sig );
377 if (hr == S_OK && out)
379 *out = out_params;
380 IWbemClassObject_AddRef( out_params );
382 if (out_params) IWbemClassObject_Release( out_params );
383 return hr;