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/us... ============================================================================== --- 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/us... ============================================================================== --- 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/us... ============================================================================== --- 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(