From: Hermès Bélusca-Maïto Date: Sun, 21 May 2017 23:36:13 +0000 (+0000) Subject: [USETUP] PartList module: Add a couple of disk/partition getters: GetDiskByBiosNumber... X-Git-Tag: 0.4.11-dev~519 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=2c76ce526c88811e35b8fbfc43a2c04f33b7e6bc [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 --- diff --git a/base/setup/lib/partlist.c b/base/setup/lib/partlist.c index 9861c241f88..d2d3f367684 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 5d2b62535fd..d23642731b1 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,