2017-02-13 3 views
1

私はx86(32ビット)用にコンパイルされたC++プログラムを持っています。カーネルモードドライバを呼び出しています。ドライバは、両方が動作しているOSのワードサイズのためにコンパイルされます。ターゲットオペレーティングシステムは、32または64ビット(私の場合はウィンドウ)です。C++で実行時にオペレーティングシステムの語長を調べる方法は?

私の問題は、OSコールによって必要とされるので、ドライバが返すポインタのサイズを決定することです。

HANDLE device = OpenDevice(); 
HANDLE packageReceivedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 
bool result = DeviceIoControl(
    device, 
    IOCTL_CODE, 
    &packageReceivedEvent, //for signaling 
    sizeof(HANDLE), //TODO does not work for 64 bit 
    nullptr, 
    0, 
    &recvBytes, 
    nullptr); 

定義が標準winbase.hとWINNT.Hから来る:システムが32ビットのワードサイズを持っていた場合

ユーザーモードプログラムの次の呼び出しは、働いていました。

sizeof(int)のようなコンパイル時のソリューションは使用できません。これは、ユーザーモードプログラムだけに関係するもので、ドライバのコンパイルには依存しません。

おそらくDeviceIoControlnInBufferSizeを予想される最高のワードサイズに設定すれば十分でしょうが、より良い解決策がありますか?

+0

が、これは実際に問題になる場合、あなたがチェックしましたか?通常、OSはスマートなので、ポインタを使用するために膨大な量のボイラープレートコードを必要とせず、32ビットプログラムの場合は有効な32ビットポインタを、使用している場合は有効な64ビットポインタを与えます64ビットプログラム。 – nwp

+1

64ビットシステムでプログラムの64ビットバージョンを使用します。それは一種のデフォルトです。 32ビット版のプログラムでは、32ビット版のプログラムを使用します。それらはまれです。 –

+1

"32ビットコンパイラ"とはどういう意味ですか?コンパイラは、実行可能ファイルを生成する実行可能ファイルです。Windowsの実行可能ファイルは32ビットと64ビットにできるため、4つの理論上の組み合わせがあり、64ビットの実行可能ファイルを生成する64ビットのコンパイラだけが「32ビットコンパイラ」であるとはっきりとは分かりません。 – MSalters

答えて

1

あなたは32ビットコードの4バイト、64ビットコードの8バイトです。この

union { 
    __int64 v; 
    HANDLE packageReceivedEvent; 
}; 
v = 0; 
BOOL fOk = FALSE; 
if (packageReceivedEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) 
{ 
    BOOL Wow64Process; 
    if (IsWow64Process(NtCurrentProcess(), &Wow64Process)) 
    { 
     fOk = DeviceIoControl(
      device, 
      IOCTL_CODE, 
      &packageReceivedEvent, //for signaling 
      Wow64Process ? 8 : 4, 
      nullptr, 
      0, 
      &recvBytes, 
      nullptr); 
    } 
} 
ULONG err = fOk ? NOERROR : GetLastError(); 

なく「ワード長」(これは常に2バイトである)が、ポインタの長さ、のようなコードが必要です。ドライバは常に「ネイティブ」でなければなりません。したがって、64ビットドライバは64ビットウィンドウで実行できます。ユーザモードアプリケーションは32ビットまたは64ビットです。実行時に確定するにはIsWow64Processを使用してください。いくつかのドライバは64ビットレイアウト構造だけを受け取り、あるものはIoIs32bitProcessで32ビットプロセスを確定し、32ビットプロセスから32ビットレイアウト構造を待ちます。明らかにあなたのドライバは64ビットレイアウト構造だけを受け入れます。あなたが入力サイズとして8つのまたは4バイトを渡す必要がある、窓64から依存またはおそらく32


それは単に予想される最高ワードサイズにのDeviceIoControlのnInBufferSize を設定するのに十分だろうが、そこには立派です ソリューションですか?

これではない解決策:あなたは、単にInputBufferLength == 8と言う場合

  • 32ビットシステムドライバは、64ビットシステムでそのInputBufferLength == sizeof(HANDLE)(およびfalseの場合STATUS_INFO_LENGTH_MISMATCHを返す) またはそのInputBufferLength >= sizeof(HANDLE)
  • を確認することができます 入力バッファの上位32ビットにはどのようなデータが入りますか?あなたのコードであなた のinit packageReceivedEvent = CreateEvent(NULL,FALSE, FALSE, NULL);によってのみ、低い32ビット - あなたは8バイトのバッファを割り当てる必要がある最初と 正しいそれのinit
+1

"ワードサイズ"は、Windowsの 'WORD'型ではなく、インテルアセンブリの構文-w postfix ofまたは" word ptr "ではなく、*機械語*のサイズを指します。これらはすべて下位互換性のために16ビットです。最新のIntelプロセッサーのワードサイズは64ビットです。 – conio

+0

@conio - この場合、私はもっと正しいと思います*レジスタサイズ*(一般)。ウィンドウのビューから正確に必要なことを言う必要があります*ポインタサイズ*(等価*レジスタサイズ*) – RbMm

関連する問題