[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 15/20] Add OnShutdown handler to poweroff/halt/reboot/hibernate/s3 VM
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/liteagent/LiteAgent.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++ src/liteagent/LiteAgent.h | 1 + 2 files changed, 67 insertions(+) diff --git a/src/liteagent/LiteAgent.cpp b/src/liteagent/LiteAgent.cpp index db6c3b9..9f6f56f 100644 --- a/src/liteagent/LiteAgent.cpp +++ b/src/liteagent/LiteAgent.cpp @@ -32,6 +32,8 @@ #define INITGUID #include <windows.h> #include <stdio.h> +#include <powrprof.h> +#include <winuser.h> #include "LiteAgent.h" #include "xeniface_ioctls.h" @@ -308,8 +310,53 @@ void CLiteAgent::OnShutdown() // check shutdown type and enact shutdown std::string type; m_dev->StoreRead("control/shutdown", type); + m_dev->StoreRemove("control/shutdown"); CLiteAgent::Log("OnShutdown(%s)\n", type.c_str()); + + BOOL res; + if (type == "poweroff" || type == "halt") { + AcquireSystemPrivilege(SE_SHUTDOWN_NAME); + m_dev->StoreWrite("control/shutdown-state", "started"); + res = InitiateSystemShutdownEx(NULL, NULL, 0, TRUE, FALSE, + SHTDN_REASON_MAJOR_OTHER | + SHTDN_REASON_MINOR_ENVIRONMENT | + SHTDN_REASON_FLAG_PLANNED); + if (!res) { + m_dev->StoreWrite("control/shutdown-state", "failed"); + CLiteAgent::Log("InitiateSystemShutdownEx failed %08x\n", GetLastError()); + } + } + else if (type == "reboot") { + AcquireSystemPrivilege(SE_SHUTDOWN_NAME); + m_dev->StoreWrite("control/shutdown-state", "started"); + res = InitiateSystemShutdownEx(NULL, NULL, 0, TRUE, TRUE, + SHTDN_REASON_MAJOR_OTHER | + SHTDN_REASON_MINOR_ENVIRONMENT | + SHTDN_REASON_FLAG_PLANNED); + if (!res) { + m_dev->StoreWrite("control/shutdown-state", "failed"); + CLiteAgent::Log("InitiateSystemShutdownEx failed %08x\n", GetLastError()); + } + } + else if (type == "hibernate") { + AcquireSystemPrivilege(SE_SHUTDOWN_NAME); + m_dev->StoreWrite("control/hibernation-state", "started"); + res = SetSystemPowerState(FALSE, FALSE); + if (!res) { + m_dev->StoreWrite("control/hibernation-state", "failed"); + CLiteAgent::Log("SetSystemPowerState failed %08x\n", GetLastError()); + } + } + else if (type == "s3") { + AcquireSystemPrivilege(SE_SHUTDOWN_NAME); + m_dev->StoreWrite("control/s3-state", "started"); + res = SetSuspendState(FALSE, TRUE, FALSE); + if (!res) { + m_dev->StoreWrite("control/s3-state", "failed"); + CLiteAgent::Log("SetSuspendState failed %08x\n", GetLastError()); + } + } } void CLiteAgent::OnSuspend() @@ -444,6 +491,25 @@ done: return match; } +void CLiteAgent::AcquireSystemPrivilege(const char* name) +{ + HANDLE token; + TOKEN_PRIVILEGES tp; + + LookupPrivilegeValue(NULL, 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 CLiteAgent::SetServiceStatus(DWORD state, DWORD exit /*= 0*/, DWORD hint /*= 0*/) { m_status.dwCurrentState = state; diff --git a/src/liteagent/LiteAgent.h b/src/liteagent/LiteAgent.h index e3a2573..5855416 100644 --- a/src/liteagent/LiteAgent.h +++ b/src/liteagent/LiteAgent.h @@ -75,6 +75,7 @@ private: // service events bool HostTimeIsUtc(); void AdjustXenTimeToUtc(FILETIME* now); bool RegMatchStr(const char* path, const char* name, const char* value); + void AcquireSystemPrivilege(const char* name); private: // service support void SetServiceStatus(DWORD state, DWORD exit = 0, DWORD hint = 0); -- 1.9.4.msysgit.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |