Author: fireball Date: Sun Dec 13 23:16:41 2015 New Revision: 70343
URL: http://svn.reactos.org/svn/reactos?rev=70343&view=rev Log: [WIN32K] - Add (yet another) shutdown.c file, and import trunk's shutdown code there. Key parts are turned off now. - Enable respective parts in the NtUserSetInformationThread. - Include undocuser.h
Added: branches/arwinss/arwinss/server/include/shutdown.h (with props) branches/arwinss/arwinss/server/main/shutdown.c (with props) Modified: branches/arwinss/arwinss/server/CMakeLists.txt branches/arwinss/arwinss/server/include/win32k.h branches/arwinss/arwinss/server/main/misc.c
Modified: branches/arwinss/arwinss/server/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/branches/arwinss/arwinss/server/CMakeList... ============================================================================== --- branches/arwinss/arwinss/server/CMakeLists.txt [iso-8859-1] (original) +++ branches/arwinss/arwinss/server/CMakeLists.txt [iso-8859-1] Sun Dec 13 23:16:41 2015 @@ -88,6 +88,7 @@ main/kbdlayout.c main/keyboard.c main/misc.c + main/shutdown.c swm/winman.c wine/atom.c wine/class.c
Added: branches/arwinss/arwinss/server/include/shutdown.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/arwinss/server/include/s... ============================================================================== --- branches/arwinss/arwinss/server/include/shutdown.h (added) +++ branches/arwinss/arwinss/server/include/shutdown.h [iso-8859-1] Sun Dec 13 23:16:41 2015 @@ -0,0 +1,9 @@ +#pragma once + +NTSTATUS +UserInitiateShutdown(IN PETHREAD Thread, + IN OUT PULONG pFlags); + +NTSTATUS +UserEndShutdown(IN PETHREAD Thread, + IN NTSTATUS ShutdownStatus);
Propchange: branches/arwinss/arwinss/server/include/shutdown.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: branches/arwinss/arwinss/server/include/win32k.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/arwinss/server/include/w... ============================================================================== --- branches/arwinss/arwinss/server/include/win32k.h [iso-8859-1] (original) +++ branches/arwinss/arwinss/server/include/win32k.h [iso-8859-1] Sun Dec 13 23:16:41 2015 @@ -52,6 +52,9 @@ #include <ntgdihdl.h> #include <ntgdi.h>
+/* Undocumented user definitions */ +#include <undocuser.h> + /* Internal Win32K Header */ #include <win32kp.h>
Modified: branches/arwinss/arwinss/server/main/misc.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/arwinss/server/main/misc... ============================================================================== --- branches/arwinss/arwinss/server/main/misc.c [iso-8859-1] (original) +++ branches/arwinss/arwinss/server/main/misc.c [iso-8859-1] Sun Dec 13 23:16:41 2015 @@ -14,7 +14,7 @@ #include <debug.h>
#include <ntstatus.h> -//#include <shutdown.h> +#include <shutdown.h> #include <csr.h>
extern PEPROCESS CsrProcess; @@ -72,8 +72,7 @@ } _SEH2_END;
- Status = STATUS_NOT_IMPLEMENTED; //UserInitiateShutdown(Thread, &CapturedFlags); - UNIMPLEMENTED; + Status = UserInitiateShutdown(Thread, &CapturedFlags);
/* Return the modified value to the caller */ _SEH2_TRY @@ -115,8 +114,7 @@ } _SEH2_END;
- Status = STATUS_NOT_IMPLEMENTED; //UserEndShutdown(Thread, ShutdownStatus); - UNIMPLEMENTED; + Status = UserEndShutdown(Thread, ShutdownStatus); break; }
Added: branches/arwinss/arwinss/server/main/shutdown.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/arwinss/server/main/shut... ============================================================================== --- branches/arwinss/arwinss/server/main/shutdown.c (added) +++ branches/arwinss/arwinss/server/main/shutdown.c [iso-8859-1] Sun Dec 13 23:16:41 2015 @@ -0,0 +1,265 @@ +/* + * PROJECT: ReactOS Win32K + * LICENSE: GPL - See COPYING in the top level directory + * FILE: server/main/misc.c + * PURPOSE: Shutdown code + * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <win32k.h> + +//#define NDEBUG +#include <debug.h> + +#include <ntstatus.h> + +/* Our local copy of shutdown flags */ +static ULONG gdwShutdownFlags = 0; + +HWND hwndSAS = NULL; + +NTSTATUS +GetProcessLuid(IN PETHREAD Thread OPTIONAL, + OUT PLUID Luid) +{ + NTSTATUS Status; + PACCESS_TOKEN Token; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + BOOLEAN CopyOnOpen, EffectiveOnly; + + if (Thread == NULL) + Thread = PsGetCurrentThread(); + + /* Use a thread token */ + Token = PsReferenceImpersonationToken(Thread, + &CopyOnOpen, + &EffectiveOnly, + &ImpersonationLevel); + if (Token == NULL) + { + /* We don't have a thread token, use a process token */ + Token = PsReferencePrimaryToken(PsGetThreadProcess(Thread)); + + /* If no token, fail */ + if (Token == NULL) + return STATUS_NO_TOKEN; + } + + /* Query the LUID */ + Status = SeQueryAuthenticationIdToken(Token, Luid); + + /* Get rid of the token and return */ + ObDereferenceObject(Token); + return Status; +} + +BOOL +NotifyLogon(IN HWND hWndSta, + IN PLUID CallerLuid, + IN ULONG Flags, + IN NTSTATUS ShutdownStatus) +{ + // LUID SystemLuid = SYSTEM_LUID; + ULONG Notif, Param; + + DPRINT("NotifyLogon(0x%lx, 0x%lx)\n", Flags, ShutdownStatus); + + /* If no Winlogon notifications are needed, just return */ + if (Flags & EWX_NONOTIFY) + return FALSE; + + /* In case we cancelled the shutdown...*/ + if (Flags & EWX_SHUTDOWN_CANCELED) + { + /* ... send a LN_LOGOFF_CANCELED to Winlogon with the real cancel status... */ + Notif = LN_LOGOFF_CANCELED; + Param = ShutdownStatus; + } + else + { + /* ... otherwise it's a real logoff. Send the shutdown flags in that case. */ + Notif = LN_LOGOFF; + Param = Flags; + } + + // FIXME: At the moment, always send the notifications... In real world some checks are done. + // if (hwndSAS && ( (Flags & EWX_SHUTDOWN) || RtlEqualLuid(CallerLuid, &SystemLuid)) ) + if (hwndSAS) + { + DPRINT("\tSending %s, Param 0x%x message to Winlogon\n", Notif == LN_LOGOFF ? "LN_LOGOFF" : "LN_LOGOFF_CANCELED", Param); + //UserPostMessage(hwndSAS, WM_LOGONNOTIFY, Notif, (LPARAM)Param); + UNIMPLEMENTED; + return TRUE; + } + else + { + DPRINT1("hwndSAS == NULL\n"); + } + + return FALSE; +} + + +NTSTATUS +UserInitiateShutdown(IN PETHREAD Thread, + IN OUT PULONG pFlags) +{ + NTSTATUS Status; + ULONG Flags = *pFlags; + LUID CallerLuid; + LUID SystemLuid = SYSTEM_LUID; + /*static PRIVILEGE_SET ShutdownPrivilege = + { + 1, PRIVILEGE_SET_ALL_NECESSARY, + { {{SE_SHUTDOWN_PRIVILEGE, 0}, 0} } + };*/ + + PPROCESSINFO ppi; + + DPRINT("UserInitiateShutdown\n"); + + /* Get the caller's LUID */ + Status = GetProcessLuid(Thread, &CallerLuid); + if (!NT_SUCCESS(Status)) + { + DPRINT1("GetProcessLuid failed\n"); + return Status; + } + + /* + * Check if this is the System LUID, and adjust flags if needed. + * In particular, be sure there is no EWX_CALLER_SYSTEM flag + * spuriously set (could be the sign of malicous app!). + */ + if (RtlEqualLuid(&CallerLuid, &SystemLuid)) + Flags |= EWX_CALLER_SYSTEM; + else + Flags &= ~EWX_CALLER_SYSTEM; + + *pFlags = Flags; + + /* Retrieve the Win32 process info */ + ppi = PsGetProcessWin32Process(PsGetThreadProcess(Thread)); + if (ppi == NULL) + return STATUS_INVALID_HANDLE; + +#if 0 + /* If the caller is not Winlogon, do some security checks */ + if (PsGetThreadProcessId(Thread) != gpidLogon) + { + /* + * Here also, be sure there is no EWX_CALLER_WINLOGON flag + * spuriously set (could be the sign of malicous app!). + */ + Flags &= ~EWX_CALLER_WINLOGON; + + *pFlags = Flags; + + /* Check whether the current process is attached to a window station */ + if (ppi->prpwinsta == NULL) + return STATUS_INVALID_HANDLE; + + /* Check whether the window station of the current process can send exit requests */ + if (!RtlAreAllAccessesGranted(ppi->amwinsta, WINSTA_EXITWINDOWS)) + return STATUS_ACCESS_DENIED; + + /* + * NOTE: USERSRV automatically adds the shutdown flag when we poweroff or reboot. + * + * If the caller wants to shutdown / reboot / power-off... + */ + if (Flags & EWX_SHUTDOWN) + { + /* ... check whether it has shutdown privilege */ + if (!HasPrivilege(&ShutdownPrivilege)) + return STATUS_PRIVILEGE_NOT_HELD; + } + else + { + /* + * ... but if it just wants to log-off, in case its + * window station is a non-IO one, fail the call. + */ + if (ppi->prpwinsta->Flags & WSS_NOIO) + return STATUS_INVALID_DEVICE_REQUEST; + } + } + + /* If the caller is not Winlogon, possibly notify it to perform the real shutdown */ + if (PsGetThreadProcessId(Thread) != gpidLogon) + { + // FIXME: HACK!! Do more checks!! + ERR("UserInitiateShutdown -- Notify Winlogon for shutdown\n"); + NotifyLogon(hwndSAS, &CallerLuid, Flags, STATUS_SUCCESS); + return STATUS_PENDING; + } + + // If we reach this point, that means it's Winlogon that triggered the shutdown. + ERR("UserInitiateShutdown -- Winlogon is doing a shutdown\n"); + + /* + * Update and save the shutdown flags globally for renotifying + * Winlogon if needed, when calling EndShutdown. + */ + Flags |= EWX_CALLER_WINLOGON; // Winlogon is doing a shutdown, be sure the internal flag is set. + *pFlags = Flags; + + /* Save the shutdown flags now */ + gdwShutdownFlags = Flags; +#else + UNIMPLEMENTED; +#endif + return STATUS_SUCCESS; +} + +NTSTATUS +UserEndShutdown(IN PETHREAD Thread, + IN NTSTATUS ShutdownStatus) +{ + NTSTATUS Status; + ULONG Flags; + LUID CallerLuid; + + DPRINT("UserEndShutdown\n"); + + /* + * FIXME: Some cleanup should be done when shutdown succeeds, + * and some reset should be done when shutdown is cancelled. + */ + Status = GetProcessLuid(Thread, &CallerLuid); + if (!NT_SUCCESS(Status)) + { + DPRINT1("GetProcessLuid failed\n"); + return Status; + } + + /* Copy the global flags because we're going to modify them for our purposes */ + Flags = gdwShutdownFlags; + + if (NT_SUCCESS(ShutdownStatus)) + { + /* Just report success, and keep the shutdown flags as they are */ + ShutdownStatus = STATUS_SUCCESS; + } + else + { + /* Report the status to Winlogon and say that we cancel the shutdown */ + Flags |= EWX_SHUTDOWN_CANCELED; + // FIXME: Should we reset gdwShutdownFlags to 0 ?? + } + + DPRINT("UserEndShutdown -- Notify Winlogon for end of shutdown\n"); + +#if 0 + NotifyLogon(hwndSAS, &CallerLuid, Flags, ShutdownStatus); +#else + UNIMPLEMENTED +#endif + + /* Always return success */ + return STATUS_SUCCESS; +} + +/* EOF */
Propchange: branches/arwinss/arwinss/server/main/shutdown.c ------------------------------------------------------------------------------ svn:eol-style = native