阅读:2316回复:2
驱动级模拟鼠标 代码分析
小弟不才最近得到一份关于驱动级虚拟鼠标的代码,本想轻松改成自己的作品,
可是真正入手的时候才发现我自己之菜, 代码是C++的源代码,简单分析下他的意思 ,他好像是生成SYS文件,源代码结构如下: function.h, 定义设备名称: hidmouse.h ,定义鼠标动作, vhidmou.h,定义一个类, vmoudev.h vhidev.cpp vhidmou.cpp: 为了方便看我都文件名列这里了,代码在后面去,) 我现在的问题是,这个sys如何用DELPHI或者VB调用,或者是c也行,请DRIVERDEVELOP各位牛人帮我看看,小弟感激不尽,祝DRIVERDEVELOP越办越好! 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_SYSTEM_CONTROL #define DRIVER_FUNCTION_STARTIO 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; }; vhidmou.h, class VirtualHidMouseDriver : public KHidMiniDriver { SAFE_DESTRUCTORS virtual NTSTATUS AddDevice(PDEVICE_OBJECT PnpDeviceObject); }; vmoudev.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 SystemControl(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); // KHidDevice Overrides 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 // The following member functions are actually defined by the // a DEVMEMBER_XXX macro (such as DEVMEMBER_DISPATCHERS). // The macro __COMMENT_ONLY never gets defined. These comment-only // definitions simply allow easy navigation to the functions within // the Developer Studio using the class browser. VOID CancelQueuedIrp(KIrp I); // COMMENT_ONLY #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 VHIDMOU.CPP #define VDW_MAIN #include <khid.h> // Note: HID minidrivers include this rather than vdw.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; } 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 }; // HardwareID for the virtual mouse. 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'} }; // We keep a pointer to an instance of the device class for use // by the exported functions which are called from other drivers VirtualHidMouse* g_DeviceInstance=NULL; // Constructor for the virtual mouse device. It is derived from // KHidDevice. VirtualHidMouse::VirtualHidMouse(PDEVICE_OBJECT Fdo) : KHidDevice( Fdo, MouseHidReportDesc, sizeof MouseHidReportDesc, DeviceID, HardwareID, NULL, NULL, &DeviceAttributes, &TheDeviceString.Sd1, sizeof TheDeviceString, 0 ) { T << "VirtualHidMouse()\n"; g_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); } // HIDCLASS calls this routine when it wants a report. We // serialize this IRP so that when we get input, we know // which IRP it is intended for. Note that HIDCLASS actually // created the device object, so we're assuming that HIDCLASS // is not using the device queue. NTSTATUS VirtualHidMouse::ReadReport(KIrp I) { return QueueIrp(I, LinkTo(CancelQueuedIrp)); // queue to device queue. // Note: A driver that relies on a bus driver or some other // lower level device to process the IRP should generally not queue // the IRP. Queueing is primarily used by lowest level drivers. // If this rule is not followed, then the lower device's dispatch // routines will be called at raised IRQL, and this is generally // not good. } 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); // See if there is any input to report UpdateState(); } // UpdateState // // Completes the current IRP if there is anything to report // VOID VirtualHidMouse::UpdateState(void) { KIrp I=CurrentIrp(); if ( !I.IsNull() ) { m_Lock.Lock(); if ( (m_DeltaX != 0) || (m_DeltaY != 0) || (m_NewButtonState != m_OldButtonState) ) { // Before processing the Irp, we need to check to see if it has been // canceled. We also want to set the Irp into an non-cancelable // state (cancel routine set to NULL) so we can process it. When // performing these operations, it is necessary to hold the global // cancel spin lock and take special precautions to ensure the Irp // is still valid. This is accomplished using the routine // KIrp::TestAndSetCancelRoutine(). if ( !I.TestAndSetCancelRoutine( LinkTo(CancelQueuedIrp), NULL, CurrentIrp()) ) { // The Irp has been canceled we stop processing and exit. Since // it was in a cancelable state previously, it will be completed by // the cancel routine that had been set on it. 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(); } } // Called indirectly by other drivers when the virtual mouse // moves. VOID VirtualHidMouse::Move(CHAR DeltaX, CHAR DeltaY) { m_Lock.Lock(); m_DeltaX += DeltaX*SCALEX; m_DeltaY += DeltaY*SCALEY; m_Lock.Unlock(); UpdateState(); } // Called indirectly by other drivers when a virtual mouse // button is clicked. // // Input: // LeftOrRight: 1=Left, 0=Right // DownOrUp: 1=Down, 0=Up // 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 << "DefaultHidRequestHandler()\n"; I.ForceReuseOfCurrentStackLocationInCalldown(); return m_Pdo.PnpCall(this, I); } ////////////////////////////////////////////////////////////////// // VirtualHidMouse::DefaultPnp // // This handler is the override of KPnpDdevice::Default. It provides // default functionality for IRP_MJ_PNP. The // system invokes this function whenever the device receives a // Pnp IRP having a minor function for which the corresponding // member function of KPnpDevice is not overridden. Note that // KHidDevice provides overrides for some of the KPnpDevice members // (e.g. OnRemoveDevice). // // Subclasses should consider if this is the appropriate default // functionality. If not, override the function. // NTSTATUS VirtualHidMouse::DefaultPnp(KIrp I) { T << "DefaultPnp Pnp request, minor=" << ULONG(I.MinorFunction()) << "\n"; I.ForceReuseOfCurrentStackLocationInCalldown(); return m_Pdo.PnpCall(this, I); } ////////////////////////////////////////////////////////////////// // VirtualHidMouse::DefaultPower // // This handler is the override of KPnpDdevice::Default. It provides // default functionality for IRP_MJ_POWER. The // system invokes this function whenever the device receives a // Power IRP having a minor function for which the corresponding // member function of KPnpDevice is not overridden. // // Subclasses should consider if this is the appropriate default // functionality. If not, override the function. // NTSTATUS VirtualHidMouse::DefaultPower(KIrp I) { T << "DefaultPower Power request, minor=" << ULONG(I.MinorFunction()) << "\n"; I.IndicatePowerIrpProcessed(); I.CopyParametersDown(); return m_Pdo.PnpPowerCall(this, I); } //////////////////////////////////////////////////////////////////////////////// // SystemControl // // This routine just passes the IRP through to the next device since this driver // is not a WMI provider. // NTSTATUS VirtualHidMouse::SystemControl(KIrp I) { I.ForceReuseOfCurrentStackLocationInCalldown(); return m_Pdo.PnpCall(this, I); } /////////////////////////////////////////////////////////////////// // OnQueryStopDevice // // This call queries the device to determine if a STOP can be done // NTSTATUS VirtualHidMouse::OnQueryStopDevice(KIrp I) { T << "OnQueryStopDevice()\n"; return STATUS_SUCCESS; } /////////////////////////////////////////////////////////////////// // OnQueryRemoveDevice // // The system is querying the device to determine if a REMOVE can be done // NTSTATUS VirtualHidMouse::OnQueryRemoveDevice(KIrp I) { T << "OnQueryRemoveDevice()\n"; return STATUS_SUCCESS; } /////////////////////////////////////////////////////////////////// // OnCancelStopDevice // // This call instructs the device to cancel a pending stop operation // NTSTATUS VirtualHidMouse::OnCancelStopDevice(KIrp I) { T << "OnCancelStopDevice()\n"; return STATUS_SUCCESS; } /////////////////////////////////////////////////////////////////// // OnCancelRemoveDevice // // This call instructs the device to cancel a pending stop operation // NTSTATUS VirtualHidMouse::OnCancelRemoveDevice(KIrp I) { T << "OnCancelRemoveDevice()\n"; return STATUS_SUCCESS; } /////////////////////////////////////////////////////////////////// // OnStartDevice // // This call instructs the device to start operation. Relevant // policies: // // m_Policies.m_CompletedByDriverWorks.m_StartDevice = TRUE // m_Policies.m_ForwardToPdoPolicy.m_CallBeforeStart = TRUE // NTSTATUS VirtualHidMouse::OnStartDevice(KIrp I) { T << "OnStartDevice()\n"; if (!m_State.m_Started) { // initialize the device } return STATUS_SUCCESS; } /////////////////////////////////////////////////////////////////// // OnStopDevice // // This call instructs the device to uninitialize itself. Relevant // policies: // // m_Policies.m_CompletedByDriverWorks.m_StopDevice = TRUE // m_Policies.m_ForwardToPdoPolicy.m_CallAfterStop = TRUE // m_Policies.m_HoldPolicy.m_CancelAllOnStop = TRUE // NTSTATUS VirtualHidMouse::OnStopDevice(KIrp I) { T << "OnStopDevice()\n"; if (m_State.m_Started) { // undo OnStartDevice here } return STATUS_SUCCESS; // IRP completed by D::W } ////////////////////////////////////////////////////////////////// // VirtualHidMouse::OnRemoveDevice // // Override of KPnpDevice member. The system calls when the device // is removed. If a device has outstanding IRPs, it should make // sure they are all complete before deleting itself. NTSTATUS VirtualHidMouse::OnRemoveDevice(KIrp I) { T << "OnRemoveDevice()\n"; 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"; g_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"; g_DeviceInstance->Click(pClick->LeftOrRight, pClick->UpOrDown); return STATUS_SUCCESS; default: return STATUS_NOT_IMPLEMENTED; } } else { *pCarryBitReturn = 0; return 0; } } |
|
|
沙发#
发布于:2009-03-25 17:26
如果没有记错这个是DriverStudio中的代码,我记的只支持9x,如果你要做2K/XP的可能要做修改
个人建议用DDK去做 |
|
|
板凳#
发布于:2009-03-26 00:48
哦~,谢谢楼上的意见,不过我还有好多原理都不太明白,总之感觉是不知道该如何出手啦,我只要一个模拟鼠标的功能,我不想去学习一门新的语言,我没有那么多时间,,,,
唉,,期待有高人能直接贴出源代码 |
|
|