以下NEwntopenfile是拦截zwopenfile的新函数体,我想在他体内来读去文件的内容,但是无法读去成功,是否以下代码有问题?
NTSTATUS NewNtOpenFile(
  OUT PHANDLE             p1,
  IN ACCESS_MASK          p2,
  IN POBJECT_ATTRIBUTES   p3,
  OUT PIO_STATUS_BLOCK    p4,
  IN ULONG                p5,
  IN ULONG                p6){
NTSTATUS rc=0;
ANSI_STRING an={0};
char buff[400]={0};
char buf[5]={0};
PFILE_OBJECT pfo;
PMDL mdl=NULL;
KEVENT event;
PIRP irp;
PIO_STACK_LOCATION irpsp=NULL; 
IO_STATUS_BLOCK IOSB;
RtlUnicodeStringToAnsiString(&an,p3->ObjectName,TRUE);
KeInitializeEvent(&event, SynchronizationEvent, FALSE); if(CheckSafe(p3->ObjectName)==1)
{
sprintf(buff,"#%s 文件可能被非法修改文件名或试图被删除(已拦截)",an.Buffer);
WLog(buff,strlen(buff));
return -1;
}rc=oldopen(p1,p2,p3,p4,p5,p6);//原有的open调用if(NT_SUCCESS(rc))
{
rc=ObReferenceObjectByHandle(*p1,GENERIC_READ,*IoFileObjectType,KernelMode,(PVOID*)&pfo,NULL);
if(NT_SUCCESS(rc))
{irp=IoAllocateIrp(pfo->DeviceObject->StackSize,TRUE);
if(!irp)
{
ObDereferenceObject(pfo);
return rc;
}  if(pfo->DeviceObject->Flags & DO_BUFFERED_IO) 
  { 
    irp->AssociatedIrp.SystemBuffer=buf;//buffered io 
  } 
  else if(pfo->DeviceObject->Flags & DO_DIRECT_IO) 
  { 
    mdl=IoAllocateMdl(buf,sizeof(buf),0,0,0); 
    MmBuildMdlForNonPagedPool(mdl); 
    irp->MdlAddress=mdl;
  } 
  else 
  { 
    irp->UserBuffer=buf;//neither i/o, use kernel buffer 
  }  irpsp=IoGetNextIrpStackLocation(irp);
  if(!irpsp)
  {
  IoFreeIrp(irp);
  ObDereferenceObject(pfo);
return rc;
  }
  irp->UserEvent = &event;
  irp->RequestorMode =KernelMode;   irpsp->FileObject=pfo;
  irpsp->MajorFunction=IRP_MJ_READ; 
  irpsp->MinorFunction=IRP_MN_NORMAL;//0 
  irpsp->Parameters.Read.ByteOffset.QuadPart=0;
  irpsp->Parameters.Read.Key=0; 
  irpsp->Parameters.Read.Length=sizeof(buf);
  IoSetCompletionRoutine(irp,IoCompletion,&event,1,1,1);
  rc=IoCallDriver(pfo->DeviceObject,irp); 
  if(rc==STATUS_PENDING)
  { 
  KeWaitForSingleObject(&event, Executive,KernelMode,0,0);
  }
 
  DbgPrint("%s\n",buf);//没有显示出东西
  
IoFreeIrp(irp);
if(mdl)
IoFreeMdl(mdl);
ObDereferenceObject(pfo);
}
}return rc;
}

解决方案 »

  1.   

    IoSetCompletionRoutine(irp,IoCompletion,&event,1,1,1);//设置irp的完成例程
     rc=IoCallDriver(pfo->DeviceObject,irp); //向下传递irp,
      if(rc==STATUS_PENDING)//是否返回值为执行中
      { 
      KeWaitForSingleObject(&event, Executive,KernelMode,0,0);//执行到等待了吗????
      }
     
      DbgPrint("%s\n",buf);//没有显示出东西再有在完成例程里面有数据吗?
      

  2.   

    感谢你看完了贴子。最后buf里没有数据,我不知道那里出错了感觉是建立irp的时候少填冲了数据?
      

  3.   

    if(rc==STATUS_PENDING)//是否返回值为执行中
      { 
      KeWaitForSingleObject(&event, Executive,KernelMode,0,0);//这里等到了,但是还是没有数据
      }