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. 转: app端数据库(性能高) realm (ios, android 均支持)

    转:  http://ios.jobbole.com/85041/ 移动端数据库新王者:realm 2016/05/14 · iOS开发 · 数据库 分享到:0 原文出处: 没故事的卓同学(@没故事的 ...

  2. Eclipse+ADT+Android SDK 搭建安卓开发环境

    Eclipse+ADT+Android SDK 搭建安卓开发环境   要求 必备知识 windows 7 基本操作. 运行环境 windows 7(64位); eclipse-jee-luna-SR2 ...

  3. JavaScript库开发者们的规则

    详细内容请点击 1. 保持无侵入性 我的HTML标记不想知道你的JavaScript代码. 2. 严禁修改和扩展Object.prototype! 这条很重要,因此需要一条完全针对它的规则.对象是Ja ...

  4. 基于AE连通性分析

    曾经做管线连通性分析,总觉得ARCGIS应该有现成的方案可以实现,但最终没有找到,后来只好自己写了套代码,但在搜索过程中找到了这样一估代码,当时留了下来,那我现在也把它留下来. Dim pLayer ...

  5. 简直喝血!H.265要被专利费活活玩死

    转自 http://news.mydrivers.com/1/440/440145.htm H.264是如今最流行的视频编码格式之一,不但技术先进,而且专利费很低,企业每年只需支付650万美元,而个人 ...

  6. NSMutableArray 根据key排序

    /** * NSMutableArray 排序 * * @param dicArray 数据 * @param key 关键字排序 * @param yesOrNo 升序或降序排列,yes为升序,no ...

  7. Part 3 ViewData and ViewBag in mvc

    ViewBag and ViewData is a mechanism(机制) to pass data from controller to view. We use '@' symbol(符号) ...

  8. opensuse pptp拨号设置注意事项

    防火墙一定要关闭 路由器要映射本地1723和1701端口 tcp协议(个别路由器和网络环境,可以先不设置) pptp配置注意协议的选择:

  9. Apache2.4 与 PHP 5.5 64位版的安装配置

    我的环境:windows7 旗舰版 64位 首先下载相关文件: php 5.5.0 windows 64版 http://windows.php.net/download/#php-5.5 (选择 6 ...

  10. Hadoop集群错误

    1.Hadoop集群所有的DataNode都启动不了解决办法 删除从节点.../usr/hadoop/tmp/dfs/ 下内容,再重新格式化namenode