/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS CSR SubSystem
- * FILE: subsystems/win32/csrss/csrsrv/procsup.c
+ * PROJECT: ReactOS Client/Server Runtime SubSystem
+ * FILE: subsystems/win32/csrsrv/procsup.c
* PURPOSE: CSR Server DLL Process Management
* PROGRAMMERS: ReactOS Portable Systems Group
* Alex Ionescu (alex@relsoft.net)
*/
-
+
/* INCLUDES *******************************************************************/
#include <srv.h>
FALSE
};
ULONG CsrProcessSequenceCount = 5;
-extern ULONG CsrTotalPerProcessDataLength; // remove 'extern' if not needed.
+extern ULONG CsrTotalPerProcessDataLength;
/* PRIVATE FUNCTIONS **********************************************************/
/*++
- * @name CsrpSetToNormalPriority
+ * @name CsrSetToNormalPriority
*
- * The CsrpSetToNormalPriority routine sets the current NT Process'
+ * The CsrSetToNormalPriority routine sets the current NT Process'
* priority to the normal priority for CSR Processes.
*
* @param None.
*--*/
VOID
NTAPI
-CsrSetToNormalPriority(VOID) // CsrpSetToNormalPriority
+CsrSetToNormalPriority(VOID)
{
KPRIORITY BasePriority = (8 + 1) + 4;
}
/*++
- * @name CsrpSetToShutdownPriority
+ * @name CsrSetToShutdownPriority
*
- * The CsrpSetToShutdownPriority routine sets the current NT Process'
+ * The CsrSetToShutdownPriority routine sets the current NT Process'
* priority to the boosted priority for CSR Processes doing shutdown.
* Additonally, it acquires the Shutdown Privilege required for shutdown.
*
*--*/
VOID
NTAPI
-CsrSetToShutdownPriority(VOID) // CsrpSetToShutdownPriority
+CsrSetToShutdownPriority(VOID)
{
KPRIORITY SetBasePriority = (8 + 1) + 6;
BOOLEAN Old;
{
/* Call the generic cleanup code */
DPRINT1("Should kill process: %p\n", CsrProcess);
- CsrProcessRefcountZero(CsrProcess);
CsrAcquireProcessLock();
+ CsrProcessRefcountZero(CsrProcess);
}
}
if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5;
/* Increase the reference count */
- CsrProcess->ReferenceCount++;
+ CsrLockedReferenceProcess(CsrProcess);
/* Initialize the Thread List */
InitializeListHead(&CsrProcess->ThreadList);
* @implemented NT4
*
* The CsrInitializeProcessStructure routine sets up support for CSR Processes
- * and CSR Threads.
+ * and CSR Threads by initializing our own CSR Root Process.
*
* @param None.
*
ServerDll = CsrLoadedServerDll[i];
/* Check if it's valid and if it has a Disconnect Callback */
- if ((ServerDll) && (ServerDll->DisconnectCallback))
+ if (ServerDll && ServerDll->DisconnectCallback)
{
/* Call it */
ServerDll->DisconnectCallback(CsrProcess);
* The CsrInsertProcess routine inserts a CSR Process into the Process List
* and notifies Server DLLs of the creation of a new CSR Process.
*
- * @param Parent
- * Optional pointer to the CSR Process creating this CSR Process.
- *
- * @param CurrentProcess
- * Optional pointer to the current CSR Process.
+ * @param ParentProcess
+ * Optional pointer to the Parent Process creating this CSR Process.
*
* @param CsrProcess
* Pointer to the CSR Process which is to be inserted.
*--*/
VOID
NTAPI
-CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
- IN PCSR_PROCESS CurrentProcess OPTIONAL,
+CsrInsertProcess(IN PCSR_PROCESS ParentProcess OPTIONAL,
IN PCSR_PROCESS CsrProcess)
{
PCSR_SERVER_DLL ServerDll;
ULONG i;
ASSERT(ProcessStructureListLocked());
- /* Set the parent */
- CsrProcess->Parent = Parent;
-
/* Insert it into the Root List */
InsertTailList(&CsrRootProcess->ListLink, &CsrProcess->ListLink);
ServerDll = CsrLoadedServerDll[i];
/* Make sure it's valid and that it has callback */
- if ((ServerDll) && (ServerDll->NewProcessCallback))
+ if (ServerDll && ServerDll->NewProcessCallback)
{
- ServerDll->NewProcessCallback(CurrentProcess, CsrProcess);
+ ServerDll->NewProcessCallback(ParentProcess, CsrProcess);
}
}
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*++
- * @name CsrGetProcessLuid
+ * @name CsrCreateProcess
* @implemented NT4
*
* Do nothing for 500ms.
*
- * @param hProcess
- * Optional handle to the process whose LUID should be returned.
+ * @param ArgumentCount
+ * Description of the parameter. Wrapped to more lines on ~70th
+ * column.
*
- * @param Luid
- * Pointer to a LUID Pointer which will receive the CSR Process' LUID
+ * @param Arguments
+ * Description of the parameter. Wrapped to more lines on ~70th
+ * column.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* otherwise.
*
- * @remarks If hProcess is not supplied, then the current thread's token will
- * be used. If that too is missing, then the current process' token
- * will be used.
+ * @remarks None.
*
*--*/
NTSTATUS
NTAPI
-CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
- PLUID Luid)
+CsrCreateProcess(IN HANDLE hProcess,
+ IN HANDLE hThread,
+ IN PCLIENT_ID ClientId,
+ IN PCSR_NT_SESSION NtSession,
+ IN ULONG Flags,
+ IN PCLIENT_ID DebugCid)
{
- HANDLE hToken = NULL;
+ PCSR_THREAD CurrentThread = CsrGetClientThread();
+ CLIENT_ID CurrentCid;
+ PCSR_PROCESS CurrentProcess;
+ PCSR_SERVER_DLL ServerDll;
+ PVOID ProcessData;
+ ULONG i;
+ PCSR_PROCESS CsrProcess;
NTSTATUS Status;
- ULONG Length;
- PTOKEN_STATISTICS TokenStats;
+ PCSR_THREAD CsrThread;
+ KERNEL_USER_TIMES KernelTimes;
- /* Check if we have a handle to a CSR Process */
- if (!hProcess)
+ /* Get the current CID and lock Processes */
+ CurrentCid = CurrentThread->ClientId;
+ CsrAcquireProcessLock();
+
+ /* Get the current CSR Thread */
+ CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
+ if (!CurrentThread)
{
- /* We don't, so try opening the Thread's Token */
- Status = NtOpenThreadToken(NtCurrentThread(),
- TOKEN_QUERY,
- FALSE,
- &hToken);
+ /* We've failed to locate the thread */
+ CsrReleaseProcessLock();
+ return STATUS_THREAD_IS_TERMINATING;
+ }
- /* Check for success */
- if (!NT_SUCCESS(Status))
+ /* 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)
{
- /* If we got some other failure, then return and quit */
- if (Status != STATUS_NO_TOKEN) return Status;
+ /* Set the pointer */
+ CsrProcess->ServerData[i] = ProcessData;
- /* We don't have a Thread Token, use a Process Token */
- hProcess = NtCurrentProcess();
- hToken = NULL;
+ /* 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;
}
}
- /* Check if we have a token by now */
- if (!hToken)
+ /* Set the Exception port for us */
+ Status = NtSetInformationProcess(hProcess,
+ ProcessExceptionPort,
+ &CsrApiPort,
+ sizeof(HANDLE));
+ if (!NT_SUCCESS(Status))
{
- /* No token yet, so open the Process Token */
- Status = NtOpenProcessToken(hProcess,
- TOKEN_QUERY,
- &hToken);
+ /* Failed */
+ CsrDeallocateProcess(CsrProcess);
+ CsrReleaseProcessLock();
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
+ if (!(Flags & CsrProcessCreateNewGroup))
+ {
+ /* Create new data */
+ CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess);
+ CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber;
+ }
+ else
+ {
+ /* Copy it 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(HANDLE));
+ ASSERT(NT_SUCCESS(Status));
if (!NT_SUCCESS(Status))
{
- /* Still no token, return the error */
- return Status;
+ /* Failed */
+ CsrDeallocateProcess(CsrProcess);
+ CsrReleaseProcessLock();
+ return STATUS_NO_MEMORY;
}
}
- /* Now get the size we'll need for the Token Information */
- Status = NtQueryInformationToken(hToken,
- TokenStatistics,
- NULL,
- 0,
- &Length);
+ /* Get the Thread Create Time */
+ Status = NtQueryInformationThread(hThread,
+ ThreadTimes,
+ (PVOID)&KernelTimes,
+ sizeof(KernelTimes),
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed */
+ CsrDeallocateProcess(CsrProcess);
+ CsrReleaseProcessLock();
+ return STATUS_NO_MEMORY;
+ }
- /* Allocate memory for the Token Info */
- if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length)))
+ /* Allocate a CSR Thread Structure */
+ CsrThread = CsrAllocateThread(CsrProcess);
+ if (!CsrThread)
{
- /* Fail and close the token */
- NtClose(hToken);
+ /* Failed */
+ CsrDeallocateProcess(CsrProcess);
+ CsrReleaseProcessLock();
return STATUS_NO_MEMORY;
}
- /* Now query the information */
- Status = NtQueryInformationToken(hToken,
- TokenStatistics,
- TokenStats,
- Length,
- &Length);
+ /* Save the data we have */
+ CsrThread->CreateTime = KernelTimes.CreateTime;
+ CsrThread->ClientId = *ClientId;
+ CsrThread->ThreadHandle = hThread;
+ ProtectHandle(hThread);
+ CsrThread->Flags = 0;
- /* Close the handle */
- NtClose(hToken);
+ /* Insert the Thread into the Process */
+ CsrInsertThread(CsrProcess, CsrThread);
- /* Check for success */
- if (NT_SUCCESS(Status))
- {
- /* Return the LUID */
- *Luid = TokenStats->AuthenticationId;
- }
+ /* Reference the session */
+ CsrReferenceNtSession(NtSession);
+ CsrProcess->NtSession = NtSession;
- /* Free the query information */
- RtlFreeHeap(CsrHeap, 0, TokenStats);
+ /* Setup Process Data */
+ CsrProcess->ClientId = *ClientId;
+ CsrProcess->ProcessHandle = hProcess;
+ CsrProcess->ShutdownLevel = 0x280;
- /* Return the Status */
+ /* Set the Priority to Background */
+ CsrSetBackgroundPriority(CsrProcess);
+
+ /* Insert the Process */
+ CsrInsertProcess(CurrentProcess, CsrProcess);
+
+ /* Release lock and return */
+ CsrReleaseProcessLock();
return Status;
}
/*++
- * @name CsrImpersonateClient
+ * @name CsrDebugProcess
* @implemented NT4
*
- * The CsrImpersonateClient will impersonate the given CSR Thread.
+ * The CsrDebugProcess routine is deprecated in NT 5.1 and higher. It is
+ * exported only for compatibility with older CSR Server DLLs.
*
- * @param CsrThread
- * Pointer to the CSR Thread to impersonate.
+ * @param CsrProcess
+ * Deprecated.
*
- * @return TRUE if impersionation suceeded, false otherwise.
+ * @return Deprecated
*
- * @remarks Impersonation can be recursive.
+ * @remarks Deprecated.
*
*--*/
-BOOLEAN
+NTSTATUS
NTAPI
-CsrImpersonateClient(IN PCSR_THREAD CsrThread)
+CsrDebugProcess(IN PCSR_PROCESS CsrProcess)
{
- NTSTATUS Status;
- PCSR_THREAD CurrentThread = CsrGetClientThread();
-
- /* Use the current thread if none given */
- if (!CsrThread) CsrThread = CurrentThread;
-
- /* Still no thread, something is wrong */
- if (!CsrThread)
- {
- /* Failure */
- return FALSE;
- }
-
- /* Make the call */
- Status = NtImpersonateThread(NtCurrentThread(),
- CsrThread->ThreadHandle,
- &CsrSecurityQos);
-
- if (!NT_SUCCESS(Status))
- {
- /* Failure */
-/*
- DPRINT1("CSRSS: Can't impersonate client thread - Status = %lx\n", Status);
- if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint();
-*/
- return FALSE;
- }
-
- /* Increase the impersonation count for the current thread */
- if (CurrentThread) ++CurrentThread->ImpersonationCount;
-
- /* Return Success */
- return TRUE;
-}
+ /* CSR does not handle debugging anymore */
+ DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
+ return STATUS_UNSUCCESSFUL;
+}
/*++
- * @name CsrRevertToSelf
+ * @name CsrDebugProcessStop
* @implemented NT4
*
- * The CsrRevertToSelf routine will attempt to remove an active impersonation.
+ * The CsrDebugProcessStop routine is deprecated in NT 5.1 and higher. It is
+ * exported only for compatibility with older CSR Server DLLs.
*
- * @param None.
+ * @param CsrProcess
+ * Deprecated.
*
- * @return TRUE if the reversion was succesful, false otherwise.
+ * @return Deprecated
*
- * @remarks Impersonation can be recursive; as such, the impersonation token
- * will only be deleted once the CSR Thread's impersonaton count
- * has reached zero.
+ * @remarks Deprecated.
*
*--*/
-BOOLEAN
+NTSTATUS
NTAPI
-CsrRevertToSelf(VOID)
+CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess)
{
- NTSTATUS Status;
- PCSR_THREAD CurrentThread = CsrGetClientThread();
- HANDLE ImpersonationToken = NULL;
-
- /* Check if we have a Current Thread */
- if (CurrentThread)
- {
- /* Make sure impersonation is on */
- if (!CurrentThread->ImpersonationCount)
- {
- // DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n");
- // DbgBreakPoint();
- return FALSE;
- }
- else if (--CurrentThread->ImpersonationCount > 0)
- {
- /* Success; impersonation count decreased but still not zero */
- return TRUE;
- }
- }
-
- /* Impersonation has been totally removed, revert to ourselves */
- Status = NtSetInformationThread(NtCurrentThread(),
- ThreadImpersonationToken,
- &ImpersonationToken,
- sizeof(HANDLE));
-
- /* Return TRUE or FALSE */
- return NT_SUCCESS(Status);
+ /* CSR does not handle debugging anymore */
+ DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
+ return STATUS_UNSUCCESSFUL;
}
/*++
/* Get the current thread entry */
CsrThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
+ /* Move to the next entry */
+ NextEntry = NextEntry->Flink;
+
/* Make sure the thread isn't already dead */
if (CsrThread->Flags & CsrThreadTerminated)
{
- NextEntry = NextEntry->Flink;
+ /* Go the the next thread */
continue;
}
/* Dereference the thread */
CsrLockedDereferenceThread(CsrThread);
- NextEntry = CsrProcess->ThreadList.Flink;
}
/* Release the Process Lock and return success */
}
/*++
- * @name CsrCreateProcess
+ * @name CsrGetProcessLuid
* @implemented NT4
*
* Do nothing for 500ms.
*
- * @param ArgumentCount
- * Description of the parameter. Wrapped to more lines on ~70th
- * column.
+ * @param hProcess
+ * Optional handle to the process whose LUID should be returned.
*
- * @param Arguments
- * Description of the parameter. Wrapped to more lines on ~70th
- * column.
+ * @param Luid
+ * Pointer to a LUID Pointer which will receive the CSR Process' LUID
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* otherwise.
*
- * @remarks None.
+ * @remarks If hProcess is not supplied, then the current thread's token will
+ * be used. If that too is missing, then the current process' token
+ * will be used.
*
*--*/
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)
+CsrGetProcessLuid(IN HANDLE hProcess OPTIONAL,
+ OUT PLUID Luid)
{
- PCSR_THREAD CurrentThread = CsrGetClientThread();
- CLIENT_ID CurrentCid;
- PCSR_PROCESS CurrentProcess;
- PVOID ProcessData;
- ULONG i;
- PCSR_PROCESS CsrProcess;
+ HANDLE hToken = NULL;
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;
- }
+ ULONG Length;
+ PTOKEN_STATISTICS TokenStats;
- /* Allocate a new Process Object */
- CsrProcess = CsrAllocateProcess();
- if (!CsrProcess)
+ /* Check if we have a handle to a CSR Process */
+ if (!hProcess)
{
- /* Couldn't allocate Process */
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
+ /* We don't, so try opening the Thread's Token */
+ Status = NtOpenThreadToken(NtCurrentThread(),
+ TOKEN_QUERY,
+ FALSE,
+ &hToken);
- /* Inherit the Process Data */
- CurrentProcess = CurrentThread->Process;
- ProcessData = &CurrentProcess->ServerData[CSR_SERVER_DLL_MAX];
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
- {
- /* Check if the DLL is Loaded and has Per Process Data */
- if ((CsrLoadedServerDll[i]) && (CsrLoadedServerDll[i]->SizeOfProcessData))
+ /* Check for success */
+ if (!NT_SUCCESS(Status))
{
- /* Set the pointer */
- CsrProcess->ServerData[i] = ProcessData;
-
- /* Copy the Data */
- RtlMoveMemory(ProcessData,
- CurrentProcess->ServerData[i],
- CsrLoadedServerDll[i]->SizeOfProcessData);
+ /* If we got some other failure, then return and quit */
+ if (Status != STATUS_NO_TOKEN) return Status;
- /* Update next data pointer */
- ProcessData = (PVOID)((ULONG_PTR)ProcessData +
- CsrLoadedServerDll[i]->SizeOfProcessData);
- }
- else
- {
- /* No data for this Server */
- CsrProcess->ServerData[i] = NULL;
+ /* We don't have a Thread Token, use a Process Token */
+ hProcess = NtCurrentProcess();
+ hToken = NULL;
}
}
- /* Set the Exception port for us */
- Status = NtSetInformationProcess(hProcess,
- ProcessExceptionPort,
- &CsrApiPort,
- sizeof(HANDLE));
- if (!NT_SUCCESS(Status))
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
-
- /* Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
- if (!(Flags & CsrProcessCreateNewGroup))
- {
- /* Create new data */
- CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess);
- CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber;
- }
- else
- {
- /* Copy it 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)
+ /* Check if we have a token by now */
+ if (!hToken)
{
- /* Set the Debug Port for us */
- Status = NtSetInformationProcess(hProcess,
- ProcessDebugPort,
- &CsrApiPort,
- sizeof(HANDLE));
- ASSERT(NT_SUCCESS(Status));
+ /* No token yet, so open the Process Token */
+ Status = NtOpenProcessToken(hProcess,
+ TOKEN_QUERY,
+ &hToken);
if (!NT_SUCCESS(Status))
{
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
+ /* Still no token, return the error */
+ return Status;
}
}
- /* Get the Thread Create Time */
- Status = NtQueryInformationThread(hThread,
- ThreadTimes,
- (PVOID)&KernelTimes,
- sizeof(KernelTimes),
- NULL);
- if (!NT_SUCCESS(Status))
- {
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
- return STATUS_NO_MEMORY;
- }
+ /* Now get the size we'll need for the Token Information */
+ Status = NtQueryInformationToken(hToken,
+ TokenStatistics,
+ NULL,
+ 0,
+ &Length);
- /* Allocate a CSR Thread Structure */
- CsrThread = CsrAllocateThread(CsrProcess);
- if (!CsrThread)
+ /* Allocate memory for the Token Info */
+ if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length)))
{
- /* Failed */
- CsrDeallocateProcess(CsrProcess);
- CsrReleaseProcessLock();
+ /* Fail and close the token */
+ NtClose(hToken);
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 */
- CsrInsertThread(CsrProcess, CsrThread);
-
- /* Reference the session */
- CsrReferenceNtSession(NtSession);
- CsrProcess->NtSession = NtSession;
+ /* Now query the information */
+ Status = NtQueryInformationToken(hToken,
+ TokenStatistics,
+ TokenStats,
+ Length,
+ &Length);
- /* Setup Process Data */
- CsrProcess->ClientId = *ClientId;
- CsrProcess->ProcessHandle = hProcess;
- CsrProcess->ShutdownLevel = 0x280;
+ /* Close the handle */
+ NtClose(hToken);
- /* Set the Priority to Background */
- CsrSetBackgroundPriority(CsrProcess);
+ /* Check for success */
+ if (NT_SUCCESS(Status))
+ {
+ /* Return the LUID */
+ *Luid = TokenStats->AuthenticationId;
+ }
- /* Insert the Process */
- CsrInsertProcess(NULL, CurrentProcess, CsrProcess);
+ /* Free the query information */
+ RtlFreeHeap(CsrHeap, 0, TokenStats);
- /* Release lock and return */
- CsrReleaseProcessLock();
+ /* Return the Status */
return Status;
}
/*++
- * @name CsrUnlockProcess
- * @implemented NT4
- *
- * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation.
- *
- * @param CsrProcess
- * Pointer to a previously locked CSR Process.
- *
- * @return STATUS_SUCCESS.
- *
- * @remarks This routine must be called with the Process Lock held.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
-{
- /* Dereference the process */
- CsrLockedDereferenceProcess(CsrProcess);
-
- /* Release the lock and return */
- CsrReleaseProcessLock();
- return STATUS_SUCCESS;
-}
-
-/*++
- * @name CsrSetBackgroundPriority
+ * @name CsrImpersonateClient
* @implemented NT4
*
- * The CsrSetBackgroundPriority routine sets the priority for the given CSR
- * Process as a Background priority.
+ * The CsrImpersonateClient will impersonate the given CSR Thread.
*
- * @param CsrProcess
- * Pointer to the CSR Process whose priority will be modified.
+ * @param CsrThread
+ * Pointer to the CSR Thread to impersonate.
*
- * @return None.
+ * @return TRUE if impersonation succeeded, false otherwise.
*
- * @remarks None.
+ * @remarks Impersonation can be recursive.
*
*--*/
-VOID
+BOOLEAN
NTAPI
-CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess)
+CsrImpersonateClient(IN PCSR_THREAD CsrThread)
{
- PROCESS_PRIORITY_CLASS PriorityClass;
+ NTSTATUS Status;
+ PCSR_THREAD CurrentThread = CsrGetClientThread();
- /* Set the Foreground bit off */
- PriorityClass.Foreground = FALSE;
+ /* Use the current thread if none given */
+ if (!CsrThread) CsrThread = CurrentThread;
- /* Set the new Priority */
- NtSetInformationProcess(CsrProcess->ProcessHandle,
- ProcessPriorityClass,
- &PriorityClass,
- sizeof(PriorityClass));
+ /* Still no thread, something is wrong */
+ if (!CsrThread)
+ {
+ /* Failure */
+ return FALSE;
+ }
+
+ /* Make the call */
+ Status = NtImpersonateThread(NtCurrentThread(),
+ CsrThread->ThreadHandle,
+ &CsrSecurityQos);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failure */
+/*
+ DPRINT1("CSRSS: Can't impersonate client thread - Status = %lx\n", Status);
+ if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint();
+*/
+ return FALSE;
+ }
+
+ /* Increase the impersonation count for the current thread */
+ if (CurrentThread) ++CurrentThread->ImpersonationCount;
+
+ /* Return Success */
+ return TRUE;
}
/*++
{
PLIST_ENTRY NextEntry;
PCSR_PROCESS CurrentProcess = NULL;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
/* Acquire the lock */
CsrAcquireProcessLock();
break;
}
- /* Next entry */
+ /* Move to the next entry */
NextEntry = NextEntry->Flink;
} while (NextEntry != &CsrRootProcess->ListLink);
CsrLockedReferenceProcess(CurrentProcess);
*CsrProcess = CurrentProcess;
}
-
+
/* Return the result */
return Status;
}
+/*++
+ * @name CsrRevertToSelf
+ * @implemented NT4
+ *
+ * The CsrRevertToSelf routine will attempt to remove an active impersonation.
+ *
+ * @param None.
+ *
+ * @return TRUE if the reversion was succesful, false otherwise.
+ *
+ * @remarks Impersonation can be recursive; as such, the impersonation token
+ * will only be deleted once the CSR Thread's impersonaton count
+ * has reached zero.
+ *
+ *--*/
+BOOLEAN
+NTAPI
+CsrRevertToSelf(VOID)
+{
+ NTSTATUS Status;
+ PCSR_THREAD CurrentThread = CsrGetClientThread();
+ HANDLE ImpersonationToken = NULL;
+
+ /* Check if we have a Current Thread */
+ if (CurrentThread)
+ {
+ /* Make sure impersonation is on */
+ if (!CurrentThread->ImpersonationCount)
+ {
+ // DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n");
+ // DbgBreakPoint();
+ return FALSE;
+ }
+ else if (--CurrentThread->ImpersonationCount > 0)
+ {
+ /* Success; impersonation count decreased but still not zero */
+ return TRUE;
+ }
+ }
+
+ /* Impersonation has been totally removed, revert to ourselves */
+ Status = NtSetInformationThread(NtCurrentThread(),
+ ThreadImpersonationToken,
+ &ImpersonationToken,
+ sizeof(HANDLE));
+
+ /* Return TRUE or FALSE */
+ return NT_SUCCESS(Status);
+}
+
+/*++
+ * @name CsrSetBackgroundPriority
+ * @implemented NT4
+ *
+ * The CsrSetBackgroundPriority routine sets the priority for the given CSR
+ * Process as a Background priority.
+ *
+ * @param CsrProcess
+ * Pointer to the CSR Process whose priority will be modified.
+ *
+ * @return None.
+ *
+ * @remarks None.
+ *
+ *--*/
+VOID
+NTAPI
+CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess)
+{
+ PROCESS_PRIORITY_CLASS PriorityClass;
+
+ /* Set the Foreground bit off */
+ PriorityClass.Foreground = FALSE;
+
+ /* Set the new Priority */
+ NtSetInformationProcess(CsrProcess->ProcessHandle,
+ ProcessPriorityClass,
+ &PriorityClass,
+ sizeof(PriorityClass));
+}
+
+/*++
+ * @name CsrSetForegroundPriority
+ * @implemented NT4
+ *
+ * The CsrSetForegroundPriority routine sets the priority for the given CSR
+ * Process as a Foreground priority.
+ *
+ * @param CsrProcess
+ * Pointer to the CSR Process whose priority will be modified.
+ *
+ * @return None.
+ *
+ * @remarks None.
+ *
+ *--*/
+VOID
+NTAPI
+CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess)
+{
+ PROCESS_PRIORITY_CLASS PriorityClass;
+
+ /* Set the Foreground bit on */
+ PriorityClass.Foreground = TRUE;
+
+ /* Set the new Priority */
+ NtSetInformationProcess(CsrProcess->ProcessHandle,
+ ProcessPriorityClass,
+ &PriorityClass,
+ sizeof(PriorityClass));
+}
+
/*++
* @name CsrShutdownProcesses
* @implemented NT4
/* Get the Process */
CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
- /* Remove the skip flag, set shutdown flags to 0*/
+ /* Move to the next entry */
+ NextEntry = NextEntry->Flink;
+
+ /* Remove the skip flag, set shutdown flags to 0 */
CsrProcess->Flags &= ~CsrProcessSkipShutdown;
CsrProcess->ShutdownFlags = 0;
-
- /* Move to the next */
- NextEntry = NextEntry->Flink;
}
/* Set shudown Priority */
- CsrpSetToShutdownPriority();
+ CsrSetToShutdownPriority();
/* Start looping */
while (TRUE)
if (!CsrProcess) break;
/* Increase reference to process */
- CsrProcess->ReferenceCount++;
+ CsrLockedReferenceProcess(CsrProcess);
FirstTry = TRUE;
while (TRUE)
{
/* Get the current server */
ServerDll = CsrLoadedServerDll[i];
- if ((ServerDll) && (ServerDll->ShutdownProcessCallback))
+
+ /* Check if it's valid and if it has a Shutdown Process Callback */
+ if (ServerDll && ServerDll->ShutdownProcessCallback)
{
/* Release the lock, make the callback, and acquire it back */
CsrReleaseProcessLock();
Quickie:
/* Return to normal priority */
- CsrpSetToNormalPriority();
+ CsrSetToNormalPriority();
+
return Status;
}
-/* FIXME: Temporary hack. This is really "CsrShutdownProcess", mostly. Used by win32csr */
+/* FIXME: Temporary hack. This is really "CsrShutdownProcess", mostly. Used by winsrv */
+#if 0
NTSTATUS
WINAPI
CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc,
/* Get the Process */
CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
- /* Remove the skip flag, set shutdown flags to 0*/
+ /* Move to the next entry */
+ NextEntry = NextEntry->Flink;
+
+ /* Remove the skip flag, set shutdown flags to 0 */
CsrProcess->Flags &= ~CsrProcessSkipShutdown;
CsrProcess->ShutdownFlags = 0;
-
- /* Move to the next */
- NextEntry = NextEntry->Flink;
}
/* Set shudown Priority */
CsrSetToNormalPriority();
return Status;
}
+#endif
/*++
- * @name CsrDebugProcess
- * @implemented NT4
- *
- * The CsrDebugProcess routine is deprecated in NT 5.1 and higher. It is
- * exported only for compatibility with older CSR Server DLLs.
- *
- * @param CsrProcess
- * Deprecated.
- *
- * @return Deprecated
- *
- * @remarks Deprecated.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrDebugProcess(IN PCSR_PROCESS CsrProcess)
-{
- /* CSR does not handle debugging anymore */
- DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
- return STATUS_UNSUCCESSFUL;
-}
-
-/*++
- * @name CsrDebugProcessStop
+ * @name CsrUnlockProcess
* @implemented NT4
*
- * The CsrDebugProcessStop routine is deprecated in NT 5.1 and higher. It is
- * exported only for compatibility with older CSR Server DLLs.
+ * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation.
*
* @param CsrProcess
- * Deprecated.
+ * Pointer to a previously locked CSR Process.
*
- * @return Deprecated
+ * @return STATUS_SUCCESS.
*
- * @remarks Deprecated.
+ * @remarks This routine must be called with the Process Lock held.
*
*--*/
NTSTATUS
NTAPI
-CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess)
-{
- /* CSR does not handle debugging anymore */
- DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
- return STATUS_UNSUCCESSFUL;
-}
-
-/*++
- * @name CsrSetForegroundPriority
- * @implemented NT4
- *
- * The CsrSetForegroundPriority routine sets the priority for the given CSR
- * Process as a Foreground priority.
- *
- * @param CsrProcess
- * Pointer to the CSR Process whose priority will be modified.
- *
- * @return None.
- *
- * @remarks None.
- *
- *--*/
-VOID
-NTAPI
-CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess)
+CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
{
- PROCESS_PRIORITY_CLASS PriorityClass;
-
- /* Set the Foreground bit on */
- PriorityClass.Foreground = TRUE;
+ /* Dereference the process */
+ CsrLockedDereferenceProcess(CsrProcess);
- /* Set the new Priority */
- NtSetInformationProcess(CsrProcess->ProcessHandle,
- ProcessPriorityClass,
- &PriorityClass,
- sizeof(PriorityClass));
+ /* Release the lock and return */
+ CsrReleaseProcessLock();
+ return STATUS_SUCCESS;
}
/* EOF */