InternetReadFile, FTP and partial buffers

Krzysztof Foltman kfoltman at portal.onet.pl
Sun Sep 5 15:25:30 CDT 2004


Hi All,

In the original WinInet FTP implementation, InternetReadFile always 
returns complete buffers, except for the last block. Some programs 
(probably ill-behaving ones, but I wouldn't bet my head on it) rely on 
that fact, and stop retrieving the file after the first incomplete block.

This patch seems to fix that, by reading the socket until the buffer is 
full or end of stream is encountered. This way, the only incomplete 
buffer returned might be the last one.

It seems to fix that particular application (which works under Windows 
correctly), however, I don't know any other applications that would use 
WinInet's FTP, so it still might be buggy in some way.

It seems there's another FTP bug, which causes (some?) FTP URL's without 
username and password to crash WINE. However, I didn't research the 
problem (except for accidently encountering it while trying to diagnose 
the problem above), and can't give a test case or a patch now.

Chris
-------------- next part --------------
Index: internet.c
===================================================================
RCS file: /home/wine/wine/dlls/wininet/internet.c,v
retrieving revision 1.95
diff -u -r1.95 internet.c
--- internet.c	19 Aug 2004 19:02:17 -0000	1.95
+++ internet.c	5 Sep 2004 19:32:46 -0000
@@ -1646,9 +1646,23 @@
             nSocket = ((LPWININETFILE)lpwh)->nDataSocket;
             if (nSocket != -1)
             {
-                int res = recv(nSocket, lpBuffer, dwNumOfBytesToRead, 0);
-                retval = (res >= 0);
-                *dwNumOfBytesRead = retval ? res : 0;
+                LPBYTE lpBufPart = (LPBYTE)lpBuffer;
+                *dwNumOfBytesRead = 0;
+                retval = TRUE;
+                while (dwNumOfBytesToRead - *dwNumOfBytesRead > 0) {
+                    int res = recv(nSocket, lpBufPart, 
+                        dwNumOfBytesToRead - *dwNumOfBytesRead, 0);
+                    if (res < 0)
+                    {
+                        *dwNumOfBytesRead = 0;
+                        retval = FALSE;
+                        break;
+                    }
+                    *dwNumOfBytesRead += res;
+                    lpBufPart += res;
+                    if (!res)
+                        break;
+                }
             }
             break;
 


More information about the wine-patches mailing list