[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.