ReactOS  0.4.15-dev-5459-gb85f005
smss.h File Reference
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
#include <ndk/cmfuncs.h>
#include <ndk/exfuncs.h>
#include <ndk/iofuncs.h>
#include <ndk/kefuncs.h>
#include <ndk/lpcfuncs.h>
#include <ndk/mmfuncs.h>
#include <ndk/obfuncs.h>
#include <ndk/psfuncs.h>
#include <ndk/rtlfuncs.h>
#include <ndk/setypes.h>
#include <ndk/umfuncs.h>
#include <ntstrsafe.h>
#include <sm/smmsg.h>
Include dependency graph for smss.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _SMP_REGISTRY_VALUE
 
struct  _SMP_SUBSYSTEM
 

Macros

#define WIN32_NO_STATUS
 
#define NTOS_MODE_USER
 
#define SMP_DEBUG_FLAG   0x01
 
#define SMP_ASYNC_FLAG   0x02
 
#define SMP_AUTOCHK_FLAG   0x04
 
#define SMP_SUBSYSTEM_FLAG   0x08
 
#define SMP_INVALID_PATH   0x10
 
#define SMP_DEFERRED_FLAG   0x20
 
#define SMP_POSIX_FLAG   0x100
 
#define SMP_OS2_FLAG   0x200
 

Typedefs

typedef struct _SMP_REGISTRY_VALUE SMP_REGISTRY_VALUE
 
typedef struct _SMP_REGISTRY_VALUEPSMP_REGISTRY_VALUE
 
typedef struct _SMP_SUBSYSTEM SMP_SUBSYSTEM
 
typedef struct _SMP_SUBSYSTEMPSMP_SUBSYSTEM
 

Functions

BOOLEAN NTAPI SmpCheckForCrashDump (IN PUNICODE_STRING FileName)
 
VOID NTAPI SmpPagingFileInitialize (VOID)
 
NTSTATUS NTAPI SmpCreatePagingFileDescriptor (IN PUNICODE_STRING PageFileToken)
 
NTSTATUS NTAPI SmpCreatePagingFiles (VOID)
 
VOID NTAPI SmpTranslateSystemPartitionInformation (VOID)
 
NTSTATUS NTAPI SmpCreateSecurityDescriptors (IN BOOLEAN InitialCall)
 
NTSTATUS NTAPI SmpInit (IN PUNICODE_STRING InitialCommand, OUT PHANDLE ProcessHandle)
 
ULONG NTAPI SmpApiLoop (IN PVOID Parameter)
 
NTSTATUS NTAPI SmpSbCreateSession (IN PVOID Reserved, IN PSMP_SUBSYSTEM OtherSubsystem, IN PRTL_USER_PROCESS_INFORMATION ProcessInformation, IN ULONG DbgSessionId, IN PCLIENT_ID DbgUiClientId)
 
BOOLEAN NTAPI SmpCheckDuplicateMuSessionId (IN ULONG MuSessionId)
 
VOID NTAPI SmpDeleteSession (IN ULONG SessionId)
 
ULONG NTAPI SmpAllocateSessionId (IN PSMP_SUBSYSTEM Subsystem, IN PSMP_SUBSYSTEM OtherSubsystem)
 
NTSTATUS NTAPI SmpGetProcessMuSessionId (IN HANDLE ProcessHandle, OUT PULONG SessionId)
 
NTSTATUS NTAPI SmpSetProcessMuSessionId (IN HANDLE ProcessHandle, IN ULONG SessionId)
 
NTSTATUS NTAPI SmpExecuteImage (IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, IN ULONG Flags, IN PRTL_USER_PROCESS_INFORMATION ProcessInformation)
 
NTSTATUS NTAPI SmpExecuteCommand (IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, OUT PHANDLE ProcessId, IN ULONG Flags)
 
NTSTATUS NTAPI SmpExecuteInitialCommand (IN ULONG MuSessionId, IN PUNICODE_STRING InitialCommand, IN HANDLE InitialCommandProcess, OUT PHANDLE ReturnPid)
 
NTSTATUS NTAPI SmpTerminate (IN PULONG_PTR Parameters, IN ULONG ParameterMask, IN ULONG ParameterCount)
 
VOID NTAPI SmpDereferenceSubsystem (IN PSMP_SUBSYSTEM SubSystem)
 
PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByCid (IN PCLIENT_ID ClientId)
 
PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByType (IN ULONG MuSessionId, IN ULONG ImageType)
 
NTSTATUS NTAPI SmpLoadSubSystem (IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, OUT PHANDLE ProcessId, IN ULONG Flags)
 
NTSTATUS NTAPI SmpLoadSubSystemsForMuSession (IN PULONG MuSessionId, OUT PHANDLE ProcessId, IN PUNICODE_STRING InitialCommand)
 
NTSTATUS NTAPI SmpAcquirePrivilege (IN ULONG Privilege, OUT PVOID *PrivilegeStat)
 
VOID NTAPI SmpReleasePrivilege (IN PVOID State)
 
NTSTATUS NTAPI SmpParseCommandLine (IN PUNICODE_STRING CommandLine, OUT PULONG Flags, OUT PUNICODE_STRING FileName, OUT PUNICODE_STRING Directory, OUT PUNICODE_STRING Arguments)
 
BOOLEAN NTAPI SmpQueryRegistrySosOption (VOID)
 
BOOLEAN NTAPI SmpSaveAndClearBootStatusData (OUT PBOOLEAN BootOkay, OUT PBOOLEAN ShutdownOkay)
 
VOID NTAPI SmpRestoreBootStatusData (IN BOOLEAN BootOkay, IN BOOLEAN ShutdownOkay)
 

Variables

RTL_CRITICAL_SECTION SmpKnownSubSysLock
 
LIST_ENTRY SmpKnownSubSysHead
 
RTL_CRITICAL_SECTION SmpSessionListLock
 
LIST_ENTRY SmpSessionListHead
 
ULONG SmpNextSessionId
 
BOOLEAN SmpNextSessionIdScanMode
 
BOOLEAN SmpDbgSsLoaded
 
HANDLE SmpWindowsSubSysProcess
 
HANDLE SmpSessionsObjectDirectory
 
HANDLE SmpWindowsSubSysProcessId
 
BOOLEAN RegPosixSingleInstance
 
UNICODE_STRING SmpDebugKeyword
 
UNICODE_STRING SmpASyncKeyword
 
UNICODE_STRING SmpAutoChkKeyword
 
PVOID SmpHeap
 
ULONG SmBaseTag
 
UNICODE_STRING SmpSystemRoot
 
PWCHAR SmpDefaultEnvironment
 
UNICODE_STRING SmpDefaultLibPath
 
LIST_ENTRY SmpSetupExecuteList
 
LIST_ENTRY SmpSubSystemList
 
LIST_ENTRY SmpSubSystemsToLoad
 
LIST_ENTRY SmpSubSystemsToDefer
 
LIST_ENTRY SmpExecuteList
 
ULONG AttachedSessionId
 
BOOLEAN SmpDebug
 

Macro Definition Documentation

◆ NTOS_MODE_USER

#define NTOS_MODE_USER

Definition at line 24 of file smss.h.

◆ SMP_ASYNC_FLAG

#define SMP_ASYNC_FLAG   0x02

Definition at line 45 of file smss.h.

◆ SMP_AUTOCHK_FLAG

#define SMP_AUTOCHK_FLAG   0x04

Definition at line 46 of file smss.h.

◆ SMP_DEBUG_FLAG

#define SMP_DEBUG_FLAG   0x01

Definition at line 44 of file smss.h.

◆ SMP_DEFERRED_FLAG

#define SMP_DEFERRED_FLAG   0x20

Definition at line 49 of file smss.h.

◆ SMP_INVALID_PATH

#define SMP_INVALID_PATH   0x10

Definition at line 48 of file smss.h.

◆ SMP_OS2_FLAG

#define SMP_OS2_FLAG   0x200

Definition at line 51 of file smss.h.

◆ SMP_POSIX_FLAG

#define SMP_POSIX_FLAG   0x100

Definition at line 50 of file smss.h.

◆ SMP_SUBSYSTEM_FLAG

#define SMP_SUBSYSTEM_FLAG   0x08

Definition at line 47 of file smss.h.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 19 of file smss.h.

Typedef Documentation

◆ PSMP_REGISTRY_VALUE

◆ PSMP_SUBSYSTEM

◆ SMP_REGISTRY_VALUE

◆ SMP_SUBSYSTEM

Function Documentation

◆ SmpAcquirePrivilege()

NTSTATUS NTAPI SmpAcquirePrivilege ( IN ULONG  Privilege,
OUT PVOID PrivilegeStat 
)

Definition at line 40 of file smutil.c.

42 {
44  ULONG Size;
46 
47  /* Assume failure */
48  *PrivilegeState = NULL;
49 
50  /* Acquire the state structure to hold everything we need */
52  0,
53  sizeof(SMP_PRIVILEGE_STATE) +
54  sizeof(TOKEN_PRIVILEGES) +
55  sizeof(LUID_AND_ATTRIBUTES));
56  if (!State) return STATUS_NO_MEMORY;
57 
58  /* Open our token */
61  &State->TokenHandle);
62  if (!NT_SUCCESS(Status))
63  {
64  /* Fail */
66  return Status;
67  }
68 
69  /* Set one privilege in the enabled state */
70  State->NewPrivileges = &State->NewBuffer;
71  State->OldPrivileges = (PTOKEN_PRIVILEGES)&State->OldBuffer;
72  State->NewPrivileges->PrivilegeCount = 1;
73  State->NewPrivileges->Privileges[0].Luid = RtlConvertUlongToLuid(Privilege);
74  State->NewPrivileges->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
75 
76  /* Adjust the privileges in the token */
77  Size = sizeof(State->OldBuffer);
78  Status = NtAdjustPrivilegesToken(State->TokenHandle,
79  FALSE,
80  State->NewPrivileges,
81  Size,
82  State->OldPrivileges,
83  &Size);
85  {
86  /* Our static buffer is not big enough, allocate a bigger one */
87  State->OldPrivileges = RtlAllocateHeap(SmpHeap, 0, Size);
88  if (!State->OldPrivileges)
89  {
90  /* Out of memory, fail */
92  goto Quickie;
93  }
94 
95  /* Now try again */
96  Status = NtAdjustPrivilegesToken(State->TokenHandle,
97  FALSE,
98  State->NewPrivileges,
99  Size,
100  State->OldPrivileges,
101  &Size);
102  }
103 
104  /* Normalize failure code and check for success */
106  if (NT_SUCCESS(Status))
107  {
108  /* We got the privilege, return */
109  *PrivilegeState = State;
110  return STATUS_SUCCESS;
111  }
112 
113 Quickie:
114  /* Check if we used a dynamic buffer */
115  if (State->OldPrivileges != (PTOKEN_PRIVILEGES)&State->OldBuffer)
116  {
117  /* Free it */
118  RtlFreeHeap(SmpHeap, 0, State->OldPrivileges);
119  }
120 
121  /* Close the token handle and free the state structure */
122  NtClose(State->TokenHandle);
124  return Status;
125 }
#define STATUS_NOT_ALL_ASSIGNED
Definition: ntstatus.h:85
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_In_ ULONG _In_ ULONG State
Definition: potypes.h:516
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
NTSTATUS NTAPI NtOpenProcessToken(IN HANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, OUT PHANDLE TokenHandle)
Definition: security.c:350
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
#define FALSE
Definition: types.h:117
PVOID SmpHeap
Definition: sminit.c:25
#define NtCurrentProcess()
Definition: nt_native.h:1657
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
#define TOKEN_QUERY
Definition: setypes.h:924
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FORCEINLINE LUID NTAPI_INLINE RtlConvertUlongToLuid(_In_ ULONG Val)
Definition: rtlfuncs.h:3541
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
struct _TOKEN_PRIVILEGES * PTOKEN_PRIVILEGES
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtAdjustPrivilegesToken(_In_ HANDLE TokenHandle, _In_ BOOLEAN DisableAllPrivileges, _In_opt_ PTOKEN_PRIVILEGES NewState, _In_ ULONG BufferLength, _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState, _When_(PreviousState!=NULL, _Out_) PULONG ReturnLength)
Removes a certain amount of privileges of a token based upon the request by the caller.
Definition: tokenadj.c:451
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:926

Referenced by _main(), SmpLoadSubSystem(), and SmpLoadSubSystemsForMuSession().

◆ SmpAllocateSessionId()

ULONG NTAPI SmpAllocateSessionId ( IN PSMP_SUBSYSTEM  Subsystem,
IN PSMP_SUBSYSTEM  OtherSubsystem 
)

Definition at line 123 of file smsessn.c.

125 {
127  PSMP_SESSION Session;
128 
129  /* Allocate a new ID while under the lock */
132 
133  /* Check for overflow */
135  {
136  /* Break if it happened */
137  UNIMPLEMENTED_DBGBREAK("SMSS: SessionId's Wrapped\n");
138  }
139  else
140  {
141  /* Detect it for next time */
142  if (!SmpNextSessionId)
144  }
145 
146  /* Allocate a session structure */
147  Session = RtlAllocateHeap(SmpHeap, 0, sizeof(SMP_SESSION));
148  if (Session)
149  {
150  /* Write the session data and insert it into the session list */
151  Session->Subsystem = Subsystem;
152  Session->SessionId = SessionId;
153  Session->OtherSubsystem = OtherSubsystem;
155  }
156  else
157  {
158  DPRINT1("SMSS: Unable to keep track of session ID -- no memory available\n");
159  }
160 
161  /* Release the session lock */
163  return SessionId;
164 }
#define TRUE
Definition: types.h:120
PSMP_SUBSYSTEM Subsystem
Definition: smsessn.c:22
ULONG SessionId
Definition: dllmain.c:28
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define InsertTailList(ListHead, Entry)
PVOID SmpHeap
Definition: sminit.c:25
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
LIST_ENTRY SmpSessionListHead
Definition: smsessn.c:27
RTL_CRITICAL_SECTION SmpSessionListLock
Definition: smsessn.c:26
ULONG SessionId
Definition: smsessn.c:21
PSMP_SUBSYSTEM OtherSubsystem
Definition: smsessn.c:23
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define DPRINT1
Definition: precomp.h:8
ULONG SmpNextSessionId
Definition: smsessn.c:28
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY Entry
Definition: smsessn.c:20
BOOLEAN SmpNextSessionIdScanMode
Definition: smsessn.c:29

Referenced by SmpLoadSubSystem(), and SmpSbCreateSession().

◆ SmpApiLoop()

ULONG NTAPI SmpApiLoop ( IN PVOID  Parameter)

Definition at line 423 of file smloop.c.

424 {
428  PSM_API_MSG ReplyMsg = NULL;
429  SM_API_MSG RequestMsg;
430  PROCESS_BASIC_INFORMATION ProcessInformation;
432 
433  /* Increase the number of API threads for throttling code for later */
435 
436  /* Mark us critical */
438 
439  /* Set the PID of the SM process itself for later checking */
442  &ProcessInformation,
443  sizeof(ProcessInformation),
444  NULL);
445  SmUniqueProcessId = (HANDLE)ProcessInformation.UniqueProcessId;
446 
447  /* Now process incoming messages */
448  while (TRUE)
449  {
450  /* Begin waiting on a request */
452  (PVOID*)&ClientContext,
453  &ReplyMsg->h,
454  &RequestMsg.h);
455  if (Status == STATUS_NO_MEMORY)
456  {
457  /* Ran out of memory, so do a little timeout and try again */
458  if (ReplyMsg) DPRINT1("SMSS: Failed to reply to calling thread, retrying.\n");
459  Timeout.QuadPart = -50000000;
461  continue;
462  }
463 
464  /* Check what kind of request we received */
465  switch (RequestMsg.h.u2.s2.Type)
466  {
467  /* A new connection */
469  /* Create the right structures for it */
471  ReplyMsg = NULL;
472  break;
473 
474  /* A closed connection */
475  case LPC_PORT_CLOSED:
476  /* Destroy any state we had for this client */
477  DPRINT1("Port closed\n");
478  //if (ClientContext) SmpPushDeferredClientContext(ClientContext);
479  ReplyMsg = NULL;
480  break;
481 
482  /* An actual API message */
483  default:
484  if (!ClientContext)
485  {
486  ReplyMsg = NULL;
487  break;
488  }
489 
490  RequestMsg.ReturnValue = STATUS_PENDING;
491 
492  /* Check if the API is valid */
493  if (RequestMsg.ApiNumber >= SmpMaxApiNumber)
494  {
495  /* It isn't, fail */
496  DPRINT1("Invalid API: %lx\n", RequestMsg.ApiNumber);
498  }
499  else if ((RequestMsg.ApiNumber <= SmpTerminateForeignSessionApi) &&
500  !(ClientContext->Subsystem))
501  {
502  /* It's valid, but doesn't have a subsystem with it */
503  DPRINT1("Invalid session API\n");
505  }
506  else
507  {
508  /* It's totally okay, so call the dispatcher for it */
509  Status = SmpApiDispatch[RequestMsg.ApiNumber](&RequestMsg,
511  SmApiPort);
512  }
513 
514  /* Write the result value and return the message back */
515  RequestMsg.ReturnValue = Status;
516  ReplyMsg = &RequestMsg;
517  break;
518  }
519  }
520  return STATUS_SUCCESS;
521 }
PORT_MESSAGE h
Definition: smmsg.h:104
NTSTATUS NTAPI SmpHandleConnectionRequest(IN HANDLE SmApiPort, IN PSB_API_MSG SbApiMsg)
Definition: smloop.c:273
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
HANDLE SmApiPort
Definition: smss.c:23
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
_In_ PVOID Parameter
Definition: ldrtypes.h:241
return STATUS_NOT_IMPLEMENTED
HANDLE SmUniqueProcessId
Definition: smloop.c:34
#define FALSE
Definition: types.h:117
NTSYSAPI NTSTATUS __cdecl RtlSetThreadIsCritical(_In_ BOOLEAN NewValue, _Out_opt_ PBOOLEAN OldValue, _In_ BOOLEAN NeedBreaks)
volatile LONG SmTotalApiThreads
Definition: smloop.c:33
PSM_API_HANDLER SmpApiDispatch[SmpMaxApiNumber - SmpCreateForeignSessionApi]
Definition: smloop.c:258
NTSTATUS NTAPI NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
Definition: wait.c:876
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
SMSRV_API_NUMBER ApiNumber
Definition: smmsg.h:105
#define STATUS_PENDING
Definition: ntstatus.h:82
_In_ PVOID ClientContext
Definition: netioddk.h:55
PVOID HANDLE
Definition: typedefs.h:73
NTSTATUS NTAPI NtReplyWaitReceivePort(IN HANDLE PortHandle, OUT PVOID *PortContext OPTIONAL, IN PPORT_MESSAGE ReplyMessage OPTIONAL, OUT PPORT_MESSAGE ReceiveMessage)
Definition: reply.c:743
static ULONG Timeout
Definition: ping.c:61
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define STATUS_SUCCESS
Definition: shellext.h:65
long __cdecl _InterlockedExchangeAdd(_Interlocked_operand_ long volatile *_Addend, long _Value)
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
NTSTATUS ReturnValue
Definition: smmsg.h:106

Referenced by SmpInit().

◆ SmpCheckDuplicateMuSessionId()

BOOLEAN NTAPI SmpCheckDuplicateMuSessionId ( IN ULONG  MuSessionId)

Definition at line 37 of file smsessn.c.

38 {
39  PSMP_SUBSYSTEM Subsystem;
40  BOOLEAN FoundDuplicate = FALSE;
41  PLIST_ENTRY NextEntry;
42 
43  /* Lock the subsystem database */
45 
46  /* Scan each entry */
47  NextEntry = SmpKnownSubSysHead.Flink;
48  while (NextEntry != &SmpKnownSubSysHead)
49  {
50  /* Check if this entry has the same session ID */
51  Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
52  if (Subsystem->MuSessionId == MuSessionId)
53  {
54  /* Break out of here! */
55  FoundDuplicate = TRUE;
56  break;
57  }
58 
59  /* Keep going */
60  NextEntry = NextEntry->Flink;
61  }
62 
63  /* Release the database and return the result */
65  return FoundDuplicate;
66 }
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define FALSE
Definition: types.h:117
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
unsigned char BOOLEAN
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: typedefs.h:119
ULONG MuSessionId
Definition: smss.h:72
base of all file and directory entries
Definition: entries.h:82
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19

Referenced by SmpLoadDeferedSubsystem(), SmpLoadSubSystem(), and SmpSbCreateSession().

◆ SmpCheckForCrashDump()

BOOLEAN NTAPI SmpCheckForCrashDump ( IN PUNICODE_STRING  FileName)

Definition at line 20 of file crashdmp.c.

21 {
22  return FALSE;
23 }
#define FALSE
Definition: types.h:117

Referenced by SmpCreatePagingFileOnFixedDrive().

◆ SmpCreatePagingFileDescriptor()

NTSTATUS NTAPI SmpCreatePagingFileDescriptor ( IN PUNICODE_STRING  PageFileToken)

Definition at line 139 of file pagefile.c.

140 {
142  ULONG MinSize = 0, MaxSize = 0;
143  BOOLEAN SystemManaged = FALSE, ZeroSize = TRUE;
144  PSMP_PAGEFILE_DESCRIPTOR Descriptor, ListDescriptor;
145  ULONG i;
146  WCHAR c;
147  PLIST_ENTRY NextEntry;
148  UNICODE_STRING PageFileName, Arguments, SecondArgument;
149 
150  /* Make sure we don't have too many */
152  {
153  DPRINT1("SMSS:PFILE: Too many paging files specified - %lu\n",
156  }
157 
158  /* Parse the specified and get the name and arguments out of it */
159  DPRINT("SMSS:PFILE: Paging file specifier `%wZ'\n", PageFileToken);
160  Status = SmpParseCommandLine(PageFileToken,
161  NULL,
162  &PageFileName,
163  NULL,
164  &Arguments);
165  if (!NT_SUCCESS(Status))
166  {
167  /* Fail */
168  DPRINT1("SMSS:PFILE: SmpParseCommandLine(%wZ) failed - Status == %lx\n",
169  PageFileToken, Status);
170  return Status;
171  }
172 
173  /* Set the variable to let everyone know we have a pagefile token */
175 
176  /* Parse the arguments, if any */
177  if (Arguments.Buffer)
178  {
179  /* Parse the pagefile size */
180  for (i = 0; i < Arguments.Length / sizeof(WCHAR); i++)
181  {
182  /* Check if it's zero */
183  c = Arguments.Buffer[i];
184  if ((c != L' ') && (c != L'\t') && (c != L'0'))
185  {
186  /* It isn't, break out */
187  ZeroSize = FALSE;
188  break;
189  }
190  }
191  }
192 
193  /* Was a pagefile not specified, or was it specified with no size? */
194  if (!(Arguments.Buffer) || (ZeroSize))
195  {
196  /* In this case, the system will manage its size */
197  SystemManaged = TRUE;
198  }
199  else
200  {
201  /* We do have a size, so convert the arguments into a number */
202  Status = RtlUnicodeStringToInteger(&Arguments, 0, &MinSize);
203  if (!NT_SUCCESS(Status))
204  {
205  /* Fail */
206  RtlFreeUnicodeString(&PageFileName);
207  RtlFreeUnicodeString(&Arguments);
208  return Status;
209  }
210 
211  /* Now advance to the next argument */
212  for (i = 0; i < Arguments.Length / sizeof(WCHAR); i++)
213  {
214  /* Found a space -- second argument must start here */
215  if (Arguments.Buffer[i] == L' ')
216  {
217  /* Use the rest of the arguments as a maximum size */
218  SecondArgument.Buffer = &Arguments.Buffer[i];
219  SecondArgument.Length = (USHORT)(Arguments.Length -
220  i * sizeof(WCHAR));
221  SecondArgument.MaximumLength = (USHORT)(Arguments.MaximumLength -
222  i * sizeof(WCHAR));
223  Status = RtlUnicodeStringToInteger(&SecondArgument, 0, &MaxSize);
224  if (!NT_SUCCESS(Status))
225  {
226  /* Fail */
227  RtlFreeUnicodeString(&PageFileName);
228  RtlFreeUnicodeString(&Arguments);
229  return Status;
230  }
231 
232  break;
233  }
234  }
235  }
236 
237  /* We are done parsing arguments */
238  RtlFreeUnicodeString(&Arguments);
239 
240  /* Now we can allocate our descriptor */
241  Descriptor = RtlAllocateHeap(RtlGetProcessHeap(),
243  sizeof(SMP_PAGEFILE_DESCRIPTOR));
244  if (!Descriptor)
245  {
246  /* Fail if we couldn't */
247  RtlFreeUnicodeString(&PageFileName);
248  return STATUS_NO_MEMORY;
249  }
250 
251  /* Capture all our data into the descriptor */
252  Descriptor->Token = *PageFileToken;
253  Descriptor->Name = PageFileName;
254  Descriptor->MinSize.QuadPart = MinSize * MEGABYTE;
255  Descriptor->MaxSize.QuadPart = MaxSize * MEGABYTE;
256  if (SystemManaged)
260  if (Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == '?')
261  {
263  }
264 
265  /* Now loop the existing descriptors */
267  do
268  {
269  /* Are there none, or have we looped back to the beginning? */
270  if (NextEntry == &SmpPagingFileDescriptorList)
271  {
272  /* This means no duplicates exist, so insert our descriptor! */
275  DPRINT("SMSS:PFILE: Created descriptor for `%wZ' (`%wZ')\n",
276  PageFileToken, &Descriptor->Name);
277  return STATUS_SUCCESS;
278  }
279 
280  /* Keep going until we find a duplicate, unless we are in "any" mode */
281  ListDescriptor = CONTAINING_RECORD(NextEntry, SMP_PAGEFILE_DESCRIPTOR, Entry);
282  NextEntry = NextEntry->Flink;
283  } while (!(ListDescriptor->Flags & SMP_PAGEFILE_ON_ANY_DRIVE) ||
285 
286  /* We found a duplicate, so skip this descriptor/pagefile and fail */
287  DPRINT1("SMSS:PFILE: Skipping duplicate specifier `%wZ'\n", PageFileToken);
288  RtlFreeUnicodeString(&PageFileName);
289  RtlFreeHeap(RtlGetProcessHeap(), 0, Descriptor);
291 }
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:339
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG SmpNumberOfPagingFiles
Definition: pagefile.c:124
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI SmpParseCommandLine(IN PUNICODE_STRING CommandLine, OUT PULONG Flags, OUT PUNICODE_STRING FileName, OUT PUNICODE_STRING Directory, OUT PUNICODE_STRING Arguments)
Definition: smutil.c:233
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define InsertTailList(ListHead, Entry)
#define STATUS_TOO_MANY_PAGING_FILES
Definition: ntstatus.h:387
#define MEGABYTE
Definition: pagefile.c:24
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
Status
Definition: gdiplustypes.h:24
#define MAX_PAGING_FILES
Definition: pagefile.c:23
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
const GLubyte * c
Definition: glext.h:8905
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SMP_PAGEFILE_SYSTEM_MANAGED
Definition: pagefile.c:89
Definition: typedefs.h:119
#define SMP_PAGEFILE_ON_ANY_DRIVE
Definition: pagefile.c:91
#define STANDARD_DRIVE_LETTER_OFFSET
Definition: pagefile.c:22
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 short USHORT
Definition: pedump.c:61
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DPRINT1
Definition: precomp.h:8
LIST_ENTRY SmpPagingFileDescriptorList
Definition: pagefile.c:122
#define c
Definition: ke_i.h:80
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:82
BOOLEAN SmpRegistrySpecifierPresent
Definition: pagefile.c:123

Referenced by SmpLoadDataFromRegistry().

◆ SmpCreatePagingFiles()

NTSTATUS NTAPI SmpCreatePagingFiles ( VOID  )

Definition at line 1049 of file pagefile.c.

1050 {
1051  NTSTATUS Status;
1053  LARGE_INTEGER Size, FuzzFactor;
1054  BOOLEAN Created = FALSE;
1055  PLIST_ENTRY NextEntry;
1056 
1057  /* Check if no paging files were requested */
1059  {
1060  /* The list should be empty -- nothing to do */
1062  DPRINT1("SMSS:PFILE: No paging file was requested\n");
1063  return STATUS_SUCCESS;
1064  }
1065 
1066  /* Initialize the volume descriptors so we can know what's available */
1068  if (!NT_SUCCESS(Status))
1069  {
1070  /* We can't make decisions without this, so fail */
1071  DPRINT1("SMSS:PFILE: Failed to create volume descriptors (status %X)\n",
1072  Status);
1073  return Status;
1074  }
1075 
1076  /* If we fail creating pagefiles, try to reduce by this much each time */
1077  FuzzFactor.QuadPart = FUZZ_FACTOR;
1078 
1079  /* Loop the descriptor list */
1080  NextEntry = SmpPagingFileDescriptorList.Flink;
1081  while (NextEntry != &SmpPagingFileDescriptorList)
1082  {
1083  /* Check what kind of descriptor this is */
1086  {
1087  /* This is a system-managed descriptor. Create the correct file */
1088  DPRINT("SMSS:PFILE: Creating a system managed paging file (`%wZ')\n",
1089  &Descriptor->Name);
1091  if (!NT_SUCCESS(Status))
1092  {
1093  /* We failed -- try again, with size minimization this time */
1094  DPRINT("SMSS:PFILE: Trying lower sizes for (`%wZ')\n",
1095  &Descriptor->Name);
1097  }
1098  }
1099  else
1100  {
1101  /* This is a manually entered descriptor. Validate its size first */
1103 
1104  /* Check if this is an ANY pagefile or a FIXED pagefile */
1105  DPRINT("SMSS:PFILE: Creating a normal paging file (`%wZ')\n",
1106  &Descriptor->Name);
1107  if (Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == L'?')
1108  {
1109  /* It's an any pagefile, try to create it wherever possible */
1110  Size = Descriptor->MinSize;
1112  &FuzzFactor,
1113  &Size);
1114  if (!NT_SUCCESS(Status))
1115  {
1116  /* We failed to create it. Try again with a smaller size */
1117  DPRINT("SMSS:PFILE: Trying lower sizes for (`%wZ')\n",
1118  &Descriptor->Name);
1119  Size.QuadPart = 16 * MEGABYTE;
1121  &FuzzFactor,
1122  &Size);
1123  }
1124  }
1125  else
1126  {
1127  /* It's a fixed pagefile: override the minimum and use ours */
1128  Size.QuadPart = 16 * MEGABYTE;
1130  &FuzzFactor,
1131  &Size);
1132  }
1133  }
1134 
1135  /* Go to the next descriptor */
1136  if (NT_SUCCESS(Status)) Created = TRUE;
1137  NextEntry = NextEntry->Flink;
1138  }
1139 
1140  /* Check if none of the code in our loops above was able to create it */
1141  if (!Created)
1142  {
1143  /* Build an emergency pagefile ourselves */
1144  DPRINT1("SMSS:PFILE: Creating emergency paging file.\n");
1146  }
1147 
1148  /* All done */
1149  return Status;
1150 }
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:339
NTSTATUS NTAPI SmpCreateEmergencyPagingFile(VOID)
Definition: pagefile.c:834
ULONG SmpNumberOfPagingFiles
Definition: pagefile.c:124
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
NTSTATUS NTAPI SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:535
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define MEGABYTE
Definition: pagefile.c:24
NTSTATUS NTAPI SmpCreateSystemManagedPagingFile(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN BOOLEAN DecreaseSize)
Definition: pagefile.c:801
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
NTSTATUS NTAPI SmpCreatePagingFileOnAnyDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:667
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SMP_PAGEFILE_SYSTEM_MANAGED
Definition: pagefile.c:89
Definition: typedefs.h:119
#define STANDARD_DRIVE_LETTER_OFFSET
Definition: pagefile.c:22
#define DPRINT1
Definition: precomp.h:8
LIST_ENTRY SmpPagingFileDescriptorList
Definition: pagefile.c:122
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI SmpValidatePagingFileSizes(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:749
base of all file and directory entries
Definition: entries.h:82
#define FUZZ_FACTOR
Definition: pagefile.c:82
LONGLONG QuadPart
Definition: typedefs.h:114
NTSTATUS NTAPI SmpCreateVolumeDescriptors(VOID)
Definition: pagefile.c:869
BOOLEAN SmpRegistrySpecifierPresent
Definition: pagefile.c:123

Referenced by SmpLoadDataFromRegistry().

◆ SmpCreateSecurityDescriptors()

NTSTATUS NTAPI SmpCreateSecurityDescriptors ( IN BOOLEAN  InitialCall)

Definition at line 975 of file sminit.c.

976 {
978  PSID WorldSid = NULL, AdminSid = NULL, SystemSid = NULL;
979  PSID RestrictedSid = NULL, OwnerSid = NULL;
983  ULONG AclLength, SidLength;
984  PACL Acl;
986  BOOLEAN ProtectionRequired = FALSE;
987 
988  /* Check if this is the first call */
989  if (InitialCall)
990  {
991  /* Create and set the primary descriptor */
997  TRUE,
998  NULL,
999  FALSE);
1001 
1002  /* Create and set the liberal descriptor */
1008  TRUE,
1009  NULL,
1010  FALSE);
1012 
1013  /* Create and set the \KnownDlls descriptor */
1019  TRUE,
1020  NULL,
1021  FALSE);
1023 
1024  /* Create and Set the \ApiPort descriptor */
1030  TRUE,
1031  NULL,
1032  FALSE);
1034  }
1035 
1036  /* Check if protection was requested in the registry (on by default) */
1037  if (SmpProtectionMode & 1) ProtectionRequired = TRUE;
1038 
1039  /* Exit if there's nothing to do */
1040  if (!(InitialCall || ProtectionRequired)) return STATUS_SUCCESS;
1041 
1042  /* Build the world SID */
1045  0, 0, 0, 0, 0, 0, 0,
1046  &WorldSid);
1047  if (!NT_SUCCESS(Status))
1048  {
1049  WorldSid = NULL;
1050  goto Quickie;
1051  }
1052 
1053  /* Build the admin SID */
1057  0, 0, 0, 0, 0, 0,
1058  &AdminSid);
1059  if (!NT_SUCCESS(Status))
1060  {
1061  AdminSid = NULL;
1062  goto Quickie;
1063  }
1064 
1065  /* Build the owner SID */
1066  Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
1068  0, 0, 0, 0, 0, 0, 0,
1069  &OwnerSid);
1070  if (!NT_SUCCESS(Status))
1071  {
1072  OwnerSid = NULL;
1073  goto Quickie;
1074  }
1075 
1076  /* Build the restricted SID */
1079  0, 0, 0, 0, 0, 0, 0,
1080  &RestrictedSid);
1081  if (!NT_SUCCESS(Status))
1082  {
1083  RestrictedSid = NULL;
1084  goto Quickie;
1085  }
1086 
1087  /* Build the system SID */
1090  0, 0, 0, 0, 0, 0, 0,
1091  &SystemSid);
1092  if (!NT_SUCCESS(Status))
1093  {
1094  SystemSid = NULL;
1095  goto Quickie;
1096  }
1097 
1098  /* Now check if we're creating the core descriptors */
1099  if (!InitialCall)
1100  {
1101  /* We're skipping NextAcl so we have to do this here */
1102  SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1103  SidLength *= 2;
1104  goto NotInitial;
1105  }
1106 
1107  /* Allocate an ACL with two ACEs with two SIDs each */
1108  SidLength = RtlLengthSid(SystemSid) + RtlLengthSid(AdminSid);
1109  AclLength = sizeof(ACL) + 2 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1110  Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1111  if (!Acl) Status = STATUS_NO_MEMORY;
1112  if (!NT_SUCCESS(Status)) goto NextAcl;
1113 
1114  /* Now build the ACL and add the two ACEs */
1121 
1122  /* Set this as the DACL */
1124  TRUE,
1125  Acl,
1126  FALSE);
1128 
1129 NextAcl:
1130  /* Allocate an ACL with 6 ACEs, two ACEs per SID */
1131  SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1132  SidLength *= 2;
1133  AclLength = sizeof(ACL) + 6 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1134  Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1135  if (!Acl) Status = STATUS_NO_MEMORY;
1136  if (!NT_SUCCESS(Status)) goto NotInitial;
1137 
1138  /* Now build the ACL and add the six ACEs */
1153 
1154  /* Now edit the last three ACEs and make them inheritable */
1155  Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1158  Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1161  Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1164 
1165  /* Set this as the DACL */
1167  TRUE,
1168  Acl,
1169  FALSE);
1171 
1172 NotInitial:
1173  /* The initial ACLs have been created, are we also protecting objects? */
1174  if (!ProtectionRequired) goto Quickie;
1175 
1176  /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1177  SidLength += RtlLengthSid(OwnerSid);
1178  AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1179  Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1180  if (!Acl) Status = STATUS_NO_MEMORY;
1181  if (!NT_SUCCESS(Status)) goto Quickie;
1182 
1183  /* Build the ACL and add the seven ACEs */
1200 
1201  /* Edit the last 4 ACEs to make then inheritable */
1202  Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1205  Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1208  Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1211  Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1214 
1215  /* Set this as the DACL for the primary SD */
1217  TRUE,
1218  Acl,
1219  FALSE);
1221 
1222  /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1223  AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1224  Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1225  if (!Acl) Status = STATUS_NO_MEMORY;
1226  if (!NT_SUCCESS(Status)) goto Quickie;
1227 
1228  /* Build the ACL and add the seven ACEs */
1245 
1246  /* Edit the last 4 ACEs to make then inheritable */
1247  Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1250  Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1253  Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1256  Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1259 
1260  /* Now set this as the DACL for the liberal SD */
1262  TRUE,
1263  Acl,
1264  FALSE);
1266 
1267 Quickie:
1268  /* Cleanup the SIDs */
1269  if (OwnerSid) RtlFreeHeap(RtlGetProcessHeap(), 0, OwnerSid);
1270  if (AdminSid) RtlFreeHeap(RtlGetProcessHeap(), 0, AdminSid);
1271  if (WorldSid) RtlFreeHeap(RtlGetProcessHeap(), 0, WorldSid);
1272  if (SystemSid) RtlFreeHeap(RtlGetProcessHeap(), 0, SystemSid);
1273  if (RestrictedSid) RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSid);
1274  return Status;
1275 }
#define GENERIC_ALL
Definition: nt_native.h:92
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
SECURITY_DESCRIPTOR SmpPrimarySDBody
Definition: sminit.c:36
PISECURITY_DESCRIPTOR SmpPrimarySecurityDescriptor
Definition: sminit.c:38
static PSID AdminSid
Definition: msgina.c:39
#define TRUE
Definition: types.h:120
PISECURITY_DESCRIPTOR SmpApiPortSecurityDescriptor
Definition: sminit.c:39
SECURITY_DESCRIPTOR SmpKnownDllsSDBody
Definition: sminit.c:36
LONG NTSTATUS
Definition: precomp.h:26
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
NTSYSAPI NTSTATUS NTAPI RtlAllocateAndInitializeSid(IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount, IN ULONG SubAuthority0, IN ULONG SubAuthority1, IN ULONG SubAuthority2, IN ULONG SubAuthority3, IN ULONG SubAuthority4, IN ULONG SubAuthority5, IN ULONG SubAuthority6, IN ULONG SubAuthority7, OUT PSID *Sid)
Definition: sid.c:290
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define FALSE
Definition: types.h:117
PISECURITY_DESCRIPTOR SmpLiberalSecurityDescriptor
Definition: sminit.c:38
#define GENERIC_WRITE
Definition: nt_native.h:90
Definition: card.h:12
unsigned char BOOLEAN
#define ACL_REVISION2
Definition: setypes.h:43
struct _ACL ACL
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:747
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_CREATOR_OWNER_RID
Definition: setypes.h:545
PISECURITY_DESCRIPTOR SmpKnownDllsSecurityDescriptor
Definition: sminit.c:39
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
PSID WorldSid
Definition: globals.c:15
#define GENERIC_READ
Definition: compat.h:135
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define SECURITY_RESTRICTED_CODE_RID
Definition: setypes.h:569
#define NULL
Definition: types.h:112
SECURITY_DESCRIPTOR SmpLiberalSDBody
Definition: sminit.c:36
ULONG SmpProtectionMode
Definition: sminit.c:41
SECURITY_DESCRIPTOR SmpApiPortSDBody
Definition: sminit.c:37
unsigned int ULONG
Definition: retypes.h:1
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define STATUS_SUCCESS
Definition: shellext.h:65
#define GENERIC_EXECUTE
Definition: nt_native.h:91
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
#define OBJECT_INHERIT_ACE
Definition: setypes.h:746
_In_ ULONG AclLength
Definition: rtlfuncs.h:1842
#define SECURITY_CREATOR_SID_AUTHORITY
Definition: setypes.h:533

Referenced by SmpConfigureProtectionMode(), and SmpInit().

◆ SmpDeleteSession()

VOID NTAPI SmpDeleteSession ( IN ULONG  SessionId)

Definition at line 98 of file smsessn.c.

99 {
100  PSMP_SESSION Session;
101 
102  /* Enter the lock and get the session structure */
104  Session = SmpSessionIdToSession(SessionId);
105  if (Session)
106  {
107  /* Remove it from the list */
108  RemoveEntryList(&Session->Entry);
110 
111  /* Now free the structure outside of the lock */
112  RtlFreeHeap(SmpHeap, 0, Session);
113  }
114  else
115  {
116  /* ID doesn't map to one of our structures, nothing to do... */
118  }
119 }
ULONG SessionId
Definition: dllmain.c:28
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PVOID SmpHeap
Definition: sminit.c:25
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
PSMP_SESSION NTAPI SmpSessionIdToSession(IN ULONG SessionId)
Definition: smsessn.c:70
RTL_CRITICAL_SECTION SmpSessionListLock
Definition: smsessn.c:26
LIST_ENTRY Entry
Definition: smsessn.c:20

Referenced by SmpLoadSubSystem(), and SmpSbCreateSession().

◆ SmpDereferenceSubsystem()

VOID NTAPI SmpDereferenceSubsystem ( IN PSMP_SUBSYSTEM  SubSystem)

Definition at line 47 of file smsubsys.c.

48 {
49  /* Acquire the database lock while we (potentially) destroy this subsystem */
51 
52  /* Drop the reference and see if it's terminating */
53  if (!(--SubSystem->ReferenceCount) && (SubSystem->Terminating))
54  {
55  /* Close all handles and free it */
56  if (SubSystem->Event) NtClose(SubSystem->Event);
57  if (SubSystem->ProcessHandle) NtClose(SubSystem->ProcessHandle);
58  if (SubSystem->SbApiPort) NtClose(SubSystem->SbApiPort);
59  RtlFreeHeap(SmpHeap, 0, SubSystem);
60  }
61 
62  /* Release the database lock */
64 }
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
PVOID SmpHeap
Definition: sminit.c:25
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18

Referenced by SmpHandleConnectionRequest(), SmpLoadSubSystem(), and SmpSbCreateSession().

◆ SmpExecuteCommand()

NTSTATUS NTAPI SmpExecuteCommand ( IN PUNICODE_STRING  CommandLine,
IN ULONG  MuSessionId,
OUT PHANDLE  ProcessId,
IN ULONG  Flags 
)

Definition at line 210 of file smss.c.

214 {
216  UNICODE_STRING Arguments, Directory, FileName;
217 
218  /* There's no longer a debugging subsystem */
219  if (Flags & SMP_DEBUG_FLAG) return STATUS_SUCCESS;
220 
221  /* Parse the command line to see what execution flags are requested */
222  Status = SmpParseCommandLine(CommandLine,
223  &Flags,
224  &FileName,
225  &Directory,
226  &Arguments);
227  if (!NT_SUCCESS(Status))
228  {
229  /* Fail if we couldn't do that */
230  DPRINT1("SMSS: SmpParseCommandLine( %wZ ) failed - Status == %lx\n",
231  CommandLine, Status);
232  return Status;
233  }
234 
235  /* Check if autochk is requested */
236  if (Flags & SMP_AUTOCHK_FLAG)
237  {
238  /* Run it */
239  Status = SmpInvokeAutoChk(&FileName, &Directory, &Arguments, Flags);
240  }
241  else if (Flags & SMP_SUBSYSTEM_FLAG)
242  {
244  &Directory,
245  CommandLine,
246  MuSessionId,
247  ProcessId,
248  Flags);
249  }
250  else if (Flags & SMP_INVALID_PATH)
251  {
252  /* An invalid image was specified, fail */
253  DPRINT1("SMSS: Image file (%wZ) not found\n", &FileName);
255  }
256  else
257  {
258  /* An actual image name was present, execute it */
260  &Directory,
261  CommandLine,
262  MuSessionId,
263  Flags,
264  NULL);
265  }
266 
267  /* Free all the token parameters */
268  if (FileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
269  if (Directory.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Directory.Buffer);
270  if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);
271 
272  /* Return to the caller */
273  if (!NT_SUCCESS(Status))
274  {
275  DPRINT1("SMSS: Command '%wZ' failed - Status == %x\n",
276  CommandLine, Status);
277  }
278  return Status;
279 }
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2709
#define SMP_AUTOCHK_FLAG
Definition: smss.h:46
NTSTATUS NTAPI SmpParseCommandLine(IN PUNICODE_STRING CommandLine, OUT PULONG Flags, OUT PUNICODE_STRING FileName, OUT PUNICODE_STRING Directory, OUT PUNICODE_STRING Arguments)
Definition: smutil.c:233
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
NTSTATUS NTAPI SmpInvokeAutoChk(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING Arguments, IN ULONG Flags)
Definition: smss.c:149
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SMP_INVALID_PATH
Definition: smss.h:48
struct _FileName FileName
Definition: fatprocs.h:893
NTSTATUS NTAPI SmpLoadSubSystem(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, OUT PHANDLE ProcessId, IN ULONG Flags)
Definition: smsubsys.c:138
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define SMP_DEBUG_FLAG
Definition: smss.h:44
#define SMP_SUBSYSTEM_FLAG
Definition: smss.h:47
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI SmpExecuteImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, IN ULONG Flags, IN PRTL_USER_PROCESS_INFORMATION ProcessInformation)
Definition: smss.c:30
base for all directory entries
Definition: entries.h:138
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3926

Referenced by SmpLoadDataFromRegistry(), SmpLoadDeferedSubsystem(), and SmpLoadSubSystemsForMuSession().

◆ SmpExecuteImage()

NTSTATUS NTAPI SmpExecuteImage ( IN PUNICODE_STRING  FileName,
IN PUNICODE_STRING  Directory,
IN PUNICODE_STRING  CommandLine,
IN ULONG  MuSessionId,
IN ULONG  Flags,
IN PRTL_USER_PROCESS_INFORMATION  ProcessInformation 
)

Definition at line 30 of file smss.c.

36 {
39  RTL_USER_PROCESS_INFORMATION LocalProcessInfo;
40  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
41 
42  /* Use the input process information if we have it, otherwise use local */
43  ProcessInfo = ProcessInformation;
44  if (!ProcessInfo) ProcessInfo = &LocalProcessInfo;
45 
46  /* Create parameters for the target process */
47  Status = RtlCreateProcessParameters(&ProcessParameters,
48  FileName,
51  Directory,
52  CommandLine,
54  NULL,
55  NULL,
56  NULL,
57  0);
58  if (!NT_SUCCESS(Status))
59  {
60  /* This is a pretty bad failure. ASSERT on checked builds and exit */
61  ASSERTMSG("RtlCreateProcessParameters failed.\n", NT_SUCCESS(Status));
62  DPRINT1("SMSS: RtlCreateProcessParameters failed for %wZ - Status == %lx\n",
63  FileName, Status);
64  return Status;
65  }
66 
67  /* Set the size field as required */
68  ProcessInfo->Size = sizeof(*ProcessInfo);
69 
70  /* Check if the debug flag was requested */
71  if (Flags & SMP_DEBUG_FLAG)
72  {
73  /* Write it in the process parameters */
74  ProcessParameters->DebugFlags = 1;
75  }
76  else
77  {
78  /* Otherwise inherit the flag that was passed to SMSS itself */
79  ProcessParameters->DebugFlags = SmpDebug;
80  }
81 
82  /* Subsystems get the first 1MB of memory reserved for DOS/IVT purposes */
84  {
85  ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
86  }
87 
88  /* And always force NX for anything that SMSS launches */
89  ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_NX;
90 
91  /* Now create the process in suspended state */
94  ProcessParameters,
95  NULL,
96  NULL,
97  NULL,
98  FALSE,
99  NULL,
100  NULL,
101  ProcessInfo);
102  RtlDestroyProcessParameters(ProcessParameters);
103  if (!NT_SUCCESS(Status))
104  {
105  /* If we couldn't create it, fail back to the caller */
106  DPRINT1("SMSS: Failed load of %wZ - Status == %lx\n",
107  FileName, Status);
108  return Status;
109  }
110 
111  /* Associate a session with this process */
112  Status = SmpSetProcessMuSessionId(ProcessInfo->ProcessHandle, MuSessionId);
113 
114  /* If the application is deferred (suspended), there's nothing to do */
115  if (Flags & SMP_DEFERRED_FLAG) return Status;
116 
117  /* Otherwise, get ready to start it, but make sure it's a native app */
119  {
120  /* Resume it */
121  NtResumeThread(ProcessInfo->ThreadHandle, NULL);
122  if (!(Flags & SMP_ASYNC_FLAG))
123  {
124  /* Block on it unless Async was requested */
126  }
127 
128  /* It's up and running now, close our handles */
129  NtClose(ProcessInfo->ThreadHandle);
130  NtClose(ProcessInfo->ProcessHandle);
131  }
132  else
133  {
134  /* This image is invalid, so kill it, close our handles, and fail */
136  NtTerminateProcess(ProcessInfo->ProcessHandle, Status);
138  NtClose(ProcessInfo->ThreadHandle);
139  NtClose(ProcessInfo->ProcessHandle);
140  DPRINT1("SMSS: Not an NT image - %wZ\n", FileName);
141  }
142 
143  /* Return the outcome of the process create */
144  return Status;
145 }
NTSYSAPI NTSTATUS NTAPI RtlCreateProcessParameters(_Out_ PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, _In_ PUNICODE_STRING ImagePathName, _In_opt_ PUNICODE_STRING DllPath, _In_opt_ PUNICODE_STRING CurrentDirectory, _In_opt_ PUNICODE_STRING CommandLine, _In_opt_ PWSTR Environment, _In_opt_ PUNICODE_STRING WindowTitle, _In_opt_ PUNICODE_STRING DesktopInfo, _In_opt_ PUNICODE_STRING ShellInfo, _In_opt_ PUNICODE_STRING RuntimeInfo)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
UNICODE_STRING SmpDefaultLibPath
Definition: sminit.c:29
#define RTL_USER_PROCESS_PARAMETERS_NX
Definition: rtltypes.h:55
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlDestroyProcessParameters(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
NTSTATUS NTAPI SmpSetProcessMuSessionId(IN HANDLE ProcessHandle, IN ULONG SessionId)
Definition: smsessn.c:199
#define FALSE
Definition: types.h:117
PWCHAR SmpDefaultEnvironment
Definition: sminit.c:28
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define IMAGE_SUBSYSTEM_NATIVE
Definition: ntimage.h:436
NTSYSAPI NTSTATUS NTAPI RtlCreateUserProcess(_In_ PUNICODE_STRING ImageFileName, _In_ ULONG Attributes, _In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters, _In_opt_ PSECURITY_DESCRIPTOR ProcessSecutityDescriptor, _In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, _In_opt_ HANDLE ParentProcess, _In_ BOOLEAN CurrentDirectory, _In_opt_ HANDLE DebugPort, _In_opt_ HANDLE ExceptionPort, _Out_ PRTL_USER_PROCESS_INFORMATION ProcessInfo)
Status
Definition: gdiplustypes.h:24
SECTION_IMAGE_INFORMATION ImageInformation
Definition: rtltypes.h:1573
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
#define RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB
Definition: rtltypes.h:46
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define SMP_ASYNC_FLAG
Definition: smss.h:45
BOOLEAN SmpDebug
Definition: smss.c:22
#define SMP_DEBUG_FLAG
Definition: smss.h:44
#define SMP_SUBSYSTEM_FLAG
Definition: smss.h:47
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
base for all directory entries
Definition: entries.h:138
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define SMP_DEFERRED_FLAG
Definition: smss.h:49
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

Referenced by SmpExecuteCommand(), SmpExecuteInitialCommand(), SmpInvokeAutoChk(), and SmpLoadSubSystem().

◆ SmpExecuteInitialCommand()

NTSTATUS NTAPI SmpExecuteInitialCommand ( IN ULONG  MuSessionId,
IN PUNICODE_STRING  InitialCommand,
IN HANDLE  InitialCommandProcess,
OUT PHANDLE  ReturnPid 
)

Definition at line 283 of file smss.c.

287 {
289  RTL_USER_PROCESS_INFORMATION ProcessInfo;
290  UNICODE_STRING Arguments, Directory, FileName;
291  ULONG Flags = 0;
292 
293  /* Check if we haven't yet connected to ourselves */
294  if (!SmApiPort)
295  {
296  /* Connect to ourselves, as a client */
298  if (!NT_SUCCESS(Status))
299  {
300  DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status);
301  return Status;
302  }
303  }
304 
305  /* Parse the initial command line */
306  Status = SmpParseCommandLine(InitialCommand,
307  &Flags,
308  &FileName,
309  &Directory,
310  &Arguments);
311  if (Flags & SMP_INVALID_PATH)
312  {
313  /* Fail if it doesn't exist */
314  DPRINT1("SMSS: Initial command image (%wZ) not found\n", &FileName);
315  if (FileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
317  }
318 
319  /* And fail if any other reason is also true */
320  if (!NT_SUCCESS(Status))
321  {
322  DPRINT1("SMSS: SmpParseCommandLine( %wZ ) failed - Status == %lx\n",
323  InitialCommand, Status);
324  return Status;
325  }
326 
327  /* Execute the initial command, but defer its full execution */
329  &Directory,
330  InitialCommand,
331  MuSessionId,
333  &ProcessInfo);
334 
335  /* Free all the token parameters */
336  if (FileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
337  if (Directory.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Directory.Buffer);
338  if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);
339 
340  /* Bail out if we couldn't execute the initial command */
341  if (!NT_SUCCESS(Status)) return Status;
342 
343  /* Now duplicate the handle to this process */
345  ProcessInfo.ProcessHandle,
347  InitialCommandProcess,
349  0,
350  0);
351  if (!NT_SUCCESS(Status))
352  {
353  /* Kill it utterly if duplication failed */
354  DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status);
356  NtResumeThread(ProcessInfo.ThreadHandle, NULL);
357  NtClose(ProcessInfo.ThreadHandle);
358  NtClose(ProcessInfo.ProcessHandle);
359  return Status;
360  }
361 
362  /* Return PID to the caller, and set this as the initial command PID */
363  if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess;
364  if (!MuSessionId) SmpInitialCommandProcessId = ProcessInfo.ClientId.UniqueProcess;
365 
366  /* Now call our server execution function to wrap up its initialization */
367  Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE);
368  if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == %lx\n", Status);
369  return Status;
370 }
HANDLE SmpInitialCommandProcessId
Definition: smss.c:24
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
HANDLE SmApiPort
Definition: smss.c:23
NTSTATUS NTAPI SmpParseCommandLine(IN PUNICODE_STRING CommandLine, OUT PULONG Flags, OUT PUNICODE_STRING FileName, OUT PUNICODE_STRING Directory, OUT PUNICODE_STRING Arguments)
Definition: smutil.c:233
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
HANDLE UniqueProcess
Definition: compat.h:825
NTSTATUS NTAPI SmExecPgm(_In_ HANDLE SmApiPort, _In_ PRTL_USER_PROCESS_INFORMATION ProcessInformation, _In_ BOOLEAN DebugFlag)
Requests the SM to start a process under a new environment session.
Definition: smclient.c:265
#define FALSE
Definition: types.h:117
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define SMP_INVALID_PATH
Definition: smss.h:48
struct _FileName FileName
Definition: fatprocs.h:893
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
NTSTATUS NTAPI SmpExecuteImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, IN ULONG Flags, IN PRTL_USER_PROCESS_INFORMATION ProcessInformation)
Definition: smss.c:30
unsigned int ULONG
Definition: retypes.h:1
base for all directory entries
Definition: entries.h:138
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define SMP_DEFERRED_FLAG
Definition: smss.h:49
NTSTATUS NTAPI SmConnectToSm(_In_opt_ PUNICODE_STRING SbApiPortName, _In_opt_ HANDLE SbApiPort, _In_opt_ ULONG ImageType, _Out_ PHANDLE SmApiPort)
Connects to the SM API port for registering a session callback port (Sb) associated to a subsystem,...
Definition: smclient.c:57
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3926

Referenced by _main(), and SmpStartCsr().

◆ SmpGetProcessMuSessionId()

NTSTATUS NTAPI SmpGetProcessMuSessionId ( IN HANDLE  ProcessHandle,
OUT PULONG  SessionId 
)

Definition at line 168 of file smsessn.c.

170 {
172  ULONG ProcessSession;
173 
174  /* Query the kernel for the session ID */
177  &ProcessSession,
178  sizeof(ProcessSession),
179  NULL);
180  if (NT_SUCCESS(Status))
181  {
182  /* Copy it back into the buffer */
183  *SessionId = ProcessSession;
184  }
185  else
186  {
187  /* Failure -- assume session zero */
188  DPRINT1("SMSS: GetProcessMuSessionId, Process=%p, Status=%x\n",
190  *SessionId = 0;
191  }
192 
193  /* Return result */
194  return Status;
195 }
ULONG SessionId
Definition: dllmain.c:28
LONG NTSTATUS
Definition: precomp.h:26
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59

Referenced by SmpHandleConnectionRequest(), SmpLoadDeferedSubsystem(), and SmpSbCreateSession().

◆ SmpInit()

NTSTATUS NTAPI SmpInit ( IN PUNICODE_STRING  InitialCommand,
OUT PHANDLE  ProcessHandle 
)

Definition at line 2449 of file sminit.c.

2451 {
2452  NTSTATUS Status, Status2;
2454  UNICODE_STRING PortName, EventName;
2455  HANDLE EventHandle, PortHandle;
2456  ULONG HardErrorMode;
2457 
2458  /* Create the SMSS Heap */
2459  SmBaseTag = RtlCreateTagHeap(RtlGetProcessHeap(),
2460  0,
2461  L"SMSS!",
2462  L"INIT");
2463  SmpHeap = RtlGetProcessHeap();
2464 
2465  /* Enable hard errors */
2466  HardErrorMode = TRUE;
2469  &HardErrorMode,
2470  sizeof(HardErrorMode));
2471 
2472  /* Initialize the subsystem list and the session list, plus their locks */
2477 
2478  /* Initialize the process list */
2480 
2481  /* Initialize session parameters */
2482  SmpNextSessionId = 1;
2485 
2486  /* Create the initial security descriptors */
2488  if (!NT_SUCCESS(Status))
2489  {
2490  /* Fail */
2492  return Status;
2493  }
2494 
2495  /* Initialize subsystem names */
2496  RtlInitUnicodeString(&SmpSubsystemName, L"NT-Session Manager");
2497  RtlInitUnicodeString(&PosixName, L"POSIX");
2498  RtlInitUnicodeString(&Os2Name, L"OS2");
2499 
2500  /* Create the SM API Port */
2501  RtlInitUnicodeString(&PortName, L"\\SmApiPort");
2503  Status = NtCreatePort(&PortHandle,
2505  sizeof(SB_CONNECTION_INFO),
2506  sizeof(SM_API_MSG),
2507  sizeof(SB_API_MSG) * 32);
2509  SmpDebugPort = PortHandle;
2510 
2511  /* Create two SM API threads */
2513  NULL,
2514  FALSE,
2515  0,
2516  0,
2517  0,
2518  SmpApiLoop,
2519  PortHandle,
2520  NULL,
2521  NULL);
2524  NULL,
2525  FALSE,
2526  0,
2527  0,
2528  0,
2529  SmpApiLoop,
2530  PortHandle,
2531  NULL,
2532  NULL);
2534 
2535  /* Create the write event that autochk can set after running */
2536  RtlInitUnicodeString(&EventName, L"\\Device\\VolumesSafeForWriteAccess");
2538  &EventName,
2539  OBJ_PERMANENT,
2540  NULL,
2541  NULL);
2542  Status2 = NtCreateEvent(&EventHandle,
2545  0,
2546  0);
2547  if (!NT_SUCCESS(Status2))
2548  {
2549  /* Should never really fail */
2550  DPRINT1("SMSS: Unable to create %wZ event - Status == %lx\n",
2551  &EventName, Status2);
2552  ASSERT(NT_SUCCESS(Status2));
2553  }
2554 
2555  /* Now initialize everything else based on the registry parameters */
2556  Status = SmpLoadDataFromRegistry(InitialCommand);
2557  if (NT_SUCCESS(Status))
2558  {
2559  /* Autochk should've run now. Set the event and save the CSRSS handle */
2563  }
2564 
2565  /* All done */
2566  return Status;
2567 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define SMSS_CHECKPOINT(x, y)
Definition: sminit.c:44
UNICODE_STRING PosixName
Definition: sminit.c:18
#define TRUE
Definition: types.h:120
PISECURITY_DESCRIPTOR SmpApiPortSecurityDescriptor
Definition: sminit.c:39
HANDLE SmpWindowsSubSysProcess
Definition: smsubsys.c:20
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
ULONG NTAPI SmpApiLoop(IN PVOID Parameter)
Definition: smloop.c:423
LIST_ENTRY NativeProcessList
Definition: sminit.c:23
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
PVOID SmpHeap
Definition: sminit.c:25
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtCreatePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:212
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG SmBaseTag
Definition: sminit.c:26
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
HANDLE SmpDebugPort
Definition: sminit.c:27
#define OBJ_PERMANENT
Definition: winternl.h:226
NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread(_In_ PVOID ThreadContext, _Out_ HANDLE *OutThreadHandle, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2, _Reserved_ PVOID Reserved3, _Reserved_ PVOID Reserved4, _Reserved_ PVOID Reserved5, _Reserved_ PVOID Reserved6, _Reserved_ PVOID Reserved7, _Reserved_ PVOID Reserved8)
LIST_ENTRY SmpSessionListHead
Definition: smsessn.c:27
RTL_CRITICAL_SECTION SmpSessionListLock
Definition: smsessn.c:26
BOOLEAN SmpDbgSsLoaded
Definition: smsessn.c:30
UNICODE_STRING SmpSubsystemName
Definition: sminit.c:18
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1105
UNICODE_STRING Os2Name
Definition: sminit.c:18
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI SmpCreateSecurityDescriptors(IN BOOLEAN InitialCall)
Definition: sminit.c:975
ULONG SmpNextSessionId
Definition: smsessn.c:28
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG NTAPI RtlCreateTagHeap(_In_ HANDLE HeapHandle, _In_ ULONG Flags, _In_opt_ PWSTR TagName, _In_ PWSTR TagSubName)
Definition: heap.c:4031
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
NTSTATUS NTAPI SmpLoadDataFromRegistry(OUT PUNICODE_STRING InitialCommand)
Definition: sminit.c:2243
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19
IN PUNICODE_STRING PortName
Definition: conport.c:35
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857
BOOLEAN SmpNextSessionIdScanMode
Definition: smsessn.c:29

Referenced by _main().

◆ SmpLoadSubSystem()

NTSTATUS NTAPI SmpLoadSubSystem ( IN PUNICODE_STRING  FileName,
IN PUNICODE_STRING  Directory,
IN PUNICODE_STRING  CommandLine,
IN ULONG  MuSessionId,
OUT PHANDLE  ProcessId,
IN ULONG  Flags 
)

Definition at line 138 of file smsubsys.c.

144 {
145  PSMP_SUBSYSTEM Subsystem, NewSubsystem, KnownSubsystem = NULL;
146  HANDLE SubSysProcessId;
148  SB_API_MSG SbApiMsg;
149  RTL_USER_PROCESS_INFORMATION ProcessInformation;
151  PVOID State;
152  PSB_CREATE_PROCESS_MSG CreateProcess = &SbApiMsg.u.CreateProcess;
153  PSB_CREATE_SESSION_MSG CreateSession = &SbApiMsg.u.CreateSession;
154 
155  /* Make sure this is a found subsystem */
156  if (Flags & SMP_INVALID_PATH)
157  {
158  DPRINT1("SMSS: Unable to find subsystem - %wZ\n", FileName);
160  }
161 
162  /* Don't use a session if the flag is set */
163  if (Flags & 0x80) MuSessionId = 0;
164 
165  /* Lock the subsystems while we do a look up */
167  while (TRUE)
168  {
169  /* Check if we found a subsystem not yet fully initialized */
170  Subsystem = SmpLocateKnownSubSysByType(MuSessionId, -1);
171  if (!Subsystem) break;
173 
174  /* Wait on it to initialize */
175  NtWaitForSingleObject(Subsystem->Event, FALSE, NULL);
176 
177  /* Dereference it and try the next one */
179  SmpDereferenceSubsystem(Subsystem);
180  }
181 
182  /* Check if this is a POSIX subsystem */
183  if (Flags & SMP_POSIX_FLAG)
184  {
185  /* Do we already have it? */
186  Subsystem = SmpLocateKnownSubSysByType(MuSessionId, IMAGE_SUBSYSTEM_POSIX_CUI);
187  }
188  else if (Flags & SMP_OS2_FLAG)
189  {
190  /* This is an OS/2 subsystem, do we we already have it? */
191  Subsystem = SmpLocateKnownSubSysByType(MuSessionId, IMAGE_SUBSYSTEM_OS2_CUI);
192  }
193 
194  /* Check if we already have one of the optional subsystems for the session */
195  if (Subsystem)
196  {
197  /* Dereference and return, no work to do */
198  SmpDereferenceSubsystem(Subsystem);
200  return STATUS_SUCCESS;
201  }
202 
203  /* Allocate a new subsystem! */
204  NewSubsystem = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_SUBSYSTEM));
205  if (!NewSubsystem)
206  {
208  return STATUS_NO_MEMORY;
209  }
210 
211  /* Initialize its header and reference count */
212  NewSubsystem->ReferenceCount = 1;
213  NewSubsystem->MuSessionId = MuSessionId;
214  NewSubsystem->ImageType = -1;
215 
216  /* Clear out all the other data for now */
217  NewSubsystem->Terminating = FALSE;
218  NewSubsystem->ProcessHandle = NULL;
219  NewSubsystem->Event = NULL;
220  NewSubsystem->PortHandle = NULL;
221  NewSubsystem->SbApiPort = NULL;
222 
223  /* Create the event we'll be waiting on for initialization */
224  Status = NtCreateEvent(&NewSubsystem->Event,
226  NULL,
228  FALSE);
229  if (!NT_SUCCESS(Status))
230  {
231  /* This failed, bail out */
232  RtlFreeHeap(SmpHeap, 0, NewSubsystem);
234  return STATUS_NO_MEMORY;
235  }
236 
237  /* Insert the subsystem and release the lock. It can now be found */
238  InsertTailList(&SmpKnownSubSysHead, &NewSubsystem->Entry);
240 
241  /* The OS/2 and POSIX subsystems are actually Windows applications! */
243  {
244  /* Locate the Windows subsystem for this session */
245  KnownSubsystem = SmpLocateKnownSubSysByType(MuSessionId,
247  if (!KnownSubsystem)
248  {
249  DPRINT1("SMSS: SmpLoadSubSystem - SmpLocateKnownSubSysByType Failed\n");
250  goto Quickie2;
251  }
252 
253  /* Fill out all the process details and call CSRSS to launch it */
254  CreateProcess->In.ImageName = FileName;
255  CreateProcess->In.CurrentDirectory = Directory;
256  CreateProcess->In.CommandLine = CommandLine;
257  CreateProcess->In.DllPath = SmpDefaultLibPath.Length ?
259  CreateProcess->In.Flags = Flags | SMP_DEFERRED_FLAG;
260  CreateProcess->In.DebugFlags = SmpDebug;
261  Status = SmpCallCsrCreateProcess(&SbApiMsg,
262  sizeof(*CreateProcess),
263  KnownSubsystem->SbApiPort);
264  if (!NT_SUCCESS(Status))
265  {
266  /* Handle failures */
267  DPRINT1("SMSS: SmpLoadSubSystem - SmpCallCsrCreateProcess Failed with Status %lx\n",
268  Status);
269  goto Quickie2;
270  }
271 
272  /* Save the process information we'll need for the create session */
273  ProcessInformation.ProcessHandle = CreateProcess->Out.ProcessHandle;
274  ProcessInformation.ThreadHandle = CreateProcess->Out.ThreadHandle;
275  ProcessInformation.ClientId = CreateProcess->Out.ClientId;
276  ProcessInformation.ImageInformation.SubSystemType = CreateProcess->Out.SubsystemType;
277  }
278  else
279  {
280  /* This must be CSRSS itself, so just launch it and that's it */
282  Directory,
283  CommandLine,
284  MuSessionId,
286  &ProcessInformation);
287  if (!NT_SUCCESS(Status))
288  {
289  /* Handle failures */
290  DPRINT1("SMSS: SmpLoadSubSystem - SmpExecuteImage Failed with Status %lx\n",
291  Status);
292  goto Quickie2;
293  }
294  }
295 
296  /* Fill out the handle and client ID in the subsystem structure now */
297  NewSubsystem->ProcessHandle = ProcessInformation.ProcessHandle;
298  NewSubsystem->ClientId = ProcessInformation.ClientId;
299 
300  /* Check if we launched a native image or a subsystem-backed image */
301  if (ProcessInformation.ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE)
302  {
303  /* This must be CSRSS itself, since it's a native subsystem image */
304  SubSysProcessId = ProcessInformation.ClientId.UniqueProcess;
305  if ((ProcessId) && !(*ProcessId)) *ProcessId = SubSysProcessId;
306 
307  /* Was this the initial CSRSS on Session 0? */
308  if (!MuSessionId)
309  {
310  /* Then save it in the global variables */
311  SmpWindowsSubSysProcessId = SubSysProcessId;
312  SmpWindowsSubSysProcess = ProcessInformation.ProcessHandle;
313  }
315  }
316  else
317  {
318  /* This is the POSIX or OS/2 subsystem process, copy its information */
319  CreateSession->ProcessInfo = ProcessInformation;
320 
321  CreateSession->DbgSessionId = 0;
322  *(PULONGLONG)&CreateSession->DbgUiClientId = 0;
323 
324  /* This should find CSRSS because they are POSIX or OS/2 subsystems */
325  Subsystem = SmpLocateKnownSubSysByType(MuSessionId,
326  ProcessInformation.ImageInformation.SubSystemType);
327  if (!Subsystem)
328  {
329  /* Odd failure -- but handle it anyway */
331  DPRINT1("SMSS: SmpLoadSubSystem - SmpLocateKnownSubSysByType Failed with Status %lx for sessionid %lu\n",
332  Status,
333  MuSessionId);
334  goto Quickie;
335  }
336 
337  /* Duplicate the parent process handle for the subsystem to have */
339  ProcessInformation.ProcessHandle,
340  Subsystem->ProcessHandle,
341  &CreateSession->ProcessInfo.ProcessHandle,
343  0,
344  0);
345  if (!NT_SUCCESS(Status))
346  {
347  /* Fail since this is critical */
348  DPRINT1("SMSS: SmpLoadSubSystem - NtDuplicateObject Failed with Status %lx for sessionid %lu\n",
349  Status,
350  MuSessionId);
351  goto Quickie;
352  }
353 
354  /* Duplicate the initial thread handle for the subsystem to have */
356  ProcessInformation.ThreadHandle,
357  Subsystem->ProcessHandle,
358  &CreateSession->ProcessInfo.ThreadHandle,
360  0,
361  0);
362  if (!NT_SUCCESS(Status))
363  {
364  /* Fail since this is critical */
365  DPRINT1("SMSS: SmpLoadSubSystem - NtDuplicateObject Failed with Status %lx for sessionid %lu\n",
366  Status,
367  MuSessionId);
368  goto Quickie;
369  }
370 
371  /* Allocate an internal Session ID for this subsystem */
372  CreateSession->SessionId = SmpAllocateSessionId(Subsystem, NULL);
373 
374  /* Send the create session message to the subsystem */
375  SbApiMsg.ReturnValue = STATUS_SUCCESS;
376  SbApiMsg.h.u2.ZeroInit = 0;
377  SbApiMsg.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
378  SbApiMsg.h.u1.s1.TotalLength = sizeof(SB_API_MSG);
379  SbApiMsg.ApiNumber = SbpCreateSession;
381  &SbApiMsg.h,
382  &SbApiMsg.h);
383  if (NT_SUCCESS(Status)) Status = SbApiMsg.ReturnValue;
384  if (!NT_SUCCESS(Status))
385  {
386  /* Delete the session and handle failure if the LPC call failed */
387  SmpDeleteSession(CreateSession->SessionId);
388  DPRINT1("SMSS: SmpLoadSubSystem - NtRequestWaitReplyPort Failed with Status %lx for sessionid %lu\n",
389  Status,
390  MuSessionId);
391  goto Quickie;
392  }
393  }
394 
395  /* Okay, everything looks good to go, initialize this subsystem now! */
396  Status = NtResumeThread(ProcessInformation.ThreadHandle, NULL);
397  if (!NT_SUCCESS(Status))
398  {
399  /* That didn't work -- back out of everything */
400  DPRINT1("SMSS: SmpLoadSubSystem - NtResumeThread failed Status %lx\n", Status);
401  goto Quickie;
402  }
403 
404  /* Check if this was the subsystem for a different session */
405  if (MuSessionId)
406  {
407  /* Wait up to 60 seconds for it to initialize */
408  Timeout.QuadPart = -600000000;
409  Status = NtWaitForSingleObject(NewSubsystem->Event, FALSE, &Timeout);
410 
411  /* Timeout is done -- does this session still exist? */
412  if (!SmpCheckDuplicateMuSessionId(MuSessionId))
413  {
414  /* Nope, it died. Cleanup should've ocurred in a different path. */
415  DPRINT1("SMSS: SmpLoadSubSystem - session deleted\n");
416  return STATUS_DELETE_PENDING;
417  }
418 
419  /* Check if we timed our or there was another error with the wait */
420  if (Status != STATUS_WAIT_0)
421  {
422  /* Something is wrong with the subsystem, so back out of everything */
423  DPRINT1("SMSS: SmpLoadSubSystem - Timeout waiting for subsystem connect with Status %lx for sessionid %lu\n",
424  Status,
425  MuSessionId);
426  goto Quickie;
427  }
428  }
429  else
430  {
431  /* This a session 0 subsystem, just wait for it to initialize */
432  NtWaitForSingleObject(NewSubsystem->Event, FALSE, NULL);
433  }
434 
435  /* Subsystem is created, resumed, and initialized. Close handles and exit */
436  NtClose(ProcessInformation.ThreadHandle);
438  goto Quickie2;
439 
440 Quickie:
441  /* This is the failure path. First check if we need to detach from session */
442  if ((AttachedSessionId == -1) || (Flags & (SMP_POSIX_FLAG | SMP_OS2_FLAG)))
443  {
444  /* We were not attached, or did not launch subsystems that required it */
445  DPRINT1("SMSS: Did not detach from Session Space: SessionId=%x Flags=%x Status=%x\n",
448  Status);
449  }
450  else
451  {
452  /* Get the privilege we need for detachment */
454  if (!NT_SUCCESS(Status))
455  {
456  /* We can't detach without it */
457  DPRINT1("SMSS: Did not detach from Session Space: SessionId=%x Flags=%x Status=%x\n",
460  Status);
461  }
462  else
463  {
464  /* Now detach from the session */
467  sizeof(AttachedSessionId));
468  if (!NT_SUCCESS(Status))
469  {
470  /* Failed to detach. Note the DPRINT1 has a typo in Windows */
471  DPRINT1("SMSS: SmpStartCsr, Couldn't Detach from Session Space. Status=%x\n", Status);
473  }
474  else
475  {
476  /* Detachment worked, reset our attached session ID */
477  AttachedSessionId = -1;
478  }
479 
480  /* And release the privilege we acquired */
482  }
483  }
484 
485  /* Since this is the failure path, terminate the subsystem process */
486  NtTerminateProcess(ProcessInformation.ProcessHandle, Status);
487  NtClose(ProcessInformation.ThreadHandle);
488 
489 Quickie2:
490  /* This is the cleanup path -- first dereference our subsystems */
492  if (Subsystem) SmpDereferenceSubsystem(Subsystem);
493  if (KnownSubsystem) SmpDereferenceSubsystem(KnownSubsystem);
494 
495  /* In the failure case, destroy the new subsystem we just created */
496  if (!NT_SUCCESS(Status))
497  {
498  RemoveEntryList(&NewSubsystem->Entry);
499  NtSetEvent(NewSubsystem->Event, NULL);
500  SmpDereferenceSubsystem(NewSubsystem);
501  }
502 
503  /* Finally, we're all done! */
505  return Status;
506 }
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
ULONG ReferenceCount
Definition: smss.h:74
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2709
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define IMAGE_SUBSYSTEM_POSIX_CUI
Definition: ntimage.h:440
HANDLE PortHandle
Definition: smss.h:69
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
BOOLEAN NTAPI SmpCheckDuplicateMuSessionId(IN ULONG MuSessionId)
Definition: smsessn.c:37
HANDLE SmpWindowsSubSysProcessId
Definition: smsubsys.c:21
ULONG NTAPI SmpAllocateSessionId(IN PSMP_SUBSYSTEM Subsystem, IN PSMP_SUBSYSTEM OtherSubsystem)
Definition: smsessn.c:123
NTSTATUS NTAPI NtRequestWaitReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE LpcRequest, IN OUT PPORT_MESSAGE LpcReply)
Definition: send.c:695
PORT_MESSAGE h
Definition: smmsg.h:232
UNICODE_STRING SmpDefaultLibPath
Definition: sminit.c:29
#define TRUE
Definition: types.h:120
ULONG AttachedSessionId
Definition: smss.c:21
LONG NTSTATUS
Definition: precomp.h:26
#define SE_LOAD_DRIVER_PRIVILEGE
Definition: security.c:664
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define STATUS_NO_SUCH_PACKAGE
Definition: ntstatus.h:490
BOOLEAN Terminating
Definition: smss.h:73
VOID NTAPI SmpDeleteSession(IN ULONG SessionId)
Definition: smsessn.c:98
_In_ ULONG _In_ ULONG State
Definition: potypes.h:516
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
struct _SB_API_MSG SB_API_MSG
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define SMP_OS2_FLAG
Definition: smss.h:51
#define InsertTailList(ListHead, Entry)
ULONG ImageType
Definition: smss.h:68
HANDLE UniqueProcess
Definition: compat.h:825
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define STATUS_WAIT_0
Definition: ntstatus.h:237
#define IMAGE_SUBSYSTEM_OS2_CUI
Definition: ntimage.h:439
HANDLE ProcessHandle
Definition: smss.h:67
#define FALSE
Definition: types.h:117
PVOID SmpHeap
Definition: sminit.c:25
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
SB_API_NUMBER ApiNumber
Definition: smmsg.h:238
#define IMAGE_SUBSYSTEM_NATIVE
Definition: ntimage.h:436
struct _SB_CREATE_SESSION_MSG SB_CREATE_SESSION_MSG
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19
HANDLE Event
Definition: smss.h:66
#define SMP_POSIX_FLAG
Definition: smss.h:50
NTSYSAPI NTSTATUS NTAPI NtSetSystemInformation(IN INT SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength)
#define NtCurrentProcess()
Definition: nt_native.h:1657
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
NTSTATUS ReturnValue
Definition: smmsg.h:239
MMRESULT CreateSession(DeviceType device_type, UINT device_id, SessionInfo **session_info)
Definition: session.c:63
Status
Definition: gdiplustypes.h:24
SECTION_IMAGE_INFORMATION ImageInformation
Definition: rtltypes.h:1573
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
union _SB_API_MSG::@3473::@3475::@3477 u
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG SmBaseTag
Definition: sminit.c:26
HANDLE SbApiPort
Definition: smss.h:70
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
VOID NTAPI SmpReleasePrivilege(IN PVOID State)
Definition: smutil.c:129
BOOLEAN SmpDebug
Definition: smss.c:22
#define SMP_INVALID_PATH
Definition: smss.h:48
#define CreateProcess
Definition: winbase.h:3629
NTSTATUS NTAPI SmpAcquirePrivilege(IN ULONG Privilege, OUT PVOID *PrivilegeStat)
Definition: smutil.c:40
ULONG MuSessionId
Definition: smss.h:72
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18
struct _FileName FileName
Definition: fatprocs.h:893
VOID NTAPI SmpDereferenceSubsystem(IN PSMP_SUBSYSTEM SubSystem)
Definition: smsubsys.c:47
static ULONG Timeout
Definition: ping.c:61
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
LIST_ENTRY Entry
Definition: smss.h:65
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByType(IN ULONG MuSessionId, IN ULONG ImageType)
Definition: smsubsys.c:102
#define NULL
Definition: types.h:112
HANDLE SmpWindowsSubSysProcess
Definition: smsubsys.c:20
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
NTSTATUS NTAPI SmpExecuteImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, IN ULONG Flags, IN PRTL_USER_PROCESS_INFORMATION ProcessInformation)
Definition: smss.c:30
base for all directory entries
Definition: entries.h:138
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define SMP_DEFERRED_FLAG
Definition: smss.h:49
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3926
CLIENT_ID ClientId
Definition: smss.h:71
NTSTATUS NTAPI SmpCallCsrCreateProcess(IN PSB_API_MSG SbApiMsg, IN USHORT MessageLength, IN HANDLE PortHandle)
Definition: smsubsys.c:29
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

Referenced by SmpExecuteCommand().

◆ SmpLoadSubSystemsForMuSession()

NTSTATUS NTAPI SmpLoadSubSystemsForMuSession ( IN PULONG  MuSessionId,
OUT PHANDLE  ProcessId,
IN PUNICODE_STRING  InitialCommand 
)

Definition at line 510 of file smsubsys.c.

513 {
514  NTSTATUS Status = STATUS_SUCCESS, Status2;
517  PLIST_ENTRY NextEntry;
519  PVOID State;
520 
521  /* Write a few last registry keys with the boot partition information */
523 
524  /* Process "SetupExecute" values */
525  NextEntry = SmpSetupExecuteList.Flink;
526  while (NextEntry != &SmpSetupExecuteList)
527  {
528  /* Execute each one and move on */
530  SmpExecuteCommand(&RegEntry->Name, 0, NULL, 0);
531  NextEntry = NextEntry->Flink;
532  }
533 
534  /* Now process the subsystems */
535  NextEntry = SmpSubSystemList.Flink;
536  while (NextEntry != &SmpSubSystemList)
537  {
538  /* Get the entry and check if this is the special Win32k entry */
540  if (_wcsicmp(RegEntry->Name.Buffer, L"Kmode") == 0)
541  {
542  /* Translate it */
543  if (!RtlDosPathNameToNtPathName_U(RegEntry->Value.Buffer,
544  &NtPath,
545  NULL,
546  NULL))
547  {
549  DPRINT1("Failed: %lx\n", Status);
550  }
551  else
552  {
553  /* Get the driver privilege */
555  if (NT_SUCCESS(Status))
556  {
557  /* Create the new session */
558  ASSERT(AttachedSessionId == -1);
560  MuSessionId,
561  sizeof(*MuSessionId));
562  if (!NT_SUCCESS(Status))
563  {
564  DPRINT1("SMSS: Session space creation failed\n");
566  RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer);
567  return Status;
568  }
569  AttachedSessionId = *MuSessionId;
570 
571  /*
572  * Start Win32k.sys on this session. Use a hardcoded value
573  * instead of the Kmode one...
574  */
576  L"\\SystemRoot\\System32\\win32k.sys");
579  sizeof(DestinationString));
580  RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer);
582  if (!NT_SUCCESS(Status))
583  {
584  DPRINT1("SMSS: Load of WIN32K failed.\n");
585  return Status;
586  }
587  }
588  }
589  }
590 
591  /* Next entry */
592  NextEntry = NextEntry->Flink;
593  }
594 
595  /* Now parse the required subsystem list */
596  NextEntry = SmpSubSystemsToLoad.Flink;
597  while (NextEntry != &SmpSubSystemsToLoad)
598  {
599  /* Get each entry and check if it's the internal debug or not */
601  if (_wcsicmp(RegEntry->Name.Buffer, L"Debug") == 0)
602  {
603  /* Load the internal debug system */
605  *MuSessionId,
606  ProcessId,
608  }
609  else
610  {
611  /* Load the required subsystem */
613  *MuSessionId,
614  ProcessId,
616  }
617  if (!NT_SUCCESS(Status))
618  {
619  DPRINT1("SMSS: Subsystem execute failed (%wZ)\n", &RegEntry->Value);
620  return Status;
621  }
622 
623  /* Move to the next entry */
624  NextEntry = NextEntry->Flink;
625  }
626 
627  /* Process the "Execute" list now */
628  NextEntry = SmpExecuteList.Blink;
629  if (NextEntry != &SmpExecuteList)
630  {
631  /* Get the custom initial command */
633 
634  /* Write the initial command and wait for 5 seconds (why??!) */
635  *InitialCommand = RegEntry->Name;
636  Timeout.QuadPart = -50000000;
638  }
639  else
640  {
641  /* Use the default Winlogon initial command */
642  RtlInitUnicodeString(InitialCommand, L"winlogon.exe");
644 
645  /* Check if there's a debugger for Winlogon */
646  Status2 = LdrQueryImageFileExecutionOptions(InitialCommand,
647  L"Debugger",
648  REG_SZ,
650  sizeof(InitialCommandBuffer) -
651  InitialCommand->Length,
652  NULL);
653  if ((NT_SUCCESS(Status2)) && (InitialCommandBuffer[0]))
654  {
655  /* Put the debugger string with the Winlogon string */
657  RtlStringCbCatW(InitialCommandBuffer, sizeof(InitialCommandBuffer), InitialCommand->Buffer);
659  }
660  }
661 
662  /* Finally check if there was a custom initial command */
663  NextEntry = SmpExecuteList.Flink;
664  while (NextEntry != &SmpExecuteList)
665  {
666  /* Execute each one */
668  SmpExecuteCommand(&RegEntry->Name, *MuSessionId, NULL, 0);
669  NextEntry = NextEntry->Flink;
670  }
671 
672  /* Return status */
673  return Status;
674 }
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2709
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
ULONG AttachedSessionId
Definition: smss.c:21
LONG NTSTATUS
Definition: precomp.h:26
#define SE_LOAD_DRIVER_PRIVILEGE
Definition: security.c:664
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_In_ ULONG _In_ ULONG State
Definition: potypes.h:516
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
WCHAR InitialCommandBuffer[256]
Definition: smsubsys.c:23
LIST_ENTRY SmpSubSystemsToLoad
Definition: sminit.c:22
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1909
NTSYSAPI NTSTATUS NTAPI NtSetSystemInformation(IN INT SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS NTAPI NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
Definition: wait.c:876
Status
Definition: gdiplustypes.h:24
LIST_ENTRY SmpSetupExecuteList
Definition: sminit.c:19
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI SmpTranslateSystemPartitionInformation(VOID)
Definition: sminit.c:811
Registry entry.
Definition: regfs.h:30
VOID NTAPI SmpReleasePrivilege(IN PVOID State)
Definition: smutil.c:129
Definition: typedefs.h:119
#define SystemExtendServiceTableInformation
Definition: DriverTester.h:35
NTSTATUS NTAPI SmpAcquirePrivilege(IN ULONG Privilege, OUT PVOID *PrivilegeStat)
Definition: smutil.c:40
NTSTATUS NTAPI LdrQueryImageFileExecutionOptions(IN PUNICODE_STRING SubKey, IN PCWSTR ValueName, IN ULONG Type, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG ReturnedLength OPTIONAL)
Definition: ldrinit.c:386
NTSTATUS NTAPI SmpExecuteCommand(IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, OUT PHANDLE ProcessId, IN ULONG Flags)
Definition: smss.c:210
LIST_ENTRY SmpExecuteList
Definition: sminit.c:23
static ULONG Timeout
Definition: ping.c:61
#define SMP_DEBUG_FLAG
Definition: smss.h:44
#define SMP_SUBSYSTEM_FLAG
Definition: smss.h:47
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
LIST_ENTRY SmpSubSystemList
Definition: sminit.c:22
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
base of all file and directory entries
Definition: entries.h:82
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
#define REG_SZ
Definition: layer.c:22

Referenced by SmpLoadDataFromRegistry(), and SmpStartCsr().

◆ SmpLocateKnownSubSysByCid()

PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByCid ( IN PCLIENT_ID  ClientId)

Definition at line 68 of file smsubsys.c.

69 {
70  PSMP_SUBSYSTEM Subsystem = NULL;
71  PLIST_ENTRY NextEntry;
72 
73  /* Lock the subsystem database */
75 
76  /* Loop each subsystem in the database */
77  NextEntry = SmpKnownSubSysHead.Flink;
78  while (NextEntry != &SmpKnownSubSysHead)
79  {
80  /* Check if this one matches the client ID and is still valid */
81  Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
82  if ((*(PULONGLONG)&Subsystem->ClientId == *(PULONGLONG)ClientId) &&
83  !(Subsystem->Terminating))
84  {
85  /* Add a reference and return it */
86  Subsystem->ReferenceCount++;
87  break;
88  }
89 
90  /* Reset the current pointer and keep searching */
91  Subsystem = NULL;
92  NextEntry = NextEntry->Flink;
93  }
94 
95  /* Release the lock and return the subsystem we found */
97  return Subsystem;
98 }
ULONG ReferenceCount
Definition: smss.h:74
BOOLEAN Terminating
Definition: smss.h:73
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1165
Definition: typedefs.h:119
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18
#define NULL
Definition: types.h:112
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
base of all file and directory entries
Definition: entries.h:82
CLIENT_ID ClientId
Definition: smss.h:71

Referenced by SmpHandleConnectionRequest().

◆ SmpLocateKnownSubSysByType()

PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByType ( IN ULONG  MuSessionId,
IN ULONG  ImageType 
)

Definition at line 102 of file smsubsys.c.

104 {
105  PSMP_SUBSYSTEM Subsystem = NULL;
106  PLIST_ENTRY NextEntry;
107 
108  /* Lock the subsystem database */
110 
111  /* Loop each subsystem in the database */
112  NextEntry = SmpKnownSubSysHead.Flink;
113  while (NextEntry != &SmpKnownSubSysHead)
114  {
115  /* Check if this one matches the image and uID, and is still valid */
116  Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
117  if ((Subsystem->ImageType == ImageType) &&
118  !(Subsystem->Terminating) &&
119  (Subsystem->MuSessionId == MuSessionId))
120  {
121  /* Return it referenced for the caller */
122  Subsystem->ReferenceCount++;
123  break;
124  }
125 
126  /* Reset the current pointer and keep searching */
127  Subsystem = NULL;
128  NextEntry = NextEntry->Flink;
129  }
130 
131  /* Release the lock and return the subsystem we found */
133  return Subsystem;
134 }
ULONG ReferenceCount
Definition: smss.h:74
BOOLEAN Terminating
Definition: smss.h:73
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
ULONG ImageType
Definition: smss.h:68
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: typedefs.h:119
ULONG MuSessionId
Definition: smss.h:72
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18
#define NULL
Definition: types.h:112
ImageType
Definition: gdiplusenums.h:192
base of all file and directory entries
Definition: entries.h:82

Referenced by SmpHandleConnectionRequest(), SmpLoadSubSystem(), and SmpSbCreateSession().

◆ SmpPagingFileInitialize()

VOID NTAPI SmpPagingFileInitialize ( VOID  )

Definition at line 130 of file pagefile.c.

131 {
132  /* Initialize the two lists */
135 }
LIST_ENTRY SmpVolumeDescriptorList
Definition: pagefile.c:122
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LIST_ENTRY SmpPagingFileDescriptorList
Definition: pagefile.c:122

Referenced by SmpLoadDataFromRegistry().

◆ SmpParseCommandLine()

NTSTATUS NTAPI SmpParseCommandLine ( IN PUNICODE_STRING  CommandLine,
OUT PULONG  Flags,
OUT PUNICODE_STRING  FileName,
OUT PUNICODE_STRING  Directory,
OUT PUNICODE_STRING  Arguments 
)

Definition at line 233 of file smutil.c.

238 {
239  ULONG Length;
240  UNICODE_STRING EnvString, PathString, CmdLineCopy, Token;
241  WCHAR PathBuffer[MAX_PATH];
242  PWCHAR FilePart;
244  UNICODE_STRING FullPathString;
245 
246  /* Initialize output arguments to NULL */
248  RtlInitUnicodeString(Arguments, NULL);
250 
251  /* Check if we haven't yet built a full default path or system root yet */
252  if (!SmpSystemRoot.Length)
253  {
254  /* Initialize it based on shared user data string */
256 
257  /* Allocate an empty string for the path */
259  sizeof(L"\\system32;");
260  RtlInitEmptyUnicodeString(&FullPathString,
262  (USHORT)Length);
263  if (FullPathString.Buffer)
264  {
265  /* Append the root, system32;, and then the current library path */
267  RtlAppendUnicodeToString(&FullPathString, L"\\system32;");
270  SmpDefaultLibPath = FullPathString;
271  }
272  }
273 
274  /* Consume the command line */
275  CmdLineCopy = *CommandLine;
276  while (TRUE)
277  {
278  /* Parse the first token and check for modifiers/specifiers */
279  Status = SmpParseToken(&CmdLineCopy, FALSE, &Token);
280  if (!(NT_SUCCESS(Status)) || !(Token.Buffer)) return STATUS_UNSUCCESSFUL;
281  if (!Flags) break;
282 
283  /* Debug requested? */
285  {
286  /* Convert into a flag */
287  *Flags |= SMP_DEBUG_FLAG;
288  }
290  {
291  /* Asynch requested, convert into a flag */
292  *Flags |= SMP_ASYNC_FLAG;
293  }
295  {
296  /* Autochk requested, convert into a flag */
298  }
299  else
300  {
301  /* No specifier found, keep going */
302  break;
303  }
304 
305  /* Get rid of this token and get the next */
307  }
308 
309  /* Initialize a string to hold the current path */
310  RtlInitUnicodeString(&EnvString, L"Path");
311  Length = PAGE_SIZE;
312  RtlInitEmptyUnicodeString(&PathString,
314  (USHORT)Length);
315  if (!PathString.Buffer)
316  {
317  /* Fail if we have no memory for this */
320  }
321 
322  /* Query the path from the environment */
324  &EnvString,
325  &PathString);
327  {
328  /* Our buffer was too small, free it */
329  RtlFreeHeap(SmpHeap, 0, PathString.Buffer);
330 
331  /* And allocate one big enough */
332  Length = PathString.Length + sizeof(UNICODE_NULL);
333  RtlInitEmptyUnicodeString(&PathString,
335  (USHORT)Length);
336  if (!PathString.Buffer)
337  {
338  /* Fail if we have no memory for this */
341  }
342 
343  /* Now try again, this should work */
345  &EnvString,
346  &PathString);
347  }
348  if (!NT_SUCCESS(Status))
349  {
350  /* Another failure means that the kernel hasn't passed the path correctly */
351  DPRINT1("SMSS: %wZ environment variable not defined.\n", &EnvString);
353  }
354  else
355  {
356  /* Check if the caller expects any flags out of here */
357  if (Flags)
358  {
359  /* We can return the image not found flag -- so does the image exist */
360  if (!(RtlDosSearchPath_U(PathString.Buffer,
361  Token.Buffer,
362  L".exe",
363  sizeof(PathBuffer),
364  PathBuffer,
365  &FilePart)) &&
367  Token.Buffer,
368  L".exe",
369  sizeof(PathBuffer),
370  PathBuffer,
371  &FilePart)))
372  {
373  /* It doesn't, let the caller know about it and exit */
375  *FileName = Token;
376  RtlFreeHeap(SmpHeap, 0, PathString.Buffer);
377  return STATUS_SUCCESS;
378  }
379  }
380  else
381  {
382  /* Caller doesn't want flags, probably wants the image itself */
383  RtlStringCbCopyW(PathBuffer, sizeof(PathBuffer), Token.Buffer);
384  }
385  }
386 
387  /* Free tokens and such, all that's left is to convert the image name */
389  RtlFreeHeap(SmpHeap, 0, PathString.Buffer);
390  if (!NT_SUCCESS(Status)) return Status;
391 
392  /* Convert it and bail out if this failed */
393  if (!RtlDosPathNameToNtPathName_U(PathBuffer, FileName, NULL, NULL))
394  {
395  DPRINT1("SMSS: Unable to translate %ws into an NT File Name\n",
396  &PathBuffer);
398  }
399  if (!NT_SUCCESS(Status)) return Status;
400 
401  /* Finally, check if the caller also wanted the directory */
402  if (Directory)
403  {
404  /* Is the file a relative name with no directory? */
405  if (FilePart <= PathBuffer)
406  {
407  /* Clear it */
409  }
410  else
411  {
412  /* There is a directory, and a filename -- separate those two */
413  *--FilePart = UNICODE_NULL;
414  RtlCreateUnicodeString(Directory, PathBuffer);
415  }
416  }
417 
418  /* We are done -- move on to the second pass to get the arguments */
419  return SmpParseToken(&CmdLineCopy, TRUE, Arguments);
420 }
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define SMP_AUTOCHK_FLAG
Definition: smss.h:46
UNICODE_STRING SmpDebugKeyword
Definition: smutil.c:34
USHORT MaximumLength
Definition: env_spec_w32.h:370
UNICODE_STRING SmpDefaultLibPath
Definition: sminit.c:29
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
NTSYSAPI ULONG NTAPI RtlDosSearchPath_U(_In_ PCWSTR Path, _In_ PCWSTR FileName, _In_ PCWSTR Extension, _In_ ULONG BufferSize, _Out_ PWSTR Buffer, _Out_ PWSTR *PartName)
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
PWCHAR SmpDefaultEnvironment
Definition: sminit.c:28
PVOID SmpHeap
Definition: sminit.c:25
NTSTATUS NTAPI SmpParseToken(IN PUNICODE_STRING Input, IN BOOLEAN SecondPass, OUT PUNICODE_STRING Token)
Definition: smutil.c:155
NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U(_In_opt_ PWSTR Environment, _In_ PCUNICODE_STRING Name, _Out_ PUNICODE_STRING Value)
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
UNICODE_STRING SmpASyncKeyword
Definition: smutil.c:34
Status
Definition: gdiplustypes.h:24
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UNICODE_STRING SmpSystemRoot
Definition: smss.c:20
ULONG SmBaseTag
Definition: sminit.c:26
#define MAX_PATH
Definition: compat.h:34
PCHAR Buffer
Definition: ntsecapi.h:174
UNICODE_STRING SmpAutoChkKeyword
Definition: smutil.c:34
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define SMP_ASYNC_FLAG
Definition: smss.h:45
#define SharedUserData
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define SMP_INVALID_PATH
Definition: smss.h:48
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
unsigned short USHORT
Definition: pedump.c:61
#define SMP_DEBUG_FLAG
Definition: smss.h:44
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
base for all directory entries
Definition: entries.h:138
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)

Referenced by SmpCreatePagingFileDescriptor(), SmpExecuteCommand(), and SmpExecuteInitialCommand().

◆ SmpQueryRegistrySosOption()

BOOLEAN NTAPI SmpQueryRegistrySosOption ( VOID  )

Definition at line 424 of file smutil.c.

425 {
430  ULONG Length;
431  WCHAR ValueBuffer[VALUE_BUFFER_SIZE];
432  PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)ValueBuffer;
433 
434  /* Open the key */
436  L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
438  &KeyName,
440  NULL,
441  NULL);
443  if (!NT_SUCCESS(Status))
444  {
445  DPRINT1("SMSS: Cannot open control key (Status 0x%x)\n", Status);
446  return FALSE;
447  }
448 
449  /* Query the value */
450  RtlInitUnicodeString(&ValueName, L"SystemStartOptions");
452  &ValueName,
454  PartialInfo,
455  sizeof(ValueBuffer),
456  &Length);
459  if (!NT_SUCCESS(Status) ||
460  ((PartialInfo->Type != REG_SZ) && (PartialInfo->Type != REG_EXPAND_SZ)))
461  {
462  DPRINT1("SMSS: Cannot query value key (Type %lu, Status 0x%x)\n",
463  PartialInfo->Type, Status);
464  return FALSE;
465  }
466 
467  /* Check if it's set to SOS or sos */
468  if (!(wcsstr((PWCHAR)PartialInfo->Data, L"SOS")) ||
469  (wcsstr((PWCHAR)PartialInfo->Data, L"sos")))
470  {
471  /* It's not set, return FALSE */
472  return FALSE;
473  }
474 
475  /* It's set, return TRUE */
476  return TRUE;
477 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
LONG NTSTATUS
Definition: precomp.h:26
#define VALUE_BUFFER_SIZE
Definition: smutil.c:23
uint16_t * PWCHAR
Definition: typedefs.h:56
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
void * PVOID
Definition: retypes.h:9
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define REG_SZ
Definition: layer.c:22

Referenced by SmpInvokeAutoChk().

◆ SmpReleasePrivilege()

VOID NTAPI SmpReleasePrivilege ( IN PVOID  State)

Definition at line 129 of file smutil.c.

130 {
132 
133  /* Adjust the privileges in the token */
134  NtAdjustPrivilegesToken(State->TokenHandle,
135  FALSE,
136  State->OldPrivileges,
137  0,
138  NULL,
139  NULL);
140 
141  /* Check if we used a dynamic buffer */
142  if (State->OldPrivileges != (PTOKEN_PRIVILEGES)&State->OldBuffer)
143  {
144  /* Free it */
145  RtlFreeHeap(SmpHeap, 0, State->OldPrivileges);
146  }
147 
148  /* Close the token handle and free the state structure */
149  NtClose(State->TokenHandle);
151 }
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define FALSE
Definition: types.h:117
PVOID SmpHeap
Definition: sminit.c:25
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtAdjustPrivilegesToken(_In_ HANDLE TokenHandle, _In_ BOOLEAN DisableAllPrivileges, _In_opt_ PTOKEN_PRIVILEGES NewState, _In_ ULONG BufferLength, _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState, _When_(PreviousState!=NULL, _Out_) PULONG ReturnLength)
Removes a certain amount of privileges of a token based upon the request by the caller.
Definition: tokenadj.c:451
struct _SMP_PRIVILEGE_STATE * PSMP_PRIVILEGE_STATE
#define NULL
Definition: types.h:112

Referenced by _main(), SmpLoadSubSystem(), and SmpLoadSubSystemsForMuSession().

◆ SmpRestoreBootStatusData()

VOID NTAPI SmpRestoreBootStatusData ( IN BOOLEAN  BootOkay,
IN BOOLEAN  ShutdownOkay 
)

Definition at line 531 of file smutil.c.

533 {
535  PVOID BootState;
536 
537  /* Lock the BSD */
538  Status = RtlLockBootStatusData(&BootState);
539  if (NT_SUCCESS(Status))
540  {
541  /* Write the bootokay and bootshutdown values */
542  RtlGetSetBootStatusData(BootState,
543  FALSE,
545  &BootOkay,
546  sizeof(BootOkay),
547  NULL);
548  RtlGetSetBootStatusData(BootState,
549  FALSE,
551  &ShutdownOkay,
552  sizeof(ShutdownOkay),
553  NULL);
554 
555  /* Unlock the BSD and return */
556  RtlUnlockBootStatusData(BootState);
557  }
558 }
NTSTATUS NTAPI RtlLockBootStatusData(_Out_ PHANDLE FileHandle)
Definition: bootdata.c:231
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI RtlUnlockBootStatusData(_In_ HANDLE FileHandle)
Definition: bootdata.c:267
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NULL
Definition: types.h:112
NTSTATUS NTAPI RtlGetSetBootStatusData(_In_ HANDLE FileHandle, _In_ BOOLEAN Read, _In_ RTL_BSD_ITEM_TYPE DataClass, _In_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnLength)
Definition: bootdata.c:161

Referenced by SmpInvokeAutoChk().

◆ SmpSaveAndClearBootStatusData()

BOOLEAN NTAPI SmpSaveAndClearBootStatusData ( OUT PBOOLEAN  BootOkay,
OUT PBOOLEAN  ShutdownOkay 
)

Definition at line 481 of file smutil.c.

483 {
485  BOOLEAN Value = TRUE;
486  PVOID BootStatusDataHandle;
487 
488  /* Assume failure */
489  *BootOkay = FALSE;
490  *ShutdownOkay = FALSE;
491 
492  /* Lock the BSD and fail if we couldn't */
493  Status = RtlLockBootStatusData(&BootStatusDataHandle);
494  if (!NT_SUCCESS(Status)) return FALSE;
495 
496  /* Read the old settings */
497  RtlGetSetBootStatusData(BootStatusDataHandle,
498  TRUE,
500  BootOkay,
501  sizeof(BOOLEAN),
502  NULL);
503  RtlGetSetBootStatusData(BootStatusDataHandle,
504  TRUE,
506  ShutdownOkay,
507  sizeof(BOOLEAN),
508  NULL);
509 
510  /* Set new ones indicating we got at least this far */
511  RtlGetSetBootStatusData(BootStatusDataHandle,
512  FALSE,
514  &Value,
515  sizeof(Value),
516  NULL);
517  RtlGetSetBootStatusData(BootStatusDataHandle,
518  FALSE,
520  &Value,
521  sizeof(Value),
522  NULL);
523 
524  /* Unlock the BSD and return */
525  RtlUnlockBootStatusData(BootStatusDataHandle);
526  return TRUE;
527 }
NTSTATUS NTAPI RtlLockBootStatusData(_Out_ PHANDLE FileHandle)
Definition: bootdata.c:231
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI RtlUnlockBootStatusData(_In_ HANDLE FileHandle)
Definition: bootdata.c:267
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NULL
Definition: types.h:112
NTSTATUS NTAPI RtlGetSetBootStatusData(_In_ HANDLE FileHandle, _In_ BOOLEAN Read, _In_ RTL_BSD_ITEM_TYPE DataClass, _In_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnLength)
Definition: bootdata.c:161

Referenced by SmpInvokeAutoChk().

◆ SmpSbCreateSession()

NTSTATUS NTAPI SmpSbCreateSession ( IN PVOID  Reserved,
IN PSMP_SUBSYSTEM  OtherSubsystem,
IN PRTL_USER_PROCESS_INFORMATION  ProcessInformation,
IN ULONG  DbgSessionId,
IN PCLIENT_ID  DbgUiClientId 
)

Definition at line 36 of file smsbapi.c.

41 {
43  ULONG SubSystemType = ProcessInformation->ImageInformation.SubSystemType;
44  ULONG MuSessionId;
46  PSMP_SUBSYSTEM KnownSubsys;
47  SB_API_MSG SbApiMsg = {0};
48  PSB_CREATE_SESSION_MSG CreateSessionMsg = &SbApiMsg.u.CreateSession;
49 
50  /* Write out the create session message including its initial process */
51  CreateSessionMsg->ProcessInfo = *ProcessInformation;
52  CreateSessionMsg->DbgSessionId = DbgSessionId;
53  if (DbgUiClientId)
54  {
55  CreateSessionMsg->DbgUiClientId = *DbgUiClientId;
56  }
57  else
58  {
59  CreateSessionMsg->DbgUiClientId.UniqueThread = NULL;
60  CreateSessionMsg->DbgUiClientId.UniqueProcess = NULL;
61  }
62 
63  /* Find a subsystem responsible for this session */
64  SmpGetProcessMuSessionId(ProcessInformation->ProcessHandle, &MuSessionId);
65  if (!SmpCheckDuplicateMuSessionId(MuSessionId))
66  {
67  NtClose(ProcessInformation->ProcessHandle);
68  NtClose(ProcessInformation->ThreadHandle);
69  DPRINT1("SMSS: CreateSession status=%x\n", STATUS_OBJECT_NAME_NOT_FOUND);
71  }
72 
73  /* Find the subsystem suitable for this initial process */
74  KnownSubsys = SmpLocateKnownSubSysByType(MuSessionId, SubSystemType);
75  if (KnownSubsys)
76  {
77  /* Duplicate the process handle into the message */
79  ProcessInformation->ProcessHandle,
80  KnownSubsys->ProcessHandle,
81  &CreateSessionMsg->ProcessInfo.ProcessHandle,
83  0,
84  0);
85  if (NT_SUCCESS(Status))
86  {
87  /* Duplicate the thread handle into the message */
89  ProcessInformation->ThreadHandle,
90  KnownSubsys->ProcessHandle,
91  &CreateSessionMsg->ProcessInfo.ThreadHandle,
93  0,
94  0);
95  if (!NT_SUCCESS(Status))
96  {
97  /* Close everything on failure */
98  NtClose(ProcessInformation->ProcessHandle);
99  NtClose(ProcessInformation->ThreadHandle);
100  SmpDereferenceSubsystem(KnownSubsys);
101  DPRINT1("SmpSbCreateSession: NtDuplicateObject (Thread) Failed %lx\n", Status);
102  return Status;
103  }
104 
105  /* Close the original handles as they are no longer needed */
106  NtClose(ProcessInformation->ProcessHandle);
107  NtClose(ProcessInformation->ThreadHandle);
108 
109  /* Finally, allocate a new SMSS session ID for this session */
110  SessionId = SmpAllocateSessionId(KnownSubsys, OtherSubsystem);
111  CreateSessionMsg->SessionId = SessionId;
112 
113  /* Fill out the LPC message header and send it to the client! */
114  SbApiMsg.ApiNumber = SbpCreateSession;
115  SbApiMsg.h.u2.ZeroInit = 0;
116  SbApiMsg.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
117  SbApiMsg.h.u1.s1.TotalLength = sizeof(SbApiMsg);
118  Status = NtRequestWaitReplyPort(KnownSubsys->SbApiPort,
119  &SbApiMsg.h,
120  &SbApiMsg.h);
121  if (!NT_SUCCESS(Status))
122  {
123  /* Bail out */
124  DPRINT1("SmpSbCreateSession: NtRequestWaitReply Failed %lx\n", Status);
125  }
126  else
127  {
128  /* If the API succeeded, get the result value from the LPC */
129  Status = SbApiMsg.ReturnValue;
130  }
131 
132  /* Delete the session on any kind of failure */
134  }
135  else
136  {
137  /* Close the handles on failure */
138  DPRINT1("SmpSbCreateSession: NtDuplicateObject (Process) Failed %lx\n", Status);
139  NtClose(ProcessInformation->ProcessHandle);
140  NtClose(ProcessInformation->ThreadHandle);
141  }
142 
143  /* Dereference the subsystem and return the status of the LPC call */
144  SmpDereferenceSubsystem(KnownSubsys);
145  return Status;
146  }
147 
148  /* If we don't yet have a subsystem, only native images can be launched */
149  if (SubSystemType != IMAGE_SUBSYSTEM_NATIVE)
150  {
151  /* Fail */
152 #if DBG
153  PCSTR SubSysName = NULL;
154  CHAR SubSysTypeName[sizeof("Type 0x")+8];
155 
156  if (SubSystemType < RTL_NUMBER_OF(SmpSubSystemNames))
157  SubSysName = SmpSubSystemNames[SubSystemType];
158  if (!SubSysName)
159  {
160  SubSysName = SubSysTypeName;
161  sprintf(SubSysTypeName, "Type 0x%08lx", SubSystemType);
162  }
163  DPRINT1("SMSS: %s SubSystem not found (either not started or destroyed).\n", SubSysName);
164 #endif
166  NtClose(ProcessInformation->ProcessHandle);
167  NtClose(ProcessInformation->ThreadHandle);
168  return Status;
169  }
170 
171 #if 0
172  /*
173  * This code is part of the LPC-based legacy debugging support for native
174  * applications, implemented with the debug client interface (DbgUi) and
175  * debug subsystem (DbgSs). It is now vestigial since WinXP+ and is here
176  * for informational purposes only.
177  */
178  if ((*(ULONGLONG)&CreateSessionMsg.DbgUiClientId) && SmpDbgSsLoaded)
179  {
180  Process = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_PROCESS));
181  if (!Process)
182  {
183  DPRINT1("Unable to initialize debugging for Native App %lx.%lx -- out of memory\n",
184  ProcessInformation->ClientId.UniqueProcess,
185  ProcessInformation->ClientId.UniqueThread);
186  NtClose(ProcessInformation->ProcessHandle);
187  NtClose(ProcessInformation->ThreadHandle);
188  return STATUS_NO_MEMORY;
189  }
190 
191  Process->DbgUiClientId = CreateSessionMsg->DbgUiClientId;
192  Process->ClientId = ProcessInformation->ClientId;
194  DPRINT1("Native Debug App %lx.%lx\n",
195  Process->ClientId.UniqueProcess,
196  Process->ClientId.UniqueThread);
197 
198  Status = NtSetInformationProcess(ProcessInformation->ProcessHandle,
200  &SmpDebugPort,
201  sizeof(SmpDebugPort));
203  }
204 #endif
205 
206  /* This is a native application being started as the initial command */
207  DPRINT("Subsystem active, starting thread\n");
208  NtClose(ProcessInformation->ProcessHandle);
209  NtResumeThread(ProcessInformation->ThreadHandle, NULL);
210  NtClose(ProcessInformation->ThreadHandle);
211  return STATUS_SUCCESS;
212 }
CLIENT_ID DbgUiClientId
Definition: smmsg.h:164
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
BOOLEAN NTAPI SmpCheckDuplicateMuSessionId(IN ULONG MuSessionId)
Definition: smsessn.c:37
ULONG NTAPI SmpAllocateSessionId(IN PSMP_SUBSYSTEM Subsystem, IN PSMP_SUBSYSTEM OtherSubsystem)
Definition: smsessn.c:123
NTSTATUS NTAPI NtRequestWaitReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE LpcRequest, IN OUT PPORT_MESSAGE LpcReply)
Definition: send.c:695
PORT_MESSAGE h
Definition: smmsg.h:232
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
char CHAR
Definition: xmlstorage.h:175
ULONG SessionId
Definition: dllmain.c:28
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI SmpDeleteSession(IN ULONG SessionId)
Definition: smsessn.c:98
LIST_ENTRY NativeProcessList
Definition: sminit.c:23
HANDLE UniqueProcess
Definition: compat.h:825
NTSTATUS NTAPI SmpGetProcessMuSessionId(IN HANDLE ProcessHandle, OUT PULONG SessionId)
Definition: smsessn.c:168
#define sprintf(buf, format,...)
Definition: sprintf.c:55
RTL_USER_PROCESS_INFORMATION ProcessInfo
Definition: smmsg.h:161
HANDLE ProcessHandle
Definition: smss.h:67
PVOID SmpHeap
Definition: sminit.c:25
SB_API_NUMBER ApiNumber
Definition: smmsg.h:238
#define IMAGE_SUBSYSTEM_NATIVE
Definition: ntimage.h:436
struct _SB_CREATE_SESSION_MSG SB_CREATE_SESSION_MSG
#define NtCurrentProcess()
Definition: nt_native.h:1657
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
NTSTATUS ReturnValue
Definition: smmsg.h:239
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
union _SB_API_MSG::@3473::@3475::@3477 u
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
ULONG SmBaseTag
Definition: sminit.c:26
PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByType(IN ULONG MuSessionId, IN ULONG ImageType)
Definition: smsubsys.c:102
HANDLE SbApiPort
Definition: smss.h:70
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
HANDLE UniqueThread
Definition: compat.h:826
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
HANDLE SmpDebugPort
Definition: sminit.c:27
VOID NTAPI SmpDereferenceSubsystem(IN PSMP_SUBSYSTEM SubSystem)
Definition: smsubsys.c:47
BOOLEAN SmpDbgSsLoaded
Definition: smsessn.c:30
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1105
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
unsigned int ULONG
Definition: retypes.h:1
const char * PCSTR
Definition: typedefs.h:52
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71

Referenced by SmpExecPgm().

◆ SmpSetProcessMuSessionId()

NTSTATUS NTAPI SmpSetProcessMuSessionId ( IN HANDLE  ProcessHandle,
IN ULONG  SessionId 
)

Definition at line 199 of file smsessn.c.

201 {
203 
204  /* Tell the kernel about the session ID */
207  &SessionId,
208  sizeof(SessionId));
209  if (!NT_SUCCESS(Status))
210  {
211  DPRINT1("SMSS: SetProcessMuSessionId, Process=%p, Status=%x\n",
213  }
214 
215  /* Return */
216  return Status;
217 }
ULONG SessionId
Definition: dllmain.c:28
LONG NTSTATUS
Definition: precomp.h:26
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1105
#define DPRINT1
Definition: precomp.h:8
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403

Referenced by SmpExecuteImage().

◆ SmpTerminate()

NTSTATUS NTAPI SmpTerminate ( IN PULONG_PTR  Parameters,
IN ULONG  ParameterMask,
IN ULONG  ParameterCount 
)

Definition at line 374 of file smss.c.

377 {
379  BOOLEAN Old;
380  ULONG Response;
381 
382  /* Give the shutdown privilege to the thread */
385  {
386  /* Thread doesn't have a token, give it to the entire process */
388  }
389 
390  /* Take down the process/machine with a hard error */
392  ParameterCount,
393  ParameterMask,
394  Parameters,
396  &Response);
397 
398  /* Terminate the process if the hard error didn't already */
400 }
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
Definition: harderr.c:551
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define SE_SHUTDOWN_PRIVILEGE
Definition: security.c:673
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
#define STATUS_NO_TOKEN
Definition: ntstatus.h:360
Definition: ncftp.h:89
unsigned int ULONG
Definition: retypes.h:1
struct Response Response
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define STATUS_SYSTEM_PROCESS_TERMINATED
Definition: ntstatus.h:670

Referenced by _main(), SmpInitializeKnownDllsInternal(), and SmpUnhandledExceptionFilter().

◆ SmpTranslateSystemPartitionInformation()

VOID NTAPI SmpTranslateSystemPartitionInformation ( VOID  )

Definition at line 811 of file sminit.c.

812 {
816  HANDLE KeyHandle, LinkHandle;
818  size_t StrLength;
819  WCHAR LinkBuffer[MAX_PATH];
820  CHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 512];
821  PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)ValueBuffer;
822  CHAR DirInfoBuffer[sizeof(OBJECT_DIRECTORY_INFORMATION) + 512];
823  POBJECT_DIRECTORY_INFORMATION DirInfo = (PVOID)DirInfoBuffer;
824 
825  /* Open the setup key */
826  RtlInitUnicodeString(&UnicodeString, L"\\Registry\\Machine\\System\\Setup");
828  &UnicodeString,
830  NULL,
831  NULL);
833  if (!NT_SUCCESS(Status))
834  {
835  DPRINT1("SMSS: Cannot open system setup key for reading: 0x%x\n", Status);
836  return;
837  }
838 
839  /* Query the system partition */
840  RtlInitUnicodeString(&UnicodeString, L"SystemPartition");
842  &UnicodeString,
844  PartialInfo,
845  sizeof(ValueBuffer),
846  &Length);
848  if (!NT_SUCCESS(Status) ||
849  ((PartialInfo->Type != REG_SZ) && (PartialInfo->Type != REG_EXPAND_SZ)))
850  {
851  DPRINT1("SMSS: Cannot query SystemPartition value (Type %lu, Status 0x%x)\n",
852  PartialInfo->Type, Status);
853  return;
854  }
855 
856  /* Initialize the system partition string */
857  RtlInitEmptyUnicodeString(&SystemPartition,
858  (PWCHAR)PartialInfo->Data,
859  PartialInfo->DataLength);
861  SystemPartition.MaximumLength,
862  &StrLength);
863  SystemPartition.Length = (USHORT)StrLength;
864 
865  /* Enumerate the directory looking for the symbolic link string */
866  RtlInitUnicodeString(&SearchString, L"SymbolicLink");
867  RtlInitEmptyUnicodeString(&LinkTarget, LinkBuffer, sizeof(LinkBuffer));
869  DirInfo,
870  sizeof(DirInfoBuffer),
871  TRUE,
872  TRUE,
873  &Context,
874  NULL);
875  if (!NT_SUCCESS(Status))
876  {
877  DPRINT1("SMSS: Cannot find drive letter for system partition\n");
878  return;
879  }
880 
881  /* Keep searching until we find it */
882  do
883  {
884  /* Is this it? */
885  if ((RtlEqualUnicodeString(&DirInfo->TypeName, &SearchString, TRUE)) &&
886  (DirInfo->Name.Length == 2 * sizeof(WCHAR)) &&
887  (DirInfo->Name.Buffer[1] == L':'))
888  {
889  /* Looks like we found it, open the link to get its target */
891  &DirInfo->Name,
894  NULL);
895  Status = NtOpenSymbolicLinkObject(&LinkHandle,
898  if (NT_SUCCESS(Status))
899  {
900  /* Open worked, query the target now */
901  Status = NtQuerySymbolicLinkObject(LinkHandle,
902  &LinkTarget,
903  NULL);
904  NtClose(LinkHandle);
905 
906  /* Check if it matches the string we had found earlier */
907  if ((NT_SUCCESS(Status)) &&
909  &LinkTarget,
910  TRUE)) ||
912  &LinkTarget,
913  TRUE)) &&
914  (LinkTarget.Buffer[SystemPartition.Length / sizeof(WCHAR)] == L'\\'))))
915  {
916  /* All done */
917  break;
918  }
919  }
920  }
921 
922  /* Couldn't find it, try again */
924  DirInfo,
925  sizeof(DirInfoBuffer),
926  TRUE,
927  FALSE,
928  &Context,
929  NULL);
930  } while (NT_SUCCESS(Status));
931  if (!NT_SUCCESS(Status))
932  {
933  DPRINT1("SMSS: Cannot find drive letter for system partition\n");
934  return;
935  }
936 
937  /* Open the setup key again, for full access this time */
939  L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup");
941  &UnicodeString,
943  NULL,
944  NULL);
946  if (!NT_SUCCESS(Status))
947  {
948  DPRINT1("SMSS: Cannot open software setup key for writing: 0x%x\n",
949  Status);
950  return;
951  }
952 
953  /* Wrap up the end of the link buffer */
954  wcsncpy(LinkBuffer, DirInfo->Name.Buffer, 2);
955  LinkBuffer[2] = L'\\';
956  LinkBuffer[3] = L'\0';
957 
958  /* Now set this as the "BootDir" */
961  &UnicodeString,
962  0,
963  REG_SZ,
964  LinkBuffer,
965  4 * sizeof(WCHAR));
966  if (!NT_SUCCESS(Status))
967  {
968  DPRINT1("SMSS: couldn't write BootDir value: 0x%x\n", Status);
969  }
971 }
HANDLE SmpDosDevicesObjectDirectory
Definition: sminit.c:27
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS</