|
@@ -4,6 +4,19 @@
|
|
|
#include <io.h>
|
|
|
#include <fcntl.h>
|
|
|
#include "Python.h"
|
|
|
+// 服务进程头文件;
|
|
|
+#include <Wtsapi32.h>
|
|
|
+#include <TlHelp32.h>
|
|
|
+#pragma comment(lib, "wtsapi32.lib")
|
|
|
+#include <Userenv.h>
|
|
|
+#pragma comment(lib,"userenv.lib")
|
|
|
+
|
|
|
+/*
|
|
|
+typedef struct _TOKEN_LINKED_TOKEN {
|
|
|
+ HANDLE LinkedToken;
|
|
|
+} TOKEN_LINKED_TOKEN, *PTOKEN_LINKED_TOKEN;
|
|
|
+SERVICE_STATUS_HANDLE hServiceStatus;
|
|
|
+*/
|
|
|
|
|
|
CScriptExecutor::CScriptExecutor(void)
|
|
|
{
|
|
@@ -54,7 +67,8 @@ DWORD CScriptExecutor::_WorkerThread(LPVOID lpParam)
|
|
|
}
|
|
|
else if (that->m_nRunType == SUBPROCESS)
|
|
|
{
|
|
|
- that->RunScripProcess();
|
|
|
+ //that->RunScriptProcess();
|
|
|
+ that->ServiceRunScriptProcess();
|
|
|
}
|
|
|
|
|
|
CloseHandle(that->m_hWorkThread);
|
|
@@ -385,7 +399,7 @@ int CScriptExecutor::RunEmbeddedScript()
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int CScriptExecutor::RunScripProcess()
|
|
|
+int CScriptExecutor::RunScriptProcess()
|
|
|
{
|
|
|
if (!PathFileExists(m_szScriptPath))
|
|
|
{
|
|
@@ -450,6 +464,168 @@ int CScriptExecutor::RunScripProcess()
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+int CScriptExecutor::ServiceRunScriptProcess()
|
|
|
+{
|
|
|
+ if (!PathFileExists(m_szScriptPath))
|
|
|
+ {
|
|
|
+ printf("Error:脚本路径无效\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ DWORD dwProcesses = 0;
|
|
|
+ BOOL bResult = FALSE;
|
|
|
+ DWORD dwRet = 0;
|
|
|
+ DWORD dwSid = GetActiveSessionID();
|
|
|
+
|
|
|
+ HANDLE hProcess = NULL, hPToken = NULL, hUserTokenDup = NULL;
|
|
|
+ if (!WTSQueryUserToken(dwSid, &hPToken))
|
|
|
+ {
|
|
|
+ PROCESSENTRY32 procEntry;
|
|
|
+ DWORD dwPid = 0;
|
|
|
+ HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
+ if (hSnap == INVALID_HANDLE_VALUE)
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ procEntry.dwSize = sizeof(PROCESSENTRY32);
|
|
|
+ if (Process32First(hSnap, &procEntry))
|
|
|
+ {
|
|
|
+ do
|
|
|
+ {
|
|
|
+ if (_tcsicmp(procEntry.szExeFile, _T("explorer.exe")) == 0)
|
|
|
+ {
|
|
|
+ DWORD exeSessionId = 0;
|
|
|
+ if (ProcessIdToSessionId(procEntry.th32ProcessID, &exeSessionId) && exeSessionId == dwSid)
|
|
|
+ {
|
|
|
+ dwPid = procEntry.th32ProcessID;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } while (Process32Next(hSnap, &procEntry));
|
|
|
+ }
|
|
|
+ CloseHandle(hSnap);
|
|
|
+
|
|
|
+ // explorer进程不存在
|
|
|
+ if (dwPid == 0)
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
|
|
|
+ if (hProcess == NULL)
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS_P,&hPToken))
|
|
|
+ {
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hPToken == NULL)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ TOKEN_LINKED_TOKEN admin;
|
|
|
+ bResult = GetTokenInformation(hPToken, (TOKEN_INFORMATION_CLASS)19, &admin, sizeof(TOKEN_LINKED_TOKEN), &dwRet);
|
|
|
+
|
|
|
+ if (!bResult) // vista 以前版本不支持TokenLinkedToken
|
|
|
+ {
|
|
|
+ TOKEN_PRIVILEGES tp;
|
|
|
+ LUID luid;
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ hUserTokenDup = admin.LinkedToken;
|
|
|
+ }
|
|
|
+
|
|
|
+ LPVOID pEnv =NULL;
|
|
|
+ DWORD dwCreationFlags = CREATE_PRESERVE_CODE_AUTHZ_LEVEL;
|
|
|
+
|
|
|
+ if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE))
|
|
|
+ {
|
|
|
+ dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pEnv = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ ZeroMemory( &m_si, sizeof(m_si) );
|
|
|
+ m_si.cb = sizeof(m_si);
|
|
|
+ m_si.dwFlags = STARTF_USESHOWWINDOW;
|
|
|
+ m_si.wShowWindow = SW_HIDE;
|
|
|
+ ZeroMemory( &m_pi, sizeof(m_pi) );
|
|
|
+
|
|
|
+ // 重定向输出;
|
|
|
+ RedirectSubprocessStdout(&m_si);
|
|
|
+ // 恢复日志线程;
|
|
|
+ ResumeThread(m_hLogThread);
|
|
|
+
|
|
|
+ // 强制stdion, stdout和stderr完全无缓冲:python -u
|
|
|
+ TCHAR szCommandLine[MAX_PATH] = { 0 };
|
|
|
+ if (_tcslen(m_szExtraSentence))
|
|
|
+ _stprintf_s(szCommandLine, _T("python -W ignore -u %s %s"), m_szScriptPath, m_szExtraSentence);
|
|
|
+ else
|
|
|
+ _stprintf_s(szCommandLine, _T("python -W ignore -u %s"), m_szScriptPath);
|
|
|
+
|
|
|
+ bResult = CreateProcessAsUser(
|
|
|
+ hUserTokenDup, // client's access token
|
|
|
+ NULL, // file to execute
|
|
|
+ szCommandLine, // command line
|
|
|
+ NULL, // pointer to process SECURITY_ATTRIBUTES
|
|
|
+ NULL, // pointer to thread SECURITY_ATTRIBUTES
|
|
|
+ TRUE, // handles are not inheritable
|
|
|
+ dwCreationFlags, // creation flags
|
|
|
+ pEnv, // pointer to new environment block
|
|
|
+ NULL, // name of current directory
|
|
|
+ &m_si, // pointer to STARTUPINFO structure
|
|
|
+ &m_pi // receives information about new process
|
|
|
+ );
|
|
|
+ if ( !bResult )
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ m_bRuned = TRUE;
|
|
|
+ m_dwSubprocessId = m_pi.dwProcessId;
|
|
|
+
|
|
|
+ // 等待进程完成退出.
|
|
|
+ WaitForSingleObject(m_pi.hProcess, INFINITE);
|
|
|
+
|
|
|
+ Sleep(5000);
|
|
|
+ // 结束日志线程;
|
|
|
+ m_bStopLogExport = TRUE;
|
|
|
+
|
|
|
+ // 关闭进程句柄.
|
|
|
+ CloseHandle(m_pi.hProcess);
|
|
|
+ CloseHandle(m_pi.hThread);
|
|
|
+
|
|
|
+ // 重置;
|
|
|
+ memset(&m_si, 0, sizeof(m_si));
|
|
|
+ memset(&m_pi, 0, sizeof(m_pi));
|
|
|
+ m_si.cb = sizeof(m_si);
|
|
|
+
|
|
|
+ if (hUserTokenDup != NULL)
|
|
|
+ CloseHandle(hUserTokenDup);
|
|
|
+ if (hProcess != NULL)
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ if (hPToken != NULL)
|
|
|
+ CloseHandle(hPToken);
|
|
|
+ if (pEnv != NULL)
|
|
|
+ DestroyEnvironmentBlock(pEnv);
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+}
|
|
|
+
|
|
|
bool CScriptExecutor::StartWorkThread()
|
|
|
{
|
|
|
// 创建线程;
|
|
@@ -620,13 +796,195 @@ void CScriptExecutor::EndSubprocessStdOut()
|
|
|
m_hStdOutRead = NULL;
|
|
|
}
|
|
|
|
|
|
-void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath, std::string strScriptCmd, int nRunType /*= PY_RUN_TYPE::EMBEDDED*/)
|
|
|
+DWORD CScriptExecutor::GetActiveSessionID()
|
|
|
+{
|
|
|
+ DWORD dwSessionId = 0;
|
|
|
+ PWTS_SESSION_INFO pSessionInfo = NULL;
|
|
|
+ DWORD dwCount = 0;
|
|
|
+
|
|
|
+ WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
|
|
|
+
|
|
|
+ for(DWORD i = 0; i < dwCount; i++)
|
|
|
+ {
|
|
|
+ WTS_SESSION_INFO si = pSessionInfo[i];
|
|
|
+ if(WTSActive == si.State)
|
|
|
+ {
|
|
|
+ dwSessionId = si.SessionId;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ WTSFreeMemory(pSessionInfo);
|
|
|
+
|
|
|
+ return dwSessionId;
|
|
|
+}
|
|
|
+
|
|
|
+BOOL CScriptExecutor::ServiceExecute(std::wstring wstrCmdLine, INT32& n32ExitResult)
|
|
|
+{
|
|
|
+ ofstream ofile("C:\\logEvent.txt");
|
|
|
+ ofile<<"start excute"<<std::endl;
|
|
|
+ DWORD dwProcesses = 0;
|
|
|
+ BOOL bResult = FALSE;
|
|
|
+
|
|
|
+ DWORD dwSid = GetActiveSessionID();
|
|
|
+
|
|
|
+ DWORD dwRet = 0;
|
|
|
+ PROCESS_INFORMATION pi;
|
|
|
+ STARTUPINFO si;
|
|
|
+ HANDLE hProcess = NULL, hPToken = NULL, hUserTokenDup = NULL;
|
|
|
+ if (!WTSQueryUserToken(dwSid, &hPToken))
|
|
|
+ {
|
|
|
+ ofile<<"get token error 1"<<std::endl;
|
|
|
+ PROCESSENTRY32 procEntry;
|
|
|
+ DWORD dwPid = 0;
|
|
|
+ HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
+ if (hSnap == INVALID_HANDLE_VALUE)
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ procEntry.dwSize = sizeof(PROCESSENTRY32);
|
|
|
+ if (Process32First(hSnap, &procEntry))
|
|
|
+ {
|
|
|
+ do
|
|
|
+ {
|
|
|
+ if (_tcsicmp(procEntry.szExeFile, _T("explorer.exe")) == 0)
|
|
|
+ {
|
|
|
+ DWORD exeSessionId = 0;
|
|
|
+ if (ProcessIdToSessionId(procEntry.th32ProcessID, &exeSessionId) && exeSessionId == dwSid)
|
|
|
+ {
|
|
|
+ dwPid = procEntry.th32ProcessID;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } while (Process32Next(hSnap, &procEntry));
|
|
|
+ }
|
|
|
+ CloseHandle(hSnap);
|
|
|
+
|
|
|
+ // explorer进程不存在
|
|
|
+ if (dwPid == 0)
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
|
|
|
+ if (hProcess == NULL)
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS_P,&hPToken))
|
|
|
+ {
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hPToken == NULL)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ TOKEN_LINKED_TOKEN admin;
|
|
|
+ bResult = GetTokenInformation(hPToken, (TOKEN_INFORMATION_CLASS)19, &admin, sizeof(TOKEN_LINKED_TOKEN), &dwRet);
|
|
|
+
|
|
|
+ if (!bResult) // vista 以前版本不支持TokenLinkedToken
|
|
|
+ {
|
|
|
+ ofile<<"Get token info error" <<std::endl;
|
|
|
+ TOKEN_PRIVILEGES tp;
|
|
|
+ LUID luid;
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ hUserTokenDup = admin.LinkedToken;
|
|
|
+ ofile<<"token: "<<hUserTokenDup<<std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ LPVOID pEnv =NULL;
|
|
|
+ DWORD dwCreationFlags = CREATE_PRESERVE_CODE_AUTHZ_LEVEL;
|
|
|
+
|
|
|
+ if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE))
|
|
|
+ {
|
|
|
+ dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pEnv = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ ZeroMemory( &si, sizeof(si) );
|
|
|
+ si.cb = sizeof(si);
|
|
|
+ si.dwFlags = STARTF_USESHOWWINDOW;
|
|
|
+ si.wShowWindow = SW_SHOWNORMAL;
|
|
|
+ ZeroMemory( &pi, sizeof(pi) );
|
|
|
+
|
|
|
+ bResult = CreateProcessAsUser(
|
|
|
+ hUserTokenDup, // client's access token
|
|
|
+ NULL, // file to execute
|
|
|
+ (LPTSTR) wstrCmdLine.c_str(), // 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
|
|
|
+ );
|
|
|
+
|
|
|
+ if(pi.hProcess)
|
|
|
+ {
|
|
|
+ if(WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, 180000))
|
|
|
+ {
|
|
|
+ DWORD dwResult = 0;
|
|
|
+ if(GetExitCodeProcess(pi.hProcess, &dwResult))
|
|
|
+ {
|
|
|
+ n32ExitResult = dwResult;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ n32ExitResult = -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle(pi.hThread);
|
|
|
+ CloseHandle(pi.hProcess);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ CloseHandle(pi.hThread);
|
|
|
+ CloseHandle(pi.hProcess);
|
|
|
+ n32ExitResult = -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (hUserTokenDup != NULL)
|
|
|
+ CloseHandle(hUserTokenDup);
|
|
|
+ if (hProcess != NULL)
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ if (hPToken != NULL)
|
|
|
+ CloseHandle(hPToken);
|
|
|
+ if (pEnv != NULL)
|
|
|
+ DestroyEnvironmentBlock(pEnv);
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+bool CScriptExecutor::InitScript(std::string strScript, std::string strLogPath, std::string strScriptCmd, int nRunType /*= PY_RUN_TYPE::EMBEDDED*/)
|
|
|
{
|
|
|
// 判断脚本是否存在;
|
|
|
if (!PathFileExists(strScript.c_str()))
|
|
|
{
|
|
|
printf("Error:脚本文件不存在\n");
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
// 判断日志文件路径是否可创建;
|
|
@@ -636,7 +994,7 @@ void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath,
|
|
|
if (!Global::MKDIR(strLogPath.c_str()))
|
|
|
{
|
|
|
printf("Error:创建目录失败\n");
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
// 创建文件;
|
|
@@ -644,7 +1002,7 @@ void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath,
|
|
|
if ( flog.bad() )
|
|
|
{
|
|
|
printf("Error:创建文件失败\n");
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
flog.close();
|
|
|
}
|
|
@@ -656,6 +1014,8 @@ void CScriptExecutor::InitScript(std::string strScript, std::string strLogPath,
|
|
|
_tcscpy_s(m_szScriptPath, strScript.c_str());
|
|
|
_tcscpy_s(m_szLogPath, strLogPath.c_str());
|
|
|
_tcscpy_s(m_szExtraSentence, strScriptCmd.c_str());
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
bool CScriptExecutor::StartScript()
|