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