} proxyinfo_t;
static ULONG max_conns = 2, max_1_0_conns = 4;
+static ULONG connect_timeout = 60000;
static const WCHAR szInternetSettings[] =
{ 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
break;
case DLL_PROCESS_DETACH:
- collect_connections(TRUE);
+ collect_connections(COLLECT_CLEANUP);
NETCON_unload();
- URLCacheContainers_DeleteAll();
+ free_urlcache();
+ free_cookie();
if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES)
{
/* It wasn't found: look for no protocol */
for (ptr = szProxy; !ret && ptr && *ptr; )
{
- LPCWSTR end, equal;
+ LPCWSTR end;
if (!(end = strchrW(ptr, ' ')))
end = ptr + strlenW(ptr);
- if (!(equal = strchrW(ptr, '=')))
+ if (!strchrW(ptr, '='))
{
if (end - ptr + 1 > *foundProxyLen)
{
proxyBytesRequired = (lstrlenW(ai->proxy) + 1) * sizeof(WCHAR);
if (ai->proxyBypass)
proxyBypassBytesRequired = (lstrlenW(ai->proxyBypass) + 1) * sizeof(WCHAR);
- if (*size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired)
+ if (!pi || *size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired)
{
*size = sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired;
return ERROR_INSUFFICIENT_BUFFER;
if (ai->proxyBypass)
proxyBypassBytesRequired = WideCharToMultiByte(CP_ACP, 0, ai->proxyBypass, -1,
NULL, 0, NULL, NULL);
- if (*size < sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired)
+ if (!pi || *size < sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired)
{
*size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired;
return ERROR_INSUFFICIENT_BUFFER;
*size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired;
return ERROR_SUCCESS;
}
+
+ case INTERNET_OPTION_CONNECT_TIMEOUT:
+ TRACE("INTERNET_OPTION_CONNECT_TIMEOUT\n");
+
+ if (*size < sizeof(ULONG))
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *(ULONG*)buffer = ai->connect_timeout;
+ *size = sizeof(ULONG);
+
+ return ERROR_SUCCESS;
}
return INET_QueryOption(hdr, option, buffer, size, unicode);
}
+static DWORD APPINFO_SetOption(object_header_t *hdr, DWORD option, void *buf, DWORD size)
+{
+ appinfo_t *ai = (appinfo_t*)hdr;
+
+ switch(option) {
+ case INTERNET_OPTION_CONNECT_TIMEOUT:
+ TRACE("INTERNET_OPTION_CONNECT_TIMEOUT\n");
+
+ if(size != sizeof(connect_timeout))
+ return ERROR_INTERNET_BAD_OPTION_LENGTH;
+ if(!*(ULONG*)buf)
+ return ERROR_BAD_ARGUMENTS;
+
+ ai->connect_timeout = *(ULONG*)buf;
+ return ERROR_SUCCESS;
+ case INTERNET_OPTION_USER_AGENT:
+ heap_free(ai->agent);
+ if (!(ai->agent = heap_strdupW(buf))) return ERROR_OUTOFMEMORY;
+ return ERROR_SUCCESS;
+ }
+
+ return INET_SetOption(hdr, option, buf, size);
+}
+
static const object_vtbl_t APPINFOVtbl = {
APPINFO_Destroy,
NULL,
APPINFO_QueryOption,
- INET_SetOption,
- NULL,
+ APPINFO_SetOption,
NULL,
NULL,
NULL,
lpwai->accessType = dwAccessType;
lpwai->proxyUsername = NULL;
lpwai->proxyPassword = NULL;
+ lpwai->connect_timeout = connect_timeout;
lpwai->agent = heap_strdupW(lpszAgent);
if(dwAccessType == INTERNET_OPEN_TYPE_PRECONFIG)
HINTERNET rc = NULL;
DWORD res = ERROR_SUCCESS;
- TRACE("(%p, %s, %i, %s, %s, %i, %i, %lx)\n", hInternet, debugstr_w(lpszServerName),
+ TRACE("(%p, %s, %i, %s, %s, %i, %x, %lx)\n", hInternet, debugstr_w(lpszServerName),
nServerPort, debugstr_w(lpszUserName), debugstr_w(lpszPassword),
dwService, dwFlags, dwContext);
*
*/
LPCWSTR lpszParam = NULL;
- BOOL bIsAbsolute = FALSE;
+ BOOL found_colon = FALSE;
LPCWSTR lpszap, lpszUrl = lpszUrl_orig;
- LPCWSTR lpszcp = NULL;
+ LPCWSTR lpszcp = NULL, lpszNetLoc;
LPWSTR lpszUrl_decode = NULL;
DWORD dwUrlLength = dwUrlLength_orig;
lpszap++;
continue;
}
- if ((*lpszap == ':') && (lpszap - lpszUrl >= 2))
+ if (*lpszap == ':')
{
- bIsAbsolute = TRUE;
+ found_colon = TRUE;
lpszcp = lpszap;
}
else
break;
}
+ if(!found_colon){
+ SetLastError(ERROR_INTERNET_UNRECOGNIZED_SCHEME);
+ return 0;
+ }
+
lpUC->nScheme = INTERNET_SCHEME_UNKNOWN;
lpUC->nPort = INTERNET_INVALID_PORT_NUMBER;
/* Parse <params> */
- lpszParam = memchrW(lpszap, ';', dwUrlLength - (lpszap - lpszUrl));
- if(!lpszParam)
- lpszParam = memchrW(lpszap, '?', dwUrlLength - (lpszap - lpszUrl));
+ lpszParam = memchrW(lpszap, '?', dwUrlLength - (lpszap - lpszUrl));
if(!lpszParam)
lpszParam = memchrW(lpszap, '#', dwUrlLength - (lpszap - lpszUrl));
SetUrlComponentValueW(&lpUC->lpszExtraInfo, &lpUC->dwExtraInfoLength,
lpszParam, lpszParam ? dwUrlLength-(lpszParam-lpszUrl) : 0);
- if (bIsAbsolute) /* Parse <protocol>:[//<net_loc>] */
- {
- LPCWSTR lpszNetLoc;
- /* Get scheme first. */
- lpUC->nScheme = GetInternetSchemeW(lpszUrl, lpszcp - lpszUrl);
- SetUrlComponentValueW(&lpUC->lpszScheme, &lpUC->dwSchemeLength,
- lpszUrl, lpszcp - lpszUrl);
+ /* Get scheme first. */
+ lpUC->nScheme = GetInternetSchemeW(lpszUrl, lpszcp - lpszUrl);
+ SetUrlComponentValueW(&lpUC->lpszScheme, &lpUC->dwSchemeLength,
+ lpszUrl, lpszcp - lpszUrl);
+
+ /* Eat ':' in protocol. */
+ lpszcp++;
- /* Eat ':' in protocol. */
- lpszcp++;
+ /* double slash indicates the net_loc portion is present */
+ if ((lpszcp[0] == '/') && (lpszcp[1] == '/'))
+ {
+ lpszcp += 2;
- /* double slash indicates the net_loc portion is present */
- if ((lpszcp[0] == '/') && (lpszcp[1] == '/'))
+ lpszNetLoc = memchrW(lpszcp, '/', dwUrlLength - (lpszcp - lpszUrl));
+ if (lpszParam)
{
- lpszcp += 2;
+ if (lpszNetLoc)
+ lpszNetLoc = min(lpszNetLoc, lpszParam);
+ else
+ lpszNetLoc = lpszParam;
+ }
+ else if (!lpszNetLoc)
+ lpszNetLoc = lpszcp + dwUrlLength-(lpszcp-lpszUrl);
+
+ /* Parse net-loc */
+ if (lpszNetLoc)
+ {
+ LPCWSTR lpszHost;
+ LPCWSTR lpszPort;
- lpszNetLoc = memchrW(lpszcp, '/', dwUrlLength - (lpszcp - lpszUrl));
- if (lpszParam)
+ /* [<user>[<:password>]@]<host>[:<port>] */
+ /* First find the user and password if they exist */
+
+ lpszHost = memchrW(lpszcp, '@', dwUrlLength - (lpszcp - lpszUrl));
+ if (lpszHost == NULL || lpszHost > lpszNetLoc)
{
- if (lpszNetLoc)
- lpszNetLoc = min(lpszNetLoc, lpszParam);
- else
- lpszNetLoc = lpszParam;
+ /* username and password not specified. */
+ SetUrlComponentValueW(&lpUC->lpszUserName, &lpUC->dwUserNameLength, NULL, 0);
+ SetUrlComponentValueW(&lpUC->lpszPassword, &lpUC->dwPasswordLength, NULL, 0);
}
- else if (!lpszNetLoc)
- lpszNetLoc = lpszcp + dwUrlLength-(lpszcp-lpszUrl);
-
- /* Parse net-loc */
- if (lpszNetLoc)
+ else /* Parse out username and password */
{
- LPCWSTR lpszHost;
- LPCWSTR lpszPort;
-
- /* [<user>[<:password>]@]<host>[:<port>] */
- /* First find the user and password if they exist */
+ LPCWSTR lpszUser = lpszcp;
+ LPCWSTR lpszPasswd = lpszHost;
- lpszHost = memchrW(lpszcp, '@', dwUrlLength - (lpszcp - lpszUrl));
- if (lpszHost == NULL || lpszHost > lpszNetLoc)
+ while (lpszcp < lpszHost)
{
- /* username and password not specified. */
- SetUrlComponentValueW(&lpUC->lpszUserName, &lpUC->dwUserNameLength, NULL, 0);
- SetUrlComponentValueW(&lpUC->lpszPassword, &lpUC->dwPasswordLength, NULL, 0);
+ if (*lpszcp == ':')
+ lpszPasswd = lpszcp;
+
+ lpszcp++;
}
- else /* Parse out username and password */
- {
- LPCWSTR lpszUser = lpszcp;
- LPCWSTR lpszPasswd = lpszHost;
- while (lpszcp < lpszHost)
- {
- if (*lpszcp == ':')
- lpszPasswd = lpszcp;
+ SetUrlComponentValueW(&lpUC->lpszUserName, &lpUC->dwUserNameLength,
+ lpszUser, lpszPasswd - lpszUser);
- lpszcp++;
- }
+ if (lpszPasswd != lpszHost)
+ lpszPasswd++;
+ SetUrlComponentValueW(&lpUC->lpszPassword, &lpUC->dwPasswordLength,
+ lpszPasswd == lpszHost ? NULL : lpszPasswd,
+ lpszHost - lpszPasswd);
- SetUrlComponentValueW(&lpUC->lpszUserName, &lpUC->dwUserNameLength,
- lpszUser, lpszPasswd - lpszUser);
+ lpszcp++; /* Advance to beginning of host */
+ }
- if (lpszPasswd != lpszHost)
- lpszPasswd++;
- SetUrlComponentValueW(&lpUC->lpszPassword, &lpUC->dwPasswordLength,
- lpszPasswd == lpszHost ? NULL : lpszPasswd,
- lpszHost - lpszPasswd);
+ /* Parse <host><:port> */
- lpszcp++; /* Advance to beginning of host */
- }
+ lpszHost = lpszcp;
+ lpszPort = lpszNetLoc;
- /* Parse <host><:port> */
+ /* special case for res:// URLs: there is no port here, so the host is the
+ entire string up to the first '/' */
+ if(lpUC->nScheme==INTERNET_SCHEME_RES)
+ {
+ SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength,
+ lpszHost, lpszPort - lpszHost);
+ lpszcp=lpszNetLoc;
+ }
+ else
+ {
+ while (lpszcp < lpszNetLoc)
+ {
+ if (*lpszcp == ':')
+ lpszPort = lpszcp;
- lpszHost = lpszcp;
- lpszPort = lpszNetLoc;
+ lpszcp++;
+ }
- /* special case for res:// URLs: there is no port here, so the host is the
- entire string up to the first '/' */
- if(lpUC->nScheme==INTERNET_SCHEME_RES)
+ /* If the scheme is "file" and the host is just one letter, it's not a host */
+ if(lpUC->nScheme==INTERNET_SCHEME_FILE && lpszPort <= lpszHost+1)
{
+ lpszcp=lpszHost;
SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength,
- lpszHost, lpszPort - lpszHost);
- lpszcp=lpszNetLoc;
+ NULL, 0);
}
else
{
- while (lpszcp < lpszNetLoc)
- {
- if (*lpszcp == ':')
- lpszPort = lpszcp;
-
- lpszcp++;
- }
-
- /* If the scheme is "file" and the host is just one letter, it's not a host */
- if(lpUC->nScheme==INTERNET_SCHEME_FILE && lpszPort <= lpszHost+1)
- {
- lpszcp=lpszHost;
- SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength,
- NULL, 0);
- }
- else
+ SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength,
+ lpszHost, lpszPort - lpszHost);
+ if (lpszPort != lpszNetLoc)
+ lpUC->nPort = atoiW(++lpszPort);
+ else switch (lpUC->nScheme)
{
- SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength,
- lpszHost, lpszPort - lpszHost);
- if (lpszPort != lpszNetLoc)
- lpUC->nPort = atoiW(++lpszPort);
- else switch (lpUC->nScheme)
- {
- case INTERNET_SCHEME_HTTP:
- lpUC->nPort = INTERNET_DEFAULT_HTTP_PORT;
- break;
- case INTERNET_SCHEME_HTTPS:
- lpUC->nPort = INTERNET_DEFAULT_HTTPS_PORT;
- break;
- case INTERNET_SCHEME_FTP:
- lpUC->nPort = INTERNET_DEFAULT_FTP_PORT;
- break;
- case INTERNET_SCHEME_GOPHER:
- lpUC->nPort = INTERNET_DEFAULT_GOPHER_PORT;
- break;
- default:
- break;
- }
+ case INTERNET_SCHEME_HTTP:
+ lpUC->nPort = INTERNET_DEFAULT_HTTP_PORT;
+ break;
+ case INTERNET_SCHEME_HTTPS:
+ lpUC->nPort = INTERNET_DEFAULT_HTTPS_PORT;
+ break;
+ case INTERNET_SCHEME_FTP:
+ lpUC->nPort = INTERNET_DEFAULT_FTP_PORT;
+ break;
+ case INTERNET_SCHEME_GOPHER:
+ lpUC->nPort = INTERNET_DEFAULT_GOPHER_PORT;
+ break;
+ default:
+ break;
}
}
}
}
- else
- {
- SetUrlComponentValueW(&lpUC->lpszUserName, &lpUC->dwUserNameLength, NULL, 0);
- SetUrlComponentValueW(&lpUC->lpszPassword, &lpUC->dwPasswordLength, NULL, 0);
- SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength, NULL, 0);
- }
}
else
{
- SetUrlComponentValueW(&lpUC->lpszScheme, &lpUC->dwSchemeLength, NULL, 0);
SetUrlComponentValueW(&lpUC->lpszUserName, &lpUC->dwUserNameLength, NULL, 0);
SetUrlComponentValueW(&lpUC->lpszPassword, &lpUC->dwPasswordLength, NULL, 0);
SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength, NULL, 0);
}
+/***********************************************************************
+ * convert_url_canonicalization_flags
+ *
+ * Helper for InternetCanonicalizeUrl
+ *
+ * PARAMS
+ * dwFlags [I] Flags suitable for InternetCanonicalizeUrl
+ *
+ * RETURNS
+ * Flags suitable for UrlCanonicalize
+ */
+static DWORD convert_url_canonicalization_flags(DWORD dwFlags)
+{
+ DWORD dwUrlFlags = URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE;
+
+ if (dwFlags & ICU_BROWSER_MODE) dwUrlFlags |= URL_BROWSER_MODE;
+ if (dwFlags & ICU_DECODE) dwUrlFlags |= URL_UNESCAPE;
+ if (dwFlags & ICU_ENCODE_PERCENT) dwUrlFlags |= URL_ESCAPE_PERCENT;
+ if (dwFlags & ICU_ENCODE_SPACES_ONLY) dwUrlFlags |= URL_ESCAPE_SPACES_ONLY;
+ /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
+ if (dwFlags & ICU_NO_ENCODE) dwUrlFlags ^= URL_ESCAPE_UNSAFE;
+ if (dwFlags & ICU_NO_META) dwUrlFlags |= URL_NO_META;
+
+ return dwUrlFlags;
+}
+
/***********************************************************************
* InternetCanonicalizeUrlA (WININET.@)
*
LPDWORD lpdwBufferLength, DWORD dwFlags)
{
HRESULT hr;
- DWORD dwURLFlags = URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE;
TRACE("(%s, %p, %p, 0x%08x) bufferlength: %d\n", debugstr_a(lpszUrl), lpszBuffer,
lpdwBufferLength, dwFlags, lpdwBufferLength ? *lpdwBufferLength : -1);
- if(dwFlags & ICU_DECODE)
- {
- dwURLFlags |= URL_UNESCAPE;
- dwFlags &= ~ICU_DECODE;
- }
-
- if(dwFlags & ICU_ESCAPE)
- {
- dwURLFlags |= URL_UNESCAPE;
- dwFlags &= ~ICU_ESCAPE;
- }
-
- if(dwFlags & ICU_BROWSER_MODE)
- {
- dwURLFlags |= URL_BROWSER_MODE;
- dwFlags &= ~ICU_BROWSER_MODE;
- }
-
- if(dwFlags & ICU_NO_ENCODE)
- {
- /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
- dwURLFlags ^= URL_ESCAPE_UNSAFE;
- dwFlags &= ~ICU_NO_ENCODE;
- }
-
- if (dwFlags) FIXME("Unhandled flags 0x%08x\n", dwFlags);
-
- hr = UrlCanonicalizeA(lpszUrl, lpszBuffer, lpdwBufferLength, dwURLFlags);
+ dwFlags = convert_url_canonicalization_flags(dwFlags);
+ hr = UrlCanonicalizeA(lpszUrl, lpszBuffer, lpdwBufferLength, dwFlags);
if (hr == E_POINTER) SetLastError(ERROR_INSUFFICIENT_BUFFER);
if (hr == E_INVALIDARG) SetLastError(ERROR_INVALID_PARAMETER);
- return (hr == S_OK) ? TRUE : FALSE;
+ return hr == S_OK;
}
/***********************************************************************
LPDWORD lpdwBufferLength, DWORD dwFlags)
{
HRESULT hr;
- DWORD dwURLFlags = URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE;
TRACE("(%s, %p, %p, 0x%08x) bufferlength: %d\n", debugstr_w(lpszUrl), lpszBuffer,
lpdwBufferLength, dwFlags, lpdwBufferLength ? *lpdwBufferLength : -1);
- if(dwFlags & ICU_DECODE)
- {
- dwURLFlags |= URL_UNESCAPE;
- dwFlags &= ~ICU_DECODE;
- }
-
- if(dwFlags & ICU_ESCAPE)
- {
- dwURLFlags |= URL_UNESCAPE;
- dwFlags &= ~ICU_ESCAPE;
- }
-
- if(dwFlags & ICU_BROWSER_MODE)
- {
- dwURLFlags |= URL_BROWSER_MODE;
- dwFlags &= ~ICU_BROWSER_MODE;
- }
-
- if(dwFlags & ICU_NO_ENCODE)
- {
- /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */
- dwURLFlags ^= URL_ESCAPE_UNSAFE;
- dwFlags &= ~ICU_NO_ENCODE;
- }
-
- if (dwFlags) FIXME("Unhandled flags 0x%08x\n", dwFlags);
-
- hr = UrlCanonicalizeW(lpszUrl, lpszBuffer, lpdwBufferLength, dwURLFlags);
+ dwFlags = convert_url_canonicalization_flags(dwFlags);
+ hr = UrlCanonicalizeW(lpszUrl, lpszBuffer, lpdwBufferLength, dwFlags);
if (hr == E_POINTER) SetLastError(ERROR_INSUFFICIENT_BUFFER);
if (hr == E_INVALIDARG) SetLastError(ERROR_INVALID_PARAMETER);
- return (hr == S_OK) ? TRUE : FALSE;
+ return hr == S_OK;
}
/* #################################################### */
TRACE("(%p %p 0x%x 0x%lx)\n", hFile, lpBuffersOut, dwFlags, dwContext);
+ if (lpBuffersOut->dwStructSize != sizeof(*lpBuffersOut)) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
hdr = get_handle_object(hFile);
if (!hdr) {
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
- if(hdr->vtbl->ReadFileExA)
- res = hdr->vtbl->ReadFileExA(hdr, lpBuffersOut, dwFlags, dwContext);
+ if(hdr->vtbl->ReadFileEx)
+ res = hdr->vtbl->ReadFileEx(hdr, lpBuffersOut->lpvBuffer, lpBuffersOut->dwBufferLength,
+ &lpBuffersOut->dwBufferLength, dwFlags, dwContext);
WININET_Release(hdr);
TRACE("(%p %p 0x%x 0x%lx)\n", hFile, lpBuffer, dwFlags, dwContext);
+ if (lpBuffer->dwStructSize != sizeof(*lpBuffer)) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
hdr = get_handle_object(hFile);
if (!hdr) {
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
- if(hdr->vtbl->ReadFileExW)
- res = hdr->vtbl->ReadFileExW(hdr, lpBuffer, dwFlags, dwContext);
+ if(hdr->vtbl->ReadFileEx)
+ res = hdr->vtbl->ReadFileEx(hdr, lpBuffer->lpvBuffer, lpBuffer->dwBufferLength, &lpBuffer->dwBufferLength,
+ dwFlags, dwContext);
WININET_Release(hdr);
/* FIXME: This function currently handles more options than it should. Options requiring
* proper handles should be moved to proper functions */
switch(option) {
- case INTERNET_OPTION_REQUEST_FLAGS:
- TRACE("INTERNET_OPTION_REQUEST_FLAGS\n");
-
- if (*size < sizeof(ULONG))
- return ERROR_INSUFFICIENT_BUFFER;
-
- *(ULONG*)buffer = 4;
- *size = sizeof(ULONG);
-
- return ERROR_SUCCESS;
-
case INTERNET_OPTION_HTTP_VERSION:
if (*size < sizeof(HTTP_VERSION_INFO))
return ERROR_INSUFFICIENT_BUFFER;
return res;
}
+ case INTERNET_OPTION_REQUEST_FLAGS:
case INTERNET_OPTION_USER_AGENT:
+ *size = 0;
return ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
case INTERNET_OPTION_POLICY:
return ERROR_INVALID_PARAMETER;
+ case INTERNET_OPTION_CONNECT_TIMEOUT:
+ TRACE("INTERNET_OPTION_CONNECT_TIMEOUT\n");
+
+ if (*size < sizeof(ULONG))
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *(ULONG*)buffer = connect_timeout;
+ *size = sizeof(ULONG);
+
+ return ERROR_SUCCESS;
}
FIXME("Stub for %d\n", option);
*size = sizeof(DWORD_PTR);
return ERROR_SUCCESS;
+ case INTERNET_OPTION_REQUEST_FLAGS:
+ WARN("INTERNET_OPTION_REQUEST_FLAGS\n");
+ *size = sizeof(DWORD);
+ return ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
+
case INTERNET_OPTION_MAX_CONNS_PER_SERVER:
case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER:
WARN("Called on global option %u\n", option);
max_1_0_conns = *(ULONG*)buf;
return ERROR_SUCCESS;
+
+ case INTERNET_OPTION_CONNECT_TIMEOUT:
+ TRACE("INTERNET_OPTION_CONNECT_TIMEOUT\n");
+
+ if(size != sizeof(connect_timeout))
+ return ERROR_INTERNET_BAD_OPTION_LENGTH;
+ if(!*(ULONG*)buf)
+ return ERROR_BAD_ARGUMENTS;
+
+ connect_timeout = *(ULONG*)buf;
+ return ERROR_SUCCESS;
+
+ case INTERNET_OPTION_SETTINGS_CHANGED:
+ FIXME("INTERNETOPTION_SETTINGS_CHANGED semi-stub\n");
+ collect_connections(COLLECT_CONNECTIONS);
+ return ERROR_SUCCESS;
}
return ERROR_INTERNET_INVALID_OPTION;
SetLastError(ERROR_INTERNET_BAD_OPTION_LENGTH);
ret = FALSE;
} else
+ TRACE("INTERNET_OPTION_ERROR_MASK: %x\n", *(ULONG*)lpBuffer);
lpwhh->ErrorMask = *(ULONG*)lpBuffer;
}
break;
case INTERNET_OPTION_PER_CONNECTION_OPTION: {
INTERNET_PER_CONN_OPTION_LISTW *con = lpBuffer;
LONG res;
- int i;
+ unsigned int i;
proxyinfo_t pi;
INTERNET_LoadProxySettings(&pi);
wbuffer, wlen );
break;
case INTERNET_OPTION_PER_CONNECTION_OPTION: {
- int i;
+ unsigned int i;
INTERNET_PER_CONN_OPTION_LISTW *listW;
INTERNET_PER_CONN_OPTION_LISTA *listA = lpBuffer;
wlen = sizeof(INTERNET_PER_CONN_OPTION_LISTW);
if (dwOption == INTERNET_OPTION_PER_CONNECTION_OPTION)
{
INTERNET_PER_CONN_OPTION_LISTW *list = wbuffer;
- int i;
+ unsigned int i;
for (i = 0; i < list->dwOptionCount; ++i) {
INTERNET_PER_CONN_OPTIONW *opt = list->pOptions + i;
switch (opt->dwOption) {
* RETURNS
* handle of connection or NULL on failure
*/
-static void AsyncInternetOpenUrlProc(WORKREQUEST *workRequest)
+typedef struct {
+ task_header_t hdr;
+ WCHAR *url;
+ WCHAR *headers;
+ DWORD headers_len;
+ DWORD flags;
+ DWORD_PTR context;
+} open_url_task_t;
+
+static void AsyncInternetOpenUrlProc(task_header_t *hdr)
{
- struct WORKREQ_INTERNETOPENURLW const *req = &workRequest->u.InternetOpenUrlW;
- appinfo_t *hIC = (appinfo_t*) workRequest->hdr;
+ open_url_task_t *task = (open_url_task_t*)hdr;
- TRACE("%p\n", hIC);
+ TRACE("%p\n", task->hdr.hdr);
- INTERNET_InternetOpenUrlW(hIC, req->lpszUrl,
- req->lpszHeaders, req->dwHeadersLength, req->dwFlags, req->dwContext);
- heap_free(req->lpszUrl);
- heap_free(req->lpszHeaders);
+ INTERNET_InternetOpenUrlW((appinfo_t*)task->hdr.hdr, task->url, task->headers,
+ task->headers_len, task->flags, task->context);
+ heap_free(task->url);
+ heap_free(task->headers);
}
HINTERNET WINAPI InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
}
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) {
- WORKREQUEST workRequest;
- struct WORKREQ_INTERNETOPENURLW *req;
-
- workRequest.asyncproc = AsyncInternetOpenUrlProc;
- workRequest.hdr = WININET_AddRef( &hIC->hdr );
- req = &workRequest.u.InternetOpenUrlW;
- req->lpszUrl = heap_strdupW(lpszUrl);
- req->lpszHeaders = heap_strdupW(lpszHeaders);
- req->dwHeadersLength = dwHeadersLength;
- req->dwFlags = dwFlags;
- req->dwContext = dwContext;
+ open_url_task_t *task;
+
+ task = alloc_async_task(&hIC->hdr, AsyncInternetOpenUrlProc, sizeof(*task));
+ task->url = heap_strdupW(lpszUrl);
+ task->headers = heap_strdupW(lpszHeaders);
+ task->headers_len = dwHeadersLength;
+ task->flags = dwFlags;
+ task->context = dwContext;
- INTERNET_AsyncCall(&workRequest);
- /*
- * This is from windows.
- */
- SetLastError(ERROR_IO_PENDING);
+ INTERNET_AsyncCall(&task->hdr);
+ SetLastError(ERROR_IO_PENDING);
} else {
ret = INTERNET_InternetOpenUrlW(hIC, lpszUrl, lpszHeaders, dwHeadersLength, dwFlags, dwContext);
}
*/
static DWORD CALLBACK INTERNET_WorkerThreadFunc(LPVOID lpvParam)
{
- LPWORKREQUEST lpRequest = lpvParam;
- WORKREQUEST workRequest;
+ task_header_t *task = lpvParam;
TRACE("\n");
- workRequest = *lpRequest;
- heap_free(lpRequest);
-
- workRequest.asyncproc(&workRequest);
- WININET_Release( workRequest.hdr );
+ task->proc(task);
+ WININET_Release(task->hdr);
+ heap_free(task);
if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES)
{
return TRUE;
}
+void *alloc_async_task(object_header_t *hdr, async_task_proc_t proc, size_t size)
+{
+ task_header_t *task;
+
+ task = heap_alloc(size);
+ if(!task)
+ return NULL;
+
+ task->hdr = WININET_AddRef(hdr);
+ task->proc = proc;
+ return task;
+}
/***********************************************************************
* INTERNET_AsyncCall (internal)
* RETURNS
*
*/
-DWORD INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest)
+DWORD INTERNET_AsyncCall(task_header_t *task)
{
BOOL bSuccess;
- LPWORKREQUEST lpNewRequest;
TRACE("\n");
- lpNewRequest = heap_alloc(sizeof(WORKREQUEST));
- if (!lpNewRequest)
- return ERROR_OUTOFMEMORY;
-
- *lpNewRequest = *lpWorkRequest;
-
- bSuccess = QueueUserWorkItem(INTERNET_WorkerThreadFunc, lpNewRequest, WT_EXECUTELONGFUNCTION);
+ bSuccess = QueueUserWorkItem(INTERNET_WorkerThreadFunc, task, WT_EXECUTELONGFUNCTION);
if (!bSuccess)
{
- heap_free(lpNewRequest);
+ heap_free(task);
return ERROR_INTERNET_ASYNC_THREAD_FAILED;
}
return ERROR_SUCCESS;
* data is available.
*/
BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
- LPDWORD lpdwNumberOfBytesAvailble,
+ LPDWORD lpdwNumberOfBytesAvailable,
DWORD dwFlags, DWORD_PTR dwContext)
{
object_header_t *hdr;
DWORD res;
- TRACE("(%p %p %x %lx)\n", hFile, lpdwNumberOfBytesAvailble, dwFlags, dwContext);
+ TRACE("(%p %p %x %lx)\n", hFile, lpdwNumberOfBytesAvailable, dwFlags, dwContext);
hdr = get_handle_object( hFile );
if (!hdr) {
}
if(hdr->vtbl->QueryDataAvailable) {
- res = hdr->vtbl->QueryDataAvailable(hdr, lpdwNumberOfBytesAvailble, dwFlags, dwContext);
+ res = hdr->vtbl->QueryDataAvailable(hdr, lpdwNumberOfBytesAvailable, dwFlags, dwContext);
}else {
WARN("wrong handle\n");
res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
return 0;
}
+/***********************************************************************
+ * InternetGetSecurityInfoByURLA (WININET.@)
+ */
+BOOL WINAPI InternetGetSecurityInfoByURLA(LPSTR lpszURL, PCCERT_CHAIN_CONTEXT *ppCertChain, DWORD *pdwSecureFlags)
+{
+ WCHAR *url;
+ BOOL res;
+
+ TRACE("(%s %p %p)\n", debugstr_a(lpszURL), ppCertChain, pdwSecureFlags);
+
+ url = heap_strdupAtoW(lpszURL);
+ if(!url)
+ return FALSE;
+
+ res = InternetGetSecurityInfoByURLW(url, ppCertChain, pdwSecureFlags);
+ heap_free(url);
+ return res;
+}
+
+/***********************************************************************
+ * InternetGetSecurityInfoByURLW (WININET.@)
+ */
+BOOL WINAPI InternetGetSecurityInfoByURLW(LPCWSTR lpszURL, PCCERT_CHAIN_CONTEXT *ppCertChain, DWORD *pdwSecureFlags)
+{
+ WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH];
+ URL_COMPONENTSW url = {sizeof(url)};
+ server_t *server;
+ BOOL res = FALSE;
+
+ TRACE("(%s %p %p)\n", debugstr_w(lpszURL), ppCertChain, pdwSecureFlags);
+
+ url.lpszHostName = hostname;
+ url.dwHostNameLength = sizeof(hostname)/sizeof(WCHAR);
+
+ res = InternetCrackUrlW(lpszURL, 0, 0, &url);
+ if(!res || url.nScheme != INTERNET_SCHEME_HTTPS) {
+ SetLastError(ERROR_INTERNET_ITEM_NOT_FOUND);
+ return FALSE;
+ }
+
+ server = get_server(hostname, url.nPort, TRUE, FALSE);
+ if(!server) {
+ SetLastError(ERROR_INTERNET_ITEM_NOT_FOUND);
+ return FALSE;
+ }
+
+ if(server->cert_chain) {
+ const CERT_CHAIN_CONTEXT *chain_dup;
+
+ chain_dup = CertDuplicateCertificateChain(server->cert_chain);
+ if(chain_dup) {
+ *ppCertChain = chain_dup;
+ *pdwSecureFlags = server->security_flags & _SECURITY_ERROR_FLAGS_MASK;
+ }else {
+ res = FALSE;
+ }
+ }else {
+ SetLastError(ERROR_INTERNET_ITEM_NOT_FOUND);
+ res = FALSE;
+ }
+
+ server_release(server);
+ return res;
+}
+
DWORD WINAPI InternetDialA( HWND hwndParent, LPSTR lpszConnectoid, DWORD dwFlags,
DWORD_PTR* lpdwConnection, DWORD dwReserved )
{