diff --git a/checkin_notes b/checkin_notes
index 54e8cd0a7f..03dedb4ca5 100644
--- a/checkin_notes
+++ b/checkin_notes
@@ -9130,3 +9130,18 @@ Rom 19 Dec 2011
samples/vboxwrapper/
vboxwrapper.cpp
vbox.cpp, .h
+
+Rom 19 Dec 2011
+ - WINSETUP: Copy the explorer primary token to get processes launched by the setup
+ process to launch with reduced permissions.
+
+ win_build/installerv2/redist/Windows/src/boinccas/
+ boinccas.vcproj
+ CALaunchBOINCManager.cpp
+ launcher.cpp, .h
+ win_build/installerv2/redist/Windows/Win32/
+ boinccas.dll
+ boinccas95.dll
+ win_build/installerv2/redist/Windows/x64/
+ boinccas.dll
+ boinccas95.dll
diff --git a/win_build/installerv2/redist/Windows/Win32/boinccas.dll b/win_build/installerv2/redist/Windows/Win32/boinccas.dll
index b356234a44..cd80f2be3f 100644
Binary files a/win_build/installerv2/redist/Windows/Win32/boinccas.dll and b/win_build/installerv2/redist/Windows/Win32/boinccas.dll differ
diff --git a/win_build/installerv2/redist/Windows/Win32/boinccas95.dll b/win_build/installerv2/redist/Windows/Win32/boinccas95.dll
index 34940d76d6..75773b6fbc 100644
Binary files a/win_build/installerv2/redist/Windows/Win32/boinccas95.dll and b/win_build/installerv2/redist/Windows/Win32/boinccas95.dll differ
diff --git a/win_build/installerv2/redist/Windows/src/boinccas/CALaunchBOINCManager.cpp b/win_build/installerv2/redist/Windows/src/boinccas/CALaunchBOINCManager.cpp
index 6d31c8447c..5d2b421a0b 100644
--- a/win_build/installerv2/redist/Windows/src/boinccas/CALaunchBOINCManager.cpp
+++ b/win_build/installerv2/redist/Windows/src/boinccas/CALaunchBOINCManager.cpp
@@ -20,28 +20,12 @@
#include "stdafx.h"
#include "boinccas.h"
+#include "launcher.h"
#include "CALaunchBOINCManager.h"
#define CUSTOMACTION_NAME _T("CALaunchBOINCManager")
#define CUSTOMACTION_PROGRESSTITLE _T("Launching BOINC Manager")
-#ifndef SECURITY_MANDATORY_LABEL_AUTHORITY
-
-#define SECURITY_MANDATORY_LABEL_AUTHORITY {0,0,0,0,0,16}
-#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L)
-#define SE_GROUP_INTEGRITY (0x00000020L)
-
-typedef struct _TOKEN_MANDATORY_LABEL {
- SID_AND_ATTRIBUTES Label;
-} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
-
-typedef enum MY_TOKEN_INFORMATION_CLASS {
- TokenVirtualizationEnabled = 24,
- TokenIntegrityLevel = 25
-} MY_TOKEN_INFORMATION_CLASS, *PMY_TOKEN_INFORMATION_CLASS;
-
-#endif
-
/////////////////////////////////////////////////////////////////////
//
// Function:
@@ -75,141 +59,29 @@ CALaunchBOINCManager::~CALaunchBOINCManager()
//
/////////////////////////////////////////////////////////////////////
-typedef BOOL (__stdcall *tSCREATEL)( IN DWORD, IN DWORD, IN DWORD, OUT SAFER_LEVEL_HANDLE*, OUT LPVOID );
-typedef BOOL (__stdcall *tSCTFL)( IN SAFER_LEVEL_HANDLE, IN HANDLE, OUT HANDLE*, IN DWORD, OUT LPVOID );
-typedef BOOL (__stdcall *tSCLOSEL)( IN SAFER_LEVEL_HANDLE );
-
UINT CALaunchBOINCManager::OnExecution()
{
- static HMODULE advapi32lib = NULL;
- static tSCREATEL pSCREATEL = NULL;
- static tSCTFL pSCTFL = NULL;
- static tSCLOSEL pSCLOSEL = NULL;
- PROCESS_INFORMATION process_info;
- STARTUPINFO startup_info;
- SAFER_LEVEL_HANDLE hSaferHandle;
- HANDLE hRestrictedToken;
- SID_IDENTIFIER_AUTHORITY siaMLA = SECURITY_MANDATORY_LABEL_AUTHORITY;
- PSID pSidMedium = NULL;
- TOKEN_MANDATORY_LABEL TIL = {0};
- DWORD dwEnableVirtualization = 1;
tstring strInstallDirectory;
tstring strBuffer;
UINT uiReturnValue = -1;
- FILE* f;
-
- memset(&process_info, 0, sizeof(process_info));
- memset(&startup_info, 0, sizeof(startup_info));
- startup_info.cb = sizeof(startup_info);
- startup_info.dwFlags = STARTF_USESHOWWINDOW;
- startup_info.wShowWindow = SW_SHOW;
-
- f = fopen("LaunchManager.txt", "w");
-
- if (!advapi32lib) {
- advapi32lib = LoadLibraryA("advapi32.dll");
- if (advapi32lib) {
- pSCREATEL = (tSCREATEL)GetProcAddress(advapi32lib, "SaferCreateLevel");
- pSCTFL = (tSCTFL)GetProcAddress(advapi32lib, "SaferComputeTokenFromLevel");
- pSCLOSEL = (tSCLOSEL)GetProcAddress(advapi32lib, "SaferCloseLevel");
- }
- }
-
- if (!pSCREATEL || !pSCTFL || !pSCLOSEL) {
- return ERROR_FILE_NOT_FOUND;
- }
uiReturnValue = GetProperty( _T("INSTALLDIR"), strInstallDirectory );
if ( uiReturnValue ) return uiReturnValue;
- // Calculate a restricted token from the current token.
- if (!pSCREATEL( SAFER_SCOPEID_USER, SAFER_LEVELID_NORMALUSER, SAFER_LEVEL_OPEN, &hSaferHandle, NULL ))
- {
- fwprintf(f, _T("SaferCreateLevel retval: '%d'\n"), GetLastError());
- }
-
- if (!pSCTFL( hSaferHandle, NULL, &hRestrictedToken, NULL, NULL ))
- {
- fwprintf(f, _T("SaferComputeTokenFromLevel retval: '%d'\n"), GetLastError());
- }
-
- AllocateAndInitializeSid(&siaMLA, 1, SECURITY_MANDATORY_MEDIUM_RID, 0, 0, 0, 0, 0, 0, 0, &pSidMedium);
-
- TIL.Label.Attributes = SE_GROUP_INTEGRITY;
- TIL.Label.Sid = pSidMedium;
-
- if (!SetTokenInformation(hRestrictedToken, (TOKEN_INFORMATION_CLASS)TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL)))
- {
- fwprintf(f, _T("SaferComputeTokenFromLevel (TokenIntegrityLevel) retval: '%d'\n"), GetLastError());
- }
-
- if (!SetTokenInformation(hRestrictedToken, (TOKEN_INFORMATION_CLASS)TokenVirtualizationEnabled, &dwEnableVirtualization, sizeof(DWORD)))
- {
- fwprintf(f, _T("SaferComputeTokenFromLevel (TokenVirtualizationEnabled) retval: '%d'\n"), GetLastError());
- }
-
-
strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("boincmgr.exe\""));
- fwprintf(f, _T("Attempting to launch boincmgr.exe\n"));
- fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str());
- if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info ))
- {
- fwprintf(f, _T("Success!!!\n"));
- CloseHandle( process_info.hProcess );
- CloseHandle( process_info.hThread );
- }
- else
- {
- fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError());
- }
+ CreateProcessWithExplorerIL( (LPWSTR)strBuffer.c_str(), NULL );
strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("gridrepublic.exe\""));
- fwprintf(f, _T("Attempting to launch gridrepublic.exe\n"));
- fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str());
- if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info ))
- {
- fwprintf(f, _T("Success!!!\n"));
- CloseHandle( process_info.hProcess );
- CloseHandle( process_info.hThread );
- }
- else
- {
- fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError());
- }
+ CreateProcessWithExplorerIL( (LPWSTR)strBuffer.c_str(), NULL );
strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("charityengine.exe\""));
- fwprintf(f, _T("Attempting to launch charityengine.exe\n"));
- fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str());
- if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info ))
- {
- fwprintf(f, _T("Success!!!\n"));
- CloseHandle( process_info.hProcess );
- CloseHandle( process_info.hThread );
- }
- else
- {
- fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError());
- }
+ CreateProcessWithExplorerIL( (LPWSTR)strBuffer.c_str(), NULL );
strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("progressthruprocessors.exe\""));
- fwprintf(f, _T("Attempting to launch progressthruprocessors.exe\n"));
- fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str());
- if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info ))
- {
- fwprintf(f, _T("Success!!!\n"));
- CloseHandle( process_info.hProcess );
- CloseHandle( process_info.hThread );
- }
- else
- {
- fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError());
- }
+ CreateProcessWithExplorerIL( (LPWSTR)strBuffer.c_str(), NULL );
+
- fclose(f);
- CloseHandle( hRestrictedToken );
- pSCLOSEL( hSaferHandle );
-
return ERROR_SUCCESS;
}
diff --git a/win_build/installerv2/redist/Windows/src/boinccas/boinccas.vcproj b/win_build/installerv2/redist/Windows/src/boinccas/boinccas.vcproj
index 5c7d21bbcf..fa71213135 100644
--- a/win_build/installerv2/redist/Windows/src/boinccas/boinccas.vcproj
+++ b/win_build/installerv2/redist/Windows/src/boinccas/boinccas.vcproj
@@ -465,6 +465,10 @@
RelativePath=".\dirops.cpp"
>
+
+
@@ -618,6 +622,10 @@
RelativePath=".\dirops.h"
>
+
+
diff --git a/win_build/installerv2/redist/Windows/src/boinccas/launcher.cpp b/win_build/installerv2/redist/Windows/src/boinccas/launcher.cpp
new file mode 100644
index 0000000000..91133ae120
--- /dev/null
+++ b/win_build/installerv2/redist/Windows/src/boinccas/launcher.cpp
@@ -0,0 +1,298 @@
+
+#include "stdafx.h"
+#include "boinccas.h"
+#include "launcher.h"
+
+
+#ifndef SECURITY_MANDATORY_UNTRUSTED_RID
+
+#define SECURITY_MANDATORY_UNTRUSTED_RID (0x00000000L)
+#define SECURITY_MANDATORY_LOW_RID (0x00001000L)
+#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L)
+#define SECURITY_MANDATORY_HIGH_RID (0x00003000L)
+#define SECURITY_MANDATORY_SYSTEM_RID (0x00004000L)
+#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID (0x00005000L)
+
+typedef struct _TOKEN_MANDATORY_LABEL {
+ SID_AND_ATTRIBUTES Label;
+} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
+
+typedef enum _MANDATORY_LEVEL {
+ MandatoryLevelUntrusted = 0,
+ MandatoryLevelLow,
+ MandatoryLevelMedium,
+ MandatoryLevelHigh,
+ MandatoryLevelSystem,
+ MandatoryLevelSecureProcess,
+ MandatoryLevelCount
+} MANDATORY_LEVEL, *PMANDATORY_LEVEL;
+
+#define TokenIntegrityLevel ((TOKEN_INFORMATION_CLASS)25)
+#endif //!SECURITY_MANDATORY_UNTRUSTED_RID
+
+/*!
+@brief Function enables/disables/removes a privelege associated with the given token
+@detailed Calls LookupPrivilegeValue() and AdjustTokenPrivileges()
+@param[in] hToken - access token handle
+@param[in] lpszPrivilege - name of privilege to enable/disable
+@param[in] dwAttributes - (SE_PRIVILEGE_ENABLED) to enable or (0) disable or (SE_PRIVILEGE_REMOVED) to remove privilege
+@return HRESULT code
+@todo Removing was checked. To check enabling and disabling.
+*/
+inline HRESULT SetPrivilege(
+ HANDLE hToken,
+ LPCTSTR lpszPrivilege,
+ DWORD dwAttributes=SE_PRIVILEGE_ENABLED
+ )
+{
+ HRESULT hr=S_OK;
+ LUID luid;
+
+ if ( LookupPrivilegeValue(
+ NULL, // lookup privilege on local system
+ lpszPrivilege, // privilege to lookup
+ &luid ) ) // receives LUID of privilege
+ {
+ TOKEN_PRIVILEGES tp;
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ tp.Privileges[0].Attributes = dwAttributes;
+
+ // Enable the privilege or disable all privileges.
+
+ if ( !AdjustTokenPrivileges(
+ hToken,
+ FALSE,
+ &tp,
+ sizeof(TOKEN_PRIVILEGES),
+ (PTOKEN_PRIVILEGES) NULL,
+ (PDWORD) NULL) )
+ hr=HRESULT_FROM_WIN32(GetLastError());
+ }//if(LookupPrivilegeValue(...))
+ else
+ hr=HRESULT_FROM_WIN32(GetLastError());
+
+ return hr;
+}
+
+/*!
+Function removes the priveleges which are not associated by default with explorer.exe at Medium Integration Level in Vista
+@returns HRESULT of the operation on SE_CREATE_GLOBAL_NAME (="SeCreateGlobalPrivilege")
+*/
+inline HRESULT ReducePrivilegesForMediumIL(HANDLE hToken)
+{
+ HRESULT hr=S_OK;
+ hr=SetPrivilege(hToken, SE_CREATE_GLOBAL_NAME, SE_PRIVILEGE_REMOVED);
+
+ SetPrivilege(hToken, SE_BACKUP_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_CREATE_PAGEFILE_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, TEXT("SeCreateSymbolicLinkPrivilege"), SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_DEBUG_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_IMPERSONATE_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_INC_BASE_PRIORITY_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_INCREASE_QUOTA_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_LOAD_DRIVER_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_MANAGE_VOLUME_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_PROF_SINGLE_PROCESS_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_REMOTE_SHUTDOWN_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_RESTORE_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_SECURITY_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_SYSTEM_ENVIRONMENT_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_SYSTEM_PROFILE_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_SYSTEMTIME_NAME, SE_PRIVILEGE_REMOVED);
+ SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, SE_PRIVILEGE_REMOVED);
+
+ return hr;
+}
+
+#define TraceLN(Function, Line) OutputDebugStringA(Function " line:" #Line "\n")
+
+/*!
+@brief Gets Integration level of the given process in Vista.
+In the older OS assumes the integration level is equal to SECURITY_MANDATORY_HIGH_RID
+
+The function opens the process for all access and opens its token for all access.
+Then it extracts token information and closes the handles.
+@param[in] dwProcessId ID of the process to operate
+@param[out] pdwProcessIL pointer to write the value
+@return HRESULT
+@retval { description }
+@remarks Function check for OS version by querying the presence of Kernel32.GetProductInfo function.
+This way is used due to the function is called from InstallShield12 script, so GetVersionEx returns incorrect value.
+@todo restrict access rights when quering for tokens
+*/
+inline HRESULT GetProcessIL(DWORD dwProcessId, LPDWORD pdwProcessIL)
+{
+ HRESULT hr=S_OK;
+ if(!pdwProcessIL)
+ hr=E_INVALIDARG;
+ if(SUCCEEDED(hr))
+ {
+ bool bVista=false;
+ {
+ // When the function is called from IS12, GetVersionEx returns dwMajorVersion=5 on Vista!
+ HMODULE hmodKernel32=LoadLibrary(L"Kernel32");
+ if(hmodKernel32 && GetProcAddress(hmodKernel32, "GetProductInfo"))
+ bVista=true;
+ if(hmodKernel32) FreeLibrary(hmodKernel32);
+ }
+
+ DWORD dwIL=SECURITY_MANDATORY_HIGH_RID;
+ if(bVista)
+ {//Vista
+ HANDLE hToken=NULL;
+ HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
+ if(hProcess)
+ {
+ if(OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
+ {
+ PTOKEN_MANDATORY_LABEL pTIL=NULL;
+ DWORD dwSize=0;
+ if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwSize)
+ && ERROR_INSUFFICIENT_BUFFER==GetLastError() && dwSize)
+ pTIL=(PTOKEN_MANDATORY_LABEL)HeapAlloc(GetProcessHeap(), 0, dwSize);
+
+ if(pTIL && GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwSize, &dwSize))
+ {
+ LPBYTE lpb=GetSidSubAuthorityCount(pTIL->Label.Sid);
+ if(lpb)
+ dwIL = *GetSidSubAuthority(pTIL->Label.Sid, *lpb-1);
+ else
+ hr=E_UNEXPECTED;
+ }
+ if(pTIL)
+ HeapFree(GetProcessHeap(), 0, pTIL);
+ CloseHandle(hToken);
+ }//if(OpenProcessToken(...))
+ CloseHandle(hProcess);
+ }//if(hProcess)
+ }//if(bVista)
+ if(SUCCEEDED(hr))
+ *pdwProcessIL=dwIL;
+ }//if(SUCCEEDED(hr))
+ return hr;
+}
+
+/*!
+@brief Function launches process with the integration level of Explorer on Vista. On the previous OS, simply creates the process.
+
+Function gets the integration level of the current process and Explorer, then launches the new process.
+If the integration levels are equal, CreateProcess is called.
+If Explorer has Medium IL, and the current process has High IL, new token is created, its rights are adjusted
+and CreateProcessWithTokenW is called.
+If Explorer has Medium IL, and the current process has High IL, error is returned.
+@param[in] szProcessName - the name of exe file (see CreatePorcess())
+@param[in] szCmdLine - the name of exe file (see CreatePorcess())
+@return HRESULT code
+@note The function cannot be used in services, due to if uses USER32.FindWindow() to get the proper instance of Explorer.
+The parent of new process in taskmgr.exe, but not the current process.
+@sa ReducePrivilegesForMediumIL()
+*/
+HRESULT CreateProcessWithExplorerIL(LPWSTR szProcessName, LPWSTR szCmdLine)
+{
+ HRESULT hr=S_OK;
+
+ BOOL bRet;
+ HANDLE hToken;
+ HANDLE hNewToken;
+
+ bool bVista=false;
+ { // When the function is called from IS12, GetVersionEx returns dwMajorVersion=5 on Vista!
+ HMODULE hmodKernel32=LoadLibrary(L"Kernel32");
+ if(hmodKernel32 && GetProcAddress(hmodKernel32, "GetProductInfo"))
+ bVista=true;
+ if(hmodKernel32) FreeLibrary(hmodKernel32);
+ }
+
+ PROCESS_INFORMATION ProcInfo = {0};
+ STARTUPINFO StartupInfo = {0};
+
+ if(bVista)
+ {
+ DWORD dwCurIL=SECURITY_MANDATORY_HIGH_RID;
+ DWORD dwExplorerID=0, dwExplorerIL=SECURITY_MANDATORY_HIGH_RID;
+
+ HWND hwndShell=::FindWindow( _T("Progman"), NULL);
+ if(hwndShell)
+ GetWindowThreadProcessId(hwndShell, &dwExplorerID);
+
+ hr=GetProcessIL(dwExplorerID, &dwExplorerIL);
+ if(SUCCEEDED(hr))
+ hr=GetProcessIL(GetCurrentProcessId(), &dwCurIL);
+ if(SUCCEEDED(hr))
+ {
+ if(dwCurIL==SECURITY_MANDATORY_HIGH_RID && dwExplorerIL==SECURITY_MANDATORY_MEDIUM_RID)
+ {
+ HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwExplorerID);
+ if(hProcess)
+ {
+ if(OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
+ {
+ if(!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL,
+ SecurityImpersonation, TokenPrimary, &hNewToken))
+ hr=HRESULT_FROM_WIN32(GetLastError());
+ if(SUCCEEDED(hr))
+ {
+ if(dwCurIL==SECURITY_MANDATORY_MEDIUM_RID && dwExplorerIL==SECURITY_MANDATORY_MEDIUM_RID)
+ {
+ hr=ReducePrivilegesForMediumIL(hNewToken);
+ }//if(dwCurIL==...)
+
+ if(SUCCEEDED(hr))
+ {
+ typedef BOOL (WINAPI *LPFN_CreateProcessWithTokenW)(
+ HANDLE hToken,
+ DWORD dwLogonFlags,
+ LPCWSTR lpApplicationName,
+ LPWSTR lpCommandLine,
+ DWORD dwCreationFlags,
+ LPVOID lpEnvironment,
+ LPCWSTR lpCurrentDirectory,
+ LPSTARTUPINFOW lpStartupInfo,
+ LPPROCESS_INFORMATION lpProcessInfo
+ );
+ LPFN_CreateProcessWithTokenW fnCreateProcessWithTokenW=NULL;
+ HINSTANCE hmodAdvApi32=LoadLibraryA("AdvApi32");
+ if(hmodAdvApi32)
+ fnCreateProcessWithTokenW=(LPFN_CreateProcessWithTokenW)GetProcAddress(hmodAdvApi32, "CreateProcessWithTokenW");
+ if(fnCreateProcessWithTokenW)
+ {
+ bRet=fnCreateProcessWithTokenW(hNewToken, 0,
+ szProcessName, szCmdLine,
+ 0, NULL, NULL, &StartupInfo, &ProcInfo);
+ if(!bRet)
+ hr=HRESULT_FROM_WIN32(GetLastError());
+ }
+ else
+ hr=E_UNEXPECTED;
+ if(hmodAdvApi32)
+ FreeLibrary(hmodAdvApi32);
+ }//if(SUCCEEDED(hr))
+ CloseHandle(hNewToken);
+ }//if (DuplicateTokenEx(...)
+ else
+ hr=HRESULT_FROM_WIN32(GetLastError());
+ CloseHandle(hToken);
+ }//if(OpenProcessToken(...))
+ else
+ hr=HRESULT_FROM_WIN32(GetLastError());
+ CloseHandle(hProcess);
+ }//if(hProcess)
+ }//if(dwCurIL==SECURITY_MANDATORY_HIGH_RID && dwExplorerIL==SECURITY_MANDATORY_MEDIUM_RID)
+ else if(dwCurIL==SECURITY_MANDATORY_MEDIUM_RID && dwExplorerIL==SECURITY_MANDATORY_HIGH_RID)
+ hr=E_ACCESSDENIED;
+ }//if(SUCCEEDED(hr))
+ }//if(bVista)
+
+ if(SUCCEEDED(hr) && !ProcInfo.dwProcessId)
+ {// 2K | XP | Vista & !UAC
+ bRet = CreateProcess(szProcessName, szCmdLine,
+ NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcInfo);
+ if(!bRet)
+ hr=HRESULT_FROM_WIN32(GetLastError());
+ }// 2K | XP | Vista & !UAC
+
+ return hr;
+}
+
+
diff --git a/win_build/installerv2/redist/Windows/src/boinccas/launcher.h b/win_build/installerv2/redist/Windows/src/boinccas/launcher.h
new file mode 100644
index 0000000000..5c56f6746c
--- /dev/null
+++ b/win_build/installerv2/redist/Windows/src/boinccas/launcher.h
@@ -0,0 +1,4 @@
+
+#pragma once
+
+HRESULT CreateProcessWithExplorerIL(LPWSTR szProcessName, LPWSTR szCmdLine);
diff --git a/win_build/installerv2/redist/Windows/x64/boinccas.dll b/win_build/installerv2/redist/Windows/x64/boinccas.dll
index 02b2e02481..0163545abf 100644
Binary files a/win_build/installerv2/redist/Windows/x64/boinccas.dll and b/win_build/installerv2/redist/Windows/x64/boinccas.dll differ
diff --git a/win_build/installerv2/redist/Windows/x64/boinccas95.dll b/win_build/installerv2/redist/Windows/x64/boinccas95.dll
index 08e13e5c9c..a61dadfbb8 100644
Binary files a/win_build/installerv2/redist/Windows/x64/boinccas95.dll and b/win_build/installerv2/redist/Windows/x64/boinccas95.dll differ