https://git.reactos.org/?p=reactos.git;a=commitdiff;h=60d9ea76d1252c80b85e8…
commit 60d9ea76d1252c80b85e8424e4a84081c20855b1
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Jun 30 19:07:02 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat Oct 27 03:16:47 2018 +0200
[USETUP][SETUPLIB] Split the registry helper code.
Split the registry helper code into registry utility functions
(create/mount/unmount/verify hives) and registry creation code
(the rest: initializing the system hives) and move it in the
setup library.
svn path=/branches/setup_improvements/; revision=75247
[USETUP][SETUPLIB] Improve how the Setup* INF APIs are interfaced in the code.
Define prototypes compatible (including their calling convention)
with the ones defined by setupapi (.h/.dll) so that it can be possible
to either use an internal implementation of these functions (via the
INFLIB library) as currently being done, or using imported setupapi
functions, as would be done by the future 1st-stage GUI installer.
[SETUPLIB] Cleanup the registry.c file and use the infsupp.h header.
svn path=/branches/setup_improvements/; revision=75345
svn path=/branches/setup_improvements/; revision=75346
[USETUP][SETUPLIB] Move some INF-related code from usetup to the setuplib.
- Move the generic INF_GetDataField() and INF_GetData() helpers to
setuplib, and rework them a bit so that they explicitly call setupapi
functions (or implementations thereof when being used in usetup);
- Rework the headers in accordance;
- Fix compilation in lib/registry.c .
- Fix compilation when these headers are used withing usetup (who
doesn't use setupapi.dll) and "reactos" (the 1st-stage GUI installer
that uses setupapi.dll).
svn path=/branches/setup_improvements/; revision=75515
svn path=/branches/setup_improvements/; revision=75537
svn path=/branches/setup_improvements/; revision=75538
---
base/setup/lib/CMakeLists.txt | 3 +
base/setup/lib/errorcode.h | 7 +-
base/setup/lib/infsupp.c | 119 +++
base/setup/lib/infsupp.h | 164 ++++
base/setup/{usetup => lib}/registry.c | 489 +----------
base/setup/{usetup => lib}/registry.h | 21 +-
base/setup/lib/regutil.c | 457 ++++++++++
base/setup/lib/regutil.h | 80 ++
base/setup/lib/setuplib.h | 2 +
base/setup/usetup/inffile.c | 159 +++-
base/setup/usetup/inffile.h | 84 +-
base/setup/usetup/registry.c | 1475 +--------------------------------
base/setup/usetup/registry.h | 31 -
base/setup/usetup/usetup.h | 1 -
14 files changed, 1023 insertions(+), 2069 deletions(-)
diff --git a/base/setup/lib/CMakeLists.txt b/base/setup/lib/CMakeLists.txt
index 819ecf34bd..c1164c809d 100644
--- a/base/setup/lib/CMakeLists.txt
+++ b/base/setup/lib/CMakeLists.txt
@@ -5,10 +5,13 @@ list(APPEND SOURCE
filesup.c
fsutil.c
genlist.c
+ infsupp.c
inicache.c
ntverrsrc.c
osdetect.c
partlist.c
+ registry.c
+ regutil.c
precomp.h)
add_library(setuplib ${SOURCE})
diff --git a/base/setup/lib/errorcode.h b/base/setup/lib/errorcode.h
index 963e137bcd..b440e4e8d3 100644
--- a/base/setup/lib/errorcode.h
+++ b/base/setup/lib/errorcode.h
@@ -7,7 +7,12 @@
#pragma once
-typedef enum
+/* setupapi.h defines ERROR_NOT_INSTALLED with another meaning */
+#ifdef ERROR_NOT_INSTALLED
+#undef ERROR_NOT_INSTALLED
+#endif
+
+typedef enum _ERROR_NUMBER
{
NOT_AN_ERROR = 0, // ERROR_SUCCESS,
ERROR_NOT_INSTALLED,
diff --git a/base/setup/lib/infsupp.c b/base/setup/lib/infsupp.c
new file mode 100644
index 0000000000..265585712e
--- /dev/null
+++ b/base/setup/lib/infsupp.c
@@ -0,0 +1,119 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Setup Library
+ * FILE: base/setup/lib/infsupp.c
+ * PURPOSE: Interfacing with Setup* API .inf files support functions
+ * PROGRAMMERS: Hervé Poussineau
+ * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "precomp.h"
+#include "infsupp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* HELPER FUNCTIONS **********************************************************/
+
+BOOLEAN
+INF_GetDataField(
+ IN PINFCONTEXT Context,
+ IN ULONG FieldIndex,
+ OUT PWCHAR *Data)
+{
+#if 0
+
+ BOOL Success;
+ PWCHAR InfData;
+ DWORD dwSize;
+
+ *Data = NULL;
+
+ Success = SetupGetStringFieldW(Context,
+ FieldIndex,
+ NULL,
+ 0,
+ &dwSize);
+ if (!Success)
+ return FALSE;
+
+ InfData = RtlAllocateHeap(ProcessHeap, 0, dwSize * sizeof(WCHAR));
+ if (!InfData)
+ return FALSE;
+
+ Success = SetupGetStringFieldW(Context,
+ FieldIndex,
+ InfData,
+ dwSize,
+ NULL);
+ if (!Success)
+ {
+ RtlFreeHeap(ProcessHeap, 0, InfData);
+ return FALSE;
+ }
+
+ *Data = InfData;
+ return TRUE;
+
+#else
+
+ *Data = (PWCHAR)pSetupGetField(Context, FieldIndex);
+ return !!*Data;
+
+#endif
+}
+
+BOOLEAN
+INF_GetData(
+ IN PINFCONTEXT Context,
+ OUT PWCHAR *Key,
+ OUT PWCHAR *Data)
+{
+ BOOL Success;
+ PWCHAR InfData[2] = {NULL, NULL};
+
+ if (Key)
+ *Key = NULL;
+
+ if (Data)
+ *Data = NULL;
+
+ /*
+ * Verify that the INF file has only one value field, in addition to its key name.
+ * Note that SetupGetFieldCount() does not count the key name as a field.
+ */
+ if (SetupGetFieldCount(Context) != 1)
+ {
+ DPRINT1("SetupGetFieldCount != 1\n");
+ return FALSE;
+ }
+
+ if (Key)
+ {
+ Success = INF_GetDataField(Context, 0, &InfData[0]);
+ if (!Success)
+ return FALSE;
+ }
+
+ if (Data)
+ {
+ Success = INF_GetDataField(Context, 1, &InfData[1]);
+ if (!Success)
+ {
+ INF_FreeData(InfData[0]);
+ return FALSE;
+ }
+ }
+
+ if (Key)
+ *Key = InfData[0];
+
+ if (Data)
+ *Data = InfData[1];
+
+ return TRUE;
+}
+
+/* EOF */
diff --git a/base/setup/lib/infsupp.h b/base/setup/lib/infsupp.h
new file mode 100644
index 0000000000..677fb9af2a
--- /dev/null
+++ b/base/setup/lib/infsupp.h
@@ -0,0 +1,164 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Setup Library
+ * FILE: base/setup/lib/infsupp.h
+ * PURPOSE: Interfacing with Setup* API .inf files support functions
+ * PROGRAMMER: Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
+ */
+
+#pragma once
+
+/* Make setupapi.h to not define the API as exports to the DLL */
+#ifdef __REACTOS__
+#define _SETUPAPI_
+#endif
+
+// FIXME: Temporary measure until all the users of this header
+// (usetup...) use or define SetupAPI-conforming APIs.
+#if defined(_SETUPAPI_H_) || defined(_INC_SETUPAPI)
+
+#include <setupapi.h>
+
+#else
+
+typedef PVOID HINF;
+typedef struct _INFCONTEXT
+{
+ HINF Inf;
+ HINF CurrentInf;
+ UINT Section;
+ UINT Line;
+} INFCONTEXT, *PINFCONTEXT;
+
+// #define SetupCloseInfFile InfCloseFile
+VOID
+WINAPI
+SetupCloseInfFile(HINF InfHandle);
+
+// #define SetupFindFirstLineW InfpFindFirstLineW
+BOOL
+WINAPI
+SetupFindFirstLineW(
+ IN HINF InfHandle,
+ IN PCWSTR Section,
+ IN PCWSTR Key,
+ IN OUT PINFCONTEXT Context);
+
+// #define SetupFindNextLine InfFindNextLine
+BOOL
+WINAPI
+SetupFindNextLine(PINFCONTEXT ContextIn,
+ PINFCONTEXT ContextOut);
+
+// #define SetupGetFieldCount InfGetFieldCount
+LONG
+WINAPI
+SetupGetFieldCount(PINFCONTEXT Context);
+
+// #define SetupGetBinaryField InfGetBinaryField
+BOOL
+WINAPI
+SetupGetBinaryField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PUCHAR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+
+// #define SetupGetIntField InfGetIntField
+BOOL
+WINAPI
+SetupGetIntField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ INT *IntegerValue); // PINT
+
+// #define SetupGetMultiSzFieldW InfGetMultiSzField
+BOOL
+WINAPI
+SetupGetMultiSzFieldW(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+
+// #define SetupGetStringFieldW InfGetStringField
+BOOL
+WINAPI
+SetupGetStringFieldW(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+
+#endif
+
+/* Lower the MAX_INF_STRING_LENGTH value in order to avoid too much stack usage */
+#undef MAX_INF_STRING_LENGTH
+#define MAX_INF_STRING_LENGTH 1024 // Still larger than in infcommon.h
+
+#ifndef INF_STYLE_WIN4
+#define INF_STYLE_WIN4 0x00000002
+#endif
+
+#if 0
+typedef PVOID HINF;
+typedef struct _INFCONTEXT
+{
+ HINF Inf;
+ HINF CurrentInf;
+ UINT Section;
+ UINT Line;
+} INFCONTEXT, *PINFCONTEXT;
+#endif
+
+C_ASSERT(sizeof(INFCONTEXT) == 2 * sizeof(HINF) + 2 * sizeof(UINT));
+
+
+/*
+ * This function corresponds to an undocumented but exported SetupAPI function
+ * that exists since WinNT4 and is still present in Win10.
+ * The returned string pointer is a read-only pointer to a string in the
+ * maintained INF cache, and is always in UNICODE (on NT systems).
+ */
+PCWSTR
+WINAPI
+pSetupGetField(PINFCONTEXT Context,
+ ULONG FieldIndex);
+
+/* A version of SetupOpenInfFileW with support for a user-provided LCID */
+// #define SetupOpenInfFileExW InfpOpenInfFileW
+HINF
+WINAPI
+SetupOpenInfFileExW(
+ IN PCWSTR FileName,
+ IN PCWSTR InfClass,
+ IN DWORD InfStyle,
+ IN LCID LocaleId,
+ OUT PUINT ErrorLine);
+
+
+/* HELPER FUNCTIONS **********************************************************/
+
+FORCEINLINE VOID
+INF_FreeData(IN PWCHAR InfData)
+{
+#if 0
+ if (InfData)
+ RtlFreeHeap(ProcessHeap, 0, InfData);
+#else
+ UNREFERENCED_PARAMETER(InfData);
+#endif
+}
+
+BOOLEAN
+INF_GetDataField(
+ IN PINFCONTEXT Context,
+ IN ULONG FieldIndex,
+ OUT PWCHAR *Data);
+
+BOOLEAN
+INF_GetData(
+ IN PINFCONTEXT Context,
+ OUT PWCHAR *Key,
+ OUT PWCHAR *Data);
+
+/* EOF */
diff --git a/base/setup/usetup/registry.c b/base/setup/lib/registry.c
similarity index 70%
copy from base/setup/usetup/registry.c
copy to base/setup/lib/registry.c
index 749835c3d7..e36e6a7c76 100644
--- a/base/setup/usetup/registry.c
+++ b/base/setup/lib/registry.c
@@ -18,15 +18,21 @@
*/
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS text-mode setup
- * FILE: base/setup/usetup/registry.c
+ * PROJECT: ReactOS Setup Library
+ * FILE: base/setup/lib/registry.c
* PURPOSE: Registry creation functions
- * PROGRAMMER:
+ * PROGRAMMERS: ...
+ * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
*/
/* INCLUDES *****************************************************************/
-#include "usetup.h"
+#include "precomp.h"
+#include "filesup.h"
+#include "infsupp.h"
+#include "regutil.h"
+
+#include "registry.h"
// HACK!
#include <strsafe.h>
@@ -34,6 +40,9 @@
#define NDEBUG
#include <debug.h>
+
+// #ifdef __REACTOS__
+#if 1 // FIXME: Disable if setupapi.h is included in the code...
#define FLG_ADDREG_BINVALUETYPE 0x00000001
#define FLG_ADDREG_NOCLOBBER 0x00000002
#define FLG_ADDREG_DELVAL 0x00000004
@@ -47,6 +56,7 @@
#define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE)
#define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE)
#define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE)
+#endif
#ifdef _M_IX86
#define Architecture L"x86"
@@ -98,7 +108,7 @@ GetRootKeyByPredefKey(
if (!IsPredefKey(KeyHandle))
return NULL;
- if (GetPredefKeyIndex(KeyHandle) >= ARRAYSIZE(RootKeys))
+ if (Index >= ARRAYSIZE(RootKeys))
return NULL;
if (RootKeyMountPoint)
@@ -406,115 +416,6 @@ do_reg_operation(HANDLE KeyHandle,
return TRUE;
}
-/*
- * This function is similar to the one in dlls/win32/advapi32/reg/reg.c
- * TODO: I should review both of them very carefully, because they may need
- * some adjustments in their NtCreateKey calls, especially for CreateOptions
- * stuff etc...
- */
-NTSTATUS
-CreateNestedKey(PHANDLE KeyHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- ULONG CreateOptions)
-{
- OBJECT_ATTRIBUTES LocalObjectAttributes;
- UNICODE_STRING LocalKeyName;
- ULONG Disposition;
- NTSTATUS Status;
- USHORT FullNameLength;
- PWCHAR Ptr;
- HANDLE LocalKeyHandle;
-
- Status = NtCreateKey(KeyHandle,
- KEY_ALL_ACCESS,
- ObjectAttributes,
- 0,
- NULL,
- CreateOptions,
- &Disposition);
- DPRINT("NtCreateKey(%wZ) called (Status %lx)\n",
ObjectAttributes->ObjectName, Status);
- if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
- {
- if (!NT_SUCCESS(Status))
- DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n",
ObjectAttributes->ObjectName, Status);
-
- return Status;
- }
-
- /* Copy object attributes */
- RtlCopyMemory(&LocalObjectAttributes,
- ObjectAttributes,
- sizeof(OBJECT_ATTRIBUTES));
- RtlCreateUnicodeString(&LocalKeyName,
- ObjectAttributes->ObjectName->Buffer);
- LocalObjectAttributes.ObjectName = &LocalKeyName;
- FullNameLength = LocalKeyName.Length;
-
- /* Remove the last part of the key name and try to create the key again. */
- while (Status == STATUS_OBJECT_NAME_NOT_FOUND)
- {
- Ptr = wcsrchr(LocalKeyName.Buffer, '\\');
- if (Ptr == NULL || Ptr == LocalKeyName.Buffer)
- {
- Status = STATUS_UNSUCCESSFUL;
- break;
- }
- *Ptr = (WCHAR)0;
- LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
-
- Status = NtCreateKey(&LocalKeyHandle,
- KEY_CREATE_SUB_KEY,
- &LocalObjectAttributes,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- &Disposition);
- DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName,
Status);
- if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
- DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n",
LocalObjectAttributes.ObjectName, Status);
- }
-
- if (!NT_SUCCESS(Status))
- {
- RtlFreeUnicodeString(&LocalKeyName);
- return Status;
- }
-
- /* Add removed parts of the key name and create them too. */
- while (TRUE)
- {
- if (LocalKeyName.Length == FullNameLength)
- {
- Status = STATUS_SUCCESS;
- *KeyHandle = LocalKeyHandle;
- break;
- }
- NtClose(LocalKeyHandle);
-
- LocalKeyName.Buffer[LocalKeyName.Length / sizeof(WCHAR)] = L'\\';
- LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
-
- Status = NtCreateKey(&LocalKeyHandle,
- KEY_ALL_ACCESS,
- &LocalObjectAttributes,
- 0,
- NULL,
- CreateOptions,
- &Disposition);
- DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName,
Status);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n",
LocalObjectAttributes.ObjectName, Status);
- break;
- }
- }
-
- RtlFreeUnicodeString(&LocalKeyName);
-
- return Status;
-}
-
/***********************************************************************
* registry_callback
*
@@ -539,7 +440,7 @@ registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete)
if (!Ok)
return TRUE; /* Don't fail if the section isn't present */
- for (;Ok; Ok = SetupFindNextLine (&Context, &Context))
+ for (;Ok; Ok = SetupFindNextLine(&Context, &Context))
{
/* get root */
if (!SetupGetStringFieldW(&Context, 1, Buffer, sizeof(Buffer)/sizeof(WCHAR),
NULL))
@@ -615,22 +516,21 @@ registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete)
return TRUE;
}
-
BOOLEAN
ImportRegistryFile(
- PCWSTR SourcePath,
- PWSTR Filename,
- PWSTR Section,
- LCID LocaleId,
- BOOLEAN Delete)
+ IN PCWSTR SourcePath,
+ IN PCWSTR FileName,
+ IN PCWSTR Section,
+ IN LCID LocaleId,
+ IN BOOLEAN Delete)
{
- WCHAR FileNameBuffer[MAX_PATH];
HINF hInf;
UINT ErrorLine;
+ WCHAR FileNameBuffer[MAX_PATH];
- /* Load inf file from install media. */
+ /* Load the INF file from the installation media */
CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2,
- SourcePath, Filename);
+ SourcePath, FileName);
hInf = SetupOpenInfFileExW(FileNameBuffer,
NULL,
@@ -639,7 +539,7 @@ ImportRegistryFile(
&ErrorLine);
if (hInf == INVALID_HANDLE_VALUE)
{
- DPRINT1("SetupOpenInfFile() failed\n");
+ DPRINT1("SetupOpenInfFileEx() failed\n");
return FALSE;
}
@@ -647,7 +547,7 @@ ImportRegistryFile(
if (!registry_callback(hInf, L"DelReg", FALSE))
{
DPRINT1("registry_callback() failed\n");
- InfCloseFile(hInf);
+ SetupCloseInfFile(hInf);
return FALSE;
}
#endif
@@ -655,305 +555,21 @@ ImportRegistryFile(
if (!registry_callback(hInf, L"AddReg", FALSE))
{
DPRINT1("registry_callback() failed\n");
- InfCloseFile(hInf);
+ SetupCloseInfFile(hInf);
return FALSE;
}
if (!registry_callback(hInf, L"AddReg.NT" Architecture, FALSE))
{
DPRINT1("registry_callback() failed\n");
- InfCloseFile(hInf);
- return FALSE;
- }
-
- InfCloseFile(hInf);
- return TRUE;
-}
-
-/*
- * Should be called under privileges
- */
-static NTSTATUS
-CreateRegistryFile(
- IN PUNICODE_STRING InstallPath,
- IN PCWSTR RegistryKey,
- IN BOOLEAN IsHiveNew,
- IN HANDLE ProtoKeyHandle
-/*
- IN PUCHAR Descriptor,
- IN ULONG DescriptorLength
-*/
- )
-{
- /* '.old' is for old valid hives, while '.brk' is for old broken
hives */
- static PCWSTR Extensions[] = {L"old", L"brk"};
-
- NTSTATUS Status;
- HANDLE FileHandle;
- UNICODE_STRING FileName;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- PCWSTR Extension;
- WCHAR PathBuffer[MAX_PATH];
- WCHAR PathBuffer2[MAX_PATH];
-
- CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3,
- InstallPath->Buffer, L"System32\\config", RegistryKey);
-
- Extension = Extensions[IsHiveNew ? 0 : 1];
-
- //
- // FIXME: The best, actually, would be to rename (move) the existing
- // System32\config\RegistryKey file to System32\config\RegistryKey.old,
- // and if it already existed some System32\config\RegistryKey.old, we should
- // first rename this one into System32\config\RegistryKey_N.old before
- // performing the original rename.
- //
-
- /* Check whether the registry hive file already existed, and if so, rename it */
- if (DoesFileExist(NULL, PathBuffer))
- {
- // UINT i;
-
- DPRINT1("Registry hive '%S' already exists, rename it\n",
PathBuffer);
-
- // i = 1;
- /* Try first by just appending the '.old' extension */
- StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s",
PathBuffer, Extension);
-#if 0
- while (DoesFileExist(NULL, PathBuffer2))
- {
- /* An old file already exists, increments its index, but not too much */
- if (i <= 0xFFFF)
- {
- /* Append '_N.old' extension */
- StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2),
L"%s_%lu.%s", PathBuffer, i, Extension);
- ++i;
- }
- else
- {
- /*
- * Too many old files exist, we will rename the file
- * using the name of the oldest one.
- */
- StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s",
PathBuffer, Extension);
- break;
- }
- }
-#endif
-
- /* Now rename the file (force the move) */
- Status = SetupMoveFile(PathBuffer, PathBuffer2, MOVEFILE_REPLACE_EXISTING);
- }
-
- /* Create the file */
- RtlInitUnicodeString(&FileName, PathBuffer);
- InitializeObjectAttributes(&ObjectAttributes,
- &FileName,
- OBJ_CASE_INSENSITIVE,
- NULL, // Could have been InstallPath, etc...
- NULL); // Descriptor
-
- Status = NtCreateFile(&FileHandle,
- FILE_GENERIC_WRITE,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_OVERWRITE_IF,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
- NULL,
- 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName,
Status);
- return Status;
- }
-
- /* Save the selected hive into the file */
- Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName,
Status);
- }
-
- /* Close the file and return */
- NtClose(FileHandle);
- return Status;
-}
-
-static BOOLEAN
-CmpLinkKeyToHive(
- IN HANDLE RootLinkKeyHandle OPTIONAL,
- IN PCWSTR LinkKeyName,
- IN PCWSTR TargetKeyName)
-{
- static UNICODE_STRING CmSymbolicLinkValueName =
- RTL_CONSTANT_STRING(L"SymbolicLinkValue");
-
- NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName;
- HANDLE TargetKeyHandle;
- ULONG Disposition;
-
- /* Initialize the object attributes */
- RtlInitUnicodeString(&KeyName, LinkKeyName);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- RootLinkKeyHandle,
- NULL);
-
- /* Create the link key */
- Status = NtCreateKey(&TargetKeyHandle,
- KEY_SET_VALUE | KEY_CREATE_LINK,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
- &Disposition);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmpLinkKeyToHive: couldn't create %S, Status =
0x%08lx\n",
- LinkKeyName, Status);
- return FALSE;
- }
-
- /* Check if the new key was actually created */
- if (Disposition != REG_CREATED_NEW_KEY)
- {
- DPRINT1("CmpLinkKeyToHive: %S already exists!\n", LinkKeyName);
- NtClose(TargetKeyHandle);
- return FALSE;
- }
-
- /* Set the target key name as link target */
- RtlInitUnicodeString(&KeyName, TargetKeyName);
- Status = NtSetValueKey(TargetKeyHandle,
- &CmSymbolicLinkValueName,
- 0,
- REG_LINK,
- KeyName.Buffer,
- KeyName.Length);
-
- /* Close the link key handle */
- NtClose(TargetKeyHandle);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmpLinkKeyToHive: couldn't create symbolic link for %S, Status
= 0x%08lx\n",
- TargetKeyName, Status);
+ SetupCloseInfFile(hInf);
return FALSE;
}
+ SetupCloseInfFile(hInf);
return TRUE;
}
-/*
- * Should be called under privileges
- */
-static NTSTATUS
-ConnectRegistry(
- IN HKEY RootKey OPTIONAL,
- IN PCWSTR RegMountPoint,
- // IN HANDLE RootDirectory OPTIONAL,
- IN PUNICODE_STRING InstallPath,
- IN PCWSTR RegistryKey
-/*
- IN PUCHAR Descriptor,
- IN ULONG DescriptorLength
-*/
- )
-{
- UNICODE_STRING KeyName, FileName;
- OBJECT_ATTRIBUTES KeyObjectAttributes;
- OBJECT_ATTRIBUTES FileObjectAttributes;
- WCHAR PathBuffer[MAX_PATH];
-
- RtlInitUnicodeString(&KeyName, RegMountPoint);
- InitializeObjectAttributes(&KeyObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- RootKey,
- NULL); // Descriptor
-
- CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3,
- InstallPath->Buffer, L"System32\\config", RegistryKey);
- RtlInitUnicodeString(&FileName, PathBuffer);
- InitializeObjectAttributes(&FileObjectAttributes,
- &FileName,
- OBJ_CASE_INSENSITIVE,
- NULL, // RootDirectory,
- NULL);
-
- /* Mount the registry hive in the registry namespace */
- return NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes);
-}
-
-
-static NTSTATUS
-VerifyRegistryHive(
- // IN HKEY RootKey OPTIONAL,
- // // IN HANDLE RootDirectory OPTIONAL,
- IN PUNICODE_STRING InstallPath,
- IN PCWSTR RegistryKey /* ,
- IN PCWSTR RegMountPoint */)
-{
- NTSTATUS Status;
- UNICODE_STRING KeyName;
- OBJECT_ATTRIBUTES ObjectAttributes;
-
- /* Try to mount the specified registry hive */
- Status = ConnectRegistry(NULL,
- L"\\Registry\\Machine\\USetup_VerifyHive",
- InstallPath,
- RegistryKey
- /* NULL, 0 */);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey,
Status);
- }
-
- DPRINT1("VerifyRegistryHive: ConnectRegistry(%S) returns Status 0x%08lx\n",
RegistryKey, Status);
-
- //
- // TODO: Check the Status error codes: STATUS_SUCCESS, STATUS_REGISTRY_RECOVERED,
- // STATUS_REGISTRY_HIVE_RECOVERED, STATUS_REGISTRY_CORRUPT,
STATUS_REGISTRY_IO_FAILED,
- // STATUS_NOT_REGISTRY_FILE, STATUS_CANNOT_LOAD_REGISTRY_FILE ;
- //(STATUS_HIVE_UNLOADED) ; STATUS_SYSTEM_HIVE_TOO_LARGE
- //
-
- if (Status == STATUS_REGISTRY_HIVE_RECOVERED) // NT_SUCCESS is still FALSE in this
case!
- DPRINT1("VerifyRegistryHive: Registry hive %S was recovered but some data
may be lost (Status 0x%08lx)\n", RegistryKey, Status);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("VerifyRegistryHive: Registry hive %S is corrupted (Status
0x%08lx)\n", RegistryKey, Status);
- return Status;
- }
-
- if (Status == STATUS_REGISTRY_RECOVERED)
- DPRINT1("VerifyRegistryHive: Registry hive %S succeeded recovered (Status
0x%08lx)\n", RegistryKey, Status);
-
- /* Unmount the hive */
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\USetup_VerifyHive");
- Status = NtUnloadKey(&ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtUnloadKey(%S, %wZ) failed, Status 0x%08lx\n", RegistryKey,
&KeyName, Status);
- }
-
- return Status;
-}
-
typedef enum _HIVE_UPDATE_STATE
{
@@ -1072,7 +688,6 @@ VerifyRegistryHives(
return Status;
}
-
NTSTATUS
RegInitializeRegistry(
IN PUNICODE_STRING InstallPath)
@@ -1444,14 +1059,9 @@ RegCleanupRegistry(
}
else
{
- RtlInitUnicodeString(&KeyName, RegistryHives[i].HiveRegistryPath);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- // Status = NtUnloadKey(&ObjectAttributes);
- Status = NtUnloadKey2(&ObjectAttributes, 1 /* REG_FORCE_UNLOAD */);
+ Status = DisconnectRegistry(NULL,
+ RegistryHives[i].HiveRegistryPath,
+ 1 /* REG_FORCE_UNLOAD */);
DPRINT1("Unmounting '%S' %s\n",
RegistryHives[i].HiveRegistryPath, NT_SUCCESS(Status) ? "succeeded" :
"failed");
/* Switch the hive state to 'Update' */
@@ -1505,39 +1115,4 @@ RegCleanupRegistry(
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
}
-
-VOID
-SetDefaultPagefile(
- WCHAR Drive)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName =
RTL_CONSTANT_STRING(L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory
Management");
- UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"PagingFiles");
- WCHAR ValueBuffer[] = L"?:\\pagefile.sys 0 0\0";
- HANDLE KeyHandle;
- NTSTATUS Status;
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle,
- NULL);
- Status = NtOpenKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- return;
-
- ValueBuffer[0] = Drive;
-
- NtSetValueKey(KeyHandle,
- &ValueName,
- 0,
- REG_MULTI_SZ,
- (PVOID)&ValueBuffer,
- sizeof(ValueBuffer));
-
- NtClose(KeyHandle);
-}
-
/* EOF */
diff --git a/base/setup/usetup/registry.h b/base/setup/lib/registry.h
similarity index 82%
copy from base/setup/usetup/registry.h
copy to base/setup/lib/registry.h
index b48777a126..7bc8d8f7a0 100644
--- a/base/setup/usetup/registry.h
+++ b/base/setup/lib/registry.h
@@ -18,10 +18,11 @@
*/
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS text-mode setup
- * FILE: base/setup/usetup/registry.h
+ * PROJECT: ReactOS Setup Library
+ * FILE: base/setup/lib/registry.h
* PURPOSE: Registry creation functions
- * PROGRAMMER:
+ * PROGRAMMERS: ...
+ * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
*/
#pragma once
@@ -38,11 +39,11 @@ GetRootKeyByName(
BOOLEAN
ImportRegistryFile(
- PCWSTR SourcePath,
- PWSTR Filename,
- PWSTR Section,
- LCID LocaleId,
- BOOLEAN Delete);
+ IN PCWSTR SourcePath,
+ IN PCWSTR FileName,
+ IN PCWSTR Section,
+ IN LCID LocaleId,
+ IN BOOLEAN Delete);
NTSTATUS
VerifyRegistryHives(
@@ -57,8 +58,4 @@ VOID
RegCleanupRegistry(
IN PUNICODE_STRING InstallPath);
-VOID
-SetDefaultPagefile(
- WCHAR Drive);
-
/* EOF */
diff --git a/base/setup/lib/regutil.c b/base/setup/lib/regutil.c
new file mode 100644
index 0000000000..eebbac0feb
--- /dev/null
+++ b/base/setup/lib/regutil.c
@@ -0,0 +1,457 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Setup Library
+ * FILE: base/setup/lib/regutil.c
+ * PURPOSE: Registry utility functions
+ * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "precomp.h"
+#include "filesup.h"
+
+#include "regutil.h"
+
+// HACK!
+#include <strsafe.h>
+
+#define NDEBUG
+#include <debug.h>
+
+
+// HACK!! These functions should actually be moved in the setup lib!
+// For the moment, see usetup/filesup.c (or .h)
+#if 1
+
+NTSTATUS
+SetupCopyFile(
+ IN PCWSTR SourceFileName,
+ IN PCWSTR DestinationFileName,
+ IN BOOLEAN FailIfExists);
+
+#define MOVEFILE_REPLACE_EXISTING 1
+
+NTSTATUS
+SetupMoveFile(
+ IN PCWSTR ExistingFileName,
+ IN PCWSTR NewFileName,
+ IN ULONG Flags);
+
+#endif
+
+/* FUNCTIONS ****************************************************************/
+
+/*
+ * This function is similar to the one in dlls/win32/advapi32/reg/reg.c
+ * TODO: I should review both of them very carefully, because they may need
+ * some adjustments in their NtCreateKey calls, especially for CreateOptions
+ * stuff etc...
+ */
+NTSTATUS
+CreateNestedKey(PHANDLE KeyHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ ULONG CreateOptions)
+{
+ OBJECT_ATTRIBUTES LocalObjectAttributes;
+ UNICODE_STRING LocalKeyName;
+ ULONG Disposition;
+ NTSTATUS Status;
+ USHORT FullNameLength;
+ PWCHAR Ptr;
+ HANDLE LocalKeyHandle;
+
+ Status = NtCreateKey(KeyHandle,
+ KEY_ALL_ACCESS,
+ ObjectAttributes,
+ 0,
+ NULL,
+ CreateOptions,
+ &Disposition);
+ DPRINT("NtCreateKey(%wZ) called (Status %lx)\n",
ObjectAttributes->ObjectName, Status);
+ if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ if (!NT_SUCCESS(Status))
+ DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n",
ObjectAttributes->ObjectName, Status);
+
+ return Status;
+ }
+
+ /* Copy object attributes */
+ RtlCopyMemory(&LocalObjectAttributes,
+ ObjectAttributes,
+ sizeof(OBJECT_ATTRIBUTES));
+ RtlCreateUnicodeString(&LocalKeyName,
+ ObjectAttributes->ObjectName->Buffer);
+ LocalObjectAttributes.ObjectName = &LocalKeyName;
+ FullNameLength = LocalKeyName.Length;
+
+ /* Remove the last part of the key name and try to create the key again. */
+ while (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ Ptr = wcsrchr(LocalKeyName.Buffer, '\\');
+ if (Ptr == NULL || Ptr == LocalKeyName.Buffer)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ break;
+ }
+ *Ptr = (WCHAR)0;
+ LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
+
+ Status = NtCreateKey(&LocalKeyHandle,
+ KEY_CREATE_SUB_KEY,
+ &LocalObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ &Disposition);
+ DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName,
Status);
+ if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
+ DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n",
LocalObjectAttributes.ObjectName, Status);
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&LocalKeyName);
+ return Status;
+ }
+
+ /* Add removed parts of the key name and create them too. */
+ while (TRUE)
+ {
+ if (LocalKeyName.Length == FullNameLength)
+ {
+ Status = STATUS_SUCCESS;
+ *KeyHandle = LocalKeyHandle;
+ break;
+ }
+ NtClose(LocalKeyHandle);
+
+ LocalKeyName.Buffer[LocalKeyName.Length / sizeof(WCHAR)] = L'\\';
+ LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
+
+ Status = NtCreateKey(&LocalKeyHandle,
+ KEY_ALL_ACCESS,
+ &LocalObjectAttributes,
+ 0,
+ NULL,
+ CreateOptions,
+ &Disposition);
+ DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName,
Status);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n",
LocalObjectAttributes.ObjectName, Status);
+ break;
+ }
+ }
+
+ RtlFreeUnicodeString(&LocalKeyName);
+
+ return Status;
+}
+
+
+/*
+ * Should be called under SE_BACKUP_PRIVILEGE privilege
+ */
+NTSTATUS
+CreateRegistryFile(
+ IN PUNICODE_STRING InstallPath,
+ IN PCWSTR RegistryKey,
+ IN BOOLEAN IsHiveNew,
+ IN HANDLE ProtoKeyHandle
+/*
+ IN PUCHAR Descriptor,
+ IN ULONG DescriptorLength
+*/
+ )
+{
+ /* '.old' is for old valid hives, while '.brk' is for old broken
hives */
+ static PCWSTR Extensions[] = {L"old", L"brk"};
+
+ NTSTATUS Status;
+ HANDLE FileHandle;
+ UNICODE_STRING FileName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PCWSTR Extension;
+ WCHAR PathBuffer[MAX_PATH];
+ WCHAR PathBuffer2[MAX_PATH];
+
+ CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3,
+ InstallPath->Buffer, L"System32\\config", RegistryKey);
+
+ Extension = Extensions[IsHiveNew ? 0 : 1];
+
+ //
+ // FIXME: The best, actually, would be to rename (move) the existing
+ // System32\config\RegistryKey file to System32\config\RegistryKey.old,
+ // and if it already existed some System32\config\RegistryKey.old, we should
+ // first rename this one into System32\config\RegistryKey_N.old before
+ // performing the original rename.
+ //
+
+ /* Check whether the registry hive file already existed, and if so, rename it */
+ if (DoesFileExist(NULL, PathBuffer))
+ {
+ // UINT i;
+
+ DPRINT1("Registry hive '%S' already exists, rename it\n",
PathBuffer);
+
+ // i = 1;
+ /* Try first by just appending the '.old' extension */
+ StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s",
PathBuffer, Extension);
+#if 0
+ while (DoesFileExist(NULL, PathBuffer2))
+ {
+ /* An old file already exists, increments its index, but not too much */
+ if (i <= 0xFFFF)
+ {
+ /* Append '_N.old' extension */
+ StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2),
L"%s_%lu.%s", PathBuffer, i, Extension);
+ ++i;
+ }
+ else
+ {
+ /*
+ * Too many old files exist, we will rename the file
+ * using the name of the oldest one.
+ */
+ StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s",
PathBuffer, Extension);
+ break;
+ }
+ }
+#endif
+
+ /* Now rename the file (force the move) */
+ Status = SetupMoveFile(PathBuffer, PathBuffer2, MOVEFILE_REPLACE_EXISTING);
+ }
+
+ /* Create the file */
+ RtlInitUnicodeString(&FileName, PathBuffer);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &FileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL, // Could have been InstallPath, etc...
+ NULL); // Descriptor
+
+ Status = NtCreateFile(&FileHandle,
+ FILE_GENERIC_WRITE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OVERWRITE_IF,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName,
Status);
+ return Status;
+ }
+
+ /* Save the selected hive into the file */
+ Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName,
Status);
+ }
+
+ /* Close the file and return */
+ NtClose(FileHandle);
+ return Status;
+}
+
+BOOLEAN
+CmpLinkKeyToHive(
+ IN HANDLE RootLinkKeyHandle OPTIONAL,
+ IN PCWSTR LinkKeyName,
+ IN PCWSTR TargetKeyName)
+{
+ static UNICODE_STRING CmSymbolicLinkValueName =
+ RTL_CONSTANT_STRING(L"SymbolicLinkValue");
+
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyName;
+ HANDLE TargetKeyHandle;
+ ULONG Disposition;
+
+ /* Initialize the object attributes */
+ RtlInitUnicodeString(&KeyName, LinkKeyName);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ RootLinkKeyHandle,
+ NULL);
+
+ /* Create the link key */
+ Status = NtCreateKey(&TargetKeyHandle,
+ KEY_SET_VALUE | KEY_CREATE_LINK,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
+ &Disposition);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CmpLinkKeyToHive: couldn't create %S, Status =
0x%08lx\n",
+ LinkKeyName, Status);
+ return FALSE;
+ }
+
+ /* Check if the new key was actually created */
+ if (Disposition != REG_CREATED_NEW_KEY)
+ {
+ DPRINT1("CmpLinkKeyToHive: %S already exists!\n", LinkKeyName);
+ NtClose(TargetKeyHandle);
+ return FALSE;
+ }
+
+ /* Set the target key name as link target */
+ RtlInitUnicodeString(&KeyName, TargetKeyName);
+ Status = NtSetValueKey(TargetKeyHandle,
+ &CmSymbolicLinkValueName,
+ 0,
+ REG_LINK,
+ KeyName.Buffer,
+ KeyName.Length);
+
+ /* Close the link key handle */
+ NtClose(TargetKeyHandle);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CmpLinkKeyToHive: couldn't create symbolic link for %S, Status
= 0x%08lx\n",
+ TargetKeyName, Status);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Should be called under SE_RESTORE_PRIVILEGE privilege
+ */
+NTSTATUS
+ConnectRegistry(
+ IN HKEY RootKey OPTIONAL,
+ IN PCWSTR RegMountPoint,
+ // IN HANDLE RootDirectory OPTIONAL,
+ IN PUNICODE_STRING InstallPath,
+ IN PCWSTR RegistryKey
+/*
+ IN PUCHAR Descriptor,
+ IN ULONG DescriptorLength
+*/
+ )
+{
+ UNICODE_STRING KeyName, FileName;
+ OBJECT_ATTRIBUTES KeyObjectAttributes;
+ OBJECT_ATTRIBUTES FileObjectAttributes;
+ WCHAR PathBuffer[MAX_PATH];
+
+ RtlInitUnicodeString(&KeyName, RegMountPoint);
+ InitializeObjectAttributes(&KeyObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ RootKey,
+ NULL); // Descriptor
+
+ CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3,
+ InstallPath->Buffer, L"System32\\config", RegistryKey);
+ RtlInitUnicodeString(&FileName, PathBuffer);
+ InitializeObjectAttributes(&FileObjectAttributes,
+ &FileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL, // RootDirectory,
+ NULL);
+
+ /* Mount the registry hive in the registry namespace */
+ return NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes);
+}
+
+/*
+ * Should be called under SE_RESTORE_PRIVILEGE privilege
+ */
+NTSTATUS
+DisconnectRegistry(
+ IN HKEY RootKey OPTIONAL,
+ IN PCWSTR RegMountPoint,
+ IN ULONG Flags)
+{
+ UNICODE_STRING KeyName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+
+ RtlInitUnicodeString(&KeyName, RegMountPoint);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ RootKey,
+ NULL);
+
+ // NOTE: NtUnloadKey == NtUnloadKey2 with Flags == 0.
+ return NtUnloadKey2(&ObjectAttributes, Flags);
+}
+
+/*
+ * Should be called under SE_RESTORE_PRIVILEGE privilege
+ */
+NTSTATUS
+VerifyRegistryHive(
+ // IN HKEY RootKey OPTIONAL,
+ // // IN HANDLE RootDirectory OPTIONAL,
+ IN PUNICODE_STRING InstallPath,
+ IN PCWSTR RegistryKey /* ,
+ IN PCWSTR RegMountPoint */)
+{
+ NTSTATUS Status;
+
+ /* Try to mount the specified registry hive */
+ Status = ConnectRegistry(NULL,
+ L"\\Registry\\Machine\\USetup_VerifyHive",
+ InstallPath,
+ RegistryKey
+ /* NULL, 0 */);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey,
Status);
+ }
+
+ DPRINT1("VerifyRegistryHive: ConnectRegistry(%S) returns Status 0x%08lx\n",
RegistryKey, Status);
+
+ //
+ // TODO: Check the Status error codes: STATUS_SUCCESS, STATUS_REGISTRY_RECOVERED,
+ // STATUS_REGISTRY_HIVE_RECOVERED, STATUS_REGISTRY_CORRUPT,
STATUS_REGISTRY_IO_FAILED,
+ // STATUS_NOT_REGISTRY_FILE, STATUS_CANNOT_LOAD_REGISTRY_FILE ;
+ //(STATUS_HIVE_UNLOADED) ; STATUS_SYSTEM_HIVE_TOO_LARGE
+ //
+
+ if (Status == STATUS_REGISTRY_HIVE_RECOVERED) // NT_SUCCESS is still FALSE in this
case!
+ DPRINT1("VerifyRegistryHive: Registry hive %S was recovered but some data
may be lost (Status 0x%08lx)\n", RegistryKey, Status);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("VerifyRegistryHive: Registry hive %S is corrupted (Status
0x%08lx)\n", RegistryKey, Status);
+ return Status;
+ }
+
+ if (Status == STATUS_REGISTRY_RECOVERED)
+ DPRINT1("VerifyRegistryHive: Registry hive %S succeeded recovered (Status
0x%08lx)\n", RegistryKey, Status);
+
+ /* Unmount the hive */
+ Status = DisconnectRegistry(NULL,
+ L"\\Registry\\Machine\\USetup_VerifyHive",
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("DisconnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey,
Status);
+ }
+
+ return Status;
+}
+
+/* EOF */
diff --git a/base/setup/lib/regutil.h b/base/setup/lib/regutil.h
new file mode 100644
index 0000000000..2b2d6a12e1
--- /dev/null
+++ b/base/setup/lib/regutil.h
@@ -0,0 +1,80 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Setup Library
+ * FILE: base/setup/lib/regutil.h
+ * PURPOSE: Registry utility functions
+ * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
+ */
+
+#pragma once
+
+/*
+ * This function is similar to the one in dlls/win32/advapi32/reg/reg.c
+ * TODO: I should review both of them very carefully, because they may need
+ * some adjustments in their NtCreateKey calls, especially for CreateOptions
+ * stuff etc...
+ */
+NTSTATUS
+CreateNestedKey(PHANDLE KeyHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ ULONG CreateOptions);
+
+/*
+ * Should be called under SE_BACKUP_PRIVILEGE privilege
+ */
+NTSTATUS
+CreateRegistryFile(
+ IN PUNICODE_STRING InstallPath,
+ IN PCWSTR RegistryKey,
+ IN BOOLEAN IsHiveNew,
+ IN HANDLE ProtoKeyHandle
+/*
+ IN PUCHAR Descriptor,
+ IN ULONG DescriptorLength
+*/
+ );
+
+BOOLEAN
+CmpLinkKeyToHive(
+ IN HANDLE RootLinkKeyHandle OPTIONAL,
+ IN PCWSTR LinkKeyName,
+ IN PCWSTR TargetKeyName);
+
+/*
+ * Should be called under SE_RESTORE_PRIVILEGE privilege
+ */
+NTSTATUS
+ConnectRegistry(
+ IN HKEY RootKey OPTIONAL,
+ IN PCWSTR RegMountPoint,
+ // IN HANDLE RootDirectory OPTIONAL,
+ IN PUNICODE_STRING InstallPath,
+ IN PCWSTR RegistryKey
+/*
+ IN PUCHAR Descriptor,
+ IN ULONG DescriptorLength
+*/
+ );
+
+/*
+ * Should be called under SE_RESTORE_PRIVILEGE privilege
+ */
+NTSTATUS
+DisconnectRegistry(
+ IN HKEY RootKey OPTIONAL,
+ IN PCWSTR RegMountPoint,
+ IN ULONG Flags);
+
+/*
+ * Should be called under SE_RESTORE_PRIVILEGE privilege
+ */
+NTSTATUS
+VerifyRegistryHive(
+ // IN HKEY RootKey OPTIONAL,
+ // // IN HANDLE RootDirectory OPTIONAL,
+ IN PUNICODE_STRING InstallPath,
+ IN PCWSTR RegistryKey /* ,
+ IN PCWSTR RegMountPoint */);
+
+/* EOF */
diff --git a/base/setup/lib/setuplib.h b/base/setup/lib/setuplib.h
index bee6e9f87f..73b308ae4f 100644
--- a/base/setup/lib/setuplib.h
+++ b/base/setup/lib/setuplib.h
@@ -34,5 +34,7 @@ extern HANDLE ProcessHeap;
#include "partlist.h"
#include "arcname.h"
#include "osdetect.h"
+#include "regutil.h"
+#include "registry.h"
/* EOF */
diff --git a/base/setup/usetup/inffile.c b/base/setup/usetup/inffile.c
index 10adbcf5c2..47edb34a58 100644
--- a/base/setup/usetup/inffile.c
+++ b/base/setup/usetup/inffile.c
@@ -21,7 +21,8 @@
* PROJECT: ReactOS text-mode setup
* FILE: base/setup/usetup/inffile.c
* PURPOSE: .inf files support functions
- * PROGRAMMER: Herv� Poussineau
+ * PROGRAMMERS: Herv� Poussineau
+ * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
*/
/* INCLUDES ******************************************************************/
@@ -31,11 +32,23 @@
#define NDEBUG
#include <debug.h>
-/* FUNCTIONS *****************************************************************/
+/* SETUP* API COMPATIBILITY FUNCTIONS ****************************************/
+/* Functions from the INFLIB library */
+
+extern VOID InfCloseFile(HINF InfHandle);
+// #define SetupCloseInfFile InfCloseFile
+VOID
+WINAPI
+SetupCloseInfFile(HINF InfHandle)
+{
+ InfCloseFile(InfHandle);
+}
+
+// #define SetupFindFirstLineW InfpFindFirstLineW
BOOL
WINAPI
-InfpFindFirstLineW(
+SetupFindFirstLineW(
IN HINF InfHandle,
IN PCWSTR Section,
IN PCWSTR Key,
@@ -53,10 +66,128 @@ InfpFindFirstLineW(
return TRUE;
}
+extern BOOLEAN InfFindNextLine(PINFCONTEXT ContextIn,
+ PINFCONTEXT ContextOut);
+// #define SetupFindNextLine InfFindNextLine
+BOOL
+WINAPI
+SetupFindNextLine(PINFCONTEXT ContextIn,
+ PINFCONTEXT ContextOut)
+{
+ return !!InfFindNextLine(ContextIn, ContextOut);
+}
+
+extern LONG InfGetFieldCount(PINFCONTEXT Context);
+// #define SetupGetFieldCount InfGetFieldCount
+LONG
+WINAPI
+SetupGetFieldCount(PINFCONTEXT Context)
+{
+ return InfGetFieldCount(Context);
+}
+
+/*
+ * This function corresponds to an undocumented but exported setupapi API
+ * that exists since WinNT4 and is still present in Win10.
+ * The returned string pointer is a read-only pointer to a string in the
+ * maintained INF cache, and is always in UNICODE (on NT systems).
+ */
+extern BOOLEAN InfGetDataField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWCHAR *Data);
+PCWSTR
+WINAPI
+pSetupGetField(PINFCONTEXT Context,
+ ULONG FieldIndex)
+{
+ PWCHAR Data = NULL;
+ if (!InfGetDataField(Context, FieldIndex, &Data))
+ return NULL;
+ return Data;
+}
+
+extern BOOLEAN InfGetBinaryField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PUCHAR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+// #define SetupGetBinaryField InfGetBinaryField
+BOOL
+WINAPI
+SetupGetBinaryField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PUCHAR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize)
+{
+ return !!InfGetBinaryField(Context,
+ FieldIndex,
+ ReturnBuffer,
+ ReturnBufferSize,
+ RequiredSize);
+}
+extern BOOLEAN InfGetIntField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ INT *IntegerValue);
+// #define SetupGetIntField InfGetIntField
+BOOL
+WINAPI
+SetupGetIntField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ INT *IntegerValue) // PINT
+{
+ return !!InfGetIntField(Context, FieldIndex, IntegerValue);
+}
+
+extern BOOLEAN InfGetMultiSzField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+// #define SetupGetMultiSzFieldW InfGetMultiSzField
+BOOL
+WINAPI
+SetupGetMultiSzFieldW(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize)
+{
+ return !!InfGetMultiSzField(Context,
+ FieldIndex,
+ ReturnBuffer,
+ ReturnBufferSize,
+ RequiredSize);
+}
+
+extern BOOLEAN InfGetStringField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+// #define SetupGetStringFieldW InfGetStringField
+BOOL
+WINAPI
+SetupGetStringFieldW(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize)
+{
+ return !!InfGetStringField(Context,
+ FieldIndex,
+ ReturnBuffer,
+ ReturnBufferSize,
+ RequiredSize);
+}
+
+
+/* SetupOpenInfFileW with support for a user-provided LCID */
+// #define SetupOpenInfFileExW InfpOpenInfFileW
HINF
WINAPI
-InfpOpenInfFileW(
+SetupOpenInfFileExW(
IN PCWSTR FileName,
IN PCWSTR InfClass,
IN DWORD InfStyle,
@@ -81,25 +212,7 @@ InfpOpenInfFileW(
}
-BOOLEAN
-INF_GetData(
- IN PINFCONTEXT Context,
- OUT PWCHAR *Key,
- OUT PWCHAR *Data)
-{
- return InfGetData(Context, Key, Data);
-}
-
-
-BOOLEAN
-INF_GetDataField(
- IN PINFCONTEXT Context,
- IN ULONG FieldIndex,
- OUT PWCHAR *Data)
-{
- return InfGetDataField(Context, FieldIndex, Data);
-}
-
+/* HELPER FUNCTIONS **********************************************************/
HINF WINAPI
INF_OpenBufferedFileA(
diff --git a/base/setup/usetup/inffile.h b/base/setup/usetup/inffile.h
index 610c9e23a3..90fb5e7d5f 100644
--- a/base/setup/usetup/inffile.h
+++ b/base/setup/usetup/inffile.h
@@ -21,88 +21,32 @@
* PROJECT: ReactOS text-mode setup
* FILE: base/setup/usetup/inffile.h
* PURPOSE: .inf files support functions
- * PROGRAMMER: Herv� Poussineau
+ * PROGRAMMERS: Herv� Poussineau
+ * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr)
*/
#pragma once
-#include <infcommon.h>
+#ifdef __REACTOS__
-extern VOID InfSetHeap(PVOID Heap);
-extern VOID InfCloseFile(HINF InfHandle);
-extern BOOLEAN InfFindNextLine(PINFCONTEXT ContextIn,
- PINFCONTEXT ContextOut);
-extern BOOLEAN InfGetBinaryField(PINFCONTEXT Context,
- ULONG FieldIndex,
- PUCHAR ReturnBuffer,
- ULONG ReturnBufferSize,
- PULONG RequiredSize);
-extern BOOLEAN InfGetMultiSzField(PINFCONTEXT Context,
- ULONG FieldIndex,
- PWSTR ReturnBuffer,
- ULONG ReturnBufferSize,
- PULONG RequiredSize);
-extern BOOLEAN InfGetStringField(PINFCONTEXT Context,
- ULONG FieldIndex,
- PWSTR ReturnBuffer,
- ULONG ReturnBufferSize,
- PULONG RequiredSize);
-
-#define SetupCloseInfFile InfCloseFile
-#define SetupFindNextLine InfFindNextLine
-#define SetupGetBinaryField InfGetBinaryField
-#define SetupGetMultiSzFieldW InfGetMultiSzField
-#define SetupGetStringFieldW InfGetStringField
-
-
-#define SetupFindFirstLineW InfpFindFirstLineW
-#define SetupGetFieldCount InfGetFieldCount
-#define SetupGetIntField InfGetIntField
+// HACK around the fact INFLIB unconditionally defines MAX_INF_STRING_LENGTH.
+#undef MAX_INF_STRING_LENGTH
-// SetupOpenInfFileW with support for a user-provided LCID
-#define SetupOpenInfFileExW InfpOpenInfFileW
+/* Functions from the INFLIB library */
+// #include <infcommon.h>
+#include <infros.h>
-#define INF_STYLE_WIN4 0x00000002
+#undef MAX_INF_STRING_LENGTH
+#define MAX_INF_STRING_LENGTH 1024
-/* FIXME: this structure is the one used in inflib, not in setupapi
- * Delete it once we don't use inflib anymore */
-typedef struct _INFCONTEXT
-{
- HINF Inf;
- HINF CurrentInf;
- UINT Section;
- UINT Line;
-} INFCONTEXT;
-C_ASSERT(sizeof(INFCONTEXT) == 2 * sizeof(PVOID) + 2 * sizeof(UINT));
+extern VOID InfSetHeap(PVOID Heap);
-BOOL
-WINAPI
-InfpFindFirstLineW(
- IN HINF InfHandle,
- IN PCWSTR Section,
- IN PCWSTR Key,
- IN OUT PINFCONTEXT Context);
+#endif /* __REACTOS__ */
-HINF
-WINAPI
-InfpOpenInfFileW(
- IN PCWSTR FileName,
- IN PCWSTR InfClass,
- IN DWORD InfStyle,
- IN LCID LocaleId,
- OUT PUINT ErrorLine);
+#include <../lib/infsupp.h>
-BOOLEAN
-INF_GetData(
- IN PINFCONTEXT Context,
- OUT PWCHAR *Key,
- OUT PWCHAR *Data);
-BOOLEAN
-INF_GetDataField(
- IN PINFCONTEXT Context,
- IN ULONG FieldIndex,
- OUT PWCHAR *Data);
+/* HELPER FUNCTIONS **********************************************************/
HINF WINAPI
INF_OpenBufferedFileA(
diff --git a/base/setup/usetup/registry.c b/base/setup/usetup/registry.c
index 749835c3d7..f8e1d72fc8 100644
--- a/base/setup/usetup/registry.c
+++ b/base/setup/usetup/registry.c
@@ -28,1484 +28,11 @@
#include "usetup.h"
-// HACK!
-#include <strsafe.h>
-
#define NDEBUG
#include <debug.h>
-#define FLG_ADDREG_BINVALUETYPE 0x00000001
-#define FLG_ADDREG_NOCLOBBER 0x00000002
-#define FLG_ADDREG_DELVAL 0x00000004
-#define FLG_ADDREG_APPEND 0x00000008
-#define FLG_ADDREG_KEYONLY 0x00000010
-#define FLG_ADDREG_OVERWRITEONLY 0x00000020
-#define FLG_ADDREG_TYPE_SZ 0x00000000
-#define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000
-#define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000
-#define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE)
-#define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE)
-#define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE)
-#define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE)
-
-#ifdef _M_IX86
-#define Architecture L"x86"
-#elif defined(_M_AMD64)
-#define Architecture L"amd64"
-#elif defined(_M_IA64)
-#define Architecture L"ia64"
-#elif defined(_M_ARM)
-#define Architecture L"arm"
-#elif defined(_M_PPC)
-#define Architecture L"ppc"
-#endif
-
/* FUNCTIONS ****************************************************************/
-#define REGISTRY_SETUP_MACHINE
L"\\Registry\\Machine\\SYSTEM\\USetup_Machine\\"
-#define REGISTRY_SETUP_USER L"\\Registry\\Machine\\SYSTEM\\USetup_User\\"
-
-typedef struct _ROOT_KEY
-{
- PCWSTR Name;
- PCWSTR MountPoint;
- HANDLE Handle;
-} ROOT_KEY, *PROOT_KEY;
-
-ROOT_KEY RootKeys[] =
-{
- { L"HKCR", REGISTRY_SETUP_MACHINE L"SOFTWARE\\Classes\\", NULL },
/* "\\Registry\\Machine\\SOFTWARE\\Classes\\" */ // HKEY_CLASSES_ROOT
- { L"HKCU", REGISTRY_SETUP_USER L".DEFAULT\\" , NULL },
/* "\\Registry\\User\\.DEFAULT\\" */ // HKEY_CURRENT_USER
- { L"HKLM", REGISTRY_SETUP_MACHINE , NULL }, /*
"\\Registry\\Machine\\" */ // HKEY_LOCAL_MACHINE
- { L"HKU" , REGISTRY_SETUP_USER , NULL }, /*
"\\Registry\\User\\" */ // HKEY_USERS
-#if 0
- { L"HKR", NULL, NULL },
-#endif
-};
-
-#define IsPredefKey(HKey) \
- (((ULONG_PTR)(HKey) & 0xF0000000) == 0x80000000)
-
-#define GetPredefKeyIndex(HKey) \
- ((ULONG_PTR)(HKey) & 0x0FFFFFFF)
-
-HANDLE
-GetRootKeyByPredefKey(
- IN HANDLE KeyHandle,
- OUT PCWSTR* RootKeyMountPoint OPTIONAL)
-{
- ULONG_PTR Index = GetPredefKeyIndex(KeyHandle);
-
- if (!IsPredefKey(KeyHandle))
- return NULL;
- if (GetPredefKeyIndex(KeyHandle) >= ARRAYSIZE(RootKeys))
- return NULL;
-
- if (RootKeyMountPoint)
- *RootKeyMountPoint = RootKeys[Index].MountPoint;
- return RootKeys[Index].Handle;
-}
-
-HANDLE
-GetRootKeyByName(
- IN PCWSTR RootKeyName,
- OUT PCWSTR* RootKeyMountPoint OPTIONAL)
-{
- UCHAR i;
-
- for (i = 0; i < ARRAYSIZE(RootKeys); ++i)
- {
- if (!_wcsicmp(RootKeyName, RootKeys[i].Name))
- {
- if (RootKeyMountPoint)
- *RootKeyMountPoint = RootKeys[i].MountPoint;
- return RootKeys[i].Handle;
- }
- }
-
- return NULL;
-}
-
-
-/***********************************************************************
- * append_multi_sz_value
- *
- * Append a multisz string to a multisz registry value.
- */
-// NOTE: Synced with setupapi/install.c ; see also mkhive/reginf.c
-#if 0
-static void
-append_multi_sz_value (HANDLE hkey,
- const WCHAR *value,
- const WCHAR *strings,
- DWORD str_size )
-{
- DWORD size, type, total;
- WCHAR *buffer, *p;
-
- if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
- if (type != REG_MULTI_SZ) return;
-
- if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size + str_size * sizeof(WCHAR) )))
return;
- if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto
done;
-
- /* compare each string against all the existing ones */
- total = size;
- while (*strings)
- {
- int len = strlenW(strings) + 1;
-
- for (p = buffer; *p; p += strlenW(p) + 1)
- if (!strcmpiW( p, strings )) break;
-
- if (!*p) /* not found, need to append it */
- {
- memcpy( p, strings, len * sizeof(WCHAR) );
- p[len] = 0;
- total += len;
- }
- strings += len;
- }
- if (total != size)
- {
- TRACE( "setting value %s to %s\n", debugstr_w(value),
debugstr_w(buffer) );
- RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total );
- }
- done:
- HeapFree( GetProcessHeap(), 0, buffer );
-}
-#endif
-
-/***********************************************************************
- * delete_multi_sz_value
- *
- * Remove a string from a multisz registry value.
- */
-#if 0
-static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string )
-{
- DWORD size, type;
- WCHAR *buffer, *src, *dst;
-
- if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
- if (type != REG_MULTI_SZ) return;
- /* allocate double the size, one for value before and one for after */
- if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2 * sizeof(WCHAR) ))) return;
- if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto
done;
- src = buffer;
- dst = buffer + size;
- while (*src)
- {
- int len = strlenW(src) + 1;
- if (strcmpiW( src, string ))
- {
- memcpy( dst, src, len * sizeof(WCHAR) );
- dst += len;
- }
- src += len;
- }
- *dst++ = 0;
- if (dst != buffer + 2*size) /* did we remove something? */
- {
- TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer
+ size) );
- RegSetValueExW( hkey, value, 0, REG_MULTI_SZ,
- (BYTE *)(buffer + size), dst - (buffer + size) );
- }
- done:
- HeapFree( GetProcessHeap(), 0, buffer );
-}
-#endif
-
-/***********************************************************************
- * do_reg_operation
- *
- * Perform an add/delete registry operation depending on the flags.
- */
-static BOOLEAN
-do_reg_operation(HANDLE KeyHandle,
- PUNICODE_STRING ValueName,
- PINFCONTEXT Context,
- ULONG Flags)
-{
- WCHAR EmptyStr = 0;
- ULONG Type;
- ULONG Size;
-
- if (Flags & FLG_ADDREG_DELVAL) /* deletion */
- {
-#if 0
- if (ValueName)
- {
- RegDeleteValueW( KeyHandle, ValueName );
- }
- else
- {
- RegDeleteKeyW( KeyHandle, NULL );
- }
-#endif
- return TRUE;
- }
-
- if (Flags & FLG_ADDREG_KEYONLY)
- return TRUE;
-
-#if 0
- if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY))
- {
- BOOL exists = !RegQueryValueExW( hkey, ValueName, NULL, NULL, NULL, NULL );
- if (exists && (flags & FLG_ADDREG_NOCLOBBER))
- return TRUE;
- if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY))
- return TRUE;
- }
-#endif
-
- switch (Flags & FLG_ADDREG_TYPE_MASK)
- {
- case FLG_ADDREG_TYPE_SZ:
- Type = REG_SZ;
- break;
-
- case FLG_ADDREG_TYPE_MULTI_SZ:
- Type = REG_MULTI_SZ;
- break;
-
- case FLG_ADDREG_TYPE_EXPAND_SZ:
- Type = REG_EXPAND_SZ;
- break;
-
- case FLG_ADDREG_TYPE_BINARY:
- Type = REG_BINARY;
- break;
-
- case FLG_ADDREG_TYPE_DWORD:
- Type = REG_DWORD;
- break;
-
- case FLG_ADDREG_TYPE_NONE:
- Type = REG_NONE;
- break;
-
- default:
- Type = Flags >> 16;
- break;
- }
-
- if (!(Flags & FLG_ADDREG_BINVALUETYPE) ||
- (Type == REG_DWORD && SetupGetFieldCount (Context) == 5))
- {
- PWCHAR Str = NULL;
-
- if (Type == REG_MULTI_SZ)
- {
- if (!SetupGetMultiSzFieldW (Context, 5, NULL, 0, &Size))
- Size = 0;
-
- if (Size)
- {
- Str = (WCHAR*) RtlAllocateHeap(ProcessHeap, 0, Size * sizeof(WCHAR));
- if (Str == NULL)
- return FALSE;
-
- SetupGetMultiSzFieldW (Context, 5, Str, Size, NULL);
- }
-
- if (Flags & FLG_ADDREG_APPEND)
- {
- if (Str == NULL)
- return TRUE;
-
- DPRINT1("append_multi_sz_value '%S' commented out,
WHY??\n", ValueName);
-// append_multi_sz_value( hkey, value, str, size );
-
- RtlFreeHeap (ProcessHeap, 0, Str);
- return TRUE;
- }
- /* else fall through to normal string handling */
- }
- else
- {
- if (!SetupGetStringFieldW(Context, 5, NULL, 0, &Size))
- Size = 0;
-
- if (Size)
- {
- Str = (WCHAR*)RtlAllocateHeap(ProcessHeap, 0, Size * sizeof(WCHAR));
- if (Str == NULL)
- return FALSE;
-
- SetupGetStringFieldW(Context, 5, Str, Size, NULL);
- }
- }
-
- if (Type == REG_DWORD)
- {
- ULONG dw = Str ? wcstoul (Str, NULL, 0) : 0;
-
- DPRINT("setting dword %wZ to %lx\n", ValueName, dw);
-
- NtSetValueKey (KeyHandle,
- ValueName,
- 0,
- Type,
- (PVOID)&dw,
- sizeof(ULONG));
- }
- else
- {
- DPRINT("setting value %wZ to %S\n", ValueName, Str);
-
- if (Str)
- {
- NtSetValueKey (KeyHandle,
- ValueName,
- 0,
- Type,
- (PVOID)Str,
- Size * sizeof(WCHAR));
- }
- else
- {
- NtSetValueKey (KeyHandle,
- ValueName,
- 0,
- Type,
- (PVOID)&EmptyStr,
- sizeof(WCHAR));
- }
- }
- RtlFreeHeap (ProcessHeap, 0, Str);
- }
- else /* get the binary data */
- {
- PUCHAR Data = NULL;
-
- if (!SetupGetBinaryField (Context, 5, NULL, 0, &Size))
- Size = 0;
-
- if (Size)
- {
- Data = (unsigned char*) RtlAllocateHeap(ProcessHeap, 0, Size);
- if (Data == NULL)
- return FALSE;
-
- DPRINT("setting binary data %wZ len %lu\n", ValueName, Size);
- SetupGetBinaryField (Context, 5, Data, Size, NULL);
- }
-
- NtSetValueKey (KeyHandle,
- ValueName,
- 0,
- Type,
- (PVOID)Data,
- Size);
-
- RtlFreeHeap (ProcessHeap, 0, Data);
- }
-
- return TRUE;
-}
-
-/*
- * This function is similar to the one in dlls/win32/advapi32/reg/reg.c
- * TODO: I should review both of them very carefully, because they may need
- * some adjustments in their NtCreateKey calls, especially for CreateOptions
- * stuff etc...
- */
-NTSTATUS
-CreateNestedKey(PHANDLE KeyHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- ULONG CreateOptions)
-{
- OBJECT_ATTRIBUTES LocalObjectAttributes;
- UNICODE_STRING LocalKeyName;
- ULONG Disposition;
- NTSTATUS Status;
- USHORT FullNameLength;
- PWCHAR Ptr;
- HANDLE LocalKeyHandle;
-
- Status = NtCreateKey(KeyHandle,
- KEY_ALL_ACCESS,
- ObjectAttributes,
- 0,
- NULL,
- CreateOptions,
- &Disposition);
- DPRINT("NtCreateKey(%wZ) called (Status %lx)\n",
ObjectAttributes->ObjectName, Status);
- if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
- {
- if (!NT_SUCCESS(Status))
- DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n",
ObjectAttributes->ObjectName, Status);
-
- return Status;
- }
-
- /* Copy object attributes */
- RtlCopyMemory(&LocalObjectAttributes,
- ObjectAttributes,
- sizeof(OBJECT_ATTRIBUTES));
- RtlCreateUnicodeString(&LocalKeyName,
- ObjectAttributes->ObjectName->Buffer);
- LocalObjectAttributes.ObjectName = &LocalKeyName;
- FullNameLength = LocalKeyName.Length;
-
- /* Remove the last part of the key name and try to create the key again. */
- while (Status == STATUS_OBJECT_NAME_NOT_FOUND)
- {
- Ptr = wcsrchr(LocalKeyName.Buffer, '\\');
- if (Ptr == NULL || Ptr == LocalKeyName.Buffer)
- {
- Status = STATUS_UNSUCCESSFUL;
- break;
- }
- *Ptr = (WCHAR)0;
- LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
-
- Status = NtCreateKey(&LocalKeyHandle,
- KEY_CREATE_SUB_KEY,
- &LocalObjectAttributes,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- &Disposition);
- DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName,
Status);
- if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
- DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n",
LocalObjectAttributes.ObjectName, Status);
- }
-
- if (!NT_SUCCESS(Status))
- {
- RtlFreeUnicodeString(&LocalKeyName);
- return Status;
- }
-
- /* Add removed parts of the key name and create them too. */
- while (TRUE)
- {
- if (LocalKeyName.Length == FullNameLength)
- {
- Status = STATUS_SUCCESS;
- *KeyHandle = LocalKeyHandle;
- break;
- }
- NtClose(LocalKeyHandle);
-
- LocalKeyName.Buffer[LocalKeyName.Length / sizeof(WCHAR)] = L'\\';
- LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
-
- Status = NtCreateKey(&LocalKeyHandle,
- KEY_ALL_ACCESS,
- &LocalObjectAttributes,
- 0,
- NULL,
- CreateOptions,
- &Disposition);
- DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName,
Status);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n",
LocalObjectAttributes.ObjectName, Status);
- break;
- }
- }
-
- RtlFreeUnicodeString(&LocalKeyName);
-
- return Status;
-}
-
-/***********************************************************************
- * registry_callback
- *
- * Called once for each AddReg and DelReg entry in a given section.
- */
-static BOOLEAN
-registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete)
-{
- NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING Name, Value;
- PUNICODE_STRING ValuePtr;
- UINT Flags;
- WCHAR Buffer[MAX_INF_STRING_LENGTH];
-
- INFCONTEXT Context;
- PCWSTR RootKeyName;
- HANDLE RootKeyHandle, KeyHandle;
- BOOLEAN Ok;
-
- Ok = SetupFindFirstLineW(hInf, Section, NULL, &Context);
- if (!Ok)
- return TRUE; /* Don't fail if the section isn't present */
-
- for (;Ok; Ok = SetupFindNextLine (&Context, &Context))
- {
- /* get root */
- if (!SetupGetStringFieldW(&Context, 1, Buffer, sizeof(Buffer)/sizeof(WCHAR),
NULL))
- continue;
- RootKeyHandle = GetRootKeyByName(Buffer, &RootKeyName);
- if (!RootKeyHandle)
- continue;
-
- /* get key */
- if (!SetupGetStringFieldW(&Context, 2, Buffer, sizeof(Buffer)/sizeof(WCHAR),
NULL))
- *Buffer = 0;
-
- DPRINT("KeyName: <%S\\%S>\n", RootKeyName, Buffer);
-
- /* get flags */
- if (!SetupGetIntField(&Context, 4, (PINT)&Flags))
- Flags = 0;
-
- DPRINT("Flags: %lx\n", Flags);
-
- RtlInitUnicodeString(&Name, Buffer);
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- RootKeyHandle,
- NULL);
-
- if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY))
- {
- Status = NtOpenKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtOpenKey(%wZ) failed (Status %lx)\n", &Name,
Status);
- continue; /* ignore if it doesn't exist */
- }
- }
- else
- {
- Status = CreateNestedKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- REG_OPTION_NON_VOLATILE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CreateNestedKey(%wZ) failed (Status %lx)\n",
&Name, Status);
- continue;
- }
- }
-
- /* get value name */
- if (SetupGetStringFieldW(&Context, 3, Buffer, sizeof(Buffer)/sizeof(WCHAR),
NULL))
- {
- RtlInitUnicodeString(&Value, Buffer);
- ValuePtr = &Value;
- }
- else
- {
- ValuePtr = NULL;
- }
-
- /* and now do it */
- if (!do_reg_operation(KeyHandle, ValuePtr, &Context, Flags))
- {
- NtClose(KeyHandle);
- return FALSE;
- }
-
- NtClose(KeyHandle);
- }
-
- return TRUE;
-}
-
-
-BOOLEAN
-ImportRegistryFile(
- PCWSTR SourcePath,
- PWSTR Filename,
- PWSTR Section,
- LCID LocaleId,
- BOOLEAN Delete)
-{
- WCHAR FileNameBuffer[MAX_PATH];
- HINF hInf;
- UINT ErrorLine;
-
- /* Load inf file from install media. */
- CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2,
- SourcePath, Filename);
-
- hInf = SetupOpenInfFileExW(FileNameBuffer,
- NULL,
- INF_STYLE_WIN4,
- LocaleId,
- &ErrorLine);
- if (hInf == INVALID_HANDLE_VALUE)
- {
- DPRINT1("SetupOpenInfFile() failed\n");
- return FALSE;
- }
-
-#if 0
- if (!registry_callback(hInf, L"DelReg", FALSE))
- {
- DPRINT1("registry_callback() failed\n");
- InfCloseFile(hInf);
- return FALSE;
- }
-#endif
-
- if (!registry_callback(hInf, L"AddReg", FALSE))
- {
- DPRINT1("registry_callback() failed\n");
- InfCloseFile(hInf);
- return FALSE;
- }
-
- if (!registry_callback(hInf, L"AddReg.NT" Architecture, FALSE))
- {
- DPRINT1("registry_callback() failed\n");
- InfCloseFile(hInf);
- return FALSE;
- }
-
- InfCloseFile(hInf);
- return TRUE;
-}
-
-/*
- * Should be called under privileges
- */
-static NTSTATUS
-CreateRegistryFile(
- IN PUNICODE_STRING InstallPath,
- IN PCWSTR RegistryKey,
- IN BOOLEAN IsHiveNew,
- IN HANDLE ProtoKeyHandle
-/*
- IN PUCHAR Descriptor,
- IN ULONG DescriptorLength
-*/
- )
-{
- /* '.old' is for old valid hives, while '.brk' is for old broken
hives */
- static PCWSTR Extensions[] = {L"old", L"brk"};
-
- NTSTATUS Status;
- HANDLE FileHandle;
- UNICODE_STRING FileName;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- PCWSTR Extension;
- WCHAR PathBuffer[MAX_PATH];
- WCHAR PathBuffer2[MAX_PATH];
-
- CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3,
- InstallPath->Buffer, L"System32\\config", RegistryKey);
-
- Extension = Extensions[IsHiveNew ? 0 : 1];
-
- //
- // FIXME: The best, actually, would be to rename (move) the existing
- // System32\config\RegistryKey file to System32\config\RegistryKey.old,
- // and if it already existed some System32\config\RegistryKey.old, we should
- // first rename this one into System32\config\RegistryKey_N.old before
- // performing the original rename.
- //
-
- /* Check whether the registry hive file already existed, and if so, rename it */
- if (DoesFileExist(NULL, PathBuffer))
- {
- // UINT i;
-
- DPRINT1("Registry hive '%S' already exists, rename it\n",
PathBuffer);
-
- // i = 1;
- /* Try first by just appending the '.old' extension */
- StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s",
PathBuffer, Extension);
-#if 0
- while (DoesFileExist(NULL, PathBuffer2))
- {
- /* An old file already exists, increments its index, but not too much */
- if (i <= 0xFFFF)
- {
- /* Append '_N.old' extension */
- StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2),
L"%s_%lu.%s", PathBuffer, i, Extension);
- ++i;
- }
- else
- {
- /*
- * Too many old files exist, we will rename the file
- * using the name of the oldest one.
- */
- StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s",
PathBuffer, Extension);
- break;
- }
- }
-#endif
-
- /* Now rename the file (force the move) */
- Status = SetupMoveFile(PathBuffer, PathBuffer2, MOVEFILE_REPLACE_EXISTING);
- }
-
- /* Create the file */
- RtlInitUnicodeString(&FileName, PathBuffer);
- InitializeObjectAttributes(&ObjectAttributes,
- &FileName,
- OBJ_CASE_INSENSITIVE,
- NULL, // Could have been InstallPath, etc...
- NULL); // Descriptor
-
- Status = NtCreateFile(&FileHandle,
- FILE_GENERIC_WRITE,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_OVERWRITE_IF,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
- NULL,
- 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName,
Status);
- return Status;
- }
-
- /* Save the selected hive into the file */
- Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName,
Status);
- }
-
- /* Close the file and return */
- NtClose(FileHandle);
- return Status;
-}
-
-static BOOLEAN
-CmpLinkKeyToHive(
- IN HANDLE RootLinkKeyHandle OPTIONAL,
- IN PCWSTR LinkKeyName,
- IN PCWSTR TargetKeyName)
-{
- static UNICODE_STRING CmSymbolicLinkValueName =
- RTL_CONSTANT_STRING(L"SymbolicLinkValue");
-
- NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName;
- HANDLE TargetKeyHandle;
- ULONG Disposition;
-
- /* Initialize the object attributes */
- RtlInitUnicodeString(&KeyName, LinkKeyName);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- RootLinkKeyHandle,
- NULL);
-
- /* Create the link key */
- Status = NtCreateKey(&TargetKeyHandle,
- KEY_SET_VALUE | KEY_CREATE_LINK,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
- &Disposition);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmpLinkKeyToHive: couldn't create %S, Status =
0x%08lx\n",
- LinkKeyName, Status);
- return FALSE;
- }
-
- /* Check if the new key was actually created */
- if (Disposition != REG_CREATED_NEW_KEY)
- {
- DPRINT1("CmpLinkKeyToHive: %S already exists!\n", LinkKeyName);
- NtClose(TargetKeyHandle);
- return FALSE;
- }
-
- /* Set the target key name as link target */
- RtlInitUnicodeString(&KeyName, TargetKeyName);
- Status = NtSetValueKey(TargetKeyHandle,
- &CmSymbolicLinkValueName,
- 0,
- REG_LINK,
- KeyName.Buffer,
- KeyName.Length);
-
- /* Close the link key handle */
- NtClose(TargetKeyHandle);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmpLinkKeyToHive: couldn't create symbolic link for %S, Status
= 0x%08lx\n",
- TargetKeyName, Status);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- * Should be called under privileges
- */
-static NTSTATUS
-ConnectRegistry(
- IN HKEY RootKey OPTIONAL,
- IN PCWSTR RegMountPoint,
- // IN HANDLE RootDirectory OPTIONAL,
- IN PUNICODE_STRING InstallPath,
- IN PCWSTR RegistryKey
-/*
- IN PUCHAR Descriptor,
- IN ULONG DescriptorLength
-*/
- )
-{
- UNICODE_STRING KeyName, FileName;
- OBJECT_ATTRIBUTES KeyObjectAttributes;
- OBJECT_ATTRIBUTES FileObjectAttributes;
- WCHAR PathBuffer[MAX_PATH];
-
- RtlInitUnicodeString(&KeyName, RegMountPoint);
- InitializeObjectAttributes(&KeyObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- RootKey,
- NULL); // Descriptor
-
- CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3,
- InstallPath->Buffer, L"System32\\config", RegistryKey);
- RtlInitUnicodeString(&FileName, PathBuffer);
- InitializeObjectAttributes(&FileObjectAttributes,
- &FileName,
- OBJ_CASE_INSENSITIVE,
- NULL, // RootDirectory,
- NULL);
-
- /* Mount the registry hive in the registry namespace */
- return NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes);
-}
-
-
-static NTSTATUS
-VerifyRegistryHive(
- // IN HKEY RootKey OPTIONAL,
- // // IN HANDLE RootDirectory OPTIONAL,
- IN PUNICODE_STRING InstallPath,
- IN PCWSTR RegistryKey /* ,
- IN PCWSTR RegMountPoint */)
-{
- NTSTATUS Status;
- UNICODE_STRING KeyName;
- OBJECT_ATTRIBUTES ObjectAttributes;
-
- /* Try to mount the specified registry hive */
- Status = ConnectRegistry(NULL,
- L"\\Registry\\Machine\\USetup_VerifyHive",
- InstallPath,
- RegistryKey
- /* NULL, 0 */);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey,
Status);
- }
-
- DPRINT1("VerifyRegistryHive: ConnectRegistry(%S) returns Status 0x%08lx\n",
RegistryKey, Status);
-
- //
- // TODO: Check the Status error codes: STATUS_SUCCESS, STATUS_REGISTRY_RECOVERED,
- // STATUS_REGISTRY_HIVE_RECOVERED, STATUS_REGISTRY_CORRUPT,
STATUS_REGISTRY_IO_FAILED,
- // STATUS_NOT_REGISTRY_FILE, STATUS_CANNOT_LOAD_REGISTRY_FILE ;
- //(STATUS_HIVE_UNLOADED) ; STATUS_SYSTEM_HIVE_TOO_LARGE
- //
-
- if (Status == STATUS_REGISTRY_HIVE_RECOVERED) // NT_SUCCESS is still FALSE in this
case!
- DPRINT1("VerifyRegistryHive: Registry hive %S was recovered but some data
may be lost (Status 0x%08lx)\n", RegistryKey, Status);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("VerifyRegistryHive: Registry hive %S is corrupted (Status
0x%08lx)\n", RegistryKey, Status);
- return Status;
- }
-
- if (Status == STATUS_REGISTRY_RECOVERED)
- DPRINT1("VerifyRegistryHive: Registry hive %S succeeded recovered (Status
0x%08lx)\n", RegistryKey, Status);
-
- /* Unmount the hive */
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\USetup_VerifyHive");
- Status = NtUnloadKey(&ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtUnloadKey(%S, %wZ) failed, Status 0x%08lx\n", RegistryKey,
&KeyName, Status);
- }
-
- return Status;
-}
-
-
-typedef enum _HIVE_UPDATE_STATE
-{
- Create, // Create a new hive file and save possibly existing old one with a .old
extension.
- Repair, // Re-create a new hive file and save possibly existing old one with a .brk
extension.
- Update // Hive update, do not need to be recreated.
-} HIVE_UPDATE_STATE;
-
-typedef struct _HIVE_LIST_ENTRY
-{
- PCWSTR HiveName; // HiveFileName;
- PCWSTR HiveRegistryPath; // HiveRegMountPoint;
- HANDLE PredefKeyHandle;
- PCWSTR RegSymLink;
- HIVE_UPDATE_STATE State;
- // PUCHAR SecurityDescriptor;
- // ULONG SecurityDescriptorLength;
-} HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY;
-
-#define NUMBER_OF_STANDARD_REGISTRY_HIVES 3
-
-HIVE_LIST_ENTRY RegistryHives[/*NUMBER_OF_STANDARD_REGISTRY_HIVES*/] =
-{
- { L"SYSTEM" , L"\\Registry\\Machine\\USetup_SYSTEM" ,
HKEY_LOCAL_MACHINE, L"SYSTEM" , Create /* , SystemSecurity ,
sizeof(SystemSecurity) */ },
- { L"SOFTWARE", L"\\Registry\\Machine\\USetup_SOFTWARE",
HKEY_LOCAL_MACHINE, L"SOFTWARE", Create /* , SoftwareSecurity,
sizeof(SoftwareSecurity) */ },
- { L"DEFAULT" , L"\\Registry\\User\\USetup_DEFAULT" ,
HKEY_USERS , L".DEFAULT", Create /* , SystemSecurity ,
sizeof(SystemSecurity) */ },
-
-// { L"BCD" , L"\\Registry\\Machine\\USetup_BCD",
HKEY_LOCAL_MACHINE, L"BCD00000000", Create /* , BcdSecurity ,
sizeof(BcdSecurity) */ },
-};
-C_ASSERT(_countof(RegistryHives) == NUMBER_OF_STANDARD_REGISTRY_HIVES);
-
-#define NUMBER_OF_SECURITY_REGISTRY_HIVES 2
-
-/** These hives are created by LSASS during 2nd stage setup */
-HIVE_LIST_ENTRY SecurityRegistryHives[/*NUMBER_OF_SECURITY_REGISTRY_HIVES*/] =
-{
- { L"SAM" , L"\\Registry\\Machine\\USetup_SAM" ,
HKEY_LOCAL_MACHINE, L"SAM" , Create /* , SystemSecurity ,
sizeof(SystemSecurity) */ },
- { L"SECURITY", L"\\Registry\\Machine\\USetup_SECURITY",
HKEY_LOCAL_MACHINE, L"SECURITY", Create /* , NULL , 0
*/ },
-};
-C_ASSERT(_countof(SecurityRegistryHives) == NUMBER_OF_SECURITY_REGISTRY_HIVES);
-
-
-NTSTATUS
-VerifyRegistryHives(
- IN PUNICODE_STRING InstallPath,
- OUT PBOOLEAN ShouldRepairRegistry)
-{
- NTSTATUS Status;
- BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
- UINT i;
-
- /* Suppose first the registry hives do not have to be fully recreated */
- *ShouldRepairRegistry = FALSE;
-
- /* Acquire restore privilege */
- Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE,
&PrivilegeSet[0]);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status
0x%08lx)\n", Status);
- /* Exit prematurely here.... */
- return Status;
- }
-
- /* Acquire backup privilege */
- Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status
0x%08lx)\n", Status);
- RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
- /* Exit prematurely here.... */
- return Status;
- }
-
- for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
- {
- Status = VerifyRegistryHive(InstallPath, RegistryHives[i].HiveName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Registry hive '%S' needs repair!\n",
RegistryHives[i].HiveName);
- RegistryHives[i].State = Repair;
- *ShouldRepairRegistry = TRUE;
- }
- else
- {
- RegistryHives[i].State = Update;
- }
- }
-
- /** These hives are created by LSASS during 2nd stage setup */
- for (i = 0; i < ARRAYSIZE(SecurityRegistryHives); ++i)
- {
- Status = VerifyRegistryHive(InstallPath, SecurityRegistryHives[i].HiveName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Registry hive '%S' needs repair!\n",
SecurityRegistryHives[i].HiveName);
- SecurityRegistryHives[i].State = Repair;
- /*
- * Note that it's not the role of the 1st-stage installer to fix
- * the security hives. This should be done at 2nd-stage installation
- * by LSASS.
- */
- }
- else
- {
- SecurityRegistryHives[i].State = Update;
- }
- }
-
- /* Reset the status (we succeeded in checking all the hives) */
- Status = STATUS_SUCCESS;
-
- /* Remove restore and backup privileges */
- RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE,
&PrivilegeSet[1]);
- RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
-
- return Status;
-}
-
-
-NTSTATUS
-RegInitializeRegistry(
- IN PUNICODE_STRING InstallPath)
-{
- NTSTATUS Status;
- HANDLE KeyHandle;
- UNICODE_STRING KeyName;
- OBJECT_ATTRIBUTES ObjectAttributes;
- BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
- ULONG Disposition;
- UINT i;
-
- /* Acquire restore privilege */
- Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE,
&PrivilegeSet[0]);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status
0x%08lx)\n", Status);
- /* Exit prematurely here.... */
- return Status;
- }
-
- /* Acquire backup privilege */
- Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status
0x%08lx)\n", Status);
- RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
- /* Exit prematurely here.... */
- return Status;
- }
-
- /*
- * Create the template proto-hive.
- *
- * Use a dummy root key name:
- * - On 2k/XP/2k3, this is "$$$PROTO.HIV"
- * - On Vista+, this is "CMI-CreateHive{guid}"
- * See
https://github.com/libyal/winreg-kb/blob/master/documentation/Registry%20fi…
- * for more information.
- */
- RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\SYSTEM\\$$$PROTO.HIV");
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = NtCreateKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtCreateKey() failed to create the proto-hive (Status %lx)\n",
Status);
- goto Quit;
- }
- NtFlushKey(KeyHandle);
-
- for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
- {
- if (RegistryHives[i].State != Create && RegistryHives[i].State !=
Repair)
- continue;
-
- Status = CreateRegistryFile(InstallPath,
- RegistryHives[i].HiveName,
- RegistryHives[i].State != Repair, //
RegistryHives[i].State == Create,
- KeyHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CreateRegistryFile(%S) failed, Status 0x%08lx\n",
RegistryHives[i].HiveName, Status);
- /* Exit prematurely here.... */
- /* That is now done, remove the proto-hive */
- NtDeleteKey(KeyHandle);
- NtClose(KeyHandle);
- goto Quit;
- }
- }
-
- /* That is now done, remove the proto-hive */
- NtDeleteKey(KeyHandle);
- NtClose(KeyHandle);
-
-
- /*
- * Prepare the registry root keys. Since we cannot create real registry keys
- * inside the master keys (\Registry, \Registry\Machine or \Registry\User),
- * we need to perform some SymLink tricks instead.
- */
-
- /* Our offline HKLM '\Registry\Machine' is inside
'\Registry\Machine\SYSTEM\USetup_Machine' */
- RtlInitUnicodeString(&KeyName,
RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].MountPoint);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- KeyHandle = NULL;
- Status = NtCreateKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE, // REG_OPTION_VOLATILE, // FIXME!
- &Disposition);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName,
Status);
- // return Status;
- }
- RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle = KeyHandle;
-
- /* Our offline HKU '\Registry\User' is inside
'\Registry\Machine\SYSTEM\USetup_User' */
- RtlInitUnicodeString(&KeyName,
RootKeys[GetPredefKeyIndex(HKEY_USERS)].MountPoint);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- KeyHandle = NULL;
- Status = NtCreateKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE, // REG_OPTION_VOLATILE, // FIXME!
- &Disposition);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName,
Status);
- // return Status;
- }
- RootKeys[GetPredefKeyIndex(HKEY_USERS)].Handle = KeyHandle;
-
-
- /*
- * Now properly mount the offline hive files
- */
- for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
- {
- // if (RegistryHives[i].State != Create && RegistryHives[i].State !=
Repair)
- // continue;
-
- if (RegistryHives[i].State == Create || RegistryHives[i].State == Repair)
- {
- Status = ConnectRegistry(NULL,
- RegistryHives[i].HiveRegistryPath,
- InstallPath,
- RegistryHives[i].HiveName
- /* SystemSecurity, sizeof(SystemSecurity) */);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n",
RegistryHives[i].HiveName, Status);
- }
-
- /* Create the registry symlink to this key */
- if
(!CmpLinkKeyToHive(RootKeys[GetPredefKeyIndex(RegistryHives[i].PredefKeyHandle)].Handle,
- RegistryHives[i].RegSymLink,
- RegistryHives[i].HiveRegistryPath))
- {
- DPRINT1("CmpLinkKeyToHive(%S) failed!\n",
RegistryHives[i].HiveName);
- }
- }
- else
- {
- /* Create *DUMMY* volatile hives just to make the update procedure working
*/
-
- RtlInitUnicodeString(&KeyName, RegistryHives[i].RegSymLink);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
-
RootKeys[GetPredefKeyIndex(RegistryHives[i].PredefKeyHandle)].Handle,
- NULL);
- KeyHandle = NULL;
- Status = NtCreateKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE, // REG_OPTION_VOLATILE, //
FIXME!
- &Disposition);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n",
&KeyName, Status);
- // return Status;
- }
- NtClose(KeyHandle);
- }
- }
-
-
- /* HKCU is a handle to 'HKU\.DEFAULT' */
-#if 0
- RtlInitUnicodeString(&KeyName, L".DEFAULT");
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- RootKeys[GetPredefKeyIndex(HKEY_USERS)].Handle,
- NULL);
-#else
- RtlInitUnicodeString(&KeyName,
RootKeys[GetPredefKeyIndex(HKEY_CURRENT_USER)].MountPoint);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-#endif
- KeyHandle = NULL;
- Status = NtOpenKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtOpenKey(%wZ) failed (Status %lx)\n", &KeyName, Status);
- }
- RootKeys[GetPredefKeyIndex(HKEY_CURRENT_USER)].Handle = KeyHandle;
-
-
- /* HKCR is a handle to 'HKLM\Software\Classes' */
-#if 0
- RtlInitUnicodeString(&KeyName, L"Software\\Classes");
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle,
- NULL);
-#else
- RtlInitUnicodeString(&KeyName,
RootKeys[GetPredefKeyIndex(HKEY_CLASSES_ROOT)].MountPoint);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-#endif
- KeyHandle = NULL;
- /* We use NtCreateKey instead of NtOpenKey because Software\Classes doesn't exist
originally */
- Status = NtCreateKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- &Disposition);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtCreateKey(%wZ) failed (Status %lx)\n", &KeyName,
Status);
- }
- else
- {
- DPRINT1("NtCreateKey() succeeded to %s the %wZ key (Status %lx)\n",
- Disposition == REG_CREATED_NEW_KEY ? "create" : /*
REG_OPENED_EXISTING_KEY */ "open",
- &KeyName, Status);
- }
- RootKeys[GetPredefKeyIndex(HKEY_CLASSES_ROOT)].Handle = KeyHandle;
-
-
- Status = STATUS_SUCCESS;
-
-
- /* Create the 'HKLM\SYSTEM\ControlSet001' key */
- // REGISTRY_SETUP_MACHINE L"SYSTEM\\ControlSet001"
- RtlInitUnicodeString(&KeyName, L"SYSTEM\\ControlSet001");
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle,
- NULL);
- Status = NtCreateKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- &Disposition);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtCreateKey() failed to create the ControlSet001 key (Status
%lx)\n", Status);
- // return Status;
- }
- else
- {
- DPRINT1("NtCreateKey() succeeded to %s the ControlSet001 key (Status
%lx)\n",
- Disposition == REG_CREATED_NEW_KEY ? "create" : /*
REG_OPENED_EXISTING_KEY */ "open",
- Status);
- }
- NtClose(KeyHandle);
-
- /* Create the 'HKLM\SYSTEM\CurrentControlSet' symlink */
- if (!CmpLinkKeyToHive(RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle,
- L"SYSTEM\\CurrentControlSet",
- REGISTRY_SETUP_MACHINE L"SYSTEM\\ControlSet001"))
- {
- DPRINT1("CmpLinkKeyToHive(CurrentControlSet) failed!\n");
- }
-
-
- Status = STATUS_SUCCESS;
-
-
-Quit:
- /* Remove restore and backup privileges */
- RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE,
&PrivilegeSet[1]);
- RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
-
- return Status;
-}
-
-VOID
-RegCleanupRegistry(
- IN PUNICODE_STRING InstallPath)
-{
- NTSTATUS Status;
- HANDLE KeyHandle;
- UNICODE_STRING KeyName;
- OBJECT_ATTRIBUTES ObjectAttributes;
- BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
- UINT i;
- WCHAR SrcPath[MAX_PATH];
- WCHAR DstPath[MAX_PATH];
-
- /* Acquire restore privilege */
- Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE,
&PrivilegeSet[0]);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status
0x%08lx)\n", Status);
- /* Exit prematurely here.... */
- return;
- }
-
- /* Acquire backup privilege */
- Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status
0x%08lx)\n", Status);
- RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
- /* Exit prematurely here.... */
- return;
- }
-
- /*
- * Note that we don't need to explicitly remove the symlinks we have created
- * since they are created volatile, inside registry keys that will be however
- * removed explictly in the following.
- */
-
- for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
- {
- if (RegistryHives[i].State != Create && RegistryHives[i].State !=
Repair)
- {
- RtlInitUnicodeString(&KeyName, RegistryHives[i].RegSymLink);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
-
RootKeys[GetPredefKeyIndex(RegistryHives[i].PredefKeyHandle)].Handle,
- NULL);
- KeyHandle = NULL;
- Status = NtOpenKey(&KeyHandle,
- DELETE,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtOpenKey(%wZ) failed, Status 0x%08lx\n",
&KeyName, Status);
- // return;
- }
-
- NtDeleteKey(KeyHandle);
- NtClose(KeyHandle);
- }
- else
- {
- RtlInitUnicodeString(&KeyName, RegistryHives[i].HiveRegistryPath);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- // Status = NtUnloadKey(&ObjectAttributes);
- Status = NtUnloadKey2(&ObjectAttributes, 1 /* REG_FORCE_UNLOAD */);
- DPRINT1("Unmounting '%S' %s\n",
RegistryHives[i].HiveRegistryPath, NT_SUCCESS(Status) ? "succeeded" :
"failed");
-
- /* Switch the hive state to 'Update' */
- RegistryHives[i].State = Update;
- }
- }
-
- /*
- * FIXME: Once force-unloading keys is correctly fixed, I'll fix
- * this code that closes some of the registry keys that were opened
- * inside the hives we've just unmounted above...
- */
-
- /* Remove the registry root keys */
- for (i = 0; i < ARRAYSIZE(RootKeys); ++i)
- {
- if (RootKeys[i].Handle)
- {
- /**/NtFlushKey(RootKeys[i].Handle);/**/ // FIXME: Why does it hang? Answer:
because we have some problems in CMAPI!
- NtDeleteKey(RootKeys[i].Handle);
- NtClose(RootKeys[i].Handle);
- RootKeys[i].Handle = NULL;
- }
- }
-
- //
- // RegBackupRegistry()
- //
- /* Now backup the hives into .sav files */
- for (i = 0; i < ARRAYSIZE(RegistryHives); ++i)
- {
- if (RegistryHives[i].State != Create && RegistryHives[i].State !=
Repair)
- continue;
-
- CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 3,
- InstallPath->Buffer, L"System32\\config",
RegistryHives[i].HiveName);
- StringCchCopyW(DstPath, ARRAYSIZE(DstPath), SrcPath);
- StringCchCatW(DstPath, ARRAYSIZE(DstPath), L".sav");
-
- DPRINT1("Copy hive: %S ==> %S\n", SrcPath, DstPath);
- Status = SetupCopyFile(SrcPath, DstPath, FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
- // return Status;
- }
- }
-
- /* Remove restore and backup privileges */
- RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE,
&PrivilegeSet[1]);
- RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
-}
-
-
VOID
SetDefaultPagefile(
WCHAR Drive)
@@ -1520,7 +47,7 @@ SetDefaultPagefile(
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
- RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle,
+ GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL),
NULL);
Status = NtOpenKey(&KeyHandle,
KEY_ALL_ACCESS,
diff --git a/base/setup/usetup/registry.h b/base/setup/usetup/registry.h
index b48777a126..ef53b708ff 100644
--- a/base/setup/usetup/registry.h
+++ b/base/setup/usetup/registry.h
@@ -26,37 +26,6 @@
#pragma once
-HANDLE
-GetRootKeyByPredefKey(
- IN HANDLE KeyHandle,
- OUT PCWSTR* RootKeyMountPoint OPTIONAL);
-
-HANDLE
-GetRootKeyByName(
- IN PCWSTR RootKeyName,
- OUT PCWSTR* RootKeyMountPoint OPTIONAL);
-
-BOOLEAN
-ImportRegistryFile(
- PCWSTR SourcePath,
- PWSTR Filename,
- PWSTR Section,
- LCID LocaleId,
- BOOLEAN Delete);
-
-NTSTATUS
-VerifyRegistryHives(
- IN PUNICODE_STRING InstallPath,
- OUT PBOOLEAN ShouldRepairRegistry);
-
-NTSTATUS
-RegInitializeRegistry(
- IN PUNICODE_STRING InstallPath);
-
-VOID
-RegCleanupRegistry(
- IN PUNICODE_STRING InstallPath);
-
VOID
SetDefaultPagefile(
WCHAR Drive);
diff --git a/base/setup/usetup/usetup.h b/base/setup/usetup/usetup.h
index 6e95582ce7..ca7fed0671 100644
--- a/base/setup/usetup/usetup.h
+++ b/base/setup/usetup/usetup.h
@@ -61,7 +61,6 @@
#include "consup.h"
#include "inffile.h"
#include "progress.h"
-#include "infros.h"
#include "filequeue.h"
#include "registry.h"
#include "fslist.h"