1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: CopyFileExA.cpp,v $
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)
34 #define _WIN32_WINNT 0x0400
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
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(
65 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
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(
87 (DWORD
) ((dwCopyFlags
& COPY_FILE_FAIL_IF_EXISTS
) ? CREATE_NEW
: CREATE_ALWAYS
),
92 if ( IsValidHandle(hTargetFile
) )
94 DWORD dwProgressResult
= PROGRESS_CONTINUE
;
96 fSuccess
= SetEndOfFile( hTargetFile
);
100 if ( !lpProgressRoutine
)
101 lpProgressRoutine
= DefCopyProgressRoutine
;
103 dwProgressResult
= lpProgressRoutine(
109 CALLBACK_STREAM_SWITCH
,
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;
134 fSuccess
= WriteFile( hTargetFile
, buffer
, dwBytesRead
, &dwBytesWritten
, NULL
);
138 BytesTransferred
.QuadPart
+= (LONGLONG
)dwBytesWritten
;
140 if ( pbCancel
&& *pbCancel
)
141 dwProgressResult
= PROGRESS_CANCEL
;
143 dwProgressResult
= lpProgressRoutine(
149 CALLBACK_CHUNK_FINISHED
,
159 CloseHandle( hTargetFile
);
161 if ( PROGRESS_CANCEL
== dwProgressResult
)
162 DeleteFileA( lpNewFileNameA
);
166 CloseHandle( hSourceFile
);