GlobalUnlock, GlobalFree exception handler

Andreas Mohr andi at rhlx01.fht-esslingen.de
Fri Nov 9 14:34:51 CST 2001


Hi all,

a program I tested does the known zero-out HIWORD game in case of a
GlobalLock()ed pointer and then calls GlobalUnlock.
--> ouch.

Use exception handler for GlobalUnlock, GlobalFree like Win98SE seems to do,
too.

-- 
Andreas Mohr                        Stauferstr. 6, D-71272 Renningen, Germany
Tel. +49 7159 800604                http://home.nexgo.de/andi.mohr/
-------------- next part --------------
Determining best CVS host...
Using CVSROOT :pserver:cvs at rhlx01.fht-esslingen.de:/home/wine
Index: memory/global.c
===================================================================
RCS file: /home/wine/wine/memory/global.c,v
retrieving revision 1.58
diff -u -r1.58 global.c
--- memory/global.c	6 Nov 2001 20:57:23 -0000	1.58
+++ memory/global.c	9 Nov 2001 20:32:00 -0000
@@ -1103,31 +1103,42 @@
 BOOL WINAPI GlobalUnlock(
               HGLOBAL hmem /* [in] Handle of global memory object */
 ) {
-   PGLOBAL32_INTERN       pintern;
-   BOOL                 locked;
+    PGLOBAL32_INTERN       pintern;
+    BOOL                 locked;
 
-   if(ISPOINTER(hmem))
-      return FALSE;
+    __TRY
+    {
+        if(ISPOINTER(hmem))
+            return FALSE;
 
-   /* HeapLock(GetProcessHeap()); */
-   pintern=HANDLE_TO_INTERN(hmem);
+        /* HeapLock(GetProcessHeap()); */
+        pintern=HANDLE_TO_INTERN(hmem);
    
-   if(pintern->Magic==MAGIC_GLOBAL_USED)
-   {
-      if((pintern->LockCount<GLOBAL_LOCK_MAX)&&(pintern->LockCount>0))
-	 pintern->LockCount--;
+        if(pintern->Magic==MAGIC_GLOBAL_USED)
+        {
+            if((pintern->LockCount<GLOBAL_LOCK_MAX)&&(pintern->LockCount>0))
+	        pintern->LockCount--;
 
-      locked = (pintern->LockCount != 0);
-      if (!locked) SetLastError(NO_ERROR);
-   }
-   else
-   {
-      WARN("invalid handle\n");
-      SetLastError(ERROR_INVALID_HANDLE);
-      locked=FALSE;
-   }
-   /* HeapUnlock(GetProcessHeap()); */
-   return locked;
+            locked = (pintern->LockCount != 0);
+            if (!locked) SetLastError(NO_ERROR);
+        }
+        else
+        {
+            WARN("invalid handle\n");
+            SetLastError(ERROR_INVALID_HANDLE);
+            locked=FALSE;
+        }
+        /* HeapUnlock(GetProcessHeap()); */
+    }
+    __EXCEPT(page_fault)
+    {
+        ERR("page fault occurred ! Caused by bug ?\n");
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+    __ENDTRY
+
+    return locked;
 }
 
 
@@ -1305,35 +1316,46 @@
 HGLOBAL WINAPI GlobalFree(
                  HGLOBAL hmem /* [in] Handle of global memory object */
 ) {
-   PGLOBAL32_INTERN pintern;
-   HGLOBAL        hreturned = 0;
+    PGLOBAL32_INTERN pintern;
+    HGLOBAL        hreturned = 0;
 
-   if(ISPOINTER(hmem)) /* POINTER */
-   {
-      if(!HeapFree(GetProcessHeap(), 0, (LPVOID) hmem)) hmem = 0;
-   }
-   else  /* HANDLE */
-   {
-      /* HeapLock(heap); */
-      pintern=HANDLE_TO_INTERN(hmem);
+    __TRY
+    {
+        if(ISPOINTER(hmem)) /* POINTER */
+        {
+            if(!HeapFree(GetProcessHeap(), 0, (LPVOID) hmem)) hmem = 0;
+        }
+        else  /* HANDLE */
+        {
+            /* HeapLock(heap); */
+            pintern=HANDLE_TO_INTERN(hmem);
       
-      if(pintern->Magic==MAGIC_GLOBAL_USED)
-      {	 
+            if(pintern->Magic==MAGIC_GLOBAL_USED)
+            {	 
 
-/* WIN98 does not make this test. That is you can free a */
-/* block you have not unlocked. Go figure!!              */
-      /* if(pintern->LockCount!=0)  */
-      /*    SetLastError(ERROR_INVALID_HANDLE);  */
-
-	 if(pintern->Pointer)
-	    if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-sizeof(HGLOBAL)))
-	       hreturned=hmem;
-	 if(!HeapFree(GetProcessHeap(), 0, pintern))
-	    hreturned=hmem;
-      }      
-      /* HeapUnlock(heap); */
-   }
-   return hreturned;
+                /* WIN98 does not make this test. That is you can free a */
+                /* block you have not unlocked. Go figure!!              */
+                /* if(pintern->LockCount!=0)  */
+                /*    SetLastError(ERROR_INVALID_HANDLE);  */
+
+	        if(pintern->Pointer)
+	            if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-sizeof(HGLOBAL)))
+	                hreturned=hmem;
+	        if(!HeapFree(GetProcessHeap(), 0, pintern))
+	            hreturned=hmem;
+            }      
+            /* HeapUnlock(heap); */
+        }
+    }
+    __EXCEPT(page_fault)
+    {
+        ERR("page fault occurred ! Caused by bug ?\n");
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+    __ENDTRY
+
+    return hreturned;
 }
 
 


More information about the wine-patches mailing list