トップ回答者
カーネルモードでのCOMポート制御について

質問
-
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
回答
-
ドライバ内で 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 ドライバへの問い合わせ処理が必要になると思うのですが、そのあたりの実装はどうされているのでしょうか?
すべての返信
-
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
-
ドライバ内で 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 ドライバへの問い合わせ処理が必要になると思うのですが、そのあたりの実装はどうされているのでしょうか?