From: Alistair Leslie-Hughes leslie_alistair@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 ) {
From: Alistair Leslie-Hughes leslie_alistair@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 );
From: Alistair Leslie-Hughes leslie_alistair@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 ) {
From: Alistair Leslie-Hughes leslie_alistair@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 );
From: Alistair Leslie-Hughes leslie_alistair@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 + } + } } } }
From: Alistair Leslie-Hughes leslie_alistair@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(); }
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