[NTFS]
[reactos.git] / reactos / drivers / filesystems / ntfs / dirctl.c
index 632d58f..53e70ba 100644 (file)
 /* FUNCTIONS ****************************************************************/
 
 
-static ULONGLONG
-NtfsGetFileSize(PFILE_RECORD_HEADER FileRecord,
-                PFILENAME_ATTRIBUTE FileName)
+ULONGLONG
+NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt,
+                PFILE_RECORD_HEADER FileRecord,
+                PCWSTR Stream,
+                ULONG StreamLength,
+                PULONGLONG AllocatedSize)
 {
-    ULONGLONG Size;
-    PNTFS_ATTR_RECORD Attribute;
+    ULONGLONG Size = 0ULL;
+    ULONGLONG Allocated = 0ULL;
+    NTSTATUS Status;
+    PNTFS_ATTR_CONTEXT DataContext;
 
-    Size = FileName->AllocatedSize;
-    Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
-    while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
-           Attribute->Type != AttributeEnd)
+    Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Stream, StreamLength, &DataContext);
+    if (NT_SUCCESS(Status))
     {
-        if (Attribute->Type == AttributeData && Attribute->NameLength == 0)
-        {
-            Size = AttributeDataLength(Attribute);
-            break;
-        }
-
-        Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length);
+        Size = AttributeDataLength(&DataContext->Record);
+        Allocated = AttributeAllocatedLength(&DataContext->Record);
+        ReleaseAttributeContext(DataContext);
     }
 
+    if (AllocatedSize != NULL) *AllocatedSize = Allocated;
+
     return Size;
 }
 
@@ -72,7 +73,7 @@ NtfsGetNameInformation(PDEVICE_EXTENSION DeviceExt,
 
     DPRINT("NtfsGetNameInformation() called\n");
 
-    FileName = GetBestFileNameFromRecord(FileRecord);
+    FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
     if (FileName == NULL)
     {
         DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
@@ -106,7 +107,7 @@ NtfsGetDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
 
     DPRINT("NtfsGetDirectoryInformation() called\n");
 
-    FileName = GetBestFileNameFromRecord(FileRecord);
+    FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
     if (FileName == NULL)
     {
         DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
@@ -114,7 +115,7 @@ NtfsGetDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
         return STATUS_OBJECT_NAME_NOT_FOUND;
     }
 
-    StdInfo = GetStandardInformationFromRecord(FileRecord);
+    StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
     ASSERT(StdInfo != NULL);
 
     Length = FileName->NameLength * sizeof (WCHAR);
@@ -134,8 +135,7 @@ NtfsGetDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
     /* Convert file flags */
     NtfsFileFlagsToAttributes(FileName->FileAttributes | StdInfo->FileAttribute, &Info->FileAttributes);
 
-    Info->EndOfFile.QuadPart = NtfsGetFileSize(FileRecord, FileName);
-    Info->AllocationSize.QuadPart = ROUND_UP(Info->EndOfFile.QuadPart, DeviceExt->NtfsInfo.BytesPerCluster);
+    Info->EndOfFile.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, (PULONGLONG)&Info->AllocationSize.QuadPart);
 
     Info->FileIndex = MFTIndex;
 
@@ -156,7 +156,7 @@ NtfsGetFullDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
 
     DPRINT("NtfsGetFullDirectoryInformation() called\n");
 
-    FileName = GetBestFileNameFromRecord(FileRecord);
+    FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
     if (FileName == NULL)
     {
         DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
@@ -164,7 +164,7 @@ NtfsGetFullDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
         return STATUS_OBJECT_NAME_NOT_FOUND;
     }
 
-    StdInfo = GetStandardInformationFromRecord(FileRecord);
+    StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
     ASSERT(StdInfo != NULL);
 
     Length = FileName->NameLength * sizeof (WCHAR);
@@ -184,8 +184,7 @@ NtfsGetFullDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
     /* Convert file flags */
     NtfsFileFlagsToAttributes(FileName->FileAttributes | StdInfo->FileAttribute, &Info->FileAttributes);
 
-    Info->EndOfFile.QuadPart = NtfsGetFileSize(FileRecord, FileName);
-    Info->AllocationSize.QuadPart = ROUND_UP(Info->EndOfFile.QuadPart, DeviceExt->NtfsInfo.BytesPerCluster);
+    Info->EndOfFile.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, (PULONGLONG)&Info->AllocationSize.QuadPart);
 
     Info->FileIndex = MFTIndex;
     Info->EaSize = 0;
@@ -207,16 +206,16 @@ NtfsGetBothDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
 
     DPRINT("NtfsGetBothDirectoryInformation() called\n");
 
-    FileName = GetBestFileNameFromRecord(FileRecord);
+    FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
     if (FileName == NULL)
     {
         DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
         NtfsDumpFileAttributes(DeviceExt, FileRecord);
         return STATUS_OBJECT_NAME_NOT_FOUND;
     }
-    ShortFileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_DOS);
+    ShortFileName = GetFileNameFromRecord(DeviceExt, FileRecord, NTFS_FILE_NAME_DOS);
 
-    StdInfo = GetStandardInformationFromRecord(FileRecord);
+    StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
     ASSERT(StdInfo != NULL);
 
     Length = FileName->NameLength * sizeof (WCHAR);
@@ -249,8 +248,7 @@ NtfsGetBothDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
     /* Convert file flags */
     NtfsFileFlagsToAttributes(FileName->FileAttributes | StdInfo->FileAttribute, &Info->FileAttributes);
 
-    Info->EndOfFile.QuadPart = NtfsGetFileSize(FileRecord, FileName);
-    Info->AllocationSize.QuadPart = ROUND_UP(Info->EndOfFile.QuadPart, DeviceExt->NtfsInfo.BytesPerCluster);
+    Info->EndOfFile.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, (PULONGLONG)&Info->AllocationSize.QuadPart);
 
     Info->FileIndex = MFTIndex;
     Info->EaSize = 0;
@@ -300,6 +298,13 @@ NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
     FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
     FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
 
+    if (NtfsFCBIsCompressed(Fcb))
+    {
+        DPRINT1("Compressed directory!\n");
+        UNIMPLEMENTED;
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
     if (SearchPattern != NULL)
     {
         if (!Ccb->DirectorySearchPattern)
@@ -366,7 +371,7 @@ NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
              */
             if (MFTRecord == OldMFTRecord)
             {
-                DPRINT("Ignoring duplicate MFT entry 0x%x\n", MFTRecord);
+                DPRINT1("Ignoring duplicate MFT entry 0x%x\n", MFTRecord);
                 Ccb->Entry++;
                 ExFreePoolWithTag(FileRecord, TAG_NTFS);
                 continue;