📄 dc.c
字号:
else
{
GotDriver = TRUE;
}
}
if (! GotDriver)
{
/* Skip to the next name but never get past the Unicode string */
while (L'\0' != *CurrentName &&
CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
{
CurrentName++;
}
if (CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
{
CurrentName++;
}
}
}
RtlFreeUnicodeString(&DriverFileNames);
if (!GotDriver)
{
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("No suitable DDI driver found\n");
continue;
}
DPRINT("Display driver %S loaded\n", CurrentName);
DPRINT("Building DDI Functions\n");
/* Construct DDI driver function dispatch table */
if (!DRIVER_BuildDDIFunctions(&DED, &PrimarySurface.DriverFunctions))
{
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("BuildDDIFunctions failed\n");
goto cleanup;
}
/* Allocate a phyical device handle from the driver */
PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
if (SetupDevMode(&PrimarySurface.DMW, DisplayNumber))
{
PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
&PrimarySurface.DMW,
L"",
HS_DDI_MAX,
PrimarySurface.FillPatterns,
sizeof(PrimarySurface.GDIInfo),
(ULONG *) &PrimarySurface.GDIInfo,
sizeof(PrimarySurface.DevInfo),
&PrimarySurface.DevInfo,
NULL,
L"",
(HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
DoDefault = (NULL == PrimarySurface.PDev);
if (DoDefault)
{
DPRINT1("DrvEnablePDev with registry parameters failed\n");
}
}
else
{
DoDefault = TRUE;
}
if (DoDefault)
{
RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
&PrimarySurface.DMW,
L"",
HS_DDI_MAX,
PrimarySurface.FillPatterns,
sizeof(PrimarySurface.GDIInfo),
(ULONG *) &PrimarySurface.GDIInfo,
sizeof(PrimarySurface.DevInfo),
&PrimarySurface.DevInfo,
NULL,
L"",
(HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
if (NULL == PrimarySurface.PDev)
{
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("DrvEnablePDEV with default parameters failed\n");
DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
continue;
}
}
if (0 == PrimarySurface.GDIInfo.ulLogPixelsX)
{
DPRINT("Adjusting GDIInfo.ulLogPixelsX\n");
PrimarySurface.GDIInfo.ulLogPixelsX = 96;
}
if (0 == PrimarySurface.GDIInfo.ulLogPixelsY)
{
DPRINT("Adjusting GDIInfo.ulLogPixelsY\n");
PrimarySurface.GDIInfo.ulLogPixelsY = 96;
}
PrimarySurface.Pointer.Exclude.right = -1;
DPRINT("calling completePDev\n");
/* Complete initialization of the physical device */
PrimarySurface.DriverFunctions.CompletePDEV(
PrimarySurface.PDev,
(HDEV)&PrimarySurface);
DPRINT("calling DRIVER_ReferenceDriver\n");
DRIVER_ReferenceDriver(L"DISPLAY");
PrimarySurface.PreparedDriver = TRUE;
PrimarySurface.DisplayNumber = DisplayNumber;
ret = TRUE;
goto cleanup;
}
cleanup:
KeSetEvent(&VideoDriverPrepared, 1, FALSE);
return ret;
}
static BOOL FASTCALL
IntPrepareDriverIfNeeded()
{
return (PrimarySurface.PreparedDriver ? TRUE : IntPrepareDriver());
}
static BOOL FASTCALL
PrepareVideoPrt()
{
PIRP Irp;
NTSTATUS Status;
IO_STATUS_BLOCK Iosb;
BOOL Prepare = TRUE;
ULONG Length = sizeof(BOOL);
PIO_STACK_LOCATION StackPtr;
LARGE_INTEGER StartOffset;
PFILE_OBJECT FileObject = PrimarySurface.VideoFileObject;
PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject;
DPRINT("PrepareVideoPrt() called\n");
KeClearEvent(&PrimarySurface.VideoFileObject->Event);
ObReferenceObjectByPointer(FileObject, 0, IoFileObjectType, KernelMode);
StartOffset.QuadPart = 0;
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
DeviceObject,
(PVOID) &Prepare,
Length,
&StartOffset,
NULL,
&Iosb);
if (NULL == Irp)
{
return FALSE;
}
/* Set up IRP Data */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
Irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
Irp->Flags |= IRP_WRITE_OPERATION;
/* Setup Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = PrimarySurface.VideoFileObject;
StackPtr->Parameters.Write.Key = 0;
Status = IoCallDriver(DeviceObject, Irp);
if (STATUS_PENDING == Status)
{
KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, TRUE, 0);
Status = Iosb.Status;
}
return NT_SUCCESS(Status);
}
BOOL FASTCALL
IntCreatePrimarySurface()
{
SIZEL SurfSize;
RECTL SurfaceRect;
SURFOBJ *SurfObj;
BOOL calledFromUser;
if (! IntPrepareDriverIfNeeded())
{
return FALSE;
}
if (! PrepareVideoPrt())
{
return FALSE;
}
DPRINT("calling EnableSurface\n");
/* Enable the drawing surface */
PrimarySurface.Handle =
PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.PDev);
if (NULL == PrimarySurface.Handle)
{
/* PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);*/
PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("DrvEnableSurface failed\n");
return FALSE;
}
PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, TRUE);
calledFromUser = UserIsEntered(); //fixme: possibly upgrade a shared lock
if (!calledFromUser){
UserEnterExclusive();
}
/* attach monitor */
IntAttachMonitor(&PrimarySurface, PrimarySurface.DisplayNumber);
SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
SurfObj->dhpdev = PrimarySurface.PDev;
SurfSize = SurfObj->sizlBitmap;
SurfaceRect.left = SurfaceRect.top = 0;
SurfaceRect.right = SurfObj->sizlBitmap.cx;
SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
/* FIXME - why does EngEraseSurface() sometimes crash?
EngEraseSurface(SurfObj, &SurfaceRect, 0); */
/* Put the pointer in the center of the screen */
GDIDEV(SurfObj)->Pointer.Pos.x = (SurfaceRect.right - SurfaceRect.left) / 2;
GDIDEV(SurfObj)->Pointer.Pos.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
EngUnlockSurface(SurfObj);
co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
if (!calledFromUser){
UserLeave();
}
return TRUE;
}
VOID FASTCALL
IntDestroyPrimarySurface()
{
BOOL calledFromUser;
DRIVER_UnreferenceDriver(L"DISPLAY");
calledFromUser = UserIsEntered();
if (!calledFromUser){
UserEnterExclusive();
}
/* detach monitor */
IntDetachMonitor(&PrimarySurface);
if (!calledFromUser){
UserLeave();
}
/*
* FIXME: Hide a mouse pointer there. Also because we have to prevent
* memory leaks with the Eng* mouse routines.
*/
DPRINT("Reseting display\n" );
PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);
PrimarySurface.DriverFunctions.DisableSurface(PrimarySurface.PDev);
PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
PrimarySurface.PreparedDriver = FALSE;
DceEmptyCache();
ObDereferenceObject(PrimarySurface.VideoFileObject);
}
HDC FASTCALL
IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
CONST PDEVMODEW InitData,
BOOL CreateAsIC)
{
HDC hNewDC;
PDC NewDC;
HDC hDC = NULL;
HRGN hVisRgn;
UNICODE_STRING StdDriver;
BOOL calledFromUser;
RtlInitUnicodeString(&StdDriver, L"DISPLAY");
if (Driver != NULL)
{
DPRINT("NAME Driver: %wZ\n", Driver);
}
else
{
DPRINT("NAME Driver: NULL\n", Driver);
}
if (Driver != NULL)
{
DPRINT("NAME Device: %wZ\n", Device);
}
else
{
DPRINT("NAME Device: NULL\n", Device);
}
if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
{
if (CreateAsIC)
{
if (! IntPrepareDriverIfNeeded())
{
DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
return NULL;
}
}
else
{
calledFromUser = UserIsEntered();
if (!calledFromUser){
UserEnterExclusive();
}
if (! co_IntGraphicsCheck(TRUE))
{
if (!calledFromUser){
UserLeave();
}
DPRINT1("Unable to initialize graphics, returning NULL dc\n");
return NULL;
}
if (!calledFromUser){
UserLeave();
}
}
}
/* Check for existing DC object */
if ((hNewDC = DC_FindOpenDC(Driver)) != NULL)
{
hDC = hNewDC;
return NtGdiCreateCompatibleDC(hDC);
}
if (Driver != NULL && Driver->Buffer != NULL)
{
if (Driver!=NULL)
DPRINT1("NAME: %wZ\n", Driver);
}
/* Allocate a DC object */
if ((hNewDC = DC_AllocDC(Driver)) == NULL)
{
return NULL;
}
NewDC = DC_LockDc( hNewDC );
/* FIXME - NewDC can be NULL!!! Don't assert here! */
if ( !NewDC )
{
DC_FreeDC( hNewDC );
return NULL;
}
NewDC->IsIC = CreateAsIC;
NewDC->DevInfo = &PrimarySurface.DevInfo;
NewDC->GDIInfo = &PrimarySurface.GDIInfo;
memcpy(NewDC->FillPatternSurfaces, PrimarySurface.FillPatterns,
sizeof(NewDC->FillPatternSurfaces));
NewDC->PDev = PrimarySurface.PDev;
NewDC->GDIDevice = (HDEV)&PrimarySurface;
NewDC->DriverFunctions = PrimarySurface.DriverFunctions;
NewDC->w.hBitmap = PrimarySurface.Handle;
NewDC->w.bitsPerPixel = NewDC->GDIInfo->cBitsPixel * NewDC->GDIInfo->cPlanes;
DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
if (! CreateAsIC)
{
NewDC->PalIndexed = NtGdiGetStockObject(DEFAULT_PALETTE);
NewDC->w.hPalette = NewDC->DevInfo->hpalDefault;
NewDC->w.ROPmode = R2_COPYPEN;
DC_UnlockDc( NewDC );
hVisRgn = NtGdiCreateRectRgn(0, 0, NewDC->GDIInfo->ulHorzRes,
NewDC->GDIInfo->ulVertRes);
NtGdiSelectVisRgn(hNewDC, hVisRgn);
NtGdiDeleteObject(hVisRgn);
/* Initialize the DC state */
DC_InitDC(hNewDC);
NtGdiSetTextColor(hNewDC, RGB(0, 0, 0));
NtGdiSetTextAlign(hNewDC, TA_TOP);
NtGdiSetBkColor(hNewDC, RGB(255, 255, 255));
NtGdiSetBkMode(hNewDC, OPAQUE);
}
else
{
DC_UnlockDc( NewDC );
}
return hNewDC;
}
HDC STDCALL
NtGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
CONST PDEVMODEW InitData)
{
UNICODE_STRING SafeDriver, SafeDevice;
DEVMODEW SafeInitData;
HDC Ret;
NTSTATUS Status = STATUS_SUCCESS;
if(InitData)
{
_SEH_TRY
{
ProbeForRead(InitData,
sizeof(DEVMODEW),
1);
RtlCopyMemory(&SafeInitData,
InitData,
sizeof(DEVMODEW));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return NULL;
}
/* FIXME - InitData can have some more bytes! */
}
if(Driver)
{
Status = IntSafeCopyUnicodeString(&SafeDriver, Driver);
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return NULL;
}
}
if(Device)
{
Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
if(!NT_SUCCESS(Status))
{
/* FIXME workaround for a real bug */
// RtlFreeUnicodeString(&SafeDriver);
// SetLastNtError(Status);
// DPRINT1("fail3\n");
// return NULL;
Device = NULL;
}
}
Ret = IntGdiCreateDC(NULL == Driver ? NULL : &SafeDriver,
NULL == Device ? NULL : &SafeDevice, NULL,
NULL == InitData ? NULL : &SafeInitData, FALSE);
return Ret;
}
HDC STDCALL
NtGdiCreateIC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
CONST PDEVMODEW InitData)
{
UNICODE_STRING SafeDriver, SafeDevice;
DEVMODEW SafeInitData;
HDC Ret;
NTSTATUS Status = STATUS_SUCCESS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -