From b22255488ef2a8ebe9424cab084ed7535ea3f214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 31 May 2006 14:26:56 +0000 Subject: [PATCH] Fix BSOD in IntPrepareDriver (bug 1321) svn path=/trunk/; revision=22126 --- reactos/subsystems/win32/win32k/include/dc.h | 1 + .../subsystems/win32/win32k/main/dllmain.c | 7 ++++ reactos/subsystems/win32/win32k/objects/dc.c | 33 ++++++++++++++++--- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index 44941bbdc5f..e1019f6de77 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -170,6 +170,7 @@ typedef struct #define DC_UnlockDc(pDC) \ GDIOBJ_UnlockObjByPtr (GdiHandleTable, pDC) +NTSTATUS FASTCALL InitDcImpl(VOID); HDC FASTCALL RetrieveDisplayHDC(VOID); HDC FASTCALL DC_AllocDC(PUNICODE_STRING Driver); VOID FASTCALL DC_InitDC(HDC DCToInit); diff --git a/reactos/subsystems/win32/win32k/main/dllmain.c b/reactos/subsystems/win32/win32k/main/dllmain.c index 36f1f15b5df..7270ea2a58e 100644 --- a/reactos/subsystems/win32/win32k/main/dllmain.c +++ b/reactos/subsystems/win32/win32k/main/dllmain.c @@ -500,6 +500,13 @@ DriverEntry ( return STATUS_UNSUCCESSFUL; } + Status = InitDcImpl(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to initialize Device context implementation!\n"); + return STATUS_UNSUCCESSFUL; + } + /* Initialize FreeType library */ if (! InitFontSupport()) { diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index 4d82639367a..384c1220d78 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -41,6 +41,17 @@ HalQueryDisplayOwnership( #endif static GDIDEVICE PrimarySurface; +static KEVENT VideoDriverNeedsPreparation; +static KEVENT VideoDriverPrepared; + + +NTSTATUS FASTCALL +InitDcImpl(VOID) +{ + KeInitializeEvent(&VideoDriverNeedsPreparation, SynchronizationEvent, TRUE); + KeInitializeEvent(&VideoDriverPrepared, NotificationEvent, FALSE); + return STATUS_SUCCESS; +} /* FIXME: DCs should probably be thread safe */ @@ -489,6 +500,17 @@ IntPrepareDriver() BOOL GotDriver; BOOL DoDefault; ULONG DisplayNumber; + LARGE_INTEGER Zero; + BOOLEAN ret = FALSE; + + Zero.QuadPart = 0; + if (STATUS_SUCCESS != KeWaitForSingleObject(&VideoDriverNeedsPreparation, Executive, KernelMode, TRUE, &Zero)) + { + /* Concurrent access. Wait for VideoDriverPrepared event */ + if (STATUS_SUCCESS == KeWaitForSingleObject(&VideoDriverPrepared, Executive, KernelMode, TRUE, NULL)) + ret = PrimarySurface.PreparedDriver; + goto cleanup; + } for (DisplayNumber = 0; ; DisplayNumber++) { @@ -502,7 +524,7 @@ IntPrepareDriver() if (PrimarySurface.VideoFileObject == NULL) { DPRINT1("FindMPDriver failed\n"); - return FALSE; + goto cleanup; } /* Retrieve DDI driver names from registry */ @@ -576,7 +598,7 @@ IntPrepareDriver() { ObDereferenceObject(PrimarySurface.VideoFileObject); DPRINT1("BuildDDIFunctions failed\n"); - return FALSE; + goto cleanup; } /* Allocate a phyical device handle from the driver */ @@ -659,10 +681,13 @@ IntPrepareDriver() PrimarySurface.PreparedDriver = TRUE; PrimarySurface.DisplayNumber = DisplayNumber; - return TRUE; + ret = TRUE; + goto cleanup; } - return FALSE; +cleanup: + KeSetEvent(&VideoDriverPrepared, 1, FALSE); + return ret; } static BOOL FASTCALL