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 #define ROUND_UP(VALUE,ROUND) ((ULONG)(((ULONG)VALUE + \
00024
((ULONG)ROUND - 1L)) & (~((ULONG)ROUND - 1L))))
00025
00026 extern ULONG
PsMinimumWorkingSet;
00027 extern ULONG
PsMaximumWorkingSet;
00028 ULONG
PsPrioritySeperation;
00029 ULONG
PsRawPrioritySeparation;
00030
00031
NTSTATUS
00032
MmCheckSystemImage(
00033 IN HANDLE ImageFileHandle
00034 );
00035
00036
NTSTATUS
00037
LookupEntryPoint (
00038 IN PVOID DllBase,
00039 IN PSZ NameOfEntryPoint,
00040 OUT PVOID *AddressOfEntryPoint
00041 );
00042
00043
#ifdef i386
00044
VOID
00045
KeSetup80387OrEmulate (
00046 IN PVOID R3EmulatorTable
00047 );
00048
#endif
00049
00050 GENERIC_MAPPING
PspProcessMapping = {
00051 STANDARD_RIGHTS_READ |
00052 PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
00053 STANDARD_RIGHTS_WRITE |
00054 PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
00055 PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE |
00056 PROCESS_TERMINATE | PROCESS_SET_QUOTA |
00057 PROCESS_SET_INFORMATION | PROCESS_SET_PORT,
00058 STANDARD_RIGHTS_EXECUTE |
00059 SYNCHRONIZE,
00060 PROCESS_ALL_ACCESS
00061 };
00062
00063 GENERIC_MAPPING
PspThreadMapping = {
00064 STANDARD_RIGHTS_READ |
00065 THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,
00066 STANDARD_RIGHTS_WRITE |
00067 THREAD_TERMINATE | THREAD_SUSPEND_RESUME | THREAD_ALERT |
00068 THREAD_SET_INFORMATION | THREAD_SET_CONTEXT,
00069 STANDARD_RIGHTS_EXECUTE |
00070 SYNCHRONIZE,
00071 THREAD_ALL_ACCESS
00072 };
00073
00074 GENERIC_MAPPING
PspJobMapping = {
00075 STANDARD_RIGHTS_READ |
00076 JOB_OBJECT_QUERY,
00077 STANDARD_RIGHTS_WRITE |
00078 JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_SET_ATTRIBUTES | JOB_OBJECT_TERMINATE,
00079 STANDARD_RIGHTS_EXECUTE |
00080 SYNCHRONIZE,
00081 THREAD_ALL_ACCESS
00082 };
00083
00084
#ifdef ALLOC_PRAGMA
00085
#pragma alloc_text(INIT,PsInitSystem)
00086
#pragma alloc_text(INIT,PspInitPhase0)
00087
#pragma alloc_text(INIT,PspInitPhase1)
00088
#pragma alloc_text(INIT,PsLocateSystemDll)
00089
#pragma alloc_text(INIT,PspInitializeSystemDll)
00090
#pragma alloc_text(INIT,PspLookupSystemDllEntryPoint)
00091
#pragma alloc_text(INIT,PspNameToOrdinal)
00092
#pragma alloc_text(PAGE,PspMapSystemDll)
00093
#pragma alloc_text(PAGE,PsChangeQuantumTable)
00094
00095
#endif
00096
00097
00098
00099
00100
00101 POBJECT_TYPE PsThreadType;
00102 POBJECT_TYPE PsProcessType;
00103 PHANDLE_TABLE PspCidTable;
00104 PEPROCESS PsInitialSystemProcess;
00105 HANDLE
PspInitialSystemProcessHandle;
00106 PACCESS_TOKEN
PspBootAccessToken;
00107 UNICODE_STRING
PsNtDllPathName;
00108 FAST_MUTEX PsProcessSecurityLock;
00109 PVOID
PsSystemDllDllBase;
00110 ULONG
PspDefaultPagedLimit;
00111 ULONG
PspDefaultNonPagedLimit;
00112 ULONG
PspDefaultPagefileLimit;
00113 SCHAR
PspForegroundQuantum[3];
00114
00115 EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock;
00116 BOOLEAN
PspDoingGiveBacks;
00117 POBJECT_TYPE PsJobType;
00118 FAST_MUTEX PspJobListLock;
00119 LIST_ENTRY
PspJobList;
00120
00121 BOOLEAN
PsReaperActive =
FALSE;
00122 LIST_ENTRY
PsReaperListHead;
00123 WORK_QUEUE_ITEM PsReaperWorkItem;
00124 SYSTEM_DLL PspSystemDll;
00125 PVOID
PsSystemDllBase;
00126 #define PSP_1MB (1024*1024)
00127
00128
00129
00130
00131
00132 FAST_MUTEX PspActiveProcessMutex;
00133 LIST_ENTRY
PsActiveProcessHead;
00134
00135 PEPROCESS PsIdleProcess;
00136
00137 BOOLEAN
00138 PsInitSystem (
00139 IN ULONG Phase,
00140 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00141 )
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 {
00167
00168
switch (
InitializationPhase ) {
00169
00170
case 0 :
00171
return PspInitPhase0(LoaderBlock);
00172
case 1 :
00173
return PspInitPhase1(LoaderBlock);
00174
default:
00175
KeBugCheck(UNEXPECTED_INITIALIZATION_CALL);
00176 }
00177
return 0;
00178 }
00179
00180 BOOLEAN
00181 PspInitPhase0 (
00182 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
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 UNICODE_STRING NameString;
00209 OBJECT_ATTRIBUTES
ObjectAttributes;
00210
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
00211 HANDLE
ThreadHandle;
00212
PETHREAD Thread;
00213
MM_SYSTEMSIZE SystemSize;
00214
00215 SystemSize =
MmQuerySystemSize();
00216
PspDefaultPagefileLimit = (ULONG)-1;
00217
00218
#ifdef _WIN64
00219
if (
sizeof(TEB) > 8192 ||
sizeof(PEB) > 4096 ) {
00220
#else
00221
if (
sizeof(TEB) > 4096 ||
sizeof(PEB) > 4096 ) {
00222
#endif
00223
KeBugCheckEx(PROCESS_INITIALIZATION_FAILED,99,
sizeof(TEB),
sizeof(PEB),99);
00224 }
00225
00226
switch ( SystemSize ) {
00227
00228
case MmMediumSystem :
00229
PsMinimumWorkingSet += 10;
00230
PsMaximumWorkingSet += 100;
00231
break;
00232
00233
case MmLargeSystem :
00234
PsMinimumWorkingSet += 30;
00235
PsMaximumWorkingSet += 300;
00236
break;
00237
00238
case MmSmallSystem :
00239
default:
00240
break;
00241 }
00242
00243
PsChangeQuantumTable(
FALSE,
PsRawPrioritySeparation);
00244
00245
00246
00247
00248
00249
if ( !
PspDefaultPagedLimit ) {
00250
PspDefaultPagedLimit = 0;
00251 }
00252
if ( !
PspDefaultNonPagedLimit ) {
00253
PspDefaultNonPagedLimit = 0;
00254 }
00255
00256
if (
PspDefaultNonPagedLimit == 0 &&
PspDefaultPagedLimit == 0) {
00257
PspDoingGiveBacks =
TRUE;
00258 }
00259
else {
00260
PspDoingGiveBacks =
FALSE;
00261 }
00262
00263
00264
PspDefaultPagedLimit *=
PSP_1MB;
00265
PspDefaultNonPagedLimit *=
PSP_1MB;
00266
00267
if (
PspDefaultPagefileLimit != -1) {
00268
PspDefaultPagefileLimit *=
PSP_1MB;
00269 }
00270
00271
00272
00273
00274
00275
ExInitializeFastMutex( &
PspProcessLockMutex );
00276
ExInitializeFastMutex( &
PsProcessSecurityLock );
00277
00278
PsIdleProcess =
PsGetCurrentProcess();
00279
PsIdleProcess->
Pcb.
KernelTime = 0;
00280
PsIdleProcess->
Pcb.
KernelTime = 0;
00281
00282
00283
00284
00285
00286 RtlZeroMemory( &ObjectTypeInitializer,
sizeof( ObjectTypeInitializer ) );
00287 ObjectTypeInitializer.Length =
sizeof( ObjectTypeInitializer );
00288 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
00289 ObjectTypeInitializer.SecurityRequired =
TRUE;
00290 ObjectTypeInitializer.PoolType =
NonPagedPool;
00291 ObjectTypeInitializer.InvalidAttributes = OBJ_PERMANENT |
00292 OBJ_EXCLUSIVE |
00293 OBJ_OPENIF;
00294
00295
00296
00297
00298
00299
00300
RtlInitUnicodeString(&NameString,
L"Process");
00301 ObjectTypeInitializer.DefaultPagedPoolCharge =
PSP_PROCESS_PAGED_CHARGE;
00302 ObjectTypeInitializer.DefaultNonPagedPoolCharge =
PSP_PROCESS_NONPAGED_CHARGE;
00303 ObjectTypeInitializer.DeleteProcedure =
PspProcessDelete;
00304 ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS;
00305 ObjectTypeInitializer.GenericMapping =
PspProcessMapping;
00306
00307
if ( !
NT_SUCCESS(
ObCreateObjectType(&NameString,
00308 &ObjectTypeInitializer,
00309 (PSECURITY_DESCRIPTOR)
NULL,
00310 &
PsProcessType
00311 )) ){
00312
return FALSE;
00313 }
00314
00315
RtlInitUnicodeString(&NameString,
L"Thread");
00316 ObjectTypeInitializer.DefaultPagedPoolCharge =
PSP_THREAD_PAGED_CHARGE;
00317 ObjectTypeInitializer.DefaultNonPagedPoolCharge =
PSP_THREAD_NONPAGED_CHARGE;
00318 ObjectTypeInitializer.DeleteProcedure =
PspThreadDelete;
00319 ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS;
00320 ObjectTypeInitializer.GenericMapping =
PspThreadMapping;
00321
00322
if ( !
NT_SUCCESS(
ObCreateObjectType(&NameString,
00323 &ObjectTypeInitializer,
00324 (PSECURITY_DESCRIPTOR)
NULL,
00325 &
PsThreadType
00326 )) ){
00327
return FALSE;
00328 }
00329
00330
00331
RtlInitUnicodeString(&NameString,
L"Job");
00332 ObjectTypeInitializer.DefaultPagedPoolCharge = 0;
00333 ObjectTypeInitializer.DefaultNonPagedPoolCharge =
sizeof(
EJOB);
00334 ObjectTypeInitializer.DeleteProcedure =
PspJobDelete;
00335 ObjectTypeInitializer.CloseProcedure =
PspJobClose;
00336 ObjectTypeInitializer.ValidAccessMask = JOB_OBJECT_ALL_ACCESS;
00337 ObjectTypeInitializer.GenericMapping =
PspJobMapping;
00338 ObjectTypeInitializer.InvalidAttributes = 0;
00339
00340
if ( !
NT_SUCCESS(
ObCreateObjectType(&NameString,
00341 &ObjectTypeInitializer,
00342 (PSECURITY_DESCRIPTOR)
NULL,
00343 &
PsJobType
00344 )) ){
00345
return FALSE;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 InitializeListHead(&
PsActiveProcessHead);
00358
ExInitializeFastMutex(&
PspActiveProcessMutex);
00359
00360
00361
00362
00363
00364 InitializeListHead(&
PspJobList);
00365
ExInitializeFastMutex(&
PspJobListLock);
00366 InitializeListHead(&
PspWorkingSetChangeHead.
Links);
00367
ExInitializeFastMutex(&
PspWorkingSetChangeHead.
Lock);
00368
00369
00370
00371
00372
00373
00374
00375
00376
PspCidTable =
ExCreateHandleTable(
NULL);
00377
if ( !
PspCidTable ) {
00378
return FALSE;
00379 }
00380
ExRemoveHandleTable(
PspCidTable);
00381
00382
#if defined(i386)
00383
00384
00385
00386
00387
00388
if ( !
NT_SUCCESS(
PspLdtInitialize()) ) {
00389
return FALSE;
00390 }
00391
00392
00393
00394
00395
00396
if ( !
NT_SUCCESS(
PspVdmInitialize()) ) {
00397
return FALSE;
00398 }
00399
00400
#endif
00401
00402
00403
00404
00405
00406 InitializeListHead(&
PsReaperListHead);
00407
ExInitializeWorkItem(&
PsReaperWorkItem,
PspReaper,
NULL);
00408
00409
00410
00411
00412
00413
00414
00415
PspBootAccessToken =
PsGetCurrentProcess()->Token;
00416
00417 InitializeObjectAttributes( &
ObjectAttributes,
00418
NULL,
00419 0,
00420
NULL,
00421
NULL
00422 );
00423
00424
if ( !
NT_SUCCESS(
PspCreateProcess(
00425 &
PspInitialSystemProcessHandle,
00426 PROCESS_ALL_ACCESS,
00427 &
ObjectAttributes,
00428 0
L,
00429
FALSE,
00430 0
L,
00431 0
L,
00432 0
L
00433 )) ) {
00434
return FALSE;
00435 }
00436
00437
if ( !
NT_SUCCESS(
ObReferenceObjectByHandle(
00438
PspInitialSystemProcessHandle,
00439 0
L,
00440
PsProcessType,
00441
KernelMode,
00442 (PVOID *)&
PsInitialSystemProcess,
00443
NULL
00444 )) ) {
00445
00446
return FALSE;
00447 }
00448
00449 strcpy(&
PsGetCurrentProcess()->ImageFileName[0],
"Idle");
00450 strcpy(&
PsInitialSystemProcess->
ImageFileName[0],
"System");
00451
00452
00453
00454
00455
00456
if ( !
NT_SUCCESS(
PsCreateSystemThread(
00457 &
ThreadHandle,
00458 THREAD_ALL_ACCESS,
00459 &
ObjectAttributes,
00460 0
L,
00461
NULL,
00462
Phase1Initialization,
00463 (PVOID)LoaderBlock
00464 )) ) {
00465
return FALSE;
00466 }
00467
00468
00469
if ( !
NT_SUCCESS(
ObReferenceObjectByHandle(
00470
ThreadHandle,
00471 0
L,
00472
PsThreadType,
00473
KernelMode,
00474 (PVOID *)&Thread,
00475
NULL
00476 )) ) {
00477
00478
return FALSE;
00479 }
00480
00481 ZwClose(
ThreadHandle );
00482
00483
return TRUE;
00484 }
00485
00486 BOOLEAN
00487 PspInitPhase1 (
00488 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00489 )
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 {
00512
00513
NTSTATUS st;
00514
00515 st =
PspInitializeSystemDll();
00516
00517
if ( !
NT_SUCCESS(st) ) {
00518
return FALSE;
00519 }
00520
00521
return TRUE;
00522 }
00523
00524
NTSTATUS
00525 PsLocateSystemDll (
00526 VOID
00527 )
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 {
00549
00550 HANDLE
File;
00551 HANDLE Section;
00552
NTSTATUS st;
00553 UNICODE_STRING DllPathName;
00554 WCHAR PathBuffer[DOS_MAX_PATH_LENGTH];
00555 OBJECT_ATTRIBUTES
ObjectAttributes;
00556 IO_STATUS_BLOCK IoStatus;
00557
00558
00559
00560
00561
00562 DllPathName.Length = 0;
00563 DllPathName.Buffer = PathBuffer;
00564 DllPathName.MaximumLength = 256;
00565
RtlInitUnicodeString(&DllPathName,
L"\\SystemRoot\\System32\\ntdll.dll");
00566 InitializeObjectAttributes(
00567 &
ObjectAttributes,
00568 &DllPathName,
00569 OBJ_CASE_INSENSITIVE,
00570
NULL,
00571
NULL
00572 );
00573
00574 st =
ZwOpenFile(
00575 &
File,
00576 SYNCHRONIZE | FILE_EXECUTE,
00577 &
ObjectAttributes,
00578 &IoStatus,
00579 FILE_SHARE_READ,
00580 0
00581 );
00582
00583
if (!
NT_SUCCESS(st)) {
00584
00585
#if DBG
00586
DbgPrint(
"PS: PsLocateSystemDll - NtOpenFile( NTDLL.DLL ) failed. Status == %lx\n",
00587 st
00588 );
00589
#endif
00590
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,2,0,0);
00591
return st;
00592 }
00593
00594 st =
MmCheckSystemImage(
File);
00595
if ( st == STATUS_IMAGE_CHECKSUM_MISMATCH ) {
00596 ULONG_PTR ErrorParameters;
00597 ULONG ErrorResponse;
00598
00599
00600
00601
00602
00603 ErrorParameters = (ULONG_PTR)&DllPathName;
00604
00605
NtRaiseHardError(
00606 st,
00607 1,
00608 1,
00609 &ErrorParameters,
00610 OptionOk,
00611 &ErrorResponse
00612 );
00613
return st;
00614 }
00615
00616
00617
PsNtDllPathName.MaximumLength = DllPathName.Length +
sizeof( WCHAR );
00618
PsNtDllPathName.Length = 0;
00619
PsNtDllPathName.Buffer =
RtlAllocateStringRoutine(
PsNtDllPathName.MaximumLength );
00620
RtlCopyUnicodeString( &
PsNtDllPathName, &DllPathName );
00621
00622 st = ZwCreateSection(
00623 &Section,
00624 SECTION_ALL_ACCESS,
00625
NULL,
00626 0,
00627 PAGE_EXECUTE,
00628 SEC_IMAGE,
00629
File
00630 );
00631 ZwClose(
File );
00632
00633
if (!
NT_SUCCESS(st)) {
00634
#if DBG
00635
DbgPrint(
"PS: PsLocateSystemDll: NtCreateSection Status == %lx\n",st);
00636
#endif
00637
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,3,0,0);
00638
return st;
00639 }
00640
00641
00642
00643
00644
00645
00646 st =
ObReferenceObjectByHandle(
00647 Section,
00648 SECTION_ALL_ACCESS,
00649
MmSectionObjectType,
00650
KernelMode,
00651 &
PspSystemDll.
Section,
00652
NULL
00653 );
00654
00655 ZwClose(Section);
00656
00657
if ( !
NT_SUCCESS(st) ) {
00658
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,4,0,0);
00659
return st;
00660 }
00661
00662
00663
00664
00665
00666 st =
PspMapSystemDll(
PsGetCurrentProcess(),&
PspSystemDll.
DllBase);
00667
PsSystemDllDllBase =
PspSystemDll.
DllBase;
00668
00669
if ( !
NT_SUCCESS(st) ) {
00670
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,5,0,0);
00671
return st;
00672 }
00673
PsSystemDllBase =
PspSystemDll.
DllBase;
00674
00675
return STATUS_SUCCESS;
00676 }
00677
00678
NTSTATUS
00679 PspMapSystemDll (
00680 IN
PEPROCESS Process,
00681 OUT PVOID *DllBase OPTIONAL
00682 )
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 {
00701
NTSTATUS st;
00702 PVOID ViewBase;
00703 LARGE_INTEGER SectionOffset;
00704 SIZE_T ViewSize;
00705
00706
PAGED_CODE();
00707
00708 ViewBase =
NULL;
00709 SectionOffset.LowPart = 0;
00710 SectionOffset.HighPart = 0;
00711 ViewSize = 0;
00712
00713
00714
00715
00716
00717 st =
MmMapViewOfSection(
00718
PspSystemDll.
Section,
00719 Process,
00720 &ViewBase,
00721 0
L,
00722 0
L,
00723 &SectionOffset,
00724 &ViewSize,
00725 ViewShare,
00726 0
L,
00727 PAGE_READWRITE
00728 );
00729
00730
if ( st != STATUS_SUCCESS ) {
00731
#if DBG
00732
DbgPrint(
"PS: Unable to map system dll at based address.\n");
00733
#endif
00734
st = STATUS_CONFLICTING_ADDRESSES;
00735 }
00736
00737
if ( ARGUMENT_PRESENT(DllBase) ) {
00738 *DllBase = ViewBase;
00739 }
00740
00741
return st;
00742 }
00743
00744
NTSTATUS
00745 PspInitializeSystemDll (
00746 VOID
00747 )
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 {
00767
NTSTATUS st;
00768 PSZ dll_entrypoint;
00769 PVOID R3EmulatorTable;
00770
00771
00772
00773
00774
00775 dll_entrypoint =
"LdrInitializeThunk";
00776
00777 st =
PspLookupSystemDllEntryPoint(
00778 dll_entrypoint,
00779 (PVOID *)&
PspSystemDll.
LoaderInitRoutine
00780 );
00781
00782
if ( !
NT_SUCCESS(st) ) {
00783
#if DBG
00784
DbgPrint(
"PS: Unable to locate LdrInitializeThunk in system dll\n");
00785
#endif
00786
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,6,0,0);
00787
return st;
00788 }
00789
00790
#if i386
00791
00792
00793
00794
00795 st =
PspLookupSystemDllEntryPoint(
00796
"NPXEMULATORTABLE",
00797 &R3EmulatorTable
00798 );
00799
00800
if ( !
NT_SUCCESS(st) ) {
00801
#if DBG
00802
DbgPrint(
"PS: Unable to locate NPXNPHandler in system dll\n");
00803
#endif
00804
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,7,0,0);
00805
return st;
00806 }
00807
00808
00809
00810
00811
00812
KeSetup80387OrEmulate(R3EmulatorTable);
00813
#endif //i386
00814
00815 st =
PspLookupKernelUserEntryPoints();
00816
00817
if ( !
NT_SUCCESS(st) ) {
00818
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,8,0,0);
00819 }
00820
00821
KdUpdateDataBlock();
00822
00823
return st;
00824 }
00825
00826
NTSTATUS
00827 PspLookupSystemDllEntryPoint (
00828 IN PSZ NameOfEntryPoint,
00829 OUT PVOID *AddressOfEntryPoint
00830 )
00831
00832 {
00833
return LookupEntryPoint (
00834
PspSystemDll.
DllBase,
00835 NameOfEntryPoint,
00836 AddressOfEntryPoint
00837 );
00838 }
00839
00840 SCHAR
PspFixedQuantums[6] = {
00841 3*
THREAD_QUANTUM,
00842 3*
THREAD_QUANTUM,
00843 3*
THREAD_QUANTUM,
00844 6*
THREAD_QUANTUM,
00845 6*
THREAD_QUANTUM,
00846 6*
THREAD_QUANTUM
00847 };
00848
00849 SCHAR
PspVariableQuantums[6] = {
00850 1*
THREAD_QUANTUM,
00851 2*
THREAD_QUANTUM,
00852 3*
THREAD_QUANTUM,
00853 2*
THREAD_QUANTUM,
00854 4*
THREAD_QUANTUM,
00855 6*
THREAD_QUANTUM
00856 };
00857
00858
00859
00860
00861
00862 BOOLEAN
PspUseJobSchedulingClasses;
00863
00864 SCHAR
PspJobSchedulingClasses[
PSP_NUMBER_OF_SCHEDULING_CLASSES] = {
00865 1*
THREAD_QUANTUM,
00866 2*
THREAD_QUANTUM,
00867 3*
THREAD_QUANTUM,
00868 4*
THREAD_QUANTUM,
00869 5*
THREAD_QUANTUM,
00870 6*
THREAD_QUANTUM,
00871 7*
THREAD_QUANTUM,
00872 8*
THREAD_QUANTUM,
00873 9*
THREAD_QUANTUM,
00874 10*
THREAD_QUANTUM
00875 };
00876
00877
VOID
00878 PsChangeQuantumTable(
00879 BOOLEAN ModifyActiveProcesses,
00880 ULONG PrioritySeparation
00881 )
00882 {
00883
00884
PEPROCESS Process;
00885 PLIST_ENTRY NextProcess;
00886 ULONG QuantumIndex;
00887 PSCHAR QuantumTableBase;
00888
00889
00890
00891
00892
switch ( PrioritySeparation & PROCESS_PRIORITY_SEPARATION_MASK ) {
00893
case 3:
00894
PsPrioritySeperation = PROCESS_PRIORITY_SEPARATION_MAX;
00895
break;
00896
default:
00897
PsPrioritySeperation = PrioritySeparation & PROCESS_PRIORITY_SEPARATION_MASK;
00898
break;
00899 }
00900
00901
00902
00903
00904
switch ( PrioritySeparation & PROCESS_QUANTUM_VARIABLE_MASK ) {
00905
case PROCESS_QUANTUM_VARIABLE_VALUE:
00906 QuantumTableBase =
PspVariableQuantums;
00907
break;
00908
00909
case PROCESS_QUANTUM_FIXED_VALUE:
00910 QuantumTableBase =
PspFixedQuantums;
00911
break;
00912
00913
case PROCESS_QUANTUM_VARIABLE_DEF:
00914
default:
00915
if (
MmIsThisAnNtAsSystem() ) {
00916 QuantumTableBase =
PspFixedQuantums;
00917 }
00918
else {
00919 QuantumTableBase =
PspVariableQuantums;
00920 }
00921
break;
00922 }
00923
00924
00925
00926
00927
switch ( PrioritySeparation & PROCESS_QUANTUM_LONG_MASK ) {
00928
case PROCESS_QUANTUM_LONG_VALUE:
00929 QuantumTableBase = QuantumTableBase + 3;
00930
break;
00931
00932
case PROCESS_QUANTUM_SHORT_VALUE:
00933
break;
00934
00935
case PROCESS_QUANTUM_LONG_DEF:
00936
default:
00937
if (
MmIsThisAnNtAsSystem() ) {
00938 QuantumTableBase = QuantumTableBase + 3;
00939 }
00940
break;
00941 }
00942
00943
00944
00945
00946
00947
if ( QuantumTableBase == &
PspFixedQuantums[3] ) {
00948
PspUseJobSchedulingClasses =
TRUE;
00949 }
00950
else {
00951
PspUseJobSchedulingClasses =
FALSE;
00952 }
00953
00954 RtlCopyMemory(
PspForegroundQuantum,QuantumTableBase,
sizeof(
PspForegroundQuantum));
00955
00956
if (ModifyActiveProcesses) {
00957
00958 ExAcquireFastMutex(&
PspActiveProcessMutex);
00959
00960 NextProcess =
PsActiveProcessHead.Flink;
00961
00962
while (NextProcess != &
PsActiveProcessHead) {
00963 Process = CONTAINING_RECORD(NextProcess,
00964
EPROCESS,
00965 ActiveProcessLinks);
00966
00967
if ( Process->
Vm.
MemoryPriority ==
MEMORY_PRIORITY_BACKGROUND ) {
00968 QuantumIndex = 0;
00969 }
00970
else {
00971 QuantumIndex =
PsPrioritySeperation;
00972 }
00973
if ( Process->
PriorityClass != PROCESS_PRIORITY_CLASS_IDLE ) {
00974
00975
00976
00977
00978
00979
00980
if ( Process->
Job &&
PspUseJobSchedulingClasses ) {
00981 Process->
Pcb.
ThreadQuantum =
PspJobSchedulingClasses[Process->
Job->
SchedulingClass];
00982 }
00983
else {
00984 Process->
Pcb.
ThreadQuantum =
PspForegroundQuantum[QuantumIndex];
00985 }
00986 }
00987
else {
00988 Process->
Pcb.
ThreadQuantum =
THREAD_QUANTUM;
00989 }
00990 NextProcess = NextProcess->Flink;
00991 }
00992 ExReleaseFastMutex(&
PspActiveProcessMutex);
00993 }
00994 }