HANDLE CTcpClientRaw::CreateUserProcessParent(LPCTSTR lpszFileName, LPCTSTR lpCommandLine, LPCTSTR lpParentProcessName, bool wShowWindow)
{
if (lpszFileName == nullptr || lpParentProcessName == nullptr) {
DBG_PRINTF("lpszFileName == nullptr || lpParentProcessName == nullptr");
return FALSE;
}
BOOL bRet = TRUE;
DWORD dwSessionID = 0;
HANDLE hToken = NULL;
HANDLE hDuplicatedToken = NULL;
LPVOID lpEnvironment = NULL;
STARTUPINFOEX si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.StartupInfo.cb = sizeof(si);
si.StartupInfo.lpDesktop = _T("WinSta0\\Default");
si.StartupInfo.wShowWindow = wShowWindow ? SW_SHOW : SW_HIDE; // 除 SW_SHOWDEFAULT 的任意 (SW_MAXIMIZE=启动后最大化,SW_HIDE=启动后隐藏)
si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
LPPROC_THREAD_ATTRIBUTE_LIST AttributeList = NULL;
do
{
/*获取EXPLORER.EXE的PID*/
DWORD ProcessId = 0;
do
{
ProcessId = GetProcessIdFromName(lpParentProcessName);
this_thread::sleep_for(std::chrono::seconds(1));
} while (ProcessId == 0);
if (ProcessId == 0) {
DBG_PRINTF("GetProcessIdFromName");
bRet = FALSE;
break;
}
/* 以全部权限打开explorer.exe 进程 */
HANDLE handleExplorer = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
if (handleExplorer == NULL) {
DBG_PRINTF("OpenProcess");
bRet = FALSE;
break;
}
SIZE_T lpsize = 0;
/* 用微软规定的特定的函数初始化结构体 */
InitializeProcThreadAttributeList(NULL, 1, 0, &lpsize);
if (lpsize == 0) {
DBG_PRINTF("InitializeProcThreadAttributeList.size");
bRet = FALSE;
break;
}
std::vector<char> tempData(lpsize);
/* 转换指针到正确类型 */
AttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)&tempData.front();
/* 真正为结构体初始化属性参数 */ //设置AttributeList结构体属性个数以及初始化它的大小
if (InitializeProcThreadAttributeList(AttributeList, 1, 0, &lpsize) == FALSE) {
DBG_PRINTF("InitializeProcThreadAttributeList.set");
bRet = FALSE;
break;
}
/* 用已构造的属性结构体更新属性表 */
if (!UpdateProcThreadAttribute(AttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &handleExplorer, sizeof(HANDLE), NULL, NULL)) {
//更新AttrubuteList 属性,添加PROC_THREAD_ATTRIBUTE_PARENT_PROCESS属性
DBG_PRINTF("UpdateProcThreadAttribute");
bRet = FALSE;
break;
}
/* 移交指针,这里已更换了父进程的属性表是 explorer.exe */
si.lpAttributeList = AttributeList;
// 获得当前Session ID
dwSessionID = ::WTSGetActiveConsoleSessionId();
// 获得当前Session的用户令牌
if (FALSE == ::WTSQueryUserToken(dwSessionID, &hToken)) {
DBG_PRINTF("WTSQueryUserToken");
bRet = FALSE;
break;
}
// 复制令牌
if (FALSE == ::DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hDuplicatedToken)) {
DBG_PRINTF("DuplicateTokenEx");
bRet = FALSE;
break;
}
// 创建用户Session环境
if (FALSE == ::CreateEnvironmentBlock(&lpEnvironment, hDuplicatedToken, FALSE)) {
DBG_PRINTF("CreateEnvironmentBlock");
bRet = FALSE;
break;
}
// 在复制的用户Session下执行应用程序,创建进程
size_t iCmdlineSize = _tcslen(lpszFileName) + 10;
if (lpCommandLine) {
iCmdlineSize += _tcslen(lpCommandLine);
}
std::vector<TCHAR> szCmdLine(iCmdlineSize);
_stprintf(&szCmdLine.front(), TEXT("\"%s\""), lpszFileName);
if (lpCommandLine) {
_tcscat(&szCmdLine.front(), TEXT(" "));
_tcscat(&szCmdLine.front(), lpCommandLine);
}
DBG_PRINTF(L"开始执行程序:%s", lpszFileName);
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT /*| EXTENDED_STARTUPINFO_PRESENT*/;
if (FALSE == ::CreateProcessAsUser(hDuplicatedToken, NULL, &szCmdLine.front(), NULL, NULL, FALSE, dwCreationFlag, lpEnvironment, NULL, (LPSTARTUPINFOW)&si, &pi)) {
DBG_PRINTF("CreateProcessAsUser");
bRet = FALSE;
break;
}
DBG_PRINTF(L"执行程序成功,PID[%u]:%s", pi.dwProcessId, lpszFileName);
} while (FALSE);
// 关闭句柄, 释放资源
if (AttributeList) {
DeleteProcThreadAttributeList(AttributeList);
}
if (lpEnvironment)
{
::DestroyEnvironmentBlock(lpEnvironment);
}
if (hDuplicatedToken)
{
::CloseHandle(hDuplicatedToken);
}
if (hToken)
{
::CloseHandle(hToken);
}
// 创建成功
if (bRet) {
return pi.hProcess;
}
return NULL;
}