/*++ * @name CsrSbCreateSession * * The CsrSbCreateSession API is called by the Session Manager whenever a new * session is created. * * @param ApiMessage * Pointer to the Session Manager API Message. * * @return TRUE in case of success, FALSE otherwise. * * @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) { PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession; HANDLE hProcess, hThread; PCSR_PROCESS CsrProcess; NTSTATUS Status; KERNEL_USER_TIMES KernelTimes; PCSR_THREAD CsrThread; //PVOID ProcessData; //ULONG i; /* Save the Process and Thread Handles */ hProcess = CreateSession->ProcessInfo.ProcessHandle; hThread = CreateSession->ProcessInfo.ThreadHandle; /* Lock the Processes */ CsrAcquireProcessLock(); /* Allocate a new process */ CsrProcess = CsrAllocateProcess(); if (!CsrProcess) { /* Fail */ ApiMessage->ReturnValue = STATUS_NO_MEMORY; CsrReleaseProcessLock(); return TRUE; } /* Set the exception port */ Status = NtSetInformationProcess(hProcess, ProcessExceptionPort, &CsrApiPort, sizeof(HANDLE)); /* Check for success */ if (!NT_SUCCESS(Status)) { /* Fail the request */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); /* Strange as it seems, NTSTATUSes are actually returned */ return (BOOLEAN)STATUS_NO_MEMORY; } /* Get the Create Time */ Status = NtQueryInformationThread(hThread, ThreadTimes, &KernelTimes, sizeof(KERNEL_USER_TIMES), NULL); /* Check for success */ if (!NT_SUCCESS(Status)) { /* Fail the request */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); /* Strange as it seems, NTSTATUSes are actually returned */ return (BOOLEAN)Status; } /* Allocate a new Thread */ 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); #if 0 /* 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) { /* Write the pointer to the data */ CsrProcess->ServerData[i] = ProcessData; /* Move to the next data location */ ProcessData = (PVOID)((ULONG_PTR)ProcessData + CsrLoadedServerDll[i]->SizeOfProcessData); } else { /* Nothing for this Process */ CsrProcess->ServerData[i] = NULL; } } #else /* HACKZ: should go in BaseSrv part of CreateCallback done in Insert below */ RtlInitializeCriticalSection(&CsrProcess->HandleTableLock); #endif /* Insert the Process */ CsrInsertProcess(NULL, NULL, CsrProcess); /* Activate the Thread */ ApiMessage->ReturnValue = NtResumeThread(hThread, NULL); /* Release lock and return */ CsrReleaseProcessLock(); return TRUE; }
/*++ * @name CsrCreateProcess * @implemented NT4 * * The CsrCreateProcess routine creates a CSR Process object for an NT Process. * * @param hProcess * Handle to an existing NT Process to which to associate this * CSR Process. * * @param hThread * Handle to an existing NT Thread to which to create its * corresponding CSR Thread for this CSR Process. * * @param ClientId * Pointer to the Client ID structure of the NT Process to associate * with this CSR Process. * * @param NtSession * @param Flags * @param DebugCid * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise. * * @remarks None. * *--*/ NTSTATUS NTAPI CsrCreateProcess(IN HANDLE hProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId, IN PCSR_NT_SESSION NtSession, IN ULONG Flags, IN PCLIENT_ID DebugCid) { PCSR_THREAD CurrentThread = CsrGetClientThread(); CLIENT_ID CurrentCid; PCSR_PROCESS CurrentProcess; PCSR_SERVER_DLL ServerDll; PVOID ProcessData; ULONG i; PCSR_PROCESS CsrProcess; NTSTATUS Status; PCSR_THREAD CsrThread; KERNEL_USER_TIMES KernelTimes; /* Get the current CID and lock Processes */ CurrentCid = CurrentThread->ClientId; CsrAcquireProcessLock(); /* Get the current CSR Thread */ CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid); if (!CurrentThread) { /* We've failed to locate the thread */ CsrReleaseProcessLock(); return STATUS_THREAD_IS_TERMINATING; } /* Allocate a new Process Object */ CsrProcess = CsrAllocateProcess(); if (!CsrProcess) { /* Couldn't allocate Process */ CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } /* Inherit the Process Data */ CurrentProcess = CurrentThread->Process; ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX]; for (i = 0; i < CSR_SERVER_DLL_MAX; i++) { /* Get the current Server */ ServerDll = CsrLoadedServerDll[i]; /* Check if the DLL is Loaded and has Per Process Data */ if (ServerDll && ServerDll->SizeOfProcessData) { /* Set the pointer */ CsrProcess->ServerData[i] = ProcessData; /* Copy the Data */ RtlMoveMemory(ProcessData, CurrentProcess->ServerData[i], ServerDll->SizeOfProcessData); /* Update next data pointer */ ProcessData = (PVOID)((ULONG_PTR)ProcessData + ServerDll->SizeOfProcessData); } else { /* No data for this Server */ CsrProcess->ServerData[i] = NULL; } } /* Set the Exception Port for us */ Status = NtSetInformationProcess(hProcess, ProcessExceptionPort, &CsrApiPort, sizeof(CsrApiPort)); if (!NT_SUCCESS(Status)) { /* Failed */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } /* Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */ if (Flags & CsrProcessCreateNewGroup) { /* * We create the process group leader of a new process group, therefore * its process group ID and sequence number are its own ones. */ CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess); CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber; } else { /* Inherit the process group ID and sequence number from the current process */ CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId; CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence; } /* Check if this is a console process */ if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp; /* Mask out non-debug flags */ Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags); /* Check if every process will be debugged */ if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren)) { /* Pass it on to the current process */ CsrProcess->DebugFlags = CsrDebugProcessChildren; CsrProcess->DebugCid = CurrentProcess->DebugCid; } /* Check if Debugging was used on this process */ if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid)) { /* Save the debug flag used */ CsrProcess->DebugFlags = Flags; /* Save the CID */ CsrProcess->DebugCid = *DebugCid; } /* Check if Debugging is enabled */ if (CsrProcess->DebugFlags) { /* Set the Debug Port for us */ Status = NtSetInformationProcess(hProcess, ProcessDebugPort, &CsrApiPort, sizeof(CsrApiPort)); ASSERT(NT_SUCCESS(Status)); if (!NT_SUCCESS(Status)) { /* Failed */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } } /* Get the Thread Create Time */ Status = NtQueryInformationThread(hThread, ThreadTimes, &KernelTimes, sizeof(KernelTimes), NULL); if (!NT_SUCCESS(Status)) { /* Failed */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } /* Allocate a CSR Thread Structure */ CsrThread = CsrAllocateThread(CsrProcess); if (!CsrThread) { /* Failed */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } /* Save the data we have */ CsrThread->CreateTime = KernelTimes.CreateTime; CsrThread->ClientId = *ClientId; CsrThread->ThreadHandle = hThread; ProtectHandle(hThread); CsrThread->Flags = 0; /* Insert the Thread into the Process */ Status = CsrInsertThread(CsrProcess, CsrThread); if (!NT_SUCCESS(Status)) { /* Bail out */ CsrDeallocateProcess(CsrProcess); CsrDeallocateThread(CsrThread); CsrReleaseProcessLock(); return Status; } /* Reference the session */ CsrReferenceNtSession(NtSession); CsrProcess->NtSession = NtSession; /* Setup Process Data */ CsrProcess->ClientId = *ClientId; CsrProcess->ProcessHandle = hProcess; CsrProcess->ShutdownLevel = 0x280; /* Set the Priority to Background */ CsrSetBackgroundPriority(CsrProcess); /* Insert the Process */ CsrInsertProcess(CurrentProcess, CsrProcess); /* Release lock and return */ CsrReleaseProcessLock(); return Status; }