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

psinit.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 psinit.c 00008 00009 Abstract: 00010 00011 Process Structure Initialization. 00012 00013 Author: 00014 00015 Mark Lucovsky (markl) 20-Apr-1989 00016 00017 Revision History: 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 // Process Structure Global Data 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 // List head and mutex that links all processes that have been initialized 00130 // 00131 00132 FAST_MUTEX PspActiveProcessMutex; 00133 LIST_ENTRY PsActiveProcessHead; 00134 //extern PIMAGE_FILE_HEADER _header; 00135 PEPROCESS PsIdleProcess; 00136 00137 BOOLEAN 00138 PsInitSystem ( 00139 IN ULONG Phase, 00140 IN PLOADER_PARAMETER_BLOCK LoaderBlock 00141 ) 00142 00143 /*++ 00144 00145 Routine Description: 00146 00147 This function fermorms process structure initialization. 00148 It is called during phase 0 and phase 1 initialization. Its 00149 function is to dispatch to the appropriate phase initialization 00150 routine. 00151 00152 Arguments: 00153 00154 Phase - Supplies the initialization phase number. 00155 00156 LoaderBlock - Supplies a pointer to a loader parameter block. 00157 00158 Return Value: 00159 00160 TRUE - Initialization succeeded. 00161 00162 FALSE - Initialization failed. 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; // Not reachable, quiet compiler 00178 } 00179 00180 BOOLEAN 00181 PspInitPhase0 ( 00182 IN PLOADER_PARAMETER_BLOCK LoaderBlock 00183 ) 00184 00185 /*++ 00186 00187 Routine Description: 00188 00189 This routine performs phase 0 process structure initialization. 00190 During this phase, the initial system process, phase 1 initialization 00191 thread, and reaper threads are created. All object types and other 00192 process structures are created and initialized. 00193 00194 Arguments: 00195 00196 None. 00197 00198 Return Value: 00199 00200 TRUE - Initialization was successful. 00201 00202 FALSE - Initialization Failed. 00203 00204 --*/ 00205 00206 { 00207 00208 UNICODE_STRING NameString; 00209 OBJECT_ATTRIBUTES ObjectAttributes; 00210 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 00211 HANDLE ThreadHandle; 00212 PETHREAD Thread; 00213 MM_SYSTEMSIZE SystemSize; 00214 00215 SystemSize = MmQuerySystemSize(); 00216 PspDefaultPagefileLimit = (ULONG)-1; 00217 00218 #ifdef _WIN64 00219 if ( sizeof(TEB) > 8192 || sizeof(PEB) > 4096 ) { 00220 #else 00221 if ( sizeof(TEB) > 4096 || sizeof(PEB) > 4096 ) { 00222 #endif 00223 KeBugCheckEx(PROCESS_INITIALIZATION_FAILED,99,sizeof(TEB),sizeof(PEB),99); 00224 } 00225 00226 switch ( SystemSize ) { 00227 00228 case MmMediumSystem : 00229 PsMinimumWorkingSet += 10; 00230 PsMaximumWorkingSet += 100; 00231 break; 00232 00233 case MmLargeSystem : 00234 PsMinimumWorkingSet += 30; 00235 PsMaximumWorkingSet += 300; 00236 break; 00237 00238 case MmSmallSystem : 00239 default: 00240 break; 00241 } 00242 00243 PsChangeQuantumTable(FALSE,PsRawPrioritySeparation); 00244 00245 // 00246 // Quotas grow as needed automatically 00247 // 00248 00249 if ( !PspDefaultPagedLimit ) { 00250 PspDefaultPagedLimit = 0; 00251 } 00252 if ( !PspDefaultNonPagedLimit ) { 00253 PspDefaultNonPagedLimit = 0; 00254 } 00255 00256 if ( PspDefaultNonPagedLimit == 0 && PspDefaultPagedLimit == 0) { 00257 PspDoingGiveBacks = TRUE; 00258 } 00259 else { 00260 PspDoingGiveBacks = FALSE; 00261 } 00262 00263 00264 PspDefaultPagedLimit *= PSP_1MB; 00265 PspDefaultNonPagedLimit *= PSP_1MB; 00266 00267 if (PspDefaultPagefileLimit != -1) { 00268 PspDefaultPagefileLimit *= PSP_1MB; 00269 } 00270 00271 // 00272 // Initialize the process security fields lock and the process lock. 00273 // 00274 00275 ExInitializeFastMutex( &PspProcessLockMutex ); 00276 ExInitializeFastMutex( &PsProcessSecurityLock ); 00277 00278 PsIdleProcess = PsGetCurrentProcess(); 00279 PsIdleProcess->Pcb.KernelTime = 0; 00280 PsIdleProcess->Pcb.KernelTime = 0; 00281 00282 // 00283 // Initialize the common fields of the Object Type Prototype record 00284 // 00285 00286 RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); 00287 ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); 00288 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; 00289 ObjectTypeInitializer.SecurityRequired = TRUE; 00290 ObjectTypeInitializer.PoolType = NonPagedPool; 00291 ObjectTypeInitializer.InvalidAttributes = OBJ_PERMANENT | 00292 OBJ_EXCLUSIVE | 00293 OBJ_OPENIF; 00294 00295 00296 // 00297 // Create Object types for Thread and Process Objects. 00298 // 00299 00300 RtlInitUnicodeString(&NameString, L"Process"); 00301 ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_PROCESS_PAGED_CHARGE; 00302 ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_PROCESS_NONPAGED_CHARGE; 00303 ObjectTypeInitializer.DeleteProcedure = PspProcessDelete; 00304 ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS; 00305 ObjectTypeInitializer.GenericMapping = PspProcessMapping; 00306 00307 if ( !NT_SUCCESS(ObCreateObjectType(&NameString, 00308 &ObjectTypeInitializer, 00309 (PSECURITY_DESCRIPTOR) NULL, 00310 &PsProcessType 00311 )) ){ 00312 return FALSE; 00313 } 00314 00315 RtlInitUnicodeString(&NameString, L"Thread"); 00316 ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_THREAD_PAGED_CHARGE; 00317 ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_THREAD_NONPAGED_CHARGE; 00318 ObjectTypeInitializer.DeleteProcedure = PspThreadDelete; 00319 ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS; 00320 ObjectTypeInitializer.GenericMapping = PspThreadMapping; 00321 00322 if ( !NT_SUCCESS(ObCreateObjectType(&NameString, 00323 &ObjectTypeInitializer, 00324 (PSECURITY_DESCRIPTOR) NULL, 00325 &PsThreadType 00326 )) ){ 00327 return FALSE; 00328 } 00329 00330 00331 RtlInitUnicodeString(&NameString, L"Job"); 00332 ObjectTypeInitializer.DefaultPagedPoolCharge = 0; 00333 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EJOB); 00334 ObjectTypeInitializer.DeleteProcedure = PspJobDelete; 00335 ObjectTypeInitializer.CloseProcedure = PspJobClose; 00336 ObjectTypeInitializer.ValidAccessMask = JOB_OBJECT_ALL_ACCESS; 00337 ObjectTypeInitializer.GenericMapping = PspJobMapping; 00338 ObjectTypeInitializer.InvalidAttributes = 0; 00339 00340 if ( !NT_SUCCESS(ObCreateObjectType(&NameString, 00341 &ObjectTypeInitializer, 00342 (PSECURITY_DESCRIPTOR) NULL, 00343 &PsJobType 00344 )) ){ 00345 return FALSE; 00346 } 00347 00348 00349 00350 00351 00352 00353 // 00354 // Initialize active process list head and mutex 00355 // 00356 00357 InitializeListHead(&PsActiveProcessHead); 00358 ExInitializeFastMutex(&PspActiveProcessMutex); 00359 00360 // 00361 // Initialize job list head and mutex 00362 // 00363 00364 InitializeListHead(&PspJobList); 00365 ExInitializeFastMutex(&PspJobListLock); 00366 InitializeListHead(&PspWorkingSetChangeHead.Links); 00367 ExInitializeFastMutex(&PspWorkingSetChangeHead.Lock); 00368 00369 // 00370 // Initialize CID handle table. 00371 // 00372 // N.B. The CID handle table is removed from the handle table list so 00373 // it will not be enumerated for object handle queries. 00374 // 00375 00376 PspCidTable = ExCreateHandleTable(NULL); 00377 if ( ! PspCidTable ) { 00378 return FALSE; 00379 } 00380 ExRemoveHandleTable(PspCidTable); 00381 00382 #if defined(i386) 00383 00384 // 00385 // Ldt Initialization 00386 // 00387 00388 if ( !NT_SUCCESS(PspLdtInitialize()) ) { 00389 return FALSE; 00390 } 00391 00392 // 00393 // Vdm support Initialization 00394 // 00395 00396 if ( !NT_SUCCESS(PspVdmInitialize()) ) { 00397 return FALSE; 00398 } 00399 00400 #endif 00401 00402 // 00403 // Initialize Reaper Data Structures 00404 // 00405 00406 InitializeListHead(&PsReaperListHead); 00407 ExInitializeWorkItem(&PsReaperWorkItem, PspReaper, NULL); 00408 00409 // 00410 // Get a pointer to the system access token. 00411 // This token is used by the boot process, so we can take the pointer 00412 // from there. 00413 // 00414 00415 PspBootAccessToken = PsGetCurrentProcess()->Token; 00416 00417 InitializeObjectAttributes( &ObjectAttributes, 00418 NULL, 00419 0, 00420 NULL, 00421 NULL 00422 ); // FIXFIX 00423 00424 if ( !NT_SUCCESS(PspCreateProcess( 00425 &PspInitialSystemProcessHandle, 00426 PROCESS_ALL_ACCESS, 00427 &ObjectAttributes, 00428 0L, 00429 FALSE, 00430 0L, 00431 0L, 00432 0L 00433 )) ) { 00434 return FALSE; 00435 } 00436 00437 if ( !NT_SUCCESS(ObReferenceObjectByHandle( 00438 PspInitialSystemProcessHandle, 00439 0L, 00440 PsProcessType, 00441 KernelMode, 00442 (PVOID *)&PsInitialSystemProcess, 00443 NULL 00444 )) ) { 00445 00446 return FALSE; 00447 } 00448 00449 strcpy(&PsGetCurrentProcess()->ImageFileName[0],"Idle"); 00450 strcpy(&PsInitialSystemProcess->ImageFileName[0],"System"); 00451 00452 // 00453 // Phase 1 System initialization 00454 // 00455 00456 if ( !NT_SUCCESS(PsCreateSystemThread( 00457 &ThreadHandle, 00458 THREAD_ALL_ACCESS, 00459 &ObjectAttributes, 00460 0L, 00461 NULL, 00462 Phase1Initialization, 00463 (PVOID)LoaderBlock 00464 )) ) { 00465 return FALSE; 00466 } 00467 00468 00469 if ( !NT_SUCCESS(ObReferenceObjectByHandle( 00470 ThreadHandle, 00471 0L, 00472 PsThreadType, 00473 KernelMode, 00474 (PVOID *)&Thread, 00475 NULL 00476 )) ) { 00477 00478 return FALSE; 00479 } 00480 00481 ZwClose( ThreadHandle ); 00482 00483 return TRUE; 00484 } 00485 00486 BOOLEAN 00487 PspInitPhase1 ( 00488 IN PLOADER_PARAMETER_BLOCK LoaderBlock 00489 ) 00490 00491 /*++ 00492 00493 Routine Description: 00494 00495 This routine performs phase 1 process structure initialization. 00496 During this phase, the system DLL is located and relevant entry 00497 points are extracted. 00498 00499 Arguments: 00500 00501 None. 00502 00503 Return Value: 00504 00505 TRUE - Initialization was successful. 00506 00507 FALSE - Initialization Failed. 00508 00509 --*/ 00510 00511 { 00512 00513 NTSTATUS st; 00514 00515 st = PspInitializeSystemDll(); 00516 00517 if ( !NT_SUCCESS(st) ) { 00518 return FALSE; 00519 } 00520 00521 return TRUE; 00522 } 00523 00524 NTSTATUS 00525 PsLocateSystemDll ( 00526 VOID 00527 ) 00528 00529 /*++ 00530 00531 Routine Description: 00532 00533 This function locates the system dll and creates a section for the 00534 DLL and maps it into the system process. 00535 00536 Arguments: 00537 00538 None. 00539 00540 Return Value: 00541 00542 TRUE - Initialization was successful. 00543 00544 FALSE - Initialization Failed. 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 // Initialize the system DLL 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 // Hard error time. A driver is corrupt. 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 // Now that we have the section, reference it, store its address in the 00643 // PspSystemDll and then close handle to the section. 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 // Map the system dll into the user part of the address space 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 Routine Description: 00687 00688 This function maps the system DLL into the specified process. 00689 00690 Arguments: 00691 00692 Process - Supplies the address of the process to map the DLL into. 00693 00694 Return Value: 00695 00696 TBD 00697 00698 --*/ 00699 00700 { 00701 NTSTATUS st; 00702 PVOID ViewBase; 00703 LARGE_INTEGER SectionOffset; 00704 SIZE_T ViewSize; 00705 00706 PAGED_CODE(); 00707 00708 ViewBase = NULL; 00709 SectionOffset.LowPart = 0; 00710 SectionOffset.HighPart = 0; 00711 ViewSize = 0; 00712 00713 // 00714 // Map the system dll into the user part of the address space 00715 // 00716 00717 st = MmMapViewOfSection( 00718 PspSystemDll.Section, 00719 Process, 00720 &ViewBase, 00721 0L, 00722 0L, 00723 &SectionOffset, 00724 &ViewSize, 00725 ViewShare, 00726 0L, 00727 PAGE_READWRITE 00728 ); 00729 00730 if ( st != STATUS_SUCCESS ) { 00731 #if DBG 00732 DbgPrint("PS: Unable to map system dll at based address.\n"); 00733 #endif 00734 st = STATUS_CONFLICTING_ADDRESSES; 00735 } 00736 00737 if ( ARGUMENT_PRESENT(DllBase) ) { 00738 *DllBase = ViewBase; 00739 } 00740 00741 return st; 00742 } 00743 00744 NTSTATUS 00745 PspInitializeSystemDll ( 00746 VOID 00747 ) 00748 00749 /*++ 00750 00751 Routine Description: 00752 00753 This function initializes the system DLL and locates 00754 various entrypoints within the DLL. 00755 00756 Arguments: 00757 00758 None. 00759 00760 Return Value: 00761 00762 TBD 00763 00764 --*/ 00765 00766 { 00767 NTSTATUS st; 00768 PSZ dll_entrypoint; 00769 PVOID R3EmulatorTable; 00770 00771 // 00772 // Locate the important system dll entrypoints 00773 // 00774 00775 dll_entrypoint = "LdrInitializeThunk"; 00776 00777 st = PspLookupSystemDllEntryPoint( 00778 dll_entrypoint, 00779 (PVOID *)&PspSystemDll.LoaderInitRoutine 00780 ); 00781 00782 if ( !NT_SUCCESS(st) ) { 00783 #if DBG 00784 DbgPrint("PS: Unable to locate LdrInitializeThunk in system dll\n"); 00785 #endif 00786 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,6,0,0); 00787 return st; 00788 } 00789 00790 #if i386 00791 // 00792 // Find 80387 emulator. 00793 // 00794 00795 st = PspLookupSystemDllEntryPoint( 00796 "NPXEMULATORTABLE", 00797 &R3EmulatorTable 00798 ); 00799 00800 if ( !NT_SUCCESS(st) ) { 00801 #if DBG 00802 DbgPrint("PS: Unable to locate NPXNPHandler in system dll\n"); 00803 #endif 00804 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,7,0,0); 00805 return st; 00806 } 00807 // 00808 // Pass emulator into kernel, and let it decide whether it should 00809 // use the emulator or set up to use the 80387 hardware. 00810 // 00811 00812 KeSetup80387OrEmulate(R3EmulatorTable); 00813 #endif //i386 00814 00815 st = PspLookupKernelUserEntryPoints(); 00816 00817 if ( !NT_SUCCESS(st) ) { 00818 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,8,0,0); 00819 } 00820 00821 KdUpdateDataBlock(); 00822 00823 return st; 00824 } 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 // The table is ONLY used when fixed quantums are selected. 00860 // 00861 00862 BOOLEAN PspUseJobSchedulingClasses; 00863 00864 SCHAR PspJobSchedulingClasses[PSP_NUMBER_OF_SCHEDULING_CLASSES] = { 00865 1*THREAD_QUANTUM, // long fixed 0 00866 2*THREAD_QUANTUM, // long fixed 1... 00867 3*THREAD_QUANTUM, 00868 4*THREAD_QUANTUM, 00869 5*THREAD_QUANTUM, 00870 6*THREAD_QUANTUM, // DEFAULT 00871 7*THREAD_QUANTUM, 00872 8*THREAD_QUANTUM, 00873 9*THREAD_QUANTUM, 00874 10*THREAD_QUANTUM // long fixed 9 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 // extract priority seperation value 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 // determine if we are using fixed or variable quantums 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 // determine if we are using long or short 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 // Job Scheduling classes are ONLY meaningful if long fixed quantums 00945 // are selected. In practice, this means stock NTS configurations 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 // If the process is contained within a JOB, AND we are 00977 // running Fixed, Long Quantums, use the quantum associated 00978 // with the Job's scheduling class 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 }

Generated on Sat May 15 19:41:32 2004 for test by doxygen 1.3.7