typedef BOOL (CALLBACK * PWTSQueryUserToken)(ULONG SessionId, PHANDLE phToken);
BOOL DSCreateProcess(DWORD flags, DWORD session, LPCTSTR lpApplicationName, LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
{
DWORD Error;
DWORD SessId = 0;
BOOL bQueryed = FALSE;
HANDLE hToken = NULL;
PWTSQueryUserToken pWTSQueryUserToken;
FARPROC pQuery = GetProcAddress(GetModuleHandle("Wtsapi32.dll"), "WTSQueryUserToken");
pWTSQueryUserToken = (PWTSQueryUserToken)pQuery;
if ((flags & CPIF_SESSION) != 0 &&
bQueryed == FALSE && pWTSQueryUserToken != NULL) {
bQueryed = pWTSQueryUserToken(session, &hToken);
//DS_ASSERT(bQueryed != FALSE || ERROR_NO_TOKEN == GetLastError());
SessId = session;
}
if ((flags & CPIF_SESSION) != 0 && bQueryed == FALSE) {
Error = GetActiveLogonSession(&SessId, &hToken, session, TRUE);
bQueryed = (Error == ERROR_SUCCESS);
}
if (bQueryed == FALSE && (CPIF_FIXEDSESS & flags)) {
Error = ERROR_TIMEOUT;
return FALSE;
}
while (bQueryed == FALSE) {
Error = GetActiveSession(&SessId);
if (Error == ERROR_SUCCESS) {
if (pWTSQueryUserToken != NULL) {
bQueryed = pWTSQueryUserToken(SessId, &hToken);
gLogger.info("WTSQueryUserToken: %d %d, hToken %p\n", GetLastError(), bQueryed, hToken);
break;
}
Error = GetActiveLogonSession(&SessId, &hToken, session, TRUE);
if (Error == ERROR_SUCCESS) {
/* Only for Windows 2000! */
bQueryed = TRUE;
break;
}
}
if (Error != ERROR_NOT_LOGON_PROCESS) {
/* Terminal Service is not running! */
//DS_ASSERT(Error == RPC_S_INVALID_BINDING);
Error = GetActiveLogonSession(&SessId, &hToken, session, FALSE);
bQueryed = (Error == ERROR_SUCCESS);
break;
}
break;
}
if (bQueryed == FALSE &&
((CPIF_SYSTEM| CPIF_INTERACITVE) & flags) == CPIF_SYSTEM) {
BOOL created = CreateProcess(lpApplicationName, lpCommandLine,
lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags,
lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
return created;
}
if (bQueryed != FALSE &&
(CPIF_SYSTEM & flags) == CPIF_SYSTEM) {
BOOL bSuccess;
HANDLE hDuplicatedToken = NULL;
CloseHandle(hToken);
bSuccess = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
if (bSuccess == FALSE) {
return FALSE;
}
bSuccess = DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityIdentification, TokenPrimary, &hDuplicatedToken);
CloseHandle(hToken);
if (bSuccess == FALSE) {
return FALSE;
}
hToken = hDuplicatedToken;
bSuccess = SetTokenInformation(hDuplicatedToken, TokenSessionId, (void*)&SessId, sizeof(SessId));
if (bSuccess == FALSE) {
CloseHandle(hToken);
return FALSE;
}
}
#if 0
LUID luid;
TOKEN_PRIVILEGES tp;
if ( LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid) ) {
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hDuplicatedToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL);
}
#endif
if (bQueryed != FALSE) {
BOOL created = FALSE;
HANDLE hDuplicatedToken = NULL;
if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityIdentification, TokenPrimary, &hDuplicatedToken) ) {
created = CreateProcessAsUser(hDuplicatedToken, lpApplicationName, lpCommandLine,
lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags,
lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
gLogger.info("CreateProcessAsUser token %p, error %d, created %d\n", hDuplicatedToken, GetLastError(), created);
CloseHandle(hDuplicatedToken);
}
CloseHandle(hToken);
return created;
}
return FALSE;
}
以高权限启动新进程
// 启动Shell
OSVERSIONINFOEX OSVerInfo;
OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if(!GetVersionEx((OSVERSIONINFO *)&OSVerInfo))
{
OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx((OSVERSIONINFO *)&OSVerInfo);
}
TCHAR atszVerb[16];
if(OSVerInfo.dwMajorVersion >= 6) // Vista 以上
{
_tcscpy(atszVerb,_T("runas"));
}
else
{
_tcscpy(atszVerb,_T(""));
}
USES_CONVERSION;
SHELLEXECUTEINFO se ;
memset(&se,0,sizeof(SHELLEXECUTEINFO));
se.cbSize = sizeof(SHELLEXECUTEINFO);
se.lpVerb = atszVerb;
se.lpFile = W2T(m_bstrShellExe);
se.lpParameters = atszBootCmd;
se.nShow = SW_HIDE ;
se.fMask = SEE_MASK_NOCLOSEPROCESS ;
if(ShellExecuteEx(&se))
{
// 启动成功
}
else
{
// 启动失败,可能UAC没有获得用户许可
}