zoukankan      html  css  js  c++  java
  • 在Windows服务进程中启动需管理员权限(带盾牌图标)的应用程序

    //启动应用程序,path:程序的路径,带exe的,dir:程序的工作路径
    BOOL LaunchApplication(LPTSTR path, LPTSTR dir)
    {
    	char buf[128] = { 0 };
    	BOOL bRet = FALSE;
    	HANDLE hUserTokenDup = NULL;
    	LPVOID pEnv = NULL;
    	do
    	{
    		DWORD dwSessionId = 0;
    		if (0xFFFFFFFF == (dwSessionId = WTSGetActiveConsoleSessionId())) {		
    			Logger::getInstance()->info(__FILE__, __LINE__, "WTSGetActiveConsoleSessionId fail");
    			break;
    		}
    
    #define DEFAULT_WINLOGON_APPLICATION		(TEXT("winlogon.exe"))
    #define DEFAULT_DEFAULT_APPLICATION		(TEXT("explorer.exe")) // 需要以explorer.exe进程的Token来创建Env环境块,否则以服务启动的App在打开文件路径的方面可能会遇到一些问题,比如最常见的是会访问C:WindowsSystem32configsystemprofile导致访问了错误的位置。
    
    		DWORD dwWinlogonPid = 0;
    		if (0xFFFFFFFF == (dwWinlogonPid = GetProcessID(DEFAULT_WINLOGON_APPLICATION, dwSessionId)))
    		{
    			Logger::getInstance()->info(__FILE__, __LINE__, "Get Process ID Failed!");
    			break;
    		}
    		if (NULL == (hUserTokenDup = GetProcessTokenDup(dwWinlogonPid)))
    		{
    			Logger::getInstance()->info(__FILE__, __LINE__, "Get Process Duplicate Token Failed!");
    			break;
    		}
    		if (!AdjustProcessTokenDup(hUserTokenDup, dwSessionId)) {
    			Logger::getInstance()->info(__FILE__, __LINE__, "Adjust Process Token Failed!");
    			break;
    		}
    		sprintf_s(buf, "dwSessionId=%d", dwSessionId);
    		Logger::getInstance()->info(__FILE__, __LINE__, "Adjust Process Token Failed!");
    		//HANDLE hDefaultTokenDup2 = NULL;
    		//DWORD dwDefaultPid = 0;
    		//if (0xFFFFFFFF == (dwDefaultPid = GetProcessID(DEFAULT_DEFAULT_APPLICATION, dwSessionId))) {
    		//	/*PRINT(ERR, TEXT("Get Process ID Failed!"));*/
    		//	break;
    		//}
    		//if (NULL == (hDefaultTokenDup2 = GetProcessTokenDup(dwDefaultPid))) {
    		//	/*PRINT(ERR, TEXT("Get Process Duplicate Token Failed!")); */
    		//	break;
    		//}
    
    		// Create Environment Block
    		/*DWORD dwCreateFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
    		if (CreateEnvironmentBlock(&pEnv, hDefaultTokenDup2, TRUE)) { dwCreateFlags |= CREATE_UNICODE_ENVIRONMENT; }*/
    
    		// Launch Process In The Client's Logon Session
    		/*TCHAR szExecute[MAX_PATH] = { 0 };
    		GetModuleFileName(NULL, szExecute, _countof(szExecute));
    		_tcsrchr(szExecute, TEXT('\'))[1] = TEXT('');
    		StringCbCat(szExecute, _countof(szExecute) - _tcslen(szExecute), lpszExecute);*/
    
    		/*TCHAR szCmdLine[MAX_PATH] = { 0 };
    		if (NULL != lpszCmdLine) {
    		StringCchPrintf(szCmdLine, _countof(szCmdLine), TEXT("%s"), lpszCmdLine);
    		}*/
    
    		PROCESS_INFORMATION pi = { 0 };
    		SECURITY_ATTRIBUTES sa = {0};
    		sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    		STARTUPINFO si = { sizeof(STARTUPINFO) };
    		si.lpDesktop = TEXT("winsta0\default");
    		si.wShowWindow = SW_SHOW;
    		si.dwFlags = STARTF_USESHOWWINDOW;
    		si.cb = sizeof(STARTUPINFO);
    
    		BOOL ret = CreateProcessAsUser(hUserTokenDup,
    			path,
    			NULL,
    			&sa,
    			&sa,
    			FALSE,
    			NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
    			NULL,
    			dir,
    			&si,
    			&pi);
    		if (!ret)
    		{
    			sprintf_s(buf, "ret=%d,nError=%d", ret, GetLastError());
    			Logger::getInstance()->info(__FILE__, __LINE__, buf);
    			break;
    		}
    		char buf[128] = { 0 };
    		sprintf_s(buf, "CreateProcessAsUser :ret=%d,nError=%d", ret, GetLastError());
    		Logger::getInstance()->info(__FILE__, __LINE__, buf);
    		CloseHandle(pi.hThread);
    		CloseHandle(pi.hProcess);
    
    		// Completed
    		bRet = TRUE;
    	} while (FALSE);
    
    	if (NULL != pEnv) { DestroyEnvironmentBlock(pEnv);  pEnv = NULL; }
    	if (NULL != hUserTokenDup) { CloseHandle(hUserTokenDup); hUserTokenDup = NULL; }
    	return bRet;
    }
    

      

    DWORD GetProcessID(LPCTSTR lpszProcessName, DWORD dwSessionId)
    {
    	DWORD dwProcessId = 0xFFFFFFFF;
    	HANDLE hSnapshot = INVALID_HANDLE_VALUE;
    	do
    	{
    		_ASSERT(NULL != lpszProcessName);
    		if (NULL == lpszProcessName) { break; }
    
    		hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    		if (INVALID_HANDLE_VALUE == hSnapshot) {
    			Logger::getInstance()->info(__FILE__, __LINE__, "CreateToolhelp32Snapshot error");
    			break;
    		}
    
    		PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
    		if (!Process32First(hSnapshot, &pe32)) {
    			Logger::getInstance()->info(__FILE__, __LINE__, "Process32First error");
    			break;
    		}
    
    		do
    		{
    			if (0 == _tcsicmp(pe32.szExeFile, lpszProcessName))
    			{
    				DWORD dwProcessSessionId = 0;
    				if (ProcessIdToSessionId(pe32.th32ProcessID, &dwProcessSessionId)
    					&& (dwSessionId == dwProcessSessionId))
    				{
    					dwProcessId = pe32.th32ProcessID;
    					break;
    				}
    			}
    		} while (Process32Next(hSnapshot, &pe32));
    
    		// Completed
    	} while (FALSE);
    
    	if (INVALID_HANDLE_VALUE != hSnapshot) { CloseHandle(hSnapshot); hSnapshot = INVALID_HANDLE_VALUE; }
    	return dwProcessId;
    }
    

      

    HANDLE GetProcessTokenDup(DWORD dwProcessId)
    {
    	HANDLE hProcess = NULL;
    	HANDLE hToken = NULL;
    	HANDLE hTokenDup = NULL;
    	do
    	{
    		if (NULL == (hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwProcessId))) {
    			Logger::getInstance()->info(__FILE__, __LINE__, "OpenProcess");//PRINT(ERR, GetLastError(), TEXT("OpenProcess")); 
    			break;
    		}
    		if (!OpenProcessToken(hProcess,
    			TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE,
    			&hToken))
    		{
    			Logger::getInstance()->info(__FILE__, __LINE__, "OpenProcessToken");
    			break;
    		}
    
    		if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup)) {
    			
    			Logger::getInstance()->info(__FILE__, __LINE__, "DuplicateTokenEx");  
    			break;
    		}
    
    		// Completed
    	} while (FALSE);
    	if (NULL != hToken) { CloseHandle(hToken); hToken = NULL; }
    	if (NULL != hProcess) { CloseHandle(hProcess); hProcess = NULL; }
    	return hTokenDup;
    }
    

      

    BOOL AdjustProcessTokenDup(HANDLE hTokenDup, DWORD dwSessionId)
    {
    	BOOL bRet = FALSE;
    	do
    	{
    		if (NULL == hTokenDup) { break; }
    
    		// Adjust Token Privileges
    		if (!SetTokenInformation(hTokenDup, TokenSessionId, (LPVOID)&dwSessionId, sizeof(dwSessionId))) {
    			Logger::getInstance()->info(__FILE__, __LINE__, "SetTokenInformation");  
    			break;
    		}
    
    		if (!AdjustTokenDupPrivileges(hTokenDup, SE_DEBUG_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "Enable SE_DEBUG_NAME Privilege Failed!"); }
    		if (!AdjustTokenDupPrivileges(hTokenDup, SE_TCB_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "Enable SE_TCB_NAME Privilege Failed!");}
    		if (!AdjustTokenDupPrivileges(hTokenDup, SE_CHANGE_NOTIFY_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "Enable SE_CHANGE_NOTIFY_NAME Privilege Failed!");}
    		if (!AdjustTokenDupPrivileges(hTokenDup, SE_INCREASE_QUOTA_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "Enable SE_INCREASE_QUOTA_NAME Privilege Failed!"); }
    		if (!AdjustTokenDupPrivileges(hTokenDup, SE_ASSIGNPRIMARYTOKEN_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "Enable SE_ASSIGNPRIMARYTOKEN_NAME Privilege Failed!"); }
    
    		// Completed
    		bRet = TRUE;
    	} while (FALSE);
    	return bRet;
    }
    

      

    BOOL AdjustTokenDupPrivileges(HANDLE hTokenDup, LPCTSTR lpszPrivileges)
    {
    	BOOL bRet = FALSE;
    	do
    	{
    		LUID luid = { 0 };
    		if (!LookupPrivilegeValue(NULL, lpszPrivileges, &luid))
    		{
    			Logger::getInstance()->info(__FILE__, __LINE__, "LookupPrivilegeValue");//PRINT(ERR, GetLastError(), TEXT("LookupPrivilegeValue"));
    			break;
    		}
    
    		TOKEN_PRIVILEGES tp = { 0 };
    		tp.PrivilegeCount = 1;
    		tp.Privileges[0].Luid = luid;
    		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
    		// Adjust token privileges
    		if (!AdjustTokenPrivileges(hTokenDup, FALSE, &tp, sizeof(tp), NULL, NULL))
    		{
    			Logger::getInstance()->info(__FILE__, __LINE__, "AdjustTokenPrivileges");//PRINT(ERR, GetLastError(), TEXT("AdjustTokenPrivileges"));
    			break;
    		}
    		// Completed
    		bRet = TRUE;
    	} while (FALSE);
    	return bRet;
    }
    

      

  • 相关阅读:
    第二次作业
    复盘一个商品期货的通用模型
    C#如何获取枚举(Enum)变量的值
    [C#]Socket通信BeginReceive异步接收数据何时回调Callback
    [C#]浮点数除零无法捕获异常的解决办法
    js对字符串进行编码方法总结
    web最全资源网址
    简单粗暴地理解js原型链--js面向对象编程
    常见前端九十道面试题及答案-韩烨
    C语言文件读写,复制
  • 原文地址:https://www.cnblogs.com/alinh/p/12410526.html
Copyright © 2011-2022 走看看