Make VIRTUAL_SetFaultHandler an internal function

Dimitrie O. Paun dpaun at rogers.com
Sun Apr 17 10:13:05 CDT 2005


On Sun, Apr 17, 2005 at 08:44:57AM -0500, Rob Shearman wrote:
> Why don't you free area here?

Details, details. But if you insist ... :)


Index: dlls/ntdll/ntdll.spec
===================================================================
RCS file: /var/cvs/wine/dlls/ntdll/ntdll.spec,v
retrieving revision 1.175
diff -u -p -r1.175 ntdll.spec
--- dlls/ntdll/ntdll.spec	30 Mar 2005 10:22:51 -0000	1.175
+++ dlls/ntdll/ntdll.spec	17 Apr 2005 04:18:44 -0000
@@ -1035,4 +1035,3 @@
 @ cdecl MODULE_DllThreadAttach(ptr)
 @ cdecl MODULE_GetLoadOrderW(ptr wstr wstr)
 @ cdecl VERSION_Init(wstr)
-@ cdecl VIRTUAL_SetFaultHandler(ptr ptr ptr)
Index: dlls/ntdll/virtual.c
===================================================================
RCS file: /var/cvs/wine/dlls/ntdll/virtual.c,v
retrieving revision 1.46
diff -u -p -r1.46 virtual.c
--- dlls/ntdll/virtual.c	22 Feb 2005 19:33:50 -0000	1.46
+++ dlls/ntdll/virtual.c	17 Apr 2005 04:20:14 -0000
@@ -1098,25 +1104,6 @@ void virtual_init(void)
 
 
 /***********************************************************************
- *           VIRTUAL_SetFaultHandler
- */
-BOOL VIRTUAL_SetFaultHandler( LPCVOID addr, HANDLERPROC proc, LPVOID arg )
-{
-    FILE_VIEW *view;
-    BOOL ret = FALSE;
-
-    RtlEnterCriticalSection( &csVirtual );
-    if ((view = VIRTUAL_FindView( addr )))
-    {
-        view->handlerProc = proc;
-        view->handlerArg  = arg;
-        ret = TRUE;
-    }
-    RtlLeaveCriticalSection( &csVirtual );
-    return ret;
-}
-
-/***********************************************************************
  *           VIRTUAL_HandleFault
  */
 DWORD VIRTUAL_HandleFault( LPCVOID addr )
Index: dlls/x11drv/dib.c
===================================================================
RCS file: /var/cvs/wine/dlls/x11drv/dib.c,v
retrieving revision 1.35
diff -u -p -r1.35 dib.c
--- dlls/x11drv/dib.c	14 Apr 2005 12:48:31 -0000	1.35
+++ dlls/x11drv/dib.c	17 Apr 2005 15:10:03 -0000
@@ -38,11 +38,32 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "x11drv.h"
+#include "excpt.h"
+#include "wine/list.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
 WINE_DECLARE_DEBUG_CHANNEL(x11drv);
 
+struct mem_area
+{
+    struct list   entry;       /* Entry in global mem area list */
+    const void   *base;        /* Base address */
+    UINT          size;        /* Size in bytes */
+    void         *data;        /* Data associated with this area */
+};
+
+static struct list mem_areas_list = LIST_INIT(mem_areas_list);
+
+static CRITICAL_SECTION csMemAreas;
+static CRITICAL_SECTION_DEBUG csMemAreas_debug =
+{
+    0, 0, &csMemAreas,
+    { &csMemAreas_debug.ProcessLocksList, &csMemAreas_debug.ProcessLocksList },
+      0, 0, { 0, (DWORD)(__FILE__ ": csMemAreas") }
+};
+static CRITICAL_SECTION csMemAreas = { &csMemAreas_debug, -1, 0, 0, 0, 0 };
+
 static int ximageDepthTable[32];
 
 /* This structure holds the arguments for DIB_SetImageBits() */
@@ -88,6 +109,89 @@ static INT X11DRV_DIB_Coerce(X_PHYSBITMA
 static INT X11DRV_DIB_Lock(X_PHYSBITMAP *,INT,BOOL);
 static void X11DRV_DIB_Unlock(X_PHYSBITMAP *,BOOL);
 
+/***********************************************************************
+ *           mem_area_find
+ *
+ * Find the memory area containing a given address. 
+ * The csMemAreas section must be held by caller.
+ *
+ * PARAMS
+ *      addr  [I] Address
+ *
+ * RETURNS
+ *      Success: area
+ *      Failure: NULL
+ */
+static struct mem_area *mem_area_find( const void *addr )
+{
+    struct list *ptr;
+
+    LIST_FOR_EACH( ptr, &mem_areas_list )
+    {
+        struct mem_area *area = LIST_ENTRY( ptr, struct mem_area, entry );
+        if (area->base > addr) break;
+        if ((const char*)addr < (const char*)area->base + area->size) return area;
+    }
+    return NULL;
+}
+
+/***********************************************************************
+ *           mem_area_add
+ *
+ * Adds a memory area to the list.
+ *
+ * PARAMS
+ *      base  [I] Beginning address of the area
+ *      size  [I] Size of the area
+ *      data  [I] Data associated with the area
+ *
+ */
+static struct mem_area *mem_area_add( const void *base, UINT size, void *data )
+{
+    struct mem_area *area;
+
+    area = HeapAlloc(GetProcessHeap(), 0, sizeof(*area));
+    if (!area) return NULL;
+
+    area->base = base;
+    area->size = size;
+    area->data = data;
+
+    EnterCriticalSection( &csMemAreas );
+    list_add_head( &mem_areas_list, &area->entry );
+    LeaveCriticalSection( &csMemAreas );
+
+    return area;
+}
+
+
+/***********************************************************************
+ *           mem_area_del
+ *
+ * Removes a memory area from the list.
+ *
+ * PARAMS
+ *      addr  [I] Address
+ *
+ * RETURNS
+ *      Success: TRUE
+ *      Failure: FALSE
+ */
+static BOOL mem_area_del( const void *addr )
+{
+    struct mem_area *area;
+
+    EnterCriticalSection( &csMemAreas );
+    area = mem_area_find( addr );
+    if (area) list_remove( &area->entry );
+    LeaveCriticalSection( &csMemAreas );
+    
+    HeapFree(GetProcessHeap(), 0, area);
+
+    return area != NULL;
+}
+
+
 /* 
   Some of the following helper functions are duplicated in
   dlls/gdi/dib.c
@@ -4268,22 +4372,34 @@ static void X11DRV_DIB_DoUpdateDIBSectio
 /***********************************************************************
  *           X11DRV_DIB_FaultHandler
  */
-static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
+LONG CALLBACK X11DRV_DIB_FaultHandler( PEXCEPTION_POINTERS ep )
 {
-  X_PHYSBITMAP *physBitmap = res;
-  INT state = X11DRV_DIB_Lock( physBitmap, DIB_Status_None, FALSE );
+    struct mem_area *area;
+    X_PHYSBITMAP *physBitmap;
+    INT state;
 
-  if (state != DIB_Status_InSync) {
-    /* no way to tell whether app needs read or write yet,
-     * try read first */
-    X11DRV_DIB_Coerce( physBitmap, DIB_Status_InSync, FALSE );
-  } else {
-    /* hm, apparently the app must have write access */
-    X11DRV_DIB_Coerce( physBitmap, DIB_Status_AppMod, FALSE );
-  }
-  X11DRV_DIB_Unlock( physBitmap, TRUE );
+    if (ep->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
+        return EXCEPTION_CONTINUE_SEARCH;
 
-  return TRUE;
+    EnterCriticalSection(&csMemAreas);
+    area = mem_area_find(ep->ExceptionRecord->ExceptionAddress);
+    if (area) physBitmap = (X_PHYSBITMAP *)area->data;
+    else physBitmap = NULL;
+    LeaveCriticalSection(&csMemAreas);
+
+    if (!physBitmap) return EXCEPTION_CONTINUE_SEARCH;
+
+    state = X11DRV_DIB_Lock( physBitmap, DIB_Status_None, FALSE );
+    if (state != DIB_Status_InSync) {
+        /* no way to tell whether app needs read or write yet, try read first */
+        X11DRV_DIB_Coerce( physBitmap, DIB_Status_InSync, FALSE );
+    } else {
+        /* hm, apparently the app must have write access */
+        X11DRV_DIB_Coerce( physBitmap, DIB_Status_AppMod, FALSE );
+    }
+    X11DRV_DIB_Unlock( physBitmap, TRUE );
+
+   return EXCEPTION_CONTINUE_EXECUTION;
 }
 
 /***********************************************************************
@@ -4566,7 +4682,6 @@ static XImage *X11DRV_XShmCreateImage( i
 HBITMAP X11DRV_CreateDIBSection( X11DRV_PDEVICE *physDev, HBITMAP hbitmap,
                                  const BITMAPINFO *bmi, UINT usage )
 {
-    extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, BOOL (*proc)(LPVOID, LPCVOID), LPVOID arg);
     X_PHYSBITMAP *physBitmap;
     DIBSECTION dib;
 
@@ -4602,7 +4717,7 @@ HBITMAP X11DRV_CreateDIBSection( X11DRV_
 
       /* install fault handler */
     InitializeCriticalSection( &physBitmap->lock );
-    if (VIRTUAL_SetFaultHandler(dib.dsBm.bmBits, X11DRV_DIB_FaultHandler, physBitmap))
+    if (mem_area_add(dib.dsBm.bmBits, dib.dsBmih.biSize, physBitmap))
     {
         X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE );
         physBitmap->status = DIB_Status_AppMod;
@@ -4616,6 +4731,8 @@ HBITMAP X11DRV_CreateDIBSection( X11DRV_
  */
 void X11DRV_DIB_DeleteDIBSection(X_PHYSBITMAP *physBitmap, DIBSECTION *dib)
 {
+  mem_area_del(dib->dsBm.bmBits);
+
   if (dib->dshSection)
       X11DRV_DIB_Coerce(physBitmap, DIB_Status_InSync, FALSE);
 
Index: dlls/x11drv/x11drv.h
===================================================================
RCS file: /var/cvs/wine/dlls/x11drv/x11drv.h,v
retrieving revision 1.69
diff -u -p -r1.69 x11drv.h
--- dlls/x11drv/x11drv.h	14 Apr 2005 12:48:11 -0000	1.69
+++ dlls/x11drv/x11drv.h	17 Apr 2005 03:42:32 -0000
@@ -234,6 +234,7 @@ extern BOOL X11DRV_SwapBuffers(X11DRV_PD
 extern void X11DRV_BITMAP_Init(void);
 extern void X11DRV_FONT_Init( int log_pixels_x, int log_pixels_y );
 
+extern LONG CALLBACK X11DRV_DIB_FaultHandler( PEXCEPTION_POINTERS ep );
 extern int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse );
 extern XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth );
 extern HGLOBAL X11DRV_DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp);
Index: dlls/x11drv/x11drv_main.c
===================================================================
RCS file: /var/cvs/wine/dlls/x11drv/x11drv_main.c,v
retrieving revision 1.102
diff -u -p -r1.102 x11drv_main.c
--- dlls/x11drv/x11drv_main.c	14 Apr 2005 12:48:11 -0000	1.102
+++ dlls/x11drv/x11drv_main.c	16 Apr 2005 16:59:03 -0000
@@ -362,6 +362,9 @@ static BOOL process_attach(void)
         using_wine_desktop = 1;
     }
 
+    /* initialize DIB handling */
+    AddVectoredExceptionHandler( TRUE, X11DRV_DIB_FaultHandler );
+
     /* initialize GDI */
     X11DRV_GDI_Initialize( display );
 
@@ -422,6 +425,9 @@ static void process_detach(void)
     /* cleanup GDI */
     X11DRV_GDI_Finalize();
 
+    /* cleanup DIB handling */
+    RemoveVectoredExceptionHandler( X11DRV_DIB_FaultHandler );
+
     DeleteCriticalSection( &X11DRV_CritSection );
 }
 

-- 
Dimi.



More information about the wine-devel mailing list