/* FUNCTIONS ******************************************************************/
+BOOLEAN
+NTAPI
+CmpLinkKeyToHive(
+ _In_z_ PWSTR LinkKeyName,
+ _In_z_ PWSTR TargetKeyName)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING LinkKeyName_U;
+ HANDLE TargetKeyHandle;
+ ULONG Disposition;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Initialize the object attributes */
+ RtlInitUnicodeString(&LinkKeyName_U, LinkKeyName);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkKeyName_U,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ /* Create the link key */
+ Status = ZwCreateKey(&TargetKeyHandle,
+ 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(TargetKeyHandle);
+ return FALSE;
+ }
+
+ /* Set the target key name as link target */
+ Status = ZwSetValueKey(TargetKeyHandle,
+ &CmSymbolicLinkValueName,
+ 0,
+ REG_LINK,
+ TargetKeyName,
+ wcslen(TargetKeyName) * sizeof(WCHAR));
+
+ /* Close the link key handle */
+ ObCloseHandle(TargetKeyHandle, KernelMode);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CM: CmpLinkKeyToHive: couldn't create symbolic link for %S\n",
+ TargetKeyName);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
VOID
NTAPI
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;
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;
IN KPROCESSOR_MODE PreviousMode)
{
PUNICODE_STRING KeyName;
+ ULONG BytesToCopy;
NTSTATUS Status = STATUS_SUCCESS;
PCM_KEY_BODY KeyBody = (PCM_KEY_BODY)ObjectBody;
PCM_KEY_CONTROL_BLOCK Kcb = KeyBody->KeyControlBlock;
/* Set the returned length */
*ReturnLength = KeyName->Length + sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR);
- /* Check if it fits into the provided buffer */
- if ((Length < sizeof(OBJECT_NAME_INFORMATION)) ||
- (Length < (*ReturnLength - sizeof(OBJECT_NAME_INFORMATION))))
+ /* Calculate amount of bytes to copy into the buffer */
+ BytesToCopy = KeyName->Length + sizeof(WCHAR);
+
+ /* Check if the provided buffer is too small to fit even anything */
+ if ((Length <= sizeof(OBJECT_NAME_INFORMATION)) ||
+ ((Length < (*ReturnLength)) && (BytesToCopy < sizeof(WCHAR))))
{
/* Free the buffer allocated by CmpConstructName */
- ExFreePool(KeyName);
+ ExFreePoolWithTag(KeyName, TAG_CM);
- /* Return buffer length failure */
+ /* Return buffer length failure without writing anything there because nothing fits */
return STATUS_INFO_LENGTH_MISMATCH;
}
+ /* Check if the provided buffer can be partially written */
+ if (Length < (*ReturnLength))
+ {
+ /* Yes, indicate so in the return status */
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+
+ /* Calculate amount of bytes which the provided buffer could handle */
+ BytesToCopy = Length - sizeof(OBJECT_NAME_INFORMATION);
+ }
+
+ /* Remove the null termination character from the size */
+ BytesToCopy -= sizeof(WCHAR);
+
/* Fill in the result */
_SEH2_TRY
{
/* Copy string content*/
RtlCopyMemory(ObjectNameInfo->Name.Buffer,
KeyName->Buffer,
- *ReturnLength);
+ BytesToCopy);
+
+ /* Null terminate it */
+ ObjectNameInfo->Name.Buffer[BytesToCopy / sizeof(WCHAR)] = 0;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_END;
/* Free the buffer allocated by CmpConstructName */
- ExFreePool(KeyName);
+ ExFreePoolWithTag(KeyName, TAG_CM);
/* Return status */
return Status;
LogHandle,
NULL,
HiveName,
- 0);
+ CheckFlags);
if (!NT_SUCCESS(Status))
{
/* Fail */
/* Success, return hive */
*Hive = NewHive;
- /* ROS: Init root key cell and prepare the hive */
+ /* HACK: ROS: Init root key cell and prepare the hive */
if (Operation == HINIT_CREATE) CmCreateRootNode(&NewHive->Hive, L"");
/* Duplicate the hive name */
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName, ValueName = { 0, 0, NULL };
- HANDLE KeyHandle;
+ HANDLE KeyHandle = NULL;
NTSTATUS Status;
ASSERT(LoaderBlock != NULL);
CmpLoadOptions.Length);
if (!NT_SUCCESS(Status)) goto Quickie;
- /* Setup value name for system boot device */
+ /* Setup value name for system boot device in ARC format */
RtlInitUnicodeString(&KeyName, L"SystemBootDevice");
- RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->NtBootPathName);
+ RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->ArcBootDeviceName);
Status = NtSetValueKey(KeyHandle,
&KeyName,
0,
RtlFreeUnicodeString(&ValueName);
/* Close the key and return */
- NtClose(KeyHandle);
+ if (KeyHandle) NtClose(KeyHandle);
/* Return the status */
return (ExpInTextModeSetup ? STATUS_SUCCESS : Status);
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 */
if (HiveBase)
{
/* Import it */
- ((PHBASE_BLOCK)HiveBase)->Length = LoaderBlock->RegistryLength;
Status = CmpInitializeHive((PCMHIVE*)&SystemHive,
HINIT_MEMORY,
HIVE_NOLAZYFLUSH,
ObjectTypeInitializer.QueryNameProcedure = CmpQueryKeyName;
ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject;
ObjectTypeInitializer.SecurityRequired = TRUE;
+ ObjectTypeInitializer.InvalidAttributes = OBJ_EXCLUSIVE | OBJ_PERMANENT;
/* Create it */
return ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmpKeyObjectType);
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();
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,
KernelMode,
(PVOID*)&RootKey,
NULL);
- if (!NT_SUCCESS(Status)) return FALSE;
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(RootKey);
+ return FALSE;
+ }
/* Completely sucessful */
return TRUE;
{
WCHAR FileBuffer[MAX_PATH], RegBuffer[MAX_PATH], ConfigPath[MAX_PATH];
UNICODE_STRING TempName, FileName, RegName;
- ULONG FileStart, RegStart, i, ErrorResponse, WorkerCount, Length;
+ ULONG i, ErrorResponse, WorkerCount, Length;
+ USHORT FileStart;
+ //ULONG RegStart;
ULONG PrimaryDisposition, SecondaryDisposition, ClusterSize;
PCMHIVE CmHive;
- HANDLE PrimaryHandle, LogHandle;
+ HANDLE PrimaryHandle = NULL, LogHandle = NULL;
NTSTATUS Status = STATUS_SUCCESS;
PVOID ErrorParameters;
PAGED_CODE();
/* And build the registry root path */
RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
- RegStart = RegName.Length;
+ //RegStart = RegName.Length;
/* Build the base name */
- RegName.Length = RegStart;
RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
UNICODE_STRING TempName, FileName, RegName;
HANDLE Thread;
NTSTATUS Status;
- ULONG RegStart, i;
+ ULONG i;
+ USHORT RegStart;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PAGED_CODE();
/* Check if we created a new hive */
if (CmpMachineHiveList[i].CmHive2)
{
- /* TODO: Add to HiveList key */
+ /* Add to HiveList key */
+ CmpAddToHiveFileList(CmpMachineHiveList[i].CmHive2);
}
}
/* Get rid of the SD */
ExFreePoolWithTag(SecurityDescriptor, TAG_CM);
- /* 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 */
+ CmpLinkKeyToHive(L"\\Registry\\User\\S-1-5-18",
+ L"\\Registry\\User\\.Default");
}
BOOLEAN
/* Initialize the hive list and lock */
InitializeListHead(&CmpHiveListHead);
- ExInitializePushLock((PVOID)&CmpHiveListHeadLock);
- ExInitializePushLock((PVOID)&CmpLoadHiveLock);
+ ExInitializePushLock(&CmpHiveListHeadLock);
+ ExInitializePushLock(&CmpLoadHiveLock);
/* Initialize registry lock */
ExInitializeResourceLite(&CmpRegistryLock);
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0);
}
- /* FIXME: Add to HiveList key */
+ /* Add to HiveList key */
+ CmpAddToHiveFileList(HardwareHive);
/* Free the security descriptor */
ExFreePoolWithTag(SecurityDescriptor, TAG_CM);
PLIST_ENTRY NextEntry, OldEntry;
PBOOT_DRIVER_NODE DriverNode;
PAGED_CODE();
-
+
/* Parse the current list */
NextEntry = DriverList->Flink;
while (NextEntry != DriverList)
{
/* Get the driver node */
DriverNode = CONTAINING_RECORD(NextEntry, BOOT_DRIVER_NODE, ListEntry.Link);
-
+
/* Get the next entry now, since we're going to free it later */
OldEntry = NextEntry;
NextEntry = NextEntry->Flink;
-
+
/* Was there a name? */
if (DriverNode->Name.Buffer)
{
/* Free it */
CmpFree(DriverNode->Name.Buffer, DriverNode->Name.Length);
}
-
+
/* Was there a registry path? */
if (DriverNode->ListEntry.RegistryPath.Buffer)
{
/* Free it */
- CmpFree(DriverNode->ListEntry.RegistryPath.Buffer,
+ CmpFree(DriverNode->ListEntry.RegistryPath.Buffer,
DriverNode->ListEntry.RegistryPath.MaximumLength);
}
-
+
/* Was there a file path? */
if (DriverNode->ListEntry.FilePath.Buffer)
{
CmpFree(DriverNode->ListEntry.FilePath.Buffer,
DriverNode->ListEntry.FilePath.MaximumLength);
}
-
+
/* Now free the node, and move on */
CmpFree(OldEntry, sizeof(BOOT_DRIVER_NODE));
}
/* Initialize the driver list */
InitializeListHead(&DriverList);
-
+
/* Open the system hive key */
RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System");
InitializeObjectAttributes(&ObjectAttributes,
NULL);
Status = NtOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
if (!NT_SUCCESS(Status)) return NULL;
-
+
/* Reference the key object to get the root hive/cell to access directly */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
NtClose(KeyHandle);
return NULL;
}
-
+
/* Do all this under the registry lock */
CmpLockRegistryExclusive();
-
+
/* Get the hive and key cell */
Hive = KeyBody->KeyControlBlock->KeyHive;
RootCell = KeyBody->KeyControlBlock->KeyCell;
-
+
/* Open the current control set key */
RtlInitUnicodeString(&KeyName, L"Current");
ControlCell = CmpFindControlSet(Hive, RootCell, &KeyName, &AutoSelect);
if (ControlCell == HCELL_NIL) goto EndPath;
-
+
/* Find all system drivers */
Success = CmpFindDrivers(Hive, ControlCell, SystemLoad, NULL, &DriverList);
if (!Success) goto EndPath;
-
+
/* Sort by group/tag */
if (!CmpSortDriverList(Hive, ControlCell, &DriverList)) goto EndPath;
-
+
/* Remove circular dependencies (cycles) and sort */
if (!CmpResolveDriverDependencies(&DriverList)) goto EndPath;
-
+
/* Loop the list to count drivers */
for (i = 0, NextEntry = DriverList.Flink;
NextEntry != &DriverList;
i++, NextEntry = NextEntry->Flink);
-
+
/* Allocate the array */
ServicePath = ExAllocatePool(NonPagedPool, (i + 1) * sizeof(PUNICODE_STRING));
if (!ServicePath) KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
-
+
/* Loop the driver list */
for (i = 0, NextEntry = DriverList.Flink;
NextEntry != &DriverList;
&DriverEntry->RegistryPath,
ServicePath[i]);
}
-
+
/* Terminate the list */
ServicePath[i] = NULL;
-
+
EndPath:
/* Free the driver list if we had one */
if (!IsListEmpty(&DriverList)) CmpFreeDriverList(Hive, &DriverList);
-
+
/* Unlock the registry */
CmpUnlockRegistry();
-
+
/* Close the key handle and dereference the object, then return the path */
ObDereferenceObject(KeyBody);
NtClose(KeyHandle);
CmpDoFlushAll(TRUE);
CmpFlushOnLockRelease = FALSE;
}
+ else
+ {
+ /* Lazy flush the registry */
+ CmpLazyFlush();
+ }
/* Release the lock and leave the critical region */
ExReleaseResourceLite(&CmpRegistryLock);
NTAPI
CmShutdownSystem(VOID)
{
- /* Kill the workers and flush all hives */
+ /* Kill the workers */
if (!CmFirstTime) CmpShutdownWorkers();
+
+ /* Flush all hives */
+ CmpLockRegistryExclusive();
CmpDoFlushAll(TRUE);
+ CmpUnlockRegistry();
+}
+
+VOID
+NTAPI
+CmpSetVersionData(VOID)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyName;
+ UNICODE_STRING ValueName;
+ UNICODE_STRING ValueData;
+ HANDLE SoftwareKeyHandle = NULL;
+ HANDLE MicrosoftKeyHandle = NULL;
+ HANDLE WindowsNtKeyHandle = NULL;
+ HANDLE CurrentVersionKeyHandle = NULL;
+ WCHAR Buffer[128];
+ NTSTATUS Status;
+
+ /* Open the 'CurrentVersion' key */
+ RtlInitUnicodeString(&KeyName,
+ L"\\REGISTRY\\MACHINE\\SOFTWARE");
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtCreateKey(&SoftwareKeyHandle,
+ KEY_CREATE_SUB_KEY,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
+ return;
+ }
+
+ /* Open the 'CurrentVersion' key */
+ RtlInitUnicodeString(&KeyName,
+ L"Microsoft");
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ SoftwareKeyHandle,
+ NULL);
+
+ Status = NtCreateKey(&MicrosoftKeyHandle,
+ KEY_CREATE_SUB_KEY,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
+ goto done;
+ }
+
+ /* Open the 'CurrentVersion' key */
+ RtlInitUnicodeString(&KeyName,
+ L"Windows NT");
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ MicrosoftKeyHandle,
+ NULL);
+
+ Status = NtCreateKey(&WindowsNtKeyHandle,
+ KEY_CREATE_SUB_KEY,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
+ goto done;
+ }
+
+ /* Open the 'CurrentVersion' key */
+ RtlInitUnicodeString(&KeyName,
+ L"CurrentVersion");
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ WindowsNtKeyHandle,
+ NULL);
+
+ Status = NtCreateKey(&CurrentVersionKeyHandle,
+ KEY_CREATE_SUB_KEY | KEY_SET_VALUE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
+ goto done;
+ }
+
+ /* Set the 'CurrentType' value */
+ RtlInitUnicodeString(&ValueName,
+ L"CurrentType");
+
+#ifdef CONFIG_SMP
+ wcscpy(Buffer, L"Multiprocessor");
+#else
+ wcscpy(Buffer, L"Uniprocessor");
+#endif
+
+ wcscat(Buffer, L" ");
+
+#if (DBG == 1)
+ wcscat(Buffer, L"Checked");
+#else
+ wcscat(Buffer, L"Free");
+#endif
+
+ RtlInitUnicodeString(&ValueData,
+ Buffer);
+
+ NtSetValueKey(CurrentVersionKeyHandle,
+ &ValueName,
+ 0,
+ REG_SZ,
+ ValueData.Buffer,
+ ValueData.Length + sizeof(WCHAR));
+
+done:;
+ /* Close the keys */
+ if (CurrentVersionKeyHandle != NULL)
+ NtClose(CurrentVersionKeyHandle);
+
+ if (WindowsNtKeyHandle != NULL)
+ NtClose(WindowsNtKeyHandle);
+
+ if (MicrosoftKeyHandle != NULL)
+ NtClose(MicrosoftKeyHandle);
+
+ if (SoftwareKeyHandle != NULL)
+ NtClose(SoftwareKeyHandle);
}
/* EOF */