📄 svcproc.cxx
字号:
return TRUE; // Report the status of the service to the service control manager. if (SetServiceStatus(statusHandle, &status)) return TRUE; // If an error occurs, stop the service. PSystemLog::Output(PSystemLog::Error, "SetServiceStatus failed"); return FALSE;}void PServiceProcess::OnStop(){}BOOL PServiceProcess::OnPause(){ SuspendThread(threadHandle); return TRUE;}void PServiceProcess::OnContinue(){ ResumeThread(threadHandle);}void PServiceProcess::OnControl(){}class ServiceManager{ public: ServiceManager() { error = 0; } virtual BOOL Create(PServiceProcess * svc) = 0; virtual BOOL Delete(PServiceProcess * svc) = 0; virtual BOOL Start(PServiceProcess * svc) = 0; virtual BOOL Stop(PServiceProcess * svc) = 0; virtual BOOL Pause(PServiceProcess * svc) = 0; virtual BOOL Resume(PServiceProcess * svc) = 0; DWORD GetError() const { return error; } protected: DWORD error;};class Win95_ServiceManager : public ServiceManager{ public: virtual BOOL Create(PServiceProcess * svc); virtual BOOL Delete(PServiceProcess * svc); virtual BOOL Start(PServiceProcess * svc); virtual BOOL Stop(PServiceProcess * svc); virtual BOOL Pause(PServiceProcess * svc); virtual BOOL Resume(PServiceProcess * svc);};BOOL Win95_ServiceManager::Create(PServiceProcess * svc){ HKEY key; if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &key) == ERROR_SUCCESS) { RegDeleteValue(key, (char *)(const char *)svc->GetName()); RegCloseKey(key); } if ((error = RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices", &key)) != ERROR_SUCCESS) return FALSE; PString cmd = "\"" + svc->GetFile() + "\""; error = RegSetValueEx(key, svc->GetName(), 0, REG_SZ, (LPBYTE)(const char *)cmd, cmd.GetLength() + 1); RegCloseKey(key); return error == ERROR_SUCCESS;}BOOL Win95_ServiceManager::Delete(PServiceProcess * svc){ HKEY key; if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &key) == ERROR_SUCCESS) { RegDeleteValue(key, (char *)(const char *)svc->GetName()); RegCloseKey(key); } if ((error = RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices", &key)) != ERROR_SUCCESS) return FALSE; error = RegDeleteValue(key, (char *)(const char *)svc->GetName()); RegCloseKey(key); return error == ERROR_SUCCESS;}BOOL Win95_ServiceManager::Start(PServiceProcess * service){ if (IsServiceRunning(service)) { PError << "Service already running" << endl; error = 1; return FALSE; } BOOL ok = _spawnl(_P_DETACH, service->GetFile(), service->GetFile(), NULL) >= 0; error = errno; return ok;}BOOL Win95_ServiceManager::Stop(PServiceProcess * service){ HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, service->GetName()); if (hEvent == NULL) { error = ::GetLastError(); PError << "Service is not running" << endl; return FALSE; } SetEvent(hEvent); CloseHandle(hEvent); // Wait for process to go away. for (PINDEX i = 0; i < 20; i++) { hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, service->GetName()); if (hEvent == NULL) return TRUE; CloseHandle(hEvent); ::Sleep(500); } error = 0x10000000; return FALSE;}BOOL Win95_ServiceManager::Pause(PServiceProcess *){ PError << "Cannot pause service under Windows 95" << endl; error = 1; return FALSE;}BOOL Win95_ServiceManager::Resume(PServiceProcess *){ PError << "Cannot resume service under Windows 95" << endl; error = 1; return FALSE;}class NT_ServiceManager : public ServiceManager{ public: NT_ServiceManager() { schSCManager = schService = NULL; } ~NT_ServiceManager(); BOOL Create(PServiceProcess * svc); BOOL Delete(PServiceProcess * svc); BOOL Start(PServiceProcess * svc); BOOL Stop(PServiceProcess * svc) { return Control(svc, SERVICE_CONTROL_STOP); } BOOL Pause(PServiceProcess * svc) { return Control(svc, SERVICE_CONTROL_PAUSE); } BOOL Resume(PServiceProcess * svc) { return Control(svc, SERVICE_CONTROL_CONTINUE); } DWORD GetError() const { return error; } private: BOOL OpenManager(); BOOL Open(PServiceProcess * svc); BOOL Control(PServiceProcess * svc, DWORD command); SC_HANDLE schSCManager, schService;};NT_ServiceManager::~NT_ServiceManager(){ if (schService != NULL) CloseServiceHandle(schService); if (schSCManager != NULL) CloseServiceHandle(schSCManager);}BOOL NT_ServiceManager::OpenManager(){ schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (schSCManager != NULL) return TRUE; error = ::GetLastError(); PError << "Could not open Service Manager." << endl; return FALSE;}BOOL NT_ServiceManager::Open(PServiceProcess * svc){ if (!OpenManager()) return FALSE; schService = OpenService(schSCManager, svc->GetName(), SERVICE_ALL_ACCESS); if (schService != NULL) return TRUE; error = ::GetLastError(); PError << "Service is not installed." << endl; return FALSE;}BOOL NT_ServiceManager::Create(PServiceProcess * svc){ if (!OpenManager()) return FALSE; schService = OpenService(schSCManager, svc->GetName(), SERVICE_ALL_ACCESS); if (schService != NULL) { PError << "Service is already installed." << endl; return FALSE; } PString binaryFilename; GetShortPathName(svc->GetFile(), binaryFilename.GetPointer(_MAX_PATH), _MAX_PATH); schService = CreateService( schSCManager, // SCManager database svc->GetName(), // name of service svc->GetName(), // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type binaryFilename, // service's binary NULL, // no load ordering group NULL, // no tag identifier svc->GetServiceDependencies(), // no dependencies NULL, // LocalSystem account NULL); // no password if (schService == NULL) { error = ::GetLastError(); return FALSE; } HKEY key; if ((error = RegCreateKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" + svc->GetName(), &key)) != ERROR_SUCCESS) return FALSE; LPBYTE fn = (LPBYTE)(const char *)binaryFilename; PINDEX fnlen = binaryFilename.GetLength()+1; if ((error = RegSetValueEx(key, "EventMessageFile", 0, REG_EXPAND_SZ, fn, fnlen)) == ERROR_SUCCESS && (error = RegSetValueEx(key, "CategoryMessageFile", 0, REG_EXPAND_SZ, fn, fnlen)) == ERROR_SUCCESS) { DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; if ((error = RegSetValueEx(key, "TypesSupported", 0, REG_DWORD, (LPBYTE)&dwData, sizeof(DWORD))) == ERROR_SUCCESS) { dwData = PSystemLog::NumLogLevels; error = RegSetValueEx(key, "CategoryCount", 0, REG_DWORD, (LPBYTE)&dwData, sizeof(DWORD)); } } RegCloseKey(key); return error == ERROR_SUCCESS;}BOOL NT_ServiceManager::Delete(PServiceProcess * svc){ if (!Open(svc)) return FALSE; PString name = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" + svc->GetName(); error = ::RegDeleteKey(HKEY_LOCAL_MACHINE, (char *)(const char *)name); if (!::DeleteService(schService)) error = ::GetLastError(); return error == ERROR_SUCCESS;}BOOL NT_ServiceManager::Start(PServiceProcess * svc){ if (!Open(svc)) return FALSE; BOOL ok = ::StartService(schService, 0, NULL); error = ::GetLastError(); return ok;}BOOL NT_ServiceManager::Control(PServiceProcess * svc, DWORD command){ if (!Open(svc)) return FALSE; SERVICE_STATUS status; BOOL ok = ::ControlService(schService, command, &status); error = ::GetLastError(); return ok;}BOOL PServiceProcess::ProcessCommand(const char * cmd){ PINDEX cmdNum = 0; while (stricmp(cmd, ServiceCommandNames[cmdNum]) != 0) { if (++cmdNum >= NumSvcCmds) { if (!CreateControlWindow(TRUE)) return FALSE; if (*cmd != '\0') PError << "Unknown command \"" << cmd << "\".\n"; else PError << "Could not start service.\n"; PError << "usage: " << GetName() << " [ "; for (cmdNum = 0; cmdNum < NumSvcCmds-1; cmdNum++) PError << ServiceCommandNames[cmdNum] << " | "; PError << ServiceCommandNames[cmdNum] << " ]" << endl; return FALSE; } } NT_ServiceManager nt; Win95_ServiceManager win95; ServiceManager * svcManager; if (isWin95) svcManager = &win95; else svcManager = &nt; BOOL good = FALSE; switch (cmdNum) { case SvcCmdNoWindow : if (controlWindow == NULL) controlWindow = (HWND)-1; break; case SvcCmdTray : if (CreateControlWindow(FALSE)) { PNotifyIconData nid(controlWindow, NIF_MESSAGE|NIF_ICON, GetName()); nid.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(ICON_RESID), IMAGE_ICON, // 16x16 icon GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0); nid.uCallbackMessage = UWM_SYSTRAY; // message sent to nid.hWnd nid.Add(); // This adds the icon debugWindow = (HWND)-1; systemLogFileName = PString(); return TRUE; } return FALSE; case SvcCmdNoTray : if (TrayIconRegistry(this, CheckTrayIcon)) { TrayIconRegistry(this, DelTrayIcon); PError << "Tray icon removed."; } else { TrayIconRegistry(this, AddTrayIcon); PError << "Tray icon installed."; } return TRUE; case SvcCmdVersion : // Version command ::SetLastError(0); PError << GetName() << " Version " << GetVersion(TRUE) << " by " << GetManufacturer() << " on " << GetOSClass() << ' ' << GetOSName() << " (" << GetOSVersion() << '-' << GetOSHardware() << ')' << endl; return TRUE; case SvcCmdInstall : // install good = svcManager->Create(this); TrayIconRegistry(this, AddTrayIcon); break; case SvcCmdRemove : // remove good = svcManager->Delete(this); TrayIconRegistry(this, DelTrayIcon); break; case SvcCmdStart : // start good = svcManager->Start(this); break; case SvcCmdStop : // stop good = svcManager->Stop(this); break; case SvcCmdPause : // pause good = svcManager->Pause(this); break; case SvcCmdResume : // resume good = svcManager->Resume(this); break; case SvcCmdDeinstall : // deinstall svcManager->Delete(this); TrayIconRegistry(this, DelTrayIcon); PConfig cfg; PStringList sections = cfg.GetSections(); PINDEX i; for (i = 0; i < sections.GetSize(); i++) cfg.DeleteSection(sections[i]); good = TRUE; break; } SetLastError(0); PError << "Service command \"" << ServiceCommandNames[cmdNum] << "\" "; if (good) PError << "successful."; else { PError << "failed - "; switch (svcManager->GetError()) { case ERROR_ACCESS_DENIED : PError << "Access denied"; break; case 0x10000000 : PError << "process still running."; break; default : PError << "error code = " << svcManager->GetError(); } } PError << endl; return TRUE;}// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -