You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
3.8 KiB
187 lines
3.8 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
event.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the event handling routines for SAC.
|
|
|
|
Author:
|
|
|
|
Sean Selitrennikoff (v-seans) - Jan 22, 1999
|
|
Brian Guarraci (briangu)
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "sac.h"
|
|
|
|
#if DBG
|
|
//
|
|
// A timer to show how many times we've hit the TimerDPC routine
|
|
//
|
|
// Note: use KD to view this value
|
|
//
|
|
ULONG TimerDpcCount = 0;
|
|
#endif
|
|
|
|
//
|
|
// Serial Port Buffer globals
|
|
//
|
|
PUCHAR SerialPortBuffer = NULL;
|
|
ULONG SerialPortProducerIndex = 0;
|
|
ULONG SerialPortConsumerIndex = 0;
|
|
|
|
VOID
|
|
WorkerProcessEvents(
|
|
IN PSAC_DEVICE_CONTEXT DeviceContext
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the routine for the worker thread. It blocks on an event, when
|
|
the event is signalled, then that indicates a request is ready to be processed.
|
|
|
|
Arguments:
|
|
|
|
DeviceContext - A pointer to this device.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Call the Worker handler
|
|
//
|
|
// Note: currently hardcoded to the console manager
|
|
//
|
|
IoMgrWorkerProcessEvents(DeviceContext);
|
|
}
|
|
|
|
|
|
VOID
|
|
TimerDpcRoutine(
|
|
IN struct _KDPC *Dpc,
|
|
IN PVOID DeferredContext,
|
|
IN PVOID SystemArgument1,
|
|
IN PVOID SystemArgument2
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is a DPC routine that is queue'd by DriverEntry. It is used to check for any
|
|
user input and then processes them.
|
|
|
|
Arguments:
|
|
|
|
DeferredContext - A pointer to the device context.
|
|
|
|
All other parameters are unused.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS Status;
|
|
SIZE_T i;
|
|
BOOLEAN HaveNewData;
|
|
HEADLESS_RSP_GET_BYTE Response;
|
|
|
|
//
|
|
// Keep track of how many times we've been here
|
|
//
|
|
#if DBG
|
|
InterlockedIncrement((volatile long *)&TimerDpcCount);
|
|
#endif
|
|
|
|
UNREFERENCED_PARAMETER(Dpc);
|
|
UNREFERENCED_PARAMETER(SystemArgument1);
|
|
UNREFERENCED_PARAMETER(SystemArgument2);
|
|
|
|
//
|
|
// default: we didn't receive any new data
|
|
//
|
|
HaveNewData = FALSE;
|
|
|
|
i = sizeof(HEADLESS_RSP_GET_BYTE);
|
|
|
|
do {
|
|
|
|
//
|
|
// Check for user input
|
|
//
|
|
Status = HeadlessDispatch(
|
|
HeadlessCmdGetByte,
|
|
NULL,
|
|
0,
|
|
&Response,
|
|
&i
|
|
);
|
|
|
|
if (! NT_SUCCESS(Status)) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If we received new data, add it to the buffer
|
|
//
|
|
if (Response.Value != 0) {
|
|
|
|
//
|
|
// we have new data
|
|
//
|
|
HaveNewData = TRUE;
|
|
|
|
//
|
|
// Assign the new value to the current producer index
|
|
//
|
|
// Note: We overrun data in the buffer if the consumer hasn't caught up
|
|
//
|
|
SerialPortBuffer[SerialPortProducerIndex] = Response.Value;
|
|
|
|
//
|
|
// Compute the new producer index and store it atomically
|
|
//
|
|
InterlockedExchange(
|
|
(volatile long *)&SerialPortProducerIndex,
|
|
(SerialPortProducerIndex + 1) % SERIAL_PORT_BUFFER_LENGTH
|
|
);
|
|
|
|
}
|
|
|
|
} while ( Response.Value != 0 );
|
|
|
|
//
|
|
// if we have new data, notify the worker thread to process the serial port buffer
|
|
//
|
|
if (HaveNewData) {
|
|
|
|
PSAC_DEVICE_CONTEXT DeviceContext;
|
|
|
|
ProcessingType = SAC_PROCESS_SERIAL_PORT_BUFFER;
|
|
DeviceContext = (PSAC_DEVICE_CONTEXT)DeferredContext;
|
|
|
|
KeSetEvent(
|
|
&(DeviceContext->ProcessEvent),
|
|
DeviceContext->PriorityBoost,
|
|
FALSE
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|