Implement display ownership, also makes ATI Rage 3rd party video driver

runnable

svn path=/trunk/; revision=4937
This commit is contained in:
Gé van Geldorp 2003-06-21 14:25:30 +00:00
parent a9b7d71462
commit ba8e03d72f
11 changed files with 259 additions and 54 deletions

View file

@ -1,4 +1,4 @@
/* $Id: blue.c,v 1.38 2003/06/20 13:04:09 gvg Exp $
/* $Id: blue.c,v 1.39 2003/06/21 14:25:30 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -170,6 +170,17 @@ ScrWrite(PDEVICE_OBJECT DeviceObject,
int rows, columns;
int processed = DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT;
if (HalQueryDisplayOwnership())
{
/* Display is in graphics mode, we're not allowed to touch it */
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return Status;
}
vidmem = DeviceExtension->VideoMemory;
rows = DeviceExtension->Rows;
columns = DeviceExtension->Columns;
@ -615,11 +626,11 @@ DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
DPRINT ("Screen Driver 0.0.6\n");
DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = ScrIoControl;
DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH) ScrCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH) ScrDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH) ScrDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH) ScrWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = (PDRIVER_DISPATCH) ScrIoControl;
IoCreateDevice (DriverObject,
sizeof(DEVICE_EXTENSION),

View file

@ -1,4 +1,4 @@
/* $Id: videoprt.c,v 1.5 2003/06/19 15:57:45 gvg Exp $
/* $Id: videoprt.c,v 1.6 2003/06/21 14:25:30 gvg Exp $
*
* VideoPort driver
* Written by Rex Jolliff
@ -38,6 +38,7 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
KIRQL IRQL;
KAFFINITY Affinity;
PVIDEO_HW_INITIALIZE HwInitialize;
PVIDEO_HW_RESET_HW HwResetHw;
LIST_ENTRY AddressMappingListHead;
INTERFACE_TYPE AdapterInterfaceType;
ULONG SystemIoBusNumber;
@ -48,7 +49,8 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
static NTSTATUS STDCALL VidDispatchOpen(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
static NTSTATUS STDCALL VidDispatchClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
static PVOID STDCALL InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
IN PHYSICAL_ADDRESS IoAddress,
@ -58,8 +60,8 @@ static VOID STDCALL InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceEx
IN PVOID MappedAddress);
static BOOLEAN CsrssInitialized = FALSE;
static HANDLE CsrssHandle = 0;
static struct _EPROCESS* Csrss = NULL;
static PEPROCESS Csrss = NULL;
static PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
PBYTE ReturnCsrssAddress(void)
{
@ -391,8 +393,8 @@ VideoPortInitialize(IN PVOID Context1,
MPDriverObject->DeviceObject = MPDeviceObject;
/* Initialize the miniport drivers dispatch table */
MPDriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH) VidDispatchOpenClose;
MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH) VidDispatchOpenClose;
MPDriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH) VidDispatchOpen;
MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH) VidDispatchClose;
MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH) VidDispatchDeviceControl;
/* Initialize our device extension */
@ -400,6 +402,7 @@ VideoPortInitialize(IN PVOID Context1,
(PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension;
DeviceExtension->DeviceObject = MPDeviceObject;
DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
DeviceExtension->HwResetHw = HwInitializationData->HwResetHw;
DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType;
DeviceExtension->SystemIoBusNumber = 0;
MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR);
@ -545,9 +548,15 @@ VideoPortInt10(IN PVOID HwDeviceExtension,
{
KV86M_REGISTERS Regs;
NTSTATUS Status;
PEPROCESS CallingProcess;
DPRINT("VideoPortInt10\n");
KeAttachProcess(Csrss);
CallingProcess = PsGetCurrentProcess();
if (CallingProcess != Csrss)
{
KeAttachProcess(Csrss);
}
memset(&Regs, 0, sizeof(Regs));
Regs.Eax = BiosArguments->Eax;
@ -559,7 +568,10 @@ VideoPortInt10(IN PVOID HwDeviceExtension,
Regs.Ebp = BiosArguments->Ebp;
Status = Ke386CallBios(0x10, &Regs);
KeDetachProcess();
if (CallingProcess != Csrss)
{
KeDetachProcess();
}
return(Status);
}
@ -1033,13 +1045,44 @@ VideoPortZeroDeviceMemory(OUT PVOID Destination,
RtlZeroMemory(Destination, Length);
}
/*
* Reset display to blue screen
*/
static BOOLEAN STDCALL
VideoPortResetDisplayParameters(Columns, Rows)
{
VIDEO_X86_BIOS_ARGUMENTS Int10Arguments;
// ------------------------------------------- Nondiscardable statics
if (NULL != ResetDisplayParametersDeviceExtension &&
(NULL == ResetDisplayParametersDeviceExtension->HwResetHw ||
! ResetDisplayParametersDeviceExtension->HwResetHw(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
Columns, Rows)))
{
/* This should really be done by HAL, but we have this nice
* VideoPortInt10 available */
// VidDispatchOpenClose
/* Set mode */
RtlZeroMemory(&Int10Arguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
Int10Arguments.Eax = 0x0003;
VideoPortInt10(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
&Int10Arguments);
/* Select 8x8 font */
Int10Arguments.Eax = 0x1112;
Int10Arguments.Ebx = 0;
VideoPortInt10(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
&Int10Arguments);
}
ResetDisplayParametersDeviceExtension = NULL;
return TRUE;
}
// VidDispatchOpen
//
// DESCRIPTION:
// Answer requests for Open/Close calls: a null operation
// Answer requests for Open calls
//
// RUN LEVEL:
// PASSIVE_LEVEL
@ -1052,37 +1095,42 @@ VideoPortZeroDeviceMemory(OUT PVOID Destination,
//
static NTSTATUS STDCALL
VidDispatchOpenClose(IN PDEVICE_OBJECT pDO,
IN PIRP Irp)
VidDispatchOpen(IN PDEVICE_OBJECT pDO,
IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
DPRINT("VidDispatchOpenClose() called\n");
DPRINT("VidDispatchOpen() called\n");
IrpStack = IoGetCurrentIrpStackLocation(Irp);
if (IrpStack->MajorFunction == IRP_MJ_CREATE &&
CsrssInitialized == FALSE)
if (! CsrssInitialized)
{
DPRINT("Referencing CSRSS\n");
Csrss = PsGetCurrentProcess();
CsrssInitialized = TRUE;
DPRINT("Csrss %p\n", Csrss);
}
else
{
DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION) pDO->DeviceExtension;
if (DeviceExtension->HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
{
Irp->IoStatus.Status = STATUS_SUCCESS;
/* Storing the device extension pointer in a static variable is an ugly
* hack. Unfortunately, we need it in VideoPortResetDisplayParameters
* and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
* parameter. On the bright side, the DISPLAY device is opened
* exclusively, so there can be only one device extension active at
* any point in time. */
ResetDisplayParametersDeviceExtension = DeviceExtension;
HalAcquireDisplayOwnership(VideoPortResetDisplayParameters);
}
else
{
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
}
else
{
Irp->IoStatus.Status = STATUS_SUCCESS;
}
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -1090,6 +1138,47 @@ VidDispatchOpenClose(IN PDEVICE_OBJECT pDO,
return STATUS_SUCCESS;
}
// VidDispatchClose
//
// DESCRIPTION:
// Answer requests for Close calls
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// Standard dispatch arguments
//
// RETURNS:
// NTSTATUS
//
static NTSTATUS STDCALL
VidDispatchClose(IN PDEVICE_OBJECT pDO,
IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
DPRINT("VidDispatchClose() called\n");
IrpStack = IoGetCurrentIrpStackLocation(Irp);
if (! CsrssInitialized)
{
CsrssInitialized = TRUE;
}
else
{
HalReleaseDisplayOwnership();
}
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// VidStartIo
//
// DESCRIPTION:

View file

@ -98,3 +98,6 @@ WRITE_PORT_BUFFER_USHORT@12
WRITE_PORT_UCHAR@8
WRITE_PORT_ULONG@8
WRITE_PORT_USHORT@8
HalReleaseDisplayOwnership@0
HalQueryDisplayOwnership@0

View file

@ -98,3 +98,6 @@ WRITE_PORT_BUFFER_USHORT=WRITE_PORT_BUFFER_USHORT@12
WRITE_PORT_UCHAR=WRITE_PORT_UCHAR@8
WRITE_PORT_ULONG=WRITE_PORT_ULONG@8
WRITE_PORT_USHORT=WRITE_PORT_USHORT@8
HalReleaseDisplayOwnership=HalReleaseDisplayOwnership@0
HalQueryDisplayOwnership=HalQueryDisplayOwnership@0

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: display.c,v 1.4 2002/09/08 10:22:24 chorns Exp $
/* $Id: display.c,v 1.5 2003/06/21 14:25:30 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -27,6 +27,71 @@
* Created 08/10/99
*/
/* DISPLAY OWNERSHIP
*
* So, who owns the physical display and is allowed to write to it?
*
* In MS NT, upon boot HAL owns the display. Somewhere in the boot
* sequence (haven't figured out exactly where or by who), some
* component calls HalAcquireDisplayOwnership. From that moment on,
* the display is owned by that component and is switched to graphics
* mode. The display is not supposed to return to text mode, except
* in case of a bug check. The bug check will call HalDisplayString
* to output a string to the text screen. HAL will notice that it
* currently doesn't own the display and will re-take ownership, by
* calling the callback function passed to HalAcquireDisplayOwnership.
* After the bugcheck, execution is halted. So, under NT, the only
* possible sequence of display modes is text mode -> graphics mode ->
* text mode (the latter hopefully happening very infrequently).
*
* Things are a little bit different in the current state of ReactOS.
* We want to have a functional interactive text mode. We should be
* able to switch from text mode to graphics mode when a GUI app is
* started and switch back to text mode when it's finished. Then, when
* another GUI app is started, another switch to and from graphics mode
* is possible. Also, when the system bugchecks in graphics mode we want
* to switch back to text mode to show the registers and stack trace.
* Last but not least, HalDisplayString is used a lot more in ReactOS,
* e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
* is present.
* 3 Components are involved in Reactos: HAL, BLUE.SYS and VIDEOPRT.SYS.
* As in NT, on boot HAL owns the display. When entering the text mode
* command interpreter, BLUE.SYS kicks in. It will write directly to the
* screen, more or less behind HALs back.
* When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
* This open call will end up in VIDEOPRT.SYS. That component will then
* take ownership of the display by calling HalAcquireDisplayOwnership.
* When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
* we want to give ownership of the display back to HAL. Using the
* standard exported HAL functions, that's a bit of a problem, because
* there is no function defined to do that. In NT, this is handled by
* HalDisplayString, but that solution isn't satisfactory in ReactOS,
* because HalDisplayString is (in some cases) also used to output debug
* messages. If we do it the NT way, the first debug message output while
* in graphics mode would switch the display back to text mode.
* So, instead, if HalDisplayString detects that HAL doesn't have ownership
* of the display, it doesn't do anything.
* To return ownership to HAL, a new function is exported,
* HalReleaseDisplayOwnership. This function is called by the DISPLAY
* device Close routine in VIDEOPRT.SYS. It is also called at the beginning
* of a bug check, so HalDisplayString is activated again.
* Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
* should also refrain from writing to the screen buffer. The text mode
* screen buffer might overlap the graphics mode screen buffer, so changing
* something in the text mode buffer might mess up the graphics screen. To
* allow BLUE.SYS to detect if HAL owns the display, another new function is
* exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
* check if it's allowed to touch the text mode buffer.
*
* In an ideal world, when HAL takes ownership of the display, it should set
* up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
* calls. Unfortunately, this will require HAL to setup a real-mode interrupt
* table etc. So, we chickened out of that by having the loader set up the
* display before switching to protected mode. If HAL is given back ownership
* after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
* since there is already support for them via the VideoPortInt10 routine.
*/
#include <ddk/ntddk.h>
#include <mps.h>
@ -156,12 +221,12 @@ HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
}
VOID
HalResetDisplay(VOID)
/* PUBLIC FUNCTIONS *********************************************************/
VOID STDCALL
HalReleaseDisplayOwnership()
/*
* FUNCTION: Reset the display
* ARGUMENTS:
* None
* FUNCTION: Release ownership of display back to HAL
*/
{
if (HalResetDisplayParameters == NULL)
@ -178,8 +243,6 @@ HalResetDisplay(VOID)
}
/* PUBLIC FUNCTIONS *********************************************************/
VOID STDCALL
HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
/*
@ -193,7 +256,6 @@ HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParamete
HalResetDisplayParameters = ResetDisplayParameters;
}
VOID STDCALL
HalDisplayString(IN PCH String)
/*
@ -212,16 +274,24 @@ HalDisplayString(IN PCH String)
static KSPIN_LOCK Lock;
ULONG Flags;
/* See comment at top of file */
if (! HalOwnsDisplay)
{
return;
}
pch = String;
pushfl(Flags);
__asm__ ("cli\n\t");
KeAcquireSpinLockAtDpcLevel(&Lock);
#if 0
if (HalOwnsDisplay == FALSE)
{
HalResetDisplay ();
HalReleaseDisplayOwnership();
}
#endif
#ifdef SCREEN_SYNCHRONIZATION
WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_CURHI);
@ -273,7 +343,6 @@ HalDisplayString(IN PCH String)
popfl(Flags);
}
VOID STDCALL
HalQueryDisplayParameters(OUT PULONG DispSizeX,
OUT PULONG DispSizeY,
@ -299,4 +368,10 @@ HalSetDisplayParameters(IN ULONG CursorPosX,
CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
}
BOOLEAN STDCALL
HalQueryDisplayOwnership()
{
return ! HalOwnsDisplay;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: reboot.c,v 1.3 2002/09/08 10:22:24 chorns Exp $
/* $Id: reboot.c,v 1.4 2003/06/21 14:25:30 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -66,7 +66,7 @@ HalReturnToFirmware (
}
else if (Action == FIRMWARE_REBOOT)
{
HalResetDisplay ();
HalReleaseDisplayOwnership();
HalReboot ();
}
}

View file

@ -1,6 +1,6 @@
#ifndef __INCLUDE_DDK_HALFUNCS_H
#define __INCLUDE_DDK_HALFUNCS_H
/* $Id: halfuncs.h,v 1.6 2003/06/07 10:14:39 chorns Exp $ */
/* $Id: halfuncs.h,v 1.7 2003/06/21 14:25:30 gvg Exp $ */
#include <ntos/haltypes.h>
@ -281,6 +281,13 @@ VOID STDCALL
WRITE_PORT_USHORT(PUSHORT Port,
USHORT Value);
/* Non-standard functions */
VOID STDCALL
HalReleaseDisplayOwnership();
BOOLEAN STDCALL
HalQueryDisplayOwnership();
#endif /* __INCLUDE_DDK_HALDDK_H */
/* EOF */

View file

@ -112,6 +112,7 @@ typedef struct
GDIINFO GDIInfo;
DEVINFO DevInfo;
DRIVER_FUNCTIONS DriverFunctions;
HANDLE DisplayDevice;
} GDIDEVICE;
/* Internal functions */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bug.c,v 1.29 2003/04/24 16:53:59 hbirr Exp $
/* $Id: bug.c,v 1.30 2003/06/21 14:25:30 gvg Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/bug.c
@ -31,6 +31,7 @@
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/kd.h>
#include <internal/ke.h>
#include <internal/ps.h>
@ -84,7 +85,11 @@ KeBugCheckWithTf(ULONG BugCheckCode,
{
PRTL_MESSAGE_RESOURCE_ENTRY Message;
NTSTATUS Status;
/* Make sure we're switching back to the blue screen and print messages on it */
HalReleaseDisplayOwnership();
KdDebugState |= KD_DEBUG_SCREEN;
__asm__("cli\n\t");
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
BugCheckCode,
@ -155,6 +160,10 @@ KeBugCheckEx(ULONG BugCheckCode,
PRTL_MESSAGE_RESOURCE_ENTRY Message;
NTSTATUS Status;
/* Make sure we're switching back to the blue screen and print messages on it */
HalReleaseDisplayOwnership();
KdDebugState |= KD_DEBUG_SCREEN;
__asm__("cli\n\t");
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
BugCheckCode,

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: device.c,v 1.7 2003/05/18 17:16:17 ea Exp $
/* $Id: device.c,v 1.8 2003/06/21 14:25:30 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -82,6 +82,8 @@ EngDeviceIoControl(HANDLE hDevice,
(void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
}
ObDereferenceObject(FileObject);
return (Status);
}
/* EOF */

View file

@ -16,7 +16,7 @@
* 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.60 2003/05/18 17:16:18 ea Exp $
/* $Id: dc.c,v 1.61 2003/06/21 14:25:30 gvg Exp $
*
* DC.C - Device context functions
*
@ -31,6 +31,7 @@
#include <win32k/coord.h>
#include <win32k/driver.h>
#include <win32k/dc.h>
#include <win32k/misc.h>
#include <win32k/print.h>
#include <win32k/region.h>
#include <win32k/gdiobj.h>
@ -247,7 +248,6 @@ BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver,
LPCWSTR Device)
{
PGD_ENABLEDRIVER GDEnableDriver;
HANDLE DeviceDriver;
DRVENABLEDATA DED;
PSURFOBJ SurfObj;
UNICODE_STRING DriverFileNames;
@ -255,7 +255,7 @@ BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver,
BOOL GotDriver;
/* Open the miniport driver */
if ((DeviceDriver = DRIVER_FindMPDriver(Driver)) == NULL)
if ((PrimarySurface.DisplayDevice = DRIVER_FindMPDriver(Driver)) == NULL)
{
DPRINT("FindMPDriver failed\n");
return(FALSE);
@ -348,7 +348,7 @@ BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver,
&PrimarySurface.DevInfo,
NULL,
L"",
DeviceDriver);
PrimarySurface.DisplayDevice);
if (PrimarySurface.PDev == NULL)
{
DPRINT("DrvEnablePDEV failed\n");
@ -479,13 +479,18 @@ BOOL STDCALL W32kDeleteDC(HDC DCHandle)
if (!DRIVER_UnreferenceDriver (DCToDelete->DriverName))
{
DPRINT( "No more references to driver, reseting display\n" );
DCToDelete->DriverFunctions.DisableSurface(DCToDelete->PDev);
CHECKPOINT;
DCToDelete->DriverFunctions.AssertMode( DCToDelete->PDev, FALSE );
CHECKPOINT;
DCToDelete->DriverFunctions.DisableSurface(DCToDelete->PDev);
CHECKPOINT;
DCToDelete->DriverFunctions.DisablePDev(DCToDelete->PDev);
PrimarySurfaceCreated = FALSE;
}
KeAttachProcess(W32kDeviceProcess);
ZwClose(PrimarySurface.DisplayDevice);
KeDetachProcess();
PrimarySurfaceCreated = FALSE;
}
}
CHECKPOINT;
/* First delete all saved DCs */