X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fconfig%2Fcmsysini.c;h=45242d28388c8eda7a7e861c6a9483a58aead6eb;hp=3587efe73262908d327ac86789b93944a58f0784;hb=527f2f90577662e8eba1b1b62f958c39b3cd4358;hpb=0372821ca059f3cb4916834e0650c83ca0daa951 diff --git a/ntoskrnl/config/cmsysini.c b/ntoskrnl/config/cmsysini.c index 3587efe7326..45242d28388 100644 --- a/ntoskrnl/config/cmsysini.c +++ b/ntoskrnl/config/cmsysini.c @@ -36,6 +36,71 @@ extern BOOLEAN CmFirstTime; /* 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) @@ -121,6 +186,7 @@ CmpQueryKeyName(IN PVOID ObjectBody, 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; @@ -155,17 +221,33 @@ CmpQueryKeyName(IN PVOID ObjectBody, /* 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 { @@ -177,7 +259,10 @@ CmpQueryKeyName(IN PVOID ObjectBody, /* 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) { @@ -187,7 +272,7 @@ CmpQueryKeyName(IN PVOID ObjectBody, _SEH2_END; /* Free the buffer allocated by CmpConstructName */ - ExFreePool(KeyName); + ExFreePoolWithTag(KeyName, TAG_CM); /* Return status */ return Status; @@ -308,11 +393,12 @@ CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName, NTSTATUS NTAPI +INIT_FUNCTION CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName, ValueName = { 0, 0, NULL }; - HANDLE KeyHandle; + HANDLE KeyHandle = NULL; NTSTATUS Status; ASSERT(LoaderBlock != NULL); @@ -338,9 +424,9 @@ CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 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, @@ -353,7 +439,7 @@ Quickie: RtlFreeUnicodeString(&ValueName); /* Close the key and return */ - NtClose(KeyHandle); + if (KeyHandle) NtClose(KeyHandle); /* Return the status */ return (ExpInTextModeSetup ? STATUS_SUCCESS : Status); @@ -361,6 +447,7 @@ Quickie: NTSTATUS NTAPI +INIT_FUNCTION CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { UNICODE_STRING ConfigName = RTL_CONSTANT_STRING(L"Control\\IDConfigDB"); @@ -562,7 +649,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 */ @@ -689,6 +776,7 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, BOOLEAN NTAPI +INIT_FUNCTION CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { PVOID HiveBase; @@ -728,7 +816,6 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) if (HiveBase) { /* Import it */ - ((PHBASE_BLOCK)HiveBase)->Length = LoaderBlock->RegistryLength; Status = CmpInitializeHive((PCMHIVE*)&SystemHive, HINIT_MEMORY, HIVE_NOLAZYFLUSH, @@ -817,6 +904,7 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) NTSTATUS NTAPI +INIT_FUNCTION CmpCreateObjectTypes(VOID) { OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; @@ -842,6 +930,7 @@ CmpCreateObjectTypes(VOID) ObjectTypeInitializer.QueryNameProcedure = CmpQueryKeyName; ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject; ObjectTypeInitializer.SecurityRequired = TRUE; + ObjectTypeInitializer.InvalidAttributes = OBJ_EXCLUSIVE | OBJ_PERMANENT; /* Create it */ return ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmpKeyObjectType); @@ -849,6 +938,7 @@ CmpCreateObjectTypes(VOID) BOOLEAN NTAPI +INIT_FUNCTION CmpCreateRootNode(IN PHHIVE Hive, IN PCWSTR Name, OUT PHCELL_INDEX Index) @@ -909,6 +999,7 @@ CmpCreateRootNode(IN PHHIVE Hive, BOOLEAN NTAPI +INIT_FUNCTION CmpCreateRegistryRoot(VOID) { UNICODE_STRING KeyName; @@ -1072,10 +1163,12 @@ CmpLoadHiveThread(IN PVOID StartContext) { 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(); @@ -1100,10 +1193,9 @@ CmpLoadHiveThread(IN PVOID StartContext) /* 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); @@ -1194,6 +1286,7 @@ CmpLoadHiveThread(IN PVOID StartContext) if (CmHive->Hive.Cluster != ClusterSize) ASSERT(FALSE); /* Set the file size */ + DPRINT("FIXME: Should set file size: %lx\n", Length); //if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length)) { /* This shouldn't fail */ @@ -1232,7 +1325,8 @@ CmpInitializeHiveList(IN USHORT Flag) UNICODE_STRING TempName, FileName, RegName; HANDLE Thread; NTSTATUS Status; - ULONG FileStart, RegStart, i; + ULONG i; + USHORT RegStart; PSECURITY_DESCRIPTOR SecurityDescriptor; PAGED_CODE(); @@ -1247,7 +1341,6 @@ CmpInitializeHiveList(IN USHORT Flag) CmpGetRegistryPath(ConfigPath); RtlInitUnicodeString(&TempName, ConfigPath); RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName); - FileStart = FileName.Length; /* And build the registry root path */ RtlInitUnicodeString(&TempName, L"\\REGISTRY\\"); @@ -1352,20 +1445,26 @@ CmpInitializeHiveList(IN USHORT Flag) /* 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 NTAPI +INIT_FUNCTION CmInitSystem1(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; @@ -1386,8 +1485,8 @@ CmInitSystem1(VOID) /* Initialize the hive list and lock */ InitializeListHead(&CmpHiveListHead); - ExInitializePushLock((PVOID)&CmpHiveListHeadLock); - ExInitializePushLock((PVOID)&CmpLoadHiveLock); + ExInitializePushLock(&CmpHiveListHeadLock); + ExInitializePushLock(&CmpLoadHiveLock); /* Initialize registry lock */ ExInitializeResourceLite(&CmpRegistryLock); @@ -1539,7 +1638,8 @@ CmInitSystem1(VOID) 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); @@ -1577,39 +1677,40 @@ CmInitSystem1(VOID) VOID NTAPI +INIT_FUNCTION CmpFreeDriverList(IN PHHIVE Hive, IN PLIST_ENTRY DriverList) { 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) { @@ -1617,7 +1718,7 @@ CmpFreeDriverList(IN PHHIVE Hive, CmpFree(DriverNode->ListEntry.FilePath.Buffer, DriverNode->ListEntry.FilePath.MaximumLength); } - + /* Now free the node, and move on */ CmpFree(OldEntry, sizeof(BOOT_DRIVER_NODE)); } @@ -1625,6 +1726,7 @@ CmpFreeDriverList(IN PHHIVE Hive, PUNICODE_STRING* NTAPI +INIT_FUNCTION CmGetSystemDriverList(VOID) { LIST_ENTRY DriverList; @@ -1644,7 +1746,7 @@ CmGetSystemDriverList(VOID) /* Initialize the driver list */ InitializeListHead(&DriverList); - + /* Open the system hive key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System"); InitializeObjectAttributes(&ObjectAttributes, @@ -1654,7 +1756,7 @@ CmGetSystemDriverList(VOID) 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, @@ -1668,38 +1770,38 @@ CmGetSystemDriverList(VOID) 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; @@ -1714,17 +1816,17 @@ CmGetSystemDriverList(VOID) &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); @@ -1847,6 +1949,11 @@ CmpUnlockRegistry(VOID) CmpDoFlushAll(TRUE); CmpFlushOnLockRelease = FALSE; } + else + { + /* Lazy flush the registry */ + CmpLazyFlush(); + } /* Release the lock and leave the critical region */ ExReleaseResourceLite(&CmpRegistryLock); @@ -1924,9 +2031,163 @@ VOID 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 */