ntdll: Implement Rtl[Add|Remove]VectoredContinueHandler semi-stubs.
This commit is contained in:
parent
009b6a25bb
commit
275ee4b376
|
@ -47,7 +47,8 @@ typedef struct
|
||||||
ULONG count;
|
ULONG count;
|
||||||
} VECTORED_HANDLER;
|
} VECTORED_HANDLER;
|
||||||
|
|
||||||
static struct list vectored_handlers = LIST_INIT(vectored_handlers);
|
static struct list vectored_exception_handlers = LIST_INIT(vectored_exception_handlers);
|
||||||
|
static struct list vectored_continue_handlers = LIST_INIT(vectored_continue_handlers);
|
||||||
|
|
||||||
static RTL_CRITICAL_SECTION vectored_handlers_section;
|
static RTL_CRITICAL_SECTION vectored_handlers_section;
|
||||||
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
||||||
|
@ -58,6 +59,47 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
||||||
};
|
};
|
||||||
static RTL_CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
static RTL_CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
|
||||||
|
static VECTORED_HANDLER *add_vectored_handler( struct list *handler_list, ULONG first,
|
||||||
|
PVECTORED_EXCEPTION_HANDLER func )
|
||||||
|
{
|
||||||
|
VECTORED_HANDLER *handler = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*handler) );
|
||||||
|
if (handler)
|
||||||
|
{
|
||||||
|
handler->func = RtlEncodePointer( func );
|
||||||
|
handler->count = 1;
|
||||||
|
RtlEnterCriticalSection( &vectored_handlers_section );
|
||||||
|
if (first) list_add_head( handler_list, &handler->entry );
|
||||||
|
else list_add_tail( handler_list, &handler->entry );
|
||||||
|
RtlLeaveCriticalSection( &vectored_handlers_section );
|
||||||
|
}
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ULONG remove_vectored_handler( struct list *handler_list, VECTORED_HANDLER *handler )
|
||||||
|
{
|
||||||
|
struct list *ptr;
|
||||||
|
ULONG ret = FALSE;
|
||||||
|
|
||||||
|
RtlEnterCriticalSection( &vectored_handlers_section );
|
||||||
|
LIST_FOR_EACH( ptr, handler_list )
|
||||||
|
{
|
||||||
|
VECTORED_HANDLER *curr_handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
|
||||||
|
if (curr_handler == handler)
|
||||||
|
{
|
||||||
|
if (!--curr_handler->count) list_remove( ptr );
|
||||||
|
else handler = NULL; /* don't free it yet */
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RtlLeaveCriticalSection( &vectored_handlers_section );
|
||||||
|
if (ret) RtlFreeHeap( GetProcessHeap(), 0, handler );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* wait_suspend
|
* wait_suspend
|
||||||
*
|
*
|
||||||
|
@ -165,7 +207,7 @@ LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||||
except_ptrs.ContextRecord = context;
|
except_ptrs.ContextRecord = context;
|
||||||
|
|
||||||
RtlEnterCriticalSection( &vectored_handlers_section );
|
RtlEnterCriticalSection( &vectored_handlers_section );
|
||||||
ptr = list_head( &vectored_handlers );
|
ptr = list_head( &vectored_exception_handlers );
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
|
handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
|
||||||
|
@ -181,7 +223,7 @@ LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||||
TRACE( "handler at %p returned %x\n", func, ret );
|
TRACE( "handler at %p returned %x\n", func, ret );
|
||||||
|
|
||||||
RtlEnterCriticalSection( &vectored_handlers_section );
|
RtlEnterCriticalSection( &vectored_handlers_section );
|
||||||
ptr = list_next( &vectored_handlers, ptr );
|
ptr = list_next( &vectored_exception_handlers, ptr );
|
||||||
if (!--handler->count) /* removed during execution */
|
if (!--handler->count) /* removed during execution */
|
||||||
{
|
{
|
||||||
list_remove( &handler->entry );
|
list_remove( &handler->entry );
|
||||||
|
@ -228,8 +270,7 @@ void WINAPI RtlRaiseStatus( NTSTATUS status )
|
||||||
*/
|
*/
|
||||||
PVOID WINAPI RtlAddVectoredContinueHandler( ULONG first, PVECTORED_EXCEPTION_HANDLER func )
|
PVOID WINAPI RtlAddVectoredContinueHandler( ULONG first, PVECTORED_EXCEPTION_HANDLER func )
|
||||||
{
|
{
|
||||||
FIXME("%u %p stub\n", first, func);
|
return add_vectored_handler( &vectored_continue_handlers, first, func );
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,8 +279,7 @@ PVOID WINAPI RtlAddVectoredContinueHandler( ULONG first, PVECTORED_EXCEPTION_HAN
|
||||||
*/
|
*/
|
||||||
ULONG WINAPI RtlRemoveVectoredContinueHandler( PVOID handler )
|
ULONG WINAPI RtlRemoveVectoredContinueHandler( PVOID handler )
|
||||||
{
|
{
|
||||||
FIXME("%p stub\n", handler);
|
return remove_vectored_handler( &vectored_continue_handlers, handler );
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,17 +288,7 @@ ULONG WINAPI RtlRemoveVectoredContinueHandler( PVOID handler )
|
||||||
*/
|
*/
|
||||||
PVOID WINAPI RtlAddVectoredExceptionHandler( ULONG first, PVECTORED_EXCEPTION_HANDLER func )
|
PVOID WINAPI RtlAddVectoredExceptionHandler( ULONG first, PVECTORED_EXCEPTION_HANDLER func )
|
||||||
{
|
{
|
||||||
VECTORED_HANDLER *handler = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*handler) );
|
return add_vectored_handler( &vectored_exception_handlers, first, func );
|
||||||
if (handler)
|
|
||||||
{
|
|
||||||
handler->func = RtlEncodePointer( func );
|
|
||||||
handler->count = 1;
|
|
||||||
RtlEnterCriticalSection( &vectored_handlers_section );
|
|
||||||
if (first) list_add_head( &vectored_handlers, &handler->entry );
|
|
||||||
else list_add_tail( &vectored_handlers, &handler->entry );
|
|
||||||
RtlLeaveCriticalSection( &vectored_handlers_section );
|
|
||||||
}
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -267,24 +297,7 @@ PVOID WINAPI RtlAddVectoredExceptionHandler( ULONG first, PVECTORED_EXCEPTION_HA
|
||||||
*/
|
*/
|
||||||
ULONG WINAPI RtlRemoveVectoredExceptionHandler( PVOID handler )
|
ULONG WINAPI RtlRemoveVectoredExceptionHandler( PVOID handler )
|
||||||
{
|
{
|
||||||
struct list *ptr;
|
return remove_vectored_handler( &vectored_exception_handlers, handler );
|
||||||
ULONG ret = FALSE;
|
|
||||||
|
|
||||||
RtlEnterCriticalSection( &vectored_handlers_section );
|
|
||||||
LIST_FOR_EACH( ptr, &vectored_handlers )
|
|
||||||
{
|
|
||||||
VECTORED_HANDLER *curr_handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
|
|
||||||
if (curr_handler == handler)
|
|
||||||
{
|
|
||||||
if (!--curr_handler->count) list_remove( ptr );
|
|
||||||
else handler = NULL; /* don't free it yet */
|
|
||||||
ret = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RtlLeaveCriticalSection( &vectored_handlers_section );
|
|
||||||
if (ret) RtlFreeHeap( GetProcessHeap(), 0, handler );
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1803,13 +1803,10 @@ static void test_vectored_continue_handler(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
handler1 = pRtlAddVectoredContinueHandler(TRUE, (void *)0xdeadbeef);
|
handler1 = pRtlAddVectoredContinueHandler(TRUE, (void *)0xdeadbeef);
|
||||||
todo_wine
|
|
||||||
ok(handler1 != 0, "RtlAddVectoredContinueHandler failed\n");
|
ok(handler1 != 0, "RtlAddVectoredContinueHandler failed\n");
|
||||||
|
|
||||||
handler2 = pRtlAddVectoredContinueHandler(TRUE, (void *)0xdeadbeef);
|
handler2 = pRtlAddVectoredContinueHandler(TRUE, (void *)0xdeadbeef);
|
||||||
todo_wine
|
|
||||||
ok(handler2 != 0, "RtlAddVectoredContinueHandler failed\n");
|
ok(handler2 != 0, "RtlAddVectoredContinueHandler failed\n");
|
||||||
todo_wine
|
|
||||||
ok(handler1 != handler2, "RtlAddVectoredContinueHandler returned same handler\n");
|
ok(handler1 != handler2, "RtlAddVectoredContinueHandler returned same handler\n");
|
||||||
|
|
||||||
if (pRtlRemoveVectoredExceptionHandler)
|
if (pRtlRemoveVectoredExceptionHandler)
|
||||||
|
@ -1819,11 +1816,9 @@ static void test_vectored_continue_handler(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pRtlRemoveVectoredContinueHandler(handler1);
|
ret = pRtlRemoveVectoredContinueHandler(handler1);
|
||||||
todo_wine
|
|
||||||
ok(ret, "RtlRemoveVectoredContinueHandler failed\n");
|
ok(ret, "RtlRemoveVectoredContinueHandler failed\n");
|
||||||
|
|
||||||
ret = pRtlRemoveVectoredContinueHandler(handler2);
|
ret = pRtlRemoveVectoredContinueHandler(handler2);
|
||||||
todo_wine
|
|
||||||
ok(ret, "RtlRemoveVectoredContinueHandler failed\n");
|
ok(ret, "RtlRemoveVectoredContinueHandler failed\n");
|
||||||
|
|
||||||
ret = pRtlRemoveVectoredContinueHandler(handler1);
|
ret = pRtlRemoveVectoredContinueHandler(handler1);
|
||||||
|
|
Loading…
Reference in New Issue