* PROJECT: ReactOS text-mode setup
* FILE: base/setup/usetup/bootsup.c
* PURPOSE: Bootloader support functions
- * PROGRAMMER:
+ * PROGRAMMERS: ...
+ * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
#include "usetup.h"
#define NDEBUG
#include <debug.h>
+/*
+ * BIG FIXME!!
+ * ===========
+ *
+ * All that stuff *MUST* go into the fsutil.c module.
+ * Indeed, all that relates to filesystem formatting details and as such
+ * *MUST* be abstracted out from this module (bootsup.c).
+ * However, bootsup.c can still deal with MBR code (actually it'll have
+ * at some point to share or give it to partlist.c, because when we'll
+ * support GPT disks, things will change a bit).
+ * And, bootsup.c can still manage initializing / adding boot entries
+ * into NTLDR and FREELDR, and installing the latter, and saving the old
+ * MBR / boot sectors in files.
+ */
#define SECTORSIZE 512
#include <pshpack1.h>
} FAT32_BOOTSECTOR, *PFAT32_BOOTSECTOR;
-typedef struct _EXT2_BOOTSECTOR
+typedef struct _BTRFS_BOOTSECTOR
{
- // The EXT2 bootsector is completely user-specific.
- // No FS data is stored there.
- UCHAR Fill[1024];
-} EXT2_BOOTSECTOR, *PEXT2_BOOTSECTOR;
+ UCHAR JumpBoot[3];
+ UCHAR ChunkMapSize;
+ UCHAR BootDrive;
+ ULONGLONG PartitionStartLBA;
+ UCHAR Fill[1521]; // 1536 - 15
+ USHORT BootSectorMagic;
+} BTRFS_BOOTSECTOR, *PBTRFS_BOOTSECTOR;
+C_ASSERT(sizeof(BTRFS_BOOTSECTOR) == 3 * 512);
// TODO: Add more bootsector structures!
#include <poppack.h>
-extern PPARTLIST PartitionList;
+/* End of BIG FIXME!! */
+
/* FUNCTIONS ****************************************************************/
+static VOID
+TrimTrailingPathSeparators_UStr(
+ IN OUT PUNICODE_STRING UnicodeString)
+{
+ while (UnicodeString->Length >= sizeof(WCHAR) &&
+ UnicodeString->Buffer[UnicodeString->Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
+ {
+ UnicodeString->Length -= sizeof(WCHAR);
+ }
+}
-static
-VOID
-CreateCommonFreeLoaderSections(
- PINICACHE IniCache)
+
+static VOID
+CreateFreeLoaderReactOSEntries(
+ IN PVOID BootStoreHandle,
+ IN PCWSTR ArcPath)
{
- PINICACHESECTION IniSection;
+ UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
+ PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
+ PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
+ BOOT_STORE_OPTIONS BootOptions;
+
+ BootEntry->Version = FreeLdr;
+ BootEntry->BootFilePath = NULL;
+
+ BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
+ RtlCopyMemory(Options->Signature,
+ NTOS_OPTIONS_SIGNATURE,
+ RTL_FIELD_SIZE(NTOS_OPTIONS, Signature));
+
+ Options->OsLoadPath = ArcPath;
+
+ /* ReactOS */
+ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS");
+ BootEntry->FriendlyName = L"\"ReactOS\"";
+ Options->OsLoadOptions = NULL; // L"";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS"));
+
+ /* ReactOS_Debug */
+ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
+ BootEntry->FriendlyName = L"\"ReactOS (Debug)\"";
+ Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Debug"));
+
+#ifdef _WINKD_
+ /* ReactOS_VBoxDebug */
+ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_VBoxDebug");
+ BootEntry->FriendlyName = L"\"ReactOS (VBoxDebug)\"";
+ Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=VBOX /SOS";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_VBoxDebug"));
+#endif
+#if DBG
+#ifndef _WINKD_
+ /* ReactOS_KdSerial */
+ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
+ BootEntry->FriendlyName = L"\"ReactOS (RosDbg)\"";
+ Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_KdSerial"));
+#endif
+
+ /* ReactOS_Screen */
+ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Screen");
+ BootEntry->FriendlyName = L"\"ReactOS (Screen)\"";
+ Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=SCREEN /SOS";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Screen"));
+
+ /* ReactOS_LogFile */
+ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_LogFile");
+ BootEntry->FriendlyName = L"\"ReactOS (Log file)\"";
+ Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=FILE /SOS";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_LogFile"));
+
+ /* ReactOS_Ram */
+ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Ram");
+ BootEntry->FriendlyName = L"\"ReactOS (RAM Disk)\"";
+ Options->OsLoadPath = L"ramdisk(0)\\ReactOS";
+ Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Ram"));
+
+ /* ReactOS_EMS */
+ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_EMS");
+ BootEntry->FriendlyName = L"\"ReactOS (Emergency Management Services)\"";
+ Options->OsLoadPath = ArcPath;
+ Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_EMS"));
+#endif
- /* Create "FREELOADER" section */
- IniSection = IniCacheAppendSection(IniCache, L"FREELOADER");
#if DBG
if (IsUnattendedSetup)
{
/* DefaultOS=ReactOS */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"DefaultOS",
#ifndef _WINKD_
- L"ReactOS_KdSerial");
+ BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
#else
- L"ReactOS_Debug");
+ BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
#endif
}
else
#endif
{
/* DefaultOS=ReactOS */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"DefaultOS",
- L"ReactOS");
+ BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS");
}
#if DBG
if (IsUnattendedSetup)
#endif
{
- /* Timeout=0 for unattended or non debug*/
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"TimeOut",
- L"0");
+ /* Timeout=0 for unattended or non debug */
+ BootOptions.Timeout = 0;
}
#if DBG
else
{
- /* Timeout=0 or 10 */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"TimeOut",
- L"10");
+ /* Timeout=10 */
+ BootOptions.Timeout = 10;
}
#endif
- /* Create "Display" section */
- IniSection = IniCacheAppendSection(IniCache, L"Display");
-
- /* TitleText=ReactOS Boot Manager */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"TitleText",
- L"ReactOS Boot Manager");
-
- /* StatusBarColor=Cyan */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"StatusBarColor",
- L"Cyan");
-
- /* StatusBarTextColor=Black */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"StatusBarTextColor",
- L"Black");
-
- /* BackdropTextColor=White */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BackdropTextColor",
- L"White");
-
- /* BackdropColor=Blue */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BackdropColor",
- L"Blue");
-
- /* BackdropFillStyle=Medium */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BackdropFillStyle",
- L"Medium");
-
- /* TitleBoxTextColor=White */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"TitleBoxTextColor",
- L"White");
-
- /* TitleBoxColor=Red */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"TitleBoxColor",
- L"Red");
-
- /* MessageBoxTextColor=White */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"MessageBoxTextColor",
- L"White");
-
- /* MessageBoxColor=Blue */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"MessageBoxColor",
- L"Blue");
-
- /* MenuTextColor=White */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"MenuTextColor",
- L"Gray");
-
- /* MenuColor=Blue */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"MenuColor",
- L"Black");
-
- /* TextColor=Yellow */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"TextColor",
- L"Gray");
-
- /* SelectedTextColor=Black */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"SelectedTextColor",
- L"Black");
-
- /* SelectedColor=Gray */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"SelectedColor",
- L"Gray");
-
- /* SelectedColor=Gray */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"ShowTime",
- L"No");
-
- /* SelectedColor=Gray */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"MenuBox",
- L"No");
-
- /* SelectedColor=Gray */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"CenterMenu",
- L"No");
-
- /* SelectedColor=Gray */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"MinimalUI",
- L"Yes");
-
- /* SelectedColor=Gray */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"TimeText",
- L"Seconds until highlighted choice will be started automatically: ");
+ BootOptions.Version = FreeLdr;
+ SetBootStoreOptions(BootStoreHandle, &BootOptions, 2 | 1);
}
-static
-NTSTATUS
-CreateNTOSEntry(
- PINICACHE IniCache,
- PINICACHESECTION OSSection,
- PWCHAR Section,
- PWCHAR Description,
- PWCHAR BootType,
- PWCHAR ArcPath,
- PWCHAR Options)
+static NTSTATUS
+CreateFreeLoaderIniForReactOS(
+ IN PCWSTR IniPath,
+ IN PCWSTR ArcPath)
{
- PINICACHESECTION IniSection;
-
- /* Insert entry into "Operating Systems" section */
- IniCacheInsertKey(OSSection,
- NULL,
- INSERT_LAST,
- Section,
- Description);
-
- /* Create new section */
- IniSection = IniCacheAppendSection(IniCache, Section);
-
- /* BootType= */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootType",
- BootType);
-
- /* SystemPath= */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"SystemPath",
- ArcPath);
-
- /* Options= */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"Options",
- Options);
+ NTSTATUS Status;
+ PVOID BootStoreHandle;
+
+ /* Initialize the INI file and create the common FreeLdr sections */
+ Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* Add the ReactOS entries */
+ CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
+ /* Close the INI file */
+ CloseBootStore(BootStoreHandle);
return STATUS_SUCCESS;
}
-static
-VOID
-CreateFreeLoaderReactOSEntries(
- PINICACHE IniCache,
- PWCHAR ArcPath)
+static NTSTATUS
+CreateFreeLoaderIniForReactOSAndBootSector(
+ IN PCWSTR IniPath,
+ IN PCWSTR ArcPath,
+ IN PCWSTR Section,
+ IN PCWSTR Description,
+ IN PCWSTR BootDrive,
+ IN PCWSTR BootPartition,
+ IN PCWSTR BootSector)
{
- PINICACHESECTION IniSection;
+ NTSTATUS Status;
+ PVOID BootStoreHandle;
+ UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(BOOT_SECTOR_OPTIONS)];
+ PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
+ PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions;
- /* Create "Operating Systems" section */
- IniSection = IniCacheAppendSection(IniCache, L"Operating Systems");
+ /* Initialize the INI file and create the common FreeLdr sections */
+ Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
+ if (!NT_SUCCESS(Status))
+ return Status;
- /* ReactOS */
- CreateNTOSEntry(IniCache, IniSection,
- L"ReactOS", L"\"ReactOS\"",
- L"Windows2003", ArcPath,
- L"");
+ /* Add the ReactOS entries */
+ CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
- /* ReactOS_Debug */
- 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 */
- CreateNTOSEntry(IniCache, IniSection,
- L"ReactOS_KdSerial", L"\"ReactOS (RosDbg)\"",
- L"Windows2003", ArcPath,
- L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
-#endif
+ BootEntry->Version = FreeLdr;
+ BootEntry->BootFilePath = NULL;
- /* ReactOS_Screen */
- CreateNTOSEntry(IniCache, IniSection,
- L"ReactOS_Screen", L"\"ReactOS (Screen)\"",
- L"Windows2003", ArcPath,
- L"/DEBUG /DEBUGPORT=SCREEN /SOS");
+ BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS);
+ RtlCopyMemory(Options->Signature,
+ BOOT_SECTOR_OPTIONS_SIGNATURE,
+ RTL_FIELD_SIZE(BOOT_SECTOR_OPTIONS, Signature));
- /* ReactOS_LogFile */
- CreateNTOSEntry(IniCache, IniSection,
- L"ReactOS_LogFile", L"\"ReactOS (Log file)\"",
- L"Windows2003", ArcPath,
- L"/DEBUG /DEBUGPORT=FILE /SOS");
+ Options->Drive = BootDrive;
+ Options->Partition = BootPartition;
+ Options->BootSectorFileName = BootSector;
- /* ReactOS_Ram */
- 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");
+ // BootEntry->BootEntryKey = MAKESTRKEY(Section);
+ BootEntry->FriendlyName = Description;
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Section));
- /* ReactOS_EMS */
- 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
+ /* Close the INI file */
+ CloseBootStore(BootStoreHandle);
+ return STATUS_SUCCESS;
}
-static
-NTSTATUS
-CreateFreeLoaderIniForReactOS(
- PWCHAR IniPath,
- PWCHAR ArcPath)
-{
- PINICACHE IniCache;
+//
+// I think this function can be generalizable as:
+// "find the corresponding 'ReactOS' boot entry in this loader config file
+// (here abstraction comes there), and if none, add a new one".
+//
- /* Initialize the INI file */
- IniCache = IniCacheCreate();
+typedef struct _ENUM_REACTOS_ENTRIES_DATA
+{
+ ULONG i;
+ BOOLEAN UseExistingEntry;
+ PCWSTR ArcPath;
+ WCHAR SectionName[80];
+ WCHAR OsName[80];
+} ENUM_REACTOS_ENTRIES_DATA, *PENUM_REACTOS_ENTRIES_DATA;
+
+// PENUM_BOOT_ENTRIES_ROUTINE
+static NTSTATUS
+NTAPI
+EnumerateReactOSEntries(
+ IN BOOT_STORE_TYPE Type,
+ IN PBOOT_STORE_ENTRY BootEntry,
+ IN PVOID Parameter OPTIONAL)
+{
+ PENUM_REACTOS_ENTRIES_DATA Data = (PENUM_REACTOS_ENTRIES_DATA)Parameter;
+ PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
+ WCHAR SystemPath[MAX_PATH];
- /* Create the common FreeLdr sections */
- CreateCommonFreeLoaderSections(IniCache);
+ /* We have a boot entry */
- /* Add the ReactOS entries */
- CreateFreeLoaderReactOSEntries(IniCache, ArcPath);
+ /* Check for supported boot type "Windows2003" */
+ if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) ||
+ RtlCompareMemory(&BootEntry->OsOptions /* Signature */,
+ NTOS_OPTIONS_SIGNATURE,
+ RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) !=
+ RTL_FIELD_SIZE(NTOS_OPTIONS, Signature))
+ {
+ /* This is not a ReactOS entry */
+ // DPRINT1(" An installation '%S' of unsupported type '%S'\n",
+ // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a");
+ DPRINT1(" An installation '%S' of unsupported type %lu\n",
+ BootEntry->FriendlyName, BootEntry->OsOptionsLength);
+ /* Continue the enumeration */
+ goto SkipThisEntry;
+ }
- /* Save the INI file */
- IniCacheSave(IniCache, IniPath);
- IniCacheDestroy(IniCache);
+ /* BootType is Windows2003, now check OsLoadPath */
+ if (!Options->OsLoadPath || !*Options->OsLoadPath)
+ {
+ /* Certainly not a ReactOS installation */
+ DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName);
+ /* Continue the enumeration */
+ goto SkipThisEntry;
+ }
- return STATUS_SUCCESS;
-}
+ RtlStringCchPrintfW(SystemPath, ARRAYSIZE(SystemPath), L"\"%s\"", Data->ArcPath);
+ if ((_wcsicmp(Options->OsLoadPath, Data->ArcPath) != 0) &&
+ (_wcsicmp(Options->OsLoadPath, SystemPath) != 0))
+ {
+ /*
+ * This entry is a ReactOS entry, but the SystemRoot
+ * does not match the one we are looking for.
+ */
+ /* Continue the enumeration */
+ goto SkipThisEntry;
+ }
-static
-NTSTATUS
-CreateFreeLoaderIniForReactOSAndBootSector(
- PWCHAR IniPath,
- PWCHAR ArcPath,
- PWCHAR Section,
- PWCHAR Description,
- PWCHAR BootDrive,
- PWCHAR BootPartition,
- PWCHAR BootSector)
-{
- PINICACHE IniCache;
- PINICACHESECTION IniSection;
+ DPRINT1(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n",
+ BootEntry->FriendlyName, Options->OsLoadPath);
+ // DPRINT1(" Found a Win2k3 install '%S' with ARC path '%S'\n",
+ // BootEntry->FriendlyName, Options->OsLoadPath);
- /* Initialize the INI file */
- IniCache = IniCacheCreate();
+ DPRINT1("EnumerateReactOSEntries: OsLoadPath: '%S'\n", Options->OsLoadPath);
- /* Create the common FreeLdr sections */
- CreateCommonFreeLoaderSections(IniCache);
+ Data->UseExistingEntry = TRUE;
+ RtlStringCchCopyW(Data->OsName, ARRAYSIZE(Data->OsName), BootEntry->FriendlyName);
- /* 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);
+ /* We have found our entry, stop the enumeration now! */
+ return STATUS_NO_MORE_ENTRIES;
+SkipThisEntry:
+ Data->UseExistingEntry = FALSE;
+ if (Type == FreeLdr && wcscmp(Data->SectionName, (PWSTR)BootEntry->BootEntryKey)== 0)
+ {
+ RtlStringCchPrintfW(Data->SectionName, ARRAYSIZE(Data->SectionName),
+ L"ReactOS_%lu", Data->i);
+ RtlStringCchPrintfW(Data->OsName, ARRAYSIZE(Data->OsName),
+ L"\"ReactOS %lu\"", Data->i);
+ Data->i++;
+ }
return STATUS_SUCCESS;
}
static
NTSTATUS
UpdateFreeLoaderIni(
- PWCHAR IniPath,
- PWCHAR ArcPath)
+ IN PCWSTR IniPath,
+ IN PCWSTR ArcPath)
{
NTSTATUS Status;
- PINICACHE IniCache;
- PINICACHESECTION IniSection;
- PINICACHESECTION OsIniSection;
- WCHAR SectionName[80];
- WCHAR OsName[80];
- WCHAR SystemPath[200];
- WCHAR SectionName2[200];
- PWCHAR KeyData;
- ULONG i,j;
-
- Status = IniCacheLoad(&IniCache, IniPath, FALSE);
+ PVOID BootStoreHandle;
+ ENUM_REACTOS_ENTRIES_DATA Data;
+ UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
+ PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
+ PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
+
+ /* Open the INI file */
+ Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, /*TRUE*/ FALSE);
if (!NT_SUCCESS(Status))
return Status;
- /* Get "Operating Systems" section */
- IniSection = IniCacheGetSection(IniCache, L"Operating Systems");
- if (IniSection == NULL)
- {
- IniCacheDestroy(IniCache);
- return STATUS_UNSUCCESSFUL;
- }
-
/* Find an existing usable or an unused section name */
- i = 1;
- wcscpy(SectionName, L"ReactOS");
- wcscpy(OsName, L"\"ReactOS\"");
- while(TRUE)
- {
- Status = IniCacheGetKey(IniSection, SectionName, &KeyData);
- if (!NT_SUCCESS(Status))
- break;
+ Data.UseExistingEntry = TRUE;
+ Data.i = 1;
+ Data.ArcPath = ArcPath;
+ RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS");
+ RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\"");
- /* Get operation system section */
- if (KeyData[0] == '"')
- {
- wcscpy(SectionName2, &KeyData[1]);
- j = wcslen(SectionName2);
- if (j > 0)
- {
- SectionName2[j-1] = 0;
- }
- }
- else
- {
- wcscpy(SectionName2, KeyData);
- }
+ //
+ // FIXME: We temporarily use EnumerateBootStoreEntries, until
+ // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
+ //
+ Status = EnumerateBootStoreEntries(BootStoreHandle, EnumerateReactOSEntries, &Data);
- /* Search for an existing ReactOS entry */
- OsIniSection = IniCacheGetSection(IniCache, SectionName2);
- if (OsIniSection != NULL)
- {
- BOOLEAN UseExistingEntry = TRUE;
+ /* Create a new "ReactOS" entry if there is none already existing that suits us */
+ if (!Data.UseExistingEntry)
+ {
+ // RtlStringCchPrintfW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS_%lu", Data.i);
+ // RtlStringCchPrintfW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS %lu\"", Data.i);
- /* Check for boot type "Windows2003" */
- Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData);
- if (NT_SUCCESS(Status))
- {
- if ((KeyData == NULL) ||
- ( (_wcsicmp(KeyData, L"Windows2003") != 0) &&
- (_wcsicmp(KeyData, L"\"Windows2003\"") != 0) ))
- {
- /* This is not a ReactOS entry */
- UseExistingEntry = FALSE;
- }
- }
- else
- {
- UseExistingEntry = FALSE;
- }
+ BootEntry->Version = FreeLdr;
+ BootEntry->BootFilePath = NULL;
- if (UseExistingEntry)
- {
- /* BootType is Windows2003. Now check SystemPath. */
- Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData);
- if (NT_SUCCESS(Status))
- {
- swprintf(SystemPath, L"\"%s\"", ArcPath);
- if ((KeyData == NULL) ||
- ( (_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. */
- UseExistingEntry = FALSE;
- }
- }
- else
- {
- UseExistingEntry = FALSE;
- }
- }
+ BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
+ RtlCopyMemory(Options->Signature,
+ NTOS_OPTIONS_SIGNATURE,
+ RTL_FIELD_SIZE(NTOS_OPTIONS, Signature));
- if (UseExistingEntry)
- {
- IniCacheDestroy(IniCache);
- return STATUS_SUCCESS;
- }
- }
+ Options->OsLoadPath = ArcPath;
- swprintf(SectionName, L"ReactOS_%lu", i);
- swprintf(OsName, L"\"ReactOS %lu\"", i);
- i++;
+ // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
+ BootEntry->FriendlyName = Data.OsName;
+ Options->OsLoadOptions = NULL; // L"";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Data.SectionName));
}
- /* Create a new "ReactOS" entry */
- CreateNTOSEntry(IniCache, IniSection,
- SectionName, OsName,
- L"Windows2003", ArcPath,
- L"");
+ /* Close the INI file */
+ CloseBootStore(BootStoreHandle);
+ return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+UpdateBootIni(
+ IN PCWSTR IniPath,
+ IN PCWSTR EntryName, // ~= ArcPath
+ IN PCWSTR EntryValue)
+{
+ NTSTATUS Status;
+ PVOID BootStoreHandle;
+ ENUM_REACTOS_ENTRIES_DATA Data;
- IniCacheSave(IniCache, IniPath);
- IniCacheDestroy(IniCache);
+ // NOTE: Technically it would be "BootSector"...
+ UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
+ PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
+ PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
- return STATUS_SUCCESS;
+ /* Open the INI file */
+ Status = OpenBootStore(&BootStoreHandle, IniPath, NtLdr, FALSE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* Find an existing usable or an unused section name */
+ Data.UseExistingEntry = TRUE;
+ // Data.i = 1;
+ Data.ArcPath = EntryName;
+ // RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS");
+ RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\"");
+
+ //
+ // FIXME: We temporarily use EnumerateBootStoreEntries, until
+ // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
+ //
+ Status = EnumerateBootStoreEntries(BootStoreHandle, EnumerateReactOSEntries, &Data);
+
+ /* If either the key was not found, or contains something else, add a new one */
+ if (!Data.UseExistingEntry /* ||
+ ( (Status == STATUS_NO_MORE_ENTRIES) && wcscmp(Data.OsName, EntryValue) ) */)
+ {
+ BootEntry->Version = NtLdr;
+ BootEntry->BootFilePath = NULL;
+
+ BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
+ RtlCopyMemory(Options->Signature,
+ NTOS_OPTIONS_SIGNATURE,
+ RTL_FIELD_SIZE(NTOS_OPTIONS, Signature));
+
+ Options->OsLoadPath = EntryName;
+
+ // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
+ // BootEntry->FriendlyName = Data.OsName;
+ BootEntry->FriendlyName = EntryValue;
+ Options->OsLoadOptions = NULL; // L"";
+ AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(0 /*Data.SectionName*/));
+ }
+
+ /* Close the INI file */
+ CloseBootStore(BootStoreHandle);
+ return STATUS_SUCCESS; // Status;
}
+
BOOLEAN
-IsThereAValidBootSector(PWSTR RootPath)
+IsThereAValidBootSector(
+ IN PCWSTR RootPath)
{
/*
* We first demand that the bootsector has a valid signature at its end.
* 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;
+ UNICODE_STRING RootPartition;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
BootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
if (BootSector == NULL)
return FALSE; // STATUS_INSUFFICIENT_RESOURCES;
+ RtlZeroMemory(BootSector, SECTORSIZE);
- /* Read current boot sector into buffer */
- RtlInitUnicodeString(&Name, RootPath);
+ /* Open the root partition - Remove any trailing backslash if needed */
+ RtlInitUnicodeString(&RootPartition, RootPath);
+ TrimTrailingPathSeparators_UStr(&RootPartition);
InitializeObjectAttributes(&ObjectAttributes,
- &Name,
+ &RootPartition,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
if (!NT_SUCCESS(Status))
goto Quit;
- RtlZeroMemory(BootSector, SECTORSIZE);
-
+ /* Read current boot sector into buffer */
FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NTSTATUS
SaveBootSector(
- PWSTR RootPath,
- PWSTR DstPath,
- ULONG Length)
+ IN PCWSTR RootPath,
+ IN PCWSTR DstPath,
+ IN ULONG Length)
{
NTSTATUS Status;
UNICODE_STRING Name;
if (BootSector == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
- /* Read current boot sector into buffer */
+ /* Open the root partition - Remove any trailing backslash if needed */
RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
return Status;
}
+ /* Read current boot sector into buffer */
FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
return Status;
}
-static
NTSTATUS
-InstallFat16BootCodeToFile(
- PWSTR SrcPath,
- PWSTR DstPath,
- PWSTR RootPath)
+InstallMbrBootCodeToDisk(
+ IN PCWSTR SrcPath,
+ IN PCWSTR RootPath)
{
NTSTATUS Status;
UNICODE_STRING Name;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
LARGE_INTEGER FileOffset;
- PFAT_BOOTSECTOR OrigBootSector;
- PFAT_BOOTSECTOR NewBootSector;
+ PPARTITION_SECTOR OrigBootSector;
+ PPARTITION_SECTOR NewBootSector;
/* Allocate buffer for original bootsector */
- OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
+ OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTITION_SECTOR));
if (OrigBootSector == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
- /* Read current boot sector into buffer */
+ /* Open the root partition - Remove any trailing backslash if needed */
RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
return Status;
}
+ /* Read current boot sector into buffer */
FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
&IoStatusBlock,
OrigBootSector,
- SECTORSIZE,
+ sizeof(PARTITION_SECTOR),
&FileOffset,
NULL);
NtClose(FileHandle);
}
/* Allocate buffer for new bootsector */
- NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
+ NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTITION_SECTOR));
if (NewBootSector == NULL)
{
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return Status;
}
- FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
- SECTORSIZE,
- &FileOffset,
+ sizeof(PARTITION_SECTOR),
+ NULL,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
return Status;
}
- /* Adjust bootsector (copy a part of the FAT BPB) */
- memcpy(&NewBootSector->OemName,
- &OrigBootSector->OemName,
- FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
- FIELD_OFFSET(FAT_BOOTSECTOR, OemName));
+ /*
+ * Copy the disk signature, the reserved fields and
+ * the partition table from the old MBR to the new one.
+ */
+ 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);
- /* Write new bootsector to DstPath */
- RtlInitUnicodeString(&Name, DstPath);
+ /* Open the root partition - Remove any trailing backslash if needed */
+ RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
NULL,
NULL);
- Status = NtCreateFile(&FileHandle,
- GENERIC_WRITE | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_OVERWRITE_IF,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
- NULL,
- 0);
+ 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 new bootsector to RootPath */
+ FileOffset.QuadPart = 0ULL;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
- SECTORSIZE,
- NULL,
+ sizeof(PARTITION_SECTOR),
+ &FileOffset,
NULL);
NtClose(FileHandle);
return Status;
}
+
static
NTSTATUS
-InstallFat32BootCodeToFile(
- PWSTR SrcPath,
- PWSTR DstPath,
- PWSTR RootPath)
+InstallFat12BootCodeToFloppy(
+ IN PCWSTR SrcPath,
+ IN PCWSTR RootPath)
{
NTSTATUS Status;
UNICODE_STRING Name;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
LARGE_INTEGER FileOffset;
- PFAT32_BOOTSECTOR OrigBootSector;
- PFAT32_BOOTSECTOR NewBootSector;
+ PFAT_BOOTSECTOR OrigBootSector;
+ PFAT_BOOTSECTOR NewBootSector;
/* Allocate buffer for original bootsector */
OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
if (OrigBootSector == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
- /* Read current boot sector into buffer */
+ /* Open the root partition - Remove any trailing backslash if needed */
RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
return Status;
}
+ /* Read current boot sector into buffer */
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
&IoStatusBlock,
OrigBootSector,
SECTORSIZE,
- NULL,
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
return Status;
}
- /* Allocate buffer for new bootsector (2 sectors) */
- NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE);
+ /* Allocate buffer for new bootsector */
+ NewBootSector = RtlAllocateHeap(ProcessHeap,
+ 0,
+ SECTORSIZE);
if (NewBootSector == NULL)
{
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
NULL,
&IoStatusBlock,
NewBootSector,
- 2 * SECTORSIZE,
+ SECTORSIZE,
NULL,
NULL);
NtClose(FileHandle);
return Status;
}
- /* Adjust bootsector (copy a part of the FAT32 BPB) */
+ /* Adjust bootsector (copy a part of the FAT16 BPB) */
memcpy(&NewBootSector->OemName,
&OrigBootSector->OemName,
- FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
- FIELD_OFFSET(FAT32_BOOTSECTOR, OemName));
-
- /* Disable the backup boot sector */
- NewBootSector->BackupBootSector = 0;
+ FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
+ FIELD_OFFSET(FAT_BOOTSECTOR, OemName));
/* Free the original boot sector */
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
- /* Write the first sector of the new bootcode to DstPath */
- RtlInitUnicodeString(&Name, DstPath);
+ /* Open the root partition - Remove any trailing backslash if needed */
+ RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
NULL,
NULL);
- Status = NtCreateFile(&FileHandle,
- GENERIC_WRITE | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_SUPERSEDE,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
- NULL,
- 0);
+ 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 new bootsector to RootPath */
+ FileOffset.QuadPart = 0ULL;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
SECTORSIZE,
- NULL,
+ &FileOffset,
NULL);
NtClose(FileHandle);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(ProcessHeap, 0, NewBootSector);
- return Status;
- }
-
- /* Write the second sector of the new bootcode to boot disk sector 14 */
- RtlInitUnicodeString(&Name, RootPath);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- 0,
- NULL,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- GENERIC_WRITE | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- 0,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(ProcessHeap, 0, NewBootSector);
- return Status;
- }
-
- FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE);
- Status = NtWriteFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &IoStatusBlock,
- ((PUCHAR)NewBootSector + SECTORSIZE),
- SECTORSIZE,
- &FileOffset,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- }
- NtClose(FileHandle);
/* Free the new boot sector */
RtlFreeHeap(ProcessHeap, 0, NewBootSector);
return Status;
}
-
+static
NTSTATUS
-InstallMbrBootCodeToDisk(
- PWSTR SrcPath,
- PWSTR RootPath)
+InstallFat16BootCode(
+ IN PCWSTR SrcPath, // FAT16 bootsector source file (on the installation medium)
+ IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
+ IN HANDLE RootPartition) // Partition holding the (old) FAT16 information
{
NTSTATUS Status;
UNICODE_STRING Name;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
LARGE_INTEGER FileOffset;
- PPARTITION_SECTOR OrigBootSector;
- PPARTITION_SECTOR NewBootSector;
+ PFAT_BOOTSECTOR OrigBootSector;
+ PFAT_BOOTSECTOR NewBootSector;
- /* Allocate buffer for original bootsector */
- OrigBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap,
- 0,
- sizeof(PARTITION_SECTOR));
+ /* Allocate a buffer for the 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;
- }
-
+ /* Read the current partition boot sector into the buffer */
FileOffset.QuadPart = 0ULL;
- Status = NtReadFile(FileHandle,
+ Status = NtReadFile(RootPartition,
NULL,
NULL,
NULL,
&IoStatusBlock,
OrigBootSector,
- sizeof(PARTITION_SECTOR),
+ SECTORSIZE,
&FileOffset,
NULL);
- NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return Status;
}
- /* Allocate buffer for new bootsector */
- NewBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap,
- 0,
- sizeof(PARTITION_SECTOR));
+ /* Allocate a buffer for the new bootsector */
+ NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
if (NewBootSector == NULL)
{
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return STATUS_INSUFFICIENT_RESOURCES;
}
- /* Read new bootsector from SrcPath */
+ /* Read the new bootsector from SrcPath */
RtlInitUnicodeString(&Name, SrcPath);
-
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
Status = NtOpenFile(&FileHandle,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes,
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
- sizeof(PARTITION_SECTOR),
- NULL,
+ SECTORSIZE,
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
return Status;
}
- /*
- * Copy the disk signature, the reserved fields and
- * the partition table from the old MBR to the new one.
- */
- RtlCopyMemory(&NewBootSector->Signature,
- &OrigBootSector->Signature,
- sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */);
+ /* Adjust the bootsector (copy a part of the FAT16 BPB) */
+ memcpy(&NewBootSector->OemName,
+ &OrigBootSector->OemName,
+ FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
+ FIELD_OFFSET(FAT_BOOTSECTOR, OemName));
/* Free the original boot sector */
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
- /* 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 the new bootsector to DstPath */
FileOffset.QuadPart = 0ULL;
- Status = NtWriteFile(FileHandle,
+ Status = NtWriteFile(DstPath,
NULL,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
- sizeof(PARTITION_SECTOR),
+ SECTORSIZE,
&FileOffset,
NULL);
- NtClose(FileHandle);
/* Free the new boot sector */
RtlFreeHeap(ProcessHeap, 0, NewBootSector);
static
NTSTATUS
-InstallFat12BootCodeToFloppy(
- PWSTR SrcPath,
- PWSTR RootPath)
+InstallFat16BootCodeToFile(
+ IN PCWSTR SrcPath,
+ IN PCWSTR DstPath,
+ IN PCWSTR RootPath)
{
NTSTATUS Status;
UNICODE_STRING Name;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
- HANDLE FileHandle;
- LARGE_INTEGER FileOffset;
- PFAT_BOOTSECTOR OrigBootSector;
- PFAT_BOOTSECTOR NewBootSector;
+ HANDLE PartitionHandle, FileHandle;
- /* Allocate buffer for original bootsector */
- OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
- if (OrigBootSector == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Read current boot sector into buffer */
+ /*
+ * Open the root partition from which the boot sector
+ * parameters will be obtained.
+ * Remove any trailing backslash if needed.
+ */
RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
- Status = NtOpenFile(&FileHandle,
+ Status = NtOpenFile(&PartitionHandle,
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);
+ FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return Status;
- }
-
- /* Allocate buffer for new bootsector */
- NewBootSector = RtlAllocateHeap(ProcessHeap,
- 0,
- SECTORSIZE);
- if (NewBootSector == NULL)
- {
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Read new bootsector from SrcPath */
- RtlInitUnicodeString(&Name, SrcPath);
+ /* Open or create the file where the new bootsector will be saved */
+ RtlInitUnicodeString(&Name, DstPath);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
- OBJ_CASE_INSENSITIVE,
+ 0, // OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
- Status = NtOpenFile(&FileHandle,
- GENERIC_READ | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- 0,
- FILE_SYNCHRONOUS_IO_NONALERT);
+ Status = NtCreateFile(&FileHandle,
+ GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OVERWRITE_IF,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
+ NULL,
+ 0);
if (!NT_SUCCESS(Status))
{
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
- RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+ DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
+ NtClose(PartitionHandle);
return Status;
}
- Status = NtReadFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &IoStatusBlock,
- NewBootSector,
- SECTORSIZE,
- NULL,
- NULL);
+ /* Install the FAT16 boot sector */
+ Status = InstallFat16BootCode(SrcPath, FileHandle, PartitionHandle);
+
+ /* Close the file and the partition */
NtClose(FileHandle);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
- RtlFreeHeap(ProcessHeap, 0, NewBootSector);
- return Status;
- }
+ NtClose(PartitionHandle);
- /* Adjust bootsector (copy a part of the FAT16 BPB) */
- memcpy(&NewBootSector->OemName,
- &OrigBootSector->OemName,
- FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
- FIELD_OFFSET(FAT_BOOTSECTOR, OemName));
+ return Status;
+}
- /* Free the original boot sector */
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+static
+NTSTATUS
+InstallFat16BootCodeToDisk(
+ IN PCWSTR SrcPath,
+ IN PCWSTR RootPath)
+{
+ NTSTATUS Status;
+ UNICODE_STRING Name;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE PartitionHandle;
- /* Write new bootsector to RootPath */
+ /*
+ * Open the root partition from which the boot sector parameters will be
+ * obtained; this is also where we will write the updated boot sector.
+ * Remove any trailing backslash if needed.
+ */
RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
- 0,
+ OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
- Status = NtOpenFile(&FileHandle,
- GENERIC_WRITE | SYNCHRONIZE,
+ Status = NtOpenFile(&PartitionHandle,
+ GENERIC_READ | 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;
- }
- FileOffset.QuadPart = 0ULL;
- Status = NtWriteFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &IoStatusBlock,
- NewBootSector,
- SECTORSIZE,
- &FileOffset,
- NULL);
- NtClose(FileHandle);
+ /* Install the FAT16 boot sector */
+ Status = InstallFat16BootCode(SrcPath, PartitionHandle, PartitionHandle);
- /* Free the new boot sector */
- RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+ /* Close the partition */
+ NtClose(PartitionHandle);
return Status;
}
+
static
NTSTATUS
-InstallFat16BootCodeToDisk(
- PWSTR SrcPath,
- PWSTR RootPath)
+InstallFat32BootCode(
+ IN PCWSTR SrcPath, // FAT32 bootsector source file (on the installation medium)
+ IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
+ IN HANDLE RootPartition) // Partition holding the (old) FAT32 information
{
NTSTATUS Status;
UNICODE_STRING Name;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
LARGE_INTEGER FileOffset;
- PFAT_BOOTSECTOR OrigBootSector;
- PFAT_BOOTSECTOR NewBootSector;
+ PFAT32_BOOTSECTOR OrigBootSector;
+ PFAT32_BOOTSECTOR NewBootSector;
+ USHORT BackupBootSector;
- /* Allocate buffer for original bootsector */
+ /* Allocate a buffer for the 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;
- }
-
+ /* Read the current boot sector into the buffer */
FileOffset.QuadPart = 0ULL;
- Status = NtReadFile(FileHandle,
+ Status = NtReadFile(RootPartition,
NULL,
NULL,
NULL,
SECTORSIZE,
&FileOffset,
NULL);
- NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return Status;
}
- /* Allocate buffer for new bootsector */
- NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
+ /* Allocate a buffer for the 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 */
+ /* Read the new bootsector from SrcPath */
RtlInitUnicodeString(&Name, SrcPath);
-
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
Status = NtOpenFile(&FileHandle,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes,
return Status;
}
+ FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
- SECTORSIZE,
- NULL,
+ 2 * SECTORSIZE,
+ &FileOffset,
NULL);
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
return Status;
}
- /* Adjust bootsector (copy a part of the FAT16 BPB) */
+ /* Adjust the bootsector (copy a part of the FAT32 BPB) */
memcpy(&NewBootSector->OemName,
&OrigBootSector->OemName,
- FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
- FIELD_OFFSET(FAT_BOOTSECTOR, OemName));
+ FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
+ FIELD_OFFSET(FAT32_BOOTSECTOR, OemName));
+
+ /*
+ * We know we copy the boot code to a file only when DstPath != RootPartition,
+ * otherwise the boot code is copied to the specified root partition.
+ */
+ if (DstPath != RootPartition)
+ {
+ /* Copy to a file: Disable the backup boot sector */
+ NewBootSector->BackupBootSector = 0;
+ }
+ else
+ {
+ /* Copy to a disk: Get the location of the backup boot sector */
+ BackupBootSector = OrigBootSector->BackupBootSector;
+ }
/* Free the original boot sector */
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
- /* 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);
+ /* Write the first sector of the new bootcode to DstPath sector 0 */
+ FileOffset.QuadPart = 0ULL;
+ Status = NtWriteFile(DstPath,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ NewBootSector,
+ SECTORSIZE,
+ &FileOffset,
+ NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
+ DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
RtlFreeHeap(ProcessHeap, 0, NewBootSector);
return Status;
}
- FileOffset.QuadPart = 0ULL;
- Status = NtWriteFile(FileHandle,
+ if (DstPath == RootPartition)
+ {
+ /* Copy to a disk: Write the backup boot sector */
+ if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
+ {
+ FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE);
+ Status = NtWriteFile(DstPath,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ NewBootSector,
+ SECTORSIZE,
+ &FileOffset,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
+ RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+ return Status;
+ }
+ }
+ }
+
+ /* Write the second sector of the new bootcode to boot disk sector 14 */
+ // FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE);
+ FileOffset.QuadPart = 14 * SECTORSIZE;
+ Status = NtWriteFile(DstPath, // or really RootPartition ???
NULL,
NULL,
NULL,
&IoStatusBlock,
- NewBootSector,
+ ((PUCHAR)NewBootSector + SECTORSIZE),
SECTORSIZE,
&FileOffset,
NULL);
- NtClose(FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
+ }
/* Free the new boot sector */
RtlFreeHeap(ProcessHeap, 0, NewBootSector);
static
NTSTATUS
-InstallFat32BootCodeToDisk(
- PWSTR SrcPath,
- PWSTR RootPath)
+InstallFat32BootCodeToFile(
+ IN PCWSTR SrcPath,
+ IN PCWSTR DstPath,
+ IN PCWSTR 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;
+ HANDLE PartitionHandle, FileHandle;
- /* Allocate buffer for original bootsector */
- OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
- if (OrigBootSector == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Read current boot sector into buffer */
+ /*
+ * Open the root partition from which the boot sector parameters
+ * will be obtained.
+ * FIXME? It might be possible that we need to also open it for writing
+ * access in case we really need to still write the second portion of
+ * the boot sector ????
+ *
+ * Remove any trailing backslash if needed.
+ */
RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
- Status = NtOpenFile(&FileHandle,
+ Status = NtOpenFile(&PartitionHandle,
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);
+ FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
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);
+ /* Open or create the file where (the first sector of ????) the new bootsector will be saved */
+ RtlInitUnicodeString(&Name, DstPath);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
- OBJ_CASE_INSENSITIVE,
+ 0, // OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
- Status = NtOpenFile(&FileHandle,
- GENERIC_READ | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- 0,
- FILE_SYNCHRONOUS_IO_NONALERT);
+ Status = NtCreateFile(&FileHandle,
+ GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_SUPERSEDE, // FILE_OVERWRITE_IF, <- is used for FAT16
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
+ NULL,
+ 0);
if (!NT_SUCCESS(Status))
{
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
- RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+ DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
+ NtClose(PartitionHandle);
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;
- }
+ /* Install the FAT32 boot sector */
+ Status = InstallFat32BootCode(SrcPath, FileHandle, PartitionHandle);
- /* Adjust bootsector (copy a part of the FAT32 BPB) */
- memcpy(&NewBootSector->OemName,
- &OrigBootSector->OemName,
- FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
- FIELD_OFFSET(FAT32_BOOTSECTOR, OemName));
+ /* Close the file and the partition */
+ NtClose(FileHandle);
+ NtClose(PartitionHandle);
- /* Get the location of the backup boot sector */
- BackupBootSector = OrigBootSector->BackupBootSector;
+ return Status;
+}
- /* Free the original boot sector */
- RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+static
+NTSTATUS
+InstallFat32BootCodeToDisk(
+ IN PCWSTR SrcPath,
+ IN PCWSTR RootPath)
+{
+ NTSTATUS Status;
+ UNICODE_STRING Name;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE PartitionHandle;
- /* Write the first sector of the new bootcode to DstPath */
+ /*
+ * Open the root partition from which the boot sector parameters will be
+ * obtained; this is also where we will write the updated boot sector.
+ * Remove any trailing backslash if needed.
+ */
RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
- 0,
- NULL,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- GENERIC_WRITE | SYNCHRONIZE,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenFile(&PartitionHandle,
+ GENERIC_READ | 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);
+ FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
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);
- }
- NtClose(FileHandle);
+ /* Install the FAT32 boot sector */
+ Status = InstallFat32BootCode(SrcPath, PartitionHandle, PartitionHandle);
- /* Free the new boot sector */
- RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+ /* Close the partition */
+ NtClose(PartitionHandle);
return Status;
}
static
NTSTATUS
-InstallExt2BootCodeToDisk(
- PWSTR SrcPath,
- PWSTR RootPath)
+InstallBtrfsBootCodeToDisk(
+ IN PCWSTR SrcPath,
+ IN PCWSTR RootPath)
{
NTSTATUS Status;
UNICODE_STRING Name;
HANDLE FileHandle;
LARGE_INTEGER FileOffset;
// PEXT2_BOOTSECTOR OrigBootSector;
- PEXT2_BOOTSECTOR NewBootSector;
+ PBTRFS_BOOTSECTOR NewBootSector;
// USHORT BackupBootSector;
+ PARTITION_INFORMATION_EX PartInfo;
#if 0
/* Allocate buffer for original bootsector */
if (OrigBootSector == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
- /* Read current boot sector into buffer */
+ /* Open the root partition - Remove any trailing backslash if needed */
RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
return Status;
}
+ /* Read current boot sector into buffer */
FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
#endif
/* Allocate buffer for new bootsector */
- NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(EXT2_BOOTSECTOR));
+ NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(BTRFS_BOOTSECTOR));
if (NewBootSector == NULL)
{
// RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
NULL,
&IoStatusBlock,
NewBootSector,
- sizeof(EXT2_BOOTSECTOR),
+ sizeof(BTRFS_BOOTSECTOR),
NULL,
NULL);
NtClose(FileHandle);
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;
// RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
#endif
- /* Write new bootsector to RootPath */
+ /* Open the root partition - Remove any trailing backslash if needed */
RtlInitUnicodeString(&Name, RootPath);
+ TrimTrailingPathSeparators_UStr(&Name);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
return Status;
}
+ /* Obtaining partition info and writing it to bootsector */
+ Status = NtDeviceIoControlFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ IOCTL_DISK_GET_PARTITION_INFO_EX,
+ NULL,
+ 0,
+ &PartInfo,
+ sizeof(PartInfo));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status);
+ NtClose(FileHandle);
+ RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+ return Status;
+ }
+
+ /* Write new bootsector to RootPath */
+
+ NewBootSector->PartitionStartLBA = PartInfo.StartingOffset.QuadPart / SECTORSIZE;
+
/* Write sector 0 */
FileOffset.QuadPart = 0ULL;
Status = NtWriteFile(FileHandle,
NULL,
&IoStatusBlock,
NewBootSector,
- sizeof(EXT2_BOOTSECTOR),
+ sizeof(BTRFS_BOOTSECTOR),
&FileOffset,
NULL);
#if 0
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);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status);
- NtClose(FileHandle);
- return Status;
- }
-
- *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))
- {
- DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status);
- }
-
- NtClose(FileHandle);
- 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;
- ULONG FileAttribute;
- PWCHAR OldValue = NULL;
-
- Status = IniCacheLoad(&Cache, BootIniPath, FALSE);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Section = IniCacheGetSection(Cache,
- L"operating systems");
- if (Section == NULL)
- {
- IniCacheDestroy(Cache);
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Check - maybe record already exists */
- Status = IniCacheGetKey(Section, EntryName, &OldValue);
-
- /* If either key was not found, or contains something else - add new one */
- if (!NT_SUCCESS(Status) || wcscmp(OldValue, EntryValue))
- {
- IniCacheInsertKey(Section,
- NULL,
- INSERT_LAST,
- EntryName,
- EntryValue);
- }
-
- Status = UnprotectBootIni(BootIniPath,
- &FileAttribute);
- if (!NT_SUCCESS(Status))
- {
- IniCacheDestroy(Cache);
- return Status;
- }
-
- Status = IniCacheSave(Cache, BootIniPath);
- if (!NT_SUCCESS(Status))
- {
- IniCacheDestroy(Cache);
- return Status;
- }
-
- FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
- Status = ProtectBootIni(BootIniPath, FileAttribute);
-
- IniCacheDestroy(Cache);
-
- return Status;
-}
-
static
NTSTATUS
InstallFatBootcodeToPartition(
/* FAT or FAT32 partition */
DPRINT("System path: '%wZ'\n", SystemRootPath);
- /* Copy FreeLoader to the system partition */
+ /* Copy FreeLoader to the system partition, always overwriting the older version */
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\freeldr.sys");
+ CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
Status = SetupCopyFile(SrcPath, DstPath);
return Status;
}
- /* Prepare for possibly copying 'freeldr.ini' */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\freeldr.ini");
-
- DoesFreeLdrExist = DoesFileExist(NULL, NULL, DstPath);
+ /* Prepare for possibly updating 'freeldr.ini' */
+ DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
if (DoesFreeLdrExist)
{
/* Update existing 'freeldr.ini' */
DPRINT1("Update existing 'freeldr.ini'\n");
-
- Status = UpdateFreeLoaderIni(DstPath, DestinationArcPath->Buffer);
+ Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
/* Check for NT and other bootloaders */
// FIXME: Check for Vista+ bootloader!
- if (DoesFileExist(NULL, SystemRootPath->Buffer, L"ntldr") == TRUE ||
- DoesFileExist(NULL, SystemRootPath->Buffer, L"boot.ini") == TRUE)
+ /*** Status = FindBootStore(PartitionHandle, NtLdr, &Version); ***/
+ /*** Status = FindBootStore(PartitionHandle, BootMgr, &Version); ***/
+ if (DoesFileExist_2(SystemRootPath->Buffer, L"NTLDR") == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"BOOT.INI") == TRUE)
{
- /* Search root directory for 'ntldr' and 'boot.ini' */
+ /* Search root directory for 'NTLDR' and 'BOOT.INI' */
DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
/* Create or update 'freeldr.ini' */
{
/* Create new 'freeldr.ini' */
DPRINT1("Create new 'freeldr.ini'\n");
- // CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\freeldr.ini");
-
- Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer);
+ Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
}
/* Install new bootcode into a file */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\bootsect.ros");
+ CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"bootsect.ros");
if (PartitionType == PARTITION_FAT32 ||
PartitionType == PARTITION_FAT32_XINT13)
}
/* Update 'boot.ini' */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\boot.ini");
-
- DPRINT1("Update 'boot.ini': %S\n", DstPath);
- Status = UpdateBootIni(DstPath,
+ /* Windows' NTLDR loads an external bootsector file when the specified drive
+ letter is C:, otherwise it will interpret it as a boot DOS path specifier. */
+ DPRINT1("Update 'boot.ini'\n");
+ Status = UpdateBootIni(SystemRootPath->Buffer,
L"C:\\bootsect.ros",
L"\"ReactOS\"");
if (!NT_SUCCESS(Status))
{
/* Non-NT bootloaders: install our own bootloader */
- PWCHAR Section;
- PWCHAR Description;
- PWCHAR BootDrive;
- PWCHAR BootPartition;
- PWCHAR BootSector;
- PWCHAR BootSectorFileName;
+ PCWSTR Section;
+ PCWSTR Description;
+ PCWSTR BootDrive;
+ PCWSTR BootPartition;
+ PCWSTR BootSector;
+
+ /* Search for COMPAQ MS-DOS 1.x (1.11, 1.12, based on MS-DOS 1.25) boot loader */
+ if (DoesFileExist_2(SystemRootPath->Buffer, L"IOSYS.COM") == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"MSDOS.COM") == TRUE)
+ {
+ DPRINT1("Found COMPAQ MS-DOS 1.x (1.11, 1.12) / MS-DOS 1.25 boot loader\n");
- if (DoesFileExist(NULL, SystemRootPath->Buffer, L"io.sys") == TRUE ||
- DoesFileExist(NULL, SystemRootPath->Buffer, L"msdos.sys") == TRUE)
+ Section = L"CPQDOS";
+ Description = L"\"COMPAQ MS-DOS 1.x / MS-DOS 1.25\"";
+ BootDrive = L"hd0";
+ BootPartition = L"1";
+ BootSector = L"BOOTSECT.DOS";
+ }
+ else
+ /* Search for Microsoft DOS or Windows 9x boot loader */
+ if (DoesFileExist_2(SystemRootPath->Buffer, L"IO.SYS") == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"MSDOS.SYS") == TRUE)
+ // WINBOOT.SYS
{
- /* 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\"";
+ Section = L"MSDOS";
+ Description = L"\"MS-DOS/Windows\"";
+ BootDrive = L"hd0";
+ BootPartition = L"1";
+ BootSector = L"BOOTSECT.DOS";
+ }
+ else
+ /* Search for IBM PC-DOS or DR-DOS 5.x boot loader */
+ if (DoesFileExist_2(SystemRootPath->Buffer, L"IBMIO.COM" ) == TRUE || // Some people refer to this file instead of IBMBIO.COM...
+ DoesFileExist_2(SystemRootPath->Buffer, L"IBMBIO.COM") == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"IBMDOS.COM") == TRUE)
+ {
+ DPRINT1("Found IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\n");
+
+ Section = L"IBMDOS";
+ Description = L"\"IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\"";
+ BootDrive = L"hd0";
+ BootPartition = L"1";
+ BootSector = L"BOOTSECT.DOS";
+ }
+ else
+ /* Search for DR-DOS 3.x boot loader */
+ if (DoesFileExist_2(SystemRootPath->Buffer, L"DRBIOS.SYS") == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"DRBDOS.SYS") == TRUE)
+ {
+ DPRINT1("Found DR-DOS 3.x\n");
+
+ Section = L"DRDOS";
+ Description = L"\"DR-DOS 3.x\"";
+ BootDrive = L"hd0";
+ BootPartition = L"1";
+ BootSector = L"BOOTSECT.DOS";
+ }
+ else
+ /* Search for Dell Real-Mode Kernel (DRMK) OS */
+ if (DoesFileExist_2(SystemRootPath->Buffer, L"DELLBIO.BIN") == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"DELLRMK.BIN") == TRUE)
+ {
+ DPRINT1("Found Dell Real-Mode Kernel OS\n");
+
+ Section = L"DRMK";
+ Description = L"\"Dell Real-Mode Kernel OS\"";
BootDrive = L"hd0";
BootPartition = L"1";
BootSector = L"BOOTSECT.DOS";
+ }
+ else
+ /* Search for MS OS/2 1.x */
+ if (DoesFileExist_2(SystemRootPath->Buffer, L"OS2BOOT.COM") == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"OS2BIO.COM" ) == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"OS2DOS.COM" ) == TRUE)
+ {
+ DPRINT1("Found MS OS/2 1.x\n");
- BootSectorFileName = L"\\bootsect.dos";
+ Section = L"MSOS2";
+ Description = L"\"MS OS/2 1.x\"";
+ BootDrive = L"hd0";
+ BootPartition = L"1";
+ BootSector = L"BOOTSECT.OS2";
+ }
+ else
+ /* Search for MS or IBM OS/2 */
+ if (DoesFileExist_2(SystemRootPath->Buffer, L"OS2BOOT") == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"OS2LDR" ) == TRUE ||
+ DoesFileExist_2(SystemRootPath->Buffer, L"OS2KRNL") == TRUE)
+ {
+ DPRINT1("Found MS/IBM OS/2\n");
+
+ Section = L"IBMOS2";
+ Description = L"\"MS/IBM OS/2\"";
+ BootDrive = L"hd0";
+ BootPartition = L"1";
+ BootSector = L"BOOTSECT.OS2";
}
else
- if (DoesFileExist(NULL, SystemRootPath->Buffer, L"kernel.sys") == TRUE)
+ /* Search for FreeDOS boot loader */
+ if (DoesFileExist_2(SystemRootPath->Buffer, L"kernel.sys") == TRUE)
{
- /* Search for root directory for 'kernel.sys' */
DPRINT1("Found FreeDOS boot loader\n");
- Section = L"DOS";
+ Section = L"FDOS";
Description = L"\"FreeDOS\"";
BootDrive = L"hd0";
BootPartition = L"1";
BootSector = L"BOOTSECT.DOS";
-
- BootSectorFileName = L"\\bootsect.dos";
}
else
{
BootDrive = L"hd0";
BootPartition = L"1";
BootSector = L"BOOTSECT.OLD";
-
- BootSectorFileName = L"\\bootsect.old";
}
/* Create or update 'freeldr.ini' */
{
/* Create new 'freeldr.ini' */
DPRINT1("Create new 'freeldr.ini'\n");
- // CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\freeldr.ini");
if (IsThereAValidBootSector(SystemRootPath->Buffer))
{
Status = CreateFreeLoaderIniForReactOSAndBootSector(
- DstPath, DestinationArcPath->Buffer,
+ SystemRootPath->Buffer, DestinationArcPath->Buffer,
Section, Description,
BootDrive, BootPartition, BootSector);
if (!NT_SUCCESS(Status))
}
/* Save current bootsector */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSectorFileName);
+ CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
Status = SaveBootSector(SystemRootPath->Buffer, DstPath, SECTORSIZE);
}
else
{
- Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer);
+ Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
static
NTSTATUS
-InstallExt2BootcodeToPartition(
+InstallBtrfsBootcodeToPartition(
PUNICODE_STRING SystemRootPath,
PUNICODE_STRING SourceRootPath,
PUNICODE_STRING DestinationArcPath,
WCHAR SrcPath[MAX_PATH];
WCHAR DstPath[MAX_PATH];
- /* EXT2 partition */
+ /* BTRFS partition */
DPRINT("System path: '%wZ'\n", SystemRootPath);
- /* Copy FreeLoader to the system partition */
+ /* Copy FreeLoader to the system partition, always overwriting the older version */
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\freeldr.sys");
+ CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
Status = SetupCopyFile(SrcPath, DstPath);
return Status;
}
- /* Prepare for possibly copying 'freeldr.ini' */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\freeldr.ini");
-
- DoesFreeLdrExist = DoesFileExist(NULL, NULL, DstPath);
+ /* Prepare for possibly updating 'freeldr.ini' */
+ DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
if (DoesFreeLdrExist)
{
/* Update existing 'freeldr.ini' */
DPRINT1("Update existing 'freeldr.ini'\n");
-
- Status = UpdateFreeLoaderIni(DstPath, DestinationArcPath->Buffer);
+ Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
{
/* Create new 'freeldr.ini' */
DPRINT1("Create new 'freeldr.ini'\n");
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\freeldr.ini");
/* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
DPRINT1("*nix or unknown boot loader found\n");
if (IsThereAValidBootSector(SystemRootPath->Buffer))
{
+ PCWSTR BootSector = L"BOOTSECT.OLD";
+
Status = CreateFreeLoaderIniForReactOSAndBootSector(
- DstPath, DestinationArcPath->Buffer,
+ SystemRootPath->Buffer, DestinationArcPath->Buffer,
L"Linux", L"\"Linux\"",
- L"hd0", L"1", L"BOOTSECT.OLD");
+ L"hd0", L"1", BootSector);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
}
/* Save current bootsector */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\bootsect.old");
+ CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
- Status = SaveBootSector(SystemRootPath->Buffer, DstPath, sizeof(EXT2_BOOTSECTOR));
+ Status = SaveBootSector(SystemRootPath->Buffer, DstPath, sizeof(BTRFS_BOOTSECTOR));
if (!NT_SUCCESS(Status))
{
DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
}
else
{
- Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer);
+ Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
/* Install new bootsector on the disk */
// if (PartitionType == PARTITION_EXT2)
{
- /* Install EXT2 bootcode */
- CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\ext2.bin");
+ /* Install BTRFS bootcode */
+ CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\btrfs.bin");
- DPRINT1("Install EXT2 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
- Status = InstallExt2BootCodeToDisk(SrcPath, SystemRootPath->Buffer);
+ DPRINT1("Install BTRFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
+ Status = InstallBtrfsBootCodeToDisk(SrcPath, SystemRootPath->Buffer);
if (!NT_SUCCESS(Status))
{
- DPRINT1("InstallExt2BootCodeToDisk() failed (Status %lx)\n", Status);
+ DPRINT1("InstallBtrfsBootCodeToDisk() failed (Status %lx)\n", Status);
return Status;
}
}
PartitionType);
}
- case PARTITION_EXT2:
+ case PARTITION_LINUX:
{
- return InstallExt2BootcodeToPartition(SystemRootPath,
- SourceRootPath,
- DestinationArcPath,
- PartitionType);
+ return InstallBtrfsBootcodeToPartition(SystemRootPath,
+ SourceRootPath,
+ DestinationArcPath,
+ PartitionType);
}
case PARTITION_IFS:
+ DPRINT1("Partitions of type NTFS or HPFS are not supported yet!\n");
break;
default:
{
NTSTATUS Status;
PFILE_SYSTEM FatFS;
- UNICODE_STRING FloppyDevice = RTL_CONSTANT_STRING(L"\\Device\\Floppy0");
+ UNICODE_STRING FloppyDevice = RTL_CONSTANT_STRING(L"\\Device\\Floppy0\\");
WCHAR SrcPath[MAX_PATH];
WCHAR DstPath[MAX_PATH];
/* Copy FreeLoader to the boot partition */
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
-
- RtlStringCchCopyW(DstPath, ARRAYSIZE(DstPath), L"\\Device\\Floppy0\\freeldr.sys");
+ CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, FloppyDevice.Buffer, L"freeldr.sys");
DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
Status = SetupCopyFile(SrcPath, DstPath);
}
/* Create new 'freeldr.ini' */
- RtlStringCchCopyW(DstPath, ARRAYSIZE(DstPath), L"\\Device\\Floppy0\\freeldr.ini");
-
DPRINT("Create new 'freeldr.ini'\n");
- Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer);
+ Status = CreateFreeLoaderIniForReactOS(FloppyDevice.Buffer, DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
return Status;
}
- /* Install FAT12/16 boosector */
+ /* Install FAT12 boosector */
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
-
- RtlStringCchCopyW(DstPath, ARRAYSIZE(DstPath), L"\\Device\\Floppy0");
+ CombinePaths(DstPath, ARRAYSIZE(DstPath), 1, FloppyDevice.Buffer);
DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
Status = InstallFat12BootCodeToFloppy(SrcPath, DstPath);
if (!NT_SUCCESS(Status))
{
- DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
+ DPRINT1("InstallFat12BootCodeToFloppy() failed (Status %lx)\n", Status);
return Status;
}