diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 82ab6ebfd39..537a89fd18e 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,25 @@ +2003-04-05 Casper S. Hornstrup + + * bootcd.bat: Install dosmbr.bin. + * drivers/storage/disk/disk.c (DiskClassDeviceControl): Pass physical + device object to IoWritePartitionTable(). + * ntoskrnl/io/xhaldrv.c (xHalReadMBR): New function. + (xHalWriteMBR): Ditto. + (xHalExamineMBR): Use xHalReadMBR() to read MBR. + (xHalIoWritePartitionTable): Partial implement. + * subsys/system/usetup/bootsup.c (InstallMBRBootCodeToDisk): New function. + * subsys/system/usetup/bootsup.h (InstallMBRBootCodeToDisk): Prototype. + * subsys/system/usetup/partlist.c (CreatePartitionListNoGUI): New function. + (CreatePartitionList): Use CreatePartitionListNoGUI() to create partition + list. + (GetPartitionInformation): New function. + (MarkPartitionActive): Ditto. + * subsys/system/usetup/partlist.h (MarkPartitionActive): Prototype. + * subsys/system/usetup/usetup.c (SelectPartitionPage): Make SystemRootPath + point to the selected partition if no partitions are active. + (BootLoaderPage): If no partitions are active, then install a DOS MBR and + mark the selected partition active. + 2003-04-05 Casper S. Hornstrup * Makefile: Add bootcd target. diff --git a/reactos/bootcd.bat b/reactos/bootcd.bat index 4ba1519fb0d..55be6dadb2a 100755 --- a/reactos/bootcd.bat +++ b/reactos/bootcd.bat @@ -15,6 +15,7 @@ rem copy FreeLoader files copy /Y %FREELDR_DIR%\bootsect\isoboot.bin %BOOTCD_DIR% copy /Y %FREELDR_DIR%\freeldr\obj\i386\setupldr.sys %BOOTCD_DIR%\disk\reactos +copy /Y %FREELDR_DIR%\bootsect\dosmbr.bin %BOOTCD_DIR%\disk\loader copy /Y %FREELDR_DIR%\bootsect\ext2.bin %BOOTCD_DIR%\disk\loader copy /Y %FREELDR_DIR%\bootsect\fat.bin %BOOTCD_DIR%\disk\loader copy /Y %FREELDR_DIR%\bootsect\fat32.bin %BOOTCD_DIR%\disk\loader diff --git a/reactos/drivers/storage/disk/disk.c b/reactos/drivers/storage/disk/disk.c index a4d5707c4b2..27a4b3875db 100644 --- a/reactos/drivers/storage/disk/disk.c +++ b/reactos/drivers/storage/disk/disk.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: disk.c,v 1.23 2003/03/28 22:45:47 ekohl Exp $ +/* $Id: disk.c,v 1.24 2003/04/05 15:36:34 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -923,7 +923,7 @@ DiskClassDeviceControl(IN PDEVICE_OBJECT DeviceObject, } else { - Status = IoWritePartitionTable(DeviceExtension->DeviceObject, + Status = IoWritePartitionTable(DeviceExtension->PhysicalDevice, DeviceExtension->DiskGeometry->BytesPerSector, DeviceExtension->DiskGeometry->SectorsPerTrack, DeviceExtension->DiskGeometry->TracksPerCylinder, diff --git a/reactos/ntoskrnl/io/xhaldrv.c b/reactos/ntoskrnl/io/xhaldrv.c index c9c4f807032..505c8ec8f57 100644 --- a/reactos/ntoskrnl/io/xhaldrv.c +++ b/reactos/ntoskrnl/io/xhaldrv.c @@ -1,4 +1,4 @@ -/* $Id: xhaldrv.c,v 1.29 2003/03/28 22:47:33 ekohl Exp $ +/* $Id: xhaldrv.c,v 1.30 2003/04/05 15:36:34 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -30,16 +30,16 @@ typedef struct _PARTITION { - unsigned char BootFlags; - unsigned char StartingHead; - unsigned char StartingSector; - unsigned char StartingCylinder; - unsigned char PartitionType; - unsigned char EndingHead; - unsigned char EndingSector; - unsigned char EndingCylinder; - unsigned int StartingBlock; - unsigned int SectorCount; + unsigned char BootFlags; /* bootable? 0=no, 128=yes */ + unsigned char StartingHead; /* beginning head number */ + unsigned char StartingSector; /* beginning sector number */ + unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */ + unsigned char PartitionType; /* Operating System type indicator code */ + unsigned char EndingHead; /* ending head number */ + unsigned char EndingSector; /* ending sector number */ + unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */ + unsigned int StartingBlock; /* first sector relative to start of disk */ + unsigned int SectorCount; /* number of sectors in partition */ } PACKED PARTITION, *PPARTITION; typedef struct _PARTITION_TABLE @@ -174,22 +174,23 @@ xHalQueryDriveLayout(IN PUNICODE_STRING DeviceName, } -VOID FASTCALL -xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, +static NTSTATUS +xHalReadMBR(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, - IN ULONG MBRTypeIdentifier, OUT PVOID *Buffer) { KEVENT Event; IO_STATUS_BLOCK StatusBlock; LARGE_INTEGER Offset; PUCHAR Sector; - PULONG Shift; - PMBR Mbr; PIRP Irp; NTSTATUS Status; - DPRINT("xHalExamineMBR()\n"); + DPRINT("xHalReadMBR()\n"); + + assert(DeviceObject); + assert(Buffer); + *Buffer = NULL; if (SectorSize < 512) @@ -200,7 +201,7 @@ xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, Sector = (PUCHAR)ExAllocatePool(PagedPool, SectorSize); if (Sector == NULL) - return; + return STATUS_NO_MEMORY; KeInitializeEvent(&Event, NotificationEvent, @@ -233,6 +234,90 @@ xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, DPRINT("Reading MBR failed (Status 0x%08lx)\n", Status); ExFreePool(Sector); + return Status; + } + + *Buffer = (PVOID)Sector; + return Status; +} + + +static NTSTATUS +xHalWriteMBR(IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + OUT PVOID Sector) +{ + KEVENT Event; + IO_STATUS_BLOCK StatusBlock; + LARGE_INTEGER Offset; + PIRP Irp; + NTSTATUS Status; + + DPRINT("xHalWriteMBR()\n"); + + if (SectorSize < 512) + SectorSize = 512; + if (SectorSize > 4096) + SectorSize = 4096; + + KeInitializeEvent(&Event, + NotificationEvent, + FALSE); + + /* Write MBR (Master Boot Record) */ + Offset.QuadPart = 0; + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, + DeviceObject, + Sector, + SectorSize, + &Offset, + &Event, + &StatusBlock); + + Status = IoCallDriver(DeviceObject, + Irp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + Status = StatusBlock.Status; + } + + if (!NT_SUCCESS(Status)) + { + DPRINT("Writing MBR failed (Status 0x%08lx)\n", + Status); + return Status; + } + + return Status; +} + + +VOID FASTCALL +xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG MBRTypeIdentifier, + OUT PVOID *Buffer) +{ + PUCHAR Sector; + PULONG Shift; + PMBR Mbr; + NTSTATUS Status; + + DPRINT("xHalExamineMBR()\n"); + + *Buffer = NULL; + + Status = xHalReadMBR(DeviceObject, + SectorSize, + (PVOID *) &Sector); + if (!NT_SUCCESS(Status)) + { + DPRINT1("\n"); return; } @@ -867,7 +952,125 @@ xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG NumberOfHeads, IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer) { - return(STATUS_NOT_IMPLEMENTED); + PPARTITION_TABLE PartitionTable; + NTSTATUS Status; + PMBR MbrBuffer; + ULONG i; + + DPRINT("xHalIoWritePartitionTable(%p %lu %lu %p)\n", + DeviceObject, + SectorSize, + SectorsPerTrack, + PartitionBuffer); + + assert(DeviceObject); + assert(PartitionBuffer); + + /* Check for 'Ontrack Disk Manager' */ + xHalExamineMBR(DeviceObject, + SectorSize, + 0x54, + (PVOID *) &MbrBuffer); + if (MbrBuffer != NULL) + { + DPRINT1("Ontrack Disk Manager is not supported\n"); + ExFreePool(MbrBuffer); + return STATUS_UNSUCCESSFUL; + } + + /* Check for 'EZ-Drive' */ + xHalExamineMBR(DeviceObject, + SectorSize, + 0x55, + (PVOID *) &MbrBuffer); + if (MbrBuffer != NULL) + { + DPRINT1("EZ-Drive is not supported\n"); + ExFreePool(MbrBuffer); + return STATUS_UNSUCCESSFUL; + } + + + for (i = 0; i < PartitionBuffer->PartitionCount; i++) + { + if (IsContainerPartition(PartitionBuffer->PartitionEntry[i].PartitionType)) + { + /* FIXME: Implement */ + DPRINT1("Writing MBRs with extended partitions is not implemented\n"); + ExFreePool(MbrBuffer); + } + } + + + ExFreePool(MbrBuffer); + + Status = xHalReadMBR(DeviceObject, + SectorSize, + (PVOID *) &MbrBuffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("xHalReadMBR() failed with status 0x%.08x\n", Status); + return Status; + } + + DPRINT1("WARNING: Only 'BootFlags' is implemented\n"); + + PartitionTable = (PPARTITION_TABLE)(&MbrBuffer->Partition[0]); + + for (i = 0; i < PartitionBuffer->PartitionCount; i++) + { + //= PartitionBuffer->PartitionEntry[i].StartingOffset; + //= PartitionBuffer->PartitionEntry[i].PartitionLength; + //= PartitionBuffer->PartitionEntry[i].HiddenSectors; + //= PartitionBuffer->PartitionEntry[i].PartitionType; + //= PartitionBuffer->PartitionEntry[i].PartitionType; + + if (PartitionBuffer->PartitionEntry[i].BootIndicator) + { + MbrBuffer->Partition[i].BootFlags |= 0x80; + } + else + { + MbrBuffer->Partition[i].BootFlags &= ~0x80; + } + + //= PartitionBuffer->PartitionEntry[i].RecognizedPartition; + //= PartitionBuffer->PartitionEntry[i].RewritePartition; + } + + + Status = xHalWriteMBR(DeviceObject, + SectorSize, + (PVOID) MbrBuffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("xHalWriteMBR() failed with status 0x%.08x\n", Status); + ExFreePool(MbrBuffer); + return Status; + } + +#ifndef NDEBUG + for (i = 0; i < PARTITION_TBL_SIZE; i++) + { + DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n", + i, + PartitionTable->Partition[i].BootFlags, + PartitionTable->Partition[i].PartitionType, + PartitionTable->Partition[i].StartingHead, + PartitionTable->Partition[i].StartingSector & 0x3f, + (((PartitionTable->Partition[i].StartingSector) & 0xc0) << 2) + + PartitionTable->Partition[i].StartingCylinder, + PartitionTable->Partition[i].EndingHead, + PartitionTable->Partition[i].EndingSector, + PartitionTable->Partition[i].EndingCylinder, + PartitionTable->Partition[i].StartingBlock, + PartitionTable->Partition[i].SectorCount); + } +#endif + + ExFreePool(MbrBuffer); + + return(STATUS_SUCCESS); } /* EOF */ diff --git a/reactos/subsys/system/usetup/bootsup.c b/reactos/subsys/system/usetup/bootsup.c index 77edba36ad3..e4909f387d6 100644 --- a/reactos/subsys/system/usetup/bootsup.c +++ b/reactos/subsys/system/usetup/bootsup.c @@ -921,6 +921,165 @@ CHECKPOINT1; } +NTSTATUS +InstallMBRBootCodeToDisk(PWSTR SrcPath, + PWSTR RootPath) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + HANDLE FileHandle; + NTSTATUS Status; + PUCHAR OrigBootSector; + PUCHAR NewBootSector; + + /* Allocate buffer for original bootsector */ + OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (OrigBootSector == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Read current boot sector into buffer */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + OrigBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + + /* Allocate buffer for new bootsector */ + NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (NewBootSector == NULL) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Read new bootsector from SrcPath */ + RtlInitUnicodeString(&Name, + SrcPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + /* Copy partition table from old MBR to new */ + memcpy((NewBootSector + 446), (OrigBootSector + 446), 4*16 /* Length of partition table */); + + /* Free the original boot sector */ + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + + /* Write new bootsector to RootPath */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_WRITE_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + + /* Free the new boot sector */ + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + + return(Status); +} + + NTSTATUS InstallFat16BootCodeToDisk(PWSTR SrcPath, PWSTR RootPath) diff --git a/reactos/subsys/system/usetup/bootsup.h b/reactos/subsys/system/usetup/bootsup.h index a069b371ad6..edb005b6939 100644 --- a/reactos/subsys/system/usetup/bootsup.h +++ b/reactos/subsys/system/usetup/bootsup.h @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: bootsup.h,v 1.3 2003/01/30 14:41:45 ekohl Exp $ +/* $Id: bootsup.h,v 1.4 2003/04/05 15:36:34 chorns Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS text-mode setup * FILE: subsys/system/usetup/bootsup.h @@ -53,6 +53,10 @@ InstallFat32BootCodeToFile(PWSTR SrcPath, PWSTR DstPath, PWSTR RootPath); +NTSTATUS +InstallMBRBootCodeToDisk(PWSTR SrcPath, + PWSTR RootPath); + NTSTATUS InstallFat16BootCodeToDisk(PWSTR SrcPath, PWSTR RootPath); diff --git a/reactos/subsys/system/usetup/partlist.c b/reactos/subsys/system/usetup/partlist.c index 89185baeb26..8bcb1f0c88e 100644 --- a/reactos/subsys/system/usetup/partlist.c +++ b/reactos/subsys/system/usetup/partlist.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: partlist.c,v 1.6 2003/01/17 13:18:15 ekohl Exp $ +/* $Id: partlist.c,v 1.7 2003/04/05 15:36:34 chorns Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS text-mode setup * FILE: subsys/system/usetup/partlist.c @@ -156,10 +156,7 @@ GetDriverName(PDISKENTRY DiskEntry) PPARTLIST -CreatePartitionList(SHORT Left, - SHORT Top, - SHORT Right, - SHORT Bottom) +CreatePartitionListNoGUI() { PPARTLIST List; OBJECT_ATTRIBUTES ObjectAttributes; @@ -179,10 +176,10 @@ CreatePartitionList(SHORT Left, if (List == NULL) return(NULL); - List->Left = Left; - List->Top = Top; - List->Right = Right; - List->Bottom = Bottom; + List->Left = 0; + List->Top = 0; + List->Right = 0; + List->Bottom = 0; List->Line = 0; @@ -314,12 +311,191 @@ CreatePartitionList(SHORT Left, List->CurrentDisk = 0; List->CurrentPartition = 0; + return(List); +} + +PPARTLIST +CreatePartitionList(SHORT Left, + SHORT Top, + SHORT Right, + SHORT Bottom) +{ + PPARTLIST List; + + List = CreatePartitionListNoGUI(); + if (List == NULL) + return(NULL); + + List->Left = Left; + List->Top = Top; + List->Right = Right; + List->Bottom = Bottom; + DrawPartitionList(List); return(List); } +PPARTENTRY +GetPartitionInformation(PPARTLIST List, + ULONG DiskNumber, + ULONG PartitionNumber, + PULONG PartEntryNumber) +{ + PPARTENTRY PartEntry; + ULONG i; + + if (List->DiskArray == NULL) + { + return(FALSE); + } + + if (DiskNumber >= List->DiskCount) + { + return(FALSE); + } + + if (PartitionNumber >= List->DiskArray[DiskNumber].PartCount) + { + return(FALSE); + } + + if (List->DiskArray[DiskNumber].FixedDisk != TRUE) + { + return(FALSE); + } + + for (i = 0; i < List->DiskArray[DiskNumber].PartCount; i++) + { + PartEntry = &List->DiskArray[DiskNumber].PartArray[i]; + if (PartEntry->PartNumber == PartitionNumber) + { + *PartEntryNumber = i; + return PartEntry; + } + } + return NULL; +} + +BOOLEAN +MarkPartitionActive(ULONG DiskNumber, + ULONG PartitionNumber, + PPARTDATA ActivePartition) +{ + PPARTLIST List; + PPARTENTRY PartEntry; + ULONG PartEntryNumber; + OBJECT_ATTRIBUTES ObjectAttributes; + DRIVE_LAYOUT_INFORMATION *LayoutBuffer; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + WCHAR Buffer[MAX_PATH]; + UNICODE_STRING Name; + HANDLE FileHandle; + + List = CreatePartitionListNoGUI(); + if (List == NULL) + { + return(FALSE); + } + + PartEntry = GetPartitionInformation(List, + DiskNumber, + PartitionNumber, + &PartEntryNumber); + if (List == NULL) + { + DestroyPartitionList(List); + return(FALSE); + } + + + swprintf(Buffer, + L"\\Device\\Harddisk%d\\Partition0", + DiskNumber); + RtlInitUnicodeString(&Name, Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + 0x10001, + &ObjectAttributes, + &Iosb, + 1, + FILE_SYNCHRONOUS_IO_NONALERT); + if (NT_SUCCESS(Status)) + { + LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192); + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_DRIVE_LAYOUT, + NULL, + 0, + LayoutBuffer, + 8192); + if (!NT_SUCCESS(Status)) + { + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + DestroyPartitionList(List); + return FALSE; + } + + + LayoutBuffer->PartitionEntry[PartEntryNumber].BootIndicator = TRUE; + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_SET_DRIVE_LAYOUT, + LayoutBuffer, + 8192, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + DestroyPartitionList(List); + return FALSE; + } + } + else + { + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + DestroyPartitionList(List); + return FALSE; + } + + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + + PartEntry->Active = TRUE; + if (!GetActiveBootPartition(List, ActivePartition)) + { + DestroyPartitionList(List); + DPRINT("GetActiveBootPartition() failed\n"); + return FALSE; + } + + DestroyPartitionList(List); + + return TRUE; +} + + VOID DestroyPartitionList(PPARTLIST List) { @@ -838,7 +1014,9 @@ GetSelectedPartition(PPARTLIST List, PartEntry = &DiskEntry->PartArray[List->CurrentPartition]; if (PartEntry->Used == FALSE) - return(FALSE); + { + return(FALSE); + } /* Copy disk-specific data */ Data->DiskSize = DiskEntry->DiskSize; @@ -870,7 +1048,6 @@ GetSelectedPartition(PPARTLIST List, Data->PartNumber = PartEntry->PartNumber; Data->PartType = PartEntry->PartType; Data->DriveLetter = PartEntry->DriveLetter; - return(TRUE); } @@ -889,7 +1066,9 @@ GetActiveBootPartition(PPARTLIST List, DiskEntry = &List->DiskArray[0]; if (DiskEntry->FixedDisk == FALSE) + { return(FALSE); + } for (i = 0; i < DiskEntry->PartCount; i++) { @@ -898,7 +1077,9 @@ GetActiveBootPartition(PPARTLIST List, PartEntry = &DiskEntry->PartArray[i]; if (PartEntry->Used == FALSE) + { return(FALSE); + } /* Copy disk-specific data */ Data->DiskSize = DiskEntry->DiskSize; diff --git a/reactos/subsys/system/usetup/partlist.h b/reactos/subsys/system/usetup/partlist.h index 79853bdf72e..fe8bf0bfbaa 100644 --- a/reactos/subsys/system/usetup/partlist.h +++ b/reactos/subsys/system/usetup/partlist.h @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: partlist.h,v 1.7 2003/02/27 14:42:43 ekohl Exp $ +/* $Id: partlist.h,v 1.8 2003/04/05 15:36:34 chorns Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS text-mode setup * FILE: subsys/system/usetup/partlist.h @@ -107,6 +107,11 @@ CreatePartitionList(SHORT Left, SHORT Right, SHORT Bottom); +BOOLEAN +MarkPartitionActive(ULONG DiskNumber, + ULONG PartitionNumber, + PPARTDATA ActivePartition); + VOID DestroyPartitionList(PPARTLIST List); diff --git a/reactos/subsys/system/usetup/usetup.c b/reactos/subsys/system/usetup/usetup.c index cb297722944..b9575d70f39 100644 --- a/reactos/subsys/system/usetup/usetup.c +++ b/reactos/subsys/system/usetup/usetup.c @@ -687,10 +687,22 @@ SelectPartitionPage(PINPUT_RECORD Ir) PathBuffer); RtlFreeUnicodeString(&SystemRootPath); - swprintf(PathBuffer, - L"\\Device\\Harddisk%lu\\Partition%lu", - ActivePartition.DiskNumber, - ActivePartition.PartNumber); + + if (ActivePartitionValid) + { + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + ActivePartition.DiskNumber, + ActivePartition.PartNumber); + } + else + { + /* We mark the selected partition as bootable */ + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + PartData.DiskNumber, + PartData.PartNumber); + } RtlCreateUnicodeString(&SystemRootPath, PathBuffer); @@ -1392,6 +1404,7 @@ BootLoaderPage(PINPUT_RECORD Ir) PINICACHE IniCache; PINICACHESECTION IniSection; NTSTATUS Status; + BOOLEAN InstallMBR = FALSE; SetTextXY(6, 8, "Installing the boot loader"); @@ -1399,19 +1412,63 @@ BootLoaderPage(PINPUT_RECORD Ir) if (ActivePartitionValid == FALSE) { - DPRINT1("Error: no active partition found\n"); - PopupError("Setup could not find an active partiton\n", - "ENTER = Reboot computer"); + /* Mark the chosen partition as active since there is no active + partition now */ + + if (!MarkPartitionActive(PartData.DiskNumber, + PartData.PartNumber, &ActivePartition)) + { + PopupError("Setup could not mark the system partiton active\n", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + InstallMBR = TRUE; + } - while(TRUE) - { - ConInKey(Ir); + if (InstallMBR) + { + WCHAR PathBuffer[MAX_PATH]; + UNICODE_STRING SystemRootMBRPath; + + RtlFreeUnicodeString(&SystemRootMBRPath); + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition0", + PartData.DiskNumber); + RtlCreateUnicodeString(&SystemRootMBRPath, + PathBuffer); - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(QUIT_PAGE); - } - } + /* Install MBR bootcode */ + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\dosmbr.bin"); + + DPRINT1("Install MBR bootcode: %S ==> %S\n", SrcPath, SystemRootMBRPath.Buffer); + Status = InstallMBRBootCodeToDisk(SrcPath, + SystemRootMBRPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallMBRBootCodeToDisk() failed (Status %lx)\n", Status); + PopupError("Setup failed to install the MBR bootcode.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } } if (ActivePartition.PartType == PARTITION_ENTRY_UNUSED)