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 = LastWriteTime;
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);
268 errCode = SetLastWriteTime(FileHandleDest,
269 FileBasic.LastWriteTime);
270 if (!NT_SUCCESS(errCode))
272 SetLastErrorByStatus(errCode);
279 NtClose(FileHandleDest);
280 if (! RC && ! KeepDestOnError)
282 SystemError = GetLastError();
283 SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL);
284 DeleteFileW(lpNewFileName);
285 SetLastError(SystemError);
290 DPRINT("Error %d during opening of dest file\n", GetLastError());
294 NtClose(FileHandleSource);
298 DPRINT("Error %d during opening of source file\n", GetLastError());
308 LPCSTR lpExistingFileName,
309 LPCSTR lpNewFileName,
310 LPPROGRESS_ROUTINE lpProgressRoutine,
316 UNICODE_STRING ExistingFileNameU;
317 UNICODE_STRING NewFileNameU;
318 ANSI_STRING ExistingFileName;
319 ANSI_STRING NewFileName;
322 RtlInitAnsiString (&ExistingFileName,
323 (LPSTR)lpExistingFileName);
325 RtlInitAnsiString (&NewFileName,
326 (LPSTR)lpNewFileName);
328 /* convert ansi (or oem) string to unicode */
331 RtlAnsiStringToUnicodeString (&ExistingFileNameU,
334 RtlAnsiStringToUnicodeString (&NewFileNameU,
340 RtlOemStringToUnicodeString (&ExistingFileNameU,
343 RtlOemStringToUnicodeString (&NewFileNameU,
348 Result = CopyFileExW (ExistingFileNameU.Buffer,
355 RtlFreeHeap (RtlGetProcessHeap (),
357 ExistingFileNameU.Buffer);
358 RtlFreeHeap (RtlGetProcessHeap (),
360 NewFileNameU.Buffer);
369 LPCSTR lpExistingFileName,
370 LPCSTR lpNewFileName,
371 WINBOOL bFailIfExists
374 return CopyFileExA (lpExistingFileName,
386 LPCWSTR lpExistingFileName,
387 LPCWSTR lpNewFileName,
388 WINBOOL bFailIfExists
391 return CopyFileExW (lpExistingFileName,