[ros-dev] About GDIOBJHDR header changes
Alex Ionescu
ionucu at videotron.ca
Mon Dec 31 05:43:57 CET 2007
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 at 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 at reactos.org
> http://www.reactos.org/mailman/listinfo/ros-dev
Best regards,
Alex Ionescu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-dev/attachments/20071230/4e9c818e/attachment-0001.html
More information about the Ros-dev
mailing list