Changeset 4842 for trunk/src


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

JH: Resync with latest Wine + fixes/additions

Location:
trunk/src/wininet
Files:
1 added
6 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}
  • trunk/src/wininet/internet.c

    r3898 r4842  
    1 /* $Id: internet.c,v 1.2 2000-07-29 14:10:09 bird Exp $
     1/* $Id: internet.c,v 1.3 2000-12-27 23:06:17 sandervl Exp $
    22 *
    33 * Wininet
     
    1515#include <tchar.h>
    1616#include <winsock.h>
     17#include <ipexport.h>
     18#include <icmpapi.h>
    1719
    1820#ifdef __WIN32OS2__
    1921#include <stdlib.h>
    2022#include <string.h>
     23#include <ctype.h>
     24#define strncasecmp strnicmp
     25#define ERROR_INTERNET_TIMEOUT ERROR_INTERNET_TIME
     26#define ERROR_INTERNET_ASYNC_THREAD_FAILED (INTERNET_ERROR_BASE + 47)
     27#define TLS_OUT_OF_INDEXES -1
    2128#else
    2229#include <sys/types.h>
     
    2734#include "internet.h"
    2835
    29 INTERNET_SCHEME GetInternetScheme(LPSTR lpszScheme);
    30 
    3136DEFAULT_DEBUG_CHANNEL(wininet)
     37
     38#define MAX_IDLE_WORKER 1000*60*1
     39#define MAX_WORKER_THREADS 10
     40#define RESPONSE_TIMEOUT 30
     41
     42#define GET_HWININET_FROM_LPWININETFINDNEXT(lpwh)\
     43(LPWININETAPPINFOA)(((LPWININETFTPSESSIONA)(lpwh->hdr.lpwhparent))->hdr.lpwhparent)
     44
     45typedef struct
     46{
     47  DWORD dwError;
     48  CHAR  response[ MAX_REPLY_LEN];
     49} WITHREADERROR, *LPWITHREADERROR;
     50
     51INTERNET_SCHEME GetInternetScheme(LPCSTR lpszScheme, int nMaxCmp);
     52BOOL INTERNET_FindNextFileA(HINTERNET hFind, LPVOID lpFindData);
     53VOID INTERNET_ExecuteWork(void);
     54
     55DWORD g_dwTlsErrIndex = TLS_OUT_OF_INDEXES;
     56LONG  dwNumThreads;
     57LONG  dwNumIdleThreads;
     58HANDLE hEventArray[2];
     59#define hQuitEvent hEventArray[0]
     60#define hWorkEvent hEventArray[1]
     61CRITICAL_SECTION csQueue;
     62LPWORKREQUEST lpHeadWorkQueue;
     63LPWORKREQUEST lpWorkQueueTail;
    3264
    3365/***********************************************************************
     
    4779WININET_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    4880{
    49         TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
    50 
    51         switch (fdwReason) {
    52                 case DLL_PROCESS_ATTACH:
    53                         break;
    54 
    55                 case DLL_PROCESS_DETACH:
    56                         break;
    57         }
    58 
    59         return TRUE;
     81        TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
     82
     83        switch (fdwReason) {
     84                case DLL_PROCESS_ATTACH:
     85                        g_dwTlsErrIndex = TlsAlloc();
     86
     87                        if(g_dwTlsErrIndex == TLS_OUT_OF_INDEXES)
     88                          return FALSE;
     89
     90                        hQuitEvent = CreateEventA(0, TRUE, FALSE, NULL);
     91                        hWorkEvent = CreateEventA(0, FALSE, FALSE, NULL);
     92                        InitializeCriticalSection(&csQueue);
     93
     94                        dwNumThreads=0;
     95                        dwNumIdleThreads=0;
     96
     97                case DLL_THREAD_ATTACH:
     98                    {
     99                      LPWITHREADERROR lpwite = HeapAlloc(GetProcessHeap(), 0, sizeof(WITHREADERROR));
     100
     101                      if (NULL == lpwite)
     102                        return FALSE;
     103
     104                      TlsSetValue(g_dwTlsErrIndex, (LPVOID)lpwite);
     105                    }
     106                    break;
     107
     108                case DLL_THREAD_DETACH:
     109                    if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES)
     110                      {
     111                        LPVOID lpwite = TlsGetValue(g_dwTlsErrIndex);
     112                        if(lpwite)
     113                          HeapFree(GetProcessHeap(), 0, lpwite);
     114                      }
     115                    break;
     116
     117                case DLL_PROCESS_DETACH:
     118                    if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES)
     119                      {
     120                        HeapFree(GetProcessHeap(), 0, TlsGetValue(g_dwTlsErrIndex));
     121                        TlsFree(g_dwTlsErrIndex);
     122                      }
     123
     124                    SetEvent(hQuitEvent);
     125
     126                    CloseHandle(hQuitEvent);
     127                    CloseHandle(hWorkEvent);
     128                    DeleteCriticalSection(&csQueue);
     129                    break;
     130        }
     131
     132        return TRUE;
    60133}
    61134
     
    72145 */
    73146INTERNETAPI HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent,
    74         DWORD dwAccessType, LPCSTR lpszProxy,
    75         LPCSTR lpszProxyBypass, DWORD dwFlags)
    76 {
    77         LPWININETAPPINFOA lpwai = NULL;
    78 
    79         TRACE("\n");
    80 
    81         if (dwFlags & INTERNET_FLAG_ASYNC)
    82         {
    83             FIXME("INTERNET_FLAG_ASYNC not supported\n");
    84         }
    85 
    86         lpwai = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETAPPINFOA));
    87         if (NULL == lpwai)
    88                 SetLastError(ERROR_OUTOFMEMORY);
    89         else
    90         {
    91                 memset(lpwai, 0, sizeof(WININETAPPINFOA));
    92                 lpwai->hdr.htype = WH_HINIT;
    93                 lpwai->hdr.lpwhparent = NULL;
    94                 lpwai->hdr.dwFlags = dwFlags;
    95                 if (NULL != lpszAgent)
    96                         lpwai->lpszAgent = strdup(lpszAgent);
    97                 if (NULL != lpszProxy)
    98                         lpwai->lpszProxy = strdup(lpszProxy);
    99                 if (NULL != lpszProxyBypass)
    100                         lpwai->lpszProxyBypass = strdup(lpszProxyBypass);
    101                 lpwai->dwAccessType = dwAccessType;
    102         }
    103 
    104         return (HINTERNET)lpwai;
     147        DWORD dwAccessType, LPCSTR lpszProxy,
     148        LPCSTR lpszProxyBypass, DWORD dwFlags)
     149{
     150        LPWININETAPPINFOA lpwai = NULL;
     151
     152        TRACE("InternetOpenA\n");
     153
     154        /* Clear any error information */
     155        INTERNET_SetLastError(0);
     156
     157        TRACE("InternetOpenA...\n");
     158
     159        lpwai = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETAPPINFOA));
     160        if (NULL == lpwai)
     161                INTERNET_SetLastError(ERROR_OUTOFMEMORY);
     162        else
     163        {
     164                memset(lpwai, 0, sizeof(WININETAPPINFOA));
     165                lpwai->hdr.htype = WH_HINIT;
     166                lpwai->hdr.lpwhparent = NULL;
     167                lpwai->hdr.dwFlags = dwFlags;
     168                if (NULL != lpszAgent)
     169                        lpwai->lpszAgent = strdup(lpszAgent);
     170                if (NULL != lpszProxy)
     171                        lpwai->lpszProxy = strdup(lpszProxy);
     172                if (NULL != lpszProxyBypass)
     173                        lpwai->lpszProxyBypass = strdup(lpszProxyBypass);
     174                lpwai->dwAccessType = dwAccessType;
     175        }
     176
     177        return (HINTERNET)lpwai;
    105178}
    106179
     
    119192    LPSTR lpszBuffer, LPDWORD lpdwBufferLength)
    120193{
    121     FIXME("stub!\n");
    122     return FALSE;
    123 }
    124 
     194    LPWITHREADERROR lpwite=(LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
     195
     196    *lpdwError = lpwite->dwError;
     197    if (lpwite->dwError)
     198    {
     199      strncpy(lpszBuffer, lpwite->response, *lpdwBufferLength);
     200      *lpdwBufferLength = strlen( lpszBuffer);
     201    }
     202    else
     203      *lpdwBufferLength=0;
     204
     205    return TRUE;
     206}
     207
     208/***********************************************************************
     209 *           InternetGetConnectedState (WININET.105)
     210 *
     211 * Return connected state
     212 *
     213 * RETURNS
     214 *    True if connected
     215 *    if lpdwStatus is not NULL, return the status (off line,
     216 *    modem, lan...) in it.
     217 *    FALSE if not connected
     218 */
     219BOOLAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved)
     220{
     221  FIXME("Stub\n");
     222  return FALSE;
     223}
    125224
    126225/***********************************************************************
     
    139238    DWORD dwService, DWORD dwFlags, DWORD dwContext)
    140239{
    141         HINTERNET rc = (HINTERNET) NULL;
    142 
    143         TRACE("\n");
    144 
    145         /* Clear any error information */
    146         SetLastError(0);
    147 
    148         switch (dwService)
    149         {
    150                 case INTERNET_SERVICE_FTP:
    151                         rc = FTP_Connect(hInternet, lpszServerName, nServerPort,
    152                                 lpszUserName, lpszPassword, dwFlags, dwContext);
    153                         break;
    154 
    155                 case INTERNET_SERVICE_HTTP:
    156                         break;
    157 
    158                 case INTERNET_SERVICE_GOPHER:
    159                 default:
    160                         break;
    161         }
    162 
    163         return rc;
     240        HINTERNET rc = (HINTERNET) NULL;
     241
     242        TRACE("\n");
     243
     244        /* Clear any error information */
     245        INTERNET_SetLastError(0);
     246
     247        switch (dwService)
     248        {
     249                case INTERNET_SERVICE_FTP:
     250                        rc = FTP_Connect(hInternet, lpszServerName, nServerPort,
     251                                lpszUserName, lpszPassword, dwFlags, dwContext);
     252                        break;
     253
     254                case INTERNET_SERVICE_HTTP:
     255                        rc = HTTP_Connect(hInternet, lpszServerName, nServerPort,
     256                        lpszUserName, lpszPassword, dwFlags, dwContext);
     257                        break;
     258
     259                case INTERNET_SERVICE_GOPHER:
     260                default:
     261                        break;
     262        }
     263
     264        return rc;
    164265}
    165266
     
    177278BOOLAPI InternetFindNextFileA(HINTERNET hFind, LPVOID lpvFindData)
    178279{
    179         DWORD access;
    180         LPWIN32_FIND_DATAA lpFindFileData;
    181         LPWININETFINDNEXTA lpwh = (LPWININETFINDNEXTA) hFind;
    182 
    183         TRACE("\n");
    184         if (NULL == lpwh || lpwh->hdr.htype != WH_HFINDNEXT)
    185                 return FALSE;
    186 
    187         if (lpwh->hdr.lpwhparent->htype != WH_HFTPSESSION)
    188         {
    189             FIXME("Only FTP find next supported\n");
    190             return FALSE;
    191         }
    192 
    193         TRACE("index(%d) size(%d)\n", lpwh->index, lpwh->size);
    194         if (lpwh->index >= lpwh->size)
    195         {
    196             SetLastError(ERROR_NO_MORE_FILES);
    197             return FALSE;
    198         }
    199 
    200         lpFindFileData = (LPWIN32_FIND_DATAA) lpvFindData;
    201         access = mktime(&lpwh->lpafp[lpwh->index].tmLastModified);
    202 
    203         /* Not all fields are filled in */
    204         lpFindFileData->ftLastAccessTime.dwHighDateTime = HIWORD(access);
    205         lpFindFileData->ftLastAccessTime.dwLowDateTime  = LOWORD(access);
    206         lpFindFileData->nFileSizeHigh = HIWORD(lpwh->lpafp[lpwh->index].nSize);
    207         lpFindFileData->nFileSizeLow = LOWORD(lpwh->lpafp[lpwh->index].nSize);
    208         if (lpwh->lpafp[lpwh->index].lpszName)
    209                 strncpy(lpFindFileData->cFileName, lpwh->lpafp[lpwh->index].lpszName, MAX_PATH);
    210         lpwh->index++;
    211 
    212         return TRUE;
    213 }
    214 
    215 
    216 /***********************************************************************
    217  *           InternetCloseHandle (WININET.89)
     280        LPWININETAPPINFOA hIC = NULL;
     281        LPWININETFINDNEXTA lpwh = (LPWININETFINDNEXTA) hFind;
     282
     283        TRACE("\n");
     284        if (NULL == lpwh || lpwh->hdr.htype != WH_HFINDNEXT)
     285        {
     286                INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     287                return FALSE;
     288        }
     289
     290        hIC = GET_HWININET_FROM_LPWININETFINDNEXT(lpwh);
     291        if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
     292        {
     293          WORKREQUEST workRequest;
     294
     295          workRequest.asyncall = INTERNETFINDNEXTA;
     296          workRequest.HFTPSESSION = (DWORD)hFind;
     297          workRequest.LPFINDFILEDATA = (DWORD)lpvFindData;
     298
     299          return INTERNET_AsyncCall(&workRequest);
     300        }
     301        else
     302          return INTERNET_FindNextFileA(hFind, lpvFindData);
     303}
     304
     305
     306/***********************************************************************
     307 *           INTERNET_FindNextFileA (Internal)
    218308 *
    219309 * Continues a file search from a previous call to FindFirstFile
     
    224314 *
    225315 */
    226 BOOLAPI InternetCloseHandle(HINTERNET hInternet)
    227 {
    228         BOOL retval = FALSE;
    229         LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hInternet;
    230 
    231         TRACE("\n");
    232         if (NULL == lpwh)
    233                 return FALSE;
    234 
    235         switch (lpwh->htype)
    236         {
    237                 case WH_HINIT:
    238                 case WH_HHTTPSESSION:
    239                 case WH_HHTTPREQ:
    240                         break;
    241                 case WH_HFTPSESSION:
    242                         retval = FTP_CloseSessionHandle((LPWININETFTPSESSIONA) lpwh);
    243                         break;
    244 
    245                 case WH_HFINDNEXT:
    246                         retval = FTP_CloseFindNextHandle((LPWININETFINDNEXTA) lpwh);
    247                         break;
    248 
    249                 default:
    250                         break;
    251         }
    252 
    253         return retval;
    254 }
    255 
    256 
    257 /***********************************************************************
    258  *           InternetCrackUrlA (WININET.95)
    259  *
    260  * Break up URL into its components
     316BOOL INTERNET_FindNextFileA(HINTERNET hFind, LPVOID lpvFindData)
     317{
     318        BOOL bSuccess = TRUE;
     319        LPWININETAPPINFOA hIC = NULL;
     320        LPWIN32_FIND_DATAA lpFindFileData;
     321        LPWININETFINDNEXTA lpwh = (LPWININETFINDNEXTA) hFind;
     322
     323        if (NULL == lpwh || lpwh->hdr.htype != WH_HFINDNEXT)
     324        {
     325            INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     326            return FALSE;
     327        }
     328
     329        /* Clear any error information */
     330        INTERNET_SetLastError(0);
     331
     332        if(lpwh->hdr.lpwhparent->htype != WH_HFTPSESSION)
     333        {
     334          FIXME("Only FTP find next supported\n");
     335          INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     336          return FALSE;
     337        }
     338
     339        lpFindFileData = (LPWIN32_FIND_DATAA) lpvFindData;
     340        memset(lpFindFileData, 0, sizeof(WIN32_FIND_DATAA));
     341
     342        if(lpwh->index >= lpwh->size)
     343        {
     344          INTERNET_SetLastError(ERROR_NO_MORE_FILES);
     345          bSuccess = FALSE;
     346          goto lend;
     347        }
     348
     349        FTP_ConvertFileProp(&lpwh->lpafp[lpwh->index], lpFindFileData);
     350        lpwh->index++;
     351
     352lend:
     353        hIC = GET_HWININET_FROM_LPWININETFINDNEXT(lpwh);
     354        if(hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
     355        {
     356          INTERNET_ASYNC_RESULT iar;
     357
     358          iar.dwResult = (DWORD)bSuccess;
     359          iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
     360
     361          hIC->lpfnStatusCB(hFind, lpwh->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
     362                &iar, sizeof(INTERNET_ASYNC_RESULT));
     363        }
     364
     365        return bSuccess;
     366}
     367
     368
     369/***********************************************************************
     370 *           INTERNET_CloseHandle (Internal)
     371 *
     372 * Closes internet handle
     373 *
     374 * RETURNS
     375 *    void
     376 *
     377 */
     378void INTERNET_CloseHandle(LPWININETAPPINFOA lpwai)
     379{
     380  if(lpwai->lpszAgent)
     381    free(lpwai->lpszAgent);
     382
     383  if(lpwai->lpszProxy)
     384    free(lpwai->lpszProxy);
     385
     386  if(lpwai->lpszProxyBypass)
     387    free(lpwai->lpszProxyBypass);
     388
     389  HeapFree(GetProcessHeap(), 0, lpwai);
     390}
     391
     392/***********************************************************************
     393 *           InternetCloseHandle (WININET.89)
     394 *
     395 * Continues a file search from a previous call to FindFirstFile
    261396 *
    262397 * RETURNS
     
    265400 *
    266401 */
     402BOOLAPI InternetCloseHandle(HINTERNET hInternet)
     403{
     404        BOOL retval = FALSE;
     405        LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hInternet;
     406
     407        TRACE("\n");
     408        if (NULL == lpwh)
     409                return FALSE;
     410
     411        /* Clear any error information */
     412        INTERNET_SetLastError(0);
     413
     414        switch (lpwh->htype)
     415        {
     416                case WH_HINIT:
     417                        INTERNET_CloseHandle((LPWININETAPPINFOA) lpwh);
     418                        retval = TRUE;
     419                        break;
     420
     421                case WH_HHTTPSESSION:
     422                        HTTP_CloseHTTPSessionHandle((LPWININETHTTPSESSIONA) lpwh);
     423                        retval = TRUE;
     424                        break;
     425
     426                case WH_HHTTPREQ:
     427                        HTTP_CloseHTTPRequestHandle((LPWININETHTTPREQA) lpwh);
     428                        retval = TRUE;
     429                        break;
     430
     431                case WH_HFTPSESSION:
     432                        retval = FTP_CloseSessionHandle((LPWININETFTPSESSIONA) lpwh);
     433                        break;
     434
     435                case WH_HFINDNEXT:
     436                        retval = FTP_CloseFindNextHandle((LPWININETFINDNEXTA) lpwh);
     437                        break;
     438
     439                default:
     440                        break;
     441        }
     442
     443        return retval;
     444}
     445
     446/***********************************************************************
     447 *           SetUrlComponentValue (Internal)
     448 *
     449 * Helper function for InternetCrackUrlA
     450 *
     451 * RETURNS
     452 *    TRUE on success
     453 *    FALSE on failure
     454 *
     455 */
     456BOOL SetUrlComponentValue(LPSTR* lppszComponent, LPDWORD dwComponentLen, LPCSTR lpszStart, INT len)
     457{
     458    TRACE("%s (%d)\n", lpszStart, len);
     459
     460    if (*dwComponentLen != 0)
     461    {
     462       if (*lppszComponent == NULL)
     463       {
     464             *lppszComponent = (LPSTR)lpszStart;
     465             *dwComponentLen = len;
     466         }
     467         else
     468         {
     469            INT ncpylen = min((*dwComponentLen)-1, len);
     470            strncpy(*lppszComponent, lpszStart, ncpylen);
     471            (*lppszComponent)[ncpylen] = '\0';
     472            *dwComponentLen = ncpylen;
     473        }
     474    }
     475
     476    return TRUE;
     477}
     478
     479
     480/***********************************************************************
     481 *           InternetCrackUrlA (WININET.95)
     482 *
     483 * Break up URL into its components
     484 *
     485 * RETURNS
     486 *    TRUE on success
     487 *    FALSE on failure
     488 *
     489 */
    267490BOOLAPI InternetCrackUrlA(LPCSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags,
    268                 LPURL_COMPONENTSA lpUrlComponents)
     491                LPURL_COMPONENTSA lpUrlComponents)
    269492{
    270493  /*
     
    273496   *
    274497   */
    275         char* szScheme   = NULL;
    276         char* szUser     = NULL;
    277         char* szPass     = NULL;
    278         char* szHost     = NULL;
    279         char* szUrlPath  = NULL;
    280         char* szParam    = NULL;
    281         char* szNetLoc   = NULL;
    282         int   nPort      = 80;
    283         int   nSchemeLen = 0;
    284         int   nUserLen   = 0;
    285         int   nPassLen   = 0;
    286         int   nHostLen   = 0;
    287         int   nUrlLen    = 0;
    288 
    289   // Find out if the URI is absolute...
    290   BOOL  bIsAbsolute = FALSE;
    291   char  cAlphanum;
    292   char* ap = (char*)lpszUrl;
    293   char* cp = NULL;
    294 
    295         TRACE("\n");
    296   while( (cAlphanum = *ap) != '\0' )
    297   {
    298     if( ((cAlphanum >= 'a') && (cAlphanum <= 'z')) ||
    299         ((cAlphanum >= 'A') && (cAlphanum <= 'Z')) ||
    300         ((cAlphanum >= '0') && (cAlphanum <= '9')) )
    301     {
    302       ap++;
    303       continue;
    304     }
    305     if( (cAlphanum == ':') && (ap - lpszUrl >= 2) )
    306     {
    307       bIsAbsolute = TRUE;
    308       cp = ap;
     498   LPSTR lpszParam    = NULL;
     499   BOOL  bIsAbsolute = FALSE;
     500   LPSTR lpszap = (char*)lpszUrl;
     501   LPSTR lpszcp = NULL;
     502
     503   TRACE("\n");
     504
     505   /* Determine if the URI is absolute. */
     506   while (*lpszap != '\0')
     507   {
     508      if (isalnum(*lpszap))
     509      {
     510           lpszap++;
     511           continue;
     512      }
     513      if ((*lpszap == ':') && (lpszap - lpszUrl >= 2))
     514      {
     515           bIsAbsolute = TRUE;
     516           lpszcp = lpszap;
     517      }
     518      else
     519      {
     520           lpszcp = (LPSTR)lpszUrl; /* Relative url */
     521      }
     522
    309523      break;
    310     }
    311     break;
    312   }
    313 
    314   // Absolute URI...
    315   //FIXME!!!! This should work on relative urls too!
    316   if( bIsAbsolute )
    317   {
    318     // Get scheme first...
    319     nSchemeLen = cp - lpszUrl;
    320     szScheme   = strdup( lpszUrl );
    321     szScheme[ nSchemeLen ] = '\0';
    322 
    323     // Eat ':' in protocol...
    324     cp++;
    325 
    326     // Parse <params>...
    327     szParam = strpbrk( lpszUrl, ";" );
    328     if( szParam != NULL )
    329     {
    330        char* sParam;
    331        // Eat ';' in Params...
    332        szParam++;
    333        sParam    = strdup( szParam );
    334        *szParam = '\0';
     524   }
     525
     526   /* Parse <params> */
     527   lpszParam = strpbrk(lpszap, ";?");
     528   if (lpszParam != NULL)
     529   {
     530         if (!SetUrlComponentValue(&lpUrlComponents->lpszExtraInfo,
     531              &lpUrlComponents->dwExtraInfoLength, lpszParam+1, strlen(lpszParam+1)))
     532         {
     533            return FALSE;
     534         }
     535   }
     536
     537   if (bIsAbsolute) /* Parse <protocol>:[//<net_loc>] */
     538   {
     539     LPSTR lpszNetLoc;
     540
     541     /* Get scheme first. */
     542     lpUrlComponents->nScheme = GetInternetScheme(lpszUrl, lpszcp - lpszUrl);
     543     if (!SetUrlComponentValue(&lpUrlComponents->lpszScheme,
     544                 &lpUrlComponents->dwSchemeLength, lpszUrl, lpszcp - lpszUrl))
     545         return FALSE;
     546
     547     /* Eat ':' in protocol. */
     548     lpszcp++;
     549
     550     /* Skip over slashes. */
     551     if (*lpszcp == '/')
     552     {
     553            lpszcp++;
     554            if (*lpszcp == '/')
     555            {
     556                  lpszcp++;
     557                  if (*lpszcp == '/')
     558                      lpszcp++;
     559            }
    335560     }
    336561
    337      // Skip over slashes...
    338      if( *cp == '/' )
     562     lpszNetLoc = strpbrk(lpszcp, "/");
     563     if (lpszParam)
    339564     {
    340       cp++;
    341       if( *cp == '/' )
    342       {
    343         cp++;
    344         if( *cp == '/' )
    345           cp++;
    346       }
     565           if (lpszNetLoc)
     566              lpszNetLoc = min(lpszNetLoc, lpszParam);
     567       else
     568              lpszNetLoc = lpszParam;
    347569     }
    348 
    349      // Parse the <net-loc>...
    350      if( GetInternetScheme( szScheme ) == INTERNET_SCHEME_FILE )
     570     else if (!lpszNetLoc)
     571          lpszNetLoc = lpszcp + strlen(lpszcp);
     572
     573     /* Parse net-loc */
     574     if (lpszNetLoc)
    351575     {
    352       szUrlPath = strdup( cp );
    353       nUrlLen   = strlen( szUrlPath );
    354       if( nUrlLen >= 2 && szUrlPath[ 1 ] == '|' )
    355         szUrlPath[ 1 ] = ':';
     576           LPSTR lpszHost;
     577           LPSTR lpszPort;
     578
     579           /* [<user>[<:password>]@]<host>[:<port>] */
     580           /* First find the user and password if they exist */
     581
     582           lpszHost = strchr(lpszcp, '@');
     583           if (lpszHost == NULL || lpszHost > lpszNetLoc)
     584           {
     585             /* username and password not specified. */
     586             SetUrlComponentValue(&lpUrlComponents->lpszUserName,
     587                     &lpUrlComponents->dwUserNameLength, NULL, 0);
     588             SetUrlComponentValue(&lpUrlComponents->lpszPassword,
     589                     &lpUrlComponents->dwPasswordLength, NULL, 0);
     590           }
     591           else /* Parse out username and password */
     592           {
     593               LPSTR lpszUser = lpszcp;
     594               LPSTR lpszPasswd = lpszHost;
     595
     596               while (lpszcp < lpszHost)
     597               {
     598                    if (*lpszcp == ':')
     599                        lpszPasswd = lpszcp;
     600
     601                    lpszcp++;
     602               }
     603
     604               SetUrlComponentValue(&lpUrlComponents->lpszUserName,
     605                         &lpUrlComponents->dwUserNameLength, lpszUser, lpszPasswd - lpszUser);
     606
     607               SetUrlComponentValue(&lpUrlComponents->lpszPassword,
     608                         &lpUrlComponents->dwPasswordLength,
     609                         lpszPasswd == lpszHost ? NULL : ++lpszPasswd,
     610                         lpszHost - lpszPasswd);
     611
     612               lpszcp++; /* Advance to beginning of host */
     613           }
     614
     615             /* Parse <host><:port> */
     616
     617           lpszHost = lpszcp;
     618           lpszPort = lpszNetLoc;
     619
     620           while (lpszcp < lpszNetLoc)
     621           {
     622             if (*lpszcp == ':')
     623                 lpszPort = lpszcp;
     624
     625             lpszcp++;
     626           }
     627
     628           SetUrlComponentValue(&lpUrlComponents->lpszHostName,
     629                &lpUrlComponents->dwHostNameLength, lpszHost, lpszPort - lpszHost);
     630
     631           if (lpszPort != lpszNetLoc)
     632             lpUrlComponents->nPort = atoi(++lpszPort);
    356633     }
    357      else
    358      {
    359       size_t nNetLocLen;
    360       szUrlPath = strpbrk(cp, "/");
    361       if( szUrlPath != NULL )
    362         nUrlLen = strlen( szUrlPath );
    363 
    364       // Find the end of our net-loc...
    365       nNetLocLen = strcspn( cp, "/" );
    366       szNetLoc   = strdup( cp );
    367       szNetLoc[ nNetLocLen ] = '\0';
    368 
    369       if( szNetLoc != NULL )
    370       {
    371         char* lpszPort;
    372         int   nPortLen;
    373         // [<user>[<:password>]@]<host>[:<port>]
    374         // First find the user and password if they exist...
    375 
    376         szHost = strchr( szNetLoc, '@' );
    377         if( szHost == NULL )
    378         {
    379                 // username and password not specified...
    380                 szHost   = szNetLoc;
    381                 nHostLen = nNetLocLen;
    382         }
    383         else
    384         {
    385                 int   nUserPassLen = nNetLocLen - nHostLen - 1;
    386                 char* szUserPass         = strdup( szNetLoc );
    387                 // Get username and/or password...
    388                 // Eat '@' in domain...
    389                 ++szHost;
    390                 nHostLen = strlen( szHost );
    391 
    392                 szUserPass[ nUserPassLen ] = '\0';
    393                 if( szUserPass != NULL )
    394                 {
    395                         szPass = strpbrk( szUserPass, ":" );
    396                         if( szPass != NULL )
    397                         {
    398                                 // Eat ':' in UserPass...
    399                                 ++szPass;
    400                                 nPassLen = strlen( szPass );
    401                                         nUserLen = nUserPassLen - nPassLen - 1;
    402                                 szUser   = strdup( szUserPass );
    403                                 szUser[ nUserLen ] = '\0';
    404                         }
    405                         else
    406                         {
    407                                 // password not specified...
    408                                 szUser = strdup( szUserPass );
    409                                 nUserLen = strlen( szUser );
    410                         }
    411                 }
    412         }
    413 
    414         // <host><:port>...
    415         // Then get the port if it exists...
    416         lpszPort = strpbrk( szHost, ":" );
    417         nPortLen = 0;
    418         if( lpszPort != NULL )
    419         {
    420                 char* szPort = lpszPort + 1;
    421                 if( szPort != NULL )
    422                 {
    423                         nPortLen = strlen( szPort );
    424                         nPort    = atoi( szPort );
    425                 }
    426                 *lpszPort = '\0';
    427                 nHostLen = strlen(szHost);
    428         }
    429       }
    430     }
    431   }
    432   // Relative URI...
    433   else
    434       return FALSE;
    435 
    436   return TRUE;
     634   }
     635
     636 /* Here lpszcp points to:
     637  *
     638  * <protocol>:[//<net_loc>][/path][;<params>][?<query>][#<fragment>]
     639  *                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     640  */
     641   if (lpszcp != 0 && *lpszcp != '\0' && (!lpszParam || lpszcp < lpszParam))
     642   {
     643       INT len;
     644
     645       /* Only truncate the parameter list if it's already been saved
     646        * in lpUrlComponents->lpszExtraInfo.
     647        */
     648       if (lpszParam && lpUrlComponents->dwExtraInfoLength)
     649           len = lpszParam - lpszcp;
     650       else
     651       {
     652             /* Leave the parameter list in lpszUrlPath.  Strip off any trailing
     653              * newlines if necessary.
     654              */
     655             LPSTR lpsznewline = strchr (lpszcp, '\n');
     656             if (lpsznewline != NULL)
     657                 len = lpsznewline - lpszcp;
     658             else
     659                 len = strlen(lpszcp);
     660        }
     661
     662        if (!SetUrlComponentValue(&lpUrlComponents->lpszUrlPath,
     663               &lpUrlComponents->dwUrlPathLength, lpszcp, len))
     664          return FALSE;
     665   }
     666   else
     667   {
     668        lpUrlComponents->dwUrlPathLength = 0;
     669   }
     670
     671   TRACE("%s: host(%s) path(%s) extra(%s)\n", lpszUrl, lpUrlComponents->lpszHostName,
     672          lpUrlComponents->lpszUrlPath, lpUrlComponents->lpszExtraInfo);
     673
     674   return TRUE;
    437675}
    438676
     
    456694
    457695/***********************************************************************
     696 *           InternetCanonicalizeUrlA (WININET.85)
     697 *
     698 * Escape unsafe characters and spaces
     699 *
     700 * RETURNS
     701 *    TRUE on success
     702 *    FALSE on failure
     703 *
     704 */
     705BOOLAPI InternetCanonicalizeUrlA(LPCSTR lpszUrl, LPSTR lpszBuffer,
     706        LPDWORD lpdwBufferLength, DWORD dwFlags)
     707{
     708  BOOL bSuccess = FALSE;
     709
     710  FIXME("Stub\n");
     711
     712  if(lpszUrl)
     713  {
     714    strncpy(lpszBuffer, lpszUrl, *lpdwBufferLength);
     715    *lpdwBufferLength = strlen(lpszUrl);
     716    bSuccess = TRUE;
     717  }
     718
     719  return bSuccess;
     720}
     721
     722/***********************************************************************
    458723 *           InternetSetStatusCallback (WININET.133)
    459724 *
     
    462727 *
    463728 * RETURNS
    464  *    Previous callback or NULL         on success
     729 *    Previous callback or NULL         on success
    465730 *    INTERNET_INVALID_STATUS_CALLBACK  on failure
    466731 *
    467732 */
    468733INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallback(
    469         HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB)
    470 {
    471         INTERNET_STATUS_CALLBACK retVal;
    472         LPWININETAPPINFOA lpwai = (LPWININETAPPINFOA)hInternet;
    473 
    474         TRACE("\n");
    475         if (lpwai->hdr.htype != WH_HINIT)
    476                 return INTERNET_INVALID_STATUS_CALLBACK;
    477 
    478         retVal = lpwai->lpfnStatusCB;
    479         lpwai->lpfnStatusCB = lpfnIntCB;
    480 
    481         return retVal;
     734        HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB)
     735{
     736        INTERNET_STATUS_CALLBACK retVal;
     737        LPWININETAPPINFOA lpwai = (LPWININETAPPINFOA)hInternet;
     738
     739        TRACE("\n");
     740        if (lpwai->hdr.htype != WH_HINIT)
     741                return INTERNET_INVALID_STATUS_CALLBACK;
     742
     743        retVal = lpwai->lpfnStatusCB;
     744        lpwai->lpfnStatusCB = lpfnIntCB;
     745
     746        return retVal;
    482747}
    483748
     
    494759 */
    495760BOOLAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer ,
    496         DWORD dwNumOfBytesToWrite, LPDWORD lpdwNumOfBytesWritten)
    497 {
    498         BOOL retval = FALSE;
    499         int nSocket = INVALID_SOCKET;
    500         LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
    501 
    502         TRACE("\n");
    503         if (NULL == lpwh)
    504                 return FALSE;
    505 
    506         switch (lpwh->htype)
    507         {
    508                 case WH_HHTTPREQ:
    509                         nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
    510                         break;
    511 
    512                 case WH_HFILE:
    513                         nSocket = ((LPWININETFILE)hFile)->nDataSocket;
    514                         break;
    515 
    516                 default:
    517                         break;
    518         }
    519 
    520         if (INVALID_SOCKET != nSocket)
    521         {
    522                 *lpdwNumOfBytesWritten = WriteDataToStream(nSocket, lpBuffer, dwNumOfBytesToWrite);
    523                 if (*lpdwNumOfBytesWritten < 0)
    524                         *lpdwNumOfBytesWritten = 0;
    525                 else
    526                         retval = TRUE;
    527         }
    528 
    529         return retval;
     761        DWORD dwNumOfBytesToWrite, LPDWORD lpdwNumOfBytesWritten)
     762{
     763        BOOL retval = FALSE;
     764        int nSocket = INVALID_SOCKET;
     765        int nBytesWritten;
     766        LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
     767
     768        TRACE("\n");
     769        if (NULL == lpwh)
     770                return FALSE;
     771
     772        switch (lpwh->htype)
     773        {
     774                case WH_HHTTPREQ:
     775                        nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
     776                        break;
     777
     778                case WH_HFILE:
     779                        nSocket = ((LPWININETFILE)hFile)->nDataSocket;
     780                        break;
     781
     782                default:
     783                        break;
     784        }
     785
     786        if (INVALID_SOCKET != nSocket)
     787        {
     788                nBytesWritten = INTERNET_WriteDataToStream(nSocket, lpBuffer, dwNumOfBytesToWrite);
     789                if (nBytesWritten < 0)
     790                        *lpdwNumOfBytesWritten = 0;
     791                else
     792                {
     793                        *lpdwNumOfBytesWritten = nBytesWritten;
     794                        retval = TRUE;
     795                }
     796        }
     797
     798        return retval;
    530799}
    531800
     
    542811 */
    543812BOOLAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
    544         DWORD dwNumOfBytesToRead, LPDWORD dwNumOfBytesRead)
    545 {
    546         BOOL retval = FALSE;
    547         int nSocket = INVALID_SOCKET;
    548         LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
    549 
    550         TRACE("\n");
    551         if (NULL == lpwh)
    552                 return FALSE;
    553 
    554         switch (lpwh->htype)
    555         {
    556                 case WH_HHTTPREQ:
    557                         nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
    558                         break;
    559 
    560                 case WH_HFILE:
    561                         nSocket = ((LPWININETFILE)hFile)->nDataSocket;
    562                         break;
    563 
    564                 default:
    565                         break;
    566         }
    567 
    568         if (INVALID_SOCKET != nSocket)
    569         {
    570                 *dwNumOfBytesRead = ReadDataFromStream(nSocket, lpBuffer, dwNumOfBytesToRead);
    571                 if (*dwNumOfBytesRead < 0)
    572                         *dwNumOfBytesRead = 0;
    573                 else
    574                         retval = TRUE;
    575         }
    576 
    577         return retval;
     813        DWORD dwNumOfBytesToRead, LPDWORD dwNumOfBytesRead)
     814{
     815        BOOL retval = FALSE;
     816        int nBytesRead;
     817        int nSocket = INVALID_SOCKET;
     818        LONG *lpBytesAvailable = 0;
     819        LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
     820
     821        TRACE("\n");
     822        if (NULL == lpwh)
     823                return FALSE;
     824
     825        switch (lpwh->htype)
     826        {
     827                case WH_HHTTPREQ:
     828                        nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
     829                        break;
     830
     831                case WH_HFILE:
     832                        nSocket = ((LPWININETFILE)hFile)->nDataSocket;
     833                        lpBytesAvailable = &(((LPWININETFILE)hFile)->lBytesAvailable);
     834                        break;
     835
     836                default:
     837                        break;
     838        }
     839
     840        if (INVALID_SOCKET != nSocket)
     841        {
     842                nBytesRead = INTERNET_ReadDataFromStream(nSocket, lpBuffer, dwNumOfBytesToRead);
     843                if (nBytesRead < 0)
     844                        *dwNumOfBytesRead = 0;
     845                else
     846                {
     847                        *dwNumOfBytesRead = nBytesRead;
     848                        retval = TRUE;
     849                }
     850        }
     851
     852        if(lpBytesAvailable)
     853          *lpBytesAvailable -= *dwNumOfBytesRead;
     854
     855        return retval;
     856}
     857
     858/***********************************************************************
     859 *           InternetQueryOptionA
     860 *
     861 * Queries an options on the specified handle
     862 *
     863 * RETURNS
     864 *    TRUE  on success
     865 *    FALSE on failure
     866 *
     867 */
     868BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD dwOption,
     869        LPVOID lpBuffer, LPDWORD lpdwBufferLength)
     870{
     871    LPWININETHANDLEHEADER lpwhh;
     872    BOOL bSuccess = FALSE;
     873
     874    TRACE("0x%08lx\n", dwOption);
     875
     876    if (NULL == hInternet)
     877    {
     878        INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     879        return FALSE;
     880    }
     881
     882    lpwhh = (LPWININETHANDLEHEADER) hInternet;
     883
     884    switch (dwOption)
     885    {
     886       case INTERNET_OPTION_HANDLE_TYPE:
     887       {
     888         ULONG type = lpwhh->htype;
     889         TRACE("INTERNET_OPTION_HANDLE_TYPE: %ld\n", type);
     890
     891         if (*lpdwBufferLength < sizeof(ULONG))
     892            INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
     893         else
     894         {
     895             memcpy(lpBuffer, &type, sizeof(ULONG));
     896             *lpdwBufferLength = sizeof(ULONG);
     897             bSuccess = TRUE;
     898         }
     899
     900         break;
     901       }
     902
     903       default:
     904         FIXME("Stub!");
     905         break;
     906    }
     907
     908    return bSuccess;
    578909}
    579910
     
    589920 *
    590921 */
    591 INTERNET_SCHEME GetInternetScheme(LPSTR lpszScheme)
     922INTERNET_SCHEME GetInternetScheme(LPCSTR lpszScheme, int nMaxCmp)
    592923{
    593924  if(lpszScheme==NULL)
    594         return INTERNET_SCHEME_UNKNOWN;
    595 
    596   if( (strcmp("ftp", lpszScheme) == 0) ||
    597                   (strcmp("FTP", lpszScheme) == 0) )
     925        return INTERNET_SCHEME_UNKNOWN;
     926
     927  if( (strncasecmp("ftp", lpszScheme, nMaxCmp) == 0))
    598928    return INTERNET_SCHEME_FTP;
    599929
    600   else if( (strcmp("gopher", lpszScheme) == 0) ||
    601                        (strcmp("GOPHER", lpszScheme) == 0) )
     930  else if( (strncasecmp("gopher", lpszScheme, nMaxCmp) == 0))
    602931    return INTERNET_SCHEME_GOPHER;
    603932
    604   else if( (strcmp("http", lpszScheme) == 0) ||
    605                        (strcmp("HTTP", lpszScheme) == 0) )
     933  else if( (strncasecmp("http", lpszScheme, nMaxCmp) == 0))
    606934    return INTERNET_SCHEME_HTTP;
    607935
    608   else if( (strcmp("https", lpszScheme) == 0) ||
    609                        (strcmp("HTTPS", lpszScheme) == 0) )
     936  else if( (strncasecmp("https", lpszScheme, nMaxCmp) == 0))
    610937    return INTERNET_SCHEME_HTTPS;
    611938
    612   else if( (strcmp("file", lpszScheme) == 0) ||
    613                        (strcmp("FILE", lpszScheme) == 0) )
     939  else if( (strncasecmp("file", lpszScheme, nMaxCmp) == 0))
    614940    return INTERNET_SCHEME_FILE;
    615941
    616   else if( (strcmp("news", lpszScheme) == 0) ||
    617                        (strcmp("NEWS", lpszScheme) == 0) )
     942  else if( (strncasecmp("news", lpszScheme, nMaxCmp) == 0))
    618943    return INTERNET_SCHEME_NEWS;
    619944
    620   else if( (strcmp("mailto", lpszScheme) == 0) ||
    621                        (strcmp("MAILTO", lpszScheme) == 0) )
     945  else if( (strncasecmp("mailto", lpszScheme, nMaxCmp) == 0))
    622946    return INTERNET_SCHEME_MAILTO;
    623 
    624947  else
    625948    return INTERNET_SCHEME_UNKNOWN;
    626949}
    627950
     951/***********************************************************************
     952 *           InternetCheckConnectionA
     953 *
     954 * Pings a requested host to check internet connection
     955 *
     956 * RETURNS
     957 *      TRUE on success and FALSE on failure.
     958 * On failure ERROR_NOT_CONNECTED is placed into GetLastError
     959 */
     960BOOLAPI InternetCheckConnectionA( LPCSTR lpszUrl, DWORD dwFlags, DWORD dwReserved)
     961{
     962  /* Instead of WINE's shelling out and executing a 'ping' we'll use the */
     963  /* ICMP.DLL instead.                                                   */
     964  DWORD rc=0;
     965  HANDLE hIcmp;
     966  char RequestBuffer[]="Odin - PING request, please reply...";
     967  char lpszHost[1024],ReplyBuffer[256];
     968  URL_COMPONENTSA UrlComponents;
     969  ULONG dest_addr;
     970  struct hostent *host;
     971
     972  if(!lpszUrl)
     973  {
     974    FIXME("Unimplemented with URL of NULL\n");
     975    return TRUE;
     976  }
     977
     978  memset(&UrlComponents, 0, sizeof(URL_COMPONENTSA));
     979
     980  UrlComponents.lpszHostName = lpszHost;
     981  UrlComponents.dwHostNameLength = 1024;
     982
     983  if(!InternetCrackUrlA(lpszUrl, 0, 0, &UrlComponents))
     984  {
     985      INTERNET_SetLastError(ERROR_NOT_CONNECTED);
     986      return FALSE;
     987  }
     988
     989  hIcmp = IcmpCreateFile();
     990
     991  if(!hIcmp)
     992    {
     993      INTERNET_SetLastError(ERROR_NOT_CONNECTED);
     994      return FALSE;
     995    }
     996
     997  dest_addr = inet_addr(lpszHost);
     998
     999  if(dest_addr == 0)
     1000    host = gethostbyname(lpszHost);
     1001  else
     1002    host = gethostbyaddr(lpszHost, strlen(lpszHost), PF_INET);
     1003
     1004  if(host->h_addr)
     1005    rc=IcmpSendEcho(hIcmp,
     1006                    (IPAddr)host->h_addr,
     1007                    RequestBuffer,
     1008                    strlen(RequestBuffer),
     1009                    NULL,
     1010                    ReplyBuffer,
     1011                    256,
     1012                    5000);
     1013  else
     1014    rc = 0;
     1015
     1016  IcmpCloseHandle(hIcmp);
     1017
     1018  return rc>0;
     1019}
    6281020
    6291021/***********************************************************************
     
    6371029 *   -1 on error
    6381030 */
    639 int WriteDataToStream(int nDataSocket, LPCVOID Buffer, DWORD BytesToWrite)
    640 {
    641         if (INVALID_SOCKET == nDataSocket)
    642             return SOCKET_ERROR;
    643 
    644         return send(nDataSocket, Buffer, BytesToWrite, 0);
    645 }
    646 
    647 
    648 /***********************************************************************
    649  *           ReadDataFromStream (internal)
     1031int INTERNET_WriteDataToStream(int nDataSocket, LPCVOID Buffer, DWORD BytesToWrite)
     1032{
     1033        if (INVALID_SOCKET == nDataSocket)
     1034            return SOCKET_ERROR;
     1035
     1036        return send(nDataSocket, Buffer, BytesToWrite, 0);
     1037}
     1038
     1039
     1040/***********************************************************************
     1041 *           INTERNET_ReadDataFromStream (internal)
    6501042 *
    6511043 * Read data from http server
     
    6561048 *   -1 on error
    6571049 */
    658 int ReadDataFromStream(int nDataSocket, LPVOID Buffer, DWORD BytesToRead)
    659 {
    660         if (INVALID_SOCKET == nDataSocket)
    661             return SOCKET_ERROR;
    662 
    663         return recv(nDataSocket, Buffer, BytesToRead, 0);
    664 }
     1050int INTERNET_ReadDataFromStream(int nDataSocket, LPVOID Buffer, DWORD BytesToRead)
     1051{
     1052        if (INVALID_SOCKET == nDataSocket)
     1053            return SOCKET_ERROR;
     1054
     1055        return recv(nDataSocket, Buffer, BytesToRead, 0);
     1056}
     1057
     1058
     1059/***********************************************************************
     1060 *           INTERNET_SetLastError (internal)
     1061 *
     1062 * Set last thread specific error
     1063 *
     1064 * RETURNS
     1065 *
     1066 */
     1067void INTERNET_SetLastError(DWORD dwError)
     1068{
     1069    LPWITHREADERROR lpwite;
     1070
     1071    lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
     1072
     1073    SetLastError(dwError);
     1074    lpwite->dwError = dwError;
     1075}
     1076
     1077
     1078/************************************************************************
     1079 *           INTERNET_GetLastError (internal)
     1080 *
     1081 * Get last thread specific error
     1082 *
     1083 * RETURNS
     1084 *
     1085 */
     1086DWORD INTERNET_GetLastError()
     1087{
     1088    LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
     1089    return lpwite->dwError;
     1090}
     1091
     1092
     1093/************************************************************************
     1094 *           INTERNET_WorkerThreadFunc (internal)
     1095 *
     1096 * Worker thread execution function
     1097 *
     1098 * RETURNS
     1099 *
     1100 */
     1101DWORD INTERNET_WorkerThreadFunc(LPVOID *lpvParam)
     1102{
     1103    DWORD dwWaitRes;
     1104
     1105    while (1)
     1106    {
     1107        dwWaitRes = WaitForMultipleObjects(2, hEventArray, FALSE, MAX_IDLE_WORKER);
     1108
     1109        if (dwWaitRes == WAIT_OBJECT_0 + 1)
     1110            INTERNET_ExecuteWork();
     1111        else
     1112            break;
     1113
     1114        InterlockedIncrement(&dwNumIdleThreads);
     1115    }
     1116
     1117    InterlockedDecrement(&dwNumIdleThreads);
     1118    InterlockedDecrement(&dwNumThreads);
     1119    TRACE("Worker thread exiting\n");
     1120    return TRUE;
     1121}
     1122
     1123
     1124/************************************************************************
     1125 *           INTERNET_InsertWorkRequest (internal)
     1126 *
     1127 * Insert work request into queue
     1128 *
     1129 * RETURNS
     1130 *
     1131 */
     1132BOOL INTERNET_InsertWorkRequest(LPWORKREQUEST lpWorkRequest)
     1133{
     1134    BOOL bSuccess = FALSE;
     1135    LPWORKREQUEST lpNewRequest;
     1136
     1137    TRACE("\n");
     1138
     1139    lpNewRequest = HeapAlloc(GetProcessHeap(), 0, sizeof(WORKREQUEST));
     1140    if (lpNewRequest)
     1141    {
     1142        memcpy(lpNewRequest, lpWorkRequest, sizeof(WORKREQUEST));
     1143        lpNewRequest->prev = NULL;
     1144
     1145        EnterCriticalSection(&csQueue);
     1146
     1147        lpNewRequest->next = lpWorkQueueTail;
     1148        if (lpWorkQueueTail)
     1149            lpWorkQueueTail->prev = lpNewRequest;
     1150        lpWorkQueueTail = lpNewRequest;
     1151        if (!lpHeadWorkQueue)
     1152            lpHeadWorkQueue = lpWorkQueueTail;
     1153
     1154        LeaveCriticalSection(&csQueue);
     1155
     1156        bSuccess = TRUE;
     1157    }
     1158
     1159    return bSuccess;
     1160}
     1161
     1162
     1163/************************************************************************
     1164 *           INTERNET_GetWorkRequest (internal)
     1165 *
     1166 * Retrieves work request from queue
     1167 *
     1168 * RETURNS
     1169 *
     1170 */
     1171BOOL INTERNET_GetWorkRequest(LPWORKREQUEST lpWorkRequest)
     1172{
     1173    BOOL bSuccess = FALSE;
     1174    LPWORKREQUEST lpRequest = NULL;
     1175
     1176    TRACE("\n");
     1177
     1178    EnterCriticalSection(&csQueue);
     1179
     1180    if (lpHeadWorkQueue)
     1181    {
     1182        lpRequest = lpHeadWorkQueue;
     1183        lpHeadWorkQueue = lpHeadWorkQueue->prev;
     1184        if (lpRequest == lpWorkQueueTail)
     1185            lpWorkQueueTail = lpHeadWorkQueue;
     1186    }
     1187
     1188    LeaveCriticalSection(&csQueue);
     1189
     1190    if (lpRequest)
     1191    {
     1192        memcpy(lpWorkRequest, lpRequest, sizeof(WORKREQUEST));
     1193        HeapFree(GetProcessHeap(), 0, lpRequest);
     1194        bSuccess = TRUE;
     1195    }
     1196
     1197    return bSuccess;
     1198}
     1199
     1200
     1201/************************************************************************
     1202 *           INTERNET_AsyncCall (internal)
     1203 *
     1204 * Retrieves work request from queue
     1205 *
     1206 * RETURNS
     1207 *
     1208 */
     1209BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest)
     1210{
     1211    HANDLE hThread;
     1212    DWORD dwTID;
     1213    BOOL bSuccess = FALSE;
     1214
     1215    TRACE("\n");
     1216
     1217    if (InterlockedDecrement(&dwNumIdleThreads) < 0)
     1218    {
     1219        InterlockedIncrement(&dwNumIdleThreads);
     1220
     1221        if (InterlockedIncrement(&dwNumThreads) > MAX_WORKER_THREADS ||
     1222            !(hThread = CreateThread(NULL, 0,
     1223            (LPTHREAD_START_ROUTINE)INTERNET_WorkerThreadFunc, NULL, 0, &dwTID)))
     1224        {
     1225            InterlockedDecrement(&dwNumThreads);
     1226            INTERNET_SetLastError(ERROR_INTERNET_ASYNC_THREAD_FAILED);
     1227            goto lerror;
     1228        }
     1229
     1230        TRACE("Created new thread\n");
     1231    }
     1232
     1233    bSuccess = TRUE;
     1234    INTERNET_InsertWorkRequest(lpWorkRequest);
     1235    SetEvent(hWorkEvent);
     1236
     1237lerror:
     1238
     1239    return bSuccess;
     1240}
     1241
     1242
     1243/************************************************************************
     1244 *           INTERNET_ExecuteWork (internal)
     1245 *
     1246 * RETURNS
     1247 *
     1248 */
     1249VOID INTERNET_ExecuteWork()
     1250{
     1251    WORKREQUEST workRequest;
     1252
     1253    TRACE("\n");
     1254
     1255    if (INTERNET_GetWorkRequest(&workRequest))
     1256    {
     1257        switch (workRequest.asyncall)
     1258        {
     1259            case FTPPUTFILEA:
     1260                FTP_FtpPutFileA((HINTERNET)workRequest.HFTPSESSION, (LPCSTR)workRequest.LPSZLOCALFILE,
     1261                    (LPCSTR)workRequest.LPSZNEWREMOTEFILE, workRequest.DWFLAGS, workRequest.DWCONTEXT);
     1262                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZLOCALFILE);
     1263                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZNEWREMOTEFILE);
     1264                break;
     1265
     1266            case FTPSETCURRENTDIRECTORYA:
     1267                FTP_FtpSetCurrentDirectoryA((HINTERNET)workRequest.HFTPSESSION,
     1268                        (LPCSTR)workRequest.LPSZDIRECTORY);
     1269                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZDIRECTORY);
     1270                break;
     1271
     1272            case FTPCREATEDIRECTORYA:
     1273                FTP_FtpCreateDirectoryA((HINTERNET)workRequest.HFTPSESSION,
     1274                        (LPCSTR)workRequest.LPSZDIRECTORY);
     1275                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZDIRECTORY);
     1276                break;
     1277
     1278            case FTPFINDFIRSTFILEA:
     1279                FTP_FtpFindFirstFileA((HINTERNET)workRequest.HFTPSESSION,
     1280                        (LPCSTR)workRequest.LPSZSEARCHFILE,
     1281                   (LPWIN32_FIND_DATAA)workRequest.LPFINDFILEDATA, workRequest.DWFLAGS,
     1282                   workRequest.DWCONTEXT);
     1283                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZSEARCHFILE);
     1284                break;
     1285
     1286            case FTPGETCURRENTDIRECTORYA:
     1287                FTP_FtpGetCurrentDirectoryA((HINTERNET)workRequest.HFTPSESSION,
     1288                        (LPSTR)workRequest.LPSZDIRECTORY, (LPDWORD)workRequest.LPDWDIRECTORY);
     1289                break;
     1290
     1291            case FTPOPENFILEA:
     1292                 FTP_FtpOpenFileA((HINTERNET)workRequest.HFTPSESSION,
     1293                    (LPCSTR)workRequest.LPSZFILENAME,
     1294                    workRequest.FDWACCESS,
     1295                    workRequest.DWFLAGS,
     1296                    workRequest.DWCONTEXT);
     1297                 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZFILENAME);
     1298                 break;
     1299
     1300            case FTPGETFILEA:
     1301                FTP_FtpGetFileA((HINTERNET)workRequest.HFTPSESSION,
     1302                    (LPCSTR)workRequest.LPSZREMOTEFILE,
     1303                    (LPCSTR)workRequest.LPSZNEWFILE,
     1304                    (BOOL)workRequest.FFAILIFEXISTS,
     1305                    workRequest.DWLOCALFLAGSATTRIBUTE,
     1306                    workRequest.DWFLAGS,
     1307                    workRequest.DWCONTEXT);
     1308                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZREMOTEFILE);
     1309                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZNEWFILE);
     1310                break;
     1311
     1312            case FTPDELETEFILEA:
     1313                FTP_FtpDeleteFileA((HINTERNET)workRequest.HFTPSESSION,
     1314                        (LPCSTR)workRequest.LPSZFILENAME);
     1315                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZFILENAME);
     1316                break;
     1317
     1318            case FTPREMOVEDIRECTORYA:
     1319                FTP_FtpRemoveDirectoryA((HINTERNET)workRequest.HFTPSESSION,
     1320                        (LPCSTR)workRequest.LPSZDIRECTORY);
     1321                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZDIRECTORY);
     1322                break;
     1323
     1324            case FTPRENAMEFILEA:
     1325                FTP_FtpRenameFileA((HINTERNET)workRequest.HFTPSESSION,
     1326                        (LPCSTR)workRequest.LPSZSRCFILE,
     1327                        (LPCSTR)workRequest.LPSZDESTFILE);
     1328                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZSRCFILE);
     1329                HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZDESTFILE);
     1330                break;
     1331
     1332            case INTERNETFINDNEXTA:
     1333                INTERNET_FindNextFileA((HINTERNET)workRequest.HFTPSESSION,
     1334                    (LPWIN32_FIND_DATAA)workRequest.LPFINDFILEDATA);
     1335                break;
     1336
     1337            case HTTPSENDREQUESTA:
     1338               HTTP_HttpSendRequestA((HINTERNET)workRequest.HFTPSESSION,
     1339                       (LPCSTR)workRequest.LPSZHEADER,
     1340                       workRequest.DWHEADERLENGTH,
     1341                       (LPVOID)workRequest.LPOPTIONAL,
     1342                       workRequest.DWOPTIONALLENGTH);
     1343               HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZHEADER);
     1344               break;
     1345
     1346            case HTTPOPENREQUESTA:
     1347               HTTP_HttpOpenRequestA((HINTERNET)workRequest.HFTPSESSION,
     1348                       (LPCSTR)workRequest.LPSZVERB,
     1349                       (LPCSTR)workRequest.LPSZOBJECTNAME,
     1350                       (LPCSTR)workRequest.LPSZVERSION,
     1351                       (LPCSTR)workRequest.LPSZREFERRER,
     1352                       (LPCSTR*)workRequest.LPSZACCEPTTYPES,
     1353                       workRequest.DWFLAGS,
     1354                       workRequest.DWCONTEXT);
     1355               HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZVERB);
     1356               HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZOBJECTNAME);
     1357               HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZVERSION);
     1358               HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZREFERRER);
     1359                break;
     1360
     1361        }
     1362    }
     1363}
     1364
     1365
     1366/************************************************************************
     1367 *          INTERNET_GetResponseBuffer
     1368 *
     1369 * RETURNS
     1370 *
     1371 */
     1372LPSTR INTERNET_GetResponseBuffer()
     1373{
     1374    LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
     1375    return lpwite->response;
     1376}
     1377
     1378
     1379/************************************************************************
     1380 *           INTERNET_GetNextLine  (internal)
     1381 *
     1382 * Parse next line in directory string listing
     1383 *
     1384 * RETURNS
     1385 *   Pointer to begining of next line
     1386 *   NULL on failure
     1387 *
     1388 */
     1389LPSTR INTERNET_GetNextLine(INT nSocket, LPSTR lpszBuffer, LPDWORD dwBuffer)
     1390{
     1391    struct timeval tv;
     1392    fd_set infd;
     1393    BOOL bSuccess = FALSE;
     1394    INT nRecv = 0;
     1395
     1396    TRACE("\n");
     1397
     1398    FD_ZERO(&infd);
     1399    FD_SET(nSocket, &infd);
     1400    tv.tv_sec=RESPONSE_TIMEOUT;
     1401    tv.tv_usec=0;
     1402
     1403    while (nRecv < *dwBuffer)
     1404    {
     1405        if (select(nSocket+1,&infd,NULL,NULL,&tv) > 0)
     1406        {
     1407            if (recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0)
     1408            {
     1409                INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
     1410                goto lend;
     1411            }
     1412
     1413            if (lpszBuffer[nRecv] == '\n')
     1414            {
     1415                bSuccess = TRUE;
     1416                break;
     1417            }
     1418            if (lpszBuffer[nRecv] != '\r')
     1419                nRecv++;
     1420        }
     1421        else
     1422        {
     1423            INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT);
     1424            goto lend;
     1425}
     1426    }
     1427
     1428lend:
     1429    if (bSuccess)
     1430    {
     1431        lpszBuffer[nRecv] = '\0';
     1432        *dwBuffer = nRecv - 1;
     1433        TRACE(":%d %s\n", nRecv, lpszBuffer);
     1434        return lpszBuffer;
     1435    }
     1436    else
     1437    {
     1438        return NULL;
     1439    }
     1440}
     1441
     1442
     1443/************************************************************************
     1444 *           InternetQueryDataAvailable (WININET.118)
     1445 *
     1446 * Fetch the amount of data available for retrieval
     1447 *
     1448 * RETURNS
     1449 *   TRUE on success
     1450 *   FALSE on failure
     1451 *
     1452 */
     1453BOOL WINAPI InternetQueryDataAvailable(HINTERNET hFile,LPDWORD lpdwNumberOfBytesAvailable,
     1454                                       DWORD dwFlags, DWORD dwContext)
     1455{
     1456    LONG lBytesAvailable;
     1457    LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
     1458
     1459    if (NULL == lpwh)
     1460    {
     1461        INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     1462        return FALSE;
     1463    }
     1464
     1465    WriteLog("InternetQueryDataAvailable for hHandle %08x",lpwh);
     1466
     1467    switch (lpwh->htype)
     1468    {
     1469            case WH_HHTTPREQ:
     1470                    *lpdwNumberOfBytesAvailable = -1;
     1471                    break;
     1472
     1473            case WH_HFILE:
     1474                    *lpdwNumberOfBytesAvailable = ((LPWININETFILE)lpwh)->lBytesAvailable;
     1475                    break;
     1476
     1477            default:
     1478                    INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
     1479                    return FALSE;
     1480    }
     1481
     1482    if(*lpdwNumberOfBytesAvailable == -1)
     1483      return FALSE;
     1484
     1485    WriteLog("InternetQueryDataAvailable returns %d",*lpdwNumberOfBytesAvailable);
     1486
     1487    return TRUE;
     1488}
  • trunk/src/wininet/internet.h

    r2624 r4842  
    1212typedef enum
    1313{
    14     WH_HINIT,
    15     WH_HFTPSESSION,
    16     WH_HGOPHERSESSION,
    17     WH_HHTTPSESSION,
    18     WH_HHTTPREQ,
    19     WH_HFILE,
    20     WH_HFINDNEXT,
     14    WH_HINIT = INTERNET_HANDLE_TYPE_INTERNET,
     15    WH_HFTPSESSION = INTERNET_HANDLE_TYPE_CONNECT_FTP,
     16    WH_HGOPHERSESSION = INTERNET_HANDLE_TYPE_CONNECT_GOPHER,
     17    WH_HHTTPSESSION = INTERNET_HANDLE_TYPE_CONNECT_HTTP,
     18    WH_HFILE = INTERNET_HANDLE_TYPE_FTP_FILE,
     19    WH_HFINDNEXT = INTERNET_HANDLE_TYPE_FTP_FIND,
     20    WH_HHTTPREQ = INTERNET_HANDLE_TYPE_HTTP_REQUEST,
    2121} WH_TYPE;
    2222
     
    2626    DWORD  dwFlags;
    2727    DWORD  dwContext;
     28    DWORD  dwError;
    2829    struct _WININETHANDLEHEADER *lpwhparent;
    2930} WININETHANDLEHEADER, *LPWININETHANDLEHEADER;
     
    3233typedef struct
    3334{
    34         WININETHANDLEHEADER hdr;
    35         LPSTR  lpszAgent;
    36         LPSTR  lpszProxy;
    37         LPSTR  lpszProxyBypass;
    38         DWORD   dwAccessType;
    39         INTERNET_STATUS_CALLBACK lpfnStatusCB;
     35        WININETHANDLEHEADER hdr;
     36        LPSTR  lpszAgent;
     37        LPSTR  lpszProxy;
     38        LPSTR  lpszProxyBypass;
     39        DWORD   dwAccessType;
     40        INTERNET_STATUS_CALLBACK lpfnStatusCB;
    4041} WININETAPPINFOA, *LPWININETAPPINFOA;
    4142
     
    4344typedef struct
    4445{
    45         WININETHANDLEHEADER hdr;
    46         LPSTR  lpszServerName;
    47         LPSTR  lpszUserName;
    48         INTERNET_PORT nServerPort;
    49         struct sockaddr_in socketAddress;
    50         struct hostent *phostent;
     46        WININETHANDLEHEADER hdr;
     47        LPSTR  lpszServerName;
     48        LPSTR  lpszUserName;
     49        INTERNET_PORT nServerPort;
     50        struct sockaddr_in socketAddress;
     51        struct hostent *phostent;
    5152} WININETHTTPSESSIONA, *LPWININETHTTPSESSIONA;
    5253
    53 
    54 typedef struct
    55 {
    56         WININETHANDLEHEADER hdr;
    57         LPSTR lpszPath;
    58         LPSTR lpszReferrer;
    59         LPSTR lpszAcceptTypes;
    60         LPSTR lpszVerb;
    61         LPSTR lpszHostName;
    62         LPSTR lpszRedirect;
    63         int     nSocketFD;
    64         int     statusCode;
    65         int     contentLength;
    66         time_t  nSystemTime;
     54#define HDR_ISREQUEST           0x0001
     55#define HDR_COMMADELIMITED      0x0002
     56#define HDR_SEMIDELIMITED       0x0004
     57
     58typedef struct
     59{
     60    LPSTR lpszField;
     61    LPSTR lpszValue;
     62    WORD  wFlags;
     63    WORD  wCount;
     64} HTTPHEADERA, *LPHTTPHEADERA;
     65
     66typedef struct
     67{
     68        WININETHANDLEHEADER hdr;
     69        LPSTR lpszPath;
     70/*        LPSTR lpszReferrer;
     71        LPSTR lpszAcceptTypes; */
     72        LPSTR lpszVerb;
     73        LPSTR lpszHostName;
     74/*        LPSTR lpszRedirect; */
     75        int     nSocketFD;
     76/*        int     statusCode;
     77        int     contentLength;
     78        time_t  nSystemTime;*/
     79        HTTPHEADERA StdHeaders[HTTP_QUERY_MAX+1];
     80        HTTPHEADERA *pCustHeaders;
     81        int nCustHeaders;
    6782} WININETHTTPREQA, *LPWININETHTTPREQA;
    6883
     
    7085typedef struct
    7186{
    72         WININETHANDLEHEADER hdr;
    73         int sndSocket;
    74         int lstnSocket;
    75         struct sockaddr_in socketAddress;
    76         struct sockaddr_in lstnSocketAddress;
    77         struct hostent *phostent;
    78         LPSTR  lpszPassword;
    79         LPSTR  lpszUserName;
    80         LPSTR  lpszResponseBuffer;
     87        WININETHANDLEHEADER hdr;
     88        int sndSocket;
     89        int lstnSocket;
     90        struct sockaddr_in socketAddress;
     91        struct sockaddr_in lstnSocketAddress;
     92        struct hostent *phostent;
     93        LPSTR  lpszPassword;
     94        LPSTR  lpszUserName;
     95                                       /* LONG   lBytesAvailable;          */
     96/*        LPSTR  lpszResponseBuffer; */
    8197} WININETFTPSESSIONA, *LPWININETFTPSESSIONA;
    8298
     
    84100typedef struct
    85101{
    86         WININETHANDLEHEADER hdr;
    87         int nDataSocket;
     102        WININETHANDLEHEADER hdr;
     103        int nDataSocket;
     104        LONG lBytesAvailable;
    88105} WININETFILE, *LPWININETFILE;
    89106
     
    91108typedef struct
    92109{
    93         BOOL      bIsDirectory;
    94         LPSTR     lpszName;
    95         DWORD     nSize;
    96         struct tm tmLastModified;
    97         unsigned short permissions;
     110        BOOL      bIsDirectory;
     111        LPSTR     lpszName;
     112        DWORD     nSize;
     113        struct tm tmLastModified;
     114        unsigned short permissions;
    98115} FILEPROPERTIESA, *LPFILEPROPERTIESA;
    99116
     
    101118typedef struct
    102119{
    103         WININETHANDLEHEADER hdr;
    104         int index;
    105         DWORD size;
    106         LPFILEPROPERTIESA lpafp;
     120        WININETHANDLEHEADER hdr;
     121        int index;
     122        DWORD size;
     123        LPFILEPROPERTIESA lpafp;
    107124} WININETFINDNEXTA, *LPWININETFINDNEXTA;
    108125
     126typedef enum
     127{
     128  FTPPUTFILEA,
     129  FTPSETCURRENTDIRECTORYA,
     130  FTPCREATEDIRECTORYA,
     131  FTPFINDFIRSTFILEA,
     132  FTPGETCURRENTDIRECTORYA,
     133  FTPOPENFILEA,
     134  FTPGETFILEA,
     135  FTPDELETEFILEA,
     136  FTPREMOVEDIRECTORYA,
     137  FTPRENAMEFILEA,
     138  INTERNETFINDNEXTA,
     139  HTTPSENDREQUESTA,
     140  HTTPOPENREQUESTA,
     141} ASYNC_FUNC;
     142
     143typedef struct WORKREQ
     144{
     145  ASYNC_FUNC asyncall;
     146  DWORD param1;
     147#define HFTPSESSION param1
     148
     149  DWORD param2;
     150#define LPSZLOCALFILE     param2
     151#define LPSZREMOTEFILE    param2
     152#define LPSZFILENAME      param2
     153#define LPSZSRCFILE       param2
     154#define LPSZDIRECTORY     param2
     155#define LPSZSEARCHFILE    param2
     156#define LPSZHEADER        param2
     157#define LPSZVERB          param2
     158
     159  DWORD param3;
     160#define LPSZNEWREMOTEFILE param3
     161#define LPSZNEWFILE       param3
     162#define LPFINDFILEDATA    param3
     163#define LPDWDIRECTORY     param3
     164#define FDWACCESS         param3
     165#define LPSZDESTFILE      param3
     166#define DWHEADERLENGTH    param3
     167#define LPSZOBJECTNAME    param3
     168
     169  DWORD param4;
     170#define DWFLAGS           param4
     171#define LPOPTIONAL        param4
     172
     173  DWORD param5;
     174#define DWCONTEXT         param5
     175#define DWOPTIONALLENGTH  param5
     176
     177  DWORD param6;
     178#define FFAILIFEXISTS     param6
     179#define LPSZVERSION       param6
     180
     181  DWORD param7;
     182#define DWLOCALFLAGSATTRIBUTE param7
     183#define LPSZREFERRER          param7
     184
     185  DWORD param8;
     186#define LPSZACCEPTTYPES   param8
     187
     188  struct WORKREQ *next;
     189  struct WORKREQ *prev;
     190
     191} WORKREQUEST, *LPWORKREQUEST;
     192
    109193time_t ConvertTimeString(LPCSTR asctime);
    110194
    111 HINTERNET FTP_Connect(HINTERNET hInterent, LPCSTR lpszServerName,
    112         INTERNET_PORT nServerPort, LPCSTR lpszUserName,
    113         LPCSTR lpszPassword, DWORD dwFlags, DWORD dwContext);
     195HINTERNET FTP_Connect(HINTERNET hInterent, LPCSTR lpszServerName,
     196        INTERNET_PORT nServerPort, LPCSTR lpszUserName,
     197        LPCSTR lpszPassword, DWORD dwFlags, DWORD dwContext);
     198
     199HINTERNET HTTP_Connect(HINTERNET hInterent, LPCSTR lpszServerName,
     200        INTERNET_PORT nServerPort, LPCSTR lpszUserName,
     201        LPCSTR lpszPassword, DWORD dwFlags, DWORD dwContext);
    114202
    115203BOOL GetAddress(LPCSTR lpszServerName, INTERNET_PORT nServerPort,
    116         struct hostent **phe, struct sockaddr_in *psa);
    117 
    118 int WriteDataToStream(int nDataSocket, LPCVOID Buffer, DWORD BytesToWrite);
    119 int ReadDataFromStream(int nDataSocket, LPVOID Buffer, DWORD BytesToRead);
     204        struct hostent **phe, struct sockaddr_in *psa);
     205
     206int  INTERNET_WriteDataToStream(int nDataSocket, LPCVOID Buffer, DWORD BytesToWrite);
     207int  INTERNET_ReadDataFromStream(int nDataSocket, LPVOID Buffer, DWORD BytesToRead);
     208void INTERNET_SetLastError(DWORD dwError);
     209DWORD INTERNET_GetLastError(void);
     210BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest);
     211LPSTR INTERNET_GetResponseBuffer(void);
     212LPSTR INTERNET_GetNextLine(INT nSocket, LPSTR lpszBuffer, LPDWORD dwBuffer);
     213
    120214BOOL FTP_CloseSessionHandle(LPWININETFTPSESSIONA lpwfs);
    121215BOOL FTP_CloseFindNextHandle(LPWININETFINDNEXTA lpwfn);
     216BOOL FTP_FtpPutFileA(HINTERNET hConnect, LPCSTR lpszLocalFile,
     217        LPCSTR lpszNewRemoteFile, DWORD dwFlags, DWORD dwContext);
     218BOOL FTP_FtpSetCurrentDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory);
     219BOOL FTP_FtpCreateDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory);
     220HINTERNET FTP_FtpFindFirstFileA(HINTERNET hConnect, LPCSTR lpszSearchFile,
     221        LPWIN32_FIND_DATAA lpFindFileData, DWORD dwFlags, DWORD dwContext);
     222BOOL FTP_FtpGetCurrentDirectoryA(HINTERNET hFtpSession, LPSTR lpszCurrentDirectory,
     223        LPDWORD lpdwCurrentDirectory);
     224BOOL FTP_ConvertFileProp(LPFILEPROPERTIESA lpafp, LPWIN32_FIND_DATAA lpFindFileData);
     225BOOL FTP_FtpRenameFileA(HINTERNET hFtpSession, LPCSTR lpszSrc, LPCSTR lpszDest);
     226BOOL FTP_FtpRemoveDirectoryA(HINTERNET hFtpSession, LPCSTR lpszDirectory);
     227BOOL FTP_FtpDeleteFileA(HINTERNET hFtpSession, LPCSTR lpszFileName);
     228HINTERNET FTP_FtpOpenFileA(HINTERNET hFtpSession, LPCSTR lpszFileName,
     229        DWORD dwAccess, DWORD dwFlags, DWORD dwContext);
     230BOOL FTP_FtpGetFileA(HINTERNET hInternet, LPCSTR lpszRemoteFile, LPCSTR lpszNewFile,
     231        BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
     232        DWORD dwContext);
     233
     234BOOL HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders,
     235        DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength);
     236HINTERNET HTTP_HttpOpenRequestA(HINTERNET hHttpSession, LPCSTR lpszVerb,
     237        LPCSTR lpszObjectName, LPCSTR lpszVersion, LPCSTR lpszReferrer,
     238        LPCSTR *lpszAcceptTypes, DWORD dwFlags, DWORD dwContext);
     239void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONA lpwhs);
     240void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQA lpwhr);
     241
     242#define MAX_REPLY_LEN 0x5B4
    122243
    123244#endif /* _WINE_INTERNET_H_ */
  • trunk/src/wininet/makefile

    r4719 r4842  
    1 # $Id: makefile,v 1.11 2000-12-02 23:56:21 bird Exp $
     1# $Id: makefile,v 1.12 2000-12-27 23:06:17 sandervl Exp $
    22
    33#
     
    2020$(OBJDIR)\wininet.obj \
    2121$(OBJDIR)\ftp.obj \
     22$(OBJDIR)\http.obj \
    2223$(OBJDIR)\utility.obj \
    2324$(OBJDIR)\initterm.obj \
     
    3435$(ODIN32_LIB)/$(ODINCRT).lib \
    3536$(ODIN32_LIB)/wsock32.lib \
     37$(ODIN32_LIB)/icmp.lib \
    3638OS2386.LIB \
    3739$(RTLLIB_O)
  • trunk/src/wininet/utility.c

    r3898 r4842  
    1 /* $Id: utility.c,v 1.2 2000-07-29 14:10:09 bird Exp $
     1/* $Id: utility.c,v 1.3 2000-12-27 23:06:17 sandervl Exp $
    22 *
    33 * Wininet - Utility functions
     
    2727time_t ConvertTimeString(LPCSTR asctime)
    2828{
    29         char tmpChar[TIME_STRING_LEN];
    30         char *tmpChar2;
    31         struct tm SystemTime;
    32         int timelen = strlen(asctime);
     29        char tmpChar[TIME_STRING_LEN];
     30        char *tmpChar2;
     31        struct tm SystemTime;
     32        int timelen = strlen(asctime);
    3333
    34         if(!asctime || !timelen)
    35                 return 0;
     34        if(!asctime || !timelen)
     35                return 0;
    3636
    37         strncpy(tmpChar, asctime, TIME_STRING_LEN);
     37        strncpy(tmpChar, asctime, TIME_STRING_LEN);
    3838
    39         //Assert that the string is the expected length
    40         if (tmpChar[TIME_STRING_LEN] != '\0')
    41         {
    42                 tmpChar[TIME_STRING_LEN] = '\0';
    43                 FIXME("\n");
    44         }
     39        //Assert that the string is the expected length
     40        if (tmpChar[TIME_STRING_LEN] != '\0')
     41        {
     42                tmpChar[TIME_STRING_LEN] = '\0';
     43                FIXME("\n");
     44        }
    4545
    46         //Convert a time such as 'Mon, 15 Nov 1999 16:09:35 GMT' into a SYSTEMTIME structure
    47         //We assume the time is in this format
    48         //and divide it into easy to swallow chunks
    49         tmpChar[3]='\0';
    50         tmpChar[7]='\0';
    51         tmpChar[11]='\0';
    52         tmpChar[16]='\0';
    53         tmpChar[19]='\0';
    54         tmpChar[22]='\0';
    55         tmpChar[25]='\0';
     46        //Convert a time such as 'Mon, 15 Nov 1999 16:09:35 GMT' into a SYSTEMTIME structure
     47        //We assume the time is in this format
     48        //and divide it into easy to swallow chunks
     49        tmpChar[3]='\0';
     50        tmpChar[7]='\0';
     51        tmpChar[11]='\0';
     52        tmpChar[16]='\0';
     53        tmpChar[19]='\0';
     54        tmpChar[22]='\0';
     55        tmpChar[25]='\0';
    5656
    57         SystemTime.tm_year = atoi(tmpChar+12) - 1900;
    58         SystemTime.tm_mday = atoi(tmpChar+5);
    59         SystemTime.tm_hour = atoi(tmpChar+17);
    60         SystemTime.tm_min = atoi(tmpChar+20);
    61         SystemTime.tm_sec = atoi(tmpChar+23);
     57        SystemTime.tm_year = atoi(tmpChar+12) - 1900;
     58        SystemTime.tm_mday = atoi(tmpChar+5);
     59        SystemTime.tm_hour = atoi(tmpChar+17);
     60        SystemTime.tm_min = atoi(tmpChar+20);
     61        SystemTime.tm_sec = atoi(tmpChar+23);
    6262
    63         //and month
    64         tmpChar2 = tmpChar + 8;
    65         switch(tmpChar2[2])
    66         {
    67                 case 'n':
    68                         if(tmpChar2[1]=='a')
    69                                 SystemTime.tm_mon = 0;
    70                         else
    71                                 SystemTime.tm_mon = 5;
    72                         break;
    73                 case 'b':
    74                         SystemTime.tm_mon = 1;
    75                         break;
    76                 case 'r':
    77                         if(tmpChar2[1]=='a')
    78                                 SystemTime.tm_mon = 2;
    79                         else
    80                                 SystemTime.tm_mon = 3;
    81                         break;
    82                 case 'y':
    83                         SystemTime.tm_mon = 4;
    84                         break;
    85                 case 'l':
    86                         SystemTime.tm_mon = 6;
    87                         break;
    88                 case 'g':
    89                         SystemTime.tm_mon = 7;
    90                         break;
    91                 case 'p':
    92                         SystemTime.tm_mon = 8;
    93                         break;
    94                 case 't':
    95                         SystemTime.tm_mon = 9;
    96                         break;
    97                 case 'v':
    98                         SystemTime.tm_mon = 10;
    99                         break;
    100                 case 'c':
    101                         SystemTime.tm_mon = 11;
    102                         break;
    103                 default:
    104                         FIXME("\n");
    105         }//switch
     63        //and month
     64        tmpChar2 = tmpChar + 8;
     65        switch(tmpChar2[2])
     66        {
     67                case 'n':
     68                        if(tmpChar2[1]=='a')
     69                                SystemTime.tm_mon = 0;
     70                        else
     71                                SystemTime.tm_mon = 5;
     72                        break;
     73                case 'b':
     74                        SystemTime.tm_mon = 1;
     75                        break;
     76                case 'r':
     77                        if(tmpChar2[1]=='a')
     78                                SystemTime.tm_mon = 2;
     79                        else
     80                                SystemTime.tm_mon = 3;
     81                        break;
     82                case 'y':
     83                        SystemTime.tm_mon = 4;
     84                        break;
     85                case 'l':
     86                        SystemTime.tm_mon = 6;
     87                        break;
     88                case 'g':
     89                        SystemTime.tm_mon = 7;
     90                        break;
     91                case 'p':
     92                        SystemTime.tm_mon = 8;
     93                        break;
     94                case 't':
     95                        SystemTime.tm_mon = 9;
     96                        break;
     97                case 'v':
     98                        SystemTime.tm_mon = 10;
     99                        break;
     100                case 'c':
     101                        SystemTime.tm_mon = 11;
     102                        break;
     103                default:
     104                        FIXME("\n");
     105        }//switch
    106106
    107         return mktime(&SystemTime);
     107        return mktime(&SystemTime);
    108108}
    109109
    110110
    111111BOOL GetAddress(LPCSTR lpszServerName, INTERNET_PORT nServerPort,
    112         struct hostent **phe, struct sockaddr_in *psa)
     112        struct hostent **phe, struct sockaddr_in *psa)
    113113{
    114         *phe = gethostbyname(lpszServerName);
    115         if (NULL == *phe)
    116         {
    117             TRACE("Failed to get hostname %s\n", lpszServerName);
    118             return FALSE;
    119         }
     114        *phe = gethostbyname(lpszServerName);
     115        if (NULL == *phe)
     116        {
     117            TRACE("Failed to get hostname %s\n", lpszServerName);
     118            return FALSE;
     119        }
    120120
    121         memcpy((char *)&psa->sin_addr, (*phe)->h_addr, (*phe)->h_length);
    122         psa->sin_family = (*phe)->h_addrtype;
    123         psa->sin_port = htons((u_short)nServerPort);
     121        memset(psa,0,sizeof(struct sockaddr_in));
     122        memcpy((char *)&psa->sin_addr, (*phe)->h_addr, (*phe)->h_length);
     123        psa->sin_family = (*phe)->h_addrtype;
     124        psa->sin_port = htons((u_short)nServerPort);
    124125
    125         return TRUE;
     126        return TRUE;
    126127}
  • trunk/src/wininet/wininet.cpp

    r2624 r4842  
    1 /* $Id: wininet.cpp,v 1.2 2000-02-03 22:50:28 sandervl Exp $ */
     1/* $Id: wininet.cpp,v 1.3 2000-12-27 23:06:17 sandervl Exp $ */
    22/*
    33 * WININET stubs
     
    1616                                       LPSTR lpszTime, DWORD cbTime)
    1717{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    18         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    19         return 0;
     18        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     19        return 0;
    2020}
    2121//******************************************************************************
     
    2424                              LPURL_COMPONENTSW lpUrlComponents)
    2525{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    26         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    27         return 0;
     26        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     27        return 0;
    2828}
    2929//******************************************************************************
     
    3232                               LPSTR lpszUrl, LPDWORD lpdwUrlLength)
    3333{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    34         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    35         return 0;
     34        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     35        return 0;
    3636}
    3737//******************************************************************************
     
    4040                               LPWSTR lpszUrl, LPDWORD lpdwUrlLength)
    4141{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    42         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    43         return 0;
    44 }
    45 //******************************************************************************
    46 //******************************************************************************
    47 BOOL WINAPI InternetCanonicalizeUrlA(LPCSTR lpszUrl, LPSTR lpszBuffer,
    48                                      LPDWORD lpdwBufferLength, DWORD dwFlags)
    49 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    50         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    51         return 0;
     42        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     43        return 0;
    5244}
    5345//******************************************************************************
     
    5648                                     LPDWORD lpdwBufferLength, DWORD dwFlags)
    5749{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    58         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    59         return 0;
     50        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     51        return 0;
    6052}
    6153//******************************************************************************
     
    6557                                DWORD dwFlags)
    6658{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    67         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    68         return 0;
     59        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     60        return 0;
    6961}
    7062//******************************************************************************
     
    7466                                DWORD dwFlags)
    7567{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    76         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    77         return 0;
     68        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     69        return 0;
    7870}
    7971//******************************************************************************
     
    8375                               DWORD dwFlags)
    8476{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    85         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    86         return 0;
     77        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     78        return 0;
    8779}
    8880//******************************************************************************
     
    9385                                  DWORD dwFlags, DWORD dwContext)
    9486{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    95         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    96         return 0;
     87        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     88        return 0;
    9789}
    9890//******************************************************************************
     
    10193                                  DWORD dwHeadersLength, DWORD dwFlags, DWORD dwContext)
    10294{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    103         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    104         return 0;
     95        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     96        return 0;
    10597}
    10698//******************************************************************************
     
    109101                                  DWORD dwHeadersLength, DWORD dwFlags, DWORD dwContext)
    110102{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    111         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    112         return 0;
     103        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     104        return 0;
    113105}
    114106//******************************************************************************
     
    118110                                    DWORD dwContext)
    119111{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    120         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    121         return 0;
    122 }
    123 //******************************************************************************
    124 //******************************************************************************
    125 BOOL WINAPI InternetQueryDataAvailable(HINTERNET hFile,LPDWORD lpdwNumberOfBytesAvailable,   
    126                                        DWORD dwFlags, DWORD dwContext)
    127 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    128         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    129         return 0;
     112        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     113        return 0;
    130114}
    131115//******************************************************************************
     
    133117BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData)
    134118{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    135         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    136         return 0;
    137 }
    138 //******************************************************************************
    139 //******************************************************************************
    140 BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer,
    141                                  LPDWORD lpdwBufferLength)
    142 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    143         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    144         return 0;
     119        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     120        return 0;
    145121}
    146122//******************************************************************************
     
    149125                                 LPDWORD lpdwBufferLength)
    150126{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    151         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    152         return 0;
     127        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     128        return 0;
    153129}
    154130//******************************************************************************
     
    157133                               DWORD dwBufferLength)
    158134{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    159         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    160         return 0;
     135        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     136        return 0;
    161137}
    162138//******************************************************************************
     
    165141                               DWORD dwBufferLength)
    166142{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    167         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    168         return 0;
     143        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     144        return 0;
    169145}
    170146//******************************************************************************
     
    173149                                 DWORD dwBufferLength, DWORD dwFlags)
    174150{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    175         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    176         return 0;
     151        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     152        return 0;
    177153}
    178154//******************************************************************************
     
    181157                                 DWORD dwBufferLength, DWORD dwFlags)
    182158{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    183         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    184         return 0;
     159        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     160        return 0;
    185161}
    186162//******************************************************************************
     
    189165                                         LPDWORD lpdwBufferLength)
    190166{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    191         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    192         return 0;
     167        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     168        return 0;
    193169}
    194170//******************************************************************************
     
    198174                                   DWORD dwFlags, DWORD dwContext)
    199175{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    200         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    201         return 0;
     176        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     177        return 0;
    202178}
    203179//******************************************************************************
     
    208184                        DWORD dwContext)
    209185{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    210         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    211         return 0;
     186        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     187        return 0;
    212188}
    213189//******************************************************************************
     
    216192                        DWORD dwFlags, DWORD dwContext)
    217193{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    218         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    219         return 0;
    220 }
    221 //******************************************************************************
    222 //******************************************************************************
    223 BOOL WINAPI FtpDeleteFileA(HINTERNET hConnect, LPCSTR lpszFileName)
    224 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    225         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    226         return 0;
     194        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     195        return 0;
    227196}
    228197//******************************************************************************
     
    230199BOOL WINAPI FtpDeleteFileW(HINTERNET hConnect, LPCWSTR lpszFileName)
    231200{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    232         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    233         return 0;
    234 }
    235 //******************************************************************************
    236 //******************************************************************************
    237 BOOL WINAPI FtpRenameFileA(HINTERNET hConnect, LPCSTR lpszExisting, LPCSTR lpszNew)
    238 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    239         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    240         return 0;
     201        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     202        return 0;
    241203}
    242204//******************************************************************************
     
    244206BOOL WINAPI FtpRenameFileW(HINTERNET hConnect, LPCWSTR lpszExisting,LPCWSTR lpszNew)
    245207{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    246         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    247         return 0;
     208        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     209        return 0;
    248210}
    249211//******************************************************************************
     
    252214                              DWORD dwAccess, DWORD dwFlags, DWORD dwContext)
    253215{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    254         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    255         return 0;
     216        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     217        return 0;
    256218}
    257219//******************************************************************************
     
    259221BOOL WINAPI FtpCreateDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory)
    260222{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    261         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    262         return 0;
    263 }
    264 //******************************************************************************
    265 //******************************************************************************
    266 BOOL WINAPI FtpRemoveDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory)
    267 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    268         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    269         return 0;
     223        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     224        return 0;
    270225}
    271226//******************************************************************************
     
    273228BOOL WINAPI FtpRemoveDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory)
    274229{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    275         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    276         return 0;
     230        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     231        return 0;
    277232}
    278233//******************************************************************************
     
    280235BOOL WINAPI FtpSetCurrentDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory)
    281236{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    282         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    283         return 0;
     237        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     238        return 0;
    284239}
    285240//******************************************************************************
     
    288243                                    LPDWORD lpdwCurrentDirectory)
    289244{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    290         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    291         return 0;
     245        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     246        return 0;
    292247}
    293248//******************************************************************************
     
    296251                        LPCSTR lpszCommand, DWORD dwContext)
    297252{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    298         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    299         return 0;
     253        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     254        return 0;
    300255}
    301256//******************************************************************************
     
    304259                        LPCWSTR lpszCommand, DWORD dwContext)
    305260{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    306         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    307         return 0;
     261        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     262        return 0;
    308263}
    309264//******************************************************************************
     
    314269                                 LPDWORD lpdwBufferLength)
    315270{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    316         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    317         return 0;
     271        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     272        return 0;
    318273}
    319274//******************************************************************************
     
    324279                                 LPDWORD lpdwBufferLength)
    325280{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    326         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    327         return 0;
     281        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     282        return 0;
    328283}
    329284//******************************************************************************
     
    331286BOOL WINAPI GopherGetLocatorTypeA(LPCSTR lpszLocator, LPDWORD lpdwGopherType)
    332287{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    333         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    334         return 0;
     288        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     289        return 0;
    335290}
    336291//******************************************************************************
     
    338293BOOL WINAPI GopherGetLocatorTypeW(LPCWSTR lpszLocator, LPDWORD lpdwGopherType)
    339294{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    340         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    341         return 0;
     295        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     296        return 0;
    342297}
    343298//******************************************************************************
     
    347302                                      DWORD dwFlags, DWORD dwContext)
    348303{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    349         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    350         return 0;
     304        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     305        return 0;
    351306}
    352307//******************************************************************************
     
    356311                                      DWORD dwFlags, DWORD dwContext)
    357312{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    358         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    359         return 0;
     313        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     314        return 0;
    360315}
    361316//******************************************************************************
     
    364319                                 LPCSTR lpszView, DWORD dwFlags, DWORD dwContext)
    365320{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    366         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    367         return 0;
     321        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     322        return 0;
    368323}
    369324//******************************************************************************
     
    372327                                 LPCWSTR lpszView, DWORD dwFlags, DWORD dwContext)
    373328{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    374         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    375         return 0;
     329        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     330        return 0;
    376331}
    377332//******************************************************************************
     
    383338                                DWORD dwContext)
    384339{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    385         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    386         return 0;
     340        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     341        return 0;
    387342}
    388343//******************************************************************************
     
    394349                                DWORD dwContext)
    395350{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    396         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    397         return 0;
    398 }
    399 //******************************************************************************
    400 //******************************************************************************
    401 HINTERNET WINAPI HttpOpenRequestA(HINTERNET hConnect, LPCSTR lpszVerb,
    402                                   LPCSTR lpszObjectName, LPCSTR lpszVersion,
    403                                   LPCSTR lpszReferrer, LPCSTR * lplpszAcceptTypes,
    404                                   DWORD dwFlags, DWORD dwContext)
    405 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    406         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    407         return 0;
     351        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     352        return 0;
    408353}
    409354//******************************************************************************
     
    414359                                  DWORD dwFlags, DWORD dwContext)
    415360{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    416         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    417         return 0;
    418 }
    419 //******************************************************************************
    420 //******************************************************************************
    421 BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hRequest, LPCSTR lpszHeaders,
    422                                    DWORD dwHeadersLength, DWORD dwModifiers)
    423 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    424         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    425         return 0;
     361        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     362        return 0;
    426363}
    427364//******************************************************************************
     
    430367                                   DWORD dwHeadersLength, DWORD dwModifiers)
    431368{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    432         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    433         return 0;
    434 }
    435 //******************************************************************************
    436 //******************************************************************************
    437 BOOL WINAPI HttpSendRequestA(HINTERNET hRequest, LPCSTR lpszHeaders,
    438                              DWORD dwHeadersLength, LPVOID lpOptional,
    439                              DWORD dwOptionalLength)
    440 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    441         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    442         return 0;
     369        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     370        return 0;
    443371}
    444372//******************************************************************************
     
    448376                             DWORD dwOptionalLength)
    449377{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    450         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    451         return 0;
    452 }
    453 //******************************************************************************
    454 //******************************************************************************
    455 BOOL WINAPI HttpQueryInfoA(HINTERNET hRequest, DWORD dwInfoLevel, LPVOID lpBuffer,
    456                            LPDWORD lpdwBufferLength, LPDWORD lpdwIndex)
    457 {dprintf(("ERROR:"__FUNCTION__" not implemented"));
    458         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    459         return 0;
     378        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     379        return 0;
    460380}
    461381//******************************************************************************
     
    464384                           LPDWORD lpdwBufferLength, LPDWORD lpdwIndex)
    465385{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    466         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    467         return 0;
     386        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     387        return 0;
    468388}
    469389//******************************************************************************
     
    471391BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName, LPCSTR lpszCookieData)
    472392{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    473         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    474         return 0;
     393        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     394        return 0;
    475395}
    476396//******************************************************************************
     
    478398BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, LPCWSTR lpszCookieData)
    479399{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    480         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    481         return 0;
     400        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     401        return 0;
    482402}
    483403//******************************************************************************
     
    486406                               LPDWORD lpdwSize)
    487407{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    488         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    489         return 0;
     408        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     409        return 0;
    490410}
    491411//******************************************************************************
     
    494414                               LPDWORD lpdwSize)
    495415{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    496         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    497         return 0;
    498 }
    499 //******************************************************************************
    500 //******************************************************************************
     416        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     417        return 0;
     418}
     419//* ******************************************************************************/
     420//* ******************************************************************************/
    501421DWORD WINAPI InternetErrorDlg(HWND hWnd, HINTERNET hRequest,
    502422                              DWORD dwError, DWORD dwFlags, LPVOID * lppvData)
    503423{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    504         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    505         return 0;
    506 }
    507 //******************************************************************************
     424        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     425        return 0;
     426}
     427//* ******************************************************************************/
     428//* ******************************************************************************/
     429DWORD WINAPI InternetCheckConnectionW(LPCWSTR lpszUrl, DWORD dwFlags, DWORD dwReserved)
     430{dprintf(("ERROR:"__FUNCTION__" not implemented"));
     431        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     432        return 0;
     433}
     434//* ******************************************************************************/
    508435//******************************************************************************
    509436DWORD WINAPI InternetConfirmZoneCrossing(HWND hWnd, LPSTR szUrlPrev,
    510437                                         LPSTR szUrlNew, BOOL bPost)
    511438{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    512         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    513         return 0;
     439        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     440        return 0;
    514441}
    515442//******************************************************************************
     
    519446                                 DWORD dwReserved)
    520447{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    521         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    522         return 0;
     448        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     449        return 0;
    523450}
    524451//******************************************************************************
     
    528455                                 DWORD dwReserved)
    529456{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    530         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    531         return 0;
     457        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     458        return 0;
    532459}
    533460//******************************************************************************
     
    539466                                 DWORD dwReserved)
    540467{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    541         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    542         return 0;
     468        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     469        return 0;
    543470}
    544471//******************************************************************************
     
    550477                                 DWORD dwReserved)
    551478{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    552         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    553         return 0;
     479        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     480        return 0;
    554481}
    555482//******************************************************************************
     
    559486                                       DWORD dwReserved)
    560487{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    561         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    562         return 0;
     488        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     489        return 0;
    563490}
    564491//******************************************************************************
     
    568495                                       DWORD dwReserved)
    569496{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    570         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    571         return 0;
     497        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     498        return 0;
    572499}
    573500//******************************************************************************
     
    575502BOOL WINAPI UnlockUrlCacheEntryFile(LPCSTR lpszUrlName, DWORD dwReserved)
    576503{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    577         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    578         return 0;
     504        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     505        return 0;
    579506}
    580507//******************************************************************************
     
    584511                                           BOOL fRandomRead, DWORD dwReserved)
    585512{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    586         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    587         return 0;
     513        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     514        return 0;
    588515}
    589516//******************************************************************************
     
    593520                                           BOOL fRandomRead, DWORD dwReserved)
    594521{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    595         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    596         return 0;
     522        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     523        return 0;
    597524}
    598525//******************************************************************************
     
    602529                                    DWORD Reserved)
    603530{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    604         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    605         return 0;
     531        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     532        return 0;
    606533}
    607534//******************************************************************************
     
    609536BOOL WINAPI UnlockUrlCacheEntryStream(HANDLE hUrlCacheStream, DWORD Reserved)
    610537{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    611         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    612         return 0;
     538        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     539        return 0;
    613540}
    614541//******************************************************************************
     
    617544                                  LPDWORD lpdwCacheEntryInfoBufferSize)
    618545{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    619         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    620         return 0;
     546        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     547        return 0;
    621548}
    622549//******************************************************************************
     
    625552                                  LPDWORD lpdwCacheEntryInfoBufferSize)
    626553{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    627         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    628         return 0;
     554        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     555        return 0;
    629556}
    630557//******************************************************************************
     
    633560                                  DWORD dwFieldControl)
    634561{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    635         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    636         return 0;
     562        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     563        return 0;
    637564}
    638565//******************************************************************************
     
    641568                                  DWORD dwFieldControl)
    642569{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    643         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    644         return 0;
     570        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     571        return 0;
    645572}
    646573//******************************************************************************
     
    650577                                      LPDWORD lpdwFirstCacheEntryInfoBufferSize)
    651578{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    652         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    653         return 0;
     579        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     580        return 0;
    654581}
    655582//******************************************************************************
     
    659586                                      LPDWORD lpdwFirstCacheEntryInfoBufferSize)
    660587{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    661         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    662         return 0;
     588        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     589        return 0;
    663590}
    664591//******************************************************************************
     
    668595                                   LPDWORD lpdwNextCacheEntryInfoBufferSize)
    669596{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    670         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    671         return 0;
     597        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     598        return 0;
    672599}
    673600//******************************************************************************
     
    677604                                   LPDWORD lpdwNextCacheEntryInfoBufferSize)
    678605{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    679         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    680         return 0;
     606        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     607        return 0;
    681608}
    682609//******************************************************************************
     
    684611BOOL WINAPI FindCloseUrlCache(HANDLE hEnumHandle)
    685612{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    686         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    687         return 0;
     613        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     614        return 0;
    688615}
    689616//******************************************************************************
     
    691618BOOL WINAPI DeleteUrlCacheEntry(LPCSTR lpszUrlName)
    692619{dprintf(("ERROR:"__FUNCTION__" not implemented"));
    693         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    694         return 0;
    695 }
    696 //******************************************************************************
    697 //******************************************************************************
     620        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     621        return 0;
     622}
     623//******************************************************************************
     624//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.