Windows Mini Class and Class Driver internal research notes



Background

-------------------------------------
This is a first windows driver research notes in my blogger. And I will try to keep it simple and clear in this article, for who wants to understand the internal behavior of Class And Mini-Class Driver.
-------------------------------------

Audience

-------------------------------------
For who wants to understand Mini-Class and Class Driver internal. And understanding more about Hid Device stack.
-------------------------------------


Introduction

-------------------------------------

First, We are going to take a example of HidUsb and HidClass, the former is a Mini-Class Driver of a HidClass.


We can simply think the relationships between them, is a child and parent relationship, Hidusb is one of the child of HidClass.


HidClass can be thought as a helper module( like Dll do) in kernel mode, for helping all Driver who wants to join a hid family.

-------------------------------------


Research

-------------------------------------

HidRegisterMiniDriver


According to MSDN, we have to call HidRegisterMinidriver to initialize a Hid Mini Class Driver, but how does it actually communicate with USB?


HidRegisterMiniDriver is exported by HidClass.sys


We could simply analysis the HidRegisterMiniDriver, it basically do a one thing, it hooked all of the IRP, and AddDevice of the HID Mini Driver Object ( such as , Hidusb Driver Object ) , and saving all of the old IRP in provided Driver object Extension.

As following (Pseudo code) :


Figure [1]


After that, HidClass is taking over the control of Mini Driver IRP, and more importantly, AddDevice has been already taking over, so when the PnP Manager try to call HidUsb's AddDevice for notify it a new device is plugged, it is actually calling a HidClass's AddDevice. But MiniDriver that one.

Function Device Object(FDO) 

------------------------------------
HidClass's AddDevice will helps all of its child create a Function Device Object(FDO) by using a child driver object. And it device name must be named _HID0000000x as following figure shown.

Figure[2]


HidClass's AddDevice will helps a Hidusb attach its device onto UsbHub / Usbccgp device, for communication, IRP Transfer.

After the FDO is created, and attached onto Usbhub / Usbccgp's device stack , Hidusb already has a ability to get a low level data transfer from its hub.

But we can see a problem that is, one HID device can provided more than one function, how HidClass can be ensure that HidUsb could tells a PnP manager which device object should be passed to a upper-level driver's AddDevice ( keyboard, mouse, joystick,etc.).



Figure [3]

Client Physical Device Object (Client PDO)

------------------------------------
Since the data parsing is not in same format, that's mean, system need to figure out which device object should be attached by upper-level appropriately, and so that their upper level driver can be run normally. As Figure[4] shown.



Figure [4]


Windows in order to solve this problem,  There is a undocumented concept comes, Client Pdo - Client Pdo is a "instance" of each HID device. such as , each _HID0000000x(FDO) can be able to provide two function (interfaces) , for example, webcam and usb-storage in a same device, such as following Figure, a single HID Device with two collection , so that will be two Client PDO.

But when and how can HIDClass know, how may Client PDO / Collection should be created?

when the device has been started, HidClass will received the IRP_MJ_PNP with minor function IRP_MN_START_DEVICE from PnP Manager, it parses a USB Report Descriptor and Create a collection and channel

As a result , we can't easily trace its device stack. Since the device named _HID000000x has two character in a different driver's device list ,

For UsbHid driver it isn't attached by anything. But it is related to one or many other device object , which saved in its driver extension

For UsbHub driver it is always attached to lower level device for committing and receiving the correct data for corresponding Usbhub port (physically).

But the interesting things is that both of the FDO and Client PDO , is also created by HidClass Driver. Since it hijacked HID MiniDriver's AddDevice and IRP Routine.

Therefore, how many number of Client PDO and what types of Client PDO will be created is totally, completely decided by HID Report Descriptor which previously fetch during the FDO initialization stage (by sending URB Packet to lower level). And stored into the FDO Driver Extension. So that whenever the PnP Manager wants to refresh the driver stack, it still be able to find out all relationship among them.

HID Report Descriptor

------------------------------------
How many collection means how many function is provided by this device.
How many channel means how many input/output usage in each collection.

Such as, Mouse HID Descriptor will as follow :
1 collection , 4 input usage (X, Y, Wheel, Button), So there is a 1 collection and 4 channel
Figure [5]

Some HID Device will provide a many function, so that will be many collection with many usage.

Client PDO Creation 

------------------------------------
After the descriptor parsed, HIDClass saved all of this information in the FDO extension(_HID0000000x)

And Most importantly, The Windows descriptor internal structure will recorded that how many collection will be included in this HID devices, and the structure will be saved in FDO Extension.

so that, HIDClass knows how many number of Client Physical Device Object should be created.

Figure[6]
After HidClass's Start Device Handler parsed descriptor, a Handler simply call a IoInvalidateDeviceRelations with FDO as parameter which indicated that what device relation should be refresh once.

It is trick part by Windows PnP Architecture, after this function, PnP Manager will send a IRP_MJ_PNP with IRP_MN_QUERY_DEVICE_RELATIONS minor function to HidClass Driver.

In that IRP handler, once again, HidClass take it over , it knows everything about FDO, and find the number of Client PDOs (collections) should be created in FDO Extension.

basically, it is a number of the collection in USB report descriptor as I mentioned

the device named: 0000000bX , X = [1, 6] in figure  , We called it is a client PDO, because it is attached by upper-level, for the HID client driver (kbdhid/ mouhid ,etc), it is a PDO character.

A device named 000000bx is corresponding to one specific function of its hid device. like following screen capture, there is a five specific functions (Client PDOs) of three hid device (FDOs).



Figure[6]

Figure[7]


Client PDO and FDO

------------------------------------
There is a reason that anything about the HID function is stored in FDO Extension, so Client PDO extension but have to store a back-pointer to its FDO extension. And get back its Report Descriptor at any given time to extract the data comes

So that when the upper level IRP is complete, devices understand the meaning of the data.

Conclusion

------------------------------------
A whole process of the initialization process will as following two graph:

Figure[8]

Figure[9]


1. HidClass's AddDevice Called by PnP Manager

2. HidClass's helps HidUsb create FDO (_HID0000000X) by HidUsb Driver Object

3. Pnp Manager send IRP with start device to HidClass

4. HidClass's Start Device Handler parse a descriptor, get the number of client pdo(000000bx), and call IoInvalidateDevice

5. PnP Send IRP_QUERY_DEVICE_RELATION with BusRelations

6. HidClass create a Client PDO by HidUsb Driver Object, And Save it in to HidUsb DeviceExtension. There is a flags to identify it is Client PDO / FDO in that extension, it affect the content which is in extension.

7. When Upper Level Driver loaded, PnP Manager call AddDevice and pass corresponding device object to its AddDevice. Such as, KbdHid Device, PnP Device call KbdHid's AddDevice with 000000b1 device object in UsbHid Driver.

------------------------------------

Thanks for reading ;)








Comments

  1. When you access content from this newsletter, your information may be shared with the sponsors or future sponsors of that content as described in ourSecurity Alarms in Moorabbin

    ReplyDelete

Post a Comment

Popular posts from this blog

Android Kernel Development - Kernel compilation and Hello World

How does Nested-Virtualization works?

Understanding ACPI and Device Tree