mirror of
https://github.com/zodiacon/WindowsInternals
synced 2026-08-09 13:18:09 +00:00
193 lines
12 KiB
C++
193 lines
12 KiB
C++
#include "stdafx.h"
|
|
|
|
#pragma comment(lib, "ntdll")
|
|
|
|
extern "C" {
|
|
#include "ntndk.h"
|
|
}
|
|
|
|
typedef enum _MI_SYSTEM_VA_TYPE {
|
|
MiVaUnused = 0,
|
|
MiVaSessionSpace = 1,
|
|
MiVaProcessSpace = 2,
|
|
MiVaBootLoaded = 3,
|
|
MiVaPfnDatabase = 4,
|
|
MiVaNonPagedPool = 5,
|
|
MiVaPagedPool = 6,
|
|
MiVaSpecialPool = 7,
|
|
MiVaSystemCache = 8,
|
|
MiVaSystemPtes = 9,
|
|
MiVaHal = 10,
|
|
MiVaSessionGlobalSpace = 11,
|
|
MiVaDriverImageSpace = 12,
|
|
MiVaMaximumType = 13
|
|
} MI_SYSTEM_VA_TYPE;
|
|
|
|
typedef struct _MM_SYSTEM_VA_LIST_ENTRY {
|
|
ULONG Number;
|
|
ULONG Peak;
|
|
ULONG Limit;
|
|
ULONG Failures;
|
|
} MM_SYSTEM_VA_LIST_ENTRY, *PMM_SYSTEM_VA_LIST_ENTRY;
|
|
|
|
typedef struct _MM_SYSTEM_VA_LIST {
|
|
ULONG AvailableVa;
|
|
ULONG AvailableVaLow;
|
|
ULONG Reserved;
|
|
ULONG TotalFailures;
|
|
MM_SYSTEM_VA_LIST_ENTRY Entry[5];
|
|
} MM_SYSTEM_VA_LIST, *PMM_SYSTEM_VA_LIST;
|
|
|
|
int main(int argc, const char* argv[]) {
|
|
NTSTATUS ntStatus;
|
|
BOOLEAN old;
|
|
ULONG resultLength;
|
|
MM_SYSTEM_VA_LIST systemVaInfo = { 0 };
|
|
ULONG i;
|
|
ULONG SetNonPaged = 0, SetPaged = 0, SetSession = 0, SetSystem = 0, SetCache = 0, SetQuery = 0, SetRegistry = 0;
|
|
|
|
//
|
|
// Print header
|
|
//
|
|
printf("\nMemLimit v1.00 - Query and set hard limits on system VA space consumption\n");
|
|
printf("Copyright (C) 2008 Alex Ionescu\n");
|
|
printf("www.alex-ionescu.com\n\n");
|
|
|
|
//
|
|
// Check if no parameters given
|
|
//
|
|
if (argc == 1)
|
|
{
|
|
//
|
|
// Display usage
|
|
//
|
|
printf("usage: memlimit [-q|-r][-n size] [-p size] [-s size] [-c size] [-t size]\n");
|
|
printf("%6s Queries the current consumption, peak, and maximums on system VA for this system and does not set any limits\n", "-q");
|
|
printf("%6s Specifies that the limits being set should be written to the registry, making them persistent\n", "-r");
|
|
printf("%6s Specifies the maximum amount of system VA space that can be used by the nonpaged pool\n"
|
|
" Under certain conditions, this limit may be exceeded by a small amount\n", "-n");
|
|
printf("%6s Specifies the maximum amount of system VA space that can be used by the paged pool\n", "-p");
|
|
printf("%6s Specifies the maximum amount of system VA space that can be used by session space allocations\n", "-s");
|
|
printf("%6s Specifies the maximum amount of system VA space that can be used by the system cache\n"
|
|
" Under certain conditions, this limit may be exceeded by a small amount\n", "-c");
|
|
printf("%6s Specifies the maximum amount of system VA space that can be used by I/O mappings\n"
|
|
" and other resources that consume system page table entries (PTEs)\n", "-t");
|
|
printf("\nThe default is 0, which means no limit is enforced.\n"
|
|
"Sizes are in MB automatically rounded up to the next system VA allocation boundary,\n"
|
|
"which is 2 MB on 32-bit systems that have Physical Address Extension (PAE) enabled\n"
|
|
"and 4 MB on 32-bit systems that do not have PAE enabled.\n");
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// Get increase working set privilege
|
|
//
|
|
ntStatus = RtlAdjustPrivilege(SE_INCREASE_QUOTA_PRIVILEGE, TRUE, FALSE, &old);
|
|
if (!NT_SUCCESS(ntStatus))
|
|
{
|
|
//
|
|
// Display error
|
|
//
|
|
printf("Failed to get required privilege.\n");
|
|
printf("Make sure that you are running with administrative privileges\n"
|
|
"and that your account has the increase quota privilege\n");
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// Check what we should do
|
|
//
|
|
for (i = 0; i < (ULONG)argc; i++)
|
|
{
|
|
//
|
|
// Check what the user wants
|
|
//
|
|
if (strstr(argv[i], "-q")) SetQuery = i + 1;
|
|
if (strstr(argv[i], "-r")) SetRegistry = i + 1;
|
|
if (strstr(argv[i], "-n")) SetNonPaged = i + 1;
|
|
if (strstr(argv[i], "-p")) SetPaged = i + 1;
|
|
if (strstr(argv[i], "-s")) SetSession = i + 1;
|
|
if (strstr(argv[i], "-c")) SetCache = i + 1;
|
|
if (strstr(argv[i], "-t")) SetSystem = i + 1;
|
|
}
|
|
|
|
//
|
|
// Do a query to get current limits
|
|
//
|
|
ntStatus = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS) 106,
|
|
&systemVaInfo,
|
|
sizeof(systemVaInfo),
|
|
&resultLength);
|
|
if (!NT_SUCCESS(ntStatus))
|
|
{
|
|
//
|
|
// Shouldn't really happen
|
|
//
|
|
printf("Failed to query memory limits. This tool only supports Vista SP1/Server 08 and higher!\n");
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// Check if this is only a query
|
|
//
|
|
if (SetQuery)
|
|
{
|
|
doQuery:
|
|
//
|
|
// Tell the user
|
|
//
|
|
printf("System Va Consumption:\n\nType\t\t\tCurrent\t\t Peak\t\t Limit \n"
|
|
"Non Paged Pool\t\t%7d KB\t%7d KB\t%7d KB\n"
|
|
"Paged Pool\t\t%7d KB\t%7d KB\t%7d KB\n"
|
|
"System Cache\t\t%7d KB\t%7d KB\t%7d KB\n"
|
|
"System PTEs\t\t%7d KB\t%7d KB\t%7d KB\n"
|
|
"Session Space\t\t%7d KB\t%7d KB\t%7d KB\n",
|
|
systemVaInfo.Entry[0].Number / 1024,
|
|
systemVaInfo.Entry[0].Peak / 1024,
|
|
systemVaInfo.Entry[0].Limit / 1024,
|
|
systemVaInfo.Entry[1].Number / 1024,
|
|
systemVaInfo.Entry[1].Peak / 1024,
|
|
systemVaInfo.Entry[1].Limit / 1024,
|
|
systemVaInfo.Entry[2].Number / 1024,
|
|
systemVaInfo.Entry[2].Peak / 1024,
|
|
systemVaInfo.Entry[2].Limit / 1024,
|
|
systemVaInfo.Entry[3].Number / 1024,
|
|
systemVaInfo.Entry[3].Peak / 1024,
|
|
systemVaInfo.Entry[3].Limit / 1024,
|
|
systemVaInfo.Entry[4].Number / 1024,
|
|
systemVaInfo.Entry[4].Peak / 1024,
|
|
systemVaInfo.Entry[4].Limit / 1024);
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Now get the limits
|
|
//
|
|
if (SetNonPaged) systemVaInfo.Entry[0].Limit = atol(argv[SetNonPaged]) * 1024 * 1024;
|
|
if (SetPaged) systemVaInfo.Entry[1].Limit = atol(argv[SetPaged]) * 1024 * 1024;
|
|
if (SetCache) systemVaInfo.Entry[2].Limit = atol(argv[SetCache]) * 1024 * 1024;
|
|
if (SetSystem) systemVaInfo.Entry[3].Limit = atol(argv[SetSystem]) * 1024 * 1024;
|
|
if (SetSession) systemVaInfo.Entry[4].Limit = atol(argv[SetSession]) * 1024 * 1024;
|
|
|
|
//
|
|
// And set them!
|
|
//
|
|
ntStatus = NtSetSystemInformation((SYSTEM_INFORMATION_CLASS) 106,
|
|
&systemVaInfo,
|
|
sizeof(systemVaInfo));
|
|
if (!NT_SUCCESS(ntStatus))
|
|
{
|
|
//
|
|
// Shouldn't really happen
|
|
//
|
|
printf("Failed to set memory limits. This tool only supports Vista SP1/Server 08 and higher!\n");
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// Print current state
|
|
//
|
|
printf("Limits set succesfully!\n\n");
|
|
goto doQuery;
|
|
}
|