joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
阅读:1191回复:0

大家帮忙看看,自己创建IRP怎么读不到文件内容?

楼主#
更多 发布于:2005-03-23 14:37
我准备在filemon拦截到对某个文件a进行读访问时(IRP_MJ_READ)利用自己创建的IRP向下层驱动读取数据,然后再将读取到的数据交给上层应用,可是怎么都读不到数据,不知道是不是我的IRP建立的有问题,请各位给我看看。

读例程:

NTSTATUS
FilemonReadDispatch(
PDEVICE_OBJECT HookDevice,
IN PIRP Irp
)
{
PIO_STACK_LOCATION  currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
    PIO_STACK_LOCATION  nextIrpStack    = IoGetNextIrpStackLocation(Irp);
    PFILE_OBJECT        fileObject;
    PHOOK_EXTENSION     hookExt;
    PCHAR               fullPathName;
    CHAR                name[PROCNAMELEN];

PUCHAR SysBuffer = NULL; //IRP中原有的MDL缓冲区

*nextIrpStack = *currentIrpStack;
//
    // Allocate a buffer
    //
    fullPathName = ExAllocatePool( PagedPool, MAXPATHLEN );
    fullPathName[0] = 0;

    //
    // Extract the file object from the IRP
    //
    fileObject    = currentIrpStack->FileObject;

    //
    // Point at the device extension, which contains information on which
    // file system this IRP is headed for
    //
    hookExt = HookDevice->DeviceExtension;

    //
    // If a GUI is up there, get the canonical pathname
    //
    FilemonGetFullPath( FALSE, fileObject, hookExt, fullPathName );

    //
    // Only log it if it passes the filter
    //
    if( FilemonGetProcess( name ) && ApplyNameFilter(fullPathName) ) {
        //
        // Determine what function we\'re dealing with
        //
LARGE_INTEGER m_time;
m_time.QuadPart = 1;

if( FilterDef.logreads ) {
UpdateStore( 100100, &m_time, \"%s\\tIRP_MJ_READ%c\\t%s\\tOffset: %d Length: %d\",
name,
(Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ? \'*\' : \' \',
fullPathName,
currentIrpStack->Parameters.Read.ByteOffset.LowPart,
currentIrpStack->Parameters.Read.Length );
}


if( (Irp->Flags & IRP_NOCACHE) ||
(Irp->Flags & IRP_PAGING_IO) ||
(Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) )
{
FileBufferSize = currentIrpStack->Parameters.Read.Length;

/*获取上层应用提供的缓冲区*/
if(Irp->MdlAddress){//Direct I/O Method
SysBuffer = (PUCHAR)MmGetSystemAddressForMdlSafe(
Irp->MdlAddress,
NormalPagePriority
);

if(SysBuffer == NULL){
return CompleteRequest(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
}
}
else
SysBuffer = Irp->UserBuffer;

/*创建一个新的缓冲区,用来给新IRP使用*/
FileBuffer = ExAllocatePool(NonPagedPool, FileBufferSize);

Status = MyReadDispatch(
hookExt->FileSystem,
fileObject,
FileBuffer,
FileBufferSize,
&currentIrpStack->Parameters.Read.ByteOffset);

if(!Status){
ExFreePool(FileBuffer);
return CompleteRequest(Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
}

RtlCopyMemory(SysBuffer, FileBuffer, FileBufferSize);

ExFreePool(FileBuffer);

if(fullPathName)
ExFreePool(fullPathName);

return CompleteRequest(Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
}
}

if(fullPathName)
ExFreePool(fullPathName);

return IoCallDriver(hookExt->FileSystem, Irp);
}

我自己的读例程:
BOOLEAN
MyReadDispatch(PDEVICE_OBJECT DeviceObject,
PFILE_OBJECT FileObject,
PUCHAR FileBuffer,
ULONG  FileBufferSize,
PLARGE_INTEGER Offset
)
{
    PIRP irp;
    KEVENT event;
PMDL   MyMDL;
    IO_STATUS_BLOCK IoStatusBlock;
    PIO_STACK_LOCATION irpSp;
ULONG MajorFunction;
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) {

        //
        // Failure!
        //
        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);

/*这里总是失败,任何内容都读不到*/
DbgPrint((\"%s content:%s\\n\",
NT_SUCCESS( IoStatusBlock.Status )? \"Success\":\"Failed\",
FileBuffer));

    return( NT_SUCCESS( IoStatusBlock.Status ));
}

完成例程:
NTSTATUS
MyReadCompleted(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
    //
    // Copy the status information back into the \"user\" IOSB.
    //
    *Irp->UserIosb = Irp->IoStatus;

    if( !NT_SUCCESS(Irp->IoStatus.Status) ) {
//总是运行到这里
        DbgPrint((\"   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;
}
 :)
游客

返回顶部