[PATCH] sapi: ISpObjectToken CreateInstance support ISpAudio

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Tue Sep 28 04:36:15 CDT 2021


Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/sapi/tests/token.c |  22 ++++
 dlls/sapi/token.c       | 283 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 304 insertions(+), 1 deletion(-)

diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c
index 47196d42dc7..fdb30975b1b 100644
--- a/dlls/sapi/tests/token.c
+++ b/dlls/sapi/tests/token.c
@@ -297,6 +297,27 @@ static void test_object_token(void)
     ISpObjectToken_Release( token );
 }
 
+static void test_token_create_instance(void)
+{
+    ISpObjectToken *token;
+    HRESULT hr;
+    ISpAudio *audio;
+
+    hr = CoCreateInstance( &CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER,
+                           &IID_ISpObjectToken, (void **)&token );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = ISpObjectToken_SetId( token, NULL, L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\AudioOutput\\TokenEnums\\MMAudioOut\\", FALSE );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = ISpObjectToken_CreateInstance( token, NULL, CLSCTX_ALL, &IID_ISpAudio, (void**)&audio);
+    ok( hr == S_OK, "got %08x\n", hr );
+    if (hr == S_OK)
+        ISpAudio_Release(audio);
+
+    ISpObjectToken_Release( token );
+}
+
 START_TEST(token)
 {
     CoInitialize( NULL );
@@ -305,5 +326,6 @@ START_TEST(token)
     test_token_enum();
     test_default_token_id();
     test_object_token();
+    test_token_create_instance();
     CoUninitialize();
 }
diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c
index ba91a425e9e..c7ab034c94f 100644
--- a/dlls/sapi/token.c
+++ b/dlls/sapi/token.c
@@ -968,13 +968,294 @@ static HRESULT WINAPI token_GetCategory( ISpObjectToken *iface,
     return E_NOTIMPL;
 }
 
+struct speech_audio
+{
+    ISpAudio ISpAudio_iface;
+    LONG ref;
+};
+
+static inline struct speech_audio *impl_from_ISpAudio(ISpAudio *iface)
+{
+    return CONTAINING_RECORD(iface, struct speech_audio, ISpAudio_iface);
+}
+
+static HRESULT WINAPI spaudio_QueryInterface(ISpAudio *iface, REFIID iid, void **obj)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+
+    TRACE("(%p, %s %p).\n", audio, debugstr_guid(iid), obj);
+
+    if (IsEqualIID(iid, &IID_IUnknown) ||
+        IsEqualIID(iid, &IID_ISequentialStream) ||
+        IsEqualIID(iid, &IID_IStream) ||
+        IsEqualIID(iid, &IID_ISpStreamFormat) ||
+        IsEqualIID(iid, &IID_ISpAudio))
+        *obj = &audio->ISpAudio_iface;
+    else
+    {
+        *obj = NULL;
+        FIXME("interface %s not implemented.\n", debugstr_guid(iid));
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown *)*obj);
+    return S_OK;
+}
+
+static ULONG WINAPI spaudio_AddRef(ISpAudio *iface)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    ULONG ref = InterlockedIncrement(&audio->ref);
+
+    TRACE("(%p): ref=%u.\n", audio, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI spaudio_Release(ISpAudio *iface)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    ULONG ref = InterlockedDecrement(&audio->ref);
+
+    TRACE("(%p): ref=%u.\n", audio, ref);
+
+    if (!ref)
+    {
+        heap_free(audio);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI spaudio_Read(ISpAudio *iface,void *pv, ULONG cb, ULONG *pcbRead)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+
+    FIXME("%p, %p, %d %p\n", audio, pv, cb, pcbRead);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_Write(ISpAudio *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+
+    FIXME("%p, %p, %d %p\n", audio, pv, cb, pcbWritten);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_Seek(ISpAudio *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %s, %d, %p\n", audio, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_SetSize(ISpAudio *iface, ULARGE_INTEGER libNewSize)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("(%p, %s)\n", audio, wine_dbgstr_longlong(libNewSize.QuadPart));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_CopyTo(ISpAudio *iface,IStream *pstm, ULARGE_INTEGER cb,
+        ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("(%p, %p, %s, %p, %p)\n", audio, pstm, wine_dbgstr_longlong(cb.QuadPart), pcbRead, pcbWritten);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_Commit(ISpAudio *iface,DWORD grfCommitFlags)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("(%p, %#x)\n", audio, grfCommitFlags);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_Revert(ISpAudio *iface)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("(%p)\n", audio);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_LockRegion(ISpAudio *iface, ULARGE_INTEGER offset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("(%p, %s, %s, %d)\n", audio, wine_dbgstr_longlong(offset.QuadPart),
+        wine_dbgstr_longlong(cb.QuadPart), dwLockType);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_UnlockRegion(ISpAudio *iface,ULARGE_INTEGER offset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("(%p, %s, %s, %d)\n", audio, wine_dbgstr_longlong(offset.QuadPart),
+        wine_dbgstr_longlong(cb.QuadPart), dwLockType);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_Stat(ISpAudio *iface, STATSTG *stg, DWORD flag)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %p, %d\n", audio, stg, flag);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_Clone(ISpAudio *iface, IStream **ppstm)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %p\n", audio, ppstm);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_GetFormat(ISpAudio *iface, GUID *format, WAVEFORMATEX **wave)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %p, %p\n", audio, format, wave);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_SetState(ISpAudio *iface, SPAUDIOSTATE state, ULONGLONG reserved)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %d, %s\n", audio, state, wine_dbgstr_longlong(reserved));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_SetFormat(ISpAudio *iface, REFGUID guid, const WAVEFORMATEX *wave)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %s, %p\n", audio, debugstr_guid(guid), wave);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_GetStatus(ISpAudio *iface, SPAUDIOSTATUS *status)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %p\n", audio, status);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_SetBufferInfo(ISpAudio *iface,const SPAUDIOBUFFERINFO *buffer)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %p\n", audio, buffer);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_GetBufferInfo(ISpAudio *iface, SPAUDIOBUFFERINFO *buffer)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %p\n", audio, buffer);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_GetDefaultFormat(ISpAudio *iface, GUID *guid, WAVEFORMATEX **wave)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %p, %p\n", audio, guid, wave);
+    return E_NOTIMPL;
+}
+
+static HANDLE WINAPI spaudio_EventHandle(ISpAudio *iface)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p\n", audio);
+    return NULL;
+}
+
+static HRESULT WINAPI spaudio_GetVolumeLevel(ISpAudio *iface, ULONG *level)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %p\n", audio, level);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_SetVolumeLevel(ISpAudio *iface, ULONG level)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %d\n", audio, level);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_GetBufferNotifySize(ISpAudio *iface, ULONG *size)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %p\n", audio, size);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spaudio_SetBufferNotifySize(ISpAudio *iface, ULONG size)
+{
+    struct speech_audio *audio = impl_from_ISpAudio(iface);
+    FIXME("%p, %d\n", audio, size);
+    return E_NOTIMPL;
+}
+
+const struct ISpAudioVtbl spaudio_vtbl =
+{
+    spaudio_QueryInterface,
+    spaudio_AddRef,
+    spaudio_Release,
+    spaudio_Read,
+    spaudio_Write,
+    spaudio_Seek,
+    spaudio_SetSize,
+    spaudio_CopyTo,
+    spaudio_Commit,
+    spaudio_Revert,
+    spaudio_LockRegion,
+    spaudio_UnlockRegion,
+    spaudio_Stat,
+    spaudio_Clone,
+    spaudio_GetFormat,
+    spaudio_SetState,
+    spaudio_SetFormat,
+    spaudio_GetStatus,
+    spaudio_SetBufferInfo,
+    spaudio_GetBufferInfo,
+    spaudio_GetDefaultFormat,
+    spaudio_EventHandle,
+    spaudio_GetVolumeLevel,
+    spaudio_SetVolumeLevel,
+    spaudio_GetBufferNotifySize,
+    spaudio_SetBufferNotifySize
+};
+
+static HRESULT speech_audio_create(void **obj)
+{
+    struct speech_audio *audio;
+
+    audio = heap_alloc(sizeof(*audio));
+    if (!audio)
+        return E_OUTOFMEMORY;
+
+    audio->ISpAudio_iface.lpVtbl = &spaudio_vtbl;
+    audio->ref = 1;
+
+    *obj = &audio->ISpAudio_iface;
+    return S_OK;
+}
+
 static HRESULT WINAPI token_CreateInstance( ISpObjectToken *iface,
                                             IUnknown *outer,
                                             DWORD class_context,
                                             REFIID riid,
                                             void **object )
 {
-    FIXME( "stub\n" );
+    struct object_token *This = impl_from_ISpObjectToken( iface );
+
+    TRACE( "(%p)->(%p 0x%08x %s, %p)\n", This, outer, class_context, debugstr_guid( riid ), object);
+
+    if (IsEqualIID(riid, &IID_ISpAudio))
+    {
+        return speech_audio_create(object);
+    }
+
+    FIXME( "Unsupported interface %s\n", debugstr_guid( riid ));
     return E_NOTIMPL;
 }
 
-- 
2.33.0




More information about the wine-devel mailing list