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
);
51 static HRESULT WINAPI
data_key_QueryInterface( ISpRegDataKey
*iface
, REFIID iid
, void **obj
)
53 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
55 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
57 if (IsEqualIID( iid
, &IID_IUnknown
) ||
58 IsEqualIID( iid
, &IID_ISpDataKey
) ||
59 IsEqualIID( iid
, &IID_ISpRegDataKey
))
61 ISpRegDataKey_AddRef( iface
);
66 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
71 static ULONG WINAPI
data_key_AddRef( ISpRegDataKey
*iface
)
73 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
74 ULONG ref
= InterlockedIncrement( &This
->ref
);
76 TRACE( "(%p) ref = %u\n", This
, ref
);
80 static ULONG WINAPI
data_key_Release( ISpRegDataKey
*iface
)
82 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
83 ULONG ref
= InterlockedDecrement(&This
->ref
);
85 TRACE( "(%p) ref = %u\n", This
, ref
);
89 if (This
->key
) RegCloseKey( This
->key
);
96 static HRESULT WINAPI
data_key_SetData( ISpRegDataKey
*iface
, LPCWSTR name
,
97 ULONG size
, const BYTE
*data
)
103 static HRESULT WINAPI
data_key_GetData( ISpRegDataKey
*iface
, LPCWSTR name
,
104 ULONG
*size
, BYTE
*data
)
110 static HRESULT WINAPI
data_key_SetStringValue( ISpRegDataKey
*iface
,
111 LPCWSTR name
, LPCWSTR value
)
117 static HRESULT WINAPI
data_key_GetStringValue( ISpRegDataKey
*iface
,
118 LPCWSTR name
, LPWSTR
*value
)
124 static HRESULT WINAPI
data_key_SetDWORD( ISpRegDataKey
*iface
,
125 LPCWSTR name
, DWORD value
)
131 static HRESULT WINAPI
data_key_GetDWORD( ISpRegDataKey
*iface
,
132 LPCWSTR name
, DWORD
*pdwValue
)
138 static HRESULT WINAPI
data_key_OpenKey( ISpRegDataKey
*iface
,
139 LPCWSTR name
, ISpDataKey
**sub_key
)
145 static HRESULT WINAPI
data_key_CreateKey( ISpRegDataKey
*iface
,
146 LPCWSTR name
, ISpDataKey
**sub_key
)
152 static HRESULT WINAPI
data_key_DeleteKey( ISpRegDataKey
*iface
, LPCWSTR name
)
158 static HRESULT WINAPI
data_key_DeleteValue( ISpRegDataKey
*iface
, LPCWSTR name
)
164 static HRESULT WINAPI
data_key_EnumKeys( ISpRegDataKey
*iface
,
165 ULONG index
, LPWSTR
*sub_key
)
171 static HRESULT WINAPI
data_key_EnumValues( ISpRegDataKey
*iface
,
172 ULONG index
, LPWSTR
*value
)
178 static HRESULT WINAPI
data_key_SetKey( ISpRegDataKey
*iface
,
179 HKEY key
, BOOL read_only
)
181 struct data_key
*This
= impl_from_ISpRegDataKey( iface
);
183 TRACE( "(%p)->(%p %d)\n", This
, key
, read_only
);
185 if (This
->key
) return SPERR_ALREADY_INITIALIZED
;
188 This
->read_only
= read_only
;
192 const struct ISpRegDataKeyVtbl data_key_vtbl
=
194 data_key_QueryInterface
,
199 data_key_SetStringValue
,
200 data_key_GetStringValue
,
206 data_key_DeleteValue
,
212 HRESULT
data_key_create( IUnknown
*outer
, REFIID iid
, void **obj
)
214 struct data_key
*This
= heap_alloc( sizeof(*This
) );
217 if (!This
) return E_OUTOFMEMORY
;
218 This
->ISpRegDataKey_iface
.lpVtbl
= &data_key_vtbl
;
221 This
->read_only
= FALSE
;
223 hr
= ISpRegDataKey_QueryInterface( &This
->ISpRegDataKey_iface
, iid
, obj
);
225 ISpRegDataKey_Release( &This
->ISpRegDataKey_iface
);
229 struct token_category
231 ISpObjectTokenCategory ISpObjectTokenCategory_iface
;
234 ISpRegDataKey
*data_key
;
237 static struct token_category
*impl_from_ISpObjectTokenCategory( ISpObjectTokenCategory
*iface
)
239 return CONTAINING_RECORD( iface
, struct token_category
, ISpObjectTokenCategory_iface
);
242 static HRESULT WINAPI
token_category_QueryInterface( ISpObjectTokenCategory
*iface
,
243 REFIID iid
, void **obj
)
245 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
247 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
249 if (IsEqualIID( iid
, &IID_IUnknown
) ||
250 IsEqualIID( iid
, &IID_ISpDataKey
) ||
251 IsEqualIID( iid
, &IID_ISpObjectTokenCategory
))
253 ISpObjectTokenCategory_AddRef( iface
);
258 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
260 return E_NOINTERFACE
;
263 static ULONG WINAPI
token_category_AddRef( ISpObjectTokenCategory
*iface
)
265 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
266 ULONG ref
= InterlockedIncrement( &This
->ref
);
268 TRACE( "(%p) ref = %u\n", This
, ref
);
272 static ULONG WINAPI
token_category_Release( ISpObjectTokenCategory
*iface
)
274 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
275 ULONG ref
= InterlockedDecrement(&This
->ref
);
277 TRACE( "(%p) ref = %u\n", This
, ref
);
281 if (This
->data_key
) ISpRegDataKey_Release( This
->data_key
);
287 static HRESULT WINAPI
token_category_SetData( ISpObjectTokenCategory
*iface
,
288 LPCWSTR name
, ULONG size
,
295 static HRESULT WINAPI
token_category_GetData( ISpObjectTokenCategory
*iface
,
296 LPCWSTR name
, ULONG
*size
,
303 static HRESULT WINAPI
token_category_SetStringValue( ISpObjectTokenCategory
*iface
,
304 LPCWSTR name
, LPCWSTR value
)
310 static HRESULT WINAPI
token_category_GetStringValue( ISpObjectTokenCategory
*iface
,
311 LPCWSTR name
, LPWSTR
*value
)
317 static HRESULT WINAPI
token_category_SetDWORD( ISpObjectTokenCategory
*iface
,
318 LPCWSTR name
, DWORD value
)
324 static HRESULT WINAPI
token_category_GetDWORD( ISpObjectTokenCategory
*iface
,
325 LPCWSTR name
, DWORD
*pdwValue
)
331 static HRESULT WINAPI
token_category_OpenKey( ISpObjectTokenCategory
*iface
,
332 LPCWSTR name
, ISpDataKey
**sub_key
)
338 static HRESULT WINAPI
token_category_CreateKey( ISpObjectTokenCategory
*iface
,
339 LPCWSTR name
, ISpDataKey
**sub_key
)
345 static HRESULT WINAPI
token_category_DeleteKey( ISpObjectTokenCategory
*iface
,
352 static HRESULT WINAPI
token_category_DeleteValue( ISpObjectTokenCategory
*iface
,
359 static HRESULT WINAPI
token_category_EnumKeys( ISpObjectTokenCategory
*iface
,
360 ULONG index
, LPWSTR
*sub_key
)
366 static HRESULT WINAPI
token_category_EnumValues( ISpObjectTokenCategory
*iface
,
367 ULONG index
, LPWSTR
*value
)
373 static HRESULT
parse_cat_id( const WCHAR
*str
, HKEY
*root
, const WCHAR
**sub_key
)
382 #define X(s) s, ARRAY_SIZE(s) - 1
383 { X(L
"HKEY_LOCAL_MACHINE\\"), HKEY_LOCAL_MACHINE
},
384 { X(L
"HKEY_CURRENT_USER\\"), HKEY_CURRENT_USER
},
389 int len
= lstrlenW( str
);
391 for (ptr
= table
; ptr
->name
; ptr
++)
393 if (len
>= ptr
->len
&& !wcsncmp( str
, ptr
->name
, ptr
->len
))
396 *sub_key
= str
+ ptr
->len
;
403 static HRESULT WINAPI
token_category_SetId( ISpObjectTokenCategory
*iface
,
404 LPCWSTR id
, BOOL create
)
406 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
412 TRACE( "(%p)->(%s %d)\n", This
, debugstr_w( id
), create
);
414 if (This
->data_key
) return SPERR_ALREADY_INITIALIZED
;
416 hr
= parse_cat_id( id
, &root
, &subkey
);
417 if (hr
!= S_OK
) return SPERR_INVALID_REGISTRY_KEY
;
420 res
= RegCreateKeyExW( root
, subkey
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
422 res
= RegOpenKeyExW( root
, subkey
, 0, KEY_ALL_ACCESS
, &key
);
423 if (res
) return SPERR_INVALID_REGISTRY_KEY
;
425 hr
= CoCreateInstance( &CLSID_SpDataKey
, NULL
, CLSCTX_ALL
,
426 &IID_ISpRegDataKey
, (void **)&This
->data_key
);
427 if (FAILED(hr
)) goto fail
;
429 hr
= ISpRegDataKey_SetKey( This
->data_key
, key
, FALSE
);
430 if (FAILED(hr
)) goto fail
;
439 static HRESULT WINAPI
token_category_GetId( ISpObjectTokenCategory
*iface
,
446 static HRESULT WINAPI
token_category_GetDataKey( ISpObjectTokenCategory
*iface
,
447 SPDATAKEYLOCATION location
,
448 ISpDataKey
**data_key
)
454 static HRESULT WINAPI
token_category_EnumTokens( ISpObjectTokenCategory
*iface
,
455 LPCWSTR req
, LPCWSTR opt
,
456 IEnumSpObjectTokens
**enum_tokens
)
458 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
459 ISpObjectTokenEnumBuilder
*builder
;
462 FIXME( "(%p)->(%s %s %p): semi-stub\n", This
, debugstr_w( req
), debugstr_w( opt
), enum_tokens
);
464 if (!This
->data_key
) return SPERR_UNINITIALIZED
;
466 hr
= CoCreateInstance( &CLSID_SpObjectTokenEnum
, NULL
, CLSCTX_ALL
,
467 &IID_ISpObjectTokenEnumBuilder
, (void **)&builder
);
468 if (FAILED(hr
)) return hr
;
470 hr
= ISpObjectTokenEnumBuilder_SetAttribs( builder
, req
, opt
);
471 if (FAILED(hr
)) goto fail
;
473 /* FIXME: Build the enumerator */
475 hr
= ISpObjectTokenEnumBuilder_QueryInterface( builder
, &IID_IEnumSpObjectTokens
,
476 (void **)enum_tokens
);
479 ISpObjectTokenEnumBuilder_Release( builder
);
483 static HRESULT WINAPI
token_category_SetDefaultTokenId( ISpObjectTokenCategory
*iface
,
490 static HRESULT WINAPI
token_category_GetDefaultTokenId( ISpObjectTokenCategory
*iface
,
493 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
494 struct data_key
*this_data_key
;
497 DWORD regvalue_size
= sizeof( regvalue
);
499 FIXME( "(%p)->(%p): semi-stub\n", iface
, id
);
502 return SPERR_UNINITIALIZED
;
507 /* todo: check HKCU's DefaultTokenId before */
509 this_data_key
= impl_from_ISpRegDataKey( This
->data_key
);
511 res
= RegGetValueW( this_data_key
->key
, NULL
, L
"DefaultDefaultTokenId", RRF_RT_REG_SZ
,
512 NULL
, ®value
, ®value_size
);
513 if (res
== ERROR_FILE_NOT_FOUND
) {
514 return SPERR_NOT_FOUND
;
515 } else if (res
!= ERROR_SUCCESS
) {
516 /* probably not the correct return value */
517 FIXME( "returning %08x\n", res
);
521 *id
= CoTaskMemAlloc( regvalue_size
);
522 wcscpy( *id
, regvalue
);
527 const struct ISpObjectTokenCategoryVtbl token_category_vtbl
=
529 token_category_QueryInterface
,
530 token_category_AddRef
,
531 token_category_Release
,
532 token_category_SetData
,
533 token_category_GetData
,
534 token_category_SetStringValue
,
535 token_category_GetStringValue
,
536 token_category_SetDWORD
,
537 token_category_GetDWORD
,
538 token_category_OpenKey
,
539 token_category_CreateKey
,
540 token_category_DeleteKey
,
541 token_category_DeleteValue
,
542 token_category_EnumKeys
,
543 token_category_EnumValues
,
544 token_category_SetId
,
545 token_category_GetId
,
546 token_category_GetDataKey
,
547 token_category_EnumTokens
,
548 token_category_SetDefaultTokenId
,
549 token_category_GetDefaultTokenId
,
552 HRESULT
token_category_create( IUnknown
*outer
, REFIID iid
, void **obj
)
554 struct token_category
*This
= heap_alloc( sizeof(*This
) );
557 if (!This
) return E_OUTOFMEMORY
;
558 This
->ISpObjectTokenCategory_iface
.lpVtbl
= &token_category_vtbl
;
560 This
->data_key
= NULL
;
562 hr
= ISpObjectTokenCategory_QueryInterface( &This
->ISpObjectTokenCategory_iface
, iid
, obj
);
564 ISpObjectTokenCategory_Release( &This
->ISpObjectTokenCategory_iface
);
570 ISpObjectTokenEnumBuilder ISpObjectTokenEnumBuilder_iface
;
578 static struct token_enum
*impl_from_ISpObjectTokenEnumBuilder( ISpObjectTokenEnumBuilder
*iface
)
580 return CONTAINING_RECORD( iface
, struct token_enum
, ISpObjectTokenEnumBuilder_iface
);
583 static HRESULT WINAPI
token_enum_QueryInterface( ISpObjectTokenEnumBuilder
*iface
,
584 REFIID iid
, void **obj
)
586 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
588 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
590 if (IsEqualIID( iid
, &IID_IUnknown
) ||
591 IsEqualIID( iid
, &IID_IEnumSpObjectTokens
) ||
592 IsEqualIID( iid
, &IID_ISpObjectTokenEnumBuilder
))
594 ISpObjectTokenEnumBuilder_AddRef( iface
);
599 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
601 return E_NOINTERFACE
;
604 static ULONG WINAPI
token_enum_AddRef( ISpObjectTokenEnumBuilder
*iface
)
606 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
607 ULONG ref
= InterlockedIncrement( &This
->ref
);
609 TRACE( "(%p) ref = %u\n", This
, ref
);
613 static ULONG WINAPI
token_enum_Release( ISpObjectTokenEnumBuilder
*iface
)
615 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
616 ULONG ref
= InterlockedDecrement(&This
->ref
);
618 TRACE( "(%p) ref = %u\n", This
, ref
);
622 heap_free( This
->req
);
623 heap_free( This
->opt
);
630 static HRESULT WINAPI
token_enum_Next( ISpObjectTokenEnumBuilder
*iface
,
631 ULONG num
, ISpObjectToken
**tokens
,
634 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
636 TRACE( "(%p)->(%u %p %p)\n", This
, num
, tokens
, fetched
);
638 if (!This
->init
) return SPERR_UNINITIALIZED
;
640 FIXME( "semi-stub: Returning an empty enumerator\n" );
642 if (fetched
) *fetched
= 0;
646 static HRESULT WINAPI
token_enum_Skip( ISpObjectTokenEnumBuilder
*iface
,
653 static HRESULT WINAPI
token_enum_Reset( ISpObjectTokenEnumBuilder
*iface
)
659 static HRESULT WINAPI
token_enum_Clone( ISpObjectTokenEnumBuilder
*iface
,
660 IEnumSpObjectTokens
**clone
)
666 static HRESULT WINAPI
token_enum_Item( ISpObjectTokenEnumBuilder
*iface
,
667 ULONG index
, ISpObjectToken
**token
)
673 static HRESULT WINAPI
token_enum_GetCount( ISpObjectTokenEnumBuilder
*iface
,
676 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
678 TRACE( "(%p)->(%p)\n", This
, count
);
680 if (!This
->init
) return SPERR_UNINITIALIZED
;
682 *count
= This
->count
;
686 static HRESULT WINAPI
token_enum_SetAttribs( ISpObjectTokenEnumBuilder
*iface
,
687 LPCWSTR req
, LPCWSTR opt
)
689 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
691 TRACE( "(%p)->(%s %s)\n", This
, debugstr_w( req
), debugstr_w( opt
) );
693 if (This
->init
) return SPERR_ALREADY_INITIALIZED
;
697 This
->req
= heap_strdupW( req
);
698 if (!This
->req
) goto out_of_mem
;
703 This
->opt
= heap_strdupW( opt
);
704 if (!This
->opt
) goto out_of_mem
;
711 heap_free( This
->req
);
712 return E_OUTOFMEMORY
;
715 static HRESULT WINAPI
token_enum_AddTokens( ISpObjectTokenEnumBuilder
*iface
,
716 ULONG num
, ISpObjectToken
**tokens
)
722 static HRESULT WINAPI
token_enum_AddTokensFromDataKey( ISpObjectTokenEnumBuilder
*iface
,
723 ISpDataKey
*data_key
,
724 LPCWSTR sub_key
, LPCWSTR cat_id
)
730 static HRESULT WINAPI
token_enum_AddTokensFromTokenEnum( ISpObjectTokenEnumBuilder
*iface
,
731 IEnumSpObjectTokens
*token_enum
)
737 static HRESULT WINAPI
token_enum_Sort( ISpObjectTokenEnumBuilder
*iface
,
744 const struct ISpObjectTokenEnumBuilderVtbl token_enum_vtbl
=
746 token_enum_QueryInterface
,
755 token_enum_SetAttribs
,
756 token_enum_AddTokens
,
757 token_enum_AddTokensFromDataKey
,
758 token_enum_AddTokensFromTokenEnum
,
762 HRESULT
token_enum_create( IUnknown
*outer
, REFIID iid
, void **obj
)
764 struct token_enum
*This
= heap_alloc( sizeof(*This
) );
767 if (!This
) return E_OUTOFMEMORY
;
768 This
->ISpObjectTokenEnumBuilder_iface
.lpVtbl
= &token_enum_vtbl
;
775 hr
= ISpObjectTokenEnumBuilder_QueryInterface( &This
->ISpObjectTokenEnumBuilder_iface
, iid
, obj
);
777 ISpObjectTokenEnumBuilder_Release( &This
->ISpObjectTokenEnumBuilder_iface
);
783 ISpObjectToken ISpObjectToken_iface
;
789 static struct object_token
*impl_from_ISpObjectToken( ISpObjectToken
*iface
)
791 return CONTAINING_RECORD( iface
, struct object_token
, ISpObjectToken_iface
);
794 static HRESULT WINAPI
token_QueryInterface( ISpObjectToken
*iface
,
795 REFIID iid
, void **obj
)
797 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
799 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
801 if (IsEqualIID( iid
, &IID_IUnknown
) ||
802 IsEqualIID( iid
, &IID_ISpDataKey
) ||
803 IsEqualIID( iid
, &IID_ISpObjectToken
))
805 ISpObjectToken_AddRef( iface
);
810 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
812 return E_NOINTERFACE
;
815 static ULONG WINAPI
token_AddRef( ISpObjectToken
*iface
)
817 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
818 ULONG ref
= InterlockedIncrement( &This
->ref
);
820 TRACE( "(%p) ref = %u\n", This
, ref
);
824 static ULONG WINAPI
token_Release( ISpObjectToken
*iface
)
826 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
827 ULONG ref
= InterlockedDecrement(&This
->ref
);
829 TRACE( "(%p) ref = %u\n", This
, ref
);
833 if (This
->token_key
) RegCloseKey( This
->token_key
);
840 static HRESULT WINAPI
token_SetData( ISpObjectToken
*iface
,
841 LPCWSTR name
, ULONG size
,
848 static HRESULT WINAPI
token_GetData( ISpObjectToken
*iface
,
849 LPCWSTR name
, ULONG
*size
,
856 static HRESULT WINAPI
token_SetStringValue( ISpObjectToken
*iface
,
857 LPCWSTR name
, LPCWSTR value
)
863 static HRESULT WINAPI
token_GetStringValue( ISpObjectToken
*iface
,
864 LPCWSTR name
, LPWSTR
*value
)
870 static HRESULT WINAPI
token_SetDWORD( ISpObjectToken
*iface
,
871 LPCWSTR name
, DWORD value
)
877 static HRESULT WINAPI
token_GetDWORD( ISpObjectToken
*iface
,
878 LPCWSTR name
, DWORD
*pdwValue
)
884 static HRESULT WINAPI
token_OpenKey( ISpObjectToken
*iface
,
885 LPCWSTR name
, ISpDataKey
**sub_key
)
891 static HRESULT WINAPI
token_CreateKey( ISpObjectToken
*iface
,
892 LPCWSTR name
, ISpDataKey
**sub_key
)
898 static HRESULT WINAPI
token_DeleteKey( ISpObjectToken
*iface
,
905 static HRESULT WINAPI
token_DeleteValue( ISpObjectToken
*iface
,
912 static HRESULT WINAPI
token_EnumKeys( ISpObjectToken
*iface
,
913 ULONG index
, LPWSTR
*sub_key
)
919 static HRESULT WINAPI
token_EnumValues( ISpObjectToken
*iface
,
920 ULONG index
, LPWSTR
*value
)
926 static HRESULT WINAPI
token_SetId( ISpObjectToken
*iface
,
927 LPCWSTR category_id
, LPCWSTR token_id
,
930 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
936 FIXME( "(%p)->(%s %s %d): semi-stub\n", This
, debugstr_w( category_id
),
937 debugstr_w(token_id
), create
);
939 if (This
->token_key
) return SPERR_ALREADY_INITIALIZED
;
941 if (!token_id
) return E_POINTER
;
943 hr
= parse_cat_id( token_id
, &root
, &subkey
);
944 if (hr
!= S_OK
) return SPERR_NOT_FOUND
;
947 res
= RegCreateKeyExW( root
, subkey
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &key
, NULL
);
949 res
= RegOpenKeyExW( root
, subkey
, 0, KEY_ALL_ACCESS
, &key
);
950 if (res
) return SPERR_NOT_FOUND
;
952 This
->token_key
= key
;
957 static HRESULT WINAPI
token_GetId( ISpObjectToken
*iface
,
964 static HRESULT WINAPI
token_GetCategory( ISpObjectToken
*iface
,
965 ISpObjectTokenCategory
**category
)
971 static HRESULT WINAPI
token_CreateInstance( ISpObjectToken
*iface
,
981 static HRESULT WINAPI
token_GetStorageFileName( ISpObjectToken
*iface
,
992 static HRESULT WINAPI
token_RemoveStorageFileName( ISpObjectToken
*iface
,
1001 static HRESULT WINAPI
token_Remove( ISpObjectToken
*iface
,
1008 static HRESULT WINAPI
token_IsUISupported( ISpObjectToken
*iface
,
1011 ULONG extra_data_size
,
1019 static HRESULT WINAPI
token_DisplayUI( ISpObjectToken
*iface
,
1024 ULONG extra_data_size
,
1031 static HRESULT WINAPI
token_MatchesAttributes( ISpObjectToken
*iface
,
1039 const struct ISpObjectTokenVtbl token_vtbl
=
1041 token_QueryInterface
,
1046 token_SetStringValue
,
1047 token_GetStringValue
,
1059 token_CreateInstance
,
1060 token_GetStorageFileName
,
1061 token_RemoveStorageFileName
,
1063 token_IsUISupported
,
1065 token_MatchesAttributes
1068 HRESULT
token_create( IUnknown
*outer
, REFIID iid
, void **obj
)
1070 struct object_token
*This
= heap_alloc( sizeof(*This
) );
1073 if (!This
) return E_OUTOFMEMORY
;
1074 This
->ISpObjectToken_iface
.lpVtbl
= &token_vtbl
;
1077 This
->token_key
= NULL
;
1079 hr
= ISpObjectToken_QueryInterface( &This
->ISpObjectToken_iface
, iid
, obj
);
1081 ISpObjectToken_Release( &This
->ISpObjectToken_iface
);