mirror of
https://github.com/reactos/reactos.git
synced 2025-06-12 08:58:31 +00:00
[VIDEOPRT/WIN32K]: Synchronize and share PEVENT/ENG_EVENT/VIDEO_PORT_EVENT implementation, as these objects are actually the same (and VideoPrt Event* APIs can be used on GRE Event Objects). Use ENG_EVENT structure from ntddvdeo.h instead of re-creating our own. Drivers using these interfaces will no longer explode.
[VIDEOPRT]: Add parameter checks to DeleteEvent and WaitForSingleObject. [VIDEOPRT]: Fix WaitForSingleObject. It was waiting on the Object paramter itself -- which is the VideoPrt/ENG Event, not a real object, we have to wait on ->pKEvent instead. [VIDEOPRT]: Fix WaitForSingleObject round two, it was returning the NT_STATUS, while VideoPrt should return VP_STATUS/Win32 error codes. [WIN32K]: Allocate/free GRE events directly from pool, instead of using Eng APIs. Use documented tag for GRE Events (Dfsm), found in pooltag.txt [WIN32K]: Implement EngMapEvent and EngUnmapEvent. svn path=/trunk/; revision=50256
This commit is contained in:
parent
05721dae3e
commit
3062a63e47
4 changed files with 186 additions and 137 deletions
|
@ -1,120 +1,140 @@
|
||||||
/*
|
/*
|
||||||
* VideoPort driver
|
* PROJECT: ReactOS Video Port Driver
|
||||||
*
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||||
* Copyright (C) 2002, 2003, 2004 ReactOS Team
|
* FILE: drivers/video/videoprt/event.c
|
||||||
*
|
* PURPOSE: Event Support Routines
|
||||||
* This library is free software; you can redistribute it and/or
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
#include "videoprt.h"
|
#include "videoprt.h"
|
||||||
|
#include "../../subsystems/win32/win32k/include/engevent.h"
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
VP_STATUS
|
||||||
VP_STATUS NTAPI
|
NTAPI
|
||||||
VideoPortCreateEvent(
|
VideoPortCreateEvent(IN PVOID HwDeviceExtension,
|
||||||
IN PVOID HwDeviceExtension,
|
IN ULONG EventFlag,
|
||||||
IN ULONG EventFlag,
|
IN PVOID Unused,
|
||||||
IN PVOID Unused,
|
OUT PEVENT *Event)
|
||||||
OUT PEVENT *Event)
|
|
||||||
{
|
{
|
||||||
PVIDEO_PORT_EVENT VpEvent;
|
VP_STATUS Result = NO_ERROR;
|
||||||
EVENT_TYPE Type = SynchronizationEvent;
|
PVIDEO_PORT_EVENT EngEvent;
|
||||||
|
|
||||||
/* Allocate storage for the event structure */
|
/* Allocate memory for the event structure */
|
||||||
VpEvent = ExAllocatePoolWithTag(
|
EngEvent = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
NonPagedPool,
|
sizeof(VIDEO_PORT_EVENT) + sizeof(KEVENT),
|
||||||
sizeof(VIDEO_PORT_EVENT),
|
TAG_VIDEO_PORT);
|
||||||
TAG_VIDEO_PORT);
|
if (EngEvent)
|
||||||
|
{
|
||||||
|
/* Set KEVENT pointer */
|
||||||
|
EngEvent->pKEvent = EngEvent + 1;
|
||||||
|
|
||||||
|
/* Initialize the kernel event */
|
||||||
|
KeInitializeEvent(EngEvent->pKEvent,
|
||||||
|
(EventFlag & EVENT_TYPE_MASK) ?
|
||||||
|
NotificationEvent : SynchronizationEvent,
|
||||||
|
EventFlag & INITIAL_EVENT_STATE_MASK);
|
||||||
|
|
||||||
/* Fail if not enough memory */
|
/* Pass pointer to our structure to the caller */
|
||||||
if (!VpEvent) return ERROR_NOT_ENOUGH_MEMORY;
|
*Event = (PEVENT)EngEvent;
|
||||||
|
DPRINT("VideoPortCreateEvent() created %p\n", EngEvent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Out of memory */
|
||||||
|
DPRINT("VideoPortCreateEvent() failed\n");
|
||||||
|
Result = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the event structure */
|
/* Return result */
|
||||||
RtlZeroMemory(VpEvent, sizeof(VIDEO_PORT_EVENT));
|
return Result;
|
||||||
VpEvent->pKEvent = &VpEvent->Event;
|
|
||||||
|
|
||||||
/* Determine the event type */
|
|
||||||
if (EventFlag & NOTIFICATION_EVENT)
|
|
||||||
Type = NotificationEvent;
|
|
||||||
|
|
||||||
/* Initialize kernel event */
|
|
||||||
KeInitializeEvent(VpEvent->pKEvent, Type, EventFlag & INITIAL_EVENT_SIGNALED);
|
|
||||||
|
|
||||||
/* Indicate success */
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
VP_STATUS
|
||||||
VP_STATUS NTAPI
|
NTAPI
|
||||||
VideoPortDeleteEvent(
|
VideoPortDeleteEvent(IN PVOID HwDeviceExtension,
|
||||||
IN PVOID HwDeviceExtension,
|
IN PEVENT Event)
|
||||||
IN PEVENT Event)
|
|
||||||
{
|
{
|
||||||
/* Free storage */
|
/* Handle error cases */
|
||||||
ExFreePool(Event);
|
if (!Event) return ERROR_INVALID_PARAMETER;
|
||||||
|
if (Event->fFlags & ENG_EVENT_USERMAPPED) return ERROR_INVALID_PARAMETER;
|
||||||
|
if (!Event->pKEvent) return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* Indicate success */
|
/* Free storage */
|
||||||
return NO_ERROR;
|
ExFreePool(Event);
|
||||||
|
|
||||||
|
/* Indicate success */
|
||||||
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
LONG
|
||||||
LONG NTAPI
|
NTAPI
|
||||||
VideoPortSetEvent(
|
VideoPortSetEvent(IN PVOID HwDeviceExtension,
|
||||||
IN PVOID HwDeviceExtension,
|
IN PEVENT Event)
|
||||||
IN PEVENT Event)
|
|
||||||
{
|
{
|
||||||
return KeSetEvent(Event->pKEvent, IO_NO_INCREMENT, FALSE);
|
return KeSetEvent(Event->pKEvent, IO_NO_INCREMENT, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
VOID
|
||||||
VOID NTAPI
|
NTAPI
|
||||||
VideoPortClearEvent(
|
VideoPortClearEvent(IN PVOID HwDeviceExtension,
|
||||||
IN PVOID HwDeviceExtension,
|
IN PEVENT Event)
|
||||||
IN PEVENT Event)
|
|
||||||
{
|
{
|
||||||
KeClearEvent(Event->pKEvent);
|
KeClearEvent(Event->pKEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
VP_STATUS
|
||||||
VP_STATUS NTAPI
|
NTAPI
|
||||||
VideoPortWaitForSingleObject(
|
VideoPortWaitForSingleObject(IN PVOID HwDeviceExtension,
|
||||||
IN PVOID HwDeviceExtension,
|
IN PVOID Event,
|
||||||
IN PVOID Object,
|
IN PLARGE_INTEGER Timeout OPTIONAL)
|
||||||
IN PLARGE_INTEGER Timeout OPTIONAL)
|
|
||||||
{
|
{
|
||||||
return KeWaitForSingleObject(
|
PVIDEO_PORT_EVENT EngEvent = Event;
|
||||||
Object,
|
NTSTATUS Status;
|
||||||
Executive,
|
|
||||||
KernelMode,
|
/* Handle error cases */
|
||||||
FALSE,
|
if (!EngEvent) return ERROR_INVALID_PARAMETER;
|
||||||
Timeout);
|
if (!EngEvent->pKEvent) return ERROR_INVALID_PARAMETER;
|
||||||
|
if (EngEvent->fFlags & ENG_EVENT_USERMAPPED) return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* Do the actual wait */
|
||||||
|
Status = KeWaitForSingleObject(EngEvent->pKEvent,
|
||||||
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
Timeout);
|
||||||
|
if (Status == STATUS_TIMEOUT)
|
||||||
|
{
|
||||||
|
/* Convert to wait timeout, otherwise NT_SUCCESS would return NO_ERROR */
|
||||||
|
return WAIT_TIMEOUT;
|
||||||
|
}
|
||||||
|
else if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* All other success codes are Win32 success */
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, return default Win32 failure */
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
||||||
|
|
|
@ -107,11 +107,7 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
|
||||||
|
|
||||||
typedef struct _VIDEO_PORT_EVENT
|
typedef struct _VIDEO_PORT_EVENT
|
||||||
{
|
{
|
||||||
/* Public part */
|
|
||||||
ENG_EVENT;
|
ENG_EVENT;
|
||||||
|
|
||||||
/* Private part */
|
|
||||||
KEVENT Event;
|
|
||||||
} VIDEO_PORT_EVENT, *PVIDEO_PORT_EVENT;
|
} VIDEO_PORT_EVENT, *PVIDEO_PORT_EVENT;
|
||||||
|
|
||||||
/* agp.c */
|
/* agp.c */
|
||||||
|
|
|
@ -1,54 +1,59 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS Win32K
|
* PROJECT: ReactOS Win32K
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||||
* FILE: subsystems/win32/win32k/eng/engevent.c
|
* FILE: subsystems/win32/win32k/eng/engevent.c
|
||||||
* PURPOSE: Event Support Routines
|
* PURPOSE: Event Support Routines
|
||||||
* PROGRAMMERS: Aleksey Bragin <aleksey@reactos.org>
|
* PROGRAMMERS: Aleksey Bragin <aleksey@reactos.org>
|
||||||
|
* ReactOS Portable Systems Group
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
#include <win32k.h>
|
#include <win32k.h>
|
||||||
|
#include <ntddvdeo.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#define TAG_ENG ' gnE'
|
/* Dfsm - <unknown> - Eng event allocation (ENG_KEVENTALLOC,ENG_ALLOC) in ntgdi\gre */
|
||||||
|
#define TAG_GRE_EVENT 'msfD'
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS **********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
EngCreateEvent(OUT PEVENT* Event)
|
EngCreateEvent(OUT PEVENT* Event)
|
||||||
{
|
{
|
||||||
|
BOOLEAN Result = TRUE;
|
||||||
PENG_EVENT EngEvent;
|
PENG_EVENT EngEvent;
|
||||||
|
|
||||||
/* Allocate memory for the event structure */
|
/* Allocate memory for the event structure */
|
||||||
EngEvent = EngAllocMem(FL_NONPAGED_MEMORY | FL_ZERO_MEMORY,
|
EngEvent = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
sizeof(ENG_EVENT),
|
sizeof(ENG_EVENT) + sizeof(KEVENT),
|
||||||
TAG_ENG);
|
TAG_GRE_EVENT);
|
||||||
|
if (EngEvent)
|
||||||
/* Check if we are out of memory */
|
|
||||||
if (!EngEvent)
|
|
||||||
{
|
{
|
||||||
/* We are, fail */
|
/* Set KEVENT pointer */
|
||||||
return FALSE;
|
EngEvent->fFlags = 0;
|
||||||
|
EngEvent->pKEvent = EngEvent + 1;
|
||||||
|
|
||||||
|
/* Initialize the kernel event */
|
||||||
|
KeInitializeEvent(EngEvent->pKEvent,
|
||||||
|
SynchronizationEvent,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
/* Pass pointer to our structure to the caller */
|
||||||
|
*Event = EngEvent;
|
||||||
|
DPRINT("EngCreateEvent() created %p\n", EngEvent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Out of memory */
|
||||||
|
DPRINT("EngCreateEvent() failed\n");
|
||||||
|
Result = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set KEVENT pointer */
|
/* Return result */
|
||||||
EngEvent->pKEvent = &EngEvent->KEvent;
|
return Result;
|
||||||
|
|
||||||
/* Initialize the kernel event */
|
|
||||||
KeInitializeEvent(EngEvent->pKEvent,
|
|
||||||
SynchronizationEvent,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
/* Pass pointer to our structure to the caller */
|
|
||||||
*Event = EngEvent;
|
|
||||||
|
|
||||||
DPRINT("EngCreateEvent() created %p\n", EngEvent);
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -66,7 +71,7 @@ EngDeleteEvent(IN PEVENT Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the allocated memory */
|
/* Free the allocated memory */
|
||||||
EngFreeMem(Event);
|
ExFreePool(Event);
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -106,18 +111,57 @@ EngMapEvent(IN HDEV hDev,
|
||||||
IN PVOID Reserved2,
|
IN PVOID Reserved2,
|
||||||
IN PVOID Reserved3)
|
IN PVOID Reserved3)
|
||||||
{
|
{
|
||||||
DPRINT("EngMapEvent(%x %x %p %p %p)\n", hDev, hUserObject, Reserved1, Reserved2, Reserved3);
|
PENG_EVENT EngEvent;
|
||||||
UNIMPLEMENTED;
|
NTSTATUS Status;
|
||||||
return NULL;
|
|
||||||
|
/* Allocate memory for the event structure */
|
||||||
|
EngEvent = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
sizeof(ENG_EVENT),
|
||||||
|
TAG_GRE_EVENT);
|
||||||
|
if (!EngEvent) return NULL;
|
||||||
|
|
||||||
|
/* Zero it out */
|
||||||
|
EngEvent->fFlags = 0;
|
||||||
|
EngEvent->pKEvent = NULL;
|
||||||
|
|
||||||
|
/* Create a handle, and have Ob fill out the pKEvent field */
|
||||||
|
Status = ObReferenceObjectByHandle(EngEvent,
|
||||||
|
EVENT_ALL_ACCESS,
|
||||||
|
ExEventObjectType,
|
||||||
|
UserMode,
|
||||||
|
&EngEvent->pKEvent,
|
||||||
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Pulse the event and set that it's mapped by user */
|
||||||
|
KePulseEvent(EngEvent->pKEvent, EVENT_INCREMENT, FALSE);
|
||||||
|
EngEvent->fFlags |= ENG_EVENT_USERMAPPED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Free the allocation */
|
||||||
|
ExFreePool(EngEvent);
|
||||||
|
EngEvent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Support legacy interface */
|
||||||
|
if (Reserved1) *(PVOID*)Reserved1 = EngEvent;
|
||||||
|
return EngEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
EngUnmapEvent(IN PEVENT Event)
|
EngUnmapEvent(IN PEVENT Event)
|
||||||
{
|
{
|
||||||
DPRINT("EngUnmapEvent(%p)\n", Event);
|
/* Must be a usermapped event */
|
||||||
UNIMPLEMENTED;
|
if (!(Event->fFlags & ENG_EVENT_USERMAPPED)) return FALSE;
|
||||||
return FALSE;
|
|
||||||
|
/* Dereference the object, destroying it */
|
||||||
|
ObDereferenceObject(Event->pKEvent);
|
||||||
|
|
||||||
|
/* Free the Eng object */
|
||||||
|
ExFreePool(Event);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -126,7 +170,6 @@ EngWaitForSingleObject(IN PEVENT Event,
|
||||||
IN PLARGE_INTEGER TimeOut)
|
IN PLARGE_INTEGER TimeOut)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("EngWaitForSingleObject(%p %I64d)\n", Event, TimeOut->QuadPart);
|
DPRINT("EngWaitForSingleObject(%p %I64d)\n", Event, TimeOut->QuadPart);
|
||||||
|
|
||||||
/* Validate parameters */
|
/* Validate parameters */
|
||||||
|
@ -148,12 +191,7 @@ EngWaitForSingleObject(IN PEVENT Event,
|
||||||
TimeOut);
|
TimeOut);
|
||||||
|
|
||||||
/* Check if there is a failure or a timeout */
|
/* Check if there is a failure or a timeout */
|
||||||
if (!NT_SUCCESS(Status))
|
return NT_SUCCESS(Status);
|
||||||
{
|
|
||||||
/* Return failure */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define ENG_EVENT_USERMAPPED 1
|
//
|
||||||
|
// Flags for the fFlags field of ENG_EVENT
|
||||||
|
//
|
||||||
|
#define ENG_EVENT_USERMAPPED 0x01
|
||||||
|
|
||||||
typedef struct _ENG_EVENT
|
/* EOF */
|
||||||
{
|
|
||||||
/* Public part */
|
|
||||||
PVOID pKEvent;
|
|
||||||
ULONG fFlags;
|
|
||||||
|
|
||||||
/* Private part */
|
|
||||||
KEVENT KEvent;
|
|
||||||
} ENG_EVENT, *PENG_EVENT;
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue