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.
564 lines
14 KiB
564 lines
14 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
mouhid.h
|
|
|
|
Abstract:
|
|
|
|
This module contains the private definitions for the HID Mouse Filter
|
|
Driver.
|
|
|
|
Note: This is not a WDM driver as it will not run on Memphis (you need a
|
|
vxd mapper to do mice for Memphis) and it uses event logs
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Revision History:
|
|
|
|
Jan-1997 : Initial writing, Dan Markarian
|
|
|
|
--*/
|
|
|
|
#ifndef _MOUHID_H
|
|
#define _MOUHID_H
|
|
|
|
#include "ntddk.h"
|
|
#include "hidusage.h"
|
|
#include "hidpi.h"
|
|
#include "ntddmou.h"
|
|
#include "kbdmou.h"
|
|
#include "mouhidm.h"
|
|
#include "wmilib.h"
|
|
|
|
//
|
|
// Allocate memory with our own pool tag. Note that Windows 95/NT are little
|
|
// endian systems.
|
|
//
|
|
#define MOUHID_POOL_TAG (ULONG) 'lCdH'
|
|
#undef ExAllocatePool
|
|
#define ExAllocatePool(type, size) \
|
|
ExAllocatePoolWithTag (type, size, MOUHID_POOL_TAG);
|
|
|
|
//
|
|
// Sometimes we allocate a bunch of structures together and need to split the
|
|
// allocation among these different structures. Use this macro to get the
|
|
// lengths of the different structures aligned properly.
|
|
//
|
|
#if defined(_WIN64)
|
|
#define ALIGNPTRLEN(x) ((x + 0x7) >> 3) << 3
|
|
#else // defined(_WIN64)
|
|
#define ALIGNPTRLEN(x) x
|
|
#endif // defined(_WIN64)
|
|
|
|
//
|
|
// Registry ProblemFlags masks.
|
|
//
|
|
#define PROBLEM_BAD_ABSOLUTE_FLAG_X_Y 0x00000001
|
|
#define PROBLEM_BAD_PHYSICAL_MIN_MAX_X 0x00000002
|
|
#define PROBLEM_BAD_PHYSICAL_MIN_MAX_Y 0x00000004
|
|
#define PROBLEM_BAD_PHYSICAL_MIN_MAX_Z 0x00000008
|
|
|
|
//
|
|
// Flags to indicate whether read completed synchronously or asynchronously
|
|
//
|
|
#define MOUHID_START_READ 0x01
|
|
#define MOUHID_END_READ 0x02
|
|
#define MOUHID_IMMEDIATE_READ 0x03
|
|
|
|
//
|
|
// I cannot find this constant after a bit of searching so I am making it up
|
|
// emperically for now.
|
|
//
|
|
// When we have an absolute mouse we need to scale its maximum value to the
|
|
// Raw Input User Thread's maximum value.
|
|
//
|
|
#define MOUHID_RIUT_ABSOLUTE_POINTER_MAX 0xFFFF
|
|
|
|
|
|
//
|
|
// Debug messaging and breakpoint macros.
|
|
//
|
|
|
|
#define DBG_STARTUP_SHUTDOWN_MASK 0x0000000F
|
|
#define DBG_SS_NOISE 0x00000001
|
|
#define DBG_SS_TRACE 0x00000002
|
|
#define DBG_SS_INFO 0x00000004
|
|
#define DBG_SS_ERROR 0x00000008
|
|
|
|
#define DBG_CALL_MASK 0x000000F0
|
|
#define DBG_CALL_NOISE 0x00000010
|
|
#define DBG_CALL_TRACE 0x00000020
|
|
#define DBG_CALL_INFO 0x00000040
|
|
#define DBG_CALL_ERROR 0x00000080
|
|
|
|
#define DBG_IOCTL_MASK 0x00000F00
|
|
#define DBG_IOCTL_NOISE 0x00000100
|
|
#define DBG_IOCTL_TRACE 0x00000200
|
|
#define DBG_IOCTL_INFO 0x00000400
|
|
#define DBG_IOCTL_ERROR 0x00000800
|
|
|
|
#define DBG_READ_MASK 0x0000F000
|
|
#define DBG_READ_NOISE 0x00001000
|
|
#define DBG_READ_TRACE 0x00002000
|
|
#define DBG_READ_INFO 0x00004000
|
|
#define DBG_READ_ERROR 0x00008000
|
|
|
|
#define DBG_CREATE_CLOSE_MASK 0x000F0000
|
|
#define DBG_CC_NOISE 0x00010000
|
|
#define DBG_CC_TRACE 0x00020000
|
|
#define DBG_CC_INFO 0x00040000
|
|
#define DBG_CC_ERROR 0x00080000
|
|
|
|
#define DBG_POWER_MASK 0x00F00000
|
|
#define DBG_POWER_NOISE 0x00100000
|
|
#define DBG_POWER_TRACE 0x00200000
|
|
#define DBG_POWER_INFO 0x00400000
|
|
#define DBG_POWER_ERROR 0x00800000
|
|
|
|
#define DBG_PNP_MASK 0x0F000000
|
|
#define DBG_PNP_NOISE 0x01000000
|
|
#define DBG_PNP_TRACE 0x02000000
|
|
#define DBG_PNP_INFO 0x04000000
|
|
#define DBG_PNP_ERROR 0x08000000
|
|
|
|
#define DBG_CANCEL_MASK 0xF0000000
|
|
#define DBG_CANCEL_NOISE 0x10000000
|
|
#define DBG_CANCEL_TRACE 0x20000000
|
|
#define DBG_CANCEL_INFO 0x40000000
|
|
#define DBG_CANCEL_ERROR 0x80000000
|
|
|
|
#define DEFAULT_DEBUG_OUTPUT_LEVEL 0x88888888
|
|
|
|
#if DBG
|
|
|
|
#define Print(_l_, _x_) \
|
|
if (Globals.DebugLevel & (_l_)) { \
|
|
DbgPrint ("MouHid: "); \
|
|
DbgPrint _x_; \
|
|
}
|
|
#define TRAP() DbgBreakPoint()
|
|
|
|
#else
|
|
#define Print(_l_,_x_)
|
|
#define TRAP()
|
|
#endif
|
|
|
|
#define MAX(_A_,_B_) (((_A_) < (_B_)) ? (_B_) : (_A_))
|
|
#define MIN(_A_,_B_) (((_A_) < (_B_)) ? (_A_) : (_B_))
|
|
|
|
|
|
#define FLIP_FLOP_WHEEL L"FlipFlopWheel" // should we change polarity of wheel
|
|
#define SCALING_FACTOR_WHEEL L"WheelScalingFactor" // The per-raden scaling factor
|
|
|
|
|
|
|
|
//
|
|
// Structures
|
|
//
|
|
typedef struct _GLOBALS {
|
|
#if DBG
|
|
//
|
|
// The level of trace output sent to the debugger. See HidCli_KdPrint above.
|
|
//
|
|
ULONG DebugLevel;
|
|
#endif
|
|
|
|
//
|
|
// Configuration flag indicating that we must treat all mouse movement as
|
|
// relative data. Overrides .IsAbsolute flag reported by the HID device.
|
|
// To set this switch, place a value of the same name into the parameters
|
|
// key.
|
|
//
|
|
BOOLEAN TreatAbsoluteAsRelative;
|
|
|
|
//
|
|
// When using a HID device of usage type HID_USAGE_GENERIC_POINTER (not
|
|
// of HID_USAGE_GENERIC_MOUSE).
|
|
// This switch overwrites the "TreatAbsoluteAsRelative" switch.
|
|
//
|
|
BOOLEAN TreatAbsolutePointerAsAbsolute;
|
|
|
|
//
|
|
// Do not Accept HID_USAGE_GENERIC_POINTER as a device. (AKA only use HID
|
|
// devices that declare themselves as HID_USAGE_GENERIC_MOUSE.)
|
|
//
|
|
BOOLEAN UseOnlyMice;
|
|
BOOLEAN Reserved[1];
|
|
|
|
//
|
|
// Pointer to this driver's null-terminated registry path.
|
|
//
|
|
UNICODE_STRING RegistryPath;
|
|
|
|
//
|
|
// Unit ID given to the keyboard class driver
|
|
//
|
|
ULONG UnitId;
|
|
|
|
} GLOBALS;
|
|
|
|
extern GLOBALS Globals;
|
|
|
|
typedef struct _DEVICE_EXTENSION
|
|
{
|
|
//
|
|
// Pointer back to the this extension's device object.
|
|
//
|
|
PDEVICE_OBJECT Self;
|
|
|
|
//
|
|
// The top of the stack before this filter was added. AKA the location
|
|
// to which all IRPS should be directed.
|
|
//
|
|
PDEVICE_OBJECT TopOfStack;
|
|
|
|
//
|
|
// "THE PDO" (ejected by Hidclass)
|
|
//
|
|
PDEVICE_OBJECT PDO;
|
|
|
|
//
|
|
// Flag indicating permission to send callbacks to the mouse class driver.
|
|
//
|
|
LONG EnableCount;
|
|
|
|
//
|
|
// Read interlock value to protect us from running out of stack space
|
|
//
|
|
ULONG ReadInterlock;
|
|
|
|
//
|
|
// Has the device been taken out from under us?
|
|
// Has it been started?
|
|
//
|
|
BOOLEAN Started;
|
|
BOOLEAN ShuttingDown;
|
|
BOOLEAN Initialized;
|
|
USHORT UnitId;
|
|
|
|
// Should the polarity of the wheel be backwards.
|
|
BOOLEAN FlipFlop;
|
|
BOOLEAN Reserved[3];
|
|
ULONG WheelScalingFactor;
|
|
|
|
//
|
|
// Write and Feature Irps get passed straight down, but read Irps do not.
|
|
// For this reason we keep around a read Irp, which we created.
|
|
//
|
|
PIRP ReadIrp;
|
|
|
|
//
|
|
// Flags indicating problems with the mouse HID device (such as bad
|
|
// absolute X-Y axes, bad physical minimum and maximum).
|
|
//
|
|
ULONG ProblemFlags;
|
|
|
|
//
|
|
// A file pointer to be used for reading
|
|
//
|
|
PFILE_OBJECT ReadFile;
|
|
|
|
//
|
|
// Event used to synchronize the completion of the read irp and the close irp
|
|
//
|
|
KEVENT ReadCompleteEvent;
|
|
|
|
//
|
|
// Event used to indicate that a read irp has been sent and is now cancelable.
|
|
//
|
|
KEVENT ReadSentEvent;
|
|
|
|
//
|
|
// A pointer to the HID extension.
|
|
//
|
|
struct _HID_EXTENSION * HidExtension;
|
|
|
|
//
|
|
// Pointer to the mouse class device object and callback routine
|
|
// above us, Used as the first parameter and the MouseClassCallback().
|
|
// routine itself.
|
|
//
|
|
CONNECT_DATA ConnectData;
|
|
|
|
//
|
|
// Remove Lock object to project IRP_MN_REMOVE_DEVICE
|
|
//
|
|
IO_REMOVE_LOCK RemoveLock;
|
|
|
|
//
|
|
// A fast mutex to prevent Create from trouncing close, as one starts the
|
|
// read loop and the other shuts it down.
|
|
//
|
|
FAST_MUTEX CreateCloseMutex;
|
|
|
|
//
|
|
// An event to halt the deletion of a device until it is ready to go.
|
|
//
|
|
KEVENT StartEvent;
|
|
|
|
//
|
|
// Buffer for a single mouse data packet so that we might hand it to
|
|
// the mouse class driver.
|
|
//
|
|
MOUSE_INPUT_DATA InputData;
|
|
|
|
//
|
|
// Buffer for the mouse attributes.
|
|
//
|
|
MOUSE_ATTRIBUTES Attributes;
|
|
USHORT AttributesAllignmentProblem; //
|
|
|
|
//
|
|
// An attachment point for the global list o devices
|
|
//
|
|
LIST_ENTRY Link;
|
|
|
|
//
|
|
// WMI Information
|
|
//
|
|
WMILIB_CONTEXT WmiLibInfo;
|
|
|
|
} DEVICE_EXTENSION, * PDEVICE_EXTENSION;
|
|
|
|
typedef struct _HID_EXTENSION {
|
|
|
|
//
|
|
// Indicates the bit size of each X,Y,Z usage value. This information is
|
|
// used should the usage's physical minimum/maximum limits be invalid (a
|
|
// common problem).
|
|
//
|
|
struct {
|
|
USHORT X;
|
|
USHORT Y;
|
|
USHORT Z;
|
|
USHORT Reserved;
|
|
} BitSize;
|
|
|
|
//
|
|
// The maximum allowed values of X and Y.
|
|
//
|
|
LONG MaxX;
|
|
LONG MaxY;
|
|
|
|
//
|
|
// Should this mouse be treated as an absolute device.
|
|
//
|
|
BOOLEAN IsAbsolute;
|
|
|
|
//
|
|
// Flag indicating whether or not a wheel usage (Z axis) exists.
|
|
//
|
|
BOOLEAN HasNoWheelUsage;
|
|
|
|
//
|
|
// Flag indicating whether or not a z axis exists on this mouse;
|
|
//
|
|
BOOLEAN HasNoZUsage;
|
|
BOOLEAN Reserved;
|
|
|
|
//
|
|
// The maximum number of usages that can be returned from a single read
|
|
// report.
|
|
USHORT MaxUsages;
|
|
USHORT Reserved2;
|
|
|
|
//
|
|
// The preparsed data associated with this hid device.
|
|
//
|
|
PHIDP_PREPARSED_DATA Ppd;
|
|
|
|
//
|
|
// The capabilities of this hid device
|
|
//
|
|
HIDP_CAPS Caps;
|
|
|
|
//
|
|
// Pointers into the buffer at the end of this structure (dynamic size).
|
|
//
|
|
PCHAR InputBuffer;
|
|
PUSAGE CurrentUsageList;
|
|
PUSAGE PreviousUsageList;
|
|
PUSAGE BreakUsageList;
|
|
PUSAGE MakeUsageList;
|
|
|
|
//
|
|
// MDLs describing the buffer at the end of this structure (dynamic size).
|
|
//
|
|
PMDL InputMdl;
|
|
|
|
//
|
|
// Buffer of dynamic size, allocated at run-time. It is used to hold one
|
|
// input report and 4 x .MaxUsageList usages (4 = previous, current, make,
|
|
// and break usages).
|
|
//
|
|
CHAR Buffer[];
|
|
} HID_EXTENSION, * PHID_EXTENSION;
|
|
|
|
//
|
|
// Prototypes.
|
|
//
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_AddDevice (
|
|
IN PDRIVER_OBJECT MouHidDriver, // The kbd Driver object.
|
|
IN PDEVICE_OBJECT PDO
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_Close (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_Create (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_CallHidClass(
|
|
IN PDEVICE_EXTENSION Data,
|
|
IN ULONG Ioctl,
|
|
PVOID InputBuffer,
|
|
ULONG InputBufferLength,
|
|
PVOID OutputBuffer,
|
|
ULONG OutputBufferLength
|
|
);
|
|
|
|
VOID
|
|
MouHid_LogError(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN NTSTATUS ErrorCode,
|
|
IN PWSTR ErrorInsertionString OPTIONAL
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_StartDevice (
|
|
IN PDEVICE_EXTENSION Data
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_StartRead (
|
|
IN PDEVICE_EXTENSION Data
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_PnP (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_Power (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_Power (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_PnPComplete (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN PVOID Context
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_GetRegistryParameters ();
|
|
|
|
VOID
|
|
MouHid_Unload(
|
|
IN PDRIVER_OBJECT Driver
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_IOCTL (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_Flush (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
KbdHid_Power (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_PassThrough (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_SystemControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_SetWmiDataItem(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG DataItemId,
|
|
IN ULONG BufferSize,
|
|
IN PUCHAR Buffer
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_SetWmiDataBlock(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN ULONG GuidIndex,
|
|
IN ULONG InstanceIndex,
|
|
IN ULONG BufferSize,
|
|
IN PUCHAR Buffer
|
|
);
|
|
|
|
NTSTATUS
|
|
MouHid_QueryWmiDataBlock(
|
|
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
|
|
MouHid_QueryWmiRegInfo(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
OUT ULONG *RegFlags,
|
|
OUT PUNICODE_STRING InstanceName,
|
|
OUT PUNICODE_STRING *RegistryPath,
|
|
OUT PUNICODE_STRING MofResourceName,
|
|
OUT PDEVICE_OBJECT *Pdo
|
|
);
|
|
|
|
extern WMIGUIDREGINFO MouHid_WmiGuidList[1];
|
|
|
|
#endif //_MOUHID_H
|