[CSRSRV]: Remove the CSRAPI Heap and just use the CSR Heap. In the future there will be separate DLLs each with their own heap, but now it's all one DLL.

[CSRSRV]: Port CsrSbApiRequestThread, CsrSbApiHandleConnectionRequest and all the Sb* APIs from CSRSRV2. Comment out parts that can't work yet.
[CSRSRV]; Port CsrSbApiPortInitialize, CsrSetProcessSecurity, CsrCreateLocalSystemSD, and almost all of CsrServerInitialization. Initialization is almost identical to CSRSRV2 now.
[CSRSRV]: Kill "Complete" routine support, nobody was using this.

svn path=/trunk/; revision=55615
This commit is contained in:
Alex Ionescu 2012-02-15 19:53:31 +00:00
parent beedafd586
commit f43c33aa00
5 changed files with 753 additions and 245 deletions

View file

@ -83,7 +83,7 @@ PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId)
} }
if (pProcessData == NULL) if (pProcessData == NULL)
{ {
pProcessData = RtlAllocateHeap(CsrssApiHeap, pProcessData = RtlAllocateHeap(CsrHeap,
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
sizeof(CSRSS_PROCESS_DATA)); sizeof(CSRSS_PROCESS_DATA));
if (pProcessData) if (pProcessData)
@ -109,7 +109,7 @@ PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId)
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ProcessData[hash] = pProcessData->next; ProcessData[hash] = pProcessData->next;
RtlFreeHeap(CsrssApiHeap, 0, pProcessData); RtlFreeHeap(CsrHeap, 0, pProcessData);
pProcessData = NULL; pProcessData = NULL;
} }
else else
@ -187,7 +187,7 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid)
*pPrevLink = pProcessData->next; *pPrevLink = pProcessData->next;
RtlFreeHeap(CsrssApiHeap, 0, pProcessData); RtlFreeHeap(CsrHeap, 0, pProcessData);
UNLOCK; UNLOCK;
if (Process) if (Process)
{ {

View file

@ -19,11 +19,18 @@
extern HANDLE hApiPort; extern HANDLE hApiPort;
HANDLE CsrssApiHeap = (HANDLE) 0;
static unsigned ApiDefinitionsCount = 0; static unsigned ApiDefinitionsCount = 0;
static PCSRSS_API_DEFINITION ApiDefinitions = NULL; static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
PCHAR CsrServerSbApiName[5] =
{
"SbCreateSession",
"SbTerminateSession",
"SbForeignSessionComplete",
"SbCreateProcess",
"Unknown Csr Sb Api Number"
};
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS FASTCALL NTSTATUS FASTCALL
@ -41,7 +48,7 @@ CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
NewCount++; NewCount++;
} }
New = RtlAllocateHeap(CsrssApiHeap, 0, New = RtlAllocateHeap(CsrHeap, 0,
(ApiDefinitionsCount + NewCount) (ApiDefinitionsCount + NewCount)
* sizeof(CSRSS_API_DEFINITION)); * sizeof(CSRSS_API_DEFINITION));
if (NULL == New) if (NULL == New)
@ -53,7 +60,7 @@ CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
{ {
RtlCopyMemory(New, ApiDefinitions, RtlCopyMemory(New, ApiDefinitions,
ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION)); ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION));
RtlFreeHeap(CsrssApiHeap, 0, ApiDefinitions); RtlFreeHeap(CsrHeap, 0, ApiDefinitions);
} }
RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions, RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions,
NewCount * sizeof(CSRSS_API_DEFINITION)); NewCount * sizeof(CSRSS_API_DEFINITION));
@ -180,7 +187,6 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
/* Multiply by 1024 entries and round to page size */ /* Multiply by 1024 entries and round to page size */
CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize); CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize);
DPRINT1("Size: %lx\n", CsrSrvSharedSectionSize);
/* Create the Secion */ /* Create the Secion */
SectionSize.LowPart = CsrSrvSharedSectionSize; SectionSize.LowPart = CsrSrvSharedSectionSize;
@ -980,115 +986,391 @@ ClientConnectionThread(HANDLE ServerPort)
RtlExitUserThread(STATUS_SUCCESS); RtlExitUserThread(STATUS_SUCCESS);
} }
/********************************************************************** /* SESSION MANAGER FUNCTIONS**************************************************/
* NAME
* ServerSbApiPortThread/1 /*++
* @name CsrSbCreateSession
* *
* DESCRIPTION * The CsrSbCreateSession API is called by the Session Manager whenever a new
* Handle connection requests from SM to the port * session is created.
* "\Windows\SbApiPort". We will accept only one *
* connection request (from the SM). * @param ApiMessage
*/ * Pointer to the Session Manager API Message.
DWORD WINAPI *
ServerSbApiPortThread (HANDLE hSbApiPortListen) * @return TRUE in case of success, FALSE othwerwise.
*
* @remarks The CsrSbCreateSession routine will initialize a new CSR NT
* Session and allocate a new CSR Process for the subsystem process.
*
*--*/
BOOLEAN
NTAPI
CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
{ {
HANDLE hConnectedPort = (HANDLE) 0; PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
SB_API_MSG Request; HANDLE hProcess, hThread;
PVOID Context = NULL; // PCSR_PROCESS CsrProcess;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status;
PPORT_MESSAGE Reply = NULL; KERNEL_USER_TIMES KernelTimes;
//PCSR_THREAD CsrThread;
//PVOID ProcessData;
//ULONG i;
DPRINT("CSR: %s called\n", __FUNCTION__); /* Save the Process and Thread Handles */
hProcess = CreateSession->ProcessInfo.ProcessHandle;
hThread = CreateSession->ProcessInfo.ThreadHandle;
RtlZeroMemory(&Request, sizeof(PORT_MESSAGE)); #if 0
Status = NtListenPort (hSbApiPortListen, & Request.h); /* Lock the Processes */
CsrAcquireProcessLock();
/* Allocate a new process */
CsrProcess = CsrAllocateProcess();
if (!CsrProcess)
{
/* Fail */
ApiMessage->ReturnValue = STATUS_NO_MEMORY;
CsrReleaseProcessLock();
return TRUE;
}
#endif
/* Set the exception port */
Status = NtSetInformationProcess(hProcess,
ProcessExceptionPort,
&hApiPort,//&CsrApiPort,
sizeof(HANDLE));
/* Check for success */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n", /* Fail the request */
__FUNCTION__, Status); #if 0
} else { CsrDeallocateProcess(CsrProcess);
DPRINT("-- 1\n"); CsrReleaseProcessLock();
Status = NtAcceptConnectPort(&hConnectedPort, #endif
NULL, /* Strange as it seems, NTSTATUSes are actually returned */
&Request.h, return (BOOLEAN)STATUS_NO_MEMORY;
TRUE, }
NULL,
NULL); /* Get the Create Time */
if(!NT_SUCCESS(Status)) Status = NtQueryInformationThread(hThread,
ThreadTimes,
&KernelTimes,
sizeof(KERNEL_USER_TIMES),
NULL);
/* Check for success */
if (!NT_SUCCESS(Status))
{
/* Fail the request */
#if 0
CsrDeallocateProcess(CsrProcess);
CsrReleaseProcessLock();
#endif
/* Strange as it seems, NTSTATUSes are actually returned */
return (BOOLEAN)Status;
}
/* Allocate a new Thread */
#if 0
CsrThread = CsrAllocateThread(CsrProcess);
if (!CsrThread)
{
/* Fail the request */
CsrDeallocateProcess(CsrProcess);
CsrReleaseProcessLock();
ApiMessage->ReturnValue = STATUS_NO_MEMORY;
return TRUE;
}
/* Setup the Thread Object */
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
CsrThread->ThreadHandle = hThread;
ProtectHandle(hThread);
CsrThread->Flags = 0;
/* Insert it into the Process List */
CsrInsertThread(CsrProcess, CsrThread);
/* Setup Process Data */
CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
CsrProcess->ProcessHandle = hProcess;
CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);
/* Set the Process Priority */
CsrSetBackgroundPriority(CsrProcess);
/* Get the first data location */
ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
/* Loop every DLL */
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Check if the DLL is loaded and has Process Data */
if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
{ {
DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n", /* Write the pointer to the data */
__FUNCTION__, Status); CsrProcess->ServerData[i] = ProcessData;
} else {
DPRINT("-- 2\n");
Status = NtCompleteConnectPort (hConnectedPort);
if(!NT_SUCCESS(Status))
{
DPRINT1("CSR: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
} else {
DPRINT("-- 3\n");
/*
* Tell the init thread the SM gave the
* green light for boostrapping.
*/
Status = NtSetEvent (hBootstrapOk, NULL);
if(!NT_SUCCESS(Status))
{
DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
}
/* Wait for messages from the SM */
DPRINT("-- 4\n");
while (TRUE)
{
Status = NtReplyWaitReceivePort(hConnectedPort,
Context,
Reply,
&Request.h);
if(!NT_SUCCESS(Status))
{
DPRINT1("CSR: %s: NtReplyWaitReceivePort failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
break;
}
switch (Request.h.u2.s2.Type) //fix .h PORT_MESSAGE_TYPE(Request)) /* Move to the next data location */
{ ProcessData = (PVOID)((ULONG_PTR)ProcessData +
/* TODO */ CsrLoadedServerDll[i]->SizeOfProcessData);
case LPC_PORT_CLOSED: }
case LPC_CLIENT_DIED: else
DPRINT1("CSR: SMSS died\n"); {
Reply = NULL; /* Nothing for this Process */
break; CsrProcess->ServerData[i] = NULL;
default:
DPRINT1("CSR: %s received message (type=%d)\n",
__FUNCTION__, Request.h.u2.s2.Type);
if (Request.ApiNumber == SbpCreateSession)
{
DPRINT("Session create... legacy CSRSS resuming thread as minimum work done\n");
Request.ReturnValue = NtResumeThread(Request.CreateSession.ProcessInfo.ThreadHandle, NULL);
}
else
{
DPRINT1("CSR: %d Not implemented in legacy CSRSS... faking success\n", Request.ApiNumber);
Request.ReturnValue = STATUS_SUCCESS;
}
Reply = &Request.h;
}
DPRINT("-- 5\n");
}
}
} }
} }
DPRINT("CSR: %s: terminating!\n", __FUNCTION__); /* Insert the Process */
if(hConnectedPort) NtClose (hConnectedPort); CsrInsertProcess(NULL, NULL, CsrProcess);
NtClose (hSbApiPortListen); #endif
NtTerminateThread (NtCurrentThread(), Status); /* Activate the Thread */
return 0; ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);
/* Release lock and return */
// CsrReleaseProcessLock();
return TRUE;
}
/*++
* @name CsrSbForeignSessionComplete
*
* The CsrSbForeignSessionComplete API is called by the Session Manager
* whenever a foreign session is completed (ie: terminated).
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE othwerwise.
*
* @remarks The CsrSbForeignSessionComplete API is not yet implemented.
*
*--*/
BOOLEAN
NTAPI
CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage)
{
/* Deprecated/Unimplemented in NT */
ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
/*++
* @name CsrSbTerminateSession
*
* The CsrSbTerminateSession API is called by the Session Manager
* whenever a foreign session should be destroyed.
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE othwerwise.
*
* @remarks The CsrSbTerminateSession API is not yet implemented.
*
*--*/
BOOLEAN
NTAPI
CsrSbTerminateSession(IN PSB_API_MSG ApiMessage)
{
ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
/*++
* @name CsrSbCreateProcess
*
* The CsrSbCreateProcess API is called by the Session Manager
* whenever a foreign session is created and a new process should be started.
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE othwerwise.
*
* @remarks The CsrSbCreateProcess API is not yet implemented.
*
*--*/
BOOLEAN
NTAPI
CsrSbCreateProcess(IN PSB_API_MSG ApiMessage)
{
ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
PSB_API_ROUTINE CsrServerSbApiDispatch[5] =
{
CsrSbCreateSession,
CsrSbTerminateSession,
CsrSbForeignSessionComplete,
CsrSbCreateProcess,
NULL
};
/*++
* @name CsrSbApiHandleConnectionRequest
*
* The CsrSbApiHandleConnectionRequest routine handles and accepts a new
* connection request to the SM API LPC Port.
*
* @param ApiMessage
* Pointer to the incoming CSR API Message which contains the
* connection request.
*
* @return STATUS_SUCCESS in case of success, or status code which caused
* the routine to error.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message)
{
NTSTATUS Status;
REMOTE_PORT_VIEW RemotePortView;
HANDLE hPort;
/* Set the Port View Structure Length */
RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
/* Accept the connection */
Status = NtAcceptConnectPort(&hPort,
NULL,
(PPORT_MESSAGE)Message,
TRUE,
NULL,
&RemotePortView);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: Sb Accept Connection failed %lx\n", Status);
return Status;
}
/* Complete the Connection */
Status = NtCompleteConnectPort(hPort);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: Sb Complete Connection failed %lx\n",Status);
}
/* Return status */
return Status;
}
/*++
* @name CsrSbApiRequestThread
*
* The CsrSbApiRequestThread routine handles incoming messages or connection
* requests on the SM API LPC Port.
*
* @param Parameter
* System-default user-defined parameter. Unused.
*
* @return The thread exit code, if the thread is terminated.
*
* @remarks Before listening on the port, the routine will first attempt
* to connect to the user subsystem.
*
*--*/
VOID
NTAPI
CsrSbApiRequestThread(IN PVOID Parameter)
{
NTSTATUS Status;
SB_API_MSG ReceiveMsg;
PSB_API_MSG ReplyMsg = NULL;
PVOID PortContext;
ULONG MessageType;
/* Start the loop */
while (TRUE)
{
/* Wait for a message to come in */
Status = NtReplyWaitReceivePort(CsrSbApiPort,
&PortContext,
&ReplyMsg->h,
&ReceiveMsg.h);
/* Check if we didn't get success */
if (Status != STATUS_SUCCESS)
{
/* If we only got a warning, keep going */
if (NT_SUCCESS(Status)) continue;
/* We failed big time, so start out fresh */
ReplyMsg = NULL;
DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
continue;
}
/* Save the message type */
MessageType = ReceiveMsg.h.u2.s2.Type;
/* Check if this is a connection request */
if (MessageType == LPC_CONNECTION_REQUEST)
{
/* Handle connection request */
CsrSbApiHandleConnectionRequest(&ReceiveMsg);
/* Start over */
ReplyMsg = NULL;
continue;
}
/* Check if the port died */
if (MessageType == LPC_PORT_CLOSED)
{
/* Close the handle if we have one */
if (PortContext) NtClose((HANDLE)PortContext);
/* Client died, start over */
ReplyMsg = NULL;
continue;
}
else if (MessageType == LPC_CLIENT_DIED)
{
/* Client died, start over */
ReplyMsg = NULL;
continue;
}
/*
* It's an API Message, check if it's within limits. If it's not, the
* NT Behaviour is to set this to the Maximum API.
*/
if (ReceiveMsg.ApiNumber > SbpMaxApiNumber)
{
ReceiveMsg.ApiNumber = SbpMaxApiNumber;
DPRINT1("CSRSS: %lx is invalid Sb ApiNumber\n", ReceiveMsg.ApiNumber);
}
/* Reuse the message */
ReplyMsg = &ReceiveMsg;
/* Make sure that the message is supported */
if (ReceiveMsg.ApiNumber < SbpMaxApiNumber)
{
/* Call the API */
if (!CsrServerSbApiDispatch[ReceiveMsg.ApiNumber](&ReceiveMsg))
{
/* It failed, so return nothing */
ReplyMsg = NULL;
}
}
else
{
/* We don't support this API Number */
ReplyMsg->ReturnValue = STATUS_NOT_IMPLEMENTED;
}
}
} }
/* EOF */ /* EOF */

View file

@ -17,12 +17,13 @@
HANDLE CsrHeap = (HANDLE) 0; HANDLE CsrHeap = (HANDLE) 0;
HANDLE CsrObjectDirectory = (HANDLE) 0; HANDLE CsrObjectDirectory = (HANDLE) 0;
UNICODE_STRING CsrDirectoryName; UNICODE_STRING CsrDirectoryName;
extern HANDLE CsrssApiHeap; UNICODE_STRING CsrSbApiPortName;
HANDLE CsrSbApiPort = 0;
PCSR_THREAD CsrSbApiRequestThreadPtr;
static unsigned ServerProcCount; static unsigned ServerProcCount;
static CSRPLUGIN_SERVER_PROCS *ServerProcs = NULL; static CSRPLUGIN_SERVER_PROCS *ServerProcs = NULL;
HANDLE CsrSmApiPort;
HANDLE hSbApiPort = (HANDLE) 0; HANDLE hSbApiPort = (HANDLE) 0;
HANDLE hBootstrapOk = (HANDLE) 0;
HANDLE hSmApiPort = (HANDLE) 0;
HANDLE hApiPort = (HANDLE) 0; HANDLE hApiPort = (HANDLE) 0;
ULONG CsrDebug = 0xFFFFFFFF; ULONG CsrDebug = 0xFFFFFFFF;
ULONG CsrMaxApiRequestThreads; ULONG CsrMaxApiRequestThreads;
@ -31,6 +32,8 @@ ULONG SessionId;
HANDLE BNOLinksDirectory; HANDLE BNOLinksDirectory;
HANDLE SessionObjectDirectory; HANDLE SessionObjectDirectory;
HANDLE DosDevicesDirectory; HANDLE DosDevicesDirectory;
HANDLE CsrInitializationEvent;
SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
@ -41,7 +44,7 @@ CsrpAddServerProcs(CSRPLUGIN_SERVER_PROCS *Procs)
DPRINT("CSR: %s called\n", __FUNCTION__); DPRINT("CSR: %s called\n", __FUNCTION__);
NewProcs = RtlAllocateHeap(CsrssApiHeap, 0, NewProcs = RtlAllocateHeap(CsrHeap, 0,
(ServerProcCount + 1) (ServerProcCount + 1)
* sizeof(CSRPLUGIN_SERVER_PROCS)); * sizeof(CSRPLUGIN_SERVER_PROCS));
if (NULL == NewProcs) if (NULL == NewProcs)
@ -52,7 +55,7 @@ CsrpAddServerProcs(CSRPLUGIN_SERVER_PROCS *Procs)
{ {
RtlCopyMemory(NewProcs, ServerProcs, RtlCopyMemory(NewProcs, ServerProcs,
ServerProcCount * sizeof(CSRPLUGIN_SERVER_PROCS)); ServerProcCount * sizeof(CSRPLUGIN_SERVER_PROCS));
RtlFreeHeap(CsrssApiHeap, 0, ServerProcs); RtlFreeHeap(CsrHeap, 0, ServerProcs);
} }
NewProcs[ServerProcCount] = *Procs; NewProcs[ServerProcCount] = *Procs;
ServerProcs = NewProcs; ServerProcs = NewProcs;
@ -61,26 +64,6 @@ CsrpAddServerProcs(CSRPLUGIN_SERVER_PROCS *Procs)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/**********************************************************************
* CallInitComplete/0
*/
static BOOL FASTCALL
CallInitComplete(void)
{
BOOL Ok;
unsigned i;
DPRINT("CSR: %s called\n", __FUNCTION__);
Ok = TRUE;
for (i = 0; i < ServerProcCount && Ok; i++)
{
Ok = (*ServerProcs[i].InitCompleteProc)();
}
return Ok;
}
BOOL BOOL
CallHardError(IN PCSRSS_PROCESS_DATA ProcessData, CallHardError(IN PCSRSS_PROCESS_DATA ProcessData,
IN PHARDERROR_MSG HardErrorMessage) IN PHARDERROR_MSG HardErrorMessage)
@ -167,7 +150,7 @@ CsrpInitWin32Csr (VOID)
return Status; return Status;
} }
Exports.CsrEnumProcessesProc = CsrEnumProcesses; Exports.CsrEnumProcessesProc = CsrEnumProcesses;
if (! (*InitProc)(&ApiDefinitions, &ServerProcs, &Exports, CsrssApiHeap)) if (! (*InitProc)(&ApiDefinitions, &ServerProcs, &Exports, CsrHeap))
{ {
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -233,12 +216,12 @@ CsrpCreateListenPort (IN LPWSTR Name,
*Port, *Port,
&ServerThread, &ServerThread,
&ClientId); &ClientId);
if (ListenThread == (PVOID)ClientConnectionThread) if (ListenThread == (PVOID)ClientConnectionThread)
{ {
CsrAddStaticServerThread(ServerThread, &ClientId, 0); CsrAddStaticServerThread(ServerThread, &ClientId, 0);
} }
NtResumeThread(ServerThread, NULL); NtResumeThread(ServerThread, NULL);
NtClose(ServerThread); NtClose(ServerThread);
return Status; return Status;
@ -254,94 +237,118 @@ NTSTATUS
NTAPI NTAPI
CsrSrvCreateSharedSection(IN PCHAR ParameterValue); CsrSrvCreateSharedSection(IN PCHAR ParameterValue);
/********************************************************************** /*++
* CsrpCreateHeap/3 * @name CsrSetProcessSecurity
*/ *
static NTSTATUS * The CsrSetProcessSecurity routine protects access to the CSRSS process
CsrpCreateHeap (VOID) * from unauthorized tampering.
*
* @param None.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSetProcessSecurity(VOID)
{ {
DPRINT("CSR: %s called\n", __FUNCTION__); NTSTATUS Status;
HANDLE hToken, hProcess = NtCurrentProcess();
ULONG Length;
PTOKEN_USER TokenInfo = NULL;
PSECURITY_DESCRIPTOR ProcSd = NULL;
PACL Dacl;
PSID UserSid;
CsrHeap = RtlGetProcessHeap(); /* Open our token */
CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE, Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
NULL, if (!NT_SUCCESS(Status)) goto Quickie;
65536,
65536,
NULL,
NULL);
if (CsrssApiHeap == NULL)
{
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
/********************************************************************** /* Get the Token User Length */
* CsrpRegisterSubsystem/3 NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);
*/
BOOLEAN g_ModernSm;
static NTSTATUS
CsrpRegisterSubsystem (VOID)
{
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES BootstrapOkAttributes;
UNICODE_STRING Name;
DPRINT("CSR: %s called\n", __FUNCTION__); /* Allocate space for it */
TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
if (!TokenInfo)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* /* Now query the data */
* Create the event object the callback port Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length);
* thread will signal *if* the SM will NtClose(hToken);
* authorize us to bootstrap. if (!NT_SUCCESS(Status)) goto Quickie;
*/
RtlInitUnicodeString (& Name, L"\\CsrssBooting"); /* Now check the SID Length */
InitializeObjectAttributes(& BootstrapOkAttributes, UserSid = TokenInfo->User.Sid;
& Name, Length = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
0, NULL, NULL);
Status = NtCreateEvent (& hBootstrapOk, /* Allocate a buffer for the Security Descriptor, with SID and DACL */
EVENT_ALL_ACCESS, ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
& BootstrapOkAttributes, if (!ProcSd)
SynchronizationEvent, {
FALSE); Status = STATUS_NO_MEMORY;
if(!NT_SUCCESS(Status)) goto Quickie;
{ }
DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
__FUNCTION__, Status); /* Set the pointer to the DACL */
return Status; Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
}
/* /* Now create the SD itself */
* Let's tell the SM a new environment Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION);
* subsystem server is in the system.
*/
RtlInitUnicodeString (& Name, L"\\Windows\\SbApiPort");
DPRINT("CSR: %s: registering with SM for\n IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__);
Status = SmConnectApiPort (& Name,
hSbApiPort,
IMAGE_SUBSYSTEM_WINDOWS_CUI,
& hSmApiPort);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
Status = SmConnectToSm(&Name, hSbApiPort, IMAGE_SUBSYSTEM_WINDOWS_GUI, &hSmApiPort); DPRINT1("CSRSS: SD creation failed - status = %lx\n", Status);
g_ModernSm = TRUE; goto Quickie;
} }
if(!NT_SUCCESS(Status))
{ /* Create the DACL for it*/
DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n", Status = RtlCreateAcl(Dacl, Length, ACL_REVISION2);
__FUNCTION__, Status); if (!NT_SUCCESS(Status))
NtClose (hBootstrapOk); {
return Status; DPRINT1("CSRSS: DACL creation failed - status = %lx\n", Status);
} goto Quickie;
/* }
* Wait for SM to reply OK... If the SM
* won't answer, we hang here forever! /* Create the ACE */
*/ Status = RtlAddAccessAllowedAce(Dacl,
DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__); ACL_REVISION,
Status = NtWaitForSingleObject (hBootstrapOk, PROCESS_VM_READ | PROCESS_VM_WRITE |
FALSE, PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
NULL); PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
NtClose (hBootstrapOk); PROCESS_QUERY_INFORMATION | READ_CONTROL,
return Status; UserSid);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: ACE creation failed - status = %lx\n", Status);
goto Quickie;
}
/* Clear the DACL in the SD */
Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: set DACL failed - status = %lx\n", Status);
goto Quickie;
}
/* Write the SD into the Process */
Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: set process DACL failed - status = %lx\n", Status);
goto Quickie;
}
/* Free the memory and return */
Quickie:
if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
RtlFreeHeap(CsrHeap, 0, TokenInfo);
return Status;
} }
/*++ /*++
@ -764,11 +771,9 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount,
{ {
/* Split Name and Value */ /* Split Name and Value */
ParameterName = Arguments[i]; ParameterName = Arguments[i];
DPRINT1("Name: %s\n", ParameterName);
ParameterValue = NULL; ParameterValue = NULL;
ParameterValue = strchr(ParameterName, '='); ParameterValue = strchr(ParameterName, '=');
if (ParameterValue) *ParameterValue++ = ANSI_NULL; if (ParameterValue) *ParameterValue++ = ANSI_NULL;
DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue);
/* Check for Object Directory */ /* Check for Object Directory */
if (!_stricmp(ParameterName, "ObjectDirectory")) if (!_stricmp(ParameterName, "ObjectDirectory"))
@ -898,21 +903,218 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount,
return Status; return Status;
} }
/*++
* @name CsrCreateLocalSystemSD
*
* The CsrCreateLocalSystemSD routine creates a Security Descriptor for
* the local account with PORT_ALL_ACCESS.
*
* @param LocalSystemSd
* Pointer to a pointer to the security descriptor to create.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
{
SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
PSID SystemSid;
ULONG Length;
PSECURITY_DESCRIPTOR SystemSd;
PACL Dacl;
NTSTATUS Status;
/* Initialize the System SID */
RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0,
&SystemSid);
/* Get the length of the SID */
Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
/* Allocate a buffer for the Security Descriptor, with SID and DACL */
SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
/* Set the pointer to the DACL */
Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
/* Now create the SD itself */
Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SystemSd);
return Status;
}
/* Create the DACL for it*/
RtlCreateAcl(Dacl, Length, ACL_REVISION2);
/* Create the ACE */
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SystemSd);
return Status;
}
/* Clear the DACL in the SD */
Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SystemSd);
return Status;
}
/* Free the SID and return*/
RtlFreeSid(SystemSid);
*LocalSystemSd = SystemSd;
return Status;
}
/*++
* @name CsrSbApiPortInitialize
*
* The CsrSbApiPortInitialize routine initializes the LPC Port used for
* communications with the Session Manager (SM) and initializes the static
* thread that will handle connection requests and APIs.
*
* @param None
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSbApiPortInitialize(VOID)
{
ULONG Size;
PSECURITY_DESCRIPTOR PortSd;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
HANDLE hRequestThread;
CLIENT_ID ClientId;
/* Calculate how much space we'll need for the Port Name */
Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR);
/* Create the buffer for it */
CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY;
/* Setup the rest of the empty string */
CsrSbApiPortName.Length = 0;
CsrSbApiPortName.MaximumLength = (USHORT)Size;
/* Now append the full port name */
RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName);
RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP);
RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME);
if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName);
/* Create Security Descriptor for this Port */
Status = CsrCreateLocalSystemSD(&PortSd);
if (!NT_SUCCESS(Status)) return Status;
/* Initialize the Attributes */
InitializeObjectAttributes(&ObjectAttributes,
&CsrSbApiPortName,
0,
NULL,
PortSd);
/* Create the Port Object */
Status = NtCreatePort(&CsrSbApiPort,
&ObjectAttributes,
sizeof(SB_CONNECTION_INFO),
sizeof(SB_API_MSG),
32 * sizeof(SB_API_MSG));
if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd);
if (NT_SUCCESS(Status))
{
/* Create the Thread to handle the API Requests */
Status = RtlCreateUserThread(NtCurrentProcess(),
NULL,
TRUE,
0,
0,
0,
(PVOID)CsrSbApiRequestThread,
NULL,
&hRequestThread,
&ClientId);
if (NT_SUCCESS(Status))
{
/* Add it as a Static Server Thread */
CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread,
&ClientId,
0);
/* Activate it */
Status = NtResumeThread(hRequestThread, NULL);
}
}
return Status;
}
/* PUBLIC FUNCTIONS ***********************************************************/ /* PUBLIC FUNCTIONS ***********************************************************/
NTSTATUS NTSTATUS
NTAPI NTAPI
CsrServerInitialization(ULONG ArgumentCount, CsrServerInitialization(IN ULONG ArgumentCount,
PCHAR Arguments[]) IN PCHAR Arguments[])
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
DPRINT("CSR: %s called\n", __FUNCTION__); /* Create the Init Event */
Status = NtCreateEvent(&CsrInitializationEvent,
Status = CsrpCreateHeap(); EVENT_ALL_ACCESS,
NULL,
SynchronizationEvent,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateHeap", Status); DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Cache System Basic Information so we don't always request it */
Status = NtQuerySystemInformation(SystemBasicInformation,
&CsrNtSysInfo,
sizeof(SYSTEM_BASIC_INFORMATION),
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Save our Heap */
CsrHeap = RtlGetProcessHeap();
/* Set our Security Descriptor to protect the process */
Status = CsrSetProcessSecurity();
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
} }
/* Parse the command line */ /* Parse the command line */
@ -923,14 +1125,8 @@ CsrServerInitialization(ULONG ArgumentCount,
__FUNCTION__, Status); __FUNCTION__, Status);
return Status; return Status;
} }
CsrInitProcessData();
Status = CsrpCreateListenPort(L"\\Windows\\ApiPort", &hApiPort, (PTHREAD_START_ROUTINE)ClientConnectionThread); CsrInitProcessData();
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateApiPort", Status);
}
Status = CsrApiRegisterDefinitions(NativeDefinitions); Status = CsrApiRegisterDefinitions(NativeDefinitions);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -938,36 +1134,62 @@ CsrServerInitialization(ULONG ArgumentCount,
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrApiRegisterDefinitions", Status); DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrApiRegisterDefinitions", Status);
} }
Status = CsrpCreateListenPort(L"\\Windows\\ApiPort", &hApiPort, (PTHREAD_START_ROUTINE)ClientConnectionThread);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateApiPort", Status);
}
Status = CsrpInitWin32Csr(); Status = CsrpInitWin32Csr();
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpInitWin32Csr", Status); DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpInitWin32Csr", Status);
} }
Status = CsrpCreateListenPort(L"\\Windows\\SbApiPort", &hSbApiPort, ServerSbApiPortThread); /* Initialize the API Port for SM communication */
Status = CsrSbApiPortInitialize();
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateCallbackPort", Status); DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
} }
Status = CsrpRegisterSubsystem(); /* We're all set! Connect to SM! */
Status = SmConnectToSm(&CsrSbApiPortName,
CsrSbApiPort,
IMAGE_SUBSYSTEM_WINDOWS_GUI,
&CsrSmApiPort);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpRegisterSubsystem", Status); DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
} }
/* Finito! Signal the event */
Status = NtSetEvent(CsrInitializationEvent, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Close the event handle now */
NtClose(CsrInitializationEvent);
/* Have us handle Hard Errors */
Status = NtSetDefaultHardErrorPort(hApiPort); Status = NtSetDefaultHardErrorPort(hApiPort);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateHardErrorPort", Status); DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
} }
if (CallInitComplete()) /* Return status */
{ return Status;
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
} }
BOOL BOOL

View file

@ -121,14 +121,18 @@ CSR_API(CsrSrvCreateThread);
CSR_API(CsrGetShutdownParameters); CSR_API(CsrGetShutdownParameters);
CSR_API(CsrSetShutdownParameters); CSR_API(CsrSetShutdownParameters);
PCSR_THREAD
NTAPI
CsrAllocateThread(IN PCSRSS_PROCESS_DATA CsrProcess);
/* api/wapi.c */ /* api/wapi.c */
NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions); NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions);
VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData, VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
PCSR_API_MESSAGE Request); PCSR_API_MESSAGE Request);
DWORD WINAPI ServerSbApiPortThread (PVOID PortHandle); VOID WINAPI CsrSbApiRequestThread (PVOID PortHandle);
VOID NTAPI ClientConnectionThread(HANDLE ServerPort); VOID NTAPI ClientConnectionThread(HANDLE ServerPort);
extern HANDLE CsrssApiHeap; extern HANDLE CsrSbApiPort;
/* api/process.c */ /* api/process.c */
typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESS_PROC)(PCSRSS_PROCESS_DATA ProcessData, typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESS_PROC)(PCSRSS_PROCESS_DATA ProcessData,

View file

@ -335,14 +335,14 @@ BOOL WINAPI
Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions, Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
PCSRPLUGIN_SERVER_PROCS ServerProcs, PCSRPLUGIN_SERVER_PROCS ServerProcs,
PCSRSS_EXPORTED_FUNCS Exports, PCSRSS_EXPORTED_FUNCS Exports,
HANDLE CsrssApiHeap) HANDLE CsrHeap)
{ {
HANDLE ServerThread; HANDLE ServerThread;
CLIENT_ID ClientId; CLIENT_ID ClientId;
NTSTATUS Status; NTSTATUS Status;
CsrExports = *Exports; CsrExports = *Exports;
Win32CsrApiHeap = CsrssApiHeap; Win32CsrApiHeap = CsrHeap;
CsrpInitVideo(); CsrpInitVideo();