Module: wine Branch: master Commit: fd07191673dea171af0449654d3106c5d6429025 URL: http://source.winehq.org/git/wine.git/?a=commit;h=fd07191673dea171af0449654d...
Author: Rob Shearman rob@codeweavers.com Date: Tue Jan 9 17:16:07 2007 +0000
ole32: Fix HGLOBALStreamImpl_CopyTo to check the return values of IStream_Read and IStream_Write and to not compare the bytes read to the bytes written.
Add tests for IStream::CopyTo of the HGLOBAL stream implementation.
---
dlls/ole32/hglobalstream.c | 20 ++--- dlls/ole32/tests/hglobalstream.c | 179 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 11 deletions(-)
diff --git a/dlls/ole32/hglobalstream.c b/dlls/ole32/hglobalstream.c index 5774c90..40a0dbf 100644 --- a/dlls/ole32/hglobalstream.c +++ b/dlls/ole32/hglobalstream.c @@ -476,21 +476,19 @@ static HRESULT WINAPI HGLOBALStreamImpl_ else copySize = cb.u.LowPart;
- IStream_Read(iface, tmpBuffer, copySize, &bytesRead); + hr = IStream_Read(iface, tmpBuffer, copySize, &bytesRead); + if (FAILED(hr)) + break;
totalBytesRead.u.LowPart += bytesRead;
- IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten); - - totalBytesWritten.u.LowPart += bytesWritten; - - /* - * Check that read & write operations were successful - */ - if (bytesRead != bytesWritten) + if (bytesRead) { - hr = STG_E_MEDIUMFULL; - break; + hr = IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten); + if (FAILED(hr)) + break; + + totalBytesWritten.u.LowPart += bytesWritten; }
if (bytesRead!=copySize) diff --git a/dlls/ole32/tests/hglobalstream.c b/dlls/ole32/tests/hglobalstream.c index c6eaa19..8f14544 100644 --- a/dlls/ole32/tests/hglobalstream.c +++ b/dlls/ole32/tests/hglobalstream.c @@ -30,6 +30,19 @@
#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
+static char const * const *expected_method_list; + +#define CHECK_EXPECTED_METHOD(method_name) \ +do { \ + ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \ + if (*expected_method_list) \ + { \ + ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \ + *expected_method_list, method_name); \ + expected_method_list++; \ + } \ +} while(0) + static void test_streamonhglobal(IStream *pStream) { const char data[] = "Test String"; @@ -82,6 +95,170 @@ static void test_streamonhglobal(IStream ok(hr == E_OUTOFMEMORY, "IStream_SetSize with large size should have returned E_OUTOFMEMORY instead of 0x%08x\n", hr); }
+static HRESULT WINAPI TestStream_QueryInterface(IStream *iface, REFIID riid, void **ppv) +{ + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_ISequentialStream) || + IsEqualIID(riid, &IID_IStream)) + { + *ppv = iface; + IUnknown_AddRef(iface); + return S_OK; + } + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI TestStream_AddRef(IStream *iface) +{ + return 2; +} + +static ULONG WINAPI TestStream_Release(IStream *iface) +{ + return 1; +} + +static HRESULT WINAPI TestStream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead) +{ + CHECK_EXPECTED_METHOD("TestStream_Read"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TestStream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten) +{ + CHECK_EXPECTED_METHOD("TestStream_Write"); + *pcbWritten = 5; + return S_OK; +} + +static HRESULT WINAPI TestStream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) +{ + CHECK_EXPECTED_METHOD("TestStream_Seek"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TestStream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize) +{ + CHECK_EXPECTED_METHOD("TestStream_SetSize"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TestStream_CopyTo(IStream *iface, IStream *pStream, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) +{ + CHECK_EXPECTED_METHOD("TestStream_CopyTo"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TestStream_Commit(IStream *iface, DWORD grfCommitFlags) +{ + CHECK_EXPECTED_METHOD("TestStream_Commit"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TestStream_Revert(IStream *iface) +{ + CHECK_EXPECTED_METHOD("TestStream_Revert"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TestStream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) +{ + CHECK_EXPECTED_METHOD("TestStream_LockRegion"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TestStream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) +{ + CHECK_EXPECTED_METHOD("TestStream_UnlockRegion"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TestStream_Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag) +{ + CHECK_EXPECTED_METHOD("TestStream_Stat"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TestStream_Clone(IStream *iface, IStream **pStream) +{ + CHECK_EXPECTED_METHOD("TestStream_Clone"); + return E_NOTIMPL; +} + +static /*const*/ IStreamVtbl StreamVtbl = +{ + TestStream_QueryInterface, + TestStream_AddRef, + TestStream_Release, + TestStream_Read, + TestStream_Write, + TestStream_Seek, + TestStream_SetSize, + TestStream_CopyTo, + TestStream_Commit, + TestStream_Revert, + TestStream_LockRegion, + TestStream_UnlockRegion, + TestStream_Stat, + TestStream_Clone +}; + +static IStream Test_Stream = { &StreamVtbl }; + +static void test_copyto(void) +{ + IStream *pStream, *pStream2; + HRESULT hr = CreateStreamOnHGlobal(NULL, FALSE, &pStream); + static const char szHello[] = "Hello"; + ULARGE_INTEGER cb; + static const char *methods_copyto[] = + { + "TestStream_Write", + NULL + }; + ULONG written; + ULARGE_INTEGER ullRead; + ULARGE_INTEGER ullWritten; + ULARGE_INTEGER libNewPosition; + static const LARGE_INTEGER llZero; + char buffer[15]; + + expected_method_list = methods_copyto; + + hr = IStream_Write(pStream, szHello, sizeof(szHello), &written); + ok_ole_success(hr, "IStream_Write"); + ok(written == sizeof(szHello), "only %d bytes written\n", written); + + hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL); + ok_ole_success(hr, "IStream_Seek"); + + cb.QuadPart = sizeof(szHello); + hr = IStream_CopyTo(pStream, &Test_Stream, cb, &ullRead, &ullWritten); + ok(ullWritten.QuadPart == 5, "ullWritten was %d instead\n", (ULONG)ullWritten.QuadPart); + ok(ullRead.QuadPart == sizeof(szHello), "only %d bytes read\n", (ULONG)ullRead.QuadPart); + ok_ole_success(hr, "IStream_CopyTo"); + + ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list); + + hr = IStream_Clone(pStream, &pStream2); + ok_ole_success(hr, "IStream_Clone"); + + hr = IStream_Seek(pStream2, llZero, STREAM_SEEK_CUR, &libNewPosition); + ok_ole_success(hr, "IStream_Seek"); + ok(libNewPosition.QuadPart == sizeof(szHello), "libNewPosition wasn't set correctly for the cloned stream\n"); + + hr = IStream_Seek(pStream2, llZero, STREAM_SEEK_SET, NULL); + ok_ole_success(hr, "IStream_Seek"); + + hr = IStream_Read(pStream2, buffer, sizeof(buffer), NULL); + ok_ole_success(hr, "IStream_Read"); + ok(!strcmp(buffer, szHello), "read data "%s" didn't match originally written data\n", buffer); + + IStream_Release(pStream2); + IStream_Release(pStream); +} + START_TEST(hglobalstream) { HRESULT hr; @@ -91,4 +268,6 @@ START_TEST(hglobalstream) ok_ole_success(hr, "CreateStreamOnHGlobal");
test_streamonhglobal(pStream); + IStream_Release(pStream); + test_copyto(); }