IopFileUtilWalkDirectoryTreeHelper

NTSTATUS __stdcall IopFileUtilWalkDirectoryTreeHelper(
        INT64 a1,
        INT64 a2,
        INT64 a3,
        INT64 a4,
        PVOID FileInformation,
        INT64 a6,
        INT64 a7){
  char v7; 
  _WORD *v8; 
  int DirectoryFile; 
  unsigned int *v11; 
  unsigned int *v12; 
  unsigned __int64 v13; 
  __int16 v14; 
  const wchar_t *i; 
  __int64 v16; 
  bool v17; 
  _UNICODE_STRING **v18; 
  __int64 v19; 
  unsigned __int64 v20; 
  __int64 v21; 
  _UNICODE_STRING *PoolWithTag; 
  UINT64 ShareAccess; 
  _IO_STATUS_BLOCK *ShareAccessa; 
  UINT64 OpenOptions; 
  PVOID OpenOptionsa; 
  int Length; 
  int FileInformationClass; 
  int ReturnSingleEntry; 
  PUNICODE_STRING FileName; 
  int v31; 
  VOID *FileHandle; 
  unsigned int *v33; 
  _UNICODE_STRING Source; 
  _IO_STATUS_BLOCK IoStatusBlock; 
  _OBJECT_ATTRIBUTES ObjectAttributes; 
  __int16 v38; 

  ObjectAttributes.ObjectName = (_UNICODE_STRING *)a1;
  *(_QWORD *)&ObjectAttributes.Length = 48i64;
  *(_QWORD *)&ObjectAttributes.Attributes = 576i64;
  v7 = a2;
  v8 = (_WORD *)a1;
  LODWORD(OpenOptions) = ~((_DWORD)a2 << 17) & 0x200000 | 0x4001;
  LODWORD(ShareAccess) = 1;
  FileHandle = 0i64;
  ObjectAttributes.RootDirectory = 0i64;
  IoStatusBlock = 0i64;
  Source = 0i64;
  *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
  DirectoryFile = ZwOpenFile(&FileHandle, 0x100001ui64, &ObjectAttributes, &IoStatusBlock, ShareAccess, OpenOptions);
  if( DirectoryFile < 0 )
    return DirectoryFile;
  v11 = (unsigned int *)FileInformation;
  LOBYTE(v31) = 1;
  FileName = 0i64;
  LOBYTE(ReturnSingleEntry) = 0;
  FileInformationClass = 3;
  Length = 1022;
  OpenOptionsa = FileInformation;
  ShareAccessa = &IoStatusBlock;
  DirectoryFile = ZwQueryDirectoryFile((UINT64)FileHandle, 0i64);
  if( DirectoryFile < 0 )
    goto LABEL_34;
  while( 2 )
  {
    if( DirectoryFile == 259 )
    {
      ZwWaitForSingleObject((UINT64)FileHandle, 1, 0i64);
      DirectoryFile = IoStatusBlock.Status;
      if( IoStatusBlock.Status < 0 )
        break;
    }
    v12 = v11;
    v33 = v11 + 15;
    v13 = (unsigned __int64)v11[15] >> 1;
    v14 = *((_WORD *)v11 + v13 + 47);
    *((_WORD *)v11 + v13 + 47) = 0;
    for( i = (const wchar_t *)v11 + 47; ; i = (const wchar_t *)v12 + 47 )
    {
      v38 = v14;
      RtlInitUnicodeString(&Source, i);
      v21 = (unsigned __int16)(Source.Length + *v8 + 2);
      PoolWithTag = (_UNICODE_STRING *)ExAllocatePoolWithTag(1ui64, (unsigned __int16)v21 + 38i64, 1967550281i64);
      if( !PoolWithTag )
        break;
      PoolWithTag[1].MaximumLength = v21;
      v8 = (_WORD *)a1;
      PoolWithTag[1].Buffer = &PoolWithTag[2].Length;
      PoolWithTag[1].Length = 0;
      RtlCopyUnicodeString(PoolWithTag + 1, (PCUNICODE_STRING)a1);
      RtlAppendUnicodeToString(PoolWithTag + 1, (WCHAR *)L"\\");
      RtlAppendUnicodeStringToString(PoolWithTag + 1, &Source);
      v16 = v12[14];
      if( (v16 & 0x10) != 0 )
      {
        v17 = !wcsicmp(i, L".") || !wcsicmp(i, L"..");
        if( (v7 & 2) != 0 )
        {
          if( (v7 & 4) == 0 || !v17 )
          {
            DirectoryFile = ((__int64(__fastcall *)(_UNICODE_STRING *, _UNICODE_STRING *, _QWORD, INT64))a3)(
                              &PoolWithTag[1],
                              &Source,
                              v12[14],
                              a4);
            goto LABEL_16;
          }
LABEL_20:
          ExFreePoolWithTag(PoolWithTag, 0);
        }
        else
        {
LABEL_16:
          if( v17 || (v7 & 8) == 0 )
            goto LABEL_20;
          v18 = *(_UNICODE_STRING ***)(a7 + 8);
          if( *v18 != (_UNICODE_STRING *)a7 )
            __fastfail(3u);
          *(_QWORD *)&PoolWithTag->Length = a7;
          PoolWithTag->Buffer = (wchar_t *)v18;
          *v18 = PoolWithTag;
          *(_QWORD *)(a7 + 8) = PoolWithTag;
        }
        v8 = (_WORD *)a1;
        goto LABEL_25;
      }
      if( (v7 & 1) != 0 )
        DirectoryFile = ((__int64(__fastcall *)(_UNICODE_STRING *, _UNICODE_STRING *, __int64, INT64, _IO_STATUS_BLOCK *, PVOID, int, int, int, PUNICODE_STRING, int))a3)(
                          &PoolWithTag[1],
                          &Source,
                          v16,
                          a4,
                          ShareAccessa,
                          OpenOptionsa,
                          Length,
                          FileInformationClass,
                          ReturnSingleEntry,
                          FileName,
                          v31);
      ExFreePoolWithTag(PoolWithTag, 0);
LABEL_25:
      if( DirectoryFile < 0 )
        goto LABEL_34;
      *((_WORD *)v12 + ((unsigned __int64)*v33 >> 1) + 47) = v38;
      v19 = *v12;
      if( !(_DWORD)v19 )
        goto LABEL_30;
      v12 = (unsigned int *)((char *)v12 + v19);
      v33 = v12 + 15;
      v20 = (unsigned __int64)v12[15] >> 1;
      v14 = *((_WORD *)v12 + v20 + 47);
      *((_WORD *)v12 + v20 + 47) = 0;
    }
    DirectoryFile = -1073741670;
LABEL_30:
    if( DirectoryFile >= 0 )
    {
      v11 = (unsigned int *)FileInformation;
      LOBYTE(v31) = 0;
      FileName = 0i64;
      LOBYTE(ReturnSingleEntry) = 0;
      FileInformationClass = 3;
      Length = 1022;
      OpenOptionsa = FileInformation;
      ShareAccessa = &IoStatusBlock;
      DirectoryFile = ZwQueryDirectoryFile((UINT64)FileHandle, 0i64);
      if( DirectoryFile >= 0 )
      {
        v8 = (_WORD *)a1;
        continue;
      }
    }
    break;
  }
LABEL_34:
  ZwClose((_HANDLE)FileHandle);
  if( DirectoryFile == -2147483642 )
    return 0;
  return DirectoryFile;
}

Referenced by:

IopFileUtilWalkDirectoryTreeBottomUp
IopFileUtilWalkDirectoryTreeTopDown