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;