3

32 ビットで実行する必要がある Windows アプリケーションがあります (他の制限により制御できないため)。ただし、私のアプリケーションは、インストールされているシステムに応じて、32 ビットまたは 64 ビットのドライバーを呼び出してアクセスする必要があります。

DeviceIoControl() 呼び出しを介してドライバーにアクセスし、インクルード ファイルで宣言されたデータ構造を交換します。データ構造には、「DWORD_PTR」として宣言されたフィールドが含まれています (インクルード ファイルも制御しません)。

私の問題は、64 ビット システムでは、ドライバーが構造体に 64 ビット整数が含まれていることを期待していることです (DWORD_PTR 宣言のため)。ただし、私の 32 ビット プログラムは、これらの DWORD_PTR を 32 ビット整数として認識します。次に、データ構造のプログラム バージョンと、それらの構造のドライバーの理解との間にデータの不一致があります。

DeviceIoControl() は ERROR_INSUFFICIENT_BUFFER で失敗します (システム コールに渡されるデータ領域が小さすぎます)。構造体の 64 ビット バージョンをドライバーに渡すと、このエラーが発生しないことを確認しました。

この混乱の中には、いくつかの醜いオプションがあります。しかし、誰かがより良い提案を持っているのだろうか?


解決:

  • REAL 64 ビット データ フィールド (__int64) を使用して、共有構造体の新しいコピーを宣言します。
  • OS アーキテクチャを動的にチェックする (32/64)
  • DeviceIoControl() 呼び出しの構造体の 32 ビットまたは 64 ビット バージョンを使用します。

欠点:

  • 構造体宣言の明示的な 64 ビット コピーを手動で維持する必要があります。それは時間が経つにつれて痛みになる可能性があります。

私の他のソリューションはこれのバリエーションですが、常に構造定義のコピーを維持する必要があります (たとえば、COM サーバーの IDL オプションなど)。

編集: これは Microsoft ドライバーであり、IoIs32bitsProcess(irp) を使用していないようです!

4

2 に答える 2

5

構造体の 32 ビット バージョンと 64 ビット バージョンの両方を維持しIoIs32BitProcess(irp)、デバイス ドライバーDEVICE_CONTROLハンドラーの関数を介して特別な処理を実装し、必要に応じてそれを 64 ビット構造に変換します。これが一般的な方法です。

これについては、MSDN にかなりの量のドキュメントがあります

後でドライバーのソース コードを制御できないとおっしゃっていたので、32 ビット版と 64 ビット版の独自のバリアントを維持し、OS アーキテクチャをチェックする適切なバリアントを送信することをお勧めします。ドライバの構造体宣言が適切に行われていないようです。

于 2009-04-09T03:22:14.843 に答える
0

常に 64 ビット定義を使用するように、ヘッダーに構造体 defs を含めるときに #define を操作する方法はありますか? それが私にとって最良の選択肢のようです(可能であれば)。

そうでない場合は、自分のコードで 64 ビット構造をシャドーイングします。そうすれば、全体に散らばる if32bit/if64bit のものではなく、注意すべき構造定義のみが存在します。これはバグが発生しやすいようです。おそらく、次のようなことができます。

_ASSERT(sizeof(myStruct) == sizeof(64bitStruct)) 

アプリの開始時に、新しいヘッダーを取得した場合は、アプリの最初の実行時に同期が必要であることを通知します。

于 2009-04-11T22:58:21.650 に答える