Skip to content

Commit d6d3d0e

Browse files
committed
[SETUPLIB] Add helpers to determine whether a disk is partitioned as a "super-floppy" (reactos#7310)
1 parent ad5d9aa commit d6d3d0e

File tree

2 files changed

+121
-43
lines changed

2 files changed

+121
-43
lines changed

base/setup/lib/utils/partlist.c

Lines changed: 104 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -478,80 +478,142 @@ EnumerateBiosDiskEntries(
478478

479479

480480
/*
481-
* Detects whether a disk reports as a "super-floppy", i.e. an unpartitioned
482-
* disk with a valid VBR, following the criteria used by IoReadPartitionTable()
481+
* Detects whether a disk is a "super-floppy", i.e. an unpartitioned
482+
* disk with only a valid VBR, as reported by IoReadPartitionTable()
483483
* and IoWritePartitionTable():
484-
* only one single partition starting at the beginning of the disk; the reported
485-
* defaults are: partition number being zero and its type being FAT16 non-bootable.
486-
* Note also that accessing \Device\HarddiskN\Partition0 or Partition1 returns
487-
* the same data.
484+
* only one single partition starting at offset zero and spanning the
485+
* whole disk, without hidden sectors, whose type is FAT16 non-bootable.
486+
*
487+
* Accessing \Device\HarddiskN\Partition0 or Partition1 on such disks
488+
* returns the same data.
488489
*/
489-
// static
490490
BOOLEAN
491-
IsSuperFloppy(
492-
IN PDISKENTRY DiskEntry)
491+
IsDiskSuperFloppy2(
492+
_In_ const DISK_PARTITION_INFO* DiskInfo,
493+
_In_opt_ const ULONGLONG* DiskSize,
494+
_In_ const PARTITION_INFORMATION* PartitionInfo)
493495
{
494-
PPARTITION_INFORMATION PartitionInfo;
495-
ULONGLONG PartitionLengthEstimate;
496-
497-
/* No layout buffer: we cannot say anything yet */
498-
if (DiskEntry->LayoutBuffer == NULL)
496+
/* Structure size must be valid */
497+
if (DiskInfo->SizeOfPartitionInfo < RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr))
499498
return FALSE;
500499

501-
/* We must have only one partition */
502-
if (DiskEntry->LayoutBuffer->PartitionCount != 1)
500+
/* The layout must be MBR */
501+
if (DiskInfo->PartitionStyle != PARTITION_STYLE_MBR)
503502
return FALSE;
504503

505-
/* Get the single partition entry */
506-
PartitionInfo = DiskEntry->LayoutBuffer->PartitionEntry;
507-
508504
/* The single partition must start at the beginning of the disk */
509505
if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
510506
PartitionInfo->HiddenSectors == 0))
511507
{
512508
return FALSE;
513509
}
514510

515-
/* The disk signature is usually set to one; warn in case it's not */
516-
if (DiskEntry->LayoutBuffer->Signature != 1)
511+
/* The disk signature is usually set to 1; warn in case it's not */
512+
if (DiskInfo->Mbr.Signature != 1)
517513
{
518-
DPRINT1("Super-Floppy disk %lu signature %08x != 1!\n",
519-
DiskEntry->DiskNumber, DiskEntry->LayoutBuffer->Signature);
514+
DPRINT1("Super-Floppy signature %08x != 1\n", DiskInfo->Mbr.Signature);
520515
}
521516

522-
/*
523-
* The partition number must be zero or one, be recognized,
524-
* have FAT16 type and report as non-bootable.
525-
*/
526-
if ((PartitionInfo->PartitionNumber != 0 &&
527-
PartitionInfo->PartitionNumber != 1) ||
528-
PartitionInfo->RecognizedPartition != TRUE ||
529-
PartitionInfo->PartitionType != PARTITION_FAT_16 ||
530-
PartitionInfo->BootIndicator != FALSE)
531-
{
532-
DPRINT1("Super-Floppy disk %lu does not return default settings!\n"
533-
" PartitionNumber = %lu, expected 0\n"
517+
/* The partition must be recognized and report as FAT16 non-bootable */
518+
if ((PartitionInfo->RecognizedPartition != TRUE) ||
519+
(PartitionInfo->PartitionType != PARTITION_FAT_16) ||
520+
(PartitionInfo->BootIndicator != FALSE))
521+
{
522+
DPRINT1("Super-Floppy does not return default settings:\n"
534523
" RecognizedPartition = %s, expected TRUE\n"
535524
" PartitionType = 0x%02x, expected 0x04 (PARTITION_FAT_16)\n"
536525
" BootIndicator = %s, expected FALSE\n",
537-
DiskEntry->DiskNumber,
538-
PartitionInfo->PartitionNumber,
539526
PartitionInfo->RecognizedPartition ? "TRUE" : "FALSE",
540527
PartitionInfo->PartitionType,
541528
PartitionInfo->BootIndicator ? "TRUE" : "FALSE");
542529
}
543530

544-
/* The partition lengths should agree */
545-
PartitionLengthEstimate = GetDiskSizeInBytes(DiskEntry);
546-
if (PartitionInfo->PartitionLength.QuadPart != PartitionLengthEstimate)
531+
/* The partition and disk sizes should agree */
532+
if (DiskSize && (PartitionInfo->PartitionLength.QuadPart != *DiskSize))
547533
{
548-
DPRINT1("PartitionLength = %I64u is different from PartitionLengthEstimate = %I64u\n",
549-
PartitionInfo->PartitionLength.QuadPart, PartitionLengthEstimate);
534+
DPRINT1("PartitionLength = %I64u is different from DiskSize = %I64u\n",
535+
PartitionInfo->PartitionLength.QuadPart, *DiskSize);
550536
}
551537

552538
return TRUE;
553539
}
554540

541+
BOOLEAN
542+
IsDiskSuperFloppy(
543+
_In_ const DRIVE_LAYOUT_INFORMATION* Layout,
544+
_In_opt_ const ULONGLONG* DiskSize)
545+
{
546+
DISK_PARTITION_INFO DiskInfo;
547+
548+
/* The layout must contain only one partition */
549+
if (Layout->PartitionCount != 1)
550+
return FALSE;
551+
552+
/* Build the disk partition info */
553+
DiskInfo.SizeOfPartitionInfo = RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
554+
DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
555+
DiskInfo.Mbr.Signature = Layout->Signature;
556+
DiskInfo.Mbr.CheckSum = 0; // Dummy value
557+
558+
/* Call the helper on the single partition entry */
559+
return IsDiskSuperFloppy2(&DiskInfo, DiskSize, Layout->PartitionEntry);
560+
}
561+
562+
BOOLEAN
563+
IsDiskSuperFloppyEx(
564+
_In_ const DRIVE_LAYOUT_INFORMATION_EX* LayoutEx,
565+
_In_opt_ const ULONGLONG* DiskSize)
566+
{
567+
DISK_PARTITION_INFO DiskInfo;
568+
const PARTITION_INFORMATION_EX* PartitionInfoEx;
569+
PARTITION_INFORMATION PartitionInfo;
570+
571+
/* The layout must be MBR and contain only one partition */
572+
if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR)
573+
return FALSE;
574+
if (LayoutEx->PartitionCount != 1)
575+
return FALSE;
576+
577+
/* Build the disk partition info */
578+
DiskInfo.SizeOfPartitionInfo = RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
579+
DiskInfo.PartitionStyle = PARTITION_STYLE_MBR; // LayoutEx->PartitionStyle;
580+
DiskInfo.Mbr.Signature = LayoutEx->Mbr.Signature;
581+
DiskInfo.Mbr.CheckSum = 0; // Dummy value
582+
583+
/* Convert the single partition entry */
584+
PartitionInfoEx = LayoutEx->PartitionEntry;
585+
586+
PartitionInfo.StartingOffset = PartitionInfoEx->StartingOffset;
587+
PartitionInfo.PartitionLength = PartitionInfoEx->PartitionLength;
588+
PartitionInfo.HiddenSectors = PartitionInfoEx->Mbr.HiddenSectors;
589+
PartitionInfo.PartitionNumber = PartitionInfoEx->PartitionNumber;
590+
PartitionInfo.PartitionType = PartitionInfoEx->Mbr.PartitionType;
591+
PartitionInfo.BootIndicator = PartitionInfoEx->Mbr.BootIndicator;
592+
PartitionInfo.RecognizedPartition = PartitionInfoEx->Mbr.RecognizedPartition;
593+
PartitionInfo.RewritePartition = PartitionInfoEx->RewritePartition;
594+
595+
/* Call the helper on the single partition entry */
596+
return IsDiskSuperFloppy2(&DiskInfo, DiskSize, &PartitionInfo);
597+
}
598+
599+
BOOLEAN
600+
IsSuperFloppy(
601+
_In_ PDISKENTRY DiskEntry)
602+
{
603+
ULONGLONG DiskSize;
604+
605+
/* No layout buffer: we cannot say anything yet */
606+
if (!DiskEntry->LayoutBuffer)
607+
return FALSE;
608+
609+
/* The disk must be MBR */
610+
if (DiskEntry->DiskStyle != PARTITION_STYLE_MBR)
611+
return FALSE;
612+
613+
DiskSize = GetDiskSizeInBytes(DiskEntry);
614+
return IsDiskSuperFloppy(DiskEntry->LayoutBuffer, &DiskSize);
615+
}
616+
555617

556618
/*
557619
* Inserts the disk region represented by PartEntry into either

base/setup/lib/utils/partlist.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,25 @@ RoundingDivide(
258258
((DiskEntry)->SectorCount.QuadPart * (DiskEntry)->BytesPerSector)
259259

260260

261+
BOOLEAN
262+
IsDiskSuperFloppy2(
263+
_In_ const DISK_PARTITION_INFO* DiskInfo,
264+
_In_opt_ const ULONGLONG* DiskSize,
265+
_In_ const PARTITION_INFORMATION* PartitionInfo);
266+
267+
BOOLEAN
268+
IsDiskSuperFloppy(
269+
_In_ const DRIVE_LAYOUT_INFORMATION* Layout,
270+
_In_opt_ const ULONGLONG* DiskSize);
271+
272+
BOOLEAN
273+
IsDiskSuperFloppyEx(
274+
_In_ const DRIVE_LAYOUT_INFORMATION_EX* LayoutEx,
275+
_In_opt_ const ULONGLONG* DiskSize);
276+
261277
BOOLEAN
262278
IsSuperFloppy(
263-
IN PDISKENTRY DiskEntry);
279+
_In_ PDISKENTRY DiskEntry);
264280

265281
BOOLEAN
266282
IsPartitionActive(

0 commit comments

Comments
 (0)