diff --git a/reactos/drivers/video/videoprt/event.c b/reactos/drivers/video/videoprt/event.c index 5d04a75fbd8..c4359755cbd 100644 --- a/reactos/drivers/video/videoprt/event.c +++ b/reactos/drivers/video/videoprt/event.c @@ -1,120 +1,140 @@ /* - * VideoPort driver - * - * Copyright (C) 2002, 2003, 2004 ReactOS Team - * - * This library is free software; you can redistribute it and/or - * 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 - * + * PROJECT: ReactOS Video Port Driver + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/video/videoprt/event.c + * PURPOSE: Event Support Routines + * PROGRAMMERS: ReactOS Portable Systems Group */ +/* INCLUDES *******************************************************************/ + #include "videoprt.h" +#include "../../subsystems/win32/win32k/include/engevent.h" /* PUBLIC FUNCTIONS ***********************************************************/ /* * @implemented */ - -VP_STATUS NTAPI -VideoPortCreateEvent( - IN PVOID HwDeviceExtension, - IN ULONG EventFlag, - IN PVOID Unused, - OUT PEVENT *Event) +VP_STATUS +NTAPI +VideoPortCreateEvent(IN PVOID HwDeviceExtension, + IN ULONG EventFlag, + IN PVOID Unused, + OUT PEVENT *Event) { - PVIDEO_PORT_EVENT VpEvent; - EVENT_TYPE Type = SynchronizationEvent; + VP_STATUS Result = NO_ERROR; + PVIDEO_PORT_EVENT EngEvent; - /* Allocate storage for the event structure */ - VpEvent = ExAllocatePoolWithTag( - NonPagedPool, - sizeof(VIDEO_PORT_EVENT), - TAG_VIDEO_PORT); + /* Allocate memory for the event structure */ + EngEvent = ExAllocatePoolWithTag(NonPagedPool, + sizeof(VIDEO_PORT_EVENT) + sizeof(KEVENT), + 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 */ - if (!VpEvent) return ERROR_NOT_ENOUGH_MEMORY; + /* Pass pointer to our structure to the caller */ + *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 */ - RtlZeroMemory(VpEvent, sizeof(VIDEO_PORT_EVENT)); - 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; + /* Return result */ + return Result; } /* * @implemented */ - -VP_STATUS NTAPI -VideoPortDeleteEvent( - IN PVOID HwDeviceExtension, - IN PEVENT Event) +VP_STATUS +NTAPI +VideoPortDeleteEvent(IN PVOID HwDeviceExtension, + IN PEVENT Event) { - /* Free storage */ - ExFreePool(Event); + /* Handle error cases */ + 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 */ - return NO_ERROR; + /* Free storage */ + ExFreePool(Event); + + /* Indicate success */ + return NO_ERROR; } /* * @implemented */ - -LONG NTAPI -VideoPortSetEvent( - IN PVOID HwDeviceExtension, - IN PEVENT Event) +LONG +NTAPI +VideoPortSetEvent(IN PVOID HwDeviceExtension, + IN PEVENT Event) { - return KeSetEvent(Event->pKEvent, IO_NO_INCREMENT, FALSE); + return KeSetEvent(Event->pKEvent, IO_NO_INCREMENT, FALSE); } /* * @implemented */ - -VOID NTAPI -VideoPortClearEvent( - IN PVOID HwDeviceExtension, - IN PEVENT Event) +VOID +NTAPI +VideoPortClearEvent(IN PVOID HwDeviceExtension, + IN PEVENT Event) { - KeClearEvent(Event->pKEvent); + KeClearEvent(Event->pKEvent); } /* * @implemented */ - -VP_STATUS NTAPI -VideoPortWaitForSingleObject( - IN PVOID HwDeviceExtension, - IN PVOID Object, - IN PLARGE_INTEGER Timeout OPTIONAL) +VP_STATUS +NTAPI +VideoPortWaitForSingleObject(IN PVOID HwDeviceExtension, + IN PVOID Event, + IN PLARGE_INTEGER Timeout OPTIONAL) { - return KeWaitForSingleObject( - Object, - Executive, - KernelMode, - FALSE, - Timeout); + PVIDEO_PORT_EVENT EngEvent = Event; + NTSTATUS Status; + + /* Handle error cases */ + if (!EngEvent) return ERROR_INVALID_PARAMETER; + 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 */ + diff --git a/reactos/drivers/video/videoprt/videoprt.h b/reactos/drivers/video/videoprt/videoprt.h index 9a24c2e6e31..eb2b8eee111 100644 --- a/reactos/drivers/video/videoprt/videoprt.h +++ b/reactos/drivers/video/videoprt/videoprt.h @@ -107,11 +107,7 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION typedef struct _VIDEO_PORT_EVENT { - /* Public part */ ENG_EVENT; - - /* Private part */ - KEVENT Event; } VIDEO_PORT_EVENT, *PVIDEO_PORT_EVENT; /* agp.c */ diff --git a/reactos/subsystems/win32/win32k/eng/engevent.c b/reactos/subsystems/win32/win32k/eng/engevent.c index d38c32ae2d1..3773c305029 100644 --- a/reactos/subsystems/win32/win32k/eng/engevent.c +++ b/reactos/subsystems/win32/win32k/eng/engevent.c @@ -1,54 +1,59 @@ /* * 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 * PURPOSE: Event Support Routines * PROGRAMMERS: Aleksey Bragin + * ReactOS Portable Systems Group */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include +#include #define NDEBUG #include -#define TAG_ENG ' gnE' +/* Dfsm - - Eng event allocation (ENG_KEVENTALLOC,ENG_ALLOC) in ntgdi\gre */ +#define TAG_GRE_EVENT 'msfD' -/* PUBLIC FUNCTIONS **********************************************************/ +/* PUBLIC FUNCTIONS ***********************************************************/ BOOL APIENTRY EngCreateEvent(OUT PEVENT* Event) { + BOOLEAN Result = TRUE; PENG_EVENT EngEvent; /* Allocate memory for the event structure */ - EngEvent = EngAllocMem(FL_NONPAGED_MEMORY | FL_ZERO_MEMORY, - sizeof(ENG_EVENT), - TAG_ENG); - - /* Check if we are out of memory */ - if (!EngEvent) + EngEvent = ExAllocatePoolWithTag(NonPagedPool, + sizeof(ENG_EVENT) + sizeof(KEVENT), + TAG_GRE_EVENT); + if (EngEvent) { - /* We are, fail */ - return FALSE; + /* Set KEVENT pointer */ + 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 */ - EngEvent->pKEvent = &EngEvent->KEvent; - - /* 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; + /* Return result */ + return Result; } BOOL @@ -66,7 +71,7 @@ EngDeleteEvent(IN PEVENT Event) } /* Free the allocated memory */ - EngFreeMem(Event); + ExFreePool(Event); /* Return success */ return TRUE; @@ -106,18 +111,57 @@ EngMapEvent(IN HDEV hDev, IN PVOID Reserved2, IN PVOID Reserved3) { - DPRINT("EngMapEvent(%x %x %p %p %p)\n", hDev, hUserObject, Reserved1, Reserved2, Reserved3); - UNIMPLEMENTED; - return NULL; + PENG_EVENT EngEvent; + NTSTATUS Status; + + /* 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 APIENTRY EngUnmapEvent(IN PEVENT Event) { - DPRINT("EngUnmapEvent(%p)\n", Event); - UNIMPLEMENTED; - return FALSE; + /* Must be a usermapped event */ + if (!(Event->fFlags & ENG_EVENT_USERMAPPED)) return FALSE; + + /* Dereference the object, destroying it */ + ObDereferenceObject(Event->pKEvent); + + /* Free the Eng object */ + ExFreePool(Event); + return TRUE; } BOOL @@ -126,7 +170,6 @@ EngWaitForSingleObject(IN PEVENT Event, IN PLARGE_INTEGER TimeOut) { NTSTATUS Status; - DPRINT("EngWaitForSingleObject(%p %I64d)\n", Event, TimeOut->QuadPart); /* Validate parameters */ @@ -148,12 +191,7 @@ EngWaitForSingleObject(IN PEVENT Event, TimeOut); /* Check if there is a failure or a timeout */ - if (!NT_SUCCESS(Status)) - { - /* Return failure */ - return FALSE; - } - - /* Return success */ - return TRUE; + return NT_SUCCESS(Status); } + +/* EOF */ diff --git a/reactos/subsystems/win32/win32k/include/engevent.h b/reactos/subsystems/win32/win32k/include/engevent.h index a1249f05fe8..be864990d2e 100644 --- a/reactos/subsystems/win32/win32k/include/engevent.h +++ b/reactos/subsystems/win32/win32k/include/engevent.h @@ -1,13 +1,8 @@ #pragma once -#define ENG_EVENT_USERMAPPED 1 +// +// Flags for the fFlags field of ENG_EVENT +// +#define ENG_EVENT_USERMAPPED 0x01 -typedef struct _ENG_EVENT -{ - /* Public part */ - PVOID pKEvent; - ULONG fFlags; - - /* Private part */ - KEVENT KEvent; -} ENG_EVENT, *PENG_EVENT; +/* EOF */