From 005d881ce1cc678d98b660a39cca6d447a98e289 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 18 May 2014 15:14:24 +0000 Subject: [PATCH] [USETUP] First part of the partition management code rewrite. This part fixes the handling of primary partitions. Extended partitions and logical drives are not handled yet. Safety checks and warnings are still missing! Partitions created by the new code are accepted by gparted and Windows. svn path=/trunk/; revision=63355 --- reactos/base/setup/usetup/bootsup.c | 8 +- reactos/base/setup/usetup/interface/usetup.c | 251 ++- reactos/base/setup/usetup/partlist.c | 1888 ++++++++---------- reactos/base/setup/usetup/partlist.h | 50 +- 4 files changed, 953 insertions(+), 1244 deletions(-) diff --git a/reactos/base/setup/usetup/bootsup.c b/reactos/base/setup/usetup/bootsup.c index 74d5ad3ffff..183641cfca0 100644 --- a/reactos/base/setup/usetup/bootsup.c +++ b/reactos/base/setup/usetup/bootsup.c @@ -1444,7 +1444,6 @@ InstallFat16BootCodeToDisk( NTSTATUS Status; PFAT_BOOTSECTOR OrigBootSector; PFAT_BOOTSECTOR NewBootSector; - PARTITION_INFORMATION *PartInfo; /* Allocate buffer for original bootsector */ OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); @@ -1543,8 +1542,7 @@ InstallFat16BootCodeToDisk( FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); - PartInfo = &PartitionList->CurrentPartition->PartInfo[PartitionList->CurrentPartitionNumber]; - NewBootSector->HiddenSectors = PartInfo->HiddenSectors; + NewBootSector->HiddenSectors = PartitionList->CurrentDisk->SectorsPerTrack; /* Free the original boot sector */ RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -1606,7 +1604,6 @@ InstallFat32BootCodeToDisk( PFAT32_BOOTSECTOR NewBootSector; LARGE_INTEGER FileOffset; USHORT BackupBootSector; - PARTITION_INFORMATION *PartInfo; /* Allocate buffer for original bootsector */ OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); @@ -1704,8 +1701,7 @@ InstallFat32BootCodeToDisk( FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); - PartInfo = &PartitionList->CurrentPartition->PartInfo[PartitionList->CurrentPartitionNumber]; - NewBootSector->HiddenSectors = PartInfo->HiddenSectors; + NewBootSector->HiddenSectors = PartitionList->CurrentDisk->SectorsPerTrack; /* Get the location of the backup boot sector */ BackupBootSector = OrigBootSector->BackupBootSector; diff --git a/reactos/base/setup/usetup/interface/usetup.c b/reactos/base/setup/usetup/interface/usetup.c index 8ba4d858be9..c0c597e617c 100644 --- a/reactos/base/setup/usetup/interface/usetup.c +++ b/reactos/base/setup/usetup/interface/usetup.c @@ -1428,6 +1428,7 @@ LayoutSettingsPage(PINPUT_RECORD Ir) } +#if 0 static BOOL IsDiskSizeValid(PPARTENTRY PartEntry) { @@ -1456,6 +1457,7 @@ IsDiskSizeValid(PPARTENTRY PartEntry) return TRUE; } } +#endif static PAGE_NUMBER @@ -1512,32 +1514,32 @@ SelectPartitionPage(PINPUT_RECORD Ir) { if (AutoPartition) { - PPARTENTRY PartEntry = PartitionList->CurrentPartition; - ULONG MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; /* in MBytes (rounded) */ - if(!IsDiskSizeValid(PartitionList->CurrentPartition)) +#if 0 + if (!IsDiskSizeValid(PartitionList->CurrentPartition)) { MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY); return SELECT_PARTITION_PAGE; /* let the user select another partition */ } - +#endif CreateNewPartition(PartitionList, - MaxSize, + PartitionList->CurrentPartition->SectorCount.QuadPart, TRUE); - DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter[0]; + DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter; return SELECT_FILE_SYSTEM_PAGE; } } else { - if(!IsDiskSizeValid(PartitionList->CurrentPartition)) +#if 0 + if (!IsDiskSizeValid(PartitionList->CurrentPartition)) { MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY); return SELECT_PARTITION_PAGE; /* let the user select another partition */ } - - DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter[0]; +#endif + DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter; return SELECT_FILE_SYSTEM_PAGE; } @@ -1547,7 +1549,7 @@ SelectPartitionPage(PINPUT_RECORD Ir) { /* Update status text */ if (PartitionList->CurrentPartition == NULL || - PartitionList->CurrentPartition->Unpartitioned == TRUE) + PartitionList->CurrentPartition->IsPartitioned == FALSE) { CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION)); } @@ -1582,26 +1584,28 @@ SelectPartitionPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */ { - if(!IsDiskSizeValid(PartitionList->CurrentPartition)) +#if 0 + if (!IsDiskSizeValid(PartitionList->CurrentPartition)) { MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY); return SELECT_PARTITION_PAGE; /* let the user select another partition */ } +#endif if (PartitionList->CurrentPartition == NULL || - PartitionList->CurrentPartition->Unpartitioned == TRUE) + PartitionList->CurrentPartition->IsPartitioned == FALSE) { CreateNewPartition(PartitionList, 0ULL, TRUE); } - DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter[0]; + DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter; return SELECT_FILE_SYSTEM_PAGE; } else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'C') /* C */ { - if (PartitionList->CurrentPartition->Unpartitioned == FALSE) + if (PartitionList->CurrentPartition->IsPartitioned == TRUE) { MUIDisplayError(ERROR_NEW_PARTITION, Ir, POPUP_WAIT_ANY_KEY); return SELECT_PARTITION_PAGE; @@ -1611,7 +1615,7 @@ SelectPartitionPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'D') /* D */ { - if (PartitionList->CurrentPartition->Unpartitioned == TRUE) + if (PartitionList->CurrentPartition->IsPartitioned == FALSE) { MUIDisplayError(ERROR_DELETE_SPACE, Ir, POPUP_WAIT_ANY_KEY); return SELECT_PARTITION_PAGE; @@ -1779,6 +1783,7 @@ CreatePartitionPage(PINPUT_RECORD Ir) ULONG MaxSize; ULONGLONG PartSize; ULONGLONG DiskSize; + ULONGLONG SectorCount; PCHAR Unit; if (PartitionList == NULL || @@ -1796,17 +1801,17 @@ CreatePartitionPage(PINPUT_RECORD Ir) CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION)); + DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */ + if (DiskSize >= 10737418240) /* 10 GB */ { - DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30; + DiskSize = DiskSize / 1073741824; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20; - + DiskSize = DiskSize / 1048576; if (DiskSize == 0) DiskSize = 1; @@ -1841,7 +1846,7 @@ CreatePartitionPage(PINPUT_RECORD Ir) #if 0 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB", - PartitionList->CurrentPartition->UnpartitionedLength / (1024*1024)); + PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / 1048576); #endif CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION)); @@ -1849,9 +1854,10 @@ CreatePartitionPage(PINPUT_RECORD Ir) PartEntry = PartitionList->CurrentPartition; while (TRUE) { - MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; /* in MBytes (rounded) */ + MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / 1048576; /* in MBytes (rounded) */ - if (MaxSize > PARTITION_MAXSIZE) MaxSize = PARTITION_MAXSIZE; + if (MaxSize > PARTITION_MAXSIZE) + MaxSize = PARTITION_MAXSIZE; ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17, /* left, top, right, bottom */ MaxSize, InputBuffer, &Quit, &Cancel); @@ -1887,23 +1893,22 @@ CreatePartitionPage(PINPUT_RECORD Ir) if (PartSize == MaxSize) { /* Use all of the unpartitioned disk space */ - PartSize = PartEntry->UnpartitionedLength; + SectorCount = PartEntry->SectorCount.QuadPart; } else { - /* Round-up by cylinder size */ - PartSize = (PartSize * 1024 * 1024 + DiskEntry->CylinderSize - 1) / - DiskEntry->CylinderSize * DiskEntry->CylinderSize; + /* Calculate the sector count from the size in MB */ + SectorCount = PartSize * 1048576 / DiskEntry->BytesPerSector; /* But never get larger than the unpartitioned disk space */ - if (PartSize > PartEntry->UnpartitionedLength) - PartSize = PartEntry->UnpartitionedLength; + if (SectorCount > PartEntry->SectorCount.QuadPart) + SectorCount = PartEntry->SectorCount.QuadPart; } DPRINT ("Partition size: %I64u bytes\n", PartSize); CreateNewPartition(PartitionList, - PartSize, + SectorCount, FALSE); return SELECT_PARTITION_PAGE; @@ -1923,7 +1928,6 @@ DeletePartitionPage(PINPUT_RECORD Ir) ULONGLONG PartSize; PCHAR Unit; PCHAR PartType; - UCHAR PartNumber; if (PartitionList == NULL || PartitionList->CurrentDisk == NULL || @@ -1935,7 +1939,6 @@ DeletePartitionPage(PINPUT_RECORD Ir) DiskEntry = PartitionList->CurrentDisk; PartEntry = PartitionList->CurrentPartition; - PartNumber = PartitionList->CurrentPartitionNumber; MUIDisplayPage(DELETE_PARTITION_PAGE); @@ -1945,46 +1948,47 @@ DeletePartitionPage(PINPUT_RECORD Ir) { PartType = MUIGetString(STRING_UNFORMATTED); } - else if (PartEntry->Unpartitioned == FALSE) + else if (PartEntry->IsPartitioned == TRUE) { - if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_12) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_16) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_HUGE) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_XINT13)) + if ((PartEntry->PartitionType == PARTITION_FAT_12) || + (PartEntry->PartitionType == PARTITION_FAT_16) || + (PartEntry->PartitionType == PARTITION_HUGE) || + (PartEntry->PartitionType == PARTITION_XINT13)) { PartType = "FAT"; } - else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13)) + else if ((PartEntry->PartitionType == PARTITION_FAT32) || + (PartEntry->PartitionType == PARTITION_FAT32_XINT13)) { PartType = "FAT32"; } - else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2) + else if (PartEntry->PartitionType == PARTITION_EXT2) { PartType = "EXT2"; } - else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS) + else if (PartEntry->PartitionType == PARTITION_IFS) { PartType = "NTFS"; /* FIXME: Not quite correct! */ } } + PartSize = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */ + if (PartSize >= 10737418240) /* 10 GB */ { - PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30; + PartSize = PartSize / 1073741824; Unit = MUIGetString(STRING_GB); } else #endif - if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */ + if (PartSize >= 10485760) /* 10 MB */ { - PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20; + PartSize = PartSize / 1048576; Unit = MUIGetString(STRING_MB); } else { - PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 9)) >> 10; + PartSize = PartSize / 1024; Unit = MUIGetString(STRING_KB); } @@ -1992,9 +1996,9 @@ DeletePartitionPage(PINPUT_RECORD Ir) { CONSOLE_PrintTextXY(6, 10, MUIGetString(STRING_HDDINFOUNK2), - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', - PartEntry->PartInfo[PartNumber].PartitionType, + (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : ':', + PartEntry->PartitionType, PartSize, Unit); } @@ -2002,24 +2006,24 @@ DeletePartitionPage(PINPUT_RECORD Ir) { CONSOLE_PrintTextXY(6, 10, " %c%c %s %I64u %s", - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', + (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : ':', PartType, PartSize, Unit); } + DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */ + if (DiskSize >= 10737418240) /* 10 GB */ { - DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30; + DiskSize = DiskSize / 1073741824; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20; - + DiskSize = DiskSize / 1048576; if (DiskSize == 0) DiskSize = 1; @@ -2085,7 +2089,6 @@ SelectFileSystemPage(PINPUT_RECORD Ir) { PDISKENTRY DiskEntry; PPARTENTRY PartEntry; - UCHAR PartNumber; ULONGLONG DiskSize; ULONGLONG PartSize; PCHAR DiskUnit; @@ -2102,54 +2105,55 @@ SelectFileSystemPage(PINPUT_RECORD Ir) DiskEntry = PartitionList->CurrentDisk; PartEntry = PartitionList->CurrentPartition; - PartNumber = PartitionList->CurrentPartitionNumber; /* adjust disk size */ - if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */ + DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; + if (DiskSize >= 10737418240) /* 10 GB */ { - DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30; + DiskSize = DiskSize / 1073741824; DiskUnit = MUIGetString(STRING_GB); } else { - DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20; + DiskSize = DiskSize / 1048576; DiskUnit = MUIGetString(STRING_MB); } /* adjust partition size */ - if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */ + PartSize = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; + if (PartSize >= 10737418240) /* 10 GB */ { - PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30; + PartSize = PartSize / 1073741824; PartUnit = MUIGetString(STRING_GB); } else { - PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20; + PartSize = PartSize / 1048576; PartUnit = MUIGetString(STRING_MB); } /* adjust partition type */ - if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_12) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_16) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_HUGE) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_XINT13)) + if ((PartEntry->PartitionType == PARTITION_FAT_12) || + (PartEntry->PartitionType == PARTITION_FAT_16) || + (PartEntry->PartitionType == PARTITION_HUGE) || + (PartEntry->PartitionType == PARTITION_XINT13)) { PartType = "FAT"; } - else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13)) + else if ((PartEntry->PartitionType == PARTITION_FAT32) || + (PartEntry->PartitionType == PARTITION_FAT32_XINT13)) { PartType = "FAT32"; } - else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2) + else if (PartEntry->PartitionType == PARTITION_EXT2) { PartType = "EXT2"; } - else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS) + else if (PartEntry->PartitionType == PARTITION_IFS) { PartType = "NTFS"; /* FIXME: Not quite correct! */ } - else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_ENTRY_UNUSED) + else if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED) { PartType = MUIGetString(STRING_FORMATUNUSED); } @@ -2164,7 +2168,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) #if 0 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of", - PartEntry->PartInfo[PartNumber].PartitionNumber, + PartEntry->PartitionNumber, PartSize, PartUnit, PartType); @@ -2197,9 +2201,9 @@ SelectFileSystemPage(PINPUT_RECORD Ir) { CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDDINFOUNK4), - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', - PartEntry->PartInfo[PartNumber].PartitionType, + (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : ':', + PartEntry->PartitionType, PartSize, PartUnit); } @@ -2207,8 +2211,8 @@ SelectFileSystemPage(PINPUT_RECORD Ir) { CONSOLE_PrintTextXY(8, 10, "%c%c %s %I64u %s", - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', + (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : ':', PartType, PartSize, PartUnit); @@ -2237,6 +2241,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) /* FIXME: Add file systems to list */ } + DrawFileSystemList(FileSystemList); if (RepairUpdateFlag) @@ -2305,12 +2310,11 @@ static ULONG FormatPartitionPage(PINPUT_RECORD Ir) { WCHAR PathBuffer[MAX_PATH]; + PDISKENTRY DiskEntry; PPARTENTRY PartEntry; - UCHAR PartNum; NTSTATUS Status; #ifndef NDEBUG - PDISKENTRY DiskEntry; ULONG Line; ULONG i; PLIST_ENTRY Entry; @@ -2326,11 +2330,8 @@ FormatPartitionPage(PINPUT_RECORD Ir) return QUIT_PAGE; } -#ifndef NDEBUG DiskEntry = PartitionList->CurrentDisk; -#endif PartEntry = PartitionList->CurrentPartition; - PartNum = PartitionList->CurrentPartitionNumber; while (TRUE) { @@ -2355,50 +2356,55 @@ FormatPartitionPage(PINPUT_RECORD Ir) if (wcscmp(FileSystemList->Selected->FileSystem, L"FAT") == 0) { - if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (4200LL * 1024LL)) + if (PartEntry->SectorCount.QuadPart < 8192) { /* FAT12 CHS partition (disk is smaller than 4.1MB) */ - PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT_12; + PartEntry->PartitionType = PARTITION_FAT_12; } - else if (PartEntry->PartInfo[PartNum].StartingOffset.QuadPart < (1024LL * 255LL * 63LL * 512LL)) + else if (PartEntry->StartSector.QuadPart < 1450560) { /* Partition starts below the 8.4GB boundary ==> CHS partition */ - if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (32LL * 1024LL * 1024LL)) + if (PartEntry->SectorCount.QuadPart < 65536) { /* FAT16 CHS partition (partiton size < 32MB) */ - PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT_16; + PartEntry->PartitionType = PARTITION_FAT_16; } - else if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL)) + else if (PartEntry->SectorCount.QuadPart < 1048576) { /* FAT16 CHS partition (partition size < 512MB) */ - PartEntry->PartInfo[PartNum].PartitionType = PARTITION_HUGE; + PartEntry->PartitionType = PARTITION_HUGE; } else { /* FAT32 CHS partition (partition size >= 512MB) */ - PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT32; + PartEntry->PartitionType = PARTITION_FAT32; } } else { /* Partition starts above the 8.4GB boundary ==> LBA partition */ - if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL)) + if (PartEntry->SectorCount.QuadPart < 1048576) { /* FAT16 LBA partition (partition size < 512MB) */ - PartEntry->PartInfo[PartNum].PartitionType = PARTITION_XINT13; + PartEntry->PartitionType = PARTITION_XINT13; } else { /* FAT32 LBA partition (partition size >= 512MB) */ - PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT32_XINT13; + PartEntry->PartitionType = PARTITION_FAT32_XINT13; } } + + DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType; } #if 0 else if (wcscmp(FileSystemList->Selected->FileSystem, L"EXT2") == 0) + { PartEntry->PartInfo[PartNum].PartitionType = PARTITION_EXT2; + DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType; + } #endif else if (!FileSystemList->Selected->FormatFunc) return QUIT_PAGE; @@ -2414,27 +2420,21 @@ FormatPartitionPage(PINPUT_RECORD Ir) DiskEntry = PartitionList->CurrentDisk; Entry = DiskEntry->PartListHead.Flink; - while (Entry != &DiskEntry->PartListHead) + while (Entry != &DiskEntry->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); - if (PartEntry->Unpartitioned == FALSE) + if (PartEntry->IsPartitioned == TRUE) { - for (i = 0; i < 4; i++) - { - CONSOLE_PrintTextXY(6, Line, - "%2u: %2u %c %12I64u %12I64u %2u %c", - i, - PartEntry->PartInfo[i].PartitionNumber, - PartEntry->PartInfo[i].BootIndicator ? 'A' : '-', - PartEntry->PartInfo[i].StartingOffset.QuadPart, - PartEntry->PartInfo[i].PartitionLength.QuadPart, - PartEntry->PartInfo[i].PartitionType, - PartEntry->PartInfo[i].RewritePartition ? '*' : ' '); - - Line++; - } - + CONSOLE_PrintTextXY(6, Line, + "%2u: %2u %c %12I64u %12I64u %2u %c", + i, + PartEntry->PartitionNumber, + PartEntry->BootIndicator ? 'A' : '-', + PartEntry->StartSector.QuadPart, + PartEntry->SectorCount.QuadPart, + PartEntry->PartitionType, + PartEntry->Dirty ? '*' : ' '); Line++; } @@ -2445,6 +2445,8 @@ FormatPartitionPage(PINPUT_RECORD Ir) PartEntry = PartitionList->CurrentPartition; #endif + CheckActiveBootPartition(PartitionList); + if (WritePartitionsToDisk(PartitionList) == FALSE) { DPRINT("WritePartitionsToDisk() failed\n"); @@ -2457,7 +2459,7 @@ FormatPartitionPage(PINPUT_RECORD Ir) swprintf(PathBuffer, L"\\Device\\Harddisk%lu\\Partition%lu", PartitionList->CurrentDisk->DiskNumber, - PartitionList->CurrentPartition->PartInfo[PartNum].PartitionNumber); + PartitionList->CurrentPartition->PartitionNumber); RtlCreateUnicodeString(&DestinationRootPath, PathBuffer); DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath); @@ -2475,7 +2477,6 @@ FormatPartitionPage(PINPUT_RECORD Ir) PartEntry->New = FALSE; - CheckActiveBootPartition(PartitionList); } #ifndef NDEBUG @@ -2500,7 +2501,6 @@ CheckFileSystemPage(PINPUT_RECORD Ir) WCHAR PathBuffer[MAX_PATH]; CHAR Buffer[MAX_PATH]; NTSTATUS Status; - UCHAR PartNum = PartitionList->CurrentPartitionNumber; /* FIXME: code duplicated in FormatPartitionPage */ /* Set DestinationRootPath */ @@ -2508,7 +2508,7 @@ CheckFileSystemPage(PINPUT_RECORD Ir) swprintf(PathBuffer, L"\\Device\\Harddisk%lu\\Partition%lu", PartitionList->CurrentDisk->DiskNumber, - PartitionList->CurrentPartition->PartInfo[PartNum].PartitionNumber); + PartitionList->CurrentPartition->PartitionNumber); RtlCreateUnicodeString(&DestinationRootPath, PathBuffer); DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath); @@ -2574,8 +2574,7 @@ CheckFileSystemPage(PINPUT_RECORD Ir) static PAGE_NUMBER InstallDirectoryPage1(PWCHAR InstallDir, PDISKENTRY DiskEntry, - PPARTENTRY PartEntry, - UCHAR PartNum) + PPARTENTRY PartEntry) { WCHAR PathBuffer[MAX_PATH]; @@ -2599,7 +2598,7 @@ InstallDirectoryPage1(PWCHAR InstallDir, swprintf(PathBuffer, L"multi(0)disk(0)rdisk(%lu)partition(%lu)", DiskEntry->BiosDiskNumber, - PartEntry->PartInfo[PartNum].PartitionNumber); + PartEntry->PartitionNumber); if (InstallDir[0] != L'\\') wcscat(PathBuffer, L"\\"); @@ -2643,8 +2642,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir) { return InstallDirectoryPage1(InstallDir, DiskEntry, - PartEntry, - PartitionList->CurrentPartitionNumber); + PartEntry); } while (TRUE) @@ -2663,8 +2661,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir) { return InstallDirectoryPage1(InstallDir, DiskEntry, - PartEntry, - PartitionList->CurrentPartitionNumber); + PartEntry); } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */ { @@ -3382,14 +3379,12 @@ BootLoaderPage(PINPUT_RECORD Ir) swprintf(PathBuffer, L"\\Device\\Harddisk%lu\\Partition%lu", PartitionList->ActiveBootDisk->DiskNumber, - PartitionList->ActiveBootPartition-> - PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionNumber); + PartitionList->ActiveBootPartition->PartitionNumber); RtlCreateUnicodeString(&SystemRootPath, PathBuffer); DPRINT("SystemRootPath: %wZ\n", &SystemRootPath); - PartitionType = PartitionList->ActiveBootPartition-> - PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType; + PartitionType = PartitionList->ActiveBootPartition->PartitionType; if (IsUnattendedSetup) { @@ -3573,8 +3568,7 @@ BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir) UCHAR PartitionType; NTSTATUS Status; - PartitionType = PartitionList->ActiveBootPartition-> - PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType; + PartitionType = PartitionList->ActiveBootPartition->PartitionType; Status = InstallVBRToPartition(&SystemRootPath, &SourceRootPath, @@ -3598,8 +3592,7 @@ BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir) WCHAR SourceMbrPathBuffer[MAX_PATH]; /* Step 1: Write the VBR */ - PartitionType = PartitionList->ActiveBootPartition-> - PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType; + PartitionType = PartitionList->ActiveBootPartition->PartitionType; Status = InstallVBRToPartition(&SystemRootPath, &SourceRootPath, diff --git a/reactos/base/setup/usetup/partlist.c b/reactos/base/setup/usetup/partlist.c index c81ce910581..3312e217c76 100644 --- a/reactos/base/setup/usetup/partlist.c +++ b/reactos/base/setup/usetup/partlist.c @@ -31,8 +31,58 @@ #define NDEBUG #include +#define DUMP_PARTITION_TABLE + /* FUNCTIONS ****************************************************************/ +#ifdef DUMP_PARTITION_TABLE +static +VOID +DumpPartitionTable( + PDISKENTRY DiskEntry) +{ + PPARTITION_INFORMATION PartitionInfo; + ULONG i; + + for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++) + { + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i]; + DbgPrint("%lu: %12I64u %12I64u %10lu %2lu %2x %c %c\n", + i, + PartitionInfo->StartingOffset.QuadPart, + PartitionInfo->PartitionLength.QuadPart, + PartitionInfo->HiddenSectors, + PartitionInfo->PartitionNumber, + PartitionInfo->PartitionType, + PartitionInfo->BootIndicator ? '*': ' ', + PartitionInfo->RewritePartition ? 'Y': 'N'); + } +} +#endif + + +ULONGLONG +Align( + IN ULONGLONG Value, + IN ULONG Alignment) +{ + ULONGLONG Temp; + + Temp = Value / Alignment; + + return Temp * Alignment; +} + + +ULONGLONG +RoundingDivide( + IN ULONGLONG Dividend, + IN ULONGLONG Divisor) +{ + return (Dividend + Divisor / 2) / Divisor; +} + + static VOID GetDriverName( @@ -70,15 +120,14 @@ GetDriverName( static VOID -AssignDriverLetters( +AssignDriveLetters( PPARTLIST List) { PDISKENTRY DiskEntry; PPARTENTRY PartEntry; PLIST_ENTRY Entry1; - //PLIST_ENTRY Entry2; + PLIST_ENTRY Entry2; CHAR Letter; - UCHAR i; Letter = 'C'; @@ -88,34 +137,29 @@ AssignDriverLetters( { DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); - if (!IsListEmpty(&DiskEntry->PartListHead)) + Entry2 = DiskEntry->PrimaryPartListHead.Flink; + while (Entry2 != &DiskEntry->PrimaryPartListHead) { - PartEntry = CONTAINING_RECORD(DiskEntry->PartListHead.Flink, - PARTENTRY, - ListEntry); + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); - for (i = 0; i < 4; i++) - PartEntry->DriveLetter[i] = 0; + PartEntry->DriveLetter = 0; - if (PartEntry->Unpartitioned == FALSE) + if (PartEntry->IsPartitioned && + !IsContainerPartition(PartEntry->PartitionType)) { - for (i = 0; i < 4; i++) + if (IsRecognizedPartition(PartEntry->PartitionType) || + (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED && + PartEntry->SectorCount.QuadPart != 0LL)) { - if (IsContainerPartition(PartEntry->PartInfo[i].PartitionType)) - continue; - - if (IsRecognizedPartition(PartEntry->PartInfo[i].PartitionType) || - (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED && - PartEntry->PartInfo[i].PartitionLength.QuadPart != 0LL)) + if (Letter <= 'Z') { - if (Letter <= 'Z') - { - PartEntry->DriveLetter[i] = Letter; - Letter++; - } + PartEntry->DriveLetter = Letter; + Letter++; } } } + + Entry2 = Entry2->Flink; } Entry1 = Entry1->Flink; @@ -172,43 +216,38 @@ UpdatePartitionNumbers( { PPARTENTRY PartEntry; PLIST_ENTRY Entry; - ULONG PartNumber; - ULONG i; +// ULONG PartitionNumber = 1; + ULONG PartitionIndex = 0; - PartNumber = 1; - Entry = DiskEntry->PartListHead.Flink; - while (Entry != &DiskEntry->PartListHead) + Entry = DiskEntry->PrimaryPartListHead.Flink; + while (Entry != &DiskEntry->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); - if (PartEntry->Unpartitioned == TRUE) + if (PartEntry->IsPartitioned == FALSE) { - for (i = 0; i < 4; i++) - { - PartEntry->PartInfo[i].PartitionNumber = 0; - } +// PartEntry->PartitionNumber = 0; + PartEntry->PartitionIndex = (ULONG)-1; } else { - for (i = 0; i < 4; i++) + if (IsContainerPartition(PartEntry->PartitionType)) { - if (IsContainerPartition(PartEntry->PartInfo[i].PartitionType)) - { - PartEntry->PartInfo[i].PartitionNumber = 0; - } - else if (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED && - PartEntry->PartInfo[i].PartitionLength.QuadPart == 0ULL) - { - PartEntry->PartInfo[i].PartitionNumber = 0; - } - else - { - PartEntry->PartInfo[i].PartitionNumber = PartNumber; - PartNumber++; - } +// PartEntry->PartitionNumber = 0; } + else if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED && + PartEntry->SectorCount.QuadPart == 0ULL) + { +// PartEntry->PartitionNumber = 0; + } + else + { +// PartEntry->PartitionNumber = PartitionNumber++; + } + + PartEntry->PartitionIndex = PartitionIndex++; } Entry = Entry->Flink; @@ -216,247 +255,6 @@ UpdatePartitionNumbers( } -static -VOID -AddPartitionToList( - ULONG DiskNumber, - PDISKENTRY DiskEntry, - DRIVE_LAYOUT_INFORMATION *LayoutBuffer) -{ - PPARTENTRY PartEntry; - ULONG i; - ULONG j; - - for (i = 0; i < LayoutBuffer->PartitionCount; i += 4) - { - for (j = 0; j < 4; j++) - { - if (LayoutBuffer->PartitionEntry[i+j].PartitionType != PARTITION_ENTRY_UNUSED || - LayoutBuffer->PartitionEntry[i+j].PartitionLength.QuadPart != 0ULL) - { - break; - } - } - - if (j >= 4) - { - continue; - } - - PartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(PARTENTRY)); - if (PartEntry == NULL) - { - return; - } - - RtlZeroMemory(PartEntry, - sizeof(PARTENTRY)); - - PartEntry->Unpartitioned = FALSE; - - for (j = 0; j < 4; j++) - { - RtlCopyMemory(&PartEntry->PartInfo[j], - &LayoutBuffer->PartitionEntry[i+j], - sizeof(PARTITION_INFORMATION)); - } - - if (IsContainerPartition(PartEntry->PartInfo[0].PartitionType)) - { - PartEntry->FormatState = Unformatted; - } - else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13)) - { -#if 0 - if (CheckFatFormat()) - { - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = Unformatted; - } -#endif - PartEntry->FormatState = Preformatted; - } - else if (PartEntry->PartInfo[0].PartitionType == PARTITION_EXT2) - { -#if 0 - if (CheckExt2Format()) - { - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = Unformatted; - } -#endif - PartEntry->FormatState = Preformatted; - } - else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS) - { -#if 0 - if (CheckNtfsFormat()) - { - PartEntry->FormatState = Preformatted; - } - else if (CheckHpfsFormat()) - { - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = Unformatted; - } -#endif - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = UnknownFormat; - } - - InsertTailList(&DiskEntry->PartListHead, - &PartEntry->ListEntry); - } -} - - -static -VOID -ScanForUnpartitionedDiskSpace( - PDISKENTRY DiskEntry) -{ - ULONGLONG LastStartingOffset; - ULONGLONG LastPartitionLength; - ULONGLONG LastUnusedPartitionLength; - PPARTENTRY PartEntry; - PPARTENTRY NewPartEntry; - PLIST_ENTRY Entry; - ULONG i; - ULONG j; - - if (IsListEmpty (&DiskEntry->PartListHead)) - { - /* Create a partition table that represents the empty disk */ - PartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(PARTENTRY)); - if (PartEntry == NULL) - return; - - RtlZeroMemory(PartEntry, - sizeof(PARTENTRY)); - - PartEntry->Unpartitioned = TRUE; - PartEntry->UnpartitionedOffset = 0ULL; - PartEntry->UnpartitionedLength = DiskEntry->DiskSize; - - PartEntry->FormatState = Unformatted; - - InsertTailList(&DiskEntry->PartListHead, - &PartEntry->ListEntry); - } - else - { - /* Start partition at head 1, cylinder 0 */ - LastStartingOffset = DiskEntry->TrackSize; - LastPartitionLength = 0ULL; - LastUnusedPartitionLength = 0ULL; - - i = 0; - Entry = DiskEntry->PartListHead.Flink; - while (Entry != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); - - for (j = 0; j < 4; j++) - { - if ((!IsContainerPartition (PartEntry->PartInfo[j].PartitionType)) && - (PartEntry->PartInfo[j].PartitionType != PARTITION_ENTRY_UNUSED || - PartEntry->PartInfo[j].PartitionLength.QuadPart != 0LL)) - { - LastUnusedPartitionLength = - PartEntry->PartInfo[j].StartingOffset.QuadPart - - (LastStartingOffset + LastPartitionLength); - - if (PartEntry->PartInfo[j].StartingOffset.QuadPart > (LastStartingOffset + LastPartitionLength) && - LastUnusedPartitionLength >= DiskEntry->CylinderSize) - { - DPRINT("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength); - - NewPartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(PARTENTRY)); - if (NewPartEntry == NULL) - return; - - RtlZeroMemory(NewPartEntry, - sizeof(PARTENTRY)); - - NewPartEntry->Unpartitioned = TRUE; - NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength; - NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength; - if (j == 0) - NewPartEntry->UnpartitionedLength -= DiskEntry->TrackSize; - - NewPartEntry->FormatState = Unformatted; - - /* Insert the table into the list */ - InsertTailList(&PartEntry->ListEntry, - &NewPartEntry->ListEntry); - } - - LastStartingOffset = PartEntry->PartInfo[j].StartingOffset.QuadPart; - LastPartitionLength = PartEntry->PartInfo[j].PartitionLength.QuadPart; - } - } - - i += 4; - Entry = Entry->Flink; - } - - /* Check for trailing unpartitioned disk space */ - if (DiskEntry->DiskSize > (LastStartingOffset + LastPartitionLength)) - { - /* Round-down to cylinder size */ - LastUnusedPartitionLength = - (DiskEntry->DiskSize - (LastStartingOffset + LastPartitionLength)) - & ~(DiskEntry->CylinderSize - 1); - - if (LastUnusedPartitionLength >= DiskEntry->CylinderSize) - { - DPRINT("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength); - - NewPartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(PARTENTRY)); - if (NewPartEntry == NULL) - return; - - RtlZeroMemory(NewPartEntry, - sizeof(PARTENTRY)); - - NewPartEntry->Unpartitioned = TRUE; - NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength; - NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength; - - /* Append the table to the list */ - InsertTailList(&DiskEntry->PartListHead, - &NewPartEntry->ListEntry); - } - } - } -} - - NTSTATUS NTAPI DiskIdentifierQueryRoutine( @@ -720,6 +518,311 @@ EnumerateBiosDiskEntries( } +static +VOID +AddPrimaryPartitionToDisk( + ULONG DiskNumber, + PDISKENTRY DiskEntry, + ULONG PartitionIndex) +{ + PPARTITION_INFORMATION PartitionInfo; + PPARTENTRY PartEntry; + + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex]; + + PartEntry = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(PARTENTRY)); + if (PartEntry == NULL) + { + return; + } + + PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector; + PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector; + + PartEntry->BootIndicator = PartitionInfo->BootIndicator; + PartEntry->PartitionType = PartitionInfo->PartitionType; + PartEntry->HiddenSectors = PartitionInfo->HiddenSectors; + + PartEntry->IsPartitioned = TRUE; + PartEntry->PartitionNumber = PartitionInfo->PartitionNumber; + PartEntry->PartitionIndex = PartitionIndex; + + if (IsContainerPartition(PartEntry->PartitionType)) + { + PartEntry->FormatState = Unformatted; + } + else if ((PartEntry->PartitionType == PARTITION_FAT_12) || + (PartEntry->PartitionType == PARTITION_FAT_16) || + (PartEntry->PartitionType == PARTITION_HUGE) || + (PartEntry->PartitionType == PARTITION_XINT13) || + (PartEntry->PartitionType == PARTITION_FAT32) || + (PartEntry->PartitionType == PARTITION_FAT32_XINT13)) + { +#if 0 + if (CheckFatFormat()) + { + PartEntry->FormatState = Preformatted; + } + else + { + PartEntry->FormatState = Unformatted; + } +#endif + PartEntry->FormatState = Preformatted; + } + else if (PartEntry->PartitionType == PARTITION_EXT2) + { +#if 0 + if (CheckExt2Format()) + { + PartEntry->FormatState = Preformatted; + } + else + { + PartEntry->FormatState = Unformatted; + } +#endif + PartEntry->FormatState = Preformatted; + } + else if (PartEntry->PartitionType == PARTITION_IFS) + { +#if 0 + if (CheckNtfsFormat()) + { + PartEntry->FormatState = Preformatted; + } + else if (CheckHpfsFormat()) + { + PartEntry->FormatState = Preformatted; + } + else + { + PartEntry->FormatState = Unformatted; + } +#endif + PartEntry->FormatState = Preformatted; + } + else + { + PartEntry->FormatState = UnknownFormat; + } + + InsertTailList(&DiskEntry->PrimaryPartListHead, + &PartEntry->ListEntry); +} + + +static +VOID +ScanForUnpartitionedDiskSpace( + PDISKENTRY DiskEntry) +{ + ULONGLONG LastStartSector; + ULONGLONG LastSectorCount; + ULONGLONG LastUnusedSectorCount; + PPARTENTRY PartEntry; + PPARTENTRY NewPartEntry; + PLIST_ENTRY Entry; + + DPRINT1("ScanForUnpartitionedDiskSpace()\n"); + + if (IsListEmpty(&DiskEntry->PrimaryPartListHead)) + { + DPRINT1("No primary partition!\n"); + + /* Create a partition table that represents the empty disk */ + NewPartEntry = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(PARTENTRY)); + if (NewPartEntry == NULL) + return; + + NewPartEntry->DiskEntry = DiskEntry; + + NewPartEntry->IsPartitioned = FALSE; + NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorsPerTrack; + NewPartEntry->SectorCount.QuadPart = Align(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - + DiskEntry->SectorsPerTrack; +DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); +DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); +DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); + + NewPartEntry->FormatState = Unformatted; + + InsertTailList(&DiskEntry->PrimaryPartListHead, + &NewPartEntry->ListEntry); + + return; + } + + /* Start partition at head 1, cylinder 0 */ + LastStartSector = DiskEntry->SectorsPerTrack; + LastSectorCount = 0ULL; + LastUnusedSectorCount = 0ULL; + + Entry = DiskEntry->PrimaryPartListHead.Flink; + while (Entry != &DiskEntry->PrimaryPartListHead) + { + PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); + + if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || + PartEntry->SectorCount.QuadPart != 0ULL) + { + LastUnusedSectorCount = + PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount); + + if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) && + LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) + { + DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount); + + NewPartEntry = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(PARTENTRY)); + if (NewPartEntry == NULL) + return; + + NewPartEntry->DiskEntry = DiskEntry; + + NewPartEntry->IsPartitioned = FALSE; + NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; + NewPartEntry->SectorCount.QuadPart = Align(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - + NewPartEntry->StartSector.QuadPart; +DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); +DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); +DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); + + NewPartEntry->FormatState = Unformatted; + + /* Insert the table into the list */ + InsertTailList(&PartEntry->ListEntry, + &NewPartEntry->ListEntry); + } + + LastStartSector = PartEntry->StartSector.QuadPart; + LastSectorCount = PartEntry->SectorCount.QuadPart; + } + + Entry = Entry->Flink; + } + + /* Check for trailing unpartitioned disk space */ + if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart) + { + LastUnusedSectorCount = Align(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment); + + if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) + { + DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount); + + NewPartEntry = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(PARTENTRY)); + if (NewPartEntry == NULL) + return; + + NewPartEntry->DiskEntry = DiskEntry; + + NewPartEntry->IsPartitioned = FALSE; + NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; + NewPartEntry->SectorCount.QuadPart = Align(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - + NewPartEntry->StartSector.QuadPart; +DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); +DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); +DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); + + NewPartEntry->FormatState = Unformatted; + + /* Append the table to the list */ + InsertTailList(&DiskEntry->PrimaryPartListHead, + &NewPartEntry->ListEntry); + } + } + + DPRINT1("ScanForUnpartitionedDiskSpace() done\n"); +} + + +static +VOID +SetDiskSignature( + IN PPARTLIST List, + IN PDISKENTRY DiskEntry) +{ + LARGE_INTEGER SystemTime; + TIME_FIELDS TimeFields; + PLIST_ENTRY Entry2; + PDISKENTRY DiskEntry2; + PUCHAR Buffer; + + Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature; + + while (1) + { + NtQuerySystemTime(&SystemTime); + RtlTimeToTimeFields(&SystemTime, &TimeFields); + + Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF); + Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF); + Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF); + Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF); + + if (DiskEntry->LayoutBuffer->Signature == 0) + { + continue; + } + + /* check if the signature already exist */ + /* FIXME: + * Check also signatures from disks, which are + * not visible (bootable) by the bios. + */ + Entry2 = List->DiskListHead.Flink; + while (Entry2 != &List->DiskListHead) + { + DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry); + + if (DiskEntry != DiskEntry2 && + DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature) + break; + + Entry2 = Entry2->Flink; + } + + if (Entry2 == &List->DiskListHead) + break; + } +} + + +static +VOID +UpdateDiskSignatures( + PPARTLIST List) +{ + PLIST_ENTRY Entry; + PDISKENTRY DiskEntry; + + /* Print partition lines*/ + Entry = List->DiskListHead.Flink; + while (Entry != &List->DiskListHead) + { + DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); + + if (DiskEntry->LayoutBuffer && + DiskEntry->LayoutBuffer->Signature == 0) + { + SetDiskSignature(List, DiskEntry); + DiskEntry->LayoutBuffer->PartitionEntry[0].RewritePartition = TRUE; + } + + Entry = Entry->Flink; + } +} + + static VOID AddDiskToList( @@ -727,7 +830,6 @@ AddDiskToList( ULONG DiskNumber, PPARTLIST List) { - DRIVE_LAYOUT_INFORMATION *LayoutBuffer; DISK_GEOMETRY DiskGeometry; SCSI_ADDRESS ScsiAddress; PDISKENTRY DiskEntry; @@ -820,21 +922,16 @@ AddDiskToList( swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature); DPRINT("Identifier: %S\n", Identifier); - DiskEntry = (PDISKENTRY)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(DISKENTRY)); + DiskEntry = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(DISKENTRY)); if (DiskEntry == NULL) { return; } - DiskEntry->Checksum = Checksum; - DiskEntry->Signature = Signature; - if (Signature == 0) - { - /* If we have no signature, set the disk to dirty. WritePartitionsToDisk creates a new signature */ - DiskEntry->Modified = TRUE; - } +// DiskEntry->Checksum = Checksum; +// DiskEntry->Signature = Signature; DiskEntry->BiosFound = FALSE; /* Check if this disk has a valid MBR */ @@ -885,27 +982,27 @@ AddDiskToList( #endif } - InitializeListHead(&DiskEntry->PartListHead); + InitializeListHead(&DiskEntry->PrimaryPartListHead); + InitializeListHead(&DiskEntry->ExtendedPartListHead); DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart; DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder; DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack; DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector; - DPRINT ("Cylinders %I64u\n", DiskEntry->Cylinders); - DPRINT ("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder); - DPRINT ("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack); - DPRINT ("BytesPerSector %I64u\n", DiskEntry->BytesPerSector); + DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders); + DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder); + DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack); + DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector); - DiskEntry->TrackSize = - (ULONGLONG)DiskGeometry.SectorsPerTrack * - (ULONGLONG)DiskGeometry.BytesPerSector; - DiskEntry->CylinderSize = - (ULONGLONG)DiskGeometry.TracksPerCylinder * - DiskEntry->TrackSize; - DiskEntry->DiskSize = - DiskGeometry.Cylinders.QuadPart * - DiskEntry->CylinderSize; + DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart * + (ULONGLONG)DiskGeometry.TracksPerCylinder * + (ULONGLONG)DiskGeometry.SectorsPerTrack; + + DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack; + + DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount); + DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment); DiskEntry->DiskNumber = DiskNumber; DiskEntry->Port = ScsiAddress.PortNumber; @@ -922,10 +1019,10 @@ AddDiskToList( */ LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + ((56 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); - LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, - 0, - LayoutBufferSize); - if (LayoutBuffer == NULL) + DiskEntry->LayoutBuffer = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + LayoutBufferSize); + if (DiskEntry->LayoutBuffer == NULL) { return; } @@ -938,25 +1035,49 @@ AddDiskToList( IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0, - LayoutBuffer, + DiskEntry->LayoutBuffer, LayoutBufferSize); if (NT_SUCCESS(Status)) { - if (LayoutBuffer->PartitionCount == 0) +#ifdef DUMP_PARTITION_TABLE + DumpPartitionTable(DiskEntry); +#endif + + if (DiskEntry->LayoutBuffer->PartitionCount == 0) { DiskEntry->NewDisk = TRUE; + DiskEntry->LayoutBuffer->PartitionCount = 4; + + for (i = 0; i < 4; i++) + DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE; } + else + { + for (i = 0; i < 4; i++) + { + if (DiskEntry->LayoutBuffer->PartitionEntry[i].PartitionType != 0) + { + AddPrimaryPartitionToDisk(DiskNumber, + DiskEntry, + i); + } + } - AddPartitionToList(DiskNumber, - DiskEntry, - LayoutBuffer); - - ScanForUnpartitionedDiskSpace(DiskEntry); + for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i++) + { + if (DiskEntry->LayoutBuffer->PartitionEntry[i].PartitionType != 0) + { +#if 0 + AddExtendedPartitionToDisk(DiskNumber, + DiskEntry, + i); +#endif + } + } + } } - RtlFreeHeap(ProcessHeap, - 0, - LayoutBuffer); + ScanForUnpartitionedDiskSpace(DiskEntry); } @@ -997,7 +1118,6 @@ CreatePartitionList( List->CurrentDisk = NULL; List->CurrentPartition = NULL; - List->CurrentPartitionNumber = 0; InitializeListHead(&List->DiskListHead); InitializeListHead(&List->BiosDiskListHead); @@ -1044,7 +1164,9 @@ CreatePartitionList( } } - AssignDriverLetters(List); + UpdateDiskSignatures(List); + + AssignDriveLetters(List); List->TopDisk = 0; List->TopPartition = 0; @@ -1054,7 +1176,6 @@ CreatePartitionList( { List->CurrentDisk = NULL; List->CurrentPartition = NULL; - List->CurrentPartitionNumber = 0; } else { @@ -1062,17 +1183,15 @@ CreatePartitionList( DISKENTRY, ListEntry); - if (IsListEmpty(&List->CurrentDisk->PartListHead)) + if (IsListEmpty(&List->CurrentDisk->PrimaryPartListHead)) { List->CurrentPartition = 0; - List->CurrentPartitionNumber = 0; } else { - List->CurrentPartition = CONTAINING_RECORD(List->CurrentDisk->PartListHead.Flink, + List->CurrentPartition = CONTAINING_RECORD(List->CurrentDisk->PrimaryPartListHead.Flink, PARTENTRY, ListEntry); - List->CurrentPartitionNumber = 0; } } @@ -1098,17 +1217,29 @@ DestroyPartitionList( /* Release driver name */ RtlFreeUnicodeString(&DiskEntry->DriverName); - /* Release partition array */ - while (!IsListEmpty(&DiskEntry->PartListHead)) + /* Release primary partition list */ + while (!IsListEmpty(&DiskEntry->PrimaryPartListHead)) { - Entry = RemoveHeadList(&DiskEntry->PartListHead); + Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead); PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); - RtlFreeHeap(ProcessHeap, - 0, - PartEntry); + RtlFreeHeap(ProcessHeap, 0, PartEntry); } + /* Release extended partition list */ + while (!IsListEmpty(&DiskEntry->ExtendedPartListHead)) + { + Entry = RemoveHeadList(&DiskEntry->ExtendedPartListHead); + PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); + + RtlFreeHeap(ProcessHeap, 0, PartEntry); + } + + /* Release layout buffer */ + if (DiskEntry->LayoutBuffer != NULL) + RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer); + + /* Release disk entry */ RtlFreeHeap(ProcessHeap, 0, DiskEntry); } @@ -1167,8 +1298,7 @@ VOID PrintPartitionData( PPARTLIST List, PDISKENTRY DiskEntry, - PPARTENTRY PartEntry, - ULONG PartNumber) + PPARTENTRY PartEntry) { CHAR LineBuffer[128]; COORD coPos; @@ -1186,24 +1316,25 @@ PrintPartitionData( coPos.X = List->Left + 1; coPos.Y = List->Top + 1 + List->Line; - if (PartEntry->Unpartitioned == TRUE) + if (PartEntry->IsPartitioned == FALSE) { + PartSize.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (PartEntry->UnpartitionledLength >= 0x280000000ULL) /* 10 GB */ + if (PartSize.QuadPart >= 10737418240) /* 10 GB */ { - PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 29)) >> 30; + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1073741824); Unit = MUIGetString(STRING_GB); } else #endif - if (PartEntry->UnpartitionedLength >= 0xA00000ULL) /* 10 MB */ + if (PartSize.QuadPart >= 10485760) /* 10 MB */ { - PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1048576); Unit = MUIGetString(STRING_MB); } else { - PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 9)) >> 10; + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1024); Unit = MUIGetString(STRING_KB); } @@ -1220,46 +1351,47 @@ PrintPartitionData( { PartType = MUIGetString(STRING_UNFORMATTED); } - else if (PartEntry->Unpartitioned == FALSE) + else if (PartEntry->IsPartitioned == TRUE) { - if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_12) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_16) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_HUGE) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_XINT13)) + if ((PartEntry->PartitionType == PARTITION_FAT_12) || + (PartEntry->PartitionType == PARTITION_FAT_16) || + (PartEntry->PartitionType == PARTITION_HUGE) || + (PartEntry->PartitionType == PARTITION_XINT13)) { PartType = "FAT"; } - else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13)) + else if ((PartEntry->PartitionType == PARTITION_FAT32) || + (PartEntry->PartitionType == PARTITION_FAT32_XINT13)) { PartType = "FAT32"; } - else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2) + else if (PartEntry->PartitionType == PARTITION_EXT2) { PartType = "EXT2"; } - else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS) + else if (PartEntry->PartitionType == PARTITION_IFS) { PartType = "NTFS"; /* FIXME: Not quite correct! */ } } + PartSize.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */ + if (PartSize.QuadPart >= 10737418240) /* 10 GB */ { - PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30; + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1073741824); Unit = MUIGetString(STRING_GB); } else #endif - if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */ + if (PartSize.QuadPart >= 10485760) /* 10 MB */ { - PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20; + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1048576); Unit = MUIGetString(STRING_MB); } else { - PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 9)) >> 10; + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1024); Unit = MUIGetString(STRING_KB); } @@ -1267,9 +1399,9 @@ PrintPartitionData( { sprintf(LineBuffer, MUIGetString(STRING_HDDINFOUNK5), - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', - PartEntry->PartInfo[PartNumber].PartitionType, + (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : ':', + PartEntry->PartitionType, PartSize.u.LowPart, Unit); } @@ -1277,8 +1409,8 @@ PrintPartitionData( { sprintf(LineBuffer, "%c%c %-24s %6lu %s", - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', + (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : ':', PartType, PartSize.u.LowPart, Unit); @@ -1286,8 +1418,7 @@ PrintPartitionData( } Attribute = (List->CurrentDisk == DiskEntry && - List->CurrentPartition == PartEntry && - List->CurrentPartitionNumber == PartNumber) ? + List->CurrentPartition == PartEntry) ? FOREGROUND_BLUE | BACKGROUND_WHITE : FOREGROUND_WHITE | BACKGROUND_BLUE; @@ -1339,7 +1470,6 @@ PrintDiskData( USHORT Height; ULARGE_INTEGER DiskSize; PCHAR Unit; - ULONG i; Width = List->Right - List->Left - 1; Height = List->Bottom - List->Top - 2; @@ -1347,16 +1477,15 @@ PrintDiskData( coPos.X = List->Left + 1; coPos.Y = List->Top + 1 + List->Line; -#if 0 - if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */ + DiskSize.QuadPart = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; + if (DiskSize.QuadPart >= 10737418240) /* 10 GB */ { - DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 29)) >> 30; + DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1073741824); Unit = MUIGetString(STRING_GB); } else -#endif { - DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 19)) >> 20; + DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1048576); if (DiskSize.QuadPart == 0) DiskSize.QuadPart = 1; Unit = MUIGetString(STRING_MB); @@ -1417,32 +1546,14 @@ PrintDiskData( PrintEmptyLine(List); /* Print partition lines*/ - Entry = DiskEntry->PartListHead.Flink; - while (Entry != &DiskEntry->PartListHead) + Entry = DiskEntry->PrimaryPartListHead.Flink; + while (Entry != &DiskEntry->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); - /* Print disk entry */ - for (i = 0; i < 4; i++) - { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED || - PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL) - { - PrintPartitionData(List, - DiskEntry, - PartEntry, - i); - } - } - - /* Print unpartitioned entry */ - if (PartEntry->Unpartitioned) - { - PrintPartitionData(List, - DiskEntry, - PartEntry, - 0); - } + PrintPartitionData(List, + DiskEntry, + PartEntry); Entry = Entry->Flink; } @@ -1484,8 +1595,8 @@ DrawPartitionList( CurrentPartLine += 2; } - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) + Entry2 = DiskEntry->PrimaryPartListHead.Flink; + while (Entry2 != &DiskEntry->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); if (PartEntry == List->CurrentPartition) @@ -1685,7 +1796,6 @@ SelectPartition( PPARTENTRY PartEntry; PLIST_ENTRY Entry1; PLIST_ENTRY Entry2; - UCHAR i; /* Check for empty disks */ if (IsListEmpty(&List->DiskListHead)) @@ -1699,21 +1809,17 @@ SelectPartition( if (DiskEntry->DiskNumber == DiskNumber) { - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) + Entry2 = DiskEntry->PrimaryPartListHead.Flink; + while (Entry2 != &DiskEntry->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); - for (i = 0; i < 4; i++) + if (PartEntry->PartitionNumber == PartitionNumber) { - if (PartEntry->PartInfo[i].PartitionNumber == PartitionNumber) - { - List->CurrentDisk = DiskEntry; - List->CurrentPartition = PartEntry; - List->CurrentPartitionNumber = i; - DrawPartitionList(List); - return TRUE; - } + List->CurrentDisk = DiskEntry; + List->CurrentPartition = PartEntry; + DrawPartitionList(List); + return TRUE; } Entry2 = Entry2->Flink; @@ -1733,11 +1839,10 @@ VOID ScrollDownPartitionList( PPARTLIST List) { - PDISKENTRY DiskEntry; +// PDISKENTRY DiskEntry; PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; +// PLIST_ENTRY Entry1; PLIST_ENTRY Entry2; - UCHAR i; /* Check for empty disks */ if (IsListEmpty(&List->DiskListHead)) @@ -1746,46 +1851,18 @@ ScrollDownPartitionList( /* Check for next usable entry on current disk */ if (List->CurrentPartition != NULL) { - Entry2 = &List->CurrentPartition->ListEntry; - PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); - - /* Check if we can move inside primary partitions */ - for (i = List->CurrentPartitionNumber + 1; i < 4; i++) - { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) - break; - } - - if (i == 4) - { - /* We're out of partitions in the current partition table. - Try to move to the next one if possible. */ - Entry2 = Entry2->Flink; - } - else - { - /* Just advance to the next partition */ - List->CurrentPartitionNumber = i; - DrawPartitionList(List); - return; - } - - while (Entry2 != &List->CurrentDisk->PartListHead) + Entry2 = List->CurrentPartition->ListEntry.Flink; + if (Entry2 != &List->CurrentDisk->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); -// if (PartEntry->HidePartEntry == FALSE) - { - List->CurrentPartition = PartEntry; - List->CurrentPartitionNumber = 0; - DrawPartitionList(List); - return; - } - - Entry2 = Entry2->Flink; + List->CurrentPartition = PartEntry; + DrawPartitionList(List); + return; } } +#if 0 /* Check for first usable entry on next disk */ if (List->CurrentDisk != NULL) { @@ -1795,25 +1872,20 @@ ScrollDownPartitionList( DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) + if (Entry2 != &DiskEntry->PartListHead) { PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); -// if (PartEntry->HidePartEntry == FALSE) - { - List->CurrentDisk = DiskEntry; - List->CurrentPartition = PartEntry; - List->CurrentPartitionNumber = 0; - DrawPartitionList(List); - return; - } - - Entry2 = Entry2->Flink; + List->CurrentDisk = DiskEntry; + List->CurrentPartition = PartEntry; + DrawPartitionList(List); + return; } Entry1 = Entry1->Flink; } } +#endif } @@ -1821,11 +1893,10 @@ VOID ScrollUpPartitionList( PPARTLIST List) { - PDISKENTRY DiskEntry; +// PDISKENTRY DiskEntry; PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; +// PLIST_ENTRY Entry1; PLIST_ENTRY Entry2; - UCHAR i; /* Check for empty disks */ if (IsListEmpty(&List->DiskListHead)) @@ -1834,56 +1905,20 @@ ScrollUpPartitionList( /* check for previous usable entry on current disk */ if (List->CurrentPartition != NULL) { - Entry2 = &List->CurrentPartition->ListEntry; - PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); - - /* Check if we can move inside primary partitions */ - if (List->CurrentPartitionNumber > 0) - { - /* Find a previous partition */ - for (i = List->CurrentPartitionNumber - 1; i > 0; i--) - { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) - break; - } - - /* Move to it and return */ - List->CurrentPartitionNumber = i; - DrawPartitionList(List); - return; - } - - /* Move to the previous entry */ - Entry2 = Entry2->Blink; - - while (Entry2 != &List->CurrentDisk->PartListHead) + Entry2 = List->CurrentPartition->ListEntry.Blink; + if (Entry2 != &List->CurrentDisk->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); -// if (PartEntry->HidePartEntry == FALSE) - { - List->CurrentPartition = PartEntry; + List->CurrentPartition = PartEntry; - /* Find last existing partition in the table */ - for (i = 3; i > 0; i--) - { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) - break; - } - - /* Move to it */ - List->CurrentPartitionNumber = i; - - /* Draw partition list and return */ - DrawPartitionList(List); - return; - } - - Entry2 = Entry2->Blink; + /* Draw partition list and return */ + DrawPartitionList(List); + return; } } - +#if 0 /* check for last usable entry on previous disk */ if (List->CurrentDisk != NULL) { @@ -1892,93 +1927,128 @@ ScrollUpPartitionList( { DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); - Entry2 = DiskEntry->PartListHead.Blink; - while (Entry2 != &DiskEntry->PartListHead) + Entry2 = DiskEntry->PrimaryPartListHead.Blink; + if (Entry2 != &DiskEntry->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); -// if (PartEntry->HidePartEntry == FALSE) - { - List->CurrentDisk = DiskEntry; - List->CurrentPartition = PartEntry; + List->CurrentDisk = DiskEntry; + List->CurrentPartition = PartEntry; - /* Find last existing partition in the table */ - for (i = 3; i > 0; i--) - { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) - break; - } - - /* Move to it */ - List->CurrentPartitionNumber = i; - - /* Draw partition list and return */ - DrawPartitionList(List); - return; - } - - Entry2 = Entry2->Blink; + /* Draw partition list and return */ + DrawPartitionList(List); + return; } Entry1 = Entry1->Blink; } } +#endif } static -PPARTENTRY -GetPrevPartitionedEntry( - PDISKENTRY DiskEntry, - PPARTENTRY CurrentEntry) +BOOLEAN +IsEmptyLayoutEntry( + PPARTITION_INFORMATION PartitionInfo) { - PPARTENTRY PrevEntry; - PLIST_ENTRY Entry; + if (PartitionInfo->StartingOffset.QuadPart == 0 && + PartitionInfo->PartitionLength.QuadPart == 0) +// PartitionInfo->PartitionType == 0) + return TRUE; - if (CurrentEntry->ListEntry.Blink == &DiskEntry->PartListHead) - return NULL; - - Entry = CurrentEntry->ListEntry.Blink; - while (Entry != &DiskEntry->PartListHead) - { - PrevEntry = CONTAINING_RECORD(Entry, - PARTENTRY, - ListEntry); - if (PrevEntry->Unpartitioned == FALSE) - return PrevEntry; - - Entry = Entry->Blink; - } - - return NULL; + return FALSE; } static -PPARTENTRY -GetNextPartitionedEntry( - PDISKENTRY DiskEntry, - PPARTENTRY CurrentEntry) +BOOLEAN +IsSamePrimaryLayoutEntry( + IN PPARTITION_INFORMATION PartitionInfo, + IN PDISKENTRY DiskEntry, + IN PPARTENTRY PartEntry) { - PPARTENTRY NextEntry; - PLIST_ENTRY Entry; + if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector && + PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) +// PartitionInfo->PartitionNumber = PartEntry->PartitionNumber && +// PartitionInfo->PartitionType == PartEntry->PartitionType + return TRUE; - if (CurrentEntry->ListEntry.Flink == &DiskEntry->PartListHead) - return NULL; + return FALSE; +} - Entry = CurrentEntry->ListEntry.Flink; - while (Entry != &DiskEntry->PartListHead) + +static +VOID +UpdateDiskLayout( + IN PDISKENTRY DiskEntry) +{ + PPARTITION_INFORMATION PartitionInfo; + PLIST_ENTRY ListEntry; + PPARTENTRY PartEntry; + ULONG Index = 0; + ULONG PartitionNumber = 1; + +DPRINT1("UpdateDiskLayout()\n"); + + ListEntry = DiskEntry->PrimaryPartListHead.Flink; + while (ListEntry != &DiskEntry->PrimaryPartListHead) { - NextEntry = CONTAINING_RECORD(Entry, - PARTENTRY, - ListEntry); - if (NextEntry->Unpartitioned == FALSE) - return NextEntry; + PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); - Entry = Entry->Flink; + if (PartEntry->IsPartitioned == TRUE) + { + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; + + if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry)) + { +DPRINT1("Updating partition entry %lu\n", Index); + PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; + PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; + PartitionInfo->HiddenSectors = 0; + PartitionInfo->PartitionNumber = (!IsContainerPartition(PartEntry->PartitionType)) ? PartitionNumber : 0; + PartitionInfo->PartitionType = PartEntry->PartitionType; + PartitionInfo->BootIndicator = PartEntry->BootIndicator; + PartitionInfo->RecognizedPartition = FALSE; + PartitionInfo->RewritePartition = TRUE; + + PartEntry->PartitionNumber = PartitionNumber; + PartEntry->PartitionIndex = Index; + + PartitionNumber++; + } + else if (!IsEmptyLayoutEntry(PartitionInfo)) + { + PartitionNumber++; + } + + Index++; + } + + ListEntry = ListEntry->Flink; } - return NULL; + for (;Index < 4; Index++) + { + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; + + if (!IsEmptyLayoutEntry(PartitionInfo)) + { +DPRINT1("Wiping partition entry %lu\n", Index); + PartitionInfo->StartingOffset.QuadPart = 0; + PartitionInfo->PartitionLength.QuadPart = 0; + PartitionInfo->HiddenSectors = 0; + PartitionInfo->PartitionNumber = 0; + PartitionInfo->PartitionType = 0; + PartitionInfo->BootIndicator = FALSE; + PartitionInfo->RecognizedPartition = FALSE; + PartitionInfo->RewritePartition = TRUE; + } + } + +#ifdef DUMP_PARTITION_TABLE + DumpPartitionTable(DiskEntry); +#endif } @@ -1990,12 +2060,12 @@ GetPrevUnpartitionedEntry( { PPARTENTRY PrevPartEntry; - if (PartEntry->ListEntry.Blink != &DiskEntry->PartListHead) + if (PartEntry->ListEntry.Blink != &DiskEntry->PrimaryPartListHead) { PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink, PARTENTRY, ListEntry); - if (PrevPartEntry->Unpartitioned == TRUE) + if (PrevPartEntry->IsPartitioned == FALSE) return PrevPartEntry; } @@ -2011,12 +2081,12 @@ GetNextUnpartitionedEntry( { PPARTENTRY NextPartEntry; - if (PartEntry->ListEntry.Flink != &DiskEntry->PartListHead) + if (PartEntry->ListEntry.Flink != &DiskEntry->PrimaryPartListHead) { NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink, PARTENTRY, ListEntry); - if (NextPartEntry->Unpartitioned == TRUE) + if (NextPartEntry->IsPartitioned == FALSE) return NextPartEntry; } @@ -2027,19 +2097,19 @@ GetNextUnpartitionedEntry( VOID CreateNewPartition( PPARTLIST List, - ULONGLONG PartitionSize, + ULONGLONG SectorCount, BOOLEAN AutoCreate) { PDISKENTRY DiskEntry; PPARTENTRY PartEntry; - PPARTENTRY PrevPartEntry; - PPARTENTRY NextPartEntry; PPARTENTRY NewPartEntry; + DPRINT1("CreateNewPartition(%I64u)\n", SectorCount); + if (List == NULL || List->CurrentDisk == NULL || List->CurrentPartition == NULL || - List->CurrentPartition->Unpartitioned == FALSE) + List->CurrentPartition->IsPartitioned == TRUE) { return; } @@ -2047,227 +2117,66 @@ CreateNewPartition( DiskEntry = List->CurrentDisk; PartEntry = List->CurrentPartition; +DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); + if (AutoCreate == TRUE || - PartitionSize == PartEntry->UnpartitionedLength) + Align(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart) { +DPRINT1("Convert existing partition entry\n"); /* Convert current entry to 'new (unformatted)' */ + PartEntry->IsPartitioned = TRUE; + PartEntry->PartitionType = PARTITION_ENTRY_UNUSED; PartEntry->FormatState = Unformatted; - PartEntry->PartInfo[0].StartingOffset.QuadPart = - PartEntry->UnpartitionedOffset + DiskEntry->TrackSize; - PartEntry->PartInfo[0].HiddenSectors = - (ULONG)(PartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - PartEntry->PartInfo[0].PartitionLength.QuadPart = - PartEntry->UnpartitionedLength - DiskEntry->TrackSize; - PartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED; - PartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */ - PartEntry->PartInfo[0].RewritePartition = TRUE; - PartEntry->PartInfo[1].RewritePartition = TRUE; - PartEntry->PartInfo[2].RewritePartition = TRUE; - PartEntry->PartInfo[3].RewritePartition = TRUE; - - /* Get previous and next partition entries */ - PrevPartEntry = GetPrevPartitionedEntry(DiskEntry, - PartEntry); - NextPartEntry = GetNextPartitionedEntry(DiskEntry, - PartEntry); - - if (PrevPartEntry != NULL && NextPartEntry != NULL) - { - /* Current entry is in the middle of the list */ - - /* Copy previous container partition data to current entry */ - RtlCopyMemory(&PartEntry->PartInfo[1], - &PrevPartEntry->PartInfo[1], - sizeof(PARTITION_INFORMATION)); - PartEntry->PartInfo[1].RewritePartition = TRUE; - - /* Update previous container partition data */ - - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = - PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PrevPartEntry->PartInfo[1].HiddenSectors = - (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - - if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) - { - /* Special case - previous partition is first partition */ - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; - } - else - { - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - } - - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; - } - else if (PrevPartEntry == NULL && NextPartEntry != NULL) - { - /* Current entry is the first entry */ - return; - } - else if (PrevPartEntry != NULL && NextPartEntry == NULL) - { - /* Current entry is the last entry */ - - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = - PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PrevPartEntry->PartInfo[1].HiddenSectors = - (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - - if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) - { - /* Special case - previous partition is first partition */ - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; - } - else - { - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - } - - if ((PartEntry->PartInfo[1].StartingOffset.QuadPart + - PartEntry->PartInfo[1].PartitionLength.QuadPart) < - (1024LL * 255LL * 63LL * 512LL)) - { - PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED; - } - else - { - PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED; - } - - PrevPartEntry->PartInfo[1].BootIndicator = FALSE; - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; - } - PartEntry->AutoCreate = AutoCreate; PartEntry->New = TRUE; - PartEntry->Unpartitioned = FALSE; - PartEntry->UnpartitionedOffset = 0ULL; - PartEntry->UnpartitionedLength = 0ULL; + PartEntry->BootIndicator = FALSE; /* FIXME */ + +DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart); +DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1); +DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart); } else { - /* Insert an initialize a new partition entry */ - NewPartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(PARTENTRY)); +DPRINT1("Add new partition entry\n"); + + /* Insert and initialize a new partition entry */ + NewPartEntry = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(PARTENTRY)); if (NewPartEntry == NULL) return; - RtlZeroMemory(NewPartEntry, - sizeof(PARTENTRY)); - /* Insert the new entry into the list */ InsertTailList(&PartEntry->ListEntry, &NewPartEntry->ListEntry); + NewPartEntry->DiskEntry = DiskEntry; + + NewPartEntry->IsPartitioned = TRUE; + NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; + NewPartEntry->SectorCount.QuadPart = Align(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - + NewPartEntry->StartSector.QuadPart; + NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED; + +DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); +DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); +DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); + NewPartEntry->New = TRUE; - NewPartEntry->FormatState = Unformatted; - NewPartEntry->PartInfo[0].StartingOffset.QuadPart = - PartEntry->UnpartitionedOffset + DiskEntry->TrackSize; - NewPartEntry->PartInfo[0].HiddenSectors = - (ULONG)(NewPartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - NewPartEntry->PartInfo[0].PartitionLength.QuadPart = - PartitionSize - DiskEntry->TrackSize; - NewPartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED; - NewPartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */ - NewPartEntry->PartInfo[0].RewritePartition = TRUE; - NewPartEntry->PartInfo[1].RewritePartition = TRUE; - NewPartEntry->PartInfo[2].RewritePartition = TRUE; - NewPartEntry->PartInfo[3].RewritePartition = TRUE; + NewPartEntry->BootIndicator = FALSE; /* FIXME */ - /* Get previous and next partition entries */ - PrevPartEntry = GetPrevPartitionedEntry(DiskEntry, - NewPartEntry); - NextPartEntry = GetNextPartitionedEntry(DiskEntry, - NewPartEntry); - - if (PrevPartEntry != NULL && NextPartEntry != NULL) - { - /* Current entry is in the middle of the list */ - - /* Copy previous container partition data to current entry */ - RtlCopyMemory(&NewPartEntry->PartInfo[1], - &PrevPartEntry->PartInfo[1], - sizeof(PARTITION_INFORMATION)); - NewPartEntry->PartInfo[1].RewritePartition = TRUE; - - /* Update previous container partition data */ - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = - NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PrevPartEntry->PartInfo[1].HiddenSectors = - (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - - if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) - { - /* Special case - previous partition is first partition */ - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; - } - else - { - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - } - - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; - } - else if (PrevPartEntry == NULL && NextPartEntry != NULL) - { - /* Current entry is the first entry */ - return; - } - else if (PrevPartEntry != NULL && NextPartEntry == NULL) - { - /* Current entry is the last entry */ - - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = - NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PrevPartEntry->PartInfo[1].HiddenSectors = - (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - - if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) - { - /* Special case - previous partition is first partition */ - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; - } - else - { - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - } - - if ((PartEntry->PartInfo[1].StartingOffset.QuadPart + - PartEntry->PartInfo[1].PartitionLength.QuadPart) < - (1024LL * 255LL * 63LL * 512LL)) - { - PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED; - } - else - { - PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED; - } - - PrevPartEntry->PartInfo[1].BootIndicator = FALSE; - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; - } - - /* Update offset and size of the remaining unpartitioned disk space */ - PartEntry->UnpartitionedOffset += PartitionSize; - PartEntry->UnpartitionedLength -= PartitionSize; + PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; + PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart); } - DiskEntry->Modified = TRUE; + UpdateDiskLayout(DiskEntry); + + DiskEntry->Dirty = TRUE; UpdatePartitionNumbers(DiskEntry); - AssignDriverLetters(List); + AssignDriveLetters(List); } @@ -2283,7 +2192,7 @@ DeleteCurrentPartition( if (List == NULL || List->CurrentDisk == NULL || List->CurrentPartition == NULL || - List->CurrentPartition->Unpartitioned == TRUE) + List->CurrentPartition->IsPartitioned == FALSE) { return; } @@ -2291,48 +2200,6 @@ DeleteCurrentPartition( DiskEntry = List->CurrentDisk; PartEntry = List->CurrentPartition; - /* Adjust container partition entries */ - - /* Get previous and next partition entries */ - PrevPartEntry = GetPrevPartitionedEntry(DiskEntry, - PartEntry); - NextPartEntry = GetNextPartitionedEntry(DiskEntry, - PartEntry); - - if (PrevPartEntry != NULL && NextPartEntry != NULL) - { - /* Current entry is in the middle of the list */ - - /* - * The first extended partition can not be deleted - * as long as other extended partitions are present. - */ - if (PrevPartEntry->ListEntry.Blink == &DiskEntry->PartListHead) - return; - - /* Copy previous container partition data to current entry */ - RtlCopyMemory(&PrevPartEntry->PartInfo[1], - &PartEntry->PartInfo[1], - sizeof(PARTITION_INFORMATION)); - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; - } - else if (PrevPartEntry == NULL && NextPartEntry != NULL) - { - /* - * A primary partition can not be deleted as long as - * extended partitions are present. - */ - return; - } - else if (PrevPartEntry != NULL && NextPartEntry == NULL) - { - /* Current entry is the last entry */ - RtlZeroMemory(&PrevPartEntry->PartInfo[1], - sizeof(PARTITION_INFORMATION)); - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; - } - - /* Adjust unpartitioned disk space entries */ /* Get pointer to previous and next unpartitioned entries */ @@ -2347,21 +2214,15 @@ DeleteCurrentPartition( /* Merge previous, current and next unpartitioned entry */ /* Adjust the previous entries length */ - PrevPartEntry->UnpartitionedLength += - (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize + - NextPartEntry->UnpartitionedLength); + PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart); /* Remove the current entry */ RemoveEntryList(&PartEntry->ListEntry); - RtlFreeHeap(ProcessHeap, - 0, - PartEntry); + RtlFreeHeap(ProcessHeap, 0, PartEntry); /* Remove the next entry */ RemoveEntryList (&NextPartEntry->ListEntry); - RtlFreeHeap(ProcessHeap, - 0, - NextPartEntry); + RtlFreeHeap(ProcessHeap, 0, NextPartEntry); /* Update current partition */ List->CurrentPartition = PrevPartEntry; @@ -2371,14 +2232,11 @@ DeleteCurrentPartition( /* Merge current and previous unpartitioned entry */ /* Adjust the previous entries length */ - PrevPartEntry->UnpartitionedLength += - (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize); + PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart; /* Remove the current entry */ RemoveEntryList(&PartEntry->ListEntry); - RtlFreeHeap(ProcessHeap, - 0, - PartEntry); + RtlFreeHeap(ProcessHeap, 0, PartEntry); /* Update current partition */ List->CurrentPartition = PrevPartEntry; @@ -2388,16 +2246,12 @@ DeleteCurrentPartition( /* Merge current and next unpartitioned entry */ /* Adjust the next entries offset and length */ - NextPartEntry->UnpartitionedOffset = - PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - NextPartEntry->UnpartitionedLength += - (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize); + NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; + NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart; /* Remove the current entry */ RemoveEntryList(&PartEntry->ListEntry); - RtlFreeHeap(ProcessHeap, - 0, - PartEntry); + RtlFreeHeap(ProcessHeap, 0, PartEntry); /* Update current partition */ List->CurrentPartition = NextPartEntry; @@ -2405,23 +2259,18 @@ DeleteCurrentPartition( else { /* Nothing to merge but change current entry */ - PartEntry->New = FALSE; - PartEntry->Unpartitioned = TRUE; - PartEntry->UnpartitionedOffset = - PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PartEntry->UnpartitionedLength = - PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - - /* Wipe the partition table */ - RtlZeroMemory(&PartEntry->PartInfo, - sizeof(PartEntry->PartInfo)); + PartEntry->IsPartitioned = FALSE; + PartEntry->FormatState = Unformatted; + PartEntry->DriveLetter = 0; } - DiskEntry->Modified = TRUE; + UpdateDiskLayout(DiskEntry); + + DiskEntry->Dirty = TRUE; UpdatePartitionNumbers(DiskEntry); - AssignDriverLetters(List); + AssignDriveLetters(List); } @@ -2432,14 +2281,12 @@ CheckActiveBootPartition( PDISKENTRY DiskEntry; PPARTENTRY PartEntry; PLIST_ENTRY ListEntry; - UCHAR i; /* Check for empty disk list */ if (IsListEmpty (&List->DiskListHead)) { List->ActiveBootDisk = NULL; List->ActiveBootPartition = NULL; - List->ActiveBootPartitionNumber = 0; return; } @@ -2456,33 +2303,29 @@ CheckActiveBootPartition( DiskEntry = List->CurrentDisk; /* Check for empty partition list */ - if (IsListEmpty (&DiskEntry->PartListHead)) + if (IsListEmpty (&DiskEntry->PrimaryPartListHead)) { List->ActiveBootDisk = NULL; List->ActiveBootPartition = NULL; - List->ActiveBootPartitionNumber = 0; return; } - PartEntry = CONTAINING_RECORD(DiskEntry->PartListHead.Flink, + PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink, PARTENTRY, ListEntry); /* Set active boot partition */ if ((DiskEntry->NewDisk == TRUE) || - (PartEntry->PartInfo[0].BootIndicator == FALSE && - PartEntry->PartInfo[1].BootIndicator == FALSE && - PartEntry->PartInfo[2].BootIndicator == FALSE && - PartEntry->PartInfo[3].BootIndicator == FALSE)) + (PartEntry->BootIndicator == FALSE)) { - PartEntry->PartInfo[0].BootIndicator = TRUE; - PartEntry->PartInfo[0].RewritePartition = TRUE; - DiskEntry->Modified = TRUE; + PartEntry->BootIndicator = TRUE; + DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].BootIndicator = TRUE; + DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE; + DiskEntry->Dirty = TRUE; /* FIXME: Might be incorrect if partitions were created by Linux FDISK */ List->ActiveBootDisk = DiskEntry; List->ActiveBootPartition = PartEntry; - List->ActiveBootPartitionNumber = 0; return; } @@ -2490,34 +2333,27 @@ CheckActiveBootPartition( /* Disk is not new, scan all partitions to find a bootable one */ List->ActiveBootDisk = NULL; List->ActiveBootPartition = NULL; - List->ActiveBootPartitionNumber = 0; - ListEntry = DiskEntry->PartListHead.Flink; - while (ListEntry != &DiskEntry->PartListHead) + ListEntry = DiskEntry->PrimaryPartListHead.Flink; + while (ListEntry != &DiskEntry->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); - /* Check if it's partitioned */ - if (!PartEntry->Unpartitioned) + /* Check if it is partitioned */ + if (PartEntry->IsPartitioned) { - /* Go through all of its 4 partitions */ - for (i = 0; i < 4; i++) + if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED && + PartEntry->BootIndicator) { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED && - PartEntry->PartInfo[i].BootIndicator) - { - /* Yes, we found it */ - List->ActiveBootDisk = DiskEntry; - List->ActiveBootPartition = PartEntry; - List->ActiveBootPartitionNumber = i; + /* Yes, we found it */ + List->ActiveBootDisk = DiskEntry; + List->ActiveBootPartition = PartEntry; - DPRINT("Found bootable partition disk %d, drive letter %c\n", - DiskEntry->DiskNumber, PartEntry->DriveLetter[i]); - - break; - } + DPRINT("Found bootable partition disk %d, drive letter %c\n", + DiskEntry->DiskNumber, PartEntry->DriveLetter); + break; } } @@ -2531,6 +2367,7 @@ BOOLEAN CheckForLinuxFdiskPartitions( PPARTLIST List) { +#if 0 PDISKENTRY DiskEntry; PPARTENTRY PartEntry; PLIST_ENTRY Entry1; @@ -2576,217 +2413,100 @@ CheckForLinuxFdiskPartitions( Entry1 = Entry1->Flink; } +#endif return FALSE; } +static +NTSTATUS +WritePartitons( + IN PPARTLIST List, + IN PDISKENTRY DiskEntry) +{ + WCHAR DstPath[MAX_PATH]; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK Iosb; + UNICODE_STRING Name; + ULONG BufferSize; + HANDLE FileHandle = NULL; + NTSTATUS Status; + + DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber); + + swprintf(DstPath, + L"\\Device\\Harddisk%d\\Partition0", + DiskEntry->DiskNumber); + RtlInitUnicodeString(&Name, + DstPath); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &Iosb, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + return Status; + } + +#ifdef DUMP_PARTITION_TABLE + DumpPartitionTable(DiskEntry); +#endif + + BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + + ((DiskEntry->LayoutBuffer->PartitionCount - 1) * sizeof(PARTITION_INFORMATION)); + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_SET_DRIVE_LAYOUT, + DiskEntry->LayoutBuffer, + BufferSize, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status); + } + + if (FileHandle != NULL) + NtClose(FileHandle); + + return Status; +} + + BOOLEAN WritePartitionsToDisk( PPARTLIST List) { - PDRIVE_LAYOUT_INFORMATION DriveLayout; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK Iosb; - WCHAR DstPath[MAX_PATH]; - UNICODE_STRING Name; - HANDLE FileHandle; - PDISKENTRY DiskEntry1; - PDISKENTRY DiskEntry2; - PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; - PLIST_ENTRY Entry2; - ULONG PartitionCount; - ULONG DriveLayoutSize; - ULONG Index; - NTSTATUS Status; + PLIST_ENTRY Entry; + PDISKENTRY DiskEntry; if (List == NULL) - { return TRUE; - } - Entry1 = List->DiskListHead.Flink; - while (Entry1 != &List->DiskListHead) + Entry = List->DiskListHead.Flink; + while (Entry != &List->DiskListHead) { - DiskEntry1 = CONTAINING_RECORD(Entry1, - DISKENTRY, - ListEntry); + DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); - if (DiskEntry1->Modified == TRUE) + if (DiskEntry->Dirty == TRUE) { - /* Count partitioned entries */ - PartitionCount = 0; - - Entry2 = DiskEntry1->PartListHead.Flink; - while (Entry2 != &DiskEntry1->PartListHead) - { - PartEntry = CONTAINING_RECORD(Entry2, - PARTENTRY, - ListEntry); - if (PartEntry->Unpartitioned == FALSE) - { - PartitionCount += 4; - } - - Entry2 = Entry2->Flink; - } - - if (PartitionCount == 0) - { - DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + - ((4 - 1) * sizeof (PARTITION_INFORMATION)); - } - else - { - DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + - ((PartitionCount - 1) * sizeof (PARTITION_INFORMATION)); - } - - DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap(ProcessHeap, - 0, - DriveLayoutSize); - if (DriveLayout == NULL) - { - DPRINT1("RtlAllocateHeap() failed\n"); - return FALSE; - } - - RtlZeroMemory(DriveLayout, - DriveLayoutSize); - - if (PartitionCount == 0) - { - /* delete all partitions in the mbr */ - DriveLayout->PartitionCount = 4; - for (Index = 0; Index < 4; Index++) - { - DriveLayout->PartitionEntry[Index].RewritePartition = TRUE; - } - } - else - { - DriveLayout->PartitionCount = PartitionCount; - Index = 0; - - Entry2 = DiskEntry1->PartListHead.Flink; - while (Entry2 != &DiskEntry1->PartListHead) - { - PartEntry = CONTAINING_RECORD(Entry2, - PARTENTRY, - ListEntry); - if (PartEntry->Unpartitioned == FALSE) - { - RtlCopyMemory(&DriveLayout->PartitionEntry[Index], - &PartEntry->PartInfo[0], - 4 * sizeof (PARTITION_INFORMATION)); - Index += 4; - } - - Entry2 = Entry2->Flink; - } - } - - if (DiskEntry1->Signature == 0) - { - LARGE_INTEGER SystemTime; - TIME_FIELDS TimeFields; - PUCHAR Buffer; - Buffer = (PUCHAR)&DiskEntry1->Signature; - - while (1) - { - NtQuerySystemTime(&SystemTime); - RtlTimeToTimeFields(&SystemTime, &TimeFields); - - Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF); - Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF); - Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF); - Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF); - - if (DiskEntry1->Signature == 0) - { - continue; - } - - /* check if the signature already exist */ - /* FIXME: - * Check also signatures from disks, which are - * not visible (bootable) by the bios. - */ - Entry2 = List->DiskListHead.Flink; - while (Entry2 != &List->DiskListHead) - { - DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry); - if (DiskEntry1 != DiskEntry2 && - DiskEntry1->Signature == DiskEntry2->Signature) - { - break; - } - - Entry2 = Entry2->Flink; - } - - if (Entry2 == &List->DiskListHead) - { - break; - } - } - - /* set one partition entry to dirty, this will update the signature */ - DriveLayout->PartitionEntry[0].RewritePartition = TRUE; - } - - DriveLayout->Signature = DiskEntry1->Signature; - - swprintf(DstPath, - L"\\Device\\Harddisk%d\\Partition0", - DiskEntry1->DiskNumber); - RtlInitUnicodeString(&Name, - DstPath); - InitializeObjectAttributes(&ObjectAttributes, - &Name, - 0, - NULL, - NULL); - - Status = NtOpenFile(&FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &Iosb, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - return FALSE; - } - - Status = NtDeviceIoControlFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_DISK_SET_DRIVE_LAYOUT, - DriveLayout, - DriveLayoutSize, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtDeviceIoControlFile() failed (Status %lx)\n", Status); - NtClose(FileHandle); - return FALSE; - } - - RtlFreeHeap(ProcessHeap, - 0, - DriveLayout); - - NtClose(FileHandle); + WritePartitons(List, DiskEntry); } - Entry1 = Entry1->Flink; + Entry = Entry->Flink; } return TRUE; @@ -2800,7 +2520,7 @@ SetMountedDeviceValues( PLIST_ENTRY Entry1, Entry2; PDISKENTRY DiskEntry; PPARTENTRY PartEntry; - UCHAR i; + LARGE_INTEGER StartingOffset; if (List == NULL) { @@ -2814,22 +2534,20 @@ SetMountedDeviceValues( DISKENTRY, ListEntry); - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) + Entry2 = DiskEntry->PrimaryPartListHead.Flink; + while (Entry2 != &DiskEntry->PrimaryPartListHead) { PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); - if (!PartEntry->Unpartitioned) + if (PartEntry->IsPartitioned) { - for (i = 0; i < 4; i++) + if (PartEntry->DriveLetter) { - if (PartEntry->DriveLetter[i]) + StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; + if (!SetMountedDeviceValue(PartEntry->DriveLetter, + DiskEntry->LayoutBuffer->Signature, + StartingOffset)) { - if (!SetMountedDeviceValue(PartEntry->DriveLetter[i], - DiskEntry->Signature, - PartEntry->PartInfo[i].StartingOffset)) - { - return FALSE; - } + return FALSE; } } } diff --git a/reactos/base/setup/usetup/partlist.h b/reactos/base/setup/usetup/partlist.h index 81282f022fc..5cf1841602d 100644 --- a/reactos/base/setup/usetup/partlist.h +++ b/reactos/base/setup/usetup/partlist.h @@ -42,12 +42,23 @@ typedef struct _PARTENTRY { LIST_ENTRY ListEntry; - CHAR DriveLetter[4]; + struct _DISKENTRY *DiskEntry; + + ULARGE_INTEGER StartSector; + ULARGE_INTEGER SectorCount; + + BOOLEAN BootIndicator; + UCHAR PartitionType; + ULONG HiddenSectors; + ULONG PartitionNumber; + ULONG PartitionIndex; + + CHAR DriveLetter; CHAR VolumeLabel[17]; CHAR FileSystemName[9]; - /* Partition is unused disk space */ - BOOLEAN Unpartitioned; + /* Partition is partitioned disk space */ + BOOLEAN IsPartitioned; /* Partition is new. Table does not exist on disk yet */ BOOLEAN New; @@ -57,15 +68,6 @@ typedef struct _PARTENTRY FORMATSTATE FormatState; - /* - * Raw offset and length of the unpartitioned disk space. - * Includes the leading, not yet existing, partition table. - */ - ULONGLONG UnpartitionedOffset; - ULONGLONG UnpartitionedLength; - - PARTITION_INFORMATION PartInfo[4]; - } PARTENTRY, *PPARTENTRY; @@ -86,18 +88,17 @@ typedef struct _DISKENTRY LIST_ENTRY ListEntry; ULONGLONG Cylinders; - ULONGLONG TracksPerCylinder; - ULONGLONG SectorsPerTrack; - ULONGLONG BytesPerSector; + ULONG TracksPerCylinder; + ULONG SectorsPerTrack; + ULONG BytesPerSector; - ULONGLONG DiskSize; - ULONGLONG CylinderSize; - ULONGLONG TrackSize; + ULARGE_INTEGER SectorCount; + ULONG SectorAlignment; BOOLEAN BiosFound; ULONG BiosDiskNumber; - ULONG Signature; - ULONG Checksum; +// ULONG Signature; +// ULONG Checksum; ULONG DiskNumber; USHORT Port; @@ -105,14 +106,17 @@ typedef struct _DISKENTRY USHORT Id; /* Has the partition list been modified? */ - BOOLEAN Modified; + BOOLEAN Dirty; BOOLEAN NewDisk; BOOLEAN NoMbr; /* MBR is absent */ UNICODE_STRING DriverName; - LIST_ENTRY PartListHead; + PDRIVE_LAYOUT_INFORMATION LayoutBuffer; + + LIST_ENTRY PrimaryPartListHead; + LIST_ENTRY ExtendedPartListHead; } DISKENTRY, *PDISKENTRY; @@ -132,11 +136,9 @@ typedef struct _PARTLIST PDISKENTRY CurrentDisk; PPARTENTRY CurrentPartition; - UCHAR CurrentPartitionNumber; PDISKENTRY ActiveBootDisk; PPARTENTRY ActiveBootPartition; - UCHAR ActiveBootPartitionNumber; LIST_ENTRY DiskListHead; LIST_ENTRY BiosDiskListHead;