mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +00:00
[SMSS] Fix three SmpLoadSubSystem bugs related to the SB_CREATE_SESSION callback.
This fixes starting the Windows 2000 POSIX subsystem in ReactOS. - The CreateSession pointer was initialized against the SbApiMsg variable, but it was the other SbApiMsg2 that was being initialized and sent through LPC. - Do not overwrite the MuSessionId (Terminal Services session ID) variable with the generated environment subsystem session ID from SmpAllocateSessionId(). - Actually initialize the SbApiMsg ApiNumber for the CreateSession LPC call. (dll\win32\kernel32\client\proc.c:3690) Retrying with: POSIX /P C:\ReactOS\system32\posix\ls.exe /C ls Breakpoint 1 hit csrsrv!CsrSbApiRequestThread+0x64: 001b:1000ac34 837dfc00 cmp dword ptr [ebp-4],0 kd> ??ReceiveMsg struct _SB_API_MSG +0x000 h : _PORT_MESSAGE +0x018 ConnectionInfo : _SB_CONNECTION_INFO +0x018 ApiNumber : 0xcccccccc (No matching name) +0x01c ReturnValue : 0n0 +0x020 u : <unnamed-tag> kd> p ... (base\system\smss\smsubsys.c:393) SMSS: SmpLoadSubSystem - NtRequestWaitReplyPort Failed with Status c0000002 for sessionid 2 ... <Retrying> ... (base\system\smss\smsubsys.c:393) SMSS: SmpLoadSubSystem - NtRequestWaitReplyPort Failed with Status c0000002 for sessionid 3 All those bugs could have been avoided *IF*, rather than (badly) duplicating its code, the existing SmpSbCreateSession() function had been used instead. - "Not sure these field mean what I think they do -- but clear them" ... ◔_◔ Those fields are related to the debug client interface (DbgUi) and session in case the subsystem being started is going to be debugged. These have nothing to do with the MuSessionId. Clarify this in the SB_CREATE_SESSION_MSG structure and in the SmpSbCreateSession() function.
This commit is contained in:
parent
f43ce46566
commit
2dddbd5c54
4 changed files with 46 additions and 39 deletions
|
@ -36,28 +36,28 @@ NTAPI
|
||||||
SmpSbCreateSession(IN PVOID Reserved,
|
SmpSbCreateSession(IN PVOID Reserved,
|
||||||
IN PSMP_SUBSYSTEM OtherSubsystem,
|
IN PSMP_SUBSYSTEM OtherSubsystem,
|
||||||
IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
|
IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
|
||||||
IN ULONG MuSessionId,
|
IN ULONG DbgSessionId,
|
||||||
IN PCLIENT_ID DbgClientId)
|
IN PCLIENT_ID DbgUiClientId)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG SubSystemType = ProcessInformation->ImageInformation.SubSystemType;
|
ULONG SubSystemType = ProcessInformation->ImageInformation.SubSystemType;
|
||||||
PSMP_SUBSYSTEM KnownSubsys;
|
ULONG MuSessionId;
|
||||||
SB_API_MSG SbApiMsg;
|
|
||||||
ULONG SessionId;
|
ULONG SessionId;
|
||||||
PSB_CREATE_SESSION_MSG CreateSessionMsg;
|
PSMP_SUBSYSTEM KnownSubsys;
|
||||||
|
SB_API_MSG SbApiMsg = {0};
|
||||||
|
PSB_CREATE_SESSION_MSG CreateSessionMsg = &SbApiMsg.u.CreateSession;
|
||||||
|
|
||||||
/* Write out the create session message including its initial process */
|
/* Write out the create session message including its initial process */
|
||||||
CreateSessionMsg = &SbApiMsg.u.CreateSession;
|
|
||||||
CreateSessionMsg->ProcessInfo = *ProcessInformation;
|
CreateSessionMsg->ProcessInfo = *ProcessInformation;
|
||||||
CreateSessionMsg->MuSessionId = MuSessionId;
|
CreateSessionMsg->DbgSessionId = DbgSessionId;
|
||||||
if (DbgClientId)
|
if (DbgUiClientId)
|
||||||
{
|
{
|
||||||
CreateSessionMsg->ClientId = *DbgClientId;
|
CreateSessionMsg->DbgUiClientId = *DbgUiClientId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CreateSessionMsg->ClientId.UniqueThread = NULL;
|
CreateSessionMsg->DbgUiClientId.UniqueThread = NULL;
|
||||||
CreateSessionMsg->ClientId.UniqueProcess = NULL;
|
CreateSessionMsg->DbgUiClientId.UniqueProcess = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find a subsystem responsible for this session */
|
/* Find a subsystem responsible for this session */
|
||||||
|
@ -70,7 +70,7 @@ SmpSbCreateSession(IN PVOID Reserved,
|
||||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the subsystem we have for this initial process */
|
/* Find the subsystem suitable for this initial process */
|
||||||
KnownSubsys = SmpLocateKnownSubSysByType(MuSessionId, SubSystemType);
|
KnownSubsys = SmpLocateKnownSubSysByType(MuSessionId, SubSystemType);
|
||||||
if (KnownSubsys)
|
if (KnownSubsys)
|
||||||
{
|
{
|
||||||
|
@ -169,8 +169,13 @@ SmpSbCreateSession(IN PVOID Reserved,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* This code handles debug applications, but it seems vestigial... */
|
/*
|
||||||
if ((*(ULONGLONG)&CreateSessionMsg.ClientId) && (SmpDbgSsLoaded))
|
* This code is part of the LPC-based legacy debugging support for native
|
||||||
|
* applications, implemented with the debug client interface (DbgUi) and
|
||||||
|
* debug subsystem (DbgSs). It is now vestigial since WinXP+ and is here
|
||||||
|
* for informational purposes only.
|
||||||
|
*/
|
||||||
|
if ((*(ULONGLONG)&CreateSessionMsg.DbgUiClientId) && SmpDbgSsLoaded)
|
||||||
{
|
{
|
||||||
Process = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_PROCESS));
|
Process = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_PROCESS));
|
||||||
if (!Process)
|
if (!Process)
|
||||||
|
@ -183,12 +188,17 @@ SmpSbCreateSession(IN PVOID Reserved,
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process->DbgClientId = CreateSessionMsg->ClientId;
|
Process->DbgUiClientId = CreateSessionMsg->DbgUiClientId;
|
||||||
Process->ClientId = ProcessInformation->ClientId;
|
Process->ClientId = ProcessInformation->ClientId;
|
||||||
InsertHeadList(&NativeProcessList, &Process->Entry);
|
InsertHeadList(&NativeProcessList, &Process->Entry);
|
||||||
DPRINT1("Native Debug App %lx.%lx\n", Process->ClientId.UniqueProcess, Process->ClientId.UniqueThread);
|
DPRINT1("Native Debug App %lx.%lx\n",
|
||||||
|
Process->ClientId.UniqueProcess,
|
||||||
|
Process->ClientId.UniqueThread);
|
||||||
|
|
||||||
Status = NtSetInformationProcess(ProcessInformation->ProcessHandle, 7, &SmpDebugPort, 4);
|
Status = NtSetInformationProcess(ProcessInformation->ProcessHandle,
|
||||||
|
ProcessDebugPort,
|
||||||
|
&SmpDebugPort,
|
||||||
|
sizeof(SmpDebugPort));
|
||||||
ASSERT(NT_SUCCESS(Status));
|
ASSERT(NT_SUCCESS(Status));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -168,8 +168,8 @@ SmpSbCreateSession(
|
||||||
IN PVOID Reserved,
|
IN PVOID Reserved,
|
||||||
IN PSMP_SUBSYSTEM OtherSubsystem,
|
IN PSMP_SUBSYSTEM OtherSubsystem,
|
||||||
IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
|
IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
|
||||||
IN ULONG MuSessionId,
|
IN ULONG DbgSessionId,
|
||||||
IN PCLIENT_ID DbgClientId
|
IN PCLIENT_ID DbgUiClientId
|
||||||
);
|
);
|
||||||
|
|
||||||
/* smsessn.c */
|
/* smsessn.c */
|
||||||
|
|
|
@ -145,7 +145,7 @@ SmpLoadSubSystem(IN PUNICODE_STRING FileName,
|
||||||
PSMP_SUBSYSTEM Subsystem, NewSubsystem, KnownSubsystem = NULL;
|
PSMP_SUBSYSTEM Subsystem, NewSubsystem, KnownSubsystem = NULL;
|
||||||
HANDLE SubSysProcessId;
|
HANDLE SubSysProcessId;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
SB_API_MSG SbApiMsg, SbApiMsg2;
|
SB_API_MSG SbApiMsg;
|
||||||
RTL_USER_PROCESS_INFORMATION ProcessInformation;
|
RTL_USER_PROCESS_INFORMATION ProcessInformation;
|
||||||
LARGE_INTEGER Timeout;
|
LARGE_INTEGER Timeout;
|
||||||
PVOID State;
|
PVOID State;
|
||||||
|
@ -316,13 +316,10 @@ SmpLoadSubSystem(IN PUNICODE_STRING FileName,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* This is the POSIX or OS/2 subsystem process, copy its information */
|
/* This is the POSIX or OS/2 subsystem process, copy its information */
|
||||||
RtlCopyMemory(&CreateSession->ProcessInfo,
|
CreateSession->ProcessInfo = ProcessInformation;
|
||||||
&ProcessInformation,
|
|
||||||
sizeof(CreateSession->ProcessInfo));
|
|
||||||
|
|
||||||
/* Not sure these field mean what I think they do -- but clear them */
|
CreateSession->DbgSessionId = 0;
|
||||||
*(PULONGLONG)&CreateSession->ClientId = 0;
|
*(PULONGLONG)&CreateSession->DbgUiClientId = 0;
|
||||||
CreateSession->MuSessionId = 0;
|
|
||||||
|
|
||||||
/* This should find CSRSS because they are POSIX or OS/2 subsystems */
|
/* This should find CSRSS because they are POSIX or OS/2 subsystems */
|
||||||
Subsystem = SmpLocateKnownSubSysByType(MuSessionId,
|
Subsystem = SmpLocateKnownSubSysByType(MuSessionId,
|
||||||
|
@ -372,25 +369,25 @@ SmpLoadSubSystem(IN PUNICODE_STRING FileName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate an internal Session ID for this subsystem */
|
/* Allocate an internal Session ID for this subsystem */
|
||||||
MuSessionId = SmpAllocateSessionId(Subsystem, 0);
|
CreateSession->SessionId = SmpAllocateSessionId(Subsystem, NULL);
|
||||||
CreateSession->SessionId = MuSessionId;
|
|
||||||
|
|
||||||
/* Send the create session message to the subsystem */
|
/* Send the create session message to the subsystem */
|
||||||
SbApiMsg2.ReturnValue = STATUS_SUCCESS;
|
SbApiMsg.ReturnValue = STATUS_SUCCESS;
|
||||||
SbApiMsg2.h.u2.ZeroInit = 0;
|
SbApiMsg.h.u2.ZeroInit = 0;
|
||||||
SbApiMsg2.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
|
SbApiMsg.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
|
||||||
SbApiMsg2.h.u1.s1.TotalLength = sizeof(SB_API_MSG);
|
SbApiMsg.h.u1.s1.TotalLength = sizeof(SB_API_MSG);
|
||||||
|
SbApiMsg.ApiNumber = SbpCreateSession;
|
||||||
Status = NtRequestWaitReplyPort(Subsystem->SbApiPort,
|
Status = NtRequestWaitReplyPort(Subsystem->SbApiPort,
|
||||||
&SbApiMsg2.h,
|
&SbApiMsg.h,
|
||||||
&SbApiMsg2.h);
|
&SbApiMsg.h);
|
||||||
if (NT_SUCCESS(Status)) Status = SbApiMsg2.ReturnValue;
|
if (NT_SUCCESS(Status)) Status = SbApiMsg.ReturnValue;
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Delete the session and handle failure if the LPC call failed */
|
/* Delete the session and handle failure if the LPC call failed */
|
||||||
SmpDeleteSession(CreateSession->SessionId);
|
SmpDeleteSession(CreateSession->SessionId);
|
||||||
DPRINT1("SMSS: SmpLoadSubSystem - NtRequestWaitReplyPort Failed with Status %lx for sessionid %lu\n",
|
DPRINT1("SMSS: SmpLoadSubSystem - NtRequestWaitReplyPort Failed with Status %lx for sessionid %lu\n",
|
||||||
Status,
|
Status,
|
||||||
CreateSession->SessionId);
|
MuSessionId);
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,9 +159,9 @@ typedef struct _SB_CREATE_SESSION_MSG
|
||||||
{
|
{
|
||||||
ULONG SessionId;
|
ULONG SessionId;
|
||||||
RTL_USER_PROCESS_INFORMATION ProcessInfo;
|
RTL_USER_PROCESS_INFORMATION ProcessInfo;
|
||||||
PVOID Unknown;
|
PVOID Reserved;
|
||||||
ULONG MuSessionId;
|
ULONG DbgSessionId;
|
||||||
CLIENT_ID ClientId;
|
CLIENT_ID DbgUiClientId;
|
||||||
} SB_CREATE_SESSION_MSG, *PSB_CREATE_SESSION_MSG;
|
} SB_CREATE_SESSION_MSG, *PSB_CREATE_SESSION_MSG;
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
C_ASSERT(sizeof(SB_CREATE_SESSION_MSG) == 0x58);
|
C_ASSERT(sizeof(SB_CREATE_SESSION_MSG) == 0x58);
|
||||||
|
|
Loading…
Reference in a new issue