[NTFS]
authorPierre Schweitzer <pierre@reactos.org>
Wed, 8 Oct 2014 19:12:48 +0000 (19:12 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Wed, 8 Oct 2014 19:12:48 +0000 (19:12 +0000)
- Remove magic value usage in NtfsDumpFileAttributes()
- Implement GetFileNameFromRecord() which returns the $FILE_NAME attribute from a FILE record
- On record lookup, also return the MFT index of the found record
- Finally implement NtfsMakeFCBFromDirEntry() which allows creating a FCB from a dir entry. It is still incomplete though, it doesn't copy any data yet from the entry

svn path=/trunk/; revision=64610

reactos/drivers/filesystems/ntfs/attrib.c
reactos/drivers/filesystems/ntfs/fcb.c
reactos/drivers/filesystems/ntfs/mft.c
reactos/drivers/filesystems/ntfs/ntfs.h

index 572f6aa..aa52547 100644 (file)
@@ -278,7 +278,7 @@ NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord)
 
     Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
     while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
-           Attribute->Type != (ATTRIBUTE_TYPE)-1)
+           Attribute->Type != AttributeEnd)
     {
         NtfsDumpAttribute(Attribute);
 
@@ -286,4 +286,22 @@ NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord)
     }
 }
 
+PFILENAME_ATTRIBUTE
+GetFileNameFromRecord(PFILE_RECORD_HEADER FileRecord)
+{
+    PNTFS_ATTR_RECORD Attribute;
+
+    Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
+    while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
+           Attribute->Type != AttributeEnd)
+    {
+        if (Attribute->Type == AttributeFileName)
+            return (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
+
+        Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length);
+    }
+
+    return NULL;
+}
+
 /* EOF */
index 0c3a6ae..f023535 100644 (file)
@@ -354,57 +354,53 @@ NtfsGetDirEntryName(PDEVICE_EXTENSION DeviceExt,
 NTSTATUS
 NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb,
                        PNTFS_FCB DirectoryFCB,
-                       PWSTR Name,
+                       PUNICODE_STRING Name,
                        PFILE_RECORD_HEADER Record,
+                        ULONGLONG MFTIndex,
                        PNTFS_FCB * fileFCB)
 {
-#if 0
-  WCHAR pathName[MAX_PATH];
-  PFCB rcFCB;
-  ULONG Size;
+    WCHAR pathName[MAX_PATH];
+    PFILENAME_ATTRIBUTE FileName;
+    PNTFS_FCB rcFCB;
+
+    DPRINT1("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p)\n", Vcb, DirectoryFCB, Name, Record, fileFCB);
 
-  if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) +
-        sizeof(WCHAR) + wcslen (Name) > MAX_PATH)
+    FileName = GetFileNameFromRecord(Record);
+    if (!FileName)
     {
-      return(STATUS_OBJECT_NAME_INVALID);
+        return STATUS_OBJECT_NAME_NOT_FOUND; // Not sure that's the best here
     }
 
-  wcscpy(pathName, DirectoryFCB->PathName);
-  if (!NtfsFCBIsRoot(DirectoryFCB))
+    if (Name->Buffer[0] != 0 && wcslen(DirectoryFCB->PathName) +
+        sizeof(WCHAR) + Name->Length / sizeof(WCHAR) > MAX_PATH)
     {
-      wcscat(pathName, L"\\");
+        return STATUS_OBJECT_NAME_INVALID;
     }
 
-  if (Name[0] != 0)
+    wcscpy(pathName, DirectoryFCB->PathName);
+    if (!NtfsFCBIsRoot(DirectoryFCB))
     {
-      wcscat(pathName, Name);
+        wcscat(pathName, L"\\");
     }
-  else
-    {
-      WCHAR entryName[MAX_PATH];
+    wcscat(pathName, Name->Buffer);
 
-      NtfsGetDirEntryName(Vcb, Record, entryName);
-      wcscat(pathName, entryName);
+    rcFCB = NtfsCreateFCB(pathName, Vcb);
+    if (!rcFCB)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-  rcFCB = NtfsCreateFCB(pathName, Vcb);
-  memcpy(&rcFCB->Entry, Record, sizeof(DIR_RECORD));
-
-  Size = rcFCB->Entry.DataLengthL;
+    rcFCB->RFCB.FileSize.QuadPart = FileName->DataSize;
+    rcFCB->RFCB.ValidDataLength.QuadPart = FileName->DataSize;
+    rcFCB->RFCB.AllocationSize.QuadPart = FileName->AllocatedSize;
 
-  rcFCB->RFCB.FileSize.QuadPart = Size;
-  rcFCB->RFCB.ValidDataLength.QuadPart = Size;
-  rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, BLOCKSIZE);
-//  DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart);
-  NtfsFCBInitializeCache(Vcb, rcFCB);
-  rcFCB->RefCount++;
-  NtfsAddFCBToTable(Vcb, rcFCB);
-  *fileFCB = rcFCB;
+    NtfsFCBInitializeCache(Vcb, rcFCB);
+    rcFCB->RefCount = 1;
+    rcFCB->MFTIndex = MFTIndex;
+    NtfsAddFCBToTable(Vcb, rcFCB);
+    *fileFCB = rcFCB;
 
-  return(STATUS_SUCCESS);
-#else
-  return STATUS_NOT_IMPLEMENTED;
-#endif
+    return STATUS_SUCCESS;
 }
 
 
@@ -460,18 +456,21 @@ NtfsDirFindFile(PNTFS_VCB Vcb,
     UNICODE_STRING File;
     PFILE_RECORD_HEADER FileRecord;
     PNTFS_ATTR_CONTEXT DataContext;
+    ULONGLONG MFTIndex;
+
+    DPRINT1("NtfsDirFindFile(%p, %p, %S, %p)\n", Vcb, DirectoryFcb, FileToFind, FoundFCB);
 
     *FoundFCB = NULL;
     RtlInitUnicodeString(&File, FileToFind);
     CurrentDir = DirectoryFcb->MFTIndex;
 
-    Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &DataContext, CurrentDir);
+    Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &DataContext, &MFTIndex, CurrentDir);
     if (!NT_SUCCESS(Status))
     {
         return Status;
     }
 
-    Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, FileToFind, FileRecord, FoundFCB);
+    Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, &File, FileRecord, MFTIndex, FoundFCB);
     ExFreePoolWithTag(FileRecord, TAG_NTFS);
 
     return Status;
index 3ab7f37..b27cfd6 100644 (file)
@@ -649,6 +649,7 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
                  PUNICODE_STRING PathName,
                  PFILE_RECORD_HEADER *FileRecord,
                  PNTFS_ATTR_CONTEXT *DataContext,
+                 PULONGLONG MFTIndex,
                  ULONGLONG CurrentMFTIndex)
 {
     UNICODE_STRING Current, Remaining;
@@ -694,6 +695,8 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
         return Status;
     }
 
+    *MFTIndex = CurrentMFTIndex;
+
     return STATUS_SUCCESS;
 }
 
@@ -701,8 +704,9 @@ NTSTATUS
 NtfsLookupFile(PDEVICE_EXTENSION Vcb,
                PUNICODE_STRING PathName,
                PFILE_RECORD_HEADER *FileRecord,
-               PNTFS_ATTR_CONTEXT *DataContext)
+               PNTFS_ATTR_CONTEXT *DataContext,
+               PULONGLONG MFTIndex)
 {
-    return NtfsLookupFileAt(Vcb, PathName, FileRecord, DataContext, NTFS_FILE_ROOT);
+    return NtfsLookupFileAt(Vcb, PathName, FileRecord, DataContext, MFTIndex, NTFS_FILE_ROOT);
 }
 /* EOF */
index 22cadd4..fd174a3 100644 (file)
@@ -433,6 +433,8 @@ DecodeRun(PUCHAR DataRun,
 VOID
 NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord);
 
+PFILENAME_ATTRIBUTE
+GetFileNameFromRecord(PFILE_RECORD_HEADER FileRecord);
 
 /* blockdev.c */
 
@@ -632,13 +634,15 @@ NTSTATUS
 NtfsLookupFile(PDEVICE_EXTENSION Vcb,
                PUNICODE_STRING PathName,
                PFILE_RECORD_HEADER *FileRecord,
-               PNTFS_ATTR_CONTEXT *DataContext);
+               PNTFS_ATTR_CONTEXT *DataContext,
+               PULONGLONG MFTIndex);
 
 NTSTATUS
 NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
                  PUNICODE_STRING PathName,
                  PFILE_RECORD_HEADER *FileRecord,
                  PNTFS_ATTR_CONTEXT *DataContext,
+                 PULONGLONG MFTIndex,
                  ULONGLONG CurrentMFTIndex);
 
 /* misc.c */