Index: reactos/base/setup/usetup/interface/usetup.c =================================================================== --- reactos/base/setup/usetup/interface/usetup.c (revision 67059) +++ reactos/base/setup/usetup/interface/usetup.c (working copy) @@ -24,8 +24,20 @@ * PROGRAMMER: Eric Kohl * Casper S. Hornstrup (chorns@users.sourceforge.net) * Hervé Poussineau (hpoussin@reactos.org) + * Gerhard Gruber (sparhawk@gmx.at) */ +/** + ChangeLog: + + 2015.04.15 sparhawk + Added support for installation on logical partitions. + + 2015.03.15 sparhawk + Changed the input field for creating a partition with user defined + size, to make it looke like an input field. +*/ + #include #include "bootsup.h" @@ -1456,7 +1468,7 @@ if (PartitionList == NULL) { PartitionList = CreatePartitionList(2, - 21, + 23, xScreen - 3, yScreen - 3); if (PartitionList == NULL) @@ -1535,7 +1547,9 @@ while (TRUE) { - /* Update status text */ + PPARTENTRY PartEntry; + + /* Update status text */ if (PartitionList->CurrentPartition == NULL) { CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION)); @@ -1672,6 +1686,9 @@ return DELETE_PARTITION_PAGE; } + + PartEntry = PartitionList->CurrentPartition; + DumpPartition("[Selected] ", PartEntry); } return SELECT_PARTITION_PAGE; @@ -1724,6 +1741,7 @@ CHAR ch; SHORT iLeft; SHORT iTop; + DWORD redraw; if (Quit != NULL) *Quit = FALSE; @@ -1757,15 +1775,43 @@ sprintf(Buffer, "%lu", MaxSize); Index = strlen(Buffer); - DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, - iLeft, - iTop, - Buffer); + coPos.X = iLeft; + coPos.Y = iTop; + redraw = TRUE; + while (TRUE) { - CONSOLE_ConInKey(&Ir); + if(redraw) + { + DWORD blen = strlen(Buffer); + COORD cursor; + FillConsoleOutputAttribute( + StdOutput, + BACKGROUND_WHITE, + blen, + coPos, + &Written); + + cursor.Y = coPos.Y; + cursor.X = coPos.X+PARTITION_SIZE_INPUT_FIELD_LENGTH-1; + FillConsoleOutputAttribute( + StdOutput, + FOREGROUND_WHITE, + 1, + cursor, + &Written); + + DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, + iLeft, + iTop, + Buffer); + } + redraw = FALSE; + +CONSOLE_ConInKey(&Ir); + if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir.Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { @@ -1792,11 +1838,7 @@ { Index--; Buffer[Index] = 0; - - DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, - iLeft, - iTop, - Buffer); + redraw = TRUE; } else if ((Ir.Event.KeyEvent.uChar.AsciiChar != 0x00) && (Index < PARTITION_SIZE_INPUT_FIELD_LENGTH)) @@ -1808,11 +1850,7 @@ Buffer[Index] = ch; Index++; Buffer[Index] = 0; - - DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, - iLeft, - iTop, - Buffer); + redraw = TRUE; } } } @@ -2247,11 +2285,9 @@ SectorCount = PartEntry->SectorCount.QuadPart; } - DPRINT("Partition size: %I64u bytes\n", PartSize); + DPRINT1("Partition size: %I64u bytes, SectorCount: %I64u\n", PartSize, SectorCount); + CreateLogicalPartition(PartitionList, SectorCount); - CreateLogicalPartition(PartitionList, - SectorCount); - return SELECT_PARTITION_PAGE; } } @@ -2530,7 +2566,6 @@ CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT)); - PartEntry->AutoCreate = FALSE; } else if (PartEntry->New == TRUE) @@ -2650,7 +2685,6 @@ return SELECT_FILE_SYSTEM_PAGE; } - static ULONG FormatPartitionPage(PINPUT_RECORD Ir) { @@ -2794,7 +2828,7 @@ if (WritePartitionsToDisk(PartitionList) == FALSE) { - DPRINT("WritePartitionsToDisk() failed\n"); + DPRINT1("WritePartitionsToDisk() failed\n"); MUIDisplayError(ERROR_WRITE_PTABLE, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } @@ -2807,7 +2841,7 @@ PartitionList->CurrentPartition->PartitionNumber); RtlCreateUnicodeString(&DestinationRootPath, PathBuffer); - DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath); + DPRINT1("Partition: %p DestinationRootPath: %wZ\n", PartitionList->CurrentPartition, &DestinationRootPath); if (FileSystemList->Selected->FormatFunc) { @@ -2821,7 +2855,6 @@ } PartEntry->New = FALSE; - } #ifndef NDEBUG @@ -2838,7 +2871,6 @@ return FORMAT_PARTITION_PAGE; } - static ULONG CheckFileSystemPage(PINPUT_RECORD Ir) { @@ -3290,7 +3322,7 @@ Status = SetupCreateDirectory(PathBuffer); if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) { - DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); + DPRINT1("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); MUIDisplayError(ERROR_CREATE_INSTALL_DIR, Ir, POPUP_WAIT_ENTER); return FALSE; } Index: reactos/base/setup/usetup/lang/de-DE.h =================================================================== --- reactos/base/setup/usetup/lang/de-DE.h (revision 67059) +++ reactos/base/setup/usetup/lang/de-DE.h (working copy) @@ -826,6 +826,12 @@ { 8, 19, + "\x07 L erstellt eine logische Partition.", + TEXT_STYLE_NORMAL + }, + { + 8, + 21, "\x07 D l”scht eine vorhandene Partition.", TEXT_STYLE_NORMAL }, Index: reactos/base/setup/usetup/lang/en-US.h =================================================================== --- reactos/base/setup/usetup/lang/en-US.h (revision 67059) +++ reactos/base/setup/usetup/lang/en-US.h (working copy) @@ -831,6 +831,12 @@ { 8, 19, + "\x07 Press L to create a logical partition.", + TEXT_STYLE_NORMAL + }, + { + 8, + 21, "\x07 Press D to delete an existing partition.", TEXT_STYLE_NORMAL }, Index: reactos/base/setup/usetup/partlist.c =================================================================== --- reactos/base/setup/usetup/partlist.c (revision 67059) +++ reactos/base/setup/usetup/partlist.c (working copy) @@ -22,8 +22,16 @@ * PURPOSE: Partition list functions * PROGRAMMER: Eric Kohl * Casper S. Hornstrup (chorns@users.sourceforge.net) + * Gerhard Gruber (sparhawk@gmx.at) */ +/** + ChangeLog: + + 2015.04.15 sparhawk + Added support for installation on logical partitions. +*/ + #include "usetup.h" #include @@ -31,49 +39,138 @@ #define NDEBUG #include -#define DUMP_PARTITION_TABLE - /* FUNCTIONS ****************************************************************/ -#ifdef DUMP_PARTITION_TABLE -static -VOID -DumpPartitionTable( - PDISKENTRY DiskEntry) +static VOID DumpPartitionTable(PDISKENTRY DiskEntry) { - PPARTITION_INFORMATION PartitionInfo; - ULONG i; + PPARTITION_INFORMATION PartitionInfo; + ULONG i; + TCHAR buffer[11]; - for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++) - { - PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i]; - DPRINT("\n%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'); - } + DPRINT1("DiskEntry: %p #: %lu dirty: %c partitions: %lu %I64u/%lu/%lu/%lu sec: %I64u align: %lu\n", + DiskEntry, + DiskEntry->DiskNumber, + DiskEntry->Dirty ? 'D' : '-', + DiskEntry->LayoutBuffer->PartitionCount, + DiskEntry->Cylinders, + DiskEntry->TracksPerCylinder, + DiskEntry->SectorsPerTrack, + DiskEntry->BytesPerSector, + DiskEntry->SectorCount, + DiskEntry->SectorAlignment + ); + DPRINT1(" # Addr StartOfs PartLength HiddenSect P# Typ Boot Rewr. Known Size\n"); + for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++) + { + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i]; + snprintf(buffer, sizeof(buffer)-1, "%02lu: ", i); + DumpPartitionInfo(buffer, PartitionInfo); + } } -#endif +VOID DumpPartition(TCHAR *pPrefix, PPARTENTRY pPartition) +{ + TCHAR *prefix = ""; + char c; -ULONGLONG -Align( - IN ULONGLONG Value, - IN ULONG Alignment) + if(pPrefix != NULL) + prefix = pPrefix; + + if(pPartition == NULL) + { + DPRINT1("%sPartition: NULL\n", prefix); + return; + } + + if(pPartition->IsPartitioned == FALSE) + c = 'U'; + else + { + if(pPartition == pPartition->DiskEntry->ExtendedPartition) + c = 'E'; + else + { + if(pPartition->LogicalPartition) + c = 'L'; + else + c = 'P'; + } + } + + DPRINT1("%sPartition: %p Flink: %p Blink: %p %2u/%2u %2u %c %c %c %c %12I64u %12I64u %7I64u MB\n", + prefix, + pPartition, + pPartition->ListEntry.Flink, + pPartition->ListEntry.Blink, + pPartition->PartitionNumber, + pPartition->PartitionIndex, + pPartition->PartitionType, + c, + pPartition->IsPartitioned ? 'Y1' : 'N', + pPartition->New ? 'N' : 'O', + pPartition->BootIndicator ? '*' : '-', + pPartition->StartSector.QuadPart, + pPartition->SectorCount.QuadPart, + (pPartition->SectorCount.QuadPart*pPartition->DiskEntry->BytesPerSector)/(1024*1024) + ); +} + +VOID DumpPartitionInfo(TCHAR *pPrefix, PPARTITION_INFORMATION pPartitionInfo) { - ULONGLONG Temp; + TCHAR *prefix = ""; + ULONGLONG PartSize; + TCHAR *Unit; - Temp = Value / Alignment; + if(pPrefix != NULL) + prefix = pPrefix; - return Temp * Alignment; + PartSize = pPartitionInfo->PartitionLength.QuadPart; +/* if (PartSize >= 10737418240) // 10 GB + { + PartSize = PartSize / 1073741824; + Unit = "GB"; + } + else*/ + if (PartSize >= 10485760) // 10 MB + { + PartSize = PartSize / 1048576; + Unit = "MB"; + } + else + { + PartSize = PartSize / 1024; + Unit = "KB"; + } + + DPRINT1("%s%p %13I64u %13I64u %10lu %2lu %2x %c %c %c %9I64u %s\n", + prefix, + pPartitionInfo, + pPartitionInfo->StartingOffset.QuadPart, + pPartitionInfo->PartitionLength.QuadPart, + pPartitionInfo->HiddenSectors, + pPartitionInfo->PartitionNumber, + pPartitionInfo->PartitionType, + pPartitionInfo->BootIndicator ? '*': '-', + pPartitionInfo->RecognizedPartition ? 'Y' : 'N', + pPartitionInfo->RewritePartition ? 'Y': 'N', + PartSize, + Unit + ); } +ULONGLONG Align(IN ULONGLONG Value, IN ULONG Alignment) +{ + ULONGLONG Temp; + Temp = Value / Alignment; + +// if((Temp * Alignment) < Value) +// Temp++; + + return Temp * Alignment; +} + + ULONGLONG RoundingDivide( IN ULONGLONG Dividend, @@ -92,6 +189,8 @@ WCHAR KeyName[32]; NTSTATUS Status; + DPRINT1("GetDriverName()\n"); + RtlInitUnicodeString(&DiskEntry->DriverName, NULL); @@ -129,6 +228,8 @@ PLIST_ENTRY Entry2; CHAR Letter; + DPRINT1("AssignDriveLetters()\n"); + Letter = 'C'; /* Assign drive letters to primary partitions */ @@ -214,44 +315,52 @@ UpdatePartitionNumbers( PDISKENTRY DiskEntry) { - PPARTENTRY PartEntry; - PLIST_ENTRY Entry; -// ULONG PartitionNumber = 1; - ULONG PartitionIndex = 0; + PPARTENTRY PartEntry; + PLIST_ENTRY Entry; + ULONG PartitionNumber = 1; + ULONG PartitionIndex = 0; - Entry = DiskEntry->PrimaryPartListHead.Flink; - while (Entry != &DiskEntry->PrimaryPartListHead) - { - PartEntry = CONTAINING_RECORD(Entry, - PARTENTRY, - ListEntry); + DPRINT1("UpdatePartitionNumbers()\n"); - if (PartEntry->IsPartitioned == FALSE) - { -// PartEntry->PartitionNumber = 0; - PartEntry->PartitionIndex = (ULONG)-1; - } - else - { - if (IsContainerPartition(PartEntry->PartitionType)) - { -// PartEntry->PartitionNumber = 0; - } - else if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED && - PartEntry->SectorCount.QuadPart == 0ULL) - { -// PartEntry->PartitionNumber = 0; - } - else - { -// PartEntry->PartitionNumber = PartitionNumber++; - } + Entry = DiskEntry->PrimaryPartListHead.Flink; + while (Entry != &DiskEntry->PrimaryPartListHead) + { + PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); - PartEntry->PartitionIndex = PartitionIndex++; - } + if (PartEntry->IsPartitioned == FALSE) + { + PartEntry->PartitionIndex = (ULONG)-1; + PartEntry->PartitionNumber = 0; + } + else + { + PartEntry->PartitionIndex = PartitionIndex++; + PartEntry->PartitionNumber = PartitionNumber++; + } - Entry = Entry->Flink; - } + Entry = Entry->Flink; + } + + Entry = DiskEntry->LogicalPartListHead.Flink; + PartitionIndex = 4; + PartitionNumber--; + while (Entry != &DiskEntry->LogicalPartListHead) + { + PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); + + if (PartEntry->IsPartitioned == FALSE) + { + PartEntry->PartitionIndex = (ULONG)-1; + PartEntry->PartitionNumber = 0; + } + else + { + PartEntry->PartitionIndex = PartitionIndex++; + PartEntry->PartitionNumber = PartitionNumber++; + } + + Entry = Entry->Flink; + } } @@ -268,6 +377,8 @@ PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; UNICODE_STRING NameU; + DPRINT1("DiskIdentifierQueryRoutine()\n"); + if (ValueType == REG_SZ && ValueLength == 20 * sizeof(WCHAR)) { @@ -300,6 +411,8 @@ PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; ULONG i; + DPRINT1("DiskConfigurationDataQueryRoutine()\n"); + if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) return STATUS_UNSUCCESSFUL; @@ -343,6 +456,8 @@ PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context; ULONG i; + DPRINT1("SystemConfigurationDataQueryRoutine()\n"); + if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || ValueLength < sizeof (CM_FULL_RESOURCE_DESCRIPTOR)) return STATUS_UNSUCCESSFUL; @@ -390,6 +505,8 @@ PCM_INT13_DRIVE_PARAMETER Int13Drives; PBIOSDISKENTRY BiosDiskEntry; + DPRINT1("EnumerateBiosDiskEntries()\n"); + memset(QueryTable, 0, sizeof(QueryTable)); QueryTable[1].Name = L"Configuration Data"; @@ -521,110 +638,100 @@ static VOID AddPartitionToDisk( - ULONG DiskNumber, - PDISKENTRY DiskEntry, - ULONG PartitionIndex, - BOOLEAN LogicalPartition) + ULONG DiskNumber, + PDISKENTRY DiskEntry, + ULONG PartitionIndex, + BOOLEAN LogicalPartition) { - PPARTITION_INFORMATION PartitionInfo; - PPARTENTRY PartEntry; + PPARTITION_INFORMATION PartitionInfo; + PPARTENTRY PartEntry; - PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex]; - if (PartitionInfo->PartitionType == 0 || - (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->PartitionType))) - return; + DPRINT1("AddPartitionToDisk()\n"); - PartEntry = RtlAllocateHeap(ProcessHeap, - HEAP_ZERO_MEMORY, - sizeof(PARTENTRY)); - if (PartEntry == NULL) - { - return; - } + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex]; + if (PartitionInfo->PartitionType == 0 || + (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->PartitionType))) + return; - PartEntry->DiskEntry = DiskEntry; + 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->DiskEntry = DiskEntry; - PartEntry->BootIndicator = PartitionInfo->BootIndicator; - PartEntry->PartitionType = PartitionInfo->PartitionType; - PartEntry->HiddenSectors = PartitionInfo->HiddenSectors; + PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart/DiskEntry->BytesPerSector; + PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart/DiskEntry->BytesPerSector; - PartEntry->LogicalPartition = LogicalPartition; - PartEntry->IsPartitioned = TRUE; - PartEntry->PartitionNumber = PartitionInfo->PartitionNumber; - PartEntry->PartitionIndex = PartitionIndex; + PartEntry->BootIndicator = PartitionInfo->BootIndicator; + PartEntry->PartitionType = PartitionInfo->PartitionType; + PartEntry->HiddenSectors = PartitionInfo->HiddenSectors; - if (IsContainerPartition(PartEntry->PartitionType)) - { - PartEntry->FormatState = Unformatted; + PartEntry->LogicalPartition = LogicalPartition; + PartEntry->IsPartitioned = TRUE; + PartEntry->PartitionNumber = PartitionInfo->PartitionNumber; + PartEntry->PartitionIndex = PartitionIndex; - if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL) - DiskEntry->ExtendedPartition = PartEntry; - } - 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 (IsContainerPartition(PartEntry->PartitionType)) + { + PartEntry->FormatState = Unformatted; + + if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL) + DiskEntry->ExtendedPartition = PartEntry; + } + 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; - } + if (CheckFatFormat()) + PartEntry->FormatState = Preformatted; + else + PartEntry->FormatState = Unformatted; #endif - PartEntry->FormatState = Preformatted; - } - else if (PartEntry->PartitionType == PARTITION_EXT2) - { + PartEntry->FormatState = Preformatted; + } + else if (PartEntry->PartitionType == PARTITION_EXT2) + { #if 0 - if (CheckExt2Format()) - { - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = Unformatted; - } + if (CheckExt2Format()) + PartEntry->FormatState = Preformatted; + else + PartEntry->FormatState = Unformatted; #endif - PartEntry->FormatState = Preformatted; - } - else if (PartEntry->PartitionType == PARTITION_IFS) - { + 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; - } + if (CheckNtfsFormat()) + PartEntry->FormatState = Preformatted; + else if (CheckHpfsFormat()) + PartEntry->FormatState = Preformatted; + else + PartEntry->FormatState = Unformatted; #endif - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = UnknownFormat; - } - - if (LogicalPartition) - InsertTailList(&DiskEntry->LogicalPartListHead, - &PartEntry->ListEntry); - else - InsertTailList(&DiskEntry->PrimaryPartListHead, - &PartEntry->ListEntry); + PartEntry->FormatState = Preformatted; + } + else + { + PartEntry->FormatState = UnknownFormat; + } + + if (LogicalPartition) + { + InsertTailList(&DiskEntry->LogicalPartListHead, + &PartEntry->ListEntry); + } + else + { + InsertTailList(&DiskEntry->PrimaryPartListHead, + &PartEntry->ListEntry); + } } @@ -631,42 +738,43 @@ static VOID ScanForUnpartitionedDiskSpace( - PDISKENTRY DiskEntry) + PDISKENTRY DiskEntry) { - ULONGLONG LastStartSector; - ULONGLONG LastSectorCount; - ULONGLONG LastUnusedSectorCount; - PPARTENTRY PartEntry; - PPARTENTRY NewPartEntry; - PLIST_ENTRY Entry; + ULONGLONG LastStartSector; + ULONGLONG LastSectorCount; + ULONGLONG LastUnusedSectorCount; + PPARTENTRY PartEntry; + PPARTENTRY NewPartEntry; + PLIST_ENTRY Entry; - DPRINT("ScanForUnpartitionedDiskSpace()\n"); + DPRINT("ScanForUnpartitionedDiskSpace()\n"); - if (IsListEmpty(&DiskEntry->PrimaryPartListHead)) - { - DPRINT1("No primary partition!\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; + /* 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->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->IsPartitioned = FALSE; + //NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorsPerTrack; + NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment; + NewPartEntry->SectorCount.QuadPart = Align(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - + DiskEntry->SectorAlignment; + 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); + InsertTailList(&DiskEntry->PrimaryPartListHead, &NewPartEntry->ListEntry); return; } @@ -890,6 +998,8 @@ PDISKENTRY DiskEntry2; PUCHAR Buffer; + DPRINT1("SetDiskSignature()\n"); + Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature; while (1) @@ -938,6 +1048,8 @@ PLIST_ENTRY Entry; PDISKENTRY DiskEntry; + DPRINT1("UpdateDiskSignatures()\n"); + /* Print partition lines*/ Entry = List->DiskListHead.Flink; while (Entry != &List->DiskListHead) @@ -979,6 +1091,8 @@ PBIOSDISKENTRY BiosDiskEntry; ULONG LayoutBufferSize; + DPRINT1("AddDiskToList()\n"); + Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, @@ -1069,9 +1183,9 @@ /* Check if this disk has a valid MBR */ if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0) - DiskEntry->NoMbr = TRUE; + DiskEntry->Mbr = FALSE; else - DiskEntry->NoMbr = FALSE; + DiskEntry->Mbr = TRUE; /* Free Mbr sector buffer */ RtlFreeHeap(ProcessHeap, @@ -1100,6 +1214,7 @@ } else { + // TODO: ? } } ListEntry = ListEntry->Flink; @@ -1132,10 +1247,16 @@ (ULONGLONG)DiskGeometry.TracksPerCylinder * (ULONGLONG)DiskGeometry.SectorsPerTrack; - DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack; + //DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack; + // If the disk is smaller than 4GB, an alignment of 63 is ok, otherwise + // the alignment should be bigger and 2048 is a suggested value. + if((DiskEntry->SectorCount.QuadPart * DiskGeometry.SectorsPerTrack) < 4294967296) // 4GB + DiskEntry->SectorAlignment = 63; + else + DiskEntry->SectorAlignment = 2048; - DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount); - DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment); + DPRINT("SectorCount: %I64u\n", DiskEntry->SectorCount); + DPRINT("SectorAlignment: %lu\n", DiskEntry->SectorAlignment); DiskEntry->DiskNumber = DiskNumber; DiskEntry->Port = ScsiAddress.PortNumber; @@ -1172,9 +1293,7 @@ LayoutBufferSize); if (NT_SUCCESS(Status)) { -#ifdef DUMP_PARTITION_TABLE DumpPartitionTable(DiskEntry); -#endif if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 && DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 && @@ -1198,13 +1317,13 @@ DPRINT1("No valid partiton table found! Use megabyte (%lu Sectors) alignment!\n", 1048756 / DiskEntry->BytesPerSector); } - + DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount); if (DiskEntry->LayoutBuffer->PartitionCount == 0) { DiskEntry->NewDisk = TRUE; DiskEntry->LayoutBuffer->PartitionCount = 4; - for (i = 0; i < 4; i++) + for (i = 0; i < 8; i++) DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE; } else @@ -1249,6 +1368,8 @@ UNICODE_STRING Name; HANDLE FileHandle; + DPRINT1("CreatePartitionList()\n"); + List = (PPARTLIST)RtlAllocateHeap(ProcessHeap, 0, sizeof (PARTLIST)); @@ -1358,6 +1479,8 @@ PPARTENTRY PartEntry; PLIST_ENTRY Entry; + DPRINT1("DestroyPartitionList()\n"); + /* Release disk and partition info */ while (!IsListEmpty(&List->DiskListHead)) { @@ -2218,98 +2341,298 @@ return FALSE; } - +/** + * Check if the entry in the partition info slot is the same as in the + * possibly new partition entry. + */ static BOOLEAN IsSamePrimaryLayoutEntry( - IN PPARTITION_INFORMATION PartitionInfo, - IN PDISKENTRY DiskEntry, - IN PPARTENTRY PartEntry) + IN PPARTITION_INFORMATION PartitionInfo, + IN PDISKENTRY DiskEntry, + IN PPARTENTRY PartEntry) { - 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 (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector && + PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) + return TRUE; - return FALSE; + return FALSE; } +static ULONG GetLogicalPartitionCount(PDISKENTRY DiskEntry) +{ + ULONG logical = 0; + PLIST_ENTRY ListEntry; + PLIST_ENTRY ListHead; + PPARTENTRY PartEntry; -static -VOID -UpdateDiskLayout( - IN PDISKENTRY DiskEntry) + ListEntry = DiskEntry->LogicalPartListHead.Flink; + ListHead = &DiskEntry->LogicalPartListHead; + while (ListEntry != ListHead) + { + PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); + if(PartEntry->IsPartitioned) + logical++; + ListEntry = ListEntry->Flink; + } + + return logical; +} + +/** + * In case of logical drives, we have to create additional partition entries + * in the table. Since we don't know how many logical partitions will be created + * we have to reallocate the drive info to accomodate new entries. + * + * The first four entries are always there and reserved for up to four primary + * and at most one extended partitions (allowing for three primaries in this case). + * For each logical partition added, it needs a separate set of four entries + * where the first slot takes the data of the logical partition layout. + * If another logical partition follows, then the second slot will take + * another partition entry marked as extended. If it is the last logical + * partition, then this slot stays empty. The other two slots are always + * unused. + */ +BOOL ReallocDriveLayout(PDISKENTRY DiskEntry) { - PPARTITION_INFORMATION PartitionInfo; - PLIST_ENTRY ListEntry; - PPARTENTRY PartEntry; - ULONG Index = 0; - ULONG PartitionNumber = 1; + ULONG primary = 0; + ULONG extended = 0; + ULONG logical = 0; + ULONG total = 0; + PLIST_ENTRY ListEntry; + PLIST_ENTRY ListHead; + PPARTENTRY PartEntry; + PDRIVE_LAYOUT_INFORMATION layout; + ULONG LayoutBufferSize; -DPRINT1("UpdateDiskLayout()\n"); + DPRINT1("ReallocDriveLayout()\n"); - ListEntry = DiskEntry->PrimaryPartListHead.Flink; - while (ListEntry != &DiskEntry->PrimaryPartListHead) - { - PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); + if(DiskEntry == NULL) + return FALSE; - if (PartEntry->IsPartitioned == TRUE) - { - PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; + ListEntry = DiskEntry->PrimaryPartListHead.Flink; + ListHead = &DiskEntry->PrimaryPartListHead; + while (ListEntry != ListHead) + { + PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); + if (PartEntry->IsPartitioned == TRUE) + { + if(IsContainerPartition(PartEntry->PartitionType)) + extended++; + else + primary++; + } - 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; + ListEntry = ListEntry->Flink; + } + logical = GetLogicalPartitionCount(DiskEntry); - PartEntry->PartitionNumber = PartitionNumber; - PartEntry->PartitionIndex = Index; + DPRINT1("Primary: %lu Extended: %lu Logical: %lu\n", primary, extended, logical); + if(primary > 4 || extended > 1 || (primary + extended) > 4) + { + DPRINT1("Invalid combination of partitions\n"); + return FALSE; + } - PartitionNumber++; - } - else if (!IsEmptyLayoutEntry(PartitionInfo)) - { - PartitionNumber++; - } + total = primary+extended; + if(total < 4) + total = 4; + total += logical*4; - Index++; - } + if(DiskEntry->LayoutBuffer) + { + DPRINT1("New #: %lu Current #: %lu\n", total, DiskEntry->LayoutBuffer->PartitionCount); - ListEntry = ListEntry->Flink; - } + // Nothing to do if the new count is the same as before. + if(total == DiskEntry->LayoutBuffer->PartitionCount) + return TRUE; + } - for (;Index < 4; Index++) - { - PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; + LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + + ((total - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); + layout = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + LayoutBufferSize); + if (layout == NULL) + { + DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize); + return FALSE; + } - 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; - } - } + if(DiskEntry->LayoutBuffer) + { + // Copy the existing entries to the new layout buffer. + if(DiskEntry->LayoutBuffer->PartitionCount < total) + LayoutBufferSize = DiskEntry->LayoutBuffer->PartitionCount; // partitions have been removed + else + LayoutBufferSize = total; // partitions have been added -#ifdef DUMP_PARTITION_TABLE - DumpPartitionTable(DiskEntry); -#endif + LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + + ((LayoutBufferSize - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); + RtlCopyMemory(layout, DiskEntry->LayoutBuffer, LayoutBufferSize); + RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer); + } + + DiskEntry->LayoutBuffer = layout; + DiskEntry->LayoutBuffer->PartitionCount = total; + + return TRUE; } +static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry) +{ + PLIST_ENTRY ListEntry; + PLIST_ENTRY ListHead; + ULONG Index; + PPARTITION_INFORMATION PartitionInfo; + PPARTITION_INFORMATION ExtendedInfo; + PPARTITION_INFORMATION LogicalPartitionInfo; + PPARTENTRY PartEntry; + LONGLONG BaseOfs; + LONGLONG ofs; + ULONG PartitionNumber = 1; + ULONG i; + ULONG logical; + DPRINT1("UpdateDiskLayout()\n"); + + // Make sure that we have enough entries in the array to handle all + // logical drives. + if(ReallocDriveLayout(DiskEntry) == FALSE) + { + DPRINT1("ReallocDriveLayout() failed.\n"); + return; + } + + ListEntry = DiskEntry->PrimaryPartListHead.Flink; + ListHead = &DiskEntry->PrimaryPartListHead; + Index = 0; + + while (ListEntry != ListHead) + { + PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); + + DumpPartition("[Layout]", PartEntry); + if (PartEntry->IsPartitioned == TRUE) + { + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; + + // If the layout of the partition hasn't changed, we can leave this + // entry as it is. + 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->PartitionType = PartEntry->PartitionType; + PartitionInfo->BootIndicator = PartEntry->BootIndicator; + PartitionInfo->RecognizedPartition = FALSE; + PartitionInfo->RewritePartition = TRUE; + PartitionInfo->PartitionNumber = PartitionNumber; + PartEntry->PartitionNumber = PartitionNumber; + PartEntry->PartitionIndex = Index; + } + + Index++; + PartitionNumber++; + + DumpPartitionInfo("[Layout]", PartitionInfo); + } + + ListEntry = ListEntry->Flink; + } + + Index = 4; + logical = GetLogicalPartitionCount(DiskEntry); + BaseOfs = DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart; + ofs = BaseOfs; + ExtendedInfo = NULL; + + // Now process the logical partitions. If there is no extended + // partition this can be skipped, because there can be no logical + // ones either (and if there were some it would be wrong anyway). + if(DiskEntry->ExtendedPartition) + { + PartitionNumber = DiskEntry->ExtendedPartition->PartitionNumber; + ListEntry = DiskEntry->LogicalPartListHead.Flink; + ListHead = &DiskEntry->LogicalPartListHead; + + while(ListEntry != ListHead) + { + PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); + DumpPartition("[Layout]", PartEntry); + if(PartEntry->IsPartitioned) + { + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; + LogicalPartitionInfo = PartitionInfo; + + PartitionInfo->StartingOffset.QuadPart = BaseOfs+ofs; + PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; + PartitionInfo->HiddenSectors = 0; + PartitionInfo->PartitionType = PartEntry->PartitionType; + PartitionInfo->BootIndicator = PartEntry->BootIndicator; + PartitionInfo->RecognizedPartition = FALSE; + PartitionInfo->RewritePartition = TRUE; + PartitionInfo->PartitionNumber = PartitionNumber; + PartEntry->PartitionNumber = PartitionNumber; + PartEntry->PartitionIndex = Index; + if(ExtendedInfo) + ExtendedInfo->PartitionLength.QuadPart = PartitionInfo->PartitionLength.QuadPart + BaseOfs; + + // Create the corresponding extended partition entry + // for the chain of logical partitions. + Index++; + + // If it is the last logical partition, we don't need + // a corresponding extended entry + if((Index+4) <= DiskEntry->LayoutBuffer->PartitionCount) + { + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; + ExtendedInfo = PartitionInfo; + PartitionInfo->PartitionNumber = PartitionNumber+logical; + PartitionInfo->PartitionType = PARTITION_EXTENDED; + PartitionInfo->StartingOffset.QuadPart = LogicalPartitionInfo->StartingOffset.QuadPart + LogicalPartitionInfo->PartitionLength.QuadPart; + ofs = PartitionInfo->StartingOffset.QuadPart; + + PartitionInfo->RecognizedPartition = FALSE; + PartitionInfo->RewritePartition = TRUE; + + PartitionNumber++; + } + else + ExtendedInfo = NULL; + + Index += 3; + } + ListEntry = ListEntry->Flink; + } + } + + for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++) + { + PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i]; + + if (IsEmptyLayoutEntry(PartitionInfo)) + { + DPRINT1("Wiping partition entry %lu\n", i); + + 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; + } + } + + DumpPartitionTable(DiskEntry); +} + + static PPARTENTRY GetPrevUnpartitionedEntry( @@ -2354,90 +2677,80 @@ VOID CreatePrimaryPartition( - PPARTLIST List, - ULONGLONG SectorCount, - BOOLEAN AutoCreate) + PPARTLIST List, + ULONGLONG SectorCount, + BOOLEAN AutoCreate) { - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PPARTENTRY NewPartEntry; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PPARTENTRY NewPartEntry; - DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount); + DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount); - if (List == NULL || - List->CurrentDisk == NULL || - List->CurrentPartition == NULL || - List->CurrentPartition->IsPartitioned == TRUE) - { - return; - } + if (List == NULL || + List->CurrentDisk == NULL || + List->CurrentPartition == NULL || + List->CurrentPartition->IsPartitioned == TRUE) + { + return; + } - DiskEntry = List->CurrentDisk; - PartEntry = List->CurrentPartition; + DiskEntry = List->CurrentDisk; + PartEntry = List->CurrentPartition; -DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); + DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); - if (AutoCreate == TRUE || - 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->AutoCreate = AutoCreate; - PartEntry->New = TRUE; - PartEntry->BootIndicator = FALSE; + if (AutoCreate == TRUE || + Align(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart) + { + DPRINT1("Convert existing partition entry\n"); + } + else + { + DPRINT1("Add new partition entry\n"); -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 - { -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; - /* Insert and initialize a new partition entry */ - NewPartEntry = RtlAllocateHeap(ProcessHeap, - HEAP_ZERO_MEMORY, - sizeof(PARTENTRY)); - if (NewPartEntry == NULL) - return; + /* Insert the new entry into the list */ + InsertTailList(&PartEntry->ListEntry, &NewPartEntry->ListEntry); - /* Insert the new entry into the list */ - InsertTailList(&PartEntry->ListEntry, - &NewPartEntry->ListEntry); + NewPartEntry->DiskEntry = DiskEntry; - NewPartEntry->DiskEntry = DiskEntry; + NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; + NewPartEntry->SectorCount.QuadPart = Align(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - + NewPartEntry->StartSector.QuadPart; - 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; + PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; + PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - 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); + PartEntry = NewPartEntry; + } - NewPartEntry->New = TRUE; - NewPartEntry->FormatState = Unformatted; - NewPartEntry->BootIndicator = FALSE; + PartEntry->IsPartitioned = TRUE; + PartEntry->FormatState = Unformatted; + PartEntry->BootIndicator = FALSE; + PartEntry->AutoCreate = AutoCreate; + PartEntry->PartitionType = PARTITION_ENTRY_UNUSED; + PartEntry->New = TRUE; - PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; - PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart); - } + 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); - UpdateDiskLayout(DiskEntry); + UpdateDiskLayout(DiskEntry); - DiskEntry->Dirty = TRUE; + DiskEntry->Dirty = TRUE; - UpdatePartitionNumbers(DiskEntry); + UpdatePartitionNumbers(DiskEntry); - AssignDriveLetters(List); + AssignDriveLetters(List); } - static VOID AddLogicalDiskSpace( @@ -2469,6 +2782,8 @@ InsertTailList(&DiskEntry->LogicalPartListHead, &NewPartEntry->ListEntry); + + DumpPartition("[NewLogicalDiskspace]", NewPartEntry); } @@ -2477,137 +2792,161 @@ PPARTLIST List, ULONGLONG SectorCount) { - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PPARTENTRY NewPartEntry; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PPARTENTRY NewPartEntry; - DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount); + DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount); - if (List == NULL || - List->CurrentDisk == NULL || - List->CurrentPartition == NULL || - List->CurrentPartition->IsPartitioned == TRUE) - { - return; - } + if (List == NULL || + List->CurrentDisk == NULL || + List->CurrentPartition == NULL || + List->CurrentPartition->IsPartitioned == TRUE) + { + return; + } - DiskEntry = List->CurrentDisk; - PartEntry = List->CurrentPartition; + DiskEntry = List->CurrentDisk; + PartEntry = List->CurrentPartition; -DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); + DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); - if (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->FormatState = Formatted; - PartEntry->AutoCreate = FALSE; - PartEntry->New = FALSE; - PartEntry->BootIndicator = FALSE; + if (Align(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart) + { + DPRINT1("Convert existing partition entry\n"); - if (PartEntry->StartSector.QuadPart < 1450560) - { - /* Partition starts below the 8.4GB boundary ==> CHS partition */ - PartEntry->PartitionType = PARTITION_EXTENDED; - } - else - { - /* Partition starts above the 8.4GB boundary ==> LBA partition */ - PartEntry->PartitionType = PARTITION_XINT13_EXTENDED; - } + /* Convert current entry to 'new (unformatted)' */ + DiskEntry->ExtendedPartition = PartEntry; + } + else + { + DPRINT1("Add new partition entry\n"); - DiskEntry->ExtendedPartition = PartEntry; + /* Insert and initialize a new partition entry */ + NewPartEntry = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(PARTENTRY)); -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 - { -DPRINT1("Add new partition entry\n"); + if (NewPartEntry == NULL) + return; - /* Insert and initialize a new partition entry */ - NewPartEntry = RtlAllocateHeap(ProcessHeap, - HEAP_ZERO_MEMORY, - sizeof(PARTENTRY)); - if (NewPartEntry == NULL) - return; + /* Insert the new entry into the list */ + InsertTailList(&PartEntry->ListEntry, + &NewPartEntry->ListEntry); - /* Insert the new entry into the list */ - InsertTailList(&PartEntry->ListEntry, - &NewPartEntry->ListEntry); + NewPartEntry->DiskEntry = DiskEntry; - NewPartEntry->DiskEntry = DiskEntry; + NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; + NewPartEntry->SectorCount.QuadPart = Align(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - + NewPartEntry->StartSector.QuadPart; - NewPartEntry->IsPartitioned = TRUE; - NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; - NewPartEntry->SectorCount.QuadPart = Align(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - - NewPartEntry->StartSector.QuadPart; + DiskEntry->ExtendedPartition = NewPartEntry; + PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; + PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart); - NewPartEntry->New = FALSE; - NewPartEntry->FormatState = Formatted; - NewPartEntry->BootIndicator = FALSE; + PartEntry = NewPartEntry; + } - if (NewPartEntry->StartSector.QuadPart < 1450560) - { - /* Partition starts below the 8.4GB boundary ==> CHS partition */ - NewPartEntry->PartitionType = PARTITION_EXTENDED; - } - else - { - /* Partition starts above the 8.4GB boundary ==> LBA partition */ - NewPartEntry->PartitionType = PARTITION_XINT13_EXTENDED; - } + PartEntry->AutoCreate = FALSE; + PartEntry->BootIndicator = FALSE; + PartEntry->FormatState = Formatted; + PartEntry->IsPartitioned = TRUE; + PartEntry->New = FALSE; - DiskEntry->ExtendedPartition = NewPartEntry; + if (PartEntry->StartSector.QuadPart < 1450560) + { + /* Partition starts below the 8.4GB boundary ==> CHS partition */ + PartEntry->PartitionType = PARTITION_EXTENDED; + } + else + { + /* Partition starts above the 8.4GB boundary ==> LBA partition */ + PartEntry->PartitionType = PARTITION_XINT13_EXTENDED; + } - PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; - PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart); + 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); -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); - } + AddLogicalDiskSpace(DiskEntry); - AddLogicalDiskSpace(DiskEntry); + UpdateDiskLayout(DiskEntry); - UpdateDiskLayout(DiskEntry); + DiskEntry->Dirty = TRUE; - DiskEntry->Dirty = TRUE; + UpdatePartitionNumbers(DiskEntry); - UpdatePartitionNumbers(DiskEntry); - - AssignDriveLetters(List); + AssignDriveLetters(List); } - -VOID -CreateLogicalPartition( - PPARTLIST List, - ULONGLONG SectorCount) +VOID CreateLogicalPartition(PPARTLIST List, ULONGLONG SectorCount) { -// PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; -// PPARTENTRY NewPartEntry; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PPARTENTRY NewPartEntry; - DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount); + DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount); - if (List == NULL || - List->CurrentDisk == NULL || - List->CurrentPartition == NULL || - List->CurrentPartition->IsPartitioned == TRUE) - { - return; - } + if (List == NULL || + List->CurrentDisk == NULL || + List->CurrentPartition == NULL || + List->CurrentPartition->IsPartitioned == TRUE) + { + return; + } -// DiskEntry = List->CurrentDisk; - PartEntry = List->CurrentPartition; + DiskEntry = List->CurrentDisk; + PartEntry = List->CurrentPartition; - DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); + if(DiskEntry == NULL || PartEntry == NULL) + return; + + DumpPartition("[Current]", PartEntry); + + // If the new partition uses the remainder of the available space + // we reuse the current entry, otherwise we have to add a new + // entry. + if (Align(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart != PartEntry->SectorCount.QuadPart) + { + /* Insert and initialize a new partition entry */ + NewPartEntry = RtlAllocateHeap(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(PARTENTRY)); + + if (NewPartEntry == NULL) + return; + + /* Insert the new entry into the list */ + InsertTailList(&PartEntry->ListEntry, &NewPartEntry->ListEntry); + + NewPartEntry->DiskEntry = DiskEntry; + NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; + NewPartEntry->SectorCount.QuadPart = SectorCount; + + PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; + PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart); + + PartEntry = NewPartEntry; + } + + PartEntry->SectorCount.QuadPart = Align(PartEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment); + PartEntry->IsPartitioned = TRUE; + PartEntry->FormatState = Unformatted; + PartEntry->AutoCreate = FALSE; + PartEntry->New = FALSE; + PartEntry->BootIndicator = FALSE; + PartEntry->LogicalPartition = TRUE; + PartEntry->PartitionType = 0; + PartEntry->PartitionType = PARTITION_FAT32; + //PartEntry->PartitionType = PARTITION_FAT32_XINT13; + + UpdateDiskLayout(DiskEntry); + DiskEntry->Dirty = TRUE; + UpdatePartitionNumbers(DiskEntry); + AssignDriveLetters(List); + DumpPartition("[LogicalCreated]", PartEntry); } - VOID DeleteCurrentPartition( PPARTLIST List) @@ -2870,64 +3209,59 @@ 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; + 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); + 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); + 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; - } + Status = NtOpenFile(&FileHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &Iosb, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile(\\Device\\Harddisk%d\\Partition0) failed (Status %lx)\n", DiskEntry->DiskNumber, Status); + return Status; + } -#ifdef DUMP_PARTITION_TABLE - DumpPartitionTable(DiskEntry); -#endif + DumpPartitionTable(DiskEntry); - 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); - } + 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); + } + NtClose(FileHandle); - if (FileHandle != NULL) - NtClose(FileHandle); - - return Status; + return Status; } @@ -2938,6 +3272,8 @@ PLIST_ENTRY Entry; PDISKENTRY DiskEntry; + DPRINT1("WritePartitionsToDisk(%p)\n", List); + if (List == NULL) return TRUE; @@ -2949,6 +3285,7 @@ if (DiskEntry->Dirty == TRUE) { WritePartitons(List, DiskEntry); + DiskEntry->Dirty = FALSE; } Entry = Entry->Flink; @@ -3006,11 +3343,7 @@ return TRUE; } - -static -ULONG -GetPrimaryPartitionCount( - IN PDISKENTRY DiskEntry) +static ULONG GetPrimaryPartitionCount(IN PDISKENTRY DiskEntry) { PLIST_ENTRY Entry; PPARTENTRY PartEntry; @@ -3021,7 +3354,7 @@ { PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); if (PartEntry->IsPartitioned == TRUE) - nCount++; + nCount++; Entry = Entry->Flink; } @@ -3029,7 +3362,6 @@ return nCount; } - ULONG PrimaryPartitionCreationChecks( IN PPARTLIST List) @@ -3077,7 +3409,6 @@ return ERROR_SUCCESS; } - ULONG LogicalPartitionCreationChecks( IN PPARTLIST List) @@ -3095,4 +3426,5 @@ return ERROR_SUCCESS; } + /* EOF */ Index: reactos/base/setup/usetup/partlist.h =================================================================== --- reactos/base/setup/usetup/partlist.h (revision 67059) +++ reactos/base/setup/usetup/partlist.h (working copy) @@ -111,7 +111,7 @@ BOOLEAN Dirty; BOOLEAN NewDisk; - BOOLEAN NoMbr; /* MBR is absent */ + BOOLEAN Mbr; /* MBR is available */ UNICODE_STRING DriverName; @@ -263,4 +263,17 @@ LogicalPartitionCreationChecks( IN PPARTLIST List); +/** + * Reallocates the drivelayout structure. The function checks how many primary + * and logical partitions are configured in the disk. If more then four primary + * or more than three primary and more than one extended partition is defined + * FALSE is returned and the layout stays untouched. At minimum four entries + * will be allocated, and for each logical partition additional four + * entries are added. The layoutpointer can be NULL. + */ +BOOL ReallocDriveLayout(PDISKENTRY pDiskEntry); + +VOID DumpPartition(TCHAR *pPrefix, PPARTENTRY pPartition); +VOID DumpPartitionInfo(TCHAR *pPrefix, PPARTITION_INFORMATION pPartitionInfo); + /* EOF */