KEY: CreateProcessAsUser, service GUI interactive, C++ 启动进程

用于xp,server 2003,不适用于vista以上(http://blog.csdn.net/zhyRzfirst/archive/2009/03/16/3994344.aspx,http://www.codeproject.com/KB/vista-security/VistaSessions.aspx,可遍历WTSEnumerateSessions获取活跃桌面后设置STARTUPINFO参数中的lpDesktop参数)

CreateProcessAsUser 1314错误解决:控制面板-管理工具-本地安全策略-本地策略-用户权限分配-替换一个进程级令牌-添加本用户

参考:

http://stackoverflow.com/questions/267838/how-can-a-windows-service-execute-a-gui-application

http://support.microsoft.com/kb/165194

#include "stdafx.h"
#include <iostream>
using namespace std;
#define RTN_OK     0#define RTN_ERROR 13#define WINSTA_ALL (WINSTA_ACCESSCLIPBOARD  | WINSTA_ACCESSGLOBALATOMS |\WINSTA_CREATEDESKTOP    | WINSTA_ENUMDESKTOPS      |\WINSTA_ENUMERATE        | WINSTA_EXITWINDOWS       |\WINSTA_READATTRIBUTES   | WINSTA_READSCREEN        |\WINSTA_WRITEATTRIBUTES  | DELETE                   |\READ_CONTROL            | WRITE_DAC                |\WRITE_OWNER)#define DESKTOP_ALL (DESKTOP_CREATEMENU      | DESKTOP_CREATEWINDOW  |\DESKTOP_ENUMERATE       | DESKTOP_HOOKCONTROL   |\DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD |\DESKTOP_READOBJECTS     | DESKTOP_SWITCHDESKTOP |\DESKTOP_WRITEOBJECTS    | DELETE                |\READ_CONTROL            | WRITE_DAC             |\WRITE_OWNER)#define GENERIC_ACCESS (GENERIC_READ    | GENERIC_WRITE |\GENERIC_EXECUTE | GENERIC_ALL)#include <windows.h>#include <stdio.h>BOOL ObtainSid(HANDLE hToken,           // Handle to an process access token.PSID   *psid             // ptr to the buffer of the logon sid);void RemoveSid(PSID *psid               // ptr to the buffer of the logon sid);BOOL AddTheAceWindowStation(HWINSTA hwinsta,         // handle to a windowstationPSID    psid             // logon sid of the process);BOOL AddTheAceDesktop(HDESK hdesk,             // handle to a desktopPSID  psid               // logon sid of the process);int main(void){HANDLE              hToken;HDESK               hdesk;HWINSTA             hwinsta;PROCESS_INFORMATION pi;PSID                psid;STARTUPINFO         si;// // obtain an access token for the user fester// if (!LogonUser("yangyh",NULL,"adobe",LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hToken))return RTN_ERROR;// // obtain a handle to the interactive windowstation// hwinsta = OpenWindowStation("winsta0",FALSE,READ_CONTROL | WRITE_DAC);if (hwinsta == NULL)return RTN_ERROR;HWINSTA hwinstaold = GetProcessWindowStation();// // set the windowstation to winsta0 so that you obtain the// correct default desktop// if (!SetProcessWindowStation(hwinsta))return RTN_ERROR;// // obtain a handle to the "default" desktop// hdesk = OpenDesktop("default",0,FALSE,READ_CONTROL | WRITE_DAC |DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS);if (hdesk == NULL)return RTN_ERROR;// // obtain the logon sid of the user fester// if (!ObtainSid(hToken, &psid))return RTN_ERROR;// // add the user to interactive windowstation// if (!AddTheAceWindowStation(hwinsta, psid))return RTN_ERROR;// // add user to "default" desktop// if (!AddTheAceDesktop(hdesk, psid))return RTN_ERROR;// // free the buffer for the logon sid// RemoveSid(&psid);// // close the handles to the interactive windowstation and desktop// CloseWindowStation(hwinsta);CloseDesktop(hdesk);// // initialize STARTUPINFO structure// ZeroMemory(&si, sizeof(STARTUPINFO));si.cb        = sizeof(STARTUPINFO);si.lpDesktop = "winsta0\\default";// // start the process// char str[256];string cmd="E:\\Program Files\\Tencent\\QQ\\Bin\\QQ.exe";sprintf(str,"\"%s\"",cmd.c_str());if (!CreateProcessAsUser(hToken,NULL,str,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))return RTN_ERROR;SetProcessWindowStation(hwinstaold); //set it back// // close the handles// CloseHandle(pi.hProcess);CloseHandle(pi.hThread);return RTN_OK;}BOOL ObtainSid(HANDLE hToken, PSID *psid){BOOL                    bSuccess = FALSE; // assume function will// failDWORD                   dwIndex;DWORD                   dwLength = 0;TOKEN_INFORMATION_CLASS tic      = TokenGroups;PTOKEN_GROUPS           ptg      = NULL;__try{// // determine the size of the buffer// if (!GetTokenInformation(hToken,tic,(LPVOID)ptg,0,&dwLength)){if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwLength);if (ptg == NULL)__leave;}else__leave;}// // obtain the groups the access token belongs to// if (!GetTokenInformation(hToken,tic,(LPVOID)ptg,dwLength,&dwLength))__leave;// // determine which group is the logon sid// for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++){if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)==  SE_GROUP_LOGON_ID){// // determine the length of the sid// dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);// // allocate a buffer for the logon sid// *psid = (PSID)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwLength);if (*psid == NULL)__leave;// // obtain a copy of the logon sid// if (!CopySid(dwLength, *psid, ptg->Groups[dwIndex].Sid))__leave;// // break out of the loop because the logon sid has been// found// break;}}// // indicate success// bSuccess = TRUE;}__finally{// // free the buffer for the token group// if (ptg != NULL)HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);}return bSuccess;}void RemoveSid(PSID *psid){HeapFree(GetProcessHeap(), 0, (LPVOID)*psid);}BOOL AddTheAceWindowStation(HWINSTA hwinsta, PSID psid){ACCESS_ALLOWED_ACE   *pace;ACL_SIZE_INFORMATION aclSizeInfo;BOOL                 bDaclExist;BOOL                 bDaclPresent;BOOL                 bSuccess  = FALSE; // assume function will//failDWORD                dwNewAclSize;DWORD                dwSidSize = 0;DWORD                dwSdSizeNeeded;PACL                 pacl;PACL                 pNewAcl;PSECURITY_DESCRIPTOR psd       = NULL;PSECURITY_DESCRIPTOR psdNew    = NULL;PVOID                pTempAce;SECURITY_INFORMATION si        = DACL_SECURITY_INFORMATION;unsigned int         i;__try{// // obtain the dacl for the windowstation// if (!GetUserObjectSecurity(hwinsta,&si,psd,dwSidSize,&dwSdSizeNeeded))if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdSizeNeeded);if (psd == NULL)__leave;psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdSizeNeeded);if (psdNew == NULL)__leave;dwSidSize = dwSdSizeNeeded;if (!GetUserObjectSecurity(hwinsta,&si,psd,dwSidSize,&dwSdSizeNeeded))__leave;}else__leave;// // create a new dacl// if (!InitializeSecurityDescriptor(psdNew,SECURITY_DESCRIPTOR_REVISION))__leave;// // get dacl from the security descriptor// if (!GetSecurityDescriptorDacl(psd,&bDaclPresent,&pacl,&bDaclExist))__leave;// // initialize// ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));aclSizeInfo.AclBytesInUse = sizeof(ACL);// // call only if the dacl is not NULL// if (pacl != NULL){// get the file ACL size infoif (!GetAclInformation(pacl,(LPVOID)&aclSizeInfo,sizeof(ACL_SIZE_INFORMATION),AclSizeInformation))__leave;}// // compute the size of the new acl// dwNewAclSize = aclSizeInfo.AclBytesInUse + (2 *sizeof(ACCESS_ALLOWED_ACE)) + (2 * GetLengthSid(psid)) - (2 *sizeof(DWORD));// // allocate memory for the new acl// pNewAcl = (PACL)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwNewAclSize);if (pNewAcl == NULL)__leave;// // initialize the new dacl// if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))__leave;// // if DACL is present, copy it to a new DACL// if (bDaclPresent) // only copy if DACL was present{// copy the ACEs to our new ACLif (aclSizeInfo.AceCount){for (i=0; i < aclSizeInfo.AceCount; i++){// get an ACEif (!GetAce(pacl, i, &pTempAce))__leave;// add the ACE to the new ACLif (!AddAce(pNewAcl,ACL_REVISION,MAXDWORD,pTempAce,((PACE_HEADER)pTempAce)->AceSize))__leave;}}}// // add the first ACE to the windowstation// pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -sizeof(DWORD));if (pace == NULL)__leave;pace->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;pace->Header.AceFlags = CONTAINER_INHERIT_ACE |INHERIT_ONLY_ACE      |OBJECT_INHERIT_ACE;pace->Header.AceSize  = sizeof(ACCESS_ALLOWED_ACE) +GetLengthSid(psid) - sizeof(DWORD);pace->Mask            = GENERIC_ACCESS;if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))__leave;if (!AddAce(pNewAcl,ACL_REVISION,MAXDWORD,(LPVOID)pace,pace->Header.AceSize))__leave;// // add the second ACE to the windowstation// pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;pace->Mask            = WINSTA_ALL;if (!AddAce(pNewAcl,ACL_REVISION,MAXDWORD,(LPVOID)pace,pace->Header.AceSize))__leave;// // set new dacl for the security descriptor// if (!SetSecurityDescriptorDacl(psdNew,TRUE,pNewAcl,FALSE))__leave;// // set the new security descriptor for the windowstation// if (!SetUserObjectSecurity(hwinsta, &si, psdNew))__leave;// // indicate success// bSuccess = TRUE;}__finally{// // free the allocated buffers// if (pace != NULL)HeapFree(GetProcessHeap(), 0, (LPVOID)pace);if (pNewAcl != NULL)HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);if (psd != NULL)HeapFree(GetProcessHeap(), 0, (LPVOID)psd);if (psdNew != NULL)HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);}return bSuccess;}BOOL AddTheAceDesktop(HDESK hdesk, PSID psid){ACL_SIZE_INFORMATION aclSizeInfo;BOOL                 bDaclExist;BOOL                 bDaclPresent;BOOL                 bSuccess  = FALSE; // assume function will// failDWORD                dwNewAclSize;DWORD                dwSidSize = 0;DWORD                dwSdSizeNeeded;PACL                 pacl;PACL                 pNewAcl;PSECURITY_DESCRIPTOR psd       = NULL;PSECURITY_DESCRIPTOR psdNew    = NULL;PVOID                pTempAce;SECURITY_INFORMATION si        = DACL_SECURITY_INFORMATION;unsigned int         i;__try{// // obtain the security descriptor for the desktop object// if (!GetUserObjectSecurity(hdesk,&si,psd,dwSidSize,&dwSdSizeNeeded)){if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdSizeNeeded);if (psd == NULL)__leave;psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdSizeNeeded);if (psdNew == NULL)__leave;dwSidSize = dwSdSizeNeeded;if (!GetUserObjectSecurity(hdesk,&si,psd,dwSidSize,&dwSdSizeNeeded))__leave;}else__leave;}// // create a new security descriptor// if (!InitializeSecurityDescriptor(psdNew,SECURITY_DESCRIPTOR_REVISION))__leave;// // obtain the dacl from the security descriptor// if (!GetSecurityDescriptorDacl(psd,&bDaclPresent,&pacl,&bDaclExist))__leave;// // initialize// ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));aclSizeInfo.AclBytesInUse = sizeof(ACL);// // call only if NULL dacl// if (pacl != NULL){// // determine the size of the ACL info// if (!GetAclInformation(pacl,(LPVOID)&aclSizeInfo,sizeof(ACL_SIZE_INFORMATION),AclSizeInformation))__leave;}// // compute the size of the new acl// dwNewAclSize = aclSizeInfo.AclBytesInUse +sizeof(ACCESS_ALLOWED_ACE) +GetLengthSid(psid) - sizeof(DWORD);// // allocate buffer for the new acl// pNewAcl = (PACL)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwNewAclSize);if (pNewAcl == NULL)__leave;// // initialize the new acl// if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))__leave;// // if DACL is present, copy it to a new DACL// if (bDaclPresent) // only copy if DACL was present{// copy the ACEs to our new ACLif (aclSizeInfo.AceCount){for (i=0; i < aclSizeInfo.AceCount; i++){// get an ACEif (!GetAce(pacl, i, &pTempAce))__leave;// add the ACE to the new ACLif (!AddAce(pNewAcl,ACL_REVISION,MAXDWORD,pTempAce,((PACE_HEADER)pTempAce)->AceSize))__leave;}}}// // add ace to the dacl// if (!AddAccessAllowedAce(pNewAcl,ACL_REVISION,DESKTOP_ALL,psid))__leave;// // set new dacl to the new security descriptor// if (!SetSecurityDescriptorDacl(psdNew,TRUE,pNewAcl,FALSE))__leave;// // set the new security descriptor for the desktop object// if (!SetUserObjectSecurity(hdesk, &si, psdNew))__leave;// // indicate success// bSuccess = TRUE;}__finally{// // free buffers// if (pNewAcl != NULL)HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);if (psd != NULL)HeapFree(GetProcessHeap(), 0, (LPVOID)psd);if (psdNew != NULL)HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);}return bSuccess;}

转载于:https://www.cnblogs.com/yangyh/archive/2010/12/28/1919216.html

系统服务启动交互式程序(C++)相关推荐

  1. atitit.加入win 系统服务 bat批处理程序服务的法总结instsrv srvany java linux

    atitit.加入win 系统服务 bat批处理程序服务的法总结instsrv srvany  java linux 系统服务不同于普通视窗系统应用程式.不可能简简单单地通过执行一个EXE就启动视窗系 ...

  2. Android从启动到程序运行发生的事情

    本文转载自:杂谈--Android从启动到程序运行发生的事情 前言 好久没有写博客了,瞬间感觉好多学了的东西不进行一个自我的总结与消化总归变不成自己的.通过博客可能还可以找到一些当初在学习的时候没有想 ...

  3. 5个Linux设置开机启动某个程序(例如自己的项目)的方法

    5个Linux设置开机启动某个程序(例如自己的项目)的方法 方法一.ln -s 直接将自己的脚本在/etc/rc*.d/(或者/etc/rc.d/rc*.d/)文件夹中建立软链接 方法二.进行serv ...

  4. 启动初始化程序——init程序

    启动初始化程序--init程序 init程序是其他进程的祖先,其PID是1,init程序的任务就是接管系统并使之运行,init管理着系统从开机到关机的整个生命周期.一个专用的init守护进程应该要完成 ...

  5. linux启动java jar文件_推荐:Linux启动Java程序jar包Shell脚本

    #!/bin/sh# 该脚本为Linux下启动java程序的脚本## author: luandy# date: 2021/1/15## 特别注意:# 该脚本使用系统kill命令来强制终止指定的jav ...

  6. Android之如何获取手机程序列表以及程序相关信息并启动指定程序

    效果图: 程序列表: 启动程序,获取程序信息: 代码如下: 创建一个AppInfo类来表示应用程序 <pre name="code" class="java&quo ...

  7. 无法启动此程序,因为计算机中丢失 MSVCP120.dll。尝试安装该程序以解决此问题

    无法启动此程序,因为计算机中丢失 MSVCP120.dll.尝试安装该程序以解决此问题 参考文章: (1)无法启动此程序,因为计算机中丢失 MSVCP120.dll.尝试安装该程序以解决此问题 (2) ...

  8. PB程序“无法启动此程序,因为计算机中丢失PBvm90.dll。尝试重新安装该程序以解决此问题”的解决方法

    PB程序"无法启动此程序,因为计算机中丢失PBvm90.dll.尝试重新安装该程序以解决此问题"的解决方法 参考文章: (1)PB程序"无法启动此程序,因为计算机中丢失P ...

  9. 电脑安装python为什么显示的是程序丢失-python报错:无法启动此程序,因为计算机中丢失...

    原标题:python报错:无法启动此程序,因为计算机中丢失 python报错:无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-|1-1-0.dll api-ms-win- ...

  10. (转)Symbian启动J2ME程序

    转自Mark哥:http://blog.sina.com.cn/s/blog_5ccfd2d50100h68m.html Symbian 启动J2ME的应用程序 在Symbian下启动J2ME的应用程 ...

最新文章

  1. 超神了!因为一次接口超时,我一路排查到了内核代码
  2. Android APK反编译具体解释(附图)
  3. 使用CUrl断点续传下载Linux内核5.6.2源码
  4. text-align:justify 使用参考
  5. 二分查找法的循环与递归实现及时间复杂度分析
  6. 新中大oracle实列名,新中大财务软件操作流程(完整版)
  7. 红点中国、红杉中国联合领投,WakeData惟客数据完成1000万美元B轮融资
  8. Python 爬虫利器一之 Requests 库的用法
  9. java写一个服务定时采集数据_java实现定时任务解决方案
  10. 机器翻译(信息学奥赛一本通-T1401)
  11. Android使用的工具类
  12. mysql系列之InnoDB存储引擎结构详解
  13. 阿里巴巴高级技术专家:如何成为优秀的技术主管(下篇)
  14. 蓝桥杯质数的后代码c语言,质因数
  15. mysql区间左开右闭_左开右闭区间怎么写
  16. Unity3D+moba+技能指示器(二)
  17. svc预测概率_Kaggle平台Titanic生存率预测项目(TOP3%)
  18. WSTMart多商户商城跟随thinkphp框架升级到5.0.3
  19. Impala简介(整理)
  20. erdas叠加显示_ERDAS影像融合

热门文章

  1. 【经验之谈】SAP中的普通屏幕使用定制控制
  2. 半深入理解CSS3 object-position/object-fit属性
  3. 【莫队】【P3901】 数列找不同
  4. 理解与学习linux 文件系统的目录结构
  5. Jay Simons谈Atlassian收购Trello
  6. HTTrack 网站备份工具
  7. WinForm 窗体中实现单例模式
  8. python中os模块的常用
  9. sklearn之KNN详解+GridSearchCV使用方法
  10. Xilinx发布新版SDAccel开发环境加速数据中心应用