vbscript/tests: Add tests for the script TypeInfo's TypeComp binds.
[wine.git] / dlls / wbemprox / reg.c
blob64e94f6e1fc178d5c032ee8374789ea009bdf2e3
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 <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wbemcli.h"
29 #include "wine/debug.h"
30 #include "wbemprox_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
34 static HRESULT to_bstr_array( BSTR *strings, DWORD count, VARIANT *var )
36 SAFEARRAY *sa;
37 HRESULT hr;
38 LONG i;
40 if (!(sa = SafeArrayCreateVector( VT_BSTR, 0, count ))) return E_OUTOFMEMORY;
41 for (i = 0; i < count; i++)
43 if ((hr = SafeArrayPutElement( sa, &i, strings[i] )) != S_OK)
45 SafeArrayDestroy( sa );
46 return hr;
49 set_variant( VT_BSTR|VT_ARRAY, 0, sa, var );
50 return S_OK;
53 static void free_bstr_array( BSTR *strings, DWORD count )
55 while (count--)
56 SysFreeString( *(strings++) );
59 static HRESULT to_i4_array( DWORD *values, DWORD count, VARIANT *var )
61 SAFEARRAY *sa;
62 HRESULT hr;
63 LONG i;
65 if (!(sa = SafeArrayCreateVector( VT_I4, 0, count ))) return E_OUTOFMEMORY;
66 for (i = 0; i < count; i++)
68 if ((hr = SafeArrayPutElement( sa, &i, &values[i] )) != S_OK)
70 SafeArrayDestroy( sa );
71 return hr;
74 set_variant( VT_I4|VT_ARRAY, 0, sa, var );
75 return S_OK;
78 static HRESULT create_key( HKEY root, const WCHAR *subkey, VARIANT *retval )
80 LONG res;
81 HKEY hkey;
83 TRACE("%p, %s\n", root, debugstr_w(subkey));
85 res = RegCreateKeyExW( root, subkey, 0, NULL, 0, 0, NULL, &hkey, NULL );
86 set_variant( VT_UI4, res, NULL, retval );
87 if (!res)
89 RegCloseKey( hkey );
90 return S_OK;
92 return HRESULT_FROM_WIN32( res );
95 HRESULT reg_create_key( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
97 VARIANT defkey, subkey, retval;
98 IWbemClassObject *sig, *out_params = NULL;
99 HRESULT hr;
101 TRACE("%p, %p\n", in, out);
103 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
104 if (hr != S_OK) return hr;
105 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
106 if (hr != S_OK) return hr;
108 hr = create_signature( class_stdregprovW, method_createkeyW, PARAM_OUT, &sig );
109 if (hr != S_OK)
111 VariantClear( &subkey );
112 return hr;
114 if (out)
116 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
117 if (hr != S_OK)
119 VariantClear( &subkey );
120 IWbemClassObject_Release( sig );
121 return hr;
124 hr = create_key( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &retval );
125 if (hr == S_OK && out_params)
126 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
128 VariantClear( &subkey );
129 IWbemClassObject_Release( sig );
130 if (hr == S_OK && out)
132 *out = out_params;
133 IWbemClassObject_AddRef( out_params );
135 if (out_params) IWbemClassObject_Release( out_params );
136 return hr;
139 static HRESULT enum_key( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *retval )
141 HKEY hkey;
142 HRESULT hr = S_OK;
143 WCHAR buf[256];
144 BSTR *strings, *tmp;
145 DWORD count = 2, len = ARRAY_SIZE( buf );
146 LONG res, i = 0;
148 TRACE("%p, %s\n", root, debugstr_w(subkey));
150 if (!(strings = heap_alloc( count * sizeof(BSTR) ))) return E_OUTOFMEMORY;
151 if ((res = RegOpenKeyExW( root, subkey, 0, KEY_ENUMERATE_SUB_KEYS, &hkey )))
153 set_variant( VT_UI4, res, NULL, retval );
154 heap_free( strings );
155 return S_OK;
157 for (;;)
159 if (i >= count)
161 count *= 2;
162 if (!(tmp = heap_realloc( strings, count * sizeof(BSTR) )))
164 RegCloseKey( hkey );
165 return E_OUTOFMEMORY;
167 strings = tmp;
169 if ((res = RegEnumKeyW( hkey, i, buf, len )) == ERROR_NO_MORE_ITEMS)
171 if (i) res = ERROR_SUCCESS;
172 break;
174 if (res) break;
175 if (!(strings[i] = SysAllocString( buf )))
177 for (i--; i >= 0; i--) SysFreeString( strings[i] );
178 hr = E_OUTOFMEMORY;
179 break;
181 i++;
183 if (hr == S_OK && !res)
185 hr = to_bstr_array( strings, i, names );
186 free_bstr_array( strings, i );
188 set_variant( VT_UI4, res, NULL, retval );
189 RegCloseKey( hkey );
190 heap_free( strings );
191 return hr;
194 HRESULT reg_enum_key( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
196 VARIANT defkey, subkey, names, retval;
197 IWbemClassObject *sig, *out_params = NULL;
198 HRESULT hr;
200 TRACE("%p, %p\n", in, out);
202 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
203 if (hr != S_OK) return hr;
204 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
205 if (hr != S_OK) return hr;
207 hr = create_signature( class_stdregprovW, method_enumkeyW, PARAM_OUT, &sig );
208 if (hr != S_OK)
210 VariantClear( &subkey );
211 return hr;
213 if (out)
215 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
216 if (hr != S_OK)
218 VariantClear( &subkey );
219 IWbemClassObject_Release( sig );
220 return hr;
223 VariantInit( &names );
224 hr = enum_key( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &retval );
225 if (hr != S_OK) goto done;
226 if (out_params)
228 if (!V_UI4( &retval ))
230 hr = IWbemClassObject_Put( out_params, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY );
231 if (hr != S_OK) goto done;
233 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
236 done:
237 VariantClear( &names );
238 VariantClear( &subkey );
239 IWbemClassObject_Release( sig );
240 if (hr == S_OK && out)
242 *out = out_params;
243 IWbemClassObject_AddRef( out_params );
245 if (out_params) IWbemClassObject_Release( out_params );
246 return hr;
249 static HRESULT enum_values( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *types, VARIANT *retval )
251 HKEY hkey = NULL;
252 HRESULT hr = S_OK;
253 BSTR *value_names = NULL;
254 DWORD count, buflen, len, *value_types = NULL;
255 LONG res, i = 0;
256 WCHAR *buf = NULL;
258 TRACE("%p, %s\n", root, debugstr_w(subkey));
260 if ((res = RegOpenKeyExW( root, subkey, 0, KEY_QUERY_VALUE, &hkey ))) goto done;
261 if ((res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, NULL, &count, &buflen, NULL, NULL, NULL )))
262 goto done;
264 hr = E_OUTOFMEMORY;
265 if (!(buf = heap_alloc( (buflen + 1) * sizeof(WCHAR) ))) goto done;
266 if (!(value_names = heap_alloc( count * sizeof(BSTR) ))) goto done;
267 if (!(value_types = heap_alloc( count * sizeof(DWORD) ))) goto done;
269 hr = S_OK;
270 for (;;)
272 len = buflen + 1;
273 res = RegEnumValueW( hkey, i, buf, &len, NULL, &value_types[i], NULL, NULL );
274 if (res == ERROR_NO_MORE_ITEMS)
276 if (i) res = ERROR_SUCCESS;
277 break;
279 if (res) break;
280 if (!(value_names[i] = SysAllocString( buf )))
282 for (i--; i >= 0; i--) SysFreeString( value_names[i] );
283 hr = E_OUTOFMEMORY;
284 break;
286 i++;
288 if (hr == S_OK && !res)
290 hr = to_bstr_array( value_names, i, names );
291 free_bstr_array( value_names, i );
292 if (hr == S_OK) hr = to_i4_array( value_types, i, types );
295 done:
296 set_variant( VT_UI4, res, NULL, retval );
297 RegCloseKey( hkey );
298 heap_free( value_names );
299 heap_free( value_types );
300 heap_free( buf );
301 return hr;
304 HRESULT reg_enum_values( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
306 VARIANT defkey, subkey, names, types, retval;
307 IWbemClassObject *sig, *out_params = NULL;
308 HRESULT hr;
310 TRACE("%p, %p\n", in, out);
312 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
313 if (hr != S_OK) return hr;
314 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
315 if (hr != S_OK) return hr;
317 hr = create_signature( class_stdregprovW, method_enumvaluesW, PARAM_OUT, &sig );
318 if (hr != S_OK)
320 VariantClear( &subkey );
321 return hr;
323 if (out)
325 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
326 if (hr != S_OK)
328 VariantClear( &subkey );
329 IWbemClassObject_Release( sig );
330 return hr;
333 VariantInit( &names );
334 VariantInit( &types );
335 hr = enum_values( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &types, &retval );
336 if (hr != S_OK) goto done;
337 if (out_params)
339 if (!V_UI4( &retval ))
341 hr = IWbemClassObject_Put( out_params, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY );
342 if (hr != S_OK) goto done;
343 hr = IWbemClassObject_Put( out_params, param_typesW, 0, &types, CIM_SINT32|CIM_FLAG_ARRAY );
344 if (hr != S_OK) goto done;
346 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
349 done:
350 VariantClear( &types );
351 VariantClear( &names );
352 VariantClear( &subkey );
353 IWbemClassObject_Release( sig );
354 if (hr == S_OK && out)
356 *out = out_params;
357 IWbemClassObject_AddRef( out_params );
359 if (out_params) IWbemClassObject_Release( out_params );
360 return hr;
363 static HRESULT get_stringvalue( HKEY root, const WCHAR *subkey, const WCHAR *name, VARIANT *value, VARIANT *retval )
365 HRESULT hr = S_OK;
366 BSTR str = NULL;
367 DWORD size;
368 LONG res;
370 TRACE("%p, %s, %s\n", root, debugstr_w(subkey), debugstr_w(name));
372 if ((res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, NULL, &size ))) goto done;
373 if (!(str = SysAllocStringLen( NULL, size / sizeof(WCHAR) - 1 )))
375 hr = E_OUTOFMEMORY;
376 goto done;
378 if (!(res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, str, &size )))
379 set_variant( VT_BSTR, 0, str, value );
381 done:
382 set_variant( VT_UI4, res, NULL, retval );
383 if (res) SysFreeString( str );
384 return hr;
387 HRESULT reg_get_stringvalue( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
389 VARIANT defkey, subkey, name, value, retval;
390 IWbemClassObject *sig, *out_params = NULL;
391 HRESULT hr;
393 TRACE("%p, %p\n", in, out);
395 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
396 if (hr != S_OK) return hr;
397 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
398 if (hr != S_OK) return hr;
399 hr = IWbemClassObject_Get( in, param_valuenameW, 0, &name, NULL, NULL );
400 if (hr != S_OK) return hr;
402 hr = create_signature( class_stdregprovW, method_getstringvalueW, PARAM_OUT, &sig );
403 if (hr != S_OK)
405 VariantClear( &name );
406 VariantClear( &subkey );
407 return hr;
409 if (out)
411 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
412 if (hr != S_OK)
414 VariantClear( &name );
415 VariantClear( &subkey );
416 IWbemClassObject_Release( sig );
417 return hr;
420 VariantInit( &value );
421 hr = get_stringvalue( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), V_BSTR(&name), &value, &retval );
422 if (hr != S_OK) goto done;
423 if (out_params)
425 if (!V_UI4( &retval ))
427 hr = IWbemClassObject_Put( out_params, param_valueW, 0, &value, CIM_STRING );
428 if (hr != S_OK) goto done;
430 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
433 done:
434 VariantClear( &name );
435 VariantClear( &subkey );
436 IWbemClassObject_Release( sig );
437 if (hr == S_OK && out)
439 *out = out_params;
440 IWbemClassObject_AddRef( out_params );
442 if (out_params) IWbemClassObject_Release( out_params );
443 return hr;