Есть ли ограничения на использование MapViewOfFile?

Я пытаюсь использовать файлы с отображением памяти как:

hFile = ::CreateFile(State.Path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 0, OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN, 0);//open the file

if(hFile !=INVALID_HANDLE_VALUE){
hMap= ::CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0);//create Mem mapping for the file in virtual memory
if( hMap!=NULL){
base = ::MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);//load the mapped file into the RAM
//start to compare some bytes (values) from mspaint.exe file in Win7
if( *((BYTE *)base + 0x1C3DF0)== 0x05 )
i++; 
if( *((BYTE *)base + 0x25250C)== 0x21 )
i++;
if( *((BYTE *)base + 0x25272A)== 0x97 )
i++;

if(i==3){
// the file is malicious
}

Как только размер файла будет в гигабайтах, функция MapViewOfFile перестанет работать, и приложение рухнет! Есть ли ограничения на использование MapViewOfFile? Любое предложение?


person Aan    schedule 06.11.2011    source источник


Ответы (3)


Вам нужно проверить возвращаемое значение! Другую причину сбоя можно найти в разделе примечаний MapViewOfFile на MSDN:

Чтобы защититься от исключений EXCEPTION_IN_PAGE_ERROR, используйте структурированную обработку исключений для защиты любого кода, который записывает или читает из отображаемого в память представления файла, отличного от файла подкачки.

Что касается других ограничений; ясно, что представление должно соответствовать пространству виртуальной памяти вашего процесса, а 32-битный процесс обычно имеет всего 2 ГБ. Если вы работаете с файлами размером в гигабайт, вам нужно отображать меньшие виды, а не весь файл сразу...

person Anders    schedule 06.11.2011

Ваше приложение дает сбой, потому что вы не проверяете MapViewOfFile на наличие ошибок — функция возвращает 0 в случае сбоя.

Что касается ограничений, функция не может отобразить блок, который больше, чем самый большой непрерывный свободный блок вашего пространства виртуальной памяти. Если ваша программа 32-разрядная, у вас есть только около 2 ГБ доступной виртуальной памяти; самый большой непрерывный свободный блок будет меньше, поскольку двоичный файл вашей программы, библиотеки DLL, ваш стек основного потока и ваша куча будут распределены в разных местах в пространстве памяти.

person avakar    schedule 06.11.2011

Вы пытаетесь отобразить весь файл в память за один раз. У вас недостаточно виртуальной памяти для этого. Нанесите на карту только ту часть, которая вам действительно нужна. Вот почему CreateFileMapping() и MapViewOfFile() позволяют указывать размеры и смещения для сопоставления. Я использую MMF для доступа к файлам размером в несколько ГБ, вам определенно нужно свести размер сопоставления к минимуму, просто перемещайте представление туда, где вам это нужно.

person Remy Lebeau    schedule 06.11.2011