https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d6d3d0eacd5d2a6fae22e…
commit d6d3d0eacd5d2a6fae22e0701f036f0d0fd01307
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Aug 30 23:24:27 2024 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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(
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1d3bce1a598e988ed2658…
commit 1d3bce1a598e988ed26580503911886113c5cc24
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sun Nov 26 12:24:24 2023 +0200
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Sun Oct 20 16:28:11 2024 +0300
[NTOS:KE] Make KeFlushQueuedDpcs SMP ready
KeFlushQueuedDpcs is used by some drivers, when unloading or removing a device, to be sure no DPC is still running their code. On a UP system this can be done "inline", on an SMP system, it requires to send an IPI to each processor that has DPCs queued and also synchronize it with the calling thread, which is what KeSetSystemAffinityThread does implicitly: When a queued DPC was detected on a remote processor (implying that processor is currently running at DISPATCH_LEVEL or above), Ke [...]
---
ntoskrnl/ke/dpc.c | 38 ++++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/ntoskrnl/ke/dpc.c b/ntoskrnl/ke/dpc.c
index 5ed9f51aad0..04d45fe1665 100644
--- a/ntoskrnl/ke/dpc.c
+++ b/ntoskrnl/ke/dpc.c
@@ -914,28 +914,46 @@ KeRemoveQueueDpc(IN PKDPC Dpc)
/*
* @implemented
*/
+_IRQL_requires_max_(APC_LEVEL)
VOID
NTAPI
KeFlushQueuedDpcs(VOID)
{
- PKPRCB CurrentPrcb = KeGetCurrentPrcb();
+ ULONG ProcessorIndex;
+ PKPRCB TargetPrcb;
+
PAGED_CODE();
+ ASSERT(KeGetCurrentThread()->SystemAffinityActive == FALSE);
- /* Check if this is an UP machine */
- if (KeActiveProcessors == 1)
+ /* Loop all processors */
+ for (ProcessorIndex = 0; ProcessorIndex < KeNumberProcessors; ProcessorIndex++)
{
+ /* Get the target processor's PRCB */
+ TargetPrcb = KiProcessorBlock[ProcessorIndex];
+
/* Check if there are DPCs on either queues */
- if ((CurrentPrcb->DpcData[DPC_NORMAL].DpcQueueDepth > 0) ||
- (CurrentPrcb->DpcData[DPC_THREADED].DpcQueueDepth > 0))
+ if ((TargetPrcb->DpcData[DPC_NORMAL].DpcQueueDepth > 0) ||
+ (TargetPrcb->DpcData[DPC_THREADED].DpcQueueDepth > 0))
{
- /* Request an interrupt */
- HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+ /* Check if this is the current processor */
+ if (TargetPrcb == KeGetCurrentPrcb())
+ {
+ /* Request a DPC interrupt */
+ HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+ }
+ else
+ {
+ /* Attach to the target processor. This will cause a DPC
+ interrupt on the target processor and flush all DPCs. */
+ KeSetSystemAffinityThread(TargetPrcb->SetMember);
+ }
}
}
- else
+
+ /* Revert back to user affinity */
+ if (KeGetCurrentThread()->SystemAffinityActive)
{
- /* FIXME: SMP support required */
- ASSERT(FALSE);
+ KeRevertToUserAffinityThread();
}
}