NtReadFile

NTSTATUS __stdcall NtReadFile(
        HANDLE FileHandle,
        HANDLE Event,
        PIO_APC_ROUTINE ApcRoutine,
        PVOID ApcContext,
        PIO_STATUS_BLOCK IoStatusBlock,
        PVOID Buffer,
        ULONG Length,
        PLARGE_INTEGER ByteOffset,
        PULONG Key){
  unsigned __int8 v10; 
  NTSTATUS result; 
  PFILE_OBJECT v12; 
  _DEVICE_OBJECT *RelatedDeviceObject; 
  __int64 v14; 
  unsigned int *p_Flags; 
  int v16; 
  PLARGE_INTEGER v17; 
  __int64 v18; 
  int v19; 
  unsigned int v20; 
  unsigned int v21; 
  struct _DMA_ADAPTER *v22; 
  __int64 v23; 
  unsigned int Flags; 
  _ETHREAD *v25; 
  PFILE_OBJECT v26; 
  __int64 v27; 
  __int64 v28; 
  NTSTATUS v29; 
  __int64(__fastcall *v30)(PFILE_OBJECT, LONGLONG *, _QWORD, __int64, __int64 *, PVOID, __int128 *, _DEVICE_OBJECT *); 
  void *v31; 
  char v32; 
  _ETHREAD *v33; 
  _ETHREAD *v34; 
  unsigned __int64 v35; 
  struct _DMA_ADAPTER *v36; 
  CHAR v37; 
  IRP *Irp; 
  IRP *v39; 
  PIO_STATUS_BLOCK v40; 
  __int64 v41; 
  int v42; 
  _DWORD *FileObjectExtension; 
  UINT64 v44; 
  UINT8 v45; 
  UINT8 v46; 
  int v47; 
  struct _DMA_ADAPTER *v48; 
  _MDL *Mdl; 
  int v50; 
  __int64 *Object; 
  IRP *Objecta; 
  UINT64 v53; 
  __int64 v54; 
  PFILE_OBJECT FileObject; 
  LONGLONG QuadPart; 
  ULONG v57; 
  PRKEVENT Eventa; 
  int v59; 
  PVOID VirtualAddress; 
  __int128 v61; 
  _ETHREAD *CurrentThread; 
  VOID *retaddr; 
  INT64 v64; 
  PVOID v65; 
  v65 = ApcContext;
  v64 = (INT64)ApcRoutine;
  FileObject = 0i64;
  Eventa = 0i64;
  v57 = 0;
  QuadPart = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v10 = *((_BYTE *)CurrentThread + 562);
  result = IopReferenceFileObject(FileHandle, 1ui64, v10, &FileObject, 0i64);
  if( result < 0 )
    return result;
  v12 = FileObject;
  RelatedDeviceObject = IoGetRelatedDeviceObject(FileObject);
  if( v10 )
  {
    v59 = 0;
    v14 = (__int64)IoStatusBlock;
    if( (unsigned __int64)IoStatusBlock >= 0x7FFFFFFF0000i64 )
      v14 = 0x7FFFFFFF0000i64;
    *(_DWORD *)v14 = *(_DWORD *)v14;
    v12 = FileObject;
    p_Flags = &FileObject->Flags;
    IopMarkApcRoutineIfAsynchronousIo32((UINT64 **)&IoStatusBlock, &v64, FileObject->Flags & 2);
    v16 = (int)Buffer;
    ProbeForWrite(Buffer, Length, 1ui64);
    if( v12->CompletionContext && (v64 & 0xFFFFFFFFFFFFFFFEui64) != 0 )
      goto LABEL_96;
    v17 = ByteOffset;
    if( ByteOffset )
    {
      if( ((unsigned __int8)ByteOffset & 3) != 0 )
        ExRaiseDatatypeMisalignment();
      QuadPart = ByteOffset->QuadPart;
      v12 = FileObject;
    }
    if( (*p_Flags & 8) == 0 )
    {
LABEL_8:
      v18 = (__int64)Key;
      if( Key )
      {
        if( (unsigned __int64)Key >= 0x7FFFFFFF0000i64 )
          v18 = 0x7FFFFFFF0000i64;
        v57 = *(_DWORD *)v18;
        v12 = FileObject;
      }
      goto LABEL_29;
    }
    v19 = *((unsigned __int16 *)RelatedDeviceObject + 152);
    if( (_WORD)v19 )
    {
      v20 = *((unsigned __int16 *)RelatedDeviceObject + 152);
      v21 = v20;
      if( ((v19 - 1) & Length) != 0 )
      {
LABEL_25:
        if( (_WORD)v19 && Length % v21 )
          goto LABEL_96;
        v20 = v21;
        if( (*((_DWORD *)RelatedDeviceObject + 38) & v16) != 0 )
          goto LABEL_96;
LABEL_20:
        if( ByteOffset && (_WORD)v19 && ((v20 - 1) & (unsigned int)QuadPart) != 0 )
          goto LABEL_96;
        goto LABEL_8;
      }
    }
    else
    {
      v20 = 0;
    }
    v21 = v20;
    if( (*((_DWORD *)RelatedDeviceObject + 38) & v16) == 0 )
      goto LABEL_20;
    goto LABEL_25;
  }
  v17 = ByteOffset;
  if( ByteOffset )
    QuadPart = ByteOffset->QuadPart;
  if( Key )
    v57 = *Key;
LABEL_29:
  if( Event )
  {
    VirtualAddress = 0i64;
    v47 = ObReferenceObjectByHandle(Event, 2u, (POBJECT_TYPE)ExEventObjectType, v10, &VirtualAddress, 0i64);
    v22 = (struct _DMA_ADAPTER *)VirtualAddress;
    Eventa = (PRKEVENT)VirtualAddress;
    if( v47 < 0 )
    {
      HalPutDmaAdapter((PADAPTER_OBJECT)v12);
      return v47;
    }
    KeResetEvent(VirtualAddress, v44, v45, v46, Objecta);
  }
  else
  {
    v22 = (struct _DMA_ADAPTER *)Eventa;
  }
  v23 = *(_QWORD *)(*((_QWORD *)RelatedDeviceObject + 1) + 80i64);
  Flags = v12->Flags;
  if( (Flags & 2) == 0 )
  {
    if( v17 || (Flags & 0x280) != 0 )
    {
      v37 = 0;
      goto LABEL_52;
    }
    if( v22 )
      HalPutDmaAdapter(v22);
LABEL_96:
    HalPutDmaAdapter((PADAPTER_OBJECT)v12);
    return -1073741811;
  }
  v25 = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)v25 + 242);
  v26 = FileObject;
  LODWORD(v27) = KeAbPreAcquire(&FileObject->Lock, 0i64, 0i64);
  LOBYTE(v54) = 0;
  if( _InterlockedExchange((volatile __int32 *)&v26->Busy, 1) )
  {
    Object = &v54;
    v12 = FileObject;
    v29 = IopWaitAndAcquireFileObjectLock(FileObject, v10);
  }
  else
  {
    if( v27 )
      *(_BYTE *)(v27 + 26) |= 1u;
    v12 = FileObject;
    ObfReferenceObject(FileObject);
    v29 = 0;
  }
  if( (_BYTE)v54 )
  {
    if( Eventa )
      HalPutDmaAdapter((PADAPTER_OBJECT)Eventa);
    HalPutDmaAdapter((PADAPTER_OBJECT)v12);
    return v29;
  }
  else
  {
    if( !v17 || QuadPart == -2 )
      QuadPart = v12->CurrentByteOffset.QuadPart;
    if( !v12->PrivateCacheMap )
      goto LABEL_62;
    v61 = 0i64;
    v30 = *(__int64(__fastcall **)(PFILE_OBJECT, LONGLONG *, _QWORD, __int64, __int64 *, PVOID, __int128 *, _DEVICE_OBJECT *))(v23 + 16);
    if( QuadPart < 0 )
    {
      if( Eventa )
        HalPutDmaAdapter((PADAPTER_OBJECT)Eventa);
      goto LABEL_90;
    }
    if( (MmVerifierData & 0x10) != 0 )
      v31 = VfFastIoSnapState();
    else
      v31 = 0i64;
    LODWORD(Object) = v57;
    LOBYTE(v28) = 1;
    v32 = v30(v12, &QuadPart, Length, v28, Object, Buffer, &v61, RelatedDeviceObject);
    if( v31 )
      VfFastIoCheckState(v31, v30);
    if( !v32 || (_DWORD)v61 && (_DWORD)v61 != -1073741807 && (_DWORD)v61 != -2147483643 )
    {
LABEL_62:
      v37 = 1;
      v22 = (struct _DMA_ADAPTER *)Eventa;
LABEL_52:
      if( QuadPart >= 0 )
      {
        IopResetEvent(v12);
        Irp = IopAllocateIrpExReturn(RelatedDeviceObject, *((_BYTE *)RelatedDeviceObject + 76), v37 ^ 1u, retaddr);
        v39 = Irp;
        VirtualAddress = Irp;
        if( Irp )
        {
          *((_QWORD *)Irp + 24) = v12;
          *((_QWORD *)Irp + 19) = CurrentThread;
          *((_QWORD *)Irp + 20) = 0i64;
          *((_BYTE *)Irp + 64) = v10;
          *((_BYTE *)Irp + 65) = 0;
          *((_BYTE *)Irp + 68) = 0;
          *((_QWORD *)Irp + 13) = 0i64;
          *((_QWORD *)Irp + 10) = v22;
          v40 = IoStatusBlock;
          *((_QWORD *)Irp + 9) = IoStatusBlock;
          *((_QWORD *)Irp + 11) = v64;
          *((_QWORD *)Irp + 12) = v65;
          v41 = *((_QWORD *)Irp + 23);
          *(_DWORD *)(v41 - 72) = 3;
          *(_QWORD *)(v41 - 24) = v12;
          *((_QWORD *)Irp + 3) = 0i64;
          *((_QWORD *)Irp + 1) = 0i64;
          v42 = *((_DWORD *)RelatedDeviceObject + 12);
          if( (v42 & 4) != 0 )
          {
            if( Length )
            {
              *((_QWORD *)v39 + 3) = IopVerifierExAllocatePoolWithQuota_0(NonPagedPoolNxCacheAligned, Length);
              *((_QWORD *)v39 + 14) = Buffer;
              v50 = 112;
            }
            else
            {
              v50 = 80;
            }
            *((_DWORD *)v39 + 4) = v50;
          }
          else
          {
            *((_DWORD *)v39 + 4) = 0;
            if( (v42 & 0x10) != 0 )
            {
              if( Length )
              {
                Mdl = IoAllocateMdl(Buffer, Length, 0, 1u, v39);
                if( !Mdl )
                  RtlRaiseStatus(-1073741670);
                MmProbeAndLockPages(Mdl, v10, IoWriteAccess);
              }
            }
            else
            {
              *((_QWORD *)v39 + 14) = Buffer;
            }
          }
          *((_DWORD *)v39 + 4) |= (v12->Flags & 8 | 0x4800) >> 3;
          *(_DWORD *)(v41 - 64) = Length;
          *(_DWORD *)(v41 - 56) = v57;
          *(_QWORD *)(v41 - 48) = QuadPart;
          FileObjectExtension = v12->FileObjectExtension;
          if( FileObjectExtension && (*FileObjectExtension & 0x10) != 0 )
            *(_DWORD *)(v41 - 52) = v40->Information;
          LODWORD(v53) = 0;
          return IopSynchronousServiceTail(RelatedDeviceObject, v39, v12, 1, v10, v37, v53);
        }
        else
        {
          IopAllocateIrpCleanup((PUNICODE_STRING)v12);
          return -1073741670;
        }
      }
      if( v22 )
        HalPutDmaAdapter(v22);
      if( !v37 )
      {
LABEL_91:
        HalPutDmaAdapter((PADAPTER_OBJECT)v12);
        return -1073741811;
      }
LABEL_90:
      IopReleaseFileObjectLock((PADAPTER_OBJECT)v12);
      goto LABEL_91;
    }
    v33 = (_ETHREAD *)KeGetCurrentThread();
    ++*((_QWORD *)v33 + 112);
    __incgsdword(0x2EDCu);
    v34 = (_ETHREAD *)KeGetCurrentThread();
    v35 = DWORD2(v61);
    *((_QWORD *)v34 + 115) += DWORD2(v61);
    __addgsqword(0x2EE8u, v35);
    *IoStatusBlock = (struct _IO_STATUS_BLOCK)v61;
    v36 = (struct _DMA_ADAPTER *)FileObject;
    if( Event )
    {
      v48 = (struct _DMA_ADAPTER *)Eventa;
      if( (FileObject->Flags & 0x8000000) == 0 )
        KeSetEvent(Eventa, 0);
      HalPutDmaAdapter(v48);
    }
    IopReleaseFileObjectLock(v36);
    HalPutDmaAdapter(v36);
    return v61;
  }
}

Referenced by:

PfSnGetPrefetchInstructions
SmKmIssueFileIo