[PATCH] sapi: Improve Get/SetDefaultTokenId stubs.

Myah Caron qsniyg at protonmail.com
Sat Aug 1 15:48:41 CDT 2020


Sorry I forgot to test under windows, I had only tested with the native dll from winetricks.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Saturday, August 1, 2020 12:52 PM, Myah Caron <qsniyg at protonmail.com> wrote:

> Signed-off-by: Myah Caron qsniyg at protonmail.com
>
> Progressing towards fixing #49641. This patch alone doesn't fix the issue, but I'm not sure when I'll get to the next patch, so I'm sending this one in by itself for the moment.
>
> dlls/sapi/tests/token.c | 253 ++++++++++++++++++++++++++++++++++++++++
> dlls/sapi/token.c | 96 ++++++++++++++-
> 2 files changed, 345 insertions(+), 4 deletions(-)
>
> diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c
> index 9f6689b83f..4d12ddb1c9 100644
> --- a/dlls/sapi/tests/token.c
> +++ b/dlls/sapi/tests/token.c
> @@ -83,6 +83,254 @@ static void test_token_category(void)
> ISpObjectTokenCategory_Release( cat );
> }
>
> +static void backup_speech(HKEY root)
> +{
>
> -   LONG res;
> -   HKEY key;
> -
> -   res = RegDeleteTreeW( root, L"SOFTWARE\\Microsoft\\Speech_winetest" );
> -   ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
> -
> -   res = RegCreateKeyW( root, L"SOFTWARE\\Microsoft\\Speech_winetest", &key );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -
> -   RegCopyTreeW( root, L"SOFTWARE\\Microsoft\\Speech", key );
> -   ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
> -
> -   RegCloseKey(key);
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
>     +}
>
> -
>
> +static void restore_speech(HKEY root, BOOL delete_backup)
> +{
>
> -   LONG res;
> -   HKEY key;
> -
> -   res = RegDeleteTreeW( root, L"SOFTWARE\\Microsoft\\Speech" );
> -   ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
> -
> -   res = RegCreateKeyW( root, L"SOFTWARE\\Microsoft\\Speech", &key );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -
> -   RegCopyTreeW( root, L"SOFTWARE\\Microsoft\\Speech_winetest", key );
> -   ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
> -
> -   RegCloseKey(key);
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -
> -   if (delete_backup) {
> -          res = RegDeleteTreeW( root, L"SOFTWARE\\\\Microsoft\\\\Speech_winetest" );
>
>
> -          ok( res == ERROR_SUCCESS, "got %08x\\n", res );
>
>
> -   }
>     +}
>
> -
>
> +static void test_token_default_id(void)
> +{
>
> -   ISpObjectTokenCategory *cat;
> -   HRESULT hr;
> -   LONG res;
> -   HKEY key;
> -   LPWSTR token_id = NULL;
> -   WCHAR regvalue[512];
> -   WCHAR regvalue2[512];
> -   DWORD regvalue_size = sizeof( regvalue );
> -
> -   hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
> -                             &IID_ISpObjectTokenCategory, (void **)&cat );
>
>
> -   ok( hr == S_OK, "got %08x\n", hr );
> -
> -   token_id = (LPWSTR)0xdeadbeef;
> -   hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
> -   ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
> -   ok( token_id == (LPWSTR)0xdeadbeef, "got %p\n", token_id );
> -
> -   hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, NULL );
> -   ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
> -
> -   /* if missing, Get/SetDefaultTokenId should initialize HKEY_LOCAL_USER's
> -         SOFTWARE\\Microsoft\\Speech\\AudioOutput */
>
>
> -   res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
> -   ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
> -
> -   hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
> -   ok( hr == S_OK, "got %08x\n", hr );
> -
> -   res = RegOpenKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
> -   ok( res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
> -
> -   hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, NULL );
> -   ok( hr == E_POINTER, "got %08x\n", hr );
> -
> -   res = RegOpenKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
> -   ok( res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
> -
> -   token_id = (LPWSTR)0xdeadbeef;
> -   hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
> -   ok( hr == S_OK, "got %08x\n", hr );
> -   ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
> -
> -   regvalue_size = sizeof( regvalue );
> -   res = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
> -                          L"DefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)&regvalue, &regvalue_size);
>
>
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   ok( !wcscmp(regvalue, token_id),
> -          "GetDefaultTokenId (%s) should be equal to the DefaultTokenId key (%s)\\n",
>
>
> -          wine_dbgstr_w(token_id), wine_dbgstr_w(regvalue) );
>
>
> -   CoTaskMemFree(token_id);
> -
> -   regvalue_size = sizeof( regvalue );
> -   res = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
> -                          L"DefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)&regvalue, &regvalue_size);
>
>
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   regvalue_size = sizeof( regvalue2 );
> -   res = RegGetValueW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
> -                          L"DefaultdefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)&regvalue2, &regvalue_size);
>
>
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   ok( !wcscmp(regvalue, regvalue2),
> -          "DefaultTokenId (%s) should be equal to the DefaultdefaultTokenId key (%s)\\n",
>
>
> -          wine_dbgstr_w(regvalue), wine_dbgstr_w(regvalue2) );
>
>
> -
> -   /* todo: test subkeys */
> -
> -   res = RegOpenKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   wcscpy(regvalue, L"bogus");
> -   regvalue_size = (wcslen(regvalue) + 1) * sizeof( WCHAR );
> -   res = RegSetValueExW( key, L"DefaultTokenId", 0, REG_SZ, (const BYTE*)regvalue, regvalue_size);
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   RegCloseKey(key);
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -
> -   token_id = (LPWSTR)0xdeadbeef;
> -   hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
> -   ok( hr == S_OK, "got %08x\n", hr );
> -   ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
> -   todo_wine ok( wcscmp(regvalue, token_id),
> -          "GetDefaultTokenId (%s) should not be equal to the bogus DefaultTokenId key (%s)\\n",
>
>
> -          wine_dbgstr_w(token_id), wine_dbgstr_w(regvalue) );
>
>
> -   CoTaskMemFree(token_id);
> -
> -   /* todo: add more tests for the resulting token_id */
> -
> -   restore_speech( HKEY_LOCAL_MACHINE, FALSE );
> -   token_id = (LPWSTR)0xdeadbeef;
> -   hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
> -   todo_wine ok( hr == 0x800703fa, "got %08x\n", hr );
> -   todo_wine ok( token_id == (LPWSTR)0xdeadbeef, "got %p\n", token_id );
> -
> -   ISpObjectTokenCategory_Release( cat );
> -
> -   hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
> -                             &IID_ISpObjectTokenCategory, (void **)&cat );
>
>
> -   ok( hr == S_OK, "got %08x\n", hr );
> -
> -   res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   res = RegDeleteTreeW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -
> -   hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
> -   todo_wine ok( hr == SPERR_NOT_FOUND, "got %08x\n", hr );
> -
> -   restore_speech( HKEY_CURRENT_USER, FALSE );
> -
> -   hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
> -   todo_wine ok( hr == SPERR_NOT_FOUND, "got %08x\n", hr );
> -
> -   restore_speech( HKEY_LOCAL_MACHINE, FALSE );
> -
> -   hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
> -   ok( hr == S_OK, "got %08x\n", hr );
> -
> -   res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
> -   ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
> -   res = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   wcscpy(regvalue, L"bogus");
> -   regvalue_size = (wcslen(regvalue) + 1) * sizeof( WCHAR );
> -   res = RegSetValueExW( key, L"DefaultdefaultTokenId", 0, REG_SZ, (const BYTE*)regvalue, regvalue_size);
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   RegCloseKey(key);
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -
> -   token_id = (LPWSTR)0xdeadbeef;
> -   hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
> -   ok( hr == S_OK, "got %08x\n", hr );
> -   ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
> -   todo_wine ok( wcscmp(regvalue, token_id),
> -          "GetDefaultTokenId (%s) should not be equal to the bogus DefaultdefaultTokenId key (%s)\\n",
>
>
> -          wine_dbgstr_w(token_id), wine_dbgstr_w(regvalue) );
>
>
> -   CoTaskMemFree(token_id);
> -
> -   /* todo: test valid DefaultdefaultTokenId values */
> -
> -   ISpObjectTokenCategory_Release( cat );
> -
> -   res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   res = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   res = RegDeleteValueW( key, L"DefaultdefaultTokenId" );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   RegCloseKey(key);
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -
> -   hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
> -                             &IID_ISpObjectTokenCategory, (void **)&cat );
>
>
> -   ok( hr == S_OK, "got %08x\n", hr );
> -   hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
> -   ok( hr == S_OK, "got %08x\n", hr );
> -
> -   token_id = (LPWSTR)0xdeadbeef;
> -   hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
> -   todo_wine ok( hr == S_OK, "got %08x\n", hr );
> -   todo_wine ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
> -   if (token_id != (LPWSTR)0xdeadbeef)
> -          CoTaskMemFree(token_id);
>
>
> -
> -   ISpObjectTokenCategory_Release( cat );
> -   restore_speech( HKEY_LOCAL_MACHINE, FALSE );
> -   hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
> -                             &IID_ISpObjectTokenCategory, (void **)&cat );
>
>
> -   ok( hr == S_OK, "got %08x\n", hr );
> -
> -   hr = ISpObjectTokenCategory_SetDefaultTokenId( cat, NULL );
> -   ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
> -
> -   hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
> -   ok( hr == S_OK, "got %08x\n", hr );
> -
> -   hr = ISpObjectTokenCategory_SetDefaultTokenId( cat, NULL );
> -   ok( hr == E_INVALIDARG, "got %08x\n", hr );
> -
> -   wcscpy(regvalue, L"deadbeef");
> -   hr = ISpObjectTokenCategory_SetDefaultTokenId( cat, regvalue );
> -   ok( hr == S_OK, "got %08x\n", hr );
> -
> -   regvalue_size = sizeof( regvalue );
> -   res = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
> -                          L"DefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)&regvalue, &regvalue_size);
>
>
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   ok( !wcscmp(regvalue, L"deadbeef"),
> -          "DefaultTokenId in registry (%s) should be equal to the set default token id (%s)\\n",
>
>
> -          wine_dbgstr_w(regvalue), wine_dbgstr_w(L"deadbeef") );
>
>
> -
> -   res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   wcscpy(regvalue, L"deadbeef");
> -   hr = ISpObjectTokenCategory_SetDefaultTokenId( cat, regvalue );
> -   ok( hr == S_OK, "got %08x\n", hr );
> -   regvalue_size = sizeof( regvalue );
> -   res = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
> -                          L"DefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)&regvalue, &regvalue_size);
>
>
> -   ok( res == ERROR_SUCCESS, "got %08x\n", res );
> -   ok( !wcscmp(regvalue, L"deadbeef"),
> -          "GetDefaultTokenId (%s) should be equal to the set DefaultTokenId key (%s)\\n",
>
>
> -          wine_dbgstr_w(token_id), wine_dbgstr_w(L"deadbeef") );
>
>
> -
> -   ISpObjectTokenCategory_Release( cat );
>     +}
>
> -
>
> static void test_token_enum(void)
> {
> ISpObjectTokenEnumBuilder *token_enum;
> @@ -121,6 +369,11 @@ START_TEST(token)
> CoInitialize( NULL );
> test_data_key();
> test_token_category();
>
> -   backup_speech( HKEY_LOCAL_MACHINE );
>
> -   backup_speech( HKEY_CURRENT_USER );
>
> -   test_token_default_id();
>
> -   restore_speech( HKEY_CURRENT_USER, TRUE );
>
> -   restore_speech( HKEY_LOCAL_MACHINE, TRUE );
>     test_token_enum();
>     CoUninitialize();
>     }
>     diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c
>     index d2b70c95cf..78c5d2cdd5 100644
>     --- a/dlls/sapi/token.c
>     +++ b/dlls/sapi/token.c
>     @@ -232,6 +232,7 @@ struct token_category
>     LONG ref;
>
>     ISpRegDataKey *data_key;
>
> -   WCHAR *subkey;
>     };
>
>     static struct token_category *impl_from_ISpObjectTokenCategory( ISpObjectTokenCategory *iface )
>     @@ -421,6 +422,8 @@ static HRESULT WINAPI token_category_SetId( ISpObjectTokenCategory *iface,
>     res = RegOpenKeyExW( root, subkey, 0, KEY_ALL_ACCESS, &key );
>     if (res) return SPERR_INVALID_REGISTRY_KEY;
>
> -   This->subkey = _wcsdup(subkey);
>
> -   hr = CoCreateInstance( &CLSID_SpDataKey, NULL, CLSCTX_ALL,
>     &IID_ISpRegDataKey, (void **)&This->data_key );
>     if (FAILED(hr)) goto fail;
>     @@ -479,18 +482,103 @@ fail:
>     return hr;
>     }
>
>     +static HRESULT get_user_speech_key( struct token_category This, HKEY key )
>     +{
>
> -   LONG res;
>
> -   WCHAR regvalue[512];
>
> -   DWORD regvalue_size = sizeof( regvalue );
>
> -
> -   res = RegOpenKeyExW( HKEY_CURRENT_USER, This->subkey, 0, KEY_ALL_ACCESS, key );
>
> -   if (res == ERROR_SUCCESS) {
>
> -          return S_OK;
>
>
> -   }
>
> -
> -   FIXME( "(%p): semi-stub\n", This );
>
> -
> -   res = RegCreateKeyW( HKEY_CURRENT_USER, This->subkey, key );
>
> -   if (res != ERROR_SUCCESS) {
>
> -          /* probably not the correct return value */
>
>
> -          FIXME( "returning %08x\\n", res );
>
>
> -          return res;
>
>
> -   }
>
> -
> -   res = RegGetValueW( HKEY_LOCAL_MACHINE, This->subkey, L"DefaultdefaultTokenId",
>
> -                          RRF_RT_REG_SZ, NULL, (LPVOID)&regvalue, &regvalue_size);
>
>
> -   if (res == ERROR_SUCCESS) {
>
> -          RegSetValueExW( *key, L"DefaultTokenId", 0, REG_SZ, (const BYTE*)regvalue, regvalue_size);
>
>
> -   }
>
> -
> -   return S_OK;
>     +}
>
> -
>
> static HRESULT WINAPI token_category_SetDefaultTokenId( ISpObjectTokenCategory *iface,
> LPCWSTR id )
> {
>
> -   FIXME( "stub\n" );
> -   return E_NOTIMPL;
>
> -   struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
>
> -   HRESULT hr;
>
> -   LONG res;
>
> -   HKEY key;
>
> -
> -   FIXME( "(%p)->(%s): semi-stub\n", iface, debugstr_w(id) );
>
> -
> -   if (!This->data_key)
>
> -          return SPERR_UNINITIALIZED;
>
>
> -
> -   if (!id)
>
> -          return E_INVALIDARG;
>
>
> -
> -   hr = get_user_speech_key( This, &key );
>
> -   if (FAILED(hr)) return hr;
>
> -
> -   res = RegSetValueExW( key, L"DefaultTokenId", 0, REG_SZ, (const BYTE*)id,
>
> -                            wcslen( id) * sizeof( WCHAR ));
>
>
> -   if (res != ERROR_SUCCESS) {
>
> -          /* probably not the correct return value */
>
>
> -          FIXME( "unable to set DefaultTokenId, returning S_FALSE\\n" );
>
>
> -          RegCloseKey( key );
>
>
> -          return S_FALSE;
>
>
> -   }
>
> -
> -   RegCloseKey( key );
>
> -
> -   return S_OK;
>     }
>
>     static HRESULT WINAPI token_category_GetDefaultTokenId( ISpObjectTokenCategory *iface,
>     LPWSTR *id )
>     {
>
>
> -   FIXME( "stub\n" );
> -   return E_NOTIMPL;
>
> -   struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
>
> -   HRESULT hr;
>
> -   LONG res;
>
> -   HKEY key;
>
> -   WCHAR regvalue[512];
>
> -   DWORD regvalue_size = sizeof( regvalue );
>
> -
> -   FIXME( "(%p)->(%p): semi-stub\n", iface, id );
>
> -
> -   if (!This->data_key)
>
> -          return SPERR_UNINITIALIZED;
>
>
> -
> -   if (!id)
>
> -          return E_POINTER;
>
>
> -
> -   hr = get_user_speech_key( This, &key );
>
> -   if (FAILED(hr)) return hr;
>
> -
> -   res = RegGetValueW( key, NULL, L"DefaultTokenId", RRF_RT_REG_SZ, NULL,
>
> -                          &regvalue, &regvalue_size);
>
>
> -   if (res != ERROR_SUCCESS) {
>
> -          FIXME( "DefaultTokenId is missing, returning S_FALSE\\n" );
>
>
> -          RegCloseKey( key );
>
>
> -          return S_FALSE;
>
>
> -   }
>
> -
> -   *id = CoTaskMemAlloc( regvalue_size );
>
> -   wcscpy( *id, regvalue );
>
> -
> -   RegCloseKey( key );
>
> -
> -   return S_OK;
>     }
>
>     const struct ISpObjectTokenCategoryVtbl token_category_vtbl =
>     --
>     2.27.0
>





More information about the wine-devel mailing list