//键盘输入可正常捕捉
问题在于没有键盘输入时,只需拖动窗口或滚动条就会捕捉到1d+3个2e 的扫描码。。
而我压根就没动过键盘呢,每次都这样只须发生上述行为(不动键盘)就会捕捉到1d+3个2e的扫描码?
请高手解释..完整代码如下:(代码有点长,已删除掉一些不太重要的)
#include <ntddk.h>
#include <ntddkbd.h>
//读请求次数
ULONG gC2pKeyCount = 0;
typedef struct _C2P_DEV_EXT
{
...//设备扩展常用结构
}C2P_DEV_EXT, *PC2P_DEV_EXT;//填充设备扩展结构
NTSTATUS c2pDevExtInit(
IN PC2P_DEV_EXT devExt,
IN PDEVICE_OBJECT pFilterDeviceObject,
IN PDEVICE_OBJECT pTargetDeviceObject,
IN PDEVICE_OBJECT pLowerDeviceObject )
{
memset(devExt, 0, sizeof(C2P_DEV_EXT));
devExt->NodeSize = sizeof(C2P_DEV_EXT);
devExt->pFilterDeviceObject = pFilterDeviceObject;
KeInitializeSpinLock(&(devExt->IoRequestsSpinLock));
KeInitializeEvent(&(devExt->IoInProgressEvent), NotificationEvent, FALSE);
devExt->TargetDeviceObject = pTargetDeviceObject;
devExt->LowerDeviceObject = pLowerDeviceObject;
return( STATUS_SUCCESS );
}extern POBJECT_TYPE IoDriverObjectType;
#define KBD_DRIVER_NAME L"\\Driver\\Kbdclass"NTSTATUS ObReferenceObjectByName(
PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE AccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID *Object
);
NTSTATUS c2pAttachDevices(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
NTSTATUS status = 0;
UNICODE_STRING uniNtNameString;
PC2P_DEV_EXT devExt;
PDEVICE_OBJECT pFilterDeviceObject = NULL;
PDEVICE_OBJECT pTargerDeviceObject = NULL;
PDEVICE_OBJECT pLowerDeviceObject = NULL;
PDRIVER_OBJECT kbdDriverObject = NULL; KdPrint(("开始绑定KbdClass下的所有设备\n")); RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME);
status = ObReferenceObjectByName(
&uniNtNameString,
OBJ_CASE_INSENSITIVE,
NULL,
0,
IoDriverObjectType,
KernelMode,
NULL,
&kbdDriverObject
); if (!NT_SUCCESS(status))
{
KdPrint(("打开驱动对象KbdClass失败!\n"));
return status;
}
else
{
ObDereferenceObject(driver);
} //这是设备链中的第一个设备
pTargerDeviceObject = kbdDriverObject->DeviceObject;
//现在开始遍历这个设备链
while(pTargerDeviceObject)
{
//生成一个过滤设备
status = IoCreateDevice(
driver,
sizeof(C2P_DEV_EXT),
NULL,
pTargerDeviceObject->DeviceType,
pTargerDeviceObject ->Characteristics,
FALSE,
&pFilterDeviceObject
);
if (!NT_SUCCESS(status))
{
KdPrint(("生成过滤设备失败\n"));
return status;
} //绑定
pLowerDeviceObject = IoAttachDeviceToDeviceStack(
pFilterDeviceObject,
pTargerDeviceObject
);
//如果绑定失败了,放弃之前操作,退出
if (pLowerDeviceObject == NULL)
{
KdPrint(("绑定设备失败!\n"));
IoDeleteDevice(pFilterDeviceObject);
pFilterDeviceObject = NULL;
return status;
} //设备扩展
devExt = (PC2P_DEV_EXT)(pFilterDeviceObject->DeviceExtension);
c2pDevExtInit(
devExt,
pFilterDeviceObject,
pTargerDeviceObject,
pLowerDeviceObject
);
//复制关键标志位
//...
//移动到下一个设备,继续遍历
pTargerDeviceObject = pTargerDeviceObject->NextDevice;
}
return status;
}//其它请求分发函数
NTSTATUS c2pDispatchGeneral( PDEVICE_OBJECT device, PIRP Irp)
{
// 其他的分发函数,直接skip然后用IoCallDriver把IRP发送到真实设备的设备对象。
KdPrint(("其它请求分发函数!\n"));
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(((PC2P_DEV_EXT)device->DeviceExtension)->LowerDeviceObject, Irp);
} //几种关键按键之下字符
unsigned char asciiTbl[]={...};//略
//键盘标志状态
#define S_SHIFT 1
#define S_CAPS 2
#define S_NUM 4
//这是一个标记,用来保存当前键盘的状态。其中有3个位,分别表示
//Caps Lock键、Num Lock键和Shift键是否按下了
static int kb_status = S_NUM;
void _stdcall print_keystroke(UCHAR sch)
{
UCHAR ch = 0;
ULONG off = 0; if ((sch & 0x80) == 0) //如果是按下(扫描码的最高位判断按下或抬起)
{
//如果按下了字母或数字等可见字符
if ((sch < 0x47) || ((sch >= 0x47 && sch < 0x54) && (kb_status & S_NUM)))
{
ch = asciiTbl[off + sch];
} switch (sch)
{
case 0x3A: kb_status = kb_status ^ S_CAPS; break;
case 0x45: kb_status = kb_status ^ S_NUM; break;
case 0x2a:
case 0x36:
kb_status = kb_status | S_SHIFT; break;
}
}
else
{
if (sch == 0xAA || sch == 0xB6)
{
kb_status = kb_status & ~S_SHIFT;
}
} if (ch >= 0x20 && ch < 0x7F)
{
DbgPrint("4.实际字符:%c\n", ch);
}
}#define LCONTROL ((USHORT)0x1D)
#define CAPS_LOCK ((USHORT)0x3A)
//这是一个IRP完成回调函数的原型
NTSTATUS c2pReadComplete(PDEVICE_OBJECT device, PIRP Irp, PVOID Context)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
ULONG i, numKeys, buff_len = 0;
PUCHAR buff = NULL;
PKEYBOARD_INPUT_DATA KeyData; //假设这个请求是成功的。很显然,如果请求失败了,这么获取进一步信息是没有意义的
if (NT_SUCCESS(Irp->IoStatus.Status))
{
//获得读请求完成后的缓冲区
buff = Irp->AssociatedIrp.SystemBuffer;
KeyData = (PKEYBOARD_INPUT_DATA)buff;
buff_len = Irp->IoStatus.Information;
numKeys = buff_len / sizeof(KEYBOARD_INPUT_DATA);
//To do something
//....
for (i = 0; i<numKeys; i++)
{
DbgPrint("1.KID结构数目:%d\n", numKeys);
DbgPrint("2.扫描码:%x\n", KeyData->MakeCode);
DbgPrint("3.%s\n", KeyData->Flags ? "抬起" : "按下");
print_keystroke((UCHAR)KeyData->MakeCode);
}
} gC2pKeyCount--; if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
return Irp->IoStatus.Status;
}
//读请求
NTSTATUS c2pDispatchRead(IN PDEVICE_OBJECT device, PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
PC2P_DEV_EXT devExt;
PIO_STACK_LOCATION currentIrpStack;
KEVENT waitEvent;
KeInitializeEvent(&waitEvent, NotificationEvent, FALSE); if (Irp->CurrentLocation == 1) //IRP当前栈空间
{
ULONG ReturnedInformation = 0;
KdPrint(("Dispatch encountered bogus current location\n"));
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} //全局变量键计数器+1
gC2pKeyCount++; //得到设备扩展,目的是为了获得下一个设备指针
devExt = (PC2P_DEV_EXT)device->DeviceExtension;
currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, c2pReadComplete, device, TRUE, TRUE, TRUE);
return IoCallDriver(devExt->LowerDeviceObject, Irp);
}
//电源相关请求
NTSTATUS c2pPower(IN PDEVICE_OBJECT device, IN PIRP Irp)
{
PC2P_DEV_EXT devExt;
devExt = (PC2P_DEV_EXT)device->DeviceExtension;
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(devExt->LowerDeviceObject, Irp);
}//PNP处理
NTSTATUS c2pPnP(IN PDEVICE_OBJECT device, PIRP Irp)
{
PC2P_DEV_EXT devExt;
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
KIRQL oldIrql;
KEVENT event; //获得真实设备
devExt = (PC2P_DEV_EXT)(device->DeviceExtension);
irpStack = IoGetCurrentIrpStackLocation(Irp); switch (irpStack->MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
KdPrint(("IRP_MN_REMOVE_DEVICE\n")); IoSkipCurrentIrpStackLocation(Irp);
IoCallDriver(devExt->LowerDeviceObject, Irp);
IoDetachDevice(devExt->LowerDeviceObject);
IoDeleteDevice(device);
status = STATUS_SUCCESS;
break; default:
//对于其它类型的IRP,全部都直接下发即可
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->LowerDeviceObject, Irp);
}
return status;
}//解除绑定,并删除本驱动生成的过滤设备
VOID c2pDetach(IN PDEVICE_OBJECT pDeviceObject)
{
PC2P_DEV_EXT devExt;
BOOLEAN NoRequestsOutstanding = FALSE;
devExt = (PC2P_DEV_EXT)pDeviceObject->DeviceExtension;
IoDetachDevice(devExt->TargetDeviceObject); //解除绑定用目标设备//以绑定COM不同
devExt->TargetDeviceObject = NULL;
IoDeleteDevice(pDeviceObject); //删除本驱动生成的过滤设备
devExt->pFilterDeviceObject = NULL;
DbgPrint(("解除绑定并删除本驱动生成的过滤设备成功\n"));
return;
}
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND * 1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND * 1000)
VOID c2pUnload(IN PDRIVER_OBJECT driver)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PC2P_DEV_EXT devExt;
LARGE_INTEGER lDelay;
PRKTHREAD CurrentThread;
//延迟些时间
lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND);
CurrentThread = KeGetCurrentThread();
KeSetPriorityThread(CurrentThread, LOW_REALTIME_PRIORITY); UNREFERENCED_PARAMETER(driver);
DeviceObject = driver->DeviceObject;
while (DeviceObject)
{
c2pDetach(DeviceObject);
DeviceObject = DeviceObject->NextDevice;
}
while (gC2pKeyCount)
{
KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
}
KdPrint(("驱动卸载成功!\n"));
}NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
ULONG i;
NTSTATUS status;
KdPrint(("驱动入口!\n")); //填写所有分发函数的指针
for (i = 0; i<IRP_MJ_MAXIMUM_FUNCTION; i++)
{
driver->MajorFunction[i] = c2pDispatchGeneral;
} driver->MajorFunction[IRP_MJ_READ] = c2pDispatchRead;
driver->MajorFunction [IRP_MJ_POWER] = c2pPower; driver->MajorFunction [IRP_MJ_PNP] = c2pPnP; // 卸载函数。
driver->DriverUnload = c2pUnload;
// gDriverObject = DriverObject; // 绑定所有键盘设备
status =c2pAttachDevices(driver, reg_path); return status;
}
问题在于没有键盘输入时,只需拖动窗口或滚动条就会捕捉到1d+3个2e 的扫描码。。
而我压根就没动过键盘呢,每次都这样只须发生上述行为(不动键盘)就会捕捉到1d+3个2e的扫描码?
请高手解释..完整代码如下:(代码有点长,已删除掉一些不太重要的)
#include <ntddk.h>
#include <ntddkbd.h>
//读请求次数
ULONG gC2pKeyCount = 0;
typedef struct _C2P_DEV_EXT
{
...//设备扩展常用结构
}C2P_DEV_EXT, *PC2P_DEV_EXT;//填充设备扩展结构
NTSTATUS c2pDevExtInit(
IN PC2P_DEV_EXT devExt,
IN PDEVICE_OBJECT pFilterDeviceObject,
IN PDEVICE_OBJECT pTargetDeviceObject,
IN PDEVICE_OBJECT pLowerDeviceObject )
{
memset(devExt, 0, sizeof(C2P_DEV_EXT));
devExt->NodeSize = sizeof(C2P_DEV_EXT);
devExt->pFilterDeviceObject = pFilterDeviceObject;
KeInitializeSpinLock(&(devExt->IoRequestsSpinLock));
KeInitializeEvent(&(devExt->IoInProgressEvent), NotificationEvent, FALSE);
devExt->TargetDeviceObject = pTargetDeviceObject;
devExt->LowerDeviceObject = pLowerDeviceObject;
return( STATUS_SUCCESS );
}extern POBJECT_TYPE IoDriverObjectType;
#define KBD_DRIVER_NAME L"\\Driver\\Kbdclass"NTSTATUS ObReferenceObjectByName(
PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE AccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID *Object
);
NTSTATUS c2pAttachDevices(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
NTSTATUS status = 0;
UNICODE_STRING uniNtNameString;
PC2P_DEV_EXT devExt;
PDEVICE_OBJECT pFilterDeviceObject = NULL;
PDEVICE_OBJECT pTargerDeviceObject = NULL;
PDEVICE_OBJECT pLowerDeviceObject = NULL;
PDRIVER_OBJECT kbdDriverObject = NULL; KdPrint(("开始绑定KbdClass下的所有设备\n")); RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME);
status = ObReferenceObjectByName(
&uniNtNameString,
OBJ_CASE_INSENSITIVE,
NULL,
0,
IoDriverObjectType,
KernelMode,
NULL,
&kbdDriverObject
); if (!NT_SUCCESS(status))
{
KdPrint(("打开驱动对象KbdClass失败!\n"));
return status;
}
else
{
ObDereferenceObject(driver);
} //这是设备链中的第一个设备
pTargerDeviceObject = kbdDriverObject->DeviceObject;
//现在开始遍历这个设备链
while(pTargerDeviceObject)
{
//生成一个过滤设备
status = IoCreateDevice(
driver,
sizeof(C2P_DEV_EXT),
NULL,
pTargerDeviceObject->DeviceType,
pTargerDeviceObject ->Characteristics,
FALSE,
&pFilterDeviceObject
);
if (!NT_SUCCESS(status))
{
KdPrint(("生成过滤设备失败\n"));
return status;
} //绑定
pLowerDeviceObject = IoAttachDeviceToDeviceStack(
pFilterDeviceObject,
pTargerDeviceObject
);
//如果绑定失败了,放弃之前操作,退出
if (pLowerDeviceObject == NULL)
{
KdPrint(("绑定设备失败!\n"));
IoDeleteDevice(pFilterDeviceObject);
pFilterDeviceObject = NULL;
return status;
} //设备扩展
devExt = (PC2P_DEV_EXT)(pFilterDeviceObject->DeviceExtension);
c2pDevExtInit(
devExt,
pFilterDeviceObject,
pTargerDeviceObject,
pLowerDeviceObject
);
//复制关键标志位
//...
//移动到下一个设备,继续遍历
pTargerDeviceObject = pTargerDeviceObject->NextDevice;
}
return status;
}//其它请求分发函数
NTSTATUS c2pDispatchGeneral( PDEVICE_OBJECT device, PIRP Irp)
{
// 其他的分发函数,直接skip然后用IoCallDriver把IRP发送到真实设备的设备对象。
KdPrint(("其它请求分发函数!\n"));
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(((PC2P_DEV_EXT)device->DeviceExtension)->LowerDeviceObject, Irp);
} //几种关键按键之下字符
unsigned char asciiTbl[]={...};//略
//键盘标志状态
#define S_SHIFT 1
#define S_CAPS 2
#define S_NUM 4
//这是一个标记,用来保存当前键盘的状态。其中有3个位,分别表示
//Caps Lock键、Num Lock键和Shift键是否按下了
static int kb_status = S_NUM;
void _stdcall print_keystroke(UCHAR sch)
{
UCHAR ch = 0;
ULONG off = 0; if ((sch & 0x80) == 0) //如果是按下(扫描码的最高位判断按下或抬起)
{
//如果按下了字母或数字等可见字符
if ((sch < 0x47) || ((sch >= 0x47 && sch < 0x54) && (kb_status & S_NUM)))
{
ch = asciiTbl[off + sch];
} switch (sch)
{
case 0x3A: kb_status = kb_status ^ S_CAPS; break;
case 0x45: kb_status = kb_status ^ S_NUM; break;
case 0x2a:
case 0x36:
kb_status = kb_status | S_SHIFT; break;
}
}
else
{
if (sch == 0xAA || sch == 0xB6)
{
kb_status = kb_status & ~S_SHIFT;
}
} if (ch >= 0x20 && ch < 0x7F)
{
DbgPrint("4.实际字符:%c\n", ch);
}
}#define LCONTROL ((USHORT)0x1D)
#define CAPS_LOCK ((USHORT)0x3A)
//这是一个IRP完成回调函数的原型
NTSTATUS c2pReadComplete(PDEVICE_OBJECT device, PIRP Irp, PVOID Context)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
ULONG i, numKeys, buff_len = 0;
PUCHAR buff = NULL;
PKEYBOARD_INPUT_DATA KeyData; //假设这个请求是成功的。很显然,如果请求失败了,这么获取进一步信息是没有意义的
if (NT_SUCCESS(Irp->IoStatus.Status))
{
//获得读请求完成后的缓冲区
buff = Irp->AssociatedIrp.SystemBuffer;
KeyData = (PKEYBOARD_INPUT_DATA)buff;
buff_len = Irp->IoStatus.Information;
numKeys = buff_len / sizeof(KEYBOARD_INPUT_DATA);
//To do something
//....
for (i = 0; i<numKeys; i++)
{
DbgPrint("1.KID结构数目:%d\n", numKeys);
DbgPrint("2.扫描码:%x\n", KeyData->MakeCode);
DbgPrint("3.%s\n", KeyData->Flags ? "抬起" : "按下");
print_keystroke((UCHAR)KeyData->MakeCode);
}
} gC2pKeyCount--; if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
return Irp->IoStatus.Status;
}
//读请求
NTSTATUS c2pDispatchRead(IN PDEVICE_OBJECT device, PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
PC2P_DEV_EXT devExt;
PIO_STACK_LOCATION currentIrpStack;
KEVENT waitEvent;
KeInitializeEvent(&waitEvent, NotificationEvent, FALSE); if (Irp->CurrentLocation == 1) //IRP当前栈空间
{
ULONG ReturnedInformation = 0;
KdPrint(("Dispatch encountered bogus current location\n"));
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} //全局变量键计数器+1
gC2pKeyCount++; //得到设备扩展,目的是为了获得下一个设备指针
devExt = (PC2P_DEV_EXT)device->DeviceExtension;
currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, c2pReadComplete, device, TRUE, TRUE, TRUE);
return IoCallDriver(devExt->LowerDeviceObject, Irp);
}
//电源相关请求
NTSTATUS c2pPower(IN PDEVICE_OBJECT device, IN PIRP Irp)
{
PC2P_DEV_EXT devExt;
devExt = (PC2P_DEV_EXT)device->DeviceExtension;
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(devExt->LowerDeviceObject, Irp);
}//PNP处理
NTSTATUS c2pPnP(IN PDEVICE_OBJECT device, PIRP Irp)
{
PC2P_DEV_EXT devExt;
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
KIRQL oldIrql;
KEVENT event; //获得真实设备
devExt = (PC2P_DEV_EXT)(device->DeviceExtension);
irpStack = IoGetCurrentIrpStackLocation(Irp); switch (irpStack->MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
KdPrint(("IRP_MN_REMOVE_DEVICE\n")); IoSkipCurrentIrpStackLocation(Irp);
IoCallDriver(devExt->LowerDeviceObject, Irp);
IoDetachDevice(devExt->LowerDeviceObject);
IoDeleteDevice(device);
status = STATUS_SUCCESS;
break; default:
//对于其它类型的IRP,全部都直接下发即可
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->LowerDeviceObject, Irp);
}
return status;
}//解除绑定,并删除本驱动生成的过滤设备
VOID c2pDetach(IN PDEVICE_OBJECT pDeviceObject)
{
PC2P_DEV_EXT devExt;
BOOLEAN NoRequestsOutstanding = FALSE;
devExt = (PC2P_DEV_EXT)pDeviceObject->DeviceExtension;
IoDetachDevice(devExt->TargetDeviceObject); //解除绑定用目标设备//以绑定COM不同
devExt->TargetDeviceObject = NULL;
IoDeleteDevice(pDeviceObject); //删除本驱动生成的过滤设备
devExt->pFilterDeviceObject = NULL;
DbgPrint(("解除绑定并删除本驱动生成的过滤设备成功\n"));
return;
}
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND * 1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND * 1000)
VOID c2pUnload(IN PDRIVER_OBJECT driver)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PC2P_DEV_EXT devExt;
LARGE_INTEGER lDelay;
PRKTHREAD CurrentThread;
//延迟些时间
lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND);
CurrentThread = KeGetCurrentThread();
KeSetPriorityThread(CurrentThread, LOW_REALTIME_PRIORITY); UNREFERENCED_PARAMETER(driver);
DeviceObject = driver->DeviceObject;
while (DeviceObject)
{
c2pDetach(DeviceObject);
DeviceObject = DeviceObject->NextDevice;
}
while (gC2pKeyCount)
{
KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
}
KdPrint(("驱动卸载成功!\n"));
}NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
ULONG i;
NTSTATUS status;
KdPrint(("驱动入口!\n")); //填写所有分发函数的指针
for (i = 0; i<IRP_MJ_MAXIMUM_FUNCTION; i++)
{
driver->MajorFunction[i] = c2pDispatchGeneral;
} driver->MajorFunction[IRP_MJ_READ] = c2pDispatchRead;
driver->MajorFunction [IRP_MJ_POWER] = c2pPower; driver->MajorFunction [IRP_MJ_PNP] = c2pPnP; // 卸载函数。
driver->DriverUnload = c2pUnload;
// gDriverObject = DriverObject; // 绑定所有键盘设备
status =c2pAttachDevices(driver, reg_path); return status;
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货