2016-12-03 10 views
0

問題は、要求された関数が存在しない古いマシンでコードを実行していることです。これを確認するにはLoadLibraryGetProcAddressを使用し、hereを使用しますが、GetProcAddressでは、使用する前にTypeDefの機能のアドレスが必要です。
は例えば、取るなどにこれら二つの、XP SP2 32ビット:関数ポインタ付きTypeDef:関数が存在しない

typedef BOOL (__stdcall *LPFN_Wow64RevertWow64FsRedirection) (PVOID OldValue); 
typedef BOOL (__stdcall *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); 
... 

... 
LPFN_Wow64RevertWow64FsRedirection wowRevert = NULL; 
LPFN_Wow64DisableWow64FsRedirection wowDisable = NULL; 
HINSTANCE hLib; 
if(GetProcAddresses(&hLib, "kernel32.dll", 2, &wowRevert,_ 
"Wow64RevertWow64FsRedirection", &wowDisable, Wow64DisableWow64FsRedirection")) 
{... 

コードをここにクラッシュ:

プロシージャエントリポイントWow64RevertWow64FsRedirectionがダイナミックリンクライブラリKERNEL32に配置することができませんでした。 DLL

それは非WINAPIののtypedefを持つ当社独自のカスタムWow64RevertWow64FsRedirectionを実装するのは簡単に十分だが、ときFUNCTどのように彼らは、ベース型に置き換えることができますkernel32.dllにイオンが存在しますか?

+0

*しかし、GetProcAddressには関数のアドレスが必要です* - そうではありません。 [GetProcAddress](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212%28v=vs.85%29.aspx)には、モジュールハンドルと文字列が必要です。 – PaulMcKenzie

+0

@Paul:ここで助けてください。あなたの[回答](http://forums.codeguru.com/showthread.php?247936-Problem-using-GetProcAddress)を見ていた途中で:これはまだ適用されますか? –

+0

'GetProcAddress'は、関数へのポインタを返します。関数を呼び出すには、関数ポインタ(文字列名のポインタを除く)は必要ありません。 – PaulMcKenzie

答えて

1

私はあなたの質問を理解するのに少し問題があります。 Wow64RevertWow64FsRedirection関数は32ビットオペレーティングシステムには存在しないため、32ビットWindows XPには存在しません。したがって、GetProcAddressでこの関数へのポインタを取得しようとすると失敗します。このエントリーポイントが見つからないという賢明なエラーが発生します。エントリポイントが見つからない場合、関数は存在しないので、呼び出すことはできません。

独自のカスタムWow64RevertWow64FsRedirection機能を実装できると主張していますが、私はこれをやりたい理由を控えめに考えていません。オペレーティングシステムがWOW64ファイルシステムリダイレクトをサポートしている場合は、Wow64RevertWow64FsRedirection機能を提供します。それがなければ、それは機能を提供しませんが、は、WOW64ファイルシステムリダイレクトのようなものがないので、そのような機能が必要です。有効化、無効化、または元に戻す必要はありません。

これは、必要以上に複雑になっているようです。プロセスが64ビットプロセスであることを最初に確認する必要はありません。エントリポイントをWow64RevertWow64FsRedirection(または必要に応じてWow64DisableWow64FsRedirection)に設定したり、存在する場合はそれを呼び出したり、存在しない場合は無視したりできます。

それは同じくらい簡単です:私はモジュールkernel32.dll.dll拡張子が暗示される)へのハンドルを取得するためにGetModuleHandle関数を呼び出しています

BOOL RevertWOW64RedirectionIfNecessary(PVOID pOldValue) 
{ 
    typedef BOOL (WINAPI * fnWow64RevertWow64FsRedirection)(PVOID); 

    fnWow64RevertWow64FsRedirection pfn = 
     reinterpret_cast<fnWow64RevertWow64FsRedirection>(
      reinterpret_cast<void*>(
      GetProcAddress(GetModuleHandle(L"kernel32"), 
          "Wow64RevertWow64FsRedirection"))); 

    if (pfn) 
    { 
     // The function exists, so call it through the pointer we obtained. 
     return pfn(pOldValue); 
    } 
    else 
    { 
     // The function does not exist, so we can't call it. 
     // But we don't ever need to call it in such cases, 
     // so do nothing and feign success. 
     return TRUE; 
    } 
} 

注意。私はkernel32.dllがどのアプリケーションのプロセスでも常にロードされることが保証されているので、LoadModuleの代わりにGetModuleHandleをここで使用できます。 GetModuleHandleを使用しているので、モジュールハンドルを解放する必要はありません。

GetProcAddress関数に結果のハンドルを、アドレスを取得する関数/プロシージャの名前を含む文字列とともに渡します。この関数は、その関数のアドレスを取得しようとします。存在する場合はそれを返します。それ以外の場合は失敗し、NULLが返されます。

有効なポインタが返されているかどうかを確認し、有効な場合はそのポインタを介して関数を動的に呼び出します。さもなければ、それは関数が利用できないことを意味するNULLを返しました、しかしその場合、私達はそれについて心配する必要もないので、コードはちょうどノーオペレーションになります。

面白いキャスティングについては、my answer hereを参照してください。このトリックについて説明しています。

+0

OUCH!数時間のグーグルがちょうど[これ](http://stackoverflow.com/questions/25413612/wow64disablewow64fsredirection-on-32-bit-windows-xp)に遭遇しました。しかし、ありがとうございました。事は、WOW64ステートメントが実行される前にコードがクラッシュしたことでした。最初に、グローバルに宣言されたのは、 'LPFN_ISWOW64PROCESS'だけであると仮定しました。 –

+0

[Codeproject](https://www.codeproject.com/Articles/1087/Loading-DLLs-made-easy?)のメソッドのように見えますが役に立たないのですか? –

+0

それは私にとってはむしろ過度に設計されています。ロードしたいモジュールがロードされていることを保証できない場合には、より役に立ちます。つまり、 'GetModuleHandle'を使うことはできず、' LoadLibrary'を呼び出さなければなりません。 'FreeLibrary'を呼び出すことを意味します。大規模な動的ロードを行う必要があるときには、複雑なラッパーマクロを使用します。これは、書き込みするコードの量を単純化し、エラーの可能性を減らすためです。しかし、このような単純なシナリオでは必要ありません。 –

関連する問題