Module: wine Branch: master Commit: 899e59ffe3b2160df4719780949f8de0cc4ba8eb URL: http://source.winehq.org/git/wine.git/?a=commit;h=899e59ffe3b2160df471978094...
Author: David Quintana gigaherz@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(); }