Hi,
As Timo pointed out, I made a typo. Here are the final structures (the ones I wrote were pseudo-code to enduce your own thinking/ideas):
lkd> dt win32k!_ENTRY -r +0x000 einfo : _EINFO +0x000 pobj : Ptr32 _BASEOBJECT +0x000 hHmgr : Ptr32 Void +0x004 ulShareCount : Uint4B +0x008 cExclusiveLock : Uint2B +0x00a BaseFlags : Uint2B +0x00c Tid : Ptr32 _W32THREAD +0x000 hFree : Ptr32 HOBJ__ +0x000 unused : Int4B +0x004 ObjectOwner : _OBJECTOWNER +0x000 Share : _OBJECTOWNER_S +0x000 Lock : Pos 0, 1 Bit +0x000 Pid_Shifted : Pos 1, 31 Bits +0x000 ulObj : Uint4B +0x008 FullUnique : Uint2B +0x00a Objt : UChar +0x00b Flags : UChar +0x00c pUser : Ptr32 Void lkd> dt win32k!_BASEOBJECT -r +0x000 hHmgr : Ptr32 Void +0x004 ulShareCount : Uint4B +0x008 cExclusiveLock : Uint2B +0x00a BaseFlags : Uint2B +0x00c Tid : Ptr32 _W32THREAD +0x000 pEThread : Ptr32 _ETHREAD +0x004 RefCount : Uint4B +0x008 ptlW32 : Ptr32 _TL +0x000 next : Ptr32 _TL +0x004 pobj : Ptr32 Void +0x008 pfnFree : Ptr32 void +0x00c pgdiDcattr : Ptr32 Void +0x010 pgdiBrushAttr : Ptr32 Void +0x014 pUMPDObjs : Ptr32 Void +0x018 pUMPDHeap : Ptr32 Void +0x01c pUMPDObj : Ptr32 Void +0x020 GdiTmpTgoList : _LIST_ENTRY +0x000 Flink : Ptr32 _LIST_ENTRY +0x004 Blink : Ptr32 _LIST_ENTRY lkd> dt GDIHandleBitFields win32k!GDIHandleBitFields +0x000 Index : Pos 0, 16 Bits +0x000 Type : Pos 16, 5 Bits +0x000 AltType : Pos 21, 2 Bits +0x000 Stock : Pos 23, 1 Bit +0x000 Unique : Pos 24, 8 Bits lkd> dt GDIObjType win32k!GDIObjType GDIObjType_DEF_TYPE = 0 GDIObjType_DC_TYPE = 1 GDIObjType_UNUSED1_TYPE = 2 GDIObjType_UNUSED2_TYPE = 3 GDIObjType_RGN_TYPE = 4 GDIObjType_SURF_TYPE = 5 GDIObjType_CLIENTOBJ_TYPE = 6 GDIObjType_PATH_TYPE = 7 GDIObjType_PAL_TYPE = 8 GDIObjType_ICMLCS_TYPE = 9 GDIObjType_LFONT_TYPE = 10 GDIObjType_RFONT_TYPE = 11 GDIObjType_PFE_TYPE = 12 GDIObjType_PFT_TYPE = 13 GDIObjType_ICMCXF_TYPE = 14 GDIObjType_SPRITE_TYPE = 15 GDIObjType_BRUSH_TYPE = 16 GDIObjType_UMPD_TYPE = 17 GDIObjType_UNUSED4_TYPE = 18 GDIObjType_SPACE_TYPE = 19 GDIObjType_UNUSED5_TYPE = 20 GDIObjType_META_TYPE = 21 GDIObjType_EFSTATE_TYPE = 22 GDIObjType_BMFD_TYPE = 23 GDIObjType_VTFD_TYPE = 24 GDIObjType_TTFD_TYPE = 25 GDIObjType_RC_TYPE = 26 GDIObjType_TEMP_TYPE = 27 GDIObjType_DRVOBJ_TYPE = 28 GDIObjType_DCIOBJ_TYPE = 29 GDIObjType_SPOOL_TYPE = 30 GDIObjType_MAX_TYPE = 30 GDIObjTypeTotal = 31 lkd> dt GDILoObjType win32k!GDILoObjType GDILoObjType_LO_BRUSH_TYPE = 0x100000 GDILoObjType_LO_DC_TYPE = 0x10000 GDILoObjType_LO_BITMAP_TYPE = 0x50000 GDILoObjType_LO_PALETTE_TYPE = 0x80000 GDILoObjType_LO_FONT_TYPE = 0xa0000 GDILoObjType_LO_REGION_TYPE = 0x40000 GDILoObjType_LO_ICMLCS_TYPE = 0x90000 GDILoObjType_LO_CLIENTOBJ_TYPE = 0x60000 GDILoObjType_LO_ALTDC_TYPE = 0x210000 GDILoObjType_LO_PEN_TYPE = 0x300000 GDILoObjType_LO_EXTPEN_TYPE = 0x500000 GDILoObjType_LO_DIBSECTION_TYPE = 0x250000 GDILoObjType_LO_METAFILE16_TYPE = 0x260000 GDILoObjType_LO_METAFILE_TYPE = 0x460000 GDILoObjType_LO_METADC16_TYPE = 0x660000
Enjoy!
(PS. Why do you have "Teams" and "Reversers" when you can just use WinDBG?)
On 30-Dec-07, at 1:53 PM, James Tabor wrote:
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
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Best regards, Alex Ionescu