Author: hbelusca
Date: Thu Jun 22 00:38:32 2017
New Revision: 75162
URL:
http://svn.reactos.org/svn/reactos?rev=75162&view=rev
Log:
[USETUP]: Experiment more with updating/repairing the registry.
Currently partly blocked by CORE-13448.
Modified:
branches/setup_improvements/base/setup/usetup/interface/usetup.c
branches/setup_improvements/base/setup/usetup/registry.c
branches/setup_improvements/base/setup/usetup/registry.h
Modified: branches/setup_improvements/base/setup/usetup/interface/usetup.c
URL:
http://svn.reactos.org/svn/reactos/branches/setup_improvements/base/setup/u…
==============================================================================
--- branches/setup_improvements/base/setup/usetup/interface/usetup.c [iso-8859-1]
(original)
+++ branches/setup_improvements/base/setup/usetup/interface/usetup.c [iso-8859-1] Thu Jun
22 00:38:32 2017
@@ -4055,32 +4055,32 @@
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;
- }
- }
-
- /* Initialize the registry and setup the default installation hives */
+ ShouldRepairRegistry = FALSE;
+ }
+ if (!ShouldRepairRegistry)
+ DPRINT1("No need to repair the registry\n");
+ }
+
+DoUpdate:
+ /* Update the registry */
+ CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE));
+
+ /* Initialize the registry and setup the registry hives */
Status = RegInitializeRegistry(&DestinationPath);
if (!NT_SUCCESS(Status))
{
@@ -4100,14 +4100,41 @@
return QUIT_PAGE;
}
- /* Update registry */
- CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE));
-
- if (!SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL,
&InfContext))
- {
- DPRINT1("SetupFindFirstLine() failed\n");
- MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER);
- goto Cleanup;
+ 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 (!Success)
+ {
+ DPRINT1("SetupFindFirstLine() failed\n");
+ MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
+ }
+ else // if (RepairUpdateFlag && !ShouldRepairRegistry)
+ {
+ /*
+ * 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.Update", NULL,
&InfContext);
+ if (!Success)
+ {
+ /* Nothing to do for update! */
+ DPRINT1("No update needed for the registry!\n");
+ goto Cleanup;
+ }
}
do
@@ -4126,7 +4153,10 @@
else if (!_wcsicmp(Action, L"DelReg"))
Delete = TRUE;
else
+ {
+ DPRINT1("Unrecognized registry INF action '%S'\n",
Action);
continue;
+ }
CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE), File);
@@ -4138,62 +4168,67 @@
}
} while (SetupFindNextLine(&InfContext, &InfContext));
- /* Update display registry settings */
- CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE));
- if (!ProcessDisplayRegistry(SetupInf, DisplayList))
- {
- MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS, 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;
- }
-
- /* Add keyboard layouts */
- CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS));
- if (!AddKeyboardLayouts())
- {
- MUIDisplayError(ERROR_ADDING_KBLAYOUTS, Ir, POPUP_WAIT_ENTER);
- goto Cleanup;
- }
-
- /* Set GeoID */
- if (!SetGeoID(MUIGetGeoID()))
- {
- MUIDisplayError(ERROR_UPDATE_GEOID, 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);
+ if (!RepairUpdateFlag || ShouldRepairRegistry)
+ {
+ /* See the explanation for this test above */
+
+ /* 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 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);
-
- /* Update the mounted devices list */
- // FIXME: This should technically be done by mountmgr (if AutoMount is enabled)!
- SetMountedDeviceValues(PartitionList);
+
+ /* Set the locale */
+ CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE));
+ if (!ProcessLocaleRegistry(LanguageList))
+ {
+ MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS, 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 GeoID */
+ if (!SetGeoID(MUIGetGeoID()))
+ {
+ MUIDisplayError(ERROR_UPDATE_GEOID, 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);
+
+ /* Update the mounted devices list */
+ // FIXME: This should technically be done by mountmgr (if AutoMount is enabled)!
+ SetMountedDeviceValues(PartitionList);
+ }
Cleanup:
//
@@ -4202,7 +4237,18 @@
//
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));
Modified: branches/setup_improvements/base/setup/usetup/registry.c
URL:
http://svn.reactos.org/svn/reactos/branches/setup_improvements/base/setup/u…
==============================================================================
--- branches/setup_improvements/base/setup/usetup/registry.c [iso-8859-1] (original)
+++ branches/setup_improvements/base/setup/usetup/registry.c [iso-8859-1] Thu Jun 22
00:38:32 2017
@@ -749,7 +749,7 @@
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
OBJ_CASE_INSENSITIVE,
- NULL, // Could have been installpath, etc...
+ NULL, // Could have been InstallPath, etc...
NULL); // Descriptor
Status = NtCreateFile(&FileHandle,
@@ -901,7 +901,7 @@
{
NTSTATUS Status;
UNICODE_STRING KeyName;
- OBJECT_ATTRIBUTES KeyObjectAttributes;
+ OBJECT_ATTRIBUTES ObjectAttributes;
/* Try to mount the specified registry hive */
Status = ConnectRegistry(NULL,
@@ -936,14 +936,14 @@
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);
@@ -997,14 +997,14 @@
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]);
@@ -1032,7 +1032,7 @@
{
DPRINT1("Registry hive '%S' needs repair!\n",
RegistryHives[i].HiveName);
RegistryHives[i].State = Repair;
- *ShouldUpdateRegistry = TRUE;
+ *ShouldRepairRegistry = TRUE;
}
else
{
@@ -1144,14 +1144,14 @@
{
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);
@@ -1237,7 +1237,7 @@
}
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,
@@ -1384,23 +1384,14 @@
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))
@@ -1420,20 +1411,68 @@
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].HiveRegistryPath);
- Status = NtUnloadKey(&KeyObjectAttributes);
- DPRINT1("Unmounting '%S' %s\n",
RegistryHives[i].HiveRegistryPath, NT_SUCCESS(Status) ? "succeeded" :
"failed");
+ {
+ 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;
+ }
}
//
@@ -1463,6 +1502,7 @@
RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE,
&PrivilegeSet[1]);
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
}
+
VOID
SetDefaultPagefile(
Modified: branches/setup_improvements/base/setup/usetup/registry.h
URL:
http://svn.reactos.org/svn/reactos/branches/setup_improvements/base/setup/u…
==============================================================================
--- branches/setup_improvements/base/setup/usetup/registry.h [iso-8859-1] (original)
+++ branches/setup_improvements/base/setup/usetup/registry.h [iso-8859-1] Thu Jun 22
00:38:32 2017
@@ -46,7 +46,7 @@
NTSTATUS
VerifyRegistryHives(
IN PUNICODE_STRING InstallPath,
- OUT PBOOLEAN ShouldUpdateRegistry);
+ OUT PBOOLEAN ShouldRepairRegistry);
NTSTATUS
RegInitializeRegistry(