Author: pschweitzer
Date: Sun May 31 21:28:52 2015
New Revision: 67983
URL:
http://svn.reactos.org/svn/reactos?rev=67983&view=rev
Log:
[NTFS]
Directly implement NtfsOpenFileById() for special files from the MFT where we cannot
moonwalk there path.
It concerns any file with ID < 0x10.
This function can only cope with file which ID is < 0xc. Windows Internals reports that
0xc - 0xf entries are unused.
It would be interesting to double check returrned status in case of error, and also what
Windows returns when attempting weird opening of suchs entries (overwrite, create for
unused, etc).
Modified:
trunk/reactos/drivers/filesystems/ntfs/create.c
trunk/reactos/drivers/filesystems/ntfs/ntfs.h
Modified: trunk/reactos/drivers/filesystems/ntfs/create.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/ntfs/c…
==============================================================================
--- trunk/reactos/drivers/filesystems/ntfs/create.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/ntfs/create.c [iso-8859-1] Sun May 31 21:28:52 2015
@@ -31,6 +31,21 @@
#define NDEBUG
#include <debug.h>
+static PCWSTR MftIdToName[] = {
+ L"$MFT",
+ L"$MFTMirr",
+ L"$LogFile",
+ L"$Volume",
+ L"AttrDef",
+ L".",
+ L"$Bitmap",
+ L"$Boot",
+ L"$BadClus",
+ L"$Quota",
+ L"$UpCase",
+ L"$Extended",
+};
+
/* FUNCTIONS ****************************************************************/
static
@@ -153,6 +168,72 @@
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(OutPath->Buffer, FullPath + WritePosition,
OutPath->MaximumLength);
+
+ return Status;
+}
+
+static
+NTSTATUS
+NtfsOpenFileById(PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject,
+ ULONGLONG MftId,
+ PNTFS_FCB * FoundFCB)
+{
+ NTSTATUS Status;
+ PNTFS_FCB FCB;
+ PFILE_RECORD_HEADER MftRecord;
+
+ DPRINT1("NtfsOpenFileById(%p, %p, %I64x, %p)\n", DeviceExt, FileObject,
MftId, FoundFCB);
+
+ ASSERT(MftId < 0x10);
+ if (MftId > 0xb) /* No entries are used yet beyond this */
+ {
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ MftRecord = ExAllocatePoolWithTag(NonPagedPool,
+ DeviceExt->NtfsInfo.BytesPerFileRecord,
+ TAG_NTFS);
+ if (MftRecord == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = ReadFileRecord(DeviceExt, MftId, MftRecord);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(MftRecord, TAG_NTFS);
+ return Status;
+ }
+
+ if (!(MftRecord->Flags & FRH_IN_USE))
+ {
+ ExFreePoolWithTag(MftRecord, TAG_NTFS);
+ return STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+
+ FCB = NtfsGrabFCBFromTable(DeviceExt, MftIdToName[MftId]);
+ if (FCB == NULL)
+ {
+ UNICODE_STRING Name;
+
+ RtlInitUnicodeString(&Name, MftIdToName[MftId]);
+ Status = NtfsMakeFCBFromDirEntry(DeviceExt, NULL, &Name, MftRecord, MftId,
&FCB);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(MftRecord, TAG_NTFS);
+ return Status;
+ }
+ }
+
+ ASSERT(FCB != NULL);
+
+ ExFreePoolWithTag(MftRecord, TAG_NTFS);
+
+ Status = NtfsAttachFCBToFileObject(DeviceExt,
+ FCB,
+ FileObject);
+ *FoundFCB = FCB;
return Status;
}
@@ -249,7 +330,7 @@
PFILE_OBJECT FileObject;
ULONG RequestedDisposition;
ULONG RequestedOptions;
- PNTFS_FCB Fcb;
+ PNTFS_FCB Fcb = NULL;
// PWSTR FileName;
NTSTATUS Status;
UNICODE_STRING FullPath;
@@ -287,13 +368,15 @@
return STATUS_INVALID_PARAMETER;
MFTId = (*(PULONGLONG)FileObject->FileName.Buffer) & NTFS_MFT_MASK;
- if (MFTId < 0xf)
- {
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
- }
-
- Status = NtfsMoonWalkID(DeviceExt, MFTId, &FullPath);
+ if (MFTId < 0x10)
+ {
+ Status = NtfsOpenFileById(DeviceExt, FileObject, MFTId, &Fcb);
+ }
+ else
+ {
+ Status = NtfsMoonWalkID(DeviceExt, MFTId, &FullPath);
+ }
+
if (!NT_SUCCESS(Status))
{
return Status;
@@ -324,14 +407,17 @@
return STATUS_SUCCESS;
}
- Status = NtfsOpenFile(DeviceExt,
- FileObject,
- ((RequestedOptions & FILE_OPEN_BY_FILE_ID) ?
FullPath.Buffer : FileObject->FileName.Buffer),
- &Fcb);
-
- if (RequestedOptions & FILE_OPEN_BY_FILE_ID)
- {
- ExFreePoolWithTag(FullPath.Buffer, TAG_NTFS);
+ if (Fcb == NULL)
+ {
+ Status = NtfsOpenFile(DeviceExt,
+ FileObject,
+ ((RequestedOptions & FILE_OPEN_BY_FILE_ID) ?
FullPath.Buffer : FileObject->FileName.Buffer),
+ &Fcb);
+
+ if (RequestedOptions & FILE_OPEN_BY_FILE_ID)
+ {
+ ExFreePoolWithTag(FullPath.Buffer, TAG_NTFS);
+ }
}
if (NT_SUCCESS(Status))
Modified: trunk/reactos/drivers/filesystems/ntfs/ntfs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/ntfs/n…
==============================================================================
--- trunk/reactos/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] Sun May 31 21:28:52 2015
@@ -643,6 +643,14 @@
ULONG NameLength,
PVOID * Data);
+NTSTATUS
+NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb,
+ PNTFS_FCB DirectoryFCB,
+ PUNICODE_STRING Name,
+ PFILE_RECORD_HEADER Record,
+ ULONGLONG MFTIndex,
+ PNTFS_FCB * fileFCB);
+
/* finfo.c */