views:

362

answers:

0

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?