2 * Speech API (SAPI) token implementation.
4 * Copyright (C) 2017 Huw Davies
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
31 #include "wine/debug.h"
33 #include "sapi_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(sapi
);
39 ISpRegDataKey ISpRegDataKey_iface
;
46 static struct data_key
*impl_from_ISpRegDataKey( ISpRegDataKey
*iface
)
48 return CONTAINING_RECORD( iface
, struct data_key
, ISpRegDataKey_iface
);
53 ISpObjectToken ISpObjectToken_iface
;
60 static struct object_token
*impl_from_ISpObjectToken( ISpObjectToken
*iface
)
62 return CONTAINING_RECORD( iface
, struct object_token
, ISpObjectToken_iface
);
65 static HRESULT WINAPI
data_key_QueryInterface( ISpRegDataKey
*iface
, REFIID iid
, void **obj
)
67 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
69 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
71 if (IsEqualIID( iid
, &IID_IUnknown
) ||
72 IsEqualIID( iid
, &IID_ISpDataKey
) ||
73 IsEqualIID( iid
, &IID_ISpRegDataKey
))
75 ISpRegDataKey_AddRef( iface
);
80 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
85 static ULONG WINAPI
data_key_AddRef( ISpRegDataKey
*iface
)
87 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
88 ULONG ref
= InterlockedIncrement( &This
->ref
);
90 TRACE( "(%p) ref = %lu\n", This
, ref
);
94 static ULONG WINAPI
data_key_Release( ISpRegDataKey
*iface
)
96 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
97 ULONG ref
= InterlockedDecrement(&This
->ref
);
99 TRACE( "(%p) ref = %lu\n", This
, ref
);
103 if (This
->key
) RegCloseKey( This
->key
);
110 static HRESULT WINAPI
data_key_SetData( ISpRegDataKey
*iface
, LPCWSTR name
,
111 ULONG size
, const BYTE
*data
)
117 static HRESULT WINAPI
data_key_GetData( ISpRegDataKey
*iface
, LPCWSTR name
,
118 ULONG
*size
, BYTE
*data
)
124 static HRESULT WINAPI
data_key_SetStringValue( ISpRegDataKey
*iface
,
125 LPCWSTR name
, LPCWSTR value
)
131 static HRESULT WINAPI
data_key_GetStringValue( ISpRegDataKey
*iface
,
132 LPCWSTR name
, LPWSTR
*value
)
134 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
138 TRACE( "%p, %s, %p\n", This
, debugstr_w(name
), value
);
144 ret
= RegGetValueW( This
->key
, NULL
, name
, RRF_RT_REG_SZ
, NULL
, NULL
, &size
);
145 if (ret
!= ERROR_SUCCESS
)
146 return SPERR_NOT_FOUND
;
148 content
= CoTaskMemAlloc(size
);
150 return E_OUTOFMEMORY
;
152 ret
= RegGetValueW( This
->key
, NULL
, name
, RRF_RT_REG_SZ
, NULL
, content
, &size
);
153 if (ret
!= ERROR_SUCCESS
)
155 CoTaskMemFree(content
);
156 return HRESULT_FROM_WIN32(ret
);
163 static HRESULT WINAPI
data_key_SetDWORD( ISpRegDataKey
*iface
,
164 LPCWSTR name
, DWORD value
)
170 static HRESULT WINAPI
data_key_GetDWORD( ISpRegDataKey
*iface
,
171 LPCWSTR name
, DWORD
*pdwValue
)
177 static HRESULT WINAPI
data_key_OpenKey( ISpRegDataKey
*iface
,
178 LPCWSTR name
, ISpDataKey
**sub_key
)
184 static HRESULT WINAPI
data_key_CreateKey( ISpRegDataKey
*iface
,
185 LPCWSTR name
, ISpDataKey
**sub_key
)
187 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
188 ISpRegDataKey
*spregkey
;
193 TRACE( "%p, %s, %p\n", This
, debugstr_w(name
), sub_key
);
195 res
= RegCreateKeyExW( This
->key
, name
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
196 if (res
!= ERROR_SUCCESS
)
197 return HRESULT_FROM_WIN32(res
);
199 hr
= data_key_create(NULL
, &IID_ISpRegDataKey
, (void**)&spregkey
);
202 hr
= ISpRegDataKey_SetKey(spregkey
, key
, FALSE
);
204 hr
= ISpRegDataKey_QueryInterface(spregkey
, &IID_ISpDataKey
, (void**)sub_key
);
205 ISpRegDataKey_Release(spregkey
);
211 static HRESULT WINAPI
data_key_DeleteKey( ISpRegDataKey
*iface
, LPCWSTR name
)
217 static HRESULT WINAPI
data_key_DeleteValue( ISpRegDataKey
*iface
, LPCWSTR name
)
223 static HRESULT WINAPI
data_key_EnumKeys( ISpRegDataKey
*iface
,
224 ULONG index
, LPWSTR
*sub_key
)
230 static HRESULT WINAPI
data_key_EnumValues( ISpRegDataKey
*iface
,
231 ULONG index
, LPWSTR
*value
)
237 static HRESULT WINAPI
data_key_SetKey( ISpRegDataKey
*iface
,
238 HKEY key
, BOOL read_only
)
240 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
242 TRACE( "(%p)->(%p %d)\n", This
, key
, read_only
);
244 if (This
->key
) return SPERR_ALREADY_INITIALIZED
;
247 This
->read_only
= read_only
;
251 const struct ISpRegDataKeyVtbl data_key_vtbl
=
253 data_key_QueryInterface
,
258 data_key_SetStringValue
,
259 data_key_GetStringValue
,
265 data_key_DeleteValue
,
271 HRESULT
data_key_create( IUnknown
*outer
, REFIID iid
, void **obj
)
273 struct data_key
*This
= heap_alloc( sizeof(*This
) );
276 if (!This
) return E_OUTOFMEMORY
;
277 This
->ISpRegDataKey_iface
.lpVtbl
= &data_key_vtbl
;
280 This
->read_only
= FALSE
;
282 hr
= ISpRegDataKey_QueryInterface( &This
->ISpRegDataKey_iface
, iid
, obj
);
284 ISpRegDataKey_Release( &This
->ISpRegDataKey_iface
);
288 struct token_category
290 ISpObjectTokenCategory ISpObjectTokenCategory_iface
;
293 ISpRegDataKey
*data_key
;
296 static struct token_category
*impl_from_ISpObjectTokenCategory( ISpObjectTokenCategory
*iface
)
298 return CONTAINING_RECORD( iface
, struct token_category
, ISpObjectTokenCategory_iface
);
301 static HRESULT WINAPI
token_category_QueryInterface( ISpObjectTokenCategory
*iface
,
302 REFIID iid
, void **obj
)
304 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
306 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
308 if (IsEqualIID( iid
, &IID_IUnknown
) ||
309 IsEqualIID( iid
, &IID_ISpDataKey
) ||
310 IsEqualIID( iid
, &IID_ISpObjectTokenCategory
))
312 ISpObjectTokenCategory_AddRef( iface
);
317 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
319 return E_NOINTERFACE
;
322 static ULONG WINAPI
token_category_AddRef( ISpObjectTokenCategory
*iface
)
324 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
325 ULONG ref
= InterlockedIncrement( &This
->ref
);
327 TRACE( "(%p) ref = %lu\n", This
, ref
);
331 static ULONG WINAPI
token_category_Release( ISpObjectTokenCategory
*iface
)
333 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
334 ULONG ref
= InterlockedDecrement(&This
->ref
);
336 TRACE( "(%p) ref = %lu\n", This
, ref
);
340 if (This
->data_key
) ISpRegDataKey_Release( This
->data_key
);
346 static HRESULT WINAPI
token_category_SetData( ISpObjectTokenCategory
*iface
,
347 LPCWSTR name
, ULONG size
,
354 static HRESULT WINAPI
token_category_GetData( ISpObjectTokenCategory
*iface
,
355 LPCWSTR name
, ULONG
*size
,
362 static HRESULT WINAPI
token_category_SetStringValue( ISpObjectTokenCategory
*iface
,
363 LPCWSTR name
, LPCWSTR value
)
369 static HRESULT WINAPI
token_category_GetStringValue( ISpObjectTokenCategory
*iface
,
370 LPCWSTR name
, LPWSTR
*value
)
376 static HRESULT WINAPI
token_category_SetDWORD( ISpObjectTokenCategory
*iface
,
377 LPCWSTR name
, DWORD value
)
383 static HRESULT WINAPI
token_category_GetDWORD( ISpObjectTokenCategory
*iface
,
384 LPCWSTR name
, DWORD
*pdwValue
)
390 static HRESULT WINAPI
token_category_OpenKey( ISpObjectTokenCategory
*iface
,
391 LPCWSTR name
, ISpDataKey
**sub_key
)
397 static HRESULT WINAPI
token_category_CreateKey( ISpObjectTokenCategory
*iface
,
398 LPCWSTR name
, ISpDataKey
**sub_key
)
404 static HRESULT WINAPI
token_category_DeleteKey( ISpObjectTokenCategory
*iface
,
411 static HRESULT WINAPI
token_category_DeleteValue( ISpObjectTokenCategory
*iface
,
418 static HRESULT WINAPI
token_category_EnumKeys( ISpObjectTokenCategory
*iface
,
419 ULONG index
, LPWSTR
*sub_key
)
425 static HRESULT WINAPI
token_category_EnumValues( ISpObjectTokenCategory
*iface
,
426 ULONG index
, LPWSTR
*value
)
432 static HRESULT
parse_cat_id( const WCHAR
*str
, HKEY
*root
, const WCHAR
**sub_key
)
441 #define X(s) s, ARRAY_SIZE(s) - 1
442 { X(L
"HKEY_LOCAL_MACHINE\\"), HKEY_LOCAL_MACHINE
},
443 { X(L
"HKEY_CURRENT_USER\\"), HKEY_CURRENT_USER
},
448 int len
= lstrlenW( str
);
450 for (ptr
= table
; ptr
->name
; ptr
++)
452 if (len
>= ptr
->len
&& !wcsncmp( str
, ptr
->name
, ptr
->len
))
455 *sub_key
= str
+ ptr
->len
;
462 static HRESULT WINAPI
token_category_SetId( ISpObjectTokenCategory
*iface
,
463 LPCWSTR id
, BOOL create
)
465 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
471 TRACE( "(%p)->(%s %d)\n", This
, debugstr_w( id
), create
);
473 if (This
->data_key
) return SPERR_ALREADY_INITIALIZED
;
475 hr
= parse_cat_id( id
, &root
, &subkey
);
476 if (hr
!= S_OK
) return SPERR_INVALID_REGISTRY_KEY
;
479 res
= RegCreateKeyExW( root
, subkey
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
481 res
= RegOpenKeyExW( root
, subkey
, 0, KEY_ALL_ACCESS
, &key
);
482 if (res
) return SPERR_INVALID_REGISTRY_KEY
;
484 hr
= CoCreateInstance( &CLSID_SpDataKey
, NULL
, CLSCTX_ALL
,
485 &IID_ISpRegDataKey
, (void **)&This
->data_key
);
486 if (FAILED(hr
)) goto fail
;
488 hr
= ISpRegDataKey_SetKey( This
->data_key
, key
, FALSE
);
489 if (FAILED(hr
)) goto fail
;
498 static HRESULT WINAPI
token_category_GetId( ISpObjectTokenCategory
*iface
,
505 static HRESULT WINAPI
token_category_GetDataKey( ISpObjectTokenCategory
*iface
,
506 SPDATAKEYLOCATION location
,
507 ISpDataKey
**data_key
)
515 ISpObjectTokenEnumBuilder ISpObjectTokenEnumBuilder_iface
;
525 static struct token_enum
*impl_from_ISpObjectTokenEnumBuilder( ISpObjectTokenEnumBuilder
*iface
)
527 return CONTAINING_RECORD( iface
, struct token_enum
, ISpObjectTokenEnumBuilder_iface
);
530 static HRESULT WINAPI
token_category_EnumTokens( ISpObjectTokenCategory
*iface
,
531 LPCWSTR req
, LPCWSTR opt
,
532 IEnumSpObjectTokens
**enum_tokens
)
534 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
535 ISpObjectTokenEnumBuilder
*builder
;
536 struct token_enum
*tokenenum
;
537 struct data_key
*this_data_key
;
540 TRACE( "(%p)->(%s %s %p)\n", This
, debugstr_w( req
), debugstr_w( opt
), enum_tokens
);
542 if (!This
->data_key
) return SPERR_UNINITIALIZED
;
544 hr
= CoCreateInstance( &CLSID_SpObjectTokenEnum
, NULL
, CLSCTX_ALL
,
545 &IID_ISpObjectTokenEnumBuilder
, (void **)&builder
);
546 if (FAILED(hr
)) return hr
;
548 hr
= ISpObjectTokenEnumBuilder_SetAttribs( builder
, req
, opt
);
549 if (FAILED(hr
)) goto fail
;
551 this_data_key
= impl_from_ISpRegDataKey( This
->data_key
);
553 tokenenum
= impl_from_ISpObjectTokenEnumBuilder( builder
);
555 if (!RegOpenKeyExW( this_data_key
->key
, L
"Tokens", 0, KEY_ALL_ACCESS
, &tokenenum
->key
))
557 RegQueryInfoKeyW(tokenenum
->key
, NULL
, NULL
, NULL
, &tokenenum
->count
, NULL
, NULL
,
558 NULL
, NULL
, NULL
, NULL
, NULL
);
561 hr
= ISpObjectTokenEnumBuilder_QueryInterface( builder
, &IID_IEnumSpObjectTokens
,
562 (void **)enum_tokens
);
565 ISpObjectTokenEnumBuilder_Release( builder
);
569 static HRESULT WINAPI
token_category_SetDefaultTokenId( ISpObjectTokenCategory
*iface
,
576 static HRESULT WINAPI
token_category_GetDefaultTokenId( ISpObjectTokenCategory
*iface
,
579 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
580 struct data_key
*this_data_key
;
583 DWORD regvalue_size
= sizeof( regvalue
);
585 FIXME( "(%p)->(%p): semi-stub\n", iface
, id
);
588 return SPERR_UNINITIALIZED
;
593 /* todo: check HKCU's DefaultTokenId before */
595 this_data_key
= impl_from_ISpRegDataKey( This
->data_key
);
597 res
= RegGetValueW( this_data_key
->key
, NULL
, L
"DefaultDefaultTokenId", RRF_RT_REG_SZ
,
598 NULL
, ®value
, ®value_size
);
599 if (res
== ERROR_FILE_NOT_FOUND
) {
600 return SPERR_NOT_FOUND
;
601 } else if (res
!= ERROR_SUCCESS
) {
602 /* probably not the correct return value */
603 FIXME( "returning %08lx\n", res
);
607 *id
= CoTaskMemAlloc( regvalue_size
);
608 wcscpy( *id
, regvalue
);
613 const struct ISpObjectTokenCategoryVtbl token_category_vtbl
=
615 token_category_QueryInterface
,
616 token_category_AddRef
,
617 token_category_Release
,
618 token_category_SetData
,
619 token_category_GetData
,
620 token_category_SetStringValue
,
621 token_category_GetStringValue
,
622 token_category_SetDWORD
,
623 token_category_GetDWORD
,
624 token_category_OpenKey
,
625 token_category_CreateKey
,
626 token_category_DeleteKey
,
627 token_category_DeleteValue
,
628 token_category_EnumKeys
,
629 token_category_EnumValues
,
630 token_category_SetId
,
631 token_category_GetId
,
632 token_category_GetDataKey
,
633 token_category_EnumTokens
,
634 token_category_SetDefaultTokenId
,
635 token_category_GetDefaultTokenId
,
638 HRESULT
token_category_create( IUnknown
*outer
, REFIID iid
, void **obj
)
640 struct token_category
*This
= heap_alloc( sizeof(*This
) );
643 if (!This
) return E_OUTOFMEMORY
;
644 This
->ISpObjectTokenCategory_iface
.lpVtbl
= &token_category_vtbl
;
646 This
->data_key
= NULL
;
648 hr
= ISpObjectTokenCategory_QueryInterface( &This
->ISpObjectTokenCategory_iface
, iid
, obj
);
650 ISpObjectTokenCategory_Release( &This
->ISpObjectTokenCategory_iface
);
654 static HRESULT WINAPI
token_enum_QueryInterface( ISpObjectTokenEnumBuilder
*iface
,
655 REFIID iid
, void **obj
)
657 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
659 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
661 if (IsEqualIID( iid
, &IID_IUnknown
) ||
662 IsEqualIID( iid
, &IID_IEnumSpObjectTokens
) ||
663 IsEqualIID( iid
, &IID_ISpObjectTokenEnumBuilder
))
665 ISpObjectTokenEnumBuilder_AddRef( iface
);
670 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
672 return E_NOINTERFACE
;
675 static ULONG WINAPI
token_enum_AddRef( ISpObjectTokenEnumBuilder
*iface
)
677 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
678 ULONG ref
= InterlockedIncrement( &This
->ref
);
680 TRACE( "(%p) ref = %lu\n", This
, ref
);
684 static ULONG WINAPI
token_enum_Release( ISpObjectTokenEnumBuilder
*iface
)
686 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
687 ULONG ref
= InterlockedDecrement(&This
->ref
);
689 TRACE( "(%p) ref = %lu\n", This
, ref
);
694 RegCloseKey(This
->key
);
695 heap_free( This
->req
);
696 heap_free( This
->opt
);
703 static HRESULT WINAPI
token_enum_Next( ISpObjectTokenEnumBuilder
*iface
,
704 ULONG num
, ISpObjectToken
**tokens
,
707 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
708 struct object_token
*object
;
715 TRACE( "(%p)->(%lu %p %p)\n", This
, num
, tokens
, fetched
);
717 if (!This
->init
) return SPERR_UNINITIALIZED
;
718 if (fetched
) *fetched
= 0;
722 RegQueryInfoKeyW( This
->key
, NULL
, NULL
, NULL
, NULL
, &size
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
723 size
= (size
+1) * sizeof(WCHAR
);
724 subkey_name
= heap_alloc(size
);
726 return E_OUTOFMEMORY
;
728 retCode
= RegEnumKeyExW( This
->key
, This
->index
, subkey_name
, &size
, NULL
, NULL
, NULL
, NULL
);
729 if (retCode
!= ERROR_SUCCESS
)
731 heap_free(subkey_name
);
737 if (RegOpenKeyExW( This
->key
, subkey_name
, 0, KEY_READ
, &sub_key
) != ERROR_SUCCESS
)
739 heap_free(subkey_name
);
743 hr
= token_create( NULL
, &IID_ISpObjectToken
, (void**)tokens
);
746 heap_free(subkey_name
);
750 object
= impl_from_ISpObjectToken( *tokens
);
751 object
->token_key
= sub_key
;
752 object
->token_id
= subkey_name
;
754 if (fetched
) *fetched
= 1;
758 static HRESULT WINAPI
token_enum_Skip( ISpObjectTokenEnumBuilder
*iface
,
765 static HRESULT WINAPI
token_enum_Reset( ISpObjectTokenEnumBuilder
*iface
)
771 static HRESULT WINAPI
token_enum_Clone( ISpObjectTokenEnumBuilder
*iface
,
772 IEnumSpObjectTokens
**clone
)
778 static HRESULT WINAPI
token_enum_Item( ISpObjectTokenEnumBuilder
*iface
,
779 ULONG index
, ISpObjectToken
**token
)
781 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
782 struct object_token
*object
;
783 ISpObjectToken
*subtoken
;
790 TRACE( "%p, %lu, %p\n", This
, index
, token
);
793 return SPERR_UNINITIALIZED
;
795 RegQueryInfoKeyW(This
->key
, NULL
, NULL
, NULL
, NULL
, &size
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
796 size
= (size
+1) * sizeof(WCHAR
);
797 subkey
= heap_alloc(size
);
799 return E_OUTOFMEMORY
;
801 ret
= RegEnumKeyExW(This
->key
, index
, subkey
, &size
, NULL
, NULL
, NULL
, NULL
);
802 if (ret
!= ERROR_SUCCESS
)
805 return HRESULT_FROM_WIN32(ret
);
808 ret
= RegOpenKeyExW (This
->key
, subkey
, 0, KEY_READ
, &key
);
809 if (ret
!= ERROR_SUCCESS
)
812 return HRESULT_FROM_WIN32(ret
);
815 hr
= token_create( NULL
, &IID_ISpObjectToken
, (void**)&subtoken
);
822 object
= impl_from_ISpObjectToken( subtoken
);
823 object
->token_key
= key
;
824 object
->token_id
= subkey
;
831 static HRESULT WINAPI
token_enum_GetCount( ISpObjectTokenEnumBuilder
*iface
,
834 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
836 TRACE( "(%p)->(%p)\n", This
, count
);
838 if (!This
->init
) return SPERR_UNINITIALIZED
;
840 *count
= This
->count
;
844 static HRESULT WINAPI
token_enum_SetAttribs( ISpObjectTokenEnumBuilder
*iface
,
845 LPCWSTR req
, LPCWSTR opt
)
847 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
849 TRACE( "(%p)->(%s %s)\n", This
, debugstr_w( req
), debugstr_w( opt
) );
851 if (This
->init
) return SPERR_ALREADY_INITIALIZED
;
855 This
->req
= heap_strdupW( req
);
856 if (!This
->req
) goto out_of_mem
;
861 This
->opt
= heap_strdupW( opt
);
862 if (!This
->opt
) goto out_of_mem
;
869 heap_free( This
->req
);
870 return E_OUTOFMEMORY
;
873 static HRESULT WINAPI
token_enum_AddTokens( ISpObjectTokenEnumBuilder
*iface
,
874 ULONG num
, ISpObjectToken
**tokens
)
880 static HRESULT WINAPI
token_enum_AddTokensFromDataKey( ISpObjectTokenEnumBuilder
*iface
,
881 ISpDataKey
*data_key
,
882 LPCWSTR sub_key
, LPCWSTR cat_id
)
888 static HRESULT WINAPI
token_enum_AddTokensFromTokenEnum( ISpObjectTokenEnumBuilder
*iface
,
889 IEnumSpObjectTokens
*token_enum
)
895 static HRESULT WINAPI
token_enum_Sort( ISpObjectTokenEnumBuilder
*iface
,
902 const struct ISpObjectTokenEnumBuilderVtbl token_enum_vtbl
=
904 token_enum_QueryInterface
,
913 token_enum_SetAttribs
,
914 token_enum_AddTokens
,
915 token_enum_AddTokensFromDataKey
,
916 token_enum_AddTokensFromTokenEnum
,
920 HRESULT
token_enum_create( IUnknown
*outer
, REFIID iid
, void **obj
)
922 struct token_enum
*This
= heap_alloc( sizeof(*This
) );
925 if (!This
) return E_OUTOFMEMORY
;
926 This
->ISpObjectTokenEnumBuilder_iface
.lpVtbl
= &token_enum_vtbl
;
935 hr
= ISpObjectTokenEnumBuilder_QueryInterface( &This
->ISpObjectTokenEnumBuilder_iface
, iid
, obj
);
937 ISpObjectTokenEnumBuilder_Release( &This
->ISpObjectTokenEnumBuilder_iface
);
941 static HRESULT WINAPI
token_QueryInterface( ISpObjectToken
*iface
,
942 REFIID iid
, void **obj
)
944 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
946 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
948 if (IsEqualIID( iid
, &IID_IUnknown
) ||
949 IsEqualIID( iid
, &IID_ISpDataKey
) ||
950 IsEqualIID( iid
, &IID_ISpObjectToken
))
952 ISpObjectToken_AddRef( iface
);
957 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
959 return E_NOINTERFACE
;
962 static ULONG WINAPI
token_AddRef( ISpObjectToken
*iface
)
964 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
965 ULONG ref
= InterlockedIncrement( &This
->ref
);
967 TRACE( "(%p) ref = %lu\n", This
, ref
);
971 static ULONG WINAPI
token_Release( ISpObjectToken
*iface
)
973 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
974 ULONG ref
= InterlockedDecrement(&This
->ref
);
976 TRACE( "(%p) ref = %lu\n", This
, ref
);
980 if (This
->token_key
) RegCloseKey( This
->token_key
);
981 free(This
->token_id
);
988 static HRESULT WINAPI
token_SetData( ISpObjectToken
*iface
,
989 LPCWSTR name
, ULONG size
,
996 static HRESULT WINAPI
token_GetData( ISpObjectToken
*iface
,
997 LPCWSTR name
, ULONG
*size
,
1004 static HRESULT WINAPI
token_SetStringValue( ISpObjectToken
*iface
,
1005 LPCWSTR name
, LPCWSTR value
)
1011 static HRESULT WINAPI
token_GetStringValue( ISpObjectToken
*iface
,
1012 LPCWSTR name
, LPWSTR
*value
)
1018 static HRESULT WINAPI
token_SetDWORD( ISpObjectToken
*iface
,
1019 LPCWSTR name
, DWORD value
)
1025 static HRESULT WINAPI
token_GetDWORD( ISpObjectToken
*iface
,
1026 LPCWSTR name
, DWORD
*pdwValue
)
1032 static HRESULT WINAPI
token_OpenKey( ISpObjectToken
*iface
,
1033 LPCWSTR name
, ISpDataKey
**sub_key
)
1035 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
1036 ISpRegDataKey
*spregkey
;
1041 TRACE( "%p, %s, %p\n", This
, debugstr_w(name
), sub_key
);
1043 ret
= RegOpenKeyExW (This
->token_key
, name
, 0, KEY_ALL_ACCESS
, &key
);
1044 if (ret
!= ERROR_SUCCESS
)
1045 return SPERR_NOT_FOUND
;
1047 hr
= data_key_create(NULL
, &IID_ISpRegDataKey
, (void**)&spregkey
);
1054 hr
= ISpRegDataKey_SetKey(spregkey
, key
, FALSE
);
1058 ISpRegDataKey_Release(spregkey
);
1062 hr
= ISpRegDataKey_QueryInterface(spregkey
, &IID_ISpDataKey
, (void**)sub_key
);
1063 ISpRegDataKey_Release(spregkey
);
1068 static HRESULT WINAPI
token_CreateKey( ISpObjectToken
*iface
,
1069 LPCWSTR name
, ISpDataKey
**sub_key
)
1075 static HRESULT WINAPI
token_DeleteKey( ISpObjectToken
*iface
,
1082 static HRESULT WINAPI
token_DeleteValue( ISpObjectToken
*iface
,
1089 static HRESULT WINAPI
token_EnumKeys( ISpObjectToken
*iface
,
1090 ULONG index
, LPWSTR
*sub_key
)
1096 static HRESULT WINAPI
token_EnumValues( ISpObjectToken
*iface
,
1097 ULONG index
, LPWSTR
*value
)
1103 static HRESULT WINAPI
token_SetId( ISpObjectToken
*iface
,
1104 LPCWSTR category_id
, LPCWSTR token_id
,
1107 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
1111 const WCHAR
*subkey
;
1113 FIXME( "(%p)->(%s %s %d): semi-stub\n", This
, debugstr_w( category_id
),
1114 debugstr_w(token_id
), create
);
1116 if (This
->token_key
) return SPERR_ALREADY_INITIALIZED
;
1118 if (!token_id
) return E_POINTER
;
1120 hr
= parse_cat_id( token_id
, &root
, &subkey
);
1121 if (hr
!= S_OK
) return SPERR_NOT_FOUND
;
1124 res
= RegCreateKeyExW( root
, subkey
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
1126 res
= RegOpenKeyExW( root
, subkey
, 0, KEY_ALL_ACCESS
, &key
);
1127 if (res
) return SPERR_NOT_FOUND
;
1129 This
->token_key
= key
;
1130 This
->token_id
= wcsdup(token_id
);
1135 static HRESULT WINAPI
token_GetId( ISpObjectToken
*iface
,
1138 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
1140 TRACE( "%p, %p\n", This
, token_id
);
1142 if (!This
->token_key
)
1143 return SPERR_UNINITIALIZED
;
1148 if (!This
->token_id
)
1150 FIXME("Loading default category not supported.\n");
1154 *token_id
= CoTaskMemAlloc( (wcslen(This
->token_id
) + 1) * sizeof(WCHAR
));
1156 return E_OUTOFMEMORY
;
1158 wcscpy(*token_id
, This
->token_id
);
1162 static HRESULT WINAPI
token_GetCategory( ISpObjectToken
*iface
,
1163 ISpObjectTokenCategory
**category
)
1169 static HRESULT WINAPI
token_CreateInstance( ISpObjectToken
*iface
,
1171 DWORD class_context
,
1179 static HRESULT WINAPI
token_GetStorageFileName( ISpObjectToken
*iface
,
1190 static HRESULT WINAPI
token_RemoveStorageFileName( ISpObjectToken
*iface
,
1199 static HRESULT WINAPI
token_Remove( ISpObjectToken
*iface
,
1206 static HRESULT WINAPI
token_IsUISupported( ISpObjectToken
*iface
,
1209 ULONG extra_data_size
,
1217 static HRESULT WINAPI
token_DisplayUI( ISpObjectToken
*iface
,
1222 ULONG extra_data_size
,
1229 static HRESULT WINAPI
token_MatchesAttributes( ISpObjectToken
*iface
,
1237 const struct ISpObjectTokenVtbl token_vtbl
=
1239 token_QueryInterface
,
1244 token_SetStringValue
,
1245 token_GetStringValue
,
1257 token_CreateInstance
,
1258 token_GetStorageFileName
,
1259 token_RemoveStorageFileName
,
1261 token_IsUISupported
,
1263 token_MatchesAttributes
1266 HRESULT
token_create( IUnknown
*outer
, REFIID iid
, void **obj
)
1268 struct object_token
*This
= heap_alloc( sizeof(*This
) );
1271 if (!This
) return E_OUTOFMEMORY
;
1272 This
->ISpObjectToken_iface
.lpVtbl
= &token_vtbl
;
1275 This
->token_key
= NULL
;
1276 This
->token_id
= NULL
;
1278 hr
= ISpObjectToken_QueryInterface( &This
->ISpObjectToken_iface
, iid
, obj
);
1280 ISpObjectToken_Release( &This
->ISpObjectToken_iface
);