[PATCH 0/6] MR1140: Sapi Token enumeration implementation.
From: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> --- dlls/sapi/token.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index 476e8d6d248..9be15e01ac0 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -496,6 +496,21 @@ static HRESULT WINAPI token_category_GetDataKey( ISpObjectTokenCategory *iface, return E_NOTIMPL; } +struct token_enum +{ + ISpObjectTokenEnumBuilder ISpObjectTokenEnumBuilder_iface; + LONG ref; + + BOOL init; + WCHAR *req, *opt; + ULONG count; +}; + +static struct token_enum *impl_from_ISpObjectTokenEnumBuilder( ISpObjectTokenEnumBuilder *iface ) +{ + return CONTAINING_RECORD( iface, struct token_enum, ISpObjectTokenEnumBuilder_iface ); +} + static HRESULT WINAPI token_category_EnumTokens( ISpObjectTokenCategory *iface, LPCWSTR req, LPCWSTR opt, IEnumSpObjectTokens **enum_tokens ) @@ -610,21 +625,6 @@ HRESULT token_category_create( IUnknown *outer, REFIID iid, void **obj ) return hr; } -struct token_enum -{ - ISpObjectTokenEnumBuilder ISpObjectTokenEnumBuilder_iface; - LONG ref; - - BOOL init; - WCHAR *req, *opt; - ULONG count; -}; - -static struct token_enum *impl_from_ISpObjectTokenEnumBuilder( ISpObjectTokenEnumBuilder *iface ) -{ - return CONTAINING_RECORD( iface, struct token_enum, ISpObjectTokenEnumBuilder_iface ); -} - static HRESULT WINAPI token_enum_QueryInterface( ISpObjectTokenEnumBuilder *iface, REFIID iid, void **obj ) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1140
From: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> --- dlls/sapi/token.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index 9be15e01ac0..34d26f6740d 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -504,6 +504,7 @@ struct token_enum BOOL init; WCHAR *req, *opt; ULONG count; + HKEY key; }; static struct token_enum *impl_from_ISpObjectTokenEnumBuilder( ISpObjectTokenEnumBuilder *iface ) @@ -517,9 +518,11 @@ static HRESULT WINAPI token_category_EnumTokens( ISpObjectTokenCategory *iface, { struct token_category *This = impl_from_ISpObjectTokenCategory( iface ); ISpObjectTokenEnumBuilder *builder; + struct token_enum *tokenenum; + struct data_key *this_data_key; HRESULT hr; - FIXME( "(%p)->(%s %s %p): semi-stub\n", This, debugstr_w( req ), debugstr_w( opt ), enum_tokens ); + TRACE( "(%p)->(%s %s %p)\n", This, debugstr_w( req ), debugstr_w( opt ), enum_tokens ); if (!This->data_key) return SPERR_UNINITIALIZED; @@ -530,7 +533,15 @@ static HRESULT WINAPI token_category_EnumTokens( ISpObjectTokenCategory *iface, hr = ISpObjectTokenEnumBuilder_SetAttribs( builder, req, opt ); if (FAILED(hr)) goto fail; - /* FIXME: Build the enumerator */ + this_data_key = impl_from_ISpRegDataKey( This->data_key ); + + tokenenum = impl_from_ISpObjectTokenEnumBuilder( builder ); + + if (!RegOpenKeyExW( this_data_key->key, L"Tokens", 0, KEY_ALL_ACCESS, &tokenenum->key )) + { + RegQueryInfoKeyW(tokenenum->key, NULL, NULL, NULL, &tokenenum->count, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); + } hr = ISpObjectTokenEnumBuilder_QueryInterface( builder, &IID_IEnumSpObjectTokens, (void **)enum_tokens ); @@ -664,6 +675,8 @@ static ULONG WINAPI token_enum_Release( ISpObjectTokenEnumBuilder *iface ) if (!ref) { + if (This->key) + RegCloseKey(This->key); heap_free( This->req ); heap_free( This->opt ); heap_free( This ); @@ -816,6 +829,7 @@ HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj ) This->opt = NULL; This->init = FALSE; This->count = 0; + This->key = NULL; hr = ISpObjectTokenEnumBuilder_QueryInterface( &This->ISpObjectTokenEnumBuilder_iface, iid, obj ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1140
From: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> --- dlls/sapi/token.c | 75 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 16 deletions(-) diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index 34d26f6740d..0f37d6efa00 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -48,6 +48,20 @@ static struct data_key *impl_from_ISpRegDataKey( ISpRegDataKey *iface ) return CONTAINING_RECORD( iface, struct data_key, ISpRegDataKey_iface ); } +struct object_token +{ + ISpObjectToken ISpObjectToken_iface; + LONG ref; + + HKEY token_key; + WCHAR *token_id; +}; + +static struct object_token *impl_from_ISpObjectToken( ISpObjectToken *iface ) +{ + return CONTAINING_RECORD( iface, struct object_token, ISpObjectToken_iface ); +} + static HRESULT WINAPI data_key_QueryInterface( ISpRegDataKey *iface, REFIID iid, void **obj ) { struct data_key *This = impl_from_ISpRegDataKey( iface ); @@ -724,8 +738,51 @@ static HRESULT WINAPI token_enum_Clone( ISpObjectTokenEnumBuilder *iface, static HRESULT WINAPI token_enum_Item( ISpObjectTokenEnumBuilder *iface, ULONG index, ISpObjectToken **token ) { - FIXME( "stub\n" ); - return E_NOTIMPL; + struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface ); + struct object_token *object; + ISpObjectToken *subtoken; + HRESULT hr; + WCHAR *subkey; + DWORD size; + LONG ret; + HKEY key; + + TRACE( "%p, %lu, %p\n", This, index, token ); + + if (!This->init) + return SPERR_UNINITIALIZED; + + RegQueryInfoKeyW(This->key, NULL, NULL, NULL, NULL, &size, NULL, NULL, NULL, NULL, NULL, NULL); + size = (size+1) * sizeof(WCHAR); + subkey = heap_alloc(size); + if (!subkey) + return E_OUTOFMEMORY; + + ret = RegEnumKeyExW(This->key, index, subkey, &size, NULL, NULL, NULL, NULL); + if (ret != ERROR_SUCCESS) + { + heap_free(subkey); + return HRESULT_FROM_WIN32(ret); + } + + ret = RegOpenKeyExW (This->key, subkey, 0, KEY_READ, &key); + if (ret != ERROR_SUCCESS) + { + heap_free(subkey); + return HRESULT_FROM_WIN32(ret); + } + + hr = token_create( NULL, &IID_ISpObjectToken, (void**)&subtoken ); + if (FAILED(hr)) + return hr; + + object = impl_from_ISpObjectToken( subtoken ); + object->token_key = key; + object->token_id = subkey; + + *token = subtoken; + + return hr; } static HRESULT WINAPI token_enum_GetCount( ISpObjectTokenEnumBuilder *iface, @@ -837,20 +894,6 @@ HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj ) return hr; } -struct object_token -{ - ISpObjectToken ISpObjectToken_iface; - LONG ref; - - HKEY token_key; - WCHAR *token_id; -}; - -static struct object_token *impl_from_ISpObjectToken( ISpObjectToken *iface ) -{ - return CONTAINING_RECORD( iface, struct object_token, ISpObjectToken_iface ); -} - static HRESULT WINAPI token_QueryInterface( ISpObjectToken *iface, REFIID iid, void **obj ) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1140
From: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> --- dlls/sapi/token.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index 0f37d6efa00..8972a5086ed 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -519,6 +519,7 @@ struct token_enum WCHAR *req, *opt; ULONG count; HKEY key; + DWORD index; }; static struct token_enum *impl_from_ISpObjectTokenEnumBuilder( ISpObjectTokenEnumBuilder *iface ) @@ -704,15 +705,54 @@ static HRESULT WINAPI token_enum_Next( ISpObjectTokenEnumBuilder *iface, ULONG *fetched ) { struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface ); + struct object_token *object; + HRESULT hr; + DWORD retCode; + WCHAR *subkey_name; + HKEY sub_key; + DWORD size; TRACE( "(%p)->(%lu %p %p)\n", This, num, tokens, fetched ); if (!This->init) return SPERR_UNINITIALIZED; + if (fetched) *fetched = 0; - FIXME( "semi-stub: Returning an empty enumerator\n" ); + *tokens = NULL; - if (fetched) *fetched = 0; - return S_FALSE; + RegQueryInfoKeyW( This->key, NULL, NULL, NULL, NULL, &size, NULL, NULL, NULL, NULL, NULL, NULL ); + size = (size+1) * sizeof(WCHAR); + subkey_name = heap_alloc(size); + if (!subkey_name) + return E_OUTOFMEMORY; + + retCode = RegEnumKeyExW( This->key, This->index, subkey_name, &size, NULL, NULL, NULL, NULL ); + if (retCode != ERROR_SUCCESS) + { + heap_free(subkey_name); + return S_FALSE; + } + + This->index++; + + if (RegOpenKeyExW( This->key, subkey_name, 0, KEY_READ, &sub_key ) != ERROR_SUCCESS) + { + heap_free(subkey_name); + return E_FAIL; + } + + hr = token_create( NULL, &IID_ISpObjectToken, (void**)tokens ); + if (FAILED(hr)) + { + heap_free(subkey_name); + return hr; + } + + object = impl_from_ISpObjectToken( *tokens ); + object->token_key = sub_key; + object->token_id = subkey_name; + + if (fetched) *fetched = 1; + return hr; } static HRESULT WINAPI token_enum_Skip( ISpObjectTokenEnumBuilder *iface, @@ -887,6 +927,7 @@ HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj ) This->init = FALSE; This->count = 0; This->key = NULL; + This->index = 0; hr = ISpObjectTokenEnumBuilder_QueryInterface( &This->ISpObjectTokenEnumBuilder_iface, iid, obj ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1140
From: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> --- dlls/sapi/sapi.rgs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dlls/sapi/sapi.rgs b/dlls/sapi/sapi.rgs index bf784fd58d6..cba07ab6184 100644 --- a/dlls/sapi/sapi.rgs +++ b/dlls/sapi/sapi.rgs @@ -30,6 +30,13 @@ HKLM } NoRemove Voices { + NoRemove Tokens + { + NoRemove 'Wine Default Voice' + { + NoRemove Attributes + } + } } } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1140
From: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> --- dlls/sapi/tests/token.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c index 7ef58e697b0..958c50359f5 100644 --- a/dlls/sapi/tests/token.c +++ b/dlls/sapi/tests/token.c @@ -191,6 +191,41 @@ static void test_default_token_id(void) ISpObjectTokenCategory_Release( cat ); } +static void tests_token_voices(void) +{ + ISpObjectTokenCategory *cat; + HRESULT hr; + IEnumSpObjectTokens *tokens; + ISpObjectToken *item; + ULONG fetched = 0; + ULONG count; + + hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER, + &IID_ISpObjectTokenCategory, (void **)&cat ); + ok( hr == S_OK, "got %08lx\n", hr ); + + hr = ISpObjectTokenCategory_SetId( cat, SPCAT_VOICES, FALSE ); + ok( hr == S_OK, "got %08lx\n", hr ); + + hr = ISpObjectTokenCategory_EnumTokens(cat, NULL, NULL, &tokens); + ok( hr == S_OK, "got %08lx\n", hr ); + + hr = IEnumSpObjectTokens_GetCount( tokens, &count ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( count != 0, "got %lu\n", count ); + ISpObjectTokenCategory_Release( cat ); + + hr = IEnumSpObjectTokens_Item(tokens, 0, &item); + ok( hr == S_OK, "got %08lx\n", hr ); + ISpObjectToken_Release(item); + + hr = IEnumSpObjectTokens_Next(tokens, 1, &item, &fetched); + ok( hr == S_OK, "got %08lx\n", hr ); + ISpObjectToken_Release(item); + + IEnumSpObjectTokens_Release(tokens); +} + static void test_object_token(void) { ISpObjectToken *token; @@ -331,5 +366,6 @@ START_TEST(token) test_token_enum(); test_default_token_id(); test_object_token(); + tests_token_voices(); CoUninitialize(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1140
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125264 Your paranoid android. === debian11 (build log) === Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report
participants (3)
-
Alistair Leslie-Hughes -
Alistair Leslie-Hughes (@alesliehughes) -
Marvin