Author: tkreuzer
Date: Sun Oct 20 19:46:28 2013
New Revision: 60725
URL:
http://svn.reactos.org/svn/reactos?rev=60725&view=rev
Log:
[WIN32K]
Add GreSetObjectOwnerEx, allowing to set the owner of not-owned objects by passing
GDIOBJFLAG_IGNOREPID as 3rd parameter. Use with care :) Dedicated to Alexander and
Hermès.
Modified:
trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c
trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] Sun Oct 20 19:46:28 2013
@@ -222,7 +222,7 @@
FORCEINLINE
VOID
-IncrementGdiHandleCount(void)
+IncrementCurrentProcessGdiHandleCount(void)
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
@@ -230,9 +230,39 @@
FORCEINLINE
VOID
-DecrementGdiHandleCount(void)
+DecrementCurrentProcessGdiHandleCount(void)
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+ if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount);
+}
+
+FORCEINLINE
+VOID
+IncrementGdiHandleCount(ULONG ulProcessId)
+{
+ PEPROCESS pep;
+ PPROCESSINFO ppi;
+ NTSTATUS Status;
+
+ Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep);
+ NT_ASSERT(NT_SUCCESS(Status));
+
+ ppi = PsGetProcessWin32Process(pep);
+ if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
+}
+
+FORCEINLINE
+VOID
+DecrementGdiHandleCount(ULONG ulProcessId)
+{
+ PEPROCESS pep;
+ PPROCESSINFO ppi;
+ NTSTATUS Status;
+
+ Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep);
+ NT_ASSERT(NT_SUCCESS(Status));
+
+ ppi = PsGetProcessWin32Process(pep);
if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount);
}
@@ -497,7 +527,7 @@
/* Decrement the process handle count */
ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj ==
HandleToUlong(PsGetCurrentProcessId()));
- DecrementGdiHandleCount();
+ DecrementCurrentProcessGdiHandleCount();
}
/* Push entry to the free list */
@@ -710,7 +740,7 @@
if (ulOwner == GDI_OBJ_HMGR_POWNED)
{
/* Increment the process handle count */
- IncrementGdiHandleCount();
+ IncrementCurrentProcessGdiHandleCount();
/* Use Process id */
ulOwner = HandleToUlong(PsGetCurrentProcessId());
@@ -729,50 +759,64 @@
NTAPI
GDIOBJ_vSetObjectOwner(
POBJ pobj,
- ULONG ulOwner)
+ ULONG ulNewOwner)
{
PENTRY pentry;
+ ULONG ulOldOwner;
/* This is a ugly HACK, needed to fix IntGdiSetDCOwnerEx */
if (GDI_HANDLE_IS_STOCKOBJ(pobj->hHmgr))
{
- DPRINT("Trying to set ownership of stock object %p to %lx\n",
pobj->hHmgr, ulOwner);
+ DPRINT("Trying to set ownership of stock object %p to %lx\n",
pobj->hHmgr, ulNewOwner);
return;
}
/* Get the handle entry */
- ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr));
+ NT_ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr));
pentry = &gpentHmgr[GDI_HANDLE_GET_INDEX(pobj->hHmgr)];
+ /* Check if the new owner is the same as the old one */
+ ulOldOwner = pentry->ObjectOwner.ulObj;
+ if (ulOldOwner == ulNewOwner)
+ {
+ /* Nothing to do */
+ return;
+ }
+
/* Is the current process requested? */
- if (ulOwner == GDI_OBJ_HMGR_POWNED)
+ if (ulNewOwner == GDI_OBJ_HMGR_POWNED)
{
/* Use process id */
- ulOwner = HandleToUlong(PsGetCurrentProcessId());
- if (pentry->ObjectOwner.ulObj != ulOwner)
- {
- IncrementGdiHandleCount();
- }
+ ulNewOwner = HandleToUlong(PsGetCurrentProcessId());
}
// HACK
- if (ulOwner == GDI_OBJ_HMGR_NONE)
- ulOwner = GDI_OBJ_HMGR_PUBLIC;
-
- if (ulOwner == GDI_OBJ_HMGR_PUBLIC ||
- ulOwner == GDI_OBJ_HMGR_NONE)
+ if (ulNewOwner == GDI_OBJ_HMGR_NONE)
+ ulNewOwner = GDI_OBJ_HMGR_PUBLIC;
+
+ /* Was the object process owned? */
+ if ((ulOldOwner != GDI_OBJ_HMGR_PUBLIC) &&
+ (ulOldOwner != GDI_OBJ_HMGR_NONE))
+ {
+ /* Decrement the previous owners handle count */
+ DecrementGdiHandleCount(ulOldOwner);
+ }
+
+ /* Is the new owner a process? */
+ if ((ulNewOwner != GDI_OBJ_HMGR_PUBLIC) &&
+ (ulNewOwner != GDI_OBJ_HMGR_NONE))
+ {
+ /* Increment the new owners handle count */
+ IncrementGdiHandleCount(ulNewOwner);
+ }
+ else
{
/* Make sure we don't leak user mode memory */
- ASSERT(pentry->pUser == NULL);
- if (pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC &&
- pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_NONE)
- {
- DecrementGdiHandleCount();
- }
+ NT_ASSERT(pentry->pUser == NULL);
}
/* Set new owner */
- pentry->ObjectOwner.ulObj = ulOwner;
+ pentry->ObjectOwner.ulObj = ulNewOwner;
DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0);
}
@@ -970,34 +1014,44 @@
BOOL
NTAPI
+GreSetObjectOwnerEx(
+ HGDIOBJ hobj,
+ ULONG ulOwner,
+ ULONG Flags)
+{
+ PENTRY pentry;
+
+ /* Check for stock objects */
+ if (GDI_HANDLE_IS_STOCKOBJ(hobj))
+ {
+ DPRINT("GreSetObjectOwner: Got stock object %p\n", hobj);
+ return FALSE;
+ }
+
+ /* Reference the handle entry */
+ pentry = ENTRY_ReferenceEntryByHandle(hobj, Flags);
+ if (!pentry)
+ {
+ DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj);
+ return FALSE;
+ }
+
+ /* Call internal function */
+ GDIOBJ_vSetObjectOwner(pentry->einfo.pobj, ulOwner);
+
+ /* Dereference the object */
+ GDIOBJ_vDereferenceObject(pentry->einfo.pobj);
+
+ return TRUE;
+}
+
+BOOL
+NTAPI
GreSetObjectOwner(
HGDIOBJ hobj,
ULONG ulOwner)
{
- PENTRY pentry;
-
- /* Check for stock objects */
- if (GDI_HANDLE_IS_STOCKOBJ(hobj))
- {
- DPRINT("GreSetObjectOwner: Got stock object %p\n", hobj);
- return FALSE;
- }
-
- /* Reference the handle entry */
- pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
- if (!pentry)
- {
- DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj);
- return FALSE;
- }
-
- /* Call internal function */
- GDIOBJ_vSetObjectOwner(pentry->einfo.pobj, ulOwner);
-
- /* Dereference the object */
- GDIOBJ_vDereferenceObject(pentry->einfo.pobj);
-
- return TRUE;
+ return GreSetObjectOwnerEx(hobj, ulOwner, 0);
}
INT
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h [iso-8859-1] Sun Oct 20 19:46:28 2013
@@ -93,6 +93,13 @@
HGDIOBJ hobj,
ULONG ulOwner);
+BOOL
+NTAPI
+GreSetObjectOwnerEx(
+ HGDIOBJ hobj,
+ ULONG ulOwner,
+ ULONG Flags);
+
INT
NTAPI
GreGetObject(