測試機器:win7x86
myhead.h:
#include <ntddk.h>
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
);
typedef NTSTATUS(__stdcall *PDRVDISPATCHFUNC)(PDEVICE_OBJECT pDevObj, PIRP pIrp);
NTSTATUS DisPatchRead(PDEVICE_OBJECT pDevObj, PIRP pIrp);
NTSTATUS Hook(BOOLEAN IsEnble);
void Unload(PDRIVER_OBJECT pDriverObj);
NTSTATUS
MyCompletionRoutine(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp,
__in PVOID Context
);
test.c
#include "myhead.h"
#include <ntddkbd.h>
extern POBJECT_TYPE *IoDriverObjectType;
PDRVDISPATCHFUNC OrlDispatchRead = NULL;
ULONG numPendingIrps = 0;
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegisterStr)
{
UNREFERENCED_PARAMETER(pRegisterStr);
NTSTATUS status = STATUS_SUCCESS;
pDriverObj->DriverUnload = Unload;
DbgPrint("DriverEntry\n");
Hook(TRUE);
return status;
}
void Unload(PDRIVER_OBJECT pDriverObj)
{
LARGE_INTEGER liDelayTime;
Hook(FALSE);
liDelayTime.QuadPart = -1000000;
while (numPendingIrps > 0)
{
KeDelayExecutionThread(KernelMode, FALSE, &liDelayTime);
}
DbgPrint("Unload\n");
}
NTSTATUS Hook(BOOLEAN IsEnble)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
UNICODE_STRING usKeyDrvName;
PDRIVER_OBJECT pKeyDrvObj = NULL;
RtlInitUnicodeString(&usKeyDrvName, L"\\Driver\\kbdclass");
status = ObReferenceObjectByName(&usKeyDrvName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, (PVOID*)&pKeyDrvObj);
if (!NT_SUCCESS(status))
{
DbgPrint("ObReferenceObjectByName error status:%p\n",status);
return status;
}
ObReferenceObject(pKeyDrvObj);
if (IsEnble)
{
OrlDispatchRead = pKeyDrvObj->MajorFunction[IRP_MJ_READ];
pKeyDrvObj->MajorFunction[IRP_MJ_READ] = (PDRVDISPATCHFUNC)DisPatchRead;
}
else
{
pKeyDrvObj->MajorFunction[IRP_MJ_READ] = OrlDispatchRead;
}
return status;
}
NTSTATUS DisPatchRead(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
DbgPrint("pIrpSp->Control:%x", pIrpSp->Control);
DbgPrint("abc:%x", SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR | SL_INVOKE_ON_CANCEL);
pIrpSp->Control = SL_INVOKE_ON_SUCCESS /*| SL_INVOKE_ON_ERROR | SL_INVOKE_ON_CANCEL*/;
if (NT_SUCCESS(pIrp->IoStatus.Status))
{
DbgPrint("DisPatchRead KEY BOARD\n");
DbgPrint("CompletionRoutine %p BOARD\n", (PVOID)pIrpSp->CompletionRoutine);
pIrpSp->Context = (PVOID)pIrpSp->CompletionRoutine;
pIrpSp->CompletionRoutine = MyCompletionRoutine;
}
if (pIrp->PendingReturned)
{
IoMarkIrpPending(pIrp);
}
numPendingIrps++;
return OrlDispatchRead(pDevObj, pIrp);
}
NTSTATUS
MyCompletionRoutine(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp,
__in PVOID Context
)
{
DbgPrint("MyCompletionRoutine\n");
PKEYBOARD_INPUT_DATA pKid;
//PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(Irp);
if (NT_SUCCESS(Irp->IoStatus.Status))
{
pKid = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
ULONG uCount = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
for (ULONG i = 0; i < uCount;i++)
{
switch (pKid->Flags)
{
case KEY_MAKE:
DbgPrint("\nFlag: KEY_MAKE\n");
break;
case KEY_BREAK:
DbgPrint("\nFlag: KEY_BREAK\n");
break;
}
DbgPrint("Key Code: %x\n", pKid->MakeCode);
}
}
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
numPendingIrps--;
if ((Irp->StackCount > (ULONG)1) && (Context != NULL))
{
return ((PIO_COMPLETION_ROUTINE)Context)(DeviceObject, Irp, NULL);
}
else
return Irp->IoStatus.Status;
}
其中
pIrpSp->Control = SL_INVOKE_ON_SUCCESS /*| SL_INVOKE_ON_ERROR | SL_INVOKE_ON_CANCEL*/;
這一句是必須要設定的,不然進不了自己的完成函數!