mirror of
https://github.com/reactos/reactos.git
synced 2024-11-09 08:08:38 +00:00
6afbc8f483
svn path=/branches/reactos-yarotows/; revision=45219
193 lines
4.9 KiB
C
193 lines
4.9 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS sysem libraries
|
|
* PURPOSE: Vectored Exception Handling
|
|
* FILE: lib/rtl/vectoreh.c
|
|
* PROGRAMERS: Thomas Weidenmueller
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include <rtl.h>
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
static RTL_CRITICAL_SECTION RtlpVectoredExceptionLock;
|
|
static LIST_ENTRY RtlpVectoredExceptionHead;
|
|
static volatile LONG RtlpVectoredExceptionsInstalled;
|
|
|
|
typedef struct _RTL_VECTORED_EXCEPTION_HANDLER
|
|
{
|
|
LIST_ENTRY ListEntry;
|
|
PVECTORED_EXCEPTION_HANDLER VectoredHandler;
|
|
ULONG Refs;
|
|
BOOLEAN Deleted;
|
|
} RTL_VECTORED_EXCEPTION_HANDLER, *PRTL_VECTORED_EXCEPTION_HANDLER;
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
|
|
IN PCONTEXT Context)
|
|
{
|
|
PLIST_ENTRY CurrentEntry;
|
|
PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
|
|
PVECTORED_EXCEPTION_HANDLER VectoredHandler;
|
|
EXCEPTION_POINTERS ExceptionInfo;
|
|
BOOLEAN Remove = FALSE;
|
|
BOOLEAN Ret = FALSE;
|
|
|
|
ExceptionInfo.ExceptionRecord = ExceptionRecord;
|
|
ExceptionInfo.ContextRecord = Context;
|
|
|
|
if(RtlpVectoredExceptionsInstalled)
|
|
{
|
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
|
CurrentEntry = RtlpVectoredExceptionHead.Flink;
|
|
while (CurrentEntry != &RtlpVectoredExceptionHead)
|
|
{
|
|
veh = CONTAINING_RECORD(CurrentEntry,
|
|
RTL_VECTORED_EXCEPTION_HANDLER,
|
|
ListEntry);
|
|
veh->Refs++;
|
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
|
|
|
VectoredHandler = RtlDecodePointer(veh->VectoredHandler);
|
|
if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
|
|
{
|
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
|
if (--veh->Refs == 0)
|
|
{
|
|
RemoveEntryList (&veh->ListEntry);
|
|
_InterlockedDecrement (&RtlpVectoredExceptionsInstalled);
|
|
Remove = TRUE;
|
|
}
|
|
Ret = TRUE;
|
|
break;
|
|
}
|
|
|
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
|
|
|
if (--veh->Refs == 0)
|
|
{
|
|
CurrentEntry = veh->ListEntry.Flink;
|
|
RemoveEntryList (&veh->ListEntry);
|
|
_InterlockedDecrement (&RtlpVectoredExceptionsInstalled);
|
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(),
|
|
0,
|
|
veh);
|
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
|
}
|
|
else
|
|
CurrentEntry = CurrentEntry->Flink;
|
|
}
|
|
|
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
|
}
|
|
|
|
if (Remove)
|
|
{
|
|
RtlFreeHeap(RtlGetProcessHeap(),
|
|
0,
|
|
veh);
|
|
}
|
|
|
|
return Ret;
|
|
}
|
|
|
|
VOID
|
|
RtlpInitializeVectoredExceptionHandling(VOID)
|
|
{
|
|
InitializeListHead(&RtlpVectoredExceptionHead);
|
|
RtlInitializeCriticalSection(&RtlpVectoredExceptionLock);
|
|
RtlpVectoredExceptionsInstalled = 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
PVOID NTAPI
|
|
RtlAddVectoredExceptionHandler(IN ULONG FirstHandler,
|
|
IN PVECTORED_EXCEPTION_HANDLER VectoredHandler)
|
|
{
|
|
PRTL_VECTORED_EXCEPTION_HANDLER veh;
|
|
|
|
veh = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
0,
|
|
sizeof(RTL_VECTORED_EXCEPTION_HANDLER));
|
|
if(veh != NULL)
|
|
{
|
|
veh->VectoredHandler = RtlEncodePointer(VectoredHandler);
|
|
veh->Refs = 1;
|
|
veh->Deleted = FALSE;
|
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
|
if(FirstHandler != 0)
|
|
{
|
|
InsertHeadList(&RtlpVectoredExceptionHead,
|
|
&veh->ListEntry);
|
|
}
|
|
else
|
|
{
|
|
InsertTailList(&RtlpVectoredExceptionHead,
|
|
&veh->ListEntry);
|
|
}
|
|
_InterlockedIncrement (&RtlpVectoredExceptionsInstalled);
|
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
|
}
|
|
|
|
return veh;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
ULONG NTAPI
|
|
RtlRemoveVectoredExceptionHandler(IN PVOID VectoredHandlerHandle)
|
|
{
|
|
PLIST_ENTRY CurrentEntry;
|
|
PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
|
|
BOOLEAN Remove = FALSE;
|
|
ULONG Ret = FALSE;
|
|
|
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
|
for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
|
|
CurrentEntry != &RtlpVectoredExceptionHead;
|
|
CurrentEntry = CurrentEntry->Flink)
|
|
{
|
|
veh = CONTAINING_RECORD(CurrentEntry,
|
|
RTL_VECTORED_EXCEPTION_HANDLER,
|
|
ListEntry);
|
|
if(veh == VectoredHandlerHandle)
|
|
{
|
|
if (!veh->Deleted)
|
|
{
|
|
if (--veh->Refs == 0)
|
|
{
|
|
RemoveEntryList (&veh->ListEntry);
|
|
Remove = TRUE;
|
|
}
|
|
veh->Deleted = TRUE;
|
|
Ret = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
|
|
|
if(Remove)
|
|
{
|
|
RtlFreeHeap(RtlGetProcessHeap(),
|
|
0,
|
|
veh);
|
|
}
|
|
|
|
return Ret;
|
|
}
|
|
|
|
/* EOF */
|