NTSTATUS IsoUsb_QueryCapabilities( IN PDEVICE_OBJECT PdoDeviceObject, IN PDEVICE_CAPABILITIES DeviceCapabilities ) /*++ Routine Description: This routine generates an internal IRP from this driver to the PDO to obtain information on the Physical Device Object's capabilities. We are most interested in learning which system power states are to be mapped to which device power states for honoring IRP_MJ_SET_POWER Irps. This is a blocking call which waits for the IRP completion routine to set an event on finishing. Arguments: DeviceObject - Physical DeviceObject for this USB controller. Return Value: NTSTATUS value from the IoCallDriver() call. --*/ { PIO_STACK_LOCATION nextStack; PIRP irp; NTSTATUS ntStatus; KEVENT event; // This is a DDK-defined DBG-only macro that ASSERTS we are not running pageable code // at higher than APC_LEVEL. PAGED_CODE(); // Build an IRP for us to generate an internal query request to the PDO irp = IoAllocateIrp(PdoDeviceObject->StackSize, FALSE); if (!irp) { return STATUS_INSUFFICIENT_RESOURCES; } // IoGetNextIrpStackLocation gives a higher level driver access to the next-lower // driver's I/O stack location in an IRP so the caller can set it up for the lower driver. nextStack = IoGetNextIrpStackLocation(irp); ISOUSB_ASSERT(nextStack != NULL); nextStack->MajorFunction= IRP_MJ_PNP; nextStack->MinorFunction= IRP_MN_QUERY_CAPABILITIES; // init an event to tell us when the completion routine's been called KeInitializeEvent(&event, NotificationEvent, FALSE); // Set a completion routine so it can signal our event when // the next lower driver is done with the Irp IoSetCompletionRoutine(irp, IsoUsb_IrpCompletionRoutine, &event, // pass the event as Context to completion routine TRUE, // invoke on success TRUE, // invoke on error TRUE); // invoke on cancellation of the Irp // set our pointer to the DEVICE_CAPABILITIES struct DeviceCapabilities->Removable=TRUE; //VON MIR EINGEFÜGT!!!******** DeviceCapabilities->SurpriseRemovalOK=TRUE; nextStack->Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities; ntStatus = IoCallDriver(PdoDeviceObject, irp); ISOUSB_KdPrint( DBGLVL_MEDIUM,(" IsoUsb_QueryCapabilities() ntStatus from IoCallDriver to PCI = 0x%x\n", ntStatus)); DeviceCapabilities->Removable=TRUE; //VON MIR EINGEFÜGT!!!******** DeviceCapabilities->SurpriseRemovalOK=TRUE; if (ntStatus == STATUS_PENDING) { // wait for irp to complete KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, NULL); } DeviceCapabilities->Removable=TRUE; //VON MIR EINGEFÜGT!!!******** DeviceCapabilities->SurpriseRemovalOK=TRUE; // failed? this is probably a bug ISOUSB_KdPrintCond( DBGLVL_DEFAULT,(!NT_SUCCESS(ntStatus)), ("IsoUsb_QueryCapabilities() failed\n")); IoFreeIrp(irp); return ntStatus; }