Fix BSOD in IntPrepareDriver (bug 1321)
authorHervé Poussineau <hpoussin@reactos.org>
Wed, 31 May 2006 14:26:56 +0000 (14:26 +0000)
committerHervé Poussineau <hpoussin@reactos.org>
Wed, 31 May 2006 14:26:56 +0000 (14:26 +0000)
svn path=/trunk/; revision=22126

reactos/subsystems/win32/win32k/include/dc.h
reactos/subsystems/win32/win32k/main/dllmain.c
reactos/subsystems/win32/win32k/objects/dc.c

index 44941bb..e1019f6 100644 (file)
@@ -170,6 +170,7 @@ typedef struct
 #define  DC_UnlockDc(pDC)  \\r
   GDIOBJ_UnlockObjByPtr (GdiHandleTable, pDC)\r
 \r
+NTSTATUS FASTCALL InitDcImpl(VOID);\r
 HDC  FASTCALL RetrieveDisplayHDC(VOID);\r
 HDC  FASTCALL DC_AllocDC(PUNICODE_STRING  Driver);\r
 VOID FASTCALL DC_InitDC(HDC  DCToInit);\r
index 36f1f15..7270ea2 100644 (file)
@@ -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())
     {
index 4d82639..384c122 100644 (file)
@@ -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