Ooops, the link
I’ve just discovered that Dmitry redesigned the hide logic and removed the PDOs array wiping in favor of a less aggressive design. But the old wipe functionality can be fetched from commits history. The logic was changed in this commit so you can see the removed PDOs array wipe functionality :
https://github.com/daynix/UsbDk/commit/0b7487ba56675427843642b90551c0afc9a6d077
In comments Dmitry said that the hotplug event was not sent by the system which I believe was a side effect of the PnP Manager being unaware about removed PDO. So you need to send IRP_MN_REMOVE_DEVICE request to PDO when this PDO is not reported by USBHUB FDO so USBHUB driver releases resources. The bad news is that IRP_MN_REMOVE_DEVICE is not supposed to be sent by third party drivers, though there is nothing special in it and you can build IRP for it, it is just reserved for the PnP Manager.
It is special in that the remove irp is a state changing irp and thus is synchronized against all other state changing irp across the system. So you can easily violate the contract across any of the devices created by the USB stack.
BUT
It doesn’t matter. Sending a remove doesn’t do what you think it does in this scenario. you are thinking like an fdo. The bus driver doesn’t release resources or delete the device object for a device object that it believes is still reported to pnp as a child. Only when the bus driver believes the pdo has been reported missing and then gets a remove will the delete happen.
Get Outlook for Androidhttps:
On Sat, Aug 20, 2016 at 10:45 AM -0700, “xxxxx@hotmail.com” > wrote:
I’ve just discovered that Dmitry redesigned the hide logic and removed the PDOs array wiping in favor of a less aggressive design. But the old wipe functionality can be fetched from commits history. The logic was changed in this commit so you can see the removed PDOs array wipe functionality :
https://github.com/daynix/UsbDk/commit/0b7487ba56675427843642b90551c0afc9a6d077
In comments Dmitry said that the hotplug event was not sent by the system which I believe was a side effect of the PnP Manager being unaware about removed PDO. So you need to send IRP_MN_REMOVE_DEVICE request to PDO when this PDO is not reported by USBHUB FDO so USBHUB driver releases resources. The bad news is that IRP_MN_REMOVE_DEVICE is not supposed to be sent by third party drivers, though there is nothing special in it and you can build IRP for it, it is just reserved for the PnP Manager.
—
NTDEV is sponsored by OSR
Visit the list online at: http:
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></https:>
Doron,
Bus driver creates and manages PDOs for devices attached to the bus. When a device has gone( i.e. unpluged or lost power ) the bus controller via its FDO driver tells PnP Manager to issue IRP_MN_QUERY_DEVICE_RELATIONS (BusRelations) by calling IoInvalidateDeviceRelations( BusRelations ) . PnP Manager issues a request and then processes PDOs that was not reported by issuing a series of requests with IRP_MN_REMOVE_DEVICE as a last request. So I don’t understand what should bus FDO driver “believes to” if it initiates this process.
When a filter attached to a bus controller FDO removes PDOs from BusRelation arrays this doesn’t affect any “believes” of the bus controller FDO driver. It still considers PDO as reported, when it detects that a device has been removed it calls IoInvalidateDeviceRelations, removes this PDO from an array and waits for IRP_MN_REMOVE_DEVICE to release all resources it associated with this PDO and then removes the PDO’s DEVICE_OBJECT by calling IoDeleteDevice(Pdo).
You don?t need to tell me how this works, I wrote all of the code in kmdf that handles pnp. I know how this works in intricate detail. This is why I am suggesting that the option of removing the bus relation entries behind the pnp and bus driver’s back is a bad idea. The list of corner cases is long and complicated.
You missed my point entirely. You suggested that when the filter removes the PDO from the reported list it should then send a remove to the PDO so the pdo and resources are cleaned up. I am saying that this is not, it is completely useless. The filter has to track the reported state as the bus driver believes it to be and then only send a remove when the bus driver reports the pdo as missing.
Sent from my Windows 10 phone
From: xxxxx@hotmail.commailto:xxxxx
Sent: Saturday, August 20, 2016 12:15 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] How to attach prevent USB PNP Devices(WDM)?
Doron,
Bus driver creates and manages PDOs for devices attached to the bus. When a device has gone( i.e. unpluged or lost power ) the bus controller via its FDO driver tells PnP Manager to issue IRP_MN_QUERY_DEVICE_RELATIONS (BusRelations) by calling IoInvalidateDeviceRelations( BusRelations ) . PnP Manager issues a request and then processes PDOs that was not reported by issuing a series of requests with IRP_MN_REMOVE_DEVICE as a last request. So I don’t understand what should bus FDO driver “believes to” if it initiates this process.
When a filter attached to a bus controller FDO removes PDOs from BusRelation arrays this doesn’t affect any “believes” of the bus controller FDO driver. It still considers PDO as reported, when it detects that a device has been removed it calls IoInvalidateDeviceRelations, removes this PDO from an array and waits for IRP_MN_REMOVE_DEVICE to release all resources it associated with this PDO and then removes the PDO’s DEVICE_OBJECT by calling IoDeleteDevice(Pdo).
—
NTDEV is sponsored by OSR
Visit the list online at: http:
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx>
> You missed my point entirely. You suggested that when the filter removes the PDO from the reported list it should then send a remove to the PDO
Actually this is you who missed the point. I suggested to do this in response to IRP_MN_QUERY_DEVICE_RELATIONS when PDO is not reported. This is what I told “So you need to send IRP_MN_REMOVE_DEVICE request to PDO when this PDO is not reported by USBHUB FDO so USBHUB driver releases resources.”
Hi All,
First a special ‘thanks’ goes to Slava Imameev,
My Friends now i can detach usb in upper filter driver, but before that i must detect usb information and then detach device i can’t recive USB_INTERFACE_DESCRIPTOR configuartion in upper filter(only recived in lower filter) please guide to me for solve this issue.
Note:
First i recived two IRP_MN_QUERY_DEVICE_RELATIONS and BusRelations event in upper and can detach and after this events i get same event in lower and get URB information
Thank you.
What is “lower” and “upper” filters in your design?
Do you attach filters to and under USBHUB FDO? So the driver stack is
OR you register filters for USB devices so the stack is
If you are not sure then what is the output of “!devstack” command for all upper and lower filter device objects?
To get a list of all device objects use “!drvobj” command, e.g.
“!drvobj USBHUB” gives a list of all devices created by usbhub driver. Then you can use !devstack for each object.
This is an example of these commands output
1: kd> !drvobj USBHUB
Driver object (86abec80) is for:
*** ERROR: Module load completed but symbols could not be loaded for ctxusbm.sys
\Driver\usbhub
Driver Extension List: (id , addr)
Device Object list:
862dc030 8708a030 87097028 8708b030
86fd4028 86aea028
1: kd> !devstack 862dc030
!DevObj !DrvObj !DevExt ObjectName
87aed690 \Driver\USBSTOR 87aed748 000000d3
862dc030 \Driver\usbhub 862dc0e8 USBPDO-4
!DevNode 875d8b08 :
DeviceInst is “USB\VID_0781&PID_5576\4C530007661201117570”
ServiceName is “USBSTOR”
xxxxx@yahoo.com wrote:
First a special ‘thanks’ goes to Slava Imameev,
My Friends now i can detach usb in upper filter driver, but before that i must detect usb information and then detach device i can’t recive USB_INTERFACE_DESCRIPTOR configuartion in upper filter(only recived in lower filter) please guide to me for solve this issue.
An upper filter won’t see the configuration descriptor request, because
that’s only sent downward from the FDO. However, there’s nothing
stopping you from sending a configuration descriptor request on your
own. You have the PDO.
If you really need to see requests sent by the FDO, then you have to
have a lower filter. You can certainly put upper and lower filter in a
single driver.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Hi All,
Slava Imameev
xxxxx@hotmail.com
What is “lower” and “upper” filters in your design?
Do you attach filters to and under USBHUB FDO? So the driver stack is
Mr.Slava my device stack is(my Driver is usbfilter):
1: kd> !drvobj USBHUB
Driver object (86399858) is for:
\Driver\usbhub
Driver Extension List: (id , addr)
Device Object list:
864ef028 86462030 85e16030 864c7028
85d1e028
1: kd> !devobj 864ef028
Device object (864ef028) is for:
000000ad \Driver\usbhub DriverObject 86399858
Current Irp 00000000 RefCount 0 Type 00008600 Flags 00002840
Dacl 88c620f8 DevExt 864ef0e0 DevObjExt 864f20a8
ExtensionFlags (0x00000800) DOE_DEFAULT_SD_PRESENT
Characteristics (0x00000080) FILE_AUTOGENERATED_DEVICE_NAME
AttachedDevice (Upper) 85de13b8 \FileSystem\usbfilter
AttachedTo (Lower) 85de2030 \FileSystem\usbfilter
Device queue is not busy.
1: kd> !devstack 864ef028
!DevObj !DrvObj !DevExt ObjectName
85de13b8 \FileSystem\usbfilter85de1470 FbtUsb11
864ef028 \Driver\usbhub 864ef0e0 000000ad
85de2030 \FileSystem\usbfilter85de20e8 FbtUsb10
86462030 \Driver\usbhub 864620e8 USBPDO-3
!DevNode 8586dbb0 :
DeviceInst is “USB\VID_0E0F&PID_0002\6&b77da92&0&2”
ServiceName is “usbhub”
Tim Roberts
xxxxx@probo.com wrote:
An upper filter won’t see the configuration descriptor request, because
that’s only sent downward from the FDO. However, there’s nothing
stopping you from sending a configuration descriptor request on your
own. You have the PDO.
If you really need to see requests sent by the FDO, then you have to
have a lower filter. You can certainly put upper and lower filter in a
single driver.
Thank you Roberts,
Please guide me further about PDO solution for send this informaion with PDO.
and you say about in discussion this below link, “no way for upper filter to access the USB configuration descriptor”
https://www.osronline.com/showthread.cfm?link=193921
Hmm do i understand correctly? you say send configuration descriptor request from lower to upper?(with some method driver-driver communication)
so my problem is first sent upper event ( IRP_MN_QUERY_DEVICE_RELATIONS) and next lower event,
please more guide to me and if may give me a sample code.
Thank you.
Continuing the previous post
I have a another sample with WDF.
why and how to usb lower filter driver can detach usb device only with return STATUS_UNSUCCESSFUL ?
NTSTATUS USBDriverCreateDevice(Inout PWDFDEVICE_INIT DeviceInit)
{
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
WDF_OBJECT_ATTRIBUTES deviceAttributes;
PDEVICE_CONTEXT deviceContext;
WDFDEVICE device;
NTSTATUS status;
PAGED_CODE();
WdfFdoInitSetFilter(DeviceInit);
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_UNKNOWN);
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
pnpPowerCallbacks.EvtDevicePrepareHardware = USBDriverEvtDevicePrepareHardware;
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
…
}
NTSTATUS
USBDriverEvtDevicePrepareHardware(
In WDFDEVICE Device,
In WDFCMRESLIST ResourceList,
In WDFCMRESLIST ResourceListTranslated
)
{
…
return STATUS_UNSUCCESSFUL;
}
How to implement only in WDM lower filter driver?
Hi,
Looking at the stack I think Tim Roberts answered the question.
To request information from PDO you need to build a request and send it to PDO or a device your lower filter is attached to. This should be a synchronous IRP with a stack location initialized like in an example below
StackLocation->MajorFunction = IRP_MJ_PNP;
StackLocation->MinorFunction = IRP_MN_QUERY_ID;
StackLocation->Parameters.QueryId.IdType = SomeType;
The same way you can implement other requests.
I believe googling will return some examples of building these requests for WDM or KMDF.
Thank you Slava Imameev for your advise me.
I wrote the following routine with name QueryInterface and call it in the pnpfilter(IRP_MN_QUERY_DEVICE_RELATIONS and BusRelations) body
when device attached i recived event and call QueryInterface
The return result of IoCallDriver is STATUS_SUCCESS. But in pnpIrp->IoStatus.Information, it is
not a string pointer but a number 0x1d8 which is just the size of IRP.
Why I cannot get the ID? Is there anything wrong in the Code?
And how to get “Device Descriptor” and “Full Configuration Descriptor”(Configuration Descriptor and Interface Descriptor) with this method(request information from PDO)?
NTSTATUS
QueryInterface(
IN PDEVICE_OBJECT DeviceObject)
{
KEVENT event;
NTSTATUS status;
PIRP irp;
IO_STATUS_BLOCK ioStatusBlock;
PIO_STACK_LOCATION irpStack;
PDEVICE_OBJECT targetObject;
DbgPrint(CURINFO " GetPciBusInterfaceStandard entered.\n");
KeInitializeEvent(&event, NotificationEvent, FALSE);
targetObject = IoGetAttachedDeviceReference(DeviceObject);
irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
targetObject,
NULL,
0,
NULL,
&event,
&ioStatusBlock);
if (irp == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto End;
}
irpStack = IoGetNextIrpStackLocation(irp);
// Set the top of stack
RtlZeroMemory(irpStack, sizeof(IO_STACK_LOCATION));
irpStack->MajorFunction = IRP_MJ_PNP;
irpStack->MinorFunction = IRP_MN_QUERY_ID;
irpStack->Parameters.QueryId.IdType = BusQueryInstanceID;
// Initialize the status to error in case the bus driver does not
// set it correctly.
irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
status = IoCallDriver(targetObject, irp);
if (status == STATUS_PENDING) {
// Block until the irp comes back.
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = ioStatusBlock.Status;
}
DbgBreakPoint();
if (NT_SUCCESS(status))
{
DbgPrint(“Instance ID %S”, irp->IoStatus.Information);
}
End:
// Done with reference
ObDereferenceObject(targetObject);
return status;
}
Thank You All.
>Why I cannot get the ID? Is there anything wrong in the Code?
The code look fine except probably for the following line that wipes everything in the stack location:
RtlZeroMemory(irpStack, sizeof(IO_STACK_LOCATION));
And how to get “Device Descriptor” and “Full Configuration Descriptor”(Configuration Descriptor and Interface Descriptor) with this method(request information from PDO)?
https://msdn.microsoft.com/en-us/library/windows/hardware/ff539283(v=vs.85).aspx