Hi!
From my teams research they say this is still valid for
xp. If the
alignment is not correct? It would fubar the rest of the structure
that has be verified as correct for XP. eg DCOBJ.
typedef struct _BASEOBJECT
{
HANDLE hHmgr; // 0x0 <- xp
PVOID pEntry; // 0x4 <- No longer a pointer.
LONG cExclusiveLock; // 0x8 <- xp
PW32THREAD Tid; // 0xc <- xp
} BASEOBJECT, *POBJ;
On Dec 30, 2007 7:52 AM, Alex Ionescu <ionucu(a)videotron.ca> wrote:
Let's begin with the GDI Base Object, which is a
header at the top of every
GDI Object. The structure is called _BASEOBJECT (what you refer to as
"GDIOBJHDR") and is defined as follows:
struct _BASEOBJECT
{
HANDLE hHmgr;
ULONG ulShareCount;
LONG cExclusiveLock;
ULONG BaseFlags;
PW32THREAD Tid;
};
The pointer to a _BASEOBJECT is known as a POBJ.
Now, how to get to this object? Well, dxg and win32k.sys now both implement
different Hmhr's (Handle Managers).
In Win32K land, the handles come from gpentHmgr, and each handle is indexed
from it. The resulting structure is called an _ENTRY, and is defined as
follows:
struct _ENTRY
{
union
{
POBJ pobj;
HANDLE hFree;
};
union
{
ULONG ulObj;
struct
{
USHORT Count:15;
USHORT Lock:1;
HANDLE Pid;
};
} ObjectOwner;
USHORT FullUnique;
UCHAR Objt;
UCHAR Flags;
PVOID pUser;
};
DXG uses a DDENTRY structure, which is similar. Handles are indexed from
gpentDdHmgr.
This is correct too. xteam confirms it. I commit an update to our
entry based on their research . Count and lock merged into Count.
FullUnique and Objt are correct.
What Greatlord hadn't noticed while reversing is
that part of the code was
dealing with the DD_ENTRY object, and part of it was dereferencing the first
member of DD_ENTRY, which is the pObj (and was now dealing with the
_BASEOBJECT).
Objt is where the object type is defined -- you already seem to know the
Win32K Objects. Here are the DXG objects:
DD_MOTIONCOMP_TYPE
DD_VIDEOPORT_TYPE
D3D_HANDLE_TYPE
DD_SURFACE_TYPE
DD_DIRECTDRAW_TYPE
DD_DEF_TYPE.
So how exactly then does DdHmgrLock work? Quite similarly to HmgrLock:
POBJ
FASTCALL
DdHmgLock(HDD_OBJ DdHandle,
UCHAR ObjectType,
BOOLEAN LockOwned)
{
POBJ Object = NULL;
PDD_ENTRY Entry;
ULONG Index;
//
// Acquire the DirectX Handle Manager Lock
//
if (!LockOwned) DdHmgAcquireHmgrSemaphore();
//
// Get the handle index and validate it
//
Index = DdHandle & 0x1FFFFF;
if (Index < gcMaxDdHmgr)
{
//
// Get the entry
//
Entry = gpentDdHmgr[Index];
//
// Validate the owner
//
if ((Entry->ObjectOwner.Pid = PsGetCurrentProcessId() & 0xFFFFFFFC)
||
!(Entry->ObjectOwner.Pid))
{
//
// Validate the object type
//
if (Entry->Objt == ObjectType)
{
//
// Validate the handle type
//
if (Entry->FullUnique == ((DdHandle >> 21) & 0x7FF))
{
//
// Get the GDI Object
//
Object = DdEntry->pObj;
//
// Make sure we can lock it
//
if (!(Object->cExclusiveLock) ||
(Object->Tid == (PW32THREAD)PsGetCurrentThread()))
{
//
// Acquire the lock
//
InterlockedIncrement(&Object->cExclusiveLock);
Object->Tid = (PW32THREAD)PsGetCurrentThread();
}
else
{
//
// Already locked by someone else
//
Object = NULL;
}
}
}
}
}
//
// Release the lock
//
if (!LockOwned) DdHmgReleaseHmgrSemaphore();
//
// Return the object
//
return Object;
}
I am looking forward to compatible Hmgr implementation in win32k!
Me too! One of our most needed things todo! 8^) HmgLock anyone?
Any questions?
Best regards,
Alex Ionescu