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