//结构化异常处理(try-except块)
__try
{
}
__except(filter_value)
{
}
在被__try{}包围的块中,如果出现异常,会根据filter_value的数值,判断是否需要在
__except{}块中处理。filter_value的数值会有三种可能。
(1)EXCEPTION_EXECUTE_HANDLER,该数值为1。进入到__except进行错误处理,处理完后
不再回到__try{}块中,转而继续执行
(2)EXCEPTION_CONTINUE_SEARCH,该数值为0。不使用__except块中的异常处理,转而向
上一层回卷。如果已经是最外层,则向操作系统请求异常处理函数
(2)EXCEPTION_CONTINUE_EXECUTION,该数值为-1。重复先前错误的指令,之歌在驱动程
序中很好用到
/************************************************************************ * 函数名称:ProbeTest * 功能描述:ProbeForRead和ProbeForWrite函数可以和try-except块配合, 用来检查某段内存是否可读写 * 参数列表: * 返回 值:VOID *************************************************************************/ VOID ProbeTest() { PVOID badPointer = NULL; KdPrint(("Enter ProbeTest\n")); __try { KdPrint(("Enter __try block\n")); //判断空指针是否可写,显示会导致异常 ProbeForWrite(badPointer, 100, 4); //由于在上面引发异常,所以以后语句不会被执行! KdPrint(("Leave __try block\n")); } __except { KdPrint(("Catch the except\n")); KdPrint(("The program will keep going\n")); } //该语句会被执行 KdPrint(("Leave ProbeTest\n")); }
//触发异常函数 函数 描述 ExRaiseStatus //用指定状态代码触发异常 ExRaiseAccessViolation //触发STATUS_ACCESS_VIOLATION异常 ExRaiseDatatypeMisalignment //触发STATUS_DATATYPE_MISALIGNMENT异常
//结构化异常处理(try-finally块) /************************************************************************ * 函数名称:TryFinallyTest * 功能描述:结构化异常处理的另一种使用方法,利用try_finally块, 强迫函数在退出前执行一段代码 * 参数列表: * 返回 值:VOID *************************************************************************/ NTSTATUS TryFinallyTest() { NTSTATUS status = STATUS_SUCCESS; __try { //做一些事情 return STATUS_SUCCESS; } __finally { //程序退出前必然运行到此 KdPrint(("Enter finaly block\n")); } }
在上面代码的__try{}块中,无论运行什么代码(即使是return语句或者触发异常),
在程序退出前都会运行__finally{}块中的代码。这样的目的是,在退出前需要运行
一些资源回收的工作,而资源回收的代码的最佳位置就是放在这个块中
/************************************************************************ * 函数名称:FoolTest * 功能描述:使用try-finally块还可以某种程度上简化代码 * 参数列表: * 返回 值:VOID *************************************************************************/ VOID FoolTest() { NTSTATUS status = STATUS_SUCCESS; //执行操作1 status = Foo1(...); //判断操作是否成功 if(!NT_SUCCESS(status)) { //回收资源 return status; } //执行操作2 status = Foo2(...); //判断操作是否成功 if(!NT_SUCCESS(status)) { //回收资源 return status; } //执行操作n status = FooN(...); //判断操作是否成功 if(!NT_SUCCESS(status)) { //回收资源 return status; } //返回状态,此状态一般是STATUS_SUCCESS return status; }
VOID FooTest() { NTSTATUS status = STATUS_SUCCESS; __try { //执行操作1 status = Foo1(...); //判断操作是否成功 if(!NT_SUCCESS(status)) { return status; } //执行操作2 status = Foo2(...); //判断操作是否成功 if(!NT_SUCCESS(status)) { return status; } //执行操作n status = FooN(...); //判断操作是否成功 if(!NT_SUCCESS(status)) { return status; } } __finally { if(!NT_SUCCESS(status)) { //回收资源 } return status; } }