tstNtQueryStuff.cpp revision 739d6ae13d627830974df4bfba63c1d5fab987b7
377d39fe3665e7789e39798b5d444df798ab610cvboxsync/* $Id$ */
377d39fe3665e7789e39798b5d444df798ab610cvboxsync/** @file
377d39fe3665e7789e39798b5d444df798ab610cvboxsync * SUP Testcase - Exploring some NT Query APIs.
377d39fe3665e7789e39798b5d444df798ab610cvboxsync */
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsync/*
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2006-2012 Oracle Corporation
377d39fe3665e7789e39798b5d444df798ab610cvboxsync *
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * available from http://www.virtualbox.org. This file is free software;
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * you can redistribute it and/or modify it under the terms of the GNU
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * General Public License (GPL) as published by the Free Software
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync *
377d39fe3665e7789e39798b5d444df798ab610cvboxsync * The contents of this file may alternatively be used under the terms
377d39fe3665e7789e39798b5d444df798ab610cvboxsync * of the Common Development and Distribution License Version 1.0
377d39fe3665e7789e39798b5d444df798ab610cvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
377d39fe3665e7789e39798b5d444df798ab610cvboxsync * VirtualBox OSE distribution, in which case the provisions of the
377d39fe3665e7789e39798b5d444df798ab610cvboxsync * CDDL are applicable instead of those of the GPL.
8998be4b936b8b2d62f2165039f464c71112bda4vboxsync *
377d39fe3665e7789e39798b5d444df798ab610cvboxsync * You may elect to license modified versions of this file under the
377d39fe3665e7789e39798b5d444df798ab610cvboxsync * terms and conditions of either the GPL or the CDDL or both.
377d39fe3665e7789e39798b5d444df798ab610cvboxsync */
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsync/*******************************************************************************
377d39fe3665e7789e39798b5d444df798ab610cvboxsync* Header Files *
377d39fe3665e7789e39798b5d444df798ab610cvboxsync*******************************************************************************/
377d39fe3665e7789e39798b5d444df798ab610cvboxsync#include <Windows.h>
377d39fe3665e7789e39798b5d444df798ab610cvboxsync#include <winternl.h>
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsynctypedef enum
377d39fe3665e7789e39798b5d444df798ab610cvboxsync{
377d39fe3665e7789e39798b5d444df798ab610cvboxsync MemoryBasicInformation = 0,
377d39fe3665e7789e39798b5d444df798ab610cvboxsync MemoryWorkingSetList,
377d39fe3665e7789e39798b5d444df798ab610cvboxsync MemorySectionName,
377d39fe3665e7789e39798b5d444df798ab610cvboxsync MemoryBasicVlmInformation
377d39fe3665e7789e39798b5d444df798ab610cvboxsync} MEMORY_INFORMATION_CLASS;
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsynctypedef struct
377d39fe3665e7789e39798b5d444df798ab610cvboxsync{
8998be4b936b8b2d62f2165039f464c71112bda4vboxsync UNICODE_STRING SectionFileName;
8998be4b936b8b2d62f2165039f464c71112bda4vboxsync WCHAR NameBuffer[ANYSIZE_ARRAY];
377d39fe3665e7789e39798b5d444df798ab610cvboxsync} MEMORY_SECTION_NAME;
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsyncextern "C"
377d39fe3665e7789e39798b5d444df798ab610cvboxsyncNTSYSAPI NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE hProcess,
377d39fe3665e7789e39798b5d444df798ab610cvboxsync IN LPCVOID pvWhere,
bbc0a3fc49446bf8fa1fcfe669c10875701692bcvboxsync IN MEMORY_INFORMATION_CLASS MemoryInfo,
dc5cd2ea4ab36898ba3231203f52460a39189263vboxsync OUT PVOID pvBuf,
377d39fe3665e7789e39798b5d444df798ab610cvboxsync IN SIZE_T cbBuf,
377d39fe3665e7789e39798b5d444df798ab610cvboxsync OUT PSIZE_T pcbReturned OPTIONAL);
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsync#include <iprt/test.h>
dc5cd2ea4ab36898ba3231203f52460a39189263vboxsync#include <iprt/string.h>
dc5cd2ea4ab36898ba3231203f52460a39189263vboxsync
dc5cd2ea4ab36898ba3231203f52460a39189263vboxsync
bbc0a3fc49446bf8fa1fcfe669c10875701692bcvboxsync/*******************************************************************************
377d39fe3665e7789e39798b5d444df798ab610cvboxsync* Structures and Typedefs *
377d39fe3665e7789e39798b5d444df798ab610cvboxsync*******************************************************************************/
377d39fe3665e7789e39798b5d444df798ab610cvboxsynctypedef struct FLAGDESC
377d39fe3665e7789e39798b5d444df798ab610cvboxsync{
377d39fe3665e7789e39798b5d444df798ab610cvboxsync ULONG f;
bbc0a3fc49446bf8fa1fcfe669c10875701692bcvboxsync const char *psz;
bbc0a3fc49446bf8fa1fcfe669c10875701692bcvboxsync} FLAGDESC;
bbc0a3fc49446bf8fa1fcfe669c10875701692bcvboxsynctypedef const FLAGDESC *PCFLAGDESC;
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
377d39fe3665e7789e39798b5d444df798ab610cvboxsync
/*******************************************************************************
* Global Variables *
*******************************************************************************/
static RTTEST g_hTest = NIL_RTTEST;
static char *stringifyAppend(char *pszBuf, size_t *pcbBuf, const char *pszAppend, bool fWithSpace)
{
size_t cchAppend = strlen(pszAppend);
if (cchAppend + 1 + fWithSpace <= *pcbBuf)
{
if (fWithSpace)
{
*pszBuf++ = ' ';
*pcbBuf += 1;
}
memcpy(pszBuf, pszAppend, cchAppend + 1);
*pcbBuf -= cchAppend;
pszBuf += cchAppend;
}
return pszBuf;
}
static char *stringifyAppendUnknownFlags(uint32_t fFlags, char *pszBuf, size_t *pcbBuf, bool fWithSpace)
{
for (unsigned iBit = 0; iBit < 32; iBit++)
if (fFlags & RT_BIT_32(iBit))
{
char szTmp[32]; /* lazy bird */
RTStrPrintf(szTmp, sizeof(szTmp), "BIT(%d)", iBit);
pszBuf = stringifyAppend(pszBuf, pcbBuf, szTmp, fWithSpace);
fWithSpace = true;
}
return pszBuf;
}
static char *stringifyFlags(uint32_t fFlags, char *pszBuf, size_t cbBuf, PCFLAGDESC paFlagDesc, size_t cFlagDesc)
{
char *pszBufStart = pszBuf;
if (fFlags)
{
for (size_t i = 0; i < cFlagDesc; i++)
{
if (fFlags & paFlagDesc[i].f)
{
fFlags &= ~paFlagDesc[i].f;
pszBuf = stringifyAppend(pszBuf, &cbBuf, paFlagDesc[i].psz, pszBuf != pszBufStart);
}
}
if (fFlags)
stringifyAppendUnknownFlags(fFlags, pszBuf, &cbBuf, pszBuf != pszBufStart);
}
else
{
pszBuf[0] = '0';
pszBuf[1] = '\0';
}
return pszBufStart;
}
static char *stringifyMemType(uint32_t fType, char *pszBuf, size_t cbBuf)
{
static const FLAGDESC s_aMemTypes[] =
{
{ MEM_PRIVATE, "PRIVATE" },
{ MEM_MAPPED, "MAPPED" },
{ MEM_IMAGE, "IMAGE" },
};
return stringifyFlags(fType, pszBuf, cbBuf, s_aMemTypes, RT_ELEMENTS(s_aMemTypes));
}
static char *stringifyMemState(uint32_t fState, char *pszBuf, size_t cbBuf)
{
static const FLAGDESC s_aMemStates[] =
{
{ MEM_FREE, "FREE" },
{ MEM_COMMIT, "COMMIT" },
{ MEM_RESERVE, "RESERVE" },
{ MEM_DECOMMIT, "DECOMMMIT" },
};
return stringifyFlags(fState, pszBuf, cbBuf, s_aMemStates, RT_ELEMENTS(s_aMemStates));
}
static char *stringifyMemProt(uint32_t fProt, char *pszBuf, size_t cbBuf)
{
static const FLAGDESC s_aProtections[] =
{
{ PAGE_NOACCESS, "NOACCESS" },
{ PAGE_READONLY, "READONLY" },
{ PAGE_READWRITE, "READWRITE" },
{ PAGE_WRITECOPY, "WRITECOPY" },
{ PAGE_EXECUTE, "EXECUTE" },
{ PAGE_EXECUTE_READ, "EXECUTE_READ" },
{ PAGE_EXECUTE_READWRITE, "EXECUTE_READWRITE" },
{ PAGE_EXECUTE_WRITECOPY, "EXECUTE_WRITECOPY" },
{ PAGE_GUARD, "GUARD" },
{ PAGE_NOCACHE, "NOCACHE" },
{ PAGE_WRITECOMBINE, "WRITECOMBINE" },
};
return stringifyFlags(fProt, pszBuf, cbBuf, s_aProtections, RT_ELEMENTS(s_aProtections));
}
static void tstQueryVirtualMemory(void)
{
RTTestISub("NtQueryVirtualMemory");
uintptr_t cbAdvance = 0;
uintptr_t uPtrWhere = 0;
for (;;)
{
SIZE_T cbActual = 0;
MEMORY_BASIC_INFORMATION MemInfo = { 0, 0, 0, 0, 0, 0, 0 };
NTSTATUS ntRc = NtQueryVirtualMemory(GetCurrentProcess(),
(void const *)uPtrWhere,
MemoryBasicInformation,
&MemInfo,
sizeof(MemInfo),
&cbActual);
if (!NT_SUCCESS(ntRc))
{
RTTestIPrintf(RTTESTLVL_ALWAYS, "%p: ntRc=%#x\n", uPtrWhere, ntRc);
break;
}
/* stringify the memory state. */
char szMemType[1024];
char szMemState[1024];
char szMemProt[1024];
RTTestIPrintf(RTTESTLVL_ALWAYS, "%p-%p %-8s %-8s %-12s\n",
MemInfo.BaseAddress, (uintptr_t)MemInfo.BaseAddress + MemInfo.RegionSize - 1,
stringifyMemType(MemInfo.Type, szMemType, sizeof(szMemType)),
stringifyMemState(MemInfo.State, szMemState, sizeof(szMemState)),
stringifyMemProt(MemInfo.Protect, szMemProt, sizeof(szMemProt))
);
if ((uintptr_t)MemInfo.BaseAddress != uPtrWhere)
RTTestIPrintf(RTTESTLVL_ALWAYS, " !Warning! Queried %p got BaseAddress=%p!\n",
uPtrWhere, MemInfo.BaseAddress);
cbAdvance = MemInfo.RegionSize;
//cbAdvance = 0;
if (uPtrWhere + cbAdvance <= uPtrWhere)
break;
uPtrWhere += MemInfo.RegionSize;
}
}
//NtQueryInformationProcess
int main()
{
RTEXITCODE rcExit = RTTestInitAndCreate("tstNtQueryStuff", &g_hTest);
if (rcExit != RTEXITCODE_SUCCESS)
return rcExit;
RTTestBanner(g_hTest);
tstQueryVirtualMemory();
return RTTestSummaryAndDestroy(g_hTest);
}