1027 lines
40 KiB
C
1027 lines
40 KiB
C
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
local.h
|
|
|
|
Abstract
|
|
|
|
Definitions that are private to the hid class driver code appear here.
|
|
|
|
Author:
|
|
|
|
Ervin P.
|
|
|
|
Environment:
|
|
|
|
Kernel mode only
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
typedef struct _HID_DESCRIPTOR *PHID_DESCRIPTOR;
|
|
typedef struct _HIDCLASS_COLLECTION *PHIDCLASS_COLLECTION;
|
|
typedef struct _HIDCLASS_DEVICE_EXTENSION *PHIDCLASS_DEVICE_EXTENSION;
|
|
typedef struct _HIDCLASS_DRIVER_EXTENSION *PHIDCLASS_DRIVER_EXTENSION;
|
|
typedef struct _HIDCLASS_FILE_EXTENSION *PHIDCLASS_FILE_EXTENSION;
|
|
typedef struct _HIDCLASS_PINGPONG *PHIDCLASS_PINGPONG;
|
|
typedef struct _HIDCLASS_REPORT *PHIDCLASS_REPORT;
|
|
typedef struct _FDO_EXTENSION *PFDO_EXTENSION;
|
|
typedef struct _PDO_EXTENSION *PPDO_EXTENSION;
|
|
|
|
|
|
#if DBG
|
|
#define LockFileExtension( f, i ) \
|
|
{ \
|
|
KeAcquireSpinLock( &(f)->ListSpinLock, (i) ); \
|
|
(f)->ListSpinLockTaken = TRUE; \
|
|
}
|
|
|
|
#define UnlockFileExtension(f, i) \
|
|
{ \
|
|
(f)->ListSpinLockTaken = FALSE; \
|
|
KeReleaseSpinLock( &(f)->ListSpinLock, (i) ); \
|
|
}
|
|
|
|
VOID DbgLogIntStart();
|
|
VOID DbgLogIntEnd();
|
|
#define DBGLOG_INTSTART() DbgLogIntStart();
|
|
#define DBGLOG_INTEND() DbgLogIntEnd();
|
|
|
|
VOID DbgTestGetDeviceString(PFDO_EXTENSION fdoExt);
|
|
VOID DbgTestGetIndexedString(PFDO_EXTENSION fdoExt);
|
|
|
|
#else
|
|
#define LockFileExtension(f, i) KeAcquireSpinLock(&(f)->ListSpinLock, (i));
|
|
#define UnlockFileExtension(f, i) KeReleaseSpinLock(&(f)->ListSpinLock, (i));
|
|
|
|
#define DBGLOG_INTSTART()
|
|
#define DBGLOG_INTEND()
|
|
#endif
|
|
|
|
#define HIDCLASS_POOL_TAG 'CdiH'
|
|
#define ALLOCATEPOOL(poolType, size) ExAllocatePoolWithTag((poolType), (size), HIDCLASS_POOL_TAG)
|
|
|
|
//
|
|
// 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(fdoExt) ((fdoExt)->deviceCapabilities.DeviceWake > PowerDeviceD0 && \
|
|
(fdoExt)->deviceCapabilities.SystemWake > PowerSystemWorking)
|
|
|
|
// #define WAITWAKE_ON(port) ((port)->WaitWakeIrp != 0)
|
|
#define REMOTEWAKE_ON(port) \
|
|
(InterlockedCompareExchangePointer(&(port)->remoteWakeIrp, NULL, NULL) != NULL)
|
|
|
|
BOOLEAN
|
|
HidpCheckRemoteWakeEnabled(
|
|
IN PPDO_EXTENSION PdoExt
|
|
);
|
|
|
|
#define SHOULD_SEND_WAITWAKE(pdoExt) (!(pdoExt)->MouseOrKeyboard && \
|
|
WAITWAKE_SUPPORTED(&(pdoExt)->deviceFdoExt->fdoExt) && \
|
|
!REMOTEWAKE_ON(pdoExt) && \
|
|
HidpCheckRemoteWakeEnabled(pdoExt))
|
|
|
|
/*
|
|
* String constants for use in compatible-id multi-string.
|
|
*/
|
|
// 0123456789 123456789 1234
|
|
#define HIDCLASS_COMPATIBLE_ID_STANDARD_NAME L"HID_DEVICE\0"
|
|
#define HIDCLASS_COMPATIBLE_ID_GENERIC_NAME L"HID_DEVICE_UP:%04x_U:%04x\0"
|
|
#define HIDCLASS_COMPATIBLE_ID_PAGE_OFFSET 14
|
|
#define HIDCLASS_COMPATIBLE_ID_USAGE_OFFSET 21
|
|
#define HIDCLASS_COMPATIBLE_ID_STANDARD_LENGTH 11
|
|
#define HIDCLASS_COMPATIBLE_ID_GENERIC_LENGTH 26
|
|
// 0123456789 123456789 123456
|
|
#define HIDCLASS_SYSTEM_KEYBOARD L"HID_DEVICE_SYSTEM_KEYBOARD\0"
|
|
#define HIDCLASS_SYSTEM_MOUSE L"HID_DEVICE_SYSTEM_MOUSE\0"
|
|
#define HIDCLASS_SYSTEM_GAMING_DEVICE L"HID_DEVICE_SYSTEM_GAME\0"
|
|
#define HIDCLASS_SYSTEM_CONTROL L"HID_DEVICE_SYSTEM_CONTROL\0"
|
|
#define HIDCLASS_SYSTEM_CONSUMER_DEVICE L"HID_DEVICE_SYSTEM_CONSUMER\0"
|
|
|
|
//
|
|
// String constant used to find out if selective suspend
|
|
// is supported on this device.
|
|
//
|
|
#define HIDCLASS_SELECTIVE_SUSPEND_ENABLED L"SelectiveSuspendEnabled\0"
|
|
#define HIDCLASS_SELECTIVE_SUSPEND_ON L"SelectiveSuspendOn\0"
|
|
#define HIDCLASS_REMOTE_WAKE_ENABLE L"RemoteWakeEnabled"
|
|
|
|
#define NO_STATUS 0x80000000 // this will never be a STATUS_xxx constant in NTSTATUS.H
|
|
|
|
#define HID_DEFAULT_IDLE_TIME 5 // in seconds
|
|
|
|
//
|
|
// Valid values for HIDCLASS_DEVICE_EXTENSION.state
|
|
//
|
|
enum deviceState {
|
|
DEVICE_STATE_INITIALIZED = 1,
|
|
DEVICE_STATE_STARTING,
|
|
DEVICE_STATE_START_SUCCESS,
|
|
DEVICE_STATE_START_FAILURE,
|
|
DEVICE_STATE_STOPPING,
|
|
DEVICE_STATE_STOPPED,
|
|
DEVICE_STATE_REMOVING,
|
|
DEVICE_STATE_REMOVED
|
|
};
|
|
|
|
enum collectionState {
|
|
COLLECTION_STATE_UNINITIALIZED = 1,
|
|
COLLECTION_STATE_INITIALIZED,
|
|
COLLECTION_STATE_RUNNING,
|
|
COLLECTION_STATE_STOPPING,
|
|
COLLECTION_STATE_STOPPED,
|
|
COLLECTION_STATE_REMOVING
|
|
};
|
|
|
|
|
|
//
|
|
// _HIDCLASS_DRIVER_EXTENSION contains per-minidriver extension information
|
|
// for the class driver. It is created upon a HidRegisterMinidriver() call.
|
|
//
|
|
|
|
typedef struct _HIDCLASS_DRIVER_EXTENSION {
|
|
|
|
//
|
|
// Pointer to the minidriver's driver object.
|
|
//
|
|
|
|
PDRIVER_OBJECT MinidriverObject;
|
|
|
|
//
|
|
// RegistryPath is a copy of the minidriver's RegistryPath that it
|
|
// received as a DriverEntry() parameter.
|
|
//
|
|
|
|
UNICODE_STRING RegistryPath;
|
|
|
|
//
|
|
// DeviceExtensionSize is the size of the minidriver's per-device
|
|
// extension.
|
|
//
|
|
|
|
ULONG DeviceExtensionSize;
|
|
|
|
//
|
|
// Dispatch routines for the minidriver. These are the only dispatch
|
|
// routines that the minidriver should ever care about, no others will
|
|
// be forwarded.
|
|
//
|
|
|
|
PDRIVER_DISPATCH MajorFunction[ IRP_MJ_MAXIMUM_FUNCTION + 1 ];
|
|
|
|
/*
|
|
* These are the minidriver's original entrypoints,
|
|
* to which we chain.
|
|
*/
|
|
PDRIVER_ADD_DEVICE AddDevice;
|
|
PDRIVER_UNLOAD DriverUnload;
|
|
|
|
//
|
|
// Number of pointers to this structure that we've handed out
|
|
//
|
|
|
|
LONG ReferenceCount;
|
|
|
|
//
|
|
// Linkage onto our global list of driver extensions
|
|
//
|
|
|
|
LIST_ENTRY ListEntry;
|
|
|
|
|
|
/*
|
|
* Either all or none of the devices driven by a given minidriver are polled.
|
|
*/
|
|
BOOLEAN DevicesArePolled;
|
|
|
|
|
|
#if DBG
|
|
|
|
ULONG Signature;
|
|
|
|
#endif
|
|
|
|
} HIDCLASS_DRIVER_EXTENSION;
|
|
|
|
#if DBG
|
|
#define HID_DRIVER_EXTENSION_SIG 'EdiH'
|
|
#endif
|
|
|
|
|
|
|
|
#define MIN_POLL_INTERVAL_MSEC 1
|
|
#define MAX_POLL_INTERVAL_MSEC 10000
|
|
#define DEFAULT_POLL_INTERVAL_MSEC 5
|
|
|
|
|
|
/*
|
|
* Device-specific flags
|
|
*/
|
|
// Nanao depends on a Win98G bug that allows GetFeature on input collection
|
|
#define DEVICE_FLAG_ALLOW_FEATURE_ON_NON_FEATURE_COLLECTION (1 << 0)
|
|
|
|
|
|
//
|
|
// HIDCLASS_COLLECTION is where we keep our per-collection information.
|
|
//
|
|
|
|
typedef struct _HIDCLASS_COLLECTION {
|
|
|
|
|
|
ULONG CollectionNumber;
|
|
ULONG CollectionIndex;
|
|
|
|
//
|
|
// NumOpens is a count of open handles against this collection.
|
|
//
|
|
|
|
ULONG NumOpens;
|
|
|
|
// Number of pending reads for all clients on this collection.
|
|
ULONG numPendingReads;
|
|
|
|
//
|
|
// FileExtensionList is the head of a list of file extensions, i.e.
|
|
// open instances against this collection.
|
|
//
|
|
|
|
LIST_ENTRY FileExtensionList;
|
|
KSPIN_LOCK FileExtensionListSpinLock;
|
|
|
|
/*
|
|
* For polled devices, we only read from the device
|
|
* once every poll interval. We queue read IRPs
|
|
* here until the poll timer expiration.
|
|
*
|
|
* Note: for a polled device, we keep a separate background
|
|
* loop for each collection. This way, queued-up read IRPs
|
|
* remain associated with the right collection.
|
|
* Also, this will keep the number of reads we do on each
|
|
* timer period roughly equal to the number of collections.
|
|
*/
|
|
ULONG PollInterval_msec;
|
|
KTIMER polledDeviceTimer;
|
|
KDPC polledDeviceTimerDPC;
|
|
LIST_ENTRY polledDeviceReadQueue;
|
|
KSPIN_LOCK polledDeviceReadQueueSpinLock;
|
|
|
|
/*
|
|
* We save old reports on polled devices for
|
|
* "opportunistic" readers who want to get a result right away.
|
|
* The polledDataIsStale flag indicates that the saved report
|
|
* is at least one poll interval old (so we should not use it).
|
|
*/
|
|
PUCHAR savedPolledReportBuf;
|
|
ULONG savedPolledReportLen;
|
|
BOOLEAN polledDataIsStale;
|
|
|
|
UNICODE_STRING SymbolicLinkName;
|
|
UNICODE_STRING SymbolicLinkName_SystemControl;
|
|
|
|
/*
|
|
* HID collection information descriptor for this collection.
|
|
*/
|
|
HID_COLLECTION_INFORMATION hidCollectionInfo;
|
|
PHIDP_PREPARSED_DATA phidDescriptor;
|
|
|
|
/*
|
|
* This buffer is used to "cook" a raw report when it's been received.
|
|
* This is only used for non-polled (interrupt) devices.
|
|
*/
|
|
PUCHAR cookedInterruptReportBuf;
|
|
|
|
/*
|
|
* This is an IRP that we queue and complete
|
|
* when a read report contains a power event.
|
|
*
|
|
* The powerEventIrp field retains an IRP
|
|
* so it needs a spinlock to synchronize cancellation.
|
|
*/
|
|
PIRP powerEventIrp;
|
|
KSPIN_LOCK powerEventSpinLock;
|
|
|
|
ULONG secureReadMode;
|
|
KSPIN_LOCK secureReadLock;
|
|
|
|
#if DBG
|
|
ULONG Signature;
|
|
#endif
|
|
|
|
} HIDCLASS_COLLECTION;
|
|
|
|
#if DBG
|
|
#define HIDCLASS_COLLECTION_SIG 'EccH'
|
|
#endif
|
|
|
|
//
|
|
// For HID devices that have at least one interrupt-style collection, we
|
|
// try to keep a set of "ping-pong" report-read IRPs pending in the minidriver
|
|
// in the event we get a report.
|
|
//
|
|
// HIDCLASS_PINGPONG contains a pointer to an IRP as well as an event
|
|
// and status block. Each device has a pointer to an array of these structures,
|
|
// the array size depending on the number of such IRPs we want to keep in
|
|
// motion.
|
|
//
|
|
// Right now the default number is 2.
|
|
//
|
|
|
|
#define MIN_PINGPONG_IRPS 2
|
|
|
|
//
|
|
// Flags to indicate whether read completed synchronously or asynchronously
|
|
//
|
|
#define PINGPONG_START_READ 0x01
|
|
#define PINGPONG_END_READ 0x02
|
|
#define PINGPONG_IMMEDIATE_READ 0x03
|
|
|
|
typedef struct _HIDCLASS_PINGPONG {
|
|
|
|
#define PINGPONG_SIG (ULONG)'gnoP'
|
|
ULONG sig;
|
|
|
|
//
|
|
// Read interlock value to protect us from running out of stack space
|
|
//
|
|
ULONG ReadInterlock;
|
|
|
|
PIRP irp;
|
|
PUCHAR reportBuffer;
|
|
LONG weAreCancelling;
|
|
|
|
KEVENT sentEvent; // When a read has been sent.
|
|
KEVENT pumpDoneEvent; // When the read loop is finally exitting.
|
|
|
|
PFDO_EXTENSION myFdoExt;
|
|
|
|
/*
|
|
* Timeout context for back-off algorithm applied to broken devices.
|
|
*/
|
|
KTIMER backoffTimer;
|
|
KDPC backoffTimerDPC;
|
|
LARGE_INTEGER backoffTimerPeriod; // in negative 100-nsec units
|
|
|
|
} HIDCLASS_PINGPONG;
|
|
|
|
#if DBG
|
|
#define HIDCLASS_REPORT_BUFFER_GUARD 'draG'
|
|
#endif
|
|
|
|
//
|
|
// All possible idle states.
|
|
//
|
|
#define IdleUninitialized 0x0
|
|
#define IdleDisabled 0x1
|
|
#define IdleWaiting 0x2
|
|
#define IdleIrpSent 0x3
|
|
#define IdleCallbackReceived 0x4
|
|
#define IdleComplete 0x5
|
|
|
|
/*
|
|
* Stores information about a Functional Device Object (FDO) which HIDCLASS attaches
|
|
* to the top of the Physical Device Object (PDO) that it get from the minidriver below.
|
|
*/
|
|
typedef struct _FDO_EXTENSION {
|
|
|
|
//
|
|
// Back pointer to the functional device object
|
|
//
|
|
PDEVICE_OBJECT fdo;
|
|
|
|
//
|
|
// HidDriverExtension is a pointer to our driver extension for the
|
|
// minidriver that gave us the PDO.
|
|
//
|
|
|
|
PHIDCLASS_DRIVER_EXTENSION driverExt;
|
|
|
|
//
|
|
// Hid descriptor that we get from the device.
|
|
//
|
|
|
|
HID_DESCRIPTOR hidDescriptor; // 9 bytes
|
|
|
|
//
|
|
// The attributes of this hid device.
|
|
//
|
|
|
|
HID_DEVICE_ATTRIBUTES hidDeviceAttributes; // 0x20 bytes
|
|
|
|
//
|
|
// Pointer to and length of the raw report descriptor.
|
|
//
|
|
|
|
PUCHAR rawReportDescription;
|
|
ULONG rawReportDescriptionLength;
|
|
|
|
//
|
|
// This device has one or more collections. We store the count and
|
|
// pointer to an array of our HIDCLASS_COLLECTION structures (one per
|
|
// collection) here.
|
|
//
|
|
|
|
PHIDCLASS_COLLECTION classCollectionArray;
|
|
|
|
/*
|
|
* This is initialized for us by HIDPARSE's HidP_GetCollectionDescription().
|
|
* It includes an array of HIDP_COLLECTION_DESC structs corresponding
|
|
* the classCollectionArray declared above.
|
|
*/
|
|
HIDP_DEVICE_DESC deviceDesc; // 0x30 bytes
|
|
BOOLEAN devDescInitialized;
|
|
|
|
//
|
|
// The maximum input size amongst ALL report types.
|
|
//
|
|
ULONG maxReportSize;
|
|
|
|
//
|
|
// For devices that have at least one interrupt collection, we keep
|
|
// a couple of ping-pong IRPs and associated structures.
|
|
// The ping-pong IRPs ferry data up from the USB hub.
|
|
//
|
|
ULONG numPingPongs;
|
|
PHIDCLASS_PINGPONG pingPongs;
|
|
|
|
//
|
|
// OpenCount represents the number of file objects aimed at this device
|
|
//
|
|
ULONG openCount;
|
|
|
|
|
|
/*
|
|
* This is the number of IRPs still outstanding in the minidriver.
|
|
*/
|
|
|
|
ULONG outstandingRequests;
|
|
|
|
enum deviceState prevState;
|
|
enum deviceState state;
|
|
|
|
UNICODE_STRING name;
|
|
|
|
/*
|
|
* deviceRelations contains an array of client PDO pointers.
|
|
*
|
|
* As the HID bus driver, HIDCLASS produces this data structure to report
|
|
* collection-PDOs to the system.
|
|
*/
|
|
PDEVICE_RELATIONS deviceRelations;
|
|
|
|
/*
|
|
* This is an array of device extensions for the collection-PDOs of this
|
|
* device-FDO.
|
|
*/
|
|
PHIDCLASS_DEVICE_EXTENSION *collectionPdoExtensions;
|
|
|
|
|
|
/*
|
|
* This includes a
|
|
* table mapping system power states to device power states.
|
|
*/
|
|
DEVICE_CAPABILITIES deviceCapabilities;
|
|
|
|
/*
|
|
* Track both current system and device power state
|
|
*/
|
|
SYSTEM_POWER_STATE systemPowerState;
|
|
DEVICE_POWER_STATE devicePowerState;
|
|
|
|
/*
|
|
* Wait Wake Irp sent to parent PDO
|
|
*/
|
|
PIRP waitWakeIrp;
|
|
KSPIN_LOCK waitWakeSpinLock;
|
|
BOOLEAN isWaitWakePending;
|
|
|
|
/*
|
|
* Queue of delayed requests due to the stack being in low power
|
|
*/
|
|
KSPIN_LOCK collectionPowerDelayedIrpQueueSpinLock;
|
|
LIST_ENTRY collectionPowerDelayedIrpQueue;
|
|
ULONG numPendingPowerDelayedIrps;
|
|
|
|
BOOLEAN isOutputOnlyDevice;
|
|
|
|
//
|
|
// Selective suspend idling context.
|
|
//
|
|
HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO idleCallbackInfo;
|
|
|
|
LONG idleState;
|
|
PULONG idleTimeoutValue;
|
|
KSPIN_LOCK idleNotificationSpinLock;
|
|
PIRP idleNotificationRequest;
|
|
BOOLEAN idleCancelling;
|
|
BOOLEAN idleEnabledInRegistry;
|
|
BOOLEAN idleEnabled;
|
|
KSPIN_LOCK idleSpinLock;
|
|
|
|
KEVENT idleDoneEvent; // When the idle notification irp has been cancelled successfully.
|
|
|
|
LONG numIdlePdos;
|
|
|
|
/*
|
|
* This is a list of WaitWake IRPs sent to the collection-PDOs
|
|
* on this device, which we just save and complete when the
|
|
* base device's WaitWake IRP completes.
|
|
*/
|
|
LIST_ENTRY collectionWaitWakeIrpQueue;
|
|
KSPIN_LOCK collectionWaitWakeIrpQueueSpinLock;
|
|
|
|
struct _FDO_EXTENSION *nextFdoExt;
|
|
|
|
/*
|
|
* Device-specific flags (DEVICE_FLAG_xxx).
|
|
*/
|
|
ULONG deviceSpecificFlags;
|
|
|
|
/*
|
|
* This is our storage space for the systemState IRP that we need to hold
|
|
* on to and complete in DevicePowerRequestCompletion.
|
|
*/
|
|
PIRP currentSystemStateIrp;
|
|
|
|
/*
|
|
* Unique number assigned to identify this HID bus.
|
|
*/
|
|
ULONG BusNumber;
|
|
|
|
//
|
|
// WMI Information
|
|
//
|
|
WMILIB_CONTEXT WmiLibInfo;
|
|
|
|
|
|
|
|
#if DBG
|
|
WCHAR dbgDriverKeyName[64];
|
|
#endif
|
|
|
|
|
|
} FDO_EXTENSION;
|
|
|
|
|
|
/*
|
|
* Stores information about a Physical Device Object (PDO) which HIDCLASS creates
|
|
* for each HID device-collection.
|
|
*/
|
|
typedef struct _PDO_EXTENSION {
|
|
|
|
enum collectionState prevState;
|
|
enum collectionState state;
|
|
|
|
ULONG collectionNum;
|
|
ULONG collectionIndex;
|
|
|
|
//
|
|
// 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;
|
|
|
|
// represents a collection on the HID "bus"
|
|
PDEVICE_OBJECT pdo;
|
|
PUNICODE_STRING name;
|
|
|
|
/*
|
|
* This is a back-pointer to the original FDO's extension.
|
|
*/
|
|
PHIDCLASS_DEVICE_EXTENSION deviceFdoExt;
|
|
|
|
/*
|
|
* Track both current system and device power state
|
|
*/
|
|
SYSTEM_POWER_STATE systemPowerState;
|
|
DEVICE_POWER_STATE devicePowerState;
|
|
BOOLEAN remoteWakeEnabled;
|
|
KSPIN_LOCK remoteWakeSpinLock;
|
|
PIRP remoteWakeIrp;
|
|
PIRP waitWakeIrp;
|
|
|
|
/*
|
|
* The status change function that was registered thru query interface
|
|
* NOTE: Can currently only register one.
|
|
*/
|
|
PHID_STATUS_CHANGE StatusChangeFn;
|
|
PVOID StatusChangeContext;
|
|
|
|
/*
|
|
* Access protection information.
|
|
* We count the number of opens for read and write on the collection.
|
|
* We also count the number of opens which RESTRICT future
|
|
* read/write opens on the collection.
|
|
*
|
|
* Note that desired access is independent of restriction.
|
|
* A client may, for example, do an open-for-read-only but
|
|
* (by not setting the FILE_SHARE_WRITE bit)
|
|
* restrict other clients from doing an open-for-write.
|
|
*/
|
|
ULONG openCount;
|
|
ULONG opensForRead;
|
|
ULONG opensForWrite;
|
|
ULONG restrictionsForRead;
|
|
ULONG restrictionsForWrite;
|
|
ULONG restrictionsForAnyOpen;
|
|
BOOLEAN MouseOrKeyboard;
|
|
|
|
//
|
|
// WMI Information
|
|
//
|
|
WMILIB_CONTEXT WmiLibInfo;
|
|
|
|
} PDO_EXTENSION;
|
|
|
|
|
|
/*
|
|
* This contains info about either a device FDO or a device-collection PDO.
|
|
* Some of the same functions process both, so we need one structure.
|
|
*/
|
|
typedef struct _HIDCLASS_DEVICE_EXTENSION {
|
|
|
|
/*
|
|
* This is the public part of a HID FDO device extension, and
|
|
* must be the first entry in this structure.
|
|
*/
|
|
HID_DEVICE_EXTENSION hidExt; // size== 0x0C.
|
|
|
|
/*
|
|
* Determines whether this is a device extension for a device-FDO or a
|
|
* device-collection-PDO; this resolves the following union.
|
|
*/
|
|
BOOLEAN isClientPdo;
|
|
|
|
/*
|
|
* Include this signature for both debug and retail --
|
|
* kenray's debug extensions look for this.
|
|
*/
|
|
#define HID_DEVICE_EXTENSION_SIG 'EddH'
|
|
ULONG Signature;
|
|
|
|
union {
|
|
FDO_EXTENSION fdoExt;
|
|
PDO_EXTENSION pdoExt;
|
|
};
|
|
|
|
|
|
} HIDCLASS_DEVICE_EXTENSION;
|
|
|
|
|
|
|
|
//
|
|
// HIDCLASS_FILE_EXTENSION is private data we keep per file object.
|
|
//
|
|
|
|
typedef struct _HIDCLASS_FILE_EXTENSION {
|
|
|
|
//
|
|
// CollectionNumber is the ordinal of the collection in the device
|
|
//
|
|
|
|
ULONG CollectionNumber;
|
|
|
|
|
|
PFDO_EXTENSION fdoExt;
|
|
|
|
//
|
|
// PendingIrpList is a list of READ IRPs currently waiting to be satisfied.
|
|
//
|
|
|
|
LIST_ENTRY PendingIrpList;
|
|
|
|
//
|
|
// ReportList is a list of reports waiting to be read on this handle.
|
|
//
|
|
|
|
LIST_ENTRY ReportList;
|
|
|
|
//
|
|
// FileList provides a way to link all of a collection's
|
|
// file extensions together.
|
|
//
|
|
|
|
LIST_ENTRY FileList;
|
|
|
|
//
|
|
// Both PendingIrpList and ReportList are protected by the same spinlock,
|
|
// ListSpinLock.
|
|
//
|
|
KSPIN_LOCK ListSpinLock;
|
|
|
|
//
|
|
// MaximumInputReportAge is only applicable for polled collections.
|
|
// It represents the maximum acceptable input report age for this handle.
|
|
// There is a value in the HIDCLASS_COLLECTION,
|
|
// CurrentMaximumInputReportAge, that represents the current minimum value
|
|
// of all of the file extensions open against the collection.
|
|
//
|
|
|
|
LARGE_INTEGER MaximumInputReportAge;
|
|
|
|
//
|
|
// CurrentInputReportQueueSize is the current size of the report input
|
|
// queue.
|
|
//
|
|
|
|
ULONG CurrentInputReportQueueSize;
|
|
|
|
/*
|
|
* This is the maximum number of reports that will be queued for the file extension.
|
|
* This starts at a default value and can be adjusted (within a fixed range) by an IOCTL.
|
|
*/
|
|
ULONG MaximumInputReportQueueSize;
|
|
#define MIN_INPUT_REPORT_QUEUE_SIZE MIN_PINGPONG_IRPS
|
|
#define MAX_INPUT_REPORT_QUEUE_SIZE (MIN_INPUT_REPORT_QUEUE_SIZE*256)
|
|
#define DEFAULT_INPUT_REPORT_QUEUE_SIZE (MIN_INPUT_REPORT_QUEUE_SIZE*16)
|
|
|
|
//
|
|
// Back pointer to the file object that this extension is for
|
|
//
|
|
|
|
PFILE_OBJECT FileObject;
|
|
|
|
|
|
/*
|
|
* File-attributes passed in irpSp->Parameters.Create.FileAttributes
|
|
* when this open was made.
|
|
*/
|
|
USHORT FileAttributes;
|
|
ACCESS_MASK accessMask;
|
|
USHORT shareMask;
|
|
|
|
//
|
|
// Closing is set when this file object is closing and will be removed
|
|
// shortly. Don't queue any more reports or IRPs to this object
|
|
// when this flag is set.
|
|
//
|
|
|
|
BOOLEAN Closing;
|
|
|
|
//
|
|
// Security has been checked.
|
|
//
|
|
|
|
BOOLEAN SecurityCheck;
|
|
|
|
//
|
|
// DWORD allignment
|
|
//
|
|
BOOLEAN Reserved [2];
|
|
|
|
/*
|
|
* This flag indicates that this client does irregular, opportunistic
|
|
* reads on the device, which is a polled device.
|
|
* Instead of waiting for the background timer-driven read loop,
|
|
* this client should have his reads completed immediately.
|
|
*/
|
|
BOOLEAN isOpportunisticPolledDeviceReader;
|
|
ULONG nowCompletingIrpForOpportunisticReader;
|
|
|
|
|
|
/*
|
|
* haveReadPrivilege TRUE indicates that the client has full
|
|
* permissions on the device, including read.
|
|
*/
|
|
BOOLEAN haveReadPrivilege;
|
|
|
|
//
|
|
// Memphis Blue Screen info
|
|
//
|
|
BLUESCREEN BlueScreenData;
|
|
|
|
BOOLEAN isSecureOpen;
|
|
ULONG SecureReadMode;
|
|
|
|
/*
|
|
* If a read fails, some clients reissue the read on the same thread.
|
|
* If this happens repeatedly, we can run out of stack space.
|
|
* So we keep track of the depth
|
|
*/
|
|
#define INSIDE_READCOMPLETE_MAX 4
|
|
ULONG insideReadCompleteCount;
|
|
|
|
#if DBG
|
|
BOOLEAN ListSpinLockTaken;
|
|
ULONG dbgNumReportsDroppedSinceLastRead;
|
|
ULONG Signature;
|
|
#endif
|
|
|
|
} HIDCLASS_FILE_EXTENSION;
|
|
|
|
#if DBG
|
|
#define HIDCLASS_FILE_EXTENSION_SIG 'efcH'
|
|
#endif
|
|
|
|
|
|
typedef struct {
|
|
|
|
#define ASYNC_COMPLETE_CONTEXT_SIG 'cnsA'
|
|
ULONG sig;
|
|
|
|
WORK_QUEUE_ITEM workItem;
|
|
PIRP irp;
|
|
PDEVICE_OBJECT devObj;
|
|
} ASYNC_COMPLETE_CONTEXT;
|
|
|
|
|
|
//
|
|
// HIDCLASS_REPORT is the structure we use to track a report returned from
|
|
// the minidriver.
|
|
//
|
|
|
|
typedef struct _HIDCLASS_REPORT {
|
|
|
|
//
|
|
// ListEntry queues this report onto a file extension.
|
|
//
|
|
|
|
LIST_ENTRY ListEntry;
|
|
|
|
ULONG reportLength;
|
|
//
|
|
// UnparsedReport is a data area for the unparsed report data as returned
|
|
// from the minidriver. The lengths of all input reports for a given
|
|
// class are the same, so we don't need to store the length in each
|
|
// report.
|
|
//
|
|
|
|
UCHAR UnparsedReport[];
|
|
|
|
} HIDCLASS_REPORT;
|
|
|
|
typedef struct _HIDCLASS_WORK_ITEM_DATA {
|
|
PIRP Irp;
|
|
PDO_EXTENSION *PdoExt;
|
|
PIO_WORKITEM Item;
|
|
BOOLEAN RemoteWakeState;
|
|
} HIDCLASS_WORK_ITEM_DATA, *PHIDCLASS_WORK_ITEM_DATA;
|
|
|
|
//
|
|
// Internal shared function prototypes
|
|
//
|
|
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
|
|
NTSTATUS HidpAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject);
|
|
VOID HidpDriverUnload(IN struct _DRIVER_OBJECT *minidriverObject);
|
|
NTSTATUS HidpCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
|
NTSTATUS HidpCallDriverSynchronous(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
|
NTSTATUS HidpCopyInputReportToUser(IN PHIDCLASS_FILE_EXTENSION fdoExtension, IN PUCHAR ReportData, IN OUT PULONG UserBufferLen, OUT PUCHAR UserBuffer);
|
|
NTSTATUS HidpCreateSymbolicLink(IN PDO_EXTENSION *pdoExtension, IN ULONG collectionNum, IN BOOLEAN Create, IN PDEVICE_OBJECT Pdo);
|
|
NTSTATUS HidpCreateClientPDOs(PHIDCLASS_DEVICE_EXTENSION hidClassExtension);
|
|
ULONG HidpSetMaxReportSize(IN FDO_EXTENSION *fdoExtension);
|
|
VOID EnqueueInterruptReport(PHIDCLASS_FILE_EXTENSION fileExtension, PHIDCLASS_REPORT report);
|
|
PHIDCLASS_REPORT DequeueInterruptReport(PHIDCLASS_FILE_EXTENSION fileExtension, LONG maxLen);
|
|
VOID HidpDestroyFileExtension(PHIDCLASS_COLLECTION collection, PHIDCLASS_FILE_EXTENSION FileExtension);
|
|
VOID HidpFlushReportQueue(IN PHIDCLASS_FILE_EXTENSION FileExtension);
|
|
NTSTATUS HidpGetCollectionDescriptor(IN FDO_EXTENSION *fdoExtension, IN ULONG collectionId, IN PVOID Buffer, IN OUT PULONG BufferSize);
|
|
NTSTATUS HidpGetCollectionInformation(IN FDO_EXTENSION *fdoExtension, IN ULONG collectionNumber, IN PVOID Buffer, IN OUT PULONG BufferSize);
|
|
NTSTATUS HidpGetDeviceDescriptor(FDO_EXTENSION *fdoExtension);
|
|
BOOLEAN HidpStartIdleTimeout(FDO_EXTENSION *fdoExt, BOOLEAN DeviceStart);
|
|
VOID HidpCancelIdleNotification(FDO_EXTENSION *fdoExt, BOOLEAN removing);
|
|
VOID HidpIdleTimeWorker(PDEVICE_OBJECT DeviceObject, PIO_WORKITEM Item);
|
|
VOID HidpIdleNotificationCallback(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension);
|
|
NTSTATUS HidpRegisterDeviceForIdleDetection(PDEVICE_OBJECT DeviceObject, ULONG IdleTime, PULONG *);
|
|
VOID HidpSetDeviceBusy(FDO_EXTENSION *fdoExt);
|
|
NTSTATUS HidpCheckIdleState(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension,PIRP Irp);
|
|
NTSTATUS HidpGetRawDeviceDescriptor(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, OUT PULONG RawDeviceDescriptorLength, OUT PUCHAR *RawDeviceDescriptor);
|
|
NTSTATUS HidpInitializePingPongIrps(FDO_EXTENSION *fdoExtension);
|
|
NTSTATUS HidpReallocPingPongIrps(FDO_EXTENSION *fdoExtension, ULONG newNumBufs);
|
|
NTSTATUS HidpIrpMajorPnpComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
|
|
NTSTATUS HidpMajorHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
|
NTSTATUS HidpParseAndBuildLinks(FDO_EXTENSION *fdoExtension);
|
|
NTSTATUS HidpFdoPowerCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
|
|
BOOLEAN EnqueueDriverExt(PHIDCLASS_DRIVER_EXTENSION driverExt);
|
|
PHIDCLASS_DRIVER_EXTENSION RefDriverExt(IN PDRIVER_OBJECT MinidriverObject);
|
|
PHIDCLASS_DRIVER_EXTENSION DerefDriverExt(IN PDRIVER_OBJECT MinidriverObject);
|
|
NTSTATUS HidpStartAllPingPongs(FDO_EXTENSION *fdoExtension);
|
|
ULONG HidiGetClassCollectionOrdinal(IN PHIDCLASS_COLLECTION ClassCollection);
|
|
PHIDP_COLLECTION_DESC HidiGetHidCollectionByClassCollection(IN PHIDCLASS_COLLECTION ClassCollection);
|
|
PHIDP_REPORT_IDS GetReportIdentifier(FDO_EXTENSION *fdoExtension, ULONG reportId);
|
|
PHIDP_COLLECTION_DESC GetCollectionDesc(FDO_EXTENSION *fdoExtension, ULONG collectionId);
|
|
PHIDCLASS_COLLECTION GetHidclassCollection(FDO_EXTENSION *fdoExtension, ULONG collectionId);
|
|
//NTSTATUS HidpGetSetFeature(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp, IN ULONG controlCode, OUT BOOLEAN *sentIrp);
|
|
NTSTATUS HidpGetSetReport(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp, IN ULONG controlCode, OUT BOOLEAN *sentIrp);
|
|
NTSTATUS HidpGetDeviceString(IN FDO_EXTENSION *fdoExt, IN OUT PIRP Irp, IN ULONG stringId, IN ULONG languageId);
|
|
NTSTATUS HidpGetPhysicalDescriptor(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorRead(IN PHIDCLASS_DEVICE_EXTENSION, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorCreate(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorWrite(IN PHIDCLASS_DEVICE_EXTENSION, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorPnp(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpPdoPnp(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpFdoPnp(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorPower(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorClose(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorDeviceControl(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorINTERNALDeviceControl(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorClose(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpIrpMajorDefault(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpInterruptReadComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
|
|
NTSTATUS HidpQueryDeviceRelations(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpQueryCollectionCapabilities(PDO_EXTENSION *pdoExt, IN OUT PIRP Irp);
|
|
NTSTATUS HidpQueryIdForClientPdo(IN PHIDCLASS_DEVICE_EXTENSION hidClassExtension, IN OUT PIRP Irp);
|
|
NTSTATUS HidpQueryInterface(IN PHIDCLASS_DEVICE_EXTENSION hidClassExtension, IN OUT PIRP Irp);
|
|
PVOID MemDup(POOL_TYPE PoolType, PVOID dataPtr, ULONG length);
|
|
BOOLEAN AllClientPDOsInitialized(FDO_EXTENSION *fdoExtension, BOOLEAN initialized);
|
|
BOOLEAN AnyClientPDOsInitialized(FDO_EXTENSION *fdoExtension, BOOLEAN initialized);
|
|
NTSTATUS ClientPdoCompletion(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, PIRP Irp);
|
|
BOOLEAN HidpDeleteDeviceObjects(FDO_EXTENSION *fdoExt);
|
|
VOID HidpCancelReadIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
|
VOID CancelAllPingPongIrps(FDO_EXTENSION *fdoExt);
|
|
VOID HidpCleanUpFdo(FDO_EXTENSION *fdoExt);
|
|
NTSTATUS HidpRemoveDevice(FDO_EXTENSION *fdoExt, IN PIRP Irp);
|
|
VOID HidpRemoveCollection(FDO_EXTENSION *fdoExt, PDO_EXTENSION *pdoExt, IN PIRP Irp);
|
|
VOID HidpDestroyCollection(FDO_EXTENSION *fdoExt, PHIDCLASS_COLLECTION Collection);
|
|
VOID CollectionPowerRequestCompletion(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus);
|
|
VOID DevicePowerRequestCompletion(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus);
|
|
NTSTATUS HidpQueryCapsCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
|
|
NTSTATUS HidpQueryDeviceCapabilities(IN PDEVICE_OBJECT PdoDeviceObject, IN PDEVICE_CAPABILITIES DeviceCapabilities);
|
|
VOID DestroyPingPongs(FDO_EXTENSION *fdoExt);
|
|
VOID CheckReportPowerEvent(FDO_EXTENSION *fdoExt, PHIDCLASS_COLLECTION collection, PUCHAR report, ULONG reportLen);
|
|
BOOLEAN StartPollingLoop(FDO_EXTENSION *fdoExt, PHIDCLASS_COLLECTION hidCollection, BOOLEAN freshQueue);
|
|
VOID StopPollingLoop(PHIDCLASS_COLLECTION hidCollection, BOOLEAN flushQueue);
|
|
BOOLEAN ReadPolledDevice(PDO_EXTENSION *pdoExt, BOOLEAN isTimerDrivenRead);
|
|
VOID PolledReadCancelRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
|
VOID EnqueueFdoExt(FDO_EXTENSION *fdoExt);
|
|
VOID DequeueFdoExt(FDO_EXTENSION *fdoExt);
|
|
NTSTATUS AllocDeviceResources(FDO_EXTENSION *fdoExt);
|
|
VOID FreeDeviceResources(FDO_EXTENSION *fdoExt);
|
|
NTSTATUS AllocCollectionResources(FDO_EXTENSION *fdoExt, ULONG collectionNum);
|
|
VOID FreeCollectionResources(FDO_EXTENSION *fdoExt, ULONG collectionNum);
|
|
NTSTATUS InitializeCollection(FDO_EXTENSION *fdoExt, ULONG collectionIndex);
|
|
NTSTATUS HidpStartCollectionPDO(FDO_EXTENSION *fdoExt, PDO_EXTENSION *pdoExt, PIRP Irp);
|
|
NTSTATUS HidpStartDevice(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, PIRP Irp);
|
|
PWCHAR SubstituteBusNames(PWCHAR oldIDs, FDO_EXTENSION *fdoExt, PDO_EXTENSION *pdoExt);
|
|
PWSTR BuildCompatibleID(PHIDCLASS_DEVICE_EXTENSION hidClassExtension);
|
|
PUNICODE_STRING MakeClientPDOName(PUNICODE_STRING fdoName, ULONG collectionId);
|
|
VOID HidpPingpongBackoffTimerDpc(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
|
|
BOOLEAN WStrCompareN(PWCHAR str1, PWCHAR str2, ULONG maxChars);
|
|
NTSTATUS SubmitWaitWakeIrp(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension);
|
|
BOOLEAN HidpIsWaitWakePending(FDO_EXTENSION *fdoExt, BOOLEAN setIfNotPending);
|
|
NTSTATUS HidpWaitWakeComplete(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus);
|
|
NTSTATUS HidpGetIndexedString(IN FDO_EXTENSION *fdoExt, IN OUT PIRP Irp, IN ULONG stringIndex, IN ULONG languageId);
|
|
VOID CompleteAllPendingReadsForCollection(PHIDCLASS_COLLECTION Collection);
|
|
VOID CompleteAllPendingReadsForFileExtension(PHIDCLASS_COLLECTION Collection, PHIDCLASS_FILE_EXTENSION fileExtension);
|
|
VOID CompleteAllPendingReadsForDevice(FDO_EXTENSION *fdoExt);
|
|
BOOLEAN MyPrivilegeCheck(PIRP Irp);
|
|
NTSTATUS QueuePowerEventIrp(PHIDCLASS_COLLECTION hidCollection, PIRP Irp);
|
|
VOID PowerEventCancelRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
|
NTSTATUS HidpPolledReadComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
|
|
NTSTATUS HidpPolledReadComplete_TimerDriven(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
|
|
VOID CollectionWaitWakeIrpCancelRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
|
VOID CompleteAllCollectionWaitWakeIrps(FDO_EXTENSION *fdoExt, NTSTATUS status);
|
|
VOID PowerDelayedCancelRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
|
|
NTSTATUS EnqueuePowerDelayedIrp(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, PIRP Irp);
|
|
PIRP DequeuePowerDelayedIrp(FDO_EXTENSION *fdoExt);
|
|
ULONG DequeueAllPdoPowerDelayedIrps(PDO_EXTENSION *pdoExt, PLIST_ENTRY dequeue);
|
|
VOID ReadDeviceFlagsFromRegistry(FDO_EXTENSION *fdoExt, PDEVICE_OBJECT pdo);
|
|
LONG WStrNCmpI(PWCHAR s1, PWCHAR s2, ULONG n);
|
|
ULONG LAtoX(PWCHAR wHexString);
|
|
ULONG WStrNCpy(PWCHAR dest, PWCHAR src, ULONG n);
|
|
NTSTATUS OpenSubkey(OUT PHANDLE Handle, IN HANDLE BaseHandle, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess);
|
|
void HidpNumberToString(PWCHAR String, USHORT Number, USHORT stringLen);
|
|
NTSTATUS GetHIDRawReportDescriptor(FDO_EXTENSION *fdoExt, PIRP irp, ULONG descriptorLen);
|
|
VOID WorkItemCallback_CompleteIrpAsynchronously(PVOID context);
|
|
NTSTATUS EnqueueInterruptReadIrp(PHIDCLASS_COLLECTION collection, PHIDCLASS_FILE_EXTENSION fileExtension, PIRP Irp);
|
|
PIRP DequeueInterruptReadIrp(PHIDCLASS_COLLECTION collection, PHIDCLASS_FILE_EXTENSION fileExtension);
|
|
NTSTATUS EnqueuePolledReadIrp(PHIDCLASS_COLLECTION collection, PIRP Irp);
|
|
PIRP DequeuePolledReadSystemIrp(PHIDCLASS_COLLECTION collection);
|
|
PIRP DequeuePolledReadIrp(PHIDCLASS_COLLECTION collection);
|
|
NTSTATUS HidpProcessInterruptReport(PHIDCLASS_COLLECTION collection, PHIDCLASS_FILE_EXTENSION FileExtension, PUCHAR Report, ULONG ReportLength, PIRP *irpToComplete);
|
|
VOID HidpFreePowerEventIrp(PHIDCLASS_COLLECTION Collection);
|
|
NTSTATUS HidpGetMsGenreDescriptor(IN FDO_EXTENSION *fdoExt, IN OUT PIRP Irp);
|
|
NTSTATUS DllUnload(VOID);
|
|
NTSTATUS DllInitialize (PUNICODE_STRING RegistryPath);
|
|
VOID HidpPowerUpPdos(IN PFDO_EXTENSION fdoExt);
|
|
NTSTATUS HidpDelayedPowerPoRequestComplete(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus);
|
|
NTSTATUS HidpIrpMajorSystemControl(PHIDCLASS_DEVICE_EXTENSION DeviceObject, PIRP Irp);
|
|
NTSTATUS HidpSetWmiDataItem(PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG GuidIndex, ULONG InstanceIndex, ULONG DataItemId, ULONG BufferSize, PUCHAR Buffer);
|
|
NTSTATUS HidpSetWmiDataBlock(PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG GuidIndex, ULONG InstanceIndex, ULONG BufferSize, PUCHAR Buffer);
|
|
NTSTATUS HidpQueryWmiDataBlock( PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG GuidIndex, ULONG InstanceIndex, ULONG InstanceCount, OUT PULONG InstanceLengthArray, ULONG BufferAvail, PUCHAR Buffer);
|
|
NTSTATUS HidpQueryWmiRegInfo( PDEVICE_OBJECT DeviceObject, ULONG *RegFlags, PUNICODE_STRING InstanceName, PUNICODE_STRING *RegistryPath, PUNICODE_STRING MofResourceName, PDEVICE_OBJECT *Pdo);
|
|
BOOLEAN HidpCreateRemoteWakeIrp (PDO_EXTENSION *PdoExt);
|
|
void HidpCreateRemoteWakeIrpWorker (PDEVICE_OBJECT DeviceObject, PHIDCLASS_WORK_ITEM_DATA ItemData);
|
|
NTSTATUS HidpToggleRemoteWake(PDO_EXTENSION *PdoExt, BOOLEAN RemoteWakeState);
|
|
|
|
#if DBG
|
|
VOID InitFdoExtDebugInfo(PHIDCLASS_DEVICE_EXTENSION hidclassExt);
|
|
#endif
|
|
|
|
|
|
extern ULONG HidpNextHidNumber;
|
|
extern FDO_EXTENSION *allFdoExtensions;
|
|
extern KSPIN_LOCK allFdoExtensionsSpinLock;
|
|
|
|
PVOID
|
|
HidpGetSystemAddressForMdlSafe(PMDL MdlAddress);
|
|
|
|
|
|
|
|
|