huaguo
驱动牛犊
驱动牛犊
  • 注册日期2009-07-04
  • 最后登录2009-09-12
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望21点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1511回复:0

请Chris<..\>看一下,谢谢

楼主#
更多 发布于:2009-07-09 15:42
/*
用在某些xp上好用,但是某些xp上不好用。希望能有人帮忙指点一下,初学者,很菜,欢迎各种形式的批评
  KeyBoard1.C

  Author: <your name>
  Last Updated: 2006-03-23

  This framework is generated by EasySYS 0.3.0
  This template file is copying from QuickSYS 0.3.0 written by Chunhua Liu

*/
#include "ntddk.h"
#include "stdarg.h"
#include "stdio.h"
#include "ntddkbd.h"
#include "dbghelp.h"
#include "KeyBoard1.h"
#include "Ioctlcmd.h"

//
// A structure representing the instance information associated with
// a particular device
//

typedef struct _DEVICE_EXTENSION
{
    //ULONG  StateVariable;
    PDEVICE_OBJECT Device;
    UNICODE_STRING ustrDeviceName;
    UNICODE_STRING ustrSymLinkName;
    PDEVICE_OBJECT TopOfStack;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

//
// Device driver routine declarations.
//
NTSTATUS KeyBoradReadComplete(
                              IN PDEVICE_OBJECT DeviceObject,
                              IN PIRP Irp,
                              IN PVOID Context
                              )
{
    PIO_STACK_LOCATION        IrpSp;
    PKEYBOARD_INPUT_DATA      KeyData;
    int                       numKeys, i;
    WCHAR KeyPressed;

    //
    // Request completed - look at the result.
    //
    IrpSp = IoGetCurrentIrpStackLocation( Irp );
    if( NT_SUCCESS( Irp->IoStatus.Status ) ) {

        //
        // Do caps-lock down and caps-lock up. Note that
        // just frobbing the MakeCode handles both the up-key
        // and down-key cases since the up/down information is specified
        // seperately in the Flags field of the keyboard input data
        // (0 means key-down, 1 means key-up).
        //
        KeyData = Irp->AssociatedIrp.SystemBuffer;
        numKeys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);

        for( i = 0; i < numKeys; i++ ) {

            //KeyP=KeyMap[KeyData.MakeCode];
            //DbgPrint(("ScanCode: %0x ", KeyData.MakeCode ));
            KeyPressed=KeyMap[KeyData.MakeCode];
            KdPrint(("%C",KeyPressed));
            //KdPrint(("ScanCode: %0x ", KeyData.MakeCode ));
            DbgPrint(("%S\n", KeyData.Flags ? "Up" : "Down" ));

            //if( KeyData.MakeCode == CAPS_LOCK) {

                //KeyData.MakeCode = LCONTROL;
            //}
        }
    }

    //
    // Mark the Irp pending if required
    //
    if( Irp->PendingReturned ) {

        IoMarkIrpPending( Irp );
    }
    return Irp->IoStatus.Status;
}
NTSTATUS KeyBoardDispatchRead(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
    PDEVICE_EXTENSION   devExt;
    PIO_STACK_LOCATION  currentIrpStack;
    PIO_STACK_LOCATION  nextIrpStack;

    //
    // Gather our variables.
    //
    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
    nextIrpStack = IoGetNextIrpStackLocation(Irp);    

    //
    // Push params down for keyboard class driver.
    //
    *nextIrpStack = *currentIrpStack;

    //  
    // Set the completion callback, so we can "frob" the keyboard data.
    //        
    IoSetCompletionRoutine( Irp, KeyBoradReadComplete,
        DeviceObject, TRUE, TRUE, TRUE );

    //
    // Return the results of the call to the keyboard class driver.
    //
    return IoCallDriver( devExt->TopOfStack, Irp );

}

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT        DriverObject,
    IN PUNICODE_STRING        RegistryPath
    );

BOOLEAN  
Keyboard1DeviceControl(    
    IN PFILE_OBJECT FileObject,
    IN BOOLEAN Wait,
    IN PVOID InputBuffer,
    IN ULONG InputBufferLength,
    OUT PVOID OutputBuffer,
    IN ULONG OutputBufferLength,
    IN ULONG IoControlCode,
    OUT PIO_STATUS_BLOCK IoStatus,
    IN PDEVICE_OBJECT DeviceObject
    );

VOID
Keyboard1Unload(
    IN PDRIVER_OBJECT        DriverObject
    );

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, Keyboard1DeviceControl)
#pragma alloc_text(PAGE, Keyboard1Unload)
#endif // ALLOC_PRAGMA


VOID
Keyboard1Unload(
    IN PDRIVER_OBJECT        DriverObject
    )
{
   // UNICODE_STRING dosDeviceName;
    UNREFERENCED_PARAMETER(DriverObject);

    ASSERT(NULL == DriverObject->DeviceObject);
    


    DbgPrint(("[KeyBoard1] unloaded\n"));
}


BOOLEAN  
Keyboard1DeviceControl(
    IN PFILE_OBJECT FileObject,
    IN BOOLEAN Wait,
    IN PVOID InputBuffer,
    IN ULONG InputBufferLength,
    OUT PVOID OutputBuffer,
    IN ULONG OutputBufferLength,
    IN ULONG IoControlCode,
    OUT PIO_STATUS_BLOCK IoStatus,
    IN PDEVICE_OBJECT DeviceObject
    )
{
    IoStatus->Status      = STATUS_SUCCESS; // Assume success
    IoStatus->Information = 0;              // Assume nothing returned
    switch ( IoControlCode )
    {
    case IOCTL_KEYBOARD1_VERSION:
        {
            //
            // Some app is saying hello
            //

            break;
        }
    default:
        KdPrint (("[KeyBoard1] unknown IRP_MJ_DEVICE_CONTROL\n"));
        IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    return TRUE;
}

NTSTATUS
Keyboard1Dispatch(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
  
    IoSkipCurrentIrpStackLocation(Irp);
    return IoCallDriver(((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->TopOfStack, Irp);
    //IoCompleteRequest( Irp, IO_NO_INCREMENT );
   // return STATUS_SUCCESS;  
}
NTSTATUS AttachInit(IN PDRIVER_OBJECT DriverObject);
NTSTATUS KeyBoardPower(
                       IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP           Irp
                       );
NTSTATUS KeyBoardPnP(
                     IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP           Irp
                     );
NTSTATUS
KeyBoardAddDevice(
                  IN PDRIVER_OBJECT   Driver,
                  IN PDEVICE_OBJECT   PDO
                  );


NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT        DriverObject,
    IN PUNICODE_STRING        RegistryPath
    )
{
    NTSTATUS            status = STATUS_SUCCESS;    
    UNICODE_STRING        ntDeviceName;
    UNICODE_STRING        dosDeviceName;
    PDEVICE_EXTENSION    deviceExtension;
    PDEVICE_OBJECT        deviceObject = NULL;
    BOOLEAN                fSymbolicLink = FALSE;

    UNICODE_STRING          deviceLinkUnicodeString;
    ULONG i;

    KdPrint(("[KeyBoard1] DriverEntry: %wZ\n", RegistryPath));

    //
    // A real driver would:
    //
    //     1. Report it's resources (IoReportResourceUsage)
    //
    //     2. Attempt to locate the device(s) it supports

    //
    // OK, we've claimed our resources & found our h/w, so create
    // a device and initialize stuff...
    //

    //
    // Setup our name and symbolic link.
    //
    RtlInitUnicodeString(&ntDeviceName, KEYBOARD1_DEVICE_NAME_W);
    RtlInitUnicodeString (&deviceLinkUnicodeString, KEYBOARD1_DOS_DEVICE_NAME_W );

  

  
    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {

        DriverObject->MajorFunction=Keyboard1Dispatch;
    }
    
    
    
    DriverObject->MajorFunction[IRP_MJ_READ]            =KeyBoardDispatchRead;
    
    
    DriverObject->MajorFunction [IRP_MJ_POWER]=KeyBoardPower;

    
    DriverObject->MajorFunction [IRP_MJ_PNP]=KeyBoardPnP;


    
    DriverObject->DriverExtension->AddDevice = KeyBoardAddDevice;//<=============================还有玄机


    
    DriverObject->DriverUnload                          = Keyboard1Unload;
    return AttachInit(DriverObject);
}
NTSTATUS
KeyBoardAddDevice(
                  IN PDRIVER_OBJECT   Driver,
                  IN PDEVICE_OBJECT   PDO
                  )
{
    PDEVICE_EXTENSION        devExt;
    IO_ERROR_LOG_PACKET      errorLogEntry;
    PDEVICE_OBJECT           device;
    NTSTATUS                 status = STATUS_SUCCESS;

    //
    // Create a filter device and attach it to the device stack.

    //

    DbgPrint(("Ctrl2capAddDevice\n"));
    status = IoCreateDevice(Driver,                  
        sizeof(DEVICE_EXTENSION),
        NULL,                    
        FILE_DEVICE_KEYBOARD,  
        0,                    
        FALSE,                
        &device              
        );

    if (!NT_SUCCESS(status)) {

        return (status);
    }

    RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));

    devExt = (PDEVICE_EXTENSION) device->DeviceExtension;
    devExt->TopOfStack = IoAttachDeviceToDeviceStack(device, PDO);

    ASSERT(devExt->TopOfStack);

    device->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    device->Flags &= ~DO_DEVICE_INITIALIZING;
    return status;
}
NTSTATUS KeyBoardPnP(
                     IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP           Irp
                     )
{
    PDEVICE_EXTENSION           devExt;
    PIO_STACK_LOCATION          irpStack;
    NTSTATUS                    status = STATUS_SUCCESS;
    KIRQL                       oldIrql;
    KEVENT                      event;        

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->MinorFunction) {
    case IRP_MN_REMOVE_DEVICE:

        //
        // Detach from the target device after passing the IRP
        // down the devnode stack.
        //
        IoSkipCurrentIrpStackLocation(Irp);
        IoCallDriver(devExt->TopOfStack, Irp);

        IoDetachDevice(devExt->TopOfStack);
        IoDeleteDevice(DeviceObject);

        status = STATUS_SUCCESS;
        break;

    case IRP_MN_SURPRISE_REMOVAL:

        //
        // Same as a remove device, but don't call IoDetach or IoDeleteDevice.
        //
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->TopOfStack, Irp);
        break;

    case IRP_MN_START_DEVICE:
    case IRP_MN_QUERY_REMOVE_DEVICE:
    case IRP_MN_QUERY_STOP_DEVICE:
    case IRP_MN_CANCEL_REMOVE_DEVICE:
    case IRP_MN_CANCEL_STOP_DEVICE:
    case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
    case IRP_MN_STOP_DEVICE:
    case IRP_MN_QUERY_DEVICE_RELATIONS:
    case IRP_MN_QUERY_INTERFACE:
    case IRP_MN_QUERY_CAPABILITIES:
    case IRP_MN_QUERY_DEVICE_TEXT:
    case IRP_MN_QUERY_RESOURCES:
    case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    case IRP_MN_READ_CONFIG:
    case IRP_MN_WRITE_CONFIG:
    case IRP_MN_EJECT:
    case IRP_MN_SET_LOCK:
    case IRP_MN_QUERY_ID:
    case IRP_MN_QUERY_PNP_DEVICE_STATE:
    default:
        //
        // Pass these through untouched
        //
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->TopOfStack, Irp);
        break;
    }

    return status;
}

NTSTATUS KeyBoardPower(
                       IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP           Irp
                       )
{
    PDEVICE_EXTENSION   devExt;

    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    //
    // Let the next power IRP out of the gate
    //
    PoStartNextPowerIrp( Irp );

    //
    // Pass this power IRP to the keyboard class driver
    //
    IoSkipCurrentIrpStackLocation( Irp );

    return PoCallDriver( devExt->TopOfStack, Irp );
}
NTSTATUS AttachInit(IN PDRIVER_OBJECT DriverObject)
{
    CCHAR              ntNameBuffer[64];
    STRING              ntNameString;
    UNICODE_STRING    ntUnicodeString;
    PDEVICE_OBJECT    device;
    NTSTATUS          status;
    PDEVICE_EXTENSION devExt;
    WCHAR             messageBuffer[]  = L"KeyBoradFilter Initialized\n";
    UNICODE_STRING    messageUnicodeString;

    //
    // Only hook onto the first keyboard's chain.
    //
    sprintf( ntNameBuffer, "\\Device\\KeyboardClass0" );
    RtlInitAnsiString( &ntNameString, ntNameBuffer );
    RtlAnsiStringToUnicodeString( &ntUnicodeString, &ntNameString, TRUE );

    //
    // Create device object for the keyboard.
    //
    status = IoCreateDevice( DriverObject,
        sizeof(DEVICE_EXTENSION),
        NULL,
        FILE_DEVICE_KEYBOARD,
        0,
        FALSE,
        &device );

    if( !NT_SUCCESS(status) ) {

        DbgPrint(("Ctrl2cap: Keyboard hook failed to create device!\n"));

        RtlFreeUnicodeString( &ntUnicodeString );
        return STATUS_SUCCESS;
    }

    RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));

    devExt = (PDEVICE_EXTENSION) device->DeviceExtension;

    //
    // Keyboard uses buffered I/O so we must as well.
    //
    device->Flags |= DO_BUFFERED_IO;
    device->Flags &= ~DO_DEVICE_INITIALIZING;

    //
    // Attach to the keyboard chain.
    //
    status = IoAttachDevice( device, &ntUnicodeString, &(devExt->TopOfStack) );

    if( !NT_SUCCESS(status) ) {

        DbgPrint(("Ctrl2cap: Connect with keyboard failed!\n"));
        IoDeleteDevice( device );
        RtlFreeUnicodeString( &ntUnicodeString );
        return STATUS_SUCCESS;
    }

    //
    // Done! Just free our string and be on our way...
    //
    RtlFreeUnicodeString( &ntUnicodeString );
    KdPrint((": Successfully connected to keyboard device\n"));

    //
    // This line simply demonstrates how a driver can print
    // stuff to the bluescreen during system initialization.
    //
    RtlInitUnicodeString (&messageUnicodeString,
        messageBuffer );
    //ZwDisplayString( &messageUnicodeString );
    return STATUS_SUCCESS;
}
游客

返回顶部