Index: pnpmgr.c =================================================================== --- ntoskrnl/io/pnpmgr/pnpmgr.c (revision 74296) +++ ntoskrnl/io/pnpmgr/pnpmgr.c (working copy) @@ -40,6 +40,8 @@ LIST_ENTRY RequestListEntry; PDEVICE_OBJECT DeviceObject; DEVICE_RELATION_TYPE Type; + PKEVENT Event; + NTSTATUS Status; } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA; /* FUNCTIONS *****************************************************************/ @@ -741,7 +743,7 @@ (DeviceNode->Flags & DNF_NEED_ENUMERATION_ONLY)) { /* Enumerate us */ - IoSynchronousInvalidateDeviceRelations(DeviceObject, BusRelations); + IoInvalidateDeviceRelations(DeviceObject, BusRelations); Status = STATUS_SUCCESS; } else @@ -916,11 +918,35 @@ INVALIDATE_DEVICE_RELATION_DATA, RequestListEntry); - IoSynchronousInvalidateDeviceRelations(Data->DeviceObject, - Data->Type); + switch (Data->Type) + { + case BusRelations: + /* Enumerate the device */ + Data->Status = IopEnumerateDevice(Data->DeviceObject); + break; + case PowerRelations: + /* Not handled yet */ + Data->Status = STATUS_NOT_IMPLEMENTED; + break; + case TargetDeviceRelation: + /* Nothing to do */ + Data->Status = STATUS_SUCCESS; + break; + default: + /* Ejection relations are not supported */ + Data->Status = STATUS_NOT_SUPPORTED; + break; + } ObDereferenceObject(Data->DeviceObject); - ExFreePool(Data); + if (Data->Event != NULL) + { + KeSetEvent(Data->Event, IO_NO_INCREMENT, FALSE); + } + else + { + ExFreePoolWithTag(Data, TAG_IO); + } KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql); } IopDeviceRelationsRequestInProgress = FALSE; @@ -4772,7 +4798,9 @@ PINVALIDATE_DEVICE_RELATION_DATA Data; KIRQL OldIrql; - Data = ExAllocatePool(NonPagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA)); + Data = ExAllocatePoolWithTag(NonPagedPool, + sizeof(INVALIDATE_DEVICE_RELATION_DATA), + TAG_IO); if (!Data) return; @@ -4779,6 +4807,7 @@ ObReferenceObject(DeviceObject); Data->DeviceObject = DeviceObject; Data->Type = Type; + Data->Event = NULL; KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql); InsertTailList(&IopDeviceRelationsRequestList, &Data->RequestListEntry); @@ -4806,23 +4835,47 @@ IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type) { + PINVALIDATE_DEVICE_RELATION_DATA Data; + KIRQL OldIrql; + KEVENT Event; + NTSTATUS Status; + PAGED_CODE(); - switch (Type) + Data = ExAllocatePoolWithTag(NonPagedPool, + sizeof(INVALIDATE_DEVICE_RELATION_DATA), + TAG_IO); + if (!Data) + return STATUS_INSUFFICIENT_RESOURCES; + + ObReferenceObject(DeviceObject); + Data->DeviceObject = DeviceObject; + Data->Type = Type; + KeInitializeEvent(&Event, NotificationEvent, FALSE); + Data->Event = &Event; + + KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql); + InsertTailList(&IopDeviceRelationsRequestList, &Data->RequestListEntry); + if (IopDeviceRelationsRequestInProgress) { - case BusRelations: - /* Enumerate the device */ - return IopEnumerateDevice(DeviceObject); - case PowerRelations: - /* Not handled yet */ - return STATUS_NOT_IMPLEMENTED; - case TargetDeviceRelation: - /* Nothing to do */ - return STATUS_SUCCESS; - default: - /* Ejection relations are not supported */ - return STATUS_NOT_SUPPORTED; + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); } + else + { + IopDeviceRelationsRequestInProgress = TRUE; + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); + + ExInitializeWorkItem(&IopDeviceRelationsWorkItem, + IopDeviceRelationsWorker, + NULL); + ExQueueWorkItem(&IopDeviceRelationsWorkItem, + DelayedWorkQueue); + } + + (void)KeWaitForSingleObject(&Event, KernelMode, Executive, FALSE, NULL); + Status = Data->Status; + ExFreePoolWithTag(Data, TAG_IO); + return Status; } /*