fatmouse527
驱动牛犊
驱动牛犊
  • 注册日期2006-12-27
  • 最后登录2009-04-10
  • 粉丝1
  • 关注0
  • 积分347分
  • 威望85点
  • 贡献值0点
  • 好评度81点
  • 原创分1分
  • 专家分0分
阅读:1747回复:11

如何绕过自己的驱动,把读、写直接传给下一层呢?我看了sfilter的但不成

楼主#
更多 发布于:2007-02-26 18:14
以下是读或写的代码

NTSTATUS
SfIssueReadWriteIrpSynchronously(
    IN PDEVICE_OBJECT DeviceObject,
    IN PFILE_OBJECT FileObject,
    IN ULONG MajorFunction,
    IN PIO_STATUS_BLOCK IoStatus,
    IN PVOID Buffer,
    IN ULONG Length,
    IN PLARGE_INTEGER ByteOffset,
    IN ULONG IrpFlags
    )
{
    PIRP Irp = NULL;
    PIO_STACK_LOCATION IrpSp = NULL;
    KEVENT Event;
    NTSTATUS Status;

    ASSERT((MajorFunction == IRP_MJ_READ) || (MajorFunction == IRP_MJ_WRITE));
    
    KeInitializeEvent(&Event, NotificationEvent, FALSE);
    //和下一级驱动建立同步的请求(这里是IRP_MJ_READ或IRP_MJ_WRITE)
    Irp = IoBuildSynchronousFsdRequest(
        MajorFunction,
        DeviceObject,
        Buffer,
        Length,
        ByteOffset,
        &Event,
        IoStatus
        );
    if (!Irp)
        return STATUS_INSUFFICIENT_RESOURCES;

    Irp->Flags |= IrpFlags;
    //获得下一级驱动的指针给IrpSp
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->FileObject = FileObject;
    //执行
    Status = IoCallDriver(DeviceObject, Irp);
    if (STATUS_PENDING == Status)
    {
        //等待完成
        KdPrint(("SfIssueReadWriteIrpSynchronously:KeWaitForSingleObject,Event, FALSE"));
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
    }
    KdPrint(("SfIssueReadWriteIrpSynchronously:finisth"));
    return IoStatus->Status;
}



====================

以下是调用的
Status = SfIssueReadWriteIrpSynchronously(
                DevExt->AttachedToDeviceObject,
                FileObject,
                IRP_MJ_READ,
                &IoStatus,    
                EncryptInfo,
                sizeof(ENCRYPT_INFO)-1,
                &ByteOffset,
                0
                );

==========================
我用的是DevExt->AttachedToDeviceObject,但是不知为什么还是不能传下去执行,它还会触发我写的IRP_MJ_READ,IRP_MJ_Write, 这是为什么呢呀?有知道的吗,请告诉我一下,谢谢了先。

最新喜欢:

LeopardLeopar...
驱网无线,快乐无限
fatmouse527
驱动牛犊
驱动牛犊
  • 注册日期2006-12-27
  • 最后登录2009-04-10
  • 粉丝1
  • 关注0
  • 积分347分
  • 威望85点
  • 贡献值0点
  • 好评度81点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2007-02-27 09:42
请大侠不啬赐教呀
驱网无线,快乐无限
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
板凳#
发布于:2007-02-27 10:31
用shadowdevice 或者直接build irp


如果只考虑应用层,可以把kernelmode的访问pass 掉
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
地板#
发布于:2007-02-27 10:39
可以借鉴楚狂人的防重入的方法,创建一个自己的工作线程来完成,
然后在IRP派遣例程中排除和该工作线程有关的所有IRP请求。
人总在矛盾中徘徊。。。
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-02-27 10:48
可能是缓冲读写,所以cc mgr会调用你的DispatchRead/Write进行paging io
fatmouse527
驱动牛犊
驱动牛犊
  • 注册日期2006-12-27
  • 最后登录2009-04-10
  • 粉丝1
  • 关注0
  • 积分347分
  • 威望85点
  • 贡献值0点
  • 好评度81点
  • 原创分1分
  • 专家分0分
5楼#
发布于:2007-02-27 11:51
我自己构建irp往下传也不成,可以读到内容,但还是经过我的irp_mj_read,倒底为什么呀,我要疯了

读的irp代码:
BOOLEAN
MyReadDispatch(PDEVICE_OBJECT DeviceObject,
PFILE_OBJECT FileObject,
PUCHAR FileBuffer,
ULONG FileBufferSize,
PLARGE_INTEGER Offset
)
{
    PIRP irp;
    KEVENT event;
    IO_STATUS_BLOCK IoStatusBlock;
    PIO_STACK_LOCATION irpSp;
    NTSTATUS Status;
    
    //
    // Set up the event we\'ll use.
    //
    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
    
    //
    // Allocate an irp for this request. This could also come from a
    // private pool, for instance.
    //
    irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
    
    if (!irp)
    {
    
        return FALSE;
    }
    
    //
    // Build the IRP\'s main body
    //
    irp->UserEvent = &event;
    irp->UserIosb = &IoStatusBlock;
    irp->Tail.Overlay.Thread = PsGetCurrentThread();
    irp->Tail.Overlay.OriginalFileObject = FileObject;
    irp->RequestorMode = KernelMode;
    irp->Flags = IRP_READ_OPERATION;
    
    //
    // Set up the I/O stack location.
    //
    irpSp = IoGetNextIrpStackLocation(irp);
    irpSp->MajorFunction = IRP_MJ_READ;
    irpSp->MinorFunction = 0;
    irpSp->DeviceObject = DeviceObject;
    irpSp->FileObject = FileObject;
    
    irp->MdlAddress = IoAllocateMdl(
                                                    FileBuffer,
                                                    FileBufferSize,
                                                    FALSE,
                                                    FALSE,
                                                    (PIRP) NULL );
    if (irp->MdlAddress == NULL)
    {
        IoFreeIrp( irp );
        return FALSE;
    }
    
    try
    {
        MmProbeAndLockPages(
                irp->MdlAddress,
                KernelMode,
                (LOCK_OPERATION) (irpSp->MajorFunction == IRP_MJ_READ ? IoWriteAccess : IoReadAccess) );
    }
    except(EXCEPTION_EXECUTE_HANDLER)
    {
        if (irp->MdlAddress != NULL)
        {
            IoFreeMdl( irp->MdlAddress );
        }
        IoFreeIrp( irp );
        return FALSE;
    }
    irp->UserBuffer = FileBuffer;
    
    
    irpSp->Parameters.Read.Length = FileBufferSize;
    irpSp->Parameters.Read.ByteOffset = *Offset;
    
    //
    // Set the completion routine.
    //
    IoSetCompletionRoutine(irp, MyReadCompleted, 0, TRUE, TRUE, TRUE);
    
    //
    // Send it to the FSD
    //
    Status = IoCallDriver(DeviceObject, irp);
    
    //
    // Wait for the I/O
    //
    if(Status == STATUS_PENDING)
    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
        
    return( NT_SUCCESS( IoStatusBlock.Status ));
}


NTSTATUS
MyReadCompleted(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
    //
    // Copy the status information back into the \"user\" IOSB.
    //
    DeviceObject;
    Context;
    *Irp->UserIosb = Irp->IoStatus;
    
    if( !NT_SUCCESS(Irp->IoStatus.Status) ) {
              KdPrint((" ERROR ON IRP: %x\\n", Irp->IoStatus.Status ));
    }
    
    //
    // Set the user event - wakes up the mainline code doing this.
    //
    KeSetEvent(Irp->UserEvent, 0, FALSE);
    
    //清除我们创建的内存变量
    if (Irp->MdlAddress) {
    
        MmUnmapLockedPages(MmGetSystemAddressForMdl(Irp->MdlAddress), Irp->MdlAddress);
        
        MmUnlockPages(Irp->MdlAddress);
        
        IoFreeMdl(Irp->MdlAddress);
        
        Irp->MdlAddress = NULL;

    }

    //
    // Free the IRP now that we are done with it.
    //
    IoFreeIrp(Irp);
    
    return STATUS_MORE_PROCESSING_REQUIRED;
}
========================
调用代码:

PSFILTER_DEVICE_EXTENSION DevExt = (PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
        UCHAR EncryptInfo[3];
        LARGE_INTEGER ByteOffset;
        ByteOffset.QuadPart = 0;
        KdPrint(("SfPostCreateWorker star---------------------------"));
        MyReadDispatch(DevExt->AttachedToDeviceObject,
                                FileObject,
                                EncryptInfo,
                                2,
                                &ByteOffset
                                );
        KdPrint(("SfPostCreateWorker finish---------------------------"));
        if (!NT_SUCCESS(Status) )
        {
            KdPrint(("SfPostCreateWorker: Read Err"));
        }
        else
        {
            KdPrint(("SfPostCreateWorker: Read Context=%x",EncryptInfo[0]));
            KdPrint(("SfPostCreateWorker: Read Context=%x",EncryptInfo[1]));
                KdPrint(("SfPostCreateWorker: Read Success"));
        }
驱网无线,快乐无限
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
6楼#
发布于:2007-02-28 09:57
检查你的CALLSTACK,怀疑你下面的某个家伙存在重入,虽然他自己能避免......
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
fatmouse527
驱动牛犊
驱动牛犊
  • 注册日期2006-12-27
  • 最后登录2009-04-10
  • 粉丝1
  • 关注0
  • 积分347分
  • 威望85点
  • 贡献值0点
  • 好评度81点
  • 原创分1分
  • 专家分0分
7楼#
发布于:2007-02-28 13:27
能告诉我怎么检查CALLSTACK吗?
你说的“重入的那个家伙”是我写的,还是系统自带的?
如果系统自己带的我怎么避过它?
驱网无线,快乐无限
fatmouse527
驱动牛犊
驱动牛犊
  • 注册日期2006-12-27
  • 最后登录2009-04-10
  • 粉丝1
  • 关注0
  • 积分347分
  • 威望85点
  • 贡献值0点
  • 好评度81点
  • 原创分1分
  • 专家分0分
8楼#
发布于:2007-02-28 13:35
谢谢了先,着急呀
驱网无线,快乐无限
driver12345
驱动牛犊
驱动牛犊
  • 注册日期2005-11-15
  • 最后登录2007-10-28
  • 粉丝0
  • 关注0
  • 积分814分
  • 威望84点
  • 贡献值0点
  • 好评度82点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-06-11 11:07
我也见到如此类的问题
我的需求是:在驱动的读调度历程监控到所要的读操作,这时候我在这里用KeWaitForSingleObject无限等待事件到达后在往下层驱动派发,也就是这时候被阻塞了,
这时候我想往这个文件里写点东西,我用ZwCreateFiles是能打开该文件的,但写的时候就被阻塞了,我用sfilter里面的方法也是一样,我没有试直接构建irp的方式
我有疑问就是:为何打开的时候不会被阻塞,而写的时候被阻塞了,他们不都要经过我们的驱动吗?
有大狭能解决此问题吗?
yandong_8212
驱动小牛
驱动小牛
  • 注册日期2006-07-28
  • 最后登录2011-02-11
  • 粉丝0
  • 关注0
  • 积分1046分
  • 威望464点
  • 贡献值1点
  • 好评度173点
  • 原创分0分
  • 专家分1分
10楼#
发布于:2007-06-11 18:41
还是用IoCreateFileSpecifyDeviceObjectHint  吧,现在已经很少有用98的系统的了.即使是2000的,也可以让他装个SP4.防止重入可以考虑线程列表的做法.Zw***,IoCallDriver都可能引起重入.有时候Io***也会.重入最大的问题就是引起死锁,比蓝屏还讨厌!
商务MSN:YanDong_8212@163.com
liyunch
驱动小牛
驱动小牛
  • 注册日期2001-06-28
  • 最后登录2014-09-05
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望134点
  • 贡献值0点
  • 好评度94点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-06-13 09:58
用Shadow Device或IoGet...Hint.
游客

返回顶部