• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
thankgoodness
博客园    首页    新随笔    联系   管理    订阅  订阅

VirtualQueryEx描述,涉及内存管理的flag

函数功能描述:查询地址空间中内存地址的信息。

函数原型:

DWORD VirtualQueryEx( HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, DWORD dwLength );

参数:
    hProcess    进程句柄。
    LpAddress   查询内存的地址。
    LpBuffer    指向MEMORY_BASIC_INFORMATION结构的指针,用于接收内存信息。
    DwLength    MEMORY_BASIC_INFORMATION结构的大小。

返回值:
    函数写入lpBuffer的字节数,如果不等于sizeof(MEMORY_BASIC_INFORMATION)表示失败。

备注:
    MEMORY_BASIC_INFORMATION在WinNT.h中定义如下:
        typedef struct _MEMORY_BASIC_INFORMATION {
            PVOID BaseAddress;       // 区域基地址。
            PVOID AllocationBase;    // 分配基地址。
            DWORD AllocationProtect; // 区域被初次保留时赋予的保护属性。
            SIZE_T RegionSize;       // 区域大小(以字节为计量单位)。
            DWORD State;             // 状态(MEM_FREE、MEM_RESERVE或 MEM_COMMIT)。
            DWORD Protect;           // 保护属性。
            DWORD Type;              // 类型。
        } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;

成员解释:

    BaseAddress                    与LpAddress参数的值相同,但是四舍五入为页面的边界值。

    AllocationBase                 指明用VirtualAlloc函数分配内存区域的基地址。LpAddress
                                   在该区域之内。

    AllocationProtect              指明该地址空间区域被初次保留时赋予该区域的保护属性。

        PAGE_READONLY              只读属性,如果试图进行写操作,将引发访问违规。如果系统
                                   区分只读、执行两种属性,那么试图在该区域执行代码也将引
                                   发访问违规。

        PAGE_READWRITE             允许读写。

        PAGE_EXECUTE               只允许执行代码,对该区域试图进行读写操作将引发访问违规。

        PAGE_EXECUTE_READ          允许执行和读取。

        PAGE_EXECUTE_READWRITE     允许读写和执行代码。

        PAGE_EXECUTE_WRITECOPY     对于该地址空间的区域,不管执行什么操作,都不会引发访问违
                                   规。如果试图在该页面上的内存中进行写入操作,就会将它自己
                                   的私有页面(受页文件的支持)拷贝赋予该进程。

        PAGE_GUARD                 在页面上写入一个字节时使应用程序收到一个通知(通过一个异
                                   常条件)。该标志有一些非常巧妙的用法。Windows 2000在创建
                                   线程堆栈时使用该标志。

        PAGE_NOACCESS              禁止一切访问。

        PAGE_NOCACHE               停用已提交页面的高速缓存。一般情况下最好不要使用该标志,
                                   因为它主要是供需要处理内存缓冲区的硬件设备驱动程序的开发
                                   人员使用的。

    RegionSize                     用于指明内存块从基地址即BaseAddress开始的所有页面的大
                                   小(以字节为计量单位)这些页面与含有用LpAddress参数设
                                   定的地址的页面拥有相同的保护属性、状态和类型。

    State                          用于指明所有相邻页面的状态。

        MEM_COMMIT                 指明已分配物理内存或者系统页文件。

        MEM_FREE                   空闲状态。该区域的虚拟地址不受任何内存的支持。该地址空间没
                                   有被保留。改状态下AllocationBase、AllocationProtect、Protect
                                   和Type等成员均未定义。

        MEM_RESERVE                指明页面被保留,但是没有分配任何物理内存。该状态下Protect成
                                   员未定。

    Protect                        用于指明所有相邻页面(内存块)的保护属性。这些页面与含有
                                   拥有相同的保属性、状态和类型。意义同AllocationProtect。

    Type                           用于指明支持所有相邻页面的物理存储器的类型(MEM_IMAGE,
                                   MEM_MAPPED或MEM_PRIVATE)。这些相邻页面拥有相同的保护属
                                   性、状态和类型。如果是Windows 98,那么这个成员将总是
                                   MEM_PRIVATE 。

        MEM_IMAGE                 指明该区域的虚拟地址原先受内存映射的映像文件(如.exe或DLL
                                  文件)的支持,但也许不再受映像文件的支持。例如,当写入模块
                                  映像中的全局变量时,“写入时拷贝”的机制将由页文件来支持特
                                  定的页面,而不是受原始映像文件的支持。

        MEM_MAPPED                该区域的虚拟地址原先是受内存映射的数据文件的支持,但也许不
                                  再受数据文件的支持。例如,数据文件可以使用“写入时拷贝”的
                                  保护属性来映射。对文件的任何写入操作都将导致页文件而不是原
                                  始数据支持特定的页面。

        MEM_PRIVATE               指明该内存区域是私有的。不被其他进程共享。


#include "stdafx.h"
#include <windows.h>
#include <TCHAR.H>

BOOL ShowProcMemInfo(DWORD dwPID);

int _tmain(int argc, char* argv[])
{
   ShowProcMemInfo( GetCurrentProcessId() );
   return 0;
}


//
显示一个进程的内存状态 dwPID为进程ID
BOOL ShowProcMemInfo(DWORD dwPID)
{
   HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
                          FALSE,
                          dwPID);
   if(hProcess == NULL)
      return FALSE;
   MEMORY_BASIC_INFORMATION mbi;
   PBYTE pAddress = NULL;
   TCHAR szInfo[200] = _T("BaseAddr     Size        Type        State         Protect "n");
   _tprintf(szInfo);

   while(TRUE)
   {
      if(VirtualQueryEx(hProcess, pAddress, &mbi, sizeof(mbi)) != sizeof(mbi))
      {
         break;
      }
      if((mbi.AllocationBase != mbi.BaseAddress) && (mbi.State != MEM_FREE))
      {
         _stprintf(szInfo, _T("  %08X  %8dK  "),
              mbi.BaseAddress,
              mbi.RegionSize>>10);
      }
      else
      {
         _stprintf(szInfo, _T("%08X    %8dK  "),
              mbi.BaseAddress,
              mbi.RegionSize>>10);
      }
      PCTSTR pStr = _T("");
      switch(mbi.Type)
      {
      case MEM_IMAGE:      pStr = _T("MEM_IMAGE  "); break;
      case MEM_MAPPED:   pStr = _T("MEM_MAPPED "); break;
      case MEM_PRIVATE:   pStr = _T("MEM_PRIVATE"); break;
      default:         pStr = _T("-----------"); break;
      }
      _tcscat(szInfo, pStr);
      _tcscat(szInfo, _T("  "));

      switch(mbi.State)
      {
      case MEM_COMMIT:   pStr = _T("MEM_COMMIT "); break;
      case MEM_RESERVE:   pStr = _T("MEM_RESERVE"); break;
      case MEM_FREE:      pStr = _T("MEM_FREE   "); break;
      default:         pStr = _T("-----------"); break;
      }
      _tcscat(szInfo, pStr);
      _tcscat(szInfo, _T("  "));

      switch(mbi.AllocationProtect)
      {
      case PAGE_READONLY:            pStr = _T("PAGE_READONLY         "); break;  
      case PAGE_READWRITE:         pStr = _T("PAGE_READWRITE        "); break;  
      case PAGE_WRITECOPY:         pStr = _T("PAGE_WRITECOPY        "); break;  
      case PAGE_EXECUTE:            pStr = _T("PAGE_EXECUTE          "); break;  
      case PAGE_EXECUTE_READ:         pStr = _T("PAGE_EXECUTE_READ     "); break;  
      case PAGE_EXECUTE_READWRITE:   pStr = _T("PAGE_EXECUTE_READWRITE"); break;  
      case PAGE_EXECUTE_WRITECOPY:   pStr = _T("PAGE_EXECUTE_WRITECOPY"); break;  
      case PAGE_GUARD:            pStr = _T("PAGE_GUARD            "); break;  
      case PAGE_NOACCESS:            pStr = _T("PAGE_NOACCESS         "); break;  
      case PAGE_NOCACHE:            pStr = _T("PAGE_NOCACHE          "); break;  
      default:                  pStr = _T("----------------------"); break;
      }
      _tcscat(szInfo, pStr);
      _tcscat(szInfo, _T(""n"));
      _tprintf(szInfo);

      pAddress = ((PBYTE)mbi.BaseAddress + mbi.RegionSize);
   }
   CloseHandle(hProcess);
   return TRUE;
}

posted @ 2009-05-21 15:24  宇晨  阅读(2406)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3