Develop the Host Program of the HID device in Windows

Source: Internet
Author: User

Reprinted please indicate the source

Author: Pony


 

This article mainly introduces how to develop a usb hid device-based PC program under XP to achieve simple communication between the host computer and hardware devices. I hope readers will forgive me for my limitations, shortcomings, and errors. I assume that the readers of this article have at least some knowledge about USB, hid, report descriptor, and other related concepts. If not, they should learn it on their own.

The development environment is supported by vs2005 and DDK. If DDK is not installed, you can find the relevant library files and header files online. The following files are required:

Basetsd. h

Hidclass. h

Hidpddi. h

Hidpi. h

Hidsdi. h

Hidusage. h

Hid. Lib

Hidclass. Lib

Hidparse. Lib

Setupapi. Lib

Developing such a program is not complicated. At least it is much simpler than writing a driver by using DDK. It is mainly used to familiarize yourself with the functions of some interfaces in DDK.

 

1. recognition device

To communicate with your own HID device, the first step is to find the device. it is easy to find the device. By comparing the device information we read with the actual device information, we can know whether the device has read the correct device. in a USB device, the information in the device descriptor uniquely identifies different USB devices. we generally use

Idvendor idproduct bcddevice

The three information identifies a USB device. the three information items are the properties in the device descriptor. therefore, our host computer program can compare the above three information with the actual device to determine whether the device is connected correctly. the device descriptor of the actual device can be found in the firmware program of the device. If you do not have the source code of the firmware program, you can also read the descriptor information of the device through some tool software, for example, USB view is a very useful tool.

You can use the APIs in DDK to identify the device.

The hidd_getattributes function can obtain the preceding attribute information, which is defined as follows:

Boolean

Hidd_getattributes (

In handle hiddeviceobject,

Out phidd_attributes attributes

);

 

The second parameter is a point

Hidd_attributes struct pointer, which is defined as follows:

Typedef struct _ hidd_attributes {

Ulong size;

Ushort vendorid;

Ushort productid;

Ushort versionnumber;

} Hidd_attributes

Therefore, this function can read the information we want from the device. however, the function also has an entry parameter, hiddeviceobject, which is a device handle. Therefore, before calling hidd_getattributes, you must call the createfile function to return a valid device operation handle. with this handle, you can communicate with the device normally.

The first parameter of createfile requires a device name. here we need to provide a complete device path name. Otherwise, an invalid handle is returned. the path name is assigned to the device after the operating system identifies the device. You can obtain it through the interface setupdigetdeviceinterfacedetail In the DDK. The definition of this function is as follows:

Setupdigetdeviceinterfacedetailw (

_ In hdevinfo deviceinfoset,

_ In psp_device_interface_data deviceinterfacedata,

_ Out_bcount_opt (deviceinterfacedetaildatasize) psp_device_interface_detail_data_w deviceinterfacedetaildata,

_ In DWORD deviceinterfacedetaildatasize,

_ Out_opt pdword requiredsize,

_ Out_opt psp_devinfo_data deviceinfodata

);

This function can obtain the details of a device interface. Note that the third parameter returns the path name returned by the third parameter. Its struct is defined as follows:

Typedef struct _ sp_device_interface_detail_data_w {

DWORD cbsize;

Wchar devicepath [anysize_array];

} Sp_device_interface_detail_data_w

The second data is the path we need.

This function has many parameters. Let's take a look at the third parameter, which is used to receive information about the device. According to the description on msdn, we can define it as follows:

Psp_device_interface_detail_datadetaildatabuffer;

Detaildatabuffer = (psp_device_interface_detail_data) malloc (requiredsize );

Detaildatabuffer-> cbsize = sizeof (sp_device_interface_detail_data );

The fourth parameter indicates the size of the third parameter. The fifth parameter is an exit parameter, which is returned by the system and tells us the actual size of the required space. therefore, we can call the setupdigetdeviceinterfacedetail function twice to obtain the requiredsize value for the first time and use it as the fourth parameter, as shown below:

Setupdigetdeviceinterfacedetail (deviceinfoset, & mydeviceinterfacedata,

Null, 0, & requiredsize, null );

Setupdigetdeviceinterfacedetail (deviceinfoset, & mydeviceinterfacedata,

Detaildatabuffer, requiredsize, & requiredsize, null );

The first two parameters are both input parameters. To obtain their values, you also need to call some other DDK interfaces. The second parameter mydeviceinterfacedata needs to be obtained using setupdienumdeviceinterfaces. The function is defined as follows:

Setupdienumdeviceinterfaces (

_ In hdevinfo deviceinfoset,

_ In_opt psp_devinfo_data deviceinfodata,

_ In const guid * interfaceclassguid,

_ In DWORD memberindex,

_ Out psp_device_interface_data deviceinterfacedata

);

Its function is to enumerate the interface information of a certain device in a certain type of device. interfaceclassguid indicates the category of the device and is identified by guid. My device is a standard HID device, memberindex indicates a device. For example, two hid devices are connected on my computer, the mouse and the keyboard. They share a guid. I use memberindex to distinguish them. Maybe 0 corresponds to the mouse, 1 corresponds to the keyboard. so it is obvious that this function can be called cyclically by changing the value of memberindex (from 0 to N) until the device we need is found.

 

The last step is how to get the guid of the device. Use a function, hidd_gethidguid (

Out lpguid hidguid

);

This function generates a guid type data, and the result is similar to the following format:

Guid: {4d1e55b2-f16f-11cf-88cb-00111111630}

With the above function, you can correctly identify a usb hid device. The DDK also provides some functions to obtain more detailed information about the device after finding the device, below are some common examples.

Boolean _ stdcall hidd_getproductstring (

_ In handle hiddeviceobject,

_ Out pvoid buffer,

_ In ulong bufferlength

);

This function can obtain the product string of the device. Of course, the premise is that the device must have the product string descriptor, because the string descriptor is optional in the device. the first parameter of this function is the handle returned by createfile. The string descriptor is expressed by a wide character. Therefore, you must note the conversion during reading. functions of the same type include:

Hidd_getmanufacturerstring

Hidd_getserialnumberstring1

Hidd_getindexedstring

 

In addition, there is a more important function

Ntstatus hidp_getcaps (

Phidp_preparsed_data preparseddata,

Phidp_caps capabilities

);

This function can obtain the communication capability of a device. Its second exit parameter is a struct like this:

Typedef struct _ hidp_caps

{

Usage usage;

Usage usagepage;

Ushort inputreportbytelength;

Ushort outputreportbytelength;

Ushort featurereportbytelength;

Ushort reserved [17];

 

Ushort numberlinkcollectionnodes;

 

Ushort numberinputbuttoncaps;

Ushort numberinputvaluecaps;

Ushort numberinputdataindices;

 

Ushort numberoutputbuttoncaps;

Ushort numberoutputvaluecaps;

Ushort numberoutputdataindices;

 

Ushort numberfeaturebuttoncaps;

Ushort numberfeaturevaluecaps;

Ushort numberfeaturedataindices;

} Hidp_caps, * phidp_caps;

The properties in this struct directly describe the specific functions of a device. For example, inputreportbytelength and outputreportbytelength indicate the input and output capabilities of the device at the communication endpoint respectively. these values are read in the device's endpoint descriptor. these values directly determine how to read and write the following hid devices.

You can also further obtain functions for a specific purpose (such as logical maximum and minimum values). For example, there is a function:

Ntstatus hidp_getvaluecaps (

Hidp_report_type reporttype,

Phidp_value_caps valuecaps,

Pulong valuecapslength,

Phidp_preparsed_data preparseddata

);

You can obtain the function of Value Type usage. After successfully calling hidp_getcaps, you can call hidp_getvaluecaps.

 

//////////////////////////////////////// ///////////////////

Result = hidp_getcaps (preparseddata, & capabilities );

Word nvaluecount = capabilities. numberinputvaluecaps;

 

Phidp_value_caps valuecaps = (phidp_value_caps) malloc (nvaluecount * sizeof (phidp_value_caps ));

 

Result = hidp_getvaluecaps (hidp_input, valuecaps, & nvaluecount, preparseddata );

//////////////////////////////////////// //////////////////

Not complete.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.