[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
This commit is contained in:
Hermès Bélusca-Maïto 2017-08-25 09:19:44 +00:00
parent f1b9c071bb
commit c560342f08
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 84 additions and 23 deletions

View file

@ -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

View file

@ -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
RtlCreateUnicodeString(SourcePath,
SourceName.Buffer);
/* 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;
}
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);