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 <kernel32/kernel32.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;
42 WINBOOL EndOfFileFound;
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);
196 LPCWSTR lpExistingFileName,
197 LPCWSTR lpNewFileName,
198 LPPROGRESS_ROUTINE lpProgressRoutine,
205 HANDLE FileHandleSource, FileHandleDest;
206 IO_STATUS_BLOCK IoStatusBlock;
207 FILE_STANDARD_INFORMATION FileStandard;
208 FILE_BASIC_INFORMATION FileBasic;
209 FILE_DISPOSITION_INFORMATION FileDispInfo;
211 WINBOOL KeepDestOnError = FALSE;
214 FileHandleSource = CreateFileW(lpExistingFileName,
219 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
221 if (INVALID_HANDLE_VALUE != FileHandleSource)
223 errCode = NtQueryInformationFile(FileHandleSource,
226 sizeof(FILE_STANDARD_INFORMATION),
227 FileStandardInformation);
228 if (!NT_SUCCESS(errCode))
230 DPRINT("Status 0x%08x obtaining FileStandardInformation for source\n", errCode);
231 SetLastErrorByStatus(errCode);
235 errCode = NtQueryInformationFile(FileHandleSource,
236 &IoStatusBlock,&FileBasic,
237 sizeof(FILE_BASIC_INFORMATION),
238 FileBasicInformation);
239 if (!NT_SUCCESS(errCode))
241 DPRINT("Status 0x%08x obtaining FileBasicInformation for source\n", errCode);
242 SetLastErrorByStatus(errCode);
246 FileHandleDest = CreateFileW(lpNewFileName,
250 dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS,
251 FileBasic.FileAttributes,
253 if (INVALID_HANDLE_VALUE != FileHandleDest)
255 errCode = CopyLoop(FileHandleSource,
257 FileStandard.EndOfFile,
262 if (!NT_SUCCESS(errCode))
264 SetLastErrorByStatus(errCode);
270 t.QuadPart = FileBasic.LastWriteTime.QuadPart;
271 errCode = SetLastWriteTime(FileHandleDest, t);
272 if (!NT_SUCCESS(errCode))
274 SetLastErrorByStatus(errCode);
281 NtClose(FileHandleDest);
282 if (! RC && ! KeepDestOnError)
284 SystemError = GetLastError();
285 SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL);
286 DeleteFileW(lpNewFileName);
287 SetLastError(SystemError);
292 DPRINT("Error %d during opening of dest file\n", GetLastError());
296 NtClose(FileHandleSource);
300 DPRINT("Error %d during opening of source file\n", GetLastError());
310 LPCSTR lpExistingFileName,
311 LPCSTR lpNewFileName,
312 LPPROGRESS_ROUTINE lpProgressRoutine,
318 UNICODE_STRING ExistingFileNameU;
319 UNICODE_STRING NewFileNameU;
320 ANSI_STRING ExistingFileName;
321 ANSI_STRING NewFileName;
324 RtlInitAnsiString (&ExistingFileName,
325 (LPSTR)lpExistingFileName);
327 RtlInitAnsiString (&NewFileName,
328 (LPSTR)lpNewFileName);
330 /* convert ansi (or oem) string to unicode */
333 RtlAnsiStringToUnicodeString (&ExistingFileNameU,
336 RtlAnsiStringToUnicodeString (&NewFileNameU,
342 RtlOemStringToUnicodeString (&ExistingFileNameU,
345 RtlOemStringToUnicodeString (&NewFileNameU,
350 Result = CopyFileExW (ExistingFileNameU.Buffer,
357 RtlFreeHeap (RtlGetProcessHeap (),
359 ExistingFileNameU.Buffer);
360 RtlFreeHeap (RtlGetProcessHeap (),
362 NewFileNameU.Buffer);
371 LPCSTR lpExistingFileName,
372 LPCSTR lpNewFileName,
373 WINBOOL bFailIfExists
376 return CopyFileExA (lpExistingFileName,
388 LPCWSTR lpExistingFileName,
389 LPCWSTR lpNewFileName,
390 WINBOOL bFailIfExists
393 return CopyFileExW (lpExistingFileName,