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;
    }
}

posted @ 2016-04-08 15:46  OracleLoyal  阅读(472)  评论(0编辑  收藏  举报