2005-08-24 18:29:45 +00:00
|
|
|
/*
|
2022-09-24 13:24:08 +00:00
|
|
|
* PROJECT: VFAT Filesystem
|
|
|
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
|
|
|
* PURPOSE: File information routines
|
|
|
|
* COPYRIGHT: Copyright 1998 Jason Filby <jasonfilby@yahoo.com>
|
|
|
|
* Copyright 2005 Hervé Poussineau <hpoussin@reactos.org>
|
|
|
|
* Copyright 2008-2018 Pierre Schweitzer <pierre@reactos.org>
|
1999-12-11 21:14:49 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
|
|
|
#include "vfat.h"
|
|
|
|
|
2013-12-19 16:20:28 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2014-10-28 20:39:42 +00:00
|
|
|
#define NASSERTS_RENAME
|
|
|
|
|
2005-01-25 21:10:42 +00:00
|
|
|
/* GLOBALS ******************************************************************/
|
|
|
|
|
2005-05-08 02:16:32 +00:00
|
|
|
const char* FileInformationClassNames[] =
|
2005-01-25 21:10:42 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
"??????",
|
|
|
|
"FileDirectoryInformation",
|
|
|
|
"FileFullDirectoryInformation",
|
|
|
|
"FileBothDirectoryInformation",
|
|
|
|
"FileBasicInformation",
|
|
|
|
"FileStandardInformation",
|
|
|
|
"FileInternalInformation",
|
|
|
|
"FileEaInformation",
|
|
|
|
"FileAccessInformation",
|
|
|
|
"FileNameInformation",
|
|
|
|
"FileRenameInformation",
|
|
|
|
"FileLinkInformation",
|
|
|
|
"FileNamesInformation",
|
|
|
|
"FileDispositionInformation",
|
|
|
|
"FilePositionInformation",
|
|
|
|
"FileFullEaInformation",
|
|
|
|
"FileModeInformation",
|
|
|
|
"FileAlignmentInformation",
|
|
|
|
"FileAllInformation",
|
|
|
|
"FileAllocationInformation",
|
|
|
|
"FileEndOfFileInformation",
|
|
|
|
"FileAlternateNameInformation",
|
|
|
|
"FileStreamInformation",
|
|
|
|
"FilePipeInformation",
|
|
|
|
"FilePipeLocalInformation",
|
|
|
|
"FilePipeRemoteInformation",
|
|
|
|
"FileMailslotQueryInformation",
|
|
|
|
"FileMailslotSetInformation",
|
|
|
|
"FileCompressionInformation",
|
|
|
|
"FileObjectIdInformation",
|
|
|
|
"FileCompletionInformation",
|
|
|
|
"FileMoveClusterInformation",
|
|
|
|
"FileQuotaInformation",
|
|
|
|
"FileReparsePointInformation",
|
|
|
|
"FileNetworkOpenInformation",
|
|
|
|
"FileAttributeTagInformation",
|
|
|
|
"FileTrackingInformation",
|
|
|
|
"FileIdBothDirectoryInformation",
|
|
|
|
"FileIdFullDirectoryInformation",
|
|
|
|
"FileValidDataLengthInformation",
|
|
|
|
"FileShortNameInformation",
|
|
|
|
"FileMaximumInformation"
|
2005-01-25 21:10:42 +00:00
|
|
|
};
|
|
|
|
|
1999-12-11 21:14:49 +00:00
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the standard file information
|
|
|
|
*/
|
2013-12-09 10:35:15 +00:00
|
|
|
NTSTATUS
|
|
|
|
VfatGetStandardInformation(
|
|
|
|
PVFATFCB FCB,
|
|
|
|
PFILE_STANDARD_INFORMATION StandardInfo,
|
|
|
|
PULONG BufferLength)
|
1999-12-11 21:14:49 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* PRECONDITION */
|
|
|
|
ASSERT(StandardInfo != NULL);
|
|
|
|
ASSERT(FCB != NULL);
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
if (vfatFCBIsDirectory(FCB))
|
2004-05-23 13:34:32 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
StandardInfo->AllocationSize.QuadPart = 0;
|
|
|
|
StandardInfo->EndOfFile.QuadPart = 0;
|
|
|
|
StandardInfo->Directory = TRUE;
|
2004-05-23 13:34:32 +00:00
|
|
|
}
|
2013-12-09 10:35:15 +00:00
|
|
|
else
|
2004-05-23 13:34:32 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
StandardInfo->AllocationSize = FCB->RFCB.AllocationSize;
|
|
|
|
StandardInfo->EndOfFile = FCB->RFCB.FileSize;
|
|
|
|
StandardInfo->Directory = FALSE;
|
2004-05-23 13:34:32 +00:00
|
|
|
}
|
2013-12-09 10:35:15 +00:00
|
|
|
StandardInfo->NumberOfLinks = 1;
|
2017-02-17 11:38:05 +00:00
|
|
|
StandardInfo->DeletePending = BooleanFlagOn(FCB->Flags, FCB_DELETE_PENDING);
|
2001-11-01 10:44:11 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
*BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
|
|
|
|
return STATUS_SUCCESS;
|
1999-12-11 21:14:49 +00:00
|
|
|
}
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatSetPositionInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PFILE_POSITION_INFORMATION PositionInfo)
|
1999-12-11 21:14:49 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
DPRINT("FsdSetPositionInformation()\n");
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
DPRINT("PositionInfo %p\n", PositionInfo);
|
|
|
|
DPRINT("Setting position %u\n", PositionInfo->CurrentByteOffset.u.LowPart);
|
2004-11-06 13:44:57 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
FileObject->CurrentByteOffset.QuadPart =
|
|
|
|
PositionInfo->CurrentByteOffset.QuadPart;
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-12-29 23:17:12 +00:00
|
|
|
}
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatGetPositionInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
PFILE_POSITION_INFORMATION PositionInfo,
|
|
|
|
PULONG BufferLength)
|
2000-12-29 23:17:12 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
UNREFERENCED_PARAMETER(FileObject);
|
|
|
|
UNREFERENCED_PARAMETER(FCB);
|
2017-06-26 18:10:43 +00:00
|
|
|
UNREFERENCED_PARAMETER(DeviceExt);
|
2009-06-19 00:21:21 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
DPRINT("VfatGetPositionInformation()\n");
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
2001-06-12 12:35:42 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
PositionInfo->CurrentByteOffset.QuadPart =
|
|
|
|
FileObject->CurrentByteOffset.QuadPart;
|
2001-06-12 12:35:42 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
DPRINT("Getting position %I64x\n",
|
|
|
|
PositionInfo->CurrentByteOffset.QuadPart);
|
2001-06-12 12:35:42 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
*BufferLength -= sizeof(FILE_POSITION_INFORMATION);
|
|
|
|
return STATUS_SUCCESS;
|
1999-12-11 21:14:49 +00:00
|
|
|
}
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatSetBasicInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB FCB,
|
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
|
|
|
PFILE_BASIC_INFORMATION BasicInfo)
|
2002-12-27 23:50:21 +00:00
|
|
|
{
|
2017-09-21 09:47:13 +00:00
|
|
|
ULONG NotifyFilter;
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
DPRINT("VfatSetBasicInformation()\n");
|
2002-12-27 23:50:21 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
ASSERT(NULL != FileObject);
|
|
|
|
ASSERT(NULL != FCB);
|
|
|
|
ASSERT(NULL != DeviceExt);
|
|
|
|
ASSERT(NULL != BasicInfo);
|
|
|
|
/* Check volume label bit */
|
|
|
|
ASSERT(0 == (*FCB->Attributes & _A_VOLID));
|
|
|
|
|
2017-09-21 09:47:13 +00:00
|
|
|
NotifyFilter = 0;
|
|
|
|
|
2017-09-21 09:45:23 +00:00
|
|
|
if (BasicInfo->FileAttributes != 0)
|
|
|
|
{
|
|
|
|
UCHAR Attributes;
|
|
|
|
|
|
|
|
Attributes = (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_ARCHIVE |
|
|
|
|
FILE_ATTRIBUTE_SYSTEM |
|
|
|
|
FILE_ATTRIBUTE_HIDDEN |
|
|
|
|
FILE_ATTRIBUTE_DIRECTORY |
|
|
|
|
FILE_ATTRIBUTE_READONLY));
|
|
|
|
|
|
|
|
if (vfatFCBIsDirectory(FCB))
|
|
|
|
{
|
2017-09-21 10:33:23 +00:00
|
|
|
if (BooleanFlagOn(BasicInfo->FileAttributes, FILE_ATTRIBUTE_TEMPORARY))
|
|
|
|
{
|
|
|
|
DPRINT("Setting temporary attribute on a directory!\n");
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2017-09-21 09:45:23 +00:00
|
|
|
Attributes |= FILE_ATTRIBUTE_DIRECTORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (BooleanFlagOn(BasicInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
|
|
|
|
{
|
|
|
|
DPRINT("Setting directory attribute on a file!\n");
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Attributes != *FCB->Attributes)
|
|
|
|
{
|
|
|
|
*FCB->Attributes = Attributes;
|
|
|
|
DPRINT("Setting attributes 0x%02x\n", *FCB->Attributes);
|
2017-09-21 09:47:13 +00:00
|
|
|
NotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
|
2017-09-21 09:45:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-17 21:24:12 +00:00
|
|
|
if (vfatVolumeIsFatX(DeviceExt))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
if (BasicInfo->CreationTime.QuadPart != 0 && BasicInfo->CreationTime.QuadPart != -1)
|
|
|
|
{
|
|
|
|
FsdSystemTimeToDosDateTime(DeviceExt,
|
|
|
|
&BasicInfo->CreationTime,
|
|
|
|
&FCB->entry.FatX.CreationDate,
|
|
|
|
&FCB->entry.FatX.CreationTime);
|
2017-09-21 09:47:13 +00:00
|
|
|
NotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (BasicInfo->LastAccessTime.QuadPart != 0 && BasicInfo->LastAccessTime.QuadPart != -1)
|
|
|
|
{
|
|
|
|
FsdSystemTimeToDosDateTime(DeviceExt,
|
|
|
|
&BasicInfo->LastAccessTime,
|
|
|
|
&FCB->entry.FatX.AccessDate,
|
|
|
|
&FCB->entry.FatX.AccessTime);
|
2017-09-21 09:47:13 +00:00
|
|
|
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (BasicInfo->LastWriteTime.QuadPart != 0 && BasicInfo->LastWriteTime.QuadPart != -1)
|
|
|
|
{
|
|
|
|
FsdSystemTimeToDosDateTime(DeviceExt,
|
|
|
|
&BasicInfo->LastWriteTime,
|
|
|
|
&FCB->entry.FatX.UpdateDate,
|
|
|
|
&FCB->entry.FatX.UpdateTime);
|
2017-09-21 09:47:13 +00:00
|
|
|
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (BasicInfo->CreationTime.QuadPart != 0 && BasicInfo->CreationTime.QuadPart != -1)
|
|
|
|
{
|
|
|
|
FsdSystemTimeToDosDateTime(DeviceExt,
|
|
|
|
&BasicInfo->CreationTime,
|
|
|
|
&FCB->entry.Fat.CreationDate,
|
|
|
|
&FCB->entry.Fat.CreationTime);
|
2017-09-21 09:47:13 +00:00
|
|
|
NotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
2004-11-06 13:44:57 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
if (BasicInfo->LastAccessTime.QuadPart != 0 && BasicInfo->LastAccessTime.QuadPart != -1)
|
|
|
|
{
|
|
|
|
FsdSystemTimeToDosDateTime(DeviceExt,
|
|
|
|
&BasicInfo->LastAccessTime,
|
|
|
|
&FCB->entry.Fat.AccessDate,
|
|
|
|
NULL);
|
2017-09-21 09:47:13 +00:00
|
|
|
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (BasicInfo->LastWriteTime.QuadPart != 0 && BasicInfo->LastWriteTime.QuadPart != -1)
|
|
|
|
{
|
|
|
|
FsdSystemTimeToDosDateTime(DeviceExt,
|
|
|
|
&BasicInfo->LastWriteTime,
|
|
|
|
&FCB->entry.Fat.UpdateDate,
|
|
|
|
&FCB->entry.Fat.UpdateTime);
|
2017-09-21 09:47:13 +00:00
|
|
|
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-18 12:03:20 +00:00
|
|
|
VfatUpdateEntry(DeviceExt, FCB);
|
2013-12-09 10:35:15 +00:00
|
|
|
|
2017-09-21 09:47:13 +00:00
|
|
|
if (NotifyFilter != 0)
|
|
|
|
{
|
2018-01-07 13:16:11 +00:00
|
|
|
vfatReportChange(DeviceExt,
|
|
|
|
FCB,
|
|
|
|
NotifyFilter,
|
|
|
|
FILE_ACTION_MODIFIED);
|
2017-09-21 09:47:13 +00:00
|
|
|
}
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
VfatGetBasicInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
PFILE_BASIC_INFORMATION BasicInfo,
|
|
|
|
PULONG BufferLength)
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(FileObject);
|
|
|
|
|
|
|
|
DPRINT("VfatGetBasicInformation()\n");
|
|
|
|
|
|
|
|
if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
|
|
|
2020-09-11 12:47:43 +00:00
|
|
|
RtlZeroMemory(BasicInfo, sizeof(FILE_BASIC_INFORMATION));
|
|
|
|
|
2017-02-17 21:24:12 +00:00
|
|
|
if (vfatVolumeIsFatX(DeviceExt))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
FCB->entry.FatX.CreationDate,
|
|
|
|
FCB->entry.FatX.CreationTime,
|
|
|
|
&BasicInfo->CreationTime);
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
FCB->entry.FatX.AccessDate,
|
|
|
|
FCB->entry.FatX.AccessTime,
|
|
|
|
&BasicInfo->LastAccessTime);
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
FCB->entry.FatX.UpdateDate,
|
|
|
|
FCB->entry.FatX.UpdateTime,
|
|
|
|
&BasicInfo->LastWriteTime);
|
|
|
|
BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
|
|
|
|
}
|
|
|
|
else
|
2011-03-07 20:28:42 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
FCB->entry.Fat.CreationDate,
|
|
|
|
FCB->entry.Fat.CreationTime,
|
|
|
|
&BasicInfo->CreationTime);
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
FCB->entry.Fat.AccessDate,
|
|
|
|
0,
|
|
|
|
&BasicInfo->LastAccessTime);
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
FCB->entry.Fat.UpdateDate,
|
|
|
|
FCB->entry.Fat.UpdateTime,
|
|
|
|
&BasicInfo->LastWriteTime);
|
|
|
|
BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
|
2011-03-07 20:28:42 +00:00
|
|
|
}
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
BasicInfo->FileAttributes = *FCB->Attributes & 0x3f;
|
|
|
|
/* Synthesize FILE_ATTRIBUTE_NORMAL */
|
|
|
|
if (0 == (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
|
|
|
|
FILE_ATTRIBUTE_ARCHIVE |
|
|
|
|
FILE_ATTRIBUTE_SYSTEM |
|
|
|
|
FILE_ATTRIBUTE_HIDDEN |
|
|
|
|
FILE_ATTRIBUTE_READONLY)))
|
2011-03-07 20:28:42 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
DPRINT("Synthesizing FILE_ATTRIBUTE_NORMAL\n");
|
|
|
|
BasicInfo->FileAttributes |= FILE_ATTRIBUTE_NORMAL;
|
2011-03-07 20:28:42 +00:00
|
|
|
}
|
2013-12-09 10:35:15 +00:00
|
|
|
DPRINT("Getting attributes 0x%02x\n", BasicInfo->FileAttributes);
|
2011-03-07 20:28:42 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
*BufferLength -= sizeof(FILE_BASIC_INFORMATION);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatSetDispositionInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
PFILE_DISPOSITION_INFORMATION DispositionInfo)
|
|
|
|
{
|
|
|
|
DPRINT("FsdSetDispositionInformation(<%wZ>, Delete %u)\n", &FCB->PathNameU, DispositionInfo->DeleteFile);
|
|
|
|
|
|
|
|
ASSERT(DeviceExt != NULL);
|
|
|
|
ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0);
|
|
|
|
ASSERT(FCB != NULL);
|
|
|
|
|
|
|
|
if (!DispositionInfo->DeleteFile)
|
2011-03-07 20:28:42 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
/* undelete the file */
|
|
|
|
FCB->Flags &= ~FCB_DELETE_PENDING;
|
|
|
|
FileObject->DeletePending = FALSE;
|
|
|
|
return STATUS_SUCCESS;
|
2011-03-07 20:28:42 +00:00
|
|
|
}
|
2013-12-09 10:35:15 +00:00
|
|
|
|
2017-02-17 11:38:05 +00:00
|
|
|
if (BooleanFlagOn(FCB->Flags, FCB_DELETE_PENDING))
|
2011-03-07 20:28:42 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
/* stream already marked for deletion. just update the file object */
|
|
|
|
FileObject->DeletePending = TRUE;
|
|
|
|
return STATUS_SUCCESS;
|
2011-03-07 20:28:42 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 17:58:18 +00:00
|
|
|
if (vfatFCBIsReadOnly(FCB))
|
2011-03-07 20:28:42 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
return STATUS_CANNOT_DELETE;
|
2011-03-07 20:28:42 +00:00
|
|
|
}
|
|
|
|
|
2020-09-26 22:39:15 +00:00
|
|
|
if (vfatFCBIsRoot(FCB) || IsDotOrDotDot(&FCB->LongNameU))
|
2011-03-07 20:28:42 +00:00
|
|
|
{
|
2015-11-14 20:41:59 +00:00
|
|
|
/* we cannot delete a '.', '..' or the root directory */
|
2015-11-14 21:10:02 +00:00
|
|
|
return STATUS_ACCESS_DENIED;
|
2015-11-14 20:41:59 +00:00
|
|
|
}
|
2002-12-27 23:50:21 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
if (!MmFlushImageSection (FileObject->SectionObjectPointer, MmFlushForDelete))
|
|
|
|
{
|
|
|
|
/* can't delete a file if its mapped into a process */
|
2002-12-27 23:50:21 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
DPRINT("MmFlushImageSection returned FALSE\n");
|
|
|
|
return STATUS_CANNOT_DELETE;
|
|
|
|
}
|
2002-12-27 23:50:21 +00:00
|
|
|
|
2017-02-17 22:25:03 +00:00
|
|
|
if (vfatFCBIsDirectory(FCB) && !VfatIsDirectoryEmpty(DeviceExt, FCB))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
/* can't delete a non-empty directory */
|
2000-12-29 23:17:12 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
return STATUS_DIRECTORY_NOT_EMPTY;
|
|
|
|
}
|
2000-12-29 23:17:12 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* all good */
|
|
|
|
FCB->Flags |= FCB_DELETE_PENDING;
|
|
|
|
FileObject->DeletePending = TRUE;
|
2001-08-14 20:47:30 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
return STATUS_SUCCESS;
|
1999-12-11 21:14:49 +00:00
|
|
|
}
|
|
|
|
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
static NTSTATUS
|
|
|
|
vfatPrepareTargetForRename(
|
|
|
|
IN PDEVICE_EXTENSION DeviceExt,
|
|
|
|
IN PVFATFCB * ParentFCB,
|
|
|
|
IN PUNICODE_STRING NewName,
|
|
|
|
IN BOOLEAN ReplaceIfExists,
|
|
|
|
IN PUNICODE_STRING ParentName,
|
|
|
|
OUT PBOOLEAN Deleted)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PVFATFCB TargetFcb;
|
|
|
|
|
|
|
|
DPRINT("vfatPrepareTargetForRename(%p, %p, %wZ, %d, %wZ, %p)\n", DeviceExt, ParentFCB, NewName, ReplaceIfExists, ParentName);
|
|
|
|
|
|
|
|
*Deleted = FALSE;
|
|
|
|
/* Try to open target */
|
|
|
|
Status = vfatGetFCBForFile(DeviceExt, ParentFCB, &TargetFcb, NewName);
|
|
|
|
/* If it exists */
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2014-10-31 11:04:12 +00:00
|
|
|
DPRINT("Target file %wZ exists. FCB Flags %08x\n", NewName, TargetFcb->Flags);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
/* Check whether we are allowed to replace */
|
|
|
|
if (ReplaceIfExists)
|
|
|
|
{
|
|
|
|
/* If that's a directory or a read-only file, we're not allowed */
|
2017-02-17 17:58:18 +00:00
|
|
|
if (vfatFCBIsDirectory(TargetFcb) || vfatFCBIsReadOnly(TargetFcb))
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
{
|
2014-10-31 11:04:12 +00:00
|
|
|
DPRINT("And this is a readonly file!\n");
|
2014-10-26 15:35:18 +00:00
|
|
|
vfatReleaseFCB(DeviceExt, *ParentFCB);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
*ParentFCB = NULL;
|
|
|
|
vfatReleaseFCB(DeviceExt, TargetFcb);
|
|
|
|
return STATUS_OBJECT_NAME_COLLISION;
|
|
|
|
}
|
|
|
|
|
2014-10-31 11:04:12 +00:00
|
|
|
|
|
|
|
/* If we still have a file object, close it. */
|
|
|
|
if (TargetFcb->FileObject)
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
{
|
2014-10-31 11:04:12 +00:00
|
|
|
if (!MmFlushImageSection(TargetFcb->FileObject->SectionObjectPointer, MmFlushForDelete))
|
|
|
|
{
|
|
|
|
DPRINT("MmFlushImageSection failed.\n");
|
|
|
|
vfatReleaseFCB(DeviceExt, *ParentFCB);
|
|
|
|
*ParentFCB = NULL;
|
|
|
|
vfatReleaseFCB(DeviceExt, TargetFcb);
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
|
|
|
|
TargetFcb->FileObject->DeletePending = TRUE;
|
|
|
|
VfatCloseFile(DeviceExt, TargetFcb->FileObject);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
|
2014-10-31 11:04:12 +00:00
|
|
|
/* If we are here, ensure the file isn't open by anyone! */
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
if (TargetFcb->OpenHandleCount != 0)
|
|
|
|
{
|
2014-10-31 11:04:12 +00:00
|
|
|
DPRINT("There are still open handles for this file.\n");
|
2014-10-26 15:35:18 +00:00
|
|
|
vfatReleaseFCB(DeviceExt, *ParentFCB);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
*ParentFCB = NULL;
|
|
|
|
vfatReleaseFCB(DeviceExt, TargetFcb);
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Effectively delete old file to allow renaming */
|
2014-10-31 11:04:12 +00:00
|
|
|
DPRINT("Effectively deleting the file.\n");
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
VfatDelEntry(DeviceExt, TargetFcb, NULL);
|
|
|
|
vfatReleaseFCB(DeviceExt, TargetFcb);
|
|
|
|
*Deleted = TRUE;
|
2014-10-31 11:04:12 +00:00
|
|
|
return STATUS_SUCCESS;
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-10-26 15:35:18 +00:00
|
|
|
vfatReleaseFCB(DeviceExt, *ParentFCB);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
*ParentFCB = NULL;
|
|
|
|
vfatReleaseFCB(DeviceExt, TargetFcb);
|
|
|
|
return STATUS_OBJECT_NAME_COLLISION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (*ParentFCB != NULL)
|
|
|
|
{
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Failure */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2016-08-06 12:25:47 +00:00
|
|
|
static
|
|
|
|
BOOLEAN
|
|
|
|
IsThereAChildOpened(PVFATFCB FCB)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
PVFATFCB VolFCB;
|
|
|
|
|
|
|
|
for (Entry = FCB->ParentListHead.Flink; Entry != &FCB->ParentListHead; Entry = Entry->Flink)
|
|
|
|
{
|
|
|
|
VolFCB = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
|
|
|
|
if (VolFCB->OpenHandleCount != 0)
|
|
|
|
{
|
|
|
|
ASSERT(VolFCB->parentFcb == FCB);
|
|
|
|
DPRINT1("At least one children file opened! %wZ (%u, %u)\n", &VolFCB->PathNameU, VolFCB->RefCount, VolFCB->OpenHandleCount);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vfatFCBIsDirectory(VolFCB) && !IsListEmpty(&VolFCB->ParentListHead))
|
|
|
|
{
|
|
|
|
if (IsThereAChildOpened(VolFCB))
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2016-08-07 12:29:48 +00:00
|
|
|
static
|
|
|
|
VOID
|
|
|
|
VfatRenameChildFCB(
|
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
|
|
|
PVFATFCB FCB)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
PVFATFCB Child;
|
|
|
|
|
|
|
|
if (IsListEmpty(&FCB->ParentListHead))
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (Entry = FCB->ParentListHead.Flink; Entry != &FCB->ParentListHead; Entry = Entry->Flink)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Child = CONTAINING_RECORD(Entry, VFATFCB, ParentListEntry);
|
|
|
|
DPRINT("Found %wZ with still %lu references (parent: %lu)!\n", &Child->PathNameU, Child->RefCount, FCB->RefCount);
|
|
|
|
|
|
|
|
Status = vfatSetFCBNewDirName(DeviceExt, Child, FCB);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (vfatFCBIsDirectory(Child))
|
|
|
|
{
|
|
|
|
VfatRenameChildFCB(DeviceExt, Child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Set the file name information
|
|
|
|
*/
|
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatSetRenameInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB FCB,
|
2014-10-26 20:23:07 +00:00
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
PFILE_RENAME_INFORMATION RenameInfo,
|
|
|
|
PFILE_OBJECT TargetFileObject)
|
|
|
|
{
|
2014-10-28 20:39:42 +00:00
|
|
|
#ifdef NASSERTS_RENAME
|
|
|
|
#pragma push_macro("ASSERT")
|
|
|
|
#undef ASSERT
|
|
|
|
#define ASSERT(x) ((VOID) 0)
|
|
|
|
#endif
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
UNICODE_STRING NewName;
|
|
|
|
UNICODE_STRING SourcePath;
|
|
|
|
UNICODE_STRING SourceFile;
|
|
|
|
UNICODE_STRING NewPath;
|
|
|
|
UNICODE_STRING NewFile;
|
|
|
|
PFILE_OBJECT RootFileObject;
|
|
|
|
PVFATFCB RootFCB;
|
|
|
|
UNICODE_STRING RenameInfoString;
|
|
|
|
PVFATFCB ParentFCB;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
HANDLE TargetHandle;
|
|
|
|
BOOLEAN DeletedTarget;
|
2014-10-27 13:38:14 +00:00
|
|
|
ULONG OldReferences, NewReferences;
|
|
|
|
PVFATFCB OldParent;
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
|
2014-10-26 20:23:07 +00:00
|
|
|
DPRINT("VfatSetRenameInfo(%p, %p, %p, %p, %p)\n", FileObject, FCB, DeviceExt, RenameInfo, TargetFileObject);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
|
|
|
|
/* Disallow renaming root */
|
|
|
|
if (vfatFCBIsRoot(FCB))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2014-10-27 13:38:14 +00:00
|
|
|
OldReferences = FCB->parentFcb->RefCount;
|
2014-10-28 20:39:42 +00:00
|
|
|
#ifdef NASSERTS_RENAME
|
|
|
|
UNREFERENCED_PARAMETER(OldReferences);
|
|
|
|
#endif
|
2014-10-27 13:38:14 +00:00
|
|
|
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
/* If we are performing relative opening for rename, get FO for getting FCB and path name */
|
|
|
|
if (RenameInfo->RootDirectory != NULL)
|
|
|
|
{
|
|
|
|
/* We cannot tolerate relative opening with a full path */
|
|
|
|
if (RenameInfo->FileName[0] == L'\\')
|
|
|
|
{
|
|
|
|
return STATUS_OBJECT_NAME_INVALID;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByHandle(RenameInfo->RootDirectory,
|
|
|
|
FILE_READ_DATA,
|
|
|
|
*IoFileObjectType,
|
|
|
|
ExGetPreviousMode(),
|
|
|
|
(PVOID *)&RootFileObject,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
RootFCB = RootFileObject->FsContext;
|
|
|
|
}
|
|
|
|
|
2015-09-04 08:37:01 +00:00
|
|
|
RtlInitEmptyUnicodeString(&NewName, NULL, 0);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
ParentFCB = NULL;
|
|
|
|
|
|
|
|
if (TargetFileObject == NULL)
|
|
|
|
{
|
|
|
|
/* If we don't have target file object, construct paths thanks to relative FCB, if any, and with
|
|
|
|
* information supplied by the user
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* First, setup a string we'll work on */
|
|
|
|
RenameInfoString.Length = RenameInfo->FileNameLength;
|
|
|
|
RenameInfoString.MaximumLength = RenameInfo->FileNameLength;
|
|
|
|
RenameInfoString.Buffer = RenameInfo->FileName;
|
|
|
|
|
|
|
|
/* Check whether we have FQN */
|
|
|
|
if (RenameInfoString.Length > 6 * sizeof(WCHAR))
|
|
|
|
{
|
|
|
|
if (RenameInfoString.Buffer[0] == L'\\' && RenameInfoString.Buffer[1] == L'?' &&
|
|
|
|
RenameInfoString.Buffer[2] == L'?' && RenameInfoString.Buffer[3] == L'\\' &&
|
|
|
|
RenameInfoString.Buffer[5] == L':' && (RenameInfoString.Buffer[4] >= L'A' &&
|
|
|
|
RenameInfoString.Buffer[4] <= L'Z'))
|
|
|
|
{
|
|
|
|
/* If so, open its target directory */
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&RenameInfoString,
|
|
|
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
|
|
|
NULL, NULL);
|
|
|
|
|
|
|
|
Status = IoCreateFile(&TargetHandle,
|
|
|
|
FILE_WRITE_DATA | SYNCHRONIZE,
|
|
|
|
&ObjectAttributes,
|
|
|
|
&IoStatusBlock,
|
|
|
|
NULL, 0,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
FILE_OPEN,
|
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT,
|
|
|
|
NULL, 0,
|
|
|
|
CreateFileTypeNone,
|
|
|
|
NULL,
|
|
|
|
IO_FORCE_ACCESS_CHECK | IO_OPEN_TARGET_DIRECTORY);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get its FO to get the FCB */
|
|
|
|
Status = ObReferenceObjectByHandle(TargetHandle,
|
|
|
|
FILE_WRITE_DATA,
|
|
|
|
*IoFileObjectType,
|
|
|
|
KernelMode,
|
|
|
|
(PVOID *)&TargetFileObject,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ZwClose(TargetHandle);
|
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Are we working on the same volume? */
|
|
|
|
if (IoGetRelatedDeviceObject(TargetFileObject) != IoGetRelatedDeviceObject(FileObject))
|
|
|
|
{
|
|
|
|
ObDereferenceObject(TargetFileObject);
|
|
|
|
ZwClose(TargetHandle);
|
|
|
|
TargetFileObject = NULL;
|
|
|
|
Status = STATUS_NOT_SAME_DEVICE;
|
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NewName.Length = 0;
|
|
|
|
NewName.MaximumLength = RenameInfo->FileNameLength;
|
|
|
|
if (RenameInfo->RootDirectory != NULL)
|
|
|
|
{
|
|
|
|
NewName.MaximumLength += sizeof(WCHAR) + RootFCB->PathNameU.Length;
|
|
|
|
}
|
|
|
|
else if (RenameInfo->FileName[0] != L'\\')
|
|
|
|
{
|
|
|
|
/* We don't have full path, and we don't have root directory:
|
|
|
|
* => we move inside the same directory
|
|
|
|
*/
|
|
|
|
NewName.MaximumLength += sizeof(WCHAR) + FCB->DirNameU.Length;
|
|
|
|
}
|
|
|
|
else if (TargetFileObject != NULL)
|
|
|
|
{
|
|
|
|
/* We had a FQN:
|
|
|
|
* => we need to use its correct path
|
|
|
|
*/
|
|
|
|
NewName.MaximumLength += sizeof(WCHAR) + ((PVFATFCB)TargetFileObject->FsContext)->PathNameU.Length;
|
|
|
|
}
|
|
|
|
|
2018-08-21 06:36:51 +00:00
|
|
|
NewName.Buffer = ExAllocatePoolWithTag(NonPagedPool, NewName.MaximumLength, TAG_NAME);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
if (NewName.Buffer == NULL)
|
|
|
|
{
|
|
|
|
if (TargetFileObject != NULL)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(TargetFileObject);
|
|
|
|
ZwClose(TargetHandle);
|
|
|
|
TargetFileObject = NULL;
|
|
|
|
}
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RenameInfo->RootDirectory != NULL)
|
|
|
|
{
|
2021-06-11 12:29:21 +00:00
|
|
|
/* Here, copy first absolute and then append relative */
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
RtlCopyUnicodeString(&NewName, &RootFCB->PathNameU);
|
|
|
|
NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
|
|
|
|
NewName.Length += sizeof(WCHAR);
|
|
|
|
RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
|
|
|
|
}
|
|
|
|
else if (RenameInfo->FileName[0] != L'\\')
|
|
|
|
{
|
|
|
|
/* Here, copy first work directory and then append filename */
|
|
|
|
RtlCopyUnicodeString(&NewName, &FCB->DirNameU);
|
|
|
|
NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
|
|
|
|
NewName.Length += sizeof(WCHAR);
|
|
|
|
RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
|
|
|
|
}
|
|
|
|
else if (TargetFileObject != NULL)
|
|
|
|
{
|
|
|
|
/* Here, copy first path name and then append filename */
|
|
|
|
RtlCopyUnicodeString(&NewName, &((PVFATFCB)TargetFileObject->FsContext)->PathNameU);
|
|
|
|
NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
|
|
|
|
NewName.Length += sizeof(WCHAR);
|
|
|
|
RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Here we should have full path, so simply copy it */
|
|
|
|
RtlCopyUnicodeString(&NewName, &RenameInfoString);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do we have to cleanup some stuff? */
|
|
|
|
if (TargetFileObject != NULL)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(TargetFileObject);
|
|
|
|
ZwClose(TargetHandle);
|
|
|
|
TargetFileObject = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* At that point, we shouldn't care about whether we are relative opening
|
|
|
|
* Target FO FCB should already have full path
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Before constructing string, just make a sanity check (just to be sure!) */
|
|
|
|
if (IoGetRelatedDeviceObject(TargetFileObject) != IoGetRelatedDeviceObject(FileObject))
|
|
|
|
{
|
|
|
|
Status = STATUS_NOT_SAME_DEVICE;
|
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewName.Length = 0;
|
|
|
|
NewName.MaximumLength = TargetFileObject->FileName.Length + ((PVFATFCB)TargetFileObject->FsContext)->PathNameU.Length + sizeof(WCHAR);
|
2018-08-21 06:36:51 +00:00
|
|
|
NewName.Buffer = ExAllocatePoolWithTag(NonPagedPool, NewName.MaximumLength, TAG_NAME);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
if (NewName.Buffer == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlCopyUnicodeString(&NewName, &((PVFATFCB)TargetFileObject->FsContext)->PathNameU);
|
2018-06-09 20:17:17 +00:00
|
|
|
/* If \, it's already backslash terminated, don't add it */
|
|
|
|
if (!vfatFCBIsRoot(TargetFileObject->FsContext))
|
|
|
|
{
|
|
|
|
NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
|
|
|
|
NewName.Length += sizeof(WCHAR);
|
|
|
|
}
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
RtlAppendUnicodeStringToString(&NewName, &TargetFileObject->FileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Explode our paths to get path & filename */
|
|
|
|
vfatSplitPathName(&FCB->PathNameU, &SourcePath, &SourceFile);
|
|
|
|
DPRINT("Old dir: %wZ, Old file: %wZ\n", &SourcePath, &SourceFile);
|
|
|
|
vfatSplitPathName(&NewName, &NewPath, &NewFile);
|
|
|
|
DPRINT("New dir: %wZ, New file: %wZ\n", &NewPath, &NewFile);
|
|
|
|
|
2020-09-26 22:39:15 +00:00
|
|
|
if (IsDotOrDotDot(&NewFile))
|
|
|
|
{
|
|
|
|
Status = STATUS_OBJECT_NAME_INVALID;
|
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
2016-08-06 08:30:30 +00:00
|
|
|
if (vfatFCBIsDirectory(FCB) && !IsListEmpty(&FCB->ParentListHead))
|
2016-06-26 10:23:35 +00:00
|
|
|
{
|
2016-08-06 12:25:47 +00:00
|
|
|
if (IsThereAChildOpened(FCB))
|
2016-06-26 10:23:35 +00:00
|
|
|
{
|
2016-08-06 12:25:47 +00:00
|
|
|
Status = STATUS_ACCESS_DENIED;
|
|
|
|
ASSERT(OldReferences == FCB->parentFcb->RefCount);
|
|
|
|
goto Cleanup;
|
2016-06-26 10:23:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
/* Are we working in place? */
|
|
|
|
if (FsRtlAreNamesEqual(&SourcePath, &NewPath, TRUE, NULL))
|
|
|
|
{
|
|
|
|
if (FsRtlAreNamesEqual(&SourceFile, &NewFile, FALSE, NULL))
|
|
|
|
{
|
|
|
|
Status = STATUS_SUCCESS;
|
2014-10-27 13:38:14 +00:00
|
|
|
ASSERT(OldReferences == FCB->parentFcb->RefCount);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FsRtlAreNamesEqual(&SourceFile, &NewFile, TRUE, NULL))
|
|
|
|
{
|
2018-01-07 13:16:11 +00:00
|
|
|
vfatReportChange(DeviceExt,
|
|
|
|
FCB,
|
|
|
|
(vfatFCBIsDirectory(FCB) ?
|
|
|
|
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
|
|
|
|
FILE_ACTION_RENAMED_OLD_NAME);
|
2014-10-26 20:23:07 +00:00
|
|
|
Status = vfatRenameEntry(DeviceExt, FCB, &NewFile, TRUE);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2018-01-07 13:16:11 +00:00
|
|
|
vfatReportChange(DeviceExt,
|
|
|
|
FCB,
|
|
|
|
(vfatFCBIsDirectory(FCB) ?
|
|
|
|
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
|
|
|
|
FILE_ACTION_RENAMED_NEW_NAME);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Try to find target */
|
|
|
|
ParentFCB = FCB->parentFcb;
|
2014-10-26 20:23:07 +00:00
|
|
|
vfatGrabFCB(DeviceExt, ParentFCB);
|
|
|
|
Status = vfatPrepareTargetForRename(DeviceExt,
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
&ParentFCB,
|
|
|
|
&NewFile,
|
|
|
|
RenameInfo->ReplaceIfExists,
|
|
|
|
&NewPath,
|
|
|
|
&DeletedTarget);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2014-10-27 13:38:14 +00:00
|
|
|
ASSERT(OldReferences == FCB->parentFcb->RefCount - 1);
|
|
|
|
ASSERT(OldReferences == ParentFCB->RefCount - 1);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
2018-01-07 13:16:11 +00:00
|
|
|
vfatReportChange(DeviceExt,
|
|
|
|
FCB,
|
|
|
|
(vfatFCBIsDirectory(FCB) ?
|
|
|
|
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
|
|
|
|
(DeletedTarget ? FILE_ACTION_REMOVED : FILE_ACTION_RENAMED_OLD_NAME));
|
2014-10-26 20:23:07 +00:00
|
|
|
Status = vfatRenameEntry(DeviceExt, FCB, &NewFile, FALSE);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (DeletedTarget)
|
|
|
|
{
|
2018-01-07 13:16:11 +00:00
|
|
|
vfatReportChange(DeviceExt,
|
|
|
|
FCB,
|
|
|
|
FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE
|
|
|
|
| FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA,
|
|
|
|
FILE_ACTION_MODIFIED);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-01-07 13:16:11 +00:00
|
|
|
vfatReportChange(DeviceExt,
|
|
|
|
FCB,
|
|
|
|
(vfatFCBIsDirectory(FCB) ?
|
|
|
|
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
|
|
|
|
FILE_ACTION_RENAMED_NEW_NAME);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-10-27 13:38:14 +00:00
|
|
|
|
|
|
|
ASSERT(OldReferences == FCB->parentFcb->RefCount - 1); // extra grab
|
|
|
|
ASSERT(OldReferences == ParentFCB->RefCount - 1); // extra grab
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-10-27 13:38:14 +00:00
|
|
|
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
/* Try to find target */
|
|
|
|
ParentFCB = NULL;
|
2014-10-27 13:38:14 +00:00
|
|
|
OldParent = FCB->parentFcb;
|
2014-10-28 20:39:42 +00:00
|
|
|
#ifdef NASSERTS_RENAME
|
|
|
|
UNREFERENCED_PARAMETER(OldParent);
|
|
|
|
#endif
|
2014-10-26 20:23:07 +00:00
|
|
|
Status = vfatPrepareTargetForRename(DeviceExt,
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
&ParentFCB,
|
|
|
|
&NewName,
|
|
|
|
RenameInfo->ReplaceIfExists,
|
|
|
|
&NewPath,
|
|
|
|
&DeletedTarget);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2014-10-27 13:38:14 +00:00
|
|
|
ASSERT(OldReferences == FCB->parentFcb->RefCount);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
2014-10-27 13:38:14 +00:00
|
|
|
NewReferences = ParentFCB->RefCount;
|
2014-10-28 20:39:42 +00:00
|
|
|
#ifdef NASSERTS_RENAME
|
|
|
|
UNREFERENCED_PARAMETER(NewReferences);
|
|
|
|
#endif
|
2014-10-27 13:38:14 +00:00
|
|
|
|
2018-01-07 13:16:11 +00:00
|
|
|
vfatReportChange(DeviceExt,
|
|
|
|
FCB,
|
|
|
|
(vfatFCBIsDirectory(FCB) ?
|
|
|
|
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
|
|
|
|
FILE_ACTION_REMOVED);
|
2014-10-26 20:23:07 +00:00
|
|
|
Status = VfatMoveEntry(DeviceExt, FCB, &NewFile, ParentFCB);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (DeletedTarget)
|
|
|
|
{
|
2018-01-07 13:16:11 +00:00
|
|
|
vfatReportChange(DeviceExt,
|
|
|
|
FCB,
|
|
|
|
FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE
|
|
|
|
| FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA,
|
|
|
|
FILE_ACTION_MODIFIED);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-01-07 13:16:11 +00:00
|
|
|
vfatReportChange(DeviceExt,
|
|
|
|
FCB,
|
|
|
|
(vfatFCBIsDirectory(FCB) ?
|
|
|
|
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
|
|
|
|
FILE_ACTION_ADDED);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-07 12:29:48 +00:00
|
|
|
if (NT_SUCCESS(Status) && vfatFCBIsDirectory(FCB))
|
|
|
|
{
|
|
|
|
VfatRenameChildFCB(DeviceExt, FCB);
|
|
|
|
}
|
|
|
|
|
2014-10-27 13:38:14 +00:00
|
|
|
ASSERT(OldReferences == OldParent->RefCount + 1); // removed file
|
|
|
|
ASSERT(NewReferences == ParentFCB->RefCount - 1); // new file
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
Cleanup:
|
2014-10-26 20:23:07 +00:00
|
|
|
if (ParentFCB != NULL) vfatReleaseFCB(DeviceExt, ParentFCB);
|
2018-08-21 06:36:51 +00:00
|
|
|
if (NewName.Buffer != NULL) ExFreePoolWithTag(NewName.Buffer, TAG_NAME);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
if (RenameInfo->RootDirectory != NULL) ObDereferenceObject(RootFileObject);
|
|
|
|
|
|
|
|
return Status;
|
2014-10-28 20:39:42 +00:00
|
|
|
#ifdef NASSERTS_RENAME
|
|
|
|
#pragma pop_macro("ASSERT")
|
|
|
|
#endif
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
|
2001-03-06 23:36:35 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the file name information
|
|
|
|
*/
|
2013-12-09 10:35:15 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatGetNameInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
PFILE_NAME_INFORMATION NameInfo,
|
|
|
|
PULONG BufferLength)
|
2001-03-06 23:36:35 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
ULONG BytesToCopy;
|
2009-06-19 00:21:21 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
UNREFERENCED_PARAMETER(FileObject);
|
2017-06-26 18:10:43 +00:00
|
|
|
UNREFERENCED_PARAMETER(DeviceExt);
|
2009-06-19 00:21:21 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
ASSERT(NameInfo != NULL);
|
|
|
|
ASSERT(FCB != NULL);
|
2001-03-06 23:36:35 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* If buffer can't hold at least the file name length, bail out */
|
|
|
|
if (*BufferLength < (ULONG)FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
2001-06-12 12:35:42 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* Save file name length, and as much file len, as buffer length allows */
|
|
|
|
NameInfo->FileNameLength = FCB->PathNameU.Length;
|
2008-11-17 11:25:36 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* Calculate amount of bytes to copy not to overflow the buffer */
|
|
|
|
BytesToCopy = min(FCB->PathNameU.Length,
|
|
|
|
*BufferLength - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]));
|
2001-06-12 12:35:42 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* Fill in the bytes */
|
|
|
|
RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, BytesToCopy);
|
2008-11-17 11:25:36 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* Check if we could write more but are not able to */
|
|
|
|
if (*BufferLength < FCB->PathNameU.Length + (ULONG)FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
|
|
|
|
{
|
|
|
|
/* Return number of bytes written */
|
|
|
|
*BufferLength -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + BytesToCopy;
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
|
|
}
|
2008-11-17 11:25:36 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* We filled up as many bytes, as needed */
|
|
|
|
*BufferLength -= (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + FCB->PathNameU.Length);
|
2001-03-06 23:36:35 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-03-06 23:36:35 +00:00
|
|
|
}
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatGetInternalInformation(
|
|
|
|
PVFATFCB Fcb,
|
2017-06-26 18:10:43 +00:00
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
PFILE_INTERNAL_INFORMATION InternalInfo,
|
|
|
|
PULONG BufferLength)
|
2001-11-01 10:44:11 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
ASSERT(InternalInfo);
|
|
|
|
ASSERT(Fcb);
|
|
|
|
|
|
|
|
if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
2017-06-26 18:10:43 +00:00
|
|
|
|
|
|
|
InternalInfo->IndexNumber.QuadPart = (LONGLONG)vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry) * DeviceExt->FatInfo.BytesPerCluster;
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
*BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
|
|
|
|
return STATUS_SUCCESS;
|
2001-11-01 10:44:11 +00:00
|
|
|
}
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
|
2002-07-20 00:57:36 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the file network open information
|
|
|
|
*/
|
2013-12-09 10:35:15 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatGetNetworkOpenInformation(
|
|
|
|
PVFATFCB Fcb,
|
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
|
|
|
PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
|
|
|
|
PULONG BufferLength)
|
2002-07-20 00:57:36 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
ASSERT(NetworkInfo);
|
|
|
|
ASSERT(Fcb);
|
|
|
|
|
|
|
|
if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
|
|
|
|
return(STATUS_BUFFER_OVERFLOW);
|
|
|
|
|
2017-02-17 21:24:12 +00:00
|
|
|
if (vfatVolumeIsFatX(DeviceExt))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
Fcb->entry.FatX.CreationDate,
|
|
|
|
Fcb->entry.FatX.CreationTime,
|
|
|
|
&NetworkInfo->CreationTime);
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
Fcb->entry.FatX.AccessDate,
|
|
|
|
Fcb->entry.FatX.AccessTime,
|
|
|
|
&NetworkInfo->LastAccessTime);
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
Fcb->entry.FatX.UpdateDate,
|
|
|
|
Fcb->entry.FatX.UpdateTime,
|
|
|
|
&NetworkInfo->LastWriteTime);
|
|
|
|
NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
Fcb->entry.Fat.CreationDate,
|
|
|
|
Fcb->entry.Fat.CreationTime,
|
|
|
|
&NetworkInfo->CreationTime);
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
Fcb->entry.Fat.AccessDate,
|
|
|
|
0,
|
|
|
|
&NetworkInfo->LastAccessTime);
|
|
|
|
FsdDosDateTimeToSystemTime(DeviceExt,
|
|
|
|
Fcb->entry.Fat.UpdateDate,
|
|
|
|
Fcb->entry.Fat.UpdateTime,
|
|
|
|
&NetworkInfo->LastWriteTime);
|
|
|
|
NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
|
|
|
|
}
|
2002-07-20 00:57:36 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
if (vfatFCBIsDirectory(Fcb))
|
|
|
|
{
|
|
|
|
NetworkInfo->EndOfFile.QuadPart = 0L;
|
|
|
|
NetworkInfo->AllocationSize.QuadPart = 0L;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
|
|
|
|
NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
NetworkInfo->FileAttributes = *Fcb->Attributes & 0x3f;
|
|
|
|
/* Synthesize FILE_ATTRIBUTE_NORMAL */
|
|
|
|
if (0 == (NetworkInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
|
|
|
|
FILE_ATTRIBUTE_ARCHIVE |
|
|
|
|
FILE_ATTRIBUTE_SYSTEM |
|
|
|
|
FILE_ATTRIBUTE_HIDDEN |
|
|
|
|
FILE_ATTRIBUTE_READONLY)))
|
|
|
|
{
|
|
|
|
DPRINT("Synthesizing FILE_ATTRIBUTE_NORMAL\n");
|
|
|
|
NetworkInfo->FileAttributes |= FILE_ATTRIBUTE_NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
|
|
|
|
return STATUS_SUCCESS;
|
2002-07-20 00:57:36 +00:00
|
|
|
}
|
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatGetEaInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB Fcb,
|
2017-06-26 18:10:43 +00:00
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
PFILE_EA_INFORMATION Info,
|
|
|
|
PULONG BufferLength)
|
2006-05-07 18:50:18 +00:00
|
|
|
{
|
2009-06-19 00:21:21 +00:00
|
|
|
UNREFERENCED_PARAMETER(FileObject);
|
|
|
|
UNREFERENCED_PARAMETER(Fcb);
|
|
|
|
|
2006-05-07 18:50:18 +00:00
|
|
|
/* FIXME - use SEH to access the buffer! */
|
|
|
|
Info->EaSize = 0;
|
|
|
|
*BufferLength -= sizeof(*Info);
|
|
|
|
if (DeviceExt->FatInfo.FatType == FAT12 ||
|
|
|
|
DeviceExt->FatInfo.FatType == FAT16)
|
|
|
|
{
|
|
|
|
/* FIXME */
|
|
|
|
DPRINT1("VFAT: FileEaInformation not implemented!\n");
|
|
|
|
}
|
2012-01-01 17:15:25 +00:00
|
|
|
return STATUS_SUCCESS;
|
2006-05-07 18:50:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-20 11:44:37 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the all file information
|
|
|
|
*/
|
2013-12-09 10:35:15 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
VfatGetAllInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB Fcb,
|
2017-06-26 18:10:43 +00:00
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
PFILE_ALL_INFORMATION Info,
|
|
|
|
PULONG BufferLength)
|
2002-07-20 11:44:37 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
ASSERT(Info);
|
|
|
|
ASSERT(Fcb);
|
|
|
|
|
2015-11-16 13:58:39 +00:00
|
|
|
if (*BufferLength < FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName))
|
2015-11-14 20:41:59 +00:00
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
2013-12-09 10:35:15 +00:00
|
|
|
|
2017-12-09 09:59:37 +00:00
|
|
|
*BufferLength -= (sizeof(FILE_ACCESS_INFORMATION) + sizeof(FILE_MODE_INFORMATION) + sizeof(FILE_ALIGNMENT_INFORMATION));
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* Basic Information */
|
2017-06-26 18:10:43 +00:00
|
|
|
Status = VfatGetBasicInformation(FileObject, Fcb, DeviceExt, &Info->BasicInformation, BufferLength);
|
2013-12-09 10:35:15 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
/* Standard Information */
|
|
|
|
Status = VfatGetStandardInformation(Fcb, &Info->StandardInformation, BufferLength);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
/* Internal Information */
|
2017-06-26 18:10:43 +00:00
|
|
|
Status = VfatGetInternalInformation(Fcb, DeviceExt, &Info->InternalInformation, BufferLength);
|
2013-12-09 10:35:15 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
/* EA Information */
|
2017-06-26 18:10:43 +00:00
|
|
|
Status = VfatGetEaInformation(FileObject, Fcb, DeviceExt, &Info->EaInformation, BufferLength);
|
2015-11-16 13:58:39 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2013-12-09 10:35:15 +00:00
|
|
|
/* Position Information */
|
2017-06-26 18:10:43 +00:00
|
|
|
Status = VfatGetPositionInformation(FileObject, Fcb, DeviceExt, &Info->PositionInformation, BufferLength);
|
2013-12-09 10:35:15 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
/* Name Information */
|
2017-06-26 18:10:43 +00:00
|
|
|
Status = VfatGetNameInformation(FileObject, Fcb, DeviceExt, &Info->NameInformation, BufferLength);
|
2013-12-09 10:35:15 +00:00
|
|
|
|
2015-11-14 20:41:59 +00:00
|
|
|
return Status;
|
2002-07-20 11:44:37 +00:00
|
|
|
}
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
static
|
|
|
|
VOID
|
|
|
|
UpdateFileSize(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB Fcb,
|
|
|
|
ULONG Size,
|
2017-02-17 21:24:12 +00:00
|
|
|
ULONG ClusterSize,
|
|
|
|
BOOLEAN IsFatX)
|
2003-01-28 16:48:03 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
if (Size > 0)
|
|
|
|
{
|
2016-06-11 09:32:00 +00:00
|
|
|
Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP_64(Size, ClusterSize);
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Fcb->RFCB.AllocationSize.QuadPart = (LONGLONG)0;
|
|
|
|
}
|
|
|
|
if (!vfatFCBIsDirectory(Fcb))
|
|
|
|
{
|
2017-02-17 21:24:12 +00:00
|
|
|
if (IsFatX)
|
2013-12-09 10:35:15 +00:00
|
|
|
Fcb->entry.FatX.FileSize = Size;
|
|
|
|
else
|
|
|
|
Fcb->entry.Fat.FileSize = Size;
|
|
|
|
}
|
|
|
|
Fcb->RFCB.FileSize.QuadPart = Size;
|
|
|
|
Fcb->RFCB.ValidDataLength.QuadPart = Size;
|
|
|
|
|
|
|
|
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
|
2003-01-28 16:48:03 +00:00
|
|
|
}
|
|
|
|
|
2002-08-14 20:58:39 +00:00
|
|
|
NTSTATUS
|
2013-12-09 10:35:15 +00:00
|
|
|
VfatSetAllocationSizeInformation(
|
|
|
|
PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB Fcb,
|
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
|
|
|
PLARGE_INTEGER AllocationSize)
|
2002-08-14 20:58:39 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
ULONG OldSize;
|
|
|
|
ULONG Cluster, FirstCluster;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
|
|
|
|
ULONG NewSize = AllocationSize->u.LowPart;
|
|
|
|
ULONG NCluster;
|
2017-02-17 21:24:12 +00:00
|
|
|
BOOLEAN AllocSizeChanged = FALSE, IsFatX = vfatVolumeIsFatX(DeviceExt);
|
2013-12-09 10:35:15 +00:00
|
|
|
|
|
|
|
DPRINT("VfatSetAllocationSizeInformation(File <%wZ>, AllocationSize %d %u)\n",
|
|
|
|
&Fcb->PathNameU, AllocationSize->HighPart, AllocationSize->LowPart);
|
|
|
|
|
2017-02-17 11:38:05 +00:00
|
|
|
if (IsFatX)
|
2013-12-09 10:35:15 +00:00
|
|
|
OldSize = Fcb->entry.FatX.FileSize;
|
|
|
|
else
|
|
|
|
OldSize = Fcb->entry.Fat.FileSize;
|
|
|
|
|
|
|
|
if (AllocationSize->u.HighPart > 0)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OldSize == NewSize)
|
|
|
|
{
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry);
|
|
|
|
|
|
|
|
if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)
|
|
|
|
{
|
|
|
|
AllocSizeChanged = TRUE;
|
|
|
|
if (FirstCluster == 0)
|
2006-05-07 18:50:18 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
Fcb->LastCluster = Fcb->LastOffset = 0;
|
|
|
|
Status = NextCluster(DeviceExt, FirstCluster, &FirstCluster, TRUE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("NextCluster failed. Status = %x\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FirstCluster == 0xffffffff)
|
|
|
|
{
|
|
|
|
return STATUS_DISK_FULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = OffsetToCluster(DeviceExt, FirstCluster,
|
|
|
|
ROUND_DOWN(NewSize - 1, ClusterSize),
|
|
|
|
&NCluster, TRUE);
|
|
|
|
if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* disk is full */
|
|
|
|
NCluster = Cluster = FirstCluster;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
|
|
|
|
{
|
|
|
|
Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
|
|
|
|
WriteCluster(DeviceExt, Cluster, 0);
|
|
|
|
Cluster = NCluster;
|
|
|
|
}
|
|
|
|
return STATUS_DISK_FULL;
|
|
|
|
}
|
|
|
|
|
2017-02-17 11:38:05 +00:00
|
|
|
if (IsFatX)
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
Fcb->entry.FatX.FirstCluster = FirstCluster;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (DeviceExt->FatInfo.FatType == FAT32)
|
|
|
|
{
|
|
|
|
Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
|
|
|
|
Fcb->entry.Fat.FirstClusterHigh = FirstCluster >> 16;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ASSERT((FirstCluster >> 16) == 0);
|
|
|
|
Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
|
|
|
|
}
|
|
|
|
}
|
2006-05-07 18:50:18 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
if (Fcb->LastCluster > 0)
|
|
|
|
{
|
|
|
|
if (Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize == Fcb->LastOffset)
|
|
|
|
{
|
|
|
|
Cluster = Fcb->LastCluster;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = OffsetToCluster(DeviceExt, Fcb->LastCluster,
|
|
|
|
Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize - Fcb->LastOffset,
|
|
|
|
&Cluster, FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = OffsetToCluster(DeviceExt, FirstCluster,
|
|
|
|
Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
|
|
|
|
&Cluster, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
Fcb->LastCluster = Cluster;
|
|
|
|
Fcb->LastOffset = Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize;
|
|
|
|
|
|
|
|
/* FIXME: Check status */
|
|
|
|
/* Cluster points now to the last cluster within the chain */
|
|
|
|
Status = OffsetToCluster(DeviceExt, Cluster,
|
|
|
|
ROUND_DOWN(NewSize - 1, ClusterSize) - Fcb->LastOffset,
|
|
|
|
&NCluster, TRUE);
|
|
|
|
if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* disk is full */
|
|
|
|
NCluster = Cluster;
|
|
|
|
Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
|
|
|
|
WriteCluster(DeviceExt, Cluster, 0xffffffff);
|
|
|
|
Cluster = NCluster;
|
|
|
|
while (NT_SUCCESS(Status) && Cluster != 0xffffffff && Cluster > 1)
|
|
|
|
{
|
|
|
|
Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
|
|
|
|
WriteCluster(DeviceExt, Cluster, 0);
|
|
|
|
Cluster = NCluster;
|
|
|
|
}
|
|
|
|
return STATUS_DISK_FULL;
|
|
|
|
}
|
2006-05-07 18:50:18 +00:00
|
|
|
}
|
2017-02-17 21:24:12 +00:00
|
|
|
UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize, vfatVolumeIsFatX(DeviceExt));
|
2003-01-19 01:06:09 +00:00
|
|
|
}
|
2013-12-09 10:35:15 +00:00
|
|
|
else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
|
2003-01-19 01:06:09 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
DPRINT("Check for the ability to set file size\n");
|
|
|
|
if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
|
|
|
|
(PLARGE_INTEGER)AllocationSize))
|
|
|
|
{
|
|
|
|
DPRINT("Couldn't set file size!\n");
|
|
|
|
return STATUS_USER_MAPPED_FILE;
|
|
|
|
}
|
|
|
|
DPRINT("Can set file size\n");
|
|
|
|
|
|
|
|
AllocSizeChanged = TRUE;
|
|
|
|
/* FIXME: Use the cached cluster/offset better way. */
|
|
|
|
Fcb->LastCluster = Fcb->LastOffset = 0;
|
2017-02-17 21:24:12 +00:00
|
|
|
UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize, vfatVolumeIsFatX(DeviceExt));
|
2013-12-09 10:35:15 +00:00
|
|
|
if (NewSize > 0)
|
2006-05-07 18:50:18 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
Status = OffsetToCluster(DeviceExt, FirstCluster,
|
|
|
|
ROUND_DOWN(NewSize - 1, ClusterSize),
|
|
|
|
&Cluster, FALSE);
|
|
|
|
|
|
|
|
NCluster = Cluster;
|
|
|
|
Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
|
|
|
|
WriteCluster(DeviceExt, Cluster, 0xffffffff);
|
|
|
|
Cluster = NCluster;
|
2006-05-07 18:50:18 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-02-17 11:38:05 +00:00
|
|
|
if (IsFatX)
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
Fcb->entry.FatX.FirstCluster = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (DeviceExt->FatInfo.FatType == FAT32)
|
|
|
|
{
|
|
|
|
Fcb->entry.Fat.FirstCluster = 0;
|
|
|
|
Fcb->entry.Fat.FirstClusterHigh = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Fcb->entry.Fat.FirstCluster = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NCluster = Cluster = FirstCluster;
|
|
|
|
Status = STATUS_SUCCESS;
|
2006-05-07 18:50:18 +00:00
|
|
|
}
|
2003-01-28 16:48:03 +00:00
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)
|
|
|
|
{
|
|
|
|
Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
|
|
|
|
WriteCluster(DeviceExt, Cluster, 0);
|
|
|
|
Cluster = NCluster;
|
2018-06-09 10:36:43 +00:00
|
|
|
}
|
|
|
|
|
2018-06-09 16:21:32 +00:00
|
|
|
if (DeviceExt->FatInfo.FatType == FAT32)
|
2018-06-09 10:36:43 +00:00
|
|
|
{
|
2018-06-09 16:21:32 +00:00
|
|
|
FAT32UpdateFreeClustersCount(DeviceExt);
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
2003-01-19 01:06:09 +00:00
|
|
|
}
|
2013-12-09 10:35:15 +00:00
|
|
|
else
|
2003-01-19 01:06:09 +00:00
|
|
|
{
|
2017-02-17 21:24:12 +00:00
|
|
|
UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize, vfatVolumeIsFatX(DeviceExt));
|
2003-01-19 01:06:09 +00:00
|
|
|
}
|
2013-12-09 10:35:15 +00:00
|
|
|
|
|
|
|
/* Update the on-disk directory entry */
|
|
|
|
Fcb->Flags |= FCB_IS_DIRTY;
|
|
|
|
if (AllocSizeChanged)
|
2003-10-11 17:51:56 +00:00
|
|
|
{
|
2018-05-18 12:03:20 +00:00
|
|
|
VfatUpdateEntry(DeviceExt, Fcb);
|
2018-01-07 14:29:33 +00:00
|
|
|
|
|
|
|
vfatReportChange(DeviceExt, Fcb, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
|
2003-10-11 17:51:56 +00:00
|
|
|
}
|
2013-12-09 10:35:15 +00:00
|
|
|
return STATUS_SUCCESS;
|
2002-08-14 20:58:39 +00:00
|
|
|
}
|
2002-07-20 11:44:37 +00:00
|
|
|
|
1999-12-11 21:14:49 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the specified file information
|
|
|
|
*/
|
2013-12-09 10:35:15 +00:00
|
|
|
NTSTATUS
|
|
|
|
VfatQueryInformation(
|
|
|
|
PVFAT_IRP_CONTEXT IrpContext)
|
1999-12-11 21:14:49 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
FILE_INFORMATION_CLASS FileInformationClass;
|
2017-02-12 08:25:42 +00:00
|
|
|
PVFATFCB FCB;
|
2013-12-09 10:35:15 +00:00
|
|
|
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
PVOID SystemBuffer;
|
|
|
|
ULONG BufferLength;
|
|
|
|
|
|
|
|
/* PRECONDITION */
|
|
|
|
ASSERT(IrpContext);
|
|
|
|
|
|
|
|
/* INITIALIZATION */
|
|
|
|
FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
|
|
|
|
FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
|
|
|
|
|
|
|
|
DPRINT("VfatQueryInformation is called for '%s'\n",
|
|
|
|
FileInformationClass >= FileMaximumInformation - 1 ? "????" : FileInformationClassNames[FileInformationClass]);
|
|
|
|
|
2016-11-23 18:21:03 +00:00
|
|
|
if (FCB == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("IRP_MJ_QUERY_INFORMATION without FCB!\n");
|
|
|
|
IrpContext->Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
2013-12-09 10:35:15 +00:00
|
|
|
|
|
|
|
SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
|
|
|
|
|
2017-02-17 11:38:05 +00:00
|
|
|
if (!BooleanFlagOn(FCB->Flags, FCB_IS_PAGE_FILE))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
if (!ExAcquireResourceSharedLite(&FCB->MainResource,
|
2015-05-25 17:30:01 +00:00
|
|
|
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
2015-05-15 16:03:29 +00:00
|
|
|
return VfatMarkIrpContextForQueue(IrpContext);
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (FileInformationClass)
|
|
|
|
{
|
|
|
|
case FileStandardInformation:
|
|
|
|
Status = VfatGetStandardInformation(FCB,
|
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FilePositionInformation:
|
|
|
|
Status = VfatGetPositionInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
IrpContext->DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FileBasicInformation:
|
|
|
|
Status = VfatGetBasicInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
IrpContext->DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FileNameInformation:
|
|
|
|
Status = VfatGetNameInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
IrpContext->DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FileInternalInformation:
|
|
|
|
Status = VfatGetInternalInformation(FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
IrpContext->DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FileNetworkOpenInformation:
|
|
|
|
Status = VfatGetNetworkOpenInformation(FCB,
|
|
|
|
IrpContext->DeviceExt,
|
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FileAllInformation:
|
|
|
|
Status = VfatGetAllInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
IrpContext->DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FileEaInformation:
|
|
|
|
Status = VfatGetEaInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
IrpContext->DeviceExt,
|
2013-12-09 10:35:15 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FileAlternateNameInformation:
|
|
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2017-02-17 11:38:05 +00:00
|
|
|
if (!BooleanFlagOn(FCB->Flags, FCB_IS_PAGE_FILE))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
ExReleaseResourceLite(&FCB->MainResource);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)
|
|
|
|
IrpContext->Irp->IoStatus.Information =
|
|
|
|
IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
|
|
|
|
else
|
|
|
|
IrpContext->Irp->IoStatus.Information = 0;
|
|
|
|
|
|
|
|
return Status;
|
1999-12-11 21:14:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the specified file information
|
|
|
|
*/
|
2013-12-09 10:35:15 +00:00
|
|
|
NTSTATUS
|
|
|
|
VfatSetInformation(
|
|
|
|
PVFAT_IRP_CONTEXT IrpContext)
|
1999-12-11 21:14:49 +00:00
|
|
|
{
|
2013-12-09 10:35:15 +00:00
|
|
|
FILE_INFORMATION_CLASS FileInformationClass;
|
2017-02-12 08:25:42 +00:00
|
|
|
PVFATFCB FCB;
|
2013-12-09 12:55:23 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2013-12-09 10:35:15 +00:00
|
|
|
PVOID SystemBuffer;
|
2018-05-26 15:12:03 +00:00
|
|
|
BOOLEAN LockDir;
|
2013-12-09 10:35:15 +00:00
|
|
|
|
|
|
|
/* PRECONDITION */
|
|
|
|
ASSERT(IrpContext);
|
|
|
|
|
|
|
|
DPRINT("VfatSetInformation(IrpContext %p)\n", IrpContext);
|
|
|
|
|
|
|
|
/* INITIALIZATION */
|
|
|
|
FileInformationClass =
|
|
|
|
IrpContext->Stack->Parameters.SetFile.FileInformationClass;
|
|
|
|
FCB = (PVFATFCB) IrpContext->FileObject->FsContext;
|
|
|
|
SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
|
|
|
|
DPRINT("VfatSetInformation is called for '%s'\n",
|
|
|
|
FileInformationClass >= FileMaximumInformation - 1 ? "????" : FileInformationClassNames[ FileInformationClass]);
|
|
|
|
|
|
|
|
DPRINT("FileInformationClass %d\n", FileInformationClass);
|
|
|
|
DPRINT("SystemBuffer %p\n", SystemBuffer);
|
|
|
|
|
2016-11-23 18:21:03 +00:00
|
|
|
if (FCB == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("IRP_MJ_SET_INFORMATION without FCB!\n");
|
|
|
|
IrpContext->Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
/* Special: We should call MmCanFileBeTruncated here to determine if changing
|
|
|
|
the file size would be allowed. If not, we bail with the right error.
|
|
|
|
We must do this before acquiring the lock. */
|
|
|
|
if (FileInformationClass == FileEndOfFileInformation)
|
|
|
|
{
|
|
|
|
DPRINT("Check for the ability to set file size\n");
|
|
|
|
if (!MmCanFileBeTruncated(IrpContext->FileObject->SectionObjectPointer,
|
|
|
|
(PLARGE_INTEGER)SystemBuffer))
|
|
|
|
{
|
|
|
|
DPRINT("Couldn't set file size!\n");
|
|
|
|
IrpContext->Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_USER_MAPPED_FILE;
|
|
|
|
}
|
|
|
|
DPRINT("Can set file size\n");
|
|
|
|
}
|
|
|
|
|
2018-05-26 15:12:03 +00:00
|
|
|
LockDir = FALSE;
|
|
|
|
if (FileInformationClass == FileRenameInformation || FileInformationClass == FileAllocationInformation ||
|
|
|
|
FileInformationClass == FileEndOfFileInformation || FileInformationClass == FileBasicInformation)
|
|
|
|
{
|
|
|
|
LockDir = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LockDir)
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
{
|
|
|
|
if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource,
|
2015-05-25 17:30:01 +00:00
|
|
|
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
{
|
2015-05-15 16:03:29 +00:00
|
|
|
return VfatMarkIrpContextForQueue(IrpContext);
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-17 11:38:05 +00:00
|
|
|
if (!BooleanFlagOn(FCB->Flags, FCB_IS_PAGE_FILE))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
if (!ExAcquireResourceExclusiveLite(&FCB->MainResource,
|
2015-05-25 17:30:01 +00:00
|
|
|
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
2018-05-26 15:12:03 +00:00
|
|
|
if (LockDir)
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
{
|
|
|
|
ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
|
|
|
|
}
|
2015-05-15 16:03:29 +00:00
|
|
|
|
|
|
|
return VfatMarkIrpContextForQueue(IrpContext);
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (FileInformationClass)
|
|
|
|
{
|
|
|
|
case FilePositionInformation:
|
2013-12-09 12:55:23 +00:00
|
|
|
Status = VfatSetPositionInformation(IrpContext->FileObject,
|
|
|
|
SystemBuffer);
|
2013-12-09 10:35:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FileDispositionInformation:
|
2013-12-09 12:55:23 +00:00
|
|
|
Status = VfatSetDispositionInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
2017-06-26 18:10:43 +00:00
|
|
|
IrpContext->DeviceExt,
|
2013-12-09 12:55:23 +00:00
|
|
|
SystemBuffer);
|
2013-12-09 10:35:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FileAllocationInformation:
|
|
|
|
case FileEndOfFileInformation:
|
2013-12-09 12:55:23 +00:00
|
|
|
Status = VfatSetAllocationSizeInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
|
|
|
IrpContext->DeviceExt,
|
|
|
|
(PLARGE_INTEGER)SystemBuffer);
|
2013-12-09 10:35:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FileBasicInformation:
|
2013-12-09 12:55:23 +00:00
|
|
|
Status = VfatSetBasicInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
|
|
|
IrpContext->DeviceExt,
|
|
|
|
SystemBuffer);
|
2013-12-09 10:35:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FileRenameInformation:
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
Status = VfatSetRenameInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
|
|
|
IrpContext->DeviceExt,
|
|
|
|
SystemBuffer,
|
|
|
|
IrpContext->Stack->Parameters.SetFile.FileObject);
|
2013-12-09 10:35:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2013-12-09 12:55:23 +00:00
|
|
|
Status = STATUS_NOT_SUPPORTED;
|
2013-12-09 10:35:15 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 11:38:05 +00:00
|
|
|
if (!BooleanFlagOn(FCB->Flags, FCB_IS_PAGE_FILE))
|
2013-12-09 10:35:15 +00:00
|
|
|
{
|
|
|
|
ExReleaseResourceLite(&FCB->MainResource);
|
|
|
|
}
|
|
|
|
|
2018-05-26 15:12:03 +00:00
|
|
|
if (LockDir)
|
[FASTFAT]
- Implement vfatPrepareTargetForRename() that prepares for renaming. It tries to open target and deletes it if it exists and if allowed. And then, it opens the parent directory.
- Implement VfatSetRenameInformation() that actually does the renaming (call as SetInformationFile). It handles cases we we have (or we don't have) TargetDirectory provided. It sends notifications as appropriated on demands.
- Implement vfatRenameEntry() that renames an entry in place. So far, it only supports FATX entries renaming. FAT entries are a bit more complex. It falls back to vfatMoveEntry() in later cases.
- Implement VfatMoveEntry() that will move an entry accross directories (or in place for FAT). Its principles are simple: it deletes the entry in old parent, and recreate it in new parent, keeping file metadata & data.
- Modify VfatDelEntry() and VfatAddEntry() so that they can handle deleting an entry without touching its data and adding an entry with an already provided FCB and thus use the given metadata.
- Implement vfatDelFCBFromTable() which is just old code moved to new routine to allow reuse. It deletes a FCB entry from hash table. Doesn't deal with references!
- Implement vfatMakeFullName() which is mostly old code moved to new routine to allow reuse. It allocates buffer and copy data for FCB full name.
- Implement vfatUpdateFCB() that will update a FCB with new names and parent. It will remove anything related to old name and will recreate using new data. It will adjust references count.
- Modify vfatMakeFCBFromDirEntry() so that it calls vfatMakeFullName().
- Modify vfatReleaseFCB() so that it calls vfatDelFCBFromTable().
- Revert VfatOpenFile() to its previous features.
- Modify VfatCreateFile() to reimplement support for SL_OPEN_TARGET_DIRECTORY. It is way less hackish than previously. It also properly opens parent now, by incrementing its handle count and by setting appropriate access rights.
[KERNEL32]
- Rewritten MoveFileWithProgressW() to implement all the missing features that are used in Windows 2k3 including links and reparse points.
- Implemented BasepMoveFileDelayed() to replace deprecated add_boot_rename_entry(). This functions is matching the features implemented in SMSS.
- Implemented BasepMoveFileCopyProgress() which is used in MoveFileWithProgressW().
- Stubbed BasepNotifyTrackingService() which is not use at the moment (FastFAT, even in Windows doesn't provide such feature).
- Reimplemented ReplaceFileA(), MoveFileWithProgressA() to quit Winisms and use our internal helpers.
- Make MoveFileX() use MoveFileWithProgressX() directly.
- Fixed a few prototypes.
TL;DR:
This (huge) commit implements file and directory renaming in FastFAT driver. This allows getting rid of old implementation in kernel32 where files were force copied.
A feature is still missing, but Jérôme should implement it anytime soon (he prototyped it already): moving directories across volumes. This requires some work in BasepCopyFileExW().
Kudos to all the devs who helped me on this: Christoph, Hervé, Jérôme, Thomas.
This finally allows killing CR-52... It was about time!
svn path=/trunk/; revision=64836
2014-10-19 21:38:32 +00:00
|
|
|
{
|
|
|
|
ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
|
|
|
|
}
|
|
|
|
|
2013-12-09 10:35:15 +00:00
|
|
|
IrpContext->Irp->IoStatus.Information = 0;
|
2013-12-09 12:55:23 +00:00
|
|
|
return Status;
|
2000-12-29 23:17:12 +00:00
|
|
|
}
|
2001-06-12 12:35:42 +00:00
|
|
|
|
|
|
|
/* EOF */
|