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... ============================================================================== --- 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;