X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fconfig%2Fcmsysini.c;h=f49c07acd12538f473e62e954e2bd6ecca0a171c;hp=dc03e96fdb8a50a7edc99c8a080939ea2f3c635f;hb=2ed65d15557489e8e9ee7ca0cfd8901cdf5f8efd;hpb=c70f992aa17e22fdd474580a1e10c253c258b88f diff --git a/ntoskrnl/config/cmsysini.c b/ntoskrnl/config/cmsysini.c index dc03e96fdb8..f49c07acd12 100644 --- a/ntoskrnl/config/cmsysini.c +++ b/ntoskrnl/config/cmsysini.c @@ -29,6 +29,7 @@ BOOLEAN CmpSpecialBootCondition; BOOLEAN CmpNoWrite; BOOLEAN CmpWasSetupBoot; BOOLEAN CmpProfileLoaded; +BOOLEAN CmpNoVolatileCreates; ULONG CmpTraceLevel = 0; extern LONG CmpFlushStarveWriters; @@ -36,6 +37,73 @@ extern BOOLEAN CmFirstTime; /* FUNCTIONS ******************************************************************/ +BOOLEAN +NTAPI +CmpLinkKeyToHive( + _In_z_ PCWSTR LinkKeyName, + _In_z_ PCWSTR TargetKeyName) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + HANDLE LinkKeyHandle; + ULONG Disposition; + + PAGED_CODE(); + + /* Initialize the object attributes */ + RtlInitUnicodeString(&KeyName, LinkKeyName); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + + /* Create the link key */ + Status = ZwCreateKey(&LinkKeyHandle, + KEY_CREATE_LINK, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CM: CmpLinkKeyToHive: couldn't create %S, Status = 0x%lx\n", + LinkKeyName, Status); + return FALSE; + } + + /* Check if the new key was actually created */ + if (Disposition != REG_CREATED_NEW_KEY) + { + DPRINT1("CM: CmpLinkKeyToHive: %S already exists!\n", LinkKeyName); + ZwClose(LinkKeyHandle); + return FALSE; + } + + /* Set the target key name as link target */ + RtlInitUnicodeString(&KeyName, TargetKeyName); + Status = ZwSetValueKey(LinkKeyHandle, + &CmSymbolicLinkValueName, + 0, + REG_LINK, + KeyName.Buffer, + KeyName.Length); + + /* Close the link key handle */ + ObCloseHandle(LinkKeyHandle, KernelMode); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("CM: CmpLinkKeyToHive: couldn't create symbolic link for %S, Status = 0x%lx\n", + TargetKeyName, Status); + return FALSE; + } + + return TRUE; +} + VOID NTAPI CmpDeleteKeyObject(PVOID DeletedObject) @@ -64,7 +132,7 @@ CmpDeleteKeyObject(PVOID DeletedObject) CmpLockRegistry(); /* Make sure this is a valid key body */ - if (KeyBody->Type == '20yk') + if (KeyBody->Type == CM_KEY_BODY_TYPE) { /* Get the KCB */ Kcb = KeyBody->KeyControlBlock; @@ -101,7 +169,7 @@ CmpCloseKeyObject(IN PEPROCESS Process OPTIONAL, if (SystemHandleCount > 1) return; /* Make sure we're a valid key body */ - if (KeyBody->Type == '20yk') + if (KeyBody->Type == CM_KEY_BODY_TYPE) { /* Don't do anything if we don't have a notify block */ if (!KeyBody->NotifyBlock) return; @@ -164,7 +232,7 @@ CmpQueryKeyName(IN PVOID ObjectBody, ((Length < (*ReturnLength)) && (BytesToCopy < sizeof(WCHAR)))) { /* Free the buffer allocated by CmpConstructName */ - ExFreePool(KeyName); + ExFreePoolWithTag(KeyName, TAG_CM); /* Return buffer length failure without writing anything there because nothing fits */ return STATUS_INFO_LENGTH_MISMATCH; @@ -197,7 +265,7 @@ CmpQueryKeyName(IN PVOID ObjectBody, BytesToCopy); /* Null terminate it */ - ObjectNameInfo->Name.Buffer[BytesToCopy / sizeof(WCHAR)] = 0; + ObjectNameInfo->Name.Buffer[BytesToCopy / sizeof(WCHAR)] = UNICODE_NULL; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -207,7 +275,7 @@ CmpQueryKeyName(IN PVOID ObjectBody, _SEH2_END; /* Free the buffer allocated by CmpConstructName */ - ExFreePool(KeyName); + ExFreePoolWithTag(KeyName, TAG_CM); /* Return status */ return Status; @@ -284,7 +352,7 @@ CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName, } /* Initialize the hive */ - Status = CmpInitializeHive((PCMHIVE*)&NewHive, + Status = CmpInitializeHive(&NewHive, Operation, HiveFlags, FileType, @@ -293,7 +361,7 @@ CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName, LogHandle, NULL, HiveName, - 0); + CheckFlags); if (!NT_SUCCESS(Status)) { /* Fail */ @@ -305,9 +373,6 @@ CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName, /* Success, return hive */ *Hive = NewHive; - /* ROS: Init root key cell and prepare the hive */ - if (Operation == HINIT_CREATE) CmCreateRootNode(&NewHive->Hive, L""); - /* Duplicate the hive name */ NewHive->FileFullPath.Buffer = ExAllocatePoolWithTag(PagedPool, HiveName->Length, @@ -319,7 +384,7 @@ CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName, HiveName->Buffer, HiveName->Length); NewHive->FileFullPath.Length = HiveName->Length; - NewHive->FileFullPath.MaximumLength = HiveName->MaximumLength; + NewHive->FileFullPath.MaximumLength = HiveName->Length; } /* Return success */ @@ -331,10 +396,11 @@ NTAPI INIT_FUNCTION CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { + NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE KeyHandle; UNICODE_STRING KeyName, ValueName = { 0, 0, NULL }; - HANDLE KeyHandle = NULL; - NTSTATUS Status; + ASSERT(LoaderBlock != NULL); /* Setup attributes for loader options */ @@ -347,9 +413,10 @@ CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) NULL, NULL); Status = NtOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes); - if (!NT_SUCCESS(Status)) goto Quickie; + if (!NT_SUCCESS(Status)) + return Status; - /* Key opened, now write to the key */ + /* Setup the value for the system start options */ RtlInitUnicodeString(&KeyName, L"SystemStartOptions"); Status = NtSetValueKey(KeyHandle, &KeyName, @@ -357,9 +424,10 @@ CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) REG_SZ, CmpLoadOptions.Buffer, CmpLoadOptions.Length); - if (!NT_SUCCESS(Status)) goto Quickie; + if (!NT_SUCCESS(Status)) + goto Quit; - /* Setup value name for system boot device in ARC format */ + /* Setup the value for the system boot device in ARC format */ RtlInitUnicodeString(&KeyName, L"SystemBootDevice"); RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->ArcBootDeviceName); Status = NtSetValueKey(KeyHandle, @@ -369,15 +437,85 @@ CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) ValueName.Buffer, ValueName.Length); -Quickie: - /* Free the buffers */ + /* Free the temporary string */ RtlFreeUnicodeString(&ValueName); +Quit: /* Close the key and return */ - if (KeyHandle) NtClose(KeyHandle); + NtClose(KeyHandle); + return Status; +} + +static +NTSTATUS +INIT_FUNCTION +CmpCreateHardwareProfile(HANDLE ControlSetHandle) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + HANDLE ProfilesHandle = NULL; + HANDLE ProfileHandle = NULL; + ULONG Disposition; + NTSTATUS Status; + + DPRINT("CmpCreateHardwareProfile()\n"); - /* Return the status */ - return (ExpInTextModeSetup ? STATUS_SUCCESS : Status); + /* Create the Hardware Profiles key */ + RtlInitUnicodeString(&KeyName, L"Hardware Profiles"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + ControlSetHandle, + NULL); + Status = NtCreateKey(&ProfilesHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + 0, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Creating the Hardware Profile key failed\n"); + goto done; + } + + /* Sanity check */ + ASSERT(Disposition == REG_CREATED_NEW_KEY); + + /* Create the 0000 key */ + RtlInitUnicodeString(&KeyName, L"0000"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + ProfilesHandle, + NULL); + Status = NtCreateKey(&ProfileHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + 0, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Creating the Hardware Profile\\0000 key failed\n"); + goto done; + } + + /* Sanity check */ + ASSERT(Disposition == REG_CREATED_NEW_KEY); + +done: + if (ProfilesHandle) + NtClose(ProfilesHandle); + + if (ProfileHandle) + NtClose(ProfileHandle); + + DPRINT("CmpCreateHardwareProfile() done\n"); + + return Status; } NTSTATUS @@ -392,75 +530,88 @@ CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock) OBJECT_ATTRIBUTES ObjectAttributes; CHAR ValueInfoBuffer[128]; PKEY_VALUE_FULL_INFORMATION ValueInfo; - CHAR Buffer[128]; WCHAR UnicodeBuffer[128]; - HANDLE SelectHandle, KeyHandle, ConfigHandle = NULL, ProfileHandle = NULL; + HANDLE SelectHandle = NULL; + HANDLE KeyHandle = NULL; + HANDLE ConfigHandle = NULL; + HANDLE ProfileHandle = NULL; HANDLE ParentHandle = NULL; ULONG ControlSet, HwProfile; - ANSI_STRING TempString; NTSTATUS Status; ULONG ResultLength, Disposition; PLOADER_PARAMETER_EXTENSION LoaderExtension; PAGED_CODE(); - /* Open the select key */ - InitializeObjectAttributes(&ObjectAttributes, - &SelectName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = NtOpenKey(&SelectHandle, KEY_READ, &ObjectAttributes); - if (!NT_SUCCESS(Status)) + /* ReactOS Hack: Hard-code current to 001 for SetupLdr */ + if (LoaderBlock->RegistryBase == NULL) { - /* ReactOS Hack: Hard-code current to 001 for SetupLdr */ - if (!LoaderBlock->RegistryBase) + /* Build the ControlSet001 key */ + RtlInitUnicodeString(&KeyName, + L"\\Registry\\Machine\\System\\ControlSet001"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtCreateKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + 0, + &Disposition); + if (!NT_SUCCESS(Status)) { - /* Build the ControlSet001 key */ - RtlInitUnicodeString(&KeyName, - L"\\Registry\\Machine\\System\\ControlSet001"); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = NtCreateKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - 0, - &Disposition); - if (!NT_SUCCESS(Status)) return Status; - - /* Don't need the handle */ - ZwClose(KeyHandle); + DPRINT1("Failed to create ControlSet001 key: 0x%lx\n", Status); + goto Cleanup; + } - /* Use hard-coded setting */ - ControlSet = 1; - goto UseSet; + /* Create the Hardware Profile keys */ + Status = CmpCreateHardwareProfile(KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create Hardware profile keys: 0x%lx\n", Status); + goto Cleanup; } - /* Fail for real boots */ - return Status; + /* Use hard-coded setting */ + ControlSet = 1; } + else + { + /* Open the select key */ + InitializeObjectAttributes(&ObjectAttributes, + &SelectName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&SelectHandle, KEY_READ, &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open select key: 0x%lx\n", Status); + goto Cleanup; + } - /* Open the current value */ - RtlInitUnicodeString(&KeyName, L"Current"); - Status = NtQueryValueKey(SelectHandle, - &KeyName, - KeyValueFullInformation, - ValueInfoBuffer, - sizeof(ValueInfoBuffer), - &ResultLength); - NtClose(SelectHandle); - if (!NT_SUCCESS(Status)) return Status; + /* Open the current value */ + RtlInitUnicodeString(&KeyName, L"Current"); + Status = NtQueryValueKey(SelectHandle, + &KeyName, + KeyValueFullInformation, + ValueInfoBuffer, + sizeof(ValueInfoBuffer), + &ResultLength); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open the Current value: 0x%lx\n", Status); + goto Cleanup; + } - /* Get the actual value pointer, and get the control set ID */ - ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer; - ControlSet = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset); + /* Get the actual value pointer, and get the control set ID */ + ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer; + ControlSet = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset); + } /* Create the current control set key */ -UseSet: RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet"); InitializeObjectAttributes(&ObjectAttributes, @@ -475,21 +626,20 @@ UseSet: NULL, REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, &Disposition); - if (!NT_SUCCESS(Status)) return Status; + if (!NT_SUCCESS(Status)) + goto Cleanup; /* Sanity check */ ASSERT(Disposition == REG_CREATED_NEW_KEY); - /* Initialize the symbolic link name */ - sprintf(Buffer, - "\\Registry\\Machine\\System\\ControlSet%03ld", - ControlSet); - RtlInitAnsiString(&TempString, Buffer); + /* Initialize the target link name */ + Status = RtlStringCbPrintfW(UnicodeBuffer, sizeof(UnicodeBuffer), + L"\\Registry\\Machine\\System\\ControlSet%03ld", + ControlSet); + if (!NT_SUCCESS(Status)) + goto Cleanup; - /* Create a Unicode string out of it */ - KeyName.MaximumLength = sizeof(UnicodeBuffer); - KeyName.Buffer = UnicodeBuffer; - Status = RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE); + RtlInitUnicodeString(&KeyName, UnicodeBuffer); /* Set the value */ Status = NtSetValueKey(KeyHandle, @@ -498,7 +648,8 @@ UseSet: REG_LINK, KeyName.Buffer, KeyName.Length); - if (!NT_SUCCESS(Status)) return Status; + if (!NT_SUCCESS(Status)) + goto Cleanup; /* Get the configuration database key */ InitializeObjectAttributes(&ObjectAttributes, @@ -507,33 +658,44 @@ UseSet: KeyHandle, NULL); Status = NtOpenKey(&ConfigHandle, KEY_READ, &ObjectAttributes); - NtClose(KeyHandle); /* Check if we don't have one */ if (!NT_SUCCESS(Status)) { /* Cleanup and exit */ - ConfigHandle = 0; + Status = STATUS_SUCCESS; goto Cleanup; } - /* Now get the current config */ - RtlInitUnicodeString(&KeyName, L"CurrentConfig"); - Status = NtQueryValueKey(ConfigHandle, - &KeyName, - KeyValueFullInformation, - ValueInfoBuffer, - sizeof(ValueInfoBuffer), - &ResultLength); - - /* Set pointer to buffer */ - ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer; - - /* Check if we failed or got a non DWORD-value */ - if (!(NT_SUCCESS(Status)) || (ValueInfo->Type != REG_DWORD)) goto Cleanup; + /* ReactOS Hack: Hard-code current to 001 for SetupLdr */ + if (LoaderBlock->RegistryBase == NULL) + { + HwProfile = 0; + } + else + { + /* Now get the current config */ + RtlInitUnicodeString(&KeyName, L"CurrentConfig"); + Status = NtQueryValueKey(ConfigHandle, + &KeyName, + KeyValueFullInformation, + ValueInfoBuffer, + sizeof(ValueInfoBuffer), + &ResultLength); + + /* Set pointer to buffer */ + ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer; + + /* Check if we failed or got a non DWORD-value */ + if (!(NT_SUCCESS(Status)) || (ValueInfo->Type != REG_DWORD)) + { + Status = STATUS_SUCCESS; + goto Cleanup; + } - /* Get the hadware profile */ - HwProfile = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset); + /* Get the hadware profile */ + HwProfile = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset); + } /* Open the hardware profile key */ RtlInitUnicodeString(&KeyName, @@ -548,21 +710,14 @@ UseSet: if (!NT_SUCCESS(Status)) { /* Exit and clean up */ - ParentHandle = 0; + Status = STATUS_SUCCESS; goto Cleanup; } /* Build the profile name */ - sprintf(Buffer, "%04ld", HwProfile); - RtlInitAnsiString(&TempString, Buffer); - - /* Convert it to Unicode */ - KeyName.MaximumLength = sizeof(UnicodeBuffer); - KeyName.Buffer = UnicodeBuffer; - Status = RtlAnsiStringToUnicodeString(&KeyName, - &TempString, - FALSE); - ASSERT(Status == STATUS_SUCCESS); + RtlStringCbPrintfW(UnicodeBuffer, sizeof(UnicodeBuffer), + L"%04ld", HwProfile); + RtlInitUnicodeString(&KeyName, UnicodeBuffer); /* Open the associated key */ InitializeObjectAttributes(&ObjectAttributes, @@ -576,7 +731,7 @@ UseSet: if (!NT_SUCCESS (Status)) { /* Cleanup and exit */ - ProfileHandle = 0; + Status = STATUS_SUCCESS; goto Cleanup; } @@ -584,7 +739,7 @@ UseSet: LoaderExtension = LoaderBlock->Extension; if (LoaderExtension) { - ASSERTMSG("ReactOS doesn't support NTLDR Profiles yet!\n", FALSE); + DPRINT("ReactOS doesn't support NTLDR Profiles yet!\n"); } /* Create the current hardware profile key */ @@ -609,19 +764,11 @@ UseSet: ASSERT(Disposition == REG_CREATED_NEW_KEY); /* Create the profile name */ - sprintf(Buffer, - "\\Registry\\Machine\\System\\CurrentControlSet\\" - "Hardware Profiles\\%04ld", - HwProfile); - RtlInitAnsiString(&TempString, Buffer); - - /* Convert it to Unicode */ - KeyName.MaximumLength = sizeof(UnicodeBuffer); - KeyName.Buffer = UnicodeBuffer; - Status = RtlAnsiStringToUnicodeString(&KeyName, - &TempString, - FALSE); - ASSERT(STATUS_SUCCESS == Status); + RtlStringCbPrintfW(UnicodeBuffer, sizeof(UnicodeBuffer), + L"\\Registry\\Machine\\System\\CurrentControlSet\\" + L"Hardware Profiles\\%04ld", + HwProfile); + RtlInitUnicodeString(&KeyName, UnicodeBuffer); /* Set it */ Status = NtSetValueKey(KeyHandle, @@ -630,17 +777,20 @@ UseSet: REG_LINK, KeyName.Buffer, KeyName.Length); - NtClose(KeyHandle); } - /* Close every opened handle */ + Status = STATUS_SUCCESS; + Cleanup: + /* Close every opened handle */ + if (SelectHandle) NtClose(SelectHandle); + if (KeyHandle) NtClose(KeyHandle); if (ConfigHandle) NtClose(ConfigHandle); if (ProfileHandle) NtClose(ProfileHandle); if (ParentHandle) NtClose(ParentHandle); - /* Return success */ - return STATUS_SUCCESS; + DPRINT("CmpCreateControlSet() done\n"); + return Status; } NTSTATUS @@ -714,16 +864,17 @@ NTAPI INIT_FUNCTION CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { + static const UNICODE_STRING HiveName = RTL_CONSTANT_STRING(L"SYSTEM"); PVOID HiveBase; ANSI_STRING LoadString; PVOID Buffer; ULONG Length; NTSTATUS Status; - BOOLEAN Allocate; UNICODE_STRING KeyName; PCMHIVE SystemHive = NULL; - UNICODE_STRING HiveName = RTL_CONSTANT_STRING(L"SYSTEM"); PSECURITY_DESCRIPTOR SecurityDescriptor; + BOOLEAN Success; + PAGED_CODE(); /* Setup the ansi string */ @@ -742,59 +893,45 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) RtlInitEmptyUnicodeString(&CmpLoadOptions, Buffer, (USHORT)Length); /* Add the load options and null-terminate */ - RtlAnsiStringToUnicodeString(&CmpLoadOptions, &LoadString, FALSE); + Status = RtlAnsiStringToUnicodeString(&CmpLoadOptions, &LoadString, FALSE); + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + CmpLoadOptions.Buffer[LoadString.Length] = UNICODE_NULL; CmpLoadOptions.Length += sizeof(WCHAR); /* Get the System Hive base address */ HiveBase = LoaderBlock->RegistryBase; - if (HiveBase) - { - /* Import it */ - ((PHBASE_BLOCK)HiveBase)->Length = LoaderBlock->RegistryLength; - Status = CmpInitializeHive((PCMHIVE*)&SystemHive, - HINIT_MEMORY, - HIVE_NOLAZYFLUSH, - HFILE_TYPE_LOG, - HiveBase, - NULL, - NULL, - NULL, - &HiveName, - 2); - if (!NT_SUCCESS(Status)) return FALSE; - - /* Set the hive filename */ - RtlCreateUnicodeString(&SystemHive->FileFullPath, - L"\\SystemRoot\\System32\\Config\\SYSTEM"); - - /* We imported, no need to create a new hive */ - Allocate = FALSE; - /* Manually set the hive as volatile, if in Live CD mode */ - if (CmpShareSystemHives) SystemHive->Hive.HiveFlags = HIVE_VOLATILE; - } - else + Status = CmpInitializeHive(&SystemHive, + HiveBase ? HINIT_MEMORY : HINIT_CREATE, + HIVE_NOLAZYFLUSH, + HFILE_TYPE_LOG, + HiveBase, + NULL, + NULL, + NULL, + &HiveName, + HiveBase ? 2 : 0); + if (!NT_SUCCESS(Status)) { - /* Create it */ - Status = CmpInitializeHive(&SystemHive, - HINIT_CREATE, - HIVE_NOLAZYFLUSH, - HFILE_TYPE_LOG, - NULL, - NULL, - NULL, - NULL, - &HiveName, - 0); - if (!NT_SUCCESS(Status)) return FALSE; + return FALSE; + } - /* Set the hive filename */ - RtlCreateUnicodeString(&SystemHive->FileFullPath, - L"\\SystemRoot\\System32\\Config\\SYSTEM"); + /* Set the hive filename */ + Success = RtlCreateUnicodeString(&SystemHive->FileFullPath, + L"\\SystemRoot\\System32\\Config\\SYSTEM"); + if (!Success) + { + return FALSE; + } - /* Tell CmpLinkHiveToMaster to allocate a hive */ - Allocate = TRUE; + /* Manually set the hive as volatile, if in Live CD mode */ + if (HiveBase && CmpShareSystemHives) + { + SystemHive->Hive.HiveFlags = HIVE_VOLATILE; } /* Save the boot type */ @@ -820,19 +957,20 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) SecurityDescriptor = CmpHiveRootSecurityDescriptor(); /* Attach it to the system key */ + /* Let CmpLinkHiveToMaster allocate a new hive if we got none from the LoaderBlock. */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM"); Status = CmpLinkHiveToMaster(&KeyName, NULL, - (PCMHIVE)SystemHive, - Allocate, + SystemHive, + !HiveBase, SecurityDescriptor); /* Free the security descriptor */ - ExFreePoolWithTag(SecurityDescriptor, TAG_CM); + ExFreePoolWithTag(SecurityDescriptor, TAG_CMSD); if (!NT_SUCCESS(Status)) return FALSE; /* Add the hive to the hive list */ - CmpMachineHiveList[3].CmHive = (PCMHIVE)SystemHive; + CmpMachineHiveList[3].CmHive = SystemHive; /* Success! */ return TRUE; @@ -881,7 +1019,6 @@ CmpCreateRootNode(IN PHHIVE Hive, { UNICODE_STRING KeyName; PCM_KEY_NODE KeyCell; - LARGE_INTEGER SystemTime; PAGED_CODE(); /* Initialize the node name and allocate it */ @@ -899,10 +1036,9 @@ CmpCreateRootNode(IN PHHIVE Hive, if (!KeyCell) return FALSE; /* Setup the cell */ - KeyCell->Signature = (USHORT)CM_KEY_NODE_SIGNATURE; + KeyCell->Signature = CM_KEY_NODE_SIGNATURE; KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE; - KeQuerySystemTime(&SystemTime); - KeyCell->LastWriteTime = SystemTime; + KeQuerySystemTime(&KeyCell->LastWriteTime); KeyCell->Parent = HCELL_NIL; KeyCell->SubKeyCounts[Stable] = 0; KeyCell->SubKeyCounts[Volatile] = 0; @@ -919,14 +1055,11 @@ CmpCreateRootNode(IN PHHIVE Hive, KeyCell->MaxValueDataLen = 0; /* Copy the name (this will also set the length) */ - KeyCell->NameLength = CmpCopyName(Hive, (PWCHAR)KeyCell->Name, &KeyName); + KeyCell->NameLength = CmpCopyName(Hive, KeyCell->Name, &KeyName); - /* Check if the name was compressed */ + /* Check if the name was compressed and set the flag if so */ if (KeyCell->NameLength < KeyName.Length) - { - /* Set the flag */ KeyCell->Flags |= KEY_COMP_NAME; - } /* Return success */ HvReleaseCell(Hive, *Index); @@ -962,7 +1095,7 @@ CmpCreateRegistryRoot(VOID) &KeyName, OBJ_CASE_INSENSITIVE, NULL, - NULL); + SecurityDescriptor); Status = ObCreateObject(KernelMode, CmpKeyObjectType, &ObjectAttributes, @@ -972,7 +1105,7 @@ CmpCreateRegistryRoot(VOID) 0, 0, (PVOID*)&RootKey); - ExFreePoolWithTag(SecurityDescriptor, TAG_CM); + ExFreePoolWithTag(SecurityDescriptor, TAG_CMSD); if (!NT_SUCCESS(Status)) return FALSE; /* Sanity check, and get the key cell */ @@ -988,11 +1121,15 @@ CmpCreateRegistryRoot(VOID) NULL, 0, &KeyName); - if (!Kcb) return FALSE; + if (!Kcb) + { + ObDereferenceObject(RootKey); + return FALSE; + } /* Initialize the object */ RootKey->KeyControlBlock = Kcb; - RootKey->Type = '20yk'; + RootKey->Type = CM_KEY_BODY_TYPE; RootKey->NotifyBlock = NULL; RootKey->ProcessID = PsGetCurrentProcessId(); @@ -1006,7 +1143,11 @@ CmpCreateRegistryRoot(VOID) 0, NULL, &CmpRegistryRootHandle); - if (!NT_SUCCESS(Status)) return FALSE; + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(RootKey); + return FALSE; + } /* Reference the key again so that we never lose it */ Status = ObReferenceObjectByHandle(CmpRegistryRootHandle, @@ -1015,7 +1156,11 @@ CmpCreateRegistryRoot(VOID) KernelMode, (PVOID*)&RootKey, NULL); - if (!NT_SUCCESS(Status)) return FALSE; + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(RootKey); + return FALSE; + } /* Completely sucessful */ return TRUE; @@ -1023,7 +1168,7 @@ CmpCreateRegistryRoot(VOID) NTSTATUS NTAPI -CmpGetRegistryPath(IN PWCHAR ConfigPath) +CmpGetRegistryPath(OUT PWCHAR ConfigPath) { OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; @@ -1036,10 +1181,12 @@ CmpGetRegistryPath(IN PWCHAR ConfigPath) /* Check if we are booted in setup */ if (ExpInTextModeSetup) { + DPRINT1("CmpGetRegistryPath TextMode setup HACK!!\n"); + /* Setup the object attributes */ InitializeObjectAttributes(&ObjectAttributes, &KeyName, - OBJ_CASE_INSENSITIVE, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); /* Open the key */ @@ -1089,10 +1236,13 @@ CmpGetRegistryPath(IN PWCHAR ConfigPath) /* Add registry path */ wcscat(ConfigPath, L"\\System32\\Config\\"); + DPRINT1("CmpGetRegistryPath: ConfigPath = '%S'\n", ConfigPath); + /* Done */ return STATUS_SUCCESS; } +_Function_class_(KSTART_ROUTINE) VOID NTAPI CmpLoadHiveThread(IN PVOID StartContext) @@ -1101,7 +1251,6 @@ CmpLoadHiveThread(IN PVOID StartContext) UNICODE_STRING TempName, FileName, RegName; ULONG i, ErrorResponse, WorkerCount, Length; USHORT FileStart; - //ULONG RegStart; ULONG PrimaryDisposition, SecondaryDisposition, ClusterSize; PCMHIVE CmHive; HANDLE PrimaryHandle = NULL, LogHandle = NULL; @@ -1117,36 +1266,35 @@ CmpLoadHiveThread(IN PVOID StartContext) CmpMachineHiveList[i].ThreadStarted = TRUE; /* Build the file name and registry name strings */ - RtlInitEmptyUnicodeString(&FileName, FileBuffer, MAX_PATH); - RtlInitEmptyUnicodeString(&RegName, RegBuffer, MAX_PATH); + RtlInitEmptyUnicodeString(&FileName, FileBuffer, sizeof(FileBuffer)); + RtlInitEmptyUnicodeString(&RegName, RegBuffer, sizeof(RegBuffer)); /* Now build the system root path */ CmpGetRegistryPath(ConfigPath); RtlInitUnicodeString(&TempName, ConfigPath); - RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName); + RtlAppendUnicodeStringToString(&FileName, &TempName); FileStart = FileName.Length; /* And build the registry root path */ RtlInitUnicodeString(&TempName, L"\\REGISTRY\\"); - RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName); - //RegStart = RegName.Length; + RtlAppendUnicodeStringToString(&RegName, &TempName); /* Build the base name */ RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName); - RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName); + RtlAppendUnicodeStringToString(&RegName, &TempName); /* Check if this is a child of the root */ - if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == '\\') + if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR) { /* Then setup the whole name */ RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].Name); - RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName); + RtlAppendUnicodeStringToString(&RegName, &TempName); } /* Now add the rest of the file name */ RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].Name); FileName.Length = FileStart; - RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName); + RtlAppendUnicodeStringToString(&FileName, &TempName); if (!CmpMachineHiveList[i].CmHive) { /* We need to allocate a new hive structure */ @@ -1159,9 +1307,12 @@ CmpLoadHiveThread(IN PVOID StartContext) &CmpMachineHiveList[i].Allocate, 0); if (!(NT_SUCCESS(Status)) || - (!(CmHive->FileHandles[HFILE_TYPE_LOG]) && !(CmpMiniNTBoot))) // HACK + (!(CmpShareSystemHives) && !(CmHive->FileHandles[HFILE_TYPE_LOG]))) { - /* We failed or couldn't get a log file, raise a hard error */ + /* + * We failed, or could not get a log file (unless + * the hive is shared), raise a hard error. + */ ErrorParameters = &FileName; NtRaiseHardError(STATUS_CANNOT_LOAD_REGISTRY_FILE, 1, @@ -1219,15 +1370,19 @@ CmpLoadHiveThread(IN PVOID StartContext) Length = CmHive->Hive.Storage[Stable].Length + HBLOCK_SIZE; /* Check if the cluster size doesn't match */ - if (CmHive->Hive.Cluster != ClusterSize) ASSERT(FALSE); + if (CmHive->Hive.Cluster != ClusterSize) + { + DPRINT1("FIXME: Support for CmHive->Hive.Cluster (%lu) != ClusterSize (%lu) is unimplemented!\n", + CmHive->Hive.Cluster, ClusterSize); + } /* Set the file size */ - DPRINT("FIXME: Should set file size: %lx\n", Length); + DPRINT("FIXME: Should set file size: %lu\n", Length); //if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length)) - { + //{ /* This shouldn't fail */ //ASSERT(FALSE); - } + //} /* Another thing we don't support is NTLDR-recovery */ if (CmHive->Hive.BaseBlock->BootRecover) ASSERT(FALSE); @@ -1255,7 +1410,7 @@ CmpLoadHiveThread(IN PVOID StartContext) VOID NTAPI -CmpInitializeHiveList(IN USHORT Flag) +CmpInitializeHiveList(VOID) { WCHAR FileBuffer[MAX_PATH], RegBuffer[MAX_PATH], ConfigPath[MAX_PATH]; UNICODE_STRING TempName, FileName, RegName; @@ -1270,17 +1425,17 @@ CmpInitializeHiveList(IN USHORT Flag) CmpNoWrite = FALSE; /* Build the file name and registry name strings */ - RtlInitEmptyUnicodeString(&FileName, FileBuffer, MAX_PATH); - RtlInitEmptyUnicodeString(&RegName, RegBuffer, MAX_PATH); + RtlInitEmptyUnicodeString(&FileName, FileBuffer, sizeof(FileBuffer)); + RtlInitEmptyUnicodeString(&RegName, RegBuffer, sizeof(RegBuffer)); /* Now build the system root path */ CmpGetRegistryPath(ConfigPath); RtlInitUnicodeString(&TempName, ConfigPath); - RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName); + RtlAppendUnicodeStringToString(&FileName, &TempName); /* And build the registry root path */ RtlInitUnicodeString(&TempName, L"\\REGISTRY\\"); - RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName); + RtlAppendUnicodeStringToString(&RegName, &TempName); RegStart = RegName.Length; /* Setup the event to synchronize workers */ @@ -1295,9 +1450,13 @@ CmpInitializeHiveList(IN USHORT Flag) /* Loop every hive we care about */ for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++) { - /* Make sure the list is setup */ + /* Make sure the list is set up */ ASSERT(CmpMachineHiveList[i].Name != NULL); + /* Load the hive as volatile, if in LiveCD mode */ + if (CmpShareSystemHives) + CmpMachineHiveList[i].HHiveFlags |= HIVE_VOLATILE; + /* Create a thread to handle this hive */ Status = PsCreateSystemThread(&Thread, THREAD_ALL_ACCESS, @@ -1348,14 +1507,14 @@ CmpInitializeHiveList(IN USHORT Flag) /* Build the base name */ RegName.Length = RegStart; RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName); - RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName); + RtlAppendUnicodeStringToString(&RegName, &TempName); /* Check if this is a child of the root */ - if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == '\\') + if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR) { /* Then setup the whole name */ RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].Name); - RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName); + RtlAppendUnicodeStringToString(&RegName, &TempName); } /* Now link the hive to its master */ @@ -1387,11 +1546,17 @@ CmpInitializeHiveList(IN USHORT Flag) } /* Get rid of the SD */ - ExFreePoolWithTag(SecurityDescriptor, TAG_CM); + ExFreePoolWithTag(SecurityDescriptor, TAG_CMSD); - /* FIXME: Link SECURITY to SAM */ + /* Link SECURITY to SAM */ + CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM", + L"\\Registry\\Machine\\SAM\\SAM"); - /* FIXME: Link S-1-5-18 to .Default */ + /* Link S-1-5-18 to .Default */ + CmpNoVolatileCreates = FALSE; + CmpLinkKeyToHive(L"\\Registry\\User\\S-1-5-18", + L"\\Registry\\User\\.Default"); + CmpNoVolatileCreates = TRUE; } BOOLEAN @@ -1450,7 +1615,7 @@ CmInitSystem1(VOID) } /* Build the master hive */ - Status = CmpInitializeHive((PCMHIVE*)&CmiVolatileHive, + Status = CmpInitializeHive(&CmiVolatileHive, HINIT_CREATE, HIVE_VOLATILE, HFILE_TYPE_PRIMARY, @@ -1476,7 +1641,7 @@ CmInitSystem1(VOID) /* Create the default security descriptor */ SecurityDescriptor = CmpHiveRootSecurityDescriptor(); - /* Create '\Registry\Machine' key. */ + /* Create '\Registry\Machine' key */ RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, @@ -1499,7 +1664,7 @@ CmInitSystem1(VOID) /* Close the handle */ NtClose(KeyHandle); - /* Create '\Registry\User' key. */ + /* Create '\Registry\User' key */ RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\USER"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, @@ -1522,6 +1687,9 @@ CmInitSystem1(VOID) /* Close the handle */ NtClose(KeyHandle); + /* After this point, do not allow creating keys in the master hive */ + CmpNoVolatileCreates = TRUE; + /* Initialize the system hive */ if (!CmpInitializeSystemHive(KeLoaderBlock)) { @@ -1529,7 +1697,7 @@ CmInitSystem1(VOID) KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 7, 0, 0); } - /* Create the 'CurrentControlSet' link. */ + /* Create the 'CurrentControlSet' link */ Status = CmpCreateControlSet(KeLoaderBlock); if (!NT_SUCCESS(Status)) { @@ -1538,7 +1706,7 @@ CmInitSystem1(VOID) } /* Create the hardware hive */ - Status = CmpInitializeHive((PCMHIVE*)&HardwareHive, + Status = CmpInitializeHive(&HardwareHive, HINIT_CREATE, HIVE_VOLATILE, HFILE_TYPE_PRIMARY, @@ -1555,13 +1723,13 @@ CmInitSystem1(VOID) } /* Add the hive to the hive list */ - CmpMachineHiveList[0].CmHive = (PCMHIVE)HardwareHive; + CmpMachineHiveList[0].CmHive = HardwareHive; /* Attach it to the machine key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE"); Status = CmpLinkHiveToMaster(&KeyName, NULL, - (PCMHIVE)HardwareHive, + HardwareHive, TRUE, SecurityDescriptor); if (!NT_SUCCESS(Status)) @@ -1574,7 +1742,7 @@ CmInitSystem1(VOID) CmpAddToHiveFileList(HardwareHive); /* Free the security descriptor */ - ExFreePoolWithTag(SecurityDescriptor, TAG_CM); + ExFreePoolWithTag(SecurityDescriptor, TAG_CMSD); /* Fill out the Hardware key with the ARC Data from the Loader */ Status = CmpInitializeHardwareConfiguration(KeLoaderBlock); @@ -1742,11 +1910,21 @@ CmGetSystemDriverList(VOID) /* Get the entry */ DriverEntry = CONTAINING_RECORD(NextEntry, BOOT_DRIVER_LIST_ENTRY, Link); - /* Allocate the path for the caller and duplicate the registry path */ + /* Allocate the path for the caller */ ServicePath[i] = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING)); - RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, - &DriverEntry->RegistryPath, - ServicePath[i]); + if (!ServicePath[i]) + { + KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0); + } + + /* Duplicate the registry path */ + Status = RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, + &DriverEntry->RegistryPath, + ServicePath[i]); + if (!NT_SUCCESS(Status)) + { + KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0); + } } /* Terminate the list */ @@ -1881,6 +2059,11 @@ CmpUnlockRegistry(VOID) CmpDoFlushAll(TRUE); CmpFlushOnLockRelease = FALSE; } + else + { + /* Lazy flush the registry */ + CmpLazyFlush(); + } /* Release the lock and leave the critical region */ ExReleaseResourceLite(&CmpRegistryLock); @@ -1929,14 +2112,14 @@ CmpReleaseTwoKcbLockByKey(IN ULONG ConvKey1, /* Get hash indexes */ Index1 = GET_HASH_INDEX(ConvKey1); Index2 = GET_HASH_INDEX(ConvKey2); - ASSERT((GET_HASH_ENTRY(CmpCacheTable, ConvKey2).Owner == KeGetCurrentThread()) || + ASSERT((GET_HASH_ENTRY(CmpCacheTable, ConvKey2)->Owner == KeGetCurrentThread()) || (CmpTestRegistryLockExclusive())); /* See which one is highest */ if (Index1 < Index2) { /* Grab them in the proper order */ - ASSERT((GET_HASH_ENTRY(CmpCacheTable, ConvKey1).Owner == KeGetCurrentThread()) || + ASSERT((GET_HASH_ENTRY(CmpCacheTable, ConvKey1)->Owner == KeGetCurrentThread()) || (CmpTestRegistryLockExclusive())); CmpReleaseKcbLockByKey(ConvKey2); CmpReleaseKcbLockByKey(ConvKey1); @@ -1946,7 +2129,7 @@ CmpReleaseTwoKcbLockByKey(IN ULONG ConvKey1, /* Release the first one first, then the second */ if (Index1 != Index2) { - ASSERT((GET_HASH_ENTRY(CmpCacheTable, ConvKey1).Owner == KeGetCurrentThread()) || + ASSERT((GET_HASH_ENTRY(CmpCacheTable, ConvKey1)->Owner == KeGetCurrentThread()) || (CmpTestRegistryLockExclusive())); CmpReleaseKcbLockByKey(ConvKey1); } @@ -1958,12 +2141,27 @@ VOID NTAPI CmShutdownSystem(VOID) { + PLIST_ENTRY ListEntry; + PCMHIVE Hive; + /* Kill the workers */ if (!CmFirstTime) CmpShutdownWorkers(); /* Flush all hives */ CmpLockRegistryExclusive(); CmpDoFlushAll(TRUE); + + /* Close all hive files */ + ListEntry = CmpHiveListHead.Flink; + while (ListEntry != &CmpHiveListHead) + { + Hive = CONTAINING_RECORD(ListEntry, CMHIVE, HiveList); + + CmpCloseHiveFiles(Hive); + + ListEntry = ListEntry->Flink; + } + CmpUnlockRegistry(); } @@ -1971,27 +2169,30 @@ VOID NTAPI CmpSetVersionData(VOID) { + NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; UNICODE_STRING ValueData; + ANSI_STRING TempString; HANDLE SoftwareKeyHandle = NULL; HANDLE MicrosoftKeyHandle = NULL; HANDLE WindowsNtKeyHandle = NULL; HANDLE CurrentVersionKeyHandle = NULL; - WCHAR Buffer[128]; - NTSTATUS Status; + WCHAR Buffer[128]; // Buffer large enough to contain a full ULONG in decimal + // representation, and the full 'CurrentType' string. - /* Open the 'CurrentVersion' key */ - RtlInitUnicodeString(&KeyName, - L"\\REGISTRY\\MACHINE\\SOFTWARE"); + /* + * Open the 'HKLM\Software\Microsoft\Windows NT\CurrentVersion' key + * (create the intermediate subkeys if needed). + */ + RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SOFTWARE"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, - OBJ_CASE_INSENSITIVE, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); - Status = NtCreateKey(&SoftwareKeyHandle, KEY_CREATE_SUB_KEY, &ObjectAttributes, @@ -2005,16 +2206,12 @@ CmpSetVersionData(VOID) return; } - /* Open the 'CurrentVersion' key */ - RtlInitUnicodeString(&KeyName, - L"Microsoft"); - + RtlInitUnicodeString(&KeyName, L"Microsoft"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, - OBJ_CASE_INSENSITIVE, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, SoftwareKeyHandle, NULL); - Status = NtCreateKey(&MicrosoftKeyHandle, KEY_CREATE_SUB_KEY, &ObjectAttributes, @@ -2025,19 +2222,15 @@ CmpSetVersionData(VOID) if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status); - goto done; + goto Quit; } - /* Open the 'CurrentVersion' key */ - RtlInitUnicodeString(&KeyName, - L"Windows NT"); - + RtlInitUnicodeString(&KeyName, L"Windows NT"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, - OBJ_CASE_INSENSITIVE, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, MicrosoftKeyHandle, NULL); - Status = NtCreateKey(&WindowsNtKeyHandle, KEY_CREATE_SUB_KEY, &ObjectAttributes, @@ -2048,19 +2241,15 @@ CmpSetVersionData(VOID) if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status); - goto done; + goto Quit; } - /* Open the 'CurrentVersion' key */ - RtlInitUnicodeString(&KeyName, - L"CurrentVersion"); - + RtlInitUnicodeString(&KeyName, L"CurrentVersion"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, - OBJ_CASE_INSENSITIVE, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, WindowsNtKeyHandle, NULL); - Status = NtCreateKey(&CurrentVersionKeyHandle, KEY_CREATE_SUB_KEY | KEY_SET_VALUE, &ObjectAttributes, @@ -2071,30 +2260,60 @@ CmpSetVersionData(VOID) if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status); - goto done; + goto Quit; } - /* Set the 'CurrentType' value */ - RtlInitUnicodeString(&ValueName, - L"CurrentType"); + /* Set the 'CurrentVersion' value */ + RtlInitUnicodeString(&ValueName, L"CurrentVersion"); + NtSetValueKey(CurrentVersionKeyHandle, + &ValueName, + 0, + REG_SZ, + CmVersionString.Buffer, + CmVersionString.Length + sizeof(WCHAR)); + /* Set the 'CurrentBuildNumber' value */ + RtlInitUnicodeString(&ValueName, L"CurrentBuildNumber"); + RtlInitEmptyUnicodeString(&ValueData, Buffer, sizeof(Buffer)); + RtlIntegerToUnicodeString(NtBuildNumber & 0xFFFF, 10, &ValueData); + NtSetValueKey(CurrentVersionKeyHandle, + &ValueName, + 0, + REG_SZ, + ValueData.Buffer, + ValueData.Length + sizeof(WCHAR)); + + /* Set the 'BuildLab' value */ + RtlInitUnicodeString(&ValueName, L"BuildLab"); + RtlInitAnsiString(&TempString, NtBuildLab); + Status = RtlAnsiStringToUnicodeString(&ValueData, &TempString, FALSE); + if (NT_SUCCESS(Status)) + { + NtSetValueKey(CurrentVersionKeyHandle, + &ValueName, + 0, + REG_SZ, + ValueData.Buffer, + ValueData.Length + sizeof(WCHAR)); + } + + /* Set the 'CurrentType' value */ + RtlInitUnicodeString(&ValueName, L"CurrentType"); + RtlStringCbPrintfW(Buffer, sizeof(Buffer), + L"%s %s", #ifdef CONFIG_SMP - wcscpy(Buffer, L"Multiprocessor"); + L"Multiprocessor" #else - wcscpy(Buffer, L"Uniprocessor"); + L"Uniprocessor" #endif - - wcscat(Buffer, L" "); - + , #if (DBG == 1) - wcscat(Buffer, L"Checked"); + L"Checked" #else - wcscat(Buffer, L"Free"); + L"Free" #endif - - RtlInitUnicodeString(&ValueData, - Buffer); - + ); + RtlInitUnicodeString(&ValueData, Buffer); NtSetValueKey(CurrentVersionKeyHandle, &ValueName, 0, @@ -2102,7 +2321,50 @@ CmpSetVersionData(VOID) ValueData.Buffer, ValueData.Length + sizeof(WCHAR)); -done:; + /* Set the 'CSDVersion' value */ + RtlInitUnicodeString(&ValueName, L"CSDVersion"); + if (CmCSDVersionString.Length != 0) + { + NtSetValueKey(CurrentVersionKeyHandle, + &ValueName, + 0, + REG_SZ, + CmCSDVersionString.Buffer, + CmCSDVersionString.Length + sizeof(WCHAR)); + } + else + { + NtDeleteValueKey(CurrentVersionKeyHandle, &ValueName); + } + + /* Set the 'CSDBuildNumber' value */ + RtlInitUnicodeString(&ValueName, L"CSDBuildNumber"); + if (CmNtSpBuildNumber != 0) + { + RtlInitEmptyUnicodeString(&ValueData, Buffer, sizeof(Buffer)); + RtlIntegerToUnicodeString(CmNtSpBuildNumber, 10, &ValueData); + NtSetValueKey(CurrentVersionKeyHandle, + &ValueName, + 0, + REG_SZ, + ValueData.Buffer, + ValueData.Length + sizeof(WCHAR)); + } + else + { + NtDeleteValueKey(CurrentVersionKeyHandle, &ValueName); + } + + /* Set the 'SystemRoot' value */ + RtlInitUnicodeString(&ValueName, L"SystemRoot"); + NtSetValueKey(CurrentVersionKeyHandle, + &ValueName, + 0, + REG_SZ, + NtSystemRoot.Buffer, + NtSystemRoot.Length + sizeof(WCHAR)); + +Quit: /* Close the keys */ if (CurrentVersionKeyHandle != NULL) NtClose(CurrentVersionKeyHandle);