ReactOS 0.4.15-dev-7961-gdcf9eb0
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);
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 */
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
113Quickie:
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_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI NtOpenProcessToken(IN HANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, OUT PHANDLE TokenHandle)
Definition: security.c:350
#define STATUS_NOT_ALL_ASSIGNED
Definition: ntstatus.h:85
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
PVOID SmpHeap
Definition: sminit.c:25
_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
uint32_t ULONG
Definition: typedefs.h:59
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
FORCEINLINE LUID NTAPI_INLINE RtlConvertUlongToLuid(_In_ ULONG Val)
Definition: rtlfuncs.h:3541
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:930
#define TOKEN_QUERY
Definition: setypes.h:928
struct _TOKEN_PRIVILEGES * PTOKEN_PRIVILEGES
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63

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 DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
ULONG SessionId
Definition: dllmain.c:28
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define InsertTailList(ListHead, Entry)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
LIST_ENTRY SmpSessionListHead
Definition: smsessn.c:27
RTL_CRITICAL_SECTION SmpSessionListLock
Definition: smsessn.c:26
BOOLEAN SmpNextSessionIdScanMode
Definition: smsessn.c:29
ULONG SmpNextSessionId
Definition: smsessn.c:28
PSMP_SUBSYSTEM Subsystem
Definition: smsessn.c:22
LIST_ENTRY Entry
Definition: smsessn.c:20
PSMP_SUBSYSTEM OtherSubsystem
Definition: smsessn.c:23
ULONG SessionId
Definition: smsessn.c:21

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 */
453 &ReplyMsg->h,
454 &RequestMsg.h);
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}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
@ ProcessBasicInformation
Definition: winternl.h:394
long __cdecl _InterlockedExchangeAdd(_Interlocked_operand_ long volatile *_Addend, long _Value)
#define LPC_CONNECTION_REQUEST
Definition: port.c:102
#define LPC_PORT_CLOSED
Definition: port.c:97
NTSYSAPI NTSTATUS __cdecl RtlSetThreadIsCritical(_In_ BOOLEAN NewValue, _Out_opt_ PBOOLEAN OldValue, _In_ BOOLEAN NeedBreaks)
_In_ PVOID ClientContext
Definition: netioddk.h:55
NTSTATUS NTAPI NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
Definition: wait.c:876
NTSTATUS NTAPI NtReplyWaitReceivePort(IN HANDLE PortHandle, OUT PVOID *PortContext OPTIONAL, IN PPORT_MESSAGE ReplyMessage OPTIONAL, OUT PPORT_MESSAGE ReceiveMessage)
Definition: reply.c:743
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
static ULONG Timeout
Definition: ping.c:61
HANDLE SmUniqueProcessId
Definition: smloop.c:34
NTSTATUS NTAPI SmpHandleConnectionRequest(IN HANDLE SmApiPort, IN PSB_API_MSG SbApiMsg)
Definition: smloop.c:273
volatile LONG SmTotalApiThreads
Definition: smloop.c:33
PSM_API_HANDLER SmpApiDispatch[SmpMaxApiNumber - SmpCreateForeignSessionApi]
Definition: smloop.c:258
@ SmpTerminateForeignSessionApi
Definition: smmsg.h:30
@ SmpMaxApiNumber
Definition: smmsg.h:36
HANDLE SmApiPort
Definition: smss.c:23
NTSTATUS ReturnValue
Definition: smmsg.h:106
PORT_MESSAGE h
Definition: smmsg.h:104
SMSRV_API_NUMBER ApiNumber
Definition: smmsg.h:105
PVOID HANDLE
Definition: typedefs.h:73
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

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}
unsigned char BOOLEAN
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG MuSessionId
Definition: smss.h:72
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

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}

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(),
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}
#define STANDARD_DRIVE_LETTER_OFFSET
Definition: pagefile.c:22
#define SMP_PAGEFILE_SYSTEM_MANAGED
Definition: pagefile.c:89
#define MEGABYTE
Definition: pagefile.c:24
#define SMP_PAGEFILE_ON_ANY_DRIVE
Definition: pagefile.c:91
BOOLEAN SmpRegistrySpecifierPresent
Definition: pagefile.c:123
ULONG SmpNumberOfPagingFiles
Definition: pagefile.c:124
#define MAX_PAGING_FILES
Definition: pagefile.c:23
LIST_ENTRY SmpPagingFileDescriptorList
Definition: pagefile.c:122
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
const GLubyte * c
Definition: glext.h:8905
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define c
Definition: ke_i.h:80
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STATUS_TOO_MANY_PAGING_FILES
Definition: ntstatus.h:387
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
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
#define DPRINT
Definition: sndvol32.h:71
USHORT MaximumLength
Definition: env_spec_w32.h:370
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by SmpLoadDataFromRegistry().

◆ SmpCreatePagingFiles()

NTSTATUS NTAPI SmpCreatePagingFiles ( VOID  )

Definition at line 1049 of file pagefile.c.

1050{
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 */
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}
NTSTATUS NTAPI SmpCreateEmergencyPagingFile(VOID)
Definition: pagefile.c:834
NTSTATUS NTAPI SmpCreatePagingFileOnAnyDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:667
#define FUZZ_FACTOR
Definition: pagefile.c:82
NTSTATUS NTAPI SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:535
NTSTATUS NTAPI SmpCreateSystemManagedPagingFile(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN BOOLEAN DecreaseSize)
Definition: pagefile.c:801
NTSTATUS NTAPI SmpCreateVolumeDescriptors(VOID)
Definition: pagefile.c:869
NTSTATUS NTAPI SmpValidatePagingFileSizes(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:749
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define ASSERT(a)
Definition: mode.c:44
LONGLONG QuadPart
Definition: typedefs.h:114

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
1129NextAcl:
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
1172NotInitial:
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
1267Quickie:
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}
PSID WorldSid
Definition: globals.c:15
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
@ Ace
Definition: card.h:12
#define GENERIC_READ
Definition: compat.h:135
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
struct _ACL ACL
static PSID AdminSid
Definition: msgina.c:39
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
#define GENERIC_ALL
Definition: nt_native.h:92
#define GENERIC_WRITE
Definition: nt_native.h:90
#define GENERIC_EXECUTE
Definition: nt_native.h:91
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
ULONG SmpProtectionMode
Definition: sminit.c:41
SECURITY_DESCRIPTOR SmpApiPortSDBody
Definition: sminit.c:37
SECURITY_DESCRIPTOR SmpLiberalSDBody
Definition: sminit.c:36
PISECURITY_DESCRIPTOR SmpLiberalSecurityDescriptor
Definition: sminit.c:38
SECURITY_DESCRIPTOR SmpKnownDllsSDBody
Definition: sminit.c:36
PISECURITY_DESCRIPTOR SmpKnownDllsSecurityDescriptor
Definition: sminit.c:39
PISECURITY_DESCRIPTOR SmpApiPortSecurityDescriptor
Definition: sminit.c:39
SECURITY_DESCRIPTOR SmpPrimarySDBody
Definition: sminit.c:36
PISECURITY_DESCRIPTOR SmpPrimarySecurityDescriptor
Definition: sminit.c:38
_In_ ULONG AclLength
Definition: rtlfuncs.h:1842
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:747
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
#define ACL_REVISION2
Definition: setypes.h:43
#define SECURITY_RESTRICTED_CODE_RID
Definition: setypes.h:569
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define OBJECT_INHERIT_ACE
Definition: setypes.h:746
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define SECURITY_CREATOR_OWNER_RID
Definition: setypes.h:545
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
#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 */
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}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
PSMP_SESSION NTAPI SmpSessionIdToSession(IN ULONG SessionId)
Definition: smsessn.c:70

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}
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{
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 */
237 {
238 /* Run it */
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:2711
struct _FileName FileName
Definition: fatprocs.h:896
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
NTSTATUS NTAPI SmpInvokeAutoChk(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING Arguments, IN ULONG Flags)
Definition: smss.c:149
#define SMP_AUTOCHK_FLAG
Definition: smss.h:46
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 SMP_DEBUG_FLAG
Definition: smss.h:44
#define SMP_INVALID_PATH
Definition: smss.h:48
#define SMP_SUBSYSTEM_FLAG
Definition: smss.h:47
base for all directory entries
Definition: entries.h:138
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

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,
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",
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 */
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 {
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",
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 */
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}
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS NTAPI RtlDestroyProcessParameters(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
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)
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)
#define RTL_USER_PROCESS_PARAMETERS_NX
Definition: rtltypes.h:55
#define RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB
Definition: rtltypes.h:46
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
#define IMAGE_SUBSYSTEM_NATIVE
Definition: ntimage.h:436
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
UNICODE_STRING SmpDefaultLibPath
Definition: sminit.c:29
PWCHAR SmpDefaultEnvironment
Definition: sminit.c:28
NTSTATUS NTAPI SmpSetProcessMuSessionId(IN HANDLE ProcessHandle, IN ULONG SessionId)
Definition: smsessn.c:199
BOOLEAN SmpDebug
Definition: smss.c:22
#define SMP_DEFERRED_FLAG
Definition: smss.h:49
#define SMP_ASYNC_FLAG
Definition: smss.h:45
SECTION_IMAGE_INFORMATION ImageInformation
Definition: rtltypes.h:1573

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{
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);
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}
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
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 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
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
HANDLE SmpInitialCommandProcessId
Definition: smss.c:24
HANDLE UniqueProcess
Definition: compat.h:825

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}
@ ProcessSessionInformation
Definition: winternl.h:880
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403

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");
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,
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}
static UNICODE_STRING PortName
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define OBJ_PERMANENT
Definition: winternl.h:226
@ ProcessDefaultHardErrorMode
Definition: winternl.h:868
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
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)
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
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
NTSTATUS NTAPI NtCreatePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:222
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1105
ULONG NTAPI RtlCreateTagHeap(_In_ HANDLE HeapHandle, _In_ ULONG Flags, _In_opt_ PWSTR TagName, _In_ PWSTR TagSubName)
Definition: heap.c:4018
HANDLE SmpDebugPort
Definition: sminit.c:27
#define SMSS_CHECKPOINT(x, y)
Definition: sminit.c:44
UNICODE_STRING PosixName
Definition: sminit.c:18
UNICODE_STRING Os2Name
Definition: sminit.c:18
NTSTATUS NTAPI SmpLoadDataFromRegistry(OUT PUNICODE_STRING InitialCommand)
Definition: sminit.c:2243
ULONG SmBaseTag
Definition: sminit.c:26
UNICODE_STRING SmpSubsystemName
Definition: sminit.c:18
LIST_ENTRY NativeProcessList
Definition: sminit.c:23
NTSTATUS NTAPI SmpCreateSecurityDescriptors(IN BOOLEAN InitialCall)
Definition: sminit.c:975
ULONG NTAPI SmpApiLoop(IN PVOID Parameter)
Definition: smloop.c:423
BOOLEAN SmpDbgSsLoaded
Definition: smsessn.c:30
HANDLE SmpWindowsSubSysProcess
Definition: smsubsys.c:20
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857

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;
154
155 /* Make sure this is a found subsystem */
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 */
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? */
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;
260 CreateProcess->In.DebugFlags = SmpDebug;
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 */
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");
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
440Quickie:
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 */
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
489Quickie2:
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}
NTSYSAPI NTSTATUS NTAPI NtSetSystemInformation(IN INT SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength)
MMRESULT CreateSession(DeviceType device_type, UINT device_id, SessionInfo **session_info)
Definition: session.c:63
#define SE_LOAD_DRIVER_PRIVILEGE
Definition: security.c:664
@ SystemSessionDetach
Definition: extypes.h:265
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
@ NotificationEvent
#define IMAGE_SUBSYSTEM_POSIX_CUI
Definition: ntimage.h:440
#define IMAGE_SUBSYSTEM_OS2_CUI
Definition: ntimage.h:439
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
NTSTATUS NTAPI NtRequestWaitReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE LpcRequest, IN OUT PPORT_MESSAGE LpcReply)
Definition: send.c:696
#define STATUS_WAIT_0
Definition: ntstatus.h:237
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define STATUS_NO_SUCH_PACKAGE
Definition: ntstatus.h:490
struct _SB_CREATE_SESSION_MSG SB_CREATE_SESSION_MSG
@ SbpCreateSession
Definition: smmsg.h:146
struct _SB_API_MSG SB_API_MSG
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
VOID NTAPI SmpDeleteSession(IN ULONG SessionId)
Definition: smsessn.c:98
ULONG AttachedSessionId
Definition: smss.c:21
#define SMP_OS2_FLAG
Definition: smss.h:51
VOID NTAPI SmpReleasePrivilege(IN PVOID State)
Definition: smutil.c:129
#define SMP_POSIX_FLAG
Definition: smss.h:50
NTSTATUS NTAPI SmpAcquirePrivilege(IN ULONG Privilege, OUT PVOID *PrivilegeStat)
Definition: smutil.c:40
HANDLE SmpWindowsSubSysProcess
Definition: smsubsys.c:20
NTSTATUS NTAPI SmpCallCsrCreateProcess(IN PSB_API_MSG SbApiMsg, IN USHORT MessageLength, IN HANDLE PortHandle)
Definition: smsubsys.c:29
VOID NTAPI SmpDereferenceSubsystem(IN PSMP_SUBSYSTEM SubSystem)
Definition: smsubsys.c:47
PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByType(IN ULONG MuSessionId, IN ULONG ImageType)
Definition: smsubsys.c:102
HANDLE SmpWindowsSubSysProcessId
Definition: smsubsys.c:21
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19
NTSTATUS ReturnValue
Definition: smmsg.h:239
SB_API_NUMBER ApiNumber
Definition: smmsg.h:238
SB_CREATE_PROCESS_MSG CreateProcess
Definition: smmsg.h:245
SB_CREATE_SESSION_MSG CreateSession
Definition: smmsg.h:242
PORT_MESSAGE h
Definition: smmsg.h:232
union _SB_API_MSG::@3530::@3532::@3534 u
HANDLE ProcessHandle
Definition: smss.h:67
HANDLE SbApiPort
Definition: smss.h:70
CLIENT_ID ClientId
Definition: smss.h:71
HANDLE Event
Definition: smss.h:66
ULONG ImageType
Definition: smss.h:68
BOOLEAN Terminating
Definition: smss.h:73
LIST_ENTRY Entry
Definition: smss.h:65
HANDLE PortHandle
Definition: smss.h:69
ULONG ReferenceCount
Definition: smss.h:74
#define CreateProcess
Definition: winbase.h:3758

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 */
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}
#define SystemExtendServiceTableInformation
Definition: DriverTester.h:35
#define REG_SZ
Definition: layer.c:22
NTSTATUS NTAPI LdrQueryImageFileExecutionOptions(_In_ PUNICODE_STRING SubKey, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
Definition: ldrinit.c:389
@ SystemSessionCreate
Definition: extypes.h:264
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1909
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 UNICODE_NULL
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
LIST_ENTRY SmpSubSystemList
Definition: sminit.c:22
LIST_ENTRY SmpSubSystemsToLoad
Definition: sminit.c:22
LIST_ENTRY SmpExecuteList
Definition: sminit.c:23
VOID NTAPI SmpTranslateSystemPartitionInformation(VOID)
Definition: sminit.c:811
LIST_ENTRY SmpSetupExecuteList
Definition: sminit.c:19
NTSTATUS NTAPI SmpExecuteCommand(IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, OUT PHANDLE ProcessId, IN ULONG Flags)
Definition: smss.c:210
WCHAR InitialCommandBuffer[256]
Definition: smsubsys.c:23
Registry entry.
Definition: regfs.h:31
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122

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}
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151

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}
ImageType
Definition: gdiplusenums.h:193

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

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{
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 */
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 */
288 }
290 {
291 /* Asynch requested, convert into a 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 */
306 RtlFreeHeap(SmpHeap, 0, Token.Buffer);
307 }
308
309 /* Initialize a string to hold the current path */
310 RtlInitUnicodeString(&EnvString, L"Path");
312 RtlInitEmptyUnicodeString(&PathString,
314 (USHORT)Length);
315 if (!PathString.Buffer)
316 {
317 /* Fail if we have no memory for this */
318 RtlFreeHeap(SmpHeap, 0, Token.Buffer);
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 */
339 RtlFreeHeap(SmpHeap, 0, Token.Buffer);
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 */
388 RtlFreeHeap(SmpHeap, 0, Token.Buffer);
389 RtlFreeHeap(SmpHeap, 0, PathString.Buffer);
390 if (!NT_SUCCESS(Status)) return Status;
391
392 /* Convert it and bail out if this failed */
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;
415 }
416 }
417
418 /* We are done -- move on to the second pass to get the arguments */
419 return SmpParseToken(&CmdLineCopy, TRUE, Arguments);
420}
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define MAX_PATH
Definition: compat.h:34
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
NTSYSAPI ULONG NTAPI RtlDosSearchPath_U(_In_ PCWSTR Path, _In_ PCWSTR FileName, _In_ PCWSTR Extension, _In_ ULONG BufferSize, _Out_ PWSTR Buffer, _Out_ PWSTR *PartName)
NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U(_In_opt_ PWSTR Environment, _In_ PCUNICODE_STRING Name, _Out_ PUNICODE_STRING Value)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
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 SharedUserData
UNICODE_STRING SmpSystemRoot
Definition: smss.c:20
NTSTATUS NTAPI SmpParseToken(IN PUNICODE_STRING Input, IN BOOLEAN SecondPass, OUT PUNICODE_STRING Token)
Definition: smutil.c:155
UNICODE_STRING SmpAutoChkKeyword
Definition: smutil.c:34
UNICODE_STRING SmpDebugKeyword
Definition: smutil.c:34
UNICODE_STRING SmpASyncKeyword
Definition: smutil.c:34
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

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

◆ SmpQueryRegistrySosOption()

BOOLEAN NTAPI SmpQueryRegistrySosOption ( VOID  )

Definition at line 424 of file smutil.c.

425{
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}
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_READ
Definition: nt_native.h:1023
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 REG_EXPAND_SZ
Definition: nt_native.h:1494
#define VALUE_BUFFER_SIZE
Definition: smutil.c:23
void * PVOID
Definition: typedefs.h:50
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243

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}
struct _SMP_PRIVILEGE_STATE * PSMP_PRIVILEGE_STATE

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}
@ RtlBsdItemBootShutdown
Definition: rtltypes.h:431
@ RtlBsdItemBootGood
Definition: rtltypes.h:430
NTSTATUS NTAPI RtlLockBootStatusData(_Out_ PHANDLE FileHandle)
Definition: bootdata.c:231
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
NTSTATUS NTAPI RtlUnlockBootStatusData(_In_ HANDLE FileHandle)
Definition: bootdata.c:267

Referenced by SmpInvokeAutoChk().

◆ SmpSaveAndClearBootStatusData()

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

Definition at line 481 of file smutil.c.

483{
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}
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

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);
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,
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}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define InsertHeadList(ListHead, Entry)
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
@ ProcessDebugPort
Definition: winternl.h:395
#define sprintf(buf, format,...)
Definition: sprintf.c:55
NTSTATUS NTAPI SmpGetProcessMuSessionId(IN HANDLE ProcessHandle, OUT PULONG SessionId)
Definition: smsessn.c:168
VOID NTAPI SmpDereferenceSubsystem(IN PSMP_SUBSYSTEM SubSystem)
Definition: smsubsys.c:47
PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByType(IN ULONG MuSessionId, IN ULONG ImageType)
Definition: smsubsys.c:102
HANDLE UniqueThread
Definition: compat.h:826
CLIENT_ID DbgUiClientId
Definition: smmsg.h:164
RTL_USER_PROCESS_INFORMATION ProcessInfo
Definition: smmsg.h:161
const char * PCSTR
Definition: typedefs.h:52
uint64_t ULONGLONG
Definition: typedefs.h:67
char CHAR
Definition: xmlstorage.h:175

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}

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;
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,
396 &Response);
397
398 /* Terminate the process if the hard error didn't already */
400}
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 SE_SHUTDOWN_PRIVILEGE
Definition: security.c:673
@ OptionShutdownSystem
Definition: extypes.h:192
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
#define STATUS_NO_TOKEN
Definition: ntstatus.h:360
#define STATUS_SYSTEM_PROCESS_TERMINATED
Definition: ntstatus.h:670
Definition: ncftp.h:89
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869

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");
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");
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 */
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");
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" */
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}
struct _OBJECT_DIRECTORY_INFORMATION OBJECT_DIRECTORY_INFORMATION
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
_Must_inspect_result_ NTSTRSAFEAPI RtlStringCbLengthW(_In_reads_or_z_(cbMax/sizeof(wchar_t)) STRSAFE_LPCWSTR psz, _In_ _In_range_(1, NTSTRSAFE_MAX_CCH *sizeof(wchar_t)) size_t cbMax, _Out_opt_ _Deref_out_range_(<, cbMax - 1) size_t *pcbLength)
Definition: ntstrsafe.h:1641
NTSTATUS NTAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PVOID Buffer, IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan, IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
Definition: obdir.c:490
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
HANDLE SmpDosDevicesObjectDirectory
Definition: sminit.c:27
static PPARTENTRY SystemPartition
Definition: usetup.c:61
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292

Referenced by SmpLoadSubSystemsForMuSession().

Variable Documentation

◆ AttachedSessionId

ULONG AttachedSessionId
extern

Definition at line 21 of file smss.c.

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

◆ RegPosixSingleInstance

BOOLEAN RegPosixSingleInstance
extern

Definition at line 22 of file smsubsys.c.

Referenced by SmpConfigureSubSystems().

◆ SmBaseTag

◆ SmpASyncKeyword

UNICODE_STRING SmpASyncKeyword

Definition at line 90 of file smss.h.

Referenced by SmpLoadDataFromRegistry().

◆ SmpAutoChkKeyword

UNICODE_STRING SmpAutoChkKeyword

Definition at line 90 of file smss.h.

Referenced by SmpLoadDataFromRegistry().

◆ SmpDbgSsLoaded

BOOLEAN SmpDbgSsLoaded
extern

Definition at line 30 of file smsessn.c.

Referenced by SmpInit(), and SmpSbCreateSession().

◆ SmpDebug

BOOLEAN SmpDebug
extern

Definition at line 22 of file smss.c.

Referenced by _main(), SmExecuteProgram(), SmpExecuteImage(), and SmpLoadSubSystem().

◆ SmpDebugKeyword

UNICODE_STRING SmpDebugKeyword
extern

Definition at line 34 of file smutil.c.

Referenced by SmpLoadDataFromRegistry(), and SmpParseCommandLine().

◆ SmpDefaultEnvironment

PWCHAR SmpDefaultEnvironment
extern

◆ SmpDefaultLibPath

UNICODE_STRING SmpDefaultLibPath
extern

◆ SmpExecuteList

LIST_ENTRY SmpExecuteList
extern

Definition at line 23 of file sminit.c.

Referenced by SmpLoadDataFromRegistry(), and SmpLoadSubSystemsForMuSession().

◆ SmpHeap

◆ SmpKnownSubSysHead

◆ SmpKnownSubSysLock

◆ SmpNextSessionId

ULONG SmpNextSessionId
extern

Definition at line 28 of file smsessn.c.

Referenced by SmpAllocateSessionId(), and SmpInit().

◆ SmpNextSessionIdScanMode

BOOLEAN SmpNextSessionIdScanMode
extern

Definition at line 29 of file smsessn.c.

Referenced by SmpAllocateSessionId(), and SmpInit().

◆ SmpSessionListHead

LIST_ENTRY SmpSessionListHead
extern

Definition at line 27 of file smsessn.c.

Referenced by SmpAllocateSessionId(), SmpInit(), and SmpSessionIdToSession().

◆ SmpSessionListLock

RTL_CRITICAL_SECTION SmpSessionListLock
extern

Definition at line 26 of file smsessn.c.

Referenced by SmpAllocateSessionId(), SmpDeleteSession(), and SmpInit().

◆ SmpSessionsObjectDirectory

HANDLE SmpSessionsObjectDirectory
extern

Definition at line 31 of file smsessn.c.

Referenced by SmpLoadDataFromRegistry().

◆ SmpSetupExecuteList

LIST_ENTRY SmpSetupExecuteList
extern

Definition at line 19 of file sminit.c.

Referenced by SmpLoadDataFromRegistry(), and SmpLoadSubSystemsForMuSession().

◆ SmpSubSystemList

LIST_ENTRY SmpSubSystemList
extern

Definition at line 22 of file sminit.c.

Referenced by SmpLoadDataFromRegistry(), and SmpLoadSubSystemsForMuSession().

◆ SmpSubSystemsToDefer

LIST_ENTRY SmpSubSystemsToDefer
extern

◆ SmpSubSystemsToLoad

LIST_ENTRY SmpSubSystemsToLoad
extern

◆ SmpSystemRoot

UNICODE_STRING SmpSystemRoot
extern

Definition at line 20 of file smss.c.

Referenced by SmpParseCommandLine().

◆ SmpWindowsSubSysProcess

HANDLE SmpWindowsSubSysProcess
extern

Definition at line 20 of file smsubsys.c.

Referenced by SmpInit(), and SmpLoadSubSystem().

◆ SmpWindowsSubSysProcessId

HANDLE SmpWindowsSubSysProcessId
extern

Definition at line 21 of file smsubsys.c.

Referenced by SmpLoadDataFromRegistry(), and SmpLoadSubSystem().