Asynchronous calls to DeviceIoControl and the bus driver

My program is a virtual USB bus driver to control the scanners on the LAN. My question is how to process the asynchronous calls to DeviceIoControl coming from the user mode programs. The codes in the caller are like below:

HANDLE Handle = CreateFile(“\\.\Usbscan0”, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
If (Handle != INVALID_HANDLE_VALUE)
{
OVERLAPPED overlapped;
BYTE byValue;
DWORD bytes, result;

memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
byValue = 0;
ResetEvent(overlapped.hEvent);
DeviceIoControl(m_hInterrupt, (DWORD) IOCTL_WAIT_ON_DEVICE_EVENT, NULL, 0, &byValue, 1, &bytes, &overlapped);
result = WaitForSingleObject(overlapped.hEvent, 200);
CancelIo(Handle);
CloseHandle(Handle);
}

What happened to my program is that the above program is blocked on DeviceIoControl until the request is completed by the bus driver.
For the scanner being connected on the PC and on the LAN, IrpTracker shows the differences, about executing DeviceIoControl, as below:

PC:
NTAPI, NtDeviceIoControlFile, Scanner Utility, \Device\Usbscan0, DEVICE_CONTROL
Call, 0x859568C0-37180, (UNKNOWN), \Device\Usbscan0, DEVICE_CONTROL
Call, 0x859568C0-37180, \Device\Usbscan0, \Device\USBPDO-2, INTERNAL_DEVICE_CONTROL
Call, 0x859568C0-37180, \Device\USBPDO-2, \Device\USBPDO-1, INTERNAL_DEVICE_CONTROL
NTAPIRet, NtDeviceIoControlFile, Scanner Utility, \Device\Usbscan0, DEVICE_CONTROL, PENDING

LAN:
NTAPI, NtDeviceIoControlFile, Scanner Utility, \Device\Usbscan0, DEVICE_CONTROL
Call, 0x848D6C50-58, (UNKNOWN), \Device\Usbscan0, DEVICE_CONTROL
Call, 0x848D6C50-58, \Device\Usbscan0, (0x84C8E9A0)\Driver\Usb2Net, INTERNAL_DEVICE_CONTROL

It seems the system bus driver, used when connected on the PC, does not return immediately. Am I right? I really do not know what’s wrong in my program to make the flow different. Any suggestions would be greatly appreciated.

Thanks.

In your redirector bus driver, are you marking the irp pending and returning STATUS_PENDING in the PDO for the scanner?

Thank Doron.
Actually I did not apply the queuing mech. for some situations and I will modify my program to use it for all bulk and interrupt transfers and do the test again.

It seems not workable for me. When the request is coming, the queue is empty, that’s not busy, and my StartIo routine is called and then blocks. My codes are like below:

// grab the queue protection
KeAcquireSpinLock(&Queue->QueueLock, &oldIrql);
// see if the queue is busy
if ((Queue->CurrentIrp == NULL) && (Queue->StallCount == 0))
{
// mark irp pending since STATUS_PENDING is returned
IoMarkIrpPending(Irp);
status = STATUS_PENDING;

// set the current IRP
Queue->CurrentIrp = Irp;

// drop the queue protection
// raise our IRQL before calling StartIo
KeReleaseSpinLockFromDpcLevel(&Queue->QueueLock);

// call the user’s StartIo routine
Queue->StartIoRoutine(Queue->DeviceObject, Queue->CurrentIrp);

// drop our IRQL back
KeLowerIrql(oldIrql);

return status;
}
// put our queue pointer into the IRP
……

Any suggestions? Thanks.

This is a homegrown serialized queue, I can’t tell you why you are blocking in the StartIo routine. I do have to ask why you are not using KMDF or at least the built in WDM StartIo functionality though

d

Hi Doron,

I used DriverWizard coming from Compuware DriverStudio to create my program. Actually I do not know much about what the structure of a USB bus driver in Windows and what it should do. It is very hard to find information about this. I just start to read “Programming the Microsoft Windows Driver Model” written by Walter Oney. For now, I will try to create a system thread for each endpoint of a device and process the I/O requests for it one by one.
Thanks for your help.

DriverWorks is dead.

  1. Throw away what you wrote
  2. goto http://www.microsoft.com/whdc/driver/wdf/KMDF.mspx and read everything you can
  3. Rewrite your driver using KMDF.

There might be some short term pain, but going the KMDF route will pay off for you in the long term. Trush me on this one ;).

d

The Compuware DriverStudio Driver::Works is old and unsupported. They had
many bugs and never supported writing bus drivers, AFAIK. As Doron said,
use KMDF. Look in the toaster sample under kmdf which has a bus driver
sample. KMDF is not perfect and with three versions floating around your
testing will take a while though you can just redistribute the latest
version (1.5, I think) to eliminate those problems. I have used the nonpnp
version when I needed a simple driver that I could dump some code into
IoCtls and DriverEntry for quick and dirty testing. That sample has the
ability to run the test application and it loads the KMDF framework and the
driver automatically. You get the KMDF installer from the redist directory.

With PnP and Power Driver::Works had several problems over the years. KMDF
was built by those who have the sources to the entire OS and access to each
piece’s owner to ensure they got it right.

wrote in message news:xxxxx@ntdev…
Hi Doron,

I used DriverWizard coming from Compuware DriverStudio to create my program.
Actually I do not know much about what the structure of a USB bus driver in
Windows and what it should do. It is very hard to find information about
this. I just start to read “Programming the Microsoft Windows Driver Model”
written by Walter Oney. For now, I will try to create a system thread for
each endpoint of a device and process the I/O requests for it one by one.
Thanks for your help.

Yes, while there are 3 versions (v1.0, 1.1, 1.5) that have been released, if you build against v1.5 you don’t have to worry about the previous versions, just v1.5. That is because a previous minor version will not be installed over the current minor version (1.5).

d

Got it! I will do it right now. Thanks.

There’s not much on which you’ll get almost unanimous agreement on this
list. This is one.

mm

>> xxxxx@Microsoft.com 2007-02-09 01:32 >>>
DriverWorks is dead.

  1. Throw away what you wrote
  2. goto http://www.microsoft.com/whdc/driver/wdf/KMDF.mspx and read
    everything you can
  3. Rewrite your driver using KMDF.

There might be some short term pain, but going the KMDF route will pay
off for you in the long term. Trush me on this one ;).

d


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer