rainit2006 / My_Windows

0 stars 0 forks source link

Device操作, HID Device (sucha as USB) #4

Open rainit2006 opened 7 years ago

rainit2006 commented 7 years ago

Device Management的函数一览 (SetupDixxxxx系列): https://msdn.microsoft.com/ja-jp/library/cc429159.aspx Device入出力 (DeviceIOControl) https://msdn.microsoft.com/ja-jp/library/cc392652.aspx

Collection Capability The capability of a collection is defined by its usage, reports, link collections, and controls. To obtain a summary of a collection's capability, a user-mode application or kernel-mode driver calls HidP_GetCaps to obtain a HIDP_CAPS structure. https://msdn.microsoft.com/windows/hardware/drivers/hid/collection-capability

HID drivers Human Interface Devices (or HID). Typically, these are devices that humans use to directly control the operation of computer systems. The definition of HID started as a device class over USB. Today, HID devices include: alphanumeric displays, barcode readers, volume controls on speakers/headsets, auxiliary displays, sensors, and MRI’s (yes, in hospitals). In addition, many hardware vendors use HID for their proprietary devices. https://msdn.microsoft.com/zh-cn/windows/hardware/drivers/hid/index

Today, HID has a standard protocol over multiple transports, and the following transports are supported natively in Windows 8 for HID: •USB •Bluetooth •Bluetooth LE •I²C https://msdn.microsoft.com/zh-cn/windows/hardware/drivers/hid/introduction-to-hid-concepts

rainit2006 commented 7 years ago

HIDクラスでは、レポートと呼ばれる単位でデータを転送する レポートの中にどのような情報がどのように並んでいるかは、レポートディスクリプタによって定義 レポートディスクリプタは、他のディスクリプタと構造が全く違う HIDディスクリプタに続いて送られ、可変長。 レポートディスクリプタのサイズはHIDディスクリプタのwDescriptorLengthで定義

HID インターフェースでは、Input、Output、Featureの3タイプのレポートをデバイスとホストの間で転送し ます。

レポートディスクリプタはデバイスに関する情報を提供するまとまり(アイテム)から構成される アイテムはショートアイテムとロングアイテムの2種類 item type には「Main」「Global」「Local」の 3 種類があり、Main item type(リポートディスクリプタ内 のデータフィールドを定義もしくはグループ化に使用)は 5 種類、Global item type(データを記述に使用) は12 種類、Local item type(特性を定義に使用)は 10 種類の item tag があります。

アイテムの形式 すべてのアイテムは1バイトのプレフィックスを持つ。 アイテムは「data」、「item tag」、「item type」と「itemSize」の 4 種類から構成されます。

パース時の動作 メインアイテムがでてくると新しいレポート構造が一時状態テーブルに割り当てられる。 グローバルアイテムはメインアイテムが出てきても一時状態テーブルに残る。 ローカルアイテムはメインアイテムが出てきたら一時状態テーブルから消える。

rainit2006 commented 7 years ago

Open the target Device 目的是获得目标Device的句柄

流程:

  1. HidD_GetHidGuid: 获得HID设备的GUID returns the device interfaceGUID for HIDClass devices.

2, SetupDiGetClassDevs: 利用GUID取得所有HID Devices信息集合
returns a handle to a device information set that contains requested device information elements for a local computer. 从GUID取得devices信息。

另外:リモートコンピュータ上のデバイスに関するデバイス情報セットを取得するには、SetupDiGetClassDevsEx関数を使います。

3, SetupDiEnumDeviceInfo: 枚举取得每个HID Device信息(SP_DEVINFO_DATA 结构体),利用index循环取得 returns a SP_DEVINFO_DATA structure that specifies a device information element in a device information set. 根据index参数取得相应的device信息。

4, 从SP_DEVINFO_DATA structure里获得HardwareID(HID)。具体实现: SetupDiGetDeviceRegistryProperty: retrieves a specified Plug and Play device property. 第三个参数里指定“SPDRP_HARDWAREID”时刻获得HardwareID。 HardwareID内容类似:"HID\VID_054C&PID_0872&MI_01&Col04"

5, 将HaredwareID和目标HardwareID进行比较,判断当前取得的Device是否是TargetDevice。 如果找到TargetDevice则往下执行。

6,取出目标Device的Path信息(变量名: strDevicePath)。具体实现用到下面两个接口。 (1)SetupDiEnumDeviceInterfaces 判断能否取得Interface以及Interface的size (2)SetupDiGetDeviceInterfaceDetail: returns details about a device interface. 其中的output 之一DeviceInterfaceDetailData里包含了path信息。

7, 取得句柄 hDeviceHandle = CreateFile(strDevicePath, GENERIC_READ | GENERIC_WRITE/0/, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL );

8, SetupDiDestroyDeviceInfoList

rainit2006 commented 7 years ago

向目标Device(HID设备)发送command 方法:HidD_SetFeature

//Example
        UCHAR buffer[BUFFER_LENGETH] = {0};
    buffer[0] = 0x01;
    buffer[1] = 0x0F;
    buffer[2] = 0x5B;   

    bRet = HidD_SetFeature(m_hDeviceHandle, buffer, BUFFER_LENGETH);

取得Device状态 根据需要,先HidD_SetFeature, 然后HidD_GetFeature。

rainit2006 commented 7 years ago

其他常用函数: SetupDiGetDeviceInstanceId 可以获得DeviceID

设定设备的有效/无效 的处理流程:

SetupDiGetClassDevs ⇒ デバイス情報セットの取得
SetupDiEnumDeviceInfo ⇒ デバイスの列挙
 列挙中に
 CM_Get_DevNode_Status ⇒ デバイスの状態(有効or無効)を取得
  SetupDiGetDeviceRegistryProperty ⇒ デバイス名を取得
 取得したりして、制御対象のデバイスを探します。

SetupDiSetClassInstallParams ⇒ デバイスの有効/無効化
SetupDiChangeState ⇒ 変更を反映

SetupDiDestroyDeviceInfoList ⇒ デバイス情報セットを解放
rainit2006 commented 7 years ago

DeviceIOControl 指定されたデバイスドライバへ制御コードを直接送信し、対応するデバイスに対応する動作をさせます。 用来控制我们指定设备的输入输出操作,使设备按照我们发的指令去工作。 应用场景: 如获取硬件设备信息、与硬件设备通信(读写数据)等

For most types of device, the application can use the standard MicrosoftWin32 API function DeviceIoControl. On the driver side, an application’s call to DeviceIoControl turns into an I/O request packet (IRP) with the major function code IRP_MJ_DEVICE_CONTROL. But,with several specific types of device, however, an application isn’t supposed to (or can’t) use DeviceIoControl to talk to a driver.


BOOL DeviceIoControl(
  HANDLE hDevice,              // デバイス、ファイル、ディレクトリいずれかのハンドル
  DWORD dwIoControlCode,       // 実行する動作の制御コード
  LPVOID lpInBuffer,           // 入力データを供給するバッファへのポインタ
  DWORD nInBufferSize,         // 入力バッファのバイト単位のサイズ
  LPVOID lpOutBuffer,          // 出力データを受け取るバッファへのポインタ
  DWORD nOutBufferSize,        // 出力バッファのバイト単位のサイズ
  LPDWORD lpBytesReturned,     // バイト数を受け取る変数へのポインタ
  LPOVERLAPPED lpOverlapped    // 非同期動作を表す構造体へのポインタ
);

这里的hDevice必须来自CreateFile函数的返回值。
HANDLE CreateFile(
    LPCTSTR lpFileName, 
    DWORD dwDesiredAccess, 
    DWORD dwShareMode, 
    LPSECURITY_ATTRIBUTES lpSecurityAttributes, 
    DWORD dwCreationDisposition, 
    DWORD dwFlagsAndAttributes, 
    HANDLE hTemplateFile
);

参数:要打开的文件名,访问权限,共享模式,安全属性,文件存在与不存在时的文件创建模式,文件属性设定(隐藏、只读、压缩、指定为系统文件等),文件副本句柄。

要说明的是第一个参数lpFileName,是设备的名称或者是和设备关连的驱动的名称,一般用\\.\DeviceName的形式,比如要打开逻辑驱动盘A就用\\.\a,也可以用\\.\PhysicalDevice0,\\.\PhsycalDebive1来指定物理驱动器,\\.\PhysicalDevice0表示本机的物理驱动器0(一般是主硬盘),从而来获取硬盘的序列号、模块名、扇区数、磁头数等相关信息

注意: DeviceIOControl函数的输入参数dwIoControlCode 表示 控制设备的指令 微软已经定义好了很多种操作,在winioctl.h文件中,但最终都是通过CTL_CODE宏来实现的,其实这就是一种通信协议。 For lists of supported control codes, see the following topics: • Communications Control Codes • Device Management Control Codes • Directory Management Control Codes • Disk Management Control Codes • File Management Control Codes • Power Management Control Codes • Volume Management Control Codes

如果某些设备没有支持这些generic指令,则无法通过DeviceIOControl函数对设备操作。

rainit2006 commented 7 years ago

涉及到显卡,声卡的功能对应,则直接调用各个厂家(Intel, Nvidia等)提供的API