Windows2003-3790/drivers/input/kbdclass/kbdclass.h
2020-09-30 16:53:55 +02:00

719 lines
16 KiB
C

/*++
Copyright (c) 1990, 1991, 1992, 1993, 1994 - 1998 Microsoft Corporation
Module Name:
kbdclass.h
Abstract:
These are the structures and defines that are used in the
keyboard class driver.
Revision History:
--*/
#ifndef _KBDCLASS_
#define _KBDCLASS_
#include <ntddkbd.h>
#include "wmilib.h"
#define KEYBOARD_POOL_TAG 'CdbK'
#undef ExAllocatePool
#define ExAllocatePool(Type, Bytes) ExAllocatePoolWithTag(Type, Bytes, KEYBOARD_POOL_TAG)
//
// Define the default number of elements in the class input data queue.
//
#define DATA_QUEUE_SIZE 100
#define MAXIMUM_PORTS_SERVICED 10
#define NAME_MAX 256
#define DUMP_COUNT 4
#define DEFAULT_DEBUG_LEVEL 0
#define MAX(a,b) (((a) < (b)) ? (b) : (a))
#if DBG
#define KbdPrint(x) KbdDebugPrint x
#else
#define KbdPrint(x)
#endif
#define KEYBOARD_POWER_LIGHT_TIME L"PowerLightTime"
#define KEYBOARD_WAIT_WAKE_ENABLE L"WaitWakeEnabled"
#define KEYBOARD_ALLOW_DISABLE L"AllowDisable"
#define IS_TRUSTED_FILE_FOR_READ(x) (&DriverEntry == (x)->FsContext2)
#define SET_TRUSTED_FILE_FOR_READ(x) ((x)->FsContext2 = &DriverEntry)
#define CLEAR_TRUSTED_FILE_FOR_READ(x) ((x)->FsContext2 = NULL)
#define ALLOW_OVERFLOW TRUE
//
// Port description
//
// Used only with the
// allforoneandoneforall turned off (AKA ConnectOneClassToOnePort
// turned on). This is the file sent to the ports.
//
typedef struct _PORT {
//
// The file Pointer to the port;
//
PFILE_OBJECT File;
//
// The port itself
//
struct _DEVICE_EXTENSION * Port;
//
// Port flags
//
BOOLEAN Enabled;
BOOLEAN Reserved [2];
BOOLEAN Free;
} PORT, *PPORT;
#define PORT_WORKING(port) ((port)->Enabled && !(port)->Free)
//
// Class device extension.
//
typedef struct _DEVICE_EXTENSION {
//
// Back pointer to the Device Object created for this port.
//
PDEVICE_OBJECT Self;
//
// Pointer to the active Class DeviceObject;
// If the AFOAOFA (all for one and one for all) switch is on then this
// points to the device object named as the first keyboard.
//
PDEVICE_OBJECT TrueClassDevice;
//
// The Target port device Object to which all IRPs are sent.
//
PDEVICE_OBJECT TopPort;
//
// The PDO if applicable.
//
PDEVICE_OBJECT PDO;
//
// A remove lock to keep track of outstanding I/Os to prevent the device
// object from leaving before such time as all I/O has been completed.
//
IO_REMOVE_LOCK RemoveLock;
//
// If this port a Plug and Play port
//
BOOLEAN PnP;
BOOLEAN Started;
BOOLEAN AllowDisable;
KSPIN_LOCK WaitWakeSpinLock;
//
// Is the Trusted Subsystem Connected
//
ULONG TrustedSubsystemCount;
//
// Number of input data items currently in the InputData queue.
//
ULONG InputCount;
//
// A Unicode string pointing to the symbolic link for the Device Interface
// of this device object.
//
UNICODE_STRING SymbolicLinkName;
//
// Start of the class input data queue (really a circular buffer).
//
PKEYBOARD_INPUT_DATA InputData;
//
// Insertion pointer for InputData.
//
PKEYBOARD_INPUT_DATA DataIn;
//
// Removal pointer for InputData.
//
PKEYBOARD_INPUT_DATA DataOut;
//
// Keyboard attributes.
//
KEYBOARD_ATTRIBUTES KeyboardAttributes;
//
// A saved state of indicator lights
//
KEYBOARD_INDICATOR_PARAMETERS IndicatorParameters;
//
// Spinlock used to synchronize access to the input data queue and its
// insertion/removal pointers.
//
KSPIN_LOCK SpinLock;
//
// Queue of pended read requests sent to this port. Access to this queue is
// guarded by SpinLock
//
LIST_ENTRY ReadQueue;
//
// Request sequence number (used for error logging).
//
ULONG SequenceNumber;
//
// The "D" and "S" states of the current device
//
DEVICE_POWER_STATE DeviceState;
SYSTEM_POWER_STATE SystemState;
ULONG UnitId;
//
// WMI Information
//
WMILIB_CONTEXT WmiLibInfo;
//
// Mapping of system to device states when a wait wake irp is active
//
DEVICE_POWER_STATE SystemToDeviceState[PowerSystemHibernate];
//
// Minimum amount of power needed to wake the device
//
DEVICE_POWER_STATE MinDeviceWakeState;
//
// Lowest system state that the machine can be in and have the device wake it up
//
SYSTEM_POWER_STATE MinSystemWakeState;
//
// Actual wait wake irp
//
PIRP WaitWakeIrp;
//
// Duplicate wait wake irp getting completed because another was queued.
//
PIRP ExtraWaitWakeIrp;
//
// Target Device Notification Handle
//
PVOID TargetNotifyHandle;
//
// Only used for a legacy port device
//
LIST_ENTRY Link;
//
// Used only for a legacy port device when grand master mode is off
//
PFILE_OBJECT File;
//
// Used for a legacy port device
//
BOOLEAN Enabled;
//
// Indicates whether it is okay to log overflow errors.
//
BOOLEAN OkayToLogOverflow;
//
// Indicates whether it is okay to send wait wake irps down the stack
// (does NOT reflect if the bus can implement or not)
//
BOOLEAN WaitWakeEnabled;
//
// Indicates whether we have received a surprise removed irp
//
BOOLEAN SurpriseRemoved;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
//
// On some busses, we can power down the bus, but not the system, in this case
// we still need to allow the device to wake said bus, therefore
// waitwake-supported should not rely on systemstate.
//
// #define WAITWAKE_SUPPORTED(port) ((port)->MinDeviceWakeState > PowerDeviceUnspecified) && \
// (port)->MinSystemWakeState > PowerSystemWorking)
#define WAITWAKE_SUPPORTED(port) ((port)->MinDeviceWakeState > PowerDeviceD0 && \
(port)->MinSystemWakeState > PowerSystemWorking)
// #define WAITWAKE_ON(port) ((port)->WaitWakeIrp != 0)
#define WAITWAKE_ON(port) \
(InterlockedCompareExchangePointer(&(port)->WaitWakeIrp, NULL, NULL) != NULL)
#define SHOULD_SEND_WAITWAKE(port) (WAITWAKE_SUPPORTED(port) && \
!WAITWAKE_ON(port) && \
KeyboardClassCheckWaitWakeEnabled(port))
//
// Global shared data
//
typedef struct _GLOBALS {
//
// Declare the global debug flag for this driver.
//
ULONG Debug;
//
// If ConnectOneClassToOnePort is off aka we want "All for one and one for
// all behavior" then we need to create the one Master DO to which all
// the goods go.
//
PDEVICE_EXTENSION GrandMaster;
//
// List of ClassDevices that associated with the same name
// aka the all for one and one for all flag is set
//
PPORT AssocClassList;
ULONG NumAssocClass;
LONG Opens;
ULONG NumberLegacyPorts;
FAST_MUTEX Mutex;
//
// Specifies the type of class-port connection to make. A '1'
// indicates a 1:1 relationship between class device objects and
// port device objects. A '0' indicates a 1:many relationship.
//
ULONG ConnectOneClassToOnePort;
//
// When kbdclass receives an output command (EG set LEDs) this flag
// instructs it to transmit that command to all attached ports,
// regardless of the unit ID which was specified.
//
ULONG SendOutputToAllPorts;
//
// Number of port drivers serviced by this class driver.
//
ULONG PortsServiced;
//
//
// IntialDevice Extension
//
DEVICE_EXTENSION InitExtension;
//
// A list of the registry path to the service parameters.
//
UNICODE_STRING RegistryPath;
//
// The base name for all class objects created as mice.
//
UNICODE_STRING BaseClassName;
WCHAR BaseClassBuffer[NAME_MAX];
//
// Linked list of all the legacy device objects that were created in
// DriverEntry or FindMorePorts. We maintain this list so we can delete
// them when we unload.
//
LIST_ENTRY LegacyDeviceList;
} GLOBALS, *PGLOBALS;
typedef struct _KBD_CALL_ALL_PORTS {
//
// Number of ports to call
//
ULONG Len;
//
// Current Called port;
//
ULONG Current;
//
// Array of Ports to call
//
PORT Port[];
} KBD_CALL_ALL_PORTS, *PKBD_CALL_ALL_PORTS;
//
// Keyboard configuration information.
//
typedef struct _KEYBOARD_CONFIGURATION_INFORMATION {
//
// Maximum size of class input data queue, in bytes.
//
ULONG DataQueueSize;
} KEYBOARD_CONFIGURATION_INFORMATION, *PKEYBOARD_CONFIGURATION_INFORMATION;
typedef struct _KEYBOARD_WORK_ITEM_DATA {
PIRP Irp;
PDEVICE_EXTENSION Data;
PIO_WORKITEM Item;
BOOLEAN WaitWakeState;
} KEYBOARD_WORK_ITEM_DATA, *PKEYBOARD_WORK_ITEM_DATA;
#define KeyboardClassDeleteLegacyDevice(de) \
{ \
if (de->InputData) { \
ExFreePool (de->InputData); \
de->InputData = de->DataIn = de->DataOut = NULL; \
} \
IoDeleteDevice (de->Self); \
de = NULL; \
}
//
// Function Declarations
//
NTSTATUS
KeyboardAddDeviceEx(
IN PDEVICE_EXTENSION NewDeviceObject,
IN PWCHAR FullClassName,
IN PFILE_OBJECT File
);
NTSTATUS
KeyboardAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
);
void
KeyboardClassGetWaitWakeEnableState(
IN PDEVICE_EXTENSION Data
);
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
KeyboardClassPassThrough(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
KeyboardClassCancel(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
KeyboardClassCleanup(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
KeyboardClassDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
KeyboardClassFlush(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
KeyboardClassCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
KeyboardClassClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
KeyboardClassRead(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
KeyboardClassReadCopyData(
IN PDEVICE_EXTENSION DeviceExtension,
IN PIRP Irp
);
PIRP
KeyboardClassDequeueRead(
IN PDEVICE_EXTENSION DeviceExtension
);
PIRP
KeyboardClassDequeueReadByFileObject(
IN PDEVICE_EXTENSION DeviceExtension,
IN PFILE_OBJECT FileObject
);
BOOLEAN
KeyboardClassCheckWaitWakeEnabled(
IN PDEVICE_EXTENSION Data
);
BOOLEAN
KeyboardClassCreateWaitWakeIrp (
IN PDEVICE_EXTENSION Data
);
NTSTATUS
KeyboardClassPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
KeyboardSendIrpSynchronously (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN BOOLEAN CopyToNext
);
NTSTATUS
KeyboardPnP (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
KeyboardClassServiceCallback(
IN PDEVICE_OBJECT DeviceObject,
IN PKEYBOARD_INPUT_DATA InputDataStart,
IN PKEYBOARD_INPUT_DATA InputDataEnd,
IN OUT PULONG InputDataConsumed
);
VOID
KeyboardClassStartIo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
KeyboardClassUnload(
IN PDRIVER_OBJECT DriverObject
);
BOOLEAN
KbdCancelRequest(
IN PVOID Context
);
VOID
KbdConfiguration();
NTSTATUS
KbdCreateClassObject(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_EXTENSION TmpDeviceExtension,
OUT PDEVICE_OBJECT * ClassDeviceObject,
OUT PWCHAR * FullDeviceName,
IN BOOLEAN Legacy
);
VOID
KbdDebugPrint(
ULONG DebugPrintLevel,
PCCHAR DebugMessage,
...
);
NTSTATUS
KbdDeterminePortsServiced(
IN PUNICODE_STRING BasePortName,
IN OUT PULONG NumberPortsServiced
);
NTSTATUS
KbdDeviceMapQueryCallback(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext
);
NTSTATUS
KbdEnableDisablePort(
IN BOOLEAN EnableFlag,
IN PIRP Irp,
IN PDEVICE_EXTENSION Port,
IN PFILE_OBJECT * File
);
NTSTATUS
KbdSendConnectRequest(
IN PDEVICE_EXTENSION ClassData,
IN PVOID ServiceCallback
);
VOID
KbdInitializeDataQueue(
IN PVOID Context
);
NTSTATUS
KeyboardCallAllPorts (
PDEVICE_OBJECT Device,
PIRP Irp,
PVOID
);
NTSTATUS
KeyboardClassEnableGlobalPort(
IN PDEVICE_EXTENSION Port,
IN BOOLEAN Enabled
);
NTSTATUS
KeyboardClassPlugPlayNotification(
IN PVOID NotificationStructure,
IN PDEVICE_EXTENSION Port
);
VOID
KeyboardClassLogError(
PVOID Object,
ULONG ErrorCode,
ULONG UniqueErrorValue,
NTSTATUS FinalStatus,
ULONG DumpCount,
ULONG *DumpData,
UCHAR MajorFunction
);
BOOLEAN
KeyboardClassCreateWaitWakeIrp (
IN PDEVICE_EXTENSION Data
);
void
KeyboardClassCreateWaitWakeIrpWorker (
IN PDEVICE_OBJECT DeviceObject,
IN PKEYBOARD_WORK_ITEM_DATA ItemData
);
NTSTATUS
KeyboardToggleWaitWake(
PDEVICE_EXTENSION Data,
BOOLEAN WaitWakeState
);
void
KeyboardToggleWaitWakeWorker (
IN PDEVICE_OBJECT DeviceObject,
PKEYBOARD_WORK_ITEM_DATA ItemData
);
NTSTATUS
KeyboardQueryDeviceKey (
IN HANDLE Handle,
IN PWCHAR ValueNameString,
OUT PVOID Data,
IN ULONG DataLength
);
VOID
KeyboardClassFindMorePorts(
PDRIVER_OBJECT DriverObject,
PVOID Context,
ULONG Count
);
NTSTATUS
KeyboardClassSystemControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
KeyboardClassSetWmiDataItem(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG GuidIndex,
IN ULONG InstanceIndex,
IN ULONG DataItemId,
IN ULONG BufferSize,
IN PUCHAR Buffer
);
NTSTATUS
KeyboardClassSetWmiDataBlock(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG GuidIndex,
IN ULONG InstanceIndex,
IN ULONG BufferSize,
IN PUCHAR Buffer
);
NTSTATUS
KeyboardClassQueryWmiDataBlock(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG GuidIndex,
IN ULONG InstanceIndex,
IN ULONG InstanceCount,
IN OUT PULONG InstanceLengthArray,
IN ULONG BufferAvail,
OUT PUCHAR Buffer
);
NTSTATUS
KeyboardClassQueryWmiRegInfo(
IN PDEVICE_OBJECT DeviceObject,
OUT ULONG *RegFlags,
OUT PUNICODE_STRING InstanceName,
OUT PUNICODE_STRING *RegistryPath,
OUT PUNICODE_STRING MofResourceName,
OUT PDEVICE_OBJECT *Pdo
);
#endif // _KBDCLASS_