NtReadFileScatter

NTSTATUS __stdcall NtReadFileScatter(
        HANDLE FileHandle,
        HANDLE Event,
        PIO_APC_ROUTINE UserApcRoutine,
        PVOID UserApcContext,
        PIO_STATUS_BLOCK UserIoStatusBlock,
        FILE_SEGMENT_ELEMENT BufferDescription[],
        ULONG BufferLength,
        PLARGE_INTEGER ByteOffset,
        PULONG Key){
  HANDLE v9; 
  PULONG v10; 
  INT8 v11; 
  NTSTATUS result; 
  __int64 v13; 
  _DEVICE_OBJECT *RelatedDeviceObject; 
  _DEVICE_OBJECT *v15; 
  int v16; 
  unsigned __int64 v17; 
  __int64 v18; 
  ULONG v19; 
  ULONG v20; 
  __int64 v21; 
  __int64 v22; 
  struct _DMA_ADAPTER *v23; 
  PLARGE_INTEGER v24; 
  unsigned int v25; 
  __int64 v26; 
  bool v27; 
  __int64 v28; 
  FILE_SEGMENT_ELEMENT *PoolWithQuota_0; 
  __int64 i; 
  __int16 v31; 
  UINT64 v32; 
  int v33; 
  UINT8 v34; 
  UINT8 v35; 
  struct _DMA_ADAPTER *v36; 
  int v37; 
  CHAR v38; 
  IRP *Irp; 
  IRP *v40; 
  PIO_STATUS_BLOCK v41; 
  __int64 v42; 
  ULONG v43; 
  MDL *Mdl; 
  FILE_SEGMENT_ELEMENT *__attribute__((__org_arrdim(0,0))) v45; 
  _DWORD *v46; 
  _ETHREAD *v47; 
  __int64 v48; 
  __int64 v49; 
  INT64 v50; 
  IRP *Object; 
  UINT64 v52; 
  KPROCESSOR_MODE AccessMode; 
  char v54[15]; 
  PVOID P; 
  LONGLONG QuadPart; 
  ULONG v57; 
  int v58; 
  PADAPTER_OBJECT DmaAdapter; 
  PVOID VirtualAddress; 
  int v61; 
  PDEVICE_OBJECT DeviceObject; 
  _ETHREAD *CurrentThread; 
  _DWORD *v64; 
  _ETHREAD *v65; 
  VOID *retaddr; 
  INT64 v68; 
  PVOID v69; 
  v69 = UserApcContext;
  v68 = (INT64)UserApcRoutine;
  v9 = Event;
  v10 = Key;
  *(_QWORD *)&v54[7] = 0i64;
  P = 0i64;
  DmaAdapter = 0i64;
  v57 = 0;
  QuadPart = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v11 = *((_BYTE *)CurrentThread + 562);
  AccessMode = v11;
  result = IopReferenceFileObject(FileHandle, 1ui64, v11, (FILE_OBJECT **)&v54[7], 0i64);
  if( result < 0 )
    return result;
  v13 = *(_QWORD *)&v54[7];
  RelatedDeviceObject = IoGetRelatedDeviceObject(*(_FILE_OBJECT **)&v54[7]);
  v15 = RelatedDeviceObject;
  DeviceObject = RelatedDeviceObject;
  v16 = *(_DWORD *)(v13 + 80);
  if( (v16 & 8) == 0
    || (v16 & 2) != 0
    || (*((_DWORD *)RelatedDeviceObject + 12) & 4) != 0
    || ((v17 = *((unsigned int *)RelatedDeviceObject + 18), (unsigned int)v17 > 0x36)
     || (v18 = 0x40000100100348i64, !_bittest64(&v18, v17)))
    && (_DWORD)v17 != 83 )
  {
    HalPutDmaAdapter((PADAPTER_OBJECT)v13);
    return -1073741811;
  }
  v19 = BufferLength;
  v20 = (BufferLength >> 12) + ((BufferLength & 0xFFF) != 0);
  if( v11 )
  {
    v58 = 0;
    v21 = (__int64)UserIoStatusBlock;
    v22 = 0x7FFFFFFF0000i64;
    if( (unsigned __int64)UserIoStatusBlock >= 0x7FFFFFFF0000i64 )
      v21 = 0x7FFFFFFF0000i64;
    *(_DWORD *)v21 = *(_DWORD *)v21;
    IopMarkApcRoutineIfAsynchronousIo32((UINT64 **)&UserIoStatusBlock, &v68, *(_BYTE *)(v13 + 80) & 2);
    v23 = *(struct _DMA_ADAPTER **)&v54[7];
    if( *(_QWORD *)(*(_QWORD *)&v54[7] + 176i64) && (v68 & 0xFFFFFFFFFFFFFFFEui64) != 0 )
    {
      HalPutDmaAdapter(*(PADAPTER_OBJECT *)&v54[7]);
      return -1073741811;
    }
    v24 = ByteOffset;
    if( ByteOffset )
    {
      if( ((unsigned __int8)ByteOffset & 3) != 0 )
        ExRaiseDatatypeMisalignment();
      QuadPart = ByteOffset->QuadPart;
      v23 = *(struct _DMA_ADAPTER **)&v54[7];
    }
    if( (*(_DWORD *)(v13 + 80) & 8) != 0 )
    {
      if( (v25 = *((unsigned __int16 *)v15 + 152), (_WORD)v25) && ((v25 - 1) & v19) != 0 && v19 % v25
        || ByteOffset && (_WORD)v25 && ((v25 - 1) & (unsigned int)QuadPart) != 0 )
      {
        HalPutDmaAdapter(v23);
        return -1073741811;
      }
    }
    v65 = (_ETHREAD *)KeGetCurrentThread();
    v26 = *(_QWORD *)(*((_QWORD *)v65 + 23) + 1408i64);
    v27 = 0;
    if( v26 )
    {
      v31 = *(_WORD *)(v26 + 8);
      if( v31 == 332 || v31 == 452 )
        v27 = 1;
    }
    v28 = v20;
    if( v28 * 8 )
    {
      if( v27 )
      {
        if( ((unsigned __int8)BufferDescription & 3) != 0 )
          ExRaiseDatatypeMisalignment();
      }
      else if( ((unsigned __int8)BufferDescription & 7) != 0 )
      {
        ExRaiseDatatypeMisalignment();
      }
      if( (unsigned __int64)&BufferDescription[v28] > 0x7FFFFFFF0000i64 || &BufferDescription[v28] < BufferDescription )
        MEMORY[0x7FFFFFFF0000] = 0;
    }
    if( v19 )
    {
      PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)IopVerifierExAllocatePoolWithQuota_0(PagedPool, 8i64 * v20);
      P = PoolWithQuota_0;
      memmove((UINT8 *)PoolWithQuota_0, (UINT8 *)BufferDescription, 8i64 * v20);
      BufferDescription = PoolWithQuota_0;
      for( i = 0i64; ; i = (unsigned int)(i + 1) )
      {
        v61 = i;
        if( (unsigned int)i >= v20 )
          break;
        if( ((__int64)BufferDescription[i].Buffer & 0xFFFi64) != 0 )
          RtlRaiseStatus(-1073741811);
      }
    }
    else
    {
      PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)P;
    }
    if( v10 )
    {
      if( (unsigned __int64)v10 < 0x7FFFFFFF0000i64 )
        v22 = (__int64)v10;
      v57 = *(_DWORD *)v22;
      PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)P;
    }
    v13 = *(_QWORD *)&v54[7];
    v9 = Event;
  }
  else
  {
    v24 = ByteOffset;
    if( ByteOffset )
      QuadPart = ByteOffset->QuadPart;
    PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)P;
    if( v10 )
      v57 = *v10;
  }
  if( v9 )
  {
    VirtualAddress = 0i64;
    v33 = ObReferenceObjectByHandle(v9, 2u, (POBJECT_TYPE)ExEventObjectType, AccessMode, &VirtualAddress, 0i64);
    v36 = (struct _DMA_ADAPTER *)VirtualAddress;
    DmaAdapter = (PADAPTER_OBJECT)VirtualAddress;
    if( v33 < 0 )
    {
      HalPutDmaAdapter((PADAPTER_OBJECT)v13);
      if( PoolWithQuota_0 )
        ExFreePoolWithTag(PoolWithQuota_0, 0);
      return v33;
    }
    KeResetEvent(VirtualAddress, v32, v34, v35, Object);
  }
  else
  {
    v36 = DmaAdapter;
  }
  v64 = (_DWORD *)(v13 + 80);
  v37 = *(_DWORD *)(v13 + 80);
  if( (v37 & 2) != 0 )
  {
    v47 = (_ETHREAD *)KeGetCurrentThread();
    --*((_WORD *)v47 + 242);
    v48 = *(_QWORD *)&v54[7];
    LODWORD(v49) = KeAbPreAcquire((PVOID)(*(_QWORD *)&v54[7] + 128i64), 0i64, 0i64);
    if( _InterlockedExchange((volatile __int32 *)(v48 + 116), 1) )
    {
      LOBYTE(v50) = AccessMode;
      v13 = *(_QWORD *)&v54[7];
      IopWaitAndAcquireFileObjectLock(*(PVOID *)&v54[7], v50);
    }
    else
    {
      if( v49 )
        *(_BYTE *)(v49 + 26) |= 1u;
      v13 = *(_QWORD *)&v54[7];
      ObfReferenceObject(*(PVOID *)&v54[7]);
    }
    if( !v24 || QuadPart == -2 )
      QuadPart = *(_QWORD *)(v13 + 104);
    v38 = 1;
    PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)P;
    v36 = DmaAdapter;
  }
  else
  {
    if( !v24 && (v37 & 0x280) == 0 )
    {
      if( v36 )
        HalPutDmaAdapter(v36);
LABEL_100:
      HalPutDmaAdapter((PADAPTER_OBJECT)v13);
      if( PoolWithQuota_0 )
        ExFreePoolWithTag(PoolWithQuota_0, 0);
      return -1073741811;
    }
    v38 = 0;
  }
  if( QuadPart < 0 )
  {
    if( v36 )
      HalPutDmaAdapter(v36);
    if( v38 )
      IopReleaseFileObjectLock((PADAPTER_OBJECT)v13);
    goto LABEL_100;
  }
  IopResetEvent((FILE_OBJECT *)v13);
  Irp = IopAllocateIrpExReturn(DeviceObject, *((_BYTE *)DeviceObject + 76), v38 ^ 1u, retaddr);
  v40 = Irp;
  VirtualAddress = Irp;
  if( Irp )
  {
    *((_QWORD *)Irp + 24) = v13;
    *((_QWORD *)Irp + 19) = CurrentThread;
    *((_QWORD *)Irp + 20) = 0i64;
    *((_BYTE *)Irp + 64) = AccessMode;
    *((_BYTE *)Irp + 65) = 0;
    *((_BYTE *)Irp + 68) = 0;
    *((_QWORD *)Irp + 13) = 0i64;
    *((_QWORD *)Irp + 10) = v36;
    v41 = UserIoStatusBlock;
    *((_QWORD *)Irp + 9) = UserIoStatusBlock;
    *((_QWORD *)Irp + 11) = v68;
    *((_QWORD *)Irp + 12) = v69;
    v42 = *((_QWORD *)Irp + 23);
    *(_DWORD *)(v42 - 72) = 3;
    *(_QWORD *)(v42 - 24) = v13;
    *((_QWORD *)Irp + 3) = 0i64;
    *((_QWORD *)Irp + 1) = 0i64;
    *((_DWORD *)Irp + 4) = 0;
    v43 = BufferLength;
    if( BufferLength )
    {
      Mdl = IoAllocateMdl(BufferDescription->Buffer, BufferLength, 0, 1u, Irp);
      if( !Mdl )
        RtlRaiseStatus(-1073741670);
      v45 = BufferDescription;
      MmProbeAndLockSelectedPages(Mdl, BufferDescription, AccessMode, IoWriteAccess);
      *((FILE_SEGMENT_ELEMENT *)v40 + 14) = (FILE_SEGMENT_ELEMENT)v45->Buffer;
      v43 = BufferLength;
    }
    if( PoolWithQuota_0 )
      ExFreePoolWithTag(PoolWithQuota_0, 0);
    *((_DWORD *)v40 + 4) |= (*v64 & 8 | 0x4800u) >> 3;
    *(_DWORD *)(v42 - 64) = v43;
    *(_DWORD *)(v42 - 56) = v57;
    *(_QWORD *)(v42 - 48) = QuadPart;
    v46 = *(_DWORD **)(v13 + 208);
    if( v46 && (*v46 & 0x10) != 0 )
      *(_DWORD *)(v42 - 52) = v41->Information;
    LODWORD(v52) = 0;
    return IopSynchronousServiceTail(DeviceObject, v40, (FILE_OBJECT *)v13, 1, AccessMode, v38, v52);
  }
  else
  {
    IopAllocateIrpCleanup((PUNICODE_STRING)v13);
    if( PoolWithQuota_0 )
      ExFreePoolWithTag(PoolWithQuota_0, 0);
    return -1073741670;
  }
}

Referenced by:

No references.