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

psp.h File Reference

#include "ntos.h"
#include "ntrtl.h"
#include "nturtl.h"
#include "zwapi.h"
#include "ki.h"
#include "wdbgexts.h"
#include "ntdbg.h"
#include <string.h>

Go to the source code of this file.

Classes

struct  _TERMINATION_PORT
struct  _GETSETCONTEXT
struct  _SYSTEM_DLL
struct  _JOB_WORKING_SET_CHANGE_HEAD
struct  _JOB_WORKING_SET_CHANGE_RECORD

Defines

#define NOEXTAPI
#define PSP_PROCESS_PAGED_CHARGE   (PAGE_SIZE)
#define PSP_PROCESS_NONPAGED_CHARGE   (sizeof(EPROCESS))
#define PSP_THREAD_PAGED_CHARGE   (0)
#define PSP_THREAD_NONPAGED_CHARGE   (sizeof(ETHREAD))
#define PSP_MAX_CREATE_PROCESS_NOTIFY   8
#define PSP_MAX_CREATE_THREAD_NOTIFY   8
#define PSP_MAX_LOAD_IMAGE_NOTIFY   8
#define PSP_NUMBER_OF_SCHEDULING_CLASSES   10
#define PSP_DEFAULT_SCHEDULING_CLASSES   5

Typedefs

typedef _TERMINATION_PORT TERMINATION_PORT
typedef _TERMINATION_PORTPTERMINATION_PORT
typedef _GETSETCONTEXT GETSETCONTEXT
typedef _GETSETCONTEXTPGETSETCONTEXT
typedef _SYSTEM_DLL SYSTEM_DLL
typedef _SYSTEM_DLL PSYSTEM_DLL
typedef _JOB_WORKING_SET_CHANGE_HEAD JOB_WORKING_SET_CHANGE_HEAD
typedef _JOB_WORKING_SET_CHANGE_HEADPJOB_WORKING_SET_CHANGE_HEAD
typedef _JOB_WORKING_SET_CHANGE_RECORD JOB_WORKING_SET_CHANGE_RECORD
typedef _JOB_WORKING_SET_CHANGE_RECORDPJOB_WORKING_SET_CHANGE_RECORD

Functions

VOID PspProcessDump (IN PVOID Object, IN POB_DUMP_CONTROL Control OPTIONAL)
VOID PspProcessDelete (IN PVOID Object)
VOID PspThreadDump (IN PVOID Object, IN POB_DUMP_CONTROL Control OPTIONAL)
VOID PspInheritQuota (IN PEPROCESS NewProcess, IN PEPROCESS ParentProcess)
VOID PspDereferenceQuota (IN PEPROCESS Process)
VOID PspThreadDelete (IN PVOID Object)
BOOLEAN PspInitPhase0 (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
BOOLEAN PspInitPhase1 (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS PspInitializeSystemDll (VOID)
NTSTATUS PspLookupSystemDllEntryPoint (IN PSZ EntryPointName, OUT PVOID *EntryPointAddress)
NTSTATUS PspLookupKernelUserEntryPoints (VOID)
USHORT PspNameToOrdinal (IN PSZ EntryPointName, IN ULONG DllBase, IN ULONG NumberOfNames, IN PULONG NameTableBase, IN PUSHORT OrdinalTableBase)
NTSTATUS PspMapSystemDll (IN PEPROCESS Process, OUT PVOID *DllBase OPTIONAL)
NTSTATUS PspCreateProcess (OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcess OPTIONAL, IN BOOLEAN InheritObjectTable, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL)
NTSTATUS PspCreateThread (OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PEPROCESS ProcessPointer, OUT PCLIENT_ID ClientId OPTIONAL, IN PCONTEXT ThreadContext OPTIONAL, IN PINITIAL_TEB InitialTeb OPTIONAL, IN BOOLEAN CreateSuspended, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext)
VOID PspUserThreadStartup (IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
VOID PspSystemThreadStartup (IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
VOID PspReaper (IN PVOID StartContext)
VOID PspNullSpecialApc (IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
DECLSPEC_NORETURN VOID PspExitThread (IN NTSTATUS ExitStatus)
NTSTATUS PspTerminateThreadByPointer (IN PETHREAD Thread, IN NTSTATUS ExitStatus)
VOID PspExitSpecialApc (IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
VOID PspExitProcess (IN BOOLEAN TrimAddressSpace, IN PEPROCESS Process)
VOID PspSetContext (OUT PKTRAP_FRAME TrapFrame, OUT PKNONVOLATILE_CONTEXT_POINTERS NonVolatileContext, IN PCONTEXT Context, KPROCESSOR_MODE Mode)
VOID PspGetContext (IN PKTRAP_FRAME TrapFrame, IN PKNONVOLATILE_CONTEXT_POINTERS NonVolatileContext, IN OUT PCONTEXT Context)
VOID PspGetSetContextSpecialApc (IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
VOID PspExitNormalApc (IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
NTSTATUS PspInitializeProcessSecurity (IN PEPROCESS Parent OPTIONAL, IN PEPROCESS Child)
VOID PspDeleteProcessSecurity (IN PEPROCESS Process)
VOID PspInitializeThreadSecurity (IN PEPROCESS Process, IN PETHREAD Thread)
VOID PspDeleteThreadSecurity (IN PETHREAD Thread)
NTSTATUS PspAssignPrimaryToken (IN PEPROCESS Process, IN HANDLE Token OPTIONAL, IN PACCESS_TOKEN TokenPointer OPTIONAL)
NTSTATUS PspSetPrimaryToken (IN HANDLE ProcessHandle, IN HANDLE TokenHandle OPTIONAL, IN PACCESS_TOKEN TokenPointer OPTIONAL)
NTSTATUS PspQueryLdtInformation (IN PEPROCESS Process, OUT PVOID LdtInformation, IN ULONG LdtInformationLength, OUT PULONG ReturnLength)
NTSTATUS PspSetLdtInformation (IN PEPROCESS Process, IN PVOID LdtInformation, IN ULONG LdtInformationLength)
NTSTATUS PspSetLdtSize (IN PEPROCESS Process, IN PVOID LdtSize, IN ULONG LdtSizeLength)
VOID PspDeleteLdt (IN PEPROCESS Process)
NTSTATUS PspSetProcessIoHandlers (IN PEPROCESS Process, IN PVOID IoHandlerInformation, IN ULONG IoHandlerLength)
VOID PspDeleteVdmObjects (IN PEPROCESS Process)
NTSTATUS PspQueryDescriptorThread (PETHREAD Thread, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength)
VOID PspJobDelete (IN PVOID Object)
VOID PspJobClose (IN PEPROCESS Process, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
NTSTATUS PspAddProcessToJob (PEJOB Job, PEPROCESS Process)
VOID PspRemoveProcessFromJob (PEJOB Job, PEPROCESS Process)
VOID PspExitProcessFromJob (PEJOB Job, PEPROCESS Process)
NTSTATUS PspTerminateProcess (PEPROCESS Process, NTSTATUS Status, PSLOCKPROCESSMODE LockMode)
VOID PspApplyJobLimitsToProcessSet (PEJOB Job)
VOID PspApplyJobLimitsToProcess (PEJOB Job, PEPROCESS Process)
BOOLEAN PspTerminateAllProcessesInJob (PEJOB Job, NTSTATUS Status, PSLOCKPROCESSMODE LockMode)
VOID PspFoldProcessAccountingIntoJob (PEJOB Job, PEPROCESS Process)
NTSTATUS PspCaptureTokenFilter (KPROCESSOR_MODE PreviousMode, PJOBOBJECT_SECURITY_LIMIT_INFORMATION SecurityLimitInfo, PPS_JOB_TOKEN_FILTER *TokenFilter)

Variables

JOB_WORKING_SET_CHANGE_HEAD PspWorkingSetChangeHead
ULONG PspCreateProcessNotifyRoutineCount
PCREATE_PROCESS_NOTIFY_ROUTINE PspCreateProcessNotifyRoutine [PSP_MAX_CREATE_PROCESS_NOTIFY]
ULONG PspCreateThreadNotifyRoutineCount
PCREATE_THREAD_NOTIFY_ROUTINE PspCreateThreadNotifyRoutine [PSP_MAX_CREATE_THREAD_NOTIFY]
ULONG PspLoadImageNotifyRoutineCount
PLOAD_IMAGE_NOTIFY_ROUTINE PspLoadImageNotifyRoutine [PSP_MAX_LOAD_IMAGE_NOTIFY]
PHANDLE_TABLE PspCidTable
HANDLE PspInitialSystemProcessHandle
PACCESS_TOKEN PspBootAccessToken
KSPIN_LOCK PspEventPairLock
SYSTEM_DLL PspSystemDll
FAST_MUTEX PspActiveProcessMutex
FAST_MUTEX PspProcessLockMutex
ULONG PspDefaultPagedLimit
ULONG PspDefaultNonPagedLimit
ULONG PspDefaultPagefileLimit
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
BOOLEAN PspDoingGiveBacks
PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout
PKWIN32_THREAD_CALLOUT PspW32ThreadCallout
PKWIN32_JOB_CALLOUT PspW32JobCallout
ULONG PspW32ProcessSize
ULONG PspW32ThreadSize
SCHAR PspForegroundQuantum [3]
SCHAR PspJobSchedulingClasses [PSP_NUMBER_OF_SCHEDULING_CLASSES]
BOOLEAN PspUseJobSchedulingClasses
FAST_MUTEX PspJobListLock
LIST_ENTRY PspJobList


Define Documentation

#define NOEXTAPI
 

Definition at line 32 of file psp.h.

#define PSP_DEFAULT_SCHEDULING_CLASSES   5
 

Definition at line 543 of file psp.h.

Referenced by NtCreateJobObject(), and NtSetInformationJobObject().

#define PSP_MAX_CREATE_PROCESS_NOTIFY   8
 

Definition at line 189 of file psp.h.

Referenced by PspCreateThread(), PspExitProcess(), and PsSetCreateProcessNotifyRoutine().

#define PSP_MAX_CREATE_THREAD_NOTIFY   8
 

Definition at line 206 of file psp.h.

Referenced by PspCreateThread(), PspExitThread(), and PsSetCreateThreadNotifyRoutine().

#define PSP_MAX_LOAD_IMAGE_NOTIFY   8
 

Definition at line 212 of file psp.h.

Referenced by PsCallImageNotifyRoutines(), and PsSetLoadImageNotifyRoutine().

#define PSP_NUMBER_OF_SCHEDULING_CLASSES   10
 

Definition at line 542 of file psp.h.

Referenced by NtSetInformationJobObject(), and PspApplyJobLimitsToProcess().

#define PSP_PROCESS_NONPAGED_CHARGE   (sizeof(EPROCESS))
 

Definition at line 56 of file psp.h.

Referenced by PspInitPhase0().

#define PSP_PROCESS_PAGED_CHARGE   (PAGE_SIZE)
 

Definition at line 55 of file psp.h.

Referenced by PspInitPhase0().

#define PSP_THREAD_NONPAGED_CHARGE   (sizeof(ETHREAD))
 

Definition at line 69 of file psp.h.

Referenced by PspInitPhase0().

#define PSP_THREAD_PAGED_CHARGE   (0)
 

Definition at line 68 of file psp.h.

Referenced by PspInitPhase0().


Typedef Documentation

typedef struct _GETSETCONTEXT GETSETCONTEXT
 

Referenced by NtGetContextThread().

typedef struct _JOB_WORKING_SET_CHANGE_HEAD JOB_WORKING_SET_CHANGE_HEAD
 

typedef struct _JOB_WORKING_SET_CHANGE_RECORD JOB_WORKING_SET_CHANGE_RECORD
 

Referenced by NtSetInformationJobObject().

typedef struct _GETSETCONTEXT * PGETSETCONTEXT
 

Referenced by PspGetSetContextSpecialApc().

typedef struct _JOB_WORKING_SET_CHANGE_HEAD * PJOB_WORKING_SET_CHANGE_HEAD
 

typedef struct _JOB_WORKING_SET_CHANGE_RECORD * PJOB_WORKING_SET_CHANGE_RECORD
 

Referenced by NtSetInformationJobObject().

typedef struct _SYSTEM_DLL PSYSTEM_DLL
 

typedef struct _TERMINATION_PORT * PTERMINATION_PORT
 

Referenced by PspExitThread().

typedef struct _SYSTEM_DLL SYSTEM_DLL
 

typedef struct _TERMINATION_PORT TERMINATION_PORT
 

Referenced by PspExitThread().


Function Documentation

NTSTATUS PspAddProcessToJob PEJOB  Job,
PEPROCESS  Process
 

Definition at line 439 of file psjob.c.

References _EJOB::ActiveProcesses, _EJOB::ActiveProcessLimit, _EJOB::CompletionKey, _EJOB::CompletionPort, _EJOB::Event, ExAcquireFastMutexUnsafe(), ExAcquireResourceExclusive, ExReleaseFastMutexUnsafe(), ExReleaseResource, FALSE, IoSetIoCompletion(), _EPROCESS::Job, _EPROCESS::JobLinks, _EJOB::JobLock, _EPROCESS::JobStatus, KeAttachProcess(), KeDetachProcess(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReadStateEvent(), _EJOB::LimitFlags, _JOB_WORKING_SET_CHANGE_HEAD::Lock, _EJOB::MaximumWorkingSetSize, _EJOB::MinimumWorkingSetSize, MmAdjustWorkingSetSize(), MmAssignProcessToJob(), MmEnforceWorkingSetLimit(), NTSTATUS(), NULL, PAGED_CODE, _EPROCESS::Pcb, _EJOB::ProcessListHead, PS_JOB_STATUS_ACCOUNTING_FOLDED, PS_JOB_STATUS_LAST_REPORT_MEMORY, PS_JOB_STATUS_NEW_PROCESS_REPORTED, PS_JOB_STATUS_NOT_REALLY_ACTIVE, PS_SET_BITS, PS_SET_CLEAR_BITS, PspApplyJobLimitsToProcess(), PspWorkingSetChangeHead, Status, _EJOB::TotalProcesses, TRUE, _EPROCESS::UniqueProcessId, and _EPROCESS::Vm.

Referenced by NtAssignProcessToJobObject(), and PspCreateProcess().

00443 { 00444 00445 NTSTATUS Status; 00446 SIZE_T MinWs,MaxWs; 00447 00448 PAGED_CODE(); 00449 00450 00451 KeEnterCriticalRegion(); 00452 ExAcquireResourceExclusive(&Job->JobLock, TRUE); 00453 00454 InsertTailList(&Job->ProcessListHead,&Process->JobLinks); 00455 00456 // 00457 // Update relevant ADD accounting info. 00458 // 00459 00460 Job->TotalProcesses++; 00461 Job->ActiveProcesses++; 00462 00463 00464 00465 // 00466 // Test for active process count exceeding limit 00467 // 00468 00469 Status = STATUS_SUCCESS; 00470 if ( Job->LimitFlags & JOB_OBJECT_LIMIT_ACTIVE_PROCESS && 00471 Job->ActiveProcesses > Job->ActiveProcessLimit ) { 00472 00473 PS_SET_CLEAR_BITS (&Process->JobStatus, 00474 PS_JOB_STATUS_NOT_REALLY_ACTIVE | PS_JOB_STATUS_ACCOUNTING_FOLDED, 00475 PS_JOB_STATUS_LAST_REPORT_MEMORY); 00476 00477 Job->ActiveProcesses--; 00478 00479 if ( Job->CompletionPort ) { 00480 IoSetIoCompletion( 00481 Job->CompletionPort, 00482 Job->CompletionKey, 00483 NULL, 00484 STATUS_SUCCESS, 00485 JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT, 00486 TRUE 00487 ); 00488 } 00489 00490 Status = STATUS_QUOTA_EXCEEDED; 00491 } 00492 00493 if ( Job->LimitFlags & JOB_OBJECT_LIMIT_JOB_TIME && KeReadStateEvent(&Job->Event) ) { 00494 PS_SET_BITS (&Process->JobStatus, PS_JOB_STATUS_NOT_REALLY_ACTIVE | PS_JOB_STATUS_ACCOUNTING_FOLDED); 00495 00496 Job->ActiveProcesses--; 00497 00498 Status = STATUS_QUOTA_EXCEEDED; 00499 } 00500 00501 if ( Status == STATUS_SUCCESS ) { 00502 00503 PspApplyJobLimitsToProcess(Job,Process); 00504 00505 if ( Process->Job->CompletionPort 00506 && Process->UniqueProcessId 00507 && !(Process->JobStatus & PS_JOB_STATUS_NOT_REALLY_ACTIVE) 00508 && !(Process->JobStatus & PS_JOB_STATUS_NEW_PROCESS_REPORTED)) { 00509 00510 PS_SET_CLEAR_BITS (&Process->JobStatus, 00511 PS_JOB_STATUS_NEW_PROCESS_REPORTED, 00512 PS_JOB_STATUS_LAST_REPORT_MEMORY); 00513 00514 IoSetIoCompletion( 00515 Job->CompletionPort, 00516 Job->CompletionKey, 00517 (PVOID)Process->UniqueProcessId, 00518 STATUS_SUCCESS, 00519 JOB_OBJECT_MSG_NEW_PROCESS, 00520 FALSE 00521 ); 00522 } 00523 00524 } 00525 00526 if ( Job->LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET ) { 00527 MinWs = Job->MinimumWorkingSetSize; 00528 MaxWs = Job->MaximumWorkingSetSize; 00529 } 00530 else { 00531 MinWs = 0; 00532 MaxWs = 0; 00533 } 00534 00535 ExReleaseResource(&Job->JobLock); 00536 00537 KeLeaveCriticalRegion(); 00538 00539 if ( Status == STATUS_SUCCESS ) { 00540 00541 if ( MinWs != 0 && MaxWs != 0 ) { 00542 00543 KeEnterCriticalRegion(); 00544 ExAcquireFastMutexUnsafe(&PspWorkingSetChangeHead.Lock); 00545 00546 KeAttachProcess (&Process->Pcb); 00547 MmAdjustWorkingSetSize(MinWs,MaxWs,FALSE); 00548 00549 // 00550 // call MM to Enable hard workingset 00551 // 00552 00553 MmEnforceWorkingSetLimit(&Process->Vm, TRUE); 00554 00555 KeDetachProcess(); 00556 00557 ExReleaseFastMutexUnsafe(&PspWorkingSetChangeHead.Lock); 00558 KeLeaveCriticalRegion(); 00559 00560 } 00561 else { 00562 MmEnforceWorkingSetLimit(&Process->Vm, FALSE); 00563 } 00564 00565 if ( !MmAssignProcessToJob(Process) ) { 00566 Status = STATUS_QUOTA_EXCEEDED; 00567 } 00568 00569 } 00570 00571 return Status; 00572 }

VOID PspApplyJobLimitsToProcess PEJOB  Job,
PEPROCESS  Process
 

Definition at line 2262 of file psjob.c.

References _EJOB::Affinity, _KPROCESS::Affinity, _EPROCESS::CommitChargeLimit, ExAcquireFastMutexUnsafe(), ExReleaseFastMutexUnsafe(), FALSE, KeSetAffinityThread(), KeSetDisableQuantumProcess(), _EJOB::LimitFlags, MEMORY_PRIORITY_FOREGROUND, _EJOB::MemoryLimitsLock, _MMSUPPORT::MemoryPriority, MmEnforceWorkingSetLimit(), NTSTATUS(), PAGED_CODE, _EPROCESS::Pcb, _EJOB::PriorityClass, _EPROCESS::PriorityClass, _EJOB::ProcessMemoryLimit, PsLockPollOnTimeout, PsLockProcess(), PSP_NUMBER_OF_SCHEDULING_CLASSES, PspJobSchedulingClasses, PsProcessPriorityBackground, PsProcessPriorityForeground, PspUseJobSchedulingClasses, PsSetProcessPriorityByClass(), PsUnlockProcess(), _EJOB::SchedulingClass, Status, _ETHREAD::Tcb, _EPROCESS::ThreadListHead, _KPROCESS::ThreadQuantum, TRUE, and _EPROCESS::Vm.

Referenced by PspAddProcessToJob(), and PspApplyJobLimitsToProcessSet().

02266 { 02267 02268 NTSTATUS Status; 02269 PLIST_ENTRY Next; 02270 PETHREAD Thread; 02271 02272 PAGED_CODE(); 02273 02274 // 02275 // The job object is held exclusive by the caller 02276 // 02277 02278 if ( Job->LimitFlags & JOB_OBJECT_LIMIT_PRIORITY_CLASS ) { 02279 Process->PriorityClass = Job->PriorityClass; 02280 02281 PsSetProcessPriorityByClass( 02282 Process, 02283 Process->Vm.MemoryPriority == MEMORY_PRIORITY_FOREGROUND ? 02284 PsProcessPriorityForeground : PsProcessPriorityBackground 02285 ); 02286 } 02287 02288 if ( Job->LimitFlags & JOB_OBJECT_LIMIT_AFFINITY ) { 02289 02290 // 02291 // the following allows this api to properly if 02292 // called while the exiting process is blocked holding the 02293 // createdeletelock. This can happen during debugger/server 02294 // lpc transactions that occur in pspexitthread 02295 // 02296 02297 Status = PsLockProcess(Process,KeGetPreviousMode(),PsLockPollOnTimeout); 02298 02299 if ( Status == STATUS_SUCCESS ) { 02300 Process->Pcb.Affinity = Job->Affinity; 02301 02302 Next = Process->ThreadListHead.Flink; 02303 02304 while ( Next != &Process->ThreadListHead) { 02305 02306 Thread = (PETHREAD)(CONTAINING_RECORD(Next,ETHREAD,ThreadListEntry)); 02307 KeSetAffinityThread(&Thread->Tcb,Job->Affinity); 02308 Next = Next->Flink; 02309 } 02310 02311 PsUnlockProcess(Process); 02312 } 02313 } 02314 02315 if ( !(Job->LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET) ) { 02316 // 02317 // call MM to disable hard workingset 02318 // 02319 02320 MmEnforceWorkingSetLimit(&Process->Vm, FALSE); 02321 } 02322 02323 ExAcquireFastMutexUnsafe(&Job->MemoryLimitsLock); 02324 if ( Job->LimitFlags & JOB_OBJECT_LIMIT_PROCESS_MEMORY ) { 02325 Process->CommitChargeLimit = Job->ProcessMemoryLimit; 02326 } 02327 else { 02328 Process->CommitChargeLimit = 0; 02329 } 02330 ExReleaseFastMutexUnsafe(&Job->MemoryLimitsLock); 02331 02332 // 02333 // If the process is NOT IDLE Priority Class, and long fixed quantums 02334 // are in use, use the scheduling class stored in the job object for this process 02335 // 02336 if ( Process->PriorityClass != PROCESS_PRIORITY_CLASS_IDLE ) { 02337 02338 if ( PspUseJobSchedulingClasses ) { 02339 Process->Pcb.ThreadQuantum = PspJobSchedulingClasses[Job->SchedulingClass]; 02340 } 02341 // 02342 // if the scheduling class is PSP_NUMBER_OF_SCHEDULING_CLASSES-1, then 02343 // give this process non-preemptive scheduling 02344 // 02345 if ( Job->SchedulingClass == PSP_NUMBER_OF_SCHEDULING_CLASSES-1 ) { 02346 KeSetDisableQuantumProcess(&Process->Pcb,TRUE); 02347 } 02348 else { 02349 KeSetDisableQuantumProcess(&Process->Pcb,FALSE); 02350 } 02351 02352 } 02353 02354 02355 }

VOID PspApplyJobLimitsToProcessSet PEJOB  Job  ) 
 

Definition at line 2210 of file psjob.c.

References ExAllocatePoolWithTag, ExFreePool(), _EPROCESS::JobStatus, _EJOB::LimitFlags, _JOB_WORKING_SET_CHANGE_HEAD::Links, ObGetObjectPointerCount(), ObReferenceObject, PAGED_CODE, PagedPool, _EJOB::ProcessListHead, PS_JOB_STATUS_NOT_REALLY_ACTIVE, PspApplyJobLimitsToProcess(), and PspWorkingSetChangeHead.

Referenced by NtSetInformationJobObject().

02213 { 02214 02215 PLIST_ENTRY Next; 02216 PEPROCESS Process; 02217 PJOB_WORKING_SET_CHANGE_RECORD WsChangeRecord; 02218 02219 PAGED_CODE(); 02220 02221 // 02222 // The job object is held exclusive by the caller 02223 // 02224 02225 Next = Job->ProcessListHead.Flink; 02226 02227 while ( Next != &Job->ProcessListHead) { 02228 02229 Process = (PEPROCESS)(CONTAINING_RECORD(Next,EPROCESS,JobLinks)); 02230 if ( !(Process->JobStatus & PS_JOB_STATUS_NOT_REALLY_ACTIVE) ) { 02231 if ( Job->LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET ) { 02232 WsChangeRecord = ExAllocatePoolWithTag( 02233 PagedPool, 02234 sizeof( *WsChangeRecord ), 02235 'rCsP' 02236 ); 02237 if ( WsChangeRecord ) { 02238 WsChangeRecord->Process = Process; 02239 ObReferenceObject(Process); 02240 // 02241 // Avoid double delete since process could be in delete routine during the above ref 02242 // 02243 if ( ObGetObjectPointerCount(Process) > 1 ) { 02244 InsertTailList(&PspWorkingSetChangeHead.Links,&WsChangeRecord->Links); 02245 } 02246 else { 02247 // 02248 // process is possibly in delete routine waiting to come 02249 // out of job. DON'T Dereference ! 02250 // 02251 ExFreePool(WsChangeRecord); 02252 } 02253 } 02254 } 02255 PspApplyJobLimitsToProcess(Job,Process); 02256 } 02257 Next = Next->Flink; 02258 } 02259 }

NTSTATUS PspAssignPrimaryToken IN PEPROCESS  Process,
IN HANDLE Token  OPTIONAL,
IN PACCESS_TOKEN TokenPointer  OPTIONAL
 

Definition at line 1256 of file ps/security.c.

References KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PsFreeProcessSecurityFields, PsLockProcessSecurityFields, SeExchangePrimaryToken(), SeTokenObjectType, Status, and Token.

Referenced by PspSetPrimaryToken().

01264 : 01265 01266 This function performs the security portions of primary token assignment. 01267 It is expected that the proper access to the process and thread objects, 01268 as well as necessary privilege, has already been established. 01269 01270 A primary token can only be replaced if the process has no threads, or 01271 has one thread. This is because the thread objects point to the primary 01272 token and must have those pointers updated when the primary token is 01273 changed. This is only expected to be necessary at logon time, when 01274 the process is in its infancy and either has zero threads or maybe one 01275 inactive thread. 01276 01277 If the assignment is successful, the old token is dereferenced and the 01278 new one is referenced. 01279 01280 01281 01282 Arguments: 01283 01284 Process - A pointer to the process whose primary token is being 01285 replaced. 01286 01287 Token - The handle value of the token to be assigned as the primary 01288 token. 01289 01290 01291 Return Value: 01292 01293 STATUS_SUCCESS - Indicates the primary token has been successfully 01294 replaced. 01295 01296 STATUS_BAD_TOKEN_TYPE - Indicates the token is not of type TokenPrimary. 01297 01298 STATUS_TOKEN_IN_USE - Indicates the token is already in use by 01299 another process. 01300 01301 Other status may be returned when attempting to reference the token 01302 object. 01303 01304 --*/ 01305 01306 { 01307 NTSTATUS 01308 Status; 01309 01310 PACCESS_TOKEN 01311 NewToken, 01312 OldToken; 01313 01314 KPROCESSOR_MODE 01315 PreviousMode; 01316 01317 01318 if ( TokenPointer == NULL ) 01319 { 01320 PreviousMode = KeGetPreviousMode(); 01321 01322 // 01323 // Reference the specified token, and make sure it can be assigned 01324 // as a primary token. 01325 // 01326 01327 Status = ObReferenceObjectByHandle ( 01328 Token, 01329 TOKEN_ASSIGN_PRIMARY, 01330 SeTokenObjectType(), 01331 PreviousMode, 01332 (PVOID *)&NewToken, 01333 NULL 01334 ); 01335 01336 if ( !NT_SUCCESS(Status) ) { 01337 return Status; 01338 } 01339 } 01340 else 01341 { 01342 NewToken = TokenPointer ; 01343 } 01344 01345 01346 // 01347 // Lock the process security fields. 01348 // 01349 01350 PsLockProcessSecurityFields(); 01351 01352 01353 01354 01355 01356 // 01357 // This routine makes sure the NewToken is suitable for assignment 01358 // as a primary token. 01359 // 01360 01361 Status = SeExchangePrimaryToken( Process, NewToken, &OldToken ); 01362 01363 01364 // 01365 // Release the process security fields 01366 // 01367 01368 PsFreeProcessSecurityFields(); 01369 01370 // 01371 // Free the old token (we don't need it). 01372 // This can't be done while the security fields are locked. 01373 // 01374 01375 if (NT_SUCCESS( Status )) { 01376 01377 ObDereferenceObject( OldToken ); 01378 } 01379 01380 // 01381 // Undo the handle reference 01382 // 01383 01384 if ( TokenPointer == NULL ) 01385 { 01386 ObDereferenceObject( NewToken ); 01387 } 01388 01389 01390 return Status; 01391 }

NTSTATUS PspCaptureTokenFilter KPROCESSOR_MODE  PreviousMode,
PJOBOBJECT_SECURITY_LIMIT_INFORMATION  SecurityLimitInfo,
PPS_JOB_TOKEN_FILTER TokenFilter
 

Definition at line 2680 of file psjob.c.

References ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), Filter, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ProbeForRead, PS_JOB_TOKEN_FILTER, SeCaptureLuidAndAttributesArray(), SeCaptureSidAndAttributesArray(), Status, and TRUE.

Referenced by NtSetInformationJobObject().

02685 { 02686 NTSTATUS Status ; 02687 PPS_JOB_TOKEN_FILTER Filter ; 02688 02689 Filter = ExAllocatePoolWithTag( NonPagedPool, 02690 sizeof( PS_JOB_TOKEN_FILTER ), 02691 'fTsP' ); 02692 02693 if ( !Filter ) 02694 { 02695 *TokenFilter = NULL ; 02696 02697 return STATUS_INSUFFICIENT_RESOURCES ; 02698 } 02699 02700 RtlZeroMemory( Filter, sizeof( PS_JOB_TOKEN_FILTER ) ); 02701 02702 try { 02703 02704 Status = STATUS_SUCCESS ; 02705 02706 // 02707 // Capture Sids to remove 02708 // 02709 02710 if (ARGUMENT_PRESENT( SecurityLimitInfo->SidsToDisable)) { 02711 02712 ProbeForRead( SecurityLimitInfo->SidsToDisable, 02713 sizeof(TOKEN_GROUPS), 02714 sizeof(ULONG) ); 02715 02716 Filter->CapturedGroupCount = SecurityLimitInfo->SidsToDisable->GroupCount; 02717 02718 Status = SeCaptureSidAndAttributesArray( 02719 SecurityLimitInfo->SidsToDisable->Groups, 02720 Filter->CapturedGroupCount, 02721 PreviousMode, 02722 NULL, 0, 02723 NonPagedPool, 02724 TRUE, 02725 &Filter->CapturedGroups, 02726 &Filter->CapturedGroupsLength 02727 ); 02728 02729 } 02730 02731 // 02732 // Capture PrivilegesToDelete 02733 // 02734 02735 if (NT_SUCCESS(Status) && 02736 ARGUMENT_PRESENT(SecurityLimitInfo->PrivilegesToDelete)) { 02737 02738 ProbeForRead( SecurityLimitInfo->PrivilegesToDelete, 02739 sizeof(TOKEN_PRIVILEGES), 02740 sizeof(ULONG) ); 02741 02742 Filter->CapturedPrivilegeCount = SecurityLimitInfo->PrivilegesToDelete->PrivilegeCount; 02743 02744 Status = SeCaptureLuidAndAttributesArray( 02745 SecurityLimitInfo->PrivilegesToDelete->Privileges, 02746 Filter->CapturedPrivilegeCount, 02747 PreviousMode, 02748 NULL, 0, 02749 NonPagedPool, 02750 TRUE, 02751 &Filter->CapturedPrivileges, 02752 &Filter->CapturedPrivilegesLength 02753 ); 02754 02755 } 02756 02757 // 02758 // Capture Restricted Sids 02759 // 02760 02761 if (NT_SUCCESS(Status) && 02762 ARGUMENT_PRESENT(SecurityLimitInfo->RestrictedSids)) { 02763 02764 ProbeForRead( SecurityLimitInfo->RestrictedSids, 02765 sizeof(TOKEN_GROUPS), 02766 sizeof(ULONG) ); 02767 02768 Filter->CapturedSidCount = SecurityLimitInfo->RestrictedSids->GroupCount; 02769 02770 Status = SeCaptureSidAndAttributesArray( 02771 SecurityLimitInfo->RestrictedSids->Groups, 02772 Filter->CapturedSidCount, 02773 PreviousMode, 02774 NULL, 0, 02775 NonPagedPool, 02776 TRUE, 02777 &Filter->CapturedSids, 02778 &Filter->CapturedSidsLength 02779 ); 02780 02781 } 02782 02783 02784 02785 } except(EXCEPTION_EXECUTE_HANDLER) { 02786 02787 Status = GetExceptionCode(); 02788 } // end_try 02789 02790 if ( !NT_SUCCESS( Status ) ) 02791 { 02792 if ( Filter->CapturedSids ) 02793 { 02794 ExFreePool( Filter->CapturedSids ); 02795 } 02796 02797 if ( Filter->CapturedPrivileges ) 02798 { 02799 ExFreePool( Filter->CapturedPrivileges ); 02800 } 02801 02802 if ( Filter->CapturedGroups ) 02803 { 02804 ExFreePool( Filter->CapturedGroups ); 02805 } 02806 02807 ExFreePool( Filter ); 02808 02809 Filter = NULL ; 02810 02811 } 02812 02813 *TokenFilter = Filter ; 02814 02815 return Status ; 02816 02817 02818 }

NTSTATUS PspCreateProcess OUT PHANDLE  ProcessHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN HANDLE ParentProcess  OPTIONAL,
IN BOOLEAN  InheritObjectTable,
IN HANDLE SectionHandle  OPTIONAL,
IN HANDLE DebugPort  OPTIONAL,
IN HANDLE ExceptionPort  OPTIONAL
 

Definition at line 969 of file ps/create.c.

References ASSERT, _SECURITY_SUBJECT_CONTEXT::ClientToken, DebugPort, _EPROCESS::DefaultHardErrorProcessing, EPROCESS, EXCEPTION_EXECUTE_HANDLER, ExInitializeFastMutex, FALSE, _OBJECT_TYPE_INITIALIZER::GenericMapping, _INITIAL_PEB::InheritedAddressSpace, INITIAL_PEB, _EPROCESS::Job, KeActiveProcessors, KeAttachProcess(), KeDetachProcess(), KeInitializeEvent, KeInitializeProcess(), KeInitializeSpinLock(), KeQuerySystemTime(), KPROCESSOR_MODE, L, _EJOB::LimitFlags, LpcPortObjectType, MmCreatePeb(), MmCreateProcessAddressSpace(), MmInitializeProcessAddressSpace(), MmSectionObjectType, MmWorkingSetList, _INITIAL_PEB::Mutant, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObject(), ObDereferenceObject, ObGetObjectSecurity(), ObInheritDeviceMap(), ObInitProcess(), ObInitProcess2(), ObInsertObject(), ObjectAttributes, ObKillProcess(), ObReferenceObject, ObReferenceObjectByHandle(), ObReleaseObjectSecurity(), PAGED_CODE, _EPROCESS::Peb, _SECURITY_SUBJECT_CONTEXT::PrimaryToken, _EPROCESS::PriorityClass, _SECURITY_SUBJECT_CONTEXT::ProcessAuditId, PsActiveProcessHead, PsDereferencePrimaryToken, PsGetCurrentProcess, PsInitialSystemProcess, PsMaximumWorkingSet, PsMinimumWorkingSet, PspActiveProcessMutex, PspAddProcessToJob(), PspDeleteProcessSecurity(), PspForegroundQuantum, PspInheritQuota(), PspInitializeProcessSecurity(), PspInitialSystemProcessHandle, PspMapSystemDll(), PsProcessPriorityBackground, PsProcessType, PsReferencePrimaryToken(), PsSetProcessPriorityByClass(), SeAccessCheck(), SeAuditProcessCreation(), _EPROCESS::SectionBaseAddress, _EPROCESS::SectionHandle, SeDetailedAuditing, _EPROCESS::SessionId, TRUE, _OBJECT_TYPE::TypeInfo, and _EPROCESS::UniqueProcessId.

Referenced by NtCreateProcess(), PsCreateSystemProcess(), and PspInitPhase0().

00982 : 00983 00984 This routine creates and initializes a process object. It implements the 00985 foundation for NtCreateProcess and for system initialization process 00986 creation. 00987 00988 Arguments: 00989 00990 ProcessHandle - Returns the handle for the new process. 00991 00992 DesiredAccess - Supplies the desired access modes to the new process. 00993 00994 ObjectAttributes - Supplies the object attributes of the new process. 00995 00996 ParentProcess - Supplies a handle to the process' parent process. If this 00997 parameter is not specified, then the process has no parent 00998 and is created using the system address space. 00999 01000 SectionHandle - Supplies a handle to a section object to be used to create 01001 the process' address space. If this parameter is not 01002 specified, then the address space is simply a clone of the 01003 parent process' address space. 01004 01005 DebugPort - Supplies a handle to a port object that will be used as the 01006 process' debug port. 01007 01008 ExceptionPort - Supplies a handle to a port object that will be used as the 01009 process' exception port. 01010 01011 Return Value: 01012 01013 TBD 01014 01015 --*/ 01016 01017 { 01018 NTSTATUS st; 01019 PEPROCESS Process; 01020 PEPROCESS Parent; 01021 KAFFINITY Affinity; 01022 KPRIORITY BasePriority; 01023 PVOID SectionToMap; 01024 PVOID ExceptionPortObject; 01025 PVOID DebugPortObject; 01026 ULONG WorkingSetMinimum, WorkingSetMaximum; 01027 HANDLE LocalProcessHandle; 01028 KPROCESSOR_MODE PreviousMode; 01029 HANDLE NewSection; 01030 NTSTATUS DuplicateStatus; 01031 INITIAL_PEB InitialPeb; 01032 BOOLEAN CreatePeb; 01033 ULONG_PTR DirectoryTableBase[2]; 01034 BOOLEAN AccessCheck; 01035 BOOLEAN MemoryAllocated; 01036 PSECURITY_DESCRIPTOR SecurityDescriptor; 01037 SECURITY_SUBJECT_CONTEXT SubjectContext; 01038 NTSTATUS accesst; 01039 NTSTATUS savedst; 01040 BOOLEAN BreakAwayRequested; 01041 PUNICODE_STRING AuditName = NULL ; 01042 01043 PAGED_CODE(); 01044 01045 BreakAwayRequested = FALSE; 01046 CreatePeb = FALSE; 01047 DirectoryTableBase[0] = 0; 01048 DirectoryTableBase[1] = 0; 01049 PreviousMode = KeGetPreviousMode(); 01050 01051 // 01052 // Parent 01053 // 01054 01055 if (ARGUMENT_PRESENT(ParentProcess) ) { 01056 st = ObReferenceObjectByHandle( 01057 ParentProcess, 01058 PROCESS_CREATE_PROCESS, 01059 PsProcessType, 01060 PreviousMode, 01061 (PVOID *)&Parent, 01062 NULL 01063 ); 01064 if ( !NT_SUCCESS(st) ) { 01065 return st; 01066 } 01067 01068 // 01069 // Until CSR understands priority class, don't 01070 // inherit base priority. This just makes things 01071 // worse ! 01072 // 01073 01074 BasePriority = (KPRIORITY) NORMAL_BASE_PRIORITY; 01075 01076 // 01077 //BasePriority = Parent->Pcb.BasePriority; 01078 // 01079 01080 Affinity = Parent->Pcb.Affinity; 01081 01082 WorkingSetMinimum = PsMinimumWorkingSet; // FIXFIX 01083 WorkingSetMaximum = PsMaximumWorkingSet; 01084 01085 01086 } else { 01087 01088 Parent = NULL; 01089 Affinity = KeActiveProcessors; 01090 BasePriority = (KPRIORITY) NORMAL_BASE_PRIORITY; 01091 01092 WorkingSetMinimum = PsMinimumWorkingSet; // FIXFIX 01093 WorkingSetMaximum = PsMaximumWorkingSet; 01094 } 01095 01096 // 01097 // Section 01098 // 01099 01100 if (ARGUMENT_PRESENT(SectionHandle) ) { 01101 01102 // 01103 // Use Object manager tag bits to indicate that breakaway is 01104 // desired 01105 // 01106 01107 if ( (UINT_PTR)SectionHandle & 1 ) { 01108 BreakAwayRequested = TRUE; 01109 } 01110 01111 st = ObReferenceObjectByHandle( 01112 SectionHandle, 01113 SECTION_MAP_EXECUTE, 01114 MmSectionObjectType, 01115 PreviousMode, 01116 (PVOID *)&SectionToMap, 01117 NULL 01118 ); 01119 if ( !NT_SUCCESS(st) ) { 01120 if (Parent) { 01121 ObDereferenceObject(Parent); 01122 } 01123 return st; 01124 } 01125 } else { 01126 SectionToMap = NULL; 01127 } 01128 01129 // 01130 // DebugPort 01131 // 01132 01133 if (ARGUMENT_PRESENT(DebugPort) ) { 01134 st = ObReferenceObjectByHandle ( 01135 DebugPort, 01136 0, 01137 LpcPortObjectType, 01138 KeGetPreviousMode(), 01139 (PVOID *)&DebugPortObject, 01140 NULL 01141 ); 01142 if ( !NT_SUCCESS(st) ) { 01143 if (Parent) { 01144 ObDereferenceObject(Parent); 01145 } 01146 if (SectionToMap) { 01147 ObDereferenceObject(SectionToMap); 01148 } 01149 return st; 01150 } 01151 } else { 01152 DebugPortObject = NULL; 01153 } 01154 01155 // 01156 // ExceptionPort 01157 // 01158 01159 if (ARGUMENT_PRESENT(ExceptionPort) ) { 01160 st = ObReferenceObjectByHandle ( 01161 ExceptionPort, 01162 0, 01163 LpcPortObjectType, 01164 KeGetPreviousMode(), 01165 (PVOID *)&ExceptionPortObject, 01166 NULL 01167 ); 01168 if ( !NT_SUCCESS(st) ) { 01169 if (Parent) { 01170 ObDereferenceObject(Parent); 01171 } 01172 if (SectionToMap) { 01173 ObDereferenceObject(SectionToMap); 01174 } 01175 if (DebugPortObject) { 01176 ObDereferenceObject(DebugPortObject); 01177 } 01178 01179 return st; 01180 } 01181 } else { 01182 ExceptionPortObject = NULL; 01183 } 01184 01185 st = ObCreateObject( 01186 KeGetPreviousMode(), 01187 PsProcessType, 01188 ObjectAttributes, 01189 KeGetPreviousMode(), 01190 NULL, 01191 (ULONG) sizeof(EPROCESS), 01192 0, 01193 0, 01194 (PVOID *)&Process 01195 ); 01196 if ( !NT_SUCCESS( st ) ) { 01197 if (Parent) { 01198 ObDereferenceObject(Parent); 01199 } 01200 if (SectionToMap) { 01201 ObDereferenceObject(SectionToMap); 01202 } 01203 if (DebugPortObject) { 01204 ObDereferenceObject(DebugPortObject); 01205 } 01206 if (ExceptionPortObject) { 01207 ObDereferenceObject(ExceptionPortObject); 01208 } 01209 return st; 01210 } 01211 01212 // 01213 // The process object is created set to NULL. Errors 01214 // That occur after this step cause the process delete 01215 // routine to be entered. 01216 // 01217 // Teardown actions that occur in the process delete routine 01218 // do not need to be performed inline. 01219 // 01220 01221 RtlZeroMemory(Process,sizeof(EPROCESS)); 01222 01223 InitializeListHead(&Process->ThreadListHead); 01224 Process->CreateProcessReported = FALSE; 01225 Process->DebugPort = DebugPortObject; 01226 Process->ExceptionPort = ExceptionPortObject; 01227 01228 01229 PspInheritQuota(Process,Parent); 01230 ObInheritDeviceMap(Process,Parent); 01231 01232 if ( Parent ) { 01233 Process->DefaultHardErrorProcessing = Parent->DefaultHardErrorProcessing; 01234 Process->InheritedFromUniqueProcessId = Parent->UniqueProcessId; 01235 Process->SessionId = Parent->SessionId; 01236 01237 } else { 01238 Process->DefaultHardErrorProcessing = 1; 01239 Process->InheritedFromUniqueProcessId = NULL; 01240 } 01241 01242 Process->ExitStatus = STATUS_PENDING; 01243 Process->LockCount = 1; 01244 Process->LockOwner = NULL; 01245 KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE); 01246 01247 // 01248 // Initialize the security fields of the process 01249 // The parent may be null exactly once (during system init). 01250 // Thereafter, a parent is always required so that we have a 01251 // security context to duplicate for the new process. 01252 // 01253 01254 st = PspInitializeProcessSecurity( Parent, Process ); 01255 01256 if (!NT_SUCCESS(st)) { 01257 01258 01259 if ( Parent ) { 01260 ObDereferenceObject(Parent); 01261 } 01262 01263 if (SectionToMap) { 01264 ObDereferenceObject(SectionToMap); 01265 } 01266 01267 ObDereferenceObject(Process); 01268 return st; 01269 } 01270 01271 // 01272 // Clone parent's object table. 01273 // If no parent (booting) then use the current object table created in 01274 // ObInitSystem. 01275 // 01276 01277 if (Parent) { 01278 01279 01280 // 01281 // Calculate address space 01282 // 01283 // If Parent == PspInitialSystem 01284 // 01285 01286 if (!MmCreateProcessAddressSpace(WorkingSetMinimum, 01287 Process, 01288 &DirectoryTableBase[0])) { 01289 01290 ObDereferenceObject(Parent); 01291 if (SectionToMap) { 01292 ObDereferenceObject(SectionToMap); 01293 } 01294 01295 PspDeleteProcessSecurity( Process ); 01296 01297 ObDereferenceObject(Process); 01298 return STATUS_INSUFFICIENT_RESOURCES; 01299 } 01300 01301 } else { 01302 01303 Process->ObjectTable = PsGetCurrentProcess()->ObjectTable; 01304 01305 DirectoryTableBase[0] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[0]; 01306 DirectoryTableBase[1] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[1]; 01307 01308 // 01309 // Initialize the Working Set Mutex and address creation mutex 01310 // for this "hand built" process. 01311 // Normally, the call the MmInitializeAddressSpace initializes the 01312 // working set mutex, however, in this case, we have already initialized 01313 // the address space and we are now creating a second process using 01314 // the address space of the idle thread. 01315 // 01316 01317 //KeInitializeMutant(&Process->WorkingSetLock, FALSE); 01318 ExInitializeFastMutex(&Process->WorkingSetLock); 01319 01320 ExInitializeFastMutex(&Process->AddressCreationLock); 01321 01322 KeInitializeSpinLock (&Process->HyperSpaceLock); 01323 01324 // 01325 // Initialize virtual address descriptor root. 01326 // 01327 01328 ASSERT (Process->VadRoot == NULL); 01329 Process->Vm.WorkingSetSize = PsGetCurrentProcess()->Vm.WorkingSetSize; 01330 KeQuerySystemTime(&Process->Vm.LastTrimTime); 01331 Process->Vm.VmWorkingSetList = MmWorkingSetList; 01332 } 01333 01334 Process->Vm.MaximumWorkingSetSize = WorkingSetMaximum; 01335 01336 KeInitializeProcess( 01337 &Process->Pcb, 01338 BasePriority, 01339 Affinity, 01340 &DirectoryTableBase[0], 01341 (BOOLEAN)(Process->DefaultHardErrorProcessing & PROCESS_HARDERROR_ALIGNMENT_BIT) 01342 ); 01343 Process->Pcb.ThreadQuantum = PspForegroundQuantum[0]; 01344 Process->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; 01345 01346 if (Parent) { 01347 01348 // 01349 // this used to happen in basesrv\srvtask.c 01350 // 01351 if ( Parent->PriorityClass == PROCESS_PRIORITY_CLASS_IDLE || 01352 Parent->PriorityClass == PROCESS_PRIORITY_CLASS_BELOW_NORMAL ) { 01353 Process->PriorityClass = Parent->PriorityClass; 01354 } 01355 // 01356 // if address space creation worked, then when going through 01357 // delete, we will attach. Of course, attaching means that the kprocess 01358 // must be initialized, so we delay the object stuff till here. 01359 01360 // 01361 st = ObInitProcess(InheritObjectTable ? Parent : (PEPROCESS)NULL,Process); 01362 01363 if (!NT_SUCCESS(st)) { 01364 01365 ObDereferenceObject(Parent); 01366 if (SectionToMap) { 01367 ObDereferenceObject(SectionToMap); 01368 } 01369 01370 PspDeleteProcessSecurity( Process ); 01371 ObDereferenceObject(Process); 01372 return st; 01373 } 01374 } 01375 01376 st = STATUS_SUCCESS; 01377 savedst = STATUS_SUCCESS; 01378 01379 // 01380 // Initialize the process address space 01381 // The address space has four possibilities 01382 // 01383 // 1 - Boot Process. Address space is initialized during 01384 // MmInit. Parent is not specified. 01385 // 01386 // 2 - System Process. Address space is a virgin address 01387 // space that only maps system space. Process is same 01388 // as PspInitialSystemProcess. 01389 // 01390 // 3 - User Process (Cloned Address Space). Address space 01391 // is cloned from the specified process. 01392 // 01393 // 4 - User Process (New Image Address Space). Address space 01394 // is initialized so that it maps the specified section. 01395 // 01396 01397 if ( SectionToMap ) { 01398 // 01399 // User Process (New Image Address Space). Don't specify Process to 01400 // clone, just SectionToMap. 01401 // 01402 01403 st = MmInitializeProcessAddressSpace( 01404 Process, 01405 NULL, 01406 SectionToMap, 01407 &AuditName 01408 ); 01409 01410 ObDereferenceObject(SectionToMap); 01411 ObInitProcess2(Process); 01412 01413 if ( NT_SUCCESS(st) ) { 01414 01415 // 01416 // In order to support relocating executables, the proper status 01417 // (STATUS_IMAGE_NOT_AT_BASE) must be returned, so save it here. 01418 // 01419 01420 savedst = st; 01421 01422 st = PspMapSystemDll(Process,NULL); 01423 } 01424 01425 CreatePeb = TRUE; 01426 01427 goto insert_process; 01428 } 01429 01430 if ( Parent ) { 01431 01432 if ( Parent != PsInitialSystemProcess ) { 01433 01434 Process->SectionBaseAddress = Parent->SectionBaseAddress; 01435 01436 // 01437 // User Process ( Cloned Address Space ). Don't specify section to 01438 // map, just Process to clone. 01439 // 01440 01441 st = MmInitializeProcessAddressSpace( 01442 Process, 01443 Parent, 01444 NULL, 01445 NULL 01446 ); 01447 01448 CreatePeb = TRUE; 01449 01450 } else { 01451 01452 // 01453 // System Process. Don't specify Process to clone or section to map 01454 // 01455 01456 st = MmInitializeProcessAddressSpace( 01457 Process, 01458 NULL, 01459 NULL, 01460 NULL 01461 ); 01462 } 01463 } 01464 01465 insert_process: 01466 01467 // 01468 // If MmInitializeProcessAddressSpace was NOT successful, then 01469 // dereference and exit. 01470 // 01471 01472 if ( !NT_SUCCESS(st) ) { 01473 01474 if (Parent) { 01475 ObDereferenceObject(Parent); 01476 } 01477 01478 KeAttachProcess(&Process->Pcb); 01479 ObKillProcess(FALSE, Process); 01480 KeDetachProcess(); 01481 01482 PspDeleteProcessSecurity( Process ); 01483 ObDereferenceObject(Process); 01484 return st; 01485 } 01486 01487 // 01488 // Reference count of process is not biased here. Each thread in the 01489 // process bias the reference count when they are created. 01490 // 01491 01492 st = ObInsertObject( 01493 Process, 01494 NULL, 01495 DesiredAccess, 01496 0, 01497 (PVOID *)NULL, 01498 &LocalProcessHandle 01499 ); 01500 01501 01502 if ( !NT_SUCCESS(st) ) { 01503 if (Parent) { 01504 ObDereferenceObject(Parent); 01505 } 01506 return st; 01507 } 01508 01509 // 01510 // See if the parent has a job. If so reference the job 01511 // and add the process in. 01512 // 01513 01514 if ( Parent && Parent->Job && !(Parent->Job->LimitFlags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK) ) { 01515 01516 if ( BreakAwayRequested ) { 01517 if ( !(Parent->Job->LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) ) { 01518 st = STATUS_ACCESS_DENIED; 01519 if (Parent) { 01520 ObDereferenceObject(Parent); 01521 } 01522 ZwClose(LocalProcessHandle); 01523 return st; 01524 } 01525 } 01526 else { 01527 ObReferenceObject(Parent->Job); 01528 Process->Job = Parent->Job; 01529 st = PspAddProcessToJob(Process->Job,Process); 01530 if ( !NT_SUCCESS(st) ) { 01531 if (Parent) { 01532 ObDereferenceObject(Parent); 01533 } 01534 ZwClose(LocalProcessHandle); 01535 return st; 01536 } 01537 } 01538 } 01539 01540 PsSetProcessPriorityByClass(Process,PsProcessPriorityBackground); 01541 01542 ExAcquireFastMutex(&PspActiveProcessMutex); 01543 InsertTailList(&PsActiveProcessHead,&Process->ActiveProcessLinks); 01544 ExReleaseFastMutex(&PspActiveProcessMutex); 01545 01546 if (Parent && CreatePeb ) { 01547 01548 // 01549 // For processes created w/ a section, 01550 // a new "virgin" PEB is created. Otherwise, 01551 // for forked processes, uses inherited PEB 01552 // with an updated mutant. 01553 01554 RtlZeroMemory(&InitialPeb, FIELD_OFFSET(INITIAL_PEB, Mutant)); 01555 InitialPeb.Mutant = (HANDLE)(-1); 01556 if ( SectionToMap ) { 01557 01558 try { 01559 Process->Peb = MmCreatePeb(Process,&InitialPeb); 01560 } except(EXCEPTION_EXECUTE_HANDLER) { 01561 ObDereferenceObject(Parent); 01562 ZwClose(LocalProcessHandle); 01563 return GetExceptionCode(); 01564 } 01565 01566 } else { 01567 01568 InitialPeb.InheritedAddressSpace = TRUE; 01569 01570 Process->Peb = Parent->Peb; 01571 01572 ZwWriteVirtualMemory( 01573 LocalProcessHandle, 01574 Process->Peb, 01575 &InitialPeb, 01576 sizeof(INITIAL_PEB), 01577 NULL 01578 ); 01579 } 01580 01581 // 01582 // The new process should have a handle to its 01583 // section. The section is either from the specified 01584 // section, or the section of its parent. 01585 // 01586 01587 if ( ARGUMENT_PRESENT(SectionHandle) ) { 01588 DuplicateStatus = ZwDuplicateObject( 01589 NtCurrentProcess(), 01590 SectionHandle, 01591 LocalProcessHandle, 01592 &NewSection, 01593 0L, 01594 0L, 01595 DUPLICATE_SAME_ACCESS 01596 ); 01597 } else { 01598 01599 DuplicateStatus = ZwDuplicateObject( 01600 ParentProcess, 01601 Parent->SectionHandle, 01602 LocalProcessHandle, 01603 &NewSection, 01604 0L, 01605 0L, 01606 DUPLICATE_SAME_ACCESS 01607 ); 01608 } 01609 01610 if ( NT_SUCCESS(DuplicateStatus) ) { 01611 Process->SectionHandle = NewSection; 01612 } 01613 01614 ObDereferenceObject(Parent); 01615 } 01616 01617 if ( Parent && ParentProcess != PspInitialSystemProcessHandle ) { 01618 01619 st = ObGetObjectSecurity( 01620 Process, 01621 &SecurityDescriptor, 01622 &MemoryAllocated 01623 ); 01624 if ( !NT_SUCCESS(st) ) { 01625 ZwClose(LocalProcessHandle); 01626 return st; 01627 } 01628 01629 // 01630 // Compute the subject security context 01631 // 01632 01633 SubjectContext.ProcessAuditId = Process; 01634 SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process); 01635 SubjectContext.ClientToken = NULL; 01636 AccessCheck = SeAccessCheck( 01637 SecurityDescriptor, 01638 &SubjectContext, 01639 FALSE, 01640 MAXIMUM_ALLOWED, 01641 0, 01642 NULL, 01643 &PsProcessType->TypeInfo.GenericMapping, 01644 PreviousMode, 01645 &Process->GrantedAccess, 01646 &accesst 01647 ); 01648 PsDereferencePrimaryToken(SubjectContext.PrimaryToken); 01649 ObReleaseObjectSecurity( 01650 SecurityDescriptor, 01651 MemoryAllocated 01652 ); 01653 01654 if ( !AccessCheck ) { 01655 Process->GrantedAccess = 0; 01656 } 01657 01658 // 01659 // It does not make any sense to create a process that can not 01660 // do anything to itself 01661 // 01662 01663 Process->GrantedAccess |= (PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_DUP_HANDLE | PROCESS_CREATE_PROCESS | PROCESS_SET_INFORMATION); 01664 01665 } else { 01666 Process->GrantedAccess = PROCESS_ALL_ACCESS; 01667 } 01668 01669 if ( SeDetailedAuditing ) { 01670 01671 SeAuditProcessCreation( Process, Parent, AuditName ); 01672 } 01673 01674 KeQuerySystemTime(&Process->CreateTime); 01675 01676 try { 01677 *ProcessHandle = LocalProcessHandle; 01678 } except(EXCEPTION_EXECUTE_HANDLER) { 01679 return st; 01680 } 01681 01682 if (savedst != STATUS_SUCCESS) { 01683 st = savedst; 01684 } 01685 01686 return st; 01687 01688 }

NTSTATUS PspCreateThread OUT PHANDLE  ThreadHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN HANDLE  ProcessHandle,
IN PEPROCESS  ProcessPointer,
OUT PCLIENT_ID ClientId  OPTIONAL,
IN PCONTEXT ThreadContext  OPTIONAL,
IN PINITIAL_TEB InitialTeb  OPTIONAL,
IN BOOLEAN  CreateSuspended,
IN PKSTART_ROUTINE StartRoutine  OPTIONAL,
IN PVOID  StartContext
 

Definition at line 262 of file ps/create.c.

References ASSERT, _SECURITY_SUBJECT_CONTEXT::ClientToken, _EJOB::CompletionKey, _EJOB::CompletionPort, DbgPrint, ETHREAD, EXCEPTION_EXECUTE_HANDLER, ExChangeHandle(), ExCreateHandle(), ExSetHandleTableOwner, FALSE, _OBJECT_TYPE_INITIALIZER::GenericMapping, _HANDLE_TABLE_ENTRY::GrantedAccess, InitialTeb, IoSetIoCompletion(), _EPROCESS::Job, _EPROCESS::JobStatus, KeEnableApcQueuingThread(), KeInitializeSemaphore(), KeInitializeSpinLock(), KeInitializeThread(), KeQuerySystemTime(), KeReadyThread(), KeResumeThread(), KernelMode, KeSuspendThread(), KPROCESSOR_MODE, L, _EJOB::MemoryLimitsLock, MmCreateKernelStack(), MmCreateTeb(), MmDeleteKernelStack(), MmDeleteTeb(), MmReadClusterSize, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObject(), ObDereferenceObject, ObGetObjectSecurity(), ObInsertObject(), _HANDLE_TABLE_ENTRY::Object, ObjectAttributes, _EPROCESS::ObjectTable, ObReferenceObject, ObReferenceObjectByHandle(), ObReleaseObjectSecurity(), PAGED_CODE, _EPROCESS::Pcb, PERFINFO_PROCESS_CREATE, PERFINFO_THREAD_CREATE, PKSTART_ROUTINE, _SECURITY_SUBJECT_CONTEXT::PrimaryToken, _SECURITY_SUBJECT_CONTEXT::ProcessAuditId, PS_JOB_STATUS_NEW_PROCESS_REPORTED, PS_JOB_STATUS_NOT_REALLY_ACTIVE, PS_SET_BITS, PS_SET_THREAD_CREATE_TIME, PsDereferencePrimaryToken, PsGetCurrentThread, PsInitialSystemProcess, PsLockPollOnTimeout, PsLockProcess(), PSP_INVALID_ID, PSP_MAX_CREATE_PROCESS_NOTIFY, PSP_MAX_CREATE_THREAD_NOTIFY, PspCidTable, PspCreateProcessNotifyRoutine, PspCreateProcessNotifyRoutineCount, PspCreateThreadNotifyRoutine, PspCreateThreadNotifyRoutineCount, PspInitializeThreadSecurity(), PspMarkProcessIdValid(), PsProcessType, PspSystemThreadStartup(), PspUserThreadStartup(), PsReferencePrimaryToken(), PsThreadType, PsUnlockProcess(), SeAccessCheck(), ThreadContext, ThreadHandle, _EPROCESS::ThreadListHead, TRUE, _OBJECT_TYPE::TypeInfo, _EPROCESS::UniqueProcessId, and VOID().

Referenced by NtCreateThread(), and PsCreateSystemThread().

00278 : 00279 00280 This routine creates and initializes a thread object. It implements the 00281 foundation for NtCreateThread and for PsCreateSystemThread. 00282 00283 Arguments: 00284 00285 ThreadHandle - Returns the handle for the new thread. 00286 00287 DesiredAccess - Supplies the desired access modes to the new thread. 00288 00289 ObjectAttributes - Supplies the object attributes of the new thread. 00290 00291 ProcessHandle - Supplies a handle to the process that the thread is being 00292 created within. 00293 00294 ClientId - Returns the CLIENT_ID of the new thread. 00295 00296 ThreadContext - Supplies a pointer to a context frame that represents the 00297 initial user-mode context for a user-mode thread. The absence 00298 of this parameter indicates that a system thread is being 00299 created. 00300 00301 InitialTeb - Supplies the contents of certain fields for the new threads 00302 TEB. This parameter is only examined if both a trap and 00303 exception frame were specified. 00304 00305 CreateSuspended - Supplies a value that controls whether or not a user-mode 00306 thread is created in a suspended state. 00307 00308 StartRoutine - Supplies the address of the system thread start routine. 00309 00310 StartContext - Supplies context for a system thread start routine. 00311 00312 Return Value: 00313 00314 TBD 00315 00316 --*/ 00317 00318 { 00319 00320 HANDLE_TABLE_ENTRY CidEntry; 00321 NTSTATUS st; 00322 PETHREAD Thread; 00323 PEPROCESS Process; 00324 PVOID KernelStack; 00325 PTEB Teb; 00326 INITIAL_TEB ITeb; 00327 KPROCESSOR_MODE PreviousMode; 00328 HANDLE LocalThreadHandle; 00329 BOOLEAN AccessCheck; 00330 BOOLEAN MemoryAllocated; 00331 PSECURITY_DESCRIPTOR SecurityDescriptor; 00332 SECURITY_SUBJECT_CONTEXT SubjectContext; 00333 NTSTATUS accesst; 00334 LARGE_INTEGER NullTime; 00335 LARGE_INTEGER CreateTime; 00336 BOOLEAN NeedToFixProcessId = FALSE; 00337 00338 PAGED_CODE(); 00339 00340 NullTime.LowPart = 0; 00341 NullTime.HighPart = 0; 00342 00343 if ( StartRoutine ) { 00344 PreviousMode = KernelMode; 00345 } else { 00346 PreviousMode = KeGetPreviousMode(); 00347 } 00348 00349 Teb = NULL; 00350 00351 Thread = NULL; 00352 Process = NULL; 00353 KernelStack = NULL; 00354 00355 if ( ProcessHandle ) { 00356 // 00357 // Process object reference count is biased by one for each thread. 00358 // This accounts for the pointer given to the kernel that remains 00359 // in effect until the thread terminates (and becomes signaled) 00360 // 00361 00362 st = ObReferenceObjectByHandle( 00363 ProcessHandle, 00364 PROCESS_CREATE_THREAD, 00365 PsProcessType, 00366 PreviousMode, 00367 (PVOID *)&Process, 00368 NULL 00369 ); 00370 } 00371 else { 00372 if ( StartRoutine ) { 00373 ObReferenceObject(ProcessPointer); 00374 Process = ProcessPointer; 00375 st = STATUS_SUCCESS; 00376 } 00377 else { 00378 st = STATUS_INVALID_HANDLE; 00379 } 00380 } 00381 if ( !NT_SUCCESS(st) ) { 00382 return st; 00383 } 00384 00385 // 00386 // If the previous mode is user and the target process is the system 00387 // process, then the operation cannot be performed. 00388 // 00389 00390 if ((PreviousMode != KernelMode) && (Process == PsInitialSystemProcess)) { 00391 ObDereferenceObject(Process); 00392 return STATUS_INVALID_HANDLE; 00393 } 00394 00395 st = ObCreateObject( 00396 PreviousMode, 00397 PsThreadType, 00398 ObjectAttributes, 00399 PreviousMode, 00400 NULL, 00401 (ULONG) sizeof(ETHREAD), 00402 0, 00403 0, 00404 (PVOID *)&Thread 00405 ); 00406 if ( !NT_SUCCESS( st ) ) { 00407 ObDereferenceObject(Process); 00408 return st; 00409 } 00410 00411 RtlZeroMemory(Thread,sizeof(ETHREAD)); 00412 CidEntry.Object = Thread; 00413 CidEntry.GrantedAccess = 0; 00414 Thread->Cid.UniqueThread = ExCreateHandle(PspCidTable,&CidEntry); 00415 00416 if ( !Thread->Cid.UniqueThread ) { 00417 ObDereferenceObject(Process); 00418 ObDereferenceObject(Thread); 00419 return( STATUS_INSUFFICIENT_RESOURCES ); 00420 } 00421 00422 // 00423 // Initialize Mm 00424 // 00425 00426 Thread->ReadClusterSize = MmReadClusterSize; 00427 00428 // 00429 // Initialize LPC 00430 // 00431 00432 KeInitializeSemaphore(&Thread->LpcReplySemaphore,0L,1L); 00433 InitializeListHead( &Thread->LpcReplyChain ); 00434 00435 // 00436 // Initialize Io 00437 // 00438 00439 InitializeListHead(&Thread->IrpList); 00440 00441 // 00442 // Initialize Registry 00443 // 00444 00445 InitializeListHead(&Thread->PostBlockList); 00446 00447 00448 // 00449 // Initialize Security 00450 // 00451 00452 PspInitializeThreadSecurity( Process, Thread ); 00453 00454 // 00455 00456 InitializeListHead(&Thread->TerminationPortList); 00457 00458 KeInitializeSpinLock(&Thread->ActiveTimerListLock); 00459 InitializeListHead(&Thread->ActiveTimerListHead); 00460 00461 // 00462 // Allocate Kernel Stack 00463 // 00464 00465 KernelStack = MmCreateKernelStack(FALSE); 00466 if ( !KernelStack ) { 00467 ObDereferenceObject(Process); 00468 ObDereferenceObject(Thread); 00469 00470 return STATUS_UNSUCCESSFUL; 00471 } 00472 00473 st = PsLockProcess(Process,KernelMode,PsLockPollOnTimeout); 00474 if ( st != STATUS_SUCCESS ) { 00475 MmDeleteKernelStack(KernelStack, FALSE); 00476 ObDereferenceObject(Process); 00477 ObDereferenceObject(Thread); 00478 00479 return STATUS_PROCESS_IS_TERMINATING; 00480 } 00481 00482 00483 // 00484 // If the process does not have its part of the client id, then 00485 // assign one 00486 // 00487 00488 if ( !Process->UniqueProcessId ) { 00489 CidEntry.Object = (PVOID)PSP_INVALID_ID; 00490 CidEntry.GrantedAccess = 0; 00491 Process->UniqueProcessId = ExCreateHandle(PspCidTable,&CidEntry); 00492 ExSetHandleTableOwner( Process->ObjectTable, Process->UniqueProcessId ); 00493 if (!Process->UniqueProcessId) { 00494 PsUnlockProcess(Process); 00495 00496 MmDeleteKernelStack(KernelStack, FALSE); 00497 ObDereferenceObject(Process); 00498 ObDereferenceObject(Thread); 00499 00500 return STATUS_UNSUCCESSFUL; 00501 } 00502 00503 NeedToFixProcessId = TRUE; 00504 00505 PERFINFO_PROCESS_CREATE(Process); 00506 } 00507 Thread->Cid.UniqueProcess = Process->UniqueProcessId; 00508 00509 Thread->ThreadsProcess = Process; 00510 00511 if (ARGUMENT_PRESENT(ThreadContext)) { 00512 00513 // 00514 // FIX. Handle exception on bad context 00515 // 00516 00517 // 00518 // User-mode thread 00519 // 00520 00521 try { 00522 00523 ITeb = *InitialTeb; 00524 00525 Teb = MmCreateTeb ( Process, &ITeb, &Thread->Cid ); 00526 00527 // 00528 // Initialize kernel thread object for user mode thread. 00529 // 00530 00531 Thread->StartAddress = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ThreadContext); 00532 #if defined(_IA64_) 00533 Thread->Win32StartAddress = (PVOID)ThreadContext->IntT0; 00534 #endif // _IA64_ 00535 00536 #if defined(_X86_) 00537 Thread->Win32StartAddress = (PVOID)ThreadContext->Eax; 00538 #endif // _X86_ 00539 00540 #if defined(_MIPS_) 00541 Thread->Win32StartAddress = (PVOID)ThreadContext->XIntA0; 00542 #endif // _MIPS_ 00543 00544 #if defined(_ALPHA_) 00545 Thread->Win32StartAddress = (PVOID)ThreadContext->IntA0; 00546 #endif // _ALPHA_ 00547 00548 #if defined(_PPC_) 00549 Thread->Win32StartAddress = (PVOID)ThreadContext->Gpr3; 00550 #endif // _PPC_ 00551 00552 (VOID) 00553 KeInitializeThread( 00554 &Thread->Tcb, 00555 KernelStack, 00556 PspUserThreadStartup, 00557 (PKSTART_ROUTINE)NULL, 00558 (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ThreadContext), 00559 ThreadContext, 00560 Teb, 00561 &Process->Pcb 00562 ); 00563 00564 } except(EXCEPTION_EXECUTE_HANDLER) { 00565 00566 00567 if ( Teb ) { 00568 MmDeleteTeb(Process, Teb); 00569 } 00570 00571 PsUnlockProcess(Process); 00572 00573 MmDeleteKernelStack(KernelStack, FALSE); 00574 Thread->Tcb.InitialStack = NULL; 00575 ObDereferenceObject(Thread); 00576 00577 return GetExceptionCode(); 00578 } 00579 00580 } else { 00581 00582 // 00583 // Initialize kernel thread object for kernel mode thread. 00584 // 00585 00586 Thread->StartAddress = (PVOID)StartRoutine; 00587 KeInitializeThread( 00588 &Thread->Tcb, 00589 KernelStack, 00590 PspSystemThreadStartup, 00591 StartRoutine, 00592 StartContext, 00593 NULL, 00594 NULL, 00595 &Process->Pcb 00596 ); 00597 00598 } 00599 00600 InsertTailList(&Process->ThreadListHead,&Thread->ThreadListEntry); 00601 00602 if ( NeedToFixProcessId ) { 00603 00604 // 00605 // Now that the thread is really there and will rundown through exit, 00606 // open up the process id 00607 // 00608 00609 ExChangeHandle(PspCidTable, Thread->Cid.UniqueProcess, PspMarkProcessIdValid, (ULONG_PTR)Process); 00610 00611 if (PspCreateProcessNotifyRoutineCount != 0) { 00612 ULONG i; 00613 00614 for (i=0; i<PSP_MAX_CREATE_PROCESS_NOTIFY; i++) { 00615 if (PspCreateProcessNotifyRoutine[i] != NULL) { 00616 (*PspCreateProcessNotifyRoutine[i])( Process->InheritedFromUniqueProcessId, 00617 Process->UniqueProcessId, 00618 TRUE 00619 ); 00620 } 00621 } 00622 } 00623 00624 00625 } 00626 00627 // 00628 // If the process has a job with a completion port, 00629 // AND if the process is really considered to be in the Job, AND 00630 // the process has not reported, report in 00631 // 00632 // This should really be done in add process to job, but can't 00633 // in this path because the process's ID isn't assigned until this point 00634 // in time 00635 // 00636 00637 if ( Process->Job 00638 && Process->Job->CompletionPort 00639 && !(Process->JobStatus & PS_JOB_STATUS_NOT_REALLY_ACTIVE) 00640 && !(Process->JobStatus & PS_JOB_STATUS_NEW_PROCESS_REPORTED)) { 00641 00642 PS_SET_BITS (&Process->JobStatus, PS_JOB_STATUS_NEW_PROCESS_REPORTED); 00643 00644 ExAcquireFastMutex(&Process->Job->MemoryLimitsLock); 00645 if (Process->Job->CompletionPort != NULL) { 00646 IoSetIoCompletion( 00647 Process->Job->CompletionPort, 00648 Process->Job->CompletionKey, 00649 (PVOID)Process->UniqueProcessId, 00650 STATUS_SUCCESS, 00651 JOB_OBJECT_MSG_NEW_PROCESS, 00652 FALSE 00653 ); 00654 } 00655 ExReleaseFastMutex(&Process->Job->MemoryLimitsLock); 00656 } 00657 00658 PERFINFO_THREAD_CREATE(Thread, InitialTeb); 00659 00660 // 00661 // Notify registered callout routines of thread creation. 00662 // 00663 00664 if (PspCreateThreadNotifyRoutineCount != 0) { 00665 ULONG i; 00666 00667 for (i=0; i<PSP_MAX_CREATE_THREAD_NOTIFY; i++) { 00668 if (PspCreateThreadNotifyRoutine[i] != NULL) { 00669 (*PspCreateThreadNotifyRoutine[i])( Thread->Cid.UniqueProcess, 00670 Thread->Cid.UniqueThread, 00671 TRUE 00672 ); 00673 } 00674 } 00675 } 00676 00677 (VOID) KeEnableApcQueuingThread(&Thread->Tcb); 00678 00679 if (CreateSuspended) { 00680 (VOID) KeSuspendThread(&Thread->Tcb); 00681 } 00682 00683 00684 PsUnlockProcess(Process); 00685 00686 // 00687 // Failures that occur after this point cause the thread to 00688 // go through PspExitThread 00689 // 00690 00691 // 00692 // Reference count of thread is biased once for itself, and 00693 // once to account for its Cid Handle 00694 // 00695 // Note: 00696 // if this fails we should do punt so we only have one 00697 // cleanup path that really goes through PspExitThread ? 00698 // Remember to free spin locks, cid... 00699 // 00700 00701 ObReferenceObject(Thread); 00702 ObReferenceObject(Thread); 00703 ObReferenceObject(Thread); 00704 00705 st = ObInsertObject( 00706 Thread, 00707 NULL, 00708 DesiredAccess, 00709 0, 00710 (PVOID *)NULL, 00711 &LocalThreadHandle 00712 ); 00713 00714 if ( !NT_SUCCESS(st) ) { 00715 00716 // 00717 // The insert failed. Terminate the thread. 00718 // 00719 00720 // 00721 // This trick us used so that Dbgk doesn't report 00722 // events for dead threads 00723 // 00724 00725 Thread->DeadThread = TRUE; 00726 Thread->HasTerminated = TRUE; 00727 00728 if (CreateSuspended) { 00729 (VOID) KeResumeThread(&Thread->Tcb); 00730 } 00731 00732 } else { 00733 00734 try { 00735 00736 *ThreadHandle = LocalThreadHandle; 00737 if (ARGUMENT_PRESENT(ClientId)) { 00738 *ClientId = Thread->Cid; 00739 } 00740 } except(EXCEPTION_EXECUTE_HANDLER) { 00741 00742 if ( GetExceptionCode() == STATUS_QUOTA_EXCEEDED ) { 00743 00744 // 00745 // This trick us used so that Dbgk doesn't report 00746 // events for dead threads 00747 // 00748 00749 Thread->DeadThread = TRUE; 00750 Thread->HasTerminated = TRUE; 00751 00752 if (CreateSuspended) { 00753 (VOID) KeResumeThread(&Thread->Tcb); 00754 } 00755 KeReadyThread(&Thread->Tcb); 00756 ObDereferenceObject(Thread); 00757 ZwClose(LocalThreadHandle); 00758 return GetExceptionCode(); 00759 } 00760 } 00761 } 00762 00763 KeQuerySystemTime(&CreateTime); 00764 ASSERT ((CreateTime.HighPart & 0xf0000000) == 0); 00765 PS_SET_THREAD_CREATE_TIME(Thread, CreateTime); 00766 00767 if ( !Thread->DeadThread ) { 00768 st = ObGetObjectSecurity( 00769 Thread, 00770 &SecurityDescriptor, 00771 &MemoryAllocated 00772 ); 00773 if ( !NT_SUCCESS(st) ) { 00774 // 00775 // This trick us used so that Dbgk doesn't report 00776 // events for dead threads 00777 // 00778 00779 Thread->DeadThread = TRUE; 00780 Thread->HasTerminated = TRUE; 00781 00782 if (CreateSuspended) { 00783 (VOID) KeResumeThread(&Thread->Tcb); 00784 } 00785 KeReadyThread(&Thread->Tcb); 00786 ObDereferenceObject(Thread); 00787 ZwClose(LocalThreadHandle); 00788 return st; 00789 } 00790 00791 // 00792 // Compute the subject security context 00793 // 00794 00795 SubjectContext.ProcessAuditId = Process; 00796 SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process); 00797 SubjectContext.ClientToken = NULL; 00798 00799 AccessCheck = SeAccessCheck( 00800 SecurityDescriptor, 00801 &SubjectContext, 00802 FALSE, 00803 MAXIMUM_ALLOWED, 00804 0, 00805 NULL, 00806 &PsThreadType->TypeInfo.GenericMapping, 00807 PreviousMode, 00808 &Thread->GrantedAccess, 00809 &accesst 00810 ); 00811 PsDereferencePrimaryToken(SubjectContext.PrimaryToken); 00812 ObReleaseObjectSecurity( 00813 SecurityDescriptor, 00814 MemoryAllocated 00815 ); 00816 00817 if ( !AccessCheck ) { 00818 Thread->GrantedAccess = 0; 00819 } 00820 00821 if ( (Thread->GrantedAccess & THREAD_SET_THREAD_TOKEN) == 0 ) 00822 { 00823 DbgPrint( "SE: Warning, new thread does not have SET_THREAD_TOKEN for itself\n" ); 00824 DbgPrint( "SE: Check that thread %x.%x isn't in some weird state\n", 00825 PsGetCurrentThread()->Cid.UniqueProcess, 00826 PsGetCurrentThread()->Cid.UniqueThread ); 00827 00828 } 00829 00830 Thread->GrantedAccess |= (THREAD_TERMINATE | THREAD_SET_INFORMATION | THREAD_QUERY_INFORMATION); 00831 00832 } 00833 else { 00834 Thread->GrantedAccess = THREAD_ALL_ACCESS; 00835 } 00836 KeReadyThread(&Thread->Tcb); 00837 ObDereferenceObject(Thread); 00838 00839 return st; 00840 }

VOID PspDeleteLdt IN PEPROCESS  Process  ) 
 

Definition at line 140 of file alpha/psldt.c.

Referenced by PspProcessDelete().

00145 : 00146 00147 This is a stub for the Ldt delete routine 00148 00149 Arguments: 00150 00151 Process -- Supplies a pointer to the process 00152 00153 Return Value: 00154 00155 None 00156 --*/ 00157 { 00158 }

VOID PspDeleteProcessSecurity IN PEPROCESS  Process  ) 
 

Definition at line 1206 of file ps/security.c.

References NULL, and SeDeassignPrimaryToken().

Referenced by PspCreateProcess(), and PspProcessDelete().

01212 : 01213 01214 This function cleans up a process's security fields as part of process 01215 deletion. It is assumed no other references to the process can occur 01216 during or after a call to this routine. This enables us to reference 01217 the process security fields without acquiring the lock protecting those 01218 fields. 01219 01220 NOTE: It may be desirable to add auditing capability to this routine 01221 at some point. 01222 01223 01224 Arguments: 01225 01226 Process - A pointer to the process being deleted. 01227 01228 01229 Return Value: 01230 01231 None. 01232 01233 --*/ 01234 01235 { 01236 01237 01238 01239 01240 // 01241 // If we are deleting a process that didn't successfully complete 01242 // process initialization, then there may be no token associated 01243 // with it yet. 01244 // 01245 01246 if (ARGUMENT_PRESENT(Process->Token)) { 01247 SeDeassignPrimaryToken( Process ); 01248 Process->Token = NULL; 01249 } 01250 01251 return; 01252 }

VOID PspDeleteThreadSecurity IN PETHREAD  Thread  ) 
 

Definition at line 1436 of file ps/security.c.

References ExFreePool(), FALSE, NULL, and ObDereferenceObject.

Referenced by PspThreadDelete().

01442 : 01443 01444 This function cleans up a thread's security fields as part of thread 01445 deletion. It is assumed no other references to the thread can occur 01446 during or after a call to this routine, so no locking is necessary 01447 to access the thread security fields. 01448 01449 01450 Arguments: 01451 01452 Thread - A pointer to the thread being deleted. 01453 01454 01455 Return Value: 01456 01457 None. 01458 01459 --*/ 01460 01461 { 01462 01463 // 01464 // clean-up client information, if there is any. 01465 // 01466 01467 if ( Thread->ActiveImpersonationInfo ) { 01468 ObDereferenceObject( Thread->ImpersonationInfo->Token ); 01469 } 01470 01471 if ( Thread->ImpersonationInfo ) { 01472 ExFreePool( Thread->ImpersonationInfo ); 01473 Thread->ActiveImpersonationInfo = FALSE; 01474 Thread->ImpersonationInfo = NULL; 01475 } 01476 01477 return; 01478 01479 }

VOID PspDeleteVdmObjects IN PEPROCESS  Process  ) 
 

Definition at line 58 of file alpha/psvdm.c.

Referenced by PspProcessDelete().

00063 : 00064 00065 This is a stub for the Vdm Objects delete routine 00066 00067 Arguments: 00068 00069 Process -- Supplies a pointer to the process 00070 00071 Return Value: 00072 00073 None 00074 --*/ 00075 { 00076 UNREFERENCED_PARAMETER(Process); 00077 } }

VOID PspDereferenceQuota IN PEPROCESS  Process  ) 
 

Definition at line 494 of file psquota.c.

References ExFreePool(), MiReturnPageFileQuota(), NonPagedPool, PagedPool, PsReturnPoolQuota(), _EPROCESS_QUOTA_BLOCK::QuotaLock, and _EPROCESS_QUOTA_BLOCK::ReferenceCount.

Referenced by PspProcessDelete().

00497 { 00498 PEPROCESS_QUOTA_BLOCK QuotaBlock; 00499 KIRQL OldIrql; 00500 00501 QuotaBlock = Process->QuotaBlock; 00502 00503 PsReturnPoolQuota(Process,NonPagedPool,Process->QuotaPoolUsage[NonPagedPool]); 00504 PsReturnPoolQuota(Process,PagedPool,Process->QuotaPoolUsage[PagedPool]); 00505 MiReturnPageFileQuota(Process->PagefileUsage,Process); 00506 00507 ExAcquireSpinLock(&QuotaBlock->QuotaLock,&OldIrql); 00508 00509 QuotaBlock->ReferenceCount--; 00510 if ( QuotaBlock->ReferenceCount == 0 ) { 00511 ExReleaseSpinLock(&QuotaBlock->QuotaLock,OldIrql); 00512 ExFreePool(QuotaBlock); 00513 } 00514 else { 00515 ExReleaseSpinLock(&QuotaBlock->QuotaLock,OldIrql); 00516 } 00517 }

VOID PspExitNormalApc IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2
 

Definition at line 631 of file psdelete.c.

References ExFreePool(), IS_SYSTEM_THREAD, KeBugCheck(), KeForceResumeThread(), KeInitializeApc(), KeInsertQueueApc(), _KAPC::NormalContext, NTSTATUS(), NULL, OriginalApcEnvironment, PAGED_CODE, PsExitSpecialApc(), PsGetCurrentThread, PspExitNormalApc(), PspExitThread(), _ETHREAD::Tcb, and UserMode.

Referenced by PspExitNormalApc(), and PspTerminateThreadByPointer().

00637 { 00638 PETHREAD Thread; 00639 PKAPC ExitApc; 00640 NTSTATUS ExitStatus; 00641 00642 PAGED_CODE(); 00643 00644 Thread = PsGetCurrentThread(); 00645 00646 if ( SystemArgument2 ) { 00647 KeBugCheck(0x12345678); 00648 } 00649 00650 ExitApc = (PKAPC) SystemArgument1; 00651 00652 if ( IS_SYSTEM_THREAD(Thread) ) { 00653 ExitStatus = (NTSTATUS)((LONG_PTR)ExitApc->NormalContext); 00654 ExFreePool(ExitApc); 00655 PspExitThread(ExitStatus); 00656 } else { 00657 00658 KeInitializeApc( 00659 ExitApc, 00660 &Thread->Tcb, 00661 OriginalApcEnvironment, 00662 PsExitSpecialApc, 00663 NULL, 00664 PspExitNormalApc, 00665 UserMode, 00666 NormalContext 00667 ); 00668 00669 if ( !KeInsertQueueApc(ExitApc,ExitApc,(PVOID) 1, 2) ) { 00670 ExFreePool(ExitApc); 00671 } 00672 00673 KeForceResumeThread(&Thread->Tcb); 00674 } 00675 }

VOID PspExitProcess IN BOOLEAN  TrimAddressSpace,
IN PEPROCESS  Process
 

Definition at line 1232 of file psdelete.c.

References FALSE, IoSetIoCompletion(), KeMaximumIncrement, KeSetProcess(), MmCleanProcessAddressSpace(), NULL, ObDereferenceObject, ObKillProcess(), PAGED_CODE, PoRundownProcess, PS_JOB_STATUS_EXIT_PROCESS_REPORTED, PS_JOB_STATUS_LAST_REPORT_MEMORY, PS_JOB_STATUS_NOT_REALLY_ACTIVE, PS_SET_CLEAR_BITS, PSP_MAX_CREATE_PROCESS_NOTIFY, PspActiveProcessMutex, PspCreateProcessNotifyRoutine, PspCreateProcessNotifyRoutineCount, and TRUE.

Referenced by PspExitThread(), and PspProcessDelete().

01236 { 01237 01238 ULONG ActualTime; 01239 01240 PAGED_CODE(); 01241 01242 if (!Process->ExitProcessCalled && PspCreateProcessNotifyRoutineCount != 0) { 01243 ULONG i; 01244 01245 for (i=0; i<PSP_MAX_CREATE_PROCESS_NOTIFY; i++) { 01246 if (PspCreateProcessNotifyRoutine[i] != NULL) { 01247 (*PspCreateProcessNotifyRoutine[i])( Process->InheritedFromUniqueProcessId, 01248 Process->UniqueProcessId, 01249 FALSE 01250 ); 01251 } 01252 } 01253 } 01254 01255 Process->ExitProcessCalled = TRUE; 01256 01257 PoRundownProcess(Process); 01258 01259 // 01260 // If the process is on the active list, remove it now. Must be done before ObKill 01261 // due to code in ex\sysinfo that references the process through the handle table 01262 // 01263 01264 if ( Process->ActiveProcessLinks.Flink != NULL && 01265 Process->ActiveProcessLinks.Blink != NULL ) { 01266 01267 ExAcquireFastMutex(&PspActiveProcessMutex); 01268 RemoveEntryList(&Process->ActiveProcessLinks); 01269 Process->ActiveProcessLinks.Flink = NULL; 01270 Process->ActiveProcessLinks.Blink = NULL; 01271 ExReleaseFastMutex(&PspActiveProcessMutex); 01272 01273 } 01274 01275 if (Process->SecurityPort) { 01276 01277 ObDereferenceObject(Process->SecurityPort); 01278 01279 Process->SecurityPort = NULL ; 01280 } 01281 01282 01283 if ( TrimAddressSpace ) { 01284 01285 01286 // 01287 // If the current process has previously set the timer resolution, 01288 // then reset it. 01289 // 01290 01291 if (Process->SetTimerResolution != FALSE) { 01292 ZwSetTimerResolution(KeMaximumIncrement, FALSE, &ActualTime); 01293 } 01294 01295 if ( Process->Job 01296 && Process->Job->CompletionPort 01297 && !(Process->JobStatus & PS_JOB_STATUS_NOT_REALLY_ACTIVE) 01298 && !(Process->JobStatus & PS_JOB_STATUS_EXIT_PROCESS_REPORTED)) { 01299 01300 ULONG_PTR ExitMessageId; 01301 01302 switch (Process->ExitStatus) { 01303 case STATUS_GUARD_PAGE_VIOLATION : 01304 case STATUS_DATATYPE_MISALIGNMENT : 01305 case STATUS_BREAKPOINT : 01306 case STATUS_SINGLE_STEP : 01307 case STATUS_ACCESS_VIOLATION : 01308 case STATUS_IN_PAGE_ERROR : 01309 case STATUS_ILLEGAL_INSTRUCTION : 01310 case STATUS_NONCONTINUABLE_EXCEPTION : 01311 case STATUS_INVALID_DISPOSITION : 01312 case STATUS_ARRAY_BOUNDS_EXCEEDED : 01313 case STATUS_FLOAT_DENORMAL_OPERAND : 01314 case STATUS_FLOAT_DIVIDE_BY_ZERO : 01315 case STATUS_FLOAT_INEXACT_RESULT : 01316 case STATUS_FLOAT_INVALID_OPERATION : 01317 case STATUS_FLOAT_OVERFLOW : 01318 case STATUS_FLOAT_STACK_CHECK : 01319 case STATUS_FLOAT_UNDERFLOW : 01320 case STATUS_INTEGER_DIVIDE_BY_ZERO : 01321 case STATUS_INTEGER_OVERFLOW : 01322 case STATUS_PRIVILEGED_INSTRUCTION : 01323 case STATUS_STACK_OVERFLOW : 01324 case STATUS_CONTROL_C_EXIT : 01325 case STATUS_FLOAT_MULTIPLE_FAULTS : 01326 case STATUS_FLOAT_MULTIPLE_TRAPS : 01327 case STATUS_REG_NAT_CONSUMPTION : 01328 ExitMessageId = JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS; 01329 break; 01330 default: 01331 ExitMessageId = JOB_OBJECT_MSG_EXIT_PROCESS; 01332 break; 01333 } 01334 01335 PS_SET_CLEAR_BITS (&Process->JobStatus, 01336 PS_JOB_STATUS_EXIT_PROCESS_REPORTED, 01337 PS_JOB_STATUS_LAST_REPORT_MEMORY); 01338 01339 ExAcquireFastMutex(&Process->Job->MemoryLimitsLock); 01340 01341 if (Process->Job->CompletionPort != NULL) { 01342 IoSetIoCompletion( 01343 Process->Job->CompletionPort, 01344 Process->Job->CompletionKey, 01345 (PVOID)Process->UniqueProcessId, 01346 STATUS_SUCCESS, 01347 ExitMessageId, 01348 FALSE 01349 ); 01350 } 01351 ExReleaseFastMutex(&Process->Job->MemoryLimitsLock); 01352 } 01353 01354 } else { 01355 KeSetProcess(&Process->Pcb,0,FALSE); 01356 ObKillProcess(FALSE, Process); 01357 MmCleanProcessAddressSpace(); 01358 } 01359 01360 }

VOID PspExitProcessFromJob PEJOB  Job,
PEPROCESS  Process
 

Definition at line 608 of file psjob.c.

References _EJOB::ActiveProcesses, ExAcquireResourceExclusive, ExReleaseResource, _EJOB::JobLock, _EPROCESS::JobStatus, KeEnterCriticalRegion, KeLeaveCriticalRegion, PAGED_CODE, PS_JOB_STATUS_NOT_REALLY_ACTIVE, PS_SET_BITS, PspFoldProcessAccountingIntoJob(), and TRUE.

Referenced by PspExitThread().

00612 { 00613 00614 PAGED_CODE(); 00615 00616 KeEnterCriticalRegion(); 00617 ExAcquireResourceExclusive(&Job->JobLock, TRUE); 00618 00619 // 00620 // Update REMOVE accounting info 00621 // 00622 00623 00624 if ( !(Process->JobStatus & PS_JOB_STATUS_NOT_REALLY_ACTIVE) ) { 00625 Job->ActiveProcesses--; 00626 PS_SET_BITS (&Process->JobStatus, PS_JOB_STATUS_NOT_REALLY_ACTIVE); 00627 } 00628 00629 PspFoldProcessAccountingIntoJob(Job,Process); 00630 00631 ExReleaseResource(&Job->JobLock); 00632 KeLeaveCriticalRegion(); 00633 }

VOID PspExitSpecialApc IN PKAPC  Apc,
IN OUT PKNORMAL_ROUTINE NormalRoutine,
IN OUT PVOID *  NormalContext,
IN OUT PVOID *  SystemArgument1,
IN OUT PVOID *  SystemArgument2
 

DECLSPEC_NORETURN VOID PspExitThread IN NTSTATUS  ExitStatus  ) 
 

Definition at line 690 of file psdelete.c.

References _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, ASSERT, _ETHREAD::Cid, CmNotifyRunDown(), DbgkExitProcess(), DbgkExitThread(), _ETHREAD::DeadThread, _KTHREAD::EnableStackSwap, EXCEPTION_EXECUTE_HANDLER, ExChangeHandle(), ExFreePool(), _ETHREAD::ExitStatus, _EPROCESS::ExitStatus, _ETHREAD::ExitTime, _EPROCESS::ExitTime, ExTimerRundown(), FALSE, IoCancelThreadIo(), IS_SYSTEM_THREAD, _EPROCESS::Job, KeBugCheck(), KeBugCheckEx(), KeDisableApcQueuingThread(), KeEnterCriticalRegion, KeFlushQueueApc(), KeForceResumeThread(), KeIsAttachedProcess, KeLeaveCriticalRegion, KeLowerIrql(), KeQuerySystemTime(), _KTHREAD::KernelApcDisable, KernelMode, KeRundownThread(), KeSetPriorityThread(), KeSetProcess(), KeTerminateThread(), L, _EPROCESS::LastThreadExitStatus, _KTHREAD::LegoData, LpcExitThread(), LpcRequestPort(), MmCleanProcessAddressSpace(), MmDeleteTeb(), NtSetEvent(), NULL, ObDereferenceObject, ObKillProcess(), PAGE_SIZE, PAGED_CODE, PASSIVE_LEVEL, _EPROCESS::Pcb, _EPROCESS::Peb, _TERMINATION_PORT::Port, PoRundownThread, _KTHREAD::Priority, ProbeForRead, _KAPC_STATE::Process, PS_GET_THREAD_CREATE_TIME, PsGetCurrentProcess, PsGetCurrentThread, PsLockIAmExiting, PsLockProcess(), PSP_INVALID_ID, PSP_MAX_CREATE_THREAD_NOTIFY, PspCidTable, PspCreateThreadNotifyRoutine, PspCreateThreadNotifyRoutineCount, PspExitProcess(), PspExitProcessFromJob(), PspLegoNotifyRoutine, PspMarkCidInvalid(), PspW32ProcessCallout, PspW32ThreadCallout, PsUnlockProcess(), PsW32ThreadCalloutExit, PTERMINATION_PORT, _KAPC::RundownRoutine, _ETHREAD::Tcb, _KTHREAD::Teb, TERMINATION_PORT, _ETHREAD::TerminationPortList, THREAD_TO_PROCESS, _ETHREAD::ThreadListEntry, _EPROCESS::ThreadListHead, TRUE, _EPROCESS::UniqueProcessId, UserMode, VOID(), _EPROCESS::Win32Process, _KTHREAD::Win32Thread, _WOW64_PROCESS::Wow64, and _EPROCESS::Wow64Process.

Referenced by NtTerminateProcess(), PsExitSpecialApc(), PspExitNormalApc(), PspSystemThreadStartup(), PspTerminateThreadByPointer(), PspUserThreadStartup(), and PsTerminateSystemThread().

00696 : 00697 00698 This function causes the currently executing thread to terminate. This 00699 function is only called from within the process structure. It is called 00700 either from mainline exit code to exit the current thread, or from 00701 PsExitSpecialApc (as a piggyback to user-mode PspExitNormalApc). 00702 00703 Arguments: 00704 00705 ExitStatus - Supplies the exit status associated with the current thread. 00706 00707 Return Value: 00708 00709 None. 00710 00711 --*/ 00712 00713 00714 { 00715 00716 PETHREAD Thread; 00717 PEPROCESS Process; 00718 PKAPC Apc; 00719 PLIST_ENTRY FirstEntry; 00720 PLIST_ENTRY NextEntry; 00721 PTERMINATION_PORT TerminationPort; 00722 LPC_CLIENT_DIED_MSG CdMsg; 00723 BOOLEAN LastThread; 00724 00725 PAGED_CODE(); 00726 00727 Thread = PsGetCurrentThread(); 00728 Process = THREAD_TO_PROCESS(Thread); 00729 00730 if ( KeIsAttachedProcess() ) { 00731 KeBugCheckEx( 00732 INVALID_PROCESS_ATTACH_ATTEMPT, 00733 (ULONG_PTR)Process, 00734 (ULONG_PTR)Thread->Tcb.ApcState.Process, 00735 (ULONG)Thread->Tcb.ApcStateIndex, 00736 (ULONG_PTR)Thread 00737 ); 00738 } 00739 00740 KeLowerIrql(PASSIVE_LEVEL); 00741 00742 if (Thread->Tcb.Priority < LOW_REALTIME_PRIORITY) { 00743 KeSetPriorityThread (&Thread->Tcb, LOW_REALTIME_PRIORITY); 00744 } 00745 00746 // 00747 // Clear any execution state associated with the thread 00748 // 00749 00750 PoRundownThread(Thread); 00751 00752 // 00753 // Account for a miss where we try to freeze a thread and bump the 00754 // freeze count, but in the freeze APC we bail from the APC due to the 00755 // pending exit APC. This results in an active thread running with a biased 00756 // freeze count and no pending APC. When this sort of thread tries to grab the 00757 // process lock, it ends of spinning since it things a freeze is pending and 00758 // an APC should occur. 00759 // 00760 // Wait mode of UserMode allows the kernel stack to page out if necessary 00761 // 00762 00763 PsLockProcess(Process,UserMode,PsLockIAmExiting); 00764 KeForceResumeThread (&Thread->Tcb); 00765 00766 // 00767 // Notify registered callout routines of thread deletion. 00768 // 00769 00770 if (PspCreateThreadNotifyRoutineCount != 0) { 00771 ULONG i; 00772 00773 for (i=0; i<PSP_MAX_CREATE_THREAD_NOTIFY; i++) { 00774 if (PspCreateThreadNotifyRoutine[i] != NULL) { 00775 (*PspCreateThreadNotifyRoutine[i])(Process->UniqueProcessId, 00776 Thread->Cid.UniqueThread, 00777 FALSE 00778 ); 00779 } 00780 } 00781 } 00782 00783 LastThread = FALSE; 00784 00785 if ( (Process->ThreadListHead.Flink == Process->ThreadListHead.Blink) 00786 && (Process->ThreadListHead.Flink == &Thread->ThreadListEntry) ) { 00787 LastThread = TRUE; 00788 if ( ExitStatus == STATUS_THREAD_IS_TERMINATING ) { 00789 if ( Process->ExitStatus == STATUS_PENDING ) { 00790 Process->ExitStatus = Process->LastThreadExitStatus; 00791 } 00792 } else { 00793 Process->ExitStatus = ExitStatus; 00794 } 00795 00796 DbgkExitProcess(ExitStatus); 00797 00798 } else { 00799 if ( ExitStatus != STATUS_THREAD_IS_TERMINATING ) { 00800 Process->LastThreadExitStatus = ExitStatus; 00801 } 00802 00803 DbgkExitThread(ExitStatus); 00804 } 00805 00806 KeLeaveCriticalRegion(); 00807 ASSERT(Thread->Tcb.KernelApcDisable == 0); 00808 00809 Thread->Tcb.KernelApcDisable = 0; 00810 00811 // 00812 // Process the TerminationPortList 00813 // 00814 if ( !IsListEmpty(&Thread->TerminationPortList) ) { 00815 00816 CdMsg.PortMsg.u1.s1.DataLength = sizeof(LARGE_INTEGER); 00817 CdMsg.PortMsg.u1.s1.TotalLength = sizeof(LPC_CLIENT_DIED_MSG); 00818 CdMsg.PortMsg.u2.s2.Type = LPC_CLIENT_DIED; 00819 CdMsg.PortMsg.u2.s2.DataInfoOffset = 0; 00820 00821 while ( !IsListEmpty(&Thread->TerminationPortList) ) { 00822 00823 NextEntry = RemoveHeadList(&Thread->TerminationPortList); 00824 TerminationPort = CONTAINING_RECORD(NextEntry,TERMINATION_PORT,Links); 00825 CdMsg.CreateTime.QuadPart = PS_GET_THREAD_CREATE_TIME(Thread); 00826 LpcRequestPort(TerminationPort->Port, (PPORT_MESSAGE)&CdMsg); 00827 ObDereferenceObject(TerminationPort->Port); 00828 ExFreePool(TerminationPort); 00829 } 00830 } else { 00831 00832 // 00833 // If there are no ports to send notifications to, 00834 // but there is an exception port, then we have to 00835 // send a client died message through the exception 00836 // port. This will allow a server a chance to get notification 00837 // if an app/thread dies before it even starts 00838 // 00839 // 00840 // We only send the exception if the thread creation really worked. 00841 // DeadThread is set when an NtCreateThread returns an error, but 00842 // the thread will actually execute this path. If DeadThread is not 00843 // set than the thread creation succeeded. The other place DeadThread 00844 // is set is when we were terminated without having any chance to move. 00845 // in this case, DeadThread is set and the exit status is set to 00846 // STATUS_THREAD_IS_TERMINATING 00847 // 00848 00849 if ( (ExitStatus == STATUS_THREAD_IS_TERMINATING && Thread->DeadThread) || 00850 !Thread->DeadThread ) { 00851 00852 CdMsg.PortMsg.u1.s1.DataLength = sizeof(LARGE_INTEGER); 00853 CdMsg.PortMsg.u1.s1.TotalLength = sizeof(LPC_CLIENT_DIED_MSG); 00854 CdMsg.PortMsg.u2.s2.Type = LPC_CLIENT_DIED; 00855 CdMsg.PortMsg.u2.s2.DataInfoOffset = 0; 00856 if ( PsGetCurrentProcess()->ExceptionPort ) { 00857 CdMsg.CreateTime.QuadPart = PS_GET_THREAD_CREATE_TIME(Thread); 00858 LpcRequestPort(PsGetCurrentProcess()->ExceptionPort, (PPORT_MESSAGE)&CdMsg); 00859 } 00860 } 00861 } 00862 00863 // 00864 // rundown the Win32 structures 00865 // 00866 00867 if ( Thread->Tcb.Win32Thread ) { 00868 (PspW32ThreadCallout)(Thread,PsW32ThreadCalloutExit); 00869 } 00870 00871 if ( LastThread && Process->Win32Process ) { 00872 (PspW32ProcessCallout)(Process,FALSE); 00873 } 00874 00875 // 00876 // User/Gdi has been given a chance to clean up. Now make sure they didn't 00877 // leave the kernel stack locked which would happen if data was still live on 00878 // this stack, but was being used by another thread 00879 // 00880 00881 if ( !Thread->Tcb.EnableStackSwap ) { 00882 KeBugCheckEx(KERNEL_STACK_LOCKED_AT_EXIT,0,0,0,0); 00883 } 00884 00885 // 00886 // Delete the thread's TEB. If the address of the TEB is in user 00887 // space, then this is a real user mode TEB. If the address is in 00888 // system space, then this is a special system thread TEB allocated 00889 // from paged or nonpaged pool. 00890 // 00891 00892 00893 if (Thread->Tcb.Teb) { 00894 if ( IS_SYSTEM_THREAD(Thread) ) { 00895 ExFreePool( Thread->Tcb.Teb ); 00896 } else { 00897 00898 // 00899 // The thread is a user-mode thread. Look to see if the thread 00900 // owns the loader lock (and any other key peb-based critical 00901 // sections. If so, do our best to release the locks. 00902 // 00903 // Since the LoaderLock used to be a mutant, releasing the lock 00904 // like this is very similar to mutant abandonment and the loader 00905 // never did anything with abandoned status anyway 00906 // 00907 00908 try { 00909 PTEB Teb; 00910 PPEB Peb; 00911 PRTL_CRITICAL_SECTION Cs; 00912 int DecrementCount; 00913 00914 Teb = Thread->Tcb.Teb; 00915 Peb = Process->Peb; 00916 00917 Cs = Peb->LoaderLock; 00918 if ( Cs ) { 00919 ProbeForRead(Cs,sizeof(*Cs),4); 00920 if ( Cs->OwningThread == Thread->Cid.UniqueThread ) { 00921 00922 // 00923 // x86 uses a 1 based recursion count 00924 // 00925 00926 #if defined(_X86_) 00927 DecrementCount = Cs->RecursionCount; 00928 #else 00929 DecrementCount = Cs->RecursionCount + 1; 00930 #endif 00931 Cs->RecursionCount = 0; 00932 Cs->OwningThread = 0; 00933 00934 // 00935 // undo lock count increments for recursion cases 00936 // 00937 00938 while(DecrementCount > 1){ 00939 InterlockedDecrement(&Cs->LockCount); 00940 DecrementCount--; 00941 } 00942 00943 // 00944 // undo final lock count 00945 // 00946 00947 if ( InterlockedDecrement(&Cs->LockCount) >= 0 ){ 00948 NtSetEvent(Cs->LockSemaphore,NULL); 00949 } 00950 } 00951 00952 // 00953 // if the thread exited while waiting on the loader 00954 // lock clean it up. There is still a potential race 00955 // here since we can not safely know what happens to 00956 // a thread after it interlocked increments the lock count 00957 // but before it sets the waiting on loader lock flag. On the 00958 // release side, it it safe since we mark ownership of the lock 00959 // before clearing the flag. This triggers the first part of this 00960 // test. The only thing out of whack is the recursion count, but this 00961 // is also safe since in this state, recursion count is 0. 00962 // 00963 00964 else if ( Teb->WaitingOnLoaderLock ) { 00965 00966 // 00967 // This code isn't right. We need to bump down our lock count 00968 // increment. 00969 // 00970 // A few cases to consider: 00971 // 00972 // Another thread releases the lock signals the event. 00973 // We take the wait and then die before setting our ID. 00974 // I doubt very much that this can happen because right 00975 // after we come out of the wait, we set the owner Id 00976 // (meaning that we would go through the other part of the if). 00977 // Bottom line is that we should just decrement our lock count 00978 // and get out of the way. There is no need to set the event. 00979 // In the RAS stress failure, I saw us setting the event 00980 // just because the lock count was >= 0. The lock was already held 00981 // by another thread so setting the event let yet another thread 00982 // also own the lock. Last one to release would get a 00983 // not owner critical section failure 00984 // 00985 // 00986 // if ( InterlockedDecrement(&Cs->LockCount) >= 0 ){ 00987 // NtSetEvent(Cs->LockSemaphore,NULL); 00988 // } 00989 // 00990 00991 InterlockedDecrement(&Cs->LockCount); 00992 } 00993 } 00994 #if defined(_WIN64) 00995 if (Process->Wow64Process) { 00996 // Do the same thing for the 32-bit PEB->Ldr 00997 PRTL_CRITICAL_SECTION32 Cs32; 00998 PPEB32 Peb32; 00999 01000 Peb32 = Process->Wow64Process->Wow64; 01001 Cs32 = (PRTL_CRITICAL_SECTION32)ULongToPtr(Peb32->LoaderLock); 01002 if (Cs32) { 01003 ProbeForRead(Cs32,sizeof(*Cs32),4); 01004 if ( Cs32->OwningThread == PtrToUlong(Thread->Cid.UniqueThread) ) { 01005 // 01006 // x86 uses a 1 based recursion count, so the 01007 // IA64 kernel needs to do the same, since 01008 // the critsect is really implemented by IA32 01009 // usermode. 01010 // 01011 DecrementCount = Cs32->RecursionCount; 01012 Cs32->RecursionCount = 0; 01013 Cs32->OwningThread = 0; 01014 01015 // 01016 // undo lock count increments for recursion cases 01017 // 01018 while(DecrementCount > 1) { 01019 InterlockedDecrement(&Cs32->LockCount); 01020 DecrementCount--; 01021 } 01022 01023 // 01024 // undo final lock count 01025 // 01026 if ( InterlockedDecrement(&Cs32->LockCount) >= 0 ){ 01027 NtSetEvent(LongToHandle(Cs32->LockSemaphore),NULL); 01028 } 01029 } else { 01030 PTEB32 Teb32 = WOW64_GET_TEB32(Teb); 01031 01032 ProbeForRead(Teb32,sizeof(*Teb32),4); 01033 if ( Teb32->WaitingOnLoaderLock ) { 01034 InterlockedDecrement(&Cs32->LockCount); 01035 } 01036 } 01037 } 01038 } 01039 #endif 01040 } 01041 except (EXCEPTION_EXECUTE_HANDLER) { 01042 ; 01043 } 01044 01045 #if defined(_WIN64) 01046 if (Process->Wow64Process) { 01047 // 01048 // Free the 32 bit Teb 01049 // 01050 try { 01051 PVOID BaseAddress; 01052 SIZE_T RegionSize; 01053 01054 // Get the TEB32 pointer 01055 BaseAddress = *(PVOID *)WOW64_TEB32_POINTER_ADDRESS(((PTEB)Thread->Tcb.Teb)); 01056 01057 // Free it. ZwFreeVirtualMemory will probe the address 01058 // for us, ensuring that it is in usermode memory. 01059 RegionSize = PAGE_SIZE; 01060 ZwFreeVirtualMemory( NtCurrentProcess(), 01061 &BaseAddress, 01062 &RegionSize, 01063 MEM_RELEASE 01064 ); 01065 01066 } 01067 except (EXCEPTION_EXECUTE_HANDLER) { 01068 ; 01069 } 01070 } 01071 #endif 01072 01073 MmDeleteTeb(Process, Thread->Tcb.Teb); 01074 Thread->Tcb.Teb = NULL; 01075 } 01076 } 01077 01078 // 01079 // Rundown The Lists: 01080 // 01081 // - Cancel Io By Thread 01082 // - Cancel Timers 01083 // - Cancel Registry Notify Requests pending against this thread 01084 // - Perform kernel thread rundown 01085 // 01086 01087 IoCancelThreadIo(Thread); 01088 ExTimerRundown(); 01089 CmNotifyRunDown(Thread); 01090 KeRundownThread(); 01091 01092 // 01093 // delete the Client Id and decrement the reference count for it. 01094 // 01095 01096 if (!(ExChangeHandle(PspCidTable, Thread->Cid.UniqueThread, PspMarkCidInvalid, PSP_INVALID_ID))) { 01097 KeBugCheck(CID_HANDLE_DELETION); 01098 } 01099 ObDereferenceObject(Thread); 01100 01101 // 01102 // Let LPC component deal with message stack in Thread->LpcReplyMessage 01103 // but do it after the client ID becomes invalid. 01104 // 01105 01106 LpcExitThread(Thread); 01107 01108 // 01109 // If this is the last thread in the process, then clean the address space 01110 // 01111 01112 if ( LastThread ) { 01113 if (!(ExChangeHandle(PspCidTable,Process->UniqueProcessId, PspMarkCidInvalid, PSP_INVALID_ID))) { 01114 KeBugCheck(CID_HANDLE_DELETION); 01115 } 01116 KeQuerySystemTime(&Process->ExitTime); 01117 PspExitProcess(TRUE,Process); 01118 } 01119 01120 01121 Thread->ExitStatus = ExitStatus; 01122 KeQuerySystemTime(&Thread->ExitTime); 01123 01124 01125 RemoveEntryList(&Thread->ThreadListEntry); 01126 KeEnterCriticalRegion(); 01127 01128 Thread->ThreadListEntry.Flink = NULL; 01129 Thread->ThreadListEntry.Blink = NULL; 01130 01131 PsUnlockProcess(Process); 01132 ASSERT(Thread->Tcb.KernelApcDisable == 0); 01133 01134 if ( LastThread ) { 01135 01136 // 01137 // can not hold the process lock while running down the object table 01138 // since this can lead to a delete routine, which will need the job 01139 // lock, BUT our lock ordering is always joblock -> processlock 01140 // 01141 01142 ObKillProcess(TRUE, Process); 01143 01144 if ( Process->Job) { 01145 01146 // 01147 // Now we can fold the process accounting into the job. Don't need to wait for 01148 // the delete routine. 01149 // 01150 01151 PspExitProcessFromJob(Process->Job,Process); 01152 01153 } 01154 01155 KeSetProcess(&Process->Pcb,0,FALSE); 01156 01157 } 01158 01159 // 01160 // Rundown pending APCs 01161 // 01162 01163 (VOID) KeDisableApcQueuingThread(&Thread->Tcb); 01164 01165 // 01166 // flush user-mode APC queue 01167 // 01168 01169 FirstEntry = KeFlushQueueApc(&Thread->Tcb,UserMode); 01170 01171 if ( FirstEntry ) { 01172 01173 NextEntry = FirstEntry; 01174 do { 01175 Apc = CONTAINING_RECORD(NextEntry, KAPC, ApcListEntry); 01176 NextEntry = NextEntry->Flink; 01177 01178 // 01179 // If the APC has a rundown routine then call it. Otherwise 01180 // deallocate the APC 01181 // 01182 01183 if ( Apc->RundownRoutine ) { 01184 (Apc->RundownRoutine)(Apc); 01185 } else { 01186 ExFreePool(Apc); 01187 } 01188 01189 } while (NextEntry != FirstEntry); 01190 } 01191 01192 if ( LastThread ) { 01193 MmCleanProcessAddressSpace(); 01194 } 01195 01196 if ( Thread->Tcb.LegoData && PspLegoNotifyRoutine ) { 01197 (PspLegoNotifyRoutine)(&Thread->Tcb); 01198 } 01199 01200 // 01201 // flush kernel-mode APC queue 01202 // There should never be any kernel mode APCs found this far 01203 // into thread termination. Since we go to PASSIVE_LEVEL upon 01204 // entering exit. 01205 // 01206 01207 FirstEntry = KeFlushQueueApc(&Thread->Tcb,KernelMode); 01208 01209 if ( FirstEntry ) { 01210 KeBugCheckEx( 01211 KERNEL_APC_PENDING_DURING_EXIT, 01212 (ULONG_PTR)FirstEntry, 01213 (ULONG_PTR)Thread->Tcb.KernelApcDisable, 01214 (ULONG_PTR)KeGetCurrentIrql(), 01215 0 01216 ); 01217 } 01218 01219 // 01220 // Terminate the thread. 01221 // 01222 // N.B. There is no return from this call. 01223 // 01224 // N.B. The kernel inserts the current thread in the reaper list and 01225 // activates a thread, if necessary, to reap the terminating thread. 01226 // 01227 01228 KeTerminateThread(0L); 01229 }

VOID PspFoldProcessAccountingIntoJob PEJOB  Job,
PEPROCESS  Process
 

Definition at line 2632 of file psjob.c.

References _EJOB::ActiveProcesses, _EPROCESS::CommitChargePeak, _EJOB::CompletionKey, _EJOB::CompletionPort, FALSE, IoSetIoCompletion(), _EPROCESS::JobStatus, KeMaximumIncrement, _KPROCESS::KernelTime, NULL, _EPROCESS::OtherOperationCount, _EJOB::OtherOperationCount, _EPROCESS::OtherTransferCount, _EJOB::OtherTransferCount, _MMSUPPORT::PageFaultCount, _EPROCESS::Pcb, _EJOB::PeakProcessMemoryUsed, PS_JOB_STATUS_ACCOUNTING_FOLDED, PS_JOB_STATUS_LAST_REPORT_MEMORY, PS_SET_CLEAR_BITS, _EPROCESS::ReadOperationCount, _EJOB::ReadOperationCount, _EPROCESS::ReadTransferCount, _EJOB::ReadTransferCount, _EJOB::ThisPeriodTotalKernelTime, _EJOB::ThisPeriodTotalUserTime, _EJOB::TotalKernelTime, _EJOB::TotalPageFaultCount, _EJOB::TotalUserTime, _KPROCESS::UserTime, _EPROCESS::Vm, _EPROCESS::WriteOperationCount, _EJOB::WriteOperationCount, _EPROCESS::WriteTransferCount, and _EJOB::WriteTransferCount.

Referenced by NtSetInformationJobObject(), PsEnforceExecutionTimeLimits(), PspExitProcessFromJob(), PspRemoveProcessFromJob(), and PspTerminateAllProcessesInJob().

02636 { 02637 LARGE_INTEGER UserTime, KernelTime; 02638 02639 if ( !(Process->JobStatus & PS_JOB_STATUS_ACCOUNTING_FOLDED) ) { 02640 UserTime.QuadPart = UInt32x32To64(Process->Pcb.UserTime,KeMaximumIncrement); 02641 KernelTime.QuadPart = UInt32x32To64(Process->Pcb.KernelTime,KeMaximumIncrement); 02642 02643 Job->TotalUserTime.QuadPart += UserTime.QuadPart; 02644 Job->TotalKernelTime.QuadPart += KernelTime.QuadPart; 02645 Job->ThisPeriodTotalUserTime.QuadPart += UserTime.QuadPart; 02646 Job->ThisPeriodTotalKernelTime.QuadPart += KernelTime.QuadPart; 02647 02648 Job->ReadOperationCount += Process->ReadOperationCount.QuadPart; 02649 Job->WriteOperationCount += Process->WriteOperationCount.QuadPart; 02650 Job->OtherOperationCount += Process->OtherOperationCount.QuadPart; 02651 Job->ReadTransferCount += Process->ReadTransferCount.QuadPart; 02652 Job->WriteTransferCount += Process->WriteTransferCount.QuadPart; 02653 Job->OtherTransferCount += Process->OtherTransferCount.QuadPart; 02654 02655 Job->TotalPageFaultCount += Process->Vm.PageFaultCount; 02656 02657 02658 if ( Process->CommitChargePeak > Job->PeakProcessMemoryUsed ) { 02659 Job->PeakProcessMemoryUsed = Process->CommitChargePeak; 02660 } 02661 02662 PS_SET_CLEAR_BITS (&Process->JobStatus, 02663 PS_JOB_STATUS_ACCOUNTING_FOLDED, 02664 PS_JOB_STATUS_LAST_REPORT_MEMORY); 02665 02666 if ( Job->CompletionPort && Job->ActiveProcesses == 0) { 02667 IoSetIoCompletion( 02668 Job->CompletionPort, 02669 Job->CompletionKey, 02670 NULL, 02671 STATUS_SUCCESS, 02672 JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO, 02673 FALSE 02674 ); 02675 } 02676 } 02677 }

VOID PspGetContext IN PKTRAP_FRAME  TrapFrame,
IN PKNONVOLATILE_CONTEXT_POINTERS  NonVolatileContext,
IN OUT PCONTEXT  Context
 

Definition at line 29 of file psctxalp.c.

References ASSERT, CONTEXT_CONTROL, CONTEXT_FLOATING_POINT, CONTEXT_INTEGER, EXCEPTION_EXECUTE_HANDLER, KeGetCurrentThread, KernelMode, and KiBreakPoints.

Referenced by PspGetSetContextApc(), PspGetSetContextSpecialApc(), and PspGetSetContextSpecialApcMain().

00037 : 00038 00039 This function selectively moves the contents of the specified trap frame 00040 and nonvolatile context to the specified context record. 00041 00042 Arguments: 00043 00044 TrapFrame - Supplies a pointer to a trap frame. 00045 00046 ContextPointers - Supplies the address of context pointers record. 00047 00048 ContextRecord - Supplies the address of a context record. 00049 00050 Return Value: 00051 00052 None. 00053 00054 --*/ 00055 00056 { 00057 00058 // 00059 // Get control information if specified. 00060 // 00061 00062 if ((ContextRecord->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) { 00063 00064 // 00065 // Get integer registers gp, ra, sp, FIR, and PSR from trap frame. 00066 // 00067 00068 ContextRecord->IntGp = TrapFrame->IntGp; 00069 ContextRecord->IntSp = TrapFrame->IntSp; 00070 ContextRecord->IntRa = TrapFrame->IntRa; 00071 ContextRecord->Fir = TrapFrame->Fir; 00072 ContextRecord->Psr = TrapFrame->Psr; 00073 } 00074 00075 // 00076 // Get integer register contents if specified. 00077 // 00078 00079 if ((ContextRecord->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { 00080 00081 // 00082 // Get volatile integer registers v0 and t0 - t7 from trap frame. 00083 // 00084 00085 ContextRecord->IntV0 = TrapFrame->IntV0; 00086 ContextRecord->IntT0 = TrapFrame->IntT0; 00087 ContextRecord->IntT1 = TrapFrame->IntT1; 00088 ContextRecord->IntT2 = TrapFrame->IntT2; 00089 ContextRecord->IntT3 = TrapFrame->IntT3; 00090 ContextRecord->IntT4 = TrapFrame->IntT4; 00091 ContextRecord->IntT5 = TrapFrame->IntT5; 00092 ContextRecord->IntT6 = TrapFrame->IntT6; 00093 ContextRecord->IntT7 = TrapFrame->IntT7; 00094 00095 // 00096 // Get nonvolatile integer registers s0 - s5 through context pointers. 00097 // 00098 00099 ContextRecord->IntS0 = *ContextPointers->IntS0; 00100 ContextRecord->IntS1 = *ContextPointers->IntS1; 00101 ContextRecord->IntS2 = *ContextPointers->IntS2; 00102 ContextRecord->IntS3 = *ContextPointers->IntS3; 00103 ContextRecord->IntS4 = *ContextPointers->IntS4; 00104 ContextRecord->IntS5 = *ContextPointers->IntS5; 00105 00106 // 00107 // Get volatile integer registers fp/s6, a0 - a5, and t8 - t12 from 00108 // trap frame. 00109 // 00110 00111 ContextRecord->IntFp = TrapFrame->IntFp; 00112 00113 ContextRecord->IntA0 = TrapFrame->IntA0; 00114 ContextRecord->IntA1 = TrapFrame->IntA1; 00115 ContextRecord->IntA2 = TrapFrame->IntA2; 00116 ContextRecord->IntA3 = TrapFrame->IntA3; 00117 ContextRecord->IntA4 = TrapFrame->IntA4; 00118 ContextRecord->IntA5 = TrapFrame->IntA5; 00119 00120 ContextRecord->IntT8 = TrapFrame->IntT8; 00121 ContextRecord->IntT9 = TrapFrame->IntT9; 00122 ContextRecord->IntT10 = TrapFrame->IntT10; 00123 ContextRecord->IntT11 = TrapFrame->IntT11; 00124 ContextRecord->IntT12 = TrapFrame->IntT12; 00125 00126 // 00127 // Get volatile integer register AT from trap frame. 00128 // Get integer register zero. 00129 // 00130 00131 ContextRecord->IntAt = TrapFrame->IntAt; 00132 ContextRecord->IntZero = 0; 00133 } 00134 00135 // 00136 // Get floating register contents if specified. 00137 // 00138 00139 if ((ContextRecord->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) { 00140 00141 // 00142 // Get volatile floating registers f0 - f1 from trap frame. 00143 // 00144 00145 ContextRecord->FltF0 = TrapFrame->FltF0; 00146 ContextRecord->FltF1 = TrapFrame->FltF1; 00147 00148 // 00149 // Get volatile floating registers f10 - f30 from trap frame. 00150 // This assumes that f10 - f30 are contiguous in the trap frame. 00151 // 00152 00153 ASSERT((&ContextRecord->FltF30 - &ContextRecord->FltF10) == 20); 00154 RtlMoveMemory(&ContextRecord->FltF10, &TrapFrame->FltF10, 00155 sizeof(ULONGLONG) * 21); 00156 00157 ContextRecord->FltF31 = 0; 00158 00159 // 00160 // Get nonvolatile floating registers f2 - f9 through context pointers. 00161 // 00162 00163 ContextRecord->FltF2 = *ContextPointers->FltF2; 00164 ContextRecord->FltF3 = *ContextPointers->FltF3; 00165 ContextRecord->FltF4 = *ContextPointers->FltF4; 00166 ContextRecord->FltF5 = *ContextPointers->FltF5; 00167 ContextRecord->FltF6 = *ContextPointers->FltF6; 00168 ContextRecord->FltF7 = *ContextPointers->FltF7; 00169 ContextRecord->FltF8 = *ContextPointers->FltF8; 00170 ContextRecord->FltF9 = *ContextPointers->FltF9; 00171 00172 // 00173 // Get floating point control register from trap frame. 00174 // Get the current software FPCR value from the TEB. 00175 // 00176 00177 ContextRecord->Fpcr = TrapFrame->Fpcr; 00178 try { 00179 ContextRecord->SoftFpcr = 00180 (ULONGLONG)(NtCurrentTeb()->FpSoftwareStatusRegister); 00181 00182 } except (EXCEPTION_EXECUTE_HANDLER) { 00183 ContextRecord->SoftFpcr = 0; 00184 } 00185 } 00186 00187 return; 00188 }

VOID PspGetSetContextSpecialApc IN PKAPC  Apc,
IN OUT PKNORMAL_ROUTINE NormalRoutine,
IN OUT PVOID *  NormalContext,
IN OUT PVOID *  SystemArgument1,
IN OUT PVOID *  SystemArgument2
 

Referenced by NtGetContextThread(), and NtSetContextThread().

VOID PspInheritQuota IN PEPROCESS  NewProcess,
IN PEPROCESS  ParentProcess
 

Definition at line 466 of file psquota.c.

References PspDefaultQuotaBlock, _EPROCESS_QUOTA_BLOCK::QuotaLock, and _EPROCESS_QUOTA_BLOCK::ReferenceCount.

Referenced by PspCreateProcess().

00470 { 00471 PEPROCESS_QUOTA_BLOCK QuotaBlock; 00472 KIRQL OldIrql; 00473 00474 if ( ParentProcess ) { 00475 QuotaBlock = ParentProcess->QuotaBlock; 00476 } 00477 else { 00478 QuotaBlock = &PspDefaultQuotaBlock; 00479 } 00480 00481 ExAcquireSpinLock(&QuotaBlock->QuotaLock,&OldIrql); 00482 QuotaBlock->ReferenceCount++; 00483 NewProcess->QuotaBlock = QuotaBlock; 00484 ExReleaseSpinLock(&QuotaBlock->QuotaLock,OldIrql); 00485 }

NTSTATUS PspInitializeProcessSecurity IN PEPROCESS Parent  OPTIONAL,
IN PEPROCESS  Child
 

Definition at line 1117 of file ps/security.c.

References NT_SUCCESS, NTSTATUS(), NULL, PspBootAccessToken, SeAssignPrimaryToken(), SeSubProcessToken(), and Status.

Referenced by PspCreateProcess().

01124 : 01125 01126 This function initializes a new process's security fields, including 01127 the assignment of a new primary token. 01128 01129 The child process is assumed to not yet have been inserted into 01130 an object table. 01131 01132 NOTE: IT IS EXPECTED THAT THIS SERVICE WILL BE CALLED WITH A NULL 01133 PARENT PROCESS POINTER EXACTLY ONCE - FOR THE INITIAL SYSTEM 01134 PROCESS. 01135 01136 01137 Arguments: 01138 01139 Parent - An optional pointer to the process being used as the parent 01140 of the new process. If this value is NULL, then the process is 01141 assumed to be the initial system process, and the boot token is 01142 assigned rather than a duplicate of the parent process's primary 01143 token. 01144 01145 Child - Supplies the address of the process being initialized. This 01146 process does not yet require security field contention protection. 01147 In particular, the security fields may be accessed without first 01148 acquiring the process security fields lock. 01149 01150 01151 01152 Return Value: 01153 01154 01155 --*/ 01156 01157 { 01158 NTSTATUS 01159 Status; 01160 01161 01162 // 01163 // Assign the primary token 01164 // 01165 01166 if (ARGUMENT_PRESENT(Parent)) { 01167 01168 // 01169 // create the primary token 01170 // This is a duplicate of the parent's token. 01171 // 01172 01173 Status = SeSubProcessToken( 01174 Parent, 01175 &Child->Token 01176 ); 01177 01178 if (!NT_SUCCESS(Status)) { 01179 Child->Token = NULL; // Needed to ensure proper deletion 01180 } 01181 01182 } else { 01183 01184 // 01185 // Reference and assign the boot token 01186 // 01187 // The use of a single boot access token assumes there is 01188 // exactly one parentless process in the system - the initial 01189 // process. If this ever changes, this code will need to change 01190 // to match the new condition (so that a token doesn't end up 01191 // being shared by multiple processes. 01192 // 01193 01194 Child->Token = NULL; 01195 SeAssignPrimaryToken( Child, PspBootAccessToken ); 01196 Status = STATUS_SUCCESS; 01197 01198 01199 } 01200 01201 return Status; 01202 01203 }

NTSTATUS PspInitializeSystemDll VOID   ) 
 

Definition at line 745 of file psinit.c.

References DbgPrint, KdUpdateDataBlock(), KeBugCheckEx(), KeSetup80387OrEmulate(), _SYSTEM_DLL::LoaderInitRoutine, NT_SUCCESS, NTSTATUS(), PspLookupKernelUserEntryPoints(), PspLookupSystemDllEntryPoint(), and PspSystemDll.

Referenced by PspInitPhase1().

00751 : 00752 00753 This function initializes the system DLL and locates 00754 various entrypoints within the DLL. 00755 00756 Arguments: 00757 00758 None. 00759 00760 Return Value: 00761 00762 TBD 00763 00764 --*/ 00765 00766 { 00767 NTSTATUS st; 00768 PSZ dll_entrypoint; 00769 PVOID R3EmulatorTable; 00770 00771 // 00772 // Locate the important system dll entrypoints 00773 // 00774 00775 dll_entrypoint = "LdrInitializeThunk"; 00776 00777 st = PspLookupSystemDllEntryPoint( 00778 dll_entrypoint, 00779 (PVOID *)&PspSystemDll.LoaderInitRoutine 00780 ); 00781 00782 if ( !NT_SUCCESS(st) ) { 00783 #if DBG 00784 DbgPrint("PS: Unable to locate LdrInitializeThunk in system dll\n"); 00785 #endif 00786 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,6,0,0); 00787 return st; 00788 } 00789 00790 #if i386 00791 // 00792 // Find 80387 emulator. 00793 // 00794 00795 st = PspLookupSystemDllEntryPoint( 00796 "NPXEMULATORTABLE", 00797 &R3EmulatorTable 00798 ); 00799 00800 if ( !NT_SUCCESS(st) ) { 00801 #if DBG 00802 DbgPrint("PS: Unable to locate NPXNPHandler in system dll\n"); 00803 #endif 00804 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,7,0,0); 00805 return st; 00806 } 00807 // 00808 // Pass emulator into kernel, and let it decide whether it should 00809 // use the emulator or set up to use the 80387 hardware. 00810 // 00811 00812 KeSetup80387OrEmulate(R3EmulatorTable); 00813 #endif //i386 00814 00815 st = PspLookupKernelUserEntryPoints(); 00816 00817 if ( !NT_SUCCESS(st) ) { 00818 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,8,0,0); 00819 } 00820 00821 KdUpdateDataBlock(); 00822 00823 return st; 00824 }

VOID PspInitializeThreadSecurity IN PEPROCESS  Process,
IN PETHREAD  Thread
 

Definition at line 1395 of file ps/security.c.

References FALSE, and NULL.

Referenced by PspCreateThread().

01402 : 01403 01404 This function initializes a new thread's security fields. 01405 01406 01407 Arguments: 01408 01409 Process - Points to the process the thread belongs to. 01410 01411 Thread - Points to the thread object being initialized. 01412 01413 01414 Return Value: 01415 01416 None. 01417 01418 --*/ 01419 01420 { 01421 01422 01423 // 01424 // Initially not impersonating anyone. 01425 // 01426 01427 Thread->ImpersonationInfo = NULL; 01428 Thread->ActiveImpersonationInfo = FALSE; 01429 01430 return; 01431 01432 }

BOOLEAN PspInitPhase0 IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 181 of file psinit.c.

References ExCreateHandleTable(), ExInitializeFastMutex, ExInitializeWorkItem, ExRemoveHandleTable(), FALSE, _EPROCESS::ImageFileName, KeBugCheckEx(), KernelMode, _KPROCESS::KernelTime, L, _JOB_WORKING_SET_CHANGE_HEAD::Links, _JOB_WORKING_SET_CHANGE_HEAD::Lock, MM_SYSTEMSIZE, MmLargeSystem, MmMediumSystem, MmQuerySystemSize(), MmSmallSystem, NonPagedPool, NT_SUCCESS, NULL, ObCreateObjectType(), ObjectAttributes, ObReferenceObjectByHandle(), _EPROCESS::Pcb, Phase1Initialization(), PsActiveProcessHead, PsChangeQuantumTable(), PsCreateSystemThread(), PsGetCurrentProcess, PsIdleProcess, PsInitialSystemProcess, PsJobType, PsMaximumWorkingSet, PsMinimumWorkingSet, PSP_1MB, PSP_PROCESS_NONPAGED_CHARGE, PSP_PROCESS_PAGED_CHARGE, PSP_THREAD_NONPAGED_CHARGE, PSP_THREAD_PAGED_CHARGE, PspActiveProcessMutex, PspBootAccessToken, PspCidTable, PspCreateProcess(), PspDefaultNonPagedLimit, PspDefaultPagedLimit, PspDefaultPagefileLimit, PspDoingGiveBacks, PspInitialSystemProcessHandle, PspJobClose(), PspJobDelete(), PspJobList, PspJobListLock, PspJobMapping, PspLdtInitialize(), PspProcessDelete(), PspProcessLockMutex, PspProcessMapping, PspReaper(), PsProcessSecurityLock, PsProcessType, PspThreadDelete(), PspThreadMapping, PspVdmInitialize(), PspWorkingSetChangeHead, PsRawPrioritySeparation, PsReaperListHead, PsReaperWorkItem, PsThreadType, RtlInitUnicodeString(), ThreadHandle, and TRUE.

Referenced by PsInitSystem().

00187 : 00188 00189 This routine performs phase 0 process structure initialization. 00190 During this phase, the initial system process, phase 1 initialization 00191 thread, and reaper threads are created. All object types and other 00192 process structures are created and initialized. 00193 00194 Arguments: 00195 00196 None. 00197 00198 Return Value: 00199 00200 TRUE - Initialization was successful. 00201 00202 FALSE - Initialization Failed. 00203 00204 --*/ 00205 00206 { 00207 00208 UNICODE_STRING NameString; 00209 OBJECT_ATTRIBUTES ObjectAttributes; 00210 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 00211 HANDLE ThreadHandle; 00212 PETHREAD Thread; 00213 MM_SYSTEMSIZE SystemSize; 00214 00215 SystemSize = MmQuerySystemSize(); 00216 PspDefaultPagefileLimit = (ULONG)-1; 00217 00218 #ifdef _WIN64 00219 if ( sizeof(TEB) > 8192 || sizeof(PEB) > 4096 ) { 00220 #else 00221 if ( sizeof(TEB) > 4096 || sizeof(PEB) > 4096 ) { 00222 #endif 00223 KeBugCheckEx(PROCESS_INITIALIZATION_FAILED,99,sizeof(TEB),sizeof(PEB),99); 00224 } 00225 00226 switch ( SystemSize ) { 00227 00228 case MmMediumSystem : 00229 PsMinimumWorkingSet += 10; 00230 PsMaximumWorkingSet += 100; 00231 break; 00232 00233 case MmLargeSystem : 00234 PsMinimumWorkingSet += 30; 00235 PsMaximumWorkingSet += 300; 00236 break; 00237 00238 case MmSmallSystem : 00239 default: 00240 break; 00241 } 00242 00243 PsChangeQuantumTable(FALSE,PsRawPrioritySeparation); 00244 00245 // 00246 // Quotas grow as needed automatically 00247 // 00248 00249 if ( !PspDefaultPagedLimit ) { 00250 PspDefaultPagedLimit = 0; 00251 } 00252 if ( !PspDefaultNonPagedLimit ) { 00253 PspDefaultNonPagedLimit = 0; 00254 } 00255 00256 if ( PspDefaultNonPagedLimit == 0 && PspDefaultPagedLimit == 0) { 00257 PspDoingGiveBacks = TRUE; 00258 } 00259 else { 00260 PspDoingGiveBacks = FALSE; 00261 } 00262 00263 00264 PspDefaultPagedLimit *= PSP_1MB; 00265 PspDefaultNonPagedLimit *= PSP_1MB; 00266 00267 if (PspDefaultPagefileLimit != -1) { 00268 PspDefaultPagefileLimit *= PSP_1MB; 00269 } 00270 00271 // 00272 // Initialize the process security fields lock and the process lock. 00273 // 00274 00275 ExInitializeFastMutex( &PspProcessLockMutex ); 00276 ExInitializeFastMutex( &PsProcessSecurityLock ); 00277 00278 PsIdleProcess = PsGetCurrentProcess(); 00279 PsIdleProcess->Pcb.KernelTime = 0; 00280 PsIdleProcess->Pcb.KernelTime = 0; 00281 00282 // 00283 // Initialize the common fields of the Object Type Prototype record 00284 // 00285 00286 RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); 00287 ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); 00288 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; 00289 ObjectTypeInitializer.SecurityRequired = TRUE; 00290 ObjectTypeInitializer.PoolType = NonPagedPool; 00291 ObjectTypeInitializer.InvalidAttributes = OBJ_PERMANENT | 00292 OBJ_EXCLUSIVE | 00293 OBJ_OPENIF; 00294 00295 00296 // 00297 // Create Object types for Thread and Process Objects. 00298 // 00299 00300 RtlInitUnicodeString(&NameString, L"Process"); 00301 ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_PROCESS_PAGED_CHARGE; 00302 ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_PROCESS_NONPAGED_CHARGE; 00303 ObjectTypeInitializer.DeleteProcedure = PspProcessDelete; 00304 ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS; 00305 ObjectTypeInitializer.GenericMapping = PspProcessMapping; 00306 00307 if ( !NT_SUCCESS(ObCreateObjectType(&NameString, 00308 &ObjectTypeInitializer, 00309 (PSECURITY_DESCRIPTOR) NULL, 00310 &PsProcessType 00311 )) ){ 00312 return FALSE; 00313 } 00314 00315 RtlInitUnicodeString(&NameString, L"Thread"); 00316 ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_THREAD_PAGED_CHARGE; 00317 ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_THREAD_NONPAGED_CHARGE; 00318 ObjectTypeInitializer.DeleteProcedure = PspThreadDelete; 00319 ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS; 00320 ObjectTypeInitializer.GenericMapping = PspThreadMapping; 00321 00322 if ( !NT_SUCCESS(ObCreateObjectType(&NameString, 00323 &ObjectTypeInitializer, 00324 (PSECURITY_DESCRIPTOR) NULL, 00325 &PsThreadType 00326 )) ){ 00327 return FALSE; 00328 } 00329 00330 00331 RtlInitUnicodeString(&NameString, L"Job"); 00332 ObjectTypeInitializer.DefaultPagedPoolCharge = 0; 00333 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EJOB); 00334 ObjectTypeInitializer.DeleteProcedure = PspJobDelete; 00335 ObjectTypeInitializer.CloseProcedure = PspJobClose; 00336 ObjectTypeInitializer.ValidAccessMask = JOB_OBJECT_ALL_ACCESS; 00337 ObjectTypeInitializer.GenericMapping = PspJobMapping; 00338 ObjectTypeInitializer.InvalidAttributes = 0; 00339 00340 if ( !NT_SUCCESS(ObCreateObjectType(&NameString, 00341 &ObjectTypeInitializer, 00342 (PSECURITY_DESCRIPTOR) NULL, 00343 &PsJobType 00344 )) ){ 00345 return FALSE; 00346 } 00347 00348 00349 00350 00351 00352 00353 // 00354 // Initialize active process list head and mutex 00355 // 00356 00357 InitializeListHead(&PsActiveProcessHead); 00358 ExInitializeFastMutex(&PspActiveProcessMutex); 00359 00360 // 00361 // Initialize job list head and mutex 00362 // 00363 00364 InitializeListHead(&PspJobList); 00365 ExInitializeFastMutex(&PspJobListLock); 00366 InitializeListHead(&PspWorkingSetChangeHead.Links); 00367 ExInitializeFastMutex(&PspWorkingSetChangeHead.Lock); 00368 00369 // 00370 // Initialize CID handle table. 00371 // 00372 // N.B. The CID handle table is removed from the handle table list so 00373 // it will not be enumerated for object handle queries. 00374 // 00375 00376 PspCidTable = ExCreateHandleTable(NULL); 00377 if ( ! PspCidTable ) { 00378 return FALSE; 00379 } 00380 ExRemoveHandleTable(PspCidTable); 00381 00382 #if defined(i386) 00383 00384 // 00385 // Ldt Initialization 00386 // 00387 00388 if ( !NT_SUCCESS(PspLdtInitialize()) ) { 00389 return FALSE; 00390 } 00391 00392 // 00393 // Vdm support Initialization 00394 // 00395 00396 if ( !NT_SUCCESS(PspVdmInitialize()) ) { 00397 return FALSE; 00398 } 00399 00400 #endif 00401 00402 // 00403 // Initialize Reaper Data Structures 00404 // 00405 00406 InitializeListHead(&PsReaperListHead); 00407 ExInitializeWorkItem(&PsReaperWorkItem, PspReaper, NULL); 00408 00409 // 00410 // Get a pointer to the system access token. 00411 // This token is used by the boot process, so we can take the pointer 00412 // from there. 00413 // 00414 00415 PspBootAccessToken = PsGetCurrentProcess()->Token; 00416 00417 InitializeObjectAttributes( &ObjectAttributes, 00418 NULL, 00419 0, 00420 NULL, 00421 NULL 00422 ); // FIXFIX 00423 00424 if ( !NT_SUCCESS(PspCreateProcess( 00425 &PspInitialSystemProcessHandle, 00426 PROCESS_ALL_ACCESS, 00427 &ObjectAttributes, 00428 0L, 00429 FALSE, 00430 0L, 00431 0L, 00432 0L 00433 )) ) { 00434 return FALSE; 00435 } 00436 00437 if ( !NT_SUCCESS(ObReferenceObjectByHandle( 00438 PspInitialSystemProcessHandle, 00439 0L, 00440 PsProcessType, 00441 KernelMode, 00442 (PVOID *)&PsInitialSystemProcess, 00443 NULL 00444 )) ) { 00445 00446 return FALSE; 00447 } 00448 00449 strcpy(&PsGetCurrentProcess()->ImageFileName[0],"Idle"); 00450 strcpy(&PsInitialSystemProcess->ImageFileName[0],"System"); 00451 00452 // 00453 // Phase 1 System initialization 00454 // 00455 00456 if ( !NT_SUCCESS(PsCreateSystemThread( 00457 &ThreadHandle, 00458 THREAD_ALL_ACCESS, 00459 &ObjectAttributes, 00460 0L, 00461 NULL, 00462 Phase1Initialization, 00463 (PVOID)LoaderBlock 00464 )) ) { 00465 return FALSE; 00466 } 00467 00468 00469 if ( !NT_SUCCESS(ObReferenceObjectByHandle( 00470 ThreadHandle, 00471 0L, 00472 PsThreadType, 00473 KernelMode, 00474 (PVOID *)&Thread, 00475 NULL 00476 )) ) { 00477 00478 return FALSE; 00479 } 00480 00481 ZwClose( ThreadHandle ); 00482 00483 return TRUE; 00484 }

BOOLEAN PspInitPhase1 IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 487 of file psinit.c.

References FALSE, NT_SUCCESS, NTSTATUS(), PspInitializeSystemDll(), and TRUE.

Referenced by PsInitSystem().

00493 : 00494 00495 This routine performs phase 1 process structure initialization. 00496 During this phase, the system DLL is located and relevant entry 00497 points are extracted. 00498 00499 Arguments: 00500 00501 None. 00502 00503 Return Value: 00504 00505 TRUE - Initialization was successful. 00506 00507 FALSE - Initialization Failed. 00508 00509 --*/ 00510 00511 { 00512 00513 NTSTATUS st; 00514 00515 st = PspInitializeSystemDll(); 00516 00517 if ( !NT_SUCCESS(st) ) { 00518 return FALSE; 00519 } 00520 00521 return TRUE; 00522 }

VOID PspJobClose IN PEPROCESS  Process,
IN PVOID  Object,
IN ACCESS_MASK  GrantedAccess,
IN ULONG  ProcessHandleCount,
IN ULONG  SystemHandleCount
 

Definition at line 709 of file psjob.c.

References _EJOB::CompletionPort, ExAcquireFastMutexUnsafe(), ExAcquireResourceExclusive, ExReleaseFastMutexUnsafe(), ExReleaseResource, _EJOB::JobLock, KeEnterCriticalRegion, KeLeaveCriticalRegion, _EJOB::MemoryLimitsLock, NULL, ObDereferenceObject, PAGED_CODE, and TRUE.

Referenced by PspInitPhase0().

00718 : 00719 00720 Called by the object manager when a handle is closed to the object. 00721 00722 Arguments: 00723 00724 Process - Process doing the close 00725 Object - Job object being closed 00726 GrantedAccess - Access ranted for this handle 00727 ProcessHandleCount - Unused and unmaintained by OB 00728 SystemHandleCount - Current handle count for this object 00729 00730 Return Value: 00731 00732 None. 00733 00734 --*/ 00735 { 00736 PEJOB Job = Object; 00737 PVOID Port; 00738 00739 PAGED_CODE (); 00740 // 00741 // If this isn't the last handle then do nothing. 00742 // 00743 if (SystemHandleCount > 1) { 00744 return; 00745 } 00746 00747 KeEnterCriticalRegion(); 00748 ExAcquireResourceExclusive(&Job->JobLock, TRUE); 00749 ExAcquireFastMutexUnsafe(&Job->MemoryLimitsLock); 00750 00751 // 00752 // Release the completion port 00753 // 00754 Port = Job->CompletionPort; 00755 Job->CompletionPort = NULL; 00756 00757 00758 ExReleaseFastMutexUnsafe(&Job->MemoryLimitsLock); 00759 ExReleaseResource(&Job->JobLock); 00760 KeLeaveCriticalRegion(); 00761 00762 if (Port != NULL) { 00763 ObDereferenceObject(Port); 00764 } 00765 }

VOID PspJobDelete IN PVOID  Object  ) 
 

Definition at line 636 of file psjob.c.

References _WIN32_JOBCALLOUT_PARAMETERS::CalloutType, _PS_JOB_TOKEN_FILTER::CapturedGroups, _PS_JOB_TOKEN_FILTER::CapturedPrivileges, _PS_JOB_TOKEN_FILTER::CapturedSids, _EJOB::CompletionPort, _WIN32_JOBCALLOUT_PARAMETERS::Data, ExAcquireResourceExclusive, ExDeleteResource, ExFreePool(), ExReleaseResource, _EJOB::Filter, _WIN32_JOBCALLOUT_PARAMETERS::Job, _EJOB::JobLinks, _EJOB::JobLock, KeEnterCriticalRegion, KeLeaveCriticalRegion, _EJOB::LimitFlags, MmDispatchWin32Callout(), NULL, ObDereferenceObject, PAGED_CODE, PspJobListLock, PspW32JobCallout, PsW32JobCalloutTerminate, _EJOB::SessionId, _EJOB::Token, and TRUE.

Referenced by PspInitPhase0().

00639 { 00640 PEJOB Job; 00641 WIN32_JOBCALLOUT_PARAMETERS Parms; 00642 00643 PAGED_CODE(); 00644 00645 Job = (PEJOB) Object; 00646 00647 // 00648 // call ntuser to delete its job structure 00649 // 00650 00651 KeEnterCriticalRegion(); 00652 ExAcquireResourceExclusive(&Job->JobLock, TRUE); 00653 00654 00655 Parms.Job = Job; 00656 Parms.CalloutType = PsW32JobCalloutTerminate; 00657 Parms.Data = NULL; 00658 MmDispatchWin32Callout( PspW32JobCallout,NULL, (PVOID)&Parms, &(Job->SessionId)); 00659 00660 ExReleaseResource(&Job->JobLock); 00661 KeLeaveCriticalRegion(); 00662 00663 Job->LimitFlags = 0; 00664 00665 if ( Job->CompletionPort ) { 00666 ObDereferenceObject(Job->CompletionPort); 00667 Job->CompletionPort = NULL; 00668 } 00669 00670 00671 // 00672 // Remove Job on Job List 00673 // 00674 00675 ExAcquireFastMutex(&PspJobListLock); 00676 RemoveEntryList(&Job->JobLinks); 00677 ExReleaseFastMutex(&PspJobListLock); 00678 00679 // 00680 // Free Security clutter: 00681 // 00682 00683 if ( Job->Token ) { 00684 ObDereferenceObject( Job->Token ); 00685 Job->Token = NULL ; 00686 } 00687 00688 if ( Job->Filter ) { 00689 if ( Job->Filter->CapturedSids ) { 00690 ExFreePool( Job->Filter->CapturedSids ); 00691 } 00692 00693 if ( Job->Filter->CapturedPrivileges ) { 00694 ExFreePool( Job->Filter->CapturedPrivileges ); 00695 } 00696 00697 if ( Job->Filter->CapturedGroups ) { 00698 ExFreePool( Job->Filter->CapturedGroups ); 00699 } 00700 00701 ExFreePool( Job->Filter ); 00702 00703 } 00704 00705 ExDeleteResource(&Job->JobLock); 00706 }

NTSTATUS PspLookupKernelUserEntryPoints VOID   ) 
 

Definition at line 25 of file kulokup2.c.

References FALSE, KeRaiseUserExceptionDispatcher, KeUserApcDispatcher, KeUserCallbackDispatcher, KeUserExceptionDispatcher, NT_SUCCESS, NTSTATUS(), PspLookupSystemDllEntryPoint(), and Status.

Referenced by PspInitializeSystemDll().

00029 : 00030 00031 The function locates user mode code that the kernel dispatches 00032 to, and stores the addresses of that code in global kernel variables. 00033 00034 Which procedures are of interest is machine dependent. 00035 00036 Arguments: 00037 00038 None. 00039 00040 Return Value: 00041 00042 NTSTATUS 00043 00044 --*/ 00045 00046 { 00047 // 00048 // NOTE WELL - This is a dummy stub to make the system build. 00049 // Replace it with proper code 00050 // 00051 00052 return STATUS_SUCCESS; 00053 } }

NTSTATUS PspLookupSystemDllEntryPoint IN PSZ  EntryPointName,
OUT PVOID *  EntryPointAddress
 

Definition at line 827 of file psinit.c.

References _SYSTEM_DLL::DllBase, LookupEntryPoint(), and PspSystemDll.

Referenced by PspInitializeSystemDll(), and PspLookupKernelUserEntryPoints().

00832 { 00833 return LookupEntryPoint ( 00834 PspSystemDll.DllBase, 00835 NameOfEntryPoint, 00836 AddressOfEntryPoint 00837 ); 00838 }

NTSTATUS PspMapSystemDll IN PEPROCESS  Process,
OUT PVOID *DllBase  OPTIONAL
 

Definition at line 679 of file psinit.c.

References DbgPrint, L, MmMapViewOfSection(), NTSTATUS(), NULL, PAGED_CODE, PspSystemDll, and _SYSTEM_DLL::Section.

Referenced by PsLocateSystemDll(), and PspCreateProcess().

00686 : 00687 00688 This function maps the system DLL into the specified process. 00689 00690 Arguments: 00691 00692 Process - Supplies the address of the process to map the DLL into. 00693 00694 Return Value: 00695 00696 TBD 00697 00698 --*/ 00699 00700 { 00701 NTSTATUS st; 00702 PVOID ViewBase; 00703 LARGE_INTEGER SectionOffset; 00704 SIZE_T ViewSize; 00705 00706 PAGED_CODE(); 00707 00708 ViewBase = NULL; 00709 SectionOffset.LowPart = 0; 00710 SectionOffset.HighPart = 0; 00711 ViewSize = 0; 00712 00713 // 00714 // Map the system dll into the user part of the address space 00715 // 00716 00717 st = MmMapViewOfSection( 00718 PspSystemDll.Section, 00719 Process, 00720 &ViewBase, 00721 0L, 00722 0L, 00723 &SectionOffset, 00724 &ViewSize, 00725 ViewShare, 00726 0L, 00727 PAGE_READWRITE 00728 ); 00729 00730 if ( st != STATUS_SUCCESS ) { 00731 #if DBG 00732 DbgPrint("PS: Unable to map system dll at based address.\n"); 00733 #endif 00734 st = STATUS_CONFLICTING_ADDRESSES; 00735 } 00736 00737 if ( ARGUMENT_PRESENT(DllBase) ) { 00738 *DllBase = ViewBase; 00739 } 00740 00741 return st; 00742 }

USHORT PspNameToOrdinal IN PSZ  EntryPointName,
IN ULONG  DllBase,
IN ULONG  NumberOfNames,
IN PULONG  NameTableBase,
IN PUSHORT  OrdinalTableBase
 

VOID PspNullSpecialApc IN PKAPC  Apc,
IN OUT PKNORMAL_ROUTINE NormalRoutine,
IN OUT PVOID *  NormalContext,
IN OUT PVOID *  SystemArgument1,
IN OUT PVOID *  SystemArgument2
 

VOID PspProcessDelete IN PVOID  Object  ) 
 

Definition at line 1363 of file psdelete.c.

References _KPROCESS::DirectoryTableBase, ExDestroyHandle(), ExFreePool(), FALSE, _EPROCESS::Job, KeBugCheck(), KeStackAttachProcess(), KeTerminateProcess, KeUnstackDetachProcess(), MmDeleteProcessAddressSpace(), NULL, ObDereferenceDeviceMap(), ObDereferenceObject, PAGED_CODE, PERFINFO_PROCESS_DELETE, PspCidTable, PspDeleteLdt(), PspDeleteProcessSecurity(), PspDeleteVdmObjects(), PspDereferenceQuota(), PspExitProcess(), PspRemoveProcessFromJob(), SeAuditProcessExit(), SeDetailedAuditing, and _EPROCESS::Token.

Referenced by PspInitPhase0().

01366 { 01367 PEPROCESS Process; 01368 ULONG AddressSpace; 01369 KAPC_STATE ApcState; 01370 01371 PAGED_CODE(); 01372 01373 Process = (PEPROCESS)Object; 01374 01375 if ( SeDetailedAuditing && Process->Token != NULL ) { 01376 SeAuditProcessExit( 01377 Process 01378 ); 01379 } 01380 01381 if ( Process->Job ) { 01382 PspRemoveProcessFromJob(Process->Job,Process); 01383 ObDereferenceObject(Process->Job); 01384 } 01385 01386 KeTerminateProcess((PKPROCESS)Process); 01387 AddressSpace = (ULONG) 01388 ((PHARDWARE_PTE)(&(Process->Pcb.DirectoryTableBase[0])))->PageFrameNumber; 01389 01390 01391 if (Process->DebugPort) { 01392 ObDereferenceObject(Process->DebugPort); 01393 } 01394 if (Process->ExceptionPort) { 01395 ObDereferenceObject(Process->ExceptionPort); 01396 } 01397 if ( Process->UniqueProcessId ) { 01398 if ( !(ExDestroyHandle(PspCidTable,Process->UniqueProcessId,NULL))) { 01399 KeBugCheck(CID_HANDLE_DELETION); 01400 } 01401 } 01402 01403 PspDeleteLdt( Process ); 01404 PspDeleteVdmObjects( Process ); 01405 01406 if ( AddressSpace ) { 01407 01408 // 01409 // Clean address space of the process 01410 // 01411 01412 KeStackAttachProcess(&Process->Pcb, &ApcState); 01413 01414 PspExitProcess(FALSE,Process); 01415 01416 KeUnstackDetachProcess(&ApcState); 01417 } 01418 01419 PspDeleteProcessSecurity( Process ); 01420 01421 if (AddressSpace) { 01422 MmDeleteProcessAddressSpace(Process); 01423 } 01424 01425 #if DEVL 01426 if ( Process->WorkingSetWatch ) { 01427 ExFreePool(Process->WorkingSetWatch); 01428 } 01429 #endif // DEVL 01430 01431 PERFINFO_PROCESS_DELETE(Process); 01432 01433 ObDereferenceDeviceMap(Process); 01434 PspDereferenceQuota(Process); 01435 }

VOID PspProcessDump IN PVOID  Object,
IN POB_DUMP_CONTROL Control  OPTIONAL
 

NTSTATUS PspQueryDescriptorThread PETHREAD  Thread,
PVOID  ThreadInformation,
ULONG  ThreadInformationLength,
PULONG  ReturnLength
 

Definition at line 112 of file alpha/psldt.c.

Referenced by NtQueryInformationThread().

00120 : 00121 00122 This function returns STATUS_NOT_IMPLEMENTED 00123 00124 Arguments: 00125 00126 Thread -- Supplies a pointer to the thread. 00127 ThreadInformation -- Supplies information on the descriptor. 00128 ThreadInformationLength -- Supplies the length of the information. 00129 ReturnLength -- Returns the number of bytes returned. 00130 00131 Return Value: 00132 00133 STATUS_NOT_IMPLEMENTED 00134 --*/ 00135 { 00136 return STATUS_NOT_IMPLEMENTED; 00137 }

NTSTATUS PspQueryLdtInformation IN PEPROCESS  Process,
OUT PVOID  LdtInformation,
IN ULONG  LdtInformationLength,
OUT PULONG  ReturnLength
 

Definition at line 25 of file alpha/psldt.c.

Referenced by NtQueryInformationProcess().

00033 : 00034 00035 This routine returns STATUS_NOT_IMPLEMENTED 00036 00037 Arguments: 00038 00039 Process -- Supplies a pointer to the process to return LDT info for 00040 LdtInformation -- Supplies a pointer to the buffer 00041 ReturnLength -- Returns the number of bytes put into the buffer 00042 00043 Return Value: 00044 00045 STATUS_NOT_IMPLEMENTED 00046 --*/ 00047 { 00048 return STATUS_NOT_IMPLEMENTED; 00049 }

VOID PspReaper IN PVOID  StartContext  ) 
 

Definition at line 57 of file psdelete.c.

References FALSE, _KTHREAD::InitialStack, KiLockContextSwap, KiLockDispatcherDatabase, KiUnlockContextSwap, KiUnlockDispatcherDatabase(), _KTHREAD::LargeStack, MmDeleteKernelStack(), NULL, ObDereferenceObject, PsReaperActive, PsReaperListHead, _KTHREAD::StackBase, _ETHREAD::Tcb, and THREAD_TO_PROCESS.

Referenced by PspInitPhase0().

00063 : 00064 00065 This routine implements the thread reaper. The reaper is responsible 00066 for processing terminated threads. This includes: 00067 00068 - deallocating their kernel stacks 00069 00070 - releasing their process' CreateDelete lock 00071 00072 - dereferencing their process 00073 00074 - dereferencing themselves 00075 00076 Arguments: 00077 00078 Context - NOT USED 00079 00080 Return Value: 00081 00082 None. 00083 00084 --*/ 00085 00086 { 00087 00088 PLIST_ENTRY NextEntry; 00089 KIRQL OldIrql, OldIrql2; 00090 PETHREAD Thread; 00091 PEPROCESS Process; 00092 00093 00094 // 00095 // Lock the dispatcher data and continually remove entries from the 00096 // reaper list until no more entries exist. 00097 // 00098 // N.B. The dispatcher database lock is used to synchronize access to 00099 // the reaper list. This is done to avoid a race condition with 00100 // the thread termination code. 00101 // 00102 00103 KiLockDispatcherDatabase(&OldIrql); 00104 NextEntry = PsReaperListHead.Flink; 00105 while (NextEntry != &PsReaperListHead) { 00106 00107 // 00108 // Remove the next thread from the reaper list, get the address of 00109 // the executive thread object, acquire the context swap lock, and 00110 // then release the both the context swap dispatcher database locks. 00111 // 00112 // N.B. The context swap lock is acquired and immediately released. 00113 // This is necessary to ensure that the respective thread has 00114 // completely passed through the context switch code before it 00115 // is terminated. 00116 // 00117 00118 RemoveEntryList(NextEntry); 00119 Thread = CONTAINING_RECORD(NextEntry, ETHREAD, TerminationPortList); 00120 00121 KiLockContextSwap(&OldIrql2); 00122 KiUnlockContextSwap(OldIrql2); 00123 00124 KiUnlockDispatcherDatabase(OldIrql); 00125 00126 // 00127 // Get the address of the executive process object, release the 00128 // process' CreateDelete lock and then dereference the process 00129 // object. 00130 // 00131 00132 Process = THREAD_TO_PROCESS(Thread); 00133 // 00134 // Delete the kernel stack and dereference the thread. 00135 // 00136 00137 MmDeleteKernelStack(Thread->Tcb.StackBase,(BOOLEAN)Thread->Tcb.LargeStack); 00138 Thread->Tcb.InitialStack = NULL; 00139 ObDereferenceObject(Thread); 00140 00141 // 00142 // Lock the dispatcher database and get the address of the next 00143 // entry in the list. 00144 // 00145 00146 KiLockDispatcherDatabase(&OldIrql); 00147 NextEntry = PsReaperListHead.Flink; 00148 } 00149 00150 // 00151 // Set the reaper not active and unlock the dispatcher database. 00152 // 00153 00154 PsReaperActive = FALSE; 00155 KiUnlockDispatcherDatabase(OldIrql); 00156 return; 00157 }

VOID PspRemoveProcessFromJob PEJOB  Job,
PEPROCESS  Process
 

Definition at line 579 of file psjob.c.

References _EJOB::ActiveProcesses, ExAcquireResourceExclusive, ExReleaseResource, _EPROCESS::JobLinks, _EJOB::JobLock, _EPROCESS::JobStatus, KeEnterCriticalRegion, KeLeaveCriticalRegion, PAGED_CODE, PS_JOB_STATUS_NOT_REALLY_ACTIVE, PS_SET_BITS, PspFoldProcessAccountingIntoJob(), and TRUE.

Referenced by PspProcessDelete().

00583 { 00584 PAGED_CODE(); 00585 00586 KeEnterCriticalRegion(); 00587 ExAcquireResourceExclusive(&Job->JobLock, TRUE); 00588 00589 RemoveEntryList(&Process->JobLinks); 00590 00591 // 00592 // Update REMOVE accounting info 00593 // 00594 00595 00596 if ( !(Process->JobStatus & PS_JOB_STATUS_NOT_REALLY_ACTIVE) ) { 00597 Job->ActiveProcesses--; 00598 PS_SET_BITS (&Process->JobStatus, PS_JOB_STATUS_NOT_REALLY_ACTIVE); 00599 } 00600 00601 PspFoldProcessAccountingIntoJob(Job,Process); 00602 00603 ExReleaseResource(&Job->JobLock); 00604 KeLeaveCriticalRegion(); 00605 }

VOID PspSetContext OUT PKTRAP_FRAME  TrapFrame,
OUT PKNONVOLATILE_CONTEXT_POINTERS  NonVolatileContext,
IN PCONTEXT  Context,
KPROCESSOR_MODE  Mode
 

Definition at line 88 of file psctx386.c.

References ASSERT, KeContextToKframes(), KernelMode, NULL, and PAGED_CODE.

Referenced by PspGetSetContextApc(), PspGetSetContextSpecialApc(), and PspGetSetContextSpecialApcMain().

00097 : 00098 00099 This function moves the contents of the specified context record 00100 into the specified trap frame, and modifies the thread's non volatile 00101 context by storing through the thread's nonvolatile context pointers. 00102 00103 N.B. - NonVolatileContext is IGNORED on the 386. 00104 00105 Arguments: 00106 00107 TrapFrame - Returns selected pieces of the context record. 00108 00109 Context - Supplies a context record to be copied in the trap and 00110 nonvolatile context. 00111 00112 Mode - Supplies the mode to be used when sanitizing the psr, epsr and fsr 00113 00114 Return Value: 00115 00116 None. 00117 00118 --*/ 00119 00120 { 00121 UNREFERENCED_PARAMETER( NonVolatileContext ); 00122 ASSERT(((TrapFrame->SegCs & MODE_MASK) != KernelMode) || 00123 (TrapFrame->EFlags & EFLAGS_V86_MASK)); 00124 00125 PAGED_CODE(); 00126 00127 KeContextToKframes(TrapFrame, NULL, Context, Context->ContextFlags, Mode); 00128 }

NTSTATUS PspSetLdtInformation IN PEPROCESS  Process,
IN PVOID  LdtInformation,
IN ULONG  LdtInformationLength
 

Definition at line 81 of file alpha/psldt.c.

Referenced by NtSetInformationProcess().

00089 : 00090 00091 This function returns STATUS_NOT_IMPLEMENTED 00092 00093 Arguments: 00094 00095 Process -- Supplies a pointer to the process whose Ldt is to be modified 00096 LdtInformation -- Supplies a pointer to the information about the Ldt 00097 modifications 00098 LdtInformationLength -- Supplies the length of the LdtInformation 00099 structure. 00100 Return Value: 00101 00102 00103 Return Value: 00104 00105 STATUS_NOT_IMPLEMENTED 00106 --*/ 00107 { 00108 return STATUS_NOT_IMPLEMENTED; 00109 }

NTSTATUS PspSetLdtSize IN PEPROCESS  Process,
IN PVOID  LdtSize,
IN ULONG  LdtSizeLength
 

Definition at line 53 of file alpha/psldt.c.

Referenced by NtSetInformationProcess().

00061 : 00062 00063 This function returns STATUS_NOT_IMPLEMENTED 00064 00065 Arguments: 00066 00067 Process -- Supplies a pointer to the process whose Ldt is to be sized 00068 LdtSize -- Supplies a pointer to the size information 00069 00070 00071 Return Value: 00072 00073 STATUS_NOT_IMPLEMENTED 00074 --*/ 00075 { 00076 return STATUS_NOT_IMPLEMENTED; 00077 }

NTSTATUS PspSetPrimaryToken IN HANDLE  ProcessHandle,
IN HANDLE TokenHandle  OPTIONAL,
IN PACCESS_TOKEN TokenPointer  OPTIONAL
 

Definition at line 366 of file psquery.c.

References _SECURITY_SUBJECT_CONTEXT::ClientToken, FALSE, _OBJECT_TYPE_INITIALIZER::GenericMapping, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObGetObjectSecurity(), ObReferenceObjectByHandle(), ObReleaseObjectSecurity(), _SECURITY_SUBJECT_CONTEXT::PrimaryToken, _SECURITY_SUBJECT_CONTEXT::ProcessAuditId, PsDereferencePrimaryToken, PspAssignPrimaryToken(), PsProcessType, PsReferencePrimaryToken(), SeAccessCheck(), SeAssignPrimaryTokenPrivilege, SeCheckPrivilegedObject(), SeIsChildTokenByPointer(), SeTokenObjectType, and _OBJECT_TYPE::TypeInfo.

Referenced by NtAssignProcessToJobObject(), and NtSetInformationProcess().

00377 { 00378 NTSTATUS st ; 00379 BOOLEAN HasPrivilege ; 00380 BOOLEAN IsChildToken ; 00381 PEPROCESS Process ; 00382 KPROCESSOR_MODE PreviousMode ; 00383 00384 // 00385 // Check to see if the supplied token is a child of the caller's 00386 // token. If so, we don't need to do the privilege check. 00387 // 00388 00389 PreviousMode = KeGetPreviousMode(); 00390 00391 if ( TokenHandle ) 00392 { 00393 // 00394 // Reference the specified token, and make sure it can be assigned 00395 // as a primary token. 00396 // 00397 00398 st = ObReferenceObjectByHandle ( 00399 TokenHandle, 00400 TOKEN_ASSIGN_PRIMARY, 00401 SeTokenObjectType(), 00402 PreviousMode, 00403 (PVOID *)&TokenPointer, 00404 NULL 00405 ); 00406 00407 if (!NT_SUCCESS(st)) { 00408 return( st ); 00409 } 00410 } 00411 00412 st = SeIsChildTokenByPointer( 00413 TokenPointer, 00414 &IsChildToken 00415 ); 00416 00417 if (!NT_SUCCESS(st)) { 00418 00419 if ( TokenHandle ) { 00420 ObDereferenceObject( TokenPointer ); 00421 } 00422 return( st ); 00423 } 00424 00425 if (!IsChildToken ) { 00426 00427 00428 // 00429 // SeCheckPrivilegedObject will perform auditing as appropriate 00430 // 00431 00432 HasPrivilege = SeCheckPrivilegedObject( 00433 SeAssignPrimaryTokenPrivilege, 00434 ProcessHandle, 00435 PROCESS_SET_INFORMATION, 00436 PreviousMode 00437 ); 00438 00439 if ( !HasPrivilege ) { 00440 00441 if ( TokenHandle ) { 00442 ObDereferenceObject( TokenPointer ); 00443 } 00444 00445 return( STATUS_PRIVILEGE_NOT_HELD ); 00446 } 00447 00448 } 00449 00450 st = ObReferenceObjectByHandle( 00451 ProcessHandle, 00452 PROCESS_SET_INFORMATION, 00453 PsProcessType, 00454 PreviousMode, 00455 (PVOID *)&Process, 00456 NULL 00457 ); 00458 00459 if ( NT_SUCCESS(st) ) { 00460 00461 // 00462 // Check for proper access to the token, and assign the primary 00463 // token for the process. 00464 // 00465 00466 st = PspAssignPrimaryToken( Process, NULL, TokenPointer ); 00467 00468 // 00469 // Recompute the process's access to itself for use 00470 // with the CurrentProcess() pseudo handle. 00471 // 00472 00473 if ( NT_SUCCESS(st) ) { 00474 00475 NTSTATUS accesst; 00476 BOOLEAN AccessCheck; 00477 BOOLEAN MemoryAllocated; 00478 PSECURITY_DESCRIPTOR SecurityDescriptor; 00479 SECURITY_SUBJECT_CONTEXT SubjectContext; 00480 00481 st = ObGetObjectSecurity( 00482 Process, 00483 &SecurityDescriptor, 00484 &MemoryAllocated 00485 ); 00486 00487 if ( NT_SUCCESS(st) ) { 00488 00489 // 00490 // Compute the subject security context 00491 // 00492 00493 SubjectContext.ProcessAuditId = Process; 00494 SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process); 00495 SubjectContext.ClientToken = NULL; 00496 AccessCheck = SeAccessCheck( 00497 SecurityDescriptor, 00498 &SubjectContext, 00499 FALSE, 00500 MAXIMUM_ALLOWED, 00501 0, 00502 NULL, 00503 &PsProcessType->TypeInfo.GenericMapping, 00504 PreviousMode, 00505 &Process->GrantedAccess, 00506 &accesst 00507 ); 00508 PsDereferencePrimaryToken(SubjectContext.PrimaryToken); 00509 ObReleaseObjectSecurity( 00510 SecurityDescriptor, 00511 MemoryAllocated 00512 ); 00513 if ( !AccessCheck ) { 00514 Process->GrantedAccess = 0; 00515 } 00516 } 00517 } 00518 00519 ObDereferenceObject(Process); 00520 } 00521 00522 if ( TokenHandle) { 00523 ObDereferenceObject( TokenPointer ); 00524 } 00525 00526 return st; 00527 }

NTSTATUS PspSetProcessIoHandlers IN PEPROCESS  Process,
IN PVOID  IoHandlerInformation,
IN ULONG  IoHandlerLength
 

Definition at line 25 of file alpha/psvdm.c.

00032 : 00033 00034 This routine returns STATUS_NOT_IMPLEMENTED 00035 00036 Arguments: 00037 00038 Process -- Supplies a pointer to the process for which Io port handlers 00039 are to be installed 00040 IoHandlerInformation -- Supplies a pointer to the information about the 00041 io port handlers 00042 IoHandlerLength -- Supplies the length of the IoHandlerInformation 00043 structure. 00044 00045 Return Value: 00046 00047 Returns STATUS_NOT_IMPLEMENTED 00048 00049 --*/ 00050 { 00051 UNREFERENCED_PARAMETER(Process); 00052 UNREFERENCED_PARAMETER(IoHandlerInformation); 00053 UNREFERENCED_PARAMETER(IoHandlerLength); 00054 return STATUS_NOT_IMPLEMENTED; 00055 }

VOID PspSystemThreadStartup IN PKSTART_ROUTINE  StartRoutine,
IN PVOID  StartContext
 

Definition at line 1920 of file ps/create.c.

References _ETHREAD::DeadThread, _ETHREAD::HasTerminated, KeBugCheck(), KeLowerIrql(), KMODE_EXCEPTION_NOT_HANDLED, MmAllowWorkingSetExpansion(), PsGetCurrentThread, PspExitThread(), and PspUnhandledExceptionInSystemThread().

Referenced by PspCreateThread().

01927 : 01928 01929 This function is called by the kernel to start a system thread. 01930 01931 Arguments: 01932 01933 StartRoutine - Supplies the address of the system threads entry point. 01934 01935 StartContext - Supplies a context value for the system thread. 01936 01937 Return Value: 01938 01939 None. 01940 01941 --*/ 01942 01943 { 01944 01945 PETHREAD Thread; 01946 01947 MmAllowWorkingSetExpansion(); 01948 01949 KeLowerIrql(0); 01950 01951 Thread = PsGetCurrentThread(); 01952 01953 try { 01954 if ( !Thread->DeadThread && !Thread->HasTerminated ) { 01955 (StartRoutine)(StartContext); 01956 } 01957 } 01958 except (PspUnhandledExceptionInSystemThread(GetExceptionInformation())) { 01959 KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED); 01960 } 01961 PspExitThread(STATUS_SUCCESS); 01962 01963 }

BOOLEAN PspTerminateAllProcessesInJob PEJOB  Job,
NTSTATUS  Status,
PSLOCKPROCESSMODE  LockMode
 

Definition at line 2570 of file psjob.c.

References _EJOB::ActiveProcesses, FALSE, _EPROCESS::JobStatus, ObDereferenceObject, ObGetObjectPointerCount(), ObReferenceObject, PAGED_CODE, _EJOB::ProcessListHead, PS_JOB_STATUS_NOT_REALLY_ACTIVE, PS_SET_BITS, PsLockPollOnTimeout, PspFoldProcessAccountingIntoJob(), PspTerminateProcess(), Status, _EJOB::TotalTerminatedProcesses, and TRUE.

Referenced by NtTerminateJobObject(), and PsEnforceExecutionTimeLimits().

02575 { 02576 PLIST_ENTRY NextProcess; 02577 PEPROCESS Process; 02578 BOOLEAN TerminatedAProcess; 02579 02580 PAGED_CODE(); 02581 02582 TerminatedAProcess = FALSE; 02583 NextProcess = Job->ProcessListHead.Flink; 02584 02585 while ( NextProcess != &Job->ProcessListHead) { 02586 02587 Process = (PEPROCESS)(CONTAINING_RECORD(NextProcess,EPROCESS,JobLinks)); 02588 02589 // 02590 // Reference the process. Assert that it is not in its 02591 // delete routine. If all is OK, then nuke and dereferece 02592 // the process 02593 // 02594 02595 ObReferenceObject(Process); 02596 02597 // 02598 // Avoid double delete since process could be in delete routine during the above ref 02599 // 02600 if ( ObGetObjectPointerCount(Process) > 1 ) { 02601 if ( !(Process->JobStatus & PS_JOB_STATUS_NOT_REALLY_ACTIVE) ) { 02602 02603 if ( PspTerminateProcess(Process,Status,LockMode) == STATUS_SUCCESS ) { 02604 02605 // 02606 // If the lockmode isn't poll, it means we ran out of 02607 // job time, so increment the terminated process count 02608 // for each nuked process 02609 // 02610 if ( LockMode != PsLockPollOnTimeout ) { 02611 Job->TotalTerminatedProcesses++; 02612 } 02613 PS_SET_BITS (&Process->JobStatus, PS_JOB_STATUS_NOT_REALLY_ACTIVE); 02614 Job->ActiveProcesses--; 02615 02616 PspFoldProcessAccountingIntoJob(Job,Process); 02617 02618 TerminatedAProcess = TRUE; 02619 } 02620 } 02621 02622 ObDereferenceObject(Process); 02623 } 02624 02625 NextProcess = NextProcess->Flink; 02626 } 02627 return TerminatedAProcess; 02628 }

NTSTATUS PspTerminateProcess PEPROCESS  Process,
NTSTATUS  Status,
PSLOCKPROCESSMODE  LockMode
 

Definition at line 384 of file psdelete.c.

References _ETHREAD::HasTerminated, IS_SYSTEM_THREAD, KeForceResumeThread(), KernelMode, NTSTATUS(), ObDereferenceObject, PAGED_CODE, PsGetCurrentProcess, PsLockProcess(), PspTerminateThreadByPointer(), PsUnlockProcess(), Status, _ETHREAD::Tcb, _EPROCESS::ThreadListHead, and TRUE.

Referenced by NtAssignProcessToJobObject(), PsEnforceExecutionTimeLimits(), and PspTerminateAllProcessesInJob().

00392 : 00393 00394 This function causes the specified process and all of 00395 its threads to terminate. 00396 00397 Arguments: 00398 00399 ProcessHandle - Supplies a handle to the process to terminate. 00400 00401 ExitStatus - Supplies the exit status associated with the process. 00402 00403 Return Value: 00404 00405 TBD 00406 00407 --*/ 00408 00409 { 00410 00411 PETHREAD Thread; 00412 PLIST_ENTRY Next; 00413 NTSTATUS st; 00414 00415 PAGED_CODE(); 00416 00417 if ( Process == PsGetCurrentProcess() ) { 00418 return STATUS_INVALID_PARAMETER; 00419 } 00420 00421 // 00422 // the following allows NtTerminateProcess to fail properly if 00423 // called while the exiting process is blocked holding the 00424 // createdeletelock. This can happen during debugger/server 00425 // lpc transactions that occur in pspexitthread 00426 // 00427 00428 st = PsLockProcess(Process,KernelMode,LockMode); 00429 00430 if ( st != STATUS_SUCCESS ) { 00431 return st; 00432 } 00433 00434 Next = Process->ThreadListHead.Flink; 00435 00436 while ( Next != &Process->ThreadListHead) { 00437 00438 Thread = (PETHREAD)(CONTAINING_RECORD(Next,ETHREAD,ThreadListEntry)); 00439 00440 if ( IS_SYSTEM_THREAD(Thread) ) { 00441 ObDereferenceObject(Process); 00442 PsUnlockProcess(Process); 00443 return STATUS_INVALID_PARAMETER; 00444 } 00445 00446 if ( !Thread->HasTerminated ) { 00447 Thread->HasTerminated = TRUE; 00448 PspTerminateThreadByPointer(Thread, Status); 00449 KeForceResumeThread(&Thread->Tcb); 00450 } 00451 Next = Next->Flink; 00452 } 00453 00454 PsUnlockProcess(Process); 00455 00456 return STATUS_SUCCESS; 00457 }

NTSTATUS PspTerminateThreadByPointer IN PETHREAD  Thread,
IN NTSTATUS  ExitStatus
 

Definition at line 160 of file psdelete.c.

References ExAllocatePool, ExFreePool(), KeInitializeApc(), KeInsertQueueApc(), KernelMode, NonPagedPool, NULL, ObDereferenceObject, OriginalApcEnvironment, PAGED_CODE, PsExitSpecialApc(), PsGetCurrentThread, PspExitNormalApc(), and PspExitThread().

Referenced by NtTerminateProcess(), NtTerminateThread(), and PspTerminateProcess().

00167 : 00168 00169 This function causes the specified thread to terminate. 00170 00171 Arguments: 00172 00173 ThreadHandle - Supplies a referenced pointer to the thread to terminate. 00174 00175 ExitStatus - Supplies the exit status associated with the thread. 00176 00177 Return Value: 00178 00179 TBD 00180 00181 --*/ 00182 00183 { 00184 00185 PKAPC ExitApc; 00186 00187 PAGED_CODE(); 00188 00189 if ( Thread == PsGetCurrentThread() ) { 00190 ObDereferenceObject(Thread); 00191 PspExitThread(ExitStatus); 00192 00193 // 00194 // Never Returns 00195 // 00196 00197 } else { 00198 ExitApc = ExAllocatePool(NonPagedPool,(ULONG)sizeof(KAPC)); 00199 00200 if ( !ExitApc ) { 00201 return STATUS_INSUFFICIENT_RESOURCES; 00202 } 00203 00204 KeInitializeApc( 00205 ExitApc, 00206 &Thread->Tcb, 00207 OriginalApcEnvironment, 00208 PsExitSpecialApc, 00209 NULL, 00210 PspExitNormalApc, 00211 KernelMode, 00212 ULongToPtr(ExitStatus) // Sundown: ExitStatus is zero-extended. 00213 ); 00214 00215 00216 if ( !KeInsertQueueApc(ExitApc,ExitApc,NULL, 2) ) { 00217 ExFreePool(ExitApc); 00218 00219 return STATUS_UNSUCCESSFUL; 00220 } 00221 } 00222 00223 return STATUS_SUCCESS; 00224 }

VOID PspThreadDelete IN PVOID  Object  ) 
 

Definition at line 1438 of file psdelete.c.

References ASSERT, _ETHREAD::Cid, ExDestroyHandle(), _KTHREAD::InitialStack, KeBugCheck(), _KTHREAD::LargeStack, MmDeleteKernelStack(), NULL, ObDereferenceObject, PAGED_CODE, PERFINFO_THREAD_DELETE, PspCidTable, PspDeleteThreadSecurity(), _ETHREAD::Tcb, THREAD_TO_PROCESS, and _KTHREAD::Win32Thread.

Referenced by PspInitPhase0().

01441 { 01442 PETHREAD Thread; 01443 PEPROCESS Process; 01444 01445 PAGED_CODE(); 01446 01447 Thread = (PETHREAD) Object; 01448 01449 PERFINFO_THREAD_DELETE(Thread); 01450 01451 ASSERT(Thread->Tcb.Win32Thread == NULL); 01452 01453 if ( Thread->Tcb.InitialStack ) { 01454 MmDeleteKernelStack(Thread->Tcb.InitialStack,(BOOLEAN)Thread->Tcb.LargeStack); 01455 } 01456 01457 if ( Thread->Cid.UniqueThread ) { 01458 if (!(ExDestroyHandle(PspCidTable,Thread->Cid.UniqueThread,NULL))) { 01459 KeBugCheck(CID_HANDLE_DELETION); 01460 } 01461 } 01462 01463 PspDeleteThreadSecurity( Thread ); 01464 01465 Process = THREAD_TO_PROCESS(Thread); 01466 if (Process) { 01467 ObDereferenceObject(Process); 01468 } 01469 }

VOID PspThreadDump IN PVOID  Object,
IN POB_DUMP_CONTROL Control  OPTIONAL
 

VOID PspUserThreadStartup IN PKSTART_ROUTINE  StartRoutine,
IN PVOID  StartContext
 

Definition at line 1800 of file ps/create.c.

References _KTHREAD::ApcState, DbgkCreateThread(), _ETHREAD::DeadThread, _SYSTEM_DLL::DllBase, ExAllocatePool, ExFreePool(), _ETHREAD::HasTerminated, KeInitializeApc(), KeInsertQueueApc(), KeLowerIrql(), _SYSTEM_DLL::LoaderInitRoutine, MmAllowWorkingSetExpansion(), NonPagedPoolMustSucceed, NULL, OriginalApcEnvironment, PAGED_CODE, _EPROCESS::Pcb, PsDefaultThreadLocaleId, PsGetCurrentProcess, PsGetCurrentThread, PspExitThread(), PspNullSpecialApc(), PspSystemDll, _ETHREAD::Tcb, TRUE, _KAPC_STATE::UserApcPending, UserMode, and _KPROCESS::UserTime.

Referenced by PspCreateThread().

01807 : 01808 01809 This function is called by the kernel to start a user-mode thread. 01810 01811 Arguments: 01812 01813 StartRoutine - Ignored. 01814 01815 StartContext - Supplies the initial pc value for the thread. 01816 01817 Return Value: 01818 01819 None. 01820 01821 --*/ 01822 01823 { 01824 PETHREAD Thread; 01825 PKAPC StartApc; 01826 PEPROCESS Process; 01827 01828 PAGED_CODE(); 01829 01830 UNREFERENCED_PARAMETER(StartRoutine); 01831 01832 Process = PsGetCurrentProcess(); 01833 01834 // 01835 // All threads start with an APC at LdrInitializeThunk 01836 // 01837 01838 MmAllowWorkingSetExpansion(); 01839 01840 Thread = PsGetCurrentThread(); 01841 01842 if ( !Thread->DeadThread && !Thread->HasTerminated ) { 01843 01844 StartApc = ExAllocatePool(NonPagedPoolMustSucceed,(ULONG)sizeof(KAPC)); 01845 01846 ((PTEB)PsGetCurrentThread()->Tcb.Teb)->CurrentLocale = PsDefaultThreadLocaleId; 01847 01848 KeInitializeApc( 01849 StartApc, 01850 &Thread->Tcb, 01851 OriginalApcEnvironment, 01852 PspNullSpecialApc, 01853 NULL, 01854 PspSystemDll.LoaderInitRoutine, 01855 UserMode, 01856 NULL 01857 ); 01858 01859 if ( !KeInsertQueueApc(StartApc,(PVOID) PspSystemDll.DllBase,NULL,0) ) { 01860 ExFreePool(StartApc); 01861 } else { 01862 Thread->Tcb.ApcState.UserApcPending = TRUE; 01863 } 01864 } else { 01865 01866 if ( !Thread->DeadThread ) { 01867 01868 // 01869 // If DeadThread is not set, then it means the thread was terminated before 01870 // it started, but creation was ok. Need to let debuggers see these threads 01871 // for an instant because if they are the last to exit, the exitprocess 01872 // message gets nuked 01873 // 01874 01875 KeLowerIrql(0); 01876 DbgkCreateThread(StartContext); 01877 01878 } 01879 PspExitThread(STATUS_THREAD_IS_TERMINATING); 01880 } 01881 01882 KeLowerIrql(0); 01883 01884 DbgkCreateThread(StartContext); 01885 01886 if ( Process->Pcb.UserTime == 0 ) { 01887 Process->Pcb.UserTime = 1; 01888 } 01889 01890 }


Variable Documentation

FAST_MUTEX PspActiveProcessMutex
 

Definition at line 524 of file psp.h.

PACCESS_TOKEN PspBootAccessToken
 

Definition at line 521 of file psp.h.

Referenced by PspInitializeProcessSecurity(), and PspInitPhase0().

PHANDLE_TABLE PspCidTable
 

Definition at line 519 of file psp.h.

PCREATE_PROCESS_NOTIFY_ROUTINE PspCreateProcessNotifyRoutine[PSP_MAX_CREATE_PROCESS_NOTIFY]
 

Definition at line 192 of file psp.h.

Referenced by PspCreateThread(), PspExitProcess(), and PsSetCreateProcessNotifyRoutine().

ULONG PspCreateProcessNotifyRoutineCount
 

Definition at line 191 of file psp.h.

Referenced by PspCreateThread(), PspExitProcess(), and PsSetCreateProcessNotifyRoutine().

PCREATE_THREAD_NOTIFY_ROUTINE PspCreateThreadNotifyRoutine[PSP_MAX_CREATE_THREAD_NOTIFY]
 

Definition at line 209 of file psp.h.

Referenced by PspCreateThread(), PspExitThread(), and PsSetCreateThreadNotifyRoutine().

ULONG PspCreateThreadNotifyRoutineCount
 

Definition at line 208 of file psp.h.

Referenced by PspCreateThread(), PspExitThread(), and PsSetCreateThreadNotifyRoutine().

ULONG PspDefaultNonPagedLimit
 

Definition at line 528 of file psp.h.

ULONG PspDefaultPagedLimit
 

Definition at line 527 of file psp.h.

ULONG PspDefaultPagefileLimit
 

Definition at line 529 of file psp.h.

EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
 

Definition at line 531 of file psp.h.

BOOLEAN PspDoingGiveBacks
 

Definition at line 532 of file psp.h.

Referenced by PspInitPhase0(), and PsReturnPoolQuota().

KSPIN_LOCK PspEventPairLock
 

Definition at line 522 of file psp.h.

SCHAR PspForegroundQuantum[3]
 

Definition at line 539 of file psp.h.

Referenced by PsChangeQuantumTable(), PspCreateProcess(), and PsSetProcessPriorityByClass().

HANDLE PspInitialSystemProcessHandle
 

Definition at line 520 of file psp.h.

LIST_ENTRY PspJobList
 

Definition at line 549 of file psp.h.

Referenced by NtCreateJobObject(), PsEnforceExecutionTimeLimits(), and PspInitPhase0().

FAST_MUTEX PspJobListLock
 

Definition at line 548 of file psp.h.

Referenced by NtCreateJobObject(), PsEnforceExecutionTimeLimits(), PspInitPhase0(), and PspJobDelete().

SCHAR PspJobSchedulingClasses[PSP_NUMBER_OF_SCHEDULING_CLASSES]
 

Definition at line 545 of file psp.h.

Referenced by PsChangeQuantumTable(), PspApplyJobLimitsToProcess(), and PsSetProcessPriorityByClass().

PLOAD_IMAGE_NOTIFY_ROUTINE PspLoadImageNotifyRoutine[PSP_MAX_LOAD_IMAGE_NOTIFY]
 

Definition at line 214 of file psp.h.

Referenced by PsCallImageNotifyRoutines(), and PsSetLoadImageNotifyRoutine().

ULONG PspLoadImageNotifyRoutineCount
 

Definition at line 213 of file psp.h.

Referenced by PsSetLoadImageNotifyRoutine().

FAST_MUTEX PspProcessLockMutex
 

Definition at line 525 of file psp.h.

Referenced by PsLockProcess(), PspInitPhase0(), and PsUnlockProcess().

SYSTEM_DLL PspSystemDll
 

Definition at line 523 of file psp.h.

Referenced by PsLocateSystemDll(), PspInitializeSystemDll(), PspLookupSystemDllEntryPoint(), PspMapSystemDll(), and PspUserThreadStartup().

BOOLEAN PspUseJobSchedulingClasses
 

Definition at line 546 of file psp.h.

Referenced by PsChangeQuantumTable(), PspApplyJobLimitsToProcess(), and PsSetProcessPriorityByClass().

PKWIN32_JOB_CALLOUT PspW32JobCallout
 

Definition at line 536 of file psp.h.

Referenced by NtAssignProcessToJobObject(), NtSetInformationJobObject(), PsEstablishWin32Callouts(), and PspJobDelete().

PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout
 

Definition at line 534 of file psp.h.

Referenced by PsConvertToGuiThread(), PsEstablishWin32Callouts(), and PspExitThread().

ULONG PspW32ProcessSize
 

Definition at line 537 of file psp.h.

PKWIN32_THREAD_CALLOUT PspW32ThreadCallout
 

Definition at line 535 of file psp.h.

Referenced by PsConvertToGuiThread(), PsEstablishWin32Callouts(), and PspExitThread().

ULONG PspW32ThreadSize
 

Definition at line 538 of file psp.h.

JOB_WORKING_SET_CHANGE_HEAD PspWorkingSetChangeHead
 

Definition at line 102 of file psp.h.

Referenced by NtSetInformationJobObject(), PspAddProcessToJob(), PspApplyJobLimitsToProcessSet(), and PspInitPhase0().


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