1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 #if defined(_MSC_VER) && (_MSC_VER >= 1400) 28 #pragma warning(disable:4740) 29 #endif 30 31 #define _WIN32_WINNT 0x0400 32 #include "macros.h" 33 34 #define BUFSIZE 16384 35 36 static DWORD CALLBACK DefCopyProgressRoutine( 37 LARGE_INTEGER TotalFileSize, // total file size, in bytes 38 LARGE_INTEGER TotalBytesTransferred, 39 // total number of bytes transferred 40 LARGE_INTEGER StreamSize, // total number of bytes for this stream 41 LARGE_INTEGER StreamBytesTransferred, 42 // total number of bytes transferred for 43 // this stream 44 DWORD dwStreamNumber, // the current stream 45 DWORD dwCallbackReason, // reason for callback 46 HANDLE hSourceFile, // handle to the source file 47 HANDLE hDestinationFile, // handle to the destination file 48 LPVOID lpData // passed by CopyFileEx 49 ) 50 { 51 return PROGRESS_CONTINUE; 52 } 53 54 55 IMPLEMENT_THUNK( kernel32, WINDOWS, BOOL, WINAPI, CopyFileExA, ( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, LPPROGRESS_ROUTINE lpProgressRoutine, LPVOID lpData, LPBOOL pbCancel, DWORD dwCopyFlags ) ) 56 { 57 BOOL fSuccess = FALSE; // Assume failure 58 59 HANDLE hSourceFile = CreateFileA( 60 lpExistingFileNameA, 61 GENERIC_READ, 62 FILE_SHARE_READ | FILE_SHARE_WRITE, 63 NULL, 64 OPEN_EXISTING, 65 0, 66 NULL 67 ); 68 69 if ( IsValidHandle(hSourceFile) ) 70 { 71 LARGE_INTEGER FileSize, BytesTransferred; 72 HANDLE hTargetFile = NULL; 73 74 SetLastError( ERROR_SUCCESS ); 75 FileSize.LowPart = GetFileSize( hSourceFile, (LPDWORD)&FileSize.HighPart ); 76 BytesTransferred.QuadPart = 0; 77 78 if ( (DWORD)-1 != FileSize.LowPart || ERROR_SUCCESS == GetLastError() ) 79 hTargetFile = CreateFileA( 80 lpNewFileNameA, 81 GENERIC_WRITE, 82 0, 83 NULL, 84 (DWORD) ((dwCopyFlags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS), 85 0, 86 NULL 87 ); 88 89 if ( IsValidHandle(hTargetFile) ) 90 { 91 DWORD dwProgressResult = PROGRESS_CONTINUE; 92 93 fSuccess = SetEndOfFile( hTargetFile ); 94 95 if ( fSuccess ) 96 { 97 if ( !lpProgressRoutine ) 98 lpProgressRoutine = DefCopyProgressRoutine; 99 100 dwProgressResult = lpProgressRoutine( 101 FileSize, 102 BytesTransferred, 103 FileSize, 104 BytesTransferred, 105 1, 106 CALLBACK_STREAM_SWITCH, 107 hSourceFile, 108 hTargetFile, 109 lpData 110 ); 111 112 // Suppress further notifications 113 114 if ( PROGRESS_QUIET == dwProgressResult ) 115 { 116 lpProgressRoutine = DefCopyProgressRoutine; 117 dwProgressResult = PROGRESS_CONTINUE; 118 } 119 } 120 121 while ( fSuccess && PROGRESS_CONTINUE == dwProgressResult ) 122 { 123 BYTE buffer[BUFSIZE]; 124 DWORD dwBytesRead, dwBytesWritten = 0; 125 126 fSuccess = ReadFile( hSourceFile, buffer, BUFSIZE, &dwBytesRead, NULL ); 127 128 if ( !dwBytesRead ) break; 129 130 if ( fSuccess ) 131 fSuccess = WriteFile( hTargetFile, buffer, dwBytesRead, &dwBytesWritten, NULL ); 132 133 if ( fSuccess ) 134 { 135 BytesTransferred.QuadPart += (LONGLONG)dwBytesWritten; 136 137 if ( pbCancel && *pbCancel ) 138 dwProgressResult = PROGRESS_CANCEL; 139 else 140 dwProgressResult = lpProgressRoutine( 141 FileSize, 142 BytesTransferred, 143 FileSize, 144 BytesTransferred, 145 1, 146 CALLBACK_CHUNK_FINISHED, 147 hSourceFile, 148 hTargetFile, 149 lpData 150 ); 151 152 } 153 154 } 155 156 CloseHandle( hTargetFile ); 157 158 if ( PROGRESS_CANCEL == dwProgressResult ) 159 DeleteFileA( lpNewFileNameA ); 160 } 161 162 163 CloseHandle( hSourceFile ); 164 } 165 166 return fSuccess; 167 }