FsRtlNotifyFilterReportChange

void __stdcall FsRtlNotifyFilterReportChange(
        PNOTIFY_SYNC NotifySync,
        PLIST_ENTRY NotifyList,
        PSTRING FullTargetName,
        USHORT TargetNameOffset,
        PSTRING StreamName,
        PSTRING NormalizedParentName,
        ULONG FilterMatch,
        ULONG Action,
        PVOID TargetContext,
        PVOID FilterContext){
  USHORT v10; 
  PSTRING v11; 
  USHORT v13; 
  _ETHREAD *CurrentThread; 
  _LIST_ENTRY *Flink; 
  INT64 v16; 
  _LIST_ENTRY *v17; 
  char v18; 
  char v19; 
  __int16 v20; 
  unsigned int v21; 
  __int64 v22; 
  unsigned __int16 v23; 
  int v24; 
  unsigned int v25; 
  unsigned int v26; 
  FILE_NOTIFY_INFORMATION *v27; 
  __int64 v28; 
  __int64 v29; 
  __int64 v30; 
  VOID *PoolWithTag; 
  __int64 v32; 
  _LIST_ENTRY *v33; 
  __int16 v34; 
  __int16 v35; 
  unsigned __int16 *v36; 
  unsigned __int16 v37; 
  unsigned __int16 *v38; 
  PSTRING v39; 
  USHORT v40; 
  __int16 v41; 
  __int16 v42; 
  char *v43; 
  bool v44; 
  unsigned __int8(__fastcall *v45)(_QWORD, PVOID, _QWORD); 
  unsigned __int8(__fastcall *v46)(_QWORD, PVOID); 
  __int16 v47; 
  char *v48; 
  int v49; 
  int v50; 
  USHORT v51; 
  __int16 v52; 
  char v53; 
  int v54; 
  int v55; 
  unsigned int v56; 
  int v57; 
  _LIST_ENTRY *Blink; 
  __int64 v59; 
  int v60; 
  int v61; 
  UINT64 SizeOfEntry; 
  char v63; 
  USHORT v64; 
  unsigned __int16 Length; 
  unsigned __int16 v67; 
  unsigned int v68; 
  _LIST_ENTRY *v69; 
  _LIST_ENTRY *v70; 
  STRING OemString; 
  int v72; 
  __int64 v73; 
  char *Buffer; 
  STRING TargetName; 
  unsigned int v76; 
  unsigned int v77; 
  __int64 v78; 
  _LIST_ENTRY *v79; 
  _LIST_ENTRY *v80; 
  _OWORD v81[6]; 
  _LIST_ENTRY *v83; 
  v83 = NotifyList;
  v10 = TargetNameOffset;
  v11 = FullTargetName;
  v13 = TargetNameOffset;
  v81[0] = 0i64;
  v73 = 0i64;
  *(_QWORD *)&TargetName.Length = 0i64;
  OemString = 0i64;
  v63 = 0;
  v72 = 0;
  if( !TargetNameOffset && v11 )
    return;
  Buffer = 0i64;
  TargetName.Buffer = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  if( CurrentThread != *((_ETHREAD **)NotifySync + 7) )
  {
    ExAcquireFastMutexUnsafe((PFAST_MUTEX)NotifySync);
    *((_QWORD *)NotifySync + 7) = CurrentThread;
    v13 = v10;
    NotifyList = v83;
  }
  ++*((_DWORD *)NotifySync + 16);
  Flink = NotifyList->Flink;
  v64 = v73;
  Length = TargetName.Length;
  v67 = OemString.Length;
  while( 1 )
  {
    v80 = Flink;
    v70 = Flink;
    if( Flink == NotifyList )
      break;
    v16 = (INT64)&Flink[-2];
    v79 = Flink - 2;
    v17 = Flink - 2;
    v69 = Flink - 2;
    if( v11 )
    {
      v36 = *(unsigned __int16 **)(v16 + 136);
      v37 = *v36;
      if( *v36 && (*(_DWORD *)(v16 + 76) & FilterMatch) != 0 )
      {
        v38 = *(unsigned __int16 **)(v16 + 136);
        v39 = NormalizedParentName;
        if( !NormalizedParentName )
        {
          *((_QWORD *)&v81[0] + 1) = v11->Buffer;
          v40 = v10;
          LOWORD(v81[0]) = v10;
          v41 = *(unsigned __int8 *)(v16 + 144);
          if( v13 != v41 )
          {
            v40 = v13 - v41;
            LOWORD(v81[0]) = v13 - v41;
          }
          WORD1(v81[0]) = v40;
          v39 = (PSTRING)v81;
          NormalizedParentName = (PSTRING)v81;
          v36 = *(unsigned __int16 **)(v16 + 136);
          v38 = v36;
          v37 = *v36;
        }
        if( v37 <= v39->Length )
        {
          if( v37 == v39->Length )
          {
            v19 = 1;
            goto LABEL_60;
          }
          v42 = *(_WORD *)(v16 + 72);
          if( (v42 & 1) != 0 )
          {
            if( (v42 & 0x10) != 0
              || ((v43 = &v39->Buffer[*v38], *(_BYTE *)(v16 + 144) != 1) ? (v44 = *(_WORD *)v43 == 92) : (v44 = *v43 == 92),
                  v44) )
            {
              v19 = 0;
LABEL_60:
              if( !memcmp(*((PVOID *)v36 + 1), v39->Buffer, v37)
                && (v19
                 || (v45 = *(unsigned __int8(__fastcall **)(_QWORD, PVOID, _QWORD))(v16 + 16)) == 0i64
                 || v45(*(_QWORD *)(v16 + 8), TargetContext, *(_QWORD *)(v16 + 24))) )
              {
                v46 = *(unsigned __int8(__fastcall **)(_QWORD, PVOID))(v16 + 64);
                if( !v46 || !FilterContext || v46(*(_QWORD *)(v16 + 8), FilterContext) )
                {
                  v17 = Flink - 2;
                  v18 = v63;
LABEL_10:
                  v20 = *(_WORD *)(v16 + 72);
                  if( (v20 & 2) != 0 )
                  {
                    v33 = Flink - 2;
                  }
                  else
                  {
                    v21 = *(_DWORD *)(v16 + 96);
                    if( v21 )
                    {
                      v78 = 0i64;
                      if( *(_DWORD *)(v16 + 100) )
                      {
                        v21 = *(_DWORD *)(v16 + 100);
                      }
                      else
                      {
                        v22 = *(_QWORD *)(v16 + 48);
                        if( v22 != v16 + 48 )
                        {
                          v78 = v22 - 168;
                          v21 = *(_DWORD *)(*(_QWORD *)(v22 - 168 + 184) + 8i64);
                        }
                      }
                      if( v19 )
                      {
                        v23 = 0;
                        v67 = 0;
                        OemString.Length = 0;
                      }
                      else if( v18 )
                      {
                        v23 = v67;
                      }
                      else
                      {
                        v47 = v20 & 0x10;
                        if( v47 || (v48 = NormalizedParentName->Buffer, v48 != v11->Buffer) )
                        {
                          if( Buffer )
                          {
                            v51 = v64;
                          }
                          else
                          {
                            Buffer = v11->Buffer;
                            v51 = v10;
                            v64 = v10;
                            LOWORD(v73) = v10;
                            v52 = *(unsigned __int8 *)(v16 + 144);
                            if( TargetNameOffset != v52 )
                            {
                              v51 = TargetNameOffset - v52;
                              v64 = TargetNameOffset - v52;
                              LOWORD(v73) = TargetNameOffset - v52;
                            }
                            WORD1(v73) = v51;
                          }
                          v53 = 0;
                          v54 = 0;
                          if( v47 )
                          {
                            v59 = (__int64)Buffer;
                          }
                          else
                          {
                            v55 = 1;
                            v56 = 0;
                            v57 = *(unsigned __int8 *)(v16 + 144);
                            Blink = v17[8].Blink;
                            if( (_BYTE)v57 == 1 )
                            {
                              while( v56 < LOWORD(Blink->Flink) )
                              {
                                if( *((_BYTE *)&Blink->Blink->Flink + v56) == 92 )
                                  ++v55;
                                ++v56;
                              }
                              v59 = (__int64)Buffer;
                              while( Buffer[v54] != 92 || (unsigned __int8)++v53 != v55 )
                                ++v54;
                            }
                            else
                            {
                              while( v56 < LOWORD(Blink->Flink) >> 1 )
                              {
                                if( *((_WORD *)&Blink->Blink->Flink + v56) == 92 )
                                  ++v55;
                                ++v56;
                              }
                              v59 = (__int64)Buffer;
                              while( *(_WORD *)&Buffer[2 * v54] != 92 || (unsigned __int8)++v53 != v55 )
                                ++v54;
                              v54 *= v57;
                            }
                            v51 = v64;
                          }
                          v68 = *(unsigned __int8 *)(v16 + 144) + v54;
                          OemString.Buffer = (char *)(v59 + v68);
                          v23 = v51 - v68;
                        }
                        else
                        {
                          v49 = **(unsigned __int16 **)(v16 + 136);
                          v50 = *(unsigned __int8 *)(v16 + 144);
                          OemString.Buffer = &v48[v50 + v49];
                          v23 = NormalizedParentName->Length - v50 - v49;
                        }
                        v67 = v23;
                        OemString.Length = v23;
                        OemString.MaximumLength = v23;
                      }
                      v24 = 12;
                      if( v63 )
                      {
                        v25 = StreamName->Length + 12;
                      }
                      else
                      {
                        if( !v19 )
                        {
                          if( *(_BYTE *)(v16 + 144) == 1 )
                            v60 = RtlxOemStringToUnicodeSize(&OemString) + 10;
                          else
                            v60 = v23 + 12;
                          v24 = v60 + 2;
                        }
                        if( TargetName.Buffer )
                        {
                          LOWORD(v61) = Length;
                        }
                        else
                        {
                          TargetName.Buffer = &v11->Buffer[TargetNameOffset];
                          LOWORD(v61) = v11->Length - TargetNameOffset;
                          Length = v61;
                          TargetName.Length = v61;
                          TargetName.MaximumLength = v61;
                        }
                        if( *(_BYTE *)(v16 + 144) == 1 )
                          v61 = RtlxOemStringToUnicodeSize(&TargetName) - 2;
                        else
                          v61 = (unsigned __int16)v61;
                        v25 = v61 + v24;
                        if( StreamName )
                        {
                          if( *(_BYTE *)(v16 + 144) == 2 )
                            v25 += StreamName->Length + 2;
                          else
                            v25 += RtlxOemStringToUnicodeSize(StreamName);
                        }
                      }
                      v26 = (*(_DWORD *)(v16 + 104) + 3) & 0xFFFFFFFC;
                      v76 = v26;
                      if( v25 > v21 || (v77 = v26 + v25, v26 + v25 > v21) )
                      {
                        *(_WORD *)(v16 + 72) |= 2u;
                        v34 = *(_WORD *)(v16 + 72);
                        v33 = (_LIST_ENTRY *)v16;
                      }
                      else
                      {
                        v27 = 0i64;
                        v28 = *(_QWORD *)(v16 + 88);
                        if( v28 )
                        {
                          *(_DWORD *)(v28 + *(unsigned int *)(v16 + 108)) = v26 - *(_DWORD *)(v16 + 108);
                          *(_DWORD *)(v16 + 108) = v26;
                          v27 = (FILE_NOTIFY_INFORMATION *)(*(_QWORD *)(v16 + 88) + v26);
                        }
                        else
                        {
                          if( !v78 )
                            goto LABEL_26;
                          v29 = *(_QWORD *)(v78 + 24);
                          if( v29 )
                          {
                            v27 = *(FILE_NOTIFY_INFORMATION **)(v78 + 24);
                            *(_QWORD *)(v16 + 88) = v29;
                          }
                          else
                          {
                            v30 = *(_QWORD *)(v78 + 8);
                            if( !v30 )
                              goto LABEL_26;
                            if( (*(_BYTE *)(v30 + 10) & 5) != 0 )
                              v27 = *(FILE_NOTIFY_INFORMATION **)(v30 + 24);
                            else
                              v27 = (FILE_NOTIFY_INFORMATION *)MmMapLockedPagesSpecifyCache(
                                                                 (PMDL)v30,
                                                                 0,
                                                                 MmCached,
                                                                 0i64,
                                                                 0,
                                                                 0x40000010u);
                            *(_QWORD *)(v16 + 88) = v27;
                          }
                          *(_DWORD *)(v16 + 100) = v21;
                        }
LABEL_26:
                        if( !*(_QWORD *)(v16 + 88) )
                        {
                          PsChargePoolQuota(*(PEPROCESS *)(v16 + 120), PagedPool, v21);
                          PoolWithTag = ExAllocatePoolWithTag((_POOL_TYPE)17, v21, 0x4E725346ui64);
                          *(_QWORD *)(v16 + 88) = PoolWithTag;
                          *(_QWORD *)(v16 + 80) = PoolWithTag;
                          *(_DWORD *)(v16 + 100) = v21;
                          v27 = *(FILE_NOTIFY_INFORMATION **)(v16 + 88);
                        }
                        if( v27 )
                        {
                          v32 = *(unsigned int *)(v16 + 104);
                          if( v26 > (unsigned int)v32 )
                            memset(*(_QWORD *)(v16 + 88) + v32, 0i64);
                          LODWORD(SizeOfEntry) = v25;
                          if( FsRtlNotifyUpdateBuffer(
                                 v27,
                                 Action,
                                 &OemString,
                                 &TargetName,
                                 StreamName,
                                 *(_BYTE *)(v16 + 144) == 2,
                                 SizeOfEntry) )
                          {
                            *(_DWORD *)(v16 + 104) = v26 + v25;
                          }
                          else
                          {
                            *(_WORD *)(v16 + 72) |= 2u;
                          }
                        }
                        v33 = v69;
                        v34 = (__int16)v69[4].Blink;
                      }
                      if( (v34 & 2) != 0 && *(_QWORD *)(v16 + 88) )
                      {
                        if( *(_QWORD *)(v16 + 80) )
                        {
                          PsReturnProcessPagedPoolQuota(*(_QWORD *)(v16 + 120), *(unsigned int *)(v16 + 100));
                          ExFreePoolWithTag(*(PVOID *)(v16 + 80), 0);
                        }
                        *(_QWORD *)(v16 + 88) = 0i64;
                        *(_QWORD *)(v16 + 80) = 0i64;
                        *(_QWORD *)(v16 + 104) = 0i64;
                        *(_DWORD *)(v16 + 100) = 0;
                      }
                      v11 = FullTargetName;
                      v10 = TargetNameOffset;
                    }
                    else
                    {
                      v33 = (_LIST_ENTRY *)v16;
                    }
                    Flink = v70;
                  }
                  v35 = (__int16)v33[4].Blink;
                  if( Action == 4 )
                  {
                    LOWORD(v33[4].Blink) = v35 | 8;
                  }
                  else
                  {
                    LOWORD(v33[4].Blink) = v35 & 0xFFF7;
                    if( *(_QWORD *)(v16 + 48) != v16 + 48 )
                      FsRtlNotifyCompleteIrpList(v16, 0i64);
                  }
                }
              }
            }
          }
        }
        NotifyList = v83;
      }
    }
    else if( TargetContext == *(PVOID *)(v16 + 24) )
    {
      OemString.Buffer = 0i64;
      v67 = 0;
      OemString.Length = 0;
      v18 = 1;
      v63 = 1;
      v19 = 0;
      goto LABEL_10;
    }
    Flink = Flink->Flink;
    v13 = TargetNameOffset;
  }
  v44 = (*((_DWORD *)NotifySync + 16))-- == 1;
  if( v44 )
  {
    *((_QWORD *)NotifySync + 7) = 0i64;
    ExReleaseFastMutexUnsafe((PFAST_MUTEX)NotifySync);
  }
}

Referenced by:

FsRtlNotifyFullReportChange
FsRtlNotifyReportChange