[WININET] Fixes multiple consecutive downloads on FTP link.

Lionel Ulmer lionel.ulmer at free.fr
Sat Jul 19 16:19:23 CDT 2003


Hi all,

With this, Ragnarok Online's patcher tool (which uses a lot of FTP transfer)
now works perfectly. Let's hope FTP transfer on Unix system or in
non-passive mode still work though.

                 Lionel

Changelog:
 - fix multiple consecutive downloads (by flushing when needed the command
   socket)
 - detect attempts to download multiple files at the same time
 - fix size / date reporting when enumerating files
 - fix Y2K problem in NT parsing of files

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- dlls/wininet/ftp.c_sent	Sat Jul 19 17:59:23 2003
+++ dlls/wininet/ftp.c	Sat Jul 19 23:14:44 2003
@@ -46,6 +46,7 @@
 #include "wininet.h"
 #include "winnls.h"
 #include "winerror.h"
+#include "winternl.h"
 
 #include "wine/debug.h"
 #include "internet.h"
@@ -835,6 +836,11 @@
         return FALSE;
     }
 
+    if (lpwfs->download_in_progress != NULL) {
+	INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
+	return FALSE;
+    }
+    
     hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     {
@@ -927,6 +933,10 @@
         hFile->hdr.dwContext = dwContext;
         hFile->hdr.lpwhparent = hFtpSession;
         hFile->nDataSocket = nDataSocket;
+	hFile->session_deleted = FALSE;
+	
+	/* Indicate that a download is currently in progress */
+	lpwfs->download_in_progress = hFile;
     }
 
     if (lpwfs->lstnSocket != -1)
@@ -978,6 +988,11 @@
         return FALSE;
     }
 
+    if (lpwfs->download_in_progress != NULL) {
+	INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
+	return FALSE;
+    }
+    
     hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     {
@@ -1485,6 +1500,7 @@
         lpwfs->hdr.dwContext = dwContext;
         lpwfs->hdr.lpwhparent = (LPWININETHANDLEHEADER)hInternet;
         lpwfs->sndSocket = nsocket;
+	lpwfs->download_in_progress = NULL;
 	sock_namelen = sizeof(lpwfs->socketAddress);
 	getsockname(nsocket, (struct sockaddr *) &lpwfs->socketAddress, &sock_namelen);
         lpwfs->phostent = phe;
@@ -2348,6 +2364,9 @@
 BOOL FTP_CloseSessionHandle(LPWININETFTPSESSIONA lpwfs)
 {
     TRACE("\n");
+
+    if (lpwfs->download_in_progress != NULL)
+	lpwfs->download_in_progress->session_deleted = TRUE;
     
     if (lpwfs->sndSocket != -1)
         close(lpwfs->sndSocket);
@@ -2396,7 +2415,7 @@
 }
 
 /***********************************************************************
- *           FTP_CloseFindNextHandle (internal)
+ *           FTP_CloseFileTransferHandle (internal)
  *
  * Closes the file transfer handle. This also 'cleans' the data queue of
  * the 'transfer conplete' message (this is a bit of a hack though :-/ )
@@ -2408,7 +2427,21 @@
  */
 BOOL FTP_CloseFileTransferHandle(LPWININETFILE lpwh)
 {
+    LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) lpwh->hdr.lpwhparent;
+    INT nResCode;
+
     TRACE("\n");
+
+    if (!lpwh->session_deleted)
+	lpwfs->download_in_progress = NULL;
+
+    /* This just serves to flush the control socket of any spurrious lines written
+       to it (like '226 Transfer complete.').
+
+       Wonder what to do if the server sends us an error code though...
+    */
+    nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
+				   MAX_REPLY_LEN, 0, 0, 0);
     
     if (lpwh->nDataSocket != -1)
         close(lpwh->nDataSocket);
@@ -2476,13 +2509,13 @@
 
     if (lpafp)
     {
-        DWORD access = mktime(&lpafp->tmLastModified);
-
+	/* Convert 'Unix' time to Windows time */
+	RtlSecondsSince1970ToTime(mktime(&lpafp->tmLastModified),
+				  (LARGE_INTEGER *) &(lpFindFileData->ftLastAccessTime));
+	
         /* Not all fields are filled in */
-        lpFindFileData->ftLastAccessTime.dwHighDateTime = HIWORD(access);
-        lpFindFileData->ftLastAccessTime.dwLowDateTime  = LOWORD(access);
-        lpFindFileData->nFileSizeHigh = HIWORD(lpafp->nSize);
-        lpFindFileData->nFileSizeLow = LOWORD(lpafp->nSize);
+        lpFindFileData->nFileSizeHigh = 0; /* We do not handle files bigger than 0xFFFFFFFF bytes yet :-) */
+        lpFindFileData->nFileSizeLow = lpafp->nSize;
 
 	if (lpafp->bIsDirectory)
 	    lpFindFileData->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
@@ -2661,7 +2694,11 @@
 	    sscanf(pszToken, "%d-%d-%d",
 		   &curFileProp->tmLastModified.tm_mon,
 		   &curFileProp->tmLastModified.tm_mday,
-		   &curFileProp->tmLastModified.tm_year); /* Do we check for Y2K problems ? */
+		   &curFileProp->tmLastModified.tm_year);
+
+	    /* Hacky and bad Y2K protection :-) */
+	    if (curFileProp->tmLastModified.tm_year < 70)
+		curFileProp->tmLastModified.tm_year += 100;
 	    
 	    pszToken = strtok(NULL, " \t");
 	    if (pszToken == NULL) {
@@ -2678,7 +2715,8 @@
 
 	    TRACE("Mod time: %2d:%2d:%2d  %2d/%2d/%2d\n",
 		  curFileProp->tmLastModified.tm_hour, curFileProp->tmLastModified.tm_min, curFileProp->tmLastModified.tm_sec,
-		  curFileProp->tmLastModified.tm_year, curFileProp->tmLastModified.tm_mon, curFileProp->tmLastModified.tm_mday);
+		  (curFileProp->tmLastModified.tm_year >= 100) ? curFileProp->tmLastModified.tm_year - 100 : curFileProp->tmLastModified.tm_year,
+		  curFileProp->tmLastModified.tm_mon, curFileProp->tmLastModified.tm_mday);
 	    
 	    pszToken = strtok(NULL, " \t");
 	    if (pszToken == NULL) {
--- dlls/wininet/internet.h_sent	Sat Jul 19 17:59:32 2003
+++ dlls/wininet/internet.h	Sat Jul 19 22:30:45 2003
@@ -117,22 +117,24 @@
 typedef struct
 {
     WININETHANDLEHEADER hdr;
+    BOOL session_deleted;
+    int nDataSocket;
+} WININETFILE, *LPWININETFILE;
+
+
+typedef struct
+{
+    WININETHANDLEHEADER hdr;
     int sndSocket;
     int lstnSocket;
     int pasvSocket; /* data socket connected by us in case of passive FTP */
+    LPWININETFILE download_in_progress;
     struct sockaddr_in socketAddress;
     struct sockaddr_in lstnSocketAddress;
     struct hostent *phostent;
     LPSTR  lpszPassword;
     LPSTR  lpszUserName;
 } WININETFTPSESSIONA, *LPWININETFTPSESSIONA;
-
-
-typedef struct
-{
-    WININETHANDLEHEADER hdr;
-    int nDataSocket;
-} WININETFILE, *LPWININETFILE;
 
 
 typedef struct


More information about the wine-patches mailing list