1:function.h

#ifndef FUNCTION_H
#define FUNCTION_H

#define DRIVER_FUNCTION_ADD_DEVICE
#define DRIVER_FUNCTION_UNLOAD
#define DRIVER_FUNCTION_INTERNAL_DEVICE_CONTROL
#define DRIVER_FUNCTION_PNP
#define DRIVER_FUNCTION_POWER
#define DRIVER_FUNCTION_STARTIO
#endif

2:hidemouse.h

#ifndef HIDMOUSE_H_
#defin HIDMOUSE_H_
#define IOCTL_VHIDMOU_MOVE \
    CTL_CODE(FILE_DEVICE_MOUSE, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS)

#define IOCTL_VHIDMOU_CLICK \
    CTL_CODE(FILE_DEVICE_MOUSE, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS)

struct MOUSE_MOVE_INFO
{
    ULONG deltaX;
    ULONG deltaY;
};

struct MOUSE_CLICK_INFO
{
    ULONG LeftOrRight;
    ULONG UpOrDown;
};
#endif
3:vhidmou.h

#ifndef VHIDMOU_H_
#define VHIDMOU_H_
class VirtualHidMouseDriver : public KHidMiniDriver
{
    SAFE_DESTRUCTORS
    virtual NTSTATUS AddDevice(PDEVICE_OBJECT PnpDeviceObject);
};
#endif
4:vmoudev.h

#ifndef MODEV_H_
#define MODEV_H_

#define MY_VENDOR_ID    0x0001
#define MY_PRODUCT_ID    0x0002
#define VERSION_NUMBER  0x0101

class VirtualHidMouse : public KHidDevice
{
    SAFE_DESTRUCTORS
public:
    VirtualHidMouse(PDEVICE_OBJECT Fdo);

virtual NTSTATUS DefaultHidRequestHandler(KIrp I);
    virtual NTSTATUS DefaultPnp(KIrp I);
    virtual NTSTATUS DefaultPower(KIrp I);

virtual NTSTATUS OnStartDevice(KIrp I);
    virtual NTSTATUS OnStopDevice(KIrp I);
    virtual NTSTATUS OnQueryRemoveDevice(KIrp I);
    virtual NTSTATUS OnQueryStopDevice(KIrp I);
    virtual NTSTATUS OnCancelRemoveDevice(KIrp I);
    virtual NTSTATUS OnCancelStopDevice(KIrp I);
    virtual NTSTATUS OnRemoveDevice(KIrp I);

virtual VOID StartIo(KIrp I);

virtual NTSTATUS ReadReport(KIrp I);

// Other
    VOID Move(CHAR deltaX, CHAR deltaY);
    VOID Click(ULONG LeftOrRight, ULONG UpOrDown);
    VOID UpdateState(void);

DEVMEMBER_CANCELIRP (VirtualHidMouse, CancelQueuedIrp)

#ifdef __COMMENT_ONLY
    VOID CancelQueuedIrp(KIrp I);
#endif

NTSTATUS IsStoppable(void) { return STATUS_SUCCESS; }
    NTSTATUS IsRemovable(void) { return STATUS_SUCCESS; }

// Data

CHAR  m_DeltaX;
    CHAR  m_DeltaY;
    UCHAR m_OldButtonState;
    UCHAR m_NewButtonState;

KSpinLock m_Lock;
    KVxDInterface m_Vxd;
    KPnpLowerDevice m_Pdo;
};

// Handler for VxD interface
ULONG __stdcall VxdControlMessageHandler(
    ULONG Edi,
    ULONG Esi,
    ULONG Ebp,
    ULONG Esp,
    ULONG Ebx,
    ULONG Edx,
    ULONG Ecx,
    ULONG ControlMessage,
    PVOID Context,
    ULONG* pCarryBitReturn
    );

struct MouseReport
{
    CHAR buttons;
    CHAR deltaX;
    CHAR deltaY;
};

#define LEFT_BUTTON 1
#define RIGHT_BUTTON 2

#endif
5:vhidmou.cpp

#define VDW_MAIN
#include <khid.h>
#include "vhidmou.h"    // the device class
#include "vmoudev.h"    // the driver class

#pragma code_seg("INIT")

DECLARE_DRIVER_CLASS(VirtualHidMouseDriver, NULL)

#pragma code_seg()

NTSTATUS VirtualHidMouseDriver::AddDevice(PDEVICE_OBJECT Fdo)
{
    NTSTATUS status;

VirtualHidMouse* p = new (NonPagedPool) VirtualHidMouse(Fdo);

if (p == NULL)
        status = STATUS_INSUFFICIENT_RESOURCES;

else
    {
        status = p->ConstructorStatus();
        if ( !NT_SUCCESS(status) )
            delete p;
    }

return status;
}

6:vmoudev.cpp

#include <khid.h>
#include "vmoudev.h"
#include "hidmouse.h"

KTrace T("",TRACE_MONITOR, TraceAlways, BreakNever, KUstring(L"HidMouse"));

#define SCALEX 3
#define SCALEY 3

HID_REPORT_DESCRIPTOR MouseHidReportDesc[] = {
    0x05, 0x01,    // Usage Page (Generic Desktop),
    0x09, 0x02,    // Usage (Mouse),  
    0xA1, 0x01,    // Collection (Application),    
    0x09, 0x01,    // Usage (Pointer),     
    0xA1, 0x00,    // Collection (Physical),        
    0x05, 0x09,    // Usage Page (Buttons),        
    0x19, 0x01,    // Usage Minimum (01),        
    0x29, 0x03,    // Usage Maximun (03),        
    0x15, 0x00,    // Logical Minimum (0),         
    0x25, 0x01,    // Logical Maximum (1),         
    0x95, 0x03,    // Report Count (3),         
    0x75, 0x01,    // Report Size (1),        
    0x81, 0x02,    // Input (Data, Variable, Absolute),    ;3 button bits        
    0x95, 0x01,    // Report Count (1),        
    0x75, 0x05,    // Report Size (5),        
    0x81, 0x01,    // Input (Constant),            ;5 bit padding        
    0x05, 0x01,    // Usage Page (Generic Desktop),        
    0x09, 0x30,    // Usage (X),         
    0x09, 0x31,    // Usage (Y),        
    0x15, 0x81,    // Logical Minimum (-127),         
    0x25, 0x7F,    // Logical Maximum (127),         
    0x75, 0x08,    // Report Size (8),         
    0x95, 0x02,    // Report Count (2),         
    0x81, 0x06,    // Input (Data, Variable, Relative),    ;2 position bytes (X & Y)    
    0xC0,         // End Collection,
    0xC0        // End Collection
    };

WCHAR HardwareID[]={L"ROOT\\NUMEGA_VIRTUAL_HID_MOUSE\0"};
WCHAR DeviceID[]  ={L"ROOT\\NUMEGA_VIRTUAL_HID_MOUSE\0"};

HID_DEVICE_ATTRIBUTES DeviceAttributes = {
    sizeof(HID_DEVICE_ATTRIBUTES),    
    MY_VENDOR_ID,
    MY_PRODUCT_ID,
    VERSION_NUMBER
    };

// Device String
struct
{
    HID_STRING_DESCRIPTOR Sd1;
    WCHAR Str1[14];
    HID_STRING_DESCRIPTOR Sd2;
    WCHAR Str2[9];
} TheDeviceString = {
        { 30, 3},  {'V','i','r','e','o',' ','S','o','f','t','w','a','r','e'},
        { 20, 3},  {'H','i','d',' ','M','o','u','s','e'}
    };

VirtualHidMouse* DeviceInstance=NULL;

VirtualHidMouse::VirtualHidMouse(PDEVICE_OBJECT Fdo) :
    KHidDevice(
        Fdo,
        MouseHidReportDesc,
        sizeof MouseHidReportDesc,
        DeviceID,
        HardwareID,
        NULL,
        NULL,
        &DeviceAttributes,
        &TheDeviceString.Sd1,
        sizeof TheDeviceString,
        0        
        )
{
    DeviceInstance = this;

m_DeltaX = m_DeltaY = 0;
    m_OldButtonState = m_NewButtonState = 0;

// Set up the PDO connection

m_Pdo.Initialize(PDO(), TopOfStack());

SetLowerDevice(&m_Pdo);

// Set standard policies
    SetPnpPolicy();

// Customize the policy for canceling the current IRP
    m_Policies.m_QueryRemovePolicy.m_CancelCurrentIrp = TRUE;

// Set up the VxD interface
    m_Vxd.Initialize("VHIDMSE", VxdControlMessageHandler, this);
}

NTSTATUS VirtualHidMouse::ReadReport(KIrp I)
{
    return QueueIrp(I, LinkTo(CancelQueuedIrp));    // queue to device queue.

}

VOID VirtualHidMouse::CancelQueuedIrp(KIrp I)
{
    KDeviceQueue dq(DeviceQueue());

if ( (PIRP)I == CurrentIrp() )
    {
        CurrentIrp() = NULL;
        CancelSpinLock::Release(I.CancelIrql());
        T << "Read IRP canceled " << I << "\n";
        I.Information() = 0;
        I.Status() = STATUS_CANCELLED;
        PnpNextIrp(I);
    }
    else if (dq.RemoveSpecificEntry(I))
    {
        CancelSpinLock::Release(I.CancelIrql());
        T << "Read IRP canceled " << I << "\n";
        I.Information() = 0;
        I.PnpComplete(this, STATUS_CANCELLED);
    }
    else
    {
        CancelSpinLock::Release(I.CancelIrql());
    }
}

// StartIo

VOID VirtualHidMouse::StartIo(KIrp I)
{
    ASSERT (I.MajorFunction() == IRP_MJ_INTERNAL_DEVICE_CONTROL);
    ASSERT (I.IoctlCode() == IOCTL_HID_READ_REPORT);

UpdateState();
}

VOID VirtualHidMouse::UpdateState(void)
{
    KIrp I=CurrentIrp();

if ( !I.IsNull() )
    {
        m_Lock.Lock();

if ( (m_DeltaX != 0) ||
             (m_DeltaY != 0) ||
             (m_NewButtonState != m_OldButtonState)
           )
        {

if ( !I.TestAndSetCancelRoutine(
                LinkTo(CancelQueuedIrp),
                NULL,
                CurrentIrp()) )
            {
                
                return;
            }

MouseReport* pReport = (MouseReport*)I.UserBuffer();

pReport->buttons = m_NewButtonState;
            pReport->deltaX = m_DeltaX;
            pReport->deltaY = m_DeltaY;

m_DeltaX = m_DeltaY = 0;
            m_OldButtonState = m_NewButtonState;

I.Information() = sizeof(MouseReport);
            I.Status() = STATUS_SUCCESS;

m_Lock.Unlock();
            PnpNextIrp(I);
        }
        else
            m_Lock.Unlock();
    }
}

VOID VirtualHidMouse::Move(CHAR DeltaX, CHAR DeltaY)
{
    m_Lock.Lock();

m_DeltaX += DeltaX*SCALEX;
    m_DeltaY += DeltaY*SCALEY;

m_Lock.Unlock();

UpdateState();
}

VOID VirtualHidMouse::Click(ULONG LeftOrRight, ULONG DownOrUp)
{
    m_Lock.Lock();

if (DownOrUp != 0)     // down
    {
        if (LeftOrRight != 0) // left
            m_NewButtonState = (m_OldButtonState | LEFT_BUTTON);
        else // right
            m_NewButtonState = (m_OldButtonState | RIGHT_BUTTON);
    }
    else    // up
    {
        if (LeftOrRight != 0) // left
            m_NewButtonState = (m_OldButtonState & ~LEFT_BUTTON);
        else // right
            m_NewButtonState = (m_OldButtonState & ~RIGHT_BUTTON);
    }

m_Lock.Unlock();

UpdateState();
}

NTSTATUS VirtualHidMouse::DefaultHidRequestHandler(KIrp I)
{
    T << "Unhandled HID request\n";

I.ForceReuseOfCurrentStackLocationInCalldown();
    return m_Pdo.PnpCall(this, I);
}

NTSTATUS VirtualHidMouse::DefaultPnp(KIrp I)
{
    T << "Unhandled Pnp request, minor=" << ULONG(I.MinorFunction()) << "\n";
    
    I.ForceReuseOfCurrentStackLocationInCalldown();
    return m_Pdo.PnpCall(this, I);
}

NTSTATUS VirtualHidMouse::DefaultPower(KIrp I)
{
    T << "Unhandled Power request, minor=" << ULONG(I.MinorFunction()) << "\n";

I.IndicatePowerIrpProcessed();
    I.CopyParametersDown();
    return m_Pdo.PnpPowerCall(this, I);
}

NTSTATUS VirtualHidMouse::OnQueryStopDevice(KIrp I)
{
    T << "Query Stop\n";
    return STATUS_SUCCESS;
}

NTSTATUS VirtualHidMouse::OnQueryRemoveDevice(KIrp I)
{
    T << "Query Remove\n";
    return STATUS_SUCCESS;
}

NTSTATUS VirtualHidMouse::OnCancelStopDevice(KIrp I)
{
    T << "Cancel Stop\n";
    return STATUS_SUCCESS;
}

NTSTATUS VirtualHidMouse::OnCancelRemoveDevice(KIrp I)
{
    T << "Cancel Remove\n";
    return STATUS_SUCCESS;
}

NTSTATUS VirtualHidMouse::OnStartDevice(KIrp I)
{
    T << "Start Device\n";

if (!m_State.m_Started)
    {

}

return STATUS_SUCCESS;
}

NTSTATUS VirtualHidMouse::OnStopDevice(KIrp I)
{
    T << "Stop Device\n";

if (m_State.m_Started)
    {

}

return STATUS_SUCCESS;
}

NTSTATUS VirtualHidMouse::OnRemoveDevice(KIrp I)
{
    return STATUS_SUCCESS;
}

ULONG __stdcall VxdControlMessageHandler(
    ULONG Edi,
    ULONG Esi,
    ULONG Ebp,
    ULONG Esp,
    ULONG Ebx,
    ULONG Edx,
    ULONG Ecx,
    ULONG ControlMessage,
    PVOID Context,
    ULONG* pCarryBitReturn
    )
{
    if (ControlMessage == W32_DEVICEIOCONTROL)
    {
        PIOCTLPARAMS p = PIOCTLPARAMS(Esi);
        MOUSE_MOVE_INFO* pMove = (MOUSE_MOVE_INFO*)p->dioc_InBuf;
        MOUSE_CLICK_INFO* pClick = (MOUSE_CLICK_INFO*)p->dioc_InBuf;

switch (p->dioc_IOCtlCode)
        {
        case IOCTL_VHIDMOU_MOVE:

T << "Move x=" << pMove->deltaX << " y=" << pMove->deltaY << "\n";

DeviceInstance->Move(UCHAR(pMove->deltaX), UCHAR(pMove->deltaY));
            return STATUS_SUCCESS;

case IOCTL_VHIDMOU_CLICK:

T << "Click U/D=" << pClick->UpOrDown << " L/R=" << pClick->LeftOrRight << "\n";

DeviceInstance->Click(pClick->LeftOrRight, pClick->UpOrDown);
            return STATUS_SUCCESS;

default:
            return STATUS_NOT_IMPLEMENTED;
        }
    }
    else
    {
        *pCarryBitReturn = 0;
        return 0;
    }
}

mouse_driver的更多相关文章

  1. 十六、USB驱动

    一.USB固件和USB传输方式 USB固件: USB固件一般不需要我们编写,在此不做程序分析. USB固件中包含USB设备的出厂信息,如厂商ID.产品ID.主版本号和次版本号等.这就是为什么当我们把U ...

随机推荐

  1. MongoDB - The mongo Shell, Configure the mongo Shell

    Customize the Prompt You may modify the content of the prompt by setting the variable prompt in the  ...

  2. 【转载】在 Visual Studio 2012 中创建 ASP.Net Web Service

    在 Visual Studio 2012 中创建 ASP.Net Web Service,步骤非常简单.如下: 第一步:创建一个“ASP.Net Empty Web Application”项目 创建 ...

  3. 一场ACM一场梦——我的一年

    听着裁判倒计时比赛结束,看着全场鲜艳的气球,今天的结果是the last result i can image. 过几天给校赛出题,去年此时的我,还从来没有过竞赛的经验,只因为在大学开学前看了一点点c ...

  4. Part 5 Select statement in sql server

    Select specific or all columns select * from 表名 select * from Student select 列名,列名... from 表名 select ...

  5. SQL中char、varchar、nvarchar

    char    char是定长的,也就是当你输入的字符小于你指定的数目时,char(8),你输入的字符小于8时,它会再后面补空值.当你输入的字符大于指定的数时,它会截取超出的字符.   nvarcha ...

  6. C#中的 具名参数 和 可选参数

    具名参数 和 可选参数 是 C# framework 4.0 出来的新特性. 一. 常规方法定义及调用 public void Demo1(string x, int y) { //do someth ...

  7. Swift中的单例的实现方式

    单例在iOS日常开发中是一个很常用的模式.对于希望在 app 的生命周期中只应该存在一个的对象,保证对象的唯一性的时候,一般都会使用单例来实现功能.在OC单例的写法如下: @implementatio ...

  8. [javascript|基本概念|Number]学习笔记

    Number类型的值:整数/浮点数值 整数 十进制  e.g.: var intNum = 50; 八进制  (严格模式下无效,解析错误)字面值首位必须是0,之后的数字序列为0-7  e.g.: va ...

  9. 7款震撼人心的HTML5文字特效

    1.CSS3五彩文字特效 文字带阴影效果 这是一款非常具有卡通形象的CSS3五彩文字特效,虽然没有迷人的动画效果,但是五彩缤纷的文字展现在屏幕上也是非常酷的,再加上每一个文字都有不同角度的阴影效果,加 ...

  10. jQuery 简单漂亮的 Nav 导航菜单

    自己写的一个简单的导航菜单,先看效果: 鼠标悬浮时菜单项向上移动成蓝底白字,点击之后底部会有蓝条表示当前选中项. 页面代码,菜单的每一项都是一个 div ,其中包括一个 ul 用来放置显示文字等,另一 ...