勾住有设备名字的驱动 拦截IRP(USB 光驱 无线上网卡等)

来源:互联网 发布:淘宝 送国外多久 编辑:程序博客网 时间:2024/06/11 01:57

#include   "ntddk.h "
#include   "string.h "

#define  FILE_DEVICE_CD_ROM 0x00000002
#define  FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
#define  DELAY_ONE_MICROSECOND  (-10)
#define  DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define  DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)


PDRIVER_DISPATCH   copyDriver_Dispatch = NULL;
PDRIVER_OBJECT     copy_driver_object = NULL;
UNICODE_STRING     linkString;


typedef struct _C2P_DEV_EXT
{
 // 这个结构的大小
 ULONG NodeSize;
 // 过滤设备对象
 PDEVICE_OBJECT pFilterDeviceObject;
 // 同时调用时的保护锁
 KSPIN_LOCK IoRequestsSpinLock;
 // 进程间同步处理 
 KEVENT IoInProgressEvent;
 // 绑定的设备对象
 PDEVICE_OBJECT TargetDeviceObject;
 // 绑定前底层设备对象
 PDEVICE_OBJECT LowerDeviceObject;
} C2P_DEV_EXT, *PC2P_DEV_EXT;


NTSTATUS pubDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
 NTSTATUS ntStatus=STATUS_ACCESS_DENIED;
 PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);

 Irp->IoStatus.Status = STATUS_SUCCESS;
 Irp->IoStatus.Information = 0; //如果请求成功,就是成功的数据;否则为0。
                                //实际填写的返回FileAllInformation结构的长度值。

 //所有电源操作,全部直接放过。
 if(irpsp->MajorFunction == IRP_MJ_POWER)
 {
  //直接发送,然后返回说已经被处理了。
  PoStartNextPowerIrp(Irp);
  IoSkipCurrentIrpStackLocation(Irp);
  ntStatus=PoCallDriver(((PC2P_DEV_EXT)DeviceObject->DeviceExtension)->LowerDeviceObject,Irp);
  return ntStatus;
 }

 // 这些请求直接下发执行即可。我们并不禁止或者改变它。
 IoSkipCurrentIrpStackLocation( Irp );
 ntStatus = IoCallDriver(((PC2P_DEV_EXT)DeviceObject->DeviceExtension)->LowerDeviceObject,Irp);
 return ntStatus;
}

NTSTATUS MyCDROMControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) 
{
 //返回请求CDROM失败!
 NTSTATUS ntStatus=STATUS_ACCESS_DENIED;
 Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
 Irp->IoStatus.Information = 0;  //如果请求成功,就是成功的数据;否则为0。
                                 //实际填写的返回FileAllInformation结构的长度值。

 IoCompleteRequest( Irp, IO_NO_INCREMENT );

 KdPrint(("ioctl compelete/r/n"));
 return ntStatus;


}

 

VOID  DriverUnload (IN PDRIVER_OBJECT pDriverObject)
{
 //还原原始派遣函数。
 if (copyDriver_Dispatch!=NULL)
 {
  copy_driver_object->MajorFunction[IRP_MJ_DEVICE_CONTROL] = copyDriver_Dispatch;
 }
}

////初始化设备扩展
//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 );
//}

//驱动入口
NTSTATUS     DriverEntry(IN   PDRIVER_OBJECT   DriverObject, IN   PUNICODE_STRING   RegistryPath )  
{  
 PDEVICE_OBJECT     TargetDeviceObject, myDeviceObject;    
 PDEVICE_OBJECT     attDeviceObject=NULL;
 PDRIVER_OBJECT     HardwareDeviceObject;
 NTSTATUS           status;
 int                i;
 UNICODE_STRING     nameString;
 PFILE_OBJECT       fileObject;
 PC2P_DEV_EXT       devExt;

 //42  53
 RtlInitUnicodeString( &nameString, L"//Device//QCUSB_COM3_1");//这是电信无线网卡的设备,可以换为光驱设备名字

 //在知道名字的情况下,通过IoGetDeviceObjectPointer函数可以得到设备对象指针。
 status = IoGetDeviceObjectPointer(
  &nameString,
  0,
  &fileObject,
  &TargetDeviceObject 
  );

 copy_driver_object=TargetDeviceObject->DriverObject;

 if (status == STATUS_SUCCESS)
  ObDereferenceObject(fileObject);

 //绑定IRP,派遣函数。
 copyDriver_Dispatch = copy_driver_object->MajorFunction[IRP_MJ_DEVICE_CONTROL];
 copy_driver_object->MajorFunction[IRP_MJ_DEVICE_CONTROL]= MyCDROMControl;

 DriverObject->DriverUnload = DriverUnload; //卸载时的回调函数。
 return   STATUS_SUCCESS;  
}