запись на 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, а на железной не срабатывает.
подскажите пожалуйста куда копать ?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.