📄 svcproc.cxx
字号:
&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 PFalse;
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;
}
PBoolean 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 PFalse;
error = RegDeleteValue(key, (char *)(const char *)svc->GetName());
RegCloseKey(key);
return error == ERROR_SUCCESS;
}
PBoolean Win95_ServiceManager::Start(PServiceProcess * service)
{
if (IsServiceRunning(service)) {
PError << "Service already running" << endl;
error = 1;
return PFalse;
}
PBoolean ok = _spawnl(_P_DETACH, service->GetFile(), service->GetFile(), NULL) >= 0;
error = errno;
return ok;
}
PBoolean Win95_ServiceManager::Stop(PServiceProcess * service)
{
HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, PFalse, service->GetName());
if (hEvent == NULL) {
error = ::GetLastError();
PError << "Service is not running" << endl;
return PFalse;
}
SetEvent(hEvent);
CloseHandle(hEvent);
// Wait for process to go away.
for (PINDEX i = 0; i < 20; i++) {
hEvent = OpenEvent(EVENT_MODIFY_STATE, PFalse, service->GetName());
if (hEvent == NULL)
return PTrue;
CloseHandle(hEvent);
::Sleep(500);
}
error = 0x10000000;
return PFalse;
}
PBoolean Win95_ServiceManager::Pause(PServiceProcess *)
{
PError << "Cannot pause service under Windows 95" << endl;
error = 1;
return PFalse;
}
PBoolean Win95_ServiceManager::Resume(PServiceProcess *)
{
PError << "Cannot resume service under Windows 95" << endl;
error = 1;
return PFalse;
}
class NT_ServiceManager : public ServiceManager
{
public:
NT_ServiceManager() { schSCManager = schService = NULL; }
~NT_ServiceManager();
PBoolean Create(PServiceProcess * svc);
PBoolean Delete(PServiceProcess * svc);
PBoolean Start(PServiceProcess * svc);
PBoolean Stop(PServiceProcess * svc)
{ return Control(svc, SERVICE_CONTROL_STOP); }
PBoolean Pause(PServiceProcess * svc)
{ return Control(svc, SERVICE_CONTROL_PAUSE); }
PBoolean Resume(PServiceProcess * svc)
{ return Control(svc, SERVICE_CONTROL_CONTINUE); }
DWORD GetError() const { return error; }
private:
PBoolean OpenManager();
PBoolean Open(PServiceProcess * svc);
PBoolean Control(PServiceProcess * svc, DWORD command);
SC_HANDLE schSCManager, schService;
};
NT_ServiceManager::~NT_ServiceManager()
{
if (schService != NULL)
CloseServiceHandle(schService);
if (schSCManager != NULL)
CloseServiceHandle(schSCManager);
}
PBoolean NT_ServiceManager::OpenManager()
{
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager != NULL)
return PTrue;
error = ::GetLastError();
PError << "Could not open Service Manager." << endl;
return PFalse;
}
PBoolean NT_ServiceManager::Open(PServiceProcess * svc)
{
if (!OpenManager())
return PFalse;
schService = OpenService(schSCManager, svc->GetName(), SERVICE_ALL_ACCESS);
if (schService != NULL)
return PTrue;
error = ::GetLastError();
PError << "Service is not installed." << endl;
return PFalse;
}
PBoolean NT_ServiceManager::Create(PServiceProcess * svc)
{
if (!OpenManager())
return PFalse;
schService = OpenService(schSCManager, svc->GetName(), SERVICE_ALL_ACCESS);
if (schService != NULL) {
PError << "Service is already installed." << endl;
return PFalse;
}
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 PFalse;
}
HKEY key;
if ((error = RegCreateKey(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" +
svc->GetName(), &key)) != ERROR_SUCCESS)
return PFalse;
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;
}
PBoolean NT_ServiceManager::Delete(PServiceProcess * svc)
{
if (!Open(svc))
return PFalse;
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;
}
PBoolean NT_ServiceManager::Start(PServiceProcess * svc)
{
if (!Open(svc))
return PFalse;
PBoolean ok = ::StartService(schService, 0, NULL);
error = ::GetLastError();
if (!ok)
return PFalse;
SERVICE_STATUS serviceStatus;
// query the service status
if (!QueryServiceStatus(schService, &serviceStatus))
return PFalse;
// if pending periodicaly re-query the status
while (serviceStatus.dwCurrentState == SERVICE_START_PENDING) {
DWORD waitTime = PMIN(serviceStatus.dwWaitHint / 10, 10000);
Sleep(waitTime);
if (! QueryServiceStatus(schService, &serviceStatus)) break;
}
if (serviceStatus.dwCurrentState == SERVICE_RUNNING) {
return PTrue;
} else {
error = serviceStatus.dwWin32ExitCode;
return PFalse;
}
}
PBoolean NT_ServiceManager::Control(PServiceProcess * svc, DWORD command)
{
if (!Open(svc))
return PFalse;
SERVICE_STATUS status;
PBoolean ok = ::ControlService(schService, command, &status);
error = ::GetLastError();
return ok;
}
PBoolean PServiceProcess::ProcessCommand(const char * cmd)
{
PINDEX cmdNum = 0;
while (strcasecmp(cmd, ServiceCommandNames[cmdNum]) != 0) {
if (++cmdNum >= NumSvcCmds) {
if (!CreateControlWindow(PTrue))
return PFalse;
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 PFalse;
}
}
NT_ServiceManager nt;
Win95_ServiceManager win95;
ServiceManager * svcManager;
if (isWin95)
svcManager = &win95;
else
svcManager = &nt;
PBoolean good = PFalse;
switch (cmdNum) {
case SvcCmdNoWindow :
if (controlWindow == NULL)
controlWindow = (HWND)-1;
break;
case SvcCmdTray :
if (CreateControlWindow(PFalse)) {
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 = DebuggerLogOutput;
return PTrue;
}
return PFalse;
case SvcCmdNoTray :
if (TrayIconRegistry(this, CheckTrayIcon)) {
TrayIconRegistry(this, DelTrayIcon);
PError << "Tray icon removed.";
}
else {
TrayIconRegistry(this, AddTrayIcon);
PError << "Tray icon installed.";
}
return PTrue;
case SvcCmdVersion : // Version command
::SetLastError(0);
PError << GetName() << " Version " << GetVersion(PTrue)
<< " by " << GetManufacturer()
<< " on " << GetOSClass() << ' ' << GetOSName()
<< " (" << GetOSVersion() << '-' << GetOSHardware() << ')' << endl;
return PTrue;
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);
#if P_CONFIG_FILE
PConfig cfg;
PStringArray sections = cfg.GetSections();
PINDEX i;
for (i = 0; i < sections.GetSize(); i++)
cfg.DeleteSection(sections[i]);
#endif // P_CONFIG_FILE
good = PTrue;
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 PTrue;
}
// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -