запись на cd - помогите разобраться
От: finder2006  
Дата: 06.06.07 14:17
Оценка:
на основе примера из ддк сделал фильтр, повесил его как верхний фильтр для класса 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, а на железной не срабатывает.
подскажите пожалуйста куда копать ?
Re: запись на cd - помогите разобраться
От: Аноним  
Дата: 06.06.07 14:44
Оценка:
Может пойти другим путем — не блокировать запись, когда она уже начинается, а сделать из CD-RW просто CD-R, чтобы писать нельзя было в принципе?
Re[2]: запись на cd - помогите разобраться
От: finder2006  
Дата: 07.06.07 05:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Может пойти другим путем — не блокировать запись, когда она уже начинается, а сделать из CD-RW просто CD-R, чтобы писать нельзя было в принципе?


а как такое сделать ?
и можно ли это реализовать динамически, т.е. чтобы можно было включать/выключать возможность записи без перезагрузки ?
Re: запись на cd - помогите разобраться
От: Alter_ Украина http://alter.org.ua
Дата: 07.06.07 10:38
Оценка: 2 (1)
Здравствуйте, finder2006, Вы писали:

F>на основе примера из ддк сделал фильтр, повесил его как верхний фильтр для класса cdrom и как первый нижний фильтр для устройства cdrom


F>но проблема в том, что отрабатывает он только при запуске на виртуальной машине vmware, а на железной не срабатывает.

F>подскажите пожалуйста куда копать ?

1. Вы забыли перехватить SCSIOP_WRITE12. Это как раз очень хорошо объясняет разницу VM/RealM
2. SPTI нужно ловить и внизу (в т.2).
--
Alter, http://alter.org.ua
Re[2]: запись на cd - помогите разобраться
От: Alter_ Украина http://alter.org.ua
Дата: 07.06.07 10:55
Оценка:
В догонку:
еще стоит словить
#define SCSIOP_FORMAT_UNIT 0x04
#define SCSIOP_WRITE6 0x0A
#define SCSIOP_WRITE_VERIFY 0x2E
#define SCSIOP_SYNCHRONIZE_CACHE 0x35
#define SCSIOP_SEND_OPC_INFO 0x54
#define SCSIOP_REPAIR_TRACK 0x58
#define SCSIOP_CLOSE_TRACK_SESSION 0x5B
#define SCSIOP_SEND_CUE_SHEET 0x5D
#define SCSIOP_BLANK 0xA1
#define SCSIOP_WRITE12 0xAA
#define SCSIOP_WRITE_VERIFY12 0xAE
#define SCSIOP_SEND_DISK_STRUCTURE 0xBF
--
Alter, http://alter.org.ua
Re[2]: запись на cd - помогите разобраться
От: finder2006  
Дата: 07.06.07 11:44
Оценка:
Здравствуйте, 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 не может ?
Re[3]: запись на cd - помогите разобраться
От: finder2006  
Дата: 07.06.07 14:51
Оценка:
Здравствуйте, finder2006, Вы писали:

A_>>2. SPTI нужно ловить и внизу (в т.2).

F>т.е. в двух местах или если ловлю внизу то вверху можно не ловить ?
F>ведь должна же быть точка миновать которую SPTI не может ?

еще в догонку
имеет ли смысл ловить SPTI, если все равно ловлю SCSI-команды на нижнем фильтре устройства, под imapi ?
Re[4]: запись на cd - помогите разобраться
От: Alter_ Украина http://alter.org.ua
Дата: 07.06.07 23:47
Оценка:
Здравствуйте, 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 его разбирает и очеловечивает.
--
Alter, http://alter.org.ua
Re[5]: запись на cd - помогите разобраться
От: finder2006  
Дата: 08.06.07 05:55
Оценка:
Здравствуйте, Alter_, Вы писали:


F>>имеет ли смысл ловить SPTI, если все равно ловлю SCSI-команды на нижнем фильтре устройства, под imapi ?

A_>Имеет, оно через др. IOCTL идет. А уже scsiport его разбирает и очеловечивает.

а какой драйвер за scsiport отвечает ? atapi ?
Re[6]: запись на cd - помогите разобраться
От: Alter_ Украина http://alter.org.ua
Дата: 08.06.07 08:47
Оценка:
Здравствуйте, 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.

Так что смотрите, какая степень защиты вам нужна
--
Alter, http://alter.org.ua
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.