PsDereferenceVsmEnclave

INT64 __stdcall PsDereferenceVsmEnclave(PVOID P){
  signed __int64 v2; 
  bool v3; 
  INT64 result; 
  _QWORD *v5; 
  _QWORD *v6; 
  _QWORD *v7; 
  void *v8; 
  v2 = _InterlockedExchangeAdd64((volatile signed __int64 *)P + 2, 0xFFFFFFFFFFFFFFFFui64);
  v3 = v2 <= 1;
  result = v2 - 1;
  if( v3 )
  {
    if( result )
      __fastfail(0xEu);
    VslCloseSecureHandle(*((_QWORD *)P + 3));
    if( *((_BYTE *)P + 76) )
    {
      v5 = (_QWORD *)*((_QWORD *)P + 13);
      while( v5 )
      {
        v6 = (_QWORD *)*v5;
        if( *v5 || (v6 = (_QWORD *)v5[1]) != 0i64 )
        {
          v5 = v6;
        }
        else
        {
          v7 = (_QWORD *)(v5[2] & 0xFFFFFFFFFFFFFFFCui64);
          if( v7 )
          {
            if( (_QWORD *)*v7 == v5 )
              *v7 = 0i64;
            else
              v7[1] = 0i64;
          }
          ExFreePoolWithTag(v5, 0);
          v5 = v7;
        }
      }
    }
    v8 = (void *)*((_QWORD *)P + 15);
    if( v8 )
      ExFreePoolWithTag(v8, 0);
    ExFreePoolWithTag(P, 0);
  }
  return result;
}

Referenced by:

MiCanDeleteEnclave
MiInitializeVsmEnclave
MiTerminateEnclave
PsCallEnclave
PsDeleteVsmEnclave