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 unsigned int reg_get_access_mask( IWbemContext
*context
)
82 if (!context
) return 0;
84 V_VT( &value
) = VT_EMPTY
;
85 if (FAILED(IWbemContext_GetValue( context
, L
"__ProviderArchitecture", 0, &value
)))
88 if (FAILED(VariantChangeType( &value
, &value
, 0, VT_I4
)))
90 VariantClear( &value
);
94 if (V_I4( &value
) == 32)
95 return KEY_WOW64_32KEY
;
96 else if (V_I4( &value
) == 64)
97 return KEY_WOW64_64KEY
;
102 static HRESULT
create_key( HKEY root
, const WCHAR
*subkey
, IWbemContext
*context
, VARIANT
*retval
)
107 TRACE("%p, %s\n", root
, debugstr_w(subkey
));
109 res
= RegCreateKeyExW( root
, subkey
, 0, NULL
, 0, reg_get_access_mask( context
), NULL
, &hkey
, NULL
);
110 set_variant( VT_UI4
, res
, NULL
, retval
);
116 return HRESULT_FROM_WIN32( res
);
119 HRESULT
reg_create_key( IWbemClassObject
*obj
, IWbemContext
*context
, IWbemClassObject
*in
, IWbemClassObject
**out
)
121 VARIANT defkey
, subkey
, retval
;
122 IWbemClassObject
*sig
, *out_params
= NULL
;
125 TRACE("%p, %p, %p, %p\n", obj
, context
, in
, out
);
127 hr
= IWbemClassObject_Get( in
, L
"hDefKey", 0, &defkey
, NULL
, NULL
);
128 if (hr
!= S_OK
) return hr
;
129 hr
= IWbemClassObject_Get( in
, L
"sSubKeyName", 0, &subkey
, NULL
, NULL
);
130 if (hr
!= S_OK
) return hr
;
132 hr
= create_signature( L
"StdRegProv", L
"CreateKey", PARAM_OUT
, &sig
);
135 VariantClear( &subkey
);
140 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
143 VariantClear( &subkey
);
144 IWbemClassObject_Release( sig
);
148 hr
= create_key( (HKEY
)(INT_PTR
)V_I4(&defkey
), V_BSTR(&subkey
), context
, &retval
);
149 if (hr
== S_OK
&& out_params
)
150 hr
= IWbemClassObject_Put( out_params
, L
"ReturnValue", 0, &retval
, CIM_UINT32
);
152 VariantClear( &subkey
);
153 IWbemClassObject_Release( sig
);
154 if (hr
== S_OK
&& out
)
157 IWbemClassObject_AddRef( out_params
);
159 if (out_params
) IWbemClassObject_Release( out_params
);
163 static HRESULT
enum_key( HKEY root
, const WCHAR
*subkey
, VARIANT
*names
, IWbemContext
*context
, VARIANT
*retval
)
169 DWORD count
= 2, len
= ARRAY_SIZE( buf
);
172 TRACE("%p, %s\n", root
, debugstr_w(subkey
));
174 if (!(strings
= heap_alloc( count
* sizeof(BSTR
) ))) return E_OUTOFMEMORY
;
175 if ((res
= RegOpenKeyExW( root
, subkey
, 0, KEY_ENUMERATE_SUB_KEYS
| reg_get_access_mask( context
), &hkey
)))
177 set_variant( VT_UI4
, res
, NULL
, retval
);
178 heap_free( strings
);
186 if (!(tmp
= heap_realloc( strings
, count
* sizeof(BSTR
) )))
189 return E_OUTOFMEMORY
;
193 if ((res
= RegEnumKeyW( hkey
, i
, buf
, len
)) == ERROR_NO_MORE_ITEMS
)
195 if (i
) res
= ERROR_SUCCESS
;
199 if (!(strings
[i
] = SysAllocString( buf
)))
201 for (i
--; i
>= 0; i
--) SysFreeString( strings
[i
] );
207 if (hr
== S_OK
&& !res
)
209 hr
= to_bstr_array( strings
, i
, names
);
210 free_bstr_array( strings
, i
);
212 set_variant( VT_UI4
, res
, NULL
, retval
);
214 heap_free( strings
);
218 HRESULT
reg_enum_key( IWbemClassObject
*obj
, IWbemContext
*context
, IWbemClassObject
*in
, IWbemClassObject
**out
)
220 VARIANT defkey
, subkey
, names
, retval
;
221 IWbemClassObject
*sig
, *out_params
= NULL
;
224 TRACE("%p, %p, %p, %p\n", obj
, context
, in
, out
);
226 hr
= IWbemClassObject_Get( in
, L
"hDefKey", 0, &defkey
, NULL
, NULL
);
227 if (hr
!= S_OK
) return hr
;
228 hr
= IWbemClassObject_Get( in
, L
"sSubKeyName", 0, &subkey
, NULL
, NULL
);
229 if (hr
!= S_OK
) return hr
;
231 hr
= create_signature( L
"StdRegProv", L
"EnumKey", PARAM_OUT
, &sig
);
234 VariantClear( &subkey
);
239 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
242 VariantClear( &subkey
);
243 IWbemClassObject_Release( sig
);
247 VariantInit( &names
);
248 hr
= enum_key( (HKEY
)(INT_PTR
)V_I4(&defkey
), V_BSTR(&subkey
), &names
, context
, &retval
);
249 if (hr
!= S_OK
) goto done
;
252 if (!V_UI4( &retval
))
254 hr
= IWbemClassObject_Put( out_params
, L
"sNames", 0, &names
, CIM_STRING
|CIM_FLAG_ARRAY
);
255 if (hr
!= S_OK
) goto done
;
257 hr
= IWbemClassObject_Put( out_params
, L
"ReturnValue", 0, &retval
, CIM_UINT32
);
261 VariantClear( &names
);
262 VariantClear( &subkey
);
263 IWbemClassObject_Release( sig
);
264 if (hr
== S_OK
&& out
)
267 IWbemClassObject_AddRef( out_params
);
269 if (out_params
) IWbemClassObject_Release( out_params
);
273 static HRESULT
enum_values( HKEY root
, const WCHAR
*subkey
, VARIANT
*names
, VARIANT
*types
, IWbemContext
*context
,
278 BSTR
*value_names
= NULL
;
279 DWORD count
, buflen
, len
, *value_types
= NULL
;
283 TRACE("%p, %s\n", root
, debugstr_w(subkey
));
285 if ((res
= RegOpenKeyExW( root
, subkey
, 0, KEY_QUERY_VALUE
| reg_get_access_mask( context
), &hkey
))) goto done
;
286 if ((res
= RegQueryInfoKeyW( hkey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &count
, &buflen
, NULL
, NULL
, NULL
)))
290 if (!(buf
= heap_alloc( (buflen
+ 1) * sizeof(WCHAR
) ))) goto done
;
291 if (!(value_names
= heap_alloc( count
* sizeof(BSTR
) ))) goto done
;
292 if (!(value_types
= heap_alloc( count
* sizeof(DWORD
) ))) goto done
;
298 res
= RegEnumValueW( hkey
, i
, buf
, &len
, NULL
, &value_types
[i
], NULL
, NULL
);
299 if (res
== ERROR_NO_MORE_ITEMS
)
301 if (i
) res
= ERROR_SUCCESS
;
305 if (!(value_names
[i
] = SysAllocString( buf
)))
307 for (i
--; i
>= 0; i
--) SysFreeString( value_names
[i
] );
313 if (hr
== S_OK
&& !res
)
315 hr
= to_bstr_array( value_names
, i
, names
);
316 free_bstr_array( value_names
, i
);
317 if (hr
== S_OK
) hr
= to_i4_array( value_types
, i
, types
);
321 set_variant( VT_UI4
, res
, NULL
, retval
);
323 heap_free( value_names
);
324 heap_free( value_types
);
329 HRESULT
reg_enum_values( IWbemClassObject
*obj
, IWbemContext
*context
, IWbemClassObject
*in
, IWbemClassObject
**out
)
331 VARIANT defkey
, subkey
, names
, types
, retval
;
332 IWbemClassObject
*sig
, *out_params
= NULL
;
335 TRACE("%p, %p, %p, %p\n", obj
, context
, in
, out
);
337 hr
= IWbemClassObject_Get( in
, L
"hDefKey", 0, &defkey
, NULL
, NULL
);
338 if (hr
!= S_OK
) return hr
;
339 hr
= IWbemClassObject_Get( in
, L
"sSubKeyName", 0, &subkey
, NULL
, NULL
);
340 if (hr
!= S_OK
) return hr
;
342 hr
= create_signature( L
"StdRegProv", L
"EnumValues", PARAM_OUT
, &sig
);
345 VariantClear( &subkey
);
350 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
353 VariantClear( &subkey
);
354 IWbemClassObject_Release( sig
);
358 VariantInit( &names
);
359 VariantInit( &types
);
360 hr
= enum_values( (HKEY
)(INT_PTR
)V_I4(&defkey
), V_BSTR(&subkey
), &names
, &types
, context
, &retval
);
361 if (hr
!= S_OK
) goto done
;
364 if (!V_UI4( &retval
))
366 hr
= IWbemClassObject_Put( out_params
, L
"sNames", 0, &names
, CIM_STRING
|CIM_FLAG_ARRAY
);
367 if (hr
!= S_OK
) goto done
;
368 hr
= IWbemClassObject_Put( out_params
, L
"Types", 0, &types
, CIM_SINT32
|CIM_FLAG_ARRAY
);
369 if (hr
!= S_OK
) goto done
;
371 hr
= IWbemClassObject_Put( out_params
, L
"ReturnValue", 0, &retval
, CIM_UINT32
);
375 VariantClear( &types
);
376 VariantClear( &names
);
377 VariantClear( &subkey
);
378 IWbemClassObject_Release( sig
);
379 if (hr
== S_OK
&& out
)
382 IWbemClassObject_AddRef( out_params
);
384 if (out_params
) IWbemClassObject_Release( out_params
);
388 static HRESULT
get_stringvalue( HKEY root
, const WCHAR
*subkey
, const WCHAR
*name
, VARIANT
*value
,
389 IWbemContext
*context
, VARIANT
*retval
)
391 DWORD size
, mask
, flags
= RRF_RT_REG_SZ
;
396 TRACE("%p, %s, %s\n", root
, debugstr_w(subkey
), debugstr_w(name
));
398 mask
= reg_get_access_mask( context
);
400 if (mask
& KEY_WOW64_64KEY
)
401 flags
|= RRF_SUBKEY_WOW6464KEY
;
402 else if (mask
& KEY_WOW64_32KEY
)
403 flags
|= RRF_SUBKEY_WOW6432KEY
;
405 if ((res
= RegGetValueW( root
, subkey
, name
, flags
, NULL
, NULL
, &size
))) goto done
;
406 if (!(str
= SysAllocStringLen( NULL
, size
/ sizeof(WCHAR
) - 1 )))
411 if (!(res
= RegGetValueW( root
, subkey
, name
, flags
, NULL
, str
, &size
)))
412 set_variant( VT_BSTR
, 0, str
, value
);
415 set_variant( VT_UI4
, res
, NULL
, retval
);
416 if (res
) SysFreeString( str
);
420 HRESULT
reg_get_stringvalue( IWbemClassObject
*obj
, IWbemContext
*context
, IWbemClassObject
*in
, IWbemClassObject
**out
)
422 VARIANT defkey
, subkey
, name
, value
, retval
;
423 IWbemClassObject
*sig
, *out_params
= NULL
;
426 TRACE("%p, %p, %p, %p\n", obj
, context
, in
, out
);
428 hr
= IWbemClassObject_Get( in
, L
"hDefKey", 0, &defkey
, NULL
, NULL
);
429 if (hr
!= S_OK
) return hr
;
430 hr
= IWbemClassObject_Get( in
, L
"sSubKeyName", 0, &subkey
, NULL
, NULL
);
431 if (hr
!= S_OK
) return hr
;
432 hr
= IWbemClassObject_Get( in
, L
"sValueName", 0, &name
, NULL
, NULL
);
435 VariantClear( &subkey
);
439 hr
= create_signature( L
"StdRegProv", L
"GetStringValue", PARAM_OUT
, &sig
);
442 VariantClear( &name
);
443 VariantClear( &subkey
);
448 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
451 VariantClear( &name
);
452 VariantClear( &subkey
);
453 IWbemClassObject_Release( sig
);
457 VariantInit( &value
);
458 hr
= get_stringvalue( (HKEY
)(INT_PTR
)V_I4(&defkey
), V_BSTR(&subkey
), V_BSTR(&name
), &value
, context
, &retval
);
459 if (hr
!= S_OK
) goto done
;
462 if (!V_UI4( &retval
))
464 hr
= IWbemClassObject_Put( out_params
, L
"sValue", 0, &value
, CIM_STRING
);
465 if (hr
!= S_OK
) goto done
;
467 hr
= IWbemClassObject_Put( out_params
, L
"ReturnValue", 0, &retval
, CIM_UINT32
);
471 VariantClear( &name
);
472 VariantClear( &subkey
);
473 IWbemClassObject_Release( sig
);
474 if (hr
== S_OK
&& out
)
477 IWbemClassObject_AddRef( out_params
);
479 if (out_params
) IWbemClassObject_Release( out_params
);
483 static void set_stringvalue( HKEY root
, const WCHAR
*subkey
, const WCHAR
*name
, const WCHAR
*value
,
484 IWbemContext
*context
, VARIANT
*retval
)
489 TRACE("%p, %s, %s, %s\n", root
, debugstr_w(subkey
), debugstr_w(name
), debugstr_w(value
));
491 if ((res
= RegOpenKeyExW( root
, subkey
, 0, KEY_SET_VALUE
| reg_get_access_mask( context
), &hkey
)))
493 set_variant( VT_UI4
, res
, NULL
, retval
);
497 res
= RegSetKeyValueW( hkey
, NULL
, name
, REG_SZ
, value
, (lstrlenW( value
) + 1) * sizeof(*value
) );
498 set_variant( VT_UI4
, res
, NULL
, retval
);
502 HRESULT
reg_set_stringvalue( IWbemClassObject
*obj
, IWbemContext
*context
, IWbemClassObject
*in
, IWbemClassObject
**out
)
504 VARIANT defkey
, subkey
, name
, value
, retval
;
505 IWbemClassObject
*sig
, *out_params
= NULL
;
508 TRACE("%p, %p, %p, %p\n", obj
, context
, in
, out
);
510 hr
= IWbemClassObject_Get( in
, L
"hDefKey", 0, &defkey
, NULL
, NULL
);
511 if (hr
!= S_OK
) return hr
;
512 hr
= IWbemClassObject_Get( in
, L
"sSubKeyName", 0, &subkey
, NULL
, NULL
);
513 if (hr
!= S_OK
) return hr
;
514 hr
= IWbemClassObject_Get( in
, L
"sValueName", 0, &name
, NULL
, NULL
);
517 VariantClear( &subkey
);
520 hr
= IWbemClassObject_Get( in
, L
"sValue", 0, &value
, NULL
, NULL
);
523 VariantClear( &name
);
524 VariantClear( &subkey
);
528 hr
= create_signature( L
"StdRegProv", L
"SetStringValue", PARAM_OUT
, &sig
);
531 VariantClear( &name
);
532 VariantClear( &subkey
);
533 VariantClear( &value
);
538 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
541 VariantClear( &name
);
542 VariantClear( &subkey
);
543 VariantClear( &value
);
544 IWbemClassObject_Release( sig
);
549 set_stringvalue( (HKEY
)(INT_PTR
)V_I4(&defkey
), V_BSTR(&subkey
), V_BSTR(&name
), V_BSTR(&value
), context
, &retval
);
551 hr
= IWbemClassObject_Put( out_params
, L
"ReturnValue", 0, &retval
, CIM_UINT32
);
553 VariantClear( &name
);
554 VariantClear( &subkey
);
555 VariantClear( &value
);
556 IWbemClassObject_Release( sig
);
557 if (hr
== S_OK
&& out
)
560 IWbemClassObject_AddRef( out_params
);
562 if (out_params
) IWbemClassObject_Release( out_params
);
566 static void set_dwordvalue( HKEY root
, const WCHAR
*subkey
, const WCHAR
*name
, DWORD value
, IWbemContext
*context
,
572 TRACE("%p, %s, %s, %#x\n", root
, debugstr_w(subkey
), debugstr_w(name
), value
);
574 if ((res
= RegOpenKeyExW( root
, subkey
, 0, KEY_SET_VALUE
| reg_get_access_mask( context
), &hkey
)))
576 set_variant( VT_UI4
, res
, NULL
, retval
);
580 res
= RegSetKeyValueW( hkey
, NULL
, name
, REG_DWORD
, &value
, sizeof(value
) );
581 set_variant( VT_UI4
, res
, NULL
, retval
);
585 HRESULT
reg_set_dwordvalue( IWbemClassObject
*obj
, IWbemContext
*context
, IWbemClassObject
*in
, IWbemClassObject
**out
)
587 VARIANT defkey
, subkey
, name
, value
, retval
;
588 IWbemClassObject
*sig
, *out_params
= NULL
;
591 TRACE("%p, %p, %p, %p\n", obj
, context
, in
, out
);
593 hr
= IWbemClassObject_Get( in
, L
"hDefKey", 0, &defkey
, NULL
, NULL
);
594 if (hr
!= S_OK
) return hr
;
595 hr
= IWbemClassObject_Get( in
, L
"sSubKeyName", 0, &subkey
, NULL
, NULL
);
596 if (hr
!= S_OK
) return hr
;
597 hr
= IWbemClassObject_Get( in
, L
"sValueName", 0, &name
, NULL
, NULL
);
600 VariantClear( &subkey
);
603 hr
= IWbemClassObject_Get( in
, L
"uValue", 0, &value
, NULL
, NULL
);
606 VariantClear( &name
);
607 VariantClear( &subkey
);
611 hr
= create_signature( L
"StdRegProv", L
"SetDWORDValue", PARAM_OUT
, &sig
);
614 VariantClear( &name
);
615 VariantClear( &subkey
);
620 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
623 VariantClear( &name
);
624 VariantClear( &subkey
);
625 IWbemClassObject_Release( sig
);
629 set_dwordvalue( (HKEY
)(INT_PTR
)V_I4(&defkey
), V_BSTR(&subkey
), V_BSTR(&name
), V_UI4(&value
), context
, &retval
);
631 hr
= IWbemClassObject_Put( out_params
, L
"ReturnValue", 0, &retval
, CIM_UINT32
);
633 VariantClear( &name
);
634 VariantClear( &subkey
);
635 IWbemClassObject_Release( sig
);
636 if (hr
== S_OK
&& out
)
639 IWbemClassObject_AddRef( out_params
);
641 if (out_params
) IWbemClassObject_Release( out_params
);
645 static void delete_key( HKEY root
, const WCHAR
*subkey
, IWbemContext
*context
, VARIANT
*retval
)
649 TRACE("%p, %s\n", root
, debugstr_w(subkey
));
651 res
= RegDeleteKeyExW( root
, subkey
, reg_get_access_mask( context
), 0 );
652 set_variant( VT_UI4
, res
, NULL
, retval
);
655 HRESULT
reg_delete_key( IWbemClassObject
*obj
, IWbemContext
*context
, IWbemClassObject
*in
, IWbemClassObject
**out
)
657 VARIANT defkey
, subkey
, retval
;
658 IWbemClassObject
*sig
, *out_params
= NULL
;
661 TRACE("%p, %p, %p, %p\n", obj
, context
, in
, out
);
663 hr
= IWbemClassObject_Get( in
, L
"hDefKey", 0, &defkey
, NULL
, NULL
);
664 if (hr
!= S_OK
) return hr
;
665 hr
= IWbemClassObject_Get( in
, L
"sSubKeyName", 0, &subkey
, NULL
, NULL
);
666 if (hr
!= S_OK
) return hr
;
668 hr
= create_signature( L
"StdRegProv", L
"DeleteKey", PARAM_OUT
, &sig
);
671 VariantClear( &subkey
);
676 hr
= IWbemClassObject_SpawnInstance( sig
, 0, &out_params
);
679 VariantClear( &subkey
);
680 IWbemClassObject_Release( sig
);
684 delete_key( (HKEY
)(INT_PTR
)V_I4(&defkey
), V_BSTR(&subkey
), context
, &retval
);
686 hr
= IWbemClassObject_Put( out_params
, L
"ReturnValue", 0, &retval
, CIM_UINT32
);
688 VariantClear( &subkey
);
689 IWbemClassObject_Release( sig
);
690 if (hr
== S_OK
&& out
)
693 IWbemClassObject_AddRef( out_params
);
695 if (out_params
) IWbemClassObject_Release( out_params
);