[fastfat_new]
authorAleksey Bragin <aleksey@reactos.org>
Thu, 15 Oct 2009 10:50:12 +0000 (10:50 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Thu, 15 Oct 2009 10:50:12 +0000 (10:50 +0000)
- Add a helper function for reading (mapping) volume's stream file object.
- Read a boot sector during volume mounting, unpack it and store values in Vcb->Bpb for later usage. In particular, a volume's serial number being empty problem is fixed now. Volume label is still empty.
- Silence more non-important debug prints.

svn path=/trunk/; revision=43477

reactos/drivers/filesystems/fastfat_new/fastfat.h
reactos/drivers/filesystems/fastfat_new/fcb.c
reactos/drivers/filesystems/fastfat_new/fsctl.c
reactos/drivers/filesystems/fastfat_new/volume.c

index 1ecdb6c..181aebd 100644 (file)
@@ -50,6 +50,13 @@ FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 NTSTATUS NTAPI
 FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 
+VOID NTAPI
+FatReadStreamFile(PVCB Vcb,
+                  ULONGLONG ByteOffset,
+                  ULONG ByteSize,
+                  PBCB *Bcb,
+                  PVOID *Buffer);
+
 /*  ------------------------------------------------------  blockdev.c  */
 NTSTATUS
 NTAPI
index bffdf7a..5092366 100644 (file)
@@ -502,7 +502,7 @@ FatSetFcbNames(IN PFAT_IRP_CONTEXT IrpContext,
         RtlDowncaseUnicodeString(UnicodeName, UnicodeName, FALSE);
         RtlUpcaseUnicodeString(UnicodeName, UnicodeName, FALSE);
 
-        DPRINT1("Converted long name: %wZ\n", UnicodeName);
+        DPRINT("Converted long name: %wZ\n", UnicodeName);
 
         /* Add the long unicode name link */
         FatInsertName(IrpContext, &Fcb->ParentFcb->Dcb.SplayLinksUnicode, &Fcb->LongName);
@@ -603,7 +603,7 @@ Fati8dot3ToString(IN PCHAR FileName,
     /* Set the length */
     OutString->Length = BaseLen + ExtLen;
 
-    DPRINT1("'%s', len %d\n", OutString->Buffer, OutString->Length);
+    DPRINT("'%s', len %d\n", OutString->Buffer, OutString->Length);
 }
 
 VOID
index b104e4c..a40d065 100644 (file)
@@ -47,6 +47,37 @@ FatiCleanVcbs(PFAT_IRP_CONTEXT IrpContext)
     ExReleaseResourceLite(&FatGlobalData.Resource);
 }
 
+VOID
+NTAPI
+FatiUnpackBpb(PBIOS_PARAMETER_BLOCK Bpb, PPACKED_BIOS_PARAMETER_BLOCK PackedBpb)
+{
+    CopyUchar2(&Bpb->BytesPerSector,     &PackedBpb->BytesPerSector[0]);
+    CopyUchar1(&Bpb->SectorsPerCluster,  &PackedBpb->SectorsPerCluster[0]);
+    CopyUchar2(&Bpb->ReservedSectors,    &PackedBpb->ReservedSectors[0]);
+    CopyUchar1(&Bpb->Fats,               &PackedBpb->Fats[0]);
+    CopyUchar2(&Bpb->RootEntries,        &PackedBpb->RootEntries[0]);
+    CopyUchar2(&Bpb->Sectors,            &PackedBpb->Sectors[0]);
+    CopyUchar1(&Bpb->Media,              &PackedBpb->Media[0]);
+    CopyUchar2(&Bpb->SectorsPerFat,      &PackedBpb->SectorsPerFat[0]);
+    CopyUchar2(&Bpb->SectorsPerTrack,    &PackedBpb->SectorsPerTrack[0]);
+    CopyUchar2(&Bpb->Heads,              &PackedBpb->Heads[0]);
+    CopyUchar4(&Bpb->HiddenSectors,      &PackedBpb->HiddenSectors[0]);
+    CopyUchar4(&Bpb->LargeSectors,       &PackedBpb->LargeSectors[0]);
+    CopyUchar4(&Bpb->LargeSectorsPerFat, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->LargeSectorsPerFat[0]);
+    CopyUchar2(&Bpb->ExtendedFlags,      &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->ExtendedFlags[0]);
+    CopyUchar2(&Bpb->FsVersion,          &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->FsVersion[0]);
+    CopyUchar4(&Bpb->RootDirFirstCluster,&((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->RootDirFirstCluster[0]);
+    CopyUchar2(&Bpb->FsInfoSector,       &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->FsInfoSector[0]);
+    CopyUchar2(&Bpb->BackupBootSector,   &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->BackupBootSector[0]);
+}
+
+BOOLEAN
+NTAPI
+FatiBpbFat32(PPACKED_BIOS_PARAMETER_BLOCK PackedBpb)
+{
+    return (*(USHORT *)(&PackedBpb->SectorsPerFat) == 0);
+}
+
 NTSTATUS
 NTAPI
 FatMountVolume(PFAT_IRP_CONTEXT IrpContext,
@@ -60,6 +91,8 @@ FatMountVolume(PFAT_IRP_CONTEXT IrpContext,
     PVOLUME_DEVICE_OBJECT VolumeDevice;
     VCB *Vcb;
     FF_ERROR Error;
+    PBCB BootBcb;
+    PPACKED_BOOT_SECTOR BootSector;
 
     DPRINT1("FatMountVolume()\n");
 
@@ -167,7 +200,46 @@ FatMountVolume(PFAT_IRP_CONTEXT IrpContext,
         goto FatMountVolumeCleanup;
     }
 
-    // TODO: Read BPB and store it in Vcb->Bpb
+    /* Read the boot sector */
+    FatReadStreamFile(Vcb, 0, sizeof(PACKED_BOOT_SECTOR), &BootBcb, (PVOID)&BootSector);
+
+    /* Check if it's successful */
+    if (!BootBcb)
+    {
+        Status = STATUS_UNRECOGNIZED_VOLUME;
+        goto FatMountVolumeCleanup;
+    }
+
+    /* Unpack data */
+    FatiUnpackBpb(&Vcb->Bpb, &BootSector->PackedBpb);
+
+    /* Verify if sector size matches */
+    if (DiskGeometry.BytesPerSector != Vcb->Bpb.BytesPerSector)
+    {
+        DPRINT1("Disk geometry BPS %d and bios BPS %d don't match!\n",
+            DiskGeometry.BytesPerSector, Vcb->Bpb.BytesPerSector);
+
+        /* Fail */
+        Status = STATUS_UNRECOGNIZED_VOLUME;
+        goto FatMountVolumeCleanup;
+    }
+
+    /* If Sectors value is set, discard the LargeSectors value */
+    if (Vcb->Bpb.Sectors) Vcb->Bpb.LargeSectors = 0;
+
+    /* Copy serial number */
+    if (FatiBpbFat32(&BootSector->PackedBpb))
+    {
+        CopyUchar4(&Vpb->SerialNumber, ((PPACKED_BOOT_SECTOR_EX)BootSector)->Id);
+    }
+    else
+    {
+        /* This is FAT12/16 */
+        CopyUchar4(&Vpb->SerialNumber, BootSector->Id);
+    }
+
+    /* Unpin the BCB */
+    CcUnpinData(BootBcb);
 
     /* Create root DCB for it */
     FatCreateRootDcb(IrpContext, &VolumeDevice->Vcb);
@@ -249,7 +321,7 @@ FatFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
     PFAT_IRP_CONTEXT IrpContext;
     BOOLEAN CanWait = TRUE;
 
-    DPRINT1("FatFileSystemControl(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
+    DPRINT("FatFileSystemControl(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
 
     /* Get CanWait flag */
     if (IoGetCurrentIrpStackLocation(Irp)->FileObject)
index f32f4ef..b870508 100644 (file)
@@ -171,4 +171,27 @@ FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
     return STATUS_NOT_IMPLEMENTED;
 }
 
+VOID
+NTAPI
+FatReadStreamFile(PVCB Vcb,
+                  ULONGLONG ByteOffset,
+                  ULONG ByteSize,
+                  PBCB *Bcb,
+                  PVOID *Buffer)
+{
+    LARGE_INTEGER Offset;
+
+    Offset.QuadPart = ByteOffset;
+
+    if (!CcMapData(Vcb->StreamFileObject,
+                   &Offset,
+                   ByteSize,
+                   TRUE, // FIXME: CanWait
+                   Bcb,
+                   Buffer))
+    {
+        ASSERT(FALSE);
+    }
+}
+
 /* EOF */