wbemprox: Implement StdRegProv.CreateKey.
[wine.git] / dlls / wbemprox / reg.c
blobed30d151006b2b0711d61a6d7b0a3ffaee9c059e
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 create_key( HKEY root, const WCHAR *subkey, VARIANT *retval )
81 LONG res;
82 HKEY hkey;
84 TRACE("%p, %s\n", root, debugstr_w(subkey));
86 res = RegCreateKeyExW( root, subkey, 0, NULL, 0, 0, NULL, &hkey, NULL );
87 set_variant( VT_UI4, res, NULL, retval );
88 if (!res)
90 RegCloseKey( hkey );
91 return S_OK;
93 return HRESULT_FROM_WIN32( res );
96 HRESULT reg_create_key( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
98 VARIANT defkey, subkey, retval;
99 IWbemClassObject *sig, *out_params = NULL;
100 HRESULT hr;
102 TRACE("%p, %p\n", in, out);
104 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
105 if (hr != S_OK) return hr;
106 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
107 if (hr != S_OK) return hr;
109 hr = create_signature( class_stdregprovW, method_createkeyW, PARAM_OUT, &sig );
110 if (hr != S_OK)
112 VariantClear( &subkey );
113 return hr;
115 if (out)
117 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
118 if (hr != S_OK)
120 VariantClear( &subkey );
121 IWbemClassObject_Release( sig );
122 return hr;
125 hr = create_key( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &retval );
126 if (hr == S_OK && out_params)
127 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
129 VariantClear( &subkey );
130 IWbemClassObject_Release( sig );
131 if (hr == S_OK && out)
133 *out = out_params;
134 IWbemClassObject_AddRef( out_params );
136 if (out_params) IWbemClassObject_Release( out_params );
137 return hr;
140 static HRESULT enum_key( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *retval )
142 HKEY hkey;
143 HRESULT hr = S_OK;
144 WCHAR buf[256];
145 BSTR *strings, *tmp;
146 DWORD count = 2, len = ARRAY_SIZE( buf );
147 LONG res, i = 0;
149 TRACE("%p, %s\n", root, debugstr_w(subkey));
151 if (!(strings = heap_alloc( count * sizeof(BSTR) ))) return E_OUTOFMEMORY;
152 if ((res = RegOpenKeyExW( root, subkey, 0, KEY_ENUMERATE_SUB_KEYS, &hkey )))
154 set_variant( VT_UI4, res, NULL, retval );
155 heap_free( strings );
156 return S_OK;
158 for (;;)
160 if (i >= count)
162 count *= 2;
163 if (!(tmp = heap_realloc( strings, count * sizeof(BSTR) )))
165 RegCloseKey( hkey );
166 return E_OUTOFMEMORY;
168 strings = tmp;
170 if ((res = RegEnumKeyW( hkey, i, buf, len )) == ERROR_NO_MORE_ITEMS)
172 if (i) res = ERROR_SUCCESS;
173 break;
175 if (res) break;
176 if (!(strings[i] = SysAllocString( buf )))
178 for (i--; i >= 0; i--) SysFreeString( strings[i] );
179 hr = E_OUTOFMEMORY;
180 break;
182 i++;
184 if (hr == S_OK && !res)
186 hr = to_bstr_array( strings, i, names );
187 free_bstr_array( strings, i );
189 set_variant( VT_UI4, res, NULL, retval );
190 RegCloseKey( hkey );
191 heap_free( strings );
192 return hr;
195 HRESULT reg_enum_key( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
197 VARIANT defkey, subkey, names, retval;
198 IWbemClassObject *sig, *out_params = NULL;
199 HRESULT hr;
201 TRACE("%p, %p\n", in, out);
203 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
204 if (hr != S_OK) return hr;
205 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
206 if (hr != S_OK) return hr;
208 hr = create_signature( class_stdregprovW, method_enumkeyW, PARAM_OUT, &sig );
209 if (hr != S_OK)
211 VariantClear( &subkey );
212 return hr;
214 if (out)
216 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
217 if (hr != S_OK)
219 VariantClear( &subkey );
220 IWbemClassObject_Release( sig );
221 return hr;
224 VariantInit( &names );
225 hr = enum_key( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &retval );
226 if (hr != S_OK) goto done;
227 if (out_params)
229 if (!V_UI4( &retval ))
231 hr = IWbemClassObject_Put( out_params, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY );
232 if (hr != S_OK) goto done;
234 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
237 done:
238 VariantClear( &names );
239 VariantClear( &subkey );
240 IWbemClassObject_Release( sig );
241 if (hr == S_OK && out)
243 *out = out_params;
244 IWbemClassObject_AddRef( out_params );
246 if (out_params) IWbemClassObject_Release( out_params );
247 return hr;
250 static HRESULT enum_values( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *types, VARIANT *retval )
252 HKEY hkey = NULL;
253 HRESULT hr = S_OK;
254 BSTR *value_names = NULL;
255 DWORD count, buflen, len, *value_types = NULL;
256 LONG res, i = 0;
257 WCHAR *buf = NULL;
259 TRACE("%p, %s\n", root, debugstr_w(subkey));
261 if ((res = RegOpenKeyExW( root, subkey, 0, KEY_QUERY_VALUE, &hkey ))) goto done;
262 if ((res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, NULL, &count, &buflen, NULL, NULL, NULL )))
263 goto done;
265 hr = E_OUTOFMEMORY;
266 if (!(buf = heap_alloc( (buflen + 1) * sizeof(WCHAR) ))) goto done;
267 if (!(value_names = heap_alloc( count * sizeof(BSTR) ))) goto done;
268 if (!(value_types = heap_alloc( count * sizeof(DWORD) ))) goto done;
270 hr = S_OK;
271 for (;;)
273 len = buflen + 1;
274 res = RegEnumValueW( hkey, i, buf, &len, NULL, &value_types[i], NULL, NULL );
275 if (res == ERROR_NO_MORE_ITEMS)
277 if (i) res = ERROR_SUCCESS;
278 break;
280 if (res) break;
281 if (!(value_names[i] = SysAllocString( buf )))
283 for (i--; i >= 0; i--) SysFreeString( value_names[i] );
284 hr = E_OUTOFMEMORY;
285 break;
287 i++;
289 if (hr == S_OK && !res)
291 hr = to_bstr_array( value_names, i, names );
292 free_bstr_array( value_names, i );
293 if (hr == S_OK) hr = to_i4_array( value_types, i, types );
296 done:
297 set_variant( VT_UI4, res, NULL, retval );
298 RegCloseKey( hkey );
299 heap_free( value_names );
300 heap_free( value_types );
301 heap_free( buf );
302 return hr;
305 HRESULT reg_enum_values( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
307 VARIANT defkey, subkey, names, types, retval;
308 IWbemClassObject *sig, *out_params = NULL;
309 HRESULT hr;
311 TRACE("%p, %p\n", in, out);
313 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
314 if (hr != S_OK) return hr;
315 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
316 if (hr != S_OK) return hr;
318 hr = create_signature( class_stdregprovW, method_enumvaluesW, PARAM_OUT, &sig );
319 if (hr != S_OK)
321 VariantClear( &subkey );
322 return hr;
324 if (out)
326 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
327 if (hr != S_OK)
329 VariantClear( &subkey );
330 IWbemClassObject_Release( sig );
331 return hr;
334 VariantInit( &names );
335 VariantInit( &types );
336 hr = enum_values( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &types, &retval );
337 if (hr != S_OK) goto done;
338 if (out_params)
340 if (!V_UI4( &retval ))
342 hr = IWbemClassObject_Put( out_params, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY );
343 if (hr != S_OK) goto done;
344 hr = IWbemClassObject_Put( out_params, param_typesW, 0, &types, CIM_SINT32|CIM_FLAG_ARRAY );
345 if (hr != S_OK) goto done;
347 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
350 done:
351 VariantClear( &types );
352 VariantClear( &names );
353 VariantClear( &subkey );
354 IWbemClassObject_Release( sig );
355 if (hr == S_OK && out)
357 *out = out_params;
358 IWbemClassObject_AddRef( out_params );
360 if (out_params) IWbemClassObject_Release( out_params );
361 return hr;
364 static HRESULT get_stringvalue( HKEY root, const WCHAR *subkey, const WCHAR *name, VARIANT *value, VARIANT *retval )
366 HRESULT hr = S_OK;
367 BSTR str = NULL;
368 DWORD size;
369 LONG res;
371 TRACE("%p, %s, %s\n", root, debugstr_w(subkey), debugstr_w(name));
373 if ((res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, NULL, &size ))) goto done;
374 if (!(str = SysAllocStringLen( NULL, size / sizeof(WCHAR) - 1 )))
376 hr = E_OUTOFMEMORY;
377 goto done;
379 if (!(res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, str, &size )))
380 set_variant( VT_BSTR, 0, str, value );
382 done:
383 set_variant( VT_UI4, res, NULL, retval );
384 if (res) SysFreeString( str );
385 return hr;
388 HRESULT reg_get_stringvalue( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
390 VARIANT defkey, subkey, name, value, retval;
391 IWbemClassObject *sig, *out_params = NULL;
392 HRESULT hr;
394 TRACE("%p, %p\n", in, out);
396 hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
397 if (hr != S_OK) return hr;
398 hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
399 if (hr != S_OK) return hr;
400 hr = IWbemClassObject_Get( in, param_valuenameW, 0, &name, NULL, NULL );
401 if (hr != S_OK) return hr;
403 hr = create_signature( class_stdregprovW, method_getstringvalueW, PARAM_OUT, &sig );
404 if (hr != S_OK)
406 VariantClear( &name );
407 VariantClear( &subkey );
408 return hr;
410 if (out)
412 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
413 if (hr != S_OK)
415 VariantClear( &name );
416 VariantClear( &subkey );
417 IWbemClassObject_Release( sig );
418 return hr;
421 VariantInit( &value );
422 hr = get_stringvalue( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), V_BSTR(&name), &value, &retval );
423 if (hr != S_OK) goto done;
424 if (out_params)
426 if (!V_UI4( &retval ))
428 hr = IWbemClassObject_Put( out_params, param_valueW, 0, &value, CIM_STRING );
429 if (hr != S_OK) goto done;
431 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
434 done:
435 VariantClear( &name );
436 VariantClear( &subkey );
437 IWbemClassObject_Release( sig );
438 if (hr == S_OK && out)
440 *out = out_params;
441 IWbemClassObject_AddRef( out_params );
443 if (out_params) IWbemClassObject_Release( out_params );
444 return hr;