2003-01-17 13:18:15 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
2017-08-26 11:42:32 +00:00
|
|
|
* PROJECT: ReactOS Setup Library
|
|
|
|
* FILE: base/setup/lib/bootsup.c
|
2003-01-17 13:18:15 +00:00
|
|
|
* PURPOSE: Bootloader support functions
|
2017-05-31 02:03:10 +00:00
|
|
|
* PROGRAMMERS: ...
|
|
|
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
2003-01-17 13:18:15 +00:00
|
|
|
*/
|
|
|
|
|
2017-08-26 11:42:32 +00:00
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
|
|
#include "bldrsup.h"
|
|
|
|
#include "filesup.h"
|
|
|
|
#include "partlist.h"
|
2020-10-17 18:29:47 +00:00
|
|
|
#include "bootcode.h"
|
|
|
|
#include "fsutil.h"
|
2017-08-26 11:42:32 +00:00
|
|
|
|
|
|
|
#include "setuplib.h" // HAXX for IsUnattendedSetup!!
|
|
|
|
|
|
|
|
#include "bootsup.h"
|
2003-01-17 13:18:15 +00:00
|
|
|
|
2010-06-07 21:38:49 +00:00
|
|
|
#define NDEBUG
|
2003-12-01 18:28:54 +00:00
|
|
|
#include <debug.h>
|
2003-01-17 13:18:15 +00:00
|
|
|
|
2017-05-31 02:03:10 +00:00
|
|
|
/*
|
|
|
|
* BIG FIXME!!
|
|
|
|
* ===========
|
|
|
|
*
|
2020-10-17 18:29:47 +00:00
|
|
|
* bootsup.c can 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 manage initializing / adding boot entries into NTLDR
|
|
|
|
* and FREELDR, and installing the latter, and saving the old MBR / boot
|
|
|
|
* sectors in files.
|
2017-05-31 02:03:10 +00:00
|
|
|
*/
|
2010-09-06 01:46:06 +00:00
|
|
|
|
2003-01-17 13:18:15 +00:00
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
|
2017-05-31 02:03:10 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2003-01-17 13:18:15 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
|
|
|
|
static VOID
|
|
|
|
CreateFreeLoaderReactOSEntries(
|
|
|
|
IN PVOID BootStoreHandle,
|
|
|
|
IN PCWSTR ArcPath)
|
2003-01-17 13:18:15 +00:00
|
|
|
{
|
2017-06-08 17:30:23 +00:00
|
|
|
UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
|
|
|
|
PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
|
2017-06-08 02:43:51 +00:00
|
|
|
PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
|
2017-06-08 17:30:23 +00:00
|
|
|
BOOT_STORE_OPTIONS BootOptions;
|
2017-06-08 02:43:51 +00:00
|
|
|
|
2017-06-08 17:30:23 +00:00
|
|
|
BootEntry->Version = FreeLdr;
|
2017-06-08 02:43:51 +00:00
|
|
|
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\"";
|
2023-11-05 08:23:43 +00:00
|
|
|
Options->OsLoadOptions = L"/FASTDETECT";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS"));
|
2017-06-08 02:43:51 +00:00
|
|
|
|
|
|
|
/* ReactOS_Debug */
|
|
|
|
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
|
|
|
|
BootEntry->FriendlyName = L"\"ReactOS (Debug)\"";
|
|
|
|
Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Debug"));
|
2017-06-08 02:43:51 +00:00
|
|
|
|
|
|
|
#ifdef _WINKD_
|
|
|
|
/* ReactOS_VBoxDebug */
|
|
|
|
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_VBoxDebug");
|
2020-06-14 11:49:22 +00:00
|
|
|
BootEntry->FriendlyName = L"\"ReactOS (VBox Debug)\"";
|
2017-06-08 02:43:51 +00:00
|
|
|
Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=VBOX /SOS";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_VBoxDebug"));
|
2017-06-08 02:43:51 +00:00
|
|
|
#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";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_KdSerial"));
|
2017-06-08 02:43:51 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* ReactOS_Screen */
|
|
|
|
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Screen");
|
|
|
|
BootEntry->FriendlyName = L"\"ReactOS (Screen)\"";
|
|
|
|
Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=SCREEN /SOS";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Screen"));
|
2017-06-08 02:43:51 +00:00
|
|
|
|
|
|
|
/* ReactOS_LogFile */
|
|
|
|
// BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_LogFile");
|
|
|
|
BootEntry->FriendlyName = L"\"ReactOS (Log file)\"";
|
|
|
|
Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=FILE /SOS";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_LogFile"));
|
2017-06-08 02:43:51 +00:00
|
|
|
|
|
|
|
/* 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";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Ram"));
|
2017-06-08 02:43:51 +00:00
|
|
|
|
|
|
|
/* 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";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_EMS"));
|
2017-06-08 02:43:51 +00:00
|
|
|
#endif
|
2003-01-17 13:18:15 +00:00
|
|
|
|
|
|
|
|
2021-09-07 20:25:34 +00:00
|
|
|
/* DefaultOS=ReactOS */
|
|
|
|
#if DBG && !defined(_WINKD_)
|
2011-07-20 17:54:28 +00:00
|
|
|
if (IsUnattendedSetup)
|
|
|
|
{
|
2024-05-04 10:47:13 +00:00
|
|
|
BootOptions.NextBootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
|
2011-07-20 17:54:28 +00:00
|
|
|
}
|
|
|
|
else
|
2006-10-30 12:41:17 +00:00
|
|
|
#endif
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2021-09-07 20:25:34 +00:00
|
|
|
#if DBG
|
2024-05-04 10:47:13 +00:00
|
|
|
BootOptions.NextBootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
|
2021-09-07 20:25:34 +00:00
|
|
|
#else
|
2024-05-04 10:47:13 +00:00
|
|
|
BootOptions.NextBootEntryKey = MAKESTRKEY(L"ReactOS");
|
2021-09-07 20:25:34 +00:00
|
|
|
#endif
|
2011-07-20 17:54:28 +00:00
|
|
|
}
|
2003-01-17 13:18:15 +00:00
|
|
|
|
2009-06-17 12:44:05 +00:00
|
|
|
#if DBG
|
2011-07-20 17:54:28 +00:00
|
|
|
if (IsUnattendedSetup)
|
2006-10-30 12:41:17 +00:00
|
|
|
#endif
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Timeout=0 for unattended or non debug */
|
|
|
|
BootOptions.Timeout = 0;
|
2011-07-20 17:54:28 +00:00
|
|
|
}
|
2009-06-17 12:44:05 +00:00
|
|
|
#if DBG
|
2011-07-20 17:54:28 +00:00
|
|
|
else
|
|
|
|
{
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Timeout=10 */
|
|
|
|
BootOptions.Timeout = 10;
|
2011-07-20 17:54:28 +00:00
|
|
|
}
|
2006-04-25 01:31:00 +00:00
|
|
|
#endif
|
2003-01-17 13:18:15 +00:00
|
|
|
|
2024-05-04 10:47:13 +00:00
|
|
|
SetBootStoreOptions(BootStoreHandle, &BootOptions,
|
|
|
|
BOOT_OPTIONS_TIMEOUT | BOOT_OPTIONS_NEXT_BOOTENTRY_KEY);
|
2015-12-30 18:26:42 +00:00
|
|
|
}
|
2008-02-27 20:13:34 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
static NTSTATUS
|
2015-12-30 18:26:42 +00:00
|
|
|
CreateFreeLoaderIniForReactOS(
|
2017-06-08 02:43:51 +00:00
|
|
|
IN PCWSTR IniPath,
|
|
|
|
IN PCWSTR ArcPath)
|
2015-12-30 18:26:42 +00:00
|
|
|
{
|
2017-06-08 02:43:51 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PVOID BootStoreHandle;
|
2015-12-30 18:26:42 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Initialize the INI file and create the common FreeLdr sections */
|
2024-05-04 10:38:07 +00:00
|
|
|
Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr,
|
|
|
|
BS_CreateAlways /* BS_OpenAlways */, BS_ReadWriteAccess);
|
2017-06-08 02:43:51 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
2015-12-30 18:26:42 +00:00
|
|
|
|
|
|
|
/* Add the ReactOS entries */
|
2017-06-08 02:43:51 +00:00
|
|
|
CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
|
2015-12-30 18:26:42 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Close the INI file */
|
2017-06-08 17:30:23 +00:00
|
|
|
CloseBootStore(BootStoreHandle);
|
2015-12-30 18:26:42 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
static NTSTATUS
|
2016-02-02 01:55:05 +00:00
|
|
|
CreateFreeLoaderIniForReactOSAndBootSector(
|
2017-05-31 01:43:12 +00:00
|
|
|
IN PCWSTR IniPath,
|
|
|
|
IN PCWSTR ArcPath,
|
|
|
|
IN PCWSTR Section,
|
|
|
|
IN PCWSTR Description,
|
2024-04-23 15:02:06 +00:00
|
|
|
IN PCWSTR BootPath,
|
2017-05-31 01:43:12 +00:00
|
|
|
IN PCWSTR BootSector)
|
2003-01-30 14:41:45 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
NTSTATUS Status;
|
2017-06-08 02:43:51 +00:00
|
|
|
PVOID BootStoreHandle;
|
2024-04-23 15:02:06 +00:00
|
|
|
UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(BOOTSECTOR_OPTIONS)];
|
2017-06-08 17:30:23 +00:00
|
|
|
PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
|
2024-04-23 15:02:06 +00:00
|
|
|
PBOOTSECTOR_OPTIONS Options = (PBOOTSECTOR_OPTIONS)&BootEntry->OsOptions;
|
|
|
|
WCHAR BootPathBuffer[MAX_PATH] = L"";
|
|
|
|
|
|
|
|
/* Since the BootPath given here is in NT format
|
|
|
|
* (not ARC), we need to hack-generate a mapping */
|
|
|
|
ULONG DiskNumber = 0, PartitionNumber = 0;
|
|
|
|
PCWSTR PathComponent = NULL;
|
|
|
|
|
|
|
|
/* From the NT path, compute the disk, partition and path components */
|
|
|
|
// NOTE: this function doesn't support stuff like \Device\FloppyX ...
|
|
|
|
if (NtPathToDiskPartComponents(BootPath, &DiskNumber, &PartitionNumber, &PathComponent))
|
|
|
|
{
|
|
|
|
DPRINT1("BootPath = '%S' points to disk #%d, partition #%d, path '%S'\n",
|
|
|
|
BootPath, DiskNumber, PartitionNumber, PathComponent);
|
|
|
|
|
|
|
|
/* HACK-build a possible ARC path:
|
|
|
|
* Hard disk path: multi(0)disk(0)rdisk(x)partition(y)[\path] */
|
|
|
|
RtlStringCchPrintfW(BootPathBuffer, _countof(BootPathBuffer),
|
|
|
|
L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
|
|
|
|
DiskNumber, PartitionNumber);
|
|
|
|
if (PathComponent && *PathComponent &&
|
|
|
|
(PathComponent[0] != L'\\' || PathComponent[1]))
|
|
|
|
{
|
|
|
|
RtlStringCchCatW(BootPathBuffer, _countof(BootPathBuffer),
|
|
|
|
PathComponent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PCWSTR Path = BootPath;
|
|
|
|
|
|
|
|
if ((_wcsnicmp(Path, L"\\Device\\Floppy", 14) == 0) &&
|
|
|
|
(Path += 14) && iswdigit(*Path))
|
|
|
|
{
|
|
|
|
DiskNumber = wcstoul(Path, (PWSTR*)&PathComponent, 10);
|
|
|
|
if (PathComponent && *PathComponent && *PathComponent != L'\\')
|
|
|
|
PathComponent = NULL;
|
|
|
|
|
|
|
|
/* HACK-build a possible ARC path:
|
|
|
|
* Floppy disk path: multi(0)disk(0)fdisk(x)[\path] */
|
|
|
|
RtlStringCchPrintfW(BootPathBuffer, _countof(BootPathBuffer),
|
|
|
|
L"multi(0)disk(0)fdisk(%lu)", DiskNumber);
|
|
|
|
if (PathComponent && *PathComponent &&
|
|
|
|
(PathComponent[0] != L'\\' || PathComponent[1]))
|
|
|
|
{
|
|
|
|
RtlStringCchCatW(BootPathBuffer, _countof(BootPathBuffer),
|
|
|
|
PathComponent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* HACK: Just keep the unresolved NT path and hope for the best... */
|
|
|
|
|
|
|
|
/* Remove any trailing backslash if needed */
|
|
|
|
UNICODE_STRING RootPartition;
|
|
|
|
RtlInitUnicodeString(&RootPartition, BootPath);
|
|
|
|
TrimTrailingPathSeparators_UStr(&RootPartition);
|
|
|
|
|
|
|
|
/* RootPartition is BootPath without counting any trailing
|
|
|
|
* path separator. Because of this, we need to copy the string
|
|
|
|
* in the buffer, instead of just using a pointer to it. */
|
|
|
|
RtlStringCchPrintfW(BootPathBuffer, _countof(BootPathBuffer),
|
|
|
|
L"%wZ", &RootPartition);
|
|
|
|
|
|
|
|
DPRINT1("Unhandled NT path '%S'\n", BootPath);
|
|
|
|
}
|
|
|
|
}
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Initialize the INI file and create the common FreeLdr sections */
|
2024-05-04 10:38:07 +00:00
|
|
|
Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr,
|
|
|
|
BS_CreateAlways /* BS_OpenAlways */, BS_ReadWriteAccess);
|
2003-01-30 14:41:45 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
2003-01-30 14:41:45 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Add the ReactOS entries */
|
|
|
|
CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2017-06-08 17:30:23 +00:00
|
|
|
BootEntry->Version = FreeLdr;
|
2017-06-08 02:43:51 +00:00
|
|
|
BootEntry->BootFilePath = NULL;
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
BootEntry->OsOptionsLength = sizeof(BOOTSECTOR_OPTIONS);
|
2017-06-08 02:43:51 +00:00
|
|
|
RtlCopyMemory(Options->Signature,
|
2024-04-23 15:02:06 +00:00
|
|
|
BOOTSECTOR_OPTIONS_SIGNATURE,
|
|
|
|
RTL_FIELD_SIZE(BOOTSECTOR_OPTIONS, Signature));
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Options->BootPath = BootPathBuffer;
|
|
|
|
Options->FileName = BootSector;
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
// BootEntry->BootEntryKey = MAKESTRKEY(Section);
|
|
|
|
BootEntry->FriendlyName = Description;
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Section));
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Close the INI file */
|
2017-06-08 17:30:23 +00:00
|
|
|
CloseBootStore(BootStoreHandle);
|
2011-07-20 17:54:28 +00:00
|
|
|
return STATUS_SUCCESS;
|
2003-01-28 17:29:22 +00:00
|
|
|
}
|
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
//
|
|
|
|
// 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".
|
|
|
|
//
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
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(
|
2017-06-08 17:30:23 +00:00
|
|
|
IN BOOT_STORE_TYPE Type,
|
|
|
|
IN PBOOT_STORE_ENTRY BootEntry,
|
2017-06-08 02:43:51 +00:00
|
|
|
IN PVOID Parameter OPTIONAL)
|
|
|
|
{
|
2017-12-23 19:17:38 +00:00
|
|
|
NTSTATUS Status;
|
2017-06-08 02:43:51 +00:00
|
|
|
PENUM_REACTOS_ENTRIES_DATA Data = (PENUM_REACTOS_ENTRIES_DATA)Parameter;
|
|
|
|
PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
|
|
|
|
WCHAR SystemPath[MAX_PATH];
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* We have a boot entry */
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* 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))
|
2017-05-31 01:47:39 +00:00
|
|
|
{
|
2017-06-08 02:43:51 +00:00
|
|
|
/* This is not a ReactOS entry */
|
2018-10-28 22:33:29 +00:00
|
|
|
// DPRINT(" An installation '%S' of unsupported type '%S'\n",
|
|
|
|
// BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a");
|
|
|
|
DPRINT(" An installation '%S' of unsupported type %lu\n",
|
|
|
|
BootEntry->FriendlyName, BootEntry->OsOptionsLength);
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Continue the enumeration */
|
|
|
|
goto SkipThisEntry;
|
2017-05-31 01:47:39 +00:00
|
|
|
}
|
2017-06-08 02:43:51 +00:00
|
|
|
|
|
|
|
/* BootType is Windows2003, now check OsLoadPath */
|
|
|
|
if (!Options->OsLoadPath || !*Options->OsLoadPath)
|
2017-05-31 01:47:39 +00:00
|
|
|
{
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Certainly not a ReactOS installation */
|
|
|
|
DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName);
|
|
|
|
/* Continue the enumeration */
|
|
|
|
goto SkipThisEntry;
|
2017-05-31 01:47:39 +00:00
|
|
|
}
|
|
|
|
|
2017-12-23 19:17:38 +00:00
|
|
|
if (_wcsicmp(Options->OsLoadPath, Data->ArcPath) != 0)
|
2017-05-31 01:47:39 +00:00
|
|
|
{
|
2017-12-23 19:17:38 +00:00
|
|
|
/* Not found, retry with a quoted path */
|
|
|
|
Status = RtlStringCchPrintfW(SystemPath, ARRAYSIZE(SystemPath), L"\"%s\"", Data->ArcPath);
|
|
|
|
if (!NT_SUCCESS(Status) || _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;
|
|
|
|
}
|
2017-05-31 01:47:39 +00:00
|
|
|
}
|
|
|
|
|
2018-10-28 22:33:29 +00:00
|
|
|
DPRINT(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n",
|
|
|
|
BootEntry->FriendlyName, Options->OsLoadPath);
|
|
|
|
// DPRINT(" Found a Win2k3 install '%S' with ARC path '%S'\n",
|
|
|
|
// BootEntry->FriendlyName, Options->OsLoadPath);
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2018-10-28 22:33:29 +00:00
|
|
|
DPRINT("EnumerateReactOSEntries: OsLoadPath: '%S'\n", Options->OsLoadPath);
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
Data->UseExistingEntry = TRUE;
|
|
|
|
RtlStringCchCopyW(Data->OsName, ARRAYSIZE(Data->OsName), BootEntry->FriendlyName);
|
|
|
|
|
|
|
|
/* 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)
|
2017-05-31 01:47:39 +00:00
|
|
|
{
|
2017-06-08 02:43:51 +00:00
|
|
|
RtlStringCchPrintfW(Data->SectionName, ARRAYSIZE(Data->SectionName),
|
|
|
|
L"ReactOS_%lu", Data->i);
|
|
|
|
RtlStringCchPrintfW(Data->OsName, ARRAYSIZE(Data->OsName),
|
|
|
|
L"\"ReactOS %lu\"", Data->i);
|
|
|
|
Data->i++;
|
2017-05-31 01:47:39 +00:00
|
|
|
}
|
2017-06-08 02:43:51 +00:00
|
|
|
return STATUS_SUCCESS;
|
2017-05-31 01:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
NTSTATUS
|
2017-06-08 02:43:51 +00:00
|
|
|
UpdateFreeLoaderIni(
|
|
|
|
IN PCWSTR IniPath,
|
|
|
|
IN PCWSTR ArcPath)
|
2017-05-31 01:47:39 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2017-06-08 02:43:51 +00:00
|
|
|
PVOID BootStoreHandle;
|
|
|
|
ENUM_REACTOS_ENTRIES_DATA Data;
|
2017-06-08 17:30:23 +00:00
|
|
|
UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
|
|
|
|
PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
|
2017-06-08 02:43:51 +00:00
|
|
|
PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
|
|
|
|
|
|
|
|
/* Open the INI file */
|
2024-05-04 10:38:07 +00:00
|
|
|
Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr,
|
|
|
|
BS_OpenExisting /* BS_OpenAlways */, BS_ReadWriteAccess);
|
2017-06-08 02:43:51 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Find an existing usable or an unused section name */
|
|
|
|
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\"");
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
//
|
2017-06-08 17:30:23 +00:00
|
|
|
// FIXME: We temporarily use EnumerateBootStoreEntries, until
|
|
|
|
// both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
|
2017-06-08 02:43:51 +00:00
|
|
|
//
|
2017-06-08 17:30:23 +00:00
|
|
|
Status = EnumerateBootStoreEntries(BootStoreHandle, EnumerateReactOSEntries, &Data);
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Create a new "ReactOS" entry if there is none already existing that suits us */
|
|
|
|
if (!Data.UseExistingEntry)
|
2017-05-31 01:47:39 +00:00
|
|
|
{
|
2017-06-08 02:43:51 +00:00
|
|
|
// RtlStringCchPrintfW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS_%lu", Data.i);
|
|
|
|
// RtlStringCchPrintfW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS %lu\"", Data.i);
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 17:30:23 +00:00
|
|
|
BootEntry->Version = FreeLdr;
|
2017-06-08 02:43:51 +00:00
|
|
|
BootEntry->BootFilePath = NULL;
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
|
|
|
|
RtlCopyMemory(Options->Signature,
|
|
|
|
NTOS_OPTIONS_SIGNATURE,
|
|
|
|
RTL_FIELD_SIZE(NTOS_OPTIONS, Signature));
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
Options->OsLoadPath = ArcPath;
|
|
|
|
|
|
|
|
// BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
|
|
|
|
BootEntry->FriendlyName = Data.OsName;
|
|
|
|
Options->OsLoadOptions = NULL; // L"";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Data.SectionName));
|
2017-05-31 01:47:39 +00:00
|
|
|
}
|
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Close the INI file */
|
2017-06-08 17:30:23 +00:00
|
|
|
CloseBootStore(BootStoreHandle);
|
2017-06-08 02:43:51 +00:00
|
|
|
return STATUS_SUCCESS;
|
2017-05-31 01:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
UpdateBootIni(
|
2017-06-08 02:43:51 +00:00
|
|
|
IN PCWSTR IniPath,
|
|
|
|
IN PCWSTR EntryName, // ~= ArcPath
|
|
|
|
IN PCWSTR EntryValue)
|
2017-05-31 01:47:39 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2017-06-08 02:43:51 +00:00
|
|
|
PVOID BootStoreHandle;
|
|
|
|
ENUM_REACTOS_ENTRIES_DATA Data;
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
// NOTE: Technically it would be "BootSector"...
|
2017-06-08 17:30:23 +00:00
|
|
|
UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
|
|
|
|
PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
|
2017-06-08 02:43:51 +00:00
|
|
|
PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
|
2017-05-31 01:47:39 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Open the INI file */
|
2024-05-04 10:38:07 +00:00
|
|
|
Status = OpenBootStore(&BootStoreHandle, IniPath, NtLdr,
|
|
|
|
BS_OpenExisting /* BS_OpenAlways */, BS_ReadWriteAccess);
|
2017-05-31 01:47:39 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* 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\"");
|
|
|
|
|
|
|
|
//
|
2017-06-08 17:30:23 +00:00
|
|
|
// FIXME: We temporarily use EnumerateBootStoreEntries, until
|
|
|
|
// both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
|
2017-06-08 02:43:51 +00:00
|
|
|
//
|
2017-06-08 17:30:23 +00:00
|
|
|
Status = EnumerateBootStoreEntries(BootStoreHandle, EnumerateReactOSEntries, &Data);
|
2017-06-08 02:43:51 +00:00
|
|
|
|
|
|
|
/* 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) ) */)
|
|
|
|
{
|
2017-06-08 17:30:23 +00:00
|
|
|
BootEntry->Version = NtLdr;
|
2017-06-08 02:43:51 +00:00
|
|
|
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"";
|
2017-06-08 17:30:23 +00:00
|
|
|
AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(0 /*Data.SectionName*/));
|
2017-06-08 02:43:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Close the INI file */
|
2017-06-08 17:30:23 +00:00
|
|
|
CloseBootStore(BootStoreHandle);
|
2017-06-08 02:43:51 +00:00
|
|
|
return STATUS_SUCCESS; // Status;
|
2017-05-31 01:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-08-26 11:42:32 +00:00
|
|
|
static
|
2016-02-02 01:55:05 +00:00
|
|
|
BOOLEAN
|
2017-05-31 02:03:10 +00:00
|
|
|
IsThereAValidBootSector(
|
|
|
|
IN PCWSTR RootPath)
|
2016-02-02 01:55:05 +00:00
|
|
|
{
|
|
|
|
/*
|
2017-05-09 15:31:53 +00:00
|
|
|
* 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.
|
2016-02-02 01:55:05 +00:00
|
|
|
*/
|
2017-05-31 02:03:10 +00:00
|
|
|
|
2017-05-09 15:31:53 +00:00
|
|
|
BOOLEAN IsValid = FALSE;
|
2016-02-02 01:55:05 +00:00
|
|
|
NTSTATUS Status;
|
2017-05-31 02:03:10 +00:00
|
|
|
UNICODE_STRING RootPartition;
|
2020-10-17 18:29:47 +00:00
|
|
|
BOOTCODE BootSector = {0};
|
2016-02-02 01:55:05 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Allocate and read the root partition bootsector.
|
|
|
|
* Remove any trailing backslash if needed. */
|
2017-05-31 02:03:10 +00:00
|
|
|
RtlInitUnicodeString(&RootPartition, RootPath);
|
|
|
|
TrimTrailingPathSeparators_UStr(&RootPartition);
|
2020-10-17 18:29:47 +00:00
|
|
|
Status = ReadBootCodeFromFile(&BootSector, &RootPartition, SECTORSIZE);
|
2017-05-09 15:31:53 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2020-10-17 18:29:47 +00:00
|
|
|
return FALSE;
|
2016-02-02 01:55:05 +00:00
|
|
|
|
2017-12-24 21:37:19 +00:00
|
|
|
/* Check for the existence of the bootsector signature */
|
2020-10-17 18:29:47 +00:00
|
|
|
IsValid = (*(PUSHORT)((PUCHAR)BootSector.BootCode + 0x1FE) == 0xAA55);
|
2017-12-24 21:37:19 +00:00
|
|
|
if (IsValid)
|
|
|
|
{
|
|
|
|
/* Check for the first instruction encoded on three bytes */
|
2020-10-17 18:29:47 +00:00
|
|
|
IsValid = (((*(PULONG)BootSector.BootCode) & 0x00FFFFFF) != 0x00000000);
|
2017-12-24 21:37:19 +00:00
|
|
|
}
|
2017-05-09 15:31:53 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Free the bootsector and return */
|
|
|
|
FreeBootCode(&BootSector);
|
2017-12-24 21:37:19 +00:00
|
|
|
return IsValid;
|
2016-02-02 01:55:05 +00:00
|
|
|
}
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2017-08-26 11:42:32 +00:00
|
|
|
static
|
2003-04-05 15:36:34 +00:00
|
|
|
NTSTATUS
|
[USETUP]
- bootsup.c/.h, usetup.c: Save the old MBR sector in the system partition (this makes easier to restore the old one).
- fslist.c/.h, usetup.h: Fix header inclusion order.
- partlist.c/.h, usetup.c: On BIOS-PC architectures, the system partition can be formatted in any FS as long as it is the active partition (on the contrary, on architectures where such system partition is required, it is formatted in FAT). We currently do not have write support for all FSes out there (apart for FAT until now), so do a "clever" "trick" to work around this problem: on initialized disks, find the active partition and check its FS. If we support write access to this FS then we're OK, otherwise we change the (active) system partition for the one on which we are going to install ReactOS (which is, by construction, formatted with a FS on which we support write access).
The MBR (resp. the VBR) of the disk (resp. of the system partition) are always saved into files, making easy for people to boot on them (using FreeLdr) or restoring them.
CORE-10898
svn path=/trunk/; revision=70837
2016-03-01 15:00:56 +00:00
|
|
|
SaveBootSector(
|
2017-05-31 02:03:10 +00:00
|
|
|
IN PCWSTR RootPath,
|
|
|
|
IN PCWSTR DstPath,
|
|
|
|
IN ULONG Length)
|
2003-04-05 15:36:34 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
UNICODE_STRING Name;
|
2010-09-06 01:46:06 +00:00
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
HANDLE FileHandle;
|
2020-10-17 18:29:47 +00:00
|
|
|
// LARGE_INTEGER FileOffset;
|
|
|
|
BOOTCODE BootSector = {0};
|
2003-04-05 15:36:34 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Allocate and read the root partition bootsector.
|
|
|
|
* Remove any trailing backslash if needed. */
|
2011-07-20 17:54:28 +00:00
|
|
|
RtlInitUnicodeString(&Name, RootPath);
|
2017-05-31 02:03:10 +00:00
|
|
|
TrimTrailingPathSeparators_UStr(&Name);
|
2020-10-17 18:29:47 +00:00
|
|
|
Status = ReadBootCodeFromFile(&BootSector, &Name, Length);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Write the bootsector to DstPath */
|
2011-07-20 17:54:28 +00:00
|
|
|
RtlInitUnicodeString(&Name, DstPath);
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&Name,
|
2017-12-23 19:17:38 +00:00
|
|
|
OBJ_CASE_INSENSITIVE,
|
2011-07-20 17:54:28 +00:00
|
|
|
NULL,
|
|
|
|
NULL);
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2011-07-20 17:54:28 +00:00
|
|
|
Status = NtCreateFile(&FileHandle,
|
2013-07-19 14:03:46 +00:00
|
|
|
GENERIC_WRITE | SYNCHRONIZE,
|
2011-07-20 17:54:28 +00:00
|
|
|
&ObjectAttributes,
|
|
|
|
&IoStatusBlock,
|
|
|
|
NULL,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
|
|
0,
|
|
|
|
FILE_SUPERSEDE,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
|
|
|
|
NULL,
|
|
|
|
0);
|
2003-01-28 17:29:22 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
FreeBootCode(&BootSector);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2011-07-20 17:54:28 +00:00
|
|
|
Status = NtWriteFile(FileHandle,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&IoStatusBlock,
|
2020-10-17 18:29:47 +00:00
|
|
|
BootSector.BootCode,
|
|
|
|
BootSector.Length,
|
2011-07-20 17:54:28 +00:00
|
|
|
NULL,
|
|
|
|
NULL);
|
2003-01-28 17:29:22 +00:00
|
|
|
NtClose(FileHandle);
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Free the bootsector and return */
|
|
|
|
FreeBootCode(&BootSector);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
2003-01-28 17:29:22 +00:00
|
|
|
}
|
|
|
|
|
2017-08-26 11:42:32 +00:00
|
|
|
|
|
|
|
static
|
2003-01-28 17:29:22 +00:00
|
|
|
NTSTATUS
|
2020-10-17 18:29:47 +00:00
|
|
|
InstallBootCodeToDisk(
|
2017-05-31 02:03:10 +00:00
|
|
|
IN PCWSTR SrcPath,
|
2020-10-17 18:29:47 +00:00
|
|
|
IN PCWSTR RootPath,
|
|
|
|
IN PFS_INSTALL_BOOTCODE InstallBootCode)
|
2003-01-28 17:29:22 +00:00
|
|
|
{
|
2020-12-03 16:13:38 +00:00
|
|
|
NTSTATUS Status, LockStatus;
|
2016-02-02 01:55:05 +00:00
|
|
|
UNICODE_STRING Name;
|
2011-07-20 17:54:28 +00:00
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
2020-10-17 18:29:47 +00:00
|
|
|
HANDLE PartitionHandle;
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/*
|
|
|
|
* Open the root partition from which the bootcode (MBR, VBR) parameters
|
|
|
|
* will be obtained; this is also where we will write the updated bootcode.
|
|
|
|
* Remove any trailing backslash if needed.
|
|
|
|
*/
|
2017-05-31 02:03:10 +00:00
|
|
|
RtlInitUnicodeString(&Name, RootPath);
|
|
|
|
TrimTrailingPathSeparators_UStr(&Name);
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2011-07-20 17:54:28 +00:00
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&Name,
|
|
|
|
OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
Status = NtOpenFile(&PartitionHandle,
|
|
|
|
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
|
2011-07-20 17:54:28 +00:00
|
|
|
&ObjectAttributes,
|
|
|
|
&IoStatusBlock,
|
2018-11-11 16:14:13 +00:00
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
2020-10-17 18:29:47 +00:00
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
2003-01-28 17:29:22 +00:00
|
|
|
|
2020-12-03 16:13:38 +00:00
|
|
|
/* Lock the volume */
|
|
|
|
LockStatus = NtFsControlFile(PartitionHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0);
|
|
|
|
if (!NT_SUCCESS(LockStatus))
|
|
|
|
{
|
|
|
|
DPRINT1("Unable to lock the volume before installing boot code. Status 0x%08x. Expect problems.\n", LockStatus);
|
|
|
|
}
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Install the bootcode (MBR, VBR) */
|
|
|
|
Status = InstallBootCode(SrcPath, PartitionHandle, PartitionHandle);
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2020-12-03 16:13:38 +00:00
|
|
|
/* dismount & Unlock the volume */
|
|
|
|
if (NT_SUCCESS(LockStatus))
|
|
|
|
{
|
|
|
|
LockStatus = NtFsControlFile(PartitionHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0);
|
|
|
|
if (!NT_SUCCESS(LockStatus))
|
|
|
|
{
|
2021-02-05 13:10:15 +00:00
|
|
|
DPRINT1("Unable to dismount the volume after installing boot code. Status 0x%08x. Expect problems.\n", LockStatus);
|
2020-12-03 16:13:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LockStatus = NtFsControlFile(PartitionHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0);
|
|
|
|
if (!NT_SUCCESS(LockStatus))
|
|
|
|
{
|
|
|
|
DPRINT1("Unable to unlock the volume after installing boot code. Status 0x%08x. Expect problems.\n", LockStatus);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Close the partition */
|
|
|
|
NtClose(PartitionHandle);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
InstallBootCodeToFile(
|
|
|
|
IN PCWSTR SrcPath,
|
|
|
|
IN PCWSTR DstPath,
|
|
|
|
IN PCWSTR RootPath,
|
|
|
|
IN PFS_INSTALL_BOOTCODE InstallBootCode)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
UNICODE_STRING Name;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
HANDLE PartitionHandle, FileHandle;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Open the root partition from which the bootcode (MBR, VBR)
|
|
|
|
* 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);
|
2004-06-23 14:09:55 +00:00
|
|
|
|
2011-07-20 17:54:28 +00:00
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&Name,
|
|
|
|
OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
Status = NtOpenFile(&PartitionHandle,
|
2013-07-19 14:03:46 +00:00
|
|
|
GENERIC_READ | SYNCHRONIZE,
|
2011-07-20 17:54:28 +00:00
|
|
|
&ObjectAttributes,
|
|
|
|
&IoStatusBlock,
|
2020-10-17 18:29:47 +00:00
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Open or create the file where the new bootsector will be saved */
|
|
|
|
RtlInitUnicodeString(&Name, DstPath);
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&Name,
|
|
|
|
OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
Status = NtCreateFile(&FileHandle,
|
|
|
|
GENERIC_WRITE | SYNCHRONIZE,
|
|
|
|
&ObjectAttributes,
|
|
|
|
&IoStatusBlock,
|
|
|
|
NULL,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
|
|
0,
|
|
|
|
FILE_SUPERSEDE, // FILE_OVERWRITE_IF
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
|
|
|
|
NULL,
|
|
|
|
0);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
|
|
|
|
NtClose(PartitionHandle);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Install the bootcode (MBR, VBR) */
|
|
|
|
Status = InstallBootCode(SrcPath, FileHandle, PartitionHandle);
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Close the file and the partition */
|
|
|
|
NtClose(FileHandle);
|
|
|
|
NtClose(PartitionHandle);
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
return Status;
|
|
|
|
}
|
2011-07-20 17:54:28 +00:00
|
|
|
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
InstallMbrBootCode(
|
|
|
|
IN PCWSTR SrcPath, // MBR source file (on the installation medium)
|
|
|
|
IN HANDLE DstPath, // Where to save the bootsector built from the source + disk information
|
|
|
|
IN HANDLE DiskHandle) // Disk holding the (old) MBR information
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
UNICODE_STRING Name;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
LARGE_INTEGER FileOffset;
|
|
|
|
BOOTCODE OrigBootSector = {0};
|
|
|
|
BOOTCODE NewBootSector = {0};
|
|
|
|
|
|
|
|
C_ASSERT(sizeof(PARTITION_SECTOR) == SECTORSIZE);
|
|
|
|
|
|
|
|
/* Allocate and read the current original MBR bootsector */
|
|
|
|
Status = ReadBootCodeByHandle(&OrigBootSector,
|
|
|
|
DiskHandle,
|
|
|
|
sizeof(PARTITION_SECTOR));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
/* Allocate and read the new bootsector from SrcPath */
|
|
|
|
RtlInitUnicodeString(&Name, SrcPath);
|
|
|
|
Status = ReadBootCodeFromFile(&NewBootSector,
|
|
|
|
&Name,
|
|
|
|
sizeof(PARTITION_SECTOR));
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
FreeBootCode(&OrigBootSector);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/*
|
|
|
|
* Copy the disk signature, the reserved fields and
|
|
|
|
* the partition table from the old MBR to the new one.
|
|
|
|
*/
|
|
|
|
RtlCopyMemory(&((PPARTITION_SECTOR)NewBootSector.BootCode)->Signature,
|
|
|
|
&((PPARTITION_SECTOR)OrigBootSector.BootCode)->Signature,
|
|
|
|
sizeof(PARTITION_SECTOR) -
|
|
|
|
FIELD_OFFSET(PARTITION_SECTOR, Signature)
|
|
|
|
/* Length of partition table */);
|
|
|
|
|
|
|
|
/* Free the original bootsector */
|
|
|
|
FreeBootCode(&OrigBootSector);
|
|
|
|
|
|
|
|
/* Write the new bootsector to DstPath */
|
2017-05-31 01:47:39 +00:00
|
|
|
FileOffset.QuadPart = 0ULL;
|
2020-10-17 18:29:47 +00:00
|
|
|
Status = NtWriteFile(DstPath,
|
2011-07-20 17:54:28 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&IoStatusBlock,
|
2020-10-17 18:29:47 +00:00
|
|
|
NewBootSector.BootCode,
|
|
|
|
NewBootSector.Length,
|
2017-05-31 01:47:39 +00:00
|
|
|
&FileOffset,
|
2011-07-20 17:54:28 +00:00
|
|
|
NULL);
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Free the new bootsector */
|
|
|
|
FreeBootCode(&NewBootSector);
|
2011-07-20 17:54:28 +00:00
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2017-08-26 11:42:32 +00:00
|
|
|
NTSTATUS
|
|
|
|
InstallMbrBootCodeToDisk(
|
|
|
|
IN PUNICODE_STRING SystemRootPath,
|
|
|
|
IN PUNICODE_STRING SourceRootPath,
|
|
|
|
IN PCWSTR DestinationDevicePathBuffer)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
WCHAR SourceMbrPathBuffer[MAX_PATH];
|
|
|
|
WCHAR DstPath[MAX_PATH];
|
|
|
|
|
|
|
|
#if 0
|
2017-12-23 19:17:38 +00:00
|
|
|
/*
|
|
|
|
* The DestinationDevicePathBuffer parameter has been built with
|
|
|
|
* the following instruction by the caller; I'm not yet sure whether
|
|
|
|
* I actually want this function to build the path instead, hence
|
|
|
|
* I keep this code here but disabled for now...
|
|
|
|
*/
|
2017-08-26 11:42:32 +00:00
|
|
|
WCHAR DestinationDevicePathBuffer[MAX_PATH];
|
2017-09-03 20:05:11 +00:00
|
|
|
RtlStringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer),
|
|
|
|
L"\\Device\\Harddisk%d\\Partition0",
|
|
|
|
DiskNumber);
|
2017-08-26 11:42:32 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2,
|
|
|
|
SourceRootPath->Buffer, L"\\loader\\dosmbr.bin");
|
|
|
|
|
|
|
|
if (IsThereAValidBootSector(DestinationDevicePathBuffer))
|
|
|
|
{
|
|
|
|
/* Save current MBR */
|
|
|
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2,
|
|
|
|
SystemRootPath->Buffer, L"mbr.old");
|
|
|
|
|
|
|
|
DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer, DstPath);
|
|
|
|
Status = SaveBootSector(DestinationDevicePathBuffer, DstPath, sizeof(PARTITION_SECTOR));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
|
|
|
|
// Don't care if we succeeded or not saving the old MBR, just go ahead.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT1("Install MBR bootcode: %S ==> %S\n",
|
|
|
|
SourceMbrPathBuffer, DestinationDevicePathBuffer);
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Install the MBR */
|
|
|
|
return InstallBootCodeToDisk(SourceMbrPathBuffer,
|
|
|
|
DestinationDevicePathBuffer,
|
|
|
|
InstallMbrBootCode);
|
2017-08-26 11:42:32 +00:00
|
|
|
}
|
|
|
|
|
2017-05-31 02:03:10 +00:00
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
static
|
2011-07-20 17:54:28 +00:00
|
|
|
NTSTATUS
|
2020-10-17 18:29:47 +00:00
|
|
|
InstallFatBootcodeToPartition(
|
|
|
|
IN PUNICODE_STRING SystemRootPath,
|
|
|
|
IN PUNICODE_STRING SourceRootPath,
|
|
|
|
IN PUNICODE_STRING DestinationArcPath,
|
2020-10-19 21:49:26 +00:00
|
|
|
IN PCWSTR FileSystemName)
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
NTSTATUS Status;
|
2020-10-17 18:29:47 +00:00
|
|
|
BOOLEAN DoesFreeLdrExist;
|
|
|
|
WCHAR SrcPath[MAX_PATH];
|
|
|
|
WCHAR DstPath[MAX_PATH];
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* FAT or FAT32 partition */
|
|
|
|
DPRINT("System path: '%wZ'\n", SystemRootPath);
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* 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");
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
|
|
|
|
Status = SetupCopyFile(SrcPath, DstPath, FALSE);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Prepare for possibly updating 'freeldr.ini' */
|
|
|
|
DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
|
|
|
|
if (DoesFreeLdrExist)
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Update existing 'freeldr.ini' */
|
|
|
|
DPRINT1("Update existing 'freeldr.ini'\n");
|
|
|
|
Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2011-07-20 17:54:28 +00:00
|
|
|
}
|
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Check for NT and other bootloaders */
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
// FIXME: Check for Vista+ bootloader!
|
|
|
|
/*** 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)
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Search root directory for 'NTLDR' and 'BOOT.INI' */
|
|
|
|
DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
|
2016-02-02 01:55:05 +00:00
|
|
|
|
|
|
|
/* Create or update 'freeldr.ini' */
|
|
|
|
if (DoesFreeLdrExist == FALSE)
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
|
|
|
/* Create new 'freeldr.ini' */
|
|
|
|
DPRINT1("Create new 'freeldr.ini'\n");
|
2017-06-08 02:43:51 +00:00
|
|
|
Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2015-04-18 09:21:51 +00:00
|
|
|
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
/* Install new bootcode into a file */
|
2017-05-31 01:43:12 +00:00
|
|
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"bootsect.ros");
|
2016-02-02 01:55:05 +00:00
|
|
|
|
2024-05-11 16:23:44 +00:00
|
|
|
if (_wcsicmp(FileSystemName, L"FAT32") == 0)
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
|
|
|
/* Install FAT32 bootcode */
|
2017-05-23 22:30:54 +00:00
|
|
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin");
|
2011-07-20 17:54:28 +00:00
|
|
|
|
|
|
|
DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath);
|
2020-10-17 18:29:47 +00:00
|
|
|
Status = InstallBootCodeToFile(SrcPath, DstPath,
|
|
|
|
SystemRootPath->Buffer,
|
|
|
|
InstallFat32BootCode);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT1("InstallBootCodeToFile(FAT32) failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
2020-10-19 21:49:26 +00:00
|
|
|
else // if (wcsicmp(FileSystemName, L"FAT") == 0)
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
|
|
|
/* Install FAT16 bootcode */
|
2017-05-23 22:30:54 +00:00
|
|
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, DstPath);
|
|
|
|
Status = InstallBootCodeToFile(SrcPath, DstPath,
|
|
|
|
SystemRootPath->Buffer,
|
|
|
|
InstallFat16BootCode);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT1("InstallBootCodeToFile(FAT16) failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update 'boot.ini' */
|
2018-08-28 10:45:03 +00:00
|
|
|
/* 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. */
|
2017-06-08 02:43:51 +00:00
|
|
|
DPRINT1("Update 'boot.ini'\n");
|
|
|
|
Status = UpdateBootIni(SystemRootPath->Buffer,
|
2011-07-20 17:54:28 +00:00
|
|
|
L"C:\\bootsect.ros",
|
|
|
|
L"\"ReactOS\"");
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
2016-02-02 01:55:05 +00:00
|
|
|
else
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
/* Non-NT bootloaders: install our own bootloader */
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2017-05-31 01:43:12 +00:00
|
|
|
PCWSTR Section;
|
|
|
|
PCWSTR Description;
|
|
|
|
PCWSTR BootSector;
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2017-05-31 01:43:12 +00:00
|
|
|
/* 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");
|
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Section = L"CPQDOS";
|
|
|
|
Description = L"\"COMPAQ MS-DOS 1.x / MS-DOS 1.25\"";
|
|
|
|
BootSector = L"BOOTSECT.DOS";
|
2017-05-31 01:43:12 +00:00
|
|
|
}
|
|
|
|
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
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
|
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Section = L"MSDOS";
|
|
|
|
Description = L"\"MS-DOS/Windows\"";
|
|
|
|
BootSector = L"BOOTSECT.DOS";
|
2017-05-31 01:43:12 +00:00
|
|
|
}
|
|
|
|
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");
|
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Section = L"IBMDOS";
|
|
|
|
Description = L"\"IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\"";
|
|
|
|
BootSector = L"BOOTSECT.DOS";
|
2017-05-31 01:43:12 +00:00
|
|
|
}
|
|
|
|
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");
|
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Section = L"DRDOS";
|
|
|
|
Description = L"\"DR-DOS 3.x\"";
|
|
|
|
BootSector = L"BOOTSECT.DOS";
|
2017-05-31 01:43:12 +00:00
|
|
|
}
|
|
|
|
else
|
2017-06-06 23:44:56 +00:00
|
|
|
/* 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");
|
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Section = L"DRMK";
|
|
|
|
Description = L"\"Dell Real-Mode Kernel OS\"";
|
|
|
|
BootSector = L"BOOTSECT.DOS";
|
2017-06-06 23:44:56 +00:00
|
|
|
}
|
|
|
|
else
|
2017-05-31 01:43:12 +00:00
|
|
|
/* 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");
|
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Section = L"MSOS2";
|
|
|
|
Description = L"\"MS OS/2 1.x\"";
|
|
|
|
BootSector = L"BOOTSECT.OS2";
|
2017-05-31 01:43:12 +00:00
|
|
|
}
|
|
|
|
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");
|
2016-02-02 01:55:05 +00:00
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Section = L"IBMOS2";
|
|
|
|
Description = L"\"MS/IBM OS/2\"";
|
|
|
|
BootSector = L"BOOTSECT.OS2";
|
2016-02-02 01:55:05 +00:00
|
|
|
}
|
|
|
|
else
|
2017-05-31 01:43:12 +00:00
|
|
|
/* Search for FreeDOS boot loader */
|
2017-05-24 16:37:49 +00:00
|
|
|
if (DoesFileExist_2(SystemRootPath->Buffer, L"kernel.sys") == TRUE)
|
2016-02-02 01:55:05 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Found FreeDOS boot loader\n");
|
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Section = L"FDOS";
|
|
|
|
Description = L"\"FreeDOS\"";
|
|
|
|
BootSector = L"BOOTSECT.DOS";
|
2016-02-02 01:55:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No or unknown boot loader */
|
|
|
|
DPRINT1("No or unknown boot loader found\n");
|
|
|
|
|
2024-04-23 15:02:06 +00:00
|
|
|
Section = L"Unknown";
|
|
|
|
Description = L"\"Unknown Operating System\"";
|
|
|
|
BootSector = L"BOOTSECT.OLD";
|
2011-07-20 17:54:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create or update 'freeldr.ini' */
|
2016-02-02 01:55:05 +00:00
|
|
|
if (DoesFreeLdrExist == FALSE)
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
|
|
|
/* Create new 'freeldr.ini' */
|
|
|
|
DPRINT1("Create new 'freeldr.ini'\n");
|
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
if (IsThereAValidBootSector(SystemRootPath->Buffer))
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
Status = CreateFreeLoaderIniForReactOSAndBootSector(
|
2017-06-08 02:43:51 +00:00
|
|
|
SystemRootPath->Buffer, DestinationArcPath->Buffer,
|
2016-02-02 01:55:05 +00:00
|
|
|
Section, Description,
|
2024-04-23 15:02:06 +00:00
|
|
|
SystemRootPath->Buffer, BootSector);
|
2016-02-02 01:55:05 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
/* Save current bootsector */
|
2017-05-31 01:43:12 +00:00
|
|
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
|
[USETUP]
- bootsup.c/.h, usetup.c: Save the old MBR sector in the system partition (this makes easier to restore the old one).
- fslist.c/.h, usetup.h: Fix header inclusion order.
- partlist.c/.h, usetup.c: On BIOS-PC architectures, the system partition can be formatted in any FS as long as it is the active partition (on the contrary, on architectures where such system partition is required, it is formatted in FAT). We currently do not have write support for all FSes out there (apart for FAT until now), so do a "clever" "trick" to work around this problem: on initialized disks, find the active partition and check its FS. If we support write access to this FS then we're OK, otherwise we change the (active) system partition for the one on which we are going to install ReactOS (which is, by construction, formatted with a FS on which we support write access).
The MBR (resp. the VBR) of the disk (resp. of the system partition) are always saved into files, making easy for people to boot on them (using FreeLdr) or restoring them.
CORE-10898
svn path=/trunk/; revision=70837
2016-03-01 15:00:56 +00:00
|
|
|
Status = SaveBootSector(SystemRootPath->Buffer, DstPath, SECTORSIZE);
|
2016-02-02 01:55:05 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
[USETUP]
- bootsup.c/.h, usetup.c: Save the old MBR sector in the system partition (this makes easier to restore the old one).
- fslist.c/.h, usetup.h: Fix header inclusion order.
- partlist.c/.h, usetup.c: On BIOS-PC architectures, the system partition can be formatted in any FS as long as it is the active partition (on the contrary, on architectures where such system partition is required, it is formatted in FAT). We currently do not have write support for all FSes out there (apart for FAT until now), so do a "clever" "trick" to work around this problem: on initialized disks, find the active partition and check its FS. If we support write access to this FS then we're OK, otherwise we change the (active) system partition for the one on which we are going to install ReactOS (which is, by construction, formatted with a FS on which we support write access).
The MBR (resp. the VBR) of the disk (resp. of the system partition) are always saved into files, making easy for people to boot on them (using FreeLdr) or restoring them.
CORE-10898
svn path=/trunk/; revision=70837
2016-03-01 15:00:56 +00:00
|
|
|
DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
|
2016-02-02 01:55:05 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2017-06-08 02:43:51 +00:00
|
|
|
Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
|
2016-02-02 01:55:05 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2011-07-20 17:54:28 +00:00
|
|
|
}
|
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
/* Install new bootsector on the disk */
|
2024-05-11 16:23:44 +00:00
|
|
|
if (_wcsicmp(FileSystemName, L"FAT32") == 0)
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
/* Install FAT32 bootcode */
|
2017-05-23 22:30:54 +00:00
|
|
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin");
|
2011-07-20 17:54:28 +00:00
|
|
|
|
|
|
|
DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
|
2020-10-17 18:29:47 +00:00
|
|
|
Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallFat32BootCode);
|
2020-12-03 16:13:38 +00:00
|
|
|
DPRINT1("Status: 0x%08X\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT1("InstallBootCodeToDisk(FAT32) failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
2020-10-19 21:49:26 +00:00
|
|
|
else // if (wcsicmp(FileSystemName, L"FAT") == 0)
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
/* Install FAT16 bootcode */
|
2017-05-23 22:30:54 +00:00
|
|
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
|
2020-10-17 18:29:47 +00:00
|
|
|
Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallFat16BootCode);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT1("InstallBootCodeToDisk(FAT16) failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-02-02 01:55:05 +00:00
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
NTSTATUS
|
2018-06-13 23:30:06 +00:00
|
|
|
InstallBtrfsBootcodeToPartition(
|
2017-08-26 11:42:32 +00:00
|
|
|
IN PUNICODE_STRING SystemRootPath,
|
|
|
|
IN PUNICODE_STRING SourceRootPath,
|
2020-10-17 18:29:47 +00:00
|
|
|
IN PUNICODE_STRING DestinationArcPath)
|
2016-02-02 01:55:05 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOLEAN DoesFreeLdrExist;
|
|
|
|
WCHAR SrcPath[MAX_PATH];
|
|
|
|
WCHAR DstPath[MAX_PATH];
|
|
|
|
|
2018-06-13 23:30:06 +00:00
|
|
|
/* BTRFS partition */
|
2016-02-02 01:55:05 +00:00
|
|
|
DPRINT("System path: '%wZ'\n", SystemRootPath);
|
|
|
|
|
2017-05-31 01:43:12 +00:00
|
|
|
/* Copy FreeLoader to the system partition, always overwriting the older version */
|
2017-05-23 22:30:54 +00:00
|
|
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
|
2017-05-31 01:43:12 +00:00
|
|
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
|
2016-02-02 01:55:05 +00:00
|
|
|
|
|
|
|
DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
|
2017-06-11 23:58:43 +00:00
|
|
|
Status = SetupCopyFile(SrcPath, DstPath, FALSE);
|
2016-02-02 01:55:05 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2017-06-08 02:43:51 +00:00
|
|
|
/* Prepare for possibly updating 'freeldr.ini' */
|
|
|
|
DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
|
2016-02-02 01:55:05 +00:00
|
|
|
if (DoesFreeLdrExist)
|
|
|
|
{
|
|
|
|
/* Update existing 'freeldr.ini' */
|
|
|
|
DPRINT1("Update existing 'freeldr.ini'\n");
|
2017-06-08 02:43:51 +00:00
|
|
|
Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
2016-02-02 01:55:05 +00:00
|
|
|
}
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
/* Check for *nix bootloaders */
|
|
|
|
|
|
|
|
/* Create or update 'freeldr.ini' */
|
|
|
|
if (DoesFreeLdrExist == FALSE)
|
|
|
|
{
|
|
|
|
/* Create new 'freeldr.ini' */
|
|
|
|
DPRINT1("Create new 'freeldr.ini'\n");
|
|
|
|
|
|
|
|
/* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
|
|
|
|
DPRINT1("*nix or unknown boot loader found\n");
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
if (IsThereAValidBootSector(SystemRootPath->Buffer))
|
|
|
|
{
|
2017-05-31 01:43:12 +00:00
|
|
|
PCWSTR BootSector = L"BOOTSECT.OLD";
|
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
Status = CreateFreeLoaderIniForReactOSAndBootSector(
|
2017-06-08 02:43:51 +00:00
|
|
|
SystemRootPath->Buffer, DestinationArcPath->Buffer,
|
2016-02-02 01:55:05 +00:00
|
|
|
L"Linux", L"\"Linux\"",
|
2024-04-23 15:02:06 +00:00
|
|
|
SystemRootPath->Buffer, BootSector);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
/* Save current bootsector */
|
2017-05-31 01:43:12 +00:00
|
|
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
|
2020-10-17 18:29:47 +00:00
|
|
|
Status = SaveBootSector(SystemRootPath->Buffer, DstPath, BTRFS_BOOTSECTOR_SIZE);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
[USETUP]
- bootsup.c/.h, usetup.c: Save the old MBR sector in the system partition (this makes easier to restore the old one).
- fslist.c/.h, usetup.h: Fix header inclusion order.
- partlist.c/.h, usetup.c: On BIOS-PC architectures, the system partition can be formatted in any FS as long as it is the active partition (on the contrary, on architectures where such system partition is required, it is formatted in FAT). We currently do not have write support for all FSes out there (apart for FAT until now), so do a "clever" "trick" to work around this problem: on initialized disks, find the active partition and check its FS. If we support write access to this FS then we're OK, otherwise we change the (active) system partition for the one on which we are going to install ReactOS (which is, by construction, formatted with a FS on which we support write access).
The MBR (resp. the VBR) of the disk (resp. of the system partition) are always saved into files, making easy for people to boot on them (using FreeLdr) or restoring them.
CORE-10898
svn path=/trunk/; revision=70837
2016-03-01 15:00:56 +00:00
|
|
|
DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
|
|
|
}
|
2016-02-02 01:55:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-08 02:43:51 +00:00
|
|
|
Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
|
2016-02-02 01:55:05 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2011-07-20 17:54:28 +00:00
|
|
|
{
|
2016-02-02 01:55:05 +00:00
|
|
|
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
2011-07-20 17:54:28 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-02 01:55:05 +00:00
|
|
|
|
|
|
|
/* Install new bootsector on the disk */
|
2020-10-17 18:29:47 +00:00
|
|
|
/* Install BTRFS bootcode */
|
|
|
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\btrfs.bin");
|
2011-07-20 17:54:28 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT1("Install BTRFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
|
|
|
|
Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallBtrfsBootCode);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("InstallBootCodeToDisk(BTRFS) failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
2011-07-20 17:54:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
2004-06-23 14:09:55 +00:00
|
|
|
}
|
|
|
|
|
2022-10-19 00:02:24 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
InstallNtfsBootcodeToPartition(
|
|
|
|
IN PUNICODE_STRING SystemRootPath,
|
|
|
|
IN PUNICODE_STRING SourceRootPath,
|
|
|
|
IN PUNICODE_STRING DestinationArcPath)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOLEAN DoesFreeLdrExist;
|
|
|
|
WCHAR SrcPath[MAX_PATH];
|
|
|
|
WCHAR DstPath[MAX_PATH];
|
|
|
|
|
|
|
|
/* NTFS partition */
|
|
|
|
DPRINT("System path: '%wZ'\n", SystemRootPath);
|
|
|
|
|
|
|
|
/* 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");
|
|
|
|
|
|
|
|
DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
|
|
|
|
Status = SetupCopyFile(SrcPath, DstPath, FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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(SystemRootPath->Buffer, DestinationArcPath->Buffer);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for *nix bootloaders */
|
|
|
|
|
|
|
|
DPRINT1("Create new 'freeldr.ini'\n");
|
|
|
|
|
|
|
|
/* 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(
|
|
|
|
SystemRootPath->Buffer, DestinationArcPath->Buffer,
|
|
|
|
L"Linux", L"\"Linux\"",
|
2024-04-23 15:02:06 +00:00
|
|
|
SystemRootPath->Buffer, BootSector);
|
2022-10-19 00:02:24 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Save current bootsector */
|
|
|
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
|
|
|
|
|
|
|
|
DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
|
|
|
|
Status = SaveBootSector(SystemRootPath->Buffer, DstPath, NTFS_BOOTSECTOR_SIZE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install new bootsector on the disk */
|
|
|
|
|
|
|
|
/* Install NTFS bootcode */
|
|
|
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\ntfs.bin");
|
|
|
|
|
|
|
|
DPRINT1("Install NTFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
|
|
|
|
Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallNtfsBootCode);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("InstallBootCodeToDisk(NTFS) failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-05-12 14:17:37 +00:00
|
|
|
|
2010-09-05 17:09:18 +00:00
|
|
|
NTSTATUS
|
2011-07-20 17:54:28 +00:00
|
|
|
InstallVBRToPartition(
|
2017-08-26 11:42:32 +00:00
|
|
|
IN PUNICODE_STRING SystemRootPath,
|
|
|
|
IN PUNICODE_STRING SourceRootPath,
|
|
|
|
IN PUNICODE_STRING DestinationArcPath,
|
2020-10-19 21:49:26 +00:00
|
|
|
IN PCWSTR FileSystemName)
|
2010-09-05 17:09:18 +00:00
|
|
|
{
|
2024-05-11 16:23:44 +00:00
|
|
|
if (_wcsicmp(FileSystemName, L"FAT") == 0 ||
|
|
|
|
_wcsicmp(FileSystemName, L"FAT32") == 0)
|
2016-02-02 01:55:05 +00:00
|
|
|
{
|
2020-10-19 21:49:26 +00:00
|
|
|
return InstallFatBootcodeToPartition(SystemRootPath,
|
|
|
|
SourceRootPath,
|
|
|
|
DestinationArcPath,
|
|
|
|
FileSystemName);
|
|
|
|
}
|
2024-05-11 16:23:44 +00:00
|
|
|
else if (_wcsicmp(FileSystemName, L"NTFS") == 0)
|
2020-10-19 21:49:26 +00:00
|
|
|
{
|
2022-10-19 00:02:24 +00:00
|
|
|
return InstallNtfsBootcodeToPartition(SystemRootPath,
|
|
|
|
SourceRootPath,
|
|
|
|
DestinationArcPath);
|
2020-10-19 21:49:26 +00:00
|
|
|
}
|
2024-05-11 16:23:44 +00:00
|
|
|
else if (_wcsicmp(FileSystemName, L"BTRFS") == 0)
|
2020-10-19 21:49:26 +00:00
|
|
|
{
|
|
|
|
return InstallBtrfsBootcodeToPartition(SystemRootPath,
|
|
|
|
SourceRootPath,
|
|
|
|
DestinationArcPath);
|
|
|
|
}
|
|
|
|
/*
|
2024-05-11 16:23:44 +00:00
|
|
|
else if (_wcsicmp(FileSystemName, L"EXT2") == 0 ||
|
|
|
|
_wcsicmp(FileSystemName, L"EXT3") == 0 ||
|
|
|
|
_wcsicmp(FileSystemName, L"EXT4") == 0)
|
2020-10-19 21:49:26 +00:00
|
|
|
{
|
|
|
|
return STATUS_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Unknown file system */
|
|
|
|
DPRINT1("Unknown file system '%S'\n", FileSystemName);
|
2010-09-05 17:09:18 +00:00
|
|
|
}
|
2011-06-29 20:27:07 +00:00
|
|
|
|
2020-10-19 21:49:26 +00:00
|
|
|
return STATUS_NOT_SUPPORTED;
|
2010-09-05 17:09:18 +00:00
|
|
|
}
|
|
|
|
|
2004-06-23 14:09:55 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
2011-07-20 17:54:28 +00:00
|
|
|
InstallFatBootcodeToFloppy(
|
2017-08-26 11:42:32 +00:00
|
|
|
IN PUNICODE_STRING SourceRootPath,
|
|
|
|
IN PUNICODE_STRING DestinationArcPath)
|
2004-06-23 14:09:55 +00:00
|
|
|
{
|
2019-02-24 16:52:33 +00:00
|
|
|
static const PCWSTR FloppyDevice = L"\\Device\\Floppy0\\";
|
|
|
|
|
2016-02-02 01:55:05 +00:00
|
|
|
NTSTATUS Status;
|
2011-07-20 17:54:28 +00:00
|
|
|
WCHAR SrcPath[MAX_PATH];
|
|
|
|
WCHAR DstPath[MAX_PATH];
|
2014-05-12 14:17:37 +00:00
|
|
|
|
2017-09-03 16:19:59 +00:00
|
|
|
/* Verify that the floppy disk is accessible */
|
2019-02-24 16:52:33 +00:00
|
|
|
if (DoesDirExist(NULL, FloppyDevice) == FALSE)
|
2017-09-03 16:19:59 +00:00
|
|
|
return STATUS_DEVICE_NOT_READY;
|
|
|
|
|
|
|
|
/* Format the floppy disk */
|
2019-02-24 16:52:33 +00:00
|
|
|
// FormatPartition(...)
|
|
|
|
Status = FormatFileSystem(FloppyDevice,
|
|
|
|
L"FAT",
|
|
|
|
FMIFS_FLOPPY,
|
|
|
|
NULL,
|
|
|
|
TRUE,
|
|
|
|
0,
|
|
|
|
NULL);
|
2011-10-29 15:10:11 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2019-02-24 16:52:33 +00:00
|
|
|
if (Status == STATUS_NOT_SUPPORTED)
|
|
|
|
DPRINT1("FAT FS non existent on this system?!\n");
|
|
|
|
else
|
|
|
|
DPRINT1("VfatFormat() failed (Status %lx)\n", Status);
|
|
|
|
|
2011-10-29 15:10:11 +00:00
|
|
|
return Status;
|
|
|
|
}
|
2004-06-23 14:09:55 +00:00
|
|
|
|
2011-07-20 17:54:28 +00:00
|
|
|
/* Copy FreeLoader to the boot partition */
|
2017-05-23 22:30:54 +00:00
|
|
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
|
2019-02-24 16:52:33 +00:00
|
|
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, FloppyDevice, L"freeldr.sys");
|
2004-06-23 14:09:55 +00:00
|
|
|
|
2011-07-20 17:54:28 +00:00
|
|
|
DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
|
2017-06-11 23:58:43 +00:00
|
|
|
Status = SetupCopyFile(SrcPath, DstPath, FALSE);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2004-06-23 14:09:55 +00:00
|
|
|
{
|
2011-07-20 17:54:28 +00:00
|
|
|
DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
|
|
|
|
return Status;
|
2004-06-23 14:09:55 +00:00
|
|
|
}
|
|
|
|
|
2011-07-20 17:54:28 +00:00
|
|
|
/* Create new 'freeldr.ini' */
|
|
|
|
DPRINT("Create new 'freeldr.ini'\n");
|
2019-02-24 16:52:33 +00:00
|
|
|
Status = CreateFreeLoaderIniForReactOS(FloppyDevice, DestinationArcPath->Buffer);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2004-06-23 14:09:55 +00:00
|
|
|
{
|
2015-04-18 09:21:51 +00:00
|
|
|
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
2004-06-23 14:09:55 +00:00
|
|
|
}
|
|
|
|
|
2017-05-31 01:43:12 +00:00
|
|
|
/* Install FAT12 boosector */
|
2017-05-23 22:30:54 +00:00
|
|
|
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
|
2019-02-24 16:52:33 +00:00
|
|
|
CombinePaths(DstPath, ARRAYSIZE(DstPath), 1, FloppyDevice);
|
2004-06-23 14:09:55 +00:00
|
|
|
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT("Install FAT12 bootcode: %S ==> %S\n", SrcPath, DstPath);
|
|
|
|
Status = InstallBootCodeToDisk(SrcPath, DstPath, InstallFat12BootCode);
|
2011-07-20 17:54:28 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2004-06-23 14:09:55 +00:00
|
|
|
{
|
2020-10-17 18:29:47 +00:00
|
|
|
DPRINT1("InstallBootCodeToDisk(FAT12) failed (Status %lx)\n", Status);
|
2011-07-20 17:54:28 +00:00
|
|
|
return Status;
|
2004-06-23 14:09:55 +00:00
|
|
|
}
|
|
|
|
|
2011-07-20 17:54:28 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-06-23 14:09:55 +00:00
|
|
|
}
|
|
|
|
|
2003-01-30 17:37:13 +00:00
|
|
|
/* EOF */
|