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
;
419 if (create
) FIXME( "Ignoring create\n" );
421 res
= RegOpenKeyExW( root
, subkey
, 0, KEY_ALL_ACCESS
, &key
);
422 if (res
) return SPERR_INVALID_REGISTRY_KEY
;
424 hr
= CoCreateInstance( &CLSID_SpDataKey
, NULL
, CLSCTX_ALL
,
425 &IID_ISpRegDataKey
, (void **)&This
->data_key
);
426 if (FAILED(hr
)) goto fail
;
428 hr
= ISpRegDataKey_SetKey( This
->data_key
, key
, FALSE
);
429 if (FAILED(hr
)) goto fail
;
438 static HRESULT WINAPI
token_category_GetId( ISpObjectTokenCategory
*iface
,
445 static HRESULT WINAPI
token_category_GetDataKey( ISpObjectTokenCategory
*iface
,
446 SPDATAKEYLOCATION location
,
447 ISpDataKey
**data_key
)
453 static HRESULT WINAPI
token_category_EnumTokens( ISpObjectTokenCategory
*iface
,
454 LPCWSTR req
, LPCWSTR opt
,
455 IEnumSpObjectTokens
**enum_tokens
)
457 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
458 ISpObjectTokenEnumBuilder
*builder
;
461 FIXME( "(%p)->(%s %s %p): semi-stub\n", This
, debugstr_w( req
), debugstr_w( opt
), enum_tokens
);
463 if (!This
->data_key
) return SPERR_UNINITIALIZED
;
465 hr
= CoCreateInstance( &CLSID_SpObjectTokenEnum
, NULL
, CLSCTX_ALL
,
466 &IID_ISpObjectTokenEnumBuilder
, (void **)&builder
);
467 if (FAILED(hr
)) return hr
;
469 hr
= ISpObjectTokenEnumBuilder_SetAttribs( builder
, req
, opt
);
470 if (FAILED(hr
)) goto fail
;
472 /* FIXME: Build the enumerator */
474 hr
= ISpObjectTokenEnumBuilder_QueryInterface( builder
, &IID_IEnumSpObjectTokens
,
475 (void **)enum_tokens
);
478 ISpObjectTokenEnumBuilder_Release( builder
);
482 static HRESULT WINAPI
token_category_SetDefaultTokenId( ISpObjectTokenCategory
*iface
,
489 static HRESULT WINAPI
token_category_GetDefaultTokenId( ISpObjectTokenCategory
*iface
,
492 struct token_category
*This
= impl_from_ISpObjectTokenCategory( iface
);
493 struct data_key
*this_data_key
;
496 DWORD regvalue_size
= sizeof( regvalue
);
498 FIXME( "(%p)->(%p): semi-stub\n", iface
, id
);
501 return SPERR_UNINITIALIZED
;
506 /* todo: check HKCU's DefaultTokenId before */
508 this_data_key
= impl_from_ISpRegDataKey( This
->data_key
);
510 res
= RegGetValueW( this_data_key
->key
, NULL
, L
"DefaultDefaultTokenId", RRF_RT_REG_SZ
,
511 NULL
, ®value
, ®value_size
);
512 if (res
== ERROR_FILE_NOT_FOUND
) {
513 return SPERR_NOT_FOUND
;
514 } else if (res
!= ERROR_SUCCESS
) {
515 /* probably not the correct return value */
516 FIXME( "returning %08x\n", res
);
520 *id
= CoTaskMemAlloc( regvalue_size
);
521 wcscpy( *id
, regvalue
);
526 const struct ISpObjectTokenCategoryVtbl token_category_vtbl
=
528 token_category_QueryInterface
,
529 token_category_AddRef
,
530 token_category_Release
,
531 token_category_SetData
,
532 token_category_GetData
,
533 token_category_SetStringValue
,
534 token_category_GetStringValue
,
535 token_category_SetDWORD
,
536 token_category_GetDWORD
,
537 token_category_OpenKey
,
538 token_category_CreateKey
,
539 token_category_DeleteKey
,
540 token_category_DeleteValue
,
541 token_category_EnumKeys
,
542 token_category_EnumValues
,
543 token_category_SetId
,
544 token_category_GetId
,
545 token_category_GetDataKey
,
546 token_category_EnumTokens
,
547 token_category_SetDefaultTokenId
,
548 token_category_GetDefaultTokenId
,
551 HRESULT
token_category_create( IUnknown
*outer
, REFIID iid
, void **obj
)
553 struct token_category
*This
= heap_alloc( sizeof(*This
) );
556 if (!This
) return E_OUTOFMEMORY
;
557 This
->ISpObjectTokenCategory_iface
.lpVtbl
= &token_category_vtbl
;
559 This
->data_key
= NULL
;
561 hr
= ISpObjectTokenCategory_QueryInterface( &This
->ISpObjectTokenCategory_iface
, iid
, obj
);
563 ISpObjectTokenCategory_Release( &This
->ISpObjectTokenCategory_iface
);
569 ISpObjectTokenEnumBuilder ISpObjectTokenEnumBuilder_iface
;
577 static struct token_enum
*impl_from_ISpObjectTokenEnumBuilder( ISpObjectTokenEnumBuilder
*iface
)
579 return CONTAINING_RECORD( iface
, struct token_enum
, ISpObjectTokenEnumBuilder_iface
);
582 static HRESULT WINAPI
token_enum_QueryInterface( ISpObjectTokenEnumBuilder
*iface
,
583 REFIID iid
, void **obj
)
585 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
587 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
589 if (IsEqualIID( iid
, &IID_IUnknown
) ||
590 IsEqualIID( iid
, &IID_IEnumSpObjectTokens
) ||
591 IsEqualIID( iid
, &IID_ISpObjectTokenEnumBuilder
))
593 ISpObjectTokenEnumBuilder_AddRef( iface
);
598 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
600 return E_NOINTERFACE
;
603 static ULONG WINAPI
token_enum_AddRef( ISpObjectTokenEnumBuilder
*iface
)
605 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
606 ULONG ref
= InterlockedIncrement( &This
->ref
);
608 TRACE( "(%p) ref = %u\n", This
, ref
);
612 static ULONG WINAPI
token_enum_Release( ISpObjectTokenEnumBuilder
*iface
)
614 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
615 ULONG ref
= InterlockedDecrement(&This
->ref
);
617 TRACE( "(%p) ref = %u\n", This
, ref
);
621 heap_free( This
->req
);
622 heap_free( This
->opt
);
629 static HRESULT WINAPI
token_enum_Next( ISpObjectTokenEnumBuilder
*iface
,
630 ULONG num
, ISpObjectToken
**tokens
,
633 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
635 TRACE( "(%p)->(%u %p %p)\n", This
, num
, tokens
, fetched
);
637 if (!This
->init
) return SPERR_UNINITIALIZED
;
639 FIXME( "semi-stub: Returning an empty enumerator\n" );
641 if (fetched
) *fetched
= 0;
645 static HRESULT WINAPI
token_enum_Skip( ISpObjectTokenEnumBuilder
*iface
,
652 static HRESULT WINAPI
token_enum_Reset( ISpObjectTokenEnumBuilder
*iface
)
658 static HRESULT WINAPI
token_enum_Clone( ISpObjectTokenEnumBuilder
*iface
,
659 IEnumSpObjectTokens
**clone
)
665 static HRESULT WINAPI
token_enum_Item( ISpObjectTokenEnumBuilder
*iface
,
666 ULONG index
, ISpObjectToken
**token
)
672 static HRESULT WINAPI
token_enum_GetCount( ISpObjectTokenEnumBuilder
*iface
,
675 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
677 TRACE( "(%p)->(%p)\n", This
, count
);
679 if (!This
->init
) return SPERR_UNINITIALIZED
;
681 *count
= This
->count
;
685 static HRESULT WINAPI
token_enum_SetAttribs( ISpObjectTokenEnumBuilder
*iface
,
686 LPCWSTR req
, LPCWSTR opt
)
688 struct token_enum
*This
= impl_from_ISpObjectTokenEnumBuilder( iface
);
690 TRACE( "(%p)->(%s %s)\n", This
, debugstr_w( req
), debugstr_w( opt
) );
692 if (This
->init
) return SPERR_ALREADY_INITIALIZED
;
696 This
->req
= heap_strdupW( req
);
697 if (!This
->req
) goto out_of_mem
;
702 This
->opt
= heap_strdupW( opt
);
703 if (!This
->opt
) goto out_of_mem
;
710 heap_free( This
->req
);
711 return E_OUTOFMEMORY
;
714 static HRESULT WINAPI
token_enum_AddTokens( ISpObjectTokenEnumBuilder
*iface
,
715 ULONG num
, ISpObjectToken
**tokens
)
721 static HRESULT WINAPI
token_enum_AddTokensFromDataKey( ISpObjectTokenEnumBuilder
*iface
,
722 ISpDataKey
*data_key
,
723 LPCWSTR sub_key
, LPCWSTR cat_id
)
729 static HRESULT WINAPI
token_enum_AddTokensFromTokenEnum( ISpObjectTokenEnumBuilder
*iface
,
730 IEnumSpObjectTokens
*token_enum
)
736 static HRESULT WINAPI
token_enum_Sort( ISpObjectTokenEnumBuilder
*iface
,
743 const struct ISpObjectTokenEnumBuilderVtbl token_enum_vtbl
=
745 token_enum_QueryInterface
,
754 token_enum_SetAttribs
,
755 token_enum_AddTokens
,
756 token_enum_AddTokensFromDataKey
,
757 token_enum_AddTokensFromTokenEnum
,
761 HRESULT
token_enum_create( IUnknown
*outer
, REFIID iid
, void **obj
)
763 struct token_enum
*This
= heap_alloc( sizeof(*This
) );
766 if (!This
) return E_OUTOFMEMORY
;
767 This
->ISpObjectTokenEnumBuilder_iface
.lpVtbl
= &token_enum_vtbl
;
774 hr
= ISpObjectTokenEnumBuilder_QueryInterface( &This
->ISpObjectTokenEnumBuilder_iface
, iid
, obj
);
776 ISpObjectTokenEnumBuilder_Release( &This
->ISpObjectTokenEnumBuilder_iface
);
782 ISpObjectToken ISpObjectToken_iface
;
788 static struct object_token
*impl_from_ISpObjectToken( ISpObjectToken
*iface
)
790 return CONTAINING_RECORD( iface
, struct object_token
, ISpObjectToken_iface
);
793 static HRESULT WINAPI
token_QueryInterface( ISpObjectToken
*iface
,
794 REFIID iid
, void **obj
)
796 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
798 TRACE( "(%p)->(%s %p)\n", This
, debugstr_guid( iid
), obj
);
800 if (IsEqualIID( iid
, &IID_IUnknown
) ||
801 IsEqualIID( iid
, &IID_ISpDataKey
) ||
802 IsEqualIID( iid
, &IID_ISpObjectToken
))
804 ISpObjectToken_AddRef( iface
);
809 FIXME( "interface %s not implemented\n", debugstr_guid( iid
) );
811 return E_NOINTERFACE
;
814 static ULONG WINAPI
token_AddRef( ISpObjectToken
*iface
)
816 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
817 ULONG ref
= InterlockedIncrement( &This
->ref
);
819 TRACE( "(%p) ref = %u\n", This
, ref
);
823 static ULONG WINAPI
token_Release( ISpObjectToken
*iface
)
825 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
826 ULONG ref
= InterlockedDecrement(&This
->ref
);
828 TRACE( "(%p) ref = %u\n", This
, ref
);
832 if (This
->token_key
) RegCloseKey( This
->token_key
);
839 static HRESULT WINAPI
token_SetData( ISpObjectToken
*iface
,
840 LPCWSTR name
, ULONG size
,
847 static HRESULT WINAPI
token_GetData( ISpObjectToken
*iface
,
848 LPCWSTR name
, ULONG
*size
,
855 static HRESULT WINAPI
token_SetStringValue( ISpObjectToken
*iface
,
856 LPCWSTR name
, LPCWSTR value
)
862 static HRESULT WINAPI
token_GetStringValue( ISpObjectToken
*iface
,
863 LPCWSTR name
, LPWSTR
*value
)
869 static HRESULT WINAPI
token_SetDWORD( ISpObjectToken
*iface
,
870 LPCWSTR name
, DWORD value
)
876 static HRESULT WINAPI
token_GetDWORD( ISpObjectToken
*iface
,
877 LPCWSTR name
, DWORD
*pdwValue
)
883 static HRESULT WINAPI
token_OpenKey( ISpObjectToken
*iface
,
884 LPCWSTR name
, ISpDataKey
**sub_key
)
890 static HRESULT WINAPI
token_CreateKey( ISpObjectToken
*iface
,
891 LPCWSTR name
, ISpDataKey
**sub_key
)
897 static HRESULT WINAPI
token_DeleteKey( ISpObjectToken
*iface
,
904 static HRESULT WINAPI
token_DeleteValue( ISpObjectToken
*iface
,
911 static HRESULT WINAPI
token_EnumKeys( ISpObjectToken
*iface
,
912 ULONG index
, LPWSTR
*sub_key
)
918 static HRESULT WINAPI
token_EnumValues( ISpObjectToken
*iface
,
919 ULONG index
, LPWSTR
*value
)
925 static HRESULT WINAPI
token_SetId( ISpObjectToken
*iface
,
926 LPCWSTR category_id
, LPCWSTR token_id
,
929 struct object_token
*This
= impl_from_ISpObjectToken( iface
);
935 FIXME( "(%p)->(%s %s %d): semi-stub\n", This
, debugstr_w( category_id
),
936 debugstr_w(token_id
), create
);
938 if (This
->token_key
) return SPERR_ALREADY_INITIALIZED
;
940 if (!token_id
) return E_POINTER
;
942 hr
= parse_cat_id( token_id
, &root
, &subkey
);
943 if (hr
!= S_OK
) return SPERR_NOT_FOUND
;
945 res
= RegOpenKeyExW( root
, subkey
, 0, KEY_ALL_ACCESS
, &key
);
946 if (res
) return SPERR_NOT_FOUND
;
948 This
->token_key
= key
;
953 static HRESULT WINAPI
token_GetId( ISpObjectToken
*iface
,
960 static HRESULT WINAPI
token_GetCategory( ISpObjectToken
*iface
,
961 ISpObjectTokenCategory
**category
)
967 static HRESULT WINAPI
token_CreateInstance( ISpObjectToken
*iface
,
977 static HRESULT WINAPI
token_GetStorageFileName( ISpObjectToken
*iface
,
988 static HRESULT WINAPI
token_RemoveStorageFileName( ISpObjectToken
*iface
,
997 static HRESULT WINAPI
token_Remove( ISpObjectToken
*iface
,
1004 static HRESULT WINAPI
token_IsUISupported( ISpObjectToken
*iface
,
1007 ULONG extra_data_size
,
1015 static HRESULT WINAPI
token_DisplayUI( ISpObjectToken
*iface
,
1020 ULONG extra_data_size
,
1027 static HRESULT WINAPI
token_MatchesAttributes( ISpObjectToken
*iface
,
1035 const struct ISpObjectTokenVtbl token_vtbl
=
1037 token_QueryInterface
,
1042 token_SetStringValue
,
1043 token_GetStringValue
,
1055 token_CreateInstance
,
1056 token_GetStorageFileName
,
1057 token_RemoveStorageFileName
,
1059 token_IsUISupported
,
1061 token_MatchesAttributes
1064 HRESULT
token_create( IUnknown
*outer
, REFIID iid
, void **obj
)
1066 struct object_token
*This
= heap_alloc( sizeof(*This
) );
1069 if (!This
) return E_OUTOFMEMORY
;
1070 This
->ISpObjectToken_iface
.lpVtbl
= &token_vtbl
;
1073 This
->token_key
= NULL
;
1075 hr
= ISpObjectToken_QueryInterface( &This
->ISpObjectToken_iface
, iid
, obj
);
1077 ISpObjectToken_Release( &This
->ISpObjectToken_iface
);