IoRegisterDeviceInterface: Create nested keys one-by-one. Modified: trunk/reactos/ntoskrnl/io/deviface.c _____
Modified: trunk/reactos/ntoskrnl/io/deviface.c --- trunk/reactos/ntoskrnl/io/deviface.c 2005-05-21 17:49:58 UTC (rev 15464) +++ trunk/reactos/ntoskrnl/io/deviface.c 2005-05-21 19:00:42 UTC (rev 15465) @@ -573,11 +573,13 @@
PUNICODE_STRING InstancePath; UNICODE_STRING GuidString; UNICODE_STRING SubKeyName; + UNICODE_STRING InterfaceKeyName; UNICODE_STRING BaseKeyName; UCHAR PdoNameInfoBuffer[sizeof(OBJECT_NAME_INFORMATION) + (256 * sizeof(WCHAR))]; POBJECT_NAME_INFORMATION PdoNameInfo = (POBJECT_NAME_INFORMATION)PdoNameInfoBuffer; UNICODE_STRING DeviceInstance = RTL_CONSTANT_STRING(L"DeviceInstance"); UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink"); + HANDLE ClassKey; HANDLE InterfaceKey; HANDLE SubKey; ULONG StartIndex; @@ -611,15 +613,11 @@ } ASSERT(PdoNameInfo->Name.Length);
- /* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\DeviceClasses{GUID}##?#ACPI#PNP0501#1#{G UID} */ + /* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses{GUID} */ ASSERT(PhysicalDeviceObject->DeviceObjectExtension->DeviceNode); InstancePath = &PhysicalDeviceObject->DeviceObjectExtension->DeviceNode->InstancePath; BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR); BaseKeyName.MaximumLength = BaseKeyName.Length - + GuidString.Length - + 5 * sizeof(WCHAR) /* 5 = size of ##?# */ - + InstancePath->Length - + sizeof(WCHAR) /* 1 = size of # */ + GuidString.Length; BaseKeyName.Buffer = ExAllocatePool( NonPagedPool, @@ -631,16 +629,6 @@ } wcscpy(BaseKeyName.Buffer, BaseKeyString); RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString); - RtlAppendUnicodeToString(&BaseKeyName, L"\##?#"); - StartIndex = BaseKeyName.Length / sizeof(WCHAR); - RtlAppendUnicodeStringToString(&BaseKeyName, InstancePath); - for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++) - { - if (BaseKeyName.Buffer[StartIndex + i] == '\') - BaseKeyName.Buffer[StartIndex + i] = '#'; - } - RtlAppendUnicodeToString(&BaseKeyName, L"#"); - RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);
/* Create BaseKeyName key in registry */ InitializeObjectAttributes( @@ -651,6 +639,57 @@ NULL); /* SecurityDescriptor */
Status = ZwCreateKey( + &ClassKey, + KEY_WRITE, + &ObjectAttributes, + 0, /* TileIndex */ + NULL, /* Class */ + REG_OPTION_VOLATILE, + NULL); /* Disposition */ + + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); + ExFreePool(BaseKeyName.Buffer); + return Status; + } + + /* Create key name for this interface: ##?#ACPI#PNP0501#1#{GUID} */ + InterfaceKeyName.Length = 0; + InterfaceKeyName.MaximumLength = + 4 * sizeof(WCHAR) + /* 4 = size of ##?# */ + InstancePath->Length + + sizeof(WCHAR) + /* 1 = size of # */ + GuidString.Length; + InterfaceKeyName.Buffer = ExAllocatePool( + NonPagedPool, + InterfaceKeyName.MaximumLength); + if (!InterfaceKeyName.Buffer) + { + DPRINT("ExAllocatePool() failed\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlAppendUnicodeToString(&InterfaceKeyName, L"##?#"); + StartIndex = InterfaceKeyName.Length / sizeof(WCHAR); + RtlAppendUnicodeStringToString(&InterfaceKeyName, InstancePath); + for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++) + { + if (InterfaceKeyName.Buffer[StartIndex + i] == '\') + InterfaceKeyName.Buffer[StartIndex + i] = '#'; + } + RtlAppendUnicodeToString(&InterfaceKeyName, L"#"); + RtlAppendUnicodeStringToString(&InterfaceKeyName, &GuidString); + + /* Create the interface key in registry */ + InitializeObjectAttributes( + &ObjectAttributes, + &InterfaceKeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF, + ClassKey, + NULL); /* SecurityDescriptor */ + + Status = ZwCreateKey( &InterfaceKey, KEY_WRITE, &ObjectAttributes, @@ -662,6 +701,7 @@ if (!NT_SUCCESS(Status)) { DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); + ZwClose(ClassKey); ExFreePool(BaseKeyName.Buffer); return Status; } @@ -678,6 +718,8 @@ { DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); ZwClose(InterfaceKey); + ZwClose(ClassKey); + ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); return Status; } @@ -694,6 +736,8 @@ { DPRINT("ExAllocatePool() failed\n"); ZwClose(InterfaceKey); + ZwClose(ClassKey); + ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); return STATUS_INSUFFICIENT_RESOURCES; } @@ -722,6 +766,8 @@ { DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status); ZwClose(InterfaceKey); + ZwClose(ClassKey); + ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); return Status; } @@ -742,8 +788,10 @@ if (!SymbolicLinkName->Buffer) { DPRINT("ExAllocatePool() failed\n"); + ZwClose(SubKey); ZwClose(InterfaceKey); - ZwClose(SubKey); + ZwClose(ClassKey); + ExFreePool(InterfaceKeyName.Buffer); ExFreePool(SubKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); return STATUS_INSUFFICIENT_RESOURCES; @@ -771,9 +819,11 @@ if (!NT_SUCCESS(Status)) { DPRINT("IoCreateSymbolicLink() failed with status 0x%08lx\n", Status); + ZwClose(SubKey); ZwClose(InterfaceKey); - ZwClose(SubKey); + ZwClose(ClassKey); ExFreePool(SubKeyName.Buffer); + ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer); ExFreePool(SymbolicLinkName->Buffer); return Status; @@ -793,9 +843,11 @@ ExFreePool(SymbolicLinkName->Buffer); }
+ ZwClose(SubKey); ZwClose(InterfaceKey); - ZwClose(SubKey); + ZwClose(ClassKey); ExFreePool(SubKeyName.Buffer); + ExFreePool(InterfaceKeyName.Buffer); ExFreePool(BaseKeyName.Buffer);
return Status;