⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hid.cpp

📁 pci 底层驱动
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
//  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 + -