ReactOS Fundraising Campaign 2012
 
€ 3,873 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

session.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.