指定用户名,拿最小session,实现和用户ui交互。
这样,搞windows的自动化部署,就可以向前一大步啦。
比以前用psexec要用户名密码,指定session要先进多啦。
安全保密性也提高了。。
#include#include #include #include #pragma comment(lib, "WtsApi32.lib")#pragma comment(lib, "advapi32.lib")#pragma comment(lib, "userenv.lib")using namespace std;HANDLE GetUserToken(DWORD dwSessionId){ HANDLE hImpersonationToken = 0; if (!WTSQueryUserToken(dwSessionId, &hImpersonationToken)) { printf(" WTSQueryUserToken ERROR: %d\n", GetLastError()); return FALSE; } DWORD dwNeededSize = 0; HANDLE *realToken = new HANDLE; TOKEN_USER *pTokenUser = NULL; PTOKEN_GROUPS pGroups = NULL; //twice call function if (!GetTokenInformation(hImpersonationToken, TokenUser, NULL, 0, &dwNeededSize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && dwNeededSize > 0) { pTokenUser = (TOKEN_USER*)new BYTE[dwNeededSize]; if (!GetTokenInformation(hImpersonationToken, TokenUser, pTokenUser, dwNeededSize, &dwNeededSize)) { printf("GetTokenInformation ERROR: %d", GetLastError()); } } return hImpersonationToken; } return hImpersonationToken;}bool GetSessionUserName(DWORD dwSessionId, char username[256]){ LPTSTR pBuffer = NULL; DWORD dwBufferLen; if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen)) { printf(" WTSQuerySessionInformation ERROR: %d\n", GetLastError()); return FALSE; } lstrcpy(username ,pBuffer); WTSFreeMemory(pBuffer); return TRUE;}void Usage(void){ printf("==============Usage================\n" "path:\\callsession.exe 'system-admin' 'path:\\xxx.exe start'\n" "==============Usage================\n");}int main(int argc, char **argv){ if(argc==1) { Usage(); return FALSE; } else if(argc==3) { LPSTR lpUsername = argv[1]; LPSTR lpCmdLine = argv[2]; DWORD session_id = -1; DWORD session_count = 0; WTS_SESSION_INFOA *pSession = NULL; char username[256]; BOOL blFound = FALSE; //EnumerateSessions if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &session_count)) { printf("WTSEnumerateSessions ERROR: %d", GetLastError()); return FALSE; } //Get the right user and his session id for(DWORD i = 0; i < session_count; ++i) { GetSessionUserName(pSession[i].SessionId,username); //if( (pSession[i].State == WTSActive) && (pSession[i].State != WTSDisconnected) ) if(!strcmp(lpUsername, username)) { printf("\tSession user's name = %s\n",username); session_id = pSession[i].SessionId; printf("\tsession_id = %d\n",session_id); blFound = TRUE; break; } } if (!blFound){ printf("No login username %s found.", lpUsername); return FALSE; } WTSFreeMemory(pSession); //free meme heap //Duplicate User Token HANDLE hTokenThis = GetUserToken(session_id); HANDLE hTokenDup = NULL; if (!DuplicateTokenEx(hTokenThis, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hTokenDup)) { printf("DuplicateTokenEx ERROR: %d\n", GetLastError()); return FALSE; } if (!SetTokenInformation(hTokenDup, TokenSessionId, &session_id, sizeof(DWORD))) { printf("SetTokenInformation Error === %d\n",GetLastError()); return FALSE; } //init this process info STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(STARTUPINFO)); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFO); si.lpDesktop = "WinSta0\\Default"; //LPVOID pEnv = NULL; DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; //CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE); if (!CreateProcessAsUser(hTokenDup, NULL, lpCmdLine, NULL, NULL, FALSE, dwCreationFlag, NULL, NULL, &si, &pi)) { printf("CreateProcessAsUser Error === %d\n",GetLastError()); return FALSE; } printf("OK"); } return 0;}