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