/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
- * FILE: subsys/system/usetup/bootsup.c
+ * FILE: base/setup/usetup/bootsup.c
* PURPOSE: Bootloader support functions
* PROGRAMMER: Eric Kohl
*/
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 <poppack.h>
extern PPARTLIST PartitionList;
PINICACHESECTION IniSection;
/* Create "FREELOADER" section */
- IniSection = IniCacheAppendSection(IniCache,
- L"FREELOADER");
+ IniSection = IniCacheAppendSection(IniCache, L"FREELOADER");
#if DBG
if (IsUnattendedSetup)
L"Seconds until highlighted choice will be started automatically: ");
}
-
-NTSTATUS
-CreateFreeLoaderIniForDos(
- PWCHAR IniPath,
- PWCHAR ArcPath)
-{
- PINICACHE IniCache;
- PINICACHESECTION IniSection;
-
- IniCache = IniCacheCreate();
-
- CreateCommonFreeLoaderSections(IniCache);
-
- /* Create "Operating Systems" section */
- IniSection = IniCacheAppendSection(IniCache, L"Operating Systems");
-
- /* REACTOS=ReactOS */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"ReactOS",
- L"\"ReactOS\"");
-
- /* ReactOS_Debug="ReactOS (Debug)" */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"ReactOS_Debug",
- L"\"ReactOS (Debug)\"");
-
- /* DOS=Dos/Windows */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"DOS",
- L"\"DOS/Windows\"");
-
- /* Create "ReactOS" section */
- IniSection = IniCacheAppendSection(IniCache, L"ReactOS");
-
- /* BootType=ReactOS */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootType",
- L"ReactOS");
-
- /* SystemPath=<ArcPath> */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"SystemPath",
- ArcPath);
-
- /* Create "ReactOS_Debug" section */
- IniSection = IniCacheAppendSection(IniCache, L"ReactOS_Debug");
-
- /* BootType=ReactOS */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootType",
- L"ReactOS");
-
- /* SystemPath=<ArcPath> */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"SystemPath",
- ArcPath);
-
- /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"Options",
- L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
-
- /* Create "DOS" section */
- IniSection = IniCacheAppendSection(IniCache,
- L"DOS");
-
- /* BootType=BootSector */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootType",
- L"BootSector");
-
- /* BootDrive=hd0 */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootDrive",
- L"hd0");
-
- /* BootPartition=1 */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootPartition",
- L"1");
-
- /* BootSector=BOOTSECT.DOS */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootSectorFile",
- L"BOOTSECT.DOS");
-
- IniCacheSave(IniCache, IniPath);
- IniCacheDestroy(IniCache);
-
- return STATUS_SUCCESS;
-}
-
-
+static
NTSTATUS
-CreateFreeLoaderEntry(
+CreateNTOSEntry(
PINICACHE IniCache,
PINICACHESECTION OSSection,
PWCHAR Section,
L"SystemPath",
ArcPath);
- /* Options=*/
+ /* Options= */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
return STATUS_SUCCESS;
}
-NTSTATUS
-CreateFreeLoaderIniForReactos(
- PWCHAR IniPath,
+static
+VOID
+CreateFreeLoaderReactOSEntries(
+ PINICACHE IniCache,
PWCHAR ArcPath)
{
- PINICACHE IniCache;
PINICACHESECTION IniSection;
- IniCache = IniCacheCreate();
-
- CreateCommonFreeLoaderSections(IniCache);
-
/* Create "Operating Systems" section */
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 */
+ 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 /RDIMAGEPATH=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,
+ PWCHAR ArcPath)
+{
+ PINICACHE IniCache;
- /* Save the ini file */
+ /* Initialize the INI file */
+ IniCache = IniCacheCreate();
+
+ /* Create the common FreeLdr sections */
+ CreateCommonFreeLoaderSections(IniCache);
+
+ /* Add the ReactOS entries */
+ CreateFreeLoaderReactOSEntries(IniCache, ArcPath);
+
+ /* Save the INI file */
IniCacheSave(IniCache, IniPath);
IniCacheDestroy(IniCache);
return STATUS_SUCCESS;
}
+static
+NTSTATUS
+CreateFreeLoaderIniForReactOSAndBootSector(
+ PWCHAR IniPath,
+ PWCHAR ArcPath,
+ PWCHAR Section,
+ PWCHAR Description,
+ PWCHAR BootDrive,
+ PWCHAR BootPartition,
+ PWCHAR BootSector)
+{
+ PINICACHE IniCache;
+ PINICACHESECTION IniSection;
+ /* Initialize the INI file */
+ IniCache = IniCacheCreate();
+
+ /* Create the common FreeLdr sections */
+ CreateCommonFreeLoaderSections(IniCache);
+
+ /* Add the ReactOS entries */
+ CreateFreeLoaderReactOSEntries(IniCache, ArcPath);
+
+ /* Get "Operating Systems" section */
+ IniSection = IniCacheGetSection(IniCache, L"Operating Systems");
+
+ /* Insert entry into "Operating Systems" section */
+ IniCacheInsertKey(IniSection,
+ NULL,
+ INSERT_LAST,
+ Section,
+ Description);
+
+ /* Create new section */
+ IniSection = IniCacheAppendSection(IniCache, Section);
+
+ /* BootType=BootSector */
+ IniCacheInsertKey(IniSection,
+ NULL,
+ INSERT_LAST,
+ L"BootType",
+ L"BootSector");
+
+ /* BootDrive= */
+ IniCacheInsertKey(IniSection,
+ NULL,
+ INSERT_LAST,
+ L"BootDrive",
+ BootDrive);
+
+ /* BootPartition= */
+ IniCacheInsertKey(IniSection,
+ NULL,
+ INSERT_LAST,
+ L"BootPartition",
+ BootPartition);
+
+ /* BootSector= */
+ IniCacheInsertKey(IniSection,
+ NULL,
+ INSERT_LAST,
+ L"BootSectorFile",
+ BootSector);
+
+ /* Save the INI file */
+ IniCacheSave(IniCache, IniPath);
+ IniCacheDestroy(IniCache);
+
+ return STATUS_SUCCESS;
+}
+
+static
NTSTATUS
UpdateFreeLoaderIni(
PWCHAR IniPath,
PWCHAR ArcPath)
{
- UNICODE_STRING Name;
+ NTSTATUS Status;
PINICACHE IniCache;
PINICACHESECTION IniSection;
PINICACHESECTION OsIniSection;
WCHAR SectionName2[200];
PWCHAR KeyData;
ULONG i,j;
- NTSTATUS Status;
-
- RtlInitUnicodeString(&Name, IniPath);
- Status = IniCacheLoad(&IniCache, &Name, FALSE);
+ Status = IniCacheLoad(&IniCache, IniPath, FALSE);
if (!NT_SUCCESS(Status))
return Status;
wcscpy(SectionName2, KeyData);
}
+ /* Search for an existing ReactOS entry */
OsIniSection = IniCacheGetSection(IniCache, SectionName2);
if (OsIniSection != NULL)
{
BOOLEAN UseExistingEntry = TRUE;
- /* Check BootType */
+ /* Check for boot type "Windows2003" */
Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData);
if (NT_SUCCESS(Status))
{
if ((KeyData == NULL) ||
- ( (_wcsicmp(KeyData, L"ReactOS") != 0) &&
- (_wcsicmp(KeyData, L"\"ReactOS\"") != 0) ))
+ ( (_wcsicmp(KeyData, L"Windows2003") != 0) &&
+ (_wcsicmp(KeyData, L"\"Windows2003\"") != 0) ))
{
/* This is not a ReactOS entry */
UseExistingEntry = FALSE;
if (UseExistingEntry)
{
- /* BootType is ReactOS. Now check SystemPath */
+ /* BootType is Windows2003. Now check SystemPath. */
Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData);
if (NT_SUCCESS(Status))
{
- swprintf(SystemPath, L"\"%S\"", ArcPath);
+ swprintf(SystemPath, L"\"%s\"", ArcPath);
if ((KeyData == NULL) ||
- ((_wcsicmp(KeyData, ArcPath) != 0) &&
- (_wcsicmp(KeyData, SystemPath) != 0) ))
+ ( (_wcsicmp(KeyData, ArcPath) != 0) &&
+ (_wcsicmp(KeyData, SystemPath) != 0) ))
{
- /* This entry is a ReactOS entry, but the SystemRoot does not
- match the one we are looking for */
+ /* This entry is a ReactOS entry, but the SystemRoot
+ does not match the one we are looking for. */
UseExistingEntry = FALSE;
}
}
i++;
}
- /* <SectionName>=<OsName> */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- SectionName,
- OsName);
-
- /* Create <SectionName> section */
- IniSection = IniCacheAppendSection(IniCache, SectionName);
-
- /* BootType=ReactOS */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootType",
- L"ReactOS");
-
- /* SystemPath=<ArcPath> */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"SystemPath",
- ArcPath);
+ /* Create a new "ReactOS" entry */
+ CreateNTOSEntry(IniCache, IniSection,
+ SectionName, OsName,
+ L"Windows2003", ArcPath,
+ L"");
IniCacheSave(IniCache, IniPath);
IniCacheDestroy(IniCache);
return STATUS_SUCCESS;
}
+BOOLEAN
+IsThereAValidBootSector(PWSTR RootPath)
+{
+ /*
+ * We first demand that the bootsector has a valid signature at its end.
+ * We then check the first 3 bytes (as a ULONG) of the bootsector for a
+ * potential "valid" instruction (the BIOS starts execution of the bootsector
+ * at its beginning). Currently this criterium is that this ULONG must be
+ * non-zero. If both these tests pass, then the bootsector is valid; otherwise
+ * it is invalid and certainly needs to be overwritten.
+ */
+ BOOLEAN IsValid = FALSE;
+ 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))
+ goto Quit;
+
+ RtlZeroMemory(BootSector, SECTORSIZE);
+
+ FileOffset.QuadPart = 0ULL;
+ Status = NtReadFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ BootSector,
+ SECTORSIZE,
+ &FileOffset,
+ NULL);
+ NtClose(FileHandle);
+ if (!NT_SUCCESS(Status))
+ goto Quit;
+
+ /* Check the instruction; we use a ULONG to read three bytes */
+ Instruction = (*(PULONG)BootSector) & 0x00FFFFFF;
+ IsValid = (Instruction != 0x00000000);
+
+ /* Check the bootsector signature */
+ IsValid &= (*(PUSHORT)(BootSector + 0x1fe) == 0xaa55);
+
+Quit:
+ /* Free the boot sector */
+ RtlFreeHeap(ProcessHeap, 0, BootSector);
+ return IsValid; // Status;
+}
NTSTATUS
-SaveCurrentBootSector(
+SaveBootSector(
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;
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
BootSector,
- SECTORSIZE,
- NULL,
+ Length,
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
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);
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
&IoStatusBlock,
OrigBootSector,
SECTORSIZE,
- NULL,
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
SECTORSIZE,
- NULL,
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
return Status;
}
-#if 0
- FilePosition.QuadPart = 0;
-#endif
+ FileOffset.QuadPart = 0ULL;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
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);
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
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;
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
OrigBootSector,
- SECTORSIZE,
- NULL,
+ sizeof(PARTITION_SECTOR),
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
}
/* Copy partition table from old MBR to new */
- RtlCopyMemory (&NewBootSector->Signature,
- &OrigBootSector->Signature,
- sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */);
+ RtlCopyMemory(&NewBootSector->Signature,
+ &OrigBootSector->Signature,
+ sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */);
/* Free the original boot sector */
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
- SECTORSIZE,
- NULL,
+ sizeof(PARTITION_SECTOR),
+ &FileOffset,
NULL);
NtClose(FileHandle);
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;
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
&IoStatusBlock,
OrigBootSector,
SECTORSIZE,
- NULL,
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
return Status;
}
-#if 0
- FilePosition.QuadPart = 0;
-#endif
+ FileOffset.QuadPart = 0ULL;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
SECTORSIZE,
- NULL,
+ &FileOffset,
NULL);
NtClose(FileHandle);
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;
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
&IoStatusBlock,
OrigBootSector,
SECTORSIZE,
- NULL,
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
}
/* Allocate buffer for new bootsector */
- NewBootSector = RtlAllocateHeap(ProcessHeap,
- 0,
- SECTORSIZE);
+ NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
if (NewBootSector == NULL)
{
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
FIELD_OFFSET(FAT_BOOTSECTOR, OemName));
- NewBootSector->HiddenSectors = PartitionList->CurrentDisk->SectorsPerTrack;
-
/* Free the original boot sector */
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return Status;
}
-#if 0
- FilePosition.QuadPart = 0;
-#endif
+ FileOffset.QuadPart = 0ULL;
+ Status = NtWriteFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ NewBootSector,
+ SECTORSIZE,
+ &FileOffset,
+ NULL);
+ NtClose(FileHandle);
+
+ /* Free the new boot sector */
+ RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+
+ return Status;
+}
+
+static
+NTSTATUS
+InstallFat32BootCodeToDisk(
+ PWSTR SrcPath,
+ PWSTR RootPath)
+{
+ NTSTATUS Status;
+ UNICODE_STRING Name;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE FileHandle;
+ LARGE_INTEGER FileOffset;
+ PFAT32_BOOTSECTOR OrigBootSector;
+ PFAT32_BOOTSECTOR NewBootSector;
+ USHORT BackupBootSector;
+
+ /* 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,
+ 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, OrigBootSector);
+ return Status;
+ }
+
+ FileOffset.QuadPart = 0ULL;
+ Status = NtReadFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ OrigBootSector,
+ SECTORSIZE,
+ &FileOffset,
+ NULL);
+ NtClose(FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+ return Status;
+ }
+
+
+ /* Allocate buffer for new bootsector (2 sectors) */
+ NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * 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,
+ GENERIC_READ | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ 0,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+ RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+ return Status;
+ }
+
+ Status = NtReadFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ NewBootSector,
+ 2 * SECTORSIZE,
+ NULL,
+ NULL);
+ NtClose(FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+ RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+ return Status;
+ }
+
+ /* Adjust bootsector (copy a part of the FAT32 BPB) */
+ memcpy(&NewBootSector->OemName,
+ &OrigBootSector->OemName,
+ FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
+ FIELD_OFFSET(FAT32_BOOTSECTOR, OemName));
+
+ /* Get the location of the backup boot sector */
+ BackupBootSector = OrigBootSector->BackupBootSector;
+
+ /* Free the original boot sector */
+ RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+
+ /* Write the first sector of the new bootcode to DstPath */
+ 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,
+ SECTORSIZE,
+ &FileOffset,
+ NULL);
+ 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,
- NewBootSector,
+ ((PUCHAR)NewBootSector + SECTORSIZE),
SECTORSIZE,
- NULL,
+ &FileOffset,
NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
+ }
NtClose(FileHandle);
/* Free the new boot sector */
return Status;
}
-
+static
NTSTATUS
-InstallFat32BootCodeToDisk(
+InstallExt2BootCodeToDisk(
PWSTR SrcPath,
PWSTR RootPath)
{
+ NTSTATUS Status;
+ UNICODE_STRING Name;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
- UNICODE_STRING Name;
HANDLE FileHandle;
- NTSTATUS Status;
- PFAT32_BOOTSECTOR OrigBootSector;
- PFAT32_BOOTSECTOR NewBootSector;
LARGE_INTEGER FileOffset;
- USHORT BackupBootSector;
+// PEXT2_BOOTSECTOR OrigBootSector;
+ PEXT2_BOOTSECTOR NewBootSector;
+ // USHORT BackupBootSector;
+#if 0
/* Allocate buffer for original bootsector */
OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
if (OrigBootSector == NULL)
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
&IoStatusBlock,
OrigBootSector,
SECTORSIZE,
- NULL,
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return Status;
}
+#endif
-
- /* Allocate buffer for new bootsector (2 sectors) */
- NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE);
+ /* Allocate buffer for new bootsector */
+ NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(EXT2_BOOTSECTOR));
if (NewBootSector == NULL)
{
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+ // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return STATUS_INSUFFICIENT_RESOURCES;
}
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+ // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
RtlFreeHeap(ProcessHeap, 0, NewBootSector);
return Status;
}
NULL,
&IoStatusBlock,
NewBootSector,
- 2 * SECTORSIZE,
+ sizeof(EXT2_BOOTSECTOR),
NULL,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+ // 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,
BackupBootSector = OrigBootSector->BackupBootSector;
/* Free the original boot sector */
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+ // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+#endif
- /* Write the first sector of the new bootcode to DstPath */
+ /* Write new bootsector to RootPath */
RtlInitUnicodeString(&Name, RootPath);
InitializeObjectAttributes(&ObjectAttributes,
NULL,
&IoStatusBlock,
NewBootSector,
- SECTORSIZE,
+ sizeof(EXT2_BOOTSECTOR),
&FileOffset,
NULL);
+#if 0
if (!NT_SUCCESS(Status))
{
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
{
DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
}
+#endif
NtClose(FileHandle);
/* Free the new boot sector */
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;
- NTSTATUS Status;
RtlInitUnicodeString(&Name, FileName);
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;
- NTSTATUS Status;
RtlInitUnicodeString(&Name, FileName);
return Status;
}
-
+static
NTSTATUS
UpdateBootIni(
PWSTR BootIniPath,
PWSTR EntryName,
PWSTR EntryValue)
{
- UNICODE_STRING Name;
+ NTSTATUS Status;
PINICACHE Cache = NULL;
PINICACHESECTION Section = NULL;
- NTSTATUS Status;
ULONG FileAttribute;
PWCHAR OldValue = NULL;
- RtlInitUnicodeString(&Name, BootIniPath);
-
- Status = IniCacheLoad(&Cache, &Name, FALSE);
+ Status = IniCacheLoad(&Cache, BootIniPath, FALSE);
if (!NT_SUCCESS(Status))
{
return Status;
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,
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 system 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");
+
+ DoesFreeLdrExist = DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini");
+ if (DoesFreeLdrExist)
+ {
+ /* Update existing 'freeldr.ini' */
+ DPRINT1("Update existing 'freeldr.ini'\n");
- DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
- Status = SetupCopyFile(SrcPath, DstPath);
+ 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;
}
+ }
+
+ /* 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 (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)
+ /* 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);
+ 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)
+ 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))
{
/* 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))
{
}
}
}
- 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);
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 = SaveBootSector(SystemRootPath->Buffer, DstPath, SECTORSIZE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SaveBootSector() 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)
+ 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);
}
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);
}
}
}
- 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 system 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");
+
+ DoesFreeLdrExist = DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini");
+ if (DoesFreeLdrExist)
+ {
+ /* Update existing 'freeldr.ini' */
+ DPRINT1("Update existing 'freeldr.ini'\n");
- DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
- Status = SetupCopyFile(SrcPath, DstPath);
+ 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");
- DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
- Status = CreateFreeLoaderIniForReactos(DstPath,
- DestinationArcPath->Buffer);
+ /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
+ DPRINT1("*nix or unknown boot loader found\n");
+
+ 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 = SaveBootSector(SystemRootPath->Buffer, DstPath, sizeof(EXT2_BOOTSECTOR));
if (!NT_SUCCESS(Status))
{
- DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
+ DPRINT1("SaveBootSector() 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;
}
}
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;
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,
wcscpy(DstPath, L"\\Device\\Floppy0\\freeldr.ini");
DPRINT("Create new 'freeldr.ini'\n");
- Status = CreateFreeLoaderIniForReactos(DstPath, DestinationArcPath->Buffer);
+ Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
- DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
+ DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
return Status;
}