Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

procobj.c File Reference

#include "ki.h"

Go to the source code of this file.

Defines

#define ASSERT_PROCESS(E)

Functions

VOID KiAttachProcess (IN PRKTHREAD Thread, IN PRKPROCESS Process, IN KIRQL OldIrql, OUT PRKAPC_STATE SavedApcState)
VOID KiMoveApcState (IN PKAPC_STATE Source, OUT PKAPC_STATE Destination)
VOID KeInitializeProcess (IN PRKPROCESS Process, IN KPRIORITY BasePriority, IN KAFFINITY Affinity, IN ULONG_PTR DirectoryTableBase[2], IN BOOLEAN Enable)
VOID KeAttachProcess (IN PRKPROCESS Process)
LOGICAL KeForceAttachProcess (IN PRKPROCESS Process)
VOID KeStackAttachProcess (IN PRKPROCESS Process, OUT PRKAPC_STATE ApcState)
VOID KeDetachProcess (VOID)
VOID KeUnstackDetachProcess (IN PRKAPC_STATE ApcState)
LONG KeReadStateProcess (IN PRKPROCESS Process)
LONG KeSetProcess (IN PRKPROCESS Process, IN KPRIORITY Increment, IN BOOLEAN Wait)
KPRIORITY KeSetPriorityProcess (IN PKPROCESS Process, IN KPRIORITY NewBase)
LOGICAL KeSetDisableQuantumProcess (IN PKPROCESS Process, IN LOGICAL Disable)
VOID KiAttachProcess (IN PRKTHREAD Thread, IN PKPROCESS Process, IN KIRQL OldIrql, OUT PRKAPC_STATE SavedApcState)


Define Documentation

#define ASSERT_PROCESS  ) 
 

Value:

{ \ ASSERT((E)->Header.Type == ProcessObject); \ }

Definition at line 57 of file procobj.c.


Function Documentation

VOID KeAttachProcess IN PRKPROCESS  Process  ) 
 

Definition at line 166 of file procobj.c.

References _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, ASSERT, ASSERT_PROCESS, DISPATCH_LEVEL, FALSE, KeBugCheckEx(), KeGetCurrentThread, KiAttachProcess(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), _KAPC_STATE::Process, and _KTHREAD::SavedApcState.

Referenced by _GetComboBoxInfo(), _GetListBoxInfo(), CheckWHFBits(), MiCloneProcessAddressSpace(), MiDoMappedCopy(), MiDoPoolCopy(), MiEmptyAllWorkingSetsWorker(), MiGetWorkingSetInfo(), MiLoadImageSection(), MiLoadSystemImage(), MmAssignProcessToJob(), MmCreatePeb(), MmCreateTeb(), MmDeleteTeb(), MmFlushVirtualMemory(), MmInitializeProcessAddressSpace(), MmMapViewOfSection(), MmProbeAndLockProcessPages(), MmSetBankedSection(), MmSetMemoryPriorityProcess(), MmUnmapViewOfSection(), NtAllocateUserPhysicalPages(), NtAllocateVirtualMemory(), NtDuplicateObject(), NtFlushInstructionCache(), NtFreeUserPhysicalPages(), NtFreeVirtualMemory(), NtLockVirtualMemory(), NtProtectVirtualMemory(), NtQueryVirtualMemory(), NtSetInformationJobObject(), NtSetInformationProcess(), NtUnlockVirtualMemory(), PsAssignImpersonationToken(), PspAddProcessToJob(), PspCreateProcess(), PspSetQuotaLimits(), SepRmCallLsa(), SetProcessFlags(), SmbTraceCompleteRdr(), SmbTraceDisconnect(), SmbTraceStop(), xxxCheckImeShowStatus(), xxxCreateDisconnectDesktop(), xxxCreateWindowStation(), xxxGetThreadDesktop(), xxxImmActivateAndUnloadThreadsLayout(), xxxMinMaximize(), xxxNotifyImeShowStatus(), xxxSendMessageToUI(), and zzzSetWindowsHookEx().

00172 : 00173 00174 This function attaches a thread to a target process' address space 00175 if, and only if, there is not already a process attached. 00176 00177 Arguments: 00178 00179 Process - Supplies a pointer to a dispatcher object of type process. 00180 00181 Return Value: 00182 00183 None. 00184 00185 --*/ 00186 00187 { 00188 00189 KIRQL OldIrql; 00190 PRKTHREAD Thread; 00191 00192 ASSERT_PROCESS(Process); 00193 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00194 00195 // 00196 // Raise IRQL to dispatcher level and lock dispatcher database. 00197 // 00198 00199 Thread = KeGetCurrentThread(); 00200 KiLockDispatcherDatabase(&OldIrql); 00201 00202 // 00203 // If the target process is the current process, then return immediately. 00204 // Otherwise, check whether there is a process address space attached or 00205 // the thread is executing a DPC. If either condition is true, then call 00206 // bug check. Otherwise, attach the target process. 00207 // 00208 00209 if (Thread->ApcState.Process == Process) { 00210 KiUnlockDispatcherDatabase(OldIrql); 00211 00212 } else if ((Thread->ApcStateIndex != 0) || 00213 (KeIsExecutingDpc() != FALSE)) { 00214 KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT, 00215 (ULONG_PTR)Process, 00216 (ULONG_PTR)Thread->ApcState.Process, 00217 (ULONG)Thread->ApcStateIndex, 00218 (ULONG)KeIsExecutingDpc()); 00219 00220 } else { 00221 KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); 00222 } 00223 00224 return; 00225 }

VOID KeDetachProcess VOID   ) 
 

Definition at line 405 of file procobj.c.

References APC_LEVEL, _KAPC_STATE::ApcListHead, _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, _KTHREAD::ApcStatePointer, ASSERT, BALANCE_INCREMENT, DISPATCH_LEVEL, FALSE, _KEVENT::Header, KeBugCheck(), KeGetCurrentThread, _KAPC_STATE::KernelApcInProgress, _KAPC_STATE::KernelApcPending, KernelMode, KiLockDispatcherDatabase, KiMoveApcState(), KiProcessOutSwapListHead, KiRequestSoftwareInterrupt(), KiSwapEvent, KiSwapProcess(), KiUnlockDispatcherDatabase(), KiWaitTest(), NULL, _KAPC_STATE::Process, ProcessInTransition, _KTHREAD::SavedApcState, _DISPATCHER_HEADER::SignalState, _KPROCESS::StackCount, _KPROCESS::State, _KPROCESS::SwapListEntry, _KPROCESS::ThreadListHead, TRUE, UserMode, and _DISPATCHER_HEADER::WaitListHead.

Referenced by _GetComboBoxInfo(), _GetListBoxInfo(), CheckWHFBits(), MiCloneProcessAddressSpace(), MiCreatePebOrTeb(), MiDoMappedCopy(), MiDoPoolCopy(), MiEmptyAllWorkingSetsWorker(), MiGetWorkingSetInfo(), MiLoadImageSection(), MiLoadSystemImage(), MmAssignProcessToJob(), MmCreatePeb(), MmCreateTeb(), MmDeleteTeb(), MmFlushVirtualMemory(), MmInitializeProcessAddressSpace(), MmMapViewOfSection(), MmProbeAndLockProcessPages(), MmSetBankedSection(), MmSetMemoryPriorityProcess(), MmUnmapViewOfSection(), MmWorkingSetManager(), NtAllocateUserPhysicalPages(), NtAllocateVirtualMemory(), NtDuplicateObject(), NtFlushInstructionCache(), NtFreeUserPhysicalPages(), NtFreeVirtualMemory(), NtLockVirtualMemory(), NtProtectVirtualMemory(), NtQueryVirtualMemory(), NtSetInformationJobObject(), NtSetInformationProcess(), NtUnlockVirtualMemory(), ObReferenceObjectByHandle(), PsAssignImpersonationToken(), PspAddProcessToJob(), PspCreateProcess(), PspSetQuotaLimits(), SepRmCallLsa(), SetProcessFlags(), SmbTraceCompleteRdr(), SmbTraceDisconnect(), SmbTraceStop(), xxxCheckImeShowStatus(), xxxCreateDisconnectDesktop(), xxxCreateWindowStation(), xxxGetThreadDesktop(), xxxImmActivateAndUnloadThreadsLayout(), xxxMinMaximize(), xxxNotifyImeShowStatus(), xxxSendMessageToUI(), and zzzSetWindowsHookEx().

00411 : 00412 00413 This function detaches a thread from another process' address space. 00414 00415 Arguments: 00416 00417 None. 00418 00419 Return Value: 00420 00421 None. 00422 00423 --*/ 00424 00425 { 00426 00427 KIRQL OldIrql; 00428 PKPROCESS Process; 00429 PKTHREAD Thread; 00430 00431 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00432 00433 // 00434 // Raise IRQL to dispatcher level and lock dispatcher database. 00435 // 00436 00437 Thread = KeGetCurrentThread(); 00438 KiLockDispatcherDatabase(&OldIrql); 00439 00440 // 00441 // If the current thread is attached to another process, then detach 00442 // it. 00443 // 00444 00445 if (Thread->ApcStateIndex != 0) { 00446 00447 // 00448 // Check if a kernel APC is in progress, the kernel APC queue is 00449 // not empty, or the user APC queue is not empty. If any of these 00450 // conditions are true, then call bug check. 00451 // 00452 00453 #if DBG 00454 00455 if ((Thread->ApcState.KernelApcInProgress) || 00456 (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) || 00457 (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) == FALSE)) { 00458 KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT); 00459 } 00460 00461 #endif 00462 00463 // 00464 // Unbias current process stack count and check if the process should 00465 // be swapped out of memory. 00466 // 00467 00468 Process = Thread->ApcState.Process; 00469 Process->StackCount -= 1; 00470 if ((Process->StackCount == 0) && 00471 (IsListEmpty(&Process->ThreadListHead) == FALSE)) { 00472 Process->State = ProcessInTransition; 00473 InsertTailList(&KiProcessOutSwapListHead, &Process->SwapListEntry); 00474 KiSwapEvent.Header.SignalState = 1; 00475 if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { 00476 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); 00477 } 00478 } 00479 00480 // 00481 // Restore APC state and check whether the kernel APC queue contains 00482 // an entry. If the kernel APC queue contains an entry then set kernel 00483 // APC pending and request a software interrupt at APC_LEVEL. 00484 // 00485 00486 KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); 00487 Thread->SavedApcState.Process = (PKPROCESS)NULL; 00488 Thread->ApcStatePointer[0] = &Thread->ApcState; 00489 Thread->ApcStatePointer[1] = &Thread->SavedApcState; 00490 Thread->ApcStateIndex = 0; 00491 if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) { 00492 Thread->ApcState.KernelApcPending = TRUE; 00493 KiRequestSoftwareInterrupt(APC_LEVEL); 00494 } 00495 00496 // 00497 // Swap the address space back to the parent process. 00498 // 00499 00500 KiSwapProcess(Thread->ApcState.Process, Process); 00501 } 00502 00503 // 00504 // Lower IRQL to its previous value and return. 00505 // 00506 00507 KiUnlockDispatcherDatabase(OldIrql); 00508 return; 00509 }

LOGICAL KeForceAttachProcess IN PRKPROCESS  Process  ) 
 

Definition at line 228 of file procobj.c.

References _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, ASSERT, ASSERT_PROCESS, DISPATCH_LEVEL, FALSE, KeBugCheckEx(), KeGetCurrentThread, KiAttachProcess(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), _KAPC_STATE::Process, ProcessInMemory, ProcessInSwap, ProcessInTransition, ProcessOutSwap, _KTHREAD::SavedApcState, and TRUE.

Referenced by MmWorkingSetManager().

00234 : 00235 00236 This function forces an attach of a thread to a target process' address 00237 space if the process is not current being swapped into or out of memory. 00238 00239 N.B. This function is for use by memory management ONLY. 00240 00241 Arguments: 00242 00243 Process - Supplies a pointer to a dispatcher object of type process. 00244 00245 Return Value: 00246 00247 None. 00248 00249 --*/ 00250 00251 { 00252 00253 KIRQL OldIrql; 00254 PRKTHREAD Thread; 00255 00256 ASSERT_PROCESS(Process); 00257 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00258 00259 // 00260 // Raise IRQL to dispatcher level and lock dispatcher database. 00261 // 00262 00263 Thread = KeGetCurrentThread(); 00264 KiLockDispatcherDatabase(&OldIrql); 00265 00266 // 00267 // Check whether there is already a process address space attached or 00268 // the thread is executing a DPC. If either condition is true, then call 00269 // bug check. 00270 // 00271 00272 if ((Thread->ApcStateIndex != 0) || 00273 (KeIsExecutingDpc() != FALSE)) { 00274 KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT, 00275 (ULONG_PTR)Process, 00276 (ULONG_PTR)Thread->ApcState.Process, 00277 (ULONG)Thread->ApcStateIndex, 00278 (ULONG)KeIsExecutingDpc()); 00279 } 00280 00281 // 00282 // If the target process is not the current process, then attach the target 00283 // process if the process is not currently being swapped in or out of memory. 00284 // 00285 00286 if (Thread->ApcState.Process == Process) { 00287 KiUnlockDispatcherDatabase(OldIrql); 00288 00289 } else { 00290 00291 // 00292 // If the target process is currently being swapped into or out of memory, 00293 // then return a value of FALSE. Otherwise, force the process to be inswapped. 00294 // 00295 00296 if ((Process->State == ProcessInSwap) || Process->State == ProcessOutSwap) { 00297 KiUnlockDispatcherDatabase(OldIrql); 00298 return FALSE; 00299 00300 } else { 00301 00302 // 00303 // If the target process is in transition, then remove it from its 00304 // transition list. 00305 // 00306 00307 if (Process->State == ProcessInTransition) { 00308 RemoveEntryList(&Process->SwapListEntry); 00309 } 00310 00311 // 00312 // Force the process state to in memory and attach the target process. 00313 // 00314 00315 Process->State = ProcessInMemory; 00316 KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); 00317 } 00318 } 00319 00320 return TRUE; 00321 }

VOID KeInitializeProcess IN PRKPROCESS  Process,
IN KPRIORITY  BasePriority,
IN KAFFINITY  Affinity,
IN ULONG_PTR  DirectoryTableBase[2],
IN BOOLEAN  Enable
 

Definition at line 63 of file procobj.c.

References ProcessInMemory, ProcessObject, and THREAD_QUANTUM.

Referenced by KiInitializeKernel(), and PspCreateProcess().

00073 : 00074 00075 This function initializes a kernel process object. The base priority, 00076 affinity, and page frame numbers for the process page table directory 00077 and hyper space are stored in the process object. 00078 00079 N.B. It is assumed that the process object is zeroed. 00080 00081 Arguments: 00082 00083 Process - Supplies a pointer to a dispatcher object of type process. 00084 00085 BasePriority - Supplies the base priority of the process. 00086 00087 Affinity - Supplies the set of processors on which children threads 00088 of the process can execute. 00089 00090 DirectoryTableBase - Supplies a pointer to an array whose fist element 00091 is the value that is to be loaded into the Directory Table Base 00092 register when a child thread is dispatched for execution and whose 00093 second element contains the page table entry that maps hyper space. 00094 00095 Enable - Supplies a boolean value that determines the default 00096 handling of data alignment exceptions for child threads. A value 00097 of TRUE causes all data alignment exceptions to be automatically 00098 handled by the kernel. A value of FALSE causes all data alignment 00099 exceptions to be actually raised as exceptions. 00100 00101 Return Value: 00102 00103 None. 00104 00105 --*/ 00106 00107 { 00108 00109 // 00110 // Initialize the standard dispatcher object header and set the initial 00111 // signal state of the process object. 00112 // 00113 00114 Process->Header.Type = ProcessObject; 00115 Process->Header.Size = sizeof(KPROCESS) / sizeof(LONG); 00116 InitializeListHead(&Process->Header.WaitListHead); 00117 00118 // 00119 // Initialize the base priority, affinity, directory table base values, 00120 // autoalignment, and stack count. 00121 // 00122 // N.B. The distinguished value MAXSHORT is used to signify that no 00123 // threads have been created for the process. 00124 // 00125 00126 Process->BasePriority = (SCHAR)BasePriority; 00127 Process->Affinity = Affinity; 00128 Process->AutoAlignment = Enable; 00129 Process->DirectoryTableBase[0] = DirectoryTableBase[0]; 00130 Process->DirectoryTableBase[1] = DirectoryTableBase[1]; 00131 Process->StackCount = MAXSHORT; 00132 00133 // 00134 // Initialize the stack count, profile listhead, ready queue list head, 00135 // accumulated runtime, process quantum, thread quantum, and thread list 00136 // head. 00137 // 00138 00139 InitializeListHead(&Process->ProfileListHead); 00140 InitializeListHead(&Process->ReadyListHead); 00141 InitializeListHead(&Process->ThreadListHead); 00142 Process->ThreadQuantum = THREAD_QUANTUM; 00143 00144 // 00145 // Initialize the process state and set the thread processor selection 00146 // seed. 00147 // 00148 00149 Process->State = ProcessInMemory; 00150 Process->ThreadSeed = (UCHAR)KiQueryLowTickCount(); 00151 00152 // 00153 // Initialize IopmBase and Iopl flag for this process (i386 only) 00154 // 00155 00156 #ifdef i386 00157 00158 Process->IopmOffset = KiComputeIopmOffset(IO_ACCESS_MAP_NONE); 00159 00160 #endif 00161 00162 return; 00163 }

LONG KeReadStateProcess IN PRKPROCESS  Process  ) 
 

Definition at line 624 of file procobj.c.

References ASSERT_PROCESS.

Referenced by NtSetInformationJobObject(), NtSetInformationProcess(), and PsLockProcess().

00630 : 00631 00632 This function reads the current signal state of a process object. 00633 00634 Arguments: 00635 00636 Process - Supplies a pointer to a dispatcher object of type process. 00637 00638 Return Value: 00639 00640 The current signal state of the process object. 00641 00642 --*/ 00643 00644 { 00645 00646 ASSERT_PROCESS(Process); 00647 00648 // 00649 // Return current signal state of process object. 00650 // 00651 00652 return Process->Header.SignalState; 00653 }

LOGICAL KeSetDisableQuantumProcess IN PKPROCESS  Process,
IN LOGICAL  Disable
 

Definition at line 907 of file procobj.c.

References ASSERT_PROCESS.

Referenced by PspApplyJobLimitsToProcess().

00914 : 00915 00916 This function disables quantum runout for realtime threads in the 00917 specified process. 00918 00919 Arguments: 00920 00921 Process - Supplies a pointer to a dispatcher object of type process. 00922 00923 Disable - Supplies a logical value that determines whether quantum 00924 runout for realtime threads in the specified process are disabled 00925 or enabled. 00926 00927 Return Value: 00928 00929 The previous value of the disable quantum state variable. 00930 00931 --*/ 00932 00933 { 00934 00935 LOGICAL DisableQuantum; 00936 00937 ASSERT_PROCESS(Process); 00938 00939 // 00940 // Capture the current state of the disable boost variable and set its 00941 // state to TRUE. 00942 // 00943 00944 DisableQuantum = Process->DisableQuantum; 00945 Process->DisableQuantum = (BOOLEAN)Disable; 00946 00947 // 00948 // Return the previous disable quantum state. 00949 // 00950 00951 return DisableQuantum; 00952 }

KPRIORITY KeSetPriorityProcess IN PKPROCESS  Process,
IN KPRIORITY  NewBase
 

Definition at line 738 of file procobj.c.

References ASSERT, ASSERT_PROCESS, _KTHREAD::BasePriority, _KTHREAD::DecrementCount, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiSetPriorityThread(), KiUnlockDispatcherDatabase(), _KTHREAD::PriorityDecrement, _KTHREAD::Quantum, and _KTHREAD::Saturation.

Referenced by NtSetInformationProcess(), and PsSetProcessPriorityByClass().

00745 : 00746 00747 This function set the base priority of a process to a new value 00748 and adjusts the priority and base priority of all child threads 00749 as appropriate. 00750 00751 Arguments: 00752 00753 Process - Supplies a pointer to a dispatcher object of type process. 00754 00755 NewBase - Supplies the new base priority of the process. 00756 00757 Return Value: 00758 00759 The previous base priority of the process. 00760 00761 --*/ 00762 00763 { 00764 00765 KPRIORITY Adjustment; 00766 PLIST_ENTRY NextEntry; 00767 KPRIORITY NewPriority; 00768 KIRQL OldIrql; 00769 KPRIORITY OldBase; 00770 PKTHREAD Thread; 00771 00772 ASSERT_PROCESS(Process); 00773 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00774 00775 // 00776 // Raise IRQL to dispatcher level and lock dispatcher database. 00777 // 00778 00779 KiLockDispatcherDatabase(&OldIrql); 00780 00781 // 00782 // Save the current process base priority, set the new process base 00783 // priority, compute the adjustment value, and adjust the priority 00784 // and base priority of all child threads as appropriate. 00785 // 00786 00787 OldBase = Process->BasePriority; 00788 Process->BasePriority = (SCHAR)NewBase; 00789 Adjustment = NewBase - OldBase; 00790 NextEntry = Process->ThreadListHead.Flink; 00791 if (NewBase >= LOW_REALTIME_PRIORITY) { 00792 while (NextEntry != &Process->ThreadListHead) { 00793 Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry); 00794 00795 // 00796 // Compute the new base priority of the thread. 00797 // 00798 00799 NewPriority = Thread->BasePriority + Adjustment; 00800 00801 // 00802 // If the new base priority is outside the realtime class, 00803 // then limit the change to the realtime class. 00804 // 00805 00806 if (NewPriority < LOW_REALTIME_PRIORITY) { 00807 NewPriority = LOW_REALTIME_PRIORITY; 00808 00809 } else if (NewPriority > HIGH_PRIORITY) { 00810 NewPriority = HIGH_PRIORITY; 00811 } 00812 00813 // 00814 // Set the base priority and the current priority of the 00815 // thread to the appropriate value. 00816 // 00817 // N.B. If priority saturation occured the last time the thread 00818 // base priority was set and the new process base priority 00819 // is not crossing from variable to realtime, then it is not 00820 // necessary to change the thread priority. 00821 // 00822 00823 if ((Thread->Saturation == 0) || (OldBase < LOW_REALTIME_PRIORITY)) { 00824 if (Thread->Saturation > 0) { 00825 NewPriority = HIGH_PRIORITY; 00826 00827 } else if (Thread->Saturation < 0) { 00828 NewPriority = LOW_REALTIME_PRIORITY; 00829 } 00830 00831 Thread->BasePriority = (SCHAR)NewPriority; 00832 Thread->Quantum = Process->ThreadQuantum; 00833 Thread->DecrementCount = 0; 00834 Thread->PriorityDecrement = 0; 00835 KiSetPriorityThread(Thread, NewPriority); 00836 } 00837 00838 NextEntry = NextEntry->Flink; 00839 } 00840 00841 } else { 00842 while (NextEntry != &Process->ThreadListHead) { 00843 Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry); 00844 00845 // 00846 // Compute the new base priority of the thread. 00847 // 00848 00849 NewPriority = Thread->BasePriority + Adjustment; 00850 00851 // 00852 // If the new base priority is outside the variable class, 00853 // then limit the change to the variable class. 00854 // 00855 00856 if (NewPriority >= LOW_REALTIME_PRIORITY) { 00857 NewPriority = LOW_REALTIME_PRIORITY - 1; 00858 00859 } else if (NewPriority <= LOW_PRIORITY) { 00860 NewPriority = 1; 00861 } 00862 00863 // 00864 // Set the base priority and the current priority of the 00865 // thread to the computed value and reset the thread quantum. 00866 // 00867 // N.B. If priority saturation occured the last time the thread 00868 // base priority was set and the new process base priority 00869 // is not crossing from realtime to variable, then it is not 00870 // necessary to change the thread priority. 00871 // 00872 00873 if ((Thread->Saturation == 0) || (OldBase >= LOW_REALTIME_PRIORITY)) { 00874 if (Thread->Saturation > 0) { 00875 NewPriority = LOW_REALTIME_PRIORITY - 1; 00876 00877 } else if (Thread->Saturation < 0) { 00878 NewPriority = 1; 00879 } 00880 00881 Thread->BasePriority = (SCHAR)NewPriority; 00882 Thread->Quantum = Process->ThreadQuantum; 00883 Thread->DecrementCount = 0; 00884 Thread->PriorityDecrement = 0; 00885 KiSetPriorityThread(Thread, NewPriority); 00886 } 00887 00888 NextEntry = NextEntry->Flink; 00889 } 00890 } 00891 00892 // 00893 // Unlock dispatcher database and lower IRQL to its previous 00894 // value. 00895 // 00896 00897 KiUnlockDispatcherDatabase(OldIrql); 00898 00899 // 00900 // Return previous process base priority 00901 // 00902 00903 return OldBase; 00904 }

LONG KeSetProcess IN PRKPROCESS  Process,
IN KPRIORITY  Increment,
IN BOOLEAN  Wait
 

Definition at line 656 of file procobj.c.

References ASSERT, ASSERT_PROCESS, DISPATCH_LEVEL, Increment, KeGetCurrentThread, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), _KTHREAD::WaitIrql, and _KTHREAD::WaitNext.

Referenced by PspExitProcess(), and PspExitThread().

00664 : 00665 00666 This function sets the signal state of a proces object to Signaled 00667 and attempts to satisfy as many Waits as possible. The previous 00668 signal state of the process object is returned as the function value. 00669 00670 Arguments: 00671 00672 Process - Supplies a pointer to a dispatcher object of type process. 00673 00674 Increment - Supplies the priority increment that is to be applied 00675 if setting the process causes a Wait to be satisfied. 00676 00677 Wait - Supplies a boolean value that signifies whether the call to 00678 KeSetProcess will be immediately followed by a call to one of the 00679 kernel Wait functions. 00680 00681 Return Value: 00682 00683 The previous signal state of the process object. 00684 00685 --*/ 00686 00687 { 00688 00689 KIRQL OldIrql; 00690 LONG OldState; 00691 PRKTHREAD Thread; 00692 00693 ASSERT_PROCESS(Process); 00694 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00695 00696 // 00697 // Raise IRQL to dispatcher level and lock dispatcher database. 00698 // 00699 00700 KiLockDispatcherDatabase(&OldIrql); 00701 00702 // 00703 // If the previous state of the process object is Not-Signaled and 00704 // the wait queue is not empty, then satisfy as many Waits as 00705 // possible. 00706 // 00707 00708 OldState = Process->Header.SignalState; 00709 Process->Header.SignalState = 1; 00710 if ((OldState == 0) && (!IsListEmpty(&Process->Header.WaitListHead))) { 00711 KiWaitTest(Process, Increment); 00712 } 00713 00714 // 00715 // If the value of the Wait argument is TRUE, then return to the 00716 // caller with IRQL raised and the dispatcher database locked. Else 00717 // release the dispatcher database lock and lower IRQL to its 00718 // previous value. 00719 // 00720 00721 if (Wait) { 00722 Thread = KeGetCurrentThread(); 00723 Thread->WaitNext = Wait; 00724 Thread->WaitIrql = OldIrql; 00725 00726 } else { 00727 KiUnlockDispatcherDatabase(OldIrql); 00728 } 00729 00730 // 00731 // Return previous signal state of process object. 00732 // 00733 00734 return OldState; 00735 }

VOID KeStackAttachProcess IN PRKPROCESS  Process,
OUT PRKAPC_STATE  ApcState
 

Definition at line 324 of file procobj.c.

References _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, ASSERT, ASSERT_PROCESS, DISPATCH_LEVEL, FALSE, KeBugCheckEx(), KeGetCurrentThread, KiAttachProcess(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), NULL, _KAPC_STATE::Process, and _KTHREAD::SavedApcState.

Referenced by NtClose(), NtSetInformationObject(), NtWaitForMultipleObjects(), ObpCreateHandle(), ObpCreateUnnamedHandle(), and PspProcessDelete().

00331 : 00332 00333 This function attaches a thread to a target process' address space 00334 and returns information about a previous attached process. 00335 00336 Arguments: 00337 00338 Process - Supplies a pointer to a dispatcher object of type process. 00339 00340 Return Value: 00341 00342 None. 00343 00344 --*/ 00345 00346 { 00347 00348 KIRQL OldIrql; 00349 PRKTHREAD Thread; 00350 00351 ASSERT_PROCESS(Process); 00352 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00353 00354 // 00355 // Raise IRQL to dispatcher level and lock dispatcher database. 00356 // 00357 00358 Thread = KeGetCurrentThread(); 00359 KiLockDispatcherDatabase(&OldIrql); 00360 00361 // 00362 // If the current thread is executing a DPC, then bug check. 00363 // 00364 00365 if (KeIsExecutingDpc() != FALSE) { 00366 KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT, 00367 (ULONG_PTR)Process, 00368 (ULONG_PTR)Thread->ApcState.Process, 00369 (ULONG)Thread->ApcStateIndex, 00370 (ULONG)KeIsExecutingDpc()); 00371 } 00372 00373 // 00374 // If the target process is not the current process, then attach the target 00375 // process. Otherwise, return a distinguished process value to indicate that 00376 // an attach was not performed. 00377 // 00378 00379 if (Thread->ApcState.Process == Process) { 00380 KiUnlockDispatcherDatabase(OldIrql); 00381 ApcState->Process = (PRKPROCESS)1; 00382 00383 } else { 00384 00385 // 00386 // If the current thread is attached to a process, then save the current 00387 // APC state in the callers APC state structure. Otherwise, save the 00388 // current APC state in the saved APC state structure, and return a NULL 00389 // process pointer. 00390 // 00391 00392 if (Thread->ApcStateIndex != 0) { 00393 KiAttachProcess(Thread, Process, OldIrql, ApcState); 00394 00395 } else { 00396 KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); 00397 ApcState->Process = NULL; 00398 } 00399 } 00400 00401 return; 00402 }

VOID KeUnstackDetachProcess IN PRKAPC_STATE  ApcState  ) 
 

Definition at line 512 of file procobj.c.

References APC_LEVEL, _KAPC_STATE::ApcListHead, _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, _KTHREAD::ApcStatePointer, ASSERT, BALANCE_INCREMENT, DISPATCH_LEVEL, FALSE, _KEVENT::Header, KeBugCheck(), KeGetCurrentThread, _KAPC_STATE::KernelApcInProgress, _KAPC_STATE::KernelApcPending, KernelMode, KiLockDispatcherDatabase, KiMoveApcState(), KiProcessOutSwapListHead, KiRequestSoftwareInterrupt(), KiSwapEvent, KiSwapProcess(), KiUnlockDispatcherDatabase(), KiWaitTest(), NULL, _KAPC_STATE::Process, ProcessInTransition, _KTHREAD::SavedApcState, _DISPATCHER_HEADER::SignalState, _KPROCESS::StackCount, _KPROCESS::State, _KPROCESS::SwapListEntry, _KPROCESS::ThreadListHead, TRUE, UserMode, and _DISPATCHER_HEADER::WaitListHead.

Referenced by NtClose(), NtSetInformationObject(), NtWaitForMultipleObjects(), ObpCreateHandle(), ObpCreateUnnamedHandle(), and PspProcessDelete().

00518 : 00519 00520 This function detaches a thread from another process' address space 00521 and restores previous attach state. 00522 00523 Arguments: 00524 00525 ApcState - Supplies a pointer to an APC state structure that was returned 00526 from a previous call to stack attach process. 00527 00528 Return Value: 00529 00530 None. 00531 00532 --*/ 00533 00534 { 00535 00536 KIRQL OldIrql; 00537 PKPROCESS Process; 00538 PKTHREAD Thread; 00539 00540 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00541 00542 // 00543 // Raise IRQL to dispatcher level and lock dispatcher database. 00544 // 00545 00546 Thread = KeGetCurrentThread(); 00547 KiLockDispatcherDatabase(&OldIrql); 00548 00549 // 00550 // If the APC state has a distinguished process pointer value, then no 00551 // attach was performed on the paired call to stack attach process. 00552 // 00553 00554 if (ApcState->Process != (PRKPROCESS)1) { 00555 00556 // 00557 // If the current thread is not attached to another process, a kernel 00558 // APC is in progress, or either the kernel or user mode APC queues 00559 // are not empty, then call bug check. 00560 // 00561 00562 if ((Thread->ApcStateIndex == 0) || 00563 (Thread->ApcState.KernelApcInProgress) || 00564 (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) || 00565 (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) == FALSE)) { 00566 KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT); 00567 } 00568 00569 // 00570 // Unbias current process stack count and check if the process should 00571 // be swapped out of memory. 00572 // 00573 00574 Process = Thread->ApcState.Process; 00575 Process->StackCount -= 1; 00576 if ((Process->StackCount == 0) && 00577 (IsListEmpty(&Process->ThreadListHead) == FALSE)) { 00578 Process->State = ProcessInTransition; 00579 InsertTailList(&KiProcessOutSwapListHead, &Process->SwapListEntry); 00580 KiSwapEvent.Header.SignalState = 1; 00581 if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { 00582 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); 00583 } 00584 } 00585 00586 // 00587 // Restore APC state and check whether the kernel APC queue contains 00588 // an entry. If the kernel APC queue contains an entry then set kernel 00589 // APC pending and request a software interrupt at APC_LEVEL. 00590 // 00591 00592 if (ApcState->Process != NULL) { 00593 KiMoveApcState(ApcState, &Thread->ApcState); 00594 00595 } else { 00596 KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); 00597 Thread->SavedApcState.Process = (PKPROCESS)NULL; 00598 Thread->ApcStatePointer[0] = &Thread->ApcState; 00599 Thread->ApcStatePointer[1] = &Thread->SavedApcState; 00600 Thread->ApcStateIndex = 0; 00601 } 00602 00603 if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) { 00604 Thread->ApcState.KernelApcPending = TRUE; 00605 KiRequestSoftwareInterrupt(APC_LEVEL); 00606 } 00607 00608 // 00609 // Swap the address space back to the parent process. 00610 // 00611 00612 KiSwapProcess(Thread->ApcState.Process, Process); 00613 } 00614 00615 // 00616 // Lower IRQL to its previous value and return. 00617 // 00618 00619 KiUnlockDispatcherDatabase(OldIrql); 00620 return; 00621 }

VOID KiAttachProcess IN PRKTHREAD  Thread,
IN PKPROCESS  Process,
IN KIRQL  OldIrql,
OUT PRKAPC_STATE  SavedApcState
 

Definition at line 955 of file procobj.c.

References ASSERT, BALANCE_INCREMENT, FALSE, _KEVENT::Header, KeGetCurrentPrcb, KernelMode, KiLockContextSwap, KiMoveApcState(), KiProcessInSwapListHead, KiReadyThread(), KiSwapEvent, KiSwapProcess(), KiSwapThread(), KiUnlockContextSwap, KiUnlockDispatcherDatabase(), KiWaitTest(), ProcessInMemory, ProcessInTransition, ProcessOutOfMemory, _KTHREAD::ProcessReadyQueue, Ready, _DISPATCHER_HEADER::SignalState, TRUE, UserMode, and _DISPATCHER_HEADER::WaitListHead.

Referenced by KeAttachProcess(), KeForceAttachProcess(), and KeStackAttachProcess().

00964 : 00965 00966 This function attaches a thread to a target process' address space. 00967 00968 N.B. The dispatcher database lock must be held when this routine is 00969 called. 00970 00971 Arguments: 00972 00973 Thread - Supplies a pointer to a dispatcher object of type thread. 00974 00975 Process - Supplies a pointer to a dispatcher object of type process. 00976 00977 OldIrql - Supplies the previous IRQL. 00978 00979 SavedApcState - Supplies a pointer to the APC state structure that receives 00980 the saved APC state. 00981 00982 Return Value: 00983 00984 None. 00985 00986 --*/ 00987 00988 { 00989 00990 PRKTHREAD OutThread; 00991 KAFFINITY Processor; 00992 PLIST_ENTRY NextEntry; 00993 KIRQL HighIrql; 00994 00995 ASSERT(Process != Thread->ApcState.Process); 00996 00997 // 00998 // Bias the stack count of the target process to signify that a 00999 // thread exists in that process with a stack that is resident. 01000 // 01001 01002 Process->StackCount += 1; 01003 01004 // 01005 // Save current APC state and initialize a new APC state. 01006 // 01007 01008 KiMoveApcState(&Thread->ApcState, SavedApcState); 01009 InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]); 01010 InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]); 01011 Thread->ApcState.Process = Process; 01012 Thread->ApcState.KernelApcInProgress = FALSE; 01013 Thread->ApcState.KernelApcPending = FALSE; 01014 Thread->ApcState.UserApcPending = FALSE; 01015 if (SavedApcState == &Thread->SavedApcState) { 01016 Thread->ApcStatePointer[0] = &Thread->SavedApcState; 01017 Thread->ApcStatePointer[1] = &Thread->ApcState; 01018 Thread->ApcStateIndex = 1; 01019 } 01020 01021 // 01022 // If the target process is in memory, then immediately enter the 01023 // new address space by loading a new Directory Table Base. Otherwise, 01024 // insert the current thread in the target process ready list, inswap 01025 // the target process if necessary, select a new thread to run on the 01026 // the current processor and context switch to the new thread. 01027 // 01028 01029 if (Process->State == ProcessInMemory) { 01030 01031 // 01032 // It is possible that the process is in memory, but there exist 01033 // threads in the process ready list. This can happen when memory 01034 // management forces a process attach. 01035 // 01036 01037 NextEntry = Process->ReadyListHead.Flink; 01038 while (NextEntry != &Process->ReadyListHead) { 01039 OutThread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry); 01040 RemoveEntryList(NextEntry); 01041 OutThread->ProcessReadyQueue = FALSE; 01042 KiReadyThread(OutThread); 01043 NextEntry = Process->ReadyListHead.Flink; 01044 } 01045 01046 KiSwapProcess(Process, SavedApcState->Process); 01047 KiUnlockDispatcherDatabase(OldIrql); 01048 01049 } else { 01050 Thread->State = Ready; 01051 Thread->ProcessReadyQueue = TRUE; 01052 InsertTailList(&Process->ReadyListHead, &Thread->WaitListEntry); 01053 if (Process->State == ProcessOutOfMemory) { 01054 Process->State = ProcessInTransition; 01055 InsertTailList(&KiProcessInSwapListHead, &Process->SwapListEntry); 01056 KiSwapEvent.Header.SignalState = 1; 01057 if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { 01058 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); 01059 } 01060 } 01061 01062 // 01063 // Clear the active processor bit in the previous process and 01064 // set active processor bit in the process being attached to. 01065 // 01066 01067 #if !defined(NT_UP) 01068 01069 KiLockContextSwap(&HighIrql); 01070 Processor = KeGetCurrentPrcb()->SetMember; 01071 SavedApcState->Process->ActiveProcessors &= ~Processor; 01072 Process->ActiveProcessors |= Processor; 01073 01074 #if defined(_ALPHA_) 01075 01076 Process->RunOnProcessors |= Processor; 01077 01078 #endif 01079 01080 KiUnlockContextSwap(HighIrql); 01081 01082 #endif 01083 01084 Thread->WaitIrql = OldIrql; 01085 KiSwapThread(); 01086 } 01087 01088 return; 01089 }

VOID KiAttachProcess IN PRKTHREAD  Thread,
IN PRKPROCESS  Process,
IN KIRQL  OldIrql,
OUT PRKAPC_STATE  SavedApcState
 

VOID KiMoveApcState IN PKAPC_STATE  Source,
OUT PKAPC_STATE  Destination
 

Definition at line 1092 of file procobj.c.

References FALSE, KernelMode, and UserMode.

Referenced by KeDetachProcess(), KeUnstackDetachProcess(), and KiAttachProcess().

01099 : 01100 01101 This function moves the APC state from the source structure to the 01102 destination structure and reinitializes list headers as appropriate. 01103 01104 Arguments: 01105 01106 Source - Supplies a pointer to the source APC state structure. 01107 01108 Destination - Supplies a pointer to the destination APC state structure. 01109 01110 01111 Return Value: 01112 01113 None. 01114 01115 --*/ 01116 01117 { 01118 01119 PLIST_ENTRY First; 01120 PLIST_ENTRY Last; 01121 01122 // 01123 // Copy the APC state from the source to the destination. 01124 // 01125 01126 *Destination = *Source; 01127 if (IsListEmpty(&Source->ApcListHead[KernelMode]) != FALSE) { 01128 InitializeListHead(&Destination->ApcListHead[KernelMode]); 01129 01130 } else { 01131 First = Source->ApcListHead[KernelMode].Flink; 01132 Last = Source->ApcListHead[KernelMode].Blink; 01133 Destination->ApcListHead[KernelMode].Flink = First; 01134 Destination->ApcListHead[KernelMode].Blink = Last; 01135 First->Blink = &Destination->ApcListHead[KernelMode]; 01136 Last->Flink = &Destination->ApcListHead[KernelMode]; 01137 } 01138 01139 if (IsListEmpty(&Source->ApcListHead[UserMode]) != FALSE) { 01140 InitializeListHead(&Destination->ApcListHead[UserMode]); 01141 01142 } else { 01143 First = Source->ApcListHead[UserMode].Flink; 01144 Last = Source->ApcListHead[UserMode].Blink; 01145 Destination->ApcListHead[UserMode].Flink = First; 01146 Destination->ApcListHead[UserMode].Blink = Last; 01147 First->Blink = &Destination->ApcListHead[UserMode]; 01148 Last->Flink = &Destination->ApcListHead[UserMode]; 01149 } 01150 01151 return; 01152 } }


Generated on Sat May 15 19:45:18 2004 for test by doxygen 1.3.7