https://git.reactos.org/?p=reactos.git;a=commitdiff;h=563d9f26c4ab04145ae5c…
commit 563d9f26c4ab04145ae5cf9054e125d9c40b5c87
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Wed May 31 01:11:05 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Jun 3 22:12:45 2018 +0200
[SETUPLIB] Adjustments in the code.
- Call OpenAndMapFile() with its new ReadWrite parameter;
- Add informative comments in osdetect.c;
- In partlist.c, check whether a disk has a valid MBR by also checking for its 0xAA55 signature.
svn path=/branches/setup_improvements/; revision=74712
---
base/setup/lib/bldrsup.c | 4 ++--
base/setup/lib/osdetect.c | 13 ++++++++++++-
base/setup/lib/partlist.c | 9 ++++++---
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/base/setup/lib/bldrsup.c b/base/setup/lib/bldrsup.c
index 493c52237e..13a1ed34e8 100644
--- a/base/setup/lib/bldrsup.c
+++ b/base/setup/lib/bldrsup.c
@@ -89,7 +89,7 @@ FindNTOSBootLoader( // By handle
#if 0
/* Check whether the loader configuration file exists */
Status = OpenAndMapFile(PartitionHandle, NtosBootLoaders[Type].LoaderConfigurationFile,
- &FileHandle, &SectionHandle, &ViewBase, &FileSize);
+ &FileHandle, &SectionHandle, &ViewBase, &FileSize, FALSE);
if (!NT_SUCCESS(Status))
{
/* The loader does not exist, continue with another one */
@@ -314,7 +314,7 @@ EnumerateNTOSBootEntries(
/* Check whether the loader configuration file exists */
Status = OpenAndMapFile(PartitionHandle, NtosBootLoaders[Type].LoaderConfigurationFile,
- &FileHandle, &SectionHandle, &ViewBase, &FileSize);
+ &FileHandle, &SectionHandle, &ViewBase, &FileSize, FALSE);
if (!NT_SUCCESS(Status))
{
/* The loader does not exist, continue with another one */
diff --git a/base/setup/lib/osdetect.c b/base/setup/lib/osdetect.c
index 20611bdc02..6b16e5624d 100644
--- a/base/setup/lib/osdetect.c
+++ b/base/setup/lib/osdetect.c
@@ -150,6 +150,8 @@ EnumerateInstallations(
{
/* This is not a ReactOS entry */
/* Certainly not a ReactOS installation */
+ DPRINT1(" A Win2k3 install '%wZ' without an ARC path?!\n", &InstallName);
+ /* Continue the enumeration */
return STATUS_SUCCESS;
}
}
@@ -171,6 +173,7 @@ EnumerateInstallations(
{
DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
NtOsInstall->InstallationName, &NtOsInstall->SystemArcPath);
+ /* Continue the enumeration */
return STATUS_SUCCESS;
}
@@ -183,6 +186,7 @@ EnumerateInstallations(
if (!ArcPathToNtPath(&SystemRootPath, BootEntry->OsLoadPath, Data->PartList))
{
DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", BootEntry->OsLoadPath);
+ /* Continue the enumeration */
return STATUS_SUCCESS;
}
@@ -198,6 +202,7 @@ EnumerateInstallations(
{
DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath);
+ /* Continue the enumeration */
return STATUS_SUCCESS;
}
@@ -205,7 +210,10 @@ EnumerateInstallations(
/* Check if this is a valid NTOS installation; stop there if it isn't one */
if (!IsValidNTOSInstallation_UStr(&SystemRootPath))
+ {
+ /* Continue the enumeration */
return STATUS_SUCCESS;
+ }
DPRINT1("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n",
BootEntry->OsLoadPath, &SystemRootPath);
@@ -228,6 +236,7 @@ EnumerateInstallations(
DPRINT1("NtPathToDiskPartComponents(%wZ) failed\n", &SystemRootPath);
}
+ /* Add the discovered NTOS installation into the list */
if (PartEntry && PartEntry->DriveLetter)
{
/* We have retrieved a partition that is mounted */
@@ -245,6 +254,7 @@ EnumerateInstallations(
DiskNumber, PartitionNumber, PartEntry,
InstallNameW);
+ /* Continue the enumeration */
return STATUS_SUCCESS;
}
@@ -301,7 +311,8 @@ CheckForValidPEAndVendor(
VendorName->Length = 0;
Status = OpenAndMapFile(RootDirectory, PathNameToFile,
- &FileHandle, &SectionHandle, &ViewBase, NULL);
+ &FileHandle, &SectionHandle, &ViewBase,
+ NULL, FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open and map file '%S', Status 0x%08lx\n", PathNameToFile, Status);
diff --git a/base/setup/lib/partlist.c b/base/setup/lib/partlist.c
index 7b74cda8f0..f29b2859a6 100644
--- a/base/setup/lib/partlist.c
+++ b/base/setup/lib/partlist.c
@@ -989,9 +989,12 @@ AddDiskToList(
// DiskEntry->Signature = Signature;
DiskEntry->BiosFound = FALSE;
- /* Check if this disk has a valid MBR */
- // FIXME: Check for the MBR signature as well, etc...
- if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0)
+ /*
+ * Check if this disk has a valid MBR: verify its signature,
+ * and whether its two first bytes are a valid instruction
+ * (related to this, see IsThereAValidBootSector() in partlist.c).
+ */
+ if (Mbr->Magic != 0xaa55 || (*(PUSHORT)Mbr->BootCode) == 0x0000)
DiskEntry->NoMbr = TRUE;
else
DiskEntry->NoMbr = FALSE;
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6b6163a5d9e64ed980b36…
commit 6b6163a5d9e64ed980b36f757b0b96043e25520a
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue May 30 00:15:54 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Jun 3 22:12:43 2018 +0200
[USETUP] Minor fixes & simplifications.
- Remove a redundant NtClose() call;
- Return failure if NtQuerySymbolicLinkObject() fails;
- Use RTL_CONSTANT_STRING and RtlInitEmptyUnicodeString() where needed;
- Reduce code indent level;
- Add old-style function annotations;
- Remove the deprecated code copyright notice, since the copyright in usage is already reported in the COPYING file in the top level ReactOS source code directory.
svn path=/branches/setup_improvements/; revision=74698
---
base/setup/usetup/drivesup.c | 69 +++++++++++++++-----------------------------
base/setup/usetup/drivesup.h | 24 ++-------------
2 files changed, 26 insertions(+), 67 deletions(-)
diff --git a/base/setup/usetup/drivesup.c b/base/setup/usetup/drivesup.c
index c81b987fc1..b8561d77ed 100644
--- a/base/setup/usetup/drivesup.c
+++ b/base/setup/usetup/drivesup.c
@@ -1,21 +1,3 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
@@ -35,22 +17,19 @@
NTSTATUS
GetSourcePaths(
- PUNICODE_STRING SourcePath,
- PUNICODE_STRING SourceRootPath,
- PUNICODE_STRING SourceRootDir)
+ OUT PUNICODE_STRING SourcePath,
+ OUT PUNICODE_STRING SourceRootPath,
+ OUT PUNICODE_STRING SourceRootDir)
{
+ NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING LinkName;
+ UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
UNICODE_STRING SourceName;
- WCHAR SourceBuffer[MAX_PATH] = {L'\0'};
+ WCHAR SourceBuffer[MAX_PATH] = L"";
HANDLE Handle;
- NTSTATUS Status;
ULONG Length;
PWCHAR Ptr;
- RtlInitUnicodeString(&LinkName,
- L"\\SystemRoot");
-
InitializeObjectAttributes(&ObjectAttributes,
&LinkName,
OBJ_CASE_INSENSITIVE,
@@ -63,35 +42,33 @@ GetSourcePaths(
if (!NT_SUCCESS(Status))
return Status;
- SourceName.Length = 0;
- SourceName.MaximumLength = MAX_PATH * sizeof(WCHAR);
- SourceName.Buffer = SourceBuffer;
+ RtlInitEmptyUnicodeString(&SourceName, SourceBuffer, sizeof(SourceBuffer));
Status = NtQuerySymbolicLinkObject(Handle,
&SourceName,
&Length);
NtClose(Handle);
- if (NT_SUCCESS(Status))
- {
- RtlCreateUnicodeString(SourcePath,
- SourceName.Buffer);
+ if (!NT_SUCCESS(Status))
+ return Status;
- /* strip trailing directory */
- Ptr = wcsrchr(SourceName.Buffer, L'\\');
- if (Ptr)
- {
- RtlCreateUnicodeString(SourceRootDir, Ptr);
- *Ptr = 0;
- }
- else
- RtlCreateUnicodeString(SourceRootDir, L"");
+ RtlCreateUnicodeString(SourcePath,
+ SourceName.Buffer);
- RtlCreateUnicodeString(SourceRootPath,
- SourceName.Buffer);
+ /* Strip trailing directory */
+ Ptr = wcsrchr(SourceName.Buffer, OBJ_NAME_PATH_SEPARATOR);
+ if (Ptr)
+ {
+ RtlCreateUnicodeString(SourceRootDir, Ptr);
+ *Ptr = UNICODE_NULL;
+ }
+ else
+ {
+ RtlCreateUnicodeString(SourceRootDir, L"");
}
- NtClose(Handle);
+ RtlCreateUnicodeString(SourceRootPath,
+ SourceName.Buffer);
return STATUS_SUCCESS;
}
diff --git a/base/setup/usetup/drivesup.h b/base/setup/usetup/drivesup.h
index 5cd200d8fc..01b38a3c57 100644
--- a/base/setup/usetup/drivesup.h
+++ b/base/setup/usetup/drivesup.h
@@ -1,21 +1,3 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
@@ -28,8 +10,8 @@
NTSTATUS
GetSourcePaths(
- PUNICODE_STRING SourcePath,
- PUNICODE_STRING SourceRootPath,
- PUNICODE_STRING SourceRootDir);
+ OUT PUNICODE_STRING SourcePath,
+ OUT PUNICODE_STRING SourceRootPath,
+ OUT PUNICODE_STRING SourceRootDir);
/* EOF */
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6681fb8af5eec6ac2897a…
commit 6681fb8af5eec6ac2897a3e4bde973992fa9456c
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Thu May 25 23:52:50 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Jun 3 22:12:43 2018 +0200
[SETUPLIB] Add a new module "bldrsup.c" (WIP) where I place all the NT boot loaders (i.e. ntldr, freeldr, and possibly bootmgr in the future) management functions.
So far we only have:
- a function FindNTOSBootLoader() that detects the existence of a given boot loader;
- a function EnumerateNTOSBootEntries() (and corresponding helpers) that enumerate the different boot entries in the configuration file(s) for a given boot loader, and for each entry, calls a user-provided callback.
Only supported at the moment: ntldr and freeldr.
Doing that allows me to simplify large portions of the NT-OS detection code so that it becomes more bootloader-agnostic, and this will help me for simplifying some parts of usetup/bootsup.c too, later...
svn path=/branches/setup_improvements/; revision=74661
---
base/setup/lib/CMakeLists.txt | 1 +
base/setup/lib/bldrsup.c | 352 ++++++++++++++++++++++++++++
base/setup/lib/bldrsup.h | 59 +++++
base/setup/lib/osdetect.c | 523 ++++++++++++------------------------------
4 files changed, 556 insertions(+), 379 deletions(-)
diff --git a/base/setup/lib/CMakeLists.txt b/base/setup/lib/CMakeLists.txt
index 6d687deb1a..819ecf34bd 100644
--- a/base/setup/lib/CMakeLists.txt
+++ b/base/setup/lib/CMakeLists.txt
@@ -1,6 +1,7 @@
list(APPEND SOURCE
arcname.c
+ bldrsup.c
filesup.c
fsutil.c
genlist.c
diff --git a/base/setup/lib/bldrsup.c b/base/setup/lib/bldrsup.c
new file mode 100644
index 0000000000..493c52237e
--- /dev/null
+++ b/base/setup/lib/bldrsup.c
@@ -0,0 +1,352 @@
+/*
+ * PROJECT: ReactOS Setup Library
+ * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: NT 5.x family (MS Windows <= 2003, and ReactOS)
+ * boot loaders management.
+ * COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
+ */
+
+// TODO: Add support for NT 6.x family! (detection + BCD manipulation).
+
+/* INCLUDES *****************************************************************/
+
+#include "precomp.h"
+
+#include "bldrsup.h"
+#include "filesup.h"
+#include "inicache.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+/* GLOBALS ******************************************************************/
+
+typedef struct _NTOS_BOOT_LOADER_FILES
+{
+ NTOS_BOOT_LOADER_TYPE Type;
+ PCWSTR LoaderExecutable;
+ PCWSTR LoaderConfigurationFile;
+ // EnumerateInstallations;
+} NTOS_BOOT_LOADER_FILES, *PNTOS_BOOT_LOADER_FILES;
+
+// Question 1: What if config file is optional?
+// Question 2: What if many config files are possible?
+NTOS_BOOT_LOADER_FILES NtosBootLoaders[] =
+{
+ {FreeLdr, L"freeldr.sys", L"freeldr.ini"},
+ {NtLdr , L"ntldr" , L"boot.ini"}, // FIXME: What about osloader.exe, etc...?
+// {NtLdr , L"setupldr" , L"txtsetup.sif"}, // FIXME
+// {BootMgr, L"bootmgr" , L"BCD"}
+};
+
+
+/* FUNCTIONS ****************************************************************/
+
+//
+// We need, for each type of bootloader (FreeLdr, NtLdr, Bootmgr):
+// 1. A function that detects its presence and its version;
+// 2. A function that opens/closes its corresponding configuration file;
+// 3. A function that adds a new boot entry. Note that for the first two BLDRs
+// this is a .INI file, while in the latter case this is a registry hive...
+//
+
+NTSTATUS
+FindNTOSBootLoader( // By handle
+ IN HANDLE PartitionHandle, // OPTIONAL
+ IN NTOS_BOOT_LOADER_TYPE Type,
+ OUT PULONG Version OPTIONAL)
+// OUT PHANDLE ConfigFileHande OPTIONAL ????
+{
+ // UINT i;
+
+ if (Type >= BldrTypeMax)
+ return STATUS_INVALID_PARAMETER;
+
+ // FIXME: Unused for now, but should be used later!!
+ *Version = 0;
+ // TODO: Check for BLDR version ONLY if Version != NULL
+
+ /* Check whether the loader executable exists */
+ if (!DoesFileExist(PartitionHandle, NtosBootLoaders[Type].LoaderExecutable))
+ {
+ /* The loader does not exist, continue with another one */
+ // DPRINT1("Loader executable '%S' does not exist, continue with another one...\n", NtosBootLoaders[Type].LoaderExecutable);
+ DPRINT1("Loader executable '%S' does not exist\n", NtosBootLoaders[Type].LoaderExecutable);
+ return STATUS_NOT_FOUND;
+ }
+
+ /* Check whether the loader configuration file exists */
+ if (!DoesFileExist(PartitionHandle, NtosBootLoaders[Type].LoaderConfigurationFile))
+ {
+ /* The loader does not exist, continue with another one */
+ // FIXME: Consider it might be optional??
+ // DPRINT1("Loader configuration file '%S' does not exist, continue with another one...\n", NtosBootLoaders[Type].LoaderConfigurationFile);
+ DPRINT1("Loader configuration file '%S' does not exist\n", NtosBootLoaders[Type].LoaderConfigurationFile);
+ return STATUS_NOT_FOUND;
+ }
+
+#if 0
+ /* Check whether the loader configuration file exists */
+ Status = OpenAndMapFile(PartitionHandle, NtosBootLoaders[Type].LoaderConfigurationFile,
+ &FileHandle, &SectionHandle, &ViewBase, &FileSize);
+ if (!NT_SUCCESS(Status))
+ {
+ /* The loader does not exist, continue with another one */
+ // FIXME: Consider it might be optional??
+ DPRINT1("Loader configuration file '%S' does not exist, continue with another one...\n", NtosBootLoaders[Type].LoaderConfigurationFile);
+ return STATUS_NOT_FOUND;
+ }
+#endif
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+FreeLdrEnumerateBootEntries(
+ IN PCHAR FileBuffer,
+ IN ULONG FileLength,
+// IN ULONG Flags, // Determine which data to retrieve
+ IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
+ IN PVOID Parameter OPTIONAL)
+{
+ NTSTATUS Status;
+ PINICACHE IniCache;
+ PINICACHEITERATOR Iterator;
+ PINICACHESECTION IniSection, OsIniSection;
+ PWCHAR SectionName, KeyData;
+/**/NTOS_BOOT_ENTRY xxBootEntry;/**/
+ PNTOS_BOOT_ENTRY BootEntry = &xxBootEntry;
+ UNICODE_STRING InstallName;
+
+ /* Open an *existing* FreeLdr.ini configuration file */
+ Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* Get the "Operating Systems" section */
+ IniSection = IniCacheGetSection(IniCache, L"Operating Systems");
+ if (IniSection == NULL)
+ {
+ IniCacheDestroy(IniCache);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Enumerate all the valid installations */
+ Iterator = IniCacheFindFirstValue(IniSection, &SectionName, &KeyData);
+ if (!Iterator) goto Quit;
+ do
+ {
+ // FIXME: Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni).
+ if (KeyData[0] == L'"')
+ {
+ /* Quoted name, copy up to the closing quote */
+ PWCHAR Begin = &KeyData[1];
+ PWCHAR End = wcschr(Begin, L'"');
+ if (!End)
+ End = Begin + wcslen(Begin);
+ RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin);
+ InstallName.Length = InstallName.MaximumLength;
+ }
+ else
+ {
+ /* Non-quoted name, copy everything */
+ RtlInitUnicodeString(&InstallName, KeyData);
+ }
+
+ DPRINT1("Boot entry '%wZ' in OS section '%S'\n", &InstallName, SectionName);
+
+ /* Search for an existing ReactOS entry */
+ OsIniSection = IniCacheGetSection(IniCache, SectionName);
+ if (!OsIniSection)
+ continue;
+
+ /* Check for supported boot type "Windows2003" */
+ Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData);
+ if (NT_SUCCESS(Status))
+ {
+ // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ?
+ if ((KeyData == NULL) ||
+ ( (_wcsicmp(KeyData, L"Windows2003") != 0) &&
+ (_wcsicmp(KeyData, L"\"Windows2003\"") != 0) ))
+ {
+ /* This is not a ReactOS entry */
+ continue;
+ }
+ }
+ else
+ {
+ /* Certainly not a ReactOS installation */
+ continue;
+ }
+
+ /* BootType is Windows2003. Now check its SystemPath. */
+ Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1(" A Win2k3 install '%wZ' without an ARC path?!\n", &InstallName);
+ continue;
+ }
+
+ DPRINT1(" Found a candidate Win2k3 install '%wZ' with ARC path '%S'\n", &InstallName, KeyData);
+ // KeyData == SystemRoot;
+
+ BootEntry->FriendlyName = &InstallName;
+ BootEntry->OsLoadPath = KeyData;
+ /* Unused stuff (for now...) */
+ BootEntry->BootFilePath = NULL;
+ BootEntry->OsOptions = NULL;
+ BootEntry->OsLoadOptions = NULL;
+
+ Status = EnumBootEntriesRoutine(FreeLdr, BootEntry, Parameter);
+ // TODO: Stop enumeration if !NT_SUCCESS(Status);
+ }
+ while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
+
+ IniCacheFindClose(Iterator);
+
+Quit:
+ IniCacheDestroy(IniCache);
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+NtLdrEnumerateBootEntries(
+ IN PCHAR FileBuffer,
+ IN ULONG FileLength,
+// IN ULONG Flags, // Determine which data to retrieve
+ IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
+ IN PVOID Parameter OPTIONAL)
+{
+ NTSTATUS Status;
+ PINICACHE IniCache;
+ PINICACHEITERATOR Iterator;
+ PINICACHESECTION IniSection;
+ PWCHAR SectionName, KeyData;
+/**/NTOS_BOOT_ENTRY xxBootEntry;/**/
+ PNTOS_BOOT_ENTRY BootEntry = &xxBootEntry;
+ UNICODE_STRING InstallName;
+
+ /* Open an *existing* boot.ini configuration file */
+ Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* Get the "Operating Systems" section */
+ IniSection = IniCacheGetSection(IniCache, L"operating systems");
+ if (IniSection == NULL)
+ {
+ IniCacheDestroy(IniCache);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Enumerate all the valid installations */
+ Iterator = IniCacheFindFirstValue(IniSection, &SectionName, &KeyData);
+ if (!Iterator) goto Quit;
+ do
+ {
+ // FIXME: Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni).
+ if (KeyData[0] == L'"')
+ {
+ /* Quoted name, copy up to the closing quote */
+ PWCHAR Begin = &KeyData[1];
+ PWCHAR End = wcschr(Begin, L'"');
+ if (!End)
+ End = Begin + wcslen(Begin);
+ RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin);
+ InstallName.Length = InstallName.MaximumLength;
+ }
+ else
+ {
+ /* Non-quoted name, copy everything */
+ RtlInitUnicodeString(&InstallName, KeyData);
+ }
+
+ DPRINT1("Boot entry '%wZ' in OS section '%S'\n", &InstallName, SectionName);
+
+ DPRINT1(" Found a Win2k3 install '%wZ' with ARC path '%S'\n", &InstallName, SectionName);
+ // SectionName == SystemRoot;
+
+ BootEntry->FriendlyName = &InstallName;
+ BootEntry->OsLoadPath = SectionName;
+ /* Unused stuff (for now...) */
+ BootEntry->BootFilePath = NULL;
+ BootEntry->OsOptions = NULL;
+ BootEntry->OsLoadOptions = NULL;
+
+ Status = EnumBootEntriesRoutine(NtLdr, BootEntry, Parameter);
+ // TODO: Stop enumeration if !NT_SUCCESS(Status);
+ }
+ while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
+
+ IniCacheFindClose(Iterator);
+
+Quit:
+ IniCacheDestroy(IniCache);
+ return STATUS_SUCCESS;
+}
+
+
+// This function may be viewed as being similar to ntos:NtEnumerateBootEntries().
+NTSTATUS
+EnumerateNTOSBootEntries(
+ IN HANDLE PartitionHandle, // OPTIONAL
+ IN NTOS_BOOT_LOADER_TYPE Type,
+// IN ULONG Flags, // Determine which data to retrieve
+ IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
+ IN PVOID Parameter OPTIONAL)
+{
+ NTSTATUS Status;
+ HANDLE FileHandle;
+ HANDLE SectionHandle;
+ // SIZE_T ViewSize;
+ ULONG FileSize;
+ PVOID ViewBase;
+
+ /*
+ * NOTE: Currently we open & map the loader configuration file without
+ * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
+ * and NTLDR's boot.ini files. But as soon as we'll implement support for
+ * BOOTMGR detection, the "configuration file" will be the BCD registry
+ * hive and then, we'll have instead to mount the hive & open it.
+ */
+
+ /* Check whether the loader configuration file exists */
+ Status = OpenAndMapFile(PartitionHandle, NtosBootLoaders[Type].LoaderConfigurationFile,
+ &FileHandle, &SectionHandle, &ViewBase, &FileSize);
+ if (!NT_SUCCESS(Status))
+ {
+ /* The loader does not exist, continue with another one */
+ // FIXME: Consider it might be optional??
+ // DPRINT1("Loader configuration file '%S' does not exist, continue with another one...\n", NtosBootLoaders[Type].LoaderConfigurationFile);
+ DPRINT1("Loader configuration file '%S' does not exist\n", NtosBootLoaders[Type].LoaderConfigurationFile);
+ return Status;
+ }
+
+ /* The loader configuration file exists, interpret it to find valid installations */
+ switch (NtosBootLoaders[Type].Type)
+ {
+ case FreeLdr:
+ Status = FreeLdrEnumerateBootEntries(ViewBase, FileSize, /* Flags, */
+ EnumBootEntriesRoutine, Parameter);
+ break;
+
+ case NtLdr:
+ Status = NtLdrEnumerateBootEntries(ViewBase, FileSize, /* Flags, */
+ EnumBootEntriesRoutine, Parameter);
+ break;
+
+ default:
+ DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[Type].Type);
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Finally, unmap and close the file */
+ UnMapFile(SectionHandle, ViewBase);
+ NtClose(FileHandle);
+
+ return Status;
+}
+
+/* EOF */
diff --git a/base/setup/lib/bldrsup.h b/base/setup/lib/bldrsup.h
new file mode 100644
index 0000000000..a0965e88e9
--- /dev/null
+++ b/base/setup/lib/bldrsup.h
@@ -0,0 +1,59 @@
+/*
+ * PROJECT: ReactOS Setup Library
+ * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: NT 5.x family (MS Windows <= 2003, and ReactOS)
+ * boot loaders management.
+ * COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
+ */
+
+// TODO: Add support for NT 6.x family! (detection + BCD manipulation).
+
+#pragma once
+
+typedef enum _NTOS_BOOT_LOADER_TYPE
+{
+ FreeLdr, // ReactOS' FreeLoader
+ NtLdr, // Windows <= 2k3 NT "FlexBoot" OS Loader NTLDR
+// BootMgr, // Vista+ BCD-oriented BOOTMGR
+ BldrTypeMax
+} NTOS_BOOT_LOADER_TYPE;
+
+/*
+ * This structure is inspired from the EFI boot entry structures
+ * BOOT_ENTRY, BOOT_OPTIONS and FILE_PATH that are defined in ndk/iotypes.h .
+ */
+typedef struct _NTOS_BOOT_ENTRY
+{
+ // ULONG Version; // We might use the ntldr version here?? Or the "BootType" as in freeldr?
+ // ULONG Length;
+ // ULONG Id; // Boot entry number (position) in the list
+/** PCWSTR FriendlyName; // Human-readable boot entry description **/
+ PUNICODE_STRING FriendlyName;
+ PCWSTR BootFilePath; // Path to e.g. osloader.exe, or winload.efi
+ PCWSTR OsLoadPath; // The OS SystemRoot path
+ PCWSTR OsOptions;
+ PCWSTR OsLoadOptions;
+} NTOS_BOOT_ENTRY, *PNTOS_BOOT_ENTRY;
+
+
+typedef NTSTATUS
+(NTAPI *PENUM_BOOT_ENTRIES_ROUTINE)(
+ IN NTOS_BOOT_LOADER_TYPE Type,
+ IN PNTOS_BOOT_ENTRY BootEntry,
+ IN PVOID Parameter OPTIONAL);
+
+
+NTSTATUS
+FindNTOSBootLoader( // By handle
+ IN HANDLE PartitionHandle, // OPTIONAL
+ IN NTOS_BOOT_LOADER_TYPE Type,
+ OUT PULONG Version);
+
+NTSTATUS
+EnumerateNTOSBootEntries(
+ IN HANDLE PartitionHandle, // OPTIONAL
+ IN NTOS_BOOT_LOADER_TYPE Type,
+ IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
+ IN PVOID Parameter OPTIONAL);
+
+/* EOF */
diff --git a/base/setup/lib/osdetect.c b/base/setup/lib/osdetect.c
index a803910fc1..20611bdc02 100644
--- a/base/setup/lib/osdetect.c
+++ b/base/setup/lib/osdetect.c
@@ -12,9 +12,9 @@
#include "ntverrsrc.h"
// #include "arcname.h"
+#include "bldrsup.h"
#include "filesup.h"
#include "genlist.h"
-#include "inicache.h"
#include "partlist.h"
#include "arcname.h"
#include "osdetect.h"
@@ -78,31 +78,6 @@ BOOL IsWindowsOS(VOID)
#endif
-typedef enum _NTOS_BOOT_LOADER_TYPE
-{
- FreeLdr, // ReactOS' FreeLDR
- NtLdr, // Windows <= 2k3 NTLDR
-// BootMgr, // Vista+ BCD-oriented BOOTMGR
-} NTOS_BOOT_LOADER_TYPE;
-
-typedef struct _NTOS_BOOT_LOADER_FILES
-{
- NTOS_BOOT_LOADER_TYPE Type;
- PCWSTR LoaderExecutable;
- PCWSTR LoaderConfigurationFile;
- // EnumerateInstallations;
-} NTOS_BOOT_LOADER_FILES, *PNTOS_BOOT_LOADER_FILES;
-
-// Question 1: What if config file is optional?
-// Question 2: What if many config files are possible?
-NTOS_BOOT_LOADER_FILES NtosBootLoaders[] =
-{
- {FreeLdr, L"freeldr.sys", L"freeldr.ini"},
- {NtLdr , L"ntldr" , L"boot.ini"},
- {NtLdr , L"setupldr" , L"txtsetup.sif"},
-// {BootMgr, L"bootmgr" , ???}
-};
-
static BOOLEAN
IsValidNTOSInstallation_UStr(
@@ -130,339 +105,146 @@ AddNTOSInstallation(
IN PPARTENTRY PartEntry OPTIONAL,
IN PCWSTR InstallationName);
+typedef struct _ENUM_INSTALLS_DATA
+{
+ IN OUT PGENERIC_LIST List;
+ IN PPARTLIST PartList;
+ // IN PPARTENTRY PartEntry;
+} ENUM_INSTALLS_DATA, *PENUM_INSTALLS_DATA;
+
+// PENUM_BOOT_ENTRIES_ROUTINE
static NTSTATUS
-FreeLdrEnumerateInstallations(
- IN OUT PGENERIC_LIST List,
- IN PPARTLIST PartList,
- // IN PPARTENTRY PartEntry,
- IN PCHAR FileBuffer,
- IN ULONG FileLength)
+NTAPI
+EnumerateInstallations(
+ IN NTOS_BOOT_LOADER_TYPE Type,
+ IN PNTOS_BOOT_ENTRY BootEntry,
+ IN PVOID Parameter OPTIONAL)
{
- NTSTATUS Status;
- PINICACHE IniCache;
- PINICACHEITERATOR Iterator;
- PINICACHESECTION IniSection, OsIniSection;
- PWCHAR SectionName, KeyData;
- UNICODE_STRING InstallName;
+ PENUM_INSTALLS_DATA Data = (PENUM_INSTALLS_DATA)Parameter;
PNTOS_INSTALLATION NtOsInstall;
UNICODE_STRING SystemRootPath;
WCHAR SystemRoot[MAX_PATH];
WCHAR InstallNameW[MAX_PATH];
- /* Open an *existing* FreeLdr.ini configuration file */
- Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
- if (!NT_SUCCESS(Status))
- return Status;
+ ULONG DiskNumber = 0, PartitionNumber = 0;
+ PCWSTR PathComponent = NULL;
+ PDISKENTRY DiskEntry = NULL;
+ PPARTENTRY PartEntry = NULL;
- /* Get the "Operating Systems" section */
- IniSection = IniCacheGetSection(IniCache, L"Operating Systems");
- if (IniSection == NULL)
- {
- IniCacheDestroy(IniCache);
- return STATUS_UNSUCCESSFUL;
- }
+ /* We have a boot entry */
- /* Enumerate all the valid installations */
- Iterator = IniCacheFindFirstValue(IniSection, &SectionName, &KeyData);
- if (!Iterator) goto Quit;
- do
- {
- // FIXME: Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni).
- if (KeyData[0] == L'"')
- {
- /* Quoted name, copy up to the closing quote */
- PWCHAR Begin = &KeyData[1];
- PWCHAR End = wcschr(Begin, L'"');
- if (!End)
- End = Begin + wcslen(Begin);
- RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin);
- InstallName.Length = InstallName.MaximumLength;
- }
- else
- {
- /* Non-quoted name, copy everything */
- RtlInitUnicodeString(&InstallName, KeyData);
- }
-
- DPRINT1("Possible installation '%wZ' in OS section '%S'\n", &InstallName, SectionName);
-
- /* Search for an existing ReactOS entry */
- OsIniSection = IniCacheGetSection(IniCache, SectionName);
- if (!OsIniSection)
- continue;
+ UNICODE_STRING InstallName;
+ // /**/RtlInitUnicodeString(&InstallName, BootEntry->FriendlyName);/**/
+ InstallName = *BootEntry->FriendlyName;
+#if 0
+ if (Type == FreeLdr)
+ {
/* Check for supported boot type "Windows2003" */
- Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData);
- if (NT_SUCCESS(Status))
- {
- // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ?
- if ((KeyData == NULL) ||
- ( (_wcsicmp(KeyData, L"Windows2003") != 0) &&
- (_wcsicmp(KeyData, L"\"Windows2003\"") != 0) ))
- {
- /* This is not a ReactOS entry */
- continue;
- }
- }
- else
- {
- /* Certainly not a ReactOS installation */
- continue;
- }
-
- /* BootType is Windows2003. Now check SystemPath. */
- Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1(" A Win2k3 install '%wZ' without an ARC path?!\n", &InstallName);
- continue;
- }
- DPRINT1(" Found a candidate Win2k3 install '%wZ' with ARC path '%S'\n", &InstallName, KeyData);
-
- // TODO: Normalize the ARC path.
-
- /*
- * Check whether we already have an installation with this ARC path.
- * If this is the case, stop there.
- */
- NtOsInstall = FindExistingNTOSInstall(List, KeyData, NULL);
- if (NtOsInstall)
- {
- DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
- NtOsInstall->InstallationName, &NtOsInstall->SystemArcPath);
- continue;
- }
-
- /*
- * Convert the ARC path into an NT path, from which we will deduce
- * the real disk drive & partition on which the candidate installation
- * resides, as well verifying whether it is indeed an NTOS installation.
- */
- RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
- if (!ArcPathToNtPath(&SystemRootPath, KeyData, PartList))
+ // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ?
+ if ((BootType == NULL) ||
+ ( (_wcsicmp(BootType, L"Windows2003") != 0) &&
+ (_wcsicmp(BootType, L"\"Windows2003\"") != 0) ))
{
- DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", KeyData);
- continue;
- }
-
- DPRINT1("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n", KeyData, &SystemRootPath);
-
- /*
- * Check whether we already have an installation with this NT path.
- * If this is the case, stop there.
- */
- NtOsInstall = FindExistingNTOSInstall(List, NULL /*KeyData*/, &SystemRootPath);
- if (NtOsInstall)
- {
- DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
- NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath);
- continue;
- }
-
- /* Set SystemRootPath */
- DPRINT1("FreeLdrEnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);
-
- if (IsValidNTOSInstallation_UStr(&SystemRootPath))
- {
- ULONG DiskNumber = 0, PartitionNumber = 0;
- PCWSTR PathComponent = NULL;
- PDISKENTRY DiskEntry = NULL;
- PPARTENTRY PartEntry = NULL;
-
- DPRINT1("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n", KeyData, &SystemRootPath);
-
- /* From the NT path, compute the disk, partition and path components */
- if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
- {
- DPRINT1("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n",
- &SystemRootPath, DiskNumber, PartitionNumber, PathComponent);
-
- /* Retrieve the corresponding disk and partition */
- if (!GetDiskOrPartition(PartList, DiskNumber, PartitionNumber, &DiskEntry, &PartEntry))
- DPRINT1("GetDiskOrPartition(disk #%d, partition #%d) failed\n", DiskNumber, PartitionNumber);
- }
- else
- {
- DPRINT1("NtPathToDiskPartComponents(%wZ) failed\n", &SystemRootPath);
- }
-
- if (PartEntry && PartEntry->DriveLetter)
- {
- /* We have retrieved a partition that is mounted */
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%wZ\"",
- PartEntry->DriveLetter, PathComponent, &InstallName);
- }
- else
- {
- /* We failed somewhere, just show the NT path */
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%wZ\"",
- &SystemRootPath, &InstallName);
- }
- AddNTOSInstallation(List, KeyData, &SystemRootPath, PathComponent,
- DiskNumber, PartitionNumber, PartEntry,
- InstallNameW);
+ /* This is not a ReactOS entry */
+ /* Certainly not a ReactOS installation */
+ return STATUS_SUCCESS;
}
}
- while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
-
- IniCacheFindClose(Iterator);
-
-Quit:
- IniCacheDestroy(IniCache);
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-NtLdrEnumerateInstallations(
- IN OUT PGENERIC_LIST List,
- IN PPARTLIST PartList,
- // IN PPARTENTRY PartEntry,
- IN PCHAR FileBuffer,
- IN ULONG FileLength)
-{
- NTSTATUS Status;
- PINICACHE IniCache;
- PINICACHEITERATOR Iterator;
- PINICACHESECTION IniSection;
- PWCHAR SectionName, KeyData;
- UNICODE_STRING InstallName;
+#endif
- PNTOS_INSTALLATION NtOsInstall;
- UNICODE_STRING SystemRootPath;
- WCHAR SystemRoot[MAX_PATH];
- WCHAR InstallNameW[MAX_PATH];
+ DPRINT1(" Found a candidate Win2k3 install '%wZ' with ARC path '%S'\n",
+ &InstallName, BootEntry->OsLoadPath);
+ // DPRINT1(" Found a Win2k3 install '%wZ' with ARC path '%S'\n",
+ // &InstallName, BootEntry->OsLoadPath);
- /* Open an *existing* FreeLdr.ini configuration file */
- Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
- if (!NT_SUCCESS(Status))
- return Status;
+ // TODO: Normalize the ARC path.
- /* Get the "Operating Systems" section */
- IniSection = IniCacheGetSection(IniCache, L"operating systems");
- if (IniSection == NULL)
+ /*
+ * Check whether we already have an installation with this ARC path.
+ * If this is the case, stop there.
+ */
+ NtOsInstall = FindExistingNTOSInstall(Data->List, BootEntry->OsLoadPath, NULL);
+ if (NtOsInstall)
{
- IniCacheDestroy(IniCache);
- return STATUS_UNSUCCESSFUL;
+ DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
+ NtOsInstall->InstallationName, &NtOsInstall->SystemArcPath);
+ return STATUS_SUCCESS;
}
- /* Enumerate all the valid installations */
- Iterator = IniCacheFindFirstValue(IniSection, &SectionName, &KeyData);
- if (!Iterator) goto Quit;
- do
+ /*
+ * Convert the ARC path into an NT path, from which we will deduce
+ * the real disk drive & partition on which the candidate installation
+ * resides, as well verifying whether it is indeed an NTOS installation.
+ */
+ RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
+ if (!ArcPathToNtPath(&SystemRootPath, BootEntry->OsLoadPath, Data->PartList))
{
- // FIXME: Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni).
- if (KeyData[0] == L'"')
- {
- /* Quoted name, copy up to the closing quote */
- PWCHAR Begin = &KeyData[1];
- PWCHAR End = wcschr(Begin, L'"');
- if (!End)
- End = Begin + wcslen(Begin);
- RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin);
- InstallName.Length = InstallName.MaximumLength;
- }
- else
- {
- /* Non-quoted name, copy everything */
- RtlInitUnicodeString(&InstallName, KeyData);
- }
-
- DPRINT1("Possible installation '%wZ' with ARC path '%S'\n", &InstallName, SectionName);
-
- DPRINT1(" Found a Win2k3 install '%wZ' with ARC path '%S'\n", &InstallName, SectionName);
+ DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", BootEntry->OsLoadPath);
+ return STATUS_SUCCESS;
+ }
- // TODO: Normalize the ARC path.
+ DPRINT1("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n",
+ BootEntry->OsLoadPath, &SystemRootPath);
- /*
- * Check whether we already have an installation with this ARC path.
- * If this is the case, stop there.
- */
- NtOsInstall = FindExistingNTOSInstall(List, SectionName, NULL);
- if (NtOsInstall)
- {
- DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
- NtOsInstall->InstallationName, &NtOsInstall->SystemArcPath);
- continue;
- }
+ /*
+ * Check whether we already have an installation with this NT path.
+ * If this is the case, stop there.
+ */
+ NtOsInstall = FindExistingNTOSInstall(Data->List, NULL /*BootEntry->OsLoadPath*/, &SystemRootPath);
+ if (NtOsInstall)
+ {
+ DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
+ NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath);
+ return STATUS_SUCCESS;
+ }
- /*
- * Convert the ARC path into an NT path, from which we will deduce
- * the real disk drive & partition on which the candidate installation
- * resides, as well verifying whether it is indeed an NTOS installation.
- */
- RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
- if (!ArcPathToNtPath(&SystemRootPath, SectionName, PartList))
- {
- DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", SectionName);
- continue;
- }
+ DPRINT1("EnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);
- DPRINT1("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n", SectionName, &SystemRootPath);
+ /* Check if this is a valid NTOS installation; stop there if it isn't one */
+ if (!IsValidNTOSInstallation_UStr(&SystemRootPath))
+ return STATUS_SUCCESS;
- /*
- * Check whether we already have an installation with this NT path.
- * If this is the case, stop there.
- */
- NtOsInstall = FindExistingNTOSInstall(List, NULL /*SectionName*/, &SystemRootPath);
- if (NtOsInstall)
- {
- DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
- NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath);
- continue;
- }
+ DPRINT1("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n",
+ BootEntry->OsLoadPath, &SystemRootPath);
- /* Set SystemRootPath */
- DPRINT1("NtLdrEnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);
+ /* From the NT path, compute the disk, partition and path components */
+ if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
+ {
+ DPRINT1("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n",
+ &SystemRootPath, DiskNumber, PartitionNumber, PathComponent);
- if (IsValidNTOSInstallation_UStr(&SystemRootPath))
+ /* Retrieve the corresponding disk and partition */
+ if (!GetDiskOrPartition(Data->PartList, DiskNumber, PartitionNumber, &DiskEntry, &PartEntry))
{
- ULONG DiskNumber = 0, PartitionNumber = 0;
- PCWSTR PathComponent = NULL;
- PDISKENTRY DiskEntry = NULL;
- PPARTENTRY PartEntry = NULL;
-
- DPRINT1("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n", SectionName, &SystemRootPath);
-
- /* From the NT path, compute the disk, partition and path components */
- if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
- {
- DPRINT1("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n",
- &SystemRootPath, DiskNumber, PartitionNumber, PathComponent);
-
- /* Retrieve the corresponding disk and partition */
- if (!GetDiskOrPartition(PartList, DiskNumber, PartitionNumber, &DiskEntry, &PartEntry))
- DPRINT1("GetDiskOrPartition(disk #%d, partition #%d) failed\n", DiskNumber, PartitionNumber);
- }
- else
- {
- DPRINT1("NtPathToDiskPartComponents(%wZ) failed\n", &SystemRootPath);
- }
-
- if (PartEntry && PartEntry->DriveLetter)
- {
- /* We have retrieved a partition that is mounted */
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%wZ\"",
- PartEntry->DriveLetter, PathComponent, &InstallName);
- }
- else
- {
- /* We failed somewhere, just show the NT path */
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%wZ\"",
- &SystemRootPath, &InstallName);
- }
- AddNTOSInstallation(List, SectionName, &SystemRootPath, PathComponent,
- DiskNumber, PartitionNumber, PartEntry,
- InstallNameW);
+ DPRINT1("GetDiskOrPartition(disk #%d, partition #%d) failed\n",
+ DiskNumber, PartitionNumber);
}
}
- while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
+ else
+ {
+ DPRINT1("NtPathToDiskPartComponents(%wZ) failed\n", &SystemRootPath);
+ }
- IniCacheFindClose(Iterator);
+ if (PartEntry && PartEntry->DriveLetter)
+ {
+ /* We have retrieved a partition that is mounted */
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%wZ\"",
+ PartEntry->DriveLetter, PathComponent, &InstallName);
+ }
+ else
+ {
+ /* We failed somewhere, just show the NT path */
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%wZ\"",
+ &SystemRootPath, &InstallName);
+ }
+ AddNTOSInstallation(Data->List, BootEntry->OsLoadPath,
+ &SystemRootPath, PathComponent,
+ DiskNumber, PartitionNumber, PartEntry,
+ InstallNameW);
-Quit:
- IniCacheDestroy(IniCache);
return STATUS_SUCCESS;
}
@@ -599,28 +381,32 @@ IsValidNTOSInstallationByHandle(
IN HANDLE SystemRootDirectory)
{
BOOLEAN Success = FALSE;
+ PCWSTR PathName;
USHORT i;
UNICODE_STRING VendorName;
WCHAR VendorNameBuffer[MAX_PATH];
/* Check for the existence of \SystemRoot\System32 */
- if (!DoesPathExist(SystemRootDirectory, L"System32\\"))
+ PathName = L"System32\\";
+ if (!DoesPathExist(SystemRootDirectory, PathName))
{
- // DPRINT1("Failed to open directory '%wZ', Status 0x%08lx\n", &FileName, Status);
+ // DPRINT1("Failed to open directory '%S', Status 0x%08lx\n", PathName, Status);
return FALSE;
}
/* Check for the existence of \SystemRoot\System32\drivers */
- if (!DoesPathExist(SystemRootDirectory, L"System32\\drivers\\"))
+ PathName = L"System32\\drivers\\";
+ if (!DoesPathExist(SystemRootDirectory, PathName))
{
- // DPRINT1("Failed to open directory '%wZ', Status 0x%08lx\n", &FileName, Status);
+ // DPRINT1("Failed to open directory '%S', Status 0x%08lx\n", PathName, Status);
return FALSE;
}
/* Check for the existence of \SystemRoot\System32\config */
- if (!DoesPathExist(SystemRootDirectory, L"System32\\config\\"))
+ PathName = L"System32\\config\\";
+ if (!DoesPathExist(SystemRootDirectory, PathName))
{
- // DPRINT1("Failed to open directory '%wZ', Status 0x%08lx\n", &FileName, Status);
+ // DPRINT1("Failed to open directory '%S', Status 0x%08lx\n", PathName, Status);
return FALSE;
}
@@ -629,14 +415,16 @@ IsValidNTOSInstallationByHandle(
* Check for the existence of SYSTEM and SOFTWARE hives in \SystemRoot\System32\config
* (but we don't check here whether they are actually valid).
*/
- if (!DoesFileExist(SystemRootDirectory, L"System32\\config\\SYSTEM"))
+ PathName = L"System32\\config\\SYSTEM";
+ if (!DoesFileExist(SystemRootDirectory, PathName))
{
- // DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &FileName, Status);
+ // DPRINT1("Failed to open file '%S', Status 0x%08lx\n", PathName, Status);
return FALSE;
}
- if (!DoesFileExist(SystemRootDirectory, L"System32\\config\\SOFTWARE"))
+ PathName = L"System32\\config\\SOFTWARE";
+ if (!DoesFileExist(SystemRootDirectory, PathName))
{
- // DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &FileName, Status);
+ // DPRINT1("Failed to open file '%S', Status 0x%08lx\n", PathName, Status);
return FALSE;
}
#endif
@@ -644,9 +432,10 @@ IsValidNTOSInstallationByHandle(
RtlInitEmptyUnicodeString(&VendorName, VendorNameBuffer, sizeof(VendorNameBuffer));
/* Check for the existence of \SystemRoot\System32\ntoskrnl.exe and retrieves its vendor name */
- Success = CheckForValidPEAndVendor(SystemRootDirectory, L"System32\\ntoskrnl.exe", &VendorName);
+ PathName = L"System32\\ntoskrnl.exe";
+ Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &VendorName);
if (!Success)
- DPRINT1("Kernel file ntoskrnl.exe is either not a PE file, or does not have any vendor?\n");
+ DPRINT1("Kernel executable '%S' is either not a PE file, or does not have any vendor?\n", PathName);
/* The kernel gives the OS its flavour */
if (Success)
@@ -666,9 +455,10 @@ IsValidNTOSInstallationByHandle(
/* OPTIONAL: Check for the existence of \SystemRoot\System32\ntkrnlpa.exe */
/* Check for the existence of \SystemRoot\System32\ntdll.dll and retrieves its vendor name */
- Success = CheckForValidPEAndVendor(SystemRootDirectory, L"System32\\ntdll.dll", &VendorName);
+ PathName = L"System32\\ntdll.dll";
+ Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &VendorName);
if (!Success)
- DPRINT1("User-mode file ntdll.dll is either not a PE file, or does not have any vendor?\n");
+ DPRINT1("User-mode DLL '%S' is either not a PE file, or does not have any vendor?\n", PathName);
if (Success)
{
for (i = 0; i < ARRAYSIZE(KnownVendors); ++i)
@@ -676,7 +466,7 @@ IsValidNTOSInstallationByHandle(
if (!!FindSubStrI(VendorName.Buffer, KnownVendors[i]))
{
/* We have found a correct vendor combination */
- DPRINT1("IsValidNTOSInstallation: The user-mode file ntdll.dll is from %S\n", KnownVendors[i]);
+ DPRINT1("IsValidNTOSInstallation: The user-mode DLL '%S' is from %S\n", PathName, KnownVendors[i]);
break;
}
}
@@ -876,15 +666,13 @@ FindNTOSInstallations(
NTSTATUS Status;
ULONG DiskNumber = PartEntry->DiskEntry->DiskNumber;
ULONG PartitionNumber = PartEntry->PartitionNumber;
- HANDLE PartitionHandle, FileHandle;
+ HANDLE PartitionHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING PartitionRootPath;
- UINT i;
- HANDLE SectionHandle;
- // SIZE_T ViewSize;
- ULONG FileSize;
- PVOID ViewBase;
+ NTOS_BOOT_LOADER_TYPE Type;
+ ENUM_INSTALLS_DATA Data;
+ ULONG Version;
WCHAR PathBuffer[MAX_PATH];
/* Set PartitionRootPath */
@@ -912,49 +700,26 @@ FindNTOSInstallations(
return;
}
+ Data.List = List;
+ Data.PartList = PartList;
+
/* Try to see whether we recognize some NT boot loaders */
- for (i = 0; i < ARRAYSIZE(NtosBootLoaders); ++i)
+ for (Type = FreeLdr; Type < BldrTypeMax; ++Type)
{
- /* Check whether the loader executable exists */
- if (!DoesFileExist(PartitionHandle, NtosBootLoaders[i].LoaderExecutable))
- {
- /* The loader does not exist, continue with another one */
- DPRINT1("Loader executable '%S' does not exist, continue with another one...\n", NtosBootLoaders[i].LoaderExecutable);
- continue;
- }
-
- /* Check whether the loader configuration file exists */
- Status = OpenAndMapFile(PartitionHandle, NtosBootLoaders[i].LoaderConfigurationFile,
- &FileHandle, &SectionHandle, &ViewBase, &FileSize);
+ Status = FindNTOSBootLoader(PartitionHandle, Type, &Version);
if (!NT_SUCCESS(Status))
{
/* The loader does not exist, continue with another one */
- // FIXME: Consider it might be optional??
- DPRINT1("Loader configuration file '%S' does not exist, continue with another one...\n", NtosBootLoaders[i].LoaderConfigurationFile);
+ DPRINT1("Loader type '%d' does not exist, or an error happened (Status 0x%08lx), continue with another one...\n",
+ Type, Status);
continue;
}
- /* The loader configuration file exists, interpret it to find valid installations */
- DPRINT1("Analyse the OS installations inside '%S' in disk #%d, partition #%d\n",
- NtosBootLoaders[i].LoaderConfigurationFile, DiskNumber, PartitionNumber);
- switch (NtosBootLoaders[i].Type)
- {
- case FreeLdr:
- Status = FreeLdrEnumerateInstallations(List, PartList, ViewBase, FileSize);
- break;
-
- case NtLdr:
- Status = NtLdrEnumerateInstallations(List, PartList, ViewBase, FileSize);
- break;
-
- default:
- DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[i].Type);
- Status = STATUS_SUCCESS;
- }
+ /* The loader exists, try to enumerate its boot entries */
+ DPRINT1("Analyse the OS installations for loader type '%d' in disk #%d, partition #%d\n",
+ Type, DiskNumber, PartitionNumber);
- /* Finally, unmap and close the file */
- UnMapFile(SectionHandle, ViewBase);
- NtClose(FileHandle);
+ EnumerateNTOSBootEntries(PartitionHandle, Type, EnumerateInstallations, &Data);
}
/* Close the partition */
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=92b99b865eca36e356626…
commit 92b99b865eca36e35662641f09680bb86ea2c5fe
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue May 23 11:39:12 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Jun 3 22:12:35 2018 +0200
[SETUPLIB][USETUP] Move some code to the SetupLib.
- filesup.c's functions ConcatPaths(), Does[Path|File]Exist(), NtPathToDiskPartComponents(), OpenAndMapFile(), UnMapFile();
- Move the inicache library to setuplib as it'll be used for the 1st stage GUI setup too (indeed, there is no good INI file API
under Win32; the Win32 profile "API" is just good enough to manipulate the win16 ini files, and are here anyways for backward
compatibility purposes only);
- Move the OS detector too.
- Remove the duplicated ConcatPaths() code in arcname.c.
svn path=/branches/setup_improvements/; revision=74634
svn path=/branches/setup_improvements/; revision=74638
---
base/setup/lib/CMakeLists.txt | 3 +
base/setup/lib/arcname.c | 136 +++++-------
base/setup/lib/filesup.c | 372 +++++++++++++++++++++++++++++++++
base/setup/lib/filesup.h | 57 ++++++
base/setup/{usetup => lib}/inicache.c | 31 +--
base/setup/{usetup => lib}/inicache.h | 27 +--
base/setup/{usetup => lib}/osdetect.c | 15 +-
base/setup/{usetup => lib}/osdetect.h | 4 +
base/setup/lib/precomp.h | 5 +-
base/setup/lib/setuplib.h | 3 +
base/setup/usetup/CMakeLists.txt | 2 -
base/setup/usetup/filesup.c | 375 +---------------------------------
base/setup/usetup/filesup.h | 57 ------
base/setup/usetup/usetup.h | 2 -
14 files changed, 520 insertions(+), 569 deletions(-)
diff --git a/base/setup/lib/CMakeLists.txt b/base/setup/lib/CMakeLists.txt
index a37be9d1fb..6d687deb1a 100644
--- a/base/setup/lib/CMakeLists.txt
+++ b/base/setup/lib/CMakeLists.txt
@@ -1,9 +1,12 @@
list(APPEND SOURCE
arcname.c
+ filesup.c
fsutil.c
genlist.c
+ inicache.c
ntverrsrc.c
+ osdetect.c
partlist.c
precomp.h)
diff --git a/base/setup/lib/arcname.c b/base/setup/lib/arcname.c
index 60af00dbb1..f40b79173e 100644
--- a/base/setup/lib/arcname.c
+++ b/base/setup/lib/arcname.c
@@ -23,6 +23,7 @@
#include "precomp.h"
+#include "filesup.h"
#include "partlist.h"
#include "arcname.h"
@@ -114,7 +115,7 @@ ArcGetNextTokenA(
OUT PANSI_STRING TokenSpecifier,
OUT PULONG Key)
{
- HRESULT hr;
+ NTSTATUS Status;
PCSTR p = ArcPath;
ULONG SpecifierLength;
ULONG KeyValue;
@@ -154,9 +155,10 @@ ArcGetNextTokenA(
#endif
/* We should have succeeded, copy the token specifier in the buffer */
- hr = StringCbCopyNA(TokenSpecifier->Buffer, TokenSpecifier->MaximumLength,
- ArcPath, SpecifierLength);
- if (FAILED(hr))
+ Status = RtlStringCbCopyNA(TokenSpecifier->Buffer,
+ TokenSpecifier->MaximumLength,
+ ArcPath, SpecifierLength);
+ if (!NT_SUCCESS(Status))
return NULL;
TokenSpecifier->Length = strlen(TokenSpecifier->Buffer) * sizeof(CHAR);
@@ -174,7 +176,7 @@ ArcGetNextTokenU(
OUT PUNICODE_STRING TokenSpecifier,
OUT PULONG Key)
{
- HRESULT hr;
+ NTSTATUS Status;
PCWSTR p = ArcPath;
ULONG SpecifierLength;
ULONG KeyValue;
@@ -216,9 +218,10 @@ ArcGetNextTokenU(
#endif
/* We should have succeeded, copy the token specifier in the buffer */
- hr = StringCbCopyNW(TokenSpecifier->Buffer, TokenSpecifier->MaximumLength,
- ArcPath, SpecifierLength);
- if (FAILED(hr))
+ Status = RtlStringCbCopyNW(TokenSpecifier->Buffer,
+ TokenSpecifier->MaximumLength,
+ ArcPath, SpecifierLength);
+ if (!NT_SUCCESS(Status))
return NULL;
TokenSpecifier->Length = wcslen(TokenSpecifier->Buffer) * sizeof(WCHAR);
@@ -298,7 +301,7 @@ ArcPathNormalize(
OUT PUNICODE_STRING NormalizedArcPath,
IN PCWSTR ArcPath)
{
- HRESULT hr;
+ NTSTATUS Status;
PCWSTR EndOfArcName;
PCWSTR p;
@@ -315,24 +318,32 @@ ArcPathNormalize(
while ((p = wcsstr(ArcPath, L"()")) && (p < EndOfArcName))
{
#if 0
- hr = StringCbCopyNW(NormalizedArcPath->Buffer, NormalizedArcPath->MaximumLength,
- ArcPath, (p - ArcPath) * sizeof(WCHAR));
+ Status = RtlStringCbCopyNW(NormalizedArcPath->Buffer,
+ NormalizedArcPath->MaximumLength,
+ ArcPath, (p - ArcPath) * sizeof(WCHAR));
#else
- hr = StringCbCatNW(NormalizedArcPath->Buffer, NormalizedArcPath->MaximumLength,
- ArcPath, (p - ArcPath) * sizeof(WCHAR));
+ Status = RtlStringCbCatNW(NormalizedArcPath->Buffer,
+ NormalizedArcPath->MaximumLength,
+ ArcPath, (p - ArcPath) * sizeof(WCHAR));
#endif
- if (FAILED(hr))
+ if (!NT_SUCCESS(Status))
return FALSE;
- hr = StringCbCatW(NormalizedArcPath->Buffer, NormalizedArcPath->MaximumLength, L"(0)");
- if (FAILED(hr))
+
+ Status = RtlStringCbCatW(NormalizedArcPath->Buffer,
+ NormalizedArcPath->MaximumLength,
+ L"(0)");
+ if (!NT_SUCCESS(Status))
return FALSE;
#if 0
NormalizedArcPath->Buffer += wcslen(NormalizedArcPath->Buffer);
#endif
ArcPath = p + 2;
}
- hr = StringCbCatW(NormalizedArcPath->Buffer, NormalizedArcPath->MaximumLength, ArcPath);
- if (FAILED(hr))
+
+ Status = RtlStringCbCatW(NormalizedArcPath->Buffer,
+ NormalizedArcPath->MaximumLength,
+ ArcPath);
+ if (!NT_SUCCESS(Status))
return FALSE;
NormalizedArcPath->Length = wcslen(NormalizedArcPath->Buffer) * sizeof(WCHAR);
@@ -450,7 +461,7 @@ ResolveArcNameManually(
IN OUT PCWSTR* ArcNamePath,
IN PPARTLIST PartList OPTIONAL)
{
- HRESULT hr;
+ NTSTATUS Status;
WCHAR TokenBuffer[50];
UNICODE_STRING Token;
PCWSTR p, q;
@@ -525,7 +536,8 @@ ResolveArcNameManually(
return STATUS_NOT_SUPPORTED;
}
- hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\Ramdisk%lu", AdapterKey);
+ Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
+ L"\\Device\\Ramdisk%lu", AdapterKey);
goto Quit;
}
}
@@ -644,14 +656,23 @@ ResolveArcNameManually(
if (ControllerType == CdRomController) // and so, AdapterType == ScsiAdapter and PeripheralType == FDiskPeripheral
- hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\Scsi\\CdRom%lu", ControllerKey);
+ {
+ Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
+ L"\\Device\\Scsi\\CdRom%lu", ControllerKey);
+ }
else
/* Now, ControllerType == DiskController */
if (PeripheralType == CdRomPeripheral)
- hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\CdRom%lu", PeripheralKey);
+ {
+ Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
+ L"\\Device\\CdRom%lu", PeripheralKey);
+ }
else
if (PeripheralType == FDiskPeripheral)
- hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\Floppy%lu", PeripheralKey);
+ {
+ Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
+ L"\\Device\\Floppy%lu", PeripheralKey);
+ }
else
if (PeripheralType == RDiskPeripheral)
{
@@ -676,78 +697,30 @@ ResolveArcNameManually(
ASSERT(PartEntry->DiskEntry == DiskEntry);
}
- hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\Harddisk%lu\\Partition%lu",
- DiskEntry->DiskNumber, PartitionNumber);
+ Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ DiskEntry->DiskNumber, PartitionNumber);
}
#if 0
else
if (PeripheralType == VDiskPeripheral)
{
// TODO: Check how Win 7+ deals with virtual disks.
- hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\VirtualHarddisk%lu\\Partition%lu",
- PeripheralKey, PartitionNumber);
+ Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
+ L"\\Device\\VirtualHarddisk%lu\\Partition%lu",
+ PeripheralKey, PartitionNumber);
}
#endif
Quit:
- if (FAILED(hr))
- {
- /*
- * We can directly cast the HRESULTs into NTSTATUS since the error codes
- * returned by StringCbPrintfW:
- * STRSAFE_E_INVALID_PARAMETER == 0x80070057,
- * STRSAFE_E_INSUFFICIENT_BUFFER == 0x8007007a,
- * do not have assigned values in the NTSTATUS space.
- */
- return (NTSTATUS)hr;
- }
+ if (!NT_SUCCESS(Status))
+ return Status;
*ArcNamePath = p;
return STATUS_SUCCESS;
}
-/**** FIXME: Redundant with filesup.c ! ****\
-|** (but filesup.c is not yet included in **|
-\** setuplib, hence this code copy) **/
-
-static
-HRESULT
-ConcatPaths(
- IN OUT PWSTR PathElem1,
- IN SIZE_T cchPathSize,
- IN PCWSTR PathElem2 OPTIONAL)
-{
- HRESULT hr;
- SIZE_T cchPathLen;
-
- if (!PathElem2)
- return S_OK;
- if (cchPathSize <= 1)
- return S_OK;
-
- cchPathLen = min(cchPathSize, wcslen(PathElem1));
-
- if (PathElem2[0] != L'\\' && cchPathLen > 0 && PathElem1[cchPathLen-1] != L'\\')
- {
- /* PathElem2 does not start with '\' and PathElem1 does not end with '\' */
- hr = StringCchCatW(PathElem1, cchPathSize, L"\\");
- if (FAILED(hr))
- return hr;
- }
- else if (PathElem2[0] == L'\\' && cchPathLen > 0 && PathElem1[cchPathLen-1] == L'\\')
- {
- /* PathElem2 starts with '\' and PathElem1 ends with '\' */
- while (*PathElem2 == L'\\')
- ++PathElem2; // Skip any backslash
- }
- hr = StringCchCatW(PathElem1, cchPathSize, PathElem2);
- return hr;
-}
-
-/*******************************************/
-
-
BOOLEAN
ArcPathToNtPath(
OUT PUNICODE_STRING NtPath,
@@ -825,9 +798,8 @@ ArcPathToNtPath(
*/
if (BeginOfPath && *BeginOfPath)
{
- HRESULT hr;
- hr = ConcatPaths(NtPath->Buffer, NtPath->MaximumLength / sizeof(WCHAR), BeginOfPath);
- if (FAILED(hr))
+ Status = ConcatPaths(NtPath->Buffer, NtPath->MaximumLength / sizeof(WCHAR), BeginOfPath);
+ if (!NT_SUCCESS(Status))
{
/* Buffer not large enough, or whatever...: just bail out */
return FALSE;
diff --git a/base/setup/lib/filesup.c b/base/setup/lib/filesup.c
new file mode 100644
index 0000000000..7550905895
--- /dev/null
+++ b/base/setup/lib/filesup.c
@@ -0,0 +1,372 @@
+/*
+ * PROJECT: ReactOS Setup Library
+ * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: File support functions.
+ * COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS ****************************************************************/
+NTSTATUS
+ConcatPaths(
+ IN OUT PWSTR PathElem1,
+ IN SIZE_T cchPathSize,
+ IN PCWSTR PathElem2 OPTIONAL)
+{
+ NTSTATUS Status;
+ SIZE_T cchPathLen;
+
+ if (!PathElem2)
+ return STATUS_SUCCESS;
+ if (cchPathSize <= 1)
+ return STATUS_SUCCESS;
+
+ cchPathLen = min(cchPathSize, wcslen(PathElem1));
+
+ if (PathElem2[0] != L'\\' && cchPathLen > 0 && PathElem1[cchPathLen-1] != L'\\')
+ {
+ /* PathElem2 does not start with '\' and PathElem1 does not end with '\' */
+ Status = RtlStringCchCatW(PathElem1, cchPathSize, L"\\");
+ if (!NT_SUCCESS(Status))
+ return Status;
+ }
+ else if (PathElem2[0] == L'\\' && cchPathLen > 0 && PathElem1[cchPathLen-1] == L'\\')
+ {
+ /* PathElem2 starts with '\' and PathElem1 ends with '\' */
+ while (*PathElem2 == L'\\')
+ ++PathElem2; // Skip any backslash
+ }
+ Status = RtlStringCchCatW(PathElem1, cchPathSize, PathElem2);
+ return Status;
+}
+
+//
+// NOTE: It may be possible to merge both DoesPathExist and DoesFileExist...
+//
+BOOLEAN
+DoesPathExist(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName)
+{
+ NTSTATUS Status;
+ HANDLE FileHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING Name;
+
+ RtlInitUnicodeString(&Name, PathName);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ RootDirectory,
+ NULL);
+
+ Status = NtOpenFile(&FileHandle,
+ FILE_LIST_DIRECTORY | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
+ if (NT_SUCCESS(Status))
+ NtClose(FileHandle);
+ else
+ DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &Name, Status);
+
+ return NT_SUCCESS(Status);
+}
+
+BOOLEAN
+DoesFileExist(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName OPTIONAL,
+ IN PCWSTR FileName)
+{
+ NTSTATUS Status;
+ HANDLE FileHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING Name;
+ WCHAR FullName[MAX_PATH];
+
+ if (PathName)
+ RtlStringCchCopyW(FullName, ARRAYSIZE(FullName), PathName);
+ else
+ FullName[0] = UNICODE_NULL;
+
+ if (FileName)
+ ConcatPaths(FullName, ARRAYSIZE(FullName), FileName);
+
+ RtlInitUnicodeString(&Name, FullName);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ RootDirectory,
+ NULL);
+
+ Status = NtOpenFile(&FileHandle,
+ GENERIC_READ | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+ if (NT_SUCCESS(Status))
+ NtClose(FileHandle);
+ else
+ DPRINT1("Failed to open file %wZ, Status 0x%08lx\n", &Name, Status);
+
+ return NT_SUCCESS(Status);
+}
+
+/*
+ * The format of NtPath should be:
+ * \Device\HarddiskXXX\PartitionYYY[\path] ,
+ * where XXX and YYY respectively represent the hard disk and partition numbers,
+ * and [\path] represent an optional path (separated by '\\').
+ *
+ * If a NT path of such a form is correctly parsed, the function returns respectively:
+ * - in pDiskNumber: the hard disk number XXX,
+ * - in pPartNumber: the partition number YYY,
+ * - in PathComponent: pointer value (inside NtPath) to the beginning of \path.
+ *
+ * NOTE: The function does not accept leading whitespace.
+ */
+BOOLEAN
+NtPathToDiskPartComponents(
+ IN PCWSTR NtPath,
+ OUT PULONG pDiskNumber,
+ OUT PULONG pPartNumber,
+ OUT PCWSTR* PathComponent OPTIONAL)
+{
+ ULONG DiskNumber, PartNumber;
+ PCWSTR Path;
+
+ *pDiskNumber = 0;
+ *pPartNumber = 0;
+ if (PathComponent) *PathComponent = NULL;
+
+ Path = NtPath;
+
+ if (_wcsnicmp(Path, L"\\Device\\Harddisk", 16) != 0)
+ {
+ /* The NT path doesn't start with the prefix string, thus it cannot be a hard disk device path */
+ DPRINT1("'%S' : Not a possible hard disk device.\n", NtPath);
+ return FALSE;
+ }
+
+ Path += 16;
+
+ /* A number must be present now */
+ if (!iswdigit(*Path))
+ {
+ DPRINT1("'%S' : expected a number! Not a regular hard disk device.\n", Path);
+ return FALSE;
+ }
+ DiskNumber = wcstoul(Path, (PWSTR*)&Path, 10);
+
+ /* Either NULL termination, or a path separator must be present now */
+ if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
+ {
+ DPRINT1("'%S' : expected a path separator!\n", Path);
+ return FALSE;
+ }
+
+ if (!*Path)
+ {
+ DPRINT1("The path only specified a hard disk (and nothing else, like a partition...), so we stop there.\n");
+ goto Quit;
+ }
+
+ /* Here, *Path == L'\\' */
+
+ if (_wcsnicmp(Path, L"\\Partition", 10) != 0)
+ {
+ /* Actually, \Partition is optional so, if we don't have it, we still return success. Or should we? */
+ DPRINT1("'%S' : unexpected format!\n", NtPath);
+ goto Quit;
+ }
+
+ Path += 10;
+
+ /* A number must be present now */
+ if (!iswdigit(*Path))
+ {
+ /* If we don't have a number it means this part of path is actually not a partition specifier, so we shouldn't fail either. Or should we? */
+ DPRINT1("'%S' : expected a number!\n", Path);
+ goto Quit;
+ }
+ PartNumber = wcstoul(Path, (PWSTR*)&Path, 10);
+
+ /* Either NULL termination, or a path separator must be present now */
+ if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
+ {
+ /* We shouldn't fail here because it just means this part of path is actually not a partition specifier. Or should we? */
+ DPRINT1("'%S' : expected a path separator!\n", Path);
+ goto Quit;
+ }
+
+ /* OK, here we really have a partition specifier: return its number */
+ *pPartNumber = PartNumber;
+
+Quit:
+ /* Return the disk number */
+ *pDiskNumber = DiskNumber;
+
+ /* Return the path component also, if the user wants it */
+ if (PathComponent) *PathComponent = Path;
+
+ return TRUE;
+}
+
+NTSTATUS
+OpenAndMapFile(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName OPTIONAL,
+ IN PCWSTR FileName, // OPTIONAL
+ OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
+ OUT PHANDLE SectionHandle,
+ OUT PVOID* BaseAddress,
+ OUT PULONG FileSize OPTIONAL)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ SIZE_T ViewSize;
+ PVOID ViewBase;
+ UNICODE_STRING Name;
+ WCHAR FullName[MAX_PATH];
+
+ if (PathName)
+ RtlStringCchCopyW(FullName, ARRAYSIZE(FullName), PathName);
+ else
+ FullName[0] = UNICODE_NULL;
+
+ if (FileName)
+ ConcatPaths(FullName, ARRAYSIZE(FullName), FileName);
+
+ RtlInitUnicodeString(&Name, FullName);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ RootDirectory,
+ NULL);
+
+ *FileHandle = NULL;
+ *SectionHandle = NULL;
+
+ Status = NtOpenFile(FileHandle,
+ GENERIC_READ | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &Name, Status);
+ return Status;
+ }
+
+ if (FileSize)
+ {
+ /* Query the file size */
+ FILE_STANDARD_INFORMATION FileInfo;
+ Status = NtQueryInformationFile(*FileHandle,
+ &IoStatusBlock,
+ &FileInfo,
+ sizeof(FileInfo),
+ FileStandardInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
+ NtClose(*FileHandle);
+ *FileHandle = NULL;
+ return Status;
+ }
+
+ if (FileInfo.EndOfFile.HighPart != 0)
+ DPRINT1("WARNING!! The file '%wZ' is too large!\n", &Name);
+
+ *FileSize = FileInfo.EndOfFile.LowPart;
+
+ DPRINT("File size: %lu\n", *FileSize);
+ }
+
+ /* Map the file in memory */
+
+ /* Create the section */
+ Status = NtCreateSection(SectionHandle,
+ SECTION_MAP_READ,
+ NULL,
+ NULL,
+ PAGE_READONLY,
+ SEC_COMMIT /* | SEC_IMAGE (_NO_EXECUTE) */,
+ *FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create a memory section for file '%wZ', Status 0x%08lx\n", &Name, Status);
+ NtClose(*FileHandle);
+ *FileHandle = NULL;
+ return Status;
+ }
+
+ /* Map the section */
+ ViewSize = 0;
+ ViewBase = NULL;
+ Status = NtMapViewOfSection(*SectionHandle,
+ NtCurrentProcess(),
+ &ViewBase,
+ 0, 0,
+ NULL,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_READONLY);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map a view for file %wZ, Status 0x%08lx\n", &Name, Status);
+ NtClose(*SectionHandle);
+ *SectionHandle = NULL;
+ NtClose(*FileHandle);
+ *FileHandle = NULL;
+ return Status;
+ }
+
+ *BaseAddress = ViewBase;
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN
+UnMapFile(
+ IN HANDLE SectionHandle,
+ IN PVOID BaseAddress)
+{
+ NTSTATUS Status;
+ BOOLEAN Success = TRUE;
+
+ Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UnMapFile: NtUnmapViewOfSection(0x%p) failed with Status 0x%08lx\n",
+ BaseAddress, Status);
+ Success = FALSE;
+ }
+ Status = NtClose(SectionHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UnMapFile: NtClose(0x%p) failed with Status 0x%08lx\n",
+ SectionHandle, Status);
+ Success = FALSE;
+ }
+
+ return Success;
+}
+
+/* EOF */
diff --git a/base/setup/lib/filesup.h b/base/setup/lib/filesup.h
new file mode 100644
index 0000000000..bf5a2835f2
--- /dev/null
+++ b/base/setup/lib/filesup.h
@@ -0,0 +1,57 @@
+/*
+ * PROJECT: ReactOS Setup Library
+ * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: File support functions.
+ * COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
+ */
+
+#pragma once
+
+#if 0
+
+BOOLEAN
+IsValidPath(
+ IN PCWSTR InstallDir);
+
+#endif
+
+NTSTATUS
+ConcatPaths(
+ IN OUT PWSTR PathElem1,
+ IN SIZE_T cchPathSize,
+ IN PCWSTR PathElem2 OPTIONAL);
+
+BOOLEAN
+DoesPathExist(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName);
+
+BOOLEAN
+DoesFileExist(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName OPTIONAL,
+ IN PCWSTR FileName);
+
+BOOLEAN
+NtPathToDiskPartComponents(
+ IN PCWSTR NtPath,
+ OUT PULONG pDiskNumber,
+ OUT PULONG pPartNumber,
+ OUT PCWSTR* PathComponent OPTIONAL);
+
+NTSTATUS
+OpenAndMapFile(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName OPTIONAL,
+ IN PCWSTR FileName, // OPTIONAL
+ OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
+ OUT PHANDLE SectionHandle,
+ OUT PVOID* BaseAddress,
+ OUT PULONG FileSize OPTIONAL);
+
+BOOLEAN
+UnMapFile(
+ IN HANDLE SectionHandle,
+ IN PVOID BaseAddress);
+
+/* EOF */
diff --git a/base/setup/usetup/inicache.c b/base/setup/lib/inicache.c
similarity index 95%
rename from base/setup/usetup/inicache.c
rename to base/setup/lib/inicache.c
index 38dd44fefd..295d957057 100644
--- a/base/setup/usetup/inicache.c
+++ b/base/setup/lib/inicache.c
@@ -1,32 +1,15 @@
/*
- * ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS text-mode setup
- * FILE: base/setup/usetup/inicache.c
- * PURPOSE: INI file parser that caches contents of INI file in memory
- * PROGRAMMER: Royce Mitchell III
+ * PROJECT: ReactOS Setup Library
+ * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: INI file parser that caches contents of INI file in memory.
+ * COPYRIGHT: Copyright 2002-2018 Royce Mitchell III
*/
/* INCLUDES *****************************************************************/
-#include "usetup.h"
+#include "precomp.h"
+
+#include "inicache.h"
#define NDEBUG
#include <debug.h>
diff --git a/base/setup/usetup/inicache.h b/base/setup/lib/inicache.h
similarity index 64%
rename from base/setup/usetup/inicache.h
rename to base/setup/lib/inicache.h
index 33db2a38e9..d9b7a3d288 100644
--- a/base/setup/usetup/inicache.h
+++ b/base/setup/lib/inicache.h
@@ -1,27 +1,8 @@
/*
- * ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS text-mode setup
- * FILE: base/setup/usetup/inicache.h
- * PURPOSE: INI file parser that caches contents of INI file in memory
- * PROGRAMMER: Royce Mitchell III
+ * PROJECT: ReactOS Setup Library
+ * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: INI file parser that caches contents of INI file in memory.
+ * COPYRIGHT: Copyright 2002-2018 Royce Mitchell III
*/
#pragma once
diff --git a/base/setup/usetup/osdetect.c b/base/setup/lib/osdetect.c
similarity index 99%
rename from base/setup/usetup/osdetect.c
rename to base/setup/lib/osdetect.c
index 97cc6430ea..a695da7466 100644
--- a/base/setup/usetup/osdetect.c
+++ b/base/setup/lib/osdetect.c
@@ -6,7 +6,18 @@
* COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
*/
-#include "usetup.h"
+/* INCLUDES *****************************************************************/
+
+#include "precomp.h"
+
+#include "ntverrsrc.h"
+// #include "arcname.h"
+#include "filesup.h"
+#include "genlist.h"
+#include "inicache.h"
+#include "partlist.h"
+#include "arcname.h"
+#include "osdetect.h"
// HACK!
#include <strsafe.h>
@@ -17,8 +28,6 @@
/* GLOBALS ******************************************************************/
-extern PPARTLIST PartitionList;
-
/* Language-independent Vendor strings */
static const PCWSTR KnownVendors[] = { L"ReactOS", L"Microsoft" };
diff --git a/base/setup/usetup/osdetect.h b/base/setup/lib/osdetect.h
similarity index 97%
rename from base/setup/usetup/osdetect.h
rename to base/setup/lib/osdetect.h
index 5076784086..b20fc427b7 100644
--- a/base/setup/usetup/osdetect.h
+++ b/base/setup/lib/osdetect.h
@@ -6,6 +6,8 @@
* COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
*/
+#pragma once
+
typedef struct _NTOS_INSTALLATION
{
LIST_ENTRY ListEntry;
@@ -24,3 +26,5 @@ typedef struct _NTOS_INSTALLATION
PGENERIC_LIST
CreateNTOSInstallationsList(
IN PPARTLIST List);
+
+/* EOF */
diff --git a/base/setup/lib/precomp.h b/base/setup/lib/precomp.h
index ea82da4f39..0ce5c12e09 100644
--- a/base/setup/lib/precomp.h
+++ b/base/setup/lib/precomp.h
@@ -16,8 +16,6 @@
#include <winreg.h>
#include <winuser.h>
-#include <strsafe.h>
-
#define NTOS_MODE_USER
#include <ndk/cmfuncs.h>
#include <ndk/exfuncs.h>
@@ -29,6 +27,9 @@
#include <ndk/rtlfuncs.h>
#include <ndk/setypes.h>
+#include <ntstrsafe.h>
+
+
/* Filesystem headers */
#include <reactos/rosioctl.h> // For extra partition IDs
diff --git a/base/setup/lib/setuplib.h b/base/setup/lib/setuplib.h
index 055ed5eef7..a53fc3cb2d 100644
--- a/base/setup/lib/setuplib.h
+++ b/base/setup/lib/setuplib.h
@@ -29,9 +29,12 @@ extern HANDLE ProcessHeap;
#include "linklist.h"
#include "ntverrsrc.h"
// #include "arcname.h"
+#include "filesup.h"
#include "fsutil.h"
#include "genlist.h"
+#include "inicache.h"
#include "partlist.h"
#include "arcname.h"
+#include "osdetect.h"
/* EOF */
diff --git a/base/setup/usetup/CMakeLists.txt b/base/setup/usetup/CMakeLists.txt
index 714182e7e7..13aea12e16 100644
--- a/base/setup/usetup/CMakeLists.txt
+++ b/base/setup/usetup/CMakeLists.txt
@@ -24,10 +24,8 @@ list(APPEND SOURCE
fslist.c
genlist.c
inffile.c
- inicache.c
keytrans.c
mui.c
- osdetect.c
partlist.c
progress.c
registry.c
diff --git a/base/setup/usetup/filesup.c b/base/setup/usetup/filesup.c
index b466e4e38d..6094ba3365 100644
--- a/base/setup/usetup/filesup.c
+++ b/base/setup/usetup/filesup.c
@@ -1,22 +1,5 @@
/*
- * ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/* COPYRIGHT: See COPYING in the top level directory
+ * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: base/setup/usetup/filesup.c
* PURPOSE: File support functions
@@ -520,360 +503,4 @@ IsValidPath(
return TRUE;
}
-NTSTATUS
-ConcatPaths(
- IN OUT PWSTR PathElem1,
- IN SIZE_T cchPathSize,
- IN PCWSTR PathElem2 OPTIONAL)
-{
- NTSTATUS Status;
- SIZE_T cchPathLen;
-
- if (!PathElem2)
- return STATUS_SUCCESS;
- if (cchPathSize <= 1)
- return STATUS_SUCCESS;
-
- cchPathLen = min(cchPathSize, wcslen(PathElem1));
-
- if (PathElem2[0] != L'\\' && cchPathLen > 0 && PathElem1[cchPathLen-1] != L'\\')
- {
- /* PathElem2 does not start with '\' and PathElem1 does not end with '\' */
- Status = RtlStringCchCatW(PathElem1, cchPathSize, L"\\");
- if (!NT_SUCCESS(Status))
- return Status;
- }
- else if (PathElem2[0] == L'\\' && cchPathLen > 0 && PathElem1[cchPathLen-1] == L'\\')
- {
- /* PathElem2 starts with '\' and PathElem1 ends with '\' */
- while (*PathElem2 == L'\\')
- ++PathElem2; // Skip any backslash
- }
- Status = RtlStringCchCatW(PathElem1, cchPathSize, PathElem2);
- return Status;
-}
-
-//
-// NOTE: It may be possible to merge both DoesPathExist and DoesFileExist...
-//
-BOOLEAN
-DoesPathExist(
- IN HANDLE RootDirectory OPTIONAL,
- IN PCWSTR PathName)
-{
- NTSTATUS Status;
- HANDLE FileHandle;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- UNICODE_STRING Name;
-
- RtlInitUnicodeString(&Name, PathName);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- RootDirectory,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- FILE_LIST_DIRECTORY | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
- if (NT_SUCCESS(Status))
- NtClose(FileHandle);
- else
- DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &Name, Status);
-
- return NT_SUCCESS(Status);
-}
-
-BOOLEAN
-DoesFileExist(
- IN HANDLE RootDirectory OPTIONAL,
- IN PCWSTR PathName OPTIONAL,
- IN PCWSTR FileName)
-{
- NTSTATUS Status;
- HANDLE FileHandle;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- UNICODE_STRING Name;
- WCHAR FullName[MAX_PATH];
-
- if (PathName)
- RtlStringCchCopyW(FullName, ARRAYSIZE(FullName), PathName);
- else
- FullName[0] = UNICODE_NULL;
-
- if (FileName)
- ConcatPaths(FullName, ARRAYSIZE(FullName), FileName);
-
- RtlInitUnicodeString(&Name, FullName);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- RootDirectory,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- GENERIC_READ | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
- if (NT_SUCCESS(Status))
- NtClose(FileHandle);
- else
- DPRINT1("Failed to open file %wZ, Status 0x%08lx\n", &Name, Status);
-
- return NT_SUCCESS(Status);
-}
-
-/*
- * The format of NtPath should be:
- * \Device\HarddiskXXX\PartitionYYY[\path] ,
- * where XXX and YYY respectively represent the hard disk and partition numbers,
- * and [\path] represent an optional path (separated by '\\').
- *
- * If a NT path of such a form is correctly parsed, the function returns respectively:
- * - in pDiskNumber: the hard disk number XXX,
- * - in pPartNumber: the partition number YYY,
- * - in PathComponent: pointer value (inside NtPath) to the beginning of \path.
- *
- * NOTE: The function does not accept leading whitespace.
- */
-BOOLEAN
-NtPathToDiskPartComponents(
- IN PCWSTR NtPath,
- OUT PULONG pDiskNumber,
- OUT PULONG pPartNumber,
- OUT PCWSTR* PathComponent OPTIONAL)
-{
- ULONG DiskNumber, PartNumber;
- PCWSTR Path;
-
- *pDiskNumber = 0;
- *pPartNumber = 0;
- if (PathComponent) *PathComponent = NULL;
-
- Path = NtPath;
-
- if (_wcsnicmp(Path, L"\\Device\\Harddisk", 16) != 0)
- {
- /* The NT path doesn't start with the prefix string, thus it cannot be a hard disk device path */
- DPRINT1("'%S' : Not a possible hard disk device.\n", NtPath);
- return FALSE;
- }
-
- Path += 16;
-
- /* A number must be present now */
- if (!iswdigit(*Path))
- {
- DPRINT1("'%S' : expected a number! Not a regular hard disk device.\n", Path);
- return FALSE;
- }
- DiskNumber = wcstoul(Path, (PWSTR*)&Path, 10);
-
- /* Either NULL termination, or a path separator must be present now */
- if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
- {
- DPRINT1("'%S' : expected a path separator!\n", Path);
- return FALSE;
- }
-
- if (!*Path)
- {
- DPRINT1("The path only specified a hard disk (and nothing else, like a partition...), so we stop there.\n");
- goto Quit;
- }
-
- /* Here, *Path == L'\\' */
-
- if (_wcsnicmp(Path, L"\\Partition", 10) != 0)
- {
- /* Actually, \Partition is optional so, if we don't have it, we still return success. Or should we? */
- DPRINT1("'%S' : unexpected format!\n", NtPath);
- goto Quit;
- }
-
- Path += 10;
-
- /* A number must be present now */
- if (!iswdigit(*Path))
- {
- /* If we don't have a number it means this part of path is actually not a partition specifier, so we shouldn't fail either. Or should we? */
- DPRINT1("'%S' : expected a number!\n", Path);
- goto Quit;
- }
- PartNumber = wcstoul(Path, (PWSTR*)&Path, 10);
-
- /* Either NULL termination, or a path separator must be present now */
- if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
- {
- /* We shouldn't fail here because it just means this part of path is actually not a partition specifier. Or should we? */
- DPRINT1("'%S' : expected a path separator!\n", Path);
- goto Quit;
- }
-
- /* OK, here we really have a partition specifier: return its number */
- *pPartNumber = PartNumber;
-
-Quit:
- /* Return the disk number */
- *pDiskNumber = DiskNumber;
-
- /* Return the path component also, if the user wants it */
- if (PathComponent) *PathComponent = Path;
-
- return TRUE;
-}
-
-NTSTATUS
-OpenAndMapFile(
- IN HANDLE RootDirectory OPTIONAL,
- IN PCWSTR PathName OPTIONAL,
- IN PCWSTR FileName, // OPTIONAL
- OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
- OUT PHANDLE SectionHandle,
- OUT PVOID* BaseAddress,
- OUT PULONG FileSize OPTIONAL)
-{
- NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- SIZE_T ViewSize;
- PVOID ViewBase;
- UNICODE_STRING Name;
- WCHAR FullName[MAX_PATH];
-
- if (PathName)
- RtlStringCchCopyW(FullName, ARRAYSIZE(FullName), PathName);
- else
- FullName[0] = UNICODE_NULL;
-
- if (FileName)
- ConcatPaths(FullName, ARRAYSIZE(FullName), FileName);
-
- RtlInitUnicodeString(&Name, FullName);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- RootDirectory,
- NULL);
-
- *FileHandle = NULL;
- *SectionHandle = NULL;
-
- Status = NtOpenFile(FileHandle,
- GENERIC_READ | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &Name, Status);
- return Status;
- }
-
- if (FileSize)
- {
- /* Query the file size */
- FILE_STANDARD_INFORMATION FileInfo;
- Status = NtQueryInformationFile(*FileHandle,
- &IoStatusBlock,
- &FileInfo,
- sizeof(FileInfo),
- FileStandardInformation);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
- NtClose(*FileHandle);
- *FileHandle = NULL;
- return Status;
- }
-
- if (FileInfo.EndOfFile.HighPart != 0)
- DPRINT1("WARNING!! The file '%wZ' is too large!\n", &Name);
-
- *FileSize = FileInfo.EndOfFile.LowPart;
-
- DPRINT("File size: %lu\n", *FileSize);
- }
-
- /* Map the file in memory */
-
- /* Create the section */
- Status = NtCreateSection(SectionHandle,
- SECTION_MAP_READ,
- NULL,
- NULL,
- PAGE_READONLY,
- SEC_COMMIT /* | SEC_IMAGE (_NO_EXECUTE) */,
- *FileHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create a memory section for file '%wZ', Status 0x%08lx\n", &Name, Status);
- NtClose(*FileHandle);
- *FileHandle = NULL;
- return Status;
- }
-
- /* Map the section */
- ViewSize = 0;
- ViewBase = NULL;
- Status = NtMapViewOfSection(*SectionHandle,
- NtCurrentProcess(),
- &ViewBase,
- 0, 0,
- NULL,
- &ViewSize,
- ViewShare,
- 0,
- PAGE_READONLY);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to map a view for file %wZ, Status 0x%08lx\n", &Name, Status);
- NtClose(*SectionHandle);
- *SectionHandle = NULL;
- NtClose(*FileHandle);
- *FileHandle = NULL;
- return Status;
- }
-
- *BaseAddress = ViewBase;
- return STATUS_SUCCESS;
-}
-
-BOOLEAN
-UnMapFile(
- IN HANDLE SectionHandle,
- IN PVOID BaseAddress)
-{
- NTSTATUS Status;
- BOOLEAN Success = TRUE;
-
- Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("UnMapFile: NtUnmapViewOfSection(0x%p) failed with Status 0x%08lx\n",
- BaseAddress, Status);
- Success = FALSE;
- }
- Status = NtClose(SectionHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("UnMapFile: NtClose(0x%p) failed with Status 0x%08lx\n",
- SectionHandle, Status);
- Success = FALSE;
- }
-
- return Success;
-}
-
/* EOF */
diff --git a/base/setup/usetup/filesup.h b/base/setup/usetup/filesup.h
index 87ab8354fe..5c2c296ecf 100644
--- a/base/setup/usetup/filesup.h
+++ b/base/setup/usetup/filesup.h
@@ -1,21 +1,3 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
@@ -46,43 +28,4 @@ BOOLEAN
IsValidPath(
IN PCWSTR InstallDir);
-NTSTATUS
-ConcatPaths(
- IN OUT PWSTR PathElem1,
- IN SIZE_T cchPathSize,
- IN PCWSTR PathElem2 OPTIONAL);
-
-BOOLEAN
-DoesPathExist(
- IN HANDLE RootDirectory OPTIONAL,
- IN PCWSTR PathName);
-
-BOOLEAN
-DoesFileExist(
- IN HANDLE RootDirectory OPTIONAL,
- IN PCWSTR PathName OPTIONAL,
- IN PCWSTR FileName);
-
-BOOLEAN
-NtPathToDiskPartComponents(
- IN PCWSTR NtPath,
- OUT PULONG pDiskNumber,
- OUT PULONG pPartNumber,
- OUT PCWSTR* PathComponent OPTIONAL);
-
-NTSTATUS
-OpenAndMapFile(
- IN HANDLE RootDirectory OPTIONAL,
- IN PCWSTR PathName OPTIONAL,
- IN PCWSTR FileName, // OPTIONAL
- OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
- OUT PHANDLE SectionHandle,
- OUT PVOID* BaseAddress,
- OUT PULONG FileSize OPTIONAL);
-
-BOOLEAN
-UnMapFile(
- IN HANDLE SectionHandle,
- IN PVOID BaseAddress);
-
/* EOF */
diff --git a/base/setup/usetup/usetup.h b/base/setup/usetup/usetup.h
index aed5dcec4c..eeb11545b4 100644
--- a/base/setup/usetup/usetup.h
+++ b/base/setup/usetup/usetup.h
@@ -60,7 +60,6 @@
/* Internal Headers */
#include "consup.h"
#include "inffile.h"
-#include "inicache.h"
#include "progress.h"
#include "infros.h"
#include "filequeue.h"
@@ -70,7 +69,6 @@
#include "cabinet.h"
#include "filesup.h"
#include "genlist.h"
-#include "osdetect.h"
#include "mui.h"
extern HANDLE ProcessHeap;