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

自己创建的IRP为什么读不到数据?

楼主#
更多 发布于:2005-03-23 14:41
我准备在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,
¤tIrpStack->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;
}

OnebyOnePlease
驱动牛犊
驱动牛犊
  • 注册日期2004-05-13
  • 最后登录2010-03-19
  • 粉丝0
  • 关注0
  • 积分99分
  • 威望31点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-03-23 16:11
我也有类似的问题,我的是重构IRP_MJ_CREATE。盼高手
joshua_yu
驱动小牛
驱动小牛
  • 注册日期2004-12-06
  • 最后登录2010-12-01
  • 粉丝0
  • 关注0
  • 积分428分
  • 威望54点
  • 贡献值0点
  • 好评度41点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-03-28 10:21
各位,我在Create例程中使用自己创建的IRP就能够正确读取文件,可是在Read例程当中就是不行,不是报告错误就是死锁在WaitForSingleObject上,看样子不完全是创建IRP的问题,应该跟读取文件的时机有关,但又不知道有什么关系,请各位老大给与帮助。

另外,看看前面的帖子,发现有人在Create例程当中复制一个stream file object然后设置CreateCompleted例程,等待Create完成,以后就用这个object创建IRP读取文件内容,不知道哪位做过,能不能给个例子阿?不胜感激,50分相送!
游客

返回顶部