4 * Copyright 1999 Corel Corporation
13 #include <sys/types.h>
14 #ifdef HAVE_SYS_SOCKET_H
15 # include <sys/socket.h>
21 #include "debugtools.h"
27 DEFAULT_DEBUG_CHANNEL(wininet);
29 #define MAX_IDLE_WORKER 1000*60*1
30 #define MAX_WORKER_THREADS 10
32 #define GET_HWININET_FROM_LPWININETFINDNEXT(lpwh) \
33 (LPWININETAPPINFOA)(((LPWININETFTPSESSIONA)(lpwh->hdr.lpwhparent))->hdr.lpwhparent)
38 CHAR response[MAX_REPLY_LEN];
39 } WITHREADERROR, *LPWITHREADERROR;
41 INTERNET_SCHEME GetInternetScheme(LPSTR lpszScheme);
42 BOOL WINAPI INTERNET_FindNextFileA(HINTERNET hFind, LPVOID lpvFindData);
43 VOID INTERNET_ExecuteWork();
45 DWORD g_dwTlsErrIndex = TLS_OUT_OF_INDEXES;
47 DWORD dwNumIdleThreads;
48 HANDLE hEventArray[2];
49 #define hQuitEvent hEventArray[0]
50 #define hWorkEvent hEventArray[1]
51 CRITICAL_SECTION csQueue;
52 LPWORKREQUEST lpHeadWorkQueue;
53 LPWORKREQUEST lpWorkQueueTail;
55 /***********************************************************************
56 * WININET_LibMain [Internal] Initializes the internal 'WININET.DLL'.
59 * hinstDLL [I] handle to the 'dlls' instance
61 * lpvReserved [I] reserverd, must be NULL
69 WININET_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
71 TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
74 case DLL_PROCESS_ATTACH:
76 g_dwTlsErrIndex = TlsAlloc();
78 if (g_dwTlsErrIndex == TLS_OUT_OF_INDEXES)
81 hQuitEvent = CreateEventA(0, TRUE, FALSE, NULL);
82 hWorkEvent = CreateEventA(0, FALSE, FALSE, NULL);
83 InitializeCriticalSection(&csQueue);
88 case DLL_THREAD_ATTACH:
90 LPWITHREADERROR lpwite = HeapAlloc(GetProcessHeap(), 0, sizeof(WITHREADERROR));
94 TlsSetValue(g_dwTlsErrIndex, (LPVOID)lpwite);
98 case DLL_THREAD_DETACH:
99 if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES)
100 HeapFree(GetProcessHeap(), 0, TlsGetValue(g_dwTlsErrIndex));
103 case DLL_PROCESS_DETACH:
105 if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES)
107 HeapFree(GetProcessHeap(), 0, TlsGetValue(g_dwTlsErrIndex));
108 TlsFree(g_dwTlsErrIndex);
111 SetEvent(hQuitEvent);
113 CloseHandle(hQuitEvent);
114 CloseHandle(hWorkEvent);
116 DeleteCriticalSection(&csQueue);
124 /***********************************************************************
125 * InternetOpenA (WININET.113)
127 * Per-application initialization of wininet
130 * HINTERNET on success
134 INTERNETAPI HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent,
135 DWORD dwAccessType, LPCSTR lpszProxy,
136 LPCSTR lpszProxyBypass, DWORD dwFlags)
138 LPWININETAPPINFOA lpwai = NULL;
142 /* Clear any error information */
143 INTERNET_SetLastError(0);
145 lpwai = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETAPPINFOA));
147 INTERNET_SetLastError(ERROR_OUTOFMEMORY);
150 memset(lpwai, 0, sizeof(WININETAPPINFOA));
151 lpwai->hdr.htype = WH_HINIT;
152 lpwai->hdr.lpwhparent = NULL;
153 lpwai->hdr.dwFlags = dwFlags;
154 if (NULL != lpszAgent)
155 lpwai->lpszAgent = strdup(lpszAgent);
156 if (NULL != lpszProxy)
157 lpwai->lpszProxy = strdup(lpszProxy);
158 if (NULL != lpszProxyBypass)
159 lpwai->lpszProxyBypass = strdup(lpszProxyBypass);
160 lpwai->dwAccessType = dwAccessType;
163 return (HINTERNET)lpwai;
167 /***********************************************************************
168 * InternetGetLastResponseInfoA (WININET.108)
170 * Return last wininet error description on the calling thread
173 * TRUE on success of writting to buffer
177 BOOL WINAPI InternetGetLastResponseInfoA(LPDWORD lpdwError,
178 LPSTR lpszBuffer, LPDWORD lpdwBufferLength)
180 LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
184 *lpdwError = lpwite->dwError;
187 strncpy(lpszBuffer, lpwite->response, *lpdwBufferLength);
188 *lpdwBufferLength = strlen(lpszBuffer);
191 *lpdwBufferLength = 0;
197 /***********************************************************************
198 * InternetGetConnectedState (WININET.103)
200 * Return connected state
204 * if lpdwStatus is not null, return the status (off line,
205 * modem, lan...) in it.
206 * FALSE if not connected
208 BOOL WINAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved)
215 /***********************************************************************
216 * InternetConnectA (WININET.93)
218 * Open a ftp, gopher or http session
221 * HINTERNET a session handle on success
225 INTERNETAPI HINTERNET WINAPI InternetConnectA(HINTERNET hInternet,
226 LPCSTR lpszServerName, INTERNET_PORT nServerPort,
227 LPCSTR lpszUserName, LPCSTR lpszPassword,
228 DWORD dwService, DWORD dwFlags, DWORD dwContext)
230 HINTERNET rc = (HINTERNET) NULL;
234 /* Clear any error information */
235 INTERNET_SetLastError(0);
239 case INTERNET_SERVICE_FTP:
240 rc = FTP_Connect(hInternet, lpszServerName, nServerPort,
241 lpszUserName, lpszPassword, dwFlags, dwContext);
244 case INTERNET_SERVICE_HTTP:
247 case INTERNET_SERVICE_GOPHER:
255 /***********************************************************************
256 * InternetFindNextFileA (WININET.102)
258 * Continues a file search from a previous call to FindFirstFile
265 BOOL WINAPI InternetFindNextFileA(HINTERNET hFind, LPVOID lpvFindData)
267 LPWININETAPPINFOA hIC = NULL;
268 LPWININETFINDNEXTA lpwh = (LPWININETFINDNEXTA) hFind;
272 if (NULL == lpwh || lpwh->hdr.htype != WH_HFINDNEXT)
274 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
278 hIC = GET_HWININET_FROM_LPWININETFINDNEXT(lpwh);
279 if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
281 WORKREQUEST workRequest;
283 workRequest.asyncall = INTERNETFINDNEXTA;
284 workRequest.HFTPSESSION = (DWORD)hFind;
285 workRequest.LPFINDFILEDATA = (DWORD)lpvFindData;
287 return INTERNET_AsyncCall(&workRequest);
291 return INTERNET_FindNextFileA(hFind, lpvFindData);
295 /***********************************************************************
296 * INTERNET_FindNextFileA (Internal)
298 * Continues a file search from a previous call to FindFirstFile
305 BOOL WINAPI INTERNET_FindNextFileA(HINTERNET hFind, LPVOID lpvFindData)
307 BOOL bSuccess = TRUE;
308 LPWININETAPPINFOA hIC = NULL;
309 LPWIN32_FIND_DATAA lpFindFileData;
310 LPWININETFINDNEXTA lpwh = (LPWININETFINDNEXTA) hFind;
314 if (NULL == lpwh || lpwh->hdr.htype != WH_HFINDNEXT)
316 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
320 /* Clear any error information */
321 INTERNET_SetLastError(0);
323 if (lpwh->hdr.lpwhparent->htype != WH_HFTPSESSION)
325 FIXME("Only FTP find next supported\n");
326 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
330 TRACE("index(%d) size(%ld)\n", lpwh->index, lpwh->size);
332 lpFindFileData = (LPWIN32_FIND_DATAA) lpvFindData;
333 ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA));
335 if (lpwh->index >= lpwh->size)
337 INTERNET_SetLastError(ERROR_NO_MORE_FILES);
342 FTP_ConvertFileProp(&lpwh->lpafp[lpwh->index], lpFindFileData);
345 TRACE("\nName: %s\nSize: %ld\n", lpFindFileData->cFileName, lpFindFileData->nFileSizeLow);
349 hIC = GET_HWININET_FROM_LPWININETFINDNEXT(lpwh);
350 if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB)
352 INTERNET_ASYNC_RESULT iar;
354 iar.dwResult = (DWORD)bSuccess;
355 iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
357 hIC->lpfnStatusCB(hFind, lpwh->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
358 &iar, sizeof(INTERNET_ASYNC_RESULT));
365 /***********************************************************************
366 * InternetCloseHandle (WININET.89)
368 * Continues a file search from a previous call to FindFirstFile
375 BOOL WINAPI InternetCloseHandle(HINTERNET hInternet)
378 LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hInternet;
384 /* Clear any error information */
385 INTERNET_SetLastError(0);
390 case WH_HHTTPSESSION:
394 retval = FTP_CloseSessionHandle((LPWININETFTPSESSIONA) lpwh);
398 retval = FTP_CloseFindNextHandle((LPWININETFINDNEXTA) lpwh);
409 /***********************************************************************
410 * InternetCrackUrlA (WININET.95)
412 * Break up URL into its components
419 BOOL WINAPI InternetCrackUrlA(LPCSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags,
420 LPURL_COMPONENTSA lpUrlComponents)
424 * <protocol>:[//<net_loc>][/path][;<params>][?<query>][#<fragment>]
427 char* szScheme = NULL;
431 char* szUrlPath = NULL;
432 char* szParam = NULL;
433 char* szNetLoc = NULL;
441 /* Find out if the URI is absolute... */
442 BOOL bIsAbsolute = FALSE;
444 char* ap = (char*)lpszUrl;
448 while( (cAlphanum = *ap) != '\0' )
450 if( ((cAlphanum >= 'a') && (cAlphanum <= 'z')) ||
451 ((cAlphanum >= 'A') && (cAlphanum <= 'Z')) ||
452 ((cAlphanum >= '0') && (cAlphanum <= '9')) )
457 if( (cAlphanum == ':') && (ap - lpszUrl >= 2) )
467 FIXME!!!! This should work on relative urls too!*/
470 /* Get scheme first... */
471 nSchemeLen = cp - lpszUrl;
472 szScheme = strdup( lpszUrl );
473 szScheme[ nSchemeLen ] = '\0';
475 /* Eat ':' in protocol... */
478 /* Parse <params>... */
479 szParam = strpbrk( lpszUrl, ";" );
480 if( szParam != NULL )
483 /* Eat ';' in Params... */
485 sParam = strdup( szParam );
489 /* Skip over slashes...*/
501 /* Parse the <net-loc>...*/
502 if( GetInternetScheme( szScheme ) == INTERNET_SCHEME_FILE )
504 szUrlPath = strdup( cp );
505 nUrlLen = strlen( szUrlPath );
506 if( nUrlLen >= 2 && szUrlPath[ 1 ] == '|' )
507 szUrlPath[ 1 ] = ':';
512 szUrlPath = strpbrk(cp, "/");
513 if( szUrlPath != NULL )
514 nUrlLen = strlen( szUrlPath );
516 /* Find the end of our net-loc... */
517 nNetLocLen = strcspn( cp, "/" );
518 szNetLoc = strdup( cp );
519 szNetLoc[ nNetLocLen ] = '\0';
520 if( szNetLoc != NULL )
524 /* [<user>[<:password>]@]<host>[:<port>] */
525 /* First find the user and password if they exist...*/
527 szHost = strchr( szNetLoc, '@' );
530 /* username and password not specified... */
532 nHostLen = nNetLocLen;
536 int nUserPassLen = nNetLocLen - nHostLen - 1;
537 char* szUserPass = strdup( szNetLoc );
538 /* Get username and/or password... */
539 /* Eat '@' in domain... */
541 nHostLen = strlen( szHost );
543 szUserPass[ nUserPassLen ] = '\0';
544 if( szUserPass != NULL )
546 szPass = strpbrk( szUserPass, ":" );
549 /* Eat ':' in UserPass... */
551 nPassLen = strlen( szPass );
552 nUserLen = nUserPassLen - nPassLen - 1;
553 szUser = strdup( szUserPass );
554 szUser[ nUserLen ] = '\0';
558 /* password not specified... */
559 szUser = strdup( szUserPass );
560 nUserLen = strlen( szUser );
565 /* <host><:port>...*/
566 /* Then get the port if it exists... */
567 lpszPort = strpbrk( szHost, ":" );
569 if( lpszPort != NULL )
571 char* szPort = lpszPort + 1;
574 nPortLen = strlen( szPort );
575 nPort = atoi( szPort );
578 nHostLen = strlen(szHost);
583 /* Relative URI... */
591 /***********************************************************************
592 * InternetAttemptConnect (WININET.81)
594 * Attempt to make a connection to the internet
597 * ERROR_SUCCESS on success
598 * Error value on failure
601 INTERNETAPI DWORD WINAPI InternetAttemptConnect(DWORD dwReserved)
604 return ERROR_SUCCESS;
608 /***********************************************************************
609 * InternetCanonicalizeUrlA (WININET.85)
611 * Escape unsafe characters and spaces
618 BOOL WINAPI InternetCanonicalizeUrlA(LPCSTR lpszUrl, LPSTR lpszBuffer,
619 LPDWORD lpdwBufferLength, DWORD dwFlags)
621 BOOL bSuccess = FALSE;
627 strncpy(lpszBuffer, lpszUrl, *lpdwBufferLength);
628 *lpdwBufferLength = strlen(lpszBuffer);
636 /***********************************************************************
637 * InternetSetStatusCallback (WININET.133)
639 * Sets up a callback function which is called as progress is made
640 * during an operation.
643 * Previous callback or NULL on success
644 * INTERNET_INVALID_STATUS_CALLBACK on failure
647 INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallback(
648 HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB)
650 INTERNET_STATUS_CALLBACK retVal;
651 LPWININETAPPINFOA lpwai = (LPWININETAPPINFOA)hInternet;
653 TRACE("0x%08lx\n", (ULONG)hInternet);
654 if (lpwai->hdr.htype != WH_HINIT)
655 return INTERNET_INVALID_STATUS_CALLBACK;
657 retVal = lpwai->lpfnStatusCB;
658 lpwai->lpfnStatusCB = lpfnIntCB;
664 /***********************************************************************
665 * InternetWriteFile (WININET.138)
667 * Write data to an open internet file
674 BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer ,
675 DWORD dwNumOfBytesToWrite, LPDWORD lpdwNumOfBytesWritten)
678 int nSocket = INVALID_SOCKET;
679 LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
688 nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
692 nSocket = ((LPWININETFILE)hFile)->nDataSocket;
699 if (INVALID_SOCKET != nSocket)
701 *lpdwNumOfBytesWritten = INTERNET_WriteDataToStream(nSocket, lpBuffer, dwNumOfBytesToWrite);
702 if (*lpdwNumOfBytesWritten < 0)
703 *lpdwNumOfBytesWritten = 0;
712 /***********************************************************************
713 * InternetReadFile (WININET.121)
715 * Read data from an open internet file
722 BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
723 DWORD dwNumOfBytesToRead, LPDWORD dwNumOfBytesRead)
726 int nSocket = INVALID_SOCKET;
727 LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
736 nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
740 nSocket = ((LPWININETFILE)hFile)->nDataSocket;
747 if (INVALID_SOCKET != nSocket)
749 *dwNumOfBytesRead = INTERNET_ReadDataFromStream(nSocket, lpBuffer, dwNumOfBytesToRead);
750 if (*dwNumOfBytesRead < 0)
751 *dwNumOfBytesRead = 0;
760 /***********************************************************************
761 * GetInternetScheme (internal)
767 * INTERNET_SCHEME_UNKNOWN on failure
770 INTERNET_SCHEME GetInternetScheme(LPSTR lpszScheme)
773 return INTERNET_SCHEME_UNKNOWN;
775 if( (strcmp("ftp", lpszScheme) == 0) ||
776 (strcmp("FTP", lpszScheme) == 0) )
777 return INTERNET_SCHEME_FTP;
778 else if( (strcmp("gopher", lpszScheme) == 0) ||
779 (strcmp("GOPHER", lpszScheme) == 0) )
780 return INTERNET_SCHEME_GOPHER;
781 else if( (strcmp("http", lpszScheme) == 0) ||
782 (strcmp("HTTP", lpszScheme) == 0) )
783 return INTERNET_SCHEME_HTTP;
784 else if( (strcmp("https", lpszScheme) == 0) ||
785 (strcmp("HTTPS", lpszScheme) == 0) )
786 return INTERNET_SCHEME_HTTPS;
787 else if( (strcmp("file", lpszScheme) == 0) ||
788 (strcmp("FILE", lpszScheme) == 0) )
789 return INTERNET_SCHEME_FILE;
790 else if( (strcmp("news", lpszScheme) == 0) ||
791 (strcmp("NEWS", lpszScheme) == 0) )
792 return INTERNET_SCHEME_NEWS;
793 else if( (strcmp("mailto", lpszScheme) == 0) ||
794 (strcmp("MAILTO", lpszScheme) == 0) )
795 return INTERNET_SCHEME_MAILTO;
797 return INTERNET_SCHEME_UNKNOWN;
801 /***********************************************************************
802 * INTERNET_WriteDataToStream (internal)
804 * Send data to server
808 * number of characters sent on success
811 int INTERNET_WriteDataToStream(int nDataSocket, LPCVOID Buffer, DWORD BytesToWrite)
813 if (INVALID_SOCKET == nDataSocket)
816 return send(nDataSocket, Buffer, BytesToWrite, 0);
820 /***********************************************************************
821 * INTERNET_ReadDataFromStream (internal)
823 * Read data from http server
827 * number of characters sent on success
830 int INTERNET_ReadDataFromStream(int nDataSocket, LPVOID Buffer, DWORD BytesToRead)
832 if (INVALID_SOCKET == nDataSocket)
835 return recv(nDataSocket, Buffer, BytesToRead, 0);
839 /***********************************************************************
840 * INTERNET_SetLastError (internal)
842 * Set last thread specific error
847 void INTERNET_SetLastError(DWORD dwError)
849 LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
851 SetLastError(dwError);
852 lpwite->dwError = dwError;
856 /***********************************************************************
857 * INTERNET_GetLastError (internal)
859 * Get last thread specific error
864 DWORD INTERNET_GetLastError()
866 LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
867 return lpwite->dwError;
871 /***********************************************************************
872 * INTERNET_WorkerThreadFunc (internal)
874 * Worker thread execution function
879 DWORD INTERNET_WorkerThreadFunc(LPVOID *lpvParam)
885 dwWaitRes = WaitForMultipleObjects(2, hEventArray, FALSE, MAX_IDLE_WORKER);
887 if (dwWaitRes == WAIT_OBJECT_0 + 1)
888 INTERNET_ExecuteWork();
892 InterlockedIncrement(&dwNumIdleThreads);
895 InterlockedDecrement(&dwNumIdleThreads);
896 InterlockedDecrement(&dwNumThreads);
897 TRACE("Worker thread exiting\n");
902 /***********************************************************************
903 * INTERNET_InsertWorkRequest (internal)
905 * Insert work request into queue
910 BOOL INTERNET_InsertWorkRequest(LPWORKREQUEST lpWorkRequest)
912 BOOL bSuccess = FALSE;
913 LPWORKREQUEST lpNewRequest;
917 lpNewRequest = HeapAlloc(GetProcessHeap(), 0, sizeof(WORKREQUEST));
920 memcpy(lpNewRequest, lpWorkRequest, sizeof(WORKREQUEST));
921 lpNewRequest->prev = NULL;
923 EnterCriticalSection(&csQueue);
925 lpNewRequest->next = lpWorkQueueTail;
927 lpWorkQueueTail->prev = lpNewRequest;
928 lpWorkQueueTail = lpNewRequest;
929 if (!lpHeadWorkQueue)
930 lpHeadWorkQueue = lpWorkQueueTail;
932 LeaveCriticalSection(&csQueue);
941 /***********************************************************************
942 * INTERNET_GetWorkRequest (internal)
944 * Retrieves work request from queue
949 BOOL INTERNET_GetWorkRequest(LPWORKREQUEST lpWorkRequest)
951 BOOL bSuccess = FALSE;
952 LPWORKREQUEST lpRequest = NULL;
956 EnterCriticalSection(&csQueue);
960 lpRequest = lpHeadWorkQueue;
961 lpHeadWorkQueue = lpHeadWorkQueue->prev;
962 if (lpRequest == lpWorkQueueTail)
963 lpWorkQueueTail = lpHeadWorkQueue;
966 LeaveCriticalSection(&csQueue);
970 memcpy(lpWorkRequest, lpRequest, sizeof(WORKREQUEST));
971 HeapFree(GetProcessHeap(), 0, lpRequest);
979 /***********************************************************************
980 * INTERNET_AsyncCall (internal)
982 * Retrieves work request from queue
987 BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest)
991 BOOL bSuccess = FALSE;
995 if (InterlockedDecrement(&dwNumIdleThreads) < 0)
997 InterlockedIncrement(&dwNumIdleThreads);
999 if (InterlockedIncrement(&dwNumThreads) > MAX_WORKER_THREADS ||
1000 !(hThread = CreateThread(NULL, 0,
1001 (LPTHREAD_START_ROUTINE)INTERNET_WorkerThreadFunc, NULL, 0, &dwTID)))
1003 InterlockedDecrement(&dwNumThreads);
1004 INTERNET_SetLastError(ERROR_INTERNET_ASYNC_THREAD_FAILED);
1008 TRACE("Created new thread\n");
1012 INTERNET_InsertWorkRequest(lpWorkRequest);
1013 SetEvent(hWorkEvent);
1021 /***********************************************************************
1022 * INTERNET_ExecuteWork (internal)
1027 VOID INTERNET_ExecuteWork()
1029 WORKREQUEST workRequest;
1033 if (INTERNET_GetWorkRequest(&workRequest))
1035 switch (workRequest.asyncall)
1038 FTP_FtpPutFileA((HINTERNET)workRequest.HFTPSESSION, (LPCSTR)workRequest.LPSZLOCALFILE,
1039 (LPCSTR)workRequest.LPSZNEWREMOTEFILE, workRequest.DWFLAGS, workRequest.DWCONTEXT);
1040 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZLOCALFILE);
1041 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZNEWREMOTEFILE);
1044 case FTPSETCURRENTDIRECTORYA:
1045 FTP_FtpSetCurrentDirectoryA((HINTERNET)workRequest.HFTPSESSION,
1046 (LPCSTR)workRequest.LPSZDIRECTORY);
1047 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZDIRECTORY);
1050 case FTPCREATEDIRECTORYA:
1051 FTP_FtpCreateDirectoryA((HINTERNET)workRequest.HFTPSESSION,
1052 (LPCSTR)workRequest.LPSZDIRECTORY);
1053 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZDIRECTORY);
1056 case FTPFINDFIRSTFILEA:
1057 FTP_FtpFindFirstFileA((HINTERNET)workRequest.HFTPSESSION,
1058 (LPCSTR)workRequest.LPSZSEARCHFILE,
1059 (LPWIN32_FIND_DATAA)workRequest.LPFINDFILEDATA, workRequest.DWFLAGS,
1060 workRequest.DWCONTEXT);
1061 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZSEARCHFILE);
1064 case FTPGETCURRENTDIRECTORYA:
1065 FTP_FtpGetCurrentDirectoryA((HINTERNET)workRequest.HFTPSESSION,
1066 (LPSTR)workRequest.LPSZDIRECTORY, (LPDWORD)workRequest.LPDWDIRECTORY);
1070 FTP_FtpOpenFileA((HINTERNET)workRequest.HFTPSESSION,
1071 (LPCSTR)workRequest.LPSZFILENAME,
1072 workRequest.FDWACCESS,
1073 workRequest.DWFLAGS,
1074 workRequest.DWCONTEXT);
1075 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZFILENAME);
1079 FTP_FtpGetFileA((HINTERNET)workRequest.HFTPSESSION,
1080 (LPCSTR)workRequest.LPSZREMOTEFILE,
1081 (LPCSTR)workRequest.LPSZNEWFILE,
1082 (BOOL)workRequest.FFAILIFEXISTS,
1083 workRequest.DWLOCALFLAGSATTRIBUTE,
1084 workRequest.DWFLAGS,
1085 workRequest.DWCONTEXT);
1086 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZREMOTEFILE);
1087 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZNEWFILE);
1090 case FTPDELETEFILEA:
1091 FTP_FtpDeleteFileA((HINTERNET)workRequest.HFTPSESSION,
1092 (LPCSTR)workRequest.LPSZFILENAME);
1093 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZFILENAME);
1096 case FTPREMOVEDIRECTORYA:
1097 FTP_FtpRemoveDirectoryA((HINTERNET)workRequest.HFTPSESSION,
1098 (LPCSTR)workRequest.LPSZDIRECTORY);
1099 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZDIRECTORY);
1102 case FTPRENAMEFILEA:
1103 FTP_FtpRenameFileA((HINTERNET)workRequest.HFTPSESSION,
1104 (LPCSTR)workRequest.LPSZSRCFILE,
1105 (LPCSTR)workRequest.LPSZDESTFILE);
1106 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZSRCFILE);
1107 HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZDESTFILE);
1110 case INTERNETFINDNEXTA:
1111 INTERNET_FindNextFileA((HINTERNET)workRequest.HFTPSESSION,
1112 (LPWIN32_FIND_DATAA)workRequest.LPFINDFILEDATA);
1119 /***********************************************************************
1120 * INTERNET_GetResponseBuffer
1125 LPSTR INTERNET_GetResponseBuffer()
1127 LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
1128 return lpwite->response;