guessle
驱动牛犊
驱动牛犊
  • 注册日期2010-02-05
  • 最后登录2011-11-15
  • 粉丝0
  • 关注0
  • 积分16分
  • 威望141点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1833回复:2

USB filter

楼主#
更多 发布于:2010-07-29 10:30
小弟目前正在研究如何寫一個USB Filter的一個小驅動
因為完全沒有基礎
所以只能自學並在網上東copy西copy的
並以Ctrl2cap這個範例改成了下列的code
安裝完成後
只要USB的Mass storage被拔除整個電腦就會出現藍屏
還請有經驗的各位幫忙看看那裡有錯

PS:因為是用Ctrl2cap改的 所以有點亂請見諒

//======================================================================
//
// Ctrl2cap
//
// Copyright (C) 1996-1999 Mark Russinovich
//
// Hook onto the keyboard I/O path and massage the input stream
// converting caps-locks into controls. This example works on
// NT 4 and Win2K and the Win2K version is very losely based on the
// i8042 port filter driver sample, kbfiltr, from the Win2K DDK.
//
// For every function I list whether the function gets called
// under NT 4, WIN2K, or both.
//
// File: ctrl2cap.c
//
//======================================================================
#include "ntddk.h"
#include <ntddkbd.h>
#include "stdarg.h"
#include "stdio.h"
#include "ctrl2cap.h"
#include "ntddkbd.h"
#undef WIN2K

#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, Ctrl2capDispatchGeneral)
#if WIN2K
#pragma alloc_text (PAGE, Ctrl2capAddDevice)
#pragma alloc_text (PAGE, Ctrl2capUnload)
#pragma alloc_text (PAGE, Ctrl2capPnP)
#pragma alloc_text (PAGE, Ctrl2capPower)
#endif // WIN2K
#endif // ALLOC_PRAGMA

extern POBJECT_TYPE IoDriverObjectType; 

extern 
NTKERNELAPI 
NTSTATUS 
ObReferenceObjectByName ( 
                         IN PUNICODE_STRING ObjectName, 
                         IN ULONG Attributes, 
                         IN PACCESS_STATE PassedAccessState OPTIONAL, 
                         IN ACCESS_MASK DesiredAccess OPTIONAL, 
                         IN POBJECT_TYPE ObjectType, 
                         IN KPROCESSOR_MODE AccessMode, 
                         IN OUT PVOID ParseContext OPTIONAL, 
                         OUT PVOID *Object 
);
//----------------------------------------------------------------------
//
// DriverEntry
//
// Installable driver initialization. Here we just set ourselves up.
// 
// Called: NT4, WIN2K
//
//----------------------------------------------------------------------
NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath 
    )
{
    ULONG                  i;

    DbgPrint (("Ctrl2cap.SYS: entering DriverEntry\n"));

    // 
    // Fill in all the dispatch entry points with the pass through function
    // and the explicitly fill in the functions we are going to intercept
    // 
    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {

        DriverObject->MajorFunction = Ctrl2capDispatchGeneral;
    }

    //
    // Our read function is where we do our real work.
    //
    //DriverObject->MajorFunction[IRP_MJ_READ] = Ctrl2capDispatchRead;

#if WIN2K
    //
    // Power IRPs are the only ones we have to handle specially under
    // Win2k since they require the special PoCallDriver and 
    // PoStartNextPowerIrp function calls.
    //
    DriverObject->MajorFunction [IRP_MJ_POWER]  = Ctrl2capPower;

    //
    // The only reason we need to handle PnP IRPs is to know when
    // a device we've attached to disappears (is removed).
    //
    DriverObject->MajorFunction [IRP_MJ_PNP]  = Ctrl2capPnP;

    //
    // Under Win2K we get told about the presence of keyboard 
    // devices through our AddDevice entry point.
    //
    DriverObject->DriverUnload = Ctrl2capUnload;
    DriverObject->DriverExtension->AddDevice = Ctrl2capAddDevice;

    return STATUS_SUCCESS;

#else  // WIN2K

    //
    // Under NT 4 we go out and hook the keyboard class device for 
    // keyboard 0.
    //
    return Ctrl2capInit( DriverObject );
#endif // WIN2K
}


//----------------------------------------------------------------------
//
// Ctrl2capInit
//
// Hook onto the keyboard's path. Why does this routine return
// status success even if there's a problem? I've found that if it 
// doesn't, the keyboard won't respond!
// 
// Called: NT4
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capInit( 
    IN PDRIVER_OBJECT DriverObject 
    )
{
    CCHAR              ntNameBuffer[64];
    STRING              ntNameString;
    UNICODE_STRING    ntUnicodeString;
    PDEVICE_OBJECT    device;
    NTSTATUS          status;
    PDEVICE_EXTENSION devExt;
    WCHAR             messageBuffer[]  = L"Ctrl2cap Initialized\n";
    UNICODE_STRING    messageUnicodeString;
    PDRIVER_OBJECT    usbDriver;
    PDEVICE_OBJECT    usbDevice;
    PDEVICE_OBJECT    pfltDevice;
    PDEVICE_OBJECT    pLowerDevice;

    //
    // Only hook onto the first keyboard's chain.
    //

#if DBG
    __debugbreak();
#endif

    sprintf( ntNameBuffer, "\\Driver\\USBSTOR" );
    RtlInitAnsiString( &ntNameString, ntNameBuffer );
    RtlAnsiStringToUnicodeString( &ntUnicodeString, &ntNameString, TRUE );
    
     status = ObReferenceObjectByName(&ntUnicodeString, OBJ_CASE_INSENSITIVE,
                                         NULL, GENERIC_READ | GENERIC_WRITE, IoDriverObjectType,
                                         KernelMode, NULL, (PVOID*)&usbDriver);

     if(!NT_SUCCESS(status))
     {
         
         DbgPrint(("Couldn't get usb driver\n"));
         return status;
     }

      usbDevice = usbDriver->DeviceObject;


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

       status = IoCreateDevice( DriverObject,
                                sizeof(DEVICE_EXTENSION),
                                NULL,
                                usbDevice->DeviceType,
                                usbDevice->Characteristics,
                                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 );
    pLowerDevice = IoAttachDeviceToDeviceStack(device, usbDevice);

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

    if(NULL == pLowerDevice)
    {
        ObDereferenceObject(usbDriver);
        DbgPrint(("attach usb device error!\n"));
        IoDeleteDevice(device);
        device = NULL;
        return STATUS_UNSUCCESSFUL;
    }

    //
    // Done! Just free our string and be on our way...
    //
    RtlFreeUnicodeString( &ntUnicodeString );
    DbgPrint(("Ctrl2cap: 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 );
    ObDereferenceObject(usbDriver);
    ZwDisplayString( &messageUnicodeString );
    return STATUS_SUCCESS;
}


#if WIN2K
//----------------------------------------------------------------------
//
// Ctrl2capAddDevice
//
// The PnP Manager calls us for each keyboard present on the system.
// We attach to each one so that we can flip caps lock to controls.
//
// Called: WIN2K
//
//----------------------------------------------------------------------
NTSTATUS
Ctrl2capAddDevice(
    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;
}


//----------------------------------------------------------------------
//
// Ctrl2capPnP
//
// We have to handle PnP IRPs so that we detach from target
// devices when appropriate.
//
// Called: WIN2K
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capPnP(
    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;
}


//----------------------------------------------------------------------
//
// Ctrl2capPower
//
// We have to handle Power IRPs specially.
//
// Called: WIN2K
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capPower(
    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 );
}


//----------------------------------------------------------------------
// 
// Ctrl2capUnload
//
// Our Win2K PnP unload function. We don't need to do anything.
//
// Called: WIN2K
//
//----------------------------------------------------------------------
VOID
Ctrl2capUnload(
   IN PDRIVER_OBJECT Driver
   )
{
#if DBG
    __debugbreak();
#endif
    UNREFERENCED_PARAMETER(Driver);
    IoDeleteDevice(device);

    ASSERT(NULL == Driver->DeviceObject);
}
#endif // WIN2K


//----------------------------------------------------------------------
// 
// Ctrl2capReadComplete
//
// Gets control after a read operation has completed.
//
// Called: WIN2K, NT4
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capReadComplete( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp,
    IN PVOID Context 
    )
{
    PIO_STACK_LOCATION        IrpSp;
    PKEYBOARD_INPUT_DATA      KeyData;
    int                       numKeys, i;

    //
    // 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++ ) {

            DbgPrint(("ScanCode: %x ", 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;
}


//----------------------------------------------------------------------
//
// Ctrl2capDispatchRead
//
// Sets up to look at the read request completion so that we can
// massage the input queue on IO completion.
//
// Called: WIN2K, NT4
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capDispatchRead( 
    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, Ctrl2capReadComplete, 
                            DeviceObject, TRUE, TRUE, TRUE );

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


//----------------------------------------------------------------------
//
// Ctrl2capDispatchGeneral
//
// This handles several functions we are not interested in 
// along to the keyboard class driver. 
//
// Called: WIN2K, NT4
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capDispatchGeneral(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp 
    )
{
    //
    // Pass the IRP to the target without touching the IRP
    //
#if WIN2K
    IoSkipCurrentIrpStackLocation(Irp);
#else // WIN2K
    //
    // This is the equivalent of the IoSkipCurrentIrpStackLocation macro,
    // which doesn't exist in the NT 4 DDK.
    //
    Irp->CurrentLocation++;
    Irp->Tail.Overlay.CurrentStackLocation++;
#endif // WIN2K
    return IoCallDriver(((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->TopOfStack, Irp);
}
guessle
驱动牛犊
驱动牛犊
  • 注册日期2010-02-05
  • 最后登录2011-11-15
  • 粉丝0
  • 关注0
  • 积分16分
  • 威望141点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2010-07-30 14:55
自推一下
請各位高手幫忙解答
guessle
驱动牛犊
驱动牛犊
  • 注册日期2010-02-05
  • 最后登录2011-11-15
  • 粉丝0
  • 关注0
  • 积分16分
  • 威望141点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2010-08-03 15:08
再頂一下
游客

返回顶部