📄 複製 -ctrl2cap.c
字号:
//======================================================================
//
// 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"
#define WIN2K 1
HANDLE hVirtual_Mouse;
#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
HANDLE OpenKeyByName(PCWSTR pwcsKeyName)
{
NTSTATUS status;
UNICODE_STRING uKeyName;
OBJECT_ATTRIBUTES oa;
HANDLE hKey;
// long dwDisposition;
RtlInitUnicodeString(&uKeyName, pwcsKeyName);
InitializeObjectAttributes(&oa, &uKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwOpenKey(&hKey, KEY_READ, &oa);
if (!NT_SUCCESS(status))
{
// DbgPrint("ZwOpenKey Failed: %lx\n", status);
// status= ZwCreateKey(&hKey, KEY_WRITE, &oa, 0, NULL,REG_OPTION_VOLATILE, dwDisposition);
// return hKey;
return 0;
}
return hKey;
}
//----------------------------------------------------------------------
//
// 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[i] = 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;
//
// 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;
}
//status=IoCreateFile(&hVirtual_Mouse,DEVICE_NAME,GENERIC_WRITE|GENERIC_READ,0,0,OPEN_EXISTING,0,0);
//
// 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 );
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;
// Jason Yu IO_ERROR_LOG_PACKET errorLogEntry;
PDEVICE_OBJECT device;
NTSTATUS status = STATUS_SUCCESS;
//
// Create a filter device and attach it to the device stack.
//
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -