📄 kbfiltr.c
字号:
if (!NT_SUCCESS(status)) {
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
return KbFilter_DispatchPassThrough(DeviceObject, Irp);
}
NTSTATUS
KbFilter_PnP(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is the dispatch routine for plug and play irps
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
Status is returned.
--*/
{
PDEVICE_EXTENSION devExt;
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
KIRQL oldIrql;
KEVENT event;
PAGED_CODE();
devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation(Irp);
switch (irpStack->MinorFunction) {
case IRP_MN_START_DEVICE: {
//
// The device is starting.
//
// We cannot touch the device (send it any non pnp irps) until a
// start device has been passed down to the lower drivers.
//
IoCopyCurrentIrpStackLocationToNext(Irp);
KeInitializeEvent(&event,
NotificationEvent,
FALSE
);
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE) KbFilter_Complete,
&event,
TRUE,
TRUE,
TRUE); // No need for Cancel
status = IoCallDriver(devExt->TopOfStack, Irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(
&event,
Executive, // Waiting for reason of a driver
KernelMode, // Waiting in kernel mode
FALSE, // No allert
NULL); // No timeout
}
if (NT_SUCCESS(status) && NT_SUCCESS(Irp->IoStatus.Status)) {
//
// As we are successfully now back from our start device
// we can do work.
//
devExt->Started = TRUE;
devExt->Removed = FALSE;
devExt->SurpriseRemoved = FALSE;
}
//
// We must now complete the IRP, since we stopped it in the
// completetion routine with MORE_PROCESSING_REQUIRED.
//
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
}
case IRP_MN_SURPRISE_REMOVAL:
//
// Same as a remove device, but don't call IoDetach or IoDeleteDevice
//
devExt->SurpriseRemoved = TRUE;
// Remove code here
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->TopOfStack, Irp);
break;
case IRP_MN_REMOVE_DEVICE:
devExt->Removed = TRUE;
// remove code here
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->TopOfStack, Irp);
IoDetachDevice(devExt->TopOfStack);
IoDeleteDevice(DeviceObject);
break;
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:
//
// Here the filter driver might modify the behavior of these IRPS
// Please see PlugPlay documentation for use of these IRPs.
//
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->TopOfStack, Irp);
break;
}
return status;
}
NTSTATUS
KbFilter_Power(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is the dispatch routine for power irps Does nothing except
record the state of the device.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
Status is returned.
--*/
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION devExt;
POWER_STATE powerState;
POWER_STATE_TYPE powerType;
PAGED_CODE();
devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation(Irp);
powerType = irpStack->Parameters.Power.Type;
powerState = irpStack->Parameters.Power.State;
switch (irpStack->MinorFunction) {
case IRP_MN_SET_POWER:
if (powerType == DevicePowerState) {
devExt->DeviceState = powerState.DeviceState;
}
case IRP_MN_POWER_SEQUENCE:
case IRP_MN_WAIT_WAKE:
case IRP_MN_QUERY_POWER:
default:
break;
}
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(devExt->TopOfStack, Irp);
}
NTSTATUS
KbFilter_InitializationRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID SynchFuncContext,
IN PI8042_SYNCH_READ_PORT ReadPort,
IN PI8042_SYNCH_WRITE_PORT WritePort,
OUT PBOOLEAN TurnTranslationOn
)
/*++
Routine Description:
This routine gets called after the following has been performed on the kb
1) a reset
2) set the typematic
3) set the LEDs
i8042prt specific code, if you are writing a packet only filter driver, you
can remove this function
Arguments:
DeviceObject - Context passed during IOCTL_INTERNAL_I8042_HOOK_KEYBOARD
SynchFuncContext - Context to pass when calling Read/WritePort
Read/WritePort - Functions to synchronoulsy read and write to the kb
TurnTranslationOn - If TRUE when this function returns, i8042prt will not
turn on translation on the keyboard
Return Value:
Status is returned.
--*/
{
PDEVICE_EXTENSION devExt;
NTSTATUS status = STATUS_SUCCESS;
devExt = DeviceObject->DeviceExtension;
//
// Do any interesting processing here. We just call any other drivers
// in the chain if they exist. Make Translation is turned on as well
//
if (devExt->UpperInitializationRoutine) {
status = (*devExt->UpperInitializationRoutine) (
devExt->UpperContext,
SynchFuncContext,
ReadPort,
WritePort,
TurnTranslationOn
);
if (!NT_SUCCESS(status)) {
return status;
}
}
*TurnTranslationOn = TRUE;
return status;
}
BOOLEAN
KbFilter_IsrHook(
PDEVICE_OBJECT DeviceObject,
PKEYBOARD_INPUT_DATA CurrentInput,
POUTPUT_PACKET CurrentOutput,
UCHAR StatusByte,
PUCHAR DataByte,
PBOOLEAN ContinueProcessing,
PKEYBOARD_SCAN_STATE ScanState
)
/*++
Routine Description:
This routine gets called at the beginning of processing of the kb interrupt.
i8042prt specific code, if you are writing a packet only filter driver, you
can remove this function
Arguments:
DeviceObject - Our context passed during IOCTL_INTERNAL_I8042_HOOK_KEYBOARD
CurrentInput - Current input packet being formulated by processing all the
interrupts
CurrentOutput - Current list of bytes being written to the keyboard or the
i8042 port.
StatusByte - Byte read from I/O port 60 when the interrupt occurred
DataByte - Byte read from I/O port 64 when the interrupt occurred.
This value can be modified and i8042prt will use this value
if ContinueProcessing is TRUE
ContinueProcessing - If TRUE, i8042prt will proceed with normal processing of
the interrupt. If FALSE, i8042prt will return from the
interrupt after this function returns. Also, if FALSE,
it is this functions responsibilityt to report the input
packet via the function provided in the hook IOCTL or via
queueing a DPC within this driver and calling the
service callback function acquired from the connect IOCTL
Return Value:
Status is returned.
--*/
{
PDEVICE_EXTENSION devExt;
BOOLEAN retVal = TRUE;
devExt = DeviceObject->DeviceExtension;
if (devExt->UpperIsrHook) {
//press
retVal = (*devExt->UpperIsrHook) (
devExt->UpperContext,
CurrentInput,
CurrentOutput,
StatusByte,
DataByte,
ContinueProcessing,
ScanState
);
if (!retVal || !(*ContinueProcessing)) {
return retVal;
}
}
*ContinueProcessing = TRUE;
return retVal;
}
VOID
KbFilter_ServiceCallback(
IN PDEVICE_OBJECT DeviceObject,
IN PKEYBOARD_INPUT_DATA InputDataStart,
IN PKEYBOARD_INPUT_DATA InputDataEnd,
IN OUT PULONG InputDataConsumed
)
/*++
Routine Description:
Called when there are keyboard packets to report to the RIT. You can do
anything you like to the packets. For instance:
o Drop a packet altogether
o Mutate the contents of a packet
o Insert packets into the stream
Arguments:
DeviceObject - Context passed during the connect IOCTL
InputDataStart - First packet to be reported
InputDataEnd - One past the last packet to be reported. Total number of
packets is equal to InputDataEnd - InputDataStart
InputDataConsumed - Set to the total number of packets consumed by the RIT
(via the function pointer we replaced in the connect
IOCTL)
Return Value:
Status is returned.
--*/
{
PDEVICE_EXTENSION devExt;
devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
if(InputDataStart->MakeCode==0x1e) //A的press 码
InputDataStart->MakeCode=0x11;//W的press码
else if(InputDataStart->MakeCode==0x11)
InputDataStart->MakeCode=0x1e;
//release
/* if(InputDataStart->MakeCode==0x91) //0x91 W 的release码
InputDataStart->MakeCode=0x9e;//0x9e A的release码
else if(InputDataStart->MakeCode==0x9e)
InputDataStart->MakeCode=0x91;
*/
(*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
InputDataStart,
InputDataEnd,
InputDataConsumed);
}
VOID
KbFilter_Unload(
IN PDRIVER_OBJECT Driver
)
/*++
Routine Description:
Free all the allocated resources associated with this driver.
Arguments:
DriverObject - Pointer to the driver object.
Return Value:
None.
--*/
{
PAGED_CODE();
UNREFERENCED_PARAMETER(Driver);
ASSERT(NULL == Driver->DeviceObject);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -