From 4d912f865f69cc87eeff8d7314794aa6f4ec2933 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 22 Apr 2015 08:30:31 +0000 Subject: [PATCH] [WININET] Sync with Wine Staging 1.7.37. CORE-9246 svn path=/trunk/; revision=67343 --- reactos/dll/win32/wininet/CMakeLists.txt | 5 +- reactos/dll/win32/wininet/cookie.c | 1 - reactos/dll/win32/wininet/ftp.c | 118 ++++++++-- reactos/dll/win32/wininet/http.c | 264 ++++++++++++++-------- reactos/dll/win32/wininet/internet.c | 100 ++------ reactos/dll/win32/wininet/internet.h | 39 +--- reactos/dll/win32/wininet/netconnection.c | 228 ++++++------------- reactos/dll/win32/wininet/urlcache.c | 8 - reactos/dll/win32/wininet/utility.c | 96 ++------ reactos/media/doc/README.WINE | 2 +- 10 files changed, 383 insertions(+), 478 deletions(-) diff --git a/reactos/dll/win32/wininet/CMakeLists.txt b/reactos/dll/win32/wininet/CMakeLists.txt index 7f968a8eddb..8c7e0cba460 100644 --- a/reactos/dll/win32/wininet/CMakeLists.txt +++ b/reactos/dll/win32/wininet/CMakeLists.txt @@ -1,4 +1,7 @@ +remove_definitions(-DWINVER=0x502) +add_definitions(-DWINVER=0x600) + add_definitions( -D__WINESRC__ -D_WINE @@ -30,6 +33,6 @@ add_library(wininet SHARED set_module_type(wininet win32dll) target_link_libraries(wininet wine ${PSEH_LIB} zlib) add_delay_importlibs(wininet secur32 crypt32 cryptui) -add_importlibs(wininet mpr shlwapi shell32 user32 advapi32 ws2_32 msvcrt kernel32 ntdll) +add_importlibs(wininet mpr shlwapi shell32 user32 advapi32 ws2_32 kernel32_vista msvcrt kernel32 ntdll) add_pch(wininet internet.h SOURCE) add_cd_file(TARGET wininet DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/win32/wininet/cookie.c b/reactos/dll/win32/wininet/cookie.c index ddbc92a1c22..2b24108e0c0 100644 --- a/reactos/dll/win32/wininet/cookie.c +++ b/reactos/dll/win32/wininet/cookie.c @@ -342,7 +342,6 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path) *pend = 0; data = heap_strdupAtoW(pbeg); - pbeg = pend+1; pbeg = strchr(pend+1, '\n'); if(!pbeg) break; diff --git a/reactos/dll/win32/wininet/ftp.c b/reactos/dll/win32/wininet/ftp.c index d3b97a9bf74..23dfecbbc3e 100644 --- a/reactos/dll/win32/wininet/ftp.c +++ b/reactos/dll/win32/wininet/ftp.c @@ -29,6 +29,8 @@ #include "internet.h" +#define RESPONSE_TIMEOUT 30 + typedef struct _ftp_session_t ftp_session_t; typedef struct @@ -789,6 +791,7 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs, INT nResCode; appinfo_t *hIC = NULL; HINTERNET hFindNext = NULL; + LPWSTR lpszSearchPath = NULL; TRACE("\n"); @@ -804,7 +807,20 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs, if (!FTP_SendPortOrPasv(lpwfs)) goto lend; - if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, NULL, + /* split search path into file and path */ + if (lpszSearchFile) + { + LPCWSTR name = lpszSearchFile, p; + if ((p = strrchrW( name, '\\' ))) name = p + 1; + if ((p = strrchrW( name, '/' ))) name = p + 1; + if (name != lpszSearchFile) + { + lpszSearchPath = heap_strndupW(lpszSearchFile, name - lpszSearchFile); + lpszSearchFile = name; + } + } + + if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, lpszSearchPath, lpwfs->hdr.lpfnStatusCB, &lpwfs->hdr, lpwfs->hdr.dwContext)) goto lend; @@ -830,6 +846,8 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs, } lend: + heap_free(lpszSearchPath); + if (lpwfs->lstnSocket != -1) { closesocket(lpwfs->lstnSocket); @@ -1181,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(errno); + return res >= 0 ? ERROR_SUCCESS : sock_get_error(); } static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif) @@ -1216,17 +1234,14 @@ static void FTPFILE_AsyncQueryDataAvailableProc(task_header_t *task) static DWORD FTPFILE_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx) { ftp_file_t *file = (ftp_file_t*) hdr; - int retval, unread = 0; + ULONG unread = 0; + int retval; 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; @@ -2328,11 +2343,11 @@ static void FTPSESSION_CloseConnection(object_header_t *hdr) if (lpwfs->download_in_progress != NULL) lpwfs->download_in_progress->session_deleted = TRUE; - if (lpwfs->sndSocket != -1) - closesocket(lpwfs->sndSocket); + if (lpwfs->sndSocket != -1) + closesocket(lpwfs->sndSocket); - if (lpwfs->lstnSocket != -1) - closesocket(lpwfs->lstnSocket); + if (lpwfs->lstnSocket != -1) + closesocket(lpwfs->lstnSocket); if (lpwfs->pasvSocket != -1) closesocket(lpwfs->pasvSocket); @@ -2409,7 +2424,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, socklen_t sock_namelen; BOOL bSuccess = FALSE; ftp_session_t *lpwfs = NULL; - char szaddr[INET_ADDRSTRLEN]; + char szaddr[INET6_ADDRSTRLEN]; TRACE("%p Server(%s) Port(%d) User(%s) Paswd(%s)\n", hIC, debugstr_w(lpszServerName), @@ -2454,7 +2469,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, if(hIC->proxyBypass) FIXME("Proxy bypass is ignored.\n"); } - if (!lpszUserName || !strlenW(lpszUserName)) { + if (!lpszUserName || !lpszUserName[0]) { HKEY key; WCHAR szPassword[MAX_PATH]; DWORD len = sizeof(szPassword); @@ -2497,7 +2512,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, (LPWSTR) lpszServerName, (strlenW(lpszServerName)+1) * sizeof(WCHAR)); sock_namelen = sizeof(socketAddr); - if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen)) + if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen, szaddr)) { INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); goto lerror; @@ -2510,10 +2525,10 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, goto lerror; } - inet_ntop(socketAddr.sin_family, &socketAddr.sin_addr, szaddr, sizeof(szaddr)); SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED, szaddr, strlen(szaddr)+1); + init_winsock(); nsocket = socket(AF_INET,SOCK_STREAM,0); if (nsocket == -1) { @@ -2526,7 +2541,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, if (connect(nsocket, (struct sockaddr *)&socketAddr, sock_namelen) < 0) { - ERR("Unable to connect (%s)\n", strerror(errno)); + ERR("Unable to connect (%d)\n", sock_get_error()); INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT); closesocket(nsocket); } @@ -2601,6 +2616,58 @@ lend: return bSuccess; } +/*********************************************************************** + * FTP_GetNextLine (internal) + * + * Parse next line in directory string listing + * + * RETURNS + * Pointer to beginning of next line + * NULL on failure + * + */ + +static LPSTR FTP_GetNextLine(INT nSocket, LPDWORD dwLen) +{ + struct timeval tv = {RESPONSE_TIMEOUT,0}; + FD_SET set; + INT nRecv = 0; + LPSTR lpszBuffer = INTERNET_GetResponseBuffer(); + + TRACE("\n"); + + FD_ZERO(&set); + FD_SET(nSocket, &set); + + while (nRecv < MAX_REPLY_LEN) + { + if (select(nSocket+1, &set, NULL, NULL, &tv) > 0) + { + if (sock_recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0) + { + INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS); + return NULL; + } + + if (lpszBuffer[nRecv] == '\n') + { + lpszBuffer[nRecv] = '\0'; + *dwLen = nRecv - 1; + TRACE(":%d %s\n", nRecv, lpszBuffer); + return lpszBuffer; + } + if (lpszBuffer[nRecv] != '\r') + nRecv++; + } + else + { + INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT); + return NULL; + } + } + + return NULL; +} /*********************************************************************** * FTP_SendCommandA (internal) @@ -2700,7 +2767,7 @@ INT FTP_ReceiveResponse(ftp_session_t *lpwfs, DWORD_PTR dwContext) while(1) { - if (!INTERNET_GetNextLine(lpwfs->sndSocket, &nRecv)) + if (!FTP_GetNextLine(lpwfs->sndSocket, &nRecv)) goto lerror; if (nRecv >= 3) @@ -2873,7 +2940,8 @@ static BOOL FTP_InitListenSocket(ftp_session_t *lpwfs) TRACE("\n"); - lpwfs->lstnSocket = socket(PF_INET, SOCK_STREAM, 0); + init_winsock(); + lpwfs->lstnSocket = socket(AF_INET, SOCK_STREAM, 0); if (lpwfs->lstnSocket == -1) { TRACE("Unable to create listening socket\n"); @@ -3016,10 +3084,10 @@ static BOOL FTP_SendPort(ftp_session_t *lpwfs) TRACE("\n"); sprintfW(szIPAddress, szIPFormat, - lpwfs->lstnSocketAddress.sin_addr.s_addr&0x000000FF, - (lpwfs->lstnSocketAddress.sin_addr.s_addr&0x0000FF00)>>8, - (lpwfs->lstnSocketAddress.sin_addr.s_addr&0x00FF0000)>>16, - (lpwfs->lstnSocketAddress.sin_addr.s_addr&0xFF000000)>>24, + lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x000000FF, + (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x0000FF00)>>8, + (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x00FF0000)>>16, + (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0xFF000000)>>24, lpwfs->lstnSocketAddress.sin_port & 0xFF, (lpwfs->lstnSocketAddress.sin_port & 0xFF00)>>8); @@ -3092,7 +3160,7 @@ static BOOL FTP_DoPassive(ftp_session_t *lpwfs) f[i] = f[i] & 0xff; dataSocketAddress = lpwfs->socketAddress; - pAddr = (char *)&(dataSocketAddress.sin_addr.s_addr); + pAddr = (char *)&(dataSocketAddress.sin_addr.S_un.S_addr); pPort = (char *)&(dataSocketAddress.sin_port); pAddr[0] = f[0]; pAddr[1] = f[1]; @@ -3155,7 +3223,7 @@ static BOOL FTP_SendPortOrPasv(ftp_session_t *lpwfs) static BOOL FTP_GetDataSocket(ftp_session_t *lpwfs, LPINT nDataSocket) { struct sockaddr_in saddr; - socklen_t addrlen = sizeof(struct sockaddr); + socklen_t addrlen = sizeof(saddr); TRACE("\n"); if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE) @@ -3559,7 +3627,7 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT lpfp->lpszName = NULL; do { - if(!(pszLine = INTERNET_GetNextLine(nSocket, &nBufLen))) + if(!(pszLine = FTP_GetNextLine(nSocket, &nBufLen))) return FALSE; pszToken = strtok(pszLine, szSpace); diff --git a/reactos/dll/win32/wininet/http.c b/reactos/dll/win32/wininet/http.c index e472d3ecbe6..2341914d793 100644 --- a/reactos/dll/win32/wininet/http.c +++ b/reactos/dll/win32/wininet/http.c @@ -37,13 +37,9 @@ #include -// ReactOS -#include "inet_ntop.c" - static const WCHAR g_szHttp1_0[] = {'H','T','T','P','/','1','.','0',0}; static const WCHAR g_szHttp1_1[] = {'H','T','T','P','/','1','.','1',0}; static const WCHAR szOK[] = {'O','K',0}; -static const WCHAR szDefaultHeader[] = {'H','T','T','P','/','1','.','0',' ','2','0','0',' ','O','K',0}; static const WCHAR hostW[] = { 'H','o','s','t',0 }; static const WCHAR szAuthorization[] = { 'A','u','t','h','o','r','i','z','a','t','i','o','n',0 }; static const WCHAR szProxy_Authorization[] = { 'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',0 }; @@ -51,7 +47,6 @@ static const WCHAR szStatus[] = { 'S','t','a','t','u','s',0 }; static const WCHAR szKeepAlive[] = {'K','e','e','p','-','A','l','i','v','e',0}; static const WCHAR szGET[] = { 'G','E','T', 0 }; static const WCHAR szHEAD[] = { 'H','E','A','D', 0 }; -static const WCHAR szCrLf[] = {'\r','\n', 0}; static const WCHAR szAccept[] = { 'A','c','c','e','p','t',0 }; static const WCHAR szAccept_Charset[] = { 'A','c','c','e','p','t','-','C','h','a','r','s','e','t', 0 }; @@ -186,7 +181,6 @@ static LPWSTR HTTP_build_req( LPCWSTR *list, int len ); static DWORD HTTP_HttpQueryInfoW(http_request_t*, DWORD, LPVOID, LPDWORD, LPDWORD); static LPWSTR HTTP_GetRedirectURL(http_request_t *req, LPCWSTR lpszUrl); static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin); -static BOOL HTTP_VerifyValidHeader(http_request_t *req, LPCWSTR field); static BOOL drain_content(http_request_t*,BOOL); static CRITICAL_SECTION connection_pool_cs; @@ -346,6 +340,11 @@ static DWORD WINAPI collect_connections_proc(void *arg) FreeLibraryAndExitThread(WININET_hModule, 0); } +/*********************************************************************** + * HTTP_GetHeader (internal) + * + * Headers section must be held + */ static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head) { int HeaderIndex = 0; @@ -356,6 +355,17 @@ static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head) return &req->custHeaders[HeaderIndex]; } +static WCHAR *get_host_header( http_request_t *req ) +{ + HTTPHEADERW *header; + WCHAR *ret = NULL; + + EnterCriticalSection( &req->headers_section ); + if ((header = HTTP_GetHeader( req, hostW ))) ret = heap_strdupW( header->lpszValue ); + LeaveCriticalSection( &req->headers_section ); + return ret; +} + 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*); @@ -387,6 +397,15 @@ static void reset_data_stream(http_request_t *req) req->read_chunked = req->read_gzip = FALSE; } +static void remove_header( http_request_t *request, const WCHAR *str, BOOL from_request ) +{ + int index; + EnterCriticalSection( &request->headers_section ); + index = HTTP_GetCustomHeaderIndex( request, str, 0, from_request ); + if (index != -1) HTTP_DeleteCustomHeader( request, index ); + LeaveCriticalSection( &request->headers_section ); +} + #ifdef HAVE_ZLIB typedef struct { @@ -513,7 +532,7 @@ static void wininet_zfree(voidpf opaque, voidpf address) static DWORD init_gzip_stream(http_request_t *req, BOOL is_gzip) { gzip_stream_t *gzip_stream; - int index, zres; + int zres; gzip_stream = heap_alloc_zero(sizeof(gzip_stream_t)); if(!gzip_stream) @@ -530,9 +549,7 @@ static DWORD init_gzip_stream(http_request_t *req, BOOL is_gzip) return ERROR_OUTOFMEMORY; } - index = HTTP_GetCustomHeaderIndex(req, szContent_Length, 0, FALSE); - if(index != -1) - HTTP_DeleteCustomHeader(req, index); + remove_header(req, szContent_Length, FALSE); if(req->read_size) { memcpy(gzip_stream->buf, req->read_buf+req->read_pos, req->read_size); @@ -606,19 +623,24 @@ static void HTTP_FixURL(http_request_t *request) static WCHAR* build_request_header(http_request_t *request, const WCHAR *verb, const WCHAR *path, const WCHAR *version, BOOL use_cr) { + static const WCHAR szSpace[] = {' ',0}; + static const WCHAR szColon[] = {':',' ',0}; + static const WCHAR szCr[] = {'\r',0}; + static const WCHAR szLf[] = {'\n',0}; LPWSTR requestString; DWORD len, n; LPCWSTR *req; UINT i; - static const WCHAR szSpace[] = { ' ',0 }; - static const WCHAR szColon[] = { ':',' ',0 }; - static const WCHAR szCr[] = { '\r',0 }; - static const WCHAR szLf[] = { '\n',0 }; + EnterCriticalSection( &request->headers_section ); /* allocate space for an array of all the string pointers to be added */ - len = (request->nCustHeaders)*5 + 10; - req = heap_alloc(len*sizeof(LPCWSTR)); + len = request->nCustHeaders * 5 + 10; + if (!(req = heap_alloc( len * sizeof(const WCHAR *) ))) + { + LeaveCriticalSection( &request->headers_section ); + return NULL; + } /* add the verb, path and HTTP version string */ n = 0; @@ -655,6 +677,7 @@ static WCHAR* build_request_header(http_request_t *request, const WCHAR *verb, requestString = HTTP_build_req( req, 4 ); heap_free( req ); + LeaveCriticalSection( &request->headers_section ); return requestString; } @@ -664,14 +687,17 @@ static WCHAR* build_response_header(http_request_t *request, BOOL use_cr) static const WCHAR crW[] = { '\r',0 }; static const WCHAR lfW[] = { '\n',0 }; static const WCHAR status_fmt[] = { ' ','%','u',' ',0 }; - const WCHAR **req; WCHAR *ret, buf[14]; DWORD i, n = 0; - req = heap_alloc((request->nCustHeaders*5+8)*sizeof(WCHAR*)); - if(!req) + EnterCriticalSection( &request->headers_section ); + + if (!(req = heap_alloc( (request->nCustHeaders * 5 + 8) * sizeof(WCHAR *) ))) + { + LeaveCriticalSection( &request->headers_section ); return NULL; + } if (request->status_code) { @@ -708,6 +734,7 @@ static WCHAR* build_response_header(http_request_t *request, BOOL use_cr) ret = HTTP_build_req(req, 0); heap_free(req); + LeaveCriticalSection( &request->headers_section ); return ret; } @@ -720,6 +747,8 @@ static void HTTP_ProcessCookies( http_request_t *request ) if(request->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES) return; + EnterCriticalSection( &request->headers_section ); + while((HeaderIndex = HTTP_GetCustomHeaderIndex(request, szSet_Cookie, numCookies++, FALSE)) != -1) { HTTPHEADERW *host; @@ -747,6 +776,8 @@ static void HTTP_ProcessCookies( http_request_t *request ) set_cookie(host->lpszValue, request->path, name, data, INTERNET_COOKIE_HTTPONLY); heap_free(name); } + + LeaveCriticalSection( &request->headers_section ); } static void strip_spaces(LPWSTR start) @@ -754,7 +785,7 @@ static void strip_spaces(LPWSTR start) LPWSTR str = start; LPWSTR end; - while (*str == ' ' && *str != '\0') + while (*str == ' ') str++; if (str != start) @@ -786,13 +817,13 @@ static inline BOOL is_basic_auth_value( LPCWSTR pszAuthValue, LPWSTR *pszRealm ) if (!token) return TRUE; realm = ptr; - while (*realm == ' ' && *realm != '\0') + while (*realm == ' ') realm++; if(!strncmpiW(realm, szRealm, ARRAYSIZE(szRealm)) && (realm[ARRAYSIZE(szRealm)] == ' ' || realm[ARRAYSIZE(szRealm)] == '=')) { token++; - while (*token == ' ' && *token != '\0') + while (*token == ' ') token++; if (*token == '\0') return TRUE; @@ -1266,10 +1297,8 @@ static DWORD HTTP_HttpAddRequestHeadersW(http_request_t *request, pFieldAndValue = HTTP_InterpretHttpHeader(lpszStart); if (pFieldAndValue) { - res = HTTP_VerifyValidHeader(request, pFieldAndValue[0]); - if (res == ERROR_SUCCESS) - res = HTTP_ProcessHeader(request, pFieldAndValue[0], - pFieldAndValue[1], dwModifier | HTTP_ADDHDR_FLAG_REQ); + res = HTTP_ProcessHeader(request, pFieldAndValue[0], + pFieldAndValue[1], dwModifier | HTTP_ADDHDR_FLAG_REQ); HTTP_FreeTokens(pFieldAndValue); } @@ -1806,8 +1835,7 @@ static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *session, http_req static DWORD HTTP_ResolveName(http_request_t *request) { server_t *server = request->proxy ? request->proxy : request->server; - socklen_t addr_len; - void *addr; + int addr_len; if(server->addr_len) return ERROR_SUCCESS; @@ -1818,23 +1846,10 @@ static DWORD HTTP_ResolveName(http_request_t *request) (strlenW(server->name)+1) * sizeof(WCHAR)); addr_len = sizeof(server->addr); - if (!GetAddress(server->name, server->port, (struct sockaddr *)&server->addr, &addr_len)) + if (!GetAddress(server->name, server->port, (SOCKADDR*)&server->addr, &addr_len, server->addr_str)) return ERROR_INTERNET_NAME_NOT_RESOLVED; - switch(server->addr.ss_family) { - case AF_INET: - addr = &((struct sockaddr_in *)&server->addr)->sin_addr; - break; - case AF_INET6: - addr = &((struct sockaddr_in6 *)&server->addr)->sin6_addr; - break; - default: - WARN("unsupported family %d\n", server->addr.ss_family); - return ERROR_INTERNET_NAME_NOT_RESOLVED; - } - server->addr_len = addr_len; - inet_ntop(server->addr.ss_family, addr, server->addr_str, sizeof(server->addr_str)); INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_NAME_RESOLVED, server->addr_str, strlen(server->addr_str)+1); @@ -1855,6 +1870,8 @@ static BOOL HTTP_GetRequestURL(http_request_t *req, LPWSTR buf) if(!host_header) return FALSE; + EnterCriticalSection( &req->headers_section ); + if (req->hdr.dwFlags & INTERNET_FLAG_SECURE) scheme = https; else @@ -1864,6 +1881,8 @@ static BOOL HTTP_GetRequestURL(http_request_t *req, LPWSTR buf) if (req->path[0] != '/') strcatW(buf, slash); strcatW(buf, req->path); + + LeaveCriticalSection( &req->headers_section ); return TRUE; } @@ -1886,6 +1905,8 @@ static void HTTPREQ_Destroy(object_header_t *hdr) if(request->req_file) req_file_release(request->req_file); + request->headers_section.DebugInfo->Spare[0] = 0; + DeleteCriticalSection( &request->headers_section ); request->read_section.DebugInfo->Spare[0] = 0; DeleteCriticalSection( &request->read_section ); WININET_Release(&request->session->hdr); @@ -2100,17 +2121,18 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe return ERROR_SUCCESS; case INTERNET_OPTION_URL: { + static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0}; WCHAR url[INTERNET_MAX_URL_LENGTH]; HTTPHEADERW *host; - static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0}; - TRACE("INTERNET_OPTION_URL\n"); + EnterCriticalSection( &req->headers_section ); host = HTTP_GetHeader(req, hostW); strcpyW(url, httpW); strcatW(url, host->lpszValue); 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); @@ -2386,7 +2408,11 @@ static void create_cache_entry(http_request_t *req) b = FALSE; if(b) { - int header_idx = HTTP_GetCustomHeaderIndex(req, szCache_Control, 0, FALSE); + int header_idx; + + EnterCriticalSection( &req->headers_section ); + + header_idx = HTTP_GetCustomHeaderIndex(req, szCache_Control, 0, FALSE); if(header_idx != -1) { WCHAR *ptr; @@ -2411,6 +2437,8 @@ static void create_cache_entry(http_request_t *req) ptr++; } } + + LeaveCriticalSection( &req->headers_section ); } if(!b) { @@ -2911,17 +2939,23 @@ static DWORD set_content_length(http_request_t *request) static const WCHAR deflateW[] = {'d','e','f','l','a','t','e',0}; static const WCHAR gzipW[] = {'g','z','i','p',0}; + EnterCriticalSection( &request->headers_section ); + encoding_idx = HTTP_GetCustomHeaderIndex(request, szContent_Encoding, 0, FALSE); if(encoding_idx != -1) { if(!strcmpiW(request->custHeaders[encoding_idx].lpszValue, gzipW)) { HTTP_DeleteCustomHeader(request, encoding_idx); + LeaveCriticalSection( &request->headers_section ); return init_gzip_stream(request, TRUE); } if(!strcmpiW(request->custHeaders[encoding_idx].lpszValue, deflateW)) { HTTP_DeleteCustomHeader(request, encoding_idx); + LeaveCriticalSection( &request->headers_section ); return init_gzip_stream(request, FALSE); } } + + LeaveCriticalSection( &request->headers_section ); } return ERROR_SUCCESS; @@ -3291,6 +3325,9 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session, request->send_timeout = session->send_timeout; request->receive_timeout = session->receive_timeout; + InitializeCriticalSection( &request->headers_section ); + request->headers_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.headers_section"); + InitializeCriticalSection( &request->read_section ); request->read_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.read_section"); @@ -3508,11 +3545,17 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, DWORD level = (dwInfoLevel & ~HTTP_QUERY_MODIFIER_FLAGS_MASK); INT index = -1; + EnterCriticalSection( &request->headers_section ); + /* Find requested header structure */ switch (level) { case HTTP_QUERY_CUSTOM: - if (!lpBuffer) return ERROR_INVALID_PARAMETER; + if (!lpBuffer) + { + LeaveCriticalSection( &request->headers_section ); + return ERROR_INVALID_PARAMETER; + } index = HTTP_GetCustomHeaderIndex(request, lpBuffer, requested_index, request_only); break; case HTTP_QUERY_RAW_HEADERS_CRLF: @@ -3526,7 +3569,10 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, else headers = build_response_header(request, TRUE); if (!headers) + { + LeaveCriticalSection( &request->headers_section ); return ERROR_OUTOFMEMORY; + } len = strlenW(headers) * sizeof(WCHAR); if (len + sizeof(WCHAR) > *lpdwBufferLength) @@ -3543,6 +3589,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, *lpdwBufferLength = len; heap_free(headers); + LeaveCriticalSection( &request->headers_section ); return res; } case HTTP_QUERY_RAW_HEADERS: @@ -3554,14 +3601,19 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, headers = build_request_header(request, request->verb, request->path, request->version, FALSE); else headers = build_response_header(request, FALSE); + if (!headers) + { + LeaveCriticalSection( &request->headers_section ); return ERROR_OUTOFMEMORY; + } len = strlenW(headers) * sizeof(WCHAR); if (len > *lpdwBufferLength) { *lpdwBufferLength = len; heap_free(headers); + LeaveCriticalSection( &request->headers_section ); return ERROR_INSUFFICIENT_BUFFER; } @@ -3581,6 +3633,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, *lpdwBufferLength = len - sizeof(WCHAR); heap_free(headers); + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } case HTTP_QUERY_STATUS_TEXT: @@ -3590,6 +3643,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, if (len + 1 > *lpdwBufferLength/sizeof(WCHAR)) { *lpdwBufferLength = (len + 1) * sizeof(WCHAR); + LeaveCriticalSection( &request->headers_section ); return ERROR_INSUFFICIENT_BUFFER; } if (lpBuffer) @@ -3598,6 +3652,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len)); } *lpdwBufferLength = len * sizeof(WCHAR); + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } break; @@ -3608,6 +3663,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, if (len + 1 > *lpdwBufferLength/sizeof(WCHAR)) { *lpdwBufferLength = (len + 1) * sizeof(WCHAR); + LeaveCriticalSection( &request->headers_section ); return ERROR_INSUFFICIENT_BUFFER; } if (lpBuffer) @@ -3616,6 +3672,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len)); } *lpdwBufferLength = len * sizeof(WCHAR); + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } break; @@ -3627,7 +3684,10 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, DWORD res = ERROR_SUCCESS; if(request_only) + { + LeaveCriticalSection( &request->headers_section ); return ERROR_HTTP_INVALID_QUERY_REQUEST; + } if(requested_index) break; @@ -3654,6 +3714,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, *lpdwBufferLength = size; } + LeaveCriticalSection( &request->headers_section ); return res; } default: @@ -3672,6 +3733,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, ((dwInfoLevel & HTTP_QUERY_FLAG_REQUEST_HEADERS) && (~lphttpHdr->wFlags & HDR_ISREQUEST))) { + LeaveCriticalSection( &request->headers_section ); return ERROR_HTTP_HEADER_NOT_FOUND; } @@ -3711,6 +3773,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, if (len > *lpdwBufferLength) { *lpdwBufferLength = len; + LeaveCriticalSection( &request->headers_section ); return ERROR_INSUFFICIENT_BUFFER; } if (lpBuffer) @@ -3721,6 +3784,8 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel, *lpdwBufferLength = len - sizeof(WCHAR); } if (lpdwIndex) (*lpdwIndex)++; + + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } @@ -4009,7 +4074,6 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl) { http_session_t *session = request->session; WCHAR path[INTERNET_MAX_PATH_LENGTH]; - int index; if(lpszUrl[0]=='/') { @@ -4073,20 +4137,9 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl) heap_free(session->hostName); - if(custom_port) { - int len; - static const WCHAR fmt[] = {'%','s',':','%','u',0}; - len = lstrlenW(hostName); - len += 7; /* 5 for strlen("65535") + 1 for ":" + 1 for '\0' */ - session->hostName = heap_alloc(len*sizeof(WCHAR)); - sprintfW(session->hostName, fmt, hostName, urlComponents.nPort); - } - else - session->hostName = heap_strdupW(hostName); + session->hostName = heap_strdupW(hostName); session->hostPort = urlComponents.nPort; - HTTP_ProcessHeader(request, hostW, session->hostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ); - heap_free(session->userName); session->userName = NULL; if (userName[0]) @@ -4101,6 +4154,11 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl) server_release(request->server); request->server = new_server; } + + if (custom_port) + HTTP_ProcessHeader(request, hostW, request->server->host_port, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ); + else + HTTP_ProcessHeader(request, hostW, request->server->name, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ); } heap_free(request->path); request->path=NULL; @@ -4123,12 +4181,8 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl) } /* Remove custom content-type/length headers on redirects. */ - index = HTTP_GetCustomHeaderIndex(request, szContent_Type, 0, TRUE); - if (0 <= index) - HTTP_DeleteCustomHeader(request, index); - index = HTTP_GetCustomHeaderIndex(request, szContent_Length, 0, TRUE); - if (0 <= index) - HTTP_DeleteCustomHeader(request, index); + remove_header(request, szContent_Type, TRUE); + remove_header(request, szContent_Length, TRUE); return ERROR_SUCCESS; } @@ -4586,6 +4640,8 @@ static void HTTP_ProcessExpires(http_request_t *request) BOOL expirationFound = FALSE; int headerIndex; + EnterCriticalSection( &request->headers_section ); + /* Look for a Cache-Control header with a max-age directive, as it takes * precedence over the Expires header. */ @@ -4666,12 +4722,16 @@ static void HTTP_ProcessExpires(http_request_t *request) request->expires.dwLowDateTime = t.u.LowPart; request->expires.dwHighDateTime = t.u.HighPart; } + + LeaveCriticalSection( &request->headers_section ); } static void HTTP_ProcessLastModified(http_request_t *request) { int headerIndex; + EnterCriticalSection( &request->headers_section ); + headerIndex = HTTP_GetCustomHeaderIndex(request, szLast_Modified, 0, FALSE); if (headerIndex != -1) { @@ -4681,18 +4741,24 @@ static void HTTP_ProcessLastModified(http_request_t *request) if (HTTP_ParseDate(expiresHeader->lpszValue, &ft)) request->last_modified = ft; } + + LeaveCriticalSection( &request->headers_section ); } static void http_process_keep_alive(http_request_t *req) { int index; + EnterCriticalSection( &req->headers_section ); + if ((index = HTTP_GetCustomHeaderIndex(req, szConnection, 0, FALSE)) != -1) req->netconn->keep_alive = !strcmpiW(req->custHeaders[index].lpszValue, szKeepAlive); else if ((index = HTTP_GetCustomHeaderIndex(req, szProxy_Connection, 0, FALSE)) != -1) req->netconn->keep_alive = !strcmpiW(req->custHeaders[index].lpszValue, szKeepAlive); else req->netconn->keep_alive = !strcmpiW(req->version, g_szHttp1_1); + + LeaveCriticalSection( &req->headers_section ); } static DWORD open_http_connection(http_request_t *request, BOOL *reusing) @@ -4864,8 +4930,12 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, if (TRACE_ON(wininet)) { - LPHTTPHEADERW Host = HTTP_GetHeader(request, hostW); - TRACE("Going to url %s %s\n", debugstr_w(Host->lpszValue), debugstr_w(request->path)); + HTTPHEADERW *host; + + EnterCriticalSection( &request->headers_section ); + host = HTTP_GetHeader( request, hostW ); + TRACE("Going to url %s %s\n", debugstr_w(host->lpszValue), debugstr_w(request->path)); + LeaveCriticalSection( &request->headers_section ); } HTTP_FixURL(request); @@ -5019,15 +5089,14 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, dwBufferSize=2048; if (request->status_code == HTTP_STATUS_DENIED) { - LPHTTPHEADERW Host = HTTP_GetHeader(request, hostW); + WCHAR *host = get_host_header( request ); DWORD dwIndex = 0; while (HTTP_HttpQueryInfoW(request,HTTP_QUERY_WWW_AUTHENTICATE,szAuthValue,&dwBufferSize,&dwIndex) == ERROR_SUCCESS) { if (HTTP_DoAuthorization(request, szAuthValue, &request->authInfo, request->session->userName, - request->session->password, - Host->lpszValue)) + request->session->password, host)) { heap_free(requestString); if(!drain_content(request, TRUE)) { @@ -5038,6 +5107,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, break; } } + heap_free( host ); if(!loop_next) { TRACE("Cleaning wrong authorization data\n"); @@ -5075,8 +5145,6 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, } if (secure_proxy_connect && request->status_code == HTTP_STATUS_OK) { - int index; - res = NETCON_secure_connect(request->netconn, request->server); if (res != ERROR_SUCCESS) { @@ -5084,8 +5152,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, http_release_netconn( request, FALSE ); break; } - index = HTTP_GetCustomHeaderIndex(request, szProxy_Authorization, 0, TRUE); - if (index != -1) HTTP_DeleteCustomHeader(request, index); + remove_header(request, szProxy_Authorization, TRUE); destroy_authinfo(request->proxyAuthInfo); request->proxyAuthInfo = NULL; @@ -5794,6 +5861,8 @@ static void HTTP_clear_response_headers( http_request_t *request ) { DWORD i; + EnterCriticalSection( &request->headers_section ); + for( i=0; inCustHeaders; i++) { if( !request->custHeaders[i].lpszField ) @@ -5805,6 +5874,8 @@ static void HTTP_clear_response_headers( http_request_t *request ) HTTP_DeleteCustomHeader( request, i ); i--; } + + LeaveCriticalSection( &request->headers_section ); } /*********************************************************************** @@ -6005,12 +6076,14 @@ static LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer) static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR value, DWORD dwModifier) { LPHTTPHEADERW lphttpHdr = NULL; - INT index = -1; + INT index; BOOL request_only = dwModifier & HTTP_ADDHDR_FLAG_REQ; DWORD res = ERROR_HTTP_INVALID_HEADER; 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; @@ -6023,7 +6096,10 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR if (index >= 0) { if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW) + { + LeaveCriticalSection( &request->headers_section ); return ERROR_HTTP_INVALID_HEADER; + } lphttpHdr = &request->custHeaders[index]; } else if (value) @@ -6037,10 +6113,16 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR if (dwModifier & HTTP_ADDHDR_FLAG_REQ) hdr.wFlags |= HDR_ISREQUEST; - return HTTP_InsertCustomHeader(request, &hdr); + res = HTTP_InsertCustomHeader(request, &hdr); + LeaveCriticalSection( &request->headers_section ); + return res; } /* no value to delete */ - else return ERROR_SUCCESS; + else + { + LeaveCriticalSection( &request->headers_section ); + return ERROR_SUCCESS; + } if (dwModifier & HTTP_ADDHDR_FLAG_REQ) lphttpHdr->wFlags |= HDR_ISREQUEST; @@ -6062,9 +6144,12 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR if (dwModifier & HTTP_ADDHDR_FLAG_REQ) hdr.wFlags |= HDR_ISREQUEST; - return HTTP_InsertCustomHeader(request, &hdr); + res = HTTP_InsertCustomHeader(request, &hdr); + LeaveCriticalSection( &request->headers_section ); + return res; } + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } else if (dwModifier & COALESCEFLAGS) @@ -6112,6 +6197,7 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR } } TRACE("<-- %d\n", res); + LeaveCriticalSection( &request->headers_section ); return res; } @@ -6119,7 +6205,7 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR * HTTP_GetCustomHeaderIndex (internal) * * Return index of custom header from header array - * + * Headers section must be held */ static INT HTTP_GetCustomHeaderIndex(http_request_t *request, LPCWSTR lpszField, int requested_index, BOOL request_only) @@ -6156,7 +6242,7 @@ static INT HTTP_GetCustomHeaderIndex(http_request_t *request, LPCWSTR lpszField, * HTTP_InsertCustomHeader (internal) * * Insert header into array - * + * Headers section must be held */ static DWORD HTTP_InsertCustomHeader(http_request_t *request, LPHTTPHEADERW lpHdr) { @@ -6188,7 +6274,8 @@ static DWORD HTTP_InsertCustomHeader(http_request_t *request, LPHTTPHEADERW lpHd * HTTP_DeleteCustomHeader (internal) * * Delete header from array - * If this function is called, the indexs may change. + * If this function is called, the index may change. + * Headers section must be held */ static BOOL HTTP_DeleteCustomHeader(http_request_t *request, DWORD index) { @@ -6209,21 +6296,6 @@ static BOOL HTTP_DeleteCustomHeader(http_request_t *request, DWORD index) } -/*********************************************************************** - * HTTP_VerifyValidHeader (internal) - * - * Verify the given header is not invalid for the given http request - * - */ -static BOOL HTTP_VerifyValidHeader(http_request_t *request, LPCWSTR field) -{ - /* Accept-Encoding is stripped from HTTP/1.0 requests. It is invalid */ - if (!strcmpW(request->version, g_szHttp1_0) && !strcmpiW(field, szAccept_Encoding)) - return ERROR_HTTP_INVALID_HEADER; - - return ERROR_SUCCESS; -} - /*********************************************************************** * IsHostInProxyBypassList (@) * diff --git a/reactos/dll/win32/wininet/internet.c b/reactos/dll/win32/wininet/internet.c index 8eb4fa561f5..f60d29aa458 100644 --- a/reactos/dll/win32/wininet/internet.c +++ b/reactos/dll/win32/wininet/internet.c @@ -28,8 +28,6 @@ #include "internet.h" -#define RESPONSE_TIMEOUT 30 - typedef struct { DWORD dwError; @@ -487,11 +485,12 @@ static void free_global_proxy( void ) static BOOL parse_proxy_url( proxyinfo_t *info, const WCHAR *url ) { static const WCHAR fmt[] = {'%','s',':','%','u',0}; - WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH] = {0}; - WCHAR username[INTERNET_MAX_USER_NAME_LENGTH] = {0}; - WCHAR password[INTERNET_MAX_PASSWORD_LENGTH] = {0}; + WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH]; + WCHAR username[INTERNET_MAX_USER_NAME_LENGTH]; + WCHAR password[INTERNET_MAX_PASSWORD_LENGTH]; URL_COMPONENTSW uc; + hostname[0] = username[0] = password[0] = 0; memset( &uc, 0, sizeof(uc) ); uc.dwStructSize = sizeof(uc); uc.lpszHostName = hostname; @@ -801,9 +800,6 @@ static VOID APPINFO_Destroy(object_header_t *hdr) 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) @@ -999,11 +995,6 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags) { appinfo_t *lpwai = NULL; -#ifdef __REACTOS__ - WSADATA wsaData; - int error = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (error) ERR("WSAStartup failed: %d\n", error); -#endif if (TRACE_ON(wininet)) { #define FE(x) { x, #x } @@ -1227,13 +1218,21 @@ BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnecti /* Must be zero */ if(dwReserved) - return FALSE; + return FALSE; if (lpdwStatus) { WARN("always returning LAN connection.\n"); *lpdwStatus = INTERNET_CONNECTION_LAN; } - return LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen) > 0; + + /* When the buffer size is zero LoadStringW fills the buffer with a pointer to + * the resource, avoid it as we must not change the buffer in this case */ + if(lpszConnectionName && dwNameLen) { + *lpszConnectionName = '\0'; + LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen); + } + + return TRUE; } @@ -3418,14 +3417,15 @@ BOOL WINAPI InternetCheckConnectionW( LPCWSTR lpszUrl, DWORD dwFlags, DWORD dwRe socklen_t sa_len = sizeof(saddr); int fd; - if (!GetAddress(hostW, port, (struct sockaddr *)&saddr, &sa_len)) + if (!GetAddress(hostW, port, (struct sockaddr *)&saddr, &sa_len, NULL)) goto End; + init_winsock(); fd = socket(saddr.ss_family, SOCK_STREAM, 0); if (fd != -1) { if (connect(fd, (struct sockaddr *)&saddr, sa_len) == 0) rc = TRUE; - close(fd); + closesocket(fd); } } else @@ -3860,72 +3860,6 @@ LPSTR INTERNET_GetResponseBuffer(void) return lpwite->response; } -/*********************************************************************** - * INTERNET_GetNextLine (internal) - * - * Parse next line in directory string listing - * - * RETURNS - * Pointer to beginning of next line - * NULL on failure - * - */ - -LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen) -{ - /* ReactOS: use select instead of poll */ - fd_set infd; - struct timeval tv; - BOOL bSuccess = FALSE; - INT nRecv = 0; - LPSTR lpszBuffer = INTERNET_GetResponseBuffer(); - - TRACE("\n"); - - FD_ZERO(&infd); - FD_SET(nSocket,&infd); - tv.tv_sec = RESPONSE_TIMEOUT; - tv.tv_usec = 0; - - while (nRecv < MAX_REPLY_LEN) - { - if (select(0, &infd, NULL, NULL, &tv) > 0) - { - if (sock_recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0) - { - INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS); - goto lend; - } - - if (lpszBuffer[nRecv] == '\n') - { - bSuccess = TRUE; - break; - } - if (lpszBuffer[nRecv] != '\r') - nRecv++; - } - else - { - INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT); - goto lend; - } - } - -lend: - if (bSuccess) - { - lpszBuffer[nRecv] = '\0'; - *dwLen = nRecv - 1; - TRACE(":%d %s\n", nRecv, lpszBuffer); - return lpszBuffer; - } - else - { - return NULL; - } -} - /********************************************************** * InternetQueryDataAvailable (WININET.@) * diff --git a/reactos/dll/win32/wininet/internet.h b/reactos/dll/win32/wininet/internet.h index 6bafbfa922b..7d0cac83781 100644 --- a/reactos/dll/win32/wininet/internet.h +++ b/reactos/dll/win32/wininet/internet.h @@ -98,7 +98,7 @@ typedef struct { INTERNET_PORT port; BOOL is_https; struct sockaddr_storage addr; - socklen_t addr_len; + int addr_len; char addr_str[INET6_ADDRSTRLEN]; WCHAR *scheme_host_port; @@ -402,8 +402,11 @@ typedef struct LPWSTR statusText; DWORD bytesToWrite; DWORD bytesWritten; + + CRITICAL_SECTION headers_section; /* section to protect the headers array */ HTTPHEADERW *custHeaders; DWORD nCustHeaders; + FILETIME last_modified; HANDLE hCacheFile; req_file_t *req_file; @@ -455,8 +458,7 @@ DWORD HTTP_Connect(appinfo_t*,LPCWSTR, LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext, DWORD dwInternalFlags, HINTERNET*) DECLSPEC_HIDDEN; -BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, - struct sockaddr *psa, socklen_t *sa_len) DECLSPEC_HIDDEN; +BOOL GetAddress(const WCHAR*,INTERNET_PORT,SOCKADDR*,int*,char*) DECLSPEC_HIDDEN; DWORD get_cookie_header(const WCHAR*,const WCHAR*,WCHAR**) DECLSPEC_HIDDEN; DWORD set_cookie(const WCHAR*,const WCHAR*,const WCHAR*,const WCHAR*,DWORD) DECLSPEC_HIDDEN; @@ -465,7 +467,6 @@ void INTERNET_SetLastError(DWORD dwError) DECLSPEC_HIDDEN; DWORD INTERNET_GetLastError(void) DECLSPEC_HIDDEN; DWORD INTERNET_AsyncCall(task_header_t*) DECLSPEC_HIDDEN; LPSTR INTERNET_GetResponseBuffer(void) DECLSPEC_HIDDEN; -LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen) DECLSPEC_HIDDEN; VOID SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, @@ -494,33 +495,7 @@ 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; -#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 /* !__REACTOS__ */ - +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; @@ -539,6 +514,8 @@ BOOL init_urlcache(void) DECLSPEC_HIDDEN; void free_urlcache(void) DECLSPEC_HIDDEN; void free_cookie(void) DECLSPEC_HIDDEN; +void init_winsock(void) DECLSPEC_HIDDEN; + #define MAX_REPLY_LEN 0x5B4 /* Used for debugging - maybe need to be shared in the Wine debugging code ? */ diff --git a/reactos/dll/win32/wininet/netconnection.c b/reactos/dll/win32/wininet/netconnection.c index 5366c603e64..55b1bfef1c8 100644 --- a/reactos/dll/win32/wininet/netconnection.c +++ b/reactos/dll/win32/wininet/netconnection.c @@ -1,5 +1,5 @@ /* - * Wininet - networking layer. Uses unix sockets. + * Wininet - networking layer * * Copyright 2002 TransGaming Technologies Inc. * Copyright 2013 Jacek Caban for CodeWeavers @@ -36,19 +36,6 @@ #include -#define RESPONSE_TIMEOUT 30 /* FROM internet.c */ - -#ifdef MSG_DONTWAIT -#define WINE_MSG_DONTWAIT MSG_DONTWAIT -#else -#define WINE_MSG_DONTWAIT 0 -#endif - -/* FIXME!!!!!! - * This should use winsock - To use winsock the functions will have to change a bit - * as they are designed for unix sockets. - */ - static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTORE store) { BOOL ret; @@ -62,6 +49,7 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_PARTIAL_CHAIN | + CERT_TRUST_IS_NOT_SIGNATURE_VALID | CERT_TRUST_IS_NOT_VALID_FOR_USAGE; TRACE("verifying %s\n", debugstr_w(conn->server->name)); @@ -128,6 +116,17 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR errors &= ~CERT_TRUST_IS_PARTIAL_CHAIN; } + if(errors & CERT_TRUST_IS_NOT_SIGNATURE_VALID) { + WARN("CERT_TRUST_IS_NOT_SIGNATURE_VALID\n"); + if(!(conn->security_flags & SECURITY_FLAG_IGNORE_UNKNOWN_CA)) { + err = conn->mask_errors && err ? ERROR_INTERNET_SEC_CERT_ERRORS : ERROR_INTERNET_INVALID_CA; + if(!conn->mask_errors) + break; + conn->security_flags |= _SECURITY_FLAG_CERT_INVALID_CA; + } + errors &= ~CERT_TRUST_IS_NOT_SIGNATURE_VALID; + } + if(errors & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { WARN("CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n"); if(!(conn->security_flags & SECURITY_FLAG_IGNORE_WRONG_USAGE)) { @@ -253,43 +252,65 @@ static BOOL ensure_cred_handle(void) return TRUE; } +static BOOL winsock_loaded = FALSE; + +static BOOL WINAPI winsock_startup(INIT_ONCE *once, void *param, void **context) +{ + WSADATA wsa_data; + DWORD res; + + res = WSAStartup(MAKEWORD(1,1), &wsa_data); + if(res == ERROR_SUCCESS) + winsock_loaded = TRUE; + else + ERR("WSAStartup failed: %u\n", res); + return TRUE; +} + +void init_winsock(void) +{ + static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; + InitOnceExecuteOnce(&init_once, winsock_startup, NULL, NULL); +} + +static void set_socket_blocking(int socket, blocking_mode_t mode) +{ + ULONG arg = mode == BLOCKING_DISALLOW; + ioctlsocket(socket, FIONBIO, &arg); +} + static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD timeout) { int result; ULONG flag; + DWORD res; + + init_winsock(); assert(server->addr_len); result = netconn->socket = socket(server->addr.ss_family, SOCK_STREAM, 0); if(result != -1) { - flag = 1; - ioctlsocket(netconn->socket, FIONBIO, &flag); + set_socket_blocking(netconn->socket, BLOCKING_DISALLOW); result = connect(netconn->socket, (struct sockaddr*)&server->addr, server->addr_len); if(result == -1) { - if (sock_get_error(errno) == WSAEINPROGRESS) { - /* ReactOS: use select instead of poll */ - fd_set outfd; - struct timeval tv; + res = sock_get_error(); + if (res == WSAEINPROGRESS || res == WSAEWOULDBLOCK) { + FD_SET set; int res; + socklen_t len = sizeof(res); + TIMEVAL timeout_timeval = {0, timeout*1000}; - 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) - { + FD_ZERO(&set); + FD_SET(netconn->socket, &set); + res = select(netconn->socket+1, NULL, &set, NULL, &timeout_timeval); + if(!res || res == SOCKET_ERROR) { closesocket(netconn->socket); netconn->socket = -1; return ERROR_INTERNET_CANNOT_CONNECT; } - else if (res > 0) - { - int err; - socklen_t len = sizeof(err); - if (!getsockopt(netconn->socket, SOL_SOCKET, SO_ERROR, (void *)&err, &len) && !err) - result = 0; - } + if (!getsockopt(netconn->socket, SOL_SOCKET, SO_ERROR, (void *)&res, &len) && !res) + result = 0; } } if(result == -1) @@ -298,19 +319,16 @@ static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD t netconn->socket = -1; } else { - flag = 0; - ioctlsocket(netconn->socket, FIONBIO, &flag); + set_socket_blocking(netconn->socket, BLOCKING_ALLOW); } } if(result == -1) return ERROR_INTERNET_CANNOT_CONNECT; -#ifdef TCP_NODELAY flag = 1; result = setsockopt(netconn->socket, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag)); if(result < 0) WARN("setsockopt(TCP_NODELAY) failed\n"); -#endif return ERROR_SUCCESS; } @@ -381,76 +399,14 @@ void NETCON_unload(void) if(have_compat_cred_handle) FreeCredentialsHandle(&compat_cred_handle); DeleteCriticalSection(&init_sechandle_cs); + WSACleanup(); } -#ifndef __REACTOS__ /* translate a unix error code into a winsock one */ -int sock_get_error( int err ) +int sock_get_error(void) { -#if !defined(__MINGW32__) && !defined (_MSC_VER) - switch (err) - { - case EINTR: return WSAEINTR; - case EBADF: return WSAEBADF; - case EPERM: - case EACCES: return WSAEACCES; - case EFAULT: return WSAEFAULT; - case EINVAL: return WSAEINVAL; - case EMFILE: return WSAEMFILE; - case EWOULDBLOCK: return WSAEWOULDBLOCK; - case EINPROGRESS: return WSAEINPROGRESS; - case EALREADY: return WSAEALREADY; - case ENOTSOCK: return WSAENOTSOCK; - case EDESTADDRREQ: return WSAEDESTADDRREQ; - case EMSGSIZE: return WSAEMSGSIZE; - case EPROTOTYPE: return WSAEPROTOTYPE; - case ENOPROTOOPT: return WSAENOPROTOOPT; - case EPROTONOSUPPORT: return WSAEPROTONOSUPPORT; - case ESOCKTNOSUPPORT: return WSAESOCKTNOSUPPORT; - case EOPNOTSUPP: return WSAEOPNOTSUPP; - case EPFNOSUPPORT: return WSAEPFNOSUPPORT; - case EAFNOSUPPORT: return WSAEAFNOSUPPORT; - case EADDRINUSE: return WSAEADDRINUSE; - case EADDRNOTAVAIL: return WSAEADDRNOTAVAIL; - case ENETDOWN: return WSAENETDOWN; - case ENETUNREACH: return WSAENETUNREACH; - case ENETRESET: return WSAENETRESET; - case ECONNABORTED: return WSAECONNABORTED; - case EPIPE: - case ECONNRESET: return WSAECONNRESET; - case ENOBUFS: return WSAENOBUFS; - case EISCONN: return WSAEISCONN; - case ENOTCONN: return WSAENOTCONN; - case ESHUTDOWN: return WSAESHUTDOWN; - case ETOOMANYREFS: return WSAETOOMANYREFS; - case ETIMEDOUT: return WSAETIMEDOUT; - case ECONNREFUSED: return WSAECONNREFUSED; - case ELOOP: return WSAELOOP; - case ENAMETOOLONG: return WSAENAMETOOLONG; - case EHOSTDOWN: return WSAEHOSTDOWN; - case EHOSTUNREACH: return WSAEHOSTUNREACH; - case ENOTEMPTY: return WSAENOTEMPTY; -#ifdef EPROCLIM - case EPROCLIM: return WSAEPROCLIM; -#endif -#ifdef EUSERS - case EUSERS: return WSAEUSERS; -#endif -#ifdef EDQUOT - case EDQUOT: return WSAEDQUOT; -#endif -#ifdef ESTALE - case ESTALE: return WSAESTALE; -#endif -#ifdef EREMOTE - case EREMOTE: return WSAEREMOTE; -#endif - default: errno=err; perror("sock_set_error"); return WSAEFAULT; - } -#endif - return err; + return WSAGetLastError(); } -#endif /* !__REACTOS__ */ int sock_send(int fd, const void *msg, size_t len, int flags) { @@ -459,7 +415,7 @@ int sock_send(int fd, const void *msg, size_t len, int flags) { ret = send(fd, msg, len, flags); } - while(ret == -1 && errno == EINTR); + while(ret == -1 && sock_get_error() == WSAEINTR); return ret; } @@ -470,18 +426,10 @@ int sock_recv(int fd, void *msg, size_t len, int flags) { ret = recv(fd, msg, len, flags); } - while(ret == -1 && errno == EINTR); + while(ret == -1 && sock_get_error() == WSAEINTR); return ret; } -static void set_socket_blocking(int socket, blocking_mode_t mode) -{ -#if defined(__MINGW32__) || defined (_MSC_VER) - ULONG arg = mode == BLOCKING_DISALLOW; - ioctlsocket(socket, FIONBIO, &arg); -#endif -} - static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode) { SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}}; @@ -715,9 +663,7 @@ DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags, if(!connection->secure) { *sent = sock_send(connection->socket, msg, len, flags); - if (*sent == -1) - return sock_get_error(errno); - return ERROR_SUCCESS; + return *sent == -1 ? sock_get_error() : ERROR_SUCCESS; } else { @@ -766,10 +712,10 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking tmp_mode = buf_len ? BLOCKING_DISALLOW : mode; set_socket_blocking(conn->socket, tmp_mode); - size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, tmp_mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT); + size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0); if(size < 0) { if(!buf_len) { - if(errno == EAGAIN || errno == EWOULDBLOCK) { + if(sock_get_error() == WSAEWOULDBLOCK) { TRACE("would block\n"); return WSAEWOULDBLOCK; } @@ -807,9 +753,9 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking assert(buf_len < ssl_buf_size); set_socket_blocking(conn->socket, mode); - size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT); + size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0); if(size < 1) { - if(size < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { + if(size < 0 && sock_get_error() == WSAEWOULDBLOCK) { TRACE("would block\n"); /* FIXME: Optimize extra_buf usage. */ @@ -879,20 +825,12 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t { int flags = 0; - switch(mode) { - case BLOCKING_ALLOW: - break; - case BLOCKING_DISALLOW: - flags = WINE_MSG_DONTWAIT; - break; - case BLOCKING_WAITALL: + if(mode == BLOCKING_WAITALL) flags = MSG_WAITALL; - break; - } set_socket_blocking(connection->socket, mode); *recvd = sock_recv(connection->socket, buf, len, flags); - return *recvd == -1 ? sock_get_error(errno) : ERROR_SUCCESS; + return *recvd == -1 ? sock_get_error() : ERROR_SUCCESS; } else { @@ -956,7 +894,6 @@ BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available) if(!connection->secure) { -#ifdef FIONREAD ULONG unread; int retval = ioctlsocket(connection->socket, FIONREAD, &unread); if (!retval) @@ -964,7 +901,6 @@ BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available) TRACE("%d bytes of queued, but unread data\n", unread); *available += unread; } -#endif } else { @@ -975,32 +911,14 @@ BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available) BOOL NETCON_is_alive(netconn_t *netconn) { -#ifdef MSG_DONTWAIT - ssize_t len; - BYTE b; - - len = sock_recv(netconn->socket, &b, 1, MSG_PEEK|MSG_DONTWAIT); - return len == 1 || (len == -1 && errno == EWOULDBLOCK); -#elif defined(__MINGW32__) || defined(_MSC_VER) - ULONG mode; int len; char b; - mode = 1; - if(!ioctlsocket(netconn->socket, FIONBIO, &mode)) - return FALSE; - + set_socket_blocking(netconn->socket, BLOCKING_DISALLOW); len = sock_recv(netconn->socket, &b, 1, MSG_PEEK); + set_socket_blocking(netconn->socket, BLOCKING_ALLOW); - mode = 0; - if(!ioctlsocket(netconn->socket, FIONBIO, &mode)) - return FALSE; - - return len == 1 || (len == -1 && errno == WSAEWOULDBLOCK); -#else - FIXME("not supported on this platform\n"); - return TRUE; -#endif + return len == 1 || (len == -1 && sock_get_error() == WSAEWOULDBLOCK); } LPCVOID NETCON_GetCert(netconn_t *connection) @@ -1047,8 +965,8 @@ DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) sizeof(tv)); if (result == -1) { - WARN("setsockopt failed (%s)\n", strerror(errno)); - return sock_get_error(errno); + WARN("setsockopt failed\n"); + return sock_get_error(); } return ERROR_SUCCESS; } diff --git a/reactos/dll/win32/wininet/urlcache.c b/reactos/dll/win32/wininet/urlcache.c index f39aa2ccdb4..3a22eb30727 100644 --- a/reactos/dll/win32/wininet/urlcache.c +++ b/reactos/dll/win32/wininet/urlcache.c @@ -1205,7 +1205,6 @@ static void dos_date_time_to_file_time(WORD fatdate, WORD fattime, static int urlcache_decode_url(const char *url, WCHAR *decoded_url, int decoded_len) { -#ifndef __REACTOS__ /* FIXME: Vista+ */ URL_COMPONENTSA uc; DWORD len, part_len; WCHAR *host_name; @@ -1217,10 +1216,8 @@ static int urlcache_decode_url(const char *url, WCHAR *decoded_url, int decoded_ uc.nScheme = INTERNET_SCHEME_UNKNOWN; if(uc.nScheme!=INTERNET_SCHEME_HTTP && uc.nScheme!=INTERNET_SCHEME_HTTPS) -#endif return MultiByteToWideChar(CP_UTF8, 0, url, -1, decoded_url, decoded_len); -#ifndef __REACTOS__ /* FIXME: Vista+ */ if(!decoded_url) decoded_len = 0; @@ -1257,7 +1254,6 @@ static int urlcache_decode_url(const char *url, WCHAR *decoded_url, int decoded_ len += part_len; return len; -#endif /* !__REACTOS__ */ } /*********************************************************************** @@ -1873,7 +1869,6 @@ BOOL WINAPI GetUrlCacheEntryInfoA(LPCSTR lpszUrlName, static int urlcache_encode_url(const WCHAR *url, char *encoded_url, int encoded_len) { -#ifndef __REACTOS__ /* FIXME: Vista+ */ URL_COMPONENTSW uc; DWORD len, part_len; WCHAR *punycode; @@ -1887,10 +1882,8 @@ static int urlcache_encode_url(const WCHAR *url, char *encoded_url, int encoded_ uc.nScheme = INTERNET_SCHEME_UNKNOWN; if(uc.nScheme!=INTERNET_SCHEME_HTTP && uc.nScheme!=INTERNET_SCHEME_HTTPS) -#endif return WideCharToMultiByte(CP_UTF8, 0, url, -1, encoded_url, encoded_len, NULL, NULL); -#ifndef __REACTOS__ /* FIXME: Vista+ */ len = WideCharToMultiByte(CP_UTF8, 0, url, uc.lpszHostName-url, encoded_url, encoded_len, NULL, NULL); if(!len) @@ -1931,7 +1924,6 @@ static int urlcache_encode_url(const WCHAR *url, char *encoded_url, int encoded_ TRACE("got (%d)%s\n", len, debugstr_a(encoded_url)); return len; -#endif /* !__REACTOS__ */ } static BOOL urlcache_encode_url_alloc(const WCHAR *url, char **encoded_url) diff --git a/reactos/dll/win32/wininet/utility.c b/reactos/dll/win32/wininet/utility.c index 826418daefd..ad441d7e067 100644 --- a/reactos/dll/win32/wininet/utility.c +++ b/reactos/dll/win32/wininet/utility.c @@ -24,19 +24,8 @@ #include "internet.h" -#ifndef HAVE_GETADDRINFO - -/* critical section to protect non-reentrant gethostbyname() */ -static CRITICAL_SECTION cs_gethostbyname; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &cs_gethostbyname, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": cs_gethostbyname") } -}; -static CRITICAL_SECTION cs_gethostbyname = { &critsect_debug, -1, 0, 0, 0, 0 }; - -#endif +// ReactOS +#include "inet_ntop.c" #define TIME_STRING_LEN 30 @@ -124,62 +113,36 @@ time_t ConvertTimeString(LPCWSTR asctime) } -BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, - struct sockaddr *psa, socklen_t *sa_len) +BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str) { - WCHAR *found; - char *name; - int len, sz; -#ifdef HAVE_GETADDRINFO - struct addrinfo *res, hints; + ADDRINFOW *res, hints; + void *addr = NULL; int ret; -#else - struct hostent *phe; - struct sockaddr_in *sin = (struct sockaddr_in *)psa; -#endif - TRACE("%s\n", debugstr_w(lpszServerName)); + TRACE("%s\n", debugstr_w(name)); - /* Validate server name first - * Check if there is something like - * pinger.macromedia.com:80 - * if yes, eliminate the :80.... - */ - found = strchrW(lpszServerName, ':'); - if (found) - len = found - lpszServerName; - else - len = strlenW(lpszServerName); - - sz = WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, NULL, 0, NULL, NULL ); - if (!(name = heap_alloc(sz + 1))) return FALSE; - WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, name, sz, NULL, NULL ); - name[sz] = 0; - -#ifdef HAVE_GETADDRINFO - memset( &hints, 0, sizeof(struct addrinfo) ); + memset( &hints, 0, sizeof(hints) ); /* Prefer IPv4 to IPv6 addresses, since some servers do not listen on * their IPv6 addresses even though they have IPv6 addresses in the DNS. */ hints.ai_family = AF_INET; - ret = getaddrinfo( name, NULL, &hints, &res ); + ret = GetAddrInfoW(name, NULL, &hints, &res); if (ret != 0) { - TRACE("failed to get IPv4 address of %s (%s), retrying with IPv6\n", debugstr_w(lpszServerName), gai_strerror(ret)); + TRACE("failed to get IPv4 address of %s, retrying with IPv6\n", debugstr_w(name)); hints.ai_family = AF_INET6; - ret = getaddrinfo( name, NULL, &hints, &res ); + ret = GetAddrInfoW(name, NULL, &hints, &res); } - heap_free( name ); if (ret != 0) { - TRACE("failed to get address of %s (%s)\n", debugstr_w(lpszServerName), gai_strerror(ret)); + TRACE("failed to get address of %s\n", debugstr_w(name)); return FALSE; } if (*sa_len < res->ai_addrlen) { WARN("address too small\n"); - freeaddrinfo( res ); + FreeAddrInfoW(res); return FALSE; } *sa_len = res->ai_addrlen; @@ -188,39 +151,18 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, switch (res->ai_family) { case AF_INET: - ((struct sockaddr_in *)psa)->sin_port = htons(nServerPort); + addr = &((struct sockaddr_in *)psa)->sin_addr; + ((struct sockaddr_in *)psa)->sin_port = htons(port); break; case AF_INET6: - ((struct sockaddr_in6 *)psa)->sin6_port = htons(nServerPort); + addr = &((struct sockaddr_in6 *)psa)->sin6_addr; + ((struct sockaddr_in6 *)psa)->sin6_port = htons(port); break; } - freeaddrinfo( res ); -#else - EnterCriticalSection( &cs_gethostbyname ); - phe = gethostbyname(name); - heap_free( name ); - - if (NULL == phe) - { - TRACE("failed to get address of %s (%d)\n", debugstr_w(lpszServerName), h_errno); - LeaveCriticalSection( &cs_gethostbyname ); - return FALSE; - } - if (*sa_len < sizeof(struct sockaddr_in)) - { - WARN("address too small\n"); - LeaveCriticalSection( &cs_gethostbyname ); - return FALSE; - } - *sa_len = sizeof(struct sockaddr_in); - memset(sin,0,sizeof(struct sockaddr_in)); - memcpy((char *)&sin->sin_addr, phe->h_addr, phe->h_length); - sin->sin_family = phe->h_addrtype; - sin->sin_port = htons(nServerPort); - - LeaveCriticalSection( &cs_gethostbyname ); -#endif + if(addr_str) + inet_ntop(res->ai_family, addr, addr_str, INET6_ADDRSTRLEN); + FreeAddrInfoW(res); return TRUE; } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 6ef13a9ae33..e6aa4701444 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -207,7 +207,7 @@ reactos/dll/win32/windowscodecsext # Synced to Wine-1.7.27 reactos/dll/win32/winemp3.acm # Synced to Wine-1.7.27 reactos/dll/win32/wing32 # Out of sync reactos/dll/win32/winhttp # Synced to WineStaging-1.7.37 -reactos/dll/win32/wininet # Synced to Wine-1.7.27 +reactos/dll/win32/wininet # Synced to WineStaging-1.7.37 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