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.

svn path=/trunk/; revision=60725
This commit is contained in:
Timo Kreuzer 2013-10-20 19:46:28 +00:00
parent 56df983f97
commit 9625b9b820
2 changed files with 88 additions and 27 deletions

View file

@ -222,7 +222,7 @@ InitGdiHandleTable(void)
FORCEINLINE FORCEINLINE
VOID VOID
IncrementGdiHandleCount(void) IncrementCurrentProcessGdiHandleCount(void)
{ {
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount); if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount);
@ -230,12 +230,42 @@ IncrementGdiHandleCount(void)
FORCEINLINE FORCEINLINE
VOID VOID
DecrementGdiHandleCount(void) DecrementCurrentProcessGdiHandleCount(void)
{ {
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount); 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);
}
static static
PENTRY PENTRY
ENTRY_pentPopFreeEntry(VOID) ENTRY_pentPopFreeEntry(VOID)
@ -497,7 +527,7 @@ GDIOBJ_vDereferenceObject(POBJ pobj)
/* Decrement the process handle count */ /* Decrement the process handle count */
ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj == ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj ==
HandleToUlong(PsGetCurrentProcessId())); HandleToUlong(PsGetCurrentProcessId()));
DecrementGdiHandleCount(); DecrementCurrentProcessGdiHandleCount();
} }
/* Push entry to the free list */ /* Push entry to the free list */
@ -710,7 +740,7 @@ GDIOBJ_hInsertObject(
if (ulOwner == GDI_OBJ_HMGR_POWNED) if (ulOwner == GDI_OBJ_HMGR_POWNED)
{ {
/* Increment the process handle count */ /* Increment the process handle count */
IncrementGdiHandleCount(); IncrementCurrentProcessGdiHandleCount();
/* Use Process id */ /* Use Process id */
ulOwner = HandleToUlong(PsGetCurrentProcessId()); ulOwner = HandleToUlong(PsGetCurrentProcessId());
@ -729,50 +759,64 @@ VOID
NTAPI NTAPI
GDIOBJ_vSetObjectOwner( GDIOBJ_vSetObjectOwner(
POBJ pobj, POBJ pobj,
ULONG ulOwner) ULONG ulNewOwner)
{ {
PENTRY pentry; PENTRY pentry;
ULONG ulOldOwner;
/* This is a ugly HACK, needed to fix IntGdiSetDCOwnerEx */ /* This is a ugly HACK, needed to fix IntGdiSetDCOwnerEx */
if (GDI_HANDLE_IS_STOCKOBJ(pobj->hHmgr)) 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; return;
} }
/* Get the handle entry */ /* 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)]; 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? */ /* Is the current process requested? */
if (ulOwner == GDI_OBJ_HMGR_POWNED) if (ulNewOwner == GDI_OBJ_HMGR_POWNED)
{ {
/* Use process id */ /* Use process id */
ulOwner = HandleToUlong(PsGetCurrentProcessId()); ulNewOwner = HandleToUlong(PsGetCurrentProcessId());
if (pentry->ObjectOwner.ulObj != ulOwner)
{
IncrementGdiHandleCount();
}
} }
// HACK // HACK
if (ulOwner == GDI_OBJ_HMGR_NONE) if (ulNewOwner == GDI_OBJ_HMGR_NONE)
ulOwner = GDI_OBJ_HMGR_PUBLIC; ulNewOwner = GDI_OBJ_HMGR_PUBLIC;
if (ulOwner == GDI_OBJ_HMGR_PUBLIC || /* Was the object process owned? */
ulOwner == GDI_OBJ_HMGR_NONE) 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 */ /* Make sure we don't leak user mode memory */
ASSERT(pentry->pUser == NULL); NT_ASSERT(pentry->pUser == NULL);
if (pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC &&
pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_NONE)
{
DecrementGdiHandleCount();
}
} }
/* Set new owner */ /* Set new owner */
pentry->ObjectOwner.ulObj = ulOwner; pentry->ObjectOwner.ulObj = ulNewOwner;
DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0); DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0);
} }
@ -970,9 +1014,10 @@ GreGetObjectOwner(HGDIOBJ hobj)
BOOL BOOL
NTAPI NTAPI
GreSetObjectOwner( GreSetObjectOwnerEx(
HGDIOBJ hobj, HGDIOBJ hobj,
ULONG ulOwner) ULONG ulOwner,
ULONG Flags)
{ {
PENTRY pentry; PENTRY pentry;
@ -984,7 +1029,7 @@ GreSetObjectOwner(
} }
/* Reference the handle entry */ /* Reference the handle entry */
pentry = ENTRY_ReferenceEntryByHandle(hobj, 0); pentry = ENTRY_ReferenceEntryByHandle(hobj, Flags);
if (!pentry) if (!pentry)
{ {
DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj); DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj);
@ -1000,6 +1045,15 @@ GreSetObjectOwner(
return TRUE; return TRUE;
} }
BOOL
NTAPI
GreSetObjectOwner(
HGDIOBJ hobj,
ULONG ulOwner)
{
return GreSetObjectOwnerEx(hobj, ulOwner, 0);
}
INT INT
NTAPI NTAPI
GreGetObject( GreGetObject(

View file

@ -93,6 +93,13 @@ GreSetObjectOwner(
HGDIOBJ hobj, HGDIOBJ hobj,
ULONG ulOwner); ULONG ulOwner);
BOOL
NTAPI
GreSetObjectOwnerEx(
HGDIOBJ hobj,
ULONG ulOwner,
ULONG Flags);
INT INT
NTAPI NTAPI
GreGetObject( GreGetObject(