阅读:1554回复:0
请Chris<..\>看一下,谢谢
/*
用在某些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; } |
|