diff --git a/base/setup/lib/utils/osdetect.c b/base/setup/lib/utils/osdetect.c index 1a4abd5cb6a..dfd46bc7469 100644 --- a/base/setup/lib/utils/osdetect.c +++ b/base/setup/lib/utils/osdetect.c @@ -186,24 +186,13 @@ EnumerateInstallations( } /* Add the discovered NTOS installation into the list */ - NtOsInstall = AddNTOSInstallation(Data->List, - BootEntry->FriendlyName, - Machine, - VendorName.Buffer, // FIXME: What if it's not NULL-terminated? - Options->OsLoadPath, - &SystemRootPath, PathComponent, - DiskNumber, PartitionNumber); - if (NtOsInstall) - { - /* Retrieve the volume corresponding to the disk and partition numbers */ - PPARTENTRY PartEntry = SelectPartition(Data->PartList, DiskNumber, PartitionNumber); - if (!PartEntry) - { - DPRINT1("SelectPartition(disk #%d, partition #%d) failed\n", - DiskNumber, PartitionNumber); - } - NtOsInstall->Volume = (PartEntry ? PartEntry->Volume : NULL); - } + AddNTOSInstallation(Data->List, + BootEntry->FriendlyName, + Machine, + VendorName.Buffer, // FIXME: What if it's not NULL-terminated? + Options->OsLoadPath, + &SystemRootPath, PathComponent, + DiskNumber, PartitionNumber); /* Continue the enumeration */ return STATUS_SUCCESS; diff --git a/base/setup/lib/utils/osdetect.h b/base/setup/lib/utils/osdetect.h index e329b1c32f4..cd90acb96ab 100644 --- a/base/setup/lib/utils/osdetect.h +++ b/base/setup/lib/utils/osdetect.h @@ -22,7 +22,6 @@ typedef struct _NTOS_INSTALLATION PCWSTR PathComponent; // Pointer inside SystemNtPath.Buffer ULONG DiskNumber; ULONG PartitionNumber; - PVOLENTRY Volume; // PVOLINFO WCHAR InstallationName[MAX_PATH]; WCHAR VendorName[MAX_PATH]; // CHAR Data[ANYSIZE_ARRAY]; diff --git a/base/setup/lib/utils/partlist.c b/base/setup/lib/utils/partlist.c index c045518cbfe..9f1588dfebb 100644 --- a/base/setup/lib/utils/partlist.c +++ b/base/setup/lib/utils/partlist.c @@ -65,8 +65,8 @@ DumpPartitionTable( ULONGLONG AlignDown( - IN ULONGLONG Value, - IN ULONG Alignment) + _In_ ULONGLONG Value, + _In_ ULONG Alignment) { ULONGLONG Temp; @@ -75,10 +75,11 @@ AlignDown( return Temp * Alignment; } +// Unused ULONGLONG AlignUp( - IN ULONGLONG Value, - IN ULONG Alignment) + _In_ ULONGLONG Value, + _In_ ULONG Alignment) { ULONGLONG Temp, Result; @@ -93,17 +94,482 @@ AlignUp( ULONGLONG RoundingDivide( - IN ULONGLONG Dividend, - IN ULONGLONG Divisor) + _In_ ULONGLONG Dividend, + _In_ ULONGLONG Divisor) { return (Dividend + Divisor / 2) / Divisor; } + +#define ADJ_LIST_ENTRY(ListEntry, Direction) \ + ((Direction) ? (ListEntry)->Flink : (ListEntry)->Blink) + +#define GET_ADJ_RECORD_IMPL(pAdjRecord, ListHead, Record, RecordType, Field, Direction) \ +do { \ + PLIST_ENTRY _ListEntry = ((Record) ? &(Record)->Field : (ListHead)); \ + _ListEntry = ADJ_LIST_ENTRY(_ListEntry, (Direction)); \ + (pAdjRecord) = ((_ListEntry == (ListHead)) \ + ? NULL : CONTAINING_RECORD(_ListEntry, RecordType, Field)); \ +} while (0) + +/** + * @brief + * Retrieves the adjacent (next or previous) disk in a given list. + * + * @param[in] DiskListHead + * The list where to search for the adjacent disk. + * + * @param[in] DiskEntry + * The disk where to continue the enumeration from (or NULL + * to retrieve the first or last one). + * + * @param[in] Direction + * TRUE or FALSE to search the next or previous disk, respectively. + * + * @return The disk, or NULL if not found. + **/ +static +PDISKENTRY +GetAdjDiskListEntry( + _In_ PLIST_ENTRY DiskListHead, + _In_opt_ PDISKENTRY DiskEntry, + _In_ BOOLEAN Direction) +{ + GET_ADJ_RECORD_IMPL(DiskEntry, DiskListHead, DiskEntry, DISKENTRY, ListEntry, Direction); + return DiskEntry; +} + +/** + * @brief + * Retrieves the adjacent (next or previous) disk region in a given list. + * + * @param[in] PartListHead + * The list where to search for the adjacent disk region. + * + * @param[in] PartEntry + * The disk region where to continue the enumeration from + * (or NULL to retrieve the first or last one). + * + * @param[in] Direction + * TRUE or FALSE to search the next or previous region, respectively. + * + * @return The disk region, or NULL if not found. + **/ +static +PPARTENTRY +GetAdjPartListEntry( // GetAdjRegionEntry + _In_ PLIST_ENTRY PartListHead, + _In_opt_ PPARTENTRY PartEntry, + _In_ BOOLEAN Direction) +{ + GET_ADJ_RECORD_IMPL(PartEntry, PartListHead, PartEntry, PARTENTRY, ListEntry, Direction); + return PartEntry; +} + + +/** + * @brief + * Finds the next disk region in order of appearance on a given MBR disk, + * starting at the specified region. + * + * The function goes into extended partitions and enumerate + * the logical regions inside. + * + * @param[in] CurrentDisk + * Specifies the disk where to find the next disk region. + * If CurrentPart != NULL, the disk CurrentPart belongs must be the same. + * + * @param[in] CurrentPart + * The disk region where to restart the search, or NULL for + * starting from the beginning of the specified disk. + * + * @return + * The next disk region, if any, or NULL when all regions on the disk + * have been enumerated. + * + * @see GetPrevMBRDiskRegionByOrder(). + **/ +static +PPARTENTRY +GetNextMBRDiskRegionByOrder( + _In_ PDISKENTRY CurrentDisk, + _In_opt_ PPARTENTRY CurrentPart) +{ + /* This helper is for MBR disks only! */ + ASSERT(CurrentDisk->DiskStyle == PARTITION_STYLE_MBR); + + /* If no region is given, restart the search at the top of the primary list */ + if (CurrentPart) + { + ASSERT(CurrentDisk == CurrentPart->DiskEntry); + + /* Check for extended and logical partitions */ + if ((CurrentPart == CurrentDisk->ExtendedPartition) || + CurrentPart->LogicalPartition) + { + /* If this is the single extended partition, + * go to the first logical region */ + if (CurrentPart == CurrentDisk->ExtendedPartition) + CurrentPart = NULL; + /* Else, this is a logical region */ + + /* The first or next region is in the logical list */ + CurrentPart = GetAdjPartListEntry(&CurrentDisk->LogicalPartListHead, + CurrentPart, TRUE); + if (CurrentPart) + return CurrentPart; + + /* We are at the end of the logical list: go to the next + * (primary) region following the extended partition */ + CurrentPart = CurrentDisk->ExtendedPartition; + } + } + + /* This is a primary region, go to the next one within the primary list */ + return GetAdjPartListEntry(&CurrentDisk->PrimaryPartListHead, + CurrentPart, TRUE); +} + +/** + * @brief + * Finds the previous disk region in order of appearance on a given MBR disk, + * starting at the specified partition. + * + * The function goes into extended partitions and enumerate + * the logical regions inside. + * + * @param[in] CurrentDisk + * Specifies the disk where to find the next disk region. + * If CurrentPart != NULL, the disk CurrentPart belongs must be the same. + * + * @param[in] CurrentPart + * The disk region where to restart the search, or NULL for + * starting from the end of the specified disk. + * + * @return + * The previous disk region, if any, or NULL when all regions on the disk + * have been enumerated. + * + * @see GetNextMBRDiskRegionByOrder(). + **/ +static +PPARTENTRY +GetPrevMBRDiskRegionByOrder( + _In_ PDISKENTRY CurrentDisk, + _In_opt_ PPARTENTRY CurrentPart) +{ + /* This helper is for MBR disks only! */ + ASSERT(CurrentDisk->DiskStyle == PARTITION_STYLE_MBR); + + /* If no region is given, restart the search at the bottom of the primary list */ + if (CurrentPart) + { + ASSERT(CurrentDisk == CurrentPart->DiskEntry); + + /* Check for logical partitions */ + if (CurrentPart->LogicalPartition) + { + /* The previous region is in the logical list */ + CurrentPart = GetAdjPartListEntry(&CurrentDisk->LogicalPartListHead, + CurrentPart, FALSE); + if (!CurrentPart) + { + /* We are at the beginning of the logical list: + * go back to the extended partition (it must be + * there since we had a logical region) */ + CurrentPart = CurrentDisk->ExtendedPartition; + ASSERT(CurrentPart); + } + /* Else, we are getting the previous logical region */ + + return CurrentPart; + } + } + + /* This is a primary region, go to the previous one within the primary list */ + CurrentPart = GetAdjPartListEntry(&CurrentDisk->PrimaryPartListHead, + CurrentPart, FALSE); + + /* Check for extended partition and look at the last logical region. + * If there are no logical regions, stay on the extended partition. */ + if (CurrentPart && (CurrentPart == CurrentDisk->ExtendedPartition)) + { + PPARTENTRY LastLogical = + GetAdjPartListEntry(&CurrentDisk->LogicalPartListHead, + NULL, FALSE); + if (LastLogical) + CurrentPart = LastLogical; + } + + return CurrentPart; +} + + +static +PPARTENTRY +GetNextMBRDiskRegionByType( + _In_ PDISKENTRY CurrentDisk, + _In_opt_ PPARTENTRY CurrentPart) +{ + /* This helper is for MBR disks only! */ + ASSERT(CurrentDisk->DiskStyle == PARTITION_STYLE_MBR); + + if (CurrentPart) + ASSERT(CurrentDisk == CurrentPart->DiskEntry); + + /* Check for primary regions first */ + if (!CurrentPart || !CurrentPart->LogicalPartition) + { + CurrentPart = GetAdjPartListEntry(&CurrentDisk->PrimaryPartListHead, + CurrentPart, TRUE); + if (CurrentPart) + return CurrentPart; + } + + /* If this was a logical region, or if no more primary regions: + * now, check for logical regions */ + if (CurrentPart && CurrentPart->LogicalPartition) + ASSERT(CurrentDisk->ExtendedPartition); + + /* If the new CurrentPart == NULL, we exhausted + * all the regions and we are done for this disk */ + // if (CurrentDisk->ExtendedPartition) + return GetAdjPartListEntry(&CurrentDisk->LogicalPartListHead, + CurrentPart, TRUE); +} + +static +PPARTENTRY +GetPrevMBRDiskRegionByType( + _In_ PDISKENTRY CurrentDisk, + _In_opt_ PPARTENTRY CurrentPart) +{ + /* This helper is for MBR disks only! */ + ASSERT(CurrentDisk->DiskStyle == PARTITION_STYLE_MBR); + + if (CurrentPart) + ASSERT(CurrentDisk == CurrentPart->DiskEntry); + + /* Check for logical regions first */ + if (!CurrentPart || CurrentPart->LogicalPartition) + { + if (CurrentPart && CurrentPart->LogicalPartition) + ASSERT(CurrentDisk->ExtendedPartition); + + // if (CurrentDisk->ExtendedPartition) + CurrentPart = GetAdjPartListEntry(&CurrentDisk->LogicalPartListHead, + CurrentPart, FALSE); + if (CurrentPart) + return CurrentPart; + } + + /* If this was a primary region, or if no more logical regions: + * now, check for primary regions */ + + /* If the new CurrentPart == NULL, we exhausted + * all the regions and we are done for this disk */ + return GetAdjPartListEntry(&CurrentDisk->PrimaryPartListHead, + CurrentPart, FALSE); +} + + +/** + * @brief + * Finds the adjacent (next or previous) disk region in order of + * appearance on a given disk, starting at the specified partition. + * + * For MBR disks, the function will go into extended partitions and + * enumerate the logical partitions inside. + * + * @param[in] CurrentDisk + * If CurrentPart == NULL, specifies the disk where to find the first + * disk region. If CurrentPart != NULL, this parameter becomes optional: + * - If CurrentDisk == NULL, the enumeration restarts at the specified + * CurrentPart using the disk where it resides. + * - If CurrentDisk != NULL, the enumeration restarts either at + * CurrentPart, if it belongs to the same disk; otherwise, the + * enumeration restarts at the first region of the specified disk. + * + * @param[in] CurrentPart + * The disk region where to restart the search, or NULL for + * starting from the beginning of the specified disk. + * + * @param[in] EnumFlags + * Enumeration flags. + * + * @return + * The disk region, if any, or NULL when all regions on the disk + * have been enumerated. + * + * @see GetAdjPartListEntry(), GetNextMBRDiskRegionByOrder(), GetPrevMBRDiskRegionByOrder(), + * GetNextMBRDiskRegionByType(), GetPrevMBRDiskRegionByType(). + **/ +PPARTENTRY +GetAdjDiskRegion( + _In_opt_ PDISKENTRY CurrentDisk, + _In_opt_ PPARTENTRY CurrentPart, + _In_ ULONG EnumFlags) +{ + BOOLEAN Direction = !(EnumFlags & ENUM_REGION_PREV); // TRUE: Next, FALSE: Previous + + /* Bail out if no parameters are given: cannot start search */ + if (!CurrentDisk && !CurrentPart) + return NULL; + + if (CurrentDisk && (!CurrentPart || (CurrentDisk != CurrentPart->DiskEntry))) + { + /* We have a disk but either, no current region, or it is present on + * a different disk: restart the search at the first or last region */ + CurrentPart = NULL; + } + else + { + /* else: (CurrentPart && (!CurrentDisk || (CurrentDisk == CurrentPart->DiskEntry))) + * and continue the search with the next/previous region */ + + /* Get the current region's disk */ + ASSERT(CurrentPart); + CurrentDisk = CurrentPart->DiskEntry; + } + +Retry: + /* If the disk is MBR, use the specific helpers; otherwise use the faster one */ + if (CurrentDisk->DiskStyle == PARTITION_STYLE_MBR) + { + /* Invalid combination */ + ASSERT(!((EnumFlags & ENUM_REGION_MBR_PRIMARY_ONLY) && + (EnumFlags & ENUM_REGION_MBR_LOGICAL_ONLY))); + + if (EnumFlags & ENUM_REGION_MBR_PRIMARY_ONLY) + { + // ASSERT(!CurrentPart || !CurrentPart->LogicalPartition); + CurrentPart = GetAdjPartListEntry(&CurrentDisk->PrimaryPartListHead, + CurrentPart, Direction); + } + else + if (EnumFlags & ENUM_REGION_MBR_LOGICAL_ONLY) + { + // ASSERT(CurrentDisk->ExtendedPartition); + // ASSERT(!CurrentPart || !CurrentPart->LogicalPartition); + CurrentPart = GetAdjPartListEntry(&CurrentDisk->LogicalPartListHead, + CurrentPart, Direction); + } + else + if (EnumFlags & ENUM_REGION_MBR_BY_ORDER) + { + // GetAdjMBRDiskRegion + CurrentPart = (Direction ? GetNextMBRDiskRegionByOrder + : GetPrevMBRDiskRegionByOrder)(CurrentDisk, CurrentPart); + } + else + { + CurrentPart = (Direction ? GetNextMBRDiskRegionByType + : GetPrevMBRDiskRegionByType)(CurrentDisk, CurrentPart); + } + } + else + { + // ASSERT(CurrentDisk->ExtendedPartition == NULL); + // ASSERT(!CurrentPart || !CurrentPart->LogicalPartition); + CurrentPart = GetAdjPartListEntry(&CurrentDisk->PrimaryPartListHead, + CurrentPart, Direction); + } + + /* If we need to check for partitioned regions + * but the current one is not, retry again */ + if ((EnumFlags & ENUM_REGION_PARTITIONED) && + CurrentPart && !CurrentPart->IsPartitioned) + { + goto Retry; + } + return CurrentPart; +} + +/** + * @brief + * Finds the adjacent (next or previous) disk region in order of appearance + * on a given disk in the list, starting at the given current partition. + * + * For MBR disks, the function will go into extended partitions + * for enumerating the logical partitions inside. + * + * @param[in] List + * The list of disks and partitions on the system. + * + * @param[in] CurrentPart + * The disk region where to restart the search, or NULL for starting + * from either the beginning (first region in the first disk) or + * from the end (last region in the last disk). + * + * @param[in] EnumFlags + * Enumeration flags. + * + * @return + * The next or the previous disk region, if any, or NULL when all + * regions have been enumerated. + **/ +PPARTENTRY +GetAdjPartition( + _In_ PPARTLIST List, + _In_opt_ PPARTENTRY CurrentPart, + _In_ ULONG EnumFlags) +{ + PLIST_ENTRY DiskListHead = &List->DiskListHead; + PDISKENTRY CurrentDisk; + + if (CurrentPart) + { + /* Check for the adjacent entry on the current partition's disk */ + CurrentDisk = CurrentPart->DiskEntry; + CurrentPart = GetAdjDiskRegion(/*CurrentDisk*/ NULL, CurrentPart, EnumFlags); + if (CurrentPart) + goto Quit; + + /* Otherwise, check the next or previous disk */ + ASSERT(!IsListEmpty(DiskListHead)); + } + else + { + /* Fail if no disks are available; otherwise, + * check the first or last disk */ + if (IsListEmpty(DiskListHead)) + return NULL; + CurrentDisk = NULL; + } + + /* Search for the first (last) partition entry on the next (previous) disk */ + while ((CurrentDisk = GetAdjDiskListEntry(DiskListHead, CurrentDisk, EnumFlags))) + { + DPRINT("Disk #%d\n", CurrentDisk->DiskNumber); + if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT) + DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n"); + + CurrentPart = GetAdjDiskRegion(CurrentDisk, NULL, EnumFlags); + if (CurrentPart) + break; + } + +Quit: + if (CurrentPart) + { + DPRINT(" %s Partition #%d, index %d - Type 0x%02x, IsPartitioned = %s, IsNew = %s, FormatState = %lu\n", + (CurrentPart->LogicalPartition ? "Logical" : "Primary"), + CurrentPart->PartitionNumber, CurrentPart->PartitionIndex, + CurrentPart->PartitionType, + CurrentPart->IsPartitioned ? "TRUE" : "FALSE", + CurrentPart->New ? "Yes" : "No", + CurrentPart->Volume.FormatState); + } + return CurrentPart; +} + + + static VOID GetDriverName( - IN PDISKENTRY DiskEntry) + _In_ PDISKENTRY DiskEntry) { RTL_QUERY_REGISTRY_TABLE QueryTable[2]; WCHAR KeyName[32]; @@ -133,32 +599,38 @@ GetDriverName( } } -static +/**** + ** VOLUME-specific + ****/ +/* + * FIXME: Rely on the MOUNTMGR to assign the drive letters. + * + * For the moment, we do it ourselves, by assigning drives to partitions + * that are *only on MBR disks*. We first assign letters to each active + * partition on each disk, then assign letters to each logical partition, + * and finish by assigning letters to the remaining primary partitions. + * (This algorithm is the one that can be observed in the Windows installer.) + */ +// static VOID AssignDriveLetters( IN PPARTLIST List) { PDISKENTRY DiskEntry; PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; - PLIST_ENTRY Entry2; WCHAR Letter; Letter = L'C'; /* Assign drive letters to primary partitions */ - for (Entry1 = List->DiskListHead.Flink; - Entry1 != &List->DiskListHead; - Entry1 = Entry1->Flink) + DiskEntry = NULL; + while ((DiskEntry = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry, TRUE))) { - DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); - - for (Entry2 = DiskEntry->PrimaryPartListHead.Flink; - Entry2 != &DiskEntry->PrimaryPartListHead; - Entry2 = Entry2->Flink) + PartEntry = NULL; + // while ((PartEntry = GetAdjPartListEntry(&DiskEntry->PrimaryPartListHead, PartEntry, TRUE))) + while ((PartEntry = GetAdjDiskRegion(DiskEntry, PartEntry, + ENUM_REGION_NEXT /*| ENUM_REGION_PARTITIONED*/ | ENUM_REGION_MBR_PRIMARY_ONLY))) { - PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); - if (!PartEntry->Volume) continue; PartEntry->Volume->Info.DriveLetter = UNICODE_NULL; @@ -175,18 +647,14 @@ AssignDriveLetters( } /* Assign drive letters to logical drives */ - for (Entry1 = List->DiskListHead.Flink; - Entry1 != &List->DiskListHead; - Entry1 = Entry1->Flink) + DiskEntry = NULL; + while ((DiskEntry = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry, TRUE))) { - DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); - - for (Entry2 = DiskEntry->LogicalPartListHead.Flink; - Entry2 != &DiskEntry->LogicalPartListHead; - Entry2 = Entry2->Flink) + PartEntry = NULL; + // while ((PartEntry = GetAdjPartListEntry(&DiskEntry->LogicalPartListHead, PartEntry, TRUE))) + while ((PartEntry = GetAdjDiskRegion(DiskEntry, PartEntry, + ENUM_REGION_NEXT /*| ENUM_REGION_PARTITIONED*/ | ENUM_REGION_MBR_LOGICAL_ONLY))) { - PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); - if (!PartEntry->Volume) continue; PartEntry->Volume->Info.DriveLetter = UNICODE_NULL; @@ -980,6 +1448,10 @@ InitVolume( return Volume; } + +/**** + ** VOLUME-specific partly (for the FS recognition) + ****/ static VOID AddPartitionToDisk( @@ -1295,7 +1767,6 @@ SetDiskSignature( { LARGE_INTEGER SystemTime; TIME_FIELDS TimeFields; - PLIST_ENTRY Entry2; PDISKENTRY DiskEntry2; PUCHAR Buffer; @@ -1327,12 +1798,9 @@ SetDiskSignature( * Check also signatures from disks, which are * not visible (bootable) by the BIOS. */ - for (Entry2 = List->DiskListHead.Flink; - Entry2 != &List->DiskListHead; - Entry2 = Entry2->Flink) + DiskEntry2 = NULL; + while ((DiskEntry2 = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry2, TRUE))) { - DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry); - if (DiskEntry2->DiskStyle == PARTITION_STYLE_GPT) { DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n"); @@ -1344,7 +1812,7 @@ SetDiskSignature( break; } - if (Entry2 == &List->DiskListHead) + if (!DiskEntry2) break; } } @@ -1354,16 +1822,10 @@ VOID UpdateDiskSignatures( IN PPARTLIST List) { - PLIST_ENTRY Entry; - PDISKENTRY DiskEntry; - /* Update each disk */ - for (Entry = List->DiskListHead.Flink; - Entry != &List->DiskListHead; - Entry = Entry->Flink) + PDISKENTRY DiskEntry = NULL; + while ((DiskEntry = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry, TRUE))) { - DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); - if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT) { DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n"); @@ -1440,6 +1902,9 @@ UpdateHwDiskNumbers( } } +/**** + ** VOLUME-specific partly (for the FS recognition) + ****/ static VOID AddDiskToList( @@ -1689,17 +2154,31 @@ AddDiskToList( (ULONGLONG)DiskGeometry.TracksPerCylinder * (ULONGLONG)DiskGeometry.SectorsPerTrack; +#if 1 DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack; DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder * DiskGeometry.SectorsPerTrack; +#else + // In diskpart... is it correct? + DiskEntry->SectorAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector; + DiskEntry->CylinderAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector; +#endif DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart); DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment); + DPRINT("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment); DiskEntry->DiskNumber = DiskNumber; DiskEntry->Port = ScsiAddress.PortNumber; +#if 1 DiskEntry->Bus = ScsiAddress.PathId; DiskEntry->Id = ScsiAddress.TargetId; +#else + // In diskpart... Do we want to store the full SCSI address? + DiskEntry->PathId = ScsiAddress.PathId; + DiskEntry->TargetId = ScsiAddress.TargetId; + DiskEntry->Lun = ScsiAddress.Lun; +#endif GetDriverName(DiskEntry); /* @@ -1857,7 +2336,6 @@ PDISKENTRY GetSystemDisk( IN PPARTLIST List) { - PLIST_ENTRY Entry; PDISKENTRY DiskEntry; /* Check for empty disk list */ @@ -1872,19 +2350,14 @@ GetSystemDisk( return List->SystemPartition->DiskEntry; /* Loop over the disks and find the correct one */ - for (Entry = List->DiskListHead.Flink; - Entry != &List->DiskListHead; - Entry = Entry->Flink) + DiskEntry = NULL; + while ((DiskEntry = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry, TRUE))) { - DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); - /* The disk must be a fixed disk and be found by the firmware */ if (DiskEntry->MediaType == FixedMedia && DiskEntry->BiosFound) - { break; - } } - if (Entry == &List->DiskListHead) + if (!DiskEntry) { /* We haven't encountered any suitable disk */ return NULL; @@ -1930,7 +2403,6 @@ PPARTENTRY GetActiveDiskPartition( IN PDISKENTRY DiskEntry) { - PLIST_ENTRY ListEntry; PPARTENTRY PartEntry; PPARTENTRY ActivePartition = NULL; @@ -1950,12 +2422,9 @@ GetActiveDiskPartition( } /* Scan all (primary) partitions to find the active disk partition */ - for (ListEntry = DiskEntry->PrimaryPartListHead.Flink; - ListEntry != &DiskEntry->PrimaryPartListHead; - ListEntry = ListEntry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjPartListEntry(&DiskEntry->PrimaryPartListHead, PartEntry, TRUE))) { - /* Retrieve the partition */ - PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); if (IsPartitionActive(PartEntry)) { /* Yes, we've found it */ @@ -2127,22 +2596,16 @@ GetDiskByBiosNumber( _In_ PPARTLIST List, _In_ ULONG HwDiskNumber) { - PDISKENTRY DiskEntry; - PLIST_ENTRY Entry; - /* Loop over the disks and find the correct one */ - for (Entry = List->DiskListHead.Flink; - Entry != &List->DiskListHead; - Entry = Entry->Flink) + PDISKENTRY DiskEntry = NULL; + while ((DiskEntry = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry, TRUE))) { - DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); - if (DiskEntry->HwDiskNumber == HwDiskNumber) - return DiskEntry; /* Disk found, return it */ + break; /* Disk found */ } - /* Disk not found, stop there */ - return NULL; + /* Return the found disk, or NULL if none */ + return DiskEntry; } PDISKENTRY @@ -2150,22 +2613,16 @@ GetDiskByNumber( _In_ PPARTLIST List, _In_ ULONG DiskNumber) { - PDISKENTRY DiskEntry; - PLIST_ENTRY Entry; - /* Loop over the disks and find the correct one */ - for (Entry = List->DiskListHead.Flink; - Entry != &List->DiskListHead; - Entry = Entry->Flink) + PDISKENTRY DiskEntry = NULL; + while ((DiskEntry = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry, TRUE))) { - DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); - if (DiskEntry->DiskNumber == DiskNumber) - return DiskEntry; /* Disk found, return it */ + break; /* Disk found */ } - /* Disk not found, stop there */ - return NULL; + /* Return the found disk, or NULL if none */ + return DiskEntry; } PDISKENTRY @@ -2175,27 +2632,20 @@ GetDiskBySCSI( _In_ USHORT Bus, _In_ USHORT Id) { - PDISKENTRY DiskEntry; - PLIST_ENTRY Entry; - /* Loop over the disks and find the correct one */ - for (Entry = List->DiskListHead.Flink; - Entry != &List->DiskListHead; - Entry = Entry->Flink) + PDISKENTRY DiskEntry = NULL; + while ((DiskEntry = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry, TRUE))) { - DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); - if (DiskEntry->Port == Port && DiskEntry->Bus == Bus && DiskEntry->Id == Id) { - /* Disk found, return it */ - return DiskEntry; + break; /* Disk found */ } } - /* Disk not found, stop there */ - return NULL; + /* Return the found disk, or NULL if none */ + return DiskEntry; } PDISKENTRY @@ -2203,22 +2653,16 @@ GetDiskBySignature( _In_ PPARTLIST List, _In_ ULONG Signature) { - PDISKENTRY DiskEntry; - PLIST_ENTRY Entry; - /* Loop over the disks and find the correct one */ - for (Entry = List->DiskListHead.Flink; - Entry != &List->DiskListHead; - Entry = Entry->Flink) + PDISKENTRY DiskEntry = NULL; + while ((DiskEntry = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry, TRUE))) { - DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); - if (DiskEntry->LayoutBuffer->Signature == Signature) - return DiskEntry; /* Disk found, return it */ + break; /* Disk found */ } - /* Disk not found, stop there */ - return NULL; + /* Return the found disk, or NULL if none */ + return DiskEntry; } PPARTENTRY @@ -2227,19 +2671,15 @@ GetPartition( _In_ ULONG PartitionNumber) { PPARTENTRY PartEntry; - PLIST_ENTRY Entry; /* Forbid whole-disk or extended container partition access */ if (PartitionNumber == 0) return NULL; /* Loop over the primary partitions first... */ - for (Entry = DiskEntry->PrimaryPartListHead.Flink; - Entry != &DiskEntry->PrimaryPartListHead; - Entry = Entry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjPartListEntry(&DiskEntry->PrimaryPartListHead, PartEntry, TRUE))) { - PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); - if (PartEntry->PartitionNumber == PartitionNumber) return PartEntry; /* Partition found, return it */ } @@ -2248,12 +2688,9 @@ GetPartition( return NULL; /* ... then over the logical partitions if needed */ - for (Entry = DiskEntry->LogicalPartListHead.Flink; - Entry != &DiskEntry->LogicalPartListHead; - Entry = Entry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjPartListEntry(&DiskEntry->LogicalPartListHead, PartEntry, TRUE))) { - PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); - if (PartEntry->PartitionNumber == PartitionNumber) return PartEntry; /* Partition found, return it */ } @@ -2287,192 +2724,6 @@ SelectPartition( return PartEntry; } -PPARTENTRY -GetNextPartition( - IN PPARTLIST List, - IN PPARTENTRY CurrentPart OPTIONAL) -{ - PLIST_ENTRY DiskListEntry; - PLIST_ENTRY PartListEntry; - PDISKENTRY CurrentDisk; - - /* Fail if no disks are available */ - if (IsListEmpty(&List->DiskListHead)) - return NULL; - - /* Check for the next usable entry on the current partition's disk */ - if (CurrentPart != NULL) - { - CurrentDisk = CurrentPart->DiskEntry; - - if (CurrentPart->LogicalPartition) - { - /* Logical partition */ - - PartListEntry = CurrentPart->ListEntry.Flink; - if (PartListEntry != &CurrentDisk->LogicalPartListHead) - { - /* Next logical partition */ - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - return CurrentPart; - } - else - { - PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink; - if (PartListEntry != &CurrentDisk->PrimaryPartListHead) - { - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - return CurrentPart; - } - } - } - else - { - /* Primary or extended partition */ - - if (CurrentPart->IsPartitioned && - IsContainerPartition(CurrentPart->PartitionType)) - { - /* First logical partition */ - PartListEntry = CurrentDisk->LogicalPartListHead.Flink; - if (PartListEntry != &CurrentDisk->LogicalPartListHead) - { - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - return CurrentPart; - } - } - else - { - /* Next primary partition */ - PartListEntry = CurrentPart->ListEntry.Flink; - if (PartListEntry != &CurrentDisk->PrimaryPartListHead) - { - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - return CurrentPart; - } - } - } - } - - /* Search for the first partition entry on the next disk */ - for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink - : List->DiskListHead.Flink); - DiskListEntry != &List->DiskListHead; - DiskListEntry = DiskListEntry->Flink) - { - CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry); - - if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT) - { - DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n"); - continue; - } - - PartListEntry = CurrentDisk->PrimaryPartListHead.Flink; - if (PartListEntry != &CurrentDisk->PrimaryPartListHead) - { - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - return CurrentPart; - } - } - - return NULL; -} - -PPARTENTRY -GetPrevPartition( - IN PPARTLIST List, - IN PPARTENTRY CurrentPart OPTIONAL) -{ - PLIST_ENTRY DiskListEntry; - PLIST_ENTRY PartListEntry; - PDISKENTRY CurrentDisk; - - /* Fail if no disks are available */ - if (IsListEmpty(&List->DiskListHead)) - return NULL; - - /* Check for the previous usable entry on the current partition's disk */ - if (CurrentPart != NULL) - { - CurrentDisk = CurrentPart->DiskEntry; - - if (CurrentPart->LogicalPartition) - { - /* Logical partition */ - - PartListEntry = CurrentPart->ListEntry.Blink; - if (PartListEntry != &CurrentDisk->LogicalPartListHead) - { - /* Previous logical partition */ - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - } - else - { - /* Extended partition */ - CurrentPart = CurrentDisk->ExtendedPartition; - } - return CurrentPart; - } - else - { - /* Primary or extended partition */ - - PartListEntry = CurrentPart->ListEntry.Blink; - if (PartListEntry != &CurrentDisk->PrimaryPartListHead) - { - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - - if (CurrentPart->IsPartitioned && - IsContainerPartition(CurrentPart->PartitionType)) - { - PartListEntry = CurrentDisk->LogicalPartListHead.Blink; - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - } - - return CurrentPart; - } - } - } - - /* Search for the last partition entry on the previous disk */ - for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink - : List->DiskListHead.Blink); - DiskListEntry != &List->DiskListHead; - DiskListEntry = DiskListEntry->Blink) - { - CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry); - - if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT) - { - DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n"); - continue; - } - - PartListEntry = CurrentDisk->PrimaryPartListHead.Blink; - if (PartListEntry != &CurrentDisk->PrimaryPartListHead) - { - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - - if (CurrentPart->IsPartitioned && - IsContainerPartition(CurrentPart->PartitionType)) - { - PartListEntry = CurrentDisk->LogicalPartListHead.Blink; - if (PartListEntry != &CurrentDisk->LogicalPartListHead) - { - CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); - return CurrentPart; - } - } - else - { - return CurrentPart; - } - } - } - - return NULL; -} static inline BOOLEAN @@ -2504,15 +2755,12 @@ ULONG GetPartitionCount( _In_ PLIST_ENTRY PartListHead) { - PLIST_ENTRY Entry; PPARTENTRY PartEntry; ULONG Count = 0; - for (Entry = PartListHead->Flink; - Entry != PartListHead; - Entry = Entry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjPartListEntry(PartListHead, PartEntry, TRUE))) { - PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); if (PartEntry->IsPartitioned) ++Count; } @@ -2587,7 +2835,6 @@ UpdateDiskLayout( { PPARTITION_INFORMATION PartitionInfo; PPARTITION_INFORMATION LinkInfo; - PLIST_ENTRY ListEntry; PPARTENTRY PartEntry; LARGE_INTEGER HiddenSectors64; ULONG Index; @@ -2610,12 +2857,9 @@ UpdateDiskLayout( /* Update the primary partition table */ Index = 0; - for (ListEntry = DiskEntry->PrimaryPartListHead.Flink; - ListEntry != &DiskEntry->PrimaryPartListHead; - ListEntry = ListEntry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjPartListEntry(&DiskEntry->PrimaryPartListHead, PartEntry, TRUE))) { - PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); - if (PartEntry->IsPartitioned) { ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED); @@ -2655,12 +2899,9 @@ UpdateDiskLayout( /* Update the logical partition table */ LinkInfo = NULL; Index = 4; - for (ListEntry = DiskEntry->LogicalPartListHead.Flink; - ListEntry != &DiskEntry->LogicalPartListHead; - ListEntry = ListEntry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjPartListEntry(&DiskEntry->LogicalPartListHead, PartEntry, TRUE))) { - PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); - if (PartEntry->IsPartitioned) { ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED); @@ -2782,15 +3023,16 @@ UpdateDiskLayout( * * @return The adjacent unpartitioned region, if it exists, or NULL. **/ +static inline PPARTENTRY GetAdjUnpartitionedEntry( _In_ PPARTENTRY PartEntry, _In_ BOOLEAN Direction) { PDISKENTRY DiskEntry = PartEntry->DiskEntry; - PLIST_ENTRY ListHead, AdjEntry; + PLIST_ENTRY ListHead; - /* In case of MBR disks only, check the logical partitions if necessary */ + /* In case of MBR disks only, check for logical partitions */ if ((DiskEntry->DiskStyle == PARTITION_STYLE_MBR) && PartEntry->LogicalPartition) { @@ -2801,19 +3043,11 @@ GetAdjUnpartitionedEntry( ListHead = &DiskEntry->PrimaryPartListHead; } - if (Direction) - AdjEntry = PartEntry->ListEntry.Flink; // Next region. - else - AdjEntry = PartEntry->ListEntry.Blink; // Previous region. - - if (AdjEntry != ListHead) + PartEntry = GetAdjPartListEntry(ListHead, PartEntry, Direction); + if (PartEntry && !PartEntry->IsPartitioned) { - PartEntry = CONTAINING_RECORD(AdjEntry, PARTENTRY, ListEntry); - if (!PartEntry->IsPartitioned) - { - ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED); - return PartEntry; - } + ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED); + return PartEntry; } return NULL; } @@ -2978,7 +3212,7 @@ DismountPartition( // it has been usually mounted with RawFS and thus needs to be dismounted. PartEntry->PartitionNumber == 0) { - /* The partition is not mounted, so just return success */ + /* The volume is not mounted, just return success */ return STATUS_SUCCESS; } @@ -3226,7 +3460,7 @@ FindSupportedSystemPartition( IN PDISKENTRY AlternativeDisk OPTIONAL, IN PPARTENTRY AlternativePart OPTIONAL) { - PLIST_ENTRY ListEntry; + // PLIST_ENTRY ListEntry; PDISKENTRY DiskEntry; PPARTENTRY PartEntry; PPARTENTRY ActivePartition; @@ -3300,12 +3534,15 @@ FindSupportedSystemPartition( * partitions in the system disk, excluding the possible current active * partition, to find a new candidate. */ - for (ListEntry = DiskEntry->PrimaryPartListHead.Flink; - ListEntry != &DiskEntry->PrimaryPartListHead; - ListEntry = ListEntry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjDiskRegion(DiskEntry, PartEntry, + ENUM_REGION_NEXT | ENUM_REGION_MBR_PRIMARY_ONLY))) + // for (ListEntry = DiskEntry->PrimaryPartListHead.Flink; + // ListEntry != &DiskEntry->PrimaryPartListHead; + // ListEntry = ListEntry->Flink) { - /* Retrieve the partition */ - PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); + // /* Retrieve the partition */ + // PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); /* Skip the current active partition */ if (PartEntry == ActivePartition) @@ -3350,12 +3587,15 @@ FindSupportedSystemPartition( // if (GetPrimaryPartitionCount(DiskEntry) < 4) { - for (ListEntry = DiskEntry->PrimaryPartListHead.Flink; - ListEntry != &DiskEntry->PrimaryPartListHead; - ListEntry = ListEntry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjDiskRegion(DiskEntry, PartEntry, + ENUM_REGION_NEXT | ENUM_REGION_MBR_PRIMARY_ONLY))) + // for (ListEntry = DiskEntry->PrimaryPartListHead.Flink; + // ListEntry != &DiskEntry->PrimaryPartListHead; + // ListEntry = ListEntry->Flink) { - /* Retrieve the partition */ - PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); + // /* Retrieve the partition */ + // PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); /* Skip the current active partition */ if (PartEntry == ActivePartition) @@ -3414,8 +3654,10 @@ UseAlternativeDisk: ***/ /* Retrieve the first partition of the disk */ - PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink, - PARTENTRY, ListEntry); + // PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink, + // PARTENTRY, ListEntry); + PartEntry = GetAdjDiskRegion(DiskEntry, NULL, + ENUM_REGION_NEXT | ENUM_REGION_MBR_PRIMARY_ONLY); ASSERT(DiskEntry == PartEntry->DiskEntry); CandidatePartition = PartEntry; @@ -3449,12 +3691,15 @@ UseAlternativeDisk: * The disk is not new, check if any partition is initialized; * if not, the first one becomes the system partition. */ - for (ListEntry = DiskEntry->PrimaryPartListHead.Flink; - ListEntry != &DiskEntry->PrimaryPartListHead; - ListEntry = ListEntry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjDiskRegion(DiskEntry, PartEntry, + ENUM_REGION_NEXT | ENUM_REGION_MBR_PRIMARY_ONLY))) + // for (ListEntry = DiskEntry->PrimaryPartListHead.Flink; + // ListEntry != &DiskEntry->PrimaryPartListHead; + // ListEntry = ListEntry->Flink) { - /* Retrieve the partition */ - PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); + // /* Retrieve the partition */ + // PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); /* Check if the partition is partitioned and is used */ // !IsContainerPartition(PartEntry->PartitionType); @@ -3464,7 +3709,8 @@ UseAlternativeDisk: break; } } - if (ListEntry == &DiskEntry->PrimaryPartListHead) + // if (ListEntry == &DiskEntry->PrimaryPartListHead) + if (!PartEntry) { /* * OK we haven't encountered any used and active partition, @@ -3595,7 +3841,6 @@ WritePartitions( ULONG BufferSize; PPARTITION_INFORMATION PartitionInfo; ULONG PartitionCount; - PLIST_ENTRY ListEntry; PPARTENTRY PartEntry; WCHAR DstPath[MAX_PATH]; @@ -3680,12 +3925,11 @@ WritePartitions( /* Update the partition numbers and device names */ +#if 0 /* Update the primary partition table */ - for (ListEntry = DiskEntry->PrimaryPartListHead.Flink; - ListEntry != &DiskEntry->PrimaryPartListHead; - ListEntry = ListEntry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjPartListEntry(&DiskEntry->PrimaryPartListHead, PartEntry, TRUE))) { - PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); if (!PartEntry->IsPartitioned) continue; ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED); @@ -3708,11 +3952,9 @@ WritePartitions( } /* Update the logical partition table */ - for (ListEntry = DiskEntry->LogicalPartListHead.Flink; - ListEntry != &DiskEntry->LogicalPartListHead; - ListEntry = ListEntry->Flink) + PartEntry = NULL; + while ((PartEntry = GetAdjPartListEntry(&DiskEntry->LogicalPartListHead, PartEntry, TRUE))) { - PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); if (!PartEntry->IsPartitioned) continue; ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED); @@ -3726,6 +3968,19 @@ WritePartitions( } PartEntry->New = FALSE; } +#else + /* Update the partition table */ + PartEntry = NULL; + while ((PartEntry = GetAdjDiskRegion(DiskEntry, PartEntry, + ENUM_REGION_NEXT | ENUM_REGION_PARTITIONED))) + { + // ASSERT(PartEntry->IsPartitioned); + // ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED); + PartEntry->New = FALSE; + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex]; + PartEntry->PartitionNumber = PartitionInfo->PartitionNumber; + } +#endif // // NOTE: Originally (see r40437), we used to install here also a new MBR @@ -3751,7 +4006,6 @@ WritePartitionsToDisk( IN PPARTLIST List) { NTSTATUS Status; - PLIST_ENTRY Entry; PDISKENTRY DiskEntry; PVOLENTRY Volume; @@ -3759,12 +4013,9 @@ WritePartitionsToDisk( return TRUE; /* Write all the partitions to all the disks */ - for (Entry = List->DiskListHead.Flink; - Entry != &List->DiskListHead; - Entry = Entry->Flink) + DiskEntry = NULL; + while ((DiskEntry = GetAdjDiskListEntry(&List->DiskListHead, DiskEntry, TRUE))) { - DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); - if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT) { DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n"); diff --git a/base/setup/lib/utils/partlist.h b/base/setup/lib/utils/partlist.h index fb20f1500c0..4eb4dc1c05c 100644 --- a/base/setup/lib/utils/partlist.h +++ b/base/setup/lib/utils/partlist.h @@ -12,6 +12,9 @@ // NOTE: They should be moved into some global header. +// /* We have to define it there, because it is not in the MS DDK */ +// #define PARTITION_LINUX 0x83 + /* OEM MBR partition types recognized by NT (see [MS-DMRP] Appendix B) */ #define PARTITION_EISA 0x12 // EISA partition #define PARTITION_HIBERNATION 0x84 // Hibernation partition for laptops @@ -129,8 +132,9 @@ typedef struct _DISKENTRY ULONG DiskNumber; // SCSI_ADDRESS; USHORT Port; - USHORT Bus; - USHORT Id; + USHORT Bus; // PathId; + USHORT Id; // TargetId; + // USHORT Lun; /* Has the partition list been modified? */ BOOLEAN Dirty; @@ -258,6 +262,51 @@ RoundingDivide( ((DiskEntry)->SectorCount.QuadPart * (DiskEntry)->BytesPerSector) +#define ENUM_REGION_NEXT 0x00 //< Enumerate the next region (default) +#define ENUM_REGION_PREV 0x01 //< Enumerate the previous region +#define ENUM_REGION_PARTITIONED 0x02 //< Enumerate only partitioned regions (otherwise, enumerate all regions, including free space) +// 0x04, 0x08 reserved +#define ENUM_REGION_MBR_PRIMARY_ONLY 0x10 //< MBR disks only: Enumerate only primary regions +#define ENUM_REGION_MBR_LOGICAL_ONLY 0x20 //< MBR disks only: Enumerate only logical regions +#define ENUM_REGION_MBR_BY_ORDER 0x40 //< MBR disks only: Enumerate by order on disk (may traverse extended partitions to enumerate the logical ones in-between), instead of by type (first all primary, then all logical) +/* +they are listed in actual +order of appearance on a given disk. For example for MBR disks, all +_primary_ partitions are enumerated first, before _logical_ partitions. +*/ +// 0x80 reserved + +PPARTENTRY +GetAdjDiskRegion( + _In_opt_ PDISKENTRY CurrentDisk, + _In_opt_ PPARTENTRY CurrentPart, + _In_ ULONG EnumFlags); + +PPARTENTRY +GetAdjPartition( + _In_ PPARTLIST List, + _In_opt_ PPARTENTRY CurrentPart, + _In_ ULONG EnumFlags); + +#if 0 // FIXME Temporary +PPARTENTRY +GetNextPartition( + IN PPARTLIST List, + IN PPARTENTRY CurrentPart OPTIONAL); + +PPARTENTRY +GetPrevPartition( + IN PPARTLIST List, + IN PPARTENTRY CurrentPart OPTIONAL); + +PPARTENTRY +GetAdjUnpartitionedEntry( + _In_ PPARTENTRY PartEntry, + _In_ BOOLEAN Direction); +#endif // FIXME Temporary + + + BOOLEAN IsDiskSuperFloppy2( _In_ const DISK_PARTITION_INFO* DiskInfo, @@ -322,21 +371,6 @@ SelectPartition( _In_ ULONG DiskNumber, _In_ ULONG PartitionNumber); -PPARTENTRY -GetNextPartition( - IN PPARTLIST List, - IN PPARTENTRY CurrentPart OPTIONAL); - -PPARTENTRY -GetPrevPartition( - IN PPARTLIST List, - IN PPARTENTRY CurrentPart OPTIONAL); - -PPARTENTRY -GetAdjUnpartitionedEntry( - _In_ PPARTENTRY PartEntry, - _In_ BOOLEAN Direction); - ERROR_NUMBER PartitionCreationChecks( _In_ PPARTENTRY PartEntry); diff --git a/base/setup/lib/utils/volutil.c b/base/setup/lib/utils/volutil.c index 153488542a0..b4883083dcf 100644 --- a/base/setup/lib/utils/volutil.c +++ b/base/setup/lib/utils/volutil.c @@ -2,22 +2,261 @@ * PROJECT: ReactOS Setup Library * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Volume utility functions - * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto + * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ -#include "precomp.h" - -#include "volutil.h" -#include "fsrec.h" -#include "devutils.h" +#include "diskpart.h" +#include #define NDEBUG #include +/* GLOBALS ********************************************************************/ + +LIST_ENTRY VolumeListHead; + +/* FUNCTIONS THAT CAME FROM PARTLIST TODO USE THEM ****************************/ + +// AssignDriveLetters + +// DetectFileSystem + + +/* FUNCTIONS ******************************************************************/ + +#if 0 // FIXME +// +// FIXME: Improve +// +static +VOID +GetVolumeExtents( + _In_ HANDLE VolumeHandle, + _In_ PVOLENTRY VolumeEntry) +{ + DWORD dwBytesReturned = 0, dwLength, i; + PVOLUME_DISK_EXTENTS pExtents; + BOOL bResult; + DWORD dwError; + + dwLength = sizeof(VOLUME_DISK_EXTENTS); + pExtents = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, dwLength); + if (pExtents == NULL) + return; + + bResult = DeviceIoControl(VolumeHandle, + IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, + NULL, + 0, + pExtents, + dwLength, + &dwBytesReturned, + NULL); + if (!bResult) + { + dwError = GetLastError(); + + if (dwError != ERROR_MORE_DATA) + { + RtlFreeHeap(ProcessHeap, 0, pExtents); + return; + } + else + { + dwLength = sizeof(VOLUME_DISK_EXTENTS) + ((pExtents->NumberOfDiskExtents - 1) * sizeof(DISK_EXTENT)); + RtlFreeHeap(ProcessHeap, 0, pExtents); + pExtents = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, dwLength); + if (pExtents == NULL) + { + return; + } + + bResult = DeviceIoControl(VolumeHandle, + IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, + NULL, + 0, + pExtents, + dwLength, + &dwBytesReturned, + NULL); + if (!bResult) + { + RtlFreeHeap(ProcessHeap, 0, pExtents); + return; + } + } + } + + for (i = 0; i < pExtents->NumberOfDiskExtents; i++) + VolumeEntry->Size.QuadPart += pExtents->Extents[i].ExtentLength.QuadPart; + + VolumeEntry->pExtents = pExtents; +} + +// +// FIXME: Improve +// +static +VOID +GetVolumeType( + _In_ HANDLE VolumeHandle, + _In_ PVOLENTRY VolumeEntry) +{ + FILE_FS_DEVICE_INFORMATION DeviceInfo; + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; + + Status = NtQueryVolumeInformationFile(VolumeHandle, + &IoStatusBlock, + &DeviceInfo, + sizeof(FILE_FS_DEVICE_INFORMATION), + FileFsDeviceInformation); + if (!NT_SUCCESS(Status)) + return; + + switch (DeviceInfo.DeviceType) + { + case FILE_DEVICE_CD_ROM: + case FILE_DEVICE_CD_ROM_FILE_SYSTEM: + VolumeEntry->VolumeType = VOLUME_TYPE_CDROM; + break; + + case FILE_DEVICE_DISK: + case FILE_DEVICE_DISK_FILE_SYSTEM: + if (DeviceInfo.Characteristics & FILE_REMOVABLE_MEDIA) + VolumeEntry->VolumeType = VOLUME_TYPE_REMOVABLE; + else + VolumeEntry->VolumeType = VOLUME_TYPE_PARTITION; + break; + + default: + VolumeEntry->VolumeType = VOLUME_TYPE_UNKNOWN; + break; + } +} + +// +// FIXME: Improve +// +static +VOID +AddVolumeToList( + ULONG ulVolumeNumber, + PWSTR pszVolumeName) +{ + PVOLENTRY VolumeEntry; + HANDLE VolumeHandle; + + DWORD dwError, dwLength; + WCHAR szPathNames[MAX_PATH + 1]; + WCHAR szVolumeName[MAX_PATH + 1]; + WCHAR szFilesystem[MAX_PATH + 1]; + + DWORD CharCount = 0; + size_t Index = 0; + + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + + DPRINT("AddVolumeToList(%S)\n", pszVolumeName); + + VolumeEntry = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(VOLENTRY)); + if (VolumeEntry == NULL) + return; + + VolumeEntry->VolumeNumber = ulVolumeNumber; + wcscpy(VolumeEntry->VolumeName, pszVolumeName); + + Index = wcslen(pszVolumeName) - 1; + + pszVolumeName[Index] = L'\0'; + + CharCount = QueryDosDeviceW(&pszVolumeName[4], VolumeEntry->DeviceName, ARRAYSIZE(VolumeEntry->DeviceName)); + + pszVolumeName[Index] = L'\\'; + + if (CharCount == 0) + { + RtlFreeHeap(ProcessHeap, 0, VolumeEntry); + return; + } + + DPRINT("DeviceName: %S\n", VolumeEntry->DeviceName); + + RtlInitUnicodeString(&Name, VolumeEntry->DeviceName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&VolumeHandle, + SYNCHRONIZE, + &ObjectAttributes, + &Iosb, + 0, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT); + if (NT_SUCCESS(Status)) + { + GetVolumeType(VolumeHandle, VolumeEntry); + GetVolumeExtents(VolumeHandle, VolumeEntry); + NtClose(VolumeHandle); + } + + if (GetVolumeInformationW(pszVolumeName, + szVolumeName, + MAX_PATH + 1, + NULL, // [out, optional] LPDWORD lpVolumeSerialNumber, + NULL, // [out, optional] LPDWORD lpMaximumComponentLength, + NULL, // [out, optional] LPDWORD lpFileSystemFlags, + szFilesystem, + MAX_PATH + 1)) + { + VolumeEntry->pszLabel = RtlAllocateHeap(ProcessHeap, + 0, + (wcslen(szVolumeName) + 1) * sizeof(WCHAR)); + if (VolumeEntry->pszLabel) + wcscpy(VolumeEntry->pszLabel, szVolumeName); + + VolumeEntry->pszFilesystem = RtlAllocateHeap(ProcessHeap, + 0, + (wcslen(szFilesystem) + 1) * sizeof(WCHAR)); + if (VolumeEntry->pszFilesystem) + wcscpy(VolumeEntry->pszFilesystem, szFilesystem); + } + else + { + dwError = GetLastError(); + if (dwError == ERROR_UNRECOGNIZED_VOLUME) + { + VolumeEntry->pszFilesystem = RtlAllocateHeap(ProcessHeap, + 0, + (3 + 1) * sizeof(WCHAR)); + if (VolumeEntry->pszFilesystem) + wcscpy(VolumeEntry->pszFilesystem, L"RAW"); + } + } + + if (GetVolumePathNamesForVolumeNameW(pszVolumeName, + szPathNames, + ARRAYSIZE(szPathNames), + &dwLength)) + { + VolumeEntry->DriveLetter = szPathNames[0]; + } + + InsertTailList(&VolumeListHead, + &VolumeEntry->ListEntry); +} +#endif -/* FUNCTIONS *****************************************************************/ NTSTATUS MountVolume( @@ -25,11 +264,36 @@ MountVolume( _In_opt_ UCHAR MbrPartitionType) { NTSTATUS Status; + UNICODE_STRING Name; HANDLE VolumeHandle; - /* If the volume is already mounted, just return success */ - if (*Volume->FileSystem) +#if 0 + /* Reset some volume information */ + Volume->DriveLetter = L'\0'; + Volume->FileSystem[0] = L'\0'; + RtlZeroMemory(Volume->VolumeLabel, sizeof(Volume->VolumeLabel)); +#endif + + /* Specify the partition as initially unformatted */ + Volume->FileSystem[0] = L'\0'; + + /* Initialize the partition volume label */ + RtlZeroMemory(Volume->VolumeLabel, sizeof(Volume->VolumeLabel)); + +#if 0 + if (!IsRecognizedPartition(MbrPartitionType)) + { + /* Unknown partition, hence unknown format (may or may not be actually formatted) */ + Volume->FormatState = UnknownFormat; return STATUS_SUCCESS; + } +#else + if (!*Volume->DeviceName) + { + /* No volume attached, bail out */ + return STATUS_SUCCESS; + } +#endif /* Try to open the volume so as to mount it */ VolumeHandle = NULL; @@ -47,7 +311,7 @@ MountVolume( } ASSERT(VolumeHandle); - /* We don't have a FS, try to guess one */ + /* Try to guess the mounted FS */ Status = InferFileSystem(NULL, VolumeHandle, Volume->FileSystem, sizeof(Volume->FileSystem)); @@ -158,7 +422,7 @@ DismountVolume( HANDLE VolumeHandle; /* If the volume is not mounted, just return success */ - if (!*Volume->FileSystem) + if (!*Volume->DeviceName || !*Volume->FileSystem) return STATUS_SUCCESS; /* Open the volume */ @@ -223,4 +487,160 @@ DismountVolume( return Status; } + +// +// FIXME: Improve; for the moment a temporary function is written below. +// +#if 0 +NTSTATUS +CreateVolumeList( + _Out_ PLIST_ENTRY VolumeListHead) +{ + BOOL Success; + HANDLE hVolume = INVALID_HANDLE_VALUE; + ULONG ulVolumeNumber = 0; + WCHAR szVolumeName[MAX_PATH]; + + InitializeListHead(VolumeListHead); + + hVolume = FindFirstVolumeW(szVolumeName, ARRAYSIZE(szVolumeName)); + if (hVolume == INVALID_HANDLE_VALUE) + { + return STATUS_UNSUCCESSFUL; + } + + AddVolumeToList(ulVolumeNumber++, szVolumeName); + + for (;;) + { + Success = FindNextVolumeW(hVolume, szVolumeName, ARRAYSIZE(szVolumeName)); + if (!Success) + { + break; + } + + AddVolumeToList(ulVolumeNumber++, szVolumeName); + } + + FindVolumeClose(hVolume); + + return STATUS_SUCCESS; +} +#else +NTSTATUS +CreateVolumeList( + _Out_ PLIST_ENTRY VolumeListHead) +{ +} +#endif + + +// +// FIXME: Improve, see also DestroyVolumeList +// +#if 0 +VOID +RemoveVolume( + _In_ PVOLENTRY VolumeEntry) +{ + RemoveEntryList(&VolumeEntry->ListEntry); + + if (VolumeEntry->pszLabel) + RtlFreeHeap(ProcessHeap, 0, VolumeEntry->pszLabel); + + if (VolumeEntry->pszFilesystem) + RtlFreeHeap(ProcessHeap, 0, VolumeEntry->pszFilesystem); + + if (VolumeEntry->pExtents) + RtlFreeHeap(ProcessHeap, 0, VolumeEntry->pExtents); + + /* Release volume entry */ + RtlFreeHeap(ProcessHeap, 0, VolumeEntry); +} +#else +VOID +RemoveVolume( + _In_ PVOLENTRY VolumeEntry) +{ + // VolumeEntry->FormatState = Unformatted; + // VolumeEntry->FileSystem[0] = L'\0'; + // VolumeEntry->DriveLetter = 0; + // RtlZeroMemory(VolumeEntry->VolumeLabel, sizeof(VolumeEntry->VolumeLabel)); + RtlFreeHeap(ProcessHeap, 0, VolumeEntry); +} +#endif + +// +// TODO: Improve, see also RemoveVolume +// +VOID +DestroyVolumeList( + _In_ PLIST_ENTRY VolumeListHead) +{ + PLIST_ENTRY Entry; + PVOLENTRY VolumeEntry; + + /* Release volume info */ + while (!IsListEmpty(VolumeListHead)) + { + Entry = RemoveHeadList(VolumeListHead); + VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry); + + if (VolumeEntry->pszLabel) + RtlFreeHeap(ProcessHeap, 0, VolumeEntry->pszLabel); + + if (VolumeEntry->pszFilesystem) + RtlFreeHeap(ProcessHeap, 0, VolumeEntry->pszFilesystem); + + if (VolumeEntry->pExtents) + RtlFreeHeap(ProcessHeap, 0, VolumeEntry->pExtents); + + /* Release volume entry */ + RtlFreeHeap(ProcessHeap, 0, VolumeEntry); + } +} + +// +// TODO: Improve. For example, do this calculation lookup while +// listing the volumes during list creation, then here, just do +// a quick lookup (for example each VOLENTRY could contain a +// linked-list to the partition(s) on which it is based upon). +// +PVOLENTRY +GetVolumeFromPartition( + _In_ PLIST_ENTRY VolumeListHead, + _In_ PPARTENTRY PartEntry) +{ + PLIST_ENTRY Entry; + PVOLENTRY VolumeEntry; + ULONG i; + + if (!PartEntry || !PartEntry->DiskEntry) + return NULL; + + for (Entry = VolumeListHead->Flink; + Entry != VolumeListHead; + Entry = Entry->Flink) + { + VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry); + + if (VolumeEntry->pExtents == NULL) + return NULL; + + for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++) + { + if (VolumeEntry->pExtents->Extents[i].DiskNumber == PartEntry->DiskEntry->DiskNumber) + { + if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) && + (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector)) + { + return VolumeEntry; + } + } + } + } + + return NULL; +} + /* EOF */ diff --git a/base/setup/lib/utils/volutil.h b/base/setup/lib/utils/volutil.h index 2763bb89844..157d981aec8 100644 --- a/base/setup/lib/utils/volutil.h +++ b/base/setup/lib/utils/volutil.h @@ -2,38 +2,106 @@ * PROJECT: ReactOS Setup Library * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Volume utility functions - * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto + * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto */ #pragma once +/* EXTRA HANDFUL MACROS *****************************************************/ + +// NOTE: They should be moved into some global header. + +// /* We have to define it there, because it is not in the MS DDK */ +// #define PARTITION_LINUX 0x83 + +/* OEM MBR partition types recognized by NT (see [MS-DMRP] Appendix B) */ +#define PARTITION_EISA 0x12 // EISA partition +#define PARTITION_HIBERNATION 0x84 // Hibernation partition for laptops +#define PARTITION_DIAGNOSTIC 0xA0 // Diagnostic partition on some Hewlett-Packard (HP) notebooks +#define PARTITION_DELL 0xDE // Dell partition +#define PARTITION_IBM 0xFE // IBM Initial Microprogram Load (IML) partition + +#define IsOEMPartition(PartitionType) \ + ( ((PartitionType) == PARTITION_EISA) || \ + ((PartitionType) == PARTITION_HIBERNATION) || \ + ((PartitionType) == PARTITION_DIAGNOSTIC) || \ + ((PartitionType) == PARTITION_DELL) || \ + ((PartitionType) == PARTITION_IBM) ) + + +/* VOLUME UTILITY FUNCTIONS *************************************************/ + +// FORMATSTATE + +typedef enum _VOLUME_TYPE +{ + VOLUME_TYPE_CDROM, + VOLUME_TYPE_PARTITION, + VOLUME_TYPE_REMOVABLE, + VOLUME_TYPE_UNKNOWN +} VOLUME_TYPE, *PVOLUME_TYPE; + +#if 0 +// +// This is the structure from diskpart +// +typedef struct _VOLENTRY +{ + LIST_ENTRY ListEntry; + + ULONG VolumeNumber; + WCHAR VolumeName[MAX_PATH]; + WCHAR DeviceName[MAX_PATH]; + + WCHAR DriveLetter; + + PWSTR pszLabel; + PWSTR pszFilesystem; + VOLUME_TYPE VolumeType; + ULARGE_INTEGER Size; + + PVOLUME_DISK_EXTENTS pExtents; + +} VOLENTRY, *PVOLENTRY; +#else + typedef struct _VOLINFO { - // WCHAR VolumeName[MAX_PATH]; ///< Name in the DOS/Win32 namespace: "\??\Volume{GUID}\" - WCHAR DeviceName[MAX_PATH]; ///< NT device name: "\Device\HarddiskVolumeN" + // LIST_ENTRY ListEntry; + + // WCHAR VolumeName[MAX_PATH]; // Name in the DOS/Win32 namespace + WCHAR DeviceName[MAX_PATH]; // NT device name WCHAR DriveLetter; WCHAR VolumeLabel[20]; WCHAR FileSystem[MAX_PATH+1]; + FORMATSTATE FormatState; + +/** The following properties may be replaced by flags **/ + + /* Volume is new and has not yet been actually formatted and mounted */ + BOOLEAN New; + + /* Volume must be checked */ + BOOLEAN NeedsCheck; - // VOLUME_TYPE VolumeType; - // ULARGE_INTEGER Size; - // PVOLUME_DISK_EXTENTS Extents; } VOLINFO, *PVOLINFO; -/* RawFS "RAW" file system name */ -#define IS_RAWFS(fs) \ - ((fs)[0] == 'R' && (fs)[1] == 'A' && (fs)[2] == 'W' && (fs)[3] == 0) +#define VOLENTRY VOLINFO +#define PVOLENTRY PVOLINFO -#define IsUnknown(VolInfo) \ - (!*(VolInfo)->FileSystem) +#endif -#define IsUnformatted(VolInfo) \ - IS_RAWFS((VolInfo)->FileSystem) -#define IsFormatted(VolInfo) \ - (!IsUnknown(VolInfo) && !IsUnformatted(VolInfo)) +// static +VOID +AssignDriveLetters( + IN PPARTLIST List); +NTSTATUS +DetectFileSystem( + _Inout_ PPARTENTRY PartEntry) // FIXME: Replace by volume entry +; NTSTATUS MountVolume( @@ -45,4 +113,14 @@ DismountVolume( _Inout_ PVOLINFO Volume, _In_ BOOLEAN Force); +// BOOLEAN +// SetMountedDeviceValue( +// IN WCHAR Letter, +// IN ULONG Signature, +// IN LARGE_INTEGER StartingOffset); + +// BOOLEAN +// SetMountedDeviceValues( +// IN PPARTLIST List); + /* EOF */ diff --git a/base/setup/reactos/reactos.c b/base/setup/reactos/reactos.c index 3909f104e20..363a42113d9 100644 --- a/base/setup/reactos/reactos.c +++ b/base/setup/reactos/reactos.c @@ -650,7 +650,19 @@ AddNTOSInstallationItem( IN SIZE_T cchBufferSize) { PNTOS_INSTALLATION NtOsInstall = (PNTOS_INSTALLATION)GetListEntryData(Entry); - PVOLINFO VolInfo = (NtOsInstall->Volume ? &NtOsInstall->Volume->Info : NULL); + PPARTENTRY PartEntry; + PVOLINFO VolInfo; + + /* Retrieve the volume corresponding to the disk and partition numbers */ + PartEntry = SelectPartition(SetupData.PartitionList, + NtOsInstall->DiskNumber, + NtOsInstall->PartitionNumber); + if (!PartEntry) + { + DPRINT1("SelectPartition(disk #%d, partition #%d) failed\n", + NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber); + } + VolInfo = (PartEntry && PartEntry->Volume ? &PartEntry->Volume->Info : NULL); if (VolInfo && VolInfo->DriveLetter) { @@ -1521,9 +1533,6 @@ FsVolCallback( // EndFormat(FmtInfo->ErrorStatus); if (FmtInfo->FileSystemName) *(PWSTR)FmtInfo->FileSystemName = UNICODE_NULL; // FIXME: HACK! - - // /* Reset the file system list */ - // ResetFileSystemList(); return 0; } diff --git a/base/setup/usetup/partlist.c b/base/setup/usetup/partlist.c index a7eb50a8b59..afd1741c6a5 100644 --- a/base/setup/usetup/partlist.c +++ b/base/setup/usetup/partlist.c @@ -559,7 +559,7 @@ PrintDiskData( DiskEntry, PrimaryPartEntry); - if (IsContainerPartition(PrimaryPartEntry->PartitionType)) + if (PrimaryPartEntry == DiskEntry->ExtendedPartition) { for (LogicalEntry = DiskEntry->LogicalPartListHead.Flink; LogicalEntry != &DiskEntry->LogicalPartListHead; @@ -843,8 +843,9 @@ ScrollUpDownPartitionList( _In_ BOOLEAN Direction) { PPARTENTRY PartEntry = - (Direction ? GetNextPartition - : GetPrevPartition)(ListUi->List, ListUi->CurrentPartition); + GetAdjPartition(ListUi->List, ListUi->CurrentPartition, + (Direction ? ENUM_REGION_NEXT : ENUM_REGION_PREV) + | ENUM_REGION_MBR_BY_ORDER); if (PartEntry) { ListUi->CurrentPartition = PartEntry; diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index 806353223a8..c9f790b327b 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -512,7 +512,19 @@ GetNTOSInstallationName( IN SIZE_T cchBufferSize) { PNTOS_INSTALLATION NtOsInstall = (PNTOS_INSTALLATION)GetListEntryData(Entry); - PVOLINFO VolInfo = (NtOsInstall->Volume ? &NtOsInstall->Volume->Info : NULL); + PPARTENTRY PartEntry; + PVOLINFO VolInfo; + + /* Retrieve the volume corresponding to the disk and partition numbers */ + PartEntry = SelectPartition(PartitionList, + NtOsInstall->DiskNumber, + NtOsInstall->PartitionNumber); + if (!PartEntry) + { + DPRINT1("SelectPartition(disk #%d, partition #%d) failed\n", + NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber); + } + VolInfo = (PartEntry && PartEntry->Volume ? &PartEntry->Volume->Info : NULL); if (VolInfo && VolInfo->DriveLetter) {