[ros-diffs] [fireball] 50409: [WINENT.DRV] - Fix a number of small mistakes in the new usermode handle mapping code (performing dirty read, masking out hUser function parameter by a local variable and thus som...

fireball at svn.reactos.org fireball at svn.reactos.org
Mon Jan 17 14:28:39 UTC 2011


Author: fireball
Date: Mon Jan 17 14:28:38 2011
New Revision: 50409

URL: http://svn.reactos.org/svn/reactos?rev=50409&view=rev
Log:
[WINENT.DRV]
- Fix a number of small mistakes in the new usermode handle mapping code (performing dirty read, masking out hUser function parameter by a local variable and thus sometimes adding an incorrect mapping, mapping NULL handles, etc).
- Thanks to Wine's usage of DllMain and our dll loader, wine*.drv still gets called even after DLL_PROCESS_DETACH. To partially fix the issue, store stock objects mapping in a static global array. Fixes "SURFACE_ShareLock failed" issues.

Modified:
    branches/arwinss/reactos/dll/win32/winent.drv/gdiobj.c

Modified: branches/arwinss/reactos/dll/win32/winent.drv/gdiobj.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent.drv/gdiobj.c?rev=50409&r1=50408&r2=50409&view=diff
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/gdiobj.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/gdiobj.c [iso-8859-1] Mon Jan 17 14:28:38 2011
@@ -28,12 +28,31 @@
 PGDI_TABLE_ENTRY GdiHandleTable = NULL;
 PGDI_SHARED_HANDLE_TABLE GdiSharedHandleTable = NULL;
 HANDLE CurrentProcessId = NULL;
+HMAPPING GdiStockMapping[STOCK_LAST + 2];
 
 /* FUNCTIONS **************************************************************/
 
 VOID InitHandleMapping()
 {
     InitializeCriticalSection(&handle_mapping_cs);
+}
+
+VOID InitStockObjectsMapping()
+{
+    HGDIOBJ hKernel, hStockUser;
+
+    hKernel = NtGdiGetStockObject(DEFAULT_BITMAP);
+    hStockUser = GetStockObject( STOCK_LAST+1 );
+
+    TRACE("Adding hUser %x hKernel %x\n", hStockUser, hKernel);
+
+    /* Make sure that both kernel mode and user mode objects are initialized */
+    if(hKernel && hStockUser)
+    {
+        GdiStockMapping[STOCK_LAST+1].hKernel = hKernel;
+        GdiStockMapping[STOCK_LAST+1].hUser = hStockUser;
+        StockObjectsInitialized = TRUE;
+    }
 }
 
 VOID AddHandleMapping(HGDIOBJ hKernel, HGDIOBJ hUser)
@@ -53,6 +72,11 @@
 static PHMAPPING FindHandleMapping(HGDIOBJ hUser)
 {
     PHMAPPING item;
+    DWORD i;
+
+    /* Check the static stock objects mapping first */
+    for (i=0; i<sizeof(GdiStockMapping)/sizeof(HMAPPING); i++)
+        if (GdiStockMapping[i].hUser == hUser) return &GdiStockMapping[i];
 
     LIST_FOR_EACH_ENTRY( item, &handle_mapping_list, HMAPPING, entry )
     {
@@ -69,36 +93,41 @@
 {
     PHMAPPING mapping;
 
+    if (!hUser) return NULL;
+
     /* Map stock objects if not mapped yet */
     if(!StockObjectsInitialized)
-    {
-        HGDIOBJ hKernel, hUser;
-
-        hKernel = NtGdiGetStockObject(DEFAULT_BITMAP);
-        hUser = GetStockObject( STOCK_LAST+1 );
-
-        /* Make sure that both kernel mode and user mode objects are initialized */
-        if(hKernel && hUser)
-        {
-            AddHandleMapping(NtGdiGetStockObject(DEFAULT_BITMAP), GetStockObject( STOCK_LAST+1 ));
-            StockObjectsInitialized = TRUE;
-        }
-    }
+        InitStockObjectsMapping();
+
+    EnterCriticalSection(&handle_mapping_cs);
 
     mapping = FindHandleMapping(hUser);
 
+    if (!mapping)
+        ERR("Couldn't find a mapping for handle %x\n", hUser);
+
+    LeaveCriticalSection(&handle_mapping_cs);
+
     return mapping ? mapping->hKernel : NULL;
 }
 
 VOID RemoveHandleMapping(HGDIOBJ hUser)
 {
     PHMAPPING mapping;
+
+    if (!hUser) return;
+
+    TRACE("Remove handle mapping %x\n", hUser);
+
+    EnterCriticalSection(&handle_mapping_cs);
 
     mapping = FindHandleMapping(hUser);
     if(mapping == NULL)
+    {
+        LeaveCriticalSection(&handle_mapping_cs);
         return;
-
-    EnterCriticalSection(&handle_mapping_cs);
+    }
+
     list_remove(&mapping->entry);
     LeaveCriticalSection(&handle_mapping_cs);
 }
@@ -168,7 +197,7 @@
             else
             {
                 Result = FALSE; // Can not be zero.
-                ERR("Objct doesn't have user data handle 0x%x!\n", hGdiObj);
+                ERR("Object doesn't have user data handle 0x%x!\n", hGdiObj);
             }
             if (Result) *UserData = Entry->UserData;
             return Result;




More information about the Ros-diffs mailing list