From f2f176a20249e034ddacc5d172e252d09fabddfe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 2 Feb 2016 01:55:05 +0000 Subject: [PATCH] [USETUP] - Use defines instead of hardcoded values for partition type IDs. - Add some support for installing ReactOS on EXT2 partitions. - Add few code that will be needed when we support NTFS installation. - Refactor InstallFatBootcodeToPartition and its auxiliary functions. CORE-4870 svn path=/trunk/; revision=70675 --- reactos/base/setup/usetup/bootsup.c | 1071 ++++++++++++------ reactos/base/setup/usetup/bootsup.h | 59 - reactos/base/setup/usetup/filesup.c | 2 +- reactos/base/setup/usetup/interface/usetup.c | 21 +- reactos/base/setup/usetup/native/fslist.c | 1 + reactos/base/setup/usetup/partlist.h | 3 - reactos/base/setup/usetup/usetup.h | 4 +- 7 files changed, 734 insertions(+), 427 deletions(-) diff --git a/reactos/base/setup/usetup/bootsup.c b/reactos/base/setup/usetup/bootsup.c index 1ce25e1bfd7..59b58a8da2c 100644 --- a/reactos/base/setup/usetup/bootsup.c +++ b/reactos/base/setup/usetup/bootsup.c @@ -78,6 +78,16 @@ typedef struct _FAT32_BOOTSECTOR USHORT BootSectorMagic; // 0xAA55 } FAT32_BOOTSECTOR, *PFAT32_BOOTSECTOR; + +typedef struct _EXT2_BOOTSECTOR +{ + // The EXT2 bootsector is completely user-specific. + // No FS data is stored there. + UCHAR Fill[1024]; +} EXT2_BOOTSECTOR, *PEXT2_BOOTSECTOR; + +// TODO: Add more bootsector structures! + #include extern PPARTLIST PartitionList; @@ -287,8 +297,9 @@ CreateCommonFreeLoaderSections( L"Seconds until highlighted choice will be started automatically: "); } +static NTSTATUS -CreateFreeLoaderEntry( +CreateNTOSEntry( PINICACHE IniCache, PINICACHESECTION OSSection, PWCHAR Section, @@ -323,7 +334,7 @@ CreateFreeLoaderEntry( L"SystemPath", ArcPath); - /* Options=*/ + /* Options= */ IniCacheInsertKey(IniSection, NULL, INSERT_LAST, @@ -345,58 +356,59 @@ CreateFreeLoaderReactOSEntries( IniSection = IniCacheAppendSection(IniCache, L"Operating Systems"); /* ReactOS */ - CreateFreeLoaderEntry(IniCache, IniSection, - L"ReactOS", L"\"ReactOS\"", - L"Windows2003", ArcPath, - L""); + CreateNTOSEntry(IniCache, IniSection, + L"ReactOS", L"\"ReactOS\"", + L"Windows2003", ArcPath, + L""); /* ReactOS_Debug */ - CreateFreeLoaderEntry(IniCache, IniSection, - L"ReactOS_Debug", L"\"ReactOS (Debug)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS"); + CreateNTOSEntry(IniCache, IniSection, + L"ReactOS_Debug", L"\"ReactOS (Debug)\"", + L"Windows2003", ArcPath, + L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS"); #ifdef _WINKD_ /* ReactOS_VBoxDebug */ - CreateFreeLoaderEntry(IniCache, IniSection, - L"ReactOS_VBoxDebug", L"\"ReactOS (VBoxDebug)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=VBOX /SOS"); + CreateNTOSEntry(IniCache, IniSection, + L"ReactOS_VBoxDebug", L"\"ReactOS (VBoxDebug)\"", + L"Windows2003", ArcPath, + L"/DEBUG /DEBUGPORT=VBOX /SOS"); #endif #if DBG #ifndef _WINKD_ /* ReactOS_KdSerial */ - CreateFreeLoaderEntry(IniCache, IniSection, - L"ReactOS_KdSerial", L"\"ReactOS (RosDbg)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL"); + CreateNTOSEntry(IniCache, IniSection, + L"ReactOS_KdSerial", L"\"ReactOS (RosDbg)\"", + L"Windows2003", ArcPath, + L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL"); #endif /* ReactOS_Screen */ - CreateFreeLoaderEntry(IniCache, IniSection, - L"ReactOS_Screen", L"\"ReactOS (Screen)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=SCREEN /SOS"); + CreateNTOSEntry(IniCache, IniSection, + L"ReactOS_Screen", L"\"ReactOS (Screen)\"", + L"Windows2003", ArcPath, + L"/DEBUG /DEBUGPORT=SCREEN /SOS"); /* ReactOS_LogFile */ - CreateFreeLoaderEntry(IniCache, IniSection, - L"ReactOS_LogFile", L"\"ReactOS (Log file)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=FILE /SOS"); + CreateNTOSEntry(IniCache, IniSection, + L"ReactOS_LogFile", L"\"ReactOS (Log file)\"", + L"Windows2003", ArcPath, + L"/DEBUG /DEBUGPORT=FILE /SOS"); /* ReactOS_Ram */ - CreateFreeLoaderEntry(IniCache, IniSection, - L"ReactOS_Ram", L"\"ReactOS (RAM Disk)\"", - L"Windows2003", L"ramdisk(0)\\ReactOS", - L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256"); + CreateNTOSEntry(IniCache, IniSection, + L"ReactOS_Ram", L"\"ReactOS (RAM Disk)\"", + L"Windows2003", L"ramdisk(0)\\ReactOS", + L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256"); /* ReactOS_EMS */ - CreateFreeLoaderEntry(IniCache, IniSection, - L"ReactOS_EMS", L"\"ReactOS (Emergency Management Services)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200"); + CreateNTOSEntry(IniCache, IniSection, + L"ReactOS_EMS", L"\"ReactOS (Emergency Management Services)\"", + L"Windows2003", ArcPath, + L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200"); #endif } +static NTSTATUS CreateFreeLoaderIniForReactOS( PWCHAR IniPath, @@ -420,10 +432,16 @@ CreateFreeLoaderIniForReactOS( return STATUS_SUCCESS; } +static NTSTATUS -CreateFreeLoaderIniForDos( +CreateFreeLoaderIniForReactOSAndBootSector( PWCHAR IniPath, - PWCHAR ArcPath) + PWCHAR ArcPath, + PWCHAR Section, + PWCHAR Description, + PWCHAR BootDrive, + PWCHAR BootPartition, + PWCHAR BootSector) { PINICACHE IniCache; PINICACHESECTION IniSection; @@ -440,15 +458,15 @@ CreateFreeLoaderIniForDos( /* Get "Operating Systems" section */ IniSection = IniCacheGetSection(IniCache, L"Operating Systems"); - /* DOS=DOS/Windows */ + /* Insert entry into "Operating Systems" section */ IniCacheInsertKey(IniSection, NULL, INSERT_LAST, - L"DOS", - L"\"DOS/Windows\""); + Section, + Description); - /* Create the "DOS" section */ - IniSection = IniCacheAppendSection(IniCache, L"DOS"); + /* Create new section */ + IniSection = IniCacheAppendSection(IniCache, Section); /* BootType=BootSector */ IniCacheInsertKey(IniSection, @@ -457,26 +475,26 @@ CreateFreeLoaderIniForDos( L"BootType", L"BootSector"); - /* BootDrive=hd0 */ + /* BootDrive= */ IniCacheInsertKey(IniSection, NULL, INSERT_LAST, L"BootDrive", - L"hd0"); + BootDrive); - /* BootPartition=1 */ + /* BootPartition= */ IniCacheInsertKey(IniSection, NULL, INSERT_LAST, L"BootPartition", - L"1"); + BootPartition); - /* BootSector=BOOTSECT.DOS */ + /* BootSector= */ IniCacheInsertKey(IniSection, NULL, INSERT_LAST, L"BootSectorFile", - L"BOOTSECT.DOS"); + BootSector); /* Save the INI file */ IniCacheSave(IniCache, IniPath); @@ -485,12 +503,13 @@ CreateFreeLoaderIniForDos( return STATUS_SUCCESS; } - +static NTSTATUS UpdateFreeLoaderIni( PWCHAR IniPath, PWCHAR ArcPath) { + NTSTATUS Status; PINICACHE IniCache; PINICACHESECTION IniSection; PINICACHESECTION OsIniSection; @@ -500,7 +519,6 @@ UpdateFreeLoaderIni( WCHAR SectionName2[200]; PWCHAR KeyData; ULONG i,j; - NTSTATUS Status; Status = IniCacheLoad(&IniCache, IniPath, FALSE); if (!NT_SUCCESS(Status)) @@ -597,10 +615,10 @@ UpdateFreeLoaderIni( } /* Create a new "ReactOS" entry */ - CreateFreeLoaderEntry(IniCache, IniSection, - SectionName, OsName, - L"Windows2003", ArcPath, - L""); + CreateNTOSEntry(IniCache, IniSection, + SectionName, OsName, + L"Windows2003", ArcPath, + L""); IniCacheSave(IniCache, IniPath); IniCacheDestroy(IniCache); @@ -608,21 +626,92 @@ UpdateFreeLoaderIni( return STATUS_SUCCESS; } +static +BOOLEAN +IsThereAValidBootSector(PWSTR RootPath) +{ + /* + * Check the first DWORD (4 bytes) of the bootsector for a potential + * "valid" instruction (the BIOS starts execution of the bootsector + * at its beginning). Currently the criterium is that this DWORD must + * be non-zero. + */ + + NTSTATUS Status; + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + LARGE_INTEGER FileOffset; + PUCHAR BootSector; + ULONG Instruction; + + /* Allocate buffer for bootsector */ + BootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); + if (BootSector == NULL) + return FALSE; // STATUS_INSUFFICIENT_RESOURCES; + + /* Read current boot sector into buffer */ + RtlInitUnicodeString(&Name, RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_READ | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, BootSector); + return FALSE; // Status; + } + + FileOffset.QuadPart = 0ULL; + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + BootSector, + SECTORSIZE, + &FileOffset, + NULL); + NtClose(FileHandle); + + Instruction = *(PULONG)BootSector; + + /* Free the boot sector */ + RtlFreeHeap(ProcessHeap, 0, BootSector); + + if (!NT_SUCCESS(Status)) + return FALSE; // Status; + + return (Instruction != 0x00000000); +} +static NTSTATUS SaveCurrentBootSector( PWSTR RootPath, - PWSTR DstPath) + PWSTR DstPath, + ULONG Length) { + NTSTATUS Status; + UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING Name; HANDLE FileHandle; - NTSTATUS Status; + LARGE_INTEGER FileOffset; PUCHAR BootSector; /* Allocate buffer for bootsector */ - BootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); + BootSector = RtlAllocateHeap(ProcessHeap, 0, Length); if (BootSector == NULL) return STATUS_INSUFFICIENT_RESOURCES; @@ -647,14 +736,15 @@ SaveCurrentBootSector( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, BootSector, - SECTORSIZE, - NULL, + Length, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -695,36 +785,37 @@ SaveCurrentBootSector( NULL, &IoStatusBlock, BootSector, - SECTORSIZE, + Length, NULL, NULL); NtClose(FileHandle); - /* Free the new boot sector */ + /* Free the boot sector */ RtlFreeHeap(ProcessHeap, 0, BootSector); return Status; } - +static NTSTATUS InstallFat16BootCodeToFile( PWSTR SrcPath, PWSTR DstPath, PWSTR RootPath) { + NTSTATUS Status; + UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING Name; HANDLE FileHandle; - NTSTATUS Status; + LARGE_INTEGER FileOffset; PFAT_BOOTSECTOR OrigBootSector; PFAT_BOOTSECTOR NewBootSector; /* Allocate buffer for original bootsector */ OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); if (OrigBootSector == NULL) - return STATUS_INSUFFICIENT_RESOURCES ; + return STATUS_INSUFFICIENT_RESOURCES; /* Read current boot sector into buffer */ RtlInitUnicodeString(&Name, RootPath); @@ -747,6 +838,7 @@ InstallFat16BootCodeToFile( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, @@ -754,7 +846,7 @@ InstallFat16BootCodeToFile( &IoStatusBlock, OrigBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -793,6 +885,7 @@ InstallFat16BootCodeToFile( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, @@ -800,7 +893,7 @@ InstallFat16BootCodeToFile( &IoStatusBlock, NewBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -845,9 +938,7 @@ InstallFat16BootCodeToFile( return Status; } -#if 0 - FilePosition.QuadPart = 0; -#endif + FileOffset.QuadPart = 0ULL; Status = NtWriteFile(FileHandle, NULL, NULL, @@ -865,21 +956,21 @@ InstallFat16BootCodeToFile( return Status; } - +static NTSTATUS InstallFat32BootCodeToFile( PWSTR SrcPath, PWSTR DstPath, PWSTR RootPath) { + NTSTATUS Status; + UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING Name; HANDLE FileHandle; - NTSTATUS Status; + LARGE_INTEGER FileOffset; PFAT32_BOOTSECTOR OrigBootSector; PFAT32_BOOTSECTOR NewBootSector; - LARGE_INTEGER FileOffset; /* Allocate buffer for original bootsector */ OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); @@ -907,6 +998,7 @@ InstallFat32BootCodeToFile( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, @@ -1008,6 +1100,7 @@ InstallFat32BootCodeToFile( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtWriteFile(FileHandle, NULL, NULL, @@ -1072,11 +1165,12 @@ InstallMbrBootCodeToDisk( PWSTR SrcPath, PWSTR RootPath) { + NTSTATUS Status; + UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING Name; HANDLE FileHandle; - NTSTATUS Status; + LARGE_INTEGER FileOffset; PPARTITION_SECTOR OrigBootSector; PPARTITION_SECTOR NewBootSector; @@ -1109,6 +1203,7 @@ InstallMbrBootCodeToDisk( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, @@ -1116,7 +1211,7 @@ InstallMbrBootCodeToDisk( &IoStatusBlock, OrigBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -1204,6 +1299,7 @@ InstallMbrBootCodeToDisk( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtWriteFile(FileHandle, NULL, NULL, @@ -1211,7 +1307,7 @@ InstallMbrBootCodeToDisk( &IoStatusBlock, NewBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); @@ -1221,17 +1317,18 @@ InstallMbrBootCodeToDisk( return Status; } - +static NTSTATUS InstallFat12BootCodeToFloppy( PWSTR SrcPath, PWSTR RootPath) { + NTSTATUS Status; + UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING Name; HANDLE FileHandle; - NTSTATUS Status; + LARGE_INTEGER FileOffset; PFAT_BOOTSECTOR OrigBootSector; PFAT_BOOTSECTOR NewBootSector; @@ -1261,6 +1358,7 @@ InstallFat12BootCodeToFloppy( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, @@ -1268,7 +1366,7 @@ InstallFat12BootCodeToFloppy( &IoStatusBlock, OrigBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -1357,9 +1455,7 @@ InstallFat12BootCodeToFloppy( return Status; } -#if 0 - FilePosition.QuadPart = 0; -#endif + FileOffset.QuadPart = 0ULL; Status = NtWriteFile(FileHandle, NULL, NULL, @@ -1367,7 +1463,7 @@ InstallFat12BootCodeToFloppy( &IoStatusBlock, NewBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); @@ -1377,17 +1473,18 @@ InstallFat12BootCodeToFloppy( return Status; } - +static NTSTATUS InstallFat16BootCodeToDisk( PWSTR SrcPath, PWSTR RootPath) { + NTSTATUS Status; + UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING Name; HANDLE FileHandle; - NTSTATUS Status; + LARGE_INTEGER FileOffset; PFAT_BOOTSECTOR OrigBootSector; PFAT_BOOTSECTOR NewBootSector; @@ -1417,6 +1514,7 @@ InstallFat16BootCodeToDisk( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, @@ -1424,7 +1522,7 @@ InstallFat16BootCodeToDisk( &IoStatusBlock, OrigBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -1434,9 +1532,7 @@ InstallFat16BootCodeToDisk( } /* Allocate buffer for new bootsector */ - NewBootSector = RtlAllocateHeap(ProcessHeap, - 0, - SECTORSIZE); + NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); if (NewBootSector == NULL) { RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -1515,9 +1611,7 @@ InstallFat16BootCodeToDisk( return Status; } -#if 0 - FilePosition.QuadPart = 0; -#endif + FileOffset.QuadPart = 0ULL; Status = NtWriteFile(FileHandle, NULL, NULL, @@ -1525,7 +1619,7 @@ InstallFat16BootCodeToDisk( &IoStatusBlock, NewBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); @@ -1535,20 +1629,20 @@ InstallFat16BootCodeToDisk( return Status; } - +static NTSTATUS InstallFat32BootCodeToDisk( PWSTR SrcPath, PWSTR RootPath) { + NTSTATUS Status; + UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING Name; HANDLE FileHandle; - NTSTATUS Status; + LARGE_INTEGER FileOffset; PFAT32_BOOTSECTOR OrigBootSector; PFAT32_BOOTSECTOR NewBootSector; - LARGE_INTEGER FileOffset; USHORT BackupBootSector; /* Allocate buffer for original bootsector */ @@ -1577,6 +1671,7 @@ InstallFat32BootCodeToDisk( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, @@ -1584,7 +1679,7 @@ InstallFat32BootCodeToDisk( &IoStatusBlock, OrigBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -1741,21 +1836,30 @@ InstallFat32BootCodeToDisk( return Status; } - static NTSTATUS -UnprotectBootIni( - PWSTR FileName, - PULONG Attributes) +InstallExt2BootCodeToDisk( + PWSTR SrcPath, + PWSTR RootPath) { + NTSTATUS Status; UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - FILE_BASIC_INFORMATION FileInfo; HANDLE FileHandle; - NTSTATUS Status; + LARGE_INTEGER FileOffset; +// PEXT2_BOOTSECTOR OrigBootSector; + PEXT2_BOOTSECTOR NewBootSector; + // USHORT BackupBootSector; - RtlInitUnicodeString(&Name, FileName); +#if 0 + /* Allocate buffer for original bootsector */ + OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); + if (OrigBootSector == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + /* Read current boot sector into buffer */ + RtlInitUnicodeString(&Name, RootPath); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -1764,72 +1868,45 @@ UnprotectBootIni( NULL); Status = NtOpenFile(&FileHandle, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, FILE_SYNCHRONOUS_IO_NONALERT); - if (Status == STATUS_NO_SUCH_FILE) - { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - *Attributes = 0; - return STATUS_SUCCESS; - } if (!NT_SUCCESS(Status)) { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); return Status; } - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); + FileOffset.QuadPart = 0ULL; + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + OrigBootSector, + SECTORSIZE, + &FileOffset, + NULL); + NtClose(FileHandle); if (!NT_SUCCESS(Status)) { - DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); - NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); return Status; } +#endif - *Attributes = FileInfo.FileAttributes; - - /* Delete attributes SYSTEM, HIDDEN and READONLY */ - FileInfo.FileAttributes = FileInfo.FileAttributes & - ~(FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_HIDDEN | - FILE_ATTRIBUTE_READONLY); - - Status = NtSetInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) + /* Allocate buffer for new bootsector */ + NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(EXT2_BOOTSECTOR)); + if (NewBootSector == NULL) { - DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); + // RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return STATUS_INSUFFICIENT_RESOURCES; } - NtClose(FileHandle); - return Status; -} - - -static -NTSTATUS -ProtectBootIni( - PWSTR FileName, - ULONG Attributes) -{ - UNICODE_STRING Name; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - FILE_BASIC_INFORMATION FileInfo; - HANDLE FileHandle; - NTSTATUS Status; - - RtlInitUnicodeString(&Name, FileName); + /* Read new bootsector from SrcPath */ + RtlInitUnicodeString(&Name, SrcPath); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -1838,19 +1915,180 @@ ProtectBootIni( NULL); Status = NtOpenFile(&FileHandle, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + // RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; } - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + sizeof(EXT2_BOOTSECTOR), + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + // RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return Status; + } + +#if 0 + /* Adjust bootsector (copy a part of the FAT32 BPB) */ + memcpy(&NewBootSector->OemName, + &OrigBootSector->OemName, + FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - + FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); + + NewBootSector->HiddenSectors = PartitionList->CurrentDisk->SectorsPerTrack; + + /* Get the location of the backup boot sector */ + BackupBootSector = OrigBootSector->BackupBootSector; + + /* Free the original boot sector */ + // RtlFreeHeap(ProcessHeap, 0, OrigBootSector); +#endif + + /* Write new bootsector to RootPath */ + RtlInitUnicodeString(&Name, RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return Status; + } + + /* Write sector 0 */ + FileOffset.QuadPart = 0ULL; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + sizeof(EXT2_BOOTSECTOR), + &FileOffset, + NULL); +#if 0 + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return Status; + } + + /* Write backup boot sector */ + if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF)) + { + FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE); + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return Status; + } + } + + /* Write sector 14 */ + FileOffset.QuadPart = 14 * SECTORSIZE; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + ((PUCHAR)NewBootSector + SECTORSIZE), + SECTORSIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); + } +#endif + NtClose(FileHandle); + + /* Free the new boot sector */ + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + + return Status; +} + +static +NTSTATUS +UnprotectBootIni( + PWSTR FileName, + PULONG Attributes) +{ + NTSTATUS Status; + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileInfo; + HANDLE FileHandle; + + RtlInitUnicodeString(&Name, FileName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + if (Status == STATUS_NO_SUCH_FILE) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + *Attributes = 0; + return STATUS_SUCCESS; + } + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + return Status; + } + + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, &FileInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); @@ -1861,7 +2099,13 @@ ProtectBootIni( return Status; } - FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes; + *Attributes = FileInfo.FileAttributes; + + /* Delete attributes SYSTEM, HIDDEN and READONLY */ + FileInfo.FileAttributes = FileInfo.FileAttributes & + ~(FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY); Status = NtSetInformationFile(FileHandle, &IoStatusBlock, @@ -1877,16 +2121,77 @@ ProtectBootIni( return Status; } +static +NTSTATUS +ProtectBootIni( + PWSTR FileName, + ULONG Attributes) +{ + NTSTATUS Status; + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileInfo; + HANDLE FileHandle; + + RtlInitUnicodeString(&Name, FileName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + return Status; + } + + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return Status; + } + FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes; + + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandle); + return Status; +} + +static NTSTATUS UpdateBootIni( PWSTR BootIniPath, PWSTR EntryName, PWSTR EntryValue) { + NTSTATUS Status; PINICACHE Cache = NULL; PINICACHESECTION Section = NULL; - NTSTATUS Status; ULONG FileAttribute; PWCHAR OldValue = NULL; @@ -1940,28 +2245,7 @@ UpdateBootIni( return Status; } - -BOOLEAN -CheckInstallFatBootcodeToPartition( - PUNICODE_STRING SystemRootPath) -{ -#ifdef __REACTOS__ - if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") || - DoesFileExist(SystemRootPath->Buffer, L"boot.ini")) - { - return TRUE; - } - else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") || - DoesFileExist(SystemRootPath->Buffer, L"msdos.sys")) - { - return TRUE; - } -#endif - - return FALSE; -} - - +static NTSTATUS InstallFatBootcodeToPartition( PUNICODE_STRING SystemRootPath, @@ -1970,62 +2254,83 @@ InstallFatBootcodeToPartition( UCHAR PartitionType) { #ifdef __REACTOS__ + NTSTATUS Status; + BOOLEAN DoesFreeLdrExist; WCHAR SrcPath[MAX_PATH]; WCHAR DstPath[MAX_PATH]; - NTSTATUS Status; /* FAT or FAT32 partition */ DPRINT("System path: '%wZ'\n", SystemRootPath); - if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE || - DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE) + /* Copy FreeLoader to the boot partition */ + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\freeldr.sys"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.sys"); + + DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = SetupCopyFile(SrcPath, DstPath); + if (!NT_SUCCESS(Status)) { - /* Search root directory for 'ntldr' and 'boot.ini'. */ - DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n"); + DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + return Status; + } - /* Copy FreeLoader to the boot partition */ - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\freeldr.sys"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.sys"); + /* Prepare for possibly copying 'freeldr.ini' */ + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.ini"); - DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); - Status = SetupCopyFile(SrcPath, DstPath); + DoesFreeLdrExist = DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini"); + if (DoesFreeLdrExist) + { + /* Update existing 'freeldr.ini' */ + DPRINT1("Update existing 'freeldr.ini'\n"); + + Status = UpdateFreeLoaderIni(DstPath, DestinationArcPath->Buffer); if (!NT_SUCCESS(Status)) { - DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); return Status; } + } - /* Create or update freeldr.ini */ - if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) + /* Check for NT and other bootloaders */ + + // FIXME: Check for Vista+ bootloader! + if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE || + DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE) + { + /* Search root directory for 'ntldr' and 'boot.ini' */ + DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n"); + + /* Create or update 'freeldr.ini' */ + if (DoesFreeLdrExist == FALSE) { /* Create new 'freeldr.ini' */ DPRINT1("Create new 'freeldr.ini'\n"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); + // wcscpy(DstPath, SystemRootPath->Buffer); + // wcscat(DstPath, L"\\freeldr.ini"); - Status = CreateFreeLoaderIniForReactOS(DstPath, - DestinationArcPath->Buffer); + Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status); return Status; } - /* Install new bootcode */ + /* Install new bootcode into a file */ + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\bootsect.ros"); + if (PartitionType == PARTITION_FAT32 || PartitionType == PARTITION_FAT32_XINT13) { /* Install FAT32 bootcode */ wcscpy(SrcPath, SourceRootPath->Buffer); wcscat(SrcPath, L"\\loader\\fat32.bin"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\bootsect.ros"); DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath); - Status = InstallFat32BootCodeToFile(SrcPath, - DstPath, + Status = InstallFat32BootCodeToFile(SrcPath, DstPath, SystemRootPath->Buffer); if (!NT_SUCCESS(Status)) { @@ -2038,12 +2343,9 @@ InstallFatBootcodeToPartition( /* Install FAT16 bootcode */ wcscpy(SrcPath, SourceRootPath->Buffer); wcscat(SrcPath, L"\\loader\\fat.bin"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\bootsect.ros"); DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath); - Status = InstallFat16BootCodeToFile(SrcPath, - DstPath, + Status = InstallFat16BootCodeToFile(SrcPath, DstPath, SystemRootPath->Buffer); if (!NT_SUCCESS(Status)) { @@ -2052,21 +2354,6 @@ InstallFatBootcodeToPartition( } } } - else - { - /* Update existing 'freeldr.ini' */ - DPRINT1("Update existing 'freeldr.ini'\n"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); - - Status = UpdateFreeLoaderIni(DstPath, - DestinationArcPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); - return Status; - } - } /* Update 'boot.ini' */ wcscpy(DstPath, SystemRootPath->Buffer); @@ -2082,66 +2369,111 @@ InstallFatBootcodeToPartition( return Status; } } - else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") == TRUE || - DoesFileExist(SystemRootPath->Buffer, L"msdos.sys") == TRUE) + else { - /* Search for root directory for 'io.sys' and 'msdos.sys'. */ - DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n"); + /* Non-NT bootloaders: install our own bootloader */ - /* Copy FreeLoader to the boot partition */ - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\freeldr.sys"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.sys"); + PWCHAR Section; + PWCHAR Description; + PWCHAR BootDrive; + PWCHAR BootPartition; + PWCHAR BootSector; + PWCHAR BootSectorFileName; - DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); - Status = SetupCopyFile(SrcPath, DstPath); - if (!NT_SUCCESS(Status)) + if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") == TRUE || + DoesFileExist(SystemRootPath->Buffer, L"msdos.sys") == TRUE) { - DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); - return Status; + /* Search for root directory for 'io.sys' and 'msdos.sys' */ + DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n"); + + Section = L"DOS"; + Description = L"\"DOS/Windows\""; + BootDrive = L"hd0"; + BootPartition = L"1"; + BootSector = L"BOOTSECT.DOS"; + + BootSectorFileName = L"\\bootsect.dos"; + } + else + if (DoesFileExist(SystemRootPath->Buffer, L"kernel.sys") == TRUE) + { + /* Search for root directory for 'kernel.sys' */ + DPRINT1("Found FreeDOS boot loader\n"); + + Section = L"DOS"; + Description = L"\"FreeDOS\""; + BootDrive = L"hd0"; + BootPartition = L"1"; + BootSector = L"BOOTSECT.DOS"; + + BootSectorFileName = L"\\bootsect.dos"; + } + else + { + /* No or unknown boot loader */ + DPRINT1("No or unknown boot loader found\n"); + + Section = L"Unknown"; + Description = L"\"Unknown Operating System\""; + BootDrive = L"hd0"; + BootPartition = L"1"; + BootSector = L"BOOTSECT.OLD"; + + BootSectorFileName = L"\\bootsect.old"; } /* Create or update 'freeldr.ini' */ - if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) + if (DoesFreeLdrExist == FALSE) { /* Create new 'freeldr.ini' */ DPRINT1("Create new 'freeldr.ini'\n"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); + // wcscpy(DstPath, SystemRootPath->Buffer); + // wcscat(DstPath, L"\\freeldr.ini"); - Status = CreateFreeLoaderIniForDos(DstPath, - DestinationArcPath->Buffer); - if (!NT_SUCCESS(Status)) + if (IsThereAValidBootSector(SystemRootPath->Buffer)) { - DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status); - return Status; - } + Status = CreateFreeLoaderIniForReactOSAndBootSector( + DstPath, DestinationArcPath->Buffer, + Section, Description, + BootDrive, BootPartition, BootSector); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status); + return Status; + } - /* Save current bootsector as 'BOOTSECT.DOS' */ - wcscpy(SrcPath, SystemRootPath->Buffer); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\bootsect.dos"); + /* Save current bootsector */ + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, BootSectorFileName); - DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath); - Status = SaveCurrentBootSector(SrcPath, - DstPath); - if (!NT_SUCCESS(Status)) + DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath); + Status = SaveCurrentBootSector(SystemRootPath->Buffer, DstPath, SECTORSIZE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); + return Status; + } + } + else { - DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); - return Status; + Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status); + return Status; + } } - /* Install new bootsector */ + /* Install new bootsector on the disk */ if (PartitionType == PARTITION_FAT32 || PartitionType == PARTITION_FAT32_XINT13) { + /* Install FAT32 bootcode */ wcscpy(SrcPath, SourceRootPath->Buffer); wcscat(SrcPath, L"\\loader\\fat32.bin"); DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); - Status = InstallFat32BootCodeToDisk(SrcPath, - SystemRootPath->Buffer); + Status = InstallFat32BootCodeToDisk(SrcPath, SystemRootPath->Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); @@ -2150,12 +2482,12 @@ InstallFatBootcodeToPartition( } else { + /* Install FAT16 bootcode */ wcscpy(SrcPath, SourceRootPath->Buffer); wcscat(SrcPath, L"\\loader\\fat.bin"); - DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); - Status = InstallFat16BootCodeToDisk(SrcPath, - SystemRootPath->Buffer); + DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); + Status = InstallFat16BootCodeToDisk(SrcPath, SystemRootPath->Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); @@ -2163,111 +2495,122 @@ InstallFatBootcodeToPartition( } } } - else - { - /* Update existing 'freeldr.ini' */ - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); - - Status = UpdateFreeLoaderIni(DstPath, DestinationArcPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); - return Status; - } - } } - else + + return STATUS_SUCCESS; +#else + return STATUS_NOT_IMPLEMENTED; +#endif +} + +static +NTSTATUS +InstallExt2BootcodeToPartition( + PUNICODE_STRING SystemRootPath, + PUNICODE_STRING SourceRootPath, + PUNICODE_STRING DestinationArcPath, + UCHAR PartitionType) +{ +#ifdef __REACTOS__ + NTSTATUS Status; + BOOLEAN DoesFreeLdrExist; + WCHAR SrcPath[MAX_PATH]; + WCHAR DstPath[MAX_PATH]; + + /* EXT2 partition */ + DPRINT("System path: '%wZ'\n", SystemRootPath); + + /* Copy FreeLoader to the boot partition */ + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\freeldr.sys"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.sys"); + + DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); + Status = SetupCopyFile(SrcPath, DstPath); + if (!NT_SUCCESS(Status)) { - /* No or unknown boot loader */ - DPRINT1("No or unknown boot loader found\n"); + DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + return Status; + } - /* Copy FreeLoader to the boot partition */ - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\freeldr.sys"); - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.sys"); + /* Prepare for possibly copying 'freeldr.ini' */ + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.ini"); - DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); - Status = SetupCopyFile(SrcPath, DstPath); + DoesFreeLdrExist = DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini"); + if (DoesFreeLdrExist) + { + /* Update existing 'freeldr.ini' */ + DPRINT1("Update existing 'freeldr.ini'\n"); + + Status = UpdateFreeLoaderIni(DstPath, DestinationArcPath->Buffer); if (!NT_SUCCESS(Status)) { - DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); + DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); return Status; } + } - /* Create or update 'freeldr.ini' */ - if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) - { - /* Create new freeldr.ini */ - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); + /* Check for *nix bootloaders */ + + /* Create or update 'freeldr.ini' */ + if (DoesFreeLdrExist == FALSE) + { + /* Create new 'freeldr.ini' */ + DPRINT1("Create new 'freeldr.ini'\n"); + wcscpy(DstPath, SystemRootPath->Buffer); + wcscat(DstPath, L"\\freeldr.ini"); + + /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */ + DPRINT1("*nix or unknown boot loader found\n"); - DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); - Status = CreateFreeLoaderIniForReactOS(DstPath, - DestinationArcPath->Buffer); + if (IsThereAValidBootSector(SystemRootPath->Buffer)) + { + Status = CreateFreeLoaderIniForReactOSAndBootSector( + DstPath, DestinationArcPath->Buffer, + L"Linux", L"\"Linux\"", + L"hd0", L"1", L"BOOTSECT.OLD"); if (!NT_SUCCESS(Status)) { - DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status); + DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status); return Status; } - /* Save current bootsector as 'BOOTSECT.OLD' */ - wcscpy(SrcPath, SystemRootPath->Buffer); + /* Save current bootsector */ wcscpy(DstPath, SystemRootPath->Buffer); wcscat(DstPath, L"\\bootsect.old"); - DPRINT("Save bootsector: %S ==> %S\n", SrcPath, DstPath); - Status = SaveCurrentBootSector(SrcPath, - DstPath); + DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath); + Status = SaveCurrentBootSector(SystemRootPath->Buffer, DstPath, sizeof(EXT2_BOOTSECTOR)); if (!NT_SUCCESS(Status)) { DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); return Status; } - - /* Install new bootsector */ - if ((PartitionType == PARTITION_FAT32) || - (PartitionType == PARTITION_FAT32_XINT13)) - { - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\fat32.bin"); - - DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); - Status = InstallFat32BootCodeToDisk(SrcPath, - SystemRootPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); - return Status; - } - } - else + } + else + { + Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer); + if (!NT_SUCCESS(Status)) { - wcscpy(SrcPath, SourceRootPath->Buffer); - wcscat(SrcPath, L"\\loader\\fat.bin"); - - DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); - Status = InstallFat16BootCodeToDisk(SrcPath, - SystemRootPath->Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); - return Status; - } + DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status); + return Status; } } - else + + /* Install new bootsector on the disk */ + // if (PartitionType == PARTITION_EXT2) { - /* Update existing 'freeldr.ini' */ - wcscpy(DstPath, SystemRootPath->Buffer); - wcscat(DstPath, L"\\freeldr.ini"); + /* Install EXT2 bootcode */ + wcscpy(SrcPath, SourceRootPath->Buffer); + wcscat(SrcPath, L"\\loader\\ext2.bin"); - Status = UpdateFreeLoaderIni(DstPath, - DestinationArcPath->Buffer); + DPRINT1("Install EXT2 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); + Status = InstallExt2BootCodeToDisk(SrcPath, SystemRootPath->Buffer); if (!NT_SUCCESS(Status)) { - DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); + DPRINT1("InstallExt2BootCodeToDisk() failed (Status %lx)\n", Status); return Status; } } @@ -2287,17 +2630,35 @@ InstallVBRToPartition( PUNICODE_STRING DestinationArcPath, UCHAR PartitionType) { - if ((PartitionType == PARTITION_FAT_12) || - (PartitionType == PARTITION_FAT_16) || - (PartitionType == PARTITION_HUGE) || - (PartitionType == PARTITION_XINT13) || - (PartitionType == PARTITION_FAT32) || - (PartitionType == PARTITION_FAT32_XINT13)) - { - return InstallFatBootcodeToPartition(SystemRootPath, - SourceRootPath, - DestinationArcPath, - PartitionType); + switch (PartitionType) + { + case PARTITION_FAT_12: + case PARTITION_FAT_16: + case PARTITION_HUGE: + case PARTITION_XINT13: + case PARTITION_FAT32: + case PARTITION_FAT32_XINT13: + { + return InstallFatBootcodeToPartition(SystemRootPath, + SourceRootPath, + DestinationArcPath, + PartitionType); + } + + case PARTITION_EXT2: + { + return InstallExt2BootcodeToPartition(SystemRootPath, + SourceRootPath, + DestinationArcPath, + PartitionType); + } + + case PARTITION_IFS: + break; + + default: + DPRINT1("PartitionType 0x%02x unknown!\n", PartitionType); + break; } return STATUS_UNSUCCESSFUL; @@ -2310,10 +2671,10 @@ InstallFatBootcodeToFloppy( PUNICODE_STRING DestinationArcPath) { #ifdef __REACTOS__ + NTSTATUS Status; UNICODE_STRING FloppyDevice = RTL_CONSTANT_STRING(L"\\Device\\Floppy0"); WCHAR SrcPath[MAX_PATH]; WCHAR DstPath[MAX_PATH]; - NTSTATUS Status; /* Format the floppy first */ Status = VfatFormat(&FloppyDevice, diff --git a/reactos/base/setup/usetup/bootsup.h b/reactos/base/setup/usetup/bootsup.h index 2014f402300..9f0dc5c1ecb 100644 --- a/reactos/base/setup/usetup/bootsup.h +++ b/reactos/base/setup/usetup/bootsup.h @@ -26,70 +26,11 @@ #pragma once -NTSTATUS -CreateFreeLoaderIniForDos( - PWCHAR IniPath, - PWCHAR ArcPath); - -NTSTATUS -CreateFreeLoaderIniForReactOS( - PWCHAR IniPath, - PWCHAR ArcPath); - -NTSTATUS -UpdateFreeLoaderIni( - PWCHAR IniPath, - PWCHAR ArcPath); - -NTSTATUS -SaveCurrentBootSector( - PWSTR RootPath, - PWSTR DstPath); - -NTSTATUS -InstallFat16BootCodeToFile( - PWSTR SrcPath, - PWSTR DstPath, - PWSTR RootPath); - -NTSTATUS -InstallFat32BootCodeToFile( - PWSTR SrcPath, - PWSTR DstPath, - PWSTR RootPath); - NTSTATUS InstallMbrBootCodeToDisk( PWSTR SrcPath, PWSTR RootPath); -NTSTATUS -InstallFat16BootCodeToDisk( - PWSTR SrcPath, - PWSTR RootPath); - -NTSTATUS -InstallFat32BootCodeToDisk( - PWSTR SrcPath, - PWSTR RootPath); - -NTSTATUS -UpdateBootIni( - PWSTR BootIniPath, - PWSTR EntryName, - PWSTR EntryValue); - -BOOLEAN -CheckInstallFatBootcodeToPartition( - PUNICODE_STRING SystemRootPath); - -NTSTATUS -InstallFatBootcodeToPartition( - PUNICODE_STRING SystemRootPath, - PUNICODE_STRING SourceRootPath, - PUNICODE_STRING DestinationArcPath, - UCHAR PartitionType); - NTSTATUS InstallVBRToPartition( PUNICODE_STRING SystemRootPath, diff --git a/reactos/base/setup/usetup/filesup.c b/reactos/base/setup/usetup/filesup.c index 496149bfee5..bed30c418d6 100644 --- a/reactos/base/setup/usetup/filesup.c +++ b/reactos/base/setup/usetup/filesup.c @@ -354,7 +354,7 @@ SetupCopyFile( RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart); IoStatusBlock.Status = 0; - ByteOffset.QuadPart = 0; + ByteOffset.QuadPart = 0ULL; Status = NtWriteFile(FileHandleDest, NULL, NULL, diff --git a/reactos/base/setup/usetup/interface/usetup.c b/reactos/base/setup/usetup/interface/usetup.c index 5779db7e7ac..491b909c017 100644 --- a/reactos/base/setup/usetup/interface/usetup.c +++ b/reactos/base/setup/usetup/interface/usetup.c @@ -2951,6 +2951,14 @@ FormatPartitionPage(PINPUT_RECORD Ir) { PartEntry->PartitionType = PARTITION_EXT2; + DiskEntry->Dirty = TRUE; + DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType; + DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE; + } + else if (wcscmp(PartEntry->FileSystem->FileSystemName, L"NTFS") == 0) + { + PartEntry->PartitionType = PARTITION_IFS; + DiskEntry->Dirty = TRUE; DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType; DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE; @@ -3149,7 +3157,6 @@ CheckFileSystemPage(PINPUT_RECORD Ir) DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status); sprintf(Buffer, "Setup failed to verify the selected partition.\n" "(Status 0x%08lx).\n", Status); - PopupError(Buffer, MUIGetString(STRING_REBOOTCOMPUTER), Ir, POPUP_WAIT_ENTER); @@ -3986,7 +3993,6 @@ RegistryPage(PINPUT_RECORD Ir) } /* Create the default hives */ -#ifdef __REACTOS__ Status = NtInitializeRegistry(CM_BOOT_FLAG_SETUP); if (!NT_SUCCESS(Status)) { @@ -3994,9 +4000,6 @@ RegistryPage(PINPUT_RECORD Ir) MUIDisplayError(ERROR_CREATE_HIVE, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } -#else - RegInitializeRegistry(); -#endif /* Update registry */ CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE)); @@ -4165,22 +4168,24 @@ BootLoaderPage(PINPUT_RECORD Ir) DPRINT("Error: active partition invalid (unused)\n"); InstallOnFloppy = TRUE; } - else if (PartitionType == 0x0A) + else if (PartitionType == PARTITION_OS2BOOTMGR) { /* OS/2 boot manager partition */ DPRINT("Found OS/2 boot manager partition\n"); InstallOnFloppy = TRUE; } - else if (PartitionType == 0x83) + else if (PartitionType == PARTITION_EXT2) { /* Linux ext2 partition */ DPRINT("Found Linux ext2 partition\n"); - InstallOnFloppy = TRUE; + InstallOnFloppy = FALSE; } else if (PartitionType == PARTITION_IFS) { /* NTFS partition */ DPRINT("Found NTFS partition\n"); + + // FIXME: Make it FALSE when we'll support NTFS installation! InstallOnFloppy = TRUE; } else if ((PartitionType == PARTITION_FAT_12) || diff --git a/reactos/base/setup/usetup/native/fslist.c b/reactos/base/setup/usetup/native/fslist.c index d00a7c91368..4d9b655936b 100644 --- a/reactos/base/setup/usetup/native/fslist.c +++ b/reactos/base/setup/usetup/native/fslist.c @@ -7,6 +7,7 @@ NATIVE_CreateFileSystemList( FS_AddProvider(List, L"FAT", VfatFormat, VfatChkdsk); #if 0 FS_AddProvider(List, L"EXT2", Ext2Format, Ext2Chkdsk); + FS_AddProvider(List, L"NTFS", NtfsFormat, NtfsChkdsk); #endif return TRUE; } diff --git a/reactos/base/setup/usetup/partlist.h b/reactos/base/setup/usetup/partlist.h index f6db531da47..049e2f75757 100644 --- a/reactos/base/setup/usetup/partlist.h +++ b/reactos/base/setup/usetup/partlist.h @@ -25,9 +25,6 @@ #pragma once -/* We have to define it there, because it is not in the MS DDK */ -#define PARTITION_EXT2 0x83 - typedef enum _FORMATSTATE { Unformatted, diff --git a/reactos/base/setup/usetup/usetup.h b/reactos/base/setup/usetup/usetup.h index c8fbb0a3425..7218bc79776 100644 --- a/reactos/base/setup/usetup/usetup.h +++ b/reactos/base/setup/usetup/usetup.h @@ -53,8 +53,10 @@ #include /* Filesystem headers */ -#include +#include #include +#include +// #include /* Internal Headers */ #include "interface/consup.h" -- 2.17.1