Я использую C ++ на Windows под Visual Studio 2012.
У меня есть начальный и конечный адрес памяти, и мне нужно сгенерировать список базовых адресов / дескрипторов страниц между двумя адресами. Я рассмотрел возможность проверки страниц вручную, но подумал, что должен быть лучший способ их перечисления.
Существует ли такой способ?
Отказ от ответственности; Дескрипторы последней страницы должны быть базовым адресом, чтобы при добавлении к ним размера страницы Windows результирующий адрес не перекрывался на следующей странице. Предпочтительное решение не будет зависеть от платформы и будет совместимо с 32-битным с / без WOW64.
VirtualQuery
в значительной степени ваш единственный вариант. Это должно быть довольно эффективно:
Функция определяет атрибуты первой страницы в регионе
а затем сканирует последующие страницы, пока не отсканирует весь диапазон
страниц или пока он не встретит страницу с несоответствующим набором
атрибутов.
Таким образом, вы начнете с того, что позвоните ему в начале интересующего вас диапазона, и получите обратно один кусок страниц. Следующий вызов начнется сразу после этого чанка, и следующий после этого, и так далее.
Вот полностью непроверенная функция, которая заполняет массив MEMORY_BASIC_INFORMATION
структуры:
int EnumVirtualAllocations(const void* ptr, size_t length, MEMORY_BASIC_INFORMATION* info, int size)
{
const void* end = (const void*)((const char*)ptr + length);
int index = 0;
while (index < size && ptr < end &&
VirtualQuery(ptr, &info[index], sizeof(*info)) == sizeof(*info))
{
MEMORY_BASIC_INFORMATION* i = &info[index];
if (i->State != MEM_FREE) index++;
ptr = (const void*)((const char*)(i->BaseAddress) + i->RegionSize);
}
return index;
}
Других решений пока нет …