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 ...
随机推荐
- 利用css使文本在限制几行之后隐藏
想要在布局中显示一段新闻的标题或是内容,特别是内容,东西超多...下面的方法就是通过css来控制文本显示多少的: 首先在html中写上: <p class="ellipsis" ...
- Kinect For Windows V2开发日志一:开发环境的配置
算是正式进军Kinect了,前段时间学的东西现在就忘了,于是从此开始记录一下. 目前为止大部分的学习资料来自于Heresy的博客,写的非常优秀,清晰明了,十分感谢.开发语言为C++,应该会一直使用,但 ...
- 洛谷P1251 餐巾(网络流)
P1251 餐巾 15通过 95提交 题目提供者该用户不存在 标签网络流贪心 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 为什么我全部10个测试点都对… 题目描述 一个餐厅在相继的N天里 ...
- oracle 数据导入导出命令
1.数据导出: 1 将数据库TEST完全导出,用户名system 密码manager 导出到D:\daochu.dmp中 exp system/manager@TEST file=d:\daoc ...
- Ionic Android开发环境搭建 下
上篇 Ionic 安装完成了,由于要开发Android,所以必不可少需要继续搭建Android开发环境. 首先,下载并安装JDK.然后配置一下环境变量. 接着,下载并安装Android SDK.下载过 ...
- CSS之简单树形菜单
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 删除HT和CAS角色与扩展在另一台服务器
背景:原先使用三合一方式部署的架构,如今不再满足企业需求,因此需要将原来的一台服务器多角色的拆分开,即由原来CAS.HT.MBX角色集一台服务器的分成两台服务器来部署,此架构为MBX角色单独部署在 ...
- 前台JS(Jquery)调用后台方法 无刷新级联菜单示例
前台用AJAX直接调用后台方法,老有人发帖提问,没事做个示例 下面是做的一个前台用JQUERY,AJAX调用后台方法做的无刷新级联菜单 http://www.dtan.so CasMenu.aspx页 ...
- JS学习第二课
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 7款个性化jQuery/HTML5地图插件
现在我们经常会用到一些地图应用,无论是在网页上还是手机App中,地图貌似是一个不可或缺的应用.本文将带领大家一起来看看一些基于jQuery和HTML5的个性化地图插件,有几款地图比较实用,有些则是具有 ...