#include "stdafx.h" #include "WindowService.h" #include #include #pragma comment ( lib, "psapi.lib" ) #include #include #include namespace WindowsService { ////////////////////////////////////////////////////////////////////////// // 全局变量; ////////////////////////////////////////////////////////////////////////// SERVICE_STATUS_HANDLE g_SvcStatusHandle; // 服务句柄; SERVICE_STATUS g_SvcStatus; // 服务状态; HANDLE g_hCtrlSvc = NULL; // 服务控制事件; TCHAR g_szlpSvrDescription[MAX_PATH] = _T(""); // 服务描述 ; TCHAR g_szSvcName[MAX_PATH] = _T(""); // 服务名称; WorkStartCallback g_lpStartWorkCallBack = NULL; // 开启工作者; WorkEndofCallback g_lpEndofWorkCallBack = NULL; // 结束工作者; ////////////////////////////////////////////////////////////////////////// // 全局函数; int InitWinSock() { WORD wVersionRequested; WSADATA wsaData; int nErrCode; wVersionRequested = MAKEWORD(2, 2); nErrCode = WSAStartup( wVersionRequested, &wsaData ); if ( 0 != nErrCode ) return -1; return 0; } /************************************************************************/ /* 函数:InitSvcVar[4/22/2016 home]; /* 描述:初始化服务变量; /* 参数:; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void InitSvcVar() { g_SvcStatusHandle = NULL; g_SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS; // | SERVICE_INTERACTIVE_PROCESS与桌面交互; g_SvcStatus.dwCurrentState = SERVICE_STOPPED; g_SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; g_SvcStatus.dwWin32ExitCode = 0; g_SvcStatus.dwServiceSpecificExitCode = 0; g_SvcStatus.dwCheckPoint = 0; g_SvcStatus.dwWaitHint = 0; } /************************************************************************/ /* 函数:IsSvcInstalled[4/22/2016 home]; /* 描述:判断服务是否安装; /* 参数:; /* 返回:若服务已安装返回TRUE,否则返回FALSE; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ BOOL IsSvcInstalled() { BOOL bResult = FALSE; // 打开服务控制管理器; SC_HANDLE schSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (schSCM != NULL) {// 打开服务; SC_HANDLE schSvc = ::OpenService(schSCM, g_szSvcName, SERVICE_QUERY_CONFIG); if (schSvc != NULL) { bResult = TRUE; ::CloseServiceHandle(schSvc); } ::CloseServiceHandle(schSCM); } return bResult; } /************************************************************************/ /* 函数:SvcInstall[4/22/2016 home]; /* 描述:安装服务; /* 参数:; /* 返回:安装成功返回TRUE,否则返回FALSE; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ BOOL SvcInstall() { // 获取服务程序的绝对路径; 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_szSvcName, // 服务名称; g_szSvcName, // 服务描述; 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_szlpSvrDescription; ::ChangeServiceConfig2(schSvc, SERVICE_CONFIG_DESCRIPTION, &ServiceDesc); // 释放资源; ::CloseServiceHandle(schSvc); ::CloseServiceHandle(schSCM); return TRUE; } /************************************************************************/ /* 函数:ServiceMain[4/23/2016 home]; /* 描述:服务入口函数; /* 参数:; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void WINAPI ServiceMain() { // 注册服务的控制函数; g_SvcStatusHandle = RegisterServiceCtrlHandler(g_szSvcName, SvcCtrlHandler); if (g_SvcStatusHandle == NULL) { SvcReportEvent(_T("Handler not installed")); return; } // 在这里设置服务状态; g_SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; g_SvcStatus.dwServiceSpecificExitCode = 0; // 注册成功后向SCM报告服务状态信息,因为服务还没初始化完成; // 所以当前服务状态为SERVICE_START_PENDING ; ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, 3000); // 处理第一个事件大约需要3秒钟; ////////////////////////////////////////////////////////////////////////// // 开始初始化服务; g_hCtrlSvc = ::CreateEvent( NULL,TRUE, FALSE, _T("CtrlService::g_hCtrlSvc")); if (g_hCtrlSvc == NULL) { // 向SCM报告服务已停止; ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 0); return; } // 向SCM报告服务正在运行; ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0, 0, 0); // 开启工作者; if ( g_lpStartWorkCallBack ) g_lpStartWorkCallBack(); // 线程中的处理函数运行结束后返回ServiceMain(), // ServiceMain()调用WaitForSingleObject, // 因为服务被停止之前ServiceMain()不会结束 WaitForSingleObject(g_hCtrlSvc,INFINITE); // INFINITE表示无限等待,等待SCM的信号; CloseHandle(g_hCtrlSvc); // 结束工作者; if ( g_lpEndofWorkCallBack ) g_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) 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_SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; // 表示我们的服务是独占一个进程的服务 ; g_SvcStatus.dwCurrentState = dwCurrentState; // 当前服务状态; g_SvcStatus.dwWaitHint = dwWaitHint; if( dwCurrentState == SERVICE_START_PENDING ) { g_SvcStatus.dwControlsAccepted = 0; // 不接受任何控制通知; } else { // 通知 SCM 服务接受哪个控制通知:这里允许停止、关机、暂停继续; g_SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ; //|SERVICE_ACCEPT_PAUSE_CONTINUE; } if ( (dwCurrentState == SERVICE_RUNNING ) || ( dwCurrentState == SERVICE_STOPPED ) ) g_SvcStatus.dwCheckPoint = 0; else g_SvcStatus.dwCheckPoint = dwCheckPoint++; // dwServiceSpecificExitCode在你终止服务并报告退出细节时很有用。 // 初始化服务时并不退出,因此值为 0; if(dwServiceSpecificExitCode == 0) { g_SvcStatus.dwWin32ExitCode = dwWin32ExitCode; } else { g_SvcStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; //用户自定义错误代码; } g_SvcStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode; //设置好nServiceStatus后,向SCM报告服务状态,非0表示成功,0表示失败; bSuccess = SetServiceStatus( g_SvcStatusHandle,&g_SvcStatus); if( !bSuccess ) { SvcReportEvent(_T("Set Service Status failed (%d) "), GetLastError()); KillService(); return FALSE; } else return TRUE; } // 结束服务; void KillService() { //LOG4C((LOG_NOTICE,"KillService.")); SetEvent(g_hCtrlSvc); //如果操作成功,则返回非零值,否则为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_szSvcName); if (hEventSource != NULL) { lpszStrings[0] = g_szSvcName; 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) { if ( lpSvcName == NULL || lpSvcName[0] == _T('\0')) { _tprintf_s(_T("要启动的服务名空\n")); return; } 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数据库; lpSvcName, // 服务名称; 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 DoStopSvc(IN LPCTSTR lpSvcName) { if ( lpSvcName == NULL || lpSvcName[0] == _T('\0')) { _tprintf_s(_T("指定要停止的服务名无效\n")); return; } 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 lpSvcName, // 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_szSvcName); _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_lpStartWorkCallBack == NULL ) g_lpStartWorkCallBack = (WorkEndofCallback)lpStartWorkCallBack; if ( g_lpEndofWorkCallBack == NULL ) g_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 ; } };