Improved file attribute and file time handling

svn path=/trunk/; revision=3902
This commit is contained in:
Gé van Geldorp 2002-12-27 23:50:21 +00:00
parent d2d897b1c4
commit 133a166af6
10 changed files with 615 additions and 152 deletions

View file

@ -1,4 +1,4 @@
/* $Id: finfo.c,v 1.22 2002/11/11 21:49:18 hbirr Exp $
/* $Id: finfo.c,v 1.23 2002/12/27 23:50:20 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -85,6 +85,45 @@ VfatGetPositionInformation(PFILE_OBJECT FileObject,
return(STATUS_SUCCESS);
}
static NTSTATUS
VfatSetBasicInformation(PFILE_OBJECT FileObject,
PVFATFCB FCB,
PDEVICE_EXTENSION DeviceExt,
PFILE_BASIC_INFORMATION BasicInfo)
{
DPRINT("VfatSetBasicInformation()\n");
assert (NULL != FileObject);
assert (NULL != FCB);
assert (NULL != DeviceExt);
assert (NULL != BasicInfo);
/* Check volume label bit */
assert(0 == (FCB->entry.Attrib & 0x08));
FsdFileTimeToDosDateTime(&(BasicInfo->CreationTime),
&(FCB->entry.CreationDate),
&(FCB->entry.CreationTime));
FsdFileTimeToDosDateTime(&(BasicInfo->LastAccessTime),
&(FCB->entry.AccessDate),
NULL);
FsdFileTimeToDosDateTime(&(BasicInfo->LastWriteTime),
&(FCB->entry.UpdateDate),
&(FCB->entry.UpdateTime));
FCB->entry.Attrib = (FCB->entry.Attrib &
(FILE_ATTRIBUTE_DIRECTORY | 0x48)) |
(BasicInfo->FileAttributes &
(FILE_ATTRIBUTE_ARCHIVE |
FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_READONLY));
DPRINT("Setting attributes 0x%02x\n", FCB->entry.Attrib);
VfatUpdateEntry(DeviceExt, FileObject);
return(STATUS_SUCCESS);
}
static NTSTATUS
VfatGetBasicInformation(PFILE_OBJECT FileObject,
PVFATFCB FCB,
@ -109,7 +148,16 @@ VfatGetBasicInformation(PFILE_OBJECT FileObject,
BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
BasicInfo->FileAttributes = FCB->entry.Attrib;
DPRINT("Getting attributes %x\n", BasicInfo->FileAttributes);
/* Synthesize FILE_ATTRIBUTE_NORMAL */
if (0 == (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
FILE_ATTRIBUTE_ARCHIVE |
FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_READONLY)))
{
BasicInfo->FileAttributes |= FILE_ATTRIBUTE_NORMAL;
}
DPRINT("Getting attributes 0x%02x\n", BasicInfo->FileAttributes);
*BufferLength -= sizeof(FILE_BASIC_INFORMATION);
return(STATUS_SUCCESS);
@ -618,6 +666,11 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
(PLARGE_INTEGER)SystemBuffer);
break;
case FileBasicInformation:
RC = VfatSetBasicInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceExt,
SystemBuffer);
break;
case FileRenameInformation:
RC = STATUS_NOT_IMPLEMENTED;
break;

View file

@ -638,6 +638,17 @@ CopyFileA(
WINBOOL bFailIfExists
);
WINBOOL
STDCALL
CopyFileExA(
LPCSTR lpExistingFileName,
LPCSTR lpNewFileName,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
LPBOOL pbCancel,
DWORD dwCopyFlags
);
WINBOOL
STDCALL
MoveFileA(
@ -653,6 +664,16 @@ MoveFileExA(
DWORD dwFlags
);
WINBOOL
STDCALL
MoveFileWithProgressA(
LPCSTR lpExistingFileName,
LPCSTR lpNewFileName,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
DWORD dwFlags
);
HANDLE
STDCALL
CreateNamedPipeA(

View file

@ -4483,6 +4483,21 @@ extern "C" {
#define TMPF_TRUETYPE (0x4)
#define TMPF_DEVICE (0x8)
/* CopyFileEx options */
#define COPY_FILE_FAIL_IF_EXISTS (1)
/* CopyProgressRoutine callback */
#define CALLBACK_CHUNK_FINISHED (0)
#define CALLBACK_STREAM_SWITCH (1)
#define PROGRESS_CONTINUE (0)
#define PROGRESS_CANCEL (1)
#define PROGRESS_STOP (2)
#define PROGRESS_QUIET (3)
/* GetFileAttributes */
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
/* --------------------- old stuff, need to organize! --------------- */
/* BEGINNING of windowsx.h stuff from old headers: */

View file

@ -37,6 +37,19 @@
extern "C" {
#endif /* __cplusplus */
typedef
DWORD (CALLBACK *PPROGRESS_ROUTINE)(
LARGE_INTEGER TotalFileSize,
LARGE_INTEGER TotalBytesTransferred,
LARGE_INTEGER StreamSize,
LARGE_INTEGER StreamBytesTransferred,
DWORD StreamNumber,
DWORD CallbackReason,
HANDLE SourceFile,
HANDLE DestinationFile,
LPVOID UserData);
typedef PPROGRESS_ROUTINE LPPROGRESS_ROUTINE;
/* These functions were a real pain, having to figure out which
had Unicode/Ascii versions and which did not */
@ -341,8 +354,10 @@ extern "C" {
#define FindNextFile FindNextFileW
#define SearchPath SearchPathW
#define CopyFile CopyFileW
#define CopyFileEx CopyFileExW
#define MoveFile MoveFileW
#define MoveFileEx MoveFileExW
#define MoveFileWithProgress MoveFileWithProgressW
#define CreateNamedPipe CreateNamedPipeW
#define GetNamedPipeHandleState GetNamedPipeHandleStateW
#define CallNamedPipe CallNamedPipeW
@ -745,8 +760,10 @@ extern "C" {
#define FindNextFile FindNextFileA
#define SearchPath SearchPathA
#define CopyFile CopyFileA
#define CopyFileEx CopyFileExA
#define MoveFile MoveFileA
#define MoveFileEx MoveFileExA
#define MoveFileWithProgress MoveFileWithProgressA
#define CreateNamedPipe CreateNamedPipeA
#define GetNamedPipeHandleState GetNamedPipeHandleStateA
#define CallNamedPipe CallNamedPipeA

View file

@ -639,6 +639,17 @@ CopyFileW(
WINBOOL bFailIfExists
);
WINBOOL
STDCALL
CopyFileExW(
LPCWSTR lpExistingFileName,
LPCWSTR lpNewFileName,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
LPBOOL pbCancel,
DWORD dwCopyFlags
);
WINBOOL
STDCALL
MoveFileW(
@ -654,6 +665,16 @@ MoveFileExW(
DWORD dwFlags
);
WINBOOL
STDCALL
MoveFileWithProgressW(
LPCWSTR lpExistingFileName,
LPCWSTR lpNewFileName,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
DWORD dwFlags
);
HANDLE
STDCALL
CreateNamedPipeW(

View file

@ -1,4 +1,4 @@
/* $Id: copy.c,v 1.11 2002/09/08 10:22:41 chorns Exp $
/* $Id: copy.c,v 1.12 2002/12/27 23:50:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -20,11 +20,178 @@
#include <kernel32/error.h>
#define LPPROGRESS_ROUTINE void*
/* FUNCTIONS ****************************************************************/
static NTSTATUS
CopyLoop (
HANDLE FileHandleSource,
HANDLE FileHandleDest,
LARGE_INTEGER SourceFileSize,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
WINBOOL *pbCancel,
WINBOOL *KeepDest
)
{
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
UCHAR *lpBuffer = NULL;
ULONG RegionSize = 0x10000;
LARGE_INTEGER BytesCopied;
DWORD CallbackReason;
DWORD ProgressResult;
WINBOOL EndOfFileFound;
*KeepDest = FALSE;
errCode = NtAllocateVirtualMemory(NtCurrentProcess(),
(PVOID *)&lpBuffer,
2,
&RegionSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (NT_SUCCESS(errCode))
{
BytesCopied.QuadPart = 0;
EndOfFileFound = FALSE;
CallbackReason = CALLBACK_STREAM_SWITCH;
while (! EndOfFileFound &&
NT_SUCCESS(errCode) &&
(NULL == pbCancel || ! *pbCancel))
{
if (NULL != lpProgressRoutine)
{
ProgressResult = (*lpProgressRoutine)(SourceFileSize,
BytesCopied,
SourceFileSize,
BytesCopied,
0,
CallbackReason,
FileHandleSource,
FileHandleDest,
lpData);
switch (ProgressResult)
{
case PROGRESS_CANCEL:
DPRINT("Progress callback requested cancel\n");
errCode = STATUS_REQUEST_ABORTED;
break;
case PROGRESS_STOP:
DPRINT("Progress callback requested stop\n");
errCode = STATUS_REQUEST_ABORTED;
*KeepDest = TRUE;
break;
case PROGRESS_QUIET:
lpProgressRoutine = NULL;
break;
case PROGRESS_CONTINUE:
default:
break;
}
CallbackReason = CALLBACK_CHUNK_FINISHED;
}
if (NT_SUCCESS(errCode))
{
errCode = NtReadFile(FileHandleSource,
NULL,
NULL,
NULL,
(PIO_STATUS_BLOCK)&IoStatusBlock,
lpBuffer,
RegionSize,
NULL,
NULL);
if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel))
{
errCode = NtWriteFile(FileHandleDest,
NULL,
NULL,
NULL,
(PIO_STATUS_BLOCK)&IoStatusBlock,
lpBuffer,
IoStatusBlock.Information,
NULL,
NULL);
if (NT_SUCCESS(errCode))
{
BytesCopied.QuadPart += IoStatusBlock.Information;
}
else
{
DPRINT("Error 0x%08x reading writing to dest\n", errCode);
}
}
else if (!NT_SUCCESS(errCode))
{
if (STATUS_END_OF_FILE == errCode)
{
EndOfFileFound = TRUE;
errCode = STATUS_SUCCESS;
}
else
{
DPRINT("Error 0x%08x reading from source\n", errCode);
}
}
}
}
if (! EndOfFileFound && (NULL != pbCancel && *pbCancel))
{
DPRINT("User requested cancel\n");
errCode = STATUS_REQUEST_ABORTED;
}
NtFreeVirtualMemory(NtCurrentProcess(),
(PVOID *)&lpBuffer,
&RegionSize,
MEM_RELEASE);
}
else
{
DPRINT("Error 0x%08x allocating buffer of %d bytes\n", errCode, RegionSize);
}
return errCode;
}
static NTSTATUS
SetLastWriteTime(
HANDLE FileHandle,
TIME LastWriteTime
)
{
NTSTATUS errCode = STATUS_SUCCESS;
IO_STATUS_BLOCK IoStatusBlock;
FILE_BASIC_INFORMATION FileBasic;
errCode = NtQueryInformationFile (FileHandle,
&IoStatusBlock,
&FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (!NT_SUCCESS(errCode))
{
DPRINT("Error 0x%08x obtaining FileBasicInformation\n", errCode);
}
else
{
FileBasic.LastWriteTime = LastWriteTime;
errCode = NtSetInformationFile (FileHandle,
&IoStatusBlock,
&FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (!NT_SUCCESS(errCode))
{
DPRINT("Error 0x%0x setting LastWriteTime\n", errCode);
}
}
return errCode;
}
WINBOOL
STDCALL
CopyFileExW (
@ -36,15 +203,15 @@ CopyFileExW (
DWORD dwCopyFlags
)
{
NTSTATUS errCode = 0;
NTSTATUS errCode;
HANDLE FileHandleSource, FileHandleDest;
IO_STATUS_BLOCK IoStatusBlock;
FILE_STANDARD_INFORMATION FileStandard;
FILE_BASIC_INFORMATION FileBasic;
FILE_POSITION_INFORMATION FilePosition;
UCHAR *lpBuffer = NULL;
ULONG RegionSize = 0x1000000;
BOOL bCancel = FALSE;
FILE_DISPOSITION_INFORMATION FileDispInfo;
WINBOOL RC = FALSE;
WINBOOL KeepDestOnError = FALSE;
DWORD SystemError;
FileHandleSource = CreateFileW(lpExistingFileName,
GENERIC_READ,
@ -53,137 +220,87 @@ CopyFileExW (
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
NULL);
if (FileHandleSource == NULL)
{
return(FALSE);
}
errCode = NtQueryInformationFile(FileHandleSource,
&IoStatusBlock,
&FileStandard,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
if (!NT_SUCCESS(errCode))
if (INVALID_HANDLE_VALUE != FileHandleSource)
{
errCode = NtQueryInformationFile(FileHandleSource,
&IoStatusBlock,
&FileStandard,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
if (!NT_SUCCESS(errCode))
{
DPRINT("Status 0x%08x obtaining FileStandardInformation for source\n", errCode);
SetLastErrorByStatus(errCode);
}
else
{
errCode = NtQueryInformationFile(FileHandleSource,
&IoStatusBlock,&FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (!NT_SUCCESS(errCode))
{
DPRINT("Status 0x%08x obtaining FileBasicInformation for source\n", errCode);
SetLastErrorByStatus(errCode);
}
else
{
FileHandleDest = CreateFileW(lpNewFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS,
FileBasic.FileAttributes,
NULL);
if (INVALID_HANDLE_VALUE != FileHandleDest)
{
errCode = CopyLoop(FileHandleSource,
FileHandleDest,
FileStandard.EndOfFile,
lpProgressRoutine,
lpData,
pbCancel,
&KeepDestOnError);
if (!NT_SUCCESS(errCode))
{
SetLastErrorByStatus(errCode);
}
else
{
errCode = SetLastWriteTime(FileHandleDest,
FileBasic.LastWriteTime);
if (!NT_SUCCESS(errCode))
{
SetLastErrorByStatus(errCode);
}
else
{
RC = TRUE;
}
}
NtClose(FileHandleDest);
if (! RC && ! KeepDestOnError)
{
SystemError = GetLastError();
SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL);
DeleteFileW(lpNewFileName);
SetLastError(SystemError);
}
}
else
{
DPRINT("Error %d during opening of dest file\n", GetLastError());
}
}
}
NtClose(FileHandleSource);
SetLastErrorByStatus(errCode);
return FALSE;
}
errCode = NtQueryInformationFile(FileHandleSource,
&IoStatusBlock,&FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (!NT_SUCCESS(errCode))
else
{
NtClose(FileHandleSource);
SetLastErrorByStatus(errCode);
return FALSE;
DPRINT("Error %d during opening of source file\n", GetLastError());
}
FileHandleDest = CreateFileW(lpNewFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS,
FileBasic.FileAttributes|FILE_FLAG_NO_BUFFERING,
NULL);
if (FileHandleDest == NULL)
{
return(FALSE);
}
FilePosition.CurrentByteOffset.QuadPart = 0;
errCode = NtSetInformationFile(FileHandleSource,
&IoStatusBlock,
&FilePosition,
sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation);
if (!NT_SUCCESS(errCode))
{
NtClose(FileHandleSource);
NtClose(FileHandleDest);
SetLastErrorByStatus(errCode);
return FALSE;
}
errCode = NtSetInformationFile(FileHandleDest,
&IoStatusBlock,
&FilePosition,
sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation);
if (!NT_SUCCESS(errCode))
{
NtClose(FileHandleSource);
NtClose(FileHandleDest);
SetLastErrorByStatus(errCode);
return FALSE;
}
errCode = NtAllocateVirtualMemory(NtCurrentProcess(),
(PVOID *)&lpBuffer,
2,
&RegionSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(errCode))
{
NtClose(FileHandleSource);
NtClose(FileHandleDest);
SetLastErrorByStatus(errCode);
return FALSE;
}
do {
errCode = NtReadFile(FileHandleSource,
NULL,
NULL,
NULL,
(PIO_STATUS_BLOCK)&IoStatusBlock,
lpBuffer,
RegionSize,
NULL,
NULL);
if (pbCancel != NULL)
bCancel = *pbCancel;
if (!NT_SUCCESS(errCode) || bCancel)
{
NtFreeVirtualMemory(NtCurrentProcess(),
(PVOID *)&lpBuffer, &RegionSize,MEM_RELEASE);
NtClose(FileHandleSource);
NtClose(FileHandleDest);
if ( errCode == STATUS_END_OF_FILE )
break;
else
return FALSE;
}
errCode = NtWriteFile(FileHandleDest,
NULL,
lpProgressRoutine,
lpData,
(PIO_STATUS_BLOCK)&IoStatusBlock,
lpBuffer,
IoStatusBlock.Information,
NULL,
NULL);
if (!NT_SUCCESS(errCode))
{
NtFreeVirtualMemory(NtCurrentProcess(),
(PVOID *)&lpBuffer,
&RegionSize,
MEM_RELEASE);
NtClose(FileHandleSource);
NtClose(FileHandleDest);
return FALSE;
}
} while ( TRUE );
return TRUE;
return RC;
}

View file

@ -1,4 +1,4 @@
/* $Id: file.c,v 1.38 2002/11/07 02:52:37 robd Exp $
/* $Id: file.c,v 1.39 2002/12/27 23:50:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -21,8 +21,6 @@
#include <kernel32/kernel32.h>
#include <kernel32/error.h>
#define LPPROGRESS_ROUTINE void*
/* GLOBALS ******************************************************************/
@ -607,6 +605,11 @@ SetFileAttributesW(LPCWSTR lpFileName,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
DPRINT("SetFileAttributes CreateFileW failed with code %d\n", GetLastError());
return FALSE;
}
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
@ -616,6 +619,7 @@ SetFileAttributesW(LPCWSTR lpFileName,
if (!NT_SUCCESS(errCode))
{
CloseHandle(hFile);
DPRINT("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", errCode);
SetLastErrorByStatus(errCode);
return FALSE;
}
@ -628,6 +632,7 @@ SetFileAttributesW(LPCWSTR lpFileName,
if (!NT_SUCCESS(errCode))
{
CloseHandle(hFile);
DPRINT("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", errCode);
SetLastErrorByStatus(errCode);
return FALSE;
}

View file

@ -1,4 +1,4 @@
/* $Id: move.c,v 1.7 2002/09/08 10:22:42 chorns Exp $
/* $Id: move.c,v 1.8 2002/12/27 23:50:21 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -17,6 +17,7 @@
#define NDEBUG
#include <kernel32/kernel32.h>
#include <kernel32/error.h>
#define FILE_RENAME_SIZE MAX_PATH +sizeof(FILE_RENAME_INFORMATION)
@ -44,6 +45,24 @@ MoveFileExA (
LPCSTR lpNewFileName,
DWORD dwFlags
)
{
return MoveFileWithProgressA (lpExistingFileName,
lpNewFileName,
NULL,
NULL,
dwFlags);
}
WINBOOL
STDCALL
MoveFileWithProgressA (
LPCSTR lpExistingFileName,
LPCSTR lpNewFileName,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
DWORD dwFlags
)
{
UNICODE_STRING ExistingFileNameU;
UNICODE_STRING NewFileNameU;
@ -77,9 +96,11 @@ MoveFileExA (
TRUE);
}
Result = MoveFileExW (ExistingFileNameU.Buffer,
NewFileNameU.Buffer,
dwFlags);
Result = MoveFileWithProgressW (ExistingFileNameU.Buffer,
NewFileNameU.Buffer,
lpProgressRoutine,
lpData,
dwFlags);
RtlFreeHeap (RtlGetProcessHeap (),
0,
@ -112,12 +133,159 @@ MoveFileExW (
LPCWSTR lpNewFileName,
DWORD dwFlags
)
{
return MoveFileWithProgressW (lpExistingFileName,
lpNewFileName,
NULL,
NULL,
dwFlags);
}
static WINBOOL
AdjustFileAttributes (
LPCWSTR ExistingFileName,
LPCWSTR NewFileName
)
{
IO_STATUS_BLOCK IoStatusBlock;
FILE_BASIC_INFORMATION ExistingInfo,
NewInfo;
HANDLE hFile;
DWORD Attributes;
NTSTATUS errCode;
WINBOOL Result = FALSE;
hFile = CreateFileW (ExistingFileName,
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
errCode = NtQueryInformationFile (hFile,
&IoStatusBlock,
&ExistingInfo,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (NT_SUCCESS (errCode))
{
if (0 != (ExistingInfo.FileAttributes & FILE_ATTRIBUTE_READONLY))
{
Attributes = ExistingInfo.FileAttributes;
ExistingInfo.FileAttributes &= ~ FILE_ATTRIBUTE_READONLY;
if (0 == (ExistingInfo.FileAttributes &
(FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_ARCHIVE)))
{
ExistingInfo.FileAttributes |= FILE_ATTRIBUTE_NORMAL;
}
errCode = NtSetInformationFile (hFile,
&IoStatusBlock,
&ExistingInfo,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (!NT_SUCCESS(errCode))
{
DPRINT("Removing READONLY attribute from source failed with status 0x%08x\n", errCode);
}
ExistingInfo.FileAttributes = Attributes;
}
CloseHandle(hFile);
if (NT_SUCCESS(errCode))
{
hFile = CreateFileW (NewFileName,
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
&NewInfo,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (NT_SUCCESS(errCode))
{
NewInfo.FileAttributes = (NewInfo.FileAttributes &
~ (FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_READONLY |
FILE_ATTRIBUTE_NORMAL)) |
(ExistingInfo.FileAttributes &
(FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_READONLY |
FILE_ATTRIBUTE_NORMAL)) |
FILE_ATTRIBUTE_ARCHIVE;
NewInfo.CreationTime = ExistingInfo.CreationTime;
NewInfo.LastAccessTime = ExistingInfo.LastAccessTime;
NewInfo.LastWriteTime = ExistingInfo.LastWriteTime;
errCode = NtSetInformationFile (hFile,
&IoStatusBlock,
&NewInfo,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
if (NT_SUCCESS(errCode))
{
Result = TRUE;
}
else
{
DPRINT("Setting attributes on dest file failed with status 0x%08x\n", errCode);
}
}
else
{
DPRINT("Obtaining attributes from dest file failed with status 0x%08x\n", errCode);
}
CloseHandle(hFile);
}
else
{
DPRINT("Opening dest file to set attributes failed with code %d\n", GetLastError());
}
}
}
else
{
DPRINT("Obtaining attributes from source file failed with status 0x%08x\n", errCode);
CloseHandle(hFile);
}
}
else
{
DPRINT("Opening source file to obtain attributes failed with code %d\n", GetLastError());
}
return Result;
}
WINBOOL
STDCALL
MoveFileWithProgressW (
LPCWSTR lpExistingFileName,
LPCWSTR lpNewFileName,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
DWORD dwFlags
)
{
HANDLE hFile = NULL;
IO_STATUS_BLOCK IoStatusBlock;
FILE_RENAME_INFORMATION *FileRename;
USHORT Buffer[FILE_RENAME_SIZE];
NTSTATUS errCode;
NTSTATUS errCode;
DWORD err;
WINBOOL Result;
hFile = CreateFileW (lpExistingFileName,
GENERIC_ALL,
@ -137,21 +305,63 @@ MoveFileExW (
memcpy (FileRename->FileName,
lpNewFileName,
min(FileRename->FileNameLength, MAX_PATH));
errCode = NtSetInformationFile (hFile,
&IoStatusBlock,
FileRename,
FILE_RENAME_SIZE,
FileRenameInformation);
CloseHandle(hFile);
if (!NT_SUCCESS(errCode))
if (NT_SUCCESS(errCode))
{
if (CopyFileW (lpExistingFileName,
lpNewFileName,
FileRename->Replace))
DeleteFileW (lpExistingFileName);
Result = TRUE;
}
return 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 &&
MOVEFILE_COPY_ALLOWED == (dwFlags & MOVEFILE_COPY_ALLOWED))
#else
else
#endif
{
Result = CopyFileExW (lpExistingFileName,
lpNewFileName,
lpProgressRoutine,
lpData,
NULL,
FileRename->Replace ? 0 : COPY_FILE_FAIL_IF_EXISTS) &&
AdjustFileAttributes(lpExistingFileName, lpNewFileName) &&
DeleteFileW (lpExistingFileName);
if (! Result)
{
/* Delete of the existing file failed so the
* existing file is still there. Clean up the
* new file (if possible)
*/
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 0
else
{
SetLastErrorByStatus (errCode);
Result = FALSE;
}
#endif
return Result;
}
/* EOF */

View file

@ -449,8 +449,10 @@ MapViewOfFile@20
MapViewOfFileEx@24
MoveFileA@8
MoveFileExA@12
MoveFileWithProgressA@20
MoveFileExW@12
MoveFileW@8
MoveFileWithProgressW@20
MulDiv@12
MultiByteToWideChar@24
OpenConsoleW@16

View file

@ -1,4 +1,4 @@
; $Id: kernel32.edf,v 1.16 2002/11/12 00:46:02 mdill Exp $
; $Id: kernel32.edf,v 1.17 2002/12/27 23:50:20 gvg Exp $
;
; kernel32.edf
;
@ -453,8 +453,10 @@ MapViewOfFile=MapViewOfFile@20
MapViewOfFileEx=MapViewOfFileEx@24
MoveFileA=MoveFileA@8
MoveFileExA=MoveFileExA@12
MoveFileWithProgressA=MoveFileWithProgressA@20
MoveFileExW=MoveFileExW@12
MoveFileW=MoveFileW@8
MoveFileWithProgressW=MoveFileWithProgressW@20
MulDiv=MulDiv@12
MultiByteToWideChar=MultiByteToWideChar@24
OpenConsoleW=OpenConsoleW@16