summaryrefslogtreecommitdiffstats
path: root/src/network/kernel/qnetworkproxy_win.cpp
diff options
context:
space:
mode:
authorThierry <thierryb@filewave.com>2012-03-28 20:09:20 +0200
committerQt by Nokia <qt-info@nokia.com>2012-04-03 12:45:46 +0200
commitaad60ec53683e057c05ff760200a467e844cfba3 (patch)
tree5c4401b2e86142714a81f3e4a5cd718166a7266e /src/network/kernel/qnetworkproxy_win.cpp
parent45b7b0599cd1ebdfe17487215b36ff766068f0e8 (diff)
Fixes a problem with the proxy detection on Windows
The current scheme is to use IE's default config. If that fails get the winhttp config. That's ok. The problem is that if you run a program as a service getting the IE config will set the fAutoDetect flag. But later the call to WinHttpGetProxyForUrl mightfail with the error code ERROR_WINHTTP_AUTODETECTION_FAILED. this patch just makes sure that we have a fallback winhttp solution in case the IE proxy is not set. The new code detcted if the current process is a service, in which case it will try to default to the system-wide proxy. Change-Id: I57e9082a46a8422c54f8f069715752c271a3a001 Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Diffstat (limited to 'src/network/kernel/qnetworkproxy_win.cpp')
-rw-r--r--src/network/kernel/qnetworkproxy_win.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp
index 4f1dece4a9..a17f547742 100644
--- a/src/network/kernel/qnetworkproxy_win.cpp
+++ b/src/network/kernel/qnetworkproxy_win.cpp
@@ -113,13 +113,49 @@ typedef HINTERNET (WINAPI * PtrWinHttpOpen)(LPCWSTR, DWORD, LPCWSTR, LPCWSTR,DWO
typedef BOOL (WINAPI * PtrWinHttpGetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*);
typedef BOOL (WINAPI * PtrWinHttpGetIEProxyConfigForCurrentUser)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*);
typedef BOOL (WINAPI * PtrWinHttpCloseHandle)(HINTERNET);
+typedef SC_HANDLE (WINAPI * PtrOpenSCManager)(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess);
+typedef BOOL (WINAPI * PtrEnumServicesStatusEx)(SC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded,
+ LPDWORD lpServicesReturned, LPDWORD lpResumeHandle, LPCWSTR pszGroupName);
+typedef BOOL (WINAPI * PtrCloseServiceHandle)(SC_HANDLE hSCObject);
static PtrWinHttpGetProxyForUrl ptrWinHttpGetProxyForUrl = 0;
static PtrWinHttpOpen ptrWinHttpOpen = 0;
static PtrWinHttpGetDefaultProxyConfiguration ptrWinHttpGetDefaultProxyConfiguration = 0;
static PtrWinHttpGetIEProxyConfigForCurrentUser ptrWinHttpGetIEProxyConfigForCurrentUser = 0;
static PtrWinHttpCloseHandle ptrWinHttpCloseHandle = 0;
+static PtrOpenSCManager ptrOpenSCManager = 0;
+static PtrEnumServicesStatusEx ptrEnumServicesStatusEx = 0;
+static PtrCloseServiceHandle ptrCloseServiceHandle = 0;
+static bool currentProcessIsService()
+{
+ if (!ptrOpenSCManager || !ptrEnumServicesStatusEx|| !ptrCloseServiceHandle)
+ return false;
+
+ SC_HANDLE hSCM = ptrOpenSCManager(0, 0, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
+ if (!hSCM)
+ return false;
+
+ ULONG bufSize = 0;
+ ULONG nbServices = 0;
+ if (ptrEnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, 0, bufSize, &bufSize, &nbServices, 0, 0))
+ return false; //error case
+
+ LPENUM_SERVICE_STATUS_PROCESS info = reinterpret_cast<LPENUM_SERVICE_STATUS_PROCESS>(malloc(bufSize));
+ bool foundService = false;
+ if (ptrEnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, (LPBYTE)info, bufSize, &bufSize, &nbServices, 0, 0)) {
+ DWORD currProcId = GetCurrentProcessId();
+ for (ULONG i = 0; i < nbServices && !foundService; i++) {
+ if (info[i].ServiceStatusProcess.dwProcessId == currProcId)
+ foundService = true;
+ }
+ }
+
+ ptrCloseServiceHandle(hSCM);
+ free(info);
+ return foundService;
+}
+
static QStringList splitSpaceSemicolon(const QString &source)
{
QStringList list;
@@ -364,10 +400,14 @@ void QWindowsSystemProxy::init()
ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)lib.resolve("WinHttpGetProxyForUrl");
ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)lib.resolve("WinHttpGetDefaultProxyConfiguration");
ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser)lib.resolve("WinHttpGetIEProxyConfigForCurrentUser");
+ ptrOpenSCManager = (PtrOpenSCManager) QSystemLibrary(L"advapi32").resolve("OpenSCManagerW");
+ ptrEnumServicesStatusEx = (PtrEnumServicesStatusEx) QSystemLibrary(L"advapi32").resolve("EnumServicesStatusExW");
+ ptrCloseServiceHandle = (PtrCloseServiceHandle) QSystemLibrary(L"advapi32").resolve("CloseServiceHandle");
// Try to obtain the Internet Explorer configuration.
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig;
- if (ptrWinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig)) {
+ const bool hasIEConfig = ptrWinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig);
+ if (hasIEConfig) {
if (ieProxyConfig.lpszAutoConfigUrl) {
autoConfigUrl = QString::fromWCharArray(ieProxyConfig.lpszAutoConfigUrl);
GlobalFree(ieProxyConfig.lpszAutoConfigUrl);
@@ -383,9 +423,13 @@ void QWindowsSystemProxy::init()
proxyBypass = splitSpaceSemicolon(QString::fromWCharArray(ieProxyConfig.lpszProxyBypass));
GlobalFree(ieProxyConfig.lpszProxyBypass);
}
- } else {
+ }
+
+ if (!hasIEConfig ||
+ (currentProcessIsService() && proxyServerList.isEmpty() && proxyBypass.isEmpty())) {
// no user configuration
// attempt to get the default configuration instead
+ // that config will serve as default if WPAD fails
WINHTTP_PROXY_INFO proxyInfo;
if (ptrWinHttpGetDefaultProxyConfiguration(&proxyInfo) &&
proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY) {