на основе примера из ддк сделал фильтр, повесил его как верхний фильтр для класса cdrom и как первый нижний фильтр для устройства cdrom
вот стек который получился:
!DevObj !DrvObj !DevExt ObjectName
1 8338f3f0 \Driver\MYDRV 8338f4a8
832f3780 \Driver\redbook 832f3838
832f3b50 \Driver\Cdrom 832f3c08 CdRom0
832f3020 \Driver\Imapi 832f30d8
2 8338f570 \Driver\MYDRV 8338f628
833cfb58 \Driver\atapi 833cfc10 IdeDeviceP0T0L0-3
стоит задача перехватить и заблокировать запись данных.
я расчитывал перехватить SPTI запрос в точке 1 и SCSI запрос в точке 2
убедительная просьба использовать таги ccode & asm для соотв. кусков кода — модератор
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIo;
NTSTATUS
DispatchIo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
//тут все как в примере ддк
if (DeviceObject != g_ControlDeviceObject)
{
return DispatchPnpIOCTL(DeviceObject, Irp);это мой обработчик
// We will just the request down as we are not interested in handling
// requests that come on the PnP stack.
// return DispatchAny(DeviceObject, Irp);
}
//тут все как в примере ддк
}
NTSTATUS DispatchPnpIOCTL(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PVOID ioBuffer = Irp->AssociatedIrp.SystemBuffer;
ULONG inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
PDEVICE_EXTENSION fidx = (PDEVICE_EXTENSION) fido->DeviceExtension;
if (!UnicodeEqualWstr(&(fidx->className), L"CDROM"))
goto exit;
if (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction)
{
ULONG ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
if (IOCTL_SCSI_PASS_THROUGH == ioControlCode)
{
PCDB pCdb = (PCDB) ((PSCSI_PASS_THROUGH) ioBuffer)->Cdb;
status = ProcessSPTI(pCdb, Irp);
}
else if (IOCTL_SCSI_PASS_THROUGH_DIRECT == ioControlCode)
{
PCDB pCdb = (PCDB) ((PSCSI_PASS_THROUGH_DIRECT) ioBuffer)->Cdb;
status = ProcessSPTI(pCdb, Irp);
}
}
exit:
if (STATUS_ACCESS_DENIED == status)
return status;
return DispatchAny(fido, Irp);
}
NTSTATUS ProcessSPTI(IN PCDB pCdb, IN PIRP Irp)
{
BOOLEAN bAccessAllow = TRUE;
NTSTATUS status = STATUS_SUCCESS;
//здесь контролируем только запись, чтение контролируется в skfsf.sys
if (SCSIOP_WRITE == pCdb->CDB10.OperationCode)
{
bAccessAllow = FALSE;
}
if (!bAccessAllow)
{
Irp->IoStatus.Status = status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
exit:
return status;
}
в ф-ю ProcessSPTI управление попадает, но на строчку bAccessAllow = FALSE; нет
подскажите в чем проблема ? пишу штатной хр-шной писалкой, вроде должно попадать, может pCdb не правильно получаю ?
второй обработчик установлен с помощью
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = DispatchInternalIOCTL;
ф-я DispatchInternalIOCTL вызывается когда надо и исправно отрабатывает след. код
if (SRB_FUNCTION_EXECUTE_SCSI == pSrb->Function)
{
if (SCSIOP_WRITE == pCdb->CDB10.OperationCode)
{
bAccessAllow = FALSE;
}
}
но проблема в том, что отрабатывает он только при запуске на виртуальной машине vmware, а на железной не срабатывает.
подскажите пожалуйста куда копать ?