Author: pschweitzer
Date: Sat Feb 14 15:35:35 2015
New Revision: 66264
URL:
http://svn.reactos.org/svn/reactos?rev=66264&view=rev
Log:
[NTFS]
Simplify the implementation of the "Open by ID" feature of our driver.
Instead of creating singleton FCB not linked to the rest of FS tree, just walk the whole
path down, to recreate it.
This doesn't make nfi work properly though. Will investigate more.
CORE-8725
Modified:
trunk/reactos/drivers/filesystems/ntfs/create.c
trunk/reactos/drivers/filesystems/ntfs/fcb.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] Sat Feb 14 15:35:35 2015
@@ -46,6 +46,18 @@
Fcb = pFileObject->FsContext;
ASSERT(Fcb);
+ if (Fcb->Flags & FCB_IS_VOLUME)
+ {
+ /* This is likely to be an opening by ID, return ourselves */
+ if (pRelativeFileName[0] == L'\\')
+ {
+ *pAbsoluteFilename = NULL;
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_INVALID_PARAMETER;
+ }
+
/* verify related object is a directory and target name
don't start with \. */
if (NtfsFCBIsDirectory(Fcb) == FALSE ||
@@ -71,6 +83,66 @@
return STATUS_SUCCESS;
}
+
+static
+NTSTATUS
+NtfsMoonWalkID(PDEVICE_EXTENSION DeviceExt,
+ ULONGLONG Id,
+ PUNICODE_STRING OutPath)
+{
+ NTSTATUS Status;
+ PFILE_RECORD_HEADER MftRecord;
+ PFILENAME_ATTRIBUTE FileName;
+ WCHAR FullPath[MAX_PATH];
+ ULONG WritePosition = MAX_PATH - 1;
+
+ DPRINT1("NtfsMoonWalkID(%p, %I64x, %p)\n", DeviceExt, Id, OutPath);
+
+ Id = Id & NTFS_MFT_MASK;
+
+ RtlZeroMemory(FullPath, sizeof(FullPath));
+ MftRecord = ExAllocatePoolWithTag(NonPagedPool,
+ DeviceExt->NtfsInfo.BytesPerFileRecord,
+ TAG_NTFS);
+ if (MftRecord == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ while (TRUE)
+ {
+ Status = ReadFileRecord(DeviceExt, Id, MftRecord);
+ if (!NT_SUCCESS(Status))
+ break;
+
+ ASSERT(MftRecord->Ntfs.Type == NRH_FILE_TYPE);
+
+ FileName = GetBestFileNameFromRecord(MftRecord);
+ WritePosition -= FileName->NameLength;
+ ASSERT(WritePosition < MAX_PATH);
+ RtlCopyMemory(FullPath + WritePosition, FileName->Name,
FileName->NameLength * sizeof(WCHAR));
+ WritePosition -= 1;
+ ASSERT(WritePosition < MAX_PATH);
+ FullPath[WritePosition] = L'\\';
+
+ Id = FileName->DirectoryFileReferenceNumber & NTFS_MFT_MASK;
+ if (Id == NTFS_FILE_ROOT)
+ break;
+ }
+
+ ExFreePoolWithTag(MftRecord, TAG_NTFS);
+
+ OutPath->Length = (MAX_PATH - WritePosition - 1) * sizeof(WCHAR);
+ OutPath->MaximumLength = (MAX_PATH - WritePosition) * sizeof(WCHAR);
+ OutPath->Buffer = ExAllocatePoolWithTag(NonPagedPool, OutPath->MaximumLength,
TAG_NTFS);
+ if (OutPath->Buffer == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlCopyMemory(OutPath->Buffer, FullPath + WritePosition,
OutPath->MaximumLength);
+
+ return Status;
+}
/*
* FUNCTION: Opens a file
@@ -80,7 +152,6 @@
NtfsOpenFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PWSTR FileName,
- BOOLEAN OpenById,
PNTFS_FCB * FoundFCB)
{
PNTFS_FCB ParentFcb;
@@ -88,81 +159,53 @@
NTSTATUS Status;
PWSTR AbsFileName = NULL;
- DPRINT1("NtfsOpenFile(%p, %p, %S, %u, %p)\n", DeviceExt, FileObject,
(!OpenById ? FileName : NULL), OpenById, FoundFCB);
+ DPRINT1("NtfsOpenFile(%p, %p, %S, %p)\n", DeviceExt, FileObject, FileName,
FoundFCB);
*FoundFCB = NULL;
- if (OpenById)
- {
- ULONGLONG Id = (*(PULONGLONG)FileName) & NTFS_MFT_MASK;
-
- DPRINT1("Will attempt to open by id: %I64x\n", Id);
-
- Fcb = NtfsGrabFCBFromTableById(DeviceExt,
- Id);
- if (Fcb == NULL)
- {
- Status = NtfsGetFCBForFileById(DeviceExt,
- &Fcb,
- Id);
- if (!NT_SUCCESS (Status))
- {
- DPRINT("Could not make a new FCB, status: %x\n", Status);
-
- return Status;
- }
-
- Fcb->Flags |= FCB_IS_OPEN_BY_ID;
- }
- }
- else
- {
- if (FileObject->RelatedFileObject)
- {
- DPRINT("Converting relative filename to absolute filename\n");
-
- Status = NtfsMakeAbsoluteFilename(FileObject->RelatedFileObject,
- FileName,
- &AbsFileName);
- FileName = AbsFileName;
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- return STATUS_UNSUCCESSFUL;
- }
-
- //FIXME: Get cannonical path name (remove .'s, ..'s and extra
separators)
-
- DPRINT("PathName to open: %S\n", FileName);
-
- /* try first to find an existing FCB in memory */
- DPRINT("Checking for existing FCB in memory\n");
- Fcb = NtfsGrabFCBFromTable(DeviceExt,
+ if (FileObject->RelatedFileObject)
+ {
+ DPRINT("Converting relative filename to absolute filename\n");
+
+ Status = NtfsMakeAbsoluteFilename(FileObject->RelatedFileObject,
+ FileName,
+ &AbsFileName);
+ if (AbsFileName) FileName = AbsFileName;
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ //FIXME: Get cannonical path name (remove .'s, ..'s and extra separators)
+
+ DPRINT("PathName to open: %S\n", FileName);
+
+ /* try first to find an existing FCB in memory */
+ DPRINT("Checking for existing FCB in memory\n");
+ Fcb = NtfsGrabFCBFromTable(DeviceExt,
+ FileName);
+ if (Fcb == NULL)
+ {
+ DPRINT("No existing FCB found, making a new one if file exists.\n");
+ Status = NtfsGetFCBForFile(DeviceExt,
+ &ParentFcb,
+ &Fcb,
FileName);
- if (Fcb == NULL)
- {
- DPRINT("No existing FCB found, making a new one if file
exists.\n");
- Status = NtfsGetFCBForFile(DeviceExt,
- &ParentFcb,
- &Fcb,
- FileName);
- if (ParentFcb != NULL)
- {
- NtfsReleaseFCB(DeviceExt,
- ParentFcb);
- }
-
- if (!NT_SUCCESS (Status))
- {
- DPRINT("Could not make a new FCB, status: %x\n", Status);
-
- if (AbsFileName)
- ExFreePool(AbsFileName);
-
- return Status;
- }
+ if (ParentFcb != NULL)
+ {
+ NtfsReleaseFCB(DeviceExt,
+ ParentFcb);
+ }
+
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT("Could not make a new FCB, status: %x\n", Status);
+
+ if (AbsFileName)
+ ExFreePool(AbsFileName);
+
+ return Status;
}
}
@@ -196,6 +239,7 @@
PNTFS_FCB Fcb;
// PWSTR FileName;
NTSTATUS Status;
+ UNICODE_STRING FullPath;
DPRINT1("NtfsCreateFile(%p, %p) called\n", DeviceObject, Irp);
@@ -213,12 +257,6 @@
return STATUS_INVALID_PARAMETER;
}
- if (RequestedOptions & FILE_OPEN_BY_FILE_ID)
- {
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
- }
-
FileObject = Stack->FileObject;
if (RequestedDisposition == FILE_CREATE ||
@@ -228,10 +266,18 @@
return STATUS_ACCESS_DENIED;
}
- if ((RequestedOptions & FILE_OPEN_BY_FILE_ID) == FILE_OPEN_BY_FILE_ID &&
- FileObject->FileName.Length != sizeof(ULONGLONG))
- {
- return STATUS_INVALID_PARAMETER;
+ if ((RequestedOptions & FILE_OPEN_BY_FILE_ID) == FILE_OPEN_BY_FILE_ID)
+ {
+ if (FileObject->FileName.Length != sizeof(ULONGLONG))
+ return STATUS_INVALID_PARAMETER;
+
+ Status = NtfsMoonWalkID(DeviceExt, (*(PULONGLONG)FileObject->FileName.Buffer),
&FullPath);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ DPRINT1("Open by ID: %I64x -> %wZ\n",
(*(PULONGLONG)FileObject->FileName.Buffer) & NTFS_MFT_MASK, &FullPath);
}
/* This a open operation for the volume itself */
@@ -258,9 +304,13 @@
Status = NtfsOpenFile(DeviceExt,
FileObject,
- FileObject->FileName.Buffer,
- ((RequestedOptions & FILE_OPEN_BY_FILE_ID) ==
FILE_OPEN_BY_FILE_ID),
+ ((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/fcb.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/ntfs/f…
==============================================================================
--- trunk/reactos/drivers/filesystems/ntfs/fcb.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/ntfs/fcb.c [iso-8859-1] Sat Feb 14 15:35:35 2015
@@ -220,8 +220,7 @@
Fcb = CONTAINING_RECORD(current_entry, NTFS_FCB, FcbListEntry);
DPRINT("Comparing '%S' and '%S'\n", FileName,
Fcb->PathName);
- if ((Fcb->Flags & FCB_IS_OPEN_BY_ID) != FCB_IS_OPEN_BY_ID &&
- _wcsicmp(FileName, Fcb->PathName) == 0)
+ if (_wcsicmp(FileName, Fcb->PathName) == 0)
{
Fcb->RefCount++;
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
@@ -229,38 +228,6 @@
}
//FIXME: need to compare against short name in FCB here
-
- current_entry = current_entry->Flink;
- }
-
- KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
-
- return NULL;
-}
-
-
-PNTFS_FCB
-NtfsGrabFCBFromTableById(PNTFS_VCB Vcb,
- ULONGLONG Id)
-{
- KIRQL oldIrql;
- PNTFS_FCB Fcb;
- PLIST_ENTRY current_entry;
-
- KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
-
- current_entry = Vcb->FcbListHead.Flink;
- while (current_entry != &Vcb->FcbListHead)
- {
- Fcb = CONTAINING_RECORD(current_entry, NTFS_FCB, FcbListEntry);
-
- if ((Fcb->Flags & FCB_IS_OPEN_BY_ID) == FCB_IS_OPEN_BY_ID &&
- Fcb->MFTIndex == Id)
- {
- Fcb->RefCount++;
- KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
- return Fcb;
- }
current_entry = current_entry->Flink;
}
@@ -698,42 +665,6 @@
NTSTATUS
-NtfsGetFCBForFileById(PNTFS_VCB Vcb,
- PNTFS_FCB *pFCB,
- ULONGLONG Id)
-{
- NTSTATUS Status;
- PFILE_RECORD_HEADER FileRecord;
-
- FileRecord = ExAllocatePoolWithTag(NonPagedPool,
- Vcb->NtfsInfo.BytesPerFileRecord,
- TAG_NTFS);
- if (FileRecord == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Status = ReadFileRecord(Vcb, Id, FileRecord);
- if (!NT_SUCCESS(Status))
- {
- ExFreePoolWithTag(FileRecord, TAG_NTFS);
- return Status;
- }
-
- if ((FileRecord->Flags & FRH_IN_USE) != FRH_IN_USE)
- {
- ExFreePoolWithTag(FileRecord, TAG_NTFS);
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = NtfsMakeFCBFromDirEntry(Vcb, NULL, NULL, FileRecord, Id, pFCB);
-
- ExFreePoolWithTag(FileRecord, TAG_NTFS);
-
- return Status;
-}
-
-NTSTATUS
NtfsReadFCBAttribute(PNTFS_VCB Vcb,
PNTFS_FCB pFCB,
ULONG Type,
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] Sat Feb 14 15:35:35 2015
@@ -416,7 +416,6 @@
#define FCB_CACHE_INITIALIZED 0x0001
#define FCB_IS_VOLUME_STREAM 0x0002
#define FCB_IS_VOLUME 0x0004
-#define FCB_IS_OPEN_BY_ID 0x0008
#define MAX_PATH 260
typedef struct _FCB
@@ -601,10 +600,6 @@
NtfsGrabFCBFromTable(PNTFS_VCB Vcb,
PCWSTR FileName);
-PNTFS_FCB
-NtfsGrabFCBFromTableById(PNTFS_VCB Vcb,
- ULONGLONG Id);
-
NTSTATUS
NtfsFCBInitializeCache(PNTFS_VCB Vcb,
PNTFS_FCB Fcb);
@@ -625,11 +620,6 @@
PNTFS_FCB *pParentFCB,
PNTFS_FCB *pFCB,
const PWSTR pFileName);
-
-NTSTATUS
-NtfsGetFCBForFileById(PNTFS_VCB Vcb,
- PNTFS_FCB *pFCB,
- ULONGLONG Id);
NTSTATUS
NtfsReadFCBAttribute(PNTFS_VCB Vcb,