Sebastian Lackner : ntdll: Implement Rtl[Add|Remove] VectoredContinueHandler semi-stubs.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Nov 14 03:22:44 CST 2014


Module: wine
Branch: master
Commit: 275ee4b376177f260693541a0f89f4e0c8c71847
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=275ee4b376177f260693541a0f89f4e0c8c71847

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Fri Nov 14 00:12:07 2014 +0100

ntdll: Implement Rtl[Add|Remove]VectoredContinueHandler semi-stubs.

---

 dlls/ntdll/exception.c       | 85 +++++++++++++++++++++++++-------------------
 dlls/ntdll/tests/exception.c |  5 ---
 2 files changed, 49 insertions(+), 41 deletions(-)

diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index 37edc77..5b4abb6 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -47,7 +47,8 @@ typedef struct
     ULONG                       count;
 } 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_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 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
  *
@@ -165,7 +207,7 @@ LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
     except_ptrs.ContextRecord = context;
 
     RtlEnterCriticalSection( &vectored_handlers_section );
-    ptr = list_head( &vectored_handlers );
+    ptr = list_head( &vectored_exception_handlers );
     while (ptr)
     {
         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 );
 
         RtlEnterCriticalSection( &vectored_handlers_section );
-        ptr = list_next( &vectored_handlers, ptr );
+        ptr = list_next( &vectored_exception_handlers, ptr );
         if (!--handler->count)  /* removed during execution */
         {
             list_remove( &handler->entry );
@@ -228,8 +270,7 @@ void WINAPI RtlRaiseStatus( NTSTATUS status )
  */
 PVOID WINAPI RtlAddVectoredContinueHandler( ULONG first, PVECTORED_EXCEPTION_HANDLER func )
 {
-    FIXME("%u %p stub\n", first, func);
-    return NULL;
+    return add_vectored_handler( &vectored_continue_handlers, first, func );
 }
 
 
@@ -238,8 +279,7 @@ PVOID WINAPI RtlAddVectoredContinueHandler( ULONG first, PVECTORED_EXCEPTION_HAN
  */
 ULONG WINAPI RtlRemoveVectoredContinueHandler( PVOID handler )
 {
-    FIXME("%p stub\n", handler);
-    return FALSE;
+    return remove_vectored_handler( &vectored_continue_handlers, handler );
 }
 
 
@@ -248,17 +288,7 @@ ULONG WINAPI RtlRemoveVectoredContinueHandler( PVOID handler )
  */
 PVOID WINAPI RtlAddVectoredExceptionHandler( 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( &vectored_handlers, &handler->entry );
-        else list_add_tail( &vectored_handlers, &handler->entry );
-        RtlLeaveCriticalSection( &vectored_handlers_section );
-    }
-    return handler;
+    return add_vectored_handler( &vectored_exception_handlers, first, func );
 }
 
 
@@ -267,24 +297,7 @@ PVOID WINAPI RtlAddVectoredExceptionHandler( ULONG first, PVECTORED_EXCEPTION_HA
  */
 ULONG WINAPI RtlRemoveVectoredExceptionHandler( PVOID handler )
 {
-    struct list *ptr;
-    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;
+    return remove_vectored_handler( &vectored_exception_handlers, handler );
 }
 
 
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 451e497..5cbab71 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -1803,13 +1803,10 @@ static void test_vectored_continue_handler(void)
     }
 
     handler1 = pRtlAddVectoredContinueHandler(TRUE, (void *)0xdeadbeef);
-    todo_wine
     ok(handler1 != 0, "RtlAddVectoredContinueHandler failed\n");
 
     handler2 = pRtlAddVectoredContinueHandler(TRUE, (void *)0xdeadbeef);
-    todo_wine
     ok(handler2 != 0, "RtlAddVectoredContinueHandler failed\n");
-    todo_wine
     ok(handler1 != handler2, "RtlAddVectoredContinueHandler returned same handler\n");
 
     if (pRtlRemoveVectoredExceptionHandler)
@@ -1819,11 +1816,9 @@ static void test_vectored_continue_handler(void)
     }
 
     ret = pRtlRemoveVectoredContinueHandler(handler1);
-    todo_wine
     ok(ret, "RtlRemoveVectoredContinueHandler failed\n");
 
     ret = pRtlRemoveVectoredContinueHandler(handler2);
-    todo_wine
     ok(ret, "RtlRemoveVectoredContinueHandler failed\n");
 
     ret = pRtlRemoveVectoredContinueHandler(handler1);




More information about the wine-cvs mailing list