ユーザーモードコンポーネントと通信する必要がある(一種のフィルター)ドライバーがあります。を呼び出してデバイスオブジェクトを作成しIoCreateDevice
、次に、によってそのデバイスオブジェクトのいわゆるMS-DOSシンボリックリンクをIoCreateSymbolicLink
作成して、ユーザーモードコード(によって)からアクセスできるようにしますCreateFile
。これは多かれ少なかれ標準的な手法です。ドライバーはフォームのシンボリックリンクを作成します\DosDevices\mydevicename
が、ユーザーモードコードは。という名前のファイルを開きます\\.\mydevicename
。
ここで、問題は、ドライバーがターミナルサーバーセッションのコンテキストでデバイスを作成するときに始まります。作成されたシンボリックリンクは実際にはローカルセッションディレクトリに属していますが、私のユーザーモードサービスは「ゼロセッション」のシステムアカウントで実行され、グローバルディレクトリに属するシンボリックリンクを「認識」します。
ドキュメントには、通常は問題がないと記載されています。ドライバーは、ほとんどの場合、DriverEntry
またはAddDevice
関数のコンテキストでデバイスオブジェクトを作成し、システムアカウントで実行されることが保証されているためです。しかし、私の場合は異なります。そして、これを変更したくありません。本当に必要なのは、任意のセッションに属する任意のスレッドのコンテキストでデバイスオブジェクトを作成/破棄できるようにすることです。
ドキュメントによると、これを解決する方法があります。ドライバは、次のように名前を付けることにより、グローバルディレクトリに属するシンボリックリンクを作成するように要求する場合があります\DosDevices\Global\mydevicename
。さらに、ユーザーモードコードが何らかのアカウントで実行された場合、ファイルに次のように名前を付けることで、グローバルディレクトリでリンクを探すように要求される場合もあります\\.\Global\mydevicename
。これは通常は必要ありませんが、シンボルがローカルディレクトリに存在しない場合は、グローバルディレクトリで自動的にチェックされます。
私はこのトリックを試しました:それは私にはうまくいきません。私はWindows2008R2、64ビットを使用しています。これまでのところ成功はありません。システムアカウントで作成されたデバイスを一貫して開くことはできますが、別のセッションで作成されたデバイスを開くことができません(エラーコードは「ファイルが見つかりません」です)。\Global
カーネル/ユーザーモードで指定するすべての組み合わせとバリエーションを試しましたが、これまでのところ結果は同じです。
これにより、シンボル分離のレベルがもう1つあるのではないかと思います。おそらく、を使用\Global
すると、グローバルなセッション全体であるが、システム全体ではないシンボリックリンクが作成されます。
これは意味がありますか?システム全体のシンボリックリンクを作成する方法はありますか?または、シンボリックリンクが別のセッションに属しているファイルを開く方法はありますか?
編集:
@HansPassantに感謝します。WinObjユーティリティを試して、ドライバが実際に作成するデバイスとシンボリックリンクを実際に確認しました。
一見、すべて問題ないようです。ディレクトリの下にすべてのデバイスが表示され\Device
、すべてのシンボリックリンクがの下にあり\GLOBAL??
ます。シンボリックリンクは正しいデバイス名を指します。
ただし、奇妙なことが1つあります。WinObj内からデバイスのプロパティを確認しようとしています。ゼロセッションで作成されたデバイスの場合、これは問題なく機能しますが、他のセッションで作成されたデバイスの場合、WinObjはエラーで応答します。
- \ Device \ mydevicenameを開くときにエラーが発生しました:システムは指定されたファイルを見つけることができません。
そのため、このデバイスオブジェクトはリストに表示されますが、OTOHを開こうとすると、「見つかりません」と表示されます。非常に奇妙な。しかし、これは私の問題を説明しています。しかし、これは本当に奇妙です。
何か案は?前もって感謝します。