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 ...
随机推荐
- 把Flume的Source设置为 Spooling directory source
把Flume的Source设置为 Spooling directory source,在设定的目录下放置需要读取的文件,一些文件在读取过程中会报错. 文件格式和报错如下: 实验一 读取汉子和“:&qu ...
- Delphi数组复制
const AA : arrary[0..4] of byte =(0,1,2,3,4) var BB : arrary[0..4] of byte; begin BB := AA ; {这样是错 ...
- POJ 2253 Frogger (最短路)
Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 28333 Accepted: 9208 Descript ...
- OpenShare常见问题及解答
OpenShare常见问题及回答: Q:OpenShare可以整合SAP么? A:当然可以,OpenShare是真正完全开放的产品,但要进行二次开发,事实上我们帮我们大部分的客户都整合了SAP,包括数 ...
- GDAL Configure in Visual Studio 2010 for Win7/ GDAL+VisualStudio2010 Win7 配置
配置环境: OS:Win& *86 Ultimate Edition(EN) VS:Visual Studio 2010(EN) Step1: GDAL源码下载:http://www.gisi ...
- Codevs 1009 产生数
题目描述 Description 给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15). 规则: 一位数可变换成另一个一位数: 规则的右部不能为零. 例如:n=234.有规 ...
- POD数据了解
Plain old data (普通旧的数据); POD 是Plain Old Data的簡寫,是指一些系統的int, char, float.指標.array之類的資料型別,這應該蠻好想像的,就是C ...
- GridView、DataGrid、DataList、Repeater、ListView、DetailsView、FormView
列表类 GridView 控件 GridView 控件以表的形式显示数据,并提供对列进行排序.分页.翻阅数据以及编辑或删除单个记录的功能. 特征:一行一条记录,就像新闻列表一样:带分页功能 ...
- 卡通投掷游戏ios源码
卡通投掷游戏源码,一款基于cocos2d很有意思的卡通投掷游戏源码,使用重力感应摇动手机让猴子打转,然后点击屏幕任何地方将猴子抛出去,抛出去的过程中会收集星星,游戏的规则就是抛得越远越好,收集的星星最 ...
- Linux C 程序 GTK+图形界面编程(22)
GTK+图形界面编程 Linux大多是在字符界面,但也可以开发图形界面 目前已经存在多种Linux下开发图形界面的程序开发包:最常用的是Qt和GTK+ Qt是一个跨平台的图形界面开发库,不仅仅支持Li ...