https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7fedeb7db334962cad79d…
commit 7fedeb7db334962cad79de12f25a448982cb43f3
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Thu Jun 22 00:38:32 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Thu Oct 25 01:00:43 2018 +0200
[USETUP] More code for updating/repairing the registry. Fix the name of the
txtsetup.sif section to look for when performing a registry upgrade.
[BOOTDATA] Add needed entries in txtsetup.sif for registry upgrade.
svn path=/branches/setup_improvements/; revision=75162
svn path=/branches/setup_improvements/; revision=75226
---
base/setup/usetup/registry.c | 102 +++++++++++++++++--------
base/setup/usetup/registry.h | 2 +-
base/setup/usetup/usetup.c | 172 +++++++++++++++++++++++++++----------------
boot/bootdata/txtsetup.sif | 9 ++-
4 files changed, 188 insertions(+), 97 deletions(-)
diff --git a/base/setup/usetup/registry.c b/base/setup/usetup/registry.c
index bb79689789..50fbb31d1d 100644
--- a/base/setup/usetup/registry.c
+++ b/base/setup/usetup/registry.c
@@ -750,7 +750,7 @@ CreateRegistryFile(
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
OBJ_CASE_INSENSITIVE,
- NULL, // Could have been installpath, etc...
+ NULL, // Could have been InstallPath, etc...
NULL); // Descriptor
Status = NtCreateFile(&FileHandle,
@@ -902,7 +902,7 @@ VerifyRegistryHive(
{
NTSTATUS Status;
UNICODE_STRING KeyName;
- OBJECT_ATTRIBUTES KeyObjectAttributes;
+ OBJECT_ATTRIBUTES ObjectAttributes;
/* Try to mount the specified registry hive */
Status = ConnectRegistry(NULL,
@@ -937,14 +937,14 @@ VerifyRegistryHive(
DPRINT1("VerifyRegistryHive: Registry hive %S succeeded recovered (Status
0x%08lx)\n", RegistryKey, Status);
/* Unmount the hive */
- InitializeObjectAttributes(&KeyObjectAttributes,
+ InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\USetup_VerifyHive");
- Status = NtUnloadKey(&KeyObjectAttributes);
+ Status = NtUnloadKey(&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtUnloadKey(%S, %wZ) failed, Status 0x%08lx\n", RegistryKey,
&KeyName, Status);
@@ -998,14 +998,14 @@ C_ASSERT(_countof(SecurityRegistryHives) ==
NUMBER_OF_SECURITY_REGISTRY_HIVES);
NTSTATUS
VerifyRegistryHives(
IN PUNICODE_STRING InstallPath,
- OUT PBOOLEAN ShouldUpdateRegistry)
+ OUT PBOOLEAN ShouldRepairRegistry)
{
NTSTATUS Status;
BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
UINT i;
- /* Suppose first the registry hives do not have to be updated/recreated */
- *ShouldUpdateRegistry = FALSE;
+ /* 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]);
@@ -1033,7 +1033,7 @@ VerifyRegistryHives(
{
DPRINT1("Registry hive '%S' needs repair!\n",
RegistryHives[i].HiveName);
RegistryHives[i].State = Repair;
- *ShouldUpdateRegistry = TRUE;
+ *ShouldRepairRegistry = TRUE;
}
else
{
@@ -1145,14 +1145,14 @@ RegInitializeRegistry(
{
DPRINT1("CreateRegistryFile(%S) failed, Status 0x%08lx\n",
RegistryHives[i].HiveName, Status);
/* Exit prematurely here.... */
- /* That is now done, clean everything up! */
+ /* That is now done, remove the proto-hive */
NtDeleteKey(KeyHandle);
NtClose(KeyHandle);
goto Quit;
}
}
- /* That is now done, clean everything up! */
+ /* That is now done, remove the proto-hive */
NtDeleteKey(KeyHandle);
NtClose(KeyHandle);
@@ -1238,7 +1238,7 @@ RegInitializeRegistry(
}
else
{
- /* Create *DUMMY* volatile hives just to make the update procedure work */
+ /* Create *DUMMY* volatile hives just to make the update procedure working
*/
RtlInitUnicodeString(&KeyName, RegistryHives[i].RegSymLink);
InitializeObjectAttributes(&ObjectAttributes,
@@ -1385,23 +1385,14 @@ RegCleanupRegistry(
IN PUNICODE_STRING InstallPath)
{
NTSTATUS Status;
+ HANDLE KeyHandle;
UNICODE_STRING KeyName;
- OBJECT_ATTRIBUTES KeyObjectAttributes;
+ OBJECT_ATTRIBUTES ObjectAttributes;
BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
UINT i;
WCHAR SrcPath[MAX_PATH];
WCHAR DstPath[MAX_PATH];
- for (i = 0; i < ARRAYSIZE(RootKeys); ++i)
- {
- if (RootKeys[i].Handle)
- {
- NtFlushKey(RootKeys[i].Handle);
- NtClose(RootKeys[i].Handle);
- RootKeys[i].Handle = NULL;
- }
- }
-
/* Acquire restore privilege */
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE,
&PrivilegeSet[0]);
if (!NT_SUCCESS(Status))
@@ -1421,20 +1412,68 @@ RegCleanupRegistry(
return;
}
- InitializeObjectAttributes(&KeyObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ /*
+ * 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)
- continue;
+ {
+ 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");
- RtlInitUnicodeString(&KeyName, RegistryHives[i].HiveRegistryPath);
- Status = NtUnloadKey(&KeyObjectAttributes);
- 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;
+ }
}
//
@@ -1465,6 +1504,7 @@ RegCleanupRegistry(
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
}
+
VOID
SetDefaultPagefile(
WCHAR Drive)
diff --git a/base/setup/usetup/registry.h b/base/setup/usetup/registry.h
index cae50e8271..0548061a35 100644
--- a/base/setup/usetup/registry.h
+++ b/base/setup/usetup/registry.h
@@ -46,7 +46,7 @@ ImportRegistryFile(
NTSTATUS
VerifyRegistryHives(
IN PUNICODE_STRING InstallPath,
- OUT PBOOLEAN ShouldUpdateRegistry);
+ OUT PBOOLEAN ShouldRepairRegistry);
NTSTATUS
RegInitializeRegistry(
diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c
index 80d6345aa2..a8e72676d3 100644
--- a/base/setup/usetup/usetup.c
+++ b/base/setup/usetup/usetup.c
@@ -4079,32 +4079,32 @@ RegistryPage(PINPUT_RECORD Ir)
PWSTR Action;
PWSTR File;
PWSTR Section;
+ BOOLEAN Success;
+ BOOLEAN ShouldRepairRegistry = FALSE;
BOOLEAN Delete;
MUIDisplayPage(REGISTRY_PAGE);
if (RepairUpdateFlag)
{
- BOOLEAN ShouldUpdateRegistry = FALSE;
-
DPRINT1("TODO: Updating / repairing the registry is not completely
implemented yet!\n");
/* Verify the registry hives and check whether we need to update or repair any of
them */
- Status = VerifyRegistryHives(&DestinationPath, &ShouldUpdateRegistry);
+ Status = VerifyRegistryHives(&DestinationPath, &ShouldRepairRegistry);
if (!NT_SUCCESS(Status))
{
DPRINT1("VerifyRegistryHives failed, Status 0x%08lx\n", Status);
- ShouldUpdateRegistry = FALSE;
- }
- if (!ShouldUpdateRegistry)
- {
- DPRINT1("No need to update the registry\n");
- // return SUCCESS_PAGE;
- goto Quit;
+ ShouldRepairRegistry = FALSE;
}
+ if (!ShouldRepairRegistry)
+ DPRINT1("No need to repair the registry\n");
}
- /* Initialize the registry and setup the default installation hives */
+DoUpdate:
+ /* Update the registry */
+ CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE));
+
+ /* Initialize the registry and setup the registry hives */
Status = RegInitializeRegistry(&DestinationPath);
if (!NT_SUCCESS(Status))
{
@@ -4124,14 +4124,41 @@ RegistryPage(PINPUT_RECORD Ir)
return QUIT_PAGE;
}
- /* Update registry */
- CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE));
+ if (!RepairUpdateFlag || ShouldRepairRegistry)
+ {
+ /*
+ * We fully setup the hives, in case we are doing a fresh installation
+ * (RepairUpdateFlag == FALSE), or in case we are doing an update
+ * (RepairUpdateFlag == TRUE) BUT we have some registry hives to
+ * "repair" (aka. recreate: ShouldRepairRegistry == TRUE).
+ */
+
+ Success = SetupFindFirstLineW(SetupInf, L"HiveInfs.Fresh", NULL,
&InfContext); // Windows-compatible
+ if (!Success)
+ Success = SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL,
&InfContext); // ReactOS-specific
- if (!SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL,
&InfContext))
+ if (!Success)
+ {
+ DPRINT1("SetupFindFirstLine() failed\n");
+ MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
+ }
+ else // if (RepairUpdateFlag && !ShouldRepairRegistry)
{
- DPRINT1("SetupFindFirstLine() failed\n");
- MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER);
- goto Cleanup;
+ /*
+ * In case we are doing an update (RepairUpdateFlag == TRUE) and
+ * NO registry hives need a repair (ShouldRepairRegistry == FALSE),
+ * we only update the hives.
+ */
+
+ Success = SetupFindFirstLineW(SetupInf, L"HiveInfs.Upgrade", NULL,
&InfContext);
+ if (!Success)
+ {
+ /* Nothing to do for update! */
+ DPRINT1("No update needed for the registry!\n");
+ goto Cleanup;
+ }
}
do
@@ -4150,7 +4177,10 @@ RegistryPage(PINPUT_RECORD Ir)
else if (!_wcsicmp(Action, L"DelReg"))
Delete = TRUE;
else
+ {
+ DPRINT1("Unrecognized registry INF action '%S'\n",
Action);
continue;
+ }
CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE), File);
@@ -4162,62 +4192,67 @@ RegistryPage(PINPUT_RECORD Ir)
}
} while (SetupFindNextLine(&InfContext, &InfContext));
- /* Update display registry settings */
- CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE));
- if (!ProcessDisplayRegistry(SetupInf, DisplayList))
+ if (!RepairUpdateFlag || ShouldRepairRegistry)
{
- MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS, Ir, POPUP_WAIT_ENTER);
- goto Cleanup;
- }
+ /* See the explanation for this test above */
- /* Set the locale */
- CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE));
- if (!ProcessLocaleRegistry(LanguageList))
- {
- MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS, Ir, POPUP_WAIT_ENTER);
- goto Cleanup;
- }
+ /* Update display registry settings */
+ CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE));
+ if (!ProcessDisplayRegistry(SetupInf, DisplayList))
+ {
+ MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
- /* Add keyboard layouts */
- CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS));
- if (!AddKeyboardLayouts())
- {
- MUIDisplayError(ERROR_ADDING_KBLAYOUTS, Ir, POPUP_WAIT_ENTER);
- goto Cleanup;
- }
+ /* Set the locale */
+ CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE));
+ if (!ProcessLocaleRegistry(LanguageList))
+ {
+ MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
- /* Set GeoID */
- if (!SetGeoID(MUIGetGeoID()))
- {
- MUIDisplayError(ERROR_UPDATE_GEOID, Ir, POPUP_WAIT_ENTER);
- goto Cleanup;
- }
+ /* Add keyboard layouts */
+ CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS));
+ if (!AddKeyboardLayouts())
+ {
+ MUIDisplayError(ERROR_ADDING_KBLAYOUTS, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
- if (!IsUnattendedSetup)
- {
- /* Update keyboard layout settings */
- CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE));
- if (!ProcessKeyboardLayoutRegistry(LayoutList))
+ /* Set GeoID */
+ if (!SetGeoID(MUIGetGeoID()))
{
- MUIDisplayError(ERROR_UPDATE_KBSETTINGS, Ir, POPUP_WAIT_ENTER);
+ MUIDisplayError(ERROR_UPDATE_GEOID, Ir, POPUP_WAIT_ENTER);
goto Cleanup;
}
- }
- /* Add codepage information to registry */
- CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE));
- if (!AddCodePage())
- {
- MUIDisplayError(ERROR_ADDING_CODEPAGE, Ir, POPUP_WAIT_ENTER);
- goto Cleanup;
- }
+ if (!IsUnattendedSetup)
+ {
+ /* Update keyboard layout settings */
+ CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE));
+ if (!ProcessKeyboardLayoutRegistry(LayoutList))
+ {
+ MUIDisplayError(ERROR_UPDATE_KBSETTINGS, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
+ }
+
+ /* Add codepage information to registry */
+ CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE));
+ if (!AddCodePage())
+ {
+ MUIDisplayError(ERROR_ADDING_CODEPAGE, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
- /* Set the default pagefile entry */
- SetDefaultPagefile(DestinationDriveLetter);
+ /* Set the default pagefile entry */
+ SetDefaultPagefile(DestinationDriveLetter);
- /* Update the mounted devices list */
- // FIXME: This should technically be done by mountmgr (if AutoMount is enabled)!
- SetMountedDeviceValues(PartitionList);
+ /* Update the mounted devices list */
+ // FIXME: This should technically be done by mountmgr (if AutoMount is enabled)!
+ SetMountedDeviceValues(PartitionList);
+ }
Cleanup:
//
@@ -4226,7 +4261,18 @@ Cleanup:
//
RegCleanupRegistry(&DestinationPath);
-Quit:
+ /*
+ * Check whether we were in update/repair mode but we were actually
+ * repairing the registry hives. If so, we have finished repairing them,
+ * and we now reset the flag and run the proper registry update.
+ * Otherwise we have finished the registry update!
+ */
+ if (RepairUpdateFlag && ShouldRepairRegistry)
+ {
+ ShouldRepairRegistry = FALSE;
+ goto DoUpdate;
+ }
+
if (NT_SUCCESS(Status))
{
CONSOLE_SetStatusText(MUIGetString(STRING_DONE));
diff --git a/boot/bootdata/txtsetup.sif b/boot/bootdata/txtsetup.sif
index ba2db1012e..f7f44d8f9b 100644
--- a/boot/bootdata/txtsetup.sif
+++ b/boot/bootdata/txtsetup.sif
@@ -524,7 +524,12 @@ Default = "XT-, AT- or extended keyboard (83-105 keys)"
0000048F = kbdeo.dll
[HiveInfs.Install]
-AddReg=caroots.inf,AddReg
-AddReg=registry.inf,AddReg
+; Called "HiveInfs.Fresh" on Windows
+AddReg = caroots.inf,AddReg
+AddReg = registry.inf,AddReg
+
+[HiveInfs.Upgrade]
+DelReg = registry.inf,DelReg
+AddReg = registry.inf,AddReg
; EOF