4 * Copyright 1999 Corel Corporation
5 * Copyright 2002 CodeWeavers Inc.
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #define MAXHOSTNAME 100 /* from http.c */
31 #include <sys/types.h>
32 #ifdef HAVE_SYS_SOCKET_H
33 # include <sys/socket.h>
35 #ifdef HAVE_SYS_TIME_H
36 # include <sys/time.h>
48 #include "wine/debug.h"
50 #define NO_SHLWAPI_STREAM
53 #include "wine/exception.h"
54 #include "msvcrt/excpt.h"
58 WINE_DEFAULT_DEBUG_CHANNEL(wininet
);
60 #define MAX_IDLE_WORKER 1000*60*1
61 #define MAX_WORKER_THREADS 10
62 #define RESPONSE_TIMEOUT 30
64 #define GET_HWININET_FROM_LPWININETFINDNEXT(lpwh) \
65 (LPWININETAPPINFOA)(((LPWININETFTPSESSIONA)(lpwh->hdr.lpwhparent))->hdr.lpwhparent)
67 /* filter for page-fault exceptions */
68 static WINE_EXCEPTION_FILTER(page_fault
)
70 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
||
71 GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION
)
72 return EXCEPTION_EXECUTE_HANDLER
;
73 return EXCEPTION_CONTINUE_SEARCH
;
79 CHAR response
[MAX_REPLY_LEN
];
80 } WITHREADERROR
, *LPWITHREADERROR
;
82 INTERNET_SCHEME
GetInternetScheme(LPCSTR lpszScheme
, INT nMaxCmp
);
83 BOOL WINAPI
INTERNET_FindNextFileA(HINTERNET hFind
, LPVOID lpvFindData
);
84 VOID
INTERNET_ExecuteWork();
86 DWORD g_dwTlsErrIndex
= TLS_OUT_OF_INDEXES
;
88 DWORD dwNumIdleThreads
;
89 HANDLE hEventArray
[2];
90 #define hQuitEvent hEventArray[0]
91 #define hWorkEvent hEventArray[1]
92 CRITICAL_SECTION csQueue
;
93 LPWORKREQUEST lpHeadWorkQueue
;
94 LPWORKREQUEST lpWorkQueueTail
;
96 /***********************************************************************
97 * WININET_LibMain [Internal] Initializes the internal 'WININET.DLL'.
100 * hinstDLL [I] handle to the DLL's instance
102 * lpvReserved [I] reserved, must be NULL
110 WININET_LibMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
112 TRACE("%x,%lx,%p\n", hinstDLL
, fdwReason
, lpvReserved
);
115 case DLL_PROCESS_ATTACH
:
117 g_dwTlsErrIndex
= TlsAlloc();
119 if (g_dwTlsErrIndex
== TLS_OUT_OF_INDEXES
)
122 hQuitEvent
= CreateEventA(0, TRUE
, FALSE
, NULL
);
123 hWorkEvent
= CreateEventA(0, FALSE
, FALSE
, NULL
);
124 InitializeCriticalSection(&csQueue
);
127 dwNumIdleThreads
= 0;
129 case DLL_THREAD_ATTACH
:
131 LPWITHREADERROR lpwite
= HeapAlloc(GetProcessHeap(), 0, sizeof(WITHREADERROR
));
135 TlsSetValue(g_dwTlsErrIndex
, (LPVOID
)lpwite
);
139 case DLL_THREAD_DETACH
:
140 if (g_dwTlsErrIndex
!= TLS_OUT_OF_INDEXES
)
142 LPVOID lpwite
= TlsGetValue(g_dwTlsErrIndex
);
144 HeapFree(GetProcessHeap(), 0, lpwite
);
148 case DLL_PROCESS_DETACH
:
150 if (g_dwTlsErrIndex
!= TLS_OUT_OF_INDEXES
)
152 HeapFree(GetProcessHeap(), 0, TlsGetValue(g_dwTlsErrIndex
));
153 TlsFree(g_dwTlsErrIndex
);
156 SetEvent(hQuitEvent
);
158 CloseHandle(hQuitEvent
);
159 CloseHandle(hWorkEvent
);
160 DeleteCriticalSection(&csQueue
);
168 /***********************************************************************
169 * InternetOpenA (WININET.@)
171 * Per-application initialization of wininet
174 * HINTERNET on success
178 HINTERNET WINAPI
InternetOpenA(LPCSTR lpszAgent
,
179 DWORD dwAccessType
, LPCSTR lpszProxy
,
180 LPCSTR lpszProxyBypass
, DWORD dwFlags
)
182 LPWININETAPPINFOA lpwai
= NULL
;
186 /* Clear any error information */
187 INTERNET_SetLastError(0);
189 lpwai
= HeapAlloc(GetProcessHeap(), 0, sizeof(WININETAPPINFOA
));
191 INTERNET_SetLastError(ERROR_OUTOFMEMORY
);
194 memset(lpwai
, 0, sizeof(WININETAPPINFOA
));
195 lpwai
->hdr
.htype
= WH_HINIT
;
196 lpwai
->hdr
.lpwhparent
= NULL
;
197 lpwai
->hdr
.dwFlags
= dwFlags
;
198 if (NULL
!= lpszAgent
)
200 if ((lpwai
->lpszAgent
= HeapAlloc( GetProcessHeap(),0,strlen(lpszAgent
)+1)))
201 strcpy( lpwai
->lpszAgent
, lpszAgent
);
203 if (NULL
!= lpszProxy
)
205 if ((lpwai
->lpszProxy
= HeapAlloc( GetProcessHeap(), 0, strlen(lpszProxy
)+1 )))
206 strcpy( lpwai
->lpszProxy
, lpszProxy
);
208 if (NULL
!= lpszProxyBypass
)
210 if ((lpwai
->lpszProxyBypass
= HeapAlloc( GetProcessHeap(), 0, strlen(lpszProxyBypass
)+1)))
211 strcpy( lpwai
->lpszProxyBypass
, lpszProxyBypass
);
213 lpwai
->dwAccessType
= dwAccessType
;
216 return (HINTERNET
)lpwai
;
220 /***********************************************************************
221 * InternetGetLastResponseInfoA (WININET.@)
223 * Return last wininet error description on the calling thread
226 * TRUE on success of writting to buffer
230 BOOL WINAPI
InternetGetLastResponseInfoA(LPDWORD lpdwError
,
231 LPSTR lpszBuffer
, LPDWORD lpdwBufferLength
)
233 LPWITHREADERROR lpwite
= (LPWITHREADERROR
)TlsGetValue(g_dwTlsErrIndex
);
237 *lpdwError
= lpwite
->dwError
;
240 strncpy(lpszBuffer
, lpwite
->response
, *lpdwBufferLength
);
241 *lpdwBufferLength
= strlen(lpszBuffer
);
244 *lpdwBufferLength
= 0;
250 /***********************************************************************
251 * InternetGetConnectedState (WININET.@)
253 * Return connected state
257 * if lpdwStatus is not null, return the status (off line,
258 * modem, lan...) in it.
259 * FALSE if not connected
261 BOOL WINAPI
InternetGetConnectedState(LPDWORD lpdwStatus
, DWORD dwReserved
)
264 FIXME("always returning LAN connection.\n");
265 *lpdwStatus
= INTERNET_CONNECTION_LAN
;
271 /***********************************************************************
272 * InternetConnectA (WININET.@)
274 * Open a ftp, gopher or http session
277 * HINTERNET a session handle on success
281 HINTERNET WINAPI
InternetConnectA(HINTERNET hInternet
,
282 LPCSTR lpszServerName
, INTERNET_PORT nServerPort
,
283 LPCSTR lpszUserName
, LPCSTR lpszPassword
,
284 DWORD dwService
, DWORD dwFlags
, DWORD dwContext
)
286 HINTERNET rc
= (HINTERNET
) NULL
;
288 TRACE("ServerPort %i\n",nServerPort
);
290 /* Clear any error information */
291 INTERNET_SetLastError(0);
295 case INTERNET_SERVICE_FTP
:
296 rc
= FTP_Connect(hInternet
, lpszServerName
, nServerPort
,
297 lpszUserName
, lpszPassword
, dwFlags
, dwContext
);
300 case INTERNET_SERVICE_HTTP
:
301 rc
= HTTP_Connect(hInternet
, lpszServerName
, nServerPort
,
302 lpszUserName
, lpszPassword
, dwFlags
, dwContext
);
305 case INTERNET_SERVICE_GOPHER
:
313 /***********************************************************************
314 * InternetFindNextFileA (WININET.@)
316 * Continues a file search from a previous call to FindFirstFile
323 BOOL WINAPI
InternetFindNextFileA(HINTERNET hFind
, LPVOID lpvFindData
)
325 LPWININETAPPINFOA hIC
= NULL
;
326 LPWININETFINDNEXTA lpwh
= (LPWININETFINDNEXTA
) hFind
;
330 if (NULL
== lpwh
|| lpwh
->hdr
.htype
!= WH_HFINDNEXT
)
332 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
336 hIC
= GET_HWININET_FROM_LPWININETFINDNEXT(lpwh
);
337 if (hIC
->hdr
.dwFlags
& INTERNET_FLAG_ASYNC
)
339 WORKREQUEST workRequest
;
341 workRequest
.asyncall
= INTERNETFINDNEXTA
;
342 workRequest
.HFTPSESSION
= (DWORD
)hFind
;
343 workRequest
.LPFINDFILEDATA
= (DWORD
)lpvFindData
;
345 return INTERNET_AsyncCall(&workRequest
);
349 return INTERNET_FindNextFileA(hFind
, lpvFindData
);
353 /***********************************************************************
354 * INTERNET_FindNextFileA (Internal)
356 * Continues a file search from a previous call to FindFirstFile
363 BOOL WINAPI
INTERNET_FindNextFileA(HINTERNET hFind
, LPVOID lpvFindData
)
365 BOOL bSuccess
= TRUE
;
366 LPWININETAPPINFOA hIC
= NULL
;
367 LPWIN32_FIND_DATAA lpFindFileData
;
368 LPWININETFINDNEXTA lpwh
= (LPWININETFINDNEXTA
) hFind
;
372 if (NULL
== lpwh
|| lpwh
->hdr
.htype
!= WH_HFINDNEXT
)
374 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
378 /* Clear any error information */
379 INTERNET_SetLastError(0);
381 if (lpwh
->hdr
.lpwhparent
->htype
!= WH_HFTPSESSION
)
383 FIXME("Only FTP find next supported\n");
384 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
388 TRACE("index(%d) size(%ld)\n", lpwh
->index
, lpwh
->size
);
390 lpFindFileData
= (LPWIN32_FIND_DATAA
) lpvFindData
;
391 ZeroMemory(lpFindFileData
, sizeof(WIN32_FIND_DATAA
));
393 if (lpwh
->index
>= lpwh
->size
)
395 INTERNET_SetLastError(ERROR_NO_MORE_FILES
);
400 FTP_ConvertFileProp(&lpwh
->lpafp
[lpwh
->index
], lpFindFileData
);
403 TRACE("\nName: %s\nSize: %ld\n", lpFindFileData
->cFileName
, lpFindFileData
->nFileSizeLow
);
407 hIC
= GET_HWININET_FROM_LPWININETFINDNEXT(lpwh
);
408 if (hIC
->lpfnStatusCB
)
410 INTERNET_ASYNC_RESULT iar
;
412 iar
.dwResult
= (DWORD
)bSuccess
;
413 iar
.dwError
= iar
.dwError
= bSuccess
? ERROR_SUCCESS
:
414 INTERNET_GetLastError();
416 SendAsyncCallback(hIC
, hFind
, lpwh
->hdr
.dwContext
,
417 INTERNET_STATUS_REQUEST_COMPLETE
, &iar
,
418 sizeof(INTERNET_ASYNC_RESULT
));
425 /***********************************************************************
426 * INTERNET_CloseHandle (internal)
428 * Close internet handle
434 VOID
INTERNET_CloseHandle(LPWININETAPPINFOA lpwai
)
438 SendAsyncCallback(lpwai
, lpwai
, lpwai
->hdr
.dwContext
,
439 INTERNET_STATUS_HANDLE_CLOSING
, lpwai
,
442 if (lpwai
->lpszAgent
)
443 HeapFree(GetProcessHeap(), 0, lpwai
->lpszAgent
);
445 if (lpwai
->lpszProxy
)
446 HeapFree(GetProcessHeap(), 0, lpwai
->lpszProxy
);
448 if (lpwai
->lpszProxyBypass
)
449 HeapFree(GetProcessHeap(), 0, lpwai
->lpszProxyBypass
);
451 HeapFree(GetProcessHeap(), 0, lpwai
);
455 /***********************************************************************
456 * InternetCloseHandle (WININET.@)
458 * Generic close handle function
465 BOOL WINAPI
InternetCloseHandle(HINTERNET hInternet
)
468 LPWININETHANDLEHEADER lpwh
= (LPWININETHANDLEHEADER
) hInternet
;
470 TRACE("%p\n",hInternet
);
475 /* Clear any error information */
476 INTERNET_SetLastError(0);
482 INTERNET_CloseHandle((LPWININETAPPINFOA
) lpwh
);
486 case WH_HHTTPSESSION
:
487 HTTP_CloseHTTPSessionHandle((LPWININETHTTPSESSIONA
) lpwh
);
492 HTTP_CloseHTTPRequestHandle((LPWININETHTTPREQA
) lpwh
);
497 retval
= FTP_CloseSessionHandle((LPWININETFTPSESSIONA
) lpwh
);
501 retval
= FTP_CloseFindNextHandle((LPWININETFINDNEXTA
) lpwh
);
507 } __EXCEPT(page_fault
) {
508 INTERNET_SetLastError(ERROR_INVALID_PARAMETER
);
517 /***********************************************************************
518 * SetUrlComponentValue (Internal)
520 * Helper function for InternetCrackUrlA
527 BOOL
SetUrlComponentValue(LPSTR
* lppszComponent
, LPDWORD dwComponentLen
, LPCSTR lpszStart
, INT len
)
529 TRACE("%s (%d)\n", lpszStart
, len
);
531 if (*dwComponentLen
!= 0)
533 if (*lppszComponent
== NULL
)
535 *lppszComponent
= (LPSTR
)lpszStart
;
536 *dwComponentLen
= len
;
540 INT ncpylen
= min((*dwComponentLen
)-1, len
);
541 strncpy(*lppszComponent
, lpszStart
, ncpylen
);
542 (*lppszComponent
)[ncpylen
] = '\0';
543 *dwComponentLen
= ncpylen
;
551 /***********************************************************************
552 * InternetCrackUrlA (WININET.@)
554 * Break up URL into its components
556 * TODO: Handle dwFlags
563 BOOL WINAPI
InternetCrackUrlA(LPCSTR lpszUrl
, DWORD dwUrlLength
, DWORD dwFlags
,
564 LPURL_COMPONENTSA lpUrlComponents
)
568 * <protocol>:[//<net_loc>][/path][;<params>][?<query>][#<fragment>]
571 LPSTR lpszParam
= NULL
;
572 BOOL bIsAbsolute
= FALSE
;
573 LPSTR lpszap
= (char*)lpszUrl
;
578 /* Determine if the URI is absolute. */
579 while (*lpszap
!= '\0')
581 if (isalnum(*lpszap
))
586 if ((*lpszap
== ':') && (lpszap
- lpszUrl
>= 2))
593 lpszcp
= (LPSTR
)lpszUrl
; /* Relative url */
600 lpszParam
= strpbrk(lpszap
, ";?");
601 if (lpszParam
!= NULL
)
603 if (!SetUrlComponentValue(&lpUrlComponents
->lpszExtraInfo
,
604 &lpUrlComponents
->dwExtraInfoLength
, lpszParam
+1, strlen(lpszParam
+1)))
610 if (bIsAbsolute
) /* Parse <protocol>:[//<net_loc>] */
614 /* Get scheme first. */
615 lpUrlComponents
->nScheme
= GetInternetScheme(lpszUrl
, lpszcp
- lpszUrl
);
616 if (!SetUrlComponentValue(&lpUrlComponents
->lpszScheme
,
617 &lpUrlComponents
->dwSchemeLength
, lpszUrl
, lpszcp
- lpszUrl
))
620 /* Eat ':' in protocol. */
623 /* Skip over slashes. */
635 lpszNetLoc
= strpbrk(lpszcp
, "/");
639 lpszNetLoc
= min(lpszNetLoc
, lpszParam
);
641 lpszNetLoc
= lpszParam
;
643 else if (!lpszNetLoc
)
644 lpszNetLoc
= lpszcp
+ strlen(lpszcp
);
652 /* [<user>[<:password>]@]<host>[:<port>] */
653 /* First find the user and password if they exist */
655 lpszHost
= strchr(lpszcp
, '@');
656 if (lpszHost
== NULL
|| lpszHost
> lpszNetLoc
)
658 /* username and password not specified. */
659 SetUrlComponentValue(&lpUrlComponents
->lpszUserName
,
660 &lpUrlComponents
->dwUserNameLength
, NULL
, 0);
661 SetUrlComponentValue(&lpUrlComponents
->lpszPassword
,
662 &lpUrlComponents
->dwPasswordLength
, NULL
, 0);
664 else /* Parse out username and password */
666 LPSTR lpszUser
= lpszcp
;
667 LPSTR lpszPasswd
= lpszHost
;
669 while (lpszcp
< lpszHost
)
677 SetUrlComponentValue(&lpUrlComponents
->lpszUserName
,
678 &lpUrlComponents
->dwUserNameLength
, lpszUser
, lpszPasswd
- lpszUser
);
680 if (lpszPasswd
!= lpszHost
)
682 SetUrlComponentValue(&lpUrlComponents
->lpszPassword
,
683 &lpUrlComponents
->dwPasswordLength
,
684 lpszPasswd
== lpszHost
? NULL
: lpszPasswd
,
685 lpszHost
- lpszPasswd
);
687 lpszcp
++; /* Advance to beginning of host */
690 /* Parse <host><:port> */
693 lpszPort
= lpszNetLoc
;
695 while (lpszcp
< lpszNetLoc
)
703 SetUrlComponentValue(&lpUrlComponents
->lpszHostName
,
704 &lpUrlComponents
->dwHostNameLength
, lpszHost
, lpszPort
- lpszHost
);
706 if (lpszPort
!= lpszNetLoc
)
707 lpUrlComponents
->nPort
= atoi(++lpszPort
);
709 lpUrlComponents
->nPort
= 0;
713 /* Here lpszcp points to:
715 * <protocol>:[//<net_loc>][/path][;<params>][?<query>][#<fragment>]
716 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
718 if (lpszcp
!= 0 && *lpszcp
!= '\0' && (!lpszParam
|| lpszcp
< lpszParam
))
722 /* Only truncate the parameter list if it's already been saved
723 * in lpUrlComponents->lpszExtraInfo.
725 if (lpszParam
&& lpUrlComponents
->dwExtraInfoLength
)
726 len
= lpszParam
- lpszcp
;
729 /* Leave the parameter list in lpszUrlPath. Strip off any trailing
730 * newlines if necessary.
732 LPSTR lpsznewline
= strchr (lpszcp
, '\n');
733 if (lpsznewline
!= NULL
)
734 len
= lpsznewline
- lpszcp
;
736 len
= strlen(lpszcp
);
739 if (!SetUrlComponentValue(&lpUrlComponents
->lpszUrlPath
,
740 &lpUrlComponents
->dwUrlPathLength
, lpszcp
, len
))
745 lpUrlComponents
->dwUrlPathLength
= 0;
748 TRACE("%s: host(%s) path(%s) extra(%s)\n", lpszUrl
, lpUrlComponents
->lpszHostName
,
749 lpUrlComponents
->lpszUrlPath
, lpUrlComponents
->lpszExtraInfo
);
755 /***********************************************************************
756 * GetUrlCacheEntryInfoA (WININET.@)
759 BOOL WINAPI
GetUrlCacheEntryInfoA(LPCSTR lpszUrl
,
760 LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntry
,
761 LPDWORD lpCacheEntrySize
)
767 /***********************************************************************
768 * CommitUrlCacheEntryA (WININET.@)
771 BOOL WINAPI
CommitUrlCacheEntryA(LPCSTR lpszUrl
, LPCSTR lpszLocalName
,
772 FILETIME ExpireTime
, FILETIME lastModified
, DWORD cacheEntryType
,
773 LPBYTE lpHeaderInfo
, DWORD headerSize
, LPCSTR fileExtension
,
780 /***********************************************************************
781 * InternetAttemptConnect (WININET.@)
783 * Attempt to make a connection to the internet
786 * ERROR_SUCCESS on success
787 * Error value on failure
790 DWORD WINAPI
InternetAttemptConnect(DWORD dwReserved
)
793 return ERROR_SUCCESS
;
797 /***********************************************************************
798 * InternetCanonicalizeUrlA (WININET.@)
800 * Escape unsafe characters and spaces
807 BOOL WINAPI
InternetCanonicalizeUrlA(LPCSTR lpszUrl
, LPSTR lpszBuffer
,
808 LPDWORD lpdwBufferLength
, DWORD dwFlags
)
811 TRACE("%s %p %p %08lx\n",debugstr_a(lpszUrl
), lpszBuffer
,
812 lpdwBufferLength
, dwFlags
);
814 /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
815 dwFlags
^= ICU_NO_ENCODE
;
817 dwFlags
|= 0x80000000; /* Don't know what this means */
819 hr
= UrlCanonicalizeA(lpszUrl
, lpszBuffer
, lpdwBufferLength
, dwFlags
);
821 return (hr
== S_OK
) ? TRUE
: FALSE
;
824 /***********************************************************************
825 * InternetSetStatusCallback (WININET.@)
827 * Sets up a callback function which is called as progress is made
828 * during an operation.
831 * Previous callback or NULL on success
832 * INTERNET_INVALID_STATUS_CALLBACK on failure
835 INTERNET_STATUS_CALLBACK WINAPI
InternetSetStatusCallback(
836 HINTERNET hInternet
,INTERNET_STATUS_CALLBACK lpfnIntCB
)
838 INTERNET_STATUS_CALLBACK retVal
;
839 LPWININETAPPINFOA lpwai
= (LPWININETAPPINFOA
)hInternet
;
841 TRACE("0x%08lx\n", (ULONG
)hInternet
);
842 if (lpwai
->hdr
.htype
!= WH_HINIT
)
843 return INTERNET_INVALID_STATUS_CALLBACK
;
845 retVal
= lpwai
->lpfnStatusCB
;
846 lpwai
->lpfnStatusCB
= lpfnIntCB
;
852 /***********************************************************************
853 * InternetWriteFile (WININET.@)
855 * Write data to an open internet file
862 BOOL WINAPI
InternetWriteFile(HINTERNET hFile
, LPCVOID lpBuffer
,
863 DWORD dwNumOfBytesToWrite
, LPDWORD lpdwNumOfBytesWritten
)
867 LPWININETHANDLEHEADER lpwh
= (LPWININETHANDLEHEADER
) hFile
;
876 nSocket
= ((LPWININETHTTPREQA
)hFile
)->nSocketFD
;
880 nSocket
= ((LPWININETFILE
)hFile
)->nDataSocket
;
889 int res
= send(nSocket
, lpBuffer
, dwNumOfBytesToWrite
, 0);
891 *lpdwNumOfBytesWritten
= retval
? res
: 0;
898 /***********************************************************************
899 * InternetReadFile (WININET.@)
901 * Read data from an open internet file
908 BOOL WINAPI
InternetReadFile(HINTERNET hFile
, LPVOID lpBuffer
,
909 DWORD dwNumOfBytesToRead
, LPDWORD dwNumOfBytesRead
)
913 LPWININETHANDLEHEADER lpwh
= (LPWININETHANDLEHEADER
) hFile
;
923 nSocket
= ((LPWININETHTTPREQA
)hFile
)->nSocketFD
;
927 nSocket
= ((LPWININETFILE
)hFile
)->nDataSocket
;
936 int res
= recv(nSocket
, lpBuffer
, dwNumOfBytesToRead
, 0);
938 *dwNumOfBytesRead
= retval
? res
: 0;
943 /***********************************************************************
944 * InternetReadFileExA (WININET.@)
946 * Read data from an open internet file
953 BOOL WINAPI
InternetReadFileExA(HINTERNET hFile
, LPINTERNET_BUFFERSA lpBuffer
,
954 DWORD dwFlags
, DWORD dwContext
)
960 /***********************************************************************
961 * InternetReadFileExW (WININET.@)
963 * Read data from an open internet file
970 BOOL WINAPI
InternetReadFileExW(HINTERNET hFile
, LPINTERNET_BUFFERSW lpBuffer
,
971 DWORD dwFlags
, DWORD dwContext
)
975 INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
979 /***********************************************************************
980 * InternetQueryOptionA (WININET.@)
982 * Queries an options on the specified handle
989 BOOL WINAPI
InternetQueryOptionA(HINTERNET hInternet
, DWORD dwOption
,
990 LPVOID lpBuffer
, LPDWORD lpdwBufferLength
)
992 LPWININETHANDLEHEADER lpwhh
;
993 BOOL bSuccess
= FALSE
;
995 TRACE("0x%08lx\n", dwOption
);
997 if (NULL
== hInternet
)
999 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
1003 lpwhh
= (LPWININETHANDLEHEADER
) hInternet
;
1007 case INTERNET_OPTION_HANDLE_TYPE
:
1009 ULONG type
= lpwhh
->htype
;
1010 TRACE("INTERNET_OPTION_HANDLE_TYPE: %ld\n", type
);
1012 if (*lpdwBufferLength
< sizeof(ULONG
))
1013 INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1016 memcpy(lpBuffer
, &type
, sizeof(ULONG
));
1017 *lpdwBufferLength
= sizeof(ULONG
);
1023 case INTERNET_OPTION_REQUEST_FLAGS
:
1026 TRACE("INTERNET_OPTION_REQUEST_FLAGS: %ld\n", flags
);
1027 if (*lpdwBufferLength
< sizeof(ULONG
))
1028 INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1031 memcpy(lpBuffer
, &flags
, sizeof(ULONG
));
1032 *lpdwBufferLength
= sizeof(ULONG
);
1038 case INTERNET_OPTION_URL
:
1039 case INTERNET_OPTION_DATAFILE_NAME
:
1041 ULONG type
= lpwhh
->htype
;
1042 if (type
== WH_HHTTPREQ
)
1044 LPWININETHTTPREQA lpreq
= hInternet
;
1047 sprintf(url
,"http://%s%s",lpreq
->lpszHostName
,lpreq
->lpszPath
);
1048 TRACE("INTERNET_OPTION_URL: %s\n",url
);
1049 if (*lpdwBufferLength
< strlen(url
)+1)
1050 INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1053 memcpy(lpBuffer
, url
, strlen(url
)+1);
1054 *lpdwBufferLength
= strlen(url
)+1;
1060 case INTERNET_OPTION_HTTP_VERSION
:
1063 * Presently hardcoded to 1.1
1065 ((HTTP_VERSION_INFO
*)lpBuffer
)->dwMajorVersion
= 1;
1066 ((HTTP_VERSION_INFO
*)lpBuffer
)->dwMinorVersion
= 1;
1072 FIXME("Stub! %ld \n",dwOption
);
1080 /***********************************************************************
1081 * InternetSetOptionW (WININET.@)
1083 * Sets an options on the specified handle
1090 BOOL WINAPI
InternetSetOptionW(HINTERNET hInternet
, DWORD dwOption
,
1091 LPVOID lpBuffer
, DWORD dwBufferLength
)
1093 LPWININETHANDLEHEADER lpwhh
;
1094 BOOL bSuccess
= FALSE
;
1096 TRACE("0x%08lx\n", dwOption
);
1098 if (NULL
== hInternet
)
1100 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
1104 lpwhh
= (LPWININETHANDLEHEADER
) hInternet
;
1109 INTERNET_SetLastError(ERROR_INVALID_PARAMETER
);
1118 /***********************************************************************
1119 * InternetSetOptionA (WININET.@)
1121 * Sets an options on the specified handle.
1128 BOOL WINAPI
InternetSetOptionA(HINTERNET hInternet
, DWORD dwOption
,
1129 LPVOID lpBuffer
, DWORD dwBufferLength
)
1131 /* FIXME!!! implement if lpBuffer is a string, dwBufferLength is
1133 return InternetSetOptionW(hInternet
,dwOption
, lpBuffer
,
1138 /***********************************************************************
1139 * InternetGetCookieA (WININET.@)
1141 * Retrieve cookie from the specified url
1148 BOOL WINAPI
InternetGetCookieA(LPCSTR lpszUrl
, LPCSTR lpszCookieName
,
1149 LPSTR lpCookieData
, LPDWORD lpdwSize
)
1151 FIXME("(%s,%s,%p), stub!\n",debugstr_a(lpszUrl
),debugstr_a(lpszCookieName
),
1156 /***********************************************************************
1157 * InternetSetCookieA (WININET.@)
1159 * Sets cookie for the specified url
1166 BOOL WINAPI
InternetSetCookieA(
1167 LPCSTR lpszUrl
, LPCSTR lpszCookieName
, LPCSTR lpCookieData
1169 FIXME("(%s,%s,%s), stub!\n",debugstr_a(lpszUrl
),debugstr_a(lpszCookieName
),debugstr_a(lpCookieData
));
1173 /***********************************************************************
1174 * GetInternetScheme (internal)
1180 * INTERNET_SCHEME_UNKNOWN on failure
1183 INTERNET_SCHEME
GetInternetScheme(LPCSTR lpszScheme
, INT nMaxCmp
)
1186 if(lpszScheme
==NULL
)
1187 return INTERNET_SCHEME_UNKNOWN
;
1189 if (!strncasecmp("ftp", lpszScheme
, nMaxCmp
))
1190 return INTERNET_SCHEME_FTP
;
1191 else if (!strncasecmp("gopher", lpszScheme
, nMaxCmp
))
1192 return INTERNET_SCHEME_GOPHER
;
1193 else if (!strncasecmp("http", lpszScheme
, nMaxCmp
))
1194 return INTERNET_SCHEME_HTTP
;
1195 else if (!strncasecmp("https", lpszScheme
, nMaxCmp
))
1196 return INTERNET_SCHEME_HTTPS
;
1197 else if (!strncasecmp("file", lpszScheme
, nMaxCmp
))
1198 return INTERNET_SCHEME_FILE
;
1199 else if (!strncasecmp("news", lpszScheme
, nMaxCmp
))
1200 return INTERNET_SCHEME_NEWS
;
1201 else if (!strncasecmp("mailto", lpszScheme
, nMaxCmp
))
1202 return INTERNET_SCHEME_MAILTO
;
1204 return INTERNET_SCHEME_UNKNOWN
;
1207 /***********************************************************************
1208 * InternetCheckConnectionA (WININET.@)
1210 * Pings a requested host to check internet connection
1214 * TRUE on success and FALSE on failure. if a failures then
1215 * ERROR_NOT_CONNECTED is places into GetLastError
1218 BOOL WINAPI
InternetCheckConnectionA( LPCSTR lpszUrl
, DWORD dwFlags
, DWORD dwReserved
)
1221 * this is a kludge which runs the resident ping program and reads the output.
1223 * Anyone have a better idea?
1234 * Crack or set the Address
1236 if (lpszUrl
== NULL
)
1239 * According to the doc we are supost to use the ip for the next
1240 * server in the WnInet internal server database. I have
1241 * no idea what that is or how to get it.
1243 * So someone needs to implement this.
1245 FIXME("Unimplemented with URL of NULL\n");
1250 URL_COMPONENTSA componets
;
1252 ZeroMemory(&componets
,sizeof(URL_COMPONENTSA
));
1253 componets
.lpszHostName
= (LPSTR
)&host
;
1254 componets
.dwHostNameLength
= 1024;
1256 if (!InternetCrackUrlA(lpszUrl
,0,0,&componets
))
1259 TRACE("host name : %s\n",componets
.lpszHostName
);
1263 * Build our ping command
1265 strcpy(command
,"ping -w 1 ");
1266 strcat(command
,host
);
1267 strcat(command
," >/dev/null 2>/dev/null");
1269 TRACE("Ping command is : %s\n",command
);
1271 status
= system(command
);
1273 TRACE("Ping returned a code of %i \n",status
);
1275 /* Ping return code of 0 indicates success */
1282 SetLastError(ERROR_NOT_CONNECTED
);
1287 /**********************************************************
1288 * InternetOpenUrlA (WININET.@)
1293 * handle of connection or NULL on failure
1295 HINTERNET WINAPI
InternetOpenUrlA(HINTERNET hInternet
, LPCSTR lpszUrl
, LPCSTR lpszHeaders
, DWORD dwHeadersLength
, DWORD dwFlags
, DWORD dwContext
)
1297 URL_COMPONENTSA urlComponents
;
1298 char protocol
[32], hostName
[MAXHOSTNAME
], userName
[1024], password
[1024], path
[2048], extra
[1024];
1299 HINTERNET client
= NULL
, client1
= NULL
;
1300 urlComponents
.dwStructSize
= sizeof(URL_COMPONENTSA
);
1301 urlComponents
.lpszScheme
= protocol
;
1302 urlComponents
.dwSchemeLength
= 32;
1303 urlComponents
.lpszHostName
= hostName
;
1304 urlComponents
.dwHostNameLength
= MAXHOSTNAME
;
1305 urlComponents
.lpszUserName
= userName
;
1306 urlComponents
.dwUserNameLength
= 1024;
1307 urlComponents
.lpszPassword
= password
;
1308 urlComponents
.dwPasswordLength
= 1024;
1309 urlComponents
.lpszUrlPath
= path
;
1310 urlComponents
.dwUrlPathLength
= 2048;
1311 urlComponents
.lpszExtraInfo
= extra
;
1312 urlComponents
.dwExtraInfoLength
= 1024;
1313 if(!InternetCrackUrlA(lpszUrl
, strlen(lpszUrl
), 0, &urlComponents
))
1315 switch(urlComponents
.nScheme
) {
1316 case INTERNET_SCHEME_FTP
:
1317 if(urlComponents
.nPort
== 0)
1318 urlComponents
.nPort
= INTERNET_DEFAULT_FTP_PORT
;
1319 client
= InternetConnectA(hInternet
, hostName
, urlComponents
.nPort
, userName
, password
, INTERNET_SERVICE_FTP
, dwFlags
, dwContext
);
1320 return FtpOpenFileA(client
, path
, GENERIC_READ
, dwFlags
, dwContext
);
1322 case INTERNET_SCHEME_HTTP
:
1323 case INTERNET_SCHEME_HTTPS
:
1325 LPCSTR accept
[2] = { "*/*", NULL
};
1326 char *hostreq
=(char*)malloc(strlen(hostName
)+9);
1327 sprintf(hostreq
, "Host: %s\r\n", hostName
);
1328 if(urlComponents
.nPort
== 0) {
1329 if(urlComponents
.nScheme
== INTERNET_SCHEME_HTTP
)
1330 urlComponents
.nPort
= INTERNET_DEFAULT_HTTP_PORT
;
1332 urlComponents
.nPort
= INTERNET_DEFAULT_HTTPS_PORT
;
1334 client
= InternetConnectA(hInternet
, hostName
, urlComponents
.nPort
, userName
, password
, INTERNET_SERVICE_HTTP
, dwFlags
, dwContext
);
1337 client1
= HttpOpenRequestA(hInternet
, NULL
, path
, NULL
, NULL
, accept
, dwFlags
, dwContext
);
1338 if(client1
== NULL
) {
1339 InternetCloseHandle(client
);
1342 HttpAddRequestHeadersA(client1
, lpszHeaders
, dwHeadersLength
, HTTP_ADDREQ_FLAG_ADD
);
1343 HttpAddRequestHeadersA(client1
, hostreq
, -1L, HTTP_ADDREQ_FLAG_ADD_IF_NEW
);
1344 if(!HttpSendRequestA(client1
, NULL
, 0, NULL
, 0)) {
1345 InternetCloseHandle(client1
);
1346 InternetCloseHandle(client
);
1352 case INTERNET_SCHEME_GOPHER
:
1353 /* gopher doesn't seem to be implemented in wine, but it's supposed
1354 * to be supported by InternetOpenUrlA. */
1359 InternetCloseHandle(client
);
1363 /***********************************************************************
1364 * INTERNET_SetLastError (internal)
1366 * Set last thread specific error
1371 void INTERNET_SetLastError(DWORD dwError
)
1373 LPWITHREADERROR lpwite
= (LPWITHREADERROR
)TlsGetValue(g_dwTlsErrIndex
);
1375 SetLastError(dwError
);
1376 lpwite
->dwError
= dwError
;
1380 /***********************************************************************
1381 * INTERNET_GetLastError (internal)
1383 * Get last thread specific error
1388 DWORD
INTERNET_GetLastError()
1390 LPWITHREADERROR lpwite
= (LPWITHREADERROR
)TlsGetValue(g_dwTlsErrIndex
);
1391 return lpwite
->dwError
;
1395 /***********************************************************************
1396 * INTERNET_WorkerThreadFunc (internal)
1398 * Worker thread execution function
1403 DWORD
INTERNET_WorkerThreadFunc(LPVOID
*lpvParam
)
1409 dwWaitRes
= WaitForMultipleObjects(2, hEventArray
, FALSE
, MAX_IDLE_WORKER
);
1411 if (dwWaitRes
== WAIT_OBJECT_0
+ 1)
1412 INTERNET_ExecuteWork();
1416 InterlockedIncrement(&dwNumIdleThreads
);
1419 InterlockedDecrement(&dwNumIdleThreads
);
1420 InterlockedDecrement(&dwNumThreads
);
1421 TRACE("Worker thread exiting\n");
1426 /***********************************************************************
1427 * INTERNET_InsertWorkRequest (internal)
1429 * Insert work request into queue
1434 BOOL
INTERNET_InsertWorkRequest(LPWORKREQUEST lpWorkRequest
)
1436 BOOL bSuccess
= FALSE
;
1437 LPWORKREQUEST lpNewRequest
;
1441 lpNewRequest
= HeapAlloc(GetProcessHeap(), 0, sizeof(WORKREQUEST
));
1444 memcpy(lpNewRequest
, lpWorkRequest
, sizeof(WORKREQUEST
));
1445 lpNewRequest
->prev
= NULL
;
1447 EnterCriticalSection(&csQueue
);
1449 lpNewRequest
->next
= lpWorkQueueTail
;
1450 if (lpWorkQueueTail
)
1451 lpWorkQueueTail
->prev
= lpNewRequest
;
1452 lpWorkQueueTail
= lpNewRequest
;
1453 if (!lpHeadWorkQueue
)
1454 lpHeadWorkQueue
= lpWorkQueueTail
;
1456 LeaveCriticalSection(&csQueue
);
1465 /***********************************************************************
1466 * INTERNET_GetWorkRequest (internal)
1468 * Retrieves work request from queue
1473 BOOL
INTERNET_GetWorkRequest(LPWORKREQUEST lpWorkRequest
)
1475 BOOL bSuccess
= FALSE
;
1476 LPWORKREQUEST lpRequest
= NULL
;
1480 EnterCriticalSection(&csQueue
);
1482 if (lpHeadWorkQueue
)
1484 lpRequest
= lpHeadWorkQueue
;
1485 lpHeadWorkQueue
= lpHeadWorkQueue
->prev
;
1486 if (lpRequest
== lpWorkQueueTail
)
1487 lpWorkQueueTail
= lpHeadWorkQueue
;
1490 LeaveCriticalSection(&csQueue
);
1494 memcpy(lpWorkRequest
, lpRequest
, sizeof(WORKREQUEST
));
1495 HeapFree(GetProcessHeap(), 0, lpRequest
);
1503 /***********************************************************************
1504 * INTERNET_AsyncCall (internal)
1506 * Retrieves work request from queue
1511 BOOL
INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest
)
1515 BOOL bSuccess
= FALSE
;
1519 if (InterlockedDecrement(&dwNumIdleThreads
) < 0)
1521 InterlockedIncrement(&dwNumIdleThreads
);
1523 if (InterlockedIncrement(&dwNumThreads
) > MAX_WORKER_THREADS
||
1524 !(hThread
= CreateThread(NULL
, 0,
1525 (LPTHREAD_START_ROUTINE
)INTERNET_WorkerThreadFunc
, NULL
, 0, &dwTID
)))
1527 InterlockedDecrement(&dwNumThreads
);
1528 INTERNET_SetLastError(ERROR_INTERNET_ASYNC_THREAD_FAILED
);
1532 TRACE("Created new thread\n");
1536 INTERNET_InsertWorkRequest(lpWorkRequest
);
1537 SetEvent(hWorkEvent
);
1545 /***********************************************************************
1546 * INTERNET_ExecuteWork (internal)
1551 VOID
INTERNET_ExecuteWork()
1553 WORKREQUEST workRequest
;
1557 if (INTERNET_GetWorkRequest(&workRequest
))
1559 switch (workRequest
.asyncall
)
1562 FTP_FtpPutFileA((HINTERNET
)workRequest
.HFTPSESSION
, (LPCSTR
)workRequest
.LPSZLOCALFILE
,
1563 (LPCSTR
)workRequest
.LPSZNEWREMOTEFILE
, workRequest
.DWFLAGS
, workRequest
.DWCONTEXT
);
1564 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZLOCALFILE
);
1565 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZNEWREMOTEFILE
);
1568 case FTPSETCURRENTDIRECTORYA
:
1569 FTP_FtpSetCurrentDirectoryA((HINTERNET
)workRequest
.HFTPSESSION
,
1570 (LPCSTR
)workRequest
.LPSZDIRECTORY
);
1571 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZDIRECTORY
);
1574 case FTPCREATEDIRECTORYA
:
1575 FTP_FtpCreateDirectoryA((HINTERNET
)workRequest
.HFTPSESSION
,
1576 (LPCSTR
)workRequest
.LPSZDIRECTORY
);
1577 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZDIRECTORY
);
1580 case FTPFINDFIRSTFILEA
:
1581 FTP_FtpFindFirstFileA((HINTERNET
)workRequest
.HFTPSESSION
,
1582 (LPCSTR
)workRequest
.LPSZSEARCHFILE
,
1583 (LPWIN32_FIND_DATAA
)workRequest
.LPFINDFILEDATA
, workRequest
.DWFLAGS
,
1584 workRequest
.DWCONTEXT
);
1585 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZSEARCHFILE
);
1588 case FTPGETCURRENTDIRECTORYA
:
1589 FTP_FtpGetCurrentDirectoryA((HINTERNET
)workRequest
.HFTPSESSION
,
1590 (LPSTR
)workRequest
.LPSZDIRECTORY
, (LPDWORD
)workRequest
.LPDWDIRECTORY
);
1594 FTP_FtpOpenFileA((HINTERNET
)workRequest
.HFTPSESSION
,
1595 (LPCSTR
)workRequest
.LPSZFILENAME
,
1596 workRequest
.FDWACCESS
,
1597 workRequest
.DWFLAGS
,
1598 workRequest
.DWCONTEXT
);
1599 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZFILENAME
);
1603 FTP_FtpGetFileA((HINTERNET
)workRequest
.HFTPSESSION
,
1604 (LPCSTR
)workRequest
.LPSZREMOTEFILE
,
1605 (LPCSTR
)workRequest
.LPSZNEWFILE
,
1606 (BOOL
)workRequest
.FFAILIFEXISTS
,
1607 workRequest
.DWLOCALFLAGSATTRIBUTE
,
1608 workRequest
.DWFLAGS
,
1609 workRequest
.DWCONTEXT
);
1610 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZREMOTEFILE
);
1611 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZNEWFILE
);
1614 case FTPDELETEFILEA
:
1615 FTP_FtpDeleteFileA((HINTERNET
)workRequest
.HFTPSESSION
,
1616 (LPCSTR
)workRequest
.LPSZFILENAME
);
1617 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZFILENAME
);
1620 case FTPREMOVEDIRECTORYA
:
1621 FTP_FtpRemoveDirectoryA((HINTERNET
)workRequest
.HFTPSESSION
,
1622 (LPCSTR
)workRequest
.LPSZDIRECTORY
);
1623 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZDIRECTORY
);
1626 case FTPRENAMEFILEA
:
1627 FTP_FtpRenameFileA((HINTERNET
)workRequest
.HFTPSESSION
,
1628 (LPCSTR
)workRequest
.LPSZSRCFILE
,
1629 (LPCSTR
)workRequest
.LPSZDESTFILE
);
1630 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZSRCFILE
);
1631 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZDESTFILE
);
1634 case INTERNETFINDNEXTA
:
1635 INTERNET_FindNextFileA((HINTERNET
)workRequest
.HFTPSESSION
,
1636 (LPWIN32_FIND_DATAA
)workRequest
.LPFINDFILEDATA
);
1639 case HTTPSENDREQUESTA
:
1640 HTTP_HttpSendRequestA((HINTERNET
)workRequest
.HFTPSESSION
,
1641 (LPCSTR
)workRequest
.LPSZHEADER
,
1642 workRequest
.DWHEADERLENGTH
,
1643 (LPVOID
)workRequest
.LPOPTIONAL
,
1644 workRequest
.DWOPTIONALLENGTH
);
1645 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZHEADER
);
1648 case HTTPOPENREQUESTA
:
1649 HTTP_HttpOpenRequestA((HINTERNET
)workRequest
.HFTPSESSION
,
1650 (LPCSTR
)workRequest
.LPSZVERB
,
1651 (LPCSTR
)workRequest
.LPSZOBJECTNAME
,
1652 (LPCSTR
)workRequest
.LPSZVERSION
,
1653 (LPCSTR
)workRequest
.LPSZREFERRER
,
1654 (LPCSTR
*)workRequest
.LPSZACCEPTTYPES
,
1655 workRequest
.DWFLAGS
,
1656 workRequest
.DWCONTEXT
);
1657 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZVERB
);
1658 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZOBJECTNAME
);
1659 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZVERSION
);
1660 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZREFERRER
);
1664 SendAsyncCallbackInt((LPWININETAPPINFOA
)workRequest
.param1
,
1665 (HINTERNET
)workRequest
.param2
, workRequest
.param3
,
1666 workRequest
.param4
, (LPVOID
)workRequest
.param5
,
1667 workRequest
.param6
);
1674 /***********************************************************************
1675 * INTERNET_GetResponseBuffer
1680 LPSTR
INTERNET_GetResponseBuffer()
1682 LPWITHREADERROR lpwite
= (LPWITHREADERROR
)TlsGetValue(g_dwTlsErrIndex
);
1684 return lpwite
->response
;
1688 /***********************************************************************
1689 * INTERNET_GetNextLine (internal)
1691 * Parse next line in directory string listing
1694 * Pointer to beginning of next line
1699 LPSTR
INTERNET_GetNextLine(INT nSocket
, LPSTR lpszBuffer
, LPDWORD dwBuffer
)
1703 BOOL bSuccess
= FALSE
;
1709 FD_SET(nSocket
, &infd
);
1710 tv
.tv_sec
=RESPONSE_TIMEOUT
;
1713 while (nRecv
< *dwBuffer
)
1715 if (select(nSocket
+1,&infd
,NULL
,NULL
,&tv
) > 0)
1717 if (recv(nSocket
, &lpszBuffer
[nRecv
], 1, 0) <= 0)
1719 INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS
);
1723 if (lpszBuffer
[nRecv
] == '\n')
1728 if (lpszBuffer
[nRecv
] != '\r')
1733 INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT
);
1741 lpszBuffer
[nRecv
] = '\0';
1742 *dwBuffer
= nRecv
- 1;
1743 TRACE(":%d %s\n", nRecv
, lpszBuffer
);
1752 /***********************************************************************
1755 BOOL WINAPI
InternetQueryDataAvailable( HINTERNET hFile
,
1756 LPDWORD lpdwNumberOfBytesAvailble
,
1757 DWORD dwFlags
, DWORD dwConext
)
1759 LPWININETHTTPREQA lpwhr
= (LPWININETHTTPREQA
) hFile
;
1766 SetLastError(ERROR_NO_MORE_FILES
);
1770 TRACE("--> %p %i %i\n",lpwhr
,lpwhr
->hdr
.htype
,lpwhr
->nSocketFD
);
1772 switch (lpwhr
->hdr
.htype
)
1775 nSocket
= lpwhr
->nSocketFD
;
1786 retval
= recv(nSocket
,buffer
,4048,MSG_PEEK
);
1790 SetLastError(ERROR_NO_MORE_FILES
);
1793 if (lpdwNumberOfBytesAvailble
)
1795 (*lpdwNumberOfBytesAvailble
) = retval
;
1798 TRACE("<-- %i\n",retval
);
1803 /***********************************************************************
1806 BOOL WINAPI
InternetLockRequestFile( HINTERNET hInternet
, HANDLE
1813 BOOL WINAPI
InternetUnlockRequestFile( HANDLE hLockHandle
)
1820 /***********************************************************************
1823 * On windows this function is supposed to dial the default internet
1824 * connection. We don't want to have Wine dial out to the internet so
1825 * we return TRUE by default. It might be nice to check if we are connected.
1833 BOOL WINAPI
InternetAutoDial(DWORD dwFlags
, HWND hwndParent
)
1837 /* Tell that we are connected to the internet. */