3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/copy.c
6 * PURPOSE: Copying files
7 * PROGRAMMER: Ariadne (ariadne@xs4all.nl)
10 * 07/02/99 Moved to seperate file
13 /* INCLUDES ****************************************************************/
18 #include "../include/debug.h"
21 /* FUNCTIONS ****************************************************************/
26 HANDLE FileHandleSource
,
27 HANDLE FileHandleDest
,
28 LARGE_INTEGER SourceFileSize
,
29 LPPROGRESS_ROUTINE lpProgressRoutine
,
36 IO_STATUS_BLOCK IoStatusBlock
;
37 UCHAR
*lpBuffer
= NULL
;
38 ULONG RegionSize
= 0x10000;
39 LARGE_INTEGER BytesCopied
;
45 errCode
= NtAllocateVirtualMemory(NtCurrentProcess(),
49 MEM_RESERVE
| MEM_COMMIT
,
52 if (NT_SUCCESS(errCode
))
54 BytesCopied
.QuadPart
= 0;
55 EndOfFileFound
= FALSE
;
56 CallbackReason
= CALLBACK_STREAM_SWITCH
;
57 while (! EndOfFileFound
&&
58 NT_SUCCESS(errCode
) &&
59 (NULL
== pbCancel
|| ! *pbCancel
))
61 if (NULL
!= lpProgressRoutine
)
63 ProgressResult
= (*lpProgressRoutine
)(SourceFileSize
,
72 switch (ProgressResult
)
75 DPRINT("Progress callback requested cancel\n");
76 errCode
= STATUS_REQUEST_ABORTED
;
79 DPRINT("Progress callback requested stop\n");
80 errCode
= STATUS_REQUEST_ABORTED
;
84 lpProgressRoutine
= NULL
;
86 case PROGRESS_CONTINUE
:
90 CallbackReason
= CALLBACK_CHUNK_FINISHED
;
92 if (NT_SUCCESS(errCode
))
94 errCode
= NtReadFile(FileHandleSource
,
98 (PIO_STATUS_BLOCK
)&IoStatusBlock
,
103 if (NT_SUCCESS(errCode
) && (NULL
== pbCancel
|| ! *pbCancel
))
105 errCode
= NtWriteFile(FileHandleDest
,
109 (PIO_STATUS_BLOCK
)&IoStatusBlock
,
111 IoStatusBlock
.Information
,
114 if (NT_SUCCESS(errCode
))
116 BytesCopied
.QuadPart
+= IoStatusBlock
.Information
;
120 DPRINT("Error 0x%08x reading writing to dest\n", errCode
);
123 else if (!NT_SUCCESS(errCode
))
125 if (STATUS_END_OF_FILE
== errCode
)
127 EndOfFileFound
= TRUE
;
128 errCode
= STATUS_SUCCESS
;
132 DPRINT("Error 0x%08x reading from source\n", errCode
);
138 if (! EndOfFileFound
&& (NULL
!= pbCancel
&& *pbCancel
))
140 DPRINT("User requested cancel\n");
141 errCode
= STATUS_REQUEST_ABORTED
;
144 NtFreeVirtualMemory(NtCurrentProcess(),
151 DPRINT("Error 0x%08x allocating buffer of %d bytes\n", errCode
, RegionSize
);
163 NTSTATUS errCode
= STATUS_SUCCESS
;
164 IO_STATUS_BLOCK IoStatusBlock
;
165 FILE_BASIC_INFORMATION FileBasic
;
167 errCode
= NtQueryInformationFile (FileHandle
,
170 sizeof(FILE_BASIC_INFORMATION
),
171 FileBasicInformation
);
172 if (!NT_SUCCESS(errCode
))
174 DPRINT("Error 0x%08x obtaining FileBasicInformation\n", errCode
);
178 FileBasic
.LastWriteTime
.QuadPart
= LastWriteTime
.QuadPart
;
179 errCode
= NtSetInformationFile (FileHandle
,
182 sizeof(FILE_BASIC_INFORMATION
),
183 FileBasicInformation
);
184 if (!NT_SUCCESS(errCode
))
186 DPRINT("Error 0x%0x setting LastWriteTime\n", errCode
);
200 LPCWSTR lpExistingFileName
,
201 LPCWSTR lpNewFileName
,
202 LPPROGRESS_ROUTINE lpProgressRoutine
,
209 HANDLE FileHandleSource
, FileHandleDest
;
210 IO_STATUS_BLOCK IoStatusBlock
;
211 FILE_STANDARD_INFORMATION FileStandard
;
212 FILE_BASIC_INFORMATION FileBasic
;
214 BOOL KeepDestOnError
= FALSE
;
217 FileHandleSource
= CreateFileW(lpExistingFileName
,
222 FILE_ATTRIBUTE_NORMAL
|FILE_FLAG_NO_BUFFERING
,
224 if (INVALID_HANDLE_VALUE
!= FileHandleSource
)
226 errCode
= NtQueryInformationFile(FileHandleSource
,
229 sizeof(FILE_STANDARD_INFORMATION
),
230 FileStandardInformation
);
231 if (!NT_SUCCESS(errCode
))
233 DPRINT("Status 0x%08x obtaining FileStandardInformation for source\n", errCode
);
234 SetLastErrorByStatus(errCode
);
238 errCode
= NtQueryInformationFile(FileHandleSource
,
239 &IoStatusBlock
,&FileBasic
,
240 sizeof(FILE_BASIC_INFORMATION
),
241 FileBasicInformation
);
242 if (!NT_SUCCESS(errCode
))
244 DPRINT("Status 0x%08x obtaining FileBasicInformation for source\n", errCode
);
245 SetLastErrorByStatus(errCode
);
249 FileHandleDest
= CreateFileW(lpNewFileName
,
253 dwCopyFlags
? CREATE_NEW
: CREATE_ALWAYS
,
254 FileBasic
.FileAttributes
,
256 if (INVALID_HANDLE_VALUE
!= FileHandleDest
)
258 errCode
= CopyLoop(FileHandleSource
,
260 FileStandard
.EndOfFile
,
265 if (!NT_SUCCESS(errCode
))
267 SetLastErrorByStatus(errCode
);
273 t
.QuadPart
= FileBasic
.LastWriteTime
.QuadPart
;
274 errCode
= SetLastWriteTime(FileHandleDest
, t
);
275 if (!NT_SUCCESS(errCode
))
277 SetLastErrorByStatus(errCode
);
284 NtClose(FileHandleDest
);
285 if (! RC
&& ! KeepDestOnError
)
287 SystemError
= GetLastError();
288 SetFileAttributesW(lpNewFileName
, FILE_ATTRIBUTE_NORMAL
);
289 DeleteFileW(lpNewFileName
);
290 SetLastError(SystemError
);
295 DPRINT("Error %d during opening of dest file\n", GetLastError());
299 NtClose(FileHandleSource
);
303 DPRINT("Error %d during opening of source file\n", GetLastError());
316 LPCSTR lpExistingFileName
,
317 LPCSTR lpNewFileName
,
318 LPPROGRESS_ROUTINE lpProgressRoutine
,
324 UNICODE_STRING ExistingFileNameU
;
325 UNICODE_STRING NewFileNameU
;
326 ANSI_STRING ExistingFileName
;
327 ANSI_STRING NewFileName
;
330 RtlInitAnsiString (&ExistingFileName
,
331 (LPSTR
)lpExistingFileName
);
333 RtlInitAnsiString (&NewFileName
,
334 (LPSTR
)lpNewFileName
);
336 /* convert ansi (or oem) string to unicode */
339 RtlAnsiStringToUnicodeString (&ExistingFileNameU
,
342 RtlAnsiStringToUnicodeString (&NewFileNameU
,
348 RtlOemStringToUnicodeString (&ExistingFileNameU
,
351 RtlOemStringToUnicodeString (&NewFileNameU
,
356 Result
= CopyFileExW (ExistingFileNameU
.Buffer
,
363 RtlFreeHeap (RtlGetProcessHeap (),
365 ExistingFileNameU
.Buffer
);
366 RtlFreeHeap (RtlGetProcessHeap (),
368 NewFileNameU
.Buffer
);
380 LPCSTR lpExistingFileName
,
381 LPCSTR lpNewFileName
,
385 return CopyFileExA (lpExistingFileName
,
400 LPCWSTR lpExistingFileName
,
401 LPCWSTR lpNewFileName
,
405 return CopyFileExW (lpExistingFileName
,