符合hid標準的觸控式螢幕驅動

跳到主要內容

已不再支援此瀏覽器。

請升級至 Microsoft Edge,以利用最新功能、安全性更新和技術支援。

鍵盤和滑鼠 HID 用戶端驅動程式

  • 發行項
  • 09/22/2022

本文內容

本主題討論鍵盤和滑鼠 HID 用戶端驅動程式。 鍵盤和滑鼠代表在 HID 使用量資料表中標準化的第一組 HID 用戶端,並在Windows作業系統中實作。

鍵盤和滑鼠 HID 用戶端驅動程式會以 HID 對應程式驅動程式的形式實作。 HID 對應程式驅動程式是核心模式 WDM 篩選驅動程式,可為非 HID 類別驅動程式與 HID 類別驅動程式之間的 I/O 要求提供雙向介面。 mapper 驅動程式會將其中一個的 I/O 要求和資料通訊協定對應到另一個要求。

Windows為 HID 鍵盤和 HID 滑鼠裝置提供系統提供的 HID 對應程式驅動程式。

架構和概觀

下圖說明 USB 鍵盤、滑鼠和觸控板裝置的系統提供驅動程式堆疊。

符合hid標準的觸控式螢幕驅動

上圖包含下列元件:

  • KBDHID.sys:適用于鍵盤的 HID 用戶端對應程式驅動程式。 將 HID 使用方式轉換成掃描碼,以與現有的鍵盤類別驅動程式進行介面。
  • MOUHID.sys:適用于滑鼠/觸控板的 HID 用戶端對應器驅動程式。 將 HID 用法轉換成滑鼠命令, (X/Y、按鈕、滾輪) ,以與現有的鍵盤類別驅動程式進行介面。
  • KBDCLASS.sys: 鍵盤類別驅動程式 會以安全的方式維護系統上所有鍵盤和鍵盤的功能。
  • MOUCLASS.sys: 滑鼠類別驅動程式 會維護系統上所有滑鼠/觸控板的功能。 驅動程式支援絕對和相對指向裝置。 這不是觸控螢幕的驅動程式,因為該驅動程式是由Windows中的不同驅動程式所管理。
  • HIDCLASS.sys: HID 類別驅動程式。 HID 類別驅動程式是KBDHID.sys和MOUHID.sys HID 用戶端之間的黏附,以及各種傳輸 (USB、藍牙等) 。

系統會建置驅動程式堆疊,如下所示:

  • 傳輸堆疊會為每個連結的 HID 裝置建立實體裝置物件 (PDO) ,並載入適當的 HID 傳輸驅動程式,進而載入 HID 類別驅動程式。
  • HID 類別驅動程式會為每個鍵盤或滑鼠 TLC 建立 PDO。 複雜 HID 裝置 (超過 1 個 TLC) 會公開為 HID 類別驅動程式所建立的多個 PDO。 例如,具有整合式滑鼠的鍵盤可能會有一個標準鍵盤控制項的集合,以及滑鼠的不同集合。
  • 鍵盤或滑鼠 hid 用戶端對應程式驅動程式會在適當的 FDO 上載入。
  • HID 對應程式驅動程式會建立鍵盤和滑鼠的 FDO,並載入類別驅動程式。

重要事項:

  • 符合支援的 HID 使用方式和最上層集合的鍵盤和滑鼠不需要廠商驅動程式。
  • 廠商可以選擇性地在 HID 堆疊中提供篩選驅動程式,以改變/增強這些特定 TLC 的功能。
  • 廠商應該建立個別的TLC,也就是廠商特有的,以在其 hid 用戶端與裝置之間交換廠商專屬資料。 除非有重大,否則請避免使用篩選驅動程式。
  • 系統會開啟所有鍵盤和滑鼠集合以供獨佔使用。
  • 系統可防止停用/啟用鍵盤。
  • 系統支援具有平滑捲動功能的水準/垂直方向盤。

驅動程式指引

Microsoft 針對撰寫驅動程式的 IHD 提供下列指引:

  1. 驅動程式開發人員允許以篩選驅動程式或新的 HID 用戶端驅動程式的形式新增其他驅動程式。 準則如下所述:

    1. 篩選驅動程式:驅動程式開發人員應該確保其值新增驅動程式是篩選驅動程式,而且不會取代 (,也不會取代) 輸入堆疊中現有Windows HID 驅動程式。

      • 下列案例允許篩選驅動程式:
        • 做為 kbdhid/azurehid 的上層篩選
        • 做為 kbdclass/mnclass 的上層篩選
      • 不建議篩選驅動程式作為 HIDCLASS 與 HID 傳輸迷你驅動程式之間的篩選
    2. 函式驅動程式:或者廠商可以建立函式驅動程式 (,而不是篩選驅動程式) ,但只針對廠商的特定 HID PDO,視需要) 搭配使用者模式服務 (。

      下列案例允許函式驅動程式:

      • 只載入特定廠商的硬體
    3. 傳輸驅動程式:Windows小組不建議建立額外的 HID Transport minidriver,因為它們是撰寫/維護的複雜驅動程式。 如果合作夥伴正在建立新的 HID Transport minidriver,特別是在 SoC 系統上,我們建議詳細的架構檢閱以瞭解原因,並確保驅動程式已正確開發。

  2. 驅動程式開發人員應該利用驅動程式架構 (KMDF 或 UMDF) ,而不會依賴 WDM 作為其篩選驅動程式。

  3. 驅動程式開發人員應該減少其服務與驅動程式堆疊之間的核心使用者轉換數目。

  4. 驅動程式開發人員應該確保能夠透過鍵盤和觸控板功能喚醒系統, (使用者 (裝置管理員) 或電腦製造商) 調整。 此外,在 SoC 系統上,這些裝置必須能夠在系統處於運作的 S0 狀態時,從較低的電源狀態喚醒自己。

  5. 驅動程式開發人員應該確保其硬體有效率地受到電源管理。

    • 當裝置閒置時,裝置可以進入其最低電源狀態。
    • 當系統處於低電源狀態時,裝置處於最低電源狀態 (,例如待命 (S3) 或連線待命) 。

鍵盤配置

鍵盤配置完整描述 Microsoft Windows 2000 和更新版本的鍵盤輸入特性。 例如,鍵盤配置會指定語言、鍵盤類型和版本、修飾詞、掃描碼等等。

如需鍵盤配置的相關資訊,請參閱下列內容:

  • Windows驅動程式開發工具組中的鍵盤標頭檔 kdb.h (DDK) ,其中會記載鍵盤配置的一般資訊。

  • 範例鍵盤 配置。

若要視覺化特定鍵盤的配置,請參閱Windows鍵盤版面配置。

如需鍵盤配置的其他詳細資料,請流覽 主控台\Clock、Language 和 Region\Language。

滑鼠上支援的按鈕和方向盤

下表識別Windows作業系統不同用戶端版本支援的功能。

功能Windows XPWindows VistaWindows 7Windows 8 和更新版本
按鈕 1-5 支援的 (P/2 & HID) 支援 (PS/2 & HID) 支援 (PS/2 & HID) 支援 (PS/2 & HID)
垂直捲動輪 支援 (PS/2 & HID) 支援 (PS/2 & HID) 支援 (PS/2 & HID) 支援 (PS/2 & HID)
水準滾動輪 不支援 僅支援 (HID) 僅支援 (HID) 僅支援 (HID)
平滑捲動滾輪支援 (水準和垂直) 不支援 部分支援 僅支援 (HID) 僅支援 (HID)

在 PS/2 滑鼠上啟用按鈕 4-5 和滾輪

Windows用來啟用新 45 & 按鈕 + 滾輪模式的方法,是用來在 IntelliMouse 相容滑鼠中啟動第三個按鈕和滾輪的方法延伸:

  • 首先,滑鼠會設定為 3 按鈕滾輪模式,其完成方式是將報表速率連續設定為 200 個報表/秒,再設定為 100 個報表/秒,然後讀取滑鼠中的識別碼。 當此序列完成時,滑鼠應該會報告 3 的識別碼。
  • 接下來,滑鼠會設定為 5 按鈕滾輪模式,其完成方式是將報表速率連續設定為 200 個報表/秒,然後再次設定為 200 個報表/秒,然後讀取滑鼠中的識別碼。 完成此順序之後,5 鍵滾輪滑鼠應該回報識別碼為 4 (,而 IntelliMouse 相容的 3 按鈕滾輪滑鼠仍會回報識別碼為 3) 。

請注意,這僅適用于 PS/2 滑鼠,不適用於 HID 滑鼠 (HID 滑鼠必須報告其報表描述元) 中的精確使用量。

標準 PS/2 相容的滑鼠資料封包格式, (2 個按鈕)

ByteD7D6D5D4D3D2D1D0註解
1 Yover Xover Ysign Xsign 標籤 M R L X/Y 溢位和符號、按鈕
2 X7 X6 X5 X4 X3 X2 X1 X0 X 資料位元組
3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 Y 資料位元組

注意

Windows滑鼠驅動程式不會檢查溢位。 如果溢位,滑鼠應該只會傳送最大帶正負號的位移值。

標準 PS/2 相容的滑鼠資料封包格式 (3 個按鈕 + VerticalWheel)

ByteD7D6D5D4D3D2D1D0註解
1 0 0 Ysign Xsign 1 M R L X/Y 符號和 R/L/M 按鈕
2 X7 X6 X5 X4 X3 X2 X1 X0 X 資料位元組
3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 Y 資料位元組
4 Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0 Z/wheel 資料位元組

標準 PS/2 相容滑鼠資料封包格式 (5 個按鈕 + VerticalWheel)

ByteD7D6D5D4D3D2D1D0註解
1 0 0 Ysign Xsign 1 M R L X/Y 符號和 R/L/M 按鈕
2 X7 X6 X5 X4 X3 X2 X1 X0 X 資料位元組
3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 Y 資料位元組
4 0 0 B5 B4 Z3 Z2 Z1 Z0 Z/wheel 資料和按鈕 4 和 5

重要

請注意,5 鍵滾輪滑鼠的 Z/wheel 資料已縮減為四位,而不是 IntelliMouse 相容 3 按鈕滾輪模式中使用的 8 位。 因為輪子通常無法在任何指定的中斷期間內產生超出範圍 +7/-8 的值,所以可以減少此減少。 Windows滑鼠驅動程式會在滑鼠處於 5 按鈕滾輪模式時,簽署四個 Z/wheel 資料位,並在滑鼠以 3 鍵滾輪模式運作時,完整 Z/滾輪資料位元組。

上的按鈕 4 & 5 會對應至WM_APPCOMMAND訊息,並對應至App_Back和App_Forward。

不需要廠商驅動程式的裝置

下列裝置不需要廠商驅動程式:

  • 符合 HID Standard 的裝置。
  • 由系統提供的非 HIDClass 驅動程式操作的鍵盤、滑鼠或遊戲連接埠裝置。

Kbfiltr 範例

Kbfiltr 的設計目的是要與 Kbdclass、鍵盤裝置的系統類別驅動程式和 I8042prt 搭配使用,這是 PS/2 樣式鍵盤的函式驅動程式。 Kbfiltr 示範如何篩選 I/O 要求,以及如何新增回呼常式,以修改 Kbdclass 和 I8042prt 的作業。

如需 Kbfiltr 作業的詳細資訊,請參閱下列內容:

  • ntddkbd.h WDK 標頭檔。

  • 範例 Kbfiltr 原始程式碼。

Kbfiltr IOCTLs

IOCTL_INTERNAL_I8042_HOOK_KEYBOARD

IOCTL_INTERNAL_I8042_HOOK_KEYBOARD要求會執行下列動作:

  • 將初始化回呼常式新增至 I8042prt 鍵盤初始化常式。
  • 將 ISR 回呼常式新增至 I8042prt 鍵盤 ISR。

初始化和 ISR 回呼是選擇性的,由 PS/2 樣式鍵盤裝置的頂層篩選驅動程式提供。

在 I8042prt 收到 IOCTL_INTERNAL_KEYBOARD_CONNECT 要求之後,它會將同步 IOCTL_INTERNAL_I8042_HOOK_KEYBOARD 要求傳送至鍵盤裝置堆疊頂端。

在 Kbfiltr 收到攔截式鍵盤要求之後,Kbfiltr 會以下列方式篩選要求:

  • 儲存傳遞至 Kbfiltr 的上層資訊,其中包括上層裝置物件的內容、初始化回呼的指標,以及 ISR 回呼的指標。
  • 以自己的資訊取代最上層資訊。
  • 將 I8042prt 的內容和指標儲存至 Kbfiltr ISR 回呼可以使用的回呼。

IOCTL_INTERNAL_KEYBOARD_CONNECT

IOCTL_INTERNAL_KEYBOARD_CONNECT要求會將 Kbdclass 服務連線到鍵盤裝置。 Kbdclass 會在開啟鍵盤裝置之前,將此要求向下傳送到鍵盤裝置堆疊。

在 Kbfiltr 收到鍵盤連線要求之後,Kbfiltr 會以下列方式篩選連接要求:

  • 儲存 Kbdclass CONNECT_DATA (Kbdclass) 結構的複本,該結構會由 Kbdclass 傳遞至篩選驅動程式。
  • 以自己的連接資訊取代類別驅動程式連接資訊。
  • IOCTL_INTERNAL_KEYBOARD_CONNECT 要求向下傳送到裝置堆疊。

如果要求不成功,Kbfiltr 會以適當的錯誤狀態完成要求。

Kbfiltr 提供篩選服務回呼常式的範本,可補充 KeyboardClassServiceCallback的作業,也就是 Kbdclass 類別服務回呼常式。 篩選服務回呼可以篩選從裝置輸入緩衝區傳輸到類別資料佇列的輸入資料。

IOCTL_INTERNAL_KEYBOARD_DISCONNECT

IOCTL_INTERNAL_KEYBOARD_DISCONNECT要求已完成,狀態為 STATUS_NOT_IMPLEMENTED。 請注意,隨插即用管理員可以新增或移除隨插即用鍵盤。

對於所有其他裝置控制要求,Kbfiltr 會略過目前的 IRP 堆疊,並將要求向下傳送到裝置堆疊,而不需進一步處理。

Kbfiltr 所實作的回呼常式

KbFilter_InitializationRoutine

請參閱 PI8042_KEYBOARD_INITIALIZATION_ROUTINE

如果鍵盤的 I8042prt 預設初始化已足夠,則不需要 KbFilter_InitializationRoutine

I8042prt 會在初始化鍵盤時 呼叫KbFilter_InitializationRoutine 。 預設鍵盤初始化包含下列作業:

  • 重設鍵盤
  • 設定具型別速率和延遲
  • 設定 led (LED)
/*
Parameters
DeviceObject [in]
Pointer to the device object that is the context for this callback.

SynchFuncContext [in]
Pointer to the context for the routines pointed to by ReadPort and Writeport.

ReadPort [in]
Pointer to the system-supplied PI8042_SYNCH_READ_PORT callback that reads from the port.

WritePort [in]
Pointer to the system-supplied PI8042_SYNCH_WRITE_PORT callback that writes to the port.

TurnTranslationOn [out]
Specifies, if TRUE, to turn translation on. Otherwise, translation is turned off.

Return value
KbFilter_InitializationRoutine returns an appropriate NTSTATUS code.
*/

NTSTATUS KbFilter_InitializationRoutine(
  In  PDEVICE_OBJECT          DeviceObject,
  In  PVOID                   SynchFuncContext,
  In  PI8042_SYNCH_READ_PORT  ReadPort,
  In  PI8042_SYNCH_WRITE_PORT WritePort,
  Out PBOOLEAN                TurnTranslationOn
);

KbFilter_IsrHook

請參閱 PI8042_KEYBOARD_ISR。 如果 I8042prt 的預設作業已足夠,就不需要此回呼。

I8042prt 鍵盤 ISR 會在驗證中斷並讀取掃描碼之後 呼叫KbFilter_IsrHook

KbFilter_IsrHook 會在 I8042prt 鍵盤的 IRQL 核心模式中執行。

/*
Parameters
DeviceObject [in]
Pointer to the filter device object of the driver that supplies this callback.

CurrentInput [in]
Pointer to the input KEYBOARD_INPUT_DATA structure that is being constructed by the ISR.

CurrentOutput [in]
Pointer to an OUTPUT_PACKET structure that specifies the bytes that are being written to the hardware device.

StatusByte [in, out]
Specifies the status byte that is read from I/O port 60 when an interrupt occurs.

DataByte [in]
Specifies the data byte that is read from I/O port 64 when an interrupt occurs.

ContinueProcessing [out]
Specifies, if TRUE, to continue processing in the I8042prt keyboard ISR after this callback returns; otherwise, processing is not continued.

ScanState [in]
Pointer to a KEYBOARD_SCAN_STATE structure that specifies the keyboard scan state.

Return value
KbFilter_IsrHook returns TRUE if the interrupt service routine should continue; otherwise it returns FALSE.
*/

KbFilter_IsrHook KbFilter_IsrHook(
  In    PDEVICE_OBJECT       DeviceObject,
  In    PKEYBOARD_INPUT_DATA CurrentInput,
  In    POUTPUT_PACKET       CurrentOutput,
  Inout UCHAR                StatusByte,
  In    PUCHAR               DataByte,
  Out   PBOOLEAN             ContinueProcessing,
  In    PKEYBOARD_SCAN_STATE ScanState
);

KbFilter_ServiceCallback

請參閱 PSERVICE_CALLBACK_ROUTINE

函式驅動程式的 ISR 分派完成常式 會呼叫 KbFilter_ServiceCallback,然後呼叫鍵盤類別驅動程式的 PSERVICE_CALLBACK_ROUTINE實作。 廠商可以實作篩選服務回呼,以修改從裝置的輸入緩衝區傳輸到類別資料佇列的輸入資料。 例如,回呼可以刪除、轉換或插入資料。

/*
Parameters
DeviceObject [in]
Pointer to the class device object.

InputDataStart [in]
Pointer to the first keyboard input data packet in the input data buffer of the port device.

InputDataEnd [in]
Pointer to the keyboard input data packet that immediately follows the last data packet in the input data buffer of the port device.

InputDataConsumed [in, out]
Pointer to the number of keyboard input data packets that are transferred by the routine.

Return value
None
*/

VOID KbFilter_ServiceCallback(
  In    PDEVICE_OBJECT       DeviceObject,
  In    PKEYBOARD_INPUT_DATA InputDataStart,
  In    PKEYBOARD_INPUT_DATA InputDataEnd,
  Inout PULONG               InputDataConsumed
);

活頁簿範例

一般檔篩選器的設計目的是要搭配使用,適用于Windows 2000 版及更新版本之滑鼠裝置的系統類別驅動程式,以及 I8042prt,這是與 Windows 2000 和更新版本搭配使用之 PS/2 樣式滑鼠的函式驅動程式。 群組篩選會示範如何篩選 I/O 要求,並新增回呼常式,以修改「叢集」和「I8042prt」的作業。

如需有關「集區篩選」作業的詳細資訊,請參閱下列各項:

  • ntddmou.h WDK 標頭檔。

  • 範例 要篩選 原始程式碼。

通訊組控制程式代碼

IOCTL_INTERNAL_I8042_HOOK_MOUSE

IOCTL_INTERNAL_I8042_HOOK_MOUSE要求會將 ISR 回呼常式新增至 I8042prt 滑鼠 ISR。 ISR 回呼是選擇性的,由高階滑鼠篩選驅動程式提供。

I8042prt 會在收到 IOCTL_INTERNAL_MOUSE_CONNECT 要求之後傳送此要求。 I8042prt 會將同步 IOCTL_INTERNAL_I8042_HOOK_MOUSE 要求傳送至滑鼠裝置堆疊頂端。

在「檔案篩選」收到攔截滑鼠要求之後,它會以下列方式篩選要求:

  • 儲存傳遞至 AzureFiltr 的上層資訊,其中包含高階裝置物件的內容,以及 ISR 回呼的指標。
  • 以自己的資訊取代高階資訊。
  • 將 I8042prt 的內容和指標儲存至可讓 Azure 篩選 ISR 回呼使用的回呼。

圖文篩選回呼常式

IOCTL_INTERNAL_MOUSE_CONNECT

IOCTL_INTERNAL_MOUSE_CONNECT要求會將一個 AzureClass 服務連線到滑鼠裝置。

IOCTL_INTERNAL_MOUSE_DISCONNECT

IOCTL_INTERNAL_MOUSE_DISCONNECT要求是由一個錯誤狀態為 STATUS_NOT_IMPLEMENTED 的STATUS_NOT_IMPLEMENTED完成。

針對所有其他要求,「通訊協定篩選」會略過目前的 IRP 堆疊,並將要求傳送至裝置堆疊,而不需進一步處理。

回呼常式

MouFilter_IsrHook

請參閱 PI8042_MOUSE_ISR

/*
Parameters
DeviceObject
Pointer to the filter device object of the driver that supplies this callback.

CurrentInput
Pointer to the input MOUSE_INPUT_DATA structure being constructed by the ISR.

CurrentOutput
Pointer to the OUTPUT_PACKET structure that specifies the bytes being written to the hardware device.

StatusByte
Specifies a status byte that is read from I/O port 60 when the interrupt occurs.

DataByte
Specifies a data byte that is read from I/O port 64 when the interrupt occurs.

ContinueProcessing
Specifies, if TRUE, that the I8042prt mouse ISR continues processing after this callback returns. Otherwise, processing is not continued.

MouseState
Pointer to a MOUSE_STATE enumeration value, which identifies the state of mouse input.

ResetSubState
Pointer to MOUSE_RESET_SUBSTATE enumeration value, which identifies the mouse reset substate. See the Remarks section.

Return value
MouFilter_IsrHook returns TRUE if the interrupt service routine should continue; otherwise it returns FALSE.
*/

BOOLEAN MouFilter_IsrHook(
   PDEVICE_OBJECT        DeviceObject,
   PMOUSE_INPUT_DATA     CurrentInput,
   POUTPUT_PACKET        CurrentOutput,
   UCHAR                 StatusByte,
   PUCHAR                DataByte,
   PBOOLEAN              ContinueProcessing,
   PMOUSE_STATE          MouseState,
   PMOUSE_RESET_SUBSTATE ResetSubState
);

如果 I8042prt 的預設作業已足夠,則不需要 MouFilter_IsrHook 回呼。

I8042prt 滑鼠 ISR 會在驗證中斷之後 呼叫MouFilter_IsrHook

若要重設滑鼠,I8042prt 會經歷一連串的作業子狀態,每個子狀態都是由MOUSE_RESET_SUBSTATE列舉值所識別。 如需 I8042prt 如何重設滑鼠和對應的滑鼠重設子狀態的詳細資訊,請參閱 ntdd8042.h 中MOUSE_RESET_SUBSTATE的檔。

MouFilter_IsrHook 在 I8042prt 滑鼠 ISR 的 IRQL 中以核心模式執行。

MouFilter_ServiceCallback

請參閱 PSERVICE_CALLBACK_ROUTINE

/*
Parameters
DeviceObject [in]
Pointer to the class device object.

InputDataStart [in]
Pointer to the first mouse input data packet in the input data buffer of the port device.

InputDataEnd [in]
Pointer to the mouse input data packet immediately following the last data packet in the port device's input data buffer.

InputDataConsumed [in, out]
Pointer to the number of mouse input data packets that are transferred by the routine.

Return value
None
*/

VOID MouFilter_ServiceCallback(
  _In_    PDEVICE_OBJECT    DeviceObject,
  _In_    PMOUSE_INPUT_DATA InputDataStart,
  _In_    PMOUSE_INPUT_DATA InputDataEnd,
  _Inout_ PULONG            InputDataConsumed
);

I8042prt 的 ISR DPC 會呼叫 MouFilter_ServiceCallback,然後呼叫 MouseClassServiceCallback。 篩選服務回呼可以設定為修改從裝置的輸入緩衝區傳輸到類別資料佇列的輸入資料。 例如,回呼可以刪除、轉換或插入資料。


其他資源