Fixed one more test, now from 23 to 22 fail. Reordered NtGdiDeleteObjectApp and created a separate function so that applications can not delete DCs belonging to DCEs. Add a check for Wnd = NULL for UserGetDCEx, this did not help the test results. Test Qemu Linux, Xp and hardware. Install and run AbiWord and FF as tests.

svn path=/trunk/; revision=31033
This commit is contained in:
James Tabor 2007-12-06 02:09:56 +00:00
parent 107d3b15e1
commit 5c4628595b
5 changed files with 68 additions and 19 deletions

View file

@ -108,12 +108,14 @@ VOID FASTCALL DC_LockDisplay(HDC);
VOID FASTCALL DC_UnlockDisplay(HDC);
VOID FASTCALL IntGdiCopyFromSaveState(PDC, PDC, HDC);
VOID FASTCALL IntGdiCopyToSaveState(PDC, PDC);
BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
VOID FASTCALL DC_UpdateXforms(PDC dc);
BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest);
BOOL FASTCALL DCU_SyncDcAttrtoUser(PDC);
BOOL FASTCALL DCU_SynchDcAttrtoUser(HDC);
VOID FASTCALL DCU_SetDcUndeletable(HDC);
VOID FASTCALL IntGetViewportExtEx(PDC dc, LPSIZE pt);
VOID FASTCALL IntGetViewportOrgEx(PDC dc, LPPOINT pt);

View file

@ -40,6 +40,7 @@ typedef struct tagDCE
#define DCX_DCEEMPTY 0x00000800
#define DCX_DCEBUSY 0x00001000
#define DCX_DCEDIRTY 0x00002000
#define DCX_DCOWNED 0x00008000
#define DCX_USESTYLE 0x00010000
#define DCX_KEEPCLIPRGN 0x00040000
#define DCX_NOCLIPCHILDREN 0x00080000

View file

@ -161,6 +161,8 @@ DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type)
FirstDce = pDce;
KeLeaveCriticalRegion();
DCU_SetDcUndeletable(pDce->hDC);
if (Type == DCE_WINDOW_DC) //Window DCE have ownership.
{ // Process should already own it.
pDce->pProcess = PsGetCurrentProcess();
@ -403,8 +405,11 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
PWINDOW Wnd = NULL;
if (NULL == Window)
{
Flags &= ~DCX_USESTYLE;
{ // Do the same as GetDC with a NULL.
Window = UserGetWindowObject(IntGetDesktopWindow());
if (Window) Wnd = Window->Wnd;
else
Flags &= ~DCX_USESTYLE;
}
else
Wnd = Window->Wnd;
@ -723,7 +728,8 @@ DceFreeDCE(PDCE pdce, BOOLEAN Force)
}
}
NtGdiDeleteObjectApp(pdce->hDC);
IntGdiDeleteDC(pdce->hDC, TRUE);
if (pdce->hClipRgn && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
{
NtGdiDeleteObject(pdce->hClipRgn);

View file

@ -910,30 +910,33 @@ NtGdiOpenDCW( PUNICODE_STRING Device,
}
//
//
//
BOOL
STDCALL
NtGdiDeleteObjectApp(HANDLE DCHandle)
FASTCALL
IntGdiDeleteDC(HDC hDC, BOOL Force)
{
PDC DCToDelete;
BOOL Ret = FALSE;
PDC DCToDelete = DC_LockDc(hDC);
if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC)
return NtGdiDeleteObject((HGDIOBJ) DCHandle);
if(IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
if (!GDIOBJ_OwnedByCurrentProcess(GdiHandleTable, DCHandle))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
DCToDelete = DC_LockDc(DCHandle);
if (DCToDelete == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if(!Force)
{
if (DCToDelete->DC_Flags & DC_FLAG_PERMANENT)
{
DPRINT1("No! You Naughty Application!\n");
// if(!UserReleaseDC(NULL, hDC, FALSE)) Ret = FALSE;
}
DC_UnlockDc( DCToDelete );
return Ret;
}
/* First delete all saved DCs */
while (DCToDelete->saveLevel)
{
@ -995,10 +998,31 @@ NtGdiDeleteObjectApp(HANDLE DCHandle)
}
DC_UnlockDc( DCToDelete );
DC_FreeDC ( DCHandle );
DC_FreeDC ( hDC );
return TRUE;
}
BOOL
STDCALL
NtGdiDeleteObjectApp(HANDLE DCHandle)
{
if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC)
return NtGdiDeleteObject((HGDIOBJ) DCHandle);
if(IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
if (!GDIOBJ_OwnedByCurrentProcess(GdiHandleTable, DCHandle))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
return IntGdiDeleteDC(DCHandle, FALSE);
}
INT
APIENTRY
NtGdiDrawEscape(

View file

@ -257,3 +257,19 @@ NtGdiSetTextColor(HDC hDC,
NtGdiSelectBrush(hDC, hBrush);
return oldColor;
}
VOID
FASTCALL
DCU_SetDcUndeletable(HDC hDC)
{
PDC dc = DC_LockDc(hDC);
if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return;
}
dc->DC_Flags |= DC_FLAG_PERMANENT;
DC_UnlockDc( dc );
return;
}