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 ****************************************************************/
19 /* FUNCTIONS ****************************************************************/
24 HANDLE FileHandleSource
,
25 HANDLE FileHandleDest
,
26 LARGE_INTEGER SourceFileSize
,
27 LPPROGRESS_ROUTINE lpProgressRoutine
,
34 IO_STATUS_BLOCK IoStatusBlock
;
35 UCHAR
*lpBuffer
= NULL
;
36 SIZE_T RegionSize
= 0x10000;
37 LARGE_INTEGER BytesCopied
;
43 errCode
= NtAllocateVirtualMemory(NtCurrentProcess(),
47 MEM_RESERVE
| MEM_COMMIT
,
50 if (NT_SUCCESS(errCode
))
52 BytesCopied
.QuadPart
= 0;
53 EndOfFileFound
= FALSE
;
54 CallbackReason
= CALLBACK_STREAM_SWITCH
;
55 while (! EndOfFileFound
&&
56 NT_SUCCESS(errCode
) &&
57 (NULL
== pbCancel
|| ! *pbCancel
))
59 if (NULL
!= lpProgressRoutine
)
61 ProgressResult
= (*lpProgressRoutine
)(SourceFileSize
,
70 switch (ProgressResult
)
73 TRACE("Progress callback requested cancel\n");
74 errCode
= STATUS_REQUEST_ABORTED
;
77 TRACE("Progress callback requested stop\n");
78 errCode
= STATUS_REQUEST_ABORTED
;
82 lpProgressRoutine
= NULL
;
84 case PROGRESS_CONTINUE
:
88 CallbackReason
= CALLBACK_CHUNK_FINISHED
;
90 if (NT_SUCCESS(errCode
))
92 errCode
= NtReadFile(FileHandleSource
,
96 (PIO_STATUS_BLOCK
)&IoStatusBlock
,
101 if (NT_SUCCESS(errCode
) && (NULL
== pbCancel
|| ! *pbCancel
))
103 errCode
= NtWriteFile(FileHandleDest
,
107 (PIO_STATUS_BLOCK
)&IoStatusBlock
,
109 IoStatusBlock
.Information
,
112 if (NT_SUCCESS(errCode
))
114 BytesCopied
.QuadPart
+= IoStatusBlock
.Information
;
118 WARN("Error 0x%08x reading writing to dest\n", errCode
);
121 else if (!NT_SUCCESS(errCode
))
123 if (STATUS_END_OF_FILE
== errCode
)
125 EndOfFileFound
= TRUE
;
126 errCode
= STATUS_SUCCESS
;
130 WARN("Error 0x%08x reading from source\n", errCode
);
136 if (! EndOfFileFound
&& (NULL
!= pbCancel
&& *pbCancel
))
138 TRACE("User requested cancel\n");
139 errCode
= STATUS_REQUEST_ABORTED
;
142 NtFreeVirtualMemory(NtCurrentProcess(),
149 TRACE("Error 0x%08x allocating buffer of %d bytes\n", errCode
, RegionSize
);
158 LARGE_INTEGER LastWriteTime
161 NTSTATUS errCode
= STATUS_SUCCESS
;
162 IO_STATUS_BLOCK IoStatusBlock
;
163 FILE_BASIC_INFORMATION FileBasic
;
165 errCode
= NtQueryInformationFile (FileHandle
,
168 sizeof(FILE_BASIC_INFORMATION
),
169 FileBasicInformation
);
170 if (!NT_SUCCESS(errCode
))
172 WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode
);
176 FileBasic
.LastWriteTime
.QuadPart
= LastWriteTime
.QuadPart
;
177 errCode
= NtSetInformationFile (FileHandle
,
180 sizeof(FILE_BASIC_INFORMATION
),
181 FileBasicInformation
);
182 if (!NT_SUCCESS(errCode
))
184 WARN("Error 0x%0x setting LastWriteTime\n", errCode
);
198 LPCWSTR lpExistingFileName
,
199 LPCWSTR lpNewFileName
,
200 LPPROGRESS_ROUTINE lpProgressRoutine
,
207 HANDLE FileHandleSource
, FileHandleDest
;
208 IO_STATUS_BLOCK IoStatusBlock
;
209 FILE_STANDARD_INFORMATION FileStandard
;
210 FILE_BASIC_INFORMATION FileBasic
;
212 BOOL KeepDestOnError
= FALSE
;
215 FileHandleSource
= CreateFileW(lpExistingFileName
,
217 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
220 FILE_ATTRIBUTE_NORMAL
|FILE_FLAG_NO_BUFFERING
,
222 if (INVALID_HANDLE_VALUE
!= FileHandleSource
)
224 errCode
= NtQueryInformationFile(FileHandleSource
,
227 sizeof(FILE_STANDARD_INFORMATION
),
228 FileStandardInformation
);
229 if (!NT_SUCCESS(errCode
))
231 TRACE("Status 0x%08x obtaining FileStandardInformation for source\n", errCode
);
232 SetLastErrorByStatus(errCode
);
236 errCode
= NtQueryInformationFile(FileHandleSource
,
237 &IoStatusBlock
,&FileBasic
,
238 sizeof(FILE_BASIC_INFORMATION
),
239 FileBasicInformation
);
240 if (!NT_SUCCESS(errCode
))
242 TRACE("Status 0x%08x obtaining FileBasicInformation for source\n", errCode
);
243 SetLastErrorByStatus(errCode
);
247 FileHandleDest
= CreateFileW(lpNewFileName
,
251 dwCopyFlags
? CREATE_NEW
: CREATE_ALWAYS
,
252 FileBasic
.FileAttributes
,
254 if (INVALID_HANDLE_VALUE
!= FileHandleDest
)
256 errCode
= CopyLoop(FileHandleSource
,
258 FileStandard
.EndOfFile
,
263 if (!NT_SUCCESS(errCode
))
265 SetLastErrorByStatus(errCode
);
271 t
.QuadPart
= FileBasic
.LastWriteTime
.QuadPart
;
272 errCode
= SetLastWriteTime(FileHandleDest
, t
);
273 if (!NT_SUCCESS(errCode
))
275 SetLastErrorByStatus(errCode
);
282 NtClose(FileHandleDest
);
283 if (! RC
&& ! KeepDestOnError
)
285 SystemError
= GetLastError();
286 SetFileAttributesW(lpNewFileName
, FILE_ATTRIBUTE_NORMAL
);
287 DeleteFileW(lpNewFileName
);
288 SetLastError(SystemError
);
293 WARN("Error %d during opening of dest file\n", GetLastError());
297 NtClose(FileHandleSource
);
301 WARN("Error %d during opening of source file\n", GetLastError());
314 LPCSTR lpExistingFileName
,
315 LPCSTR lpNewFileName
,
316 LPPROGRESS_ROUTINE lpProgressRoutine
,
322 PWCHAR ExistingFileNameW
;
326 if (!(ExistingFileNameW
= FilenameA2W(lpExistingFileName
, FALSE
)))
329 if (!(NewFileNameW
= FilenameA2W(lpNewFileName
, TRUE
)))
332 Result
= CopyFileExW (ExistingFileNameW
,
339 RtlFreeHeap (RtlGetProcessHeap (),
353 LPCSTR lpExistingFileName
,
354 LPCSTR lpNewFileName
,
358 return CopyFileExA (lpExistingFileName
,
373 LPCWSTR lpExistingFileName
,
374 LPCWSTR lpNewFileName
,
378 return CopyFileExW (lpExistingFileName
,
393 LPCWSTR lpExistingFileName
,
394 LPCWSTR lpNewFileName
,
395 LPPROGRESS_ROUTINE lpProgressRoutine
,