MSDN WinUSB Example
The WinUSB user-mode library uses device interface classes to communicate with the kernel-mode USB stack. The INF file that loads winusb.sys specifies a device interface class GUID in the registry. When winusb.sys loads, it calls IoRegisterDeviceInterface to register a device interface that belongs to the device interface class that is specified in the registry.
User-mode software must call SetupDiGetClassDevs to enumerate the registered device interfaces that are associated with one of these device interface classes. The user-mode software must then pass the symbolic link of a device interface to the WinUsb_Initialize routine to obtain a WinUSB handle for the device interface.
The code example in this topic illustrates how user-mode software can enumerate device interfaces and obtain a WinUSB handle. For this example, assume that the INF file stores a device interface class GUID in the registry as follows.
HKR,,DeviceInterfaceGUIDs, 0x10000,"{058815B2-9805-47d3-B7D5-ABC464D3CA06}"
The example user-mode software calls SetupDiGetClassDevs to query for information about all of the registered device interfaces in the device interface class that is associated with this GUID. SetupDiGetClassDevs then returns a handle to a device information set that contains information about the device interfaces.
#include initguid.h
#include setupapi.h
// Example GUID definition. This GUID must match
// the GUID that was specified in the INF file
// that loaded winusb.sys.
DEFINE_GUID(InterfaceClassGuidConstant,0x058815B2, 0x9805, 0x47d3, 0xB7, 0xD5, 0xAB, 0xC4, 0x64, 0xD3, 0xCA, 0x06);
GUID InterfaceClassGuid = InterfaceClassGuidConstant;
// Define a handle to a device information set.
HDEVINFO hdevClassInfo;
// Retrieve a device information set.
hdevClassInfo = SetupDiGetClassDevs
(&InterfaceClassGuid, NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hdevClassInfo == INVALID_HANDLE_VALUE) {
// ERROR }
The call to SetupDiGetClassDevs in the preceding code
example requests registered device interfaces (DIGCF_DEVICEINTERFACE) for the
device interface class that the InterfaceClassGuid variable specifies.
Only device interfaces for presently installed devices (DIGCF_PRESENT) are
returned.
Next, the example application must iteratively call SetupDiEnumDeviceInterfaces
to determine how many elements are in the device information set.
// Initialize variables.
SP_DEVICE_INTERFACE_DATA DeviceData;
DeviceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
for (nMemberIndex = 0; TRUE; nMemberIndex++) {
nStatus = SetupDiEnumDeviceInterfaces (hdevClassInfo, NULL,
(LPGUID)&InterfaceGuid, nMemberIndex,
&DeviceData);
if (nStatus != TRUE) break;
}
Now, the example application must enumerate the registered device interfaces
that are associated with the device interface class. The example application
calls SetupDiEnumDeviceInterfaces iteratively, once again; but
now it retrieves hardware identifiers (IDs) and symbolic links for each
registered interface. The application will use the symbolic links to obtain a
WinUSB device interface handle.
// Allocate array that will hold information about the devices that
// are associated with this interface class.
struct DeviceData {
TCHAR *HardwareId;
TCHAR *Path; // symbolic link
TCHAR *FriendlyName;
DWORD DeviceInstance;
} *DeviceList;
DeviceList = (struct DeviceData *) malloc
((nMemberIndex + 1) * sizeof(struct DeviceData));
if (DeviceList == NULL) { // ERROR }
// Enumerate devices that are associated with the interface.
for (i = 0; i < nMemberIndex; i++) {
nStatus = SetupDiEnumDeviceInterfaces
(hdevClassInfo, NULL,
(LPGUID)&InterfaceGuid, i,
&DeviceData);
if (nStatus != TRUE) break;
// Retrieve the size of the device data.
nStatus = SetupDiGetDeviceInterfaceDetail
(hdevClassInfo, &DeviceData,
NULL, 0, &nSize, NULL);
if (nStatus != TRUE) break;
// Allocate memory for the device detail buffer.
SP_DEVICE_INTERFACE_DATA pBuffer;
pBuffer = (PSP_INTERFACE_DEVICE_DETAIL_DATA)
malloc (nSize));
if (pBuffer == NULL) { // ERROR }
// Initialize variables.
DeviceData.cbSize =
sizeof(SP_INTERFACE_DEVICE_DATA);
nStatus = SetupDiGetDeviceInterfaceDetail
(hdevClassInfo, &DeviceData,
pBuffer, nSize, NULL,&DeviceData));
if (nStatus = FALSE)) { // ERROR }
//****************************************
// Save the device interface path:
// This path can be used to open
// the interface with CreateFile.
//****************************************
// Calculate the length of the path string.
// Add 1 for the terminating NULL character.
nLen = strlen(DeviceData.DevicePath) + 1;
DeviceList[i].Path =
(TCHAR *) malloc (nLen * sizeof(TCHAR));
StringCchCopy(DeviceList[i].Path, nLen,
DeviceData.DevicePath);
// Save the device instance.
DeviceList[i].DeviceInstance =
DeviceInfoData.DevInst;
//****************************************
// Retrieve registry values.
//****************************************
// Initialize variables that are used in registry
// operations.
SP_DEVINFO_DATA DevInfoData;
//****************************************
// Retrieve the device friendly name.
//****************************************
// Query for the size of the friendly name.
nStatus = SetupDiGetDeviceRegistryProperty
(hdevClassInfo, &DevnfoData,
SPDRP_FRIENDLYNAME, &dwRegType,
NULL, 0, &dwRegSize);
if (nStatus == FALSE) { // ERROR }
// Allocate buffer for the friendly name.
pBuffer = (TCHAR *) malloc
(dwRegSize * sizeof(TCHAR));
if (pBuffer = == NULL) { // ERROR }
// Retrieve the friendly name.
nStatus = SetupDiGetDeviceRegistryProperty
(hdevClassInfo, &DevInfoData,
SPDRP_FRIENDLYNAME, NULL,
(PBYTE) *pBuffer, dwRegSize, NULL);
if (nStatus == FALSE) { // ERROR }
// Store the friendly name for this device.
DeviceList[i].FriendlyName = pBuffer;
// ************************************
// Retrieve the hardware ID.
// ************************************
// Query for the size of the hardware ID.
nStatus = SetupDiGetDeviceRegistryProperty
(hdevClassInfo, &DevnfoData,
SPDRP_HARDWAREID, &dwRegType,
NULL, 0, &dwRegSize);
if (nStatus == FALSE) { // ERROR }
// Allocate a buffer for the hardware ID.
pBuffer = (TCHAR *) malloc
(dwRegSize * sizeof(TCHAR));
if (pBuffer = == NULL) { // ERROR }
// Retrieve the hardware ID.
nStatus = SetupDiGetDeviceRegistryProperty
(hdevClassInfo, &DevInfoData,
SPDRP_HARDWAREID, NULL,
(PBYTE) *pBuffer, dwRegSize, NULL);
if (nStatus == FALSE) { // ERROR }
// Store the hardware ID for this device.
DeviceList[i].HardwareId = pBuffer;
}
The example software next opens the first device interface in the device
interface list. The device interface must be opened with the overlapped
flag.
// Create a symbolic link to device interface
LPCTSTR Path;
HANDLE DeviceInterfaceHandle;
Path = DeviceList[0].Path;
DeviceInterfaceHandle = CreateFile (Path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ |
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if (DeviceInterfaceHandle == INVALID_HANDLE_VALUE) { // ERROR }
After the example software opens the device interface, the application must
call WinUsb_Initialize to obtain a WinUSB handle.
WINUSB_INTERFACE_HANDLE WinUSBHandle;
nStatus = WinUsb_Initialize (DeviceInterfaceHandle, &WinUSBHandle);
if (nStatus = FALSE) { // ERROR }
The example software manages a composite USB device, whose first interface
(interface 0) contains bulk transfer endpoints. In the following code example,
the example software:
- Calls WinUsb_QueryInterfaceSettings to retrieve the
interface descriptor (USB_INTERFACE_DESCRIPTOR)
for interface 0. - Calls WinUsb_QueryPipe to query for information (WINUSB_PIPE_INFORMATION) about the pipe for endpoint 0.
- Verifies that the pipe is a bulk transfer pipe.
- Calls WinUsb_SetPipePolicy to set the time-out
interval for the pipe.
// ********************************************
// The first interface is for bulk transfers.
// ********************************************
USB_INTERFACE_DESCRIPTOR interface;
nStatus = WinUsb_QueryInterfaceSettings
(WinUSBHandle, 0, &interface);
if (nStatus = FALSE) { // ERROR }
WINUSB_PIPE_INFORMATION pipe;
nStatus = WinUsb_QueryPipe (WinUSBHandle, 0,
(UCHAR) 0, &pipe);
if (nStatus == FALSE) { // ERROR }
Verify that the pipe type is set to the correct USBD_PIPE_TYPE
enumeration value before calling WinUsb_SetPipePolicy.
if (pipe.PipeType != UsbdPipeTypeBulk) { // ERROR }
// Set the transfer time-out interval for endpoint 0
// to 10000 milliseconds.
UCHAR timeout = 10000;
nStatus = WinUsb_SetPipePolicy (WinUSBHandle,
pipe.PipeId, PIPE_TRANSFER_TIMEOUT,
sizeof (timeout), &timeout);
if (nStatus == FALSE) { // ERROR }
The second interface (interface 1) contains interrupt transfer endpoints. In
the following code example, the example software
- Calls WinUsb_GetAssociatedInterface to obtain a
handle to interface 1. - Calls WinUsb_QueryInterfaceSettings to retrieve the
interface descriptor for interface 1. - Calls WinUsb_QueryPipe to query for information about the
pipe for endpoint 0. - Verifies that the pipe is an interrupt transfer pipe.
// *************************************************
// The second interface is for interrupt transfers
// *************************************************
WINUSB_INTERFACE_HANDLE WinUSBHandleAlt;
nStatus = WinUsb_GetAssociatedInterface (WinUSBHandle, 0,
&WinUSBHandleAlt);
if (nStatus == FALSE) { // ERROR }
nStatus = WinUsb_QueryInterfaceSettings (WinUSBHandleAlt, 0,
&interface);
if (nStatus == FALSE) { // ERROR }
nStatus = WinUsb_QueryPipe (WinUSBHandleAlt, 0, (UCHAR) 0, &pipe);
if (nStatus == FALSE) { // ERROR }
if (pipe.PipeType != UsbdPipeTypeInterrupt) { // ERROR }
MSDN WinUSB Example的更多相关文章
- Visual Studio 2010的MSDN帮助文档离线使用
如果没有在安装vs过程中安装帮助,也可通过Visual Studio帮助菜单中的Manage Help Settings来对帮助进行设置或安装. 可以选择从磁盘安装内容,如果选择从磁盘安装可能会要求提 ...
- MSDN文档篇
很多人网上下载3~10G不等的MSDN文档,发现,下载完成了不会用 很多人每次都得在线下载文档,手上万千PC,都重新下载不是得疯了? so==> 先看几张图 推荐一个工具:https://vsh ...
- "Installation failed !" in GUI but not in CLI (/usr/bin/winusb: line 78: 18265 Terminated )
"Installation failed !" in GUI but not in CLI (/usr/bin/winusb: line 78: 18265 Terminated ...
- 使用SHFB(Sandcastle Help File Builder)建立MSDN风格的代码文档
使用SHFB(Sandcastle Help File Builder)建立MSDN风格的代码文档 下载地址:http://sandcastle.codeplex.com/ 下载地址2:http:// ...
- MSDN杂志上Wix相关的文章
使用 MSBuild 和 Windows Installer XML 执行自动发布: http://msdn.microsoft.com/zh-cn/magazine/cc163456.aspx 用于 ...
- 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)[msdn.microsoft.com]
看到Microsoft官方一篇关于异步编程的文章,感觉挺好,不敢独享,分享给大家. 原文地址:https://msdn.microsoft.com/zh-cn/library/hh191443.asp ...
- [已解决]从微软合作伙伴资源和MSDN下载系统和软件Microsoft download Manager无效
有个itellyou,更新了所有MSDN的软件包.如果自己有微软的注册账户,还是从微软官网下载比较好.而且对自己账户里的系统和itellyou里的做了对比.发现SHA1码不相同,估计官方分配的序列号也 ...
- diff/merge configuration in Team Foundation - common Command and Argument values - MSDN Blogs
One of the extensibility points we have in Team Foundation V1 is that you can configure any other di ...
- 源码网站(msdn.itellyou.cn) good
verysource 100万源码http://www.verysource.com/category/delphi-vcl/ MSDN DOWNLOADhttp://msdn.itellyou.cn ...
随机推荐
- 【转】用CornerStone配置SVN,HTTP及svn简单使用说明
已经安装了的小伙伴请直接看三步骤 一.下载地址 CornerStoneV2.6:http://pan.baidu.com/s/1qWEsEbM密码:www.macx.cn 二.安装破解方法 1.安装之 ...
- 第9月第12天 lua_push lua_to luaL_check stack quick
1. c代码中通过lua_push 把数据压入堆栈,lua调用c函数得到数据.luaL_check是对lua_to的封装,从堆栈中获取lua代码中函数调用的数据. static int lread(l ...
- ajax函数说明
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...
- Redis持久化——AOF
一.是什么? AOF是以日志的形式来记录每个写操作,将Redis执行过的所有写操作记录下来(读操作不做记录),只许追加文件不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis ...
- 记录自己对EventLoop和性能问题处理的一点心得【转】
转自:http://www.cnblogs.com/lanyuliuyun/p/4483384.html 1.EventLoop 这里说的EventLoop不是指某一个具体的库或是框架,而是指一种程序 ...
- free vmstat查看内存及系统调优【转】
内存查看 查看内存是否存在瓶颈,使用top指令看比较麻烦,而free命令更为直观: [/home/weber#]free total used free shared buffers cached M ...
- 揭开webRTC媒体服务器的神秘面纱——WebRTC媒体服务器&开源项目介绍
揭开webRTC媒体服务器的神秘面纱--WebRTC媒体服务器&开源项目介绍 WebRTC生态系统是非常庞大的.当我第一次尝试理解WebRTC时,网络资源之多让人难以置信.本文针对webRTC ...
- 在 Ubuntu13.10 服务器中安装 Munin(监视工具)【转】
Munin 监测工具可检测所有的计算机,并记录好看到的计算机.通过图形Web界面的的方式显示所有信息.重点是即插即用的功能.完成安装后,大量的控插件会被打. 使用 Munin 您可以轻松地监视您的计算 ...
- MySQL的聚集索引和非聚集索引
一. MYSQL的索引 mysql中,不同的存储引擎对索引的实现方式不同,大致说下MyISAM和InnoDB两种存储引擎. MyISAM的B+Tree的叶子节点上的data,并不是数据本身,而是数据存 ...
- Ueditor百度编辑器中的 setContent()方法的使用
百度编辑器Ueditor所提供的setContent()方法作用是:设置或者改变编辑器里面的文字内容或html内容 函数说明:setContent(string,boolean); 参数string ...