vbscript: Handle index read access to array properties.
[wine.git] / dlls / sapi / token.c
blob478a400f92087fd0e077a5e7a2447cd746153092
1 /*
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
21 #include <stdarg.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
28 #include "sapiddk.h"
29 #include "sperror.h"
31 #include "wine/debug.h"
33 #include "sapi_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(sapi);
37 struct data_key
39 ISpRegDataKey ISpRegDataKey_iface;
40 LONG ref;
42 HKEY key;
43 BOOL read_only;
46 static struct data_key *impl_from_ISpRegDataKey( ISpRegDataKey *iface )
48 return CONTAINING_RECORD( iface, struct data_key, ISpRegDataKey_iface );
51 struct object_token
53 ISpObjectToken ISpObjectToken_iface;
54 LONG ref;
56 HKEY token_key;
57 WCHAR *token_id;
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 );
76 *obj = iface;
77 return S_OK;
80 FIXME( "interface %s not implemented\n", debugstr_guid( iid ) );
81 *obj = NULL;
82 return E_NOINTERFACE;
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 );
91 return 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 );
101 if (!ref)
103 if (This->key) RegCloseKey( This->key );
104 heap_free( This );
107 return ref;
110 static HRESULT WINAPI data_key_SetData( ISpRegDataKey *iface, LPCWSTR name,
111 ULONG size, const BYTE *data )
113 FIXME( "stub\n" );
114 return E_NOTIMPL;
117 static HRESULT WINAPI data_key_GetData( ISpRegDataKey *iface, LPCWSTR name,
118 ULONG *size, BYTE *data )
120 FIXME( "stub\n" );
121 return E_NOTIMPL;
124 static HRESULT WINAPI data_key_SetStringValue( ISpRegDataKey *iface,
125 LPCWSTR name, LPCWSTR value )
127 FIXME( "stub\n" );
128 return E_NOTIMPL;
131 static HRESULT WINAPI data_key_GetStringValue( ISpRegDataKey *iface,
132 LPCWSTR name, LPWSTR *value )
134 struct data_key *This = impl_from_ISpRegDataKey( iface );
135 DWORD ret, size;
136 WCHAR *content;
138 TRACE( "%p, %s, %p\n", This, debugstr_w(name), value);
140 if (!This->key)
141 return E_HANDLE;
143 size = 0;
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);
149 if (!content)
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);
159 *value = content;
160 return S_OK;
163 static HRESULT WINAPI data_key_SetDWORD( ISpRegDataKey *iface,
164 LPCWSTR name, DWORD value )
166 FIXME( "stub\n" );
167 return E_NOTIMPL;
170 static HRESULT WINAPI data_key_GetDWORD( ISpRegDataKey *iface,
171 LPCWSTR name, DWORD *pdwValue )
173 FIXME( "stub\n" );
174 return E_NOTIMPL;
177 static HRESULT WINAPI data_key_OpenKey( ISpRegDataKey *iface,
178 LPCWSTR name, ISpDataKey **sub_key )
180 FIXME( "stub\n" );
181 return E_NOTIMPL;
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;
189 HRESULT hr;
190 HKEY key;
191 LONG res;
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);
200 if (SUCCEEDED(hr))
202 hr = ISpRegDataKey_SetKey(spregkey, key, FALSE);
203 if (SUCCEEDED(hr))
204 hr = ISpRegDataKey_QueryInterface(spregkey, &IID_ISpDataKey, (void**)sub_key);
205 ISpRegDataKey_Release(spregkey);
208 return hr;
211 static HRESULT WINAPI data_key_DeleteKey( ISpRegDataKey *iface, LPCWSTR name )
213 FIXME( "stub\n" );
214 return E_NOTIMPL;
217 static HRESULT WINAPI data_key_DeleteValue( ISpRegDataKey *iface, LPCWSTR name )
219 FIXME( "stub\n" );
220 return E_NOTIMPL;
223 static HRESULT WINAPI data_key_EnumKeys( ISpRegDataKey *iface,
224 ULONG index, LPWSTR *sub_key )
226 FIXME( "stub\n" );
227 return E_NOTIMPL;
230 static HRESULT WINAPI data_key_EnumValues( ISpRegDataKey *iface,
231 ULONG index, LPWSTR *value )
233 FIXME( "stub\n" );
234 return E_NOTIMPL;
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;
246 This->key = key;
247 This->read_only = read_only;
248 return S_OK;
251 const struct ISpRegDataKeyVtbl data_key_vtbl =
253 data_key_QueryInterface,
254 data_key_AddRef,
255 data_key_Release,
256 data_key_SetData,
257 data_key_GetData,
258 data_key_SetStringValue,
259 data_key_GetStringValue,
260 data_key_SetDWORD,
261 data_key_GetDWORD,
262 data_key_OpenKey,
263 data_key_CreateKey,
264 data_key_DeleteKey,
265 data_key_DeleteValue,
266 data_key_EnumKeys,
267 data_key_EnumValues,
268 data_key_SetKey
271 HRESULT data_key_create( IUnknown *outer, REFIID iid, void **obj )
273 struct data_key *This = heap_alloc( sizeof(*This) );
274 HRESULT hr;
276 if (!This) return E_OUTOFMEMORY;
277 This->ISpRegDataKey_iface.lpVtbl = &data_key_vtbl;
278 This->ref = 1;
279 This->key = NULL;
280 This->read_only = FALSE;
282 hr = ISpRegDataKey_QueryInterface( &This->ISpRegDataKey_iface, iid, obj );
284 ISpRegDataKey_Release( &This->ISpRegDataKey_iface );
285 return hr;
288 struct token_category
290 ISpObjectTokenCategory ISpObjectTokenCategory_iface;
291 LONG ref;
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 );
313 *obj = iface;
314 return S_OK;
317 FIXME( "interface %s not implemented\n", debugstr_guid( iid ) );
318 *obj = NULL;
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 );
328 return 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 );
338 if (!ref)
340 if (This->data_key) ISpRegDataKey_Release( This->data_key );
341 heap_free( This );
343 return ref;
346 static HRESULT WINAPI token_category_SetData( ISpObjectTokenCategory *iface,
347 LPCWSTR name, ULONG size,
348 const BYTE *data )
350 FIXME( "stub\n" );
351 return E_NOTIMPL;
354 static HRESULT WINAPI token_category_GetData( ISpObjectTokenCategory *iface,
355 LPCWSTR name, ULONG *size,
356 BYTE *data )
358 FIXME( "stub\n" );
359 return E_NOTIMPL;
362 static HRESULT WINAPI token_category_SetStringValue( ISpObjectTokenCategory *iface,
363 LPCWSTR name, LPCWSTR value )
365 FIXME( "stub\n" );
366 return E_NOTIMPL;
369 static HRESULT WINAPI token_category_GetStringValue( ISpObjectTokenCategory *iface,
370 LPCWSTR name, LPWSTR *value )
372 FIXME( "stub\n" );
373 return E_NOTIMPL;
376 static HRESULT WINAPI token_category_SetDWORD( ISpObjectTokenCategory *iface,
377 LPCWSTR name, DWORD value )
379 FIXME( "stub\n" );
380 return E_NOTIMPL;
383 static HRESULT WINAPI token_category_GetDWORD( ISpObjectTokenCategory *iface,
384 LPCWSTR name, DWORD *pdwValue )
386 FIXME( "stub\n" );
387 return E_NOTIMPL;
390 static HRESULT WINAPI token_category_OpenKey( ISpObjectTokenCategory *iface,
391 LPCWSTR name, ISpDataKey **sub_key )
393 FIXME( "stub\n" );
394 return E_NOTIMPL;
397 static HRESULT WINAPI token_category_CreateKey( ISpObjectTokenCategory *iface,
398 LPCWSTR name, ISpDataKey **sub_key )
400 FIXME( "stub\n" );
401 return E_NOTIMPL;
404 static HRESULT WINAPI token_category_DeleteKey( ISpObjectTokenCategory *iface,
405 LPCWSTR name )
407 FIXME( "stub\n" );
408 return E_NOTIMPL;
411 static HRESULT WINAPI token_category_DeleteValue( ISpObjectTokenCategory *iface,
412 LPCWSTR name )
414 FIXME( "stub\n" );
415 return E_NOTIMPL;
418 static HRESULT WINAPI token_category_EnumKeys( ISpObjectTokenCategory *iface,
419 ULONG index, LPWSTR *sub_key )
421 FIXME( "stub\n" );
422 return E_NOTIMPL;
425 static HRESULT WINAPI token_category_EnumValues( ISpObjectTokenCategory *iface,
426 ULONG index, LPWSTR *value )
428 FIXME( "stub\n" );
429 return E_NOTIMPL;
432 static HRESULT parse_cat_id( const WCHAR *str, HKEY *root, const WCHAR **sub_key )
434 struct table
436 const WCHAR *name;
437 unsigned int len;
438 HKEY key;
439 } table[] =
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 },
444 { NULL }
445 #undef X
447 struct table *ptr;
448 int len = lstrlenW( str );
450 for (ptr = table; ptr->name; ptr++)
452 if (len >= ptr->len && !wcsncmp( str, ptr->name, ptr->len ))
454 *root = ptr->key;
455 *sub_key = str + ptr->len;
456 return S_OK;
459 return S_FALSE;
462 static HRESULT WINAPI token_category_SetId( ISpObjectTokenCategory *iface,
463 LPCWSTR id, BOOL create )
465 struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
466 HKEY root, key;
467 const WCHAR *subkey;
468 LONG res;
469 HRESULT hr;
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;
478 if (create)
479 res = RegCreateKeyExW( root, subkey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL );
480 else
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;
491 return hr;
493 fail:
494 RegCloseKey( key );
495 return hr;
498 static HRESULT WINAPI token_category_GetId( ISpObjectTokenCategory *iface,
499 LPWSTR *id )
501 FIXME( "stub\n" );
502 return E_NOTIMPL;
505 static HRESULT WINAPI token_category_GetDataKey( ISpObjectTokenCategory *iface,
506 SPDATAKEYLOCATION location,
507 ISpDataKey **data_key )
509 FIXME( "stub\n" );
510 return E_NOTIMPL;
513 struct token_enum
515 ISpObjectTokenEnumBuilder ISpObjectTokenEnumBuilder_iface;
516 LONG ref;
518 BOOL init;
519 WCHAR *req, *opt;
520 ULONG count;
521 HKEY key;
522 DWORD index;
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;
538 HRESULT hr;
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 );
564 fail:
565 ISpObjectTokenEnumBuilder_Release( builder );
566 return hr;
569 static HRESULT WINAPI token_category_SetDefaultTokenId( ISpObjectTokenCategory *iface,
570 LPCWSTR id )
572 FIXME( "stub\n" );
573 return E_NOTIMPL;
576 static HRESULT WINAPI token_category_GetDefaultTokenId( ISpObjectTokenCategory *iface,
577 LPWSTR *id )
579 struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
580 struct data_key *this_data_key;
581 LONG res;
582 WCHAR regvalue[512];
583 DWORD regvalue_size = sizeof( regvalue );
585 FIXME( "(%p)->(%p): semi-stub\n", iface, id );
587 if (!This->data_key)
588 return SPERR_UNINITIALIZED;
590 if (!id)
591 return E_POINTER;
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, &regvalue, &regvalue_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 );
604 return res;
607 *id = CoTaskMemAlloc( regvalue_size );
608 wcscpy( *id, regvalue );
610 return S_OK;
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) );
641 HRESULT hr;
643 if (!This) return E_OUTOFMEMORY;
644 This->ISpObjectTokenCategory_iface.lpVtbl = &token_category_vtbl;
645 This->ref = 1;
646 This->data_key = NULL;
648 hr = ISpObjectTokenCategory_QueryInterface( &This->ISpObjectTokenCategory_iface, iid, obj );
650 ISpObjectTokenCategory_Release( &This->ISpObjectTokenCategory_iface );
651 return hr;
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 );
666 *obj = iface;
667 return S_OK;
670 FIXME( "interface %s not implemented\n", debugstr_guid( iid ) );
671 *obj = NULL;
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 );
681 return 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 );
691 if (!ref)
693 if (This->key)
694 RegCloseKey(This->key);
695 heap_free( This->req );
696 heap_free( This->opt );
697 heap_free( This );
700 return ref;
703 static HRESULT WINAPI token_enum_Next( ISpObjectTokenEnumBuilder *iface,
704 ULONG num, ISpObjectToken **tokens,
705 ULONG *fetched )
707 struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface );
708 struct object_token *object;
709 HRESULT hr;
710 DWORD retCode;
711 WCHAR *subkey_name;
712 HKEY sub_key;
713 DWORD size;
715 TRACE( "(%p)->(%lu %p %p)\n", This, num, tokens, fetched );
717 if (!This->init) return SPERR_UNINITIALIZED;
718 if (fetched) *fetched = 0;
720 *tokens = NULL;
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);
725 if (!subkey_name)
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);
732 return S_FALSE;
735 This->index++;
737 if (RegOpenKeyExW( This->key, subkey_name, 0, KEY_READ, &sub_key ) != ERROR_SUCCESS)
739 heap_free(subkey_name);
740 return E_FAIL;
743 hr = token_create( NULL, &IID_ISpObjectToken, (void**)tokens );
744 if (FAILED(hr))
746 heap_free(subkey_name);
747 return hr;
750 object = impl_from_ISpObjectToken( *tokens );
751 object->token_key = sub_key;
752 object->token_id = subkey_name;
754 if (fetched) *fetched = 1;
755 return hr;
758 static HRESULT WINAPI token_enum_Skip( ISpObjectTokenEnumBuilder *iface,
759 ULONG num )
761 FIXME( "stub\n" );
762 return E_NOTIMPL;
765 static HRESULT WINAPI token_enum_Reset( ISpObjectTokenEnumBuilder *iface)
767 FIXME( "stub\n" );
768 return E_NOTIMPL;
771 static HRESULT WINAPI token_enum_Clone( ISpObjectTokenEnumBuilder *iface,
772 IEnumSpObjectTokens **clone )
774 FIXME( "stub\n" );
775 return E_NOTIMPL;
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;
784 HRESULT hr;
785 WCHAR *subkey;
786 DWORD size;
787 LONG ret;
788 HKEY key;
790 TRACE( "%p, %lu, %p\n", This, index, token );
792 if (!This->init)
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);
798 if (!subkey)
799 return E_OUTOFMEMORY;
801 ret = RegEnumKeyExW(This->key, index, subkey, &size, NULL, NULL, NULL, NULL);
802 if (ret != ERROR_SUCCESS)
804 heap_free(subkey);
805 return HRESULT_FROM_WIN32(ret);
808 ret = RegOpenKeyExW (This->key, subkey, 0, KEY_READ, &key);
809 if (ret != ERROR_SUCCESS)
811 heap_free(subkey);
812 return HRESULT_FROM_WIN32(ret);
815 hr = token_create( NULL, &IID_ISpObjectToken, (void**)&subtoken );
816 if (FAILED(hr))
818 heap_free(subkey);
819 return hr;
822 object = impl_from_ISpObjectToken( subtoken );
823 object->token_key = key;
824 object->token_id = subkey;
826 *token = subtoken;
828 return hr;
831 static HRESULT WINAPI token_enum_GetCount( ISpObjectTokenEnumBuilder *iface,
832 ULONG *count )
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;
841 return S_OK;
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;
853 if (req)
855 This->req = heap_strdupW( req );
856 if (!This->req) goto out_of_mem;
859 if (opt)
861 This->opt = heap_strdupW( opt );
862 if (!This->opt) goto out_of_mem;
865 This->init = TRUE;
866 return S_OK;
868 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 )
876 FIXME( "stub\n" );
877 return E_NOTIMPL;
880 static HRESULT WINAPI token_enum_AddTokensFromDataKey( ISpObjectTokenEnumBuilder *iface,
881 ISpDataKey *data_key,
882 LPCWSTR sub_key, LPCWSTR cat_id )
884 FIXME( "stub\n" );
885 return E_NOTIMPL;
888 static HRESULT WINAPI token_enum_AddTokensFromTokenEnum( ISpObjectTokenEnumBuilder *iface,
889 IEnumSpObjectTokens *token_enum )
891 FIXME( "stub\n" );
892 return E_NOTIMPL;
895 static HRESULT WINAPI token_enum_Sort( ISpObjectTokenEnumBuilder *iface,
896 LPCWSTR first )
898 FIXME( "stub\n" );
899 return E_NOTIMPL;
902 const struct ISpObjectTokenEnumBuilderVtbl token_enum_vtbl =
904 token_enum_QueryInterface,
905 token_enum_AddRef,
906 token_enum_Release,
907 token_enum_Next,
908 token_enum_Skip,
909 token_enum_Reset,
910 token_enum_Clone,
911 token_enum_Item,
912 token_enum_GetCount,
913 token_enum_SetAttribs,
914 token_enum_AddTokens,
915 token_enum_AddTokensFromDataKey,
916 token_enum_AddTokensFromTokenEnum,
917 token_enum_Sort
920 HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj )
922 struct token_enum *This = heap_alloc( sizeof(*This) );
923 HRESULT hr;
925 if (!This) return E_OUTOFMEMORY;
926 This->ISpObjectTokenEnumBuilder_iface.lpVtbl = &token_enum_vtbl;
927 This->ref = 1;
928 This->req = NULL;
929 This->opt = NULL;
930 This->init = FALSE;
931 This->count = 0;
932 This->key = NULL;
933 This->index = 0;
935 hr = ISpObjectTokenEnumBuilder_QueryInterface( &This->ISpObjectTokenEnumBuilder_iface, iid, obj );
937 ISpObjectTokenEnumBuilder_Release( &This->ISpObjectTokenEnumBuilder_iface );
938 return hr;
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 );
953 *obj = iface;
954 return S_OK;
957 FIXME( "interface %s not implemented\n", debugstr_guid( iid ) );
958 *obj = NULL;
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 );
968 return 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 );
978 if (!ref)
980 if (This->token_key) RegCloseKey( This->token_key );
981 free(This->token_id);
982 heap_free( This );
985 return ref;
988 static HRESULT WINAPI token_SetData( ISpObjectToken *iface,
989 LPCWSTR name, ULONG size,
990 const BYTE *data )
992 FIXME( "stub\n" );
993 return E_NOTIMPL;
996 static HRESULT WINAPI token_GetData( ISpObjectToken *iface,
997 LPCWSTR name, ULONG *size,
998 BYTE *data )
1000 FIXME( "stub\n" );
1001 return E_NOTIMPL;
1004 static HRESULT WINAPI token_SetStringValue( ISpObjectToken *iface,
1005 LPCWSTR name, LPCWSTR value )
1007 FIXME( "stub\n" );
1008 return E_NOTIMPL;
1011 static HRESULT WINAPI token_GetStringValue( ISpObjectToken *iface,
1012 LPCWSTR name, LPWSTR *value )
1014 FIXME( "stub\n" );
1015 return E_NOTIMPL;
1018 static HRESULT WINAPI token_SetDWORD( ISpObjectToken *iface,
1019 LPCWSTR name, DWORD value )
1021 FIXME( "stub\n" );
1022 return E_NOTIMPL;
1025 static HRESULT WINAPI token_GetDWORD( ISpObjectToken *iface,
1026 LPCWSTR name, DWORD *pdwValue )
1028 FIXME( "stub\n" );
1029 return E_NOTIMPL;
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;
1037 HRESULT hr;
1038 HKEY key;
1039 LONG ret;
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);
1048 if (FAILED(hr))
1050 RegCloseKey(key);
1051 return hr;
1054 hr = ISpRegDataKey_SetKey(spregkey, key, FALSE);
1055 if (FAILED(hr))
1057 RegCloseKey(key);
1058 ISpRegDataKey_Release(spregkey);
1059 return hr;
1062 hr = ISpRegDataKey_QueryInterface(spregkey, &IID_ISpDataKey, (void**)sub_key);
1063 ISpRegDataKey_Release(spregkey);
1065 return hr;
1068 static HRESULT WINAPI token_CreateKey( ISpObjectToken *iface,
1069 LPCWSTR name, ISpDataKey **sub_key )
1071 FIXME( "stub\n" );
1072 return E_NOTIMPL;
1075 static HRESULT WINAPI token_DeleteKey( ISpObjectToken *iface,
1076 LPCWSTR name )
1078 FIXME( "stub\n" );
1079 return E_NOTIMPL;
1082 static HRESULT WINAPI token_DeleteValue( ISpObjectToken *iface,
1083 LPCWSTR name )
1085 FIXME( "stub\n" );
1086 return E_NOTIMPL;
1089 static HRESULT WINAPI token_EnumKeys( ISpObjectToken *iface,
1090 ULONG index, LPWSTR *sub_key )
1092 FIXME( "stub\n" );
1093 return E_NOTIMPL;
1096 static HRESULT WINAPI token_EnumValues( ISpObjectToken *iface,
1097 ULONG index, LPWSTR *value )
1099 FIXME( "stub\n" );
1100 return E_NOTIMPL;
1103 static HRESULT WINAPI token_SetId( ISpObjectToken *iface,
1104 LPCWSTR category_id, LPCWSTR token_id,
1105 BOOL create )
1107 struct object_token *This = impl_from_ISpObjectToken( iface );
1108 BOOL res;
1109 HRESULT hr;
1110 HKEY root, key;
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;
1123 if (create)
1124 res = RegCreateKeyExW( root, subkey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL);
1125 else
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);
1132 return S_OK;
1135 static HRESULT WINAPI token_GetId( ISpObjectToken *iface,
1136 LPWSTR *token_id )
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;
1145 if (!token_id)
1146 return E_POINTER;
1148 if (!This->token_id)
1150 FIXME("Loading default category not supported.\n");
1151 return E_POINTER;
1154 *token_id = CoTaskMemAlloc( (wcslen(This->token_id) + 1) * sizeof(WCHAR));
1155 if (!*token_id)
1156 return E_OUTOFMEMORY;
1158 wcscpy(*token_id, This->token_id);
1159 return S_OK;
1162 static HRESULT WINAPI token_GetCategory( ISpObjectToken *iface,
1163 ISpObjectTokenCategory **category )
1165 FIXME( "stub\n" );
1166 return E_NOTIMPL;
1169 static HRESULT WINAPI token_CreateInstance( ISpObjectToken *iface,
1170 IUnknown *outer,
1171 DWORD class_context,
1172 REFIID riid,
1173 void **object )
1175 FIXME( "stub\n" );
1176 return E_NOTIMPL;
1179 static HRESULT WINAPI token_GetStorageFileName( ISpObjectToken *iface,
1180 REFCLSID caller,
1181 LPCWSTR key_name,
1182 LPCWSTR filename,
1183 ULONG folder,
1184 LPWSTR *filepath )
1186 FIXME( "stub\n" );
1187 return E_NOTIMPL;
1190 static HRESULT WINAPI token_RemoveStorageFileName( ISpObjectToken *iface,
1191 REFCLSID caller,
1192 LPCWSTR key_name,
1193 BOOL delete_file )
1195 FIXME( "stub\n" );
1196 return E_NOTIMPL;
1199 static HRESULT WINAPI token_Remove( ISpObjectToken *iface,
1200 REFCLSID caller )
1202 FIXME( "stub\n" );
1203 return E_NOTIMPL;
1206 static HRESULT WINAPI token_IsUISupported( ISpObjectToken *iface,
1207 LPCWSTR ui_type,
1208 void *extra_data,
1209 ULONG extra_data_size,
1210 IUnknown *object,
1211 BOOL *supported )
1213 FIXME( "stub\n" );
1214 return E_NOTIMPL;
1217 static HRESULT WINAPI token_DisplayUI( ISpObjectToken *iface,
1218 HWND parent,
1219 LPCWSTR title,
1220 LPCWSTR ui_type,
1221 void *extra_data,
1222 ULONG extra_data_size,
1223 IUnknown *object )
1225 FIXME( "stub\n" );
1226 return E_NOTIMPL;
1229 static HRESULT WINAPI token_MatchesAttributes( ISpObjectToken *iface,
1230 LPCWSTR attributes,
1231 BOOL *matches )
1233 FIXME( "stub\n" );
1234 return E_NOTIMPL;
1237 const struct ISpObjectTokenVtbl token_vtbl =
1239 token_QueryInterface,
1240 token_AddRef,
1241 token_Release,
1242 token_SetData,
1243 token_GetData,
1244 token_SetStringValue,
1245 token_GetStringValue,
1246 token_SetDWORD,
1247 token_GetDWORD,
1248 token_OpenKey,
1249 token_CreateKey,
1250 token_DeleteKey,
1251 token_DeleteValue,
1252 token_EnumKeys,
1253 token_EnumValues,
1254 token_SetId,
1255 token_GetId,
1256 token_GetCategory,
1257 token_CreateInstance,
1258 token_GetStorageFileName,
1259 token_RemoveStorageFileName,
1260 token_Remove,
1261 token_IsUISupported,
1262 token_DisplayUI,
1263 token_MatchesAttributes
1266 HRESULT token_create( IUnknown *outer, REFIID iid, void **obj )
1268 struct object_token *This = heap_alloc( sizeof(*This) );
1269 HRESULT hr;
1271 if (!This) return E_OUTOFMEMORY;
1272 This->ISpObjectToken_iface.lpVtbl = &token_vtbl;
1273 This->ref = 1;
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 );
1281 return hr;