IopUpdateResourceMapForPnPDevice(
IN PDEVICE_NODE DeviceNode);
+NTSTATUS
+NTAPI
+IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
+ OUT PHANDLE Handle);
+
PDEVICE_NODE
FASTCALL
IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
IO_STACK_LOCATION Stack;
ULONG RequiredLength;
NTSTATUS Status;
+ HANDLE InstanceHandle, ControlHandle;
+ UNICODE_STRING KeyName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
DPRINT("Sending IRP_MN_FILTER_RESOURCE_REQUIREMENTS to device stack\n");
}
}
+ Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, &InstanceHandle);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ RtlInitUnicodeString(&KeyName, L"Control");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ InstanceHandle,
+ NULL);
+ Status = ZwCreateKey(&ControlHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ZwClose(InstanceHandle);
+ return Status;
+ }
+
+ RtlInitUnicodeString(&KeyName, L"ActiveService");
+ Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, DeviceNode->ServiceName.Buffer, DeviceNode->ServiceName.Length);
+
if (NT_SUCCESS(Status))
IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
+ ZwClose(ControlHandle);
+ ZwClose(InstanceHandle);
+
return Status;
}
KIRQL OldIrql;
UNICODE_STRING FullServiceName;
UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_");
+ UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN");
+ HANDLE TempHandle;
DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n",
ParentNode, PhysicalDeviceObject, ServiceName);
RtlZeroMemory(Node, sizeof(DEVICE_NODE));
+ if (!ServiceName)
+ ServiceName = &UnknownDeviceName;
+
if (!PhysicalDeviceObject)
{
- if (ServiceName)
+ FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName->Length;
+ FullServiceName.Length = 0;
+ FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength);
+ if (!FullServiceName.Buffer)
{
- FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName->Length;
- FullServiceName.Length = 0;
- FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength);
- if (!FullServiceName.Buffer)
- {
- ExFreePool(Node);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
- RtlAppendUnicodeStringToString(&FullServiceName, ServiceName);
+ ExFreePool(Node);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- Status = PnpRootCreateDevice(ServiceName ? &FullServiceName : NULL, &PhysicalDeviceObject);
+ RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
+ RtlAppendUnicodeStringToString(&FullServiceName, ServiceName);
+
+ Status = PnpRootCreateDevice(&FullServiceName, &PhysicalDeviceObject, &Node->InstancePath);
if (!NT_SUCCESS(Status))
{
DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status);
return Status;
}
+ /* Create the device key for legacy drivers */
+ Status = IopCreateDeviceKeyPath(&Node->InstancePath, &TempHandle);
+ if (NT_SUCCESS(Status))
+ ZwClose(TempHandle);
+
+ ExFreePool(FullServiceName.Buffer);
+
/* This is for drivers passed on the command line to ntoskrnl.exe */
IopDeviceNodeSetFlag(Node, DNF_STARTED);
IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER);
ULONG ResCount;
ULONG ListSize, ResultLength;
NTSTATUS Status;
+ HANDLE ControlHandle;
DPRINT("IopSetDeviceInstanceData() called\n");
sizeof(DefaultConfigFlags));
}
+ /* Create the 'Control' key */
+ RtlInitUnicodeString(&KeyName, L"Control");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ InstanceKey,
+ NULL);
+ Status = ZwCreateKey(&ControlHandle, 0, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
+
+ if (NT_SUCCESS(Status))
+ ZwClose(ControlHandle);
+
DPRINT("IopSetDeviceInstanceData() done\n");
- return STATUS_SUCCESS;
+ return Status;
}
BOOLEAN
NTSTATUS
PnpRootCreateDevice(
IN PUNICODE_STRING ServiceName,
- IN PDEVICE_OBJECT *PhysicalDeviceObject)
+ OUT PDEVICE_OBJECT *PhysicalDeviceObject,
+ OUT OPTIONAL PUNICODE_STRING FullInstancePath)
{
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
- UNICODE_STRING UnknownServiceName = RTL_CONSTANT_STRING(L"LEGACY_UNKNOWN");
- PUNICODE_STRING LocalServiceName;
PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
WCHAR DevicePath[MAX_PATH + 1];
WCHAR InstancePath[5];
PPNPROOT_DEVICE Device = NULL;
NTSTATUS Status;
ULONG i;
+ UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\");
DeviceExtension = PnpRootDeviceObject->DeviceExtension;
KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
- if (ServiceName)
- LocalServiceName = ServiceName;
- else
- LocalServiceName = &UnknownServiceName;
-
- DPRINT("Creating a PnP root device for service '%wZ'\n", LocalServiceName);
+ DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName);
/* Search for a free instance ID */
- _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, LocalServiceName);
+ _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, ServiceName);
for (i = 0; i < 9999; i++)
{
_snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", i);
}
if (i == 9999)
{
- DPRINT1("Too much legacy devices reported for service '%wZ'\n", &LocalServiceName);
+ DPRINT1("Too much legacy devices reported for service '%wZ'\n", ServiceName);
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}
goto cleanup;
}
+ if (FullInstancePath)
+ {
+ FullInstancePath->MaximumLength = Device->DeviceID.Length + PathSep.Length + Device->InstanceID.Length;
+ FullInstancePath->Length = 0;
+ FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength);
+ if (!FullInstancePath->Buffer)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+
+ RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID);
+ RtlAppendUnicodeStringToString(FullInstancePath, &PathSep);
+ RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID);
+ }
+
/* Initialize a device object */
Status = IoCreateDevice(
PnpRootDeviceObject->DriverObject,