3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/file.c
6 * PURPOSE: Directory functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
8 * Gerhard W. Gruber (sparhawk_at_gmx.at)
13 /* INCLUDES *****************************************************************/
19 #include "../include/debug.h"
21 /* GLOBALS *****************************************************************/
23 /* FUNCTIONS ****************************************************************/
26 AdjustFileAttributes (
27 LPCWSTR ExistingFileName
,
31 IO_STATUS_BLOCK IoStatusBlock
;
32 FILE_BASIC_INFORMATION ExistingInfo
,
39 hFile
= CreateFileW (ExistingFileName
,
40 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
44 FILE_ATTRIBUTE_NORMAL
,
46 if (INVALID_HANDLE_VALUE
!= hFile
)
48 errCode
= NtQueryInformationFile (hFile
,
51 sizeof(FILE_BASIC_INFORMATION
),
52 FileBasicInformation
);
53 if (NT_SUCCESS (errCode
))
55 if (0 != (ExistingInfo
.FileAttributes
& FILE_ATTRIBUTE_READONLY
))
57 Attributes
= ExistingInfo
.FileAttributes
;
58 ExistingInfo
.FileAttributes
&= ~ FILE_ATTRIBUTE_READONLY
;
59 if (0 == (ExistingInfo
.FileAttributes
&
60 (FILE_ATTRIBUTE_HIDDEN
|
61 FILE_ATTRIBUTE_SYSTEM
|
62 FILE_ATTRIBUTE_ARCHIVE
)))
64 ExistingInfo
.FileAttributes
|= FILE_ATTRIBUTE_NORMAL
;
66 errCode
= NtSetInformationFile (hFile
,
69 sizeof(FILE_BASIC_INFORMATION
),
70 FileBasicInformation
);
71 if (!NT_SUCCESS(errCode
))
73 DPRINT("Removing READONLY attribute from source failed with status 0x%08x\n", errCode
);
75 ExistingInfo
.FileAttributes
= Attributes
;
79 if (NT_SUCCESS(errCode
))
81 hFile
= CreateFileW (NewFileName
,
82 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
86 FILE_ATTRIBUTE_NORMAL
,
88 if (INVALID_HANDLE_VALUE
!= hFile
)
90 errCode
= NtQueryInformationFile(hFile
,
93 sizeof(FILE_BASIC_INFORMATION
),
94 FileBasicInformation
);
95 if (NT_SUCCESS(errCode
))
97 NewInfo
.FileAttributes
= (NewInfo
.FileAttributes
&
98 ~ (FILE_ATTRIBUTE_HIDDEN
|
99 FILE_ATTRIBUTE_SYSTEM
|
100 FILE_ATTRIBUTE_READONLY
|
101 FILE_ATTRIBUTE_NORMAL
)) |
102 (ExistingInfo
.FileAttributes
&
103 (FILE_ATTRIBUTE_HIDDEN
|
104 FILE_ATTRIBUTE_SYSTEM
|
105 FILE_ATTRIBUTE_READONLY
|
106 FILE_ATTRIBUTE_NORMAL
)) |
107 FILE_ATTRIBUTE_ARCHIVE
;
108 NewInfo
.CreationTime
= ExistingInfo
.CreationTime
;
109 NewInfo
.LastAccessTime
= ExistingInfo
.LastAccessTime
;
110 NewInfo
.LastWriteTime
= ExistingInfo
.LastWriteTime
;
111 errCode
= NtSetInformationFile (hFile
,
114 sizeof(FILE_BASIC_INFORMATION
),
115 FileBasicInformation
);
116 if (NT_SUCCESS(errCode
))
122 DPRINT("Setting attributes on dest file failed with status 0x%08x\n", errCode
);
127 DPRINT("Obtaining attributes from dest file failed with status 0x%08x\n", errCode
);
133 DPRINT("Opening dest file to set attributes failed with code %d\n", GetLastError());
139 DPRINT("Obtaining attributes from source file failed with status 0x%08x\n", errCode
);
145 DPRINT("Opening source file to obtain attributes failed with code %d\n", GetLastError());
151 /***********************************************************************
152 * add_boot_rename_entry
154 * Adds an entry to the registry that is loaded when windows boots and
155 * checks if there are some files to be removed or renamed/moved.
156 * <fn1> has to be valid and <fn2> may be NULL. If both pointers are
157 * non-NULL then the file is moved, otherwise it is deleted. The
158 * entry of the registrykey is always appended with two zero
159 * terminated strings. If <fn2> is NULL then the second entry is
160 * simply a single 0-byte. Otherwise the second filename goes
161 * there. The entries are prepended with \??\ before the path and the
162 * second filename gets also a '!' as the first character if
163 * MOVEFILE_REPLACE_EXISTING is set. After the final string another
164 * 0-byte follows to indicate the end of the strings.
166 * \??\D:\test\file1[0]
167 * !\??\D:\test\file1_renamed[0]
168 * \??\D:\Test|delete[0]
169 * [0] <- file is to be deleted, second string empty
170 * \??\D:\test\file2[0]
171 * !\??\D:\test\file2_renamed[0]
172 * [0] <- indicates end of strings
175 * \??\D:\test\file1[0]
176 * !\??\D:\test\file1_renamed[0]
177 * \??\D:\Test|delete[0]
178 * [0] <- file is to be deleted, second string empty
179 * [0] <- indicates end of strings
182 static BOOL
add_boot_rename_entry( LPCWSTR source
, LPCWSTR dest
, DWORD flags
)
184 static const WCHAR ValueName
[] = {'P','e','n','d','i','n','g',
185 'F','i','l','e','R','e','n','a','m','e',
186 'O','p','e','r','a','t','i','o','n','s',0};
187 static const WCHAR SessionW
[] = {'M','a','c','h','i','n','e','\\',
188 'S','y','s','t','e','m','\\',
189 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
190 'C','o','n','t','r','o','l','\\',
191 'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r',0};
192 static const int info_size
= FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION
, Data
);
194 OBJECT_ATTRIBUTES attr
;
195 UNICODE_STRING nameW
, source_name
, dest_name
;
196 KEY_VALUE_PARTIAL_INFORMATION
*info
;
204 DPRINT("Add support to smss for keys created by MOVEFILE_DELAY_UNTIL_REBOOT\n");
206 if (!RtlDosPathNameToNtPathName_U( (LPWSTR
)source
, &source_name
, NULL
, NULL
))
208 SetLastError( ERROR_PATH_NOT_FOUND
);
211 dest_name
.Buffer
= NULL
;
212 if (dest
&& !RtlDosPathNameToNtPathName_U( (LPWSTR
)dest
, &dest_name
, NULL
, NULL
))
214 RtlFreeUnicodeString( &source_name
);
215 SetLastError( ERROR_PATH_NOT_FOUND
);
219 attr
.Length
= sizeof(attr
);
220 attr
.RootDirectory
= 0;
221 attr
.ObjectName
= &nameW
;
223 attr
.SecurityDescriptor
= NULL
;
224 attr
.SecurityQualityOfService
= NULL
;
225 RtlInitUnicodeString( &nameW
, SessionW
);
227 if (NtCreateKey( &Reboot
, KEY_ALL_ACCESS
, &attr
, 0, NULL
, 0, NULL
) != STATUS_SUCCESS
)
229 DPRINT1("Error creating key for reboot managment [%s]\n",
230 "SYSTEM\\CurrentControlSet\\Control\\Session Manager");
231 RtlFreeUnicodeString( &source_name
);
232 RtlFreeUnicodeString( &dest_name
);
236 len1
= source_name
.Length
+ sizeof(WCHAR
);
239 len2
= dest_name
.Length
+ sizeof(WCHAR
);
240 if (flags
& MOVEFILE_REPLACE_EXISTING
)
241 len2
+= sizeof(WCHAR
); /* Plus 1 because of the leading '!' */
243 else len2
= sizeof(WCHAR
); /* minimum is the 0 characters for the empty second string */
245 RtlInitUnicodeString( &nameW
, ValueName
);
247 /* First we check if the key exists and if so how many bytes it already contains. */
248 if (NtQueryValueKey( Reboot
, &nameW
, KeyValuePartialInformation
,
249 NULL
, 0, &DataSize
) == STATUS_BUFFER_OVERFLOW
)
251 if (!(Buffer
= HeapAlloc( GetProcessHeap(), 0, DataSize
+ len1
+ len2
+ sizeof(WCHAR
) )))
253 if (NtQueryValueKey( Reboot
, &nameW
, KeyValuePartialInformation
,
254 Buffer
, DataSize
, &DataSize
)) goto Quit
;
255 info
= (KEY_VALUE_PARTIAL_INFORMATION
*)Buffer
;
256 if (info
->Type
!= REG_MULTI_SZ
) goto Quit
;
257 if (DataSize
> sizeof(info
)) DataSize
-= sizeof(WCHAR
); /* remove terminating null (will be added back later) */
261 DataSize
= info_size
;
262 if (!(Buffer
= HeapAlloc( GetProcessHeap(), 0, DataSize
+ len1
+ len2
+ sizeof(WCHAR
) )))
266 memcpy( Buffer
+ DataSize
, source_name
.Buffer
, len1
);
268 p
= (WCHAR
*)(Buffer
+ DataSize
);
271 if (flags
& MOVEFILE_REPLACE_EXISTING
)
273 memcpy( p
, dest_name
.Buffer
, len2
);
279 DataSize
+= sizeof(WCHAR
);
283 p
= (WCHAR
*)(Buffer
+ DataSize
);
285 DataSize
+= sizeof(WCHAR
);
287 rc
= !NtSetValueKey(Reboot
, &nameW
, 0, REG_MULTI_SZ
, Buffer
+ info_size
, DataSize
- info_size
);
290 RtlFreeUnicodeString( &source_name
);
291 RtlFreeUnicodeString( &dest_name
);
292 if (Reboot
) NtClose(Reboot
);
293 HeapFree( GetProcessHeap(), 0, Buffer
);
303 MoveFileWithProgressW (
304 LPCWSTR lpExistingFileName
,
305 LPCWSTR lpNewFileName
,
306 LPPROGRESS_ROUTINE lpProgressRoutine
,
312 IO_STATUS_BLOCK IoStatusBlock
;
313 PFILE_RENAME_INFORMATION FileRename
;
316 UNICODE_STRING DstPathU
;
319 DPRINT("MoveFileWithProgressW()\n");
321 if (dwFlags
& MOVEFILE_DELAY_UNTIL_REBOOT
)
322 return add_boot_rename_entry( lpExistingFileName
, lpNewFileName
, dwFlags
);
324 hFile
= CreateFileW (lpExistingFileName
,
326 FILE_SHARE_WRITE
|FILE_SHARE_READ
,
329 FILE_FLAG_BACKUP_SEMANTICS
,
332 if (hFile
== INVALID_HANDLE_VALUE
)
338 /* validate & translate the filename */
339 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpNewFileName
,
344 DPRINT("Invalid destination path\n");
346 SetLastError(ERROR_PATH_NOT_FOUND
);
350 FileRename
= alloca(sizeof(FILE_RENAME_INFORMATION
) + DstPathU
.Length
);
351 if ((dwFlags
& MOVEFILE_REPLACE_EXISTING
) == MOVEFILE_REPLACE_EXISTING
)
352 FileRename
->ReplaceIfExists
= TRUE
;
354 FileRename
->ReplaceIfExists
= FALSE
;
356 memcpy(FileRename
->FileName
, DstPathU
.Buffer
, DstPathU
.Length
);
357 RtlFreeHeap (RtlGetProcessHeap (),
362 * Is the length the count of characters or the length of the buffer?
364 FileRename
->FileNameLength
= DstPathU
.Length
/ sizeof(WCHAR
);
365 errCode
= NtSetInformationFile (hFile
,
368 sizeof(FILE_RENAME_INFORMATION
) + DstPathU
.Length
,
369 FileRenameInformation
);
372 if (GetFileAttributesW(lpExistingFileName
) & FILE_ATTRIBUTE_DIRECTORY
)
380 * Fail now move the folder
381 * Before we fail at CreateFileW
385 if (NT_SUCCESS(errCode
))
393 Result
= CopyFileExW (lpExistingFileName
,
398 FileRename
->ReplaceIfExists
? 0 : COPY_FILE_FAIL_IF_EXISTS
);
401 /* Cleanup the source file */
402 AdjustFileAttributes(lpExistingFileName
, lpNewFileName
);
403 Result
= DeleteFileW (lpExistingFileName
);
408 /* move folder code start */
409 WIN32_FIND_DATAW findBuffer
;
410 LPCWSTR lpExistingFileName2
= NULL
;
411 LPCWSTR lpNewFileName2
= NULL
;
412 LPCWSTR lpDeleteFile
= NULL
;
418 /* Build the string */
419 size
= wcslen(lpExistingFileName
);
421 lpDeleteFile
= (LPCWSTR
) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,MAX_PATH
* sizeof(WCHAR
));
422 if (lpDeleteFile
== NULL
)
425 lpNewFileName2
= (LPCWSTR
) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,MAX_PATH
* sizeof(WCHAR
));
426 if (lpNewFileName2
== NULL
)
429 lpExistingFileName2
= (LPCWSTR
) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,MAX_PATH
* sizeof(WCHAR
));
430 if (lpExistingFileName2
== NULL
)
433 if ((size
+6)*sizeof(WCHAR
)>MAX_PATH
)
435 HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,(VOID
*) lpExistingFileName2
,(size
+6)*sizeof(WCHAR
));
436 if (lpExistingFileName2
== NULL
)
440 wcscpy( (WCHAR
*)lpExistingFileName2
,lpExistingFileName
);
441 wcscpy( (WCHAR
*)&lpExistingFileName2
[size
],L
"\\*.*\0");
443 /* Get the file name */
444 memset(&findBuffer
,0,sizeof(WIN32_FIND_DATAW
));
445 hFile
= FindFirstFileW(lpExistingFileName2
, &findBuffer
);
449 if (findBuffer
.cFileName
[0] == L
'\0')
452 DPRINT("MoveFileWithProgressW : lpExistingFileName1 = %S\n",lpExistingFileName
);
453 DPRINT("MoveFileWithProgressW : lpExistingFileName2 = %S\n",lpExistingFileName2
);
454 DPRINT("MoveFileWithProgressW : lpNewFileName = %S\n",lpNewFileName
);
456 DPRINT("MoveFileWithProgressW : loop = %d %d %d\n",TRUE
, FALSE
, loop
);
459 CreateDirectoryW(lpNewFileName
,NULL
);
462 /* search the file */
467 if ((!wcscmp(findBuffer
.cFileName
,L
"..")) || (!wcscmp(findBuffer
.cFileName
,L
".")))
469 loop
= FindNextFileW(hFile
, &findBuffer
);
473 size
= wcslen(lpExistingFileName2
)-4;
475 wcscpy( (WCHAR
*)&lpExistingFileName2
[size
],L
"\0");
477 if (wcsncmp(lpExistingFileName
,lpExistingFileName2
,size
))
483 size
= GetFullPathNameW(lpExistingFileName2
, MAX_PATH
,(LPWSTR
) lpDeleteFile
, NULL
);
486 lpDeleteFile
= (LPCWSTR
) HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
487 (VOID
*) lpDeleteFile
,size
);
489 if (lpDeleteFile
== NULL
)
495 GetFullPathNameW(lpExistingFileName2
, size
,(LPWSTR
) lpDeleteFile
, NULL
);
498 DPRINT("MoveFileWithProgressW : folder : %s\n",lpDeleteFile
);
500 Result
= RemoveDirectoryW(lpDeleteFile
);
505 size
= wcslen(lpExistingFileName
);
507 if ((size
+6)*sizeof(WCHAR
)>MAX_PATH
)
509 lpExistingFileName2
= (LPCWSTR
) HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
510 (VOID
*)lpExistingFileName2
,(size
+6)*sizeof(WCHAR
));
512 if (lpExistingFileName2
== NULL
)
519 wcscpy( (WCHAR
*)lpExistingFileName2
,lpExistingFileName
);
520 wcscpy( (WCHAR
*)&lpExistingFileName2
[size
],L
"\\*.*\0");
522 /* Get the file name */
523 memset(&findBuffer
,0,sizeof(WIN32_FIND_DATAW
));
524 hFile
= FindFirstFileW(lpExistingFileName2
, &findBuffer
);
530 if (findBuffer
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
532 DPRINT("MoveFileWithProgressW : 1: %S %S\n",lpExistingFileName2
,findBuffer
.cFileName
);
534 /* Build the new string */
535 size
= wcslen(findBuffer
.cFileName
);
536 size2
= wcslen(lpExistingFileName2
);
538 if ((size2
+size
+6)*sizeof(WCHAR
)>MAX_PATH
)
540 lpExistingFileName2
= (LPCWSTR
) HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
541 (VOID
*)lpExistingFileName2
, (size2
+size
+6)*sizeof(WCHAR
));
543 if (lpExistingFileName2
== NULL
)
550 wcscpy( (WCHAR
*)&lpExistingFileName2
[size2
-3],findBuffer
.cFileName
);
551 wcscpy( (WCHAR
*)&lpExistingFileName2
[size2
+size
-3],L
"\\*.*\0");
554 /* Build the new dst string */
555 size
= wcslen(lpExistingFileName2
) + wcslen(lpNewFileName
);
556 size2
= wcslen(lpExistingFileName
);
560 lpNewFileName2
= (LPCWSTR
) HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
561 (VOID
*) lpNewFileName2
, size
*sizeof(WCHAR
));
563 if (lpNewFileName2
== NULL
)
570 wcscpy((WCHAR
*) lpNewFileName2
,lpNewFileName
);
571 size
= wcslen(lpNewFileName
);
572 wcscpy((WCHAR
*)&lpNewFileName2
[size
], (WCHAR
*)&lpExistingFileName2
[size2
]);
573 size
= wcslen(lpNewFileName2
);
574 wcscpy( (WCHAR
*)&lpNewFileName2
[size
-4],L
"\0");
576 /* build dest path */
577 /* remove this code when it will be out into kernel32.dll ? */
579 size
= GetFullPathNameW(lpNewFileName2
, MAX_PATH
,(LPWSTR
) lpDeleteFile
, NULL
);
582 lpDeleteFile
= (LPCWSTR
) HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
583 (VOID
*) lpDeleteFile
,size
) ;
585 if (lpDeleteFile
== NULL
)
591 GetFullPathNameW(lpNewFileName2
, size
,(LPWSTR
) lpDeleteFile
, NULL
);
596 DPRINT("MoveFileWithProgressW : CreateDirectoryW lpNewFileName2 : %S\n",lpNewFileName2
);
597 DPRINT("MoveFileWithProgressW : CreateDirectoryW : %S\n",lpDeleteFile
);
599 CreateDirectoryW(lpDeleteFile
,NULL
);
601 DPRINT("MoveFileWithProgressW : 1x: %S : %S \n",lpExistingFileName2
, lpNewFileName2
);
604 memset(&findBuffer
,0,sizeof(WIN32_FIND_DATAW
));
605 hFile
= FindFirstFileW(lpExistingFileName2
, &findBuffer
);
610 /* Build the new string */
611 size
= wcslen(findBuffer
.cFileName
);
612 size2
= wcslen(lpExistingFileName2
);
613 wcscpy( (WCHAR
*)lpDeleteFile
,lpExistingFileName2
);
614 wcscpy( (WCHAR
*)&lpDeleteFile
[size2
-3],findBuffer
.cFileName
);
616 /* Build dest string */
617 size
= wcslen(lpDeleteFile
) + wcslen(lpNewFileName
);
618 size2
= wcslen(lpExistingFileName
);
620 if (size
*sizeof(WCHAR
)>MAX_PATH
)
622 lpNewFileName2
= (LPCWSTR
) HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
623 (VOID
*) lpNewFileName2
, size
*sizeof(WCHAR
));
625 if (lpNewFileName2
== NULL
)
632 wcscpy((WCHAR
*) lpNewFileName2
,lpNewFileName
);
633 size
= wcslen(lpNewFileName
);
634 wcscpy((WCHAR
*)&lpNewFileName2
[size
], (WCHAR
*)&lpDeleteFile
[size2
]);
637 Result
= CopyFileW(lpDeleteFile
,lpNewFileName2
, FALSE
);
640 DPRINT("MoveFileWithProgressW : Delete file : %S : %S\n",lpDeleteFile
, lpNewFileName2
);
643 Result
= DeleteFileW(lpDeleteFile
);
646 DPRINT("MoveFileWithProgressW : Fails\n");
650 DPRINT("MoveFileWithProgressW : 2 : %S : %S \n",lpExistingFileName2
,findBuffer
.cFileName
);
651 loop
= FindNextFileW(hFile
, &findBuffer
);
655 memset(&findBuffer
,0,sizeof(WIN32_FIND_DATAW
));
656 hFile
= FindFirstFileW(lpExistingFileName2
, &findBuffer
);
660 if (findBuffer
.cFileName
[0] == L
'\0')
666 Result
= RemoveDirectoryW(lpExistingFileName
);
667 DPRINT("MoveFileWithProgressW RemoveDirectoryW :%S",lpExistingFileName
);
671 DPRINT("MoveFileWithProgressW : result : r=%d, T=%d, F=%d",Result
,TRUE
,FALSE
);
673 if (lpNewFileName2
!= NULL
)
675 HeapFree(GetProcessHeap(),0,(VOID
*) lpNewFileName2
);
676 lpNewFileName2
= NULL
;
679 if (lpExistingFileName2
!= NULL
)
681 HeapFree(GetProcessHeap(),0,(VOID
*) lpExistingFileName2
);
682 lpExistingFileName2
= NULL
;
685 if (lpDeleteFile
!= NULL
)
687 HeapFree(GetProcessHeap(),0,(VOID
*) lpDeleteFile
);
692 // end move folder code
697 /* FIXME file rename not yet implemented in all FSDs so it will always
698 * fail, even when the move is to the same device
700 //else if (STATUS_NOT_IMPLEMENTED == errCode)
703 UNICODE_STRING SrcPathU
;
705 SrcPathU
.Buffer
= alloca(sizeof(WCHAR
) * MAX_PATH
);
706 SrcPathU
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
707 SrcPathU
.Length
= GetFullPathNameW(lpExistingFileName
, MAX_PATH
, SrcPathU
.Buffer
, NULL
);
708 if (SrcPathU
.Length
>= MAX_PATH
)
710 SetLastError(ERROR_FILENAME_EXCED_RANGE
);
713 SrcPathU
.Length
*= sizeof(WCHAR
);
715 DstPathU
.Buffer
= alloca(sizeof(WCHAR
) * MAX_PATH
);
716 DstPathU
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
717 DstPathU
.Length
= GetFullPathNameW(lpNewFileName
, MAX_PATH
, DstPathU
.Buffer
, NULL
);
718 if (DstPathU
.Length
>= MAX_PATH
)
720 SetLastError(ERROR_FILENAME_EXCED_RANGE
);
723 DstPathU
.Length
*= sizeof(WCHAR
);
725 if (0 == RtlCompareUnicodeString(&SrcPathU
, &DstPathU
, TRUE
))
727 /* Source and destination file are the same, nothing to do */
731 Result
= CopyFileExW (lpExistingFileName
,
736 FileRename
->ReplaceIfExists
? 0 : COPY_FILE_FAIL_IF_EXISTS
);
739 /* Cleanup the source file */
740 AdjustFileAttributes(lpExistingFileName
, lpNewFileName
);
741 Result
= DeleteFileW (lpExistingFileName
);
755 MoveFileWithProgressA (
756 LPCSTR lpExistingFileName
,
757 LPCSTR lpNewFileName
,
758 LPPROGRESS_ROUTINE lpProgressRoutine
,
763 PWCHAR ExistingFileNameW
;
767 if (!(ExistingFileNameW
= FilenameA2W(lpExistingFileName
, FALSE
)))
770 if (!(NewFileNameW
= FilenameA2W(lpNewFileName
, TRUE
)))
773 ret
= MoveFileWithProgressW (ExistingFileNameW
,
779 RtlFreeHeap (RtlGetProcessHeap (), 0, NewFileNameW
);
791 LPCWSTR lpExistingFileName
,
792 LPCWSTR lpNewFileName
795 return MoveFileExW (lpExistingFileName
,
797 MOVEFILE_COPY_ALLOWED
);
807 LPCWSTR lpExistingFileName
,
808 LPCWSTR lpNewFileName
,
812 return MoveFileWithProgressW (lpExistingFileName
,
826 LPCSTR lpExistingFileName
,
830 return MoveFileExA (lpExistingFileName
,
832 MOVEFILE_COPY_ALLOWED
);
842 LPCSTR lpExistingFileName
,
843 LPCSTR lpNewFileName
,
847 return MoveFileWithProgressA (lpExistingFileName
,