4 * Copyright 1999 Corel Corporation
5 * Copyright 2002 CodeWeavers Inc.
6 * Copyright 2002 Jaco Greeff
7 * Copyright 2002 TransGaming Technologies Inc.
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #define MAXHOSTNAME 100 /* from http.c */
34 #include <sys/types.h>
35 #ifdef HAVE_SYS_SOCKET_H
36 # include <sys/socket.h>
38 #ifdef HAVE_SYS_TIME_H
39 # include <sys/time.h>
52 #include "wine/debug.h"
54 #define NO_SHLWAPI_STREAM
57 #include "wine/exception.h"
62 #include "wine/unicode.h"
64 WINE_DEFAULT_DEBUG_CHANNEL(wininet
);
66 #define MAX_IDLE_WORKER 1000*60*1
67 #define MAX_WORKER_THREADS 10
68 #define RESPONSE_TIMEOUT 30
70 #define GET_HWININET_FROM_LPWININETFINDNEXT(lpwh) \
71 (LPWININETAPPINFOA)(((LPWININETFTPSESSIONA)(lpwh->hdr.lpwhparent))->hdr.lpwhparent)
73 /* filter for page-fault exceptions */
74 static WINE_EXCEPTION_FILTER(page_fault
)
76 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
||
77 GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION
)
78 return EXCEPTION_EXECUTE_HANDLER
;
79 return EXCEPTION_CONTINUE_SEARCH
;
85 CHAR response
[MAX_REPLY_LEN
];
86 } WITHREADERROR
, *LPWITHREADERROR
;
88 BOOL WINAPI
INTERNET_FindNextFileA(HINTERNET hFind
, LPVOID lpvFindData
);
89 VOID
INTERNET_ExecuteWork();
91 DWORD g_dwTlsErrIndex
= TLS_OUT_OF_INDEXES
;
93 DWORD dwNumIdleThreads
;
95 HANDLE hEventArray
[2];
96 #define hQuitEvent hEventArray[0]
97 #define hWorkEvent hEventArray[1]
98 CRITICAL_SECTION csQueue
;
99 LPWORKREQUEST lpHeadWorkQueue
;
100 LPWORKREQUEST lpWorkQueueTail
;
102 /***********************************************************************
103 * DllMain [Internal] Initializes the internal 'WININET.DLL'.
106 * hinstDLL [I] handle to the DLL's instance
108 * lpvReserved [I] reserved, must be NULL
115 BOOL WINAPI
DllMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
117 TRACE("%p,%lx,%p\n", hinstDLL
, fdwReason
, lpvReserved
);
120 case DLL_PROCESS_ATTACH
:
122 g_dwTlsErrIndex
= TlsAlloc();
124 if (g_dwTlsErrIndex
== TLS_OUT_OF_INDEXES
)
127 hQuitEvent
= CreateEventA(0, TRUE
, FALSE
, NULL
);
128 hWorkEvent
= CreateEventA(0, FALSE
, FALSE
, NULL
);
129 InitializeCriticalSection(&csQueue
);
132 dwNumIdleThreads
= 0;
135 case DLL_THREAD_ATTACH
:
137 LPWITHREADERROR lpwite
= HeapAlloc(GetProcessHeap(), 0, sizeof(WITHREADERROR
));
141 TlsSetValue(g_dwTlsErrIndex
, (LPVOID
)lpwite
);
145 case DLL_THREAD_DETACH
:
146 if (g_dwTlsErrIndex
!= TLS_OUT_OF_INDEXES
)
148 LPVOID lpwite
= TlsGetValue(g_dwTlsErrIndex
);
150 HeapFree(GetProcessHeap(), 0, lpwite
);
154 case DLL_PROCESS_DETACH
:
156 if (g_dwTlsErrIndex
!= TLS_OUT_OF_INDEXES
)
158 HeapFree(GetProcessHeap(), 0, TlsGetValue(g_dwTlsErrIndex
));
159 TlsFree(g_dwTlsErrIndex
);
162 SetEvent(hQuitEvent
);
164 CloseHandle(hQuitEvent
);
165 CloseHandle(hWorkEvent
);
166 DeleteCriticalSection(&csQueue
);
174 /***********************************************************************
175 * InternetInitializeAutoProxyDll (WININET.@)
177 * Setup the internal proxy
186 BOOL WINAPI
InternetInitializeAutoProxyDll(DWORD dwReserved
)
189 INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
193 /***********************************************************************
194 * DetectAutoProxyUrl (WININET.@)
196 * Auto detect the proxy url
202 BOOL WINAPI
DetectAutoProxyUrl(LPSTR lpszAutoProxyUrl
,
203 DWORD dwAutoProxyUrlLength
, DWORD dwDetectFlags
)
206 INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
211 /***********************************************************************
212 * InternetOpenA (WININET.@)
214 * Per-application initialization of wininet
217 * HINTERNET on success
221 HINTERNET WINAPI
InternetOpenA(LPCSTR lpszAgent
, DWORD dwAccessType
,
222 LPCSTR lpszProxy
, LPCSTR lpszProxyBypass
, DWORD dwFlags
)
224 LPWININETAPPINFOA lpwai
= NULL
;
226 TRACE("(%s, %li, %s, %s, %li)\n", debugstr_a(lpszAgent
), dwAccessType
,
227 debugstr_a(lpszProxy
), debugstr_a(lpszProxyBypass
), dwFlags
);
229 /* Clear any error information */
230 INTERNET_SetLastError(0);
232 lpwai
= HeapAlloc(GetProcessHeap(), 0, sizeof(WININETAPPINFOA
));
234 INTERNET_SetLastError(ERROR_OUTOFMEMORY
);
237 memset(lpwai
, 0, sizeof(WININETAPPINFOA
));
238 lpwai
->hdr
.htype
= WH_HINIT
;
239 lpwai
->hdr
.lpwhparent
= NULL
;
240 lpwai
->hdr
.dwFlags
= dwFlags
;
241 if (NULL
!= lpszAgent
)
243 if ((lpwai
->lpszAgent
= HeapAlloc( GetProcessHeap(),0,strlen(lpszAgent
)+1)))
244 strcpy( lpwai
->lpszAgent
, lpszAgent
);
246 if(dwAccessType
== INTERNET_OPEN_TYPE_PRECONFIG
)
249 if (!RegOpenKeyA(HKEY_CURRENT_USER
, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", &key
))
251 DWORD keytype
, len
, enabled
;
252 RegQueryValueExA(key
, "ProxyEnable", NULL
, NULL
, (BYTE
*)&enabled
, NULL
);
255 if(!RegQueryValueExA(key
, "ProxyServer", NULL
, &keytype
, NULL
, &len
) && len
&& keytype
== REG_SZ
)
257 lpwai
->lpszProxy
=HeapAlloc( GetProcessHeap(), 0, len
+1 );
258 RegQueryValueExA(key
, "ProxyServer", NULL
, &keytype
, (BYTE
*)lpwai
->lpszProxy
, &len
);
259 TRACE("Proxy = %s\n", lpwai
->lpszProxy
);
260 dwAccessType
= INTERNET_OPEN_TYPE_PROXY
;
265 TRACE("Proxy is not enabled.\n");
270 else if (NULL
!= lpszProxy
)
272 if ((lpwai
->lpszProxy
= HeapAlloc( GetProcessHeap(), 0, strlen(lpszProxy
)+1 )))
273 strcpy( lpwai
->lpszProxy
, lpszProxy
);
275 if (NULL
!= lpszProxyBypass
)
277 if ((lpwai
->lpszProxyBypass
= HeapAlloc( GetProcessHeap(), 0, strlen(lpszProxyBypass
)+1)))
278 strcpy( lpwai
->lpszProxyBypass
, lpszProxyBypass
);
280 lpwai
->dwAccessType
= dwAccessType
;
283 TRACE("returning %p\n", (HINTERNET
)lpwai
);
284 return (HINTERNET
)lpwai
;
288 /***********************************************************************
289 * InternetOpenW (WININET.@)
291 * Per-application initialization of wininet
294 * HINTERNET on success
298 HINTERNET WINAPI
InternetOpenW(LPCWSTR lpszAgent
, DWORD dwAccessType
,
299 LPCWSTR lpszProxy
, LPCWSTR lpszProxyBypass
, DWORD dwFlags
)
301 HINTERNET rc
= (HINTERNET
)NULL
;
302 INT lenAgent
= lstrlenW(lpszAgent
)+1;
303 INT lenProxy
= lstrlenW(lpszProxy
)+1;
304 INT lenBypass
= lstrlenW(lpszProxyBypass
)+1;
305 CHAR
*szAgent
= (CHAR
*)HeapAlloc(GetProcessHeap(), 0, lenAgent
*sizeof(CHAR
));
306 CHAR
*szProxy
= (CHAR
*)HeapAlloc(GetProcessHeap(), 0, lenProxy
*sizeof(CHAR
));
307 CHAR
*szBypass
= (CHAR
*)HeapAlloc(GetProcessHeap(), 0, lenBypass
*sizeof(CHAR
));
309 if (!szAgent
|| !szProxy
|| !szBypass
)
317 return (HINTERNET
)NULL
;
320 WideCharToMultiByte(CP_ACP
, -1, lpszAgent
, -1, szAgent
, lenAgent
,
322 WideCharToMultiByte(CP_ACP
, -1, lpszProxy
, -1, szProxy
, lenProxy
,
324 WideCharToMultiByte(CP_ACP
, -1, lpszProxyBypass
, -1, szBypass
, lenBypass
,
327 rc
= InternetOpenA(szAgent
, dwAccessType
, szProxy
, szBypass
, dwFlags
);
329 HeapFree(GetProcessHeap(), 0, szAgent
);
330 HeapFree(GetProcessHeap(), 0, szProxy
);
331 HeapFree(GetProcessHeap(), 0, szBypass
);
336 /***********************************************************************
337 * InternetGetLastResponseInfoA (WININET.@)
339 * Return last wininet error description on the calling thread
342 * TRUE on success of writting to buffer
346 BOOL WINAPI
InternetGetLastResponseInfoA(LPDWORD lpdwError
,
347 LPSTR lpszBuffer
, LPDWORD lpdwBufferLength
)
349 LPWITHREADERROR lpwite
= (LPWITHREADERROR
)TlsGetValue(g_dwTlsErrIndex
);
353 *lpdwError
= lpwite
->dwError
;
356 strncpy(lpszBuffer
, lpwite
->response
, *lpdwBufferLength
);
357 *lpdwBufferLength
= strlen(lpszBuffer
);
360 *lpdwBufferLength
= 0;
366 /***********************************************************************
367 * InternetGetConnectedState (WININET.@)
369 * Return connected state
373 * if lpdwStatus is not null, return the status (off line,
374 * modem, lan...) in it.
375 * FALSE if not connected
377 BOOL WINAPI
InternetGetConnectedState(LPDWORD lpdwStatus
, DWORD dwReserved
)
380 FIXME("always returning LAN connection.\n");
381 *lpdwStatus
= INTERNET_CONNECTION_LAN
;
386 /***********************************************************************
387 * InternetGetConnectedStateEx (WININET.@)
389 * Return connected state
393 * if lpdwStatus is not null, return the status (off line,
394 * modem, lan...) in it.
395 * FALSE if not connected
397 BOOL WINAPI
InternetGetConnectedStateExW(LPDWORD lpdwStatus
, LPWSTR lpszConnectionName
,
398 DWORD dwNameLen
, DWORD dwReserved
)
405 FIXME("always returning LAN connection.\n");
406 *lpdwStatus
= INTERNET_CONNECTION_LAN
;
411 /***********************************************************************
412 * InternetConnectA (WININET.@)
414 * Open a ftp, gopher or http session
417 * HINTERNET a session handle on success
421 HINTERNET WINAPI
InternetConnectA(HINTERNET hInternet
,
422 LPCSTR lpszServerName
, INTERNET_PORT nServerPort
,
423 LPCSTR lpszUserName
, LPCSTR lpszPassword
,
424 DWORD dwService
, DWORD dwFlags
, DWORD dwContext
)
426 HINTERNET rc
= (HINTERNET
) NULL
;
428 TRACE("(%p, %s, %i, %s, %s, %li, %li, %li)\n", hInternet
, debugstr_a(lpszServerName
),
429 nServerPort
, debugstr_a(lpszUserName
), debugstr_a(lpszPassword
),
430 dwService
, dwFlags
, dwContext
);
432 /* Clear any error information */
433 INTERNET_SetLastError(0);
437 case INTERNET_SERVICE_FTP
:
438 rc
= FTP_Connect(hInternet
, lpszServerName
, nServerPort
,
439 lpszUserName
, lpszPassword
, dwFlags
, dwContext
);
442 case INTERNET_SERVICE_HTTP
:
443 rc
= HTTP_Connect(hInternet
, lpszServerName
, nServerPort
,
444 lpszUserName
, lpszPassword
, dwFlags
, dwContext
);
447 case INTERNET_SERVICE_GOPHER
:
452 TRACE("returning %p\n", rc
);
457 /***********************************************************************
458 * InternetConnectW (WININET.@)
460 * Open a ftp, gopher or http session
463 * HINTERNET a session handle on success
467 HINTERNET WINAPI
InternetConnectW(HINTERNET hInternet
,
468 LPCWSTR lpszServerName
, INTERNET_PORT nServerPort
,
469 LPCWSTR lpszUserName
, LPCWSTR lpszPassword
,
470 DWORD dwService
, DWORD dwFlags
, DWORD dwContext
)
472 HINTERNET rc
= (HINTERNET
)NULL
;
476 CHAR
*szServerName
= NULL
;
477 CHAR
*szUserName
= NULL
;
478 CHAR
*szPassword
= NULL
;
482 lenServer
= lstrlenW(lpszServerName
)+1;
483 szServerName
= (CHAR
*)HeapAlloc(GetProcessHeap(), 0, lenServer
*sizeof(CHAR
));
484 WideCharToMultiByte(CP_ACP
, -1, lpszServerName
, -1, szServerName
, lenServer
,
489 lenUser
= lstrlenW(lpszUserName
)+1;
490 szUserName
= (CHAR
*)HeapAlloc(GetProcessHeap(), 0, lenUser
*sizeof(CHAR
));
491 WideCharToMultiByte(CP_ACP
, -1, lpszUserName
, -1, szUserName
, lenUser
,
496 lenPass
= lstrlenW(lpszPassword
)+1;
497 szPassword
= (CHAR
*)HeapAlloc(GetProcessHeap(), 0, lenPass
*sizeof(CHAR
));
498 WideCharToMultiByte(CP_ACP
, -1, lpszPassword
, -1, szPassword
, lenPass
,
503 rc
= InternetConnectA(hInternet
, szServerName
, nServerPort
,
504 szUserName
, szPassword
, dwService
, dwFlags
, dwContext
);
506 if (szServerName
) HeapFree(GetProcessHeap(), 0, szServerName
);
507 if (szUserName
) HeapFree(GetProcessHeap(), 0, szUserName
);
508 if (szPassword
) HeapFree(GetProcessHeap(), 0, szPassword
);
513 /***********************************************************************
514 * InternetFindNextFileA (WININET.@)
516 * Continues a file search from a previous call to FindFirstFile
523 BOOL WINAPI
InternetFindNextFileA(HINTERNET hFind
, LPVOID lpvFindData
)
525 LPWININETAPPINFOA hIC
= NULL
;
526 LPWININETFINDNEXTA lpwh
= (LPWININETFINDNEXTA
) hFind
;
530 if (NULL
== lpwh
|| lpwh
->hdr
.htype
!= WH_HFINDNEXT
)
532 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
536 hIC
= GET_HWININET_FROM_LPWININETFINDNEXT(lpwh
);
537 if (hIC
->hdr
.dwFlags
& INTERNET_FLAG_ASYNC
)
539 WORKREQUEST workRequest
;
541 workRequest
.asyncall
= INTERNETFINDNEXTA
;
542 workRequest
.HFTPSESSION
= (DWORD
)hFind
;
543 workRequest
.LPFINDFILEDATA
= (DWORD
)lpvFindData
;
545 return INTERNET_AsyncCall(&workRequest
);
549 return INTERNET_FindNextFileA(hFind
, lpvFindData
);
553 /***********************************************************************
554 * INTERNET_FindNextFileA (Internal)
556 * Continues a file search from a previous call to FindFirstFile
563 BOOL WINAPI
INTERNET_FindNextFileA(HINTERNET hFind
, LPVOID lpvFindData
)
565 BOOL bSuccess
= TRUE
;
566 LPWININETAPPINFOA hIC
= NULL
;
567 LPWIN32_FIND_DATAA lpFindFileData
;
568 LPWININETFINDNEXTA lpwh
= (LPWININETFINDNEXTA
) hFind
;
572 if (NULL
== lpwh
|| lpwh
->hdr
.htype
!= WH_HFINDNEXT
)
574 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
578 /* Clear any error information */
579 INTERNET_SetLastError(0);
581 if (lpwh
->hdr
.lpwhparent
->htype
!= WH_HFTPSESSION
)
583 FIXME("Only FTP find next supported\n");
584 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
588 TRACE("index(%d) size(%ld)\n", lpwh
->index
, lpwh
->size
);
590 lpFindFileData
= (LPWIN32_FIND_DATAA
) lpvFindData
;
591 ZeroMemory(lpFindFileData
, sizeof(WIN32_FIND_DATAA
));
593 if (lpwh
->index
>= lpwh
->size
)
595 INTERNET_SetLastError(ERROR_NO_MORE_FILES
);
600 FTP_ConvertFileProp(&lpwh
->lpafp
[lpwh
->index
], lpFindFileData
);
603 TRACE("\nName: %s\nSize: %ld\n", lpFindFileData
->cFileName
, lpFindFileData
->nFileSizeLow
);
607 hIC
= GET_HWININET_FROM_LPWININETFINDNEXT(lpwh
);
608 if (hIC
->lpfnStatusCB
)
610 INTERNET_ASYNC_RESULT iar
;
612 iar
.dwResult
= (DWORD
)bSuccess
;
613 iar
.dwError
= iar
.dwError
= bSuccess
? ERROR_SUCCESS
:
614 INTERNET_GetLastError();
616 SendAsyncCallback(hIC
, hFind
, lpwh
->hdr
.dwContext
,
617 INTERNET_STATUS_REQUEST_COMPLETE
, &iar
,
618 sizeof(INTERNET_ASYNC_RESULT
));
625 /***********************************************************************
626 * INTERNET_CloseHandle (internal)
628 * Close internet handle
634 VOID
INTERNET_CloseHandle(LPWININETAPPINFOA lpwai
)
638 SendAsyncCallback(lpwai
, lpwai
, lpwai
->hdr
.dwContext
,
639 INTERNET_STATUS_HANDLE_CLOSING
, lpwai
,
642 if (lpwai
->lpszAgent
)
643 HeapFree(GetProcessHeap(), 0, lpwai
->lpszAgent
);
645 if (lpwai
->lpszProxy
)
646 HeapFree(GetProcessHeap(), 0, lpwai
->lpszProxy
);
648 if (lpwai
->lpszProxyBypass
)
649 HeapFree(GetProcessHeap(), 0, lpwai
->lpszProxyBypass
);
651 HeapFree(GetProcessHeap(), 0, lpwai
);
655 /***********************************************************************
656 * InternetCloseHandle (WININET.@)
658 * Generic close handle function
665 BOOL WINAPI
InternetCloseHandle(HINTERNET hInternet
)
668 LPWININETHANDLEHEADER lpwh
= (LPWININETHANDLEHEADER
) hInternet
;
670 TRACE("%p\n",hInternet
);
675 /* Clear any error information */
676 INTERNET_SetLastError(0);
682 INTERNET_CloseHandle((LPWININETAPPINFOA
) lpwh
);
686 case WH_HHTTPSESSION
:
687 HTTP_CloseHTTPSessionHandle((LPWININETHTTPSESSIONA
) lpwh
);
692 HTTP_CloseHTTPRequestHandle((LPWININETHTTPREQA
) lpwh
);
697 retval
= FTP_CloseSessionHandle((LPWININETFTPSESSIONA
) lpwh
);
701 retval
= FTP_CloseFindNextHandle((LPWININETFINDNEXTA
) lpwh
);
707 } __EXCEPT(page_fault
) {
708 INTERNET_SetLastError(ERROR_INVALID_PARAMETER
);
717 /***********************************************************************
718 * ConvertUrlComponentValue (Internal)
720 * Helper function for InternetCrackUrlW
723 void ConvertUrlComponentValue(LPSTR
* lppszComponent
, LPDWORD dwComponentLen
,
724 LPWSTR lpwszComponent
, DWORD dwwComponentLen
,
728 if (*dwComponentLen
!= 0)
730 int nASCIILength
=WideCharToMultiByte(CP_ACP
,0,lpwszComponent
,dwwComponentLen
,NULL
,0,NULL
,NULL
);
731 if (*lppszComponent
== NULL
)
733 int nASCIIOffset
=WideCharToMultiByte(CP_ACP
,0,lpwszStart
,lpwszComponent
-lpwszStart
,NULL
,0,NULL
,NULL
);
734 *lppszComponent
= (LPSTR
)lpszStart
+nASCIIOffset
;
735 *dwComponentLen
= nASCIILength
;
739 INT ncpylen
= min((*dwComponentLen
)-1, nASCIILength
);
740 WideCharToMultiByte(CP_ACP
,0,lpwszComponent
,dwwComponentLen
,*lppszComponent
,ncpylen
+1,NULL
,NULL
);
741 (*lppszComponent
)[ncpylen
]=0;
742 *dwComponentLen
= ncpylen
;
748 /***********************************************************************
749 * InternetCrackUrlA (WININET.@)
751 * Break up URL into its components
753 * TODO: Handle dwFlags
760 BOOL WINAPI
InternetCrackUrlA(LPCSTR lpszUrl
, DWORD dwUrlLength
, DWORD dwFlags
,
761 LPURL_COMPONENTSA lpUrlComponents
)
767 dwUrlLength
=strlen(lpszUrl
);
768 lpwszUrl
=HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(dwUrlLength
+1));
769 memset(lpwszUrl
,0,sizeof(WCHAR
)*(dwUrlLength
+1));
770 nLength
=MultiByteToWideChar(CP_ACP
,0,lpszUrl
,dwUrlLength
,lpwszUrl
,dwUrlLength
+1);
771 memset(&UCW
,0,sizeof(UCW
));
772 if(lpUrlComponents
->dwHostNameLength
!=0)
773 UCW
.dwHostNameLength
=1;
774 if(lpUrlComponents
->dwUserNameLength
!=0)
775 UCW
.dwUserNameLength
=1;
776 if(lpUrlComponents
->dwPasswordLength
!=0)
777 UCW
.dwPasswordLength
=1;
778 if(lpUrlComponents
->dwUrlPathLength
!=0)
779 UCW
.dwUrlPathLength
=1;
780 if(lpUrlComponents
->dwSchemeLength
!=0)
781 UCW
.dwSchemeLength
=1;
782 if(lpUrlComponents
->dwExtraInfoLength
!=0)
783 UCW
.dwExtraInfoLength
=1;
784 if(!InternetCrackUrlW(lpwszUrl
,nLength
,dwFlags
,&UCW
))
786 HeapFree(GetProcessHeap(), 0, lpwszUrl
);
789 ConvertUrlComponentValue(&lpUrlComponents
->lpszHostName
, &lpUrlComponents
->dwHostNameLength
,
790 UCW
.lpszHostName
, UCW
.dwHostNameLength
,
792 ConvertUrlComponentValue(&lpUrlComponents
->lpszUserName
, &lpUrlComponents
->dwUserNameLength
,
793 UCW
.lpszUserName
, UCW
.dwUserNameLength
,
795 ConvertUrlComponentValue(&lpUrlComponents
->lpszPassword
, &lpUrlComponents
->dwPasswordLength
,
796 UCW
.lpszPassword
, UCW
.dwPasswordLength
,
798 ConvertUrlComponentValue(&lpUrlComponents
->lpszUrlPath
, &lpUrlComponents
->dwUrlPathLength
,
799 UCW
.lpszUrlPath
, UCW
.dwUrlPathLength
,
801 ConvertUrlComponentValue(&lpUrlComponents
->lpszScheme
, &lpUrlComponents
->dwSchemeLength
,
802 UCW
.lpszScheme
, UCW
.dwSchemeLength
,
804 ConvertUrlComponentValue(&lpUrlComponents
->lpszExtraInfo
, &lpUrlComponents
->dwExtraInfoLength
,
805 UCW
.lpszExtraInfo
, UCW
.dwExtraInfoLength
,
807 lpUrlComponents
->nScheme
=UCW
.nScheme
;
808 lpUrlComponents
->nPort
=UCW
.nPort
;
809 HeapFree(GetProcessHeap(), 0, lpwszUrl
);
811 TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", lpszUrl
,
812 debugstr_an(lpUrlComponents
->lpszScheme
,lpUrlComponents
->dwSchemeLength
),
813 debugstr_an(lpUrlComponents
->lpszHostName
,lpUrlComponents
->dwHostNameLength
),
814 debugstr_an(lpUrlComponents
->lpszUrlPath
,lpUrlComponents
->dwUrlPathLength
),
815 debugstr_an(lpUrlComponents
->lpszExtraInfo
,lpUrlComponents
->dwExtraInfoLength
));
820 /***********************************************************************
821 * GetInternetSchemeW (internal)
827 * INTERNET_SCHEME_UNKNOWN on failure
830 INTERNET_SCHEME
GetInternetSchemeW(LPCWSTR lpszScheme
, INT nMaxCmp
)
832 INTERNET_SCHEME iScheme
=INTERNET_SCHEME_UNKNOWN
;
833 WCHAR lpszFtp
[]={'f','t','p',0};
834 WCHAR lpszGopher
[]={'g','o','p','h','e','r',0};
835 WCHAR lpszHttp
[]={'h','t','t','p',0};
836 WCHAR lpszHttps
[]={'h','t','t','p','s',0};
837 WCHAR lpszFile
[]={'f','i','l','e',0};
838 WCHAR lpszNews
[]={'n','e','w','s',0};
839 WCHAR lpszMailto
[]={'m','a','i','l','t','o',0};
840 WCHAR lpszRes
[]={'r','e','s',0};
841 WCHAR
* tempBuffer
=NULL
;
844 return INTERNET_SCHEME_UNKNOWN
;
846 tempBuffer
=malloc(nMaxCmp
+1);
847 strncpyW(tempBuffer
,lpszScheme
,nMaxCmp
);
848 tempBuffer
[nMaxCmp
]=0;
850 if (nMaxCmp
==strlenW(lpszFtp
) && !strncmpW(lpszFtp
, tempBuffer
, nMaxCmp
))
851 iScheme
=INTERNET_SCHEME_FTP
;
852 else if (nMaxCmp
==strlenW(lpszGopher
) && !strncmpW(lpszGopher
, tempBuffer
, nMaxCmp
))
853 iScheme
=INTERNET_SCHEME_GOPHER
;
854 else if (nMaxCmp
==strlenW(lpszHttp
) && !strncmpW(lpszHttp
, tempBuffer
, nMaxCmp
))
855 iScheme
=INTERNET_SCHEME_HTTP
;
856 else if (nMaxCmp
==strlenW(lpszHttps
) && !strncmpW(lpszHttps
, tempBuffer
, nMaxCmp
))
857 iScheme
=INTERNET_SCHEME_HTTPS
;
858 else if (nMaxCmp
==strlenW(lpszFile
) && !strncmpW(lpszFile
, tempBuffer
, nMaxCmp
))
859 iScheme
=INTERNET_SCHEME_FILE
;
860 else if (nMaxCmp
==strlenW(lpszNews
) && !strncmpW(lpszNews
, tempBuffer
, nMaxCmp
))
861 iScheme
=INTERNET_SCHEME_NEWS
;
862 else if (nMaxCmp
==strlenW(lpszMailto
) && !strncmpW(lpszMailto
, tempBuffer
, nMaxCmp
))
863 iScheme
=INTERNET_SCHEME_MAILTO
;
864 else if (nMaxCmp
==strlenW(lpszRes
) && !strncmpW(lpszRes
, tempBuffer
, nMaxCmp
))
865 iScheme
=INTERNET_SCHEME_RES
;
870 /***********************************************************************
871 * SetUrlComponentValueW (Internal)
873 * Helper function for InternetCrackUrlW
880 BOOL
SetUrlComponentValueW(LPWSTR
* lppszComponent
, LPDWORD dwComponentLen
, LPCWSTR lpszStart
, INT len
)
882 TRACE("%s (%d)\n", debugstr_wn(lpszStart
,len
), len
);
884 if (*dwComponentLen
!= 0 || *lppszComponent
== NULL
)
886 if (*lppszComponent
== NULL
)
888 *lppszComponent
= (LPWSTR
)lpszStart
;
889 *dwComponentLen
= len
;
893 INT ncpylen
= min((*dwComponentLen
)-1, len
);
894 strncpyW(*lppszComponent
, lpszStart
, ncpylen
);
895 (*lppszComponent
)[ncpylen
] = '\0';
896 *dwComponentLen
= ncpylen
;
903 /***********************************************************************
904 * InternetCrackUrlW (WININET.@)
906 BOOL WINAPI
InternetCrackUrlW(LPCWSTR lpszUrl
, DWORD dwUrlLength
, DWORD dwFlags
,
907 LPURL_COMPONENTSW lpUC
)
911 * <protocol>:[//<net_loc>][/path][;<params>][?<query>][#<fragment>]
914 LPWSTR lpszParam
= NULL
;
915 BOOL bIsAbsolute
= FALSE
;
916 LPWSTR lpszap
= (WCHAR
*)lpszUrl
;
917 LPWSTR lpszcp
= NULL
;
918 WCHAR lpszSeparators
[3]={';','?',0};
919 WCHAR lpszSlash
[2]={'/',0};
921 dwUrlLength
=strlenW(lpszUrl
);
925 /* Determine if the URI is absolute. */
926 while (*lpszap
!= '\0')
928 if (isalnumW(*lpszap
))
933 if ((*lpszap
== ':') && (lpszap
- lpszUrl
>= 2))
940 lpszcp
= (LPWSTR
)lpszUrl
; /* Relative url */
947 lpszParam
= strpbrkW(lpszap
, lpszSeparators
);
948 if (lpszParam
!= NULL
)
950 if (!SetUrlComponentValueW(&lpUC
->lpszExtraInfo
, &lpUC
->dwExtraInfoLength
,
951 lpszParam
, dwUrlLength
-(lpszParam
-lpszUrl
)))
957 if (bIsAbsolute
) /* Parse <protocol>:[//<net_loc>] */
960 WCHAR wszAbout
[]={'a','b','o','u','t',':',0};
962 /* Get scheme first. */
963 lpUC
->nScheme
= GetInternetSchemeW(lpszUrl
, lpszcp
- lpszUrl
);
964 if (!SetUrlComponentValueW(&lpUC
->lpszScheme
, &lpUC
->dwSchemeLength
,
965 lpszUrl
, lpszcp
- lpszUrl
))
968 /* Eat ':' in protocol. */
971 /* if the scheme is "about", there is no host */
972 if(strncmpW(wszAbout
,lpszUrl
, lpszcp
- lpszUrl
)==0)
974 SetUrlComponentValueW(&lpUC
->lpszUserName
, &lpUC
->dwUserNameLength
, NULL
, 0);
975 SetUrlComponentValueW(&lpUC
->lpszPassword
, &lpUC
->dwPasswordLength
, NULL
, 0);
976 SetUrlComponentValueW(&lpUC
->lpszHostName
, &lpUC
->dwHostNameLength
, NULL
, 0);
981 /* Skip over slashes. */
993 lpszNetLoc
= strpbrkW(lpszcp
, lpszSlash
);
997 lpszNetLoc
= min(lpszNetLoc
, lpszParam
);
999 lpszNetLoc
= lpszParam
;
1001 else if (!lpszNetLoc
)
1002 lpszNetLoc
= lpszcp
+ dwUrlLength
-(lpszcp
-lpszUrl
);
1010 /* [<user>[<:password>]@]<host>[:<port>] */
1011 /* First find the user and password if they exist */
1013 lpszHost
= strchrW(lpszcp
, '@');
1014 if (lpszHost
== NULL
|| lpszHost
> lpszNetLoc
)
1016 /* username and password not specified. */
1017 SetUrlComponentValueW(&lpUC
->lpszUserName
, &lpUC
->dwUserNameLength
, NULL
, 0);
1018 SetUrlComponentValueW(&lpUC
->lpszPassword
, &lpUC
->dwPasswordLength
, NULL
, 0);
1020 else /* Parse out username and password */
1022 LPWSTR lpszUser
= lpszcp
;
1023 LPWSTR lpszPasswd
= lpszHost
;
1025 while (lpszcp
< lpszHost
)
1028 lpszPasswd
= lpszcp
;
1033 SetUrlComponentValueW(&lpUC
->lpszUserName
, &lpUC
->dwUserNameLength
,
1034 lpszUser
, lpszPasswd
- lpszUser
);
1036 if (lpszPasswd
!= lpszHost
)
1038 SetUrlComponentValueW(&lpUC
->lpszPassword
, &lpUC
->dwPasswordLength
,
1039 lpszPasswd
== lpszHost
? NULL
: lpszPasswd
,
1040 lpszHost
- lpszPasswd
);
1042 lpszcp
++; /* Advance to beginning of host */
1045 /* Parse <host><:port> */
1048 lpszPort
= lpszNetLoc
;
1050 /* special case for res:// URLs: there is no port here, so the host is the
1051 entire string up to the first '/' */
1052 if(lpUC
->nScheme
==INTERNET_SCHEME_RES
)
1054 SetUrlComponentValueW(&lpUC
->lpszHostName
, &lpUC
->dwHostNameLength
,
1055 lpszHost
, lpszPort
- lpszHost
);
1061 while (lpszcp
< lpszNetLoc
)
1069 /* If the scheme is "file" and the host is just one letter, it's not a host */
1070 if(lpUC
->nScheme
==INTERNET_SCHEME_FILE
&& (lpszPort
-lpszHost
)==1)
1073 SetUrlComponentValueW(&lpUC
->lpszHostName
, &lpUC
->dwHostNameLength
,
1079 SetUrlComponentValueW(&lpUC
->lpszHostName
, &lpUC
->dwHostNameLength
,
1080 lpszHost
, lpszPort
- lpszHost
);
1081 if (lpszPort
!= lpszNetLoc
)
1082 lpUC
->nPort
= atoiW(++lpszPort
);
1091 /* Here lpszcp points to:
1093 * <protocol>:[//<net_loc>][/path][;<params>][?<query>][#<fragment>]
1094 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1096 if (lpszcp
!= 0 && *lpszcp
!= '\0' && (!lpszParam
|| lpszcp
< lpszParam
))
1100 /* Only truncate the parameter list if it's already been saved
1101 * in lpUC->lpszExtraInfo.
1103 if (lpszParam
&& lpUC
->dwExtraInfoLength
)
1104 len
= lpszParam
- lpszcp
;
1107 /* Leave the parameter list in lpszUrlPath. Strip off any trailing
1108 * newlines if necessary.
1110 LPWSTR lpsznewline
= strchrW(lpszcp
, '\n');
1111 if (lpsznewline
!= NULL
)
1112 len
= lpsznewline
- lpszcp
;
1114 len
= dwUrlLength
-(lpszcp
-lpszUrl
);
1117 if (!SetUrlComponentValueW(&lpUC
->lpszUrlPath
, &lpUC
->dwUrlPathLength
,
1123 lpUC
->dwUrlPathLength
= 0;
1126 TRACE("%s: host(%s) path(%s) extra(%s)\n", debugstr_wn(lpszUrl
,dwUrlLength
),
1127 debugstr_wn(lpUC
->lpszHostName
,lpUC
->dwHostNameLength
),
1128 debugstr_wn(lpUC
->lpszUrlPath
,lpUC
->dwUrlPathLength
),
1129 debugstr_wn(lpUC
->lpszExtraInfo
,lpUC
->dwExtraInfoLength
));
1134 /***********************************************************************
1135 * InternetAttemptConnect (WININET.@)
1137 * Attempt to make a connection to the internet
1140 * ERROR_SUCCESS on success
1141 * Error value on failure
1144 DWORD WINAPI
InternetAttemptConnect(DWORD dwReserved
)
1147 return ERROR_SUCCESS
;
1151 /***********************************************************************
1152 * InternetCanonicalizeUrlA (WININET.@)
1154 * Escape unsafe characters and spaces
1161 BOOL WINAPI
InternetCanonicalizeUrlA(LPCSTR lpszUrl
, LPSTR lpszBuffer
,
1162 LPDWORD lpdwBufferLength
, DWORD dwFlags
)
1165 TRACE("%s %p %p %08lx\n",debugstr_a(lpszUrl
), lpszBuffer
,
1166 lpdwBufferLength
, dwFlags
);
1168 /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
1169 dwFlags
^= ICU_NO_ENCODE
;
1171 dwFlags
|= 0x80000000; /* Don't know what this means */
1173 hr
= UrlCanonicalizeA(lpszUrl
, lpszBuffer
, lpdwBufferLength
, dwFlags
);
1175 return (hr
== S_OK
) ? TRUE
: FALSE
;
1178 /***********************************************************************
1179 * InternetCanonicalizeUrlW (WININET.@)
1181 * Escape unsafe characters and spaces
1188 BOOL WINAPI
InternetCanonicalizeUrlW(LPCWSTR lpszUrl
, LPWSTR lpszBuffer
,
1189 LPDWORD lpdwBufferLength
, DWORD dwFlags
)
1192 TRACE("%s %p %p %08lx\n", debugstr_w(lpszUrl
), lpszBuffer
,
1193 lpdwBufferLength
, dwFlags
);
1195 /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
1196 dwFlags
^= ICU_NO_ENCODE
;
1198 dwFlags
|= 0x80000000; /* Don't know what this means */
1200 hr
= UrlCanonicalizeW(lpszUrl
, lpszBuffer
, lpdwBufferLength
, dwFlags
);
1202 return (hr
== S_OK
) ? TRUE
: FALSE
;
1206 /***********************************************************************
1207 * InternetSetStatusCallbackA (WININET.@)
1209 * Sets up a callback function which is called as progress is made
1210 * during an operation.
1213 * Previous callback or NULL on success
1214 * INTERNET_INVALID_STATUS_CALLBACK on failure
1217 INTERNET_STATUS_CALLBACK WINAPI
InternetSetStatusCallbackA(
1218 HINTERNET hInternet
,INTERNET_STATUS_CALLBACK lpfnIntCB
)
1220 INTERNET_STATUS_CALLBACK retVal
;
1221 LPWININETAPPINFOA lpwai
= (LPWININETAPPINFOA
)hInternet
;
1223 TRACE("0x%08lx\n", (ULONG
)hInternet
);
1224 if (lpwai
->hdr
.htype
!= WH_HINIT
)
1225 return INTERNET_INVALID_STATUS_CALLBACK
;
1227 retVal
= lpwai
->lpfnStatusCB
;
1228 lpwai
->lpfnStatusCB
= lpfnIntCB
;
1234 /***********************************************************************
1235 * InternetWriteFile (WININET.@)
1237 * Write data to an open internet file
1244 BOOL WINAPI
InternetWriteFile(HINTERNET hFile
, LPCVOID lpBuffer
,
1245 DWORD dwNumOfBytesToWrite
, LPDWORD lpdwNumOfBytesWritten
)
1247 BOOL retval
= FALSE
;
1249 LPWININETHANDLEHEADER lpwh
= (LPWININETHANDLEHEADER
) hFile
;
1255 switch (lpwh
->htype
)
1258 FIXME("This shouldn't be here! We don't support this kind"
1259 " of connection anymore. Must use NETCON functions,"
1260 " especially if using SSL\n");
1261 nSocket
= ((LPWININETHTTPREQA
)hFile
)->netConnection
.socketFD
;
1265 nSocket
= ((LPWININETFILE
)hFile
)->nDataSocket
;
1274 int res
= send(nSocket
, lpBuffer
, dwNumOfBytesToWrite
, 0);
1275 retval
= (res
>= 0);
1276 *lpdwNumOfBytesWritten
= retval
? res
: 0;
1283 /***********************************************************************
1284 * InternetReadFile (WININET.@)
1286 * Read data from an open internet file
1293 BOOL WINAPI
InternetReadFile(HINTERNET hFile
, LPVOID lpBuffer
,
1294 DWORD dwNumOfBytesToRead
, LPDWORD dwNumOfBytesRead
)
1296 BOOL retval
= FALSE
;
1298 LPWININETHANDLEHEADER lpwh
= (LPWININETHANDLEHEADER
) hFile
;
1305 /* FIXME: this should use NETCON functions! */
1306 switch (lpwh
->htype
)
1309 if (!NETCON_recv(&((LPWININETHTTPREQA
)hFile
)->netConnection
, lpBuffer
,
1310 dwNumOfBytesToRead
, 0, (int *)dwNumOfBytesRead
))
1312 *dwNumOfBytesRead
= 0;
1313 retval
= TRUE
; /* Under windows, it seems to return 0 even if nothing was read... */
1320 /* FIXME: FTP should use NETCON_ stuff */
1321 nSocket
= ((LPWININETFILE
)hFile
)->nDataSocket
;
1324 int res
= recv(nSocket
, lpBuffer
, dwNumOfBytesToRead
, 0);
1325 retval
= (res
>= 0);
1326 *dwNumOfBytesRead
= retval
? res
: 0;
1336 int res
= recv(nSocket
, lpBuffer
, dwNumOfBytesToRead
, 0);
1337 retval
= (res
>= 0);
1338 *dwNumOfBytesRead
= retval
? res
: 0;
1343 /***********************************************************************
1344 * InternetReadFileExA (WININET.@)
1346 * Read data from an open internet file
1353 BOOL WINAPI
InternetReadFileExA(HINTERNET hFile
, LPINTERNET_BUFFERSA lpBuffer
,
1354 DWORD dwFlags
, DWORD dwContext
)
1360 /***********************************************************************
1361 * InternetReadFileExW (WININET.@)
1363 * Read data from an open internet file
1370 BOOL WINAPI
InternetReadFileExW(HINTERNET hFile
, LPINTERNET_BUFFERSW lpBuffer
,
1371 DWORD dwFlags
, DWORD dwContext
)
1375 INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1379 /***********************************************************************
1380 * INET_QueryOptionHelper (internal)
1382 static BOOL
INET_QueryOptionHelper(BOOL bIsUnicode
, HINTERNET hInternet
, DWORD dwOption
,
1383 LPVOID lpBuffer
, LPDWORD lpdwBufferLength
)
1385 LPWININETHANDLEHEADER lpwhh
;
1386 BOOL bSuccess
= FALSE
;
1388 TRACE("(%p, 0x%08lx, %p, %p)\n", hInternet
, dwOption
, lpBuffer
, lpdwBufferLength
);
1390 if (NULL
== hInternet
)
1392 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
1396 lpwhh
= (LPWININETHANDLEHEADER
) hInternet
;
1400 case INTERNET_OPTION_HANDLE_TYPE
:
1402 ULONG type
= lpwhh
->htype
;
1403 TRACE("INTERNET_OPTION_HANDLE_TYPE: %ld\n", type
);
1405 if (*lpdwBufferLength
< sizeof(ULONG
))
1406 INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1409 memcpy(lpBuffer
, &type
, sizeof(ULONG
));
1410 *lpdwBufferLength
= sizeof(ULONG
);
1416 case INTERNET_OPTION_REQUEST_FLAGS
:
1419 TRACE("INTERNET_OPTION_REQUEST_FLAGS: %ld\n", flags
);
1420 if (*lpdwBufferLength
< sizeof(ULONG
))
1421 INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1424 memcpy(lpBuffer
, &flags
, sizeof(ULONG
));
1425 *lpdwBufferLength
= sizeof(ULONG
);
1431 case INTERNET_OPTION_URL
:
1432 case INTERNET_OPTION_DATAFILE_NAME
:
1434 ULONG type
= lpwhh
->htype
;
1435 if (type
== WH_HHTTPREQ
)
1437 LPWININETHTTPREQA lpreq
= hInternet
;
1440 sprintf(url
,"http://%s%s",lpreq
->lpszHostName
,lpreq
->lpszPath
);
1441 TRACE("INTERNET_OPTION_URL: %s\n",url
);
1442 if (*lpdwBufferLength
< strlen(url
)+1)
1443 INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1448 *lpdwBufferLength
=MultiByteToWideChar(CP_ACP
,0,url
,-1,lpBuffer
,*lpdwBufferLength
);
1452 memcpy(lpBuffer
, url
, strlen(url
)+1);
1453 *lpdwBufferLength
= strlen(url
)+1;
1460 case INTERNET_OPTION_HTTP_VERSION
:
1463 * Presently hardcoded to 1.1
1465 ((HTTP_VERSION_INFO
*)lpBuffer
)->dwMajorVersion
= 1;
1466 ((HTTP_VERSION_INFO
*)lpBuffer
)->dwMinorVersion
= 1;
1472 FIXME("Stub! %ld \n",dwOption
);
1479 /***********************************************************************
1480 * InternetQueryOptionW (WININET.@)
1482 * Queries an options on the specified handle
1489 BOOL WINAPI
InternetQueryOptionW(HINTERNET hInternet
, DWORD dwOption
,
1490 LPVOID lpBuffer
, LPDWORD lpdwBufferLength
)
1492 return INET_QueryOptionHelper(TRUE
, hInternet
, dwOption
, lpBuffer
, lpdwBufferLength
);
1495 /***********************************************************************
1496 * InternetQueryOptionA (WININET.@)
1498 * Queries an options on the specified handle
1505 BOOL WINAPI
InternetQueryOptionA(HINTERNET hInternet
, DWORD dwOption
,
1506 LPVOID lpBuffer
, LPDWORD lpdwBufferLength
)
1508 return INET_QueryOptionHelper(FALSE
, hInternet
, dwOption
, lpBuffer
, lpdwBufferLength
);
1512 /***********************************************************************
1513 * InternetSetOptionW (WININET.@)
1515 * Sets an options on the specified handle
1522 BOOL WINAPI
InternetSetOptionW(HINTERNET hInternet
, DWORD dwOption
,
1523 LPVOID lpBuffer
, DWORD dwBufferLength
)
1525 LPWININETHANDLEHEADER lpwhh
;
1527 TRACE("0x%08lx\n", dwOption
);
1529 if (NULL
== hInternet
)
1531 INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE
);
1535 lpwhh
= (LPWININETHANDLEHEADER
) hInternet
;
1539 case INTERNET_OPTION_HTTP_VERSION
:
1541 HTTP_VERSION_INFO
* pVersion
=(HTTP_VERSION_INFO
*)lpBuffer
;
1542 FIXME("Option INTERNET_OPTION_HTTP_VERSION(%ld,%ld): STUB\n",pVersion
->dwMajorVersion
,pVersion
->dwMinorVersion
);
1545 case INTERNET_OPTION_ERROR_MASK
:
1547 unsigned long flags
=*(unsigned long*)lpBuffer
;
1548 FIXME("Option INTERNET_OPTION_ERROR_MASK(%ld): STUB\n",flags
);
1551 case INTERNET_OPTION_CODEPAGE
:
1553 unsigned long codepage
=*(unsigned long*)lpBuffer
;
1554 FIXME("Option INTERNET_OPTION_CODEPAGE (%ld): STUB\n",codepage
);
1557 case INTERNET_OPTION_REQUEST_PRIORITY
:
1559 unsigned long priority
=*(unsigned long*)lpBuffer
;
1560 FIXME("Option INTERNET_OPTION_REQUEST_PRIORITY (%ld): STUB\n",priority
);
1564 FIXME("Option %ld STUB\n",dwOption
);
1565 INTERNET_SetLastError(ERROR_INVALID_PARAMETER
);
1573 /***********************************************************************
1574 * InternetSetOptionA (WININET.@)
1576 * Sets an options on the specified handle.
1583 BOOL WINAPI
InternetSetOptionA(HINTERNET hInternet
, DWORD dwOption
,
1584 LPVOID lpBuffer
, DWORD dwBufferLength
)
1592 case INTERNET_OPTION_PROXY
:
1594 LPINTERNET_PROXY_INFOA pi
= (LPINTERNET_PROXY_INFOA
) lpBuffer
;
1595 LPINTERNET_PROXY_INFOW piw
;
1596 DWORD proxlen
, prbylen
;
1599 proxlen
= MultiByteToWideChar( CP_ACP
, 0, pi
->lpszProxy
, -1, NULL
, 0);
1600 prbylen
= MultiByteToWideChar( CP_ACP
, 0, pi
->lpszProxyBypass
, -1, NULL
, 0);
1601 wlen
= sizeof(*piw
) + proxlen
+ prbylen
;
1602 wbuffer
= HeapAlloc( GetProcessHeap(), 0, wlen
);
1603 piw
= (LPINTERNET_PROXY_INFOW
) wbuffer
;
1604 piw
->dwAccessType
= pi
->dwAccessType
;
1605 prox
= (LPWSTR
) &piw
[1];
1606 prby
= &prox
[proxlen
+1];
1607 MultiByteToWideChar( CP_ACP
, 0, pi
->lpszProxy
, -1, prox
, proxlen
);
1608 MultiByteToWideChar( CP_ACP
, 0, pi
->lpszProxyBypass
, -1, prby
, prbylen
);
1609 piw
->lpszProxy
= prox
;
1610 piw
->lpszProxyBypass
= prby
;
1613 case INTERNET_OPTION_USER_AGENT
:
1614 case INTERNET_OPTION_USERNAME
:
1615 case INTERNET_OPTION_PASSWORD
:
1616 wlen
= MultiByteToWideChar( CP_ACP
, 0, lpBuffer
, dwBufferLength
,
1618 wbuffer
= HeapAlloc( GetProcessHeap(), 0, wlen
);
1619 MultiByteToWideChar( CP_ACP
, 0, lpBuffer
, dwBufferLength
,
1624 wlen
= dwBufferLength
;
1627 r
= InternetSetOptionW(hInternet
,dwOption
, wbuffer
, wlen
);
1629 if( lpBuffer
!= wbuffer
)
1630 HeapFree( GetProcessHeap(), 0, wbuffer
);
1636 /***********************************************************************
1637 * InternetSetOptionExA (WININET.@)
1639 BOOL WINAPI
InternetSetOptionExA(HINTERNET hInternet
, DWORD dwOption
,
1640 LPVOID lpBuffer
, DWORD dwBufferLength
, DWORD dwFlags
)
1642 FIXME("Flags %08lx ignored\n", dwFlags
);
1643 return InternetSetOptionA( hInternet
, dwOption
, lpBuffer
, dwBufferLength
);
1646 /***********************************************************************
1647 * InternetSetOptionExW (WININET.@)
1649 BOOL WINAPI
InternetSetOptionExW(HINTERNET hInternet
, DWORD dwOption
,
1650 LPVOID lpBuffer
, DWORD dwBufferLength
, DWORD dwFlags
)
1652 FIXME("Flags %08lx ignored\n", dwFlags
);
1653 if( dwFlags
& ~ISO_VALID_FLAGS
)
1655 SetLastError( ERROR_INVALID_PARAMETER
);
1658 return InternetSetOptionW( hInternet
, dwOption
, lpBuffer
, dwBufferLength
);
1662 /***********************************************************************
1663 * InternetCheckConnectionA (WININET.@)
1665 * Pings a requested host to check internet connection
1668 * TRUE on success and FALSE on failure. If a failure then
1669 * ERROR_NOT_CONNECTED is placesd into GetLastError
1672 BOOL WINAPI
InternetCheckConnectionA( LPCSTR lpszUrl
, DWORD dwFlags
, DWORD dwReserved
)
1675 * this is a kludge which runs the resident ping program and reads the output.
1677 * Anyone have a better idea?
1688 * Crack or set the Address
1690 if (lpszUrl
== NULL
)
1693 * According to the doc we are supost to use the ip for the next
1694 * server in the WnInet internal server database. I have
1695 * no idea what that is or how to get it.
1697 * So someone needs to implement this.
1699 FIXME("Unimplemented with URL of NULL\n");
1704 URL_COMPONENTSA componets
;
1706 ZeroMemory(&componets
,sizeof(URL_COMPONENTSA
));
1707 componets
.lpszHostName
= (LPSTR
)&host
;
1708 componets
.dwHostNameLength
= 1024;
1710 if (!InternetCrackUrlA(lpszUrl
,0,0,&componets
))
1713 TRACE("host name : %s\n",componets
.lpszHostName
);
1717 * Build our ping command
1719 strcpy(command
,"ping -w 1 ");
1720 strcat(command
,host
);
1721 strcat(command
," >/dev/null 2>/dev/null");
1723 TRACE("Ping command is : %s\n",command
);
1725 status
= system(command
);
1727 TRACE("Ping returned a code of %i \n",status
);
1729 /* Ping return code of 0 indicates success */
1736 SetLastError(ERROR_NOT_CONNECTED
);
1742 /***********************************************************************
1743 * InternetCheckConnectionW (WININET.@)
1745 * Pings a requested host to check internet connection
1748 * TRUE on success and FALSE on failure. If a failure then
1749 * ERROR_NOT_CONNECTED is placed into GetLastError
1752 BOOL WINAPI
InternetCheckConnectionW(LPCWSTR lpszUrl
, DWORD dwFlags
, DWORD dwReserved
)
1758 len
= lstrlenW(lpszUrl
)+1;
1759 if (!(szUrl
= (CHAR
*)HeapAlloc(GetProcessHeap(), 0, len
*sizeof(CHAR
))))
1761 WideCharToMultiByte(CP_ACP
, -1, lpszUrl
, -1, szUrl
, len
, NULL
, NULL
);
1762 rc
= InternetCheckConnectionA((LPCSTR
)szUrl
, dwFlags
, dwReserved
);
1763 HeapFree(GetProcessHeap(), 0, szUrl
);
1769 /**********************************************************
1770 * InternetOpenUrlA (WININET.@)
1775 * handle of connection or NULL on failure
1777 HINTERNET WINAPI
InternetOpenUrlA(HINTERNET hInternet
, LPCSTR lpszUrl
,
1778 LPCSTR lpszHeaders
, DWORD dwHeadersLength
, DWORD dwFlags
, DWORD dwContext
)
1780 URL_COMPONENTSA urlComponents
;
1781 char protocol
[32], hostName
[MAXHOSTNAME
], userName
[1024];
1782 char password
[1024], path
[2048], extra
[1024];
1783 HINTERNET client
= NULL
, client1
= NULL
;
1785 TRACE("(%p, %s, %s, %08lx, %08lx, %08lx\n", hInternet
, debugstr_a(lpszUrl
), debugstr_a(lpszHeaders
),
1786 dwHeadersLength
, dwFlags
, dwContext
);
1788 urlComponents
.dwStructSize
= sizeof(URL_COMPONENTSA
);
1789 urlComponents
.lpszScheme
= protocol
;
1790 urlComponents
.dwSchemeLength
= 32;
1791 urlComponents
.lpszHostName
= hostName
;
1792 urlComponents
.dwHostNameLength
= MAXHOSTNAME
;
1793 urlComponents
.lpszUserName
= userName
;
1794 urlComponents
.dwUserNameLength
= 1024;
1795 urlComponents
.lpszPassword
= password
;
1796 urlComponents
.dwPasswordLength
= 1024;
1797 urlComponents
.lpszUrlPath
= path
;
1798 urlComponents
.dwUrlPathLength
= 2048;
1799 urlComponents
.lpszExtraInfo
= extra
;
1800 urlComponents
.dwExtraInfoLength
= 1024;
1801 if(!InternetCrackUrlA(lpszUrl
, strlen(lpszUrl
), 0, &urlComponents
))
1803 switch(urlComponents
.nScheme
) {
1804 case INTERNET_SCHEME_FTP
:
1805 if(urlComponents
.nPort
== 0)
1806 urlComponents
.nPort
= INTERNET_DEFAULT_FTP_PORT
;
1807 client
= InternetConnectA(hInternet
, hostName
, urlComponents
.nPort
,
1808 userName
, password
, INTERNET_SERVICE_FTP
, dwFlags
, dwContext
);
1809 return FtpOpenFileA(client
, path
, GENERIC_READ
, dwFlags
, dwContext
);
1810 case INTERNET_SCHEME_HTTP
:
1811 case INTERNET_SCHEME_HTTPS
:
1813 LPCSTR accept
[2] = { "*/*", NULL
};
1814 char *hostreq
=(char*)malloc(strlen(hostName
)+9);
1815 sprintf(hostreq
, "Host: %s\r\n", hostName
);
1816 if(urlComponents
.nPort
== 0) {
1817 if(urlComponents
.nScheme
== INTERNET_SCHEME_HTTP
)
1818 urlComponents
.nPort
= INTERNET_DEFAULT_HTTP_PORT
;
1820 urlComponents
.nPort
= INTERNET_DEFAULT_HTTPS_PORT
;
1822 client
= InternetConnectA(hInternet
, hostName
, urlComponents
.nPort
, userName
,
1823 password
, INTERNET_SERVICE_HTTP
, dwFlags
, dwContext
);
1826 client1
= HttpOpenRequestA(client
, NULL
, path
, NULL
, NULL
, accept
, dwFlags
, dwContext
);
1827 if(client1
== NULL
) {
1828 InternetCloseHandle(client
);
1831 HttpAddRequestHeadersA(client1
, lpszHeaders
, dwHeadersLength
, HTTP_ADDREQ_FLAG_ADD
);
1832 if(!HttpSendRequestA(client1
, NULL
, 0, NULL
, 0)) {
1833 InternetCloseHandle(client1
);
1834 InternetCloseHandle(client
);
1839 case INTERNET_SCHEME_GOPHER
:
1840 /* gopher doesn't seem to be implemented in wine, but it's supposed
1841 * to be supported by InternetOpenUrlA. */
1848 /**********************************************************
1849 * InternetOpenUrlW (WININET.@)
1854 * handle of connection or NULL on failure
1856 HINTERNET WINAPI
InternetOpenUrlW(HINTERNET hInternet
, LPCWSTR lpszUrl
,
1857 LPCWSTR lpszHeaders
, DWORD dwHeadersLength
, DWORD dwFlags
, DWORD dwContext
)
1859 HINTERNET rc
= (HINTERNET
)NULL
;
1861 INT lenUrl
= lstrlenW(lpszUrl
)+1;
1862 INT lenHeaders
= lstrlenW(lpszHeaders
)+1;
1863 CHAR
*szUrl
= (CHAR
*)HeapAlloc(GetProcessHeap(), 0, lenUrl
*sizeof(CHAR
));
1864 CHAR
*szHeaders
= (CHAR
*)HeapAlloc(GetProcessHeap(), 0, lenHeaders
*sizeof(CHAR
));
1866 if (!szUrl
|| !szHeaders
)
1869 HeapFree(GetProcessHeap(), 0, szUrl
);
1871 HeapFree(GetProcessHeap(), 0, szHeaders
);
1872 return (HINTERNET
)NULL
;
1875 WideCharToMultiByte(CP_ACP
, -1, lpszUrl
, -1, szUrl
, lenUrl
,
1877 WideCharToMultiByte(CP_ACP
, -1, lpszHeaders
, -1, szHeaders
, lenHeaders
,
1880 rc
= InternetOpenUrlA(hInternet
, szUrl
, szHeaders
,
1881 dwHeadersLength
, dwFlags
, dwContext
);
1883 HeapFree(GetProcessHeap(), 0, szUrl
);
1884 HeapFree(GetProcessHeap(), 0, szHeaders
);
1890 /***********************************************************************
1891 * INTERNET_SetLastError (internal)
1893 * Set last thread specific error
1898 void INTERNET_SetLastError(DWORD dwError
)
1900 LPWITHREADERROR lpwite
= (LPWITHREADERROR
)TlsGetValue(g_dwTlsErrIndex
);
1902 SetLastError(dwError
);
1904 lpwite
->dwError
= dwError
;
1908 /***********************************************************************
1909 * INTERNET_GetLastError (internal)
1911 * Get last thread specific error
1916 DWORD
INTERNET_GetLastError()
1918 LPWITHREADERROR lpwite
= (LPWITHREADERROR
)TlsGetValue(g_dwTlsErrIndex
);
1919 return lpwite
->dwError
;
1923 /***********************************************************************
1924 * INTERNET_WorkerThreadFunc (internal)
1926 * Worker thread execution function
1931 DWORD
INTERNET_WorkerThreadFunc(LPVOID
*lpvParam
)
1938 INTERNET_ExecuteWork();
1941 dwWaitRes
= WaitForMultipleObjects(2, hEventArray
, FALSE
, MAX_IDLE_WORKER
);
1943 if (dwWaitRes
== WAIT_OBJECT_0
+ 1)
1944 INTERNET_ExecuteWork();
1948 InterlockedIncrement(&dwNumIdleThreads
);
1951 InterlockedDecrement(&dwNumIdleThreads
);
1952 InterlockedDecrement(&dwNumThreads
);
1953 TRACE("Worker thread exiting\n");
1958 /***********************************************************************
1959 * INTERNET_InsertWorkRequest (internal)
1961 * Insert work request into queue
1966 BOOL
INTERNET_InsertWorkRequest(LPWORKREQUEST lpWorkRequest
)
1968 BOOL bSuccess
= FALSE
;
1969 LPWORKREQUEST lpNewRequest
;
1973 lpNewRequest
= HeapAlloc(GetProcessHeap(), 0, sizeof(WORKREQUEST
));
1976 memcpy(lpNewRequest
, lpWorkRequest
, sizeof(WORKREQUEST
));
1977 lpNewRequest
->prev
= NULL
;
1979 EnterCriticalSection(&csQueue
);
1981 lpNewRequest
->next
= lpWorkQueueTail
;
1982 if (lpWorkQueueTail
)
1983 lpWorkQueueTail
->prev
= lpNewRequest
;
1984 lpWorkQueueTail
= lpNewRequest
;
1985 if (!lpHeadWorkQueue
)
1986 lpHeadWorkQueue
= lpWorkQueueTail
;
1988 LeaveCriticalSection(&csQueue
);
1991 InterlockedIncrement(&dwNumJobs
);
1998 /***********************************************************************
1999 * INTERNET_GetWorkRequest (internal)
2001 * Retrieves work request from queue
2006 BOOL
INTERNET_GetWorkRequest(LPWORKREQUEST lpWorkRequest
)
2008 BOOL bSuccess
= FALSE
;
2009 LPWORKREQUEST lpRequest
= NULL
;
2013 EnterCriticalSection(&csQueue
);
2015 if (lpHeadWorkQueue
)
2017 lpRequest
= lpHeadWorkQueue
;
2018 lpHeadWorkQueue
= lpHeadWorkQueue
->prev
;
2019 if (lpRequest
== lpWorkQueueTail
)
2020 lpWorkQueueTail
= lpHeadWorkQueue
;
2023 LeaveCriticalSection(&csQueue
);
2027 memcpy(lpWorkRequest
, lpRequest
, sizeof(WORKREQUEST
));
2028 HeapFree(GetProcessHeap(), 0, lpRequest
);
2030 InterlockedDecrement(&dwNumJobs
);
2037 /***********************************************************************
2038 * INTERNET_AsyncCall (internal)
2040 * Retrieves work request from queue
2045 BOOL
INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest
)
2049 BOOL bSuccess
= FALSE
;
2053 if (InterlockedDecrement(&dwNumIdleThreads
) < 0)
2055 InterlockedIncrement(&dwNumIdleThreads
);
2057 if (InterlockedIncrement(&dwNumThreads
) > MAX_WORKER_THREADS
||
2058 !(hThread
= CreateThread(NULL
, 0,
2059 (LPTHREAD_START_ROUTINE
)INTERNET_WorkerThreadFunc
, NULL
, 0, &dwTID
)))
2061 InterlockedDecrement(&dwNumThreads
);
2062 INTERNET_SetLastError(ERROR_INTERNET_ASYNC_THREAD_FAILED
);
2066 TRACE("Created new thread\n");
2070 INTERNET_InsertWorkRequest(lpWorkRequest
);
2071 SetEvent(hWorkEvent
);
2079 /***********************************************************************
2080 * INTERNET_ExecuteWork (internal)
2085 VOID
INTERNET_ExecuteWork()
2087 WORKREQUEST workRequest
;
2091 if (INTERNET_GetWorkRequest(&workRequest
))
2093 TRACE("Got work %d\n", workRequest
.asyncall
);
2094 switch (workRequest
.asyncall
)
2097 FTP_FtpPutFileA((HINTERNET
)workRequest
.HFTPSESSION
, (LPCSTR
)workRequest
.LPSZLOCALFILE
,
2098 (LPCSTR
)workRequest
.LPSZNEWREMOTEFILE
, workRequest
.DWFLAGS
, workRequest
.DWCONTEXT
);
2099 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZLOCALFILE
);
2100 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZNEWREMOTEFILE
);
2103 case FTPSETCURRENTDIRECTORYA
:
2104 FTP_FtpSetCurrentDirectoryA((HINTERNET
)workRequest
.HFTPSESSION
,
2105 (LPCSTR
)workRequest
.LPSZDIRECTORY
);
2106 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZDIRECTORY
);
2109 case FTPCREATEDIRECTORYA
:
2110 FTP_FtpCreateDirectoryA((HINTERNET
)workRequest
.HFTPSESSION
,
2111 (LPCSTR
)workRequest
.LPSZDIRECTORY
);
2112 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZDIRECTORY
);
2115 case FTPFINDFIRSTFILEA
:
2116 FTP_FtpFindFirstFileA((HINTERNET
)workRequest
.HFTPSESSION
,
2117 (LPCSTR
)workRequest
.LPSZSEARCHFILE
,
2118 (LPWIN32_FIND_DATAA
)workRequest
.LPFINDFILEDATA
, workRequest
.DWFLAGS
,
2119 workRequest
.DWCONTEXT
);
2120 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZSEARCHFILE
);
2123 case FTPGETCURRENTDIRECTORYA
:
2124 FTP_FtpGetCurrentDirectoryA((HINTERNET
)workRequest
.HFTPSESSION
,
2125 (LPSTR
)workRequest
.LPSZDIRECTORY
, (LPDWORD
)workRequest
.LPDWDIRECTORY
);
2129 FTP_FtpOpenFileA((HINTERNET
)workRequest
.HFTPSESSION
,
2130 (LPCSTR
)workRequest
.LPSZFILENAME
,
2131 workRequest
.FDWACCESS
,
2132 workRequest
.DWFLAGS
,
2133 workRequest
.DWCONTEXT
);
2134 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZFILENAME
);
2138 FTP_FtpGetFileA((HINTERNET
)workRequest
.HFTPSESSION
,
2139 (LPCSTR
)workRequest
.LPSZREMOTEFILE
,
2140 (LPCSTR
)workRequest
.LPSZNEWFILE
,
2141 (BOOL
)workRequest
.FFAILIFEXISTS
,
2142 workRequest
.DWLOCALFLAGSATTRIBUTE
,
2143 workRequest
.DWFLAGS
,
2144 workRequest
.DWCONTEXT
);
2145 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZREMOTEFILE
);
2146 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZNEWFILE
);
2149 case FTPDELETEFILEA
:
2150 FTP_FtpDeleteFileA((HINTERNET
)workRequest
.HFTPSESSION
,
2151 (LPCSTR
)workRequest
.LPSZFILENAME
);
2152 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZFILENAME
);
2155 case FTPREMOVEDIRECTORYA
:
2156 FTP_FtpRemoveDirectoryA((HINTERNET
)workRequest
.HFTPSESSION
,
2157 (LPCSTR
)workRequest
.LPSZDIRECTORY
);
2158 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZDIRECTORY
);
2161 case FTPRENAMEFILEA
:
2162 FTP_FtpRenameFileA((HINTERNET
)workRequest
.HFTPSESSION
,
2163 (LPCSTR
)workRequest
.LPSZSRCFILE
,
2164 (LPCSTR
)workRequest
.LPSZDESTFILE
);
2165 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZSRCFILE
);
2166 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZDESTFILE
);
2169 case INTERNETFINDNEXTA
:
2170 INTERNET_FindNextFileA((HINTERNET
)workRequest
.HFTPSESSION
,
2171 (LPWIN32_FIND_DATAA
)workRequest
.LPFINDFILEDATA
);
2174 case HTTPSENDREQUESTA
:
2175 HTTP_HttpSendRequestA((HINTERNET
)workRequest
.HFTPSESSION
,
2176 (LPCSTR
)workRequest
.LPSZHEADER
,
2177 workRequest
.DWHEADERLENGTH
,
2178 (LPVOID
)workRequest
.LPOPTIONAL
,
2179 workRequest
.DWOPTIONALLENGTH
);
2180 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZHEADER
);
2183 case HTTPOPENREQUESTA
:
2184 HTTP_HttpOpenRequestA((HINTERNET
)workRequest
.HFTPSESSION
,
2185 (LPCSTR
)workRequest
.LPSZVERB
,
2186 (LPCSTR
)workRequest
.LPSZOBJECTNAME
,
2187 (LPCSTR
)workRequest
.LPSZVERSION
,
2188 (LPCSTR
)workRequest
.LPSZREFERRER
,
2189 (LPCSTR
*)workRequest
.LPSZACCEPTTYPES
,
2190 workRequest
.DWFLAGS
,
2191 workRequest
.DWCONTEXT
);
2192 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZVERB
);
2193 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZOBJECTNAME
);
2194 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZVERSION
);
2195 HeapFree(GetProcessHeap(), 0, (LPVOID
)workRequest
.LPSZREFERRER
);
2199 SendAsyncCallbackInt((LPWININETAPPINFOA
)workRequest
.param1
,
2200 (HINTERNET
)workRequest
.param2
, workRequest
.param3
,
2201 workRequest
.param4
, (LPVOID
)workRequest
.param5
,
2202 workRequest
.param6
);
2209 /***********************************************************************
2210 * INTERNET_GetResponseBuffer
2215 LPSTR
INTERNET_GetResponseBuffer()
2217 LPWITHREADERROR lpwite
= (LPWITHREADERROR
)TlsGetValue(g_dwTlsErrIndex
);
2219 return lpwite
->response
;
2222 /***********************************************************************
2223 * INTERNET_GetNextLine (internal)
2225 * Parse next line in directory string listing
2228 * Pointer to beginning of next line
2233 LPSTR
INTERNET_GetNextLine(INT nSocket
, LPSTR lpszBuffer
, LPDWORD dwBuffer
)
2237 BOOL bSuccess
= FALSE
;
2243 FD_SET(nSocket
, &infd
);
2244 tv
.tv_sec
=RESPONSE_TIMEOUT
;
2247 while (nRecv
< *dwBuffer
)
2249 if (select(nSocket
+1,&infd
,NULL
,NULL
,&tv
) > 0)
2251 if (recv(nSocket
, &lpszBuffer
[nRecv
], 1, 0) <= 0)
2253 INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS
);
2257 if (lpszBuffer
[nRecv
] == '\n')
2262 if (lpszBuffer
[nRecv
] != '\r')
2267 INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT
);
2275 lpszBuffer
[nRecv
] = '\0';
2276 *dwBuffer
= nRecv
- 1;
2277 TRACE(":%d %s\n", nRecv
, lpszBuffer
);
2286 /***********************************************************************
2289 BOOL WINAPI
InternetQueryDataAvailable( HINTERNET hFile
,
2290 LPDWORD lpdwNumberOfBytesAvailble
,
2291 DWORD dwFlags
, DWORD dwConext
)
2293 LPWININETHTTPREQA lpwhr
= (LPWININETHTTPREQA
) hFile
;
2300 SetLastError(ERROR_NO_MORE_FILES
);
2304 TRACE("--> %p %i\n",lpwhr
,lpwhr
->hdr
.htype
);
2306 switch (lpwhr
->hdr
.htype
)
2309 if (!NETCON_recv(&((LPWININETHTTPREQA
)hFile
)->netConnection
, buffer
,
2310 4048, MSG_PEEK
, (int *)lpdwNumberOfBytesAvailble
))
2312 SetLastError(ERROR_NO_MORE_FILES
);
2320 FIXME("unsuported file type\n");
2324 TRACE("<-- %i\n",retval
);
2329 /***********************************************************************
2332 BOOL WINAPI
InternetLockRequestFile( HINTERNET hInternet
, HANDLE
2339 BOOL WINAPI
InternetUnlockRequestFile( HANDLE hLockHandle
)
2346 /***********************************************************************
2349 * On windows this function is supposed to dial the default internet
2350 * connection. We don't want to have Wine dial out to the internet so
2351 * we return TRUE by default. It might be nice to check if we are connected.
2358 BOOL WINAPI
InternetAutodial(DWORD dwFlags
, HWND hwndParent
)
2362 /* Tell that we are connected to the internet. */
2366 /***********************************************************************
2367 * InternetAutodialHangup
2369 * Hangs up an connection made with InternetAutodial
2378 BOOL WINAPI
InternetAutodialHangup(DWORD dwReserved
)
2382 /* we didn't dial, we don't disconnect */
2386 /***********************************************************************
2388 * InternetCombineUrlA
2390 * Combine a base URL with a relative URL
2398 BOOL WINAPI
InternetCombineUrlA(LPCSTR lpszBaseUrl
, LPCSTR lpszRelativeUrl
,
2399 LPSTR lpszBuffer
, LPDWORD lpdwBufferLength
,
2403 /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
2404 dwFlags
^= ICU_NO_ENCODE
;
2405 hr
=UrlCombineA(lpszBaseUrl
,lpszRelativeUrl
,lpszBuffer
,lpdwBufferLength
,dwFlags
);
2410 /***********************************************************************
2412 * InternetCombineUrlW
2414 * Combine a base URL with a relative URL
2422 BOOL WINAPI
InternetCombineUrlW(LPCWSTR lpszBaseUrl
, LPCWSTR lpszRelativeUrl
,
2423 LPWSTR lpszBuffer
, LPDWORD lpdwBufferLength
,
2427 /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
2428 dwFlags
^= ICU_NO_ENCODE
;
2429 hr
=UrlCombineW(lpszBaseUrl
,lpszRelativeUrl
,lpszBuffer
,lpdwBufferLength
,dwFlags
);