📄 service.c
字号:
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A// PARTICULAR PURPOSE.//// Copyright (C) 1993-1997 Microsoft Corporation. All Rights Reserved.//// MODULE: service.c//// PURPOSE: Implements functions required by all services// windows.//// FUNCTIONS:// main(int argc, char **argv);// service_ctrl(DWORD dwCtrlCode);// service_main(DWORD dwArgc, LPTSTR *lpszArgv);// CmdInstallService();// CmdRemoveService();// ControlHandler ( DWORD dwCtrlType );// GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );//// COMMENTS://// AUTHOR: Craig Link - Microsoft Developer Support///* * modified Mar.07, 2002 by Feng Qin <fqin@ncsa.uiuc.edu> * Mar.15, 2002 * * removed some functions we don't use at all * add code to start the service immediately after service is installed * * $Id: service.c,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $ */#ifdef WIN32#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <process.h>#include <tchar.h>#include "service.h"// internal variablesSERVICE_STATUS ssStatus; // current status of the serviceSERVICE_STATUS_HANDLE sshStatusHandle;DWORD dwErr = 0;TCHAR szErr[256];//// FUNCTION: service_main//// PURPOSE: To perform actual initialization of the service//// PARAMETERS:// dwArgc - number of command line arguments// lpszArgv - array of command line arguments//// RETURN VALUE:// none//// COMMENTS:// This routine performs the service initialization and then calls// the user defined ServiceStart() routine to perform majority// of the work.//void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv) { // register our service control handler: // sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl); if ( !sshStatusHandle ) goto clean; // SERVICE_STATUS members that don't change in example // ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssStatus.dwServiceSpecificExitCode = 0; // report the status to the service control manager. // if ( !ReportStatusToSCMgr( SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000) ) // wait hint goto clean; ServiceStart( dwArgc, lpszArgv ); clean: // try to report the stopped status to the service control manager. // if ( sshStatusHandle ) (VOID)ReportStatusToSCMgr( SERVICE_STOPPED, dwErr, 0); return;}//// FUNCTION: service_ctrl//// PURPOSE: This function is called by the SCM whenever// ControlService() is called on this service.//// PARAMETERS:// dwCtrlCode - type of control requested//// RETURN VALUE:// none//// COMMENTS://VOID WINAPI service_ctrl(DWORD dwCtrlCode) { // Handle the requested control code. // switch ( dwCtrlCode ) { // Stop the service. // // SERVICE_STOP_PENDING should be reported before // setting the Stop Event - hServerStopEvent - in // ServiceStop(). This avoids a race condition // which may result in a 1053 - The Service did not respond... // error. case SERVICE_CONTROL_STOP: ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0); ServiceStop(); return; // Update the service status. // case SERVICE_CONTROL_INTERROGATE: break; // invalid control code // default: break; } ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);// ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);}//// FUNCTION: ReportStatusToSCMgr()//// PURPOSE: Sets the current status of the service and// reports it to the Service Control Manager//// PARAMETERS:// dwCurrentState - the state of the service// dwWin32ExitCode - error code to report// dwWaitHint - worst case estimate to next checkpoint//// RETURN VALUE:// TRUE - success// FALSE - failure//// COMMENTS://BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) { static DWORD dwCheckPoint = 1; BOOL fResult = TRUE; if ( dwCurrentState == SERVICE_START_PENDING ) ssStatus.dwControlsAccepted = 0; else ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; ssStatus.dwCurrentState = dwCurrentState; ssStatus.dwWin32ExitCode = dwWin32ExitCode; ssStatus.dwWaitHint = dwWaitHint; if ( ( dwCurrentState == SERVICE_RUNNING ) || ( dwCurrentState == SERVICE_STOPPED ) ) ssStatus.dwCheckPoint = 0; else ssStatus.dwCheckPoint = dwCheckPoint++; // Report the status of the service to the service control manager. // if ( !(fResult = SetServiceStatus( sshStatusHandle, &ssStatus)) ) { AddToMessageLog(TEXT("SetServiceStatus")); } return fResult;}//// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)//// PURPOSE: Allows any thread to log an error message//// PARAMETERS:// lpszMsg - text for message//// RETURN VALUE:// none//// COMMENTS://VOID AddToMessageLog(LPTSTR lpszMsg) { TCHAR szMsg[256]; HANDLE hEventSource; LPTSTR lpszStrings[2]; dwErr = GetLastError(); // Use event logging to log the error. // hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME)); printf(lpszMsg); _stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr); lpszStrings[0] = szMsg; lpszStrings[1] = lpszMsg; if ( hEventSource != NULL ) { ReportEvent(hEventSource, // handle of event source EVENTLOG_ERROR_TYPE, // event type 0, // event category 0, // event ID NULL, // current user's SID 2, // strings in lpszStrings 0, // no bytes of raw data lpszStrings, // array of error strings NULL); // no raw data (VOID) DeregisterEventSource(hEventSource); }}/////////////////////////////////////////////////////////////////////// The following code handles service installation and removal////// FUNCTION: CmdInstallService()//// PURPOSE: Installs the service and Starts it//// PARAMETERS:// argc: number of arguments// argv: all of the arguments including the program's name//// RETURN VALUE:// none//// COMMENTS://void CmdInstallService(int argc, char **argv) { SC_HANDLE schService; SC_HANDLE schSCManager; TCHAR szPath[512]; if ( GetModuleFileName( NULL, szPath, 512 ) == 0 ) { _tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256)); return; } schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if ( schSCManager ) { schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS); if ( !schService ) { schService = CreateService( schSCManager, // SCManager database TEXT(SZSERVICENAME), // name of service TEXT(SZSERVICEDISPLAYNAME), // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_DEMAND_START, // start type SERVICE_ERROR_NORMAL, // error control type szPath, // service's binary NULL, // no load ordering group NULL, // no tag identifier TEXT(SZDEPENDENCIES), // dependencies NULL, // LocalSystem account NULL); // no password } else { _tprintf(TEXT("%s already installed.\n"), TEXT(SZSERVICEDISPLAYNAME) ); } if ( schService ) { if ( QueryServiceStatus( schService, &ssStatus ) ) { int rc; if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) { rc = StartService(schService, argc-1, argv+1); } if ( rc != 0 ) _tprintf(TEXT("%s started.\n"), TEXT(SZSERVICEDISPLAYNAME) ); } CloseServiceHandle(schService); } else { _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256)); } CloseServiceHandle(schSCManager); } else _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));}//// FUNCTION: CmdRemoveService()//// PURPOSE: Stops and removes the service//// PARAMETERS:// none//// RETURN VALUE:// TRUE: service exists and is removed// FALSE: service doesn't exist//// COMMENTS://BOOL CmdRemoveService() { BOOL isExist = FALSE; SC_HANDLE schService; SC_HANDLE schSCManager; schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if ( schSCManager ) { schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS); if ( schService ) { isExist = TRUE; // try to stop the service if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) ) { _tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME)); Sleep( 1000 ); while ( QueryServiceStatus( schService, &ssStatus ) ) { if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING ) { _tprintf(TEXT(".")); Sleep( 1000 ); } else break; } if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) _tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) ); else _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) ); } // now remove the service if ( DeleteService(schService) ) _tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) ); else _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256)); CloseServiceHandle(schService); } CloseServiceHandle(schSCManager); } else _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256)); return isExist;}//// FUNCTION: CmdStartService()//// PURPOSE: Start service if it exists//// PARAMETERS:// argc: number of arguments// argv: arguments including program's name//// RETURN VALUE:// TRUE: service exists and is started// FALSE: service doesn't exist//// COMMENTS://BOOL CmdStartService(int argc, char **argv) { BOOL isExist = FALSE; SC_HANDLE schService; SC_HANDLE schSCManager; schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if ( schSCManager ) { schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS); if ( schService ) { isExist = TRUE; if ( QueryServiceStatus( schService, &ssStatus ) ) { int rc; if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) { rc = StartService(schService, argc-1, argv+1); } if ( rc != 0 ) _tprintf(TEXT("%s started.\n"), TEXT(SZSERVICEDISPLAYNAME) ); } CloseServiceHandle(schService); } CloseServiceHandle(schSCManager); } else _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256)); return isExist;}//// FUNCTION: GetLastErrorText//// PURPOSE: copies error message text to string//// PARAMETERS:// lpszBuf - destination buffer// dwSize - size of buffer//// RETURN VALUE:// destination buffer//// COMMENTS://LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize ) { DWORD dwRet; LPTSTR lpszTemp = NULL; dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, GetLastError(), LANG_NEUTRAL, (LPTSTR)&lpszTemp, 0, NULL ); // supplied buffer is not long enough if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) ) lpszBuf[0] = TEXT('\0'); else { lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character _stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() ); } if ( lpszTemp ) LocalFree((HLOCAL) lpszTemp ); return lpszBuf;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -