https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c560342f08edfa2824a6d…
commit c560342f08edfa2824a6dc0a1fc7188f169c12b7
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Aug 25 09:19:44 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat Oct 27 18:13:42 2018 +0200
[SETUPLIB] Diverse fixes (incl. initialization fixes).
- Compute the installation source paths based on the full path of the
installer program that uses the setup library.
- Add INF_STYLE_OLDNT define in infsupp.h.
- Add some (silenced) diagnostic DPRINTs.
svn path=/branches/setup_improvements/; revision=75667
- Use correct inf style flags in SetupOpenInfFileEx() calls when opening
txtsetup.sif and unattend.inf. Technically txtsetup.sif would be
INF_STYLE_WIN4, but since we use "$ReactOS$" as its version signature,
it would not work when opening it with setupapi.dll functions.
Hence this flag is combined with INF_STYLE_OLDNT too.
- Don't fail if opening the \SystemRoot symbolic link doesn't work
(usually due to incorrect access rights); in that case, just use the
installer image file path as the installation source path.
svn path=/branches/setup_improvements/; revision=75676
---
base/setup/lib/infsupp.h | 4 ++
base/setup/lib/setuplib.c | 103 +++++++++++++++++++++++++++++++++++-----------
2 files changed, 84 insertions(+), 23 deletions(-)
diff --git a/base/setup/lib/infsupp.h b/base/setup/lib/infsupp.h
index 677fb9af2a..db6043c03f 100644
--- a/base/setup/lib/infsupp.h
+++ b/base/setup/lib/infsupp.h
@@ -95,6 +95,10 @@ SetupGetStringFieldW(PINFCONTEXT Context,
#undef MAX_INF_STRING_LENGTH
#define MAX_INF_STRING_LENGTH 1024 // Still larger than in infcommon.h
+#ifndef INF_STYLE_OLDNT
+#define INF_STYLE_OLDNT 0x00000001
+#endif
+
#ifndef INF_STYLE_WIN4
#define INF_STYLE_WIN4 0x00000002
#endif
diff --git a/base/setup/lib/setuplib.c b/base/setup/lib/setuplib.c
index a1744cc99e..c5a8a6f981 100644
--- a/base/setup/lib/setuplib.c
+++ b/base/setup/lib/setuplib.c
@@ -41,6 +41,8 @@ CheckUnattendedSetup(
CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2,
pSetupData->SourcePath.Buffer, L"unattend.inf");
+ DPRINT("UnattendInf path: '%S'\n", UnattendInfPath);
+
if (DoesFileExist(NULL, UnattendInfPath) == FALSE)
{
DPRINT("Does not exist: %S\n", UnattendInfPath);
@@ -50,7 +52,7 @@ CheckUnattendedSetup(
/* Load 'unattend.inf' from installation media */
UnattendInf = SetupOpenInfFileExW(UnattendInfPath,
NULL,
- INF_STYLE_WIN4,
+ INF_STYLE_OLDNT,
pSetupData->LanguageId,
&ErrorLine);
@@ -263,7 +265,8 @@ InstallSetupInfFile(
#if 0
/* TODO: Append the standard unattend.inf file */
- CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2,
pSetupData->SourcePath.Buffer, L"unattend.inf");
+ CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2,
+ pSetupData->SourcePath.Buffer, L"unattend.inf");
if (DoesFileExist(NULL, UnattendInfPath) == FALSE)
{
DPRINT("Does not exist: %S\n", UnattendInfPath);
@@ -379,8 +382,6 @@ Quit:
#endif
}
-
-
NTSTATUS
GetSourcePaths(
OUT PUNICODE_STRING SourcePath,
@@ -388,41 +389,97 @@ GetSourcePaths(
OUT PUNICODE_STRING SourceRootDir)
{
NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
- UNICODE_STRING SourceName;
- WCHAR SourceBuffer[MAX_PATH] = L"";
HANDLE Handle;
- ULONG Length;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UCHAR ImageFileBuffer[sizeof(UNICODE_STRING) + MAX_PATH * sizeof(WCHAR)];
+ PUNICODE_STRING InstallSourcePath = (PUNICODE_STRING)&ImageFileBuffer;
+ WCHAR SystemRootBuffer[MAX_PATH] = L"";
+ UNICODE_STRING SystemRootPath = RTL_CONSTANT_STRING(L"\\SystemRoot");
+ ULONG BufferSize;
PWCHAR Ptr;
+ /* Determine the installation source path via the full path of the installer */
+ RtlInitEmptyUnicodeString(InstallSourcePath,
+ (PWSTR)((ULONG_PTR)ImageFileBuffer +
sizeof(UNICODE_STRING)),
+ sizeof(ImageFileBuffer) - sizeof(UNICODE_STRING)
+ /* Reserve space for a NULL terminator */ - sizeof(UNICODE_NULL));
+ BufferSize = sizeof(ImageFileBuffer);
+ Status = NtQueryInformationProcess(NtCurrentProcess(),
+ ProcessImageFileName,
+ InstallSourcePath,
+ BufferSize,
+ NULL);
+ // STATUS_INFO_LENGTH_MISMATCH or STATUS_BUFFER_TOO_SMALL ?
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* Manually NULL-terminate */
+ InstallSourcePath->Buffer[InstallSourcePath->Length / sizeof(WCHAR)] =
UNICODE_NULL;
+
+ /* Strip the trailing file name */
+ Ptr = wcsrchr(InstallSourcePath->Buffer, OBJ_NAME_PATH_SEPARATOR);
+ if (Ptr)
+ *Ptr = UNICODE_NULL;
+ InstallSourcePath->Length = wcslen(InstallSourcePath->Buffer) * sizeof(WCHAR);
+
+
+ /*
+ * Now resolve the full path to \SystemRoot. In case it prefixes
+ * the installation source path determined from the full path of
+ * the installer, we use instead the resolved \SystemRoot as the
+ * installation source path.
+ * Otherwise, we use instead the path from the full installer path.
+ */
+
InitializeObjectAttributes(&ObjectAttributes,
- &LinkName,
+ &SystemRootPath,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenSymbolicLinkObject(&Handle,
- SYMBOLIC_LINK_ALL_ACCESS,
+ SYMBOLIC_LINK_QUERY,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
- return Status;
+ {
+ /*
+ * We failed at opening the \SystemRoot link (usually due to wrong
+ * access rights). Do not consider this as a fatal error, but use
+ * instead the image file path as the installation source path.
+ */
+ DPRINT1("NtOpenSymbolicLinkObject(%wZ) failed with Status 0x%08lx\n",
+ &SystemRootPath, Status);
+ goto InitPaths;
+ }
- RtlInitEmptyUnicodeString(&SourceName, SourceBuffer, sizeof(SourceBuffer));
+ RtlInitEmptyUnicodeString(&SystemRootPath,
+ SystemRootBuffer,
+ sizeof(SystemRootBuffer));
Status = NtQuerySymbolicLinkObject(Handle,
- &SourceName,
- &Length);
+ &SystemRootPath,
+ &BufferSize);
NtClose(Handle);
if (!NT_SUCCESS(Status))
- return Status;
+ return Status; // Unexpected error
+
+ /* Check whether the resolved \SystemRoot is a prefix of the image file path */
+ if (RtlPrefixUnicodeString(&SystemRootPath, InstallSourcePath, TRUE))
+ {
+ /* Yes it is, so we use instead SystemRoot as the installation source path */
+ InstallSourcePath = &SystemRootPath;
+ }
- RtlCreateUnicodeString(SourcePath,
- SourceName.Buffer);
+
+InitPaths:
+ /*
+ * Retrieve the different source path components
+ */
+ RtlCreateUnicodeString(SourcePath, InstallSourcePath->Buffer);
/* Strip trailing directory */
- Ptr = wcsrchr(SourceName.Buffer, OBJ_NAME_PATH_SEPARATOR);
+ Ptr = wcsrchr(InstallSourcePath->Buffer, OBJ_NAME_PATH_SEPARATOR);
if (Ptr)
{
RtlCreateUnicodeString(SourceRootDir, Ptr);
@@ -433,13 +490,11 @@ GetSourcePaths(
RtlCreateUnicodeString(SourceRootDir, L"");
}
- RtlCreateUnicodeString(SourceRootPath,
- SourceName.Buffer);
+ RtlCreateUnicodeString(SourceRootPath, InstallSourcePath->Buffer);
return STATUS_SUCCESS;
}
-
ERROR_NUMBER
LoadSetupInf(
OUT HINF* SetupInf,
@@ -454,9 +509,11 @@ LoadSetupInf(
CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2,
pSetupData->SourcePath.Buffer, L"txtsetup.sif");
+ DPRINT("SetupInf path: '%S'\n", FileNameBuffer);
+
*SetupInf = SetupOpenInfFileExW(FileNameBuffer,
NULL,
- INF_STYLE_WIN4,
+ INF_STYLE_WIN4 | INF_STYLE_OLDNT,
pSetupData->LanguageId,
&ErrorLine);