[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