卸载 WinInet 时应用程序挂起或崩溃

发布于 2024-08-02 00:16:53 字数 1576 浏览 6 评论 0原文

我有一个使用 WinInet 的 VC++ 应用程序。 它执行以下操作:

  • 调用 LoadLibrary() 加载 WinInet.dll
  • 调用 InternetAttemptConnect()
  • 调用 InternetOpen()
  • 调用 InternetConnect() 提供 INTERNET_SERVICE_FTP 作为 dwService

如果最后一次调用失败(通常是因为传递了错误的密码)InternetConnect() 返回 0,这应该通过将错误写入日志并退出应用程序来处理。

当发生这种情况时,应用程序调用 InternetCloseHandle() 来关闭 InternetOpen() 返回的句柄,并离开 WinMain()

之后,库卸载开始 - 持有 wininet.dll 句柄的静态对象被销毁并调用 FreeLibrary() 或由 Windows 调用 FreeLibrary()。 无论如何,对 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 尚未正确完成,处理此问题需要一些额外的操作和时间。

对于这种情况有解决方法吗?

I have a VC++ application that uses WinInet. It does the following:

  • calls LoadLibrary() to load WinInet.dll
  • calls InternetAttemptConnect()
  • calls InternetOpen()
  • calls InternetConnect() providing INTERNET_SERVICE_FTP as dwService

If the last call fails (usually because of wrong password passed) InternetConnect() returns 0 and this should be handled by writing an error into the log and quitting the application.

When that happens the application calls InternetCloseHandle() for closing the handle returned by InternetOpen() and leaves WinMain().

After that libraries unloading begins - either a static object holding a handle to wininet.dll is destriyed and FreeLibrary() is called or FreeLibrary() is called by Windows. In any case the call to FreeLibrary() either hangs or crashes.

Usually it hangs with the following call stack:

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 

Sometimes it just crashes with no reasonable call stack to show. I suppose the problem is that WinInet has not been finalized properly and handling this requires some extra action and time.

Is there a workaround for this situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文