- Reordered IntGdiGet/SetDCState and separated the copy sections.

- When creating DCE for window handles, allocate a DC structure for the default window DC.
- Return Dhpdev if not zero for NtGdiOpenDCW.
- Reordered the DC object. 

svn path=/trunk/; revision=28918
This commit is contained in:
James Tabor 2007-09-07 12:21:26 +00:00
parent 5b0be27588
commit bd954074fa
4 changed files with 194 additions and 160 deletions

View file

@ -59,12 +59,19 @@ typedef struct _WIN_DC_INFO
typedef struct _DC
{
HDC hSelf;
HDC hNext;
PDC_ATTR pDc_Attr;
HGDIOBJ hHmgr;
PVOID pvEntry;
ULONG lucExcLock;
ULONG Tid;
DHPDEV PDev;
INT DC_Type;
INT DC_Flags;
DHPDEV PDev;
PDC_ATTR pDc_Attr;
DC_ATTR Dc_Attr;
HDC hSelf;
HDC hNext;
HSURF FillPatternSurfaces[HS_DDI_MAX];
PGDIINFO GDIInfo;
PDEVINFO DevInfo;
@ -85,11 +92,9 @@ typedef struct _DC
HPALETTE PalIndexed;
WIN_DC_INFO w;
DC_ATTR Dc_Attr;
HANDLE hFile;
LPENHMETAHEADER emh;
} DC, *PDC;
typedef struct _GDIPOINTER /* should stay private to ENG */
@ -151,6 +156,8 @@ BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody);
HDC FASTCALL DC_GetNextDC (PDC pDC);
VOID FASTCALL DC_SetNextDC (PDC pDC, HDC hNextDC);
VOID FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner);
VOID FASTCALL IntGdiCopyFromSaveState(PDC, PDC);
VOID FASTCALL IntGdiCopyToSaveState(PDC, PDC);
VOID FASTCALL DC_UpdateXforms(PDC dc);
BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest);

View file

@ -159,7 +159,7 @@ IntGdiGetObject(HANDLE handle, INT count, LPVOID buffer);
HDC FASTCALL
IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
PVOID pUMdhpdev,
CONST PDEVMODEW InitData,
BOOL CreateAsIC);

View file

@ -39,7 +39,7 @@
/* NOTE - I think we should store this per window station (including gdi objects) */
static PDCE FirstDce = NULL;
static HDC defaultDCstate = NULL;
static PDC defaultDCstate = NULL;
//static INT DCECount = 0;
#define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \
@ -126,12 +126,16 @@ DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type)
ExFreePoolWithTag(pDce, TAG_PDCE);
return NULL;
}
//
// If NULL, first time through! Build the default window dc!
//
if (NULL == defaultDCstate) // Ultra HAX! Dedicated to GvG!
{ // This is a cheesy way to do this.
// But, due to the right way of creating gdi handles there is no choice.
defaultDCstate = IntGdiGetDCState(pDce->hDC);
DC_SetOwnership( defaultDCstate, NULL);
PDC dc = DC_LockDc ( pDce->hDC );
defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
RtlZeroMemory(defaultDCstate, sizeof(DC));
IntGdiCopyToSaveState(dc, defaultDCstate);
DC_UnlockDc( dc );
}
pDce->hwndCurrent = (Window ? Window->hSelf : NULL);
@ -144,8 +148,7 @@ DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type)
KeLeaveCriticalRegion();
if (Type == DCE_WINDOW_DC) //Window DCE have ownership.
{
DC_SetOwnership(pDce->hDC, PsGetCurrentProcess());
{ // Process should already own it.
pDce->pProcess = PsGetCurrentProcess();
}
else
@ -248,13 +251,8 @@ DceReleaseDC(DCE* dce, BOOL EndPaint)
/* make the DC clean so that SetDCState doesn't try to update the vis rgn */
IntGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);
if( dce->pProcess ) // Attempt to fix Dc_Attr problem.
DC_SetOwnership( defaultDCstate, dce->pProcess);
else
DC_SetOwnership( defaultDCstate, PsGetCurrentProcess());
IntGdiSetDCState(dce->hDC, defaultDCstate);
DC_SetOwnership( defaultDCstate, NULL); // Return default dc state to inaccessible mode.
PDC dc = DC_LockDc ( dce->hDC );
IntGdiCopyFromSaveState(dc, defaultDCstate); // Was SetDCState.
dce->DCXFlags &= ~DCX_DCEBUSY;
if (dce->DCXFlags & DCX_DCEDIRTY)

View file

@ -809,7 +809,7 @@ IntDestroyPrimarySurface()
HDC FASTCALL
IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
PVOID pUMdhpdev,
CONST PDEVMODEW InitData,
BOOL CreateAsIC)
{
@ -909,6 +909,7 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
memcpy(NewDC->FillPatternSurfaces, PrimarySurface.FillPatterns,
sizeof(NewDC->FillPatternSurfaces));
NewDC->PDev = PrimarySurface.PDev;
if(pUMdhpdev) pUMdhpdev = NewDC->PDev;
NewDC->GDIDevice = (HDEV)&PrimarySurface;
NewDC->DriverFunctions = PrimarySurface.DriverFunctions;
NewDC->w.hBitmap = PrimarySurface.Handle;
@ -963,6 +964,7 @@ NtGdiOpenDCW( PUNICODE_STRING Device,
{
UNICODE_STRING SafeDevice;
DEVMODEW SafeInitData;
PVOID Dhpdev;
HDC Ret;
NTSTATUS Status = STATUS_SUCCESS;
@ -970,6 +972,12 @@ NtGdiOpenDCW( PUNICODE_STRING Device,
{
_SEH_TRY
{
if (pUMdhpdev)
{
ProbeForWrite(pUMdhpdev,
sizeof(PVOID),
1);
}
ProbeForRead(InitData,
sizeof(DEVMODEW),
1);
@ -1002,10 +1010,12 @@ NtGdiOpenDCW( PUNICODE_STRING Device,
Ret = IntGdiCreateDC(NULL == Device ? NULL : &SafeDevice,
NULL,
NULL,
NULL == pUMdhpdev ? NULL : &Dhpdev,
NULL == InitData ? NULL : &SafeInitData,
(BOOL) iType); // FALSE 0 DCW, TRUE 1 ICW
if (pUMdhpdev) pUMdhpdev = Dhpdev;
return Ret;
}
@ -1281,29 +1291,11 @@ NtGdiSetBkColor(HDC hDC, COLORREF color)
return oldColor;
}
HDC STDCALL
IntGdiGetDCState(HDC hDC)
VOID
FASTCALL
IntGdiCopyToSaveState(PDC dc, PDC newdc)
{
PDC newdc, dc;
HDC hnewdc;
dc = DC_LockDc(hDC);
if (dc == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
hnewdc = DC_AllocDC(NULL);
if (hnewdc == NULL)
{
DC_UnlockDc(dc);
return 0;
}
newdc = DC_LockDc( hnewdc );
/* FIXME - newdc can be NULL!!!! Don't assert here!!! */
ASSERT( newdc );
newdc->w.flags = dc->w.flags | DC_SAVED;
newdc->Dc_Attr.hpen = dc->Dc_Attr.hpen;
newdc->Dc_Attr.hbrush = dc->Dc_Attr.hbrush;
@ -1344,7 +1336,6 @@ IntGdiGetDCState(HDC hDC)
newdc->w.xformWorld2Vport = dc->w.xformWorld2Vport;
newdc->w.xformVport2World = dc->w.xformVport2World;
newdc->w.vport2WorldValid = dc->w.vport2WorldValid;
DCU_UpdateUserXForms(newdc, WORLD_TO_PAGE_IDENTITY|DEVICE_TO_WORLD_INVALID|WORLD_XFORM_CHANGED );
newdc->Dc_Attr.ptlWindowOrg.x = dc->Dc_Attr.ptlWindowOrg.x;
newdc->Dc_Attr.ptlWindowOrg.y = dc->Dc_Attr.ptlWindowOrg.y;
newdc->Dc_Attr.szlWindowExt.cx = dc->Dc_Attr.szlWindowExt.cx;
@ -1354,7 +1345,6 @@ IntGdiGetDCState(HDC hDC)
newdc->Dc_Attr.szlViewportExt.cx = dc->Dc_Attr.szlViewportExt.cx;
newdc->Dc_Attr.szlViewportExt.cy = dc->Dc_Attr.szlViewportExt.cy;
newdc->hSelf = hnewdc;
newdc->saveLevel = 0;
newdc->IsIC = dc->IsIC;
@ -1370,27 +1360,15 @@ IntGdiGetDCState(HDC hDC)
newdc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
NtGdiCombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
}
DCU_SyncDcAttrtoUser(newdc, -1);
DC_UnlockDc( newdc );
DC_UnlockDc( dc );
return hnewdc;
}
VOID
STDCALL
IntGdiSetDCState ( HDC hDC, HDC hDCSave )
FASTCALL
IntGdiCopyFromSaveState(PDC dc, PDC dcs)
{
PDC dc, dcs;
HDC hDC = dc->hSelf;
dc = DC_LockDc ( hDC );
if ( dc )
{
dcs = DC_LockDc ( hDCSave );
if ( dcs )
{
if ( dcs->w.flags & DC_SAVED )
{
dc->w.flags = dcs->w.flags & ~DC_SAVED;
dc->w.hFirstBitmap = dcs->w.hFirstBitmap;
@ -1416,7 +1394,7 @@ IntGdiSetDCState ( HDC hDC, HDC hDCSave )
dc->Dc_Attr.iMapMode = dcs->Dc_Attr.iMapMode;
dc->Dc_Attr.iGraphicsMode = dcs->Dc_Attr.iGraphicsMode;
#if 0
/* Apparently, the DC origin is not changed by [GS]etDCState */
/* Apparently, the DC origin is not changed by [GS]etDCState */
dc->w.DCOrgX = dcs->w.DCOrgX;
dc->w.DCOrgY = dcs->w.DCOrgY;
#endif
@ -1428,7 +1406,6 @@ IntGdiSetDCState ( HDC hDC, HDC hDCSave )
dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport;
dc->w.xformVport2World = dcs->w.xformVport2World;
dc->w.vport2WorldValid = dcs->w.vport2WorldValid;
DCU_UpdateUserXForms(dc, WORLD_TO_PAGE_IDENTITY|DEVICE_TO_WORLD_INVALID|WORLD_XFORM_CHANGED );
dc->Dc_Attr.ptlWindowOrg.x = dcs->Dc_Attr.ptlWindowOrg.x;
dc->Dc_Attr.ptlWindowOrg.y = dcs->Dc_Attr.ptlWindowOrg.y;
dc->Dc_Attr.szlWindowExt.cx = dcs->Dc_Attr.szlWindowExt.cx;
@ -1459,7 +1436,6 @@ IntGdiSetDCState ( HDC hDC, HDC hDCSave )
{
NtGdiDeleteObject( dc->w.hClipRgn );
}
dc->w.hClipRgn = 0;
}
{
@ -1477,6 +1453,7 @@ IntGdiSetDCState ( HDC hDC, HDC hDCSave )
NtGdiSelectObject( hDC, dcs->Dc_Attr.hbrush );
NtGdiSelectObject( hDC, dcs->Dc_Attr.hlfntNew );
NtGdiSelectObject( hDC, dcs->Dc_Attr.hpen );
NtGdiSetBkColor( hDC, dcs->Dc_Attr.crBackgroundClr);
NtGdiSetTextColor( hDC, dcs->Dc_Attr.crForegroundClr);
@ -1485,11 +1462,65 @@ IntGdiSetDCState ( HDC hDC, HDC hDCSave )
#if 0
GDISelectPalette16( hDC, dcs->w.hPalette, FALSE );
#endif
} else {
}
HDC STDCALL
IntGdiGetDCState(HDC hDC)
{
PDC newdc, dc;
HDC hnewdc;
dc = DC_LockDc(hDC);
if (dc == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
hnewdc = DC_AllocDC(NULL);
if (hnewdc == NULL)
{
DC_UnlockDc(dc);
return 0;
}
newdc = DC_LockDc( hnewdc );
/* FIXME - newdc can be NULL!!!! Don't assert here!!! */
ASSERT( newdc );
newdc->hSelf = hnewdc;
IntGdiCopyToSaveState( dc, newdc);
DCU_SyncDcAttrtoUser(newdc, -1);
DC_UnlockDc( newdc );
DC_UnlockDc( dc );
return hnewdc;
}
VOID
STDCALL
IntGdiSetDCState ( HDC hDC, HDC hDCSave )
{
PDC dc, dcs;
dc = DC_LockDc ( hDC );
if ( dc )
{
dcs = DC_LockDc ( hDCSave );
if ( dcs )
{
if ( dcs->w.flags & DC_SAVED )
{
IntGdiCopyFromSaveState( dc, dcs);
}
else
{
DC_UnlockDc(dc);
}
DC_UnlockDc ( dcs );
} else {
}
else
{
DC_UnlockDc ( dc );
SetLastWin32Error(ERROR_INVALID_HANDLE);
}
@ -2607,7 +2638,6 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner)
{
PDC DC;
// DC_FreeDcAttr(hDC, NULL);
GDIOBJ_SetOwnership(GdiHandleTable, hDC, Owner);
DC = DC_LockDc(hDC);
if (NULL != DC)
@ -2626,7 +2656,6 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner)
}
DC_UnlockDc(DC);
}
// DC_AllocateDcAttr(hDC, Owner);
}
BOOL FASTCALL