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 static ULONG gDebugChannel
= kernel32file
;
20 /* FUNCTIONS ****************************************************************/
25 HANDLE FileHandleSource
,
26 HANDLE FileHandleDest
,
27 LARGE_INTEGER SourceFileSize
,
28 LPPROGRESS_ROUTINE lpProgressRoutine
,
35 IO_STATUS_BLOCK IoStatusBlock
;
36 UCHAR
*lpBuffer
= NULL
;
37 SIZE_T RegionSize
= 0x10000;
38 LARGE_INTEGER BytesCopied
;
44 errCode
= NtAllocateVirtualMemory(NtCurrentProcess(),
48 MEM_RESERVE
| MEM_COMMIT
,
51 if (NT_SUCCESS(errCode
))
53 BytesCopied
.QuadPart
= 0;
54 EndOfFileFound
= FALSE
;
55 CallbackReason
= CALLBACK_STREAM_SWITCH
;
56 while (! EndOfFileFound
&&
57 NT_SUCCESS(errCode
) &&
58 (NULL
== pbCancel
|| ! *pbCancel
))
60 if (NULL
!= lpProgressRoutine
)
62 ProgressResult
= (*lpProgressRoutine
)(SourceFileSize
,
71 switch (ProgressResult
)
74 TRACE("Progress callback requested cancel\n");
75 errCode
= STATUS_REQUEST_ABORTED
;
78 TRACE("Progress callback requested stop\n");
79 errCode
= STATUS_REQUEST_ABORTED
;
83 lpProgressRoutine
= NULL
;
85 case PROGRESS_CONTINUE
:
89 CallbackReason
= CALLBACK_CHUNK_FINISHED
;
91 if (NT_SUCCESS(errCode
))
93 errCode
= NtReadFile(FileHandleSource
,
97 (PIO_STATUS_BLOCK
)&IoStatusBlock
,
102 if (NT_SUCCESS(errCode
) && (NULL
== pbCancel
|| ! *pbCancel
))
104 errCode
= NtWriteFile(FileHandleDest
,
108 (PIO_STATUS_BLOCK
)&IoStatusBlock
,
110 IoStatusBlock
.Information
,
113 if (NT_SUCCESS(errCode
))
115 BytesCopied
.QuadPart
+= IoStatusBlock
.Information
;
119 WARN("Error 0x%08x reading writing to dest\n", errCode
);
122 else if (!NT_SUCCESS(errCode
))
124 if (STATUS_END_OF_FILE
== errCode
)
126 EndOfFileFound
= TRUE
;
127 errCode
= STATUS_SUCCESS
;
131 WARN("Error 0x%08x reading from source\n", errCode
);
137 if (! EndOfFileFound
&& (NULL
!= pbCancel
&& *pbCancel
))
139 TRACE("User requested cancel\n");
140 errCode
= STATUS_REQUEST_ABORTED
;
143 NtFreeVirtualMemory(NtCurrentProcess(),
150 TRACE("Error 0x%08x allocating buffer of %d bytes\n", errCode
, RegionSize
);
159 LARGE_INTEGER LastWriteTime
162 NTSTATUS errCode
= STATUS_SUCCESS
;
163 IO_STATUS_BLOCK IoStatusBlock
;
164 FILE_BASIC_INFORMATION FileBasic
;
166 errCode
= NtQueryInformationFile (FileHandle
,
169 sizeof(FILE_BASIC_INFORMATION
),
170 FileBasicInformation
);
171 if (!NT_SUCCESS(errCode
))
173 WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode
);
177 FileBasic
.LastWriteTime
.QuadPart
= LastWriteTime
.QuadPart
;
178 errCode
= NtSetInformationFile (FileHandle
,
181 sizeof(FILE_BASIC_INFORMATION
),
182 FileBasicInformation
);
183 if (!NT_SUCCESS(errCode
))
185 WARN("Error 0x%0x setting LastWriteTime\n", errCode
);
199 LPCWSTR lpExistingFileName
,
200 LPCWSTR lpNewFileName
,
201 LPPROGRESS_ROUTINE lpProgressRoutine
,
208 HANDLE FileHandleSource
, FileHandleDest
;
209 IO_STATUS_BLOCK IoStatusBlock
;
210 FILE_STANDARD_INFORMATION FileStandard
;
211 FILE_BASIC_INFORMATION FileBasic
;
213 BOOL KeepDestOnError
= FALSE
;
216 FileHandleSource
= CreateFileW(lpExistingFileName
,
218 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
221 FILE_ATTRIBUTE_NORMAL
|FILE_FLAG_NO_BUFFERING
,
223 if (INVALID_HANDLE_VALUE
!= FileHandleSource
)
225 errCode
= NtQueryInformationFile(FileHandleSource
,
228 sizeof(FILE_STANDARD_INFORMATION
),
229 FileStandardInformation
);
230 if (!NT_SUCCESS(errCode
))
232 TRACE("Status 0x%08x obtaining FileStandardInformation for source\n", errCode
);
233 SetLastErrorByStatus(errCode
);
237 errCode
= NtQueryInformationFile(FileHandleSource
,
238 &IoStatusBlock
,&FileBasic
,
239 sizeof(FILE_BASIC_INFORMATION
),
240 FileBasicInformation
);
241 if (!NT_SUCCESS(errCode
))
243 TRACE("Status 0x%08x obtaining FileBasicInformation for source\n", errCode
);
244 SetLastErrorByStatus(errCode
);
248 FileHandleDest
= CreateFileW(lpNewFileName
,
252 dwCopyFlags
? CREATE_NEW
: CREATE_ALWAYS
,
253 FileBasic
.FileAttributes
,
255 if (INVALID_HANDLE_VALUE
!= FileHandleDest
)
257 errCode
= CopyLoop(FileHandleSource
,
259 FileStandard
.EndOfFile
,
264 if (!NT_SUCCESS(errCode
))
266 SetLastErrorByStatus(errCode
);
272 t
.QuadPart
= FileBasic
.LastWriteTime
.QuadPart
;
273 errCode
= SetLastWriteTime(FileHandleDest
, t
);
274 if (!NT_SUCCESS(errCode
))
276 SetLastErrorByStatus(errCode
);
283 NtClose(FileHandleDest
);
284 if (! RC
&& ! KeepDestOnError
)
286 SystemError
= GetLastError();
287 SetFileAttributesW(lpNewFileName
, FILE_ATTRIBUTE_NORMAL
);
288 DeleteFileW(lpNewFileName
);
289 SetLastError(SystemError
);
294 WARN("Error %d during opening of dest file\n", GetLastError());
298 NtClose(FileHandleSource
);
302 WARN("Error %d during opening of source file\n", GetLastError());
315 LPCSTR lpExistingFileName
,
316 LPCSTR lpNewFileName
,
317 LPPROGRESS_ROUTINE lpProgressRoutine
,
323 PWCHAR ExistingFileNameW
;
327 if (!(ExistingFileNameW
= FilenameA2W(lpExistingFileName
, FALSE
)))
330 if (!(NewFileNameW
= FilenameA2W(lpNewFileName
, TRUE
)))
333 Result
= CopyFileExW (ExistingFileNameW
,
340 RtlFreeHeap (RtlGetProcessHeap (),
354 LPCSTR lpExistingFileName
,
355 LPCSTR lpNewFileName
,
359 return CopyFileExA (lpExistingFileName
,
374 LPCWSTR lpExistingFileName
,
375 LPCWSTR lpNewFileName
,
379 return CopyFileExW (lpExistingFileName
,
394 LPCWSTR lpExistingFileName
,
395 LPCWSTR lpNewFileName
,
396 LPPROGRESS_ROUTINE lpProgressRoutine
,