On 4/21/22 12:53, Alistair Leslie-Hughes wrote:
+static DWORD call_progress_dialog(LPPROGRESS_ROUTINE progress, LARGE_INTEGER size, LARGE_INTEGER transferred,
DWORD cbtype, HANDLE h1, HANDLE h2, void *param)
+{
- DWORD cbret;
- cbret = progress( size, transferred, size, transferred, 1, cbtype, h1, h2, param );
- if (cbret == PROGRESS_STOP)
SetLastError( ERROR_REQUEST_ABORTED );
- else if (cbret == PROGRESS_CANCEL)
- {
BOOLEAN disp = TRUE;
SetFileInformationByHandle( h2, FileDispositionInfo, &disp, sizeof(disp) );
Might be better to use Nt* function here, and corresponding structure instead of a bare BOOLEAN.
SetLastError( ERROR_REQUEST_ABORTED );
- }
- return cbret;
+}
It seems returning NTSTATUS here and setting last error once would be easier to follow.
/***********************************************************************
- CopyFileExW (kernelbase.@)
@@ -499,11 +516,14 @@ BOOL WINAPI CopyFileExW( const WCHAR *source, const WCHAR *dest, LPPROGRESS_ROUT { static const int buffer_size = 65536; HANDLE h1, h2;
- FILE_BASIC_INFORMATION info;
FILE_NETWORK_OPEN_INFORMATION info;
FILE_BASIC_INFORMATION basic_info; IO_STATUS_BLOCK io; DWORD count; BOOL ret = FALSE; char *buffer;
LARGE_INTEGER transferred;
DWORD cbret;
if (!source || !dest) {
@@ -533,7 +553,7 @@ BOOL WINAPI CopyFileExW( const WCHAR *source, const WCHAR *dest, LPPROGRESS_ROUT return FALSE; }
- if (!set_ntstatus( NtQueryInformationFile( h1, &io, &info, sizeof(info), FileBasicInformation )))
- if (!set_ntstatus( NtQueryInformationFile( h1, &io, &info, sizeof(info), FileNetworkOpenInformation )))
Why is this necessary?
{ WARN("GetFileInformationByHandle returned error for %s\n", debugstr_w(source));
Outdated message text (not caused by this patch of course).
HeapFree( GetProcessHeap(), 0, buffer );
@@ -569,6 +589,17 @@ BOOL WINAPI CopyFileExW( const WCHAR *source, const WCHAR *dest, LPPROGRESS_ROUT return FALSE; }
- if (progress)
- {
transferred.QuadPart = 0;
cbret = call_progress_dialog(progress, info.EndOfFile, transferred, CALLBACK_STREAM_SWITCH, h1, h2, param);
if (cbret == PROGRESS_QUIET)
progress = NULL;
else if (cbret != PROGRESS_CONTINUE)
goto done;
- }
while (ReadFile( h1, buffer, buffer_size, &count, NULL ) && count) { char *p = buffer;
@@ -578,13 +609,28 @@ BOOL WINAPI CopyFileExW( const WCHAR *source, const WCHAR *dest, LPPROGRESS_ROUT if (!WriteFile( h2, p, count, &res, NULL ) || !res) goto done; p += res; count -= res;
if (progress)
{
transferred.QuadPart += res;
cbret = call_progress_dialog(progress, info.EndOfFile, transferred, CALLBACK_CHUNK_FINISHED, h1, h2, param);
if (cbret == PROGRESS_QUIET)
progress = NULL;
else if (cbret != PROGRESS_CONTINUE)
goto done;
} }
It should be possible to avoid duplication of continue/quite conditions, and progress != null check.
} ret = TRUE;
done: /* Maintain the timestamp of source file to destination file */
- info.FileAttributes = 0;
- NtSetInformationFile( h2, &io, &info, sizeof(info), FileBasicInformation );
- basic_info.CreationTime = info.CreationTime;
- basic_info.LastAccessTime = info.LastAccessTime;
- basic_info.LastWriteTime = info.LastWriteTime;
- basic_info.ChangeTime = info.ChangeTime;
- basic_info.FileAttributes = 0;
- NtSetInformationFile( h2, &io, &basic_info, sizeof(basic_info), FileBasicInformation ); HeapFree( GetProcessHeap(), 0, buffer ); CloseHandle( h1 ); CloseHandle( h2 );