//Перехват ошибок
catch (unsigned int code)
{
printf("\nСгенерировано исключение");
printf("\nКод исключения: code=%x",code);
if (code!=0xC0000005)
{
printf("\nНеизвестное исключение");
}
if (code==0xC0000005)
{
printf("\nТекст исключения: Попытка записи в защищённую область памяти");
}
// проверка: находится ли индекс в нужном диапазоне
if (i>=32*Kb)
{
printf("Попытка доступа к ячейке за границами буфера\n");
}
}
_set_se_translator(oldhandler);
getchar();
if (p1) freebuffer(p1);
if (p2) freebuffer(p2);
if (p3) freebuffer(p3);
}
Результат работы программы показан на рис. 3.
Рис. 3. Работа примера 3
Индивидуальное задание
Зарезервировать память 30 Мбт. Выделяя порциями необходимую память считать в нее последовательно от 1 до 20 дискет. Найти контрольную сумму считанных байтов. Записать эти дискеты на винчестер в файлы в виде отдельных образов.
Алгоритм работы программы
Первой частью задания было резервирование памяти в 30Мб. Для этого воспользовались функцией VirtualAlloc:
LPVOID VirtualAlloc(
LPVOID lpAddress,
DWORD dwSize,
DWORD flAllocationType,
DWORD flProtect
);
lpAddress адрес по которому необходимо выделить память.
dwSize размер памяти для выделения
flAllocationType тип выделения (MEM_COMMIT, MEM_RESERVE, MEM_RESET, MEM_TOP_DOWN)
flProtect тип доступа (PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE, E_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD)
NULL – ошибка.
Для изменения типа доступа VirtualProtect:
BOOL VirtualProtect(
LPVOID lpAddress,
DWORD dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);
lpAddress начальный адрес защищаемой области памяти
dwSize размер памяти для изменения
flNewProtect
устанавливаемый тип защиты (PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE, E_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD)
lpflOldProtect указатель на переменную для сохранения предведущего типа доступа
Не NULL все нормально.
Для освобождения памяти VirtualFree:
BOOL VirtualFree(
LPVOID lpAddress,
DWORD dwSize,
DWORD dwFreeType
);
lpAddress начальный адрес освобождаемой области (должен быть получен функцией VirtualAlloc)
dwSize размер освобождаемой области в байтах
dwFreeType тип освобождения памяти (MEM_DECOMMIT, MEM_RELEASE).
Не NULL – все нормально.
Текст программы
#include <windows.h>
#include <stdio.h>
#include <iostream.h>
#define MEGABYTE 1048576
#define MSIZE 30
void main (void)
{
int startinglogicalsector=0, //номер сектора, с которого начнется чтение
numberofsectors=1; // кличество читаемых секторов
DWORD bytesread; // вспомог. ячейка
char drive_name[] = "\\\\.\\a:"; //имя дисковода А:
HANDLE hFile;
int ii=0;
//Зарезервируем 30 Мб памяти
PBYTE buff=(PBYTE)VirtualAlloc(NULL, MSIZE*MEGABYTE,MEM_RESERVE, PAGE_READWRITE);
while(ii<20)
{
MessageBox(0,"вставте дискетку", NULL, MB_OK);
// открыть дисковое устройство как файл
hFile=CreateFile(drive_name,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,0,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
MessageBox(0,"Открыть устройство не удалось",NULL,MB_OK|MB_ICONSTOP);
return;
}
//установить начальную точку чтения в файле на начало заданного сектора
SetFilePointer(hFile, 512*startinglogicalsector, 0, FILE_BEGIN);
// выделить память для результата чтения
VirtualAlloc(buff, numberofsectors*512, MEM_COMMIT, PAGE_READWRITE);
// читать данные с устройства
if(!ReadFile(hFile, buff,numberofsectors*512, &bytesread, NULL))
{
VirtualFree(buff,MSIZE*MEGABYTE,NULL);
MessageBox(0,"Чтение данных НЕ удалось", NULL, MB_OK|MB_ICONSTOP);
return;
}
// закрыть файл (устройство)
CloseHandle(hFile);
// распечатать результаты в 16-ти ричной форме
int j=0;
for (int i=0; i<512; i++)
{if (buff[i]<16) printf("%c", '0');
printf("%X ", buff[i]);
j++;
if (j>15) {j=0; printf("\n"); }
}
ii++;
}
VirtualFree(buff,MSIZE*MEGABYTE,NULL);
MessageBox(0,"OK!!!", "Результат", MB_OK);
}
Результат работы программы показан на рис. 4.
Рис. 4. Пример работы программы
Рис. 5. Ошибка чтения
Cписок использованных источников
1. Р.САЙМОН, WINDOWS 2000 API ЭНЦИКЛОПЕДИЯ ПРОГРАММИСТА, 2002
2. Тихомиров В.А., Тихомиров В.А. Маленькие Уроки большого API
3. Рихтер Д., Рихтер Д. Создание эффективных WIN32-приложений, 2001
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.