diff --git a/base/setup/usetup/mui.c b/base/setup/usetup/mui.c index 0ddbdfebbb9..a983f0f47a1 100644 --- a/base/setup/usetup/mui.c +++ b/base/setup/usetup/mui.c @@ -297,11 +297,11 @@ AddHotkeySettings( NTSTATUS Status; RtlInitUnicodeString(&KeyName, - L"\\Registry\\User\\.DEFAULT\\Keyboard Layout\\Toggle"); + L".DEFAULT\\Keyboard Layout\\Toggle"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - NULL, + GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&KeyHandle, @@ -384,17 +384,16 @@ AddKbLayoutsToRegistry( ULONG Disposition; ULONG uIndex = 0; ULONG uCount = 0; - WCHAR szKeyName[48] = L"\\Registry\\User\\.DEFAULT\\Keyboard Layout"; + WCHAR szKeyName[48] = L".DEFAULT\\Keyboard Layout"; WCHAR szValueName[3 + 1]; WCHAR szLangID[8 + 1]; // Open the keyboard layout key - RtlInitUnicodeString(&KeyName, - szKeyName); + RtlInitUnicodeString(&KeyName, szKeyName); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - NULL, + GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&KeyHandle, @@ -416,7 +415,7 @@ AddKbLayoutsToRegistry( KeyName.MaximumLength = sizeof(szKeyName); Status = RtlAppendUnicodeToString(&KeyName, L"\\Preload"); - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { DPRINT1("RtlAppend failed! (%lx)\n", Status); DPRINT1("String is %wZ\n", &KeyName); @@ -426,7 +425,7 @@ AddKbLayoutsToRegistry( InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - NULL, + GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&KeyHandle, @@ -443,11 +442,11 @@ AddKbLayoutsToRegistry( return FALSE; } - RtlInitUnicodeString(&KeyName, L"\\Registry\\User\\.DEFAULT\\Keyboard Layout\\Substitutes"); + RtlInitUnicodeString(&KeyName, L".DEFAULT\\Keyboard Layout\\Substitutes"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - NULL, + GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&SubKeyHandle, @@ -577,15 +576,15 @@ AddCodepageToRegistry( // Open the nls codepage key RtlInitUnicodeString(&KeyName, - L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage"); + L"SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - NULL, + GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL), NULL); - Status = NtOpenKey(&KeyHandle, - KEY_WRITE, - &ObjectAttributes); + Status = NtOpenKey(&KeyHandle, + KEY_WRITE, + &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); @@ -656,15 +655,15 @@ AddFontsSettingsToRegistry( ULONG uIndex = 0; RtlInitUnicodeString(&KeyName, - L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes"); + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - NULL, + GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL), NULL); - Status = NtOpenKey(&KeyHandle, - KEY_WRITE, - &ObjectAttributes); + Status = NtOpenKey(&KeyHandle, + KEY_WRITE, + &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); diff --git a/base/setup/usetup/registry.c b/base/setup/usetup/registry.c index fc9b127358f..7fda1c928c5 100644 --- a/base/setup/usetup/registry.c +++ b/base/setup/usetup/registry.c @@ -59,41 +59,66 @@ /* FUNCTIONS ****************************************************************/ -static -BOOLEAN -GetRootKey( - PWCHAR Name) +typedef struct _ROOT_KEY { - if (!_wcsicmp (Name, L"HKCR")) - { - wcscpy (Name, L"\\Registry\\Machine\\SOFTWARE\\Classes\\"); - return TRUE; - } - - if (!_wcsicmp (Name, L"HKCU")) - { - wcscpy (Name, L"\\Registry\\User\\.DEFAULT\\"); - return TRUE; - } - - if (!_wcsicmp (Name, L"HKLM")) - { - wcscpy (Name, L"\\Registry\\Machine\\"); - return TRUE; - } - - if (!_wcsicmp (Name, L"HKU")) - { - wcscpy (Name, L"\\Registry\\User\\"); - return TRUE; - } + PCWSTR Name; + PCWSTR MountPoint; + HANDLE Handle; +} ROOT_KEY, *PROOT_KEY; +ROOT_KEY RootKeys[] = +{ + // L"\\Registry\\Machine\\SYSTEM\\USetup_Machine\\SOFTWARE\\Classes\\" + { L"HKCR", L"\\Registry\\Machine\\USetup_SOFTWARE\\Classes\\", NULL }, /* "\\Registry\\Machine\\SOFTWARE\\Classes\\" */ // HKEY_CLASSES_ROOT + { L"HKCU", L"\\Registry\\User\\USetup_DEFAULT\\" , NULL }, /* "\\Registry\\User\\.DEFAULT\\" */ // HKEY_CURRENT_USER + { L"HKLM", L"\\Registry\\Machine\\SYSTEM\\USetup_Machine\\" , NULL }, /* "\\Registry\\Machine\\" */ // HKEY_LOCAL_MACHINE + { L"HKU" , L"\\Registry\\Machine\\SYSTEM\\USetup_User\\" , NULL }, /* "\\Registry\\User\\" */ // HKEY_USERS #if 0 - if (!_wcsicmp (Name, L"HKR")) - return FALSE; + { L"HKR", NULL, NULL }, #endif +}; - return FALSE; +#define IsPredefKey(HKey) \ + (((ULONG_PTR)(HKey) & 0xF0000000) == 0x80000000) + +#define GetPredefKeyIndex(HKey) \ + ((ULONG_PTR)(HKey) & 0x0FFFFFFF) + +HANDLE +GetRootKeyByPredefKey( + IN HANDLE KeyHandle, + OUT PCWSTR* RootKeyMountPoint OPTIONAL) +{ + ULONG_PTR Index = GetPredefKeyIndex(KeyHandle); + + if (!IsPredefKey(KeyHandle)) + return NULL; + if (GetPredefKeyIndex(KeyHandle) >= ARRAYSIZE(RootKeys)) + return NULL; + + if (RootKeyMountPoint) + *RootKeyMountPoint = RootKeys[Index].MountPoint; + return RootKeys[Index].Handle; +} + +HANDLE +GetRootKeyByName( + IN PCWSTR RootKeyName, + OUT PCWSTR* RootKeyMountPoint OPTIONAL) +{ + UCHAR i; + + for (i = 0; i < ARRAYSIZE(RootKeys); ++i) + { + if (!_wcsicmp(RootKeyName, RootKeys[i].Name)) + { + if (RootKeyMountPoint) + *RootKeyMountPoint = RootKeys[i].MountPoint; + return RootKeys[i].Handle; + } + } + + return NULL; } @@ -481,11 +506,11 @@ registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete) UNICODE_STRING Name, Value; PUNICODE_STRING ValuePtr; UINT Flags; - ULONG Length; WCHAR Buffer[MAX_INF_STRING_LENGTH]; INFCONTEXT Context; - HANDLE KeyHandle; + PCWSTR RootKeyName; + HANDLE RootKeyHandle, KeyHandle; BOOLEAN Ok; Ok = SetupFindFirstLineW(hInf, Section, NULL, &Context); @@ -497,15 +522,15 @@ registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete) /* get root */ if (!SetupGetStringFieldW(&Context, 1, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL)) continue; - if (!GetRootKey (Buffer)) + RootKeyHandle = GetRootKeyByName(Buffer, &RootKeyName); + if (!RootKeyHandle) continue; /* get key */ - Length = wcslen(Buffer); - if (!SetupGetStringFieldW(&Context, 2, Buffer + Length, sizeof(Buffer)/sizeof(WCHAR) - Length, NULL)) + if (!SetupGetStringFieldW(&Context, 2, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL)) *Buffer = 0; - DPRINT("KeyName: <%S>\n", Buffer); + DPRINT("KeyName: <%S\\%S>\n", RootKeyName, Buffer); /* get flags */ if (!SetupGetIntField(&Context, 4, (PINT)&Flags)) @@ -517,7 +542,7 @@ registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete) InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, - NULL, + RootKeyHandle, NULL); if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) @@ -621,13 +646,611 @@ ImportRegistryFile( return TRUE; } +/* + * Should be called under privileges + */ +// static +NTSTATUS +CreateRegistryFile( + IN PUNICODE_STRING InstallPath, + IN PCWSTR RegistryKey, + IN HANDLE ProtoKeyHandle) +{ + NTSTATUS Status; + HANDLE FileHandle; + UNICODE_STRING FileName; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + WCHAR PathBuffer[MAX_PATH]; + + /* Create the file */ + CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3, + InstallPath->Buffer, L"System32\\config", RegistryKey); + RtlInitUnicodeString(&FileName, PathBuffer); + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, // Could have been installpath, etc... + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_GENERIC_WRITE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName, Status); + return Status; + } + + /* Save the selected hive into the file */ + Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName, Status); + } + + /* Close the file and return */ + NtClose(FileHandle); + return Status; +} + +static BOOLEAN +CmpLinkKeyToHive( + IN HANDLE RootLinkKeyHandle OPTIONAL, + IN PCWSTR LinkKeyName, + IN PCWSTR TargetKeyName) +{ + static UNICODE_STRING CmSymbolicLinkValueName = + RTL_CONSTANT_STRING(L"SymbolicLinkValue"); + + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + HANDLE TargetKeyHandle; + ULONG Disposition; + + /* Initialize the object attributes */ + RtlInitUnicodeString(&KeyName, LinkKeyName); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootLinkKeyHandle, + NULL); + + /* Create the link key */ + Status = NtCreateKey(&TargetKeyHandle, + KEY_SET_VALUE | KEY_CREATE_LINK, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmpLinkKeyToHive: couldn't create %S, Status = 0x%08lx\n", + LinkKeyName, Status); + return FALSE; + } + + /* Check if the new key was actually created */ + if (Disposition != REG_CREATED_NEW_KEY) + { + DPRINT1("CmpLinkKeyToHive: %S already exists!\n", LinkKeyName); + NtClose(TargetKeyHandle); + return FALSE; + } + + /* Set the target key name as link target */ + RtlInitUnicodeString(&KeyName, TargetKeyName); + Status = NtSetValueKey(TargetKeyHandle, + &CmSymbolicLinkValueName, + 0, + REG_LINK, + KeyName.Buffer, + KeyName.Length); + + /* Close the link key handle */ + NtClose(TargetKeyHandle); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmpLinkKeyToHive: couldn't create symbolic link for %S, Status = 0x%08lx\n", + TargetKeyName, Status); + return FALSE; + } + + return TRUE; +} + +/* + * Should be called under privileges + */ +// static +NTSTATUS +ConnectRegistry( + IN HKEY RootKey OPTIONAL, + // IN HANDLE RootDirectory OPTIONAL, + IN PUNICODE_STRING InstallPath, + IN PCWSTR RegistryKey, + // IN PUCHAR Descriptor, + // IN ULONG DescriptorLength, + IN PCWSTR RegMountPoint) +{ + NTSTATUS Status; + UNICODE_STRING KeyName, FileName; + OBJECT_ATTRIBUTES KeyObjectAttributes; + OBJECT_ATTRIBUTES FileObjectAttributes; + WCHAR PathBuffer[MAX_PATH]; + + RtlInitUnicodeString(&KeyName, RegMountPoint); + InitializeObjectAttributes(&KeyObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootKey, + NULL); + + CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3, + InstallPath->Buffer, L"System32\\config", RegistryKey); + RtlInitUnicodeString(&FileName, PathBuffer); + InitializeObjectAttributes(&FileObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, // RootDirectory, + NULL); + +#if 0 + IN PCMHIVE HiveToConnect; + /* + * Add security to the root key. + * NOTE: One can implement this using the lpSecurityAttributes + * parameter of RegCreateKeyExW. + */ + Status = CmiCreateSecurityKey(&HiveToConnect->Hive, + HiveToConnect->Hive.BaseBlock->RootCell, + Descriptor, DescriptorLength); + if (!NT_SUCCESS(Status)) + DPRINT1("Failed to add security for root key '%S'\n", Path); +#endif + + /* Mount the registry hive in the registry namespace */ + Status = NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes); + + return Status; +} + +NTSTATUS +RegInitializeRegistry( + IN PUNICODE_STRING InstallPath) +{ + NTSTATUS Status; + HANDLE KeyHandle; + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + BOOLEAN PrivilegeSet[2] = {FALSE, FALSE}; + ULONG Disposition; + UINT i; + PCWSTR RegistryKeys[] = + { + L"SYSTEM", + L"SOFTWARE", + L"DEFAULT", // L".DEFAULT", + // L"SAM", + // L"SECURITY", + // L"BCD00000000", + }; + +#if 0 + /* Initialize the current session registry */ + Status = NtInitializeRegistry(CM_BOOT_FLAG_SETUP); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status); + return Status; + } +#endif + + /* Acquire restore privilege */ + Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[0]); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status); + /* Exit prematurely here.... */ + return Status; + } + + /* Acquire backup privilege */ + Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status); + RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); + /* Exit prematurely here.... */ + return Status; + } + + /* + * Create the template proto-hive. + * + * Use a dummy root key name: + * - On 2k/XP/2k3, this is "$$$PROTO.HIV" + * - On Vista+, this is "CMI-CreateHive{guid}" + * See https://github.com/libyal/winreg-kb/blob/master/documentation/Registry%20files.asciidoc + * for more information. + */ + RtlInitUnicodeString(&KeyName, + L"\\Registry\\Machine\\SYSTEM\\$$$PROTO.HIV"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtCreateKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateKey() failed to create the proto-hive (Status %lx)\n", Status); + goto Quit; + } + NtFlushKey(KeyHandle); + + for (i = 0; i < ARRAYSIZE(RegistryKeys); ++i) + { + Status = CreateRegistryFile(InstallPath, + RegistryKeys[i], + KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateRegistryFile(%S) failed, Status 0x%08lx\n", RegistryKeys[i], Status); + /* Exit prematurely here.... */ + /* That is now done, clean everything up! */ + NtDeleteKey(KeyHandle); + NtClose(KeyHandle); + goto Quit; + } + } + + /* That is now done, clean everything up! */ + NtDeleteKey(KeyHandle); + NtClose(KeyHandle); + + + /* + * Prepare the installation roots. Since we cannot create real registry keys + * inside the master keys (\Registry, \Registry\Machine or \Registry\User), + * we need to perform some SymLink tricks instead. + */ + + /* Our offline HKLM '\Registry\Machine' is inside '\Registry\Machine\SYSTEM\USetup_Machine' */ + RtlInitUnicodeString(&KeyName, RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].MountPoint); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + KeyHandle = NULL; + Status = NtCreateKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName, Status); + // return Status; + } + RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle = KeyHandle; + + /* Our offline HKU '\Registry\User' is inside '\Registry\Machine\SYSTEM\USetup_User' */ + RtlInitUnicodeString(&KeyName, RootKeys[GetPredefKeyIndex(HKEY_USERS)].MountPoint); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + KeyHandle = NULL; + Status = NtCreateKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName, Status); + // return Status; + } + RootKeys[GetPredefKeyIndex(HKEY_USERS)].Handle = KeyHandle; + + + + /* + * Now properly mount the offline hive files + */ + + /* Create SYSTEM key */ + Status = + ConnectRegistry(NULL, + InstallPath, + RegistryKeys[0], + // SystemSecurity, sizeof(SystemSecurity), + L"\\Registry\\Machine\\USetup_SYSTEM"); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ConnectRegistry(SYSTEM) failed, Status 0x%08lx\n", Status); + } + + /* Create the 'HKLM\SYSTEM' symlink to this key */ + if (!CmpLinkKeyToHive(RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, + L"SYSTEM", + L"\\Registry\\Machine\\USetup_SYSTEM")) + { + DPRINT1("CmpLinkKeyToHive(SYSTEM) failed!\n"); + } + + + /* Create SOFTWARE key */ + Status = + ConnectRegistry(NULL, + InstallPath, + RegistryKeys[1], + // SoftwareSecurity, sizeof(SoftwareSecurity), + L"\\Registry\\Machine\\USetup_SOFTWARE"); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ConnectRegistry(SOFTWARE) failed, Status 0x%08lx\n", Status); + } + + /* Create the 'HKLM\Software' symlink to this key */ + if (!CmpLinkKeyToHive(RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, + L"Software", + L"\\Registry\\Machine\\USetup_SOFTWARE")) + { + DPRINT1("CmpLinkKeyToHive(SOFTWARE) failed!\n"); + } + + + /* Create DEFAULT key */ + Status = + ConnectRegistry(NULL, + InstallPath, + RegistryKeys[2], + // SystemSecurity, sizeof(SystemSecurity), + L"\\Registry\\User\\USetup_DEFAULT"); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ConnectRegistry(DEFAULT) failed, Status 0x%08lx\n", Status); + } + + /* Create the 'HKU\.DEFAULT' symlink to this key */ + if (!CmpLinkKeyToHive(RootKeys[GetPredefKeyIndex(HKEY_USERS)].Handle, + L".DEFAULT", + L"\\Registry\\User\\USetup_DEFAULT")) + { + DPRINT1("CmpLinkKeyToHive(DEFAULT) failed!\n"); + } + + /* HKCU is a handle to 'HKU\.DEFAULT' */ +#if 0 + RtlInitUnicodeString(&KeyName, L".DEFAULT"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootKeys[GetPredefKeyIndex(HKEY_USERS)].Handle, + NULL); +#else + RtlInitUnicodeString(&KeyName, RootKeys[GetPredefKeyIndex(HKEY_CURRENT_USER)].MountPoint); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); +#endif + KeyHandle = NULL; + Status = NtOpenKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenKey(%wZ) failed (Status %lx)\n", &KeyName, Status); + } + RootKeys[GetPredefKeyIndex(HKEY_CURRENT_USER)].Handle = KeyHandle; + + + /* HKCR is a handle to 'HKLM\Software\Classes' */ +#if 0 + RtlInitUnicodeString(&KeyName, L"Software\\Classes"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, + NULL); +#else + RtlInitUnicodeString(&KeyName, RootKeys[GetPredefKeyIndex(HKEY_CLASSES_ROOT)].MountPoint); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); +#endif + KeyHandle = NULL; + Status = NtCreateKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + 0, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateKey(%wZ) failed (Status %lx)\n", &KeyName, Status); + } + else + { + DPRINT1("NtCreateKey() succeeded to %s the %wZ key (Status %lx)\n", + Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open", + &KeyName, Status); + } + RootKeys[GetPredefKeyIndex(HKEY_CLASSES_ROOT)].Handle = KeyHandle; + + +#if 0 + /* Create SAM key */ + ConnectRegistry(NULL, + &SamHive, + // SystemSecurity, sizeof(SystemSecurity), + L"\\Registry\\Machine\\USetup_SAM"); + + /* Create SECURITY key */ + ConnectRegistry(NULL, + &SecurityHive, + // NULL, 0, + L"\\Registry\\Machine\\USetup_SECURITY"); + + /* Create BCD key */ + ConnectRegistry(NULL, + &BcdHive, + // BcdSecurity, sizeof(BcdSecurity), + L"\\Registry\\Machine\\USetup_BCD00000000"); +#endif + + Status = STATUS_SUCCESS; + + + /* Create the 'HKLM\SYSTEM\ControlSet001' key */ + // L"\\Registry\\Machine\\SYSTEM\\USetup_Machine\\SYSTEM\\ControlSet001" + RtlInitUnicodeString(&KeyName, L"SYSTEM\\ControlSet001"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, + NULL); + Status = NtCreateKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateKey() failed to create the ControlSet001 key (Status %lx)\n", Status); + // return Status; + } + else + { + DPRINT1("NtCreateKey() succeeded to %s the ControlSet001 key (Status %lx)\n", + Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open", + Status); + } + NtClose(KeyHandle); + + /* Create the 'HKLM\SYSTEM\CurrentControlSet' symlink */ + if (!CmpLinkKeyToHive(RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, + L"SYSTEM\\CurrentControlSet", + L"\\Registry\\Machine\\SYSTEM\\USetup_Machine\\SYSTEM\\ControlSet001")) + { + DPRINT1("CmpLinkKeyToHive(CurrentControlSet) failed!\n"); + } + + +Quit: + /* Remove restore and backup privileges */ + RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]); + RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); + + return Status; +} + +VOID +RegCleanupRegistry(VOID) +{ + NTSTATUS Status; + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES KeyObjectAttributes; + BOOLEAN PrivilegeSet[2] = {FALSE, FALSE}; + UCHAR i; + + for (i = 0; i < ARRAYSIZE(RootKeys); ++i) + { + if (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)) + { + DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status); + /* Exit prematurely here.... */ + return; + } + + /* Acquire backup privilege */ + Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status); + RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); + /* Exit prematurely here.... */ + return; + } + + InitializeObjectAttributes(&KeyObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\USetup_SYSTEM"); + Status = NtUnloadKey(&KeyObjectAttributes); + + RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\USetup_SOFTWARE"); + Status = NtUnloadKey(&KeyObjectAttributes); + + RtlInitUnicodeString(&KeyName, L"\\Registry\\User\\USetup_DEFAULT"); + Status = NtUnloadKey(&KeyObjectAttributes); + +#if 0 + RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\USetup_SAM"); + Status = NtUnloadKey(&KeyObjectAttributes); + + RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\USetup_SECURITY"); + Status = NtUnloadKey(&KeyObjectAttributes); + + RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\USetup_BCD00000000"); + Status = NtUnloadKey(&KeyObjectAttributes); +#endif + + /* Remove restore and backup privileges */ + RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]); + RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); +} VOID SetDefaultPagefile( WCHAR Drive) { OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"); + UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"); UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"PagingFiles"); WCHAR ValueBuffer[] = L"?:\\pagefile.sys 0 0\0"; HANDLE KeyHandle; @@ -636,7 +1259,7 @@ SetDefaultPagefile( InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - NULL, + RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, NULL); Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, diff --git a/base/setup/usetup/registry.h b/base/setup/usetup/registry.h index 5064bb97f3e..c97d897a78f 100644 --- a/base/setup/usetup/registry.h +++ b/base/setup/usetup/registry.h @@ -26,6 +26,16 @@ #pragma once +HANDLE +GetRootKeyByPredefKey( + IN HANDLE KeyHandle, + OUT PCWSTR* RootKeyMountPoint OPTIONAL); + +HANDLE +GetRootKeyByName( + IN PCWSTR RootKeyName, + OUT PCWSTR* RootKeyMountPoint OPTIONAL); + BOOLEAN ImportRegistryFile( PWSTR Filename, @@ -33,9 +43,12 @@ ImportRegistryFile( LCID LocaleId, BOOLEAN Delete); -BOOLEAN -SetInstallPathValue( - PUNICODE_STRING InstallPath); +NTSTATUS +RegInitializeRegistry( + IN PUNICODE_STRING InstallPath); + +VOID +RegCleanupRegistry(VOID); VOID SetDefaultPagefile( diff --git a/base/setup/usetup/settings.c b/base/setup/usetup/settings.c index a6dc2ed0fb2..d358f85e391 100644 --- a/base/setup/usetup/settings.c +++ b/base/setup/usetup/settings.c @@ -214,7 +214,7 @@ GetComputerIdentifier( NULL); Status = NtOpenKey(&ProcessorsKey, - KEY_QUERY_VALUE , + KEY_QUERY_VALUE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { @@ -676,14 +676,17 @@ ProcessDisplayRegistry( HINF InfFile, PGENERIC_LIST List) { + NTSTATUS Status; PGENERIC_LIST_ENTRY Entry; INFCONTEXT Context; + PWCHAR Buffer; PWCHAR ServiceName; ULONG StartValue; - NTSTATUS Status; - WCHAR RegPath [255]; - PWCHAR Buffer; ULONG Width, Height, Bpp; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + HANDLE KeyHandle; + WCHAR RegPath[255]; DPRINT("ProcessDisplayRegistry() called\n"); @@ -700,7 +703,7 @@ ProcessDisplayRegistry( return FALSE; } - /* Enable the right driver */ + /* Enable the correct driver */ if (!INF_GetDataField(&Context, 3, &ServiceName)) { DPRINT1("INF_GetDataField() failed\n"); @@ -708,15 +711,31 @@ ProcessDisplayRegistry( } ASSERT(wcslen(ServiceName) < 10); - DPRINT("Service name: %S\n", ServiceName); + DPRINT1("Service name: '%S'\n", ServiceName); + + swprintf(RegPath, L"System\\CurrentControlSet\\Services\\%s", ServiceName); + RtlInitUnicodeString(&KeyName, RegPath); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL), + NULL); + Status = NtOpenKey(&KeyHandle, + KEY_SET_VALUE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); + return FALSE; + } StartValue = 1; - Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES, - ServiceName, + Status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE, KeyHandle, L"Start", REG_DWORD, &StartValue, - sizeof(ULONG)); + sizeof(StartValue)); + NtClose(KeyHandle); if (!NT_SUCCESS(Status)) { DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status); @@ -724,7 +743,6 @@ ProcessDisplayRegistry( } /* Set the resolution */ - swprintf(RegPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", ServiceName); if (!INF_GetDataField(&Context, 4, &Buffer)) { @@ -732,57 +750,80 @@ ProcessDisplayRegistry( return FALSE; } + swprintf(RegPath, + L"System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", + ServiceName); + DPRINT1("RegPath: '%S'\n", RegPath); + RtlInitUnicodeString(&KeyName, RegPath); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL), + NULL); + Status = NtOpenKey(&KeyHandle, + KEY_SET_VALUE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); + return FALSE; + } + Width = wcstoul(Buffer, NULL, 10); - Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, - RegPath, + Status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE, KeyHandle, L"DefaultSettings.XResolution", REG_DWORD, &Width, - sizeof(ULONG)); + sizeof(Width)); if (!NT_SUCCESS(Status)) { DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status); + NtClose(KeyHandle); return FALSE; } if (!INF_GetDataField(&Context, 5, &Buffer)) { DPRINT1("INF_GetDataField() failed\n"); + NtClose(KeyHandle); return FALSE; } Height = wcstoul(Buffer, 0, 0); - Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, - RegPath, + Status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE, KeyHandle, L"DefaultSettings.YResolution", REG_DWORD, &Height, - sizeof(ULONG)); + sizeof(Height)); if (!NT_SUCCESS(Status)) { DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status); + NtClose(KeyHandle); return FALSE; } if (!INF_GetDataField(&Context, 6, &Buffer)) { DPRINT1("INF_GetDataField() failed\n"); + NtClose(KeyHandle); return FALSE; } Bpp = wcstoul(Buffer, 0, 0); - Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, - RegPath, + Status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE, KeyHandle, L"DefaultSettings.BitsPerPel", REG_DWORD, &Bpp, - sizeof(ULONG)); + sizeof(Bpp)); if (!NT_SUCCESS(Status)) { DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status); + NtClose(KeyHandle); return FALSE; } + NtClose(KeyHandle); + DPRINT("ProcessDisplayRegistry() done\n"); return TRUE; @@ -814,17 +855,17 @@ ProcessLocaleRegistry( /* Open the default users locale key */ RtlInitUnicodeString(&KeyName, - L"\\Registry\\User\\.DEFAULT\\Control Panel\\International"); + L".DEFAULT\\Control Panel\\International"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - NULL, + GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); - Status = NtOpenKey(&KeyHandle, - KEY_SET_VALUE, - &ObjectAttributes); + Status = NtOpenKey(&KeyHandle, + KEY_SET_VALUE, + &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); @@ -832,8 +873,7 @@ ProcessLocaleRegistry( } /* Set default user locale */ - RtlInitUnicodeString(&ValueName, - L"Locale"); + RtlInitUnicodeString(&ValueName, L"Locale"); Status = NtSetValueKey(KeyHandle, &ValueName, 0, @@ -853,17 +893,17 @@ ProcessLocaleRegistry( /* Open the NLS language key */ RtlInitUnicodeString(&KeyName, - L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language"); + L"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - NULL, + GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL), NULL); - Status = NtOpenKey(&KeyHandle, - KEY_SET_VALUE, - &ObjectAttributes); + Status = NtOpenKey(&KeyHandle, + KEY_SET_VALUE, + &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); @@ -871,8 +911,7 @@ ProcessLocaleRegistry( } /* Set default language */ - RtlInitUnicodeString(&ValueName, - L"Default"); + RtlInitUnicodeString(&ValueName, L"Default"); Status = NtSetValueKey(KeyHandle, &ValueName, 0, @@ -887,14 +926,13 @@ ProcessLocaleRegistry( } /* Set install language */ - RtlInitUnicodeString(&ValueName, - L"InstallLanguage"); - Status = NtSetValueKey (KeyHandle, - &ValueName, - 0, - REG_SZ, - (PVOID)LanguageId, - (wcslen(LanguageId) + 1) * sizeof(WCHAR)); + RtlInitUnicodeString(&ValueName, L"InstallLanguage"); + Status = NtSetValueKey(KeyHandle, + &ValueName, + 0, + REG_SZ, + (PVOID)LanguageId, + (wcslen(LanguageId) + 1) * sizeof(WCHAR)); NtClose(KeyHandle); if (!NT_SUCCESS(Status)) { @@ -1191,22 +1229,18 @@ BOOLEAN SetGeoID( PWCHAR Id) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName; - UNICODE_STRING ValueName; - HANDLE KeyHandle; - WCHAR szKeyName[] = L"\\Registry\\User\\.DEFAULT\\Control Panel\\International\\Geo"; - WCHAR szValueName[] = L"Nation"; NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name; + HANDLE KeyHandle; - RtlInitUnicodeString(&KeyName, - szKeyName); + RtlInitUnicodeString(&Name, + L".DEFAULT\\Control Panel\\International\\Geo"); InitializeObjectAttributes(&ObjectAttributes, - &KeyName, + &Name, OBJ_CASE_INSENSITIVE, - NULL, + GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); - Status = NtOpenKey(&KeyHandle, KEY_SET_VALUE, &ObjectAttributes); @@ -1216,9 +1250,9 @@ SetGeoID( return FALSE; } - RtlInitUnicodeString(&ValueName, szValueName); + RtlInitUnicodeString(&Name, L"Nation"); Status = NtSetValueKey(KeyHandle, - &ValueName, + &Name, 0, REG_SZ, (PVOID)Id, diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index 9170b232250..4eb2558fdff 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -816,9 +816,9 @@ SetupStartPage(PINPUT_RECORD Ir) MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } - DPRINT1("SourcePath: '%wZ'", &SourcePath); - DPRINT1("SourceRootPath: '%wZ'", &SourceRootPath); - DPRINT1("SourceRootDir: '%wZ'", &SourceRootDir); + DPRINT1("SourcePath: '%wZ'\n", &SourcePath); + DPRINT1("SourceRootPath: '%wZ'\n", &SourceRootPath); + DPRINT1("SourceRootDir: '%wZ'\n", &SourceRootDir); /* Load txtsetup.sif from install media. */ CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2, SourcePath.Buffer, L"txtsetup.sif"); @@ -4046,8 +4046,7 @@ FileCopyPage(PINPUT_RECORD Ir) * QuitPage * * SIDEEFFECTS - * Calls SetInstallPathValue - * Calls NtInitializeRegistry + * Calls RegInitializeRegistry * Calls ImportRegistryFile * Calls SetDefaultPagefile * Calls SetMountedDeviceValues @@ -4074,21 +4073,23 @@ RegistryPage(PINPUT_RECORD Ir) return SUCCESS_PAGE; } - /************************ HACK!!!!!!!!!!! *********************************/ - if (!SetInstallPathValue(&DestinationPath)) - { - DPRINT1("SetInstallPathValue() failed\n"); - MUIDisplayError(ERROR_INITIALIZE_REGISTRY, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - /************************ HACK!!!!!!!!!!! *********************************/ - - /* Create the default hives */ - Status = NtInitializeRegistry(CM_BOOT_FLAG_SETUP); + /* Initialize the registry and setup the default installation hives */ + Status = RegInitializeRegistry(&DestinationPath); if (!NT_SUCCESS(Status)) { - DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status); - MUIDisplayError(ERROR_CREATE_HIVE, Ir, POPUP_WAIT_ENTER); + DPRINT1("RegInitializeRegistry() failed\n"); + /********** HACK!!!!!!!!!!! **********/ + if (Status == STATUS_NOT_IMPLEMENTED) + { + /* The hack was called, display its corresponding error */ + MUIDisplayError(ERROR_INITIALIZE_REGISTRY, Ir, POPUP_WAIT_ENTER); + } + else + /*************************************/ + { + /* Something else (correct) failed */ + MUIDisplayError(ERROR_CREATE_HIVE, Ir, POPUP_WAIT_ENTER); + } return QUIT_PAGE; } @@ -4098,6 +4099,7 @@ RegistryPage(PINPUT_RECORD Ir) if (!SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL, &InfContext)) { DPRINT1("SetupFindFirstLine() failed\n"); + RegCleanupRegistry(); MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } @@ -4132,6 +4134,7 @@ RegistryPage(PINPUT_RECORD Ir) { DPRINT1("Importing %S failed\n", File); + RegCleanupRegistry(); MUIDisplayError(ERROR_IMPORT_HIVE, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } @@ -4141,6 +4144,7 @@ RegistryPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE)); if (!ProcessDisplayRegistry(SetupInf, DisplayList)) { + RegCleanupRegistry(); MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } @@ -4149,6 +4153,7 @@ RegistryPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE)); if (!ProcessLocaleRegistry(LanguageList)) { + RegCleanupRegistry(); MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } @@ -4157,6 +4162,7 @@ RegistryPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS)); if (!AddKeyboardLayouts()) { + RegCleanupRegistry(); MUIDisplayError(ERROR_ADDING_KBLAYOUTS, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } @@ -4164,6 +4170,7 @@ RegistryPage(PINPUT_RECORD Ir) /* Set GeoID */ if (!SetGeoID(MUIGetGeoID())) { + RegCleanupRegistry(); MUIDisplayError(ERROR_UPDATE_GEOID, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } @@ -4174,6 +4181,7 @@ RegistryPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE)); if (!ProcessKeyboardLayoutRegistry(LayoutList)) { + RegCleanupRegistry(); MUIDisplayError(ERROR_UPDATE_KBSETTINGS, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } @@ -4183,6 +4191,7 @@ RegistryPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE)); if (!AddCodePage()) { + RegCleanupRegistry(); MUIDisplayError(ERROR_ADDING_CODEPAGE, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } @@ -4193,6 +4202,12 @@ RegistryPage(PINPUT_RECORD Ir) /* Update the mounted devices list */ SetMountedDeviceValues(PartitionList); + // + // TODO: Unload all the registry stuff, perform cleanup, + // and copy the created hive files into .sav ones. + // + RegCleanupRegistry(); + CONSOLE_SetStatusText(MUIGetString(STRING_DONE)); return BOOT_LOADER_PAGE; @@ -4211,8 +4226,7 @@ RegistryPage(PINPUT_RECORD Ir) * QuitPage * * SIDEEFFECTS - * Calls SetInstallPathValue - * Calls NtInitializeRegistry + * Calls RegInitializeRegistry * Calls ImportRegistryFile * Calls SetDefaultPagefile * Calls SetMountedDeviceValues @@ -4865,12 +4879,10 @@ RunUSetup(VOID) InfSetHeap(ProcessHeap); -#if 0 /* Tell the Cm this is a setup boot, and it has to behave accordingly */ Status = NtInitializeRegistry(CM_BOOT_FLAG_SETUP); if (!NT_SUCCESS(Status)) DPRINT1("NtInitializeRegistry() failed (Status 0x%08lx)\n", Status); -#endif /* Create the PnP thread in suspended state */ Status = RtlCreateUserThread(NtCurrentProcess(),