mouse_driver
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的更多相关文章
- 十六、USB驱动
一.USB固件和USB传输方式 USB固件: USB固件一般不需要我们编写,在此不做程序分析. USB固件中包含USB设备的出厂信息,如厂商ID.产品ID.主版本号和次版本号等.这就是为什么当我们把U ...
随机推荐
- python 基础——常用功能片段
1. 元素去重 data = [1,2,3,4,4,5,5,6] res = set(data) 2. 元素去重排序 res = sorted(set(data)) 2. 打印重复的元素 res = ...
- 如何优雅地制作精排 ePub —— 个人电子书制作规范及基本样式表
随着大数据时代的到来,多种移动阅读终端方兴未艾 —— Amazon Kindle不再小众.各互联网巨头纷纷推出旗下的电子书阅读软件.有了阅读的软件/硬件支持,必不可少的就是阅读什么的问题了.ePub格 ...
- SQL---------表的约束
表的约束 防止同一条数据完全重复:主键约束(primary key)唯一键约束(unique),自增长: 防止数据为空: 非空约束(not noll),默认值: 防止乱填数据: 外键, 定义数据类型, ...
- 【原则】常用windows开发 客户端工具 收集
1. Navicat Premium 推荐: mysql客户端, postgreSQL 客户端, Sqlite客户端 2. robomongo 推荐:mongoDB客户端
- 如何提高手机APP的用户体验?
详细内容请点击 随着移动互联网如日中天,如火如荼的时候,手机APP开发日益高涨了起来,关于手机APP的用户体验,也是一个老话长谈的话题.从事这行业也很久了,以下是我个人在工作中的一些关于APP的用户体 ...
- web.config里面使用configSource
在asp.net中如果修改了配置文件web.config以后,会导致应用程序重启,所有回话(session)丢失掉,在 .NET Framework 2.0 以后的版本中,可以在一个单独文件中包括所有 ...
- android自定义UI模板图文详解
不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一 ...
- Jquery AJax Post 返回值问题
var msg=0; Validater('abc'); function Validater(Name) { var itemId = 1; $.ajax({ url: 'adminmenu/Val ...
- 关于servlet是在什么时候初始化的个人总结
今天无意中看到一个博主的总结,总结的是servlet是在什么时候初始化的,并且附上了实例.但是由于那位博主的实例有问题,所以总结的也有误.这里我把我的体会写下来,分享给大家. java代码: @Ove ...
- Memcached解决单台服务器故障问题
<beitmemcached> <add key="name1" value="server1:port" /> <add key ...