ReactOS  0.4.15-dev-341-g17c5fb8
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 }
VOID NTAPI SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:301
_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:2239
VOID NTAPI SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:360
VOID NTAPI SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:336
VOID NTAPI SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:314
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_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:426
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
BOOLEAN NTAPI SePrivilegeCheck(PPRIVILEGE_SET Privileges, PSECURITY_SUBJECT_CONTEXT SubjectContext, KPROCESSOR_MODE PreviousMode)
Definition: priv.c:491
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)
Definition: audit.c:845

Referenced by NtSetInformationProcess(), 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;
29  LRESULT lResult = MCSR_GOODFORSHUTDOWN;
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(WndChild->head.h, WM_QUERYENDSESSION, 0, lParams))
50  {
51  lResult = MCSR_DONOTSHUTDOWN;
52  break;
53  }
54  }
55  else
56  {
57  co_IntSendMessage(WndChild->head.h, 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(pWindow->head.h, WM_QUERYENDSESSION, 0, lParams))
74  {
75  lResult = MCSR_DONOTSHUTDOWN;
76  }
77  }
78  else
79  {
80  co_IntSendMessage(pWindow->head.h, 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 }
#define MCSR_GOODFORSHUTDOWN
Definition: undocuser.h:106
#define MCSR_DONOTSHUTDOWN
Definition: undocuser.h:108
#define TRUE
Definition: types.h:120
#define WM_QUERYENDSESSION
Definition: winuser.h:1604
int32_t INT
Definition: typedefs.h:57
WPARAM wParam
Definition: combotst.c:138
BOOL FASTCALL DestroyTimersForWindow(PTHREADINFO pti, PWND Window)
Definition: timer.c:522
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
unsigned int BOOL
Definition: ntddk_ex.h:94
THRDESKHEAD head
Definition: ntuser.h:659
LONG_PTR LPARAM
Definition: windef.h:208
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
LIST_ENTRY List
Definition: psmgr.c:57
#define WM_ENDSESSION
Definition: winuser.h:1609
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1446
#define MCSR_SHUTDOWNFINISHED
Definition: undocuser.h:107
#define MCS_ENDSESSION
Definition: undocuser.h:103
HWND *FASTCALL IntWinListChildren(PWND Window)
Definition: window.c:255
Definition: ntuser.h:657
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define USERTAG_WINDOWLIST
Definition: tags.h:297
LONG_PTR LRESULT
Definition: windef.h:209
LPARAM lParam
Definition: combotst.c:139
#define MCS_QUERYENDSESSION
Definition: undocuser.h:104

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");
154  UserPostMessage(hwndSAS, WM_LOGONNOTIFY, Notif, (LPARAM)Param);
155  return TRUE;
156  }
157  else
158  {
159  ERR("hwndSAS == NULL\n");
160  }
161 
162  return FALSE;
163 }
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1346
#define TRUE
Definition: types.h:120
#define LN_LOGOFF_CANCELED
Definition: undocuser.h:120
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define LN_LOGOFF
Definition: undocuser.h:113
LONG_PTR LPARAM
Definition: windef.h:208
HWND hwndSAS
Definition: winsta.c:24
#define EWX_SHUTDOWN_CANCELED
Definition: undocuser.h:125
#define TRACE(s)
Definition: solgame.cpp:4
#define EWX_NONOTIFY
Definition: undocuser.h:133
#define WM_LOGONNOTIFY
Definition: undocuser.h:37
#define ERR(fmt,...)
Definition: debug.h:110
unsigned int ULONG
Definition: retypes.h:1

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 }
BOOL NotifyLogon(IN HWND hWndSta, IN PLUID CallerLuid, IN ULONG Flags, IN NTSTATUS ShutdownStatus)
Definition: shutdown.c:121
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
smooth NULL
Definition: ftsmooth.c:416
HWND hwndSAS
Definition: winsta.c:24
#define EWX_SHUTDOWN_CANCELED
Definition: undocuser.h:125
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
static ULONG gdwShutdownFlags
Definition: shutdown.c:14
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:110
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:788
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:3014

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
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");
208  return STATUS_INVALID_HANDLE;
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  */
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");
226  return STATUS_INVALID_HANDLE;
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");
233  return STATUS_ACCESS_DENIED;
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
#define WINSTA_EXITWINDOWS
Definition: winuser.h:413
BOOL NotifyLogon(IN HWND hWndSta, IN PLUID CallerLuid, IN ULONG Flags, IN NTSTATUS ShutdownStatus)
Definition: shutdown.c:121
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
struct _WINSTATION_OBJECT * prpwinsta
Definition: win32.h:258
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define EWX_CALLER_WINLOGON
Definition: undocuser.h:127
PEPROCESS __stdcall PsGetThreadProcess(_In_ PETHREAD Thread)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define EWX_SHUTDOWN
Definition: winuser.h:634
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
#define EWX_CALLER_SYSTEM
Definition: undocuser.h:126
#define WSS_NOIO
Definition: winsta.h:9
smooth NULL
Definition: ftsmooth.c:416
#define SE_SHUTDOWN_PRIVILEGE
Definition: security.c:673
HWND hwndSAS
Definition: winsta.c:24
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
HANDLE NTAPI PsGetThreadProcessId(IN PETHREAD Thread)
Definition: thread.c:745
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
static ULONG gdwShutdownFlags
Definition: shutdown.c:14
#define SYSTEM_LUID
Definition: setypes.h:672
BOOLEAN HasPrivilege(IN PPRIVILEGE_SET Privilege)
Definition: shutdown.c:92
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:110
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:788
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:3014
ACCESS_MASK amwinsta
Definition: win32.h:260
HANDLE gpidLogon
Definition: simplecall.c:15

Referenced by NtUserSetInformationThread().

Variable Documentation

◆ gdwShutdownFlags

ULONG gdwShutdownFlags = 0
static

Definition at line 14 of file shutdown.c.

Referenced by UserEndShutdown(), and UserInitiateShutdown().