00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "mi.h"
00024
00025 MMPTE MmSharedUserDataPte;
00026
00027 extern MMINPAGE_SUPPORT_LIST MmInPageSupportList;
00028 extern MMEVENT_COUNT_LIST MmEventCountList;
00029 extern KMUTANT MmSystemLoadLock;
00030 extern ULONG_PTR
MmSystemPtesStart[
MaximumPtePoolTypes];
00031 extern ULONG
MiSpecialPoolPtes;
00032 extern ULONG
MmPagedPoolCommit;
00033
00034 extern PVOID
BBTBuffer;
00035 extern ULONG
BBTPagesToReserve;
00036
00037 ULONG_PTR
MmSubsectionBase;
00038 ULONG_PTR
MmSubsectionTopPage;
00039 ULONG
MmDataClusterSize;
00040 ULONG
MmCodeClusterSize;
00041 PFN_NUMBER
MmResidentAvailableAtInit;
00042 KEVENT MmImageMappingPteEvent;
00043 PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
00044 LIST_ENTRY
MmLockConflictList;
00045 LOGICAL
MmPagedPoolMaximumDesired =
FALSE;
00046
00047 PERFINFO_MMINIT_DECL;
00048
00049
VOID
00050
MiMapBBTMemory (
00051 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00052 );
00053
00054
VOID
00055
MiInitializeSpecialPool(
00056 VOID
00057 );
00058
00059
VOID
00060
MiEnablePagingTheExecutive(
00061 VOID
00062 );
00063
00064
VOID
00065
MiEnablePagingOfDriverAtInit (
00066 IN
PMMPTE PointerPte,
00067 IN
PMMPTE LastPte
00068 );
00069
00070
VOID
00071
MiBuildPagedPool (
00072 );
00073
00074
VOID
00075
MiMergeMemoryLimit (
00076 IN OUT
PPHYSICAL_MEMORY_DESCRIPTOR Memory,
00077 IN PFN_NUMBER StartPage,
00078 IN PFN_NUMBER NumberOfPages
00079 );
00080
00081
VOID
00082
MiWriteProtectSystemImage (
00083 IN PVOID DllBase
00084 );
00085
00086
#ifndef NO_POOL_CHECKS
00087
VOID
00088
MiInitializeSpecialPoolCriteria (
00089 IN VOID
00090 );
00091
#endif
00092
00093
#if defined (_X86PAE_)
00094
VOID
00095 MiCheckPaeLicense (
00096 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
00097 IN PBOOLEAN IncludeType,
00098 OUT
PPHYSICAL_MEMORY_DESCRIPTOR Memory
00099 );
00100
#endif
00101
00102
#ifdef ALLOC_PRAGMA
00103
#pragma alloc_text(INIT,MmInitSystem)
00104
#pragma alloc_text(INIT,MiMapBBTMemory)
00105
#pragma alloc_text(INIT,MmInitializeMemoryLimits)
00106
#pragma alloc_text(INIT,MiMergeMemoryLimit)
00107
#pragma alloc_text(INIT,MmFreeLoaderBlock)
00108
#pragma alloc_text(INIT,MiBuildPagedPool)
00109
#pragma alloc_text(INIT,MiFindInitializationCode)
00110
#pragma alloc_text(INIT,MiEnablePagingTheExecutive)
00111
#pragma alloc_text(INIT,MiEnablePagingOfDriverAtInit)
00112
#if defined (_X86PAE_)
00113
#pragma alloc_text(INIT,MiCheckPaeLicense)
00114
#endif
00115
#pragma alloc_text(PAGELK,MiFreeInitializationCode)
00116
#endif
00117
00118 #define MM_MAX_LOADER_BLOCKS 30
00119
00120
00121
00122
00123
00124
00125 ULONG
MmModifiedPageLifeInSeconds = 300;
00126
00127 LARGE_INTEGER
MiModifiedPageLife;
00128
00129 BOOLEAN
MiTimerPending =
FALSE;
00130
00131 KEVENT MiMappedPagesTooOldEvent;
00132
00133 KDPC MiModifiedPageWriterTimerDpc;
00134
00135 KTIMER MiModifiedPageWriterTimer;
00136
00137
00138
00139
00140
00141
00142
00143 #define MM_SMALL_SYSTEM ((13*1024*1024) / 4096)
00144
00145 #define MM_MEDIUM_SYSTEM ((19*1024*1024) / 4096)
00146
00147 #define MM_MIN_INITIAL_PAGED_POOL ((32*1024*1024) >> PAGE_SHIFT)
00148
00149 #define MM_DEFAULT_IO_LOCK_LIMIT (2 * 1024 * 1024)
00150
00151 extern ULONG
MmMaximumWorkingSetSize;
00152
00153 extern ULONG
MmEnforceWriteProtection;
00154
00155 extern CHAR MiPteStr[];
00156
00157 extern LONG
MiTrimInProgressCount;
00158
00159
#if !defined (_WIN64)
00160
00161
#if !defined (_X86PAE_)
00162 PFN_NUMBER
MmSystemPageDirectory;
00163
#else
00164
PFN_NUMBER
MmSystemPageDirectory[PD_PER_SYSTEM];
00165
#endif
00166
00167 PMMPTE MmSystemPagePtes;
00168
#endif
00169
00170 ULONG
MmTotalSystemCodePages;
00171
00172 MM_SYSTEMSIZE MmSystemSize;
00173
00174 ULONG
MmLargeSystemCache;
00175
00176 ULONG
MmProductType;
00177
00178 LIST_ENTRY
MmLoadedUserImageList;
00179 PPAGE_FAULT_NOTIFY_ROUTINE MmPageFaultNotifyRoutine;
00180 PHARD_FAULT_NOTIFY_ROUTINE MmHardFaultNotifyRoutine;
00181
00182
00183 BOOLEAN
00184 MmInitSystem (
00185 IN ULONG Phase,
00186 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
00187 IN
PPHYSICAL_MEMORY_DESCRIPTOR PhysicalMemoryBlock
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
00217
00218
00219
00220
00221 {
00222 HANDLE
ThreadHandle;
00223 OBJECT_ATTRIBUTES
ObjectAttributes;
00224
PMMPTE PointerPte;
00225
PMMPTE PointerPde;
00226
PMMPTE StartPde;
00227
PMMPTE StartPpe;
00228
PMMPTE StartingPte;
00229
PMMPTE EndPde;
00230
PMMPFN Pfn1;
00231
MMPTE Pointer;
00232 PFN_NUMBER i, j;
00233 PFN_NUMBER PageFrameIndex;
00234 PFN_NUMBER DirectoryFrameIndex;
00235
MMPTE TempPte;
00236 KIRQL OldIrql;
00237 LOGICAL First;
00238 PLIST_ENTRY NextEntry;
00239 PLDR_DATA_TABLE_ENTRY DataTableEntry;
00240 ULONG MaximumSystemCacheSize;
00241 ULONG MaximumSystemCacheSizeTotal;
00242
PEPROCESS Process;
00243 PIMAGE_NT_HEADERS NtHeaders;
00244 ULONG_PTR SystemPteMultiplier;
00245
00246 BOOLEAN IncludeType[
LoaderMaximum];
00247 ULONG MemoryAlloc[(
sizeof(
PHYSICAL_MEMORY_DESCRIPTOR) +
00248
sizeof(
PHYSICAL_MEMORY_RUN)*
MAX_PHYSICAL_MEMORY_FRAGMENTS) /
00249
sizeof(ULONG)];
00250
00251
PPHYSICAL_MEMORY_DESCRIPTOR Memory;
00252
00253
00254
00255
00256
00257
if (Phase == 0) {
00258
MmThrottleTop = 450;
00259
MmThrottleBottom = 127;
00260
00261
00262
00263
00264
00265
00266
#if defined(_AXP64_) || defined(_IA64_)
00267
00268
MmHighestUserAddress = MM_HIGHEST_USER_ADDRESS;
00269
MmUserProbeAddress = MM_USER_PROBE_ADDRESS;
00270
MmSystemRangeStart = MM_SYSTEM_RANGE_START;
00271
00272
#else
00273
00274
MmHighestUserAddress = (PVOID)(
KSEG0_BASE - 0x10000 - 1);
00275
MmUserProbeAddress =
KSEG0_BASE - 0x10000;
00276
MmSystemRangeStart = (PVOID)
KSEG0_BASE;
00277
00278
#endif
00279
00280
MiHighestUserPte =
MiGetPteAddress (
MmHighestUserAddress);
00281
MiHighestUserPde =
MiGetPdeAddress (
MmHighestUserAddress);
00282
00283
MmVirtualBias = 0;
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
MmHighSectionBase = ((PCHAR)
MmHighestUserAddress - 0x800000);
00294
00295
if (
ExVerifySuite(TerminalServer) ==
TRUE) {
00296
MiHydra =
TRUE;
00297
MiSystemViewStart =
MM_SYSTEM_VIEW_START_IF_HYDRA;
00298
MmSessionBase = (ULONG_PTR)
MM_SESSION_SPACE_DEFAULT;
00299
00300 }
else {
00301
MiSystemViewStart =
MM_SYSTEM_VIEW_START;
00302
MiHydra =
FALSE;
00303 }
00304
00305 MaximumSystemCacheSize = (
MM_SYSTEM_CACHE_END -
MM_SYSTEM_CACHE_START) >>
PAGE_SHIFT;
00306
00307
00308
00309
00310
00311
00312
00313
#if defined(_X86_)
00314
00315
MmVirtualBias = LoaderBlock->u.I386.VirtualBias;
00316
00317
if (
MmVirtualBias != 0) {
00318
MmHighestUserAddress = ((PCHAR)
MmHighestUserAddress + 0x40000000);
00319
MmSystemRangeStart = ((PCHAR)
MmSystemRangeStart + 0x40000000);
00320
MmUserProbeAddress += 0x40000000;
00321
MiMaximumWorkingSet += 0x40000000 >>
PAGE_SHIFT;
00322
00323
MiHighestUserPte =
MiGetPteAddress (
MmHighestUserAddress);
00324
MiHighestUserPde =
MiGetPdeAddress (
MmHighestUserAddress);
00325
00326 MaximumSystemCacheSize -=
MM_BOOT_IMAGE_SIZE >>
PAGE_SHIFT;
00327
00328
if (
MiHydra ==
TRUE) {
00329
00330
00331
00332
00333
00334
00335
00336 MaximumSystemCacheSize -= (
MI_SESSION_SPACE_TOTAL_SIZE +
MM_SYSTEM_VIEW_SIZE_IF_HYDRA) >>
PAGE_SHIFT;
00337
00338
MiSystemViewStart = (ULONG_PTR)(
MM_SYSTEM_CACHE_START +
00339 (MaximumSystemCacheSize <<
PAGE_SHIFT));
00340
00341
MmSessionBase =
MiSystemViewStart +
MM_SYSTEM_VIEW_SIZE_IF_HYDRA +
MM_BOOT_IMAGE_SIZE;
00342
00343 }
else {
00344 MaximumSystemCacheSize -=
MM_SYSTEM_VIEW_SIZE >>
PAGE_SHIFT;
00345
MiSystemViewStart = (ULONG_PTR)(
MM_SYSTEM_CACHE_START +
00346 (MaximumSystemCacheSize <<
PAGE_SHIFT) +
00347
MM_BOOT_IMAGE_SIZE);
00348 }
00349 }
00350
00351
#else
00352
00353
if (
MiHydra ==
TRUE) {
00354 MaximumSystemCacheSize -=
MM_SYSTEM_VIEW_SIZE_IF_HYDRA >>
PAGE_SHIFT;
00355
MiSystemViewStart =
MM_SYSTEM_VIEW_START_IF_HYDRA;
00356 }
00357
00358
#endif
00359
00360
if (
MiHydra ==
TRUE) {
00361
MmSessionSpace = (
PMM_SESSION_SPACE)((ULONG_PTR)
MmSessionBase +
MI_SESSION_IMAGE_SIZE);
00362
00363
MiSessionBasePte =
MiGetPteAddress (
MmSessionBase);
00364
MiSessionLastPte =
MiGetPteAddress (
MI_SESSION_SPACE_END);
00365 }
00366
00367
00368
00369
00370
00371
#if DBG
00372
if ((
sizeof(
MMWSL) % 8) != 0) {
00373
DbgPrint(
"working set list is not a quadword sized structure\n");
00374 }
00375
00376
if ((
sizeof(
CONTROL_AREA) % 8) != 0) {
00377
DbgPrint(
"control area list is not a quadword sized structure\n");
00378 }
00379
00380
if ((
sizeof(
SUBSECTION) % 8) != 0) {
00381
DbgPrint(
"subsection list is not a quadword sized structure\n");
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 PointerPte = (
PMMPTE)
MmPagedPoolStart;
00391 Pointer.
u.Long =
MiProtoAddressForPte (PointerPte);
00392 TempPte = Pointer;
00393 PointerPde =
MiPteToProto(&TempPte);
00394
if (PointerPte != PointerPde) {
00395
DbgPrint(
"unable to map start of paged pool as prototype pte %p %p\n",
00396 PointerPde,
00397 PointerPte);
00398 }
00399
00400 PointerPte =
00401 (
PMMPTE)((ULONG_PTR)
MM_NONPAGED_POOL_END & ~((1 <<
PTE_SHIFT) - 1));
00402
00403 Pointer.
u.Long =
MiProtoAddressForPte (PointerPte);
00404 TempPte = Pointer;
00405 PointerPde =
MiPteToProto(&TempPte);
00406
if (PointerPte != PointerPde) {
00407
DbgPrint(
"unable to map end of nonpaged pool as prototype pte %p %p\n",
00408 PointerPde,
00409 PointerPte);
00410 }
00411
00412 PointerPte = (
PMMPTE)(((ULONG_PTR)
NON_PAGED_SYSTEM_END -
00413 0x37000 +
PAGE_SIZE - 1) & ~(
PAGE_SIZE - 1));
00414
00415
for (j = 0; j < 20; j++) {
00416 Pointer.
u.Long =
MiProtoAddressForPte (PointerPte);
00417 TempPte = Pointer;
00418 PointerPde =
MiPteToProto(&TempPte);
00419
if (PointerPte != PointerPde) {
00420
DbgPrint(
"unable to map end of nonpaged pool as prototype pte %p %p\n",
00421 PointerPde,
00422 PointerPte);
00423 }
00424
00425 PointerPte++;
00426 }
00427
00428 PointerPte = (
PMMPTE)(((ULONG_PTR)
MM_NONPAGED_POOL_END - 0x133448) & ~(ULONG_PTR)7);
00429 Pointer.
u.Long =
MiGetSubsectionAddressForPte (PointerPte);
00430 TempPte = Pointer;
00431 PointerPde = (
PMMPTE)
MiGetSubsectionAddress(&TempPte);
00432
if (PointerPte != PointerPde) {
00433
DbgPrint(
"unable to map end of nonpaged pool as section pte %p %p\n",
00434 PointerPde,
00435 PointerPte);
00436
00437
MiFormatPte(&TempPte);
00438 }
00439
00440
00441
00442
00443
00444
#endif //dbg
00445
00446
if (
MmEnforceWriteProtection) {
00447
MiPteStr[0] = (
CHAR)1;
00448 }
00449
00450 InitializeListHead( &
MmLoadedUserImageList );
00451 InitializeListHead( &
MmLockConflictList );
00452
00453
MmCriticalSectionTimeout.QuadPart = Int32x32To64(
00454
MmCritsectTimeoutSeconds,
00455 -10000000);
00456
00457
00458
00459
00460
00461
00462
00463
ExInitializeFastMutex (&
MmSectionCommitMutex);
00464
ExInitializeFastMutex (&
MmSectionBasedMutex);
00465
ExInitializeFastMutex (&
MmDynamicMemoryMutex);
00466
00467
KeInitializeMutant (&
MmSystemLoadLock,
FALSE);
00468
00469
KeInitializeEvent (&
MmAvailablePagesEvent, NotificationEvent,
TRUE);
00470
KeInitializeEvent (&
MmAvailablePagesEventHigh, NotificationEvent,
TRUE);
00471
KeInitializeEvent (&
MmMappedFileIoComplete, NotificationEvent,
FALSE);
00472
KeInitializeEvent (&
MmImageMappingPteEvent, NotificationEvent,
FALSE);
00473
KeInitializeEvent (&
MmZeroingPageEvent, SynchronizationEvent,
FALSE);
00474
KeInitializeEvent (&
MmCollidedFlushEvent, NotificationEvent,
FALSE);
00475
KeInitializeEvent (&
MmCollidedLockEvent, NotificationEvent,
FALSE);
00476
KeInitializeEvent (&
MiMappedPagesTooOldEvent, NotificationEvent,
FALSE);
00477
00478
KeInitializeDpc( &
MiModifiedPageWriterTimerDpc,
MiModifiedPageWriterTimerDispatch,
NULL );
00479
KeInitializeTimerEx( &
MiModifiedPageWriterTimer, SynchronizationTimer );
00480
00481
MiModifiedPageLife.QuadPart = Int32x32To64(
00482
MmModifiedPageLifeInSeconds,
00483 -10000000);
00484
00485 InitializeListHead (&
MmWorkingSetExpansionHead.
ListHead);
00486 InitializeListHead (&
MmInPageSupportList.
ListHead);
00487 InitializeListHead (&
MmEventCountList.
ListHead);
00488
00489
MmZeroingPageThreadActive =
FALSE;
00490
00491
00492
00493
00494
00495 Memory = (
PPHYSICAL_MEMORY_DESCRIPTOR)&MemoryAlloc;
00496 Memory->
NumberOfRuns =
MAX_PHYSICAL_MEMORY_FRAGMENTS;
00497
00498
00499
for (i=0; i <
LoaderMaximum; i++) {
00500 IncludeType[i] =
TRUE;
00501 }
00502
00503
00504 IncludeType[
LoaderBad] =
FALSE;
00505 IncludeType[
LoaderFirmwarePermanent] =
FALSE;
00506 IncludeType[
LoaderSpecialMemory] =
FALSE;
00507 IncludeType[
LoaderBBTMemory] =
FALSE;
00508
00509
MmInitializeMemoryLimits(LoaderBlock, IncludeType, Memory);
00510
00511
#if defined (_X86PAE_)
00512
MiCheckPaeLicense (LoaderBlock, IncludeType, Memory);
00513
#endif
00514
00515
#if defined (_X86PAE_) || defined (_WIN64)
00516
Mm64BitPhysicalAddress =
TRUE;
00517
#endif
00518
00519
00520
00521
00522
00523
for (i = 0; i < PhysicalMemoryBlock->NumberOfRuns; i += 1) {
00524
MiMergeMemoryLimit (Memory,
00525 PhysicalMemoryBlock->
Run[i].
BasePage,
00526 PhysicalMemoryBlock->Run[i].PageCount
00527 );
00528 }
00529
00530
00531
00532
00533
00534
for (i=0; i < Memory->
NumberOfRuns; i++) {
00535
for (j=i+1; j < Memory->
NumberOfRuns; j++) {
00536
if (Memory->
Run[j].
BasePage < Memory->
Run[i].
BasePage) {
00537
00538 PhysicalMemoryBlock->Run[0] = Memory->
Run[j];
00539 Memory->
Run[j] = Memory->
Run[i];
00540 Memory->
Run[i] = PhysicalMemoryBlock->Run[0];
00541 }
00542
00543
if (Memory->
Run[i].
BasePage + Memory->
Run[i].
PageCount ==
00544 Memory->
Run[j].
BasePage) {
00545
00546 Memory->
NumberOfRuns -= 1;
00547 Memory->
Run[i].
PageCount += Memory->
Run[j].
PageCount;
00548 Memory->
Run[j] = Memory->
Run[Memory->
NumberOfRuns];
00549 i -= 1;
00550
break;
00551 }
00552 }
00553 }
00554
00555
00556
00557
00558
00559
00560
if (strstr(LoaderBlock->LoadOptions, SAFEBOOT_LOAD_OPTION_A)) {
00561
MmVerifyDriverBufferLength = (ULONG)-1;
00562
MmDontVerifyRandomDrivers =
TRUE;
00563
MmSpecialPoolTag = (ULONG)-1;
00564
MmSnapUnloads =
FALSE;
00565
MmProtectFreedNonPagedPool =
FALSE;
00566
MmEnforceWriteProtection = 0;
00567
MmTrackLockedPages =
FALSE;
00568
MmTrackPtes =
FALSE;
00569 }
00570
else {
00571
MiTriageSystem (LoaderBlock);
00572 }
00573
00574 SystemPteMultiplier = 0;
00575
00576
if (
MmNumberOfSystemPtes == 0) {
00577
#if defined (_WIN64)
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
if ((
MiHydra ==
TRUE) && (
ExpMultiUserTS ==
TRUE)) {
00591 SystemPteMultiplier = 128;
00592 }
00593
else {
00594 SystemPteMultiplier = 64;
00595 }
00596
if (Memory->
NumberOfPages < 0x8000) {
00597 SystemPteMultiplier >>= 1;
00598 }
00599
#else
00600
if (Memory->
NumberOfPages <
MM_MEDIUM_SYSTEM) {
00601
MmNumberOfSystemPtes =
MM_MINIMUM_SYSTEM_PTES;
00602 }
else {
00603
MmNumberOfSystemPtes =
MM_DEFAULT_SYSTEM_PTES;
00604
if (Memory->
NumberOfPages > 8192) {
00605
MmNumberOfSystemPtes +=
MmNumberOfSystemPtes;
00606
00607
00608
00609
00610
00611
if ((
MiHydra ==
TRUE) && (
ExpMultiUserTS ==
TRUE)) {
00612
MmNumberOfSystemPtes =
MM_MAXIMUM_SYSTEM_PTES;
00613 }
00614 }
00615 }
00616
#endif
00617
}
00618
else if (
MmNumberOfSystemPtes == (ULONG)-1) {
00619
00620
00621
00622
00623
00624
00625
00626
MiRequestedSystemPtes =
MmNumberOfSystemPtes;
00627
00628
#if defined (_WIN64)
00629
SystemPteMultiplier = 256;
00630
#else
00631
MmNumberOfSystemPtes =
MM_MAXIMUM_SYSTEM_PTES;
00632
#endif
00633
}
00634
00635
if (SystemPteMultiplier != 0) {
00636
if (Memory->
NumberOfPages * SystemPteMultiplier >
MM_MAXIMUM_SYSTEM_PTES) {
00637
MmNumberOfSystemPtes =
MM_MAXIMUM_SYSTEM_PTES;
00638 }
00639
else {
00640
MmNumberOfSystemPtes = (ULONG)(Memory->
NumberOfPages * SystemPteMultiplier);
00641 }
00642 }
00643
00644
if (
MmNumberOfSystemPtes >
MM_MAXIMUM_SYSTEM_PTES) {
00645
MmNumberOfSystemPtes =
MM_MAXIMUM_SYSTEM_PTES;
00646 }
00647
00648
if (
MmNumberOfSystemPtes <
MM_MINIMUM_SYSTEM_PTES) {
00649
MmNumberOfSystemPtes =
MM_MINIMUM_SYSTEM_PTES;
00650 }
00651
00652
if (
MmHeapSegmentReserve == 0) {
00653
MmHeapSegmentReserve = 1024 * 1024;
00654 }
00655
00656
if (
MmHeapSegmentCommit == 0) {
00657
MmHeapSegmentCommit =
PAGE_SIZE * 2;
00658 }
00659
00660
if (
MmHeapDeCommitTotalFreeThreshold == 0) {
00661
MmHeapDeCommitTotalFreeThreshold = 64 * 1024;
00662 }
00663
00664
if (
MmHeapDeCommitFreeBlockThreshold == 0) {
00665
MmHeapDeCommitFreeBlockThreshold =
PAGE_SIZE;
00666 }
00667
00668
#ifndef NO_POOL_CHECKS
00669
MiInitializeSpecialPoolCriteria ();
00670
#endif
00671
00672
00673
00674
00675
00676
00677
00678
if ((
MmVerifyDriverBufferLength != (ULONG)-1) ||
00679 ((
MmSpecialPoolTag != 0) && (
MmSpecialPoolTag != (ULONG)-1))) {
00680
MmNumberOfSystemPtes +=
MM_SPECIAL_POOL_PTES;
00681 }
00682
00683
MmNumberOfSystemPtes +=
BBTPagesToReserve;
00684
00685
00686
00687
00688
00689
ExInitializeResource (&
MmSystemWsLock);
00690
00691
MiInitMachineDependent (LoaderBlock);
00692
00693
#if PFN_CONSISTENCY
00694
MiPfnProtectionEnabled =
TRUE;
00695
#endif
00696
00697
MiReloadBootLoadedDrivers (LoaderBlock);
00698
00699
MiInitializeDriverVerifierList (LoaderBlock);
00700
00701 j = (
sizeof(
PHYSICAL_MEMORY_DESCRIPTOR) +
00702 (
sizeof(
PHYSICAL_MEMORY_RUN) *
00703 (Memory->
NumberOfRuns - 1)));
00704
00705
MmPhysicalMemoryBlock =
ExAllocatePoolWithTag (
NonPagedPoolMustSucceed,
00706 j,
00707 ' mM');
00708
00709 RtlCopyMemory (
MmPhysicalMemoryBlock, Memory, j);
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
MmReadClusterSize = 7;
00731
if (
MmNumberOfPhysicalPages <=
MM_SMALL_SYSTEM ) {
00732
MmSystemSize =
MmSmallSystem;
00733
MmMaximumDeadKernelStacks = 0;
00734
MmModifiedPageMinimum = 40;
00735
MmModifiedPageMaximum = 100;
00736
MmDataClusterSize = 0;
00737
MmCodeClusterSize = 1;
00738
MmReadClusterSize = 2;
00739
00740 }
else if (
MmNumberOfPhysicalPages <=
MM_MEDIUM_SYSTEM ) {
00741
MmSystemSize =
MmSmallSystem;
00742
MmMaximumDeadKernelStacks = 2;
00743
MmModifiedPageMinimum = 80;
00744
MmModifiedPageMaximum = 150;
00745
MmSystemCacheWsMinimum += 100;
00746
MmSystemCacheWsMaximum += 150;
00747
MmDataClusterSize = 1;
00748
MmCodeClusterSize = 2;
00749
MmReadClusterSize = 4;
00750
00751 }
else {
00752
MmSystemSize =
MmMediumSystem;
00753
MmMaximumDeadKernelStacks = 5;
00754
MmModifiedPageMinimum = 150;
00755
MmModifiedPageMaximum = 300;
00756
MmSystemCacheWsMinimum += 400;
00757
MmSystemCacheWsMaximum += 800;
00758
MmDataClusterSize = 3;
00759
MmCodeClusterSize = 7;
00760 }
00761
00762
if (
MmNumberOfPhysicalPages < ((24*1024*1024)/
PAGE_SIZE)) {
00763
MmSystemCacheWsMinimum = 32;
00764 }
00765
00766
if (
MmNumberOfPhysicalPages >= ((32*1024*1024)/
PAGE_SIZE)) {
00767
00768
00769
00770
00771
if (
MmProductType == 0x00690057 ) {
00772
MmSystemSize =
MmLargeSystem;
00773
00774 }
else {
00775
00776
00777
00778
00779
00780
if (
MmNumberOfPhysicalPages >= ((64*1024*1024)/
PAGE_SIZE)) {
00781
MmSystemSize =
MmLargeSystem;
00782 }
00783 }
00784 }
00785
00786
if (
MmNumberOfPhysicalPages > ((33*1024*1024)/
PAGE_SIZE)) {
00787
MmModifiedPageMinimum = 400;
00788
MmModifiedPageMaximum = 800;
00789
MmSystemCacheWsMinimum += 500;
00790
MmSystemCacheWsMaximum += 900;
00791 }
00792
00793
00794
00795
00796
00797
if (
MmProductType == 0x00690057) {
00798 SharedUserData->NtProductType = NtProductWinNt;
00799
MmProductType = 0;
00800
MmThrottleTop = 250;
00801
MmThrottleBottom = 30;
00802
00803 }
else {
00804
if (
MmProductType == 0x0061004c ) {
00805 SharedUserData->NtProductType = NtProductLanManNt;
00806
00807 }
else {
00808 SharedUserData->NtProductType = NtProductServer;
00809 }
00810
00811
MmProductType = 1;
00812
MmThrottleTop = 450;
00813
MmThrottleBottom = 80;
00814
MmMinimumFreePages = 81;
00815 }
00816
00817
MiAdjustWorkingSetManagerParameters((BOOLEAN)(
MmProductType == 0 ?
TRUE :
FALSE));
00818
00819
00820
00821
00822
00823
00824
MmResidentAvailablePages =
MmAvailablePages -
MM_FLUID_PHYSICAL_PAGES;
00825
00826
00827
00828
00829
00830
MmResidentAvailablePages -=
MmSystemCacheWsMinimum;
00831
MmResidentAvailableAtInit =
MmResidentAvailablePages;
00832
00833
00834
if (
MmResidentAvailablePages < 0) {
00835
#if DBG
00836
DbgPrint(
"system cache working set too big\n");
00837
#endif
00838
return FALSE;
00839 }
00840
00841
00842
00843
00844
00845
00846
KeInitializeSpinLock (&
MmChargeCommitmentLock);
00847
00848
MiInitializeIoTrackers ();
00849
00850
00851
00852
00853
00854
KeInitializeSpinLock (&
MmExpansionLock);
00855
00856
ExInitializeFastMutex (&
MmPageFileCreationLock);
00857
00858
00859
00860
00861
00862
ExInitializeResource (&
MmSectionExtendResource);
00863
ExInitializeResource (&
MmSectionExtendSetResource);
00864
00865
00866
00867
00868
00869 StartPde =
MiGetPdeAddress (
MmSystemCacheWorkingSetList);
00870 PointerPte =
MiGetPteAddress (
MmSystemCacheWorkingSetList);
00871
00872
#if defined (_WIN64)
00873
00874 StartPpe =
MiGetPteAddress(StartPde);
00875
00876 TempPte =
ValidKernelPte;
00877
00878
if (StartPpe->
u.Hard.Valid == 0) {
00879
00880
00881
00882
00883
00884
00885 DirectoryFrameIndex =
MiRemoveAnyPage(
00886
MI_GET_PAGE_COLOR_FROM_PTE (StartPpe));
00887 TempPte.
u.Hard.PageFrameNumber = DirectoryFrameIndex;
00888 *StartPpe = TempPte;
00889
00890
00891 Pfn1 =
MI_PFN_ELEMENT(DirectoryFrameIndex);
00892 Pfn1->
PteFrame =
MI_GET_PAGE_FRAME_FROM_PTE (
00893
MiGetPteAddress(
PDE_KTBASE));
00894 Pfn1->
PteAddress = StartPpe;
00895 Pfn1->
u2.ShareCount += 1;
00896 Pfn1->
u3.e2.ReferenceCount = 1;
00897 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
00898 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
00899
00900
MiFillMemoryPte (StartPde,
00901
PAGE_SIZE,
00902
ZeroKernelPte.
u.Long);
00903 }
00904
00905
00906
00907
00908
00909
ASSERT (StartPde->
u.Hard.Valid == 0);
00910
00911 PageFrameIndex =
MiRemoveAnyPage(
00912
MI_GET_PAGE_COLOR_FROM_PTE (StartPde));
00913 TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
00914
MI_WRITE_VALID_PTE (StartPde, TempPte);
00915
00916 Pfn1 =
MI_PFN_ELEMENT(PageFrameIndex);
00917 Pfn1->
PteFrame = DirectoryFrameIndex;
00918 Pfn1->
PteAddress = StartPde;
00919 Pfn1->
u2.ShareCount += 1;
00920 Pfn1->
u3.e2.ReferenceCount = 1;
00921 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
00922 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
00923
00924
MiFillMemoryPte (
MiGetVirtualAddressMappedByPte (StartPde),
00925
PAGE_SIZE,
00926
ZeroKernelPte.
u.Long);
00927
00928 StartPpe =
MiGetPpeAddress(
MmSystemCacheStart);
00929 StartPde =
MiGetPdeAddress(
MmSystemCacheStart);
00930 PointerPte =
MiGetVirtualAddressMappedByPte (StartPde);
00931
00932
#else
00933
#if !defined(_X86PAE_)
00934
ASSERT ((StartPde + 1) ==
MiGetPdeAddress (
MmSystemCacheStart));
00935
#endif
00936
#endif
00937
00938 MaximumSystemCacheSizeTotal = MaximumSystemCacheSize;
00939
00940
#if defined(_X86_)
00941
MaximumSystemCacheSizeTotal +=
MiMaximumSystemCacheSizeExtra;
00942
#endif
00943
00944
00945
00946
00947
00948 i = (
MmNumberOfPhysicalPages + 65) / 1024;
00949
00950
if (i >= 4) {
00951
00952
00953
00954
00955
00956
00957
MmSizeOfSystemCacheInPages = (PFN_COUNT)(
00958 ((128*1024*1024) >>
PAGE_SHIFT) +
00959 ((i - 4) * ((64*1024*1024) >>
PAGE_SHIFT)));
00960
if (
MmSizeOfSystemCacheInPages > MaximumSystemCacheSizeTotal) {
00961
MmSizeOfSystemCacheInPages = MaximumSystemCacheSizeTotal;
00962 }
00963 }
00964
00965
MmSystemCacheEnd = (PVOID)(((PCHAR)
MmSystemCacheStart +
00966
MmSizeOfSystemCacheInPages *
PAGE_SIZE) - 1);
00967
00968
#if defined(_X86_)
00969
if (
MmSizeOfSystemCacheInPages > MaximumSystemCacheSize) {
00970
ASSERT (
MiMaximumSystemCacheSizeExtra != 0);
00971
MmSystemCacheEnd = (PVOID)(((PCHAR)
MmSystemCacheStart +
00972 MaximumSystemCacheSize *
PAGE_SIZE) - 1);
00973
00974
MiSystemCacheStartExtra = (PVOID)
MM_SYSTEM_CACHE_START_EXTRA;
00975
MiSystemCacheEndExtra = (PVOID)(((PCHAR)
MiSystemCacheStartExtra +
00976 (
MmSizeOfSystemCacheInPages - MaximumSystemCacheSize) *
PAGE_SIZE) - 1);
00977 }
00978
else {
00979
MiSystemCacheStartExtra =
MmSystemCacheStart;
00980
MiSystemCacheEndExtra =
MmSystemCacheEnd;
00981 }
00982
#endif
00983
00984 EndPde =
MiGetPdeAddress(
MmSystemCacheEnd);
00985
00986 TempPte =
ValidKernelPte;
00987
00988
#if defined(_WIN64)
00989
First = (StartPpe->
u.Hard.Valid == 0) ?
TRUE :
FALSE;
00990
#endif
00991
00992
#if !defined (_WIN64)
00993
DirectoryFrameIndex =
MI_GET_PAGE_FRAME_FROM_PTE (
MiGetPteAddress(PDE_BASE));
00994
#endif
00995
00996
LOCK_PFN (OldIrql);
00997
while (StartPde <= EndPde) {
00998
00999
#if defined (_WIN64)
01000
if (First ==
TRUE ||
MiIsPteOnPdeBoundary(StartPde)) {
01001 First =
FALSE;
01002 StartPpe =
MiGetPteAddress(StartPde);
01003
01004
01005
01006
01007
01008 DirectoryFrameIndex =
MiRemoveAnyPage(
01009
MI_GET_PAGE_COLOR_FROM_PTE (StartPpe));
01010 TempPte.
u.Hard.PageFrameNumber = DirectoryFrameIndex;
01011 *StartPpe = TempPte;
01012
01013 Pfn1 =
MI_PFN_ELEMENT(DirectoryFrameIndex);
01014 Pfn1->
PteFrame =
MI_GET_PAGE_FRAME_FROM_PTE (
01015
MiGetPteAddress(
PDE_KTBASE));
01016 Pfn1->
PteAddress = StartPpe;
01017 Pfn1->
u2.ShareCount += 1;
01018 Pfn1->
u3.e2.ReferenceCount = 1;
01019 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01020 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
01021
01022
MiFillMemoryPte (StartPde,
01023
PAGE_SIZE,
01024
ZeroKernelPte.
u.Long);
01025 }
01026
#endif
01027
01028
ASSERT (StartPde->u.Hard.Valid == 0);
01029
01030
01031
01032
01033
01034 PageFrameIndex =
MiRemoveAnyPage(
01035
MI_GET_PAGE_COLOR_FROM_PTE (StartPde));
01036 TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
01037
MI_WRITE_VALID_PTE (StartPde, TempPte);
01038
01039 Pfn1 =
MI_PFN_ELEMENT(PageFrameIndex);
01040 Pfn1->
PteFrame = DirectoryFrameIndex;
01041 Pfn1->
PteAddress = StartPde;
01042 Pfn1->
u2.ShareCount += 1;
01043 Pfn1->
u3.e2.ReferenceCount = 1;
01044 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01045 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
01046
01047
MiFillMemoryPte (PointerPte,
01048
PAGE_SIZE,
01049
ZeroKernelPte.
u.Long);
01050
01051 StartPde += 1;
01052 PointerPte +=
PTE_PER_PAGE;
01053 }
01054
01055
#if defined(_X86_)
01056
if (
MiSystemCacheEndExtra !=
MmSystemCacheEnd) {
01057
01058 StartPde =
MiGetPdeAddress (
MiSystemCacheStartExtra);
01059 EndPde =
MiGetPdeAddress(
MiSystemCacheEndExtra);
01060
01061 PointerPte =
MiGetPteAddress (
MiSystemCacheStartExtra);
01062
01063
while (StartPde <= EndPde) {
01064
01065
ASSERT (StartPde->u.Hard.Valid == 0);
01066
01067
01068
01069
01070
01071 PageFrameIndex =
MiRemoveAnyPage(
01072
MI_GET_PAGE_COLOR_FROM_PTE (StartPde));
01073 TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
01074
MI_WRITE_VALID_PTE (StartPde, TempPte);
01075
01076 Pfn1 =
MI_PFN_ELEMENT(PageFrameIndex);
01077 Pfn1->
PteFrame =
MI_GET_PAGE_FRAME_FROM_PTE (
01078
MiGetPdeAddress(PDE_BASE));
01079 Pfn1->
PteAddress = StartPde;
01080 Pfn1->
u2.ShareCount += 1;
01081 Pfn1->
u3.e2.ReferenceCount = 1;
01082 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
01083 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
01084
01085
MiFillMemoryPte (PointerPte,
01086
PAGE_SIZE,
01087
ZeroKernelPte.
u.Long);
01088
01089 StartPde += 1;
01090 PointerPte +=
PTE_PER_PAGE;
01091 }
01092 }
01093
#endif
01094
01095
UNLOCK_PFN (OldIrql);
01096
01097
01098
01099
01100
01101
01102
if (
MmLargeSystemCache != 0 &&
MmNumberOfPhysicalPages > 0x7FF0) {
01103
if ((
MmAvailablePages >
01104
MmSystemCacheWsMaximum + ((64*1024*1024) >>
PAGE_SHIFT))) {
01105
MmSystemCacheWsMaximum =
01106
MmAvailablePages - ((32*1024*1024) >>
PAGE_SHIFT);
01107
ASSERT ((LONG)
MmSystemCacheWsMaximum > (LONG)
MmSystemCacheWsMinimum);
01108
MmMoreThanEnoughFreePages = 256;
01109 }
01110 }
01111
01112
if (
MmSystemCacheWsMaximum > (
MM_MAXIMUM_WORKING_SET - 5)) {
01113
MmSystemCacheWsMaximum =
MM_MAXIMUM_WORKING_SET - 5;
01114 }
01115
01116
if (
MmSystemCacheWsMaximum >
MmSizeOfSystemCacheInPages) {
01117
MmSystemCacheWsMaximum =
MmSizeOfSystemCacheInPages;
01118
if ((
MmSystemCacheWsMinimum + 500) >
MmSystemCacheWsMaximum) {
01119
MmSystemCacheWsMinimum =
MmSystemCacheWsMaximum - 500;
01120 }
01121 }
01122
01123
MiInitializeSystemCache ((ULONG)
MmSystemCacheWsMinimum,
01124 (ULONG)
MmSystemCacheWsMaximum);
01125
01126
01127
01128
01129
01130
01131
MmTotalCommitLimit =
MmAvailablePages << 2;
01132
MmTotalCommitLimitMaximum =
MmTotalCommitLimit;
01133
01134
MmAttemptForCantExtend.
Segment =
NULL;
01135
MmAttemptForCantExtend.
RequestedExpansionSize = 1;
01136
MmAttemptForCantExtend.
ActualExpansion = 1;
01137
MmAttemptForCantExtend.
InProgress =
FALSE;
01138
MmAttemptForCantExtend.
PageFileNumber =
MI_EXTEND_ANY_PAGEFILE;
01139
01140
KeInitializeEvent (&
MmAttemptForCantExtend.
Event,
01141 NotificationEvent,
01142
FALSE);
01143
01144
if (
MmOverCommit == 0) {
01145
01146
01147
01148
01149
01150
01151
if (
MmAvailablePages > 1024) {
01152
MmOverCommit =
MmAvailablePages - 1024;
01153 }
01154 }
01155
01156
01157
01158
01159
01160
01161
MmMaximumWorkingSetSize = (ULONG)(
MmAvailablePages - 512);
01162
01163
if (
MmMaximumWorkingSetSize > (
MM_MAXIMUM_WORKING_SET - 5)) {
01164
MmMaximumWorkingSetSize =
MM_MAXIMUM_WORKING_SET - 5;
01165 }
01166
01167
01168
01169
01170
01171
KeInitializeEvent (&
MmModifiedPageWriterEvent, NotificationEvent,
FALSE);
01172
01173
01174
01175
01176
01177
MiBuildPagedPool ();
01178
01179
01180
01181
01182
01183
01184
if (
MiInitializeLoadedModuleList (LoaderBlock) ==
FALSE) {
01185
#if DBG
01186
DbgPrint(
"Loaded module list initialization failed\n");
01187
#endif
01188
return FALSE;
01189 }
01190
01191
01192
01193
01194
01195
01196
01197
if (
MmUnusedSegmentTrimLevel < 5) {
01198
MmUnusedSegmentTrimLevel = 5;
01199 }
01200
else if (
MmUnusedSegmentTrimLevel > 40) {
01201
MmUnusedSegmentTrimLevel = 40;
01202 }
01203
01204
MmMaxUnusedSegmentPagedPoolUsage = (
MmSizeOfPagedPoolInBytes / 100) * (
MmUnusedSegmentTrimLevel << 1);
01205
MmUnusedSegmentPagedPoolReduction =
MmMaxUnusedSegmentPagedPoolUsage >> 2;
01206
01207
MmMaxUnusedSegmentNonPagedPoolUsage = (
MmMaximumNonPagedPoolInBytes / 100) * (
MmUnusedSegmentTrimLevel << 1);
01208
MmUnusedSegmentNonPagedPoolReduction =
MmMaxUnusedSegmentNonPagedPoolUsage >> 2;
01209
01210
01211
01212
01213
01214
01215
01216
#if !defined (_WIN64)
01217
if (
MmNumberOfPhysicalPages > ((127*1024*1024) >>
PAGE_SHIFT)) {
01218
01219 PointerPde =
MiGetPdeAddress ((PCHAR)
MmPagedPoolEnd + 1);
01220 StartingPte =
MiGetPteAddress ((PCHAR)
MmPagedPoolEnd + 1);
01221 j = 0;
01222
01223 TempPte =
ValidKernelPde;
01224
LOCK_PFN (OldIrql);
01225
while (PointerPde->
u.Hard.Valid == 0) {
01226
01227
MiChargeCommitmentCantExpand (1,
TRUE);
01228
MM_TRACK_COMMIT (
MM_DBG_COMMIT_EXTRA_SYSTEM_PTES, 1);
01229
01230 PageFrameIndex =
MiRemoveZeroPage (
01231
MI_GET_PAGE_COLOR_FROM_PTE (PointerPde));
01232 TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
01233
MI_WRITE_VALID_PTE (PointerPde, TempPte);
01234
MiInitializePfn (PageFrameIndex, PointerPde, 1);
01235 PointerPde += 1;
01236 StartingPte +=
PAGE_SIZE /
sizeof(
MMPTE);
01237 j +=
PAGE_SIZE /
sizeof(
MMPTE);
01238 }
01239
01240
UNLOCK_PFN (OldIrql);
01241
01242
if (j != 0) {
01243 StartingPte =
MiGetPteAddress ((PCHAR)
MmPagedPoolEnd + 1);
01244
MmNonPagedSystemStart =
MiGetVirtualAddressMappedByPte (StartingPte);
01245
MmNumberOfSystemPtes += j;
01246
MiAddSystemPtes (StartingPte, j,
SystemPteSpace);
01247 }
01248 }
01249
#endif
01250
01251
01252
#if DBG
01253
if (MmDebug &
MM_DBG_DUMP_BOOT_PTES) {
01254
MiDumpValidAddresses ();
01255
MiDumpPfn ();
01256 }
01257
#endif
01258
01259
MmPageFaultNotifyRoutine =
NULL;
01260
MmHardFaultNotifyRoutine =
NULL;
01261
01262
return TRUE;
01263 }
01264
01265
if (Phase == 1) {
01266
01267
#if DBG
01268
MmDebug |=
MM_DBG_CHECK_PFN_LOCK;
01269
#endif
01270
01271
#ifdef _X86_
01272
MiInitMachineDependent (LoaderBlock);
01273
#endif
01274
MiMapBBTMemory(LoaderBlock);
01275
01276
if (!
MiSectionInitialization ()) {
01277
return FALSE;
01278 }
01279
01280 Process =
PsGetCurrentProcess ();
01281
if (Process->
PhysicalVadList.Flink ==
NULL) {
01282
KeInitializeSpinLock (&Process->
AweLock);
01283 InitializeListHead (&Process->
PhysicalVadList);
01284 }
01285
01286
#if defined(MM_SHARED_USER_DATA_VA)
01287
01288
01289
01290
01291
01292 PointerPte =
MiGetPteAddress(KI_USER_SHARED_DATA);
01293
ASSERT (PointerPte->
u.Hard.Valid == 1);
01294 PageFrameIndex =
MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);
01295
01296
MI_MAKE_VALID_PTE (
MmSharedUserDataPte,
01297 PageFrameIndex,
01298
MM_READONLY,
01299 PointerPte);
01300 Pfn1 =
MI_PFN_ELEMENT (PageFrameIndex);
01301
01302
LOCK_PFN (OldIrql);
01303
01304 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
01305
01306
UNLOCK_PFN (OldIrql);
01307
#endif
01308
01309
if (
MiHydra ==
TRUE) {
01310
MiSessionWideInitializeAddresses ();
01311
MiInitializeSessionWsSupport ();
01312
MiInitializeSessionIds ();
01313 }
01314
01315
01316
01317
01318
01319
if ((MmLockPagesPercentage < 5) || (MmLockPagesPercentage >= 100)) {
01320
01321
01322
01323
01324
01325
01326
MmLockPagesLimit = (PFN_NUMBER)-1;
01327 }
01328
else {
01329
01330
01331
01332
01333
01334
MmLockPagesLimit = (PFN_NUMBER)((
MmAvailablePages *
MmLockPagesPercentage) / 100);
01335 }
01336
01337
01338
01339
01340
01341 InitializeObjectAttributes( &
ObjectAttributes,
NULL, 0,
NULL,
NULL );
01342
01343
if (!
NT_SUCCESS(
PsCreateSystemThread(
01344 &
ThreadHandle,
01345 THREAD_ALL_ACCESS,
01346 &
ObjectAttributes,
01347 0
L,
01348
NULL,
01349
MiModifiedPageWriter,
01350
NULL
01351 ))) {
01352
return FALSE;
01353 }
01354 ZwClose (
ThreadHandle);
01355
01356
01357
01358
01359
01360
01361
01362
01363
KeInitializeEvent (&
MmWorkingSetManagerEvent,
01364 SynchronizationEvent,
01365
FALSE);
01366
01367 InitializeObjectAttributes( &
ObjectAttributes,
NULL, 0,
NULL,
NULL );
01368
01369
if (!
NT_SUCCESS(
PsCreateSystemThread(
01370 &
ThreadHandle,
01371 THREAD_ALL_ACCESS,
01372 &
ObjectAttributes,
01373 0
L,
01374
NULL,
01375
KeBalanceSetManager,
01376
NULL
01377 ))) {
01378
01379
return FALSE;
01380 }
01381 ZwClose (
ThreadHandle);
01382
01383
if (!
NT_SUCCESS(
PsCreateSystemThread(
01384 &
ThreadHandle,
01385 THREAD_ALL_ACCESS,
01386 &
ObjectAttributes,
01387 0
L,
01388
NULL,
01389
KeSwapProcessOrStack,
01390
NULL
01391 ))) {
01392
01393
return FALSE;
01394 }
01395 ZwClose (
ThreadHandle);
01396
01397
#ifndef NO_POOL_CHECKS
01398
MiInitializeSpecialPoolCriteria ();
01399
#endif
01400
01401
#if defined(_X86_)
01402
MiEnableKernelVerifier ();
01403
#endif
01404
01405
ExAcquireResourceExclusive (&
PsLoadedModuleResource,
TRUE);
01406
01407 NextEntry =
PsLoadedModuleList.Flink;
01408
01409
for ( ; NextEntry != &
PsLoadedModuleList; NextEntry = NextEntry->Flink) {
01410
01411 DataTableEntry = CONTAINING_RECORD(NextEntry,
01412 LDR_DATA_TABLE_ENTRY,
01413 InLoadOrderLinks);
01414
01415 NtHeaders =
RtlImageNtHeader(DataTableEntry->DllBase);
01416
01417
if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
01418 (NtHeaders->OptionalHeader.MajorImageVersion >= 5)) {
01419 DataTableEntry->Flags |= LDRP_ENTRY_NATIVE;
01420 }
01421
01422
MiWriteProtectSystemImage (DataTableEntry->DllBase);
01423 }
01424
ExReleaseResource (&
PsLoadedModuleResource);
01425
01426 InterlockedDecrement (&
MiTrimInProgressCount);
01427
01428
return TRUE;
01429 }
01430
01431
if (Phase == 2) {
01432
MiEnablePagingTheExecutive();
01433
return TRUE;
01434 }
01435
01436
return FALSE;
01437 }
01438
01439
VOID
01440 MiMapBBTMemory (
01441 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
01442 )
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466 {
01467 PVOID Va;
01468
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
01469 PLIST_ENTRY NextMd;
01470 PFN_NUMBER NumberOfPagesMapped;
01471 PFN_NUMBER NumberOfPages;
01472 PFN_NUMBER PageFrameIndex;
01473
PMMPTE PointerPte;
01474
PMMPTE PointerPde;
01475
PMMPTE LastPde;
01476
MMPTE TempPte;
01477
01478
if (
BBTPagesToReserve <= 0) {
01479
return;
01480 }
01481
01482
01483
01484
01485
01486 NumberOfPages = (
BBTPagesToReserve + (
PTE_PER_PAGE - 1)) & ~(
PTE_PER_PAGE - 1);
01487
01488 PointerPte =
MiReserveSystemPtes((ULONG)NumberOfPages,
01489
SystemPteSpace,
01490
MM_VA_MAPPED_BY_PDE,
01491 0,
01492
FALSE);
01493
01494
if (PointerPte ==
NULL) {
01495
BBTPagesToReserve = 0;
01496
return;
01497 }
01498
01499
01500
01501
01502
01503 PointerPde =
MiGetPteAddress (PointerPte);
01504 LastPde =
MiGetPteAddress (PointerPte + NumberOfPages);
01505
01506
ASSERT (LastPde != PointerPde);
01507
01508
do {
01509 TempPte = *PointerPde;
01510 TempPte.
u.Long |=
MM_PTE_OWNER_MASK;
01511
MI_WRITE_VALID_PTE (PointerPde, TempPte);
01512 PointerPde += 1;
01513 }
while (PointerPde < LastPde);
01514
01515
KeFlushEntireTb (
TRUE,
TRUE);
01516
01517 Va =
MiGetVirtualAddressMappedByPte (PointerPte);
01518
01519 TempPte =
ValidUserPte;
01520 NumberOfPagesMapped = 0;
01521
01522 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
01523
01524
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
01525
01526 MemoryDescriptor = CONTAINING_RECORD(NextMd,
01527
MEMORY_ALLOCATION_DESCRIPTOR,
01528 ListEntry);
01529
01530
if (MemoryDescriptor->
MemoryType ==
LoaderBBTMemory) {
01531
01532 PageFrameIndex = MemoryDescriptor->
BasePage;
01533 NumberOfPages = MemoryDescriptor->
PageCount;
01534
01535
if (NumberOfPagesMapped + NumberOfPages >
BBTPagesToReserve) {
01536 NumberOfPages =
BBTPagesToReserve - NumberOfPagesMapped;
01537 }
01538
01539 NumberOfPagesMapped += NumberOfPages;
01540
01541
do {
01542
01543 TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
01544
MI_WRITE_VALID_PTE (PointerPte, TempPte);
01545
01546 PointerPte += 1;
01547 PageFrameIndex += 1;
01548 NumberOfPages -= 1;
01549 }
while (NumberOfPages);
01550
01551
if (NumberOfPagesMapped ==
BBTPagesToReserve) {
01552
break;
01553 }
01554 }
01555
01556 NextMd = MemoryDescriptor->
ListEntry.Flink;
01557 }
01558
01559 RtlZeroMemory(Va,
BBTPagesToReserve <<
PAGE_SHIFT);
01560
01561
01562
01563
01564
01565
if (NumberOfPagesMapped <
BBTPagesToReserve) {
01566
BBTPagesToReserve = (ULONG)NumberOfPagesMapped;
01567 }
01568 *(PULONG)Va =
BBTPagesToReserve;
01569
01570
01571
01572
01573
01574
01575
BBTBuffer = Va;
01576
01577
PERFINFO_MMINIT_START();
01578 }
01579
01580
01581
VOID
01582 MmInitializeMemoryLimits (
01583 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
01584 IN PBOOLEAN IncludeType,
01585 OUT
PPHYSICAL_MEMORY_DESCRIPTOR Memory
01586 )
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614 {
01615
01616
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
01617 PLIST_ENTRY NextMd;
01618 PFN_NUMBER i;
01619 PFN_NUMBER LowestFound;
01620 PFN_NUMBER Found;
01621 PFN_NUMBER Merged;
01622 PFN_NUMBER NextPage;
01623 PFN_NUMBER
TotalPages;
01624
01625
TotalPages = 0;
01626
01627
01628
01629
01630
01631 LowestFound = 0;
01632 Memory->Run[0].BasePage = 0xffffffff;
01633 NextPage = 0xffffffff;
01634 Memory->Run[0].PageCount = 0;
01635 i = 0;
01636
01637
do {
01638 Merged =
FALSE;
01639 Found =
FALSE;
01640 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
01641
01642
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
01643
01644 MemoryDescriptor = CONTAINING_RECORD(NextMd,
01645
MEMORY_ALLOCATION_DESCRIPTOR,
01646 ListEntry);
01647
01648
if (MemoryDescriptor->
MemoryType <
LoaderMaximum &&
01649 IncludeType [MemoryDescriptor->
MemoryType] ) {
01650
01651
01652
01653
01654
01655
if (MemoryDescriptor->
BasePage == NextPage) {
01656
ASSERT (MemoryDescriptor->
PageCount != 0);
01657 Memory->Run[i - 1].PageCount += MemoryDescriptor->
PageCount;
01658 NextPage += MemoryDescriptor->
PageCount;
01659
TotalPages += MemoryDescriptor->
PageCount;
01660 Merged =
TRUE;
01661 Found =
TRUE;
01662
break;
01663 }
01664
01665
if (MemoryDescriptor->
BasePage >= LowestFound) {
01666
if (Memory->Run[i].BasePage > MemoryDescriptor->
BasePage) {
01667 Memory->Run[i].BasePage = MemoryDescriptor->
BasePage;
01668 Memory->Run[i].PageCount = MemoryDescriptor->
PageCount;
01669 }
01670 Found =
TRUE;
01671 }
01672 }
01673 NextMd = MemoryDescriptor->
ListEntry.Flink;
01674 }
01675
01676
if (!Merged && Found) {
01677 NextPage = Memory->Run[i].BasePage + Memory->Run[i].PageCount;
01678
TotalPages += Memory->Run[i].PageCount;
01679 i += 1;
01680 }
01681 Memory->Run[i].BasePage = 0xffffffff;
01682 LowestFound = NextPage;
01683
01684 }
while (Found);
01685
ASSERT (i <= Memory->NumberOfRuns);
01686 Memory->NumberOfRuns = (ULONG)i;
01687 Memory->NumberOfPages =
TotalPages;
01688
01689
return;
01690 }
01691
01692
#if defined (_X86PAE_)
01693
01694
static
01695
VOID
01696 MiCheckPaeLicense (
01697 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
01698 IN PBOOLEAN IncludeType,
01699 OUT
PPHYSICAL_MEMORY_DESCRIPTOR Memory
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
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
01729 PLIST_ENTRY NextMd;
01730 PFN_NUMBER i;
01731 PFN_NUMBER LowestFound;
01732 PFN_NUMBER Found;
01733 PFN_NUMBER Merged;
01734 PFN_NUMBER NextPage;
01735 PFN_NUMBER LastPage;
01736 PFN_NUMBER MaxPage;
01737 PFN_NUMBER
TotalPages;
01738
static BOOLEAN BeenHere =
FALSE;
01739
01740
if (BeenHere ==
TRUE) {
01741
return;
01742 }
01743
01744 BeenHere =
TRUE;
01745
01746
01747
01748
01749
01750
01751
if (
ExVerifySuite(DataCenter) ==
TRUE) {
01752
01753
01754
01755
01756
01757
01758
if (LoaderBlock->u.I386.VirtualBias == 0) {
01759
01760
01761
01762
01763
01764
01765 MaxPage = 8 * 1024 * 1024;
01766 }
01767
else {
01768
01769
01770
01771
01772
01773
01774
01775 MaxPage = 4 * 1024 * 1024;
01776 }
01777 }
01778
else if ((
MmProductType != 0x00690057) &&
01779 (
ExVerifySuite(Enterprise) ==
TRUE)) {
01780
01781
01782
01783
01784
01785
01786 MaxPage = 2 * 1024 * 1024;
01787 }
01788
else {
01789
01790
01791
01792
01793
01794
01795 MaxPage = 1024 * 1024;
01796 }
01797
01798
TotalPages = 0;
01799
01800
01801
01802
01803
01804
01805 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
01806
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
01807
01808 MemoryDescriptor = CONTAINING_RECORD(NextMd,
01809
MEMORY_ALLOCATION_DESCRIPTOR,
01810 ListEntry);
01811
01812
if (MemoryDescriptor->
BasePage >= MaxPage) {
01813 MemoryDescriptor->
BasePage = 0;
01814 MemoryDescriptor->
PageCount = 0;
01815 }
01816
01817 LastPage = MemoryDescriptor->
BasePage + MemoryDescriptor->
PageCount;
01818
01819
if (LastPage >= MaxPage || LastPage < MemoryDescriptor->
BasePage) {
01820 MemoryDescriptor->
PageCount = MaxPage - MemoryDescriptor->
BasePage - 1;
01821 }
01822
01823 NextMd = MemoryDescriptor->
ListEntry.Flink;
01824 }
01825
01826
01827
01828
01829
01830
01831 LowestFound = 0;
01832 Memory->Run[0].BasePage = 0xffffffff;
01833 NextPage = 0xffffffff;
01834 Memory->Run[0].PageCount = 0;
01835 i = 0;
01836
01837
do {
01838 Merged =
FALSE;
01839 Found =
FALSE;
01840 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
01841
01842
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
01843
01844 MemoryDescriptor = CONTAINING_RECORD(NextMd,
01845
MEMORY_ALLOCATION_DESCRIPTOR,
01846 ListEntry);
01847
01848
01849
if (MemoryDescriptor->
BasePage || MemoryDescriptor->
PageCount) {
01850
01851
if (MemoryDescriptor->
MemoryType <
LoaderMaximum &&
01852 IncludeType [MemoryDescriptor->
MemoryType] ) {
01853
01854
01855
01856
01857
01858
if (MemoryDescriptor->
BasePage == NextPage) {
01859
ASSERT (MemoryDescriptor->
PageCount != 0);
01860 Memory->Run[i - 1].PageCount += MemoryDescriptor->
PageCount;
01861 NextPage += MemoryDescriptor->
PageCount;
01862
TotalPages += MemoryDescriptor->
PageCount;
01863 Merged =
TRUE;
01864 Found =
TRUE;
01865
break;
01866 }
01867
01868
if (MemoryDescriptor->
BasePage >= LowestFound) {
01869
if (Memory->Run[i].BasePage > MemoryDescriptor->
BasePage) {
01870 Memory->Run[i].BasePage = MemoryDescriptor->
BasePage;
01871 Memory->Run[i].PageCount = MemoryDescriptor->
PageCount;
01872 }
01873 Found =
TRUE;
01874 }
01875 }
01876 }
01877 NextMd = MemoryDescriptor->
ListEntry.Flink;
01878 }
01879
01880
if (!Merged && Found) {
01881 NextPage = Memory->Run[i].BasePage + Memory->Run[i].PageCount;
01882
TotalPages += Memory->Run[i].PageCount;
01883 i += 1;
01884 }
01885 Memory->Run[i].BasePage = 0xffffffff;
01886 LowestFound = NextPage;
01887
01888 }
while (Found);
01889
ASSERT (i <= Memory->NumberOfRuns);
01890 Memory->NumberOfRuns = (ULONG)i;
01891 Memory->NumberOfPages =
TotalPages;
01892
01893
return;
01894 }
01895
#endif
01896
01897
01898
VOID
01899 MiMergeMemoryLimit (
01900 IN OUT
PPHYSICAL_MEMORY_DESCRIPTOR Memory,
01901 IN PFN_NUMBER StartPage,
01902 IN PFN_NUMBER NumberOfPages
01903 )
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931 {
01932 PFN_NUMBER EndPage, sp, ep, i;
01933
01934 EndPage = StartPage + NumberOfPages;
01935
01936
01937
01938
01939
01940
for (i=0; i < Memory->NumberOfRuns; i++) {
01941 sp = Memory->Run[i].BasePage;
01942 ep = sp + Memory->Run[i].PageCount;
01943
01944
if (sp < StartPage) {
01945
if (ep > StartPage && ep < EndPage) {
01946
01947 StartPage = ep;
01948 }
01949
01950
if (ep > EndPage) {
01951
01952
01953
01954
01955
01956 StartPage = EndPage;
01957 }
01958
01959 }
else {
01960
01961
01962
if (sp < EndPage) {
01963
if (ep < EndPage) {
01964
01965
01966
01967
01968
01969
MiMergeMemoryLimit (Memory, StartPage, sp - StartPage);
01970 StartPage = ep;
01971
01972 }
else {
01973
01974 EndPage = sp;
01975 }
01976 }
01977 }
01978
01979
01980
01981
01982
01983
if (StartPage == EndPage) {
01984
return ;
01985 }
01986 }
01987
01988
01989
01990
01991
01992
if (Memory->NumberOfRuns ==
MAX_PHYSICAL_MEMORY_FRAGMENTS) {
01993
return ;
01994 }
01995
01996 Memory->Run[Memory->NumberOfRuns].BasePage = StartPage;
01997 Memory->Run[Memory->NumberOfRuns].PageCount = EndPage - StartPage;
01998 Memory->NumberOfPages += EndPage - StartPage;
01999 Memory->NumberOfRuns += 1;
02000 }
02001
02002
02003
02004
VOID
02005 MmFreeLoaderBlock (
02006 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02007 )
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030 {
02031
02032 PLIST_ENTRY NextMd;
02033
PMMPTE Pde;
02034
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
02035
MEMORY_ALLOCATION_DESCRIPTOR SavedDescriptor[
MM_MAX_LOADER_BLOCKS];
02036 PFN_NUMBER i;
02037 PFN_NUMBER NextPhysicalPage;
02038
PMMPFN Pfn1;
02039 LONG BlockNumber = -1;
02040 KIRQL OldIrql;
02041
02042
02043
02044
02045
02046
02047
02048 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
02049
02050
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
02051
02052 MemoryDescriptor = CONTAINING_RECORD(NextMd,
02053
MEMORY_ALLOCATION_DESCRIPTOR,
02054 ListEntry);
02055
02056
02057
switch (MemoryDescriptor->
MemoryType) {
02058
case LoaderOsloaderHeap:
02059
case LoaderRegistryData:
02060
case LoaderNlsData:
02061
02062
02063
02064
02065
02066
02067
02068
02069
if (BlockNumber != -1 &&
02070 MemoryDescriptor->
MemoryType == SavedDescriptor[BlockNumber].
MemoryType &&
02071 MemoryDescriptor->
BasePage == SavedDescriptor[BlockNumber].
BasePage + SavedDescriptor[BlockNumber].
PageCount) {
02072
02073
02074
02075
02076
02077 SavedDescriptor[BlockNumber].
PageCount += MemoryDescriptor->
PageCount;
02078 }
02079
else {
02080 BlockNumber += 1;
02081
if (BlockNumber >=
MM_MAX_LOADER_BLOCKS) {
02082
KeBugCheckEx (MEMORY_MANAGEMENT, 0, 0, 0, 0);
02083 }
02084 SavedDescriptor[BlockNumber] = *MemoryDescriptor;
02085 }
02086
02087
break;
02088
02089
default:
02090
02091
break;
02092 }
02093
02094 NextMd = MemoryDescriptor->
ListEntry.Flink;
02095 }
02096
02097
LOCK_PFN (OldIrql);
02098
02099
while (BlockNumber >= 0) {
02100
02101 i = SavedDescriptor[BlockNumber].
PageCount;
02102 NextPhysicalPage = SavedDescriptor[BlockNumber].BasePage;
02103
02104 Pfn1 =
MI_PFN_ELEMENT (NextPhysicalPage);
02105
while (i != 0) {
02106
02107
if (Pfn1->
u3.e2.ReferenceCount == 0) {
02108
if (Pfn1->
u1.Flink == 0) {
02109
02110
02111
02112
02113
02114
02115 Pfn1->
PteAddress =
02116 (
PMMPTE)(NextPhysicalPage <<
PTE_SHIFT);
02117
MiInsertPageInList (
MmPageLocationList[
FreePageList],
02118 NextPhysicalPage);
02119 }
02120 }
else {
02121
02122
if (NextPhysicalPage != 0) {
02123
02124
02125
02126
02127
02128
02129
if (!
MI_IS_PHYSICAL_ADDRESS (
02130
MiGetVirtualAddressMappedByPte (Pfn1->
PteAddress))) {
02131
02132
02133
02134
02135
02136 *(Pfn1->
PteAddress) =
ZeroPte;
02137 }
02138
02139
MI_SET_PFN_DELETED (Pfn1);
02140
MiDecrementShareCountOnly (NextPhysicalPage);
02141 }
02142 }
02143
02144 Pfn1++;
02145 i -= 1;
02146 NextPhysicalPage += 1;
02147 }
02148
02149 BlockNumber -= 1;
02150 }
02151
02152
02153
02154
02155
02156
02157
02158
#if defined(_X86_)
02159
02160
if (
MmVirtualBias != 0) {
02161 Pde =
MiGetPdeAddress(
KSEG0_BASE);
02162
MI_WRITE_INVALID_PTE (Pde,
ZeroKernelPte);
02163
MI_WRITE_INVALID_PTE (Pde + 1,
ZeroKernelPte);
02164
MI_WRITE_INVALID_PTE (Pde + 2,
ZeroKernelPte);
02165
MI_WRITE_INVALID_PTE (Pde + 3,
ZeroKernelPte);
02166
02167
#if defined(_X86PAE_)
02168
MI_WRITE_INVALID_PTE (Pde + 4,
ZeroKernelPte);
02169
MI_WRITE_INVALID_PTE (Pde + 5,
ZeroKernelPte);
02170
MI_WRITE_INVALID_PTE (Pde + 6,
ZeroKernelPte);
02171
MI_WRITE_INVALID_PTE (Pde + 7,
ZeroKernelPte);
02172
#endif
02173
02174 }
02175
02176
#endif
02177
02178
KeFlushEntireTb (
TRUE,
TRUE);
02179
UNLOCK_PFN (OldIrql);
02180
return;
02181 }
02182
02183
VOID
02184 MiBuildPagedPool (
02185 VOID
02186 )
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210 {
02211 SIZE_T
Size;
02212
PMMPTE PointerPte;
02213
PMMPTE PointerPde;
02214
PMMPTE PointerPpe;
02215
PMMPTE PointerPpeEnd;
02216
MMPTE TempPte;
02217
PMMPFN Pfn1;
02218 PFN_NUMBER PageFrameIndex;
02219 KIRQL OldIrql;
02220 ULONG i;
02221
02222
#if !defined (_WIN64)
02223
02224
02225
02226
02227
02228
#if defined (_X86PAE_)
02229
02230 PointerPte =
MiGetPteAddress(PDE_BASE);
02231
02232
for (i = 0 ; i < PD_PER_SYSTEM; i += 1) {
02233
MmSystemPageDirectory[i] =
MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);
02234 Pfn1 =
MI_PFN_ELEMENT(
MmSystemPageDirectory[i]);
02235 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
02236 PointerPte += 1;
02237 }
02238
02239
02240
02241
02242
02243 PointerPte =
MiReserveSystemPtes (
02244 PD_PER_SYSTEM,
02245
SystemPteSpace,
02246
MM_COLOR_ALIGNMENT,
02247 ((ULONG_PTR)PDE_BASE &
MM_COLOR_MASK_VIRTUAL),
02248
TRUE);
02249
02250
MmSystemPagePtes = (
PMMPTE)
MiGetVirtualAddressMappedByPte (PointerPte);
02251
02252 TempPte =
ValidKernelPde;
02253
02254
for (i = 0 ; i < PD_PER_SYSTEM; i += 1) {
02255 TempPte.
u.Hard.PageFrameNumber =
MmSystemPageDirectory[i];
02256
MI_WRITE_VALID_PTE (PointerPte, TempPte);
02257 PointerPte += 1;
02258 }
02259
02260
#else
02261
02262
MmSystemPageDirectory =
MI_GET_PAGE_FRAME_FROM_PTE (
MiGetPteAddress(PDE_BASE));
02263
02264 Pfn1 =
MI_PFN_ELEMENT(
MmSystemPageDirectory);
02265
02266 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
02267
02268
MmSystemPagePtes = (
PMMPTE)
MiMapPageInHyperSpace (
MmSystemPageDirectory,
02269 &OldIrql);
02270
MiUnmapPageInHyperSpace (OldIrql);
02271
02272
if (!
MI_IS_PHYSICAL_ADDRESS(
MmSystemPagePtes)) {
02273
02274
02275
02276
02277
02278 PointerPte =
MiReserveSystemPtes (
02279 1,
02280
SystemPteSpace,
02281
MM_COLOR_ALIGNMENT,
02282 ((ULONG_PTR)PDE_BASE &
MM_COLOR_MASK_VIRTUAL),
02283
TRUE);
02284 TempPte =
ValidKernelPde;
02285 TempPte.
u.Hard.PageFrameNumber =
MmSystemPageDirectory;
02286
MI_WRITE_VALID_PTE (PointerPte, TempPte);
02287
MmSystemPagePtes = (
PMMPTE)
MiGetVirtualAddressMappedByPte (PointerPte);
02288 }
02289
#endif
02290
02291
#endif
02292
02293
if (
MmPagedPoolMaximumDesired ==
TRUE) {
02294
MmSizeOfPagedPoolInBytes =
02295 ((PCHAR)
MmNonPagedSystemStart - (PCHAR)
MmPagedPoolStart);
02296 }
02297
02298
02299
02300
02301
02302
if (
MmSizeOfPagedPoolInBytes == 0) {
02303
MmSizeOfPagedPoolInBytes = 2 *
MmMaximumNonPagedPoolInBytes;
02304 }
02305
02306
if (
MmIsThisAnNtAsSystem()) {
02307
if ((
MmNumberOfPhysicalPages > ((24*1024*1024) >>
PAGE_SHIFT)) &&
02308 (
MmSizeOfPagedPoolInBytes <
MM_MINIMUM_PAGED_POOL_NTAS)) {
02309
02310
MmSizeOfPagedPoolInBytes =
MM_MINIMUM_PAGED_POOL_NTAS;
02311 }
02312 }
02313
02314
if (
MmSizeOfPagedPoolInBytes >
02315 (ULONG_PTR)((PCHAR)
MmNonPagedSystemStart - (PCHAR)
MmPagedPoolStart)) {
02316
MmSizeOfPagedPoolInBytes =
02317 ((PCHAR)
MmNonPagedSystemStart - (PCHAR)
MmPagedPoolStart);
02318 }
02319
02320
Size =
BYTES_TO_PAGES(
MmSizeOfPagedPoolInBytes);
02321
02322
if (
Size <
MM_MIN_INITIAL_PAGED_POOL) {
02323
Size =
MM_MIN_INITIAL_PAGED_POOL;
02324 }
02325
02326
if (
Size > (
MM_MAX_PAGED_POOL >>
PAGE_SHIFT)) {
02327
Size =
MM_MAX_PAGED_POOL >>
PAGE_SHIFT;
02328 }
02329
02330
Size = (
Size + (
PTE_PER_PAGE - 1)) /
PTE_PER_PAGE;
02331
MmSizeOfPagedPoolInBytes = (ULONG_PTR)
Size *
PAGE_SIZE *
PTE_PER_PAGE;
02332
02333
ASSERT ((
MmSizeOfPagedPoolInBytes + (PCHAR)
MmPagedPoolStart) <=
02334 (PCHAR)
MmNonPagedSystemStart);
02335
02336
02337
02338
02339
02340
Size =
Size *
PTE_PER_PAGE;
02341
02342
MmPagedPoolEnd = (PVOID)(((PUCHAR)
MmPagedPoolStart +
02343
MmSizeOfPagedPoolInBytes) - 1);
02344
02345
MmPageAlignedPoolBase[
PagedPool] =
MmPagedPoolStart;
02346
02347
02348
02349
02350
02351 PointerPde =
MiGetPdeAddress (
MmPagedPoolStart);
02352
MmPagedPoolBasePde = PointerPde;
02353
02354 TempPte =
ValidKernelPde;
02355
02356
#if defined (_WIN64)
02357
02358
02359
02360
02361
02362
02363 PointerPpe =
MiGetPpeAddress (
MmPagedPoolStart);
02364 PointerPpeEnd =
MiGetPpeAddress (
MmPagedPoolEnd);
02365
02366
while (PointerPpe <= PointerPpeEnd) {
02367
02368
if (PointerPpe->
u.Hard.Valid == 0) {
02369 PageFrameIndex =
MiRemoveAnyPage(
02370
MI_GET_PAGE_COLOR_FROM_PTE (PointerPpe));
02371 TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
02372 *PointerPpe = TempPte;
02373
02374 Pfn1 =
MI_PFN_ELEMENT(PageFrameIndex);
02375 Pfn1->
PteFrame =
MI_GET_PAGE_FRAME_FROM_PTE (
02376
MiGetPteAddress(
PDE_KTBASE));
02377 Pfn1->
PteAddress = PointerPpe;
02378 Pfn1->
u2.ShareCount = 1;
02379 Pfn1->
u3.e2.ReferenceCount = 1;
02380 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
02381 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
02382 }
02383
02384 PointerPpe += 1;
02385 }
02386
02387
#endif
02388
02389 PointerPte =
MiGetPteAddress (
MmPagedPoolStart);
02390
MmPagedPoolInfo.FirstPteForPagedPool = PointerPte;
02391
MmPagedPoolInfo.LastPteForPagedPool =
MiGetPteAddress (
MmPagedPoolEnd);
02392
02393
MiFillMemoryPte (PointerPde,
02394
sizeof(
MMPTE) *
02395 (1 +
MiGetPdeAddress (
MmPagedPoolEnd) - PointerPde),
02396
MM_KERNEL_NOACCESS_PTE);
02397
02398
LOCK_PFN (OldIrql);
02399
02400
02401
02402
02403
02404 PageFrameIndex =
MiRemoveAnyPage(
02405
MI_GET_PAGE_COLOR_FROM_PTE (PointerPde));
02406 TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
02407
MI_WRITE_VALID_PTE (PointerPde, TempPte);
02408
02409 Pfn1 =
MI_PFN_ELEMENT(PageFrameIndex);
02410
#if defined (_WIN64)
02411
Pfn1->
PteFrame =
MI_GET_PAGE_FRAME_FROM_PTE(
MiGetPpeAddress (
MmPagedPoolStart));
02412
#else
02413
#if !defined (_X86PAE_)
02414
Pfn1->
PteFrame =
MmSystemPageDirectory;
02415
#else
02416
Pfn1->
PteFrame =
MmSystemPageDirectory[(PointerPde -
MiGetPdeAddress(0)) /
PDE_PER_PAGE];
02417
#endif
02418
#endif
02419
Pfn1->
PteAddress = PointerPde;
02420 Pfn1->
u2.ShareCount = 1;
02421 Pfn1->
u3.e2.ReferenceCount = 1;
02422 Pfn1->
u3.e1.PageLocation =
ActiveAndValid;
02423 Pfn1->
OriginalPte.
u.Long =
MM_DEMAND_ZERO_WRITE_PTE;
02424
MiFillMemoryPte (PointerPte,
PAGE_SIZE,
MM_KERNEL_NOACCESS_PTE);
02425
02426
UNLOCK_PFN (OldIrql);
02427
02428
MmPagedPoolInfo.NextPdeForPagedPoolExpansion = PointerPde + 1;
02429
02430
02431
02432
02433
02434
MiCreateBitMap (&
MmPagedPoolInfo.PagedPoolAllocationMap,
Size,
NonPagedPool);
02435
RtlSetAllBits (
MmPagedPoolInfo.PagedPoolAllocationMap);
02436
02437
02438
02439
02440
02441
RtlClearBits (
MmPagedPoolInfo.PagedPoolAllocationMap, 0,
PTE_PER_PAGE);
02442
02443
MiCreateBitMap (&
MmPagedPoolInfo.EndOfPagedPoolBitmap,
Size,
NonPagedPool);
02444
RtlClearAllBits (
MmPagedPoolInfo.EndOfPagedPoolBitmap);
02445
02446
02447
02448
02449
02450
if (
MmVerifyDriverBufferLength != (ULONG)-1) {
02451
MiCreateBitMap (&
VerifierLargePagedPoolMap,
Size,
NonPagedPool);
02452
RtlClearAllBits (
VerifierLargePagedPoolMap);
02453 }
02454
02455
02456
02457
02458
02459
InitializePool (
PagedPool, 0
L);
02460
02461
MiInitializeSpecialPool();
02462
02463
02464
02465
02466
02467
MiInitializeSystemSpaceMap ((PVOID)0);
02468
02469
return;
02470 }
02471
02472
02473
VOID
02474 MiFindInitializationCode (
02475 OUT PVOID *StartVa,
02476 OUT PVOID *EndVa
02477 )
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502 {
02503 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
02504 PVOID CurrentBase;
02505 PVOID InitStart;
02506 PVOID InitEnd;
02507 PLIST_ENTRY Next;
02508 PIMAGE_NT_HEADERS NtHeader;
02509 PIMAGE_SECTION_HEADER SectionTableEntry;
02510 PIMAGE_SECTION_HEADER LastDiscard;
02511 LONG i;
02512 PVOID MiFindInitializationCodeAddress;
02513
02514 MiFindInitializationCodeAddress = MmGetProcedureAddress((PVOID)&
MiFindInitializationCode);
02515
02516 *StartVa =
NULL;
02517
02518
02519
02520
02521
02522
02523
KeEnterCriticalRegion();
02524
ExAcquireResourceExclusive (&
PsLoadedModuleResource,
TRUE);
02525 Next =
PsLoadedModuleList.Flink;
02526
02527
while ( Next != &
PsLoadedModuleList ) {
02528 LdrDataTableEntry = CONTAINING_RECORD( Next,
02529 LDR_DATA_TABLE_ENTRY,
02530 InLoadOrderLinks
02531 );
02532
if (LdrDataTableEntry->SectionPointer !=
NULL) {
02533
02534
02535
02536
02537
02538
02539 Next = Next->Flink;
02540
continue;
02541 }
02542
02543 CurrentBase = (PVOID)LdrDataTableEntry->DllBase;
02544 NtHeader =
RtlImageNtHeader(CurrentBase);
02545
02546 SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeader +
02547
sizeof(ULONG) +
02548
sizeof(IMAGE_FILE_HEADER) +
02549 NtHeader->FileHeader.SizeOfOptionalHeader);
02550
02551
02552
02553
02554
02555 i = NtHeader->FileHeader.NumberOfSections;
02556
02557 InitStart =
NULL;
02558
while (i > 0) {
02559
02560
#if DBG
02561
if ((*(PULONG)SectionTableEntry->Name == 'tini') ||
02562 (*(PULONG)SectionTableEntry->Name == 'egap')) {
02563
DbgPrint(
"driver %wZ has lower case sections (init or pagexxx)\n",
02564 &LdrDataTableEntry->FullDllName);
02565 }
02566
#endif //DBG
02567
02568
02569
02570
02571
02572
02573
02574
if ((*(PULONG)SectionTableEntry->Name == 'TINI') ||
02575 ((SectionTableEntry->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)) {
02576
02577
02578 InitStart = (PVOID)((PCHAR)CurrentBase + SectionTableEntry->VirtualAddress);
02579 InitEnd = (PVOID)((PCHAR)InitStart + SectionTableEntry->SizeOfRawData - 1);
02580 InitEnd = (PVOID)((PCHAR)
PAGE_ALIGN ((PCHAR)InitEnd +
02581 (NtHeader->OptionalHeader.SectionAlignment - 1)) - 1);
02582 InitStart = (PVOID)
ROUND_TO_PAGES (InitStart);
02583
02584
02585
02586
02587
02588
02589
if (i == 1) {
02590 LastDiscard = SectionTableEntry;
02591 }
02592
else {
02593 LastDiscard =
NULL;
02594
do {
02595 i -= 1;
02596 SectionTableEntry += 1;
02597
02598
if ((SectionTableEntry->Characteristics &
02599 IMAGE_SCN_MEM_DISCARDABLE) != 0) {
02600
02601
02602
02603
02604
02605 LastDiscard = SectionTableEntry;
02606 }
else {
02607
break;
02608 }
02609 }
while (i > 1);
02610 }
02611
02612
if (LastDiscard) {
02613 InitEnd = (PVOID)(((PCHAR)CurrentBase +
02614 LastDiscard->VirtualAddress) +
02615 (LastDiscard->SizeOfRawData - 1));
02616
02617
02618
02619
02620
02621
02622
02623
if (i != 1) {
02624 InitEnd = (PVOID)((PCHAR)
PAGE_ALIGN ((PCHAR)InitEnd +
02625 (NtHeader->OptionalHeader.SectionAlignment - 1)) - 1);
02626 }
02627 }
02628
02629
if (InitEnd > (PVOID)((PCHAR)CurrentBase +
02630 LdrDataTableEntry->SizeOfImage)) {
02631 InitEnd = (PVOID)(((ULONG_PTR)CurrentBase +
02632 (LdrDataTableEntry->SizeOfImage - 1)) |
02633 (
PAGE_SIZE - 1));
02634 }
02635
02636
if (InitStart <= InitEnd) {
02637
if ((MiFindInitializationCodeAddress >= InitStart) &&
02638 (MiFindInitializationCodeAddress <= InitEnd)) {
02639
02640
02641
02642
02643
02644
02645 *StartVa = InitStart;
02646 *EndVa = InitEnd;
02647 }
02648
else {
02649
MiFreeInitializationCode (InitStart, InitEnd);
02650 }
02651 }
02652 }
02653 i -= 1;
02654 SectionTableEntry += 1;
02655 }
02656 Next = Next->Flink;
02657 }
02658
ExReleaseResource (&
PsLoadedModuleResource);
02659
KeLeaveCriticalRegion();
02660
return;
02661 }
02662
02663
VOID
02664 MiFreeInitializationCode (
02665 IN PVOID StartVa,
02666 IN PVOID EndVa
02667 )
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691 {
02692
PMMPFN Pfn1;
02693
PMMPTE PointerPte;
02694 PFN_NUMBER PageFrameIndex;
02695 KIRQL OldIrql;
02696 PVOID UnlockHandle;
02697
02698 UnlockHandle = MmLockPagableCodeSection((PVOID)
MiFreeInitializationCode);
02699
ASSERT(UnlockHandle);
02700
02701
if (
MI_IS_PHYSICAL_ADDRESS(StartVa)) {
02702
LOCK_PFN (OldIrql);
02703
while (StartVa < EndVa) {
02704
02705
02706
02707
02708
02709
02710 PageFrameIndex =
MI_CONVERT_PHYSICAL_TO_PFN (StartVa);
02711
02712 Pfn1 =
MI_PFN_ELEMENT (PageFrameIndex);
02713 Pfn1->
u2.ShareCount = 0;
02714 Pfn1->
u3.e2.ReferenceCount = 0;
02715
MI_SET_PFN_DELETED (Pfn1);
02716
MiInsertPageInList (
MmPageLocationList[
FreePageList], PageFrameIndex);
02717 StartVa = (PVOID)((PUCHAR)StartVa +
PAGE_SIZE);
02718 }
02719
UNLOCK_PFN (OldIrql);
02720 }
else {
02721 PointerPte =
MiGetPteAddress (StartVa);
02722
MiDeleteSystemPagableVm (PointerPte,
02723 (PFN_NUMBER) (1 +
MiGetPteAddress (EndVa) -
02724 PointerPte),
02725
ZeroKernelPte,
02726
FALSE,
02727
NULL);
02728 }
02729
MmUnlockPagableImageSection(UnlockHandle);
02730
return;
02731 }
02732
02733
02734
VOID
02735 MiEnablePagingTheExecutive (
02736 VOID
02737 )
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762 {
02763 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
02764 PVOID CurrentBase;
02765 PLIST_ENTRY Next;
02766 PIMAGE_NT_HEADERS NtHeader;
02767 PIMAGE_SECTION_HEADER SectionTableEntry;
02768 LONG i;
02769
PMMPTE PointerPte;
02770
PMMPTE LastPte;
02771 BOOLEAN PageSection;
02772 PVOID SectionBaseAddress;
02773
02774
02775
02776
02777
02778
02779
if (
MmDisablePagingExecutive
02780
#if defined(REMOTE_BOOT)
02781
|| (
IoRemoteBootClient && IoCscInitializationFailed)
02782
#endif
02783
) {
02784
return;
02785 }
02786
02787
02788
02789
02790
02791
02792
KeEnterCriticalRegion();
02793
ExAcquireResourceExclusive (&
PsLoadedModuleResource,
TRUE);
02794 Next =
PsLoadedModuleList.Flink;
02795
while ( Next != &
PsLoadedModuleList ) {
02796 LdrDataTableEntry = CONTAINING_RECORD( Next,
02797 LDR_DATA_TABLE_ENTRY,
02798 InLoadOrderLinks
02799 );
02800
if (LdrDataTableEntry->SectionPointer !=
NULL) {
02801
02802
02803
02804
02805
02806 Next = Next->Flink;
02807
continue;
02808 }
02809
02810 CurrentBase = (PVOID)LdrDataTableEntry->DllBase;
02811 NtHeader =
RtlImageNtHeader(CurrentBase);
02812
02813 SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeader +
02814
sizeof(ULONG) +
02815
sizeof(IMAGE_FILE_HEADER) +
02816 NtHeader->FileHeader.SizeOfOptionalHeader);
02817
02818
02819
02820
02821
02822
02823 i = NtHeader->FileHeader.NumberOfSections;
02824
02825 PointerPte =
NULL;
02826
02827
while (i > 0) {
02828
02829
if (
MI_IS_PHYSICAL_ADDRESS (CurrentBase)) {
02830
02831
02832
02833
02834
02835
break;
02836 }
02837
02838 SectionBaseAddress =
SECTION_BASE_ADDRESS(SectionTableEntry);
02839
02840 PageSection = ((*(PULONG)SectionTableEntry->Name == 'EGAP') ||
02841 (*(PULONG)SectionTableEntry->Name == 'ade.')) &&
02842 (SectionBaseAddress !=
02843 ((PUCHAR)CurrentBase + SectionTableEntry->VirtualAddress));
02844
02845
if (*(PULONG)SectionTableEntry->Name == 'EGAP' &&
02846 SectionTableEntry->Name[4] ==
'K' &&
02847 SectionTableEntry->Name[5] ==
'D') {
02848
02849
02850
02851
02852
02853 PageSection =
KdPitchDebugger;
02854 }
02855
02856
if ((*(PULONG)SectionTableEntry->Name == 'EGAP') &&
02857 (*(PULONG)&SectionTableEntry->Name[4] == 'RDYH')) {
02858
02859
02860
02861
02862
02863
if (
MiHydra ==
TRUE) {
02864 PageSection =
FALSE;
02865 }
02866 }
02867
02868
if ((*(PULONG)SectionTableEntry->Name == 'EGAP') &&
02869 (*(PULONG)&SectionTableEntry->Name[4] == 'YFRV')) {
02870
02871
02872
02873
02874
02875
if (
MmVerifyDriverBufferLength != (ULONG)-1) {
02876 PageSection =
FALSE;
02877 }
02878 }
02879
02880
if ((*(PULONG)SectionTableEntry->Name == 'EGAP') &&
02881 (*(PULONG)&SectionTableEntry->Name[4] == 'CEPS')) {
02882
02883
02884
02885
02886
02887
if (
MiSpecialPoolPtes != 0) {
02888 PageSection =
FALSE;
02889 }
02890 }
02891
02892
if (PageSection) {
02893
02894
02895
02896
02897
if (PointerPte ==
NULL) {
02898
02899
02900
02901
02902
02903 PointerPte =
MiGetPteAddress (
ROUND_TO_PAGES (
02904 (ULONG_PTR)CurrentBase +
02905 SectionTableEntry->VirtualAddress));
02906 }
02907 LastPte =
MiGetPteAddress ((ULONG_PTR)CurrentBase +
02908 SectionTableEntry->VirtualAddress +
02909 (NtHeader->OptionalHeader.SectionAlignment - 1) +
02910 SectionTableEntry->SizeOfRawData -
02911
PAGE_SIZE);
02912
02913 }
else {
02914
02915
02916
02917
02918
02919
02920
if (PointerPte !=
NULL) {
02921
MiEnablePagingOfDriverAtInit (PointerPte, LastPte);
02922 PointerPte =
NULL;
02923 }
02924 }
02925 i -= 1;
02926 SectionTableEntry += 1;
02927 }
02928
02929
if (PointerPte !=
NULL) {
02930
MiEnablePagingOfDriverAtInit (PointerPte, LastPte);
02931 }
02932
02933 Next = Next->Flink;
02934 }
02935
02936
ExReleaseResource (&
PsLoadedModuleResource);
02937
KeLeaveCriticalRegion();
02938
02939
return;
02940 }
02941
02942
02943
VOID
02944 MiEnablePagingOfDriverAtInit (
02945 IN
PMMPTE PointerPte,
02946 IN
PMMPTE LastPte
02947 )
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967 {
02968 PVOID Base;
02969 PFN_NUMBER PageFrameIndex;
02970
PMMPFN Pfn;
02971
MMPTE TempPte;
02972 KIRQL OldIrql;
02973 KIRQL OldIrqlWs;
02974 LOGICAL SessionAddress;
02975
02976 Base =
MiGetVirtualAddressMappedByPte (PointerPte);
02977 SessionAddress =
MI_IS_SESSION_PTE (PointerPte);
02978
02979
LOCK_SYSTEM_WS (OldIrqlWs);
02980
LOCK_PFN (OldIrql);
02981
02982
while (PointerPte <= LastPte) {
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
if (PointerPte->u.Hard.Valid == 1) {
02993 PageFrameIndex =
MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);
02994 Pfn =
MI_PFN_ELEMENT (PageFrameIndex);
02995
ASSERT (Pfn->
u2.ShareCount == 1);
02996
02997
if (Pfn->
u1.WsIndex == 0) {
02998
02999
03000
03001
03002
03003
03004
MI_ZERO_WSINDEX (Pfn);
03005
03006
03007
03008
03009
03010
03011
if (Pfn->
OriginalPte.
u.Long == 0) {
03012 Pfn->
OriginalPte.
u.Long =
MM_KERNEL_DEMAND_ZERO_PTE;
03013
#if defined(_IA64_)
03014
Pfn->
OriginalPte.
u.Soft.Protection |=
MM_EXECUTE;
03015
#endif
03016
}
03017
03018 Pfn->
u3.e1.Modified = 1;
03019 TempPte = *PointerPte;
03020
03021
MI_MAKE_VALID_PTE_TRANSITION (TempPte,
03022 Pfn->
OriginalPte.
u.Soft.Protection);
03023
03024
KeFlushSingleTb (Base,
03025
TRUE,
03026
TRUE,
03027 (PHARDWARE_PTE)PointerPte,
03028 TempPte.
u.Flush);
03029
03030
03031
03032
03033
03034
03035
03036
03037
MiDecrementShareCount (PageFrameIndex);
03038
03039
MmResidentAvailablePages += 1;
03040
MmTotalSystemCodePages += 1;
03041 }
03042
else {
03043
03044
03045
03046
03047
03048
03049 }
03050
03051 }
03052 Base = (PVOID)((PCHAR)Base +
PAGE_SIZE);
03053 PointerPte += 1;
03054 }
03055
03056
UNLOCK_PFN (OldIrql);
03057
UNLOCK_SYSTEM_WS (OldIrqlWs);
03058
03059
if (SessionAddress ==
TRUE) {
03060
03061
03062
03063
03064
03065
MI_FLUSH_ENTIRE_SESSION_TB (
TRUE,
TRUE);
03066 }
03067
03068
return;
03069 }
03070
03071
03072
MM_SYSTEMSIZE
03073 MmQuerySystemSize(
03074 VOID
03075 )
03076 {
03077
03078
03079
03080
03081
03082
return MmSystemSize;
03083 }
03084
03085
NTKERNELAPI
03086 BOOLEAN
03087 MmIsThisAnNtAsSystem(
03088 VOID
03089 )
03090 {
03091
return (BOOLEAN)
MmProductType;
03092 }
03093
03094
NTKERNELAPI
03095
VOID
03096
FASTCALL
03097 MmSetPageFaultNotifyRoutine(
03098 PPAGE_FAULT_NOTIFY_ROUTINE NotifyRoutine
03099 )
03100 {
03101
MmPageFaultNotifyRoutine = NotifyRoutine;
03102 }
03103
03104
NTKERNELAPI
03105
VOID
03106
FASTCALL
03107 MmSetHardFaultNotifyRoutine(
03108 PHARD_FAULT_NOTIFY_ROUTINE NotifyRoutine
03109 )
03110 {
03111
MmHardFaultNotifyRoutine = NotifyRoutine;
03112 }