Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Функция VMQuery


Начиная изучать архитектуру памяти в Windows, я пользовался функцией VirtualQuery как «поводырем». Если Вы читали первое издание моей книги, то заметите, что про грамма VMMap была гораздо проще ее нынешней версии, представленной в следую щем разделе. Прежняя была построена на очень простом цикле, из которого перио дически вызывалась функция VirtualQuery, и для каждого вызова я формировал одпу строку, содержавшую элементы структуры MEMORY_BASIC__INFORMATION. Изучая полученные дампы и сверяясь с документацией из SDK (в то время весьма неудачной), я пытался разобраться в архитектуре подсистемы управления памятью. Что ж, с тех пор я многому научился и теперь знаю, что функция VirtualQuery и структура MEMO RY_BASIC_INFORMATION не дают полной картины

Проблема в том, чю в MEMORY_BASIC_INFORMATION возвращается отнюдь не вся информация, имеющаяся в распоряжении системы. Если Вам нужны простейшие дан ные о состоянии памяти по конкретному адресу, VirtualQuery действительно незаме нима. Она отлично работает, если Вас интересует, передана ли по этому адресу фи зическая память и доступен ли он для операций чтения или записи. Но попробуйте e ее помощью узнать общий размер зарезервированного региона и количество блоков в нем или выяснить, не содержит ли этот регион стек потока, — ничего не выйдет

Чтобы получать более полную информацию о памяти, я создал собственную фун кцию и назвал ее VMQuery.

BOOL VMQuery( HANDLE hProcess, PVOID pvAddress, PVMQUERY pVMQ);

По аналогии с VirtualQueryEx она принимает в hProcess описатель процесса, в pvAddress — адрес памяти, а в pVMQ — указатель на структуру, заполняемую самой функцией. Структура VMQUERY (тоже определенная мной) представляет собой вот что.

typedef struct
{

// информация о регионе
PVOID pvRgnBaseAddress;
DWORD dwRgnProtection;

// PAGE_*
SIZE_T RgnSize;
DWORD dwRgnStorage;

// MEM_* Free. Irnage, Mapped, Private
DWORD dwRgnBlocks;
DWORD dwRgnGuardBlks; // если > 0, регион содержит стек потока
BOOL tRqnlsAStack; // TRUE, если регион содержит стек потока




Начало  Назад  Вперед