FsRtlNotifyFilterReportChangeLiteEx

void **__fastcall FsRtlNotifyFilterReportChangeLiteEx(
        volatile signed __int64 *a1,
        struct _REAL_NOTIFY_SYNC **a2,
        const VOID **a3,
        const VOID **a4,
        int a5,
        int a6,
        __int64 a7,
        __int64 a8,
        char a9,
        __int64 a10){
  void **result; 
  const VOID **v11; 
  struct _REAL_NOTIFY_SYNC **v12; 
  _ETHREAD *CurrentThread; 
  volatile signed __int64 v15; 
  struct _REAL_NOTIFY_SYNC *v16; 
  char *v17; 
  __int16 *v18; 
  char v19; 
  unsigned __int8(__fastcall *v20)(_QWORD, __int64, _QWORD); 
  unsigned __int8(__fastcall *v21)(_QWORD); 
  __int16 v22; 
  unsigned int v23; 
  char *v24; 
  char *v25; 
  unsigned int v26; 
  unsigned int v27; 
  _DWORD *v28; 
  __int64 v29; 
  __int64 v30; 
  __int64 v31; 
  VOID **PoolWithTag; 
  __int64 v33; 
  char *v34; 
  char *v35; 
  __int16 v36; 
  __int16 v37; 
  UINT64 BugCheckOnFailure; 
  UINT64 Priority; 
  char v40; 
  struct _REAL_NOTIFY_SYNC *v41; 
  PNOTIFY_SYNC NotifySync[4]; 
  char *v43; 
  __int64 v44; 
  void *retaddr; 

  result = &retaddr;
  v11 = a4;
  v12 = a2;
  if( *a2 == (struct _REAL_NOTIFY_SYNC *)a2 )
    return result;
  result = (void **)a10;
  if( a10 )
  {
    if( *(_DWORD *)a10 < 0x50u )
      return result;
  }
  if( !*a1 )
  {
    NotifySync[0] = 0i64;
    FsRtlNotifyInitializeSync((INT64 *)NotifySync);
    if( _InterlockedCompareExchange64(a1, (signed __int64)NotifySync[0], 0i64) )
      FsRtlNotifyUninitializeSync(NotifySync);
  }
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v15 = *a1;
  if( CurrentThread != *(_ETHREAD **)(*a1 + 56) )
  {
    ExAcquireFastMutexUnsafe(*(PFAST_MUTEX *)a1);
    *(_QWORD *)(*a1 + 56) = CurrentThread;
    v15 = *a1;
  }
  ++*(_DWORD *)(v15 + 64);
  v16 = *v12;
  while( 1 )
  {
    NotifySync[2] = v16;
    v41 = v16;
    if( v16 == (struct _REAL_NOTIFY_SYNC *)v12 )
      break;
    v17 = (char *)v16 - 32;
    NotifySync[1] = (struct _REAL_NOTIFY_SYNC *)((char *)v16 - 32);
    v44 = (__int64)v16 - 32;
    v18 = (__int16 *)((char *)v16 + 40);
    v19 = (unsigned __int8)*v18 >> 7;
    v40 = v19;
    if( (*((_DWORD *)v16 + 11) & a5) != 0
      && ((a9 & 1) != 0
       || (*v18 & 1) != 0
       && ((v20 = (unsigned __int8(__fastcall *)(_QWORD, __int64, _QWORD))*((_QWORD *)v17 + 2)) == 0i64
        || v20(*((_QWORD *)v17 + 1), a7, *((_QWORD *)v17 + 3)))) )
    {
      v21 = (unsigned __int8(__fastcall *)(_QWORD))*((_QWORD *)v17 + 8);
      if( !v21 || !a8 || v21(*((_QWORD *)v17 + 1)) )
      {
        v22 = *v18;
        if( (*v18 & 2) == 0 )
        {
          v23 = *((_DWORD *)v17 + 24);
          if( v23 )
          {
            v24 = 0i64;
            v43 = 0i64;
            if( *((_DWORD *)v17 + 25) )
            {
              v23 = *((_DWORD *)v17 + 25);
            }
            else
            {
              v25 = (char *)*((_QWORD *)v17 + 6);
              if( v25 != v17 + 48 )
              {
                v24 = v25 - 168;
                v43 = v25 - 168;
                v23 = *(_DWORD *)(*((_QWORD *)v25 + 2) + 8i64);
              }
            }
            v26 = *(unsigned __int16 *)a3 + (v19 != 0 ? 84 : 12);
            if( v11 )
              v26 += *(unsigned __int16 *)v11 + 2;
            v27 = (*((_DWORD *)v17 + 26) + 3) & 0xFFFFFFFC;
            if( v26 > v23 || v26 + v27 > v23 )
            {
              v36 = v22 | 2;
              *v18 = v36;
              v16 = v41;
            }
            else
            {
              v28 = 0i64;
              v29 = *((_QWORD *)v17 + 11);
              if( v29 )
              {
                *(_DWORD *)(v29 + *((unsigned int *)v17 + 27)) = v27 - *((_DWORD *)v17 + 27);
                *((_DWORD *)v17 + 27) = v27;
                v28 = (_DWORD *)(*((_QWORD *)v17 + 11) + v27);
              }
              else
              {
                if( !v24 )
                  goto LABEL_30;
                v30 = *((_QWORD *)v24 + 3);
                if( v30 )
                {
                  v28 = (_DWORD *)*((_QWORD *)v24 + 3);
                  *((_QWORD *)v17 + 11) = v30;
                }
                else
                {
                  v31 = *((_QWORD *)v24 + 1);
                  if( !v31 )
                    goto LABEL_30;
                  if( (*(_BYTE *)(v31 + 10) & 5) != 0 )
                  {
                    v28 = *(_DWORD **)(v31 + 24);
                  }
                  else
                  {
                    LODWORD(Priority) = 1073741840;
                    LODWORD(BugCheckOnFailure) = 0;
                    v28 = MmMapLockedPagesSpecifyCache((_MDL *)v31, 0, MmCached, 0i64, BugCheckOnFailure, Priority);
                  }
                  *((_QWORD *)v17 + 11) = v28;
                }
                *((_DWORD *)v17 + 25) = v23;
              }
LABEL_30:
              if( !*((_QWORD *)v17 + 11) )
              {
                PsChargePoolQuota(*((_EPROCESS **)v17 + 15), PagedPool, v23);
                PoolWithTag = ExAllocatePoolWithTag(0x11ui64, v23, 1316115270i64);
                *((_QWORD *)v17 + 11) = PoolWithTag;
                *((_QWORD *)v17 + 10) = PoolWithTag;
                *((_DWORD *)v17 + 25) = v23;
                v28 = (_DWORD *)*((_QWORD *)v17 + 11);
              }
              v16 = v41;
              if( v28 )
              {
                v33 = *((unsigned int *)v17 + 26);
                if( v27 > (unsigned int)v33 )
                  memset((VOID *)(*((_QWORD *)v17 + 11) + v33), 0i64, v27 - v33);
                *v28 = 0;
                v28[1] = a6;
                if( v40 )
                {
                  *((_QWORD *)v28 + 1) = *(_QWORD *)(a10 + 8);
                  *((_QWORD *)v28 + 2) = *(_QWORD *)(a10 + 16);
                  *((_QWORD *)v28 + 3) = *(_QWORD *)(a10 + 24);
                  *((_QWORD *)v28 + 4) = *(_QWORD *)(a10 + 32);
                  *((_QWORD *)v28 + 5) = *(_QWORD *)(a10 + 40);
                  *((_QWORD *)v28 + 6) = *(_QWORD *)(a10 + 48);
                  v28[14] = *(_DWORD *)(a10 + 56);
                  v28[15] = *(_DWORD *)(a10 + 60);
                  *((_QWORD *)v28 + 8) = *(_QWORD *)(a10 + 64);
                  *((_QWORD *)v28 + 9) = *(_QWORD *)(a10 + 72);
                  v28[20] = v26 - 84;
                  v34 = (char *)(v28 + 21);
                }
                else
                {
                  v28[2] = v26 - 12;
                  v34 = (char *)(v28 + 3);
                }
                memmove(v34, a3[1], *(unsigned __int16 *)a3);
                if( a4 )
                {
                  v35 = &v34[*(unsigned __int16 *)a3];
                  *(_WORD *)v35 = 58;
                  memmove(v35 + 2, a4[1], *(unsigned __int16 *)a4);
                }
                *((_DWORD *)v17 + 26) = v26 + v27;
              }
              v18 = (__int16 *)(v44 + 72);
              v36 = *(_WORD *)(v44 + 72);
            }
            if( (v36 & 2) != 0 && *((_QWORD *)v17 + 11) )
            {
              if( *((_QWORD *)v17 + 10) )
              {
                PsReturnProcessPagedPoolQuota(*((_QWORD *)v17 + 15), *((_DWORD *)v17 + 25));
                ExFreePoolWithTag(*((PVOID *)v17 + 10), 0);
              }
              *((_QWORD *)v17 + 11) = 0i64;
              *((_QWORD *)v17 + 10) = 0i64;
              *((_QWORD *)v17 + 13) = 0i64;
              *((_DWORD *)v17 + 25) = 0;
            }
            v11 = a4;
          }
          else
          {
            v16 = v41;
          }
        }
        v37 = *v18;
        if( a6 == 4 )
        {
          *v18 = v37 | 8;
        }
        else
        {
          *v18 = v37 & 0xFFF7;
          if( *((char **)v17 + 6) != v17 + 48 )
            FsRtlNotifyCompleteIrpList((_NOTIFY_CHANGE_LITE *)v17, 0);
        }
      }
    }
    v16 = *(struct _REAL_NOTIFY_SYNC **)v16;
    v12 = a2;
  }
  --*(_DWORD *)(*a1 + 64);
  result = (void **)*a1;
  if( !*(_DWORD *)(*a1 + 64) )
  {
    result[7] = 0i64;
    return(void **)ExReleaseFastMutexUnsafe(*(PFAST_MUTEX *)a1);
  }
  return result;
}

Referenced by:

FsRtlNotifyFilterReportChangeLite