sapi: Implement SpObjectTokenCategory::SetId().
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c
index b70dc50..9262641 100644
--- a/dlls/sapi/token.c
+++ b/dlls/sapi/token.c
@@ -231,6 +231,8 @@
{
ISpObjectTokenCategory ISpObjectTokenCategory_iface;
LONG ref;
+
+ ISpRegDataKey *data_key;
};
struct token_category *impl_from_ISpObjectTokenCategory( ISpObjectTokenCategory *iface )
@@ -277,6 +279,7 @@
if (!ref)
{
+ if (This->data_key) ISpRegDataKey_Release( This->data_key );
heap_free( This );
}
return ref;
@@ -368,11 +371,69 @@
return E_NOTIMPL;
}
+static HRESULT parse_cat_id( const WCHAR *str, HKEY *root, const WCHAR **sub_key )
+{
+ static const WCHAR HKLM[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E','\\'};
+ static const WCHAR HKCU[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\'};
+ struct table
+ {
+ const WCHAR *name;
+ int size;
+ HKEY key;
+ } table[] =
+ {
+ { HKLM, sizeof(HKLM), HKEY_LOCAL_MACHINE },
+ { HKCU, sizeof(HKCU), HKEY_CURRENT_USER },
+ { NULL }
+ };
+ struct table *ptr;
+ int len = strlenW( str );
+
+ for (ptr = table; ptr->name; ptr++)
+ {
+ if (len >= ptr->size / sizeof(ptr->name[0]) && !memcmp( str, ptr->name, ptr->size ))
+ {
+ *root = ptr->key;
+ *sub_key = str + ptr->size / sizeof(ptr->name[0]);
+ return S_OK;
+ }
+ }
+ return S_FALSE;
+}
+
static HRESULT WINAPI token_category_SetId( ISpObjectTokenCategory *iface,
LPCWSTR id, BOOL create )
{
- FIXME( "stub\n" );
- return E_NOTIMPL;
+ struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
+ HKEY root, key;
+ const WCHAR *subkey;
+ LONG res;
+ HRESULT hr;
+
+ TRACE( "(%p)->(%s %d)\n", This, debugstr_w( id ), create );
+
+ if (This->data_key) return SPERR_ALREADY_INITIALIZED;
+
+ hr = parse_cat_id( id, &root, &subkey );
+ if (hr != S_OK) return SPERR_INVALID_REGISTRY_KEY;
+
+ if (create) FIXME( "Ignoring create\n" );
+
+ res = RegOpenKeyExW( root, subkey, 0, KEY_ALL_ACCESS, &key );
+ if (res) return SPERR_INVALID_REGISTRY_KEY;
+
+ hr = CoCreateInstance( &CLSID_SpDataKey, NULL, CLSCTX_ALL,
+ &IID_ISpRegDataKey, (void **)&This->data_key );
+ if (FAILED(hr)) goto fail;
+
+ hr = ISpRegDataKey_SetKey( This->data_key, key, FALSE );
+ if (FAILED(hr)) goto fail;
+
+ return hr;
+
+fail:
+ RegCloseKey( key );
+ return hr;
}
static HRESULT WINAPI token_category_GetId( ISpObjectTokenCategory *iface,
@@ -445,6 +506,7 @@
if (!This) return E_OUTOFMEMORY;
This->ISpObjectTokenCategory_iface.lpVtbl = &token_category_vtbl;
This->ref = 1;
+ This->data_key = NULL;
hr = ISpObjectTokenCategory_QueryInterface( &This->ISpObjectTokenCategory_iface, iid, obj );