- Sync wininet with Wine 1.1.22. Tested on Firefox 2.0 and Downloader

svn path=/trunk/; revision=41059
This commit is contained in:
Dmitry Chapyshev 2009-05-23 10:18:19 +00:00
parent 24ceaa277d
commit 0f06b0408a
11 changed files with 1460 additions and 980 deletions

View file

@ -23,6 +23,10 @@
#include "config.h"
#include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@ -48,7 +52,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet);
* Cookies are currently memory only.
* Cookies are NOT THREAD SAFE
* Cookies could use A LOT OF MEMORY. We need some kind of memory management here!
* Cookies should care about the expiry time
*/
typedef struct _cookie_domain cookie_domain;
@ -62,7 +65,7 @@ struct _cookie
LPWSTR lpCookieName;
LPWSTR lpCookieData;
time_t expiry; /* FIXME: not used */
FILETIME expiry;
};
struct _cookie_domain
@ -76,7 +79,7 @@ struct _cookie_domain
static struct list domain_list = LIST_INIT(domain_list);
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data);
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data, FILETIME expiry);
static cookie *COOKIE_findCookie(cookie_domain *domain, LPCWSTR lpszCookieName);
static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain);
static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path);
@ -84,13 +87,14 @@ static void COOKIE_deleteDomain(cookie_domain *deadDomain);
/* adds a cookie to the domain */
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data)
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data, FILETIME expiry)
{
cookie *newCookie = HeapAlloc(GetProcessHeap(), 0, sizeof(cookie));
list_init(&newCookie->entry);
newCookie->lpCookieName = NULL;
newCookie->lpCookieData = NULL;
newCookie->expiry = expiry;
if (name)
{
@ -177,6 +181,7 @@ static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path)
static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostNameLen, LPWSTR path, int pathLen)
{
URL_COMPONENTSW UrlComponents;
BOOL rc;
UrlComponents.lpszExtraInfo = NULL;
UrlComponents.lpszPassword = NULL;
@ -191,7 +196,22 @@ static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostName
UrlComponents.dwHostNameLength = hostNameLen;
UrlComponents.dwUrlPathLength = pathLen;
return InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents);
rc = InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents);
/* discard the webpage off the end of the path */
if (pathLen > 0 && path[pathLen-1] != '/')
{
LPWSTR ptr;
ptr = strrchrW(path,'/');
if (ptr)
*(++ptr) = 0;
else
{
path[0] = '/';
path[1] = 0;
}
}
return rc;
}
/* match a domain. domain must match if the domain is not NULL. path must match if the path is not NULL */
@ -215,12 +235,23 @@ static BOOL COOKIE_matchDomain(LPCWSTR lpszCookieDomain, LPCWSTR lpszCookiePath,
}
if (lpszCookiePath)
{
INT len;
TRACE("comparing paths: %s with %s\n", debugstr_w(lpszCookiePath), debugstr_w(searchDomain->lpCookiePath));
/* paths match at the beginning. so a path of /foo would match
* /foobar and /foo/bar
*/
if (!searchDomain->lpCookiePath)
return FALSE;
if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath))
if (allow_partial)
{
len = lstrlenW(searchDomain->lpCookiePath);
if (strncmpiW(searchDomain->lpCookiePath, lpszCookiePath, len)!=0)
return FALSE;
}
else if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath))
return FALSE;
}
return TRUE;
}
@ -262,6 +293,7 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
struct list * cursor;
unsigned int cnt = 0, domain_count = 0, cookie_count = 0;
WCHAR hostName[2048], path[2048];
FILETIME tm;
TRACE("(%s, %s, %p, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName),
lpCookieData, lpdwSize);
@ -276,10 +308,12 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0]));
if (!ret || !hostName[0]) return FALSE;
GetSystemTimeAsFileTime(&tm);
LIST_FOR_EACH(cursor, &domain_list)
{
cookie_domain *cookiesDomain = LIST_ENTRY(cursor, cookie_domain, entry);
if (COOKIE_matchDomain(hostName, NULL /* FIXME: path */, cookiesDomain, TRUE))
if (COOKIE_matchDomain(hostName, path, cookiesDomain, TRUE))
{
struct list * cursor;
domain_count++;
@ -288,6 +322,14 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
LIST_FOR_EACH(cursor, &cookiesDomain->cookie_list)
{
cookie *thisCookie = LIST_ENTRY(cursor, cookie, entry);
/* check for expiry */
if ((thisCookie->expiry.dwLowDateTime != 0 || thisCookie->expiry.dwHighDateTime != 0) && CompareFileTime(&tm,&thisCookie->expiry) > 0)
{
TRACE("Found expired cookie. deleting\n");
COOKIE_deleteCookie(thisCookie, FALSE);
continue;
}
if (lpCookieData == NULL) /* return the size of the buffer required to lpdwSize */
{
unsigned int len;
@ -405,27 +447,116 @@ static BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWST
cookie_domain *thisCookieDomain = NULL;
cookie *thisCookie;
struct list *cursor;
LPWSTR data, value;
WCHAR *ptr;
FILETIME expiry;
BOOL expired = FALSE;
value = data = HeapAlloc(GetProcessHeap(), 0, (strlenW(cookie_data) + 1) * sizeof(WCHAR));
strcpyW(data,cookie_data);
memset(&expiry,0,sizeof(expiry));
/* lots of information can be parsed out of the cookie value */
ptr = data;
for (;;)
{
static const WCHAR szDomain[] = {'d','o','m','a','i','n','=',0};
static const WCHAR szPath[] = {'p','a','t','h','=',0};
static const WCHAR szExpires[] = {'e','x','p','i','r','e','s','=',0};
static const WCHAR szSecure[] = {'s','e','c','u','r','e',0};
static const WCHAR szHttpOnly[] = {'h','t','t','p','o','n','l','y',0};
if (!(ptr = strchrW(ptr,';'))) break;
*ptr++ = 0;
value = HeapAlloc(GetProcessHeap(), 0, (ptr - data) * sizeof(WCHAR));
strcpyW(value, data);
while (*ptr == ' ') ptr++; /* whitespace */
if (strncmpiW(ptr, szDomain, 7) == 0)
{
ptr+=strlenW(szDomain);
domain = ptr;
TRACE("Parsing new domain %s\n",debugstr_w(domain));
}
else if (strncmpiW(ptr, szPath, 5) == 0)
{
ptr+=strlenW(szPath);
path = ptr;
TRACE("Parsing new path %s\n",debugstr_w(path));
}
else if (strncmpiW(ptr, szExpires, 8) == 0)
{
FILETIME ft;
SYSTEMTIME st;
FIXME("persistent cookies not handled (%s)\n",debugstr_w(ptr));
ptr+=strlenW(szExpires);
if (InternetTimeToSystemTimeW(ptr, &st, 0))
{
SystemTimeToFileTime(&st, &expiry);
GetSystemTimeAsFileTime(&ft);
if (CompareFileTime(&ft,&expiry) > 0)
{
TRACE("Cookie already expired.\n");
expired = TRUE;
}
}
}
else if (strncmpiW(ptr, szSecure, 6) == 0)
{
FIXME("secure not handled (%s)\n",debugstr_w(ptr));
ptr += strlenW(szSecure);
}
else if (strncmpiW(ptr, szHttpOnly, 8) == 0)
{
FIXME("httponly not handled (%s)\n",debugstr_w(ptr));
ptr += strlenW(szHttpOnly);
}
else if (*ptr)
{
FIXME("Unknown additional option %s\n",debugstr_w(ptr));
break;
}
}
LIST_FOR_EACH(cursor, &domain_list)
{
thisCookieDomain = LIST_ENTRY(cursor, cookie_domain, entry);
if (COOKIE_matchDomain(domain, NULL /* FIXME: path */, thisCookieDomain, FALSE))
if (COOKIE_matchDomain(domain, path, thisCookieDomain, FALSE))
break;
thisCookieDomain = NULL;
}
if (!thisCookieDomain)
{
if (!expired)
thisCookieDomain = COOKIE_addDomain(domain, path);
else
{
HeapFree(GetProcessHeap(),0,data);
if (value != data) HeapFree(GetProcessHeap(), 0, value);
return TRUE;
}
}
if ((thisCookie = COOKIE_findCookie(thisCookieDomain, cookie_name)))
COOKIE_deleteCookie(thisCookie, FALSE);
TRACE("setting cookie %s=%s for domain %s\n", debugstr_w(cookie_name),
debugstr_w(cookie_data), debugstr_w(thisCookieDomain->lpCookieDomain));
TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_w(cookie_name),
debugstr_w(value), debugstr_w(thisCookieDomain->lpCookieDomain),debugstr_w(thisCookieDomain->lpCookiePath));
if (!COOKIE_addCookie(thisCookieDomain, cookie_name, cookie_data))
if (!expired && !COOKIE_addCookie(thisCookieDomain, cookie_name, value, expiry))
{
HeapFree(GetProcessHeap(),0,data);
if (value != data) HeapFree(GetProcessHeap(), 0, value);
return FALSE;
}
HeapFree(GetProcessHeap(),0,data);
if (value != data) HeapFree(GetProcessHeap(), 0, value);
return TRUE;
}
@ -475,7 +606,7 @@ BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
* the cookie data in the form of name[=data].
*/
if (!(data = strchrW(cookie, '='))) data = cookie + len;
else data++;
else *data++ = 0;
ret = set_cookie(hostName, path, cookie, data);
@ -692,3 +823,28 @@ BOOL WINAPI InternetSetPerSiteCookieDecisionW( LPCWSTR pchHostName, DWORD dwDeci
FIXME("(%s, 0x%08x) stub\n", debugstr_w(pchHostName), dwDecision);
return FALSE;
}
/***********************************************************************
* IsDomainLegalCookieDomainW (WININET.@)
*/
BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 )
{
const WCHAR *p;
FIXME("(%s, %s)\n", debugstr_w(s1), debugstr_w(s2));
if (!s1 || !s2)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (s1[0] == '.' || !s1[0] || s2[0] == '.' || !s2[0])
{
SetLastError(ERROR_INVALID_NAME);
return FALSE;
}
if (!(p = strchrW(s2, '.'))) return FALSE;
if (strchrW(p + 1, '.') && !strcmpW(p + 1, s1)) return TRUE;
else if (!strcmpW(s1, s2)) return TRUE;
return FALSE;
}

View file

@ -21,6 +21,10 @@
#include "config.h"
#include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <stdarg.h>
#include "windef.h"

View file

@ -30,6 +30,10 @@
#include "config.h"
#include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
@ -42,6 +46,9 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#include <time.h>
#include <assert.h>
@ -90,7 +97,7 @@ typedef struct
BOOL bIsDirectory;
LPWSTR lpszName;
DWORD nSize;
struct tm tmLastModified;
SYSTEMTIME tmLastModified;
unsigned short permissions;
} FILEPROPERTIESW, *LPFILEPROPERTIESW;
@ -199,8 +206,6 @@ static BOOL FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszC
static BOOL FTP_FtpRenameFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszSrc, LPCWSTR lpszDest);
static BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
static BOOL FTP_FtpDeleteFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName);
static HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName,
DWORD fdwAccess, DWORD dwFlags, DWORD_PTR dwContext);
static BOOL FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
DWORD_PTR dwContext);
@ -854,13 +859,13 @@ lend:
if (hFindNext)
{
iar.dwResult = (DWORD)hFindNext;
iar.dwResult = (DWORD_PTR)hFindNext;
iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
iar.dwResult = (DWORD)hFindNext;
iar.dwResult = (DWORD_PTR)hFindNext;
iar.dwError = hFindNext ? ERROR_SUCCESS : INTERNET_GetLastError();
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
@ -1071,6 +1076,268 @@ lend:
return bSuccess;
}
/***********************************************************************
* FTPFILE_Destroy(internal)
*
* Closes the file transfer handle. This also 'cleans' the data queue of
* the 'transfer complete' message (this is a bit of a hack though :-/ )
*
*/
static void FTPFILE_Destroy(WININETHANDLEHEADER *hdr)
{
LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr;
LPWININETFTPSESSIONW lpwfs = lpwh->lpFtpSession;
INT nResCode;
TRACE("\n");
if (!lpwh->session_deleted)
lpwfs->download_in_progress = NULL;
if (lpwh->nDataSocket != -1)
closesocket(lpwh->nDataSocket);
nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
if (nResCode > 0 && nResCode != 226) WARN("server reports failed transfer\n");
WININET_Release(&lpwh->lpFtpSession->hdr);
HeapFree(GetProcessHeap(), 0, lpwh);
}
static DWORD FTPFILE_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
{
switch(option) {
case INTERNET_OPTION_HANDLE_TYPE:
TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
if (*size < sizeof(ULONG))
return ERROR_INSUFFICIENT_BUFFER;
*size = sizeof(DWORD);
*(DWORD*)buffer = INTERNET_HANDLE_TYPE_FTP_FILE;
return ERROR_SUCCESS;
}
return INET_QueryOption(option, buffer, size, unicode);
}
static DWORD FTPFILE_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read)
{
WININETFTPFILE *file = (WININETFTPFILE*)hdr;
int res;
if (file->nDataSocket == -1)
return ERROR_INTERNET_DISCONNECTED;
/* FIXME: FTP should use NETCON_ stuff */
res = recv(file->nDataSocket, buffer, size, MSG_WAITALL);
*read = res>0 ? res : 0;
return res>=0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME*/
}
static DWORD FTPFILE_ReadFileExA(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSA *buffers,
DWORD flags, DWORD_PTR context)
{
return FTPFILE_ReadFile(hdr, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength);
}
static DWORD FTPFILE_ReadFileExW(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSW *buffers,
DWORD flags, DWORD_PTR context)
{
return FTPFILE_ReadFile(hdr, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength);
}
static BOOL FTPFILE_WriteFile(WININETHANDLEHEADER *hdr, const void *buffer, DWORD size, DWORD *written)
{
LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr;
int res;
res = send(lpwh->nDataSocket, buffer, size, 0);
*written = res>0 ? res : 0;
return res >= 0;
}
static void FTP_ReceiveRequestData(WININETFTPFILE *file, BOOL first_notif)
{
INTERNET_ASYNC_RESULT iar;
BYTE buffer[4096];
int available;
TRACE("%p\n", file);
available = recv(file->nDataSocket, buffer, sizeof(buffer), MSG_PEEK);
if(available != -1) {
iar.dwResult = (DWORD_PTR)file->hdr.hInternet;
iar.dwError = first_notif ? 0 : available;
}else {
iar.dwResult = 0;
iar.dwError = INTERNET_GetLastError();
}
INTERNET_SendCallback(&file->hdr, file->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar,
sizeof(INTERNET_ASYNC_RESULT));
}
static void FTPFILE_AsyncQueryDataAvailableProc(WORKREQUEST *workRequest)
{
WININETFTPFILE *file = (WININETFTPFILE*)workRequest->hdr;
FTP_ReceiveRequestData(file, FALSE);
}
static DWORD FTPFILE_QueryDataAvailable(WININETHANDLEHEADER *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx)
{
LPWININETFTPFILE file = (LPWININETFTPFILE) hdr;
int retval, unread = 0;
TRACE("(%p %p %x %lx)\n", file, available, flags, ctx);
#ifdef FIONREAD
retval = ioctlsocket(file->nDataSocket, FIONREAD, &unread);
if (!retval)
TRACE("%d bytes of queued, but unread data\n", unread);
#else
FIXME("FIONREAD not available\n");
#endif
*available = unread;
if(!unread) {
BYTE byte;
*available = 0;
retval = recv(file->nDataSocket, &byte, 1, MSG_PEEK);
if(retval > 0) {
WORKREQUEST workRequest;
*available = 0;
workRequest.asyncproc = FTPFILE_AsyncQueryDataAvailableProc;
workRequest.hdr = WININET_AddRef( &file->hdr );
INTERNET_AsyncCall(&workRequest);
return ERROR_IO_PENDING;
}
}
return ERROR_SUCCESS;
}
static const HANDLEHEADERVtbl FTPFILEVtbl = {
FTPFILE_Destroy,
NULL,
FTPFILE_QueryOption,
NULL,
FTPFILE_ReadFile,
FTPFILE_ReadFileExA,
FTPFILE_ReadFileExW,
FTPFILE_WriteFile,
FTPFILE_QueryDataAvailable,
NULL
};
/***********************************************************************
* FTP_FtpOpenFileW (Internal)
*
* Open a remote file for writing or reading
*
* RETURNS
* HINTERNET handle on success
* NULL on failure
*
*/
HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs,
LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
DWORD_PTR dwContext)
{
INT nDataSocket;
BOOL bSuccess = FALSE;
LPWININETFTPFILE lpwh = NULL;
LPWININETAPPINFOW hIC = NULL;
HINTERNET handle = NULL;
TRACE("\n");
/* Clear any error information */
INTERNET_SetLastError(0);
if (GENERIC_READ == fdwAccess)
{
/* Set up socket to retrieve data */
bSuccess = FTP_SendRetrieve(lpwfs, lpszFileName, dwFlags);
}
else if (GENERIC_WRITE == fdwAccess)
{
/* Set up socket to send data */
bSuccess = FTP_SendStore(lpwfs, lpszFileName, dwFlags);
}
/* Get data socket to server */
if (bSuccess && FTP_GetDataSocket(lpwfs, &nDataSocket))
{
lpwh = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPFILE));
lpwh->hdr.htype = WH_HFILE;
lpwh->hdr.vtbl = &FTPFILEVtbl;
lpwh->hdr.dwFlags = dwFlags;
lpwh->hdr.dwContext = dwContext;
lpwh->hdr.refs = 1;
lpwh->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB;
lpwh->nDataSocket = nDataSocket;
lpwh->session_deleted = FALSE;
WININET_AddRef( &lpwfs->hdr );
lpwh->lpFtpSession = lpwfs;
list_add_head( &lpwfs->hdr.children, &lpwh->hdr.entry );
handle = WININET_AllocHandle( &lpwh->hdr );
if( !handle )
goto lend;
/* Indicate that a download is currently in progress */
lpwfs->download_in_progress = lpwh;
}
if (lpwfs->lstnSocket != -1)
closesocket(lpwfs->lstnSocket);
hIC = lpwfs->lpAppInfo;
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
INTERNET_ASYNC_RESULT iar;
if (lpwh)
{
iar.dwResult = (DWORD_PTR)handle;
iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
if(bSuccess) {
FTP_ReceiveRequestData(lpwh, TRUE);
}else {
iar.dwResult = 0;
iar.dwError = INTERNET_GetLastError();
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
}
lend:
if( lpwh )
WININET_Release( &lpwh->hdr );
return handle;
}
/***********************************************************************
* FtpOpenFileA (WININET.@)
*
@ -1184,181 +1451,6 @@ lend:
}
/***********************************************************************
* FTPFILE_Destroy(internal)
*
* Closes the file transfer handle. This also 'cleans' the data queue of
* the 'transfer complete' message (this is a bit of a hack though :-/ )
*
*/
static void FTPFILE_Destroy(WININETHANDLEHEADER *hdr)
{
LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr;
LPWININETFTPSESSIONW lpwfs = lpwh->lpFtpSession;
INT nResCode;
TRACE("\n");
WININET_Release(&lpwh->lpFtpSession->hdr);
if (!lpwh->session_deleted)
lpwfs->download_in_progress = NULL;
if (lpwh->nDataSocket != -1)
closesocket(lpwh->nDataSocket);
nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
if (nResCode > 0 && nResCode != 226) WARN("server reports failed transfer\n");
HeapFree(GetProcessHeap(), 0, lpwh);
}
static DWORD FTPFILE_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
{
switch(option) {
case INTERNET_OPTION_HANDLE_TYPE:
TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
if (*size < sizeof(ULONG))
return ERROR_INSUFFICIENT_BUFFER;
*size = sizeof(DWORD);
*(DWORD*)buffer = INTERNET_HANDLE_TYPE_FTP_FILE;
return ERROR_SUCCESS;
}
return INET_QueryOption(option, buffer, size, unicode);
}
static DWORD FTPFILE_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read)
{
WININETFTPFILE *file = (WININETFTPFILE*)hdr;
int res;
if (file->nDataSocket == -1)
return ERROR_INTERNET_DISCONNECTED;
/* FIXME: FTP should use NETCON_ stuff */
res = recv(file->nDataSocket, buffer, size, MSG_WAITALL);
*read = res>0 ? res : 0;
return res>=0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME*/
}
static BOOL FTPFILE_WriteFile(WININETHANDLEHEADER *hdr, const void *buffer, DWORD size, DWORD *written)
{
LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr;
int res;
res = send(lpwh->nDataSocket, buffer, size, 0);
*written = res>0 ? res : 0;
return res >= 0;
}
static const HANDLEHEADERVtbl FTPFILEVtbl = {
FTPFILE_Destroy,
NULL,
FTPFILE_QueryOption,
NULL,
FTPFILE_ReadFile,
NULL,
FTPFILE_WriteFile,
NULL,
NULL
};
/***********************************************************************
* FTP_FtpOpenFileW (Internal)
*
* Open a remote file for writing or reading
*
* RETURNS
* HINTERNET handle on success
* NULL on failure
*
*/
HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs,
LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
DWORD_PTR dwContext)
{
INT nDataSocket;
BOOL bSuccess = FALSE;
LPWININETFTPFILE lpwh = NULL;
LPWININETAPPINFOW hIC = NULL;
HINTERNET handle = NULL;
TRACE("\n");
/* Clear any error information */
INTERNET_SetLastError(0);
if (GENERIC_READ == fdwAccess)
{
/* Set up socket to retrieve data */
bSuccess = FTP_SendRetrieve(lpwfs, lpszFileName, dwFlags);
}
else if (GENERIC_WRITE == fdwAccess)
{
/* Set up socket to send data */
bSuccess = FTP_SendStore(lpwfs, lpszFileName, dwFlags);
}
/* Get data socket to server */
if (bSuccess && FTP_GetDataSocket(lpwfs, &nDataSocket))
{
lpwh = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPFILE));
lpwh->hdr.htype = WH_HFILE;
lpwh->hdr.vtbl = &FTPFILEVtbl;
lpwh->hdr.dwFlags = dwFlags;
lpwh->hdr.dwContext = dwContext;
lpwh->hdr.refs = 1;
lpwh->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB;
lpwh->nDataSocket = nDataSocket;
lpwh->session_deleted = FALSE;
WININET_AddRef( &lpwfs->hdr );
lpwh->lpFtpSession = lpwfs;
list_add_head( &lpwfs->hdr.children, &lpwh->hdr.entry );
handle = WININET_AllocHandle( &lpwh->hdr );
if( !handle )
goto lend;
/* Indicate that a download is currently in progress */
lpwfs->download_in_progress = lpwh;
}
if (lpwfs->lstnSocket != -1)
closesocket(lpwfs->lstnSocket);
hIC = lpwfs->lpAppInfo;
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
INTERNET_ASYNC_RESULT iar;
if (lpwh)
{
iar.dwResult = (DWORD)handle;
iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
iar.dwResult = (DWORD)bSuccess;
iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
lend:
if( lpwh )
WININET_Release( &lpwh->hdr );
return handle;
}
/***********************************************************************
* FtpGetFileA (WININET.@)
*
@ -2256,7 +2348,7 @@ HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
assert( hIC->hdr.htype == WH_HINIT );
if (NULL == lpszUserName && NULL != lpszPassword)
if ((!lpszUserName || !*lpszUserName) && lpszPassword && *lpszPassword)
{
INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
goto lerror;
@ -2302,7 +2394,7 @@ HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
if(hIC->lpszProxyBypass)
FIXME("Proxy bypass is ignored.\n");
}
if ( !lpszUserName) {
if (!lpszUserName || !strlenW(lpszUserName)) {
HKEY key;
WCHAR szPassword[MAX_PATH];
DWORD len = sizeof(szPassword);
@ -2336,7 +2428,7 @@ HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
{
INTERNET_ASYNC_RESULT iar;
iar.dwResult = (DWORD)handle;
iar.dwResult = (DWORD_PTR)handle;
iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&hIC->hdr, dwContext,
@ -2397,16 +2489,6 @@ lerror:
handle = NULL;
}
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
INTERNET_ASYNC_RESULT iar;
iar.dwResult = bSuccess ? (DWORD_PTR)lpwfs : 0;
iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
return handle;
}
@ -2737,7 +2819,7 @@ static BOOL FTP_InitListenSocket(LPWININETFTPSESSIONW lpwfs)
lpwfs->lstnSocketAddress = lpwfs->socketAddress;
/* and get the system to assign us a port */
lpwfs->lstnSocketAddress.sin_port = htons((u_short) 0);
lpwfs->lstnSocketAddress.sin_port = htons(0);
if (bind(lpwfs->lstnSocket,(struct sockaddr *) &lpwfs->lstnSocketAddress, sizeof(struct sockaddr_in)) == -1)
{
@ -3220,7 +3302,7 @@ static void FTPFINDNEXT_Destroy(WININETHANDLEHEADER *hdr)
HeapFree(GetProcessHeap(), 0, lpwfn);
}
static DWORD WINAPI FTPFINDNEXT_FindNextFileProc(WININETFTPFINDNEXTW *find, LPVOID data)
static DWORD FTPFINDNEXT_FindNextFileProc(WININETFTPFINDNEXTW *find, LPVOID data)
{
WIN32_FIND_DATAW *find_data = data;
DWORD res = ERROR_SUCCESS;
@ -3308,6 +3390,7 @@ static const HANDLEHEADERVtbl FTPFINDNEXTVtbl = {
NULL,
NULL,
NULL,
NULL,
FTPFINDNEXT_FindNextFileW
};
@ -3382,9 +3465,7 @@ static BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFi
if (lpafp)
{
/* Convert 'Unix' time to Windows time */
RtlSecondsSince1970ToTime(mktime(&lpafp->tmLastModified),
(LARGE_INTEGER *) &(lpFindFileData->ftLastAccessTime));
SystemTimeToFileTime( &lpafp->tmLastModified, &lpFindFileData->ftLastAccessTime );
lpFindFileData->ftLastWriteTime = lpFindFileData->ftLastAccessTime;
lpFindFileData->ftCreationTime = lpFindFileData->ftLastAccessTime;
@ -3452,12 +3533,12 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT
lpfp->nSize = atol(pszToken);
}
lpfp->tmLastModified.tm_sec = 0;
lpfp->tmLastModified.tm_min = 0;
lpfp->tmLastModified.tm_hour = 0;
lpfp->tmLastModified.tm_mday = 0;
lpfp->tmLastModified.tm_mon = 0;
lpfp->tmLastModified.tm_year = 0;
lpfp->tmLastModified.wSecond = 0;
lpfp->tmLastModified.wMinute = 0;
lpfp->tmLastModified.wHour = 0;
lpfp->tmLastModified.wDay = 0;
lpfp->tmLastModified.wMonth = 0;
lpfp->tmLastModified.wYear = 0;
/* Determine month */
pszToken = strtok(NULL, szSpace);
@ -3465,34 +3546,31 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT
if(strlen(pszToken) >= 3) {
pszToken[3] = 0;
if((pszTmp = StrStrIA(szMonths, pszToken)))
lpfp->tmLastModified.tm_mon = ((pszTmp - szMonths) / 3)+1;
lpfp->tmLastModified.wMonth = ((pszTmp - szMonths) / 3)+1;
}
/* Determine day */
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
lpfp->tmLastModified.tm_mday = atoi(pszToken);
lpfp->tmLastModified.wDay = atoi(pszToken);
/* Determine time or year */
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
if((pszTmp = strchr(pszToken, ':'))) {
struct tm* apTM;
time_t aTime;
SYSTEMTIME curr_time;
*pszTmp = 0;
pszTmp++;
lpfp->tmLastModified.tm_min = atoi(pszTmp);
lpfp->tmLastModified.tm_hour = atoi(pszToken);
time(&aTime);
apTM = localtime(&aTime);
lpfp->tmLastModified.tm_year = apTM->tm_year;
lpfp->tmLastModified.wMinute = atoi(pszTmp);
lpfp->tmLastModified.wHour = atoi(pszToken);
GetLocalTime( &curr_time );
lpfp->tmLastModified.wYear = curr_time.wYear;
}
else {
lpfp->tmLastModified.tm_year = atoi(pszToken) - 1900;
lpfp->tmLastModified.tm_hour = 12;
lpfp->tmLastModified.wYear = atoi(pszToken);
lpfp->tmLastModified.wHour = 12;
}
TRACE("Mod time: %02d:%02d:%02d %02d/%02d/%02d\n",
lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.tm_min, lpfp->tmLastModified.tm_sec,
(lpfp->tmLastModified.tm_year >= 100) ? lpfp->tmLastModified.tm_year - 100 : lpfp->tmLastModified.tm_year,
lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.tm_mday);
TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n",
lpfp->tmLastModified.wHour, lpfp->tmLastModified.wMinute, lpfp->tmLastModified.wSecond,
lpfp->tmLastModified.wYear, lpfp->tmLastModified.wMonth, lpfp->tmLastModified.wDay);
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
@ -3505,31 +3583,30 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT
05-09-03 06:02PM 12656686 2003-04-21bgm_cmd_e.rgz
*/
else if(isdigit(pszToken[0]) && 8 == strlen(pszToken)) {
int mon, mday, year, hour, min;
lpfp->permissions = 0xFFFF; /* No idea, put full permission :-) */
sscanf(pszToken, "%d-%d-%d",
&lpfp->tmLastModified.tm_mon,
&lpfp->tmLastModified.tm_mday,
&lpfp->tmLastModified.tm_year);
sscanf(pszToken, "%d-%d-%d", &mon, &mday, &year);
lpfp->tmLastModified.wDay = mday;
lpfp->tmLastModified.wMonth = mon;
lpfp->tmLastModified.wYear = year;
/* Hacky and bad Y2K protection :-) */
if (lpfp->tmLastModified.tm_year < 70)
lpfp->tmLastModified.tm_year += 100;
if (lpfp->tmLastModified.wYear < 70) lpfp->tmLastModified.wYear += 2000;
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
sscanf(pszToken, "%d:%d",
&lpfp->tmLastModified.tm_hour,
&lpfp->tmLastModified.tm_min);
sscanf(pszToken, "%d:%d", &hour, &min);
lpfp->tmLastModified.wHour = hour;
lpfp->tmLastModified.wMinute = min;
if((pszToken[5] == 'P') && (pszToken[6] == 'M')) {
lpfp->tmLastModified.tm_hour += 12;
lpfp->tmLastModified.wHour += 12;
}
lpfp->tmLastModified.tm_sec = 0;
lpfp->tmLastModified.wSecond = 0;
TRACE("Mod time: %02d:%02d:%02d %02d/%02d/%02d\n",
lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.tm_min, lpfp->tmLastModified.tm_sec,
(lpfp->tmLastModified.tm_year >= 100) ? lpfp->tmLastModified.tm_year - 100 : lpfp->tmLastModified.tm_year,
lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.tm_mday);
TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n",
lpfp->tmLastModified.wHour, lpfp->tmLastModified.wMinute, lpfp->tmLastModified.wSecond,
lpfp->tmLastModified.wYear, lpfp->tmLastModified.wMonth, lpfp->tmLastModified.wDay);
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;

File diff suppressed because it is too large Load diff

View file

@ -31,6 +31,10 @@
#define MAXHOSTNAME 100 /* from http.c */
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
@ -113,7 +117,7 @@ HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info )
{
num = HANDLE_CHUNK_SIZE;
p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof (UINT)* num);
sizeof (*WININET_Handles)* num);
if( !p )
goto end;
WININET_Handles = p;
@ -123,7 +127,7 @@ HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info )
{
num = WININET_dwMaxHandles + HANDLE_CHUNK_SIZE;
p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
WININET_Handles, sizeof (UINT)* num);
WININET_Handles, sizeof (*WININET_Handles)* num);
if( !p )
goto end;
WININET_Handles = p;
@ -182,7 +186,8 @@ BOOL WININET_Release( LPWININETHANDLEHEADER info )
info->vtbl->CloseConnection( info );
}
/* Don't send a callback if this is a session handle created with InternetOpenUrl */
if (info->htype != WH_HHTTPSESSION || !(info->dwInternalFlags & INET_OPENURL))
if ((info->htype != WH_HHTTPSESSION && info->htype != WH_HFTPSESSION)
|| !(info->dwInternalFlags & INET_OPENURL))
{
INTERNET_SendCallback(info, info->dwContext,
INTERNET_STATUS_HANDLE_CLOSING, &info->hInternet,
@ -410,8 +415,11 @@ static BOOL INTERNET_ConfigureProxy( LPWININETAPPINFOW lpwai )
TRACE("http proxy (from environment) = %s\n", debugstr_w(lpwai->lpszProxy));
enabled = 1;
}
if (!enabled) TRACE("Proxy is not enabled.\n");
if (!enabled)
{
TRACE("Proxy is not enabled.\n");
lpwai->dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
}
RegCloseKey( key );
return (enabled > 0);
}
@ -459,7 +467,7 @@ static void dump_INTERNET_FLAGS(DWORD dwFlags)
FE(INTERNET_FLAG_TRANSFER_BINARY)
};
#undef FE
int i;
unsigned int i;
for (i = 0; i < (sizeof(flag) / sizeof(flag[0])); i++) {
if (flag[i].val & dwFlags) {
@ -543,8 +551,10 @@ static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b
if (ai->lpszProxyBypass)
proxyBypassBytesRequired = (lstrlenW(ai->lpszProxyBypass) + 1) * sizeof(WCHAR);
if (*size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired)
{
*size = sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired;
return ERROR_INSUFFICIENT_BUFFER;
}
proxy = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW));
proxy_bypass = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired);
@ -574,8 +584,10 @@ static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b
proxyBypassBytesRequired = WideCharToMultiByte(CP_ACP, 0, ai->lpszProxyBypass, -1,
NULL, 0, NULL, NULL);
if (*size < sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired)
{
*size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired;
return ERROR_INSUFFICIENT_BUFFER;
}
proxy = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA));
proxy_bypass = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired);
@ -779,7 +791,7 @@ HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType,
BOOL WINAPI InternetGetLastResponseInfoA(LPDWORD lpdwError,
LPSTR lpszBuffer, LPDWORD lpdwBufferLength)
{
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
TRACE("\n");
@ -816,7 +828,7 @@ BOOL WINAPI InternetGetLastResponseInfoA(LPDWORD lpdwError,
BOOL WINAPI InternetGetLastResponseInfoW(LPDWORD lpdwError,
LPWSTR lpszBuffer, LPDWORD lpdwBufferLength)
{
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
TRACE("\n");
@ -856,7 +868,7 @@ BOOL WINAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved)
TRACE("(%p, 0x%08x)\n", lpdwStatus, dwReserved);
if (lpdwStatus) {
FIXME("always returning LAN connection.\n");
WARN("always returning LAN connection.\n");
*lpdwStatus = INTERNET_CONNECTION_LAN;
}
return TRUE;
@ -900,7 +912,7 @@ BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnecti
return FALSE;
if (lpdwStatus) {
FIXME("always returning LAN connection.\n");
WARN("always returning LAN connection.\n");
*lpdwStatus = INTERNET_CONNECTION_LAN;
}
return LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen);
@ -1813,7 +1825,7 @@ INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackA(
INTERNET_STATUS_CALLBACK retVal;
LPWININETHANDLEHEADER lpwh;
TRACE("0x%08x\n", (ULONG)hInternet);
TRACE("%p\n", hInternet);
if (!(lpwh = WININET_GetObject(hInternet)))
return INTERNET_INVALID_STATUS_CALLBACK;
@ -1841,7 +1853,7 @@ INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW(
INTERNET_STATUS_CALLBACK retVal;
LPWININETHANDLEHEADER lpwh;
TRACE("0x%08x\n", (ULONG)hInternet);
TRACE("%p\n", hInternet);
if (!(lpwh = WININET_GetObject(hInternet)))
return INTERNET_INVALID_STATUS_CALLBACK;
@ -1994,33 +2006,40 @@ BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOu
/***********************************************************************
* InternetReadFileExW (WININET.@)
*
* Read data from an open internet file.
*
* PARAMS
* hFile [I] Handle returned by InternetOpenUrl() or HttpOpenRequest().
* lpBuffersOut [I/O] Buffer.
* dwFlags [I] Flags.
* dwContext [I] Context for callbacks.
*
* RETURNS
* FALSE, last error is set to ERROR_CALL_NOT_IMPLEMENTED
*
* NOTES
* Not implemented in Wine or native either (as of IE6 SP2).
*
* SEE
* InternetReadFileExA()
*/
BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer,
DWORD dwFlags, DWORD_PTR dwContext)
{
ERR("(%p, %p, 0x%x, 0x%lx): not implemented in native\n", hFile, lpBuffer, dwFlags, dwContext);
LPWININETHANDLEHEADER hdr;
DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
TRACE("(%p %p 0x%x 0x%lx)\n", hFile, lpBuffer, dwFlags, dwContext);
hdr = WININET_GetObject(hFile);
if (!hdr) {
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if(hdr->vtbl->ReadFileExW)
res = hdr->vtbl->ReadFileExW(hdr, lpBuffer, dwFlags, dwContext);
WININET_Release(hdr);
TRACE("-- %s (%u, bytes read: %d)\n", res == ERROR_SUCCESS ? "TRUE": "FALSE",
res, lpBuffer->dwBufferLength);
if(res != ERROR_SUCCESS)
SetLastError(res);
return res == ERROR_SUCCESS;
}
DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode)
{
static BOOL warn = TRUE;
switch(option) {
case INTERNET_OPTION_REQUEST_FLAGS:
TRACE("INTERNET_OPTION_REQUEST_FLAGS\n");
@ -2047,8 +2066,11 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode)
return ERROR_SUCCESS;
case INTERNET_OPTION_CONNECTED_STATE:
FIXME("INTERNET_OPTION_CONNECTED_STATE: semi-stub\n");
if (warn) {
FIXME("INTERNET_OPTION_CONNECTED_STATE: semi-stub\n");
warn = FALSE;
}
if (*size < sizeof(ULONG))
return ERROR_INSUFFICIENT_BUFFER;
@ -2133,8 +2155,7 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode)
case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME:
case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
FIXME("Unhandled dwOption %d\n", option->dwOption);
option->Value.dwValue = 0;
res = ERROR_INVALID_PARAMETER;
memset(&option->Value, 0, sizeof(option->Value));
break;
default:
@ -2256,9 +2277,14 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
{
case INTERNET_OPTION_CALLBACK:
{
INTERNET_STATUS_CALLBACK callback = *(INTERNET_STATUS_CALLBACK *)lpBuffer;
ret = (set_status_callback(lpwhh, callback, TRUE) != INTERNET_INVALID_STATUS_CALLBACK);
break;
if (!lpwhh)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE;
}
WININET_Release(lpwhh);
INTERNET_SetLastError(ERROR_INTERNET_OPTION_NOT_SETTABLE);
return FALSE;
}
case INTERNET_OPTION_HTTP_VERSION:
{
@ -2342,8 +2368,35 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
case INTERNET_OPTION_DISABLE_AUTODIAL:
FIXME("Option INTERNET_OPTION_DISABLE_AUTODIAL; STUB\n");
break;
case 86:
FIXME("86\n");
case INTERNET_OPTION_HTTP_DECODING:
FIXME("INTERNET_OPTION_HTTP_DECODING; STUB\n");
INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION);
ret = FALSE;
break;
case INTERNET_OPTION_COOKIES_3RD_PARTY:
FIXME("INTERNET_OPTION_COOKIES_3RD_PARTY; STUB\n");
INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION);
ret = FALSE;
break;
case INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY:
FIXME("INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY; STUB\n");
INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION);
ret = FALSE;
break;
case INTERNET_OPTION_CODEPAGE_PATH:
FIXME("INTERNET_OPTION_CODEPAGE_PATH; STUB\n");
INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION);
ret = FALSE;
break;
case INTERNET_OPTION_CODEPAGE_EXTRA:
FIXME("INTERNET_OPTION_CODEPAGE_EXTRA; STUB\n");
INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION);
ret = FALSE;
break;
case INTERNET_OPTION_IDN:
FIXME("INTERNET_OPTION_IDN; STUB\n");
INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION);
ret = FALSE;
break;
default:
FIXME("Option %d STUB\n",dwOption);
@ -2381,12 +2434,15 @@ BOOL WINAPI InternetSetOptionA(HINTERNET hInternet, DWORD dwOption,
case INTERNET_OPTION_CALLBACK:
{
LPWININETHANDLEHEADER lpwh;
INTERNET_STATUS_CALLBACK callback = *(INTERNET_STATUS_CALLBACK *)lpBuffer;
if (!(lpwh = WININET_GetObject(hInternet))) return FALSE;
r = (set_status_callback(lpwh, callback, FALSE) != INTERNET_INVALID_STATUS_CALLBACK);
if (!(lpwh = WININET_GetObject(hInternet)))
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE;
}
WININET_Release(lpwh);
return r;
INTERNET_SetLastError(ERROR_INTERNET_OPTION_NOT_SETTABLE);
return FALSE;
}
case INTERNET_OPTION_PROXY:
{
@ -2475,6 +2531,18 @@ BOOL WINAPI InternetTimeFromSystemTimeA( const SYSTEMTIME* time, DWORD format, L
TRACE( "%p 0x%08x %p 0x%08x\n", time, format, string, size );
if (!time || !string || format != INTERNET_RFC1123_FORMAT)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (size < INTERNET_RFC1123_BUFSIZE * sizeof(*string))
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
ret = InternetTimeFromSystemTimeW( time, format, stringW, sizeof(stringW) );
if (ret) WideCharToMultiByte( CP_ACP, 0, stringW, -1, string, size, NULL, NULL );
@ -2492,10 +2560,17 @@ BOOL WINAPI InternetTimeFromSystemTimeW( const SYSTEMTIME* time, DWORD format, L
TRACE( "%p 0x%08x %p 0x%08x\n", time, format, string, size );
if (!time || !string) return FALSE;
if (format != INTERNET_RFC1123_FORMAT || size < INTERNET_RFC1123_BUFSIZE * sizeof(WCHAR))
if (!time || !string || format != INTERNET_RFC1123_FORMAT)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (size < INTERNET_RFC1123_BUFSIZE * sizeof(*string))
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
sprintfW( string, date,
WININET_wkday[time->wDayOfWeek],
@ -2805,6 +2880,8 @@ static HINTERNET INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUr
else
urlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT;
}
if (urlComponents.nScheme == INTERNET_SCHEME_HTTPS) dwFlags |= INTERNET_FLAG_SECURE;
/* FIXME: should use pointers, not handles, as handles are not thread-safe */
client = HTTP_Connect(hIC, hostName, urlComponents.nPort,
userName, password, dwFlags, dwContext, INET_OPENURL);
@ -3010,7 +3087,7 @@ static LPWITHREADERROR INTERNET_AllocThreadError(void)
*/
void INTERNET_SetLastError(DWORD dwError)
{
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
if (!lpwite)
lpwite = INTERNET_AllocThreadError();
@ -3031,7 +3108,7 @@ void INTERNET_SetLastError(DWORD dwError)
*/
DWORD INTERNET_GetLastError(void)
{
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
if (!lpwite) return 0;
/* TlsGetValue clears last error, so set it again here */
SetLastError(lpwite->dwError);
@ -3104,7 +3181,7 @@ BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest)
*/
LPSTR INTERNET_GetResponseBuffer(void)
{
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
if (!lpwite)
lpwite = INTERNET_AllocThreadError();
TRACE("\n");
@ -3451,6 +3528,9 @@ static BOOL calc_url_length(LPURL_COMPONENTSW lpUrlComponents,
if (lpUrlComponents->lpszUrlPath)
*lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath);
if (lpUrlComponents->lpszExtraInfo)
*lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, ExtraInfo);
return TRUE;
}
@ -3699,7 +3779,6 @@ BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags,
}
}
if (lpUrlComponents->lpszUrlPath)
{
dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath);
@ -3707,6 +3786,13 @@ BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags,
lpszUrl += dwLen;
}
if (lpUrlComponents->lpszExtraInfo)
{
dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, ExtraInfo);
memcpy(lpszUrl, lpUrlComponents->lpszExtraInfo, dwLen * sizeof(WCHAR));
lpszUrl += dwLen;
}
*lpszUrl = '\0';
return TRUE;
@ -3732,6 +3818,25 @@ DWORD WINAPI InternetConfirmZoneCrossingW( HWND hWnd, LPWSTR szUrlPrev, LPWSTR s
return ERROR_SUCCESS;
}
/***********************************************************************
* PrivacySetZonePreferenceW (WININET.@)
*/
DWORD WINAPI PrivacySetZonePreferenceW( DWORD zone, DWORD type, DWORD template, LPCWSTR preference )
{
FIXME( "%x %x %x %s: stub\n", zone, type, template, debugstr_w(preference) );
return 0;
}
/***********************************************************************
* PrivacyGetZonePreferenceW (WININET.@)
*/
DWORD WINAPI PrivacyGetZonePreferenceW( DWORD zone, DWORD type, LPDWORD template,
LPWSTR preference, LPDWORD length )
{
FIXME( "%x %x: stub\n", zone, type );
return 0;
}
DWORD WINAPI InternetDialA( HWND hwndParent, LPSTR lpszConnectoid, DWORD dwFlags,
DWORD_PTR* lpdwConnection, DWORD dwReserved )
{

View file

@ -42,29 +42,17 @@
# include <sys/socket.h>
#endif
#if defined(__MINGW32__) || defined (_MSC_VER)
#include "ws2tcpip.h"
#ifndef MSG_WAITALL
#define MSG_WAITALL 0
#endif
#else
#if !defined(__MINGW32__) && !defined(_MSC_VER)
#define closesocket close
#define ioctlsocket ioctl
#endif /* __MINGW32__ */
/* ReactOS-specific definitions */
#undef CP_UNIXCP
#define CP_UNIXCP CP_THREAD_ACP
/* used for netconnection.c stuff */
typedef struct
{
BOOL useSSL;
int socketFD;
void *ssl_s;
char *peek_msg;
char *peek_msg_mem;
size_t peek_len;
} WININET_NETCONNECTION;
static inline LPWSTR WININET_strdupW( LPCWSTR str )
@ -133,6 +121,7 @@ typedef struct {
DWORD (*SetOption)(WININETHANDLEHEADER*,DWORD,void*,DWORD);
DWORD (*ReadFile)(WININETHANDLEHEADER*,void*,DWORD,DWORD*);
DWORD (*ReadFileExA)(WININETHANDLEHEADER*,INTERNET_BUFFERSA*,DWORD,DWORD_PTR);
DWORD (*ReadFileExW)(WININETHANDLEHEADER*,INTERNET_BUFFERSW*,DWORD,DWORD_PTR);
BOOL (*WriteFile)(WININETHANDLEHEADER*,const void*,DWORD,DWORD*);
DWORD (*QueryDataAvailable)(WININETHANDLEHEADER*,DWORD*,DWORD,DWORD_PTR);
DWORD (*FindNextFileW)(WININETHANDLEHEADER*,void*);
@ -206,12 +195,18 @@ typedef struct
LPWSTR lpszStatusText;
DWORD dwContentLength; /* total number of bytes to be read */
DWORD dwContentRead; /* bytes of the content read so far */
DWORD dwBytesToWrite;
DWORD dwBytesWritten;
HTTPHEADERW *pCustHeaders;
DWORD nCustHeaders;
HANDLE hCacheFile;
LPWSTR lpszCacheFile;
struct HttpAuthInfo *pAuthInfo;
struct HttpAuthInfo *pProxyAuthInfo;
BOOL read_chunked; /* are we reading in chunked mode? */
DWORD read_pos; /* current read position in read_buf */
DWORD read_size; /* valid data size in read_buf */
char read_buf[4096]; /* buffer for already read but not returned data */
} WININETHTTPREQW, *LPWININETHTTPREQW;
@ -297,6 +292,12 @@ struct WORKREQ_HTTPSENDREQUESTW
BOOL bEndRequest;
};
struct WORKREQ_HTTPENDREQUESTW
{
DWORD dwFlags;
DWORD_PTR dwContext;
};
struct WORKREQ_SENDCALLBACK
{
DWORD_PTR dwContext;
@ -320,6 +321,11 @@ struct WORKREQ_INTERNETREADFILEEXA
LPINTERNET_BUFFERSA lpBuffersOut;
};
struct WORKREQ_INTERNETREADFILEEXW
{
LPINTERNET_BUFFERSW lpBuffersOut;
};
typedef struct WORKREQ
{
void (*asyncproc)(struct WORKREQ*);
@ -338,9 +344,11 @@ typedef struct WORKREQ
struct WORKREQ_FTPRENAMEFILEW FtpRenameFileW;
struct WORKREQ_FTPFINDNEXTW FtpFindNextW;
struct WORKREQ_HTTPSENDREQUESTW HttpSendRequestW;
struct WORKREQ_HTTPENDREQUESTW HttpEndRequestW;
struct WORKREQ_SENDCALLBACK SendCallback;
struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW;
struct WORKREQ_INTERNETREADFILEEXA InternetReadFileExA;
struct WORKREQ_INTERNETREADFILEEXW InternetReadFileExW;
} u;
} WORKREQUEST, *LPWORKREQUEST;
@ -381,7 +389,6 @@ INTERNETAPI HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs,
LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion,
LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes,
DWORD dwFlags, DWORD_PTR dwContext);
BOOL HTTP_FinishedReading(LPWININETHTTPREQW lpwhr);
VOID SendAsyncCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext,
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
@ -391,8 +398,6 @@ VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext,
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
DWORD dwStatusInfoLength);
LPHTTPHEADERW HTTP_GetHeader(LPWININETHTTPREQW lpwhr, LPCWSTR header);
BOOL NETCON_connected(WININET_NETCONNECTION *connection);
BOOL NETCON_init(WININET_NETCONNECTION *connnection, BOOL useSSL);
BOOL NETCON_create(WININET_NETCONNECTION *connection, int domain,
@ -406,7 +411,6 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len,
BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
int *recvd /* out */);
BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *available);
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer);
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection);
DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value);

View file

@ -23,6 +23,10 @@
#include "config.h"
#include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <sys/types.h>
#ifdef HAVE_POLL_H
#include <poll.h>
@ -33,10 +37,12 @@
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
@ -55,9 +61,6 @@
#undef FAR
#undef DSA
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#include <stdarg.h>
#include <stdlib.h>
@ -115,17 +118,18 @@ MAKE_FUNCPTR(SSL_connect);
MAKE_FUNCPTR(SSL_shutdown);
MAKE_FUNCPTR(SSL_write);
MAKE_FUNCPTR(SSL_read);
MAKE_FUNCPTR(SSL_pending);
MAKE_FUNCPTR(SSL_get_verify_result);
MAKE_FUNCPTR(SSL_get_peer_certificate);
MAKE_FUNCPTR(SSL_CTX_get_timeout);
MAKE_FUNCPTR(SSL_CTX_set_timeout);
MAKE_FUNCPTR(SSL_CTX_set_default_verify_paths);
MAKE_FUNCPTR(i2d_X509);
/* OpenSSL's libcrypto functions that we use */
MAKE_FUNCPTR(BIO_new_fp);
MAKE_FUNCPTR(ERR_get_error);
MAKE_FUNCPTR(ERR_error_string);
MAKE_FUNCPTR(i2d_X509);
#undef MAKE_FUNCPTR
#endif
@ -178,12 +182,12 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
DYNSSL(SSL_shutdown);
DYNSSL(SSL_write);
DYNSSL(SSL_read);
DYNSSL(SSL_pending);
DYNSSL(SSL_get_verify_result);
DYNSSL(SSL_get_peer_certificate);
DYNSSL(SSL_CTX_get_timeout);
DYNSSL(SSL_CTX_set_timeout);
DYNSSL(SSL_CTX_set_default_verify_paths);
DYNSSL(i2d_X509);
#undef DYNSSL
#define DYNCRYPTO(x) \
@ -197,6 +201,7 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
DYNCRYPTO(BIO_new_fp);
DYNCRYPTO(ERR_get_error);
DYNCRYPTO(ERR_error_string);
DYNCRYPTO(i2d_X509);
#undef DYNCRYPTO
pSSL_library_init();
@ -204,8 +209,6 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
pBIO_new_fp(stderr, BIO_NOCLOSE); /* FIXME: should use winedebug stuff */
meth = pSSLv23_method();
connection->peek_msg = NULL;
connection->peek_msg_mem = NULL;
#else
FIXME("can't use SSL, not compiled in.\n");
INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR);
@ -326,11 +329,6 @@ BOOL NETCON_close(WININET_NETCONNECTION *connection)
#ifdef SONAME_LIBSSL
if (connection->useSSL)
{
HeapFree(GetProcessHeap(),0,connection->peek_msg_mem);
connection->peek_msg = NULL;
connection->peek_msg_mem = NULL;
connection->peek_len = 0;
pSSL_shutdown(connection->ssl_s);
pSSL_free(connection->ssl_s);
connection->ssl_s = NULL;
@ -538,55 +536,8 @@ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int f
else
{
#ifdef SONAME_LIBSSL
if (flags & ~(MSG_PEEK|MSG_WAITALL))
FIXME("SSL_read does not support the following flag: %08x\n", flags);
/* this ugly hack is all for MSG_PEEK. eww gross */
if (flags & MSG_PEEK && !connection->peek_msg)
{
connection->peek_msg = connection->peek_msg_mem = HeapAlloc(GetProcessHeap(), 0, (sizeof(char) * len) + 1);
}
else if (flags & MSG_PEEK && connection->peek_msg)
{
if (len < connection->peek_len)
FIXME("buffer isn't big enough. Do the expect us to wrap?\n");
*recvd = min(len, connection->peek_len);
memcpy(buf, connection->peek_msg, *recvd);
return TRUE;
}
else if (connection->peek_msg)
{
*recvd = min(len, connection->peek_len);
memcpy(buf, connection->peek_msg, *recvd);
connection->peek_len -= *recvd;
connection->peek_msg += *recvd;
if (connection->peek_len == 0)
{
HeapFree(GetProcessHeap(), 0, connection->peek_msg_mem);
connection->peek_msg_mem = NULL;
connection->peek_msg = NULL;
}
/* check if we got enough data from the peek buffer */
if (!(flags & MSG_WAITALL) || (*recvd == len))
return TRUE;
/* otherwise, fall through */
}
*recvd += pSSL_read(connection->ssl_s, (char*)buf + *recvd, len - *recvd);
if (flags & MSG_PEEK) /* must copy stuff into buffer */
{
connection->peek_len = *recvd;
if (!*recvd)
{
HeapFree(GetProcessHeap(), 0, connection->peek_msg_mem);
connection->peek_msg_mem = NULL;
connection->peek_msg = NULL;
}
else
memcpy(connection->peek_msg, buf, *recvd);
}
if (*recvd < 1 && len)
return FALSE;
return TRUE;
*recvd = pSSL_read(connection->ssl_s, buf, len);
return *recvd > 0 || !len;
#else
return FALSE;
#endif
@ -604,13 +555,9 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail
if (!NETCON_connected(connection))
return FALSE;
#ifdef SONAME_LIBSSL
if (connection->peek_msg) *available = connection->peek_len;
#endif
#ifdef FIONREAD
if (!connection->useSSL)
{
#ifdef FIONREAD
int unread;
int retval = ioctlsocket(connection->socketFD, FIONREAD, &unread);
if (!retval)
@ -618,115 +565,17 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail
TRACE("%d bytes of queued, but unread data\n", unread);
*available += unread;
}
}
#endif
return TRUE;
}
/******************************************************************************
* NETCON_getNextLine
*/
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer)
{
TRACE("\n");
if (!NETCON_connected(connection)) return FALSE;
if (!connection->useSSL)
{
struct timeval tv;
fd_set infd;
BOOL bSuccess = FALSE;
DWORD nRecv = 0;
FD_ZERO(&infd);
FD_SET(connection->socketFD, &infd);
tv.tv_sec=RESPONSE_TIMEOUT;
tv.tv_usec=0;
while (nRecv < *dwBuffer)
{
if (select(connection->socketFD+1,&infd,NULL,NULL,&tv) > 0)
{
if (recv(connection->socketFD, &lpszBuffer[nRecv], 1, 0) <= 0)
{
INTERNET_SetLastError(sock_get_error(errno));
goto lend;
}
if (lpszBuffer[nRecv] == '\n')
{
bSuccess = TRUE;
break;
}
if (lpszBuffer[nRecv] != '\r')
nRecv++;
}
else
{
INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT);
goto lend;
}
}
lend: /* FIXME: don't use labels */
if (bSuccess)
{
lpszBuffer[nRecv++] = '\0';
*dwBuffer = nRecv;
TRACE(":%u %s\n", nRecv, lpszBuffer);
return TRUE;
}
else
{
return FALSE;
}
}
else
{
#ifdef SONAME_LIBSSL
long prev_timeout;
DWORD nRecv = 0;
BOOL success = TRUE;
prev_timeout = pSSL_CTX_get_timeout(ctx);
pSSL_CTX_set_timeout(ctx, RESPONSE_TIMEOUT);
while (nRecv < *dwBuffer)
{
int recv = 1;
if (!NETCON_recv(connection, &lpszBuffer[nRecv], 1, 0, &recv))
{
INTERNET_SetLastError(ERROR_CONNECTION_ABORTED);
success = FALSE;
}
if (lpszBuffer[nRecv] == '\n')
{
success = TRUE;
break;
}
if (lpszBuffer[nRecv] != '\r')
nRecv++;
}
pSSL_CTX_set_timeout(ctx, prev_timeout);
if (success)
{
lpszBuffer[nRecv++] = '\0';
*dwBuffer = nRecv;
TRACE("_SSL:%u %s\n", nRecv, lpszBuffer);
return TRUE;
}
return FALSE;
#else
return FALSE;
*available = pSSL_pending(connection->ssl_s);
#endif
}
return TRUE;
}
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection)
{
#ifdef SONAME_LIBSSL
@ -788,7 +637,7 @@ DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value
tv.tv_usec = (value % 1000) * 1000;
result = setsockopt(connection->socketFD, SOL_SOCKET,
send ? SO_SNDTIMEO : SO_RCVTIMEO, &tv,
send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv,
sizeof(tv));
if (result == -1)

View file

@ -692,6 +692,7 @@ static LPURLCACHE_HEADER URLCacheContainer_LockIndex(URLCACHECONTAINER * pContai
* of the memory mapped file */
if (pHeader->dwFileSize != pContainer->file_size)
{
UnmapViewOfFile( pHeader );
URLCacheContainer_CloseIndex(pContainer);
error = URLCacheContainer_OpenIndex(pContainer);
if (error != ERROR_SUCCESS)
@ -3623,10 +3624,26 @@ BOOL WINAPI IsUrlCacheEntryExpiredW( LPCWSTR url, DWORD dwFlags, FILETIME* pftLa
/***********************************************************************
* GetDiskInfoA (WININET.@)
*/
DWORD WINAPI GetDiskInfoA(void *p0, void *p1, void *p2, void *p3)
BOOL WINAPI GetDiskInfoA(PCSTR path, PDWORD cluster_size, PDWORDLONG free, PDWORDLONG total)
{
FIXME("(%p, %p, %p, %p)\n", p0, p1, p2, p3);
return 0;
BOOL ret;
ULARGE_INTEGER bytes_free, bytes_total;
TRACE("(%s, %p, %p, %p)\n", debugstr_a(path), cluster_size, free, total);
if (!path)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if ((ret = GetDiskFreeSpaceExA(path, NULL, &bytes_total, &bytes_free)))
{
if (cluster_size) *cluster_size = 1;
if (free) *free = bytes_free.QuadPart;
if (total) *total = bytes_total.QuadPart;
}
return ret;
}
/***********************************************************************
@ -3637,3 +3654,12 @@ DWORD WINAPI RegisterUrlCacheNotification(LPVOID a, DWORD b, DWORD c, DWORD d, D
FIXME("(%p %x %x %x %x %x)\n", a, b, c, d, e, f);
return 0;
}
/***********************************************************************
* IncrementUrlCacheHeaderData (WININET.@)
*/
BOOL WINAPI IncrementUrlCacheHeaderData(DWORD index, LPDWORD data)
{
FIXME("(%u, %p)\n", index, data);
return FALSE;
}

View file

@ -25,6 +25,10 @@
#include "config.h"
#include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@ -40,6 +44,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
#ifndef HAVE_GETADDRINFO
/* critical section to protect non-reentrant gethostbyname() */
static CRITICAL_SECTION cs_gethostbyname;
static CRITICAL_SECTION_DEBUG critsect_debug =
@ -50,6 +56,8 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
};
static CRITICAL_SECTION cs_gethostbyname = { &critsect_debug, -1, 0, 0, 0, 0 };
#endif
#define TIME_STRING_LEN 30
time_t ConvertTimeString(LPCWSTR asctime)
@ -142,7 +150,12 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
WCHAR *found;
char *name;
int len, sz;
#ifdef HAVE_GETADDRINFO
struct addrinfo *res, hints;
int ret;
#else
struct hostent *phe;
#endif
TRACE("%s\n", debugstr_w(lpszServerName));
@ -158,27 +171,45 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
len = strlenW(lpszServerName);
sz = WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, NULL, 0, NULL, NULL );
name = HeapAlloc(GetProcessHeap(), 0, sz+1);
if (!(name = HeapAlloc( GetProcessHeap(), 0, sz + 1 ))) return FALSE;
WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, name, sz, NULL, NULL );
name[sz] = 0;
#ifdef HAVE_GETADDRINFO
memset( &hints, 0, sizeof(struct addrinfo) );
hints.ai_family = AF_INET;
ret = getaddrinfo( name, NULL, &hints, &res );
HeapFree( GetProcessHeap(), 0, name );
if (ret != 0)
{
TRACE("failed to get address of %s (%s)\n", debugstr_w(lpszServerName), gai_strerror(ret));
return FALSE;
}
memset( psa, 0, sizeof(struct sockaddr_in) );
memcpy( &psa->sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, sizeof(struct in_addr) );
psa->sin_family = res->ai_family;
psa->sin_port = htons(nServerPort);
freeaddrinfo( res );
#else
EnterCriticalSection( &cs_gethostbyname );
phe = gethostbyname(name);
HeapFree( GetProcessHeap(), 0, name );
if (NULL == phe)
{
TRACE("Failed to get hostname: (%s)\n", debugstr_w(lpszServerName) );
TRACE("failed to get address of %s (%d)\n", debugstr_w(lpszServerName), h_errno);
LeaveCriticalSection( &cs_gethostbyname );
return FALSE;
}
memset(psa,0,sizeof(struct sockaddr_in));
memcpy((char *)&psa->sin_addr, phe->h_addr, phe->h_length);
psa->sin_family = phe->h_addrtype;
psa->sin_port = htons(nServerPort);
LeaveCriticalSection( &cs_gethostbyname );
#endif
return TRUE;
}

View file

@ -18,6 +18,7 @@
<library>secur32</library>
<library>crypt32</library>
<library>ws2_32</library>
<library>pseh</library>
<file>cookie.c</file>
<file>dialogs.c</file>
<file>ftp.c</file>

View file

@ -1,5 +1,5 @@
101 stub -noname DoConnectoidsExist
102 stub -noname GetDiskInfoA
102 stdcall -noname GetDiskInfoA(str ptr ptr ptr)
103 stub -noname PerformOperationOverUrlCacheA
104 stub -noname HttpCheckDavComplianceA
105 stub -noname HttpCheckDavComplianceW
@ -9,7 +9,7 @@
111 stub -noname ExportCookieFileW
112 stub -noname IsProfilesEnabled
116 stub -noname IsDomainlegalCookieDomainA
117 stub -noname IsDomainLegalCookieDomainW
117 stdcall -noname IsDomainLegalCookieDomainW(wstr wstr)
118 stub -noname FindP3PPolicySymbol
120 stub -noname MapResourceToPolicy
121 stub -noname GetP3PPolicy
@ -109,7 +109,7 @@
@ stdcall HttpSendRequestExA(long ptr ptr long long)
@ stdcall HttpSendRequestExW(long ptr ptr long long)
@ stdcall HttpSendRequestW(ptr wstr long ptr long)
@ stub IncrementUrlCacheHeaderData
@ stdcall IncrementUrlCacheHeaderData(long ptr)
@ stub InternetAlgIdToStringA
@ stub InternetAlgIdToStringW
@ stdcall InternetAttemptConnect(long)
@ -213,10 +213,10 @@
@ stdcall IsUrlCacheEntryExpiredW(wstr long ptr)
@ stub LoadUrlCacheContent
@ stub ParseX509EncodedCertificateForListBoxEntry
@ stub PrivacyGetZonePreferenceW # (long long ptr ptr ptr)
@ stub PrivacySetZonePreferenceW # (long long long wstr)
@ stdcall PrivacyGetZonePreferenceW(long long ptr ptr ptr)
@ stdcall PrivacySetZonePreferenceW(long long long wstr)
@ stdcall ReadUrlCacheEntryStream(ptr long ptr ptr long)
@ stub RegisterUrlCacheNotification
@ stdcall RegisterUrlCacheNotification(ptr long long long long long)
@ stdcall ResumeSuspendedDownload(long long)
@ stdcall RetrieveUrlCacheEntryFileA(str ptr ptr long)
@ stdcall RetrieveUrlCacheEntryFileW(wstr ptr ptr long)