IoSetCompletionRoutine(dx->HidIrp, (PIO_COMPLETION_ROUTINE)ReadComplete, &event, TRUE, TRUE, TRUE);

 NTSTATUS status = IoCallDriver(dx->HidDevice, dx->HidIrp);

 if (status == STATUS_PENDING) {

  KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);

  status = dx->HidIrp->IoStatus.Status;

 }

 // return IRP completion status

 DebugPrint('ReadHidKbdInputReport: status %x', status);

 BytesTxd = dx->HidIrp->IoStatus.Information;

 if (BytesTxd>0) RtlCopyMemory(Buffer, dx->HidReport, BytesTxd);

 return status;

}

NTSTATUS ReadComplete(IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN PKEVENT Event) {

 KeSetEvent(Event, 0, FALSE);

 return STATUS_MORE_PROCESSING_REQUIRED;

}

Even Better …

Two problems exist with the permanently allocated IRP solution I have just presented. The first is that the driver will not cope with two 'simultaneous' read requests as it uses the same buffer in each call. A quick fix to this problem would be to allow only one read request at a time. The next best solution is dropping the shared buffer; an MDL must then be allocated for the user buffer in each read request.

In fact, the best solution is not to use a permanently allocated IRP, but to reuse the Read IRP. If the HidKbd device uses Direct I/O, the operating system will even do the MDL allocation. In this version, the ReadHidKbdInputReport routine only needs to set up the next IRP stack location appropriately. In fact, calling IoCopyCurrentIrpStackLocationToNext will probably do this job just fine.

The second problem with both the earlier techniques of calling the HID class driver is that they can be inefficient. In both the earlier cases, the call to KeWaitForSingleObject forces the current thread to block waiting for the event to become signalled. As HidKbd may operate in the context of a user thread, this may stop any other overlapped operations from running.[60] The solution to this problem is to modify the completion routine. If the completion routine completes the original Read IRP, there is no need for ReadHidKbdInputReport to wait for the IRP completion event.

This technique should be used wherever possible. The HidKbd Create and Close IRP use this technique as they pass their IRPs to the HID class driver, which completes them in due course. However, it is probably still worth using events in the CallHidIoctl routine for two reasons. The first is that HidKbd needs to know the IRP results. Secondly, my guess is that the HID class driver will be able to complete these IOCTLs straightaway, as it should already have the information at hand.

The CallUSBDI routine in the UsbKbd driver is a candidate for this technique, as it is more than likely that the USB class drivers will take some time to process a USBDI request. However, it is usually the case that the USBDI call results are needed. Processing the results in a completion routine is just about possible. However, this will probably lead to code that is very complicated. In the end, it is probably simplest to leave the UsbKbd code as it is.

Other HID Class IOCTLs

The DDK header files define several other HID IOCTLs. However, some of these are used by the HID class driver when it talks to a minidriver. It is not clear if any of these are available to HID clients.

Conclusion

This chapter concludes my look at the Human Input Device class driver. It is straightforward to write a user mode application to communicate with a HID device. A Win32 program looks for devices that use the HID device interface. They must then interrogate each device to see if their capabilities are of interest. The program can then read input reports and send output reports.

If need be, you can write a kernel mode HID client. It is best if you use the Plug and Play Notification technique to find any devices that support the HID device interface. Then, you can get the device capabilities and send and receive reports in a broadly similar way to user mode applications.

Both user mode and kernel mode HID clients can make use of the HID parsing routines. These make it much easier to find HID device's capabilities and to generate and understand reports.

Appendix A

Information Resources

Microsoft is the best source of information for most core Windows device driver development issues. Various books and newsgroups are also available to help driver writers. You may well need to check out other sources of information particular to your type of driver. You may need to seek help from vendors, standards bodies, and trade associations, as well as other driver writers.

A Microsoft Developer Network (MSDN) Professional Subscription provides most of the basic information you need to write device drivers. You get all the basic tools, Driver Development Kits (DDKs), and beta test versions of the Microsoft operating systems. However, it is worth keeping an eye on the Microsoft websites, as helpful articles and late-breaking news can often be posted. You will also need a C or C++ compiler, such as Visual Studio. The crucial Microsoft web sites are:

http://www.microsoft.com/hwdev/

http://www.microsoft.com/hwdev/driver/

http://msdn.microsoft.com/developer/

The DDKs include many example drivers that are very useful. Searching through these examples will often show you how to use a particular function or technique. Alternatively, you can base your entire driver on an existing example. Needless to say, do not use code blindly — make sure you understand what is going on. Finally, the sample driver directories often contain useful documentation in the form of Word or text files.

Table A.1 Information resources

Advanced Configuration and Power Interface Specification, Revision 1.0 http://www.teleport.com/~acpi/
Device Bay Interface Specification, Version 1.0 http://www.device-bay.org
Display Data Channel Standard, Version 3.0 http://www.vesa.org
Extended Display Identification Data Standard, Version 2.0
El Torito — Bootable CD-ROM Format Specification, Version 1.0 http://www.ptltd.com/techs/specs.html
Compaq, Intel, Phoenix BIOS Boot Specification, Version 1.01
Human Input Devices http://www.usb.org/developers/
IEEE 1394 Information ftp://ftp.symbios.com/pub/standards/io/
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату