// http://msdn.microsoft.com/en-gb/library/windows/desktop/ms686335.aspx static void restartService(const char *lpServiceName) { SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); assert(hSCManager); if (!hSCManager) { return; } SC_HANDLE hService = OpenServiceA(hSCManager, lpServiceName, SC_MANAGER_ALL_ACCESS); assert(hService); if (!hService) { return; } SERVICE_STATUS_PROCESS ssp; DWORD cbBytesNeeded; QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE) &ssp, sizeof ssp, &cbBytesNeeded); BOOL bRet; if (ssp.dwCurrentState == SERVICE_RUNNING) { bRet = ControlService(hService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS) &ssp); assert(bRet); while (ssp.dwCurrentState != SERVICE_STOPPED) { Sleep(ssp.dwWaitHint); QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE) &ssp, sizeof ssp, &cbBytesNeeded); } bRet = StartService(hService, 0, NULL); assert(bRet); } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); }
LPSERVICE_STATUS_PROCESS QueryService(LPCTSTR ServiceName) { SC_HANDLE hSCManager = NULL; LPSERVICE_STATUS_PROCESS pServiceInfo = NULL; SC_HANDLE hSc = NULL; DWORD BufSiz = 0; DWORD BytesNeeded = 0; DWORD Ret; hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager == NULL) { ReportLastError(); return NULL; } hSc = OpenService(hSCManager, ServiceName, SERVICE_QUERY_STATUS); if (hSc == NULL) goto fail; Ret = QueryServiceStatusEx(hSc, SC_STATUS_PROCESS_INFO, NULL, BufSiz, &BytesNeeded); if ((Ret != 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) goto fail; pServiceInfo = (LPSERVICE_STATUS_PROCESS)HeapAlloc(GetProcessHeap(), 0, BytesNeeded); if (pServiceInfo == NULL) goto fail; if (!QueryServiceStatusEx(hSc, SC_STATUS_PROCESS_INFO, (LPBYTE)pServiceInfo, BytesNeeded, &BytesNeeded)) { goto fail; } CloseServiceHandle(hSc); CloseServiceHandle(hSCManager); return pServiceInfo; fail: ReportLastError(); if (pServiceInfo) HeapFree(GetProcessHeap(), 0, pServiceInfo); if (hSc) CloseServiceHandle(hSc); if (hSCManager) CloseServiceHandle(hSCManager); return NULL; }
/* {{{ proto mixed win32_query_service_status(string servicename [, string machine]) Queries the status of a service */ static PHP_FUNCTION(win32_query_service_status) { char *machine = NULL; char *service = NULL; size_t machine_len = 0; size_t service_len = 0; SC_HANDLE hsvc; SC_HANDLE hmgr; SERVICE_STATUS_PROCESS *st; DWORD size; if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &service, &service_len, &machine, &machine_len)) { RETURN_FALSE; } hmgr = OpenSCManager(machine, NULL, GENERIC_READ); if (hmgr) { hsvc = OpenService(hmgr, service, SERVICE_QUERY_STATUS); if (hsvc) { size = sizeof(*st); st = emalloc(size); if (!QueryServiceStatusEx(hsvc, SC_STATUS_PROCESS_INFO, (LPBYTE)st, size, &size)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { RETVAL_LONG(GetLastError()); goto out_fail; } st = erealloc(st, size); if (!QueryServiceStatusEx(hsvc, SC_STATUS_PROCESS_INFO, (LPBYTE)st, size, &size)) { RETVAL_LONG(GetLastError()); goto out_fail; } } /* map the struct to an array */ array_init(return_value); add_assoc_long(return_value, "ServiceType", st->dwServiceType); add_assoc_long(return_value, "CurrentState", st->dwCurrentState); add_assoc_long(return_value, "ControlsAccepted", st->dwControlsAccepted); add_assoc_long(return_value, "Win32ExitCode", st->dwWin32ExitCode); add_assoc_long(return_value, "ServiceSpecificExitCode", st->dwServiceSpecificExitCode); add_assoc_long(return_value, "CheckPoint", st->dwCheckPoint); add_assoc_long(return_value, "WaitHint", st->dwWaitHint); add_assoc_long(return_value, "ProcessId", st->dwProcessId); add_assoc_long(return_value, "ServiceFlags", st->dwServiceFlags); out_fail: CloseServiceHandle(hsvc); } else { RETVAL_LONG(GetLastError()); } CloseServiceHandle(hmgr); } else { RETVAL_LONG(GetLastError()); } }
BOOL UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService) { SC_HANDLE hScm; BOOL bRet = FALSE; hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); if (hScm != NULL) { SC_HANDLE hService; hService = OpenServiceW(hScm, pService->lpServiceName, SERVICE_QUERY_STATUS); if (hService) { DWORD size; QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&pService->ServiceStatusProcess, sizeof(SERVICE_STATUS_PROCESS), &size); CloseServiceHandle(hService); bRet = TRUE; } CloseServiceHandle(hScm); } return bRet; }
bool IsServiceInstalled() { bool ret = false; SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); if (NULL == schSCManager) { return ret; } SC_HANDLE schService = OpenService( schSCManager, srvName, SERVICE_ALL_ACCESS); if (schService != NULL) { SERVICE_STATUS_PROCESS ssStatus; DWORD dwBytesNeeded; if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssStatus, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { if (ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING) { ret = true; } } } CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return ret; }
BOOL IsServiceRunning(HWND hWnd, SC_HANDLE schSCManager, char *szSvcName) { SC_HANDLE schService; SERVICE_STATUS_PROCESS ssStatus; DWORD dwBytesNeeded; schService = OpenService( schSCManager, // SCM база с данни szSvcName, // име на сервиса SERVICE_ALL_ACCESS); // пълен достъп if (schService == NULL) { return FALSE; } if (!QueryServiceStatusEx( schService, // дръжка до сервиса SC_STATUS_PROCESS_INFO, // информационно ниво (LPBYTE) &ssStatus, // адреса на структура sizeof(SERVICE_STATUS_PROCESS), // големина на структура &dwBytesNeeded)) // необходима големина, ако буфера е много малък { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } // Проверява дали сервиса работи. if(ssStatus.dwCurrentState == SERVICE_RUNNING) { CloseServiceHandle(schService); return TRUE; } return FALSE; }
int check_run() { int install_res = check_install(); if (install_res != 1) return install_res; int res = 0; SC_HANDLE sch_manager = NULL; SC_HANDLE sch_service = NULL; sch_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (sch_manager) { sch_service = OpenService(sch_manager, "win_srv_tests_helper", SERVICE_ALL_ACCESS); if (sch_service) { SERVICE_STATUS_PROCESS ssp_status; DWORD dw_temp; if (QueryServiceStatusEx(sch_service, SC_STATUS_PROCESS_INFO, reinterpret_cast<LPBYTE> (&ssp_status), sizeof(SERVICE_STATUS_PROCESS), &dw_temp ) == TRUE ) { if (ssp_status.dwCurrentState == SERVICE_RUNNING) res = 1; } CloseServiceHandle(sch_service); } CloseServiceHandle(sch_manager); } else { res = -1; std::cout << "Error in open SCManager" << std::endl; } return res; }
BOOL WaitForService( SC_HANDLE hService, ULONG RetryCount) { ULONG Index = 0; DWORD dwSize; SERVICE_STATUS_PROCESS Info; do { if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&Info, sizeof(SERVICE_STATUS_PROCESS), &dwSize)) { logmsg("QueryServiceStatusEx failed %x\n", GetLastError()); break; } if (Info.dwCurrentState == SERVICE_RUNNING) return TRUE; Sleep(1000); }while(Index++ < RetryCount); logmsg("Timeout while waiting for service to become ready %p\n", hService); return FALSE; }
// // Purpose: // Deletes a service from the SCM database // // Parameters: // None // // Return value: // None // VOID __stdcall DoDeleteSvc() { SC_HANDLE schSCManager; SC_HANDLE schService; SERVICE_STATUS_PROCESS ssp; DWORD dwBytesNeeded; // 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 DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS); // need delete access if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); return; } if (ssp.dwCurrentState != SERVICE_STOPPED) { DoStopSvc(); } // Delete the service. if (!DeleteService(schService)) { printf("DeleteService failed (%d)\n", GetLastError()); } else printf("Service deleted successfully\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); }
/* ServiceRemove() https://msdn.microsoft.com/en-us/library/windows/desktop/ms682571%28v=vs.85%29.aspx */ int ServiceRemove( ) { SC_HANDLE schSCManager; SC_HANDLE schService; SERVICE_STATUS_PROCESS ssStatus; DWORD dwBytesNeeded; // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (schSCManager == NULL){ printf("[-] Error :: ServiceRemove!OpenSCManager() failed (%d)\n", GetLastError()); return -1; } // Get a handle to the service. schService = OpenService(schSCManager, SVCNAME, DELETE|SERVICE_QUERY_STATUS); if (schService == NULL) { printf("[-] Error :: ServiceRemove!OpenService() failed :: exit_code = %d\n",GetLastError()); CloseServiceHandle(schSCManager); return -1; } // Check the status in case the service is started. If it's the case, then stop it first. if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssStatus, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { printf("[-] Error :: ServiceRemove!QueryServiceStatusEx() failed :: exit_code = %d\n",GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return -1; } if (ssStatus.dwCurrentState == SERVICE_RUNNING || ssStatus.dwCurrentState == SERVICE_START_PENDING ) { printf("[i] Debug :: ServiceRemove :: Stopping the service...\n"); ServiceStop( ); } // Delete the service if (!DeleteService(schService)) { printf("[-] Error :: ServiceRemove!DeleteService() failed :: exit_code = %d\n",GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return -1; } // Delete Registry keys DeleteRegistryKeys( ); printf("[+] Debug :: Service deleted sucessfully !\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return 0; }
static void test_service(void) { static const WCHAR spooler[] = {'S','p','o','o','l','e','r',0}; static const WCHAR dummyW[] = {'d','u','m','m','y',0}; SERVICE_STATUS_PROCESS status; SC_HANDLE scm, service; IShellDispatch2 *sd; DWORD dummy; HRESULT hr; BSTR name; VARIANT v; hr = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch2, (void**)&sd); if (hr != S_OK) { win_skip("IShellDispatch2 not supported\n"); return; } V_VT(&v) = VT_I2; V_I2(&v) = 10; hr = IShellDispatch2_IsServiceRunning(sd, NULL, &v); ok(V_VT(&v) == VT_BOOL, "got %d\n", V_VT(&v)); ok(V_BOOL(&v) == VARIANT_FALSE, "got %d\n", V_BOOL(&v)); EXPECT_HR(hr, S_OK); scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); service = OpenServiceW(scm, spooler, SERVICE_QUERY_STATUS); QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status, sizeof(SERVICE_STATUS_PROCESS), &dummy); CloseServiceHandle(service); CloseServiceHandle(scm); /* service should exist */ name = SysAllocString(spooler); V_VT(&v) = VT_I2; hr = IShellDispatch2_IsServiceRunning(sd, name, &v); EXPECT_HR(hr, S_OK); ok(V_VT(&v) == VT_BOOL, "got %d\n", V_VT(&v)); if (status.dwCurrentState == SERVICE_RUNNING) ok(V_BOOL(&v) == VARIANT_TRUE, "got %d\n", V_BOOL(&v)); else ok(V_BOOL(&v) == VARIANT_FALSE, "got %d\n", V_BOOL(&v)); SysFreeString(name); /* service doesn't exist */ name = SysAllocString(dummyW); V_VT(&v) = VT_I2; hr = IShellDispatch2_IsServiceRunning(sd, name, &v); EXPECT_HR(hr, S_OK); ok(V_VT(&v) == VT_BOOL, "got %d\n", V_VT(&v)); ok(V_BOOL(&v) == VARIANT_FALSE, "got %d\n", V_BOOL(&v)); SysFreeString(name); IShellDispatch2_Release(sd); }
DWORD ServiceStatus(CONST printInfoStruct& printInfo) { SC_HANDLE hSCM; SC_HANDLE hService; DWORD cbBufSize; LPBYTE lpBuf = NULL; if (debug) std::wcout << L"Opening SC Manager" << '\n'; hSCM = OpenSCManager(NULL, NULL, GENERIC_READ); if (hSCM == NULL) goto die; if (debug) std::wcout << L"Getting Service Information" << '\n'; hService = OpenService(hSCM, printInfo.service.c_str(), SERVICE_QUERY_STATUS); if (hService == NULL) goto die; QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, NULL, 0, &cbBufSize); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto die; lpBuf = new BYTE[cbBufSize]; if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, lpBuf, cbBufSize, &cbBufSize)) { LPSERVICE_STATUS_PROCESS pInfo = (LPSERVICE_STATUS_PROCESS)lpBuf; return pInfo->dwCurrentState; } die: die(); if (hSCM) CloseServiceHandle(hSCM); if (hService) CloseServiceHandle(hService); delete [] lpBuf; return -1; }
Status uninstallService() { SC_HANDLE schSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT); if (schSCManager == nullptr) { return Status(1); } SC_HANDLE schService = OpenService(schSCManager, kServiceName.c_str(), SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE); if (schService == nullptr) { CloseServiceHandle(schService); return Status(1); } SERVICE_STATUS_PROCESS ssStatus; DWORD dwBytesNeeded; if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssStatus, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return Status(1); } SERVICE_STATUS ssSvcStatus = {}; if (ssStatus.dwCurrentState != SERVICE_STOPPED) { ControlService(schService, SERVICE_CONTROL_STOP, &ssSvcStatus); // Wait 3 seconds to give the service an opportunity to stop. Sleep(3000); QueryServiceStatus(schService, &ssSvcStatus); if (ssSvcStatus.dwCurrentState != SERVICE_STOPPED) { CloseServiceHandle(schSCManager); CloseServiceHandle(schService); return Status(1); } } auto s = DeleteService(schService); CloseServiceHandle(schSCManager); CloseServiceHandle(schService); return Status(s ? 0 : 1); }
BOOL kull_m_service_getUniqueForName(PCWSTR serviceName, SERVICE_STATUS_PROCESS * pServiceStatusProcess) { BOOL status = FALSE; SC_HANDLE hSC, hS; DWORD szNeeded; if(hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT)) { if(hS = OpenService(hSC, serviceName, SERVICE_QUERY_STATUS)) { status = QueryServiceStatusEx(hS, SC_STATUS_PROCESS_INFO, (BYTE *) pServiceStatusProcess, sizeof(SERVICE_STATUS_PROCESS), &szNeeded); CloseServiceHandle(hS); } CloseServiceHandle(hSC); } return status; }
BOOL UtilGetServiceState ( _In_ SC_HANDLE hService, _Out_ DWORD* State ) /*++ Routine Description: Gets the state of the service using QueryServiceStatusEx Arguments: hService - handle to the service to query State - pointer to a variable that receives the state Return Value: TRUE if service is queried successfully. --*/ { SERVICE_STATUS_PROCESS ServiceStatus; DWORD BytesNeeded; BOOL Result; *State = 0; Result = QueryServiceStatusEx ( hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus, sizeof(ServiceStatus), &BytesNeeded); if (Result == FALSE) { ErrorPrint("QueryServiceStatusEx failed, last error 0x%x", GetLastError()); return FALSE; } *State = ServiceStatus.dwCurrentState; return TRUE; }
static HRESULT WINAPI ShellDispatch_IsServiceRunning(IShellDispatch2 *iface, BSTR name, VARIANT *running) { SERVICE_STATUS_PROCESS status; SC_HANDLE scm, service; DWORD dummy; TRACE("(%s, %p)\n", debugstr_w(name), running); V_VT(running) = VT_BOOL; V_BOOL(running) = VARIANT_FALSE; scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); if (!scm) { ERR("failed to connect to service manager\n"); return S_OK; } service = OpenServiceW(scm, name, SERVICE_QUERY_STATUS); if (!service) { ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError()); CloseServiceHandle(scm); return S_OK; } if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status, sizeof(SERVICE_STATUS_PROCESS), &dummy)) { TRACE("failed to query service status (%u)\n", GetLastError()); CloseServiceHandle(service); CloseServiceHandle(scm); return S_OK; } if (status.dwCurrentState == SERVICE_RUNNING) V_BOOL(running) = VARIANT_TRUE; CloseServiceHandle(service); CloseServiceHandle(scm); return S_OK; }
void ServiceManager::WaitForServiceStop(const SCMHandleHolder &schService) { static const DWORD SERVICE_STOP_WAIT_QUANTUM = 50; static const DWORD SERVICE_STOP_ITERATIONS = 20000 / 50; //Total timeout is 20 seconds SERVICE_STATUS_PROCESS ssp; DWORD iterationNumber = 0; do { Sleep(SERVICE_STOP_WAIT_QUANTUM); DWORD bytesNeeded; if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) { throw UsbDkServiceManagerFailedException(TEXT("QueryServiceStatusEx failed")); } } while ((ssp.dwCurrentState != SERVICE_STOPPED) && (iterationNumber++ < SERVICE_STOP_ITERATIONS)); }
BOOL enzyme::kernel::Service::stop() { if(mHandle != INVALID_HANDLE_VALUE) { CloseHandle(mHandle); } if(mSCHandle != INVALID_HANDLE_VALUE) { SERVICE_STATUS_PROCESS status; if(ControlService(mSCHandle, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&status)) { DWORD timeout = GetTickCount() + 5000; while(status.dwCurrentState != SERVICE_STOPPED) { DWORD tmp; if(GetTickCount() >= timeout) { std::clog << "Timeout stopping kernel driver" << std::endl; break; } Sleep(50); if(!QueryServiceStatusEx(mSCHandle, SC_STATUS_PROCESS_INFO, (LPBYTE)&status, sizeof(SERVICE_STATUS_PROCESS), &tmp)) { break; } } } else if(GetLastError() != ERROR_SERVICE_NOT_ACTIVE) { std::clog << lasterror() << std::endl; } DeleteService(mSCHandle); return CloseServiceHandle(mSCHandle); } return TRUE; }
int analysis::driverStatus() { DWORD dwBytes; SERVICE_STATUS_PROCESS status; if(!manager) manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(!manager) return 0; if(!service) service=OpenServiceA( manager, "hookrevealer", SERVICE_ALL_ACCESS); if(!service) return DRIVER_NOT_INSTALLED; if(!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&status, sizeof(SERVICE_STATUS_PROCESS), &dwBytes)) return 0; if(status.dwCurrentState == SERVICE_STOPPED || status.dwCurrentState == SERVICE_STOP_PENDING) return DRIVER_STOPPED; return DRIVER_STARTED; }
static int UninstallService(const char * sServiceName) { SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(schSCManager == NULL) { printf("OpenSCManager failed (%d)!", GetLastError()); return EXIT_FAILURE; } SC_HANDLE schService = OpenService(schSCManager, sServiceName, SERVICE_QUERY_STATUS | SERVICE_STOP | DELETE); if(schService == NULL) { printf("OpenService failed (%d)!", GetLastError()); CloseServiceHandle(schSCManager); return EXIT_FAILURE; } SERVICE_STATUS_PROCESS ssp; DWORD dwBytesNeeded; if(QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded) != 0) { if(ssp.dwCurrentState != SERVICE_STOPPED && ssp.dwCurrentState != SERVICE_STOP_PENDING) { ControlService(schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp); } } if(DeleteService(schService) == false) { printf("DeleteService failed (%d)!", GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return EXIT_FAILURE; } else { printf("PtokaX service '%s' deleted successfully.", sServiceName); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return EXIT_SUCCESS; } }
BOOL MainFrame::StopDependentServices(SC_HANDLE schSCManager, SC_HANDLE schService) { 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 // 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; }
// // Purpose: // Starts the service if possible. // // Parameters: // None // // Return value: // None // void MainFrame::DoStartSvc(LPCTSTR szSvcName) { SERVICE_STATUS_PROCESS ssStatus; DWORD dwOldCheckPoint; DWORD dwStartTickCount; DWORD dwWaitTime; DWORD dwBytesNeeded; // Get a handle to the SCM database. SC_HANDLE 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. SC_HANDLE schService = OpenService( schSCManager, // SCM database szSvcName, // name of service SERVICE_ALL_ACCESS); // full access if (schService == NULL) { //printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } // Check the status in case the service is not stopped. 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 { //printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); 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) { //printf("Cannot start the service because it is already running\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); 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 { //printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return; } if ( ssStatus.dwCheckPoint > dwOldCheckPoint ) { // Continue to wait and check. dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; } else { if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint) { //printf("Timeout waiting for service to stop\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return; } } } // Attempt to start the service. if (!StartService( schService, // handle to service 0, // number of arguments NULL) ) // no arguments { //printf("StartService failed (%d)\n", GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); 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 { //printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); 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 { //printf("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) { //printf("Service started successfully.\n"); } //else //{ // printf("Service not started. \n"); // printf(" Current State: %d\n", ssStatus.dwCurrentState); // printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode); // printf(" Check Point: %d\n", ssStatus.dwCheckPoint); // printf(" Wait Hint: %d\n", ssStatus.dwWaitHint); //} CloseServiceHandle(schService); CloseServiceHandle(schSCManager); }
BOOL PacketIsServiceStopPending() { BOOL bResult = FALSE; SERVICE_STATUS_PROCESS ssp; DWORD dwStartTime = GetTickCount(); DWORD dwBytesNeeded; DWORD dwTimeout = 30000; // 30-second time-out // DWORD dwWaitTime; // Get a handle to the SCM database. SC_HANDLE 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 FALSE; } // Get a handle to the service. SC_HANDLE schService = OpenService( schSCManager, // SCM database _T(NPF_DRIVER_NAME_SMALL), // name of service SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS); if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return FALSE; } // 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 (ssp.dwCurrentState == SERVICE_STOP_PENDING) { bResult = TRUE; } stop_cleanup: CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return bResult; }
/** * Reports if the rxapi service is in the running state at the time this * function returns. If the service is in the START PENDING state the function * waits untils the service is running or has timed out. * * @param hService Opened service handle, must have the SERVICE_QUERY_STATUS * privilege. * * @return True the service is not running, otherwise false. */ static bool hasServiceStarted(SC_HANDLE hService) { SERVICE_STATUS_PROCESS ssp; DWORD needed; if ( QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &needed) == 0 ) { return false; } if ( ssp.dwCurrentState == SERVICE_RUNNING || ssp.dwCurrentState == SERVICE_STOPPED || ssp.dwCurrentState == SERVICE_STOP_PENDING ) { return ssp.dwCurrentState == SERVICE_RUNNING; } // Save the tick count and initial checkpoint. uint32_t startTicks = GetTickCount(); uint32_t oldCheck = ssp.dwCheckPoint; uint32_t waitTime; // Check the status until the service is no longer start pending. rxapi is // not pausable, so PAUSED or PAUSED_PENDING should not be possible. while ( ssp.dwCurrentState == SERVICE_START_PENDING ) { // Do not wait longer than the wait hint, which for rxapi will be 2000 // milliseconds. // // Microsoft suggests that a good interval is one tenth the wait hint, // but not less than 1 second and no more than 10 seconds. rxapi usually // starts in less than 200 milliseconds. waitTime = ssp.dwWaitHint / 10; if( waitTime < 200 ) { waitTime = 200; } else if ( waitTime > 10000 ) { waitTime = 10000; } Sleep(waitTime); BOOL success = QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &needed); if ( ! success || ssp.dwCurrentState == SERVICE_RUNNING ) { break; } if ( ssp.dwCheckPoint > oldCheck ) { // The service is making progress, so continue. startTicks = GetTickCount(); oldCheck = ssp.dwCheckPoint; } else { if( (GetTickCount() - startTicks) > ssp.dwWaitHint ) { // The wait hint interval has expired and we are still not // started, so quit. break; } } } return ssp.dwCurrentState == SERVICE_RUNNING ? true : false; }
DWORD WINAPI PlayLogonSoundThread( IN LPVOID lpParameter) { BYTE TokenUserBuffer[256]; PTOKEN_USER pTokenUser = (TOKEN_USER*)TokenUserBuffer; ULONG Length; HKEY hKey; WCHAR wszBuffer[MAX_PATH] = {0}; WCHAR wszDest[MAX_PATH]; DWORD dwSize = sizeof(wszBuffer), dwType; SERVICE_STATUS_PROCESS Info; UNICODE_STRING SidString; NTSTATUS Status; ULONG Index = 0; SC_HANDLE hSCManager, hService; // // FIXME: Isn't it possible to *JUST* impersonate the current user // *AND* open its HKCU?? // /* Get SID of current user */ Status = NtQueryInformationToken((HANDLE)lpParameter, TokenUser, TokenUserBuffer, sizeof(TokenUserBuffer), &Length); if (!NT_SUCCESS(Status)) { ERR("NtQueryInformationToken failed: %x!\n", Status); return 0; } /* Convert SID to string */ RtlInitEmptyUnicodeString(&SidString, wszBuffer, sizeof(wszBuffer)); Status = RtlConvertSidToUnicodeString(&SidString, pTokenUser->User.Sid, FALSE); if (!NT_SUCCESS(Status)) { ERR("RtlConvertSidToUnicodeString failed: %x!\n", Status); return 0; } /* Build path to logon sound registry key. Note: We can't use HKCU here, because Winlogon is owned by SYSTEM user */ if (FAILED(StringCbCopyW(wszBuffer + SidString.Length/sizeof(WCHAR), sizeof(wszBuffer) - SidString.Length, L"\\AppEvents\\Schemes\\Apps\\.Default\\WindowsLogon\\.Current"))) { /* SID is too long. Should not happen. */ ERR("StringCbCopyW failed!\n"); return 0; } /* Open registry key and query sound path */ if (RegOpenKeyExW(HKEY_USERS, wszBuffer, 0, KEY_READ, &hKey) != ERROR_SUCCESS) { ERR("RegOpenKeyExW(%ls) failed!\n", wszBuffer); return 0; } if (RegQueryValueExW(hKey, NULL, NULL, &dwType, (LPBYTE)wszBuffer, &dwSize) != ERROR_SUCCESS || (dwType != REG_SZ && dwType != REG_EXPAND_SZ)) { ERR("RegQueryValueExW failed!\n"); RegCloseKey(hKey); return 0; } RegCloseKey(hKey); if (!wszBuffer[0]) { /* No sound has been set */ ERR("No sound has been set\n"); return 0; } /* Expand environment variables */ if (!ExpandEnvironmentStringsW(wszBuffer, wszDest, MAX_PATH)) { ERR("ExpandEnvironmentStringsW failed!\n"); return 0; } /* Open the service manager */ hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (!hSCManager) { ERR("OpenSCManager failed (%x)\n", GetLastError()); return 0; } /* Open the wdmaud service */ hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ); if (!hService) { /* The service is not installed */ TRACE("Failed to open wdmaud service (%x)\n", GetLastError()); CloseServiceHandle(hSCManager); return 0; } /* Wait for wdmaud to start */ do { if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&Info, sizeof(SERVICE_STATUS_PROCESS), &dwSize)) { TRACE("QueryServiceStatusEx failed (%x)\n", GetLastError()); break; } if (Info.dwCurrentState == SERVICE_RUNNING) break; Sleep(1000); } while (Index++ < 20); CloseServiceHandle(hService); CloseServiceHandle(hSCManager); /* If wdmaud is not running exit */ if (Info.dwCurrentState != SERVICE_RUNNING) { WARN("wdmaud has not started!\n"); return 0; } /* Sound subsystem is running. Play logon sound. */ TRACE("Playing logon sound: %ls\n", wszDest); PlaySoundRoutine(wszDest, TRUE, SND_FILENAME); return 0; }
/** * Waits for a service to enter a stopped state. * This function does not stop the service, it just blocks until the service * is stopped. * * @param serviceName The service to wait for. * @param maxWaitSeconds The maximum number of seconds to wait * @return state of the service after a timeout or when stopped. * A value of 255 is returned for an error. Typical values are: * SERVICE_STOPPED 0x00000001 * SERVICE_START_PENDING 0x00000002 * SERVICE_STOP_PENDING 0x00000003 * SERVICE_RUNNING 0x00000004 * SERVICE_CONTINUE_PENDING 0x00000005 * SERVICE_PAUSE_PENDING 0x00000006 * SERVICE_PAUSED 0x00000007 * last status not set 0x000000CF * Could no query status 0x000000DF * Could not open service, access denied 0x000000EB * Could not open service, invalid handle 0x000000EC * Could not open service, invalid name 0x000000ED * Could not open service, does not exist 0x000000EE * Could not open service, other error 0x000000EF * Could not open SCM, access denied 0x000000FD * Could not open SCM, database does not exist 0x000000FE; * Could not open SCM, other error 0x000000FF; * Note: The strange choice of error codes above SERVICE_PAUSED are chosen * in case Windows comes out with other service stats higher than 7, they * would likely call it 8 and above. JS code that uses this in TestAUSHelper * only handles values up to 255 so that's why we don't use GetLastError * directly. */ DWORD WaitForServiceStop(LPCWSTR serviceName, DWORD maxWaitSeconds) { // 0x000000CF is defined above to be not set DWORD lastServiceState = 0x000000CF; // Get a handle to the SCM database. SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE); if (!serviceManager) { DWORD lastError = GetLastError(); switch(lastError) { case ERROR_ACCESS_DENIED: return 0x000000FD; case ERROR_DATABASE_DOES_NOT_EXIST: return 0x000000FE; default: return 0x000000FF; } } // Get a handle to the service. SC_HANDLE service = OpenServiceW(serviceManager, serviceName, SERVICE_QUERY_STATUS); if (!service) { DWORD lastError = GetLastError(); CloseServiceHandle(serviceManager); switch(lastError) { case ERROR_ACCESS_DENIED: return 0x000000EB; case ERROR_INVALID_HANDLE: return 0x000000EC; case ERROR_INVALID_NAME: return 0x000000ED; case ERROR_SERVICE_DOES_NOT_EXIST: return 0x000000EE; default: return 0x000000EF; } } DWORD currentWaitMS = 0; SERVICE_STATUS_PROCESS ssp; ssp.dwCurrentState = lastServiceState; while (currentWaitMS < maxWaitSeconds * 1000) { DWORD bytesNeeded; if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) { DWORD lastError = GetLastError(); switch (lastError) { case ERROR_INVALID_HANDLE: ssp.dwCurrentState = 0x000000D9; break; case ERROR_ACCESS_DENIED: ssp.dwCurrentState = 0x000000DA; break; case ERROR_INSUFFICIENT_BUFFER: ssp.dwCurrentState = 0x000000DB; break; case ERROR_INVALID_PARAMETER: ssp.dwCurrentState = 0x000000DC; break; case ERROR_INVALID_LEVEL: ssp.dwCurrentState = 0x000000DD; break; case ERROR_SHUTDOWN_IN_PROGRESS: ssp.dwCurrentState = 0x000000DE; break; // These 3 errors can occur when the service is not yet stopped but // it is stopping. case ERROR_INVALID_SERVICE_CONTROL: case ERROR_SERVICE_CANNOT_ACCEPT_CTRL: case ERROR_SERVICE_NOT_ACTIVE: currentWaitMS += 50; Sleep(50); continue; default: ssp.dwCurrentState = 0x000000DF; } // We couldn't query the status so just break out break; } // The service is already in use. if (ssp.dwCurrentState == SERVICE_STOPPED) { break; } currentWaitMS += 50; Sleep(50); } lastServiceState = ssp.dwCurrentState; CloseServiceHandle(service); CloseServiceHandle(serviceManager); return lastServiceState; }
/* * DriverSetInfo * * Purpose: * * Sets registry info for selected driver object * */ VOID DriverSetInfo( PROP_OBJECT_INFO *Context, HWND hwndDlg ) { BOOL cond = FALSE, bResult, fGroup, bRet; INT nEndOfList, nEnd, nStart; DWORD i, bytesNeeded, dwServices, dwGroups; LPWSTR lpType; SC_HANDLE SchSCManager; SC_HANDLE schService; LPENUM_SERVICE_STATUS lpDependencies = NULL; LPQUERY_SERVICE_CONFIG psci; LPSERVICE_DESCRIPTION psd; SERVICE_STATUS_PROCESS ssp; ENUM_SERVICE_STATUS ess; WCHAR szBuffer[MAX_PATH + 1]; if (Context == NULL) { ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), TRUE); return; } __try { ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), FALSE); psci = NULL; SchSCManager = NULL; bResult = FALSE; do { SchSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE); if (SchSCManager == NULL) { break; } schService = OpenService(SchSCManager, Context->lpObjectName, SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS); if (schService == NULL) { break; } bytesNeeded = 0; bResult = QueryServiceConfig(schService, NULL, 0, &bytesNeeded); if ((bResult == FALSE) && (bytesNeeded == 0)) { break; } psci = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); if (psci == NULL) { break; } //disable comboboxes EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONGROUP), FALSE); bResult = QueryServiceConfig(schService, psci, bytesNeeded, &bytesNeeded); if (bResult) { //set key name (identical to object name) SetDlgItemText(hwndDlg, IDC_SERVICE_KEYNAME, Context->lpObjectName); //set image path info SetDlgItemText(hwndDlg, IDC_SERVICE_IMAGEPATH, psci->lpBinaryPathName); //set display name SetDlgItemText(hwndDlg, IDC_SERVICE_DISPLAYNAME, psci->lpDisplayName); //set load order group SetDlgItemText(hwndDlg, IDC_SERVICE_LOADORDERGROUP, psci->lpLoadOrderGroup); //Service Type lpType = T_UnknownType; switch (psci->dwServiceType) { case SERVICE_KERNEL_DRIVER: lpType = L"Kernel-Mode Driver"; break; case SERVICE_FILE_SYSTEM_DRIVER: lpType = L"File System Driver"; break; case SERVICE_ADAPTER: lpType = L"Adapter"; break; case SERVICE_RECOGNIZER_DRIVER: lpType = L"File System Recognizer"; break; case SERVICE_WIN32_OWN_PROCESS: lpType = L"Own Process"; break; case SERVICE_WIN32_SHARE_PROCESS: lpType = L"Share Process"; break; case (SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS): lpType = L"Own Process (Interactive)"; SetDlgItemText(hwndDlg, ID_SERVICE_NAME, psci->lpServiceStartName); break; case (SERVICE_WIN32_SHARE_PROCESS | SERVICE_INTERACTIVE_PROCESS): lpType = L"Share Process (Interactive)"; SetDlgItemText(hwndDlg, ID_SERVICE_NAME, psci->lpServiceStartName); break; } SetDlgItemText(hwndDlg, ID_SERVICE_TYPE, lpType); //Start Type lpType = T_UnknownType; switch (psci->dwStartType) { case SERVICE_AUTO_START: lpType = L"Auto"; break; case SERVICE_BOOT_START: lpType = L"Boot"; break; case SERVICE_DEMAND_START: lpType = L"On Demand"; break; case SERVICE_DISABLED: lpType = L"Disabled"; break; case SERVICE_SYSTEM_START: lpType = L"System"; break; } SetDlgItemText(hwndDlg, ID_SERVICE_START, lpType); //Error Control lpType = T_Unknown; switch (psci->dwErrorControl) { case SERVICE_ERROR_CRITICAL: lpType = L"Critical"; break; case SERVICE_ERROR_IGNORE: lpType = L"Ignore"; break; case SERVICE_ERROR_NORMAL: lpType = L"Normal"; break; case SERVICE_ERROR_SEVERE: lpType = L"Severe"; break; } SetDlgItemText(hwndDlg, ID_SERVICE_ERROR, lpType); //dwTagId if (psci->dwTagId) { RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); ultostr(psci->dwTagId, szBuffer); SetDlgItemText(hwndDlg, ID_SERVICE_TAG, szBuffer); } else { //not assigned tag SetDlgItemText(hwndDlg, ID_SERVICE_TAG, L""); } //State RtlSecureZeroMemory(&ssp, sizeof(ssp)); if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(ssp), &bytesNeeded)) { lpType = T_Unknown; switch (ssp.dwCurrentState) { case SERVICE_STOPPED: lpType = L"Stopped"; break; case SERVICE_START_PENDING: lpType = L"Start Pending"; break; case SERVICE_STOP_PENDING: lpType = L"Stop Pending"; break; case SERVICE_RUNNING: lpType = L"Running"; break; case SERVICE_CONTINUE_PENDING: lpType = L"Continue Pending"; break; case SERVICE_PAUSE_PENDING: lpType = L"Pause Pending"; break; case SERVICE_PAUSED: lpType = L"Paused"; break; } SetDlgItemText(hwndDlg, ID_SERVICE_CURRENT, lpType); } else { SetDlgItemText(hwndDlg, ID_SERVICE_CURRENT, T_CannotQuery); } //Service Description bRet = FALSE; SetDlgItemText(hwndDlg, ID_SERVICE_DESCRIPTION, L""); bytesNeeded = 0x1000; psd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); if (psd) { bRet = QueryServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)psd, bytesNeeded, &bytesNeeded); if ((bRet == FALSE) && (bytesNeeded != 0)) { HeapFree(GetProcessHeap(), 0, psd); psd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); } if (psd) { //set description or hide window bRet = QueryServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)psd, bytesNeeded, &bytesNeeded); if (bRet) { SetDlgItemText(hwndDlg, IDC_SERVICE_DESCRIPTION, psd->lpDescription); } HeapFree(GetProcessHeap(), 0, psd); } } if (bRet == FALSE) { //not enough memory, hide description window ShowWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DESCRIPTION), SW_HIDE); } //Service Dependencies if (psci->lpDependencies) { //first list DependsOnService, DependsOnGroup nEndOfList = 0; nEnd = 0; nStart = 0; dwGroups = 0; dwServices = 0; //calc total number of symbols while ((psci->lpDependencies[nEndOfList] != L'\0') || (psci->lpDependencies[nEndOfList + 1] != L'\0')) nEndOfList++; if (nEndOfList > 0) { SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONGROUP, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); //iterate through MULTI_SZ string do { while (psci->lpDependencies[nEnd] != L'\0') { nEnd++; } RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); //maximum bytes that can be copied is sizeof(szBuffer) _strncpy(szBuffer, sizeof(szBuffer), &psci->lpDependencies[nStart], nEnd); //check if dependency is a group (has "+" before name) fGroup = (szBuffer[0] == SC_GROUP_IDENTIFIER); if (fGroup) { SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONGROUP, CB_ADDSTRING, (WPARAM)0, (LPARAM)&szBuffer[1]); dwGroups++; } else { SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE, CB_ADDSTRING, (WPARAM)0, (LPARAM)&szBuffer); dwServices++; } nEnd++; nStart = nEnd; } while (nEnd < nEndOfList); //group present, enable combobox if (dwGroups > 0) { EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONGROUP), TRUE); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONGROUP, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); } //service present, enable combobox if (dwServices > 0) { EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE), TRUE); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); } } //if (nEndOfList > 0) //second list services that depends on this service SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); dwServices = 0; bytesNeeded = 1024; bRet = FALSE; //avoid SCM unexpected behaviour by using preallocated buffer lpDependencies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); if (lpDependencies) { bRet = EnumDependentServices(schService, SERVICE_STATE_ALL, lpDependencies, bytesNeeded, &bytesNeeded, &dwServices); if (bRet && (GetLastError() == ERROR_MORE_DATA)) { //more memory needed for enum HeapFree(GetProcessHeap(), 0, lpDependencies); dwServices = 0; lpDependencies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded); if (lpDependencies) { bRet = EnumDependentServices(schService, SERVICE_STATE_ALL, lpDependencies, bytesNeeded, &bytesNeeded, &dwServices); } } //list dependents if (bRet && dwServices) { for (i = 0; i < dwServices; i++) { ess = *(lpDependencies + i); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES, CB_ADDSTRING, (WPARAM)0, (LPARAM)ess.lpServiceName); } //enable combobox and set current selection to the first item EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES), TRUE); SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); } HeapFree(GetProcessHeap(), 0, lpDependencies); } } //if (psi->lpDependencies) } //bResult != FALSE CloseServiceHandle(schService); } while (cond); if (psci != NULL) { HeapFree(GetProcessHeap(), 0, psci); } if (SchSCManager) { CloseServiceHandle(SchSCManager); } if (bResult == FALSE) { EnumChildWindows(hwndDlg, DriverShowChildWindows, SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), SW_SHOW); } else { SetFocus(GetDlgItem(hwndDlg, ID_SERVICE_JUMPTOKEY)); } } __except (exceptFilter(GetExceptionCode(), GetExceptionInformation())) { EnumChildWindows(hwndDlg, DriverShowChildWindows, SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), SW_SHOW); return; } }
static BOOL DoStartService(PMAIN_WND_INFO Info, HWND hProgress, LPWSTR lpStartParams) { SC_HANDLE hSCManager; SC_HANDLE hService; SERVICE_STATUS_PROCESS ServiceStatus; DWORD BytesNeeded = 0; DWORD dwStartTickCount; DWORD dwOldCheckPoint; DWORD dwWaitTime; DWORD dwMaxWait; BOOL bRet = FALSE; BOOL bWhiteSpace = TRUE; LPWSTR lpChar; DWORD dwArgsCount = 0; LPCWSTR *lpArgsVector = NULL; if (lpStartParams != NULL) { /* Count the number of arguments */ lpChar = lpStartParams; while (*lpChar != 0) { if (iswspace(*lpChar)) { bWhiteSpace = TRUE; } else { if (bWhiteSpace == TRUE) { dwArgsCount++; bWhiteSpace = FALSE; } } lpChar++; } /* Allocate the arguments vector and add one for the service name */ lpArgsVector = LocalAlloc(LMEM_FIXED, (dwArgsCount + 1) * sizeof(LPCWSTR)); if (!lpArgsVector) return FALSE; /* Make the service name the first argument */ lpArgsVector[0] = Info->pCurrentService->lpServiceName; /* Fill the arguments vector */ dwArgsCount = 1; bWhiteSpace = TRUE; lpChar = lpStartParams; while (*lpChar != 0) { if (iswspace(*lpChar)) { *lpChar = 0; bWhiteSpace = TRUE; } else { if (bWhiteSpace == TRUE) { lpArgsVector[dwArgsCount] = lpChar; dwArgsCount++; bWhiteSpace = FALSE; } } lpChar++; } } hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager) { hService = OpenService(hSCManager, Info->pCurrentService->lpServiceName, SERVICE_START | SERVICE_QUERY_STATUS); if (hService) { if (hProgress) { /* Increment the progress bar */ IncrementProgressBar(hProgress, DEFAULT_STEP); } /* Start the service */ bRet = StartService(hService, dwArgsCount, lpArgsVector); if (!bRet && GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) { /* If it's already running, just return TRUE */ bRet = TRUE; } else if (bRet) { bRet = FALSE; /* Get the service status to check if it's running */ if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus, sizeof(SERVICE_STATUS_PROCESS), &BytesNeeded)) { /* We don't want to wait for more than 30 seconds */ dwMaxWait = 30000; dwStartTickCount = GetTickCount(); /* Loop until it's running */ while (ServiceStatus.dwCurrentState != SERVICE_RUNNING) { dwOldCheckPoint = ServiceStatus.dwCheckPoint; dwWaitTime = ServiceStatus.dwWaitHint / 10; /* Get the latest status info */ if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus, sizeof(SERVICE_STATUS_PROCESS), &BytesNeeded)) { /* Something went wrong... */ break; } /* Is the service making progress? */ if (ServiceStatus.dwCheckPoint > dwOldCheckPoint) { /* It is, get the latest tickcount to reset the max wait time */ dwStartTickCount = GetTickCount(); dwOldCheckPoint = ServiceStatus.dwCheckPoint; IncrementProgressBar(hProgress, DEFAULT_STEP); } else { /* It's not, make sure we haven't exceeded our wait time */ if (GetTickCount() >= dwStartTickCount + dwMaxWait) { /* We have, give up */ break; } } /* Adjust the wait hint times */ if (dwWaitTime < 200) dwWaitTime = 200; else if (dwWaitTime > 10000) dwWaitTime = 10000; /* Wait before trying again */ Sleep(dwWaitTime); } } if (ServiceStatus.dwCurrentState == SERVICE_RUNNING) { bRet = TRUE; } } CloseServiceHandle(hService); } CloseServiceHandle(hSCManager); } if (lpArgsVector) LocalFree((LPVOID)lpArgsVector); return bRet; }
// // FUNCTION: SvcQueryConfig // // PURPOSE: Query the service status and trigger-start configuration // // PARAMETERS: // none // // RETURN VALUE: // none // // COMMENTS: // This function does not require administrative priviledge // void SvcQueryConfig() { // Open the local default service control manager database SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (!schSCManager) { wprintf(L"OpenSCManager failed w/err 0x%08lx\n", GetLastError()); return; } // Try to open the service to query its status and config SC_HANDLE schService = OpenService(schSCManager, SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); if (NULL != schService) { wprintf(L"%s was installed.\n", SERVICE_DISPLAY_NAME); DWORD cbBytesNeeded; // // Query the status of the service // SERVICE_STATUS_PROCESS ssp; if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(ssp), &cbBytesNeeded)) { wprintf(L"Service status: "); switch (ssp.dwCurrentState) { case SERVICE_STOPPED: wprintf(L"Stopped\n"); break; case SERVICE_RUNNING: wprintf(L"Running\n"); break; case SERVICE_PAUSED: wprintf(L"Paused\n"); break; case SERVICE_START_PENDING: case SERVICE_STOP_PENDING: case SERVICE_CONTINUE_PENDING: case SERVICE_PAUSE_PENDING: wprintf(L"Pending\n"); break; } } else { wprintf(L"QueryServiceStatusEx failed w/err 0x%08lx\n", GetLastError()); } // // Query the trigger-start configuration of the service // BOOL fIsTriggerStart; if (GetServiceTriggerInfo(schService, &fIsTriggerStart)) { wprintf(L"Is trigger-start: %s", fIsTriggerStart ? L"Yes" : L"No"); } else { wprintf(L"GetServiceTriggerInfo failed w/err 0x%08lx\n", GetLastError()); } CloseServiceHandle(schService); } else { DWORD dwErr = GetLastError(); if (dwErr == ERROR_SERVICE_DOES_NOT_EXIST) { wprintf(L"%s was not installed.\n", SERVICE_DISPLAY_NAME); } else { wprintf(L"OpenService failed w/err 0x%08lx\n", dwErr); } } CloseServiceHandle(schSCManager); }
int _cdecl main(int argc, char *argv[]) { SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; SERVICE_STATUS_PROCESS serviceInfo; DWORD bytesNeeded; HANDLE hDevice = NULL; BOOL bResult; DWORD result; ULONG threadId; HANDLE thread = NULL; LOG_CONTEXT context; INT inputChar; // // Initialize handle in case of error // context.ShutDown = NULL; context.VerbosityFlags = 0; // // Start the kernel mode driver through the service manager // hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS) ; if (NULL == hSCManager) { result = GetLastError(); printf("ERROR opening Service Manager...\n"); DisplayError( result ); goto Main_Continue; } hService = OpenService( hSCManager, FILESPY_SERVICE_NAME, FILESPY_SERVICE_ACCESS); if (NULL == hService) { result = GetLastError(); printf("ERROR opening FileSpy Service...\n"); DisplayError( result ); goto Main_Continue; } if (!QueryServiceStatusEx( hService, SC_STATUS_PROCESS_INFO, (UCHAR *)&serviceInfo, sizeof(serviceInfo), &bytesNeeded)) { result = GetLastError(); printf("ERROR querrying status of FileSpy Service...\n"); DisplayError( result ); goto Main_Continue; } if(serviceInfo.dwCurrentState != SERVICE_RUNNING) { // // Service hasn't been started yet, so try to start service // if (!StartService(hService, 0, NULL)) { result = GetLastError(); printf("ERROR starting FileSpy service...\n"); DisplayError( result ); goto Main_Continue; } } Main_Continue: printf("Hit [Enter] to begin command mode...\n"); // // Open the device that is used to talk to FileSpy. // printf("FileSpy: Opening device...\n"); hDevice = CreateFile( FILESPY_W32_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDevice == INVALID_HANDLE_VALUE) { result = GetLastError(); printf("ERROR opening device...\n"); DisplayError( result ); goto Main_Exit; } // // Initialize the fields of the LOG_CONTEXT. // context.Device = hDevice; context.ShutDown = CreateSemaphore( NULL, 0, 1, L"FileSpy shutdown"); if (context.ShutDown == NULL) { // // Insufficient memory for this semaphore, so shutdown. // printf( "ERROR insufficient memory\n" ); goto Main_Exit; } context.CleaningUp = FALSE; context.LogToScreen = context.NextLogToScreen = TRUE; context.LogToFile = FALSE; context.OutputFile = NULL; // // Check the valid parameters for startup // if (argc > 1) { if (InterpretCommand(argc - 1, &(argv[1]), &context) == USAGE_ERROR) { goto Main_Exit; } } // // Propagate the /s switch to the variable that the logging // thread checks. // context.LogToScreen = context.NextLogToScreen; // // Check to see what devices we are attached to from // previous runs of this program. // bResult = ListDevices(&context); if (!bResult) { result = GetLastError(); printf("ERROR listing devices...\n"); DisplayError( result ); } // // Create the thread to read the log records that are gathered // by filespy.sys. // printf("FileSpy: Creating logging thread...\n"); thread = CreateThread( NULL, 0, RetrieveLogRecords, (LPVOID)&context, 0, &threadId); if (!thread) { result = GetLastError(); printf("ERROR creating logging thread...\n"); DisplayError( result ); goto Main_Exit; } while (inputChar = getchar()) { CHAR commandLine[81]; INT parmCount, count, ch; CHAR **parms; BOOLEAN newParm; DWORD returnValue = SUCCESS; if (inputChar == '\n') { // // Start command interpreter. First we must turn off logging // to screen if we are. Also, remember the state of logging // to the screen, so that we can reinstate that when command // interpreter is finished. // context.NextLogToScreen = context.LogToScreen; context.LogToScreen = FALSE; while (returnValue != EXIT_INTERPRETER) { // // Print prompt // printf(">"); // // Read in next line, keeping track of the number of parameters // as you go // parmCount = 1; for (count = 0; (count < 80) && ((ch = getchar())!= '\n'); count++) { commandLine[count] = (CHAR)ch; if (ch == ' ') { parmCount ++; } } commandLine[count] = '\0'; parms = (CHAR **)malloc(parmCount * sizeof(CHAR *)); parmCount = 0; newParm = TRUE; for (count = 0; commandLine[count] != '\0'; count++) { if (newParm) { parms[parmCount] = &(commandLine[count]); parmCount ++; } if (commandLine[count] == ' ' ) { newParm = TRUE; } else { newParm = FALSE; } } // // We've got our parameter count and parameter list, so // send it off to be interpreted. // returnValue = InterpretCommand(parmCount, parms, &context); free(parms); if (returnValue == EXIT_PROGRAM) { // Time to stop the program goto Main_Cleanup; } } // Set LogToScreen appropriately based on any commands seen context.LogToScreen = context.NextLogToScreen; if (context.LogToScreen) { printf("Should be logging to screen...\n"); } } } Main_Cleanup: // // Clean up the threads, then fall through to Main_Exit // printf("FileSpy: Cleaning up...\n"); // // Set the Cleaning up flag to TRUE to notify other threads // that we are cleaning up // context.CleaningUp = TRUE; // // Wait for everyone to shut down // WaitForSingleObject(context.ShutDown, INFINITE); if (context.LogToFile) { fclose(context.OutputFile); } Main_Exit: // // Clean up the data that is always around and exit // if(context.ShutDown) { CloseHandle(context.ShutDown); } if (thread) { CloseHandle(thread); } if(hSCManager) { CloseServiceHandle(hSCManager); } if(hService) { CloseServiceHandle(hService); } if (hDevice) { CloseHandle(hDevice); } printf("FileSpy: All done\n"); return 0; }