---
������dlls/kernel32/path.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++---
������1 file changed, 101 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index a389743171..98891cde6d 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -43,6 +43,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
������
������#define MAX_PATHNAME_LEN������ ������ ������ ������ 1024
������
+/* struct to hold progress function callback for MoveFileWithProgressW */
+typedef struct {
+������ ������ LPPROGRESS_ROUTINE progress;
+������ ������ VOID *data;
+������ ������ BOOL status;������ ������ ������ ������ ������ ������ ������ ������ ������ ������ /* flush successful */
+} MFWFData;
+
������static int path_safe_mode = -1;������ /* path mode set by SetSearchPathMode */
������
������/* check if a file name is for an executable file (.exe or .com) */
@@ -1159,10 +1166,14 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest,
������ ������ ������static const int buffer_size = 65536;
������ ������ ������HANDLE h1, h2;
������ ������ ������BY_HANDLE_FILE_INFORMATION info;
+������ ������ LARGE_INTEGER file_position,file_size;
������ ������ ������DWORD count;
������ ������ ������BOOL ret = FALSE;
������ ������ ������char *buffer;
+������ ������ DWORD progressExit = 0;
������
+������ ������ /* init file size/position */
+������ ������ file_position.QuadPart=file_size.QuadPart=0;
������ ������ ������if (!source || !dest)
������ ������ ������{
������ ������ ������ ������ ������SetLastError(ERROR_INVALID_PARAMETER);
@@ -1193,6 +1204,10 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest,
������ ������ ������ ������ ������return FALSE;
������ ������ ������}
������
+������ ������ /* update total size */
+������ ������ file_size.LowPart = info.nFileSizeLow;
+������ ������ file_size.HighPart = info.nFileSizeHigh;
+
������ ������ ������if (!(flags & COPY_FILE_FAIL_IF_EXISTS))
������ ������ ������{
������ ������ ������ ������ ������BOOL same_file = FALSE;
@@ -1231,6 +1246,32 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest,
������ ������ ������ ������ ������ ������ ������if (!WriteFile( h2, p, count, &res, NULL ) || !res) goto done;
������ ������ ������ ������ ������ ������ ������p += res;
������ ������ ������ ������ ������ ������ ������count -= res;
+������ ������ ������ ������ ������ ������ file_position.QuadPart += res;
+������ ������ ������ ������ }
+������ ������ ������ ������ /* Call progress function ? */
+������ ������ ������ ������ if (progress != NULL) {
+������ ������ ������ ������ ������ ������ progressExit = progress(file_size, file_position, file_size,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������file_position, 1, CALLBACK_CHUNK_FINISHED, h1, h2, param);
+������ ������ ������ ������ ������ ������ switch (progressExit) {
+������ ������ ������ ������ ������ ������ ������ ������ case PROGRESS_CONTINUE:
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ // keep at it
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ break;
+������ ������ ������ ������ ������ ������ ������ ������ case PROGRESS_QUIET:
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ // requested not to be called again
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ progress = NULL;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ break;
+������ ������ ������ ������ ������ ������ ������ ������ case PROGRESS_CANCEL:
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ // cancel and clean up
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ CloseHandle( h2 );
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ h2 = INVALID_HANDLE_VALUE;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ DeleteFileW( dest );
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ SetLastError( ERROR_REQUEST_ABORTED );
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ goto done;
+������ ������ ������ ������ ������ ������ ������ ������ case PROGRESS_STOP:
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ // do nothing, allow for a restart (??)
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ SetLastError( ERROR_REQUEST_ABORTED );
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ goto done;
+������ ������ ������ ������ ������ ������ }
������ ������ ������ ������ ������}
������ ������ ������}
������ ������ ������ret =������ TRUE;
@@ -1239,7 +1280,10 @@ done:
������ ������ ������SetFileTime(h2, NULL, NULL, &info.ftLastWriteTime);
������ ������ ������HeapFree( GetProcessHeap(), 0, buffer );
������ ������ ������CloseHandle( h1 );
-������ ������ CloseHandle( h2 );
+������ ������ if (h2 != INVALID_HANDLE_VALUE)
+������ ������ {
+������ ������ ������ ������ CloseHandle( h2 );
+������ ������ }
������ ������ ������return ret;
������}
������
@@ -1269,6 +1313,39 @@ BOOL WINAPI CopyFileExA(LPCSTR sourceFilename, LPCSTR destFilename,
������}
������
������
+/**************************************************************************
+ *������ ������ ������ ������ ������ ������moveFileWFlush
+ */
+DWORD CALLBACK moveFileWFlush(LARGE_INTEGER TotalFileSize,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ LARGE_INTEGER TotalBytesTransferred,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ LARGE_INTEGER StreamSize,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ LARGE_INTEGER StreamBytesTransferred,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ DWORD dwStreamNumber, DWORD dwCallbackReason,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ HANDLE hSourceFile,HANDLE hDestinationFile,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ LPVOID lpData )
+{
+������ ������ MFWFData *data = (MFWFData *)lpData;
+������ ������ DWORD rval = 0;
+
+������ ������ if ( data->progress != NULL)
+������ ������ {
+������ ������ ������ ������ rval = data->progress( TotalFileSize, TotalBytesTransferred,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������StreamSize, StreamBytesTransferred,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������dwStreamNumber, dwCallbackReason,
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������hSourceFile, hDestinationFile, data->data);
+������ ������ }
+������ ������ /* continue the copy? */
+������ ������ if (rval == 0 ) {
+������ ������ ������ ������ /* completed the copy? */
+������ ������ ������ ������ if (TotalFileSize.QuadPart == TotalBytesTransferred.QuadPart)
+������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ /* flush the data */
+������ ������ ������ ������ ������ ������ data->status = FlushFileBuffers(hDestinationFile)?1:0;
+������ ������ ������ ������ }
+������ ������ }
+������ ������ return rval;
+}
+
������/**************************************************************************
������ *������ ������ ������ ������ ������ ������MoveFileWithProgressW������ ������(KERNEL32.@)
������ */
@@ -1293,9 +1370,6 @@ BOOL WINAPI MoveFileWithProgressW( LPCWSTR source, LPCWSTR dest,
������ ������ ������if (!dest)
������ ������ ������ ������ ������return DeleteFileW( source );
������
-������ ������ if (flag & MOVEFILE_WRITE_THROUGH)
-������ ������ ������ ������ FIXME("MOVEFILE_WRITE_THROUGH unimplemented\n");
-
������ ������ ������/* check if we are allowed to rename the source */
������
������ ������ ������if (!RtlDosPathNameToNtPathName_U( source, &nt_name, NULL, NULL ))
@@ -1369,8 +1443,30 @@ BOOL WINAPI MoveFileWithProgressW( LPCWSTR source, LPCWSTR dest,
������ ������ ������}
������
������ ������ ������/* now perform the rename */
+������ ������ if ((flag & MOVEFILE_WRITE_THROUGH) && !(flag & MOVEFILE_DELAY_UNTIL_REBOOT))
+������ ������ {
+������ ������ ������ ������ /* save the original progress function && param, set status to 0 */
+������ ������ ������ ������ MFWFData data;
+������ ������ ������ ������ data.progress = fnProgress;
+������ ������ ������ ������ data.data = param;
+������ ������ ������ ������ data.status = 0;
+������ ������ ������ ������ /* try to copy the file, if it fails or the flush failed, set error */
+������ ������ ������ ������ if (CopyFileExW( source, dest, moveFileWFlush, &data, NULL, 0) == 0
+������ ������ ������ ������ ������|| !data.status) {
+������ ������ ������ ������ ������ ������ /* failed, set error */
+������ ������ ������ ������ ������ ������ FILE_SetDosError();
+������ ������ ������ ������ ������ ������ goto error;
+������ ������ ������ ������ }
������
-������ ������ if (rename( source_unix.Buffer, dest_unix.Buffer ) == -1)
+������ ������ ������ ������ /* delete the source file */
+������ ������ ������ ������ if (!DeleteFileW( source ))
+������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ /* failed, set error */
+������ ������ ������ ������ ������ ������ FILE_SetDosError();
+������ ������ ������ ������ ������ ������ goto error;
+������ ������ ������ ������ }
+������ ������ }
+������ ������ else if (rename( source_unix.Buffer, dest_unix.Buffer ) == -1)
������ ������ ������{
������ ������ ������ ������ ������if (errno == EXDEV && (flag & MOVEFILE_COPY_ALLOWED))
������ ������ ������ ������ ������{
--������
2.14.1