Fix the network proxy code for windows to detect properly services

This patch makes it so even sub processes of services are also
detected to be running in the context of a service. With the previous
code it would only detect that the current process is a service
and not the sub processes.

This fix makes sure we detect properly if the current process
is running in the context of a service. This is important to
detect properly the proxy configuration of the current user.

Change-Id: I110dee62597aec3f8e2f6925166a428f72d14fd0
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
Thierry Bastian 2013-07-18 18:20:42 +02:00 committed by The Qt Project
parent c1f76a3347
commit 3655d71719

View File

@ -53,6 +53,7 @@
#include <string.h> #include <string.h>
#include <qt_windows.h> #include <qt_windows.h>
#include <wininet.h> #include <wininet.h>
#include <lmcons.h>
#include "qnetworkfunctions_wince.h" #include "qnetworkfunctions_wince.h"
/* /*
@ -115,48 +116,38 @@ typedef HINTERNET (WINAPI * PtrWinHttpOpen)(LPCWSTR, DWORD, LPCWSTR, LPCWSTR,DWO
typedef BOOL (WINAPI * PtrWinHttpGetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*); typedef BOOL (WINAPI * PtrWinHttpGetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*);
typedef BOOL (WINAPI * PtrWinHttpGetIEProxyConfigForCurrentUser)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*); typedef BOOL (WINAPI * PtrWinHttpGetIEProxyConfigForCurrentUser)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*);
typedef BOOL (WINAPI * PtrWinHttpCloseHandle)(HINTERNET); 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); typedef BOOL (WINAPI * PtrCloseServiceHandle)(SC_HANDLE hSCObject);
static PtrWinHttpGetProxyForUrl ptrWinHttpGetProxyForUrl = 0; static PtrWinHttpGetProxyForUrl ptrWinHttpGetProxyForUrl = 0;
static PtrWinHttpOpen ptrWinHttpOpen = 0; static PtrWinHttpOpen ptrWinHttpOpen = 0;
static PtrWinHttpGetDefaultProxyConfiguration ptrWinHttpGetDefaultProxyConfiguration = 0; static PtrWinHttpGetDefaultProxyConfiguration ptrWinHttpGetDefaultProxyConfiguration = 0;
static PtrWinHttpGetIEProxyConfigForCurrentUser ptrWinHttpGetIEProxyConfigForCurrentUser = 0; static PtrWinHttpGetIEProxyConfigForCurrentUser ptrWinHttpGetIEProxyConfigForCurrentUser = 0;
static PtrWinHttpCloseHandle ptrWinHttpCloseHandle = 0; static PtrWinHttpCloseHandle ptrWinHttpCloseHandle = 0;
static PtrOpenSCManager ptrOpenSCManager = 0;
static PtrEnumServicesStatusEx ptrEnumServicesStatusEx = 0;
static PtrCloseServiceHandle ptrCloseServiceHandle = 0;
#ifndef Q_OS_WINCE
static bool currentProcessIsService() static bool currentProcessIsService()
{ {
if (!ptrOpenSCManager || !ptrEnumServicesStatusEx|| !ptrCloseServiceHandle) typedef BOOL (WINAPI *PtrGetUserName)(LPTSTR lpBuffer, LPDWORD lpnSize);
return false; typedef BOOL (WINAPI *PtrLookupAccountName)(LPCTSTR lpSystemName, LPCTSTR lpAccountName, PSID Sid,
LPDWORD cbSid, LPTSTR ReferencedDomainName, LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse);
static PtrGetUserName ptrGetUserName = (PtrGetUserName)QSystemLibrary::resolve(QLatin1String("Advapi32"), "GetUserNameW");
static PtrLookupAccountName ptrLookupAccountName = (PtrLookupAccountName)QSystemLibrary::resolve(QLatin1String("Advapi32"), "LookupAccountNameW");
SC_HANDLE hSCM = ptrOpenSCManager(0, 0, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT); if (ptrGetUserName && ptrLookupAccountName) {
if (!hSCM) wchar_t userName[UNLEN + 1] = L"";
return false; DWORD size = UNLEN;
if (ptrGetUserName(userName, &size)) {
ULONG bufSize = 0; SID_NAME_USE type = SidTypeUser;
ULONG nbServices = 0; DWORD dummy = MAX_PATH;
if (ptrEnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, 0, bufSize, &bufSize, &nbServices, 0, 0)) wchar_t dummyStr[MAX_PATH] = L"";
return false; //error case PSID psid = 0;
if (ptrLookupAccountName(NULL, userName, &psid, &dummy, dummyStr, &dummy, &type))
LPENUM_SERVICE_STATUS_PROCESS info = reinterpret_cast<LPENUM_SERVICE_STATUS_PROCESS>(malloc(bufSize)); return type != SidTypeUser; //returns true if the current user is not a user
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;
} }
} }
return false;
ptrCloseServiceHandle(hSCM);
free(info);
return foundService;
} }
#endif // ! Q_OS_WINCE
static QStringList splitSpaceSemicolon(const QString &source) static QStringList splitSpaceSemicolon(const QString &source)
{ {
@ -418,9 +409,6 @@ void QWindowsSystemProxy::init()
ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)lib.resolve("WinHttpGetProxyForUrl"); ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)lib.resolve("WinHttpGetProxyForUrl");
ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)lib.resolve("WinHttpGetDefaultProxyConfiguration"); ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)lib.resolve("WinHttpGetDefaultProxyConfiguration");
ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser)lib.resolve("WinHttpGetIEProxyConfigForCurrentUser"); 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. // Try to obtain the Internet Explorer configuration.
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig; WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig;