mirror of
https://github.com/owntone/owntone-server.git
synced 2025-11-10 05:59:45 -05:00
Merge from dev-FireflyShell branch
This commit is contained in:
171
win32/FireflyShell/ServiceControl.h
Normal file
171
win32/FireflyShell/ServiceControl.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
*(C) 2006 Roku LLC
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License Version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* Please read README.txt in the same directory as this source file for
|
||||
* further license information.
|
||||
*/
|
||||
|
||||
#ifndef SERVICECONTROL_H
|
||||
#define SERVICECONTROL_H
|
||||
|
||||
class Service
|
||||
{
|
||||
SC_HANDLE m_sc_manager;
|
||||
SC_HANDLE m_sc_service;
|
||||
bool m_can_control;
|
||||
|
||||
public:
|
||||
|
||||
class Status : public SERVICE_STATUS
|
||||
{
|
||||
bool WaitPending();
|
||||
|
||||
public:
|
||||
Status()
|
||||
{
|
||||
SERVICE_STATUS *clearable_this = this;
|
||||
ZeroMemory(clearable_this, sizeof(SERVICE_STATUS));
|
||||
}
|
||||
|
||||
bool operator==(const Status &r) const
|
||||
{
|
||||
const SERVICE_STATUS *lhs = this;
|
||||
const SERVICE_STATUS *rhs = &r;
|
||||
return memcmp(lhs, rhs, sizeof(SERVICE_STATUS)) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const Status &r) const
|
||||
{
|
||||
const SERVICE_STATUS *lhs = this;
|
||||
const SERVICE_STATUS *rhs = &r;
|
||||
return memcmp(lhs, rhs, sizeof(SERVICE_STATUS)) != 0;
|
||||
}
|
||||
|
||||
void AssertValid() const
|
||||
{
|
||||
// If we've been written then this shouldn't be zero.
|
||||
ATLASSERT(dwCurrentState != 0);
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return dwCurrentState != 0;
|
||||
}
|
||||
|
||||
bool IsRunning() const
|
||||
{
|
||||
AssertValid();
|
||||
return dwCurrentState == SERVICE_RUNNING;
|
||||
}
|
||||
|
||||
bool IsStopped() const
|
||||
{
|
||||
AssertValid();
|
||||
return dwCurrentState == SERVICE_STOPPED;
|
||||
}
|
||||
|
||||
bool IsPaused() const
|
||||
{
|
||||
AssertValid();
|
||||
return dwCurrentState == SERVICE_PAUSED;
|
||||
}
|
||||
|
||||
bool IsPending() const
|
||||
{
|
||||
AssertValid();
|
||||
switch (dwCurrentState)
|
||||
{
|
||||
case SERVICE_CONTINUE_PENDING:
|
||||
case SERVICE_PAUSE_PENDING:
|
||||
case SERVICE_START_PENDING:
|
||||
case SERVICE_STOP_PENDING:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Service() : m_sc_manager(NULL), m_sc_service(NULL), m_can_control(false) {}
|
||||
~Service() { Close(); }
|
||||
|
||||
bool IsOpen() const
|
||||
{
|
||||
return m_sc_service != NULL;
|
||||
}
|
||||
bool Open(const TCHAR *name);
|
||||
void Close();
|
||||
|
||||
bool GetStatus(Status *status) const;
|
||||
|
||||
bool Start();
|
||||
bool StartAndWait();
|
||||
bool Stop();
|
||||
bool StopAndWait();
|
||||
bool WaitPending(Status *status, DWORD existing_state);
|
||||
bool PollPending(Status *status, DWORD existing_state);
|
||||
|
||||
bool CanControl() const
|
||||
{
|
||||
// For the time being - need to deal with running as a user that can't control.
|
||||
return IsOpen() && m_can_control;
|
||||
}
|
||||
|
||||
CString GetBinaryPath() const;
|
||||
|
||||
/// Pass SERVICE_AUTO_START, SERVICE_BOOT_START, SERVICE_DEMAND_START,
|
||||
/// SERVICE_DISABLED or SERVICE_SYSTEM_START.
|
||||
bool ConfigureStartup(DWORD dwStartup);
|
||||
|
||||
DWORD GetStartup() const;
|
||||
};
|
||||
|
||||
class ServiceStatusObserver
|
||||
{
|
||||
public:
|
||||
virtual void OnServiceStatus(Service::Status old_status, Service::Status new_status) = 0;
|
||||
};
|
||||
|
||||
class ServiceStatusMonitor
|
||||
{
|
||||
Service::Status m_service_status;
|
||||
std::vector<ServiceStatusObserver *> m_service_observers;
|
||||
|
||||
void FireServiceStatus(Service::Status old_status, Service::Status new_status)
|
||||
{
|
||||
std::vector<ServiceStatusObserver *>::iterator i = m_service_observers.begin();
|
||||
while (i != m_service_observers.end())
|
||||
{
|
||||
(*i)->OnServiceStatus(old_status, new_status);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void Poll(Service *service);
|
||||
void Subscribe(ServiceStatusObserver *obs)
|
||||
{
|
||||
m_service_observers.push_back(obs);
|
||||
}
|
||||
|
||||
void Unsubscribe(ServiceStatusObserver *obs)
|
||||
{
|
||||
std::vector<ServiceStatusObserver *>::iterator i = std::find(m_service_observers.begin(), m_service_observers.end(), obs);
|
||||
ATLASSERT(i != m_service_observers.end());
|
||||
if (i != m_service_observers.end())
|
||||
{
|
||||
m_service_observers.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
#endif // SERVICECONTROL_H
|
||||
Reference in New Issue
Block a user