これには有効な解決策があります。これは一種のハックですが、機能します。
解決策を示す前に、簡単な免責事項を述べます。私はヘファーマンにほぼ同意します。それは意図されたものではありません。実際には、配送コードに対してこれを行うことはお勧めしません。これは、32 ビットのテキスト エディター、ワープロ (32 ビットの Office を含む)、または通常のアプリがサポートしていないものです。64 ビット システムの通常のユーザーは、ファイルを直接システム ディレクトリで開いたり保存したりしません。そして、ほとんどの管理者以外のユーザーは、とにかくそこにあるファイルに触れるための適切な許可を持っていません. Microsoft は、32 ビット アプリの非常に正当な理由でファイル システムをリダイレクトします。それと戦おうとしないでください。
それでは解決策に進みましょう。
トリックは、DLL_THREAD_ATTACH コールバックごとに DllMain で DLL が Wow64DisableWow64FsRedirection を呼び出すようにすることです。
最初に、DllMain のみを持ち、"StartDisableRedirect" と "DisableRedirection" の 2 つの関数をエクスポートする単純な DLL を作成します。
bool g_fDisableRedirect = false;
__declspec(dllexport)
int DisableRedirection()
{
void* pVoid = NULL;
Wow64DisableWow64FsRedirection(&pVoid);
return 0;
}
__declspec(dllexport)
int StartDisableRedirect()
{
g_fDisableRedirect = true;
return 0;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
{
void* pVoid = NULL;
if (g_fDisableRedirect)
{
DisableRedirection();
}
break;
}
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
バイナリ (EXE または DLL) をこの DLL に直接リンクさせます。次に、GetOpenFileName を呼び出す直前に、StartDisableRedirect (後続のスレッドがリダイレクトされないようにするため) と DisableRedirect (現在のスレッド用) を呼び出します。
フックが実際にスレッドの処理を開始する前に、すべての DLL (システム DLL を含む) がロードされるように、意図的に「開始」関数を作成しました。Wow64Disable を実装する DLL が私の DLL の前にロードされるとは思いたくありませんでした。DllMain からコードを呼び出すときは、非常に注意する必要があります (読む: すべきではありません)。
extern int StartDisableRedirect();
extern int DisableRedirection();
void OnFile(HWND hwndParent)
{
StartDisableRedirect();
DisableRedirection();
OPENFILENAME ofn = {};
WCHAR szFile[MAX_PATH*2] = {};
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwndParent;
ofn.lpstrFilter = L"All Files\0*.*\0\0";
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = ARRAYSIZE(szFile);
ofn.Flags = OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
::GetOpenFileName(&ofn);
}