reactos/drivers/network/tdi/cte/events.c

158 lines
3.1 KiB
C

/*
* PROJECT: ReactOS TDI driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/network/tdi/cte/events.c
* PURPOSE: CTE events support
* PROGRAMMERS: Oleg Baikalow (obaikalow@gmail.com)
*/
/* INCLUDES *****************************************************************/
#include "precomp.h"
typedef struct _CTEBLOCK_EVENT
{
NTSTATUS Status;
KEVENT Event;
} CTEBLOCK_EVENT, *PCTEBLOCK_EVENT;
struct _CTE_DELAYED_EVENT;
typedef void (*CTE_WORKER_ROUTINE)(struct _CTE_DELAYED_EVENT *, void *Context);
typedef struct _CTE_DELAYED_EVENT
{
BOOLEAN Queued;
KSPIN_LOCK Lock;
CTE_WORKER_ROUTINE WorkerRoutine;
PVOID Context;
WORK_QUEUE_ITEM WorkItem;
} CTE_DELAYED_EVENT, *PCTE_DELAYED_EVENT;
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
NTSTATUS
NTAPI
CTEBlock(PCTEBLOCK_EVENT Block)
{
NTSTATUS Status;
/* Perform the wait */
Status = KeWaitForSingleObject(&Block->Event, UserRequest, KernelMode, FALSE, NULL);
/* Update event status if wait was not successful */
if (!NT_SUCCESS(Status)) Block->Status = Status;
return Block->Status;
}
VOID
NTAPI
InternalWorker(IN PVOID Parameter)
{
PCTE_DELAYED_EVENT Event = (PCTE_DELAYED_EVENT)Parameter;
KIRQL OldIrql;
/* Acquire the lock */
KeAcquireSpinLock(&Event->Lock, &OldIrql);
/* Make sure it is queued */
ASSERT(Event->Queued);
Event->Queued = FALSE;
/* Release the lock */
KeReleaseSpinLock(&Event->Lock, OldIrql);
/* Call the real worker routine */
(*Event->WorkerRoutine)(Event, Event->Context);
}
/*
* @implemented
*/
VOID
NTAPI
CTEInitEvent(PCTE_DELAYED_EVENT Event,
CTE_WORKER_ROUTINE Routine)
{
/* Init the structure, lock and a work item */
Event->Queued = FALSE;
KeInitializeSpinLock(&Event->Lock);
Event->WorkerRoutine = Routine;
ExInitializeWorkItem(&Event->WorkItem, InternalWorker, Event);
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
CTELogEvent (
ULONG Unknown0,
ULONG Unknown1,
ULONG Unknown2,
ULONG Unknown3,
ULONG Unknown4,
ULONG Unknown5,
ULONG Unknown6
)
{
/* Probably call
* IoAllocateErrorLogEntry and
* IoWriteErrorLogEntry
*/
return STATUS_NOT_IMPLEMENTED;
}
/*
* @implemented
*/
BOOLEAN
NTAPI
CTEScheduleEvent(PCTE_DELAYED_EVENT Event,
PVOID Context)
{
KIRQL OldIrql;
/* Acquire the lock */
KeAcquireSpinLock(&Event->Lock, &OldIrql);
/* Make sure it is queued */
if (!Event->Queued)
{
/* Mark it as queued and set optional context pointer */
Event->Queued = TRUE;
Event->Context = Context;
/* Actually queue it */
ExQueueWorkItem(&Event->WorkItem, CriticalWorkQueue);
}
/* Release the lock */
KeReleaseSpinLock(&Event->Lock, OldIrql);
return TRUE;
}
/*
* @implemented
*/
LONG
NTAPI
CTESignal(PCTEBLOCK_EVENT Block, NTSTATUS Status)
{
/* Set status right away */
Block->Status = Status;
/* Set the event */
return KeSetEvent(&Block->Event, IO_NO_INCREMENT, FALSE);
}
/* EOF */