WinInet を使用する VC++ アプリケーションがあります。次のことを行います。
- WinInet.dll
LoadLibrary()
をロードする呼び出し - 通話
InternetAttemptConnect()
- 通話
InternetOpen()
- として
InternetConnect()
提供する呼び出しINTERNET_SERVICE_FTP
dwService
最後の呼び出しが失敗した場合 (通常、渡されたパスワードが間違っているため)InternetConnect()
は 0 を返します。これは、ログにエラーを書き込んでアプリケーションを終了することで処理する必要があります。
それが起こると、アプリケーションはInternetCloseHandle()
によって返されたハンドルを閉じるように呼び出し、InternetOpen()
を離れWinMain()
ます。
その後、ライブラリのアンロードが開始されます。wininet.dll へのハンドルを保持する静的オブジェクトが破棄されFreeLibrary()
て呼び出されるかFreeLibrary()
、Windows によって呼び出されます。いずれにせよ、呼び出しがFreeLibrary()
ハングまたはクラッシュします。
通常、次のコール スタックでハングします。
ntdll.dll!KiFastSystemCallRet()
ntdll.dll!NtWaitForSingleObject() + 0xc
kernel32.dll!WaitForSingleObject() + 0x12
wininet.dll!InternetInitializeAutoProxyDll() + 0xe3
wininet.dll!InternetInitializeAutoProxyDll() + 0x193e
wininet.dll!771b159d()
ntdll.dll!LdrInitializeThunk() + 0x24
ntdll.dll!LdrDisableThreadCalloutsForDll() + 0x949
kernel32.dll!FreeLibrary() + 0x19
MyApp.exe!$E5() + 0x10 C++ <-presumably the static object destructor call
msvcr71.dll!doexit(int code=0, int quick=0, int retcaller=0) Line 376 C
msvcr71.dll!exit(int code=0) Line 303 + 0xd C
MyApp.exe!wWinMainCRTStartup() Line 406 C <-entry point of my application
kernel32.dll!RegisterWaitForInputIdle() + 0x49
適切なコール スタックを表示せずにクラッシュすることもあります。問題は、WinInet が適切にファイナライズされておらず、これを処理するために追加のアクションと時間が必要になることだと思います。
この状況の回避策はありますか?