00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "psp.h"
00022
00023
00024
00025
00026 extern PVOID
MmWorkingSetList;
00027
00028
#ifdef ALLOC_PRAGMA
00029
#pragma alloc_text(PAGE, NtCreateThread)
00030
#pragma alloc_text(PAGE, NtCreateProcess)
00031
#pragma alloc_text(PAGE, PsCreateSystemThread)
00032
#pragma alloc_text(PAGE, PspCreateThread)
00033
#pragma alloc_text(PAGE, PsCreateSystemProcess)
00034
#pragma alloc_text(PAGE, PspCreateProcess)
00035
#pragma alloc_text(PAGE, PspUserThreadStartup)
00036
#pragma alloc_text(PAGE, PsLockProcess)
00037
#pragma alloc_text(PAGE, PsUnlockProcess)
00038
#pragma alloc_text(PAGE, PsSetLoadImageNotifyRoutine)
00039
#pragma alloc_text(PAGE, PsCallImageNotifyRoutines)
00040
#endif
00041
00042
00043 extern UNICODE_STRING
CmCSDVersionString;
00044
00045 LCID
PsDefaultSystemLocaleId;
00046 LCID
PsDefaultThreadLocaleId;
00047 LANGID
PsDefaultUILanguageId;
00048 LANGID
PsInstallUILanguageId;
00049
00050
00051
00052
00053
00054
00055 ULONG
PsMinimumWorkingSet = 20;
00056 ULONG
PsMaximumWorkingSet = 45;
00057
00058 BOOLEAN
PsImageNotifyEnabled;
00059
00060
00061
00062
00063
00064 FAST_MUTEX PspProcessLockMutex;
00065
00066
NTSTATUS
00067 NtCreateThread(
00068 OUT PHANDLE ThreadHandle,
00069 IN ACCESS_MASK DesiredAccess,
00070 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
00071 IN HANDLE ProcessHandle,
00072 OUT PCLIENT_ID ClientId,
00073 IN PCONTEXT ThreadContext,
00074 IN PINITIAL_TEB InitialTeb,
00075 IN BOOLEAN CreateSuspended
00076 )
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 {
00111
NTSTATUS st;
00112 INITIAL_TEB CapturedInitialTeb;
00113
00114
PAGED_CODE();
00115
00116
if ( KeGetPreviousMode() !=
KernelMode ) {
00117
00118
00119
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 }
00173
00174
NTSTATUS
00175 PsCreateSystemThread(
00176 OUT PHANDLE ThreadHandle,
00177 IN ACCESS_MASK DesiredAccess,
00178 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
00179 IN HANDLE ProcessHandle OPTIONAL,
00180 OUT PCLIENT_ID ClientId OPTIONAL,
00181 IN
PKSTART_ROUTINE StartRoutine,
00182 IN PVOID StartContext
00183 )
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
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 }
00246
00247
00248 BOOLEAN
00249 PspMarkProcessIdValid(
00250 IN
PHANDLE_TABLE_ENTRY HandleEntry,
00251 IN ULONG_PTR Parameter
00252 )
00253 {
00254 HandleEntry->Object = (PVOID)Parameter;
00255
return TRUE;
00256 }
00257
00258
00259
00260
00261
NTSTATUS
00262 PspCreateThread(
00263 OUT PHANDLE ThreadHandle,
00264 IN ACCESS_MASK DesiredAccess,
00265 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
00266 IN HANDLE ProcessHandle,
00267 IN
PEPROCESS ProcessPointer,
00268 OUT PCLIENT_ID ClientId OPTIONAL,
00269 IN PCONTEXT ThreadContext OPTIONAL,
00270 IN PINITIAL_TEB InitialTeb OPTIONAL,
00271 IN BOOLEAN CreateSuspended,
00272 IN PKSTART_ROUTINE StartRoutine OPTIONAL,
00273 IN PVOID StartContext
00274 )
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
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
00358
00359
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
00387
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
00424
00425
00426 Thread->ReadClusterSize =
MmReadClusterSize;
00427
00428
00429
00430
00431
00432
KeInitializeSemaphore(&Thread->LpcReplySemaphore,0
L,1
L);
00433 InitializeListHead( &Thread->LpcReplyChain );
00434
00435
00436
00437
00438
00439 InitializeListHead(&Thread->IrpList);
00440
00441
00442
00443
00444
00445 InitializeListHead(&Thread->PostBlockList);
00446
00447
00448
00449
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
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
00485
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
00515
00516
00517
00518
00519
00520
00521
try {
00522
00523 ITeb = *
InitialTeb;
00524
00525 Teb =
MmCreateTeb ( Process, &ITeb, &Thread->Cid );
00526
00527
00528
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
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
00606
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
00629
00630
00631
00632
00633
00634
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
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
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
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
00718
00719
00720
00721
00722
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
00746
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
00776
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
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 }
00841
00842
NTSTATUS
00843 NtCreateProcess(
00844 OUT PHANDLE ProcessHandle,
00845 IN ACCESS_MASK DesiredAccess,
00846 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
00847 IN HANDLE ParentProcess,
00848 IN BOOLEAN InheritObjectTable,
00849 IN HANDLE SectionHandle OPTIONAL,
00850 IN HANDLE DebugPort OPTIONAL,
00851 IN HANDLE ExceptionPort OPTIONAL
00852 )
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 {
00878
NTSTATUS st;
00879
00880
PAGED_CODE();
00881
00882
if ( KeGetPreviousMode() !=
KernelMode ) {
00883
00884
00885
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 }
00912
00913
00914
NTSTATUS
00915 PsCreateSystemProcess(
00916 OUT PHANDLE ProcessHandle,
00917 IN ACCESS_MASK DesiredAccess,
00918 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
00919 )
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
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 }
00965
00966
00967
00968
NTSTATUS
00969 PspCreateProcess(
00970 OUT PHANDLE ProcessHandle,
00971 IN ACCESS_MASK DesiredAccess,
00972 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
00973 IN HANDLE ParentProcess OPTIONAL,
00974 IN BOOLEAN InheritObjectTable,
00975 IN HANDLE SectionHandle OPTIONAL,
00976 IN HANDLE DebugPort OPTIONAL,
00977 IN HANDLE ExceptionPort OPTIONAL
00978 )
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
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
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
01070
01071
01072
01073
01074 BasePriority = (KPRIORITY) NORMAL_BASE_PRIORITY;
01075
01076
01077
01078
01079
01080 Affinity = Parent->Pcb.Affinity;
01081
01082 WorkingSetMinimum =
PsMinimumWorkingSet;
01083 WorkingSetMaximum =
PsMaximumWorkingSet;
01084
01085
01086 }
else {
01087
01088 Parent =
NULL;
01089 Affinity =
KeActiveProcessors;
01090 BasePriority = (KPRIORITY) NORMAL_BASE_PRIORITY;
01091
01092 WorkingSetMinimum =
PsMinimumWorkingSet;
01093 WorkingSetMaximum =
PsMaximumWorkingSet;
01094 }
01095
01096
01097
01098
01099
01100
if (ARGUMENT_PRESENT(SectionHandle) ) {
01101
01102
01103
01104
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
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
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
01214
01215
01216
01217
01218
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
01249
01250
01251
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
01273
01274
01275
01276
01277
if (Parent) {
01278
01279
01280
01281
01282
01283
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
01310
01311
01312
01313
01314
01315
01316
01317
01318
ExInitializeFastMutex(&Process->WorkingSetLock);
01319
01320
ExInitializeFastMutex(&Process->AddressCreationLock);
01321
01322
KeInitializeSpinLock (&Process->HyperSpaceLock);
01323
01324
01325
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
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
01357
01358
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
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
if ( SectionToMap ) {
01398
01399
01400
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
01417
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
01438
01439
01440
01441 st =
MmInitializeProcessAddressSpace(
01442 Process,
01443 Parent,
01444
NULL,
01445
NULL
01446 );
01447
01448 CreatePeb =
TRUE;
01449
01450 }
else {
01451
01452
01453
01454
01455
01456 st =
MmInitializeProcessAddressSpace(
01457 Process,
01458
NULL,
01459
NULL,
01460
NULL
01461 );
01462 }
01463 }
01464
01465 insert_process:
01466
01467
01468
01469
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
01489
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
01511
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
01550
01551
01552
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
01583
01584
01585
01586
01587
if ( ARGUMENT_PRESENT(SectionHandle) ) {
01588 DuplicateStatus = ZwDuplicateObject(
01589 NtCurrentProcess(),
01590 SectionHandle,
01591 LocalProcessHandle,
01592 &NewSection,
01593 0
L,
01594 0
L,
01595 DUPLICATE_SAME_ACCESS
01596 );
01597 }
else {
01598
01599 DuplicateStatus = ZwDuplicateObject(
01600 ParentProcess,
01601 Parent->
SectionHandle,
01602 LocalProcessHandle,
01603 &NewSection,
01604 0
L,
01605 0
L,
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
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
01660
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 }
01689
01690
NTSTATUS
01691 PsSetCreateProcessNotifyRoutine(
01692 IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
01693 IN BOOLEAN Remove
01694 )
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
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 }
01753
01754
NTSTATUS
01755 PsSetCreateThreadNotifyRoutine(
01756 IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine
01757 )
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
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 }
01798
01799
VOID
01800 PspUserThreadStartup(
01801 IN PKSTART_ROUTINE StartRoutine,
01802 IN PVOID StartContext
01803 )
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
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
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
01870
01871
01872
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 }
01891
01892
01893
01894 ULONG
01895 PspUnhandledExceptionInSystemThread(
01896 IN PEXCEPTION_POINTERS ExceptionPointers
01897 )
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 }
01918
01919
VOID
01920 PspSystemThreadStartup(
01921 IN PKSTART_ROUTINE StartRoutine,
01922 IN PVOID StartContext
01923 )
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
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 }
01964
01965
NTSTATUS
01966 PsLockProcess(
01967 IN
PEPROCESS Process,
01968 IN KPROCESSOR_MODE WaitMode,
01969 IN
PSLOCKPROCESSMODE LockMode
01970 )
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
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
02027
02028
02029
02030
KeEnterCriticalRegion();
02031
02032
ExAcquireFastMutexUnsafe(&
PspProcessLockMutex);
02033
02034
02035
02036
02037
02038
if (Process->LockCount != 1) {
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
if (LocalLockMode ==
PsLockReturnTimeout) {
02050
ExReleaseFastMutexUnsafe(&
PspProcessLockMutex);
02051
KeLeaveCriticalRegion();
02052
return STATUS_TIMEOUT;
02053
02054 }
else {
02055
02056
02057
02058
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
02071
02072
02073
02074 Process->LockCount -= 1;
02075
do {
02076
02077 WaitSuccess =
FALSE;
02078
02079
02080
02081
02082
02083
if (Process->ExitTime.QuadPart != 0 && LocalLockMode !=
PsLockWaitForever) {
02084
Status = STATUS_PROCESS_IS_TERMINATING;
02085
break;
02086 }
02087
02088
02089
02090
02091
02092
02093
ExReleaseFastMutexUnsafe(&
PspProcessLockMutex);
02094 rewait:
02095
Status =
KeWaitForSingleObject(&Process->LockEvent,
02096
Executive,
02097 WaitMode,
02098
FALSE,
02099 Timeout);
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
if (
Status == STATUS_USER_APC
02110 && WaitMode ==
UserMode
02111 && LocalLockMode ==
PsLockWaitForever ) {
02112 WaitMode =
KernelMode;
02113
goto rewait;
02114 }
02115
02116
02117
02118
02119
02120
02121
02122
ExAcquireFastMutexUnsafe(&
PspProcessLockMutex);
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
if ( Process->ExitTime.QuadPart != 0
02133 && LocalLockMode !=
PsLockWaitForever ) {
02134
02135
if (
Status == STATUS_SUCCESS ) {
02136
02137
02138
02139
02140
02141 WaitSuccess =
TRUE;
02142 }
02143
Status = STATUS_PROCESS_IS_TERMINATING;
02144
break;
02145 }
02146
02147 }
while (
Status == STATUS_TIMEOUT);
02148
02149
02150
02151
02152
02153
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
02163
02164
02165
02166
02167
02168
02169
KeClearEvent(&Process->LockEvent);
02170 }
else {
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
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
02200
02201
02202
02203
02204
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
02221
02222
02223
02224
ExReleaseFastMutexUnsafe(&
PspProcessLockMutex);
02225
02226
if (
Status != STATUS_SUCCESS) {
02227
KeLeaveCriticalRegion();
02228 }
else {
02229
02230
02231
02232
02233
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 }
02246
02247
02248
02249
VOID
02250 PsUnlockProcess(
02251 IN
PEPROCESS Process
02252 )
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272 {
02273
02274
PAGED_CODE();
02275
02276
02277
02278
02279
02280
02281
ExAcquireFastMutexUnsafe(&
PspProcessLockMutex);
02282
02283
02284
02285
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
02296
02297
02298
02299
ExReleaseFastMutexUnsafe(&
PspProcessLockMutex);
02300
KeLeaveCriticalRegion();
02301
return;
02302 }
02303
02304
02305 HANDLE
02306 PsGetCurrentProcessId( VOID )
02307 {
02308
return PsGetCurrentThread()->Cid.UniqueProcess;
02309 }
02310
02311 HANDLE
02312 PsGetCurrentThreadId( VOID )
02313 {
02314
return PsGetCurrentThread()->Cid.UniqueThread;
02315 }
02316
02317 BOOLEAN
02318 PsGetVersion(
02319 PULONG MajorVersion OPTIONAL,
02320 PULONG MinorVersion OPTIONAL,
02321 PULONG BuildNumber OPTIONAL,
02322 PUNICODE_STRING CSDVersion OPTIONAL
02323 )
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 }
02342
02343
NTSTATUS
02344 PsSetLoadImageNotifyRoutine(
02345 IN
PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
02346 )
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
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 }
02394
02395
VOID
02396 PsCallImageNotifyRoutines(
02397 IN PUNICODE_STRING FullImageName,
02398 IN HANDLE ProcessId,
02399 IN
PIMAGE_INFO ImageInfo
02400 )
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
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 }