стоит задача перехватить и заблокировать запись данных.
я расчитывал перехватить 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.sysif (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, а на железной не срабатывает.
подскажите пожалуйста куда копать ?
Re: запись на cd - помогите разобраться
От:
Аноним
Дата:
06.06.07 14:44
Оценка:
Может пойти другим путем — не блокировать запись, когда она уже начинается, а сделать из CD-RW просто CD-R, чтобы писать нельзя было в принципе?
Здравствуйте, Аноним, Вы писали:
А>Может пойти другим путем — не блокировать запись, когда она уже начинается, а сделать из CD-RW просто CD-R, чтобы писать нельзя было в принципе?
а как такое сделать ?
и можно ли это реализовать динамически, т.е. чтобы можно было включать/выключать возможность записи без перезагрузки ?
Здравствуйте, finder2006, Вы писали:
F>на основе примера из ддк сделал фильтр, повесил его как верхний фильтр для класса cdrom и как первый нижний фильтр для устройства cdrom
F>но проблема в том, что отрабатывает он только при запуске на виртуальной машине vmware, а на железной не срабатывает. F>подскажите пожалуйста куда копать ?
1. Вы забыли перехватить SCSIOP_WRITE12. Это как раз очень хорошо объясняет разницу VM/RealM
2. SPTI нужно ловить и внизу (в т.2).
Здравствуйте, Alter_, Вы писали:
A_>Здравствуйте, finder2006, Вы писали:
F>>на основе примера из ддк сделал фильтр, повесил его как верхний фильтр для класса cdrom и как первый нижний фильтр для устройства cdrom
F>>но проблема в том, что отрабатывает он только при запуске на виртуальной машине vmware, а на железной не срабатывает. F>>подскажите пожалуйста куда копать ?
A_>1. Вы забыли перехватить SCSIOP_WRITE12. Это как раз очень хорошо объясняет разницу VM/RealM
спасибо
а можно подробнее про разницу VM/RealM ?
и еще если вы в курсе — почему SCSIOP_WRITE12 нет в scsi.h ?
A_>2. SPTI нужно ловить и внизу (в т.2).
т.е. в двух местах или если ловлю внизу то вверху можно не ловить ?
ведь должна же быть точка миновать которую SPTI не может ?
Здравствуйте, finder2006, Вы писали:
A_>>2. SPTI нужно ловить и внизу (в т.2). F>т.е. в двух местах или если ловлю внизу то вверху можно не ловить ? F>ведь должна же быть точка миновать которую SPTI не может ?
еще в догонку
имеет ли смысл ловить SPTI, если все равно ловлю SCSI-команды на нижнем фильтре устройства, под imapi ?
Здравствуйте, finder2006, Вы писали:
A_>>>2. SPTI нужно ловить и внизу (в т.2). F>>т.е. в двух местах или если ловлю внизу то вверху можно не ловить ? F>>ведь должна же быть точка миновать которую SPTI не может ?
SPTI в нижней точке ловить.
F>>а можно подробнее про разницу VM/RealM ?
Просто разные устройства реализуют/поддерживают разные варианты команд. Некоторые — оба.
Вот в вашем случае реальное устройство умеет WRITE12 и imapi об этом как-то узнало. А в VM — видимо только WRITE10.
F>>и еще если вы в курсе — почему SCSIOP_WRITE12 нет в scsi.h
А в scsi.h много чего нет... Давно его делали
F>имеет ли смысл ловить SPTI, если все равно ловлю SCSI-команды на нижнем фильтре устройства, под imapi ?
Имеет, оно через др. IOCTL идет. А уже scsiport его разбирает и очеловечивает.
F>>имеет ли смысл ловить SPTI, если все равно ловлю SCSI-команды на нижнем фильтре устройства, под imapi ? A_>Имеет, оно через др. IOCTL идет. А уже scsiport его разбирает и очеловечивает.
Здравствуйте, finder2006, Вы писали:
F>>>имеет ли смысл ловить SPTI, если все равно ловлю SCSI-команды на нижнем фильтре устройства, под imapi ? A_>>Имеет, оно через др. IOCTL идет. А уже scsiport его разбирает и очеловечивает.
F>а какой драйвер за scsiport отвечает ? atapi ?
В NT4 был scsiport (общий), а atapi — miniport к нему (как и все остальные ide и scsi драйвера)
В 2000 сделали для ATA отдельный порт-драйвер PciIde/PciIdex и насколько я понимаю — atapi является миникопрот к кому-то из них.
А еще позже сделали подобную штуку для mass-storage/raid (как зовут — не помню).
Но в любом случае могут существовать в природе драйвера, которые полностью самостоятельно делают всю работу, без port-драйвера.
Т.е. если вы хотите отловить совсем-совсен внизу и исключить возможность прямой передачи команд через драйвер контроллера (минуя cdrom и компанию) —
вам нужно вешаться на bus-driver'а IDE/SCSI/RAID и там все отлавливать.
Но тогда есть еще возможность для совсем хитрых утилит — работать напрямую с устройством через порты контроллера. А совсем хитрые могут это делать еще и не через READ_PORT_XXX/WRITE_PORT_XXX, а просто через IN/OUT.