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@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