From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:34624) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S0gsn-0004KL-KW for qemu-devel@nongnu.org; Thu, 23 Feb 2012 17:11:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S0gsm-0003Nq-5D for qemu-devel@nongnu.org; Thu, 23 Feb 2012 17:11:25 -0500 Received: from mail-pw0-f45.google.com ([209.85.160.45]:60119) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S0gsl-0003Ky-WC for qemu-devel@nongnu.org; Thu, 23 Feb 2012 17:11:24 -0500 Received: by mail-pw0-f45.google.com with SMTP id ro12so2239875pbb.4 for ; Thu, 23 Feb 2012 14:11:23 -0800 (PST) Sender: fluxion From: Michael Roth Date: Thu, 23 Feb 2012 16:10:55 -0600 Message-Id: <1330035055-29838-9-git-send-email-mdroth@linux.vnet.ibm.com> In-Reply-To: <1330035055-29838-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1330035055-29838-1-git-send-email-mdroth@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 8/8] qemu-ga: add win32 guest-shutdown command List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com Implement guest-shutdown RPC for Windows. Functionally this should be equivalent to the posix implementation. Original patch by Gal Hammer Signed-off-by: Michael Roth --- 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