NtWriteFileGather

NTSTATUS __stdcall NtWriteFileGather(
        INT64 a1,
        INT64 a2,
        INT64 a3,
        INT64 a4,
        INT64 a5,
        VOID *Src,
        ULONG Length,
        INT64 a8,
        INT64 a9){
  int *v9; 
  INT64 v10; 
  int v11; 
  INT8 PreviousMode; 
  NTSTATUS result; 
  unsigned __int8 GrantedAccess; 
  _ADAPTER_OBJECT *v15; 
  _DWORD *v16; 
  unsigned int *p_Offset; 
  unsigned int Offset; 
  unsigned __int64 v19; 
  __int64 v20; 
  ULONG v21; 
  INT64 v22; 
  __int64 v23; 
  _EWOW64PROCESS *WoW64Process; 
  bool v25; 
  __int64 v26; 
  ULONG v27; 
  void *PoolWithQuota_0; 
  unsigned int v29; 
  unsigned int v30; 
  unsigned int v31; 
  unsigned __int16 Machine; 
  int v33; 
  UINT8 v34; 
  CHAR v35; 
  _DEVICE_OBJECT *v36; 
  _IRP *Irp; 
  _IRP *v38; 
  INT64 v39; 
  _IO_STACK_LOCATION *CurrentStackLocation; 
  _MDL *Mdl; 
  _KPROCESSOR_MODE v42; 
  _MDL *v43; 
  __int64 MajorFunction; 
  __int64 v45; 
  _DWORD *v46; 
  bool v47; 
  _ETHREAD *v48; 
  _FILE_OBJECT *v49; 
  _BYTE *v50; 
  NTSTATUS v51; 
  UINT8 v52; 
  CHAR AccessMode; 
  char AccessMode_1; 
  __int64 Buffer; 
  bool v56; 
  _FILE_OBJECT *pFileObject; 
  PVOID P; 
  int v59; 
  PVOID EventObject; 
  int v61; 
  unsigned int *v62; 
  VOID *CallersCaller; 
  PVOID Object; 
  unsigned int v65; 
  _OBJECT_HANDLE_INFORMATION pHandleInformation; 
  _ETHREAD *CurrentThread; 
  _ETHREAD *v68; 
  VOID *retaddr; 
  INT64 v71; 
  INT64 v72; 

  v72 = a4;
  v71 = a3;
  v9 = (int *)a9;
  v10 = a8;
  v11 = 0;
  pFileObject = 0i64;
  P = 0i64;
  pHandleInformation = 0i64;
  EventObject = 0i64;
  v59 = 0;
  Buffer = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  PreviousMode = CurrentThread->Tcb.PreviousMode;
  AccessMode = PreviousMode;
  result = IopReferenceFileObject((VOID *)a1, 0i64, PreviousMode, &pFileObject, &pHandleInformation);
  if( result < 0 )
    return result;
  GrantedAccess = pHandleInformation.GrantedAccess;
  v15 = (_ADAPTER_OBJECT *)pFileObject;
  LODWORD(v16) = IoGetRelatedDeviceObject((INT64)pFileObject);
  CallersCaller = v16;
  p_Offset = &v15->AdapterObject.ScatterTranslationEnd.Offset;
  v62 = &v15->AdapterObject.ScatterTranslationEnd.Offset;
  Offset = v15->AdapterObject.ScatterTranslationEnd.Offset;
  if( (Offset & 8) == 0
    || (Offset & 2) != 0
    || (v16[12] & 4) != 0
    || ((v19 = (unsigned int)v16[18], (unsigned int)v19 > 0x36) || (v20 = 0x40000100100348i64, !_bittest64(&v20, v19)))
    && (_DWORD)v19 != 83 )
  {
    HalPutDmaAdapter(v15);
    return -1073741811;
  }
  LOBYTE(v11) = (Length & 0xFFF) != 0;
  v21 = (Length >> 12) + v11;
  if( PreviousMode )
  {
    if( ((~(unsigned __int8)(Offset >> 5) & 4 | 2) & GrantedAccess) == 0 )
    {
      HalPutDmaAdapter(v15);
      return -1073741790;
    }
    v61 = 0;
    v22 = a5;
    v23 = 0x7FFFFFFF0000i64;
    if( (unsigned __int64)a5 >= 0x7FFFFFFF0000i64 )
      v22 = 0x7FFFFFFF0000i64;
    *(_DWORD *)v22 = *(_DWORD *)v22;
    IopMarkApcRoutineIfAsynchronousIo32((UINT64 **)&a5, &v71, *(_BYTE *)p_Offset & 2);
    v68 = (_ETHREAD *)KeGetCurrentThread();
    WoW64Process = v68->Tcb.ApcState.Process->WoW64Process;
    v25 = 0;
    if( WoW64Process )
    {
      Machine = WoW64Process->Machine;
      if( Machine == 332 || Machine == 452 )
        v25 = 1;
    }
    v56 = v25;
    v26 = 8i64 * v21;
    if( v26 )
    {
      if( v25 )
      {
        if( ((unsigned __int8)Src & 3) != 0 )
          ExRaiseDatatypeMisalignment();
      }
      else if( ((unsigned __int8)Src & 7) != 0 )
      {
        ExRaiseDatatypeMisalignment();
      }
      if( (unsigned __int64)Src + v26 > 0x7FFFFFFF0000i64 || (char *)Src + v26 < Src )
        MEMORY[0x7FFFFFFF0000] = 0;
    }
    v27 = Length;
    if( Length )
    {
      PoolWithQuota_0 = IopVerifierExAllocatePoolWithQuota_0(PagedPool, 8i64 * v21);
      P = PoolWithQuota_0;
      memmove(PoolWithQuota_0, Src, 8 * v21);
      Src = PoolWithQuota_0;
      v29 = 0;
      v65 = 0;
      while( v29 < v21 )
      {
        if( (*((_DWORD *)Src + 2 * v29) & 0xFFFi64) != 0 )
          RtlRaiseStatus(-1073741811);
        v65 = ++v29;
      }
      v27 = Length;
    }
    v15 = (_ADAPTER_OBJECT *)pFileObject;
    if( pFileObject->CompletionContext && (v71 & 0xFFFFFFFFFFFFFFFEui64) != 0 )
      RtlRaiseStatus(-1073741811);
    if( v10 )
    {
      if( (v10 & 3) != 0 )
        ExRaiseDatatypeMisalignment();
      Buffer = *(_QWORD *)v10;
      v15 = (_ADAPTER_OBJECT *)pFileObject;
    }
    p_Offset = &v15->AdapterObject.ScatterTranslationEnd.Offset;
    v62 = &v15->AdapterObject.ScatterTranslationEnd.Offset;
    v30 = v15->AdapterObject.ScatterTranslationEnd.Offset;
    if( (v30 & 8) != 0 )
    {
      v31 = *((unsigned __int16 *)CallersCaller + 152);
      if( (_WORD)v31 && ((v31 - 1) & v27) != 0 && v27 % v31 )
        RtlRaiseStatus(-1073741811);
      if( v10
        && Buffer != -1
        && (Buffer != -2 || (v30 & 2) == 0)
        && (_WORD)v31
        && ((v31 - 1) & (unsigned int)Buffer) != 0 )
      {
        RtlRaiseStatus(-1073741811);
      }
    }
    if( v9 )
    {
      if( (unsigned __int64)v9 < 0x7FFFFFFF0000i64 )
        v23 = (__int64)v9;
      v59 = *(_DWORD *)v23;
      v15 = (_ADAPTER_OBJECT *)pFileObject;
    }
    PreviousMode = AccessMode;
  }
  else
  {
    if( v10 )
      Buffer = *(_QWORD *)v10;
    if( v9 )
      v59 = *v9;
  }
  if( (GrantedAccess & 6) == 4 )
    Buffer = -1i64;
  if( a2 )
  {
    Object = 0i64;
    v33 = ObReferenceObjectByHandle((VOID *)a2, 2ui64, (_OBJECT_TYPE *)ExEventObjectType, PreviousMode, &Object, 0i64);
    EventObject = Object;
    if( v33 < 0 )
    {
      HalPutDmaAdapter(v15);
      if( P )
        ExFreePoolWithTag(P, 0);
      return v33;
    }
    KeResetEvent((_KEVENT *)Object);
  }
  if( (*p_Offset & 2) != 0 )
  {
    v47 = (*p_Offset & 4) != 0;
    v48 = (_ETHREAD *)KeGetCurrentThread();
    --v48->Tcb.KernelApcDisable;
    v49 = pFileObject;
    v50 = KeAbPreAcquire(pFileObject->gap80, 0i64, 0i64);
    AccessMode_1 = 0;
    if( _InterlockedExchange((volatile __int32 *)&v49->Busy, 1) )
    {
      v52 = v47;
      v35 = AccessMode;
      v15 = (_ADAPTER_OBJECT *)pFileObject;
      v51 = IopWaitAndAcquireFileObjectLock(pFileObject, AccessMode, v52, v50, (INT64)&AccessMode_1);
    }
    else
    {
      if( v50 )
        v50[26] |= 1u;
      v15 = (_ADAPTER_OBJECT *)pFileObject;
      ObfReferenceObject(pFileObject);
      v51 = 0;
      v35 = AccessMode;
    }
    if( AccessMode_1 )
    {
      if( EventObject )
        HalPutDmaAdapter((PADAPTER_OBJECT)EventObject);
      HalPutDmaAdapter(v15);
      if( P )
        ExFreePoolWithTag(P, 0);
      return v51;
    }
    v34 = 1;
    if( !v10 && !(_DWORD)Buffer || Buffer == -2 )
      Buffer = (__int64)v15->AdapterObject.CrashDump.ScatterHint.Buffer;
    p_Offset = v62;
  }
  else
  {
    if( !v10 && (*p_Offset & 0x280) == 0 )
    {
      if( EventObject )
        HalPutDmaAdapter((PADAPTER_OBJECT)EventObject);
LABEL_122:
      HalPutDmaAdapter(v15);
      if( P )
        ExFreePoolWithTag(P, 0);
      return -1073741811;
    }
    v34 = 0;
    v35 = AccessMode;
  }
  if( Buffer < 0 && Buffer != -1 )
  {
    if( EventObject )
      HalPutDmaAdapter((PADAPTER_OBJECT)EventObject);
    if( v34 )
      IopReleaseFileObjectLock(v15);
    goto LABEL_122;
  }
  IopResetEvent((_FILE_OBJECT *)v15);
  v36 = (_DEVICE_OBJECT *)CallersCaller;
  Irp = IopAllocateIrpExReturn((_DEVICE_OBJECT *)CallersCaller, *((_BYTE *)CallersCaller + 76), v34 ^ 1u, retaddr);
  v38 = Irp;
  Object = Irp;
  if( Irp )
  {
    Irp->Tail.OriginalFileObject = (_FILE_OBJECT *)v15;
    Irp->Tail.Thread = CurrentThread;
    Irp->Tail.AuxiliaryBuffer = 0i64;
    Irp->RequestorMode = v35;
    Irp->PendingReturned = 0;
    Irp->Cancel = 0;
    Irp->CancelRoutine = 0i64;
    Irp->UserEvent = (_KEVENT *)EventObject;
    v39 = a5;
    Irp->UserIosb = (_IO_STATUS_BLOCK *)a5;
    Irp->Overlay.UserApcRoutine = (void(__fastcall *)(void *, _IO_STATUS_BLOCK *, unsigned int))v71;
    Irp->Overlay.UserApcContext = (void *)v72;
    CurrentStackLocation = Irp->Tail.CurrentStackLocation;
    *(_DWORD *)&CurrentStackLocation[-1].MajorFunction = 4;
    CurrentStackLocation[-1].FileObject = (_FILE_OBJECT *)v15;
    if( (*p_Offset & 0x10) != 0 )
      CurrentStackLocation[-1].Flags = 4;
    Irp->AssociatedIrp.MasterIrp = 0i64;
    Irp->MdlAddress = 0i64;
    Irp->Flags = 0;
    if( Length )
    {
      Mdl = IoAllocateMdl(*(VOID **)Src, Length, 0, 1u, Irp);
      v43 = Mdl;
      if( !Mdl )
        RtlRaiseStatus(-1073741670);
      MajorFunction = CurrentStackLocation[-1].MajorFunction;
      LOBYTE(v42) = AccessMode;
      MmProbeAndLockSelectedPages(Mdl, (PFILE_SEGMENT_ELEMENT)Src, v42, IoReadAccess);
      if( (MmTrackLockedPages & 1) != 0 )
      {
        v45 = MajorFunction;
        v36 = (_DEVICE_OBJECT *)CallersCaller;
        MmUpdateMdlTracker(v43, *(VOID **)(*((_QWORD *)CallersCaller + 1) + 8 * v45 + 112), CallersCaller);
      }
      else
      {
        v36 = (_DEVICE_OBJECT *)CallersCaller;
      }
      v38->UserBuffer = *(void **)Src;
    }
    if( P )
      ExFreePoolWithTag(P, 0);
    v38->Flags |= (*v62 & 8 | 0x5000) >> 3;
    LODWORD(CurrentStackLocation[-1].Parameters.SecurityContext) = Length;
    CurrentStackLocation[-1].Parameters.Options = v59;
    *(_QWORD *)&CurrentStackLocation[-1].Parameters.FileAttributes = Buffer;
    v46 = *(_DWORD **)v15->gapD0;
    if( v46 && (*v46 & 0x10) != 0 )
      *(&CurrentStackLocation[-1].Parameters.Options + 1) = *(_DWORD *)(v39 + 8);
    return IopSynchronousServiceTail(v36, v38, (_FILE_OBJECT *)v15, 1u, AccessMode, v34, WriteTransfer);
  }
  else
  {
    IopAllocateIrpCleanup(v15, EventObject);
    if( P )
      ExFreePoolWithTag(P, 0);
    return -1073741670;
  }
}

Referenced by:

No references.