From 7fedeb7db334962cad79de12f25a448982cb43f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Thu, 22 Jun 2017 00:38:32 +0000 Subject: [PATCH] [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 | 184 ++++++++++++++++++++++------------- boot/bootdata/txtsetup.sif | 9 +- 4 files changed, 194 insertions(+), 103 deletions(-) diff --git a/base/setup/usetup/registry.c b/base/setup/usetup/registry.c index bb79689789c..50fbb31d1d9 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; + } - RtlInitUnicodeString(&KeyName, RegistryHives[i].HiveRegistryPath); - Status = NtUnloadKey(&KeyObjectAttributes); - DPRINT1("Unmounting '%S' %s\n", RegistryHives[i].HiveRegistryPath, NT_SUCCESS(Status) ? "succeeded" : "failed"); + 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; + } } // @@ -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 cae50e8271e..0548061a35e 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 80d6345aa2e..a8e72676d30 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 (!SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL, &InfContext)) + if (!RepairUpdateFlag || ShouldRepairRegistry) { - DPRINT1("SetupFindFirstLine() failed\n"); - MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER); - goto Cleanup; + /* + * 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.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,63 +4192,68 @@ 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; - } - - /* 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)) + /* Update display registry settings */ + CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE)); + if (!ProcessDisplayRegistry(SetupInf, DisplayList)) { - MUIDisplayError(ERROR_UPDATE_KBSETTINGS, Ir, POPUP_WAIT_ENTER); + 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); + 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); } - /* 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: // // TODO: Unload all the registry stuff, perform 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 ba2db1012e3..f7f44d8f9b5 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