[ros-dev] About GDIOBJHDR header changes

Magnus Olsen magnus at greatlord.com
Sun Dec 30 16:00:10 CET 2007


Hi
I try verify some stuff, the _BASEOBJECT does not match for dxg 
I want it be in this order. 

 struct DD_BASEOBJECT
 {
    HANDLE hHmgr; // Handle for this object
    LONG cExclusiveLock; // lock with InterlockedIncrement or not
    ULONG ulShareCount;  
    PW32THREAD Tid;   // contain which thread it belong to, PsGetCurrentThread()
    ULONG BaseFlags;     
 } *POBJ;
  ----- Original Message ----- 
  From: Alex Ionescu 
  To: ReactOS Development List 
  Sent: Sunday, December 30, 2007 2:52 PM
  Subject: Re: [ros-dev] About GDIOBJHDR header changes


  Both Timo and Magnus are half-right, half-wrong, and are confused by no less then three different structures that come into play. The fact that Feng's book is outdated doesn't help much! Greatlord's reversing of the DdHmgLock function was also completely busted, further confusing matters.


  So here's my attempt to clear things up.


  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.


  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!


  Any questions?


  On 30-Dec-07, at 7:02 AM, Magnus Olsen wrote:



    I forget to say this
    EDD_SURFACE DxLock expect it is always value 2 in Type
    other wise the lock will fail. 
    here is some of my code it is part of DxLock lock process I am working on. 
    here is the code  I am working on and some rethinking how GDIOBJHDR 
    can look like.

    Some rethinking why not ?

    typedef struct _GDIOBJHDR
    {
        HGDIOBJ     hHmgr;
        union {
                      struct {
                                    WORD count;
                              };
                      struct {
                                    WORD type;
                              } u;
                  DWORD Entry;
                } 

        ULONG       cExcLock;
        ULONG       Tid;
    }GDIOBJHDR, PGDIOBJHDR;


    DWORD
    STDCALL
    DxLock(HANDLE hSurface, PDD_LOCKDATA puLockData, HDC hdcClip)
    {
        DD_LOCKDATA LockData;
        PEDD_SURFACE pSurface;

        _SEH_TRY
        {
            ProbeForRead(puLockData, sizeof(DD_LOCKDATA), 1);
            RtlCopyMemory(&LockData,puLockData, sizeof(DD_LOCKDATA));
        }
        _SEH_HANDLE
        {
            _SEH_YIELD(return DDERR_GENERIC);
        }
        _SEH_END;
        
        pSurface = DdHmgLock(hSurface,2,0);
        .......
        .......
        .......
    }



    LPVOID
    STDCALL
    DdHmgLock(HANDLE hObject, WORD GdiObjectType, BOOL AcqurieHmgrSemaphoreAndRelease )
    {
        PGDIOBJHDR pObjhdr = NULL;
        PVOID pRetObjhdr = NULL;
        DWORD position = hObject & 0x1FFFFF;

        /* check see if we need Acqurie Hmgr Semaphore */
        if ( !AcqurieHmgrSemaphoreAndRelease )
        {
            DdHmgAcquireHmgrSemaphore();
        }

        /* Check see if  position we are in range,  gcMaxDdHmgr is our counter how many object we got */
        if (  position < gcMaxDdHmgr   )
        {
            /* Get our Gdi Object */
            pObjhdr = (LPBYTE)gpentDdHmgr + (position * sizeof(GDIOBJHDR) );

            /* Vaildate if we got the object type we wanted */        
            if ( ( pObjhdr->Type == GdiObjectType ) &&
                 (( pObjhdr->Entry) == (((DWORD)hObject >> 21) & 0x7FF) ) &&
                 (pObjhdr->cExcLock) &&
                 (pObjhdr->Tid != PsGetCurrentThread() ) )
            {
                InterlockedIncrement(pObjhdr->cExcLock);
                pObjhdr->Tid = PsGetCurrentThread();
                pRetObjhdr = (PVOID) pObjhdr;
            }        
        }

        /* check see if we need release Hmgr Semaphore */
        if ( !AcqurieHmgrSemaphoreAndRelease )
        {
            DdHmgReleaseHmgrSemaphore();
        }

        return pRetObjhdr;
    }
      Original Message ----- 
      From: Magnus Olsen 
      To: ReactOS Development List 
      Sent: Sunday, December 30, 2007 12:07 PM
      Subject: Re: [ros-dev] About GDIOBJHDR header changes


      Hi Jim and Timo
      I base it on how dxg.sys acts when it lock a 
      dx object. 
      rember that DWORD store data diffent 
      the 2 we see it should be the type
      rember that the byte order for DWORD is 
      casted it mean if it got 2 it is store in the higher part
      see memory layout

      memory layout 
       ---------------------------------
      | WORD 00  | bit 0-15   |
       ---------------------------------
      | WORD 01  | bit 16-31 |
       ---------------------------------

      word 01 and word 00 are swaped when it display as DWORD, in DWORD the word 01 will become bit 0-15, word 00 will become bit 16-31
      that expain the value 0,1,2,3 we see in PVOID Entry. if we split it. we will see value 0,1,2,3,4 in Type amd count is often 0.
      I have no clude yet what diffent type it exists. 

      the count is often set to 0
      and the type is set to 0, 1, 2, 3 and so on. 

      Still any unclear why I think it we should Split PVOID into two diffent members ?




      ----- Original Message ----- 
        From: Timo Kreuzer 
        To: ReactOS Development List 
        Sent: Sunday, December 30, 2007 4:24 AM
        Subject: Re: [ros-dev] About GDIOBJHDR header changes


        James Tabor schrieb: 
Hi!

  typedef struct _GDIOBJHDR
{
    HGDIOBJ     hHmgr;
    PVOID       unknownCount;
    ULONG       cExcLock;
    ULONG       Tid;
}GDIOBJHDR, PGDIOBJHDR;

    I thought PVOID unknownCount was PVOID pEntry which is the pointer
back to the handle table entry. That could have changed since this is
based on Yuan book and w2k. Remember too, that DxDD handles are
different and handled outside normal DC's.
  Yuan says it's pEntry, I came to the conclusion it's probably a counter, because it's values are small like 1,2,3..0x200
        see http://www.reactos.org/wiki/index.php/Techwiki/win32k/GDIOBJHDR
        Has probably changed from 2k to xp.
        I agree, DX objects might be different, maybe they have a different header structure, I have never looked at DX object memory, so I don't know how they look...
        I just can say that all GDI objects I have dumped the memory of, don't have a type field there, it's always been 0.

        Timo





------------------------------------------------------------------------



        _______________________________________________
        Ros-dev mailing list
        Ros-dev at reactos.org
        http://www.reactos.org/mailman/listinfo/ros-dev



--------------------------------------------------------------------------



      _______________________________________________
      Ros-dev mailing list
      Ros-dev at reactos.org
      http://www.reactos.org/mailman/listinfo/ros-dev
    _______________________________________________
    Ros-dev mailing list
    Ros-dev at reactos.org
    http://www.reactos.org/mailman/listinfo/ros-dev


  Best regards,
  Alex Ionescu




------------------------------------------------------------------------------


  _______________________________________________
  Ros-dev mailing list
  Ros-dev at reactos.org
  http://www.reactos.org/mailman/listinfo/ros-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-dev/attachments/20071230/0761be24/attachment-0001.html 


More information about the Ros-dev mailing list