Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensession.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2008 Hans Leidekker for CodeWeavers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "config.h" 00020 #include "wine/port.h" 00021 #include "wine/debug.h" 00022 00023 #include <stdarg.h> 00024 #include <stdlib.h> 00025 00026 #include "windef.h" 00027 #include "winbase.h" 00028 #include "winhttp.h" 00029 #include "wincrypt.h" 00030 #include "winreg.h" 00031 00032 #include "winhttp_private.h" 00033 00034 WINE_DEFAULT_DEBUG_CHANNEL(winhttp); 00035 00036 #define DEFAULT_RESOLVE_TIMEOUT 0 00037 #define DEFAULT_CONNECT_TIMEOUT 20000 00038 #define DEFAULT_SEND_TIMEOUT 30000 00039 #define DEFAULT_RECEIVE_TIMEOUT 30000 00040 00041 /* FIXME */ 00042 #define CP_UNIXCP CP_ACP 00043 00044 void set_last_error( DWORD error ) 00045 { 00046 /* FIXME */ 00047 SetLastError( error ); 00048 } 00049 00050 DWORD get_last_error( void ) 00051 { 00052 /* FIXME */ 00053 return GetLastError(); 00054 } 00055 00056 void send_callback( object_header_t *hdr, DWORD status, LPVOID info, DWORD buflen ) 00057 { 00058 TRACE("%p, 0x%08x, %p, %u\n", hdr, status, info, buflen); 00059 00060 if (hdr->callback && (hdr->notify_mask & status)) hdr->callback( hdr->handle, hdr->context, status, info, buflen ); 00061 } 00062 00063 /*********************************************************************** 00064 * WinHttpCheckPlatform (winhttp.@) 00065 */ 00066 BOOL WINAPI WinHttpCheckPlatform( void ) 00067 { 00068 TRACE("\n"); 00069 return TRUE; 00070 } 00071 00072 /*********************************************************************** 00073 * session_destroy (internal) 00074 */ 00075 static void session_destroy( object_header_t *hdr ) 00076 { 00077 session_t *session = (session_t *)hdr; 00078 struct list *item, *next; 00079 domain_t *domain; 00080 00081 TRACE("%p\n", session); 00082 00083 LIST_FOR_EACH_SAFE( item, next, &session->cookie_cache ) 00084 { 00085 domain = LIST_ENTRY( item, domain_t, entry ); 00086 delete_domain( domain ); 00087 } 00088 heap_free( session->agent ); 00089 heap_free( session->proxy_server ); 00090 heap_free( session->proxy_bypass ); 00091 heap_free( session->proxy_username ); 00092 heap_free( session->proxy_password ); 00093 heap_free( session ); 00094 } 00095 00096 static BOOL session_query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen ) 00097 { 00098 session_t *session = (session_t *)hdr; 00099 00100 switch (option) 00101 { 00102 case WINHTTP_OPTION_REDIRECT_POLICY: 00103 { 00104 if (!buffer || *buflen < sizeof(DWORD)) 00105 { 00106 *buflen = sizeof(DWORD); 00107 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00108 return FALSE; 00109 } 00110 00111 *(DWORD *)buffer = hdr->redirect_policy; 00112 *buflen = sizeof(DWORD); 00113 return TRUE; 00114 } 00115 case WINHTTP_OPTION_RESOLVE_TIMEOUT: 00116 *(DWORD *)buffer = session->resolve_timeout; 00117 *buflen = sizeof(DWORD); 00118 return TRUE; 00119 case WINHTTP_OPTION_CONNECT_TIMEOUT: 00120 *(DWORD *)buffer = session->connect_timeout; 00121 *buflen = sizeof(DWORD); 00122 return TRUE; 00123 case WINHTTP_OPTION_SEND_TIMEOUT: 00124 *(DWORD *)buffer = session->send_timeout; 00125 *buflen = sizeof(DWORD); 00126 return TRUE; 00127 case WINHTTP_OPTION_RECEIVE_TIMEOUT: 00128 *(DWORD *)buffer = session->recv_timeout; 00129 *buflen = sizeof(DWORD); 00130 return TRUE; 00131 default: 00132 FIXME("unimplemented option %u\n", option); 00133 set_last_error( ERROR_INVALID_PARAMETER ); 00134 return FALSE; 00135 } 00136 } 00137 00138 static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen ) 00139 { 00140 session_t *session = (session_t *)hdr; 00141 00142 switch (option) 00143 { 00144 case WINHTTP_OPTION_PROXY: 00145 { 00146 WINHTTP_PROXY_INFO *pi = buffer; 00147 00148 FIXME("%u %s %s\n", pi->dwAccessType, debugstr_w(pi->lpszProxy), debugstr_w(pi->lpszProxyBypass)); 00149 return TRUE; 00150 } 00151 case WINHTTP_OPTION_REDIRECT_POLICY: 00152 { 00153 DWORD policy; 00154 00155 if (buflen != sizeof(policy)) 00156 { 00157 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00158 return FALSE; 00159 } 00160 00161 policy = *(DWORD *)buffer; 00162 TRACE("0x%x\n", policy); 00163 hdr->redirect_policy = policy; 00164 return TRUE; 00165 } 00166 case WINHTTP_OPTION_DISABLE_FEATURE: 00167 set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); 00168 return FALSE; 00169 case WINHTTP_OPTION_RESOLVE_TIMEOUT: 00170 session->resolve_timeout = *(DWORD *)buffer; 00171 return TRUE; 00172 case WINHTTP_OPTION_CONNECT_TIMEOUT: 00173 session->connect_timeout = *(DWORD *)buffer; 00174 return TRUE; 00175 case WINHTTP_OPTION_SEND_TIMEOUT: 00176 session->send_timeout = *(DWORD *)buffer; 00177 return TRUE; 00178 case WINHTTP_OPTION_RECEIVE_TIMEOUT: 00179 session->recv_timeout = *(DWORD *)buffer; 00180 return TRUE; 00181 default: 00182 FIXME("unimplemented option %u\n", option); 00183 set_last_error( ERROR_INVALID_PARAMETER ); 00184 return FALSE; 00185 } 00186 } 00187 00188 static const object_vtbl_t session_vtbl = 00189 { 00190 session_destroy, 00191 session_query_option, 00192 session_set_option 00193 }; 00194 00195 /*********************************************************************** 00196 * WinHttpOpen (winhttp.@) 00197 */ 00198 HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWSTR bypass, DWORD flags ) 00199 { 00200 session_t *session; 00201 HINTERNET handle = NULL; 00202 00203 TRACE("%s, %u, %s, %s, 0x%08x\n", debugstr_w(agent), access, debugstr_w(proxy), debugstr_w(bypass), flags); 00204 00205 if (!(session = heap_alloc_zero( sizeof(session_t) ))) return NULL; 00206 00207 session->hdr.type = WINHTTP_HANDLE_TYPE_SESSION; 00208 session->hdr.vtbl = &session_vtbl; 00209 session->hdr.flags = flags; 00210 session->hdr.refs = 1; 00211 session->hdr.redirect_policy = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP; 00212 session->resolve_timeout = DEFAULT_RESOLVE_TIMEOUT; 00213 session->connect_timeout = DEFAULT_CONNECT_TIMEOUT; 00214 session->send_timeout = DEFAULT_SEND_TIMEOUT; 00215 session->recv_timeout = DEFAULT_RECEIVE_TIMEOUT; 00216 list_init( &session->cookie_cache ); 00217 00218 if (agent && !(session->agent = strdupW( agent ))) goto end; 00219 if (access == WINHTTP_ACCESS_TYPE_DEFAULT_PROXY) 00220 { 00221 WINHTTP_PROXY_INFO info; 00222 00223 WinHttpGetDefaultProxyConfiguration( &info ); 00224 session->access = info.dwAccessType; 00225 if (info.lpszProxy && !(session->proxy_server = strdupW( info.lpszProxy ))) 00226 { 00227 GlobalFree( (LPWSTR)info.lpszProxy ); 00228 GlobalFree( (LPWSTR)info.lpszProxyBypass ); 00229 goto end; 00230 } 00231 if (info.lpszProxyBypass && !(session->proxy_bypass = strdupW( info.lpszProxyBypass ))) 00232 { 00233 GlobalFree( (LPWSTR)info.lpszProxy ); 00234 GlobalFree( (LPWSTR)info.lpszProxyBypass ); 00235 goto end; 00236 } 00237 } 00238 else if (access == WINHTTP_ACCESS_TYPE_NAMED_PROXY) 00239 { 00240 session->access = access; 00241 if (proxy && !(session->proxy_server = strdupW( proxy ))) goto end; 00242 if (bypass && !(session->proxy_bypass = strdupW( bypass ))) goto end; 00243 } 00244 00245 if (!(handle = alloc_handle( &session->hdr ))) goto end; 00246 session->hdr.handle = handle; 00247 00248 end: 00249 release_object( &session->hdr ); 00250 TRACE("returning %p\n", handle); 00251 return handle; 00252 } 00253 00254 /*********************************************************************** 00255 * connect_destroy (internal) 00256 */ 00257 static void connect_destroy( object_header_t *hdr ) 00258 { 00259 connect_t *connect = (connect_t *)hdr; 00260 00261 TRACE("%p\n", connect); 00262 00263 release_object( &connect->session->hdr ); 00264 00265 heap_free( connect->hostname ); 00266 heap_free( connect->servername ); 00267 heap_free( connect->username ); 00268 heap_free( connect->password ); 00269 heap_free( connect ); 00270 } 00271 00272 static BOOL connect_query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen ) 00273 { 00274 connect_t *connect = (connect_t *)hdr; 00275 00276 switch (option) 00277 { 00278 case WINHTTP_OPTION_PARENT_HANDLE: 00279 { 00280 if (!buffer || *buflen < sizeof(HINTERNET)) 00281 { 00282 *buflen = sizeof(HINTERNET); 00283 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00284 return FALSE; 00285 } 00286 00287 *(HINTERNET *)buffer = ((object_header_t *)connect->session)->handle; 00288 *buflen = sizeof(HINTERNET); 00289 return TRUE; 00290 } 00291 case WINHTTP_OPTION_RESOLVE_TIMEOUT: 00292 *(DWORD *)buffer = connect->session->resolve_timeout; 00293 *buflen = sizeof(DWORD); 00294 return TRUE; 00295 case WINHTTP_OPTION_CONNECT_TIMEOUT: 00296 *(DWORD *)buffer = connect->session->connect_timeout; 00297 *buflen = sizeof(DWORD); 00298 return TRUE; 00299 case WINHTTP_OPTION_SEND_TIMEOUT: 00300 *(DWORD *)buffer = connect->session->send_timeout; 00301 *buflen = sizeof(DWORD); 00302 return TRUE; 00303 case WINHTTP_OPTION_RECEIVE_TIMEOUT: 00304 *(DWORD *)buffer = connect->session->recv_timeout; 00305 *buflen = sizeof(DWORD); 00306 return TRUE; 00307 default: 00308 FIXME("unimplemented option %u\n", option); 00309 set_last_error( ERROR_INVALID_PARAMETER ); 00310 return FALSE; 00311 } 00312 } 00313 00314 static const object_vtbl_t connect_vtbl = 00315 { 00316 connect_destroy, 00317 connect_query_option, 00318 NULL 00319 }; 00320 00321 static BOOL domain_matches(LPCWSTR server, LPCWSTR domain) 00322 { 00323 static const WCHAR localW[] = { '<','l','o','c','a','l','>',0 }; 00324 BOOL ret = FALSE; 00325 00326 if (!strcmpiW( domain, localW ) && !strchrW( server, '.' )) 00327 ret = TRUE; 00328 else if (*domain == '*') 00329 { 00330 if (domain[1] == '.') 00331 { 00332 LPCWSTR dot; 00333 00334 /* For a hostname to match a wildcard, the last domain must match 00335 * the wildcard exactly. E.g. if the wildcard is *.a.b, and the 00336 * hostname is www.foo.a.b, it matches, but a.b does not. 00337 */ 00338 dot = strchrW( server, '.' ); 00339 if (dot) 00340 { 00341 int len = strlenW( dot + 1 ); 00342 00343 if (len > strlenW( domain + 2 )) 00344 { 00345 LPCWSTR ptr; 00346 00347 /* The server's domain is longer than the wildcard, so it 00348 * could be a subdomain. Compare the last portion of the 00349 * server's domain. 00350 */ 00351 ptr = dot + len + 1 - strlenW( domain + 2 ); 00352 if (!strcmpiW( ptr, domain + 2 )) 00353 { 00354 /* This is only a match if the preceding character is 00355 * a '.', i.e. that it is a matching domain. E.g. 00356 * if domain is '*.b.c' and server is 'www.ab.c' they 00357 * do not match. 00358 */ 00359 ret = *(ptr - 1) == '.'; 00360 } 00361 } 00362 else 00363 ret = !strcmpiW( dot + 1, domain + 2 ); 00364 } 00365 } 00366 } 00367 else 00368 ret = !strcmpiW( server, domain ); 00369 return ret; 00370 } 00371 00372 /* Matches INTERNET_MAX_HOST_NAME_LENGTH in wininet.h, also RFC 1035 */ 00373 #define MAX_HOST_NAME_LENGTH 256 00374 00375 static BOOL should_bypass_proxy(session_t *session, LPCWSTR server) 00376 { 00377 LPCWSTR ptr; 00378 BOOL ret = FALSE; 00379 00380 if (!session->proxy_bypass) return FALSE; 00381 ptr = session->proxy_bypass; 00382 do { 00383 LPCWSTR tmp = ptr; 00384 00385 ptr = strchrW( ptr, ';' ); 00386 if (!ptr) 00387 ptr = strchrW( tmp, ' ' ); 00388 if (ptr) 00389 { 00390 if (ptr - tmp < MAX_HOST_NAME_LENGTH) 00391 { 00392 WCHAR domain[MAX_HOST_NAME_LENGTH]; 00393 00394 memcpy( domain, tmp, (ptr - tmp) * sizeof(WCHAR) ); 00395 domain[ptr - tmp] = 0; 00396 ret = domain_matches( server, domain ); 00397 } 00398 ptr += 1; 00399 } 00400 else if (*tmp) 00401 ret = domain_matches( server, tmp ); 00402 } while (ptr && !ret); 00403 return ret; 00404 } 00405 00406 BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT port ) 00407 { 00408 session_t *session = connect->session; 00409 BOOL ret = TRUE; 00410 00411 if (session->proxy_server && !should_bypass_proxy(session, server)) 00412 { 00413 LPCWSTR colon; 00414 00415 if ((colon = strchrW( session->proxy_server, ':' ))) 00416 { 00417 if (!connect->servername || strncmpiW( connect->servername, 00418 session->proxy_server, colon - session->proxy_server - 1 )) 00419 { 00420 heap_free( connect->servername ); 00421 if (!(connect->servername = heap_alloc( 00422 (colon - session->proxy_server + 1) * sizeof(WCHAR) ))) 00423 { 00424 ret = FALSE; 00425 goto end; 00426 } 00427 memcpy( connect->servername, session->proxy_server, 00428 (colon - session->proxy_server) * sizeof(WCHAR) ); 00429 connect->servername[colon - session->proxy_server] = 0; 00430 if (*(colon + 1)) 00431 connect->serverport = atoiW( colon + 1 ); 00432 else 00433 connect->serverport = INTERNET_DEFAULT_PORT; 00434 } 00435 } 00436 else 00437 { 00438 if (!connect->servername || strcmpiW( connect->servername, 00439 session->proxy_server )) 00440 { 00441 heap_free( connect->servername ); 00442 if (!(connect->servername = strdupW( session->proxy_server ))) 00443 { 00444 ret = FALSE; 00445 goto end; 00446 } 00447 connect->serverport = INTERNET_DEFAULT_PORT; 00448 } 00449 } 00450 } 00451 else if (server) 00452 { 00453 heap_free( connect->servername ); 00454 if (!(connect->servername = strdupW( server ))) 00455 { 00456 ret = FALSE; 00457 goto end; 00458 } 00459 connect->serverport = port; 00460 } 00461 end: 00462 return ret; 00463 } 00464 00465 /*********************************************************************** 00466 * WinHttpConnect (winhttp.@) 00467 */ 00468 HINTERNET WINAPI WinHttpConnect( HINTERNET hsession, LPCWSTR server, INTERNET_PORT port, DWORD reserved ) 00469 { 00470 connect_t *connect; 00471 session_t *session; 00472 HINTERNET hconnect = NULL; 00473 00474 TRACE("%p, %s, %u, %x\n", hsession, debugstr_w(server), port, reserved); 00475 00476 if (!server) 00477 { 00478 set_last_error( ERROR_INVALID_PARAMETER ); 00479 return NULL; 00480 } 00481 if (!(session = (session_t *)grab_object( hsession ))) 00482 { 00483 set_last_error( ERROR_INVALID_HANDLE ); 00484 return NULL; 00485 } 00486 if (session->hdr.type != WINHTTP_HANDLE_TYPE_SESSION) 00487 { 00488 release_object( &session->hdr ); 00489 set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); 00490 return NULL; 00491 } 00492 if (!(connect = heap_alloc_zero( sizeof(connect_t) ))) 00493 { 00494 release_object( &session->hdr ); 00495 return NULL; 00496 } 00497 connect->hdr.type = WINHTTP_HANDLE_TYPE_CONNECT; 00498 connect->hdr.vtbl = &connect_vtbl; 00499 connect->hdr.refs = 1; 00500 connect->hdr.flags = session->hdr.flags; 00501 connect->hdr.callback = session->hdr.callback; 00502 connect->hdr.notify_mask = session->hdr.notify_mask; 00503 connect->hdr.context = session->hdr.context; 00504 00505 addref_object( &session->hdr ); 00506 connect->session = session; 00507 list_add_head( &session->hdr.children, &connect->hdr.entry ); 00508 00509 if (!(connect->hostname = strdupW( server ))) goto end; 00510 connect->hostport = port; 00511 00512 if (!set_server_for_hostname( connect, server, port )) 00513 goto end; 00514 00515 if (!(hconnect = alloc_handle( &connect->hdr ))) goto end; 00516 connect->hdr.handle = hconnect; 00517 00518 send_callback( &session->hdr, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED, &hconnect, sizeof(hconnect) ); 00519 00520 end: 00521 release_object( &connect->hdr ); 00522 00523 TRACE("returning %p\n", hconnect); 00524 return hconnect; 00525 } 00526 00527 /*********************************************************************** 00528 * request_destroy (internal) 00529 */ 00530 static void request_destroy( object_header_t *hdr ) 00531 { 00532 request_t *request = (request_t *)hdr; 00533 DWORD i; 00534 00535 TRACE("%p\n", request); 00536 00537 release_object( &request->connect->hdr ); 00538 00539 heap_free( request->verb ); 00540 heap_free( request->path ); 00541 heap_free( request->version ); 00542 heap_free( request->raw_headers ); 00543 heap_free( request->status_text ); 00544 for (i = 0; i < request->num_headers; i++) 00545 { 00546 heap_free( request->headers[i].field ); 00547 heap_free( request->headers[i].value ); 00548 } 00549 heap_free( request->headers ); 00550 heap_free( request ); 00551 } 00552 00553 static void str_to_buffer( WCHAR *buffer, const WCHAR *str, LPDWORD buflen ) 00554 { 00555 int len = 0; 00556 if (str) len = strlenW( str ); 00557 if (buffer && *buflen > len) 00558 { 00559 memcpy( buffer, str, len * sizeof(WCHAR) ); 00560 buffer[len] = 0; 00561 } 00562 *buflen = len * sizeof(WCHAR); 00563 } 00564 00565 static WCHAR *blob_to_str( DWORD encoding, CERT_NAME_BLOB *blob ) 00566 { 00567 WCHAR *ret; 00568 DWORD size, format = CERT_SIMPLE_NAME_STR | CERT_NAME_STR_CRLF_FLAG; 00569 00570 size = CertNameToStrW( encoding, blob, format, NULL, 0 ); 00571 if ((ret = LocalAlloc( 0, size * sizeof(WCHAR) ))) 00572 CertNameToStrW( encoding, blob, format, ret, size ); 00573 00574 return ret; 00575 } 00576 00577 static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen ) 00578 { 00579 request_t *request = (request_t *)hdr; 00580 00581 switch (option) 00582 { 00583 case WINHTTP_OPTION_SECURITY_FLAGS: 00584 { 00585 DWORD flags; 00586 int bits; 00587 00588 if (!buffer || *buflen < sizeof(flags)) 00589 { 00590 *buflen = sizeof(flags); 00591 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00592 return FALSE; 00593 } 00594 00595 flags = 0; 00596 if (hdr->flags & WINHTTP_FLAG_SECURE) flags |= SECURITY_FLAG_SECURE; 00597 flags |= request->netconn.security_flags; 00598 bits = netconn_get_cipher_strength( &request->netconn ); 00599 if (bits >= 128) 00600 flags |= SECURITY_FLAG_STRENGTH_STRONG; 00601 else if (bits >= 56) 00602 flags |= SECURITY_FLAG_STRENGTH_MEDIUM; 00603 else 00604 flags |= SECURITY_FLAG_STRENGTH_WEAK; 00605 *(DWORD *)buffer = flags; 00606 *buflen = sizeof(flags); 00607 return TRUE; 00608 } 00609 case WINHTTP_OPTION_SERVER_CERT_CONTEXT: 00610 { 00611 const CERT_CONTEXT *cert; 00612 00613 if (!buffer || *buflen < sizeof(cert)) 00614 { 00615 *buflen = sizeof(cert); 00616 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00617 return FALSE; 00618 } 00619 00620 if (!(cert = netconn_get_certificate( &request->netconn ))) return FALSE; 00621 *(CERT_CONTEXT **)buffer = (CERT_CONTEXT *)cert; 00622 *buflen = sizeof(cert); 00623 return TRUE; 00624 } 00625 case WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT: 00626 { 00627 const CERT_CONTEXT *cert; 00628 const CRYPT_OID_INFO *oidInfo; 00629 WINHTTP_CERTIFICATE_INFO *ci = buffer; 00630 00631 FIXME("partial stub\n"); 00632 00633 if (!buffer || *buflen < sizeof(*ci)) 00634 { 00635 *buflen = sizeof(*ci); 00636 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00637 return FALSE; 00638 } 00639 if (!(cert = netconn_get_certificate( &request->netconn ))) return FALSE; 00640 00641 ci->ftExpiry = cert->pCertInfo->NotAfter; 00642 ci->ftStart = cert->pCertInfo->NotBefore; 00643 ci->lpszSubjectInfo = blob_to_str( cert->dwCertEncodingType, &cert->pCertInfo->Subject ); 00644 ci->lpszIssuerInfo = blob_to_str( cert->dwCertEncodingType, &cert->pCertInfo->Issuer ); 00645 ci->lpszProtocolName = NULL; 00646 oidInfo = CryptFindOIDInfo( CRYPT_OID_INFO_OID_KEY, 00647 cert->pCertInfo->SignatureAlgorithm.pszObjId, 00648 0 ); 00649 if (oidInfo) 00650 ci->lpszSignatureAlgName = (LPWSTR)oidInfo->pwszName; 00651 else 00652 ci->lpszSignatureAlgName = NULL; 00653 ci->lpszEncryptionAlgName = NULL; 00654 ci->dwKeySize = netconn_get_cipher_strength( &request->netconn ); 00655 00656 CertFreeCertificateContext( cert ); 00657 *buflen = sizeof(*ci); 00658 return TRUE; 00659 } 00660 case WINHTTP_OPTION_SECURITY_KEY_BITNESS: 00661 { 00662 if (!buffer || *buflen < sizeof(DWORD)) 00663 { 00664 *buflen = sizeof(DWORD); 00665 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00666 return FALSE; 00667 } 00668 00669 *(DWORD *)buffer = netconn_get_cipher_strength( &request->netconn ); 00670 *buflen = sizeof(DWORD); 00671 return TRUE; 00672 } 00673 case WINHTTP_OPTION_RESOLVE_TIMEOUT: 00674 *(DWORD *)buffer = request->resolve_timeout; 00675 *buflen = sizeof(DWORD); 00676 return TRUE; 00677 case WINHTTP_OPTION_CONNECT_TIMEOUT: 00678 *(DWORD *)buffer = request->connect_timeout; 00679 *buflen = sizeof(DWORD); 00680 return TRUE; 00681 case WINHTTP_OPTION_SEND_TIMEOUT: 00682 *(DWORD *)buffer = request->send_timeout; 00683 *buflen = sizeof(DWORD); 00684 return TRUE; 00685 case WINHTTP_OPTION_RECEIVE_TIMEOUT: 00686 *(DWORD *)buffer = request->recv_timeout; 00687 *buflen = sizeof(DWORD); 00688 return TRUE; 00689 00690 case WINHTTP_OPTION_USERNAME: 00691 str_to_buffer( buffer, request->connect->username, buflen ); 00692 return TRUE; 00693 00694 case WINHTTP_OPTION_PASSWORD: 00695 str_to_buffer( buffer, request->connect->password, buflen ); 00696 return TRUE; 00697 00698 case WINHTTP_OPTION_PROXY_USERNAME: 00699 str_to_buffer( buffer, request->connect->session->proxy_username, buflen ); 00700 return TRUE; 00701 00702 case WINHTTP_OPTION_PROXY_PASSWORD: 00703 str_to_buffer( buffer, request->connect->session->proxy_password, buflen ); 00704 return TRUE; 00705 00706 default: 00707 FIXME("unimplemented option %u\n", option); 00708 set_last_error( ERROR_INVALID_PARAMETER ); 00709 return FALSE; 00710 } 00711 } 00712 00713 static WCHAR *buffer_to_str( WCHAR *buffer, DWORD buflen ) 00714 { 00715 WCHAR *ret; 00716 if ((ret = heap_alloc( (buflen + 1) * sizeof(WCHAR)))) 00717 { 00718 memcpy( ret, buffer, buflen * sizeof(WCHAR) ); 00719 ret[buflen] = 0; 00720 return ret; 00721 } 00722 set_last_error( ERROR_OUTOFMEMORY ); 00723 return NULL; 00724 } 00725 00726 static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen ) 00727 { 00728 request_t *request = (request_t *)hdr; 00729 00730 switch (option) 00731 { 00732 case WINHTTP_OPTION_PROXY: 00733 { 00734 WINHTTP_PROXY_INFO *pi = buffer; 00735 00736 FIXME("%u %s %s\n", pi->dwAccessType, debugstr_w(pi->lpszProxy), debugstr_w(pi->lpszProxyBypass)); 00737 return TRUE; 00738 } 00739 case WINHTTP_OPTION_DISABLE_FEATURE: 00740 { 00741 DWORD disable; 00742 00743 if (buflen != sizeof(DWORD)) 00744 { 00745 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00746 return FALSE; 00747 } 00748 00749 disable = *(DWORD *)buffer; 00750 TRACE("0x%x\n", disable); 00751 hdr->disable_flags |= disable; 00752 return TRUE; 00753 } 00754 case WINHTTP_OPTION_AUTOLOGON_POLICY: 00755 { 00756 DWORD policy; 00757 00758 if (buflen != sizeof(DWORD)) 00759 { 00760 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00761 return FALSE; 00762 } 00763 00764 policy = *(DWORD *)buffer; 00765 TRACE("0x%x\n", policy); 00766 hdr->logon_policy = policy; 00767 return TRUE; 00768 } 00769 case WINHTTP_OPTION_REDIRECT_POLICY: 00770 { 00771 DWORD policy; 00772 00773 if (buflen != sizeof(DWORD)) 00774 { 00775 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00776 return FALSE; 00777 } 00778 00779 policy = *(DWORD *)buffer; 00780 TRACE("0x%x\n", policy); 00781 hdr->redirect_policy = policy; 00782 return TRUE; 00783 } 00784 case WINHTTP_OPTION_SECURITY_FLAGS: 00785 { 00786 DWORD flags; 00787 00788 if (buflen < sizeof(DWORD)) 00789 { 00790 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00791 return FALSE; 00792 } 00793 flags = *(DWORD *)buffer; 00794 TRACE("0x%x\n", flags); 00795 if (!(flags & (SECURITY_FLAG_IGNORE_CERT_CN_INVALID | 00796 SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | 00797 SECURITY_FLAG_IGNORE_UNKNOWN_CA | 00798 SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE))) 00799 { 00800 set_last_error( ERROR_INVALID_PARAMETER ); 00801 return FALSE; 00802 } 00803 request->netconn.security_flags = flags; 00804 return TRUE; 00805 } 00806 case WINHTTP_OPTION_RESOLVE_TIMEOUT: 00807 request->resolve_timeout = *(DWORD *)buffer; 00808 return TRUE; 00809 case WINHTTP_OPTION_CONNECT_TIMEOUT: 00810 request->connect_timeout = *(DWORD *)buffer; 00811 return TRUE; 00812 case WINHTTP_OPTION_SEND_TIMEOUT: 00813 request->send_timeout = *(DWORD *)buffer; 00814 return TRUE; 00815 case WINHTTP_OPTION_RECEIVE_TIMEOUT: 00816 request->recv_timeout = *(DWORD *)buffer; 00817 return TRUE; 00818 00819 case WINHTTP_OPTION_USERNAME: 00820 { 00821 connect_t *connect = request->connect; 00822 00823 heap_free( connect->username ); 00824 if (!(connect->username = buffer_to_str( buffer, buflen ))) return FALSE; 00825 return TRUE; 00826 } 00827 case WINHTTP_OPTION_PASSWORD: 00828 { 00829 connect_t *connect = request->connect; 00830 00831 heap_free( connect->password ); 00832 if (!(connect->password = buffer_to_str( buffer, buflen ))) return FALSE; 00833 return TRUE; 00834 } 00835 case WINHTTP_OPTION_PROXY_USERNAME: 00836 { 00837 session_t *session = request->connect->session; 00838 00839 heap_free( session->proxy_username ); 00840 if (!(session->proxy_username = buffer_to_str( buffer, buflen ))) return FALSE; 00841 return TRUE; 00842 } 00843 case WINHTTP_OPTION_PROXY_PASSWORD: 00844 { 00845 session_t *session = request->connect->session; 00846 00847 heap_free( session->proxy_password ); 00848 if (!(session->proxy_password = buffer_to_str( buffer, buflen ))) return FALSE; 00849 return TRUE; 00850 } 00851 default: 00852 FIXME("unimplemented option %u\n", option); 00853 set_last_error( ERROR_INVALID_PARAMETER ); 00854 return TRUE; 00855 } 00856 } 00857 00858 static const object_vtbl_t request_vtbl = 00859 { 00860 request_destroy, 00861 request_query_option, 00862 request_set_option 00863 }; 00864 00865 /*********************************************************************** 00866 * WinHttpOpenRequest (winhttp.@) 00867 */ 00868 HINTERNET WINAPI WinHttpOpenRequest( HINTERNET hconnect, LPCWSTR verb, LPCWSTR object, LPCWSTR version, 00869 LPCWSTR referrer, LPCWSTR *types, DWORD flags ) 00870 { 00871 request_t *request; 00872 connect_t *connect; 00873 HINTERNET hrequest = NULL; 00874 00875 TRACE("%p, %s, %s, %s, %s, %p, 0x%08x\n", hconnect, debugstr_w(verb), debugstr_w(object), 00876 debugstr_w(version), debugstr_w(referrer), types, flags); 00877 00878 if (!(connect = (connect_t *)grab_object( hconnect ))) 00879 { 00880 set_last_error( ERROR_INVALID_HANDLE ); 00881 return NULL; 00882 } 00883 if (connect->hdr.type != WINHTTP_HANDLE_TYPE_CONNECT) 00884 { 00885 release_object( &connect->hdr ); 00886 set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); 00887 return NULL; 00888 } 00889 if (!(request = heap_alloc_zero( sizeof(request_t) ))) 00890 { 00891 release_object( &connect->hdr ); 00892 return NULL; 00893 } 00894 request->hdr.type = WINHTTP_HANDLE_TYPE_REQUEST; 00895 request->hdr.vtbl = &request_vtbl; 00896 request->hdr.refs = 1; 00897 request->hdr.flags = flags; 00898 request->hdr.callback = connect->hdr.callback; 00899 request->hdr.notify_mask = connect->hdr.notify_mask; 00900 request->hdr.context = connect->hdr.context; 00901 00902 addref_object( &connect->hdr ); 00903 request->connect = connect; 00904 list_add_head( &connect->hdr.children, &request->hdr.entry ); 00905 00906 if (!netconn_init( &request->netconn, request->hdr.flags & WINHTTP_FLAG_SECURE )) goto end; 00907 request->resolve_timeout = connect->session->resolve_timeout; 00908 request->connect_timeout = connect->session->connect_timeout; 00909 request->send_timeout = connect->session->send_timeout; 00910 request->recv_timeout = connect->session->recv_timeout; 00911 00912 if (!verb || !verb[0]) verb = getW; 00913 if (!(request->verb = strdupW( verb ))) goto end; 00914 00915 if (object) 00916 { 00917 WCHAR *path, *p; 00918 unsigned int len; 00919 00920 len = strlenW( object ) + 1; 00921 if (object[0] != '/') len++; 00922 if (!(p = path = heap_alloc( len * sizeof(WCHAR) ))) goto end; 00923 00924 if (object[0] != '/') *p++ = '/'; 00925 strcpyW( p, object ); 00926 request->path = path; 00927 } 00928 else if (!(request->path = strdupW( slashW ))) goto end; 00929 00930 if (!version || !version[0]) version = http1_1; 00931 if (!(request->version = strdupW( version ))) goto end; 00932 00933 if (!(hrequest = alloc_handle( &request->hdr ))) goto end; 00934 request->hdr.handle = hrequest; 00935 00936 send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED, &hrequest, sizeof(hrequest) ); 00937 00938 end: 00939 release_object( &request->hdr ); 00940 00941 TRACE("returning %p\n", hrequest); 00942 return hrequest; 00943 } 00944 00945 /*********************************************************************** 00946 * WinHttpCloseHandle (winhttp.@) 00947 */ 00948 BOOL WINAPI WinHttpCloseHandle( HINTERNET handle ) 00949 { 00950 object_header_t *hdr; 00951 00952 TRACE("%p\n", handle); 00953 00954 if (!(hdr = grab_object( handle ))) 00955 { 00956 set_last_error( ERROR_INVALID_HANDLE ); 00957 return FALSE; 00958 } 00959 release_object( hdr ); 00960 free_handle( handle ); 00961 return TRUE; 00962 } 00963 00964 static BOOL query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen ) 00965 { 00966 BOOL ret = FALSE; 00967 00968 if (!buflen) 00969 { 00970 set_last_error( ERROR_INVALID_PARAMETER ); 00971 return FALSE; 00972 } 00973 00974 switch (option) 00975 { 00976 case WINHTTP_OPTION_CONTEXT_VALUE: 00977 { 00978 if (!buffer || *buflen < sizeof(DWORD_PTR)) 00979 { 00980 *buflen = sizeof(DWORD_PTR); 00981 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 00982 return FALSE; 00983 } 00984 00985 *(DWORD_PTR *)buffer = hdr->context; 00986 *buflen = sizeof(DWORD_PTR); 00987 return TRUE; 00988 } 00989 default: 00990 if (hdr->vtbl->query_option) ret = hdr->vtbl->query_option( hdr, option, buffer, buflen ); 00991 else 00992 { 00993 FIXME("unimplemented option %u\n", option); 00994 set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); 00995 return FALSE; 00996 } 00997 break; 00998 } 00999 return ret; 01000 } 01001 01002 /*********************************************************************** 01003 * WinHttpQueryOption (winhttp.@) 01004 */ 01005 BOOL WINAPI WinHttpQueryOption( HINTERNET handle, DWORD option, LPVOID buffer, LPDWORD buflen ) 01006 { 01007 BOOL ret = FALSE; 01008 object_header_t *hdr; 01009 01010 TRACE("%p, %u, %p, %p\n", handle, option, buffer, buflen); 01011 01012 if (!(hdr = grab_object( handle ))) 01013 { 01014 set_last_error( ERROR_INVALID_HANDLE ); 01015 return FALSE; 01016 } 01017 01018 ret = query_option( hdr, option, buffer, buflen ); 01019 01020 release_object( hdr ); 01021 return ret; 01022 } 01023 01024 static BOOL set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen ) 01025 { 01026 BOOL ret = TRUE; 01027 01028 if (!buffer) 01029 { 01030 set_last_error( ERROR_INVALID_PARAMETER ); 01031 return FALSE; 01032 } 01033 01034 switch (option) 01035 { 01036 case WINHTTP_OPTION_CONTEXT_VALUE: 01037 { 01038 if (buflen != sizeof(DWORD_PTR)) 01039 { 01040 set_last_error( ERROR_INSUFFICIENT_BUFFER ); 01041 return FALSE; 01042 } 01043 01044 hdr->context = *(DWORD_PTR *)buffer; 01045 return TRUE; 01046 } 01047 default: 01048 if (hdr->vtbl->set_option) ret = hdr->vtbl->set_option( hdr, option, buffer, buflen ); 01049 else 01050 { 01051 FIXME("unimplemented option %u\n", option); 01052 set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); 01053 return FALSE; 01054 } 01055 break; 01056 } 01057 return ret; 01058 } 01059 01060 /*********************************************************************** 01061 * WinHttpSetOption (winhttp.@) 01062 */ 01063 BOOL WINAPI WinHttpSetOption( HINTERNET handle, DWORD option, LPVOID buffer, DWORD buflen ) 01064 { 01065 BOOL ret = FALSE; 01066 object_header_t *hdr; 01067 01068 TRACE("%p, %u, %p, %u\n", handle, option, buffer, buflen); 01069 01070 if (!(hdr = grab_object( handle ))) 01071 { 01072 set_last_error( ERROR_INVALID_HANDLE ); 01073 return FALSE; 01074 } 01075 01076 ret = set_option( hdr, option, buffer, buflen ); 01077 01078 release_object( hdr ); 01079 return ret; 01080 } 01081 01082 /*********************************************************************** 01083 * WinHttpDetectAutoProxyConfigUrl (winhttp.@) 01084 */ 01085 BOOL WINAPI WinHttpDetectAutoProxyConfigUrl( DWORD flags, LPWSTR *url ) 01086 { 01087 FIXME("0x%08x, %p\n", flags, url); 01088 01089 set_last_error( ERROR_WINHTTP_AUTODETECTION_FAILED ); 01090 return FALSE; 01091 } 01092 01093 static const WCHAR Connections[] = { 01094 'S','o','f','t','w','a','r','e','\\', 01095 'M','i','c','r','o','s','o','f','t','\\', 01096 'W','i','n','d','o','w','s','\\', 01097 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 01098 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 01099 'C','o','n','n','e','c','t','i','o','n','s',0 }; 01100 static const WCHAR WinHttpSettings[] = { 01101 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 }; 01102 static const DWORD WINHTTPSETTINGS_MAGIC = 0x18; 01103 static const DWORD WINHTTP_PROXY_TYPE_DIRECT = 1; 01104 static const DWORD WINHTTP_PROXY_TYPE_PROXY = 2; 01105 01106 struct winhttp_settings_header 01107 { 01108 DWORD magic; 01109 DWORD unknown; /* always zero? */ 01110 DWORD flags; /* one of WINHTTP_PROXY_TYPE_* */ 01111 }; 01112 01113 static inline void copy_char_to_wchar_sz(const BYTE *src, DWORD len, WCHAR *dst) 01114 { 01115 const BYTE *begin; 01116 01117 for (begin = src; src - begin < len; src++, dst++) 01118 *dst = *src; 01119 *dst = 0; 01120 } 01121 01122 /*********************************************************************** 01123 * WinHttpGetDefaultProxyConfiguration (winhttp.@) 01124 */ 01125 BOOL WINAPI WinHttpGetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info ) 01126 { 01127 LONG l; 01128 HKEY key; 01129 BOOL got_from_reg = FALSE, direct = TRUE; 01130 char *envproxy; 01131 01132 TRACE("%p\n", info); 01133 01134 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key ); 01135 if (!l) 01136 { 01137 DWORD type, size = 0; 01138 01139 l = RegQueryValueExW( key, WinHttpSettings, NULL, &type, NULL, &size ); 01140 if (!l && type == REG_BINARY && 01141 size >= sizeof(struct winhttp_settings_header) + 2 * sizeof(DWORD)) 01142 { 01143 BYTE *buf = heap_alloc( size ); 01144 01145 if (buf) 01146 { 01147 struct winhttp_settings_header *hdr = 01148 (struct winhttp_settings_header *)buf; 01149 DWORD *len = (DWORD *)(hdr + 1); 01150 01151 l = RegQueryValueExW( key, WinHttpSettings, NULL, NULL, buf, 01152 &size ); 01153 if (!l && hdr->magic == WINHTTPSETTINGS_MAGIC && 01154 hdr->unknown == 0) 01155 { 01156 if (hdr->flags & WINHTTP_PROXY_TYPE_PROXY) 01157 { 01158 BOOL sane = FALSE; 01159 LPWSTR proxy = NULL; 01160 LPWSTR proxy_bypass = NULL; 01161 01162 /* Sanity-check length of proxy string */ 01163 if ((BYTE *)len - buf + *len <= size) 01164 { 01165 sane = TRUE; 01166 proxy = GlobalAlloc( 0, (*len + 1) * sizeof(WCHAR) ); 01167 if (proxy) 01168 copy_char_to_wchar_sz( (BYTE *)(len + 1), *len, proxy ); 01169 len = (DWORD *)((BYTE *)(len + 1) + *len); 01170 } 01171 if (sane) 01172 { 01173 /* Sanity-check length of proxy bypass string */ 01174 if ((BYTE *)len - buf + *len <= size) 01175 { 01176 proxy_bypass = GlobalAlloc( 0, (*len + 1) * sizeof(WCHAR) ); 01177 if (proxy_bypass) 01178 copy_char_to_wchar_sz( (BYTE *)(len + 1), *len, proxy_bypass ); 01179 } 01180 else 01181 { 01182 sane = FALSE; 01183 GlobalFree( proxy ); 01184 proxy = NULL; 01185 } 01186 } 01187 info->lpszProxy = proxy; 01188 info->lpszProxyBypass = proxy_bypass; 01189 if (sane) 01190 { 01191 got_from_reg = TRUE; 01192 direct = FALSE; 01193 info->dwAccessType = 01194 WINHTTP_ACCESS_TYPE_NAMED_PROXY; 01195 TRACE("http proxy (from registry) = %s, bypass = %s\n", 01196 debugstr_w(info->lpszProxy), 01197 debugstr_w(info->lpszProxyBypass)); 01198 } 01199 } 01200 } 01201 heap_free( buf ); 01202 } 01203 } 01204 RegCloseKey( key ); 01205 } 01206 if (!got_from_reg && (envproxy = getenv( "http_proxy" ))) 01207 { 01208 char *colon, *http_proxy; 01209 01210 if ((colon = strchr( envproxy, ':' ))) 01211 { 01212 if (*(colon + 1) == '/' && *(colon + 2) == '/') 01213 { 01214 static const char http[] = "http://"; 01215 01216 /* It's a scheme, check that it's http */ 01217 if (!strncmp( envproxy, http, strlen( http ) )) 01218 http_proxy = envproxy + strlen( http ); 01219 else 01220 { 01221 WARN("unsupported scheme in $http_proxy: %s\n", envproxy); 01222 http_proxy = NULL; 01223 } 01224 } 01225 else 01226 http_proxy = envproxy; 01227 } 01228 else 01229 http_proxy = envproxy; 01230 if (http_proxy) 01231 { 01232 WCHAR *http_proxyW; 01233 int len; 01234 01235 len = MultiByteToWideChar( CP_UNIXCP, 0, http_proxy, -1, NULL, 0 ); 01236 if ((http_proxyW = GlobalAlloc( 0, len * sizeof(WCHAR)))) 01237 { 01238 MultiByteToWideChar( CP_UNIXCP, 0, http_proxy, -1, http_proxyW, len ); 01239 direct = FALSE; 01240 info->dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; 01241 info->lpszProxy = http_proxyW; 01242 info->lpszProxyBypass = NULL; 01243 TRACE("http proxy (from environment) = %s\n", 01244 debugstr_w(info->lpszProxy)); 01245 } 01246 } 01247 } 01248 if (direct) 01249 { 01250 info->dwAccessType = WINHTTP_ACCESS_TYPE_NO_PROXY; 01251 info->lpszProxy = NULL; 01252 info->lpszProxyBypass = NULL; 01253 } 01254 return TRUE; 01255 } 01256 01257 /*********************************************************************** 01258 * WinHttpGetIEProxyConfigForCurrentUser (winhttp.@) 01259 */ 01260 BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser( WINHTTP_CURRENT_USER_IE_PROXY_CONFIG *config ) 01261 { 01262 TRACE("%p\n", config); 01263 01264 if (!config) 01265 { 01266 set_last_error( ERROR_INVALID_PARAMETER ); 01267 return FALSE; 01268 } 01269 01270 /* FIXME: read from HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings */ 01271 01272 FIXME("returning no proxy used\n"); 01273 config->fAutoDetect = FALSE; 01274 config->lpszAutoConfigUrl = NULL; 01275 config->lpszProxy = NULL; 01276 config->lpszProxyBypass = NULL; 01277 01278 return TRUE; 01279 } 01280 01281 /*********************************************************************** 01282 * WinHttpGetProxyForUrl (winhttp.@) 01283 */ 01284 BOOL WINAPI WinHttpGetProxyForUrl( HINTERNET hsession, LPCWSTR url, WINHTTP_AUTOPROXY_OPTIONS *options, 01285 WINHTTP_PROXY_INFO *info ) 01286 { 01287 FIXME("%p, %s, %p, %p\n", hsession, debugstr_w(url), options, info); 01288 01289 set_last_error( ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR ); 01290 return FALSE; 01291 } 01292 01293 /*********************************************************************** 01294 * WinHttpSetDefaultProxyConfiguration (winhttp.@) 01295 */ 01296 BOOL WINAPI WinHttpSetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info ) 01297 { 01298 LONG l; 01299 HKEY key; 01300 BOOL ret = FALSE; 01301 const WCHAR *src; 01302 01303 TRACE("%p\n", info); 01304 01305 if (!info) 01306 { 01307 set_last_error( ERROR_INVALID_PARAMETER ); 01308 return FALSE; 01309 } 01310 switch (info->dwAccessType) 01311 { 01312 case WINHTTP_ACCESS_TYPE_NO_PROXY: 01313 break; 01314 case WINHTTP_ACCESS_TYPE_NAMED_PROXY: 01315 if (!info->lpszProxy) 01316 { 01317 set_last_error( ERROR_INVALID_PARAMETER ); 01318 return FALSE; 01319 } 01320 /* Only ASCII characters are allowed */ 01321 for (src = info->lpszProxy; *src; src++) 01322 if (*src > 0x7f) 01323 { 01324 set_last_error( ERROR_INVALID_PARAMETER ); 01325 return FALSE; 01326 } 01327 if (info->lpszProxyBypass) 01328 { 01329 for (src = info->lpszProxyBypass; *src; src++) 01330 if (*src > 0x7f) 01331 { 01332 set_last_error( ERROR_INVALID_PARAMETER ); 01333 return FALSE; 01334 } 01335 } 01336 break; 01337 default: 01338 set_last_error( ERROR_INVALID_PARAMETER ); 01339 return FALSE; 01340 } 01341 01342 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0, 01343 KEY_WRITE, NULL, &key, NULL ); 01344 if (!l) 01345 { 01346 DWORD size = sizeof(struct winhttp_settings_header) + 2 * sizeof(DWORD); 01347 BYTE *buf; 01348 01349 if (info->dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY) 01350 { 01351 size += strlenW( info->lpszProxy ); 01352 if (info->lpszProxyBypass) 01353 size += strlenW( info->lpszProxyBypass ); 01354 } 01355 buf = heap_alloc( size ); 01356 if (buf) 01357 { 01358 struct winhttp_settings_header *hdr = 01359 (struct winhttp_settings_header *)buf; 01360 DWORD *len = (DWORD *)(hdr + 1); 01361 01362 hdr->magic = WINHTTPSETTINGS_MAGIC; 01363 hdr->unknown = 0; 01364 if (info->dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY) 01365 { 01366 BYTE *dst; 01367 01368 hdr->flags = WINHTTP_PROXY_TYPE_PROXY; 01369 *len++ = strlenW( info->lpszProxy ); 01370 for (dst = (BYTE *)len, src = info->lpszProxy; *src; 01371 src++, dst++) 01372 *dst = *src; 01373 len = (DWORD *)dst; 01374 if (info->lpszProxyBypass) 01375 { 01376 *len++ = strlenW( info->lpszProxyBypass ); 01377 for (dst = (BYTE *)len, src = info->lpszProxyBypass; *src; 01378 src++, dst++) 01379 *dst = *src; 01380 } 01381 else 01382 *len++ = 0; 01383 } 01384 else 01385 { 01386 hdr->flags = WINHTTP_PROXY_TYPE_DIRECT; 01387 *len++ = 0; 01388 *len++ = 0; 01389 } 01390 l = RegSetValueExW( key, WinHttpSettings, 0, REG_BINARY, buf, size ); 01391 if (!l) 01392 ret = TRUE; 01393 heap_free( buf ); 01394 } 01395 RegCloseKey( key ); 01396 } 01397 return ret; 01398 } 01399 01400 /*********************************************************************** 01401 * WinHttpSetStatusCallback (winhttp.@) 01402 */ 01403 WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback( HINTERNET handle, WINHTTP_STATUS_CALLBACK callback, 01404 DWORD flags, DWORD_PTR reserved ) 01405 { 01406 object_header_t *hdr; 01407 WINHTTP_STATUS_CALLBACK ret; 01408 01409 TRACE("%p, %p, 0x%08x, 0x%lx\n", handle, callback, flags, reserved); 01410 01411 if (!(hdr = grab_object( handle ))) 01412 { 01413 set_last_error( ERROR_INVALID_HANDLE ); 01414 return WINHTTP_INVALID_STATUS_CALLBACK; 01415 } 01416 ret = hdr->callback; 01417 hdr->callback = callback; 01418 hdr->notify_mask = flags; 01419 01420 release_object( hdr ); 01421 return ret; 01422 } 01423 01424 /*********************************************************************** 01425 * WinHttpSetTimeouts (winhttp.@) 01426 */ 01427 BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int send, int receive ) 01428 { 01429 BOOL ret = TRUE; 01430 object_header_t *hdr; 01431 request_t *request; 01432 session_t *session; 01433 01434 TRACE("%p, %d, %d, %d, %d\n", handle, resolve, connect, send, receive); 01435 01436 if (resolve < -1 || connect < -1 || send < -1 || receive < -1) 01437 { 01438 set_last_error( ERROR_INVALID_PARAMETER ); 01439 return FALSE; 01440 } 01441 01442 if (!(hdr = grab_object( handle ))) 01443 { 01444 set_last_error( ERROR_INVALID_HANDLE ); 01445 return FALSE; 01446 } 01447 01448 switch(hdr->type) 01449 { 01450 case WINHTTP_HANDLE_TYPE_REQUEST: 01451 request = (request_t *)hdr; 01452 request->connect_timeout = connect; 01453 01454 if (resolve < 0) resolve = 0; 01455 request->resolve_timeout = resolve; 01456 01457 if (send < 0) send = 0; 01458 request->send_timeout = send; 01459 01460 if (receive < 0) receive = 0; 01461 request->recv_timeout = receive; 01462 01463 if (netconn_connected( &request->netconn )) 01464 { 01465 if (netconn_set_timeout( &request->netconn, TRUE, send )) ret = FALSE; 01466 if (netconn_set_timeout( &request->netconn, FALSE, receive )) ret = FALSE; 01467 } 01468 01469 release_object( &request->hdr ); 01470 break; 01471 01472 case WINHTTP_HANDLE_TYPE_SESSION: 01473 session = (session_t *)hdr; 01474 session->connect_timeout = connect; 01475 01476 if (resolve < 0) resolve = 0; 01477 session->resolve_timeout = resolve; 01478 01479 if (send < 0) send = 0; 01480 session->send_timeout = send; 01481 01482 if (receive < 0) receive = 0; 01483 session->recv_timeout = receive; 01484 break; 01485 01486 default: 01487 release_object( hdr ); 01488 set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); 01489 return FALSE; 01490 } 01491 return ret; 01492 } 01493 01494 static const WCHAR wkday[7][4] = 01495 {{'S','u','n', 0}, {'M','o','n', 0}, {'T','u','e', 0}, {'W','e','d', 0}, 01496 {'T','h','u', 0}, {'F','r','i', 0}, {'S','a','t', 0}}; 01497 static const WCHAR month[12][4] = 01498 {{'J','a','n', 0}, {'F','e','b', 0}, {'M','a','r', 0}, {'A','p','r', 0}, 01499 {'M','a','y', 0}, {'J','u','n', 0}, {'J','u','l', 0}, {'A','u','g', 0}, 01500 {'S','e','p', 0}, {'O','c','t', 0}, {'N','o','v', 0}, {'D','e','c', 0}}; 01501 01502 /*********************************************************************** 01503 * WinHttpTimeFromSystemTime (WININET.@) 01504 */ 01505 BOOL WINAPI WinHttpTimeFromSystemTime( const SYSTEMTIME *time, LPWSTR string ) 01506 { 01507 static const WCHAR format[] = 01508 {'%','s',',',' ','%','0','2','d',' ','%','s',' ','%','4','d',' ','%','0', 01509 '2','d',':','%','0','2','d',':','%','0','2','d',' ','G','M','T', 0}; 01510 01511 TRACE("%p, %p\n", time, string); 01512 01513 if (!time || !string) return FALSE; 01514 01515 sprintfW( string, format, 01516 wkday[time->wDayOfWeek], 01517 time->wDay, 01518 month[time->wMonth - 1], 01519 time->wYear, 01520 time->wHour, 01521 time->wMinute, 01522 time->wSecond ); 01523 01524 return TRUE; 01525 } 01526 01527 /*********************************************************************** 01528 * WinHttpTimeToSystemTime (WININET.@) 01529 */ 01530 BOOL WINAPI WinHttpTimeToSystemTime( LPCWSTR string, SYSTEMTIME *time ) 01531 { 01532 unsigned int i; 01533 const WCHAR *s = string; 01534 WCHAR *end; 01535 01536 TRACE("%s, %p\n", debugstr_w(string), time); 01537 01538 if (!string || !time) return FALSE; 01539 01540 /* Windows does this too */ 01541 GetSystemTime( time ); 01542 01543 /* Convert an RFC1123 time such as 'Fri, 07 Jan 2005 12:06:35 GMT' into 01544 * a SYSTEMTIME structure. 01545 */ 01546 01547 while (*s && !isalphaW( *s )) s++; 01548 if (s[0] == '\0' || s[1] == '\0' || s[2] == '\0') return TRUE; 01549 time->wDayOfWeek = 7; 01550 01551 for (i = 0; i < 7; i++) 01552 { 01553 if (toupperW( wkday[i][0] ) == toupperW( s[0] ) && 01554 toupperW( wkday[i][1] ) == toupperW( s[1] ) && 01555 toupperW( wkday[i][2] ) == toupperW( s[2] ) ) 01556 { 01557 time->wDayOfWeek = i; 01558 break; 01559 } 01560 } 01561 01562 if (time->wDayOfWeek > 6) return TRUE; 01563 while (*s && !isdigitW( *s )) s++; 01564 time->wDay = strtolW( s, &end, 10 ); 01565 s = end; 01566 01567 while (*s && !isalphaW( *s )) s++; 01568 if (s[0] == '\0' || s[1] == '\0' || s[2] == '\0') return TRUE; 01569 time->wMonth = 0; 01570 01571 for (i = 0; i < 12; i++) 01572 { 01573 if (toupperW( month[i][0]) == toupperW( s[0] ) && 01574 toupperW( month[i][1]) == toupperW( s[1] ) && 01575 toupperW( month[i][2]) == toupperW( s[2] ) ) 01576 { 01577 time->wMonth = i + 1; 01578 break; 01579 } 01580 } 01581 if (time->wMonth == 0) return TRUE; 01582 01583 while (*s && !isdigitW( *s )) s++; 01584 if (*s == '\0') return TRUE; 01585 time->wYear = strtolW( s, &end, 10 ); 01586 s = end; 01587 01588 while (*s && !isdigitW( *s )) s++; 01589 if (*s == '\0') return TRUE; 01590 time->wHour = strtolW( s, &end, 10 ); 01591 s = end; 01592 01593 while (*s && !isdigitW( *s )) s++; 01594 if (*s == '\0') return TRUE; 01595 time->wMinute = strtolW( s, &end, 10 ); 01596 s = end; 01597 01598 while (*s && !isdigitW( *s )) s++; 01599 if (*s == '\0') return TRUE; 01600 time->wSecond = strtolW( s, &end, 10 ); 01601 s = end; 01602 01603 time->wMilliseconds = 0; 01604 return TRUE; 01605 } Generated on Sat May 19 2012 04:22:08 for ReactOS by
1.7.6.1
|