VC 服务程序的编写
2014-12-27 20:58
302 查看
参考:http://msdn.microsoft.com/en-us/library/windows/desktop/bb540476(v=vs.85).aspx
sample.h
svccontrol.cpp
sample.h
// The following are message definitions. // // Values are 32 bit values laid out as follows: // // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // +---+-+-+-----------------------+-------------------------------+ // |Sev|C|R| Facility | Code | // +---+-+-+-----------------------+-------------------------------+ // // where // // Sev - is the severity code // // 00 - Success // 01 - Informational // 10 - Warning // 11 - Error // // C - is the Customer code flag // // R - is a reserved bit // // Facility - is the facility code // // Code - is the facility's status code // // // Define the facility codes // #define FACILITY_SYSTEM 0x0 #define FACILITY_STUBS 0x3 #define FACILITY_RUNTIME 0x2 #define FACILITY_IO_ERROR_CODE 0x4 // // Define the severity codes // #define STATUS_SEVERITY_WARNING 0x2 #define STATUS_SEVERITY_SUCCESS 0x0 #define STATUS_SEVERITY_INFORMATIONAL 0x1 #define STATUS_SEVERITY_ERROR 0x3 // // MessageId: SVC_ERROR // // MessageText: // // An error has occurred (%2). // #define SVC_ERROR ((DWORD)0xC0020001L) // A message file must end with a period on its own line // followed by a blank line.svc.cpp
#include <windows.h> #include <tchar.h> #include <strsafe.h> #include "sample.h" #include <locale.h> #include <iostream> #include <conio.h> using namespace std; //#pragma comment(lib, "advapi32.lib") #define SVCNAME TEXT("SvcName") SERVICE_STATUS gSvcStatus; SERVICE_STATUS_HANDLE gSvcStatusHandle; HANDLE ghSvcStopEvent = NULL; VOID SvcInstall(void); VOID WINAPI SvcCtrlHandler( DWORD ); VOID WINAPI SvcMain( DWORD, LPTSTR * ); VOID ReportSvcStatus( DWORD, DWORD, DWORD ); VOID SvcInit( DWORD, LPTSTR * ); VOID SvcReportEvent( LPTSTR ); #define logName "c:/log.txt" TCHAR * GetErrString(TCHAR *str, DWORD errcode) { LPVOID lpbuf; if(FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpbuf, 0, NULL )) { lstrcpy(str,(LPCWSTR)lpbuf); LocalFree(lpbuf); } return str; } void DebugA(const char *Format, ...) { va_list va; char szOutputString[8096]; va_start(va, Format); memset(szOutputString, 0, 8096); wvsprintfA(szOutputString, Format, va); sprintf(szOutputString,"%s\n",szOutputString); OutputDebugStringA(szOutputString); do { freopen(logName, "a+", stdout); fprintf(stdout, "(pid=%d)%s:%d\t", GetCurrentProcessId(), __FILE__, __LINE__); fprintf(stdout, szOutputString ); fflush(stdout); } while (0); va_end(va); } void DebugW(const WCHAR *Format, ...) { va_list va; WCHAR szOutputString[8096]; va_start(va, Format); memset(szOutputString, 0, 8096); wvsprintfW(szOutputString, Format, va); wsprintf(szOutputString,L"%s\n",szOutputString); OutputDebugStringW(szOutputString); do { freopen(logName, "a+", stdout); fprintf(stdout, "(pid=%d)%s:%d\t", GetCurrentProcessId(), __FILE__, __LINE__); setlocale(LC_ALL,"chs"); //chs fwprintf_s(stdout,szOutputString); //_locale_t locale; // locale = _create_locale(LC_ALL, "chs"); //_fwprintf_l(stdout,szOutputString,_create_locale(LC_ALL, "chs")); fflush(stdout); } while (0); va_end(va); } // // Purpose: // Entry point for the process // // Parameters: // None // // Return value: // None // void __cdecl _tmain(int argc, TCHAR *argv[]) { // If command-line parameter is "install", install the service. // Otherwise, the service is probably being started by the SCM. if( lstrcmpi( argv[1], TEXT("install")) == 0 ) { SvcInstall(); return; } // TO_DO: Add any additional services for the process to this table. SERVICE_TABLE_ENTRY DispatchTable[] = { { SVCNAME, (LPSERVICE_MAIN_FUNCTION) SvcMain }, { NULL, NULL } }; // This call returns when the service has stopped. // The process should simply terminate when the call returns. BOOL ret=StartServiceCtrlDispatcher( DispatchTable ); if (!ret) { SvcReportEvent(TEXT("StartServiceCtrlDispatcher")); TCHAR err[1024]; int code=GetLastError(); GetErrString(err,code); DebugW(_T("Register Service Main Function Error msg:%d %s %d!"),code,err,ret); } else{ DebugA("StartServiceCtrlDispatcher success %d! ",ret); } } // // Purpose: // Installs a service in the SCM database // // Parameters: // None // // Return value: // None // VOID SvcInstall() { SC_HANDLE schSCManager; SC_HANDLE schService; TCHAR szPath[MAX_PATH]; if( !GetModuleFileName(NULL, szPath, MAX_PATH ) ) { printf("Cannot install service (%d)\n", GetLastError()); return; } // 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; } // Create the service schService = CreateService( schSCManager, // SCM database SVCNAME, // name of service SVCNAME, // service 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, // path to service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // no dependencies NULL, // LocalSystem account NULL); // no password if (schService == NULL) { printf("CreateService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } else printf("Service installed successfully\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } // // Purpose: // Entry point for the service // // Parameters: // dwArgc - Number of arguments in the lpszArgv array // lpszArgv - Array of strings. The first string is the name of // the service and subsequent strings are passed by the process // that called the StartService function to start the service. // // Return value: // None. // VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv ) { // Register the handler function for the service gSvcStatusHandle = RegisterServiceCtrlHandler( SVCNAME, SvcCtrlHandler); if( !gSvcStatusHandle ) { SvcReportEvent(TEXT("RegisterServiceCtrlHandler")); return; } DebugA("SvcMain..."); // These SERVICE_STATUS members remain as set here gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; gSvcStatus.dwServiceSpecificExitCode = 0; // Report initial status to the SCM ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR, 3000 ); // Perform service-specific initialization and work. SvcInit( dwArgc, lpszArgv ); } // // Purpose: // The service code // // Parameters: // dwArgc - Number of arguments in the lpszArgv array // lpszArgv - Array of strings. The first string is the name of // the service and subsequent strings are passed by the process // that called the StartService function to start the service. // // Return value: // None // VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv) { // TO_DO: Declare and set any required variables. // Be sure to periodically call ReportSvcStatus() with // SERVICE_START_PENDING. If initialization fails, call // ReportSvcStatus with SERVICE_STOPPED. // Create an event. The control handler function, SvcCtrlHandler, // signals this event when it receives the stop control code. ghSvcStopEvent = CreateEvent( NULL, // default security attributes TRUE, // manual reset event FALSE, // not signaled NULL); // no name if ( ghSvcStopEvent == NULL) { ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return; } // Report running status when initialization is complete. ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 ); // TO_DO: Perform work until service stops. while(1) { // Check whether to stop the service. DebugA("service running"); WaitForSingleObject(ghSvcStopEvent, INFINITE); ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return; } } // // Purpose: // Sets the current service status and reports it to the SCM. // // Parameters: // dwCurrentState - The current state (see SERVICE_STATUS) // dwWin32ExitCode - The system error code // dwWaitHint - Estimated time for pending operation, // in milliseconds // // Return value: // None // VOID ReportSvcStatus( DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) { static DWORD dwCheckPoint = 1; // Fill in the SERVICE_STATUS structure. gSvcStatus.dwCurrentState = dwCurrentState; gSvcStatus.dwWin32ExitCode = dwWin32ExitCode; gSvcStatus.dwWaitHint = dwWaitHint; if (dwCurrentState == SERVICE_START_PENDING) gSvcStatus.dwControlsAccepted = 0; else gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; if ( (dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED) ) gSvcStatus.dwCheckPoint = 0; else gSvcStatus.dwCheckPoint = dwCheckPoint++; // Report the status of the service to the SCM. SetServiceStatus( gSvcStatusHandle, &gSvcStatus ); } // // Purpose: // Called by SCM whenever a control code is sent to the service // using the ControlService function. // // Parameters: // dwCtrl - control code // // Return value: // None // VOID WINAPI SvcCtrlHandler( DWORD dwCtrl ) { // Handle the requested control code. switch(dwCtrl) { case SERVICE_CONTROL_STOP: ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); // Signal the service to stop. SetEvent(ghSvcStopEvent); ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0); return; case SERVICE_CONTROL_INTERROGATE: break; default: break; } } // // Purpose: // Logs messages to the event log // // Parameters: // szFunction - name of function that failed // // Return value: // None // // Remarks: // The service must have an entry in the Application event log. // VOID SvcReportEvent(LPTSTR szFunction) { HANDLE hEventSource; LPCTSTR lpszStrings[2]; TCHAR Buffer[80]; hEventSource = RegisterEventSource(NULL, SVCNAME); if( NULL != hEventSource ) { StringCchPrintf(Buffer, 80, TEXT("%s failed with %d"), szFunction, GetLastError()); lpszStrings[0] = SVCNAME; lpszStrings[1] = Buffer; ReportEvent(hEventSource, // event log handle EVENTLOG_ERROR_TYPE, // event type 0, // event category SVC_ERROR, // event identifier NULL, // no security identifier 2, // size of lpszStrings array 0, // no binary data lpszStrings, // array of strings NULL); // no binary data DeregisterEventSource(hEventSource); } }svcconfig.cpp
#include <windows.h> #include <tchar.h> #include <strsafe.h> #include <stdio.h> #pragma comment(lib, "advapi32.lib") TCHAR szCommand[10]; TCHAR szSvcName[80]; VOID __stdcall DisplayUsage(void); VOID __stdcall DoQuerySvc(void); VOID __stdcall DoUpdateSvcDesc(void); VOID __stdcall DoDisableSvc(void); VOID __stdcall DoEnableSvc(void); VOID __stdcall DoDeleteSvc(void); // // Purpose: // Entry point function. Executes specified command from user. // // Parameters: // Command-line syntax is: svcconfig [command] [service_path] // // Return value: // None // void __cdecl _tmain(int argc, TCHAR *argv[]) { printf("\n"); if( argc != 3 ) { printf("ERROR:\tIncorrect number of arguments\n\n"); DisplayUsage(); return; } StringCchCopy(szCommand, 10, argv[1]); StringCchCopy(szSvcName, 80, argv[2]); if (lstrcmpi( szCommand, TEXT("query")) == 0 ) DoQuerySvc(); else if (lstrcmpi( szCommand, TEXT("describe")) == 0 ) DoUpdateSvcDesc(); else if (lstrcmpi( szCommand, TEXT("disable")) == 0 ) DoDisableSvc(); else if (lstrcmpi( szCommand, TEXT("enable")) == 0 ) DoEnableSvc(); else if (lstrcmpi( szCommand, TEXT("delete")) == 0 ) DoDeleteSvc(); else { _tprintf(TEXT("Unknown command (%s)\n\n"), szCommand); DisplayUsage(); } } VOID __stdcall DisplayUsage() { printf("Description:\n"); printf("\tCommand-line tool that configures a service.\n\n"); printf("Usage:\n"); printf("\tsvcconfig [command] [service_name]\n\n"); printf("\t[command]\n"); printf("\t query\n"); printf("\t describe\n"); printf("\t disable\n"); printf("\t enable\n"); printf("\t delete\n"); } // // Purpose: // Retrieves and displays the current service configuration. // // Parameters: // None // // Return value: // None // VOID __stdcall DoQuerySvc() { SC_HANDLE schSCManager; SC_HANDLE schService; LPQUERY_SERVICE_CONFIG lpsc; LPSERVICE_DESCRIPTION lpsd; DWORD dwBytesNeeded, cbBufSize, dwError; // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("OpenSCManager failed (%d)\n", GetLastError()); return; } // Get a handle to the service. schService = OpenService( schSCManager, // SCM database szSvcName, // name of service SERVICE_QUERY_CONFIG); // need query config access if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } // Get the configuration information. if( !QueryServiceConfig( schService, NULL, 0, &dwBytesNeeded)) { dwError = GetLastError(); if( ERROR_INSUFFICIENT_BUFFER == dwError ) { cbBufSize = dwBytesNeeded; lpsc = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LMEM_FIXED, cbBufSize); } else { printf("QueryServiceConfig failed (%d)", dwError); goto cleanup; } } if( !QueryServiceConfig( schService, lpsc, cbBufSize, &dwBytesNeeded) ) { printf("QueryServiceConfig failed (%d)", GetLastError()); goto cleanup; } if( !QueryServiceConfig2( schService, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded)) { dwError = GetLastError(); if( ERROR_INSUFFICIENT_BUFFER == dwError ) { cbBufSize = dwBytesNeeded; lpsd = (LPSERVICE_DESCRIPTION) LocalAlloc(LMEM_FIXED, cbBufSize); } else { printf("QueryServiceConfig2 failed (%d)", dwError); goto cleanup; } } if (! QueryServiceConfig2( schService, SERVICE_CONFIG_DESCRIPTION, (LPBYTE) lpsd, cbBufSize, &dwBytesNeeded) ) { printf("QueryServiceConfig2 failed (%d)", GetLastError()); goto cleanup; } // Print the configuration information. _tprintf(TEXT("%s configuration: \n"), 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(schService); CloseServiceHandle(schSCManager); } // // Purpose: // Disables the service. // // Parameters: // None // // Return value: // None // VOID __stdcall DoDisableSvc() { SC_HANDLE schSCManager; SC_HANDLE schService; // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("OpenSCManager failed (%d)\n", GetLastError()); return; } // Get a handle to the service. schService = OpenService( schSCManager, // SCM database szSvcName, // name of service SERVICE_CHANGE_CONFIG); // need change config access if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } // Change the service start type. if (! ChangeServiceConfig( schService, // handle of service 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 { printf("ChangeServiceConfig failed (%d)\n", GetLastError()); } else printf("Service disabled successfully.\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } // // Purpose: // Enables the service. // // Parameters: // None // // Return value: // None // VOID __stdcall DoEnableSvc() { SC_HANDLE schSCManager; SC_HANDLE schService; // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("OpenSCManager failed (%d)\n", GetLastError()); return; } // Get a handle to the service. schService = OpenService( schSCManager, // SCM database szSvcName, // name of service SERVICE_CHANGE_CONFIG); // need change config access if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } // Change the service start type. if (! ChangeServiceConfig( schService, // handle of service 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 { printf("ChangeServiceConfig failed (%d)\n", GetLastError()); } else printf("Service enabled successfully.\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } // // Purpose: // Updates the service description to "This is a test description". // // Parameters: // None // // Return value: // None // VOID __stdcall DoUpdateSvcDesc() { SC_HANDLE schSCManager; SC_HANDLE schService; SERVICE_DESCRIPTION sd; LPTSTR szDesc = TEXT("This is a test description"); // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("OpenSCManager failed (%d)\n", GetLastError()); return; } // Get a handle to the service. schService = OpenService( schSCManager, // SCM database szSvcName, // name of service SERVICE_CHANGE_CONFIG); // need change config access if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } // Change the service description. sd.lpDescription = szDesc; if( !ChangeServiceConfig2( schService, // handle to service SERVICE_CONFIG_DESCRIPTION, // change: description &sd) ) // new description { printf("ChangeServiceConfig2 failed\n"); } else printf("Service description updated successfully.\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } // // Purpose: // Deletes a service from the SCM database // // Parameters: // None // // Return value: // None // VOID __stdcall DoDeleteSvc() { SC_HANDLE schSCManager; SC_HANDLE schService; SERVICE_STATUS ssStatus; // 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); // need delete access if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } // Delete the service. if (! DeleteService(schService) ) { printf("DeleteService failed (%d)\n", GetLastError()); } else printf("Service deleted successfully\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); }
svccontrol.cpp
#include <windows.h> #include <tchar.h> #include <strsafe.h> #include <aclapi.h> #include <stdio.h> #pragma comment(lib, "advapi32.lib") TCHAR szCommand[10]; TCHAR szSvcName[80]; SC_HANDLE schSCManager; SC_HANDLE schService; VOID __stdcall DisplayUsage(void); VOID __stdcall DoStartSvc(void); VOID __stdcall DoUpdateSvcDacl(void); VOID __stdcall DoStopSvc(void); BOOL __stdcall StopDependentServices(void); // // Purpose: // Entry point function. Executes specified command from user. // // Parameters: // Command-line syntax is: svccontrol [command] [service_name] // // Return value: // None // void _tmain(int argc, TCHAR *argv[]) { printf("\n"); if( argc != 3 ) { printf("ERROR: Incorrect number of arguments\n\n"); DisplayUsage(); return; } StringCchCopy(szCommand, 10, argv[1]); StringCchCopy(szSvcName, 80, argv[2]); if (lstrcmpi( szCommand, TEXT("start")) == 0 ) DoStartSvc(); else if (lstrcmpi( szCommand, TEXT("dacl")) == 0 ) DoUpdateSvcDacl(); else if (lstrcmpi( szCommand, TEXT("stop")) == 0 ) DoStopSvc(); else { _tprintf(TEXT("Unknown command (%s)\n\n"), szCommand); DisplayUsage(); } } VOID __stdcall DisplayUsage() { printf("Description:\n"); printf("\tCommand-line tool that controls a service.\n\n"); printf("Usage:\n"); printf("\tsvccontrol [command] [service_name]\n\n"); printf("\t[command]\n"); printf("\t start\n"); printf("\t dacl\n"); printf("\t stop\n"); } // // Purpose: // Starts the service if possible. // // Parameters: // None // // Return value: // None // VOID __stdcall DoStartSvc() { SERVICE_STATUS_PROCESS ssStatus; DWORD dwOldCheckPoint; DWORD dwStartTickCount; DWORD dwWaitTime; 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 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); } // // Purpose: // Updates the service DACL to grant start, stop, delete, and read // control access to the Guest account. // // Parameters: // None // // Return value: // None // VOID __stdcall DoUpdateSvcDacl() { 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; // 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, // SCManager database szSvcName, // name of service READ_CONTROL | WRITE_DAC); // access if (schService == NULL) { printf("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. printf("HeapAlloc failed\n"); goto dacl_cleanup; } if (!QueryServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded)) { printf("QueryServiceObjectSecurity failed (%d)\n", GetLastError()); goto dacl_cleanup; } } else { printf("QueryServiceObjectSecurity failed (%d)\n", GetLastError()); goto dacl_cleanup; } } // Get the DACL. if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted)) { printf("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); } // // Purpose: // Stops the service. // // Parameters: // None // // Return value: // None // VOID __stdcall DoStopSvc() { 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. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("OpenSCManager failed (%d)\n", GetLastError()); return; } // Get a handle to the service. schService = OpenService( schSCManager, // SCM database szSvcName, // name of service SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS); if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } // Make sure the service is not already stopped. if ( !QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded ) ) { printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); goto stop_cleanup; } if ( ssp.dwCurrentState == SERVICE_STOPPED ) { printf("Service is already stopped.\n"); goto stop_cleanup; } // If a stop is pending, wait for it. while ( ssp.dwCurrentState == SERVICE_STOP_PENDING ) { printf("Service stop pending...\n"); // Do not wait longer than the wait hint. A good interval is // one-tenth of the wait hint but not less than 1 second // and not more than 10 seconds. dwWaitTime = ssp.dwWaitHint / 10; if( dwWaitTime < 1000 ) dwWaitTime = 1000; else if ( dwWaitTime > 10000 ) dwWaitTime = 10000; Sleep( dwWaitTime ); if ( !QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded ) ) { printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); goto stop_cleanup; } if ( ssp.dwCurrentState == SERVICE_STOPPED ) { printf("Service stopped successfully.\n"); goto stop_cleanup; } if ( GetTickCount() - dwStartTime > dwTimeout ) { printf("Service stop timed out.\n"); goto stop_cleanup; } } // If the service is running, dependencies must be stopped first. StopDependentServices(); // Send a stop code to the service. if ( !ControlService( schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS) &ssp ) ) { printf( "ControlService failed (%d)\n", GetLastError() ); goto stop_cleanup; } // Wait for the service to stop. while ( ssp.dwCurrentState != SERVICE_STOPPED ) { Sleep( ssp.dwWaitHint ); if ( !QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded ) ) { printf( "QueryServiceStatusEx failed (%d)\n", GetLastError() ); goto stop_cleanup; } if ( ssp.dwCurrentState == SERVICE_STOPPED ) break; if ( GetTickCount() - dwStartTime > dwTimeout ) { printf( "Wait timed out\n" ); goto stop_cleanup; } } printf("Service stopped successfully\n"); stop_cleanup: CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } BOOL __stdcall 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 // 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; }
相关文章推荐
- VC2008中编写Windows服务(Windows Service)程序
- VC编写有图形界面的Windows服务程序
- VC编写系统服务程序笔记
- VC2010 编写windows service 服务程序
- VC编写Windows服务程序
- VC2010 编写windows service 服务程序
- VC编写系统服务程序笔记
- VC编写有图形界面的Windows服务程序
- 孙鑫VC学习笔记:第十五讲 编写一个基于MFC对话框的聊天程序
- 用 C 语言编写 Windows 服务程序的五个步骤
- 孙鑫VC学习笔记:第十六讲 用异步套接字编写聊天程序
- VC++编写电子邮件程序
- VC++下使用ADO编写数据库程序
- (转)用C语言编写Windows服务程序的五个步骤
- 用VC编写基于Windows的精确定时程序
- 如何利用VB编写NT服务程序
- 编写 Window 服务程序
- 在VC程序中调用服务组件
- NT服务程序编写
- VC++下使用ADO编写数据库程序