[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 1/2] Refactor XenAgent
- Merge IDeviceCreator interface into CDeviceList base class - Add CXenIfaceDeviceList and CConvDeviceList, derived from CDeviceList - Moves IFace functionality to CXenIfaceDeviceList - Moves Conv device functionality to CConvDeviceList - Seperate RegisterDeviceNotification from SetupApi enumeration, so that static devices do not need to hold the handle open (i.e. Conv device) - CConvDeviceList only opens the handle when neccessary, as the MS driver for the ACPI device only allows 1 open handle at a time. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenagent/convdevice.cpp | 59 +++- src/xenagent/convdevice.h | 22 ++ src/xenagent/devicelist.cpp | 166 ++++++----- src/xenagent/devicelist.h | 57 ++-- src/xenagent/service.cpp | 486 +------------------------------- src/xenagent/service.h | 86 +----- src/xenagent/xenifacedevice.cpp | 348 +++++++++++++++++++++++ src/xenagent/xenifacedevice.h | 43 +++ 8 files changed, 619 insertions(+), 648 deletions(-) diff --git a/src/xenagent/convdevice.cpp b/src/xenagent/convdevice.cpp index 5ac40ff..5a25be1 100644 --- a/src/xenagent/convdevice.cpp +++ b/src/xenagent/convdevice.cpp @@ -29,6 +29,7 @@ * SUCH DAMAGE. */ +#define INITGUID #include <windows.h> #include <stdio.h> #include <powrprof.h> @@ -37,6 +38,11 @@ #include "service.h" #include "convdevice.h" #include "devicelist.h" +#include "messages.h" + +/* 317fc439-3f77-41c8-b09e-08ad63272aa3 */ +DEFINE_GUID(GUID_GPIOBUTTONS_LAPTOPSLATE_INTERFACE, \ + 0x317fc439, 0x3f77, 0x41c8, 0xb0, 0x9e, 0x08, 0xad, 0x63, 0x27, 0x2a, 0xa3); CConvDevice::CConvDevice(const wchar_t* path) : CDevice(path) { @@ -65,7 +71,11 @@ void CConvDevice::SetMode(DWORD new_mode) if (current_mode == new_mode) break; - Write(&buffer, sizeof(buffer)); + if (Open()) { + Write(&buffer, sizeof(buffer)); + Close(); + } + Sleep(1000); // yield } } @@ -135,3 +145,50 @@ fail2: fail1: return false; } + +CConvDeviceList::CConvDeviceList(CXenAgent* agent) : CDeviceList(GUID_GPIOBUTTONS_LAPTOPSLATE_INTERFACE), m_agent(agent) +{} + +/*virtual*/ CConvDeviceList::~CConvDeviceList() +{} + +/*virtual*/ CDevice* CConvDeviceList::Create(const wchar_t* path) +{ + return new CConvDevice(path); +} + +/*virtual*/ void CConvDeviceList::OnDeviceAdded(CDevice* dev) +{ + UNREFERENCED_PARAMETER(dev); +} + +/*virtual*/ void CConvDeviceList::OnDeviceRemoved(CDevice* dev) +{ + UNREFERENCED_PARAMETER(dev); +} + +/*virtual*/ void CConvDeviceList::OnDeviceSuspend(CDevice* dev) +{ + UNREFERENCED_PARAMETER(dev); +} + +/*virtual*/ void CConvDeviceList::OnDeviceResume(CDevice* dev) +{ + UNREFERENCED_PARAMETER(dev); +} + +void CConvDeviceList::SetSlateMode(std::string& mode) +{ + CCritSec crit(&m_crit); + CConvDevice* device = (CConvDevice*)GetFirstDevice(); + + if (device == NULL) + return; + + m_agent->EventLog(EVENT_XENUSER_MODE_SWITCH); + + if (mode == "laptop") + device->SetMode(CCONV_DEVICE_LAPTOP_MODE); + else if (mode == "slate") + device->SetMode(CCONV_DEVICE_SLATE_MODE); +} diff --git a/src/xenagent/convdevice.h b/src/xenagent/convdevice.h index 90f8035..088ff15 100644 --- a/src/xenagent/convdevice.h +++ b/src/xenagent/convdevice.h @@ -56,4 +56,26 @@ private: bool GetMode(DWORD *mode); }; +class CXenAgent; + +class CConvDeviceList : public CDeviceList +{ +public: + CConvDeviceList(CXenAgent* agent); + virtual ~CConvDeviceList(); + +protected: // CDeviceList + virtual CDevice* Create(const wchar_t* path); + virtual void OnDeviceAdded(CDevice* dev); + virtual void OnDeviceRemoved(CDevice* dev); + virtual void OnDeviceSuspend(CDevice* dev); + virtual void OnDeviceResume(CDevice* dev); + +public: + void SetSlateMode(std::string& mode); + +private: + CXenAgent* m_agent; +}; + #endif diff --git a/src/xenagent/devicelist.cpp b/src/xenagent/devicelist.cpp index 4acf532..d6af5d4 100644 --- a/src/xenagent/devicelist.cpp +++ b/src/xenagent/devicelist.cpp @@ -65,6 +65,15 @@ static void DebugPrint(const wchar_t* fmt, ...) OutputDebugStringW(buffer); } +CCritSec::CCritSec(LPCRITICAL_SECTION crit) : m_crit(crit) +{ + EnterCriticalSection(m_crit); +} +CCritSec::~CCritSec() +{ + LeaveCriticalSection(m_crit); +} + CDevice::CDevice(const wchar_t* path) : m_handle(INVALID_HANDLE_VALUE), m_path(path), m_notify(NULL) { @@ -81,6 +90,11 @@ const wchar_t* CDevice::Path() const return m_path.c_str(); } +HDEVNOTIFY CDevice::Notify() const +{ + return m_notify; +} + bool CDevice::Open() { Close(); @@ -104,7 +118,7 @@ void CDevice::Close() m_handle = INVALID_HANDLE_VALUE; } -HDEVNOTIFY CDevice::Register(HANDLE svc) +bool CDevice::Register(HANDLE svc) { Unregister(); @@ -114,7 +128,7 @@ HDEVNOTIFY CDevice::Register(HANDLE svc) devhdl.dbch_handle = m_handle; m_notify = RegisterDeviceNotification(svc, &devhdl, DEVICE_NOTIFY_SERVICE_HANDLE); - return m_notify; + return (m_notify != NULL); } void CDevice::Unregister() @@ -162,24 +176,32 @@ bool CDevice::Ioctl(DWORD ioctl, void* in, DWORD insz, void* out, DWORD outsz, D } CDeviceList::CDeviceList(const GUID& itf) : - m_guid(itf), m_notify(NULL), m_handle(NULL), m_impl(NULL) + m_guid(itf), m_notify(NULL), m_handle(NULL) { + InitializeCriticalSection(&m_crit); } CDeviceList::~CDeviceList() { - Stop(); + UnregisterForDeviceChange(); + CleanupDeviceList(); + + DeleteCriticalSection(&m_crit); } -#pragma warning(push) -#pragma warning(disable:6102) // Using value from failed function call +CDevice* CDeviceList::GetFirstDevice() +{ + DeviceMap::iterator it = m_devs.begin(); + if (it == m_devs.end()) + return NULL; + return *it; +} -bool CDeviceList::Start(HANDLE handle, IDeviceCreator* impl) +bool CDeviceList::RegisterForDeviceChange(HANDLE handle) { - Stop(); + UnregisterForDeviceChange(); m_handle = handle; - m_impl = impl; DEV_BROADCAST_DEVICEINTERFACE dev = { 0 }; dev.dbcc_size = sizeof(dev); @@ -187,9 +209,21 @@ bool CDeviceList::Start(HANDLE handle, IDeviceCreator* impl) dev.dbcc_classguid = m_guid; m_notify = RegisterDeviceNotificationA(handle, &dev, DEVICE_NOTIFY_SERVICE_HANDLE); - if (m_notify == NULL) - return false; + return m_notify != NULL; +} + +void CDeviceList::UnregisterForDeviceChange() +{ + if (m_notify != NULL) + UnregisterDeviceNotification(m_notify); + m_notify = NULL; +} +#pragma warning(push) +#pragma warning(disable:6102) // Using value from failed function call + +void CDeviceList::EnumerateDevices() +{ HDEVINFO info; SP_DEVICE_INTERFACE_DATA itf; PSP_DEVICE_INTERFACE_DETAIL_DATA detail; @@ -201,7 +235,7 @@ bool CDeviceList::Start(HANDLE handle, IDeviceCreator* impl) NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (info == INVALID_HANDLE_VALUE) - return true; // non fatal, just missing already present device(s) + return; // non fatal, just missing already present device(s) itf.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for (idx = 0; @@ -229,23 +263,17 @@ bool CDeviceList::Start(HANDLE handle, IDeviceCreator* impl) itf.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); } SetupDiDestroyDeviceInfoList(info); - return true; } #pragma warning(pop) -void CDeviceList::Stop() +void CDeviceList::CleanupDeviceList() { - if (m_notify != NULL) - UnregisterDeviceNotification(m_notify); - m_notify = NULL; - for (DeviceMap::iterator it = m_devs.begin(); it != m_devs.end(); ++it) { - if (m_impl) - m_impl->OnDeviceRemoved(it->second); - delete it->second; + OnDeviceRemoved(*it); + delete *it; } m_devs.clear(); } @@ -302,14 +330,14 @@ void CDeviceList::OnPowerEvent(DWORD evt, LPVOID data) for (DeviceMap::iterator it = m_devs.begin(); it != m_devs.end(); ++it) - m_impl->OnDeviceResume(it->second); + OnDeviceResume(*it); break; case PBT_APMSUSPEND: for (DeviceMap::iterator it = m_devs.begin(); it != m_devs.end(); ++it) - m_impl->OnDeviceSuspend(it->second); + OnDeviceSuspend(*it); break; default: @@ -317,37 +345,25 @@ void CDeviceList::OnPowerEvent(DWORD evt, LPVOID data) } } -CDevice* CDeviceList::GetFirstDevice() -{ - DeviceMap::iterator it = m_devs.begin(); - if (it == m_devs.end()) - return NULL; - return it->second; -} - void CDeviceList::DeviceArrival(const std::wstring& path) { DebugPrint(L"DeviceArrival(%ws)\n", path.c_str()); - CDevice* dev; - if (m_impl) - dev = m_impl->Create(path.c_str()); - else - dev = new CDevice(path.c_str()); + CDevice* dev = Create(path.c_str()); if (dev == NULL) goto fail1; + if (m_handle == NULL) + goto done; + if (!dev->Open()) goto fail2; - HDEVNOTIFY nfy = dev->Register(m_handle); - if (nfy == NULL) + if (!dev->Register(m_handle)) goto fail3; - m_devs[nfy] = dev; - - if (m_impl) - m_impl->OnDeviceAdded(dev); - +done: + OnDeviceAdded(dev); + m_devs.push_back(dev); return; fail3: @@ -362,44 +378,60 @@ fail1: void CDeviceList::DeviceRemoved(HDEVNOTIFY nfy) { - DeviceMap::iterator it = m_devs.find(nfy); - if (it == m_devs.end()) - return; // spurious event? + for (DeviceMap::iterator it = m_devs.begin(); + it != m_devs.end(); + ++it) { + CDevice* dev = *it; + + if (dev->Notify() != nfy) + continue; - CDevice* dev = it->second; - DebugPrint(L"DeviceRemoved(%ws)\n", dev->Path()); + DebugPrint(L"DeviceRemoved(%ws)\n", dev->Path()); - delete dev; // handles unregister() - m_devs.erase(it); + delete dev; // handles unregister() + m_devs.erase(it); + return; + } + // Spurious event? } void CDeviceList::DeviceRemovePending(HDEVNOTIFY nfy) { - DeviceMap::iterator it = m_devs.find(nfy); - if (it == m_devs.end()) - return; // spurious event? + for (DeviceMap::iterator it = m_devs.begin(); + it != m_devs.end(); + ++it) { + CDevice* dev = *it; - CDevice* dev = it->second; - DebugPrint(L"DeviceRemovePending(%ws)\n", dev->Path()); + if (dev->Notify() != nfy) + continue; + + DebugPrint(L"DeviceRemovePending(%ws)\n", dev->Path()); - if (m_impl) - m_impl->OnDeviceRemoved(dev); + OnDeviceRemoved(dev); - dev->Close(); + dev->Close(); + return; + } + // Spurious event? } void CDeviceList::DeviceRemoveFailed(HDEVNOTIFY nfy) { - DeviceMap::iterator it = m_devs.find(nfy); - if (it == m_devs.end()) - return; // spurious event? + for (DeviceMap::iterator it = m_devs.begin(); + it != m_devs.end(); + ++it) { + CDevice* dev = *it; - CDevice* dev = it->second; - DebugPrint(L"DeviceRemoveFailed(%ws)\n", dev->Path()); + if (dev->Notify() != nfy) + continue; - if (!dev->Open()) - DeviceRemoved(nfy); + DebugPrint(L"DeviceRemoveFailed(%ws)\n", dev->Path()); + + if (!dev->Open()) + DeviceRemoved(nfy); - if (m_impl) - m_impl->OnDeviceAdded(dev); + OnDeviceAdded(dev); + return; + } + // Spurious event? } diff --git a/src/xenagent/devicelist.h b/src/xenagent/devicelist.h index e96df56..3e260f8 100644 --- a/src/xenagent/devicelist.h +++ b/src/xenagent/devicelist.h @@ -34,9 +34,18 @@ #include <windows.h> #include <dbt.h> -#include <map> +#include <vector> #include <string> +class CCritSec +{ +public: + CCritSec(LPCRITICAL_SECTION crit); + ~CCritSec(); +private: + LPCRITICAL_SECTION m_crit; +}; + class CDevice { public: @@ -44,10 +53,11 @@ public: virtual ~CDevice(); const wchar_t* Path() const; + HDEVNOTIFY Notify() const; bool Open(); void Close(); - HDEVNOTIFY Register(HANDLE svc); + bool Register(HANDLE svc); void Unregister(); protected: @@ -60,27 +70,31 @@ private: HDEVNOTIFY m_notify; }; -class IDeviceCreator +class CDeviceList { -public: +protected: + CDeviceList(const GUID& itf); + virtual CDevice* Create(const wchar_t* path) = 0; - virtual void OnDeviceAdded(CDevice* dev) = 0; - virtual void OnDeviceRemoved(CDevice* dev) = 0; - virtual void OnDeviceSuspend(CDevice* dev) = 0; - virtual void OnDeviceResume(CDevice* dev) = 0; -}; + virtual void OnDeviceAdded(CDevice* dev) = 0; + virtual void OnDeviceRemoved(CDevice* dev) = 0; + virtual void OnDeviceSuspend(CDevice* dev) = 0; + virtual void OnDeviceResume(CDevice* dev) = 0; + + CRITICAL_SECTION m_crit; -class CDeviceList -{ public: - CDeviceList(const GUID& itf); - ~CDeviceList(); + virtual ~CDeviceList(); + + CDevice* GetFirstDevice(); + + bool RegisterForDeviceChange(HANDLE svc); + void UnregisterForDeviceChange(); + void EnumerateDevices(); + void CleanupDeviceList(); - bool Start(HANDLE svc, IDeviceCreator* impl); - void Stop(); void OnDeviceEvent(DWORD evt, LPVOID data); void OnPowerEvent(DWORD evt, LPVOID data); - CDevice* GetFirstDevice(); private: void DeviceArrival(const std::wstring& path); @@ -88,13 +102,12 @@ private: void DeviceRemovePending(HDEVNOTIFY nfy); void DeviceRemoveFailed(HDEVNOTIFY nfy); - typedef std::map< HDEVNOTIFY, CDevice* > DeviceMap; + typedef std::vector< CDevice* > DeviceMap; - GUID m_guid; - DeviceMap m_devs; - HDEVNOTIFY m_notify; - HANDLE m_handle; - IDeviceCreator* m_impl; + GUID m_guid; + DeviceMap m_devs; + HDEVNOTIFY m_notify; + HANDLE m_handle; }; #endif diff --git a/src/xenagent/service.cpp b/src/xenagent/service.cpp index 85fac63..535d761 100644 --- a/src/xenagent/service.cpp +++ b/src/xenagent/service.cpp @@ -29,478 +29,14 @@ * SUCH DAMAGE. */ -#define INITGUID #include <windows.h> #include <stdio.h> #include <powrprof.h> #include <winuser.h> -#include <xeniface_ioctls.h> - #include "service.h" #include "messages.h" - -class CCritSec -{ -public: - CCritSec(LPCRITICAL_SECTION crit); - ~CCritSec(); -private: - LPCRITICAL_SECTION m_crit; -}; - -CCritSec::CCritSec(LPCRITICAL_SECTION crit) : m_crit(crit) -{ - EnterCriticalSection(m_crit); -} -CCritSec::~CCritSec() -{ - LeaveCriticalSection(m_crit); -} - -CXenIfaceCreator::CXenIfaceCreator(CXenAgent& agent) : - m_devlist(GUID_INTERFACE_XENIFACE), m_device(NULL), - m_ctxt_shutdown(NULL), m_ctxt_suspend(NULL), - m_ctxt_slate_mode(NULL), m_agent(agent) -{ - m_evt_shutdown = CreateEvent(NULL, TRUE, FALSE, NULL); - m_evt_suspend = CreateEvent(NULL, TRUE, FALSE, NULL); - m_evt_slate_mode = CreateEvent(NULL, TRUE, FALSE, NULL); - m_count = 0; - - InitializeCriticalSection(&m_crit); -} - -CXenIfaceCreator::~CXenIfaceCreator() -{ - CloseHandle(m_evt_slate_mode); - CloseHandle(m_evt_suspend); - CloseHandle(m_evt_shutdown); - - DeleteCriticalSection(&m_crit); -} - -bool CXenIfaceCreator::Start(HANDLE svc) -{ - return m_devlist.Start(svc, this); -} - -void CXenIfaceCreator::Stop() -{ - // Check if registry key is present, implies Windows Update - // require a reboot, which may spend time installing updates - LogIfRebootPending(); - - m_devlist.Stop(); -} - -void CXenIfaceCreator::OnDeviceEvent(DWORD evt, LPVOID data) -{ - m_devlist.OnDeviceEvent(evt, data); -} - -void CXenIfaceCreator::OnPowerEvent(DWORD evt, LPVOID data) -{ - m_devlist.OnPowerEvent(evt, data); -} - -void CXenIfaceCreator::Log(const char* message) -{ - // if possible, send to xeniface to forward to logs - if (m_device && TryEnterCriticalSection(&m_crit)) { - m_device->Log(message); - LeaveCriticalSection(&m_crit); - } -} - -/*virtual*/ CDevice* CXenIfaceCreator::Create(const wchar_t* path) -{ - return new CXenIfaceDevice(path); -} - -/*virtual*/ void CXenIfaceCreator::OnDeviceAdded(CDevice* dev) -{ - CXenAgent::Log("OnDeviceAdded(%ws)\n", dev->Path()); - - CCritSec crit(&m_crit); - if (m_device == NULL) { - m_device = (CXenIfaceDevice*)dev; - - m_device->SuspendRegister(m_evt_suspend, &m_ctxt_suspend); - - StartShutdownWatch(); - - if (m_agent.ConvDevicePresent()) - StartSlateModeWatch(); - - SetXenTime(); - } -} - -/*virtual*/ void CXenIfaceCreator::OnDeviceRemoved(CDevice* dev) -{ - CXenAgent::Log("OnDeviceRemoved(%ws)\n", dev->Path()); - - CCritSec crit(&m_crit); - if (m_device == dev) { - if (m_ctxt_suspend) { - m_device->SuspendDeregister(m_ctxt_suspend); - m_ctxt_suspend = NULL; - } - - if (m_agent.ConvDevicePresent()) - StopSlateModeWatch(); - - StopShutdownWatch(); - - m_device = NULL; - } -} - -/*virtual*/ void CXenIfaceCreator::OnDeviceSuspend(CDevice* dev) -{ - CXenAgent::Log("OnDeviceSuspend(%ws)\n", dev->Path()); - - if (m_agent.ConvDevicePresent()) - StopSlateModeWatch(); - - StopShutdownWatch(); -} - -/*virtual*/ void CXenIfaceCreator::OnDeviceResume(CDevice* dev) -{ - CXenAgent::Log("OnDeviceResume(%ws)\n", dev->Path()); - - StartShutdownWatch(); - - if (m_agent.ConvDevicePresent()) - StartSlateModeWatch(); -} - -bool CXenIfaceCreator::CheckShutdown() -{ - CCritSec crit(&m_crit); - if (m_device == NULL) - return false; - - std::string type; - if (!m_device->StoreRead("control/shutdown", type)) - return false; - - if (type != "") - CXenAgent::Log("Shutdown(%ws) = '%s'\n", m_device->Path(), type.c_str()); - - if (type == "poweroff") { - m_device->StoreWrite("control/shutdown", ""); - m_agent.EventLog(EVENT_XENUSER_POWEROFF); - - AcquireShutdownPrivilege(); -#pragma warning(suppress:28159) /* Consider using a design alternative... Rearchitect to avoid Reboot */ - if (!InitiateSystemShutdownEx(NULL, NULL, 0, TRUE, FALSE, - SHTDN_REASON_MAJOR_OTHER | - SHTDN_REASON_MINOR_ENVIRONMENT | - SHTDN_REASON_FLAG_PLANNED)) { - CXenAgent::Log("InitiateSystemShutdownEx failed %08x\n", GetLastError()); - } - return true; - } else if (type == "reboot") { - m_device->StoreWrite("control/shutdown", ""); - m_agent.EventLog(EVENT_XENUSER_REBOOT); - - AcquireShutdownPrivilege(); -#pragma warning(suppress:28159) /* Consider using a design alternative... Rearchitect to avoid Reboot */ - if (!InitiateSystemShutdownEx(NULL, NULL, 0, TRUE, TRUE, - SHTDN_REASON_MAJOR_OTHER | - SHTDN_REASON_MINOR_ENVIRONMENT | - SHTDN_REASON_FLAG_PLANNED)) { - CXenAgent::Log("InitiateSystemShutdownEx failed %08x\n", GetLastError()); - } - return true; - } else if (type == "s4") { - m_device->StoreWrite("control/shutdown", ""); - m_agent.EventLog(EVENT_XENUSER_S4); - - AcquireShutdownPrivilege(); - if (!SetSystemPowerState(FALSE, FALSE)) { - CXenAgent::Log("SetSystemPowerState failed %08x\n", GetLastError()); - } - return false; - } else if (type == "s3") { - m_device->StoreWrite("control/shutdown", ""); - m_agent.EventLog(EVENT_XENUSER_S3); - - AcquireShutdownPrivilege(); - if (!SetSuspendState(FALSE, TRUE, FALSE)) { - CXenAgent::Log("SetSuspendState failed %08x\n", GetLastError()); - } - return false; - } - - return false; -} - -void CXenIfaceCreator::CheckXenTime() -{ - CCritSec crit(&m_crit); - if (m_device == NULL) - return; - - SetXenTime(); -} - -void CXenIfaceCreator::CheckSuspend() -{ - CCritSec crit(&m_crit); - if (m_device == NULL) - return; - - DWORD count = 0; - - if (!m_device->SuspendGetCount(&count)) - return; - - if (m_count == count) - return; - - CXenAgent::Log("Suspend(%ws)\n", m_device->Path()); - - m_agent.EventLog(EVENT_XENUSER_UNSUSPENDED); - - // recreate watches, as suspending deactivated the watch - if (m_agent.ConvDevicePresent()) - StopSlateModeWatch(); - - StopShutdownWatch(); - - StartShutdownWatch(); - - if (m_agent.ConvDevicePresent()) - StartSlateModeWatch(); - - m_count = count; -} - -bool CXenIfaceCreator::CheckSlateMode(std::string *mode) -{ - CCritSec crit(&m_crit); - if (m_device == NULL) - return false; - - if (!m_device->StoreRead("control/laptop-slate-mode", *mode)) - return false; - - if (*mode != "") - m_device->StoreWrite("control/laptop-slate-mode", ""); - - return true; -} - -void CXenIfaceCreator::LogIfRebootPending() -{ - HKEY Key; - LONG lResult; - - lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\RebootRequired", - 0, - KEY_READ, - &Key); - if (lResult != ERROR_SUCCESS) - return; // key doesnt exist, dont log anything - - RegCloseKey(Key); - - CXenAgent::Log("RebootRequired detected\n"); -} - -void CXenIfaceCreator::StartShutdownWatch() -{ - if (m_ctxt_shutdown) - return; - - m_device->StoreAddWatch("control/shutdown", m_evt_shutdown, &m_ctxt_shutdown); - - m_device->StoreWrite("control/feature-poweroff", "1"); - m_device->StoreWrite("control/feature-reboot", "1"); - m_device->StoreWrite("control/feature-s3", "1"); - m_device->StoreWrite("control/feature-s4", "1"); -} - -void CXenIfaceCreator::StopShutdownWatch() -{ - if (!m_ctxt_shutdown) - return; - - m_device->StoreWrite("control/feature-poweroff", ""); - m_device->StoreWrite("control/feature-reboot", ""); - m_device->StoreWrite("control/feature-s3", ""); - m_device->StoreWrite("control/feature-s4", ""); - - m_device->StoreRemoveWatch(m_ctxt_shutdown); - m_ctxt_shutdown = NULL; -} - -void CXenIfaceCreator::StartSlateModeWatch() -{ - if (m_ctxt_slate_mode) - return; - - m_device->StoreAddWatch("control/laptop-slate-mode", m_evt_slate_mode, &m_ctxt_slate_mode); - m_device->StoreWrite("control/feature-laptop-slate-mode", "1"); -} - -void CXenIfaceCreator::StopSlateModeWatch() -{ - if (!m_ctxt_slate_mode) - return; - - m_device->StoreRemove("control/feature-laptop-slate-mode"); - - m_device->StoreRemoveWatch(m_ctxt_slate_mode); - m_ctxt_slate_mode = NULL; -} - -void CXenIfaceCreator::AcquireShutdownPrivilege() -{ - HANDLE token; - TOKEN_PRIVILEGES tp; - - LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid); - tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - tp.PrivilegeCount = 1; - - if (!OpenProcessToken(GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, - &token)) - return; - - AdjustTokenPrivileges(token, FALSE, &tp, NULL, 0, NULL); - CloseHandle(token); -} - -void CXenIfaceCreator::SetXenTime() -{ - bool local; - - FILETIME now = { 0 }; - if (!m_device->SharedInfoGetTime(&now, &local)) - return; - - SYSTEMTIME cur = { 0 }; - if (local) - GetLocalTime(&cur); - else - GetSystemTime(&cur); - - SYSTEMTIME sys = { 0 }; - if (!FileTimeToSystemTime(&now, &sys)) - return; - - if (memcmp(&cur, &sys, sizeof(SYSTEMTIME)) == 0) - return; - - CXenAgent::Log("RTC is in %s\n", local ? "local time" : "UTC"); - CXenAgent::Log("Time Now = %d/%d/%d %d:%02d:%02d.%d\n", - cur.wYear, cur.wMonth, cur.wDay, - cur.wHour, cur.wMinute, cur.wSecond, cur.wMilliseconds); - CXenAgent::Log("New Time = %d/%d/%d %d:%02d:%02d.%d\n", - sys.wYear, sys.wMonth, sys.wDay, - sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds); - - if (local) - SetLocalTime(&sys); - else - SetSystemTime(&sys); -} - -/* 317fc439-3f77-41c8-b09e-08ad63272aa3 */ -DEFINE_GUID(GUID_GPIOBUTTONS_LAPTOPSLATE_INTERFACE, \ - 0x317fc439, 0x3f77, 0x41c8, 0xb0, 0x9e, 0x08, 0xad, 0x63, 0x27, 0x2a, 0xa3); - -CConvCreator::CConvCreator(CXenAgent& agent) : - m_devlist(GUID_GPIOBUTTONS_LAPTOPSLATE_INTERFACE), m_device(NULL), - m_agent(agent) -{ - InitializeCriticalSection(&m_crit); -} - -CConvCreator::~CConvCreator() -{ - DeleteCriticalSection(&m_crit); -} - -bool CConvCreator::Start(HANDLE svc) -{ - return m_devlist.Start(svc, this); -} - -void CConvCreator::Stop() -{ - m_devlist.Stop(); -} - -void CConvCreator::OnDeviceEvent(DWORD evt, LPVOID data) -{ - m_devlist.OnDeviceEvent(evt, data); -} - -void CConvCreator::OnPowerEvent(DWORD evt, LPVOID data) -{ - m_devlist.OnPowerEvent(evt, data); -} - -void CConvCreator::SetSlateMode(std::string mode) -{ - CCritSec crit(&m_crit); - if (m_device == NULL) - return; - - m_agent.EventLog(EVENT_XENUSER_MODE_SWITCH); - - if (mode == "laptop") - m_device->SetMode(CCONV_DEVICE_LAPTOP_MODE); - else if (mode == "slate") - m_device->SetMode(CCONV_DEVICE_SLATE_MODE); -} - -bool CConvCreator::DevicePresent() -{ - return m_device != NULL; -} - -/*virtual*/ CDevice* CConvCreator::Create(const wchar_t* path) -{ - return new CConvDevice(path); -} - -/*virtual*/ void CConvCreator::OnDeviceAdded(CDevice* dev) -{ - CXenAgent::Log("OnDeviceAdded(%ws)\n", dev->Path()); - - CCritSec crit(&m_crit); - if (m_device == NULL) - m_device = (CConvDevice*)dev; -} - -/*virtual*/ void CConvCreator::OnDeviceRemoved(CDevice* dev) -{ - CXenAgent::Log("OnDeviceRemoved(%ws)\n", dev->Path()); - - CCritSec crit(&m_crit); - if (m_device == dev) - m_device = NULL; -} - -/*virtual*/ void CConvCreator::OnDeviceSuspend(CDevice* dev) -{ - CXenAgent::Log("OnDeviceSuspend(%ws)\n", dev->Path()); -} - -/*virtual*/ void CConvCreator::OnDeviceResume(CDevice* dev) -{ - CXenAgent::Log("OnDeviceResume(%ws)\n", dev->Path()); -} +#include "xeniface_ioctls.h" static CXenAgent s_service; @@ -609,8 +145,8 @@ static CXenAgent s_service; #pragma warning(push) #pragma warning(disable:4355) -CXenAgent::CXenAgent() noexcept : m_handle(NULL), m_evtlog(NULL), m_xeniface(*this), - m_conv(*this) +CXenAgent::CXenAgent() noexcept : m_handle(NULL), m_evtlog(NULL), + m_xeniface(this), m_conv(this) { m_status.dwServiceType = SERVICE_WIN32; m_status.dwCurrentState = SERVICE_START_PENDING; @@ -635,20 +171,22 @@ CXenAgent::~CXenAgent() void CXenAgent::OnServiceStart() { CXenAgent::Log("OnServiceStart()\n"); - m_conv.Start(m_handle); - m_xeniface.Start(m_handle); + m_xeniface.RegisterForDeviceChange(m_handle); + m_xeniface.EnumerateDevices(); + m_conv.EnumerateDevices(); } void CXenAgent::OnServiceStop() { CXenAgent::Log("OnServiceStop()\n"); - m_xeniface.Stop(); - m_conv.Stop(); + m_xeniface.LogIfRebootPending(); + m_xeniface.UnregisterForDeviceChange(); + m_xeniface.CleanupDeviceList(); + m_conv.CleanupDeviceList(); } void CXenAgent::OnDeviceEvent(DWORD evt, LPVOID data) { - m_conv.OnDeviceEvent(evt, data); m_xeniface.OnDeviceEvent(evt, data); } @@ -686,7 +224,7 @@ bool CXenAgent::ServiceMainLoop() std::string mode; ResetEvent(m_xeniface.m_evt_slate_mode); - if (m_xeniface.CheckSlateMode(&mode)) + if (m_xeniface.CheckSlateMode(mode)) m_conv.SetSlateMode(mode); return true; // continue loop @@ -722,7 +260,7 @@ void CXenAgent::EventLog(DWORD evt) bool CXenAgent::ConvDevicePresent() { - return m_conv.DevicePresent(); + return m_conv.GetFirstDevice() != NULL; } void CXenAgent::SetServiceStatus(DWORD state, DWORD exit /*= 0*/, DWORD hint /*= 0*/) diff --git a/src/xenagent/service.h b/src/xenagent/service.h index e886de6..32a6b8d 100644 --- a/src/xenagent/service.h +++ b/src/xenagent/service.h @@ -45,88 +45,6 @@ #include "xenifacedevice.h" #include "convdevice.h" -class CXenAgent; - -class CXenIfaceCreator : public IDeviceCreator -{ -public: - CXenIfaceCreator(CXenAgent&); - virtual ~CXenIfaceCreator(); - CXenIfaceCreator& operator=(const CXenIfaceCreator&); - - bool Start(HANDLE svc); - void Stop(); - void OnDeviceEvent(DWORD evt, LPVOID data); - void OnPowerEvent(DWORD evt, LPVOID data); - void Log(const char *message); - -public: // IDeviceCreator - virtual CDevice* Create(const wchar_t* path); - virtual void OnDeviceAdded(CDevice* dev); - virtual void OnDeviceRemoved(CDevice* dev); - virtual void OnDeviceSuspend(CDevice* dev); - virtual void OnDeviceResume(CDevice* dev); - -public: - bool CheckShutdown(); - void CheckXenTime(); - void CheckSuspend(); - bool CheckSlateMode(std::string *mode); - -public: - HANDLE m_evt_shutdown; - HANDLE m_evt_suspend; - HANDLE m_evt_slate_mode; - -private: - void LogIfRebootPending(); - void StartShutdownWatch(); - void StopShutdownWatch(); - void StartSlateModeWatch(); - void StopSlateModeWatch(); - void AcquireShutdownPrivilege(); - bool IsRTCInUTC(); - void SetXenTime(); - -private: - CXenAgent& m_agent; - CDeviceList m_devlist; - CXenIfaceDevice* m_device; - CRITICAL_SECTION m_crit; - void* m_ctxt_shutdown; - void* m_ctxt_suspend; - void* m_ctxt_slate_mode; - DWORD m_count; -}; - -class CConvCreator : public IDeviceCreator -{ -public: - CConvCreator(CXenAgent&); - virtual ~CConvCreator(); - CConvCreator& operator=(const CConvCreator&); - - bool Start(HANDLE svc); - void Stop(); - void OnDeviceEvent(DWORD evt, LPVOID data); - void OnPowerEvent(DWORD evt, LPVOID data); - void SetSlateMode(std::string mode); - bool DevicePresent(); - -public: - virtual CDevice* Create(const wchar_t* path); - virtual void OnDeviceAdded(CDevice* dev); - virtual void OnDeviceRemoved(CDevice* dev); - virtual void OnDeviceSuspend(CDevice* dev); - virtual void OnDeviceResume(CDevice* dev); - -private: - CXenAgent& m_agent; - CDeviceList m_devlist; - CConvDevice* m_device; - CRITICAL_SECTION m_crit; -}; - class CXenAgent { public: // statics @@ -165,8 +83,8 @@ private: // service support SERVICE_STATUS_HANDLE m_handle; HANDLE m_evtlog; HANDLE m_svc_stop; - CXenIfaceCreator m_xeniface; - CConvCreator m_conv; + CXenIfaceDeviceList m_xeniface; + CConvDeviceList m_conv; }; #endif diff --git a/src/xenagent/xenifacedevice.cpp b/src/xenagent/xenifacedevice.cpp index 6ebf163..eea63e4 100644 --- a/src/xenagent/xenifacedevice.cpp +++ b/src/xenagent/xenifacedevice.cpp @@ -29,12 +29,16 @@ * SUCH DAMAGE. */ +#define INITGUID #include <windows.h> #include <winioctl.h> +#include <powrprof.h> +#include "service.h" #include "xenifacedevice.h" #include "devicelist.h" #include "xeniface_ioctls.h" +#include "messages.h" CXenIfaceDevice::CXenIfaceDevice(const wchar_t* path) : CDevice(path) {} @@ -169,3 +173,347 @@ bool CXenIfaceDevice::Log(const std::string& msg) (void*)msg.c_str(), (DWORD)msg.length() + 1, NULL, 0); } + +CXenIfaceDeviceList::CXenIfaceDeviceList(CXenAgent* agent) : CDeviceList(GUID_INTERFACE_XENIFACE), + m_agent(agent), + m_ctxt_suspend(NULL), + m_ctxt_shutdown(NULL), + m_ctxt_slate_mode(NULL) +{ + m_evt_shutdown = CreateEvent(NULL, TRUE, FALSE, NULL); + m_evt_suspend = CreateEvent(NULL, TRUE, FALSE, NULL); + m_evt_slate_mode = CreateEvent(NULL, TRUE, FALSE, NULL); + m_count = 0; +} + +/*virtual*/ CXenIfaceDeviceList::~CXenIfaceDeviceList() +{ + CloseHandle(m_evt_slate_mode); + CloseHandle(m_evt_suspend); + CloseHandle(m_evt_shutdown); +} + +/*virtual*/ CDevice* CXenIfaceDeviceList::Create(const wchar_t* path) +{ + return new CXenIfaceDevice(path); +} + +/*virtual*/ void CXenIfaceDeviceList::OnDeviceAdded(CDevice* dev) +{ + CCritSec crit(&m_crit); + + if (GetFirstDevice() != NULL) + return; + + CXenIfaceDevice* device = (CXenIfaceDevice*)dev; + + device->SuspendRegister(m_evt_suspend, &m_ctxt_suspend); + StartShutdownWatch(device); + + if (m_agent->ConvDevicePresent()) + StartSlateModeWatch(device); + + SetXenTime(device); +} + +/*virtual*/ void CXenIfaceDeviceList::OnDeviceRemoved(CDevice* dev) +{ + CCritSec crit(&m_crit); + CXenIfaceDevice* device = (CXenIfaceDevice*)dev; + + if (dev != GetFirstDevice()) + return; + + if (m_ctxt_suspend) + device->SuspendDeregister(m_ctxt_suspend); + m_ctxt_suspend = NULL; + + if (m_agent->ConvDevicePresent()) + StopSlateModeWatch(device); + + StopShutdownWatch(device); +} + +/*virtual*/ void CXenIfaceDeviceList::OnDeviceSuspend(CDevice* dev) +{ + CCritSec crit(&m_crit); + CXenIfaceDevice* device = (CXenIfaceDevice*)dev; + + if (dev != GetFirstDevice()) + return; + + if (m_agent->ConvDevicePresent()) + StopSlateModeWatch(device); + + StopShutdownWatch(device); +} + +/*virtual*/ void CXenIfaceDeviceList::OnDeviceResume(CDevice* dev) +{ + CCritSec crit(&m_crit); + CXenIfaceDevice* device = (CXenIfaceDevice*)dev; + + if (dev != GetFirstDevice()) + return; + + StartShutdownWatch(device); + + if (m_agent->ConvDevicePresent()) + StartSlateModeWatch(device); +} + +void CXenIfaceDeviceList::Log(const char* message) +{ + // if possible, send to xeniface to forward to logs + if (TryEnterCriticalSection(&m_crit)) { + CXenIfaceDevice* device = (CXenIfaceDevice*)GetFirstDevice(); + if (device != NULL) + device->Log(message); + LeaveCriticalSection(&m_crit); + } +} + +bool CXenIfaceDeviceList::CheckShutdown() +{ + CCritSec crit(&m_crit); + CXenIfaceDevice* device = (CXenIfaceDevice*)GetFirstDevice(); + + if (device == NULL) + return false; + + std::string type; + if (!device->StoreRead("control/shutdown", type)) + return false; + + if (type != "") + CXenAgent::Log("Shutdown(%ws) = '%s'\n", device->Path(), type.c_str()); + + if (type == "poweroff") { + device->StoreWrite("control/shutdown", ""); + m_agent->EventLog(EVENT_XENUSER_POWEROFF); + + AcquireShutdownPrivilege(); +#pragma warning(suppress:28159) /* Consider using a design alternative... Rearchitect to avoid Reboot */ + if (!InitiateSystemShutdownEx(NULL, NULL, 0, TRUE, FALSE, + SHTDN_REASON_MAJOR_OTHER | + SHTDN_REASON_MINOR_ENVIRONMENT | + SHTDN_REASON_FLAG_PLANNED)) { + CXenAgent::Log("InitiateSystemShutdownEx failed %08x\n", GetLastError()); + } + return true; + } else if (type == "reboot") { + device->StoreWrite("control/shutdown", ""); + m_agent->EventLog(EVENT_XENUSER_REBOOT); + + AcquireShutdownPrivilege(); +#pragma warning(suppress:28159) /* Consider using a design alternative... Rearchitect to avoid Reboot */ + if (!InitiateSystemShutdownEx(NULL, NULL, 0, TRUE, TRUE, + SHTDN_REASON_MAJOR_OTHER | + SHTDN_REASON_MINOR_ENVIRONMENT | + SHTDN_REASON_FLAG_PLANNED)) { + CXenAgent::Log("InitiateSystemShutdownEx failed %08x\n", GetLastError()); + } + return true; + } else if (type == "s4") { + device->StoreWrite("control/shutdown", ""); + m_agent->EventLog(EVENT_XENUSER_S4); + + AcquireShutdownPrivilege(); + if (!SetSystemPowerState(FALSE, FALSE)) { + CXenAgent::Log("SetSystemPowerState failed %08x\n", GetLastError()); + } + return false; + } else if (type == "s3") { + device->StoreWrite("control/shutdown", ""); + m_agent->EventLog(EVENT_XENUSER_S3); + + AcquireShutdownPrivilege(); + if (!SetSuspendState(FALSE, TRUE, FALSE)) { + CXenAgent::Log("SetSuspendState failed %08x\n", GetLastError()); + } + return false; + } + + return false; +} + +void CXenIfaceDeviceList::CheckXenTime() +{ + CCritSec crit(&m_crit); + CXenIfaceDevice* device = (CXenIfaceDevice*)GetFirstDevice(); + + if (device == NULL) + return; + + SetXenTime(device); +} + +void CXenIfaceDeviceList::CheckSuspend() +{ + CCritSec crit(&m_crit); + CXenIfaceDevice* device = (CXenIfaceDevice*)GetFirstDevice(); + + if (device == NULL) + return; + + DWORD count = 0; + + if (!device->SuspendGetCount(&count)) + return; + + if (m_count == count) + return; + + CXenAgent::Log("Suspend(%ws)\n", device->Path()); + + m_agent->EventLog(EVENT_XENUSER_UNSUSPENDED); + + // recreate watches, as suspending deactivated the watch + if (m_agent->ConvDevicePresent()) + StopSlateModeWatch(device); + + StopShutdownWatch(device); + + StartShutdownWatch(device); + + if (m_agent->ConvDevicePresent()) + StartSlateModeWatch(device); + + m_count = count; +} + +bool CXenIfaceDeviceList::CheckSlateMode(std::string& mode) +{ + CCritSec crit(&m_crit); + CXenIfaceDevice* device = (CXenIfaceDevice*)GetFirstDevice(); + + if (device == NULL) + return false; + + if (!device->StoreRead("control/laptop-slate-mode", mode)) + return false; + + if (mode != "") + device->StoreWrite("control/laptop-slate-mode", ""); + + return true; +} + +void CXenIfaceDeviceList::LogIfRebootPending() +{ + HKEY Key; + LONG lResult; + + lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\RebootRequired", + 0, + KEY_READ, + &Key); + if (lResult != ERROR_SUCCESS) + return; // key doesnt exist, dont log anything + + RegCloseKey(Key); + + CXenAgent::Log("RebootRequired detected\n"); +} + +void CXenIfaceDeviceList::StartShutdownWatch(CXenIfaceDevice* device) +{ + if (m_ctxt_shutdown) + return; + + device->StoreAddWatch("control/shutdown", m_evt_shutdown, &m_ctxt_shutdown); + + device->StoreWrite("control/feature-poweroff", "1"); + device->StoreWrite("control/feature-reboot", "1"); + device->StoreWrite("control/feature-s3", "1"); + device->StoreWrite("control/feature-s4", "1"); +} + +void CXenIfaceDeviceList::StopShutdownWatch(CXenIfaceDevice* device) +{ + if (!m_ctxt_shutdown) + return; + + device->StoreWrite("control/feature-poweroff", ""); + device->StoreWrite("control/feature-reboot", ""); + device->StoreWrite("control/feature-s3", ""); + device->StoreWrite("control/feature-s4", ""); + + device->StoreRemoveWatch(m_ctxt_shutdown); + m_ctxt_shutdown = NULL; +} + +void CXenIfaceDeviceList::StartSlateModeWatch(CXenIfaceDevice* device) +{ + if (m_ctxt_slate_mode) + return; + + device->StoreAddWatch("control/laptop-slate-mode", m_evt_slate_mode, &m_ctxt_slate_mode); + device->StoreWrite("control/feature-laptop-slate-mode", "1"); +} + +void CXenIfaceDeviceList::StopSlateModeWatch(CXenIfaceDevice* device) +{ + if (!m_ctxt_slate_mode) + return; + + device->StoreRemove("control/feature-laptop-slate-mode"); + + device->StoreRemoveWatch(m_ctxt_slate_mode); + m_ctxt_slate_mode = NULL; +} + +void CXenIfaceDeviceList::AcquireShutdownPrivilege() +{ + HANDLE token; + TOKEN_PRIVILEGES tp; + + LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid); + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + tp.PrivilegeCount = 1; + + if (!OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, + &token)) + return; + + AdjustTokenPrivileges(token, FALSE, &tp, NULL, 0, NULL); + CloseHandle(token); +} + +void CXenIfaceDeviceList::SetXenTime(CXenIfaceDevice* device) +{ + bool local; + + FILETIME now = { 0 }; + if (!device->SharedInfoGetTime(&now, &local)) + return; + + SYSTEMTIME cur = { 0 }; + if (local) + GetLocalTime(&cur); + else + GetSystemTime(&cur); + + SYSTEMTIME sys = { 0 }; + if (!FileTimeToSystemTime(&now, &sys)) + return; + + if (memcmp(&cur, &sys, sizeof(SYSTEMTIME)) == 0) + return; + + CXenAgent::Log("RTC is in %s\n", local ? "local time" : "UTC"); + CXenAgent::Log("Time Now = %d/%d/%d %d:%02d:%02d.%d\n", + cur.wYear, cur.wMonth, cur.wDay, + cur.wHour, cur.wMinute, cur.wSecond, cur.wMilliseconds); + CXenAgent::Log("New Time = %d/%d/%d %d:%02d:%02d.%d\n", + sys.wYear, sys.wMonth, sys.wDay, + sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds); + + if (local) + SetLocalTime(&sys); + else + SetSystemTime(&sys); +} diff --git a/src/xenagent/xenifacedevice.h b/src/xenagent/xenifacedevice.h index b89b8b1..dcac685 100644 --- a/src/xenagent/xenifacedevice.h +++ b/src/xenagent/xenifacedevice.h @@ -61,4 +61,47 @@ public: // logging bool Log(const std::string& msg); }; +class CXenAgent; + +class CXenIfaceDeviceList : public CDeviceList +{ +public: + CXenIfaceDeviceList(CXenAgent* agent); + virtual ~CXenIfaceDeviceList(); + +protected: // CDeviceList + virtual CDevice* Create(const wchar_t* path); + virtual void OnDeviceAdded(CDevice* dev); + virtual void OnDeviceRemoved(CDevice* dev); + virtual void OnDeviceSuspend(CDevice* dev); + virtual void OnDeviceResume(CDevice* dev); + +public: + HANDLE m_evt_shutdown; + HANDLE m_evt_suspend; + HANDLE m_evt_slate_mode; + + void Log(const char* message); + bool CheckShutdown(); + void CheckXenTime(); + void CheckSuspend(); + bool CheckSlateMode(std::string& mode); + +private: + void LogIfRebootPending(); + void StartShutdownWatch(CXenIfaceDevice* device); + void StopShutdownWatch(CXenIfaceDevice* device); + void StartSlateModeWatch(CXenIfaceDevice* device); + void StopSlateModeWatch(CXenIfaceDevice* device); + void AcquireShutdownPrivilege(); + void SetXenTime(CXenIfaceDevice* device); + +private: + CXenAgent* m_agent; + DWORD m_count; + void* m_ctxt_suspend; + void* m_ctxt_shutdown; + void* m_ctxt_slate_mode; +}; + #endif -- 2.31.1.windows.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |