📄 hid.cpp
字号:
//
// File: hid.cpp
// Description: The implementation of class HidProcessing
//
// Created: Wed. Jan 15, 2003
//
//
// Copyright and Disclaimer:
//
// ---------------------------------------------------------------
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// IN NO EVENT SHALL CONEXANT BE LIABLE TO ANY PARTY FOR DIRECT,
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE
// AND ITS DOCUMENTATION, EVEN IF CONEXANT HAS BEEN ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2000-2001 Conexant Systems, Inc.
//
// All Rights Reserved.
// ---------------------------------------------------------------
//
// Module Revision Id:
//
//
#include "common.h"
//definitions for the hid report descriptor
#include <hidtoken.h>
#include <hidusage.h>
#include "hid_commands.h"
#include "hid.h"
/////////////////////////////////////////////////////////////////////////////////////////
//HID report descriptor
//
// This complicated data structure defines the structure and types of reports we send to
// the operating system through the HID class driver.
//
// This driver supports three types of reports, keyboard reports, consumer reports, and
// page 0xFFBC reports. These are listed in that order in the descriptor, and are
// each defined by a collection. To make it easier to fill in these reports, some C-style
// data structures have been defined that match the report descriptor fields. These
// are KEYBOARD_USAGE_PAGE_REPORT and CONSUMER_USAGE_PAGE_REPORT. They must be updated
// if the report descriptor is changed.
//
// In general, modifiers that are global apply to all items coming after them in the
// descriptor. Local items apply only to the first main item following them.
//
// Things are added to the report by inserting input items after setting up the state of
// the input item by setting the min and max for the item, the usage for the item, and the
// size of the item. If we're inserting several one bit items, we can define once at the
// beginning that the item size is one bit, and that the values are 0 and 1 since these
// are global properties and apply to every item after.
//
// The 1's at the end of things such as HIDP_GLOBAL_USAGE_PAGE_1 mean that the item has
// one byte of data
//
HID_REPORT_DESCRIPTOR HidProcessing::_s_report_descriptor[] =
{
//usage page (generic desktop) and usage (keyboard) for the first top level collection
HIDP_GLOBAL_USAGE_PAGE_1, HID_USAGE_PAGE_GENERIC,
HIDP_LOCAL_USAGE_1, HID_USAGE_GENERIC_KEYBOARD,
//Keyboard top level collection
HIDP_MAIN_COLLECTION, HIDP_MAIN_COLLECTION_APP,
//The following data is in the keyboard usage page.
HIDP_GLOBAL_USAGE_PAGE_1, HID_USAGE_PAGE_KEYBOARD,
//*****BYTE 0 : report ID
HIDP_GLOBAL_REPORT_ID, REPORT_ID_KEYBOARD,
//*****BYTE 1 : modifiers
// bit 0: left ctrl
// bit 1: left shift
// bit 2: left alt
// bit 3: left GUI
// bit 4: right ctrl
// bit 5: right shift
// bit 6: right alt
// bit 7: rigth GUI
//These are the usages of the modifier bits.
//They are sequential in number, and apply to each bit in the array
// in order starting with bit 0.
HIDP_LOCAL_USAGE_MIN_1, HID_USAGE_KEYBOARD_LCTRL,
HIDP_LOCAL_USAGE_MAX_1, HID_USAGE_KEYBOARD_RGUI,
//The bits can take on the values 0 or 1
HIDP_GLOBAL_LOG_MIN_1, 0,
HIDP_GLOBAL_LOG_MAX_1, 1,
//An array of 8 1-bit fields.
HIDP_GLOBAL_REPORT_COUNT_1, 8,
HIDP_GLOBAL_REPORT_SIZE, 1,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_ARRAY,
//*****BYTE 2: Reserved
//1 8-bit field
HIDP_GLOBAL_REPORT_COUNT_1, 1,
HIDP_GLOBAL_REPORT_SIZE, 8,
HIDP_MAIN_INPUT_1, ITEM_CONSTANT,
//***** BYTES 3 - 8
//These are the min and max values that may be returned as key presses
HIDP_GLOBAL_LOG_MIN_1, 0,
HIDP_GLOBAL_LOG_MAX_1, 101,
//These are the usages applied to each key press.
HIDP_LOCAL_USAGE_MIN_1, 0,
HIDP_LOCAL_USAGE_MAX_1, 101,
//Array of 6 8-bit fields
HIDP_GLOBAL_REPORT_COUNT_1, 6,
HIDP_GLOBAL_REPORT_SIZE, 8,
HIDP_MAIN_INPUT_1, ITEM_DATA | ITEM_ARRAY,
//End keyboard collection
HIDP_MAIN_ENDCOLLECTION, // End Collection
/////////////////////////////////////////////////////////////////////////////////////
//Consumer usage page top level collection
HIDP_GLOBAL_USAGE_PAGE_1, HID_USAGE_PAGE_CONSUMER,
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_CONTROL,
HIDP_MAIN_COLLECTION, HIDP_MAIN_COLLECTION_APP,
//****BYTE 0 = Report ID
HIDP_GLOBAL_REPORT_ID, REPORT_ID_CONSUMER,
//***BYTE 1 = volume
//valid values are 0 or 1
HIDP_GLOBAL_LOG_MIN_1, 0,
HIDP_GLOBAL_LOG_MAX_1, 1,
//1 bit reports
HIDP_GLOBAL_REPORT_SIZE, 1,
HIDP_GLOBAL_REPORT_COUNT_1, 1,
//bit 0: volume up
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_VOLUME_UP,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//bit 1: volume down
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_VOLUME_DOWN,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//bit 2: mute
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_MUTE,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//5 bits of padding to make it an even byte.
HIDP_GLOBAL_REPORT_SIZE, 1,
HIDP_GLOBAL_REPORT_COUNT_1, 5,
HIDP_MAIN_INPUT_1, ITEM_CONSTANT,
//*****BYTE 2 = channel
//valid values are 0 or 1
HIDP_GLOBAL_LOG_MIN_1, 0,
HIDP_GLOBAL_LOG_MAX_1, 1,
//1 bit reports
HIDP_GLOBAL_REPORT_SIZE, 1,
HIDP_GLOBAL_REPORT_COUNT_1, 1,
//bit 0: channel up
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_CHANNEL_UP,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//bit 1: channel down
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_CHANNEL_DOWN,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//6 bits of padding to make it a byte
HIDP_GLOBAL_REPORT_SIZE, 1,
HIDP_GLOBAL_REPORT_COUNT_1, 6,
HIDP_MAIN_INPUT_1, ITEM_CONSTANT,
//*****BYTE 3 PVR
//valid values are 0 or 1
HIDP_GLOBAL_LOG_MIN_1, 0,
HIDP_GLOBAL_LOG_MAX_1, 1,
//1 bit reports
HIDP_GLOBAL_REPORT_SIZE, 1,
HIDP_GLOBAL_REPORT_COUNT_1, 1,
//bit 0: play
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_PLAY,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//bit 1: stop
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_STOP,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//bit 2: pause
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_PAUSE,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//bit 3: record
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_RECORD,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//bit 4: fast forward
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_FAST_FORWARD,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//bit 5: rewind
HIDP_LOCAL_USAGE_1, HID_USAGE_CONSUMER_REWIND,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//2 bits of padding to make it a byte
HIDP_GLOBAL_REPORT_SIZE, 1,
HIDP_GLOBAL_REPORT_COUNT_1, 2,
HIDP_MAIN_INPUT_1, ITEM_CONSTANT,
//End consumer usage page
HIDP_MAIN_ENDCOLLECTION,
/////////////////////////////////////////////////////////////////////////////////////
//Vender-defined usage page. 0xFFBC.
//0xFFBC, usage 0x88 is Microsoft's usage page for extra buttons
HIDP_GLOBAL_USAGE_PAGE_2, 0xBC, 0xFF,
HIDP_LOCAL_USAGE_1, 0x88,
HIDP_MAIN_COLLECTION, HIDP_MAIN_COLLECTION_APP,
HIDP_GLOBAL_REPORT_ID, 3,
//Bit 0 is usage 0x4B (DVD angle). This is just to test
HIDP_LOCAL_USAGE_1, 0x4B,
//valid values are 0 or 1
HIDP_GLOBAL_LOG_MIN_1, 0,
HIDP_GLOBAL_LOG_MAX_1, 1,
//Two one-bit fields
HIDP_GLOBAL_REPORT_SIZE, 1,
HIDP_GLOBAL_REPORT_COUNT_1, 1,
HIDP_MAIN_INPUT_1, ITEM_DATA|ITEM_VARIABLE,
//Put in 7 bits of padding to make it an even byte.
HIDP_GLOBAL_REPORT_SIZE, 1,
HIDP_GLOBAL_REPORT_COUNT_1, 7,
HIDP_MAIN_INPUT_1, ITEM_CONSTANT,
//End vender-defined usage page
HIDP_MAIN_ENDCOLLECTION,
};
/////////////////////////////////////////////////////////////////////////////////////////
//HidProcessing::_s_hid_descriptor
//
// This structure is required to define our HID device, and is returned in response to
// IOCTL_HID_GET_DEVICE_DESCRIPTOR. It provides the length of the report descriptor
// later used in IOCTL_HID_GET_REPORT_DESCRIPTOR.
//
USB_HID_DESCRIPTOR HidProcessing::_s_hid_descriptor =
{
sizeof(USB_HID_DESCRIPTOR), // length of this descriptor
HID_HID_DESCRIPTOR_TYPE,
0x110, // hid version (1.10)
0x00, // country code == Not Specified
0x01, // number of descriptors
HID_REPORT_DESCRIPTOR_TYPE, // first descriptor's type
sizeof(_s_report_descriptor) // first descriptor's size
};
/////////////////////////////////////////////////////////////////////////////////////////
//HidProcessing::processHidIoctl
//
// This is the main entry point for HID IRPs. This function calls an appropriate function
// depending on the IOCTL code of the IRP. Note that HID IOCTL's are internal device
// control IRPs rather than device control IRPs.
//
NTSTATUS HidProcessing::processHidIoctl(PIRP p_irp)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
dbgLogInfo(("HidMiniIoctl Enter\n"));
//
// Get a pointer to the current location in the Irp
//
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(p_irp);
switch (IrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
// Return the HID descriptor
dbgLogTrace(("IOCTL_HID_GET_DEVICE_DESCRIPTOR\n"));
ntStatus = getHidDescriptor(p_irp);
break;
case IOCTL_HID_GET_REPORT_DESCRIPTOR:
// Return the Report descriptor
dbgLogTrace(("IOCTL_HID_GET_REPORT_DESCRIPTOR\n"));
ntStatus = getReportDescriptor(p_irp);
break;
case IOCTL_HID_READ_REPORT:
// Perform a read
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -