CmpEnumerateAllHigherLayerKcbs

void **__fastcall CmpEnumerateAllHigherLayerKcbs(
        __int64 a1,
        unsigned int (__fastcall *a2)(ULONG_PTR, __int64),
        unsigned int (__fastcall *a3)(ULONG_PTR, __int64, __int64),
        __int64 a4,
        __int64 a5,
        char a6,
        char a7){
  void **result; 
  void **v8; 
  bool v9; 
  unsigned int(__fastcall *v11)(ULONG_PTR, __int64, __int64); 
  void **v13; 
  char v14; 
  ULONG_PTR v15; 
  void **v16; 
  void *retaddr; 
  result = &retaddr;
  v8 = *(void ***)(a1 + 192);
  v9 = 0;
  v11 = a3;
  if( v8 )
  {
    v13 = (void **)v8[4];
    result = v8 + 4;
    v14 = 0;
    if( v13 != v8 + 4 )
    {
      while( v13 == v8 + 4 )
      {
        v13 = v8;
        v14 = 1;
        v8 = (void **)v8[3];
LABEL_19:
        result = (void **)(*(_QWORD *)(a1 + 192) + 32i64);
        if( v13 == result )
          return result;
      }
      v15 = (ULONG_PTR)v13[2];
      v16 = v13;
      if( v14 )
      {
        v13 = (void **)*v13;
        if( !v9 )
          v9 = v11(v15, a4, a5) == 1;
        if( a6 )
          CmpDereferenceKeyControlBlockWithLock(v15, a4, 0);
        else
          CmpUnlockKcb(v15);
        if( v9 )
        {
          v13 = v8;
          v14 = 1;
          v8 = (void **)v8[3];
          goto LABEL_18;
        }
      }
      else
      {
        if( a6 )
        {
          CmpReferenceKeyControlBlock((UINT64)v13[2]);
        }
        else if( a7 )
        {
          CmpLockKcbExclusive((__int64)v13[2]);
        }
        else
        {
          ExAcquirePushLockSharedEx(v15 + 48, 0i64);
          _InterlockedIncrement((volatile signed __int32 *)(v15 + 56));
        }
        if( a2(v15, a5) == 1 )
        {
          v13 = (void **)v13[4];
          v8 = v16;
        }
        else
        {
          v13 = (void **)*v13;
          if( a6 )
            CmpDereferenceKeyControlBlockWithLock(v15, a4, 0);
          else
            CmpUnlockKcb(v15);
        }
      }
      v14 = 0;
LABEL_18:
      v11 = a3;
      goto LABEL_19;
    }
  }
  return result;
}

Referenced by:

CmRestoreKey
CmpCleanupDiscardReplaceContext
CmpCommitDiscardAndReplaceKcbAndUnbackedHigherLayers
CmpFlushNotifiesOnAllUnbackedHigherLayerKcbs
CmpInvalidateAllHigherLayerKcbs
CmpPrepareDiscardAndReplaceKcbAndUnbackedHigherLayers
CmpPrepareToInvalidateAllHigherLayerKcbs