KGUARDED_MUTEX PpDeviceReferenceTableLock;
RTL_AVL_TABLE PpDeviceReferenceTable;
+extern ERESOURCE IopDriverLoadResource;
extern ULONG ExpInitializationPhase;
extern BOOLEAN ExpInTextModeSetup;
extern BOOLEAN PnpSystemInit;
PDRIVER_OBJECT IopRootDriverObject;
PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList = NULL;
+LIST_ENTRY IopDeviceRelationsRequestList;
+WORK_QUEUE_ITEM IopDeviceRelationsWorkItem;
+BOOLEAN IopDeviceRelationsRequestInProgress;
+KSPIN_LOCK IopDeviceRelationsSpinLock;
typedef struct _INVALIDATE_DEVICE_RELATION_DATA
{
+ LIST_ENTRY RequestListEntry;
PDEVICE_OBJECT DeviceObject;
DEVICE_RELATION_TYPE Type;
- PIO_WORKITEM WorkItem;
} INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
/* FUNCTIONS *****************************************************************/
continue;
}
- DPRINT1("Installed service '%S' for critical device '%wZ'\n", PartialInfo->Data, &ChildIdNameU);
+ DPRINT("Installed service '%S' for critical device '%wZ'\n", PartialInfo->Data, &ChildIdNameU);
}
else
{
PDEVICE_NODE DeviceNode)
{
NTSTATUS Status;
- HANDLE InstanceHandle = INVALID_HANDLE_VALUE, ControlHandle = INVALID_HANDLE_VALUE;
+ HANDLE InstanceHandle = NULL, ControlHandle = NULL;
UNICODE_STRING KeyName;
OBJECT_ATTRIBUTES ObjectAttributes;
RtlInitUnicodeString(&KeyName, L"Control");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
- OBJ_CASE_INSENSITIVE,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
InstanceHandle,
NULL);
Status = ZwCreateKey(&ControlHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
// }
ByeBye:
- if (ControlHandle != INVALID_HANDLE_VALUE)
+ if (ControlHandle != NULL)
ZwClose(ControlHandle);
- if (InstanceHandle != INVALID_HANDLE_VALUE)
+ if (InstanceHandle != NULL)
ZwClose(InstanceHandle);
return Status;
return Status;
}
-static VOID NTAPI
-IopAsynchronousInvalidateDeviceRelations(
- IN PDEVICE_OBJECT DeviceObject,
- IN PVOID InvalidateContext)
+static
+VOID
+NTAPI
+IopDeviceRelationsWorker(
+ _In_ PVOID Context)
{
- PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext;
+ PLIST_ENTRY ListEntry;
+ PINVALIDATE_DEVICE_RELATION_DATA Data;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql);
+ while (!IsListEmpty(&IopDeviceRelationsRequestList))
+ {
+ ListEntry = RemoveHeadList(&IopDeviceRelationsRequestList);
+ KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
+ Data = CONTAINING_RECORD(ListEntry,
+ INVALIDATE_DEVICE_RELATION_DATA,
+ RequestListEntry);
- IoSynchronousInvalidateDeviceRelations(
- Data->DeviceObject,
- Data->Type);
+ IoSynchronousInvalidateDeviceRelations(Data->DeviceObject,
+ Data->Type);
- ObDereferenceObject(Data->DeviceObject);
- IoFreeWorkItem(Data->WorkItem);
- ExFreePool(Data);
+ ObDereferenceObject(Data->DeviceObject);
+ ExFreePool(Data);
+ KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql);
+ }
+ IopDeviceRelationsRequestInProgress = FALSE;
+ KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
}
NTSTATUS
/* Open key */
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
- OBJ_CASE_INSENSITIVE,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
hParent,
NULL);
Status = ZwCreateKey(&hKey,
RtlInitUnicodeString(&KeyName, L"LogConf");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
- OBJ_CASE_INSENSITIVE,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
InstanceKey,
NULL);
Status = ZwCreateKey(&LogConfKey,
RtlInitUnicodeString(&KeyName, L"Control");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
- OBJ_CASE_INSENSITIVE,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
InstanceKey,
NULL);
Status = ZwCreateKey(&ControlHandle, 0, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
PVOID Context)
{
- IO_STATUS_BLOCK IoStatusBlock;
- PDEVICE_NODE ParentDeviceNode;
- WCHAR InstancePath[MAX_PATH];
- IO_STACK_LOCATION Stack;
- NTSTATUS Status;
- ULONG RequiredLength;
- LCID LocaleId;
- HANDLE InstanceKey = NULL;
- UNICODE_STRING ValueName;
- UNICODE_STRING ParentIdPrefix = { 0, 0, NULL };
- UNICODE_STRING InstancePathU;
- DEVICE_CAPABILITIES DeviceCapabilities;
- PDEVICE_OBJECT OldDeviceObject;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PWSTR InformationString;
+ PDEVICE_NODE ParentDeviceNode;
+ WCHAR InstancePath[MAX_PATH];
+ IO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+ ULONG RequiredLength;
+ LCID LocaleId;
+ HANDLE InstanceKey = NULL;
+ UNICODE_STRING ValueName;
+ UNICODE_STRING ParentIdPrefix = { 0, 0, NULL };
+ UNICODE_STRING InstancePathU;
+ DEVICE_CAPABILITIES DeviceCapabilities;
+ PDEVICE_OBJECT OldDeviceObject;
- DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
- DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
+ DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
+ DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
- ParentDeviceNode = (PDEVICE_NODE)Context;
+ ParentDeviceNode = (PDEVICE_NODE)Context;
- /*
- * We are called for the parent too, but we don't need to do special
- * handling for this node
- */
+ /*
+ * We are called for the parent too, but we don't need to do special
+ * handling for this node
+ */
+ if (DeviceNode == ParentDeviceNode)
+ {
+ DPRINT("Success\n");
+ return STATUS_SUCCESS;
+ }
- if (DeviceNode == ParentDeviceNode)
- {
- DPRINT("Success\n");
- return STATUS_SUCCESS;
- }
+ /*
+ * Make sure this device node is a direct child of the parent device node
+ * that is given as an argument
+ */
+ if (DeviceNode->Parent != ParentDeviceNode)
+ {
+ DPRINT("Skipping 2+ level child\n");
+ return STATUS_SUCCESS;
+ }
- /*
- * Make sure this device node is a direct child of the parent device node
- * that is given as an argument
- */
+ /* Skip processing if it was already completed before */
+ if (DeviceNode->Flags & DNF_PROCESSED)
+ {
+ /* Nothing to do */
+ return STATUS_SUCCESS;
+ }
- if (DeviceNode->Parent != ParentDeviceNode)
- {
- DPRINT("Skipping 2+ level child\n");
- return STATUS_SUCCESS;
- }
+ /* Get Locale ID */
+ Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwQueryDefaultLocale() failed with status 0x%lx\n", Status);
+ return Status;
+ }
- /* Skip processing if it was already completed before */
- if (DeviceNode->Flags & DNF_PROCESSED)
- {
- /* Nothing to do */
- return STATUS_SUCCESS;
- }
+ /*
+ * FIXME: For critical errors, cleanup and disable device, but always
+ * return STATUS_SUCCESS.
+ */
- /* Get Locale ID */
- Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ZwQueryDefaultLocale() failed with status 0x%lx\n", Status);
- return Status;
- }
+ DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n");
- /*
- * FIXME: For critical errors, cleanup and disable device, but always
- * return STATUS_SUCCESS.
- */
+ Stack.Parameters.QueryId.IdType = BusQueryDeviceID;
+ Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_ID,
+ &Stack);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IopInitiatePnpIrp() failed (Status %x)\n", Status);
- DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n");
+ /* We have to return success otherwise we abort the traverse operation */
+ return STATUS_SUCCESS;
+ }
- Stack.Parameters.QueryId.IdType = BusQueryDeviceID;
- Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
- &IoStatusBlock,
- IRP_MN_QUERY_ID,
- &Stack);
- if (NT_SUCCESS(Status))
- {
- /* Copy the device id string */
- wcscpy(InstancePath, (PWSTR)IoStatusBlock.Information);
+ /* Copy the device id string */
+ InformationString = (PWSTR)IoStatusBlock.Information;
+ wcscpy(InstancePath, InformationString);
- /*
- * FIXME: Check for valid characters, if there is invalid characters
- * then bugcheck.
- */
- }
- else
- {
- DPRINT1("IopInitiatePnpIrp() failed (Status %x)\n", Status);
+ /*
+ * FIXME: Check for valid characters, if there is invalid characters
+ * then bugcheck.
+ */
- /* We have to return success otherwise we abort the traverse operation */
- return STATUS_SUCCESS;
- }
+ ExFreePoolWithTag(InformationString, 0);
- DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after enumeration)\n");
+ DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after enumeration)\n");
- Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IopInitiatePnpIrp() failed (Status 0x%08lx)\n", Status);
+ Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IopInitiatePnpIrp() failed (Status 0x%08lx)\n", Status);
- /* We have to return success otherwise we abort the traverse operation */
- return STATUS_SUCCESS;
- }
+ /* We have to return success otherwise we abort the traverse operation */
+ return STATUS_SUCCESS;
+ }
- /* This bit is only check after enumeration */
- if (DeviceCapabilities.HardwareDisabled)
- {
- /* FIXME: Cleanup device */
- DeviceNode->Flags |= DNF_DISABLED;
- return STATUS_SUCCESS;
- }
- else
- DeviceNode->Flags &= ~DNF_DISABLED;
+ /* This bit is only check after enumeration */
+ if (DeviceCapabilities.HardwareDisabled)
+ {
+ /* FIXME: Cleanup device */
+ DeviceNode->Flags |= DNF_DISABLED;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ DeviceNode->Flags &= ~DNF_DISABLED;
+ }
- if (!DeviceCapabilities.UniqueID)
- {
- /* Device has not a unique ID. We need to prepend parent bus unique identifier */
- DPRINT("Instance ID is not unique\n");
- Status = IopGetParentIdPrefix(DeviceNode, &ParentIdPrefix);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IopGetParentIdPrefix() failed (Status 0x%08lx)\n", Status);
+ if (!DeviceCapabilities.UniqueID)
+ {
+ /* Device has not a unique ID. We need to prepend parent bus unique identifier */
+ DPRINT("Instance ID is not unique\n");
+ Status = IopGetParentIdPrefix(DeviceNode, &ParentIdPrefix);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IopGetParentIdPrefix() failed (Status 0x%08lx)\n", Status);
- /* We have to return success otherwise we abort the traverse operation */
- return STATUS_SUCCESS;
- }
- }
+ /* We have to return success otherwise we abort the traverse operation */
+ return STATUS_SUCCESS;
+ }
+ }
- DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
+ DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
- Stack.Parameters.QueryId.IdType = BusQueryInstanceID;
- Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
- &IoStatusBlock,
- IRP_MN_QUERY_ID,
- &Stack);
- if (NT_SUCCESS(Status))
- {
- /* Append the instance id string */
- wcscat(InstancePath, L"\\");
- if (ParentIdPrefix.Length > 0)
- {
- /* Add information from parent bus device to InstancePath */
- wcscat(InstancePath, ParentIdPrefix.Buffer);
- if (IoStatusBlock.Information && *(PWSTR)IoStatusBlock.Information)
- wcscat(InstancePath, L"&");
- }
- if (IoStatusBlock.Information)
- wcscat(InstancePath, (PWSTR)IoStatusBlock.Information);
+ Stack.Parameters.QueryId.IdType = BusQueryInstanceID;
+ Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_ID,
+ &Stack);
+ if (NT_SUCCESS(Status))
+ {
+ InformationString = (PWSTR)IoStatusBlock.Information;
- /*
- * FIXME: Check for valid characters, if there is invalid characters
- * then bugcheck
- */
- }
- else
- {
- DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
- }
- RtlFreeUnicodeString(&ParentIdPrefix);
+ /* Append the instance id string */
+ wcscat(InstancePath, L"\\");
+ if (ParentIdPrefix.Length > 0)
+ {
+ /* Add information from parent bus device to InstancePath */
+ wcscat(InstancePath, ParentIdPrefix.Buffer);
+ if (InformationString && *InformationString)
+ {
+ wcscat(InstancePath, L"&");
+ }
+ }
+ if (InformationString)
+ {
+ wcscat(InstancePath, InformationString);
+ }
- if (!RtlCreateUnicodeString(&InstancePathU, InstancePath))
- {
- DPRINT("No resources\n");
- /* FIXME: Cleanup and disable device */
- }
+ /*
+ * FIXME: Check for valid characters, if there is invalid characters
+ * then bugcheck
+ */
- /* Verify that this is not a duplicate */
- OldDeviceObject = IopGetDeviceObjectFromDeviceInstance(&InstancePathU);
- if (OldDeviceObject != NULL)
- {
- PDEVICE_NODE OldDeviceNode = IopGetDeviceNode(OldDeviceObject);
+ if (InformationString)
+ {
+ ExFreePoolWithTag(InformationString, 0);
+ }
+ }
+ else
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
+ }
+ RtlFreeUnicodeString(&ParentIdPrefix);
- DPRINT1("Duplicate device instance '%wZ'\n", &InstancePathU);
- DPRINT1("Current instance parent: '%wZ'\n", &DeviceNode->Parent->InstancePath);
- DPRINT1("Old instance parent: '%wZ'\n", &OldDeviceNode->Parent->InstancePath);
+ if (!RtlCreateUnicodeString(&InstancePathU, InstancePath))
+ {
+ DPRINT("No resources\n");
+ /* FIXME: Cleanup and disable device */
+ }
- KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
- 0x01,
- (ULONG_PTR)DeviceNode->PhysicalDeviceObject,
- (ULONG_PTR)OldDeviceObject,
- 0);
- }
+ /* Verify that this is not a duplicate */
+ OldDeviceObject = IopGetDeviceObjectFromDeviceInstance(&InstancePathU);
+ if (OldDeviceObject != NULL)
+ {
+ PDEVICE_NODE OldDeviceNode = IopGetDeviceNode(OldDeviceObject);
- DeviceNode->InstancePath = InstancePathU;
+ DPRINT1("Duplicate device instance '%wZ'\n", &InstancePathU);
+ DPRINT1("Current instance parent: '%wZ'\n", &DeviceNode->Parent->InstancePath);
+ DPRINT1("Old instance parent: '%wZ'\n", &OldDeviceNode->Parent->InstancePath);
- DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
+ KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
+ 0x01,
+ (ULONG_PTR)DeviceNode->PhysicalDeviceObject,
+ (ULONG_PTR)OldDeviceObject,
+ 0);
+ }
- /*
- * Create registry key for the instance id, if it doesn't exist yet
- */
- Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
+ DeviceNode->InstancePath = InstancePathU;
- /* We have to return success otherwise we abort the traverse operation */
- return STATUS_SUCCESS;
- }
+ DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
- IopQueryHardwareIds(DeviceNode, InstanceKey);
+ /*
+ * Create registry key for the instance id, if it doesn't exist yet
+ */
+ Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
- IopQueryCompatibleIds(DeviceNode, InstanceKey);
+ /* We have to return success otherwise we abort the traverse operation */
+ return STATUS_SUCCESS;
+ }
- DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
+ IopQueryHardwareIds(DeviceNode, InstanceKey);
- Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription;
- Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
- Status = IopInitiatePnpIrp(
- DeviceNode->PhysicalDeviceObject,
- &IoStatusBlock,
- IRP_MN_QUERY_DEVICE_TEXT,
- &Stack);
- /* This key is mandatory, so even if the Irp fails, we still write it */
- RtlInitUnicodeString(&ValueName, L"DeviceDesc");
- if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND)
- {
- if (NT_SUCCESS(Status) &&
- IoStatusBlock.Information &&
- (*(PWSTR)IoStatusBlock.Information != 0))
- {
- /* This key is overriden when a driver is installed. Don't write the
- * new description if another one already exists */
- Status = ZwSetValueKey(InstanceKey,
- &ValueName,
- 0,
- REG_SZ,
- (PVOID)IoStatusBlock.Information,
- ((ULONG)wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
- }
- else
- {
- UNICODE_STRING DeviceDesc = RTL_CONSTANT_STRING(L"Unknown device");
- DPRINT("Driver didn't return DeviceDesc (Status 0x%08lx), so place unknown device there\n", Status);
+ IopQueryCompatibleIds(DeviceNode, InstanceKey);
- Status = ZwSetValueKey(InstanceKey,
- &ValueName,
- 0,
- REG_SZ,
- DeviceDesc.Buffer,
- DeviceDesc.MaximumLength);
+ DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ZwSetValueKey() failed (Status 0x%lx)\n", Status);
- }
+ Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription;
+ Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
+ Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_DEVICE_TEXT,
+ &Stack);
+ InformationString = NT_SUCCESS(Status) ? (PWSTR)IoStatusBlock.Information
+ : NULL;
+ /* This key is mandatory, so even if the Irp fails, we still write it */
+ RtlInitUnicodeString(&ValueName, L"DeviceDesc");
+ if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ if (InformationString &&
+ *InformationString != UNICODE_NULL)
+ {
+ /* This key is overriden when a driver is installed. Don't write the
+ * new description if another one already exists */
+ Status = ZwSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_SZ,
+ InformationString,
+ ((ULONG)wcslen(InformationString) + 1) * sizeof(WCHAR));
+ }
+ else
+ {
+ UNICODE_STRING DeviceDesc = RTL_CONSTANT_STRING(L"Unknown device");
+ DPRINT("Driver didn't return DeviceDesc (Status 0x%08lx), so place unknown device there\n", Status);
- }
- }
+ Status = ZwSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_SZ,
+ DeviceDesc.Buffer,
+ DeviceDesc.MaximumLength);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwSetValueKey() failed (Status 0x%lx)\n", Status);
+ }
- DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
+ }
+ }
- Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation;
- Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
- Status = IopInitiatePnpIrp(
- DeviceNode->PhysicalDeviceObject,
- &IoStatusBlock,
- IRP_MN_QUERY_DEVICE_TEXT,
- &Stack);
- if (NT_SUCCESS(Status) && IoStatusBlock.Information)
- {
- DPRINT("LocationInformation: %S\n", (PWSTR)IoStatusBlock.Information);
- RtlInitUnicodeString(&ValueName, L"LocationInformation");
- Status = ZwSetValueKey(InstanceKey,
- &ValueName,
- 0,
- REG_SZ,
- (PVOID)IoStatusBlock.Information,
- ((ULONG)wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
- }
- }
- else
- {
- DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
- }
+ if (InformationString)
+ {
+ ExFreePoolWithTag(InformationString, 0);
+ }
- DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
+ DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
- Status = IopInitiatePnpIrp(
- DeviceNode->PhysicalDeviceObject,
- &IoStatusBlock,
- IRP_MN_QUERY_BUS_INFORMATION,
- NULL);
- if (NT_SUCCESS(Status) && IoStatusBlock.Information)
- {
- PPNP_BUS_INFORMATION BusInformation =
- (PPNP_BUS_INFORMATION)IoStatusBlock.Information;
+ Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation;
+ Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
+ Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_DEVICE_TEXT,
+ &Stack);
+ if (NT_SUCCESS(Status) && IoStatusBlock.Information)
+ {
+ InformationString = (PWSTR)IoStatusBlock.Information;
+ DPRINT("LocationInformation: %S\n", InformationString);
+ RtlInitUnicodeString(&ValueName, L"LocationInformation");
+ Status = ZwSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_SZ,
+ InformationString,
+ ((ULONG)wcslen(InformationString) + 1) * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
+ }
- DeviceNode->ChildBusNumber = BusInformation->BusNumber;
- DeviceNode->ChildInterfaceType = BusInformation->LegacyBusType;
- DeviceNode->ChildBusTypeIndex = IopGetBusTypeGuidIndex(&BusInformation->BusTypeGuid);
- ExFreePool(BusInformation);
- }
- else
- {
- DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
+ ExFreePoolWithTag(InformationString, 0);
+ }
+ else
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
+ }
- DeviceNode->ChildBusNumber = 0xFFFFFFF0;
- DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
- DeviceNode->ChildBusTypeIndex = -1;
- }
+ DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
- DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
+ Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_BUS_INFORMATION,
+ NULL);
+ if (NT_SUCCESS(Status) && IoStatusBlock.Information)
+ {
+ PPNP_BUS_INFORMATION BusInformation = (PPNP_BUS_INFORMATION)IoStatusBlock.Information;
- Status = IopInitiatePnpIrp(
- DeviceNode->PhysicalDeviceObject,
- &IoStatusBlock,
- IRP_MN_QUERY_RESOURCES,
- NULL);
- if (NT_SUCCESS(Status) && IoStatusBlock.Information)
- {
- DeviceNode->BootResources =
- (PCM_RESOURCE_LIST)IoStatusBlock.Information;
- IopDeviceNodeSetFlag(DeviceNode, DNF_HAS_BOOT_CONFIG);
- }
- else
- {
- DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
- DeviceNode->BootResources = NULL;
- }
+ DeviceNode->ChildBusNumber = BusInformation->BusNumber;
+ DeviceNode->ChildInterfaceType = BusInformation->LegacyBusType;
+ DeviceNode->ChildBusTypeIndex = IopGetBusTypeGuidIndex(&BusInformation->BusTypeGuid);
+ ExFreePoolWithTag(BusInformation, 0);
+ }
+ else
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
- DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
+ DeviceNode->ChildBusNumber = 0xFFFFFFF0;
+ DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
+ DeviceNode->ChildBusTypeIndex = -1;
+ }
- Status = IopInitiatePnpIrp(
- DeviceNode->PhysicalDeviceObject,
- &IoStatusBlock,
- IRP_MN_QUERY_RESOURCE_REQUIREMENTS,
- NULL);
- if (NT_SUCCESS(Status))
- {
- DeviceNode->ResourceRequirements =
- (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information;
- }
- else
- {
- DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
- DeviceNode->ResourceRequirements = NULL;
- }
+ DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
- if (InstanceKey != NULL)
- {
- IopSetDeviceInstanceData(InstanceKey, DeviceNode);
- }
+ Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_RESOURCES,
+ NULL);
+ if (NT_SUCCESS(Status) && IoStatusBlock.Information)
+ {
+ DeviceNode->BootResources = (PCM_RESOURCE_LIST)IoStatusBlock.Information;
+ IopDeviceNodeSetFlag(DeviceNode, DNF_HAS_BOOT_CONFIG);
+ }
+ else
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
+ DeviceNode->BootResources = NULL;
+ }
+
+ DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
+
+ Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_RESOURCE_REQUIREMENTS,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ DeviceNode->ResourceRequirements = (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information;
+ }
+ else
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
+ DeviceNode->ResourceRequirements = NULL;
+ }
- ZwClose(InstanceKey);
+ if (InstanceKey != NULL)
+ {
+ IopSetDeviceInstanceData(InstanceKey, DeviceNode);
+ }
- IopDeviceNodeSetFlag(DeviceNode, DNF_PROCESSED);
+ ZwClose(InstanceKey);
- if (!IopDeviceNodeHasFlag(DeviceNode, DNF_LEGACY_DRIVER))
- {
- /* Report the device to the user-mode pnp manager */
- IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED,
- &DeviceNode->InstancePath);
- }
+ IopDeviceNodeSetFlag(DeviceNode, DNF_PROCESSED);
- return STATUS_SUCCESS;
+ if (!IopDeviceNodeHasFlag(DeviceNode, DNF_LEGACY_DRIVER))
+ {
+ /* Report the device to the user-mode pnp manager */
+ IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED,
+ &DeviceNode->InstancePath);
+ }
+
+ return STATUS_SUCCESS;
}
static
PLDR_DATA_TABLE_ENTRY ModuleObject;
PDRIVER_OBJECT DriverObject;
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE);
/* Get existing DriverObject pointer (in case the driver has
already been loaded and initialized) */
Status = IopGetDriverObject(
if (!BootDrivers) DeviceNode->Problem = CM_PROB_DRIVER_FAILED_LOAD;
}
}
+ ExReleaseResourceLite(&IopDriverLoadResource);
+ KeLeaveCriticalRegion();
/* Driver is loaded and initialized at this point */
if (NT_SUCCESS(Status))
DPRINT1("ZwOpenKey(%wZ) failed with status 0x%08lx\n", &KeyPathU, Status);
}
- DPRINT1("Firmware mapper is %s\n", KeyValue != 0 ? "disabled" : "enabled");
+ DPRINT("Firmware mapper is %s\n", KeyValue != 0 ? "disabled" : "enabled");
return (KeyValue != 0) ? TRUE : FALSE;
}
PIP_UNIMPLEMENTED();
case DevicePropertyRemovalPolicy:
PIP_UNIMPLEMENTED();
+ break;
case DevicePropertyInstallState:
- PIP_UNIMPLEMENTED();
+ PIP_REGISTRY_DATA(REGSTR_VAL_CONFIGFLAGS, REG_DWORD);
+ break;
case DevicePropertyResourceRequirements:
PIP_UNIMPLEMENTED();
case DevicePropertyAllocatedResources:
*/
RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
- InitializeObjectAttributes(&ObjectAttributes, &KeyName,
- OBJ_CASE_INSENSITIVE, *DevInstRegKey, NULL);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ *DevInstRegKey,
+ NULL);
Status = ZwCreateKey(DevInstRegKey, DesiredAccess, &ObjectAttributes,
0, NULL, ExpInTextModeSetup ? REG_OPTION_VOLATILE : 0, NULL);
ZwClose(ObjectAttributes.RootDirectory);
IN PDEVICE_OBJECT DeviceObject,
IN DEVICE_RELATION_TYPE Type)
{
- PIO_WORKITEM WorkItem;
PINVALIDATE_DEVICE_RELATION_DATA Data;
+ KIRQL OldIrql;
Data = ExAllocatePool(NonPagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
if (!Data)
return;
- WorkItem = IoAllocateWorkItem(DeviceObject);
- if (!WorkItem)
- {
- ExFreePool(Data);
- return;
- }
ObReferenceObject(DeviceObject);
Data->DeviceObject = DeviceObject;
Data->Type = Type;
- Data->WorkItem = WorkItem;
- IoQueueWorkItem(
- WorkItem,
- IopAsynchronousInvalidateDeviceRelations,
- DelayedWorkQueue,
- Data);
+ KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql);
+ InsertTailList(&IopDeviceRelationsRequestList, &Data->RequestListEntry);
+ if (IopDeviceRelationsRequestInProgress)
+ {
+ KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
+ return;
+ }
+ IopDeviceRelationsRequestInProgress = TRUE;
+ KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
+
+ ExInitializeWorkItem(&IopDeviceRelationsWorkItem,
+ IopDeviceRelationsWorker,
+ NULL);
+ ExQueueWorkItem(&IopDeviceRelationsWorkItem,
+ DelayedWorkQueue);
}
/*