📄 dc.c
字号:
SetLastWin32Error(ERROR_INVALID_HANDLE);
break;
}
XlateObj = IntGdiCreateBrushXlate(dc, pen, &Failed);
PENOBJ_UnlockPen(pen);
if (Failed)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
break;
}
objOrg = (HGDIOBJ)dc->Dc_Attr.hpen;
dc->Dc_Attr.hpen = hGDIObj;
if (dc->XlatePen != NULL)
EngDeleteXlate(dc->XlatePen);
dc->XlatePen = XlateObj;
break;
case GDI_OBJECT_TYPE_BRUSH:
brush = BRUSHOBJ_LockBrush((HPEN) hGDIObj);
if (brush == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
break;
}
XlateObj = IntGdiCreateBrushXlate(dc, brush, &Failed);
BRUSHOBJ_UnlockBrush(brush);
if (Failed)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
break;
}
objOrg = (HGDIOBJ)dc->Dc_Attr.hbrush;
dc->Dc_Attr.hbrush = hGDIObj;
if (dc->XlateBrush != NULL)
EngDeleteXlate(dc->XlateBrush);
dc->XlateBrush = XlateObj;
break;
case GDI_OBJECT_TYPE_FONT:
if(NT_SUCCESS(TextIntRealizeFont((HFONT)hGDIObj)))
{
objOrg = (HGDIOBJ)dc->Dc_Attr.hlfntNew;
dc->Dc_Attr.hlfntNew = (HFONT) hGDIObj;
}
break;
case GDI_OBJECT_TYPE_BITMAP:
// must be memory dc to select bitmap
if (!(dc->w.flags & DC_MEMORY))
{
DC_UnlockDc(dc);
return NULL;
}
pb = BITMAPOBJ_LockBitmap(hGDIObj);
if (NULL == pb)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
DC_UnlockDc(dc);
return NULL;
}
objOrg = (HGDIOBJ)dc->w.hBitmap;
/* Release the old bitmap, lock the new one and convert it to a SURF */
dc->w.hBitmap = hGDIObj;
// if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
if(pb->dib)
{
dc->w.bitsPerPixel = pb->dib->dsBmih.biBitCount;
dc->w.hPalette = pb->hDIBPalette;
}
else
{
dc->w.bitsPerPixel = BitsPerFormat(pb->SurfObj.iBitmapFormat);
dc->w.hPalette = dc->DevInfo->hpalDefault;
}
/* Reselect brush and pen to regenerate the XLATEOBJs. */
NtGdiSelectObject ( hDC, dc->Dc_Attr.hbrush );
NtGdiSelectObject ( hDC, dc->Dc_Attr.hpen );
DC_UnlockDc ( dc );
hVisRgn = NtGdiCreateRectRgn ( 0, 0, pb->SurfObj.sizlBitmap.cx, pb->SurfObj.sizlBitmap.cy );
BITMAPOBJ_UnlockBitmap( pb );
IntGdiSelectVisRgn ( hDC, hVisRgn );
NtGdiDeleteObject ( hVisRgn );
return objOrg;
case GDI_OBJECT_TYPE_REGION:
/*
* The return value is one of the following values:
* SIMPLEREGION
* COMPLEXREGION
* NULLREGION
*/
objectType = IntGdiExtSelectClipRgn(dc, (HRGN)hGDIObj, RGN_COPY);
DC_UnlockDc (dc);
return (HGDIOBJ)objectType;
default:
break;
}
DC_UnlockDc( dc );
return objOrg;
}
WORD STDCALL
IntGdiSetHookFlags(HDC hDC, WORD Flags)
{
WORD wRet;
DC *dc = DC_LockDc(hDC);
if (NULL == dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
wRet = dc->w.flags & DC_DIRTY;
/* "Undocumented Windows" info is slightly confusing.
*/
DPRINT("DC %p, Flags %04x\n", hDC, Flags);
if (Flags & DCHF_INVALIDATEVISRGN)
{
dc->w.flags |= DC_DIRTY;
}
else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
{
dc->w.flags &= ~DC_DIRTY;
}
DC_UnlockDc(dc);
return wRet;
}
BOOL
STDCALL
NtGdiGetDCDword(
HDC hDC,
UINT u,
DWORD *Result
)
{
BOOL Ret = TRUE;
DC *dc;
DWORD SafeResult = 0;
NTSTATUS Status = STATUS_SUCCESS;
if(!Result)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
dc = DC_LockDc(hDC);
if(!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
switch (u)
{
case GdiGetJournal:
break;
case GdiGetRelAbs:
SafeResult = dc->Dc_Attr.lRelAbs;
break;
case GdiGetBreakExtra:
SafeResult = dc->Dc_Attr.lBreakExtra;
break;
case GdiGerCharBreak:
SafeResult = dc->Dc_Attr.cBreak;
break;
case GdiGetArcDirection:
SafeResult = dc->w.ArcDirection;
break;
case GdiGetEMFRestorDc:
break;
case GdiGetFontLanguageInfo:
break;
case GdiGetIsMemDc:
SafeResult = dc->DC_Type;
break;
case GdiGetMapMode:
SafeResult = dc->Dc_Attr.iMapMode;
break;
case GdiGetTextCharExtra:
SafeResult = dc->Dc_Attr.lTextExtra;
break;
default:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
if (Ret)
{
_SEH_TRY
{
ProbeForWrite(Result,
sizeof(DWORD),
1);
*Result = SafeResult;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(dc);
return FALSE;
}
DC_UnlockDc(dc);
return Ret;
}
BOOL
STDCALL
NtGdiGetAndSetDCDword(
HDC hDC,
UINT u,
DWORD dwIn,
DWORD *Result
)
{
BOOL Ret = TRUE;
DC *dc;
DWORD SafeResult = 0;
NTSTATUS Status = STATUS_SUCCESS;
if(!Result)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
dc = DC_LockDc(hDC);
if(!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
switch (u)
{
case GdtGetSetCopyCount:
break;
case GdiGetSetTextAlign:
SafeResult = dc->Dc_Attr.lTextAlign;
dc->Dc_Attr.lTextAlign = dwIn;
dc->Dc_Attr.flTextAlign = dwIn;
break;
case GdiGetSetRelAbs:
SafeResult = dc->Dc_Attr.lRelAbs;
dc->Dc_Attr.lRelAbs = dwIn;
break;
case GdiGetSetTextCharExtra:
SafeResult = dc->Dc_Attr.lTextExtra;
dc->Dc_Attr.lTextExtra = dwIn;
break;
case GdiGetSetSelectFont:
break;
case GdiGetSetMapperFlagsInternal:
break;
case GdiGetSetMapMode:
SafeResult = dc->Dc_Attr.iMapMode;
dc->Dc_Attr.iMapMode = dwIn;
break;
case GdiGetSetArcDirection:
if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Ret = FALSE;
}
SafeResult = dc->w.ArcDirection;
dc->w.ArcDirection = dwIn;
break;
default:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
if (Ret)
{
_SEH_TRY
{
ProbeForWrite(Result,
sizeof(DWORD),
1);
*Result = SafeResult;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(dc);
return FALSE;
}
DC_UnlockDc(dc);
return Ret;
}
DC_SET_MODE( NtGdiSetBkMode, Dc_Attr.jBkMode, TRANSPARENT, OPAQUE )
DC_SET_MODE( NtGdiSetPolyFillMode, Dc_Attr.jFillMode, ALTERNATE, WINDING )
DC_SET_MODE( NtGdiSetROP2, Dc_Attr.jROP2, R2_BLACK, R2_WHITE )
DC_SET_MODE( NtGdiSetStretchBltMode, Dc_Attr.jStretchBltMode, BLACKONWHITE, HALFTONE )
// ---------------------------------------------------- Private Interface
HDC FASTCALL
DC_AllocDC(PUNICODE_STRING Driver)
{
PDC NewDC;
HDC hDC;
PWSTR Buf = NULL;
// PDC_ATTR DC_Attr = NULL;
if (Driver != NULL)
{
Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
if(!Buf)
{
return NULL;
}
RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength);
}
hDC = (HDC) GDIOBJ_AllocObj(GdiHandleTable, GDI_OBJECT_TYPE_DC);
if (hDC == NULL)
{
if(Buf)
{
ExFreePool(Buf);
}
return NULL;
}
#if 0
PVOID NewMem = NULL;
ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size
NTSTATUS Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
&NewMem,
0,
&MemSize,
MEM_COMMIT,
PAGE_READWRITE);
KeEnterCriticalRegion();
{
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
if (NT_SUCCESS(Status))
{
RtlZeroMemory(NewMem, MemSize);
Entry->UserData = NewMem;
DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
}
else
{
DPRINT("DC_ATTR not allocated!\n");
}
}
KeLeaveCriticalRegion();
#endif
NewDC = DC_LockDc(hDC);
/* FIXME - Handle NewDC == NULL! */
#if 0
if(NewMem)
{
NewDC->pDc_Attr = NewMem; // Store pointer
DC_Attr = NewMem;
}
#endif
if (Driver != NULL)
{
RtlCopyMemory(&NewDC->DriverName, Driver, sizeof(UNICODE_STRING));
NewDC->DriverName.Buffer = Buf;
}
// gxf_long a;
// a.f = 1.0f;
NewDC->w.xformWorld2Wnd.eM11 = 1.0f;
// DC_Attr->mxWorldToPage.efM11.lExp = XFPEXP(a);
// DC_Attr->mxWorldToPage.efM11.lMant = XFPMANT(a);
NewDC->w.xformWorld2Wnd.eM12 = 0.0f; //Already Zero!
NewDC->w.xformWorld2Wnd.eM21 = 0.0f;
NewDC->w.xformWorld2Wnd.eM22 = 1.0f;
// DC_Attr->mxWorldToPage.efM22.lExp = XFPEXP(a);
// DC_Attr->mxWorldToPage.efM22.lMant = XFPMANT(a);
NewDC->w.xformWorld2Wnd.eDx = 0.0f; //Already Zero!
NewDC->w.xformWorld2Wnd.eDy = 0.0f;
NewDC->w.xformWorld2Vport = NewDC->w.xformWorld2Wnd;
// DC_Attr->mxWorldToDevice = DC_Attr->mxWorldToPage;
NewDC->w.xformVport2World = NewDC->w.xformWorld2Wnd;
// DC_Attr->mxDevicetoWorld = DC_Attr->mxWorldToPage;
NewDC->w.vport2WorldValid = TRUE;
// DC_Attr->flXform = DEVICE_TO_PAGE_INVALID; // More research.
NewDC->Dc_Attr.iMapMode = MM_TEXT;
// DC_Attr->iMapMode = MM_TEXT;
//// HELP! FLOAT to INT !!!!!!!!!
NewDC->Dc_Attr.szlWindowExt.cx = 1.0f;
NewDC->Dc_Attr.szlWindowExt.cy = 1.0f;
NewDC->Dc_Attr.szlViewportExt.cx = 1.0f;
NewDC->Dc_Attr.szlViewportExt.cy = 1.0f;
NewDC->Dc_Attr.crForegroundClr = 0;
// NewDC->pDc_Attr->ulForegroundClr = 0; // Already Zero
// NewDC->pDc_Attr->crForegroundClr = 0;
NewDC->Dc_Attr.crBackgroundClr = 0xffffff;
// DC_Attr->ulBackgroundClr = 0xffffff;
// DC_Attr->crBackgroundClr = 0xffffff;
NewDC->Dc_Attr.hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
TextIntRealizeFont(NewDC->Dc_Attr.hlfntNew);
// DC_Attr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
NewDC->w.hPalette = NtGdiGetStockObject(DEFAULT_PALETTE);
DC_UnlockDc(NewDC);
return hDC;
}
HDC FASTCALL
DC_FindOpenDC(PUNICODE_STRING Driver)
{
return NULL;
}
/*!
* Initialize some common fields in the Device Context structure.
*/
VOID FASTCALL
DC_InitDC(HDC DCHandle)
{
// NtGdiRealizeDefaultPalette(DCHandle);
NtGdiSelectObject(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
NtGdiSelectObject(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
//NtGdiSelectObject(DCHandle, hFont);
/*
{
int res;
res = CLIPPING_UpdateGCRegion(DCToInit);
ASSERT ( res != ERROR );
}
*/
}
VOID FASTCALL
DC_FreeDC(HDC DCToFree)
{
#if 0
KeEnterCriticalRegion();
{
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree);
PGDI_TABLE_ENTRY Entry = &GdiH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -