[WININET] Sync with Wine Staging 1.7.47. CORE-9924

svn path=/trunk/; revision=68559
This commit is contained in:
Amine Khaldi 2015-07-22 19:43:18 +00:00
parent 9e1c2a00b9
commit fa6c5cde14
11 changed files with 365 additions and 528 deletions

View file

@ -324,8 +324,10 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
UnlockUrlCacheEntryStream(cookie, 0);
cookie_container = get_cookie_container(domain, path, TRUE);
if(!cookie_container)
if(!cookie_container) {
heap_free(str);
return FALSE;
}
GetSystemTimeAsFileTime(&time);
for(pbeg=str; pbeg && *pbeg; name=data=NULL) {
@ -926,6 +928,7 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
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};
static const WCHAR szVersion[] = {'v','e','r','s','i','o','n','=',0};
if (!(ptr = strchrW(ptr,';'))) break;
*ptr++ = 0;
@ -1006,6 +1009,11 @@ DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_nam
cookie_flags |= INTERNET_COOKIE_HTTPONLY;
ptr += strlenW(szHttpOnly);
}
else if (strncmpiW(ptr, szVersion, 8) == 0)
{
FIXME("version not handled (%s)\n",debugstr_w(ptr));
ptr += strlenW(szVersion);
}
else if (*ptr)
{
FIXME("Unknown additional option %s\n",debugstr_w(ptr));

View file

@ -556,6 +556,15 @@ BOOL WINAPI InternetShowSecurityInfoByURLW(LPCWSTR url, HWND window)
return FALSE;
}
/***********************************************************************
* ParseX509EncodedCertificateForListBoxEntry (@)
*/
DWORD WINAPI ParseX509EncodedCertificateForListBoxEntry(LPBYTE cert, DWORD len, LPSTR szlistbox, LPDWORD listbox)
{
FIXME("stub: %p %d %s %p\n", cert, len, debugstr_a(szlistbox), listbox);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/***********************************************************************
* ShowX509EncodedCertificate (@)
*/

View file

@ -1199,7 +1199,7 @@ static DWORD FTPFILE_WriteFile(object_header_t *hdr, const void *buffer, DWORD s
res = sock_send(lpwh->nDataSocket, buffer, size, 0);
*written = res>0 ? res : 0;
return res >= 0 ? ERROR_SUCCESS : sock_get_error();
return res >= 0 ? ERROR_SUCCESS : WSAGetLastError();
}
static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif)
@ -2541,7 +2541,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
if (connect(nsocket, (struct sockaddr *)&socketAddr, sock_namelen) < 0)
{
ERR("Unable to connect (%d)\n", sock_get_error());
ERR("Unable to connect (%d)\n", WSAGetLastError());
INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT);
closesocket(nsocket);
}

View file

@ -362,10 +362,17 @@ static WCHAR *get_host_header( http_request_t *req )
EnterCriticalSection( &req->headers_section );
if ((header = HTTP_GetHeader( req, hostW ))) ret = heap_strdupW( header->lpszValue );
else ret = heap_strdupW( req->server->canon_host_port );
LeaveCriticalSection( &req->headers_section );
return ret;
}
typedef enum {
BLOCKING_ALLOW,
BLOCKING_DISALLOW,
BLOCKING_WAITALL
} blocking_mode_t;
struct data_stream_vtbl_t {
DWORD (*get_avail_data)(data_stream_t*,http_request_t*);
BOOL (*end_of_data)(data_stream_t*,http_request_t*);
@ -394,7 +401,7 @@ static void reset_data_stream(http_request_t *req)
destroy_data_stream(req->data_stream);
req->data_stream = &req->netconn_stream.data_stream;
req->read_pos = req->read_size = req->netconn_stream.content_read = 0;
req->read_chunked = req->read_gzip = FALSE;
req->read_gzip = FALSE;
}
static void remove_header( http_request_t *request, const WCHAR *str, BOOL from_request )
@ -743,15 +750,22 @@ static void HTTP_ProcessCookies( http_request_t *request )
int HeaderIndex;
int numCookies = 0;
LPHTTPHEADERW setCookieHeader;
WCHAR *path, *tmp;
if(request->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES)
return;
path = heap_strdupW(request->path);
if (!path)
return;
tmp = strrchrW(path, '/');
if (tmp && tmp[1]) tmp[1] = 0;
EnterCriticalSection( &request->headers_section );
while((HeaderIndex = HTTP_GetCustomHeaderIndex(request, szSet_Cookie, numCookies++, FALSE)) != -1)
{
HTTPHEADERW *host;
const WCHAR *data;
WCHAR *name;
@ -760,10 +774,6 @@ static void HTTP_ProcessCookies( http_request_t *request )
if (!setCookieHeader->lpszValue)
continue;
host = HTTP_GetHeader(request, hostW);
if(!host)
continue;
data = strchrW(setCookieHeader->lpszValue, '=');
if(!data)
continue;
@ -773,11 +783,12 @@ static void HTTP_ProcessCookies( http_request_t *request )
continue;
data++;
set_cookie(host->lpszValue, request->path, name, data, INTERNET_COOKIE_HTTPONLY);
set_cookie(request->server->name, path, name, data, INTERNET_COOKIE_HTTPONLY);
heap_free(name);
}
LeaveCriticalSection( &request->headers_section );
heap_free(path);
}
static void strip_spaces(LPWSTR start)
@ -849,7 +860,7 @@ static void destroy_authinfo( struct HttpAuthInfo *authinfo )
heap_free(authinfo);
}
static UINT retrieve_cached_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR *auth_data)
static UINT retrieve_cached_basic_authorization(const WCHAR *host, const WCHAR *realm, char **auth_data)
{
basicAuthorizationData *ad;
UINT rc = 0;
@ -859,7 +870,7 @@ static UINT retrieve_cached_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR
EnterCriticalSection(&authcache_cs);
LIST_FOR_EACH_ENTRY(ad, &basicAuthorizationCache, basicAuthorizationData, entry)
{
if (!strcmpiW(host,ad->host) && !strcmpW(realm,ad->realm))
if (!strcmpiW(host, ad->host) && (!realm || !strcmpW(realm, ad->realm)))
{
TRACE("Authorization found in cache\n");
*auth_data = heap_alloc(ad->authorizationLen);
@ -1541,40 +1552,17 @@ static UINT HTTP_EncodeBase64( LPCSTR bin, unsigned int len, LPWSTR base64 )
return n;
}
#define CH(x) (((x) >= 'A' && (x) <= 'Z') ? (x) - 'A' : \
((x) >= 'a' && (x) <= 'z') ? (x) - 'a' + 26 : \
((x) >= '0' && (x) <= '9') ? (x) - '0' + 52 : \
((x) == '+') ? 62 : ((x) == '/') ? 63 : -1)
static const signed char HTTP_Base64Dec[256] =
static const signed char HTTP_Base64Dec[] =
{
CH( 0),CH( 1),CH( 2),CH( 3),CH( 4),CH( 5),CH( 6),CH( 7),CH( 8),CH( 9),
CH(10),CH(11),CH(12),CH(13),CH(14),CH(15),CH(16),CH(17),CH(18),CH(19),
CH(20),CH(21),CH(22),CH(23),CH(24),CH(25),CH(26),CH(27),CH(28),CH(29),
CH(30),CH(31),CH(32),CH(33),CH(34),CH(35),CH(36),CH(37),CH(38),CH(39),
CH(40),CH(41),CH(42),CH(43),CH(44),CH(45),CH(46),CH(47),CH(48),CH(49),
CH(50),CH(51),CH(52),CH(53),CH(54),CH(55),CH(56),CH(57),CH(58),CH(59),
CH(60),CH(61),CH(62),CH(63),CH(64),CH(65),CH(66),CH(67),CH(68),CH(69),
CH(70),CH(71),CH(72),CH(73),CH(74),CH(75),CH(76),CH(77),CH(78),CH(79),
CH(80),CH(81),CH(82),CH(83),CH(84),CH(85),CH(86),CH(87),CH(88),CH(89),
CH(90),CH(91),CH(92),CH(93),CH(94),CH(95),CH(96),CH(97),CH(98),CH(99),
CH(100),CH(101),CH(102),CH(103),CH(104),CH(105),CH(106),CH(107),CH(108),CH(109),
CH(110),CH(111),CH(112),CH(113),CH(114),CH(115),CH(116),CH(117),CH(118),CH(119),
CH(120),CH(121),CH(122),CH(123),CH(124),CH(125),CH(126),CH(127),CH(128),CH(129),
CH(130),CH(131),CH(132),CH(133),CH(134),CH(135),CH(136),CH(137),CH(138),CH(139),
CH(140),CH(141),CH(142),CH(143),CH(144),CH(145),CH(146),CH(147),CH(148),CH(149),
CH(150),CH(151),CH(152),CH(153),CH(154),CH(155),CH(156),CH(157),CH(158),CH(159),
CH(160),CH(161),CH(162),CH(163),CH(164),CH(165),CH(166),CH(167),CH(168),CH(169),
CH(170),CH(171),CH(172),CH(173),CH(174),CH(175),CH(176),CH(177),CH(178),CH(179),
CH(180),CH(181),CH(182),CH(183),CH(184),CH(185),CH(186),CH(187),CH(188),CH(189),
CH(190),CH(191),CH(192),CH(193),CH(194),CH(195),CH(196),CH(197),CH(198),CH(199),
CH(200),CH(201),CH(202),CH(203),CH(204),CH(205),CH(206),CH(207),CH(208),CH(209),
CH(210),CH(211),CH(212),CH(213),CH(214),CH(215),CH(216),CH(217),CH(218),CH(219),
CH(220),CH(221),CH(222),CH(223),CH(224),CH(225),CH(226),CH(227),CH(228),CH(229),
CH(230),CH(231),CH(232),CH(233),CH(234),CH(235),CH(236),CH(237),CH(238),CH(239),
CH(240),CH(241),CH(242),CH(243),CH(244),CH(245),CH(246),CH(247),CH(248), CH(249),
CH(250),CH(251),CH(252),CH(253),CH(254),CH(255),
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20 */
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30 */
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40 */
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50 */
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60 */
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70 */
};
#undef CH
/***********************************************************************
* HTTP_DecodeBase64
@ -1629,6 +1617,21 @@ static UINT HTTP_DecodeBase64( LPCWSTR base64, LPSTR bin )
return n;
}
static WCHAR *encode_auth_data( const WCHAR *scheme, const char *data, UINT data_len )
{
WCHAR *ret;
UINT len, scheme_len = strlenW( scheme );
/* scheme + space + base64 encoded data (3/2/1 bytes data -> 4 bytes of characters) */
len = scheme_len + 1 + ((data_len + 2) * 4) / 3;
if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
memcpy( ret, scheme, scheme_len * sizeof(WCHAR) );
ret[scheme_len] = ' ';
HTTP_EncodeBase64( data, data_len, ret + scheme_len + 1 );
return ret;
}
/***********************************************************************
* HTTP_InsertAuthorization
*
@ -1636,27 +1639,16 @@ static UINT HTTP_DecodeBase64( LPCWSTR base64, LPSTR bin )
*/
static BOOL HTTP_InsertAuthorization( http_request_t *request, struct HttpAuthInfo *pAuthInfo, LPCWSTR header )
{
static const WCHAR wszBasic[] = {'B','a','s','i','c',0};
WCHAR *host, *authorization = NULL;
if (pAuthInfo)
{
static const WCHAR wszSpace[] = {' ',0};
static const WCHAR wszBasic[] = {'B','a','s','i','c',0};
unsigned int len;
WCHAR *authorization = NULL;
if (pAuthInfo->auth_data_len)
{
/* scheme + space + base64 encoded data (3/2/1 bytes data -> 4 bytes of characters) */
len = strlenW(pAuthInfo->scheme)+1+((pAuthInfo->auth_data_len+2)*4)/3;
authorization = heap_alloc((len+1)*sizeof(WCHAR));
if (!authorization)
if (!(authorization = encode_auth_data(pAuthInfo->scheme, pAuthInfo->auth_data, pAuthInfo->auth_data_len)))
return FALSE;
strcpyW(authorization, pAuthInfo->scheme);
strcatW(authorization, wszSpace);
HTTP_EncodeBase64(pAuthInfo->auth_data,
pAuthInfo->auth_data_len,
authorization+strlenW(authorization));
/* clear the data as it isn't valid now that it has been sent to the
* server, unless it's Basic authentication which doesn't do
* connection tracking */
@ -1670,9 +1662,35 @@ static BOOL HTTP_InsertAuthorization( http_request_t *request, struct HttpAuthIn
TRACE("Inserting authorization: %s\n", debugstr_w(authorization));
HTTP_ProcessHeader(request, header, authorization, HTTP_ADDHDR_FLAG_REQ | HTTP_ADDHDR_FLAG_REPLACE);
HTTP_ProcessHeader(request, header, authorization,
HTTP_ADDHDR_FLAG_REQ | HTTP_ADDHDR_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
heap_free(authorization);
}
else if (!strcmpW(header, szAuthorization) && (host = get_host_header(request)))
{
UINT data_len;
char *data;
if ((data_len = retrieve_cached_basic_authorization(host, NULL, &data)))
{
TRACE("Found cached basic authorization for %s\n", debugstr_w(host));
if (!(authorization = encode_auth_data(wszBasic, data, data_len)))
{
heap_free(data);
heap_free(host);
return FALSE;
}
TRACE("Inserting authorization: %s\n", debugstr_w(authorization));
HTTP_ProcessHeader(request, header, authorization,
HTTP_ADDHDR_FLAG_REQ | HTTP_ADDHDR_FLAG_REPLACE | HTTP_ADDHDR_FLAG_ADD);
heap_free(data);
heap_free(authorization);
}
heap_free(host);
}
return TRUE;
}
@ -1864,20 +1882,21 @@ static BOOL HTTP_GetRequestURL(http_request_t *req, LPWSTR buf)
static const WCHAR https[] = { 'h','t','t','p','s',':','/','/',0 };
static const WCHAR slash[] = { '/',0 };
LPHTTPHEADERW host_header;
const WCHAR *host;
LPCWSTR scheme;
host_header = HTTP_GetHeader(req, hostW);
if(!host_header)
return FALSE;
EnterCriticalSection( &req->headers_section );
host_header = HTTP_GetHeader(req, hostW);
if (host_header) host = host_header->lpszValue;
else host = req->server->canon_host_port;
if (req->hdr.dwFlags & INTERNET_FLAG_SECURE)
scheme = https;
else
scheme = http;
strcpyW(buf, scheme);
strcatW(buf, host_header->lpszValue);
strcatW(buf, host);
if (req->path[0] != '/')
strcatW(buf, slash);
strcatW(buf, req->path);
@ -2123,16 +2142,12 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe
case INTERNET_OPTION_URL: {
static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0};
WCHAR url[INTERNET_MAX_URL_LENGTH];
HTTPHEADERW *host;
TRACE("INTERNET_OPTION_URL\n");
EnterCriticalSection( &req->headers_section );
host = HTTP_GetHeader(req, hostW);
strcpyW(url, httpW);
strcatW(url, host->lpszValue);
strcatW(url, req->server->canon_host_port);
strcatW(url, req->path);
LeaveCriticalSection( &req->headers_section );
TRACE("INTERNET_OPTION_URL: %s\n",debugstr_w(url));
return str_to_buffer(url, buffer, size, unicode);
@ -2499,7 +2514,7 @@ static DWORD read_more_data( http_request_t *req, int maxlen )
if (maxlen == -1) maxlen = sizeof(req->read_buf);
res = NETCON_recv( req->netconn, req->read_buf + req->read_size,
maxlen - req->read_size, BLOCKING_ALLOW, &len );
maxlen - req->read_size, TRUE, &len );
if(res == ERROR_SUCCESS)
req->read_size += len;
@ -2645,24 +2660,28 @@ static DWORD netconn_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
{
netconn_stream_t *netconn_stream = (netconn_stream_t*)stream;
DWORD res = ERROR_SUCCESS;
int len = 0;
int len = 0, ret = 0;
size = min(size, netconn_stream->content_length-netconn_stream->content_read);
if(size && is_valid_netconn(req->netconn)) {
if((res = NETCON_recv(req->netconn, buf, size, blocking_mode, &len))) {
len = 0;
if(blocking_mode == BLOCKING_DISALLOW && res == WSAEWOULDBLOCK)
res = ERROR_SUCCESS;
else
while((res = NETCON_recv(req->netconn, buf+ret, size-ret, blocking_mode != BLOCKING_DISALLOW, &len)) == ERROR_SUCCESS) {
if(!len) {
netconn_stream->content_length = netconn_stream->content_read;
}else if(!len) {
netconn_stream->content_length = netconn_stream->content_read;
break;
}
ret += len;
netconn_stream->content_read += len;
if(blocking_mode != BLOCKING_WAITALL || size == ret)
break;
}
if(ret || (blocking_mode == BLOCKING_DISALLOW && res == WSAEWOULDBLOCK))
res = ERROR_SUCCESS;
}
netconn_stream->content_read += *read = len;
TRACE("read %u bytes\n", len);
TRACE("read %u bytes\n", ret);
*read = ret;
return res;
}
@ -2676,7 +2695,7 @@ static BOOL netconn_drain_content(data_stream_t *stream, http_request_t *req)
return TRUE;
do {
if(NETCON_recv(req->netconn, buf, sizeof(buf), BLOCKING_DISALLOW, &len) != ERROR_SUCCESS)
if(NETCON_recv(req->netconn, buf, sizeof(buf), FALSE, &len) != ERROR_SUCCESS)
return FALSE;
netconn_stream->content_read += len;
@ -2716,7 +2735,7 @@ static DWORD read_more_chunked_data(chunked_stream_t *stream, http_request_t *re
if (maxlen == -1) maxlen = sizeof(stream->buf);
res = NETCON_recv( req->netconn, stream->buf + stream->buf_size,
maxlen - stream->buf_size, BLOCKING_ALLOW, &len );
maxlen - stream->buf_size, TRUE, &len );
if(res == ERROR_SUCCESS)
stream->buf_size += len;
@ -2777,8 +2796,19 @@ static DWORD start_next_chunk(chunked_stream_t *stream, http_request_t *req)
if (req->contentLength == ~0u) req->contentLength = chunk_size;
else req->contentLength += chunk_size;
if (!chunk_size) stream->end_of_data = TRUE;
return discard_chunked_eol(stream, req);
/* eat the rest of this line */
if ((res = discard_chunked_eol(stream, req)) != ERROR_SUCCESS)
return res;
/* if there's chunk data, return now */
if (chunk_size) return ERROR_SUCCESS;
/* otherwise, eat the terminator for this chunk */
if ((res = discard_chunked_eol(stream, req)) != ERROR_SUCCESS)
return res;
stream->end_of_data = TRUE;
return ERROR_SUCCESS;
}
remove_chunked_data(stream, 1);
}
@ -2841,7 +2871,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
break;
}
res = NETCON_recv(req->netconn, (char *)buf+ret_read, read_bytes, BLOCKING_ALLOW, (int*)&read_bytes);
res = NETCON_recv(req->netconn, (char *)buf+ret_read, read_bytes, TRUE, (int*)&read_bytes);
if(res != ERROR_SUCCESS)
break;
}
@ -2930,7 +2960,6 @@ static DWORD set_content_length(http_request_t *request)
request->data_stream = &chunked_stream->data_stream;
request->contentLength = ~0u;
request->read_chunked = TRUE;
}
if(request->decoding) {
@ -3379,15 +3408,13 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
HTTP_ProcessHeader(request, HTTP_ACCEPT, lpszAcceptTypes[i],
HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA |
HTTP_ADDHDR_FLAG_REQ |
(i == 0 ? HTTP_ADDHDR_FLAG_REPLACE : 0));
(i == 0 ? (HTTP_ADDHDR_FLAG_REPLACE | HTTP_ADDHDR_FLAG_ADD) : 0));
}
}
request->verb = heap_strdupW(lpszVerb && *lpszVerb ? lpszVerb : szGET);
request->version = heap_strdupW(lpszVersion && *lpszVersion ? lpszVersion : g_szHttp1_1);
HTTP_ProcessHeader(request, hostW, request->server->canon_host_port, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDHDR_FLAG_REQ);
if (hIC->proxy && hIC->proxy[0] && !HTTP_ShouldBypassProxy(hIC, session->hostName))
HTTP_DealWithProxy( hIC, session, request );
@ -3540,7 +3567,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex)
{
LPHTTPHEADERW lphttpHdr = NULL;
BOOL request_only = dwInfoLevel & HTTP_QUERY_FLAG_REQUEST_HEADERS;
BOOL request_only = !!(dwInfoLevel & HTTP_QUERY_FLAG_REQUEST_HEADERS);
INT requested_index = lpdwIndex ? *lpdwIndex : 0;
DWORD level = (dwInfoLevel & ~HTTP_QUERY_MODIFIER_FLAGS_MASK);
INT index = -1;
@ -4219,8 +4246,8 @@ static void HTTP_InsertCookies(http_request_t *request)
if(res != ERROR_SUCCESS || !cookies)
return;
get_cookie_header(request->server->name, request->path, &cookies);
HTTP_HttpAddRequestHeadersW(request, cookies, strlenW(cookies), HTTP_ADDREQ_FLAG_REPLACE);
HTTP_HttpAddRequestHeadersW(request, cookies, strlenW(cookies),
HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
heap_free(cookies);
}
@ -4880,6 +4907,9 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
if (!request->verb)
request->verb = heap_strdupW(szGET);
HTTP_ProcessHeader(request, hostW, request->server->canon_host_port,
HTTP_ADDREQ_FLAG_ADD_IF_NEW | HTTP_ADDHDR_FLAG_REQ);
if (dwContentLength || strcmpW(request->verb, szGET))
{
sprintfW(contentLengthStr, szContentLength, dwContentLength);
@ -4941,7 +4971,8 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
HTTP_FixURL(request);
if (request->hdr.dwFlags & INTERNET_FLAG_KEEP_CONNECTION)
{
HTTP_ProcessHeader(request, szConnection, szKeepAlive, HTTP_ADDHDR_FLAG_REQ | HTTP_ADDHDR_FLAG_REPLACE);
HTTP_ProcessHeader(request, szConnection, szKeepAlive,
HTTP_ADDHDR_FLAG_REQ | HTTP_ADDHDR_FLAG_REPLACE | HTTP_ADDHDR_FLAG_ADD);
}
HTTP_InsertAuthorization(request, request->authInfo, szAuthorization);
HTTP_InsertAuthorization(request, request->proxyAuthInfo, szProxy_Authorization);
@ -5089,7 +5120,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
dwBufferSize=2048;
if (request->status_code == HTTP_STATUS_DENIED)
{
WCHAR *host = get_host_header( request );
WCHAR *host = heap_strdupW( request->server->canon_host_port );
DWORD dwIndex = 0;
while (HTTP_HttpQueryInfoW(request,HTTP_QUERY_WWW_AUTHENTICATE,szAuthValue,&dwBufferSize,&dwIndex) == ERROR_SUCCESS)
{
@ -5830,8 +5861,8 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
session->password = heap_strdupW(lpszPassword);
session->hostPort = serverPort;
session->connect_timeout = hIC->connect_timeout;
session->send_timeout = INFINITE;
session->receive_timeout = INFINITE;
session->send_timeout = 0;
session->receive_timeout = 0;
/* Don't send a handle created callback if this handle was created with InternetOpenUrl */
if (!(session->hdr.dwInternalFlags & INET_OPENURL))
@ -5958,7 +5989,7 @@ static DWORD HTTP_GetResponseHeaders(http_request_t *request, INT *len)
/* Add status code */
HTTP_ProcessHeader(request, szStatus, status_code,
HTTP_ADDHDR_FLAG_REPLACE);
HTTP_ADDHDR_FLAG_REPLACE | HTTP_ADDHDR_FLAG_ADD);
heap_free(request->version);
heap_free(request->statusText);
@ -6075,34 +6106,112 @@ static LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer)
static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR value, DWORD dwModifier)
{
LPHTTPHEADERW lphttpHdr = NULL;
LPHTTPHEADERW lphttpHdr;
INT index;
BOOL request_only = dwModifier & HTTP_ADDHDR_FLAG_REQ;
DWORD res = ERROR_HTTP_INVALID_HEADER;
BOOL request_only = !!(dwModifier & HTTP_ADDHDR_FLAG_REQ);
DWORD res = ERROR_SUCCESS;
TRACE("--> %s: %s - 0x%08x\n", debugstr_w(field), debugstr_w(value), dwModifier);
EnterCriticalSection( &request->headers_section );
/* REPLACE wins out over ADD */
if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE)
dwModifier &= ~HTTP_ADDHDR_FLAG_ADD;
if (dwModifier & HTTP_ADDHDR_FLAG_ADD)
index = -1;
else
index = HTTP_GetCustomHeaderIndex(request, field, 0, request_only);
index = HTTP_GetCustomHeaderIndex(request, field, 0, request_only);
if (index >= 0)
{
lphttpHdr = &request->custHeaders[index];
/* replace existing header if FLAG_REPLACE is given */
if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE)
{
HTTP_DeleteCustomHeader( request, index );
if (value && value[0])
{
HTTPHEADERW hdr;
hdr.lpszField = (LPWSTR)field;
hdr.lpszValue = (LPWSTR)value;
hdr.wFlags = hdr.wCount = 0;
if (dwModifier & HTTP_ADDHDR_FLAG_REQ)
hdr.wFlags |= HDR_ISREQUEST;
res = HTTP_InsertCustomHeader( request, &hdr );
}
goto out;
}
/* do not add new header if FLAG_ADD_IF_NEW is set */
if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW)
{
LeaveCriticalSection( &request->headers_section );
return ERROR_HTTP_INVALID_HEADER;
res = ERROR_HTTP_INVALID_HEADER; /* FIXME */
goto out;
}
/* handle appending to existing header */
if (dwModifier & COALESCEFLAGS)
{
LPWSTR lpsztmp;
WCHAR ch = 0;
INT len = 0;
INT origlen = strlenW(lphttpHdr->lpszValue);
INT valuelen = strlenW(value);
/* FIXME: Should it really clear HDR_ISREQUEST? */
if (dwModifier & HTTP_ADDHDR_FLAG_REQ)
lphttpHdr->wFlags |= HDR_ISREQUEST;
else
lphttpHdr->wFlags &= ~HDR_ISREQUEST;
if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA)
{
ch = ',';
lphttpHdr->wFlags |= HDR_COMMADELIMITED;
}
else if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON)
{
ch = ';';
lphttpHdr->wFlags |= HDR_COMMADELIMITED;
}
len = origlen + valuelen + ((ch > 0) ? 2 : 0);
lpsztmp = heap_realloc(lphttpHdr->lpszValue, (len+1)*sizeof(WCHAR));
if (lpsztmp)
{
lphttpHdr->lpszValue = lpsztmp;
/* FIXME: Increment lphttpHdr->wCount. Perhaps lpszValue should be an array */
if (ch > 0)
{
lphttpHdr->lpszValue[origlen] = ch;
origlen++;
lphttpHdr->lpszValue[origlen] = ' ';
origlen++;
}
memcpy(&lphttpHdr->lpszValue[origlen], value, valuelen*sizeof(WCHAR));
lphttpHdr->lpszValue[len] = '\0';
}
else
{
WARN("heap_realloc (%d bytes) failed\n",len+1);
res = ERROR_OUTOFMEMORY;
}
goto out;
}
lphttpHdr = &request->custHeaders[index];
}
else if (value)
/* FIXME: What about other combinations? */
if ((dwModifier & ~HTTP_ADDHDR_FLAG_REQ) == HTTP_ADDHDR_FLAG_REPLACE)
{
res = ERROR_HTTP_HEADER_NOT_FOUND;
goto out;
}
/* FIXME: What if value == ""? */
if (value)
{
HTTPHEADERW hdr;
@ -6113,89 +6222,12 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR
if (dwModifier & HTTP_ADDHDR_FLAG_REQ)
hdr.wFlags |= HDR_ISREQUEST;
res = HTTP_InsertCustomHeader(request, &hdr);
LeaveCriticalSection( &request->headers_section );
return res;
}
/* no value to delete */
else
{
LeaveCriticalSection( &request->headers_section );
return ERROR_SUCCESS;
res = HTTP_InsertCustomHeader( request, &hdr );
goto out;
}
if (dwModifier & HTTP_ADDHDR_FLAG_REQ)
lphttpHdr->wFlags |= HDR_ISREQUEST;
else
lphttpHdr->wFlags &= ~HDR_ISREQUEST;
if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE)
{
HTTP_DeleteCustomHeader( request, index );
if (value && value[0])
{
HTTPHEADERW hdr;
hdr.lpszField = (LPWSTR)field;
hdr.lpszValue = (LPWSTR)value;
hdr.wFlags = hdr.wCount = 0;
if (dwModifier & HTTP_ADDHDR_FLAG_REQ)
hdr.wFlags |= HDR_ISREQUEST;
res = HTTP_InsertCustomHeader(request, &hdr);
LeaveCriticalSection( &request->headers_section );
return res;
}
LeaveCriticalSection( &request->headers_section );
return ERROR_SUCCESS;
}
else if (dwModifier & COALESCEFLAGS)
{
LPWSTR lpsztmp;
WCHAR ch = 0;
INT len = 0;
INT origlen = strlenW(lphttpHdr->lpszValue);
INT valuelen = strlenW(value);
if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA)
{
ch = ',';
lphttpHdr->wFlags |= HDR_COMMADELIMITED;
}
else if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON)
{
ch = ';';
lphttpHdr->wFlags |= HDR_COMMADELIMITED;
}
len = origlen + valuelen + ((ch > 0) ? 2 : 0);
lpsztmp = heap_realloc(lphttpHdr->lpszValue, (len+1)*sizeof(WCHAR));
if (lpsztmp)
{
lphttpHdr->lpszValue = lpsztmp;
/* FIXME: Increment lphttpHdr->wCount. Perhaps lpszValue should be an array */
if (ch > 0)
{
lphttpHdr->lpszValue[origlen] = ch;
origlen++;
lphttpHdr->lpszValue[origlen] = ' ';
origlen++;
}
memcpy(&lphttpHdr->lpszValue[origlen], value, valuelen*sizeof(WCHAR));
lphttpHdr->lpszValue[len] = '\0';
res = ERROR_SUCCESS;
}
else
{
WARN("heap_realloc (%d bytes) failed\n",len+1);
res = ERROR_OUTOFMEMORY;
}
}
/* FIXME: What if value == NULL? */
out:
TRACE("<-- %d\n", res);
LeaveCriticalSection( &request->headers_section );
return res;

View file

@ -711,7 +711,7 @@ static BOOL INTERNET_ConfigureProxy( appinfo_t *lpwai )
if (wpi.proxyEnabled)
{
TRACE("http proxy = %s bypass = %s\n", debugstr_w(lpwai->proxy), debugstr_w(lpwai->proxyBypass));
TRACE("http proxy = %s bypass = %s\n", debugstr_w(wpi.proxy), debugstr_w(wpi.proxyBypass));
lpwai->accessType = INTERNET_OPEN_TYPE_PROXY;
lpwai->proxy = wpi.proxy;

View file

@ -129,6 +129,7 @@ typedef struct
{
int socket;
BOOL secure;
BOOL is_blocking;
CtxtHandle ssl_ctx;
SecPkgContext_StreamSizes ssl_sizes;
server_t *server;
@ -416,7 +417,6 @@ typedef struct
CRITICAL_SECTION read_section; /* section to protect the following fields */
DWORD contentLength; /* total number of bytes to be read */
BOOL read_chunked; /* are we reading in chunked mode? */
BOOL read_gzip; /* are we reading in gzip mode? */
DWORD read_pos; /* current read position in read_buf */
DWORD read_size; /* valid data size in read_buf */
@ -477,29 +477,22 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
DWORD dwStatusInfoLength) DECLSPEC_HIDDEN;
BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen) DECLSPEC_HIDDEN;
typedef enum {
BLOCKING_ALLOW,
BLOCKING_DISALLOW,
BLOCKING_WAITALL
} blocking_mode_t;
DWORD create_netconn(BOOL,server_t*,DWORD,BOOL,DWORD,netconn_t**) DECLSPEC_HIDDEN;
void free_netconn(netconn_t*) DECLSPEC_HIDDEN;
void NETCON_unload(void) DECLSPEC_HIDDEN;
DWORD NETCON_secure_connect(netconn_t*,server_t*) DECLSPEC_HIDDEN;
DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
int *sent /* out */) DECLSPEC_HIDDEN;
DWORD NETCON_recv(netconn_t*,void*,size_t,blocking_mode_t,int*) DECLSPEC_HIDDEN;
DWORD NETCON_recv(netconn_t*,void*,size_t,BOOL,int*) DECLSPEC_HIDDEN;
BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available) DECLSPEC_HIDDEN;
BOOL NETCON_is_alive(netconn_t*) DECLSPEC_HIDDEN;
LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN;
int NETCON_GetCipherStrength(netconn_t*) DECLSPEC_HIDDEN;
DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC_HIDDEN;
int sock_get_error(void) DECLSPEC_HIDDEN;
int sock_send(int fd, const void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
int sock_recv(int fd, void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
server_t *get_server(const WCHAR*,INTERNET_PORT,BOOL,BOOL);
server_t *get_server(const WCHAR*,INTERNET_PORT,BOOL,BOOL) DECLSPEC_HIDDEN;
DWORD create_req_file(const WCHAR*,req_file_t**) DECLSPEC_HIDDEN;
void req_file_release(req_file_t*) DECLSPEC_HIDDEN;

View file

@ -273,10 +273,13 @@ void init_winsock(void)
InitOnceExecuteOnce(&init_once, winsock_startup, NULL, NULL);
}
static void set_socket_blocking(int socket, blocking_mode_t mode)
static void set_socket_blocking(netconn_t *conn, BOOL is_blocking)
{
ULONG arg = mode == BLOCKING_DISALLOW;
ioctlsocket(socket, FIONBIO, &arg);
if(conn->is_blocking != is_blocking) {
ULONG arg = !is_blocking;
ioctlsocket(conn->socket, FIONBIO, &arg);
}
conn->is_blocking = is_blocking;
}
static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD timeout)
@ -290,11 +293,11 @@ static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD t
assert(server->addr_len);
result = netconn->socket = socket(server->addr.ss_family, SOCK_STREAM, 0);
if(result != -1) {
set_socket_blocking(netconn->socket, BLOCKING_DISALLOW);
set_socket_blocking(netconn, FALSE);
result = connect(netconn->socket, (struct sockaddr*)&server->addr, server->addr_len);
if(result == -1)
{
res = sock_get_error();
res = WSAGetLastError();
if (res == WSAEINPROGRESS || res == WSAEWOULDBLOCK) {
FD_SET set;
int res;
@ -318,9 +321,6 @@ static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD t
closesocket(netconn->socket);
netconn->socket = -1;
}
else {
set_socket_blocking(netconn->socket, BLOCKING_ALLOW);
}
}
if(result == -1)
return ERROR_INTERNET_CANNOT_CONNECT;
@ -399,13 +399,8 @@ void NETCON_unload(void)
if(have_compat_cred_handle)
FreeCredentialsHandle(&compat_cred_handle);
DeleteCriticalSection(&init_sechandle_cs);
WSACleanup();
}
/* translate a unix error code into a winsock one */
int sock_get_error(void)
{
return WSAGetLastError();
if(winsock_loaded)
WSACleanup();
}
int sock_send(int fd, const void *msg, size_t len, int flags)
@ -415,7 +410,7 @@ int sock_send(int fd, const void *msg, size_t len, int flags)
{
ret = send(fd, msg, len, flags);
}
while(ret == -1 && sock_get_error() == WSAEINTR);
while(ret == -1 && WSAGetLastError() == WSAEINTR);
return ret;
}
@ -426,7 +421,7 @@ int sock_recv(int fd, void *msg, size_t len, int flags)
{
ret = recv(fd, msg, len, flags);
}
while(ret == -1 && sock_get_error() == WSAEINTR);
while(ret == -1 && WSAGetLastError() == WSAEINTR);
return ret;
}
@ -466,6 +461,8 @@ static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode
assert(status != SEC_E_OK);
set_socket_blocking(connection, TRUE);
while(status == SEC_I_CONTINUE_NEEDED || status == SEC_E_INCOMPLETE_MESSAGE) {
if(out_buf.cbBuffer) {
assert(status == SEC_I_CONTINUE_NEEDED);
@ -660,10 +657,13 @@ static BOOL send_ssl_chunk(netconn_t *conn, const void *msg, size_t size)
DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
int *sent /* out */)
{
/* send is always blocking. */
set_socket_blocking(connection, TRUE);
if(!connection->secure)
{
*sent = sock_send(connection->socket, msg, len, flags);
return *sent == -1 ? sock_get_error() : ERROR_SUCCESS;
return *sent == -1 ? WSAGetLastError() : ERROR_SUCCESS;
}
else
{
@ -686,22 +686,17 @@ DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
}
}
static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking_mode_t mode, SIZE_T *ret_size, BOOL *eof)
static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, BOOL blocking, SIZE_T *ret_size, BOOL *eof)
{
const SIZE_T ssl_buf_size = conn->ssl_sizes.cbHeader+conn->ssl_sizes.cbMaximumMessage+conn->ssl_sizes.cbTrailer;
SecBuffer bufs[4];
SecBufferDesc buf_desc = {SECBUFFER_VERSION, sizeof(bufs)/sizeof(*bufs), bufs};
SSIZE_T size, buf_len = 0;
blocking_mode_t tmp_mode;
int i;
SECURITY_STATUS res;
assert(conn->extra_len < ssl_buf_size);
/* BLOCKING_WAITALL is handled by caller */
if(mode == BLOCKING_WAITALL)
mode = BLOCKING_ALLOW;
if(conn->extra_len) {
memcpy(conn->ssl_buf, conn->extra_buf, conn->extra_len);
buf_len = conn->extra_len;
@ -710,12 +705,11 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking
conn->extra_buf = NULL;
}
tmp_mode = buf_len ? BLOCKING_DISALLOW : mode;
set_socket_blocking(conn->socket, tmp_mode);
set_socket_blocking(conn, blocking && !buf_len);
size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
if(size < 0) {
if(!buf_len) {
if(sock_get_error() == WSAEWOULDBLOCK) {
if(WSAGetLastError() == WSAEWOULDBLOCK) {
TRACE("would block\n");
return WSAEWOULDBLOCK;
}
@ -726,10 +720,10 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking
buf_len += size;
}
*ret_size = buf_len;
if(!buf_len) {
TRACE("EOF\n");
*eof = TRUE;
*ret_size = 0;
return ERROR_SUCCESS;
}
@ -752,10 +746,10 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking
case SEC_E_INCOMPLETE_MESSAGE:
assert(buf_len < ssl_buf_size);
set_socket_blocking(conn->socket, mode);
set_socket_blocking(conn, blocking);
size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
if(size < 1) {
if(size < 0 && sock_get_error() == WSAEWOULDBLOCK) {
if(size < 0 && WSAGetLastError() == WSAEWOULDBLOCK) {
TRACE("would block\n");
/* FIXME: Optimize extra_buf usage. */
@ -815,7 +809,7 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking
* Basically calls 'recv()' unless we should use SSL
* number of chars received is put in *recvd
*/
DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t mode, int *recvd)
DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, BOOL blocking, int *recvd)
{
*recvd = 0;
if (!len)
@ -823,18 +817,13 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t
if (!connection->secure)
{
int flags = 0;
if(mode == BLOCKING_WAITALL)
flags = MSG_WAITALL;
set_socket_blocking(connection->socket, mode);
*recvd = sock_recv(connection->socket, buf, len, flags);
return *recvd == -1 ? sock_get_error() : ERROR_SUCCESS;
set_socket_blocking(connection, blocking);
*recvd = sock_recv(connection->socket, buf, len, 0);
return *recvd == -1 ? WSAGetLastError() : ERROR_SUCCESS;
}
else
{
SIZE_T size = 0, cread;
SIZE_T size = 0;
BOOL eof;
DWORD res;
@ -848,17 +837,13 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t
heap_free(connection->peek_msg_mem);
connection->peek_msg_mem = connection->peek_msg = NULL;
}
/* check if we have enough data from the peek buffer */
if(mode != BLOCKING_WAITALL || size == len) {
*recvd = size;
return ERROR_SUCCESS;
}
mode = BLOCKING_DISALLOW;
*recvd = size;
return ERROR_SUCCESS;
}
do {
res = read_ssl_chunk(connection, (BYTE*)buf+size, len-size, mode, &cread, &eof);
res = read_ssl_chunk(connection, (BYTE*)buf, len, blocking, &size, &eof);
if(res != ERROR_SUCCESS) {
if(res == WSAEWOULDBLOCK) {
if(size)
@ -868,14 +853,7 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t
}
break;
}
if(eof) {
TRACE("EOF\n");
break;
}
size += cread;
}while(!size || (mode == BLOCKING_WAITALL && size < len));
}while(!size && !eof);
TRACE("received %ld bytes\n", size);
*recvd = size;
@ -914,11 +892,10 @@ BOOL NETCON_is_alive(netconn_t *netconn)
int len;
char b;
set_socket_blocking(netconn->socket, BLOCKING_DISALLOW);
set_socket_blocking(netconn, FALSE);
len = sock_recv(netconn->socket, &b, 1, MSG_PEEK);
set_socket_blocking(netconn->socket, BLOCKING_ALLOW);
return len == 1 || (len == -1 && sock_get_error() == WSAEWOULDBLOCK);
return len == 1 || (len == -1 && WSAGetLastError() == WSAEWOULDBLOCK);
}
LPCVOID NETCON_GetCert(netconn_t *connection)
@ -947,26 +924,14 @@ int NETCON_GetCipherStrength(netconn_t *connection)
DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value)
{
int result;
struct timeval tv;
/* value is in milliseconds, convert to struct timeval */
if (value == INFINITE)
{
tv.tv_sec = 0;
tv.tv_usec = 0;
}
else
{
tv.tv_sec = value / 1000;
tv.tv_usec = (value % 1000) * 1000;
}
result = setsockopt(connection->socket, SOL_SOCKET,
send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv,
sizeof(tv));
send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&value,
sizeof(value));
if (result == -1)
{
WARN("setsockopt failed\n");
return sock_get_error();
return WSAGetLastError();
}
return ERROR_SUCCESS;
}

View file

@ -975,7 +975,8 @@ static BOOL urlcache_create_file_pathW(
LPCSTR szLocalFileName,
BYTE Directory,
LPWSTR wszPath,
LPLONG lpBufferSize)
LPLONG lpBufferSize,
BOOL trunc_name)
{
LONG nRequired;
int path_len = strlenW(pContainer->path);
@ -989,6 +990,8 @@ static BOOL urlcache_create_file_pathW(
nRequired = (path_len + file_name_len) * sizeof(WCHAR);
if(Directory != CACHE_CONTAINER_NO_SUBDIR)
nRequired += (DIR_LENGTH + 1) * sizeof(WCHAR);
if (trunc_name && nRequired >= *lpBufferSize)
nRequired = *lpBufferSize;
if (nRequired <= *lpBufferSize)
{
int dir_len;
@ -1004,7 +1007,9 @@ static BOOL urlcache_create_file_pathW(
{
dir_len = 0;
}
MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, wszPath + dir_len + path_len, file_name_len);
MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, wszPath + dir_len + path_len,
*lpBufferSize/sizeof(WCHAR)-dir_len-path_len);
wszPath[*lpBufferSize/sizeof(WCHAR)-1] = 0;
*lpBufferSize = nRequired;
return TRUE;
}
@ -1093,7 +1098,7 @@ static DWORD urlcache_delete_file(const cache_container *container,
if(!urlcache_create_file_pathW(container, header,
(LPCSTR)url_entry+url_entry->local_name_off,
url_entry->cache_dir, path, &path_size))
url_entry->cache_dir, path, &path_size, FALSE))
goto succ;
if(!GetFileAttributesExW(path, GetFileExInfoStandard, &attr))
@ -1291,9 +1296,6 @@ static DWORD urlcache_copy_entry(cache_container *container, const urlcache_head
dos_date_time_to_file_time(url_entry->sync_date, url_entry->sync_time, &entry_info->LastSyncTime);
}
if(size%4 && size<*info_size)
ZeroMemory((LPBYTE)entry_info+size, 4-size%4);
size = DWORD_ALIGN(size);
if(unicode)
url_len = urlcache_decode_url((const char*)url_entry+url_entry->url_off, NULL, 0);
else
@ -1319,8 +1321,10 @@ static DWORD urlcache_copy_entry(cache_container *container, const urlcache_head
LPSTR file_name;
file_name = (LPSTR)entry_info+size;
file_name_size = *info_size-size;
if((unicode && urlcache_create_file_pathW(container, header, (LPCSTR)url_entry+url_entry->local_name_off, url_entry->cache_dir, (LPWSTR)file_name, &file_name_size)) ||
(!unicode && urlcache_create_file_pathA(container, header, (LPCSTR)url_entry+url_entry->local_name_off, url_entry->cache_dir, file_name, &file_name_size))) {
if((unicode && urlcache_create_file_pathW(container, header, (LPCSTR)url_entry+url_entry->local_name_off,
url_entry->cache_dir, (LPWSTR)file_name, &file_name_size, FALSE)) ||
(!unicode && urlcache_create_file_pathA(container, header, (LPCSTR)url_entry+url_entry->local_name_off,
url_entry->cache_dir, file_name, &file_name_size))) {
entry_info->lpszLocalFileName = file_name;
}
size += file_name_size;
@ -2612,7 +2616,7 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
char file_name[MAX_PATH];
WCHAR extW[MAX_PATH];
BYTE cache_dir;
LONG full_path_len;
LONG full_path_len, ext_len = 0;
BOOL generate_name = FALSE;
DWORD error;
HANDLE file;
@ -2643,6 +2647,8 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
p--;
}
if(e-p >= MAX_PATH)
e = p+MAX_PATH-1;
memcpy(file_name, p, e-p);
file_name[e-p] = 0;
@ -2682,7 +2688,7 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
cache_dir = CACHE_CONTAINER_NO_SUBDIR;
full_path_len = MAX_PATH * sizeof(WCHAR);
if(!urlcache_create_file_pathW(container, header, file_name, cache_dir, full_path, &full_path_len)) {
if(!urlcache_create_file_pathW(container, header, file_name, cache_dir, full_path, &full_path_len, TRUE)) {
WARN("Failed to get full path for filename %s, needed %u bytes.\n",
debugstr_a(file_name), full_path_len);
cache_container_unlock_index(container, header);
@ -2696,7 +2702,7 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
WCHAR *p;
extW[0] = '.';
MultiByteToWideChar(CP_ACP, 0, ext, -1, extW+1, MAX_PATH-1);
ext_len = MultiByteToWideChar(CP_ACP, 0, ext, -1, extW+1, MAX_PATH-1);
for(p=extW; *p; p++) {
switch(*p) {
@ -2714,6 +2720,10 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
extW[0] = '\0';
}
if(!generate_name && full_path_len+5+ext_len>=MAX_PATH) { /* strlen("[255]") = 5 */
full_path_len = MAX_PATH-5-ext_len-1;
}
for(i=0; i<255 && !generate_name; i++) {
static const WCHAR format[] = {'[','%','u',']','%','s',0};
@ -2727,6 +2737,9 @@ static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_
}
}
if(full_path_len+8+ext_len >= MAX_PATH)
full_path_len = MAX_PATH-8-ext_len-1;
/* Try to generate random name */
GetSystemTimeAsFileTime(&ft);
strcpyW(full_path+full_path_len+8, extW);

View file

@ -216,7 +216,7 @@
@ stdcall IsUrlCacheEntryExpiredA(str long ptr)
@ stdcall IsUrlCacheEntryExpiredW(wstr long ptr)
@ stdcall LoadUrlCacheContent()
@ stub ParseX509EncodedCertificateForListBoxEntry
@ stdcall ParseX509EncodedCertificateForListBoxEntry(ptr long str ptr)
@ stdcall PrivacyGetZonePreferenceW(long long ptr ptr ptr)
@ stdcall PrivacySetZonePreferenceW(long long long wstr)
@ stdcall ReadUrlCacheEntryStream(ptr long ptr ptr long)

View file

@ -1,73 +1,15 @@
diff -prudN e:\Wine\dlls\wininet/cookie.c e:\reactos-clean\dll\win32\wininet/cookie.c
--- e:\Wine\dlls\wininet/cookie.c 2013-03-02 14:18:01.994544800 +0100
+++ e:\reactos-clean\dll\win32\wininet/cookie.c 2013-05-20 20:45:34.175815800 +0100
@@ -250,6 +254,7 @@ static BOOL save_persistent_cookie(cooki
BOOL do_save = FALSE;
char buf[64], *dyn_buf;
FILETIME time;
+ DWORD dwBytesWritten;
diff -pudN e:\wine\dlls\wininet/http.c e:\reactos\dll\win32\wininet/http.c
--- e:\wine\dlls\wininet/http.c 2015-07-14 15:44:36.040192300 +0100
+++ e:\reactos\dll\win32\wininet/http.c 2015-07-20 14:37:24.319646400 +0100
@@ -143,6 +118,7 @@ static const WCHAR emptyW[] = {0};
if (!create_cookie_url(domain->lpCookieDomain, domain->lpCookiePath, cookie_url, sizeof(cookie_url)/sizeof(cookie_url[0])))
return FALSE;
@@ -288,31 +293,31 @@ static BOOL save_persistent_cookie(cooki
continue;
#define COLLECT_TIME 60000
dyn_buf = heap_strdupWtoA(cookie_container->lpCookieName);
- if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), NULL, NULL)) {
+ if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &dwBytesWritten, NULL)) {
heap_free(dyn_buf);
do_save = FALSE;
break;
}
heap_free(dyn_buf);
- if(!WriteFile(cookie_handle, "\n", 1, NULL, NULL)) {
+ if(!WriteFile(cookie_handle, "\n", 1, &dwBytesWritten, NULL)) {
do_save = FALSE;
break;
}
+#undef ARRAYSIZE
#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
dyn_buf = heap_strdupWtoA(cookie_container->lpCookieData);
- if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), NULL, NULL)) {
+ if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &dwBytesWritten, NULL)) {
heap_free(dyn_buf);
do_save = FALSE;
break;
}
heap_free(dyn_buf);
- if(!WriteFile(cookie_handle, "\n", 1, NULL, NULL)) {
+ if(!WriteFile(cookie_handle, "\n", 1, &dwBytesWritten, NULL)) {
do_save = FALSE;
break;
}
dyn_buf = heap_strdupWtoA(domain->lpCookieDomain);
- if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), NULL, NULL)) {
+ if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &dwBytesWritten, NULL)) {
heap_free(dyn_buf);
do_save = FALSE;
break;
@@ -320,7 +325,7 @@ static BOOL save_persistent_cookie(cooki
heap_free(dyn_buf);
dyn_buf = heap_strdupWtoA(domain->lpCookiePath);
- if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), NULL, NULL)) {
+ if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &dwBytesWritten, NULL)) {
heap_free(dyn_buf);
do_save = FALSE;
break;
@@ -330,7 +335,7 @@ static BOOL save_persistent_cookie(cooki
sprintf(buf, "\n%u\n%u\n%u\n%u\n%u\n*\n", cookie_container->flags,
cookie_container->expiry.dwLowDateTime, cookie_container->expiry.dwHighDateTime,
cookie_container->create.dwLowDateTime, cookie_container->create.dwHighDateTime);
- if(!WriteFile(cookie_handle, buf, strlen(buf), NULL, NULL)) {
+ if(!WriteFile(cookie_handle, buf, strlen(buf), &dwBytesWritten, NULL)) {
do_save = FALSE;
break;
}
diff -prudN e:\Wine\dlls\wininet/http.c e:\reactos-clean\dll\win32\wininet/http.c
--- e:\Wine\dlls\wininet/http.c 2013-03-16 11:54:52.608610100 +0100
+++ e:\reactos-clean\dll\win32\wininet/http.c 2013-05-20 16:36:21.826074500 +0100
@@ -242,7 +249,13 @@ void server_release(server_t *server)
struct HttpAuthInfo
@@ -229,7 +205,13 @@ void server_release(server_t *server)
if(InterlockedDecrement(&server->ref))
return;
@ -81,17 +23,20 @@ diff -prudN e:\Wine\dlls\wininet/http.c e:\reactos-clean\dll\win32\wininet/http.
if(server->cert_chain)
CertFreeCertificateChain(server->cert_chain);
@@ -324,7 +337,7 @@ BOOL collect_connections(collect_type_t
@@ -311,7 +293,11 @@ BOOL collect_connections(collect_type_t
BOOL remaining = FALSE;
DWORD64 now;
- now = GetTickCount64();
+#ifdef __REACTOS__
+ now = GetTickCount();
+#else
now = GetTickCount64();
+#endif
LIST_FOR_EACH_ENTRY_SAFE(server, server_safe, &connection_pool, server_t, entry) {
LIST_FOR_EACH_ENTRY_SAFE(netconn, netconn_safe, &server->conn_pool, netconn_t, pool_entry) {
@@ -1870,13 +1883,14 @@ static void http_release_netconn(http_re
if(!req->netconn)
@@ -1973,13 +1959,14 @@ static void http_release_netconn(http_re
if(!is_valid_netconn(req->netconn))
return;
+#ifndef __REACTOS__
@ -106,185 +51,57 @@ diff -prudN e:\Wine\dlls\wininet/http.c e:\reactos-clean\dll\win32\wininet/http.
req->netconn = NULL;
run_collector = !collector_running;
@@ -1904,6 +1918,10 @@ static void http_release_netconn(http_re
@@ -2007,6 +1994,10 @@ static void http_release_netconn(http_re
}
return;
}
+#else
+ // silence unused function warning
+ /* Silence unused function warning */
+ (void)collect_connections_proc;
+#endif
INTERNET_SendCallback(&req->hdr, req->hdr.dwContext,
INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
diff -prudN e:\Wine\dlls\wininet/internet.c e:\reactos-clean\dll\win32\wininet/internet.c
--- e:\Wine\dlls\wininet/internet.c 2013-03-16 11:54:52.609610800 +0100
+++ e:\reactos-clean\dll\win32\wininet/internet.c 2013-05-20 16:43:55.864085500 +0100
@@ -292,11 +297,9 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL,
if (g_dwTlsErrIndex == TLS_OUT_OF_INDEXES)
return FALSE;
- if(!init_urlcache())
- {
- TlsFree(g_dwTlsErrIndex);
- return FALSE;
- }
+#ifndef __REACTOS__
+ URLCacheContainers_CreateDefaults();
+#endif
WININET_hModule = hinstDLL;
break;
@@ -750,6 +753,9 @@ static VOID APPINFO_Destroy(object_heade
heap_free(lpwai->proxyBypass);
heap_free(lpwai->proxyUsername);
heap_free(lpwai->proxyPassword);
+#ifdef __REACTOS__
+ WSACleanup();
+#endif
}
static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
@@ -945,6 +951,11 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR l
LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags)
diff -pudN e:\wine\dlls\wininet/internet.c e:\reactos\dll\win32\wininet/internet.c
--- e:\wine\dlls\wininet/internet.c 2015-04-12 18:21:54.309796800 +0100
+++ e:\reactos\dll\win32\wininet/internet.c 2015-07-20 14:38:19.188784800 +0100
@@ -1033,6 +996,9 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR l
{
appinfo_t *lpwai = NULL;
+#ifdef __REACTOS__
+ WSADATA wsaData;
+ int error = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (error) ERR("WSAStartup failed: %d\n", error);
+#endif
+#ifdef __REACTOS__
+ init_winsock();
+#endif
if (TRACE_ON(wininet)) {
#define FE(x) { x, #x }
@@ -3759,19 +3770,23 @@ LPSTR INTERNET_GetResponseBuffer(void)
LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen)
{
- struct pollfd pfd;
+ // ReactOS: use select instead of poll
+ fd_set infd;
+ struct timeval tv;
BOOL bSuccess = FALSE;
INT nRecv = 0;
LPSTR lpszBuffer = INTERNET_GetResponseBuffer();
TRACE("\n");
- pfd.fd = nSocket;
- pfd.events = POLLIN;
+ FD_ZERO(&infd);
+ FD_SET(nSocket,&infd);
+ tv.tv_sec = RESPONSE_TIMEOUT;
+ tv.tv_usec = 0;
while (nRecv < MAX_REPLY_LEN)
{
- if (poll(&pfd,1, RESPONSE_TIMEOUT * 1000) > 0)
+ if (select(0, &infd, NULL, NULL, &tv) > 0)
{
if (recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0)
{
diff -prudN e:\Wine\dlls\wininet/internet.h e:\reactos-clean\dll\win32\wininet/internet.h
--- e:\Wine\dlls\wininet/internet.h 2013-03-02 14:18:02.010553900 +0100
+++ e:\reactos-clean\dll\win32\wininet/internet.h 2013-05-20 17:12:12.531037400 +0100
@@ -419,7 +419,30 @@ BOOL NETCON_is_alive(netconn_t*) DECLSPE
LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN;
int NETCON_GetCipherStrength(netconn_t*) DECLSPEC_HIDDEN;
DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC_HIDDEN;
+#ifndef __REACTOS__
int sock_get_error(int) DECLSPEC_HIDDEN;
+#else
+#define sock_get_error(x) WSAGetLastError()
+const char *inet_ntop(int, const void *, char *, socklen_t);
+
+static inline long unix_recv(int socket, void *buffer, size_t length, int flags)
+{
+ return recv(socket, buffer, length, flags);
+}
+#define recv unix_recv
+
+static inline int unix_ioctl(int filedes, long request, void *arg)
+{
+ return ioctlsocket(filedes, request, arg);
+}
+#define ioctlsocket unix_ioctl
+
+static inline int unix_getsockopt(int socket, int level, int option_name, void *option_value, socklen_t *option_len)
+{
+ return getsockopt(socket, level, option_name, option_value, option_len);
+}
+#define getsockopt unix_getsockopt
+#endif
server_t *get_server(const WCHAR*,INTERNET_PORT,BOOL,BOOL);
diff -prudN e:\Wine\dlls\wininet/netconnection.c e:\reactos-clean\dll\win32\wininet/netconnection.c
--- e:\Wine\dlls\wininet/netconnection.c 2013-03-16 11:54:52.610611400 +0100
+++ e:\reactos-clean\dll\win32\wininet/netconnection.c 2013-05-20 17:12:51.246334100 +0100
@@ -619,12 +624,16 @@ static DWORD create_netconn_socket(serve
if(result == -1)
{
if (sock_get_error(errno) == WSAEINPROGRESS) {
- struct pollfd pfd;
+ // ReactOS: use select instead of poll
+ fd_set outfd;
+ struct timeval tv;
int res;
- pfd.fd = netconn->socket;
- pfd.events = POLLOUT;
- res = poll(&pfd, 1, timeout);
+ FD_ZERO(&outfd);
+ FD_SET(netconn->socket, &outfd);
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ res = select(0, NULL, &outfd, NULL, &tv);
if (!res)
{
closesocket(netconn->socket);
@@ -741,6 +750,7 @@ void NETCON_unload(void)
#endif
}
+#ifndef __REACTOS__
/* translate a unix error code into a winsock one */
int sock_get_error( int err )
{
@@ -807,6 +817,7 @@ int sock_get_error( int err )
#endif
return err;
}
+#endif
#ifdef SONAME_LIBSSL
static DWORD netcon_secure_connect_setup(netconn_t *connection, long tls_option)
diff -prudN e:\Wine\dlls\wininet/urlcache.c e:\reactos-clean\dll\win32\wininet/urlcache.c
--- e:\Wine\dlls\wininet/urlcache.c 2013-03-16 11:54:52.613613400 +0100
+++ e:\reactos-clean\dll\win32\wininet/urlcache.c 2013-05-20 17:05:34.969949600 +0100
@@ -201,6 +205,8 @@ typedef struct _URLCACHECONTAINER
static const wininet_flag_info access_type[] = {
diff -pudN e:\wine\dlls\wininet/urlcache.c e:\reactos\dll\win32\wininet/urlcache.c
--- e:\wine\dlls\wininet/urlcache.c 2015-07-14 15:44:36.059193400 +0100
+++ e:\reactos\dll\win32\wininet/urlcache.c 2015-07-20 14:40:55.736738800 +0100
@@ -202,6 +179,8 @@ typedef struct
/* List of all containers available */
static struct list UrlContainers = LIST_INIT(UrlContainers);
+// ReactOS r54992
+/* ReactOS r54992 */
+BOOL bDefaultContainersAdded = FALSE;
static DWORD URLCache_CreateHashTable(LPURLCACHE_HEADER pHeader, HASH_CACHEFILE_ENTRY *pPrevHash, HASH_CACHEFILE_ENTRY **ppHash);
@@ -587,6 +593,8 @@ static void URLCacheContainers_CreateDef
static const WCHAR HistoryPrefix[] = {'V','i','s','i','t','e','d',':',0};
static inline char *heap_strdupWtoUTF8(LPCWSTR str)
{
@@ -752,6 +731,8 @@ static void cache_containers_init(void)
static const WCHAR UrlSuffix[] = {'C','o','n','t','e','n','t','.','I','E','5',0};
static const WCHAR HistorySuffix[] = {'H','i','s','t','o','r','y','.','I','E','5',0};
static const WCHAR CookieSuffix[] = {0};
static const WCHAR CookiePrefix[] = {'C','o','o','k','i','e',':',0};
+ // ReactOS r50916
+ /* ReactOS r50916 */
+ static const WCHAR UserProfile[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
static const struct
{
int nFolder; /* CSIDL_* constant */
@@ -601,6 +609,13 @@ static void URLCacheContainers_CreateDef
@@ -766,6 +747,13 @@ static void cache_containers_init(void)
};
DWORD i;
+ // ReactOS r50916
+ /* ReactOS r50916 */
+ if (GetEnvironmentVariableW(UserProfile, NULL, 0) == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)
+ {
+ TRACE("Environment variable 'USERPROFILE' does not exist!\n");
@ -294,25 +111,25 @@ diff -prudN e:\Wine\dlls\wininet/urlcache.c e:\reactos-clean\dll\win32\wininet/u
for (i = 0; i < sizeof(DefaultContainerData) / sizeof(DefaultContainerData[0]); i++)
{
WCHAR wszCachePath[MAX_PATH];
@@ -655,6 +670,10 @@ static DWORD URLCacheContainers_FindCont
if(!lpwszUrl)
@@ -835,6 +823,10 @@ static DWORD cache_containers_find(const
if(!url)
return ERROR_INVALID_PARAMETER;
+ // ReactOS r54992
+ /* ReactOS r54992 */
+ if (!bDefaultContainersAdded)
+ URLCacheContainers_CreateDefaults();
+ cache_containers_init();
+
LIST_FOR_EACH_ENTRY(pContainer, &UrlContainers, URLCACHECONTAINER, entry)
LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
{
int prefix_len = strlenW(pContainer->cache_prefix);
@@ -693,6 +712,10 @@ static BOOL URLCacheContainers_Enum(LPCW
if (lpwszSearchPattern && dwIndex > 0)
int prefix_len = strlen(container->cache_prefix);
@@ -861,6 +853,10 @@ static BOOL cache_containers_enum(char *
if (search_pattern && index > 0)
return FALSE;
+ // ReactOS r54992
+ /* ReactOS r54992 */
+ if (!bDefaultContainersAdded)
+ URLCacheContainers_CreateDefaults();
+ cache_containers_init();
+
LIST_FOR_EACH_ENTRY(pContainer, &UrlContainers, URLCACHECONTAINER, entry)
LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
{
if (lpwszSearchPattern)
if (search_pattern)

View file

@ -207,7 +207,7 @@ reactos/dll/win32/windowscodecsext # Synced to WineStaging-1.7.37
reactos/dll/win32/winemp3.acm # Synced to WineStaging-1.7.47
reactos/dll/win32/wing32 # Out of sync
reactos/dll/win32/winhttp # Synced to WineStaging-1.7.47
reactos/dll/win32/wininet # Synced to WineStaging-1.7.37
reactos/dll/win32/wininet # Synced to WineStaging-1.7.47
reactos/dll/win32/winmm # Forked at Wine-20050628
reactos/dll/win32/winmm/midimap # Forked at Wine-20050628
reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628