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 ...
随机推荐
- oracle lsnrctl
Oracle 11G在windows 7系统上不需要设置系统环境变量. 在命令行环境中运行命令: echo %ORACLE_SID% 可以看到此变量并不存在.也可以到注册表验证: HKEY_CURRE ...
- .NET中的Queue和Stack
1.ArrayList类 ArrayList类主要用于对一个数组中的元素进行各种处理.在ArrayList中主要使用Add.Remove.RemoveAt.Insert四个方法对栈进行操作.Add方法 ...
- javaweb学习总结二十五(response对象的用法一)
一:Reponse对象的概念 当客户端发送http请求时,服务器端会对每一次请求,创建request对象和response对象. response对象包括三个部分:响应头.响应状态码以及响应体 二:r ...
- 日历控件table布局
作为初学者,一开始就接触div+css ,所以说实话,我并不怎么喜欢table布局,一般逃避. 先上这次的效果图: 看到这个图,第一次用table布局没实现,原因是给tr加下边框失效.当时没找到原因, ...
- ServiceStack简介
原文:http://bbs.csdn.net/topics/390911450?page=1#post-398388262 在帖子中看到,大致了解了下,非常好的框架,留着学习 https://gith ...
- 浅谈sqlserver数据库优化(一)----开光篇
今天暂时无事,风和日丽,万里无云.游山的.玩水的.遛麻雀的都闲的不亦乐乎,也忙的不亦乐乎.在这美好的季节,依旧躲在被窝或是电脑旁绞尽脑汁敲键盘的人们,也别有一番滋味.废话少说,言归正传. 赶上了一个最 ...
- win8.1开启虚拟wifi
1. 使用管理员身份打开cmd 2. 然后输入netsh wlan set hostednetwork mode=allow 3. 接着输入netsh wlan start hostednetwork ...
- UI2_UINavigationBar
// // AppDelegate.m // UI2_UINavigationBar // // Created by zhangxueming on 15/7/6. // Copyright (c) ...
- (转)一网打尽当下NoSQL类型、适用场景及使用公司
摘要:对比传统关系型数据库,NoSQL有着更为复杂的分类——键值.面向文档.列存储以及图数据库.这里就带你一览NoSQL各种类型的适用场景及一些知名公司的方案选择. 在过去几年,关系型数据库一直是数据 ...
- tomcat中的get、post区别
最近做一个项目,前台传到后台的数据是乱码.看着代码应该是正确的,但是就是有问题,然后请教了旁边的老司机才找到问题是什么.话不多说,下面是模拟情景的代码,其实也很简单,前台一个form表单,post ...