www.pudn.com > pnpi8042.rar > i8042prt.h


/* 
 
Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved 
 
Module Name: 
 
    i8042prt.h 
 
Abstract: 
 
    These are the structures and defines that are used in the 
    Intel i8042 port driver. 
 
Revision History: 
 
--*/ 
 
#ifndef _I8042PRT_ 
#define _I8042PRT_ 
 
#include "ntddk.h" 
#include  
#include  
#include  
#include "kbdmou.h" 
#include "wmilib.h" 
#include "i8042cfg.h" 
#include "i8042str.h" 
 
#define I8042_POOL_TAG (ULONG) '2408' 
#undef ExAllocatePool 
#define ExAllocatePool(type, size) \ 
            ExAllocatePoolWithTag (type, size, I8042_POOL_TAG) 
 
#if DBG 
#ifdef PAGED_CODE 
#undef PAGED_CODE 
#endif 
 
#define PAGED_CODE() \ 
    if (KeGetCurrentIrql() > APC_LEVEL) { \ 
    KdPrint(( "8042: Pageable code called at IRQL %d\n", KeGetCurrentIrql() )); \ 
        DbgBreakPoint(); \ 
        } 
#endif 
 
#define MOUSE_RECORD_ISR     DBG 
#define I8042_VERBOSE        DBG  
#define KEYBOARD_RECORD_INIT DBG 
 
#define DELAY_SYSBUTTON_COMPLETION 1 
 
// 
// Define the timer values. 
// 
 
 
#define I8042_ASYNC_NO_TIMEOUT -1 
#define I8042_ASYNC_TIMEOUT     3 
 
// 
// Define the default number of entries in the input data queue. 
// 
 
#define DATA_QUEUE_SIZE    100 
 
// 
// Define the default stall value. 
// 
 
#define I8042_STALL_DEFAULT      50 
 
// 
// Custom resource type used when pruning the fdo's resource lists 
//  
#define I8X_REMOVE_RESOURCE 0xef 
 
// 
// Length (including NULL) of the PnP string identifying the mouse 
// 
// New style mice will respond with MSHxxxx 
// Old style mice will respond with pnpxxxx 
//  
#define MOUSE_PNPID_LENGTH 8 
 
// 
// Number of times to poll the hardware (determined empiracally) 
// 
#define I8X_POLL_ITERATIONS_MAX (11200) 
 
// 
// Define the default "sync time" used to determine when the start 
// of a new mouse data packet is expected.  The value is in units 
// of 100 nanoseconds. 
// 
 
#define MOUSE_SYNCH_PACKET_100NS 10000000UL // 1 second, in 100 ns units 
 
// 
// Time, in ms, for the mouse to respond to the query ID sequence 
// 
#define WHEEL_DETECTION_TIMEOUT 1500 
 
// 
// Default for how to initialize the mouse 
// 
#define I8X_INIT_POLLED_DEFAULT 0 
 
 
#define IOCTL_INTERNAL_MOUSE_RESET  \ 
            CTL_CODE(FILE_DEVICE_MOUSE, 0x0FFF, METHOD_NEITHER, FILE_ANY_ACCESS) 
 
#define FAILED_RESET_STOP           (0) 
#define FAILED_RESET_PROCEED        (1) 
#define FAILED_RESET_PROCEED_ALWAYS (2) 
 
#define FAILED_RESET_DEFAULT        FAILED_RESET_PROCEED 
#define STR_FAILED_RESET            L"KeyboardFailedReset" 
 
// 
// Define booleans. 
// 
#define WAIT_FOR_ACKNOWLEDGE    TRUE 
#define NO_WAIT_FOR_ACKNOWLEDGE FALSE 
#define AND_OPERATION           TRUE 
#define OR_OPERATION            FALSE 
#define ENABLE_OPERATION        TRUE 
#define DISABLE_OPERATION       FALSE 
 
// 
// Default keyboard scan code mode. 
// 
 
#define KEYBOARD_SCAN_CODE_SET 0x01 
 
// 
// Default number of function keys, number of LED indicators, and total 
// number of keys located on the known types of keyboard. 
// 
 
#define NUM_KNOWN_KEYBOARD_TYPES                   8 
#define KEYBOARD_TYPE_DEFAULT                      4 
#define KEYBOARD_INDICATORS_DEFAULT                0 
 
typedef struct _KEYBOARD_TYPE_INFORMATION { 
    USHORT NumberOfFunctionKeys; 
    USHORT NumberOfIndicators; 
    USHORT NumberOfKeysTotal; 
} KEYBOARD_TYPE_INFORMATION, *PKEYBOARD_TYPE_INFORMATION; 
 
static const 
KEYBOARD_TYPE_INFORMATION KeyboardTypeInformation[NUM_KNOWN_KEYBOARD_TYPES] = { 
    {10, 3, 84},     // PC/XT 83- 84-key keyboard (and compatibles) 
    {12, 3, 102},    // Olivetti M24 102-key keyboard (and compatibles) 
    {10, 3, 84},     // All AT type keyboards (84-86 keys) 
    {12, 3, 101},    // Enhanced 101- or 102-key keyboards (and compatibles) 
    {12, 3, 101},    // 5: 
    {12, 3, 101},    // 6: 
    { 0, 0, 0},      // 7: Japanese Keyboard 
    { 0, 0, 0}       // 8: Korean keyboard 
}; 
 
typedef struct _KEYBOARD_OEM_INFORMATION { 
    KEYBOARD_ID               KeyboardId; 
    KEYBOARD_TYPE_INFORMATION KeyboardTypeInformation; 
} KEYBOARD_OEM_INFORMATION, *PKEYBOARD_OEM_INFORMATION; 
 
// 
// Keyboard hardware OEM id. by MSKK 
// 
#define MSFT    0x0 // Microsoft 
#define AX      0x1 // AX consortium 
#define TOSHIBA 0x2 // TOSHIBA 
#define EPSON   0x4 // EPSON 
#define FJ      0x5 // Fujitsu 
#define IBMJ    0x7 // IBM Japan 
#define DECJ    0x8 // DEC Japan 
#define PANA    0xA // Panasonic 
#define NEC     0xD // NEC 
 
#define FE_SUBTYPE(SubType,OemId) ((SubType)|((OemId<<4))) 
 
#define IBM02_KEYBOARD(Id)     (((Id).Type == 0x7) && ((Id).Subtype == FE_SUBTYPE(3,MSFT))) 
#define AX_KEYBOARD(Id)        (((Id).Type == 0x7) && ((Id).Subtype == FE_SUBTYPE(1,MSFT))) 
#define OYAYUBI_KEYBOARD(Id)   (((Id).Type == 0x7) && ((Id).Subtype == FE_SUBTYPE(2,FJ))) 
#define DEC_KANJI_KEYBOARD(Id) (((Id).Type == 0x7) && (((Id).Subtype == FE_SUBTYPE(1,DECJ)) || \ 
                                                       ((Id).Subtype == FE_SUBTYPE(2,DECJ)))) 
 
static const 
KEYBOARD_OEM_INFORMATION KeyboardFarEastOemInformation[] = { 
    {{7, FE_SUBTYPE(1,MSFT)}, {12,3,101}}, // PC/AT 101 Enhanced Japanese Keyboard 
    {{7, FE_SUBTYPE(1,MSFT)}, {12,4,105}}, // AX standard Japanese keyboard 
    {{7, FE_SUBTYPE(2,MSFT)}, {12,3,106}}, // PC/AT 106 Japanese Keyboard 
    {{7, FE_SUBTYPE(3,MSFT)}, {12,3,106}}, // IBM 5576-002 keyboard 
    {{7, FE_SUBTYPE(1,MSFT)}, {12,4,105}}, // AX consortium compatible keyboard 
    {{7, FE_SUBTYPE(2,FJ  )}, {12,3,108}}, // Fujitsu OYAYUBI shift keyboard 
    {{7, FE_SUBTYPE(1,DECJ)}, {17,3,111}}, // DEC LK411 (Ansi layout) keyboard 
    {{7, FE_SUBTYPE(2,DECJ)}, {17,3,112}}, // DEC LK411 (JIS layout) keyboard 
    {{8, FE_SUBTYPE(3,MSFT)}, {12,3,101}}, // PC/AT 101 Enhanced Korean Keyboard (A) 
    {{8, FE_SUBTYPE(4,MSFT)}, {12,3,101}}, // PC/AT 101 Enhanced Korean Keyboard (B) 
    {{8, FE_SUBTYPE(5,MSFT)}, {12,3,101}}, // PC/AT 101 Enhanced Korean Keyboard (C) 
    {{8, FE_SUBTYPE(6,MSFT)}, {12,3,103}}, // PC/AT 103 Enhanced Korean Keyboard 
    {{0, FE_SUBTYPE(0,MSFT)}, { 0,0,  0}}  // Array terminator 
}; 
 
 
// 
// Minimum, maximum, and default values for keyboard typematic rate and delay. 
// 
 
#define KEYBOARD_TYPEMATIC_RATE_MINIMUM     2 
#define KEYBOARD_TYPEMATIC_RATE_MAXIMUM    30 
#define KEYBOARD_TYPEMATIC_RATE_DEFAULT    30 
#define KEYBOARD_TYPEMATIC_DELAY_MINIMUM  250 
#define KEYBOARD_TYPEMATIC_DELAY_MAXIMUM 1000 
#define KEYBOARD_TYPEMATIC_DELAY_DEFAULT  250 
 
 
// 
// Define the 8042 mouse status bits. 
// 
#define LEFT_BUTTON        0x01 
#define RIGHT_BUTTON       0x02 
#define MIDDLE_BUTTON      0x04 
#define BUTTON_4           0x10 
#define BUTTON_5           0x20 
 
#define X_DATA_SIGN        0x10 
#define Y_DATA_SIGN        0x20 
#define X_OVERFLOW         0x40 
#define Y_OVERFLOW         0x80 
 
#define MOUSE_SIGN_OVERFLOW_MASK (X_DATA_SIGN | Y_DATA_SIGN | X_OVERFLOW | Y_OVERFLOW) 
 
// 
// Define the maximum positive and negative values for mouse motion. 
// 
 
#define MOUSE_MAXIMUM_POSITIVE_DELTA 0x000000FF 
#define MOUSE_MAXIMUM_NEGATIVE_DELTA 0xFFFFFF00 
 
// 
// Default number of buttons and sample rate for the i8042 mouse. 
// 
 
#define MOUSE_NUMBER_OF_BUTTONS     2 
#define MOUSE_SAMPLE_RATE           60 
 
// 
// Define the mouse resolution specifier.  Note that (2**MOUSE_RESOLUTION) 
// specifies counts-per-millimeter.  Counts-per-centimeter is 
// (counts-per-millimeter * 10). 
// 
 
#define MOUSE_RESOLUTION            3 
 
// 
// Define the maximum number of resets we allow without success before we 
// give up and consider the mouse dead 
// 
#define MOUSE_RESET_TIMEOUT         (1500 * 1000 * 10) 
 
#define MOUSE_RESETS_MAX             3 
#define MOUSE_RESENDS_MAX            4 
#define MOUSE_RESET_RESENDS_MAX      10 
 
// 
// Defines and macros for Globals.ControllerData->HardwarePresent. 
// 
#define KEYBOARD_HARDWARE_PRESENT               0x001 
#define MOUSE_HARDWARE_PRESENT                  0x002 
#define BALLPOINT_HARDWARE_PRESENT              0x004 
#define WHEELMOUSE_HARDWARE_PRESENT             0x008 
#define DUP_KEYBOARD_HARDWARE_PRESENT           0x010 
#define DUP_MOUSE_HARDWARE_PRESENT              0x020 
#define KEYBOARD_HARDWARE_INITIALIZED           0x100 
#define MOUSE_HARDWARE_INITIALIZED              0x200 
#define FIVE_BUTTON_HARDWARE_PRESENT           0x1000 
#define PHANTOM_KEYBOARD_HARDWARE_REPORTED     0x4000 
#define PHANTOM_MOUSE_HARDWARE_REPORTED        0x8000 
 
#define TEST_HARDWARE_PRESENT(bits)         \ 
 ((Globals.ControllerData->HardwarePresent & (bits)) == (bits)) 
#define CLEAR_HW_FLAGS(bits) (Globals.ControllerData->HardwarePresent &= ~(bits)) 
#define SET_HW_FLAGS(bits) (Globals.ControllerData->HardwarePresent |= (bits)) 
#define KEYBOARD_PRESENT()      TEST_HARDWARE_PRESENT(KEYBOARD_HARDWARE_PRESENT) 
#define MOUSE_PRESENT()         TEST_HARDWARE_PRESENT(MOUSE_HARDWARE_PRESENT)  
#define WHEEL_PRESENT()         TEST_HARDWARE_PRESENT(WHEELMOUSE_HARDWARE_PRESENT) 
#define FIVE_PRESENT()         TEST_HARDWARE_PRESENT(FIVE_BUTTON_HARDWARE_PRESENT) 
#define KEYBOARD_INITIALIZED() \ 
                            TEST_HARDWARE_PRESENT(KEYBOARD_HARDWARE_INITIALIZED) 
#define MOUSE_INITIALIZED()    \ 
                            TEST_HARDWARE_PRESENT(MOUSE_HARDWARE_INITIALIZED)  
#define KEYBOARD_STARTED() (Globals.KeyboardExtension          ?    \ 
                            Globals.KeyboardExtension->Started :    \ 
                            FALSE)                                   
#define MOUSE_STARTED() (Globals.MouseExtension          ?    \ 
                         Globals.MouseExtension->Started :    \ 
                         FALSE)                                   
#define CLEAR_MOUSE_PRESENT() CLEAR_HW_FLAGS(MOUSE_HARDWARE_INITIALIZED | MOUSE_HARDWARE_PRESENT | WHEELMOUSE_HARDWARE_PRESENT) 
#define CLEAR_KEYBOARD_PRESENT() CLEAR_HW_FLAGS(KEYBOARD_HARDWARE_INITIALIZED | KEYBOARD_HARDWARE_PRESENT) 
 
#define KBD_POWERED_UP_STARTED      0x00000001 
#define KBD_POWERED_DOWN            0x00000002 
#define MOU_POWERED_UP_STARTED      0x00000010 
#define MOU_POWERED_DOWN            0x00000020 
#define KBD_POWERED_UP_SUCCESS      0x00000100 
#define KBD_POWERED_UP_FAILURE      0x00000200 
#define MOU_POWERED_UP_SUCCESS      0x00001000 
#define MOU_POWERED_UP_FAILURE      0x00002000 
 
#define WORK_ITEM_QUEUED            0x10000000 
 
#define MOU_POWER_FLAGS             (MOU_POWERED_DOWN       |   \ 
                                     MOU_POWERED_UP_STARTED |   \ 
                                     MOU_POWERED_UP_SUCCESS) 
 
#define KBD_POWER_FLAGS             (KBD_POWERED_DOWN       |   \ 
                                     KBD_POWERED_UP_STARTED |   \ 
                                     KBD_POWERED_UP_SUCCESS) 
 
#define SET_PWR_FLAGS(bits)     (Globals.PowerFlags |= (bits)) 
#define CMP_PWR_FLAGS(bits)     ((Globals.PowerFlags & (bits)) == (bits)) 
#define TEST_PWR_FLAGS(bits)    (Globals.PowerFlags & (bits)) 
 
#define KEYBOARD_POWERED_DOWN_SUCCESS() CMP_PWR_FLAGS(KBD_POWERED_DOWN) 
#define MOUSE_POWERED_DOWN_SUCCESS()    CMP_PWR_FLAGS(MOU_POWERED_DOWN) 
 
#define KEYBOARD_POWERED_UP_SUCCESSFULLY()  SET_PWR_FLAGS(KBD_POWERED_UP_SUCCESS) 
#define MOUSE_POWERED_UP_SUCCESSFULLY()     SET_PWR_FLAGS(MOU_POWERED_UP_SUCCESS) 
 
#define KEYBOARD_POWERED_UP_FAILURE()  SET_PWR_FLAGS(KBD_POWERED_UP_FAILURE) 
#define MOUSE_POWERED_UP_FAILURE()     SET_PWR_FLAGS(MOU_POWERED_UP_FAILURE) 
 
#define KEYBOARD_POWERED_UP_FAILED()  CMP_PWR_FLAGS(KBD_POWERED_UP_FAILURE) 
#define MOUSE_POWERED_UP_FAILED()     CMP_PWR_FLAGS(MOU_POWERED_UP_FAILURE) 
 
#define KEYBOARD_POWERED_UP_SUCCESS() CMP_PWR_FLAGS(KBD_POWERED_UP_SUCCESS) 
#define MOUSE_POWERED_UP_SUCCESS()    CMP_PWR_FLAGS(MOU_POWERED_UP_SUCCESS) 
#define A_POWERED_UP_SUCCEEDED() \ 
            TEST_PWR_FLAGS(KBD_POWERED_UP_SUCCESS | MOU_POWERED_UP_SUCCESS) 
                     
#define IS_KEYBOARD(_devExt_) ((_devExt_)->IsKeyboard) 
#define IS_MOUSE(_devExt_) ((_devExt_)->IsKeyboard == FALSE) 
 
#define IS_LEVEL_TRIGGERED(_devExt_)   ((_devExt_)->InterruptDescriptor.Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE) 
#define IS_EDGE_TRIGGERED(_devExt_)    ((_devExt_)->InterruptDescriptor.Flags == CM_RESOURCE_INTERRUPT_LATCHED) 
 
#define DEVICE_START_SUCCESS(status)    (NT_SUCCESS((status)) || ((status) == STATUS_DEVICE_NOT_CONNECTED)) 
 
#define INIT_FIRST_TIME         0x00000001 
#define INIT_KEYBOARD           0x00010000 
#define INIT_MOUSE              0x00020000 
 
#if _X86_ 
    #define WRAP_IO_FUNCTIONS 0 
#else 
    #define WRAP_IO_FUNCTIONS 1 
#endif 
 
typedef 
UCHAR 
(*PI8X_READ_UCHAR) ( 
    PUCHAR Address 
    ); 
 
typedef 
VOID 
(*PI8X_WRITE_UCHAR) ( 
    PUCHAR Address, 
    UCHAR Byte 
    ); 
 
// 
// Define macros for performing I/O on the 8042 command/status and data 
// registers. 
// 
#define I8X_PUT_COMMAND_BYTE(Address, Byte)                                  \ 
    Globals.I8xWriteXxxUchar(Address, (UCHAR) Byte) 
     
#define I8X_PUT_DATA_BYTE(Address, Byte)                                     \ 
    Globals.I8xWriteXxxUchar(Address, (UCHAR) Byte) 
     
#define I8X_GET_STATUS_BYTE(Address)                                         \ 
    Globals.I8xReadXxxUchar(Address) 
     
#define I8X_GET_DATA_BYTE(Address)                                           \ 
    Globals.I8xReadXxxUchar(Address) 
     
#define I8X_WRITE_CMD_TO_MOUSE( )                                            \ 
    I8xPutByteAsynchronous(                                                  \ 
        (CCHAR) CommandPort,                                                 \ 
        (UCHAR) I8042_WRITE_TO_AUXILIARY_DEVICE                              \ 
        )  
 
#define I8X_MOUSE_COMMAND( Byte )                                            \ 
    I8xPutByteAsynchronous(                                                  \ 
        (CCHAR) DataPort,                                                    \ 
        (UCHAR) Byte                                                         \ 
        ) 
         
// 
// Define commands to the 8042 controller. 
// 
#define I8042_READ_CONTROLLER_COMMAND_BYTE      0x20 
#define I8042_WRITE_CONTROLLER_COMMAND_BYTE     0x60 
#define I8042_DISABLE_MOUSE_DEVICE              0xA7 
#define I8042_ENABLE_MOUSE_DEVICE               0xA8 
#define I8042_AUXILIARY_DEVICE_TEST             0xA9 
#define I8042_KEYBOARD_DEVICE_TEST              0xAB 
#define I8042_DISABLE_KEYBOARD_DEVICE           0xAD 
#define I8042_ENABLE_KEYBOARD_DEVICE            0xAE 
#define I8042_WRITE_TO_AUXILIARY_DEVICE         0xD4 
 
// 
// Define the 8042 Controller Command Byte. 
// 
 
#define CCB_ENABLE_KEYBOARD_INTERRUPT 0x01 
#define CCB_ENABLE_MOUSE_INTERRUPT    0x02 
#define CCB_DISABLE_KEYBOARD_DEVICE   0x10 
#define CCB_DISABLE_MOUSE_DEVICE      0x20 
#define CCB_KEYBOARD_TRANSLATE_MODE   0x40 
 
 
// 
// Define the 8042 Controller Status Register bits. 
// 
 
#define OUTPUT_BUFFER_FULL       0x01 
#define INPUT_BUFFER_FULL        0x02 
#define MOUSE_OUTPUT_BUFFER_FULL 0x20 
 
// 
// Define the 8042 responses. 
// 
#define ACKNOWLEDGE         0xFA 
#define RESEND              0xFE 
#define FAILURE             0xFC 
 
// 
// Define commands to the keyboard (through the 8042 data port). 
// 
 
#define SET_KEYBOARD_INDICATORS           0xED 
#define SELECT_SCAN_CODE_SET              0xF0 
#define READ_KEYBOARD_ID                  0xF2 
#define SET_KEYBOARD_TYPEMATIC            0xF3 
#define SET_ALL_TYPEMATIC_MAKE_BREAK      0xFA 
#define KEYBOARD_RESET                    0xFF 
 
// 
// Define the keyboard responses. 
// 
 
#define KEYBOARD_COMPLETE_SUCCESS 0xAA 
#define KEYBOARD_COMPLETE_FAILURE 0xFC 
#define KEYBOARD_BREAK_CODE       0xF0 
#define KEYBOARD_DEBUG_HOTKEY_ENH 0x37 // SysReq scan code for Enhanced Keyboard 
#define KEYBOARD_DEBUG_HOTKEY_AT  0x54 // SysReq scan code for 84-key Keyboard 
 
// 
// Define keyboard power scan codes 
// 
#define KEYBOARD_POWER_CODE        0x5E 
#define KEYBOARD_SLEEP_CODE        0x5F 
#define KEYBOARD_WAKE_CODE         0x63 
 
/* 
Power event  
        Set1:   Make = E0, 5E   Break = E0, DE 
        Set2:   Make = E0, 37   Break = E0, F0, 37 
Sleep event  
        Set1:   Make = E0, 5F   Break = E0, DF 
        Set2:   Make = E0, 3F   Break = E0, F0, 3F 
Wake event  
        Set1:   Make = E0, 63   Break = E0, E3 
        Set2:   Make = E0, 5E   Break = E0, F0, 5E 
*/ 
 
// 
// Define commands to the mouse (through the 8042 data port). 
// 
 
#define SET_MOUSE_RESOLUTION              0xE8 
#define SET_MOUSE_SAMPLING_RATE           0xF3 
#define MOUSE_RESET                       0xFF 
#define ENABLE_MOUSE_TRANSMISSION         0xF4 
#define SET_MOUSE_SCALING_1TO1            0xE6 
#define READ_MOUSE_STATUS                 0xE9 
#define GET_DEVICE_ID                     0xF2 
 
// 
// Define the mouse responses. 
// 
 
#define MOUSE_COMPLETE      0xAA 
#define MOUSE_ID_BYTE       0x00 
#define WHEELMOUSE_ID_BYTE  0x03 
#define FIVEBUTTON_ID_BYTE  0x04 
 
// 
// Define the i8042 controller input/output ports. 
// 
 
typedef enum _I8042_IO_PORT_TYPE { 
    DataPort = 0, 
    CommandPort, 
    MaximumPortCount 
 
} I8042_IO_PORT_TYPE; 
 
// 
// Define the device types attached to the i8042 controller. 
// 
 
typedef enum _I8042_DEVICE_TYPE { 
    ControllerDeviceType, 
    KeyboardDeviceType, 
    MouseDeviceType, 
    UndefinedDeviceType 
} I8042_DEVICE_TYPE; 
 
// 
// Intel i8042 configuration information. 
// 
#ifdef FE_SB 
#define KBD_IDENTIFIER  0x10 
#endif 
 
typedef struct _I8042_CONFIGURATION_INFORMATION { 
 
    // 
    // Bus interface type. 
    // 
    INTERFACE_TYPE InterfaceType; 
 
    // 
    // Bus Number. 
    // 
    ULONG BusNumber; 
 
    // 
    // The port/register resources used by this device. 
    // 
    CM_PARTIAL_RESOURCE_DESCRIPTOR PortList[MaximumPortCount]; 
    ULONG PortListCount; 
 
    // 
    // The highest IRQL between the two potential interrupts 
    // 
    KIRQL InterruptSynchIrql; 
 
    // 
    // Number of retries allowed. 
    // 
    USHORT ResendIterations; 
 
    // 
    // Number of polling iterations allowed. 
    // 
    USHORT PollingIterations; 
 
    // 
    // Maximum number of polling iterations allowed. 
    // 
    USHORT PollingIterationsMaximum; 
 
    // 
    // Maximum number of times to check the Status register in 
    // the ISR before deciding the interrupt is spurious. 
    // 
    USHORT PollStatusIterations; 
 
    // 
    // Microseconds to stall in KeStallExecutionProcessor calls. 
    // 
    USHORT StallMicroseconds; 
 
    // 
    // Tracking resolution on the mouse 
    // 
    // USHORT MouseResolution; 
 
    // 
    // Flag that indicates whether floating point context should be saved. 
    // 
    BOOLEAN FloatingSave; 
 
    // 
    // Flag indicating if the interrupts should be shared 
    // 
    BOOLEAN SharedInterrupts; 
 
#ifdef FE_SB 
    // 
    // Detected Device Identifier 
    // 
    WCHAR OverrideKeyboardIdentifier[KBD_IDENTIFIER]; 
#endif 
 
} I8042_CONFIGURATION_INFORMATION, *PI8042_CONFIGURATION_INFORMATION; 
 
// 
// Define the common portion of the keyboard/mouse device extension. 
// 
typedef struct COMMON_DATA { 
    // 
    // Pointer back to the this extension's device object. 
    // 
    PDEVICE_OBJECT      Self; 
  
    PKINTERRUPT InterruptObject; 
 
    // 
    // The spin lock guarding the object's ISR 
    // 
    KSPIN_LOCK          InterruptSpinLock;          
  
    // 
    // 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 root) 
    // 
    PDEVICE_OBJECT      PDO; 
  
    // 
    // Remove tracking 
    // 
    IO_REMOVE_LOCK RemoveLock; 
 
    // 
    // The IRP sent to the device to power it to D0 
    // 
    PIRP OutstandingPowerIrp; 
 
    // 
    // Current power state that the device is in 
    // 
    DEVICE_POWER_STATE PowerState; 
 
    // 
    // Current power state that the system in in 
    // 
    SYSTEM_POWER_STATE SystemState; 
 
    POWER_ACTION ShutdownType;  
 
    //  
    // Number of input data items currently in the InputData queue 
    // 
    ULONG InputCount; 
       
    // 
    // Reference count for number of keyboard enables. 
    // 
    LONG EnableCount; 
 
    // 
    // Timer used to retry the ISR DPC routine when the class 
    // driver is unable to consume all the port driver's data. 
    // 
    KTIMER DataConsumptionTimer; 
  
    // 
    // DPC queue for completion of requests that fail by exceeding 
    // the maximum number of retries. 
    // 
    KDPC RetriesExceededDpc; 
 
    // 
    // DPC queue for logging overrun and internal driver errors. 
    // 
    KDPC ErrorLogDpc; 
 
    // 
    // DPC queue for command timeouts. 
    // 
    KDPC TimeOutDpc; 
 
    // 
    // DPC queue for resetting the device  
    // 
    KDPC ResetDpc; 
 
    // 
    // Request sequence number (used for error logging). 
    // 
    ULONG SequenceNumber; 
   
    // 
    // Class connection data. 
    // 
    CONNECT_DATA ConnectData; 
 
    // 
    // WMI Information 
    // 
    WMILIB_CONTEXT WmiLibInfo; 
 
    // 
    // Current output buffer being written to the device 
    // 
    OUTPUT_PACKET CurrentOutput; 
 
    // 
    // Translated resource descriptor for the interrupt 
    // 
    CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptDescriptor; 
 
    PNP_DEVICE_STATE PnpDeviceState; 
 
    // 
    // Current resend count. 
    // 
    SHORT ResendCount; 
 
    // 
    // Indicates whether it is okay to log overflow errors. 
    // 
    BOOLEAN OkayToLogOverflow; 
 
    BOOLEAN Initialized; 
 
    BOOLEAN IsIsrActivated; 
 
    BOOLEAN IsKeyboard; 
 
    // 
    // Has it been started? 
    // Has the device been manually removed? 
    // 
    BOOLEAN Started; 
 
} *PCOMMON_DATA; 
 
#define GET_COMMON_DATA(ext) ((PCOMMON_DATA) ext) 
#define MANUALLY_REMOVED(ext) ((ext)->PnpDeviceState & PNP_DEVICE_REMOVED) 
 
// 
// Define the keyboard portion of the port device extension. 
// 
typedef struct _PORT_KEYBOARD_EXTENSION { 
 
    //  
    // Data in common with the mouse extension; 
    // 
    struct COMMON_DATA; 
      
    // 
    // bitfield which represents the power capabilities of the kb 
    // 
    UCHAR PowerCaps; 
 
    // 
    // A newly found power event which we need to inform the PO system of 
    // 
    UCHAR PowerEvent; 
     
    UCHAR CurrentScanCode, LastScanCode; 
 
    // 
    // Irp to be completed when one the power buttons is pressed 
    // 
    PIRP SysButtonEventIrp; 
 
    // 
    // DPC to handle power button events (updating our caps and completing 
    // previous IOCTL requests) 
    // 
    KDPC SysButtonEventDpc;  
 
    // 
    // Spin lock to guard the cancel routine and the IOCTL handler 
    // 
    KSPIN_LOCK SysButtonSpinLock; 
 
    // 
    // Symbolic name for the interface 
    // 
    UNICODE_STRING SysButtonInterfaceName;  
 
    // 
    // Keyboard attributes. 
    // 
    KEYBOARD_ATTRIBUTES KeyboardAttributes; 
 
    // 
    // Extended keyboard ID 
    // 
    KEYBOARD_ID_EX KeyboardIdentifierEx; 
 
    // 
    // Initial values of keyboard typematic rate and delay. 
    // 
    KEYBOARD_TYPEMATIC_PARAMETERS KeyRepeatCurrent; 
 
    // 
    // Current indicator (LED) setting. 
    // 
    KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; 
 
    // 
    // Keyboard ISR DPC queue. 
    // 
    KDPC KeyboardIsrDpc; 
 
    // 
    // Keyboard ISR DPC recall queue. 
    // 
    KDPC KeyboardIsrDpcRetry; 
 
    // 
    // Used by the ISR and the ISR DPC (in I8xDpcVariableOperation calls) 
    // to control processing by the ISR DPC. 
    // 
    LONG DpcInterlockKeyboard; 
  
    // 
    // Start of the port keyboard input data queue (really a circular buffer). 
    // 
    PKEYBOARD_INPUT_DATA InputData; 
  
    // 
    // Insertion pointer for keyboard InputData. 
    // 
    PKEYBOARD_INPUT_DATA DataIn; 
  
    // 
    // Removal pointer for keyboard InputData. 
    // 
    PKEYBOARD_INPUT_DATA DataOut; 
  
    // 
    // Points one input packet past the end of the InputData buffer. 
    // 
    PKEYBOARD_INPUT_DATA DataEnd; 
  
    // 
    // Current keyboard input packet. 
    // 
    KEYBOARD_INPUT_DATA CurrentInput; 
  
    // 
    // Current keyboard scan input state. 
    // 
    KEYBOARD_SCAN_STATE CurrentScanState; 
   
    // 
    // Routine to call after the mouse is reset 
    // 
    PI8042_KEYBOARD_INITIALIZATION_ROUTINE InitializationHookCallback; 
     
    // 
    // Routine to call when a byte is received via the interrupt 
    // 
    PI8042_KEYBOARD_ISR IsrHookCallback; 
      
    // 
    // Context variable for InitializationRoutine 
    // 
    PVOID HookContext; 
 
    // 
    // Crash by key combination. 
    // 
    // CrashFlags used to be Dump1Keys 
    // 
    LONG CrashFlags;          // CrashDump call first press keys flag 
                              //  7 6 5 4 3 2 1 0 bit 
                              //    | | |   | | +--- Right Shift Key 
                              //    | | |   | +----- Right Ctrl Key 
                              //    | | |   +------- Right Alt Key 
                              //    | | +----------- Left Shift Key 
                              //    | +------------- Left Ctrl Key 
                              //    +--------------- Left Alt Key 
    // 
    // CurrentCrashFlags used to be Dump2Key 
    // 
    LONG CurrentCrashFlags;            
 
    // 
    // Key to be pressed 2 times to cause the crash dump 
    // 
    UCHAR CrashScanCode;  
 
    // 
    // Alternate to CrashScanCode, used only for the print screen scan codes(s) 
    // 
    UCHAR CrashScanCode2; 
 
    // 
    // If FAILED_RESET_PROCEED, ignore the fact that the keyboard did not send 
    // an ACK in response to the reset command and still look for the  
    // success/failure code in the i8042 controller. 
    // 
    UCHAR FailedReset; 
 
} PORT_KEYBOARD_EXTENSION, *PPORT_KEYBOARD_EXTENSION; 
 
// 
// Define the structure used to enable the mouse 
// 
typedef struct _ENABLE_MOUSE {  
    KDPC Dpc; 
    KTIMER Timer; 
 
    USHORT    Count; 
    BOOLEAN   FirstTime; 
    BOOLEAN   Enabled; 
} ENABLE_MOUSE; 
 
typedef enum _INTERNAL_RESET_STATE { 
    InternalContinueTimer = 0x0, 
    InternalMouseReset, 
    InternalPauseOneSec 
} INTERNAL_RESET_STATE; 
 
typedef enum _ISR_RESET_STATE { 
    IsrResetNormal = 0x0, 
    IsrResetStopResetting, 
 
    IsrResetQueueReset, 
    IsrResetPause  
} ISR_RESET_STATE; 
 
typedef enum _ISR_DPC_CAUSE { 
    IsrDpcCauseKeyboardWriteComplete = 1, 
    IsrDpcCauseMouseWriteComplete, 
    IsrDpcCauseMouseResetComplete 
} ISR_DPC_CAUSE; 
 
typedef struct _RESET_MOUSE { 
    KDPC Dpc; 
    KTIMER Timer; 
 
    ISR_RESET_STATE IsrResetState; 
 
} RESET_MOUSE; 
 
#define I8X_MOUSE_INIT_COUNTERS(mouExt)                                     \ 
    {                                                                       \ 
        (mouExt)->ResetCount = (mouExt)->FailedCompleteResetCount = -1;     \ 
        (mouExt)->ResendCount = 0;                                          \ 
    } 
 
// 
// Define the mouse portion of the port device extension. 
// 
typedef struct _PORT_MOUSE_EXTENSION { 
 
    struct COMMON_DATA; 
 
    // 
    // Mouse attributes. 
    // 
    MOUSE_ATTRIBUTES MouseAttributes; 
 
    // 
    // Reset IRP used in StartIO 
    // 
    PIRP ResetIrp; 
 
    // 
    // Mouse ISR DPC queue. 
    // 
    KDPC MouseIsrDpc; 
  
    // 
    // Mouse ISR DPC recall queue. 
    // 
    KDPC MouseIsrDpcRetry; 
 
    // 
    // Mouse ISR reset queue. 
    // 
    KDPC MouseIsrResetDpc; 
 
    // 
    // These two structs represent different methods of initialization.   
    // 
    union { 
        RESET_MOUSE  ResetMouse;  
        ENABLE_MOUSE EnableMouse; 
    }; 
 
    // 
    // Used by the ISR and the ISR DPC (in I8xDpcVariableOperation calls) 
    // to control processing by the ISR DPC. 
    // 
    LONG DpcInterlockMouse; 
  
    // 
    // Start of the port mouse input data queue (really a circular buffer). 
    // 
    PMOUSE_INPUT_DATA InputData; 
  
    // 
    // Insertion pointer for mouse InputData. 
    // 
    PMOUSE_INPUT_DATA DataIn; 
  
    // 
    // Removal pointer for mouse InputData. 
    // 
    PMOUSE_INPUT_DATA DataOut; 
  
    // 
    // Points one input packet past the end of the InputData buffer. 
    // 
    PMOUSE_INPUT_DATA DataEnd; 
  
    // 
    // Current mouse input packet.                   (24 bytes) 
    // 
    MOUSE_INPUT_DATA CurrentInput; 
  
    // 
    // Current mouse input state. 
    // 
    MOUSE_STATE InputState; 
    MOUSE_RESET_SUBSTATE InputResetSubState; 
  
    MOUSE_RESET_SUBSTATE WorkerResetSubState; 
 
    // 
    // Count the number of times we have reset and failed 
    // 
    UCHAR ResetCount; 
 
    // 
    // Count the number of times we have reset and not gone through the entire 
    // reset process 
    // 
    UCHAR FailedCompleteResetCount; 
 
    // 
    // Current mouse sign and overflow data. 
    // 
    UCHAR CurrentSignAndOverflow; 
  
    // 
    // Previous mouse sign and overflow data. 
    // 
    UCHAR PreviousSignAndOverflow; 
 
    // 
    // The tick count (since system boot) at which the mouse last interrupted. 
    // Retrieved via KeQueryTickCount.  Used to determine whether a byte of 
    // the mouse data packet has been lost.  Allows the driver to synch 
    // up with the true mouse input state. 
    // 
    LARGE_INTEGER PreviousTick; 
  
    // 
    // Number of interval timer ticks to wait before deciding that the 
    // next mouse interrupt is for the start of a new packet.  Used to 
    // synch up again if a byte of the mouse packet gets lost. 
    // 
    ULONG SynchTickCount; 
 
    // 
    // The amount of time that is valid between sending a set sampling sequence 
    //  (of 20, 40, and 60) and receiving the first pnp id packet from the mouse 
    // 
    // Expressed in terms of system ticks 
    // 
    ULONG WheelDetectionTimeout; 
 
    // 
    // Contains a multi sz list of pnp mouse IDs to check for a wheel mouse 
    // 
    UNICODE_STRING WheelDetectionIDs; 
 
    // 
    // Plug n Play ID received from the mouse during reset 
    // 
    WCHAR PnPID[MOUSE_PNPID_LENGTH]; 
 
    // 
    // An upper filter callback hook to call when processing mouse bytes 
    // 
    PI8042_MOUSE_ISR IsrHookCallback; 
      
    // 
    // Context variable for IsrHookCallback 
    // 
    PVOID HookContext; 
 
    PVOID NotificationEntry; 
 
    // 
    // List of sample rates to send to the mouse during a reset 
    // 
    PUCHAR SampleRates; 
 
    ULONG MouseResetStallTime; 
 
    // 
    // Index into the SampleRates array 
    // 
    UCHAR SampleRatesIndex; 
 
    // 
    // Previous mouse button data. 
    // 
    UCHAR PreviousButtons; 
 
    // 
    // Statue to transition to after the last sample rate from SampleRates has 
    // been sent to the mouse 
    // 
    USHORT PostSamplesState; 
 
    // 
    // Keep track of last byte of data received from mouse so we can detect 
    // the two-byte string which indicates a potential reset 
    // 
    UCHAR LastByteReceived; 
 
    // 
    // Tracking resolution on the mouse 
    // 
    UCHAR Resolution; 
  
    // 
    // One of 3 states that determines whether we should try and detect the wheel 
    // on the mouse or not 
    // 
    UCHAR EnableWheelDetection; 
  
    // 
    // Skip button detection if it overridden in the registry.   
    // 
    UCHAR NumberOfButtonsOverride; 
 
    // 
    // If 0, then initalize the mouse via the interrupt, if non zero, initialize 
    // the mouse via polling 
    // 
    UCHAR InitializePolled; 
 
#if MOUSE_RECORD_ISR 
    ULONG RecordHistoryFlags; 
    ULONG RecordHistoryCount; 
    ULONG RecordHistoryState; 
#endif 
 
} PORT_MOUSE_EXTENSION, *PPORT_MOUSE_EXTENSION; 
 
// 
// controller specific data used by both devices 
// 
typedef struct _CONTROLLER_DATA {  
 
    // 
    // Indicate which hardware is actually present (keyboard and/or mouse). 
    // 
    ULONG HardwarePresent; 
     
    // 
    // IOCTL synchronization object 
    // 
    PCONTROLLER_OBJECT ControllerObject; 
 
    // 
    // Port configuration information. 
    // 
    I8042_CONFIGURATION_INFORMATION Configuration;  
 
    // 
    // Timer used to timeout i8042 commands. 
    // 
    KTIMER CommandTimer; 
 
    // 
    // Spin lock to guard freeing of bytes written to device 
    // 
    KSPIN_LOCK BytesSpinLock; 
 
    // 
    // Spin lock to guard powering the devices back up 
    // 
    KSPIN_LOCK PowerSpinLock; 
 
    // 
    // Default buffer to use for a write to a device if the request <=4 bytes 
    // (avoid lots of tiny sized allocs) 
    // 
    UCHAR DefaultBuffer[4]; 
 
    // 
    // Timer count used by the command time out routine. 
    // 
    LONG TimerCount; 
 
    // 
    // Interrupt to synchronize against 
    // 
    // IN PKINTERRUPT HigherInterrupt; 
 
    // 
    // The mapped addresses for this device's registers. 
    // 
    PUCHAR DeviceRegisters[MaximumPortCount]; 
 
    // 
    // List of ports in IRP_MN_FILTER_RESOURCE_REQUIREMENTS 
    // 
    PHYSICAL_ADDRESS KnownPorts[MaximumPortCount]; 
 
    ULONG KnownPortsCount; 
 
#if DBG 
    ULONG CurrentIoControlCode; 
#endif 
 
} CONTROLLER_DATA, *PCONTROLLER_DATA; 
 
#define POST_BUTTONDETECT_COMMAND                 (SET_MOUSE_RESOLUTION) 
#define POST_BUTTONDETECT_COMMAND_SUBSTATE        (ExpectingSetResolutionDefaultACK) 
 
#define POST_WHEEL_DETECT_COMMAND                 (GET_DEVICE_ID) 
#define POST_WHEEL_DETECT_COMMAND_SUBSTATE        (ExpectingGetDeviceId2ACK) 
 
#define ExpectingPnpId                            (I8042ReservedMinimum+  2) 
#define PostWheelDetectState                      (I8042ReservedMinimum+  3) 
#define PostEnableWheelState                      (I8042ReservedMinimum+  4) 
 
#define QueueingMouseReset                        (I8042ReservedMinimum+100) 
#define MouseResetFailed                          (I8042ReservedMinimum+101) 
 
#define ExpectingLegacyPnpIdByte2_Make            (I8042ReservedMinimum+200) 
#define ExpectingLegacyPnpIdByte2_Break           (I8042ReservedMinimum+201) 
#define ExpectingLegacyPnpIdByte3_Make            (I8042ReservedMinimum+202) 
#define ExpectingLegacyPnpIdByte3_Break           (I8042ReservedMinimum+203) 
#define ExpectingLegacyPnpIdByte4_Make            (I8042ReservedMinimum+204) 
#define ExpectingLegacyPnpIdByte4_Break           (I8042ReservedMinimum+205) 
#define ExpectingLegacyPnpIdByte5_Make            (I8042ReservedMinimum+206) 
#define ExpectingLegacyPnpIdByte5_Break           (I8042ReservedMinimum+207) 
#define ExpectingLegacyPnpIdByte6_Make            (I8042ReservedMinimum+208) 
#define ExpectingLegacyPnpIdByte6_Break           (I8042ReservedMinimum+209) 
#define ExpectingLegacyPnpIdByte7_Make            (I8042ReservedMinimum+210) 
#define ExpectingLegacyPnpIdByte7_Break           (I8042ReservedMinimum+211) 
 
#define QueueingMousePolledReset                  (I8042ReservedMinimum+300) 
 
#define KeepOldSubState                           (I8042ReservedMinimum+400) 
 
typedef struct _GLOBALS { 
  
#if I8042_VERBOSE 
    // 
    // Flags:  Bit field for enabling debugging print statements 
    // Level:  Legacy way of controllign debugging statements 
    // 
    ULONG DebugFlags; 
    ULONG IsrDebugFlags; 
#endif  
 
    // 
    // Pointer to controller specific data that both extensions may access it 
    // 
    PCONTROLLER_DATA ControllerData; 
 
    // 
    // The two possible extensions that can be created 
    // 
    PPORT_MOUSE_EXTENSION MouseExtension; 
    PPORT_KEYBOARD_EXTENSION KeyboardExtension; 
 
    // 
    // Generic read and write functions.  Since we can use both memory and port 
    // type resources, we must use a function pointer to abstract access to them. 
    // 
    PI8X_READ_UCHAR I8xReadXxxUchar; 
 
    PI8X_WRITE_UCHAR I8xWriteXxxUchar; 
 
    //  
    // Path to the driver's entry in the registry 
    // 
    UNICODE_STRING RegistryPath; 
 
    // 
    // Keep track of the number of AddDevice and StartDevice calls.  Want to  
    // postpone h/w initialization until the last StartDevice is received 
    // (due to some h/w which freezes if initialized more than once) 
    // 
    LONG AddedKeyboards; 
    LONG AddedMice; 
    LONG StartedDevices; 
    ULONG PowerFlags; 
     
    // 
    // Provide mutual exclusion during dispatch functions 
    // 
    FAST_MUTEX DispatchMutex;  
 
    // 
    // Set during the first H/W intialization to indicate that the register 
    // addresses must be unmapped when the driver is unloaded.  It is also used  
    // when calling I8X_PUT_COMMAND_BYTE, I8X_PUT_DATA_BYTE, I8X_GET_STATUS_BYTE, 
    // I8X_GET_DATA_BYTE. 
    // 
    BOOLEAN RegistersMapped; 
 
    BOOLEAN BreakOnSysRq; 
 
    BOOLEAN Headless; 
 
    BOOLEAN ReportResetErrors; 
 
} GLOBALS; 
 
extern GLOBALS Globals; 
 
#define RECORD_INIT               0x00000001 
#define RECORD_RESUME_FROM_POWER  0x00000002 
#define RECORD_DPC_RESET          0x00000004 
#define RECORD_DPC_RESET_POLLED   0x00000008 
#define RECORD_HW_PROFILE_CHANGE  0x00000010 
 
#if MOUSE_RECORD_ISR 
typedef struct _MOUSE_STATE_RECORD { 
    USHORT InputResetSubState; 
    USHORT InputState; 
    UCHAR  LastByte; 
    UCHAR  Reserved; 
    UCHAR  Byte; 
    UCHAR  Command; 
    LARGE_INTEGER Time; 
} MOUSE_STATE_RECORD, *PMOUSE_STATE_RECORD; 
 
extern PMOUSE_STATE_RECORD IsrStateHistory; 
extern PMOUSE_STATE_RECORD CurrentIsrState; 
extern PMOUSE_STATE_RECORD IsrStateHistoryEnd; 
extern ULONG               IsrStateCount; 
 
#define RECORD_ISR_STATE(devExt, byte, lastbyte, time)                  \ 
    if ((devExt->RecordHistoryFlags & devExt->RecordHistoryState)) {    \ 
        if (CurrentIsrState >= IsrStateHistoryEnd) {                    \ 
            CurrentIsrState = IsrStateHistory;                          \ 
            RtlFillMemory(CurrentIsrState, sizeof(MOUSE_STATE_RECORD), 0x88);  \ 
            CurrentIsrState++;                                          \ 
        }                                                               \ 
        CurrentIsrState->InputState = (USHORT) devExt->InputState;      \ 
        CurrentIsrState->InputResetSubState = (USHORT) devExt->InputResetSubState;    \ 
        CurrentIsrState->Byte = byte;                                   \ 
        CurrentIsrState->LastByte = lastbyte;                           \ 
        CurrentIsrState->Time = time;                                   \ 
        CurrentIsrState++;                                              \ 
    } 
 
#define RECORD_ISR_STATE_COMMAND(devExt, command)                     \ 
    if ((devExt->RecordHistoryFlags & devExt->RecordHistoryState))    \ 
            CurrentIsrState->Command = command;                        
 
#define RECORD_ISR_STATE_TRANSITION(devExt, state)                          \ 
    if ((devExt->RecordHistoryFlags & devExt->RecordHistoryState)) {        \ 
        if (CurrentIsrState >= IsrStateHistoryEnd) CurrentIsrState = IsrStateHistory; \ 
        RtlFillMemory(CurrentIsrState, sizeof(MOUSE_STATE_RECORD), 0xFF);   \ 
        CurrentIsrState->Time.LowPart  = state;                             \ 
        CurrentIsrState++;                                                  \ 
    } 
 
#define SET_RECORD_STATE(devExt, state)                                 \ 
    {                                                                   \ 
        if (IsrStateHistory) devExt->RecordHistoryState |= (state);     \ 
        RECORD_ISR_STATE_TRANSITION(devExt, state);                     \ 
    } 
 
#define CLEAR_RECORD_STATE(devExt) devExt->RecordHistoryState = 0x0; 
 
#define SET_RECORD_FLAGS(devExt, flags) if (IsrStateHistory) devExt->RecordHistoryFlags |= (flags) 
#define CLEAR_RECORD_FLAGS(devExt, flags) devExt->RecordHistoryFlags &= ~(flags) 
 
#else 
 
#define RECORD_ISR_STATE(devExt, byte, lastbyte, time)  
#define RECORD_ISR_STATE_COMMAND(devExt, command) 
#define SET_RECORD_STATE(devExt, state) 
#define CLEAR_RECORD_STATE(devExt) 
#define SET_RECORD_FLAGS(devExt, flags)  
#define CLEAN_RECORD_FLAGS(devExt, flags)  
 
#endif // MOUSE_RECORD_ISR 
 
typedef struct _I8X_KEYBOARD_WORK_ITEM { 
    PIO_WORKITEM  Item; 
    ULONG MakeCode; 
    PIRP Irp; 
} I8X_KEYBOARD_WORK_ITEM, *PI8X_KEYBOARD_WORK_ITEM; 
 
typedef struct _I8X_MOUSE_RESET_INFO { 
    PPORT_MOUSE_EXTENSION MouseExtension; 
    INTERNAL_RESET_STATE  InternalResetState; 
} I8X_MOUSE_RESET_INFO, * PI8X_MOUSE_RESET_INFO; 
 
// 
// Define the port TransmitControllerCommandByte context structure. 
// 
typedef struct _I8042_TRANSMIT_CCB_CONTEXT { 
    IN ULONG HardwareDisableEnableMask; 
    IN BOOLEAN AndOperation; 
    IN UCHAR ByteMask; 
    OUT NTSTATUS Status; 
} I8042_TRANSMIT_CCB_CONTEXT, *PI8042_TRANSMIT_CCB_CONTEXT; 
 
// 
// Define the port InitializeDataQueue context structure. 
// 
typedef struct _I8042_INITIALIZE_DATA_CONTEXT { 
    IN PVOID DeviceExtension; 
    IN CCHAR DeviceType; 
} I8042_INITIALIZE_DATA_CONTEXT, *PI8042_INITIALIZE_DATA_CONTEXT; 
 
// 
// Define the port Get/SetDataQueuePointer context structures. 
// 
typedef struct _GET_DATA_POINTER_CONTEXT { 
    IN PVOID DeviceExtension; 
    IN CCHAR DeviceType; 
    OUT PVOID DataIn; 
    OUT PVOID DataOut; 
    OUT ULONG InputCount; 
} GET_DATA_POINTER_CONTEXT, *PGET_DATA_POINTER_CONTEXT; 
 
typedef struct _SET_DATA_POINTER_CONTEXT { 
    IN PVOID DeviceExtension; 
    IN CCHAR DeviceType; 
    IN ULONG InputCount; 
    IN PVOID DataOut; 
} SET_DATA_POINTER_CONTEXT, *PSET_DATA_POINTER_CONTEXT; 
 
typedef struct _POWER_UP_WORK_ITEM { 
    WORK_QUEUE_ITEM Item; 
    PIRP MousePowerIrp; 
    PIRP KeyboardPowerIrp; 
} POWER_UP_WORK_ITEM, *PPOWER_UP_WORK_ITEM; 
 
// 
// Define the port timer context structure. 
// 
typedef struct _TIMER_CONTEXT { 
    IN PDEVICE_OBJECT DeviceObject; 
    IN PLONG TimerCounter; 
    OUT LONG NewTimerCount; 
} TIMER_CONTEXT, *PTIMER_CONTEXT; 
 
// 
// Define the device InitiateOutput context structure. 
// 
typedef struct INITIATE_OUTPUT_CONTEXT { 
    IN PDEVICE_OBJECT DeviceObject; 
    IN PUCHAR Bytes; 
    IN ULONG ByteCount; 
} INITIATE_OUTPUT_CONTEXT, *PINITIATE_OUTPUT_CONTEXT; 
 
// 
// Statically allocate the (known) scancode-to-indicator-light mapping. 
// This information is returned by the 
// IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION device control request. 
// 
 
#define KEYBOARD_NUMBER_OF_INDICATORS              3 
 
static const INDICATOR_LIST IndicatorList[KEYBOARD_NUMBER_OF_INDICATORS] = { 
        {0x3A, KEYBOARD_CAPS_LOCK_ON}, 
        {0x45, KEYBOARD_NUM_LOCK_ON}, 
        {0x46, KEYBOARD_SCROLL_LOCK_ON}}; 
 
// 
// Define the context structure and operations for I8xDpcVariableOperation. 
// 
typedef enum _OPERATION_TYPE { 
        IncrementOperation, 
        DecrementOperation, 
        WriteOperation, 
        ReadOperation 
} OPERATION_TYPE; 
 
typedef struct _VARIABLE_OPERATION_CONTEXT { 
    IN PLONG VariableAddress; 
    IN OPERATION_TYPE Operation; 
    IN OUT PLONG NewValue; 
} VARIABLE_OPERATION_CONTEXT, *PVARIABLE_OPERATION_CONTEXT; 
 
// 
// Define the actions to be taked on processing a system button 
// 
typedef enum _SYS_BUTTON_ACTION { 
    NoAction =0, 
    SendAction, 
    UpdateAction 
} SYS_BUTTON_ACTION; 
 
// 
// Function prototypes. 
// 
 
// begin_i8042dep 
NTSTATUS 
DriverEntry( 
    IN PDRIVER_OBJECT DriverObject, 
    IN PUNICODE_STRING RegistryPath 
    ); 
 
BOOLEAN 
I8xDetermineSharedInterrupts( 
    VOID 
    ); 
 
VOID 
I8xDrainOutputBuffer( 
    IN PUCHAR DataAddress, 
    IN PUCHAR CommandAddress 
    ); 
 
VOID 
I8xGetByteAsynchronous( 
    IN CCHAR DeviceType, 
    OUT PUCHAR Byte 
    ); 
 
NTSTATUS 
I8xGetBytePolled( 
    IN CCHAR DeviceType, 
    OUT PUCHAR Byte 
    ); 
 
VOID 
I8xGetDataQueuePointer( 
    IN PGET_DATA_POINTER_CONTEXT Context 
    ); 
 
VOID 
I8xInitializeHardware( 
    NTSTATUS *KeyboardStatus, 
    NTSTATUS *MouseStatus, 
    ULONG    InitFlags  
    ); 
 
NTSTATUS 
I8xInitializeHardwareAtBoot( 
    NTSTATUS *KeyboardStatus, 
    NTSTATUS *MouseStatus 
    ); 
 
VOID 
I8xLogError( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN NTSTATUS ErrorCode, 
    IN ULONG UniqueErrorValue, 
    IN NTSTATUS FinalStatus, 
    IN PULONG DumpData, 
    IN ULONG DumpCount 
    ); 
 
VOID 
I8xPutByteAsynchronous( 
    IN CCHAR PortType, 
    IN UCHAR Byte 
    ); 
 
NTSTATUS 
I8xPutBytePolled( 
    IN CCHAR PortType, 
    IN BOOLEAN WaitForAcknowledge, 
    IN CCHAR AckDeviceType, 
    IN UCHAR Byte 
    ); 
 
VOID 
I8xReinitializeHardware ( 
    PPOWER_UP_WORK_ITEM Item 
    ); 
 
VOID 
I8xServiceParameters( 
    IN PUNICODE_STRING RegistryPath 
    ); 
 
NTSTATUS 
I8xGetControllerCommand( 
    IN ULONG HardwareDisableEnableMask, 
    OUT PUCHAR Byte 
    ); 
 
NTSTATUS 
I8xPutControllerCommand( 
    IN UCHAR Byte 
    ); 
 
NTSTATUS 
I8xToggleInterrupts( 
    BOOLEAN State 
    ); 
 
NTSTATUS 
I8xPutControllerCommand( 
    IN UCHAR Byte 
    ); 
 
VOID 
I8xTransmitControllerCommand( 
    IN PI8042_TRANSMIT_CCB_CONTEXT TransmitCCBContext 
    ); 
// end_i8042dep 
 
// begin_i8042cmn 
NTSTATUS 
I8xClose ( 
    IN PDEVICE_OBJECT    DeviceObject, 
    IN PIRP              Irp 
    ); 
 
VOID 
I8042CompletionDpc( 
    IN PKDPC Dpc, 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN ISR_DPC_CAUSE IsrDpcCause 
    ); 
 
IO_ALLOCATION_ACTION 
I8xControllerRoutine ( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp, 
    IN PVOID          MapRegisterBase, 
    IN PVOID          Context 
    ); 
 
NTSTATUS 
I8xCreate ( 
    IN PDEVICE_OBJECT    DeviceObject, 
    IN PIRP              Irp 
    ); 
 
VOID 
I8xDecrementTimer( 
    IN PTIMER_CONTEXT Context 
    ); 
 
VOID 
I8xDpcVariableOperation( 
    IN  PVOID Context 
    ); 
 
VOID 
I8042ErrorLogDpc( 
    IN PKDPC Dpc, 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN PVOID Context 
    ); 
 
NTSTATUS 
I8xFlush( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ); 
 
VOID 
I8xInitializeDataQueue( 
    IN PI8042_INITIALIZE_DATA_CONTEXT InitializeDataContext 
    ); 
 
VOID 
I8xInitiateOutputWrapper( 
    IN PINITIATE_OUTPUT_CONTEXT InitiateContext  
    ); 
 
VOID 
I8xInitiateIo( 
    IN PDEVICE_OBJECT DeviceObject 
    ); 
 
NTSTATUS 
I8xDeviceControl( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ); 
 
NTSTATUS 
I8xInternalDeviceControl( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ); 
 
VOID 
I8042RetriesExceededDpc( 
    IN PKDPC Dpc, 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN PVOID Context 
    ); 
 
BOOLEAN 
I8xSanityCheckResources( 
    VOID 
    ); 
 
NTSTATUS 
I8xSendIoctl( 
    PDEVICE_OBJECT      Target, 
    ULONG               Ioctl, 
    PVOID               InputBuffer, 
    ULONG               InputBufferLength 
    ); 
 
VOID 
I8xSetDataQueuePointer( 
    IN PSET_DATA_POINTER_CONTEXT Context 
    ); 
 
VOID 
I8xStartIo( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ); 
 
VOID 
I8xCompletePendedRequest( 
    PDEVICE_OBJECT DeviceObject, 
    PIRP Irp, 
    ULONG_PTR Information, 
    NTSTATUS Status 
    ); 
 
VOID 
I8xFinishResetRequest( 
    PPORT_MOUSE_EXTENSION MouseExtension, 
    BOOLEAN Failed, 
    BOOLEAN RaiseIrql, 
    BOOLEAN CancelTimer 
    ); 
 
VOID 
I8042TimeOutDpc( 
    IN PKDPC Dpc, 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PVOID SystemContext1, 
    IN PVOID SystemContext2 
    ); 
// end_i8042cmn 
 
// begin_kbddep 
UCHAR 
I8xConvertTypematicParameters( 
    IN USHORT Rate, 
    IN USHORT Delay 
    ); 
 
NTSTATUS 
I8xInitializeKeyboard( 
    IN PPORT_KEYBOARD_EXTENSION KeyboardExtension 
    ); 
 
NTSTATUS 
I8xKeyboardConfiguration( 
    IN PPORT_KEYBOARD_EXTENSION KeyboardExtension, 
    IN PCM_RESOURCE_LIST ResourceList 
    ); 
 
BOOLEAN 
I8042KeyboardInterruptService( 
    IN PKINTERRUPT Interrupt, 
    IN PDEVICE_OBJECT DeviceObject 
    ); 
 
VOID 
I8xKeyboardServiceParameters( 
    IN PUNICODE_STRING          RegistryPath, 
    IN PPORT_KEYBOARD_EXTENSION KeyboardExtension 
    ); 
 
VOID 
I8xQueueCurrentKeyboardInput( 
    IN PDEVICE_OBJECT DeviceObject 
    ); 
// end_kbddep 
 
// begin_kbdcmn 
VOID 
I8042KeyboardIsrDpc( 
    IN PKDPC Dpc, 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN PVOID Context 
    ); 
 
BOOLEAN 
I8xWriteDataToKeyboardQueue( 
    IN PPORT_KEYBOARD_EXTENSION KeyboardExtension, 
    IN PKEYBOARD_INPUT_DATA InputData 
    ); 
// end_kbdcmn 
 
// begin_kbdpnp 
NTSTATUS 
I8xKeyboardConnectInterrupt( 
    PPORT_KEYBOARD_EXTENSION KeyboardExtension 
    ); 
 
NTSTATUS 
I8xKeyboardInitializeHardware( 
    PPORT_KEYBOARD_EXTENSION    KeyboardExtension, 
    PPORT_MOUSE_EXTENSION       MouseExtension 
    ); 
 
VOID 
I8xKeyboardRemoveDevice( 
    PDEVICE_OBJECT DeviceObject 
    ); 
 
NTSTATUS 
I8xKeyboardStartDevice( 
    IN OUT PPORT_KEYBOARD_EXTENSION KeyboardExtension, 
    IN PCM_RESOURCE_LIST ResourceList 
    ); 
// end_kbdpnp 
 
// begin_moucmn 
VOID 
I8042MouseIsrDpc( 
    IN PKDPC Dpc, 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN PVOID Context 
    ); 
 
BOOLEAN 
I8xWriteDataToMouseQueue( 
    IN PPORT_MOUSE_EXTENSION MouseExtension, 
    IN PMOUSE_INPUT_DATA InputData 
    ); 
// end_moucmn 
 
// begin_moudep 
NTSTATUS 
I8xMouseConfiguration( 
    IN PPORT_MOUSE_EXTENSION MouseExtension, 
    IN PCM_RESOURCE_LIST ResourceList 
    ); 
 
VOID 
MouseCopyWheelIDs( 
    PUNICODE_STRING Destination, 
    PUNICODE_STRING Source 
    ); 
 
NTSTATUS 
I8xMouseEnableTransmission( 
    IN PPORT_MOUSE_EXTENSION MouseExtension 
    ); 
 
NTSTATUS 
I8xTransmitByteSequence( 
    PUCHAR Bytes, 
    ULONG* UniqueErrorValue, 
    ULONG* ErrorCode, 
    ULONG* DumpData, 
    ULONG* DumpCount 
    ); 
 
NTSTATUS 
I8xGetBytePolledIterated( 
    IN CCHAR DeviceType, 
    OUT PUCHAR Byte, 
    ULONG Attempts 
    ); 
 
NTSTATUS 
I8xFindWheelMouse( 
    IN PPORT_MOUSE_EXTENSION MouseExtension 
    ); 
 
NTSTATUS 
I8xInitializeMouse( 
    IN PPORT_MOUSE_EXTENSION MouseExension 
    ); 
 
BOOLEAN 
I8042MouseInterruptService( 
    IN PKINTERRUPT Interrupt, 
    IN PVOID Context 
    ); 
 
NTSTATUS 
I8xQueryNumberOfMouseButtons( 
    OUT PUCHAR          NumberOfMouseButtons 
    ); 
 
NTSTATUS 
I8xResetMouse( 
    PPORT_MOUSE_EXTENSION MouseExtension 
    ); 
 
VOID 
I8xResetMouseFailed( 
    PPORT_MOUSE_EXTENSION MouseExtension 
    ); 
 
VOID 
I8xSendResetCommand ( 
    PPORT_MOUSE_EXTENSION MouseExtension 
    ); 
 
VOID 
I8xMouseServiceParameters( 
    IN PUNICODE_STRING       RegistryPath, 
    IN PPORT_MOUSE_EXTENSION MouseExtension 
    ); 
 
VOID 
I8xQueueCurrentMouseInput( 
    IN PDEVICE_OBJECT DeviceObject 
    ); 
 
BOOLEAN 
I8xVerifyMousePnPID( 
    PPORT_MOUSE_EXTENSION   MouseExtension, 
    PWSTR                   MouseID 
    ); 
// end_moudep 
 
// begin_moupnp 
NTSTATUS 
I8xMouseConnectInterruptAndEnable( 
    PPORT_MOUSE_EXTENSION MouseExtension, 
    BOOLEAN Reset 
    ); 
 
NTSTATUS 
I8xMouseInitializeHardware( 
    PPORT_KEYBOARD_EXTENSION    KeyboardExtension, 
    PPORT_MOUSE_EXTENSION       MouseExtension 
    ); 
 
NTSTATUS 
I8xProfileNotificationCallback( 
    IN PHWPROFILE_CHANGE_NOTIFICATION NotificationStructure, 
    PPORT_MOUSE_EXTENSION MouseExtension 
    ); 
 
VOID 
I8xMouseRemoveDevice( 
    PDEVICE_OBJECT DeviceObject 
    ); 
 
NTSTATUS 
I8xMouseStartDevice( 
    PPORT_MOUSE_EXTENSION MouseExtension, 
    IN PCM_RESOURCE_LIST ResourceList 
    ); 
 
BOOLEAN 
I8xMouseEnableSynchRoutine( 
    IN PPORT_MOUSE_EXTENSION    MouseExtension 
    ); 
 
VOID 
I8xMouseEnableDpc( 
    IN PKDPC                    Dpc, 
    IN PPORT_MOUSE_EXTENSION    MouseExtension, 
    IN PVOID                    SystemArg1,  
    IN PVOID                    SystemArg2 
    ); 
 
VOID  
I8xIsrResetDpc( 
    IN PKDPC                    Dpc, 
    IN PPORT_MOUSE_EXTENSION    MouseExtension, 
    IN ULONG                    ResetPolled, 
    IN PVOID                    SystemArg2 
    ); 
 
VOID 
I8xMouseResetTimeoutProc( 
    IN PKDPC                    Dpc, 
    IN PPORT_MOUSE_EXTENSION    MouseExtension, 
    IN PVOID                    SystemArg1,  
    IN PVOID                    SystemArg2 
    ); 
 
BOOLEAN 
I8xMouseResetSynchRoutine( 
    PI8X_MOUSE_RESET_INFO ResetInfo  
    ); 
 
VOID 
I8xMouseInitializeInterruptWorker( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIO_WORKITEM   Item  
    ); 
 
VOID 
I8xMouseInitializePolledWorker( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIO_WORKITEM   Item  
    ); 
// end_moupnp 
 
// begin_pnp 
NTSTATUS 
I8xAddDevice ( 
    IN PDRIVER_OBJECT   Driver, 
    IN PDEVICE_OBJECT   PDO 
    ); 
 
NTSTATUS 
I8xFilterResourceRequirements( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ); 
 
NTSTATUS 
I8xFindPortCallout( 
    IN PVOID                        Context, 
    IN PUNICODE_STRING              PathName, 
    IN INTERFACE_TYPE               BusType, 
    IN ULONG                        BusNumber, 
    IN PKEY_VALUE_FULL_INFORMATION *BusInformation, 
    IN CONFIGURATION_TYPE           ControllerType, 
    IN ULONG                        ControllerNumber, 
    IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, 
    IN CONFIGURATION_TYPE           PeripheralType, 
    IN ULONG                        PeripheralNumber, 
    IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation 
    ); 
 
LONG 
I8xManuallyRemoveDevice( 
    PCOMMON_DATA CommonData 
    ); 
 
NTSTATUS 
I8xPnP ( 
    IN PDEVICE_OBJECT    DeviceObject, 
    IN PIRP              Irp 
    ); 
 
NTSTATUS 
I8xPnPComplete ( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN PKEVENT Event 
    ); 
 
NTSTATUS 
I8xPower ( 
    IN PDEVICE_OBJECT    DeviceObject, 
    IN PIRP              Irp 
    ); 
 
NTSTATUS 
I8xPowerUpToD0Complete( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN PVOID Context 
    ); 
 
void 
I8xSetPowerFlag( 
    IN ULONG Flag, 
    IN BOOLEAN Set 
    ); 
 
NTSTATUS 
I8xRegisterDeviceInterface( 
    PDEVICE_OBJECT PDO, 
    CONST GUID *Guid, 
    PUNICODE_STRING SymbolicName 
    ); 
 
BOOLEAN 
I8xRemovePort( 
    IN PIO_RESOURCE_DESCRIPTOR ResDesc 
    ); 
 
NTSTATUS 
I8xSendIrpSynchronously ( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN BOOLEAN Strict 
    ); 
 
VOID 
I8xUnload( 
    IN PDRIVER_OBJECT DriverObject 
    ); 
// end_pnp 
 
// begin_sysbtn 
VOID 
I8xCompleteSysButtonIrp( 
    PIRP Irp, 
    ULONG Event, 
    NTSTATUS Status 
    ); 
 
#if DELAY_SYSBUTTON_COMPLETION 
VOID  
I8xCompleteSysButtonEventWorker( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PI8X_KEYBOARD_WORK_ITEM Item 
    ); 
#endif 
 
NTSTATUS 
I8xKeyboardGetSysButtonCaps( 
    PPORT_KEYBOARD_EXTENSION KeyboardExtension, 
    PIRP Irp 
    ); 
 
NTSTATUS  
I8xKeyboardGetSysButtonEvent( 
    PPORT_KEYBOARD_EXTENSION KeyboardExtension, 
    PIRP Irp 
    ); 
 
VOID 
I8xKeyboardSysButtonEventDpc( 
    IN PKDPC Dpc, 
    IN PDEVICE_OBJECT DeviceObject, 
    IN SYS_BUTTON_ACTION Action,  
    IN ULONG ButtonEvent  
    ); 
 
VOID 
I8xSysButtonCancelRoutine(  
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ); 
// end_sysbtn 
 
// begin_hook 
VOID 
I8xMouseIsrWritePort( 
    IN PDEVICE_OBJECT   DeviceObject, 
    IN UCHAR            Value 
    ); 
 
VOID 
I8xKeyboardIsrWritePort( 
    IN PDEVICE_OBJECT   DeviceObject, 
    IN UCHAR            Value 
    ); 
 
NTSTATUS  
I8xKeyboardSynchReadPort ( 
    IN PDEVICE_OBJECT   DeviceObject, 
    IN PUCHAR           Value, 
    IN BOOLEAN          Dummy 
    ); 
 
NTSTATUS  
I8xKeyboardSynchWritePort ( 
    IN PDEVICE_OBJECT   DeviceObject,                            
    IN UCHAR            Value, 
    IN BOOLEAN          WaitForACK 
    ); 
// end_hook 
 
// begin_wmi 
NTSTATUS 
I8xSystemControl ( 
    IN PDEVICE_OBJECT    DeviceObject, 
    IN PIRP              Irp 
    ); 
 
NTSTATUS 
I8xInitWmi( 
    PCOMMON_DATA CommonData 
    ); 
 
NTSTATUS 
I8xSetWmiDataBlock( 
    IN PDEVICE_OBJECT   DeviceObject, 
    IN PIRP             Irp, 
    IN ULONG            GuidIndex, 
    IN ULONG            InstanceIndex, 
    IN ULONG            BufferSize, 
    IN PUCHAR           Buffer 
    ); 
 
NTSTATUS 
I8xSetWmiDataItem( 
    IN PDEVICE_OBJECT   DeviceObject, 
    IN PIRP             Irp, 
    IN ULONG            GuidIndex, 
    IN ULONG            InstanceIndex, 
    IN ULONG            DataItemId, 
    IN ULONG            BufferSize, 
    IN PUCHAR           Buffer 
    ); 
 
NTSTATUS 
I8xKeyboardQueryWmiDataBlock( 
    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 
I8xMouseQueryWmiDataBlock( 
    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 
I8xQueryWmiRegInfo( 
    IN PDEVICE_OBJECT   DeviceObject, 
    OUT PULONG          RegFlags, 
    OUT PUNICODE_STRING InstanceName, 
    OUT PUNICODE_STRING *RegistryPath, 
    OUT PUNICODE_STRING MofResourceName, 
    OUT PDEVICE_OBJECT  *Pdo 
    ); 
 
 
// end_wmi 
 
// 
// Flags to represent modifier key states  
// 
#define CRASH_R_SHIFT  0x01 
#define CRASH_R_CTRL   0x02 
#define CRASH_R_ALT    0x04 
 
#define CRASH_L_SHIFT  0x10 
#define CRASH_L_CTRL   0x20 
#define CRASH_L_ALT    0x40 
 
#define CRASH_FIRST_TIME   0x100 
#define CRASH_SECOND_TIME  0x200 
#define CRASH_BOTH_TIMES (CRASH_FIRST_TIME | CRASH_SECOND_TIME) 
 
VOID 
I8xProcessCrashDump( 
    PPORT_KEYBOARD_EXTENSION DeviceExtension, 
    UCHAR ScanCode, 
    KEYBOARD_SCAN_STATE ScanState 
    ); 
 
VOID 
I8xServiceCrashDump( 
    IN PPORT_KEYBOARD_EXTENSION DeviceExtension, 
    IN PUNICODE_STRING          RegistryPath 
    ); 
 
#if defined(_X86_) 
#ifndef _FJKBD_H_ 
#define _FJKBD_H_ 
 
// 
// oyayubi-shift keyboard internal input mode value. 
// 
#define THUMB_NOROMAN_ALPHA_CAPSON     0x01 
#define THUMB_NOROMAN_ALPHA_CAPSOFF    0x02 
#define THUMB_NOROMAN_HIRAGANA         0x03 
#define THUMB_NOROMAN_KATAKANA         0x04 
#define THUMB_ROMAN_ALPHA_CAPSON       0x05 
#define THUMB_ROMAN_ALPHA_CAPSOFF      0x06 
#define THUMB_ROMAN_HIRAGANA           0x07 
#define THUMB_ROMAN_KATAKANA           0x08 
 
// 
// Following functions are oyayubi-shift keyboard use only. 
// 
NTSTATUS 
I8042SetIMEStatusForOasys( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN OUT PINITIATE_OUTPUT_CONTEXT InitiateContext 
    ); 
 
ULONG 
I8042QueryIMEStatusForOasys( 
    IN PKEYBOARD_IME_STATUS KeyboardIMEStatus 
    ); 
 
VOID 
I8xKeyboardInitiateIoForOasys( 
    IN PDEVICE_OBJECT DeviceObject 
    ); 
#endif // _FJKBD_H_ 
#endif // _X86_ 
 
#if DBG 
#define DEFAULT_DEBUG_FLAGS 0x88888808 // 0x8cc8888f 
#else  
#define DEFAULT_DEBUG_FLAGS 0x0  
#endif 
 
 
#if I8042_VERBOSE 
// 
//Debug messaging and breakpoint macros 
// 
#define DBG_ALWAYS                 0x00000000 
 
#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_DPC_MASK              0x0000F000 
#define DBG_DPC_NOISE             0x00001000 
#define DBG_DPC_TRACE             0x00002000 
#define DBG_DPC_INFO              0x00004000 
#define DBG_DPC_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_BUFIO_MASK            0xF0000000 
#define DBG_BUFIO_NOISE           0x10000000 
#define DBG_BUFIO_TRACE           0x20000000 
#define DBG_BUFIO_INFO            0x40000000 
#define DBG_BUFIO_ERROR           0x80000000 
 
#define DBG_KBISR_NOISE           0x00000001 
#define DBG_KBISR_TRACE           0x00000002 
#define DBG_KBISR_INFO            0x00000004 
#define DBG_KBISR_ERROR           0x00000008 
 
#define DBG_KBISR_STATE           0x00000010 
#define DBG_KBISR_SCODE           0x00000020 
#define DBG_KBISR_BREAK           0x00000040 
#define DBG_KBISR_EMUL            0x00000080 
 
#define DBG_KBISR_POWER            0x00000100 
 
#define DBG_MOUISR_MASK            0x000F0000 
#define DBG_MOUISR_NOISE           0x00010000 
#define DBG_MOUISR_TRACE           0x00020000 
#define DBG_MOUISR_INFO            0x00040000 
#define DBG_MOUISR_ERROR           0x00080000 
 
#define DBG_MOUISR_STATE           0x00100000 
#define DBG_MOUISR_BYTE            0x00200000 
#define DBG_MOUISR_RESETTING       0x00400000 
#define DBG_MOUISR_ACK             0x00800000 
 
#define DBG_MOUISR_PNPID           0x01000000 
#define DBG_MOUISR_BREAK           0x02000000 
// #define DBG_MOUISR_BREAK           0x04000000 
 
#define Print(_flags_, _x_) \ 
            if (Globals.DebugFlags & (_flags_) || !(_flags_)) { \ 
                DbgPrint (pDriverName); \ 
                DbgPrint _x_; \ 
            } 
#define IsrPrint(_flags_, _x_) \ 
            if (Globals.IsrDebugFlags & (_flags_) || !(_flags_)) { \ 
                DbgPrint (((ULONG)(_flags_)) >= 0x0001000 ? pIsrMou : pIsrKb); \ 
                DbgPrint _x_; \ 
            } 
#define TRAP() DbgBreakPoint() 
 
#else 
 
#define Print(_l_,_x_) 
#define IsrPrint(_l_,_x_) 
#define TRAP() 
 
#endif  // I8042_VERBOSE 
 
static UCHAR ScanCodeToUChar[] = { 
    0x00,            // Nothing 
    0x00,            // Esc 
    '1', 
    '2', 
    '3', 
    '4', 
    '5', 
    '6', 
    '7', 
    '8', 
    '9', 
    '0', 
    '-', 
    '=', 
    0x00,           // Backspace 
    0x00,           // Tab 
    'Q', 
    'W', 
    'E', 
    'R', 
    'T', 
    'Y', 
    'U', 
    'I', 
    'O', 
    'P', 
    '[', 
    ']', 
    '\\', 
    0x00,            // Caps lock 
    'A', 
    'S', 
    'D', 
    'F', 
    'G', 
    'H', 
    'I', 
    'J', 
    'K', 
    'L', 
    ';', 
    '\'', 
    0x00,           // Return 
    0x00,           // Shift left 
    'Z', 
    'X', 
    'C', 
    'V', 
    'B', 
    'N', 
    'M', 
    ',', 
    '.', 
    '/' 
    }; 
 
 
static const int ScanCodeToUCharCount = sizeof(ScanCodeToUChar)/sizeof(UCHAR); 
    /* 
    0x00,           // Shift right 
    0x00,           // Ctrl left 
    0x00,           // Alt left 
    ' ',  
    0x00,           // Alt right 
    0x00,           // Ctrl right 
    0x00,           // num lock 
    */ 
 
#define CTRL_SCANCODE          0x1d 
#define LEFT_SHIFT_SCANCODE    0x2A 
#define RIGHT_SHIFT_SCANCODE   0x36 
#define ALT_SCANCODE           0x38 
#define SCROLL_LOCK_SCANCODE   0x46 
 
#endif // _I8042PRT_