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 ****************************************************************/
20 static ULONG gDebugChannel
= kernel32file
;
23 /* FUNCTIONS ****************************************************************/
28 HANDLE FileHandleSource
,
29 HANDLE FileHandleDest
,
30 LARGE_INTEGER SourceFileSize
,
31 LPPROGRESS_ROUTINE lpProgressRoutine
,
38 IO_STATUS_BLOCK IoStatusBlock
;
39 UCHAR
*lpBuffer
= NULL
;
40 SIZE_T RegionSize
= 0x10000;
41 LARGE_INTEGER BytesCopied
;
47 errCode
= NtAllocateVirtualMemory(NtCurrentProcess(),
51 MEM_RESERVE
| MEM_COMMIT
,
54 if (NT_SUCCESS(errCode
))
56 BytesCopied
.QuadPart
= 0;
57 EndOfFileFound
= FALSE
;
58 CallbackReason
= CALLBACK_STREAM_SWITCH
;
59 while (! EndOfFileFound
&&
60 NT_SUCCESS(errCode
) &&
61 (NULL
== pbCancel
|| ! *pbCancel
))
63 if (NULL
!= lpProgressRoutine
)
65 ProgressResult
= (*lpProgressRoutine
)(SourceFileSize
,
74 switch (ProgressResult
)
77 TRACE("Progress callback requested cancel\n");
78 errCode
= STATUS_REQUEST_ABORTED
;
81 TRACE("Progress callback requested stop\n");
82 errCode
= STATUS_REQUEST_ABORTED
;
86 lpProgressRoutine
= NULL
;
88 case PROGRESS_CONTINUE
:
92 CallbackReason
= CALLBACK_CHUNK_FINISHED
;
94 if (NT_SUCCESS(errCode
))
96 errCode
= NtReadFile(FileHandleSource
,
100 (PIO_STATUS_BLOCK
)&IoStatusBlock
,
105 if (NT_SUCCESS(errCode
) && (NULL
== pbCancel
|| ! *pbCancel
))
107 errCode
= NtWriteFile(FileHandleDest
,
111 (PIO_STATUS_BLOCK
)&IoStatusBlock
,
113 IoStatusBlock
.Information
,
116 if (NT_SUCCESS(errCode
))
118 BytesCopied
.QuadPart
+= IoStatusBlock
.Information
;
122 WARN("Error 0x%08x reading writing to dest\n", errCode
);
125 else if (!NT_SUCCESS(errCode
))
127 if (STATUS_END_OF_FILE
== errCode
)
129 EndOfFileFound
= TRUE
;
130 errCode
= STATUS_SUCCESS
;
134 WARN("Error 0x%08x reading from source\n", errCode
);
140 if (! EndOfFileFound
&& (NULL
!= pbCancel
&& *pbCancel
))
142 TRACE("User requested cancel\n");
143 errCode
= STATUS_REQUEST_ABORTED
;
146 NtFreeVirtualMemory(NtCurrentProcess(),
153 TRACE("Error 0x%08x allocating buffer of %d bytes\n", errCode
, RegionSize
);
162 LARGE_INTEGER LastWriteTime
165 NTSTATUS errCode
= STATUS_SUCCESS
;
166 IO_STATUS_BLOCK IoStatusBlock
;
167 FILE_BASIC_INFORMATION FileBasic
;
169 errCode
= NtQueryInformationFile (FileHandle
,
172 sizeof(FILE_BASIC_INFORMATION
),
173 FileBasicInformation
);
174 if (!NT_SUCCESS(errCode
))
176 WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode
);
180 FileBasic
.LastWriteTime
.QuadPart
= LastWriteTime
.QuadPart
;
181 errCode
= NtSetInformationFile (FileHandle
,
184 sizeof(FILE_BASIC_INFORMATION
),
185 FileBasicInformation
);
186 if (!NT_SUCCESS(errCode
))
188 WARN("Error 0x%0x setting LastWriteTime\n", errCode
);
202 LPCWSTR lpExistingFileName
,
203 LPCWSTR lpNewFileName
,
204 LPPROGRESS_ROUTINE lpProgressRoutine
,
211 HANDLE FileHandleSource
, FileHandleDest
;
212 IO_STATUS_BLOCK IoStatusBlock
;
213 FILE_STANDARD_INFORMATION FileStandard
;
214 FILE_BASIC_INFORMATION FileBasic
;
216 BOOL KeepDestOnError
= FALSE
;
219 FileHandleSource
= CreateFileW(lpExistingFileName
,
221 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
224 FILE_ATTRIBUTE_NORMAL
|FILE_FLAG_NO_BUFFERING
,
226 if (INVALID_HANDLE_VALUE
!= FileHandleSource
)
228 errCode
= NtQueryInformationFile(FileHandleSource
,
231 sizeof(FILE_STANDARD_INFORMATION
),
232 FileStandardInformation
);
233 if (!NT_SUCCESS(errCode
))
235 TRACE("Status 0x%08x obtaining FileStandardInformation for source\n", errCode
);
236 SetLastErrorByStatus(errCode
);
240 errCode
= NtQueryInformationFile(FileHandleSource
,
241 &IoStatusBlock
,&FileBasic
,
242 sizeof(FILE_BASIC_INFORMATION
),
243 FileBasicInformation
);
244 if (!NT_SUCCESS(errCode
))
246 TRACE("Status 0x%08x obtaining FileBasicInformation for source\n", errCode
);
247 SetLastErrorByStatus(errCode
);
251 FileHandleDest
= CreateFileW(lpNewFileName
,
255 dwCopyFlags
? CREATE_NEW
: CREATE_ALWAYS
,
256 FileBasic
.FileAttributes
,
258 if (INVALID_HANDLE_VALUE
!= FileHandleDest
)
260 errCode
= CopyLoop(FileHandleSource
,
262 FileStandard
.EndOfFile
,
267 if (!NT_SUCCESS(errCode
))
269 SetLastErrorByStatus(errCode
);
275 t
.QuadPart
= FileBasic
.LastWriteTime
.QuadPart
;
276 errCode
= SetLastWriteTime(FileHandleDest
, t
);
277 if (!NT_SUCCESS(errCode
))
279 SetLastErrorByStatus(errCode
);
286 NtClose(FileHandleDest
);
287 if (! RC
&& ! KeepDestOnError
)
289 SystemError
= GetLastError();
290 SetFileAttributesW(lpNewFileName
, FILE_ATTRIBUTE_NORMAL
);
291 DeleteFileW(lpNewFileName
);
292 SetLastError(SystemError
);
297 WARN("Error %d during opening of dest file\n", GetLastError());
301 NtClose(FileHandleSource
);
305 WARN("Error %d during opening of source file\n", GetLastError());
318 LPCSTR lpExistingFileName
,
319 LPCSTR lpNewFileName
,
320 LPPROGRESS_ROUTINE lpProgressRoutine
,
326 PWCHAR ExistingFileNameW
;
330 if (!(ExistingFileNameW
= FilenameA2W(lpExistingFileName
, FALSE
)))
333 if (!(NewFileNameW
= FilenameA2W(lpNewFileName
, TRUE
)))
336 Result
= CopyFileExW (ExistingFileNameW
,
343 RtlFreeHeap (RtlGetProcessHeap (),
357 LPCSTR lpExistingFileName
,
358 LPCSTR lpNewFileName
,
362 return CopyFileExA (lpExistingFileName
,
377 LPCWSTR lpExistingFileName
,
378 LPCWSTR lpNewFileName
,
382 return CopyFileExW (lpExistingFileName
,
397 LPCWSTR lpExistingFileName
,
398 LPCWSTR lpNewFileName
,
399 LPPROGRESS_ROUTINE lpProgressRoutine
,