#include "stdafx.h" #include "WinService.h" #include #include #pragma comment ( lib, "psapi.lib" ) #include #include #include namespace WinService { SCVariant g_scVariant; int InitWinSock() { WORD wVersionRequested; WSADATA wsaData; int nErrCode; wVersionRequested = MAKEWORD(2, 2); nErrCode = WSAStartup(wVersionRequested, &wsaData); if (0 != nErrCode) return -1; return 0; } /************************************************************************/ /* 函数:[7/20/2017 IT]; /* 描述:初始化服务名称和描述名称; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void InitServiceName(IN LPCTSTR lpServiceName, IN LPCTSTR lpServiceDescription) { if (lpServiceName == NULL || lpServiceName[0] == '\0') { TCHAR szModuleFileName[MAX_PATH] = { 0 }; TCHAR szExeName[MAX_PATH] = { 0 }; TCHAR szDrive[_MAX_DRIVE] = { 0 }; TCHAR szDir[_MAX_DIR] = { 0 }; TCHAR szFna[_MAX_DIR] = { 0 }; TCHAR szExt[_MAX_DIR] = { 0 }; ::GetModuleFileName(NULL, szModuleFileName, sizeof(szModuleFileName) / sizeof(TCHAR)); _tsplitpath_s(szModuleFileName, szDrive, szDir, szFna, szExt); // 用程序名来当服务名称; _stprintf_s(g_scVariant.scName, _T("%s"), szFna); } else { _stprintf_s(g_scVariant.scName, _T("%s"), lpServiceName); } if (lpServiceDescription == NULL || lpServiceDescription[0] == '\0') _stprintf_s(g_scVariant.scDescription, _T("%s"), g_scVariant.scName); else _stprintf_s(g_scVariant.scDescription, _T("%s"), lpServiceDescription); } /************************************************************************/ /* 函数:[7/20/2017 IT]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ BOOL IsInstalled() { BOOL bResult = FALSE; // 打开服务控制管理器; SC_HANDLE schSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (schSCM != NULL) {// 打开服务; SC_HANDLE schSvc = ::OpenService(schSCM, g_scVariant.scName, SERVICE_QUERY_CONFIG); if (schSvc != NULL) { bResult = TRUE; ::CloseServiceHandle(schSvc); } ::CloseServiceHandle(schSCM); } return bResult; } /************************************************************************/ /* 函数:[7/20/2017 IT]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ BOOL Install() { // 获取服务程序的绝对路径; TCHAR szFilePath[MAX_PATH]; if (0 == ::GetModuleFileName(NULL, szFilePath, MAX_PATH)) { _tprintf_s(_T("Cannot Install Service (%d)\n"), GetLastError()); return FALSE; } // 打开服务控制管理器,获取SCM数据库句柄; SC_HANDLE schSCM = ::OpenSCManager( NULL, // 本地计算机; NULL, // ServicesActive database; SC_MANAGER_ALL_ACCESS // 所有权限; ); if (schSCM == NULL) { _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError()); return FALSE; } // 创建服务; SC_HANDLE schSvc = ::CreateService( schSCM, // SCM数据库; g_scVariant.scName, // 服务名称; g_scVariant.scDescription, // 服务描述; SERVICE_ALL_ACCESS, // 需要的访问权限; SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // 服务类型; SERVICE_AUTO_START, //SERVICE_DEMAND_START, // 启动类型; SERVICE_ERROR_NORMAL, // 错误控制类型; szFilePath, // 服务程序路径; NULL, // 无加载顺序组; NULL, // 无标签标识; _T(""), // 无依赖; NULL, // 本地系统账号; NULL // 无密码(no password); ); if (schSvc == NULL) { _tprintf_s(_T("CreateService failed (%d)\n"), GetLastError()); CloseServiceHandle(schSvc); return FALSE; } // 设置服务的描述; SERVICE_DESCRIPTION ServiceDesc; ServiceDesc.lpDescription = g_scVariant.scDescription; ::ChangeServiceConfig2(schSvc, SERVICE_CONFIG_DESCRIPTION, &ServiceDesc); // 释放资源; ::CloseServiceHandle(schSvc); ::CloseServiceHandle(schSCM); return TRUE; } /************************************************************************/ /* 函数:[7/20/2017 IT]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ BOOL Uninstall() { if (!IsInstalled()) return TRUE; SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hSCM == NULL) return FALSE; SC_HANDLE hService = ::OpenService(hSCM, g_scVariant.scName, SERVICE_STOP | DELETE); if (hService == NULL) { ::CloseServiceHandle(hSCM); return FALSE; } SERVICE_STATUS scStatus; ::ControlService(hService, SERVICE_CONTROL_STOP, &scStatus); // 删除服务; BOOL bDelete = ::DeleteService(hService); ::CloseServiceHandle(hService); ::CloseServiceHandle(hSCM); if (bDelete) { //LOG4C((LOG_NOTICE,"服务成功卸载")); return TRUE; } //LOG4C((LOG_NOTICE,"服务卸载失败")); LogEvent(_T("Service could not be deleted")); return FALSE; } /************************************************************************/ /* 函数:ServiceMain[4/23/2016 home]; /* 描述:服务入口函数; /* 参数:; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void WINAPI ServiceMain() { // 注册服务的控制函数; g_scVariant.scStatusHandle = RegisterServiceCtrlHandler(g_scVariant.scName, SvcCtrlHandler); if (g_scVariant.scStatusHandle == NULL) { SvcReportEvent(_T("Handler not installed")); return; } // 在这里设置服务状态; g_scVariant.scStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; g_scVariant.scStatus.dwServiceSpecificExitCode = 0; // 注册成功后向SCM报告服务状态信息,因为服务还没初始化完成; // 所以当前服务状态为SERVICE_START_PENDING ; ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, 3000); // 处理第一个事件大约需要3秒钟; ////////////////////////////////////////////////////////////////////////// // 开始初始化服务; g_scVariant.hscEvent = ::CreateEvent(NULL, TRUE, FALSE, _T("CtrlService::g_hCtrlSvc")); if (g_scVariant.hscEvent == NULL) { // 向SCM报告服务已停止; ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 0); return; } // 向SCM报告服务正在运行; ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0); // 开启工作者; if (g_scVariant.lpStartWorkCallBack) g_scVariant.lpStartWorkCallBack(); // 线程中的处理函数运行结束后返回ServiceMain(), // ServiceMain()调用WaitForSingleObject, // 因为服务被停止之前ServiceMain()不会结束 WaitForSingleObject(g_scVariant.hscEvent, INFINITE); // INFINITE表示无限等待,等待SCM的信号; CloseHandle(g_scVariant.hscEvent); // 结束工作者; if (g_scVariant.lpEndofWorkCallBack) g_scVariant.lpEndofWorkCallBack(); SvcReportEvent(_T("Service stopped")); // 向SCM报告服务已停止工作; ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0, 0, 0); } /************************************************************************/ /* 函数:SvcCtrlHandler[4/23/2016 home]; /* 描述:每当有控制码发送给服务时被SCM调用; /* 参数:; /* [IN] dwControlCode:发送给服务的控制码; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void WINAPI SvcCtrlHandler(IN DWORD dwControlCode) { BOOL bsucc = FALSE; switch (dwControlCode) { case SERVICE_CONTROL_SHUTDOWN: // 关掉服务; case SERVICE_CONTROL_STOP: // 停止服务; bsucc = ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 1, 0); if (bsucc) { if (g_scVariant.lpEndofWorkCallBack) g_scVariant.lpEndofWorkCallBack(); KillService(); } break; case SERVICE_CONTROL_PAUSE: // 暂停服务; break; case SERVICE_CONTROL_CONTINUE: // 恢复被暂停的服务; break; case SERVICE_CONTROL_INTERROGATE: break; default: SvcReportEvent(_T("Bad service request")); } } /************************************************************************/ /* 函数:ReportSvcStatus[4/22/2016 home]; /* 描述:设置当前服务状态,并将其报告给SCM; /* 参数:; /* [IN] dwCurrentState:服务当前状态(详情见 SERVICE_STATUS); /* [IN] dwWin32ExitCode:系统返回服务的错误码; /* [IN] dwServiceSpecificExitCode:用户自定义的服务错误码; /* [OUT] dwCheckPoint:; /* [IN/OUT] dwWaitHint:挂起操作的估计用时; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ BOOL ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint) { BOOL bSuccess; // 填充SERVICE_STATUS结构体,以便用于设置服务状态; g_scVariant.scStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; // 表示我们的服务是独占一个进程的服务 ; g_scVariant.scStatus.dwCurrentState = dwCurrentState; // 当前服务状态; g_scVariant.scStatus.dwWaitHint = dwWaitHint; if (dwCurrentState == SERVICE_START_PENDING) { g_scVariant.scStatus.dwControlsAccepted = 0; // 不接受任何控制通知; } else { // 通知 SCM 服务接受哪个控制通知:这里允许停止、关机、暂停继续; g_scVariant.scStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; //|SERVICE_ACCEPT_PAUSE_CONTINUE; } if ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED)) g_scVariant.scStatus.dwCheckPoint = 0; else g_scVariant.scStatus.dwCheckPoint = dwCheckPoint++; // dwServiceSpecificExitCode在你终止服务并报告退出细节时很有用。 // 初始化服务时并不退出,因此值为 0; if (dwServiceSpecificExitCode == 0) { g_scVariant.scStatus.dwWin32ExitCode = dwWin32ExitCode; } else { g_scVariant.scStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; //用户自定义错误代码; } g_scVariant.scStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode; //设置好nServiceStatus后,向SCM报告服务状态,非0表示成功,0表示失败; bSuccess = SetServiceStatus(g_scVariant.scStatusHandle, &g_scVariant.scStatus); if (!bSuccess) { SvcReportEvent(_T("Set Service Status failed (%d) "), GetLastError()); KillService(); return FALSE; } else return TRUE; } // 结束服务; void KillService() { if (g_scVariant.hscEvent) SetEvent(g_scVariant.hscEvent); //如果操作成功,则返回非零值,否则为0。设置事件的状态为有标记,释放任意等待线程。如果事件是手工的,此事件将保持有标记直到调用ResetEvent。这种情况下将释放多个线程,如果事件是自动的,此事件将保持有标记,直到一个线程被释放,系统将设置事件的状态为无标记。如果没有线程在等待,则此事件将保持有标记,直到一个线程被释放。 //ReportStatusToSCMgr(SERVICE_STOPPED,NO_ERROR,0,0,0); } /************************************************************************/ /* 函数:[4/23/2016 home]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void SvcReportEvent(IN LPCTSTR pFormat, ...) { TCHAR szReport[MAX_PATH] = { 0 }; HANDLE hEventSource; LPCTSTR lpszStrings[2]; va_list pArg = NULL; va_start(pArg, pFormat); StringCchVPrintf(szReport, MAX_PATH, pFormat, pArg); va_end(pArg); hEventSource = RegisterEventSource(NULL, g_scVariant.scName); if (hEventSource != NULL) { lpszStrings[0] = g_scVariant.scName; lpszStrings[1] = szReport; ReportEvent( hEventSource, // 事件日志句柄; EVENTLOG_INFORMATION_TYPE, // 事件类型; 0, // 事件类别; 0/*SVC_ERROR*/, // 事件标识; NULL, // 无安全标识; 2, // lpszStrings数组大小; 0, // 无二进制数据; lpszStrings, // 字符串数组; NULL // 无二进制数据; ); DeregisterEventSource(hEventSource); } } /************************************************************************/ /* 函数:StartSvc[4/23/2016 home]; /* 描述:启动服务; /* 参数:; /* [IN] lpSvcName:要打开的服务名称; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void StartSvc(IN LPCTSTR lpSvcName) { TCHAR szSvcName[MAX_PATH] = { 0 }; if (lpSvcName == NULL || lpSvcName[0] == _T('\0')) _stprintf_s(szSvcName, _T("%s"), g_scVariant.scName); else _stprintf_s(szSvcName, _T("%s"), lpSvcName); SC_HANDLE schSCM; SC_HANDLE schService; SERVICE_STATUS_PROCESS ssStatus; DWORD dwOldCheckPoint; DWORD dwStartTickCount; DWORD dwWaitTime; DWORD dwBytesNeeded; // 打开服务管理器; schSCM = OpenSCManager( NULL, // NULL表示要地计算机; NULL, // NULl表示服务活动数据库; SC_MANAGER_ALL_ACCESS); // 全部管理权限; if (NULL == schSCM) { _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError()); return; } // 获取服务句柄; schService = OpenService( schSCM, // SCM数据库; szSvcName, // 服务名称; SERVICE_ALL_ACCESS); // 全部权限; if (schService == NULL) { _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError()); CloseServiceHandle(schSCM); return; } // 启动服务前,检查服务状态以防服务不是停止的状态; if (!QueryServiceStatusEx( schService, // 服务句柄; SC_STATUS_PROCESS_INFO, // 要查询的服务状态类型; (LPBYTE)&ssStatus, // 服务状态对象地址; sizeof(SERVICE_STATUS_PROCESS), // 结构体大小; &dwBytesNeeded)) // size needed if buffer is too small { _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCM); return; } // Check if the service is already running. It would be possible // to stop the service here, but for simplicity this example just returns. // 如果服务已经在运行,检查;可以在这里停止服务,简单起见,这里只返回; if (ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING) { _tprintf_s(_T("Cannot start the service because it is already running\n")); CloseServiceHandle(schService); CloseServiceHandle(schSCM); return; } // Save the tick count and initial checkpoint. // 保持计数值并初始化检查点; dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; // Wait for the service to stop before attempting to start it. // 在尝试启动服务前,等待服务停止; while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) { // Do not wait longer than the wait hint. A good interval is // one-tenth of the wait hint but not less than 1 second // and not more than 10 seconds. dwWaitTime = ssStatus.dwWaitHint / 10; if (dwWaitTime < 1000) dwWaitTime = 1000; else if (dwWaitTime > 10000) dwWaitTime = 10000; Sleep(dwWaitTime); // Check the status until the service is no longer stop pending. // 检测状态直到服务不再停止等待; if (!QueryServiceStatusEx( schService, // handle to service SC_STATUS_PROCESS_INFO, // information level (LPBYTE)&ssStatus, // address of structure sizeof(SERVICE_STATUS_PROCESS), // size of structure &dwBytesNeeded)) // size needed if buffer is too small { _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCM); return; } if (ssStatus.dwCheckPoint > dwOldCheckPoint) { // Continue to wait and check. // 继续等待并检测; dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; } else { if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint) { _tprintf_s(_T("Timeout waiting for service to stop\n")); CloseServiceHandle(schService); CloseServiceHandle(schSCM); return; } } } // Attempt to start the service. // 尝试启动服务; if (!StartService( schService, // handle to service 0, // number of arguments NULL)) // no arguments { _tprintf_s(_T("StartService failed (%d)\n"), GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCM); return; } else printf("Service start pending...\n"); // Check the status until the service is no longer start pending. // 检测服务状态直到服务不再启动挂起操作; if (!QueryServiceStatusEx( schService, // handle to service SC_STATUS_PROCESS_INFO, // info level (LPBYTE)&ssStatus, // address of structure sizeof(SERVICE_STATUS_PROCESS), // size of structure &dwBytesNeeded)) // if buffer too small { _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCM); return; } // Save the tick count and initial checkpoint. dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; while (ssStatus.dwCurrentState == SERVICE_START_PENDING) { // Do not wait longer than the wait hint. A good interval is // one-tenth the wait hint, but no less than 1 second and no // more than 10 seconds. dwWaitTime = ssStatus.dwWaitHint / 10; if (dwWaitTime < 1000) dwWaitTime = 1000; else if (dwWaitTime > 10000) dwWaitTime = 10000; Sleep(dwWaitTime); // Check the status again. if (!QueryServiceStatusEx( schService, // handle to service SC_STATUS_PROCESS_INFO, // info level (LPBYTE)&ssStatus, // address of structure sizeof(SERVICE_STATUS_PROCESS), // size of structure &dwBytesNeeded)) // if buffer too small { _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError()); break; } if (ssStatus.dwCheckPoint > dwOldCheckPoint) { // Continue to wait and check. dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; } else { if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint) { // No progress made within the wait hint. break; } } } // Determine whether the service is running. if (ssStatus.dwCurrentState == SERVICE_RUNNING) { _tprintf_s(_T("Service started successfully.\n")); } else { _tprintf_s(_T("Service not started. \n")); _tprintf_s(_T(" Current State: %d\n"), ssStatus.dwCurrentState); _tprintf_s(_T(" Exit Code: %d\n"), ssStatus.dwWin32ExitCode); _tprintf_s(_T(" Check Point: %d\n"), ssStatus.dwCheckPoint); _tprintf_s(_T(" Wait Hint: %d\n"), ssStatus.dwWaitHint); } CloseServiceHandle(schService); CloseServiceHandle(schSCM); } /************************************************************************/ /* 函数:UpdateSvcDacl[4/23/2016 home]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void UpdateSvcDacl(IN LPCTSTR lpSvcName) { if (lpSvcName == NULL || lpSvcName[0] == _T('\0')) return; EXPLICIT_ACCESS ea; SECURITY_DESCRIPTOR sd; PSECURITY_DESCRIPTOR psd = NULL; PACL pacl = NULL; PACL pNewAcl = NULL; BOOL bDaclPresent = FALSE; BOOL bDaclDefaulted = FALSE; DWORD dwError = 0; DWORD dwSize = 0; DWORD dwBytesNeeded = 0; SC_HANDLE schSCManager; SC_HANDLE schService; // 获取SCM数据库的句柄值; schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError()); return; } // Get a handle to the service schService = OpenService( schSCManager, // SCManager database lpSvcName, // name of service READ_CONTROL | WRITE_DAC); // access if (schService == NULL) { _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError()); CloseServiceHandle(schSCManager); return; } // Get the current security descriptor. // 获取当前服务的安全描述符; if (!QueryServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, &psd, // using NULL does not work on all versions 0, &dwBytesNeeded)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { dwSize = dwBytesNeeded; psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); if (psd == NULL) { // Note: HeapAlloc does not support GetLastError. _tprintf_s(_T("HeapAlloc failed\n")); goto dacl_cleanup; } if (!QueryServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded)) { _tprintf_s(_T("QueryServiceObjectSecurity failed (%d)\n"), GetLastError()); goto dacl_cleanup; } } else { _tprintf_s(_T("QueryServiceObjectSecurity failed (%d)\n"), GetLastError()); goto dacl_cleanup; } } // Get the DACL. if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted)) { _tprintf_s(_T("GetSecurityDescriptorDacl failed(%d)\n"), GetLastError()); goto dacl_cleanup; } // Build the ACE. BuildExplicitAccessWithName(&ea, TEXT("GUEST"), SERVICE_START | SERVICE_STOP | READ_CONTROL | DELETE, SET_ACCESS, NO_INHERITANCE); dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl); if (dwError != ERROR_SUCCESS) { printf("SetEntriesInAcl failed(%d)\n", dwError); goto dacl_cleanup; } // Initialize a new security descriptor. if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { printf("InitializeSecurityDescriptor failed(%d)\n", GetLastError()); goto dacl_cleanup; } // Set the new DACL in the security descriptor. if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)) { printf("SetSecurityDescriptorDacl failed(%d)\n", GetLastError()); goto dacl_cleanup; } // Set the new DACL for the service object. if (!SetServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, &sd)) { printf("SetServiceObjectSecurity failed(%d)\n", GetLastError()); goto dacl_cleanup; } else printf("Service DACL updated successfully\n"); dacl_cleanup: CloseServiceHandle(schSCManager); CloseServiceHandle(schService); if (NULL != pNewAcl) LocalFree((HLOCAL)pNewAcl); if (NULL != psd) HeapFree(GetProcessHeap(), 0, (LPVOID)psd); } void StopSvc(IN LPCTSTR lpSvcName) { TCHAR szSvcName[MAX_PATH] = { 0 }; if (lpSvcName == NULL || lpSvcName[0] == _T('\0')) _stprintf_s(szSvcName, _T("%s"), g_scVariant.scName); else _stprintf_s(szSvcName, _T("%s"), lpSvcName); SERVICE_STATUS_PROCESS ssp; DWORD dwStartTime = GetTickCount(); DWORD dwBytesNeeded; DWORD dwTimeout = 30000; // 30-second time-out DWORD dwWaitTime; SC_HANDLE schSCManager; SC_HANDLE schService; // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("OpenSCManager failed (%d)\n", GetLastError()); return; } // Get a handle to the service. schService = OpenService( schSCManager, // SCM database szSvcName, // name of service SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS); if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } // Make sure the service is not already stopped. if (!QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); goto stop_cleanup; } if (ssp.dwCurrentState == SERVICE_STOPPED) { printf("Service is already stopped.\n"); goto stop_cleanup; } // If a stop is pending, wait for it. while (ssp.dwCurrentState == SERVICE_STOP_PENDING) { printf("Service stop pending...\n"); // Do not wait longer than the wait hint. A good interval is // one-tenth of the wait hint but not less than 1 second // and not more than 10 seconds. dwWaitTime = ssp.dwWaitHint / 10; if (dwWaitTime < 1000) dwWaitTime = 1000; else if (dwWaitTime > 10000) dwWaitTime = 10000; Sleep(dwWaitTime); if (!QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); goto stop_cleanup; } if (ssp.dwCurrentState == SERVICE_STOPPED) { printf("Service stopped successfully.\n"); goto stop_cleanup; } if (GetTickCount() - dwStartTime > dwTimeout) { printf("Service stop timed out.\n"); goto stop_cleanup; } } // If the service is running, dependencies must be stopped first. StopDependentServices(); // Send a stop code to the service. if (!ControlService( schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp)) { printf("ControlService failed (%d)\n", GetLastError()); goto stop_cleanup; } // Wait for the service to stop. while (ssp.dwCurrentState != SERVICE_STOPPED) { Sleep(ssp.dwWaitHint); if (!QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); goto stop_cleanup; } if (ssp.dwCurrentState == SERVICE_STOPPED) break; if (GetTickCount() - dwStartTime > dwTimeout) { printf("Wait timed out\n"); goto stop_cleanup; } } printf("Service stopped successfully\n"); stop_cleanup: CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } BOOL StopDependentServices() { DWORD i; DWORD dwBytesNeeded; DWORD dwCount; LPENUM_SERVICE_STATUS lpDependencies = NULL; ENUM_SERVICE_STATUS ess; SC_HANDLE hDepService; SERVICE_STATUS_PROCESS ssp; DWORD dwStartTime = GetTickCount(); DWORD dwTimeout = 30000; // 30-second time-out SC_HANDLE schSCManager = NULL; SC_HANDLE schService = NULL; // Pass a zero-length buffer to get the required buffer size. if (EnumDependentServices(schService, SERVICE_ACTIVE, lpDependencies, 0, &dwBytesNeeded, &dwCount)) { // If the Enum call succeeds, then there are no dependent // services, so do nothing. return TRUE; } else { if (GetLastError() != ERROR_MORE_DATA) return FALSE; // Unexpected error // Allocate a buffer for the dependencies. lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded); if (!lpDependencies) return FALSE; __try { // Enumerate the dependencies. if (!EnumDependentServices(schService, SERVICE_ACTIVE, lpDependencies, dwBytesNeeded, &dwBytesNeeded, &dwCount)) return FALSE; for (i = 0; i < dwCount; i++) { ess = *(lpDependencies + i); // Open the service. hDepService = OpenService(schSCManager, ess.lpServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS); if (!hDepService) return FALSE; __try { // Send a stop code. if (!ControlService(hDepService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp)) return FALSE; // Wait for the service to stop. while (ssp.dwCurrentState != SERVICE_STOPPED) { Sleep(ssp.dwWaitHint); if (!QueryServiceStatusEx( hDepService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) return FALSE; if (ssp.dwCurrentState == SERVICE_STOPPED) break; if (GetTickCount() - dwStartTime > dwTimeout) return FALSE; } } __finally { // Always release the service handle. CloseServiceHandle(hDepService); } } } __finally { // Always free the enumeration buffer. HeapFree(GetProcessHeap(), 0, lpDependencies); } } return TRUE; } /************************************************************************/ /* 函数:[4/23/2016 home]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void DoQuerySvc(IN LPCTSTR lpSvcName) { if (lpSvcName == NULL || lpSvcName[0] == _T('\0')) { _tprintf_s(_T("要查询的服务名称无效\n")); return; } SC_HANDLE hSCM; SC_HANDLE hSvc; LPQUERY_SERVICE_CONFIG lpsc; LPSERVICE_DESCRIPTION lpsd; DWORD dwBytesNeeded, cbBfuSize, dwError; // 获取SCM句柄; hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hSCM == NULL) { _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError()); return; } // 获取服务句柄; hSvc = OpenService( hSCM, lpSvcName, SERVICE_QUERY_CONFIG // 需要查询设置的权限; ); if (hSvc == NULL) { _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError()); CloseServiceHandle(hSCM); return; } // 获取服务设置信息; if (!QueryServiceConfig(hSvc, NULL, 0, &dwBytesNeeded)) { dwError = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == dwError) { cbBfuSize = dwBytesNeeded; lpsc = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, cbBfuSize); } else { _tprintf_s(_T("QueryServiceConfig failed (%d)\n"), dwError); goto cleanup; } } if (!QueryServiceConfig(hSvc, lpsc, cbBfuSize, &dwBytesNeeded)) { _tprintf_s(_T("QuerySericeConfig failed (%d)\n"), GetLastError()); goto cleanup; } if (!QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded)) { dwError = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == dwError) { cbBfuSize = dwBytesNeeded; lpsd = (LPSERVICE_DESCRIPTION)LocalAlloc(LMEM_FIXED, cbBfuSize); } else { _tprintf_s(_T("QuerySericeConfig2 failed (%d)\n"), GetLastError()); goto cleanup; } } if (!QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)lpsd, cbBfuSize, &dwBytesNeeded)) { _tprintf_s(_T("QuerySericeConfig2 failed (%d)\n"), GetLastError()); goto cleanup; } ////////////////////////////////////////////////////////////////////////// // 查询成功,组织要返回的东西; _tprintf(TEXT("%s configuration: \n"), g_scVariant.scName); _tprintf(TEXT(" Type: 0x%x\n"), lpsc->dwServiceType); _tprintf(TEXT(" Start Type: 0x%x\n"), lpsc->dwStartType); _tprintf(TEXT(" Error Control: 0x%x\n"), lpsc->dwErrorControl); _tprintf(TEXT(" Binary path: %s\n"), lpsc->lpBinaryPathName); _tprintf(TEXT(" Account: %s\n"), lpsc->lpServiceStartName); if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0) _tprintf(TEXT(" Description: %s\n"), lpsd->lpDescription); if (lpsc->lpLoadOrderGroup != NULL && lstrcmp(lpsc->lpLoadOrderGroup, TEXT("")) != 0) _tprintf(TEXT(" Load order group: %s\n"), lpsc->lpLoadOrderGroup); if (lpsc->dwTagId != 0) _tprintf(TEXT(" Tag ID: %d\n"), lpsc->dwTagId); if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0) _tprintf(TEXT(" Dependencies: %s\n"), lpsc->lpDependencies); // 释放资源; LocalFree(lpsc); LocalFree(lpsd); cleanup: CloseServiceHandle(hSvc); CloseServiceHandle(hSCM); } /************************************************************************/ /* 函数:[4/23/2016 home]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void DoDisableSvc(IN LPCTSTR lpSvcName) { if (lpSvcName == NULL || lpSvcName[0] == _T('\0')) { _tprintf_s(_T("要禁用的服务名称无效\n")); return; } SC_HANDLE schSCM; SC_HANDLE schSvc; // 打开SCM; schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (schSCM == NULL) { _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError()); return; } // 获取服务句柄; schSvc = OpenService(schSCM, lpSvcName, SERVICE_CHANGE_CONFIG); if (schSvc == NULL) { _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError()); CloseServiceHandle(schSCM); return; } if (!ChangeServiceConfig( schSvc, SERVICE_NO_CHANGE, // service type: no change SERVICE_DISABLED, // service start type SERVICE_NO_CHANGE, // error control: no change NULL, // binary path: no change NULL, // load order group: no change NULL, // tag ID: no change NULL, // dependencies: no change NULL, // account name: no change NULL, // password: no change NULL)) // display name: no change { _tprintf_s(_T("ChangeServiceConfig failed (%d)\n"), GetLastError()); } CloseServiceHandle(schSvc); CloseServiceHandle(schSCM); } /************************************************************************/ /* 函数:[4/23/2016 home]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void DoEnableSvc(IN LPCTSTR lpSvcName) { if (lpSvcName == NULL || lpSvcName[0] == _T('\0')) { _tprintf_s(_T("要启用的服务名称无效\n")); return; } SC_HANDLE schSCM; SC_HANDLE schSvc; // Get a handle to the SCM database. // 获取SCM数据库句柄; schSCM = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCM) { printf("OpenSCManager failed (%d)\n", GetLastError()); return; } // Get a handle to the service. // 获取服务句柄值; schSvc = OpenService( schSCM, // SCM database lpSvcName, // name of service SERVICE_CHANGE_CONFIG); // need change config access if (schSvc == NULL) { _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError()); CloseServiceHandle(schSCM); return; } // Change the service start type. // 改变服务启动类型; if (!ChangeServiceConfig( schSvc, // 服务句柄; SERVICE_NO_CHANGE, // service type: no change SERVICE_DEMAND_START, // service start type SERVICE_NO_CHANGE, // error control: no change NULL, // binary path: no change NULL, // load order group: no change NULL, // tag ID: no change NULL, // dependencies: no change NULL, // account name: no change NULL, // password: no change NULL)) // display name: no change { _tprintf_s(_T("ChangeServiceConfig failed (%d)\n"), GetLastError()); } else { _tprintf_s(_T("Service enabled successfully.\n")); } CloseServiceHandle(schSvc); CloseServiceHandle(schSCM); } /************************************************************************/ /* 函数:[4/23/2016 home]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void DoUpdateSvcDesc(IN LPCTSTR lpSvcName) { if (lpSvcName == NULL || lpSvcName[0] == _T('\0')) { _tprintf_s(_T("要更新描述的服务名称无效\n")); return; } SC_HANDLE schSCM; SC_HANDLE schSvc; SERVICE_DESCRIPTION sd; LPTSTR szDesc = TEXT("This is a test description"); // Get a handle to the SCM database. // 获取SCM数据库句柄; schSCM = OpenSCManager( NULL, // NULL表示本地计算机; NULL, // NULL表示:ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCM) { _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError()); return; } // Get a handle to the service. // 获取服务句柄值; schSvc = OpenService( schSCM, // SCM 数据库句柄; lpSvcName, // 服务名称; SERVICE_CHANGE_CONFIG); // need change config access if (schSvc == NULL) { _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError()); CloseServiceHandle(schSCM); return; } // Change the service description. // 改变服务描述; sd.lpDescription = szDesc; if (!ChangeServiceConfig2( schSvc, // 服务句柄; SERVICE_CONFIG_DESCRIPTION, // 要改变的类型: description; &sd)) // 新描述; { _tprintf_s(_T("ChangeServiceConfig2 failed\n")); } else { _tprintf_s(_T("Service description updated successfully.\n")); } CloseServiceHandle(schSvc); CloseServiceHandle(schSCM); } /************************************************************************/ /* 函数:[4/23/2016 home]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void DoDeleteSvc(IN LPCTSTR lpSvcName) { if (lpSvcName == NULL || lpSvcName[0] == _T('\0')) { _tprintf_s(_T("要删除的服务名称无效\n")); return; } SC_HANDLE schSCM; SC_HANDLE schSvc; SERVICE_STATUS ssStatus; // 打开服务管理器; schSCM = OpenSCManager( NULL, // NULL表示本地计算机; NULL, // NULL表示ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCM) { _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError()); return; } // 打开服务; schSvc = OpenService( schSCM, // SCM database lpSvcName, // name of service SERVICE_STOP | DELETE // need delete access ); if (schSvc == NULL) { _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError()); CloseServiceHandle(schSCM); return; } // 删除服务关,需要先停止服务; if (!::ControlService(schSvc, SERVICE_CONTROL_STOP, &ssStatus)) { _tprintf_s(_T("删除服务前停止服务失败 (%d)\n"), GetLastError()); } // 删除服务; if (!DeleteService(schSvc)) { _tprintf_s(_T("DeleteService failed (%d)\n"), GetLastError()); SvcReportEvent(_T("Service could not be deleted")); } else { _tprintf_s(_T("Service deleted successfully\n")); } CloseServiceHandle(schSvc); CloseServiceHandle(schSCM); } /************************************************************************/ /* 函数:SetCallBack[5/5/2016 Home]; /* 描述:设置回调函数; /* 参数:; /* [IN] lpStartWorkCallBack:工作开始回调指针; /* [IN] lpEndofWorkCallBack:工作结束回调指针; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void SetCallBack(IN LPVOID lpStartWorkCallBack, IN LPVOID lpEndofWorkCallBack) { if (g_scVariant.lpStartWorkCallBack == NULL) g_scVariant.lpStartWorkCallBack = (WorkEndofCallback)lpStartWorkCallBack; if (g_scVariant.lpEndofWorkCallBack == NULL) g_scVariant.lpEndofWorkCallBack = (WorkEndofCallback)lpEndofWorkCallBack; } /************************************************************************/ /* 函数:StartProcess[5/6/2016 IT]; /* 描述:在服务进程里,调用外部EXE; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ BOOL StartProcess(IN LPCTSTR lpExePath) { #if 0 if (!lpExePath || !PathFileExists(lpExePath)) { return FALSE; } HANDLE hToken; if (!GetTokenByName(hToken, _T("EXPLORER.EXE"))) { return FALSE; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.lpDesktop = TEXT("winsta0\\default"); BOOL bResult = CreateProcessAsUser(hToken, lpExePath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); DWORD dwError = GetLastError();// 返回740错误,表示服务必须在Admin账号下运行才能创建成功; //CreateProcessWithTokenW(hToken, ) CloseHandle(hToken); if (bResult) { // WriteLogAlways(_T("C:\\serverlog.txt"),_T("CreateProcessAsUser ok")); } else { //WriteLogAlways(_T("C:\\servererrlog.txt"),_T("CreateProcessAsUser failed")); } #else HANDLE hPtoken = NULL; GetExplorerToken(&hPtoken); //if(!GetTokenByName(hPtoken,_T("EXPLORER.EXE"))) //{ // return FALSE; //} PROCESS_INFORMATION pi; STARTUPINFOW si = { sizeof(STARTUPINFO), NULL, L"", NULL, 0, 0, 0, 0, 0, 0, 0, STARTF_USESHOWWINDOW, 0, 0, NULL, 0, 0, 0 }; si.wShowWindow = SW_SHOW; si.lpDesktop = NULL; ZeroMemory(&pi, sizeof(pi)); static HMODULE advapi32_dll = LoadLibraryW(L"advapi32.dll"); if (!advapi32_dll) return FALSE; /*static F_CreateProcessWithTokenW f_CreateProcessWithTokenW = (F_CreateProcessWithTokenW)( GetProcAddress(advapi32_dll,"CreateProcessWithTokenW")); if (f_CreateProcessWithTokenW == NULL) return ; */ BOOL bResult = CreateProcessWithTokenW(hPtoken, LOGON_WITH_PROFILE, NULL, (LPWSTR)lpExePath, NULL, NULL, NULL, &si, &pi); DWORD dwError = GetLastError(); Sleep(1000); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); #endif return bResult; } /************************************************************************/ /* 函数:[5/6/2016 IT]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ BOOL GetTokenByName(IN HANDLE &hToken, IN LPCTSTR lpName) { if (!lpName) { return FALSE; } BOOL bRet = FALSE; HANDLE hProcessSnap = NULL; PROCESSENTRY32 pe32 = { 0 }; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) return FALSE; pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hProcessSnap, &pe32)) { do { CString exefile = pe32.szExeFile; CString paraname = lpName; if (!exefile.CompareNoCase(lpName)) { HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken); CloseHandle(hProcessSnap); return bRet; } } while (Process32Next(hProcessSnap, &pe32)); bRet = TRUE; } else bRet = FALSE; CloseHandle(hProcessSnap); return bRet; } /************************************************************************/ /* 函数:[5/6/2016 IT]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ // Jeff.Hacker. WINDOWS NT 以上的内核需要提权,才能对系统进行高级管理; BOOL GetDebugPriv() { // 返回的访问令牌指针; HANDLE hToken; // 接收所返回的制定特权名称的信息; LUID sedebugnameValue; // 新特权信息的指针(结构体); TOKEN_PRIVILEGES tkp; DWORD dwCurProcId = GetCurrentProcessId(); // 要修改访问权限的进程句柄; HANDLE hCurProc; hCurProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwCurProcId); if (!::OpenProcessToken(hCurProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { //ShowSystemErrorInfo(_T("升级包OpenProcessToken失败."),GetLastError()); return FALSE; } if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) { //ShowSystemErrorInfo(_T("升级包LookupPrivilegeValue失败."),GetLastError()); CloseHandle(hToken); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = sedebugnameValue; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!::AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL)) { //ShowSystemErrorInfo(_T("升级包AdjustTokenPrivileges失败."),GetLastError()); CloseHandle(hToken); return FALSE; } CloseHandle(hCurProc); CloseHandle(hToken); return TRUE; } DWORD GetExplorerToken(OUT HANDLE* phExplorerToken) { DWORD dwStatus = ERROR_FILE_NOT_FOUND; BOOL bRet = FALSE; HANDLE hProcess = NULL; HANDLE hProcessSnap = NULL; TCHAR szExplorerPath[MAX_PATH] = { 0 }; TCHAR FileName[MAX_PATH] = { 0 }; PROCESSENTRY32 pe32 = { 0 }; __try { GetWindowsDirectory(szExplorerPath, MAX_PATH); _tcscat_s(szExplorerPath, MAX_PATH, _T("\\Explorer.EXE")); hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) { dwStatus = GetLastError(); __leave; } pe32.dwSize = sizeof(PROCESSENTRY32); if (!Process32First(hProcessSnap, &pe32)) { dwStatus = GetLastError(); __leave; } int ii = 0; do { hProcess = OpenProcess(PROCESS_ALL_ACCESS/*PROCESS_QUERY_INFORMATION*/, FALSE, pe32.th32ProcessID); if (NULL != hProcess) { ii++; //if ( GetModuleFileNameEx(hProcess , NULL , FileName , MAX_PATH) ) //{ if (_tcsicmp(pe32.szExeFile, _T("Explorer.EXE")) == 0) { HANDLE hToken; if (OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken)) { HANDLE hNewToken = NULL; DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken); *phExplorerToken = hNewToken; dwStatus = 0; CloseHandle(hToken); } break; } //} CloseHandle(hProcess); hProcess = NULL; } } while (Process32Next(hProcessSnap, &pe32)); } __finally { if (NULL != hProcess) { CloseHandle(hProcess); } if (NULL != hProcessSnap) { CloseHandle(hProcessSnap); } } return dwStatus; } // 打进服务事件日志里; void LogEvent(IN LPCTSTR pFormat, ...) { TCHAR chMsg[MAX_PATH]; HANDLE hEventLog; LPTSTR lpszStrings[1]; va_list pArg; va_start(pArg, pFormat); StringCchVPrintf(chMsg, MAX_PATH, pFormat, pArg); va_end(pArg); lpszStrings[0] = chMsg; hEventLog = RegisterEventSource(NULL, g_scVariant.scName); if (hEventLog != NULL) { ReportEvent(hEventLog, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*)&lpszStrings[0], NULL); if (hEventLog) DeregisterEventSource(hEventLog); } } };