[NTFS] Fix the FileNamesInformation/FileNameInformation class confusion that was...
[reactos.git] / drivers / filesystems / ntfs / dirctl.c
index ba7231d..ab784fc 100644 (file)
 
 /* FUNCTIONS ****************************************************************/
 
-/**
-* @name NtfsAddFilenameToDirectory
-* @implemented
-*
-* Adds a $FILE_NAME attribute to a given directory index.
-*
-* @param DeviceExt
-* Points to the target disk's DEVICE_EXTENSION.
-*
-* @param DirectoryMftIndex
-* Mft index of the parent directory which will receive the file.
-*
-* @param FileReferenceNumber
-* File reference of the file to be added to the directory. This is a combination of the 
-* Mft index and sequence number.
-*
-* @param FilenameAttribute
-* Pointer to the FILENAME_ATTRIBUTE of the file being added to the directory.
-*
-* @param CaseSensitive
-* Boolean indicating if the function should operate in case-sensitive mode. This will be TRUE
-* if an application created the file with the FILE_FLAG_POSIX_SEMANTICS flag.
-*
-* @return
-* STATUS_SUCCESS on success.
-* STATUS_INSUFFICIENT_RESOURCES if an allocation fails.
-* STATUS_NOT_IMPLEMENTED if target address isn't at the end of the given file record.
-*
-* @remarks
-* WIP - Can only support a few files in a directory.
-* One FILENAME_ATTRIBUTE is added to the directory's index for each link to that file. So, each
-* file which contains one FILENAME_ATTRIBUTE for a long name and another for the 8.3 name, will
-* get both attributes added to its parent directory.
-*/
-NTSTATUS
-NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt,
-                           ULONGLONG DirectoryMftIndex,
-                           ULONGLONG FileReferenceNumber,
-                           PFILENAME_ATTRIBUTE FilenameAttribute,
-                           BOOLEAN CaseSensitive)
-{
-    NTSTATUS Status = STATUS_SUCCESS;
-    PFILE_RECORD_HEADER ParentFileRecord;
-    PNTFS_ATTR_CONTEXT IndexRootContext;
-    PINDEX_ROOT_ATTRIBUTE I30IndexRoot;
-    ULONG IndexRootOffset;
-    ULONGLONG I30IndexRootLength;
-    ULONG LengthWritten;
-    PNTFS_ATTR_RECORD DestinationAttribute;
-    PINDEX_ROOT_ATTRIBUTE NewIndexRoot;
-    ULONG AttributeLength;
-    PNTFS_ATTR_RECORD NextAttribute;
-    PB_TREE NewTree;
-    ULONG BtreeIndexLength;
-    ULONG MaxIndexSize;
-
-    // Allocate memory for the parent directory
-    ParentFileRecord = ExAllocatePoolWithTag(NonPagedPool,
-                                             DeviceExt->NtfsInfo.BytesPerFileRecord,
-                                             TAG_NTFS);
-    if (!ParentFileRecord)
-    {
-        DPRINT1("ERROR: Couldn't allocate memory for file record!\n");
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    // Open the parent directory
-    Status = ReadFileRecord(DeviceExt, DirectoryMftIndex, ParentFileRecord);
-    if (!NT_SUCCESS(Status))
-    {
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-        DPRINT1("ERROR: Couldn't read parent directory with index %I64u\n",
-                DirectoryMftIndex);
-        return Status;
-    }
-
-    DPRINT1("Dumping old parent file record:\n");
-    NtfsDumpFileRecord(DeviceExt, ParentFileRecord);
-
-    // Find the index root attribute for the directory
-    Status = FindAttribute(DeviceExt,
-                           ParentFileRecord,
-                           AttributeIndexRoot,
-                           L"$I30",
-                           4,
-                           &IndexRootContext,
-                           &IndexRootOffset);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ERROR: Couldn't find $I30 $INDEX_ROOT attribute for parent directory with MFT #: %I64u!\n",
-                DirectoryMftIndex);
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-        return Status;
-    }
-
-    // Find the maximum index size given what the file record can hold
-    MaxIndexSize = DeviceExt->NtfsInfo.BytesPerFileRecord
-                   - IndexRootOffset
-                   - IndexRootContext->Record.Resident.ValueOffset
-                   - FIELD_OFFSET(INDEX_ROOT_ATTRIBUTE, Header)
-                   - (sizeof(ULONG) * 2);
-
-    // Allocate memory for the index root data
-    I30IndexRootLength = AttributeDataLength(&IndexRootContext->Record);
-    I30IndexRoot = (PINDEX_ROOT_ATTRIBUTE)ExAllocatePoolWithTag(NonPagedPool, I30IndexRootLength, TAG_NTFS);
-    if (!I30IndexRoot)
-    {
-        DPRINT1("ERROR: Couldn't allocate memory for index root attribute!\n");
-        ReleaseAttributeContext(IndexRootContext);
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-    }
-
-    // Read the Index Root
-    Status = ReadAttribute(DeviceExt, IndexRootContext, 0, (PCHAR)I30IndexRoot, I30IndexRootLength);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ERROR: Couln't read index root attribute for Mft index #%I64u\n", DirectoryMftIndex);
-        ReleaseAttributeContext(IndexRootContext);
-        ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-        return Status;
-    }
-
-    // Convert the index to a B*Tree
-    Status = CreateBTreeFromIndex(IndexRootContext, I30IndexRoot, &NewTree);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ERROR: Failed to create B-Tree from Index!\n");
-        ReleaseAttributeContext(IndexRootContext);
-        ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-        return Status;
-    }
-
-    DumpBTree(NewTree);
-
-    // Insert the key for the file we're adding
-    Status = NtfsInsertKey(FileReferenceNumber, FilenameAttribute, NewTree->RootNode, CaseSensitive);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ERROR: Failed to insert key into B-Tree!\n");
-        DestroyBTree(NewTree);
-        ReleaseAttributeContext(IndexRootContext);
-        ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-        return Status;
-    }
-
-    DumpBTree(NewTree);
-    
-    // Convert B*Tree back to Index Root
-    Status = CreateIndexRootFromBTree(DeviceExt, NewTree, MaxIndexSize, &NewIndexRoot, &BtreeIndexLength);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ERROR: Failed to create Index root from B-Tree!\n");
-        DestroyBTree(NewTree);
-        ReleaseAttributeContext(IndexRootContext);
-        ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-        return Status;
-    }
-
-    // We're done with the B-Tree now
-    DestroyBTree(NewTree);
-
-    // Write back the new index root attribute to the parent directory file record
-
-    // First, we need to resize the attribute.
-    // CreateIndexRootFromBTree() should have verified that the index root fits within MaxIndexSize.
-    // We can't set the size as we normally would, because if we extend past the file record, 
-    // we must create an index allocation and index bitmap (TODO). Also TODO: support file records with
-    // $ATTRIBUTE_LIST's.
-    AttributeLength = NewIndexRoot->Header.AllocatedSize + FIELD_OFFSET(INDEX_ROOT_ATTRIBUTE, Header);
-    DestinationAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)ParentFileRecord + IndexRootOffset);
-
-    // Find the attribute (or attribute-end marker) after the index root
-    NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)DestinationAttribute + DestinationAttribute->Length);
-    if (NextAttribute->Type != AttributeEnd)
-    {
-        DPRINT1("FIXME: For now, only resizing index root at the end of a file record is supported!\n");
-        ExFreePoolWithTag(NewIndexRoot, TAG_NTFS);
-        ReleaseAttributeContext(IndexRootContext);
-        ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-        return STATUS_NOT_IMPLEMENTED;
-    }
-
-    // Update the length of the attribute in the file record of the parent directory
-    InternalSetResidentAttributeLength(IndexRootContext,
-                                       ParentFileRecord,
-                                       IndexRootOffset,
-                                       AttributeLength);
-
-    NT_ASSERT(ParentFileRecord->BytesInUse <= DeviceExt->NtfsInfo.BytesPerFileRecord);
-
-    Status = UpdateFileRecord(DeviceExt, DirectoryMftIndex, ParentFileRecord);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ERROR: Failed to update file record of directory with index: %llx\n", DirectoryMftIndex);
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-        ExFreePoolWithTag(NewIndexRoot, TAG_NTFS);
-        ReleaseAttributeContext(IndexRootContext);
-        ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
-        return Status;
-    }
-
-    // Write the new index root to disk
-    Status = WriteAttribute(DeviceExt,
-                            IndexRootContext,
-                            0,
-                            (PUCHAR)NewIndexRoot,
-                            AttributeLength,
-                            &LengthWritten);
-    if (!NT_SUCCESS(Status) )
-    {
-        DPRINT1("ERROR: Unable to write new index root attribute to parent directory!\n");
-        ExFreePoolWithTag(NewIndexRoot, TAG_NTFS);
-        ReleaseAttributeContext(IndexRootContext);
-        ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
-        ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-        return Status;
-    }
-    
-    // re-read the parent file record, so we can dump it
-    Status = ReadFileRecord(DeviceExt, DirectoryMftIndex, ParentFileRecord);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ERROR: Couldn't read parent directory after messing with it!\n");
-    }
-    else
-    {
-        DPRINT1("Dumping new parent file record:\n");
-        NtfsDumpFileRecord(DeviceExt, ParentFileRecord);
-    }
-
-    // Cleanup
-    ExFreePoolWithTag(NewIndexRoot, TAG_NTFS);
-    ReleaseAttributeContext(IndexRootContext);
-    ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
-    ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
-
-    return Status;
-}
-
 ULONGLONG
 NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt,
                 PFILE_RECORD_HEADER FileRecord,
@@ -293,8 +49,8 @@ NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt,
     Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Stream, StreamLength, &DataContext, NULL);
     if (NT_SUCCESS(Status))
     {
-        Size = AttributeDataLength(&DataContext->Record);
-        Allocated = AttributeAllocatedLength(&DataContext->Record);
+        Size = AttributeDataLength(DataContext->pRecord);
+        Allocated = AttributeAllocatedLength(DataContext->pRecord);
         ReleaseAttributeContext(DataContext);
     }
 
@@ -305,16 +61,16 @@ NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt,
 
 
 static NTSTATUS
-NtfsGetNameInformation(PDEVICE_EXTENSION DeviceExt,
-                       PFILE_RECORD_HEADER FileRecord,
-                       ULONGLONG MFTIndex,
-                       PFILE_NAMES_INFORMATION Info,
-                       ULONG BufferLength)
+NtfsGetNamesInformation(PDEVICE_EXTENSION DeviceExt,
+                        PFILE_RECORD_HEADER FileRecord,
+                        ULONGLONG MFTIndex,
+                        PFILE_NAMES_INFORMATION Info,
+                        ULONG BufferLength)
 {
     ULONG Length;
     PFILENAME_ATTRIBUTE FileName;
 
-    DPRINT("NtfsGetNameInformation() called\n");
+    DPRINT("NtfsGetNamesInformation() called\n");
 
     FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
     if (FileName == NULL)
@@ -621,7 +377,7 @@ NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
                                 &FileRecord,
                                 &MFTRecord,
                                 Fcb->MFTIndex,
-                                (Stack->Flags & SL_CASE_SENSITIVE));
+                                BooleanFlagOn(Stack->Flags, SL_CASE_SENSITIVE));
 
         if (NT_SUCCESS(Status))
         {
@@ -639,12 +395,12 @@ NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
 
             switch (FileInformationClass)
             {
-                case FileNameInformation:
-                    Status = NtfsGetNameInformation(DeviceExtension,
-                                                    FileRecord,
-                                                    MFTRecord,
-                                                    (PFILE_NAMES_INFORMATION)Buffer,
-                                                    BufferLength);
+                case FileNamesInformation:
+                    Status = NtfsGetNamesInformation(DeviceExtension,
+                                                     FileRecord,
+                                                     MFTRecord,
+                                                     (PFILE_NAMES_INFORMATION)Buffer,
+                                                     BufferLength);
                     break;
 
                 case FileDirectoryInformation: