Revision 546b60d0

b/qga/commands-win32.c
15 15
#include "qga-qmp-commands.h"
16 16
#include "qerror.h"
17 17

  
18
#ifndef SHTDN_REASON_FLAG_PLANNED
19
#define SHTDN_REASON_FLAG_PLANNED 0x80000000
20
#endif
21

  
18 22
void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
19 23
{
20
    error_set(err, QERR_UNSUPPORTED);
24
    HANDLE token;
25
    TOKEN_PRIVILEGES priv;
26
    UINT shutdown_flag = EWX_FORCE;
27

  
28
    slog("guest-shutdown called, mode: %s", mode);
29

  
30
    if (!has_mode || strcmp(mode, "powerdown") == 0) {
31
        shutdown_flag |= EWX_POWEROFF;
32
    } else if (strcmp(mode, "halt") == 0) {
33
        shutdown_flag |= EWX_SHUTDOWN;
34
    } else if (strcmp(mode, "reboot") == 0) {
35
        shutdown_flag |= EWX_REBOOT;
36
    } else {
37
        error_set(err, QERR_INVALID_PARAMETER_VALUE, "mode",
38
                  "halt|powerdown|reboot");
39
        return;
40
    }
41

  
42
    /* Request a shutdown privilege, but try to shut down the system
43
       anyway. */
44
    if (OpenProcessToken(GetCurrentProcess(),
45
        TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token))
46
    {
47
        LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
48
            &priv.Privileges[0].Luid);
49

  
50
        priv.PrivilegeCount = 1;
51
        priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
52

  
53
        AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, 0);
54
    }
55

  
56
    if (!ExitWindowsEx(shutdown_flag, SHTDN_REASON_FLAG_PLANNED)) {
57
        slog("guest-shutdown failed: %d", GetLastError());
58
        error_set(err, QERR_UNDEFINED_ERROR);
59
    }
21 60
}
22 61

  
23 62
int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, Error **err)

Also available in: Unified diff