none
カーネルモードでのCOMポート制御について RRS feed

  • 質問

  • COMポートのドライバを作成しています。

    通常、COMポートのドライバをインストールすると
    デバイスマネージャの「ポート (COMとLPT)」クラスにデバイスが登録されますが、
    今回の開発では新規のデバイスクラスを作成して、
    そこにデバイスを登録する形を実現したいと考えています。

    そこで、INFファイルの[Version]セクションにて以下の設定を行いました。
    ・Classに新規のクラス名を定義
    ・ClassGuidに、guidgen.exeで生成したGUIDを指定

    また、ドライバ内では以下の対応を行って
    ターミナルからCOMポートのオープンやIOCTLの制御などが出来るようになりました。
    ・IoCreateSymbolicLink()にてシンボリックリンクを生成
    ・RtlWriteRegistryValue()にてDEVICEMAP\SERIALCOMMレジストリにデバイスの情報を登録

    しかしポート番号の排他が出来ていないようで、
    デバイスマネージャで確認すると
    今回登録したはずのポート番号が「使用中」と表示されません。

    以下URLを見て、ComDBClaimPort()などを使えば
    COMポートデータベースの制御が可能かと思ったのですが、
    こちらはユーザーモードのAPIみたいですね。

    http://msdn.microsoft.com/en-us/library/windows/hardware/ff546483(v=vs.85).aspx

    カーネルモードでCOMポートデータベースの制御を行いたい場合は
    どの様にすれば良いでしょうか?
    アドバイス頂けると大変ありがたいです。

    【開発環境】
    OS:Windows XP(32 bit)
    WDK:7600.16385.1


    2014年1月9日 7:31

回答

  • ドライバ内で IoCreateSymbolicLink() をコールする際に 1st パラメータにセットする SymbolicLinkName は、どのように決定されているのでしょうか?

    WDK サンプル serenum.sys をベースに、serial.sys に実装されている serial!SerialDoExternalNaming ルーチン相当の処理を移植したのでは?。。。と推測しておりますが、このポーティングの際に、serial!SerialReadSymName ルーチンに相当する部分も併せて移植されたのでしょうか?

    ご存知とは思いますが。。。
    serial!SerialDoExternalNaming ルーチンで使用している SymbolicLinkName は、このドライバ自身が決定している訳ではなく、acpi ドライバが割り当てた名前を使用しています。
    要するに serial ドライバは IoCreateSymbolicLink() コールにて COM ポート名を指定する際に、その名前を acpi ドライバが管理する下記レジストリから取得しています。

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\<X>\Device Parameters]
    "PortName"="COM<N>"

    (上記レジストリ キーの <X> 部分と、レジストリ値 <N> 部分が示す序数は、同じ値であるとは限りません。)

    ですので、COM ポート名割り当ての排他を行いたいのであれば、シリアル デバイス スタックの基底となる PDO を提供する acpi ドライバへの問い合わせ処理が必要になると思うのですが、そのあたりの実装はどうされているのでしょうか?

    • 回答の候補に設定 星 睦美 2014年1月21日 5:30
    • 回答としてマーク 星 睦美 2014年1月27日 2:48
    2014年1月15日 10:44

すべての返信

  • 一応確認させて頂きたいのですが、serenum.sysのバイナリまたは、相当のソースコードを使っているのでしょうか?
    また、INFファイルはどのようにして作られたのでしょうか?

    2014年1月10日 17:47
    モデレータ
  • Atomu Hidaka-様

    レスありがとうございます。
    ご確認の内容に回答させて頂きます。

    > serenum.sysのバイナリまたは、相当のソースコードを使っているのでしょうか?

    はい、WDKのサンプルserenumのソースをベースに作成しています。

    > INFファイルはどのようにして作られたのでしょうか?

    こちらは以下URLを参考に新規に作成しています。

    http://blogs.msdn.com/b/jpwdkblog/archive/2009/05/20/inf.aspx
    http://msdn.microsoft.com/en-us/library/windows/hardware/ff547465(v=vs.85).aspx


    2014年1月11日 8:09
  • ドライバ内で IoCreateSymbolicLink() をコールする際に 1st パラメータにセットする SymbolicLinkName は、どのように決定されているのでしょうか?

    WDK サンプル serenum.sys をベースに、serial.sys に実装されている serial!SerialDoExternalNaming ルーチン相当の処理を移植したのでは?。。。と推測しておりますが、このポーティングの際に、serial!SerialReadSymName ルーチンに相当する部分も併せて移植されたのでしょうか?

    ご存知とは思いますが。。。
    serial!SerialDoExternalNaming ルーチンで使用している SymbolicLinkName は、このドライバ自身が決定している訳ではなく、acpi ドライバが割り当てた名前を使用しています。
    要するに serial ドライバは IoCreateSymbolicLink() コールにて COM ポート名を指定する際に、その名前を acpi ドライバが管理する下記レジストリから取得しています。

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\<X>\Device Parameters]
    "PortName"="COM<N>"

    (上記レジストリ キーの <X> 部分と、レジストリ値 <N> 部分が示す序数は、同じ値であるとは限りません。)

    ですので、COM ポート名割り当ての排他を行いたいのであれば、シリアル デバイス スタックの基底となる PDO を提供する acpi ドライバへの問い合わせ処理が必要になると思うのですが、そのあたりの実装はどうされているのでしょうか?

    • 回答の候補に設定 星 睦美 2014年1月21日 5:30
    • 回答としてマーク 星 睦美 2014年1月27日 2:48
    2014年1月15日 10:44
  • フォーラム オペレーターの星 睦美です。

    お馬鹿 さんからの返信が質問の参考になったのではないかと思いますので、私から[回答としてマーク] させていただきました。もし引き続き質問がありましたら、遠慮なく[回答としてのマークの解除] をして返信できます。

    それではこれからもMSDN フォーラムをお役立てください。


    フォーラム オペレーター 星 睦美 - MSDN Community Support

    2014年1月27日 2:51