Hi I been working on dxg.sys some time now and documented some behovir, I started blackbox how DxLock work. it is base on gdi how thing it work, using same GDIOBJHDR struct. I do not go into detail here we all known who dx is handle in win32k in xp and higher.
here is the public header of GDIOBJHDR typedef struct _GDIOBJHDR { HGDIOBJ hHmgr; PVOID unknownCount; ULONG cExcLock; ULONG Tid; }GDIOBJHDR, PGDIOBJHDR;
I want change it to
typedef struct _GDIOBJHDR { HGDIOBJ hHmgr; WORD Count; WORD Type; ULONG cExcLock; ULONG Tid; }GDIOBJHDR, PGDIOBJHDR;
hHmgr Handle for this object.
Count A counter of a kind
Type which GDI Object type it is
cExcLock if the object is lock or not
Tid The Thread it belong to
I hope we can do this change and I want comment and verify from Timo and Jim about this change
Hi,
I have never seen an ObjectType value in that field.
Timo
Magnus Olsen schrieb:
... I want change it to
typedef struct _GDIOBJHDR { HGDIOBJ hHmgr; WORD Count; WORD Type; ULONG cExcLock; ULONG Tid; }GDIOBJHDR, PGDIOBJHDR;
hHmgr Handle for this object.
Count A counter of a kind
Type which GDI Object type it is
cExcLock if the object is lock or not
Tid The Thread it belong to
I hope we can do this change and I want comment and verify from Timo and Jim about this change
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
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.
Count A counter of a kind
Type which GDI Object type it is
Thanks, James
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
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@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
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@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
------------------------------------------------------------------------------
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
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 ourcounter 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@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Best regards, Alex Ionescu
Thank u alex to clear things up I have add thuse struct at http://www.reactos.org/wiki/index.php/Techwiki/win32k/structures
----- 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@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
--------------------------------------------------------------------------
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Best regards, Alex Ionescu
------------------------------------------------------------------------------
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
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@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
--------------------------------------------------------------------------
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Best regards, Alex Ionescu
------------------------------------------------------------------------------
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
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 ourcounter 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@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Best regards, Alex Ionescu
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Best regards, Alex Ionescu
Thx I verify it I hope it is last miste from my side here is what I found in dxg when I Play with BASEOBJECT
struct _BASEOBJECT { HANDLE hHmgr; ULONG ulShareCount; LONG cExclusiveLock; PW32THREAD Tid; ULONG BaseFlags; } DD_BASEOBJECT, *PDD_BASEOBJECT, *POBJ;
only diffent is Tid and BaseFlags was need change place, aganst the version that alex posted ----- Original Message ----- From: Alex Ionescu To: ReactOS Development List Sent: Sunday, December 30, 2007 4:18 PM Subject: Re: [ros-dev] About GDIOBJHDR header changes
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@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
----------------------------------------------------------------------
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Best regards, Alex Ionescu
--------------------------------------------------------------------------
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Best regards, Alex Ionescu
------------------------------------------------------------------------------
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
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
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
Hi!
On Dec 30, 2007 10:43 PM, Alex Ionescu ionucu@videotron.ca wrote:
Hi,
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
I like this one: lkd> dt win32k!_W32THREAD -r +0x000 pEThread : Ptr32 _ETHREAD +0x004 RefCount : Uint4B +0x008 ptlW32 : Ptr32 _TL +0x000 next : Ptr32 _TL +0x000 next : Ptr32 _TL +0x004 pobj : Ptr32 Void +0x008 pfnFree : Ptr32 +0x004 pobj : Ptr32 Void +0x008 pfnFree : Ptr32 +0x00c pgdiDcattr : Ptr32 Void +0x010 pgdiBrushAttr : Ptr32 Void +0x014 pUMPDObjs : Ptr32 Void +0x018 pUMPDHeap : Ptr32 Void +0x01c dwEngAcquireCount : Uint4B +0x020 pSemTable : Ptr32 Void +0x024 pUMPDObj : Ptr32 Void
This sets on top of thread info above the "USER specific fields". Thanks! James
what I reading the _ENTRY should look like this as final version, correct me if I am wrong
typedef struct _ENTRY { union { PDD_BASEOBJECT pobj; HANDLE hFree; } einfo;
union { ULONG ulObj; struct { USHORT Count; USHORT Pid_Shifted; } Share; } ObjectOwner; USHORT FullUnique; UCHAR Objt; UCHAR Flags; PVOID pUser; } DD_ENTRY, *PDD_ENTRY;
----- Original Message ----- From: "James Tabor" jimtabor.rosdev@gmail.com To: "ReactOS Development List" ros-dev@reactos.org Sent: Monday, December 31, 2007 7:46 AM Subject: Re: [ros-dev] About GDIOBJHDR header changes
Hi!
On Dec 30, 2007 10:43 PM, Alex Ionescu ionucu@videotron.ca wrote:
Hi,
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
I like this one: lkd> dt win32k!_W32THREAD -r +0x000 pEThread : Ptr32 _ETHREAD +0x004 RefCount : Uint4B +0x008 ptlW32 : Ptr32 _TL +0x000 next : Ptr32 _TL +0x000 next : Ptr32 _TL +0x004 pobj : Ptr32 Void +0x008 pfnFree : Ptr32 +0x004 pobj : Ptr32 Void +0x008 pfnFree : Ptr32 +0x00c pgdiDcattr : Ptr32 Void +0x010 pgdiBrushAttr : Ptr32 Void +0x014 pUMPDObjs : Ptr32 Void +0x018 pUMPDHeap : Ptr32 Void +0x01c dwEngAcquireCount : Uint4B +0x020 pSemTable : Ptr32 Void +0x024 pUMPDObj : Ptr32 Void
This sets on top of thread info above the "USER specific fields". Thanks! James
Ref: http://forum.sysinternals.com/forum_posts.asp?TID=901 _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Wrong, it should be like this:
typedef struct _BASEOBJECT { HANDLE hHmgr; ULONG ulShareCount; USHORT cExclusiveLock; USHORT BaseFlags; PW32THREAD Tid; } BASEOBJECT, *POBJ;
typedef struct _EINFO { union { POBJ pobj; HOBJ hFree; }; } EINFO, *PEINFO;
typedef struct _OBJECTOWNER_S { ULONG Lock:1; ULONG Pid_Shifted:31; } OBJECTOWNER_S, *POBJECTOWNER_S;
typedef struct _OBJECTOWNER { union { OBJECTOWNER_S Share; ULONG ulObj; }; } OBJECTOWNER, *POBJECTOWNER;
typedef struct _ENTRY { EINFO einfo; OBJECTOWNER ObjectOwner; USHORT FullUnique; UCHAR Objt; UCHAR Flags; PVOID pUser; } ENTRY, DD_ENTRY, *PENTRY, *PDD_ENTRY;
Also, now you don't need to do Pid & 0xFFFFFFFC in your code, you can just use .Pid_Shifted directly.
On 31-Dec-07, at 8:42 AM, Magnus Olsen wrote:
what I reading the _ENTRY should look like this as final version, correct me if I am wrong
typedef struct _ENTRY { union { PDD_BASEOBJECT pobj; HANDLE hFree; } einfo;
union { ULONG ulObj; struct { USHORT Count; USHORT Pid_Shifted; } Share; } ObjectOwner; USHORT FullUnique; UCHAR Objt; UCHAR Flags; PVOID pUser;} DD_ENTRY, *PDD_ENTRY;
----- Original Message ----- From: "James Tabor" jimtabor.rosdev@gmail.com To: "ReactOS Development List" ros-dev@reactos.org Sent: Monday, December 31, 2007 7:46 AM Subject: Re: [ros-dev] About GDIOBJHDR header changes
Hi!
On Dec 30, 2007 10:43 PM, Alex Ionescu ionucu@videotron.ca wrote:
Hi,
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
I like this one: lkd> dt win32k!_W32THREAD -r +0x000 pEThread : Ptr32 _ETHREAD +0x004 RefCount : Uint4B +0x008 ptlW32 : Ptr32 _TL +0x000 next : Ptr32 _TL +0x000 next : Ptr32 _TL +0x004 pobj : Ptr32 Void +0x008 pfnFree : Ptr32 +0x004 pobj : Ptr32 Void +0x008 pfnFree : Ptr32 +0x00c pgdiDcattr : Ptr32 Void +0x010 pgdiBrushAttr : Ptr32 Void +0x014 pUMPDObjs : Ptr32 Void +0x018 pUMPDHeap : Ptr32 Void +0x01c dwEngAcquireCount : Uint4B +0x020 pSemTable : Ptr32 Void +0x024 pUMPDObj : Ptr32 Void
This sets on top of thread info above the "USER specific fields". Thanks! James
Ref: http://forum.sysinternals.com/forum_posts.asp?TID=901 _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev
Best regards, Alex Ionescu
Alex Ionescu 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; };
Your structure is 20 bytes long, I can say for sure that for all gdi objects I have seen the header is 16 bytes. Maybe you mean struct _BASEOBJECT { HANDLE hHmgr; ULONG ulShareCount; USHORT cExclusiveLock; USHORT BaseFlags; PW32THREAD Tid; }; This would match my findings with having 0x8000 in the BaseFlags field
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; };
I remember a discussion about this some time ago, when I suggested something similar to this one and you were the one who disagreed and now you come up with this one ;-) (Everyone remember we have to deal with endianess.) I agree on most of it, but the second union: the structure consists of 16 bits + 32 bits. Can you explain the fields of the second union please.
Regards, Timo