David Quintana : shlwapi: Test and fix the behaviour of the CopyTo method for file sizes not multiple of the internal buffer size , on SHCreateStreamOnFileEx-returned IStreams.

Alexandre Julliard julliard at winehq.org
Thu Nov 7 14:10:03 CST 2013


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

Author: David Quintana <gigaherz at gmail.com>
Date:   Tue Oct 29 15:00:53 2013 +0100

shlwapi: Test and fix the behaviour of the CopyTo method for file sizes not multiple of the internal buffer size, on SHCreateStreamOnFileEx-returned IStreams.

---

 dlls/shlwapi/istream.c       |   16 +++++++-------
 dlls/shlwapi/tests/istream.c |   48 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/dlls/shlwapi/istream.c b/dlls/shlwapi/istream.c
index 42f47fe..044594b 100644
--- a/dlls/shlwapi/istream.c
+++ b/dlls/shlwapi/istream.c
@@ -231,22 +231,22 @@ static HRESULT WINAPI IStream_fnCopyTo(IStream *iface, IStream* pstm, ULARGE_INT
   ulSize = cb.QuadPart;
   while (ulSize)
   {
-    ULONG ulLeft, ulAmt;
+    ULONG ulLeft, ulRead, ulWritten;
 
     ulLeft = ulSize > sizeof(copyBuff) ? sizeof(copyBuff) : ulSize;
 
     /* Read */
-    hRet = IStream_fnRead(iface, copyBuff, ulLeft, &ulAmt);
-    if (pcbRead)
-      pcbRead->QuadPart += ulAmt;
-    if (FAILED(hRet) || ulAmt != ulLeft)
+    hRet = IStream_fnRead(iface, copyBuff, ulLeft, &ulRead);
+    if (FAILED(hRet) || ulRead == 0)
       break;
+    if (pcbRead)
+      pcbRead->QuadPart += ulRead;
 
     /* Write */
-    hRet = IStream_fnWrite(pstm, copyBuff, ulLeft, &ulAmt);
+    hRet = IStream_fnWrite(pstm, copyBuff, ulRead, &ulWritten);
     if (pcbWritten)
-      pcbWritten->QuadPart += ulAmt;
-    if (FAILED(hRet) || ulAmt != ulLeft)
+      pcbWritten->QuadPart += ulWritten;
+    if (FAILED(hRet) || ulWritten != ulLeft)
       break;
 
     ulSize -= ulLeft;
diff --git a/dlls/shlwapi/tests/istream.c b/dlls/shlwapi/tests/istream.c
index 097e70a..760b847 100644
--- a/dlls/shlwapi/tests/istream.c
+++ b/dlls/shlwapi/tests/istream.c
@@ -655,6 +655,52 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm)
 }
 
 
+void test_SHCreateStreamOnFileEx_CopyTo(void)
+{
+    HRESULT ret;
+    IStream *src, *dst;
+    WCHAR tmpPath[MAX_PATH];
+    WCHAR srcFileName[MAX_PATH];
+    WCHAR dstFileName[MAX_PATH];
+    ULARGE_INTEGER count, read, written;
+    LARGE_INTEGER distance;
+    static const char srcContents[1];
+    static const WCHAR prefix[] = { 'T', 'S', 'T', 0 };
+
+    GetTempPathW(MAX_PATH, tmpPath);
+    GetTempFileNameW(tmpPath, prefix, 0, srcFileName);
+    GetTempFileNameW(tmpPath, prefix, 0, dstFileName);
+
+    ret = pSHCreateStreamOnFileEx(srcFileName, STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE, FILE_ATTRIBUTE_TEMPORARY, FALSE, NULL, &src);
+    ok(SUCCEEDED(ret), "SHCreateStreamOnFileEx failed with ret=0x%08x\n", ret);
+
+    written.QuadPart = 0;
+    ret = IStream_Write(src, srcContents, sizeof(srcContents), &written.LowPart);
+    ok(SUCCEEDED(ret), "ISequentialStream_Write failed with ret=0x%08x\n", ret);
+
+    distance.QuadPart = 0;
+    ret = IStream_Seek(src, distance, STREAM_SEEK_SET, &written);
+    ok(SUCCEEDED(ret), "ISequentialStream_Seek failed with ret=0x%08x\n", ret);
+
+    ret = pSHCreateStreamOnFileEx(dstFileName, STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE, FILE_ATTRIBUTE_TEMPORARY, FALSE, NULL, &dst);
+    ok(SUCCEEDED(ret), "SHCreateStreamOnFileEx failed with ret=0x%08x\n", ret);
+
+    /* Test using a count larger than the source file, so that the Read operation will fall short */
+    count.QuadPart = 2;
+
+    ret = IStream_CopyTo(src, dst, count, &read, &written);
+    ok(SUCCEEDED(ret), "CopyTo failed with ret=0x%08x\n", ret);
+
+    ok(read.QuadPart == 1, "read does not match size: %d != 1\n", read.LowPart);
+    ok(written.QuadPart == 1, "written does not match size: %d != 1\n", written.LowPart);
+
+    IStream_Release(dst);
+    IStream_Release(src);
+    DeleteFileW( srcFileName );
+    DeleteFileW( dstFileName );
+}
+
+
 START_TEST(istream)
 {
     static const DWORD stgm_access[] = {
@@ -712,4 +758,6 @@ START_TEST(istream)
             }
         }
     }
+
+    test_SHCreateStreamOnFileEx_CopyTo();
 }




More information about the wine-cvs mailing list