sapi: Add stubs for SpObjectToken.

Signed-off-by: Myah Caron <qsniyg@protonmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Myah Caron 2020-09-16 06:22:59 +00:00 committed by Alexandre Julliard
parent 0e53f6bfa1
commit 64808e17b2
6 changed files with 431 additions and 0 deletions

View File

@ -110,6 +110,7 @@ static struct class_factory file_stream_cf = { { &class_factory_vtbl }, file_
static struct class_factory speech_voice_cf = { { &class_factory_vtbl }, speech_voice_create }; static struct class_factory speech_voice_cf = { { &class_factory_vtbl }, speech_voice_create };
static struct class_factory token_category_cf = { { &class_factory_vtbl }, token_category_create }; static struct class_factory token_category_cf = { { &class_factory_vtbl }, token_category_create };
static struct class_factory token_enum_cf = { { &class_factory_vtbl }, token_enum_create }; static struct class_factory token_enum_cf = { { &class_factory_vtbl }, token_enum_create };
static struct class_factory token_cf = { { &class_factory_vtbl }, token_create };
/****************************************************************** /******************************************************************
* DllGetClassObject * DllGetClassObject
@ -128,6 +129,8 @@ HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID iid, void **obj )
cf = &token_category_cf.IClassFactory_iface; cf = &token_category_cf.IClassFactory_iface;
else if (IsEqualCLSID( clsid, &CLSID_SpObjectTokenEnum )) else if (IsEqualCLSID( clsid, &CLSID_SpObjectTokenEnum ))
cf = &token_enum_cf.IClassFactory_iface; cf = &token_enum_cf.IClassFactory_iface;
else if (IsEqualCLSID( clsid, &CLSID_SpObjectToken ))
cf = &token_cf.IClassFactory_iface;
else if (IsEqualCLSID( clsid, &CLSID_SpVoice )) else if (IsEqualCLSID( clsid, &CLSID_SpVoice ))
cf = &speech_voice_cf.IClassFactory_iface; cf = &speech_voice_cf.IClassFactory_iface;

View File

@ -51,6 +51,19 @@ coclass SpObjectTokenEnum
[default] interface IEnumSpObjectTokens; [default] interface IEnumSpObjectTokens;
} }
[
uuid(ef411752-3736-4cb4-9c8c-8ef4ccb58efe),
helpstring("Object Token"),
progid("SAPI.SpObjectToken.1"),
vi_progid("SAPI.SpObjectToken"),
threading(both)
]
coclass SpObjectToken
{
interface ISpObjectToken;
[default] interface ISpDataKey;
}
[ [
uuid(96749377-3391-11d2-9ee3-00c04f797396), uuid(96749377-3391-11d2-9ee3-00c04f797396),
helpstring("Speech Voice"), helpstring("Speech Voice"),

View File

@ -25,6 +25,7 @@ HRESULT file_stream_create( IUnknown *outer, REFIID iid, void **obj ) DECLSPEC_H
HRESULT speech_voice_create( IUnknown *outer, REFIID iid, void **obj ) DECLSPEC_HIDDEN; HRESULT speech_voice_create( IUnknown *outer, REFIID iid, void **obj ) DECLSPEC_HIDDEN;
HRESULT token_category_create( IUnknown *outer, REFIID iid, void **obj ) DECLSPEC_HIDDEN; HRESULT token_category_create( IUnknown *outer, REFIID iid, void **obj ) DECLSPEC_HIDDEN;
HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj ) DECLSPEC_HIDDEN; HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj ) DECLSPEC_HIDDEN;
HRESULT token_create( IUnknown *outer, REFIID iid, void **obj ) DECLSPEC_HIDDEN;
static inline LPWSTR heap_strdupW(LPCWSTR str) static inline LPWSTR heap_strdupW(LPCWSTR str)
{ {

View File

@ -174,6 +174,130 @@ static void test_default_token_id(void)
ISpObjectTokenCategory_Release( cat ); ISpObjectTokenCategory_Release( cat );
} }
static void test_object_token(void)
{
ISpObjectToken *token;
HRESULT hr;
LPWSTR tempW, token_id;
ISpObjectTokenCategory *cat;
hr = CoCreateInstance( &CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER,
&IID_ISpObjectToken, (void **)&token );
ok( hr == S_OK, "got %08x\n", hr );
hr = ISpObjectToken_GetId( token, NULL );
todo_wine ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
tempW = (LPWSTR)0xdeadbeef;
hr = ISpObjectToken_GetId( token, &tempW );
todo_wine ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
ok( tempW == (LPWSTR)0xdeadbeef, "got %s\n", wine_dbgstr_w(tempW) );
hr = ISpObjectToken_GetCategory( token, NULL );
todo_wine ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
cat = (LPVOID)0xdeadbeef;
hr = ISpObjectToken_GetCategory( token, &cat );
todo_wine ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
ok( cat == (LPVOID)0xdeadbeef, "got %p\n", cat );
hr = ISpObjectToken_SetId( token, NULL, NULL, FALSE );
todo_wine ok( hr == E_POINTER, "got %08x\n", hr );
hr = ISpObjectToken_SetId( token, L"bogus", NULL, FALSE );
todo_wine ok( hr == E_POINTER, "got %08x\n", hr );
hr = ISpObjectToken_SetId( token, NULL, L"bogus", FALSE );
todo_wine ok( hr == SPERR_NOT_FOUND, "got %08x\n", hr );
hr = ISpObjectToken_SetId( token, NULL, L"HKEY_LOCAL_MACHINE\\SOFTWARE\\winetest bogus", FALSE );
todo_wine ok( hr == SPERR_NOT_FOUND, "got %08x\n", hr );
/* SetId succeeds even if the key is invalid, but exists */
hr = ISpObjectToken_SetId( token, NULL, L"HKEY_LOCAL_MACHINE\\SOFTWARE", FALSE );
todo_wine ok( hr == S_OK, "got %08x\n", hr );
hr = ISpObjectToken_SetId( token, NULL, NULL, FALSE );
todo_wine ok( hr == SPERR_ALREADY_INITIALIZED, "got %08x\n", hr );
hr = ISpObjectToken_SetId( token, NULL, L"bogus", FALSE );
todo_wine ok( hr == SPERR_ALREADY_INITIALIZED, "got %08x\n", hr );
hr = ISpObjectToken_GetId( token, NULL );
todo_wine ok( hr == E_POINTER, "got %08x\n", hr );
hr = ISpObjectToken_GetCategory( token, NULL );
todo_wine ok( hr == E_POINTER, "got %08x\n", hr );
tempW = NULL;
hr = ISpObjectToken_GetId( token, &tempW );
todo_wine ok( hr == S_OK, "got %08x\n", hr );
todo_wine ok( tempW != NULL, "got %p\n", tempW );
if (tempW) {
ok( !wcscmp(tempW, L"HKEY_LOCAL_MACHINE\\SOFTWARE"), "got %s\n",
wine_dbgstr_w(tempW) );
CoTaskMemFree( tempW );
}
cat = (LPVOID)0xdeadbeef;
hr = ISpObjectToken_GetCategory( token, &cat );
todo_wine ok( hr == SPERR_INVALID_REGISTRY_KEY, "got %08x\n", hr );
ok( cat == (LPVOID)0xdeadbeef, "got %p\n", cat );
/* get the default token id for SPCAT_AUDIOOUT */
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 );
if (hr == SPERR_NOT_FOUND) {
skip( "AudioOutput category not found for GetDefaultTokenId\n" );
return;
}
ok( hr == S_OK, "got %08x\n", hr );
ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
ISpObjectTokenCategory_Release( cat );
/* recreate token in order to SetId again */
ISpObjectToken_Release( token );
hr = CoCreateInstance( &CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER,
&IID_ISpObjectToken, (void **)&token );
ok( hr == S_OK, "got %08x\n", hr );
/* NULL appears to auto-detect the category */
hr = ISpObjectToken_SetId( token, NULL, token_id, FALSE );
todo_wine ok( hr == S_OK, "got %08x\n", hr );
tempW = NULL;
hr = ISpObjectToken_GetId( token, &tempW );
todo_wine ok( hr == S_OK, "got %08x\n", hr );
todo_wine ok( tempW != NULL, "got %p\n", tempW );
if (tempW) {
ok( !wcsncmp(tempW, token_id, wcslen(token_id)),
"got %s (expected %s)\n", wine_dbgstr_w(tempW), wine_dbgstr_w(token_id) );
CoTaskMemFree( tempW );
}
cat = (LPVOID)0xdeadbeef;
hr = ISpObjectToken_GetCategory( token, &cat );
todo_wine ok( hr == S_OK, "got %08x\n", hr );
todo_wine ok( cat != (LPVOID)0xdeadbeef, "got %p\n", cat );
if (cat != (LPVOID)0xdeadbeef) {
tempW = NULL;
hr = ISpObjectTokenCategory_GetId( cat, &tempW );
todo_wine ok( hr == S_OK, "got %08x\n", hr );
todo_wine ok( tempW != NULL, "got %p\n", tempW );
if (tempW) {
ok( !wcscmp(tempW, SPCAT_AUDIOOUT), "got %s\n", wine_dbgstr_w(tempW) );
CoTaskMemFree( tempW );
}
/* not freed by ISpObjectToken_Release */
ISpObjectTokenCategory_Release( cat );
}
ISpObjectToken_Release( token );
}
START_TEST(token) START_TEST(token)
{ {
CoInitialize( NULL ); CoInitialize( NULL );
@ -181,5 +305,6 @@ START_TEST(token)
test_token_category(); test_token_category();
test_token_enum(); test_token_enum();
test_default_token_id(); test_default_token_id();
test_object_token();
CoUninitialize(); CoUninitialize();
} }

View File

@ -776,3 +776,279 @@ HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj )
ISpObjectTokenEnumBuilder_Release( &This->ISpObjectTokenEnumBuilder_iface ); ISpObjectTokenEnumBuilder_Release( &This->ISpObjectTokenEnumBuilder_iface );
return hr; return hr;
} }
struct object_token
{
ISpObjectToken ISpObjectToken_iface;
LONG ref;
};
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 )
{
struct object_token *This = impl_from_ISpObjectToken( iface );
TRACE( "(%p)->(%s %p)\n", This, debugstr_guid( iid ), obj );
if (IsEqualIID( iid, &IID_IUnknown ) ||
IsEqualIID( iid, &IID_ISpDataKey ) ||
IsEqualIID( iid, &IID_ISpObjectToken ))
{
ISpObjectToken_AddRef( iface );
*obj = iface;
return S_OK;
}
FIXME( "interface %s not implemented\n", debugstr_guid( iid ) );
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI token_AddRef( ISpObjectToken *iface )
{
struct object_token *This = impl_from_ISpObjectToken( iface );
ULONG ref = InterlockedIncrement( &This->ref );
TRACE( "(%p) ref = %u\n", This, ref );
return ref;
}
static ULONG WINAPI token_Release( ISpObjectToken *iface )
{
struct object_token *This = impl_from_ISpObjectToken( iface );
ULONG ref = InterlockedDecrement(&This->ref);
TRACE( "(%p) ref = %u\n", This, ref );
if (!ref)
{
heap_free( This );
}
return ref;
}
static HRESULT WINAPI token_SetData( ISpObjectToken *iface,
LPCWSTR name, ULONG size,
const BYTE *data )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_GetData( ISpObjectToken *iface,
LPCWSTR name, ULONG *size,
BYTE *data )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_SetStringValue( ISpObjectToken *iface,
LPCWSTR name, LPCWSTR value )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_GetStringValue( ISpObjectToken *iface,
LPCWSTR name, LPWSTR *value )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_SetDWORD( ISpObjectToken *iface,
LPCWSTR name, DWORD value )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_GetDWORD( ISpObjectToken *iface,
LPCWSTR name, DWORD *pdwValue )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_OpenKey( ISpObjectToken *iface,
LPCWSTR name, ISpDataKey **sub_key )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_CreateKey( ISpObjectToken *iface,
LPCWSTR name, ISpDataKey **sub_key )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_DeleteKey( ISpObjectToken *iface,
LPCWSTR name )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_DeleteValue( ISpObjectToken *iface,
LPCWSTR name )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_EnumKeys( ISpObjectToken *iface,
ULONG index, LPWSTR *sub_key )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_EnumValues( ISpObjectToken *iface,
ULONG index, LPWSTR *value )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_SetId( ISpObjectToken *iface,
LPCWSTR category_id, LPCWSTR token_id,
BOOL create )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_GetId( ISpObjectToken *iface,
LPWSTR *token_id )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_GetCategory( ISpObjectToken *iface,
ISpObjectTokenCategory **category )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_CreateInstance( ISpObjectToken *iface,
IUnknown *outer,
DWORD class_context,
REFIID riid,
void **object )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_GetStorageFileName( ISpObjectToken *iface,
REFCLSID caller,
LPCWSTR key_name,
LPCWSTR filename,
ULONG folder,
LPWSTR *filepath )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_RemoveStorageFileName( ISpObjectToken *iface,
REFCLSID caller,
LPCWSTR key_name,
BOOL delete_file )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_Remove( ISpObjectToken *iface,
REFCLSID caller )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_IsUISupported( ISpObjectToken *iface,
LPCWSTR ui_type,
void *extra_data,
ULONG extra_data_size,
IUnknown *object,
BOOL *supported )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_DisplayUI( ISpObjectToken *iface,
HWND parent,
LPCWSTR title,
LPCWSTR ui_type,
void *extra_data,
ULONG extra_data_size,
IUnknown *object )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
static HRESULT WINAPI token_MatchesAttributes( ISpObjectToken *iface,
LPCWSTR attributes,
BOOL *matches )
{
FIXME( "stub\n" );
return E_NOTIMPL;
}
const struct ISpObjectTokenVtbl token_vtbl =
{
token_QueryInterface,
token_AddRef,
token_Release,
token_SetData,
token_GetData,
token_SetStringValue,
token_GetStringValue,
token_SetDWORD,
token_GetDWORD,
token_OpenKey,
token_CreateKey,
token_DeleteKey,
token_DeleteValue,
token_EnumKeys,
token_EnumValues,
token_SetId,
token_GetId,
token_GetCategory,
token_CreateInstance,
token_GetStorageFileName,
token_RemoveStorageFileName,
token_Remove,
token_IsUISupported,
token_DisplayUI,
token_MatchesAttributes
};
HRESULT token_create( IUnknown *outer, REFIID iid, void **obj )
{
struct object_token *This = heap_alloc( sizeof(*This) );
HRESULT hr;
if (!This) return E_OUTOFMEMORY;
This->ISpObjectToken_iface.lpVtbl = &token_vtbl;
This->ref = 1;
hr = ISpObjectToken_QueryInterface( &This->ISpObjectToken_iface, iid, obj );
ISpObjectToken_Release( &This->ISpObjectToken_iface );
return hr;
}

View File

@ -1064,6 +1064,19 @@ library SpeechLib
interface ISpObjectTokenCategory; interface ISpObjectTokenCategory;
} }
[
uuid(ef411752-3736-4cb4-9c8c-8ef4ccb58efe),
helpstring("Object Token"),
progid("SAPI.SpObjectToken.1"),
vi_progid("SAPI.SpObjectToken"),
threading(both)
]
coclass SpObjectToken
{
interface ISpObjectToken;
[default] interface ISpDataKey;
}
[ [
uuid(3bee4890-4fe9-4a37-8c1e-5e7e12791c1f) uuid(3bee4890-4fe9-4a37-8c1e-5e7e12791c1f)
] ]