[SMSS2]: Implement executing the initial command as well as doing the SM-to-SM initial connection.

[SMSS2]: Implement the main LPC loop and handle all the supported APIs (all stubs for now). Also handle new connection requests and implement SmpHandleConnectionRequest.
[SMSS2]: Implement subsystem helper functions.
[SMSS2]: Use SmApiPort2 instead of Sm2ApiPort.
[SMSS2]: Rename the SMSRV_APIs not to conflict with the function names, nor with the client functions in smlib.

svn path=/trunk/; revision=55478
This commit is contained in:
Alex Ionescu 2012-02-07 07:13:42 +00:00
parent 35a3e62e9d
commit dfb761830d
9 changed files with 660 additions and 25 deletions

View file

@ -15,7 +15,7 @@ list(APPEND SOURCE
add_executable(smss2 WIN32 ${SOURCE})
target_link_libraries(smss2 nt pseh)
target_link_libraries(smss2 nt pseh smlib)
add_pch(smss2 smss.h)

View file

@ -2439,7 +2439,7 @@ SmpInit(IN PUNICODE_STRING InitialCommand,
RtlInitUnicodeString(&Os2Name, L"OS2");
/* Create the SM API Port */
RtlInitUnicodeString(&PortName, L"\\Sm2ApiPort");
RtlInitUnicodeString(&PortName, L"\\SmApiPort2");
InitializeObjectAttributes(&ObjectAttributes, &PortName, 0, NULL, NULL);
Status = NtCreatePort(&PortHandle,
&ObjectAttributes,

View file

@ -14,26 +14,365 @@
/* GLOBALS ********************************************************************/
typedef struct _SMP_CLIENT_CONTEXT
{
PVOID Subsystem;
HANDLE ProcessHandle;
HANDLE PortHandle;
ULONG dword10;
} SMP_CLIENT_CONTEXT, *PSMP_CLIENT_CONTEXT;
typedef
NTSTATUS
(NTAPI *PSM_API_HANDLER)(
IN PSM_API_MSG SmApiMsg,
IN PSMP_CLIENT_CONTEXT ClientContext,
IN HANDLE SmApiPort
);
volatile LONG SmTotalApiThreads;
HANDLE SmUniqueProcessId;
/* API HANDLERS ***************************************************************/
NTSTATUS
NTAPI
SmpCreateForeignSession(IN PSM_API_MSG SmApiMsg,
IN PSMP_CLIENT_CONTEXT ClientContext,
IN HANDLE SmApiPort)
{
DPRINT1("%s is not yet implemented\n", __FUNCTION__);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
SmpSessionComplete(IN PSM_API_MSG SmApiMsg,
IN PSMP_CLIENT_CONTEXT ClientContext,
IN HANDLE SmApiPort)
{
DPRINT1("%s is not yet implemented\n", __FUNCTION__);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
SmpTerminateForeignSession(IN PSM_API_MSG SmApiMsg,
IN PSMP_CLIENT_CONTEXT ClientContext,
IN HANDLE SmApiPort)
{
DPRINT1("%s is not yet implemented\n", __FUNCTION__);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
SmpExecPgm(IN PSM_API_MSG SmApiMsg,
IN PSMP_CLIENT_CONTEXT ClientContext,
IN HANDLE SmApiPort)
{
DPRINT1("%s is not yet implemented\n", __FUNCTION__);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
SmpLoadDeferedSubsystem(IN PSM_API_MSG SmApiMsg,
IN PSMP_CLIENT_CONTEXT ClientContext,
IN HANDLE SmApiPort)
{
DPRINT1("%s is not yet implemented\n", __FUNCTION__);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
SmpStartCsr(IN PSM_API_MSG SmApiMsg,
IN PSMP_CLIENT_CONTEXT ClientContext,
IN HANDLE SmApiPort)
{
DPRINT1("%s is not yet implemented\n", __FUNCTION__);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
SmpStopCsr(IN PSM_API_MSG SmApiMsg,
IN PSMP_CLIENT_CONTEXT ClientContext,
IN HANDLE SmApiPort)
{
DPRINT1("%s is not yet implemented\n", __FUNCTION__);
return STATUS_SUCCESS;
}
PSM_API_HANDLER SmpApiDispatch[SmMaxApiNumber] =
{
SmpCreateForeignSession,
SmpSessionComplete,
SmpTerminateForeignSession,
SmpExecPgm,
SmpLoadDeferedSubsystem,
SmpStartCsr,
SmpStopCsr
};
/* FUNCTIONS ******************************************************************/
NTSTATUS
NTAPI
SmpHandleConnectionRequest(IN HANDLE SmApiPort,
IN PSB_API_MSG SbApiMsg)
{
BOOLEAN Accept = TRUE;
HANDLE PortHandle, ProcessHandle;
ULONG SessionId;
UNICODE_STRING SubsystemPort;
SMP_CLIENT_CONTEXT *ClientContext;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
REMOTE_PORT_VIEW PortView;
SECURITY_QUALITY_OF_SERVICE SecurityQos;
PSMP_SUBSYSTEM CidSubsystem, TypeSubsystem;
/* Initialize QoS data */
SecurityQos.ImpersonationLevel = SecurityIdentification;
SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
SecurityQos.EffectiveOnly = TRUE;
/* Check if this is SM connecting to itself */
if (SbApiMsg->h.ClientId.UniqueProcess == SmUniqueProcessId)
{
/* No need to get any handle -- assume session 0 */
DPRINT1("SM connecting to SM\n");
ProcessHandle = NULL;
SessionId = 0;
}
else
{
/* Reference the foreign process */
DPRINT1("Incoming request from %lx\n", SbApiMsg->h.ClientId.UniqueProcess);
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
Status = NtOpenProcess(&ProcessHandle,
PROCESS_QUERY_INFORMATION,
&ObjectAttributes,
&SbApiMsg->h.ClientId);
if (!NT_SUCCESS(Status)) Accept = FALSE;
/* Get its session ID */
SmpGetProcessMuSessionId(ProcessHandle, &SessionId);
}
/* See if we already know about the caller's subystem */
CidSubsystem = SmpLocateKnownSubSysByCid(&SbApiMsg->h.ClientId);
if ((CidSubsystem) && (Accept))
{
/* Check if we already have a subsystem for this kind of image */
TypeSubsystem = SmpLocateKnownSubSysByType(SessionId,
SbApiMsg->ConnectionInfo.SubsystemType);
if (TypeSubsystem == CidSubsystem)
{
/* Someone is trying to take control of an existing subsystem, fail */
Accept = FALSE;
DPRINT1("SMSS: Connection from SubSystem rejected\n");
DPRINT1("SMSS: Image type already being served\n");
}
else
{
/* Set this image type as the type for this subsystem */
CidSubsystem->ImageType = SbApiMsg->ConnectionInfo.SubsystemType;
}
/* Drop the reference we had acquired */
if (TypeSubsystem) SmpDereferenceSubsystem(TypeSubsystem);
}
/* Check if we'll be accepting the connection */
if (Accept)
{
/* We will, so create a client context for it */
ClientContext = RtlAllocateHeap(SmpHeap, 0, sizeof(SMP_CLIENT_CONTEXT));
if (ClientContext)
{
ClientContext->ProcessHandle = ProcessHandle;
ClientContext->Subsystem = CidSubsystem;
ClientContext->dword10 = 0;
ClientContext->PortHandle = NULL;
}
else
{
/* Failed to allocate a client context, so reject the connection */
DPRINT1("Rejecting connectiond due to lack of memory\n");
Accept = FALSE;
}
}
else
{
/* Use a bogus context since we're going to reject the message */
ClientContext = (PSMP_CLIENT_CONTEXT)SbApiMsg;
}
/* Now send the actual accept reply (which could be a rejection) */
PortView.Length = sizeof(PortView);
DPRINT1("Accepting: %d connection with context: %p\n", Accept, ClientContext);
Status = NtAcceptConnectPort(&PortHandle,
ClientContext,
&SbApiMsg->h,
Accept,
NULL,
&PortView);
if (!(Accept) || !(NT_SUCCESS(Status)))
{
/* Close the process handle, reference the subsystem, and exit */
DPRINT1("Accept failed or rejected: %lx\n", Status);
if (ClientContext != (PVOID)SbApiMsg) RtlFreeHeap(SmpHeap, 0, ClientContext);
if (ProcessHandle) NtClose(ProcessHandle);
if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem);
return Status;
}
/* Save the port handle now that we've accepted it */
if (ClientContext) ClientContext->PortHandle = PortHandle;
if (CidSubsystem) CidSubsystem->PortHandle = PortHandle;
/* Complete the port connection */
Status = NtCompleteConnectPort(PortHandle);
if ((NT_SUCCESS(Status)) && (CidSubsystem))
{
/* This was an actual subsystem, so connect back to it */
DPRINT1("Connecting back to %wZ\n", &SubsystemPort);
SbApiMsg->ConnectionInfo.SbApiPortName[119] = UNICODE_NULL;
RtlCreateUnicodeString(&SubsystemPort,
SbApiMsg->ConnectionInfo.SbApiPortName);
Status = NtConnectPort(&CidSubsystem->SbApiPort,
&SubsystemPort,
&SecurityQos,
NULL,
NULL,
NULL,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: Connect back to Sb %wZ failed %lx\n", &SubsystemPort, Status);
}
RtlFreeUnicodeString(&SubsystemPort);
/* Now that we're connected, signal the event handle */
NtSetEvent(CidSubsystem->Event, NULL);
}
else if (CidSubsystem)
{
/* We failed to complete the connection, so clear the port handle */
DPRINT1("Completing the connection failed: %lx\n", Status);
CidSubsystem->PortHandle = NULL;
}
/* Dereference the subsystem and return the result */
if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem);
return Status;
}
ULONG
NTAPI
SmpApiLoop(IN PVOID Parameter)
{
HANDLE SmApiPort = (HANDLE)Parameter;
NTSTATUS Status;
PVOID ClientContext;
PSM_API_MSG RequestMsg = NULL;
SM_API_MSG ReplyMsg;
PSMP_CLIENT_CONTEXT ClientContext;
PSM_API_MSG ReplyMsg = NULL;
SM_API_MSG RequestMsg;
PROCESS_BASIC_INFORMATION ProcessInformation;
LARGE_INTEGER Timeout;
DPRINT1("API Loop: %p\n", SmApiPort);
/* Increase the number of API threads for throttling code for later */
_InterlockedExchangeAdd(&SmTotalApiThreads, 1);
/* Mark us critical */
RtlSetThreadIsCritical(TRUE, NULL, TRUE);
/* Set the PID of the SM process itself for later checking */
NtQueryInformationProcess(NtCurrentProcess(),
ProcessBasicInformation,
&ProcessInformation,
sizeof(ProcessInformation),
NULL);
SmUniqueProcessId = (HANDLE)ProcessInformation.UniqueProcessId;
/* Now process incoming messages */
while (TRUE)
{
/* Begin waiting on a request */
DPRINT1("API Loop: %p\n", SmApiPort);
Status = NtReplyWaitReceivePort(SmApiPort,
&ClientContext,
&RequestMsg->h,
&ReplyMsg.h);
DPRINT1("API loop returned: %lx\n", Status);
(PVOID*)&ClientContext,
&ReplyMsg->h,
&RequestMsg.h);
if (Status == STATUS_NO_MEMORY)
{
/* Ran out of memory, so do a little timeout and try again */
if (ReplyMsg) DPRINT1("SMSS: Failed to reply to calling thread, retrying.\n");
Timeout.QuadPart = -50000000;
NtDelayExecution(FALSE, &Timeout);
continue;
}
/* Check what kind of request we received */
switch (RequestMsg.h.u2.s2.Type)
{
/* A new connection */
case LPC_CONNECTION_REQUEST:
/* Create the right structures for it */
DPRINT1("New connection request\n");
SmpHandleConnectionRequest(SmApiPort, (PSB_API_MSG)&RequestMsg);
ReplyMsg = NULL;
break;
/* A closed connection */
case LPC_PORT_CLOSED:
/* Destroy any state we had for this client */
DPRINT1("Port closed\n");
//if (ClientContext) SmpPushDeferredClientContext(ClientContext);
ReplyMsg = NULL;
break;
/* An actual API message */
default:
if (!ClientContext)
{
ReplyMsg = NULL;
break;
}
RequestMsg.ReturnValue = STATUS_PENDING;
/* Check if the API is valid */
if (RequestMsg.ApiNumber >= SmMaxApiNumber)
{
/* It isn't, fail */
DPRINT1("Invalid API: %lx\n", RequestMsg.ApiNumber);
Status = STATUS_NOT_IMPLEMENTED;
}
else if ((RequestMsg.ApiNumber <= SmTerminateForeignSessionApi) &&
!(ClientContext->Subsystem))
{
/* It's valid, but doesn't have a subsystem with it */
DPRINT1("Invalid session API\n");
Status = STATUS_INVALID_PARAMETER;
}
else
{
/* It's totally okay, so call the dispatcher for it */
DPRINT1("Calling dispatcher for ID: %lx\n", RequestMsg.ApiNumber);
Status = SmpApiDispatch[RequestMsg.ApiNumber](&RequestMsg,
ClientContext,
SmApiPort);
}
/* Write the result valud and return the message back */
RequestMsg.ReturnValue = Status;
ReplyMsg = &RequestMsg;
break;
}
}
return STATUS_SUCCESS;
}

View file

@ -23,6 +23,37 @@ HANDLE SmpSessionsObjectDirectory;
/* FUNCTIONS ******************************************************************/
NTSTATUS
NTAPI
SmpGetProcessMuSessionId(IN HANDLE ProcessHandle,
OUT PULONG SessionId)
{
NTSTATUS Status;
ULONG ProcessSession;
/* Query the kernel for the session ID */
Status = NtQueryInformationProcess(ProcessHandle,
ProcessSessionInformation,
&ProcessSession,
sizeof(ProcessSession),
NULL);
if (NT_SUCCESS(Status))
{
/* Copy it back into the buffer */
*SessionId = ProcessSession;
}
else
{
/* Failure -- assume session zero */
DPRINT1("SMSS: GetProcessMuSessionId, Process=%x, Status=%x\n",
ProcessHandle, Status);
*SessionId = 0;
}
/* Return result */
return Status;
}
NTSTATUS
NTAPI
SmpSetProcessMuSessionId(IN HANDLE ProcessHandle,
@ -30,7 +61,7 @@ SmpSetProcessMuSessionId(IN HANDLE ProcessHandle,
{
NTSTATUS Status;
/* Tell the kernel about our session ID */
/* Tell the kernel about the session ID */
Status = NtSetInformationProcess(ProcessHandle,
ProcessSessionInformation,
&SessionId,

View file

@ -29,6 +29,8 @@ ULONG NtInitialUserProcessBufferType = REG_SZ;
UNICODE_STRING SmpSystemRoot;
ULONG AttachedSessionId = -1;
BOOLEAN SmpDebug, SmpEnableDots;
HANDLE SmApiPort;
HANDLE SmpInitialCommandProcessId;
/* FUNCTIONS ******************************************************************/
@ -57,6 +59,7 @@ SmpExecuteImage(IN PUNICODE_STRING FileName,
NTSTATUS Status;
RTL_USER_PROCESS_INFORMATION LocalProcessInfo;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
DPRINT1("Executing image: %wZ\n", FileName);
/* Use the input process information if we have it, otherwise use local */
ProcessInfo = ProcessInformation;
@ -295,6 +298,103 @@ SmpExecuteCommand(IN PUNICODE_STRING CommandLine,
return Status;
}
NTSTATUS
NTAPI
SmpExecuteInitialCommand(IN ULONG MuSessionId,
IN PUNICODE_STRING InitialCommand,
IN HANDLE InitialCommandProcess,
OUT PHANDLE ReturnPid)
{
NTSTATUS Status;
RTL_USER_PROCESS_INFORMATION ProcessInfo;
UNICODE_STRING Arguments, ImageFileDirectory, ImageFileName;
ULONG Flags = 0;
/* Check if we haven't yet connected to ourselves */
if (!SmApiPort)
{
/* Connect to ourselves, as a client */
Status = SmConnectToSm(0, 0, 0, &SmApiPort);
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status);
return Status;
}
}
/* Parse the initial command line */
Status = SmpParseCommandLine(InitialCommand,
(PULONG)&Flags,
&ImageFileName,
&ImageFileDirectory,
&Arguments);
if (Flags & SMP_INVALID_PATH)
{
/* Fail if it doesn't exist */
DPRINT1("SMSS: Initial command image (%wZ) not found\n", &ImageFileName);
if (ImageFileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
/* And fail if any other reason is also true */
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: SmpParseCommand( %wZ ) failed - Status == %lx\n",
InitialCommand, Status);
return Status;
}
/* Execute the initial command -- but defer its full execution */
Status = SmpExecuteImage(&ImageFileName,
&ImageFileDirectory,
InitialCommand,
MuSessionId,
SMP_DEFERRED_FLAG,
&ProcessInfo);
/* Free any buffers we had lying around */
if (ImageFileName.Buffer)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer);
}
if (ImageFileDirectory.Buffer)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileDirectory.Buffer);
}
if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);
/* Bail out if we couldn't execute the initial command */
if (!NT_SUCCESS(Status)) return Status;
/* Now duplicate the handle to this process */
Status = NtDuplicateObject(NtCurrentProcess(),
ProcessInfo.ProcessHandle,
NtCurrentProcess(),
InitialCommandProcess,
PROCESS_ALL_ACCESS,
0,
0);
if (!NT_SUCCESS(Status))
{
/* Kill it utterly if duplication failed */
DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status);
NtTerminateProcess(ProcessInfo.ProcessHandle, Status);
NtResumeThread(ProcessInfo.ThreadHandle, NULL);
NtClose(ProcessInfo.ThreadHandle);
NtClose(ProcessInfo.ProcessHandle);
return Status;
}
/* Return PID to the caller, and set this as the initial command PID */
if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess;
if (!MuSessionId) SmpInitialCommandProcessId = ProcessInfo.ClientId.UniqueProcess;
/* Now call our server execution function to wrap up its initialization */
Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE);
if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == %lx\n", Status);
return Status;
}
NTSTATUS
NTAPI
ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
@ -630,6 +730,9 @@ _main(IN INT argc,
DPRINT1("SMSS: SmpInit return failure - Status == %x\n", Status);
RtlInitUnicodeString(&DbgString, L"Session Manager Initialization");
Parameters[1] = Status;
DPRINT1("SMSS-2 Loaded... Launching original SMSS\n");
Status = LaunchOldSmss(Handles);
goto SetupHack;
//_SEH2_LEAVE; Hack so that setup can work. will go away later
}
@ -647,14 +750,21 @@ _main(IN INT argc,
DPRINT1("Global Flags Set to SMSS Debugging: Not yet supported\n");
}
#if 0
/* Execute the initial command (Winlogon.exe) */
Status = SmpExecuteInitialCommand(0, &InitialCommand, &Handles[1], NULL);
#else
/* Launch the original SMSS */
DPRINT1("SMSS-2 Loaded... Launching original SMSS\n");
Status = LaunchOldSmss(Handles);
#endif
if (!NT_SUCCESS(Status))
{
/* Fail and raise a hard error */
DPRINT1("SMSS: Execute Old SMSS failed\n");
RtlInitUnicodeString(&DbgString,
L"Session Manager LaunchOldSmss");
Parameters[1] = Status;
_SEH2_LEAVE;
}
/* Execute the initial command (Winlogon.exe) */
Status = SmpExecuteInitialCommand(0, &InitialCommand, &Handles[1], NULL);
if (!NT_SUCCESS(Status))
{
/* Fail and raise a hard error */
@ -679,6 +789,7 @@ _main(IN INT argc,
SmpReleasePrivilege(State);
/* Wait on either CSRSS or Winlogon to die */
SetupHack:
Status = NtWaitForMultipleObjects(RTL_NUMBER_OF(Handles),
Handles,
WaitAny,

View file

@ -49,6 +49,20 @@ typedef struct _SMP_REGISTRY_VALUE
PCHAR AnsiValue;
} SMP_REGISTRY_VALUE, *PSMP_REGISTRY_VALUE;
typedef struct _SMP_SUBSYSTEM
{
LIST_ENTRY Entry;
HANDLE Event;
HANDLE ProcessHandle;
ULONG ImageType;
HANDLE PortHandle;
HANDLE SbApiPort;
CLIENT_ID ClientId;
ULONG MuSessionId;
BOOLEAN Terminating;
ULONG ReferenceCount;
} SMP_SUBSYSTEM, *PSMP_SUBSYSTEM;
/* EXTERNALS ******************************************************************/
extern RTL_CRITICAL_SECTION SmpKnownSubSysLock;
@ -209,4 +223,31 @@ NTAPI
SmpTranslateSystemPartitionInformation(
VOID
);
PSMP_SUBSYSTEM
NTAPI
SmpLocateKnownSubSysByCid(
IN PCLIENT_ID ClientId
);
PSMP_SUBSYSTEM
NTAPI
SmpLocateKnownSubSysByType(
IN ULONG MuSessionId,
IN ULONG ImageType
);
NTSTATUS
NTAPI
SmpGetProcessMuSessionId(
IN HANDLE ProcessHandle,
OUT PULONG SessionId
);
VOID
NTAPI
SmpDereferenceSubsystem(
IN PSMP_SUBSYSTEM SubSystem
);
#endif

View file

@ -7,6 +7,7 @@
<library>nt</library>
<library>pseh</library>
<library>ntdll</library>
<library>smlib</library>
<pch>smss.h</pch>
<compilationunit name="unit.c">
<file>smss.c</file>

View file

@ -23,6 +23,97 @@ WCHAR InitialCommandBuffer[256];
/* FUNCTIONS ******************************************************************/
VOID
NTAPI
SmpDereferenceSubsystem(IN PSMP_SUBSYSTEM SubSystem)
{
/* Acquire the database lock while we (potentially) destroy this subsystem */
RtlEnterCriticalSection(&SmpKnownSubSysLock);
/* Drop the reference and see if it's terminating */
if (!(--SubSystem->ReferenceCount) && (SubSystem->Terminating))
{
/* Close all handles and free it */
if (SubSystem->Event) NtClose(SubSystem->Event);
if (SubSystem->ProcessHandle) NtClose(SubSystem->ProcessHandle);
if (SubSystem->SbApiPort) NtClose(SubSystem->SbApiPort);
RtlFreeHeap(SmpHeap, 0, SubSystem);
}
/* Release the database lock */
RtlLeaveCriticalSection(&SmpKnownSubSysLock);
}
PSMP_SUBSYSTEM
NTAPI
SmpLocateKnownSubSysByCid(IN PCLIENT_ID ClientId)
{
PSMP_SUBSYSTEM Subsystem = NULL;
PLIST_ENTRY NextEntry;
/* Lock the subsystem database */
RtlEnterCriticalSection(&SmpKnownSubSysLock);
/* Loop each subsystem in the database */
NextEntry = SmpKnownSubSysHead.Flink;
while (NextEntry != &SmpKnownSubSysHead)
{
/* Check if this one matches the client ID and is still valid */
Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
if ((*(PULONGLONG)&Subsystem->ClientId == *(PULONGLONG)&ClientId) &&
!(Subsystem->Terminating))
{
/* Add a reference and return it */
Subsystem->ReferenceCount++;
break;
}
/* Reset the current pointer and keep earching */
Subsystem = NULL;
NextEntry = NextEntry->Flink;
}
/* Release the lock and return the subsystem we found */
RtlLeaveCriticalSection(&SmpKnownSubSysLock);
return Subsystem;
}
PSMP_SUBSYSTEM
NTAPI
SmpLocateKnownSubSysByType(IN ULONG MuSessionId,
IN ULONG ImageType)
{
PSMP_SUBSYSTEM Subsystem = NULL;
PLIST_ENTRY NextEntry;
/* Lock the subsystem database */
RtlEnterCriticalSection(&SmpKnownSubSysLock);
/* Loop each subsystem in the database */
NextEntry = SmpKnownSubSysHead.Flink;
while (NextEntry != &SmpKnownSubSysHead)
{
/* Check if this one matches the image and uID, and is still valid */
Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
if ((Subsystem->ImageType == ImageType) &&
!(Subsystem->Terminating) &&
(Subsystem->MuSessionId == MuSessionId))
{
/* Return it referenced for the caller */
Subsystem->ReferenceCount++;
break;
}
/* Reset the current pointer and keep earching */
Subsystem = NULL;
NextEntry = NextEntry->Flink;
}
/* Release the lock and return the subsystem we found */
RtlLeaveCriticalSection(&SmpKnownSubSysLock);
return Subsystem;
}
NTSTATUS
NTAPI
SmpLoadSubSystem(IN PUNICODE_STRING FileName,

View file

@ -21,14 +21,14 @@
//
typedef enum _SMSRV_API_NUMBER
{
SmpCreateForeignSession,
SmpSessionComplete,
SmpTerminateForeignSession,
SmpExecPgm,
SmpLoadDeferedSubsystem,
SmpStartCsr,
SmpStopCsr,
SmpMaxApiNumber // Based on BasepMaxApiNumber, UserpMaxApiNumber...
SmCreateForeignSessionApi,
SmSessionCompleteApi,
SmTerminateForeignSessionApi,
SmExecPgmApi,
SmLoadDeferedSubsystemApi,
SmStartCsrApi,
SmStopCsrApi,
SmMaxApiNumber // Based on BasepMaxApiNumber, UserpMaxApiNumber...
} SMSRV_API_NUMBER;
//
@ -184,7 +184,7 @@ typedef struct _SB_CONNECTION_INFO
//
typedef struct _SB_API_MSG
{
PORT_MESSAGE Header;
PORT_MESSAGE h;
union
{
SB_CONNECTION_INFO ConnectionInfo;
@ -208,4 +208,25 @@ typedef struct _SB_API_MSG
//
C_ASSERT(sizeof(SB_CONNECTION_INFO) == 0xF4);
C_ASSERT(sizeof(SB_API_MSG) == 0x110);
//
// The actual server functions that a client linking with smlib can call
//
NTSTATUS
NTAPI
SmConnectToSm(
IN PUNICODE_STRING SbApiPortName,
IN HANDLE SbApiPort,
IN ULONG ImageType,
IN HANDLE SmApiPort
);
NTSTATUS
NTAPI
SmExecPgm(
IN HANDLE SmApiPort,
IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
IN BOOLEAN DebugFlag
);
#endif