From: Duy Pham Duc phamducduy6122011@gmail.com
--- dlls/kernelbase/file.c | 78 ++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 38 deletions(-)
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index b69edcf8288..13224852784 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -500,6 +500,33 @@ BOOL WINAPI DECLSPEC_HOTPATCH AreFileApisANSI(void) return !oem_file_apis; }
+/****************************************************************************** + * cpfile2_cb_abrt_chk + * + * Check for aborting, e.g routine return COPYFILE2_PROGRESS_PAUSED/CANCEL + */ +static BOOL cpfile2_cb_abrt_chk( PCOPYFILE2_PROGRESS_ROUTINE *routine, void *params, BOOL *delete_dest, const COPYFILE2_MESSAGE* msg ) +{ + switch((*routine)(msg, params)) + { + case COPYFILE2_PROGRESS_QUIET: + *routine = NULL; + break; + + case COPYFILE2_PROGRESS_CANCEL: + case COPYFILE2_PROGRESS_STOP: + *delete_dest = TRUE; + return HRESULT_FROM_WIN32(ERROR_REQUEST_ABORTED); + + case COPYFILE2_PROGRESS_PAUSE: + return HRESULT_FROM_WIN32(ERROR_REQUEST_PAUSED); + + case COPYFILE2_PROGRESS_CONTINUE: + return TRUE; + } + return TRUE; +} + /****************************************************************************** * copy_file */ @@ -564,6 +591,13 @@ static BOOL copy_file( const WCHAR *source, const WCHAR *dest, COPYFILE2_EXTENDE WARN("GetFileInformationByHandle returned error for %s\n", debugstr_w(source)); HeapFree( GetProcessHeap(), 0, buffer ); CloseHandle( h1 ); + if(progress) { + COPYFILE2_MESSAGE msg = {0}; + msg.Type = COPYFILE2_CALLBACK_ERROR; + msg.Info.Error.CopyPhase = COPYFILE2_PHASE_PREPARE_SOURCE; + msg.Info.Error.hrFailure = HRESULT_FROM_WIN32(GetLastError()); + progress(&msg, params->pvCallbackContext); + } return FALSE; }
@@ -618,7 +652,8 @@ static BOOL copy_file( const WCHAR *source, const WCHAR *dest, COPYFILE2_EXTENDE msg.Info.StreamStarted.hDestinationFile = h2; msg.Info.StreamStarted.uliStreamSize = msg.Info.StreamStarted.uliTotalFileSize = file_size; - progress(&msg, params->pvCallbackContext); + if((ret = cpfile2_cb_abrt_chk(&progress, params->pvCallbackContext, &delete_dest, &msg)) != TRUE) + goto done; }
while (ReadFile( h1, buffer, buffer_size, &count, NULL ) && count) @@ -637,22 +672,8 @@ static BOOL copy_file( const WCHAR *source, const WCHAR *dest, COPYFILE2_EXTENDE msg.Info.ChunkStarted.uliStreamSize = msg.Info.ChunkStarted.uliTotalFileSize = file_size; - switch(progress(&msg, params->pvCallbackContext)) - { - case COPYFILE2_PROGRESS_STOP: - /* Fall-through */ - case COPYFILE2_PROGRESS_CANCEL: - ret = HRESULT_FROM_WIN32(ERROR_REQUEST_ABORTED); + if((ret = cpfile2_cb_abrt_chk(&progress, params->pvCallbackContext, &delete_dest, &msg)) != TRUE) goto done; - case COPYFILE2_PROGRESS_PAUSE: - ret = HRESULT_FROM_WIN32(ERROR_REQUEST_PAUSED); - goto done; - case COPYFILE2_PROGRESS_QUIET: - progress = 0; - break; - default: - break; - } } while (count != 0) { @@ -678,24 +699,8 @@ static BOOL copy_file( const WCHAR *source, const WCHAR *dest, COPYFILE2_EXTENDE msg.Info.ChunkFinished.uliTotalBytesTransferred.QuadPart = bytes_transfered; chunk_id++; - switch(progress(&msg, params->pvCallbackContext)) - { - case COPYFILE2_PROGRESS_STOP: - if(params->dwCopyFlags & COPY_FILE_RESTARTABLE) - FIXME("COPY_FILE_RESTARTABLE flag is unsupported"); - /* Fall-through */ - case COPYFILE2_PROGRESS_CANCEL: - ret = HRESULT_FROM_WIN32(ERROR_REQUEST_ABORTED); - goto done; - case COPYFILE2_PROGRESS_PAUSE: - ret = HRESULT_FROM_WIN32(ERROR_REQUEST_PAUSED); + if((ret = cpfile2_cb_abrt_chk(&progress, params->pvCallbackContext, &delete_dest, &msg)) != TRUE) goto done; - case COPYFILE2_PROGRESS_QUIET: - progress = 0; - goto done; - default: - break; - } } } ret = TRUE; @@ -717,11 +722,8 @@ done: msg.Info.StreamFinished.uliStreamBytesTransferred.QuadPart = msg.Info.StreamFinished.uliTotalBytesTransferred.QuadPart = (ULONGLONG)liPos.QuadPart; - if(progress(&msg, params->pvCallbackContext) == COPYFILE2_PROGRESS_CANCEL) - { - delete_dest = TRUE; - ret = HRESULT_FROM_WIN32(ERROR_REQUEST_ABORTED); - } + if((ret = cpfile2_cb_abrt_chk(&progress, params->pvCallbackContext, &delete_dest, &msg)) != TRUE) + goto done; }
/* Maintain the timestamp of source file to destination file and read-only attribute */