https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8a049d0b68ac18d4dfdaf4db3d3a2ef9bce2f607
commit 8a049d0b68ac18d4dfdaf4db3d3a2ef9bce2f607 Author: Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> AuthorDate: Tue Oct 31 22:32:02 2023 +0900 Commit: GitHub <nore...@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 */