阅读:1888回复:2
USB filter
小弟目前正在研究如何寫一個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); } |
|
沙发#
发布于:2010-07-30 14:55
自推一下
請各位高手幫忙解答 |
|
板凳#
发布于:2010-08-03 15:08
再頂一下
|
|