[C++] 纯文本查看 复制代码
BOOL LaunchAppIntoDifferentSession(WCHAR *szExe,WCHAR *szDir)//以SYSTEM运行程序
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL bResult = FALSE;
DWORD dwSessionId, winlogonPid;
HANDLE hUserToken, hUserTokenDup, hPToken, hProcess;
DWORD dwCreationFlags;
dwSessionId = WTSGetActiveConsoleSessionId();
//////////////////////////////////////////
// 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 (_wcsicmp(procEntry.szExeFile, L"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 = (LPWSTR)L"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))
{
int abcd = GetLastError();
// printf("Process token open Error: %u\n", GetLastError());
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
// printf("Lookup Privilege value Error: %u\n", GetLastError());
}
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))
{
int abc = GetLastError();
// printf("Adjust Privilege value Error: %u\n", GetLastError());
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
// printf("Token does not have the provilege\n");
}
LPVOID pEnv = NULL;
if (CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE))
{
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
}
else
pEnv = NULL;
// Launch the process in the client's logon session.
bResult = CreateProcessAsUser(
hUserTokenDup, // client's access token
szExe, // 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
szDir, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
);
CloseHandle(hProcess);
CloseHandle(hUserToken);
CloseHandle(hUserTokenDup);
CloseHandle(hPToken);
return bResult;
}
BOOL bInstallService;
WHCAR szAppName[]=L"TopC";
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS status;
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
HANDLE hEvent = INVALID_HANDLE_VALUE;
//服务控制函数
void WINAPI ServiceStrl(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
status.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus(hServiceStatus, &status);
//告诉服务线程停止工作
::SetEvent(hEvent);
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
}
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
// Register the control request handler
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
//注册服务控制
hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
SetServiceStatus(hServiceStatus, &status);
//如下代码可以为启动服务前的准备工作
hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if (hEvent == NULL)
{
status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hServiceStatus, &status);
return;
}
//更改服务状态为启动
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hServiceStatus, &status);
//等待用户选择停止服务,
//当然你也可以把你的服务代码用线程来执行,
//此时这里只需等待线程结束既可。
///////////////////////////////////////////////////////////////////////以SYSTEM启动自己或别的程序
WCHAR szExe[MAX_PATH];
HINSTANCE hInst = GetModuleHandle(NULL);
GetModuleFileName(hInst, szExe, MAX_PATH);
int iLen = wcslen(szExe);
szExe[iLen] = L'\0';
LaunchAppIntoDifferentSession(szExe,NULL);
///////////////////////////////////////////////////////////////////////
while (WaitForSingleObject(hEvent, 1000) != WAIT_OBJECT_0)
{
//服务程序代码放这里
}
//停止服务
status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hServiceStatus, &status);
}
DWORD ServiceRunState()//查询当前服务状态
{
BOOL bResult = FALSE;
//打开服务控制管理器
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM != NULL)
{
//打开服务
SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_STATUS);
if (hService != NULL)
{
SERVICE_STATUS ss;
QueryServiceStatus(hService, &ss);
bResult = ss.dwCurrentState;
::CloseServiceHandle(hService);
}
::CloseServiceHandle(hSCM);
}
return bResult;
}
BOOL IsServiceInstalled()//查询服务是否安装
{
BOOL bResult = FALSE;
//打开服务控制管理器
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM != NULL)
{
//打开服务
SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);
if (hService != NULL)
{
bResult = TRUE;
::CloseServiceHandle(hService);
}
::CloseServiceHandle(hSCM);
}
return bResult;
}
BOOL InstallService()//安装服务
{
if (IsServiceInstalled())
return TRUE;
//打开服务控制管理器
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
return FALSE;
}
// Get the executable file path
TCHAR szFilePath[MAX_PATH];
::GetModuleFileName(NULL, szFilePath, MAX_PATH);
//创建服务
SC_HANDLE hService = ::CreateService(
hSCM,
szServiceName,
szServiceName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, //如果为SERVICE_DEMAND_START则表示此服务需手工启动
SERVICE_ERROR_NORMAL,
szFilePath,
NULL,
NULL,
_T(""),
NULL,
NULL);
if (hService == NULL)
{
::CloseServiceHandle(hSCM);
return FALSE;
}
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return TRUE;
}
BOOL UninstallService()//卸载服务
{
if (!IsServiceInstalled())
return TRUE;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
return FALSE;
}
SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
if (hService == NULL)
{
::CloseServiceHandle(hSCM);
return FALSE;
}
SERVICE_STATUS status;
::ControlService(hService, SERVICE_CONTROL_STOP, &status);
//删除服务
BOOL bDelete = ::DeleteService(hService);
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
if (bDelete)
return TRUE;
return FALSE;
}
void Init()//初始化参数
{
hServiceStatus = NULL;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
}
//开启服务
BOOL ServiceCtrlStart()
{
BOOL bRet;
SC_HANDLE hSCM;
SC_HANDLE hService;
hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (hSCM != NULL)
{
// hService = OpenService(hSCM, szServiceName, SERVICE_START);
hService = OpenService(hSCM, szServiceName, SERVICE_ALL_ACCESS);
if (hService != NULL)
{
ChangeServiceConfig(hService, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
//开始Service
bRet = StartService(hService, 0, NULL);
CloseServiceHandle(hService);
}
else
{
bRet = FALSE;
}
CloseServiceHandle(hSCM);
}
else
{
bRet = FALSE;
}
return bRet;
}
//停止服务
BOOL ServiceCtrlStop()
{
BOOL bRet;
SC_HANDLE hSCM;
SC_HANDLE hService;
SERVICE_STATUS ServiceStatus;
hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM != NULL)
{
hService = OpenService(hSCM, szServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS);
if (hService != NULL)
{
QueryServiceStatus(hService, &ServiceStatus);
if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
bRet = ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus);
}
else
{
bRet = FALSE;
}
CloseServiceHandle(hService);
}
else
{
bRet = FALSE;
}
CloseServiceHandle(hSCM);
}
else
{
bRet = FALSE;
}
return bRet;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
hInst = hInstance;
Init();
SERVICE_TABLE_ENTRY st[] =
{
{ szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{ NULL, NULL }
};
if (_wcsicmp(lpCmdLine, L"/install") == 0)//安装服务
{
InstallService();
return 0;
}
else if (_wcsicmp(lpCmdLine, L"/uninstall") == 0)//卸载服务
{
UninstallService();
return 0;
}
else if (_wcsicmp(lpCmdLine, L"/start") == 0)//开始启动服务
{
ServiceCtrlStart();
return 0;
}
else if (_wcsicmp(lpCmdLine, L"/stop") == 0)//停止服务
{
ServiceCtrlStop();
return 0;
}
if (ServiceRunState() != SERVICE_RUNNING)
{
if (IsServiceInstalled())
{
if (ServiceRunState() == SERVICE_STOPPED)
ServiceCtrlStart();
StartServiceCtrlDispatcher(st);
return 0;
}
}
ServiceCtrlStop();//程序已经以SYSTEM运行,退出服务
//下面是程序运行代码
}