Window 驱动开发(三) WDK源码中 usbView 例子的编译及说明


引用于 http://blog.csdn.net/chenyujing1234 

欢迎大家提出意见,一起讨论!

示例代码: http://download.csdn.net/detail/chenyujing1234/4352191

 

Window 驱动开发(三) WDK源码中 usbView 例子的编译及说明_第1张图片

 

1、编译过程

步骤一、加入.h .c .rc文件

将D:\WINDDK\7600.16385.1\src\usb\usbview下的文件加入到VS2005中新建的工程中。

(方法参考 http://blog.csdn.net/chenyujing1234/article/details/7565364)

 

Window 驱动开发(三) WDK源码中 usbView 例子的编译及说明_第2张图片

步骤二、加.h .cpp .rc的连接目录与lib

 

.h

D:\WINDDK\7600.16385.1\inc\api;D:\WINDDK\7600.16385.1\Debuggers\winext\manifest

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

 .lib

D:\WINDDK\7600.16385.1\lib\wxp\i386

kernel32.lib user32.lib gdi32.lib comctl32.lib cfgmgr32.lib  setupapi.lib

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

.rc

D:\WINDDK\7600.16385.1\Debuggers\winext\manifest;D:\WINDDK\3790.1830\inc\wxp

定义预处理器定义: WINNT

Window 驱动开发(三) WDK源码中 usbView 例子的编译及说明_第3张图片

 

步骤三、修改usbview.rc文件

(1)屏蔽掉第26行  //#include <common.ver>

不然编译通过,但报错 error RC2104: undefined keyword or key name: VER_FILEFLAGSMASK

Window 驱动开发(三) WDK源码中 usbView 例子的编译及说明_第4张图片

 

(2)屏蔽掉第78 79行

#ifndef WINNT
    //LTEXT           "Version",IDC_STATIC,55,45,24,8
    //LTEXT           VER_PRODUCTVERSION_STR,IDC_STATIC,87,45,33,8
#endif

不然报错

VER_PRODUCTVERSION_STR未定义

==========================================================================================================

编译通过了.   ^-^

 

2、分析源码

(1)WinMain做使能指定堆的特征,然后就是创建窗口了

[cpp]  view plain copy
  1. int WINAPI  
  2. WinMain (  
  3.     __in HINSTANCE hInstance,  
  4.     __in_opt HINSTANCE hPrevInstance,  
  5.     __in LPSTR lpCmdLine,  
  6.     __in int nCmdShow  
  7. )  
  8. {  
  9.     MSG     msg;  
  10.     HACCEL  hAccel;  
  11.   
  12.     // 使能指定堆的特征  
  13.     HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);  
  14.   
  15.     ghInstance = hInstance;  
  16.   
  17.       
  18.   
  19.     ghSplitCursor = LoadCursor(ghInstance,  
  20.                                MAKEINTRESOURCE(IDC_SPLIT));  
  21.   
  22.     if (!ghSplitCursor)  
  23.     {  
  24.         OOPS();  
  25.         return 0;  
  26.     }  
  27.   
  28.     hAccel = LoadAccelerators(ghInstance,  
  29.                               MAKEINTRESOURCE(IDACCEL));  
  30.   
  31.     if (!hAccel)  
  32.     {  
  33.         OOPS();  
  34.         return 0;  
  35.     }  
  36.   
  37.     if (!CreateTextBuffer())  
  38.     {  
  39.         return 0;  
  40.     }  
  41.   
  42.     if (!CreateMainWindow(nCmdShow))  
  43.     {  
  44.         return 0;  
  45.     }  
  46.   
  47.     while (GetMessage(&msg, NULL, 0, 0))  
  48.     {  
  49.         if (!TranslateAccelerator(ghMainWnd,  
  50.                                   hAccel,  
  51.                                   &msg) &&  
  52.             !IsDialogMessage(ghMainWnd,  
  53.                              &msg))  
  54.         {  
  55.             TranslateMessage(&msg);  
  56.             DispatchMessage(&msg);  
  57.         }  
  58.     }  
  59.   
  60.     DestroyTextBuffer();  
  61.   
  62.     CHECKFORLEAKS();  
  63.   
  64.     return 1;  
  65. }  


 

(2)在初始化窗口里向系统注册了两个通知:USB插入通知,HUB设备通知; 然后就是调用RefreshTree();来刷新树Hub列表

 

[cpp]  view plain copy
  1. BOOL  
  2. USBView_OnInitDialog (  
  3.     HWND    hWnd,  
  4.     HWND    hWndFocus,  
  5.     LPARAM  lParam  
  6. )  
  7. {  
  8.     HFONT                           hFont;  
  9.     HIMAGELIST                      himl;  
  10.     HICON                           hicon;  
  11.     DEV_BROADCAST_DEVICEINTERFACE   broadcastInterface;  
  12.   
  13.   
  14.     // 注册当USB被插入的通知   
  15.     broadcastInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);  
  16.     broadcastInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;  
  17.   
  18.     memcpy( &(broadcastInterface.dbcc_classguid),  
  19.             &(GUID_CLASS_USB_DEVICE),  
  20.             sizeof(struct _GUID));  
  21.   
  22.     gNotifyDevHandle = RegisterDeviceNotification(hWnd,  
  23.                                                   &broadcastInterface,  
  24.                                                   DEVICE_NOTIFY_WINDOW_HANDLE);  
  25.   
  26.     // 注册Hub 通知  
  27.     memcpy( &(broadcastInterface.dbcc_classguid),  
  28.             &(GUID_CLASS_USBHUB),  
  29.             sizeof(struct _GUID));  
  30.   
  31.     gNotifyHubHandle = RegisterDeviceNotification(hWnd,  
  32.                                                   &broadcastInterface,  
  33.                                                   DEVICE_NOTIFY_WINDOW_HANDLE);  
  34.   
  35.     //end add  
  36.   
  37.     ghTreeWnd = GetDlgItem(hWnd, IDC_TREE);  
  38.   
  39.     //added  
  40.     if ((himl = ImageList_Create(15, 15,  
  41.                                  FALSE, 2, 0)) == NULL)  
  42.     {  
  43.         OOPS();  
  44.     }  
  45.   
  46.     hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_ICON));  
  47.     giGoodDevice = ImageList_AddIcon(himl, hicon);  
  48.   
  49.     hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_BADICON));  
  50.     giBadDevice = ImageList_AddIcon(himl, hicon);  
  51.   
  52.     hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_COMPUTER));  
  53.     giComputer = ImageList_AddIcon(himl, hicon);  
  54.   
  55.     hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_HUB));  
  56.     giHub = ImageList_AddIcon(himl, hicon);  
  57.   
  58.     hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_NODEVICE));  
  59.     giNoDevice = ImageList_AddIcon(himl, hicon);  
  60.   
  61.   
  62.     TreeView_SetImageList(ghTreeWnd, himl, TVSIL_NORMAL);  
  63.     // end add  
  64.   
  65.   
  66.     ghEditWnd = GetDlgItem(hWnd, IDC_EDIT);  
  67.   
  68.     ghStatusWnd = GetDlgItem(hWnd, IDC_STATUS);  
  69.   
  70.     ghMainMenu = GetMenu(hWnd);  
  71.   
  72.     if (ghMainMenu == NULL)  
  73.     {  
  74.         OOPS();  
  75.     }  
  76.   
  77.     hFont  = CreateFont(13,  8, 0, 0,  
  78.                         400, 0, 0, 0,  
  79.                         0,   1, 2, 1,  
  80.                         49,  TEXT("Courier"));  
  81.   
  82.     SendMessage(ghEditWnd,  
  83.                 WM_SETFONT,  
  84.                 (WPARAM) hFont,  
  85.                 0);  
  86.   
  87.     //  刷新Hub列表  
  88.     RefreshTree();  
  89.   
  90.     return FALSE;  
  91. }  


 (3)

[cpp]  view plain copy
  1. VOID RefreshTree (VOID)  
  2. {  
  3.     TCHAR  statusText[128];  
  4.     ULONG devicesConnected;  
  5.    
  6.     // Clear the selection of the TreeView, so that when the tree is  
  7.     // destroyed, the control won't try to constantly "shift" the  
  8.     // selection to another item.  
  9.     //  
  10.     TreeView_SelectItem(ghTreeWnd, NULL);  
  11.    
  12.     // Clear the edit control  
  13.     //  
  14.     SetWindowText(ghEditWnd, _T(""));  
  15.    
  16.     // Destroy the current contents of the TreeView  
  17.     //  
  18.     if (ghTreeRoot)  
  19.     {  
  20.         WalkTree(ghTreeRoot, CleanupItem, 0);  
  21.    
  22.         TreeView_DeleteAllItems(ghTreeWnd);  
  23.    
  24.         ghTreeRoot = NULL;  
  25.     }  
  26.    
  27.     // Create the root tree node  
  28.     //  
  29.     ghTreeRoot = AddLeaf(TVI_ROOT, 0, _T("My Computer"), ComputerIcon);  
  30.    
  31.     if (ghTreeRoot != NULL)  
  32.     {  
  33.         // Enumerate all USB buses and populate the tree  
  34.         //  
  35.         EnumerateHostControllers(ghTreeRoot, &devicesConnected);  
  36.    
  37.         //  
  38.         // Expand all tree nodes  
  39.         //  
  40.         WalkTree(ghTreeRoot, ExpandItem, 0);  
  41.    
  42.         // Update Status Line with number of devices connected  
  43.         //  
  44.         _stprintf_s(statusText, sizeof(statusText)/sizeof(statusText[0]), _T("Devices Connected: %d   Hubs Connected: %d"),  
  45.                  devicesConnected, TotalHubs);  
  46.         SetWindowText(ghStatusWnd, statusText);  
  47.     }  
  48.     else  
  49.     {  
  50.         OOPS();  
  51.     }  
  52.    
  53. }  


 

从以上代码可以看出RefreshTree做了以下几件事:

21)用TreeTreeView_SelectIItem宏来清除TreeView中的选项。

目的是当树被毁坏时,控件不会try to constantly "shift" the selection to another item

22)清除编辑框控件;

23)毁坏TreeView当前的内容。

[cpp]  view plain copy
  1. // Destroy the current contents of the TreeView  
  2.     //  
  3.     if (ghTreeRoot)  
  4.     {  
  5.         WalkTree(ghTreeRoot, CleanupItem, 0);  
  6.    
  7.         TreeView_DeleteAllItems(ghTreeWnd);  
  8.    
  9.         ghTreeRoot = NULL;  
  10.     }  



WalkTree是一个不好理解的函数,它是一个递归函数,在两个地方递归:

对于上面代码,它首先会递归调用来找到ghTreeRoot的孩子节点,然后调用CleanupItem函数;

然后对ghTreeWnd调用CleanupItem函数;

最后会递归调用找到ghTreeRoot的弟兄节点,然后调用CleanupItem函数;

[cpp]  view plain copy
  1. VOID  
  2. CleanupItem (  
  3.     HWND      hTreeWnd,  
  4.     HTREEITEM hTreeItem  
  5. )  
  6. {  
  7.     TV_ITEM tvi;  
  8.     PVOID   info;  
  9.    
  10.     tvi.mask = TVIF_HANDLE | TVIF_PARAM;  
  11.     tvi.hItem = hTreeItem;  
  12.    
  13.     TreeView_GetItem(hTreeWnd,  
  14.                      &tvi);  
  15.    
  16.     info = (PVOID)tvi.lParam;  
  17.    
  18.     if (info)  
  19.     {  
  20.         PTSTR                               DriverKey = NULL;  
  21.         PUSB_NODE_INFORMATION               HubInfo = NULL;  
  22.         PUSB_HUB_CAPABILITIES               HubCaps = NULL;  
  23.         PUSB_HUB_CAPABILITIES_EX            HubCapsEx = NULL;  
  24.         PTSTR                               HubName = NULL;  
  25.         PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfoEx = NULL;  
  26.         PUSB_DESCRIPTOR_REQUEST             ConfigDesc = NULL;  
  27.         PSTRING_DESCRIPTOR_NODE             StringDescs = NULL;  
  28.    
  29.         switch (*(PUSBDEVICEINFOTYPE)info)  
  30.         {  
  31.             case HostControllerInfo:  
  32.                 //  
  33.                 // Remove this host controller from the list of enumerated  
  34.                 // host controllers.  
  35.                 //  
  36.                 RemoveEntryList(&((PUSBHOSTCONTROLLERINFO)info)->ListEntry);  
  37.    
  38.                 DriverKey = ((PUSBHOSTCONTROLLERINFO)info)->DriverKey;  
  39.                 break;  
  40.    
  41.             case RootHubInfo:  
  42.                 HubInfo = ((PUSBROOTHUBINFO)info)->HubInfo;  
  43.                 HubName = ((PUSBROOTHUBINFO)info)->HubName;  
  44.                 HubCaps = ((PUSBROOTHUBINFO)info)->HubCaps;  
  45.                 HubCapsEx = ((PUSBROOTHUBINFO)info)->HubCapsEx;  
  46.                 break;  
  47.    
  48.             case ExternalHubInfo:  
  49.                 HubInfo = ((PUSBEXTERNALHUBINFO)info)->HubInfo;  
  50.                 HubName = ((PUSBEXTERNALHUBINFO)info)->HubName;  
  51.                 HubCaps = ((PUSBROOTHUBINFO)info)->HubCaps;  
  52.                 HubCapsEx = ((PUSBROOTHUBINFO)info)->HubCapsEx;  
  53.                 ConnectionInfoEx = ((PUSBEXTERNALHUBINFO)info)->ConnectionInfo;  
  54.                 ConfigDesc = ((PUSBEXTERNALHUBINFO)info)->ConfigDesc;  
  55.                 StringDescs = ((PUSBEXTERNALHUBINFO)info)->StringDescs;  
  56.                 break;  
  57.    
  58.             case DeviceInfo:  
  59.                 ConnectionInfoEx = ((PUSBDEVICEINFO)info)->ConnectionInfo;  
  60.                 ConfigDesc = ((PUSBDEVICEINFO)info)->ConfigDesc;  
  61.                 StringDescs = ((PUSBDEVICEINFO)info)->StringDescs;  
  62.                 break;  
  63.         }  
  64.    
  65.         if (DriverKey)  
  66.         {  
  67.             FREE(DriverKey);  
  68.         }  
  69.    
  70.         if (HubInfo)  
  71.         {  
  72.             FREE(HubInfo);  
  73.         }  
  74.    
  75.         if (HubName)  
  76.         {  
  77.             FREE(HubName);  
  78.         }  
  79.    
  80.         if (HubCaps)  
  81.         {  
  82.             FREE(HubCaps);  
  83.         }  
  84.    
  85.         if (HubCapsEx)  
  86.         {  
  87.             FREE(HubCapsEx);  
  88.         }  
  89.    
  90.         if (ConfigDesc)  
  91.         {  
  92.             FREE(ConfigDesc);  
  93.         }  
  94.    
  95.         if (StringDescs)  
  96.         {  
  97.             PSTRING_DESCRIPTOR_NODE Next;  
  98.    
  99.             do {  
  100.    
  101.                 Next = StringDescs->Next;  
  102.                 FREE(StringDescs);  
  103.                 StringDescs = Next;  
  104.    
  105.             } while (StringDescs);  
  106.         }  
  107.    
  108.         if (ConnectionInfoEx)  
  109.         {  
  110.             FREE(ConnectionInfoEx);  
  111.         }  
  112.    
  113.         FREE(info);  
  114.     }  
  115. }  


 


24)创建根树节点

ghTreeRoot = AddLeaf(TVI_ROOT, 0, _T("My Computer"), ComputerIcon);


25)枚举所有的USB总线并填充入树中

[cpp]  view plain copy
  1. // Enumerate all USB buses and populate the tree  
  2. //  
  3. EnumerateHostControllers(ghTreeRoot, &devicesConnected);  


EnumerateHostControllers做了以下事情:

251)重复试主控制器并尽力打开它们;

如果打得开HCD设备,那么再去枚举主控制器。

[cpp]  view plain copy
  1. for (HCNum = 0; HCNum < NUM_HCS_TO_CHECK; HCNum++)  
  2. {  
  3.     _stprintf_s(HCName, sizeof(HCName)/sizeof(HCName[0]), _T("\\\\.\\HCD%d"), HCNum);  
  4.   
  5.            // 打开HCD设备  
  6.     hHCDev = CreateFile(HCName,  
  7.                         GENERIC_WRITE,  
  8.                         FILE_SHARE_WRITE,  
  9.                         NULL,  
  10.                         OPEN_EXISTING,  
  11.                         0,  
  12.                         NULL);  
  13.   
  14.     // If the handle is valid, then we've successfully opened a Host  
  15.     // Controller.  Display some info about the Host Controller itself,  
  16.     // then enumerate the Root Hub attached to the Host Controller.  
  17.     //  
  18.     if (hHCDev != INVALID_HANDLE_VALUE)  
  19.     {  
  20.         leafName = HCName + _tcslen(_T("\\\\.\\")) - _tcslen(_T(""));  
  21.   
  22.                    // 枚举主控制器  
  23.         EnumerateHostController(hTreeParent,  
  24.                                 hHCDev,  
  25.                                 leafName);  
  26.   
  27.         CloseHandle(hHCDev);  
  28.     }  
  29. }  



EnumerateHostController

2511)分配一个结构体保存关于主控制器的信息

 

[cpp]  view plain copy
  1. typedef struct _USBHOSTCONTROLLERINFO  
  2. {  
  3.     USBDEVICEINFOTYPE                   DeviceInfoType;  
  4.    
  5.     LIST_ENTRY                          ListEntry;  
  6.    
  7.     PTSTR                               DriverKey;  
  8.    
  9.     ULONG                               VendorID;  
  10.    
  11.     ULONG                               DeviceID;  
  12.    
  13.     ULONG                               SubSysID;  
  14.    
  15.     ULONG                               Revision;  
  16.    
  17. } USBHOSTCONTROLLERINFO, *PUSBHOSTCONTROLLERINFO;  


 hcInfo = (PUSBHOSTCONTROLLERINFO)ALLOC(sizeof(USBHOSTCONTROLLERINFO));


 

2512)为此主控制器获得驱动的主名字

 driverKeyName = GetHCDDriverKeyName(hHCDev);


 

2513)它果它已经在枚举的主控制器列表中,那么就不枚举了

[cpp]  view plain copy
  1. listEntry = EnumeratedHCListHead.Flink;  
  2.    
  3. while (listEntry != &EnumeratedHCListHead)  
  4. {  
  5.     hcInfoInList = CONTAINING_RECORD(listEntry,  
  6.                                      USBHOSTCONTROLLERINFO,  
  7.                                      ListEntry);  
  8.   
  9.                    // 已经在列表中  
  10.     if (_tcscmp(driverKeyName, hcInfoInList->DriverKey) == 0)  
  11.     {  
  12.         // Already on the list, exit  
  13.         //  
  14.         FREE(driverKeyName);  
  15.         FREE(hcInfo);  
  16.         return;  
  17.     }  
  18.   
  19.     listEntry = listEntry->Flink;  
  20. }  



 

2514)为主控制器获得设备的id

[cpp]  view plain copy
  1. deviceDesc = DriverNameToDeviceDesc(driverKeyName, FALSE);  
  2.    
  3. if (deviceDesc)  
  4. {  
  5.     leafName = deviceDesc;  
  6. }  
  7. else  
  8. {  
  9.     OOPS();  
  10. }  




 

2515)增加此控制器到设备树中

 

[cpp]  view plain copy
  1. hHCItem = AddLeaf(hTreeParent,  
  2.                   (LPARAM)hcInfo,  
  3.                   leafName,  
  4.                   GoodDeviceIcon);  



添加后返回HTREEITEM类型。

2516)把这个主控制器加入到已枚举的主控制器列表中;

2517)获得这个主控制器的root hub的名字,然后根据(2515)中返回的HTREEITEM变量来枚举root hub

 

[cpp]  view plain copy
  1. rootHubName = GetRootHubName(hHCDev);  
  2.    
  3. if (rootHubName != NULL)  
  4. {  
  5.     if (EnumerateHub(hHCItem,  
  6.                  rootHubName,  
  7.                  NULL,      // ConnectionInfo  
  8.                  NULL,      // ConfigDesc  
  9.                  NULL,      // StringDescs  
  10.                  _T("RootHub")  // DeviceDesc  
  11.                 ) == FALSE)  
  12.     {  
  13.         FREE(rootHubName);  
  14.     }  
  15. }  



 

252)现在用新的GUIO迭代主控制器(与(251)的操作有点类似)

[cpp]  view plain copy
  1. deviceInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_HOST_CONTROLLER,  
  2.                                      NULL,  
  3.                                      NULL,  
  4.                                      (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));  



HDEVINFO

  SetupDiGetClassDevs(

  const GUID* ClassGuid,

  PCTSTR Enumerator,

  HWND hwndParent,

  DWORD Flags

  );
参数说明  

输入参数:

  PGUIDClassGuid

  在创建设备列表的时候提供一个指向GUID的指针。如果设定了标志DIGCF_ALLCLASSES,则这个参数可以忽略,且列表结果中包括所有已经安装的设备类别

  PCTSTREnumerator

  提供包含设备实例的枚举注册表分支下的键名,可以通过它获取设备信息。如果这个参数没有指定,则要从整个枚举树中获取所有设备实例的设备信息

  HWNDhwndParent

  提供顶级窗口的句柄,所有用户接口可以使用它来与成员联系

  DWORDFlags

  提供在设备信息结构中使用的控制选项。可以是以下数值:

  DIGCF_PRESENT - 只返回当前存在的设备

  DIGCF_ALLCLASSES - 返回所有已安装的设备。如果这个标志设置了,ClassGuid参数将被忽略。

  DIGCF_PROFILE - 只返回当前硬件配置文件中的设备。

  DIGCF_DEVICEINTERFACE - 返回所有支持的设备

  DIGCF_DEFAULT - 只返回与系统默认设备相关的设备。

返回值

  HDEVINFO

  如果函数运行成功,返回设备信息结构的句柄,该结构包含与指定参数匹配的所有已安装设备。如果失败,则返回INVALID_HANDLE_VALUE。调用GetLastError可以获得更多错误信息。

2521)根据(252)的返回的的HDEVINFO枚举出所有USB设备的信息。

[cpp]  view plain copy
  1. for (index=0;  
  2.  SetupDiEnumDeviceInterfaces(deviceInfo,  
  3.                              0,  
  4.                              (LPGUID)&GUID_CLASS_USB_HOST_CONTROLLER,  
  5.                              index,  
  6.                              &deviceInfoData);  



SetupDiEnumDeviceInterfaces为系统的API,它用于:

枚举出被包含在设备信息集里的接口。

[cpp]  view plain copy
  1. BOOL SetupDiEnumDeviceInterfaces(  
  2.   _In_      HDEVINFO DeviceInfoSet,  
  3.   _In_opt_  PSP_DEVINFO_DATA DeviceInfoData,  
  4.   _In_      const GUID *InterfaceClassGuid,  
  5.   _In_      DWORD MemberIndex,  
  6.   _Out_     PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData  
  7. );  


 

Parameters

DeviceInfoSet [in]

A pointer to a device information set that contains the device interfaces for which to return information. This handle is typically returned by SetupDiGetClassDevs .

DeviceInfoData [in, optional]

A pointer to an SP_DEVINFO_DATA structure that specifies a device information element in DeviceInfoSet. This parameter is optional and can be NULL. If this parameter is specified, SetupDiEnumDeviceInterfacesconstrains the enumeration to the interfaces that are supported by the specified device. If this parameter isNULL, repeated calls to SetupDiEnumDeviceInterfaces return information about the interfaces that are associated with all the device information elements in DeviceInfoSet. This pointer is typically returned bySetupDiEnumDeviceInfo .

InterfaceClassGuid [in]

A pointer to a GUID that specifies the device interface class for the requested interface.

MemberIndex [in]

A zero-based index into the list of interfaces in the device information set. The caller should call this function first with MemberIndex set to zero to obtain the first interface. Then, repeatedly increment MemberIndex and retrieve an interface until this function fails and GetLastError returns ERROR_NO_MORE_ITEMS.

If DeviceInfoData specifies a particular device, the MemberIndex is relative to only the interfaces exposed by that device.

DeviceInterfaceData [out]

A pointer to a caller-allocated buffer that contains, on successful return, a completedSP_DEVICE_INTERFACE_DATA structure that identifies an interface that meets the search parameters. The caller must set DeviceInterfaceData.cbSize to sizeof(SP_DEVICE_INTERFACE_DATA) before calling this function.

2522)根据(2521)得到的设备信息来获得设备接口的详细信息

[cpp]  view plain copy
  1. SetupDiGetDeviceInterfaceDetail(deviceInfo,  
  2.                                             &deviceInfoData,  
  3.                                             NULL,  
  4.                                             0,  
  5.                                             &requiredLength,  
  6.                                             NULL);  
  7.    
  8. deviceDetailData = GlobalAlloc(GPTR, requiredLength);  
  9.   
  10. deviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);  
  11.   
  12.            // 获得设备接口的详细信息  
  13. SetupDiGetDeviceInterfaceDetail(deviceInfo,  
  14.                                 &deviceInfoData,  
  15.                                 deviceDetailData,  
  16.                                 requiredLength,  
  17.                                 &requiredLength,  
  18.                                 NULL);  



2523)根据(2522)得到的详细信息中的名称来打开设备,度枚举出主控制器

[cpp]  view plain copy
  1. hHCDev = CreateFile(deviceDetailData->DevicePath,  
  2.                                 GENERIC_WRITE,  
  3.                                 FILE_SHARE_WRITE,  
  4.                                 NULL,  
  5.                                 OPEN_EXISTING,  
  6.                                 0,  
  7.                                 NULL);  
  8.    
  9. // If the handle is valid, then we've successfully opened a Host  
  10. // Controller.  Display some info about the Host Controller itself,  
  11. // then enumerate the Root Hub attached to the Host Controller.  
  12. //  
  13. if (hHCDev != INVALID_HANDLE_VALUE)  
  14. {  
  15.     leafName = deviceDetailData->DevicePath;  
  16.   
  17.                    // 枚举主控制器  
  18.     EnumerateHostController(hTreeParent,  
  19.                             hHCDev,  
  20.                             leafName);  
  21.   
  22.     CloseHandle(hHCDev);  
  23. }  



26)扩展所有的树节点

  

[cpp]  view plain copy
  1. // Expand all tree nodes  
  2. //  
  3. WalkTree(ghTreeRoot, ExpandItem, 0);  


 

27)用已连接的设备的ID号来更新状态行。

 

[cpp]  view plain copy
  1.  _stprintf_s(statusText, sizeof(statusText)/sizeof(statusText[0]), _T("Devices Connected: %d   Hubs Connected: %d"),  
  2.                  devicesConnected, TotalHubs);  
  3. SetWindowText(ghStatusWnd, statusText);  



 

 

 

 




你可能感兴趣的:(Window 驱动开发(三) WDK源码中 usbView 例子的编译及说明)