qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 7/7] qemu-ga: add win32 guest-shutdown command


From: Michael Roth
Subject: [Qemu-devel] [PATCH 7/7] qemu-ga: add win32 guest-shutdown command
Date: Mon, 23 Jan 2012 08:21:45 -0600

Implement guest-shutdown RPC for Windows. Functionally this should be
equivalent to the posix implementation.

Original patch by Gal Hammer <address@hidden>

Signed-off-by: Michael Roth <address@hidden>
---
 qga/commands-win32.c |   41 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index d96f1ad..4aa0f0d 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -15,9 +15,48 @@
 #include "qga-qmp-commands.h"
 #include "qerror.h"
 
+#ifndef SHTDN_REASON_FLAG_PLANNED
+#define SHTDN_REASON_FLAG_PLANNED 0x80000000
+#endif
+
 void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
 {
-    error_set(err, QERR_UNSUPPORTED);
+    HANDLE token;
+    TOKEN_PRIVILEGES priv;
+    UINT shutdown_flag = EWX_FORCE;
+
+    slog("guest-shutdown called, mode: %s", mode);
+
+    if (!has_mode || strcmp(mode, "powerdown") == 0) {
+        shutdown_flag |= EWX_POWEROFF;
+    } else if (strcmp(mode, "halt") == 0) {
+        shutdown_flag |= EWX_SHUTDOWN;
+    } else if (strcmp(mode, "reboot") == 0) {
+        shutdown_flag |= EWX_REBOOT;
+    } else {
+        error_set(err, QERR_INVALID_PARAMETER_VALUE, "mode",
+                  "halt|powerdown|reboot");
+        return;
+    }
+
+    /* Request a shutdown privilege, but try to shut down the system
+       anyway. */
+    if (OpenProcessToken(GetCurrentProcess(),
+        TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token))
+    {
+        LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
+            &priv.Privileges[0].Luid);
+
+        priv.PrivilegeCount = 1;
+        priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+        AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, 0);
+    }
+
+    if (!ExitWindowsEx(shutdown_flag, SHTDN_REASON_FLAG_PLANNED)) {
+        slog("guest-shutdown failed: %d", GetLastError());
+        error_set(err, QERR_UNDEFINED_ERROR);
+    }
 }
 
 int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, 
Error **err)
-- 
1.7.4.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]