- Added two new function's to support thread and process information free attribute list support.

svn path=/trunk/; revision=44792
This commit is contained in:
James Tabor 2009-12-28 07:02:32 +00:00
parent 7781a0c84e
commit 050435c284
2 changed files with 144 additions and 0 deletions

View file

@ -114,6 +114,9 @@ Win32kProcessCallback(struct _EPROCESS *Process,
InitializeListHead(&Win32Process->MenuListHead);
InitializeListHead(&Win32Process->GDIBrushAttrFreeList);
InitializeListHead(&Win32Process->GDIDcAttrFreeList);
InitializeListHead(&Win32Process->PrivateFontListHead);
ExInitializeFastMutex(&Win32Process->PrivateFontListLock);

View file

@ -12,6 +12,147 @@
#include <debug.h>
#define GDIDCATTRFREE 8
typedef struct _GDI_DC_ATTR_FREELIST
{
LIST_ENTRY Entry;
DWORD nEntries;
PVOID AttrList[GDIDCATTRFREE];
} GDI_DC_ATTR_FREELIST, *PGDI_DC_ATTR_FREELIST;
typedef struct _GDI_DC_ATTR_ENTRY
{
DC_ATTR Attr[GDIDCATTRFREE];
} GDI_DC_ATTR_ENTRY, *PGDI_DC_ATTR_ENTRY;
PDC_ATTR
FASTCALL
AllocateDcAttr(VOID)
{
PTHREADINFO pti;
PPROCESSINFO ppi;
PDC_ATTR pDc_Attr;
PGDI_DC_ATTR_FREELIST pGdiDcAttrFreeList;
PGDI_DC_ATTR_ENTRY pGdiDcAttrEntry;
int i;
pti = PsGetCurrentThreadWin32Thread();
if (pti->pgdiDcattr)
{
pDc_Attr = pti->pgdiDcattr; // Get the free one.
pti->pgdiDcattr = NULL;
return pDc_Attr;
}
ppi = PsGetCurrentProcessWin32Process();
if (!ppi->pDCAttrList) // If set point is null, allocate new group.
{
pGdiDcAttrEntry = EngAllocUserMem(sizeof(GDI_DC_ATTR_ENTRY), 0);
if (!pGdiDcAttrEntry)
{
DPRINT1("DcAttr Failed User Allocation!\n");
return NULL;
}
DPRINT("AllocDcAttr User 0x%x\n",pGdiDcAttrEntry);
pGdiDcAttrFreeList = ExAllocatePoolWithTag( PagedPool,
sizeof(GDI_DC_ATTR_FREELIST),
GDITAG_DC_FREELIST);
if ( !pGdiDcAttrFreeList )
{
EngFreeUserMem(pGdiDcAttrEntry);
return NULL;
}
RtlZeroMemory(pGdiDcAttrFreeList, sizeof(GDI_DC_ATTR_FREELIST));
DPRINT("AllocDcAttr Ex 0x%x\n",pGdiDcAttrFreeList);
InsertHeadList( &ppi->GDIDcAttrFreeList, &pGdiDcAttrFreeList->Entry);
pGdiDcAttrFreeList->nEntries = GDIDCATTRFREE;
// Start at the bottom up and set end of free list point.
ppi->pDCAttrList = &pGdiDcAttrEntry->Attr[GDIDCATTRFREE-1];
// Build the free attr list.
for ( i = 0; i < GDIDCATTRFREE; i++)
{
pGdiDcAttrFreeList->AttrList[i] = &pGdiDcAttrEntry->Attr[i];
}
}
pDc_Attr = ppi->pDCAttrList;
pGdiDcAttrFreeList = (PGDI_DC_ATTR_FREELIST)ppi->GDIDcAttrFreeList.Flink;
// Free the list when it is full!
if ( pGdiDcAttrFreeList->nEntries-- == 1)
{ // No more free entries, so yank the list.
RemoveEntryList( &pGdiDcAttrFreeList->Entry );
ExFreePoolWithTag( pGdiDcAttrFreeList, GDITAG_DC_FREELIST );
if ( IsListEmpty( &ppi->GDIDcAttrFreeList ) )
{
ppi->pDCAttrList = NULL;
return pDc_Attr;
}
pGdiDcAttrFreeList = (PGDI_DC_ATTR_FREELIST)ppi->GDIDcAttrFreeList.Flink;
}
ppi->pDCAttrList = pGdiDcAttrFreeList->AttrList[pGdiDcAttrFreeList->nEntries-1];
return pDc_Attr;
}
VOID
FASTCALL
FreeDcAttr(PDC_ATTR pDc_Attr)
{
PTHREADINFO pti;
PPROCESSINFO ppi;
PGDI_DC_ATTR_FREELIST pGdiDcAttrFreeList;
pti = PsGetCurrentThreadWin32Thread();
if (!pti) return;
if (!pti->pgdiDcattr)
{ // If it is null, just cache it for the next time.
pti->pgdiDcattr = pDc_Attr;
return;
}
ppi = PsGetCurrentProcessWin32Process();
pGdiDcAttrFreeList = (PGDI_DC_ATTR_FREELIST)ppi->GDIDcAttrFreeList.Flink;
// We add to the list of free entries, so this will grows!
if ( IsListEmpty(&ppi->GDIDcAttrFreeList) ||
pGdiDcAttrFreeList->nEntries == GDIDCATTRFREE )
{
pGdiDcAttrFreeList = ExAllocatePoolWithTag( PagedPool,
sizeof(GDI_DC_ATTR_FREELIST),
GDITAG_DC_FREELIST);
if ( !pGdiDcAttrFreeList )
{
return;
}
InsertHeadList( &ppi->GDIDcAttrFreeList, &pGdiDcAttrFreeList->Entry);
pGdiDcAttrFreeList->nEntries = 0;
}
// Up count, save the entry and set end of free list point.
++pGdiDcAttrFreeList->nEntries; // Top Down...
pGdiDcAttrFreeList->AttrList[pGdiDcAttrFreeList->nEntries-1] = pDc_Attr;
ppi->pDCAttrList = pDc_Attr;
return;
}
VOID
FASTCALL
DC_AllocateDcAttr(HDC hDC)