Question

We have a piece of code to upload/download and list files at ftp server. It uses WinInet to handle FTP commands. It has been working fine for several years. However, in Windows 8.1 and in Windows 7 with IE 11 the same code sometimes returns error 12003. There is no errors in ftp server logs.

Simple function is used to check if there were errors in FTP-response

bool IsLastErrorReallyAnError()
{
 int err = GetLastError();

 bool isError = true;

 if (err == ERROR_INTERNET_EXTENDED_ERROR)
 {
     isError = false;
     DWORD error, size = 0;
    ::InternetGetLastResponseInfo(&error, NULL, &size);
    std::vector<wchar_t> response(size+1);
    ::InternetGetLastResponseInfo(&error, &response[0], &size);

    utils::trace("Backup", "Checking FTP respose", &response[0]);

    std::vector<std::wstring> lines;
    boost::split(lines, std::wstring(&response[0]), boost::is_any_of(L"\n"));

    for (auto it = lines.cbegin(); it != lines.cend(); ++it)
    {
        // If some response starts with 5хх then it is real error
        if (boost::starts_with(*it,L"5"))
        {
            utils::trace("Backup", "Real FTP error", &((*it)[0]));
            isError = true;
            break;
        }
    }

    if (!isError)
    {
        utils::trace("Backup", "Checking FTP respose ", L"false error!");
    }
 }

 return isError;
}

And in logs of our programm we get

05:56:43.680    0x21c   ERR CFtpFileSystem  CFtpFileSystem::TryOpenBinaryFile: FtpOpenFileW error 12003
05:56:43.680    0x21c   INF Backup  Checking FTP respose: 226 Transfer OK
200 Type set to I

05:56:43.680    0x21c   INF Backup  Checking FTP respose : false error!

In FTP server logs (it has different timezone):

(000445)30.10.2013 16:56:23 - (not logged in) (10.16.83.3)> Connected, sending welcome message...
(000445)30.10.2013 16:56:23 - (not logged in) (10.16.83.3)> 220-FileZilla Server version 0.9.41 beta
(000445)30.10.2013 16:56:23 - (not logged in) (10.16.83.3)> 220-written by Tim Kosse (Tim.Kosse@gmx.de)
(000445)30.10.2013 16:56:23 - (not logged in) (10.16.83.3)> 220 Please visit http://sourceforge.net/projects/filezilla/
(000445)30.10.2013 16:56:29 - (not logged in) (10.16.83.3)> USER test
(000445)30.10.2013 16:56:29 - (not logged in) (10.16.83.3)> 331 Password required for test
(000445)30.10.2013 16:56:35 - (not logged in) (10.16.83.3)> PASS ****
(000445)30.10.2013 16:56:35 - test (10.16.83.3)> 230 Logged on
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> TYPE I
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 200 Type set to I
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> PASV
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 227 Entering Passive Mode (10,16,82,191,238,169)
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> STOR /srv-test/0f0c04cc-c323-4bb6-a814-696fbbd695c3/527101B9/ab42ed5a-7df0-4421-a03c-d9f75891dcbf
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 150 Connection accepted
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 226 Transfer OK
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> TYPE I
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 200 Type set to I
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> PASV
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 227 Entering Passive Mode (10,16,82,191,238,170)
(000445)30.10.2013 16:56:56 - test (10.16.83.3)> disconnected.

Any ideas how to tune wininet version which comes with IE11 to get rid of such errors?

Was it helpful?

Solution

Unfortunately, not a problem in your code.

It's one of the few cases, where you actually are getting caught in a brandnew, yet major problem in the updated WinInet included with the just released IE 11. It will break most FTP apps using Microsoft's FTP classes for Win 7/8 users who upgrade. I recommend you add yourself to this bug report: https://connect.microsoft.com/IE/feedback/details/808279/ftpopenfile-and-internetwritefile-broken-changed-in-ie11 to hopefully instill some urgency into Microsoft.

Details

The underlying problem appears to be any FTP interaction where WinInet depends on specific server responses. It will work the FIRST time in an FTP session but after that, WinInet always lags behind one response - thus never seeing the correct response codes it needs to handle subsequent requests.

Example

PASV mode STOR requires the WinInet to parse the server response for the open data port. It will fail for the second upload, if FtpOpenFile() is used (although FtpPutFile seems to work, and possible PORT mode).

Related Problems

There are also reports about any more than the very first FtpRename failing - because after the RNFR piece, WinInet waits for a specific response before sending the RNTO piece. When WinInet lags behind, it will never see the PREVIOUS server response code, never the necessary Server response code it is waiting for (although traces confirm that the server did send it).

How to Reproduce

This can be observed by using InternetGetLastResponseInfo() after each FTP API call. After the first PASV upload using FtpOpenFile() or the first Rename, all subsequent FTP API calls will show the server response to the PRECEDING FTP API call.

(PS: I thought I had pointed this bug out yesterday - no sense everyone trying to "fix" their own code when the problem is elsehwere. But somehow the info disappears by the next day. Hopefully people will find the information on other sites using Google.)

OTHER TIPS

I solved this problem by dynamically loading an old version of the DLL that I've found on SxS folder.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top