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

create.c File Reference

#include "psp.h"

Go to the source code of this file.

Functions

NTSTATUS NtCreateThread (OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, OUT PCLIENT_ID ClientId, IN PCONTEXT ThreadContext, IN PINITIAL_TEB InitialTeb, IN BOOLEAN CreateSuspended)
NTSTATUS PsCreateSystemThread (OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle OPTIONAL, OUT PCLIENT_ID ClientId OPTIONAL, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
BOOLEAN PspMarkProcessIdValid (IN PHANDLE_TABLE_ENTRY HandleEntry, IN ULONG_PTR Parameter)
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)
NTSTATUS NtCreateProcess (OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcess, IN BOOLEAN InheritObjectTable, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL)
NTSTATUS PsCreateSystemProcess (OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes 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 PsSetCreateProcessNotifyRoutine (IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, IN BOOLEAN Remove)
NTSTATUS PsSetCreateThreadNotifyRoutine (IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
VOID PspUserThreadStartup (IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
ULONG PspUnhandledExceptionInSystemThread (IN PEXCEPTION_POINTERS ExceptionPointers)
VOID PspSystemThreadStartup (IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
NTSTATUS PsLockProcess (IN PEPROCESS Process, IN KPROCESSOR_MODE WaitMode, IN PSLOCKPROCESSMODE LockMode)
VOID PsUnlockProcess (IN PEPROCESS Process)
HANDLE PsGetCurrentProcessId (VOID)
HANDLE PsGetCurrentThreadId (VOID)
BOOLEAN PsGetVersion (PULONG MajorVersion OPTIONAL, PULONG MinorVersion OPTIONAL, PULONG BuildNumber OPTIONAL, PUNICODE_STRING CSDVersion OPTIONAL)
NTSTATUS PsSetLoadImageNotifyRoutine (IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine)
VOID PsCallImageNotifyRoutines (IN PUNICODE_STRING FullImageName, IN HANDLE ProcessId, IN PIMAGE_INFO ImageInfo)

Variables

PVOID MmWorkingSetList
UNICODE_STRING CmCSDVersionString
LCID PsDefaultSystemLocaleId
LCID PsDefaultThreadLocaleId
LANGID PsDefaultUILanguageId
LANGID PsInstallUILanguageId
ULONG PsMinimumWorkingSet = 20
ULONG PsMaximumWorkingSet = 45
BOOLEAN PsImageNotifyEnabled
FAST_MUTEX PspProcessLockMutex


Function Documentation

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

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

References DebugPort, EXCEPTION_EXECUTE_HANDLER, KernelMode, NTSTATUS(), ObjectAttributes, PAGED_CODE, ProbeForWriteHandle, and PspCreateProcess().

Referenced by TestTokenOpenPrimary(), UdbgTest1(), and UdbgTest2().

00856 : 00857 00858 This routine creates a process object. 00859 00860 Arguments: 00861 00862 ProcessHandle - Returns the handle for the new process. 00863 00864 DesiredAccess - Supplies the desired access modes to the new process. 00865 00866 ObjectAttributes - Supplies the object attributes of the new process. 00867 . 00868 . 00869 . 00870 00871 Return Value: 00872 00873 TBD 00874 00875 --*/ 00876 00877 { 00878 NTSTATUS st; 00879 00880 PAGED_CODE(); 00881 00882 if ( KeGetPreviousMode() != KernelMode ) { 00883 00884 // 00885 // Probe all arguments 00886 // 00887 00888 try { 00889 ProbeForWriteHandle(ProcessHandle); 00890 } except(EXCEPTION_EXECUTE_HANDLER) { 00891 return GetExceptionCode(); 00892 } 00893 } 00894 00895 if ( ARGUMENT_PRESENT(ParentProcess) ) { 00896 st = PspCreateProcess( 00897 ProcessHandle, 00898 DesiredAccess, 00899 ObjectAttributes, 00900 ParentProcess, 00901 InheritObjectTable, 00902 SectionHandle, 00903 DebugPort, 00904 ExceptionPort 00905 ); 00906 } else { 00907 st = STATUS_INVALID_PARAMETER; 00908 } 00909 00910 return st; 00911 }

NTSTATUS NtCreateThread OUT PHANDLE  ThreadHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN HANDLE  ProcessHandle,
OUT PCLIENT_ID  ClientId,
IN PCONTEXT  ThreadContext,
IN PINITIAL_TEB  InitialTeb,
IN BOOLEAN  CreateSuspended
 

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

References EXCEPTION_EXECUTE_HANDLER, InitialTeb, KernelMode, NTSTATUS(), NULL, ObjectAttributes, PAGED_CODE, ProbeForRead, ProbeForWrite(), ProbeForWriteHandle, ProbeForWriteUlong, PspCreateThread(), ThreadContext, and ThreadHandle.

Referenced by TestTokenInitialize().

00080 : 00081 00082 This system service API creates and initializes a thread object. 00083 00084 Arguments: 00085 00086 ThreadHandle - Returns the handle for the new thread. 00087 00088 DesiredAccess - Supplies the desired access modes to the new thread. 00089 00090 ObjectAttributes - Supplies the object attributes of the new thread. 00091 00092 ProcessHandle - Supplies a handle to the process that the thread is being 00093 created within. 00094 00095 ClientId - Returns the CLIENT_ID of the new thread. 00096 00097 ThreadContext - Supplies an initial context for the new thread. 00098 00099 InitialTeb - Supplies the initial contents for the thread's TEB. 00100 00101 CreateSuspended - Supplies a value that controls whether or not a 00102 thread is created in a suspended state. 00103 00104 Return Value: 00105 00106 TBD 00107 00108 --*/ 00109 00110 { 00111 NTSTATUS st; 00112 INITIAL_TEB CapturedInitialTeb; 00113 00114 PAGED_CODE(); 00115 00116 if ( KeGetPreviousMode() != KernelMode ) { 00117 00118 // 00119 // Probe all arguments 00120 // 00121 00122 try { 00123 ProbeForWriteHandle(ThreadHandle); 00124 00125 if ( ARGUMENT_PRESENT(ClientId) ) { 00126 ProbeForWriteUlong((PULONG)ClientId); 00127 ProbeForWrite(ClientId, sizeof(CLIENT_ID), sizeof(ULONG)); 00128 } 00129 00130 if ( ARGUMENT_PRESENT(ThreadContext) ) { 00131 ProbeForRead(ThreadContext, sizeof(CONTEXT), CONTEXT_ALIGN); 00132 } 00133 else { 00134 return STATUS_INVALID_PARAMETER; 00135 } 00136 ProbeForRead(InitialTeb, sizeof(InitialTeb->OldInitialTeb), sizeof(ULONG)); 00137 CapturedInitialTeb.OldInitialTeb = InitialTeb->OldInitialTeb; 00138 if (CapturedInitialTeb.OldInitialTeb.OldStackBase == NULL && 00139 CapturedInitialTeb.OldInitialTeb.OldStackLimit == NULL 00140 ) { 00141 ProbeForRead(InitialTeb, sizeof(INITIAL_TEB), sizeof(ULONG)); 00142 CapturedInitialTeb = *InitialTeb; 00143 } 00144 } except(EXCEPTION_EXECUTE_HANDLER) { 00145 return GetExceptionCode(); 00146 } 00147 } else { 00148 if (InitialTeb->OldInitialTeb.OldStackBase == NULL && 00149 InitialTeb->OldInitialTeb.OldStackLimit == NULL 00150 ) { 00151 CapturedInitialTeb = *InitialTeb; 00152 } else { 00153 CapturedInitialTeb.OldInitialTeb = InitialTeb->OldInitialTeb; 00154 } 00155 } 00156 00157 st = PspCreateThread ( 00158 ThreadHandle, 00159 DesiredAccess, 00160 ObjectAttributes, 00161 ProcessHandle, 00162 NULL, 00163 ClientId, 00164 ThreadContext, 00165 &CapturedInitialTeb, 00166 CreateSuspended, 00167 NULL, 00168 NULL 00169 ); 00170 00171 return st; 00172 }

VOID PsCallImageNotifyRoutines IN PUNICODE_STRING  FullImageName,
IN HANDLE  ProcessId,
IN PIMAGE_INFO  ImageInfo
 

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

References NULL, PAGED_CODE, PIMAGE_INFO, PsImageNotifyEnabled, PSP_MAX_LOAD_IMAGE_NOTIFY, and PspLoadImageNotifyRoutine.

Referenced by DbgkCreateThread(), MiLoadSystemImage(), and MiMapViewOfImageSection().

02403 : 02404 02405 This function actually calls the registered image notify functions (on behalf) 02406 of mapview.c and sysload.c 02407 02408 Arguments: 02409 02410 FullImageName - The name of the image being loaded 02411 02412 ProcessId - The process that the image is being loaded into (0 for driver loads) 02413 02414 ImageInfo - Various flags for the image 02415 02416 Return Value: 02417 02418 None. 02419 02420 --*/ 02421 02422 { 02423 int i; 02424 02425 PAGED_CODE(); 02426 02427 if ( PsImageNotifyEnabled ) { 02428 for (i=0; i<PSP_MAX_LOAD_IMAGE_NOTIFY; i++) { 02429 if (PspLoadImageNotifyRoutine[i] != NULL) { 02430 (*PspLoadImageNotifyRoutine[i])( 02431 (PUNICODE_STRING) FullImageName, 02432 ProcessId, 02433 ImageInfo 02434 ); 02435 } 02436 } 02437 } 02438 } }

NTSTATUS PsCreateSystemProcess OUT PHANDLE  ProcessHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL
 

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

References FALSE, NTSTATUS(), NULL, ObjectAttributes, PAGED_CODE, PspCreateProcess(), and PspInitialSystemProcessHandle.

00923 : 00924 00925 This routine creates a system process object. A system process 00926 has an address space that is initialized to an empty address space 00927 that maps the system. 00928 00929 The process inherits its access token and other attributes from the 00930 initial system process. The process is created with an empty handle table. 00931 00932 Arguments: 00933 00934 ProcessHandle - Returns the handle for the new process. 00935 00936 DesiredAccess - Supplies the desired access modes to the new process. 00937 00938 ObjectAttributes - Supplies the object attributes of the new process. 00939 00940 00941 Return Value: 00942 00943 TBD 00944 00945 --*/ 00946 00947 { 00948 NTSTATUS st; 00949 00950 PAGED_CODE(); 00951 00952 st = PspCreateProcess( 00953 ProcessHandle, 00954 DesiredAccess, 00955 ObjectAttributes, 00956 PspInitialSystemProcessHandle, 00957 FALSE, 00958 (HANDLE) NULL, 00959 (HANDLE) NULL, 00960 (HANDLE) NULL 00961 ); 00962 00963 return st; 00964 }

NTSTATUS PsCreateSystemThread OUT PHANDLE  ThreadHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN HANDLE ProcessHandle  OPTIONAL,
OUT PCLIENT_ID ClientId  OPTIONAL,
IN PKSTART_ROUTINE  StartRoutine,
IN PVOID  StartContext
 

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

References FALSE, NTSTATUS(), NULL, ObjectAttributes, PAGED_CODE, PKSTART_ROUTINE, PsInitialSystemProcess, PspCreateThread(), and ThreadHandle.

Referenced by CreateSystemThread(), DoResourceTest(), ExpCreateWorkerThread(), ExpWorkerInitialization(), FsRtlInitializeWorkerThread(), IopStartApcHardError(), MemPrintInitialize(), MiModifiedPageWriter(), MiSectionInitialization(), MmInitSystem(), PspInitPhase0(), SeRmInitPhase1(), and SmbTraceStart().

00187 : 00188 00189 This routine creates and starts a system thread. 00190 00191 Arguments: 00192 00193 ThreadHandle - Returns the handle for the new thread. 00194 00195 DesiredAccess - Supplies the desired access modes to the new thread. 00196 00197 ObjectAttributes - Supplies the object attributes of the new thread. 00198 00199 ProcessHandle - Supplies a handle to the process that the thread is being 00200 created within. If this parameter is not specified, then 00201 the initial system process is used. 00202 00203 ClientId - Returns the CLIENT_ID of the new thread. 00204 00205 StartRoutine - Supplies the address of the system thread start routine. 00206 00207 StartContext - Supplies context for a system thread start routine. 00208 00209 Return Value: 00210 00211 TBD 00212 00213 --*/ 00214 00215 { 00216 NTSTATUS st; 00217 HANDLE SystemProcess; 00218 PEPROCESS ProcessPointer; 00219 00220 PAGED_CODE(); 00221 00222 ProcessPointer = NULL; 00223 if (ARGUMENT_PRESENT(ProcessHandle)) { 00224 SystemProcess = ProcessHandle; 00225 } else { 00226 SystemProcess = NULL; 00227 ProcessPointer = PsInitialSystemProcess; 00228 } 00229 00230 st = PspCreateThread ( 00231 ThreadHandle, 00232 DesiredAccess, 00233 ObjectAttributes, 00234 SystemProcess, 00235 ProcessPointer, 00236 ClientId, 00237 NULL, 00238 NULL, 00239 FALSE, 00240 StartRoutine, 00241 StartContext 00242 ); 00243 00244 return st; 00245 }

HANDLE PsGetCurrentProcessId VOID   ) 
 

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

References PsGetCurrentThread.

Referenced by SeAuditHandleCreation().

02307 { 02308 return PsGetCurrentThread()->Cid.UniqueProcess; 02309 }

HANDLE PsGetCurrentThreadId VOID   ) 
 

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

References PsGetCurrentThread.

02313 { 02314 return PsGetCurrentThread()->Cid.UniqueThread; 02315 }

BOOLEAN PsGetVersion PULONG MajorVersion  OPTIONAL,
PULONG MinorVersion  OPTIONAL,
PULONG BuildNumber  OPTIONAL,
PUNICODE_STRING CSDVersion  OPTIONAL
 

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

References CmCSDVersionString, NtBuildNumber, NtMajorVersion, and NtMinorVersion.

02324 { 02325 if (ARGUMENT_PRESENT(MajorVersion)) { 02326 *MajorVersion = NtMajorVersion; 02327 } 02328 02329 if (ARGUMENT_PRESENT(MinorVersion)) { 02330 *MinorVersion = NtMinorVersion; 02331 } 02332 02333 if (ARGUMENT_PRESENT(BuildNumber)) { 02334 *BuildNumber = NtBuildNumber & 0x3FFF; 02335 } 02336 02337 if (ARGUMENT_PRESENT(CSDVersion)) { 02338 *CSDVersion = CmCSDVersionString; 02339 } 02340 return (NtBuildNumber >> 28) == 0xC; 02341 }

NTSTATUS PsLockProcess IN PEPROCESS  Process,
IN KPROCESSOR_MODE  WaitMode,
IN PSLOCKPROCESSMODE  LockMode
 

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

References ExAcquireFastMutexUnsafe(), Executive, ExReleaseFastMutexUnsafe(), FALSE, _KTHREAD::FreezeCount, KeClearEvent, KeEnterCriticalRegion, KeGetCurrentThread, KeLeaveCriticalRegion, KeReadStateProcess(), _KTHREAD::KernelApcDisable, KernelMode, KeSetEvent(), KeWaitForSingleObject(), NTSTATUS(), NULL, PAGED_CODE, PsGetCurrentThread, PsLockIAmExiting, PSLOCKPROCESSMODE, PsLockReturnTimeout, PsLockWaitForever, PspProcessLockMutex, PsUnlockProcess(), Status, _ETHREAD::Tcb, TRUE, and UserMode.

Referenced by DbgkCreateThread(), DbgkpResumeProcess(), DbgkpSuspendProcess(), NtAssignProcessToJobObject(), NtSetInformationProcess(), NtSetInformationThread(), NtTerminateProcess(), NtTerminateThread(), PspApplyJobLimitsToProcess(), PspCreateThread(), PspExitThread(), and PspTerminateProcess().

01974 : 01975 01976 This function is used to lock the process from create/delete and to 01977 freeze threads from entering/exiting the process. 01978 01979 Arguments: 01980 01981 Process - Pointer to the process to lock 01982 01983 WaitMode - Supplies the processor mode to issue the wait under 01984 01985 LockMode - The type of lock to attempt 01986 01987 PsLockPollOnTimeout - Use a timeout and poll for the lock 01988 bailing if the process exits. 01989 01990 PsLockReturnTimeout - Do not poll, just timeout wait and 01991 return if you can not get the lock. 01992 01993 PsLockWaitForever - Wait without a timeout 01994 01995 01996 Return Value: 01997 01998 STATUS_SUCCESS - You got the lock, you must call PsUnlocProcess later on 01999 02000 STATUS_TIMEOUT - You requested PsLockReturnTimeout, and the lock was not available 02001 02002 STATUS_PROCESS_IS_TERMINATING - The process you are trying to lock is terminating 02003 02004 --*/ 02005 02006 { 02007 02008 LARGE_INTEGER DueTime; 02009 NTSTATUS Status; 02010 PLARGE_INTEGER Timeout; 02011 PETHREAD Thread; 02012 PSLOCKPROCESSMODE LocalLockMode; 02013 BOOLEAN WaitSuccess; 02014 02015 PAGED_CODE(); 02016 02017 LocalLockMode = LockMode; 02018 if ( LockMode == PsLockIAmExiting ) { 02019 LocalLockMode = PsLockWaitForever; 02020 } 02021 02022 Thread = PsGetCurrentThread(); 02023 02024 retry: 02025 // 02026 // Acquire process lock fast mutex to synchronize access to the ownership, 02027 // lock count, and synchronization event of the specified process. 02028 // 02029 02030 KeEnterCriticalRegion(); 02031 02032 ExAcquireFastMutexUnsafe(&PspProcessLockMutex); 02033 02034 // 02035 // Check if the process lock can be acquired. 02036 // 02037 02038 if (Process->LockCount != 1) { 02039 02040 // 02041 // The process lock is currently owned. 02042 // 02043 // If the lock mode is return timeout, then release the process lock 02044 // fast mutex and return timeout. Otherwise, set the timout value, 02045 // decrement the lock count, release the process lock fast mutex, and 02046 // wait for the process event. 02047 // 02048 02049 if (LocalLockMode == PsLockReturnTimeout) { 02050 ExReleaseFastMutexUnsafe(&PspProcessLockMutex); 02051 KeLeaveCriticalRegion(); 02052 return STATUS_TIMEOUT; 02053 02054 } else { 02055 02056 // 02057 // If the lock mode is not wait forever, then set the timeout 02058 // value to one second. Otherwise set the timeout to forever. 02059 // 02060 02061 if (LocalLockMode != PsLockWaitForever) { 02062 DueTime.QuadPart = - 10 * 1000 * 1000; 02063 Timeout = &DueTime; 02064 02065 } else { 02066 Timeout = NULL; 02067 } 02068 02069 // 02070 // Decrement the lock count and loop waiting for the process to 02071 // terminate or the lock to be granted. 02072 // 02073 02074 Process->LockCount -= 1; 02075 do { 02076 02077 WaitSuccess = FALSE; 02078 // 02079 // If the specified process has exited, then set the 02080 // completion status and exit the loop. 02081 // 02082 02083 if (Process->ExitTime.QuadPart != 0 && LocalLockMode != PsLockWaitForever) { 02084 Status = STATUS_PROCESS_IS_TERMINATING; 02085 break; 02086 } 02087 02088 // 02089 // Release the process lock fast mutex and wait for the 02090 // lock to be granted or time out to occur. 02091 // 02092 02093 ExReleaseFastMutexUnsafe(&PspProcessLockMutex); 02094 rewait: 02095 Status = KeWaitForSingleObject(&Process->LockEvent, 02096 Executive, 02097 WaitMode, 02098 FALSE, 02099 Timeout); 02100 02101 // 02102 // If waitmode is user-mode, then we can pop out of the wait with 02103 // status_user_apc. If callers are using PsLockWaitForever, they 02104 // don't expect this API to return without holding the lock, so 02105 // we need to re-execute the wait. Only place waitforever is used 02106 // in conjunction with UserMode is exit where all we want to do 02107 // with user-mode is allow our stack to swap, not service an exitapc 02108 // 02109 if ( Status == STATUS_USER_APC 02110 && WaitMode == UserMode 02111 && LocalLockMode == PsLockWaitForever ) { 02112 WaitMode = KernelMode; 02113 goto rewait; 02114 } 02115 02116 // 02117 // Reacquire the process lock fast mutex and continue the 02118 // loop if timeout has occured. 02119 // 02120 // 02121 02122 ExAcquireFastMutexUnsafe(&PspProcessLockMutex); 02123 02124 // 02125 // If the specified process has exited, then set the 02126 // completion status and exit the loop. This test needs 02127 // to be repeated so we catch the non-timed out wait 02128 // case where the process terminated and the lock was released 02129 // during the wait period 02130 // 02131 02132 if ( Process->ExitTime.QuadPart != 0 02133 && LocalLockMode != PsLockWaitForever ) { 02134 02135 if ( Status == STATUS_SUCCESS ) { 02136 // 02137 // We came out of the wait due to someone setting the 02138 // event. Since we are now going to bail, 02139 // we need to set the event to pass ownership on to someone else. 02140 // 02141 WaitSuccess = TRUE; 02142 } 02143 Status = STATUS_PROCESS_IS_TERMINATING; 02144 break; 02145 } 02146 02147 } while (Status == STATUS_TIMEOUT); 02148 02149 // 02150 // If the completion status is success, then the lock has been 02151 // granted and the owner is set. Otherwise, a user APC is pending 02152 // or the process has terminated and the lock request should be 02153 // dropped. 02154 // 02155 02156 if (Status != STATUS_SUCCESS) { 02157 Status = STATUS_PROCESS_IS_TERMINATING; 02158 Process->LockCount += 1; 02159 02160 if ( Process->LockCount == 1 ) { 02161 // 02162 // No one else is involved with the lock. We were granted owner 02163 // ship. We need to make sure the event is NOT signalled 02164 // 02165 // Is doesn't matter if we bail in this case due to a successful 02166 // wait, timeout. A lock count of 1 is the initial state 02167 // of a free lock. 02168 02169 KeClearEvent(&Process->LockEvent); 02170 } else { 02171 02172 // 02173 // A LockCount !=1 means that others are involved 02174 // in the lock. We requested ownership of the lock 02175 // by decrementing lockcount. 02176 // 02177 // We were granted ownership IF our wait was satisfied. 02178 // Since we are bailing, we need to pass this ownership along 02179 // to the next waiter. 02180 // 02181 // If we were not granted ownership (wait timed out, or we 02182 // bailed before the wait) then we don't have to do anything 02183 // more than increment the lock count 02184 // 02185 02186 if ( WaitSuccess ) { 02187 KeSetEvent(&Process->LockEvent, 0, FALSE); 02188 } 02189 } 02190 02191 } else { 02192 Process->LockOwner = KeGetCurrentThread(); 02193 } 02194 } 02195 02196 } else { 02197 02198 // 02199 // The process lock is not currently owned. 02200 // 02201 // If the lock mode is not wait forever and the process has already 02202 // terminated, then set the completion status to process terminating. 02203 // Otherwise, decrement the lock count, set the lock owner, and set 02204 // the completion status to success. 02205 // 02206 02207 if ((LocalLockMode != PsLockWaitForever) && 02208 ( (Process->ExitTime.QuadPart != 0 || KeReadStateProcess(&Process->Pcb) != FALSE) ) 02209 ) { 02210 Status = STATUS_PROCESS_IS_TERMINATING; 02211 02212 } else { 02213 Process->LockCount -= 1; 02214 Process->LockOwner = KeGetCurrentThread(); 02215 Status = STATUS_SUCCESS; 02216 } 02217 } 02218 02219 // 02220 // Release the process lock fast mutex and return the completion 02221 // status. 02222 // 02223 02224 ExReleaseFastMutexUnsafe(&PspProcessLockMutex); 02225 02226 if (Status != STATUS_SUCCESS) { 02227 KeLeaveCriticalRegion(); 02228 } else { 02229 02230 // 02231 // We don't want to be "frozen" with the process lock held, so now 02232 // that we own the lock, check to see if we have a pending freeze count, 02233 // and if we do and dropping the lock will help, then drop it 02234 // 02235 02236 if ((LockMode != PsLockIAmExiting) && 02237 (Thread->Tcb.FreezeCount != 0) && 02238 (Thread->Tcb.KernelApcDisable == (ULONG) -1) ) { 02239 PsUnlockProcess(Process); 02240 goto retry; 02241 } 02242 } 02243 02244 return Status; 02245 }

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 }

BOOLEAN PspMarkProcessIdValid IN PHANDLE_TABLE_ENTRY  HandleEntry,
IN ULONG_PTR  Parameter
 

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

References TRUE.

Referenced by PspCreateThread().

00253 { 00254 HandleEntry->Object = (PVOID)Parameter; 00255 return TRUE; 00256 }

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 }

ULONG PspUnhandledExceptionInSystemThread IN PEXCEPTION_POINTERS  ExceptionPointers  ) 
 

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

References EXCEPTION_EXECUTE_HANDLER, KeBugCheckEx(), and KMODE_EXCEPTION_NOT_HANDLED.

Referenced by PspSystemThreadStartup().

01898 { 01899 KdPrint(("PS: Unhandled Kernel Mode Exception Pointers = 0x%p\n", ExceptionPointers)); 01900 KdPrint(("Code %x Addr %p Info0 %p Info1 %p Info2 %p Info3 %p\n", 01901 ExceptionPointers->ExceptionRecord->ExceptionCode, 01902 (ULONG_PTR)ExceptionPointers->ExceptionRecord->ExceptionAddress, 01903 ExceptionPointers->ExceptionRecord->ExceptionInformation[0], 01904 ExceptionPointers->ExceptionRecord->ExceptionInformation[1], 01905 ExceptionPointers->ExceptionRecord->ExceptionInformation[2], 01906 ExceptionPointers->ExceptionRecord->ExceptionInformation[3] 01907 )); 01908 01909 KeBugCheckEx( 01910 KMODE_EXCEPTION_NOT_HANDLED, 01911 ExceptionPointers->ExceptionRecord->ExceptionCode, 01912 (ULONG_PTR)ExceptionPointers->ExceptionRecord->ExceptionAddress, 01913 ExceptionPointers->ExceptionRecord->ExceptionInformation[0], 01914 ExceptionPointers->ExceptionRecord->ExceptionInformation[1] 01915 ); 01916 return EXCEPTION_EXECUTE_HANDLER; 01917 }

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 }

NTSTATUS PsSetCreateProcessNotifyRoutine IN PCREATE_PROCESS_NOTIFY_ROUTINE  NotifyRoutine,
IN BOOLEAN  Remove
 

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

References NULL, PSP_MAX_CREATE_PROCESS_NOTIFY, PspCreateProcessNotifyRoutine, and PspCreateProcessNotifyRoutineCount.

01698 : 01699 01700 This function allows an installable file system to hook into process 01701 creation and deletion to track those events against their own internal 01702 data structures. 01703 01704 Arguments: 01705 01706 NotifyRoutine - Supplies the address of a routine which is called at 01707 process creation and deletion. The routine is passed the unique Id 01708 of the created or deleted process and the parent process if it was 01709 created with the inherit handles option. If it was created without 01710 the inherit handle options, then the parent process Id will be NULL. 01711 The third parameter passed to the notify routine is TRUE if the process 01712 is being created and FALSE if it is being deleted. 01713 01714 The callout for creation happens just after the first thread in the 01715 process has been created. The callout for deletion happens after the 01716 last thread in a process has terminated and the address space is about 01717 to be deleted. It is possible to get a deletion call without a creation 01718 call if the pathological case where a process is created and deleted 01719 without a thread ever being created. 01720 01721 Remove - FALSE specifies to install the callout and TRUE specifies to 01722 remove the callout that mat 01723 01724 Return Value: 01725 01726 STATUS_SUCCESS if successful, and STATUS_INVALID_PARAMETER if not. 01727 01728 --*/ 01729 01730 { 01731 01732 ULONG i; 01733 01734 for (i=0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++) { 01735 if (Remove) { 01736 if (PspCreateProcessNotifyRoutine[i] == NotifyRoutine) { 01737 PspCreateProcessNotifyRoutine[i] = NULL; 01738 PspCreateProcessNotifyRoutineCount -= 1; 01739 return STATUS_SUCCESS; 01740 } 01741 01742 } else { 01743 if (PspCreateProcessNotifyRoutine[i] == NULL) { 01744 PspCreateProcessNotifyRoutine[i] = NotifyRoutine; 01745 PspCreateProcessNotifyRoutineCount += 1; 01746 return STATUS_SUCCESS; 01747 } 01748 } 01749 } 01750 01751 return Remove ? STATUS_PROCEDURE_NOT_FOUND : STATUS_INVALID_PARAMETER; 01752 }

NTSTATUS PsSetCreateThreadNotifyRoutine IN PCREATE_THREAD_NOTIFY_ROUTINE  NotifyRoutine  ) 
 

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

References NTSTATUS(), NULL, PSP_MAX_CREATE_THREAD_NOTIFY, PspCreateThreadNotifyRoutine, PspCreateThreadNotifyRoutineCount, and Status.

01761 : 01762 01763 This function allows an installable file system to hook into thread 01764 creation and deletion to track those events against their own internal 01765 data structures. 01766 01767 Arguments: 01768 01769 NotifyRoutine - Supplies the address of the routine which is called at 01770 thread creation and deletion. The routine is passed the unique Id 01771 of the created or deleted thread and the unique Id of the containing 01772 process. The third parameter passed to the notify routine is TRUE if 01773 the thread is being created and FALSE if it is being deleted. 01774 01775 Return Value: 01776 01777 STATUS_SUCCESS if successful, and STATUS_INSUFFICIENT_RESOURCES if not. 01778 01779 --*/ 01780 01781 { 01782 01783 ULONG i; 01784 NTSTATUS Status; 01785 01786 Status = STATUS_INSUFFICIENT_RESOURCES; 01787 for (i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i += 1) { 01788 if (PspCreateThreadNotifyRoutine[i] == NULL) { 01789 PspCreateThreadNotifyRoutine[i] = NotifyRoutine; 01790 PspCreateThreadNotifyRoutineCount += 1; 01791 Status = STATUS_SUCCESS; 01792 break; 01793 } 01794 } 01795 01796 return Status; 01797 }

NTSTATUS PsSetLoadImageNotifyRoutine IN PLOAD_IMAGE_NOTIFY_ROUTINE  NotifyRoutine  ) 
 

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

References NTSTATUS(), NULL, PAGED_CODE, PLOAD_IMAGE_NOTIFY_ROUTINE, PsImageNotifyEnabled, PSP_MAX_LOAD_IMAGE_NOTIFY, PspLoadImageNotifyRoutine, PspLoadImageNotifyRoutineCount, Status, and TRUE.

02350 : 02351 02352 This function allows a device driver to get notified for 02353 image loads. The notify is issued for both kernel and user 02354 mode image loads system-wide. 02355 02356 Arguments: 02357 02358 NotifyRoutine - Supplies the address of a routine which is called at 02359 image load. The routine is passed information describing the 02360 image being loaded. 02361 02362 The callout for creation happens just after the image is loaded 02363 into memory but before executiona of the image. 02364 02365 Remove - FALSE specifies to install the callout and TRUE specifies to 02366 remove the callout that mat 02367 02368 Return Value: 02369 02370 STATUS_SUCCESS if successful, and STATUS_INVALID_PARAMETER if not. 02371 02372 --*/ 02373 02374 { 02375 02376 ULONG i; 02377 NTSTATUS Status; 02378 02379 PAGED_CODE(); 02380 02381 Status = STATUS_INSUFFICIENT_RESOURCES; 02382 for (i=0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) { 02383 if (PspLoadImageNotifyRoutine[i] == NULL) { 02384 PspLoadImageNotifyRoutine[i] = NotifyRoutine; 02385 PspLoadImageNotifyRoutineCount += 1; 02386 Status = STATUS_SUCCESS; 02387 PsImageNotifyEnabled = TRUE; 02388 break; 02389 } 02390 } 02391 02392 return Status; 02393 }

VOID PsUnlockProcess IN PEPROCESS  Process  ) 
 

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

References ExAcquireFastMutexUnsafe(), ExReleaseFastMutexUnsafe(), FALSE, KeLeaveCriticalRegion, KeSetEvent(), NULL, PAGED_CODE, and PspProcessLockMutex.

Referenced by DbgkCreateThread(), DbgkpResumeProcess(), DbgkpSuspendProcess(), NtAssignProcessToJobObject(), NtSetInformationProcess(), NtSetInformationThread(), NtTerminateProcess(), NtTerminateThread(), PsLockProcess(), PspApplyJobLimitsToProcess(), PspCreateThread(), PspExitThread(), and PspTerminateProcess().

02256 : 02257 02258 This function is the opposite of a successful call to PsLockProcess. It 02259 simply releases the createdelete lock for a process. 02260 02261 Arguments: 02262 02263 Process - Supplies the address of the process whose create/delete 02264 lock is to be released. 02265 02266 Return Value: 02267 02268 None. 02269 02270 --*/ 02271 02272 { 02273 02274 PAGED_CODE(); 02275 02276 // 02277 // Acquire process lock fast mutex to synchronize access to the ownership, 02278 // lock count, and synchronization event of the specified process. 02279 // 02280 02281 ExAcquireFastMutexUnsafe(&PspProcessLockMutex); 02282 02283 // 02284 // Increment the lock count and clear the lock owner. If the lock count 02285 // is less than one, then set the lock event. 02286 // 02287 02288 Process->LockCount += 1; 02289 Process->LockOwner = NULL; 02290 if (Process->LockCount != 1) { 02291 KeSetEvent(&Process->LockEvent, 0, FALSE); 02292 } 02293 02294 // 02295 // Release the process lock fast mutex and return. 02296 // 02297 02298 02299 ExReleaseFastMutexUnsafe(&PspProcessLockMutex); 02300 KeLeaveCriticalRegion(); 02301 return; 02302 }


Variable Documentation

UNICODE_STRING CmCSDVersionString
 

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

PVOID MmWorkingSetList
 

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

LCID PsDefaultSystemLocaleId
 

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

Referenced by CmGetSystemControlValues(), CmpCreatePerfKeys(), IopProcessNewDeviceNode(), LdrpSearchResourceSection_U(), NtQueryDefaultLocale(), and NtSetDefaultLocale().

LCID PsDefaultThreadLocaleId
 

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

Referenced by CmGetSystemControlValues(), NtQueryDefaultLocale(), NtSetDefaultLocale(), and PspUserThreadStartup().

LANGID PsDefaultUILanguageId
 

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

Referenced by CmGetSystemControlValues().

BOOLEAN PsImageNotifyEnabled
 

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

Referenced by DbgkCreateThread(), MiLoadSystemImage(), MiMapViewOfImageSection(), PsCallImageNotifyRoutines(), and PsSetLoadImageNotifyRoutine().

LANGID PsInstallUILanguageId
 

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

Referenced by CmGetSystemControlValues(), LdrpSearchResourceSection_U(), NtQueryDefaultUILanguage(), and NtQueryInstallUILanguage().

ULONG PsMaximumWorkingSet = 45
 

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

Referenced by PspCreateProcess(), and PspInitPhase0().

ULONG PsMinimumWorkingSet = 20
 

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

FAST_MUTEX PspProcessLockMutex
 

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

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


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