ReactOS 0.4.17-dev-650-gd0e71de
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 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 35 of file smutil.c.

37{
39 ULONG Size;
41
42 /* Assume failure */
43 *PrivilegeState = NULL;
44
45 /* Acquire the state structure to hold everything we need */
47 0,
48 sizeof(SMP_PRIVILEGE_STATE) +
49 sizeof(TOKEN_PRIVILEGES) +
50 sizeof(LUID_AND_ATTRIBUTES));
51 if (!State) return STATUS_NO_MEMORY;
52
53 /* Open our token */
56 &State->TokenHandle);
57 if (!NT_SUCCESS(Status))
58 {
59 /* Fail */
61 return Status;
62 }
63
64 /* Set one privilege in the enabled state */
65 State->NewPrivileges = &State->NewBuffer;
66 State->OldPrivileges = (PTOKEN_PRIVILEGES)&State->OldBuffer;
67 State->NewPrivileges->PrivilegeCount = 1;
68 State->NewPrivileges->Privileges[0].Luid = RtlConvertUlongToLuid(Privilege);
69 State->NewPrivileges->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
70
71 /* Adjust the privileges in the token */
72 Size = sizeof(State->OldBuffer);
74 FALSE,
75 State->NewPrivileges,
76 Size,
77 State->OldPrivileges,
78 &Size);
80 {
81 /* Our static buffer is not big enough, allocate a bigger one */
82 State->OldPrivileges = RtlAllocateHeap(SmpHeap, 0, Size);
83 if (!State->OldPrivileges)
84 {
85 /* Out of memory, fail */
87 goto Quickie;
88 }
89
90 /* Now try again */
92 FALSE,
93 State->NewPrivileges,
94 Size,
95 State->OldPrivileges,
96 &Size);
97 }
98
99 /* Normalize failure code and check for success */
101 if (NT_SUCCESS(Status))
102 {
103 /* We got the privilege, return */
104 *PrivilegeState = State;
105 return STATUS_SUCCESS;
106 }
107
108Quickie:
109 /* Check if we used a dynamic buffer */
110 if (State->OldPrivileges != (PTOKEN_PRIVILEGES)&State->OldBuffer)
111 {
112 /* Free it */
113 RtlFreeHeap(SmpHeap, 0, State->OldPrivileges);
114 }
115
116 /* Close the token handle and free the state structure */
117 NtClose(State->TokenHandle);
119 return Status;
120}
#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:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
#define NtCurrentProcess()
Definition: nt_native.h:1660
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3419
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:138
#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:4539
FORCEINLINE LUID NTAPI_INLINE RtlConvertUlongToLuid(_In_ ULONG Val)
Definition: rtlfuncs.h:3558
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:942
#define TOKEN_QUERY
Definition: setypes.h:940
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: cicbase.cpp:63
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#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_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:211
static ULONG Timeout
Definition: ping.c:61
long __cdecl _InterlockedExchangeAdd(_Interlocked_operand_ long volatile *_Addend, long _Value)
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
#define STATUS_PENDING
Definition: telnetd.h:14
PVOID HANDLE
Definition: typedefs.h:73
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336

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
Definition: actypes.h:127
Entry
Definition: section.c:5216
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19
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
#define L(x)
Definition: resources.c:13
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:177
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:481
short WCHAR
Definition: pedump.c:58
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:228
#define DPRINT
Definition: sndvol32.h:73
USHORT MaximumLength
Definition: env_spec_w32.h:370
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342

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 998 of file sminit.c.

999{
1001 PSID WorldSid = NULL, AdminSid = NULL, SystemSid = NULL;
1002 PSID RestrictedSid = NULL, OwnerSid = NULL;
1006 ULONG AclLength, SidLength;
1007 PACL Acl;
1009 BOOLEAN ProtectionRequired = FALSE;
1010
1011 /* Check if this is the first call */
1012 if (InitialCall)
1013 {
1014 /* Create and set the primary descriptor */
1020 TRUE,
1021 NULL,
1022 FALSE);
1024
1025 /* Create and set the liberal descriptor */
1031 TRUE,
1032 NULL,
1033 FALSE);
1035
1036 /* Create and set the \KnownDlls descriptor */
1042 TRUE,
1043 NULL,
1044 FALSE);
1046
1047 /* Create and Set the \ApiPort descriptor */
1053 TRUE,
1054 NULL,
1055 FALSE);
1057 }
1058
1059 /* Check if protection was requested in the registry (on by default) */
1060 if (SmpProtectionMode & 1) ProtectionRequired = TRUE;
1061
1062 /* Exit if there's nothing to do */
1063 if (!(InitialCall || ProtectionRequired)) return STATUS_SUCCESS;
1064
1065 /* Build the world SID */
1068 0, 0, 0, 0, 0, 0, 0,
1069 &WorldSid);
1070 if (!NT_SUCCESS(Status))
1071 {
1072 WorldSid = NULL;
1073 goto Quickie;
1074 }
1075
1076 /* Build the admin SID */
1080 0, 0, 0, 0, 0, 0,
1081 &AdminSid);
1082 if (!NT_SUCCESS(Status))
1083 {
1084 AdminSid = NULL;
1085 goto Quickie;
1086 }
1087
1088 /* Build the owner SID */
1089 Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
1091 0, 0, 0, 0, 0, 0, 0,
1092 &OwnerSid);
1093 if (!NT_SUCCESS(Status))
1094 {
1095 OwnerSid = NULL;
1096 goto Quickie;
1097 }
1098
1099 /* Build the restricted SID */
1102 0, 0, 0, 0, 0, 0, 0,
1103 &RestrictedSid);
1104 if (!NT_SUCCESS(Status))
1105 {
1106 RestrictedSid = NULL;
1107 goto Quickie;
1108 }
1109
1110 /* Build the system SID */
1113 0, 0, 0, 0, 0, 0, 0,
1114 &SystemSid);
1115 if (!NT_SUCCESS(Status))
1116 {
1117 SystemSid = NULL;
1118 goto Quickie;
1119 }
1120
1121 /* Now check if we're creating the core descriptors */
1122 if (!InitialCall)
1123 {
1124 /* We're skipping NextAcl so we have to do this here */
1125 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1126 SidLength *= 2;
1127 goto NotInitial;
1128 }
1129
1130 /* Allocate an ACL with two ACEs with two SIDs each */
1131 SidLength = RtlLengthSid(SystemSid) + RtlLengthSid(AdminSid);
1132 AclLength = sizeof(ACL) + 2 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1133 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1134 if (!Acl) Status = STATUS_NO_MEMORY;
1135 if (!NT_SUCCESS(Status)) goto NextAcl;
1136
1137 /* Now build the ACL and add the two ACEs */
1144
1145 /* Set this as the DACL */
1147 TRUE,
1148 Acl,
1149 FALSE);
1151
1152NextAcl:
1153 /* Allocate an ACL with 6 ACEs, two ACEs per SID */
1154 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1155 SidLength *= 2;
1156 AclLength = sizeof(ACL) + 6 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1157 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1158 if (!Acl) Status = STATUS_NO_MEMORY;
1159 if (!NT_SUCCESS(Status)) goto NotInitial;
1160
1161 /* Now build the ACL and add the six ACEs */
1176
1177 /* Now edit the last three ACEs and make them inheritable */
1178 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1181 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1184 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1187
1188 /* Set this as the DACL */
1190 TRUE,
1191 Acl,
1192 FALSE);
1194
1195NotInitial:
1196 /* The initial ACLs have been created, are we also protecting objects? */
1197 if (!ProtectionRequired) goto Quickie;
1198
1199 /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1200 SidLength += RtlLengthSid(OwnerSid);
1201 AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1202 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1203 if (!Acl) Status = STATUS_NO_MEMORY;
1204 if (!NT_SUCCESS(Status)) goto Quickie;
1205
1206 /* Build the ACL and add the seven ACEs */
1223
1224 /* Edit the last 4 ACEs to make then inheritable */
1225 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1228 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1231 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1234 Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1237
1238 /* Set this as the DACL for the primary SD */
1240 TRUE,
1241 Acl,
1242 FALSE);
1244
1245 /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1246 AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1247 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1248 if (!Acl) Status = STATUS_NO_MEMORY;
1249 if (!NT_SUCCESS(Status)) goto Quickie;
1250
1251 /* Build the ACL and add the seven ACEs */
1268
1269 /* Edit the last 4 ACEs to make then inheritable */
1270 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1273 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1276 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1279 Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1282
1283 /* Now set this as the DACL for the liberal SD */
1285 TRUE,
1286 Acl,
1287 FALSE);
1289
1290Quickie:
1291 /* Cleanup the SIDs */
1292 if (OwnerSid) RtlFreeHeap(RtlGetProcessHeap(), 0, OwnerSid);
1293 if (AdminSid) RtlFreeHeap(RtlGetProcessHeap(), 0, AdminSid);
1294 if (WorldSid) RtlFreeHeap(RtlGetProcessHeap(), 0, WorldSid);
1295 if (SystemSid) RtlFreeHeap(RtlGetProcessHeap(), 0, SystemSid);
1296 if (RestrictedSid) RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSid);
1297 return Status;
1298}
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
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
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
_In_ ULONG AclLength
Definition: rtlfuncs.h:1859
#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 207 of file smss.c.

211{
214
215 /* There's no longer a debugging subsystem */
216 if (Flags & SMP_DEBUG_FLAG) return STATUS_SUCCESS;
217
218 /* Parse the command line to see what execution flags are requested */
219 Status = SmpParseCommandLine(CommandLine,
220 &Flags,
221 &FileName,
222 &Directory,
223 &Arguments);
224 if (!NT_SUCCESS(Status))
225 {
226 /* Fail if we couldn't do that */
227 DPRINT1("SMSS: SmpParseCommandLine(%wZ) failed - Status == %lx\n",
228 CommandLine, Status);
229 return Status;
230 }
231
232 /* Check if autochk is requested */
234 {
235 /* Run it */
237 }
238 else if (Flags & SMP_SUBSYSTEM_FLAG)
239 {
241 &Directory,
242 CommandLine,
243 MuSessionId,
244 ProcessId,
245 Flags);
246 }
247 else if (Flags & SMP_INVALID_PATH)
248 {
249 /* An invalid image was specified, fail */
250 DPRINT1("SMSS: Image file (%wZ) not found\n", &FileName);
252 }
253 else
254 {
255 /* An actual image name was present, execute it */
257 &Directory,
258 CommandLine,
259 MuSessionId,
260 Flags,
261 NULL);
262 }
263
264 /* Free all the token parameters */
265 if (FileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
266 if (Directory.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Directory.Buffer);
267 if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);
268
269 /* Return to the caller */
270 if (!NT_SUCCESS(Status))
271 {
272 DPRINT1("SMSS: Command '%wZ' failed - Status == %x\n",
273 CommandLine, Status);
274 }
275 return Status;
276}
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2712
struct _FileName FileName
Definition: fatprocs.h:897
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3962
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
#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}
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:453
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
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:1600

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 280 of file smss.c.

284{
288 ULONG Flags = 0;
289
290 /* Check if we haven't yet connected to ourselves */
291 if (!SmApiPort)
292 {
293 /* Connect to ourselves, as a client */
295 if (!NT_SUCCESS(Status))
296 {
297 DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status);
298 return Status;
299 }
300 }
301
302 /* Parse the initial command line */
303 Status = SmpParseCommandLine(InitialCommand,
304 &Flags,
305 &FileName,
306 &Directory,
307 &Arguments);
309 {
310 /* Fail if it doesn't exist */
311 DPRINT1("SMSS: Initial command image (%wZ) not found\n", &FileName);
312 if (FileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
314 }
315
316 /* And fail if any other reason is also true */
317 if (!NT_SUCCESS(Status))
318 {
319 DPRINT1("SMSS: SmpParseCommandLine(%wZ) failed - Status == %lx\n",
320 InitialCommand, Status);
321 return Status;
322 }
323
324 /* Execute the initial command, but defer its full execution */
326 &Directory,
327 InitialCommand,
328 MuSessionId,
330 &ProcessInfo);
331
332 /* Free all the token parameters */
333 if (FileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
334 if (Directory.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Directory.Buffer);
335 if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);
336
337 /* Bail out if we couldn't execute the initial command */
338 if (!NT_SUCCESS(Status)) return Status;
339
340 /* Now duplicate the handle to this process */
342 ProcessInfo.ProcessHandle,
344 InitialCommandProcess,
346 0,
347 0);
348 if (!NT_SUCCESS(Status))
349 {
350 /* Kill it utterly if duplication failed */
351 DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status);
353 NtResumeThread(ProcessInfo.ThreadHandle, NULL);
354 NtClose(ProcessInfo.ThreadHandle);
355 NtClose(ProcessInfo.ProcessHandle);
356 return Status;
357 }
358
359 /* Return PID to the caller, and set this as the initial command PID */
360 if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess;
361 if (!MuSessionId) SmpInitialCommandProcessId = ProcessInfo.ClientId.UniqueProcess;
362
363 /* Now call our server execution function to wrap up its initialization */
364 Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE);
365 if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == %lx\n", Status);
366 return Status;
367}
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1327
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:3427
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}
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:407
@ ProcessSessionInformation
Definition: winternl.h:1906

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

◆ SmpInit()

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

Definition at line 2473 of file sminit.c.

2475{
2476 NTSTATUS Status, Status2;
2478 UNICODE_STRING PortName, EventName;
2479 HANDLE EventHandle, PortHandle;
2480 ULONG HardErrorMode;
2481
2482 /* Create the SMSS Heap */
2483 SmBaseTag = RtlCreateTagHeap(RtlGetProcessHeap(),
2484 0,
2485 L"SMSS!",
2486 L"INIT");
2487 SmpHeap = RtlGetProcessHeap();
2488
2489 /* Enable hard errors */
2490 HardErrorMode = TRUE;
2493 &HardErrorMode,
2494 sizeof(HardErrorMode));
2495
2496 /* Initialize the subsystem list and the session list, plus their locks */
2501
2502 /* Initialize the process list */
2504
2505 /* Initialize session parameters */
2506 SmpNextSessionId = 1;
2509
2510 /* Create the initial security descriptors */
2512 if (!NT_SUCCESS(Status))
2513 {
2514 /* Fail */
2516 return Status;
2517 }
2518
2519 /* Initialize subsystem names */
2520 RtlInitUnicodeString(&SmpSubsystemName, L"NT-Session Manager");
2523
2524 /* Create the SM API Port */
2525 RtlInitUnicodeString(&PortName, L"\\SmApiPort");
2527 Status = NtCreatePort(&PortHandle,
2529 sizeof(SB_CONNECTION_INFO),
2530 sizeof(SM_API_MSG),
2531 sizeof(SB_API_MSG) * 32);
2533 SmpDebugPort = PortHandle;
2534
2535 /* Create two SM API threads */
2537 NULL,
2538 FALSE,
2539 0,
2540 0,
2541 0,
2542 SmpApiLoop,
2543 PortHandle,
2544 NULL,
2545 NULL);
2548 NULL,
2549 FALSE,
2550 0,
2551 0,
2552 0,
2553 SmpApiLoop,
2554 PortHandle,
2555 NULL,
2556 NULL);
2558
2559 /* Create the write event that autochk can set after running */
2560 RtlInitUnicodeString(&EventName, L"\\Device\\VolumesSafeForWriteAccess");
2562 &EventName,
2564 NULL,
2565 NULL);
2566 Status2 = NtCreateEvent(&EventHandle,
2569 0,
2570 0);
2571 if (!NT_SUCCESS(Status2))
2572 {
2573 /* Should never really fail */
2574 DPRINT1("SMSS: Unable to create %wZ event - Status == %lx\n",
2575 &EventName, Status2);
2576 ASSERT(NT_SUCCESS(Status2));
2577 }
2578
2579 /* Now initialize everything else based on the registry parameters */
2580 Status = SmpLoadDataFromRegistry(InitialCommand);
2581 if (NT_SUCCESS(Status))
2582 {
2583 /* Autochk should've run now. Set the event and save the CSRSS handle */
2587 }
2588
2589 /* All done */
2590 return Status;
2591}
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 EVENT_ALL_ACCESS
Definition: isotest.c:82
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
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:463
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_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)
Definition: query.c:1422
#define OBJ_PERMANENT
Definition: winternl.h:226
ULONG NTAPI RtlCreateTagHeap(_In_ HANDLE HeapHandle, _In_ ULONG Flags, _In_opt_ PWSTR TagName, _In_ PWSTR TagSubName)
Definition: heap.c:4037
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:2267
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:998
ULONG NTAPI SmpApiLoop(IN PVOID Parameter)
Definition: smloop.c:423
BOOLEAN SmpDbgSsLoaded
Definition: smsessn.c:30
HANDLE SmpWindowsSubSysProcess
Definition: smsubsys.c:20
@ ProcessDefaultHardErrorMode
Definition: winternl.h:1894
_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:564
@ SystemSessionDetach
Definition: extypes.h:265
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1342
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:395
@ 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:330
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:416
#define STATUS_NO_SUCH_PACKAGE
Definition: ntstatus.h:584
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:124
#define SMP_POSIX_FLAG
Definition: smss.h:50
NTSTATUS NTAPI SmpAcquirePrivilege(IN ULONG Privilege, OUT PVOID *PrivilegeStat)
Definition: smutil.c:35
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
union _SB_API_MSG::@3843::@3845::@3847 u
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
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:3479

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;
515 PSMP_REGISTRY_VALUE RegEntry;
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 */
529 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
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 */
539 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
540 if (_wcsicmp(RegEntry->Name.Buffer, L"Kmode") == 0)
541 {
542 /* Translate it */
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 */
600 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
601 if (_wcsicmp(RegEntry->Name.Buffer, L"Debug") == 0)
602 {
603 /* Load the internal debug system */
604 Status = SmpExecuteCommand(&RegEntry->Value,
605 *MuSessionId,
606 ProcessId,
608 }
609 else
610 {
611 /* Load the required subsystem */
612 Status = SmpExecuteCommand(&RegEntry->Value,
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 */
632 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
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 */
667 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
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
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
#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:392
@ SystemSessionCreate
Definition: extypes.h:264
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1956
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:389
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
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:832
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:207
WCHAR InitialCommandBuffer[256]
Definition: smsubsys.c:23
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
UNICODE_STRING Name
Definition: smss.h:58
UNICODE_STRING Value
Definition: smss.h:59

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:192

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 228 of file smutil.c.

233{
235 UNICODE_STRING EnvString, PathString, CmdLineCopy, Token;
236 WCHAR PathBuffer[MAX_PATH];
237 PWCHAR FilePart;
239 UNICODE_STRING FullPathString;
240
241 /* Initialize output arguments to NULL */
243 RtlInitUnicodeString(Arguments, NULL);
245
246 /* Check if we haven't yet built a full default path or system root yet */
248 {
249 /* Initialize it based on shared user data string */
251
252 /* Allocate an empty string for the path */
254 sizeof(L"\\system32;");
255 RtlInitEmptyUnicodeString(&FullPathString,
257 (USHORT)Length);
258 if (FullPathString.Buffer)
259 {
260 /* Append the root, system32;, and then the current library path */
262 RtlAppendUnicodeToString(&FullPathString, L"\\system32;");
265 SmpDefaultLibPath = FullPathString;
266 }
267 }
268
269 /* Consume the command line */
270 CmdLineCopy = *CommandLine;
271 while (TRUE)
272 {
273 /* Parse the first token and check for modifiers/specifiers */
274 Status = SmpParseToken(&CmdLineCopy, FALSE, &Token);
275 if (!(NT_SUCCESS(Status)) || !(Token.Buffer)) return STATUS_UNSUCCESSFUL;
276 if (!Flags) break;
277
278 /* Debug requested? */
280 {
281 /* Convert into a flag */
283 }
285 {
286 /* Asynch requested, convert into a flag */
288 }
290 {
291 /* Autochk requested, convert into a flag */
293 }
294 else
295 {
296 /* No specifier found, keep going */
297 break;
298 }
299
300 /* Get rid of this token and get the next */
301 RtlFreeHeap(SmpHeap, 0, Token.Buffer);
302 }
303
304 /* Initialize a string to hold the current path */
305 RtlInitUnicodeString(&EnvString, L"Path");
307 RtlInitEmptyUnicodeString(&PathString,
309 (USHORT)Length);
310 if (!PathString.Buffer)
311 {
312 /* Fail if we have no memory for this */
313 RtlFreeHeap(SmpHeap, 0, Token.Buffer);
315 }
316
317 /* Query the path from the environment */
319 &EnvString,
320 &PathString);
322 {
323 /* Our buffer was too small, free it */
324 RtlFreeHeap(SmpHeap, 0, PathString.Buffer);
325
326 /* And allocate one big enough */
327 Length = PathString.Length + sizeof(UNICODE_NULL);
328 RtlInitEmptyUnicodeString(&PathString,
330 (USHORT)Length);
331 if (!PathString.Buffer)
332 {
333 /* Fail if we have no memory for this */
334 RtlFreeHeap(SmpHeap, 0, Token.Buffer);
336 }
337
338 /* Now try again, this should work */
340 &EnvString,
341 &PathString);
342 }
343 if (!NT_SUCCESS(Status))
344 {
345 /* Another failure means that the kernel hasn't passed the path correctly */
346 DPRINT1("SMSS: %wZ environment variable not defined.\n", &EnvString);
348 }
349 else
350 {
351 /* Check if the caller expects any flags out of here */
352 if (Flags)
353 {
354 /* We can return the image not found flag -- so does the image exist */
355 if (!(RtlDosSearchPath_U(PathString.Buffer,
356 Token.Buffer,
357 L".exe",
358 sizeof(PathBuffer),
359 PathBuffer,
360 &FilePart)) &&
362 Token.Buffer,
363 L".exe",
364 sizeof(PathBuffer),
365 PathBuffer,
366 &FilePart)))
367 {
368 /* It doesn't, let the caller know about it and exit */
370 *FileName = Token;
371 RtlFreeHeap(SmpHeap, 0, PathString.Buffer);
372 return STATUS_SUCCESS;
373 }
374 }
375 else
376 {
377 /* Caller doesn't want flags, probably wants the image itself */
378 RtlStringCbCopyW(PathBuffer, sizeof(PathBuffer), Token.Buffer);
379 }
380 }
381
382 /* Free tokens and such, all that's left is to convert the image name */
383 RtlFreeHeap(SmpHeap, 0, Token.Buffer);
384 RtlFreeHeap(SmpHeap, 0, PathString.Buffer);
385 if (!NT_SUCCESS(Status)) return Status;
386
387 /* Convert it and bail out if this failed */
389 {
390 DPRINT1("SMSS: Unable to translate %ws into an NT File Name\n",
391 &PathBuffer);
393 }
394 if (!NT_SUCCESS(Status)) return Status;
395
396 /* Finally, check if the caller also wanted the directory */
397 if (Directory)
398 {
399 /* Is the file a relative name with no directory? */
400 if (FilePart <= PathBuffer)
401 {
402 /* Clear it */
404 }
405 else
406 {
407 /* There is a directory, and a filename -- separate those two */
408 *--FilePart = UNICODE_NULL;
410 }
411 }
412
413 /* We are done -- move on to the second pass to get the arguments */
414 return SmpParseToken(&CmdLineCopy, TRUE, Arguments);
415}
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)
Definition: env.c:659
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:387
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:150
UNICODE_STRING SmpAutoChkKeyword
Definition: smutil.c:29
UNICODE_STRING SmpDebugKeyword
Definition: smutil.c:29
UNICODE_STRING SmpASyncKeyword
Definition: smutil.c:29
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().

◆ SmpReleasePrivilege()

VOID NTAPI SmpReleasePrivilege ( IN PVOID  State)

Definition at line 124 of file smutil.c.

125{
127
128 /* Adjust the privileges in the token */
129 NtAdjustPrivilegesToken(State->TokenHandle,
130 FALSE,
131 State->OldPrivileges,
132 0,
133 NULL,
134 NULL);
135
136 /* Check if we used a dynamic buffer */
137 if (State->OldPrivileges != (PTOKEN_PRIVILEGES)&State->OldBuffer)
138 {
139 /* Free it */
140 RtlFreeHeap(SmpHeap, 0, State->OldPrivileges);
141 }
142
143 /* Close the token handle and free the state structure */
144 NtClose(State->TokenHandle);
146}
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 469 of file smutil.c.

471{
473 PVOID BootState;
474
475 /* Lock the BSD */
476 Status = RtlLockBootStatusData(&BootState);
477 if (NT_SUCCESS(Status))
478 {
479 /* Write the bootokay and bootshutdown values */
480 RtlGetSetBootStatusData(BootState,
481 FALSE,
483 &BootOkay,
484 sizeof(BootOkay),
485 NULL);
486 RtlGetSetBootStatusData(BootState,
487 FALSE,
489 &ShutdownOkay,
490 sizeof(ShutdownOkay),
491 NULL);
492
493 /* Unlock the BSD and return */
494 RtlUnlockBootStatusData(BootState);
495 }
496}
@ RtlBsdItemBootShutdown
Definition: rtltypes.h:433
@ RtlBsdItemBootGood
Definition: rtltypes.h:432
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 419 of file smutil.c.

421{
424 PVOID BootStatusDataHandle;
425
426 /* Assume failure */
427 *BootOkay = FALSE;
428 *ShutdownOkay = FALSE;
429
430 /* Lock the BSD and fail if we couldn't */
431 Status = RtlLockBootStatusData(&BootStatusDataHandle);
432 if (!NT_SUCCESS(Status)) return FALSE;
433
434 /* Read the old settings */
435 RtlGetSetBootStatusData(BootStatusDataHandle,
436 TRUE,
438 BootOkay,
439 sizeof(BOOLEAN),
440 NULL);
441 RtlGetSetBootStatusData(BootStatusDataHandle,
442 TRUE,
444 ShutdownOkay,
445 sizeof(BOOLEAN),
446 NULL);
447
448 /* Set new ones indicating we got at least this far */
449 RtlGetSetBootStatusData(BootStatusDataHandle,
450 FALSE,
452 &Value,
453 sizeof(Value),
454 NULL);
455 RtlGetSetBootStatusData(BootStatusDataHandle,
456 FALSE,
458 &Value,
459 sizeof(Value),
460 NULL);
461
462 /* Unlock the BSD and return */
463 RtlUnlockBootStatusData(BootStatusDataHandle);
464 return TRUE;
465}
_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
@ ProcessDebugPort
Definition: cicbase.cpp:64
#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
#define sprintf
Definition: sprintf.c:45
char CHAR
Definition: pedump.c:57
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
uint64_t ULONGLONG
Definition: typedefs.h:67
const char * PCSTR
Definition: typedefs.h:52

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 371 of file smss.c.

374{
376 BOOLEAN Old;
378
379 /* Give the shutdown privilege to the thread */
382 {
383 /* Thread doesn't have a token, give it to the entire process */
385 }
386
387 /* Take down the process/machine with a hard error */
389 ParameterCount,
390 ParameterMask,
393 &Response);
394
395 /* Terminate the process if the hard error didn't already */
397}
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:573
@ 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:454
#define STATUS_SYSTEM_PROCESS_TERMINATED
Definition: ntstatus.h:792
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 832 of file sminit.c.

833{
837 HANDLE KeyHandle, LinkHandle;
839 size_t StrLength;
840 WCHAR LinkBuffer[MAX_PATH];
841 struct { KEY_VALUE_PARTIAL_INFORMATION; CHAR Buffer[512]; } ValueBuffer;
842 struct { OBJECT_DIRECTORY_INFORMATION; WCHAR Buffer[256]; } DirInfoBuffer;
843 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)&ValueBuffer;
844 POBJECT_DIRECTORY_INFORMATION DirInfo = (PVOID)&DirInfoBuffer;
845
846 /* Open the setup key */
847 RtlInitUnicodeString(&UnicodeString, L"\\Registry\\Machine\\System\\Setup");
851 NULL,
852 NULL);
854 if (!NT_SUCCESS(Status))
855 {
856 DPRINT1("SMSS: Cannot open system setup key for reading: 0x%x\n", Status);
857 return;
858 }
859
860 /* Query the system partition */
861 RtlInitUnicodeString(&UnicodeString, L"SystemPartition");
865 &ValueBuffer,
866 sizeof(ValueBuffer),
867 &Length);
869 if (!NT_SUCCESS(Status) ||
870 ((PartialInfo->Type != REG_SZ) && (PartialInfo->Type != REG_EXPAND_SZ)))
871 {
872 DPRINT1("SMSS: Cannot query SystemPartition value (Type %lu, Status 0x%x)\n",
873 (NT_SUCCESS(Status) ? PartialInfo->Type : REG_NONE), Status);
874 return;
875 }
876
877 /* Initialize the system partition string */
878 RtlInitEmptyUnicodeString(&SystemPartition,
879 (PWCHAR)PartialInfo->Data,
880 PartialInfo->DataLength);
882 SystemPartition.MaximumLength,
883 &StrLength);
884 SystemPartition.Length = (USHORT)StrLength;
885
886 /* Enumerate the directory looking for the symbolic link string */
887 RtlInitUnicodeString(&SymLinkU, L"SymbolicLink");
888 RtlInitEmptyUnicodeString(&LinkTarget, LinkBuffer, sizeof(LinkBuffer));
890 &DirInfoBuffer,
891 sizeof(DirInfoBuffer),
892 TRUE,
893 TRUE,
894 &Context,
895 NULL);
896 /* Keep searching until we find it */
897 while (NT_SUCCESS(Status))
898 {
899 /* Is this it? */
900 if (RtlEqualUnicodeString(&DirInfo->TypeName, &SymLinkU, TRUE) &&
901 (DirInfo->Name.Length == 2 * sizeof(WCHAR)) &&
902 (DirInfo->Name.Buffer[1] == L':'))
903 {
904 /* Looks like we found it, open the link to get its target */
906 &DirInfo->Name,
909 NULL);
910 Status = NtOpenSymbolicLinkObject(&LinkHandle,
913 if (NT_SUCCESS(Status))
914 {
915 /* Open worked, query the target now */
917 &LinkTarget,
918 NULL);
919 NtClose(LinkHandle);
920
921 /* Check if it matches the string we had found earlier */
922 if (NT_SUCCESS(Status) &&
925 (LinkTarget.Buffer[SystemPartition.Length / sizeof(WCHAR)] == L'\\'))))
926 {
927 /* All done */
928 break;
929 }
930 }
931 }
932
933 /* Couldn't find it, try again */
935 &DirInfoBuffer,
936 sizeof(DirInfoBuffer),
937 TRUE,
938 FALSE,
939 &Context,
940 NULL);
941 }
942 if (!NT_SUCCESS(Status))
943 {
944 DPRINT1("SMSS: Cannot find drive letter for system partition: 0x%x\n", Status);
945#if (NTDDI_VERSION > NTDDI_WIN7SP1) || defined(__REACTOS__)
946 /* If we failed because no drive letter associated to the system
947 * volume was found (none was assigned to it), fall back to using
948 * the OS boot drive letter instead. Otherwise, fail altogether.
949 * NOTE: This has been introduced in a post-SP1 Windows 7 update. */
951 return;
952 DirInfo->Name.Buffer = DirInfoBuffer.Buffer;
953 DirInfo->Name.Buffer[0] = SharedUserData->NtSystemRoot[0];
954 DirInfo->Name.Buffer[1] = SharedUserData->NtSystemRoot[1]; // == L':';
955#else
956 return;
957#endif
958 }
959
960 /* Open the setup key again, for full access this time */
962 L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup");
966 NULL,
967 NULL);
969 if (!NT_SUCCESS(Status))
970 {
971 DPRINT1("SMSS: Cannot open software setup key for writing: 0x%x\n", Status);
972 return;
973 }
974
975 /* Wrap up the end of the link buffer */
976 LinkBuffer[0] = DirInfo->Name.Buffer[0];
977 LinkBuffer[1] = DirInfo->Name.Buffer[1]; // == L':';
978 LinkBuffer[2] = L'\\';
979 LinkBuffer[3] = UNICODE_NULL;
980
981 /* Now set this as the "BootDir" */
985 0,
986 REG_SZ,
987 LinkBuffer,
988 4 * sizeof(WCHAR));
989 if (!NT_SUCCESS(Status))
990 {
991 DPRINT1("SMSS: couldn't write BootDir value: 0x%x\n", Status);
992 }
994}
PPARTENTRY SystemPartition
Definition: reactos.c:32
Definition: bufpool.h:45
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
struct _OBJECT_DIRECTORY_INFORMATION OBJECT_DIRECTORY_INFORMATION
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1270
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
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
@ KeyValuePartialInformation
Definition: nt_native.h:1185
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define KEY_READ
Definition: nt_native.h:1026
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)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define REG_NONE
Definition: nt_native.h:1495
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:285
_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
HANDLE SmpDosDevicesObjectDirectory
Definition: sminit.c:27
_In_ PVOID Context
Definition: storport.h:2269
UNICODE_STRING TypeName
Definition: obtypes.h:254
void * PVOID
Definition: typedefs.h:50
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PCUNICODE_STRING UnicodeString
Definition: wdfstring.h:64
_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 29 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().