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. python 基础——常用功能片段

    1. 元素去重 data = [1,2,3,4,4,5,5,6] res = set(data) 2. 元素去重排序 res = sorted(set(data)) 2. 打印重复的元素 res = ...

  2. 如何优雅地制作精排 ePub —— 个人电子书制作规范及基本样式表

    随着大数据时代的到来,多种移动阅读终端方兴未艾 —— Amazon Kindle不再小众.各互联网巨头纷纷推出旗下的电子书阅读软件.有了阅读的软件/硬件支持,必不可少的就是阅读什么的问题了.ePub格 ...

  3. SQL---------表的约束

    表的约束 防止同一条数据完全重复:主键约束(primary key)唯一键约束(unique),自增长: 防止数据为空: 非空约束(not noll),默认值: 防止乱填数据: 外键, 定义数据类型, ...

  4. 【原则】常用windows开发 客户端工具 收集

    1.  Navicat Premium 推荐: mysql客户端, postgreSQL 客户端, Sqlite客户端 2.  robomongo 推荐:mongoDB客户端

  5. 如何提高手机APP的用户体验?

    详细内容请点击 随着移动互联网如日中天,如火如荼的时候,手机APP开发日益高涨了起来,关于手机APP的用户体验,也是一个老话长谈的话题.从事这行业也很久了,以下是我个人在工作中的一些关于APP的用户体 ...

  6. web.config里面使用configSource

    在asp.net中如果修改了配置文件web.config以后,会导致应用程序重启,所有回话(session)丢失掉,在 .NET Framework 2.0 以后的版本中,可以在一个单独文件中包括所有 ...

  7. android自定义UI模板图文详解

    不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一 ...

  8. Jquery AJax Post 返回值问题

    var msg=0; Validater('abc'); function Validater(Name) { var itemId = 1; $.ajax({ url: 'adminmenu/Val ...

  9. 关于servlet是在什么时候初始化的个人总结

    今天无意中看到一个博主的总结,总结的是servlet是在什么时候初始化的,并且附上了实例.但是由于那位博主的实例有问题,所以总结的也有误.这里我把我的体会写下来,分享给大家. java代码: @Ove ...

  10. Memcached解决单台服务器故障问题

    <beitmemcached> <add key="name1" value="server1:port" /> <add key ...