BOOLEAN CmpNoWrite;
BOOLEAN CmpWasSetupBoot;
BOOLEAN CmpProfileLoaded;
+BOOLEAN CmpNoVolatileCreates;
ULONG CmpTraceLevel = 0;
extern LONG CmpFlushStarveWriters;
BOOLEAN
NTAPI
CmpLinkKeyToHive(
- _In_z_ PWSTR LinkKeyName,
- _In_z_ PWSTR TargetKeyName)
+ _In_z_ PCWSTR LinkKeyName,
+ _In_z_ PCWSTR TargetKeyName)
{
+ NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING LinkKeyName_U;
- HANDLE TargetKeyHandle;
+ UNICODE_STRING KeyName;
+ HANDLE LinkKeyHandle;
ULONG Disposition;
- NTSTATUS Status;
+
PAGED_CODE();
/* Initialize the object attributes */
- RtlInitUnicodeString(&LinkKeyName_U, LinkKeyName);
+ RtlInitUnicodeString(&KeyName, LinkKeyName);
InitializeObjectAttributes(&ObjectAttributes,
- &LinkKeyName_U,
+ &KeyName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
/* Create the link key */
- Status = ZwCreateKey(&TargetKeyHandle,
+ Status = ZwCreateKey(&LinkKeyHandle,
KEY_CREATE_LINK,
&ObjectAttributes,
0,
&Disposition);
if (!NT_SUCCESS(Status))
{
- DPRINT1("CM: CmpLinkKeyToHive: couldn't create %S Status = 0x%lx\n",
+ DPRINT1("CM: CmpLinkKeyToHive: couldn't create %S, Status = 0x%lx\n",
LinkKeyName, Status);
return FALSE;
}
if (Disposition != REG_CREATED_NEW_KEY)
{
DPRINT1("CM: CmpLinkKeyToHive: %S already exists!\n", LinkKeyName);
- ZwClose(TargetKeyHandle);
+ ZwClose(LinkKeyHandle);
return FALSE;
}
/* Set the target key name as link target */
- Status = ZwSetValueKey(TargetKeyHandle,
+ RtlInitUnicodeString(&KeyName, TargetKeyName);
+ Status = ZwSetValueKey(LinkKeyHandle,
&CmSymbolicLinkValueName,
0,
REG_LINK,
- TargetKeyName,
- wcslen(TargetKeyName) * sizeof(WCHAR));
+ KeyName.Buffer,
+ KeyName.Length);
/* Close the link key handle */
- ObCloseHandle(TargetKeyHandle, KernelMode);
+ ObCloseHandle(LinkKeyHandle, KernelMode);
if (!NT_SUCCESS(Status))
{
- DPRINT1("CM: CmpLinkKeyToHive: couldn't create symbolic link for %S\n",
- TargetKeyName);
+ DPRINT1("CM: CmpLinkKeyToHive: couldn't create symbolic link for %S, Status = 0x%lx\n",
+ TargetKeyName, Status);
return FALSE;
}
BytesToCopy);
/* Null terminate it */
- ObjectNameInfo->Name.Buffer[BytesToCopy / sizeof(WCHAR)] = 0;
+ ObjectNameInfo->Name.Buffer[BytesToCopy / sizeof(WCHAR)] = UNICODE_NULL;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
/* Initialize the hive */
- Status = CmpInitializeHive((PCMHIVE*)&NewHive,
+ Status = CmpInitializeHive(&NewHive,
Operation,
HiveFlags,
FileType,
/* Success, return hive */
*Hive = NewHive;
- /* HACK: 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,
HiveName->Buffer,
HiveName->Length);
NewHive->FileFullPath.Length = HiveName->Length;
- NewHive->FileFullPath.MaximumLength = HiveName->MaximumLength;
+ NewHive->FileFullPath.MaximumLength = HiveName->Length;
}
/* Return success */
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 */
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,
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,
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");
+
+ /* 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 the status */
- return (ExpInTextModeSetup ? STATUS_SUCCESS : Status);
+ return Status;
}
NTSTATUS
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,
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,
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,
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);
+ /* 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;
+ /* 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;
+ /* 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,
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,
if (!NT_SUCCESS (Status))
{
/* Cleanup and exit */
- ProfileHandle = 0;
+ Status = STATUS_SUCCESS;
goto Cleanup;
}
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,
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
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 */
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 */
- 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 */
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;
{
UNICODE_STRING KeyName;
PCM_KEY_NODE KeyCell;
- LARGE_INTEGER SystemTime;
PAGED_CODE();
/* Initialize the node name and allocate it */
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;
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);
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
- NULL);
+ SecurityDescriptor);
Status = ObCreateObject(KernelMode,
CmpKeyObjectType,
&ObjectAttributes,
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 */
return TRUE;
}
-NTSTATUS
-NTAPI
-CmpGetRegistryPath(IN PWCHAR ConfigPath)
+static NTSTATUS
+CmpGetRegistryPath(OUT PWCHAR ConfigPath)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- NTSTATUS Status;
- HANDLE KeyHandle;
- PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
- UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE");
- UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"InstallPath");
- ULONG BufferSize, ResultSize;
+ /* Just use default path */
+ wcscpy(ConfigPath, L"\\SystemRoot");
/* Check if we are booted in setup */
- if (ExpInTextModeSetup)
+ if (!ExpInTextModeSetup)
{
- /* Setup the object attributes */
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- /* Open the key */
- Status = ZwOpenKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Allocate the buffer */
- BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;
- ValueInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_CM);
- if (!ValueInfo)
- {
- /* Fail */
- ZwClose(KeyHandle);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Query the value */
- Status = ZwQueryValueKey(KeyHandle,
- &ValueName,
- KeyValuePartialInformation,
- ValueInfo,
- BufferSize,
- &ResultSize);
- ZwClose(KeyHandle);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- ExFreePoolWithTag(ValueInfo, TAG_CM);
- return Status;
- }
-
- /* Copy the config path and null-terminate it */
- RtlCopyMemory(ConfigPath,
- ValueInfo->Data,
- ValueInfo->DataLength);
- ConfigPath[ValueInfo->DataLength / sizeof(WCHAR)] = UNICODE_NULL;
- ExFreePoolWithTag(ValueInfo, TAG_CM);
+ /* Add registry path */
+#if 0
+ ResultSize = wcslen(ConfigPath);
+ if (ResultSize && ConfigPath[ResultSize - 1] == L'\\')
+ ConfigPath[ResultSize - 1] = UNICODE_NULL;
+#endif
+ wcscat(ConfigPath, L"\\System32\\Config\\");
}
else
{
- /* Just use default path */
- wcscpy(ConfigPath, L"\\SystemRoot");
+ wcscat(ConfigPath, L"\\");
}
- /* 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)
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;
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 */
&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,
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);
VOID
NTAPI
-CmpInitializeHiveList(IN USHORT Flag)
+CmpInitializeHiveList(VOID)
{
WCHAR FileBuffer[MAX_PATH], RegBuffer[MAX_PATH], ConfigPath[MAX_PATH];
UNICODE_STRING TempName, FileName, RegName;
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 */
/* 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,
/* 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 */
}
/* Get rid of the SD */
- ExFreePoolWithTag(SecurityDescriptor, TAG_CM);
+ ExFreePoolWithTag(SecurityDescriptor, TAG_CMSD);
/* Link SECURITY to SAM */
CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM",
L"\\Registry\\Machine\\SAM\\SAM");
/* Link S-1-5-18 to .Default */
+ CmpNoVolatileCreates = FALSE;
CmpLinkKeyToHive(L"\\Registry\\User\\S-1-5-18",
L"\\Registry\\User\\.Default");
+ CmpNoVolatileCreates = TRUE;
}
BOOLEAN
}
/* Build the master hive */
- Status = CmpInitializeHive((PCMHIVE*)&CmiVolatileHive,
+ Status = CmpInitializeHive(&CmiVolatileHive,
HINIT_CREATE,
HIVE_VOLATILE,
HFILE_TYPE_PRIMARY,
/* Create the default security descriptor */
SecurityDescriptor = CmpHiveRootSecurityDescriptor();
- /* Create '\Registry\Machine' key. */
+ /* Create '\Registry\Machine' key */
RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
/* Close the handle */
NtClose(KeyHandle);
- /* Create '\Registry\User' key. */
+ /* Create '\Registry\User' key */
RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\USER");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
/* 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))
{
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 7, 0, 0);
}
- /* Create the 'CurrentControlSet' link. */
+ /* Create the 'CurrentControlSet' link */
Status = CmpCreateControlSet(KeLoaderBlock);
if (!NT_SUCCESS(Status))
{
}
/* Create the hardware hive */
- Status = CmpInitializeHive((PCMHIVE*)&HardwareHive,
+ Status = CmpInitializeHive(&HardwareHive,
HINIT_CREATE,
HIVE_VOLATILE,
HFILE_TYPE_PRIMARY,
}
/* 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))
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);
/* 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 */
/* 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);
/* 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);
}
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();
}
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,
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,
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,
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,
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,
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);