IoPageReadEx

NTSTATUS __stdcall IoPageReadEx(
        FILE_OBJECT *FileObject,
        MDL *MemoryDescriptorList,
        LARGE_INTEGER *StartingOffset,
        KEVENT *Event,
        IO_STATUS_BLOCK *IoStatusBlock,
        UINT64 Flags,
        PVOID IoAttributionContext){
  INT64 v9; 
  unsigned __int8 v10; 
  _DEVICE_OBJECT *RelatedDeviceObject; 
  _DEVICE_OBJECT *v12; 
  int v13; 
  __int64 v14; 
  IRP *Irp; 
  int IoPriorityThread; 
  __int64 v17; 
  _ETHREAD *CurrentThread; 
  _LARGE_INTEGER v20; 
  VOID *retaddr; 
  v9 = (Flags & 1) << 32;
  v10 = ((Flags & 1) != 0 ? 4 : 0) | 1;
  if( (Flags & 2) != 0 )
    v10 = (Flags & 1) != 0 ? 4 : 0;
  if( (Flags & 8) != 0 )
    v10 |= 2u;
  RelatedDeviceObject = IoGetRelatedDeviceObject(FileObject);
  v12 = RelatedDeviceObject;
  v13 = 1027;
  v14 = (__int64)RelatedDeviceObject;
  if( (Flags & 4) == 0 )
    v13 = 67;
  if( v10 >= 4u )
    v14 = -1i64;
  Irp = IopAllocateIrpExReturn((DEVICE_OBJECT *)v14, *((_BYTE *)RelatedDeviceObject + 76), 0, retaddr);
  if( Irp )
    goto LABEL_10;
  if( (unsigned int)MmIsFileObjectAPagingFile(FileObject) )
  {
    _InterlockedIncrement(&IoPageReadIrpAllocationFailure);
    Irp = IopAllocateReserveIrp(v20, *((_BYTE *)v12 + 76), 0i64);
    if( !Irp )
      return -1073741670;
  }
  else
  {
    _InterlockedIncrement(&IoPageReadNonPagefileIrpAllocationFailure);
    if( (MemoryDescriptorList->MdlFlags & 0x40) == 0 || (v13 & 0x40) == 0 )
      return -1073741670;
    Irp = IopAllocateBackpocketIrp((_DEVICE_OBJECT *)v14, *((_BYTE *)v12 + 76), 1u);
    if( !Irp )
      return -1073741670;
  }
LABEL_10:
  if( (unsigned int)MmIsFileObjectAPagingFile(FileObject)
    || (MemoryDescriptorList->MdlFlags & 0x40) != 0 && (v13 & 0x40) != 0 )
  {
    *((_BYTE *)Irp + 71) |= 0x20u;
  }
  *((_DWORD *)Irp + 4) = v13;
  IoPriorityThread = PsGetIoPriorityThread((__int64)KeGetCurrentThread());
  if( IoPriorityThread < 2 )
  {
    if( (v10 & 1) == 0 || (Flags & 1) == 1 || (*((_BYTE *)KeGetCurrentThread() + 1304) & 0x40) != 0 )
    {
      ++IoPagingReadLowPriorityCount;
    }
    else
    {
      ++IoPagingReadLowPriorityBumpedCount;
      IoPriorityThread = 2;
    }
  }
  if( (v10 & 2) != 0 && IoPriorityThread == 2 )
    IoPriorityThread = 3;
  *((_QWORD *)Irp + 1) = MemoryDescriptorList;
  *((_BYTE *)Irp + 64) = 0;
  *((_DWORD *)Irp + 4) = v13 | ((IoPriorityThread << 17) + 0x20000);
  *((_QWORD *)Irp + 10) = Event;
  *((_QWORD *)Irp + 9) = IoStatusBlock;
  *((_QWORD *)Irp + 14) = (char *)MemoryDescriptorList->StartVa + MemoryDescriptorList->ByteOffset;
  *((_QWORD *)Irp + 24) = FileObject;
  *((_QWORD *)Irp + 19) = KeGetCurrentThread();
  *(_BYTE *)(v17 - 72) = 3;
  *(_QWORD *)(v17 - 24) = FileObject;
  *(_DWORD *)(v17 - 64) = MemoryDescriptorList->ByteCount;
  *(LARGE_INTEGER *)(v17 - 48) = *StartingOffset;
  if( IoAttributionContext )
    IopSetDiskIoAttributionExtension(Irp, *((_QWORD *)IoAttributionContext + 3));
  else
    IoSetDiskIoAttributionFromThread(Irp, *((_ETHREAD **)Irp + 19));
  if( v9 )
    IopSetDriverFlagsExtension((INT64)Irp, v9);
  IoStatusBlock->Information = (unsigned __int64)Irp;
  IopQueueThreadIrp(Irp);
  if( (unsigned __int8)MmIsRecursiveIoFault() )
  {
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    *((_DWORD *)CurrentThread + 339) += (MemoryDescriptorList->ByteCount + 4095) >> 12;
  }
  return IofCallDriver(v12, Irp);
}

Referenced by:

IoPageRead
MiIssueHardFaultIo
MiMakeOutswappedPageResident
MiPageRead
MiPfIssueCoalescedSupport