https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8a049d0b68ac18d4dfdaf…
commit 8a049d0b68ac18d4dfdaf4db3d3a2ef9bce2f607
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Oct 31 22:32:02 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Tue Oct 31 22:32:02 2023 +0900
[SHELL32][SDK] Implement CopyStreamUI (#5848)
- Modify shell32.spec.
- Add CopyStreamUI prototype to <undocshell.h>.
CORE-19278
---
dll/win32/shell32/shell32.spec | 2 +-
dll/win32/shell32/stubs.cpp | 11 ----
dll/win32/shell32/utils.cpp | 117 +++++++++++++++++++++++++++++++++++++++
sdk/include/reactos/undocshell.h | 8 +++
4 files changed, 126 insertions(+), 12 deletions(-)
diff --git a/dll/win32/shell32/shell32.spec b/dll/win32/shell32/shell32.spec
index dbdbfabd758..eb8685fe3c6 100644
--- a/dll/win32/shell32/shell32.spec
+++ b/dll/win32/shell32/shell32.spec
@@ -444,7 +444,7 @@
723 stdcall -noname SHCreateSessionKey(long ptr)
724 stdcall -noname SHIsTempDisplayMode()
725 stdcall -noname GetFileDescriptor(ptr long long wstr)
-726 stdcall -noname CopyStreamUI(ptr ptr ptr)
+726 stdcall -noname CopyStreamUI(ptr ptr ptr int64)
727 stdcall SHGetImageList(long ptr ptr)
730 stdcall RestartDialogEx(long wstr long long)
731 stdcall -noname -stub SHRegisterDarwinLink(long long long)
diff --git a/dll/win32/shell32/stubs.cpp b/dll/win32/shell32/stubs.cpp
index b1e153fdb67..91e8ae00beb 100644
--- a/dll/win32/shell32/stubs.cpp
+++ b/dll/win32/shell32/stubs.cpp
@@ -86,17 +86,6 @@ SHReValidateDarwinCache(VOID)
FIXME("SHReValidateDarwinCache() stub\n");
}
-/*
- * Unimplemented
- */
-EXTERN_C HRESULT
-WINAPI
-CopyStreamUI(IStream *pSrc, IStream *pDst, IProgressDialog *pProgDlg)
-{
- FIXME("CopyStreamUI() stub\n");
- return E_FAIL;
-}
-
/*
* Unimplemented
*/
diff --git a/dll/win32/shell32/utils.cpp b/dll/win32/shell32/utils.cpp
index 697a4f59cea..1e7cfbe28ac 100644
--- a/dll/win32/shell32/utils.cpp
+++ b/dll/win32/shell32/utils.cpp
@@ -540,6 +540,123 @@ LargeIntegerToString(
pNumberFormat, dwNumberFlags);
}
+/*************************************************************************
+ * CopyStreamUI [SHELL32.726]
+ *
+ * Copy a stream to another stream with optional progress display.
+ */
+EXTERN_C
+HRESULT WINAPI
+CopyStreamUI(
+ _In_ IStream *pSrc,
+ _Out_ IStream *pDst,
+ _Inout_opt_ IProgressDialog *pProgress,
+ _In_opt_ DWORDLONG dwlSize)
+{
+ HRESULT hr = E_FAIL;
+ DWORD cbBuff, cbRead, dwSizeToWrite;
+ DWORDLONG cbDone;
+ LPVOID pBuff;
+ CComHeapPtr<BYTE> pHeapPtr;
+ STATSTG Stat;
+ BYTE abBuff[1024];
+
+ TRACE("(%p, %p, %p, %I64u)\n", pSrc, pDst, pProgress, dwlSize);
+
+ if (dwlSize == 0) // Invalid size?
+ {
+ // Get the stream size
+ ZeroMemory(&Stat, sizeof(Stat));
+ if (FAILED(pSrc->Stat(&Stat, STATFLAG_NONAME)))
+ pProgress = NULL; // No size info. Disable progress
+ else
+ dwlSize = Stat.cbSize.QuadPart;
+ }
+
+ if (!pProgress) // Progress is disabled?
+ {
+ ULARGE_INTEGER uliSize;
+
+ if (dwlSize > 0)
+ uliSize.QuadPart = dwlSize;
+ else
+ uliSize.HighPart = uliSize.LowPart = INVALID_FILE_SIZE;
+
+ return pSrc->CopyTo(pDst, uliSize, NULL, NULL); // One punch
+ }
+
+ // Allocate the buffer if necessary
+ if (dwlSize > 0 && dwlSize <= sizeof(abBuff))
+ {
+ cbBuff = sizeof(abBuff);
+ pBuff = abBuff;
+ }
+ else
+ {
+#define COPY_STREAM_DEFAULT_BUFFER_SIZE 0x4000
+ cbBuff = COPY_STREAM_DEFAULT_BUFFER_SIZE;
+ if (pHeapPtr.AllocateBytes(cbBuff))
+ {
+ pBuff = pHeapPtr;
+ }
+ else // Low memory?
+ {
+ cbBuff = sizeof(abBuff);
+ pBuff = abBuff;
+ }
+#undef COPY_STREAM_DEFAULT_BUFFER_SIZE
+ }
+
+ // Start reading
+ LARGE_INTEGER zero;
+ zero.QuadPart = 0;
+ pSrc->Seek(zero, 0, NULL);
+ pDst->Seek(zero, 0, NULL);
+ cbDone = 0;
+ pProgress->SetProgress64(cbDone, dwlSize);
+
+ // Repeat reading and writing until goal
+ for (;;)
+ {
+ hr = pSrc->Read(pBuff, cbBuff, &cbRead);
+ if (FAILED(hr))
+ break;
+
+ // Calculate the size to write
+ if (dwlSize > 0)
+ dwSizeToWrite = (DWORD)min((DWORDLONG)(dwlSize - cbDone),
(DWORDLONG)cbRead);
+ else
+ dwSizeToWrite = cbRead;
+
+ if (dwSizeToWrite == 0) // No need to write?
+ {
+ hr = S_OK;
+ break;
+ }
+
+ hr = pDst->Write(pBuff, dwSizeToWrite, NULL);
+ if (hr != S_OK)
+ break;
+
+ cbDone += dwSizeToWrite;
+
+ if (pProgress->HasUserCancelled()) // Cancelled?
+ {
+ hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
+ break;
+ }
+ pProgress->SetProgress64(cbDone, dwlSize);
+
+ if (dwlSize > 0 && cbDone >= dwlSize) // Reached the goal?
+ {
+ hr = S_OK;
+ break;
+ }
+ }
+
+ return hr;
+}
+
/*************************************************************************
* SHOpenPropSheetA [SHELL32.707]
*
diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h
index 95cc7b6998b..8fad6faa6a8 100644
--- a/sdk/include/reactos/undocshell.h
+++ b/sdk/include/reactos/undocshell.h
@@ -817,6 +817,14 @@ LONG WINAPI SHRegQueryValueExW(
#define SHRegQueryValueEx SHRegQueryValueExA
#endif
+EXTERN_C
+HRESULT WINAPI
+CopyStreamUI(
+ _In_ IStream *pSrc,
+ _Out_ IStream *pDst,
+ _Inout_opt_ IProgressDialog *pProgress,
+ _In_opt_ DWORDLONG dwlSize);
+
/*****************************************************************************
* INVALID_FILETITLE_CHARACTERS
*/