* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: dc.c,v 1.149 2004/12/12 01:40:38 weiden Exp $
+/* $Id$
*
* DC.C - Device context functions
*
*/
+
#include <w32k.h>
+#define NDEBUG
+#include <debug.h>
+
#ifndef OBJ_COLORSPACE
#define OBJ_COLORSPACE (14)
#endif
return 0; \
} \
ft = dc->dc_field; \
- DC_UnlockDc( hdc ); \
+ DC_UnlockDc(dc); \
return ft; \
}
} \
BOOL STDCALL NtGdi##FuncName ( HDC hdc, LP##type pt ) \
{ \
- NTSTATUS Status; \
+ NTSTATUS Status = STATUS_SUCCESS; \
type Safept; \
PDC dc; \
if(!pt) \
return FALSE; \
} \
Int##FuncName( dc, &Safept); \
- DC_UnlockDc(hdc); \
- Status = MmCopyToCaller(pt, &Safept, sizeof( type )); \
+ DC_UnlockDc(dc); \
+ _SEH_TRY \
+ { \
+ ProbeForWrite(pt, \
+ sizeof( type ), \
+ 1); \
+ *pt = Safept; \
+ } \
+ _SEH_HANDLE \
+ { \
+ Status = _SEH_GetExceptionCode(); \
+ } \
+ _SEH_END; \
if(!NT_SUCCESS(Status)) \
{ \
SetLastNtError(Status); \
} \
prevMode = dc->dc_field; \
dc->dc_field = mode; \
- DC_UnlockDc ( hdc ); \
+ DC_UnlockDc ( dc ); \
return prevMode; \
}
}
HDC STDCALL
-NtGdiCreateCompatableDC(HDC hDC)
+NtGdiCreateCompatibleDC(HDC hDC)
{
PDC NewDC, OrigDC;
HBITMAP hBitmap;
if (hDC == NULL)
{
RtlInitUnicodeString(&DriverName, L"DISPLAY");
- DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL);
+ DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE);
if (NULL == DisplayDC)
{
return NULL;
if (NULL == hNewDC)
{
- DC_UnlockDc(hDC);
+ DC_UnlockDc(OrigDC);
if (NULL != DisplayDC)
{
NtGdiDeleteDC(DisplayDC);
/* Copy information from original DC to new DC */
NewDC->hSelf = hNewDC;
+ NewDC->IsIC = FALSE;
NewDC->PDev = OrigDC->PDev;
- NewDC->DMW = OrigDC->DMW;
memcpy(NewDC->FillPatternSurfaces,
OrigDC->FillPatternSurfaces,
sizeof OrigDC->FillPatternSurfaces);
/* Create default bitmap */
if (!(hBitmap = NtGdiCreateBitmap( 1, 1, 1, NewDC->w.bitsPerPixel, NULL )))
{
- DC_UnlockDc( hDC );
- DC_UnlockDc( hNewDC );
+ DC_UnlockDc( OrigDC );
+ DC_UnlockDc( NewDC );
DC_FreeDC( hNewDC );
if (NULL != DisplayDC)
{
NewDC->w.textAlign = OrigDC->w.textAlign;
NewDC->w.backgroundColor = OrigDC->w.backgroundColor;
NewDC->w.backgroundMode = OrigDC->w.backgroundMode;
- DC_UnlockDc( hDC );
+ NewDC->w.ROPmode = OrigDC->w.ROPmode;
+ DC_UnlockDc(NewDC);
+ DC_UnlockDc(OrigDC);
if (NULL != DisplayDC)
{
NtGdiDeleteDC(DisplayDC);
}
- DC_UnlockDc(hNewDC);
hVisRgn = NtGdiCreateRectRgn(0, 0, 1, 1);
NtGdiSelectVisRgn(hNewDC, hVisRgn);
if (Valid)
{
ProfilePath = ExAllocatePoolWithTag(PagedPool,
- (wcslen(RegistryPath.Buffer) +
+ (wcslen(RegistryPath.Buffer) +
wcslen(Insert) + 1) * sizeof(WCHAR),
TAG_DC);
if (NULL != ProfilePath)
return Valid;
}
-BOOL FASTCALL
-IntCreatePrimarySurface()
+static BOOL FASTCALL
+IntPrepareDriver()
{
PGD_ENABLEDRIVER GDEnableDriver;
DRVENABLEDATA DED;
- SURFOBJ *SurfObj;
- SIZEL SurfSize;
UNICODE_STRING DriverFileNames;
PWSTR CurrentName;
BOOL GotDriver;
BOOL DoDefault;
ULONG DisplayNumber;
- RECTL SurfaceRect;
for (DisplayNumber = 0; ; DisplayNumber++)
{
if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
{
DPRINT1("FindDriverFileNames failed\n");
- /* return FALSE; */
continue;
}
{
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("No suitable DDI driver found\n");
- /* return FALSE; */
continue;
}
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("DrvEnablePDEV with default parameters failed\n");
DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
- /* return FALSE; */
continue;
}
}
PrimarySurface.GDIInfo.ulLogPixelsY = 96;
}
+ PrimarySurface.Pointer.Exclude.right = -1;
+
DPRINT("calling completePDev\n");
/* Complete initialization of the physical device */
DRIVER_ReferenceDriver(L"DISPLAY");
- DPRINT("calling EnableSurface\n");
+ PrimarySurface.PreparedDriver = TRUE;
+ PrimarySurface.DisplayNumber = DisplayNumber;
- /* 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; */
- continue;
- }
+ return TRUE;
+ }
- /* attach monitor */
- IntAttachMonitor(&PrimarySurface, DisplayNumber);
-
- SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
- SurfObj->dhpdev = PrimarySurface.PDev;
- SurfSize = SurfObj->sizlBitmap;
- SurfSize = SurfObj->sizlBitmap;
- SurfaceRect.left = SurfaceRect.top = 0;
- SurfaceRect.right = SurfObj->sizlBitmap.cx;
- SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
- EngEraseSurface(SurfObj, &SurfaceRect, 0);
- EngUnlockSurface(SurfObj);
- IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
- break;
+ return FALSE;
+}
+
+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.
PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);
PrimarySurface.DriverFunctions.DisableSurface(PrimarySurface.PDev);
PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
+ PrimarySurface.PreparedDriver = FALSE;
DceEmptyCache();
IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
- CONST PDEVMODEW InitData)
+ CONST PDEVMODEW InitData,
+ BOOL CreateAsIC)
{
HDC hNewDC;
PDC NewDC;
HDC hDC = NULL;
- SURFOBJ *SurfObj;
HRGN hVisRgn;
UNICODE_STRING StdDriver;
+ BOOL calledFromUser;
RtlInitUnicodeString(&StdDriver, L"DISPLAY");
-
+
if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
{
- if (! IntGraphicsCheck(TRUE))
+ if (CreateAsIC)
{
- DPRINT1("Unable to initialize graphics, returning NULL dc\n");
- return NULL;
+ 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();
+ }
+
}
}
if ((hNewDC = DC_FindOpenDC(Driver)) != NULL)
{
hDC = hNewDC;
- return NtGdiCreateCompatableDC(hDC);
+ return NtGdiCreateCompatibleDC(hDC);
}
if (Driver != NULL && Driver->Buffer != NULL)
{
- DPRINT("NAME: %S\n", Driver->Buffer); // FIXME: Should not crash if NULL
+ DPRINT("NAME: %wZ\n", Driver); // FIXME: Should not crash if NULL
}
/* Allocate a DC object */
NewDC = DC_LockDc( hNewDC );
/* FIXME - NewDC can be NULL!!! Don't assert here! */
- ASSERT( NewDC );
+ if ( !NewDC )
+ {
+ DC_FreeDC( hNewDC );
+ return NULL;
+ }
- NewDC->DMW = PrimarySurface.DMW;
+ NewDC->IsIC = CreateAsIC;
NewDC->DevInfo = &PrimarySurface.DevInfo;
NewDC->GDIInfo = &PrimarySurface.GDIInfo;
memcpy(NewDC->FillPatternSurfaces, PrimarySurface.FillPatterns,
NewDC->DriverFunctions = PrimarySurface.DriverFunctions;
NewDC->w.hBitmap = PrimarySurface.Handle;
- NewDC->DMW.dmSize = sizeof(NewDC->DMW);
- NewDC->DMW.dmFields = 0x000fc000;
-
- /* FIXME: get mode selection information from somewhere */
-
- NewDC->DMW.dmLogPixels = 96;
- SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
- NewDC->DMW.dmBitsPerPel = BitsPerFormat(SurfObj->iBitmapFormat);
- NewDC->DMW.dmPelsWidth = SurfObj->sizlBitmap.cx;
- NewDC->DMW.dmPelsHeight = SurfObj->sizlBitmap.cy;
- NewDC->DMW.dmDisplayFlags = 0;
- NewDC->DMW.dmDisplayFrequency = 0;
-
- NewDC->w.bitsPerPixel = NewDC->DMW.dmBitsPerPel; // FIXME: set this here??
-
- NewDC->w.hPalette = NewDC->DevInfo->hpalDefault;
-
+ NewDC->w.bitsPerPixel = NewDC->GDIInfo->cBitsPixel * NewDC->GDIInfo->cPlanes;
DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
-
- DC_UnlockDc( hNewDC );
- hVisRgn = NtGdiCreateRectRgn(0, 0, SurfObj->sizlBitmap.cx,
- SurfObj->sizlBitmap.cy);
- 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);
+ if (! CreateAsIC)
+ {
+ 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 );
+ }
- EngUnlockSurface(SurfObj);
-
return hNewDC;
}
UNICODE_STRING SafeDriver, SafeDevice;
DEVMODEW SafeInitData;
HDC Ret;
- NTSTATUS Status;
-
+ NTSTATUS Status = STATUS_SUCCESS;
+
if(InitData)
{
- Status = MmCopyFromCaller(&SafeInitData, InitData, sizeof(DEVMODEW));
+ _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);
}
/* FIXME - InitData can have some more bytes! */
}
-
+
if(Driver)
{
Status = IntSafeCopyUnicodeString(&SafeDriver, Driver);
return NULL;
}
}
-
+
if(Device)
{
Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
return NULL;
}
}
-
- Ret = IntGdiCreateDC(&SafeDriver, &SafeDevice, NULL, &SafeInitData);
-
+
+ Ret = IntGdiCreateDC(NULL == Driver ? NULL : &SafeDriver,
+ NULL == Device ? NULL : &SafeDevice, NULL,
+ NULL == InitData ? NULL : &SafeInitData, FALSE);
+
return Ret;
}
NtGdiCreateIC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
- CONST PDEVMODEW DevMode)
+ CONST PDEVMODEW InitData)
{
- /* FIXME: this should probably do something else... */
- return NtGdiCreateDC(Driver, Device, Output, DevMode);
+ 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))
+ {
+ RtlFreeUnicodeString(&SafeDriver);
+ SetLastNtError(Status);
+ return NULL;
+ }
+ }
+
+ Ret = IntGdiCreateDC(NULL == Driver ? NULL : &SafeDriver,
+ NULL == Device ? NULL : &SafeDevice, NULL,
+ NULL == InitData ? NULL : &SafeInitData, TRUE);
+
+ return Ret;
}
BOOL STDCALL
{
PDC DCToDelete;
+ if (!GDIOBJ_OwnedByCurrentProcess(DCHandle))
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
DCToDelete = DC_LockDc(DCHandle);
if (DCToDelete == NULL)
{
- return FALSE;
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
}
/* First delete all saved DCs */
}
DC_SetNextDC (DCToDelete, DC_GetNextDC (savedDC));
DCToDelete->saveLevel--;
- DC_UnlockDc( savedHDC );
+ DC_UnlockDc( savedDC );
NtGdiDeleteDC (savedHDC);
}
#if 0 /* FIXME */
PATH_DestroyGdiPath (&DCToDelete->w.path);
#endif
- DC_UnlockDc( DCHandle );
+ DC_UnlockDc( DCToDelete );
DC_FreeDC ( DCHandle );
return TRUE;
{
HGDIOBJ SelObject;
DC *dc;
-
+
if(!(dc = DC_LockDc(hDC)))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
-
+
switch(ObjectType)
{
case OBJ_PEN:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
break;
}
-
- DC_UnlockDc(hDC);
+
+ DC_UnlockDc(dc);
return SelObject;
}
{
Point->x = dc->w.DCOrgX;
Point->y = dc->w.DCOrgY;
-
+
return TRUE;
}
BOOL Ret;
DC *dc;
POINT SafePoint;
- NTSTATUS Status;
-
+ NTSTATUS Status = STATUS_SUCCESS;
+
if(!Point)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
-
+
dc = DC_LockDc(hDC);
if(!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
-
+
Ret = IntGdiGetDCOrgEx(dc, &SafePoint);
-
- Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT));
+
+ _SEH_TRY
+ {
+ ProbeForWrite(Point,
+ sizeof(POINT),
+ 1);
+ *Point = SafePoint;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return FALSE;
}
-
- DC_UnlockDc(hDC);
+
+ DC_UnlockDc(dc);
return Ret;
}
oldColor = dc->w.backgroundColor;
dc->w.backgroundColor = color;
hBrush = dc->w.hBrush;
- DC_UnlockDc ( hDC );
+ DC_UnlockDc(dc);
NtGdiSelectObject(hDC, hBrush);
return oldColor;
}
hnewdc = DC_AllocDC(NULL);
if (hnewdc == NULL)
{
- DC_UnlockDc( hDC );
+ DC_UnlockDc(dc);
return 0;
}
newdc = DC_LockDc( hnewdc );
newdc->hSelf = hnewdc;
newdc->saveLevel = 0;
+ newdc->IsIC = dc->IsIC;
#if 0
PATH_InitGdiPath( &newdc->w.path );
newdc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
NtGdiCombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
}
- DC_UnlockDc( hnewdc );
- DC_UnlockDc( hDC );
+ DC_UnlockDc( newdc );
+ DC_UnlockDc( dc );
return hnewdc;
}
res = CLIPPING_UpdateGCRegion( dc );
ASSERT ( res != ERROR );
}
- DC_UnlockDc ( hDC );
+ DC_UnlockDc ( dc );
#else
- DC_UnlockDc ( hDC );
+ DC_UnlockDc ( dc );
NtGdiSelectClipRgn(hDC, dcs->w.hClipRgn);
#endif
GDISelectPalette16( hDC, dcs->w.hPalette, FALSE );
#endif
} else {
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
}
- DC_UnlockDc ( hDCSave );
+ DC_UnlockDc ( dcs );
} else {
- DC_UnlockDc ( hDC );
+ DC_UnlockDc ( dc );
SetLastWin32Error(ERROR_INVALID_HANDLE);
}
}
SetLastWin32Error(ERROR_INVALID_HANDLE);
}
-INT STDCALL
-NtGdiGetDeviceCaps(HDC hDC,
- INT Index)
+INT FASTCALL
+IntGdiGetDeviceCaps(PDC dc, INT Index)
{
- PDC dc;
- INT ret;
+ INT ret = 0;
POINT pt;
- dc = DC_LockDc(hDC);
- if (dc == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
/* Retrieve capability */
switch (Index)
{
break;
case PHYSICALWIDTH:
- if(NtGdiEscape(hDC, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.x;
}
break;
case PHYSICALHEIGHT:
- if(NtGdiEscape(hDC, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.y;
}
break;
case PHYSICALOFFSETX:
- if(NtGdiEscape(hDC, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.x;
}
break;
case PHYSICALOFFSETY:
- if(NtGdiEscape(hDC, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.y;
}
break;
case SCALINGFACTORX:
- if(NtGdiEscape(hDC, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.x;
}
break;
case SCALINGFACTORY:
- if(NtGdiEscape(hDC, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
+ if(IntGdiEscape(dc, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
{
ret = pt.y;
}
break;
}
+ return ret;
+}
+
+INT STDCALL
+NtGdiGetDeviceCaps(HDC hDC,
+ INT Index)
+{
+ PDC dc;
+ INT ret;
+
+ dc = DC_LockDc(hDC);
+ if (dc == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ ret = IntGdiGetDeviceCaps(dc, Index);
+
DPRINT("(%04x,%d): returning %d\n", hDC, Index, ret);
- DC_UnlockDc( hDC );
+ DC_UnlockDc( dc );
return ret;
}
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
-
+
ObjectType = GDIOBJ_GetObjectType(Handle);
switch (ObjectType)
{
break;
}
- GDIOBJ_UnlockObj(Handle);
+ GDIOBJ_UnlockObjByPtr(GdiObject);
return Result;
}
{
INT Ret;
LPVOID SafeBuf;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
if (count <= 0)
{
return 0;
}
+ _SEH_TRY
+ {
+ ProbeForWrite(buffer,
+ count,
+ 1);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return 0;
+ }
+
SafeBuf = ExAllocatePoolWithTag(PagedPool, count, TAG_GDIOBJ);
if(!SafeBuf)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
-
+
Ret = IntGdiGetObject(handle, count, SafeBuf);
-
- Status = MmCopyToCaller(buffer, SafeBuf, count);
+
+ _SEH_TRY
+ {
+ /* pointer already probed! */
+ RtlCopyMemory(buffer,
+ SafeBuf,
+ count);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
ExFreePool(SafeBuf);
if(!NT_SUCCESS(Status))
{
result = 0;
break;
}
- GDIOBJ_UnlockObj(handle);
+ GDIOBJ_UnlockObjByPtr(ptr);
return result;
}
if ((SaveLevel < 1) || (SaveLevel > dc->saveLevel))
{
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return FALSE;
}
dcs = DC_LockDc (hdcs);
if (dcs == NULL)
{
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return FALSE;
}
DC_SetNextDC (dcs, DC_GetNextDC (dcs));
if (--dc->saveLevel < SaveLevel)
{
- DC_UnlockDc( hDC );
- DC_UnlockDc( hdcs );
+ DC_UnlockDc( dc );
+ DC_UnlockDc( dcs );
NtGdiSetDCState(hDC, hdcs);
#if 0
if (!PATH_AssignGdiPath( &dc->w.path, &dcs->w.path ))
}
else
{
- DC_UnlockDc( hdcs );
+ DC_UnlockDc( dcs );
}
NtGdiDeleteDC (hdcs);
}
- DC_UnlockDc( hDC );
+ DC_UnlockDc( dc );
return success;
}
dc = DC_LockDc (hDC);
if (dc == NULL)
{
- DC_UnlockDc(hdcs);
+ DC_UnlockDc(dcs);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
DC_SetNextDC (dcs, DC_GetNextDC (dc));
DC_SetNextDC (dc, hdcs);
ret = ++dc->saveLevel;
- DC_UnlockDc( hdcs );
- DC_UnlockDc( hDC );
+ DC_UnlockDc( dcs );
+ DC_UnlockDc( dc );
return ret;
}
PGDIBRUSHOBJ brush;
XLATEOBJ *XlateObj;
DWORD objectType;
- ULONG NumColors = 0;
HRGN hVisRgn;
BOOLEAN Failed;
if(!hDC || !hGDIObj) return NULL;
-
+
dc = DC_LockDc(hDC);
if (NULL == dc)
{
}
XlateObj = IntGdiCreateBrushXlate(dc, pen, &Failed);
- PENOBJ_UnlockPen(hGDIObj);
+ PENOBJ_UnlockPen(pen);
if (Failed)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
}
XlateObj = IntGdiCreateBrushXlate(dc, brush, &Failed);
- BRUSHOBJ_UnlockBrush(hGDIObj);
+ BRUSHOBJ_UnlockBrush(brush);
if (Failed)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
// must be memory dc to select bitmap
if (!(dc->w.flags & DC_MEMORY))
{
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return NULL;
}
pb = BITMAPOBJ_LockBitmap(hGDIObj);
if (NULL == pb)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return NULL;
}
objOrg = (HGDIOBJ)dc->w.hBitmap;
if(pb->dib)
{
dc->w.bitsPerPixel = pb->dib->dsBmih.biBitCount;
-
- if(pb->dib->dsBmih.biBitCount <= 8)
- {
- if(pb->dib->dsBmih.biBitCount == 1) { NumColors = 2; } else
- if(pb->dib->dsBmih.biBitCount == 4) { NumColors = 16; } else
- if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; }
- dc->w.hPalette = PALETTE_AllocPaletteIndexedRGB(NumColors, pb->ColorMap);
- }
- else
- {
- dc->w.hPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
- pb->dib->dsBitfields[0],
- pb->dib->dsBitfields[1],
- pb->dib->dsBitfields[2]);
- }
+ dc->w.hPalette = pb->hDIBPalette;
}
else
{
NtGdiSelectObject ( hDC, dc->w.hBrush );
NtGdiSelectObject ( hDC, dc->w.hPen );
- DC_UnlockDc ( hDC );
+ DC_UnlockDc ( dc );
hVisRgn = NtGdiCreateRectRgn ( 0, 0, pb->SurfObj.sizlBitmap.cx, pb->SurfObj.sizlBitmap.cy );
- BITMAPOBJ_UnlockBitmap( hGDIObj );
+ BITMAPOBJ_UnlockBitmap( pb );
NtGdiSelectVisRgn ( hDC, hVisRgn );
NtGdiDeleteObject ( hVisRgn );
return objOrg;
case GDI_OBJECT_TYPE_REGION:
- DC_UnlockDc (hDC);
+ DC_UnlockDc (dc);
/*
* The return value is one of the following values:
* SIMPLEREGION
default:
break;
}
- DC_UnlockDc( hDC );
+ DC_UnlockDc( dc );
return objOrg;
}
dc->w.flags &= ~DC_DIRTY;
}
- DC_UnlockDc(hDC);
+ DC_UnlockDc(dc);
return wRet;
}
PDC NewDC;
HDC hDC;
PWSTR Buf = NULL;
-
+
if (Driver != NULL)
{
Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
NewDC = DC_LockDc(hDC);
/* FIXME - Handle NewDC == NULL! */
-
+
if (Driver != NULL)
{
RtlCopyMemory(&NewDC->DriverName, Driver, sizeof(UNICODE_STRING));
NewDC->w.hPalette = NtGdiGetStockObject(DEFAULT_PALETTE);
- DC_UnlockDc(hDC);
+ DC_UnlockDc(NewDC);
return hDC;
}
{
GDIOBJ_CopyOwnership(hDC, DC->w.hGCClipRgn);
}
- DC_UnlockDc(hDC);
+ DC_UnlockDc(DC);
}
}
/*! \brief Enumerate possible display settings for the given display...
*
* \todo Make thread safe!?
- * \todo Don't ignore lpszDeviceName
+ * \todo Don't ignore pDeviceName
* \todo Implement non-raw mode (only return settings valid for driver and monitor)
*/
BOOL FASTCALL
IntEnumDisplaySettings(
- PUNICODE_STRING lpszDeviceName,
- DWORD iModeNum,
- LPDEVMODEW lpDevMode,
- DWORD dwFlags)
+ IN PUNICODE_STRING pDeviceName OPTIONAL,
+ IN DWORD iModeNum,
+ IN OUT LPDEVMODEW pDevMode,
+ IN DWORD dwFlags)
{
static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
static DWORD SizeOfCachedDevModes = 0;
- LPDEVMODEW CachedMode = NULL;
+ PDEVMODEW CachedMode = NULL;
DEVMODEW DevMode;
INT Size, OldSize;
ULONG DisplayNumber = 0; /* only default display supported */
-
- if (lpDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
- lpDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
- lpDevMode->dmSize != SIZEOF_DEVMODEW_500)
+
+ DPRINT("DevMode->dmSize = %d\n", pDevMode->dmSize);
+ DPRINT("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra);
+ if (pDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
+ pDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
+ pDevMode->dmSize != SIZEOF_DEVMODEW_500)
{
SetLastWin32Error(STATUS_INVALID_PARAMETER);
return FALSE;
if (iModeNum == ENUM_CURRENT_SETTINGS)
{
- CachedMode = &PrimarySurface.DMW;
- assert(CachedMode->dmSize > 0);
+ CachedMode = &PrimarySurface.DMW;
+ ASSERT(CachedMode->dmSize > 0);
}
else if (iModeNum == ENUM_REGISTRY_SETTINGS)
{
{
if (iModeNum == 0 || CachedDevModes == NULL) /* query modes from drivers */
{
+ BOOL PrimarySurfaceCreated = FALSE;
UNICODE_STRING DriverFileNames;
LPWSTR CurrentName;
DRVENABLEDATA DrvEnableData;
-
+
/* Retrieve DDI driver names from registry */
RtlInitUnicodeString(&DriverFileNames, NULL);
if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
DPRINT1("FindDriverFileNames failed\n");
return FALSE;
}
-
+
+ if (!HalQueryDisplayOwnership())
+ {
+ IntCreatePrimarySurface();
+ PrimarySurfaceCreated = TRUE;
+ }
+
/*
* DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
* scan all of them until a good one found.
{
INT i;
PGD_ENABLEDRIVER GDEnableDriver;
-
+
/* Get the DDI driver's entry point */
GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
if (NULL == GDEnableDriver)
DPRINT("FindDDIDriver failed for %S\n", CurrentName);
continue;
}
-
+
/* Call DDI driver's EnableDriver function */
RtlZeroMemory(&DrvEnableData, sizeof (DrvEnableData));
-
+
if (!GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof (DrvEnableData), &DrvEnableData))
{
DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
continue;
}
-
+
CachedDevModesEnd = CachedDevModes;
-
+
/* find DrvGetModes function */
for (i = 0; i < DrvEnableData.c; i++)
{
PDRVFN DrvFn = DrvEnableData.pdrvfn + i;
PGD_GETMODES GetModes;
INT SizeNeeded, SizeUsed;
-
+
if (DrvFn->iFunc != INDEX_DrvGetModes)
continue;
-
+
GetModes = (PGD_GETMODES)DrvFn->pfn;
-
+
/* make sure we have enough memory to hold the modes */
SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject), 0, NULL);
if (SizeNeeded <= 0)
DPRINT("DrvGetModes failed for %S\n", CurrentName);
break;
}
-
+
SizeUsed = CachedDevModesEnd - CachedDevModes;
if (SizeOfCachedDevModes - SizeUsed < SizeNeeded)
{
PVOID NewBuffer;
-
+
SizeOfCachedDevModes += SizeNeeded;
NewBuffer = ExAllocatePool(PagedPool, SizeOfCachedDevModes);
if (NewBuffer == NULL)
SizeOfCachedDevModes = 0;
CachedDevModes = NULL;
CachedDevModesEnd = NULL;
+ if (PrimarySurfaceCreated)
+ {
+ IntDestroyPrimarySurface();
+ }
SetLastWin32Error(STATUS_NO_MEMORY);
return FALSE;
}
CachedDevModes = NewBuffer;
CachedDevModesEnd = (DEVMODEW *)((PCHAR)NewBuffer + SizeUsed);
}
-
+
/* query modes */
SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject),
SizeOfCachedDevModes - SizeUsed,
break;
}
}
-
+
+ if (PrimarySurfaceCreated)
+ {
+ IntDestroyPrimarySurface();
+ }
+
RtlFreeUnicodeString(&DriverFileNames);
}
}
}
- assert(CachedMode != NULL);
+ ASSERT(CachedMode != NULL);
- Size = OldSize = lpDevMode->dmSize;
+ Size = OldSize = pDevMode->dmSize;
if (Size > CachedMode->dmSize)
Size = CachedMode->dmSize;
- RtlCopyMemory(lpDevMode, CachedMode, Size);
- RtlZeroMemory((PCHAR)lpDevMode + Size, OldSize - Size);
- lpDevMode->dmSize = OldSize;
-
- Size = OldSize = lpDevMode->dmDriverExtra;
+ RtlCopyMemory(pDevMode, CachedMode, Size);
+ RtlZeroMemory((PCHAR)pDevMode + Size, OldSize - Size);
+ pDevMode->dmSize = OldSize;
+
+ Size = OldSize = pDevMode->dmDriverExtra;
if (Size > CachedMode->dmDriverExtra)
Size = CachedMode->dmDriverExtra;
- RtlCopyMemory((PCHAR)lpDevMode + lpDevMode->dmSize,
+ RtlCopyMemory((PCHAR)pDevMode + pDevMode->dmSize,
(PCHAR)CachedMode + CachedMode->dmSize, Size);
- RtlZeroMemory((PCHAR)lpDevMode + lpDevMode->dmSize + Size, OldSize - Size);
- lpDevMode->dmDriverExtra = OldSize;
+ RtlZeroMemory((PCHAR)pDevMode + pDevMode->dmSize + Size, OldSize - Size);
+ pDevMode->dmDriverExtra = OldSize;
return TRUE;
}
+LONG
+FASTCALL
+IntChangeDisplaySettings(
+ IN PUNICODE_STRING pDeviceName OPTIONAL,
+ IN LPDEVMODEW DevMode,
+ IN DWORD dwflags,
+ IN PVOID lParam OPTIONAL)
+{
+ BOOLEAN Global = FALSE;
+ BOOLEAN NoReset = FALSE;
+ BOOLEAN Reset = FALSE;
+ BOOLEAN SetPrimary = FALSE;
+ LONG Ret=0;
+ NTSTATUS Status ;
+
+ DPRINT1("display flag : %x\n",dwflags);
+
+ if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
+ {
+ /* Check global, reset and noreset flags */
+ if ((dwflags & CDS_GLOBAL) == CDS_GLOBAL)
+ Global = TRUE;
+ if ((dwflags & CDS_NORESET) == CDS_NORESET)
+ NoReset = TRUE;
+ dwflags &= ~(CDS_GLOBAL | CDS_NORESET);
+ }
+ if ((dwflags & CDS_RESET) == CDS_RESET)
+ Reset = TRUE;
+ if ((dwflags & CDS_SET_PRIMARY) == CDS_SET_PRIMARY)
+ SetPrimary = TRUE;
+ dwflags &= ~(CDS_RESET | CDS_SET_PRIMARY);
+
+ if (Reset && NoReset)
+ return DISP_CHANGE_BADFLAGS;
+
+ if (dwflags == 0)
+ {
+ /* Dynamically change graphics mode */
+ DPRINT1("flag 0 UNIMPLEMENT \n");
+ return DISP_CHANGE_FAILED;
+ }
+
+ if ((dwflags & CDS_TEST) == CDS_TEST)
+ {
+ /* Test reslution */
+ dwflags &= ~CDS_TEST;
+ DPRINT1("flag CDS_TEST UNIMPLEMENT");
+ Ret = DISP_CHANGE_FAILED;
+ }
+
+ if ((dwflags & CDS_FULLSCREEN) == CDS_FULLSCREEN)
+ {
+ DEVMODE lpDevMode;
+ /* Full Screen */
+ dwflags &= ~CDS_FULLSCREEN;
+ DPRINT1("flag CDS_FULLSCREEN partially implemented");
+ Ret = DISP_CHANGE_FAILED;
+
+ lpDevMode.dmBitsPerPel =0;
+ lpDevMode.dmPelsWidth =0;
+ lpDevMode.dmPelsHeight =0;
+ lpDevMode.dmDriverExtra =0;
+
+ lpDevMode.dmSize = sizeof(DEVMODE);
+ Status = IntEnumDisplaySettings(pDeviceName, ENUM_CURRENT_SETTINGS, &lpDevMode, 0);
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+
+ DPRINT1("Req Mode : %d x %d x %d\n", DevMode->dmPelsWidth,DevMode->dmPelsHeight,DevMode->dmBitsPerPel);
+ DPRINT1("Current Mode : %d x %d x %d\n", lpDevMode.dmPelsWidth,lpDevMode.dmPelsHeight, lpDevMode.dmBitsPerPel);
+
+
+ if ((lpDevMode.dmBitsPerPel == DevMode->dmBitsPerPel) &&
+ (lpDevMode.dmPelsWidth == DevMode->dmPelsWidth) &&
+ (lpDevMode.dmPelsHeight == DevMode->dmPelsHeight))
+ Ret = DISP_CHANGE_SUCCESSFUL;
+ }
+
+ if ((dwflags & CDS_VIDEOPARAMETERS) == CDS_VIDEOPARAMETERS)
+ {
+ dwflags &= ~CDS_VIDEOPARAMETERS;
+ if (lParam == NULL) Ret=DISP_CHANGE_BADPARAM;
+ else
+ {
+ DPRINT1("flag CDS_VIDEOPARAMETERS UNIMPLEMENT");
+ Ret = DISP_CHANGE_FAILED;
+ }
+
+ }
+
+ if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
+ {
+
+ UNICODE_STRING ObjectName;
+ UNICODE_STRING KernelModeName;
+ WCHAR KernelModeNameBuffer[256];
+ UNICODE_STRING RegistryKey;
+ WCHAR RegistryKeyBuffer[512];
+ PDEVICE_OBJECT DeviceObject;
+ ULONG LastSlash;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE DevInstRegKey;
+ ULONG NewValue;
+
+
+ DPRINT1("set CDS_UPDATEREGISTRY \n");
+
+ dwflags &= ~CDS_UPDATEREGISTRY;
+
+ /* Get device name (pDeviceName is "\.\xxx") */
+ for (LastSlash = pDeviceName->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
+ {
+ if (pDeviceName->Buffer[LastSlash - 1] == L'\\')
+ break;
+ }
+
+ if (LastSlash == 0) return DISP_CHANGE_RESTART;
+ ObjectName = *pDeviceName;
+ ObjectName.Length -= LastSlash * sizeof(WCHAR);
+ ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
+ ObjectName.Buffer += LastSlash;
+
+ KernelModeName.Length = 0;
+ KernelModeName.MaximumLength = sizeof(KernelModeNameBuffer);
+ KernelModeName.Buffer = KernelModeNameBuffer;
+
+ /* Open \??\xxx (ex: "\??\DISPLAY1") */
+ Status = RtlAppendUnicodeToString(&KernelModeName, L"\\??\\");
+
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+ Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
+
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+ Status = ObReferenceObjectByName(
+ &KernelModeName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ 0,
+ IoDeviceObjectType,
+ KernelMode,
+ NULL,
+ (PVOID*)&DeviceObject);
+
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+ /* Get associated driver name (ex: "VBE") */
+ for (LastSlash = DeviceObject->DriverObject->DriverName.Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
+ {
+ if (DeviceObject->DriverObject->DriverName.Buffer[LastSlash - 1] == L'\\')
+ break;
+ }
+
+ if (LastSlash == 0) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+ ObjectName = DeviceObject->DriverObject->DriverName;
+ ObjectName.Length -= LastSlash * sizeof(WCHAR);
+ ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
+ ObjectName.Buffer += LastSlash;
+
+ RegistryKey.Length = 0;
+ RegistryKey.MaximumLength = sizeof(RegistryKeyBuffer);
+ RegistryKey.Buffer = RegistryKeyBuffer;
+
+ /* Open registry key */
+ Status = RtlAppendUnicodeToString(&RegistryKey,
+ L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\");
+
+ if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+ Status = RtlAppendUnicodeStringToString(&RegistryKey, &ObjectName);
+
+ if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+ Status = RtlAppendUnicodeToString(&RegistryKey,
+ L"\\Device0");
+
+ if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+
+ InitializeObjectAttributes(&ObjectAttributes, &RegistryKey,
+ OBJ_CASE_INSENSITIVE, NULL, NULL);
+ Status = ZwOpenKey(&DevInstRegKey, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes);
+ ObDereferenceObject(DeviceObject);
+ if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+
+ /* Update needed fields */
+ if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL)
+ {
+ RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.BitsPerPel");
+ NewValue = DevMode->dmBitsPerPel;
+ Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
+ }
+
+ if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSWIDTH)
+ {
+ RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.XResolution");
+ NewValue = DevMode->dmPelsWidth;
+ Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
+ }
+
+ if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSHEIGHT)
+ {
+ RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.YResolution");
+ NewValue = DevMode->dmPelsHeight;
+ Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
+ }
+
+ ZwClose(DevInstRegKey);
+ if (NT_SUCCESS(Status))
+ Ret = DISP_CHANGE_RESTART;
+ else
+ /* return DISP_CHANGE_NOTUPDATED when we can save to reg only vaild for NT */
+ Ret = DISP_CHANGE_NOTUPDATED;
+
+ }
+
+ if (dwflags != 0)
+ Ret = DISP_CHANGE_BADFLAGS;
+
+ return Ret;
+}
/* EOF */