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 )