Windows 核心編程之 異常處理


下面程序是一個數組,預定了內存,但是沒有分配物理內存。利用異常處理不可訪問,當寫入數據時,會觸發異常,然後申請內存,這樣就節省了內存使用率

// SEH.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <assert.h>
#include <Strsafe.h>

typedef struct MyTest
{
	char name[10];
	int  age;

}CELL,*PCELL;

const int g_h = 1024;
const int g_l = 512;

int g_len = 1024 * 512;

typedef CELL MyStruct[g_h][g_l];

MyStruct* pMyTest = NULL;


void Init(PBYTE* pData, DWORD dwsize)
{
	*pData =(PBYTE)VirtualAlloc(NULL, dwsize, 
		MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE);

	assert(NULL != pData);

}


LONG ExceptionFilter(PEXCEPTION_POINTERS pep, DWORD dwSize)
{
	// Default to trying another filter (safest thing to do)
	LONG lDisposition = EXCEPTION_EXECUTE_HANDLER;;

	// We only fix access violations
	if (pep->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
		return(EXCEPTION_CONTINUE_EXECUTION);

	// Get address of attempted access and get attempted read or write
	PVOID pvAddrTouched = (PVOID) pep->ExceptionRecord->ExceptionInformation[1];
	BOOL bAttemptedRead = (pep->ExceptionRecord->ExceptionInformation[0] == 0);
	void* pAddress = pMyTest;

	// Is attempted access within this VMArray's reserved region?
	if ((pAddress <= pvAddrTouched) && 
		(pvAddrTouched < ((PBYTE) pAddress + dwSize))) {

			TCHAR sz[200];
			StringCchPrintf(sz, _countof(sz), TEXT("Violation: Attempting to %s"),
				bAttemptedRead ? TEXT("Read") : TEXT("Write"));
			printf("%S\n",sz);

			if (!bAttemptedRead) 
			{
				BOOL bCommittedStorage = FALSE;  // Assume committing storage fails
				do {
					bCommittedStorage = (NULL != VirtualAlloc(pvAddrTouched, 
						sizeof(CELL), MEM_COMMIT, PAGE_READWRITE));
					if (!bCommittedStorage ) {
						MessageBox(NULL, 
							TEXT("Please close some other applications and Press OK."), 
							TEXT("Insufficient Memory Available"), MB_ICONWARNING | MB_OK);
					}
				} while (!bCommittedStorage);
				lDisposition = (bCommittedStorage 
					? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER);
			}
	}

	return(lDisposition);
}
static LONG WINAPI MYhandledExceptionFilter(PEXCEPTION_POINTERS pep) {

		MessageBoxA(NULL,"1","1",MB_OK);

	return EXCEPTION_EXECUTE_HANDLER;
}

int _tmain(int argc, _TCHAR* argv[])
{
// 	HMODULE hmudule = LoadLibrary("kernel32.dll");
// 	PUNHANDLEDEXCEPTIONFILTER = (PUNHANDLEDEXCEPTIONFILTER)GetProcAddress(hmudule,
// 		"");

	SetUnhandledExceptionFilter(MYhandledExceptionFilter);

	int i = 0;
	strlen(NULL);

	int j = 10 / i;

	Init((PBYTE*)&pMyTest,g_len);
	__try
	{
		int a = (*pMyTest)[0][0].age;
	}
	__except(ExceptionFilter(GetExceptionInformation(),g_len))
	{
		printf("111\n");
	}
	

	__try
	{
		(*pMyTest)[0][0].age = 10;

		(*pMyTest)[0][1].age = 11;

		(*pMyTest)[0][2].age = 11;
	}
	__except(ExceptionFilter(GetExceptionInformation(),g_len))
	{
		printf("222\n");
	}

	getchar();

	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章