mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 02:26:03 +00:00
- Split up the handling if the fsd returns STATUS_NOT_IMPLEMENTED in MoveFileWithProgressW.
- Converted the destination name before calling NtSetInformationFile in MoveFileWithProgressW. svn path=/trunk/; revision=11912
This commit is contained in:
parent
98ac389c31
commit
88ab19cd71
1 changed files with 95 additions and 41 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: move.c,v 1.14 2004/06/13 20:04:55 navaraf Exp $
|
/* $Id: move.c,v 1.15 2004/12/04 15:38:22 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -16,9 +16,15 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "../include/debug.h"
|
#include "../include/debug.h"
|
||||||
|
|
||||||
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
#define FILE_RENAME_SIZE MAX_PATH +sizeof(FILE_RENAME_INFORMATION)
|
#if defined(__GNUC__)
|
||||||
|
void * alloca(size_t size);
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
void* _alloca(size_t size);
|
||||||
|
#else
|
||||||
|
#error Unknown compiler for alloca intrinsic stack allocation "function"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
@ -164,11 +170,12 @@ MoveFileWithProgressW (
|
||||||
{
|
{
|
||||||
HANDLE hFile = NULL;
|
HANDLE hFile = NULL;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
FILE_RENAME_INFORMATION *FileRename;
|
PFILE_RENAME_INFORMATION FileRename;
|
||||||
USHORT Buffer[FILE_RENAME_SIZE];
|
|
||||||
NTSTATUS errCode;
|
NTSTATUS errCode;
|
||||||
DWORD err;
|
|
||||||
BOOL Result;
|
BOOL Result;
|
||||||
|
UNICODE_STRING DstPathU;
|
||||||
|
|
||||||
|
DPRINT("MoveFileWithProgressW()\n");
|
||||||
|
|
||||||
hFile = CreateFileW (lpExistingFileName,
|
hFile = CreateFileW (lpExistingFileName,
|
||||||
GENERIC_ALL,
|
GENERIC_ALL,
|
||||||
|
@ -178,71 +185,118 @@ MoveFileWithProgressW (
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
FileRename = (FILE_RENAME_INFORMATION *)Buffer;
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* validate & translate the filename */
|
||||||
|
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpNewFileName,
|
||||||
|
&DstPathU,
|
||||||
|
NULL,
|
||||||
|
NULL))
|
||||||
|
{
|
||||||
|
DPRINT("Invalid destination path\n");
|
||||||
|
CloseHandle(hFile);
|
||||||
|
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileRename = alloca(sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length);
|
||||||
if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == MOVEFILE_REPLACE_EXISTING)
|
if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == MOVEFILE_REPLACE_EXISTING)
|
||||||
FileRename->ReplaceIfExists = TRUE;
|
FileRename->ReplaceIfExists = TRUE;
|
||||||
else
|
else
|
||||||
FileRename->ReplaceIfExists = FALSE;
|
FileRename->ReplaceIfExists = FALSE;
|
||||||
FileRename->FileNameLength = wcslen (lpNewFileName);
|
|
||||||
memcpy (FileRename->FileName,
|
|
||||||
lpNewFileName,
|
|
||||||
min(FileRename->FileNameLength, MAX_PATH));
|
|
||||||
|
|
||||||
|
memcpy(FileRename->FileName, DstPathU.Buffer, DstPathU.Length);
|
||||||
|
RtlFreeHeap (RtlGetProcessHeap (),
|
||||||
|
0,
|
||||||
|
DstPathU.Buffer);
|
||||||
|
/*
|
||||||
|
* FIXME:
|
||||||
|
* Is the length the count of characters or the length of the buffer?
|
||||||
|
*/
|
||||||
|
FileRename->FileNameLength = DstPathU.Length / sizeof(WCHAR);
|
||||||
errCode = NtSetInformationFile (hFile,
|
errCode = NtSetInformationFile (hFile,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
FileRename,
|
FileRename,
|
||||||
FILE_RENAME_SIZE,
|
sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length,
|
||||||
FileRenameInformation);
|
FileRenameInformation);
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
if (NT_SUCCESS(errCode))
|
if (NT_SUCCESS(errCode))
|
||||||
{
|
{
|
||||||
Result = TRUE;
|
Result = TRUE;
|
||||||
}
|
}
|
||||||
/* FIXME file rename not yet implemented in all FSDs so it will always
|
|
||||||
* fail, even when the move is to the same device
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
else if (STATUS_NOT_SAME_DEVICE == errCode &&
|
else if (STATUS_NOT_SAME_DEVICE == errCode &&
|
||||||
MOVEFILE_COPY_ALLOWED == (dwFlags & MOVEFILE_COPY_ALLOWED))
|
MOVEFILE_COPY_ALLOWED == (dwFlags & MOVEFILE_COPY_ALLOWED))
|
||||||
#else
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
Result = CopyFileExW (lpExistingFileName,
|
Result = CopyFileExW (lpExistingFileName,
|
||||||
lpNewFileName,
|
lpNewFileName,
|
||||||
lpProgressRoutine,
|
lpProgressRoutine,
|
||||||
lpData,
|
lpData,
|
||||||
NULL,
|
NULL,
|
||||||
FileRename->ReplaceIfExists ? 0 : COPY_FILE_FAIL_IF_EXISTS) &&
|
FileRename->ReplaceIfExists ? 0 : COPY_FILE_FAIL_IF_EXISTS);
|
||||||
AdjustFileAttributes(lpExistingFileName, lpNewFileName) &&
|
if (Result)
|
||||||
DeleteFileW (lpExistingFileName);
|
|
||||||
if (! Result)
|
|
||||||
{
|
{
|
||||||
/* Delete of the existing file failed so the
|
/* Cleanup the source file */
|
||||||
* existing file is still there. Clean up the
|
AdjustFileAttributes(lpExistingFileName, lpNewFileName);
|
||||||
* new file (if possible)
|
Result = DeleteFileW (lpExistingFileName);
|
||||||
*/
|
|
||||||
err = GetLastError();
|
|
||||||
if (! SetFileAttributesW (lpNewFileName, FILE_ATTRIBUTE_NORMAL))
|
|
||||||
{
|
|
||||||
DPRINT("Removing possible READONLY attrib from new file failed with code %d\n", GetLastError());
|
|
||||||
}
|
|
||||||
if (! DeleteFileW (lpNewFileName))
|
|
||||||
{
|
|
||||||
DPRINT("Deleting new file during cleanup failed with code %d\n", GetLastError());
|
|
||||||
}
|
|
||||||
SetLastError (err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* See FIXME above */
|
#if 1
|
||||||
#if 0
|
/* FIXME file rename not yet implemented in all FSDs so it will always
|
||||||
|
* fail, even when the move is to the same device
|
||||||
|
*/
|
||||||
|
else if (STATUS_NOT_IMPLEMENTED == errCode)
|
||||||
|
{
|
||||||
|
|
||||||
|
UNICODE_STRING SrcPathU;
|
||||||
|
|
||||||
|
SrcPathU.Buffer = alloca(sizeof(WCHAR) * MAX_PATH);
|
||||||
|
SrcPathU.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
||||||
|
SrcPathU.Length = GetFullPathNameW(lpExistingFileName, MAX_PATH, SrcPathU.Buffer, NULL);
|
||||||
|
if (SrcPathU.Length >= MAX_PATH)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
SrcPathU.Length *= sizeof(WCHAR);
|
||||||
|
|
||||||
|
DstPathU.Buffer = alloca(sizeof(WCHAR) * MAX_PATH);
|
||||||
|
DstPathU.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
||||||
|
DstPathU.Length = GetFullPathNameW(lpNewFileName, MAX_PATH, DstPathU.Buffer, NULL);
|
||||||
|
if (DstPathU.Length >= MAX_PATH)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
DstPathU.Length *= sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (0 == RtlCompareUnicodeString(&SrcPathU, &DstPathU, TRUE))
|
||||||
|
{
|
||||||
|
/* Source and destination file are the same, nothing to do */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = CopyFileExW (lpExistingFileName,
|
||||||
|
lpNewFileName,
|
||||||
|
lpProgressRoutine,
|
||||||
|
lpData,
|
||||||
|
NULL,
|
||||||
|
FileRename->ReplaceIfExists ? 0 : COPY_FILE_FAIL_IF_EXISTS);
|
||||||
|
if (Result)
|
||||||
|
{
|
||||||
|
/* Cleanup the source file */
|
||||||
|
AdjustFileAttributes(lpExistingFileName, lpNewFileName);
|
||||||
|
Result = DeleteFileW (lpExistingFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetLastErrorByStatus (errCode);
|
SetLastErrorByStatus (errCode);
|
||||||
Result = FALSE;
|
Result = FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue