00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#ifndef _MI_
00024
#define _MI_
00025
00026
#include "ntos.h"
00027
#include "ntimage.h"
00028
#include "ki.h"
00029
#include "fsrtl.h"
00030
#include "zwapi.h"
00031
#include "pool.h"
00032
#include "ntiodump.h"
00033
#include "stdio.h"
00034
#include "string.h"
00035
#include "safeboot.h"
00036
#include "triage.h"
00037
00038
#if defined(_X86_)
00039
#include "..\mm\i386\mi386.h"
00040
00041
#elif defined(_AXP64_)
00042
#include "..\mm\axp64\mialpha.h"
00043
00044
#elif defined(_ALPHA_)
00045
#include "..\mm\alpha\mialpha.h"
00046
00047
#elif defined(_IA64_)
00048
#include "..\mm\ia64\miia64.h"
00049
00050
#else
00051
#error "mm: a target architecture must be defined."
00052
#endif
00053
00054
#if defined (_WIN64)
00055
#define ASSERT32(exp)
00056
#define ASSERT64(exp) ASSERT(exp)
00057
#else
00058 #define ASSERT32(exp) ASSERT(exp)
00059 #define ASSERT64(exp)
00060
#endif
00061
00062
00063
00064
00065 #define MI_SPECIAL_POOL_PAGABLE 0x8000
00066 #define MI_SPECIAL_POOL_VERIFIER 0x4000
00067 #define MI_SPECIAL_POOL_PTE_PAGABLE 0x0002
00068 #define MI_SPECIAL_POOL_PTE_NONPAGABLE 0x0004
00069
00070
00071 #define _2gb 0x80000000 // 2 gigabytes
00072 #define _4gb 0x100000000 // 4 gigabytes
00073
00074 #define MM_FLUSH_COUNTER_MASK (0xFFFFF)
00075
00076 #define MM_FREE_WSLE_SHIFT 4
00077
00078 #define WSLE_NULL_INDEX ((ULONG)0xFFFFFFF)
00079
00080 #define MM_FREE_POOL_SIGNATURE (0x50554F4C)
00081
00082 #define MM_MINIMUM_PAGED_POOL_NTAS ((SIZE_T)(48*1024*1024))
00083
00084 #define MM_ALLOCATION_FILLS_VAD ((PMMPTE)(ULONG_PTR)~3)
00085
00086 #define MM_WORKING_SET_LIST_SEARCH 17
00087
00088 #define MM_FLUID_WORKING_SET 8
00089
00090 #define MM_FLUID_PHYSICAL_PAGES 32 //see MmResidentPages below.
00091
00092 #define MM_USABLE_PAGES_FREE 32
00093
00094 #define X64K (ULONG)65536
00095
00096 #define MM_HIGHEST_VAD_ADDRESS ((PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (64 * 1024)))
00097
00098
00099 #define MM_NO_WS_EXPANSION ((PLIST_ENTRY)0)
00100 #define MM_WS_EXPANSION_IN_PROGRESS ((PLIST_ENTRY)35)
00101 #define MM_WS_SWAPPED_OUT ((PLIST_ENTRY)37)
00102 #define MM_IO_IN_PROGRESS ((PLIST_ENTRY)97) // MUST HAVE THE HIGHEST VALUE
00103
00104 #define MM_PAGES_REQUIRED_FOR_MAPPED_IO 7
00105
00106 #define MM4K_SHIFT 12 //MUST BE LESS THAN OR EQUAL TO PAGE_SHIFT
00107 #define MM4K_MASK 0xfff
00108
00109 #define MMSECTOR_SHIFT 9 //MUST BE LESS THAN OR EQUAL TO PAGE_SHIFT
00110
00111 #define MMSECTOR_MASK 0x1ff
00112
00113 #define MM_LOCK_BY_REFCOUNT 0
00114
00115 #define MM_LOCK_BY_NONPAGE 1
00116
00117 #define MM_FORCE_TRIM 6
00118
00119 #define MM_GROW_WSLE_HASH 20
00120
00121 #define MM_MAXIMUM_WRITE_CLUSTER (MM_MAXIMUM_DISK_IO_SIZE / PAGE_SIZE)
00122
00123
00124
00125
00126
00127 #define MM_MAXIMUM_FLUSH_COUNT (FLUSH_MULTIPLE_MAXIMUM-1)
00128
00129
00130
00131
00132
00133 #define MM_ZERO_ACCESS 0 // this value is not used.
00134 #define MM_READONLY 1
00135 #define MM_EXECUTE 2
00136 #define MM_EXECUTE_READ 3
00137 #define MM_READWRITE 4 // bit 2 is set if this is writable.
00138 #define MM_WRITECOPY 5
00139 #define MM_EXECUTE_READWRITE 6
00140 #define MM_EXECUTE_WRITECOPY 7
00141
00142 #define MM_NOCACHE 0x8
00143 #define MM_GUARD_PAGE 0x10
00144 #define MM_DECOMMIT 0x10 //NO_ACCESS, Guard page
00145 #define MM_NOACCESS 0x18 //NO_ACCESS, Guard_page, nocache.
00146 #define MM_UNKNOWN_PROTECTION 0x100 //bigger than 5 bits!
00147 #define MM_LARGE_PAGES 0x111
00148
00149 #define PROTECT_KSTACKS 1
00150
00151 #define MM_KSTACK_OUTSWAPPED 0x1F //Debug marking for kernel stacks
00152
00153 #define MM_PROTECTION_WRITE_MASK 4
00154 #define MM_PROTECTION_COPY_MASK 1
00155 #define MM_PROTECTION_OPERATION_MASK 7 // mask off guard page and nocache.
00156 #define MM_PROTECTION_EXECUTE_MASK 2
00157
00158 #define MM_SECURE_DELETE_CHECK 0x55
00159
00160
00161
00162
00163
00164 #define MM_DBG_WRITEFAULT 0x1
00165 #define MM_DBG_PTE_UPDATE 0x2
00166 #define MM_DBG_DUMP_WSL 0x4
00167 #define MM_DBG_PAGEFAULT 0x8
00168 #define MM_DBG_WS_EXPANSION 0x10
00169 #define MM_DBG_MOD_WRITE 0x20
00170 #define MM_DBG_CHECK_PTE 0x40
00171 #define MM_DBG_VAD_CONFLICT 0x80
00172 #define MM_DBG_SECTIONS 0x100
00173 #define MM_DBG_SYS_PTES 0x400
00174 #define MM_DBG_CLEAN_PROCESS 0x800
00175 #define MM_DBG_COLLIDED_PAGE 0x1000
00176 #define MM_DBG_DUMP_BOOT_PTES 0x2000
00177 #define MM_DBG_FORK 0x4000
00178 #define MM_DBG_DIR_BASE 0x8000
00179 #define MM_DBG_FLUSH_SECTION 0x10000
00180 #define MM_DBG_PRINTS_MODWRITES 0x20000
00181 #define MM_DBG_PAGE_IN_LIST 0x40000
00182 #define MM_DBG_CHECK_PFN_LOCK 0x80000
00183 #define MM_DBG_PRIVATE_PAGES 0x100000
00184 #define MM_DBG_WALK_VAD_TREE 0x200000
00185 #define MM_DBG_SWAP_PROCESS 0x400000
00186 #define MM_DBG_LOCK_CODE 0x800000
00187 #define MM_DBG_STOP_ON_ACCVIO 0x1000000
00188 #define MM_DBG_PAGE_REF_COUNT 0x2000000
00189 #define MM_DBG_SHOW_NT_CALLS 0x10000000
00190 #define MM_DBG_SHOW_FAULTS 0x40000000
00191 #define MM_DBG_SESSIONS 0x80000000
00192
00193
00194
00195
00196
00197
00198 #define MM_COPY_ON_WRITE_MASK 5
00199
00200 extern ULONG
MmProtectToValue[32];
00201 extern ULONG
MmProtectToPteMask[32];
00202 extern ULONG
MmMakeProtectNotWriteCopy[32];
00203 extern ACCESS_MASK
MmMakeSectionAccess[8];
00204 extern ACCESS_MASK
MmMakeFileAccess[8];
00205
00206
00207
00208
00209
00210
00211 extern LARGE_INTEGER
MmSevenMinutes;
00212 extern LARGE_INTEGER
MmWorkingSetProtectionTime;
00213 extern LARGE_INTEGER
MmOneSecond;
00214 extern LARGE_INTEGER
MmTwentySeconds;
00215 extern LARGE_INTEGER
MmShortTime;
00216 extern LARGE_INTEGER
MmHalfSecond;
00217 extern LARGE_INTEGER
Mm30Milliseconds;
00218 extern LARGE_INTEGER
MmCriticalSectionTimeout;
00219
00220
00221
00222
00223
00224 extern ULONG
MmCritsectTimeoutSeconds;
00225
00226
00227
00228
00229
00230 extern PEPROCESS ExpDefaultErrorPortProcess;
00231
00232 extern SIZE_T
MmExtendedCommit;
00233
00234
00235
00236
00237
00238 extern PFN_NUMBER
MmHiberPages;
00239
00240
00241
00242
00243
00244
00245 extern ULONG
MiIoRetryLevel;
00246 extern ULONG
MiFaultRetries;
00247 extern ULONG
MiUserIoRetryLevel;
00248 extern ULONG
MiUserFaultRetries;
00249
00250 #define MmIsRetryIoStatus(S) (((S) == STATUS_INSUFFICIENT_RESOURCES) || \
00251
((S) == STATUS_WORKING_SET_QUOTA) || \
00252
((S) == STATUS_NO_MEMORY))
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 #define MI_CONVERT_FROM_PTE_PROTECTION(PROTECTION_MASK) \
00275
(MmProtectToValue[PROTECTION_MASK])
00276
00277 #define MI_MASK_TO_PTE(PROTECTION_MASK) MmProtectToPteMask[PROTECTION_MASK]
00278
00279
00280 #define MI_IS_PTE_PROTECTION_COPY_WRITE(PROTECTION_MASK) \
00281
(((PROTECTION_MASK) & MM_COPY_ON_WRITE_MASK) == MM_COPY_ON_WRITE_MASK)
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 #define MI_ROUND_TO_64K(LENGTH) (((LENGTH) + X64K - 1) & ~(X64K - 1))
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 #define MI_ROUND_TO_SIZE(LENGTH,ALIGNMENT) \
00335
(((LENGTH) + ((ALIGNMENT) - 1)) & ~((ALIGNMENT) - 1))
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 #define MI_64K_ALIGN(VA) ((PVOID)((ULONG_PTR)(VA) & ~((LONG)X64K - 1)))
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 #define MI_ALIGN_TO_SIZE(VA,ALIGNMENT) ((PVOID)((ULONG_PTR)(VA) & ~((ULONG_PTR) ALIGNMENT - 1)))
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 #define MI_STARTING_OFFSET(SUBSECT,PTE) \
00418
(((LONGLONG)((ULONG_PTR)((PTE) - ((SUBSECT)->SubsectionBase))) << PAGE_SHIFT) + \
00419
((LONGLONG)((SUBSECT)->StartingSector) << MMSECTOR_SHIFT));
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 #define MiFindEmptyAddressRangeDown(SizeOfRange,HighestAddressToEndAt,Alignment) \
00452
(MiFindEmptyAddressRangeDownTree( \
00453
(SizeOfRange), \
00454
(HighestAddressToEndAt), \
00455
(Alignment), \
00456
(PMMADDRESS_NODE)(PsGetCurrentProcess()->VadRoot)))
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 #define MiGetPreviousVad(VAD) ((PMMVAD)MiGetPreviousNode((PMMADDRESS_NODE)(VAD)))
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 #define MiGetNextVad(VAD) ((PMMVAD)MiGetNextNode((PMMADDRESS_NODE)(VAD)))
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 #define MiGetFirstVad(Process) \
00527
((PMMVAD)MiGetFirstNode((PMMADDRESS_NODE)(Process->VadRoot)))
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 #define MiCheckForConflictingVad(StartingAddress,EndingAddress) \
00557
((PMMVAD)MiCheckForConflictingNode( \
00558
MI_VA_TO_VPN(StartingAddress), \
00559
MI_VA_TO_VPN(EndingAddress), \
00560
(PMMADDRESS_NODE)(PsGetCurrentProcess()->VadRoot)))
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 #define MiGetNextClone(CLONE) \
00584
((PMMCLONE_DESCRIPTOR)MiGetNextNode((PMMADDRESS_NODE)(CLONE)))
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 #define MiGetPreviousClone(CLONE) \
00610
((PMMCLONE_DESCRIPTOR)MiGetPreviousNode((PMMADDRESS_NODE)(CLONE)))
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 #define MiGetFirstClone() \
00635
((PMMCLONE_DESCRIPTOR)MiGetFirstNode((PMMADDRESS_NODE)(PsGetCurrentProcess()->CloneRoot)))
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 #define MiInsertClone(CLONE) \
00660
{ \
00661
ASSERT ((CLONE)->NumberOfPtes != 0); \
00662
MiInsertNode(((PMMADDRESS_NODE)(CLONE)),(PMMADDRESS_NODE *)&(PsGetCurrentProcess()->CloneRoot)); \
00663
}
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 #define MiRemoveClone(CLONE) \
00688
MiRemoveNode((PMMADDRESS_NODE)(CLONE),(PMMADDRESS_NODE *)&(PsGetCurrentProcess()->CloneRoot));
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 #define MiLocateCloneAddress(VA) \
00716
(PsGetCurrentProcess()->CloneRoot ? \
00717
((PMMCLONE_DESCRIPTOR)MiLocateAddressInTree(((ULONG_PTR)VA), \
00718
(PMMADDRESS_NODE *)&(PsGetCurrentProcess()->CloneRoot))) : \
00719
((PMMCLONE_DESCRIPTOR)NULL))
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 #define MiCheckForConflictingClone(START,END) \
00748
((PMMCLONE_DESCRIPTOR)(MiCheckForConflictingNode(START,END, \
00749
(PMMADDRESS_NODE)(PsGetCurrentProcess()->CloneRoot))))
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 #define MI_VA_TO_PAGE(va) ((ULONG_PTR)(va) >> PAGE_SHIFT)
00760
00761 #define MI_VA_TO_VPN(va) ((ULONG_PTR)(va) >> PAGE_SHIFT)
00762
00763 #define MI_VPN_TO_VA(vpn) (PVOID)((vpn) << PAGE_SHIFT)
00764
00765 #define MI_VPN_TO_VA_ENDING(vpn) (PVOID)(((vpn) << PAGE_SHIFT) | (PAGE_SIZE - 1))
00766
00767 #define MiGetByteOffset(va) ((ULONG_PTR)(va) & (PAGE_SIZE - 1))
00768
00769 #define MI_PFN_ELEMENT(index) (&MmPfnDatabase[index])
00770
00771
00772
00773
00774
00775 #define MI_MAKE_PROTECT_NOT_WRITE_COPY(PROTECT) \
00776
(MmMakeProtectNotWriteCopy[PROTECT])
00777
00778
00779
00780
00781
00782
#if defined(_ALPHA_) || defined(_X86_)
00783
00784
#define MiLockPfnDatabase(OldIrql) \
00785
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock)
00786
00787
#define MiUnlockPfnDatabase(OldIrql) \
00788
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql)
00789
00790
#define MiTryToLockPfnDatabase(OldIrql) \
00791
KeTryToAcquireQueuedSpinLock(LockQueuePfnLock, &OldIrql)
00792
00793
#define MiReleasePfnLock() \
00794
KiReleaseQueuedSpinLock(&KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock])
00795
00796
#define MiLockSystemSpace(OldIrql) \
00797
OldIrql = KeAcquireQueuedSpinLock(LockQueueSystemSpaceLock)
00798
00799
#define MiUnlockSystemSpace(OldIrql) \
00800
KeReleaseQueuedSpinLock(LockQueueSystemSpaceLock, OldIrql)
00801
00802
#define MiLockSystemSpaceAtDpcLevel() \
00803
KiAcquireQueuedSpinLock(&KeGetCurrentPrcb()->LockQueue[LockQueueSystemSpaceLock])
00804
00805
#define MiUnlockSystemSpaceFromDpcLevel() \
00806
KiReleaseQueuedSpinLock(&KeGetCurrentPrcb()->LockQueue[LockQueueSystemSpaceLock])
00807
00808
#else
00809
00810 #define MiLockPfnDatabase(OldIrql) \
00811
ExAcquireSpinLock(&MmPfnLock, &OldIrql)
00812
00813 #define MiUnlockPfnDatabase(OldIrql) \
00814
ExReleaseSpinLock(&MmPfnLock, OldIrql)
00815
00816 #define MiTryToLockPfnDatabase(OldIrql) \
00817
KeTryToAcquireSpinLock(&MmPfnLock, &OldIrql)
00818
00819 #define MiReleasePfnLock() \
00820
KiReleaseSpinLock(&MmPfnLock)
00821
00822 #define MiLockSystemSpace(OldIrql) \
00823
ExAcquireSpinLock(&MmSystemSpaceLock, &OldIrql)
00824
00825 #define MiUnlockSystemSpace(OldIrql) \
00826
ExReleaseSpinLock(&MmSystemSpaceLock, OldIrql)
00827
00828 #define MiLockSystemSpaceAtDpcLevel() \
00829
ExAcquireSpinLockAtDpcLevel(&MmSystemSpaceLock)
00830
00831 #define MiUnlockSystemSpaceFromDpcLevel() \
00832
ExReleaseSpinLockFromDpcLevel(&MmSystemSpaceLock)
00833
00834
#endif
00835
00836
#if PFN_CONSISTENCY
00837
00838
#define CONSISTENCY_LOCK_PFN(OLDIRQL) LOCK_PFN(OLDIRQL)
00839
#define CONSISTENCY_UNLOCK_PFN(OLDIRQL) UNLOCK_PFN(OLDIRQL)
00840
00841
#define CONSISTENCY_LOCK_PFN2(OLDIRQL) LOCK_PFN2(OLDIRQL)
00842
#define CONSISTENCY_UNLOCK_PFN2(OLDIRQL) UNLOCK_PFN2(OLDIRQL)
00843
00844
#define PFN_CONSISTENCY_SET \
00845
(MiPfnLockOwner = PsGetCurrentThread(), MiMapInPfnDatabase())
00846
#define PFN_CONSISTENCY_UNSET \
00847
(MiUnMapPfnDatabase(), MiPfnLockOwner = (PETHREAD)0)
00848
00849
VOID
00850 MiMapInPfnDatabase (
00851 VOID
00852 );
00853
00854
VOID
00855 MiUnMapPfnDatabase (
00856 VOID
00857 );
00858
00859
VOID
00860 MiSetModified (
00861 IN
PMMPFN Pfn1,
00862 IN ULONG Dirty
00863 );
00864
00865
extern PMMPTE MiPfnStartPte;
00866
extern PFN_NUMBER MiPfnPtes;
00867
extern BOOLEAN MiPfnProtectionEnabled;
00868
extern PETHREAD MiPfnLockOwner;
00869
00870
#define PFN_LOCK_OWNED_BY_ME() (MiPfnLockOwner == PsGetCurrentThread())
00871
00872
00873
#else // PFN_CONSISTENCY
00874
00875 #define CONSISTENCY_LOCK_PFN(OLDIRQL)
00876 #define CONSISTENCY_UNLOCK_PFN(OLDIRQL)
00877
00878 #define CONSISTENCY_LOCK_PFN2(OLDIRQL)
00879 #define CONSISTENCY_UNLOCK_PFN2(OLDIRQL)
00880
00881 #define PFN_CONSISTENCY_SET
00882 #define PFN_CONSISTENCY_UNSET
00883
00884
#endif // PFN_CONSISTENCY
00885
00886 #define LOCK_PFN(OLDIRQL) ASSERT (KeGetCurrentIrql() <= APC_LEVEL); \
00887
MiLockPfnDatabase(OLDIRQL); \
00888
PFN_CONSISTENCY_SET;
00889
00890 #define LOCK_PFN_WITH_TRY(OLDIRQL) \
00891
ASSERT (KeGetCurrentIrql() <= APC_LEVEL); \
00892
do { \
00893
} while (MiTryToLockPfnDatabase(OLDIRQL) == FALSE); \
00894
PFN_CONSISTENCY_SET;
00895
00896 #define UNLOCK_PFN(OLDIRQL) \
00897
PFN_CONSISTENCY_UNSET; \
00898
MiUnlockPfnDatabase(OLDIRQL); \
00899
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
00900
00901 #define LOCK_PFN2(OLDIRQL) ASSERT (KeGetCurrentIrql() <= DISPATCH_LEVEL); \
00902
MiLockPfnDatabase(OLDIRQL); \
00903
PFN_CONSISTENCY_SET;
00904
00905 #define UNLOCK_PFN2(OLDIRQL) \
00906
PFN_CONSISTENCY_UNSET; \
00907
MiUnlockPfnDatabase(OLDIRQL); \
00908
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
00909
00910 #define UNLOCK_PFN_AND_THEN_WAIT(OLDIRQL) \
00911
{ \
00912
KIRQL XXX; \
00913
ASSERT (KeGetCurrentIrql() == 2); \
00914
ASSERT (OLDIRQL <= APC_LEVEL); \
00915
KiLockDispatcherDatabase (&XXX); \
00916
PFN_CONSISTENCY_UNSET; \
00917
MiReleasePfnLock(); \
00918
(KeGetCurrentThread())->WaitIrql = OLDIRQL; \
00919
(KeGetCurrentThread())->WaitNext = TRUE; \
00920
}
00921
00922 #define LOCK_AWE(PROCESS,OldIrql) \
00923
ExAcquireSpinLock(&((PROCESS)->AweLock), &OldIrql)
00924
00925 #define UNLOCK_AWE(PROCESS,OldIrql) \
00926
ExReleaseSpinLock(&((PROCESS)->AweLock), OldIrql)
00927
00928 extern KMUTANT MmSystemLoadLock;
00929
00930
#if DBG
00931
#define SYSLOAD_LOCK_OWNED_BY_ME() ((PETHREAD)MmSystemLoadLock.OwnerThread == PsGetCurrentThread())
00932
#else
00933 #define SYSLOAD_LOCK_OWNED_BY_ME()
00934
#endif
00935
00936
#if DBG
00937
#define MM_PFN_LOCK_ASSERT() \
00938
if (MmDebug & 0x80000) { \
00939
ASSERT (KeGetCurrentIrql() == 2); \
00940
}
00941
00942
extern PETHREAD MiExpansionLockOwner;
00943
00944
#define MM_SET_EXPANSION_OWNER() ASSERT (MiExpansionLockOwner == NULL); \
00945
MiExpansionLockOwner = PsGetCurrentThread();
00946
00947
#define MM_CLEAR_EXPANSION_OWNER() ASSERT (MiExpansionLockOwner == PsGetCurrentThread()); \
00948
MiExpansionLockOwner = NULL;
00949
00950
#else
00951 #define MM_PFN_LOCK_ASSERT()
00952 #define MM_SET_EXPANSION_OWNER()
00953 #define MM_CLEAR_EXPANSION_OWNER()
00954
#endif //DBG
00955
00956
00957 #define LOCK_EXPANSION(OLDIRQL) ASSERT (KeGetCurrentIrql() <= APC_LEVEL); \
00958
ExAcquireSpinLock (&MmExpansionLock, &OLDIRQL);\
00959
MM_SET_EXPANSION_OWNER ();
00960
00961 #define UNLOCK_EXPANSION(OLDIRQL) MM_CLEAR_EXPANSION_OWNER (); \
00962
ExReleaseSpinLock (&MmExpansionLock, OLDIRQL); \
00963
ASSERT (KeGetCurrentIrql() <= APC_LEVEL);
00964
00965 #define UNLOCK_EXPANSION_AND_THEN_WAIT(OLDIRQL) \
00966
{ \
00967
KIRQL XXX; \
00968
ASSERT (KeGetCurrentIrql() == 2); \
00969
ASSERT (OLDIRQL <= APC_LEVEL); \
00970
KiLockDispatcherDatabase (&XXX); \
00971
MM_CLEAR_EXPANSION_OWNER (); \
00972
KiReleaseSpinLock (&MmExpansionLock); \
00973
(KeGetCurrentThread())->WaitIrql = OLDIRQL; \
00974
(KeGetCurrentThread())->WaitNext = TRUE; \
00975
}
00976
00977
#if defined(_ALPHA_) && !defined(_AXP64_)
00978
#define LOCK_EXPANSION_IF_ALPHA(OLDIRQL) \
00979
ExAcquireSpinLock (&MmExpansionLock, &OLDIRQL); \
00980
MM_SET_EXPANSION_OWNER ();
00981
#else
00982 #define LOCK_EXPANSION_IF_ALPHA(OLDIRQL)
00983
#endif //ALPHA
00984
00985
00986
#if defined(_ALPHA_) && !defined(_AXP64_)
00987
#define UNLOCK_EXPANSION_IF_ALPHA(OLDIRQL) \
00988
MM_CLEAR_EXPANSION_OWNER (); \
00989
ExReleaseSpinLock ( &MmExpansionLock, OLDIRQL )
00990
#else
00991 #define UNLOCK_EXPANSION_IF_ALPHA(OLDIRQL)
00992
#endif //ALPHA
00993
00994
00995 extern LIST_ENTRY
MmLockConflictList;
00996 extern PETHREAD MmSystemLockOwner;
00997
00998 #define LOCK_SYSTEM_WS(OLDIRQL) \
00999
ASSERT (KeGetCurrentIrql() <= APC_LEVEL); \
01000
KeRaiseIrql(APC_LEVEL,&OLDIRQL); \
01001
ExAcquireResourceExclusive(&MmSystemWsLock,TRUE); \
01002
ASSERT (MmSystemLockOwner == NULL); \
01003
MmSystemLockOwner = PsGetCurrentThread();
01004
01005 #define UNLOCK_SYSTEM_WS(OLDIRQL) \
01006
ASSERT (MmSystemLockOwner == PsGetCurrentThread()); \
01007
MmSystemLockOwner = NULL; \
01008
ExReleaseResource (&MmSystemWsLock); \
01009
KeLowerIrql (OLDIRQL); \
01010
ASSERT (KeGetCurrentIrql() <= APC_LEVEL);
01011
01012 #define UNLOCK_SYSTEM_WS_NO_IRQL() \
01013
ASSERT (MmSystemLockOwner == PsGetCurrentThread()); \
01014
MmSystemLockOwner = NULL; \
01015
ExReleaseResource (&MmSystemWsLock);
01016
01017 #define MM_SYSTEM_WS_LOCK_ASSERT() \
01018
ASSERT (PsGetCurrentThread() == MmSystemLockOwner);
01019
01020 #define LOCK_HYPERSPACE(OLDIRQL) \
01021
ExAcquireSpinLock ( &(PsGetCurrentProcess())->HyperSpaceLock, OLDIRQL );
01022
01023
01024 #define UNLOCK_HYPERSPACE(OLDIRQL) \
01025
ExReleaseSpinLock ( &(PsGetCurrentProcess())->HyperSpaceLock, OLDIRQL );
01026
01027
#if defined (_AXP64_)
01028
#define MI_WS_OWNER(PROCESS) ((PROCESS)->WorkingSetLock.Owner == KeGetCurrentThread())
01029
#define MI_NOT_WS_OWNER(PROCESS) (!MI_WS_OWNER(PROCESS))
01030
#else
01031 #define MI_WS_OWNER(PROCESS) 1
01032 #define MI_NOT_WS_OWNER(PROCESS) 1
01033
#endif
01034
01035 #define MI_MUTEX_ACQUIRED_UNSAFE 0x88
01036
01037 #define MI_IS_WS_UNSAFE(PROCESS) ((PROCESS)->WorkingSetLock.OldIrql == MI_MUTEX_ACQUIRED_UNSAFE)
01038
01039 #define LOCK_WS(PROCESS) \
01040
ASSERT (MI_NOT_WS_OWNER(PROCESS)); \
01041
ExAcquireFastMutex( &((PROCESS)->WorkingSetLock)); \
01042
ASSERT (!MI_IS_WS_UNSAFE(PROCESS));
01043
01044 #define LOCK_WS_UNSAFE(PROCESS) \
01045
ASSERT (MI_NOT_WS_OWNER(PROCESS)); \
01046
ASSERT (KeGetCurrentIrql() == APC_LEVEL); \
01047
ExAcquireFastMutexUnsafe( &((PROCESS)->WorkingSetLock));\
01048
(PROCESS)->WorkingSetLock.OldIrql = MI_MUTEX_ACQUIRED_UNSAFE;
01049
01050 #define MI_MUST_BE_UNSAFE(PROCESS) \
01051
ASSERT (KeGetCurrentIrql() == APC_LEVEL); \
01052
ASSERT (MI_WS_OWNER(PROCESS)); \
01053
ASSERT (MI_IS_WS_UNSAFE(PROCESS));
01054
01055 #define MI_MUST_BE_SAFE(PROCESS) \
01056
ASSERT (MI_WS_OWNER(PROCESS)); \
01057
ASSERT (!MI_IS_WS_UNSAFE(PROCESS));
01058
#if 0
01059
01060
#define MI_MUST_BE_UNSAFE(PROCESS) \
01061
if (KeGetCurrentIrql() != APC_LEVEL) { \
01062
KeBugCheckEx(MEMORY_MANAGEMENT, 0x32, (ULONG_PTR)PROCESS, KeGetCurrentIrql(), 0); \
01063
} \
01064
if (!MI_WS_OWNER(PROCESS)) { \
01065
KeBugCheckEx(MEMORY_MANAGEMENT, 0x33, (ULONG_PTR)PROCESS, 0, 0); \
01066
} \
01067
if (!MI_IS_WS_UNSAFE(PROCESS)) { \
01068
KeBugCheckEx(MEMORY_MANAGEMENT, 0x34, (ULONG_PTR)PROCESS, 0, 0); \
01069
}
01070
01071
#define MI_MUST_BE_SAFE(PROCESS) \
01072
if (!MI_WS_OWNER(PROCESS)) { \
01073
KeBugCheckEx(MEMORY_MANAGEMENT, 0x42, (ULONG_PTR)PROCESS, 0, 0); \
01074
} \
01075
if (MI_IS_WS_UNSAFE(PROCESS)) { \
01076
KeBugCheckEx(MEMORY_MANAGEMENT, 0x43, (ULONG_PTR)PROCESS, 0, 0); \
01077
}
01078
#endif
01079
01080
01081 #define UNLOCK_WS(PROCESS) \
01082
MI_MUST_BE_SAFE(PROCESS); \
01083
ExReleaseFastMutex(&((PROCESS)->WorkingSetLock));
01084
01085 #define UNLOCK_WS_UNSAFE(PROCESS) \
01086
MI_MUST_BE_UNSAFE(PROCESS); \
01087
ExReleaseFastMutexUnsafe(&((PROCESS)->WorkingSetLock)); \
01088
ASSERT (KeGetCurrentIrql() == APC_LEVEL);
01089
01090 #define LOCK_ADDRESS_SPACE(PROCESS) \
01091
ExAcquireFastMutex( &((PROCESS)->AddressCreationLock))
01092
01093 #define LOCK_WS_AND_ADDRESS_SPACE(PROCESS) \
01094
LOCK_ADDRESS_SPACE(PROCESS); \
01095
LOCK_WS_UNSAFE(PROCESS);
01096
01097 #define UNLOCK_WS_AND_ADDRESS_SPACE(PROCESS) \
01098
UNLOCK_WS_UNSAFE(PROCESS); \
01099
UNLOCK_ADDRESS_SPACE(PROCESS);
01100
01101 #define UNLOCK_ADDRESS_SPACE(PROCESS) \
01102
ExReleaseFastMutex( &((PROCESS)->AddressCreationLock))
01103
01104
01105
01106
01107
01108
01109 #define UNLOCK_WS_REGARDLESS(PROCESS, WSHELDSAFE) \
01110
ASSERT (MI_WS_OWNER (PROCESS)); \
01111
if (MI_IS_WS_UNSAFE (PROCESS)) { \
01112
UNLOCK_WS_UNSAFE (PROCESS); \
01113
WSHELDSAFE = FALSE; \
01114
} \
01115
else { \
01116
UNLOCK_WS (PROCESS); \
01117
WSHELDSAFE = TRUE; \
01118
}
01119
01120 #define LOCK_WS_REGARDLESS(PROCESS, WSHELDSAFE) \
01121
if (WSHELDSAFE == TRUE) { \
01122
LOCK_WS (PROCESS); \
01123
} \
01124
else { \
01125
LOCK_WS_UNSAFE (PROCESS); \
01126
}
01127
01128 #define ZERO_LARGE(LargeInteger) \
01129
(LargeInteger).LowPart = 0; \
01130
(LargeInteger).HighPart = 0;
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157 #define MI_CHECK_BIT(ARRAY,BIT) \
01158
(((ULONG)ARRAY[(BIT) / (sizeof(ULONG)*8)] >> ((BIT) & 0x1F)) & 1)
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186 #define MI_SET_BIT(ARRAY,BIT) \
01187
(ULONG)ARRAY[(BIT) / (sizeof(ULONG)*8)] |= (1 << ((BIT) & 0x1F))
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 #define MI_CLEAR_BIT(ARRAY,BIT) \
01216
(ULONG)ARRAY[(BIT) / (sizeof(ULONG)*8)] &= ~(1 << ((BIT) & 0x1F))
01217
01218
01219 #define MI_MAGIC_AWE_PTEFRAME 0xffffedcb
01220
01221 #define MI_PFN_IS_AWE(Pfn1) \
01222
((Pfn1->u2.ShareCount <= 3) && \
01223
(Pfn1->u3.e1.PageLocation == ActiveAndValid) && \
01224
(Pfn1->u3.e1.VerifierAllocation == 0) && \
01225
(Pfn1->u3.e1.LargeSessionAllocation == 0) && \
01226
(Pfn1->u3.e1.StartOfAllocation == 1) && \
01227
(Pfn1->u3.e1.EndOfAllocation == 1) && \
01228
(Pfn1->PteFrame == MI_MAGIC_AWE_PTEFRAME))
01229
01230
01231 typedef ULONG
WSLE_NUMBER, *
PWSLE_NUMBER;
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 #define StartOfAllocation ReadInProgress
01242
01243 #define EndOfAllocation WriteInProgress
01244
01245 #define LargeSessionAllocation PrototypePte
01246
01247
01248
01249
01250
01251
01252
01253 typedef struct _MMPFNENTRY {
01254 ULONG
Modified : 1;
01255 ULONG
ReadInProgress : 1;
01256 ULONG
WriteInProgress : 1;
01257 ULONG
PrototypePte: 1;
01258 ULONG
PageColor : 3;
01259 ULONG
ParityError : 1;
01260 ULONG
PageLocation : 3;
01261 ULONG
InPageError : 1;
01262 ULONG
VerifierAllocation : 1;
01263 ULONG
RemovalRequested : 1;
01264 ULONG
Reserved : 1;
01265 ULONG
LockCharged : 1;
01266 ULONG
DontUse : 16;
01267 }
MMPFNENTRY;
01268
01269
#if defined (_X86PAE_)
01270
#pragma pack(1)
01271
#endif
01272
01273 typedef struct _MMPFN {
01274
union {
01275 PFN_NUMBER
Flink;
01276 WSLE_NUMBER WsIndex;
01277 PKEVENT Event;
01278 NTSTATUS ReadStatus;
01279 struct _MMPFN *
NextStackPfn;
01280 } u1;
01281 PMMPTE PteAddress;
01282
union {
01283 PFN_NUMBER Blink;
01284 ULONG ShareCount;
01285 ULONG SecondaryColorFlink;
01286 } u2;
01287
union {
01288 MMPFNENTRY e1;
01289
struct {
01290 USHORT ShortFlags;
01291 USHORT ReferenceCount;
01292 } e2;
01293 }
u3;
01294
#if defined (_WIN64)
01295
ULONG UsedPageTableEntries;
01296
#endif
01297 MMPTE OriginalPte;
01298 PFN_NUMBER
PteFrame;
01299 }
MMPFN, *
PMMPFN;
01300
01301
#if defined (_X86PAE_)
01302
#pragma pack()
01303
#endif
01304
01305
#if defined (_WIN64)
01306
01307
01308
01309
01310
01311
01312
#define MI_CAPTURE_USED_PAGETABLE_ENTRIES(PFN) \
01313
ASSERT ((PFN)->UsedPageTableEntries <= PTE_PER_PAGE); \
01314
(PFN)->OriginalPte.u.Soft.UsedPageTableEntries = (PFN)->UsedPageTableEntries;
01315
01316
#define MI_RETRIEVE_USED_PAGETABLE_ENTRIES_FROM_PTE(RBL, PTE) \
01317
ASSERT ((PTE)->u.Soft.UsedPageTableEntries <= PTE_PER_PAGE); \
01318
(RBL)->UsedPageTableEntries = (ULONG)(((PMMPTE)(PTE))->u.Soft.UsedPageTableEntries);
01319
01320
#define MI_ZERO_USED_PAGETABLE_ENTRIES_IN_INPAGE_SUPPORT(INPAGE_SUPPORT) \
01321
(INPAGE_SUPPORT)->UsedPageTableEntries = 0;
01322
01323
#define MI_ZERO_USED_PAGETABLE_ENTRIES_IN_PFN(PFN) (PFN)->UsedPageTableEntries = 0;
01324
01325
#define MI_INSERT_USED_PAGETABLE_ENTRIES_IN_PFN(PFN, INPAGE_SUPPORT) \
01326
ASSERT ((INPAGE_SUPPORT)->UsedPageTableEntries <= PTE_PER_PAGE); \
01327
(PFN)->UsedPageTableEntries = (INPAGE_SUPPORT)->UsedPageTableEntries;
01328
01329
#define MI_ZERO_USED_PAGETABLE_ENTRIES(PFN) \
01330
(PFN)->UsedPageTableEntries = 0;
01331
01332
#define MI_GET_USED_PTES_HANDLE(VA) \
01333
((PVOID)MI_PFN_ELEMENT((PFN_NUMBER)MiGetPdeAddress(VA)->u.Hard.PageFrameNumber))
01334
01335
#define MI_GET_USED_PTES_FROM_HANDLE(PFN) \
01336
((ULONG)(((PMMPFN)(PFN))->UsedPageTableEntries))
01337
01338
#define MI_INCREMENT_USED_PTES_BY_HANDLE(PFN) \
01339
(((PMMPFN)(PFN))->UsedPageTableEntries += 1); \
01340
ASSERT (((PMMPFN)(PFN))->UsedPageTableEntries <= PTE_PER_PAGE)
01341
01342
#define MI_DECREMENT_USED_PTES_BY_HANDLE(PFN) \
01343
(((PMMPFN)(PFN))->UsedPageTableEntries -= 1); \
01344
ASSERT (((PMMPFN)(PFN))->UsedPageTableEntries < PTE_PER_PAGE)
01345
01346
#else
01347
01348 #define MI_CAPTURE_USED_PAGETABLE_ENTRIES(PFN)
01349 #define MI_RETRIEVE_USED_PAGETABLE_ENTRIES_FROM_PTE(RBL, PTE)
01350 #define MI_ZERO_USED_PAGETABLE_ENTRIES_IN_INPAGE_SUPPORT(INPAGE_SUPPORT)
01351 #define MI_ZERO_USED_PAGETABLE_ENTRIES_IN_PFN(PFN)
01352
01353 #define MI_INSERT_USED_PAGETABLE_ENTRIES_IN_PFN(PFN, INPAGE_SUPPORT)
01354
01355 #define MI_GET_USED_PTES_HANDLE(VA) ((PVOID)&MmWorkingSetList->UsedPageTableEntries[MiGetPpePdeOffset(VA)])
01356
01357 #define MI_GET_USED_PTES_FROM_HANDLE(PDSHORT) ((ULONG)(*(PUSHORT)(PDSHORT)))
01358
01359 #define MI_INCREMENT_USED_PTES_BY_HANDLE(PDSHORT) ((*(PUSHORT)(PDSHORT)) += 1); \
01360
ASSERT (((*(PUSHORT)(PDSHORT)) <= PTE_PER_PAGE))
01361
01362 #define MI_DECREMENT_USED_PTES_BY_HANDLE(PDSHORT) ((*(PUSHORT)(PDSHORT)) -= 1); \
01363
ASSERT (((*(PUSHORT)(PDSHORT)) < PTE_PER_PAGE))
01364
01365
#endif
01366
01367 extern LOGICAL
MmDynamicPfn;
01368
01369 extern FAST_MUTEX MmDynamicMemoryMutex;
01370
01371 extern PFN_NUMBER
MmSystemLockPagesCount;
01372
01373
#if DBG
01374
01375
#define MI_LOCK_ID_COUNTER_MAX 64
01376
ULONG MiLockIds[MI_LOCK_ID_COUNTER_MAX];
01377
01378
#define MI_MARK_PFN_AS_LOCK_CHARGED(Pfn, CallerId) \
01379
ASSERT (Pfn->u3.e1.LockCharged == 0); \
01380
ASSERT (CallerId < MI_LOCK_ID_COUNTER_MAX); \
01381
MiLockIds[CallerId] += 1; \
01382
Pfn->u3.e1.LockCharged = 1;
01383
01384
#define MI_UNMARK_PFN_AS_LOCK_CHARGED(Pfn, CallerId) \
01385
ASSERT (Pfn->u3.e1.LockCharged == 1); \
01386
ASSERT (CallerId < MI_LOCK_ID_COUNTER_MAX); \
01387
MiLockIds[CallerId] += 1; \
01388
Pfn->u3.e1.LockCharged = 0;
01389
01390
#else
01391 #define MI_MARK_PFN_AS_LOCK_CHARGED(Pfn, CallerId)
01392 #define MI_UNMARK_PFN_AS_LOCK_CHARGED(Pfn, CallerId)
01393
#endif
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417 #define MI_ADD_LOCKED_PAGE_CHARGE(Pfn, CallerId) \
01418
ASSERT (Pfn->u3.e2.ReferenceCount != 0); \
01419
if (Pfn->u3.e2.ReferenceCount == 1) { \
01420
if (Pfn->u2.ShareCount != 0) { \
01421
ASSERT (Pfn->u3.e1.PageLocation == ActiveAndValid); \
01422
MI_MARK_PFN_AS_LOCK_CHARGED(Pfn, CallerId); \
01423
MmSystemLockPagesCount += 1; \
01424
} \
01425
else { \
01426
ASSERT (Pfn->u3.e1.LockCharged == 1); \
01427
} \
01428
}
01429
01430 #define MI_ADD_LOCKED_PAGE_CHARGE_FOR_MODIFIED_PAGE(Pfn, CallerId) \
01431
ASSERT (Pfn->u3.e1.PageLocation != ActiveAndValid); \
01432
ASSERT (Pfn->u2.ShareCount == 0); \
01433
if (Pfn->u3.e2.ReferenceCount == 0) { \
01434
MI_MARK_PFN_AS_LOCK_CHARGED(Pfn, CallerId); \
01435
MmSystemLockPagesCount += 1; \
01436
}
01437
01438 #define MI_ADD_LOCKED_PAGE_CHARGE_FOR_TRANSITION_PAGE(Pfn, CallerId) \
01439
ASSERT (Pfn->u3.e1.PageLocation == ActiveAndValid); \
01440
ASSERT (Pfn->u2.ShareCount == 0); \
01441
ASSERT (Pfn->u3.e2.ReferenceCount != 0); \
01442
if (Pfn->u3.e2.ReferenceCount == 1) { \
01443
MI_MARK_PFN_AS_LOCK_CHARGED(Pfn, CallerId); \
01444
MmSystemLockPagesCount += 1; \
01445
}
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470 #define MI_REMOVE_LOCKED_PAGE_CHARGE(Pfn, CallerId) \
01471
ASSERT (Pfn->u3.e2.ReferenceCount != 0); \
01472
if (Pfn->u3.e2.ReferenceCount == 2) { \
01473
if (Pfn->u2.ShareCount >= 1) { \
01474
ASSERT (Pfn->u3.e1.PageLocation == ActiveAndValid); \
01475
MI_UNMARK_PFN_AS_LOCK_CHARGED(Pfn, CallerId); \
01476
MmSystemLockPagesCount -= 1; \
01477
} \
01478
else { \
01479
01480
01481
01482
01483
01484 \
01485 NOTHING; \
01486 } \
01487 } \
01488 else if (Pfn->u3.e2.ReferenceCount == 1) { \
01489
01490
01491
01492
01493 \
01494 ASSERT (Pfn->u3.e1.PageLocation != ActiveAndValid); \
01495 ASSERT (Pfn->u2.ShareCount == 0); \
01496 MI_UNMARK_PFN_AS_LOCK_CHARGED(Pfn, CallerId); \
01497 MmSystemLockPagesCount -= 1; \
01498 } \
01499 else { \
01500
01501
01502
01503
01504
01505
01506 \
01507 NOTHING; \
01508 }
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
#define MI_ZERO_WSINDEX(Pfn) \
01537
Pfn->u1.Event = NULL;
01538
01539
typedef enum _MMSHARE_TYPE {
01540
Normal,
01541
ShareCountOnly,
01542
AndValid
01543 }
MMSHARE_TYPE;
01544
01545
typedef struct _MMWSLE_HASH {
01546 ULONG_PTR Key;
01547
WSLE_NUMBER Index;
01548 }
MMWSLE_HASH, *
PMMWSLE_HASH;
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574 #define MI_WSLE_HASH(Address, Wsl) \
01575
((WSLE_NUMBER)(((ULONG_PTR)PAGE_ALIGN(Address) >> (PAGE_SHIFT - 2)) % \
01576
((Wsl)->HashTableSize - 1)))
01577
01578
01579
01580
01581
01582
typedef struct _MMWSLENTRY {
01583 ULONG_PTR Valid : 1;
01584 ULONG_PTR LockedInWs : 1;
01585 ULONG_PTR LockedInMemory : 1;
01586 ULONG_PTR Protection : 5;
01587 ULONG_PTR SameProtectAsProto : 1;
01588 ULONG_PTR Direct : 1;
01589 ULONG_PTR Age : 2;
01590
#if MM_VIRTUAL_PAGE_FILLER
01591 ULONG_PTR Filler :
MM_VIRTUAL_PAGE_FILLER;
01592
#endif
01593
ULONG_PTR VirtualPageNumber :
MM_VIRTUAL_PAGE_SIZE;
01594 }
MMWSLENTRY;
01595
01596
typedef struct _MMWSLE {
01597 union {
01598 PVOID VirtualAddress;
01599 ULONG_PTR Long;
01600 MMWSLENTRY e1;
01601 } u1;
01602 }
MMWSLE;
01603
01604 #define MI_GET_PROTECTION_FROM_WSLE(Wsl) ((Wsl)->u1.e1.Protection)
01605
01606 typedef MMWSLE *
PMMWSLE;
01607
01608
01609
01610
01611
01612
typedef struct _MMWSL {
01613 SIZE_T
Quota;
01614
WSLE_NUMBER FirstFree;
01615
WSLE_NUMBER FirstDynamic;
01616 WSLE_NUMBER LastEntry;
01617 WSLE_NUMBER NextSlot;
01618
PMMWSLE Wsle;
01619 SIZE_T
NumberOfCommittedPageTables;
01620
WSLE_NUMBER LastInitializedWsle;
01621
WSLE_NUMBER NonDirectCount;
01622 PMMWSLE_HASH HashTable;
01623 ULONG
HashTableSize;
01624
PKEVENT WaitingForImageMapping;
01625 PVOID
HashTableStart;
01626 PVOID
HighestPermittedHashAddress;
01627
01628
01629
01630
#if !defined (_WIN64)
01631
PVOID
Align1;
01632 PVOID
Align2;
01633
01634
01635
01636
01637
USHORT UsedPageTableEntries[
MM_USER_PAGE_TABLE_PAGES];
01638
#endif
01639
01640
#ifndef _WIN64
01641
ULONG
CommittedPageTables[
MM_USER_PAGE_TABLE_PAGES/(
sizeof(ULONG)*8)];
01642
#endif
01643
01644 }
MMWSL, *
PMMWSL;
01645
01646 #ifdef _MI_USE_CLAIMS_
01647
01648
01649
01650
01651
01652
01653
#define MI_CLAIM_INCR 30
01654
01655
#endif
01656
01657
01658
01659
01660
01661 #define MI_USE_AGE_COUNT 4
01662
#define MI_USE_AGE_MAX (MI_USE_AGE_COUNT - 1)
01663
01664
01665
01666
01667
01668
01669
#define MI_REPLACEMENT_FREE_GROWTH_SHIFT 5
01670
01671
01672
01673
01674
01675
01676
#define MI_REPLACEMENT_CLAIM_THRESHOLD_SHIFT 3
01677
01678
01679
01680
01681
01682
01683 #define MI_REPLACEMENT_EAVAIL_THRESHOLD_SHIFT 3
01684
01685
01686
01687
01688
01689
01690
#define MI_IMMEDIATE_REPLACEMENT_AGE 2
01691
01692
01693
01694
01695
01696
#define MI_MAX_TRIM_PASSES 4
01697
#define MI_PASS0_TRIM_AGE 2
01698 #define MI_PASS1_TRIM_AGE 1
01699
#define MI_PASS2_TRIM_AGE 1
01700
#define MI_PASS3_TRIM_AGE 1
01701
#define MI_PASS4_TRIM_AGE 0
01702
01703
01704
01705
01706
01707
#define MI_TRIM_AGE_THRESHOLD 2
01708
01709
01710
01711
01712
01713
#define MI_FOREGROUND_CLAIM_AVAILABLE_SHIFT 3
01714
01715
01716
01717
01718
01719
#define MI_BACKGROUND_CLAIM_AVAILABLE_SHIFT 1
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
typedef struct _MI_NEXT_ESTIMATION_SLOT_CONST {
01763
WSLE_NUMBER Stride;
01764 }
MI_NEXT_ESTIMATION_SLOT_CONST;
01765
01766
01767
#define MI_CALC_NEXT_ESTIMATION_SLOT_CONST(NextEstimationSlotConst, WorkingSetList) \
01768
(NextEstimationSlotConst).Stride = 1 << MiEstimationShift;
01769
01770
#define MI_NEXT_VALID_ESTIMATION_SLOT(Previous, StartEntry, Minimum, Maximum, NextEstimationSlotConst, Wsle) \
01771
ASSERT(((Previous) >= Minimum) && ((Previous) <= Maximum)); \
01772
ASSERT(((StartEntry) >= Minimum) && ((StartEntry) <= Maximum)); \
01773
do { \
01774
(Previous) += (NextEstimationSlotConst).Stride; \
01775
if ((Previous) > Maximum) { \
01776
(Previous) = Minimum + ((Previous + 1) & (NextEstimationSlotConst.Stride - 1)); \
01777
StartEntry += 1; \
01778
(Previous) = StartEntry; \
01779
} \
01780
if ((Previous) > Maximum || (Previous) < Minimum) { \
01781
StartEntry = Minimum; \
01782
(Previous) = StartEntry; \
01783
} \
01784
} while (Wsle[Previous].u1.e1.Valid == 0);
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
#define MI_NEXT_VALID_AGING_SLOT(Previous, Minimum, Maximum, Wsle) \
01822
ASSERT(((Previous) >= Minimum) && ((Previous) <= Maximum)); \
01823
do { \
01824
(Previous) += 1; \
01825
if ((Previous) > Maximum) { \
01826
Previous = Minimum; \
01827
} \
01828
} while ((Wsle[Previous].u1.e1.Valid == 0));
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
#define MI_CALCULATE_USAGE_ESTIMATE(SampledAgeCounts) \
01855
(((SampledAgeCounts)[1] + \
01856
(SampledAgeCounts)[2] + (SampledAgeCounts)[3]) \
01857
<< MiEstimationShift)
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
#define MI_RESET_WSLE_AGE(PointerPte, Wsle) \
01883
(Wsle)->u1.e1.Age = 0;
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
#define MI_GET_WSLE_AGE(PointerPte, Wsle) \
01908
((Wsle)->u1.e1.Age)
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
#define MI_INC_WSLE_AGE(PointerPte, Wsle) \
01935
if ((Wsle)->u1.e1.Age < 3) { \
01936
(Wsle)->u1.e1.Age += 1; \
01937
}
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
#define MI_UPDATE_USE_ESTIMATE(PointerPte, Wsle, SampledAgeCounts) \
01967
(SampledAgeCounts)[(Wsle)->u1.e1.Age] += 1;
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
#define MI_WS_GROWING_TOO_FAST(VmSupport) \
01993
((VmSupport)->GrowthSinceLastEstimate > \
01994
(((MI_CLAIM_INCR * (MmAvailablePages*MmAvailablePages)) / (64*64)) + 1))
01995
01996
01997
01998
01999
02000 #define SECTION_BASE_ADDRESS(_NtSection) \
02001 (*((PVOID *)&(_NtSection)->PointerToRelocations))
02002
02003 typedef enum _SECTION_CHECK_TYPE {
02004 CheckDataSection,
02005 CheckImageSection,
02006 CheckUserDataSection,
02007 CheckBothSection
02008 }
SECTION_CHECK_TYPE;
02009
02010 typedef struct _MMEXTEND_INFO {
02011 UINT64 CommittedSize;
02012 ULONG ReferenceCount;
02013 }
MMEXTEND_INFO, *
PMMEXTEND_INFO;
02014
02015
typedef struct _SEGMENT {
02016
struct _CONTROL_AREA *
ControlArea;
02017 PVOID
SegmentBaseAddress;
02018 ULONG TotalNumberOfPtes;
02019 ULONG NonExtendedPtes;
02020 UINT64 SizeOfSegment;
02021 SIZE_T ImageCommitment;
02022 PSECTION_IMAGE_INFORMATION ImageInformation;
02023 PVOID SystemImageBase;
02024 SIZE_T NumberOfCommittedPages;
02025 MMPTE SegmentPteTemplate;
02026 PVOID BasedAddress;
02027 PMMEXTEND_INFO ExtendInfo;
02028 PMMPTE PrototypePte;
02029 MMPTE ThePtes[
MM_PROTO_PTE_ALIGNMENT /
PAGE_SIZE];
02030
02031 }
SEGMENT, *
PSEGMENT;
02032
02033 typedef struct _EVENT_COUNTER {
02034 ULONG RefCount;
02035 KEVENT Event;
02036 LIST_ENTRY ListEntry;
02037 }
EVENT_COUNTER, *
PEVENT_COUNTER;
02038
02039 typedef struct _MMSECTION_FLAGS {
02040 unsigned BeingDeleted : 1;
02041 unsigned BeingCreated : 1;
02042 unsigned BeingPurged : 1;
02043 unsigned NoModifiedWriting : 1;
02044 unsigned FailAllIo : 1;
02045 unsigned Image : 1;
02046 unsigned Based : 1;
02047 unsigned File : 1;
02048 unsigned Networked : 1;
02049 unsigned NoCache : 1;
02050 unsigned PhysicalMemory : 1;
02051 unsigned CopyOnWrite : 1;
02052 unsigned Reserve : 1;
02053 unsigned Commit : 1;
02054 unsigned FloppyMedia : 1;
02055
unsigned WasPurged : 1;
02056
unsigned UserReference : 1;
02057 unsigned GlobalMemory : 1;
02058 unsigned DeleteOnClose : 1;
02059 unsigned FilePointerNull : 1;
02060 unsigned DebugSymbolsLoaded : 1;
02061 unsigned SetMappedFileIoComplete : 1;
02062 unsigned CollidedFlush : 1;
02063 unsigned NoChange : 1;
02064 unsigned HadUserReference : 1;
02065 unsigned ImageMappedInSystemSpace : 1;
02066
unsigned filler0 : 1;
02067 unsigned Accessed : 1;
02068 unsigned GlobalOnlyPerSession : 1;
02069
unsigned filler : 3;
02070 }
MMSECTION_FLAGS;
02071
02072 typedef struct _CONTROL_AREA {
02073 PSEGMENT Segment;
02074 LIST_ENTRY
DereferenceList;
02075 ULONG
NumberOfSectionReferences;
02076 ULONG
NumberOfPfnReferences;
02077 ULONG
NumberOfMappedViews;
02078 USHORT NumberOfSubsections;
02079 USHORT FlushInProgressCount;
02080 ULONG NumberOfUserReferences;
02081 union {
02082 ULONG LongFlags;
02083 MMSECTION_FLAGS Flags;
02084 } u;
02085 PFILE_OBJECT FilePointer;
02086 PEVENT_COUNTER WaitingForDeletion;
02087
USHORT ModifiedWriteCount;
02088 USHORT NumberOfSystemCacheViews;
02089 SIZE_T PagedPoolUsage;
02090 SIZE_T NonPagedPoolUsage;
02091 }
CONTROL_AREA, *
PCONTROL_AREA;
02092
02093 typedef struct _LARGE_CONTROL_AREA {
02094 PSEGMENT Segment;
02095 LIST_ENTRY
DereferenceList;
02096 ULONG
NumberOfSectionReferences;
02097 ULONG
NumberOfPfnReferences;
02098 ULONG
NumberOfMappedViews;
02099 USHORT NumberOfSubsections;
02100
USHORT FlushInProgressCount;
02101 ULONG
NumberOfUserReferences;
02102 union {
02103 ULONG LongFlags;
02104 MMSECTION_FLAGS Flags;
02105 } u;
02106 PFILE_OBJECT FilePointer;
02107 PEVENT_COUNTER WaitingForDeletion;
02108 USHORT ModifiedWriteCount;
02109 USHORT NumberOfSystemCacheViews;
02110 SIZE_T PagedPoolUsage;
02111 SIZE_T NonPagedPoolUsage;
02112 LIST_ENTRY UserGlobalList;
02113 ULONG SessionId;
02114 ULONG Pad;
02115 }
LARGE_CONTROL_AREA, *
PLARGE_CONTROL_AREA;
02116
02117 typedef struct _MMSUBSECTION_FLAGS {
02118
unsigned ReadOnly : 1;
02119 unsigned ReadWrite : 1;
02120 unsigned CopyOnWrite : 1;
02121 unsigned GlobalMemory: 1;
02122 unsigned Protection : 5;
02123 unsigned LargePages : 1;
02124 unsigned StartingSector4132 : 10;
02125
unsigned SectorEndOffset : 12;
02126 }
MMSUBSECTION_FLAGS;
02127
02128
typedef struct _SUBSECTION {
02129
PCONTROL_AREA ControlArea;
02130
union {
02131 ULONG LongFlags;
02132
MMSUBSECTION_FLAGS SubsectionFlags;
02133 } u;
02134 ULONG StartingSector;
02135 ULONG NumberOfFullSectors;
02136
PMMPTE SubsectionBase;
02137 ULONG UnusedPtes;
02138 ULONG PtesInSubsection;
02139
struct _SUBSECTION *NextSubsection;
02140 }
SUBSECTION, *
PSUBSECTION;
02141
02142
#define MI_MAXIMUM_SECTION_SIZE ((UINT64)16*1024*1024*1024*1024*1024 - (1<<MM4K_SHIFT))
02143
02144
#if DBG
02145
VOID
02146 MiSubsectionConsistent(
02147 IN PSUBSECTION Subsection
02148 );
02149
#endif
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
#define Mi4KStartForSubsection(address, subsection) \
02177
subsection->StartingSector = ((PLARGE_INTEGER)address)->LowPart; \
02178
subsection->u.SubsectionFlags.StartingSector4132 = \
02179
(((PLARGE_INTEGER)(address))->HighPart & 0x3ff);
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
#define Mi4KStartFromSubsection(address, subsection) \
02206
((PLARGE_INTEGER)address)->LowPart = subsection->StartingSector; \
02207
((PLARGE_INTEGER)address)->HighPart = subsection->u.SubsectionFlags.StartingSector4132;
02208
02209 typedef struct _MMDEREFERENCE_SEGMENT_HEADER {
02210 KSPIN_LOCK Lock;
02211 KSEMAPHORE Semaphore;
02212 LIST_ENTRY ListHead;
02213 }
MMDEREFERENCE_SEGMENT_HEADER;
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
typedef struct _MMPAGE_FILE_EXPANSION {
02225 PSEGMENT Segment;
02226 LIST_ENTRY DereferenceList;
02227 SIZE_T RequestedExpansionSize;
02228 SIZE_T ActualExpansion;
02229
KEVENT Event;
02230 ULONG InProgress;
02231 ULONG PageFileNumber;
02232 }
MMPAGE_FILE_EXPANSION, *
PMMPAGE_FILE_EXPANSION;
02233
02234 #define MI_EXTEND_ANY_PAGEFILE ((ULONG)-1)
02235
02236
typedef struct _MMWORKING_SET_EXPANSION_HEAD {
02237 LIST_ENTRY ListHead;
02238 }
MMWORKING_SET_EXPANSION_HEAD;
02239
02240 #define SUBSECTION_READ_ONLY 1L
02241 #define SUBSECTION_READ_WRITE 2L
02242
#define SUBSECTION_COPY_ON_WRITE 4L
02243
#define SUBSECTION_SHARE_ALLOW 8L
02244
02245
typedef struct _MMFLUSH_BLOCK {
02246 LARGE_INTEGER ErrorOffset;
02247 IO_STATUS_BLOCK IoStatus;
02248
KEVENT IoEvent;
02249 ULONG IoCount;
02250 }
MMFLUSH_BLOCK, *
PMMFLUSH_BLOCK;
02251
02252 typedef struct _MMINPAGE_SUPPORT {
02253 KEVENT Event;
02254 IO_STATUS_BLOCK
IoStatus;
02255 LARGE_INTEGER
ReadOffset;
02256 ULONG
WaitCount;
02257
#if defined (_WIN64)
02258
ULONG UsedPageTableEntries;
02259
#endif
02260
union {
02261
PETHREAD Thread;
02262
PMMFLUSH_BLOCK Flush;
02263 } u;
02264
PFILE_OBJECT FilePointer;
02265 PMMPTE BasePte;
02266 PMMPFN Pfn;
02267 LOGICAL Completed;
02268 MDL Mdl;
02269 PFN_NUMBER Page[
MM_MAXIMUM_READ_CLUSTER_SIZE + 1];
02270 LIST_ENTRY ListEntry;
02271 #if defined (_PREFETCH_)
02272
PMDL PrefetchMdl;
02273
#endif
02274
}
MMINPAGE_SUPPORT, *
PMMINPAGE_SUPPORT;
02275
02276
#if defined (_PREFETCH_)
02277
#define MI_PF_DUMMY_PAGE_PTE ((PMMPTE)0x23452345)
02278 #endif
02279
02280 typedef struct _MMPAGE_READ {
02281 LARGE_INTEGER ReadOffset;
02282 PFILE_OBJECT FilePointer;
02283 PMMPTE BasePte;
02284
PMMPFN Pfn;
02285
MDL Mdl;
02286 PFN_NUMBER Page[
MM_MAXIMUM_READ_CLUSTER_SIZE + 1];
02287 }
MMPAGE_READ, *
PMMPAGE_READ;
02288
02289
02290
02291
02292
02293
typedef struct _MMADDRESS_NODE {
02294 ULONG_PTR StartingVpn;
02295 ULONG_PTR EndingVpn;
02296
struct _MMADDRESS_NODE *Parent;
02297
struct _MMADDRESS_NODE *LeftChild;
02298
struct _MMADDRESS_NODE *RightChild;
02299 }
MMADDRESS_NODE, *
PMMADDRESS_NODE;
02300
02301
typedef struct _SECTION {
02302
MMADDRESS_NODE Address;
02303 PSEGMENT Segment;
02304 LARGE_INTEGER SizeOfSection;
02305 union {
02306 ULONG LongFlags;
02307 MMSECTION_FLAGS Flags;
02308 } u;
02309 ULONG InitialPageProtection;
02310 }
SECTION, *
PSECTION;
02311
02312
02313
02314
02315
02316
02317
02318
typedef struct _MMBANKED_SECTION {
02319 PFN_NUMBER
BasePhysicalPage;
02320
PMMPTE BasedPte;
02321 ULONG
BankSize;
02322 ULONG
BankShift;
02323
PBANKED_SECTION_ROUTINE BankedRoutine;
02324 PVOID
Context;
02325
PMMPTE CurrentMappedPte;
02326
MMPTE BankTemplate[1];
02327 }
MMBANKED_SECTION, *
PMMBANKED_SECTION;
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
#if defined (_WIN64)
02338
02339
#define COMMIT_SIZE 51
02340
02341 #if ((COMMIT_SIZE + PAGE_SHIFT) < 63)
02342
#error COMMIT_SIZE too small
02343 #endif
02344
02345 #else
02346 #define COMMIT_SIZE 19
02347
02348 #if ((COMMIT_SIZE + PAGE_SHIFT) < 31)
02349 #error COMMIT_SIZE too small
02350 #endif
02351 #endif
02352
02353 #define MM_MAX_COMMIT (((ULONG_PTR) 1 << COMMIT_SIZE) - 1)
02354
02355
#define MM_VIEW_UNMAP 0
02356 #define MM_VIEW_SHARE 1
02357
02358 typedef struct _MMVAD_FLAGS {
02359 ULONG_PTR CommitCharge :
COMMIT_SIZE;
02360 ULONG_PTR PhysicalMapping : 1;
02361 ULONG_PTR ImageMap : 1;
02362 ULONG_PTR UserPhysicalPages : 1;
02363 ULONG_PTR NoChange : 1;
02364 ULONG_PTR WriteWatch : 1;
02365 ULONG_PTR Protection : 5;
02366 ULONG_PTR LargePages : 1;
02367 ULONG_PTR MemCommit: 1;
02368 ULONG_PTR PrivateMemory : 1;
02369 }
MMVAD_FLAGS;
02370
02371
typedef struct _MMVAD_FLAGS2 {
02372
unsigned FileOffset : 24;
02373 unsigned SecNoChange : 1;
02374
unsigned OneSecured : 1;
02375 unsigned MultipleSecured : 1;
02376 unsigned ReadOnly : 1;
02377
unsigned StoredInVad : 1;
02378 unsigned ExtendableFile : 1;
02379 unsigned Inherit : 1;
02380 unsigned CopyOnWrite : 1;
02381 }
MMVAD_FLAGS2;
02382
02383 typedef struct _MMADDRESS_LIST {
02384 ULONG_PTR StartVpn;
02385 ULONG_PTR EndVpn;
02386 }
MMADDRESS_LIST, *
PMMADDRESS_LIST;
02387
02388 typedef struct _MMSECURE_ENTRY {
02389
union {
02390 ULONG_PTR LongFlags2;
02391 MMVAD_FLAGS2 VadFlags2;
02392 } u2;
02393 ULONG_PTR StartVpn;
02394 ULONG_PTR EndVpn;
02395 LIST_ENTRY List;
02396 }
MMSECURE_ENTRY, *
PMMSECURE_ENTRY;
02397
02398 typedef struct _MMVAD {
02399 ULONG_PTR
StartingVpn;
02400 ULONG_PTR
EndingVpn;
02401 struct _MMVAD *
Parent;
02402 struct _MMVAD *
LeftChild;
02403
struct _MMVAD *
RightChild;
02404
union {
02405 ULONG_PTR LongFlags;
02406 MMVAD_FLAGS VadFlags;
02407 } u;
02408
PCONTROL_AREA ControlArea;
02409
PMMPTE FirstPrototypePte;
02410
PMMPTE LastContiguousPte;
02411 union {
02412 ULONG LongFlags2;
02413 MMVAD_FLAGS2 VadFlags2;
02414 } u2;
02415 union {
02416 LIST_ENTRY List;
02417
MMADDRESS_LIST Secured;
02418 } u3;
02419 union {
02420
PMMBANKED_SECTION Banked;
02421
PMMEXTEND_INFO ExtendedInfo;
02422 } u4;
02423 }
MMVAD, *
PMMVAD;
02424
02425
02426 typedef struct _MMVAD_SHORT {
02427 ULONG_PTR StartingVpn;
02428 ULONG_PTR EndingVpn;
02429 struct _MMVAD *Parent;
02430 struct _MMVAD *LeftChild;
02431
struct _MMVAD *RightChild;
02432
union {
02433 ULONG_PTR LongFlags;
02434 MMVAD_FLAGS VadFlags;
02435 } u;
02436 }
MMVAD_SHORT, *
PMMVAD_SHORT;
02437
02438
#define MI_GET_PROTECTION_FROM_VAD(_Vad) ((ULONG)(_Vad)->u.VadFlags.Protection)
02439
02440 typedef struct _MI_PHYSICAL_VIEW {
02441 LIST_ENTRY ListEntry;
02442
PMMVAD Vad;
02443 PCHAR StartVa;
02444 PCHAR EndVa;
02445 PRTL_BITMAP
BitMap;
02446 }
MI_PHYSICAL_VIEW, *
PMI_PHYSICAL_VIEW;
02447
02448
#define MI_PHYSICAL_VIEW_KEY 'vpmM'
02449
#define MI_WRITEWATCH_VIEW_KEY 'wWmM'
02450
02451
02452
02453
02454
02455
extern ULONG_PTR
MiActiveWriteWatch;
02456
02457
VOID
02458 MiCaptureWriteWatchDirtyBit (
02459 IN
PEPROCESS Process,
02460 IN PVOID VirtualAddress
02461 );
02462
02463 VOID
02464
MiMarkProcessAsWriteWatch (
02465 IN
PEPROCESS Process
02466 );
02467
02468
02469
02470
02471
02472
02473 typedef struct _MMCLONE_BLOCK {
02474 MMPTE ProtoPte;
02475 LONG CloneRefCount;
02476 }
MMCLONE_BLOCK;
02477
02478 typedef MMCLONE_BLOCK *
PMMCLONE_BLOCK;
02479
02480 typedef struct _MMCLONE_HEADER {
02481 ULONG NumberOfPtes;
02482 ULONG NumberOfProcessReferences;
02483
PMMCLONE_BLOCK ClonePtes;
02484 }
MMCLONE_HEADER, *
PMMCLONE_HEADER;
02485
02486
02487
typedef struct _MMCLONE_DESCRIPTOR {
02488 ULONG_PTR StartingVpn;
02489 ULONG_PTR EndingVpn;
02490
struct _MMCLONE_DESCRIPTOR *Parent;
02491
struct _MMCLONE_DESCRIPTOR *LeftChild;
02492
struct _MMCLONE_DESCRIPTOR *RightChild;
02493
PMMCLONE_HEADER CloneHeader;
02494 ULONG NumberOfPtes;
02495 ULONG NumberOfReferences;
02496 SIZE_T PagedPoolQuotaCharge;
02497 }
MMCLONE_DESCRIPTOR, *
PMMCLONE_DESCRIPTOR;
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
#define MiCreateBitMap(BMH,S,P) { \
02512
ULONG _S; \
02513
_S = sizeof(RTL_BITMAP) + (ULONG)((((S) + 31) / 32) * 4); \
02514
*(BMH) = (PRTL_BITMAP)ExAllocatePoolWithTag( (P), _S, ' mM'); \
02515
if (*(BMH)) { \
02516
RtlInitializeBitMap( *(BMH), (PULONG)((*(BMH))+1), (ULONG)S); \
02517
} \
02518
}
02519
02520
#define MiRemoveBitMap(BMH) { \
02521
ExFreePool(*(BMH)); \
02522 *(BMH) = NULL; \
02523 }
02524
02525
#define MI_INITIALIZE_ZERO_MDL(MDL) { \
02526
MDL->Next = (PMDL) NULL; \
02527 MDL->MdlFlags = 0; \
02528 MDL->StartVa = NULL; \
02529 MDL->ByteOffset = 0; \
02530
MDL->ByteCount = 0; \
02531 }
02532
02533
02534
02535
02536
02537 typedef struct _MMMOD_WRITER_LISTHEAD {
02538 LIST_ENTRY ListHead;
02539 KEVENT Event;
02540 }
MMMOD_WRITER_LISTHEAD, *
PMMMOD_WRITER_LISTHEAD;
02541
02542 typedef struct _MMMOD_WRITER_MDL_ENTRY {
02543 LIST_ENTRY
Links;
02544 LARGE_INTEGER
WriteOffset;
02545
union {
02546 IO_STATUS_BLOCK
IoStatus;
02547 LARGE_INTEGER LastByte;
02548 } u;
02549 PIRP Irp;
02550 ULONG_PTR LastPageToWrite;
02551 PMMMOD_WRITER_LISTHEAD PagingListHead;
02552 PLIST_ENTRY CurrentList;
02553 struct _MMPAGING_FILE *PagingFile;
02554 PFILE_OBJECT File;
02555 PCONTROL_AREA ControlArea;
02556 PERESOURCE FileResource;
02557 MDL Mdl;
02558 PFN_NUMBER Page[1];
02559 }
MMMOD_WRITER_MDL_ENTRY, *
PMMMOD_WRITER_MDL_ENTRY;
02560
02561
02562 #define MM_PAGING_FILE_MDLS 2
02563
02564 typedef struct _MMPAGING_FILE {
02565 PFN_NUMBER
Size;
02566 PFN_NUMBER
MaximumSize;
02567 PFN_NUMBER MinimumSize;
02568 PFN_NUMBER FreeSpace;
02569 PFN_NUMBER CurrentUsage;
02570 PFN_NUMBER PeakUsage;
02571 PFN_NUMBER Hint;
02572 PFN_NUMBER HighestPage;
02573 PMMMOD_WRITER_MDL_ENTRY Entry[
MM_PAGING_FILE_MDLS];
02574 PRTL_BITMAP Bitmap;
02575
PFILE_OBJECT File;
02576 UNICODE_STRING PageFileName;
02577 ULONG PageFileNumber;
02578 BOOLEAN Extended;
02579 BOOLEAN HintSetToZero;
02580 }
MMPAGING_FILE, *
PMMPAGING_FILE;
02581
02582
typedef struct _MMINPAGE_SUPPORT_LIST {
02583 LIST_ENTRY ListHead;
02584 ULONG Count;
02585 }
MMINPAGE_SUPPORT_LIST, *
PMMINPAGE_SUPPORT_LIST;
02586
02587
typedef struct _MMEVENT_COUNT_LIST {
02588 LIST_ENTRY ListHead;
02589 ULONG Count;
02590 }
MMEVENT_COUNT_LIST, *
PMMEVENT_COUNT_LIST;
02591
02592
02593
02594
02595
02596
#define MM_SYS_PTE_TABLES_MAX 5
02597
02598 typedef enum _MMSYSTEM_PTE_POOL_TYPE {
02599 SystemPteSpace,
02600
NonPagedPoolExpansion,
02601
MaximumPtePoolTypes
02602 }
MMSYSTEM_PTE_POOL_TYPE;
02603
02604
typedef struct _MMFREE_POOL_ENTRY {
02605 LIST_ENTRY List;
02606 PFN_NUMBER
Size;
02607 ULONG Signature;
02608 struct _MMFREE_POOL_ENTRY *Owner;
02609 }
MMFREE_POOL_ENTRY, *
PMMFREE_POOL_ENTRY;
02610
02611
02612
typedef struct _MMLOCK_CONFLICT {
02613 LIST_ENTRY List;
02614
PETHREAD Thread;
02615 }
MMLOCK_CONFLICT, *
PMMLOCK_CONFLICT;
02616
02617
02618
02619
02620
02621
typedef struct _MMVIEW {
02622 ULONG_PTR Entry;
02623
PCONTROL_AREA ControlArea;
02624 }
MMVIEW, *
PMMVIEW;
02625
02626
02627
02628
02629
02630
02631
02632 typedef struct _MMSESSION {
02633
02634
02635
02636
02637
02638
02639
FAST_MUTEX SystemSpaceViewLock;
02640
02641
02642
02643
02644
02645
02646
02647 PFAST_MUTEX SystemSpaceViewLockPointer;
02648 PCHAR SystemSpaceViewStart;
02649
PMMVIEW SystemSpaceViewTable;
02650 ULONG SystemSpaceHashSize;
02651 ULONG SystemSpaceHashEntries;
02652 ULONG SystemSpaceHashKey;
02653 PRTL_BITMAP SystemSpaceBitMap;
02654
02655 }
MMSESSION, *
PMMSESSION;
02656
02657 extern MMSESSION MmSession;
02658
02659
#define LOCK_SYSTEM_VIEW_SPACE(_Session) \
02660 ExAcquireFastMutex (_Session->SystemSpaceViewLockPointer)
02661
02662 #define UNLOCK_SYSTEM_VIEW_SPACE(_Session) \
02663 ExReleaseFastMutex (_Session->SystemSpaceViewLockPointer)
02664
02665
02666
02667
02668
02669 typedef struct _MMPTE_FLUSH_LIST {
02670 ULONG Count;
02671 PMMPTE FlushPte[
MM_MAXIMUM_FLUSH_COUNT];
02672 PVOID FlushVa[
MM_MAXIMUM_FLUSH_COUNT];
02673 }
MMPTE_FLUSH_LIST, *
PMMPTE_FLUSH_LIST;
02674
02675 typedef struct _LOCK_TRACKER {
02676 LIST_ENTRY ListEntry;
02677
PMDL Mdl;
02678 PVOID StartVa;
02679 PFN_NUMBER Count;
02680 ULONG Offset;
02681 ULONG Length;
02682 PFN_NUMBER Page;
02683 PVOID CallingAddress;
02684 PVOID CallersCaller;
02685 LIST_ENTRY GlobalListEntry;
02686 ULONG Who;
02687 PEPROCESS Process;
02688 }
LOCK_TRACKER, *
PLOCK_TRACKER;
02689
02690 extern LOGICAL
MmTrackLockedPages;
02691 extern BOOLEAN
MiTrackingAborted;
02692
02693
typedef struct _LOCK_HEADER {
02694 LIST_ENTRY ListHead;
02695 PFN_NUMBER Count;
02696 }
LOCK_HEADER, *
PLOCK_HEADER;
02697
02698
extern LOGICAL
MmSnapUnloads;
02699
02700
#define MI_UNLOADED_DRIVERS 50
02701
02702
typedef struct _UNLOADED_DRIVERS {
02703 UNICODE_STRING Name;
02704 PVOID StartAddress;
02705 PVOID EndAddress;
02706 LARGE_INTEGER CurrentTime;
02707 }
UNLOADED_DRIVERS, *
PUNLOADED_DRIVERS;
02708
02709
extern PUNLOADED_DRIVERS MiUnloadedDrivers;
02710
02711
VOID
02712
MiRemoveConflictFromList (
02713 IN PMMLOCK_CONFLICT Conflict
02714 );
02715
02716
VOID
02717
MiInsertConflictInList (
02718 IN PMMLOCK_CONFLICT Conflict
02719 );
02720
02721
02722
VOID
02723
MiInitMachineDependent (
02724 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02725 );
02726
02727
VOID
02728
MiBuildPagedPool (
02729 VOID
02730 );
02731
02732
VOID
02733
MiInitializeNonPagedPool (
02734 VOID
02735 );
02736
02737 BOOLEAN
02738
MiInitializeSystemSpaceMap (
02739 PVOID Session OPTIONAL
02740 );
02741
02742
VOID
02743
MiFindInitializationCode (
02744 OUT PVOID *StartVa,
02745 OUT PVOID *EndVa
02746 );
02747
02748
VOID
02749
MiFreeInitializationCode (
02750 IN PVOID StartVa,
02751 IN PVOID EndVa
02752 );
02753
02754
02755 ULONG
02756
MiSectionInitialization (
02757 VOID
02758 );
02759
02760
VOID
02761
FASTCALL
02762
MiDecrementReferenceCount (
02763 IN PFN_NUMBER PageFrameIndex
02764 );
02765
02766
VOID
02767
FASTCALL
02768
MiDecrementShareCount (
02769 IN PFN_NUMBER PageFrameIndex
02770 );
02771
02772
#define MiDecrementShareCountOnly(P) MiDecrementShareCount(P)
02773
02774
#define MiDecrementShareAndValidCount(P) MiDecrementShareCount(P)
02775
02776
02777
02778
02779
02780
VOID
02781
FASTCALL
02782
MiInsertPageInList (
02783 IN
PMMPFNLIST ListHead,
02784 IN PFN_NUMBER PageFrameIndex
02785 );
02786
02787
VOID
02788
FASTCALL
02789
MiInsertStandbyListAtFront (
02790 IN PFN_NUMBER PageFrameIndex
02791 );
02792
02793 PFN_NUMBER
02794
FASTCALL
02795
MiRemovePageFromList (
02796 IN
PMMPFNLIST ListHead
02797 );
02798
02799
VOID
02800
FASTCALL
02801
MiUnlinkPageFromList (
02802 IN PMMPFN Pfn
02803 );
02804
02805
VOID
02806
MiUnlinkFreeOrZeroedPage (
02807 IN PFN_NUMBER Page
02808 );
02809
02810
VOID
02811
FASTCALL
02812
MiInsertFrontModifiedNoWrite (
02813 IN PFN_NUMBER PageFrameIndex
02814 );
02815
02816 ULONG
02817
FASTCALL
02818
MiEnsureAvailablePageOrWait (
02819 IN
PEPROCESS Process,
02820 IN PVOID VirtualAddress
02821 );
02822
02823 PFN_NUMBER
02824
FASTCALL
02825
MiRemoveZeroPage (
02826 IN ULONG PageColor
02827 );
02828
02829
#define MiRemoveZeroPageIfAny(COLOR) \
02830
(MmFreePagesByColor[ZeroedPageList][COLOR].Flink != MM_EMPTY_LIST) ? \
02831
MiRemoveZeroPage(COLOR) : 0
02832
02833
02834 PFN_NUMBER
02835
FASTCALL
02836
MiRemoveAnyPage (
02837 IN ULONG PageColor
02838 );
02839
02840 PVOID
02841
MiFindContiguousMemory (
02842 IN PFN_NUMBER LowestPfn,
02843 IN PFN_NUMBER HighestPfn,
02844 IN PFN_NUMBER BoundaryPfn,
02845 IN PFN_NUMBER SizeInPages,
02846 IN PVOID CallingAddress
02847 );
02848
02849 PVOID
02850
MiCheckForContiguousMemory (
02851 IN PVOID BaseAddress,
02852 IN PFN_NUMBER BaseAddressPages,
02853 IN PFN_NUMBER SizeInPages,
02854 IN PFN_NUMBER LowestPfn,
02855 IN PFN_NUMBER HighestPfn,
02856 IN PFN_NUMBER BoundaryPfn
02857 );
02858
02859
02860
02861
02862
02863
VOID
02864
MiInitializePfn (
02865 IN PFN_NUMBER PageFrameIndex,
02866 IN
PMMPTE PointerPte,
02867 IN ULONG ModifiedState
02868 );
02869
02870
VOID
02871
MiInitializePfnForOtherProcess (
02872 IN PFN_NUMBER PageFrameIndex,
02873 IN
PMMPTE PointerPte,
02874 IN PFN_NUMBER ContainingPageFrame
02875 );
02876
02877
VOID
02878
MiInitializeCopyOnWritePfn (
02879 IN PFN_NUMBER PageFrameIndex,
02880 IN
PMMPTE PointerPte,
02881 IN WSLE_NUMBER WorkingSetIndex,
02882 IN PVOID SessionSpace
02883 );
02884
02885
VOID
02886
MiInitializeTransitionPfn (
02887 IN PFN_NUMBER PageFrameIndex,
02888 IN
PMMPTE PointerPte,
02889 IN WSLE_NUMBER WorkingSetIndex
02890 );
02891
02892
VOID
02893
MiFlushInPageSupportBlock (
02894 );
02895
02896
VOID
02897
MiFreeInPageSupportBlock (
02898 IN PMMINPAGE_SUPPORT Support
02899 );
02900
02901
PMMINPAGE_SUPPORT
02902
MiGetInPageSupportBlock (
02903 VOID
02904 );
02905
02906
02907
02908
02909
02910
02911
VOID
02912
FASTCALL
02913
MiZeroPhysicalPage (
02914 IN PFN_NUMBER PageFrameIndex,
02915 IN ULONG Color
02916 );
02917
02918
VOID
02919
FASTCALL
02920
MiRestoreTransitionPte (
02921 IN PFN_NUMBER PageFrameIndex
02922 );
02923
02924
PSUBSECTION
02925
MiGetSubsectionAndProtoFromPte (
02926 IN
PMMPTE PointerPte,
02927 IN
PMMPTE *ProtoPte,
02928 IN
PEPROCESS Process
02929 );
02930
02931 PVOID
02932
MiMapPageInHyperSpace (
02933 IN PFN_NUMBER PageFrameIndex,
02934 OUT PKIRQL OldIrql
02935 );
02936
02937
#define MiUnmapPageInHyperSpace(OLDIRQL) UNLOCK_HYPERSPACE(OLDIRQL)
02938
02939
02940 PVOID
02941
MiMapImageHeaderInHyperSpace (
02942 IN PFN_NUMBER PageFrameIndex
02943 );
02944
02945
VOID
02946
MiUnmapImageHeaderInHyperSpace (
02947 VOID
02948 );
02949
02950
VOID
02951
MiUpdateImageHeaderPage (
02952 IN
PMMPTE PointerPte,
02953 IN PFN_NUMBER PageFrameNumber,
02954 IN PCONTROL_AREA ControlArea
02955 );
02956
02957 PFN_NUMBER
02958
MiGetPageForHeader (
02959 VOID
02960 );
02961
02962
VOID
02963
MiRemoveImageHeaderPage (
02964 IN PFN_NUMBER PageFrameNumber
02965 );
02966
02967 PVOID
02968
MiMapPageToZeroInHyperSpace (
02969 IN PFN_NUMBER PageFrameIndex
02970 );
02971
02972
02973
NTSTATUS
02974
MiGetWritablePagesInSection(
02975 IN PSECTION Section,
02976 OUT PULONG WritablePages
02977 );
02978
02979
02980
02981
02982
02983
PMMPTE
02984
MiReserveSystemPtes (
02985 IN ULONG NumberOfPtes,
02986 IN MMSYSTEM_PTE_POOL_TYPE SystemPteType,
02987 IN ULONG Alignment,
02988 IN ULONG Offset,
02989 IN ULONG BugCheckOnFailure
02990 );
02991
02992
VOID
02993
MiReleaseSystemPtes (
02994 IN
PMMPTE StartingPte,
02995 IN ULONG NumberOfPtes,
02996 IN MMSYSTEM_PTE_POOL_TYPE SystemPteType
02997 );
02998
02999
VOID
03000
MiInitializeSystemPtes (
03001 IN
PMMPTE StartingPte,
03002 IN ULONG NumberOfPtes,
03003 IN MMSYSTEM_PTE_POOL_TYPE SystemPteType
03004 );
03005
03006
VOID
03007
MiAddMappedPtes (
03008 IN
PMMPTE FirstPte,
03009 IN ULONG NumberOfPtes,
03010 IN PCONTROL_AREA ControlArea
03011 );
03012
03013
VOID
03014
MiInitializeIoTrackers (
03015 VOID
03016 );
03017
03018 PVOID
03019
MiMapSinglePage (
03020 IN PVOID VirtualAddress OPTIONAL,
03021 IN PFN_NUMBER PageFrameIndex,
03022 IN MEMORY_CACHING_TYPE CacheType,
03023 IN MM_PAGE_PRIORITY Priority
03024 );
03025
03026
VOID
03027
MiUnmapSinglePage (
03028 IN PVOID BaseAddress
03029 );
03030
03031
03032
03033
03034
03035
NTSTATUS
03036
MiDispatchFault (
03037 IN BOOLEAN StoreInstrution,
03038 IN PVOID VirtualAdress,
03039 IN
PMMPTE PointerPte,
03040 IN
PMMPTE PointerProtoPte,
03041 IN
PEPROCESS Process,
03042 OUT PLOGICAL ApcNeeded
03043 );
03044
03045
NTSTATUS
03046
MiResolveDemandZeroFault (
03047 IN PVOID VirtualAddress,
03048 IN
PMMPTE PointerPte,
03049 IN
PEPROCESS Process,
03050 IN ULONG PrototypePte
03051 );
03052
03053
NTSTATUS
03054
MiResolveTransitionFault (
03055 IN PVOID FaultingAddress,
03056 IN
PMMPTE PointerPte,
03057 IN
PEPROCESS Process,
03058 IN ULONG PfnLockHeld,
03059 OUT PLOGICAL ApcNeeded
03060 );
03061
03062
NTSTATUS
03063
MiResolvePageFileFault (
03064 IN PVOID FaultingAddress,
03065 IN
PMMPTE PointerPte,
03066 IN PMMINPAGE_SUPPORT *ReadBlock,
03067 IN
PEPROCESS Process
03068 );
03069
03070
NTSTATUS
03071
MiResolveProtoPteFault (
03072 IN BOOLEAN StoreInstruction,
03073 IN PVOID VirtualAddress,
03074 IN
PMMPTE PointerPte,
03075 IN
PMMPTE PointerProtoPte,
03076 IN PMMINPAGE_SUPPORT *ReadBlock,
03077 IN
PEPROCESS Process,
03078 OUT PLOGICAL ApcNeeded
03079 );
03080
03081
03082
NTSTATUS
03083
MiResolveMappedFileFault (
03084 IN PVOID FaultingAddress,
03085 IN
PMMPTE PointerPte,
03086 IN PMMINPAGE_SUPPORT *ReadBlock,
03087 IN
PEPROCESS Process
03088 );
03089
03090
VOID
03091
MiAddValidPageToWorkingSet (
03092 IN PVOID VirtualAddress,
03093 IN
PMMPTE PointerPte,
03094 IN PMMPFN Pfn1,
03095 IN ULONG WsleMask
03096 );
03097
03098
NTSTATUS
03099
MiWaitForInPageComplete (
03100 IN PMMPFN Pfn,
03101 IN
PMMPTE PointerPte,
03102 IN PVOID FaultingAddress,
03103 IN
PMMPTE PointerPteContents,
03104 IN PMMINPAGE_SUPPORT InPageSupport,
03105 IN
PEPROCESS CurrentProcess
03106 );
03107
03108
NTSTATUS
03109
FASTCALL
03110
MiCopyOnWrite (
03111 IN PVOID FaultingAddress,
03112 IN
PMMPTE PointerPte
03113 );
03114
03115
VOID
03116
MiSetDirtyBit (
03117 IN PVOID FaultingAddress,
03118 IN
PMMPTE PointerPte,
03119 IN ULONG PfnHeld
03120 );
03121
03122
VOID
03123
MiSetModifyBit (
03124 IN PMMPFN Pfn
03125 );
03126
03127
PMMPTE
03128
MiFindActualFaultingPte (
03129 IN PVOID FaultingAddress
03130 );
03131
03132
VOID
03133
MiInitializeReadInProgressPfn (
03134 IN
PMDL Mdl,
03135 IN
PMMPTE BasePte,
03136 IN
PKEVENT Event,
03137 IN WSLE_NUMBER WorkingSetIndex
03138 );
03139
03140
NTSTATUS
03141
MiAccessCheck (
03142 IN
PMMPTE PointerPte,
03143 IN BOOLEAN WriteOperation,
03144 IN KPROCESSOR_MODE PreviousMode,
03145 IN ULONG Protection,
03146 IN BOOLEAN CallerHoldsPfnLock
03147 );
03148
03149
NTSTATUS
03150
FASTCALL
03151
MiCheckForUserStackOverflow (
03152 IN PVOID FaultingAddress
03153 );
03154
03155
PMMPTE
03156
MiCheckVirtualAddress (
03157 IN PVOID VirtualAddress,
03158 OUT PULONG ProtectCode
03159 );
03160
03161
NTSTATUS
03162
FASTCALL
03163
MiCheckPdeForPagedPool (
03164 IN PVOID VirtualAddress
03165 );
03166
03167
VOID
03168
MiInitializeMustSucceedPool (
03169 VOID
03170 );
03171
03172
03173
03174
03175
03176
PMMADDRESS_NODE
03177
FASTCALL
03178
MiGetNextNode (
03179 IN PMMADDRESS_NODE Node
03180 );
03181
03182
PMMADDRESS_NODE
03183
FASTCALL
03184
MiGetPreviousNode (
03185 IN PMMADDRESS_NODE Node
03186 );
03187
03188
03189
PMMADDRESS_NODE
03190
FASTCALL
03191
MiGetFirstNode (
03192 IN PMMADDRESS_NODE Root
03193 );
03194
03195
PMMADDRESS_NODE
03196
MiGetLastNode (
03197 IN PMMADDRESS_NODE Root
03198 );
03199
03200
VOID
03201
FASTCALL
03202
MiInsertNode (
03203 IN PMMADDRESS_NODE Node,
03204 IN OUT PMMADDRESS_NODE *Root
03205 );
03206
03207
VOID
03208
FASTCALL
03209
MiRemoveNode (
03210 IN PMMADDRESS_NODE Node,
03211 IN OUT PMMADDRESS_NODE *Root
03212 );
03213
03214
PMMADDRESS_NODE
03215
FASTCALL
03216
MiLocateAddressInTree (
03217 IN ULONG_PTR Vpn,
03218 IN PMMADDRESS_NODE *Root
03219 );
03220
03221
PMMADDRESS_NODE
03222
MiCheckForConflictingNode (
03223 IN ULONG_PTR StartVpn,
03224 IN ULONG_PTR EndVpn,
03225 IN PMMADDRESS_NODE Root
03226 );
03227
03228 PVOID
03229
MiFindEmptyAddressRangeInTree (
03230 IN SIZE_T SizeOfRange,
03231 IN ULONG_PTR Alignment,
03232 IN PMMADDRESS_NODE Root,
03233 OUT PMMADDRESS_NODE *PreviousVad
03234 );
03235
03236 PVOID
03237
MiFindEmptyAddressRangeDownTree (
03238 IN SIZE_T SizeOfRange,
03239 IN PVOID HighestAddressToEndAt,
03240 IN ULONG_PTR Alignment,
03241 IN PMMADDRESS_NODE Root
03242 );
03243
03244
VOID
03245
NodeTreeWalk (
03246 PMMADDRESS_NODE Start
03247 );
03248
03249
03250
03251
03252
03253
VOID
03254
MiInsertVad (
03255 IN PMMVAD Vad
03256 );
03257
03258
VOID
03259
MiRemoveVad (
03260 IN PMMVAD Vad
03261 );
03262
03263
PMMVAD
03264
FASTCALL
03265
MiLocateAddress (
03266 IN PVOID Vad
03267 );
03268
03269 PVOID
03270
MiFindEmptyAddressRange (
03271 IN SIZE_T SizeOfRange,
03272 IN ULONG_PTR Alignment,
03273 IN ULONG QuickCheck
03274 );
03275
03276
03277
03278
03279
03280
03281
NTSTATUS
03282
MiCloneProcessAddressSpace (
03283 IN
PEPROCESS ProcessToClone,
03284 IN
PEPROCESS ProcessToInitialize,
03285 IN PFN_NUMBER PdePhysicalPage,
03286 IN PFN_NUMBER HyperPhysicalPage
03287 );
03288
03289
03290 ULONG
03291
MiDecrementCloneBlockReference (
03292 IN PMMCLONE_DESCRIPTOR CloneDescriptor,
03293 IN PMMCLONE_BLOCK CloneBlock,
03294 IN
PEPROCESS CurrentProcess
03295 );
03296
03297
VOID
03298
MiWaitForForkToComplete (
03299 IN
PEPROCESS CurrentProcess
03300 );
03301
03302
03303
03304
03305
03306
WSLE_NUMBER
03307
MiLocateAndReserveWsle (
03308 IN
PMMSUPPORT WsInfo
03309 );
03310
03311
VOID
03312
MiReleaseWsle (
03313 IN WSLE_NUMBER WorkingSetIndex,
03314 IN
PMMSUPPORT WsInfo
03315 );
03316
03317
VOID
03318
MiUpdateWsle (
03319 IN PWSLE_NUMBER DesiredIndex,
03320 IN PVOID VirtualAddress,
03321 IN PMMWSL WorkingSetList,
03322 IN PMMPFN Pfn
03323 );
03324
03325
VOID
03326
MiInitializeWorkingSetList (
03327 IN
PEPROCESS CurrentProcess
03328 );
03329
03330
VOID
03331
MiGrowWsleHash (
03332 IN
PMMSUPPORT WsInfo
03333 );
03334
03335 ULONG
03336
MiTrimWorkingSet (
03337 ULONG Reduction,
03338 IN
PMMSUPPORT WsInfo,
03339 IN ULONG ForcedReduction
03340 );
03341
03342
VOID
03343
MiRemoveWorkingSetPages (
03344 IN PMMWSL WorkingSetList,
03345 IN
PMMSUPPORT WsInfo
03346 );
03347
03348
#ifdef _MI_USE_CLAIMS_
03349
VOID
03350 MiAgeAndEstimateAvailableInWorkingSet(
03351 IN
PMMSUPPORT VmSupport,
03352 IN BOOLEAN DoAging,
03353 IN OUT PULONG TotalClaim,
03354 IN OUT PULONG TotalEstimatedAvailable
03355 );
03356
#endif
03357
03358
VOID
03359
FASTCALL
03360
MiInsertWsle (
03361 IN WSLE_NUMBER Entry,
03362 IN PMMWSL WorkingSetList
03363 );
03364
03365
VOID
03366
FASTCALL
03367
MiRemoveWsle (
03368 IN WSLE_NUMBER Entry,
03369 IN PMMWSL WorkingSetList
03370 );
03371
03372
VOID
03373
MiFreeWorkingSetRange (
03374 IN PVOID StartVa,
03375 IN PVOID EndVa,
03376 IN
PMMSUPPORT WsInfo
03377 );
03378
03379
WSLE_NUMBER
03380
FASTCALL
03381
MiLocateWsle (
03382 IN PVOID VirtualAddress,
03383 IN PMMWSL WorkingSetList,
03384 IN WSLE_NUMBER WsPfnIndex
03385 );
03386
03387 ULONG
03388
MiFreeWsle (
03389 IN WSLE_NUMBER WorkingSetIndex,
03390 IN
PMMSUPPORT WsInfo,
03391 IN
PMMPTE PointerPte
03392 );
03393
03394
VOID
03395
MiSwapWslEntries (
03396 IN WSLE_NUMBER SwapEntry,
03397 IN WSLE_NUMBER Entry,
03398 IN
PMMSUPPORT WsInfo
03399 );
03400
03401
VOID
03402
MiRemoveWsleFromFreeList (
03403 IN ULONG Entry,
03404 IN PMMWSLE Wsle,
03405 IN PMMWSL WorkingSetList
03406 );
03407
03408 ULONG
03409
MiRemovePageFromWorkingSet (
03410 IN
PMMPTE PointerPte,
03411 IN PMMPFN Pfn1,
03412 IN
PMMSUPPORT WsInfo
03413 );
03414
03415
VOID
03416
MiTakePageFromWorkingSet (
03417 IN ULONG Entry,
03418 IN
PMMSUPPORT WsInfo,
03419 IN
PMMPTE PointerPte
03420 );
03421
03422 PFN_NUMBER
03423
MiDeleteSystemPagableVm (
03424 IN
PMMPTE PointerPte,
03425 IN PFN_NUMBER NumberOfPtes,
03426 IN
MMPTE NewPteValue,
03427 IN LOGICAL SessionAllocation,
03428 OUT PPFN_NUMBER ResidentPages OPTIONAL
03429 );
03430
03431
VOID
03432
MiLockCode (
03433 IN
PMMPTE FirstPte,
03434 IN
PMMPTE LastPte,
03435 IN ULONG LockType
03436 );
03437
03438 PLDR_DATA_TABLE_ENTRY
03439
MiLookupDataTableEntry (
03440 IN PVOID AddressWithinSection,
03441 IN ULONG ResourceHeld
03442 );
03443
03444
VOID
03445
MiFlushTb (
03446 VOID
03447 );
03448
03449
03450
03451
03452
03453
VOID
03454
MiObtainFreePages (
03455 VOID
03456 );
03457
03458
VOID
03459
MiModifiedPageWriter (
03460 IN PVOID StartContext
03461 );
03462
03463
VOID
03464
MiMappedPageWriter (
03465 IN PVOID StartContext
03466 );
03467
03468 LOGICAL
03469
MiIssuePageExtendRequest (
03470 IN PMMPAGE_FILE_EXPANSION PageExtend
03471 );
03472
03473
VOID
03474
MiIssuePageExtendRequestNoWait (
03475 IN PFN_NUMBER SizeInPages
03476 );
03477
03478 SIZE_T
03479
MiExtendPagingFiles (
03480 IN PMMPAGE_FILE_EXPANSION PageExpand
03481 );
03482
03483
VOID
03484
MiContractPagingFiles (
03485 VOID
03486 );
03487
03488
VOID
03489
MiAttemptPageFileReduction (
03490 VOID
03491 );
03492
03493 LOGICAL
03494
MiCancelWriteOfMappedPfn (
03495 IN PFN_NUMBER PageToStop
03496 );
03497
03498
03499
03500
03501
03502
VOID
03503
MiDeleteVirtualAddresses (
03504 IN PUCHAR StartingAddress,
03505 IN PUCHAR EndingAddress,
03506 IN ULONG AddressSpaceDeletion,
03507 IN PMMVAD Vad
03508 );
03509
03510
VOID
03511
MiDeletePte (
03512 IN
PMMPTE PointerPte,
03513 IN PVOID VirtualAddress,
03514 IN ULONG AddressSpaceDeletion,
03515 IN
PEPROCESS CurrentProcess,
03516 IN
PMMPTE PrototypePte,
03517 IN PMMPTE_FLUSH_LIST PteFlushList OPTIONAL
03518 );
03519
03520
VOID
03521
MiDeletePageTablesForPhysicalRange (
03522 IN PVOID StartingAddress,
03523 IN PVOID EndingAddress
03524 );
03525
03526
VOID
03527
MiFlushPteList (
03528 IN PMMPTE_FLUSH_LIST PteFlushList,
03529 IN ULONG AllProcessors,
03530 IN
MMPTE FillPte
03531 );
03532
03533
03534 ULONG
03535
FASTCALL
03536
MiReleasePageFileSpace (
03537 IN
MMPTE PteContents
03538 );
03539
03540
VOID
03541
FASTCALL
03542
MiUpdateModifiedWriterMdls (
03543 IN ULONG PageFileNumber
03544 );
03545
03546
VOID
03547
MiRemoveUserPhysicalPagesVad (
03548 IN PMMVAD_SHORT FoundVad
03549 );
03550
03551
VOID
03552
MiCleanPhysicalProcessPages (
03553 IN
PEPROCESS Process
03554 );
03555
03556
VOID
03557
MiPhysicalViewRemover (
03558 IN
PEPROCESS Process,
03559 IN PMMVAD Vad
03560 );
03561
03562
VOID
03563
MiPhysicalViewAdjuster (
03564 IN
PEPROCESS Process,
03565 IN PMMVAD OldVad,
03566 IN PMMVAD NewVad
03567 );
03568
03569
03570
03571
03572
03573 ULONG
03574
MiDoesPdeExistAndMakeValid (
03575 IN
PMMPTE PointerPde,
03576 IN
PEPROCESS TargetProcess,
03577 IN ULONG PfnMutexHeld,
03578 OUT PULONG Waited
03579 );
03580
03581
#if defined (_WIN64)
03582
LOGICAL
03583
MiDoesPpeExistAndMakeValid (
03584 IN
PMMPTE PointerPpe,
03585 IN
PEPROCESS TargetProcess,
03586 IN ULONG PfnMutexHeld,
03587 OUT PULONG Waited
03588 );
03589
#endif
03590
03591 ULONG
03592
MiMakePdeExistAndMakeValid (
03593 IN
PMMPTE PointerPde,
03594 IN
PEPROCESS TargetProcess,
03595 IN ULONG PfnMutexHeld
03596 );
03597
03598
#if defined (_WIN64)
03599
ULONG
03600
MiMakePpeExistAndMakeValid (
03601 IN
PMMPTE PointerPde,
03602 IN
PEPROCESS TargetProcess,
03603 IN ULONG PfnMutexHeld
03604 );
03605
#else
03606
#define MiMakePpeExistAndMakeValid(PDE, PROCESS, PFNMUTEXHELD)
03607
#endif
03608
03609 ULONG
03610
FASTCALL
03611
MiMakeSystemAddressValid (
03612 IN PVOID VirtualAddress,
03613 IN
PEPROCESS CurrentProcess
03614 );
03615
03616 ULONG
03617
FASTCALL
03618
MiMakeSystemAddressValidPfnWs (
03619 IN PVOID VirtualAddress,
03620 IN
PEPROCESS CurrentProcess OPTIONAL
03621 );
03622
03623 ULONG
03624
FASTCALL
03625
MiMakeSystemAddressValidPfnSystemWs (
03626 IN PVOID VirtualAddress
03627 );
03628
03629 ULONG
03630
FASTCALL
03631
MiMakeSystemAddressValidPfn (
03632 IN PVOID VirtualAddress
03633 );
03634
03635 ULONG
03636
FASTCALL
03637
MiLockPagedAddress (
03638 IN PVOID VirtualAddress,
03639 IN ULONG PfnLockHeld
03640 );
03641
03642
VOID
03643
FASTCALL
03644
MiUnlockPagedAddress (
03645 IN PVOID VirtualAddress,
03646 IN ULONG PfnLockHeld
03647 );
03648
03649 ULONG
03650
FASTCALL
03651
MiIsPteDecommittedPage (
03652 IN
PMMPTE PointerPte
03653 );
03654
03655 ULONG
03656
FASTCALL
03657
MiIsProtectionCompatible (
03658 IN ULONG OldProtect,
03659 IN ULONG NewProtect
03660 );
03661
03662 ULONG
03663
FASTCALL
03664
MiMakeProtectionMask (
03665 IN ULONG Protect
03666 );
03667
03668 ULONG
03669
MiIsEntireRangeCommitted (
03670 IN PVOID StartingAddress,
03671 IN PVOID EndingAddress,
03672 IN PMMVAD Vad,
03673 IN
PEPROCESS Process
03674 );
03675
03676 ULONG
03677
MiIsEntireRangeDecommitted (
03678 IN PVOID StartingAddress,
03679 IN PVOID EndingAddress,
03680 IN PMMVAD Vad,
03681 IN
PEPROCESS Process
03682 );
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
#define MiGetProtoPteAddress(VAD,VPN) \
03712
((((((VPN) - (VAD)->StartingVpn) << PTE_SHIFT) + \
03713
(ULONG_PTR)(VAD)->FirstPrototypePte) <= (ULONG_PTR)(VAD)->LastContiguousPte) ? \
03714
((PMMPTE)(((((VPN) - (VAD)->StartingVpn) << PTE_SHIFT) + \
03715
(ULONG_PTR)(VAD)->FirstPrototypePte))) : \
03716
MiGetProtoPteAddressExtended ((VAD),(VPN)))
03717
03718
PMMPTE
03719
FASTCALL
03720
MiGetProtoPteAddressExtended (
03721 IN PMMVAD Vad,
03722 IN ULONG_PTR Vpn
03723 );
03724
03725
PSUBSECTION
03726
FASTCALL
03727
MiLocateSubsection (
03728 IN PMMVAD Vad,
03729 IN ULONG_PTR Vpn
03730 );
03731
03732
VOID
03733
MiInitializeSystemCache (
03734 IN ULONG MinimumWorkingSet,
03735 IN ULONG MaximumWorkingSet
03736 );
03737
03738
VOID
03739
MiAdjustWorkingSetManagerParameters(
03740 BOOLEAN WorkStation
03741 );
03742
03743
03744
03745
03746
03747
VOID
03748
FASTCALL
03749
MiInsertBasedSection (
03750 IN PSECTION Section
03751 );
03752
03753
NTSTATUS
03754
MiMapViewOfPhysicalSection (
03755 IN PCONTROL_AREA ControlArea,
03756 IN
PEPROCESS Process,
03757 IN PVOID *CapturedBase,
03758 IN PLARGE_INTEGER SectionOffset,
03759 IN PSIZE_T CapturedViewSize,
03760 IN ULONG ProtectionMask,
03761 IN ULONG_PTR ZeroBits,
03762 IN ULONG AllocationType,
03763 IN BOOLEAN WriteCombined,
03764 OUT PBOOLEAN ReleasedWsMutex
03765 );
03766
03767
VOID
03768
MiRemoveImageSectionObject(
03769 IN
PFILE_OBJECT File,
03770 IN PCONTROL_AREA ControlArea
03771 );
03772
03773
VOID
03774
MiAddSystemPtes(
03775 IN
PMMPTE StartingPte,
03776 IN ULONG NumberOfPtes,
03777 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
03778 );
03779
03780
VOID
03781
MiRemoveMappedView (
03782 IN
PEPROCESS CurrentProcess,
03783 IN PMMVAD Vad
03784 );
03785
03786 PVOID
03787
MiFindEmptySectionBaseDown (
03788 IN ULONG SizeOfRange,
03789 IN PVOID HighestAddressToEndAt
03790 );
03791
03792
VOID
03793
MiSegmentDelete (
03794 PSEGMENT Segment
03795 );
03796
03797
VOID
03798
MiSectionDelete (
03799 PVOID Object
03800 );
03801
03802
VOID
03803
MiDereferenceSegmentThread (
03804 IN PVOID StartContext
03805 );
03806
03807
NTSTATUS
03808
MiCreateImageFileMap (
03809 IN
PFILE_OBJECT File,
03810 OUT PSEGMENT *Segment
03811 );
03812
03813
NTSTATUS
03814
MiCreateDataFileMap (
03815 IN
PFILE_OBJECT File,
03816 OUT PSEGMENT *Segment,
03817 IN PUINT64 MaximumSize,
03818 IN ULONG SectionPageProtection,
03819 IN ULONG AllocationAttributes,
03820 IN ULONG IgnoreFileSizing
03821 );
03822
03823
NTSTATUS
03824
MiCreatePagingFileMap (
03825 OUT PSEGMENT *Segment,
03826 IN PUINT64 MaximumSize,
03827 IN ULONG ProtectionMask,
03828 IN ULONG AllocationAttributes
03829 );
03830
03831
VOID
03832
MiPurgeSubsectionInternal (
03833 IN PSUBSECTION Subsection,
03834 IN ULONG PteOffset
03835 );
03836
03837
VOID
03838
MiPurgeImageSection (
03839 IN PCONTROL_AREA ControlArea,
03840 IN
PEPROCESS Process
03841 );
03842
03843
VOID
03844
MiCleanSection (
03845 IN PCONTROL_AREA ControlArea,
03846 IN LOGICAL DirtyDataPagesOk
03847 );
03848
03849
VOID
03850
MiCheckControlArea (
03851 IN PCONTROL_AREA ControlArea,
03852 IN
PEPROCESS CurrentProcess,
03853 IN KIRQL PreviousIrql
03854 );
03855
03856 LOGICAL
03857
MiCheckPurgeAndUpMapCount (
03858 IN PCONTROL_AREA ControlArea
03859 );
03860
03861
VOID
03862
MiCheckForControlAreaDeletion (
03863 IN PCONTROL_AREA ControlArea
03864 );
03865
03866 BOOLEAN
03867
MiCheckControlAreaStatus (
03868 IN SECTION_CHECK_TYPE SectionCheckType,
03869 IN
PSECTION_OBJECT_POINTERS SectionObjectPointers,
03870 IN ULONG DelayClose,
03871 OUT PCONTROL_AREA *ControlArea,
03872 OUT PKIRQL OldIrql
03873 );
03874
03875
PEVENT_COUNTER
03876
MiGetEventCounter (
03877 );
03878
03879
VOID
03880
MiFlushEventCounter (
03881 );
03882
03883
VOID
03884
MiFreeEventCounter (
03885 IN PEVENT_COUNTER Support,
03886 IN ULONG Flush
03887 );
03888
03889 ULONG
03890
MiCanFileBeTruncatedInternal (
03891 IN
PSECTION_OBJECT_POINTERS SectionPointer,
03892 IN PLARGE_INTEGER NewFileSize OPTIONAL,
03893 IN LOGICAL BlockNewViews,
03894 OUT PKIRQL PreviousIrql
03895 );
03896
03897
#define STATUS_MAPPED_WRITER_COLLISION (0xC0033333)
03898
03899
NTSTATUS
03900
MiFlushSectionInternal (
03901 IN
PMMPTE StartingPte,
03902 IN
PMMPTE FinalPte,
03903 IN PSUBSECTION FirstSubsection,
03904 IN PSUBSECTION LastSubsection,
03905 IN ULONG Synchronize,
03906 IN LOGICAL WriteInProgressOk,
03907 OUT PIO_STATUS_BLOCK IoStatus
03908 );
03909
03910
03911
03912
03913
03914
NTSTATUS
03915
MiProtectVirtualMemory (
03916 IN
PEPROCESS Process,
03917 IN PVOID *CapturedBase,
03918 IN PSIZE_T CapturedRegionSize,
03919 IN ULONG Protect,
03920 IN PULONG LastProtect
03921 );
03922
03923 ULONG
03924
MiGetPageProtection (
03925 IN
PMMPTE PointerPte,
03926 IN
PEPROCESS Process
03927 );
03928
03929 ULONG
03930
MiSetProtectionOnSection (
03931 IN
PEPROCESS Process,
03932 IN PMMVAD Vad,
03933 IN PVOID StartingAddress,
03934 IN PVOID EndingAddress,
03935 IN ULONG NewProtect,
03936 OUT PULONG CapturedOldProtect,
03937 IN ULONG DontCharge
03938 );
03939
03940
NTSTATUS
03941
MiCheckSecuredVad (
03942 IN PMMVAD Vad,
03943 IN PVOID Base,
03944 IN ULONG_PTR Size,
03945 IN ULONG ProtectionMask
03946 );
03947
03948 ULONG
03949
MiChangeNoAccessForkPte (
03950 IN
PMMPTE PointerPte,
03951 IN ULONG ProtectionMask
03952 );
03953
03954
VOID
03955
MiSetImageProtect (
03956 IN PSEGMENT Segment,
03957 IN ULONG Protection
03958 );
03959
03960
03961
03962
03963
03964 ULONG
03965
FASTCALL
03966
MiChargePageFileQuota (
03967 IN SIZE_T QuotaCharge,
03968 IN
PEPROCESS CurrentProcess
03969 );
03970
03971
VOID
03972
MiReturnPageFileQuota (
03973 IN SIZE_T QuotaCharge,
03974 IN
PEPROCESS CurrentProcess
03975 );
03976
03977 LOGICAL
03978
FASTCALL
03979
MiChargeCommitment (
03980 IN SIZE_T QuotaCharge,
03981 IN
PEPROCESS Process OPTIONAL
03982 );
03983
03984 LOGICAL
03985
FASTCALL
03986
MiChargeCommitmentCantExpand (
03987 IN SIZE_T QuotaCharge,
03988 IN ULONG MustSucceed
03989 );
03990
03991
VOID
03992
FASTCALL
03993
MiReturnCommitment (
03994 IN SIZE_T QuotaCharge
03995 );
03996
03997
extern SIZE_T
MmPeakCommitment;
03998
03999
extern SIZE_T
MmTotalCommitLimitMaximum;
04000
04001 SIZE_T
04002
MiCalculatePageCommitment (
04003 IN PVOID StartingAddress,
04004 IN PVOID EndingAddress,
04005 IN PMMVAD Vad,
04006 IN
PEPROCESS Process
04007 );
04008
04009
VOID
04010
MiReturnPageTablePageCommitment (
04011 IN PVOID StartingAddress,
04012 IN PVOID EndingAddress,
04013 IN
PEPROCESS CurrentProcess,
04014 IN PMMVAD PreviousVad,
04015 IN PMMVAD NextVad
04016 );
04017
04018
VOID
04019
MiEmptyAllWorkingSets (
04020 VOID
04021 );
04022
04023
VOID
04024
MiFlushAllPages (
04025 VOID
04026 );
04027
04028
VOID
04029
MiModifiedPageWriterTimerDispatch (
04030 IN
PKDPC Dpc,
04031 IN PVOID DeferredContext,
04032 IN PVOID SystemArgument1,
04033 IN PVOID SystemArgument2
04034 );
04035
04036 LONGLONG
04037
MiStartingOffset(
04038 IN PSUBSECTION Subsection,
04039 IN
PMMPTE PteAddress
04040 );
04041
04042 LARGE_INTEGER
04043
MiEndingOffset(
04044 IN PSUBSECTION Subsection
04045 );
04046
04047
VOID
04048
MiReloadBootLoadedDrivers (
04049 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
04050 );
04051
04052 LOGICAL
04053
MiInitializeLoadedModuleList (
04054 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
04055 );
04056
04057
VOID
04058
MiEnableRandomSpecialPool (
04059 IN LOGICAL Enable
04060 );
04061
04062 LOGICAL
04063
MiTriageSystem (
04064 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
04065 );
04066
04067 LOGICAL
04068 MiTriageAddDrivers (
04069 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
04070 );
04071
04072 LOGICAL
04073
MiTriageVerifyDriver (
04074 IN PLDR_DATA_TABLE_ENTRY DataTableEntry
04075 );
04076
04077 #if defined (_WIN64)
04078
#define MM_SPECIAL_POOL_PTES ((1024 * 1024) / sizeof (MMPTE))
04079 #else
04080
#define MM_SPECIAL_POOL_PTES 25000
04081 #endif
04082
04083 #define MI_SUSPECT_DRIVER_BUFFER_LENGTH 512
04084
04085 extern WCHAR
MmVerifyDriverBuffer[];
04086 extern ULONG
MmVerifyDriverBufferLength;
04087 extern ULONG
MmVerifyDriverLevel;
04088
04089
extern LOGICAL
MmDontVerifyRandomDrivers;
04090 extern LOGICAL
MmSnapUnloads;
04091
extern LOGICAL
MmProtectFreedNonPagedPool;
04092 extern ULONG
MmEnforceWriteProtection;
04093 extern LOGICAL
MmTrackLockedPages;
04094
extern LOGICAL
MmTrackPtes;
04095
04096
#define VI_POOL_FREELIST_END ((ULONG_PTR)-1)
04097
04098
typedef struct _VI_POOL_ENTRY_INUSE {
04099 PVOID VirtualAddress;
04100 PVOID CallingAddress;
04101 SIZE_T NumberOfBytes;
04102 ULONG_PTR Tag;
04103 }
VI_POOL_ENTRY_INUSE, *
PVI_POOL_ENTRY_INUSE;
04104
04105 typedef struct _VI_POOL_ENTRY {
04106 union {
04107
VI_POOL_ENTRY_INUSE InUse;
04108 ULONG_PTR FreeListNext;
04109 };
04110 }
VI_POOL_ENTRY, *
PVI_POOL_ENTRY;
04111
04112 #define MI_VERIFIER_ENTRY_SIGNATURE 0x98761940
04113
04114 typedef struct _MI_VERIFIER_DRIVER_ENTRY {
04115 LIST_ENTRY
Links;
04116 ULONG
Loads;
04117 ULONG
Unloads;
04118
04119 UNICODE_STRING
BaseName;
04120 PVOID
StartAddress;
04121 PVOID
EndAddress;
04122
04123 #define VI_VERIFYING_DIRECTLY 0x1
04124 #define VI_VERIFYING_INVERSELY 0x2
04125
04126 ULONG
Flags;
04127 ULONG_PTR
Signature;
04128 ULONG_PTR
Reserved;
04129 KSPIN_LOCK
VerifierPoolLock;
04130
04131
PVI_POOL_ENTRY PoolHash;
04132 ULONG_PTR
PoolHashSize;
04133 ULONG_PTR PoolHashFree;
04134 ULONG_PTR PoolHashReserved;
04135
04136 ULONG CurrentPagedPoolAllocations;
04137 ULONG CurrentNonPagedPoolAllocations;
04138 ULONG PeakPagedPoolAllocations;
04139 ULONG PeakNonPagedPoolAllocations;
04140
04141 SIZE_T PagedBytes;
04142 SIZE_T NonPagedBytes;
04143 SIZE_T PeakPagedBytes;
04144 SIZE_T PeakNonPagedBytes;
04145
04146 }
MI_VERIFIER_DRIVER_ENTRY, *
PMI_VERIFIER_DRIVER_ENTRY;
04147
04148
typedef struct _MI_VERIFIER_POOL_HEADER {
04149 ULONG_PTR ListIndex;
04150 PMI_VERIFIER_DRIVER_ENTRY Verifier;
04151 }
MI_VERIFIER_POOL_HEADER, *
PMI_VERIFIER_POOL_HEADER;
04152
04153
typedef struct _MM_DRIVER_VERIFIER_DATA {
04154 ULONG
Level;
04155 ULONG
RaiseIrqls;
04156 ULONG
AcquireSpinLocks;
04157 ULONG
SynchronizeExecutions;
04158
04159 ULONG
AllocationsAttempted;
04160 ULONG
AllocationsSucceeded;
04161 ULONG
AllocationsSucceededSpecialPool;
04162 ULONG
AllocationsWithNoTag;
04163
04164 ULONG
TrimRequests;
04165 ULONG
Trims;
04166 ULONG
AllocationsFailed;
04167 ULONG
AllocationsFailedDeliberately;
04168
04169 ULONG
Loads;
04170 ULONG
Unloads;
04171 ULONG
UnTrackedPool;
04172 ULONG
Fill;
04173
04174 ULONG
CurrentPagedPoolAllocations;
04175 ULONG
CurrentNonPagedPoolAllocations;
04176 ULONG
PeakPagedPoolAllocations;
04177 ULONG
PeakNonPagedPoolAllocations;
04178
04179 SIZE_T
PagedBytes;
04180 SIZE_T
NonPagedBytes;
04181 SIZE_T
PeakPagedBytes;
04182 SIZE_T
PeakNonPagedBytes;
04183
04184 }
MM_DRIVER_VERIFIER_DATA, *
PMM_DRIVER_VERIFIER_DATA;
04185
04186 LOGICAL
04187
MiInitializeDriverVerifierList (
04188 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
04189 );
04190
04191 LOGICAL
04192 MiApplyDriverVerifier (
04193 IN PLDR_DATA_TABLE_ENTRY,
04194 IN PMI_VERIFIER_DRIVER_ENTRY Verifier
04195 );
04196
04197 VOID
04198
MiVerifyingDriverUnloading (
04199 IN PLDR_DATA_TABLE_ENTRY DataTableEntry
04200 );
04201
04202
VOID
04203
MiVerifierCheckThunks (
04204 IN PLDR_DATA_TABLE_ENTRY DataTableEntry
04205 );
04206
04207
extern ULONG
MiActiveVerifierThunks;
04208
extern LIST_ENTRY
MiSuspectDriverList;
04209
04210
extern LOGICAL
KernelVerifier;
04211
04212
extern MM_DRIVER_VERIFIER_DATA MmVerifierData;
04213
04214
VOID
04215
MiEnableKernelVerifier (
04216 VOID
04217 );
04218
04219
#if 0
04220
04221 #define MM_COMMIT_COUNTER_MAX 70
04222
04223
#define MM_TRACK_COMMIT(_index, bump) \
04224
if (_index >= MM_COMMIT_COUNTER_MAX) { \
04225 DbgPrint("Mm: Invalid commit counter %d %d\n", _index, MM_COMMIT_COUNTER_MAX); \
04226
DbgBreakPoint(); \
04227 } \
04228
else { \
04229 MmTrackCommit[_index] += (bump); \
04230 }
04231
04232
extern SIZE_T MmTrackCommit[MM_COMMIT_COUNTER_MAX];
04233
04234 #else
04235
04236 #define MM_TRACK_COMMIT(_index, bump)
04237
04238 #endif
04239
04240 #define MI_FREED_SPECIAL_POOL_SIGNATURE 0x98764321
04241
04242
#define MI_STACK_BYTES 1024
04243
04244
typedef struct _MI_FREED_SPECIAL_POOL {
04245
POOL_HEADER OverlaidPoolHeader;
04246 MI_VERIFIER_POOL_HEADER OverlaidVerifierPoolHeader;
04247
04248 ULONG Signature;
04249 ULONG TickCount;
04250 ULONG NumberOfBytesRequested;
04251 ULONG Pagable;
04252
04253 PVOID VirtualAddress;
04254 PVOID StackPointer;
04255 ULONG StackBytes;
04256 PETHREAD Thread;
04257
04258 UCHAR StackData[
MI_STACK_BYTES];
04259 }
MI_FREED_SPECIAL_POOL, *
PMI_FREED_SPECIAL_POOL;
04260
04261 #define MM_DBG_COMMIT_NONPAGED_POOL_EXPANSION 0
04262 #define MM_DBG_COMMIT_PAGED_POOL_PAGETABLE 1
04263 #define MM_DBG_COMMIT_PAGED_POOL_PAGES 2
04264 #define MM_DBG_COMMIT_SESSION_POOL_PAGE_TABLES 3
04265 #define MM_DBG_COMMIT_ALLOCVM1 4
04266 #define MM_DBG_COMMIT_ALLOCVM2 5
04267 #define MM_DBG_COMMIT_IMAGE 6
04268 #define MM_DBG_COMMIT_PAGEFILE_BACKED_SHMEM 7
04269 #define MM_DBG_COMMIT_INDEPENDENT_PAGES 8
04270 #define MM_DBG_COMMIT_CONTIGUOUS_PAGES 9
04271 #define MM_DBG_COMMIT_MDL_PAGES 10
04272 #define MM_DBG_COMMIT_NONCACHED_PAGES 11
04273 #define MM_DBG_COMMIT_MAPVIEW_DATA 12
04274 #define MM_DBG_COMMIT_FILL_SYSTEM_DIRECTORY 13
04275
#define MM_DBG_COMMIT_EXTRA_SYSTEM_PTES 14
04276 #define MM_DBG_COMMIT_DRIVER_PAGING_AT_INIT 15
04277 #define MM_DBG_COMMIT_PAGEFILE_FULL 16
04278 #define MM_DBG_COMMIT_PROCESS_CREATE 17
04279 #define MM_DBG_COMMIT_KERNEL_STACK_CREATE 18
04280 #define MM_DBG_COMMIT_SET_PROTECTION 19
04281 #define MM_DBG_COMMIT_SESSION_CREATE 20
04282 #define MM_DBG_COMMIT_SESSION_IMAGE_PAGES 21
04283 #define MM_DBG_COMMIT_SESSION_PAGETABLE_PAGES 22
04284 #define MM_DBG_COMMIT_SESSION_SHARED_IMAGE 23
04285 #define MM_DBG_COMMIT_DRIVER_PAGES 24
04286 #define MM_DBG_COMMIT_INSERT_VAD 25
04287 #define MM_DBG_COMMIT_SESSION_WS_INIT 26
04288 #define MM_DBG_COMMIT_SESSION_ADDITIONAL_WS_PAGES 27
04289 #define MM_DBG_COMMIT_SESSION_ADDITIONAL_WS_HASHPAGES 28
04290
04291 #define MM_DBG_COMMIT_RETURN_NONPAGED_POOL_EXPANSION 29
04292 #define MM_DBG_COMMIT_RETURN_PAGED_POOL_PAGES 30
04293 #define MM_DBG_COMMIT_RETURN_SESSION_POOL_PAGE_TABLES 31
04294 #define MM_DBG_COMMIT_RETURN_ALLOCVM1 32
04295 #define MM_DBG_COMMIT_RETURN_ALLOCVM2 33
04296 #define MM_DBG_COMMIT_RETURN_ALLOCVM3 34
04297 #define MM_DBG_COMMIT_RETURN_IMAGE_NO_LARGE_CA 35
04298 #define MM_DBG_COMMIT_RETURN_PAGEFILE_BACKED_SHMEM 36
04299 #define MM_DBG_COMMIT_RETURN_NTFREEVM1 37
04300 #define MM_DBG_COMMIT_RETURN_NTFREEVM2 38
04301 #define MM_DBG_COMMIT_RETURN_NTFREEVM3 39
04302 #define MM_DBG_COMMIT_RETURN_NTFREEVM4 40
04303 #define MM_DBG_COMMIT_RETURN_MDL_PAGES 41
04304 #define MM_DBG_COMMIT_RETURN_NONCACHED_PAGES 42
04305 #define MM_DBG_COMMIT_RETURN_MAPVIEW_DATA 43
04306 #define MM_DBG_COMMIT_RETURN_PAGETABLES 44
04307 #define MM_DBG_COMMIT_RETURN_PROTECTION 45
04308 #define MM_DBG_COMMIT_RETURN_SEGMENT_DELETE1 46
04309 #define MM_DBG_COMMIT_RETURN_SEGMENT_DELETE2 47
04310 #define MM_DBG_COMMIT_RETURN_SESSION_CREATE_FAILURE1 48
04311
#define MM_DBG_COMMIT_RETURN_SESSION_DEREFERENCE 49
04312
#define MM_DBG_COMMIT_RETURN_SESSION_IMAGE_FAILURE1 50
04313
#define MM_DBG_COMMIT_RETURN_SESSION_PAGETABLE_PAGES 51
04314
#define MM_DBG_COMMIT_RETURN_VAD 52
04315 #define MM_DBG_COMMIT_RETURN_SESSION_WSL_FAILURE 54
04316
#define MM_DBG_COMMIT_RETURN_PROCESS_CREATE_FAILURE1 55
04317 #define MM_DBG_COMMIT_RETURN_PROCESS_DELETE 56
04318
#define MM_DBG_COMMIT_RETURN_PROCESS_CLEAN_PAGETABLES 57
04319
#define MM_DBG_COMMIT_RETURN_KERNEL_STACK_FAILURE1 58
04320
#define MM_DBG_COMMIT_RETURN_KERNEL_STACK_FAILURE2 59
04321
#define MM_DBG_COMMIT_RETURN_KERNEL_STACK_DELETE 60
04322
#define MM_DBG_COMMIT_RETURN_SESSION_DRIVER_LOAD_FAILURE1 61
04323
#define MM_DBG_COMMIT_RETURN_DRIVER_INIT_CODE 62
04324
#define MM_DBG_COMMIT_RETURN_DRIVER_UNLOAD 63
04325
#define MM_DBG_COMMIT_RETURN_DRIVER_UNLOAD1 64
04326
04327
04328
#if 1 // LWFIX - TEMP TEMP TEMP
04329
04330
#define MM_BUMP_COUNTER_MAX 60
04331
04332 #define MM_BUMP_COUNTER(_index, bump) \
04333
if (_index >= MM_BUMP_COUNTER_MAX) { \
04334 DbgPrint("Mm: Invalid bump counter %d %d\n", _index, MM_BUMP_COUNTER_MAX); \
04335
DbgBreakPoint(); \
04336
} \
04337
else { \
04338
MmResTrack[_index] += (bump); \
04339
}
04340
#else
04341
04342
#define MM_BUMP_COUNTER(_index, bump)
04343
04344
#endif
04345
04346
extern ULONG
MiSpecialPagesNonPaged;
04347
extern ULONG
MiSpecialPagesNonPagedMaximum;
04348
04349
extern ULONG
MmLockPagesPercentage;
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
#define MI_NONPAGABLE_MEMORY_AVAILABLE() \
04376
((SPFN_NUMBER) \
04377
(MmResidentAvailablePages - \
04378
MmTotalFreeSystemPtes[NonPagedPoolExpansion] - \
04379
(MiSpecialPagesNonPagedMaximum - MiSpecialPagesNonPaged) - \
04380
MmSystemLockPagesCount))
04381
04382
extern ULONG
MmLargePageMinimum;
04383
04384
04385
04386
04387
04388
VOID
04389
MiDumpValidAddresses (
04390 VOID
04391 );
04392
04393
VOID
04394
MiDumpPfn ( VOID );
04395
04396
VOID
04397
MiDumpWsl ( VOID );
04398
04399
04400
VOID
04401
MiFormatPte (
04402 IN
PMMPTE PointerPte
04403 );
04404
04405
VOID
04406 MiCheckPfn ( VOID );
04407
04408 VOID
04409
MiCheckPte ( VOID );
04410
04411
VOID
04412 MiFormatPfn (
04413 IN PMMPFN PointerPfn
04414 );
04415
04416
04417
04418
04419
extern MMPTE ZeroPte;
04420
04421
extern MMPTE ZeroKernelPte;
04422
04423
extern MMPTE ValidKernelPteLocal;
04424
04425
extern MMPTE ValidKernelPte;
04426
04427
extern MMPTE ValidKernelPde;
04428
04429
extern MMPTE ValidKernelPdeLocal;
04430
04431
extern MMPTE ValidUserPte;
04432
04433
extern MMPTE ValidPtePte;
04434
04435
extern MMPTE ValidPdePde;
04436
04437
extern MMPTE DemandZeroPde;
04438
04439
extern MMPTE DemandZeroPte;
04440
04441
extern MMPTE KernelPrototypePte;
04442
04443
extern MMPTE TransitionPde;
04444
04445
extern MMPTE PrototypePte;
04446
04447
extern MMPTE NoAccessPte;
04448
04449
extern ULONG_PTR
MmSubsectionBase;
04450
04451
extern ULONG_PTR
MmSubsectionTopPage;
04452
04453
extern BOOLEAN
MiHydra;
04454
04455 extern ULONG
ExpMultiUserTS;
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469
04470
extern PFN_COUNT
MmNumberOfPhysicalPages;
04471
04472
04473
04474
04475
04476
extern PFN_NUMBER
MmLowestPhysicalPage;
04477
04478
04479
04480
04481
04482
extern PFN_NUMBER
MmHighestPhysicalPage;
04483
04484
04485
04486
04487
04488
extern PFN_NUMBER
MmHighestPossiblePhysicalPage;
04489
04490
04491
04492
04493
04494
04495
extern PFN_COUNT
MmAvailablePages;
04496
04497
04498
04499
04500
04501
extern PFN_NUMBER
MmMoreThanEnoughFreePages;
04502
04503
04504
04505
04506
04507
04508
04509
04510
04511
04512
04513
04514
extern SPFN_NUMBER
MmResidentAvailablePages;
04515
04516
04517
04518
04519
04520
04521
extern PFN_NUMBER
MmPagesAboveWsMinimum;
04522
04523
04524
04525
04526
04527
04528
extern PFN_NUMBER
MmPagesAboveWsMaximum;
04529
04530
04531
04532
04533
04534
04535
extern PFN_NUMBER
MmPagesAboveWsThreshold;
04536
04537
04538
04539
04540
04541
04542
extern PFN_NUMBER
MmWorkingSetSizeIncrement;
04543
04544
04545
04546
04547
04548
extern PFN_NUMBER
MmWorkingSetSizeExpansion;
04549
04550
04551
04552
04553
04554
04555 extern PFN_NUMBER
MmWsAdjustThreshold;
04556
04557
04558
04559
04560
04561
04562
extern PFN_NUMBER
MmWsExpandThreshold;
04563
04564
04565
04566
04567
04568
extern PFN_NUMBER
MmWsTrimReductionGoal;
04569
04570
extern ULONG
MiDelayPageFaults;
04571
04572
extern PMMPFN MmPfnDatabase;
04573
04574
extern MMPFNLIST MmZeroedPageListHead;
04575
04576
extern MMPFNLIST MmFreePageListHead;
04577
04578
extern MMPFNLIST MmStandbyPageListHead;
04579
04580
extern MMPFNLIST MmModifiedPageListHead;
04581
04582
extern MMPFNLIST MmModifiedNoWritePageListHead;
04583
04584
extern MMPFNLIST MmBadPageListHead;
04585
04586
extern PMMPFNLIST MmPageLocationList[
NUMBER_OF_PAGE_LISTS];
04587
04588
extern MMPFNLIST MmModifiedPageListByColor[
MM_MAXIMUM_NUMBER_OF_COLORS];
04589
04590
extern ULONG
MmModNoWriteInsert;
04591
04592
04593
04594
04595
04596
extern KEVENT MmAvailablePagesEvent;
04597
04598 extern KEVENT MmAvailablePagesEventHigh;
04599
04600
04601
04602
04603
04604 extern KEVENT MmZeroingPageEvent;
04605
04606
04607
04608
04609
04610
04611
04612
04613
extern BOOLEAN
MmZeroingPageThreadActive;
04614
04615
04616
04617
04618
04619
extern PFN_NUMBER
MmMinimumFreePagesToZero;
04620
04621
04622
04623
04624
04625
extern KEVENT MmMappedFileIoComplete;
04626
04627
04628
04629
04630
04631
extern PMMPTE MmFirstReservedMappingPte;
04632
04633
extern PMMPTE MmLastReservedMappingPte;
04634
04635
04636
04637
04638
04639
04640
04641
extern PVOID
MmNonPagedSystemStart;
04642
04643
extern PCHAR
MmSystemSpaceViewStart;
04644
04645
extern LOGICAL
MmProtectFreedNonPagedPool;
04646
04647
04648
04649
04650
04651
extern SIZE_T
MmSizeOfNonPagedPoolInBytes;
04652
04653
extern SIZE_T
MmMinimumNonPagedPoolSize;
04654
04655
extern SIZE_T
MmDefaultMaximumNonPagedPool;
04656
04657
extern ULONG
MmMinAdditionNonPagedPoolPerMb;
04658
04659
extern ULONG
MmMaxAdditionNonPagedPoolPerMb;
04660
04661
extern SIZE_T
MmSizeOfPagedPoolInBytes;
04662
04663
extern SIZE_T
MmMaximumNonPagedPoolInBytes;
04664
04665
extern PFN_NUMBER
MmAllocatedNonPagedPool;
04666
04667
extern PFN_NUMBER
MmSizeOfNonPagedMustSucceed;
04668
04669
extern PVOID
MmNonPagedPoolExpansionStart;
04670
04671
extern ULONG
MmExpandedPoolBitPosition;
04672
04673 extern PFN_NUMBER
MmNumberOfFreeNonPagedPool;
04674
04675
extern ULONG
MmMustSucceedPoolBitPosition;
04676
04677
extern ULONG
MmNumberOfSystemPtes;
04678
04679
extern ULONG
MiRequestedSystemPtes;
04680
04681
extern ULONG
MmTotalFreeSystemPtes[
MaximumPtePoolTypes];
04682
04683
extern SIZE_T
MmLockPagesLimit;
04684
04685
extern PMMPTE MmSystemPagePtes;
04686
04687
#if !defined (_X86PAE_)
04688 extern ULONG
MmSystemPageDirectory;
04689
#else
04690 extern ULONG
MmSystemPageDirectory[];
04691
#endif
04692
04693
extern PMMPTE MmPagedPoolBasePde;
04694
04695
extern SIZE_T
MmHeapSegmentReserve;
04696
04697
extern SIZE_T
MmHeapSegmentCommit;
04698
04699
extern SIZE_T
MmHeapDeCommitTotalFreeThreshold;
04700
04701
extern SIZE_T
MmHeapDeCommitFreeBlockThreshold;
04702
04703
#define MI_MAX_FREE_LIST_HEADS 4
04704
04705
extern LIST_ENTRY
MmNonPagedPoolFreeListHead[
MI_MAX_FREE_LIST_HEADS];
04706
04707
04708
04709
04710
04711
extern ULONG
MmFlushCounter;
04712
04713
04714
04715
04716
04717
extern PVOID
MmNonPagedPoolStart;
04718
04719 extern PVOID
MmNonPagedPoolEnd;
04720
04721 extern PVOID
MmPagedPoolStart;
04722
04723 extern PVOID
MmPagedPoolEnd;
04724
04725 extern PVOID
MmNonPagedMustSucceed;
04726
04727
04728
04729
04730
04731
typedef struct _MM_PAGED_POOL_INFO {
04732
04733 PRTL_BITMAP PagedPoolAllocationMap;
04734 PRTL_BITMAP EndOfPagedPoolBitmap;
04735 PRTL_BITMAP PagedPoolLargeSessionAllocationMap;
04736
PMMPTE FirstPteForPagedPool;
04737
PMMPTE LastPteForPagedPool;
04738
PMMPTE NextPdeForPagedPoolExpansion;
04739 ULONG PagedPoolHint;
04740 SIZE_T PagedPoolCommit;
04741 SIZE_T AllocatedPagedPool;
04742
04743 }
MM_PAGED_POOL_INFO, *
PMM_PAGED_POOL_INFO;
04744
04745
extern MM_PAGED_POOL_INFO MmPagedPoolInfo;
04746
04747
extern PVOID
MmPageAlignedPoolBase[2];
04748
04749
extern PRTL_BITMAP
VerifierLargePagedPoolMap;
04750
04751
04752
04753
04754
04755
04756
04757
extern MMPTE MmFirstFreeSystemPte[
MaximumPtePoolTypes];
04758
04759
extern ULONG_PTR
MiSystemViewStart;
04760
04761
04762
04763
04764
04765
04766
04767
extern PMMWSL MmSystemCacheWorkingSetList;
04768
04769
extern PMMWSLE MmSystemCacheWsle;
04770
04771
extern PVOID
MmSystemCacheStart;
04772
04773
extern PVOID
MmSystemCacheEnd;
04774
04775 extern PRTL_BITMAP
MmSystemCacheAllocationMap;
04776
04777
extern PRTL_BITMAP
MmSystemCacheEndingMap;
04778
04779
extern PFN_NUMBER
MmSystemCacheWsMinimum;
04780
04781
extern PFN_NUMBER
MmSystemCacheWsMaximum;
04782
04783
04784
04785
04786
04787
04788
04789
04790
extern ULONG
MmAliasAlignment;
04791
04792
04793
04794
04795
04796
04797 extern ULONG
MmAliasAlignmentOffset;
04798
04799
04800
04801
04802
04803
04804
extern ULONG
MmAliasAlignmentMask;
04805
04806
04807
04808
04809
04810
04811
extern ULONG
MmNumberDeadKernelStacks;
04812
extern ULONG
MmMaximumDeadKernelStacks;
04813
extern PMMPFN MmFirstDeadKernelStack;
04814
04815
04816
04817
04818
04819
04820
04821 extern PMMPTE MmSystemPteBase;
04822
04823
extern PMMWSL MmWorkingSetList;
04824
04825
extern PMMWSLE MmWsle;
04826
04827
04828
04829
04830
04831
04832
extern PMMVAD MmVirtualAddressDescriptorRoot;
04833
04834
extern PMMADDRESS_NODE MmSectionBasedRoot;
04835
04836
extern PVOID
MmHighSectionBase;
04837
04838
04839
04840
04841
04842
extern FAST_MUTEX MmSectionCommitMutex;
04843
04844
04845
04846
04847
04848
extern FAST_MUTEX MmSectionBasedMutex;
04849
04850
04851
04852
04853
04854 extern ERESOURCE MmSectionExtendResource;
04855
extern ERESOURCE MmSectionExtendSetResource;
04856
04857
04858
04859
04860
04861
extern KEVENT MmImageMappingPteEvent;
04862
04863
04864
04865
04866
04867
extern ULONG
MmDataClusterSize;
04868
04869
extern ULONG
MmCodeClusterSize;
04870
04871
04872
04873
04874
04875
extern FAST_MUTEX MmPageFileCreationLock;
04876
04877
04878
04879
04880
04881
extern PKEVENT MmPagingFileCreated;
04882
04883
04884
04885
04886
04887 extern ULONG_PTR
MmPagingFileDebug[];
04888
04889
04890
04891
04892
04893
04894
04895
extern KSPIN_LOCK
MmPfnLock;
04896
04897
04898
04899
04900
04901
04902
extern ERESOURCE MmSystemWsLock;
04903
04904
04905
04906
04907
04908
extern KSPIN_LOCK
MmSystemSpaceLock;
04909
04910
04911
04912
04913
04914
extern KSPIN_LOCK
MmChargeCommitmentLock;
04915
04916
04917
04918
04919
04920
extern KSPIN_LOCK
MmExpansionLock;
04921
04922
04923
04924
04925
04926
extern MMPTE GlobalPte;
04927
04928
04929
04930
04931
04932
extern ULONG
MmSystemPageColor;
04933
04934
extern ULONG
MmSecondaryColors;
04935
04936
extern ULONG
MmProcessColorSeed;
04937
04938
04939
04940
04941
04942
04943
04944 extern ULONG
MmDisablePagingExecutive;
04945
04946
04947
04948
04949
04950
04951
#if DBG
04952 extern ULONG MmDebug;
04953 #endif
04954
04955
04956
04957
04958
04959 extern MMDEREFERENCE_SEGMENT_HEADER MmDereferenceSegmentHeader;
04960
04961
extern LIST_ENTRY
MmUnusedSegmentList;
04962
04963
extern KEVENT MmUnusedSegmentCleanup;
04964
04965
extern SIZE_T
MmMaxUnusedSegmentPagedPoolUsage;
04966
04967
extern SIZE_T
MmUnusedSegmentPagedPoolUsage;
04968 extern SIZE_T
MiUnusedSegmentPagedPoolUsage;
04969
04970
extern SIZE_T
MmUnusedSegmentPagedPoolReduction;
04971
04972
extern SIZE_T
MmMaxUnusedSegmentNonPagedPoolUsage;
04973
04974
extern SIZE_T
MmUnusedSegmentNonPagedPoolUsage;
04975
extern SIZE_T
MiUnusedSegmentNonPagedPoolUsage;
04976
04977
extern SIZE_T
MmUnusedSegmentNonPagedPoolReduction;
04978
04979
extern ULONG
MmUnusedSegmentTrimLevel;
04980
04981
extern ULONG
MmUnusedSegmentCount;
04982
04983
#define MI_UNUSED_SEGMENTS_COUNT_UPDATE(_count) \
04984
MmUnusedSegmentCount += (_count);
04985
04986
#define MI_FILESYSTEM_NONPAGED_POOL_CHARGE 150
04987
04988
#define MI_FILESYSTEM_PAGED_POOL_CHARGE 1024
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
04999
05000
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010
#define MI_UNUSED_SEGMENTS_SURPLUS() \
05011
(MmUnusedSegmentPagedPoolUsage > MmMaxUnusedSegmentPagedPoolUsage) || \
05012
(MmUnusedSegmentNonPagedPoolUsage > MmMaxUnusedSegmentNonPagedPoolUsage)
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031
05032
05033
05034
#define MI_UNUSED_SEGMENTS_INSERT_CHARGE(_ControlArea) \
05035
{ \
05036
MM_PFN_LOCK_ASSERT(); \
05037
ASSERT (_ControlArea->PagedPoolUsage >= sizeof(SEGMENT)); \
05038
ASSERT (_ControlArea->NonPagedPoolUsage >= sizeof(CONTROL_AREA) + sizeof(SUBSECTION)); \
05039
ASSERT (MiUnusedSegmentNonPagedPoolUsage + _ControlArea->NonPagedPoolUsage > MiUnusedSegmentNonPagedPoolUsage); \
05040
ASSERT (MiUnusedSegmentPagedPoolUsage + _ControlArea->PagedPoolUsage > MiUnusedSegmentPagedPoolUsage); \
05041
MiUnusedSegmentPagedPoolUsage += _ControlArea->PagedPoolUsage; \
05042
MiUnusedSegmentNonPagedPoolUsage += _ControlArea->NonPagedPoolUsage;\
05043
MmUnusedSegmentPagedPoolUsage += (_ControlArea->PagedPoolUsage + MI_FILESYSTEM_PAGED_POOL_CHARGE); \
05044
MmUnusedSegmentNonPagedPoolUsage += (_ControlArea->NonPagedPoolUsage + MI_FILESYSTEM_NONPAGED_POOL_CHARGE);\
05045
MI_UNUSED_SEGMENTS_COUNT_UPDATE(1); \
05046
}
05047
05048
05049
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060
05061
05062
05063
05064
05065
05066
05067
05068
#define MI_UNUSED_SEGMENTS_REMOVE_CHARGE(_ControlArea) \
05069
{ \
05070
MM_PFN_LOCK_ASSERT(); \
05071 ASSERT (_ControlArea->PagedPoolUsage >= sizeof(SEGMENT)); \
05072
ASSERT (_ControlArea->NonPagedPoolUsage >= sizeof(CONTROL_AREA) + sizeof(SUBSECTION)); \
05073 ASSERT (MmUnusedSegmentNonPagedPoolUsage - _ControlArea->NonPagedPoolUsage < MmUnusedSegmentNonPagedPoolUsage); \
05074
ASSERT (MmUnusedSegmentPagedPoolUsage - _ControlArea->PagedPoolUsage < MmUnusedSegmentPagedPoolUsage); \
05075
MiUnusedSegmentPagedPoolUsage -= _ControlArea->PagedPoolUsage; \
05076
MiUnusedSegmentNonPagedPoolUsage -= _ControlArea->NonPagedPoolUsage;\
05077
MmUnusedSegmentPagedPoolUsage -= (_ControlArea->PagedPoolUsage + MI_FILESYSTEM_PAGED_POOL_CHARGE); \
05078
MmUnusedSegmentNonPagedPoolUsage -= (_ControlArea->NonPagedPoolUsage + MI_FILESYSTEM_NONPAGED_POOL_CHARGE);\
05079 MI_UNUSED_SEGMENTS_COUNT_UPDATE(-1); \
05080
}
05081
05082
05083
05084
05085
05086
extern MMWORKING_SET_EXPANSION_HEAD MmWorkingSetExpansionHead;
05087
05088 extern MMPAGE_FILE_EXPANSION MmAttemptForCantExtend;
05089
05090
05091
05092
05093
05094 extern MMMOD_WRITER_LISTHEAD MmPagingFileHeader;
05095
05096 extern MMMOD_WRITER_LISTHEAD MmMappedFileHeader;
05097
05098 extern PMMPAGING_FILE MmPagingFile[
MAX_PAGE_FILES];
05099
05100 #define MM_MAPPED_FILE_MDLS 4
05101
05102
05103
extern PMMMOD_WRITER_MDL_ENTRY MmMappedFileMdl[
MM_MAPPED_FILE_MDLS];
05104
05105
extern LIST_ENTRY
MmFreePagingSpaceLow;
05106
05107
extern ULONG
MmNumberOfActiveMdlEntries;
05108
05109
extern ULONG
MmNumberOfPagingFiles;
05110
05111
extern KEVENT MmModifiedPageWriterEvent;
05112
05113
extern KEVENT MmCollidedFlushEvent;
05114
05115
extern KEVENT MmCollidedLockEvent;
05116
05117
05118
05119
05120
05121
extern SIZE_T
MmTotalCommittedPages;
05122
05123
extern SIZE_T
MmTotalCommitLimit;
05124
05125
extern SIZE_T
MmOverCommit;
05126
05127
extern SIZE_T
MmSharedCommit;
05128
05129
05130
05131
05132
05133
extern PFN_NUMBER
MmMinimumFreePages;
05134
05135
extern PFN_NUMBER
MmFreeGoal;
05136
05137
extern PFN_NUMBER
MmModifiedPageMaximum;
05138
05139
extern PFN_NUMBER
MmModifiedPageMinimum;
05140
05141
extern ULONG
MmModifiedWriteClusterSize;
05142
05143
extern ULONG
MmMinimumFreeDiskSpace;
05144
05145
extern ULONG
MmPageFileExtension;
05146
05147
extern ULONG
MmMinimumPageFileReduction;
05148
05149
extern LARGE_INTEGER
MiModifiedPageLife;
05150
05151
extern BOOLEAN
MiTimerPending;
05152
05153
extern KEVENT MiMappedPagesTooOldEvent;
05154
05155
extern KDPC MiModifiedPageWriterTimerDpc;
05156
05157
extern KTIMER MiModifiedPageWriterTimer;
05158
05159
05160
05161
05162
05163
extern PFN_NUMBER
MmSystemProcessWorkingSetMin;
05164
05165
extern PFN_NUMBER
MmSystemProcessWorkingSetMax;
05166
05167
extern PFN_NUMBER
MmMinimumWorkingSetSize;
05168
05169
05170
05171
05172
05173
extern PMMPTE MmDebugPte;
05174
05175
extern PMMPTE MmCrashDumpPte;
05176
05177
extern ULONG
MiOverCommitCallCount;
05178
05179 extern SIZE_T
MmResTrack[
MM_BUMP_COUNTER_MAX];
05180
05181
05182
05183
05184
05185
extern PPAGE_FAULT_NOTIFY_ROUTINE MmPageFaultNotifyRoutine;
05186
extern PHARD_FAULT_NOTIFY_ROUTINE MmHardFaultNotifyRoutine;
05187
05188
05189
05190
05191
05192
05193
05194
#define HYDRA_PROCESS ((PEPROCESS)1)
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213
05214
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224
05225
05226
extern ULONG_PTR
MmSessionBase;
05227
05228
05229
05230
05231
05232
#define MI_SESSION_SPACE_STRUCT_SIZE MM_ALLOCATION_GRANULARITY
05233
05234
#define MI_SESSION_SPACE_WS_SIZE (4*1024*1024 - MI_SESSION_SPACE_STRUCT_SIZE)
05235
05236
#define MI_SESSION_IMAGE_SIZE (8*1024*1024)
05237
05238
#define MI_SESSION_VIEW_SIZE (20*1024*1024)
05239
05240
#define MI_SESSION_POOL_SIZE (16*1024*1024)
05241
05242
#define MM_SESSION_SPACE_DATA_SIZE PAGE_SIZE
05243
05244
#define MI_SESSION_SPACE_TOTAL_SIZE \
05245
(MI_SESSION_IMAGE_SIZE + \
05246
MI_SESSION_SPACE_STRUCT_SIZE + \
05247
MI_SESSION_SPACE_WS_SIZE + \
05248 MI_SESSION_VIEW_SIZE + \
05249
MI_SESSION_POOL_SIZE)
05250
05251
05252
05253
05254
05255
05256 #define MI_SESSION_MAXIMUM_WORKING_SET \
05257
((ULONG)(MI_SESSION_SPACE_TOTAL_SIZE >> PAGE_SHIFT))
05258
05259
05260
05261
05262
05263
#define MI_SESSION_SPACE_PAGE_TABLES \
05264 (MI_SESSION_SPACE_TOTAL_SIZE / MM_VA_MAPPED_BY_PDE)
05265
05266
05267
05268
05269
05270
05271
#define MI_SESSION_IMAGE_OFFSET (0)
05272
05273
#define MI_SESSION_DATA_OFFSET (8*1024*1024)
05274
05275
#define MI_SESSION_WS_OFFSET (8*1024*1024 + MI_SESSION_SPACE_STRUCT_SIZE)
05276
05277
#define MI_SESSION_VIEW_OFFSET (12*1024*1024)
05278
05279
#define MI_SESSION_POOL_OFFSET (32*1024*1024)
05280
05281
05282
05283
05284
05285
05286
05287 #define MI_SESSION_IMAGE_START ((ULONG_PTR)MmSessionBase)
05288
05289
#define MI_SESSION_SPACE_WS (MmSessionBase + MI_SESSION_WS_OFFSET)
05290
05291
#define MI_SESSION_VIEW_START (MmSessionBase + MI_SESSION_VIEW_OFFSET)
05292
05293 #define MI_SESSION_POOL (MmSessionBase + MI_SESSION_POOL_OFFSET)
05294
05295
#define MI_SESSION_SPACE_END ((ULONG_PTR)MmSessionBase + \
05296 MI_SESSION_SPACE_TOTAL_SIZE)
05297
05298
05299
05300
05301
05302 #define MI_IS_SESSION_IMAGE_ADDRESS(VirtualAddress) \
05303 (MiHydra == TRUE && (PVOID)(VirtualAddress) >= (PVOID)MI_SESSION_IMAGE_START && (PVOID)(VirtualAddress) < (PVOID)(MI_SESSION_IMAGE_START + MI_SESSION_IMAGE_SIZE))
05304
05305 #define MI_IS_SESSION_POOL_ADDRESS(VirtualAddress) \
05306 (MiHydra == TRUE && (PVOID)(VirtualAddress) >= (PVOID)MI_SESSION_POOL && (PVOID)(VirtualAddress) < (PVOID)(MI_SESSION_POOL + MI_SESSION_POOL_SIZE))
05307
05308 #define MI_IS_SESSION_ADDRESS(_VirtualAddress) \
05309 (MiHydra == TRUE && (PVOID)(_VirtualAddress) >= (PVOID)MmSessionBase && (PVOID)(_VirtualAddress) < (PVOID)(MI_SESSION_SPACE_END))
05310
05311 #define MI_IS_SESSION_PTE(_Pte) \
05312 (MiHydra == TRUE && (PMMPTE)(_Pte) >= MiSessionBasePte && (PMMPTE)(_Pte) < MiSessionLastPte)
05313
05314
05315 #define SESSION_GLOBAL(_Session) (_Session->GlobalVirtualAddress)
05316
05317 #define MM_DBG_SESSION_INITIAL_PAGETABLE_ALLOC 0
05318 #define MM_DBG_SESSION_INITIAL_PAGETABLE_FREE_RACE 1
05319 #define MM_DBG_SESSION_INITIAL_PAGE_ALLOC 2
05320 #define MM_DBG_SESSION_INITIAL_PAGE_FREE_FAIL1 3
05321 #define MM_DBG_SESSION_INITIAL_PAGETABLE_FREE_FAIL1 4
05322
#define MM_DBG_SESSION_WS_PAGE_FREE 5
05323 #define MM_DBG_SESSION_PAGETABLE_ALLOC 6
05324 #define MM_DBG_SESSION_SYSMAPPED_PAGES_ALLOC 7
05325 #define MM_DBG_SESSION_WS_PAGETABLE_ALLOC 8
05326 #define MM_DBG_SESSION_PAGEDPOOL_PAGETABLE_ALLOC 9
05327 #define MM_DBG_SESSION_PAGEDPOOL_PAGETABLE_FREE_FAIL1 10
05328 #define MM_DBG_SESSION_WS_PAGE_ALLOC 11
05329 #define MM_DBG_SESSION_WS_PAGE_ALLOC_GROWTH 12
05330
#define MM_DBG_SESSION_INITIAL_PAGE_FREE 13
05331
#define MM_DBG_SESSION_PAGETABLE_FREE 14
05332
#define MM_DBG_SESSION_PAGEDPOOL_PAGETABLE_ALLOC1 15
05333
#define MM_DBG_SESSION_DRIVER_PAGES_LOCKED 16
05334
#define MM_DBG_SESSION_DRIVER_PAGES_UNLOCKED 17
05335
#define MM_DBG_SESSION_WS_HASHPAGE_ALLOC 18
05336
#define MM_DBG_SESSION_SYSMAPPED_PAGES_COMMITTED 19
05337
05338
#define MM_DBG_SESSION_COMMIT_PAGEDPOOL_PAGES 30
05339
#define MM_DBG_SESSION_COMMIT_DELETE_VM_RETURN 31
05340
#define MM_DBG_SESSION_COMMIT_POOL_FREED 32
05341
#define MM_DBG_SESSION_COMMIT_IMAGE_UNLOAD 33
05342
#define MM_DBG_SESSION_COMMIT_IMAGELOAD_FAILED1 34
05343
#define MM_DBG_SESSION_COMMIT_IMAGELOAD_FAILED2 35
05344
#define MM_DBG_SESSION_COMMIT_IMAGELOAD_NOACCESS 36
05345
05346
#if DBG
05347
#define MM_SESS_COUNTER_MAX 40
05348
05349
#define MM_BUMP_SESS_COUNTER(_index, bump) \
05350
if (_index >= MM_SESS_COUNTER_MAX) { \
05351
DbgPrint("Mm: Invalid bump counter %d %d\n", _index, MM_SESS_COUNTER_MAX); \
05352
DbgBreakPoint(); \
05353
} \
05354
else if (MiHydra == TRUE) { \
05355
MmSessionSpace->Debug[_index] += (bump); \
05356
}
05357
05358
typedef struct _MM_SESSION_MEMORY_COUNTERS {
05359 SIZE_T NonPagablePages;
05360 SIZE_T CommittedPages;
05361 } MM_SESSION_MEMORY_COUNTERS, *PMM_SESSION_MEMORY_COUNTERS;
05362
05363
#define MM_SESS_MEMORY_COUNTER_MAX 8
05364
05365
#define MM_SNAP_SESS_MEMORY_COUNTERS(_index) \
05366 if (_index >= MM_SESS_MEMORY_COUNTER_MAX) { \
05367 DbgPrint("Mm: Invalid session mem counter %d %d\n", _index, MM_SESS_MEMORY_COUNTER_MAX); \
05368 DbgBreakPoint(); \
05369 } \
05370 else { \
05371 MmSessionSpace->Debug2[_index].NonPagablePages = MmSessionSpace->NonPagablePages; \
05372 MmSessionSpace->Debug2[_index].CommittedPages = MmSessionSpace->CommittedPages; \
05373 }
05374
05375
#else
05376 #define MM_BUMP_SESS_COUNTER(_index, bump)
05377
#define MM_SNAP_SESS_MEMORY_COUNTERS(_index)
05378 #endif
05379
05380
05381
#define MM_SESSION_FAILURE_NO_IDS 0
05382
#define MM_SESSION_FAILURE_NO_COMMIT 1
05383
#define MM_SESSION_FAILURE_NO_RESIDENT 2
05384
#define MM_SESSION_FAILURE_RACE_DETECTED 3
05385
#define MM_SESSION_FAILURE_NO_SYSPTES 4
05386 #define MM_SESSION_FAILURE_NO_PAGED_POOL 5
05387 #define MM_SESSION_FAILURE_NO_NONPAGED_POOL 6
05388 #define MM_SESSION_FAILURE_NO_IMAGE_VA_SPACE 7
05389 #define MM_SESSION_FAILURE_NO_SESSION_PAGED_POOL 8
05390
05391 #define MM_SESSION_FAILURE_CAUSES 9
05392
05393 ULONG
MmSessionFailureCauses[
MM_SESSION_FAILURE_CAUSES];
05394
05395
#define MM_BUMP_SESSION_FAILURES(_index) MmSessionFailureCauses[_index] += 1;
05396
05397
05398
05399
05400
05401
typedef struct _MM_SESSION_SPACE_FLAGS {
05402 ULONG
Initialized : 1;
05403 ULONG
BeingDeleted : 1;
05404 ULONG
WorkingSetInserted : 1;
05405 ULONG
SessionListInserted : 1;
05406 ULONG
HasWsLock : 1;
05407 ULONG
DeletePending : 1;
05408 ULONG
Filler : 26;
05409 }
MM_SESSION_SPACE_FLAGS;
05410
05411
05412
05413
05414
05415
05416
05417
05418
05419
05420
05421
05422
05423
05424
typedef struct _MM_SESSION_SPACE {
05425
05426 ULONG
ReferenceCount;
05427 union {
05428 ULONG
LongFlags;
05429
MM_SESSION_SPACE_FLAGS Flags;
05430 } u;
05431 ULONG SessionId;
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442 PFN_NUMBER
SessionPageDirectoryIndex;
05443
05444
05445
05446
05447
05448
05449
05450 struct _MM_SESSION_SPACE *
GlobalVirtualAddress;
05451
05452 KSPIN_LOCK
SpinLock;
05453
05454
05455
05456
05457
05458
05459 LIST_ENTRY
ProcessList;
05460
05461
05462
05463
05464
05465 SIZE_T
NonPagedPoolBytes;
05466 SIZE_T
PagedPoolBytes;
05467 ULONG
NonPagedPoolAllocations;
05468 ULONG
PagedPoolAllocations;
05469
05470
05471
05472
05473
05474
05475
05476
05477
05478 SIZE_T
NonPagablePages;
05479
05480
05481
05482
05483
05484
05485
05486 SIZE_T
CommittedPages;
05487
05488 LARGE_INTEGER
LastProcessSwappedOutTime;
05489
05490
#if defined (_WIN64)
05491
05492
05493
05494
05495
05496
05497
MMPTE PageDirectory;
05498
05499 #else
05500
05501
05502
05503
05504
05505
05506
MMPTE PageTables[
MI_SESSION_SPACE_PAGE_TABLES];
05507
05508
#endif
05509
05510
05511
05512
05513
05514
FAST_MUTEX PagedPoolMutex;
05515
05516
05517
05518
05519
05520 PVOID
PagedPoolStart;
05521
05522
05523
05524
05525
05526
05527 PVOID
PagedPoolEnd;
05528
05529
05530
05531
05532
05533
PMMPTE PagedPoolBasePde;
05534
05535
MM_PAGED_POOL_INFO PagedPoolInfo;
05536
05537 ULONG
Color;
05538
05539 ULONG
ProcessOutSwapCount;
05540
05541
05542
05543
05544
05545
05546
05547 LIST_ENTRY
ImageList;
05548
05549
05550
05551
05552
05553
PMMPTE GlobalPteEntry;
05554
05555 ULONG
CopyOnWriteCount;
05556
05557
05558
05559
05560
05561 ULONG
AttachCount;
05562
05563
KEVENT AttachEvent;
05564
05565
PEPROCESS LastProcess;
05566
05567
05568
05569
05570
05571
MMSUPPORT Vm;
05572
PMMWSLE Wsle;
05573
05574
ERESOURCE WsLock;
05575
05576
05577
05578
05579
05580
05581 LIST_ENTRY
WsListEntry;
05582
05583
05584
05585
05586
05587
05588
05589
05590
MMSESSION Session;
05591
05592
05593
05594
05595
05596
05597
05598
05599
DRIVER_OBJECT Win32KDriverObject;
05600
05601
PETHREAD WorkingSetLockOwner;
05602
05603
05604
05605
05606
05607
POOL_DESCRIPTOR PagedPool;
05608
05609 #if defined(_IA64_)
05610
REGION_MAP_INFO SessionMapInfo;
05611 #endif
05612
05613
#if DBG
05614
PETHREAD SessionLockOwner;
05615 ULONG WorkingSetLockOwnerCount;
05616
05617 ULONG_PTR
Debug[MM_SESS_COUNTER_MAX];
05618
05619 MM_SESSION_MEMORY_COUNTERS Debug2[MM_SESS_MEMORY_COUNTER_MAX];
05620
#endif
05621
05622 }
MM_SESSION_SPACE, *
PMM_SESSION_SPACE;
05623
05624
extern PMM_SESSION_SPACE MmSessionSpace;
05625
05626
extern ULONG
MiSessionCount;
05627
05628
05629
05630
05631
05632 #define MI_FLUSH_SESSION_TB(OLDIRQL) KeRaiseIrql (DISPATCH_LEVEL, &OLDIRQL); \
05633
KeFlushEntireTb (TRUE, TRUE); \
05634
KeLowerIrql (OLDIRQL);
05635
05636
#if DBG
05637
#define MM_SET_SESSION_LOCK_OWNER() ASSERT (MmSessionSpace->SessionLockOwner == NULL); \
05638
MmSessionSpace->SessionLockOwner = PsGetCurrentThread();
05639
05640
#define MM_CLEAR_SESSION_LOCK_OWNER() ASSERT (MmSessionSpace->SessionLockOwner == PsGetCurrentThread()); \
05641
MmSessionSpace->SessionLockOwner = NULL;
05642 #else
05643
#define MM_SET_SESSION_LOCK_OWNER()
05644 #define MM_CLEAR_SESSION_LOCK_OWNER()
05645
#endif
05646
05647
#define LOCK_SESSION(OLDIRQL) ExAcquireSpinLock (&((SESSION_GLOBAL(MmSessionSpace))->SpinLock), &OLDIRQL); \
05648
MM_SET_SESSION_LOCK_OWNER ();
05649
05650
#define UNLOCK_SESSION(OLDIRQL) MM_CLEAR_SESSION_LOCK_OWNER (); \
05651
ExReleaseSpinLock (&((SESSION_GLOBAL(MmSessionSpace))->SpinLock), OLDIRQL);
05652
05653
05654
05655
05656
05657
#define MI_SESSION_SPACE_WORKING_SET_MINIMUM 20
05658
05659
#define MI_SESSION_SPACE_WORKING_SET_MAXIMUM 384
05660
05661
NTSTATUS
05662
MiSessionCommitPageTables(
05663 PVOID StartVa,
05664 PVOID EndVa
05665 );
05666
05667
NTSTATUS
05668
MiInitializeSessionPool(
05669 VOID
05670 );
05671
05672
VOID
05673
MiCheckSessionPoolAllocations(
05674 VOID
05675 );
05676
05677 VOID
05678
MiFreeSessionPoolBitMaps(
05679 VOID
05680 );
05681
05682
VOID
05683
MiDetachSession(
05684 VOID
05685 );
05686
05687
VOID
05688 MiAttachSession(
05689 IN PMM_SESSION_SPACE SessionGlobal
05690 );
05691
05692
#define MM_SET_SESSION_RESOURCE_OWNER() \
05693
ASSERT (MmSessionSpace->WorkingSetLockOwner == NULL); \
05694 MmSessionSpace->WorkingSetLockOwner = PsGetCurrentThread();
05695
05696
#define MM_CLEAR_SESSION_RESOURCE_OWNER() \
05697
ASSERT (MmSessionSpace->WorkingSetLockOwner == PsGetCurrentThread()); \
05698
MmSessionSpace->WorkingSetLockOwner = NULL;
05699
05700 #define MM_SESSION_SPACE_WS_LOCK_ASSERT() \
05701 ASSERT (MmSessionSpace->WorkingSetLockOwner == PsGetCurrentThread())
05702
05703 #define LOCK_SESSION_SPACE_WS(OLDIRQL) \
05704 ASSERT (KeGetCurrentIrql() <= APC_LEVEL); \
05705
KeRaiseIrql(APC_LEVEL,&OLDIRQL); \
05706
ExAcquireResourceExclusive(&MmSessionSpace->WsLock, TRUE); \
05707
MM_SET_SESSION_RESOURCE_OWNER ();
05708
05709
#define UNLOCK_SESSION_SPACE_WS(OLDIRQL) \
05710
MM_CLEAR_SESSION_RESOURCE_OWNER (); \
05711
ExReleaseResource (&MmSessionSpace->WsLock); \
05712
KeLowerIrql (OLDIRQL); \
05713
ASSERT (KeGetCurrentIrql() <= APC_LEVEL);
05714
05715
extern PMMPTE MiHighestUserPte;
05716
extern PMMPTE MiHighestUserPde;
05717
05718
extern PMMPTE MiSessionBasePte;
05719
extern PMMPTE MiSessionLastPte;
05720
05721
NTSTATUS
05722
MiEmptyWorkingSet (
05723 IN
PMMSUPPORT WsInfo,
05724 IN LOGICAL WaitOk
05725 );
05726
05727
05728
05729
05730
05731
05732
05733
05734
05735
05736
05737
05738
05739
05740
05741
05742
05743
05744
05745
05746
05747
05748
#define MiGetPdeSessionIndex(va) ((ULONG)(((ULONG_PTR)(va) - (ULONG_PTR)MmSessionBase) >> PDI_SHIFT))
05749
05750
05751
05752
05753
05754
05755
05756
05757
05758
05759
05760
05761
05762
05763
05764
05765
05766
05767
05768
05769
05770
05771
05772
05773
05774
05775
05776
05777
typedef struct _IMAGE_ENTRY_IN_SESSION {
05778 LIST_ENTRY Link;
05779 PVOID Address;
05780 PVOID LastAddress;
05781 ULONG ImageCountInThisSession;
05782
PMMPTE PrototypePtes;
05783 PLDR_DATA_TABLE_ENTRY DataTableEntry;
05784 }
IMAGE_ENTRY_IN_SESSION, *
PIMAGE_ENTRY_IN_SESSION;
05785
05786
extern LIST_ENTRY
MiSessionWsList;
05787
05788
NTSTATUS
05789
FASTCALL
05790
MiCheckPdeForSessionSpace(
05791 IN PVOID VirtualAddress
05792 );
05793
05794
NTSTATUS
05795
MiShareSessionImage (
05796 IN PSECTION Section,
05797 IN OUT PSIZE_T ViewSize
05798 );
05799
05800
VOID
05801
MiSessionWideInitializeAddresses (
05802 VOID
05803 );
05804
05805
NTSTATUS
05806
MiSessionWideReserveImageAddress (
05807 IN PUNICODE_STRING pImageName,
05808 IN PSECTION Section,
05809 IN ULONG_PTR Alignment,
05810 OUT PVOID *ppAddr,
05811 OUT PBOOLEAN pAlreadyLoaded
05812 );
05813
05814
VOID
05815
MiInitializeSessionIds (
05816 VOID
05817 );
05818
05819
VOID
05820
MiInitializeSessionWsSupport(
05821 VOID
05822 );
05823
05824
VOID
05825
MiSessionAddProcess (
05826 IN
PEPROCESS NewProcess
05827 );
05828
05829
VOID
05830
MiSessionRemoveProcess (
05831 VOID
05832 );
05833
05834
NTSTATUS
05835
MiRemovePsLoadedModule(
05836 PLDR_DATA_TABLE_ENTRY DataTableEntry
05837 );
05838
05839
NTSTATUS
05840
MiRemoveImageSessionWide(
05841 IN PVOID BaseAddr
05842 );
05843
05844
NTSTATUS
05845
MiDeleteSessionVirtualAddresses(
05846 IN PVOID VirtualAddress,
05847 IN SIZE_T NumberOfBytes
05848 );
05849
05850
NTSTATUS
05851
MiUnloadSessionImageByForce (
05852 IN SIZE_T NumberOfPtes,
05853 IN PVOID ImageBase
05854 );
05855
05856
NTSTATUS
05857
MiSessionWideGetImageSize(
05858 IN PVOID BaseAddress,
05859 OUT PSIZE_T NumberOfBytes OPTIONAL,
05860 OUT PSIZE_T CommitPages OPTIONAL
05861 );
05862
05863
PIMAGE_ENTRY_IN_SESSION
05864
MiSessionLookupImage (
05865 IN PVOID BaseAddress
05866 );
05867
05868
NTSTATUS
05869
MiSessionCommitImagePages(
05870 PVOID BaseAddr,
05871 SIZE_T Size
05872 );
05873
05874
VOID
05875
MiSessionUnloadAllImages (
05876 VOID
05877 );
05878
05879
VOID
05880
MiFreeSessionSpaceMap (
05881 VOID
05882 );
05883
05884
NTSTATUS
05885
MiSessionInitializeWorkingSetList (
05886 VOID
05887 );
05888
05889
VOID
05890
MiSessionUnlinkWorkingSet (
05891 VOID
05892 );
05893
05894
NTSTATUS
05895
MiSessionCopyOnWrite (
05896 IN PMM_SESSION_SPACE SessionSpace,
05897 IN PVOID FaultingAddress,
05898 IN
PMMPTE PointerPte
05899 );
05900
05901
VOID
05902
MiSessionOutSwapProcess (
05903 IN
PEPROCESS Process
05904 );
05905
05906
VOID
05907
MiSessionInSwapProcess (
05908 IN
PEPROCESS Process
05909 );
05910
05911
#if !defined (_X86PAE_)
05912
05913
#define MI_GET_DIRECTORY_FRAME_FROM_PROCESS(_Process) \
05914
MI_GET_PAGE_FRAME_FROM_PTE((PMMPTE)(&((_Process)->Pcb.DirectoryTableBase[0])))
05915
05916
#else
05917
05918
#define MI_GET_DIRECTORY_FRAME_FROM_PROCESS(_Process) \
05919
((_Process)->PaePageDirectoryPage)
05920
#endif
05921
05922
PERFINFO_MIH_DECL
05923
05924
#if defined(_MIALT4K_)
05925
NTSTATUS
05926 MiSetCopyPagesFor4kPage(
05927 IN
PEPROCESS Process,
05928 IN OUT PMMVAD *Vad,
05929 IN OUT PVOID *StartingAddress,
05930 IN OUT PVOID *EndingAddress,
05931 IN ULONG ProtectionMask);
05932
#endif
05933
05934
#endif // MI