Author: pschweitzer
Date: Fri Oct 31 14:21:35 2014
New Revision: 65145

URL: http://svn.reactos.org/svn/reactos?rev=65145&view=rev
Log:
[NTFS]
- Move FSCTL_GET_NTFS_VOLUME_DATA implementation in its own function 
GetNfsVolumeData(), so remove it from NtfsUserFsRequest()
- Add support for FSCTL_GET_NTFS_FILE_RECORD in NtfsUserFsRequest()
- Implement GetNtfsFileRecord() which returns a file record. Not fully sure 
about its implementation, this is to be checked.

This does not really improve the nfi situation in any kind yet...

CORE-8725

Modified:
    trunk/reactos/drivers/filesystems/ntfs/fsctl.c

Modified: trunk/reactos/drivers/filesystems/ntfs/fsctl.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/ntfs/fsctl.c?rev=65145&r1=65144&r2=65145&view=diff
==============================================================================
--- trunk/reactos/drivers/filesystems/ntfs/fsctl.c      [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/ntfs/fsctl.c      [iso-8859-1] Fri Oct 31 
14:21:35 2014
@@ -528,71 +528,151 @@
 
 static
 NTSTATUS
+GetNfsVolumeData(PDEVICE_EXTENSION DeviceExt,
+                 PIRP Irp)
+{
+    PIO_STACK_LOCATION Stack;
+    PNTFS_VOLUME_DATA_BUFFER DataBuffer;
+    PNTFS_ATTR_RECORD Attribute;
+
+    DataBuffer = (PNTFS_VOLUME_DATA_BUFFER)Irp->UserBuffer;
+    Stack = IoGetCurrentIrpStackLocation(Irp);
+
+    if (Stack->Parameters.FileSystemControl.OutputBufferLength < 
sizeof(NTFS_VOLUME_DATA_BUFFER) ||
+        Irp->UserBuffer == NULL)
+    {
+        DPRINT1("Invalid output! %d %p\n", 
Stack->Parameters.FileSystemControl.OutputBufferLength, Irp->UserBuffer);
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    DataBuffer->VolumeSerialNumber.QuadPart = DeviceExt->NtfsInfo.SerialNumber;
+    DataBuffer->NumberSectors.QuadPart = DeviceExt->NtfsInfo.SectorCount;
+    DataBuffer->TotalClusters.QuadPart = DeviceExt->NtfsInfo.SectorCount / 
DeviceExt->NtfsInfo.SectorsPerCluster;
+    DataBuffer->FreeClusters.QuadPart = NtfsGetFreeClusters(DeviceExt);
+    DataBuffer->TotalReserved.QuadPart = 0LL; // FIXME
+    DataBuffer->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
+    DataBuffer->BytesPerCluster = DeviceExt->NtfsInfo.BytesPerCluster;
+    DataBuffer->BytesPerFileRecordSegment = 
DeviceExt->NtfsInfo.BytesPerFileRecord;
+    DataBuffer->ClustersPerFileRecordSegment = 
DeviceExt->NtfsInfo.BytesPerFileRecord / DeviceExt->NtfsInfo.BytesPerCluster;
+    DataBuffer->MftStartLcn.QuadPart = DeviceExt->NtfsInfo.MftStart.QuadPart;
+    DataBuffer->Mft2StartLcn.QuadPart = 
DeviceExt->NtfsInfo.MftMirrStart.QuadPart;
+    DataBuffer->MftZoneStart.QuadPart = 0; // FIXME
+    DataBuffer->MftZoneEnd.QuadPart = 0; // FIXME
+
+    Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)DeviceExt->MasterFileTable + 
DeviceExt->MasterFileTable->AttributeOffset);
+    while (Attribute < 
(PNTFS_ATTR_RECORD)((ULONG_PTR)DeviceExt->MasterFileTable + 
DeviceExt->MasterFileTable->BytesInUse) &&
+           Attribute->Type != AttributeEnd)
+    {
+        if (Attribute->Type == AttributeData)
+        {
+            ASSERT(Attribute->IsNonResident);
+            DataBuffer->MftValidDataLength.QuadPart = 
Attribute->NonResident.DataSize;
+
+            break;
+        }
+
+        Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + 
Attribute->Length);
+    }
+
+    if (Stack->Parameters.FileSystemControl.OutputBufferLength >= 
sizeof(NTFS_EXTENDED_VOLUME_DATA) + sizeof(NTFS_VOLUME_DATA_BUFFER))
+    {
+        PNTFS_EXTENDED_VOLUME_DATA ExtendedData = 
(PNTFS_EXTENDED_VOLUME_DATA)((ULONG_PTR)Irp->UserBuffer + 
sizeof(NTFS_VOLUME_DATA_BUFFER));
+
+        ExtendedData->ByteCount = sizeof(NTFS_EXTENDED_VOLUME_DATA);
+        ExtendedData->MajorVersion = DeviceExt->NtfsInfo.MajorVersion;
+        ExtendedData->MinorVersion = DeviceExt->NtfsInfo.MinorVersion;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
+GetNtfsFileRecord(PDEVICE_EXTENSION DeviceExt,
+                  PIRP Irp)
+{
+    NTSTATUS Status;
+    PIO_STACK_LOCATION Stack;
+    PNTFS_FILE_RECORD_INPUT_BUFFER InputBuffer;
+    PFILE_RECORD_HEADER FileRecord;
+    PNTFS_FILE_RECORD_OUTPUT_BUFFER OutputBuffer;
+    ULONGLONG MFTRecord;
+
+    Stack = IoGetCurrentIrpStackLocation(Irp);
+
+    if (Stack->Parameters.FileSystemControl.InputBufferLength < 
sizeof(NTFS_FILE_RECORD_INPUT_BUFFER) ||
+        Irp->AssociatedIrp.SystemBuffer == NULL)
+    {
+        DPRINT1("Invalid input! %d %p\n", 
Stack->Parameters.FileSystemControl.InputBufferLength, 
Irp->AssociatedIrp.SystemBuffer);
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    if (Stack->Parameters.FileSystemControl.OutputBufferLength < 
sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER) ||
+        Irp->AssociatedIrp.SystemBuffer == NULL)
+    {
+        DPRINT1("Invalid output! %d %p\n", 
Stack->Parameters.FileSystemControl.OutputBufferLength, 
Irp->AssociatedIrp.SystemBuffer);
+        return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    FileRecord = ExAllocatePoolWithTag(NonPagedPool,
+                                       DeviceExt->NtfsInfo.BytesPerFileRecord,
+                                       TAG_NTFS);
+    if (FileRecord == NULL)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    InputBuffer = 
(PNTFS_FILE_RECORD_INPUT_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+
+    MFTRecord = InputBuffer->FileReferenceNumber.QuadPart;
+    Status = ReadFileRecord(DeviceExt, MFTRecord, FileRecord);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed reading record: %I64x\n", MFTRecord);
+        ExFreePoolWithTag(FileRecord, TAG_NTFS);
+        return Status;
+    }
+
+    if (Stack->Parameters.FileSystemControl.OutputBufferLength < 
(FIELD_OFFSET(NTFS_FILE_RECORD_OUTPUT_BUFFER, FileRecordBuffer) + 
FileRecord->BytesInUse))
+    {
+        DPRINT1("Buffer too small: %lu vs %lu\n", 
Stack->Parameters.FileSystemControl.OutputBufferLength, FileRecord->BytesInUse);
+        ExFreePoolWithTag(FileRecord, TAG_NTFS);
+        return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    OutputBuffer = 
(PNTFS_FILE_RECORD_OUTPUT_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+    OutputBuffer->FileReferenceNumber.QuadPart = MFTRecord;
+    OutputBuffer->FileRecordLength = FileRecord->BytesInUse;
+    RtlCopyMemory(OutputBuffer->FileRecordBuffer, FileRecord, 
FileRecord->BytesInUse);
+
+    ExFreePoolWithTag(FileRecord, TAG_NTFS);
+
+    return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
 NtfsUserFsRequest(PDEVICE_OBJECT DeviceObject,
                   PIRP Irp)
 {
     NTSTATUS Status;
     PIO_STACK_LOCATION Stack;
     PDEVICE_EXTENSION DeviceExt;
-    PNTFS_VOLUME_DATA_BUFFER DataBuffer;
-    PNTFS_ATTR_RECORD Attribute;
 
     DPRINT1("NtfsUserFsRequest(%p, %p)\n", DeviceObject, Irp);
 
     Stack = IoGetCurrentIrpStackLocation(Irp);
+    DeviceExt = DeviceObject->DeviceExtension;
     switch (Stack->Parameters.FileSystemControl.FsControlCode)
     {
         case FSCTL_GET_NTFS_VOLUME_DATA:
-            DeviceExt = DeviceObject->DeviceExtension;
-            DataBuffer = (PNTFS_VOLUME_DATA_BUFFER)Irp->UserBuffer;
-
-            if (Stack->Parameters.FileSystemControl.OutputBufferLength < 
sizeof(NTFS_VOLUME_DATA_BUFFER) ||
-                Irp->UserBuffer == NULL)
-            {
-                DPRINT1("Invalid output! %d %p\n", 
Stack->Parameters.FileSystemControl.OutputBufferLength, Irp->UserBuffer);
-                Status = STATUS_INVALID_PARAMETER;
-                break;
-            }
-
-            DataBuffer->VolumeSerialNumber.QuadPart = 
DeviceExt->NtfsInfo.SerialNumber;
-            DataBuffer->NumberSectors.QuadPart = 
DeviceExt->NtfsInfo.SectorCount;
-            DataBuffer->TotalClusters.QuadPart = 
DeviceExt->NtfsInfo.SectorCount / DeviceExt->NtfsInfo.SectorsPerCluster;
-            DataBuffer->FreeClusters.QuadPart = NtfsGetFreeClusters(DeviceExt);
-            DataBuffer->TotalReserved.QuadPart = 0LL; // FIXME
-            DataBuffer->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
-            DataBuffer->BytesPerCluster = DeviceExt->NtfsInfo.BytesPerCluster;
-            DataBuffer->BytesPerFileRecordSegment = 
DeviceExt->NtfsInfo.BytesPerFileRecord;
-            DataBuffer->ClustersPerFileRecordSegment = 
DeviceExt->NtfsInfo.BytesPerFileRecord / DeviceExt->NtfsInfo.BytesPerCluster;
-            DataBuffer->MftStartLcn.QuadPart = 
DeviceExt->NtfsInfo.MftStart.QuadPart;
-            DataBuffer->Mft2StartLcn.QuadPart = 
DeviceExt->NtfsInfo.MftMirrStart.QuadPart;
-            DataBuffer->MftZoneStart.QuadPart = 0; // FIXME
-            DataBuffer->MftZoneEnd.QuadPart = 0; // FIXME
-
-            Attribute = 
(PNTFS_ATTR_RECORD)((ULONG_PTR)DeviceExt->MasterFileTable + 
DeviceExt->MasterFileTable->AttributeOffset);
-            while (Attribute < 
(PNTFS_ATTR_RECORD)((ULONG_PTR)DeviceExt->MasterFileTable + 
DeviceExt->MasterFileTable->BytesInUse) &&
-                   Attribute->Type != AttributeEnd)
-            {
-                if (Attribute->Type == AttributeData)
-                {
-                    ASSERT(Attribute->IsNonResident);
-                    DataBuffer->MftValidDataLength.QuadPart = 
Attribute->NonResident.DataSize;
-
-                    break;
-                }
-
-                Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + 
Attribute->Length);
-            }
-
-            if (Stack->Parameters.FileSystemControl.OutputBufferLength >= 
sizeof(NTFS_EXTENDED_VOLUME_DATA) + sizeof(NTFS_VOLUME_DATA_BUFFER))
-            {
-                PNTFS_EXTENDED_VOLUME_DATA ExtendedData = 
(PNTFS_EXTENDED_VOLUME_DATA)((ULONG_PTR)Irp->UserBuffer + 
sizeof(NTFS_VOLUME_DATA_BUFFER));
-
-                ExtendedData->ByteCount = sizeof(NTFS_EXTENDED_VOLUME_DATA);
-                ExtendedData->MajorVersion = DeviceExt->NtfsInfo.MajorVersion;
-                ExtendedData->MinorVersion = DeviceExt->NtfsInfo.MinorVersion;
-            }
-
-            Status = STATUS_SUCCESS;
+            Status = GetNfsVolumeData(DeviceExt, Irp);
+            break;
+
+        case FSCTL_GET_NTFS_FILE_RECORD:
+            Status = GetNtfsFileRecord(DeviceExt, Irp);
             break;
 
         default:


Reply via email to