Author: ion
Date: Mon Jan 30 02:10:39 2012
New Revision: 55311
URL:
http://svn.reactos.org/svn/reactos?rev=55311&view=rev
Log:
[SMSS2]: Flesh out the _main function in the new SMSS, including the SEH filter and
SmpTerminate support. Instead of launching Winlogon (The "initial command", we
launch the ReactOS SMSS for now -- and kill the system if it is ever terminated, as we
should). We use the right priority, set the right critical flags, use the correct debug
parameters, and acquire/release the correct privileges. Only thing not supported is
launching ntsd if the "Debug Initial Command" global flag is set. I promise to
implement that once someone implements ntsd ;-)
Added:
trunk/reactos/base/system/smss2/crashdmp.c (with props)
trunk/reactos/base/system/smss2/pagefile.c (with props)
trunk/reactos/base/system/smss2/sminit.c (with props)
trunk/reactos/base/system/smss2/smloop.c (with props)
trunk/reactos/base/system/smss2/smsbapi.c (with props)
trunk/reactos/base/system/smss2/smsessn.c (with props)
trunk/reactos/base/system/smss2/smsubsys.c (with props)
trunk/reactos/base/system/smss2/smutil.c (with props)
Modified:
trunk/reactos/base/system/smss2/CMakeLists.txt
trunk/reactos/base/system/smss2/smss.c
trunk/reactos/base/system/smss2/smss.h
Modified: trunk/reactos/base/system/smss2/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/CMakeLis…
==============================================================================
--- trunk/reactos/base/system/smss2/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/CMakeLists.txt [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -2,12 +2,20 @@
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/subsys)
list(APPEND SOURCE
- smss.c
- smss.rc)
+ crashdmp.c
+ pagefile.c
+ sminit.c
+ smloop.c
+ smsbapi.c
+ smsessn.c
+ smsubsys.c
+ smutil.c
+ smss.c
+ smss.rc)
add_executable(smss2 WIN32 ${SOURCE})
-target_link_libraries(smss2 nt)
+target_link_libraries(smss2 nt pseh)
add_pch(smss2 smss.h)
Added: trunk/reactos/base/system/smss2/crashdmp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/crashdmp…
==============================================================================
--- trunk/reactos/base/system/smss2/crashdmp.c (added)
+++ trunk/reactos/base/system/smss2/crashdmp.c [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -1,0 +1,17 @@
+/*
+ * PROJECT: ReactOS Windows-Compatible Session Manager
+ * LICENSE: BSD 2-Clause License
+ * FILE: base/system/smss/smss.c
+ * PURPOSE: Main SMSS Code
+ * PROGRAMMERS: Alex Ionescu
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "smss.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
Propchange: trunk/reactos/base/system/smss2/crashdmp.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/base/system/smss2/pagefile.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/pagefile…
==============================================================================
--- trunk/reactos/base/system/smss2/pagefile.c (added)
+++ trunk/reactos/base/system/smss2/pagefile.c [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -1,0 +1,17 @@
+/*
+ * PROJECT: ReactOS Windows-Compatible Session Manager
+ * LICENSE: BSD 2-Clause License
+ * FILE: base/system/smss/smss.c
+ * PURPOSE: Main SMSS Code
+ * PROGRAMMERS: Alex Ionescu
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "smss.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
Propchange: trunk/reactos/base/system/smss2/pagefile.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/base/system/smss2/sminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/sminit.c…
==============================================================================
--- trunk/reactos/base/system/smss2/sminit.c (added)
+++ trunk/reactos/base/system/smss2/sminit.c [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -1,0 +1,25 @@
+/*
+ * PROJECT: ReactOS Windows-Compatible Session Manager
+ * LICENSE: BSD 2-Clause License
+ * FILE: base/system/smss/smss.c
+ * PURPOSE: Main SMSS Code
+ * PROGRAMMERS: Alex Ionescu
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "smss.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+NTAPI
+SmpInit(IN PUNICODE_STRING InitialCommand,
+ OUT PHANDLE ProcessHandle)
+{
+ return STATUS_SUCCESS;
+}
Propchange: trunk/reactos/base/system/smss2/sminit.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/base/system/smss2/smloop.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smloop.c…
==============================================================================
--- trunk/reactos/base/system/smss2/smloop.c (added)
+++ trunk/reactos/base/system/smss2/smloop.c [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -1,0 +1,17 @@
+/*
+ * PROJECT: ReactOS Windows-Compatible Session Manager
+ * LICENSE: BSD 2-Clause License
+ * FILE: base/system/smss/smss.c
+ * PURPOSE: Main SMSS Code
+ * PROGRAMMERS: Alex Ionescu
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "smss.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
Propchange: trunk/reactos/base/system/smss2/smloop.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/base/system/smss2/smsbapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smsbapi.…
==============================================================================
--- trunk/reactos/base/system/smss2/smsbapi.c (added)
+++ trunk/reactos/base/system/smss2/smsbapi.c [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -1,0 +1,17 @@
+/*
+ * PROJECT: ReactOS Windows-Compatible Session Manager
+ * LICENSE: BSD 2-Clause License
+ * FILE: base/system/smss/smss.c
+ * PURPOSE: Main SMSS Code
+ * PROGRAMMERS: Alex Ionescu
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "smss.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
Propchange: trunk/reactos/base/system/smss2/smsbapi.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/base/system/smss2/smsessn.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smsessn.…
==============================================================================
--- trunk/reactos/base/system/smss2/smsessn.c (added)
+++ trunk/reactos/base/system/smss2/smsessn.c [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -1,0 +1,17 @@
+/*
+ * PROJECT: ReactOS Windows-Compatible Session Manager
+ * LICENSE: BSD 2-Clause License
+ * FILE: base/system/smss/smss.c
+ * PURPOSE: Main SMSS Code
+ * PROGRAMMERS: Alex Ionescu
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "smss.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
Propchange: trunk/reactos/base/system/smss2/smsessn.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/base/system/smss2/smss.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smss.c?r…
==============================================================================
--- trunk/reactos/base/system/smss2/smss.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smss.c [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -27,6 +27,9 @@
ULONG NtInitialUserProcessBufferType = REG_SZ;
UNICODE_STRING NtSystemRoot;
+
+ULONG AttachedSessionId = -1;
+BOOLEAN SmpDebug;
/* FUNCTIONS ******************************************************************/
@@ -176,7 +179,7 @@
(USHORT)Size);
/* Append the DLL path to it */
- RtlAppendUnicodeToString(&Environment, L"Path=" );
+ RtlAppendUnicodeToString(&Environment, L"Path=");
RtlAppendUnicodeStringToString(&Environment, &ProcessParams->DllPath);
RtlAppendUnicodeStringToString(&Environment, &NullString);
@@ -246,19 +249,20 @@
NTSTATUS
NTAPI
-LaunchOldSmss(VOID)
+LaunchOldSmss(OUT PHANDLE Handles)
{
PINIT_BUFFER InitBuffer;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
PRTL_USER_PROCESS_INFORMATION ProcessInfo;
- LARGE_INTEGER Timeout;
NTSTATUS Status;
PCHAR Environment;
- SIZE_T Size;
-
+
+ /* No handles at first */
+ Handles[0] = Handles[1] = NULL;
+
/* Setup system root */
RtlInitUnicodeString(&NtSystemRoot, SharedUserData->NtSystemRoot);
-
+
/* Allocate the initialization buffer */
InitBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(INIT_BUFFER));
if (!InitBuffer)
@@ -266,7 +270,7 @@
/* Bugcheck */
return STATUS_NO_MEMORY;
}
-
+
/* Launch initial process */
ProcessInfo = &InitBuffer->ProcessInfo;
Status = ExpLoadInitialProcess(InitBuffer, &ProcessParameters,
&Environment);
@@ -277,51 +281,223 @@
return Status;
}
- /* Wait 5 seconds for initial process to initialize */
- Timeout.QuadPart = Int32x32To64(5, -10000000);
- Status = ZwWaitForSingleObject(ProcessInfo->ProcessHandle, FALSE, &Timeout);
- if (Status == STATUS_SUCCESS)
- {
- /* Failed, display error */
- DPRINT1("INIT: Session Manager terminated.\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Close process handles */
- ZwClose(ProcessInfo->ThreadHandle);
- ZwClose(ProcessInfo->ProcessHandle);
-
- /* Free the initial process environment */
- Size = 0;
- ZwFreeVirtualMemory(NtCurrentProcess(),
- (PVOID*)&Environment,
- &Size,
- MEM_RELEASE);
-
- /* Free the initial process parameters */
- Size = 0;
- ZwFreeVirtualMemory(NtCurrentProcess(),
- (PVOID*)&ProcessParameters,
- &Size,
- MEM_RELEASE);
- return STATUS_SUCCESS;
+ /* Return the handle and status */
+ Handles[0] = ProcessInfo->ProcessHandle;
+ Handles[1] = ProcessInfo->ProcessHandle;
+ return Status;
}
NTSTATUS
-__cdecl
+NTAPI
+SmpTerminate(IN PULONG_PTR Parameters,
+ IN ULONG ParameterMask,
+ IN ULONG ParameterCount)
+{
+ NTSTATUS Status;
+ BOOLEAN Old;
+ ULONG Response;
+
+ /* Give the shutdown privilege to the thread */
+ if (RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, TRUE, &Old) ==
+ STATUS_NO_TOKEN)
+ {
+ /* Thread doesn't have a token, give it to the entire process */
+ RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &Old);
+ }
+
+ /* Take down the process/machine with a hard error */
+ Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
+ ParameterCount,
+ ParameterMask,
+ Parameters,
+ OptionShutdownSystem,
+ &Response);
+
+ /* Terminate the process if the hard error didn't already */
+ return NtTerminateProcess(NtCurrentProcess(), Status);
+}
+
+LONG
+SmpUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
+{
+ ULONG_PTR Parameters[4];
+ UNICODE_STRING DestinationString;
+
+ /* Print and breakpoint into the debugger */
+ DbgPrint("SMSS: Unhandled exception - Status == %x IP == %x\n",
+ ExceptionInfo->ExceptionRecord->ExceptionCode,
+ ExceptionInfo->ExceptionRecord->ExceptionAddress);
+ DbgPrint(" Memory Address: %x Read/Write: %x\n",
+ ExceptionInfo->ExceptionRecord->ExceptionInformation[0],
+ ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
+ DbgBreakPoint();
+
+ /* Build the hard error and terminate */
+ RtlInitUnicodeString(&DestinationString, L"Unhandled Exception in Session
Manager");
+ Parameters[0] = (ULONG_PTR)&DestinationString;
+ Parameters[1] = ExceptionInfo->ExceptionRecord->ExceptionCode;
+ Parameters[2] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
+ Parameters[3] = (ULONG_PTR)ExceptionInfo->ContextRecord;
+ SmpTerminate(Parameters, 1, RTL_NUMBER_OF(Parameters));
+
+ /* We hould never get here */
+ ASSERT(FALSE);
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+NTSTATUS
_main(IN INT argc,
IN PCHAR argv[],
IN PCHAR envp[],
IN ULONG DebugFlag)
{
NTSTATUS Status;
-
- /* Launch the original SMSS */
- DPRINT1("SMSS-2 Loaded... Launching original SMSS\n");
- Status = LaunchOldSmss();
-
- /* Terminate this SMSS for now, later we'll have an LPC thread running */
- return NtTerminateThread(NtCurrentThread(), Status);
+ KPRIORITY SetBasePriority;
+ ULONG_PTR Parameters[4];
+ HANDLE Handles[2];
+ PVOID State;
+ ULONG Flags;
+ PROCESS_BASIC_INFORMATION ProcessInfo;
+ UNICODE_STRING DbgString, InitialCommand;
+
+ /* Make us critical */
+ RtlSetProcessIsCritical(TRUE, NULL, FALSE);
+ RtlSetThreadIsCritical(TRUE, NULL, FALSE);
+
+ /* Raise our priority */
+ SetBasePriority = 11;
+ Status = NtSetInformationProcess(NtCurrentProcess(),
+ ProcessBasePriority,
+ (PVOID)&SetBasePriority,
+ sizeof(SetBasePriority));
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Save the debug flag if it was passed */
+ if (DebugFlag) SmpDebug = DebugFlag;
+
+ /* Build the hard error parameters */
+ Parameters[0] = (ULONG_PTR)&DbgString;
+ Parameters[1] = Parameters[2] = Parameters[3] = 0;
+
+ /* Enter SEH so we can terminate correctly if anything goes wrong */
+ _SEH2_TRY
+ {
+ /* Initialize SMSS */
+ Status = SmpInit(&InitialCommand, Handles);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SMSS: SmpInit return failure - Status == %x\n");
+ RtlInitUnicodeString(&DbgString, L"Session Manager
Initialization");
+ Parameters[1] = Status;
+ _SEH2_LEAVE;
+ }
+
+ /* Get the global flags */
+ Status = NtQuerySystemInformation(SystemFlagsInformation,
+ &Flags,
+ sizeof(Flags),
+ NULL);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Before executing the initial command check if the debug flag is on */
+ if (Flags & (FLG_DEBUG_INITIAL_COMMAND | FLG_DEBUG_INITIAL_COMMAND_EX))
+ {
+ /* SMSS should launch ntsd with a few parameters at this point */
+ DPRINT1("Global Flags Set to SMSS Debugging: Not yet
supported\n");
+ }
+
+#if 0
+ /* Execute the initial command (Winlogon.exe) */
+ Status = SmpExecuteInitialCommand(0, &InitialCommand, &Handles[1],
NULL);
+#else
+ /* Launch the original SMSS */
+ DPRINT1("SMSS-2 Loaded... Launching original SMSS\n");
+ Status = LaunchOldSmss(Handles);
+#endif
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail and raise a hard error */
+ DPRINT1("SMSS: Execute Initial Command failed\n");
+ RtlInitUnicodeString(&DbgString,
+ L"Session Manager ExecuteInitialCommand");
+ Parameters[1] = Status;
+ _SEH2_LEAVE;
+ }
+
+ /* Check if we're already attached to a session */
+ Status = SmpAcquirePrivilege(SE_LOAD_DRIVER_PRIVILEGE, &State);
+ if (AttachedSessionId != -1)
+ {
+ /* Detach from it, we should be in no session right now */
+ Status = NtSetSystemInformation(SystemSessionDetach,
+ &AttachedSessionId,
+ sizeof(AttachedSessionId));
+ ASSERT(NT_SUCCESS(Status));
+ AttachedSessionId = -1;
+ }
+ SmpReleasePrivilege(State);
+
+ /* Wait on either CSRSS or Winlogon to die */
+ Status = NtWaitForMultipleObjects(RTL_NUMBER_OF(Handles),
+ Handles,
+ WaitAny,
+ FALSE,
+ NULL);
+ if (Status == STATUS_WAIT_0)
+ {
+ /* CSRSS is dead, get exit code and prepare for the hard error */
+ RtlInitUnicodeString(&DbgString, L"Windows SubSystem");
+ Status = NtQueryInformationProcess(Handles[0],
+ ProcessBasicInformation,
+ &ProcessInfo,
+ sizeof(ProcessInfo),
+ NULL);
+ DPRINT1("SMSS: Windows subsystem terminated when it wasn't supposed
to.\n");
+ }
+ else
+ {
+ /* The initial command is dead or we have another failure */
+ RtlInitUnicodeString(&DbgString, L"Windows Logon Process");
+ if (Status == STATUS_WAIT_1)
+ {
+ /* Winlogon.exe got terminated, get its exit code */
+ Status = NtQueryInformationProcess(Handles[1],
+ ProcessBasicInformation,
+ &ProcessInfo,
+ sizeof(ProcessInfo),
+ NULL);
+ }
+ else
+ {
+ /* Something else satisfied our wait, so set the wait status */
+ ProcessInfo.ExitStatus = Status;
+ Status = STATUS_SUCCESS;
+ }
+ DPRINT1("SMSS: Initial command '%wZ' terminated when it
wasn't supposed to.\n",
+ &InitialCommand);
+ }
+
+ /* Check if NtQueryInformationProcess was successful */
+ if (NT_SUCCESS(Status))
+ {
+ /* Then we must have a valid exit status in the structure, use it */
+ Parameters[1] = ProcessInfo.ExitStatus;
+ }
+ else
+ {
+ /* We really don't know what happened, so set a generic error */
+ Parameters[1] = STATUS_UNSUCCESSFUL;
+ }
+ }
+ _SEH2_EXCEPT(SmpUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
+ {
+ /* The filter should never return here */
+ ASSERT(FALSE);
+ }
+ _SEH2_END;
+
+ /* Something in the init loop failed, terminate SMSS */
+ return SmpTerminate(Parameters, 1, RTL_NUMBER_OF(Parameters));
}
/* EOF */
Modified: trunk/reactos/base/system/smss2/smss.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smss.h?r…
==============================================================================
--- trunk/reactos/base/system/smss2/smss.h [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smss.h [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -1,4 +1,53 @@
+/*
+ * PROJECT: ReactOS Windows-Compatible Session Manager
+ * LICENSE: BSD 2-Clause License
+ * FILE: base/system/smss/smss.h
+ * PURPOSE: Main SMSS Header
+ * PROGRAMMERS: Alex Ionescu
+ */
+
+/* DEPENDENCIES ***************************************************************/
+
+//
+// Native Headers
+//
#define WIN32_NO_STATUS
-#include <windows.h>
+#include <windows.h> // Should just be using ntdef.h I think
+#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
+#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A)
+#ifdef ENABLE_RTL_NUMBER_OF_V2
+#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V2(A)
+#else
+#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V1(A)
+#endif
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
+
+//
+// SM Protocol Header
+//
+#include "sm/smmsg.h"
+
+/* DEFINES ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+NTAPI
+SmpInit(
+ IN PUNICODE_STRING InitialCommand,
+ OUT PHANDLE ProcessHandle
+);
+
+NTSTATUS
+NTAPI
+SmpAcquirePrivilege(
+ IN ULONG Privilege,
+ OUT PVOID *PrivilegeStat
+);
+
+VOID
+NTAPI
+SmpReleasePrivilege(
+ IN PVOID State
+);
Added: trunk/reactos/base/system/smss2/smsubsys.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smsubsys…
==============================================================================
--- trunk/reactos/base/system/smss2/smsubsys.c (added)
+++ trunk/reactos/base/system/smss2/smsubsys.c [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -1,0 +1,19 @@
+/*
+ * PROJECT: ReactOS Windows-Compatible Session Manager
+ * LICENSE: BSD 2-Clause License
+ * FILE: base/system/smss/smss.c
+ * PURPOSE: Main SMSS Code
+ * PROGRAMMERS: Alex Ionescu
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "smss.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+/* EOF */
Propchange: trunk/reactos/base/system/smss2/smsubsys.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/base/system/smss2/smutil.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smutil.c…
==============================================================================
--- trunk/reactos/base/system/smss2/smutil.c (added)
+++ trunk/reactos/base/system/smss2/smutil.c [iso-8859-1] Mon Jan 30 02:10:39 2012
@@ -1,0 +1,141 @@
+/*
+ * PROJECT: ReactOS Windows-Compatible Session Manager
+ * LICENSE: BSD 2-Clause License
+ * FILE: base/system/smss/smss.c
+ * PURPOSE: Main SMSS Code
+ * PROGRAMMERS: Alex Ionescu
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "smss.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS ********************************************************************/
+
+typedef struct _SMP_PRIVILEGE_STATE
+{
+ HANDLE TokenHandle;
+ PTOKEN_PRIVILEGES OldPrivileges;
+ PTOKEN_PRIVILEGES NewPrivileges;
+ UCHAR OldBuffer[1024];
+ TOKEN_PRIVILEGES NewBuffer;
+} SMP_PRIVILEGE_STATE, *PSMP_PRIVILEGE_STATE;
+
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+NTAPI
+SmpAcquirePrivilege(IN ULONG Privilege,
+ OUT PVOID *PrivilegeState)
+{
+ PSMP_PRIVILEGE_STATE State;
+ ULONG Size;
+ NTSTATUS Status;
+
+ /* Assume failure */
+ *PrivilegeState = NULL;
+
+ /* Acquire the state structure to hold everything we need */
+ State = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ sizeof(SMP_PRIVILEGE_STATE) +
+ sizeof(TOKEN_PRIVILEGES) +
+ sizeof(LUID_AND_ATTRIBUTES));
+ if (!State) return STATUS_NO_MEMORY;
+
+ /* Open our token */
+ Status = NtOpenProcessToken(NtCurrentProcess(),
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+ &State->TokenHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, State);
+ return Status;
+ }
+
+ /* Set one privilege in the enabled state */
+ State->NewPrivileges = &State->NewBuffer;
+ State->OldPrivileges = (PTOKEN_PRIVILEGES)&State->OldBuffer;
+ State->NewPrivileges->PrivilegeCount = 1;
+ State->NewPrivileges->Privileges[0].Luid = RtlConvertUlongToLuid(Privilege);
+ State->NewPrivileges->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ /* Adjust the privileges in the token */
+ Size = sizeof(State->OldBuffer);
+ Status = NtAdjustPrivilegesToken(State->TokenHandle,
+ FALSE,
+ State->NewPrivileges,
+ Size,
+ State->OldPrivileges,
+ &Size);
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ /* Our static buffer is not big enough, allocate a bigger one */
+ State->OldPrivileges = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
+ if (!State->OldPrivileges)
+ {
+ /* Out of memory, fail */
+ Status = STATUS_NO_MEMORY;
+ goto Quickie;
+ }
+
+ /* Now try again */
+ Status = NtAdjustPrivilegesToken(State->TokenHandle,
+ FALSE,
+ State->NewPrivileges,
+ Size,
+ State->OldPrivileges,
+ &Size);
+ }
+
+ /* Normalize failure code and check for success */
+ if (Status == STATUS_NOT_ALL_ASSIGNED) Status = STATUS_PRIVILEGE_NOT_HELD;
+ if (NT_SUCCESS(Status))
+ {
+ /* We got the privilege, return */
+ *PrivilegeState = State;
+ return STATUS_SUCCESS;
+ }
+
+Quickie:
+ /* Check if we used a dynamic buffer */
+ if (State->OldPrivileges != (PTOKEN_PRIVILEGES)&State->OldBuffer)
+ {
+ /* Free it */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, State->OldPrivileges);
+ }
+
+ /* Close the token handle and free the state structure */
+ NtClose(State->TokenHandle);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, State);
+ return Status;
+}
+
+VOID
+NTAPI
+SmpReleasePrivilege(IN PVOID PrivState)
+{
+ PSMP_PRIVILEGE_STATE State = (PSMP_PRIVILEGE_STATE)PrivState;
+
+ /* Adjust the privileges in the token */
+ NtAdjustPrivilegesToken(State->TokenHandle,
+ FALSE,
+ State->OldPrivileges,
+ 0,
+ NULL,
+ NULL);
+
+ /* Check if we used a dynamic buffer */
+ if (State->OldPrivileges != (PTOKEN_PRIVILEGES)&State->OldBuffer)
+ {
+ /* Free it */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, State->OldPrivileges);
+ }
+
+ /* Close the token handle and free the state structure */
+ NtClose(State->TokenHandle);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, State);
+}
Propchange: trunk/reactos/base/system/smss2/smutil.c
------------------------------------------------------------------------------
svn:eol-style = native