https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d6d3d0eacd5d2a6fae22e0701f036f0d0fd01307

commit d6d3d0eacd5d2a6fae22e0701f036f0d0fd01307
Author:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
AuthorDate: Fri Aug 30 23:24:27 2024 +0200
Commit:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
CommitDate: Sun Oct 20 16:51:23 2024 +0200

    [SETUPLIB] Add helpers to determine whether a disk is partitioned as a 
"super-floppy" (#7310)
---
 base/setup/lib/utils/partlist.c | 146 ++++++++++++++++++++++++++++------------
 base/setup/lib/utils/partlist.h |  18 ++++-
 2 files changed, 121 insertions(+), 43 deletions(-)

diff --git a/base/setup/lib/utils/partlist.c b/base/setup/lib/utils/partlist.c
index 8c8c597e084..c045518cbfe 100644
--- a/base/setup/lib/utils/partlist.c
+++ b/base/setup/lib/utils/partlist.c
@@ -478,33 +478,29 @@ EnumerateBiosDiskEntries(
 
 
 /*
- * Detects whether a disk reports as a "super-floppy", i.e. an unpartitioned
- * disk with a valid VBR, following the criteria used by IoReadPartitionTable()
+ * Detects whether a disk is a "super-floppy", i.e. an unpartitioned
+ * disk with only a valid VBR, as reported by IoReadPartitionTable()
  * and IoWritePartitionTable():
- * only one single partition starting at the beginning of the disk; the 
reported
- * defaults are: partition number being zero and its type being FAT16 
non-bootable.
- * Note also that accessing \Device\HarddiskN\Partition0 or Partition1 returns
- * the same data.
+ * only one single partition starting at offset zero and spanning the
+ * whole disk, without hidden sectors, whose type is FAT16 non-bootable.
+ *
+ * Accessing \Device\HarddiskN\Partition0 or Partition1 on such disks
+ * returns the same data.
  */
-// static
 BOOLEAN
-IsSuperFloppy(
-    IN PDISKENTRY DiskEntry)
+IsDiskSuperFloppy2(
+    _In_ const DISK_PARTITION_INFO* DiskInfo,
+    _In_opt_ const ULONGLONG* DiskSize,
+    _In_ const PARTITION_INFORMATION* PartitionInfo)
 {
-    PPARTITION_INFORMATION PartitionInfo;
-    ULONGLONG PartitionLengthEstimate;
-
-    /* No layout buffer: we cannot say anything yet */
-    if (DiskEntry->LayoutBuffer == NULL)
+    /* Structure size must be valid */
+    if (DiskInfo->SizeOfPartitionInfo < 
RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr))
         return FALSE;
 
-    /* We must have only one partition */
-    if (DiskEntry->LayoutBuffer->PartitionCount != 1)
+    /* The layout must be MBR */
+    if (DiskInfo->PartitionStyle != PARTITION_STYLE_MBR)
         return FALSE;
 
-    /* Get the single partition entry */
-    PartitionInfo = DiskEntry->LayoutBuffer->PartitionEntry;
-
     /* The single partition must start at the beginning of the disk */
     if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
           PartitionInfo->HiddenSectors == 0))
@@ -512,46 +508,112 @@ IsSuperFloppy(
         return FALSE;
     }
 
-    /* The disk signature is usually set to one; warn in case it's not */
-    if (DiskEntry->LayoutBuffer->Signature != 1)
+    /* The disk signature is usually set to 1; warn in case it's not */
+    if (DiskInfo->Mbr.Signature != 1)
     {
-        DPRINT1("Super-Floppy disk %lu signature %08x != 1!\n",
-                DiskEntry->DiskNumber, DiskEntry->LayoutBuffer->Signature);
+        DPRINT1("Super-Floppy signature %08x != 1\n", DiskInfo->Mbr.Signature);
     }
 
-    /*
-     * The partition number must be zero or one, be recognized,
-     * have FAT16 type and report as non-bootable.
-     */
-    if ((PartitionInfo->PartitionNumber != 0 &&
-         PartitionInfo->PartitionNumber != 1) ||
-        PartitionInfo->RecognizedPartition != TRUE ||
-        PartitionInfo->PartitionType != PARTITION_FAT_16 ||
-        PartitionInfo->BootIndicator != FALSE)
-    {
-        DPRINT1("Super-Floppy disk %lu does not return default settings!\n"
-                "    PartitionNumber = %lu, expected 0\n"
+    /* The partition must be recognized and report as FAT16 non-bootable */
+    if ((PartitionInfo->RecognizedPartition != TRUE) ||
+        (PartitionInfo->PartitionType != PARTITION_FAT_16) ||
+        (PartitionInfo->BootIndicator != FALSE))
+    {
+        DPRINT1("Super-Floppy does not return default settings:\n"
                 "    RecognizedPartition = %s, expected TRUE\n"
                 "    PartitionType = 0x%02x, expected 0x04 
(PARTITION_FAT_16)\n"
                 "    BootIndicator = %s, expected FALSE\n",
-                DiskEntry->DiskNumber,
-                PartitionInfo->PartitionNumber,
                 PartitionInfo->RecognizedPartition ? "TRUE" : "FALSE",
                 PartitionInfo->PartitionType,
                 PartitionInfo->BootIndicator ? "TRUE" : "FALSE");
     }
 
-    /* The partition lengths should agree */
-    PartitionLengthEstimate = GetDiskSizeInBytes(DiskEntry);
-    if (PartitionInfo->PartitionLength.QuadPart != PartitionLengthEstimate)
+    /* The partition and disk sizes should agree */
+    if (DiskSize && (PartitionInfo->PartitionLength.QuadPart != *DiskSize))
     {
-        DPRINT1("PartitionLength = %I64u is different from 
PartitionLengthEstimate = %I64u\n",
-                PartitionInfo->PartitionLength.QuadPart, 
PartitionLengthEstimate);
+        DPRINT1("PartitionLength = %I64u is different from DiskSize = %I64u\n",
+                PartitionInfo->PartitionLength.QuadPart, *DiskSize);
     }
 
     return TRUE;
 }
 
+BOOLEAN
+IsDiskSuperFloppy(
+    _In_ const DRIVE_LAYOUT_INFORMATION* Layout,
+    _In_opt_ const ULONGLONG* DiskSize)
+{
+    DISK_PARTITION_INFO DiskInfo;
+
+    /* The layout must contain only one partition */
+    if (Layout->PartitionCount != 1)
+        return FALSE;
+
+    /* Build the disk partition info */
+    DiskInfo.SizeOfPartitionInfo = 
RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
+    DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
+    DiskInfo.Mbr.Signature = Layout->Signature;
+    DiskInfo.Mbr.CheckSum = 0; // Dummy value
+
+    /* Call the helper on the single partition entry */
+    return IsDiskSuperFloppy2(&DiskInfo, DiskSize, Layout->PartitionEntry);
+}
+
+BOOLEAN
+IsDiskSuperFloppyEx(
+    _In_ const DRIVE_LAYOUT_INFORMATION_EX* LayoutEx,
+    _In_opt_ const ULONGLONG* DiskSize)
+{
+    DISK_PARTITION_INFO DiskInfo;
+    const PARTITION_INFORMATION_EX* PartitionInfoEx;
+    PARTITION_INFORMATION PartitionInfo;
+
+    /* The layout must be MBR and contain only one partition */
+    if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR)
+        return FALSE;
+    if (LayoutEx->PartitionCount != 1)
+        return FALSE;
+
+    /* Build the disk partition info */
+    DiskInfo.SizeOfPartitionInfo = 
RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
+    DiskInfo.PartitionStyle = PARTITION_STYLE_MBR; // LayoutEx->PartitionStyle;
+    DiskInfo.Mbr.Signature = LayoutEx->Mbr.Signature;
+    DiskInfo.Mbr.CheckSum = 0; // Dummy value
+
+    /* Convert the single partition entry */
+    PartitionInfoEx = LayoutEx->PartitionEntry;
+
+    PartitionInfo.StartingOffset = PartitionInfoEx->StartingOffset;
+    PartitionInfo.PartitionLength = PartitionInfoEx->PartitionLength;
+    PartitionInfo.HiddenSectors = PartitionInfoEx->Mbr.HiddenSectors;
+    PartitionInfo.PartitionNumber = PartitionInfoEx->PartitionNumber;
+    PartitionInfo.PartitionType = PartitionInfoEx->Mbr.PartitionType;
+    PartitionInfo.BootIndicator = PartitionInfoEx->Mbr.BootIndicator;
+    PartitionInfo.RecognizedPartition = 
PartitionInfoEx->Mbr.RecognizedPartition;
+    PartitionInfo.RewritePartition = PartitionInfoEx->RewritePartition;
+
+    /* Call the helper on the single partition entry */
+    return IsDiskSuperFloppy2(&DiskInfo, DiskSize, &PartitionInfo);
+}
+
+BOOLEAN
+IsSuperFloppy(
+    _In_ PDISKENTRY DiskEntry)
+{
+    ULONGLONG DiskSize;
+
+    /* No layout buffer: we cannot say anything yet */
+    if (!DiskEntry->LayoutBuffer)
+        return FALSE;
+
+    /* The disk must be MBR */
+    if (DiskEntry->DiskStyle != PARTITION_STYLE_MBR)
+        return FALSE;
+
+    DiskSize = GetDiskSizeInBytes(DiskEntry);
+    return IsDiskSuperFloppy(DiskEntry->LayoutBuffer, &DiskSize);
+}
+
 
 /*
  * Inserts the disk region represented by PartEntry into either
diff --git a/base/setup/lib/utils/partlist.h b/base/setup/lib/utils/partlist.h
index 3b52325cff2..fb20f1500c0 100644
--- a/base/setup/lib/utils/partlist.h
+++ b/base/setup/lib/utils/partlist.h
@@ -258,9 +258,25 @@ RoundingDivide(
     ((DiskEntry)->SectorCount.QuadPart * (DiskEntry)->BytesPerSector)
 
 
+BOOLEAN
+IsDiskSuperFloppy2(
+    _In_ const DISK_PARTITION_INFO* DiskInfo,
+    _In_opt_ const ULONGLONG* DiskSize,
+    _In_ const PARTITION_INFORMATION* PartitionInfo);
+
+BOOLEAN
+IsDiskSuperFloppy(
+    _In_ const DRIVE_LAYOUT_INFORMATION* Layout,
+    _In_opt_ const ULONGLONG* DiskSize);
+
+BOOLEAN
+IsDiskSuperFloppyEx(
+    _In_ const DRIVE_LAYOUT_INFORMATION_EX* LayoutEx,
+    _In_opt_ const ULONGLONG* DiskSize);
+
 BOOLEAN
 IsSuperFloppy(
-    IN PDISKENTRY DiskEntry);
+    _In_ PDISKENTRY DiskEntry);
 
 BOOLEAN
 IsPartitionActive(

Reply via email to