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) を使用していないようです!