sapi: Implement ISpRegDataKey GetStringValue.
[wine.git] / dlls / sapi / token.c
blobb5cfc45e5a32cd64b3f21bf0d7e365e9c29f3878
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 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 );
62 *obj = iface;
63 return S_OK;
66 FIXME( "interface %s not implemented\n", debugstr_guid( iid ) );
67 *obj = NULL;
68 return E_NOINTERFACE;
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 = %lu\n", This, ref );
77 return 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 = %lu\n", This, ref );
87 if (!ref)
89 if (This->key) RegCloseKey( This->key );
90 heap_free( This );
93 return ref;
96 static HRESULT WINAPI data_key_SetData( ISpRegDataKey *iface, LPCWSTR name,
97 ULONG size, const BYTE *data )
99 FIXME( "stub\n" );
100 return E_NOTIMPL;
103 static HRESULT WINAPI data_key_GetData( ISpRegDataKey *iface, LPCWSTR name,
104 ULONG *size, BYTE *data )
106 FIXME( "stub\n" );
107 return E_NOTIMPL;
110 static HRESULT WINAPI data_key_SetStringValue( ISpRegDataKey *iface,
111 LPCWSTR name, LPCWSTR value )
113 FIXME( "stub\n" );
114 return E_NOTIMPL;
117 static HRESULT WINAPI data_key_GetStringValue( ISpRegDataKey *iface,
118 LPCWSTR name, LPWSTR *value )
120 struct data_key *This = impl_from_ISpRegDataKey( iface );
121 DWORD ret, size;
122 WCHAR *content;
124 TRACE( "%p, %s, %p\n", This, debugstr_w(name), value);
126 if (!This->key)
127 return E_HANDLE;
129 size = 0;
130 ret = RegGetValueW( This->key, NULL, name, RRF_RT_REG_SZ, NULL, NULL, &size );
131 if (ret != ERROR_SUCCESS)
132 return SPERR_NOT_FOUND;
134 content = CoTaskMemAlloc(size);
135 if (!content)
136 return E_OUTOFMEMORY;
138 ret = RegGetValueW( This->key, NULL, name, RRF_RT_REG_SZ, NULL, content, &size );
139 if (ret != ERROR_SUCCESS)
141 CoTaskMemFree(content);
142 return HRESULT_FROM_WIN32(ret);
145 *value = content;
146 return S_OK;
149 static HRESULT WINAPI data_key_SetDWORD( ISpRegDataKey *iface,
150 LPCWSTR name, DWORD value )
152 FIXME( "stub\n" );
153 return E_NOTIMPL;
156 static HRESULT WINAPI data_key_GetDWORD( ISpRegDataKey *iface,
157 LPCWSTR name, DWORD *pdwValue )
159 FIXME( "stub\n" );
160 return E_NOTIMPL;
163 static HRESULT WINAPI data_key_OpenKey( ISpRegDataKey *iface,
164 LPCWSTR name, ISpDataKey **sub_key )
166 FIXME( "stub\n" );
167 return E_NOTIMPL;
170 static HRESULT WINAPI data_key_CreateKey( ISpRegDataKey *iface,
171 LPCWSTR name, ISpDataKey **sub_key )
173 struct data_key *This = impl_from_ISpRegDataKey( iface );
174 ISpRegDataKey *spregkey;
175 HRESULT hr;
176 HKEY key;
177 LONG res;
179 TRACE( "%p, %s, %p\n", This, debugstr_w(name), sub_key );
181 res = RegCreateKeyExW( This->key, name, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL );
182 if (res != ERROR_SUCCESS)
183 return HRESULT_FROM_WIN32(res);
185 hr = data_key_create(NULL, &IID_ISpRegDataKey, (void**)&spregkey);
186 if (SUCCEEDED(hr))
188 hr = ISpRegDataKey_SetKey(spregkey, key, FALSE);
189 if (SUCCEEDED(hr))
190 hr = ISpRegDataKey_QueryInterface(spregkey, &IID_ISpDataKey, (void**)sub_key);
191 ISpRegDataKey_Release(spregkey);
194 return hr;
197 static HRESULT WINAPI data_key_DeleteKey( ISpRegDataKey *iface, LPCWSTR name )
199 FIXME( "stub\n" );
200 return E_NOTIMPL;
203 static HRESULT WINAPI data_key_DeleteValue( ISpRegDataKey *iface, LPCWSTR name )
205 FIXME( "stub\n" );
206 return E_NOTIMPL;
209 static HRESULT WINAPI data_key_EnumKeys( ISpRegDataKey *iface,
210 ULONG index, LPWSTR *sub_key )
212 FIXME( "stub\n" );
213 return E_NOTIMPL;
216 static HRESULT WINAPI data_key_EnumValues( ISpRegDataKey *iface,
217 ULONG index, LPWSTR *value )
219 FIXME( "stub\n" );
220 return E_NOTIMPL;
223 static HRESULT WINAPI data_key_SetKey( ISpRegDataKey *iface,
224 HKEY key, BOOL read_only )
226 struct data_key *This = impl_from_ISpRegDataKey( iface );
228 TRACE( "(%p)->(%p %d)\n", This, key, read_only );
230 if (This->key) return SPERR_ALREADY_INITIALIZED;
232 This->key = key;
233 This->read_only = read_only;
234 return S_OK;
237 const struct ISpRegDataKeyVtbl data_key_vtbl =
239 data_key_QueryInterface,
240 data_key_AddRef,
241 data_key_Release,
242 data_key_SetData,
243 data_key_GetData,
244 data_key_SetStringValue,
245 data_key_GetStringValue,
246 data_key_SetDWORD,
247 data_key_GetDWORD,
248 data_key_OpenKey,
249 data_key_CreateKey,
250 data_key_DeleteKey,
251 data_key_DeleteValue,
252 data_key_EnumKeys,
253 data_key_EnumValues,
254 data_key_SetKey
257 HRESULT data_key_create( IUnknown *outer, REFIID iid, void **obj )
259 struct data_key *This = heap_alloc( sizeof(*This) );
260 HRESULT hr;
262 if (!This) return E_OUTOFMEMORY;
263 This->ISpRegDataKey_iface.lpVtbl = &data_key_vtbl;
264 This->ref = 1;
265 This->key = NULL;
266 This->read_only = FALSE;
268 hr = ISpRegDataKey_QueryInterface( &This->ISpRegDataKey_iface, iid, obj );
270 ISpRegDataKey_Release( &This->ISpRegDataKey_iface );
271 return hr;
274 struct token_category
276 ISpObjectTokenCategory ISpObjectTokenCategory_iface;
277 LONG ref;
279 ISpRegDataKey *data_key;
282 static struct token_category *impl_from_ISpObjectTokenCategory( ISpObjectTokenCategory *iface )
284 return CONTAINING_RECORD( iface, struct token_category, ISpObjectTokenCategory_iface );
287 static HRESULT WINAPI token_category_QueryInterface( ISpObjectTokenCategory *iface,
288 REFIID iid, void **obj )
290 struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
292 TRACE( "(%p)->(%s %p)\n", This, debugstr_guid( iid ), obj );
294 if (IsEqualIID( iid, &IID_IUnknown ) ||
295 IsEqualIID( iid, &IID_ISpDataKey ) ||
296 IsEqualIID( iid, &IID_ISpObjectTokenCategory ))
298 ISpObjectTokenCategory_AddRef( iface );
299 *obj = iface;
300 return S_OK;
303 FIXME( "interface %s not implemented\n", debugstr_guid( iid ) );
304 *obj = NULL;
305 return E_NOINTERFACE;
308 static ULONG WINAPI token_category_AddRef( ISpObjectTokenCategory *iface )
310 struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
311 ULONG ref = InterlockedIncrement( &This->ref );
313 TRACE( "(%p) ref = %lu\n", This, ref );
314 return ref;
317 static ULONG WINAPI token_category_Release( ISpObjectTokenCategory *iface )
319 struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
320 ULONG ref = InterlockedDecrement(&This->ref);
322 TRACE( "(%p) ref = %lu\n", This, ref );
324 if (!ref)
326 if (This->data_key) ISpRegDataKey_Release( This->data_key );
327 heap_free( This );
329 return ref;
332 static HRESULT WINAPI token_category_SetData( ISpObjectTokenCategory *iface,
333 LPCWSTR name, ULONG size,
334 const BYTE *data )
336 FIXME( "stub\n" );
337 return E_NOTIMPL;
340 static HRESULT WINAPI token_category_GetData( ISpObjectTokenCategory *iface,
341 LPCWSTR name, ULONG *size,
342 BYTE *data )
344 FIXME( "stub\n" );
345 return E_NOTIMPL;
348 static HRESULT WINAPI token_category_SetStringValue( ISpObjectTokenCategory *iface,
349 LPCWSTR name, LPCWSTR value )
351 FIXME( "stub\n" );
352 return E_NOTIMPL;
355 static HRESULT WINAPI token_category_GetStringValue( ISpObjectTokenCategory *iface,
356 LPCWSTR name, LPWSTR *value )
358 FIXME( "stub\n" );
359 return E_NOTIMPL;
362 static HRESULT WINAPI token_category_SetDWORD( ISpObjectTokenCategory *iface,
363 LPCWSTR name, DWORD value )
365 FIXME( "stub\n" );
366 return E_NOTIMPL;
369 static HRESULT WINAPI token_category_GetDWORD( ISpObjectTokenCategory *iface,
370 LPCWSTR name, DWORD *pdwValue )
372 FIXME( "stub\n" );
373 return E_NOTIMPL;
376 static HRESULT WINAPI token_category_OpenKey( ISpObjectTokenCategory *iface,
377 LPCWSTR name, ISpDataKey **sub_key )
379 FIXME( "stub\n" );
380 return E_NOTIMPL;
383 static HRESULT WINAPI token_category_CreateKey( ISpObjectTokenCategory *iface,
384 LPCWSTR name, ISpDataKey **sub_key )
386 FIXME( "stub\n" );
387 return E_NOTIMPL;
390 static HRESULT WINAPI token_category_DeleteKey( ISpObjectTokenCategory *iface,
391 LPCWSTR name )
393 FIXME( "stub\n" );
394 return E_NOTIMPL;
397 static HRESULT WINAPI token_category_DeleteValue( ISpObjectTokenCategory *iface,
398 LPCWSTR name )
400 FIXME( "stub\n" );
401 return E_NOTIMPL;
404 static HRESULT WINAPI token_category_EnumKeys( ISpObjectTokenCategory *iface,
405 ULONG index, LPWSTR *sub_key )
407 FIXME( "stub\n" );
408 return E_NOTIMPL;
411 static HRESULT WINAPI token_category_EnumValues( ISpObjectTokenCategory *iface,
412 ULONG index, LPWSTR *value )
414 FIXME( "stub\n" );
415 return E_NOTIMPL;
418 static HRESULT parse_cat_id( const WCHAR *str, HKEY *root, const WCHAR **sub_key )
420 struct table
422 const WCHAR *name;
423 unsigned int len;
424 HKEY key;
425 } table[] =
427 #define X(s) s, ARRAY_SIZE(s) - 1
428 { X(L"HKEY_LOCAL_MACHINE\\"), HKEY_LOCAL_MACHINE },
429 { X(L"HKEY_CURRENT_USER\\"), HKEY_CURRENT_USER },
430 { NULL }
431 #undef X
433 struct table *ptr;
434 int len = lstrlenW( str );
436 for (ptr = table; ptr->name; ptr++)
438 if (len >= ptr->len && !wcsncmp( str, ptr->name, ptr->len ))
440 *root = ptr->key;
441 *sub_key = str + ptr->len;
442 return S_OK;
445 return S_FALSE;
448 static HRESULT WINAPI token_category_SetId( ISpObjectTokenCategory *iface,
449 LPCWSTR id, BOOL create )
451 struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
452 HKEY root, key;
453 const WCHAR *subkey;
454 LONG res;
455 HRESULT hr;
457 TRACE( "(%p)->(%s %d)\n", This, debugstr_w( id ), create );
459 if (This->data_key) return SPERR_ALREADY_INITIALIZED;
461 hr = parse_cat_id( id, &root, &subkey );
462 if (hr != S_OK) return SPERR_INVALID_REGISTRY_KEY;
464 if (create)
465 res = RegCreateKeyExW( root, subkey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL );
466 else
467 res = RegOpenKeyExW( root, subkey, 0, KEY_ALL_ACCESS, &key );
468 if (res) return SPERR_INVALID_REGISTRY_KEY;
470 hr = CoCreateInstance( &CLSID_SpDataKey, NULL, CLSCTX_ALL,
471 &IID_ISpRegDataKey, (void **)&This->data_key );
472 if (FAILED(hr)) goto fail;
474 hr = ISpRegDataKey_SetKey( This->data_key, key, FALSE );
475 if (FAILED(hr)) goto fail;
477 return hr;
479 fail:
480 RegCloseKey( key );
481 return hr;
484 static HRESULT WINAPI token_category_GetId( ISpObjectTokenCategory *iface,
485 LPWSTR *id )
487 FIXME( "stub\n" );
488 return E_NOTIMPL;
491 static HRESULT WINAPI token_category_GetDataKey( ISpObjectTokenCategory *iface,
492 SPDATAKEYLOCATION location,
493 ISpDataKey **data_key )
495 FIXME( "stub\n" );
496 return E_NOTIMPL;
499 static HRESULT WINAPI token_category_EnumTokens( ISpObjectTokenCategory *iface,
500 LPCWSTR req, LPCWSTR opt,
501 IEnumSpObjectTokens **enum_tokens )
503 struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
504 ISpObjectTokenEnumBuilder *builder;
505 HRESULT hr;
507 FIXME( "(%p)->(%s %s %p): semi-stub\n", This, debugstr_w( req ), debugstr_w( opt ), enum_tokens );
509 if (!This->data_key) return SPERR_UNINITIALIZED;
511 hr = CoCreateInstance( &CLSID_SpObjectTokenEnum, NULL, CLSCTX_ALL,
512 &IID_ISpObjectTokenEnumBuilder, (void **)&builder );
513 if (FAILED(hr)) return hr;
515 hr = ISpObjectTokenEnumBuilder_SetAttribs( builder, req, opt );
516 if (FAILED(hr)) goto fail;
518 /* FIXME: Build the enumerator */
520 hr = ISpObjectTokenEnumBuilder_QueryInterface( builder, &IID_IEnumSpObjectTokens,
521 (void **)enum_tokens );
523 fail:
524 ISpObjectTokenEnumBuilder_Release( builder );
525 return hr;
528 static HRESULT WINAPI token_category_SetDefaultTokenId( ISpObjectTokenCategory *iface,
529 LPCWSTR id )
531 FIXME( "stub\n" );
532 return E_NOTIMPL;
535 static HRESULT WINAPI token_category_GetDefaultTokenId( ISpObjectTokenCategory *iface,
536 LPWSTR *id )
538 struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
539 struct data_key *this_data_key;
540 LONG res;
541 WCHAR regvalue[512];
542 DWORD regvalue_size = sizeof( regvalue );
544 FIXME( "(%p)->(%p): semi-stub\n", iface, id );
546 if (!This->data_key)
547 return SPERR_UNINITIALIZED;
549 if (!id)
550 return E_POINTER;
552 /* todo: check HKCU's DefaultTokenId before */
554 this_data_key = impl_from_ISpRegDataKey( This->data_key );
556 res = RegGetValueW( this_data_key->key, NULL, L"DefaultDefaultTokenId", RRF_RT_REG_SZ,
557 NULL, &regvalue, &regvalue_size);
558 if (res == ERROR_FILE_NOT_FOUND) {
559 return SPERR_NOT_FOUND;
560 } else if (res != ERROR_SUCCESS) {
561 /* probably not the correct return value */
562 FIXME( "returning %08lx\n", res );
563 return res;
566 *id = CoTaskMemAlloc( regvalue_size );
567 wcscpy( *id, regvalue );
569 return S_OK;
572 const struct ISpObjectTokenCategoryVtbl token_category_vtbl =
574 token_category_QueryInterface,
575 token_category_AddRef,
576 token_category_Release,
577 token_category_SetData,
578 token_category_GetData,
579 token_category_SetStringValue,
580 token_category_GetStringValue,
581 token_category_SetDWORD,
582 token_category_GetDWORD,
583 token_category_OpenKey,
584 token_category_CreateKey,
585 token_category_DeleteKey,
586 token_category_DeleteValue,
587 token_category_EnumKeys,
588 token_category_EnumValues,
589 token_category_SetId,
590 token_category_GetId,
591 token_category_GetDataKey,
592 token_category_EnumTokens,
593 token_category_SetDefaultTokenId,
594 token_category_GetDefaultTokenId,
597 HRESULT token_category_create( IUnknown *outer, REFIID iid, void **obj )
599 struct token_category *This = heap_alloc( sizeof(*This) );
600 HRESULT hr;
602 if (!This) return E_OUTOFMEMORY;
603 This->ISpObjectTokenCategory_iface.lpVtbl = &token_category_vtbl;
604 This->ref = 1;
605 This->data_key = NULL;
607 hr = ISpObjectTokenCategory_QueryInterface( &This->ISpObjectTokenCategory_iface, iid, obj );
609 ISpObjectTokenCategory_Release( &This->ISpObjectTokenCategory_iface );
610 return hr;
613 struct token_enum
615 ISpObjectTokenEnumBuilder ISpObjectTokenEnumBuilder_iface;
616 LONG ref;
618 BOOL init;
619 WCHAR *req, *opt;
620 ULONG count;
623 static struct token_enum *impl_from_ISpObjectTokenEnumBuilder( ISpObjectTokenEnumBuilder *iface )
625 return CONTAINING_RECORD( iface, struct token_enum, ISpObjectTokenEnumBuilder_iface );
628 static HRESULT WINAPI token_enum_QueryInterface( ISpObjectTokenEnumBuilder *iface,
629 REFIID iid, void **obj )
631 struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface );
633 TRACE( "(%p)->(%s %p)\n", This, debugstr_guid( iid ), obj );
635 if (IsEqualIID( iid, &IID_IUnknown ) ||
636 IsEqualIID( iid, &IID_IEnumSpObjectTokens ) ||
637 IsEqualIID( iid, &IID_ISpObjectTokenEnumBuilder ))
639 ISpObjectTokenEnumBuilder_AddRef( iface );
640 *obj = iface;
641 return S_OK;
644 FIXME( "interface %s not implemented\n", debugstr_guid( iid ) );
645 *obj = NULL;
646 return E_NOINTERFACE;
649 static ULONG WINAPI token_enum_AddRef( ISpObjectTokenEnumBuilder *iface )
651 struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface );
652 ULONG ref = InterlockedIncrement( &This->ref );
654 TRACE( "(%p) ref = %lu\n", This, ref );
655 return ref;
658 static ULONG WINAPI token_enum_Release( ISpObjectTokenEnumBuilder *iface )
660 struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface );
661 ULONG ref = InterlockedDecrement(&This->ref);
663 TRACE( "(%p) ref = %lu\n", This, ref );
665 if (!ref)
667 heap_free( This->req );
668 heap_free( This->opt );
669 heap_free( This );
672 return ref;
675 static HRESULT WINAPI token_enum_Next( ISpObjectTokenEnumBuilder *iface,
676 ULONG num, ISpObjectToken **tokens,
677 ULONG *fetched )
679 struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface );
681 TRACE( "(%p)->(%lu %p %p)\n", This, num, tokens, fetched );
683 if (!This->init) return SPERR_UNINITIALIZED;
685 FIXME( "semi-stub: Returning an empty enumerator\n" );
687 if (fetched) *fetched = 0;
688 return S_FALSE;
691 static HRESULT WINAPI token_enum_Skip( ISpObjectTokenEnumBuilder *iface,
692 ULONG num )
694 FIXME( "stub\n" );
695 return E_NOTIMPL;
698 static HRESULT WINAPI token_enum_Reset( ISpObjectTokenEnumBuilder *iface)
700 FIXME( "stub\n" );
701 return E_NOTIMPL;
704 static HRESULT WINAPI token_enum_Clone( ISpObjectTokenEnumBuilder *iface,
705 IEnumSpObjectTokens **clone )
707 FIXME( "stub\n" );
708 return E_NOTIMPL;
711 static HRESULT WINAPI token_enum_Item( ISpObjectTokenEnumBuilder *iface,
712 ULONG index, ISpObjectToken **token )
714 FIXME( "stub\n" );
715 return E_NOTIMPL;
718 static HRESULT WINAPI token_enum_GetCount( ISpObjectTokenEnumBuilder *iface,
719 ULONG *count )
721 struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface );
723 TRACE( "(%p)->(%p)\n", This, count );
725 if (!This->init) return SPERR_UNINITIALIZED;
727 *count = This->count;
728 return S_OK;
731 static HRESULT WINAPI token_enum_SetAttribs( ISpObjectTokenEnumBuilder *iface,
732 LPCWSTR req, LPCWSTR opt)
734 struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface );
736 TRACE( "(%p)->(%s %s)\n", This, debugstr_w( req ), debugstr_w( opt ) );
738 if (This->init) return SPERR_ALREADY_INITIALIZED;
740 if (req)
742 This->req = heap_strdupW( req );
743 if (!This->req) goto out_of_mem;
746 if (opt)
748 This->opt = heap_strdupW( opt );
749 if (!This->opt) goto out_of_mem;
752 This->init = TRUE;
753 return S_OK;
755 out_of_mem:
756 heap_free( This->req );
757 return E_OUTOFMEMORY;
760 static HRESULT WINAPI token_enum_AddTokens( ISpObjectTokenEnumBuilder *iface,
761 ULONG num, ISpObjectToken **tokens )
763 FIXME( "stub\n" );
764 return E_NOTIMPL;
767 static HRESULT WINAPI token_enum_AddTokensFromDataKey( ISpObjectTokenEnumBuilder *iface,
768 ISpDataKey *data_key,
769 LPCWSTR sub_key, LPCWSTR cat_id )
771 FIXME( "stub\n" );
772 return E_NOTIMPL;
775 static HRESULT WINAPI token_enum_AddTokensFromTokenEnum( ISpObjectTokenEnumBuilder *iface,
776 IEnumSpObjectTokens *token_enum )
778 FIXME( "stub\n" );
779 return E_NOTIMPL;
782 static HRESULT WINAPI token_enum_Sort( ISpObjectTokenEnumBuilder *iface,
783 LPCWSTR first )
785 FIXME( "stub\n" );
786 return E_NOTIMPL;
789 const struct ISpObjectTokenEnumBuilderVtbl token_enum_vtbl =
791 token_enum_QueryInterface,
792 token_enum_AddRef,
793 token_enum_Release,
794 token_enum_Next,
795 token_enum_Skip,
796 token_enum_Reset,
797 token_enum_Clone,
798 token_enum_Item,
799 token_enum_GetCount,
800 token_enum_SetAttribs,
801 token_enum_AddTokens,
802 token_enum_AddTokensFromDataKey,
803 token_enum_AddTokensFromTokenEnum,
804 token_enum_Sort
807 HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj )
809 struct token_enum *This = heap_alloc( sizeof(*This) );
810 HRESULT hr;
812 if (!This) return E_OUTOFMEMORY;
813 This->ISpObjectTokenEnumBuilder_iface.lpVtbl = &token_enum_vtbl;
814 This->ref = 1;
815 This->req = NULL;
816 This->opt = NULL;
817 This->init = FALSE;
818 This->count = 0;
820 hr = ISpObjectTokenEnumBuilder_QueryInterface( &This->ISpObjectTokenEnumBuilder_iface, iid, obj );
822 ISpObjectTokenEnumBuilder_Release( &This->ISpObjectTokenEnumBuilder_iface );
823 return hr;
826 struct object_token
828 ISpObjectToken ISpObjectToken_iface;
829 LONG ref;
831 HKEY token_key;
832 WCHAR *token_id;
835 static struct object_token *impl_from_ISpObjectToken( ISpObjectToken *iface )
837 return CONTAINING_RECORD( iface, struct object_token, ISpObjectToken_iface );
840 static HRESULT WINAPI token_QueryInterface( ISpObjectToken *iface,
841 REFIID iid, void **obj )
843 struct object_token *This = impl_from_ISpObjectToken( iface );
845 TRACE( "(%p)->(%s %p)\n", This, debugstr_guid( iid ), obj );
847 if (IsEqualIID( iid, &IID_IUnknown ) ||
848 IsEqualIID( iid, &IID_ISpDataKey ) ||
849 IsEqualIID( iid, &IID_ISpObjectToken ))
851 ISpObjectToken_AddRef( iface );
852 *obj = iface;
853 return S_OK;
856 FIXME( "interface %s not implemented\n", debugstr_guid( iid ) );
857 *obj = NULL;
858 return E_NOINTERFACE;
861 static ULONG WINAPI token_AddRef( ISpObjectToken *iface )
863 struct object_token *This = impl_from_ISpObjectToken( iface );
864 ULONG ref = InterlockedIncrement( &This->ref );
866 TRACE( "(%p) ref = %lu\n", This, ref );
867 return ref;
870 static ULONG WINAPI token_Release( ISpObjectToken *iface )
872 struct object_token *This = impl_from_ISpObjectToken( iface );
873 ULONG ref = InterlockedDecrement(&This->ref);
875 TRACE( "(%p) ref = %lu\n", This, ref );
877 if (!ref)
879 if (This->token_key) RegCloseKey( This->token_key );
880 free(This->token_id);
881 heap_free( This );
884 return ref;
887 static HRESULT WINAPI token_SetData( ISpObjectToken *iface,
888 LPCWSTR name, ULONG size,
889 const BYTE *data )
891 FIXME( "stub\n" );
892 return E_NOTIMPL;
895 static HRESULT WINAPI token_GetData( ISpObjectToken *iface,
896 LPCWSTR name, ULONG *size,
897 BYTE *data )
899 FIXME( "stub\n" );
900 return E_NOTIMPL;
903 static HRESULT WINAPI token_SetStringValue( ISpObjectToken *iface,
904 LPCWSTR name, LPCWSTR value )
906 FIXME( "stub\n" );
907 return E_NOTIMPL;
910 static HRESULT WINAPI token_GetStringValue( ISpObjectToken *iface,
911 LPCWSTR name, LPWSTR *value )
913 FIXME( "stub\n" );
914 return E_NOTIMPL;
917 static HRESULT WINAPI token_SetDWORD( ISpObjectToken *iface,
918 LPCWSTR name, DWORD value )
920 FIXME( "stub\n" );
921 return E_NOTIMPL;
924 static HRESULT WINAPI token_GetDWORD( ISpObjectToken *iface,
925 LPCWSTR name, DWORD *pdwValue )
927 FIXME( "stub\n" );
928 return E_NOTIMPL;
931 static HRESULT WINAPI token_OpenKey( ISpObjectToken *iface,
932 LPCWSTR name, ISpDataKey **sub_key )
934 FIXME( "stub\n" );
935 return E_NOTIMPL;
938 static HRESULT WINAPI token_CreateKey( ISpObjectToken *iface,
939 LPCWSTR name, ISpDataKey **sub_key )
941 FIXME( "stub\n" );
942 return E_NOTIMPL;
945 static HRESULT WINAPI token_DeleteKey( ISpObjectToken *iface,
946 LPCWSTR name )
948 FIXME( "stub\n" );
949 return E_NOTIMPL;
952 static HRESULT WINAPI token_DeleteValue( ISpObjectToken *iface,
953 LPCWSTR name )
955 FIXME( "stub\n" );
956 return E_NOTIMPL;
959 static HRESULT WINAPI token_EnumKeys( ISpObjectToken *iface,
960 ULONG index, LPWSTR *sub_key )
962 FIXME( "stub\n" );
963 return E_NOTIMPL;
966 static HRESULT WINAPI token_EnumValues( ISpObjectToken *iface,
967 ULONG index, LPWSTR *value )
969 FIXME( "stub\n" );
970 return E_NOTIMPL;
973 static HRESULT WINAPI token_SetId( ISpObjectToken *iface,
974 LPCWSTR category_id, LPCWSTR token_id,
975 BOOL create )
977 struct object_token *This = impl_from_ISpObjectToken( iface );
978 BOOL res;
979 HRESULT hr;
980 HKEY root, key;
981 const WCHAR *subkey;
983 FIXME( "(%p)->(%s %s %d): semi-stub\n", This, debugstr_w( category_id ),
984 debugstr_w(token_id), create );
986 if (This->token_key) return SPERR_ALREADY_INITIALIZED;
988 if (!token_id) return E_POINTER;
990 hr = parse_cat_id( token_id, &root, &subkey );
991 if (hr != S_OK) return SPERR_NOT_FOUND;
993 if (create)
994 res = RegCreateKeyExW( root, subkey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL);
995 else
996 res = RegOpenKeyExW( root, subkey, 0, KEY_ALL_ACCESS, &key );
997 if (res) return SPERR_NOT_FOUND;
999 This->token_key = key;
1000 This->token_id = wcsdup(token_id);
1002 return S_OK;
1005 static HRESULT WINAPI token_GetId( ISpObjectToken *iface,
1006 LPWSTR *token_id )
1008 struct object_token *This = impl_from_ISpObjectToken( iface );
1010 TRACE( "%p, %p\n", This, token_id);
1012 if (!This->token_key)
1013 return SPERR_UNINITIALIZED;
1015 if (!token_id)
1016 return E_POINTER;
1018 if (!This->token_id)
1020 FIXME("Loading default category not supported.\n");
1021 return E_POINTER;
1024 *token_id = CoTaskMemAlloc( (wcslen(This->token_id) + 1) * sizeof(WCHAR));
1025 if (!*token_id)
1026 return E_OUTOFMEMORY;
1028 wcscpy(*token_id, This->token_id);
1029 return S_OK;
1032 static HRESULT WINAPI token_GetCategory( ISpObjectToken *iface,
1033 ISpObjectTokenCategory **category )
1035 FIXME( "stub\n" );
1036 return E_NOTIMPL;
1039 static HRESULT WINAPI token_CreateInstance( ISpObjectToken *iface,
1040 IUnknown *outer,
1041 DWORD class_context,
1042 REFIID riid,
1043 void **object )
1045 FIXME( "stub\n" );
1046 return E_NOTIMPL;
1049 static HRESULT WINAPI token_GetStorageFileName( ISpObjectToken *iface,
1050 REFCLSID caller,
1051 LPCWSTR key_name,
1052 LPCWSTR filename,
1053 ULONG folder,
1054 LPWSTR *filepath )
1056 FIXME( "stub\n" );
1057 return E_NOTIMPL;
1060 static HRESULT WINAPI token_RemoveStorageFileName( ISpObjectToken *iface,
1061 REFCLSID caller,
1062 LPCWSTR key_name,
1063 BOOL delete_file )
1065 FIXME( "stub\n" );
1066 return E_NOTIMPL;
1069 static HRESULT WINAPI token_Remove( ISpObjectToken *iface,
1070 REFCLSID caller )
1072 FIXME( "stub\n" );
1073 return E_NOTIMPL;
1076 static HRESULT WINAPI token_IsUISupported( ISpObjectToken *iface,
1077 LPCWSTR ui_type,
1078 void *extra_data,
1079 ULONG extra_data_size,
1080 IUnknown *object,
1081 BOOL *supported )
1083 FIXME( "stub\n" );
1084 return E_NOTIMPL;
1087 static HRESULT WINAPI token_DisplayUI( ISpObjectToken *iface,
1088 HWND parent,
1089 LPCWSTR title,
1090 LPCWSTR ui_type,
1091 void *extra_data,
1092 ULONG extra_data_size,
1093 IUnknown *object )
1095 FIXME( "stub\n" );
1096 return E_NOTIMPL;
1099 static HRESULT WINAPI token_MatchesAttributes( ISpObjectToken *iface,
1100 LPCWSTR attributes,
1101 BOOL *matches )
1103 FIXME( "stub\n" );
1104 return E_NOTIMPL;
1107 const struct ISpObjectTokenVtbl token_vtbl =
1109 token_QueryInterface,
1110 token_AddRef,
1111 token_Release,
1112 token_SetData,
1113 token_GetData,
1114 token_SetStringValue,
1115 token_GetStringValue,
1116 token_SetDWORD,
1117 token_GetDWORD,
1118 token_OpenKey,
1119 token_CreateKey,
1120 token_DeleteKey,
1121 token_DeleteValue,
1122 token_EnumKeys,
1123 token_EnumValues,
1124 token_SetId,
1125 token_GetId,
1126 token_GetCategory,
1127 token_CreateInstance,
1128 token_GetStorageFileName,
1129 token_RemoveStorageFileName,
1130 token_Remove,
1131 token_IsUISupported,
1132 token_DisplayUI,
1133 token_MatchesAttributes
1136 HRESULT token_create( IUnknown *outer, REFIID iid, void **obj )
1138 struct object_token *This = heap_alloc( sizeof(*This) );
1139 HRESULT hr;
1141 if (!This) return E_OUTOFMEMORY;
1142 This->ISpObjectToken_iface.lpVtbl = &token_vtbl;
1143 This->ref = 1;
1145 This->token_key = NULL;
1146 This->token_id = NULL;
1148 hr = ISpObjectToken_QueryInterface( &This->ISpObjectToken_iface, iid, obj );
1150 ISpObjectToken_Release( &This->ISpObjectToken_iface );
1151 return hr;