2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS CSR Sub System
4 * FILE: subsystems/win32/csrss/csrsrv/procsup.c
5 * PURPOSE: CSR Process Management
6 * PROGRAMMERS: ReactOS Portable Systems Group
10 /* INCLUDES *******************************************************************/
17 /* GLOBALS ********************************************************************/
19 RTL_CRITICAL_SECTION ProcessDataLock
;
20 PCSR_PROCESS CsrRootProcess
;
21 SECURITY_QUALITY_OF_SERVICE CsrSecurityQos
=
23 sizeof(SECURITY_QUALITY_OF_SERVICE
),
24 SecurityImpersonation
,
25 SECURITY_STATIC_TRACKING
,
28 LONG CsrProcessSequenceCount
= 5;
29 extern ULONG CsrTotalPerProcessDataLength
;
31 /* FUNCTIONS ******************************************************************/
35 CsrSetToNormalPriority(VOID
)
37 KPRIORITY BasePriority
= (8 + 1) + 4;
39 /* Set the Priority */
40 NtSetInformationProcess(NtCurrentProcess(),
48 CsrSetToShutdownPriority(VOID
)
50 KPRIORITY SetBasePriority
= (8 + 1) + 6;
53 /* Get the shutdown privilege */
54 if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
,
59 /* Set the Priority */
60 NtSetInformationProcess(NtCurrentProcess(),
69 CsrGetProcessLuid(HANDLE hProcess OPTIONAL
,
75 PTOKEN_STATISTICS TokenStats
;
77 /* Check if we have a handle to a CSR Process */
80 /* We don't, so try opening the Thread's Token */
81 Status
= NtOpenThreadToken(NtCurrentThread(),
86 /* Check for success */
87 if (!NT_SUCCESS(Status
))
89 /* If we got some other failure, then return and quit */
90 if (Status
!= STATUS_NO_TOKEN
) return Status
;
92 /* We don't have a Thread Token, use a Process Token */
93 hProcess
= NtCurrentProcess();
98 /* Check if we have a token by now */
101 /* No token yet, so open the Process Token */
102 Status
= NtOpenProcessToken(hProcess
,
105 if (!NT_SUCCESS(Status
))
107 /* Still no token, return the error */
112 /* Now get the size we'll need for the Token Information */
113 Status
= NtQueryInformationToken(hToken
,
119 /* Allocate memory for the Token Info */
120 if (!(TokenStats
= RtlAllocateHeap(CsrHeap
, 0, Length
)))
122 /* Fail and close the token */
124 return STATUS_NO_MEMORY
;
127 /* Now query the information */
128 Status
= NtQueryInformationToken(hToken
,
134 /* Close the handle */
137 /* Check for success */
138 if (NT_SUCCESS(Status
))
140 /* Return the LUID */
141 *Luid
= TokenStats
->AuthenticationId
;
144 /* Free the query information */
145 RtlFreeHeap(CsrHeap
, 0, TokenStats
);
147 /* Return the Status */
153 CsrImpersonateClient(IN PCSR_THREAD CsrThread
)
156 PCSR_THREAD CurrentThread
= NtCurrentTeb()->CsrClientThread
;
158 /* Use the current thread if none given */
159 if (!CsrThread
) CsrThread
= CurrentThread
;
161 /* Still no thread, something is wrong */
169 Status
= NtImpersonateThread(NtCurrentThread(),
170 CsrThread
->ThreadHandle
,
173 if (!NT_SUCCESS(Status
))
179 /* Increase the impersonation count for the current thread */
180 if (CurrentThread
) ++CurrentThread
->ImpersonationCount
;
188 CsrRevertToSelf(VOID
)
191 PCSR_THREAD CurrentThread
= NtCurrentTeb()->CsrClientThread
;
192 HANDLE ImpersonationToken
= NULL
;
194 /* Check if we have a Current Thread */
197 /* Make sure impersonation is on */
198 if (!CurrentThread
->ImpersonationCount
)
202 else if (--CurrentThread
->ImpersonationCount
> 0)
204 /* Success; impersonation count decreased but still not zero */
209 /* Impersonation has been totally removed, revert to ourselves */
210 Status
= NtSetInformationThread(NtCurrentThread(),
211 ThreadImpersonationToken
,
215 /* Return TRUE or FALSE */
216 return NT_SUCCESS(Status
);
221 FindProcessForShutdown(IN PLUID CallerLuid
)
223 PCSR_PROCESS CsrProcess
, ReturnCsrProcess
= NULL
;
227 LUID SystemLuid
= SYSTEM_LUID
;
228 BOOLEAN IsSystemLuid
= FALSE
, IsOurLuid
= FALSE
;
229 PLIST_ENTRY NextEntry
;
231 /* Set the List Pointers */
232 NextEntry
= CsrRootProcess
->ListLink
.Flink
;
233 while (NextEntry
!= &CsrRootProcess
->ListLink
)
235 /* Get the process */
236 CsrProcess
= CONTAINING_RECORD(NextEntry
, CSR_PROCESS
, ListLink
);
238 /* Move to the next entry */
239 NextEntry
= NextEntry
->Flink
;
241 /* Skip this process if it's already been processed */
242 if (CsrProcess
->Flags
& CsrProcessSkipShutdown
) continue;
244 /* Get the LUID of this Process */
245 Status
= CsrGetProcessLuid(CsrProcess
->ProcessHandle
, &ProcessLuid
);
247 /* Check if we didn't get access to the LUID */
248 if (Status
== STATUS_ACCESS_DENIED
)
250 /* FIXME:Check if we have any threads */
253 if (!NT_SUCCESS(Status
))
255 /* We didn't have access, so skip it */
256 CsrProcess
->Flags
|= CsrProcessSkipShutdown
;
260 /* Check if this is the System LUID */
261 if ((IsSystemLuid
= RtlEqualLuid(&ProcessLuid
, &SystemLuid
)))
263 /* Mark this process */
264 CsrProcess
->ShutdownFlags
|= CsrShutdownSystem
;
266 else if (!(IsOurLuid
= RtlEqualLuid(&ProcessLuid
, CallerLuid
)))
268 /* Our LUID doesn't match with the caller's */
269 CsrProcess
->ShutdownFlags
|= CsrShutdownOther
;
272 /* Check if we're past the previous level */
273 if (CsrProcess
->ShutdownLevel
> Level
)
275 /* Update the level */
276 Level
= CsrProcess
->ShutdownLevel
;
278 /* Set the final process */
279 ReturnCsrProcess
= CsrProcess
;
283 /* Check if we found a process */
284 if (ReturnCsrProcess
)
286 /* Skip this one next time */
287 ReturnCsrProcess
->Flags
|= CsrProcessSkipShutdown
;
290 return ReturnCsrProcess
;
293 /* This is really "CsrShutdownProcess", mostly */
296 CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc
,
299 PVOID
* RealContext
= (PVOID
*)Context
;
300 PLUID CallerLuid
= RealContext
[0];
301 PCSR_PROCESS CsrProcess
= NULL
;
302 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
304 PLIST_ENTRY NextEntry
;
307 /* Acquire process lock */
308 CsrAcquireProcessLock();
310 /* Get the list pointers */
311 NextEntry
= CsrRootProcess
->ListLink
.Flink
;
312 while (NextEntry
!= &CsrRootProcess
->ListLink
)
314 /* Get the Process */
315 CsrProcess
= CONTAINING_RECORD(NextEntry
, CSR_PROCESS
, ListLink
);
317 /* Remove the skip flag, set shutdown flags to 0*/
318 CsrProcess
->Flags
&= ~CsrProcessSkipShutdown
;
319 CsrProcess
->ShutdownFlags
= 0;
321 /* Move to the next */
322 NextEntry
= NextEntry
->Flink
;
325 /* Set shudown Priority */
326 CsrSetToShutdownPriority();
328 /* Loop all processes */
329 //DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart);
334 /* Find the next process to shutdown */
336 if (!(CsrProcess
= FindProcessForShutdown(CallerLuid
)))
339 CsrReleaseProcessLock();
340 Status
= STATUS_SUCCESS
;
345 /* Release the lock, make the callback, and acquire it back */
346 //DPRINT1("Found process: %lx\n", CsrProcess->ClientId.UniqueProcess);
347 CsrReleaseProcessLock();
348 Result
= (ULONG
)EnumProc(CsrProcess
, (PVOID
)((ULONG_PTR
)Context
| FirstTry
));
349 CsrAcquireProcessLock();
351 /* Check the result */
352 //DPRINT1("Result: %d\n", Result);
353 if (Result
== CsrShutdownCsrProcess
)
355 /* The callback unlocked the process */
358 else if (Result
== CsrShutdownNonCsrProcess
)
360 /* A non-CSR process, the callback didn't touch it */
363 else if (Result
== CsrShutdownCancelled
)
365 /* Shutdown was cancelled, unlock and exit */
366 CsrReleaseProcessLock();
367 Status
= STATUS_CANCELLED
;
371 /* No matches during the first try, so loop again */
372 if (FirstTry
&& Result
== CsrShutdownNonCsrProcess
)
380 /* Return to normal priority */
381 CsrSetToNormalPriority();
386 * @name CsrProcessRefcountZero
388 * The CsrProcessRefcountZero routine is executed when a CSR Process has lost
389 * all its active references. It removes and de-allocates the CSR Process.
392 * Pointer to the CSR Process that is to be deleted.
396 * @remarks Do not call this routine. It is reserved for the internal
397 * thread management routines when a CSR Process has lost all
400 * This routine is called with the Process Lock held.
405 CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess
)
407 ASSERT(ProcessStructureListLocked());
409 /* Remove the Process from the list */
410 CsrRemoveProcess(CsrProcess
);
412 /* Check if there's a session */
413 if (CsrProcess
->NtSession
)
415 /* Dereference the Session */
416 CsrDereferenceNtSession(CsrProcess
->NtSession
, 0);
419 /* Close the Client Port if there is one */
420 if (CsrProcess
->ClientPort
) NtClose(CsrProcess
->ClientPort
);
422 /* Close the process handle */
423 NtClose(CsrProcess
->ProcessHandle
);
425 /* Free the Proces Object */
426 CsrDeallocateProcess(CsrProcess
);
430 * @name CsrLockedDereferenceProcess
432 * The CsrLockedDereferenceProcess dereferences a CSR Process while the
433 * Process Lock is already being held.
436 * Pointer to the CSR Process to be dereferenced.
440 * @remarks This routine will return with the Process Lock held.
445 CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess
)
449 /* Decrease reference count */
450 LockCount
= --CsrProcess
->ReferenceCount
;
451 ASSERT(LockCount
>= 0);
454 /* Call the generic cleanup code */
455 DPRINT1("Should kill process: %p\n", CsrProcess
);
456 CsrProcessRefcountZero(CsrProcess
);
457 CsrAcquireProcessLock();
462 * @name CsrDereferenceProcess
465 * The CsrDereferenceProcess routine removes a reference from a CSR Process.
468 * Pointer to the CSR Process to dereference.
472 * @remarks If the reference count has reached zero (ie: the CSR Process has
473 * no more active references), it will be deleted.
478 CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess
)
482 /* Acquire process lock */
483 CsrAcquireProcessLock();
485 /* Decrease reference count */
486 LockCount
= --CsrProcess
->ReferenceCount
;
487 ASSERT(LockCount
>= 0);
490 /* Call the generic cleanup code */
491 CsrProcessRefcountZero(CsrProcess
);
495 /* Just release the lock */
496 CsrReleaseProcessLock();
501 * @name CsrDestroyProcess
504 * The CsrDestroyProcess routine destroys the CSR Process corresponding to
508 * Pointer to the Client ID Structure corresponding to the CSR
509 * Process which is about to be destroyed.
514 * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
515 * if the CSR Process is already terminating.
522 CsrDestroyProcess(IN PCLIENT_ID Cid
,
523 IN NTSTATUS ExitStatus
)
525 PCSR_THREAD CsrThread
;
526 PCSR_PROCESS CsrProcess
;
527 CLIENT_ID ClientId
= *Cid
;
528 PLIST_ENTRY NextEntry
;
531 CsrAcquireProcessLock();
533 /* Find the thread */
534 CsrThread
= CsrLocateThreadByClientId(&CsrProcess
, &ClientId
);
536 /* Make sure we got one back, and that it's not already gone */
537 if (!(CsrThread
) || (CsrProcess
->Flags
& CsrProcessTerminating
))
539 /* Release the lock and return failure */
540 CsrReleaseProcessLock();
541 return STATUS_THREAD_IS_TERMINATING
;
544 /* Set the terminated flag */
545 CsrProcess
->Flags
|= CsrProcessTerminating
;
547 /* Get the List Pointers */
548 NextEntry
= CsrProcess
->ThreadList
.Flink
;
549 while (NextEntry
!= &CsrProcess
->ThreadList
)
551 /* Get the current thread entry */
552 CsrThread
= CONTAINING_RECORD(NextEntry
, CSR_THREAD
, Link
);
554 /* Make sure the thread isn't already dead */
555 if (CsrThread
->Flags
& CsrThreadTerminated
)
557 NextEntry
= NextEntry
->Flink
;
561 /* Set the Terminated flag */
562 CsrThread
->Flags
|= CsrThreadTerminated
;
564 /* Acquire the Wait Lock */
565 CsrAcquireWaitLock();
567 /* Do we have an active wait block? */
568 if (CsrThread
->WaitBlock
)
570 /* Notify waiters of termination */
571 CsrNotifyWaitBlock(CsrThread
->WaitBlock
,
575 CsrProcessTerminating
,
579 /* Release the Wait Lock */
580 CsrReleaseWaitLock();
582 /* Dereference the thread */
583 CsrLockedDereferenceThread(CsrThread
);
584 NextEntry
= CsrProcess
->ThreadList
.Flink
;
587 /* Release the Process Lock and return success */
588 CsrReleaseProcessLock();
589 return STATUS_SUCCESS
;
593 * @name CsrCreateProcess
596 * Do nothing for 500ms.
598 * @param ArgumentCount
599 * Description of the parameter. Wrapped to more lines on ~70th
603 * Description of the parameter. Wrapped to more lines on ~70th
606 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
614 CsrCreateProcess(IN HANDLE hProcess
,
616 IN PCLIENT_ID ClientId
,
617 IN PCSR_NT_SESSION NtSession
,
619 IN PCLIENT_ID DebugCid
)
621 PCSR_THREAD CurrentThread
= NtCurrentTeb()->CsrClientThread
;
622 CLIENT_ID CurrentCid
;
623 PCSR_PROCESS CurrentProcess
;
624 // PVOID ProcessData;
626 PCSR_PROCESS CsrProcess
;
628 PCSR_THREAD CsrThread
;
629 KERNEL_USER_TIMES KernelTimes
;
631 /* Get the current CID and lock Processes */
632 CurrentCid
= CurrentThread
->ClientId
;
633 CsrAcquireProcessLock();
635 /* Get the current CSR Thread */
636 CurrentThread
= CsrLocateThreadByClientId(&CurrentProcess
, &CurrentCid
);
639 /* We've failed to locate the thread */
640 CsrReleaseProcessLock();
641 return STATUS_THREAD_IS_TERMINATING
;
644 /* Allocate a new Process Object */
645 CsrProcess
= CsrAllocateProcess();
648 /* Couldn't allocate Process */
649 CsrReleaseProcessLock();
650 return STATUS_NO_MEMORY
;
654 /* Inherit the Process Data */
655 CurrentProcess
= CurrentThread
->Process
;
656 ProcessData
= &CurrentProcess
->ServerData
[CSR_SERVER_DLL_MAX
];
657 for (i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
659 /* Check if the DLL is Loaded and has Per Process Data */
660 if ((CsrLoadedServerDll
[i
]) && (CsrLoadedServerDll
[i
]->SizeOfProcessData
))
662 /* Set the pointer */
663 CsrProcess
->ServerData
[i
] = ProcessData
;
666 RtlMoveMemory(ProcessData
,
667 CurrentProcess
->ServerData
[i
],
668 CsrLoadedServerDll
[i
]->SizeOfProcessData
);
670 /* Update next data pointer */
671 ProcessData
= (PVOID
)((ULONG_PTR
)ProcessData
+
672 CsrLoadedServerDll
[i
]->SizeOfProcessData
);
676 /* No data for this Server */
677 CsrProcess
->ServerData
[i
] = NULL
;
682 /* Set the Exception port to us */
683 Status
= NtSetInformationProcess(hProcess
,
684 ProcessExceptionPort
,
687 if (!NT_SUCCESS(Status
))
690 CsrDeallocateProcess(CsrProcess
);
691 CsrReleaseProcessLock();
692 return STATUS_NO_MEMORY
;
695 /* If Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
696 if (!(Flags
& CsrProcessCreateNewGroup
))
698 /* Create new data */
699 CsrProcess
->ProcessGroupId
= HandleToUlong(ClientId
->UniqueProcess
);
700 CsrProcess
->ProcessGroupSequence
= CsrProcess
->SequenceNumber
;
704 /* Copy it from the current process */
705 CsrProcess
->ProcessGroupId
= CurrentProcess
->ProcessGroupId
;
706 CsrProcess
->ProcessGroupSequence
= CurrentProcess
->ProcessGroupSequence
;
709 /* Check if this is a console process */
710 if (Flags
& CsrProcessIsConsoleApp
) CsrProcess
->Flags
|= CsrProcessIsConsoleApp
;
712 /* Mask out non-debug flags */
713 Flags
&= ~(CsrProcessIsConsoleApp
| CsrProcessCreateNewGroup
| CsrProcessPriorityFlags
);
715 /* Check if every process will be debugged */
716 if (!(Flags
) && (CurrentProcess
->DebugFlags
& CsrDebugProcessChildren
))
718 /* Pass it on to the current process */
719 CsrProcess
->DebugFlags
= CsrDebugProcessChildren
;
720 CsrProcess
->DebugCid
= CurrentProcess
->DebugCid
;
723 /* Check if Debugging was used on this process */
724 if ((Flags
& (CsrDebugOnlyThisProcess
| CsrDebugProcessChildren
)) && (DebugCid
))
726 /* Save the debug flag used */
727 CsrProcess
->DebugFlags
= Flags
;
730 CsrProcess
->DebugCid
= *DebugCid
;
733 /* Check if we debugging is enabled */
734 if (CsrProcess
->DebugFlags
)
736 /* Set the Debug Port to us */
737 Status
= NtSetInformationProcess(hProcess
,
741 ASSERT(NT_SUCCESS(Status
));
742 if (!NT_SUCCESS(Status
))
745 CsrDeallocateProcess(CsrProcess
);
746 CsrReleaseProcessLock();
747 return STATUS_NO_MEMORY
;
751 /* Get the Thread Create Time */
752 Status
= NtQueryInformationThread(hThread
,
757 if (!NT_SUCCESS(Status
))
760 CsrDeallocateProcess(CsrProcess
);
761 CsrReleaseProcessLock();
762 return STATUS_NO_MEMORY
;
765 /* Allocate a CSR Thread Structure */
766 CsrThread
= CsrAllocateThread(CsrProcess
);
770 CsrDeallocateProcess(CsrProcess
);
771 CsrReleaseProcessLock();
772 return STATUS_NO_MEMORY
;
775 /* Save the data we have */
776 CsrThread
->CreateTime
= KernelTimes
.CreateTime
;
777 CsrThread
->ClientId
= *ClientId
;
778 CsrThread
->ThreadHandle
= hThread
;
779 ProtectHandle(hThread
);
780 CsrThread
->Flags
= 0;
782 /* Insert the Thread into the Process */
783 CsrInsertThread(CsrProcess
, CsrThread
);
785 /* Reference the session */
786 CsrReferenceNtSession(NtSession
);
787 CsrProcess
->NtSession
= NtSession
;
789 /* Setup Process Data */
790 CsrProcess
->ClientId
= *ClientId
;
791 CsrProcess
->ProcessHandle
= hProcess
;
792 CsrProcess
->ShutdownLevel
= 0x280;
794 /* Set the Priority to Background */
795 CsrSetBackgroundPriority(CsrProcess
);
797 /* Insert the Process */
798 CsrInsertProcess(NULL
, CurrentProcess
, CsrProcess
);
800 /* Release lock and return */
801 CsrReleaseProcessLock();
806 * @name CsrUnlockProcess
809 * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation.
812 * Pointer to a previously locked CSR Process.
814 * @return STATUS_SUCCESS.
816 * @remarks This routine must be called with the Process Lock held.
821 CsrUnlockProcess(IN PCSR_PROCESS CsrProcess
)
823 /* Dereference the process */
824 CsrLockedDereferenceProcess(CsrProcess
);
826 /* Release the lock and return */
827 CsrReleaseProcessLock();
828 return STATUS_SUCCESS
;
832 * @name CsrSetBackgroundPriority
835 * The CsrSetBackgroundPriority routine sets the priority for the given CSR
836 * Process as a Background priority.
839 * Pointer to the CSR Process whose priority will be modified.
848 CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess
)
850 PROCESS_PRIORITY_CLASS PriorityClass
;
852 /* Set the Foreground bit off */
853 PriorityClass
.Foreground
= FALSE
;
855 /* Set the new Priority */
856 NtSetInformationProcess(CsrProcess
->ProcessHandle
,
857 ProcessPriorityClass
,
859 sizeof(PriorityClass
));
863 * @name CsrAllocateProcess
866 * The CsrAllocateProcess routine allocates a new CSR Process object.
868 * @return Pointer to the newly allocated CSR Process.
875 CsrAllocateProcess(VOID
)
877 PCSR_PROCESS CsrProcess
;
880 /* Calculate the amount of memory this should take */
881 TotalSize
= sizeof(CSR_PROCESS
) +
882 (CSR_SERVER_DLL_MAX
* sizeof(PVOID
)) +
883 CsrTotalPerProcessDataLength
;
885 /* Allocate a Process */
886 CsrProcess
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, TotalSize
);
887 if (!CsrProcess
) return NULL
;
889 /* Handle the Sequence Number and protect against overflow */
890 CsrProcess
->SequenceNumber
= CsrProcessSequenceCount
++;
891 if (CsrProcessSequenceCount
< 5) CsrProcessSequenceCount
= 5;
893 /* Increase the reference count */
894 CsrProcess
->ReferenceCount
++;
896 /* Initialize the Thread List */
897 InitializeListHead(&CsrProcess
->ThreadList
);
899 /* Return the Process */
904 * @name CsrLockedReferenceProcess
906 * The CsrLockedReferenceProcess refences a CSR Process while the
907 * Process Lock is already being held.
910 * Pointer to the CSR Process to be referenced.
914 * @remarks This routine will return with the Process Lock held.
919 CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess
)
921 /* Increment the reference count */
922 ++CsrProcess
->ReferenceCount
;
926 * @name CsrServerInitialization
929 * The CsrInitializeProcessStructure routine sets up support for CSR Processes
934 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
942 CsrInitializeProcessStructure(VOID
)
947 /* Initialize the Lock */
948 Status
= RtlInitializeCriticalSection(&ProcessDataLock
);
949 if (!NT_SUCCESS(Status
)) return Status
;
951 /* Set up the Root Process */
952 CsrRootProcess
= CsrAllocateProcess();
953 if (!CsrRootProcess
) return STATUS_NO_MEMORY
;
955 /* Set up the minimal information for it */
956 InitializeListHead(&CsrRootProcess
->ListLink
);
957 CsrRootProcess
->ProcessHandle
= (HANDLE
)-1;
958 CsrRootProcess
->ClientId
= NtCurrentTeb()->ClientId
;
960 /* Initialize the Thread Hash List */
961 for (i
= 0; i
< 256; i
++) InitializeListHead(&CsrThreadHashTable
[i
]);
963 /* Initialize the Wait Lock */
964 return RtlInitializeCriticalSection(&CsrWaitListsLock
);
968 * @name CsrDeallocateProcess
970 * The CsrDeallocateProcess frees the memory associated with a CSR Process.
973 * Pointer to the CSR Process to be freed.
977 * @remarks Do not call this routine. It is reserved for the internal
978 * thread management routines when a CSR Process has been cleanly
979 * dereferenced and killed.
984 CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess
)
986 /* Free the process object from the heap */
987 RtlFreeHeap(CsrHeap
, 0, CsrProcess
);
991 * @name CsrRemoveProcess
993 * The CsrRemoveProcess function undoes a CsrInsertProcess operation and
994 * removes the CSR Process from the Process List and notifies Server DLLs
998 * Pointer to the CSR Process to remove.
1007 CsrRemoveProcess(IN PCSR_PROCESS CsrProcess
)
1009 PCSR_SERVER_DLL ServerDll
;
1011 ASSERT(ProcessStructureListLocked());
1013 /* Remove us from the Process List */
1014 RemoveEntryList(&CsrProcess
->ListLink
);
1016 /* Release the lock */
1017 CsrReleaseProcessLock();
1019 /* Loop every Server DLL */
1020 for (i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
1022 /* Get the Server DLL */
1023 ServerDll
= CsrLoadedServerDll
[i
];
1025 /* Check if it's valid and if it has a Disconnect Callback */
1026 if ((ServerDll
) && (ServerDll
->DisconnectCallback
))
1029 ServerDll
->DisconnectCallback(CsrProcess
);
1035 * @name CsrInsertProcess
1037 * The CsrInsertProcess routine inserts a CSR Process into the Process List
1038 * and notifies Server DLLs of the creation of a new CSR Process.
1041 * Optional pointer to the CSR Process creating this CSR Process.
1043 * @param CurrentProcess
1044 * Optional pointer to the current CSR Process.
1047 * Pointer to the CSR Process which is to be inserted.
1056 CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL
,
1057 IN PCSR_PROCESS CurrentProcess OPTIONAL
,
1058 IN PCSR_PROCESS CsrProcess
)
1061 PCSR_SERVER_DLL ServerDll
;
1064 ASSERT(ProcessStructureListLocked());
1066 /* Set the parent */
1067 CsrProcess
->Parent
= Parent
;
1069 /* Insert it into the Root List */
1070 InsertTailList(&CsrRootProcess
->ListLink
, &CsrProcess
->ListLink
);
1072 /* Notify the Server DLLs */
1073 for (i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
1075 /* Get the current Server DLL */
1076 ServerDll
= CsrLoadedServerDll
[i
];
1078 /* Make sure it's valid and that it has callback */
1079 if ((ServerDll
) && (ServerDll
->NewProcessCallback
))
1081 ServerDll
->NewProcessCallback(CurrentProcess
, CsrProcess
);
1088 * @name CsrLockProcessByClientId
1091 * The CsrLockProcessByClientId routine locks the CSR Process corresponding
1092 * to the given Process ID and optionally returns it.
1095 * Process ID corresponding to the CSR Process which will be locked.
1098 * Optional pointer to a CSR Process pointer which will hold the
1099 * CSR Process corresponding to the given Process ID.
1101 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
1104 * @remarks Locking a CSR Process is defined as acquiring an extra
1105 * reference to it and returning with the Process Lock held.
1110 CsrLockProcessByClientId(IN HANDLE Pid
,
1111 OUT PCSR_PROCESS
*CsrProcess
)
1113 PLIST_ENTRY NextEntry
;
1114 PCSR_PROCESS CurrentProcess
= NULL
;
1117 /* Acquire the lock */
1118 CsrAcquireProcessLock();
1120 /* Assume failure */
1121 ASSERT(CsrProcess
!= NULL
);
1124 /* Setup the List Pointers */
1125 NextEntry
= &CsrRootProcess
->ListLink
;
1128 /* Get the Process */
1129 CurrentProcess
= CONTAINING_RECORD(NextEntry
, CSR_PROCESS
, ListLink
);
1131 /* Check for PID Match */
1132 if (CurrentProcess
->ClientId
.UniqueProcess
== Pid
)
1134 Status
= STATUS_SUCCESS
;
1139 NextEntry
= NextEntry
->Flink
;
1140 } while (NextEntry
!= &CsrRootProcess
->ListLink
);
1142 /* Check if we didn't find it in the list */
1143 if (!NT_SUCCESS(Status
))
1145 /* Nothing found, release the lock */
1146 CsrReleaseProcessLock();
1150 /* Lock the found process and return it */
1151 CsrLockedReferenceProcess(CurrentProcess
);
1152 *CsrProcess
= CurrentProcess
;
1155 /* Return the result */