diff --git a/reactos/include/win32k/dc.h b/reactos/include/win32k/dc.h index eae4b3ea6ed..44384bd3f93 100644 --- a/reactos/include/win32k/dc.h +++ b/reactos/include/win32k/dc.h @@ -132,6 +132,7 @@ VOID FASTCALL DC_FreeDC(HDC DCToFree); HDC FASTCALL DC_GetNextDC (PDC pDC); VOID FASTCALL DC_SetNextDC (PDC pDC, HDC hNextDC); BOOL FASTCALL DC_InternalDeleteDC( PDC DCToDelete ); +VOID FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner); VOID FASTCALL DC_UpdateXforms(PDC dc); BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest); diff --git a/reactos/include/win32k/gdiobj.h b/reactos/include/win32k/gdiobj.h index d558ca5db03..f0a6fd596f1 100644 --- a/reactos/include/win32k/gdiobj.h +++ b/reactos/include/win32k/gdiobj.h @@ -1,7 +1,6 @@ /* * GDI object common header definition * - * (RJJ) taken from WINE */ #ifndef __WIN32K_GDIOBJ_H @@ -67,7 +66,9 @@ BOOL FASTCALL GDIOBJ_UnlockObj (HGDIOBJ Obj, DWORD ObjectType); BOOL FASTCALL GDIOBJ_UnlockMultipleObj(PGDIMULTILOCK pList, INT nObj); DWORD FASTCALL GDIOBJ_GetObjectType(HGDIOBJ ObjectHandle); BOOL FASTCALL GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle); -void FASTCALL GDIOBJ_TakeOwnership(HGDIOBJ ObjectHandle); +void FASTCALL GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS Owner); +void FASTCALL GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo); +BOOL FASTCALL GDIOBJ_LockMultipleObj(PGDIMULTILOCK pList, INT nObj); /* a couple macros for debugging GDIOBJ locking */ #define GDIOBJ_LockObj(obj,ty) GDIOBJ_LockObjDbg(__FILE__,__LINE__,obj,ty) diff --git a/reactos/subsys/win32k/include/object.h b/reactos/subsys/win32k/include/object.h index cf1d58bcd8f..063d7f3557a 100644 --- a/reactos/subsys/win32k/include/object.h +++ b/reactos/subsys/win32k/include/object.h @@ -119,10 +119,6 @@ VOID FASTCALL CreateStockObjects (VOID); BOOL FASTCALL CleanupForProcess (struct _EPROCESS *Process, INT Pid); -VOID FASTCALL GDIOBJ_MarkObjectGlobal (HGDIOBJ ObjectHandle); -VOID FASTCALL GDIOBJ_UnmarkObjectGlobal (HGDIOBJ ObjectHandle); -BOOL FASTCALL GDIOBJ_LockMultipleObj (PGDIMULTILOCK pList, INT nObj); - PPOINT FASTCALL GDI_Bezier (const POINT *Points, INT count, PINT nPtsOut); /* objects/objconv.c */ diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index dc285c08f84..aaf48cd292c 100644 --- a/reactos/subsys/win32k/ntuser/windc.c +++ b/reactos/subsys/win32k/ntuser/windc.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: windc.c,v 1.38 2003/11/24 21:20:35 gvg Exp $ +/* $Id: windc.c,v 1.39 2003/11/26 21:48:35 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -137,7 +137,7 @@ DceAllocDCE(HWND hWnd, DCE_TYPE Type) if (NULL == defaultDCstate) { defaultDCstate = NtGdiGetDCState(Dce->hDC); - GDIOBJ_MarkObjectGlobal(defaultDCstate); + GDIOBJ_SetOwnership(defaultDCstate, NULL); } Dce->hwndCurrent = hWnd; Dce->hClipRgn = NULL; @@ -266,7 +266,6 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) BOOL UpdateVisRgn = TRUE; BOOL UpdateClipOrigin = FALSE; HANDLE hRgnVisible = NULL; - PDC DC; if (NULL == hWnd) { @@ -383,25 +382,8 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) } else if (! GDIOBJ_OwnedByCurrentProcess(Dce->Self)) { - GDIOBJ_TakeOwnership(Dce->Self); - GDIOBJ_TakeOwnership(Dce->hDC); - DC = DC_LockDc(Dce->hDC); - if (NULL != DC) - { - if (NULL != DC->w.hClipRgn) - { - GDIOBJ_TakeOwnership(DC->w.hClipRgn); - } - if (NULL != DC->w.hVisRgn) - { - GDIOBJ_TakeOwnership(DC->w.hVisRgn); - } - if (NULL != DC->w.hGCClipRgn) - { - GDIOBJ_TakeOwnership(DC->w.hGCClipRgn); - } - DC_UnlockDc(Dce->hDC); - } + GDIOBJ_SetOwnership(Dce->Self, PsGetCurrentProcess()); + DC_SetOwnership(Dce->hDC, PsGetCurrentProcess()); } } else diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index 9af92a34675..9e891b9c4e3 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: winsta.c,v 1.47 2003/11/25 22:06:31 gvg Exp $ + * $Id: winsta.c,v 1.48 2003/11/26 21:48:35 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -293,7 +293,7 @@ IntInitializeDesktopGraphics(VOID) IntDestroyPrimarySurface(); return FALSE; } - GDIOBJ_MarkObjectGlobal(ScreenDeviceContext); + DC_SetOwnership(ScreenDeviceContext, NULL); EnableMouse(ScreenDeviceContext); /* not the best place to load the cursors but it's good for now */ IntLoadDefaultCursors(FALSE); @@ -309,7 +309,7 @@ IntEndDesktopGraphics(VOID) EnableMouse(FALSE); if (NULL != ScreenDeviceContext) { - GDIOBJ_UnmarkObjectGlobal(ScreenDeviceContext); + DC_SetOwnership(ScreenDeviceContext, PsGetCurrentProcess()); NtGdiDeleteDC(ScreenDeviceContext); ScreenDeviceContext = NULL; } diff --git a/reactos/subsys/win32k/objects/cliprgn.c b/reactos/subsys/win32k/objects/cliprgn.c index eb635f49a2b..581dfadae42 100644 --- a/reactos/subsys/win32k/objects/cliprgn.c +++ b/reactos/subsys/win32k/objects/cliprgn.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: cliprgn.c,v 1.25 2003/09/24 16:01:32 weiden Exp $ */ +/* $Id: cliprgn.c,v 1.26 2003/11/26 21:48:35 gvg Exp $ */ #undef WIN32_LEAN_AND_MEAN #include @@ -131,6 +131,7 @@ NtGdiSelectVisRgn(HDC hdc, HRGN hrgn) if (dc->w.hVisRgn == NULL) { dc->w.hVisRgn = NtGdiCreateRectRgn(0, 0, 0, 0); + GDIOBJ_CopyOwnership(hdc, dc->w.hVisRgn); } retval = NtGdiCombineRgn(dc->w.hVisRgn, hrgn, 0, RGN_COPY); diff --git a/reactos/subsys/win32k/objects/color.c b/reactos/subsys/win32k/objects/color.c index 1ed5452c72a..f3c47c9689e 100644 --- a/reactos/subsys/win32k/objects/color.c +++ b/reactos/subsys/win32k/objects/color.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: color.c,v 1.27 2003/10/23 15:34:44 gvg Exp $ */ +/* $Id: color.c,v 1.28 2003/11/26 21:48:35 gvg Exp $ */ // FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping @@ -167,7 +167,7 @@ HBRUSH STDCALL NtGdiGetSysColorBrush(int nIndex) SysBrushes[nIndex] = (HBRUSH) ((DWORD)NtGdiCreateSolidBrush(SysColours[nIndex])); if (NULL != SysBrushes[nIndex]) { - GDIOBJ_MarkObjectGlobal(SysBrushes[nIndex]); + GDIOBJ_SetOwnership(SysBrushes[nIndex], NULL); } } diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 21c6266de4d..3ffdbcba350 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dc.c,v 1.101 2003/11/26 18:44:08 navaraf Exp $ +/* $Id: dc.c,v 1.102 2003/11/26 21:48:35 gvg Exp $ * * DC.C - Device context functions * @@ -617,7 +617,7 @@ IntCreatePrimarySurface() DPRINT("Adjusting GDIInfo.ulLogPixelsY\n"); PrimarySurface.GDIInfo.ulLogPixelsY = 96; } - GDIOBJ_MarkObjectGlobal(PrimarySurface.DevInfo.hpalDefault); + GDIOBJ_SetOwnership(PrimarySurface.DevInfo.hpalDefault, NULL); DPRINT("calling completePDev\n"); @@ -1987,4 +1987,30 @@ DC_InvertXform(const XFORM *xformSrc, return TRUE; } + +VOID FASTCALL +DC_SetOwnership(HDC hDC, PEPROCESS Owner) +{ + PDC DC; + + GDIOBJ_SetOwnership(hDC, Owner); + DC = DC_LockDc(hDC); + if (NULL != DC) + { + if (NULL != DC->w.hClipRgn) + { + GDIOBJ_CopyOwnership(hDC, DC->w.hClipRgn); + } + if (NULL != DC->w.hVisRgn) + { + GDIOBJ_CopyOwnership(hDC, DC->w.hVisRgn); + } + if (NULL != DC->w.hGCClipRgn) + { + GDIOBJ_CopyOwnership(hDC, DC->w.hGCClipRgn); + } + DC_UnlockDc(hDC); + } +} + /* EOF */ diff --git a/reactos/subsys/win32k/objects/gdiobj.c b/reactos/subsys/win32k/objects/gdiobj.c index 4a4a0f2d577..58afcc2fc42 100644 --- a/reactos/subsys/win32k/objects/gdiobj.c +++ b/reactos/subsys/win32k/objects/gdiobj.c @@ -19,7 +19,7 @@ /* * GDIOBJ.C - GDI object manipulation routines * - * $Id: gdiobj.c,v 1.51 2003/11/25 22:06:31 gvg Exp $ + * $Id: gdiobj.c,v 1.52 2003/11/26 21:48:35 gvg Exp $ * */ @@ -273,6 +273,7 @@ GDIOBJ_AllocObj(WORD Size, DWORD ObjectType, GDICLEANUPPROC CleanupProc) W32Process->GDIObjects++; } +//if (0x4001b == (DWORD) GDI_HANDLE_CREATE(Index, ObjectType)) __asm__("int $3\n"); return GDI_HANDLE_CREATE(Index, ObjectType); } @@ -424,71 +425,6 @@ GDIOBJ_UnlockMultipleObj(PGDIMULTILOCK pList, INT nObj) return TRUE; } -/*! - * Marks the object as global. (Creator process ID is set to GDI_GLOBAL_PROCESS). Global objects may be - * accessed by any process. - * \param ObjectHandle - handle of the object to make global. - * - * \note Only stock objects should be marked global. -*/ -VOID FASTCALL -GDIOBJ_MarkObjectGlobal(HGDIOBJ ObjectHandle) -{ - PEPROCESS Process; - PW32PROCESS W32Process; - NTSTATUS Status; - PGDIOBJHDR ObjHdr; - - DPRINT("GDIOBJ_MarkObjectGlobal handle 0x%08x\n", ObjectHandle); - ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(ObjectHandle)); - if (NULL == ObjHdr) - { - return; - } - - Status = PsLookupProcessByProcessId((PVOID)ObjHdr->hProcessId, &Process); - if(NT_SUCCESS(Status)) - { - W32Process = Process->Win32Process; - if(W32Process) - { - W32Process->GDIObjects--; - } - ObDereferenceObject(Process); - } - - ObjHdr->hProcessId = GDI_GLOBAL_PROCESS; -} - -/*! - * Removes the global mark from the object. Global objects may be - * accessed by any process. - * \param ObjectHandle - handle of the object to make local. - * - * \note Only stock objects should be marked global. -*/ -VOID FASTCALL -GDIOBJ_UnmarkObjectGlobal(HGDIOBJ ObjectHandle) -{ - PW32PROCESS W32Process; - PGDIOBJHDR ObjHdr; - - DPRINT("GDIOBJ_MarkObjectGlobal handle 0x%08x\n", ObjectHandle); - ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(ObjectHandle)); - if (NULL == ObjHdr /*|| GDI_GLOBAL_PROCESS != ObjHdr->hProcessId*/) - { - return; - } - - W32Process = PsGetCurrentProcess()->Win32Process; - if(W32Process) - { - W32Process->GDIObjects++; - } - - ObjHdr->hProcessId = PsGetCurrentProcessId(); -} - /*! * Get the type of the object. * \param ObjectHandle - handle of the object. @@ -564,7 +500,7 @@ CreateStockObjects(void) { if (NULL != StockObjects[Object]) { - GDIOBJ_MarkObjectGlobal(StockObjects[Object]); + GDIOBJ_SetOwnership(StockObjects[Object], NULL); /* GDI_HANDLE_SET_STOCKOBJ(StockObjects[Object]);*/ } } @@ -810,16 +746,91 @@ GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle) } void FASTCALL -GDIOBJ_TakeOwnership(HGDIOBJ ObjectHandle) +GDIOBJ_SetOwnership(HGDIOBJ ObjectHandle, PEPROCESS NewOwner) { PGDIOBJHDR ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(ObjectHandle)); + PEPROCESS OldProcess; + PW32PROCESS W32Process; + NTSTATUS Status; DPRINT("GDIOBJ_OwnedByCurrentProcess: ObjectHandle: 0x%08x\n", ObjectHandle); ASSERT(GDI_VALID_OBJECT(ObjectHandle, ObjHdr, GDI_OBJECT_TYPE_DONTCARE, GDIOBJFLAG_IGNOREPID)); - if (GDI_GLOBAL_PROCESS != ObjHdr->hProcessId) + if ((NULL == NewOwner && GDI_GLOBAL_PROCESS != ObjHdr->hProcessId) + || (NULL != NewOwner && ObjHdr->hProcessId != (HANDLE) NewOwner->UniqueProcessId)) { - ObjHdr->hProcessId = PsGetCurrentProcessId(); + Status = PsLookupProcessByProcessId((PVOID)ObjHdr->hProcessId, &OldProcess); + if (NT_SUCCESS(Status)) + { + W32Process = OldProcess->Win32Process; + if (W32Process) + { + W32Process->GDIObjects--; + } + ObDereferenceObject(OldProcess); + } + } + + if (NULL == NewOwner) + { + ObjHdr->hProcessId = GDI_GLOBAL_PROCESS; + } + else if (ObjHdr->hProcessId != (HANDLE) NewOwner->UniqueProcessId) + { + ObjHdr->hProcessId = (HANDLE) NewOwner->UniqueProcessId; + W32Process = NewOwner->Win32Process; + if (W32Process) + { + W32Process->GDIObjects++; + } + } +} + +void FASTCALL +GDIOBJ_CopyOwnership(HGDIOBJ CopyFrom, HGDIOBJ CopyTo) +{ + PGDIOBJHDR ObjHdrFrom = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(CopyFrom)); + PGDIOBJHDR ObjHdrTo = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(CopyTo)); + NTSTATUS Status; + PEPROCESS ProcessFrom; + PEPROCESS CurrentProcess; + + ASSERT(NULL != ObjHdrFrom && NULL != ObjHdrTo); + if (NULL != ObjHdrFrom && NULL != ObjHdrTo + && ObjHdrTo->hProcessId != ObjHdrFrom->hProcessId) + { + if (ObjHdrFrom->hProcessId == GDI_GLOBAL_PROCESS) + { + GDIOBJ_SetOwnership(CopyTo, NULL); + } + else + { + /* Warning: ugly hack ahead + * + * During process cleanup, we can't call PsLookupProcessByProcessId + * for the current process, 'cause that function will try to + * reference the process, and since the process is closing down + * that will result in a bugcheck. + * So, instead, we call PsGetCurrentProcess, which doesn't reference + * the process. If the current process is indeed the one we're + * looking for, we use it, otherwise we can (safely) call + * PsLookupProcessByProcessId + */ + CurrentProcess = PsGetCurrentProcess(); + if (ObjHdrFrom->hProcessId == (HANDLE) CurrentProcess->UniqueProcessId) + { + GDIOBJ_SetOwnership(CopyTo, CurrentProcess); + } + else + { + Status = PsLookupProcessByProcessId((PVOID) ObjHdrFrom->hProcessId, &ProcessFrom); + if (NT_SUCCESS(Status)) + { + GDIOBJ_SetOwnership(CopyTo, ProcessFrom); + ObDereferenceObject(ProcessFrom); + } + } + } } }