From: Shaun Ren sren@codeweavers.com
--- dlls/sapi/stream.c | 113 +++++++++++++++++++++++++++++++-------- dlls/sapi/tests/stream.c | 112 +++++++++++++++++++++++++++++++++++--- 2 files changed, 197 insertions(+), 28 deletions(-)
diff --git a/dlls/sapi/stream.c b/dlls/sapi/stream.c index 4fe86b19014..9037bf52334 100644 --- a/dlls/sapi/stream.c +++ b/dlls/sapi/stream.c @@ -103,81 +103,150 @@ static ULONG WINAPI spstream_Release(ISpStream *iface)
static HRESULT WINAPI spstream_Read(ISpStream *iface, void *pv, ULONG cb, ULONG *read) { - FIXME("(%p, %p, %ld, %p): stub.\n", iface, pv, cb, read); + struct spstream *This = impl_from_ISpStream(iface);
- return E_NOTIMPL; + TRACE("(%p, %p, %ld, %p).\n", iface, pv, cb, read); + + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_Read(This->base_stream, pv, cb, read); }
static HRESULT WINAPI spstream_Write(ISpStream *iface, const void *pv, ULONG cb, ULONG *written) { - FIXME("(%p, %p, %ld, %p): stub.\n", iface, pv, cb, written); + struct spstream *This = impl_from_ISpStream(iface);
- return E_NOTIMPL; + TRACE("(%p, %p, %ld, %p).\n", iface, pv, cb, written); + + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_Write(This->base_stream, pv, cb, written); }
static HRESULT WINAPI spstream_Seek(ISpStream *iface, LARGE_INTEGER mode, DWORD origin, ULARGE_INTEGER *position) { - FIXME("(%p, %s, %ld, %p): stub.\n", iface, wine_dbgstr_longlong(mode.QuadPart), origin, position); + struct spstream *This = impl_from_ISpStream(iface);
- return E_NOTIMPL; + TRACE("(%p, %s, %ld, %p).\n", iface, wine_dbgstr_longlong(mode.QuadPart), origin, position); + + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_Seek(This->base_stream, mode, origin, position); }
static HRESULT WINAPI spstream_SetSize(ISpStream *iface, ULARGE_INTEGER size) { - FIXME("(%p, %s): stub.\n", iface, wine_dbgstr_longlong(size.QuadPart)); + struct spstream *This = impl_from_ISpStream(iface);
- return E_NOTIMPL; + TRACE("(%p, %s).\n", iface, wine_dbgstr_longlong(size.QuadPart)); + + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_SetSize(This->base_stream, size); }
static HRESULT WINAPI spstream_CopyTo(ISpStream *iface, IStream *stream, ULARGE_INTEGER cb, ULARGE_INTEGER *read, ULARGE_INTEGER *written) { - FIXME("(%p, %p, %s, %p, %p): stub.\n", iface, stream, wine_dbgstr_longlong(cb.QuadPart), - read, written); + struct spstream *This = impl_from_ISpStream(iface);
- return E_NOTIMPL; + TRACE("(%p, %p, %s, %p, %p).\n", iface, stream, wine_dbgstr_longlong(cb.QuadPart), read, written); + + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_CopyTo(This->base_stream, stream, cb, read, written); }
static HRESULT WINAPI spstream_Commit(ISpStream *iface, DWORD flag) { - FIXME("(%p, %ld): stub.\n", iface, flag); + struct spstream *This = impl_from_ISpStream(iface);
- return E_NOTIMPL; + TRACE("(%p, %ld).\n", iface, flag); + + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_Commit(This->base_stream, flag); }
static HRESULT WINAPI spstream_Revert(ISpStream *iface) { - FIXME("(%p): stub.\n", iface); + struct spstream *This = impl_from_ISpStream(iface);
- return E_NOTIMPL; + TRACE("(%p).\n", iface); + + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_Revert(This->base_stream); }
static HRESULT WINAPI spstream_LockRegion(ISpStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER cb, DWORD type) { - FIXME("(%p, %s, %s, %ld): stub.\n", iface, wine_dbgstr_longlong(offset.QuadPart), + struct spstream *This = impl_from_ISpStream(iface); + + TRACE("(%p, %s, %s, %ld).\n", iface, wine_dbgstr_longlong(offset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), type);
- return E_NOTIMPL; + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_LockRegion(This->base_stream, offset, cb, type); }
static HRESULT WINAPI spstream_UnlockRegion(ISpStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER cb, DWORD type) { - FIXME("(%p, %s, %s, %ld): stub.\n", iface, wine_dbgstr_longlong(offset.QuadPart), + struct spstream *This = impl_from_ISpStream(iface); + + TRACE("(%p, %s, %s, %ld).\n", iface, wine_dbgstr_longlong(offset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), type);
- return E_NOTIMPL; + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_UnlockRegion(This->base_stream, offset, cb, type); }
static HRESULT WINAPI spstream_Stat(ISpStream *iface, STATSTG *statstg, DWORD flag) { - FIXME("(%p, %p, %ld): stub.\n", iface, statstg, flag); + struct spstream *This = impl_from_ISpStream(iface);
- return E_NOTIMPL; + TRACE("(%p, %p, %ld).\n", iface, statstg, flag); + + if (This->closed) + return SPERR_STREAM_CLOSED; + else if (!This->base_stream) + return SPERR_UNINITIALIZED; + + return IStream_Stat(This->base_stream, statstg, flag); }
static HRESULT WINAPI spstream_Clone(ISpStream *iface, IStream **stream) { - FIXME("(%p, %p): stub.\n", iface, stream); + TRACE("(%p, %p).\n", iface, stream);
return E_NOTIMPL; } diff --git a/dlls/sapi/tests/stream.c b/dlls/sapi/tests/stream.c index 6613f7ea723..7920eed9b7f 100644 --- a/dlls/sapi/tests/stream.c +++ b/dlls/sapi/tests/stream.c @@ -93,6 +93,11 @@ static void test_spstream(void) IStream *base_stream, *base_stream2; GUID fmtid, fmtid2; WAVEFORMATEX *wfx = NULL, *wfx2 = NULL; + char buf[4] = {0}; + ULONG read, written; + LARGE_INTEGER zero = {0}; + ULARGE_INTEGER uzero = {0}, size, pos; + STATSTG statstg; HRESULT hr;
hr = CoCreateInstance(&CLSID_SpMMAudioOut, NULL, CLSCTX_INPROC_SERVER, @@ -110,12 +115,6 @@ static void test_spstream(void) &IID_ISpStream, (void **)&stream); ok(hr == S_OK, "Failed to create ISpStream interface: %#lx.\n", hr);
- hr = ISpStream_SetBaseStream(stream, NULL, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#lx.\n", hr); - - hr = ISpStream_SetBaseStream(stream, base_stream, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#lx.\n", hr); - hr = ISpStream_GetBaseStream(stream, &base_stream2); ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr);
@@ -131,6 +130,40 @@ static void test_spstream(void) &IID_ISpStream, (void **)&stream); ok(hr == S_OK, "Failed to create ISpStream interface: %#lx.\n", hr);
+ hr = ISpStream_Read(stream, buf, sizeof(buf), &read); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + hr = ISpStream_Write(stream, buf, sizeof(buf), &written); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + hr = ISpStream_Seek(stream, zero, STREAM_SEEK_CUR, &pos); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + size.QuadPart = 4; + hr = ISpStream_SetSize(stream, size); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + hr = ISpStream_CopyTo(stream, NULL, size, NULL, NULL); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + hr = ISpStream_Commit(stream, 0); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + hr = ISpStream_Revert(stream); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + hr = ISpStream_LockRegion(stream, uzero, size, LOCK_WRITE); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + hr = ISpStream_UnlockRegion(stream, uzero, size, LOCK_WRITE); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + hr = ISpStream_Stat(stream, &statstg, 0); + ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr); + + hr = ISpStream_Clone(stream, NULL); + ok(hr == E_NOTIMPL, "got %#lx.\n", hr); + hr = ISpStream_GetFormat(stream, &fmtid2, &wfx2); ok(hr == SPERR_UNINITIALIZED, "got %#lx.\n", hr);
@@ -155,6 +188,40 @@ static void test_spstream(void) ok(IsEqualGUID(&fmtid2, &SPDFID_WaveFormatEx), "got %s.\n", wine_dbgstr_guid(&fmtid2)); ok(!memcmp(wfx, wfx2, sizeof(WAVEFORMATEX)), "wfx mismatch.\n");
+ /* TODO: Many IStream methods are not yet implemented in SpMMSysAudio. */ + hr = ISpStream_Read(stream, buf, sizeof(buf), &read); + todo_wine ok(hr == STG_E_ACCESSDENIED, "got %#lx.\n", hr); + + hr = ISpStream_Write(stream, buf, sizeof(buf), &written); + ok(hr == SP_AUDIO_STOPPED, "got %#lx.\n", hr); + + hr = ISpStream_Seek(stream, zero, STREAM_SEEK_CUR, &pos); + todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + + hr = ISpStream_SetSize(stream, size); + todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + + hr = ISpStream_CopyTo(stream, NULL, size, NULL, NULL); + todo_wine ok(hr == STG_E_ACCESSDENIED, "got %#lx.\n", hr); + + hr = ISpStream_Commit(stream, 0); + todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + + hr = ISpStream_Revert(stream); + ok(hr == E_NOTIMPL, "got %#lx.\n", hr); + + hr = ISpStream_LockRegion(stream, uzero, size, LOCK_WRITE); + ok(hr == E_NOTIMPL, "got %#lx.\n", hr); + + hr = ISpStream_UnlockRegion(stream, uzero, size, LOCK_WRITE); + ok(hr == E_NOTIMPL, "got %#lx.\n", hr); + + hr = ISpStream_Stat(stream, &statstg, 0); + todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + + hr = ISpStream_Clone(stream, NULL); + ok(hr == E_NOTIMPL, "got %#lx.\n", hr); + hr = ISpStream_Close(stream); ok(hr == S_OK, "got %#lx.\n", hr);
@@ -167,6 +234,39 @@ static void test_spstream(void) hr = ISpStream_GetFormat(stream, &fmtid2, &wfx2); ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr);
+ hr = ISpStream_Read(stream, buf, sizeof(buf), &read); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_Write(stream, buf, sizeof(buf), &written); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_Seek(stream, zero, STREAM_SEEK_CUR, &pos); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_SetSize(stream, size); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_CopyTo(stream, NULL, size, NULL, NULL); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_Commit(stream, 0); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_Revert(stream); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_LockRegion(stream, uzero, size, LOCK_WRITE); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_UnlockRegion(stream, uzero, size, LOCK_WRITE); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_Stat(stream, &statstg, 0); + ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr); + + hr = ISpStream_Clone(stream, NULL); + ok(hr == E_NOTIMPL, "got %#lx.\n", hr); + hr = ISpStream_Close(stream); ok(hr == SPERR_STREAM_CLOSED, "got %#lx.\n", hr);