Windows2000/private/ntos/mm/miglobal.c

554 lines
22 KiB
C
Raw Permalink Normal View History

2001-01-01 00:00:00 +01:00
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
miglobal.c
Abstract:
This module contains the private global storage for the memory management subsystem.
Author:
Lou Perazzoli (loup) 6-Apr-1989
--*/
#include "mi.h"
PVOID MmHighestUserAddress;// Highest user address;
PVOID MmSystemRangeStart;// Start of system address range.
ULONG_PTR MmUserProbeAddress;// User probe address;
ULONG_PTR MmVirtualBias;// Virtual bias applied during the loading of the kernel image.
ULONG MmSecondaryColors;// Number of secondary colors, based on level 2 d cache size.
ULONG MmProcessColorSeed = 0x12345678;// The starting color index seed, incremented at each process creation.
PFN_COUNT MmNumberOfPhysicalPages;// Total number of physical pages available on the system.
PFN_NUMBER MmLowestPhysicalPage = (PFN_NUMBER)-1;// Lowest physical page number in the system.
PFN_NUMBER MmHighestPhysicalPage;// Highest physical page number in the system.
PFN_NUMBER MmHighestPossiblePhysicalPage;// Highest possible physical page number in the system.
// Total number of available pages in the system.
// This is the sum of the pages on the zeroed, free and standby lists.
PFN_COUNT MmAvailablePages;
PFN_NUMBER MmThrottleTop;
PFN_NUMBER MmThrottleBottom;
MMINFO_COUNTERS MmInfoCounters;// System wide memory management statistics block.
// Total number of physical pages which would be usable if every process was at its minimum working set size.
// This value is initialized at system initialization to MmAvailablePages - MM_FLUID_PHYSICAL_PAGES.
// Every time a thread is created, the kernel stack is subtracted from
// this and every time a process is created, the minimum working set is subtracted from this.
// If the value would become negative, the operation (create process/kernel stack/ adjust working set) fails.
// The PFN LOCK must be owned to manipulate this value.
SPFN_NUMBER MmResidentAvailablePages;
// The total number of pages which would be removed from working sets if every working set was at its minimum.
PFN_NUMBER MmPagesAboveWsMinimum;
// The total number of pages which would be removed from working sets
// if every working set above its maximum was at its maximum.
PFN_NUMBER MmPagesAboveWsMaximum;
// The number of pages to add to a working set if there are ample
// available pages and the working set is below its maximum.
// If memory is becoming short and MmPagesAboveWsMinimum is greater than MmPagesAboveWsThreshold, trim working sets.
PFN_NUMBER MmPagesAboveWsThreshold = 37;
PFN_NUMBER MmWorkingSetSizeIncrement = 6;
// The number of pages to extend the maximum working set size by
// if the working set at its maximum and there are ample available pages.
PFN_NUMBER MmWorkingSetSizeExpansion = 20;
// The number of pages required to be freed by working set reduction before working set reduction is attempted.
PFN_NUMBER MmWsAdjustThreshold = 45;
// The number of pages available to allow the working set to be expanded above its maximum.
PFN_NUMBER MmWsExpandThreshold = 90;
// The total number of pages to reduce by working set trimming.
PFN_NUMBER MmWsTrimReductionGoal = 29;
// The total number of pages needed for the loader to successfully hibernate.
PFN_NUMBER MmHiberPages = 512;
// Registry-settable threshold for using large pages. x86 only.
ULONG MmLargePageMinimum;
PMMPFN MmPfnDatabase;
MMPFNLIST MmZeroedPageListHead = {
0, // Total
ZeroedPageList, // ListName
MM_EMPTY_LIST, //Flink
MM_EMPTY_LIST // Blink
};
MMPFNLIST MmFreePageListHead = {
0, // Total
FreePageList, // ListName
MM_EMPTY_LIST, //Flink
MM_EMPTY_LIST // Blink
};
MMPFNLIST MmStandbyPageListHead = {
0, // Total
StandbyPageList, // ListName
MM_EMPTY_LIST, //Flink
MM_EMPTY_LIST // Blink
};
MMPFNLIST MmModifiedPageListHead = {
0, // Total
ModifiedPageList, // ListName
MM_EMPTY_LIST, //Flink
MM_EMPTY_LIST // Blink
};
MMPFNLIST MmModifiedNoWritePageListHead = {
0, // Total
ModifiedNoWritePageList, // ListName
MM_EMPTY_LIST, //Flink
MM_EMPTY_LIST // Blink
};
MMPFNLIST MmBadPageListHead = {
0, // Total
BadPageList, // ListName
MM_EMPTY_LIST, //Flink
MM_EMPTY_LIST // Blink
};
PMMPFNLIST MmPageLocationList[NUMBER_OF_PAGE_LISTS] = {
&MmZeroedPageListHead,
&MmFreePageListHead,
&MmStandbyPageListHead,
&MmModifiedPageListHead,
&MmModifiedNoWritePageListHead,
&MmBadPageListHead,
NULL,
NULL };
// PMMPFNLIST MmPageLocationList[FreePageList] = &MmFreePageListHead;
// PMMPFNLIST MmPageLocationList[ZeroedPageList] = &MmZeroedPageListHead;
// PMMPFNLIST MmPageLocationList[StandbyPageList] = &MmStandbyPageListHead;
// PMMPFNLIST MmPageLocationList[ModifiedPageList] = &MmModifiedPageListHead;
// PMMPFNLIST MmPageLocationList[ModifiedNoWritePageList] = &MmModifiedNoWritePageListHead;
// PMMPFNLIST MmPageLocationList[BadPageList] = &MmBadPageListHead;
// PMMPFNLIST MmPageLocationList[ActiveAndValid] = NULL;
// PMMPFNLIST MmPageLocationList[TransitionPage] = NULL;
PMMPTE MiHighestUserPte;
PMMPTE MiHighestUserPde;
PMMPTE MiSessionBasePte;
PMMPTE MiSessionLastPte;
// Hyper space items.
PMMPTE MmFirstReservedMappingPte;
PMMPTE MmLastReservedMappingPte;
PMMWSL MmWorkingSetList;
PMMWSLE MmWsle;
KEVENT MmAvailablePagesEvent;// Event for available pages, set means pages are available.
KEVENT MmZeroingPageEvent;// Event for the zeroing page thread.
// Boolean to indicate if the zeroing page thread is currently
// active. This is set to true when the zeroing page event is
// set and set to false when the zeroing page thread is done zeroing all the pages on the free list.
BOOLEAN MmZeroingPageThreadActive;
// Minimum number of free pages before zeroing page thread starts.
PFN_NUMBER MmMinimumFreePagesToZero = 8;
// System space sizes - MmNonPagedSystemStart to MM_NON_PAGED_SYSTEM_END
// defines the ranges of PDEs which must be copied into a new process's address space.
PVOID MmNonPagedSystemStart;
LOGICAL MmProtectFreedNonPagedPool;
LOGICAL MmDynamicPfn = FALSE;
#if PFN_CONSISTENCY
PMMPTE MiPfnStartPte;
PFN_NUMBER MiPfnPtes;
BOOLEAN MiPfnProtectionEnabled;
PETHREAD MiPfnLockOwner;
#endif
#ifdef MM_BUMP_COUNTER_MAX
SIZE_T MmResTrack[MM_BUMP_COUNTER_MAX];
#endif
#ifdef MM_COMMIT_COUNTER_MAX
SIZE_T MmTrackCommit[MM_COMMIT_COUNTER_MAX];
#endif
// Set via the registry to identify which drivers are leaking locked pages.
LOGICAL MmTrackLockedPages;
// Set via the registry to identify drivers which unload without releasing resources or still have active timers, etc.
LOGICAL MmSnapUnloads = TRUE;
#if DBG
PETHREAD MiExpansionLockOwner;
#endif
// Pool sizes.
SIZE_T MmSizeOfNonPagedPoolInBytes;
SIZE_T MmMaximumNonPagedPoolInBytes;
SIZE_T MmMinimumNonPagedPoolSize = 256 * 1024; // 256k
ULONG MmMinAdditionNonPagedPoolPerMb = 32 * 1024; // 32k
SIZE_T MmDefaultMaximumNonPagedPool = 1024 * 1024; // 1mb
ULONG MmMaxAdditionNonPagedPoolPerMb = 400 * 1024; //400k
SIZE_T MmSizeOfPagedPoolInBytes = 32 * 1024 * 1024; // 32 MB.
PFN_NUMBER MmSizeOfNonPagedMustSucceed = 4 * PAGE_SIZE; // 4 pages
ULONG MmNumberOfSystemPtes;
ULONG MiRequestedSystemPtes;
ULONG MmLockPagesPercentage;
PFN_NUMBER MmLockPagesLimit;
PMMPTE MmFirstPteForPagedPool;
PMMPTE MmLastPteForPagedPool;
PMMPTE MmPagedPoolBasePde;
// Pool bit maps and other related structures.
PVOID MmPageAlignedPoolBase[2];
PVOID MmNonPagedMustSucceed;
ULONG MmExpandedPoolBitPosition;
PFN_NUMBER MmNumberOfFreeNonPagedPool;
ULONG MmMustSucceedPoolBitPosition;
// MmFirstFreeSystemPte contains the offset from the Nonpaged system base to the first free system PTE.
// Note that an offset of FFFFF indicates an empty list.
MMPTE MmFirstFreeSystemPte[MaximumPtePoolTypes];
// System cache sizes.
PMMWSL MmSystemCacheWorkingSetList = (PMMWSL)MM_SYSTEM_CACHE_WORKING_SET;
MMSUPPORT MmSystemCacheWs;
PMMWSLE MmSystemCacheWsle;
PVOID MmSystemCacheStart = (PVOID)MM_SYSTEM_CACHE_START;
PVOID MmSystemCacheEnd;
PRTL_BITMAP MmSystemCacheAllocationMap;
PRTL_BITMAP MmSystemCacheEndingMap;
// This value should not be greater than 256MB in a system with 1GB of system space.
PFN_COUNT MmSizeOfSystemCacheInPages = 64 * 256; //64MB.
// Default sizes for the system cache.
PFN_NUMBER MmSystemCacheWsMinimum = 288;
PFN_NUMBER MmSystemCacheWsMaximum = 350;
// Cells to track unused thread kernel stacks to avoid TB flushes every time a thread terminates.
ULONG MmNumberDeadKernelStacks;
ULONG MmMaximumDeadKernelStacks = 5;
PMMPFN MmFirstDeadKernelStack = (PMMPFN)NULL;
// MmSystemPteBase contains the address of 1 PTE before the first free system PTE (zero indicates an empty list).
// The value of this field does not change once set.
PMMPTE MmSystemPteBase;
PMMWSL MmWorkingSetList;
PMMWSLE MmWsle;
PMMADDRESS_NODE MmSectionBasedRoot;
PVOID MmHighSectionBase;
POBJECT_TYPE MmSectionObjectType;// Section object type.
FAST_MUTEX MmSectionCommitMutex;// Section commit mutex.
FAST_MUTEX MmSectionBasedMutex;// Section base address mutex.
// Resource for section extension.
ERESOURCE MmSectionExtendResource;
ERESOURCE MmSectionExtendSetResource;
// Pagefile creation lock.
FAST_MUTEX MmPageFileCreationLock;
MMDEREFERENCE_SEGMENT_HEADER MmDereferenceSegmentHeader;
LIST_ENTRY MmUnusedSegmentList;
KEVENT MmUnusedSegmentCleanup;
ULONG MmUnusedSegmentCount;
SIZE_T MmMaxUnusedSegmentPagedPoolUsage;// Maximum amount of paged pool to keep in unused segments.
// Amount of paged pool used by unused segments.
SIZE_T MmUnusedSegmentPagedPoolUsage;
SIZE_T MiUnusedSegmentPagedPoolUsage;
SIZE_T MmUnusedSegmentPagedPoolReduction;// Amount to reduce paged pool by when it starts getting low.
SIZE_T MmMaxUnusedSegmentNonPagedPoolUsage;// Maximum amount of nonpaged pool to keep in unused segments.
// Amount of nonpaged pool used by unused segments.
SIZE_T MmUnusedSegmentNonPagedPoolUsage;
SIZE_T MiUnusedSegmentNonPagedPoolUsage;
// Amount to reduce nonpaged pool by when it starts getting low.
SIZE_T MmUnusedSegmentNonPagedPoolReduction;
// Unused File Cache trim level - this is the percentage of pool consumed by unused file segments.
// The minimum is 5%, the maximum (ie: largest caching)
// is 40%. Under 20% is almost always the correct value.
ULONG MmUnusedSegmentTrimLevel = 18;
MMWORKING_SET_EXPANSION_HEAD MmWorkingSetExpansionHead;
MMPAGE_FILE_EXPANSION MmAttemptForCantExtend;
// Paging files
MMMOD_WRITER_LISTHEAD MmPagingFileHeader;
MMMOD_WRITER_LISTHEAD MmMappedFileHeader;
PMMMOD_WRITER_MDL_ENTRY MmMappedFileMdl[MM_MAPPED_FILE_MDLS]; ;
LIST_ENTRY MmFreePagingSpaceLow;
ULONG MmNumberOfActiveMdlEntries;
PMMPAGING_FILE MmPagingFile[MAX_PAGE_FILES];
ULONG MmNumberOfPagingFiles;
KEVENT MmModifiedPageWriterEvent;
KEVENT MmWorkingSetManagerEvent;
KEVENT MmCollidedFlushEvent;
// Total number of committed pages.
SIZE_T MmTotalCommittedPages;
// Limit on committed pages. When MmTotalCommittedPages would become
// greater than or equal to this number the paging files must be expanded.
SIZE_T MmTotalCommitLimit;
SIZE_T MmTotalCommitLimitMaximum;
// Number of pages to overcommit without expanding the paging file.
// MmTotalCommitLimit = (total paging file space) + MmOverCommit.
SIZE_T MmOverCommit;
// Modified page writer.
// Minimum number of free pages before working set trimming and aggressive modified page writing is started.
PFN_NUMBER MmMinimumFreePages = 26;
// Stop writing modified pages when MmFreeGoal pages exist.
PFN_NUMBER MmFreeGoal = 100;
// Start writing pages if more than this number of pages is on the modified page list.
PFN_NUMBER MmModifiedPageMaximum;
// Minimum number of modified pages required before the modified page writer is started.
PFN_NUMBER MmModifiedPageMinimum;
// Amount of disk space that must be free after the paging file is extended.
ULONG MmMinimumFreeDiskSpace = 1024 * 1024;
// Size to extend the paging file by.
ULONG MmPageFileExtension = 128; //128 pages
// Size to reduce the paging file by.
ULONG MmMinimumPageFileReduction = 256; //256 pages (1mb)
ULONG MmModifiedWriteClusterSize = MM_MAXIMUM_WRITE_CLUSTER;// Number of pages to write in a single I/O.
ULONG MmReadClusterSize = 7;// Number of pages to read in a single I/O if possible.
// Spin locks.
// Spinlock which guards PFN database.
// This spinlock is used by memory management for accessing the PFN database.
// The I/O system makes use of it for unlocking pages during I/O completion.
// KSPIN_LOCK MmPfnLock;
// Spinlock which guards the working set list for the system shared address space (paged pool, system cache, pagable drivers).
ERESOURCE MmSystemWsLock;
PETHREAD MmSystemLockOwner;
// Spin lock for allowing working set expansion.
KSPIN_LOCK MmExpansionLock;
// Spin lock for protecting hyper space access.
// System process working set sizes.
PFN_NUMBER MmSystemProcessWorkingSetMin = 50;
PFN_NUMBER MmSystemProcessWorkingSetMax = 450;
PFN_NUMBER MmMaximumWorkingSetSize;
PFN_NUMBER MmMinimumWorkingSetSize = 20;
ULONG MmSystemPageColor;// Page color for system working set.
LARGE_INTEGER MmSevenMinutes = { 0, -1 };// Time constants
// note that the following constant is initialized to five seconds, but is set to 3 on very small workstations.
// The constant used to be called MmFiveSecondsAbsolute, but since its value changes depending on
// the system type and size, I decided to change the name to reflect this
LARGE_INTEGER MmWorkingSetProtectionTime = { 5 * 1000 * 1000 * 10, 0 };
LARGE_INTEGER MmOneSecond = { (ULONG)(-1 * 1000 * 1000 * 10), -1 };
LARGE_INTEGER MmTwentySeconds = { (ULONG)(-20 * 1000 * 1000 * 10), -1 };
LARGE_INTEGER MmShortTime = { (ULONG)(-10 * 1000 * 10), -1 };// 10 milliseconds
LARGE_INTEGER MmHalfSecond = { (ULONG)(-5 * 100 * 1000 * 10), -1 };
LARGE_INTEGER Mm30Milliseconds = { (ULONG)(-30 * 1000 * 10), -1 };
// Parameters for user mode passed up via PEB in MmCreatePeb
ULONG MmCritsectTimeoutSeconds = 2592000;
LARGE_INTEGER MmCriticalSectionTimeout;// Filled in by mminit.c
SIZE_T MmHeapSegmentReserve = 1024 * 1024;
SIZE_T MmHeapSegmentCommit = PAGE_SIZE * 2;
SIZE_T MmHeapDeCommitTotalFreeThreshold = 64 * 1024;
SIZE_T MmHeapDeCommitFreeBlockThreshold = PAGE_SIZE;
// Set from ntos\config\CMDAT3.C Used by customers to disable paging of executive on machines with lots of memory.
// Worth a few TPS on a database server.
ULONG MmDisablePagingExecutive;
BOOLEAN Mm64BitPhysicalAddress;
#if DBG
ULONG MmDebug;
#endif
// Map a page protection from the Pte.Protect field into a protection mask.
ULONG MmProtectToValue[32] = {
PAGE_NOACCESS,
PAGE_READONLY,
PAGE_EXECUTE,
PAGE_EXECUTE_READ,
PAGE_READWRITE,
PAGE_WRITECOPY,
PAGE_EXECUTE_READWRITE,
PAGE_EXECUTE_WRITECOPY,
PAGE_NOACCESS,
PAGE_NOCACHE | PAGE_READONLY,
PAGE_NOCACHE | PAGE_EXECUTE,
PAGE_NOCACHE | PAGE_EXECUTE_READ,
PAGE_NOCACHE | PAGE_READWRITE,
PAGE_NOCACHE | PAGE_WRITECOPY,
PAGE_NOCACHE | PAGE_EXECUTE_READWRITE,
PAGE_NOCACHE | PAGE_EXECUTE_WRITECOPY,
PAGE_NOACCESS,
PAGE_GUARD | PAGE_READONLY,
PAGE_GUARD | PAGE_EXECUTE,
PAGE_GUARD | PAGE_EXECUTE_READ,
PAGE_GUARD | PAGE_READWRITE,
PAGE_GUARD | PAGE_WRITECOPY,
PAGE_GUARD | PAGE_EXECUTE_READWRITE,
PAGE_GUARD | PAGE_EXECUTE_WRITECOPY,
PAGE_NOACCESS,
PAGE_NOCACHE | PAGE_GUARD | PAGE_READONLY,
PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE,
PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE_READ,
PAGE_NOCACHE | PAGE_GUARD | PAGE_READWRITE,
PAGE_NOCACHE | PAGE_GUARD | PAGE_WRITECOPY,
PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE_READWRITE,
PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE_WRITECOPY
};
ULONG MmProtectToPteMask[32] = {
MM_PTE_NOACCESS,
MM_PTE_READONLY | MM_PTE_CACHE,
MM_PTE_EXECUTE | MM_PTE_CACHE,
MM_PTE_EXECUTE_READ | MM_PTE_CACHE,
MM_PTE_READWRITE | MM_PTE_CACHE,
MM_PTE_WRITECOPY | MM_PTE_CACHE,
MM_PTE_EXECUTE_READWRITE | MM_PTE_CACHE,
MM_PTE_EXECUTE_WRITECOPY | MM_PTE_CACHE,
MM_PTE_NOACCESS,
MM_PTE_NOCACHE | MM_PTE_READONLY,
MM_PTE_NOCACHE | MM_PTE_EXECUTE,
MM_PTE_NOCACHE | MM_PTE_EXECUTE_READ,
MM_PTE_NOCACHE | MM_PTE_READWRITE,
MM_PTE_NOCACHE | MM_PTE_WRITECOPY,
MM_PTE_NOCACHE | MM_PTE_EXECUTE_READWRITE,
MM_PTE_NOCACHE | MM_PTE_EXECUTE_WRITECOPY,
MM_PTE_NOACCESS,
MM_PTE_GUARD | MM_PTE_READONLY | MM_PTE_CACHE,
MM_PTE_GUARD | MM_PTE_EXECUTE | MM_PTE_CACHE,
MM_PTE_GUARD | MM_PTE_EXECUTE_READ | MM_PTE_CACHE,
MM_PTE_GUARD | MM_PTE_READWRITE | MM_PTE_CACHE,
MM_PTE_GUARD | MM_PTE_WRITECOPY | MM_PTE_CACHE,
MM_PTE_GUARD | MM_PTE_EXECUTE_READWRITE | MM_PTE_CACHE,
MM_PTE_GUARD | MM_PTE_EXECUTE_WRITECOPY | MM_PTE_CACHE,
MM_PTE_NOACCESS,
MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_READONLY,
MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE,
MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE_READ,
MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_READWRITE,
MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_WRITECOPY,
MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE_READWRITE,
MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE_WRITECOPY
};
// Conversion which takes a Pte.Protect and builds a new Pte.Protect which is not copy-on-write.
ULONG MmMakeProtectNotWriteCopy[32] = {
MM_NOACCESS,
MM_READONLY,
MM_EXECUTE,
MM_EXECUTE_READ,
MM_READWRITE,
MM_READWRITE, //not copy
MM_EXECUTE_READWRITE,
MM_EXECUTE_READWRITE,
MM_NOACCESS,
MM_NOCACHE | MM_READONLY,
MM_NOCACHE | MM_EXECUTE,
MM_NOCACHE | MM_EXECUTE_READ,
MM_NOCACHE | MM_READWRITE,
MM_NOCACHE | MM_READWRITE,
MM_NOCACHE | MM_EXECUTE_READWRITE,
MM_NOCACHE | MM_EXECUTE_READWRITE,
MM_NOACCESS,
MM_GUARD_PAGE | MM_READONLY,
MM_GUARD_PAGE | MM_EXECUTE,
MM_GUARD_PAGE | MM_EXECUTE_READ,
MM_GUARD_PAGE | MM_READWRITE,
MM_GUARD_PAGE | MM_READWRITE,
MM_GUARD_PAGE | MM_EXECUTE_READWRITE,
MM_GUARD_PAGE | MM_EXECUTE_READWRITE,
MM_NOACCESS,
MM_NOCACHE | MM_GUARD_PAGE | MM_READONLY,
MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE,
MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE_READ,
MM_NOCACHE | MM_GUARD_PAGE | MM_READWRITE,
MM_NOCACHE | MM_GUARD_PAGE | MM_READWRITE,
MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE_READWRITE,
MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE_READWRITE
};
// Converts a protection code to an access right for section access.
// This uses only the lower 3 bits of the 5 bit protection code.
ACCESS_MASK MmMakeSectionAccess[8] = { SECTION_MAP_READ,
SECTION_MAP_READ,
SECTION_MAP_EXECUTE,
SECTION_MAP_EXECUTE | SECTION_MAP_READ,
SECTION_MAP_WRITE,
SECTION_MAP_READ,
SECTION_MAP_EXECUTE | SECTION_MAP_WRITE,
SECTION_MAP_EXECUTE | SECTION_MAP_READ };
// Converts a protection code to an access right for file access.
// This uses only the lower 3 bits of the 5 bit protection code.
ACCESS_MASK MmMakeFileAccess[8] = { FILE_READ_DATA,
FILE_READ_DATA,
FILE_EXECUTE,
FILE_EXECUTE | FILE_READ_DATA,
FILE_WRITE_DATA | FILE_READ_DATA,
FILE_READ_DATA,
FILE_EXECUTE | FILE_WRITE_DATA | FILE_READ_DATA,
FILE_EXECUTE | FILE_READ_DATA };
MM_PAGED_POOL_INFO MmPagedPoolInfo;
// Some Hydra variables.
BOOLEAN MiHydra;
ULONG_PTR MmSessionBase;
PMM_SESSION_SPACE MmSessionSpace;
LIST_ENTRY MiSessionWsList;
ULONG_PTR MiSystemViewStart;
// Both retry level and initial count must both be initialized to the same value.
// Note that the Driver Verifier can override these.
ULONG MiIoRetryLevel = 25;
ULONG MiFaultRetries = 25;
ULONG MiUserIoRetryLevel = 10;
ULONG MiUserFaultRetries = 10;
#ifdef ALLOC_DATA_PRAGMA
#pragma data_seg("INIT")
#endif
WCHAR MmVerifyDriverBuffer[MI_SUSPECT_DRIVER_BUFFER_LENGTH];
ULONG MmVerifyDriverBufferLength = sizeof(MmVerifyDriverBuffer);
ULONG MmVerifyDriverBufferType = REG_NONE;
ULONG MmVerifyDriverLevel = (ULONG)-1;
#ifdef ALLOC_DATA_PRAGMA
#pragma data_seg()
#endif