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(a)protonmail.com> wrote:
Signed-off-by: Myah Caron qsniyg(a)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)®value, ®value_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)®value, ®value_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)®value2, ®value_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)®value, ®value_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)®value, ®value_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)®value, ®value_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,
- ®value, ®value_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