NtNotifyChangeDirectoryFileEx

NTSTATUS __stdcall NtNotifyChangeDirectoryFileEx(
        VOID *Handle,
        VOID *rdx0,
        INT64 a3,
        INT64 a4,
        UINT64 *a5,
        VOID *Address,
        UINT64 Length,
        INT64 a8,
        CHAR a9,
        INT64 a10){
  INT8 PreviousMode; 
  __int64 v13; 
  size_t v14; 
  UINT8 v15; 
  NTSTATUS result; 
  _ADAPTER_OBJECT *v17; 
  int v18; 
  _DEVICE_OBJECT *v19; 
  _DEVICE_OBJECT *v20; 
  _IRP *Irp; 
  _IRP *v22; 
  _IO_STACK_LOCATION *CurrentStackLocation; 
  __int64 v24; 
  unsigned int Flags; 
  char v26; 
  bool v27; 
  _ETHREAD *v28; 
  _FILE_OBJECT *v29; 
  _BYTE *v30; 
  VOID *PoolWithQuota; 
  _MDL *Mdl; 
  __int64 v33; 
  INT64 v34; 
  _FILE_OBJECT *pFileObject; 
  PVOID EventObject; 
  PVOID Object; 
  _ETHREAD *CurrentThread; 
  VOID *retaddr; 
  INT64 v40; 
  INT64 v41; 

  v41 = a4;
  v40 = a3;
  pFileObject = 0i64;
  EventObject = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  PreviousMode = CurrentThread->Tcb.PreviousMode;
  if( PreviousMode )
  {
    v13 = (__int64)a5;
    if( (unsigned __int64)a5 >= 0x7FFFFFFF0000i64 )
      v13 = 0x7FFFFFFF0000i64;
    *(_DWORD *)v13 = *(_DWORD *)v13;
    v14 = Length;
    if( (_DWORD)Length )
      ProbeForWrite((UINT64)Address, (unsigned int)Length, 4i64);
    if( (a8 & 0xFFFFF000) != 0 || !(_DWORD)a8 )
      return -1073741811;
  }
  else
  {
    v14 = Length;
  }
  v15 = 1;
  result = IopReferenceFileObject(Handle, 1ui64, PreviousMode, &pFileObject, 0i64);
  if( result >= 0 )
  {
    v17 = (_ADAPTER_OBJECT *)pFileObject;
    if( pFileObject->CompletionContext && (v40 & 0xFFFFFFFFFFFFFFFEui64) != 0 )
    {
      v18 = -1073741811;
      goto LABEL_39;
    }
    if( rdx0 )
    {
      Object = 0i64;
      v18 = ObReferenceObjectByHandle(rdx0, 2ui64, (_OBJECT_TYPE *)ExEventObjectType, PreviousMode, &Object, 0i64);
      EventObject = Object;
      if( v18 < 0 )
      {
LABEL_39:
        HalPutDmaAdapter(v17);
        return v18;
      }
      KeResetEvent((_KEVENT *)Object);
    }
    if( (v17->AdapterObject.ScatterTranslationEnd.Offset & 2) != 0 )
    {
      v27 = (v17->AdapterObject.ScatterTranslationEnd.Offset & 4) != 0;
      v28 = (_ETHREAD *)KeGetCurrentThread();
      --v28->Tcb.KernelApcDisable;
      v29 = pFileObject;
      v30 = KeAbPreAcquire(pFileObject->gap80, 0i64, 0i64);
      LOBYTE(v34) = 0;
      if( _InterlockedExchange((volatile __int32 *)&v29->Busy, 1) )
      {
        v17 = (_ADAPTER_OBJECT *)pFileObject;
        v18 = IopWaitAndAcquireFileObjectLock(pFileObject, PreviousMode, v27, v30, (INT64)&v34);
      }
      else
      {
        if( v30 )
          v30[26] |= 1u;
        v17 = (_ADAPTER_OBJECT *)pFileObject;
        ObfReferenceObject(pFileObject);
        v18 = 0;
      }
      if( (_BYTE)v34 )
      {
        if( EventObject )
          HalPutDmaAdapter((PADAPTER_OBJECT)EventObject);
        goto LABEL_39;
      }
      LOBYTE(v34) = 1;
    }
    else
    {
      v15 = 0;
      LOBYTE(v34) = 0;
      if( PreviousMode )
        IopMarkApcRoutineIfAsynchronousIo32(&a5, &v40, 0);
    }
    IopResetEvent((_FILE_OBJECT *)v17);
    LODWORD(v19) = IoGetRelatedDeviceObject((INT64)v17);
    v20 = v19;
    Irp = IopAllocateIrpExReturn(v19, v19->StackSize, v15 ^ 1u, retaddr);
    v22 = Irp;
    Object = Irp;
    if( !Irp )
    {
      IopAllocateIrpCleanup(v17, EventObject);
      return -1073741670;
    }
    Irp->Tail.OriginalFileObject = (_FILE_OBJECT *)v17;
    Irp->Tail.Thread = CurrentThread;
    Irp->RequestorMode = PreviousMode;
    Irp->UserEvent = (_KEVENT *)EventObject;
    Irp->UserIosb = (_IO_STATUS_BLOCK *)a5;
    Irp->Overlay.UserApcRoutine = (void(__fastcall *)(void *, _IO_STATUS_BLOCK *, unsigned int))v40;
    Irp->Overlay.UserApcContext = (void *)v41;
    CurrentStackLocation = Irp->Tail.CurrentStackLocation;
    CurrentStackLocation[-1].MajorFunction = 12;
    v24 = (unsigned int)a10;
    CurrentStackLocation[-1].MinorFunction = ((_DWORD)a10 == 2) + 2;
    CurrentStackLocation[-1].FileObject = (_FILE_OBJECT *)v17;
    if( !v14 )
      goto LABEL_21;
    Flags = v20->Flags;
    if( (Flags & 4) != 0 )
    {
      PoolWithQuota = IopVerifierExAllocatePoolWithQuota(v24, v14);
      v22->AssociatedIrp.MasterIrp = (_IRP *)PoolWithQuota;
      if( !*(&stru_140CF2E80 + 1657) )
        memset(PoolWithQuota, 0i64, v14);
      v22->Flags = 112;
      v15 = v34;
      LODWORD(v24) = a10;
    }
    else if( (Flags & 0x10) != 0 )
    {
      Mdl = IoAllocateMdl(Address, v14, 0, 1u, v22);
      if( !Mdl )
        RtlRaiseStatus(-1073741670);
      IopProbeAndLockPages_1(Mdl, PreviousMode, v33, v20, CurrentStackLocation[-1].MajorFunction);
      LODWORD(v24) = a10;
      goto LABEL_21;
    }
    v22->UserBuffer = Address;
LABEL_21:
    LODWORD(CurrentStackLocation[-1].Parameters.SecurityContext) = v14;
    CurrentStackLocation[-1].Parameters.Options = a8;
    if( CurrentStackLocation[-1].MinorFunction == 3 )
      *(_DWORD *)&CurrentStackLocation[-1].Parameters.FileAttributes = v24;
    CurrentStackLocation[-1].Flags = 0;
    v26 = CurrentStackLocation[-1].Flags;
    if( a9 )
      v26 = 1;
    CurrentStackLocation[-1].Flags = v26;
    return IopSynchronousServiceTail(v20, v22, (_FILE_OBJECT *)v17, 0, PreviousMode, v15, OtherTransfer);
  }
  return result;
}

Referenced by:

NtNotifyChangeDirectoryFile