对于 PS/2 的串口过滤基本上使用通用的绑定设备的方法就可以实现,那么,在 USB 的传输方式上,究竟会是什么样的呢?
对于这个问题,我在 开源的 ctr2cap 的基础上,做了一些简化的操作,让它来达到这个功能。。。
想想今天数据结构的第一次上机考试,通过 USB 来传输文件的云云。。。
如果,我是老师,你们就完了,装上我写的这个驱动,什么东西都别想出去。。。
哈哈。。。当然,我没有这样做,但是我可以基于以上做一些很猥琐的操作,那是不难的。。。
当然,这样的绑定太常规了,过段时间,我要通过 HOOK API 来实现它,或者 通过 IDT 的重定向的指针,更底层的实现以下这个过滤。。。
#include <wdm.h>
#define KBD_DRIVER_NAME L"//Driver//Kbdclass"
PDRIVER_OBJECT gDriverObject = NULL;
typedef struct _C2P_DEV_EXT
{
ULONG nodeSize;
PDEVICE_OBJECT pFltDevObj; //过滤设备
KSPIN_LOCK IoRequestsSpinLock; //保护锁
KEVENT IoInProcessEvent; //同步处理
PDEVICE_OBJECT TargeDevObj; //要绑定的设备
PDEVICE_OBJECT LowerDevObj; //绑定前的底层设备
}C2P_DEV_EXT, *PC2P_DEV_EXT;
//对设备扩展的初始化
NTSTATUS c2pDevExtInit(PC2P_DEV_EXT devExt,
PDEVICE_OBJECT pFltDevObj,
PDEVICE_OBJECT pTargeDevObj,
PDEVICE_OBJECT LowerDevObj
)
{
memset(devExt, 0, sizeof(C2P_DEV_EXT));
devExt->nodeSize = sizeof(C2P_DEV_EXT);
devExt->pFltDevObj = pFltDevObj;
KeInitializeSpinLock(&(devExt->IoRequestsSpinLock));
KeInitializeEvent(&(devExt->IoInProcessEvent), NotificationEvent, FALSE);
devExt->LowerDevObj = LowerDevObj;
devExt->TargeDevObj = pTargeDevObj;
return STATUS_SUCCESS;
}
//声明一个未公开的函数
NTSTATUS
ObReferenceObjectByName(
PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE AccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID *Object
);
extern POBJECT_TYPE IoDriverObjectType;
ULONG gC2pKeyCount = 0;
//打开驱动对象并绑定
NTSTATUS c2pAttachDevice(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
NTSTATUS status = 0;
UNICODE_STRING unitNameStr;
PC2P_DEV_EXT devExt;
PDEVICE_OBJECT pFltDevObj = NULL;
PDEVICE_OBJECT pTargeDevObj = NULL;
PDEVICE_OBJECT pLowerDevObj = NULL;
PDRIVER_OBJECT kbdDriverObj = NULL;
RtlInitUnicodeString(&unitNameStr, KBD_DRIVER_NAME);
status = ObReferenceObjectByName(
&unitNameStr,
OBJ_CASE_INSENSITIVE,
NULL,
0,
IoDriverObjectType,
KernelMode,
NULL,
&kbdDriverObj);
if (!NT_SUCCESS(status))
{
KdPrint(("geting device is fail /n"));
return status;
}
else
{
ObDereferenceObject(driver);
}
pTargeDevObj = kbdDriverObj->DeviceObject; //得到设备链的第一个设备
while (pTargeDevObj)
{
status = IoCreateDevice(driver,
sizeof(C2P_DEV_EXT),
NULL,
pTargeDevObj->DeviceType,
pTargeDevObj->Characteristics,
FALSE,
&pFltDevObj);
if (!NT_SUCCESS(status))
{
KdPrint(("createing is fail/n"));
return status;
}
pLowerDevObj = IoAttachDeviceToDeviceStack(pFltDevObj, pTargeDevObj); //绑定后,返回真实的设备指针
if (NULL == pLowerDevObj)
{
KdPrint(("attach device is fail/n"));
IoDeleteDevice(pFltDevObj);
pFltDevObj = NULL;
return status;
}
devExt = (PC2P_DEV_EXT)(pFltDevObj->DeviceExtension);
c2pDevExtInit(devExt,pFltDevObj, pTargeDevObj, pLowerDevObj); //初始化设备扩展
pFltDevObj->DeviceType = pLowerDevObj->DeviceType; //拷贝原来设备的信息
pFltDevObj->Characteristics = pLowerDevObj->Characteristics;
pFltDevObj->StackSize = pLowerDevObj->StackSize + 1;
pFltDevObj->Flags |= pLowerDevObj->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
pTargeDevObj = pTargeDevObj->NextDevice;
}
return status;
}
VOID c2pDetach(PDEVICE_OBJECT pDeviceObj)
{
PC2P_DEV_EXT devExt;
BOOLEAN NoRequstOutStand = FALSE;
devExt = (PC2P_DEV_EXT)(pDeviceObj->DeviceExtension);
__try
{
__try
{
IoDetachDevice(devExt->TargeDevObj);
devExt->TargeDevObj = NULL;
IoDeleteDevice(pDeviceObj);
devExt->pFltDevObj = NULL;
KdPrint(("deAttach is over/n"));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
__finally
{
}
return;
}
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
//卸载函数
VOID DriverUnload(PDRIVER_OBJECT driver)
{
PDEVICE_OBJECT devObj = NULL;
PDEVICE_OBJECT devOldObj = NULL;
PC2P_DEV_EXT devExt;
LARGE_INTEGER lDelay;
PRKTHREAD CurrentThread;
lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND);
CurrentThread = KeGetCurrentThread();
KdPrint(("driver is unload.../n"));
devObj = driver->DeviceObject;
while (devObj) //卸载设备对象
{
c2pDetach(devObj);
devObj = devObj->NextDevice;
}
ASSERT(NULL == driver->DeviceObject);
while(gC2pKeyCount)
{
KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
}
KdPrint(("driverUnload is ok/n"));
return;
}
//普通的分发函数
NTSTATUS c2pDispatchGeneral(PDEVICE_OBJECT device,
PIRP pIrp)
{
KdPrint(("General dispatch/n"));
IoSkipCurrentIrpStackLocation(pIrp);
return IoCallDriver(((PC2P_DEV_EXT)device->DeviceExtension)->LowerDevObj, pIrp);
}
//对电源的处理
NTSTATUS c2pDispatchPower(PDEVICE_OBJECT device,
PIRP pIrp)
{
PC2P_DEV_EXT devExt;
devExt = (PC2P_DEV_EXT)(device->DeviceExtension);
PoStartNextPowerIrp(pIrp);
IoSkipCurrentIrpStackLocation(pIrp);
return PoCallDriver(devExt->LowerDevObj, pIrp);
}
//即插即用的处理
NTSTATUS c2pDispatchPnp(PDEVICE_OBJECT device, PIRP pIrp)
{
PC2P_DEV_EXT devExt;
PIO_STACK_LOCATION IrpStack;
NTSTATUS status = STATUS_SUCCESS;
KIRQL oldIrq;
KEVENT event;
devExt = (PC2P_DEV_EXT)(device->DeviceExtension);
IrpStack = IoGetCurrentIrpStackLocation(pIrp);
switch (IrpStack->MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
KdPrint(("irp_mn_remove_device/n"));
IoSkipCurrentIrpStackLocation(pIrp);
IoCallDriver(devExt->LowerDevObj, pIrp);
IoDetachDevice(devExt->LowerDevObj);
IoDeleteDevice(device);
return STATUS_SUCCESS;
break;
default:
IoSkipCurrentIrpStackLocation(pIrp);
status = IoCallDriver(devExt->LowerDevObj, pIrp);
}
return status;
}
//完成函数
NTSTATUS c2pCompleteRead(PDEVICE_OBJECT device,
PIRP irp,
PVOID Context)
{
PIO_STACK_LOCATION pIrp;
ULONG buf_len = 0;
PUCHAR buffer = NULL;
size_t i;
pIrp = IoGetCurrentIrpStackLocation(irp);
if (NT_SUCCESS(irp->IoStatus.Status))
{
buffer = irp->AssociatedIrp.SystemBuffer; //得到缓冲区的内容
buf_len = irp->IoStatus.Information; //得到写入的长度
for (i = 0; i < buf_len; i++)
{
KdPrint(("ctr2 is %x/n", buffer));
}
}
gC2pKeyCount--;
if (irp->PendingReturned)
{
IoMarkIrpPending(irp);
}
return irp->IoStatus.Status;
}
//读的分发函数
NTSTATUS c2pDispatchRead(PDEVICE_OBJECT devObj, PIRP irp)
{
NTSTATUS status = STATUS_SUCCESS;
PC2P_DEV_EXT devExt;
PIO_STACK_LOCATION currentIrp;
KEVENT waitEvent;
KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
if (1 == irp->CurrentLocation)
{
KdPrint(("dispatch is Error /n"));
irp->IoStatus.Status = status;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;
}
gC2pKeyCount++;
devExt = (PC2P_DEV_EXT)(devObj->DeviceExtension);
currentIrp = IoGetCurrentIrpStackLocation(irp);
IoCopyCurrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(irp, c2pCompleteRead, devObj, TRUE, TRUE, TRUE);
return IoCallDriver(devExt->LowerDevObj, irp);
}
//主函数
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
ULONG i;
NTSTATUS status;
KdPrint(("driver is starting/n"));
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
driver->MajorFunction = c2pDispatchGeneral;
}
driver->MajorFunction[IRP_MJ_READ] = c2pDispatchRead;
driver->MajorFunction[IRP_MJ_POWER] = c2pDispatchPower;
driver->MajorFunction[IRP_MJ_PNP] = c2pDispatchPnp;
driver->DriverUnload = DriverUnload;
gDriverObject = driver;
status = c2pAttachDevice(driver, reg_path);
return STATUS_SUCCESS;
}