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