kernel32 [1/5]: Export part of UnhandledExceptionHandler as an internal Wine function.

Dan Hipschman dsh at linux.ucla.edu
Mon Nov 19 20:25:57 CST 2007


This patch exports the part of UnhandledExceptionFilter that sets a page
as either writable or executable in some cases to allow continued execution
as an internal wine function.  This is used in the next patch to implement
exception handling in code generated by WIDL.  It needs to be able to do
this because if we can continue execution in these cases then we shouldn't
wind down the handler stack.  We also shouldn't execute an "except" block
if we can continue normally.

---
 dlls/kernel32/except.c      |   31 +++++++++++++++++++++----------
 dlls/kernel32/kernel32.spec |    3 +++
 include/wine/exception.h    |    1 +
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/dlls/kernel32/except.c b/dlls/kernel32/except.c
index 0817d23..3680600 100644
--- a/dlls/kernel32/except.c
+++ b/dlls/kernel32/except.c
@@ -446,26 +446,37 @@ static inline BOOL check_no_exec( void *addr )
 
 
 /*******************************************************************
- *         UnhandledExceptionFilter   (KERNEL32.@)
+ *         __wine_handle_page_fault_gracefully
+ *
+ * Set page access protections on some page faults so we can
+ * continue execution.  Return TRUE if this was possible, FALSE
+ * if the page fault can't be handled gracefully.
  */
-LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
+BOOL __wine_handle_page_fault_gracefully( const EXCEPTION_RECORD *rec )
 {
-    const EXCEPTION_RECORD *rec = epointers->ExceptionRecord;
-
     if (rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && rec->NumberParameters >= 2)
     {
         switch(rec->ExceptionInformation[0])
         {
         case EXCEPTION_WRITE_FAULT:
-            if (check_resource_write( (void *)rec->ExceptionInformation[1] ))
-                return EXCEPTION_CONTINUE_EXECUTION;
-            break;
+            return check_resource_write( (void *)rec->ExceptionInformation[1] );
         case EXCEPTION_EXECUTE_FAULT:
-            if (check_no_exec( (void *)rec->ExceptionInformation[1] ))
-                return EXCEPTION_CONTINUE_EXECUTION;
-            break;
+            return check_no_exec( (void *)rec->ExceptionInformation[1] );
         }
     }
+    return FALSE;
+}
+
+
+/*******************************************************************
+ *         UnhandledExceptionFilter   (KERNEL32.@)
+ */
+LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
+{
+    const EXCEPTION_RECORD *rec = epointers->ExceptionRecord;
+
+    if (__wine_handle_page_fault_gracefully( rec ))
+        return EXCEPTION_CONTINUE_EXECUTION;
 
     if (!NtCurrentTeb()->Peb->BeingDebugged)
     {
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index bc3ba3a..0d12406 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -1234,6 +1234,9 @@
 # All functions must be prefixed with '__wine_' (for internal functions)
 # or 'wine_' (for user-visible functions) to avoid namespace conflicts.
 
+# Exception handling
+@ cdecl __wine_handle_page_fault_gracefully(ptr)
+
 # 16-bit relays
 @ cdecl __wine_dll_register_16(ptr str)
 @ cdecl __wine_dll_unregister_16(ptr)
diff --git a/include/wine/exception.h b/include/wine/exception.h
index eebfdfb..f7b6a60 100644
--- a/include/wine/exception.h
+++ b/include/wine/exception.h
@@ -187,6 +187,7 @@ static inline EXCEPTION_REGISTRATION_RECORD *__wine_pop_frame( EXCEPTION_REGISTR
 #endif
 }
 
+BOOL __wine_handle_page_fault_gracefully( const EXCEPTION_RECORD *rec );
 
 /* Wine-specific exceptions codes */
 



More information about the wine-patches mailing list