xref: /trunk/main/sal/systools/win32/uwinapi/CopyFileExA.cpp (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 }