📄 svcproc.cxx
字号:
};
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 (strcasecmp(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 + -