使用服务提升程序的权限及不同用户切换时显示客户端程序的图标

来源:互联网 发布:vb和易语言 编辑:程序博客网 时间:2024/06/07 00:58

  在Win7和Vista下用户开启UAC权限时普通用户获取管理员权限时会弹出用户账户控制的对话框,当用户点击否时程序无法获取管理员,这样程序无法提升权限。 可以通过服务启动程序,就可以避免弹出用户账户控制,在服务中使用CreateProcessAsUser改变程序的权限。

  服务程序启动客户端程序时,若客户端程序是GUI程序,则程序切换不同的用户时会导致客户端程序的图标不显示,为了显示客户端程序的图标,可以使用当前用户的句柄来创建要启动的进程,即使用explorer.exe的句柄,对于需要提升程序权限的部分,使用winlogon.exe的句柄。

 程序范例如下:

BOOL LaunchAppIntoDifferentSession()
{
 PROCESS_INFORMATION pi;
 STARTUPINFO si;
 BOOL bResult = FALSE;
 DWORD dwSessionId,winlogonPid;
 HANDLE hUserToken,hUserTokenDup,hPToken,hProcess;
 DWORD dwCreationFlags;

 // Log the client on to the local computer.

// dwSessionId = WTSGetActiveConsoleSessionId();

PWTS_SESSION_INFO  pSessionInfo = 0; 
 DWORD dwCount = 0;  
 ::WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount); 
 int session_id = 0; 
 for (DWORD i = 0; i < dwCount; ++i)
 {       
  WTS_SESSION_INFO si = pSessionInfo[i];  
  if (WTSActive == si.State)   
  {         
   session_id = si.SessionId;   
   break;     
  } 
 }    ::WTSFreeMemory(pSessionInfo);
 dwSessionId=session_id;

 //////////////////////////////////////////
 // Find the winlogon process
 ////////////////////////////////////////

 PROCESSENTRY32 procEntry;

 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 if (hSnap == INVALID_HANDLE_VALUE)
 {
  return 1 ;
 }

 procEntry.dwSize = sizeof(PROCESSENTRY32);

 if (!Process32First(hSnap, &procEntry))
 {
  return 1 ;
 }

 do
 {
  //if (_stricmp(procEntry.szExeFile, "explorer.exe") == 0)
  if (_stricmp(procEntry.szExeFile, "winlogon.exe") == 0)
  {
   // We found a winlogon process...make sure it's running in the console session
   DWORD winlogonSessId = 0;
   if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId)
   {
    winlogonPid = procEntry.th32ProcessID;
    break;
   }
  }

 } while (Process32Next(hSnap, &procEntry));

 ////////////////////////////////////////////////////////////////////////

 WTSQueryUserToken(dwSessionId,&hUserToken);
 dwCreationFlags = NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE;
 ZeroMemory(&si, sizeof(STARTUPINFO));
 si.cb= sizeof(STARTUPINFO);
 si.lpDesktop = "winsta0\\default";
 ZeroMemory(&pi, sizeof(pi));
 TOKEN_PRIVILEGES tp;
 LUID luid;
 hProcess = OpenProcess(MAXIMUM_ALLOWED,FALSE,winlogonPid);

 if(!::OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY
  |TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_ADJUST_SESSIONID
  |TOKEN_READ|TOKEN_WRITE,&hPToken))
 {
 }

 if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid))
 {

 }
 tp.PrivilegeCount =1;
 tp.Privileges[0].Luid =luid;
 tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;

 DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hUserTokenDup);
 int dup = GetLastError();

 //Adjust Token privilege
 SetTokenInformation(hUserTokenDup,TokenSessionId,(void*)dwSessionId,sizeof(DWORD));

 if (!AdjustTokenPrivileges(hUserTokenDup,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,NULL))
 {

 }

 if (GetLastError()== ERROR_NOT_ALL_ASSIGNED)
 {

 }

 LPVOID pEnv =NULL;

 if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE))
 {
  dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
 }
 else
  pEnv=NULL;

 // Launch the process in the client's logon session.
 char ProtectEXEPATH[MAX_PATH]={"0"};
 sprintf(ProtectEXEPATH,"%s%s",g_strMainAppPath,EXENAME);

 bResult = CreateProcessAsUser(
  hUserTokenDup,            // client's access token
  ProtectEXEPATH/*_T("C:\\ModifyTTL.exe")*/,              // file to execute
  NULL,     // command line
  NULL,              // pointer to process SECURITY_ATTRIBUTES
  NULL,              // pointer to thread SECURITY_ATTRIBUTES
  FALSE,             // handles are not inheritable
  dwCreationFlags,  // creation flags
  pEnv,              // pointer to new environment block
  NULL,              // name of current directory
  &si,               // pointer to STARTUPINFO structure
  &pi                // receives information about new process
  );
 // End impersonation of client.

 //GetLastError Shud be 0

 int iResultOfCreateProcessAsUser = GetLastError();

 //Perform All the Close Handles task

 CloseHandle(hProcess);
 CloseHandle(hUserToken);
 CloseHandle(hUserTokenDup);
 CloseHandle(hPToken);

 return 0;
}

 

0 0
原创粉丝点击