none
デバイスオブジェクトハンドルの取得方法 RRS feed

  • 質問

  • CreateFileで取得したデバイスオブジェクトハンドルを、再度デバイスドライバから取得する方法はありますか。

    既にオープンされているデバイスオブジェクトについて、そのハンドルを得る方法です。

     

     

     

     

     

    • 移動 Mike Wang (MSCS) 2012年10月2日 12:47 (移動元:Windows デバイスドライバー開発)
    2011年6月4日 8:42

回答

  • > 要するに、デバイス ハンドルのオープン云々と言うことではなく、2つの DLL 間で配列変数のデータを共有したい(あるいはデータの同期を取りたい)と言うことでしょうか?

    マルチプロセス云々については、質問の本題からそれている話であることは承知ですが、異なるプロセス空間でハンドルを共有することは不可能とおっしゃっていたので、実際の対策を説明した次第です。

    > ドライバやデバイス ハンドルとは全然関係のない話になってきたような 

    おっしゃる通りです。関係のない話になってしまっています。ありがとうございました。

     

     

     

    • 回答としてマーク cdefg 2011年6月16日 0:16
    2011年6月16日 0:16

すべての返信

  • どのような種類の Device Driver を作成されていて、なぜ User Mode 側で取得した Device Handle を Driver 側で必要とするのか、その背景が書かれていないので参考になるかわかりませんが。。。
    (。。。といか、Driver が自身の Device Object 対応する Device Handle を必要とするシナリオが私には思い浮かばないので。。。)

    試したことはありませんが、下記 Object Manager Service Function を使えば、とりあえず Device Handle を取得することは可能ではないかと。。。

    ----------
    - ObOpenObjectByPointer -
    http://msdn.microsoft.com/en-us/library/ff550985(v=vs.85).aspx
    ----------

    具体的には、IRP の IO_STACK_LOCATION 構造体 FileObject メンバにセットされてくる FILE_OBJECT 構造体ポインタを ObOpenObjectByPointer() の 1st パラメータにセットしてコールすれば、もしかしたら既存の Device Handle を取得できるかもしれません。
    ただしこの方法で取得できるのは、Create IRP が成功した後 (当たり前の話ですが)でないとダメだと思います。
    (上記ドキュメントにもそれらしいことが書いてあると思いますので、ご自身でご確認ください。)
    また IO_STACK_LOCATION 構造体 FileObject メンバには、必ず FILE_OBJECT 構造体ポインタがセットされている訳ではないと思いますので、その点にも注意が必要になると思います。

    ただ。。。
    CreateFile() API で取得される Device Handle と Driver が生成する Device Object は、ほとんどの場合「1対1」の関係にはならないと思いますので、1つの Device Object に対して、CreateFile() API が成功した数だけ Device Handle が存在する。。。ということになるんだと思います。
    (そのような情報をなぜ Driver 側で把握しなければならないのか。。。やっぱり私にはその理由が思い浮かばないので、もし差し支えが無ければ後学のためご教授いただければ幸いです。)

    私の認識に誤りがありましたらご容赦ください。

    2011年6月6日 10:54
  • 回答ありがとうございました。

    質問文を読み返すと、質問の意図が非常に伝わりにくい内容でした。申し訳ありません。

    ユーザモード側で取得したデバイスオブジェクトハンドルをドライバ側で必要とするわけではなく、

    ユーザモード側で取得したデバイスオブジェクトハンドルを再度、ユーザモードで取得する方法についてでした。

    その背景については、以下の通りです。

    機能的には独立したPCIボードAとPCIボードBがあり、両ボードを1つのボードに統合することになりました。

    それに伴い、デバイスドライバとDLLも統合することになりましたが、DLLの統合にあたりできるかぎりソースコードを修正しない方針としました。

    従来、2つのDLLはそれぞれCreateFileによりハンドルを得ていましたが、今度は一方のDLLのCreateFileは残して、

    もう一方のDLLは既にオープン済みのハンドルを取得できないものかと考え、質問させていただきました。

     

    2011年6月7日 5:12
  • 今回のご質問はドライバ側の実装ではなく、ユーザ モード側 DLL の実装に関するご質問。。。という理解でよろしいのでしょうか?
    DLL の実装に関するご質問。。。と言うことだとしても、この内容に対してコメントするには、以下の2点に関してその前提を明確にしておく必要があると思います。

    ------------------------------------
    ☆ "PCI Board A" と "PCI Board B" はそれぞれ独立した機能を提供しているとのことですが、
       ドライバを統合させた場合、それぞれの機能に対するデバイス オブジェクトも統合することが
       可能なのでしょうか?
       つまりデバイス側の仕様として、ドライバが1つのデバイス オブジェクトで、"PCI Board A" /
       "PCI Board B" それぞれが提供する機能をサポートできる作りになっているのでしょうか?

    ☆ "PCI Board A" と "PCI Board B" に対応する DLL は、同一プロセスの異なるスレッド コンテキスト
       として動作させることが前提でしょうか?
       それとも異なるプロセス空間で動作させるのでしょうか?
    ------------------------------------

    先の返信でも少し触れましたが、1つのデバイス ハンドルはそれに対応する1つのファイル オブジェクトに結びつけられ、そのファイル オブジェクトは1つのデバイス オブジェクトに結び付けられるはずだと思います。
    つまり (DevNode の階層構造およびドライバの作りにも依存しますが)、基本的に1つのデバイス ハンドルで制御できるのは、それに結び付けられている1ついのデバイス オブジェクトに対してのみのはずだと思うのです。
    なので、PCI Board を統合したとしても、ドライバが機能的に2つ以上のデバイス オブジェクトを必要とするのであれば、デバイス ハンドルも2つ以上必要になると思います。
    (私の理解不足で申し訳ありませんが、異なる2つの機能を1つの Board 上に統合させたとしても、それを1つのデバイス オブジェクトで制御する方法がイメージできないのです。。。たとえば。。。キーボード/マウス一体型のデバイスなどを考えてみても、デバイス オブジェクトは個々に独立しているはずだし。。。。)

    また、ハンドルを管理するハンドル テーブルはプロセス単位で保持されるはずなので、異なるプロセス空間でハンドルを共有することは不可能だと思うのですが。。。。

    私の認識に誤りがありましたらご容赦ください。

    2011年6月7日 11:52
  • 回答ありがとうございます。

    デバイスドライバについて、詳細を確認しましたが、デバイスオブジェクトも統合し、1つのデバイスオブジェクトで"PCI Board A" と "PCI Board B"の機能をサポートします。

    また、"PCI Board A" と "PCI Board B"に対応するDLLは、同一プロセスでも異なるプロセスでも動作可能で、同一プロセスの場合は、同一スレッドでも異なるスレッドでも動作可能にします。

    尚、デバイスドライバで行っていることといえば、"PCI Board A" 用と "PCI Board B" 用のそれぞれに定義されたI/Oコントロールを受けつけ、I/O空間に割り当てられた"PCI Board A" または "PCI Board B"のI/O PORTにアクセスするだけのことです。

     

     

     

    2011年6月14日 5:18
  • > 同一プロセスでも異なるプロセスでも動作可能

    この前提があるのであれば、異なる DLL 間でデバイス ハンドルを共有するような実装をすべきでは無いと思いますし、また不可能だと思います。
    先の返信も触れましたが、ハンドルを管理するハンドル テーブルはプロセス単位で保持されるはずなので、異なるプロセス空間でハンドルを共有することは不可能だと思います。
    仮に DLL 間でデバイス ハンドルを共有しなければならない必然性があるのだとすれば、その仕様自体に無理がある。。。ということではないかと。。。

    2011年6月14日 12:26
  • 度々説明不足で申し訳ありません。

    DLL内部ではプロセスIDとデバイスハンドルを関連付けたプロセス間共有の配列変数を用意し、プロセスの起動・終了ごとに配列を更新します。

    DLLの関数が呼び出されたときは、現在のプロセスIDを上記配列から検索し、それぞれのプロセスにおけるデバイスハンドルでデバイスドライバにアクセスするため、異なるプロセスでも正常に動作します。

    今回、DLLを統合しますが、上記配列変数は統合前の変数名から変更せず、別名・同機能で2種類実装したいと思っています。

    プロセスの起動時、一方のDLLはCreateFileで取得したハンドルで配列変数を更新し、もう一方のDLLは何らかの方法により取得したハンドルで配列変数を更新できれば、2つの配列変数の中身は全く同じものになるのではないかと考えております。

    そこで、既にオープンされているデバイスオブジェクトについて、そのハンドルを得る方法を質問させて頂きました。

     

    2011年6月15日 8:53
  • > 今回、DLLを統合しますが、上記配列変数は統合前の変数名から変更せず、別名・同機能で2種類実装したいと思っています。

    要するに、デバイス ハンドルのオープン云々と言うことではなく、2つの DLL 間で配列変数のデータを共有したい(あるいはデータの同期を取りたい)と言うことでしょうか?
    (。。。なんか、ドライバやデバイス ハンドルとは全然関係のない話になってきたような。。。)

    2011年6月15日 12:38
  • > 要するに、デバイス ハンドルのオープン云々と言うことではなく、2つの DLL 間で配列変数のデータを共有したい(あるいはデータの同期を取りたい)と言うことでしょうか?

    マルチプロセス云々については、質問の本題からそれている話であることは承知ですが、異なるプロセス空間でハンドルを共有することは不可能とおっしゃっていたので、実際の対策を説明した次第です。

    > ドライバやデバイス ハンドルとは全然関係のない話になってきたような 

    おっしゃる通りです。関係のない話になってしまっています。ありがとうございました。

     

     

     

    • 回答としてマーク cdefg 2011年6月16日 0:16
    2011年6月16日 0:16