[ros-dev] About GDIOBJHDR header changes
Alex Ionescu
ionucu at videotron.ca
Sun Dec 30 16:18:35 CET 2007
There is no DD_BASEOBJECT, the cExclusiveLock really is at +0x08,
I've verified in the disassembly as well as with WinDBG.
On 30-Dec-07, at 10:00 AM, Magnus Olsen wrote:
> 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
> _______________________________________________
> 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/274f1fa8/attachment-0001.html
More information about the Ros-dev
mailing list