#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
#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 */
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++)
{
if (PrimarySurface.VideoFileObject == NULL)
{
DPRINT1("FindMPDriver failed\n");
- return FALSE;
+ goto cleanup;
}
/* Retrieve DDI driver names from registry */
{
ObDereferenceObject(PrimarySurface.VideoFileObject);
DPRINT1("BuildDDIFunctions failed\n");
- return FALSE;
+ goto cleanup;
}
/* Allocate a phyical device handle from the driver */
PrimarySurface.PreparedDriver = TRUE;
PrimarySurface.DisplayNumber = DisplayNumber;
- return TRUE;
+ ret = TRUE;
+ goto cleanup;
}
- return FALSE;
+cleanup:
+ KeSetEvent(&VideoDriverPrepared, 1, FALSE);
+ return ret;
}
static BOOL FASTCALL