关于windows下的卷过滤
我使用的原型是寒江独钓下的例子磁盘的虚拟,我现在只想要实现对于E盘的写的拒绝嗯,代码:
#include<ntddk.h>
#include< Ntddvol.h>
PDEVICE_OBJECT DesDev;//要记录的D盘的过滤设备
typedef struct _DevExt
{
WCHAR VolumeLetter;//卷的名字如C或D
PDEVICE_OBJECT FltDev;
PDEVICE_OBJECT LowerDev;
PDEVICE_OBJECT PhyDev;
}DevExt,*PDevExt;
typedef struct _Parameter
{
DevExt ParDexExt;
KEVENT Event;
}Par,*PPar;
//下发请求的分发函数
NTSTATUS Dispatch(PDEVICE_OBJECT Device,PIRP irp)
{
PDevExt lp=(PDevExt)Device->DeviceExtension ;
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(lp->LowerDev ,irp);
}
NTSTATUS DispatchPower(PDEVICE_OBJECT Device,PIRP irp)
{
PDevExt lp=(PDevExt)Device->DeviceExtension ;
PoStartNextPowerIrp(irp);
IoSkipCurrentIrpStackLocation(irp);
return PoCallDriver(lp->LowerDev ,irp);
}
NTSTATUS DispatchReadWrite(PDEVICE_OBJECT Device,PIRP irp)
{
if(DesDev==Device)
{
return STATUS_SUCCESS;
}
else
{
return Dispatch( Device, irp);
}
}
NTSTATUS MyProc(PDEVICE_OBJECT Device,PIRP irp,PVOID Context)
{
PPar lp=(PPar)Device->DeviceExtension ;
NTSTATUS status=STATUS_SUCCESS;
UNICODE_STRING DosName={0};
ASSERT(Context!=NULL);
status=IoVolumeDeviceToDosName(lp->ParDexExt .PhyDev,&DosName);
//将dos名字改为大写
lp->ParDexExt.VolumeLetter =DosName.Buffer [0];
if(DosName.Length >0)
DbgPrint("The Str is: %ws\n",DosName.Buffer );
else
KdPrint(("对不起,没有获得卷的名称"));
_asm
{
int 3;
}
KeSetEvent(&lp->Event ,0,FALSE);
return STATUS_SUCCESS;
}
NTSTATUS DispatchCtrl(PDEVICE_OBJECT Device,PIRP irp)
{
PDevExt lp=(PDevExt)Device->DeviceExtension ;
NTSTATUS status=STATUS_SUCCESS;
PIO_STACK_LOCATION irpsp=IoGetCurrentIrpStackLocation(irp);
PKEVENT Event=NULL;
Event=new KEVENT;
KeInitializeEvent(Event,NotificationEvent,FALSE);
Par nowPar={0};
nowPar.ParDexExt=*lp;
nowPar.Event=*Event;
switch(irpsp->Parameters .DeviceIoControl .IoControlCode )
{
case IOCTL_VOLUME_ONLINE:
{
IoCopyCurrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(irp,MyProc,&nowPar,TRUE,TRUE,TRUE);
status=IoCallDriver(lp->LowerDev ,irp);
KeWaitForSingleObject(&nowPar.Event ,Executive,KernelMode,FALSE,NULL);
delete Event;
return status;
}
default:
break;
}
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(lp->LowerDev ,irp);
}
NTSTATUS DispatchAdd(PDRIVER_OBJECT Driver,PDEVICE_OBJECT Device)
{
NTSTATUS status=STATUS_SUCCESS;
PDevExt lp=NULL;
PDEVICE_OBJECT FltDev=NULL;
PDEVICE_OBJECT LowerDev=NULL;
PDEVICE_OBJECT PhyDev=Device;
status=IoCreateDevice(Driver,sizeof(DevExt),NULL,FILE_DEVICE_DISK,FILE_DEVICE_SECURE_OPEN,FALSE,&FltDev);
if(!NT_SUCCESS(status))
{
goto ERROUT;
}
lp=(PDevExt)FltDev->DeviceExtension ;
//清空过滤设备的扩展
RtlZeroMemory(lp,sizeof(DevExt));
LowerDev=IoAttachDeviceToDeviceStack(FltDev,Device);
if(NULL==LowerDev)
{
status=STATUS_NO_SUCH_DEVICE;
goto ERROUT;
}
FltDev->Flags |=LowerDev->Flags ;
FltDev->Flags &=~DO_DEVICE_INITIALIZING;
//进行初始化设备扩展
lp->FltDev =FltDev;
lp->LowerDev =LowerDev;
lp->PhyDev =Device;
ERROUT:
if(!NT_SUCCESS(status))
{
//如果上面有不成功的地方首先需要接触可能存在的附加
if(NULL!=LowerDev)
{
IoDetachDevice(LowerDev);
lp->LowerDev =NULL;
}
//然后删除可能建立的过滤设备
if(NULL!=FltDev)
{
IoDeleteDevice(FltDev);
lp->FltDev =NULL;
}
}
return status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
ULONG i=0;
for(i=0;i<=IRP_MJ_MAXIMUM_FUNCTION;i++)
{
DriverObject->MajorFunction [i]=Dispatch;
}
DriverObject->MajorFunction [IRP_MJ_POWER]=DispatchPower;
DriverObject->MajorFunction [IRP_MJ_WRITE]=DispatchReadWrite;
DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL]=DispatchCtrl;
DriverObject->DriverExtension ->AddDevice =DispatchAdd;
return STATUS_SUCCESS;
}