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
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
)
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
);
49 set_variant( VT_BSTR
|VT_ARRAY
, 0, sa
, var
);
53 static void free_bstr_array( BSTR
*strings
, DWORD count
)
56 SysFreeString( *(strings
++) );
59 static HRESULT
to_i4_array( DWORD
*values
, DWORD count
, VARIANT
*var
)
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
);
74 set_variant( VT_I4
|VT_ARRAY
, 0, sa
, var
);
78 static HRESULT
create_key( HKEY root
, const WCHAR
*subkey
, VARIANT
*retval
)
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
);
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
;
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
);
111 VariantClear( &subkey
);
116 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
119 VariantClear( &subkey
);
120 IWbemClassObject_Release( sig
);
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
)
133 IWbemClassObject_AddRef( out_params
);
135 if (out_params
) IWbemClassObject_Release( out_params
);
139 static HRESULT
enum_key( HKEY root
, const WCHAR
*subkey
, VARIANT
*names
, VARIANT
*retval
)
145 DWORD count
= 2, len
= ARRAY_SIZE( buf
);
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
);
162 if (!(tmp
= heap_realloc( strings
, count
* sizeof(BSTR
) )))
165 return E_OUTOFMEMORY
;
169 if ((res
= RegEnumKeyW( hkey
, i
, buf
, len
)) == ERROR_NO_MORE_ITEMS
)
171 if (i
) res
= ERROR_SUCCESS
;
175 if (!(strings
[i
] = SysAllocString( buf
)))
177 for (i
--; i
>= 0; i
--) SysFreeString( strings
[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
);
190 heap_free( strings
);
194 HRESULT
reg_enum_key( IWbemClassObject
*obj
, IWbemClassObject
*in
, IWbemClassObject
**out
)
196 VARIANT defkey
, subkey
, names
, retval
;
197 IWbemClassObject
*sig
, *out_params
= NULL
;
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
);
210 VariantClear( &subkey
);
215 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
218 VariantClear( &subkey
);
219 IWbemClassObject_Release( sig
);
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
;
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
);
237 VariantClear( &names
);
238 VariantClear( &subkey
);
239 IWbemClassObject_Release( sig
);
240 if (hr
== S_OK
&& out
)
243 IWbemClassObject_AddRef( out_params
);
245 if (out_params
) IWbemClassObject_Release( out_params
);
249 static HRESULT
enum_values( HKEY root
, const WCHAR
*subkey
, VARIANT
*names
, VARIANT
*types
, VARIANT
*retval
)
253 BSTR
*value_names
= NULL
;
254 DWORD count
, buflen
, len
, *value_types
= 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
)))
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
;
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
;
280 if (!(value_names
[i
] = SysAllocString( buf
)))
282 for (i
--; i
>= 0; i
--) SysFreeString( value_names
[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
);
296 set_variant( VT_UI4
, res
, NULL
, retval
);
298 heap_free( value_names
);
299 heap_free( value_types
);
304 HRESULT
reg_enum_values( IWbemClassObject
*obj
, IWbemClassObject
*in
, IWbemClassObject
**out
)
306 VARIANT defkey
, subkey
, names
, types
, retval
;
307 IWbemClassObject
*sig
, *out_params
= NULL
;
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
);
320 VariantClear( &subkey
);
325 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
328 VariantClear( &subkey
);
329 IWbemClassObject_Release( sig
);
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
;
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
);
350 VariantClear( &types
);
351 VariantClear( &names
);
352 VariantClear( &subkey
);
353 IWbemClassObject_Release( sig
);
354 if (hr
== S_OK
&& out
)
357 IWbemClassObject_AddRef( out_params
);
359 if (out_params
) IWbemClassObject_Release( out_params
);
363 static HRESULT
get_stringvalue( HKEY root
, const WCHAR
*subkey
, const WCHAR
*name
, VARIANT
*value
, VARIANT
*retval
)
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 )))
378 if (!(res
= RegGetValueW( root
, subkey
, name
, RRF_RT_REG_SZ
, NULL
, str
, &size
)))
379 set_variant( VT_BSTR
, 0, str
, value
);
382 set_variant( VT_UI4
, res
, NULL
, retval
);
383 if (res
) SysFreeString( str
);
387 HRESULT
reg_get_stringvalue( IWbemClassObject
*obj
, IWbemClassObject
*in
, IWbemClassObject
**out
)
389 VARIANT defkey
, subkey
, name
, value
, retval
;
390 IWbemClassObject
*sig
, *out_params
= NULL
;
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
);
405 VariantClear( &name
);
406 VariantClear( &subkey
);
411 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
414 VariantClear( &name
);
415 VariantClear( &subkey
);
416 IWbemClassObject_Release( sig
);
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
;
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
);
434 VariantClear( &name
);
435 VariantClear( &subkey
);
436 IWbemClassObject_Release( sig
);
437 if (hr
== S_OK
&& out
)
440 IWbemClassObject_AddRef( out_params
);
442 if (out_params
) IWbemClassObject_Release( out_params
);