- 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 "config.h"
#include "wine/port.h" #include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -48,7 +52,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet);
* Cookies are currently memory only. * Cookies are currently memory only.
* Cookies are NOT THREAD SAFE * Cookies are NOT THREAD SAFE
* Cookies could use A LOT OF MEMORY. We need some kind of memory management here! * 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; typedef struct _cookie_domain cookie_domain;
@ -62,7 +65,7 @@ struct _cookie
LPWSTR lpCookieName; LPWSTR lpCookieName;
LPWSTR lpCookieData; LPWSTR lpCookieData;
time_t expiry; /* FIXME: not used */ FILETIME expiry;
}; };
struct _cookie_domain struct _cookie_domain
@ -76,7 +79,7 @@ struct _cookie_domain
static struct list domain_list = LIST_INIT(domain_list); 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 cookie *COOKIE_findCookie(cookie_domain *domain, LPCWSTR lpszCookieName);
static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain); static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain);
static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path); 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 */ /* 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)); cookie *newCookie = HeapAlloc(GetProcessHeap(), 0, sizeof(cookie));
list_init(&newCookie->entry); list_init(&newCookie->entry);
newCookie->lpCookieName = NULL; newCookie->lpCookieName = NULL;
newCookie->lpCookieData = NULL; newCookie->lpCookieData = NULL;
newCookie->expiry = expiry;
if (name) 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) static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostNameLen, LPWSTR path, int pathLen)
{ {
URL_COMPONENTSW UrlComponents; URL_COMPONENTSW UrlComponents;
BOOL rc;
UrlComponents.lpszExtraInfo = NULL; UrlComponents.lpszExtraInfo = NULL;
UrlComponents.lpszPassword = NULL; UrlComponents.lpszPassword = NULL;
@ -191,7 +196,22 @@ static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostName
UrlComponents.dwHostNameLength = hostNameLen; UrlComponents.dwHostNameLength = hostNameLen;
UrlComponents.dwUrlPathLength = pathLen; 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 */ /* match a domain. domain must match if the domain is not NULL. path must match if the path is not NULL */
@ -215,11 +235,22 @@ static BOOL COOKIE_matchDomain(LPCWSTR lpszCookieDomain, LPCWSTR lpszCookiePath,
} }
if (lpszCookiePath) if (lpszCookiePath)
{ {
INT len;
TRACE("comparing paths: %s with %s\n", debugstr_w(lpszCookiePath), debugstr_w(searchDomain->lpCookiePath)); 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) if (!searchDomain->lpCookiePath)
return FALSE; 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 FALSE;
} }
return TRUE; return TRUE;
} }
@ -262,6 +293,7 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
struct list * cursor; struct list * cursor;
unsigned int cnt = 0, domain_count = 0, cookie_count = 0; unsigned int cnt = 0, domain_count = 0, cookie_count = 0;
WCHAR hostName[2048], path[2048]; WCHAR hostName[2048], path[2048];
FILETIME tm;
TRACE("(%s, %s, %p, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName), TRACE("(%s, %s, %p, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName),
lpCookieData, lpdwSize); 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])); ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0]));
if (!ret || !hostName[0]) return FALSE; if (!ret || !hostName[0]) return FALSE;
GetSystemTimeAsFileTime(&tm);
LIST_FOR_EACH(cursor, &domain_list) LIST_FOR_EACH(cursor, &domain_list)
{ {
cookie_domain *cookiesDomain = LIST_ENTRY(cursor, cookie_domain, entry); 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; struct list * cursor;
domain_count++; domain_count++;
@ -288,6 +322,14 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
LIST_FOR_EACH(cursor, &cookiesDomain->cookie_list) LIST_FOR_EACH(cursor, &cookiesDomain->cookie_list)
{ {
cookie *thisCookie = LIST_ENTRY(cursor, cookie, entry); 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 */ if (lpCookieData == NULL) /* return the size of the buffer required to lpdwSize */
{ {
unsigned int len; unsigned int len;
@ -405,27 +447,116 @@ static BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWST
cookie_domain *thisCookieDomain = NULL; cookie_domain *thisCookieDomain = NULL;
cookie *thisCookie; cookie *thisCookie;
struct list *cursor; 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) LIST_FOR_EACH(cursor, &domain_list)
{ {
thisCookieDomain = LIST_ENTRY(cursor, cookie_domain, entry); thisCookieDomain = LIST_ENTRY(cursor, cookie_domain, entry);
if (COOKIE_matchDomain(domain, NULL /* FIXME: path */, thisCookieDomain, FALSE)) if (COOKIE_matchDomain(domain, path, thisCookieDomain, FALSE))
break; break;
thisCookieDomain = NULL; thisCookieDomain = NULL;
} }
if (!thisCookieDomain) if (!thisCookieDomain)
thisCookieDomain = COOKIE_addDomain(domain, path); {
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))) if ((thisCookie = COOKIE_findCookie(thisCookieDomain, cookie_name)))
COOKIE_deleteCookie(thisCookie, FALSE); COOKIE_deleteCookie(thisCookie, FALSE);
TRACE("setting cookie %s=%s for domain %s\n", debugstr_w(cookie_name), TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_w(cookie_name),
debugstr_w(cookie_data), debugstr_w(thisCookieDomain->lpCookieDomain)); 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; return FALSE;
}
HeapFree(GetProcessHeap(),0,data);
if (value != data) HeapFree(GetProcessHeap(), 0, value);
return TRUE; return TRUE;
} }
@ -475,7 +606,7 @@ BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
* the cookie data in the form of name[=data]. * the cookie data in the form of name[=data].
*/ */
if (!(data = strchrW(cookie, '='))) data = cookie + len; if (!(data = strchrW(cookie, '='))) data = cookie + len;
else data++; else *data++ = 0;
ret = set_cookie(hostName, path, cookie, data); 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); FIXME("(%s, 0x%08x) stub\n", debugstr_w(pchHostName), dwDecision);
return FALSE; 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 "config.h"
#include "wine/port.h" #include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <stdarg.h> #include <stdarg.h>
#include "windef.h" #include "windef.h"

View file

@ -30,6 +30,10 @@
#include "config.h" #include "config.h"
#include "wine/port.h" #include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -42,6 +46,9 @@
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> # include <unistd.h>
#endif #endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
@ -90,7 +97,7 @@ typedef struct
BOOL bIsDirectory; BOOL bIsDirectory;
LPWSTR lpszName; LPWSTR lpszName;
DWORD nSize; DWORD nSize;
struct tm tmLastModified; SYSTEMTIME tmLastModified;
unsigned short permissions; unsigned short permissions;
} FILEPROPERTIESW, *LPFILEPROPERTIESW; } 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_FtpRenameFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszSrc, LPCWSTR lpszDest);
static BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory); static BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
static BOOL FTP_FtpDeleteFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName); 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, static BOOL FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags, BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
DWORD_PTR dwContext); DWORD_PTR dwContext);
@ -854,13 +859,13 @@ lend:
if (hFindNext) if (hFindNext)
{ {
iar.dwResult = (DWORD)hFindNext; iar.dwResult = (DWORD_PTR)hFindNext;
iar.dwError = ERROR_SUCCESS; iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED, SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
&iar, sizeof(INTERNET_ASYNC_RESULT)); &iar, sizeof(INTERNET_ASYNC_RESULT));
} }
iar.dwResult = (DWORD)hFindNext; iar.dwResult = (DWORD_PTR)hFindNext;
iar.dwError = hFindNext ? ERROR_SUCCESS : INTERNET_GetLastError(); iar.dwError = hFindNext ? ERROR_SUCCESS : INTERNET_GetLastError();
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT)); &iar, sizeof(INTERNET_ASYNC_RESULT));
@ -1071,6 +1076,268 @@ lend:
return bSuccess; 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.@) * 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.@) * FtpGetFileA (WININET.@)
* *
@ -2256,7 +2348,7 @@ HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
assert( hIC->hdr.htype == WH_HINIT ); assert( hIC->hdr.htype == WH_HINIT );
if (NULL == lpszUserName && NULL != lpszPassword) if ((!lpszUserName || !*lpszUserName) && lpszPassword && *lpszPassword)
{ {
INTERNET_SetLastError(ERROR_INVALID_PARAMETER); INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
goto lerror; goto lerror;
@ -2302,7 +2394,7 @@ HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
if(hIC->lpszProxyBypass) if(hIC->lpszProxyBypass)
FIXME("Proxy bypass is ignored.\n"); FIXME("Proxy bypass is ignored.\n");
} }
if ( !lpszUserName) { if (!lpszUserName || !strlenW(lpszUserName)) {
HKEY key; HKEY key;
WCHAR szPassword[MAX_PATH]; WCHAR szPassword[MAX_PATH];
DWORD len = sizeof(szPassword); DWORD len = sizeof(szPassword);
@ -2336,7 +2428,7 @@ HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
{ {
INTERNET_ASYNC_RESULT iar; INTERNET_ASYNC_RESULT iar;
iar.dwResult = (DWORD)handle; iar.dwResult = (DWORD_PTR)handle;
iar.dwError = ERROR_SUCCESS; iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&hIC->hdr, dwContext, SendAsyncCallback(&hIC->hdr, dwContext,
@ -2397,16 +2489,6 @@ lerror:
handle = NULL; 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; return handle;
} }
@ -2737,7 +2819,7 @@ static BOOL FTP_InitListenSocket(LPWININETFTPSESSIONW lpwfs)
lpwfs->lstnSocketAddress = lpwfs->socketAddress; lpwfs->lstnSocketAddress = lpwfs->socketAddress;
/* and get the system to assign us a port */ /* 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) 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); 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; WIN32_FIND_DATAW *find_data = data;
DWORD res = ERROR_SUCCESS; DWORD res = ERROR_SUCCESS;
@ -3308,6 +3390,7 @@ static const HANDLEHEADERVtbl FTPFINDNEXTVtbl = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
FTPFINDNEXT_FindNextFileW FTPFINDNEXT_FindNextFileW
}; };
@ -3382,9 +3465,7 @@ static BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFi
if (lpafp) if (lpafp)
{ {
/* Convert 'Unix' time to Windows time */ SystemTimeToFileTime( &lpafp->tmLastModified, &lpFindFileData->ftLastAccessTime );
RtlSecondsSince1970ToTime(mktime(&lpafp->tmLastModified),
(LARGE_INTEGER *) &(lpFindFileData->ftLastAccessTime));
lpFindFileData->ftLastWriteTime = lpFindFileData->ftLastAccessTime; lpFindFileData->ftLastWriteTime = lpFindFileData->ftLastAccessTime;
lpFindFileData->ftCreationTime = lpFindFileData->ftLastAccessTime; lpFindFileData->ftCreationTime = lpFindFileData->ftLastAccessTime;
@ -3452,12 +3533,12 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT
lpfp->nSize = atol(pszToken); lpfp->nSize = atol(pszToken);
} }
lpfp->tmLastModified.tm_sec = 0; lpfp->tmLastModified.wSecond = 0;
lpfp->tmLastModified.tm_min = 0; lpfp->tmLastModified.wMinute = 0;
lpfp->tmLastModified.tm_hour = 0; lpfp->tmLastModified.wHour = 0;
lpfp->tmLastModified.tm_mday = 0; lpfp->tmLastModified.wDay = 0;
lpfp->tmLastModified.tm_mon = 0; lpfp->tmLastModified.wMonth = 0;
lpfp->tmLastModified.tm_year = 0; lpfp->tmLastModified.wYear = 0;
/* Determine month */ /* Determine month */
pszToken = strtok(NULL, szSpace); pszToken = strtok(NULL, szSpace);
@ -3465,34 +3546,31 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT
if(strlen(pszToken) >= 3) { if(strlen(pszToken) >= 3) {
pszToken[3] = 0; pszToken[3] = 0;
if((pszTmp = StrStrIA(szMonths, pszToken))) if((pszTmp = StrStrIA(szMonths, pszToken)))
lpfp->tmLastModified.tm_mon = ((pszTmp - szMonths) / 3)+1; lpfp->tmLastModified.wMonth = ((pszTmp - szMonths) / 3)+1;
} }
/* Determine day */ /* Determine day */
pszToken = strtok(NULL, szSpace); pszToken = strtok(NULL, szSpace);
if(!pszToken) continue; if(!pszToken) continue;
lpfp->tmLastModified.tm_mday = atoi(pszToken); lpfp->tmLastModified.wDay = atoi(pszToken);
/* Determine time or year */ /* Determine time or year */
pszToken = strtok(NULL, szSpace); pszToken = strtok(NULL, szSpace);
if(!pszToken) continue; if(!pszToken) continue;
if((pszTmp = strchr(pszToken, ':'))) { if((pszTmp = strchr(pszToken, ':'))) {
struct tm* apTM; SYSTEMTIME curr_time;
time_t aTime;
*pszTmp = 0; *pszTmp = 0;
pszTmp++; pszTmp++;
lpfp->tmLastModified.tm_min = atoi(pszTmp); lpfp->tmLastModified.wMinute = atoi(pszTmp);
lpfp->tmLastModified.tm_hour = atoi(pszToken); lpfp->tmLastModified.wHour = atoi(pszToken);
time(&aTime); GetLocalTime( &curr_time );
apTM = localtime(&aTime); lpfp->tmLastModified.wYear = curr_time.wYear;
lpfp->tmLastModified.tm_year = apTM->tm_year;
} }
else { else {
lpfp->tmLastModified.tm_year = atoi(pszToken) - 1900; lpfp->tmLastModified.wYear = atoi(pszToken);
lpfp->tmLastModified.tm_hour = 12; lpfp->tmLastModified.wHour = 12;
} }
TRACE("Mod time: %02d:%02d:%02d %02d/%02d/%02d\n", TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n",
lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.tm_min, lpfp->tmLastModified.tm_sec, lpfp->tmLastModified.wHour, lpfp->tmLastModified.wMinute, lpfp->tmLastModified.wSecond,
(lpfp->tmLastModified.tm_year >= 100) ? lpfp->tmLastModified.tm_year - 100 : lpfp->tmLastModified.tm_year, lpfp->tmLastModified.wYear, lpfp->tmLastModified.wMonth, lpfp->tmLastModified.wDay);
lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.tm_mday);
pszToken = strtok(NULL, szSpace); pszToken = strtok(NULL, szSpace);
if(!pszToken) continue; 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 05-09-03 06:02PM 12656686 2003-04-21bgm_cmd_e.rgz
*/ */
else if(isdigit(pszToken[0]) && 8 == strlen(pszToken)) { else if(isdigit(pszToken[0]) && 8 == strlen(pszToken)) {
int mon, mday, year, hour, min;
lpfp->permissions = 0xFFFF; /* No idea, put full permission :-) */ lpfp->permissions = 0xFFFF; /* No idea, put full permission :-) */
sscanf(pszToken, "%d-%d-%d", sscanf(pszToken, "%d-%d-%d", &mon, &mday, &year);
&lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.wDay = mday;
&lpfp->tmLastModified.tm_mday, lpfp->tmLastModified.wMonth = mon;
&lpfp->tmLastModified.tm_year); lpfp->tmLastModified.wYear = year;
/* Hacky and bad Y2K protection :-) */ /* Hacky and bad Y2K protection :-) */
if (lpfp->tmLastModified.tm_year < 70) if (lpfp->tmLastModified.wYear < 70) lpfp->tmLastModified.wYear += 2000;
lpfp->tmLastModified.tm_year += 100;
pszToken = strtok(NULL, szSpace); pszToken = strtok(NULL, szSpace);
if(!pszToken) continue; if(!pszToken) continue;
sscanf(pszToken, "%d:%d", sscanf(pszToken, "%d:%d", &hour, &min);
&lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.wHour = hour;
&lpfp->tmLastModified.tm_min); lpfp->tmLastModified.wMinute = min;
if((pszToken[5] == 'P') && (pszToken[6] == 'M')) { 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", TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n",
lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.tm_min, lpfp->tmLastModified.tm_sec, lpfp->tmLastModified.wHour, lpfp->tmLastModified.wMinute, lpfp->tmLastModified.wSecond,
(lpfp->tmLastModified.tm_year >= 100) ? lpfp->tmLastModified.tm_year - 100 : lpfp->tmLastModified.tm_year, lpfp->tmLastModified.wYear, lpfp->tmLastModified.wMonth, lpfp->tmLastModified.wDay);
lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.tm_mday);
pszToken = strtok(NULL, szSpace); pszToken = strtok(NULL, szSpace);
if(!pszToken) continue; 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 */ #define MAXHOSTNAME 100 /* from http.c */
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -113,7 +117,7 @@ HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info )
{ {
num = HANDLE_CHUNK_SIZE; num = HANDLE_CHUNK_SIZE;
p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof (UINT)* num); sizeof (*WININET_Handles)* num);
if( !p ) if( !p )
goto end; goto end;
WININET_Handles = p; WININET_Handles = p;
@ -123,7 +127,7 @@ HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info )
{ {
num = WININET_dwMaxHandles + HANDLE_CHUNK_SIZE; num = WININET_dwMaxHandles + HANDLE_CHUNK_SIZE;
p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
WININET_Handles, sizeof (UINT)* num); WININET_Handles, sizeof (*WININET_Handles)* num);
if( !p ) if( !p )
goto end; goto end;
WININET_Handles = p; WININET_Handles = p;
@ -182,7 +186,8 @@ BOOL WININET_Release( LPWININETHANDLEHEADER info )
info->vtbl->CloseConnection( info ); info->vtbl->CloseConnection( info );
} }
/* Don't send a callback if this is a session handle created with InternetOpenUrl */ /* 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_SendCallback(info, info->dwContext,
INTERNET_STATUS_HANDLE_CLOSING, &info->hInternet, 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)); TRACE("http proxy (from environment) = %s\n", debugstr_w(lpwai->lpszProxy));
enabled = 1; 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 ); RegCloseKey( key );
return (enabled > 0); return (enabled > 0);
} }
@ -459,7 +467,7 @@ static void dump_INTERNET_FLAGS(DWORD dwFlags)
FE(INTERNET_FLAG_TRANSFER_BINARY) FE(INTERNET_FLAG_TRANSFER_BINARY)
}; };
#undef FE #undef FE
int i; unsigned int i;
for (i = 0; i < (sizeof(flag) / sizeof(flag[0])); i++) { for (i = 0; i < (sizeof(flag) / sizeof(flag[0])); i++) {
if (flag[i].val & dwFlags) { if (flag[i].val & dwFlags) {
@ -543,8 +551,10 @@ static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b
if (ai->lpszProxyBypass) if (ai->lpszProxyBypass)
proxyBypassBytesRequired = (lstrlenW(ai->lpszProxyBypass) + 1) * sizeof(WCHAR); proxyBypassBytesRequired = (lstrlenW(ai->lpszProxyBypass) + 1) * sizeof(WCHAR);
if (*size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired) if (*size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired)
return ERROR_INSUFFICIENT_BUFFER; {
*size = sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired;
return ERROR_INSUFFICIENT_BUFFER;
}
proxy = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW)); proxy = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW));
proxy_bypass = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired); 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, proxyBypassBytesRequired = WideCharToMultiByte(CP_ACP, 0, ai->lpszProxyBypass, -1,
NULL, 0, NULL, NULL); NULL, 0, NULL, NULL);
if (*size < sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired) if (*size < sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired)
{
*size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired;
return ERROR_INSUFFICIENT_BUFFER; return ERROR_INSUFFICIENT_BUFFER;
}
proxy = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA)); proxy = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA));
proxy_bypass = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired); 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, BOOL WINAPI InternetGetLastResponseInfoA(LPDWORD lpdwError,
LPSTR lpszBuffer, LPDWORD lpdwBufferLength) LPSTR lpszBuffer, LPDWORD lpdwBufferLength)
{ {
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
TRACE("\n"); TRACE("\n");
@ -816,7 +828,7 @@ BOOL WINAPI InternetGetLastResponseInfoA(LPDWORD lpdwError,
BOOL WINAPI InternetGetLastResponseInfoW(LPDWORD lpdwError, BOOL WINAPI InternetGetLastResponseInfoW(LPDWORD lpdwError,
LPWSTR lpszBuffer, LPDWORD lpdwBufferLength) LPWSTR lpszBuffer, LPDWORD lpdwBufferLength)
{ {
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
TRACE("\n"); TRACE("\n");
@ -856,7 +868,7 @@ BOOL WINAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved)
TRACE("(%p, 0x%08x)\n", lpdwStatus, dwReserved); TRACE("(%p, 0x%08x)\n", lpdwStatus, dwReserved);
if (lpdwStatus) { if (lpdwStatus) {
FIXME("always returning LAN connection.\n"); WARN("always returning LAN connection.\n");
*lpdwStatus = INTERNET_CONNECTION_LAN; *lpdwStatus = INTERNET_CONNECTION_LAN;
} }
return TRUE; return TRUE;
@ -900,7 +912,7 @@ BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnecti
return FALSE; return FALSE;
if (lpdwStatus) { if (lpdwStatus) {
FIXME("always returning LAN connection.\n"); WARN("always returning LAN connection.\n");
*lpdwStatus = INTERNET_CONNECTION_LAN; *lpdwStatus = INTERNET_CONNECTION_LAN;
} }
return LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen); return LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen);
@ -1813,7 +1825,7 @@ INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackA(
INTERNET_STATUS_CALLBACK retVal; INTERNET_STATUS_CALLBACK retVal;
LPWININETHANDLEHEADER lpwh; LPWININETHANDLEHEADER lpwh;
TRACE("0x%08x\n", (ULONG)hInternet); TRACE("%p\n", hInternet);
if (!(lpwh = WININET_GetObject(hInternet))) if (!(lpwh = WININET_GetObject(hInternet)))
return INTERNET_INVALID_STATUS_CALLBACK; return INTERNET_INVALID_STATUS_CALLBACK;
@ -1841,7 +1853,7 @@ INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW(
INTERNET_STATUS_CALLBACK retVal; INTERNET_STATUS_CALLBACK retVal;
LPWININETHANDLEHEADER lpwh; LPWININETHANDLEHEADER lpwh;
TRACE("0x%08x\n", (ULONG)hInternet); TRACE("%p\n", hInternet);
if (!(lpwh = WININET_GetObject(hInternet))) if (!(lpwh = WININET_GetObject(hInternet)))
return INTERNET_INVALID_STATUS_CALLBACK; return INTERNET_INVALID_STATUS_CALLBACK;
@ -1994,33 +2006,40 @@ BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOu
/*********************************************************************** /***********************************************************************
* InternetReadFileExW (WININET.@) * InternetReadFileExW (WININET.@)
* * SEE
* Read data from an open internet file. * InternetReadFileExA()
*
* 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).
*
*/ */
BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer, BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer,
DWORD dwFlags, DWORD_PTR dwContext) 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);
return FALSE;
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) DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode)
{ {
static BOOL warn = TRUE;
switch(option) { switch(option) {
case INTERNET_OPTION_REQUEST_FLAGS: case INTERNET_OPTION_REQUEST_FLAGS:
TRACE("INTERNET_OPTION_REQUEST_FLAGS\n"); TRACE("INTERNET_OPTION_REQUEST_FLAGS\n");
@ -2047,8 +2066,11 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode)
return ERROR_SUCCESS; return ERROR_SUCCESS;
case INTERNET_OPTION_CONNECTED_STATE: 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)) if (*size < sizeof(ULONG))
return ERROR_INSUFFICIENT_BUFFER; 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_TIME:
case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL: case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
FIXME("Unhandled dwOption %d\n", option->dwOption); FIXME("Unhandled dwOption %d\n", option->dwOption);
option->Value.dwValue = 0; memset(&option->Value, 0, sizeof(option->Value));
res = ERROR_INVALID_PARAMETER;
break; break;
default: default:
@ -2256,9 +2277,14 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
{ {
case INTERNET_OPTION_CALLBACK: case INTERNET_OPTION_CALLBACK:
{ {
INTERNET_STATUS_CALLBACK callback = *(INTERNET_STATUS_CALLBACK *)lpBuffer; if (!lpwhh)
ret = (set_status_callback(lpwhh, callback, TRUE) != INTERNET_INVALID_STATUS_CALLBACK); {
break; 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: case INTERNET_OPTION_HTTP_VERSION:
{ {
@ -2342,8 +2368,35 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
case INTERNET_OPTION_DISABLE_AUTODIAL: case INTERNET_OPTION_DISABLE_AUTODIAL:
FIXME("Option INTERNET_OPTION_DISABLE_AUTODIAL; STUB\n"); FIXME("Option INTERNET_OPTION_DISABLE_AUTODIAL; STUB\n");
break; break;
case 86: case INTERNET_OPTION_HTTP_DECODING:
FIXME("86\n"); 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; break;
default: default:
FIXME("Option %d STUB\n",dwOption); FIXME("Option %d STUB\n",dwOption);
@ -2381,12 +2434,15 @@ BOOL WINAPI InternetSetOptionA(HINTERNET hInternet, DWORD dwOption,
case INTERNET_OPTION_CALLBACK: case INTERNET_OPTION_CALLBACK:
{ {
LPWININETHANDLEHEADER lpwh; LPWININETHANDLEHEADER lpwh;
INTERNET_STATUS_CALLBACK callback = *(INTERNET_STATUS_CALLBACK *)lpBuffer;
if (!(lpwh = WININET_GetObject(hInternet))) return FALSE; if (!(lpwh = WININET_GetObject(hInternet)))
r = (set_status_callback(lpwh, callback, FALSE) != INTERNET_INVALID_STATUS_CALLBACK); {
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE;
}
WININET_Release(lpwh); WININET_Release(lpwh);
return r; INTERNET_SetLastError(ERROR_INTERNET_OPTION_NOT_SETTABLE);
return FALSE;
} }
case INTERNET_OPTION_PROXY: 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 ); 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) ); ret = InternetTimeFromSystemTimeW( time, format, stringW, sizeof(stringW) );
if (ret) WideCharToMultiByte( CP_ACP, 0, stringW, -1, string, size, NULL, NULL ); 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 ); TRACE( "%p 0x%08x %p 0x%08x\n", time, format, string, size );
if (!time || !string) return FALSE; if (!time || !string || format != INTERNET_RFC1123_FORMAT)
{
if (format != INTERNET_RFC1123_FORMAT || size < INTERNET_RFC1123_BUFSIZE * sizeof(WCHAR)) SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
}
if (size < INTERNET_RFC1123_BUFSIZE * sizeof(*string))
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
sprintfW( string, date, sprintfW( string, date,
WININET_wkday[time->wDayOfWeek], WININET_wkday[time->wDayOfWeek],
@ -2805,6 +2880,8 @@ static HINTERNET INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUr
else else
urlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT; 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 */ /* FIXME: should use pointers, not handles, as handles are not thread-safe */
client = HTTP_Connect(hIC, hostName, urlComponents.nPort, client = HTTP_Connect(hIC, hostName, urlComponents.nPort,
userName, password, dwFlags, dwContext, INET_OPENURL); userName, password, dwFlags, dwContext, INET_OPENURL);
@ -3010,7 +3087,7 @@ static LPWITHREADERROR INTERNET_AllocThreadError(void)
*/ */
void INTERNET_SetLastError(DWORD dwError) void INTERNET_SetLastError(DWORD dwError)
{ {
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
if (!lpwite) if (!lpwite)
lpwite = INTERNET_AllocThreadError(); lpwite = INTERNET_AllocThreadError();
@ -3031,7 +3108,7 @@ void INTERNET_SetLastError(DWORD dwError)
*/ */
DWORD INTERNET_GetLastError(void) DWORD INTERNET_GetLastError(void)
{ {
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
if (!lpwite) return 0; if (!lpwite) return 0;
/* TlsGetValue clears last error, so set it again here */ /* TlsGetValue clears last error, so set it again here */
SetLastError(lpwite->dwError); SetLastError(lpwite->dwError);
@ -3104,7 +3181,7 @@ BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest)
*/ */
LPSTR INTERNET_GetResponseBuffer(void) LPSTR INTERNET_GetResponseBuffer(void)
{ {
LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex);
if (!lpwite) if (!lpwite)
lpwite = INTERNET_AllocThreadError(); lpwite = INTERNET_AllocThreadError();
TRACE("\n"); TRACE("\n");
@ -3451,6 +3528,9 @@ static BOOL calc_url_length(LPURL_COMPONENTSW lpUrlComponents,
if (lpUrlComponents->lpszUrlPath) if (lpUrlComponents->lpszUrlPath)
*lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath); *lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath);
if (lpUrlComponents->lpszExtraInfo)
*lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, ExtraInfo);
return TRUE; return TRUE;
} }
@ -3699,7 +3779,6 @@ BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags,
} }
} }
if (lpUrlComponents->lpszUrlPath) if (lpUrlComponents->lpszUrlPath)
{ {
dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath); dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath);
@ -3707,6 +3786,13 @@ BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags,
lpszUrl += dwLen; lpszUrl += dwLen;
} }
if (lpUrlComponents->lpszExtraInfo)
{
dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, ExtraInfo);
memcpy(lpszUrl, lpUrlComponents->lpszExtraInfo, dwLen * sizeof(WCHAR));
lpszUrl += dwLen;
}
*lpszUrl = '\0'; *lpszUrl = '\0';
return TRUE; return TRUE;
@ -3732,6 +3818,25 @@ DWORD WINAPI InternetConfirmZoneCrossingW( HWND hWnd, LPWSTR szUrlPrev, LPWSTR s
return ERROR_SUCCESS; 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 WINAPI InternetDialA( HWND hwndParent, LPSTR lpszConnectoid, DWORD dwFlags,
DWORD_PTR* lpdwConnection, DWORD dwReserved ) DWORD_PTR* lpdwConnection, DWORD dwReserved )
{ {

View file

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

View file

@ -23,6 +23,10 @@
#include "config.h" #include "config.h"
#include "wine/port.h" #include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_POLL_H #ifdef HAVE_POLL_H
#include <poll.h> #include <poll.h>
@ -33,10 +37,12 @@
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
# include <sys/time.h> # include <sys/time.h>
#endif #endif
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h> # include <sys/socket.h>
#endif #endif
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> # include <unistd.h>
#endif #endif
@ -55,9 +61,6 @@
#undef FAR #undef FAR
#undef DSA #undef DSA
#endif #endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
@ -115,17 +118,18 @@ MAKE_FUNCPTR(SSL_connect);
MAKE_FUNCPTR(SSL_shutdown); MAKE_FUNCPTR(SSL_shutdown);
MAKE_FUNCPTR(SSL_write); MAKE_FUNCPTR(SSL_write);
MAKE_FUNCPTR(SSL_read); MAKE_FUNCPTR(SSL_read);
MAKE_FUNCPTR(SSL_pending);
MAKE_FUNCPTR(SSL_get_verify_result); MAKE_FUNCPTR(SSL_get_verify_result);
MAKE_FUNCPTR(SSL_get_peer_certificate); MAKE_FUNCPTR(SSL_get_peer_certificate);
MAKE_FUNCPTR(SSL_CTX_get_timeout); MAKE_FUNCPTR(SSL_CTX_get_timeout);
MAKE_FUNCPTR(SSL_CTX_set_timeout); MAKE_FUNCPTR(SSL_CTX_set_timeout);
MAKE_FUNCPTR(SSL_CTX_set_default_verify_paths); MAKE_FUNCPTR(SSL_CTX_set_default_verify_paths);
MAKE_FUNCPTR(i2d_X509);
/* OpenSSL's libcrypto functions that we use */ /* OpenSSL's libcrypto functions that we use */
MAKE_FUNCPTR(BIO_new_fp); MAKE_FUNCPTR(BIO_new_fp);
MAKE_FUNCPTR(ERR_get_error); MAKE_FUNCPTR(ERR_get_error);
MAKE_FUNCPTR(ERR_error_string); MAKE_FUNCPTR(ERR_error_string);
MAKE_FUNCPTR(i2d_X509);
#undef MAKE_FUNCPTR #undef MAKE_FUNCPTR
#endif #endif
@ -178,12 +182,12 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
DYNSSL(SSL_shutdown); DYNSSL(SSL_shutdown);
DYNSSL(SSL_write); DYNSSL(SSL_write);
DYNSSL(SSL_read); DYNSSL(SSL_read);
DYNSSL(SSL_pending);
DYNSSL(SSL_get_verify_result); DYNSSL(SSL_get_verify_result);
DYNSSL(SSL_get_peer_certificate); DYNSSL(SSL_get_peer_certificate);
DYNSSL(SSL_CTX_get_timeout); DYNSSL(SSL_CTX_get_timeout);
DYNSSL(SSL_CTX_set_timeout); DYNSSL(SSL_CTX_set_timeout);
DYNSSL(SSL_CTX_set_default_verify_paths); DYNSSL(SSL_CTX_set_default_verify_paths);
DYNSSL(i2d_X509);
#undef DYNSSL #undef DYNSSL
#define DYNCRYPTO(x) \ #define DYNCRYPTO(x) \
@ -197,6 +201,7 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
DYNCRYPTO(BIO_new_fp); DYNCRYPTO(BIO_new_fp);
DYNCRYPTO(ERR_get_error); DYNCRYPTO(ERR_get_error);
DYNCRYPTO(ERR_error_string); DYNCRYPTO(ERR_error_string);
DYNCRYPTO(i2d_X509);
#undef DYNCRYPTO #undef DYNCRYPTO
pSSL_library_init(); 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 */ pBIO_new_fp(stderr, BIO_NOCLOSE); /* FIXME: should use winedebug stuff */
meth = pSSLv23_method(); meth = pSSLv23_method();
connection->peek_msg = NULL;
connection->peek_msg_mem = NULL;
#else #else
FIXME("can't use SSL, not compiled in.\n"); FIXME("can't use SSL, not compiled in.\n");
INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR); INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR);
@ -326,11 +329,6 @@ BOOL NETCON_close(WININET_NETCONNECTION *connection)
#ifdef SONAME_LIBSSL #ifdef SONAME_LIBSSL
if (connection->useSSL) 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_shutdown(connection->ssl_s);
pSSL_free(connection->ssl_s); pSSL_free(connection->ssl_s);
connection->ssl_s = NULL; connection->ssl_s = NULL;
@ -538,55 +536,8 @@ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int f
else else
{ {
#ifdef SONAME_LIBSSL #ifdef SONAME_LIBSSL
if (flags & ~(MSG_PEEK|MSG_WAITALL)) *recvd = pSSL_read(connection->ssl_s, buf, len);
FIXME("SSL_read does not support the following flag: %08x\n", flags); return *recvd > 0 || !len;
/* 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;
#else #else
return FALSE; return FALSE;
#endif #endif
@ -604,13 +555,9 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail
if (!NETCON_connected(connection)) if (!NETCON_connected(connection))
return FALSE; return FALSE;
#ifdef SONAME_LIBSSL
if (connection->peek_msg) *available = connection->peek_len;
#endif
#ifdef FIONREAD
if (!connection->useSSL) if (!connection->useSSL)
{ {
#ifdef FIONREAD
int unread; int unread;
int retval = ioctlsocket(connection->socketFD, FIONREAD, &unread); int retval = ioctlsocket(connection->socketFD, FIONREAD, &unread);
if (!retval) 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); TRACE("%d bytes of queued, but unread data\n", unread);
*available += unread; *available += unread;
} }
}
#endif #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 else
{ {
#ifdef SONAME_LIBSSL #ifdef SONAME_LIBSSL
long prev_timeout; *available = pSSL_pending(connection->ssl_s);
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;
#endif #endif
} }
return TRUE;
} }
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection) LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection)
{ {
#ifdef SONAME_LIBSSL #ifdef SONAME_LIBSSL
@ -788,7 +637,7 @@ DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value
tv.tv_usec = (value % 1000) * 1000; tv.tv_usec = (value % 1000) * 1000;
result = setsockopt(connection->socketFD, SOL_SOCKET, result = setsockopt(connection->socketFD, SOL_SOCKET,
send ? SO_SNDTIMEO : SO_RCVTIMEO, &tv, send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv,
sizeof(tv)); sizeof(tv));
if (result == -1) if (result == -1)

View file

@ -692,6 +692,7 @@ static LPURLCACHE_HEADER URLCacheContainer_LockIndex(URLCACHECONTAINER * pContai
* of the memory mapped file */ * of the memory mapped file */
if (pHeader->dwFileSize != pContainer->file_size) if (pHeader->dwFileSize != pContainer->file_size)
{ {
UnmapViewOfFile( pHeader );
URLCacheContainer_CloseIndex(pContainer); URLCacheContainer_CloseIndex(pContainer);
error = URLCacheContainer_OpenIndex(pContainer); error = URLCacheContainer_OpenIndex(pContainer);
if (error != ERROR_SUCCESS) if (error != ERROR_SUCCESS)
@ -3623,10 +3624,26 @@ BOOL WINAPI IsUrlCacheEntryExpiredW( LPCWSTR url, DWORD dwFlags, FILETIME* pftLa
/*********************************************************************** /***********************************************************************
* GetDiskInfoA (WININET.@) * 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); BOOL ret;
return 0; 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); FIXME("(%p %x %x %x %x %x)\n", a, b, c, d, e, f);
return 0; 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 "config.h"
#include "wine/port.h" #include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -40,6 +44,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(wininet); WINE_DEFAULT_DEBUG_CHANNEL(wininet);
#ifndef HAVE_GETADDRINFO
/* critical section to protect non-reentrant gethostbyname() */ /* critical section to protect non-reentrant gethostbyname() */
static CRITICAL_SECTION cs_gethostbyname; static CRITICAL_SECTION cs_gethostbyname;
static CRITICAL_SECTION_DEBUG critsect_debug = 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 }; static CRITICAL_SECTION cs_gethostbyname = { &critsect_debug, -1, 0, 0, 0, 0 };
#endif
#define TIME_STRING_LEN 30 #define TIME_STRING_LEN 30
time_t ConvertTimeString(LPCWSTR asctime) time_t ConvertTimeString(LPCWSTR asctime)
@ -142,7 +150,12 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
WCHAR *found; WCHAR *found;
char *name; char *name;
int len, sz; int len, sz;
#ifdef HAVE_GETADDRINFO
struct addrinfo *res, hints;
int ret;
#else
struct hostent *phe; struct hostent *phe;
#endif
TRACE("%s\n", debugstr_w(lpszServerName)); TRACE("%s\n", debugstr_w(lpszServerName));
@ -158,27 +171,45 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
len = strlenW(lpszServerName); len = strlenW(lpszServerName);
sz = WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, NULL, 0, NULL, NULL ); 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 ); WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, name, sz, NULL, NULL );
name[sz] = 0; 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 ); EnterCriticalSection( &cs_gethostbyname );
phe = gethostbyname(name); phe = gethostbyname(name);
HeapFree( GetProcessHeap(), 0, name ); HeapFree( GetProcessHeap(), 0, name );
if (NULL == phe) 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 ); LeaveCriticalSection( &cs_gethostbyname );
return FALSE; return FALSE;
} }
memset(psa,0,sizeof(struct sockaddr_in)); memset(psa,0,sizeof(struct sockaddr_in));
memcpy((char *)&psa->sin_addr, phe->h_addr, phe->h_length); memcpy((char *)&psa->sin_addr, phe->h_addr, phe->h_length);
psa->sin_family = phe->h_addrtype; psa->sin_family = phe->h_addrtype;
psa->sin_port = htons(nServerPort); psa->sin_port = htons(nServerPort);
LeaveCriticalSection( &cs_gethostbyname ); LeaveCriticalSection( &cs_gethostbyname );
#endif
return TRUE; return TRUE;
} }

View file

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

View file

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