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. oracle lsnrctl

    Oracle 11G在windows 7系统上不需要设置系统环境变量. 在命令行环境中运行命令: echo %ORACLE_SID% 可以看到此变量并不存在.也可以到注册表验证: HKEY_CURRE ...

  2. .NET中的Queue和Stack

    1.ArrayList类 ArrayList类主要用于对一个数组中的元素进行各种处理.在ArrayList中主要使用Add.Remove.RemoveAt.Insert四个方法对栈进行操作.Add方法 ...

  3. javaweb学习总结二十五(response对象的用法一)

    一:Reponse对象的概念 当客户端发送http请求时,服务器端会对每一次请求,创建request对象和response对象. response对象包括三个部分:响应头.响应状态码以及响应体 二:r ...

  4. 日历控件table布局

    作为初学者,一开始就接触div+css ,所以说实话,我并不怎么喜欢table布局,一般逃避. 先上这次的效果图: 看到这个图,第一次用table布局没实现,原因是给tr加下边框失效.当时没找到原因, ...

  5. ServiceStack简介

    原文:http://bbs.csdn.net/topics/390911450?page=1#post-398388262 在帖子中看到,大致了解了下,非常好的框架,留着学习 https://gith ...

  6. 浅谈sqlserver数据库优化(一)----开光篇

    今天暂时无事,风和日丽,万里无云.游山的.玩水的.遛麻雀的都闲的不亦乐乎,也忙的不亦乐乎.在这美好的季节,依旧躲在被窝或是电脑旁绞尽脑汁敲键盘的人们,也别有一番滋味.废话少说,言归正传. 赶上了一个最 ...

  7. win8.1开启虚拟wifi

    1. 使用管理员身份打开cmd 2. 然后输入netsh wlan set hostednetwork mode=allow 3. 接着输入netsh wlan start hostednetwork ...

  8. UI2_UINavigationBar

    // // AppDelegate.m // UI2_UINavigationBar // // Created by zhangxueming on 15/7/6. // Copyright (c) ...

  9. (转)一网打尽当下NoSQL类型、适用场景及使用公司

    摘要:对比传统关系型数据库,NoSQL有着更为复杂的分类——键值.面向文档.列存储以及图数据库.这里就带你一览NoSQL各种类型的适用场景及一些知名公司的方案选择. 在过去几年,关系型数据库一直是数据 ...

  10. tomcat中的get、post区别

    最近做一个项目,前台传到后台的数据是乱码.看着代码应该是正确的,但是就是有问题,然后请教了旁边的老司机才找到问题是什么.话不多说,下面是模拟情景的代码,其实也很简单,前台一个form表单,post   ...