void CService::ServiceCtrlHandler(DWORD controlCode) { switch(controlCode) { case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_SHUTDOWN: m_Status = SERVICE_STOP_PENDING; SendStatusToSCM( m_Status, NO_ERROR, 0, 1, 5000 ); StopService(); return; case SERVICE_CONTROL_INTERROGATE: break; default: break; } SendStatusToSCM(m_Status, NO_ERROR, 0, 0, 0); }
void CService::ServiceCtrlHandler(DWORD controlCode) { DWORD currentState = 0; switch(controlCode) { case SERVICE_CONTROL_STOP: currentState = SERVICE_STOP_PENDING; SendStatusToSCM( SERVICE_STOP_PENDING, NO_ERROR, 0, 1, 5000 ); StopService(); return; case SERVICE_CONTROL_PAUSE: if (m_bRunningService && !m_bPauseService) { SendStatusToSCM( SERVICE_PAUSE_PENDING, NO_ERROR, 0, 1, 1000 ); PauseService(); currentState = SERVICE_PAUSED; } break; case SERVICE_CONTROL_CONTINUE: if (m_bRunningService && m_bPauseService) { SendStatusToSCM( SERVICE_CONTINUE_PENDING, NO_ERROR, 0, 1, 1000 ); ResumeService(); currentState = SERVICE_RUNNING; } break; case SERVICE_CONTROL_INTERROGATE: break; case SERVICE_CONTROL_SHUTDOWN: return; default: break; } SendStatusToSCM(currentState, NO_ERROR, 0, 0, 0); }
void CService::ServiceMain(DWORD argc, LPTSTR *argv) { BOOL res; if (!m_StatusHandle) { terminate(GetLastError()); return; } res = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 1, 5000); if (!res) { terminate(GetLastError()); return; } m_pDev = new CDevice(); if (!m_pDev || !m_pDev->Init(m_StatusHandle) || !m_pDev->Start()) { terminate(GetLastError()); return; } DEV_BROADCAST_DEVICEINTERFACE filter; ZeroMemory(&filter, sizeof(filter)); filter.dbcc_size = sizeof(filter); filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; filter.dbcc_classguid = GUID_DEVINTERFACE_BALLOON; m_hDevNotify = RegisterDeviceNotification(m_StatusHandle, &filter, DEVICE_NOTIFY_SERVICE_HANDLE); if (!m_hDevNotify) { terminate(GetLastError()); return; } m_evTerminate = CreateEvent(NULL, TRUE, FALSE, NULL); if (!m_evTerminate) { terminate(GetLastError()); return; } res = InitService(); if (!res) { terminate(GetLastError()); return; } res = SendStatusToSCM(SERVICE_RUNNING, NO_ERROR, 0 , 0, 0); if (!res) { terminate(GetLastError()); return; } WaitForSingleObject(m_evTerminate, INFINITE); terminate(0); }
void CService::ServiceMain(DWORD argc, LPTSTR *argv) { BOOL res; if (!m_StatusHandle) { terminate(GetLastError()); return; } res = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 1, 5000); if (!res) { terminate(GetLastError()); return; } m_pDev = new CDevice(); if (!m_pDev || !m_pDev->Init(this) || !m_pDev->Start()) { terminate(GetLastError()); return; } m_hDevNotify = RegisterDeviceInterfaceNotification(); if (m_hDevNotify == NULL) { terminate(GetLastError()); return; } m_evTerminate = CreateEvent(NULL, TRUE, FALSE, NULL); if (!m_evTerminate) { terminate(GetLastError()); return; } res = InitService(); if (!res) { terminate(GetLastError()); return; } res = SendStatusToSCM(SERVICE_RUNNING, NO_ERROR, 0 , 0, 0); if (!res) { terminate(GetLastError()); return; } WaitForSingleObject(m_evTerminate, INFINITE); terminate(0); }
void CService::GetStatus(SC_HANDLE service) { SERVICE_STATUS status; DWORD CurrentState; QueryServiceStatus(service, &status); switch(status.dwCurrentState) { case SERVICE_RUNNING: CurrentState = SERVICE_RUNNING; printf("Service RUNNING.\n"); break; case SERVICE_STOPPED: CurrentState = SERVICE_STOPPED; printf("Service STOPPED.\n"); break; case SERVICE_CONTINUE_PENDING: CurrentState = SERVICE_CONTINUE_PENDING; printf("Service is resuming...\n"); break; case SERVICE_START_PENDING: CurrentState = SERVICE_START_PENDING; printf("Service is starting...\n"); break; case SERVICE_STOP_PENDING: CurrentState = SERVICE_STOP_PENDING; printf("Service is stopping...\n"); break; default: break; } SendStatusToSCM(CurrentState, NO_ERROR, 0, 0, 0); }
void CService::terminate(DWORD error) { UnregisterNotification(m_hDevNotify); if (m_evTerminate) { CloseHandle(m_evTerminate); m_evTerminate = NULL; } if (m_StatusHandle) { SendStatusToSCM(SERVICE_STOPPED, error, 0, 0, 0); } delete m_pDev; }
// Handle an error from ServiceMain by cleaning up // and telling SCM that the service didn't start. VOID terminate(DWORD error) { // if terminateEvent has been created, close it. if (terminateEvent) CloseHandle(terminateEvent); // Send a message to the scm to tell about // stopage if (serviceStatusHandle) SendStatusToSCM(SERVICE_STOPPED, error, 0, 0, 0); // If the thread has started kill it off if (threadHandle) CloseHandle(threadHandle); // Do not need to close serviceStatusHandle }
void CService::terminate(DWORD error) { if (m_evTerminate) { CloseHandle(m_evTerminate); } if (m_evWakeUp) { CloseHandle(m_evWakeUp); } DeleteCriticalSection(&m_scWrite); if (m_StatusHandle) { SendStatusToSCM(SERVICE_STOPPED, error, 0, 0, 0); } if (m_thHandle) { CloseHandle(m_thHandle); } delete m_pMemStat; delete m_pDev; }
void CService::ServiceMain(DWORD argc, LPTSTR *argv) { BOOL res; if (!m_StatusHandle) { terminate(GetLastError()); return; } m_pMemStat = new CMemStat; if (!m_pMemStat || !m_pMemStat->Init()) { terminate(GetLastError()); return; } m_pDev = new CDevice; if (!m_pDev || !m_pDev->Init()) { terminate(GetLastError()); return; } res = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 1, 5000); if (!res) { terminate(GetLastError()); return; } m_evTerminate = CreateEvent(NULL, TRUE, FALSE, NULL); if (!m_evTerminate) { terminate(GetLastError()); return; } m_evWakeUp = CreateEvent(NULL, TRUE, FALSE, NULL); if (!m_evWakeUp) { terminate(GetLastError()); return; } InitializeCriticalSection(&m_scWrite); res = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 2, 1000); if (!res) { terminate(GetLastError()); return; } res = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 3, 5000); if (!res) { terminate(GetLastError()); return; } res = InitService(); if (!res) { terminate(GetLastError()); return; } res = SendStatusToSCM(SERVICE_RUNNING, NO_ERROR, 0 , 0, 0); if (!res) { terminate(GetLastError()); return; } WaitForSingleObject(m_evTerminate, INFINITE); terminate(0); }
// ServiceMain is called when the SCM wants to // start the service. When it returns, the service // has stopped. It therefore waits on an event // just before the end of the function, and // that event gets set when it is time to stop. // It also returns on any error because the // service cannot start if there is an eror. VOID ServiceMain(DWORD argc, LPTSTR *argv) { BOOL success; // immediately call Registration function serviceStatusHandle = RegisterServiceCtrlHandler( SERVICE_NAME, (LPHANDLER_FUNCTION) ServiceCtrlHandler); if (!serviceStatusHandle) { terminate(GetLastError()); return; } // Notify SCM of progress success = SendStatusToSCM( SERVICE_START_PENDING, NO_ERROR, 0, 1, 5000); if (!success) { terminate(GetLastError()); return; } // create the termination event terminateEvent = CreateEvent (0, TRUE, FALSE, 0); if (!terminateEvent) { terminate(GetLastError()); return; } // Notify SCM of progress success = SendStatusToSCM( SERVICE_START_PENDING, NO_ERROR, 0, 2, 1000); if (!success) { terminate(GetLastError()); return; } // Notify SCM of progress success = SendStatusToSCM( SERVICE_START_PENDING, NO_ERROR, 0, 3, 5000); if (!success) { terminate(GetLastError()); return; } // Start the service itself success = InitService(); if (!success) { terminate(GetLastError()); return; } // The service is now running. // Notify SCM of progress success = SendStatusToSCM( SERVICE_RUNNING, NO_ERROR, 0, 0, 0); if (!success) { terminate(GetLastError()); return; } // Wait for stop signal, and then terminate WaitForSingleObject (terminateEvent, INFINITE); terminate(0); }
// Dispatches events received from the service // control manager VOID ServiceCtrlHandler (DWORD controlCode) { DWORD currentState = 0; BOOL success; switch(controlCode) { // There is no START option because // ServiceMain gets called on a start // Stop the service case SERVICE_CONTROL_STOP: currentState = SERVICE_STOP_PENDING; // Tell the SCM what's happening success = SendStatusToSCM( SERVICE_STOP_PENDING, NO_ERROR, 0, 1, 5000); // Not much to do if not successful // Stop the service StopService(); return; // Pause the service case SERVICE_CONTROL_PAUSE: if (runningService && !pauseService) { // Tell the SCM what's happening success = SendStatusToSCM( SERVICE_PAUSE_PENDING, NO_ERROR, 0, 1, 1000); PauseService(); currentState = SERVICE_PAUSED; } break; // Resume from a pause case SERVICE_CONTROL_CONTINUE: if (runningService && pauseService) { // Tell the SCM what's happening success = SendStatusToSCM( SERVICE_CONTINUE_PENDING, NO_ERROR, 0, 1, 1000); ResumeService(); currentState = SERVICE_RUNNING; } break; // Update current status case SERVICE_CONTROL_INTERROGATE: // it will fall to bottom and send status break; // Do nothing in a shutdown. Could do cleanup // here but it must be very quick. case SERVICE_CONTROL_SHUTDOWN: // Do nothing on shutdown return; default: break; } SendStatusToSCM(currentState, NO_ERROR, 0, 0, 0); }