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

commit 2c76ce526c88811e35b8fbfc43a2c04f33b7e6bc
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Sun May 21 23:36:13 2017 +0000
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Thu May 31 18:00:58 2018 +0200

    [USETUP] PartList module: Add a couple of disk/partition getters: 
GetDiskByBiosNumber, GetDiskByNumber, GetDiskBySCSI, GetDiskBySignature, 
GetPartition, GetDiskOrPartition.
    They will be used in the subsequent commits.
    
    svn path=/branches/setup_improvements/; revision=74617
---
 base/setup/lib/partlist.c | 249 ++++++++++++++++++++++++++++++++++++++++------
 base/setup/lib/partlist.h |  39 +++++++-
 2 files changed, 258 insertions(+), 30 deletions(-)

diff --git a/base/setup/lib/partlist.c b/base/setup/lib/partlist.c
index 9861c241f8..d2d3f36768 100644
--- a/base/setup/lib/partlist.c
+++ b/base/setup/lib/partlist.c
@@ -1067,6 +1067,21 @@ AddDiskToList(
     DiskEntry->Id = ScsiAddress.TargetId;
 
     GetDriverName(DiskEntry);
+    /*
+     * Actually it would be more correct somehow to use:
+     *
+     * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
+     * ULONG ReturnedLength;
+     *
+     * Status = NtQueryObject(SomeHandleToTheDisk,
+     *                        ObjectNameInformation,
+     *                        &NameInfo,
+     *                        sizeof(NameInfo),
+     *                        &ReturnedLength);
+     * etc...
+     *
+     * See examples in 
https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267
+     */
 
     InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, 
DiskNumber);
 
@@ -1329,53 +1344,229 @@ DestroyPartitionList(
     RtlFreeHeap(ProcessHeap, 0, List);
 }
 
-//
-// FIXME: This function is COMPLETELY BROKEN!!!!
-//
-BOOLEAN
-SelectPartition(
+PDISKENTRY
+GetDiskByBiosNumber(
     IN PPARTLIST List,
-    IN ULONG DiskNumber,
-    IN ULONG PartitionNumber)
+    IN ULONG BiosDiskNumber)
 {
     PDISKENTRY DiskEntry;
-    PPARTENTRY PartEntry;
-    PLIST_ENTRY Entry1, Entry2;
+    PLIST_ENTRY Entry;
 
     /* Check for empty disks */
     if (IsListEmpty(&List->DiskListHead))
-        return FALSE;
+        return NULL;
 
-    /* Check for first usable entry on next disk */
-    Entry1 = List->CurrentDisk->ListEntry.Flink;
-    while (Entry1 != &List->DiskListHead)
+    /* Loop over the disks and find the correct one */
+    Entry = List->DiskListHead.Flink;
+    while (Entry != &List->DiskListHead)
     {
-        DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
+        DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+        Entry = Entry->Flink;
+
+        if (DiskEntry->BiosDiskNumber == BiosDiskNumber)
+        {
+            /* Disk found */
+            return DiskEntry;
+        }
+    }
+
+    /* Disk not found, stop there */
+    return NULL;
+}
+
+PDISKENTRY
+GetDiskByNumber(
+    IN PPARTLIST List,
+    IN ULONG DiskNumber)
+{
+    PDISKENTRY DiskEntry;
+    PLIST_ENTRY Entry;
+
+    /* Check for empty disks */
+    if (IsListEmpty(&List->DiskListHead))
+        return NULL;
+
+    /* Loop over the disks and find the correct one */
+    Entry = List->DiskListHead.Flink;
+    while (Entry != &List->DiskListHead)
+    {
+        DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+        Entry = Entry->Flink;
 
         if (DiskEntry->DiskNumber == DiskNumber)
         {
-            Entry2 = DiskEntry->PrimaryPartListHead.Flink;
-            while (Entry2 != &DiskEntry->PrimaryPartListHead)
-            {
-                PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
+            /* Disk found */
+            return DiskEntry;
+        }
+    }
 
-                if (PartEntry->PartitionNumber == PartitionNumber)
-                {
-                    List->CurrentDisk = DiskEntry;
-                    List->CurrentPartition = PartEntry;
-                    return TRUE;
-                }
+    /* Disk not found, stop there */
+    return NULL;
+}
 
-                Entry2 = Entry2->Flink;
-            }
+PDISKENTRY
+GetDiskBySCSI(
+    IN PPARTLIST List,
+    IN USHORT Port,
+    IN USHORT Bus,
+    IN USHORT Id)
+{
+    PDISKENTRY DiskEntry;
+    PLIST_ENTRY Entry;
 
-            return FALSE;
+    /* Check for empty disks */
+    if (IsListEmpty(&List->DiskListHead))
+        return NULL;
+
+    /* Loop over the disks and find the correct one */
+    Entry = List->DiskListHead.Flink;
+    while (Entry != &List->DiskListHead)
+    {
+        DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+        Entry = Entry->Flink;
+
+        if (DiskEntry->Port == Port &&
+            DiskEntry->Bus  == Bus  &&
+            DiskEntry->Id   == Id)
+        {
+            /* Disk found */
+            return DiskEntry;
         }
+    }
 
-        Entry1 = Entry1->Flink;
+    /* Disk not found, stop there */
+    return NULL;
+}
+
+PDISKENTRY
+GetDiskBySignature(
+    IN PPARTLIST List,
+    IN ULONG Signature)
+{
+    PDISKENTRY DiskEntry;
+    PLIST_ENTRY Entry;
+
+    /* Check for empty disks */
+    if (IsListEmpty(&List->DiskListHead))
+        return NULL;
+
+    /* Loop over the disks and find the correct one */
+    Entry = List->DiskListHead.Flink;
+    while (Entry != &List->DiskListHead)
+    {
+        DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+        Entry = Entry->Flink;
+
+        if (DiskEntry->LayoutBuffer->Signature == Signature)
+        {
+            /* Disk found */
+            return DiskEntry;
+        }
     }
 
-    return FALSE;
+    /* Disk not found, stop there */
+    return NULL;
+}
+
+PPARTENTRY
+GetPartition(
+    // IN PPARTLIST List,
+    IN PDISKENTRY DiskEntry,
+    IN ULONG PartitionNumber)
+{
+    PPARTENTRY PartEntry;
+    PLIST_ENTRY Entry;
+
+    /* Disk found, loop over the primary partitions first... */
+    Entry = DiskEntry->PrimaryPartListHead.Flink;
+    while (Entry != &DiskEntry->PrimaryPartListHead)
+    {
+        PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+        Entry = Entry->Flink;
+
+        if (PartEntry->PartitionNumber == PartitionNumber)
+        {
+            /* Partition found */
+            return PartEntry;
+        }
+    }
+
+    /* ... then over the logical partitions if needed */
+    Entry = DiskEntry->LogicalPartListHead.Flink;
+    while (Entry != &DiskEntry->LogicalPartListHead)
+    {
+        PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+        Entry = Entry->Flink;
+
+        if (PartEntry->PartitionNumber == PartitionNumber)
+        {
+            /* Partition found */
+            return PartEntry;
+        }
+    }
+
+    /* The partition was not found on the disk, stop there */
+    return NULL;
+}
+
+BOOLEAN
+GetDiskOrPartition(
+    IN PPARTLIST List,
+    IN ULONG DiskNumber,
+    IN ULONG PartitionNumber OPTIONAL,
+    OUT PDISKENTRY* pDiskEntry,
+    OUT PPARTENTRY* pPartEntry OPTIONAL)
+{
+    PDISKENTRY DiskEntry;
+    PPARTENTRY PartEntry = NULL;
+
+    /* Find the disk */
+    DiskEntry = GetDiskByNumber(List, DiskNumber);
+    if (!DiskEntry)
+        return FALSE;
+
+    /* If we have a partition (PartitionNumber != 0), find it */
+    if (PartitionNumber != 0)
+    {
+        PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
+        if (!PartEntry)
+            return FALSE;
+        ASSERT(PartEntry->DiskEntry == DiskEntry);
+    }
+
+    /* Return the disk (and optionally the partition) */
+    *pDiskEntry = DiskEntry;
+    if (pPartEntry) *pPartEntry = PartEntry;
+    return TRUE;
+}
+
+//
+// NOTE: Was introduced broken in r6258 by Casper
+//
+BOOLEAN
+SelectPartition(
+    IN PPARTLIST List,
+    IN ULONG DiskNumber,
+    IN ULONG PartitionNumber)
+{
+    PDISKENTRY DiskEntry;
+    PPARTENTRY PartEntry;
+
+    DiskEntry = GetDiskByNumber(List, DiskNumber);
+    if (!DiskEntry)
+        return FALSE;
+
+    PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
+    if (!PartEntry)
+        return FALSE;
+
+    ASSERT(PartEntry->DiskEntry == DiskEntry);
+    ASSERT(DiskEntry->DiskNumber == DiskNumber);
+    ASSERT(PartEntry->PartitionNumber == PartitionNumber);
+
+    List->CurrentDisk = DiskEntry;
+    List->CurrentPartition = PartEntry;
+    return TRUE;
 }
 
 PPARTENTRY
diff --git a/base/setup/lib/partlist.h b/base/setup/lib/partlist.h
index 5d2b62535f..d23642731b 100644
--- a/base/setup/lib/partlist.h
+++ b/base/setup/lib/partlist.h
@@ -87,11 +87,12 @@ typedef struct _DISKENTRY
     /* BIOS parameters */
     BOOLEAN BiosFound;
     ULONG BiosDiskNumber;
-//    ULONG Signature;
+//    ULONG Signature;  // Obtained from LayoutBuffer->Signature
 //    ULONG Checksum;
 
     /* SCSI parameters */
     ULONG DiskNumber;
+//  SCSI_ADDRESS;
     USHORT Port;
     USHORT Bus;
     USHORT Id;
@@ -217,6 +218,42 @@ VOID
 DestroyPartitionList(
     IN PPARTLIST List);
 
+PDISKENTRY
+GetDiskByBiosNumber(
+    IN PPARTLIST List,
+    IN ULONG BiosDiskNumber);
+
+PDISKENTRY
+GetDiskByNumber(
+    IN PPARTLIST List,
+    IN ULONG DiskNumber);
+
+PDISKENTRY
+GetDiskBySCSI(
+    IN PPARTLIST List,
+    IN USHORT Port,
+    IN USHORT Bus,
+    IN USHORT Id);
+
+PDISKENTRY
+GetDiskBySignature(
+    IN PPARTLIST List,
+    IN ULONG Signature);
+
+PPARTENTRY
+GetPartition(
+    // IN PPARTLIST List,
+    IN PDISKENTRY DiskEntry,
+    IN ULONG PartitionNumber);
+
+BOOLEAN
+GetDiskOrPartition(
+    IN PPARTLIST List,
+    IN ULONG DiskNumber,
+    IN ULONG PartitionNumber OPTIONAL,
+    OUT PDISKENTRY* pDiskEntry,
+    OUT PPARTENTRY* pPartEntry OPTIONAL);
+
 BOOLEAN
 SelectPartition(
     IN PPARTLIST List,

Reply via email to