none
どなたかWindowsXPもサポートするフィルタドライバの方式選択について教えてください RRS feed

  • 質問

  • みなさん初めまして。

    最後にWindows用ドライバを開発してから15年、(見た目に)特殊なキー機能を持つキーがあるUSBキーボードのためのドライバが必要になり、再び勉強しなおしております。(見た目に)特殊な機能を持つキーとは、要するにキートップがカラフルで、OADG109キー(死語?)のキートップに書かれた文字とは違った意味の動作をアプリケーションに与える契機となる役目を果たすものです。

    PCに接続しているキーボードが1つなら良いのですが、ノートPCへの外付けキーボードとして接続すると2台のUSBキーボードとして動作することになり、区別が必要になってしまった、と言う事です(これまでは1つのキーボードで利用してたので問題になりませんでした)。

    そこで、USBキーボードドライバへのフィルターを作って、特殊な色のキーのデータをフィルタリングして、特定アプリにイベント通知すればいいよねと安易な気持ちで調べ始めたところ、DDKじゃなくてWDKに改称されいるし、WDMじゃなくてKMDFとかUMDFとか色々あって、現時点でどの選択が良いのか、どの方式に手を付けたらいいのか判断できずにおります。
    と言うのも、サポート対象が WindowsXP から Windows10 まで広く対応しなければならず、その点で、WDKの選択肢が7600? になりそうだと思い始めた矢先、WDK8には HID Minidriver Sample (UMDF version 2) があることを知った為です。 WDK7600は *MDF1.9 仕様と言う事でしたので…

    前置きが長くて済みませんが質問をさせて頂きます。

    ① 例えば、特定の USB キーボードの 特定のキーの打鍵を 特定のアプリにのみ通知したい時、KMDF レベルじゃ無くて UMDF レベルで実現可能なのでしょうか?
         (キーボードクラスに渡る前のキーボードのレポートデータ中のキーバッファを、VID,PID に応じて必要時にゼロにできるのかどうか。)
    ② (UMDFで可能だとして) WDK8 の HID Minidriver を WDK7600 でビルドさせるには変更が必要でしょうか?
         (UMDFは署名が不要? かと思っています。)

    なかなか需要の無さそうな内容で済みませんが、ご意見を頂けますと嬉しいです。



    2017年12月1日 11:40

回答

  • 私自身試したわけではないので、質問者様の意図通りの動作となるか不明ですが。
    XP以降であれば、RawInput APIを使用することで、キーボード入力から
    デバイスの判別が出来そうな感じですので、少し調べてみてはいかがでしょうか?


    • 回答の候補に設定 お馬鹿 2017年12月4日 8:09
    • 回答としてマーク DeviceIoError 2017年12月4日 8:55
    • 回答としてマークされていない DeviceIoError 2017年12月4日 11:34
    • 回答としてマーク DeviceIoError 2017年12月4日 11:34
    2017年12月4日 4:30

すべての返信

  • ① XP SP2 以降を対象とするのであれば、下記ドキュメントを読む限り、UMDF でのドライバ開発は可能なようです。
    ----------------------------------------
    UMDF の紹介
    https://msdn.microsoft.com/ja-jp/library/ff554928(v=vs.85).aspx

    UMDF のバージョン情報
    https://msdn.microsoft.com/ja-jp/library/ff561356(v=vs.85).aspx

    Windows XP、Windows Vista および Windows Server 2008 のユーザー モード ドライバー フレームワーク バージョン 1.9 の更新
    https://support.microsoft.com/ja-jp/help/970159/user-mode-driver-framework-version-1-9-update-for-windows-xp--for-wind
    ----------------------------------------

    ② 色々と変更が必要です。
       しかもとても面倒くさい。
       UMDF であっても、署名は恐らく必要。
       (UMDF の Keyboard Filter が署名無しで行けるなら、キーロガーみたいなマルウェアを作ってる人たちは大喜びすると思います。)

    そもそも、なぜ新たに Keyboard Filter を作らなければならないのか、すっごく疑問に思うのですが。。。

    > PCに接続しているキーボードが1つなら良いのですが、
    > ノートPCへの外付けキーボードとして接続すると
    > 2台のUSBキーボードとして動作することになり、
    > 区別が必要になってしまった、と言う事です
    > (これまでは1つのキーボードで利用してたので問題になりませんでした)。
    これ↑が本質的な問題ならば、inf ファイルで特定の VID/PID を持つ USB キーボードにだけそのドライバを適用するように書き換えれば、それで済む話では?
    問題となっている keyboard driver の inf ファイルで、[Manufacturer] セクションをどのように記述しているのか、きちんと精査されることをお勧めします。
    (まぁ、デジタル署名は必要になるでしょうけど。)
    ----------------------------------------
    INFファイルを記述する
    https://blogs.msdn.microsoft.com/jpwdkblog/2009/05/19/inf/
    ----------------------------------------
    • 回答としてマーク DeviceIoError 2017年12月4日 4:03
    • 回答としてマークされていない DeviceIoError 2017年12月4日 9:36
    2017年12月4日 3:05
  • お馬鹿さま

    また、こちらの説明不足でいらぬ誤解をさせてしまい、すみませんでした。

    >それで済む話では?

    そうですね。 その当時よりプライベートなドライバがあれば良かったのですが、キーボードが1台であったがために、キーボードフックで十分に対処できていたので、ドライバは作成していませんでした。 また、2台のキーボードのどちらから上がってきたコードかを見分けるには、ローレベルを含むキーボードフックではできないと理解しています。

    いずれにしても UMDF でできると理解出来ました。
    また、「しかもとても面倒くさい」と言う言葉にたじろぎつつ、今の私ではどのくらい面倒なのか見当もつきませんが、やればできると理解します。

    貴重なご意見を頂き、ありがとうございました。

    2017年12月4日 4:15
  • 私自身試したわけではないので、質問者様の意図通りの動作となるか不明ですが。
    XP以降であれば、RawInput APIを使用することで、キーボード入力から
    デバイスの判別が出来そうな感じですので、少し調べてみてはいかがでしょうか?


    • 回答の候補に設定 お馬鹿 2017年12月4日 8:09
    • 回答としてマーク DeviceIoError 2017年12月4日 8:55
    • 回答としてマークされていない DeviceIoError 2017年12月4日 11:34
    • 回答としてマーク DeviceIoError 2017年12月4日 11:34
    2017年12月4日 4:30
  • > その当時よりプライベートなドライバがあれば良かったのですが、
    > キーボードが1台であったがために、
    > キーボードフックで十分に対処できていたので、
    > ドライバは作成していませんでした。

    であるなら、極力ドライバ開発をしない方向で検討すべきと思います。
    uemu さんが提示されている Raw Input API で代用できないか、検討されることをお勧めします。
    Raw Input API のドキュメントを読む限り、デバイス ハンドル (hDevice) により、個別のキーボード デバイスからの入力を識別することは可能であると思われます。
    問題は、複数の hDevice からフックしたいキーボード デバイスをどーやって特定するかがポイントになると思いますが、Setup API 等と組み合わせて、取得した hDevice から、そのキーボード デバイス ハンドルに紐づけられたデバイス インスタンス パスを割り出せれば、uemu さんが提案された方法で実現できると思います。
    (なので、私からの返信よりも、uemu さんからの返信の方が「回答」としてふさわしいと思います。)
    • 回答としてマーク DeviceIoError 2017年12月4日 8:57
    • 回答としてマークされていない DeviceIoError 2017年12月4日 11:34
    2017年12月4日 8:09
  • uemu さま
    貴重な情報をありがとうございます。

    少なくとも次の説明から構造体の仕様まで読む限り、WM_INPUT を受け取る契機となったデバイスの情報を取得する事はできるようです。

    https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms645543(v=vs.85).aspx

    システムに対して WM_INPUT を注入してもらう手続き(RegisterRawInputDevices の実行) を踏む必要があり、本来ならアプリ側の修正が必要になってしまうようですが、RegisterRawInputDevices の実行時に指定するdwFlagsに RIDEV_INPUTSINK を加えると、WM_INPUTをいつでも注入してくれるそうです。

    これにより、キーボードフックと併用することで、目的のキーボードか否かを判断することで目的を達成できそうです。

    良いヒントを頂きまして、ありがとうございます。

    2017年12月4日 8:55
  • お馬鹿さま

    アドバイスありがとうございます。

    uemuさまからのアドバイスの通り、Raw Input を調べております。
    メッセージ受信時に渡される構造体から RID_DEVICE_INFO_HID を引っ張れば、VIDとPIDを確認可能な様だと思っています。


    2017年12月4日 9:13
  • 後からこのスレッドを参照する人のためにも、私の返信にマークした「回答」は外してください。
    今回のケースの場合、uemu さんからの返信がもっとも「回答」にふさわしいと思います。
    (あくまでも個人的な私見ですが、複数の返信に「回答」をマークしてあるスレッドは非常に読みにくいと感じており、「回答」のマークは出来る限り1つに絞った方が良いと考えています。)

    追記
    確かに RID_DEVICE_INFO_HID 構造体のメンバーに、dwVendorId, dwProductId, dwVersionNumber がありますね。
    きちんと確認もせずにテキトーな返信をしてしまい、申しわけありませんでした。

    • 編集済み お馬鹿 2017年12月4日 10:04 追記
    2017年12月4日 9:38
  • お馬鹿さま

    もともと私の質問は、WindowsXp をもサポートする方法で、簡単な方法を選択することを目的としていました。
    今回は解決に至る為の回答は 1 つではなかったと思いますが、ご希望通り1つに絞りました。

    今後ともよろしくお願い致します。


    2017年12月4日 11:54