https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7fedeb7db334962cad79de...
commit 7fedeb7db334962cad79de12f25a448982cb43f3 Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Thu Jun 22 00:38:32 2017 +0000 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@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