VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/RTSystemShutdown-win.cpp@ 46727

Last change on this file since 46727 was 39729, checked in by vboxsync, 13 years ago

Acquire the necessary privileges to perform shutdown if need too. Also, don't leak the log message string.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1/* $Id: RTSystemShutdown-win.cpp 39729 2012-01-08 17:29:43Z vboxsync $ */
2/** @file
3 * IPRT - RTSystemShutdown, Windows.
4 */
5
6/*
7 * Copyright (C) 2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <iprt/system.h>
32#include "internal/iprt.h"
33
34#include <iprt/assert.h>
35#include <iprt/err.h>
36#include <iprt/string.h>
37
38#include <Windows.h>
39
40
41RTDECL(int) RTSystemShutdown(RTMSINTERVAL cMsDelay, uint32_t fFlags, const char *pszLogMsg)
42{
43 AssertPtrReturn(pszLogMsg, VERR_INVALID_POINTER);
44 AssertReturn(!(fFlags & ~RTSYSTEM_SHUTDOWN_VALID_MASK), VERR_INVALID_PARAMETER);
45
46 PRTUTF16 pwszLogMsg;
47 int rc = RTStrToUtf16(pszLogMsg, &pwszLogMsg);
48 if (RT_FAILURE(rc))
49 return rc;
50 DWORD cSecsTimeout = (cMsDelay + 499) / 1000;
51 BOOL fRebootAfterShutdown = (fFlags & RTSYSTEM_SHUTDOWN_ACTION_MASK) == RTSYSTEM_SHUTDOWN_REBOOT
52 ? TRUE : FALSE;
53 BOOL fForceAppsClosed = fFlags & RTSYSTEM_SHUTDOWN_FORCE ? TRUE : FALSE;
54
55 /*
56 * Do the
57 */
58 if (InitiateSystemShutdownW(NULL /*pwszMachineName = NULL = localhost*/,
59 pwszLogMsg,
60 cSecsTimeout,
61 fForceAppsClosed,
62 fRebootAfterShutdown))
63 rc = (fFlags & RTSYSTEM_SHUTDOWN_ACTION_MASK) == RTSYSTEM_SHUTDOWN_HALT ? VINF_SYS_MAY_POWER_OFF : VINF_SUCCESS;
64 else
65 {
66 /* If we failed because of missing privileges, try get the right to
67 shut down the system and call the api again. */
68 DWORD dwErr = GetLastError();
69 rc = RTErrConvertFromWin32(dwErr);
70 if (dwErr == ERROR_ACCESS_DENIED)
71 {
72 HANDLE hToken = NULL;
73 if (OpenThreadToken(GetCurrentThread(),
74 TOKEN_ADJUST_PRIVILEGES,
75 TRUE /*OpenAsSelf*/,
76 &hToken))
77 dwErr = NO_ERROR;
78 else
79 {
80 dwErr = GetLastError();
81 if (dwErr == ERROR_NO_TOKEN)
82 {
83 if (OpenProcessToken(GetCurrentProcess(),
84 TOKEN_ADJUST_PRIVILEGES,
85 &hToken))
86 dwErr = NO_ERROR;
87 else
88 dwErr = GetLastError();
89 }
90 }
91
92 if (dwErr == NO_ERROR)
93 {
94 union
95 {
96 TOKEN_PRIVILEGES TokenPriv;
97 char ab[sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES)];
98 } u;
99 u.TokenPriv.PrivilegeCount = 1;
100 u.TokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
101 if (LookupPrivilegeValue(NULL /*localhost*/, SE_SHUTDOWN_NAME, &u.TokenPriv.Privileges[0].Luid))
102 {
103 if (AdjustTokenPrivileges(hToken,
104 FALSE /*DisableAllPrivileges*/,
105 &u.TokenPriv,
106 RT_OFFSETOF(TOKEN_PRIVILEGES, Privileges[1]),
107 NULL,
108 NULL) )
109 {
110 if (InitiateSystemShutdownW(NULL /*pwszMachineName = NULL = localhost*/,
111 pwszLogMsg,
112 cSecsTimeout,
113 fForceAppsClosed,
114 fRebootAfterShutdown))
115 rc = (fFlags & RTSYSTEM_SHUTDOWN_ACTION_MASK) == RTSYSTEM_SHUTDOWN_HALT ? VINF_SYS_MAY_POWER_OFF : VINF_SUCCESS;
116 else
117 {
118 dwErr = GetLastError();
119 rc = RTErrConvertFromWin32(dwErr);
120 }
121 }
122 CloseHandle(hToken);
123 }
124 }
125 }
126 }
127
128 RTUtf16Free(pwszLogMsg);
129 return rc;
130}
131RT_EXPORT_SYMBOL(RTSystemShutdown);
132
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette