update dev300-m58
[ooovba.git] / sal / systools / win32 / uwinapi / CopyFileExA.cpp
blobe4a44713c7f33cda99b7e6e55c1f86d64d847060
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: CopyFileExA.cpp,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
31 #pragma warning(disable:4740)
32 #endif
34 #define _WIN32_WINNT 0x0400
35 #include "macros.h"
37 #define BUFSIZE 16384
39 static DWORD CALLBACK DefCopyProgressRoutine(
40 LARGE_INTEGER TotalFileSize, // total file size, in bytes
41 LARGE_INTEGER TotalBytesTransferred,
42 // total number of bytes transferred
43 LARGE_INTEGER StreamSize, // total number of bytes for this stream
44 LARGE_INTEGER StreamBytesTransferred,
45 // total number of bytes transferred for
46 // this stream
47 DWORD dwStreamNumber, // the current stream
48 DWORD dwCallbackReason, // reason for callback
49 HANDLE hSourceFile, // handle to the source file
50 HANDLE hDestinationFile, // handle to the destination file
51 LPVOID lpData // passed by CopyFileEx
54 return PROGRESS_CONTINUE;
58 IMPLEMENT_THUNK( kernel32, WINDOWS, BOOL, WINAPI, CopyFileExA, ( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, LPPROGRESS_ROUTINE lpProgressRoutine, LPVOID lpData, LPBOOL pbCancel, DWORD dwCopyFlags ) )
60 BOOL fSuccess = FALSE; // Assume failure
62 HANDLE hSourceFile = CreateFileA(
63 lpExistingFileNameA,
64 GENERIC_READ,
65 FILE_SHARE_READ | FILE_SHARE_WRITE,
66 NULL,
67 OPEN_EXISTING,
69 NULL
72 if ( IsValidHandle(hSourceFile) )
74 LARGE_INTEGER FileSize, BytesTransferred;
75 HANDLE hTargetFile = NULL;
77 SetLastError( ERROR_SUCCESS );
78 FileSize.LowPart = GetFileSize( hSourceFile, (LPDWORD)&FileSize.HighPart );
79 BytesTransferred.QuadPart = 0;
81 if ( (DWORD)-1 != FileSize.LowPart || ERROR_SUCCESS == GetLastError() )
82 hTargetFile = CreateFileA(
83 lpNewFileNameA,
84 GENERIC_WRITE,
86 NULL,
87 (DWORD) ((dwCopyFlags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS),
89 NULL
92 if ( IsValidHandle(hTargetFile) )
94 DWORD dwProgressResult = PROGRESS_CONTINUE;
96 fSuccess = SetEndOfFile( hTargetFile );
98 if ( fSuccess )
100 if ( !lpProgressRoutine )
101 lpProgressRoutine = DefCopyProgressRoutine;
103 dwProgressResult = lpProgressRoutine(
104 FileSize,
105 BytesTransferred,
106 FileSize,
107 BytesTransferred,
109 CALLBACK_STREAM_SWITCH,
110 hSourceFile,
111 hTargetFile,
112 lpData
115 // Suppress further notifications
117 if ( PROGRESS_QUIET == dwProgressResult )
119 lpProgressRoutine = DefCopyProgressRoutine;
120 dwProgressResult = PROGRESS_CONTINUE;
124 while ( fSuccess && PROGRESS_CONTINUE == dwProgressResult )
126 BYTE buffer[BUFSIZE];
127 DWORD dwBytesRead, dwBytesWritten = 0;
129 fSuccess = ReadFile( hSourceFile, buffer, BUFSIZE, &dwBytesRead, NULL );
131 if ( !dwBytesRead ) break;
133 if ( fSuccess )
134 fSuccess = WriteFile( hTargetFile, buffer, dwBytesRead, &dwBytesWritten, NULL );
136 if ( fSuccess )
138 BytesTransferred.QuadPart += (LONGLONG)dwBytesWritten;
140 if ( pbCancel && *pbCancel )
141 dwProgressResult = PROGRESS_CANCEL;
142 else
143 dwProgressResult = lpProgressRoutine(
144 FileSize,
145 BytesTransferred,
146 FileSize,
147 BytesTransferred,
149 CALLBACK_CHUNK_FINISHED,
150 hSourceFile,
151 hTargetFile,
152 lpData
159 CloseHandle( hTargetFile );
161 if ( PROGRESS_CANCEL == dwProgressResult )
162 DeleteFileA( lpNewFileNameA );
166 CloseHandle( hSourceFile );
169 return fSuccess;