From 552225632827ffe66a3a8f4045628cc8762b1a6d Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Thu, 15 May 2014 14:05:48 +0200 Subject: [PATCH] winhttp: Reimplement WinHttpGetProxyForUrl on top of jsproxy. --- dlls/winhttp/Makefile.in | 2 +- dlls/winhttp/pac.js | 244 ------------------------ dlls/winhttp/rsrc.rc | 3 - dlls/winhttp/session.c | 484 ++++++----------------------------------------- 4 files changed, 58 insertions(+), 675 deletions(-) delete mode 100644 dlls/winhttp/pac.js diff --git a/dlls/winhttp/Makefile.in b/dlls/winhttp/Makefile.in index 118c6c1f9bc..948e0edc8a5 100644 --- a/dlls/winhttp/Makefile.in +++ b/dlls/winhttp/Makefile.in @@ -1,6 +1,6 @@ MODULE = winhttp.dll IMPORTLIB = winhttp -IMPORTS = uuid user32 advapi32 +IMPORTS = uuid jsproxy user32 advapi32 DELAYIMPORTS = oleaut32 ole32 crypt32 secur32 EXTRALIBS = $(SOCKET_LIBS) diff --git a/dlls/winhttp/pac.js b/dlls/winhttp/pac.js deleted file mode 100644 index 4cfac535180..00000000000 --- a/dlls/winhttp/pac.js +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2011 Hans Leidekker for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * Based on nsProxyAutoConfig.js from mozilla.org. - */ - -function myIpAddress() { - try { - return dns_resolve(''); - } catch (e) { - return '127.0.0.1'; - } -} - -function dnsResolve(host) { - try { - return dns_resolve(host); - } catch (e) { - return null; - } -} - -function dnsDomainIs(host, domain) { - return (host.length >= domain.length && - host.substring(host.length - domain.length) == domain); -} - -function dnsDomainLevels(host) { - return host.split('.').length-1; -} - -function convert_addr(ipchars) { - var bytes = ipchars.split('.'); - var result = ((bytes[0] & 0xff) << 24) | - ((bytes[1] & 0xff) << 16) | - ((bytes[2] & 0xff) << 8) | - (bytes[3] & 0xff); - return result; -} - -function isInNet(ipaddr, pattern, maskstr) { - var test = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(ipaddr); - if (test == null) { - ipaddr = dnsResolve(ipaddr); - if (ipaddr == null) - return false; - } else if (test[1] > 255 || test[2] > 255 || - test[3] > 255 || test[4] > 255) { - return false; // not an IP address - } - var host = convert_addr(ipaddr); - var pat = convert_addr(pattern); - var mask = convert_addr(maskstr); - return ((host & mask) == (pat & mask)); -} - -function isPlainHostName(host) { - return (host.search('\\.') == -1); -} - -function isResolvable(host) { - var ip = dnsResolve(host); - return (ip != null); -} - -function localHostOrDomainIs(host, hostdom) { - return (host == hostdom) || - (hostdom.lastIndexOf(host + '.', 0) == 0); -} - -function shExpMatch(url, pattern) { - pattern = pattern.replace(/\./g, '\\.'); - pattern = pattern.replace(/\*/g, '.*'); - pattern = pattern.replace(/\?/g, '.'); - var newRe = new RegExp('^'+pattern+'$'); - return newRe.test(url); -} - -var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6}; -var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11}; - -function weekdayRange() { - function getDay(weekday) { - if (weekday in wdays) { - return wdays[weekday]; - } - return -1; - } - var date = new Date(); - var argc = arguments.length; - var wday; - if (argc < 1) - return false; - if (arguments[argc - 1] == 'GMT') { - argc--; - wday = date.getUTCDay(); - } else { - wday = date.getDay(); - } - var wd1 = getDay(arguments[0]); - var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1; - return (wd1 == -1 || wd2 == -1) ? false - : (wd1 <= wday && wday <= wd2); -} - -function dateRange() { - function getMonth(name) { - if (name in months) { - return months[name]; - } - return -1; - } - var date = new Date(); - var argc = arguments.length; - if (argc < 1) { - return false; - } - var isGMT = (arguments[argc - 1] == 'GMT'); - - if (isGMT) { - argc--; - } - // function will work even without explicit handling of this case - if (argc == 1) { - var tmp = parseInt(arguments[0]); - if (isNaN(tmp)) { - return ((isGMT ? date.getUTCMonth() : date.getMonth()) == getMonth(arguments[0])); - } else if (tmp < 32) { - return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp); - } else { - return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) == tmp); - } - } - var year = date.getFullYear(); - var date1, date2; - date1 = new Date(year, 0, 1, 0, 0, 0); - date2 = new Date(year, 11, 31, 23, 59, 59); - var adjustMonth = false; - for (var i = 0; i < (argc >> 1); i++) { - var tmp = parseInt(arguments[i]); - if (isNaN(tmp)) { - var mon = getMonth(arguments[i]); - date1.setMonth(mon); - } else if (tmp < 32) { - adjustMonth = (argc <= 2); - date1.setDate(tmp); - } else { - date1.setFullYear(tmp); - } - } - for (var i = (argc >> 1); i < argc; i++) { - var tmp = parseInt(arguments[i]); - if (isNaN(tmp)) { - var mon = getMonth(arguments[i]); - date2.setMonth(mon); - } else if (tmp < 32) { - date2.setDate(tmp); - } else { - date2.setFullYear(tmp); - } - } - if (adjustMonth) { - date1.setMonth(date.getMonth()); - date2.setMonth(date.getMonth()); - } - if (isGMT) { - var tmp = date; - tmp.setFullYear(date.getUTCFullYear()); - tmp.setMonth(date.getUTCMonth()); - tmp.setDate(date.getUTCDate()); - tmp.setHours(date.getUTCHours()); - tmp.setMinutes(date.getUTCMinutes()); - tmp.setSeconds(date.getUTCSeconds()); - date = tmp; - } - return ((date1 <= date) && (date <= date2)); -} - -function timeRange() { - var argc = arguments.length; - var date = new Date(); - var isGMT= false; - - if (argc < 1) { - return false; - } - if (arguments[argc - 1] == 'GMT') { - isGMT = true; - argc--; - } - - var hour = isGMT ? date.getUTCHours() : date.getHours(); - var date1, date2; - date1 = new Date(); - date2 = new Date(); - - if (argc == 1) { - return (hour == arguments[0]); - } else if (argc == 2) { - return ((arguments[0] <= hour) && (hour <= arguments[1])); - } else { - switch (argc) { - case 6: - date1.setSeconds(arguments[2]); - date2.setSeconds(arguments[5]); - case 4: - var middle = argc >> 1; - date1.setHours(arguments[0]); - date1.setMinutes(arguments[1]); - date2.setHours(arguments[middle]); - date2.setMinutes(arguments[middle + 1]); - if (middle == 2) { - date2.setSeconds(59); - } - break; - default: - throw 'timeRange: bad number of arguments' - } - } - - if (isGMT) { - date.setFullYear(date.getUTCFullYear()); - date.setMonth(date.getUTCMonth()); - date.setDate(date.getUTCDate()); - date.setHours(date.getUTCHours()); - date.setMinutes(date.getUTCMinutes()); - date.setSeconds(date.getUTCSeconds()); - } - return ((date1 <= date) && (date <= date2)); -} diff --git a/dlls/winhttp/rsrc.rc b/dlls/winhttp/rsrc.rc index b18be18f110..3dca59ff3a9 100644 --- a/dlls/winhttp/rsrc.rc +++ b/dlls/winhttp/rsrc.rc @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* @makedep: pac.js */ -pac.js 40 "pac.js" - #define WINE_FILEDESCRIPTION_STR "Wine HTTP Library" #define WINE_FILENAME_STR "winhttp.dll" #define WINE_FILEVERSION_MAJOR 5 diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index ebbec2ea422..e773f050e1f 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -47,9 +47,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(winhttp); #define DEFAULT_SEND_TIMEOUT 30000 #define DEFAULT_RECEIVE_TIMEOUT 30000 -static const WCHAR global_funcsW[] = {'g','l','o','b','a','l','_','f','u','n','c','s',0}; -static const WCHAR dns_resolveW[] = {'d','n','s','_','r','e','s','o','l','v','e',0}; - void set_last_error( DWORD error ) { /* FIXME */ @@ -1258,15 +1255,6 @@ static BOOL is_domain_suffix( const char *domain, const char *suffix ) return FALSE; } -static void printf_addr( const WCHAR *fmt, WCHAR *buf, struct sockaddr_in *addr ) -{ - sprintfW( buf, fmt, - (unsigned int)(ntohl( addr->sin_addr.s_addr ) >> 24 & 0xff), - (unsigned int)(ntohl( addr->sin_addr.s_addr ) >> 16 & 0xff), - (unsigned int)(ntohl( addr->sin_addr.s_addr ) >> 8 & 0xff), - (unsigned int)(ntohl( addr->sin_addr.s_addr ) & 0xff) ); -} - static int reverse_lookup( const struct addrinfo *ai, char *hostname, size_t len ) { int ret = -1; @@ -1622,281 +1610,9 @@ done: return ret; } -static HRESULT WINAPI dispex_QueryInterface( - IDispatchEx *iface, REFIID riid, void **ppv ) -{ - *ppv = NULL; - - if (IsEqualGUID( riid, &IID_IUnknown ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IDispatchEx )) - *ppv = iface; - else - return E_NOINTERFACE; - - return S_OK; -} - -static ULONG WINAPI dispex_AddRef( - IDispatchEx *iface ) -{ - return 2; -} - -static ULONG WINAPI dispex_Release( - IDispatchEx *iface ) -{ - return 1; -} - -static HRESULT WINAPI dispex_GetTypeInfoCount( - IDispatchEx *iface, UINT *info ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI dispex_GetTypeInfo( - IDispatchEx *iface, UINT info, LCID lcid, ITypeInfo **type_info ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI dispex_GetIDsOfNames( - IDispatchEx *iface, REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *id ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI dispex_Invoke( - IDispatchEx *iface, DISPID member, REFIID riid, LCID lcid, WORD flags, - DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep, UINT *err ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI dispex_DeleteMemberByName( - IDispatchEx *iface, BSTR name, DWORD flags ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI dispex_DeleteMemberByDispID( - IDispatchEx *iface, DISPID id ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI dispex_GetMemberProperties( - IDispatchEx *iface, DISPID id, DWORD flags_fetch, DWORD *flags ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI dispex_GetMemberName( - IDispatchEx *iface, DISPID id, BSTR *name ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI dispex_GetNextDispID( - IDispatchEx *iface, DWORD flags, DISPID id, DISPID *next ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI dispex_GetNameSpaceParent( - IDispatchEx *iface, IUnknown **unk ) -{ - return E_NOTIMPL; -} - -#define DISPID_GLOBAL_DNSRESOLVE 0x1000 - -static HRESULT WINAPI dispex_GetDispID( - IDispatchEx *iface, BSTR name, DWORD flags, DISPID *id ) -{ - if (!strcmpW( name, dns_resolveW )) - { - *id = DISPID_GLOBAL_DNSRESOLVE; - return S_OK; - } - return DISP_E_UNKNOWNNAME; -} - -static HRESULT dns_resolve( const WCHAR *hostname, VARIANT *result ) -{ -#ifdef HAVE_GETADDRINFO - static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; - WCHAR addr[16]; - struct addrinfo *ai, *elem; - char *hostnameA; - int res; - - if (hostname[0]) - hostnameA = strdupWA( hostname ); - else - hostnameA = get_computer_name( ComputerNamePhysicalDnsFullyQualified ); - - if (!hostnameA) return E_OUTOFMEMORY; - res = getaddrinfo( hostnameA, NULL, NULL, &ai ); - heap_free( hostnameA ); - if (res) return S_FALSE; - - elem = ai; - while (elem && elem->ai_family != AF_INET) elem = elem->ai_next; - if (!elem) - { - freeaddrinfo( ai ); - return S_FALSE; - } - printf_addr( fmtW, addr, (struct sockaddr_in *)elem->ai_addr ); - freeaddrinfo( ai ); - V_VT( result ) = VT_BSTR; - V_BSTR( result ) = SysAllocString( addr ); - return S_OK; -#else - FIXME("getaddrinfo not found at build time\n"); - return S_FALSE; -#endif -} - -static HRESULT WINAPI dispex_InvokeEx( - IDispatchEx *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, - VARIANT *result, EXCEPINFO *exep, IServiceProvider *caller ) -{ - if (id == DISPID_GLOBAL_DNSRESOLVE) - { - if (params->cArgs != 1) return DISP_E_BADPARAMCOUNT; - if (V_VT(¶ms->rgvarg[0]) != VT_BSTR) return DISP_E_BADVARTYPE; - return dns_resolve( V_BSTR(¶ms->rgvarg[0]), result ); - } - return DISP_E_MEMBERNOTFOUND; -} - -static const IDispatchExVtbl dispex_vtbl = -{ - dispex_QueryInterface, - dispex_AddRef, - dispex_Release, - dispex_GetTypeInfoCount, - dispex_GetTypeInfo, - dispex_GetIDsOfNames, - dispex_Invoke, - dispex_GetDispID, - dispex_InvokeEx, - dispex_DeleteMemberByName, - dispex_DeleteMemberByDispID, - dispex_GetMemberProperties, - dispex_GetMemberName, - dispex_GetNextDispID, - dispex_GetNameSpaceParent -}; - -static IDispatchEx global_dispex = { &dispex_vtbl }; - -static HRESULT WINAPI site_QueryInterface( - IActiveScriptSite *iface, REFIID riid, void **ppv ) -{ - *ppv = NULL; - - if (IsEqualGUID( &IID_IUnknown, riid )) - *ppv = iface; - else if (IsEqualGUID( &IID_IActiveScriptSite, riid )) - *ppv = iface; - else - return E_NOINTERFACE; - - IUnknown_AddRef( (IUnknown *)*ppv ); - return S_OK; -} - -static ULONG WINAPI site_AddRef( - IActiveScriptSite *iface ) -{ - return 2; -} - -static ULONG WINAPI site_Release( - IActiveScriptSite *iface ) -{ - return 1; -} - -static HRESULT WINAPI site_GetLCID( - IActiveScriptSite *iface, LCID *lcid ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI site_GetItemInfo( - IActiveScriptSite *iface, LPCOLESTR name, DWORD mask, - IUnknown **item, ITypeInfo **type_info ) +static BOOL parse_script_result( const char *result, WINHTTP_PROXY_INFO *info ) { - if (!strcmpW( name, global_funcsW ) && mask == SCRIPTINFO_IUNKNOWN) - { - *item = (IUnknown *)&global_dispex; - return S_OK; - } - return E_NOTIMPL; -} - -static HRESULT WINAPI site_GetDocVersionString( - IActiveScriptSite *iface, BSTR *version ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI site_OnScriptTerminate( - IActiveScriptSite *iface, const VARIANT *result, const EXCEPINFO *info ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI site_OnStateChange( - IActiveScriptSite *iface, SCRIPTSTATE state ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI site_OnScriptError( - IActiveScriptSite *iface, IActiveScriptError *error ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI site_OnEnterScript( - IActiveScriptSite *iface ) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI site_OnLeaveScript( - IActiveScriptSite *iface ) -{ - return E_NOTIMPL; -} - -static const IActiveScriptSiteVtbl site_vtbl = -{ - site_QueryInterface, - site_AddRef, - site_Release, - site_GetLCID, - site_GetItemInfo, - site_GetDocVersionString, - site_OnScriptTerminate, - site_OnStateChange, - site_OnScriptError, - site_OnEnterScript, - site_OnLeaveScript -}; - -static IActiveScriptSite script_site = { &site_vtbl }; - -static BOOL parse_script_result( VARIANT result, WINHTTP_PROXY_INFO *info ) -{ - static const WCHAR proxyW[] = {'P','R','O','X','Y'}; - const WCHAR *p; + const char *p; WCHAR *q; int len; @@ -1904,18 +1620,17 @@ static BOOL parse_script_result( VARIANT result, WINHTTP_PROXY_INFO *info ) info->lpszProxy = NULL; info->lpszProxyBypass = NULL; - if (V_VT( &result ) != VT_BSTR) return TRUE; - TRACE("%s\n", debugstr_w( V_BSTR( &result ) )); + TRACE("%s\n", debugstr_a( result )); - p = V_BSTR( &result ); + p = result; while (*p == ' ') p++; - len = strlenW( p ); - if (len >= 5 && !memicmpW( p, proxyW, sizeof(proxyW)/sizeof(WCHAR) )) + len = strlen( p ); + if (len >= 5 && !strncasecmp( p, "PROXY", sizeof("PROXY") - 1 )) { p += 5; while (*p == ' ') p++; if (!*p || *p == ';') return TRUE; - if (!(info->lpszProxy = q = strdupW( p ))) return FALSE; + if (!(info->lpszProxy = q = strdupAW( p ))) return FALSE; info->dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; for (; *q; q++) { @@ -1929,128 +1644,7 @@ static BOOL parse_script_result( VARIANT result, WINHTTP_PROXY_INFO *info ) return TRUE; } -static BSTR include_pac_utils( BSTR script ) -{ - static const WCHAR pacjsW[] = {'p','a','c','.','j','s',0}; - HMODULE hmod = GetModuleHandleA( "winhttp.dll" ); - HRSRC rsrc; - DWORD size; - const char *data; - BSTR ret; - int len; - - if (!(rsrc = FindResourceW( hmod, pacjsW, (LPCWSTR)40 ))) return NULL; - size = SizeofResource( hmod, rsrc ); - data = LoadResource( hmod, rsrc ); - - len = MultiByteToWideChar( CP_ACP, 0, data, size, NULL, 0 ); - if (!(ret = SysAllocStringLen( NULL, len + SysStringLen( script ) + 1 ))) return NULL; - MultiByteToWideChar( CP_ACP, 0, data, size, ret, len ); - ret[len] = 0; - strcatW( ret, script ); - return ret; -} - -#ifdef _WIN64 -#define IActiveScriptParse_Release IActiveScriptParse64_Release -#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew -#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText -#else -#define IActiveScriptParse_Release IActiveScriptParse32_Release -#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew -#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText -#endif - -static BOOL run_script( const BSTR script, const WCHAR *url, WINHTTP_PROXY_INFO *info ) -{ - static const WCHAR jscriptW[] = {'J','S','c','r','i','p','t',0}; - static const WCHAR findproxyW[] = {'F','i','n','d','P','r','o','x','y','F','o','r','U','R','L',0}; - IActiveScriptParse *parser = NULL; - IActiveScript *engine = NULL; - IDispatch *dispatch = NULL; - BOOL ret = FALSE; - CLSID clsid; - DISPID dispid; - BSTR func = NULL, hostname = NULL, full_script = NULL; - URL_COMPONENTSW uc; - VARIANT args[2], result; - DISPPARAMS params; - HRESULT hr, init; - - memset( &uc, 0, sizeof(uc) ); - uc.dwStructSize = sizeof(uc); - if (!WinHttpCrackUrl( url, 0, 0, &uc )) return FALSE; - if (!(hostname = SysAllocStringLen( NULL, uc.dwHostNameLength + 1 ))) return FALSE; - memcpy( hostname, uc.lpszHostName, uc.dwHostNameLength * sizeof(WCHAR) ); - hostname[uc.dwHostNameLength] = 0; - - init = CoInitialize( NULL ); - hr = CLSIDFromProgID( jscriptW, &clsid ); - if (hr != S_OK) goto done; - - hr = CoCreateInstance( &clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, - &IID_IActiveScript, (void **)&engine ); - if (hr != S_OK) goto done; - - hr = IActiveScript_QueryInterface( engine, &IID_IActiveScriptParse, (void **)&parser ); - if (hr != S_OK) goto done; - - hr = IActiveScriptParse_InitNew( parser ); - if (hr != S_OK) goto done; - - hr = IActiveScript_SetScriptSite( engine, &script_site ); - if (hr != S_OK) goto done; - - hr = IActiveScript_AddNamedItem( engine, global_funcsW, SCRIPTITEM_GLOBALMEMBERS ); - if (hr != S_OK) goto done; - - if (!(full_script = include_pac_utils( script ))) goto done; - - hr = IActiveScriptParse_ParseScriptText( parser, full_script, NULL, NULL, NULL, 0, 0, 0, NULL, NULL ); - if (hr != S_OK) goto done; - - hr = IActiveScript_SetScriptState( engine, SCRIPTSTATE_STARTED ); - if (hr != S_OK) goto done; - - hr = IActiveScript_GetScriptDispatch( engine, NULL, &dispatch ); - if (hr != S_OK) goto done; - - if (!(func = SysAllocString( findproxyW ))) goto done; - hr = IDispatch_GetIDsOfNames( dispatch, &IID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispid ); - if (hr != S_OK) goto done; - - V_VT( &args[0] ) = VT_BSTR; - V_BSTR( &args[0] ) = hostname; - V_VT( &args[1] ) = VT_BSTR; - V_BSTR( &args[1] ) = SysAllocString( url ); - - params.rgvarg = args; - params.rgdispidNamedArgs = NULL; - params.cArgs = 2; - params.cNamedArgs = 0; - hr = IDispatch_Invoke( dispatch, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, - ¶ms, &result, NULL, NULL ); - VariantClear( &args[1] ); - if (hr != S_OK) - { - WARN("script failed 0x%08x\n", hr); - goto done; - } - ret = parse_script_result( result, info ); - -done: - SysFreeString( full_script ); - SysFreeString( hostname ); - SysFreeString( func ); - if (dispatch) IDispatch_Release( dispatch ); - if (parser) IActiveScriptParse_Release( parser ); - if (engine) IActiveScript_Release( engine ); - if (SUCCEEDED( init )) CoUninitialize(); - if (!ret) set_last_error( ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT ); - return ret; -} - -static BSTR download_script( const WCHAR *url ) +static char *download_script( const WCHAR *url, DWORD *out_size ) { static const WCHAR typeW[] = {'*','/','*',0}; static const WCHAR *acceptW[] = {typeW, NULL}; @@ -2059,8 +1653,8 @@ static BSTR download_script( const WCHAR *url ) URL_COMPONENTSW uc; DWORD status, size = sizeof(status), offset, to_read, bytes_read, flags = 0; char *tmp, *buffer = NULL; - BSTR script = NULL; - int len; + + *out_size = 0; memset( &uc, 0, sizeof(uc) ); uc.dwStructSize = sizeof(uc); @@ -2089,6 +1683,7 @@ static BSTR download_script( const WCHAR *url ) if (!bytes_read) break; to_read -= bytes_read; offset += bytes_read; + *out_size += bytes_read; if (!to_read) { to_read = size; @@ -2097,19 +1692,51 @@ static BSTR download_script( const WCHAR *url ) buffer = tmp; } } - len = MultiByteToWideChar( CP_ACP, 0, buffer, offset, NULL, 0 ); - if (!(script = SysAllocStringLen( NULL, len ))) goto done; - MultiByteToWideChar( CP_ACP, 0, buffer, offset, script, len ); - script[len] = 0; done: WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); - heap_free( buffer ); heap_free( hostname ); - if (!script) set_last_error( ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT ); - return script; + if (!buffer) set_last_error( ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT ); + return buffer; +} + +struct AUTO_PROXY_SCRIPT_BUFFER +{ + DWORD dwStructSize; + LPSTR lpszScriptBuffer; + DWORD dwScriptBufferSize; +}; + +BOOL WINAPI InternetDeInitializeAutoProxyDll(LPSTR, DWORD); +BOOL WINAPI InternetGetProxyInfo(LPCSTR, DWORD, LPSTR, DWORD, LPSTR *, LPDWORD); +BOOL WINAPI InternetInitializeAutoProxyDll(DWORD, LPSTR, LPSTR, void *, struct AUTO_PROXY_SCRIPT_BUFFER *); + +static BOOL run_script( char *script, DWORD size, const WCHAR *url, WINHTTP_PROXY_INFO *info ) +{ + BOOL ret; + char *result, *urlA; + DWORD len_result; + struct AUTO_PROXY_SCRIPT_BUFFER buffer; + + buffer.dwStructSize = sizeof(buffer); + buffer.lpszScriptBuffer = script; + buffer.dwScriptBufferSize = size; + + if (!(urlA = strdupWA( url ))) return FALSE; + if (!(ret = InternetInitializeAutoProxyDll( 0, NULL, NULL, NULL, &buffer ))) + { + heap_free( urlA ); + return FALSE; + } + if ((ret = InternetGetProxyInfo( urlA, strlen(urlA), NULL, 0, &result, &len_result ))) + { + ret = parse_script_result( result, info ); + heap_free( result ); + } + heap_free( urlA ); + return InternetDeInitializeAutoProxyDll( NULL, 0 ); } /*********************************************************************** @@ -2121,7 +1748,8 @@ BOOL WINAPI WinHttpGetProxyForUrl( HINTERNET hsession, LPCWSTR url, WINHTTP_AUTO WCHAR *detected_pac_url = NULL; const WCHAR *pac_url; session_t *session; - BSTR script; + char *script; + DWORD size; BOOL ret = FALSE; TRACE("%p, %s, %p, %p\n", hsession, debugstr_w(url), options, info); @@ -2154,9 +1782,11 @@ BOOL WINAPI WinHttpGetProxyForUrl( HINTERNET hsession, LPCWSTR url, WINHTTP_AUTO if (options->dwFlags & WINHTTP_AUTOPROXY_CONFIG_URL) pac_url = options->lpszAutoConfigUrl; else pac_url = detected_pac_url; - if (!(script = download_script( pac_url ))) goto done; - ret = run_script( script, url, info ); - SysFreeString( script ); + if ((script = download_script( pac_url, &size ))) + { + ret = run_script( script, size, url, info ); + heap_free( script ); + } done: GlobalFree( detected_pac_url ); -- 2.11.4.GIT