[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
This commit is contained in:
Hermès Bélusca-Maïto 2017-06-22 00:38:32 +00:00
parent b20908acc8
commit 7fedeb7db3
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
4 changed files with 194 additions and 103 deletions

View file

@ -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)

View file

@ -46,7 +46,7 @@ ImportRegistryFile(
NTSTATUS
VerifyRegistryHives(
IN PUNICODE_STRING InstallPath,
OUT PBOOLEAN ShouldUpdateRegistry);
OUT PBOOLEAN ShouldRepairRegistry);
NTSTATUS
RegInitializeRegistry(

View file

@ -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));

View file

@ -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