Rob Shearman : 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 .

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jan 10 05:35:58 CST 2007


Module: wine
Branch: master
Commit: fd07191673dea171af0449654d3106c5d6429025
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fd07191673dea171af0449654d3106c5d6429025

Author: Rob Shearman <rob at 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();
 }




More information about the wine-cvs mailing list