q065700
驱动牛犊
驱动牛犊
  • 注册日期2007-11-09
  • 最后登录2008-05-08
  • 粉丝0
  • 关注0
  • 积分530分
  • 威望54点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
阅读:1362回复:10

谁帮我看一下哪里有问题-----文件的读取。

楼主#
更多 发布于:2007-11-19 16:25
NTSTATUS
SfRead (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PIO_STACK_LOCATION    irpSp = IoGetCurrentIrpStackLocation(Irp);
    PFILE_OBJECT        file_object = irpSp->FileObject;
    PSFILTER_DEVICE_EXTENSION    devExt = DeviceObject->DeviceExtension;
    NTSTATUS            status;
    LARGE_INTEGER        offset;
    ULONG            length;
    void            *buffer;
    PMDL            mdl;

    KEVENT            waitEvent;

//    Irp;DeviceObject;length;offset;status;buffer;mdl

    // 对控制设备的操作,我直接失败  // 这是老牛的原话
    if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
    {
        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        
        return    STATUS_INVALID_DEVICE_REQUEST;
    }
    
    // 对文件系统的其他设备的操作,passthru
    if (devExt->StorageStackDeviceObject == NULL)
    {
        DbgPrint("其他设备对sfread的调用直接PASS\n");
        return    SfPassThrough(DeviceObject, Irp);
    }

    // 到这里说明是对卷的文件操作

//    DbgPrint("关注:设置完成历程!\n");

    // 初始化事件
    KeInitializeEvent(  &waitEvent,
        NotificationEvent,
        FALSE );
    
    // 因为我们要等待完成,所以必须拷贝当前调用栈
    IoCopyCurrentIrpStackLocationToNext ( Irp );
    
    // 设置完成函数,并把事件的指针当上下文传入
    IoSetCompletionRoutine( Irp,
                                                                 SfReadCompletion,
            &waitEvent,     //context parameter
            TRUE,
            TRUE,
            TRUE );
    
    status = IoCallDriver( devExt->AttachedToDeviceObject, Irp );
    
    //
    //  Wait for the operation to complete
    //
    
    if (STATUS_PENDING == status)
    {
        status = KeWaitForSingleObject( &waitEvent,
            Executive,
            KernelMode,
            FALSE,
            NULL );
        ASSERT( STATUS_SUCCESS == status );

        return    STATUS_SUCCESS;
    }

    // 以下代码用来得到读偏移量(从irpSp中)和长度:
    offset.QuadPart = irpSp->Parameters.Read.ByteOffset.QuadPart;
    length = irpSp->Parameters.Read.Length;

//    DbgPrint("end \n");

    switch(irpSp->MinorFunction)
        {
            // 我先保留文件的偏移位置
        case IRP_MN_NORMAL:
                            if (Irp->MdlAddress != NULL)
            {
                          buffer =
                                                                              MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
                                               NormalPagePriority);
            }
            
            else
            {
                buffer = Irp->UserBuffer;
            }

            DbgPrint("输出出:IRP_MN_NORMAL buffer = %s\n", buffer);
            
            // ..........如果有数据,就往buffer中写入...............

            Irp->IoStatus.Information = length;
            Irp->IoStatus.Status = STATUS_SUCCESS;
            Irp->Tail.Overlay.OriginalFileObject->
                                                                              CurrentByteOffset.QuadPart = offset.QuadPart + length;
            
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            
            return    STATUS_SUCCESS;

        case IRP_MN_MDL:

//            DbgPrint("观察:IRP_MN_MDL\n");

            mdl = MyMdlMemoryAllocate(length);
            if (mdl == NULL)
            {
                return    STATUS_SUCCESS;
            }

            Irp->MdlAddress = mdl;

            // ..........如果有数据,就往buffer中写入...............

            Irp->IoStatus.Information = length;
            Irp->IoStatus.Status = STATUS_SUCCESS;
            Irp->Tail.Overlay.OriginalFileObject->
                                                                               CurrentByteOffset.QuadPart = offset.QuadPart + length;
        
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            
            return    STATUS_SUCCESS;

        case IRP_MN_COMPLETE:
            Irp->IoStatus.Information = length;
            Irp->IoStatus.Status = STATUS_SUCCESS;
            Irp->Tail.Overlay.OriginalFileObject->
                                                                               CurrentByteOffset.QuadPart = offset.QuadPart + length;
            
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            
            return    STATUS_SUCCESS;
    
        default:
            break;
        }

    return    STATUS_SUCCESS;
}

这个是驱动小妹给的,不知道怎么让他在debugview中显示出来。迷糊~~~~~~
q065700
驱动牛犊
驱动牛犊
  • 注册日期2007-11-09
  • 最后登录2008-05-08
  • 粉丝0
  • 关注0
  • 积分530分
  • 威望54点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-11-20 08:38
高手大虾们近来看一下吧~~~~~~
alwaysrun
驱动小牛
驱动小牛
  • 注册日期2006-06-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1059分
  • 威望752点
  • 贡献值1点
  • 好评度98点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-11-20 10:06
看不出,顶一下
一颗平常的心!
q065700
驱动牛犊
驱动牛犊
  • 注册日期2007-11-09
  • 最后登录2008-05-08
  • 粉丝0
  • 关注0
  • 积分530分
  • 威望54点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-11-20 10:21
会不会这里没问题,在绑定卷时出的问题?
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
地下室#
发布于:2007-11-20 13:43
Just a quick look and I see BSOD already because some IRPs are completed twice and some IRPs are simply by-passed.
“驱动小妹”
驱动牛犊
驱动牛犊
  • 注册日期2006-09-09
  • 最后登录2007-11-24
  • 粉丝0
  • 关注0
  • 积分770分
  • 威望78点
  • 贡献值0点
  • 好评度77点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-11-20 14:18
你新见一个文本文件,然后往里面写入数据。如“驱动小妹”
然后加载驱动,打开DBGVIEW   打开后, 打开你刚才的文本文件。
在DBGVIEW中,你可以在很多DbgPrint("输出出:IRP_MN_NORMAL buffer = %s\n", buffer);
中看到“驱动小妹”的数据。

也可以在打开文件的状态“保存”文件。 在DBGVIEW中看到文件中的数据。

你试试
q065700
驱动牛犊
驱动牛犊
  • 注册日期2007-11-09
  • 最后登录2008-05-08
  • 粉丝0
  • 关注0
  • 积分530分
  • 威望54点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-11-20 15:09
没有出现输出很多的数据。
“驱动小妹”
驱动牛犊
驱动牛犊
  • 注册日期2006-09-09
  • 最后登录2007-11-24
  • 粉丝0
  • 关注0
  • 积分770分
  • 威望78点
  • 贡献值0点
  • 好评度77点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-11-20 15:49
if (STATUS_PENDING == status)
    {
        status = KeWaitForSingleObject( &waitEvent,
            Executive,
            KernelMode,
            FALSE,
            NULL );
        ASSERT( STATUS_SUCCESS == status );

        return    STATUS_SUCCESS;  // 这句注销掉
    }
“驱动小妹”
驱动牛犊
驱动牛犊
  • 注册日期2006-09-09
  • 最后登录2007-11-24
  • 粉丝0
  • 关注0
  • 积分770分
  • 威望78点
  • 贡献值0点
  • 好评度77点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-11-21 08:39
最好不要在系统启动前加载过滤驱动,因为有DbgPrint("输出出:IRP_MN_NORMAL buffer = %s\n", buffer);可能系统启动不了。

在进入系统之后再去启动程序

因为有大哥说%s\n", buffer可能没结束标志,很可能使系统重起。如果要想系统没关系,
最好把
DbgPrint("输出出:IRP_MN_NORMAL buffer = %s\n", buffer);
注销掉
            
            // ..........如果有数据,就往buffer中写入...............
q065700
驱动牛犊
驱动牛犊
  • 注册日期2007-11-09
  • 最后登录2008-05-08
  • 粉丝0
  • 关注0
  • 积分530分
  • 威望54点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-11-21 09:00
谢谢
weather1123
驱动牛犊
驱动牛犊
  • 注册日期2007-09-12
  • 最后登录2008-07-20
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望7点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-11-28 22:37
为什么我照上面那么弄机子根本跑不起来
游客

返回顶部