shakesky
驱动牛犊
驱动牛犊
  • 注册日期2006-03-16
  • 最后登录2011-06-25
  • 粉丝0
  • 关注0
  • 积分581分
  • 威望69点
  • 贡献值0点
  • 好评度58点
  • 原创分0分
  • 专家分0分
阅读:3849回复:28

求教:如何在create中利用file_object读取打开的文件的内容

楼主#
更多 发布于:2007-07-10 15:00
如何在create中利用file_object读取打开的文件的内容,用IoBuildSynchronousFsdRequest可行否?我要读取文件头部,来判断是否是加密过的文件,哪位给段代码呀,谢谢!
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-07-10 15:15
我也在做这一部分啊
我也需要
顶上去
shakesky
驱动牛犊
驱动牛犊
  • 注册日期2006-03-16
  • 最后登录2011-06-25
  • 粉丝0
  • 关注0
  • 积分581分
  • 威望69点
  • 贡献值0点
  • 好评度58点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-07-10 16:46
自己顶一个
shakesky
驱动牛犊
驱动牛犊
  • 注册日期2006-03-16
  • 最后登录2011-06-25
  • 粉丝0
  • 关注0
  • 积分581分
  • 威望69点
  • 贡献值0点
  • 好评度58点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-07-10 22:33
linuxyf
驱动小牛
驱动小牛
  • 注册日期2007-04-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望162点
  • 贡献值0点
  • 好评度161点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2007-07-11 08:18
关注,一涉及到关键问题,高手们都沉默了。
在孤独和无助中缓慢前行...
shakesky
驱动牛犊
驱动牛犊
  • 注册日期2006-03-16
  • 最后登录2011-06-25
  • 粉丝0
  • 关注0
  • 积分581分
  • 威望69点
  • 贡献值0点
  • 好评度58点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-07-11 09:44
引用第4楼linuxyf于2007-07-11 08:18发表的  :
关注,一涉及到关键问题,高手们都沉默了。

不会把,这也算是关键问题?
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-07-11 19:42
我贴出我的代码,大家一起研究看看,有问题啊,现在。。。



#define        MARKSTRING        "waintech20070708"
#define        MARKLEN            16


extern PWIT_THREAD pmythread;

static NTSTATUS MyIrpComplete (
                               PDEVICE_OBJECT dev,
                               PIRP irp,
                               PVOID context);
                              
// 在create中调用
NTSTATUS
SpyBuildMyRWIrp(
                IN PDEVICE_OBJECT olddev,
                IN PIRP oldirp
                )
{
    PIRP                irp;

    PVOID                Buffer = NULL;
    ULONG                Length = MARKLEN;
    LARGE_INTEGER          offset;
    CHAR                RWFlag = 1;
    MY_READ_CONTEXT        my_context;
    NTSTATUS            Status = STATUS_SUCCESS;
    
    PFILE_OBJECT            pFileObject;
    PIO_STACK_LOCATION        irpsp;
    
    pFileObject = IoGetCurrentIrpStackLocation(oldirp)->FileObject;
    
    
    Buffer = ExAllocatePoolWithTag(NonPagedPool, 4096, FILESPY_POOL_TAG);
    if(Buffer == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    //RtlCopyMemory( Buffer, MARKSTRING, MARKLEN);
    offset.QuadPart = 0;
    if(RWFlag)
        irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ,olddev,Buffer,Length,&offset,NULL);
    else
        irp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE,olddev,Buffer,Length,&offset,NULL);
    if(irp == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    irp->Flags = IRP_NOCACHE | IRP_READ_OPERATION;
    irp->Tail.Overlay.Thread = oldirp->Tail.Overlay.Thread;
    irp->Tail.Overlay.OriginalFileObject = pFileObject;
    irp->RequestorMode = KernelMode;
    irp->Flags = 0x43;    //
    irpsp = IoGetNextIrpStackLocation(irp);
    irpsp->FileObject = pFileObject;// We need a FileObject to identify the file we are reading
    irpsp->FileObject->CurrentByteOffset = offset;
    irpsp->DeviceObject = olddev;
    
    KeInitializeEvent(&my_context.event,NotificationEvent,FALSE);
    IoSetCompletionRoutine(irp,MyIrpComplete,&my_context,TRUE,TRUE,TRUE);
    //Buffer是缓冲。在Irp中被用做UserBuffer接收数据。offset是 这次读的偏移量。以上代码构造一个读irp.请注意,此时您还没有设置FileObject.实际上我是这样发出请求的:
        
    WITDoItInThread(pmythread,  "11111111111111111111111111111", do_something);
    // 关键:  FileObject是否只需要设置此元素???如果我的加密标识放在文件尾部,我怎么得倒尾部的offset呢???
    Status = IoCallDriver(olddev,irp);
    WITDoItInThread(pmythread,  "xxxxxxxxxxxxxxxxxxxxx", do_something);
    //irp = NULL;
    return STATUS_SUCCESS;
    if(Status == STATUS_PENDING) {
        WITDoItInThread(pmythread,  "aaaaaaaaaaaaaaaaaaaaaa", do_something);
        KeWaitForSingleObject(&my_context.event,Executive,KernelMode,FALSE,NULL);
        WITDoItInThread(pmythread,  "bbbbbbbbbbbbbbbbbbbbbbbbb", do_something);
    }
    {
        ANSI_STRING            tempstr;
        RtlInitAnsiString( &tempstr, "waintech20070708" );
        
        //WITDoItInThread(pmythread,  "ccccccccccccccccccccccccccccc", do_something);
        WITDoItInThread(pmythread,  Buffer, do_something);
        if(!RtlCompareMemory(MARKSTRING , &tempstr, MARKLEN))
        {
            //KdPrint(("spy! SpyBuildMyRWIrp jjjjjjjjjjjjjjjjjjjjjjjjj: %s", Buffer));
            WITDoItInThread(pmythread,  Buffer, do_something);
        }
    }
    //IoCompleteRequest( irp, IO_NO_INCREMENT );
    ExFreePoolWithTag(Buffer, FILESPY_POOL_TAG);
    return STATUS_SUCCESS;

}

// 再看看MyIrpComplete如何收场:
// 一个通用的irp完成函数:
static NTSTATUS MyIrpComplete (
                               PDEVICE_OBJECT dev,
                               PIRP irp,
                               PVOID context)
{
    PFILESPY_DEVICE_EXTENSION DevExt = (PFILESPY_DEVICE_EXTENSION) dev->DeviceExtension;
    PMY_READ_CONTEXT my_context = (PMY_READ_CONTEXT)context;
    KeSetEvent(&my_context->event,IO_NO_INCREMENT,FALSE);
    my_context->Information = irp->IoStatus.Information;
    my_context->Status = irp->IoStatus.Status;
    // 释放irp,过程非常复杂
    WITDoItInThread(pmythread,  "eeeeeeeeeeeeeeeeeee", do_something);
    if (irp->MdlAddress)
    {
        MmUnmapLockedPages(
            MmGetSystemAddressForMdl(irp->MdlAddress),
            irp->MdlAddress);
        MmUnlockPages(irp->MdlAddress);
        IoFreeMdl(irp->MdlAddress);
    }
    WITDoItInThread(pmythread,  "fffffffffffffffffff", do_something);
    IoFreeIrp(irp);    
    WITDoItInThread(pmythread,  "ggggggggggggggggggg", do_something);
    // 返回处理未结束.???
    return STATUS_MORE_PROCESSING_REQUIRED;
}

WITDoItInThread函数该成kdprint即可测试。
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-07-11 19:45
在调用IoCallDriver开始,出现黑屏或兰屏,我调试了N次了,无奈啊。。。
shakesky
驱动牛犊
驱动牛犊
  • 注册日期2006-03-16
  • 最后登录2011-06-25
  • 粉丝0
  • 关注0
  • 积分581分
  • 威望69点
  • 贡献值0点
  • 好评度58点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-07-11 21:38
引用第7楼wengzuhong于2007-07-11 19:45发表的  :
在调用IoCallDriver开始,出现黑屏或兰屏,我调试了N次了,无奈啊。。。

错误是啥?
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
9楼#
发布于:2007-07-12 04:50
FileObject in IRP has not  been fully constructed in MJ_CREATE dispatch routine. You cannot use it for read.
shakesky
驱动牛犊
驱动牛犊
  • 注册日期2006-03-16
  • 最后登录2011-06-25
  • 粉丝0
  • 关注0
  • 积分581分
  • 威望69点
  • 贡献值0点
  • 好评度58点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-07-12 09:40
引用第9楼michaelgz于2007-07-12 04:50发表的  :
FileObject in IRP has not  been fully constructed in MJ_CREATE dispatch routine. You cannot use it for read.

那该啥时候读,如何读?
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-07-12 10:21
错误: 我就没抓到错误,只出现黑屏,直接重启,我还想问,我的softice为什么没抓到信息,是不是少了什么设置?   而且系统也没有dump,郁闷。
shakesky
驱动牛犊
驱动牛犊
  • 注册日期2006-03-16
  • 最后登录2011-06-25
  • 粉丝0
  • 关注0
  • 积分581分
  • 威望69点
  • 贡献值0点
  • 好评度58点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-07-12 23:00
我用windbg,
shakesky
驱动牛犊
驱动牛犊
  • 注册日期2006-03-16
  • 最后登录2011-06-25
  • 粉丝0
  • 关注0
  • 积分581分
  • 威望69点
  • 贡献值0点
  • 好评度58点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2007-07-12 23:00
我用windbg,
fantasyemperor
驱动牛犊
驱动牛犊
  • 注册日期2007-04-24
  • 最后登录2008-02-18
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2007-07-13 09:12
我也有段代码,可是读出来的数据总是一样是0x4e9052eb 20534654
NTSTATUS
MakeAsynchronousRequest (
                         PDEVICE_OBJECT   TopOfDeviceStack,
                         PVOID               ReadBuffer,
                         ULONG               NumBytes
                         )
                         /*++
                         Arguments:

                         TopOfDeviceStack -

                         WriteBuffer       - Buffer to be sent to the TopOfDeviceStack.

                         NumBytes  - Size of buffer to be sent to the TopOfDeviceStack.

                         --*/
{
    NTSTATUS        status;
    PIRP            irp;
    LARGE_INTEGER   startingOffset;
    PIO_STACK_LOCATION  nextStack;
    PVOID context;
    IO_STATUS_BLOCK  IoStatusBlock;
    KEVENT          event;
    MY_READ_CONTEXT    myReadContext;

    startingOffset.QuadPart = (LONGLONG) 0;


    irp = IoAllocateIrp( TopOfDeviceStack->StackSize, TRUE );
    if (NULL == irp) {

        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Obtain a pointer to the stack location of the first driver that will be
    // invoked.  This is where the function codes and the parameters are set.
    //
 //   irp->Flags=IRP_BUFFERED_IO;
    //irp->AssociatedIrp.SystemBuffer = ReadBuffer;
    //irp->MdlAddress = NULL;
    //nextStack = IoGetNextIrpStackLocation( irp );
    //nextStack->MajorFunction = IRP_MJ_READ;
    //nextStack->Parameters.Read.Length = NumBytes;
    //nextStack->Parameters.Read.ByteOffset= startingOffset;
    irp = IoBuildAsynchronousFsdRequest(
        IRP_MJ_READ,
        TopOfDeviceStack,
        ReadBuffer,
        NumBytes,
        &startingOffset, // Optional
        &IoStatusBlock
        );


    //DbgPrint("%X",IoStatusBlock.Status);
    //DbgPrint("%X",IoStatusBlock.Information);
    //if (NULL == irp) {

    //    return STATUS_INSUFFICIENT_RESOURCES;
    //}    
    //
    // Allocate memory for context structure to be passed to the completion routine.
    //
    //myReadContext.context = ExAllocatePoolWithTag(NonPagedPool, sizeof(ULONG_PTR), 'ITag');

    //if (NULL == myReadContext.context ) {
    //    IoFreeIrp(irp);  
    //    return STATUS_INSUFFICIENT_RESOURCES;
    //}
    myReadContext.event=&event;
    KeInitializeEvent(&event, NotificationEvent, FALSE);
    IoSetCompletionRoutine(irp,
        MakeAsynchronousRequestCompletion,
        &myReadContext,//context,
        TRUE,
        TRUE,
        TRUE);
    //
    // If you want to change any value in the IRP stack, you must
    // first obtain the stack location by calling IoGetNextIrpStackLocation.
    // This is the location that is initialized by the IoBuildxxx requests and  
    // is the one that the target device driver is going to view.
    //
    //nextStack = IoGetNextIrpStackLocation(irp);
    //
    // Change the MajorFunction code to something appropriate.
    //
    //nextStack->MajorFunction = IRP_MJ_READ;

    memset(ReadBuffer,'1',READ_BUFF_SIZE);
    DbgPrint("%X",*((ULONG*)ReadBuffer));
 //  
    //DbgPrint("%X",nextStack->MajorFunction);
    status=IoCallDriver(TopOfDeviceStack, irp);
    
    if(status==STATUS_PENDING)
    {
        KeWaitForSingleObject(&event, Executive,KernelMode,0,0);
        //status=irp->IoStatus.Status;
    }
    DbgPrint("%X %X",((ULONG*)ReadBuffer)[0],((ULONG*)ReadBuffer)[1]);
    return status;
}
NTSTATUS
MakeAsynchronousRequestCompletion(
                                  IN PDEVICE_OBJECT   DeviceObject,
                                  IN PIRP             Irp,
                                  IN PVOID            Context
                                  )
{
    PMDL mdl, nextMdl;

    PMY_READ_CONTEXT    pMyReadContext=(PMY_READ_CONTEXT)Context;
    //
    // If the target device object is set up to do buffered i/o
    // (TopOfDeviceStack->Flags and DO_BUFFERED_IO), then
    // IoBuildAsynchronousFsdRequest request allocates a system buffer
    // for read and write operation. If you stop the completion of the IRP
    // here, you must free that buffer.
    //

    //if(Irp->AssociatedIrp.SystemBuffer && (Irp->Flags & IRP_DEALLOCATE_BUFFER) ) {
    //    ExFreePool(Irp->AssociatedIrp.SystemBuffer);
    //}

    //
    // If the target device object is set up do direct i/o (DO_DIRECT_IO), then
    // IoBuildAsynchronousFsdRequest creates an MDL to describe the buffer
    // and locks the pages. If you stop the completion of the IRP, you must unlock
    // the pages and free the MDL.
    //

    //else if (Irp->MdlAddress != NULL) {
    //    for (mdl = Irp->MdlAddress; mdl != NULL; mdl = nextMdl) {
    //        nextMdl = mdl->Next;
    //        MmUnlockPages( mdl ); IoFreeMdl( mdl ); // This function will also unmap pages.
    //    }
    //    Irp->MdlAddress = NULL;
    //}

    //if(pMyReadContext->context) {
    //    ExFreePool(pMyReadContext->context);
    //}

    
    //
    // If you intend to queue the IRP and reuse it for another request,
    // make sure you call IoReuseIrp(Irp, STATUS_SUCCESS) before you reuse.
    //
    DbgPrint("Information %X",Irp->IoStatus.Information);
    DbgPrint("Status %X",Irp->IoStatus.Status);
    IoFreeIrp(Irp);
    KeSetEvent(pMyReadContext->event,IO_NO_INCREMENT,FALSE);
    //
    // NOTE: this is the only status that you can return for driver-created asynchronous IRPs.
    //
    return STATUS_MORE_PROCESSING_REQUIRED;
}
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2007-07-13 11:08
上楼,你在哪儿调用此函数?
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
16楼#
发布于:2007-07-13 11:11
IFS中关于如何利用自己的IRP来实现IO操作的文章,
名字大概是:”Rolling Your Own“,
我记得前段时间我也贴在坛子里了,
所以,大家在问问题前一定要先搜,再问!
人总在矛盾中徘徊。。。
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
17楼#
发布于:2007-07-13 11:12
人总在矛盾中徘徊。。。
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2007-07-13 11:25
谢谢了,先
shakesky
驱动牛犊
驱动牛犊
  • 注册日期2006-03-16
  • 最后登录2011-06-25
  • 粉丝0
  • 关注0
  • 积分581分
  • 威望69点
  • 贡献值0点
  • 好评度58点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2007-07-16 14:10
终于搞定了,总结一下:不要怀疑调用IoBuildDeviceIoControlRequest,下发Irp来读取文件片断有问题,导致蓝屏出错原因往往是有些file_object对象无效或者还没完全生成,加了些屏蔽条件就好了。
下面是我的,希望对大家有帮助
sfcreate中:
    if(!SfIsObjectFile(FileObject))
        break;
            
    FileCtx.FsContext = FileObject->FsContext;
    if ((IrpSp->Parameters.Create.SecurityContext->DesiredAccess
        == FILE_READ_ATTRIBUTES) ) //FILE_READ_DATA
        break;

                     BOOLEAN
SfIsObjectFile(
    IN PFILE_OBJECT FileObject
    )
{
    PFSRTL_COMMON_FCB_HEADER fcb = (PFSRTL_COMMON_FCB_HEADER) FileObject->FsContext;
    if (!fcb) {
        return FALSE;
    }
    if (fcb->NodeTypeCode == FAT_NTC_FCB)
        return TRUE;
    else if (fcb->NodeTypeCode == NTFS_NTC_FCB)
        return TRUE;

    return FALSE;
}
上一页
游客

返回顶部