Ignore:
Timestamp:
Dec 28, 2000, 12:06:39 AM (25 years ago)
Author:
sandervl
Message:

JH: Resync with latest Wine + fixes/additions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wininet/ftp.c

    r3898 r4842  
    1 /* $Id: ftp.c,v 1.2 2000-07-29 14:10:08 bird Exp $
     1/* $Id: ftp.c,v 1.3 2000-12-27 23:06:17 sandervl Exp $
    22 *
    33 * WININET - Ftp implementation
     
    3131#include "internet.h"
    3232
     33#define ERROR_INTERNET_TIMEOUT ERROR_INTERNET_TIME
     34
    3335DEFAULT_DEBUG_CHANNEL(wininet)
    3436
    35 #define NOACCOUNT               "noaccount"
    36 #define MAX_REPLY_LEN           0x5B4
    37 #define DATA_PACKET_SIZE        0x2000
    38 #define szCRLF                  "\r\n"
    39 #define MAX_BACKLOG             5
     37#define NOACCOUNT               "noaccount"
     38#define DATA_PACKET_SIZE        0x2000
     39#define szCRLF                  "\r\n"
     40#define MAX_BACKLOG             5
    4041
    4142typedef enum {
     
    8687static const char szMonths[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
    8788
    88 BOOL FTP_SendCommand(int nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam);
     89BOOL FTP_SendCommand(int nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam,
     90        INTERNET_STATUS_CALLBACK lpfnStatusCB, HINTERNET hHandle, DWORD dwContext);
    8991BOOL FTP_SendStore(LPWININETFTPSESSIONA lpwfs, LPCSTR lpszRemoteFile, DWORD dwType);
    9092BOOL FTP_InitDataSocket(LPWININETFTPSESSIONA lpwfs, LPINT nDataSocket);
    9193BOOL FTP_SendData(LPWININETFTPSESSIONA lpwfs, int nDataSocket, HANDLE hFile);
    92 int FTP_ReceiveResponse(int nSocket, LPSTR lpszResponse, DWORD dwResponse);
    93 DWORD FTP_SendRetrieve(LPWININETFTPSESSIONA lpwfs, LPCSTR lpszRemoteFile, DWORD dwType);
     94int FTP_ReceiveResponse(int nSocket, LPSTR lpszResponse, DWORD dwResponse,
     95     INTERNET_STATUS_CALLBACK lpfnStatusCB, HINTERNET hHandle, DWORD dwContext);
     96DWORD FTP_SendRetrieve(LPWININETFTPSESSIONA lpwfs, LPCSTR lpszRemoteFile, DWORD dwType, LONG *lBytesAvailable);
    9497BOOL FTP_RetrieveFileData(LPWININETFTPSESSIONA lpwfs, int nDataSocket, DWORD nBytes, HANDLE hFile);
    9598BOOL FTP_InitListenSocket(LPWININETFTPSESSIONA lpwfs);
     
    101104BOOL FTP_ParsePermission(LPCSTR lpszPermission, LPFILEPROPERTIESA lpfp);
    102105BOOL FTP_ParseDirectory(LPWININETFTPSESSIONA lpwfs, int nSocket, LPFILEPROPERTIESA *lpafp, LPDWORD dwfp);
    103 HINTERNET FTP_ReceiveFileList(LPWININETFTPSESSIONA lpwfs, int nSocket, LPWIN32_FIND_DATAA lpFindFileData);
    104 LPSTR FTP_GetNextLine(int nSocket, LPSTR lpszBuffer, DWORD dwBuffer);
     106HINTERNET FTP_ReceiveFileList(LPWININETFTPSESSIONA lpwfs, int nSocket,
     107                 LPWIN32_FIND_DATAA lpFindFileData, DWORD dwContext);
     108/*LPSTR FTP_GetNextLine(int nSocket, LPSTR lpszBuffer, DWORD dwBuffer);*/
     109DWORD FTP_SetResponseError(DWORD dwResponse);
    105110
    106111/***********************************************************************
     
    117122    LPCSTR lpszNewRemoteFile, DWORD dwFlags, DWORD dwContext)
    118123{
    119         HANDLE hFile = (HANDLE)NULL;
    120         BOOL bSuccess = FALSE;
    121         DWORD nRC = ERROR_SUCCESS;
    122         LPWININETAPPINFOA hIC = NULL;
    123         LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
    124 
    125         TRACE(" lpszLocalFile(%s) lpszNewRemoteFile(%s)\n", lpszLocalFile, lpszNewRemoteFile);
    126         if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
    127         {
    128             SetLastError(ERROR_INVALID_HANDLE);
    129             nRC = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
    130             goto lend;
    131         }
    132 
    133         /* Open file to be uploaded */
    134         if (NULL == (hFile = CreateFileA(lpszLocalFile, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0)))
    135         {
    136             SetLastError(ERROR_FILE_NOT_FOUND);
    137             nRC = ERROR_FILE_NOT_FOUND;
    138             goto lend;
    139         }
    140 
    141         hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
    142         if (hIC->lpfnStatusCB)
    143                 hIC->lpfnStatusCB(hConnect, lpwfs->hdr.dwContext, INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
    144 
    145         if (FTP_SendStore(lpwfs, lpszNewRemoteFile, dwFlags))
    146         {
    147                 int nDataSocket;
    148 
    149                 /* Accept connection from ftp server */
    150                 if (FTP_InitDataSocket(lpwfs, &nDataSocket))
    151                 {
    152                         FTP_SendData(lpwfs, nDataSocket, hFile);
    153                         bSuccess = TRUE;
    154                         close(nDataSocket);
    155                 }
    156         }
     124        LPWININETAPPINFOA hIC = NULL;
     125        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
     126
     127        TRACE(" lpszLocalFile(%s) lpszNewRemoteFile(%s)\n", lpszLocalFile, lpszNewRemoteFile);
     128        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     129        {
     130            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     131            return FALSE;
     132        }
     133
     134        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     135        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     136        {
     137          WORKREQUEST workRequest;
     138
     139          workRequest.asyncall = FTPPUTFILEA;
     140          workRequest.HFTPSESSION = (DWORD)hConnect;
     141          workRequest.LPSZLOCALFILE = (DWORD)strdup(lpszLocalFile);
     142          workRequest.LPSZNEWREMOTEFILE = (DWORD)strdup(lpszNewRemoteFile);
     143          workRequest.DWFLAGS = dwFlags;
     144          workRequest.DWCONTEXT = dwContext;
     145
     146          return INTERNET_AsyncCall(&workRequest);
     147        }
     148        else
     149        {
     150          return FTP_FtpPutFileA(hConnect, lpszLocalFile,
     151                        lpszNewRemoteFile, dwFlags, dwContext);
     152        }
     153}
     154
     155/***********************************************************************
     156 *           FTP_FtpPutFileA (Internal)
     157 *
     158 * Uploads a file to the FTP server
     159 *
     160 * RETURNS
     161 *   TRUE on success
     162 *   FALSE on failure
     163 *
     164 */
     165BOOL FTP_FtpPutFileA(HINTERNET hConnect, LPCSTR lpszLocalFile,
     166                  LPCSTR lpszNewRemoteFile, DWORD dwFlags, DWORD dwContext)
     167{
     168        HANDLE hFile = (HANDLE)NULL;
     169        BOOL bSuccess = FALSE;
     170        LPWININETAPPINFOA hIC = NULL;
     171        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
     172        INT nResCode;
     173
     174        TRACE(" lpszLocalFile(%s) lpszNewRemoteFile(%s)\n", lpszLocalFile, lpszNewRemoteFile);
     175        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     176        {
     177            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     178            return FALSE;
     179        }
     180
     181        /* Clear any error information */
     182        INTERNET_SetLastError(0);
     183
     184        /* Open file to be uploaded */
     185        if (INVALID_HANDLE_VALUE == (hFile = CreateFileA(lpszLocalFile, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0)))
     186        {
     187            INTERNET_SetLastError(ERROR_FILE_NOT_FOUND);
     188            goto lend;
     189        }
     190
     191        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     192        if (hIC->lpfnStatusCB)
     193                hIC->lpfnStatusCB(hConnect, lpwfs->hdr.dwContext, INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
     194
     195        if (FTP_SendStore(lpwfs, lpszNewRemoteFile, dwFlags))
     196        {
     197                int nDataSocket;
     198
     199                /* Accept connection from ftp server */
     200                if (FTP_InitDataSocket(lpwfs, &nDataSocket))
     201                {
     202                        FTP_SendData(lpwfs, nDataSocket, hFile);
     203                        close(nDataSocket);
     204                        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     205                                        MAX_REPLY_LEN, 0, 0, 0);
     206
     207                        if(nResCode)
     208                        {
     209                          if(nResCode == 226)
     210                            bSuccess = TRUE;
     211                          else
     212                            FTP_SetResponseError(nResCode);
     213                        }
     214                }
     215        }
    157216
    158217lend:
    159         if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC  && hIC->lpfnStatusCB)
    160         {
    161                 INTERNET_ASYNC_RESULT iar;
    162 
    163                 iar.dwResult = (DWORD)bSuccess;
    164                 iar.dwError = nRC;
    165                 hIC->lpfnStatusCB(hConnect, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
    166                         &iar, sizeof(INTERNET_ASYNC_RESULT));
    167         }
    168 
    169         if (hFile)
    170             CloseHandle(hFile);
    171 
    172         return bSuccess;
    173 }
    174 
     218        if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC  && hIC->lpfnStatusCB)
     219        {
     220                INTERNET_ASYNC_RESULT iar;
     221
     222                iar.dwResult = (DWORD)bSuccess;
     223                iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
     224                hIC->lpfnStatusCB(hConnect, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     225                        &iar, sizeof(INTERNET_ASYNC_RESULT));
     226        }
     227
     228        if (hFile)
     229            CloseHandle(hFile);
     230
     231        return bSuccess;
     232}
    175233
    176234/***********************************************************************
     
    186244BOOLAPI FtpSetCurrentDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory)
    187245{
    188         int nResCode;
    189         LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
    190         LPWININETAPPINFOA hIC = NULL;
    191         DWORD nRC = ERROR_SUCCESS;
    192         DWORD bSuccess = FALSE;
    193 
    194         TRACE("lpszDirectory(%s)\n", lpszDirectory);
    195 
    196         if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
    197         {
    198             SetLastError(ERROR_INVALID_HANDLE);
    199             nRC = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
    200             return FALSE;
    201         }
    202 
    203         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_CWD, lpszDirectory))
    204                 goto lend;
    205 
    206         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    207         if (nResCode)
    208         {
    209                 if (nResCode == 250)
    210                         bSuccess = TRUE;
    211                 else
    212                     ERR("Unable to set directory %s\n", lpszDirectory);
    213         }
    214 
    215 lend:
    216         hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
    217         if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
    218         {
    219                 INTERNET_ASYNC_RESULT iar;
    220 
    221                 iar.dwResult = (DWORD)bSuccess;
    222                 iar.dwError = nRC;
    223                 hIC->lpfnStatusCB(hConnect, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
    224                         &iar, sizeof(INTERNET_ASYNC_RESULT));
    225         }
    226         return bSuccess;
    227 }
    228 
    229 
    230 /***********************************************************************
    231  *           FtpCreateDirectoryA (WININET.31)
    232  *
    233  * Create new directory on the FTP server
     246        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
     247        LPWININETAPPINFOA hIC = NULL;
     248
     249        TRACE("lpszDirectory(%s)\n", lpszDirectory);
     250
     251        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     252        {
     253            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     254            return FALSE;
     255        }
     256
     257        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     258        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     259        {
     260          WORKREQUEST workRequest;
     261
     262          workRequest.asyncall = FTPSETCURRENTDIRECTORYA;
     263          workRequest.HFTPSESSION = (DWORD)hConnect;
     264          workRequest.LPSZDIRECTORY = (DWORD)strdup(lpszDirectory);
     265
     266          return INTERNET_AsyncCall(&workRequest);
     267        }
     268        else
     269        {
     270          return FTP_FtpSetCurrentDirectoryA(hConnect, lpszDirectory);
     271        }
     272}
     273
     274/***********************************************************************
     275 *           FTP_FtpSetCurrentDirectoryA (Internal)
     276 *
     277 * Change the working directory on the FTP server
    234278 *
    235279 * RETURNS
     
    238282 *
    239283 */
     284BOOL FTP_FtpSetCurrentDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory)
     285{
     286        int nResCode;
     287        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
     288        LPWININETAPPINFOA hIC = NULL;
     289        DWORD bSuccess = FALSE;
     290
     291        TRACE("lpszDirectory(%s)\n", lpszDirectory);
     292
     293        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     294        {
     295            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     296            return FALSE;
     297        }
     298
     299        /* Clear any error information */
     300        INTERNET_SetLastError(0);
     301
     302        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     303        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_CWD, lpszDirectory,
     304                             hIC->lpfnStatusCB, hConnect, lpwfs->hdr.dwContext))
     305                goto lend;
     306
     307        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     308                                       MAX_REPLY_LEN, hIC->lpfnStatusCB, hConnect, lpwfs->hdr.dwContext);
     309        if (nResCode)
     310        {
     311                if (nResCode == 250)
     312                        bSuccess = TRUE;
     313                else
     314                    FTP_SetResponseError(nResCode);
     315        }
     316
     317lend:
     318        if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     319        {
     320                INTERNET_ASYNC_RESULT iar;
     321
     322                iar.dwResult = (DWORD)bSuccess;
     323                iar.dwError = bSuccess ? ERROR_SUCCESS : ERROR_INTERNET_EXTENDED_ERROR;
     324                hIC->lpfnStatusCB(hConnect, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     325                        &iar, sizeof(INTERNET_ASYNC_RESULT));
     326        }
     327        return bSuccess;
     328}
     329
     330
     331/***********************************************************************
     332 *           FtpCreateDirectoryA (WININET.31)
     333 *
     334 * Create new directory on the FTP server
     335 *
     336 * RETURNS
     337 *    TRUE on success
     338 *    FALSE on failure
     339 *
     340 */
    240341BOOLAPI FtpCreateDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory)
    241342{
    242         int nResCode;
    243         BOOL bSuccess = FALSE;
    244         LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
    245 
    246         TRACE("\n");
    247         if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
    248         {
    249             SetLastError(ERROR_INVALID_HANDLE);
    250             return FALSE;
    251         }
    252 
    253         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_MKD, lpszDirectory))
    254             goto lend;
    255 
    256         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    257         if (nResCode)
    258         {
    259                 if (nResCode == 257)
    260                         bSuccess = TRUE;
    261                 else
    262                     ERR("Unable to create directory: %s\n", lpszDirectory);
    263         }
     343        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
     344        LPWININETAPPINFOA hIC = NULL;
     345
     346        TRACE("\n");
     347        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     348        {
     349            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     350            return FALSE;
     351        }
     352
     353        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     354        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     355        {
     356          WORKREQUEST workRequest;
     357
     358          workRequest.asyncall = FTPCREATEDIRECTORYA;
     359          workRequest.HFTPSESSION = (DWORD)hConnect;
     360          workRequest.LPSZDIRECTORY = (DWORD)strdup(lpszDirectory);
     361
     362          return INTERNET_AsyncCall(&workRequest);
     363        }
     364        else
     365        {
     366          return FTP_FtpCreateDirectoryA(hConnect, lpszDirectory);
     367        }
     368}
     369
     370/***********************************************************************
     371 *           FTP_FtpCreateDirectoryA (Internal)
     372 *
     373 * Create new directory on the FTP server
     374 *
     375 * RETURNS
     376 *    TRUE on success
     377 *    FALSE on failure
     378 *
     379 */
     380BOOL FTP_FtpCreateDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory)
     381{
     382        int nResCode;
     383        BOOL bSuccess = FALSE;
     384        LPWININETAPPINFOA hIC = NULL;
     385        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
     386
     387        TRACE("\n");
     388        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     389        {
     390            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     391            return FALSE;
     392        }
     393
     394        /* Clear any error information */
     395        INTERNET_SetLastError(0);
     396
     397        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_MKD, lpszDirectory, 0, 0, 0))
     398            goto lend;
     399
     400        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     401                                       MAX_REPLY_LEN, 0, 0, 0);
     402        if (nResCode)
     403        {
     404                if (nResCode == 257)
     405                        bSuccess = TRUE;
     406                else
     407                    FTP_SetResponseError(nResCode);
     408        }
    264409lend:
    265         return bSuccess;
     410        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     411        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     412        {
     413                INTERNET_ASYNC_RESULT iar;
     414
     415                iar.dwResult = (DWORD)bSuccess;
     416                iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
     417                hIC->lpfnStatusCB(hConnect, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     418                        &iar, sizeof(INTERNET_ASYNC_RESULT));
     419        }
     420
     421        return bSuccess;
    266422}
    267423
     
    280436    LPCSTR lpszSearchFile, LPWIN32_FIND_DATAA lpFindFileData, DWORD dwFlags, DWORD dwContext)
    281437{
    282         int nResCode;
    283         LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
    284         LPWININETFINDNEXTA hFindNext = NULL;
    285 
    286         TRACE("\n");
    287 
    288         if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
    289         {
    290             SetLastError(ERROR_INVALID_HANDLE);
    291             return FALSE;
    292         }
    293 
    294         if (!FTP_InitListenSocket(lpwfs))
    295             goto lend;
    296 
    297         if (!FTP_SendType(lpwfs, INTERNET_FLAG_TRANSFER_ASCII))
    298             goto lend;
    299 
    300         if (!FTP_SendPort(lpwfs))
    301             goto lend;
    302 
    303         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, lpszSearchFile))
    304             goto lend;
    305 
    306         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    307         if (nResCode)
    308         {
    309             if (nResCode == 125 || nResCode == 150)
    310             {
    311                 int nDataSocket;
    312 
    313                 if (FTP_InitDataSocket(lpwfs, &nDataSocket))
    314                 {
    315                         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    316                         if (nResCode == 226)
    317                                 SetLastError(ERROR_NO_MORE_FILES);
    318                         else
    319                                 hFindNext = FTP_ReceiveFileList(lpwfs, nDataSocket, lpFindFileData);
    320                         close(nDataSocket);
    321                 }
    322             }
    323             else if (nResCode == 226)
    324             {
    325                 /* Closing data connection, requested file action successful */
    326             }
    327             else
    328             {
    329                 TRACE("Unable to retrieve directory listing\n");
    330             }
    331         }
     438        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
     439        LPWININETAPPINFOA hIC = NULL;
     440
     441        TRACE("\n");
     442
     443        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     444        {
     445            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     446            return FALSE;
     447        }
     448
     449        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     450        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     451        {
     452          WORKREQUEST workRequest;
     453
     454          workRequest.asyncall = FTPFINDFIRSTFILEA;
     455          workRequest.HFTPSESSION = (DWORD)hConnect;
     456          workRequest.LPSZSEARCHFILE = (DWORD)strdup(lpszSearchFile);
     457          workRequest.LPFINDFILEDATA = (DWORD)lpFindFileData;
     458          workRequest.DWFLAGS = dwFlags;
     459          workRequest.DWCONTEXT = dwContext;
     460
     461          INTERNET_AsyncCall(&workRequest);
     462          return NULL;
     463        }
     464        else
     465        {
     466          return FTP_FtpFindFirstFileA(hConnect, lpszSearchFile, lpFindFileData,
     467                dwFlags, dwContext);
     468        }
     469}
     470
     471/***********************************************************************
     472 *           FTP_FtpFindFirstFileA (Internal)
     473 *
     474 * Search the specified directory
     475 *
     476 * RETURNS
     477 *    HINTERNET on success
     478 *    NULL on failure
     479 *
     480 */
     481HINTERNET FTP_FtpFindFirstFileA(HINTERNET hConnect,
     482    LPCSTR lpszSearchFile, LPWIN32_FIND_DATAA lpFindFileData, DWORD dwFlags, DWORD dwContext)
     483{
     484        int nResCode;
     485        LPWININETAPPINFOA hIC = NULL;
     486        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hConnect;
     487        LPWININETFINDNEXTA hFindNext = NULL;
     488
     489        TRACE("\n");
     490
     491        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     492        {
     493            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     494            return FALSE;
     495        }
     496
     497        /* Clear any error information */
     498        INTERNET_SetLastError(0);
     499
     500        if (!FTP_InitListenSocket(lpwfs))
     501            goto lend;
     502
     503        if (!FTP_SendType(lpwfs, INTERNET_FLAG_TRANSFER_ASCII))
     504            goto lend;
     505
     506        if (!FTP_SendPort(lpwfs))
     507            goto lend;
     508
     509        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     510        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, lpszSearchFile,
     511                             hIC->lpfnStatusCB, hConnect, lpwfs->hdr.dwContext))
     512            goto lend;
     513
     514        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     515                       MAX_REPLY_LEN, hIC->lpfnStatusCB, hConnect, lpwfs->hdr.dwContext);
     516        if (nResCode)
     517        {
     518            if (nResCode == 125 || nResCode == 150)
     519            {
     520                int nDataSocket;
     521
     522                if (FTP_InitDataSocket(lpwfs, &nDataSocket))
     523                {
     524                        hFindNext = FTP_ReceiveFileList(lpwfs, nDataSocket, lpFindFileData, dwContext);
     525
     526                        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     527                                       MAX_REPLY_LEN, hIC->lpfnStatusCB, hConnect, lpwfs->hdr.dwContext);
     528                        if (nResCode != 226 && nResCode != 250)
     529                                INTERNET_SetLastError(ERROR_NO_MORE_FILES);
     530
     531                        close(nDataSocket);
     532                }
     533            }
     534            else
     535              FTP_SetResponseError(nResCode);
     536        }
    332537
    333538lend:
    334         if (lpwfs->lstnSocket != INVALID_SOCKET)
    335             close(lpwfs->lstnSocket);
    336 
    337         return (HINTERNET)hFindNext;
     539        if (lpwfs->lstnSocket != INVALID_SOCKET)
     540            close(lpwfs->lstnSocket);
     541
     542        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     543        {
     544                INTERNET_ASYNC_RESULT iar;
     545
     546                if(hFindNext)
     547                {
     548                  iar.dwResult = (DWORD)hFindNext;
     549                  iar.dwError = ERROR_SUCCESS;
     550                  hIC->lpfnStatusCB(hConnect, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
     551                        &iar, sizeof(INTERNET_ASYNC_RESULT));
     552                }
     553
     554                iar.dwResult = (DWORD)hFindNext;
     555                iar.dwError = hFindNext ? ERROR_SUCCESS : INTERNET_GetLastError();
     556                hIC->lpfnStatusCB(hConnect, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     557                        &iar, sizeof(INTERNET_ASYNC_RESULT));
     558        }
     559
     560        return (HINTERNET)hFindNext;
    338561}
    339562
     
    350573 */
    351574BOOLAPI FtpGetCurrentDirectoryA(HINTERNET hFtpSession, LPSTR lpszCurrentDirectory,
    352         LPDWORD lpdwCurrentDirectory)
    353 {
    354         int nResCode;
    355         LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
    356         LPWININETAPPINFOA hIC = NULL;
    357         DWORD bSuccess = FALSE;
    358 
    359         TRACE("\n");
    360 
    361         if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
    362         {
    363             SetLastError(ERROR_INVALID_HANDLE);
    364             return FALSE;
    365         }
    366 
    367         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PWD, NULL))
    368                 goto lend;
    369 
    370         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    371         if (nResCode)
    372         {
    373                 if (nResCode == 257) /* Extract directory name */
    374                 {
    375                         int firstpos, lastpos, len;
    376 
    377                         for (firstpos = 0, lastpos = 0; lpwfs->lpszResponseBuffer[lastpos]; lastpos++)
    378                         {
    379                                 if ('"' == lpwfs->lpszResponseBuffer[lastpos])
    380                                 {
    381                                         if (!firstpos)
    382                                                 firstpos = lastpos;
    383                                         else
    384                                                 break;
    385                                 }
    386                         }
    387 
    388                         len = lastpos - firstpos + 1;
    389                         strncpy(lpszCurrentDirectory, &lpwfs->lpszResponseBuffer[firstpos],
    390                                 len < *lpdwCurrentDirectory ? len : *lpdwCurrentDirectory);
    391                         lpszCurrentDirectory[len] = '\0';
    392                         *lpdwCurrentDirectory = len;
    393                         bSuccess = TRUE;
    394                 }
    395                 else
    396                         ERR("Unable to get current directory\n");
    397         }
     575        LPDWORD lpdwCurrentDirectory)
     576{
     577        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     578        LPWININETAPPINFOA hIC = NULL;
     579
     580        TRACE("\n");
     581
     582        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     583        {
     584            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     585            return FALSE;
     586        }
     587
     588        hIC = (LPWININETAPPINFOA)lpwfs->hdr.lpwhparent;
     589        if( hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     590        {
     591          WORKREQUEST workRequest;
     592
     593          workRequest.asyncall = FTPGETCURRENTDIRECTORYA;
     594          workRequest.HFTPSESSION = (DWORD)hFtpSession;
     595          workRequest.LPSZDIRECTORY = (DWORD)lpszCurrentDirectory;
     596          workRequest.LPDWDIRECTORY = (DWORD)lpdwCurrentDirectory;
     597
     598          return INTERNET_AsyncCall(&workRequest);
     599        }
     600        else
     601        {
     602          return FTP_FtpGetCurrentDirectoryA(hFtpSession, lpszCurrentDirectory,
     603                        lpdwCurrentDirectory);
     604        }
     605}
     606
     607/***********************************************************************
     608 *           FTP_FtpGetCurrentDirectoryA (Internal)
     609 *
     610 * Retrieves the current directory
     611 *
     612 * RETURNS
     613 *    TRUE on success
     614 *    FALSE on failure
     615 *
     616 */
     617BOOL FTP_FtpGetCurrentDirectoryA(HINTERNET hFtpSession, LPSTR lpszCurrentDirectory,
     618        LPDWORD lpdwCurrentDirectory)
     619{
     620        int nResCode;
     621        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     622        LPWININETAPPINFOA hIC = NULL;
     623        DWORD bSuccess = FALSE;
     624
     625        TRACE("\n");
     626
     627        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     628        {
     629            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     630            return FALSE;
     631        }
     632
     633        /* Clear any error information */
     634        INTERNET_SetLastError(0);
     635
     636        memset(lpszCurrentDirectory, 0, *lpdwCurrentDirectory);
     637
     638        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     639        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PWD, NULL,
     640                    hIC->lpfnStatusCB, hFtpSession, lpwfs->hdr.dwContext))
     641                goto lend;
     642
     643        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     644                      MAX_REPLY_LEN, hIC->lpfnStatusCB, hFtpSession, lpwfs->hdr.dwContext);
     645        if (nResCode)
     646        {
     647                if (nResCode == 257)              /* Extract directory name*/
     648                {
     649                        int firstpos, lastpos, len;
     650                        LPSTR lpszResponseBuffer = INTERNET_GetResponseBuffer();
     651
     652                        for (firstpos = 0, lastpos = 0; lpszResponseBuffer[lastpos]; lastpos++)
     653                        {
     654                                if ('"' == lpszResponseBuffer[lastpos])
     655                                {
     656                                        if (!firstpos)
     657                                                firstpos = lastpos;
     658                                        else
     659                                                break;
     660                                }
     661                        }
     662
     663                        len = lastpos - firstpos + 1;
     664                        strncpy(lpszCurrentDirectory, &lpszResponseBuffer[firstpos+1],
     665                                len < *lpdwCurrentDirectory ? len : *lpdwCurrentDirectory);
     666                        *lpdwCurrentDirectory = len;
     667                        bSuccess = TRUE;
     668                }
     669                else
     670                        FTP_SetResponseError(nResCode);
     671        }
    398672
    399673lend:
    400         hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
    401         if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
    402         {
    403                 INTERNET_ASYNC_RESULT iar;
    404 
    405                 iar.dwResult = (DWORD)bSuccess;
    406                 iar.dwError = bSuccess ? ERROR_SUCCESS : ERROR_SUCCESS;
    407                 hIC->lpfnStatusCB(hFtpSession, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
    408                         &iar, sizeof(INTERNET_ASYNC_RESULT));
    409 
    410         }
    411 
    412         return (DWORD) bSuccess;
     674        if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     675        {
     676                INTERNET_ASYNC_RESULT iar;
     677
     678                iar.dwResult = (DWORD)bSuccess;
     679                iar.dwError = bSuccess ? ERROR_SUCCESS : ERROR_SUCCESS;
     680                hIC->lpfnStatusCB(hFtpSession, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     681                        &iar, sizeof(INTERNET_ASYNC_RESULT));
     682
     683        }
     684
     685        return (DWORD) bSuccess;
    413686}
    414687
     
    425698 */
    426699INTERNETAPI HINTERNET WINAPI FtpOpenFileA(HINTERNET hFtpSession,
    427         LPCSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
    428         DWORD dwContext)
    429 {
    430         int nDataSocket;
    431         DWORD nSuccess = 0;
    432         LPWININETFILE hFile = NULL;
    433         LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
    434 
    435         TRACE("\n");
    436         if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
    437         {
    438             SetLastError(ERROR_INVALID_HANDLE);
    439             return FALSE;
    440         }
    441 
    442         if (GENERIC_READ == fdwAccess)
    443         {
    444                 /* Set up socket to retrieve data */
    445                 nSuccess = FTP_SendRetrieve(lpwfs, lpszFileName, dwFlags);
    446         }
    447         else if (GENERIC_WRITE == fdwAccess)
    448         {
    449                 /* Set up socket to send data */
    450                 nSuccess = FTP_SendStore(lpwfs, lpszFileName, dwFlags);
    451         }
    452 
    453         /* Accept connection from server */
    454         if (nSuccess && FTP_InitDataSocket(lpwfs, &nDataSocket))
    455         {
    456                 hFile = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFILE));
    457                 hFile->hdr.htype = WH_HFILE;
    458                 hFile->hdr.dwFlags = dwFlags;
    459                 hFile->hdr.dwContext = dwContext;
    460                 hFile->hdr.lpwhparent = hFtpSession;
    461                 hFile->nDataSocket = nDataSocket;
    462         }
    463 
    464         return (HINTERNET)hFile;
    465 }
    466 
     700        LPCSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
     701        DWORD dwContext)
     702{
     703        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     704        LPWININETAPPINFOA hIC = NULL;
     705
     706        TRACE("\n");
     707        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     708        {
     709            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     710            return FALSE;
     711        }
     712
     713        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     714
     715        if( hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     716        {
     717          WORKREQUEST workRequest;
     718
     719          workRequest.asyncall = FTPOPENFILEA;
     720          workRequest.HFTPSESSION = (DWORD)hFtpSession;
     721          workRequest.LPSZFILENAME = (DWORD)strdup(lpszFileName);
     722          workRequest.FDWACCESS = fdwAccess;
     723          workRequest.DWFLAGS = dwFlags;
     724          workRequest.DWCONTEXT = dwContext;
     725
     726          INTERNET_AsyncCall(&workRequest);
     727          return NULL;
     728        }
     729        else
     730        {
     731          return FTP_FtpOpenFileA(hFtpSession, lpszFileName, fdwAccess, dwFlags, dwContext);
     732        }
     733}
     734
     735/***********************************************************************
     736 *           FTP_FtpOpenFileA (Internal)
     737 *
     738 * Open a remote file for writing or reading
     739 *
     740 * RETURNS
     741 *    HINTERNET handle on success
     742 *    NULL on failure
     743 *
     744 */
     745HINTERNET FTP_FtpOpenFileA(HINTERNET hFtpSession,
     746        LPCSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
     747        DWORD dwContext)
     748{
     749        int nDataSocket;
     750        LONG lBytesAvailable = 0;
     751        BOOL bSuccess = 0;
     752        LPWININETFILE hFile = NULL;
     753        LPWININETAPPINFOA hIC = NULL;
     754        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     755
     756        TRACE("\n");
     757        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     758        {
     759            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     760            return FALSE;
     761        }
     762
     763        /* Clear any error information */
     764        INTERNET_SetLastError(0);
     765
     766        if (GENERIC_READ == fdwAccess)
     767        {
     768                /* Set up socket to retrieve data */
     769                bSuccess = FTP_SendRetrieve(lpwfs, lpszFileName, dwFlags, &lBytesAvailable);
     770        }
     771        else if (GENERIC_WRITE == fdwAccess)
     772        {
     773                /* Set up socket to send data */
     774                bSuccess = FTP_SendStore(lpwfs, lpszFileName, dwFlags);
     775        }
     776
     777        /* Accept connection from server */
     778        if (bSuccess && FTP_InitDataSocket(lpwfs, &nDataSocket))
     779        {
     780                hFile = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFILE));
     781          WriteLog("Created hFile (OPEN) at %x (%d)",hFile,lBytesAvailable);
     782                hFile->hdr.htype = WH_HFILE;
     783                hFile->hdr.dwFlags = dwFlags;
     784                hFile->hdr.dwContext = dwContext;
     785                hFile->hdr.lpwhparent = hFtpSession;
     786                hFile->nDataSocket = nDataSocket;
     787                hFile->lBytesAvailable = lBytesAvailable;
     788        }
     789
     790        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     791        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     792        {
     793          INTERNET_ASYNC_RESULT iar;
     794
     795          if(hFile)
     796          {
     797            iar.dwResult = (DWORD)hFile;
     798            iar.dwError = ERROR_SUCCESS;
     799            hIC->lpfnStatusCB(hFtpSession, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
     800                &iar, sizeof(INTERNET_ASYNC_RESULT));
     801          }
     802
     803          iar.dwResult = (DWORD)bSuccess;
     804          iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
     805          hIC->lpfnStatusCB(hFtpSession, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     806                &iar, sizeof(INTERNET_ASYNC_RESULT));
     807        }
     808
     809        return (HINTERNET)hFile;
     810}
    467811
    468812/***********************************************************************
     
    477821 */
    478822BOOLAPI FtpGetFileA(HINTERNET hInternet, LPCSTR lpszRemoteFile, LPCSTR lpszNewFile,
    479         BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
    480         DWORD dwContext)
    481 {
    482         DWORD nBytes;
    483         BOOL bSuccess = FALSE;
    484         HANDLE hFile;
    485         LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hInternet;
    486 
    487         TRACE("lpszRemoteFile(%s) lpszNewFile(%s)\n", lpszRemoteFile, lpszNewFile);
    488         if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
    489         {
    490             SetLastError(ERROR_INVALID_HANDLE);
    491             return FALSE;
    492         }
    493 
    494         /* Ensure we can write to lpszNewfile by opening it */
    495         hFile = CreateFileA(lpszNewFile, GENERIC_WRITE, 0, 0, fFailIfExists ?
    496                 CREATE_NEW : CREATE_ALWAYS, dwLocalFlagsAttribute, 0);
    497         if (INVALID_HANDLE_VALUE == hFile)
    498             return FALSE;
    499 
    500         /* Set up socket to retrieve data */
    501         nBytes = FTP_SendRetrieve(lpwfs, lpszRemoteFile, dwInternetFlags);
    502 
    503         if (nBytes > 0)
    504         {
    505                 int nDataSocket;
    506 
    507                 /* Accept connection from ftp server */
    508                 if (FTP_InitDataSocket(lpwfs, &nDataSocket))
    509                 {
    510                         int nResCode;
    511 
    512                         /* Receive data */
    513                         FTP_RetrieveFileData(lpwfs, nDataSocket, nBytes, hFile);
    514                         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    515                         if (nResCode)
    516                         {
    517                                 if (nResCode == 226)
    518                                         bSuccess = TRUE;
    519 
    520                         }
    521                         close(nDataSocket);
    522                 }
    523         }
    524 
    525         if (hFile)
    526                 CloseHandle(hFile);
    527         return bSuccess;
     823        BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
     824        DWORD dwContext)
     825{
     826        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hInternet;
     827        LPWININETAPPINFOA hIC = NULL;
     828
     829        TRACE("lpszRemoteFile(%s) lpszNewFile(%s)\n", lpszRemoteFile, lpszNewFile);
     830        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     831        {
     832            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     833            return FALSE;
     834        }
     835
     836        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     837        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     838        {
     839          WORKREQUEST workRequest;
     840
     841          workRequest.asyncall = FTPGETFILEA;
     842          workRequest.HFTPSESSION = (DWORD)hInternet;
     843          workRequest.LPSZREMOTEFILE = (DWORD)strdup(lpszRemoteFile);
     844          workRequest.LPSZNEWFILE = (DWORD)strdup(lpszNewFile);
     845          workRequest.DWLOCALFLAGSATTRIBUTE = dwLocalFlagsAttribute;
     846          workRequest.FFAILIFEXISTS = (DWORD)fFailIfExists;
     847          workRequest.DWFLAGS = dwInternetFlags;
     848          workRequest.DWCONTEXT = dwContext;
     849
     850          return INTERNET_AsyncCall(&workRequest);
     851        }
     852        else
     853        {
     854          return FTP_FtpGetFileA(hInternet, lpszRemoteFile, lpszNewFile,
     855                fFailIfExists, dwLocalFlagsAttribute, dwInternetFlags, dwContext);
     856        }
     857}
     858
     859/***********************************************************************
     860 *           FTP_FtpGetFileA (Internal)
     861 *
     862 * Retrieve file from the FTP server
     863 *
     864 * RETURNS
     865 *    TRUE on success
     866 *    FALSE on failure
     867 *
     868 */
     869BOOL FTP_FtpGetFileA(HINTERNET hInternet, LPCSTR lpszRemoteFile, LPCSTR lpszNewFile,
     870        BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
     871        DWORD dwContext)
     872{
     873        DWORD nBytes;
     874        BOOL bSuccess = FALSE;
     875        HANDLE hFile;
     876        LPWININETAPPINFOA hIC = NULL;
     877        LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hInternet;
     878
     879        TRACE("lpszRemoteFile(%s) lpszNewFile(%s)\n", lpszRemoteFile, lpszNewFile);
     880        if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     881        {
     882            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     883            return FALSE;
     884        }
     885
     886        /* Clear any error information */
     887        INTERNET_SetLastError(0);
     888
     889        /* Ensure we can write to lpszNewfile by opening it */
     890        hFile = CreateFileA(lpszNewFile, GENERIC_WRITE, 0, 0, fFailIfExists ?
     891                CREATE_NEW : CREATE_ALWAYS, dwLocalFlagsAttribute, 0);
     892        if (INVALID_HANDLE_VALUE == hFile)
     893            goto lend;
     894
     895        /* Set up socket to retrieve data */
     896        nBytes = FTP_SendRetrieve(lpwfs, lpszRemoteFile, dwInternetFlags, NULL);
     897
     898        if (nBytes > 0)
     899        {
     900                int nDataSocket;
     901
     902                /* Accept connection from ftp server */
     903                if (FTP_InitDataSocket(lpwfs, &nDataSocket))
     904                {
     905                        int nResCode;
     906
     907                        /* Receive data */
     908                        FTP_RetrieveFileData(lpwfs, nDataSocket, nBytes, hFile);
     909                        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     910                                            MAX_REPLY_LEN, 0, 0, 0);
     911                        if (nResCode)
     912                        {
     913                                if (nResCode == 226)
     914                                        bSuccess = TRUE;
     915                                else
     916                                        FTP_SetResponseError(nResCode);
     917
     918                        }
     919                        close(nDataSocket);
     920                }
     921        }
     922
     923lend:
     924        if (hFile)
     925                CloseHandle(hFile);
     926
     927        hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     928        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     929        {
     930          INTERNET_ASYNC_RESULT iar;
     931
     932          iar.dwResult = (DWORD)bSuccess;
     933          iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
     934          hIC->lpfnStatusCB(hInternet, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     935                &iar, sizeof(INTERNET_ASYNC_RESULT));
     936        }
     937
     938        return bSuccess;
     939}
     940
     941/***********************************************************************
     942 *           FTP_DeleteFileA (WININET.33)
     943 *
     944 * Delete a file on the ftp server
     945 *
     946 * RETURNS
     947 *   TRUE on success
     948 *   FALSE on failure
     949 *
     950 */
     951BOOLAPI FtpDeleteFileA(HINTERNET hFtpSession, LPCSTR lpszFileName)
     952{
     953    LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     954    LPWININETAPPINFOA hIC = NULL;
     955
     956    if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     957    {
     958        INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     959        return FALSE;
     960    }
     961
     962    hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     963    if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     964    {
     965          WORKREQUEST workRequest;
     966
     967          workRequest.asyncall = FTPDELETEFILEA;
     968          workRequest.HFTPSESSION = (DWORD)hFtpSession;
     969          workRequest.LPSZFILENAME = (DWORD)strdup(lpszFileName);
     970
     971          return INTERNET_AsyncCall(&workRequest);
     972    }
     973    else
     974    {
     975          return FTP_FtpDeleteFileA(hFtpSession, lpszFileName);
     976    }
     977}
     978
     979/***********************************************************************
     980 *           FTP_FtpDeleteFileA  (Internal)
     981 *
     982 * Delete a file on the ftp server
     983 *
     984 * RETURNS
     985 *    TRUE on success
     986 *    FALSE on failure
     987 *
     988 */
     989BOOL FTP_FtpDeleteFileA(HINTERNET hFtpSession, LPCSTR lpszFileName)
     990{
     991      INT nResCode;
     992      BOOL bSuccess = FALSE;
     993      LPWININETAPPINFOA hIC = NULL;
     994      LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     995
     996      TRACE("0x%08lx\n", (ULONG) hFtpSession);
     997      if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     998      {
     999            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     1000            return FALSE;
     1001      }
     1002
     1003                                    /* Clear any error information*/
     1004      INTERNET_SetLastError(0);
     1005
     1006      if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_DELE, lpszFileName, 0, 0, 0))
     1007          goto lend;
     1008
     1009      nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     1010            MAX_REPLY_LEN, 0, 0, 0);
     1011      if (nResCode)
     1012      {
     1013            if (nResCode == 250)
     1014                bSuccess = TRUE;
     1015            else
     1016                FTP_SetResponseError(nResCode);
     1017      }
     1018lend:
     1019      hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     1020      if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     1021      {
     1022            INTERNET_ASYNC_RESULT iar;
     1023
     1024            iar.dwResult = (DWORD)bSuccess;
     1025            iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
     1026                hIC->lpfnStatusCB(hFtpSession, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     1027                    &iar, sizeof(INTERNET_ASYNC_RESULT));
     1028      }
     1029
     1030      return bSuccess;
     1031}
     1032
     1033/***********************************************************************
     1034 *           FtpRemoveDirectoryA  (WININET.45)
     1035 *
     1036 * Remove a directory on the ftp server
     1037 *
     1038 * RETURNS
     1039 *    TRUE on success
     1040 *    FALSE on failure
     1041 *
     1042 */
     1043BOOLAPI FtpRemoveDirectoryA(HINTERNET hFtpSession, LPCSTR lpszDirectory)
     1044{
     1045     LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     1046     LPWININETAPPINFOA hIC = NULL;
     1047
     1048     if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     1049     {
     1050           INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     1051           return FALSE;
     1052     }
     1053
     1054     hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     1055     if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     1056     {
     1057              WORKREQUEST workRequest;
     1058
     1059              workRequest.asyncall = FTPREMOVEDIRECTORYA;
     1060              workRequest.HFTPSESSION = (DWORD)hFtpSession;
     1061              workRequest.LPSZDIRECTORY = (DWORD)strdup(lpszDirectory);
     1062
     1063              return INTERNET_AsyncCall(&workRequest);
     1064      }
     1065      else
     1066      {
     1067              return FTP_FtpRemoveDirectoryA(hFtpSession, lpszDirectory);
     1068      }
     1069}
     1070
     1071/************************************************************************
     1072 *           FTP_FtpRemoveDirectoryA  (Internal)
     1073 *
     1074 * Remove a directory on the ftp server
     1075 *
     1076 * RETURNS
     1077 *    TRUE on success
     1078 *    FALSE on failure
     1079 *
     1080 */
     1081BOOL FTP_FtpRemoveDirectoryA(HINTERNET hFtpSession, LPCSTR lpszDirectory)
     1082{
     1083     INT nResCode;
     1084     BOOL bSuccess = FALSE;
     1085     LPWININETAPPINFOA hIC = NULL;
     1086     LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     1087
     1088     TRACE("\n");
     1089     if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     1090     {
     1091         INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     1092         return FALSE;
     1093     }
     1094
     1095                             /* Clear any error information*/
     1096     INTERNET_SetLastError(0);
     1097
     1098     if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RMD, lpszDirectory, 0, 0, 0))
     1099         goto lend;
     1100
     1101     nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     1102         MAX_REPLY_LEN, 0, 0, 0);
     1103     if (nResCode)
     1104     {
     1105         if (nResCode == 250)
     1106             bSuccess = TRUE;
     1107         else
     1108             FTP_SetResponseError(nResCode);
     1109     }
     1110
     1111lend:
     1112     hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     1113     if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     1114     {
     1115         INTERNET_ASYNC_RESULT iar;
     1116
     1117         iar.dwResult = (DWORD)bSuccess;
     1118         iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
     1119         hIC->lpfnStatusCB(hFtpSession, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     1120             &iar, sizeof(INTERNET_ASYNC_RESULT));
     1121     }
     1122
     1123     return bSuccess;
     1124}
     1125
     1126/***********************************************************************
     1127 *           FtpRenameFileA  (WININET.47)
     1128 *
     1129 * Rename a file on the ftp server
     1130 *
     1131 * RETURNS
     1132 *    TRUE on success
     1133 *    FALSE on failure
     1134 *
     1135 */
     1136BOOL WINAPI FtpRenameFileA(HINTERNET hFtpSession, LPCSTR lpszSrc, LPCSTR lpszDest)
     1137{
     1138   LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     1139   LPWININETAPPINFOA hIC = NULL;
     1140
     1141   if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     1142   {
     1143         INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     1144         return FALSE;
     1145   }
     1146
     1147   hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     1148   if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     1149   {
     1150       WORKREQUEST workRequest;
     1151
     1152       workRequest.asyncall = FTPRENAMEFILEA;
     1153       workRequest.HFTPSESSION = (DWORD)hFtpSession;
     1154       workRequest.LPSZSRCFILE = (DWORD)strdup(lpszSrc);
     1155       workRequest.LPSZDESTFILE = (DWORD)strdup(lpszDest);
     1156
     1157       return INTERNET_AsyncCall(&workRequest);
     1158   }
     1159   else
     1160   {
     1161       return FTP_FtpRenameFileA(hFtpSession, lpszSrc, lpszDest);
     1162   }
     1163}
     1164
     1165/************************************************************************
     1166 *           FTP_FtpRenameFileA  (Internal)
     1167 *
     1168 * Rename a file on the ftp server
     1169 *
     1170 * RETURNS
     1171 *    TRUE on success
     1172 *    FALSE on failure
     1173 *
     1174 */
     1175BOOL FTP_FtpRenameFileA(HINTERNET hFtpSession, LPCSTR lpszSrc, LPCSTR lpszDest)
     1176{
     1177    INT nResCode;
     1178    BOOL bSuccess = FALSE;
     1179    LPWININETAPPINFOA hIC = NULL;
     1180    LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) hFtpSession;
     1181
     1182    TRACE("\n");
     1183    if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
     1184    {
     1185        INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     1186        return FALSE;
     1187    }
     1188
     1189                            /* Clear any error information*/
     1190    INTERNET_SetLastError(0);
     1191
     1192    if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RNFR, lpszSrc, 0, 0, 0))
     1193        goto lend;
     1194
     1195    nResCode = FTP_ReceiveResponse(lpwfs->sndSocket,
     1196        INTERNET_GetResponseBuffer(), MAX_REPLY_LEN, 0, 0, 0);
     1197    if (nResCode == 350)
     1198    {
     1199        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RNTO, lpszDest, 0, 0, 0))
     1200            goto lend;
     1201
     1202        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket,
     1203                    INTERNET_GetResponseBuffer(), MAX_REPLY_LEN, 0, 0, 0);
     1204    }
     1205
     1206    if (nResCode == 250)
     1207        bSuccess = TRUE;
     1208    else
     1209        FTP_SetResponseError(nResCode);
     1210
     1211lend:
     1212    hIC = (LPWININETAPPINFOA) lpwfs->hdr.lpwhparent;
     1213    if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     1214    {
     1215        INTERNET_ASYNC_RESULT iar;
     1216
     1217        iar.dwResult = (DWORD)bSuccess;
     1218        iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
     1219        hIC->lpfnStatusCB(hFtpSession, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     1220            &iar, sizeof(INTERNET_ASYNC_RESULT));
     1221    }
     1222
     1223    return bSuccess;
    5281224}
    5291225
     
    5411237
    5421238HINTERNET FTP_Connect(HINTERNET hInternet, LPCSTR lpszServerName,
    543         INTERNET_PORT nServerPort, LPCSTR lpszUserName,
    544         LPCSTR lpszPassword, DWORD dwFlags, DWORD dwContext)
    545 {
    546         struct sockaddr_in socketAddr;
    547         struct hostent *phe = NULL;
    548         int nsocket = INVALID_SOCKET;
    549         LPWININETAPPINFOA hIC = NULL;
    550         BOOL result, bSuccess = FALSE;
    551         LPWININETFTPSESSIONA lpwfs = NULL;
    552 
    553         TRACE(" Server(%s) Port(%d) User(%s)\n", lpszServerName, nServerPort,
    554                 lpszUserName);
    555 
    556         if (((LPWININETHANDLEHEADER)hInternet)->htype != WH_HINIT)
    557                 goto lerror;
    558 
    559         hIC = (LPWININETAPPINFOA) hInternet;
    560 
    561         if (NULL == lpszUserName && NULL != lpszPassword)
    562                 goto lerror;
    563 
    564         if (hIC->lpfnStatusCB)
    565                 hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_RESOLVING_NAME,
    566                         lpszServerName, strlen(lpszServerName));
    567 
    568         if (!GetAddress(lpszServerName, nServerPort, &phe, &socketAddr))
    569                 goto lerror;
    570 
    571         if (hIC->lpfnStatusCB)
    572                 hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_NAME_RESOLVED,
    573                         lpszServerName, strlen(lpszServerName));
    574 
    575         if (INVALID_SOCKET == (nsocket = socket(phe->h_addrtype,SOCK_STREAM,0)))
    576         {
    577                 ERR("Unable to create socket\n");
    578                 goto lerror;
    579         }
    580 
    581         result = connect(nsocket, (struct sockaddr *)&socketAddr,
    582                         sizeof(socketAddr));
    583 
    584         if (!result)
    585         {
    586                 TRACE("Connected to server\n");
    587                 lpwfs = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPSESSIONA));
    588                 if (NULL == lpwfs)
    589                 {
    590                     SetLastError(ERROR_OUTOFMEMORY);
    591                     goto lerror;
    592                 }
    593 
    594                 lpwfs->hdr.htype = WH_HFTPSESSION;
    595                 lpwfs->hdr.dwFlags = dwFlags;
    596                 lpwfs->hdr.dwContext = dwContext;
    597                 lpwfs->hdr.lpwhparent = (LPWININETHANDLEHEADER)hInternet;
    598                 lpwfs->sndSocket = nsocket;
    599                 memcpy(&lpwfs->socketAddress, &socketAddr, sizeof(socketAddr));
    600                 lpwfs->phostent = phe;
    601 
    602                 if (NULL == lpszUserName)
    603                 {
    604                     lpwfs->lpszUserName = strdup("anonymous");
    605                     lpwfs->lpszPassword = strdup("user@server");
    606                 }
    607                 else
    608                 {
    609                     lpwfs->lpszUserName = strdup(lpszUserName);
    610                     lpwfs->lpszPassword = strdup(lpszPassword);
    611                 }
    612 
    613                 lpwfs->lpszResponseBuffer = HeapAlloc(GetProcessHeap(), 0, MAX_REPLY_LEN);
    614                 if (NULL == lpwfs)
    615                 {
    616                     SetLastError(ERROR_OUTOFMEMORY);
    617                     goto lerror;
    618                 }
    619 
    620                 if (hIC->lpfnStatusCB)
    621                         hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_CONNECTING_TO_SERVER,
    622                                 &lpwfs->socketAddress, sizeof(struct sockaddr_in));
    623 
    624                 if (FTP_ConnectToHost(lpwfs))
    625                 {
    626                         if (hIC->lpfnStatusCB)
    627                         {
    628                                 INTERNET_ASYNC_RESULT iar;
    629 
    630                                 hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_CONNECTED_TO_SERVER,
    631                                         &lpwfs->socketAddress, sizeof(struct sockaddr_in));
    632 
    633                                 iar.dwResult = (DWORD)lpwfs;
    634                                 iar.dwError = ERROR_SUCCESS;
    635 
    636                                 hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_HANDLE_CREATED,
    637                                         &iar, sizeof(INTERNET_ASYNC_RESULT));
    638                         }
    639                         TRACE("Successfully logged into server\n");
    640                         bSuccess = TRUE;
    641                 }
    642         }
     1239        INTERNET_PORT nServerPort, LPCSTR lpszUserName,
     1240        LPCSTR lpszPassword, DWORD dwFlags, DWORD dwContext)
     1241{
     1242        struct sockaddr_in socketAddr;
     1243        struct hostent *phe = NULL;
     1244        int nsocket = INVALID_SOCKET, sock_namelen;
     1245        LPWININETAPPINFOA hIC = NULL;
     1246        BOOL result, bSuccess = FALSE;
     1247        LPWININETFTPSESSIONA lpwfs = NULL;
     1248
     1249        TRACE(" Server(%s) Port(%d) User(%s)\n", lpszServerName, nServerPort,
     1250                lpszUserName);
     1251
     1252        if (((LPWININETHANDLEHEADER)hInternet)->htype != WH_HINIT)
     1253                goto lerror;
     1254
     1255        hIC = (LPWININETAPPINFOA) hInternet;
     1256
     1257        if (NULL == lpszUserName && NULL != lpszPassword)
     1258        {
     1259                INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_USER_NAME);
     1260                goto lerror;
     1261        }
     1262
     1263        if(nServerPort == INTERNET_INVALID_PORT_NUMBER)
     1264           nServerPort = INTERNET_DEFAULT_FTP_PORT;
     1265
     1266        if (hIC->lpfnStatusCB)
     1267                hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_RESOLVING_NAME,
     1268                        (LPSTR)lpszServerName, strlen(lpszServerName));
     1269
     1270        if (!GetAddress(lpszServerName, nServerPort, &phe, &socketAddr))
     1271        {
     1272                INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED);
     1273                goto lerror;
     1274        }
     1275
     1276        if (hIC->lpfnStatusCB)
     1277                hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_NAME_RESOLVED,
     1278                        (LPSTR)lpszServerName, strlen(lpszServerName));
     1279
     1280        if (INVALID_SOCKET == (nsocket = socket(AF_INET, SOCK_STREAM, 0)))
     1281        {
     1282                INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT);
     1283                goto lerror;
     1284        }
     1285
     1286        if(hIC->lpfnStatusCB)
     1287                hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_CONNECTING_TO_SERVER,
     1288                        &socketAddr, sizeof(struct sockaddr_in));
     1289
     1290        if(connect(nsocket, (struct sockaddr *)&socketAddr, sizeof(socketAddr)) < 0)
     1291        {
     1292          INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT);
     1293        }
     1294        else
     1295        {
     1296                TRACE("Connected to server\n");
     1297
     1298                if(hIC->lpfnStatusCB)
     1299                   hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_CONNECTED_TO_SERVER,
     1300                       &socketAddr, sizeof(struct sockaddr_in));
     1301
     1302                lpwfs = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPSESSIONA));
     1303                if (NULL == lpwfs)
     1304                {
     1305                    INTERNET_SetLastError(ERROR_OUTOFMEMORY);
     1306                    goto lerror;
     1307                }
     1308
     1309                lpwfs->hdr.htype = WH_HFTPSESSION;
     1310                lpwfs->hdr.dwFlags = dwFlags;
     1311                lpwfs->hdr.dwContext = dwContext;
     1312                lpwfs->hdr.lpwhparent = (LPWININETHANDLEHEADER)hInternet;
     1313                lpwfs->sndSocket = nsocket;
     1314                sock_namelen = sizeof(lpwfs->socketAddress);
     1315                getsockname(nsocket,(struct sockaddr *)&lpwfs->socketAddress, &sock_namelen);
     1316                lpwfs->phostent = phe;
     1317
     1318                if (NULL == lpszUserName)
     1319                {
     1320                    lpwfs->lpszUserName = strdup("anonymous");
     1321                    lpwfs->lpszPassword = strdup("user@server");
     1322                }
     1323                else
     1324                {
     1325                    lpwfs->lpszUserName = strdup(lpszUserName);
     1326                    lpwfs->lpszPassword = strdup(lpszPassword);
     1327                }
     1328
     1329                if (FTP_ConnectToHost(lpwfs))
     1330                {
     1331                        if (hIC->lpfnStatusCB)
     1332                        {
     1333                                INTERNET_ASYNC_RESULT iar;
     1334
     1335                                iar.dwResult = (DWORD)lpwfs;
     1336                                iar.dwError = ERROR_SUCCESS;
     1337
     1338                                hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_HANDLE_CREATED,
     1339                                        &iar, sizeof(INTERNET_ASYNC_RESULT));
     1340                        }
     1341                        TRACE("Successfully logged into server\n");
     1342                        bSuccess = TRUE;
     1343                }
     1344        }
    6431345
    6441346lerror:
    645         if (!bSuccess && INVALID_SOCKET != nsocket)
    646                 close(nsocket);
    647 
    648         if (!bSuccess && lpwfs)
    649         {
    650                 HeapFree(GetProcessHeap(), 0, lpwfs);
    651                 lpwfs = NULL;
    652         }
    653 
    654         if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
    655         {
    656                 INTERNET_ASYNC_RESULT iar;
    657 
    658                 iar.dwResult = (DWORD)lpwfs;
    659                 iar.dwError = bSuccess ? ERROR_SUCCESS : ERROR_INTERNET_CANNOT_CONNECT;
    660                 hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
    661                         &iar, sizeof(INTERNET_ASYNC_RESULT));
    662 
    663         }
    664 
    665         return (HINTERNET) lpwfs;
     1347        if (!bSuccess && INVALID_SOCKET != nsocket)
     1348                close(nsocket);
     1349
     1350        if (!bSuccess && lpwfs)
     1351        {
     1352                HeapFree(GetProcessHeap(), 0, lpwfs);
     1353                lpwfs = NULL;
     1354        }
     1355
     1356        if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     1357        {
     1358                INTERNET_ASYNC_RESULT iar;
     1359
     1360                iar.dwResult = (DWORD)lpwfs;
     1361                iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
     1362                hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     1363                        &iar, sizeof(INTERNET_ASYNC_RESULT));
     1364        }
     1365
     1366        return (HINTERNET) lpwfs;
    6661367}
    6671368
     
    6791380BOOL FTP_ConnectToHost(LPWININETFTPSESSIONA lpwfs)
    6801381{
    681         int nResCode;
    682         BOOL bSuccess = FALSE;
    683 
    684         TRACE("\n");
    685         FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    686 
    687         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_USER, lpwfs->lpszUserName))
    688             goto lend;
    689 
    690         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    691         if (nResCode)
    692         {
    693                 /* Login successful... */
    694                 if (nResCode == 230)
    695                         bSuccess = TRUE;
    696                 /* User name okay, need password... */
    697                 else if (nResCode == 331)
    698                         bSuccess = FTP_SendPassword(lpwfs);
    699                 /* Need account for login... */
    700                 else if (nResCode == 332)
    701                         bSuccess = FTP_SendAccount(lpwfs);
    702         }
    703 
    704         TRACE("Returning %d\n", bSuccess);
     1382        int nResCode;
     1383        BOOL bSuccess = FALSE;
     1384
     1385        TRACE("\n");
     1386        FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(), MAX_REPLY_LEN, 0, 0, 0);
     1387
     1388        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_USER, lpwfs->lpszUserName, 0, 0, 0))
     1389            goto lend;
     1390
     1391        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     1392                                       MAX_REPLY_LEN, 0, 0, 0);
     1393        if (nResCode)
     1394        {
     1395                /* Login successful... */
     1396                if (nResCode == 230)
     1397                        bSuccess = TRUE;
     1398                /* User name okay, need password... */
     1399                else if (nResCode == 331)
     1400                        bSuccess = FTP_SendPassword(lpwfs);
     1401                /* Need account for login... */
     1402                else if (nResCode == 332)
     1403                        bSuccess = FTP_SendAccount(lpwfs);
     1404                else
     1405                  FTP_SetResponseError(nResCode);
     1406        }
     1407
     1408        TRACE("Returning %d\n", bSuccess);
    7051409lend:
    706         return bSuccess;
     1410        return bSuccess;
    7071411}
    7081412
     
    7181422 *
    7191423 */
    720 BOOL FTP_SendCommand(int nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam)
    721 {
    722         int len;
    723         char *buf;
    724         int nBytesSent = 0;
    725         int nRC        = 0;
    726         BOOL bParamHasLen;
    727 
    728         TRACE("%d: (%s)\n", ftpCmd, lpszParam);
    729 
    730         bParamHasLen = lpszParam && strlen(lpszParam) > 0;
    731         len = (bParamHasLen ? strlen(lpszParam) : -1) + strlen(szFtpCommands[ftpCmd]) +
    732             strlen(szCRLF)+ 1;
    733         if (NULL == (buf = HeapAlloc(GetProcessHeap(), 0, len+1)))
    734         {
    735             SetLastError(ERROR_OUTOFMEMORY);
    736             return FALSE;
    737         }
    738         sprintf(buf, "%s%s%s%s", szFtpCommands[ftpCmd], bParamHasLen ? " " : "",
    739                 bParamHasLen ? lpszParam : "", szCRLF);
    740 
    741         TRACE("Sending (%s)\n", buf);
    742         while((nBytesSent < len) && (nRC != SOCKET_ERROR))
    743         {
    744                 nRC = send(nSocket, buf+nBytesSent, len - nBytesSent, 0);
    745                 /* Here, we shall call the callback function to update the status. */
    746                 nBytesSent += nRC;
    747         }
    748 
    749         HeapFree(GetProcessHeap(), 0, buf);
    750         return (nRC != SOCKET_ERROR);
     1424BOOL FTP_SendCommand(int nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam,
     1425        INTERNET_STATUS_CALLBACK lpfnStatusCB, HINTERNET hHandle, DWORD dwContext)
     1426{
     1427        int len;
     1428        char *buf;
     1429        int nBytesSent = 0;
     1430        int nRC        = 0;
     1431        BOOL bParamHasLen;
     1432
     1433        TRACE("%d: (%s) %d\n", ftpCmd, lpszParam, nSocket);
     1434
     1435        if(lpfnStatusCB)
     1436          lpfnStatusCB(hHandle, dwContext, INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
     1437
     1438        bParamHasLen = lpszParam && strlen(lpszParam) > 0;
     1439        len = (bParamHasLen ? strlen(lpszParam) : -1) + strlen(szFtpCommands[ftpCmd]) +
     1440            strlen(szCRLF)+ 1;
     1441        if (NULL == (buf = HeapAlloc(GetProcessHeap(), 0, len+1)))
     1442        {
     1443            INTERNET_SetLastError(ERROR_OUTOFMEMORY);
     1444            return FALSE;
     1445        }
     1446        sprintf(buf, "%s%s%s%s", szFtpCommands[ftpCmd], bParamHasLen ? " " : "",
     1447                bParamHasLen ? lpszParam : "", szCRLF);
     1448
     1449        TRACE("Sending (%s)\n", buf);
     1450        while((nBytesSent < len) && (nRC != SOCKET_ERROR))
     1451        {
     1452                nRC = send(nSocket, buf+nBytesSent, len - nBytesSent, 0);
     1453                /* Here, we shall call the callback function to update the status. */
     1454                nBytesSent += nRC;
     1455        }
     1456
     1457        HeapFree(GetProcessHeap(), 0, buf);
     1458
     1459        if(lpfnStatusCB)
     1460          lpfnStatusCB(hHandle, dwContext, INTERNET_STATUS_REQUEST_SENT,
     1461                &nBytesSent, sizeof(DWORD));
     1462
     1463        return (nRC != SOCKET_ERROR);
    7511464}
    7521465
     
    7631476 */
    7641477
    765 int FTP_ReceiveResponse(int nSocket, LPSTR lpszResponse, DWORD dwResponse)
    766 {
    767         int nRecv = 0;
    768         char resp[4];
    769         int rc = 0;
    770 
    771         TRACE("\n");
    772         while(1)
    773         {
    774                 while (nRecv < dwResponse)
    775                 {
    776                         if (recv(nSocket, &lpszResponse[nRecv], 1, 0) < 0)
    777                             goto lerror;
    778 
    779                         if (lpszResponse[nRecv] == '\n')
    780                             break;
    781                         if (lpszResponse[nRecv] != '\r')
    782                             nRecv++;
    783                 }
    784 
    785                 if (nRecv > 3 && lpszResponse[3] != '-')
    786                     break;
    787 
    788                 nRecv = 0;
    789         }
    790 
    791         if (nRecv > 0)
    792         {
    793                 memset(lpszResponse+nRecv-1, 0, dwResponse-nRecv);
    794                 memcpy(resp, lpszResponse, 3*sizeof(char));
    795                 resp[3] = '\0';
    796                 rc = atoi(resp);
    797                 TRACE(" Reply(%d) bytes(%d) %s\n", rc, nRecv, lpszResponse);
    798         }
     1478int FTP_ReceiveResponse(int nSocket, LPSTR lpszResponse, DWORD dwResponse,
     1479        INTERNET_STATUS_CALLBACK lpfnStatusCB, HINTERNET hHandle, DWORD dwContext)
     1480{
     1481        DWORD nRecv = 0;
     1482        int rc = 0;
     1483        char firstprefix[5];
     1484        BOOL multiline = FALSE;
     1485
     1486        TRACE("\n");
     1487
     1488        if(lpfnStatusCB)
     1489          lpfnStatusCB(hHandle, dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
     1490
     1491        while(1)
     1492        {
     1493                nRecv = dwResponse;
     1494
     1495                if(!INTERNET_GetNextLine(nSocket, lpszResponse, &nRecv))
     1496                  goto lerror;
     1497
     1498                if (nRecv >= 3)
     1499                {
     1500                    if(!multiline)
     1501                    {
     1502                        if(lpszResponse[3] != '-')
     1503                                break;
     1504                        else
     1505                        {
     1506                          /* Start multiline response. Loop until we get 'nnn' */
     1507                          multiline = TRUE;
     1508                          memcpy(firstprefix, lpszResponse, 3);
     1509                          firstprefix[3] = ' ';
     1510                          firstprefix[4] = '\0';
     1511                        }
     1512                    }
     1513                    else
     1514                    {
     1515                      if(!memcmp(firstprefix, lpszResponse, 4))
     1516                        break;
     1517                    }
     1518                }
     1519        }
     1520
     1521        if (nRecv >= 3)
     1522        {
     1523                lpszResponse[nRecv] = '\0';
     1524                rc = atoi(lpszResponse);
     1525
     1526                if(lpfnStatusCB)
     1527                        lpfnStatusCB(hHandle, dwContext, INTERNET_STATUS_RESPONSE_RECEIVED,
     1528                                &nRecv, sizeof(DWORD));
     1529        }
    7991530
    8001531lerror:
    801         return rc;
     1532        return rc;
    8021533}
    8031534
     
    8151546BOOL FTP_SendPassword(LPWININETFTPSESSIONA lpwfs)
    8161547{
    817         int nResCode;
    818         BOOL bSuccess = FALSE;
    819 
    820         TRACE("\n");
    821         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PASS, lpwfs->lpszPassword))
    822             goto lend;
    823 
    824         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    825         if (nResCode)
    826         {
    827                 TRACE("Received reply code %d\n", nResCode);
    828                 /* Login successful... */
    829                 if (nResCode == 230)
    830                         bSuccess = TRUE;
    831                 /* Command not implemented, superfluous at the server site... */
    832                 /* Need account for login... */
    833                 else if (nResCode == 332)
    834                         bSuccess = FTP_SendAccount(lpwfs);
    835                 else
    836                         TRACE("Password failed\n");
    837         }
     1548        int nResCode;
     1549        BOOL bSuccess = FALSE;
     1550
     1551        TRACE("\n");
     1552        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PASS, lpwfs->lpszPassword, 0, 0, 0))
     1553            goto lend;
     1554
     1555        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     1556                                       MAX_REPLY_LEN, 0, 0, 0);
     1557        if (nResCode)
     1558        {
     1559                TRACE("Received reply code %d\n", nResCode);
     1560                /* Login successful... */
     1561                if (nResCode == 230)
     1562                        bSuccess = TRUE;
     1563                /* Command not implemented, superfluous at the server site... */
     1564                /* Need account for login... */
     1565                else if (nResCode == 332)
     1566                        bSuccess = FTP_SendAccount(lpwfs);
     1567                else
     1568                        FTP_SetResponseError(nResCode);
     1569        }
    8381570lend:
    839         TRACE("Returning %d\n", bSuccess);
    840         return bSuccess;
     1571        TRACE("Returning %d\n", bSuccess);
     1572        return bSuccess;
    8411573}
    8421574
     
    8541586BOOL FTP_SendAccount(LPWININETFTPSESSIONA lpwfs)
    8551587{
    856         int nResCode;
    857         BOOL bSuccess = FALSE;
    858 
    859         TRACE("\n");
    860         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_ACCT, NOACCOUNT))
    861             goto lend;
    862 
    863         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    864         if (nResCode)
    865         {
    866             bSuccess = TRUE;
    867         }
     1588        int nResCode;
     1589        BOOL bSuccess = FALSE;
     1590
     1591        TRACE("\n");
     1592        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_ACCT, NOACCOUNT, 0, 0, 0))
     1593            goto lend;
     1594
     1595        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     1596                                       MAX_REPLY_LEN, 0, 0, 0);
     1597        if (nResCode)
     1598        {
     1599            bSuccess = TRUE;
     1600        }
     1601        else
     1602            FTP_SetResponseError(nResCode);
    8681603
    8691604lend:
    870         return bSuccess;
     1605        return bSuccess;
    8711606}
    8721607
     
    8841619BOOL FTP_SendStore(LPWININETFTPSESSIONA lpwfs, LPCSTR lpszRemoteFile, DWORD dwType)
    8851620{
    886         int nResCode;
    887         BOOL bSuccess = FALSE;
    888 
    889         TRACE("\n");
    890         if (!FTP_InitListenSocket(lpwfs))
    891             goto lend;
    892 
    893         if (!FTP_SendType(lpwfs, dwType))
    894             goto lend;
    895 
    896         if (!FTP_SendPort(lpwfs))
    897             goto lend;
    898 
    899         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_STOR, lpszRemoteFile))
    900             goto lend;
    901 
    902         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    903         if (nResCode)
    904         {
    905                 if (nResCode == 150)
    906                     bSuccess = TRUE;
    907         }
     1621        int nResCode;
     1622        BOOL bSuccess = FALSE;
     1623
     1624        TRACE("\n");
     1625        if (!FTP_InitListenSocket(lpwfs))
     1626            goto lend;
     1627
     1628        if (!FTP_SendType(lpwfs, dwType))
     1629            goto lend;
     1630
     1631        if (!FTP_SendPort(lpwfs))
     1632            goto lend;
     1633
     1634        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_STOR, lpszRemoteFile, 0, 0, 0))
     1635            goto lend;
     1636
     1637        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     1638                                       MAX_REPLY_LEN, 0, 0, 0);
     1639        if (nResCode)
     1640        {
     1641                if (nResCode == 150)
     1642                    bSuccess = TRUE;
     1643                else
     1644                    FTP_SetResponseError(nResCode);
     1645        }
    9081646
    9091647lend:
    910         if (!bSuccess && INVALID_SOCKET != lpwfs->lstnSocket)
    911         {
    912             close(lpwfs->lstnSocket);
    913             lpwfs->lstnSocket = INVALID_SOCKET;
    914         }
    915 
    916         return bSuccess;
     1648        if (!bSuccess && INVALID_SOCKET != lpwfs->lstnSocket)
     1649        {
     1650            close(lpwfs->lstnSocket);
     1651            lpwfs->lstnSocket = INVALID_SOCKET;
     1652        }
     1653
     1654        return bSuccess;
    9171655}
    9181656
     
    9301668BOOL FTP_InitListenSocket(LPWININETFTPSESSIONA lpwfs)
    9311669{
    932         BOOL bSuccess = FALSE;
    933         socklen_t namelen = sizeof(struct sockaddr_in);
    934 
    935         TRACE("\n");
    936 
    937         lpwfs->lstnSocket = socket(PF_INET, SOCK_STREAM, 0);
    938         if (INVALID_SOCKET == lpwfs->lstnSocket)
    939         {
    940                 TRACE("Unable to create listening socket\n");
    941                 goto lend;
    942         }
    943 
    944         lpwfs->lstnSocketAddress.sin_family = AF_INET;
    945         lpwfs->lstnSocketAddress.sin_port = htons((u_short) 0);
    946         lpwfs->lstnSocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
    947         if (SOCKET_ERROR == bind(lpwfs->lstnSocket,&lpwfs->lstnSocketAddress, sizeof(struct sockaddr_in)))
    948         {
    949                 TRACE("Unable to bind socket: %d\n", errno);
    950                 goto lend;
    951         }
    952 
    953         if (SOCKET_ERROR == listen(lpwfs->lstnSocket, MAX_BACKLOG))
    954         {
    955                 TRACE("listen failed\n");
    956                 goto lend;
    957         }
    958 
    959         if (SOCKET_ERROR != getsockname(lpwfs->lstnSocket, &lpwfs->lstnSocketAddress, &namelen))
    960                 bSuccess = TRUE;
     1670        BOOL bSuccess = FALSE;
     1671        socklen_t namelen = sizeof(struct sockaddr_in);
     1672
     1673        TRACE("\n");
     1674
     1675        lpwfs->lstnSocket = socket(PF_INET, SOCK_STREAM, 0);
     1676        if (INVALID_SOCKET == lpwfs->lstnSocket)
     1677        {
     1678                TRACE("Unable to create listening socket\n");
     1679                goto lend;
     1680        }
     1681
     1682        /* We obtain our IP addr from the name of the command cgannel socket */
     1683        lpwfs->lstnSocketAddress = lpwfs->socketAddress;
     1684
     1685        /* and get the system to assign us a port */
     1686        lpwfs->lstnSocketAddress.sin_port = htons((u_short) 0);
     1687
     1688        if (SOCKET_ERROR == bind(lpwfs->lstnSocket, (struct sockaddr *)&lpwfs->lstnSocketAddress, sizeof(struct sockaddr_in)))
     1689        {
     1690                TRACE("Unable to bind socket: %d\n", errno);
     1691                goto lend;
     1692        }
     1693
     1694        if (SOCKET_ERROR == listen(lpwfs->lstnSocket, MAX_BACKLOG))
     1695        {
     1696                TRACE("listen failed\n");
     1697                goto lend;
     1698        }
     1699
     1700        if (SOCKET_ERROR != getsockname(lpwfs->lstnSocket, (struct sockaddr *)&lpwfs->lstnSocketAddress, &namelen))
     1701                bSuccess = TRUE;
    9611702
    9621703lend:
    963         if (!bSuccess && INVALID_SOCKET == lpwfs->lstnSocket)
    964         {
    965                 close(lpwfs->lstnSocket);
    966                 lpwfs->lstnSocket = INVALID_SOCKET;
    967         }
    968 
    969         return bSuccess;
     1704        if (!bSuccess && INVALID_SOCKET == lpwfs->lstnSocket)
     1705        {
     1706                close(lpwfs->lstnSocket);
     1707                lpwfs->lstnSocket = INVALID_SOCKET;
     1708        }
     1709
     1710        return bSuccess;
    9701711}
    9711712
     
    9831724BOOL FTP_SendType(LPWININETFTPSESSIONA lpwfs, DWORD dwType)
    9841725{
    985         int nResCode;
    986         char type[2] = { "I\0" };
    987         BOOL bSuccess = FALSE;
    988 
    989         TRACE("\n");
    990         if (dwType & INTERNET_FLAG_TRANSFER_ASCII)
    991             *type = 'A';
    992 
    993         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_TYPE, type))
    994             goto lend;
    995 
    996         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN)/100;
    997         if (nResCode)
    998         {
    999                 if (nResCode == 2)
    1000                         bSuccess = TRUE;
    1001                 else if (nResCode == 4)
    1002                 {
    1003                         /* Possible to restart */
    1004                 }
    1005                 else if (nResCode == 5)
    1006                 {
    1007                         /* Nothing can be done here */
    1008                 }
    1009         }
     1726        int nResCode;
     1727        char type[2] = { "I\0" };
     1728        BOOL bSuccess = FALSE;
     1729
     1730        TRACE("\n");
     1731        if (dwType & INTERNET_FLAG_TRANSFER_ASCII)
     1732            *type = 'A';
     1733
     1734        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_TYPE, type, 0, 0, 0))
     1735            goto lend;
     1736
     1737        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     1738                                       MAX_REPLY_LEN, 0, 0, 0)/100;
     1739        if (nResCode)
     1740        {
     1741                if (nResCode == 2)
     1742                        bSuccess = TRUE;
     1743                else
     1744                        FTP_SetResponseError(nResCode);
     1745        }
    10101746
    10111747lend:
    1012         return bSuccess;
     1748        return bSuccess;
    10131749}
    10141750
     
    10261762BOOL FTP_SendPort(LPWININETFTPSESSIONA lpwfs)
    10271763{
    1028         int nResCode;
    1029         char szIPAddress[64];
    1030         BOOL bSuccess = FALSE;
    1031 
    1032         TRACE("\n");
    1033 
    1034         sprintf(szIPAddress, "%d,%d,%d,%d,%d,%d",
    1035                 lpwfs->socketAddress.sin_addr.s_addr&0x000000FF,
    1036                 (lpwfs->socketAddress.sin_addr.s_addr&0x0000FF00)>>8,
    1037                 (lpwfs->socketAddress.sin_addr.s_addr&0x00FF0000)>>16,
    1038                 (lpwfs->socketAddress.sin_addr.s_addr&0xFF000000)>>24,
    1039                 lpwfs->lstnSocketAddress.sin_port & 0xFF,
    1040                 (lpwfs->lstnSocketAddress.sin_port & 0xFF00)>>8);
    1041 
    1042         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PORT, szIPAddress))
    1043             goto lend;
    1044 
    1045         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    1046         if (nResCode)
    1047         {
    1048                 if (nResCode == 200)
    1049                         bSuccess = TRUE;
    1050                 else
    1051                 {
    1052                         TRACE("SendPort failed\n");
    1053                 }
    1054         }
     1764        int nResCode;
     1765        char szIPAddress[64];
     1766        BOOL bSuccess = FALSE;
     1767
     1768        TRACE("\n");
     1769
     1770        sprintf(szIPAddress, "%d,%d,%d,%d,%d,%d",
     1771                lpwfs->socketAddress.sin_addr.s_addr&0x000000FF,
     1772                (lpwfs->socketAddress.sin_addr.s_addr&0x0000FF00)>>8,
     1773                (lpwfs->socketAddress.sin_addr.s_addr&0x00FF0000)>>16,
     1774                (lpwfs->socketAddress.sin_addr.s_addr&0xFF000000)>>24,
     1775                lpwfs->lstnSocketAddress.sin_port & 0xFF,
     1776                (lpwfs->lstnSocketAddress.sin_port & 0xFF00)>>8);
     1777
     1778        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PORT, szIPAddress, 0, 0, 0))
     1779            goto lend;
     1780
     1781        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     1782                                       MAX_REPLY_LEN, 0, 0, 0);
     1783        if (nResCode)
     1784        {
     1785                if (nResCode == 200)
     1786                        bSuccess = TRUE;
     1787                else
     1788                        FTP_SetResponseError(nResCode);
     1789        }
    10551790
    10561791lend:
    1057         return bSuccess;
     1792        return bSuccess;
    10581793}
    10591794
     
    10711806BOOL FTP_InitDataSocket(LPWININETFTPSESSIONA lpwfs, LPINT nDataSocket)
    10721807{
    1073         struct sockaddr_in saddr;
    1074         socklen_t addrlen = sizeof(struct sockaddr);
    1075 
    1076         TRACE("\n");
    1077         *nDataSocket = accept(lpwfs->lstnSocket, &saddr, &addrlen);
    1078         close(lpwfs->lstnSocket);
    1079         lpwfs->lstnSocket = INVALID_SOCKET;
    1080 
    1081         return *nDataSocket != INVALID_SOCKET;
     1808        struct sockaddr_in saddr;
     1809        socklen_t addrlen = sizeof(struct sockaddr);
     1810
     1811        TRACE("\n");
     1812        *nDataSocket = accept(lpwfs->lstnSocket, (struct sockaddr *)&saddr, &addrlen);
     1813        close(lpwfs->lstnSocket);
     1814        lpwfs->lstnSocket = INVALID_SOCKET;
     1815
     1816        return *nDataSocket != INVALID_SOCKET;
    10821817}
    10831818
     
    10951830BOOL FTP_SendData(LPWININETFTPSESSIONA lpwfs, int nDataSocket, HANDLE hFile)
    10961831{
    1097         BY_HANDLE_FILE_INFORMATION fi;
    1098         DWORD nBytesRead = 0;
    1099         DWORD nBytesSent = 0;
    1100         DWORD nTotalSent = 0;
    1101         DWORD nBytesToSend, nLen, nRC = 1;
    1102         time_t s_long_time, e_long_time;
    1103         long nSeconds;
    1104         char *lpszBuffer;
    1105 
    1106         TRACE("\n");
    1107         lpszBuffer = HeapAlloc(GetProcessHeap(), 0, sizeof(char)*DATA_PACKET_SIZE);
    1108         memset(lpszBuffer, 0, sizeof(char)*DATA_PACKET_SIZE);
    1109 
    1110         /* Get the size of the file. */
    1111         GetFileInformationByHandle(hFile, &fi);
    1112         time(&s_long_time);
    1113 
    1114         do
    1115         {
    1116                 nBytesToSend = nBytesRead - nBytesSent;
    1117 
    1118                 if (nBytesToSend <= 0)
    1119                 {
    1120                         /* Read data from file. */
    1121                         nBytesSent = 0;
    1122                         if (!ReadFile(hFile, lpszBuffer, DATA_PACKET_SIZE, &nBytesRead, 0))
    1123                             ERR("Failed reading from file\n");
    1124 
    1125                         if (nBytesRead > 0)
    1126                                 nBytesToSend = nBytesRead;
    1127                         else
    1128                                 break;
    1129                 }
    1130 
    1131                 nLen = DATA_PACKET_SIZE < nBytesToSend ?
    1132                     DATA_PACKET_SIZE : nBytesToSend;
    1133                 nRC  = send(nDataSocket, lpszBuffer, nLen, 0);
    1134 
    1135                 if (nRC != SOCKET_ERROR)
    1136                 {
    1137                         nBytesSent += nRC;
    1138                         nTotalSent += nRC;
    1139                 }
    1140 
    1141                 /* Do some computation to display the status. */
    1142                 time(&e_long_time);
    1143                 nSeconds = e_long_time - s_long_time;
    1144                 if( nSeconds / 60 > 0 )
    1145                 {
     1832        BY_HANDLE_FILE_INFORMATION fi;
     1833        DWORD nBytesRead = 0;
     1834        DWORD nBytesSent = 0;
     1835        DWORD nTotalSent = 0;
     1836        LONG  nBytesToSend;
     1837        DWORD nLen, nRC = 1;
     1838        time_t s_long_time, e_long_time;
     1839        long nSeconds;
     1840        char *lpszBuffer;
     1841
     1842        TRACE("\n");
     1843        lpszBuffer = HeapAlloc(GetProcessHeap(), 0, sizeof(char)*DATA_PACKET_SIZE);
     1844        memset(lpszBuffer, 0, sizeof(char)*DATA_PACKET_SIZE);
     1845
     1846        /* Get the size of the file. */
     1847        GetFileInformationByHandle(hFile, &fi);
     1848        time(&s_long_time);
     1849
     1850        do
     1851        {
     1852                nBytesToSend = nBytesRead - nBytesSent;
     1853
     1854                if (nBytesToSend <= 0)
     1855                {
     1856                        /* Read data from file. */
     1857                        nBytesSent = 0;
     1858                        if (!ReadFile(hFile, lpszBuffer, DATA_PACKET_SIZE, &nBytesRead, 0))
     1859                            ERR("Failed reading from file\n");
     1860
     1861                        if (nBytesRead > 0)
     1862                                nBytesToSend = nBytesRead;
     1863                        else
     1864                                break;
     1865                }
     1866
     1867                nLen = DATA_PACKET_SIZE < nBytesToSend ?
     1868                    DATA_PACKET_SIZE : nBytesToSend;
     1869                nRC  = send(nDataSocket, lpszBuffer, nLen, 0);
     1870
     1871                if (nRC != SOCKET_ERROR)
     1872                {
     1873                        nBytesSent += nRC;
     1874                        nTotalSent += nRC;
     1875                }
     1876
     1877                /* Do some computation to display the status. */
     1878                time(&e_long_time);
     1879                nSeconds = e_long_time - s_long_time;
     1880                if( nSeconds / 60 > 0 )
     1881                {
    11461882/*
    1147                         TRACE( "%d bytes of %d bytes (%d%%) in %d min %d sec estimated remainig time %d sec\t\t\r",
    1148                                 nTotalSent, fi.nFileSizeLow, nTotalSent*100/st.st_size, nSeconds / 60,
    1149                                 nSeconds % 60, (st.st_size - nTotalSent) * nSeconds / nTotalSent );
     1883                        TRACE( "%d bytes of %d bytes (%d%%) in %d min %d sec estimated remainig time %d sec\t\t\r",
     1884                                nTotalSent, fi.nFileSizeLow, nTotalSent*100/st.st_size, nSeconds / 60,
     1885                                nSeconds % 60, (st.st_size - nTotalSent) * nSeconds / nTotalSent );
    11501886*/
    1151                 }
    1152                 else
    1153                 {
     1887                }
     1888                else
     1889                {
    11541890/*
    1155                         TRACE( "%d bytes of %d bytes (%d%%) in %d sec estimated remainig time %d sec\t\t\r",
    1156                                 nTotalSent, fi.nFileSizeLow, nTotalSent*100/st.st_size, nSeconds,
    1157                                 (st.st_size - nTotalSent) * nSeconds / nTotalSent);
     1891                        TRACE( "%d bytes of %d bytes (%d%%) in %d sec estimated remainig time %d sec\t\t\r",
     1892                                nTotalSent, fi.nFileSizeLow, nTotalSent*100/st.st_size, nSeconds,
     1893                                (st.st_size - nTotalSent) * nSeconds / nTotalSent);
    11581894*/
    11591895
    1160                 }
    1161         } while (nRC != SOCKET_ERROR);
    1162 
    1163         TRACE("file transfer complete!\n");
    1164 
    1165         if(lpszBuffer != NULL)
    1166                 HeapFree(GetProcessHeap(), 0, lpszBuffer);
    1167 
    1168         return nTotalSent;
     1896                }
     1897        } while (nRC != SOCKET_ERROR);
     1898
     1899        TRACE("file transfer complete!\n");
     1900
     1901        if(lpszBuffer != NULL)
     1902                HeapFree(GetProcessHeap(), 0, lpszBuffer);
     1903
     1904        return nTotalSent;
    11691905}
    11701906
     
    11801916 *
    11811917 */
    1182 DWORD FTP_SendRetrieve(LPWININETFTPSESSIONA lpwfs, LPCSTR lpszRemoteFile, DWORD dwType)
    1183 {
    1184         int nResCode;
    1185         DWORD nResult = 0;
    1186 
    1187         TRACE("\n");
    1188         if (!FTP_InitListenSocket(lpwfs))
    1189             goto lend;
    1190 
    1191         if (!FTP_SendType(lpwfs, dwType))
    1192             goto lend;
    1193 
    1194         if (!FTP_SendPort(lpwfs))
    1195             goto lend;
    1196 
    1197         if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RETR, lpszRemoteFile))
    1198             goto lend;
    1199 
    1200         nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    1201         if (nResCode)
    1202         {
    1203                 if (nResCode == 125 || nResCode == 150)
    1204                 {
    1205                         /* Parse size of data to be retrieved */
    1206                         int i, sizepos = -1;
    1207                         for (i = strlen(lpwfs->lpszResponseBuffer) - 1; i >= 0; i--)
    1208                         {
    1209                                 if ('(' == lpwfs->lpszResponseBuffer[i])
    1210                                 {
    1211                                         sizepos = i;
    1212                                         break;
    1213                                 }
    1214                         }
    1215 
    1216                         if (sizepos >= 0)
    1217                         {
    1218                                 nResult = atol(&lpwfs->lpszResponseBuffer[sizepos+1]);
    1219                                 TRACE("Waiting to receive %d bytes\n", nResult);
    1220                         }
    1221                 }
    1222         }
     1918DWORD FTP_SendRetrieve(LPWININETFTPSESSIONA lpwfs, LPCSTR lpszRemoteFile, DWORD dwType, LONG *lBytesAvailable)
     1919{
     1920        int nResCode;
     1921        DWORD nResult = 0;
     1922
     1923        TRACE("\n");
     1924        if (!FTP_InitListenSocket(lpwfs))
     1925            goto lend;
     1926
     1927        if (!FTP_SendType(lpwfs, dwType))
     1928            goto lend;
     1929
     1930        if (!FTP_SendPort(lpwfs))
     1931            goto lend;
     1932
     1933        if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RETR, lpszRemoteFile, 0, 0, 0))
     1934            goto lend;
     1935
     1936        nResCode = FTP_ReceiveResponse(lpwfs->sndSocket, INTERNET_GetResponseBuffer(),
     1937                                       MAX_REPLY_LEN, 0, 0, 0);
     1938        if (nResCode)
     1939        {
     1940                if (nResCode == 125 || nResCode == 150)
     1941                {
     1942                        /* Parse size of data to be retrieved */
     1943                        int i, sizepos = -1;
     1944                        LPSTR lpszResponseBuffer = INTERNET_GetResponseBuffer();
     1945                        for (i = strlen(lpszResponseBuffer) - 1; i >= 0; i--)
     1946                        {
     1947                                if ('(' == lpszResponseBuffer[i])
     1948                                {
     1949                                        sizepos = i;
     1950                                        break;
     1951                                }
     1952                        }
     1953
     1954                        if (sizepos >= 0)
     1955                        {
     1956                                nResult = atol(&lpszResponseBuffer[sizepos+1]);
     1957                                TRACE("Waiting to receive %d bytes\n", nResult);
     1958
     1959                                if(lBytesAvailable)
     1960                                  *lBytesAvailable = nResult;
     1961                        }
     1962                        else
     1963                                if(lBytesAvailable)
     1964                                  *lBytesAvailable = -1;
     1965                }
     1966        }
    12231967
    12241968lend:
    1225         if (0 == nResult && INVALID_SOCKET != lpwfs->lstnSocket)
    1226         {
    1227             close(lpwfs->lstnSocket);
    1228             lpwfs->lstnSocket = INVALID_SOCKET;
    1229         }
    1230 
    1231         return nResult;
     1969        if (0 == nResult && INVALID_SOCKET != lpwfs->lstnSocket)
     1970        {
     1971            close(lpwfs->lstnSocket);
     1972            lpwfs->lstnSocket = INVALID_SOCKET;
     1973        }
     1974
     1975        return nResult;
    12321976}
    12331977
     
    12451989BOOL FTP_RetrieveFileData(LPWININETFTPSESSIONA lpwfs, int nDataSocket, DWORD nBytes, HANDLE hFile)
    12461990{
    1247         DWORD nBytesWritten;
    1248         DWORD nBytesReceived = 0;
    1249         int nRC = 0;
    1250         char *lpszBuffer;
    1251 
    1252         TRACE("\n");
    1253 
    1254         if (INVALID_HANDLE_VALUE == hFile)
    1255                 return FALSE;
    1256 
    1257         lpszBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(char)*DATA_PACKET_SIZE);
    1258         if (NULL == lpszBuffer)
    1259         {
    1260                 SetLastError(ERROR_OUTOFMEMORY);
    1261                 return FALSE;
    1262         }
    1263 
    1264         while (nBytesReceived < nBytes && nRC != SOCKET_ERROR)
    1265         {
    1266                 nRC = recv(nDataSocket, lpszBuffer, DATA_PACKET_SIZE, 0);
    1267                 if (nRC != SOCKET_ERROR)
    1268                 {
    1269                         /* other side closed socket. */
    1270                         if (nRC == 0)
    1271                                 goto recv_end;
    1272                         WriteFile(hFile, lpszBuffer, nRC, &nBytesWritten, NULL);
    1273                         nBytesReceived += nRC;
    1274                 }
    1275 
    1276                 TRACE("%d bytes of %ld (%ld%%)\r", nBytesReceived, nBytes,
     1991        DWORD nBytesWritten;
     1992        DWORD nBytesReceived = 0;
     1993        int nRC = 0;
     1994        char *lpszBuffer;
     1995
     1996        TRACE("\n");
     1997
     1998        if (INVALID_HANDLE_VALUE == hFile)
     1999                return FALSE;
     2000
     2001        lpszBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(char)*DATA_PACKET_SIZE);
     2002        if (NULL == lpszBuffer)
     2003        {
     2004                INTERNET_SetLastError(ERROR_OUTOFMEMORY);
     2005                return FALSE;
     2006        }
     2007
     2008        while (nBytesReceived < nBytes && nRC != SOCKET_ERROR)
     2009        {
     2010                nRC = recv(nDataSocket, lpszBuffer, DATA_PACKET_SIZE, 0);
     2011                if (nRC != SOCKET_ERROR)
     2012                {
     2013                        /* other side closed socket. */
     2014                        if (nRC == 0)
     2015                                goto recv_end;
     2016                        WriteFile(hFile, lpszBuffer, nRC, &nBytesWritten, NULL);
     2017                        nBytesReceived += nRC;
     2018
     2019//                      INTERNET_SubstractFromDataAvailable(lpwfs,nRC);
     2020                }
     2021
     2022                TRACE("%d bytes of %ld (%ld%%)\r", nBytesReceived, nBytes,
    12772023                  nBytesReceived * 100 / nBytes);
    1278         }
    1279 
    1280         TRACE("Data transfer complete\n");
    1281         if (NULL != lpszBuffer)
    1282             HeapFree(GetProcessHeap(), 0, lpszBuffer);
     2024        }
     2025
     2026        TRACE("Data transfer complete\n");
     2027        if (NULL != lpszBuffer)
     2028            HeapFree(GetProcessHeap(), 0, lpszBuffer);
    12832029
    12842030recv_end:
    1285         return  (nRC != SOCKET_ERROR);
     2031        return  (nRC != SOCKET_ERROR);
    12862032}
    12872033
     
    13002046{
    13012047    if (INVALID_SOCKET != lpwfs->sndSocket)
    1302         close(lpwfs->sndSocket);
     2048        close(lpwfs->sndSocket);
    13032049
    13042050    if (INVALID_SOCKET != lpwfs->lstnSocket)
    1305         close(lpwfs->lstnSocket);
     2051        close(lpwfs->lstnSocket);
    13062052
    13072053    if (lpwfs->lpszPassword)
    1308         HeapFree(GetProcessHeap(), 0, lpwfs->lpszPassword);
     2054        HeapFree(GetProcessHeap(), 0, lpwfs->lpszPassword);
    13092055
    13102056    if (lpwfs->lpszUserName)
    1311         HeapFree(GetProcessHeap(), 0, lpwfs->lpszUserName);
    1312 
    1313     if (lpwfs->lpszResponseBuffer)
    1314         HeapFree(GetProcessHeap(), 0, lpwfs->lpszResponseBuffer);
     2057        HeapFree(GetProcessHeap(), 0, lpwfs->lpszUserName);
     2058
     2059    if (INTERNET_GetResponseBuffer())
     2060        HeapFree(GetProcessHeap(), 0, INTERNET_GetResponseBuffer());
    13152061
    13162062    HeapFree(GetProcessHeap(), 0, lpwfs);
     
    13362082    for (i = 0; i < lpwfn->size; i++)
    13372083    {
    1338         if (NULL != lpwfn->lpafp[i].lpszName)
    1339             HeapFree(GetProcessHeap(), 0, lpwfn->lpafp[i].lpszName);
     2084        if (NULL != lpwfn->lpafp[i].lpszName)
     2085            HeapFree(GetProcessHeap(), 0, lpwfn->lpafp[i].lpszName);
    13402086    }
    13412087
     
    13572103 *
    13582104 */
    1359 HINTERNET FTP_ReceiveFileList(LPWININETFTPSESSIONA lpwfs, int nSocket, LPWIN32_FIND_DATAA lpFindFileData)
    1360 {
    1361         DWORD dwSize;
    1362         LPFILEPROPERTIESA lpafp = NULL;
    1363         LPWININETFINDNEXTA lpwfn = NULL;
    1364 
    1365         TRACE("\n");
    1366 
    1367         if (FTP_ParseDirectory(lpwfs, nSocket, &lpafp, &dwSize))
    1368         {
    1369                 DWORD access = mktime(&lpafp->tmLastModified);
    1370 
    1371                 /* Not all fields are filled in */
    1372                 lpFindFileData->ftLastAccessTime.dwHighDateTime = HIWORD(access);
    1373                 lpFindFileData->ftLastAccessTime.dwLowDateTime  = LOWORD(access);
    1374                 lpFindFileData->nFileSizeHigh = HIWORD(lpafp->nSize);
    1375                 lpFindFileData->nFileSizeLow = LOWORD(lpafp->nSize);
    1376                 strncpy(lpFindFileData->cFileName, lpafp->lpszName, MAX_PATH);
    1377 
    1378                 lpwfn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETFINDNEXTA));
    1379                 if (NULL != lpwfn)
    1380                 {
    1381                     lpwfn->hdr.htype = WH_HFINDNEXT;
    1382                     lpwfn->hdr.lpwhparent = (LPWININETHANDLEHEADER)lpwfs;
    1383                     lpwfn->index = 1;
    1384                     lpwfn->size = dwSize;
    1385                     lpwfn->lpafp = lpafp;
    1386                 }
    1387         }
    1388 
    1389         return (HINTERNET)lpwfn;
    1390 }
    1391 
    1392 
    1393 /***********************************************************************
    1394  *           FTP_ParseDirectory (internal)
    1395  *
    1396  * Parse string of directory information
     2105HINTERNET FTP_ReceiveFileList(LPWININETFTPSESSIONA lpwfs, int nSocket,
     2106                LPWIN32_FIND_DATAA lpFindFileData, DWORD dwContext)
     2107{
     2108        DWORD dwSize;
     2109        LPFILEPROPERTIESA lpafp = NULL;
     2110        LPWININETFINDNEXTA lpwfn = NULL;
     2111
     2112        TRACE("\n");
     2113
     2114        if (FTP_ParseDirectory(lpwfs, nSocket, &lpafp, &dwSize))
     2115        {
     2116                FTP_ConvertFileProp(lpafp, lpFindFileData);
     2117
     2118                lpwfn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETFINDNEXTA));
     2119                if (NULL != lpwfn)
     2120                {
     2121                    lpwfn->hdr.htype = WH_HFINDNEXT;
     2122                    lpwfn->hdr.lpwhparent = (LPWININETHANDLEHEADER)lpwfs;
     2123                    lpwfn->index = 1;
     2124                    lpwfn->size = dwSize;
     2125                    lpwfn->lpafp = lpafp;
     2126                }
     2127        }
     2128
     2129        return (HINTERNET)lpwfn;
     2130}
     2131
     2132
     2133/***********************************************************************
     2134 *           FTP_ConvertFileProp (internal)
     2135 *
     2136 Converts FILEPROPERTIESA struct to WIN32_FILE_DATAA
    13972137 *
    13982138 * RETURNS
     
    14012141 *
    14022142 */
     2143BOOL FTP_ConvertFileProp(LPFILEPROPERTIESA lpafp, LPWIN32_FIND_DATAA lpFindFileData)
     2144{
     2145        BOOL bSuccess = FALSE;
     2146
     2147        ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA));
     2148
     2149        if(lpafp)
     2150        {
     2151                DWORD access = mktime(&lpafp->tmLastModified);
     2152
     2153                /* Not all fields are filled in */
     2154                lpFindFileData->ftLastAccessTime.dwHighDateTime = HIWORD(access);
     2155                lpFindFileData->ftLastAccessTime.dwLowDateTime  = LOWORD(access);
     2156                lpFindFileData->nFileSizeHigh = HIWORD(lpafp->nSize);
     2157                lpFindFileData->nFileSizeLow = LOWORD(lpafp->nSize);
     2158
     2159                if(lpafp->bIsDirectory)
     2160                  lpFindFileData->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
     2161
     2162                if(lpafp->lpszName)
     2163                  strncpy(lpFindFileData->cFileName, lpafp->lpszName, MAX_PATH);
     2164
     2165                bSuccess = TRUE;
     2166        }
     2167
     2168    return bSuccess;
     2169}
     2170
     2171/***********************************************************************
     2172 *           FTP_ParseDirectory (internal)
     2173 *
     2174 * Parse string of directory information
     2175 *
     2176 * RETURNS
     2177 *   TRUE on success
     2178 *   FALSE on failure
     2179 *
     2180 */
    14032181#define MAX_MONTH_LEN 10
     2182#define MIN_LEN_DIR_ENTRY 15
    14042183
    14052184BOOL FTP_ParseDirectory(LPWININETFTPSESSIONA lpwfs, int nSocket, LPFILEPROPERTIESA *lpafp, LPDWORD dwfp)
     
    14112190   * drwx--s---     2         pcarrier  ens     512    Sep 28  1995           pcarrier
    14122191   */
    1413         char* pszMinutes;
    1414         char* pszHour;
    1415         time_t aTime;
    1416         struct tm* apTM;
    1417         char pszMonth[MAX_MONTH_LEN];
    1418         char* pszMatch;
    1419         BOOL bSuccess = TRUE;
    1420         LPFILEPROPERTIESA curFileProp = NULL;
    1421         char* pszLine  = NULL;
    1422         char* pszToken = NULL;
    1423         int nTokenToSkip = 3;
    1424         int nCount = 0;
    1425         int nSeconds = 0;
    1426         int nMinutes = 0;
    1427         int nHour    = 0;
    1428         int nDay     = 0;
    1429         int nMonth   = 0;
    1430         int nYear    = 0;
    1431         int sizeFilePropArray = 20;
    1432         int indexFilePropArray = 0;
    1433 
    1434         TRACE("\n");
    1435 
    1436         /* Skip over the first line */
    1437         FTP_GetNextLine(nSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN);
    1438 
    1439         /* Allocate intial file properties array */
    1440         *lpafp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FILEPROPERTIESA)*(sizeFilePropArray));
    1441         if (NULL == lpafp)
    1442         {
    1443             bSuccess = FALSE;
    1444             goto lend;
    1445         }
    1446 
    1447         while ((pszLine = FTP_GetNextLine(nSocket, lpwfs->lpszResponseBuffer, MAX_REPLY_LEN)) != NULL)
    1448         {
    1449                 if (sizeFilePropArray < indexFilePropArray)
    1450                 {
    1451                         LPFILEPROPERTIESA tmpafp;
    1452 
    1453                         sizeFilePropArray *= 2;
    1454                         tmpafp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *lpafp,
    1455                                 sizeof(FILEPROPERTIESA)*sizeFilePropArray);
    1456                         if (NULL == tmpafp)
    1457                         {
    1458                             bSuccess = FALSE;
    1459                             goto lend;
    1460                         }
    1461 
    1462                         *lpafp = tmpafp;
    1463                 }
    1464 
    1465                 curFileProp = &((*lpafp)[indexFilePropArray]);
    1466 
    1467                 /* First Parse the permissions. */
    1468                 pszToken = strtok(pszLine, " \t" );
    1469                 FTP_ParsePermission(pszToken, curFileProp);
    1470 
    1471                 nTokenToSkip = 3;
    1472                 nCount = 0;
    1473                 do
    1474                 {
    1475                         pszToken = strtok( NULL, " \t" );
    1476                         nCount++;
    1477                 } while( nCount <= nTokenToSkip );
    1478 
    1479                 /* Store the size of the file in the param list. */
    1480                 if (pszToken != NULL)
    1481                         curFileProp->nSize = atol(pszToken);
    1482 
    1483                 /* Parse last modified time. */
    1484                 nSeconds = 0;
    1485                 nMinutes = 0;
    1486                 nHour    = 0;
    1487                 nDay     = 0;
    1488                 nMonth   = 0;
    1489                 nYear    = 0;
    1490 
    1491                 pszToken = strtok( NULL, " \t" );
    1492                 strncpy(pszMonth, pszToken, MAX_MONTH_LEN);
    1493                 strupr(pszMonth);
    1494                 pszMatch = strstr(szMonths, pszMonth);
    1495                 if( pszMatch != NULL )
    1496                         nMonth = (pszMatch - szMonths) / 3;
    1497 
    1498                 pszToken = strtok(NULL, " \t");
    1499                 if (pszToken != NULL)
    1500                         nDay = atoi(pszToken);
    1501 
    1502                 pszToken = strtok(NULL, " \t");
    1503                 pszMinutes = strchr(pszToken, ':');
    1504                 if( pszMinutes != NULL )
    1505                 {
    1506                         pszMinutes++;
    1507                         nMinutes = atoi(pszMinutes);
    1508                         pszHour = pszMinutes - 3;
    1509                         if (pszHour != NULL)
    1510                                 nHour = atoi(pszHour);
    1511                         time(&aTime);
    1512                         apTM = localtime( &aTime );
    1513                         nYear = apTM->tm_year;
    1514                 }
    1515                 else
    1516                 {
    1517                         nYear  = atoi(pszToken);
    1518                         nYear -= 1900;
    1519                         nHour  = 12;
    1520                 }
    1521 
    1522                 curFileProp->tmLastModified.tm_sec  = nSeconds;
    1523                 curFileProp->tmLastModified.tm_min  = nMinutes;
    1524                 curFileProp->tmLastModified.tm_hour = nHour;
    1525                 curFileProp->tmLastModified.tm_mday = nDay;
    1526                 curFileProp->tmLastModified.tm_mon  = nMonth;
    1527                 curFileProp->tmLastModified.tm_year = nYear;
    1528 
    1529                 pszToken = strtok(NULL, " \t");
    1530                 if(pszToken != NULL)
    1531                 {
    1532                         curFileProp->lpszName = strdup(pszToken);
    1533                         TRACE(": %s\n", curFileProp->lpszName);
    1534                 }
    1535 
    1536                 indexFilePropArray++;
    1537         }
    1538 
    1539         if (bSuccess)
    1540         {
    1541                 if (indexFilePropArray < sizeFilePropArray - 1)
    1542                 {
    1543                         LPFILEPROPERTIESA tmpafp;
    1544 
    1545                         tmpafp = HeapReAlloc(GetProcessHeap(), 0, *lpafp,
    1546                                 sizeof(FILEPROPERTIESA)*indexFilePropArray);
    1547                         if (NULL == tmpafp)
    1548                                 *lpafp = tmpafp;
    1549                 }
    1550                 *dwfp = indexFilePropArray;
    1551         }
    1552         else
    1553         {
    1554                 HeapFree(GetProcessHeap(), 0, *lpafp);
    1555         }
     2192        char* pszMinutes;
     2193        char* pszHour;
     2194        time_t aTime;
     2195        struct tm* apTM;
     2196        char pszMonth[MAX_MONTH_LEN];
     2197        char* pszMatch;
     2198        BOOL bSuccess = TRUE;
     2199        DWORD nBufLen = MAX_REPLY_LEN;
     2200        LPFILEPROPERTIESA curFileProp = NULL;
     2201        char* pszLine  = NULL;
     2202        char* pszToken = NULL;
     2203        int nTokenToSkip = 3;
     2204        int nCount = 0;
     2205        int nSeconds = 0;
     2206        int nMinutes = 0;
     2207        int nHour    = 0;
     2208        int nDay     = 0;
     2209        int nMonth   = 0;
     2210        int nYear    = 0;
     2211        int sizeFilePropArray = 20;
     2212        int indexFilePropArray = 0;
     2213
     2214        TRACE("\n");
     2215
     2216        *lpafp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FILEPROPERTIESA)*(sizeFilePropArray));
     2217        if(NULL == lpafp)
     2218          {
     2219            bSuccess = FALSE;
     2220            goto lend;
     2221          }
     2222
     2223        while ((pszLine = INTERNET_GetNextLine(nSocket, INTERNET_GetResponseBuffer(), &nBufLen)) != NULL)
     2224        {
     2225                if (sizeFilePropArray < indexFilePropArray)
     2226                {
     2227                        LPFILEPROPERTIESA tmpafp;
     2228
     2229                        sizeFilePropArray *= 2;
     2230                        tmpafp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *lpafp,
     2231                                sizeof(FILEPROPERTIESA)*sizeFilePropArray);
     2232                        if (NULL == tmpafp)
     2233                        {
     2234                            bSuccess = FALSE;
     2235                            goto lend;
     2236                        }
     2237
     2238                        *lpafp = tmpafp;
     2239                }
     2240
     2241                curFileProp = &((*lpafp)[indexFilePropArray]);
     2242
     2243                /* First Parse the permissions. */
     2244                pszToken = strtok(pszLine, " \t" );
     2245
     2246                if(!pszToken || 10 != strlen(pszToken) || nBufLen < MIN_LEN_DIR_ENTRY)
     2247                {
     2248                  nBufLen = MAX_REPLY_LEN;
     2249                  continue;
     2250                }
     2251
     2252                FTP_ParsePermission(pszToken, curFileProp);
     2253
     2254                nTokenToSkip = 3;
     2255                nCount = 0;
     2256                do
     2257                {
     2258                        pszToken = strtok( NULL, " \t" );
     2259                        nCount++;
     2260                } while( nCount <= nTokenToSkip );
     2261
     2262                /* Store the size of the file in the param list. */
     2263                if (pszToken != NULL)
     2264                        curFileProp->nSize = atol(pszToken);
     2265
     2266                /* Parse last modified time. */
     2267                nSeconds = 0;
     2268                nMinutes = 0;
     2269                nHour    = 0;
     2270                nDay     = 0;
     2271                nMonth   = 0;
     2272                nYear    = 0;
     2273
     2274                pszToken = strtok( NULL, " \t" );
     2275                strncpy(pszMonth, pszToken, MAX_MONTH_LEN);
     2276                strupr(pszMonth);
     2277                pszMatch = strstr(szMonths, pszMonth);
     2278                if( pszMatch != NULL )
     2279                        nMonth = (pszMatch - szMonths) / 3;
     2280
     2281                pszToken = strtok(NULL, " \t");
     2282                if (pszToken != NULL)
     2283                        nDay = atoi(pszToken);
     2284
     2285                pszToken = strtok(NULL, " \t");
     2286                pszMinutes = strchr(pszToken, ':');
     2287                if( pszMinutes != NULL )
     2288                {
     2289                        pszMinutes++;
     2290                        nMinutes = atoi(pszMinutes);
     2291                        pszHour = pszMinutes - 3;
     2292                        if (pszHour != NULL)
     2293                                nHour = atoi(pszHour);
     2294                        time(&aTime);
     2295                        apTM = localtime( &aTime );
     2296                        nYear = apTM->tm_year;
     2297                }
     2298                else
     2299                {
     2300                        nYear  = atoi(pszToken);
     2301                        nYear -= 1900;
     2302                        nHour  = 12;
     2303                }
     2304
     2305                curFileProp->tmLastModified.tm_sec  = nSeconds;
     2306                curFileProp->tmLastModified.tm_min  = nMinutes;
     2307                curFileProp->tmLastModified.tm_hour = nHour;
     2308                curFileProp->tmLastModified.tm_mday = nDay;
     2309                curFileProp->tmLastModified.tm_mon  = nMonth;
     2310                curFileProp->tmLastModified.tm_year = nYear;
     2311
     2312                pszToken = strtok(NULL, " \t");
     2313                if(pszToken != NULL)
     2314                {
     2315                        curFileProp->lpszName = strdup(pszToken);
     2316                        TRACE(": %s\n", curFileProp->lpszName);
     2317                }
     2318
     2319                nBufLen = MAX_REPLY_LEN;
     2320                indexFilePropArray++;
     2321        }
     2322
     2323        if (bSuccess && indexFilePropArray)
     2324        {
     2325                if (indexFilePropArray < sizeFilePropArray - 1)
     2326                {
     2327                        LPFILEPROPERTIESA tmpafp;
     2328
     2329                        tmpafp = HeapReAlloc(GetProcessHeap(), 0, *lpafp,
     2330                                sizeof(FILEPROPERTIESA)*indexFilePropArray);
     2331                        if (NULL == tmpafp)
     2332                                *lpafp = tmpafp;
     2333                }
     2334                *dwfp = indexFilePropArray;
     2335        }
     2336        else
     2337        {
     2338                HeapFree(GetProcessHeap(), 0, *lpafp);
     2339                INTERNET_SetLastError(ERROR_NO_MORE_FILES);
     2340                bSuccess = FALSE;
     2341        }
    15562342
    15572343lend:
     
    15722358BOOL FTP_ParsePermission(LPCSTR lpszPermission, LPFILEPROPERTIESA lpfp)
    15732359{
    1574         BOOL bSuccess = TRUE;
    1575         unsigned short nPermission = 0;
    1576         int nPos = 1;
    1577         int nLast  = 9;
    1578 
    1579         TRACE("\n");
    1580         if ((*lpszPermission != 'd') && (*lpszPermission != '-') && (*lpszPermission != 'l'))
    1581         {
    1582                 bSuccess = FALSE;
    1583                 return bSuccess;
    1584         }
    1585 
    1586         lpfp->bIsDirectory = (*lpszPermission == 'd');
    1587         do
    1588         {
    1589                 switch (nPos)
    1590                 {
    1591                         case 1:
    1592                                 nPermission |= (*(lpszPermission+1) == 'r' ? 1 : 0) << 8;
    1593                                 break;
    1594                         case 2:
    1595                                 nPermission |= (*(lpszPermission+2) == 'w' ? 1 : 0) << 7;
    1596                                 break;
    1597                         case 3:
    1598                                 nPermission |= (*(lpszPermission+3) == 'x' ? 1 : 0) << 6;
    1599                                 break;
    1600                         case 4:
    1601                                 nPermission |= (*(lpszPermission+4) == 'r' ? 1 : 0) << 5;
    1602                                 break;
    1603                         case 5:
    1604                                 nPermission |= (*(lpszPermission+5) == 'w' ? 1 : 0) << 4;
    1605                                 break;
    1606                         case 6:
    1607                                 nPermission |= (*(lpszPermission+6) == 'x' ? 1 : 0) << 3;
    1608                                 break;
    1609                         case 7:
    1610                                 nPermission |= (*(lpszPermission+7) == 'r' ? 1 : 0) << 2;
    1611                                 break;
    1612                         case 8:
    1613                                 nPermission |= (*(lpszPermission+8) == 'w' ? 1 : 0) << 1;
    1614                                 break;
    1615                         case 9:
    1616                                 nPermission |= (*(lpszPermission+9) == 'x' ? 1 : 0);
    1617                                 break;
    1618                 }
    1619                 nPos++;
    1620         }while (nPos <= nLast);
    1621 
    1622         lpfp->permissions = nPermission;
    1623         return bSuccess;
    1624 }
    1625 
    1626 
    1627 /***********************************************************************
    1628  *           FTP_GetNextLine  (internal)
    1629  *
    1630  * Parse next line in directory string listing
    1631  *
    1632  * RETURNS
    1633  *   Pointer to begining of next line
    1634  *   NULL on failure
    1635  *
    1636  */
    1637 
    1638 LPSTR FTP_GetNextLine(int nSocket, LPSTR lpszBuffer, DWORD dwBuffer)
    1639 {
    1640         BOOL bSuccess = FALSE;
    1641         int nRecv = 0;
    1642 
    1643         TRACE("\n");
    1644         while (nRecv < dwBuffer)
    1645         {
    1646                 if (recv(nSocket, &lpszBuffer[nRecv], 1, 0) < 0)
    1647                     goto lend;
    1648                 if (lpszBuffer[nRecv] == '\n')
    1649                 {
    1650                     bSuccess = TRUE;
    1651                     break;
    1652                 }
    1653                 if (lpszBuffer[nRecv] != '\r')
    1654                     nRecv++;
    1655         }
    1656 
    1657 lend:
    1658         if (bSuccess)
    1659         {
    1660                 lpszBuffer[nRecv] = '\0';
    1661                 TRACE(": %s\n", lpszBuffer);
    1662                 return lpszBuffer;
    1663         }
    1664         else
    1665             return NULL;
    1666 }
    1667 
     2360        BOOL bSuccess = TRUE;
     2361        unsigned short nPermission = 0;
     2362        int nPos = 1;
     2363        int nLast  = 9;
     2364
     2365        TRACE("\n");
     2366        if ((*lpszPermission != 'd') && (*lpszPermission != '-') && (*lpszPermission != 'l'))
     2367        {
     2368                bSuccess = FALSE;
     2369                return bSuccess;
     2370        }
     2371
     2372        lpfp->bIsDirectory = (*lpszPermission == 'd');
     2373        do
     2374        {
     2375                switch (nPos)
     2376                {
     2377                        case 1:
     2378                                nPermission |= (*(lpszPermission+1) == 'r' ? 1 : 0) << 8;
     2379                                break;
     2380                        case 2:
     2381                                nPermission |= (*(lpszPermission+2) == 'w' ? 1 : 0) << 7;
     2382                                break;
     2383                        case 3:
     2384                                nPermission |= (*(lpszPermission+3) == 'x' ? 1 : 0) << 6;
     2385                                break;
     2386                        case 4:
     2387                                nPermission |= (*(lpszPermission+4) == 'r' ? 1 : 0) << 5;
     2388                                break;
     2389                        case 5:
     2390                                nPermission |= (*(lpszPermission+5) == 'w' ? 1 : 0) << 4;
     2391                                break;
     2392                        case 6:
     2393                                nPermission |= (*(lpszPermission+6) == 'x' ? 1 : 0) << 3;
     2394                                break;
     2395                        case 7:
     2396                                nPermission |= (*(lpszPermission+7) == 'r' ? 1 : 0) << 2;
     2397                                break;
     2398                        case 8:
     2399                                nPermission |= (*(lpszPermission+8) == 'w' ? 1 : 0) << 1;
     2400                                break;
     2401                        case 9:
     2402                                nPermission |= (*(lpszPermission+9) == 'x' ? 1 : 0);
     2403                                break;
     2404                }
     2405                nPos++;
     2406        }while (nPos <= nLast);
     2407
     2408        lpfp->permissions = nPermission;
     2409        return bSuccess;
     2410}
     2411
     2412/***********************************************************************
     2413 *           FTP_SetResponseError (internal)
     2414 *
     2415 * Set the appropriate error code for a given response from the server
     2416 *
     2417 * RETURNS
     2418 *
     2419 */
     2420DWORD FTP_SetResponseError(DWORD dwResponse)
     2421{
     2422    DWORD dwCode = 0;
     2423
     2424    switch(dwResponse)
     2425    {
     2426        case 421:   /* Service not available - Server may be shutting down.*/
     2427            dwCode = ERROR_INTERNET_TIMEOUT;
     2428            break;
     2429
     2430        case 425:                          /* Cannot open data connection.*/
     2431            dwCode = ERROR_INTERNET_CANNOT_CONNECT;
     2432            break;
     2433
     2434        case 426:                   /* Connection closed, transer aborted.*/
     2435            dwCode = ERROR_INTERNET_CONNECTION_ABORTED;
     2436            break;
     2437
     2438        case 500:                   /* Syntax error. Command unrecognized.*/
     2439        case 501:       /* Syntax error. Error in parameters or arguments.*/
     2440            dwCode = ERROR_INTERNET_INCORRECT_FORMAT;
     2441            break;
     2442
     2443        case 530:                       /* Not logged in. Login incorrect.*/
     2444            dwCode = ERROR_INTERNET_LOGIN_FAILURE;
     2445            break;
     2446
     2447        case 550:   /* File action not taken. File not found or no access.*/
     2448            dwCode = ERROR_INTERNET_ITEM_NOT_FOUND;
     2449            break;
     2450
     2451        case 450:              /* File action not taken. File may be busy.*/
     2452        case 451:                         /* Action aborted. Server error.*/
     2453        case 452:/* Action not taken. Insufficient storage space on server.*/
     2454        case 502:                              /* Command not implemented.*/
     2455        case 503:                              /* Bad sequence of command.*/
     2456        case 504:           /* Command not implemented for that parameter.*/
     2457        case 532:                        /* Need account for storing files*/
     2458        case 551:   /* Requested action aborted. Page type unknown*/
     2459        case 552:   /* Action aborted. Exceeded storage allocation*/
     2460        case 553:      /* Action not taken. File name not allowed.*/
     2461
     2462        default:
     2463            dwCode = ERROR_INTERNET_INTERNAL_ERROR;
     2464            break;
     2465    }
     2466
     2467    INTERNET_SetLastError(dwCode);
     2468    return dwCode;
     2469}
Note: See TracChangeset for help on using the changeset viewer.