ReactOS 0.4.15-dev-8236-g99f0937
shutdown.c File Reference
#include <win32k.h>
Include dependency graph for shutdown.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (UserShutdown)
 
LRESULT IntClientShutdown (IN PWND pWindow, IN WPARAM wParam, IN LPARAM lParam)
 
BOOLEAN HasPrivilege (IN PPRIVILEGE_SET Privilege)
 
BOOL NotifyLogon (IN HWND hWndSta, IN PLUID CallerLuid, IN ULONG Flags, IN NTSTATUS ShutdownStatus)
 
NTSTATUS UserInitiateShutdown (IN PETHREAD Thread, IN OUT PULONG pFlags)
 
NTSTATUS UserEndShutdown (IN PETHREAD Thread, IN NTSTATUS ShutdownStatus)
 

Variables

static ULONG gdwShutdownFlags = 0
 

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserShutdown  )

◆ HasPrivilege()

BOOLEAN HasPrivilege ( IN PPRIVILEGE_SET  Privilege)

Definition at line 92 of file shutdown.c.

93{
96
97 /* Capture and lock the security subject context */
100
101 /* Do privilege check */
103
104 /* Audit the privilege */
105#if 0
108 0,
109 Privilege,
110 Result,
111 UserMode);
112#endif
113
114 /* Unlock and release the security subject context and return */
117 return Result;
118}
unsigned char BOOLEAN
#define NULL
Definition: types.h:112
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2246
#define UserMode
Definition: asm.h:35
VOID NTAPI SePrivilegeObjectAuditAlarm(_In_ HANDLE Handle, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ ACCESS_MASK DesiredAccess, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted, _In_ KPROCESSOR_MODE CurrentMode)
Raises an audit with alarm notification message when an object tries to acquire this privilege.
Definition: audit.c:1321
BOOLEAN NTAPI SePrivilegeCheck(_In_ PPRIVILEGE_SET Privileges, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a set of privileges exist and match within a security subject context.
Definition: priv.c:698
VOID NTAPI SeLockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Locks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:107
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: subject.c:171
VOID NTAPI SeUnlockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Unlocks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:138
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: subject.c:85
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by NtSetInformationProcess(), NtSetInformationThread(), and UserInitiateShutdown().

◆ IntClientShutdown()

LRESULT IntClientShutdown ( IN PWND  pWindow,
IN WPARAM  wParam,
IN LPARAM  lParam 
)

Definition at line 22 of file shutdown.c.

25{
26 LPARAM lParams;
27 BOOL KillTimers;
28 INT i;
30 HWND *List;
31
32 KillTimers = wParam & MCS_ENDSESSION ? TRUE : FALSE;
33 lParams = lParam & (ENDSESSION_LOGOFF | ENDSESSION_CRITICAL | ENDSESSION_CLOSEAPP);
34
35 /* First, send end sessions to children */
36 List = IntWinListChildren(pWindow);
37
38 if (List)
39 {
40 for (i = 0; List[i]; i++)
41 {
42 PWND WndChild;
43
44 if (!(WndChild = UserGetWindowObject(List[i])))
45 continue;
46
48 {
49 if (!co_IntSendMessage(UserHMGetHandle(WndChild), WM_QUERYENDSESSION, 0, lParams))
50 {
51 lResult = MCSR_DONOTSHUTDOWN;
52 break;
53 }
54 }
55 else
56 {
57 co_IntSendMessage(UserHMGetHandle(WndChild), WM_ENDSESSION, KillTimers, lParams);
58 if (KillTimers)
59 {
60 DestroyTimersForWindow(WndChild->head.pti, WndChild);
61 }
62 lResult = MCSR_SHUTDOWNFINISHED;
63 }
64 }
66 if (lResult == MCSR_DONOTSHUTDOWN)
67 return lResult;
68 }
69
70 /* Send to the caller */
72 {
73 if (!co_IntSendMessage(UserHMGetHandle(pWindow), WM_QUERYENDSESSION, 0, lParams))
74 {
75 lResult = MCSR_DONOTSHUTDOWN;
76 }
77 }
78 else
79 {
80 co_IntSendMessage(UserHMGetHandle(pWindow), WM_ENDSESSION, KillTimers, lParams);
81 if (KillTimers)
82 {
83 DestroyTimersForWindow(pWindow->head.pti, pWindow);
84 }
85 lResult = MCSR_SHUTDOWNFINISHED;
86 }
87
88 return lResult;
89}
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
Definition: ntuser.h:694
THRDESKHEAD head
Definition: ntuser.h:695
int32_t INT
Definition: typedefs.h:58
#define MCSR_GOODFORSHUTDOWN
Definition: undocuser.h:108
#define MCS_QUERYENDSESSION
Definition: undocuser.h:106
#define MCSR_SHUTDOWNFINISHED
Definition: undocuser.h:109
#define MCS_ENDSESSION
Definition: undocuser.h:105
#define MCSR_DONOTSHUTDOWN
Definition: undocuser.h:110
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:122
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1445
#define USERTAG_WINDOWLIST
Definition: tags.h:298
BOOL FASTCALL DestroyTimersForWindow(PTHREADINFO pti, PWND Window)
Definition: timer.c:522
HWND *FASTCALL IntWinListChildren(PWND Window)
Definition: window.c:274
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
#define WM_QUERYENDSESSION
Definition: winuser.h:1622
#define WM_ENDSESSION
Definition: winuser.h:1627

Referenced by IntDefWindowProc().

◆ NotifyLogon()

BOOL NotifyLogon ( IN HWND  hWndSta,
IN PLUID  CallerLuid,
IN ULONG  Flags,
IN NTSTATUS  ShutdownStatus 
)

Definition at line 121 of file shutdown.c.

125{
126 // LUID SystemLuid = SYSTEM_LUID;
127 ULONG Notif, Param;
128
129 ERR("NotifyLogon(0x%lx, 0x%lx)\n", Flags, ShutdownStatus);
130
131 /* If no Winlogon notifications are needed, just return */
132 if (Flags & EWX_NONOTIFY)
133 return FALSE;
134
135 /* In case we cancelled the shutdown...*/
137 {
138 /* ... send a LN_LOGOFF_CANCELED to Winlogon with the real cancel status... */
139 Notif = LN_LOGOFF_CANCELED;
140 Param = ShutdownStatus;
141 }
142 else
143 {
144 /* ... otherwise it's a real logoff. Send the shutdown flags in that case. */
145 Notif = LN_LOGOFF;
146 Param = Flags;
147 }
148
149 // FIXME: At the moment, always send the notifications... In real world some checks are done.
150 // if (hwndSAS && ( (Flags & EWX_SHUTDOWN) || RtlEqualLuid(CallerLuid, &SystemLuid)) )
151 if (hwndSAS)
152 {
153 TRACE("\tSending %s message to Winlogon\n", Notif == LN_LOGOFF ? "LN_LOGOFF" : "LN_LOGOFF_CANCELED");
155 return TRUE;
156 }
157 else
158 {
159 ERR("hwndSAS == NULL\n");
160 }
161
162 return FALSE;
163}
#define ERR(fmt,...)
Definition: debug.h:113
HWND hwndSAS
Definition: winsta.c:24
#define TRACE(s)
Definition: solgame.cpp:4
uint32_t ULONG
Definition: typedefs.h:59
#define EWX_SHUTDOWN_CANCELED
Definition: undocuser.h:127
#define EWX_NONOTIFY
Definition: undocuser.h:135
#define WM_LOGONNOTIFY
Definition: undocuser.h:37
#define LN_LOGOFF
Definition: undocuser.h:115
#define LN_LOGOFF_CANCELED
Definition: undocuser.h:122
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1345
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by UserEndShutdown(), and UserInitiateShutdown().

◆ UserEndShutdown()

NTSTATUS UserEndShutdown ( IN PETHREAD  Thread,
IN NTSTATUS  ShutdownStatus 
)

Definition at line 290 of file shutdown.c.

292{
294 ULONG Flags;
295 LUID CallerLuid;
296
297 TRACE("UserEndShutdown called\n");
298
299 /*
300 * FIXME: Some cleanup should be done when shutdown succeeds,
301 * and some reset should be done when shutdown is cancelled.
302 */
303 //STUB;
304
305 Status = GetProcessLuid(Thread, NULL, &CallerLuid);
306 if (!NT_SUCCESS(Status))
307 {
308 ERR("UserEndShutdown: GetProcessLuid failed\n");
309 return Status;
310 }
311
312 /* Copy the global flags because we're going to modify them for our purposes */
314
315 if (NT_SUCCESS(ShutdownStatus))
316 {
317 /* Just report success, and keep the shutdown flags as they are */
318 ShutdownStatus = STATUS_SUCCESS;
319 }
320 else
321 {
322 /* Report the status to Winlogon and say that we cancel the shutdown */
324 // FIXME: Should we reset gdwShutdownFlags to 0 ??
325 }
326
327 TRACE("UserEndShutdown: Notify Winlogon for end of shutdown\n");
328 NotifyLogon(hwndSAS, &CallerLuid, Flags, ShutdownStatus);
329
330 /* Always return success */
331 return STATUS_SUCCESS;
332}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
Status
Definition: gdiplustypes.h:25
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:815
static ULONG gdwShutdownFlags
Definition: shutdown.c:14
BOOL NotifyLogon(IN HWND hWndSta, IN PLUID CallerLuid, IN ULONG Flags, IN NTSTATUS ShutdownStatus)
Definition: shutdown.c:121

Referenced by NtUserSetInformationThread().

◆ UserInitiateShutdown()

NTSTATUS UserInitiateShutdown ( IN PETHREAD  Thread,
IN OUT PULONG  pFlags 
)

Definition at line 166 of file shutdown.c.

168{
170 ULONG Flags = *pFlags;
171 LUID CallerLuid;
172 LUID SystemLuid = SYSTEM_LUID;
173 static PRIVILEGE_SET ShutdownPrivilege =
174 {
176 { {{SE_SHUTDOWN_PRIVILEGE, 0}, 0} }
177 };
178
179 PPROCESSINFO ppi;
180
181 TRACE("UserInitiateShutdown\n");
182
183 /* Get the caller's LUID */
184 Status = GetProcessLuid(Thread, NULL, &CallerLuid);
185 if (!NT_SUCCESS(Status))
186 {
187 ERR("UserInitiateShutdown: GetProcessLuid failed\n");
188 return Status;
189 }
190
191 /*
192 * Check if this is the System LUID, and adjust flags if needed.
193 * In particular, be sure there is no EWX_CALLER_SYSTEM flag
194 * spuriously set (could be the sign of malicous app!).
195 */
196 if (RtlEqualLuid(&CallerLuid, &SystemLuid))
198 else
199 Flags &= ~EWX_CALLER_SYSTEM;
200
201 *pFlags = Flags;
202
203 /* Retrieve the Win32 process info */
205 if (ppi == NULL)
206 {
207 ERR("UserInitiateShutdown: Failed to get win32 thread!\n");
209 }
210
211 /* If the caller is not Winlogon, do some security checks */
213 {
214 /*
215 * Here also, be sure there is no EWX_CALLER_WINLOGON flag
216 * spuriously set (could be the sign of malicous app!).
217 */
218 Flags &= ~EWX_CALLER_WINLOGON;
219
220 *pFlags = Flags;
221
222 /* Check whether the current process is attached to a window station */
223 if (ppi->prpwinsta == NULL)
224 {
225 ERR("UserInitiateShutdown: Process is not attached to a desktop\n");
227 }
228
229 /* Check whether the window station of the current process can send exit requests */
231 {
232 ERR("UserInitiateShutdown: Caller doesn't have the rights to shutdown\n");
234 }
235
236 /*
237 * NOTE: USERSRV automatically adds the shutdown flag when we poweroff or reboot.
238 *
239 * If the caller wants to shutdown / reboot / power-off...
240 */
241 if (Flags & EWX_SHUTDOWN)
242 {
243 /* ... check whether it has shutdown privilege */
244 if (!HasPrivilege(&ShutdownPrivilege))
245 {
246 ERR("UserInitiateShutdown: Caller doesn't have the rights to shutdown\n");
248 }
249 }
250 else
251 {
252 /*
253 * ... but if it just wants to log-off, in case its
254 * window station is a non-IO one, fail the call.
255 */
256 if (ppi->prpwinsta->Flags & WSS_NOIO)
257 {
258 ERR("UserInitiateShutdown: Caller doesn't have the rights to logoff\n");
260 }
261 }
262 }
263
264 /* If the caller is not Winlogon, possibly notify it to perform the real shutdown */
266 {
267 // FIXME: HACK!! Do more checks!!
268 TRACE("UserInitiateShutdown: Notify Winlogon for shutdown\n");
269 NotifyLogon(hwndSAS, &CallerLuid, Flags, STATUS_SUCCESS);
270 return STATUS_PENDING;
271 }
272
273 // If we reach this point, that means it's Winlogon that triggered the shutdown.
274 TRACE("UserInitiateShutdown: Winlogon is doing a shutdown\n");
275
276 /*
277 * Update and save the shutdown flags globally for renotifying
278 * Winlogon if needed, when calling EndShutdown.
279 */
280 Flags |= EWX_CALLER_WINLOGON; // Winlogon is doing a shutdown, be sure the internal flag is set.
281 *pFlags = Flags;
282
283 /* Save the shutdown flags now */
285
286 return STATUS_SUCCESS;
287}
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
PEPROCESS __stdcall PsGetThreadProcess(_In_ PETHREAD Thread)
#define SE_SHUTDOWN_PRIVILEGE
Definition: security.c:673
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
HANDLE NTAPI PsGetThreadProcessId(IN PETHREAD Thread)
Definition: thread.c:745
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_PENDING
Definition: ntstatus.h:82
HANDLE gpidLogon
Definition: simplecall.c:15
ACCESS_MASK amwinsta
Definition: win32.h:268
struct _WINSTATION_OBJECT * prpwinsta
Definition: win32.h:266
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define EWX_CALLER_SYSTEM
Definition: undocuser.h:128
#define EWX_CALLER_WINLOGON
Definition: undocuser.h:129
BOOLEAN HasPrivilege(IN PPRIVILEGE_SET Privilege)
Definition: shutdown.c:92
#define WSS_NOIO
Definition: winsta.h:9
#define EWX_SHUTDOWN
Definition: winuser.h:639
#define WINSTA_EXITWINDOWS
Definition: winuser.h:413
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
#define SYSTEM_LUID
Definition: setypes.h:700
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83

Referenced by NtUserSetInformationThread().

Variable Documentation

◆ gdwShutdownFlags

ULONG gdwShutdownFlags = 0
static

Definition at line 14 of file shutdown.c.

Referenced by UserEndShutdown(), and UserInitiateShutdown().