[NTFS]
[reactos.git] / reactos / drivers / filesystems / ntfs / fcb.c
index 0c3a6ae..d1c1591 100644 (file)
@@ -118,10 +118,7 @@ NtfsDestroyFCB(PNTFS_FCB Fcb)
 BOOLEAN
 NtfsFCBIsDirectory(PNTFS_FCB Fcb)
 {
-    UNREFERENCED_PARAMETER(Fcb);
-//  return(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY);
-//  return(Fcb->Entry.FileFlags & 0x02);
-    return TRUE;
+    return ((Fcb->Entry.FileAttributes & NTFS_FILE_TYPE_DIRECTORY) == NTFS_FILE_TYPE_DIRECTORY);
 }
 
 
@@ -275,19 +272,43 @@ PNTFS_FCB
 NtfsMakeRootFCB(PNTFS_VCB Vcb)
 {
     PNTFS_FCB Fcb;
+    PFILE_RECORD_HEADER MftRecord;
+    PFILENAME_ATTRIBUTE FileName;
 
-    Fcb = NtfsCreateFCB(L"\\", Vcb);
+    MftRecord = ExAllocatePoolWithTag(NonPagedPool,
+                                      Vcb->NtfsInfo.BytesPerFileRecord,
+                                      TAG_NTFS);
+    if (MftRecord == NULL)
+    {
+        return NULL;
+    }
 
-//    memset(Fcb->entry.Filename, ' ', 11);
+    if (!NT_SUCCESS(ReadFileRecord(Vcb, NTFS_FILE_ROOT, MftRecord)))
+    {
+        return NULL;
+    }
+
+    FileName = GetFileNameFromRecord(MftRecord);
+    if (!FileName)
+    {
+        return NULL;
+    }
+
+    Fcb = NtfsCreateFCB(L"\\", Vcb);
+    if (!Fcb)
+    {
+        return NULL;
+    }
 
-//    Fcb->Entry.DataLengthL = Vcb->CdInfo.RootSize;
-//    Fcb->Entry.ExtentLocationL = Vcb->CdInfo.RootStart;
-//    Fcb->Entry.FileFlags = 0x02; // FILE_ATTRIBUTE_DIRECTORY;
+    memcpy(&Fcb->Entry, FileName, FIELD_OFFSET(FILENAME_ATTRIBUTE, NameLength));
+    Fcb->Entry.NameType = FileName->NameType;
+    Fcb->Entry.NameLength = 0;
+    Fcb->Entry.Name[0] = UNICODE_NULL;
     Fcb->RefCount = 1;
     Fcb->DirIndex = 0;
-    Fcb->RFCB.FileSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
-    Fcb->RFCB.ValidDataLength.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
-    Fcb->RFCB.AllocationSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
+    Fcb->RFCB.FileSize.QuadPart = FileName->DataSize;
+    Fcb->RFCB.ValidDataLength.QuadPart = FileName->DataSize;
+    Fcb->RFCB.AllocationSize.QuadPart = FileName->AllocatedSize;
     Fcb->MFTIndex = NTFS_FILE_ROOT;
 
     NtfsFCBInitializeCache(Vcb, Fcb);
@@ -354,57 +375,55 @@ 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;
 
-  if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) +
-        sizeof(WCHAR) + wcslen (Name) > MAX_PATH)
+    DPRINT1("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p)\n", Vcb, DirectoryFCB, Name, Record, fileFCB);
+
+    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;
+    memcpy(&rcFCB->Entry, FileName, FIELD_OFFSET(FILENAME_ATTRIBUTE, NameLength));
+    rcFCB->Entry.NameType = FileName->NameType;
+    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 +479,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;