hejiaming87
驱动牛犊
驱动牛犊
  • 注册日期2009-07-27
  • 最后登录2010-07-29
  • 粉丝2
  • 关注0
  • 积分15分
  • 威望131点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3210回复:1

为什么我拦截U盘的SCSIOP_WRITE会出现问题 主要是USBSCSIPassThrough()函数的代码

楼主#
更多 发布于:2009-09-13 16:21
#include "filter.h"

ULONG       InstanceCount = 0;

int            flag=1; //这个是应用层控制的


#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, FilterAddDevice)
#pragma alloc_text (PAGE, FilterDispatchPnp)
#pragma alloc_text (PAGE, FilterUnload)
#endif

#ifdef IOCTL_INTERFACE

#ifdef ALLOC_PRAGMA
#pragma alloc_text (PAGE, FilterCreateControlObject)
#pragma alloc_text (PAGE, FilterDeleteControlObject)
#pragma alloc_text (PAGE, FilterDispatchIo)
#endif
FAST_NUTEX ControlMutex;
//ULONG       InstanceCount = 0;
//PDEVICE_OBJECT    ControlDeviceObject;

#endif

PDEVICE_OBJECT    ControlDeviceObject;


NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS    status = STATUS_SUCCESS;
    ULONG        ulIndex;
    PDRIVER_DISPATCH  * dispatch;

    DbgPrint("test:1111111111111111\n");

    DbgPrint("观察:Entry DriverEntry\n");

    UNREFERENCED_PARAMETER (RegistryPath);

    for (ulIndex=0,dispatch=DriverObject->MajorFunction;
                    ulIndex<=IRP_MJ_MAXIMUM_FUNCTION;
                    ulIndex++,dispatch++)
    {
        *dispatch = FilterPass;
    }

    DriverObject->MajorFunction[IRP_MJ_SCSI]=USBSCSIPassThrough;
//    DriverObject->MajorFunction[IRP_MJ_SCSI]=FilterPass;

    DriverObject->MajorFunction[IRP_MJ_PNP] = FilterDispatchPnp;
    DriverObject->DriverUnload = FilterUnload;
    DriverObject->DriverExtension->AddDevice = FilterAddDevice;

#ifdef IOCTL_INTERFACE
//    DriverObject->MajorFunction[IRP_MJ_CREATE]  =
//    DriverObject->MajorFunction[IRP_MJ_CLOSE]   =
//    DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
//    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]
//    = FilterDispatchIo;

//    DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSCSIPassThrough;

    ExInitializeFastMutex(&ControlMutex);
#endif

    return    status;
}

VOID
FilterUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{
    PAGED_CODE();

    ASSERT(DriverObject->DeviceObject == NULL);

    DbgPrint("观察:Entry FilterUnload\n");

    return;
}

NTSTATUS
FilterAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PDEVICE_OBJECT        deviceObject=NULL;
    PDEVICE_EXTENSION    deviceExtension;
    ULONG                deviceType=FILE_DEVICE_DISK;

    UNICODE_STRING      ntName;
    UNICODE_STRING      win32Name;


    RtlInitUnicodeString(&ntName, L"\\Device\\dnmm");
    RtlInitUnicodeString(&win32Name, L"\\DosDevices\\dnmm");

    DbgPrint("观察:Entry FilterAddDevice\n");

    PAGED_CODE();

    if (!IoIsWdmVersionAvailable(1,0x20))
    {
        deviceObject=IoGetAttachedDeviceReference(PhysicalDeviceObject);
        deviceType=deviceObject->DeviceType;
        ObDereferenceObject(deviceObject);
    }

    status=IoCreateDevice(
        DriverObject,
        sizeof (DEVICE_EXTENSION),
        &ntName,
        FILE_DEVICE_DISK,
        FILE_DEVICE_SECURE_OPEN,
        FALSE,
        &deviceObject
        );

    if (!NT_SUCCESS(status))
    {
        return    status;
    }

    deviceExtension=(PDEVICE_EXTENSION)deviceObject->DeviceExtension;

    deviceExtension->NextLowerDriver=IoAttachDeviceToDeviceStack(
                                        deviceObject,
                                        PhysicalDeviceObject);

    if (NULL==deviceExtension->NextLowerDriver)
    {
        DbgPrint("注意了:FilterAddDevice:NULL==deviceExtension->NextLowerDriver\n");
        IoDeleteDevice(deviceObject);
        return    STATUS_UNSUCCESSFUL;
    }

    status = IoCreateSymbolicLink(
                &win32Name,
                &ntName);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("重点啊:IoCreateSymbolicLink(&win32Name, &ntName) 错了的\n");
    }

    deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags&
                            (DO_BUFFERED_IO|DO_DIRECT_IO|DO_POWER_PAGABLE);

//    deviceObject->DeviceType=deviceExtension->NextLowerDriver->DeviceType;
    deviceObject->DeviceType=FILE_DEVICE_DISK;

    deviceObject->Characteristics=deviceExtension->NextLowerDriver->Characteristics;

    deviceExtension->Self=deviceObject;

    IoInitializeRemoveLock(&deviceExtension->RemoveLock,
                            POOL_TAG,1,100);

    INITIALIZE_PNP_STATE(deviceExtension);

    deviceObject->Flags&=~DO_DEVICE_INITIALIZING;


    return    STATUS_SUCCESS;
}

NTSTATUS
FilterDispatchIo(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp )
{
    PIO_STACK_LOCATION    irpStack;
    NTSTATUS            status;
    PCONTROL_DEVICE_EXTENSION    deviceExtension;

    DbgPrint("观察:Entry FilterDispatchIo\n");

    PAGED_CODE();

    if (DeviceObject!=ControlDeviceObject)
    {
        return    FilterPass(DeviceObject,Irp);
    }

    deviceExtension=ControlDeviceObject->DeviceExtension;

    if (!deviceExtension->Deleted)
    {
        status=STATUS_SUCCESS;
        Irp->IoStatus.Information=0;
        irpStack=IoGetCurrentIrpStackLocation(Irp);

        switch(irpStack->MajorFunction)
        {
        case IRP_MJ_CREATE:
            DbgPrint("I am IRP_MJ_CREATE\n");
            break;
        case IRP_MJ_CLOSE:
            DbgPrint("I am IRP_MJ_CLOSE\n");
            break;
        case IRP_MJ_CLEANUP:
            DbgPrint("I am IRP_MJ_CLEANUP\n");
            break;
        case IRP_MJ_DEVICE_CONTROL:
            DbgPrint("I am IRP_MJ_DEVICE_CONTROL\n");
            break;

        default:
            break;
        }
    }

    else
    {
        ASSERTMSG(FALSE, "Requests being sent to a dead device\n");
        status = STATUS_DEVICE_REMOVED;
    }

    Irp->IoStatus.Status=status;
    IoCompleteRequest(Irp,IO_NO_INCREMENT);

    DbgPrint("观察:Entry FilterDispatchIo is over!!!\n");

    return status;

}

NTSTATUS
FilterPass(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PDEVICE_EXTENSION        deviceExtension;
    NTSTATUS                status;
    PIO_STACK_LOCATION        irpStack;
    PVOID                   inputBuffer;
    CHAR                    n;

    DbgPrint("观察:Entry FilterPass!\n");

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    DbgPrint("关键:irpStack->MajorFunction=%d\n",irpStack->MajorFunction);
        
    if (irpStack->MajorFunction==IRP_MJ_DEVICE_CONTROL)
    {
        if (irpStack->Parameters.DeviceIoControl.IoControlCode==IOCTL_800)
        {
            inputBuffer = Irp->AssociatedIrp.SystemBuffer;
            DbgPrint("我得到了IOCTL_800并且inputBuffer=%s\n",inputBuffer);
            
            n=*(CHAR*)inputBuffer;
            n=n-'0';

            if (n==0)
            {
                DbgPrint("flag=0\n");
                flag=0;
            }

            if (n==1)
            {
                DbgPrint("flag=1\n");
                flag=1;
            }
        }
    }
    
    deviceExtension=(PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    status=IoAcquireRemoveLock(&deviceExtension->RemoveLock,Irp);

    if (!NT_SUCCESS(status))
    {
        Irp->IoStatus.Status=status;
        IoCompleteRequest(Irp,IO_NO_INCREMENT);
        return status;
    }
    
    IoSkipCurrentIrpStackLocation(Irp);
    status=IoCallDriver(deviceExtension->NextLowerDriver,Irp);
    IoReleaseRemoveLock(&deviceExtension->RemoveLock,Irp);
    
    return    status;

}

NTSTATUS
FilterDispatchPnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PDEVICE_EXTENSION    deviceExtension;
    PIO_STACK_LOCATION    irpStack;
    NTSTATUS            status;
    KEVENT                event;

    DbgPrint("观察:Entry FilterDispatchPnp.\n");

    PAGED_CODE();

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    status = IoAcquireRemoveLock(&deviceExtension->RemoveLock,Irp);

    if (!NT_SUCCESS(status))
    {
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp,IO_NO_INCREMENT);
        return    status;
    }

    switch(irpStack->MinorFunction)
    {
    case IRP_MN_START_DEVICE:
    
        DbgPrint("观察:IRP_MN_START_DEVICE:\n");

        KeInitializeEvent(&event,NotificationEvent,FALSE);
        IoCopyCurrentIrpStackLocationToNext(Irp);
        IoSetCompletionRoutine(Irp,
                               (PIO_COMPLETION_ROUTINE) FilterStartCompletionRoutine,
                               &event,
                               TRUE,
                               TRUE,
                               TRUE);

        status = IoCallDriver(deviceExtension->NextLowerDriver,Irp);

        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
            status = Irp->IoStatus.Status;
        }

        if (NT_SUCCESS(status))
        {
            SET_NEW_PNP_STATE(deviceExtension,Started);

            if (deviceExtension->NextLowerDriver->Characteristics & FILE_REMOVABLE_MEDIA)
            {
                DeviceObject->Characteristics|=FILE_REMOVABLE_MEDIA;
            }

#ifdef    IOCTL_INTERFACE
            if (Stop != deviceExtension->PreviousPnPState)
            {
                FilterCreateControlObject(DeviceObject);
            }
#endif
        }

        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp,IO_NO_INCREMENT);
        IoReleaseRemoveLock(&deviceExtension->RemoveLock,Irp);

        return    status;

    case IRP_MN_REMOVE_DEVICE:

        DbgPrint("观察:IRP_MN_REMOV_DEVICE:\n");

        IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock,Irp);

        IoSkipCurrentIrpStackLocation(Irp);

        status = IoCallDriver(deviceExtension->NextLowerDriver,Irp);

        SET_NEW_PNP_STATE(deviceExtension,Deleted);

#ifdef    IOCTL_INTERFACE
        FilterDeleteControlObject();
#endif
        IoDetachDevice(deviceExtension->NextLowerDriver);
        IoDeleteDevice(DeviceObject);

        return    status;

    case IRP_MN_QUERY_STOP_DEVICE:

        DbgPrint("观察:IRP_MN_QUERY_STOP_DEVICE:\n");

        SET_NEW_PNP_STATE(deviceExtension,StopPending);
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_CANCEL_STOP_DEVICE:

        DbgPrint("观察:IRP_MN_CANCEL_STOP_DEVICE:\n");

        if (StopPending == deviceExtension->DevicePnPState)
        {
            RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
        }

        status = STATUS_SUCCESS;
        break;

        case IRP_MN_STOP_DEVICE:
        SET_NEW_PNP_STATE(deviceExtension, Stopped);
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_QUERY_REMOVE_DEVICE:

        DbgPrint("观察:IRP_MN_QUERY_REMOVE_DEVICE:\n");

        SET_NEW_PNP_STATE(deviceExtension, RemovePending);
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_SURPRISE_REMOVAL:

        DbgPrint("观察:IRP_MN_SURPRISE_REMOVAL:\n");

        SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending);
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_CANCEL_REMOVE_DEVICE:

        DbgPrint("观察:IRP_MN_CANCEL_REMOVE_DEVICE:\n");

        if(RemovePending == deviceExtension->DevicePnPState)
        {
            RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
        }

        status = STATUS_SUCCESS; // We must not fail this IRP.
        break;

    case IRP_MN_DEVICE_USAGE_NOTIFICATION:

        DbgPrint("观察:IRP_MN_DEVICE_USAGE_NOTIFICATION:\n");

        if ((DeviceObject->AttachedDevice == NULL) ||
            (DeviceObject->AttachedDevice->Flags & DO_POWER_PAGABLE)) {

            DeviceObject->Flags |= DO_POWER_PAGABLE;
        }

        IoCopyCurrentIrpStackLocationToNext(Irp);

        IoSetCompletionRoutine(
            Irp,
            FilterDeviceUsageNotificationCompletionRoutine,
            NULL,
            TRUE,
            TRUE,
            TRUE
            );

        return IoCallDriver(deviceExtension->NextLowerDriver, Irp);

    default:

        DbgPrint("观察:default:\n");

        status = Irp->IoStatus.Status;

        break;
    }
    
    Irp->IoStatus.Status = status;
    IoSkipCurrentIrpStackLocation(Irp);
    status = IoCallDriver(deviceExtension->NextLowerDriver,Irp);
    IoReleaseRemoveLock(&deviceExtension->RemoveLock,Irp);

    return    status;
}

NTSTATUS
FilterStartCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp, IN PVOID Context
    )
{
    PKEVENT        event = (PKEVENT)Context;

    DbgPrint("观察:Entry FilterStartCompletionRoutine!\n");

    UNREFERENCED_PARAMETER(DeviceObject);

    if (Irp->PendingReturned == TRUE)
    {
        KeSetEvent(event,IO_NO_INCREMENT,FALSE);
    }

    return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS
FilterCreateControlObject(                          //这个一般不会出现
    IN PDEVICE_OBJECT DeviceObject
    )
{
    UNICODE_STRING        ntDeviceName;
    UNICODE_STRING        symbolicLinkName;
    PCONTROL_DEVICE_EXTENSION    deviceExtension;
    NTSTATUS    status = STATUS_UNSUCCESSFUL;
    UNICODE_STRING    sddlString;

    DbgPrint("观察:Entry FilterCreateControlObject!\n");

    PAGED_CODE();

//    ExAcquireFastMutexUnsafe(&ControlMutex);

    if (1 == ++InstanceCount)
    {
        RtlInitUnicodeString(&ntDeviceName, NTDEVICE_NAME_STRING);
        RtlInitUnicodeString(&symbolicLinkName, SYMBOLIC_NAME_STRING);

        RtlInitUnicodeString( &sddlString, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)");
/*    
        status = IoCreateDeviceSecure(
                    DeviceObject->DriverObject,
                    sizeof(CONTROL_DEVICE_EXTENSION),
                    &ntDeviceName,
                    FILE_DEVICE_UNKNOWN,
                    FILE_DEVICE_SECURE_OPEN,
                    FALSE,
                    &sddlString,
                    (LPCGUID)&GUID_SD_FILTER_CONTROL_OBJECT,
                    &ControlDeviceObject
                    );
*/
        if (NT_SUCCESS(status))
        {
            ControlDeviceObject->Flags |= DO_BUFFERED_IO;

            status = IoCreateSymbolicLink(&symbolicLinkName,&ntDeviceName);
        
            if ( !NT_SUCCESS( status ))
            {
                IoDeleteDevice(ControlDeviceObject);
                DbgPrint("IoCreateSymbolicLink failed %x\n", status);
                goto End;
            }
        
            deviceExtension = ControlDeviceObject->DeviceExtension;
            deviceExtension->ControlData = NULL;
            deviceExtension->Deleted = FALSE;

            ControlDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
        }

        else
        {
            DbgPrint("IoCreateDevice failed %x\n", status);
        }
    }

End:
    
 //   ExReleaseFastMutexUnsafe(&ControlMutex);
    return status;
}

VOID
FilterDeleteControlObject(
)
{
    UNICODE_STRING      symbolicLinkName;
    PCONTROL_DEVICE_EXTENSION   deviceExtension;

    PAGED_CODE();

    DbgPrint("观察:Entry FilterDeleteControlObject!\n");

//    ExAcquireFastMutexUnsafe (&ControlMutex);

    if(!(--InstanceCount) && ControlDeviceObject)
    {
        RtlInitUnicodeString(&symbolicLinkName, SYMBOLIC_NAME_STRING);
        deviceExtension = ControlDeviceObject->DeviceExtension;
        deviceExtension->Deleted = TRUE;
        IoDeleteSymbolicLink(&symbolicLinkName);
        IoDeleteDevice(ControlDeviceObject);
        ControlDeviceObject = NULL;
    }

//    ExReleaseFastMutexUnsafe (&ControlMutex);

}


NTSTATUS
FilterDeviceUsageNotificationCompletionRoutine(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
{
    PDEVICE_EXTENSION       deviceExtension;

    DbgPrint("观察:Entry FilterDeviceUsageNotificationCompletionRoutine!\n");

    UNREFERENCED_PARAMETER(Context);

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    if (Irp->PendingReturned)
    {
        IoMarkIrpPending(Irp);
    }

    if (!(deviceExtension->NextLowerDriver->Flags & DO_POWER_PAGABLE))
    {
        DeviceObject->Flags &= ~DO_POWER_PAGABLE;
    }

    IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);

    return STATUS_CONTINUE_COMPLETION;
}

NTSTATUS
USBSCSIPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    PDEVICE_EXTENSION        deviceExtension;
    NTSTATUS                status;
    PIO_STACK_LOCATION        irpStack;

    PSCSI_REQUEST_BLOCK        CurSrb;
    PMODE_PARAMETER_HEADER    modeData;
    PDEVICE_OBJECT            pDeviceObject;

    PCDB    cdb ;
    UCHAR    opCode;
    KIRQL   IrqLevel;

    PDEVICE_EXTENSION StorExtension = ( PDEVICE_EXTENSION )
                                   DeviceObject->DeviceExtension;

    IoAcquireRemoveLock(&StorExtension->RemoveLock,Irp);

    DbgPrint("观察:USBSCSICompletion\n");

    irpStack = IoGetCurrentIrpStackLocation( Irp );

    CurSrb = ExAllocatePoolWithTag(NonPagedPool,
                                sizeof(SCSI_REQUEST_BLOCK),
                                DISK_TAG_SRB);
    if (CurSrb == NULL)
    {
        DbgPrint("观察:CurSrb==NULL\n");
    }
    else
    {
        DbgPrint("观察:CurSrb!=NULL\n");
    }

    RtlZeroMemory(CurSrb, SCSI_REQUEST_BLOCK_SIZE);

    if (irpStack->MajorFunction==IRP_MJ_INTERNAL_DEVICE_CONTROL)
    {
        DbgPrint("注意:我终于得到了IRP_MJ_INTERNAL_DEVICE_CONTROL\n");
        
        CurSrb=irpStack->Parameters.Scsi.Srb;
        cdb = (PCDB)CurSrb->Cdb;
        opCode=cdb->CDB6GENERIC.OperationCode;

        if (opCode==SCSIOP_WRITE)
        {
            IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp);
            DbgPrint("关键:opCode==SCSIOP_WRITE\n");
            Irp->IoStatus.Status=STATUS_UNSUCCESSFUL;
            Irp->Iostatus.Information=.........;   //这里的操作字符有点忘记了
            Irp->Irpcomplete(IRP,...);             //这里的操作字符有点忘记了
            return Irp->IoStatus.Status;
        }

    }

    IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp);

    IoAcquireRemoveLock(&StorExtension->RemoveLock,Irp);
    IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp);

    IoSkip...Location(Irp);
    return IoCall...(...);
}


wei
tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
沙发#
发布于:2009-09-19 14:06
首先
一个irp被complete了以后就不能再引用了

if (opCode==SCSIOP_WRITE)
        {
            IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp);
            DbgPrint("关键:opCode==SCSIOP_WRITE\n");
            Irp->IoStatus.Status=STATUS_UNSUCCESSFUL;
            Irp->Iostatus.Information=.........;   //这里的操作字符有点忘记了
            Irp->Irpcomplete(IRP,...);             //这里的操作字符有点忘记了
            return Irp->IoStatus.Status;
        }

这个地方的return是不能引用这个已经complete了的irp的

然后
scsi的complete不是irp的complete.这样设置一个status设置一个info就行的
中间涉及到srb的数个field的设置
SrbStatus,ScsiStatus,还可能需要做auto sense
建议先读一读scsi的规范
游客

返回顶部