#include "MyFilter.h"
#include <srb.h>
#include <scsi.h>
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo);
VOID DriverUnload(IN PDRIVER_OBJECT fido);
NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp);
NTSTATUS DispatchWmi(IN PDEVICE_OBJECT fido, IN PIRP Irp);
ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo);
NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx);
NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx);
/******************************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)//驱动程序入口函数
{
KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n", DriverObject));
DriverObject->DriverUnload = DriverUnload;//注册设备卸载例程
DriverObject->DriverExtension->AddDevice = AddDevice;//注册增加设备例程
for (int i = 0; i < arraysize(DriverObject->MajorFunction); ++i)
DriverObject->MajorFunction[i] = DispatchAny;//注册一般irp的回调函数
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;//注册IRP_MJ_POWER的回调函数
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;//注册IRP_MJ_PNP的回调函数
DriverObject->MajorFunction[IRP_MJ_SCSI] = DispatchForSCSI;//注册IRP_MJ_SCSI的回调函数
return STATUS_SUCCESS;
}
/******************************************************************************************/
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
{
PAGED_CODE();
NTSTATUS status;
PDEVICE_OBJECT fido;
status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL,
GetDeviceTypeToUse(pdo), 0, FALSE, &fido);//创建驱动对象DriverObject对应的设备对象fido,fido为输出参数
if (!NT_SUCCESS(status))//创建失败
{
KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
return status;
}
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;//获得fido的设备扩展对象
IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0);//初始化fido的自旋锁
pdx->DeviceObject = fido;//设置pdx从属于的设备对象为fido
pdx->Pdo = pdo;
PDEVICE_OBJECT dev = IoAttachDeviceToDeviceStack(fido, pdo);//将过滤驱动fido附加在底层驱动pdo之上,返回fido的下层对象
if (!dev)//添加fido到设备栈失败
{
KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
status = STATUS_DEVICE_REMOVED;
}
else
{
pdx->LowerDeviceObject = dev;//记录下层设备对象
fido->Flags |= dev->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE);//由于不知道底层驱动是直接IO还是BufferIO,因此将标志都置上
fido->Flags &= ~DO_DEVICE_INITIALIZING;//清除initializing标志,开始接收irp
}
if (!NT_SUCCESS(status))//添加fido到设备栈失败
{
if (pdx->LowerDeviceObject)//如果fido在设备栈中不是最底层的设备对象
IoDetachDevice(pdx->LowerDeviceObject);//将fido从设备栈中删除
IoDeleteDevice(fido);//删除fido
}
return status;
}
/******************************************************************************************/
#pragma PAGEDCODE
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
PAGED_CODE();
KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX\n", DriverObject));
}
/******************************************************************************************/
#pragma LOCKEDCODE
NTSTATUS DispatchForSCSI(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{
KdPrint((DRIVERNAME " - Enter DispatchForSCSI \n"));
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;//获得设备扩展对象
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);//获得本层设备对象对应的io堆栈
NTSTATUS status;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);//获得自旋锁,开始同步
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
IoCopyCurrentIrpStackLocationToNext(Irp);//将当前io堆栈复制到下层io堆栈
IoSetCompletionRoutine( Irp,
USBSCSICompletion,//设置完成irp请求时的回调函数为USBSCSICompletion
NULL,
TRUE,
TRUE,
TRUE );
status = IoCallDriver(pdx->LowerDeviceObject, Irp);//调用下层设备对象的驱动程序处理此irp
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);//释放自旋锁,结束同步
return status;
}
/******************************************************************************************/
#pragma LOCKEDCODE
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info)
{
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);//结束irp请求
return status;
}
NTSTATUS USBSCSICompletion( IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context )
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;//获得设备扩展对象
IoAcquireRemoveLock(&pdx->RemoveLock,Irp);//获得自旋锁
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);//获得本层设备对象对应的io堆栈
PSCSI_REQUEST_BLOCK CurSrb=irpStack->Parameters.Scsi.Srb;//得到irp中的scsi请求块
PCDB cdb = (PCDB)CurSrb->Cdb;
UCHAR opCode=cdb->CDB6GENERIC.OperationCode;//得到scsi的操作码
if(opCode==SCSIOP_MODE_SENSE && CurSrb->DataBuffer
&& CurSrb->DataTransferLength >= sizeof(MODE_PARAMETER_HEADER))//如果操作码为SCSIOP_MODE_SENSE,即scsi总线检测到u盘
{
KdPrint(("SCSIOP_MODE_SENSE comming!\n"));
PMODE_PARAMETER_HEADER modeData = (PMODE_PARAMETER_HEADER)CurSrb->DataBuffer;
modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;//设置写保护,达到只读功能
}
if ( Irp->PendingReturned )//如果irp的pending位为true,即异步调用下层驱动时请求未完成
{
IoMarkIrpPending( Irp );//将irp的pending状态从设备栈向上传播
}
IoReleaseRemoveLock(&pdx->RemoveLock,Irp);//释放自旋锁
return Irp->IoStatus.Status ;
}
/******************************************************************************************/
#pragma LOCKEDCODE
NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;//获得设备扩展对象
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获得本层对象对应的io堆栈
NTSTATUS status;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);//获得自旋锁,开始同步
if (!NT_SUCCESS(status))//获得失败
return CompleteRequest(Irp,status,0);//结束本次irp请求
IoSkipCurrentIrpStackLocation(Irp);//因为对irp不做任何处理,所以跳过本层io堆栈,让下层驱动继续处理此irp
status = IoCallDriver(pdx->LowerDeviceObject,Irp);//调用下层设备对象的驱动程序处理此irp
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);//释放自旋锁,结束同步
return status;
}
/******************************************************************************************/
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
PoStartNextPowerIrp(Irp);//每个处理IRP_MJ_POWER请求必须完成的操作,告诉系统的电源管理器驱动可以处理下一个power irp请求
NTSTATUS status;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);//获得自旋锁,开始同步
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
IoSkipCurrentIrpStackLocation(Irp);//因为对irp不做任何处理,所以跳过本层io堆栈,让下层驱动继续处理此irp
status = PoCallDriver(pdx->LowerDeviceObject, Irp);//把这个power irp请求传递给下层驱动
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);//释放自旋锁,结束同步
return status;
}
/******************************************************************************************/
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获得本层对象对应的io堆栈
ULONG fcn = stack->MinorFunction;//pnp为irp的主操作码,获得pnp的子操作码