/** * Main entry point when running as a service. */ void WINAPI SvcMain(DWORD argc, LPWSTR *argv) { // Setup logging, and backup the old logs WCHAR updatePath[MAX_PATH + 1]; if (GetLogDirectoryPath(updatePath)) { BackupOldLogs(updatePath, LOGS_TO_KEEP); LogInit(updatePath, L"maintenanceservice.log"); } // Disable every privilege we don't need. Processes started using // CreateProcess will use the same token as this process. UACHelper::DisablePrivileges(NULL); // Register the handler function for the service gSvcStatusHandle = RegisterServiceCtrlHandlerW(SVC_NAME, SvcCtrlHandler); if (!gSvcStatusHandle) { LOG(("RegisterServiceCtrlHandler failed (%d)\n", GetLastError())); ExecuteServiceCommand(argc, argv); LogFinish(); exit(1); } // These values will be re-used later in calls involving gSvcStatus gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; gSvcStatus.dwServiceSpecificExitCode = 0; // Report initial status to the SCM ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000); // This event will be used to tell the SvcCtrlHandler when the work is // done for when a stop comamnd is manually issued. gWorkDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!gWorkDoneEvent) { ReportSvcStatus(SERVICE_STOPPED, 1, 0); StartTerminationThread(); return; } // Initialization complete and we're about to start working on // the actual command. Report the service state as running to the SCM. ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); // The service command was executed, stop logging and set an event // to indicate the work is done in case someone is waiting on a // service stop operation. ExecuteServiceCommand(argc, argv); LogFinish(); SetEvent(gWorkDoneEvent); // If we aren't already in a stopping state then tell the SCM we're stopped // now. If we are already in a stopping state then the SERVICE_STOPPED state // will be set by the SvcCtrlHandler. if (!gServiceControlStopping) { ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); StartTerminationThread(); } }
bool RevertVMToLastSnapshotByPipeNameW(const wchar_t *pPipeName) { return SUCCEEDED(ExecuteServiceCommand(pPipeName, kRevertToLastSnapshot)); }
bool ForceInstantBreakInByPipeNameW(const wchar_t *pPipeName) { return SUCCEEDED(ExecuteServiceCommand(pPipeName, kInstantBreak)); }