https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e589513b468602dd34944…
commit e589513b468602dd34944377d9af1cbc1a09feb0
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Thu Jun 8 02:43:51 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Oct 14 23:45:45 2018 +0200
[USETUP] As evoked in 27603a10 (r74943), adapt the code in bootsup.c to abstract the
manipulation of freeldr.ini and boot.ini, and make it use the new features of bldrsup.c
committed in 27603a10 (r74952).
In particular the helper functions CreateCommonFreeLdrSections() and
(Un)protectBootIni() are now removed from there (they are used in bldrsup.c only).
This should pave the way for future integration with other sorts of NT boot loaders
(BootMgr and (u)EFI boot loader).
svn path=/branches/setup_improvements/; revision=74954
---
base/setup/usetup/bootsup.c | 947 ++++++++++++++------------------------------
1 file changed, 296 insertions(+), 651 deletions(-)
diff --git a/base/setup/usetup/bootsup.c b/base/setup/usetup/bootsup.c
index 469693b56a..2d978b6364 100644
--- a/base/setup/usetup/bootsup.c
+++ b/base/setup/usetup/bootsup.c
@@ -125,345 +125,140 @@ TrimTrailingPathSeparators_UStr(
}
}
-static
-VOID
-CreateCommonFreeLoaderSections(
- PINICACHE IniCache)
+
+static VOID
+CreateFreeLoaderReactOSEntries(
+ IN PVOID BootStoreHandle,
+ IN PCWSTR ArcPath)
{
- PINICACHESECTION IniSection;
+ UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
+ PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry;
+ PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
+ NTOS_BOOT_OPTIONS BootOptions;
+
+ BootEntry->Version = L"Windows2003";
+ 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"";
+ AddNTOSBootEntry(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";
+ AddNTOSBootEntry(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";
+ AddNTOSBootEntry(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";
+ AddNTOSBootEntry(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";
+ AddNTOSBootEntry(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";
+ AddNTOSBootEntry(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";
+ AddNTOSBootEntry(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";
+ AddNTOSBootEntry(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: ");
-}
-
-static
-NTSTATUS
-CreateNTOSEntry(
- PINICACHE IniCache,
- PINICACHESECTION OSSection,
- PWCHAR Section,
- PWCHAR Description,
- PWCHAR BootType,
- PWCHAR ArcPath,
- PWCHAR Options)
-{
- 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);
-
- return STATUS_SUCCESS;
-}
-
-static
-VOID
-CreateFreeLoaderReactOSEntries(
- PINICACHE IniCache,
- PWCHAR ArcPath)
-{
- PINICACHESECTION IniSection;
-
- /* Create "Operating Systems" section */
- IniSection = IniCacheAppendSection(IniCache, L"Operating Systems");
-
- /* ReactOS */
- CreateNTOSEntry(IniCache, IniSection,
- L"ReactOS", L"\"ReactOS\"",
- L"Windows2003", ArcPath,
- L"");
-
- /* 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
-
- /* ReactOS_Screen */
- CreateNTOSEntry(IniCache, IniSection,
- L"ReactOS_Screen", L"\"ReactOS
(Screen)\"",
- L"Windows2003", ArcPath,
- L"/DEBUG /DEBUGPORT=SCREEN /SOS");
-
- /* ReactOS_LogFile */
- CreateNTOSEntry(IniCache, IniSection,
- L"ReactOS_LogFile", L"\"ReactOS (Log
file)\"",
- L"Windows2003", ArcPath,
- L"/DEBUG /DEBUGPORT=FILE /SOS");
-
- /* 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");
-
- /* 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
+ SetNTOSBootOptions(BootStoreHandle, &BootOptions, 2 | 1);
}
-static
-NTSTATUS
+static NTSTATUS
CreateFreeLoaderIniForReactOS(
- PWCHAR IniPath,
- PWCHAR ArcPath)
+ IN PCWSTR IniPath,
+ IN PCWSTR ArcPath)
{
- PINICACHE IniCache;
-
- /* Initialize the INI file */
- IniCache = IniCacheCreate();
+ NTSTATUS Status;
+ PVOID BootStoreHandle;
- /* Create the common FreeLdr sections */
- CreateCommonFreeLoaderSections(IniCache);
+ /* Initialize the INI file and create the common FreeLdr sections */
+ Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
+ if (!NT_SUCCESS(Status))
+ return Status;
/* Add the ReactOS entries */
- CreateFreeLoaderReactOSEntries(IniCache, ArcPath);
-
- /* Save the INI file */
- IniCacheSave(IniCache, IniPath);
- IniCacheDestroy(IniCache);
+ CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
+ /* Close the INI file */
+ CloseNTOSBootLoaderStore(BootStoreHandle);
return STATUS_SUCCESS;
}
-static
-NTSTATUS
+static NTSTATUS
CreateFreeLoaderIniForReactOSAndBootSector(
IN PCWSTR IniPath,
IN PCWSTR ArcPath,
@@ -472,385 +267,249 @@ CreateFreeLoaderIniForReactOSAndBootSector(
IN PCWSTR BootDrive,
IN PCWSTR BootPartition,
IN PCWSTR BootSector)
-{
- PINICACHE IniCache;
- PINICACHESECTION IniSection;
-
- /* Initialize the INI file */
- IniCache = IniCacheCreate();
-
- /* Create the common FreeLdr sections */
- CreateCommonFreeLoaderSections(IniCache);
-
- /* Add the ReactOS entries */
- CreateFreeLoaderReactOSEntries(IniCache, (PWCHAR)ArcPath);
-
- /* Get "Operating Systems" section */
- IniSection = IniCacheGetSection(IniCache, L"Operating Systems");
-
- /* Insert entry into "Operating Systems" section */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- (PWCHAR)Section,
- (PWCHAR)Description);
-
- /* Create new section */
- IniSection = IniCacheAppendSection(IniCache, (PWCHAR)Section);
-
- /* BootType=BootSector */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootType",
- L"BootSector");
-
- /* BootDrive= */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootDrive",
- (PWCHAR)BootDrive);
-
- /* BootPartition= */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootPartition",
- (PWCHAR)BootPartition);
-
- /* BootSector= */
- IniCacheInsertKey(IniSection,
- NULL,
- INSERT_LAST,
- L"BootSectorFile",
- (PWCHAR)BootSector);
-
- /* Save the INI file */
- IniCacheSave(IniCache, (PWCHAR)IniPath);
- IniCacheDestroy(IniCache);
-
- return STATUS_SUCCESS;
-}
-
-static
-NTSTATUS
-UpdateFreeLoaderIni(
- PWCHAR IniPath,
- PWCHAR 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;
+ PVOID BootStoreHandle;
+ UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) +
sizeof(BOOT_SECTOR_OPTIONS)];
+ PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry;
+ PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions;
- Status = IniCacheLoad(&IniCache, IniPath, FALSE);
+ /* Initialize the INI file and create the common FreeLdr sections */
+ Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
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;
-
- /* 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);
- }
-
- /* Search for an existing ReactOS entry */
- OsIniSection = IniCacheGetSection(IniCache, SectionName2);
- if (OsIniSection != NULL)
- {
- BOOLEAN UseExistingEntry = TRUE;
-
- /* 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;
- }
-
- 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;
- }
- }
+ /* Add the ReactOS entries */
+ CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
- if (UseExistingEntry)
- {
- IniCacheDestroy(IniCache);
- return STATUS_SUCCESS;
- }
- }
+ /**/BootEntry->Version = L"BootSector";/**/
+ BootEntry->BootFilePath = NULL;
- swprintf(SectionName, L"ReactOS_%lu", i);
- swprintf(OsName, L"\"ReactOS %lu\"", i);
- i++;
- }
+ BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS);
+ RtlCopyMemory(Options->Signature,
+ BOOT_SECTOR_OPTIONS_SIGNATURE,
+ RTL_FIELD_SIZE(BOOT_SECTOR_OPTIONS, Signature));
- /* Create a new "ReactOS" entry */
- CreateNTOSEntry(IniCache, IniSection,
- SectionName, OsName,
- L"Windows2003", ArcPath,
- L"");
+ Options->Drive = BootDrive;
+ Options->Partition = BootPartition;
+ Options->BootSectorFileName = BootSector;
- IniCacheSave(IniCache, IniPath);
- IniCacheDestroy(IniCache);
+ // BootEntry->BootEntryKey = MAKESTRKEY(Section);
+ BootEntry->FriendlyName = Description;
+ AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Section));
+ /* Close the INI file */
+ CloseNTOSBootLoaderStore(BootStoreHandle);
return STATUS_SUCCESS;
}
-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;
+//
+// 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".
+//
- RtlInitUnicodeString(&Name, FileName);
+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 NTOS_BOOT_LOADER_TYPE Type,
+ IN PNTOS_BOOT_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];
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ /* We have a boot entry */
- Status = NtOpenFile(&FileHandle,
- GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- 0,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (Status == STATUS_NO_SUCH_FILE)
+ /* 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))
{
- DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
- *Attributes = 0;
- return STATUS_SUCCESS;
+ /* This is not a ReactOS entry */
+ DPRINT1(" An installation '%S' of unsupported type
'%S'\n",
+ BootEntry->FriendlyName,
+ BootEntry->Version ? BootEntry->Version : L"n/a");
+ /* Continue the enumeration */
+ goto SkipThisEntry;
}
- if (!NT_SUCCESS(Status))
+
+ /* BootType is Windows2003, now check OsLoadPath */
+ if (!Options->OsLoadPath || !*Options->OsLoadPath)
{
- DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
- return Status;
+ /* Certainly not a ReactOS installation */
+ DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n",
BootEntry->FriendlyName);
+ /* Continue the enumeration */
+ goto SkipThisEntry;
}
- Status = NtQueryInformationFile(FileHandle,
- &IoStatusBlock,
- &FileInfo,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
- if (!NT_SUCCESS(Status))
+ RtlStringCchPrintfW(SystemPath, ARRAYSIZE(SystemPath), L"\"%s\"",
Data->ArcPath);
+ if ((_wcsicmp(Options->OsLoadPath, Data->ArcPath) != 0) &&
+ (_wcsicmp(Options->OsLoadPath, SystemPath) != 0))
{
- DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status);
- NtClose(FileHandle);
- return Status;
+ /*
+ * This entry is a ReactOS entry, but the SystemRoot
+ * does not match the one we are looking for.
+ */
+ /* Continue the enumeration */
+ goto SkipThisEntry;
}
- *Attributes = FileInfo.FileAttributes;
+ 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);
- /* Delete attributes SYSTEM, HIDDEN and READONLY */
- FileInfo.FileAttributes = FileInfo.FileAttributes &
- ~(FILE_ATTRIBUTE_SYSTEM |
- FILE_ATTRIBUTE_HIDDEN |
- FILE_ATTRIBUTE_READONLY);
+ DPRINT1("EnumerateReactOSEntries: OsLoadPath: '%S'\n",
Options->OsLoadPath);
- Status = NtSetInformationFile(FileHandle,
- &IoStatusBlock,
- &FileInfo,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
- if (!NT_SUCCESS(Status))
+ 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)
{
- DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status);
+ RtlStringCchPrintfW(Data->SectionName, ARRAYSIZE(Data->SectionName),
+ L"ReactOS_%lu", Data->i);
+ RtlStringCchPrintfW(Data->OsName, ARRAYSIZE(Data->OsName),
+ L"\"ReactOS %lu\"", Data->i);
+ Data->i++;
}
-
- NtClose(FileHandle);
- return Status;
+ return STATUS_SUCCESS;
}
static
NTSTATUS
-ProtectBootIni(
- PWSTR FileName,
- ULONG Attributes)
+UpdateFreeLoaderIni(
+ IN PCWSTR IniPath,
+ IN PCWSTR ArcPath)
{
NTSTATUS Status;
- UNICODE_STRING Name;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- FILE_BASIC_INFORMATION FileInfo;
- HANDLE FileHandle;
+ PVOID BootStoreHandle;
+ ENUM_REACTOS_ENTRIES_DATA Data;
+ UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
+ PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry;
+ PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
+
+ /* Open the INI file */
+ Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, FreeLdr, /*TRUE*/
FALSE);
+ if (!NT_SUCCESS(Status))
+ return Status;
- RtlInitUnicodeString(&Name, FileName);
+ /* 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\"");
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ //
+ // FIXME: We temporarily use EnumerateNTOSBootEntries, until
+ // both QueryNTOSBootEntry and ModifyNTOSBootEntry get implemented.
+ //
+ Status = EnumerateNTOSBootEntries(BootStoreHandle, EnumerateReactOSEntries,
&Data);
- Status = NtOpenFile(&FileHandle,
- GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- 0,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(Status))
+ /* Create a new "ReactOS" entry if there is none already existing that
suits us */
+ if (!Data.UseExistingEntry)
{
- DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
- return Status;
- }
+ // RtlStringCchPrintfW(Data.SectionName, ARRAYSIZE(Data.SectionName),
L"ReactOS_%lu", Data.i);
+ // RtlStringCchPrintfW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS
%lu\"", Data.i);
- 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;
- }
+ BootEntry->Version = L"Windows2003";
+ BootEntry->BootFilePath = NULL;
- FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes;
+ BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
+ RtlCopyMemory(Options->Signature,
+ NTOS_OPTIONS_SIGNATURE,
+ RTL_FIELD_SIZE(NTOS_OPTIONS, Signature));
- Status = NtSetInformationFile(FileHandle,
- &IoStatusBlock,
- &FileInfo,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status);
+ Options->OsLoadPath = ArcPath;
+
+ // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
+ BootEntry->FriendlyName = Data.OsName;
+ Options->OsLoadOptions = NULL; // L"";
+ AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Data.SectionName));
}
- NtClose(FileHandle);
- return Status;
+ /* Close the INI file */
+ CloseNTOSBootLoaderStore(BootStoreHandle);
+ return STATUS_SUCCESS;
}
static
NTSTATUS
UpdateBootIni(
- PWSTR BootIniPath,
- PWSTR EntryName,
- PWSTR EntryValue)
+ IN PCWSTR IniPath,
+ IN PCWSTR EntryName, // ~= ArcPath
+ IN PCWSTR EntryValue)
{
NTSTATUS Status;
- PINICACHE Cache = NULL;
- PINICACHESECTION Section = NULL;
- ULONG FileAttribute;
- PWCHAR OldValue = NULL;
+ PVOID BootStoreHandle;
+ ENUM_REACTOS_ENTRIES_DATA Data;
- 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;
- }
+ // NOTE: Technically it would be "BootSector"...
+ UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
+ PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry;
+ PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
- Status = IniCacheSave(Cache, BootIniPath);
+ /* Open the INI file */
+ Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, NtLdr, FALSE);
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;
+ /* 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 EnumerateNTOSBootEntries, until
+ // both QueryNTOSBootEntry and ModifyNTOSBootEntry get implemented.
+ //
+ Status = EnumerateNTOSBootEntries(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 = L"Windows2003"; // NOTE: See remark above
+ 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"";
+ AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(0
/*Data.SectionName*/));
+ }
+
+ /* Close the INI file */
+ CloseNTOSBootLoaderStore(BootStoreHandle);
+ return STATUS_SUCCESS; // Status;
}
@@ -2129,15 +1788,12 @@ InstallFatBootcodeToPartition(
}
/* Prepare for possibly updating 'freeldr.ini' */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer,
L"freeldr.ini");
-
- DoesFreeLdrExist = DoesFileExist(NULL, DstPath);
+ 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);
@@ -2161,9 +1817,7 @@ InstallFatBootcodeToPartition(
{
/* 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);
@@ -2205,12 +1859,10 @@ InstallFatBootcodeToPartition(
}
/* Update 'boot.ini' */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer,
L"boot.ini");
-
/* 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': %S\n", DstPath);
- Status = UpdateBootIni(DstPath,
+ DPRINT1("Update 'boot.ini'\n");
+ Status = UpdateBootIni(SystemRootPath->Buffer,
L"C:\\bootsect.ros",
L"\"ReactOS\"");
if (!NT_SUCCESS(Status))
@@ -2352,12 +2004,11 @@ InstallFatBootcodeToPartition(
{
/* 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))
@@ -2379,7 +2030,7 @@ InstallFatBootcodeToPartition(
}
else
{
- Status = CreateFreeLoaderIniForReactOS(DstPath,
DestinationArcPath->Buffer);
+ Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer,
DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status
%lx)\n", Status);
@@ -2449,16 +2100,13 @@ InstallBtrfsBootcodeToPartition(
return Status;
}
- /* Prepare for possibly copying 'freeldr.ini' */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer,
L"freeldr.ini");
-
- DoesFreeLdrExist = DoesFileExist(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);
@@ -2473,7 +2121,6 @@ InstallBtrfsBootcodeToPartition(
{
/* 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");
@@ -2483,7 +2130,7 @@ InstallBtrfsBootcodeToPartition(
PCWSTR BootSector = L"BOOTSECT.OLD";
Status = CreateFreeLoaderIniForReactOSAndBootSector(
- DstPath, DestinationArcPath->Buffer,
+ SystemRootPath->Buffer, DestinationArcPath->Buffer,
L"Linux", L"\"Linux\"",
L"hd0", L"1", BootSector);
if (!NT_SUCCESS(Status))
@@ -2505,7 +2152,7 @@ InstallBtrfsBootcodeToPartition(
}
else
{
- Status = CreateFreeLoaderIniForReactOS(DstPath,
DestinationArcPath->Buffer);
+ Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer,
DestinationArcPath->Buffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status
%lx)\n", Status);
@@ -2619,10 +2266,8 @@ InstallFatBootcodeToFloppy(
}
/* Create new 'freeldr.ini' */
- CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, FloppyDevice.Buffer,
L"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);
@@ -2631,7 +2276,7 @@ InstallFatBootcodeToFloppy(
/* Install FAT12 boosector */
CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer,
L"\\loader\\fat.bin");
- RtlStringCchCopyW(DstPath, ARRAYSIZE(DstPath), FloppyDevice.Buffer);
+ CombinePaths(DstPath, ARRAYSIZE(DstPath), 1, FloppyDevice.Buffer);
DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
Status = InstallFat12BootCodeToFloppy(SrcPath, DstPath);