From: Shaun Ren sren@codeweavers.com
--- dlls/sapi/tests/Makefile.in | 2 +- dlls/sapi/tests/token.c | 58 +++++++++++++++++++++++++++++++++++-- dlls/sapi/token.c | 23 +++++++++++++-- 3 files changed, 78 insertions(+), 5 deletions(-)
diff --git a/dlls/sapi/tests/Makefile.in b/dlls/sapi/tests/Makefile.in index 4c107d5e994..4e792f2daae 100644 --- a/dlls/sapi/tests/Makefile.in +++ b/dlls/sapi/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = sapi.dll -IMPORTS = ole32 user32 advapi32 winmm +IMPORTS = ole32 oleaut32 user32 advapi32 winmm
SOURCES = \ automation.c \ diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c index 543b19ec69a..a651eb47c62 100644 --- a/dlls/sapi/tests/token.c +++ b/dlls/sapi/tests/token.c @@ -657,7 +657,7 @@ static IClassFactory test_class_cf = { &ClassFactoryVtbl };
static void test_object_token(void) { - static const WCHAR test_token_id[] = L"HKEY_LOCAL_MACHINE\Software\Wine\Winetest\sapi\TestToken"; + static const WCHAR test_token_id[] = L"HKEY_LOCAL_MACHINE\Software\Winetest\sapi\TestToken";
ISpObjectToken *token; IDispatch *disp; @@ -665,6 +665,7 @@ static void test_object_token(void) ISpDataKey *sub_key; HRESULT hr; LPWSTR tempW, token_id; + BSTR tempB; ISpObjectTokenCategory *cat; DWORD regid; IUnknown *obj; @@ -863,11 +864,64 @@ static void test_object_token(void) CoTaskMemFree( tempW ); }
+ hr = ISpObjectToken_SetStringValue( token, L"409", L"409 - TestToken" ); + ok( hr == S_OK, "got %08lx\n", hr ); + hr = ISpObjectToken_SetStringValue( token, L"407", L"407 - TestToken" ); + ok( hr == S_OK, "got %08lx\n", hr ); + hr = ISpObjectToken_SetStringValue( token, L"E40C", L"E40C - TestToken" ); + ok( hr == S_OK, "got %08lx\n", hr ); + + hr = ISpObjectToken_QueryInterface( token, &IID_ISpeechObjectToken, (void **)&speech_token ); + ok( hr == S_OK, "got %08lx\n", hr ); + + hr = ISpeechObjectToken_GetDescription( speech_token, 0x409, NULL ); + ok( hr == E_POINTER, "got %08lx\n", hr ); + + tempB = NULL; + hr = ISpeechObjectToken_GetDescription( speech_token, 0x409, &tempB ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( tempB && !wcscmp( tempB, L"409 - TestToken" ), "got %s\n", wine_dbgstr_w( tempB ) ); + SysFreeString( tempB ); + + tempB = NULL; + hr = ISpeechObjectToken_GetDescription( speech_token, 0x10407, &tempB ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( tempB && !wcscmp( tempB, L"407 - TestToken" ), "got %s\n", wine_dbgstr_w( tempB ) ); + SysFreeString( tempB ); + + tempB = NULL; + hr = ISpeechObjectToken_GetDescription( speech_token, 0xE40C, &tempB ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( tempB && !wcscmp( tempB, L"E40C - TestToken" ), "got %s\n", wine_dbgstr_w( tempB ) ); + SysFreeString( tempB ); + + tempB = (BSTR)0xdeadbeef; + hr = ISpeechObjectToken_GetDescription( speech_token, 0x406, &tempB ); + ok( hr == SPERR_NOT_FOUND, "got %08lx\n", hr ); + ok( tempB == (BSTR)0xdeadbeef || broken(tempB == NULL) /* < win7 */, "got %p\n", tempB ); + + hr = ISpObjectToken_SetStringValue( token, NULL, L"TestToken" ); + ok( hr == S_OK, "got %08lx\n", hr ); + + tempB = NULL; + hr = ISpeechObjectToken_GetDescription( speech_token, 0x406, &tempB ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( tempB && !wcscmp( tempB, L"TestToken" ), "got %s\n", wine_dbgstr_w( tempB ) ); + SysFreeString( tempB ); + + tempB = NULL; + hr = ISpeechObjectToken_GetDescription( speech_token, 0x0, &tempB ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( tempB && !wcscmp( tempB, L"TestToken" ), "got %s\n", wine_dbgstr_w( tempB ) ); + SysFreeString( tempB ); + + ISpeechObjectToken_Release( speech_token ); + ISpObjectToken_Release( test_class_token ); IUnknown_Release( obj ); ISpObjectToken_Release( token );
- RegDeleteTreeA( HKEY_LOCAL_MACHINE, "Software\Wine\Winetest\sapi" ); + RegDeleteTreeA( HKEY_LOCAL_MACHINE, "Software\Winetest\sapi" ); }
START_TEST(token) diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index 53b64a4383f..e5d87505e34 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -1829,8 +1829,27 @@ static HRESULT WINAPI speech_token_get_Category( ISpeechObjectToken *iface, static HRESULT WINAPI speech_token_GetDescription( ISpeechObjectToken *iface, LONG locale, BSTR *desc ) { - FIXME( "stub\n" ); - return E_NOTIMPL; + struct object_token *This = impl_from_ISpeechObjectToken( iface ); + WCHAR langid[5]; + WCHAR *desc_wstr = NULL; + HRESULT hr; + + TRACE( "(%p)->(%#lx %p)\n", This, locale, desc ); + + if (!desc) return E_POINTER; + + swprintf( langid, ARRAY_SIZE( langid ), L"%X", LANGIDFROMLCID( locale ) ); + + hr = ISpObjectToken_GetStringValue( &This->ISpObjectToken_iface, langid, &desc_wstr ); + if (hr == SPERR_NOT_FOUND) + hr = ISpObjectToken_GetStringValue( &This->ISpObjectToken_iface, NULL, &desc_wstr ); + if (FAILED(hr)) + return hr; + + *desc = SysAllocString( desc_wstr ); + + CoTaskMemFree( desc_wstr ); + return *desc ? S_OK : E_OUTOFMEMORY; }
static HRESULT WINAPI speech_token_SetId( ISpeechObjectToken *iface,
From: Shaun Ren sren@codeweavers.com
--- dlls/sapi/Makefile.in | 1 + dlls/sapi/dispatch.c | 85 ++++++++++++++++++++++++++++++++++++++++ dlls/sapi/sapi_private.h | 9 +++++ dlls/sapi/tests/token.c | 20 ++++++++++ dlls/sapi/token.c | 14 ++++++- 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 dlls/sapi/dispatch.c
diff --git a/dlls/sapi/Makefile.in b/dlls/sapi/Makefile.in index 008d0f74545..9c3950f08da 100644 --- a/dlls/sapi/Makefile.in +++ b/dlls/sapi/Makefile.in @@ -5,6 +5,7 @@ DELAYIMPORTS = winmm SOURCES = \ async.c \ automation.c \ + dispatch.c \ main.c \ mmaudio.c \ resource.c \ diff --git a/dlls/sapi/dispatch.c b/dlls/sapi/dispatch.c new file mode 100644 index 00000000000..df0c6c9bf9c --- /dev/null +++ b/dlls/sapi/dispatch.c @@ -0,0 +1,85 @@ +/* + * ITypeInfo cache for IDispatch + * + * Copyright 2019 Zebediah Figura + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "wine/debug.h" + +#define COBJMACROS + +#include "objbase.h" +#include "sapiddk.h" + +#include "sapi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(sapi); + +static ITypeLib *typelib; +static ITypeInfo *typeinfos[last_tid]; + +static REFIID tid_id[] = +{ + &IID_ISpeechObjectToken, +}; + +HRESULT get_typeinfo(enum type_id tid, ITypeInfo **ret) +{ + HRESULT hr; + + if (!typelib) + { + ITypeLib *tl; + + hr = LoadRegTypeLib(&LIBID_SpeechLib, 5, 4, LOCALE_SYSTEM_DEFAULT, &tl); + if (FAILED(hr)) + { + ERR("Failed to load typelib, hr %#lx.\n", hr); + return hr; + } + if (InterlockedCompareExchangePointer((void **)&typelib, tl, NULL)) + ITypeLib_Release(tl); + } + if (!typeinfos[tid]) + { + ITypeInfo *typeinfo; + + hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_id[tid], &typeinfo); + if (FAILED(hr)) + { + ERR("Failed to get type info for %s, hr %#lx.\n", debugstr_guid(tid_id[tid]), hr); + return hr; + } + if (InterlockedCompareExchangePointer((void **)(typeinfos + tid), typeinfo, NULL)) + ITypeInfo_Release(typeinfo); + } + ITypeInfo_AddRef(*ret = typeinfos[tid]); + return S_OK; +} + +void release_typelib(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(typeinfos); ++i) + { + if (typeinfos[i]) + ITypeInfo_Release(typeinfos[i]); + } + if (typelib) + ITypeLib_Release(typelib); +} diff --git a/dlls/sapi/sapi_private.h b/dlls/sapi/sapi_private.h index f6a5e966461..9a3c92cc4dc 100644 --- a/dlls/sapi/sapi_private.h +++ b/dlls/sapi/sapi_private.h @@ -52,3 +52,12 @@ HRESULT mmaudio_out_create( IUnknown *outer, REFIID iid, void **obj ); HRESULT token_category_create( IUnknown *outer, REFIID iid, void **obj ); HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj ); HRESULT token_create( IUnknown *outer, REFIID iid, void **obj ); + +enum type_id +{ + ISpeechObjectToken_tid, + last_tid +}; + +HRESULT get_typeinfo( enum type_id tid, ITypeInfo **typeinfo ); +void release_typelib( void ); diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c index a651eb47c62..ec8a101fea4 100644 --- a/dlls/sapi/tests/token.c +++ b/dlls/sapi/tests/token.c @@ -26,6 +26,8 @@
#include "wine/test.h"
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); + static void test_data_key(void) { ISpRegDataKey *data_key; @@ -669,6 +671,8 @@ static void test_object_token(void) ISpObjectTokenCategory *cat; DWORD regid; IUnknown *obj; + DISPPARAMS params; + VARIANT arg, ret;
hr = CoCreateInstance( &CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER, &IID_ISpObjectToken, (void **)&token ); @@ -915,6 +919,22 @@ static void test_object_token(void) ok( tempB && !wcscmp( tempB, L"TestToken" ), "got %s\n", wine_dbgstr_w( tempB ) ); SysFreeString( tempB );
+ memset( ¶ms, 0, sizeof(params) ); + params.cArgs = 1; + params.cNamedArgs = 0; + params.rgvarg = &arg; + VariantInit( &arg ); + V_VT( &arg ) = VT_I4; + V_I4( &arg ) = 0x409; + VariantInit( &ret ); + hr = ISpeechObjectToken_Invoke( speech_token, DISPID_SOTGetDescription, &IID_NULL, + 0, DISPATCH_METHOD, ¶ms, &ret, NULL, NULL ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( V_VT( &ret ) == VT_BSTR, "got %#x\n", V_VT( &ret ) ); + ok( V_BSTR( &ret ) && !wcscmp( V_BSTR( &ret ), L"409 - TestToken" ), + "got %s\n", wine_dbgstr_w( V_BSTR( &ret ) ) ); + VariantClear( &ret ); + ISpeechObjectToken_Release( speech_token );
ISpObjectToken_Release( test_class_token ); diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index e5d87505e34..c8cb806bbae 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -1801,8 +1801,18 @@ static HRESULT WINAPI speech_token_Invoke( ISpeechObjectToken *iface, EXCEPINFO *excepinfo, UINT *argerr ) { - FIXME( "stub\n" ); - return E_NOTIMPL; + ITypeInfo *ti; + HRESULT hr; + + TRACE( "(%p)->(%ld %s %#lx %#x %p %p %p %p)\n", iface, dispid, + debugstr_guid( iid ), lcid, flags, params, result, excepinfo, argerr ); + + if (FAILED(hr = get_typeinfo( ISpeechObjectToken_tid, &ti ))) + return hr; + hr = ITypeInfo_Invoke( ti, iface, dispid, flags, params, result, excepinfo, argerr ); + ITypeInfo_Release( ti ); + + return hr; }
static HRESULT WINAPI speech_token_get_Id( ISpeechObjectToken *iface,
From: Shaun Ren sren@codeweavers.com
--- dlls/sapi/tests/token.c | 7 +++++++ dlls/sapi/token.c | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c index ec8a101fea4..6265cde2bc3 100644 --- a/dlls/sapi/tests/token.c +++ b/dlls/sapi/tests/token.c @@ -660,6 +660,7 @@ static IClassFactory test_class_cf = { &ClassFactoryVtbl }; static void test_object_token(void) { static const WCHAR test_token_id[] = L"HKEY_LOCAL_MACHINE\Software\Winetest\sapi\TestToken"; + static const WCHAR *get_description = L"GetDescription";
ISpObjectToken *token; IDispatch *disp; @@ -671,6 +672,7 @@ static void test_object_token(void) ISpObjectTokenCategory *cat; DWORD regid; IUnknown *obj; + DISPID dispid; DISPPARAMS params; VARIANT arg, ret;
@@ -919,6 +921,11 @@ static void test_object_token(void) ok( tempB && !wcscmp( tempB, L"TestToken" ), "got %s\n", wine_dbgstr_w( tempB ) ); SysFreeString( tempB );
+ dispid = 0xdeadbeef; + hr = ISpeechObjectToken_GetIDsOfNames( speech_token, &IID_NULL, (WCHAR **)&get_description, 1, 0x409, &dispid ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( dispid == DISPID_SOTGetDescription, "got %08lx\n", dispid ); + memset( ¶ms, 0, sizeof(params) ); params.cArgs = 1; params.cNamedArgs = 0; diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index c8cb806bbae..888da86d7a4 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -1787,8 +1787,18 @@ static HRESULT WINAPI speech_token_GetIDsOfNames( ISpeechObjectToken *iface, LCID lcid, DISPID *dispids ) { - FIXME( "stub\n" ); - return E_NOTIMPL; + ITypeInfo *ti; + HRESULT hr; + + TRACE( "(%p)->(%s %p %u %#lx %p)\n", + iface, debugstr_guid( iid ), names, count, lcid, dispids ); + + if (FAILED(hr = get_typeinfo( ISpeechObjectToken_tid, &ti ))) + return hr; + hr = ITypeInfo_GetIDsOfNames( ti, names, count, dispids ); + ITypeInfo_Release( ti ); + + return hr; }
static HRESULT WINAPI speech_token_Invoke( ISpeechObjectToken *iface,
From: Shaun Ren sren@codeweavers.com
--- dlls/sapi/tests/token.c | 5 +++++ dlls/sapi/token.c | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c index 6265cde2bc3..a68a0b7cd46 100644 --- a/dlls/sapi/tests/token.c +++ b/dlls/sapi/tests/token.c @@ -362,6 +362,11 @@ static void test_token_enum(void) hr = ISpObjectTokenEnumBuilder_AddTokens( token_enum, 3, tokens ); ok( hr == S_OK, "got %08lx\n", hr );
+ count = 0xdeadbeef; + hr = ISpeechObjectTokens_get_Count( speech_tokens, (LONG *)&count ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( count == 3, "got %lu\n", count ); + hr = ISpeechObjectTokens_get__NewEnum( speech_tokens, &unk ); ok( hr == S_OK, "got %08lx\n", hr ); hr = IUnknown_QueryInterface( unk, &IID_IEnumVARIANT, (void **)&enumvar ); diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index 888da86d7a4..2cfc34304c9 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -1313,8 +1313,11 @@ static HRESULT WINAPI speech_tokens_Invoke( ISpeechObjectTokens *iface, static HRESULT WINAPI speech_tokens_get_Count( ISpeechObjectTokens *iface, LONG *count ) { - FIXME( "stub\n" ); - return E_NOTIMPL; + struct token_enum *This = impl_from_ISpeechObjectTokens( iface ); + + TRACE( "(%p)->(%p)\n", This, count ); + + return ISpObjectTokenEnumBuilder_GetCount( &This->ISpObjectTokenEnumBuilder_iface, (ULONG *)count ); }
static HRESULT WINAPI speech_tokens_Item( ISpeechObjectTokens *iface,
From: Shaun Ren sren@codeweavers.com
--- dlls/sapi/Makefile.in | 2 +- dlls/sapi/tests/token.c | 28 ++++++++++++++++++++++++++++ dlls/sapi/token.c | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/dlls/sapi/Makefile.in b/dlls/sapi/Makefile.in index 9c3950f08da..a6c4d86037e 100644 --- a/dlls/sapi/Makefile.in +++ b/dlls/sapi/Makefile.in @@ -1,5 +1,5 @@ MODULE = sapi.dll -IMPORTS = uuid ole32 user32 advapi32 +IMPORTS = uuid ole32 oleaut32 user32 advapi32 DELAYIMPORTS = winmm
SOURCES = \ diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c index a68a0b7cd46..89cbb5150a4 100644 --- a/dlls/sapi/tests/token.c +++ b/dlls/sapi/tests/token.c @@ -256,6 +256,7 @@ static void test_token_enum(void) ISpObjectToken *out_tokens[5]; WCHAR token_id[MAX_PATH]; ULONG count; + VARIANT vars[3]; int i;
hr = CoCreateInstance( &CLSID_SpObjectTokenEnum, NULL, CLSCTX_INPROC_SERVER, @@ -372,6 +373,33 @@ static void test_token_enum(void) hr = IUnknown_QueryInterface( unk, &IID_IEnumVARIANT, (void **)&enumvar ); ok( hr == S_OK, "got %08lx\n", hr ); IUnknown_Release( unk ); + + V_VT( &vars[0] ) = VT_ILLEGAL; + V_DISPATCH( &vars[0] ) = (IDispatch *)0xdeadbeef; + hr = IEnumVARIANT_Next( enumvar, 1, vars, NULL ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( V_VT( &vars[0] ) == VT_DISPATCH, "got %#x\n", V_VT( &vars[0] ) ); + ok( V_DISPATCH( &vars[0] ) != (IDispatch *)0xdeadbeef && V_DISPATCH( &vars[0] ) != NULL, + "got %p\n", V_DISPATCH( &vars[0] ) ); + VariantClear( &vars[0] ); + + for ( i = 0; i < 3; i++ ) { + V_VT( &vars[i] ) = VT_ILLEGAL; + V_DISPATCH( &vars[i] ) = (IDispatch *)0xdeadbeef; + } + count = 0xdeadbeef; + + hr = IEnumVARIANT_Next( enumvar, 3, vars, &count ); + ok( hr == S_FALSE, "got %08lx\n", hr ); + ok( count == 2, "got %lu\n", count ); + for ( i = 0; i < 2; i++ ) { + ok( V_VT( &vars[i] ) == VT_DISPATCH, "got %#x\n", V_VT( &vars[i] ) ); + ok( V_DISPATCH( &vars[i] ) != (IDispatch *)0xdeadbeef && V_DISPATCH( &vars[i] ) != NULL, + "got %p\n", V_DISPATCH( &vars[i] ) ); + VariantClear( &vars[i] ); + } + ok( V_VT( &vars[2] ) == VT_ILLEGAL, "got %#x\n", V_VT( &vars[2] ) ); + IEnumVARIANT_Release( enumvar );
ISpeechObjectTokens_Release( speech_tokens ); diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index 2cfc34304c9..b7f78fe98bd 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -1206,8 +1206,41 @@ static ULONG WINAPI enum_var_Release( IEnumVARIANT *iface ) static HRESULT WINAPI enum_var_Next( IEnumVARIANT *iface, ULONG count, VARIANT *vars, ULONG *fetched ) { - FIXME( "stub\n" ); - return E_NOTIMPL; + struct enum_var *This = impl_from_IEnumVARIANT( iface ); + ULONG i, total; + HRESULT hr; + + TRACE( "(%p)->(%lu %p %p)\n", This, count, vars, fetched ); + + if (fetched) *fetched = 0; + + if (FAILED(hr = ISpObjectTokenEnumBuilder_GetCount( This->token_enum, &total ))) + return hr; + + for ( i = 0; i < count && This->index < total; i++, This->index++ ) + { + ISpObjectToken *token; + IDispatch *disp; + + if (FAILED(hr = ISpObjectTokenEnumBuilder_Item( This->token_enum, This->index, &token ))) + goto fail; + + hr = ISpObjectToken_QueryInterface( token, &IID_IDispatch, (void **)&disp ); + ISpObjectToken_Release( token ); + if (FAILED(hr)) goto fail; + + VariantInit( &vars[i] ); + V_VT( &vars[i] ) = VT_DISPATCH; + V_DISPATCH( &vars[i] ) = disp; + } + + if (fetched) *fetched = i; + return i == count ? S_OK : S_FALSE; + +fail: + while (i--) + VariantClear( &vars[i] ); + return hr; }
static HRESULT WINAPI enum_var_Skip( IEnumVARIANT *iface, ULONG count )
From: Shaun Ren sren@codeweavers.com
--- dlls/sapi/dispatch.c | 1 + dlls/sapi/sapi_private.h | 1 + dlls/sapi/tests/token.c | 11 ++++++++++- dlls/sapi/token.c | 14 ++++++++++++-- 4 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/dlls/sapi/dispatch.c b/dlls/sapi/dispatch.c index df0c6c9bf9c..731ae9ae48f 100644 --- a/dlls/sapi/dispatch.c +++ b/dlls/sapi/dispatch.c @@ -35,6 +35,7 @@ static ITypeInfo *typeinfos[last_tid]; static REFIID tid_id[] = { &IID_ISpeechObjectToken, + &IID_ISpeechObjectTokens, };
HRESULT get_typeinfo(enum type_id tid, ITypeInfo **ret) diff --git a/dlls/sapi/sapi_private.h b/dlls/sapi/sapi_private.h index 9a3c92cc4dc..55e1460ad38 100644 --- a/dlls/sapi/sapi_private.h +++ b/dlls/sapi/sapi_private.h @@ -56,6 +56,7 @@ HRESULT token_create( IUnknown *outer, REFIID iid, void **obj ); enum type_id { ISpeechObjectToken_tid, + ISpeechObjectTokens_tid, last_tid };
diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c index 89cbb5150a4..6d2c40ea154 100644 --- a/dlls/sapi/tests/token.c +++ b/dlls/sapi/tests/token.c @@ -256,7 +256,8 @@ static void test_token_enum(void) ISpObjectToken *out_tokens[5]; WCHAR token_id[MAX_PATH]; ULONG count; - VARIANT vars[3]; + VARIANT vars[3], ret; + DISPPARAMS params; int i;
hr = CoCreateInstance( &CLSID_SpObjectTokenEnum, NULL, CLSCTX_INPROC_SERVER, @@ -402,6 +403,14 @@ static void test_token_enum(void)
IEnumVARIANT_Release( enumvar );
+ memset( ¶ms, 0, sizeof(params) ); + VariantInit( &ret ); + hr = ISpeechObjectTokens_Invoke( speech_tokens, DISPID_SOTsCount, &IID_NULL, 0, + DISPATCH_PROPERTYGET, ¶ms, &ret, NULL, NULL ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( V_VT( &ret ) == VT_I4, "got %#x\n", V_VT( &ret ) ); + ok( V_I4( &ret ) == 3, "got %ld\n", V_I4( &ret ) ); + ISpeechObjectTokens_Release( speech_tokens ); ISpObjectTokenEnumBuilder_Release( token_enum );
diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c index b7f78fe98bd..ad8163c9567 100644 --- a/dlls/sapi/token.c +++ b/dlls/sapi/token.c @@ -1339,8 +1339,18 @@ static HRESULT WINAPI speech_tokens_Invoke( ISpeechObjectTokens *iface, EXCEPINFO *excepinfo, UINT *argerr ) { - FIXME( "stub\n" ); - return E_NOTIMPL; + ITypeInfo *ti; + HRESULT hr; + + TRACE( "(%p)->(%ld %s %#lx %#x %p %p %p %p)\n", iface, dispid, + debugstr_guid( iid ), lcid, flags, params, result, excepinfo, argerr ); + + if (FAILED(hr = get_typeinfo( ISpeechObjectTokens_tid, &ti ))) + return hr; + hr = ITypeInfo_Invoke( ti, iface, dispid, flags, params, result, excepinfo, argerr ); + ITypeInfo_Release( ti ); + + return hr; }
static HRESULT WINAPI speech_tokens_get_Count( ISpeechObjectTokens *iface,
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 tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=143051
Your paranoid android.
=== debian11b (64 bit WoW report) ===
adsldp: ldap: Timeout