SepSetTokenUserAndGroups

NTSTATUS __stdcall SepSetTokenUserAndGroups(
        _TOKEN *Token,
        _SID_AND_ATTRIBUTES *User,
        UINT64 GroupCount,
        _SID_AND_ATTRIBUTES *Groups,
        UINT64 GroupsLength){
  char v5; 
  UINT8 v6; 
  unsigned int IntegrityLevelIndex; 
  int v8; 
  unsigned int v10; 
  NTSTATUS result; 
  int v14; 
  _SEP_LOGON_SESSION_REFERENCES *LogonSession; 
  _ETHREAD *CurrentThread; 
  _SEP_LOGON_SESSION_REFERENCES *v17; 
  _SEP_SID_VALUES_BLOCK *v18; 
  _SEP_SID_VALUES_BLOCK *SharedSidValues; 
  int v20; 
  _SEP_SID_VALUES_BLOCK *TokenSidValues; 
  unsigned __int8 *p_SidValuesStart; 
  unsigned int v23; 
  __int64 v24; 
  _SID_AND_ATTRIBUTES *UserAndGroups; 
  __int64 v26; 
  unsigned int Attributes; 
  UINT64 v28; 
  UINT64 IntegrityLevelIndexInGroups; 
  VOID *v30; 
  _SEP_SID_VALUES_BLOCK *SidValues; 
  _SID_AND_ATTRIBUTES *v32; 

  v32 = User;
  SidValues = 0i64;
  v5 = 0;
  v30 = 0i64;
  v6 = 0;
  IntegrityLevelIndex = Token->IntegrityLevelIndex;
  v8 = -1;
  v10 = GroupCount;
  if( IntegrityLevelIndex != -1 )
  {
    v8 = IntegrityLevelIndex - 1;
    result = SepDuplicateSid(Groups[IntegrityLevelIndex - 1].Sid, &v30);
    if( result < 0 )
      return result;
    Token->IntegrityLevelSidValue = v30;
  }
  LODWORD(IntegrityLevelIndexInGroups) = v8;
  LODWORD(v28) = GroupsLength;
  v14 = SepCreateSidValuesBlock(&SidValues, User, v10, Groups, v28, IntegrityLevelIndexInGroups);
  if( v14 >= 0 )
  {
    LogonSession = Token->LogonSession;
    if( LogonSession->SharedSidValues )
      goto LABEL_14;
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    --CurrentThread->Tcb.KernelApcDisable;
    ExAcquirePushLockExclusiveEx(&Token->LogonSession->SharedDataLock, 0i64);
    v17 = Token->LogonSession;
    if( !v17->SharedSidValues )
    {
      if( _InterlockedIncrement64(&SidValues->ReferenceCount) <= 1 )
        __fastfail(0xEu);
      v5 = 1;
      Token->LogonSession->SharedSidValues = SidValues;
      v17 = Token->LogonSession;
    }
    if( (_InterlockedExchangeAdd64(&v17->SharedDataLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(&v17->SharedDataLock);
    KeAbPostRelease(&v17->SharedDataLock);
    KeLeaveCriticalRegionThread(KeGetCurrentThread());
    LogonSession = Token->LogonSession;
    if( !v5 )
    {
LABEL_14:
      v18 = SidValues;
      v6 = SepCompareSidValuesBlocks(SidValues, LogonSession->SharedSidValues);
    }
    else
    {
      v18 = SidValues;
    }
    SharedSidValues = LogonSession->SharedSidValues;
    if( v5 )
    {
      v20 = 0;
    }
    else
    {
      if( v6 )
      {
        SepLogTokenSidManagement(2, v18, SharedSidValues, (__int64)Token);
        if( _InterlockedIncrement64(&Token->LogonSession->SharedSidValues->ReferenceCount) <= 1 )
          __fastfail(0xEu);
        Token->TokenSidValues = Token->LogonSession->SharedSidValues;
        SepDereferenceSidValuesBlock(SidValues, Token, 0i64);
        goto LABEL_23;
      }
      v20 = 1;
    }
    SepLogTokenSidManagement(v20, v18, SharedSidValues, (__int64)Token);
    Token->TokenSidValues = v18;
LABEL_23:
    TokenSidValues = Token->TokenSidValues;
    Token->UserAndGroups = (_SID_AND_ATTRIBUTES *)&Token->VariablePart;
    p_SidValuesStart = (unsigned __int8 *)&TokenSidValues->SidValuesStart;
    v23 = 0;
    Token->UserAndGroupCount = v10 + 1;
    if( v10 != -1 )
    {
      v24 = (__int64)v32;
      do
      {
        UserAndGroups = Token->UserAndGroups;
        v26 = v23;
        if( v23 == Token->IntegrityLevelIndex )
        {
          UserAndGroups[v23].Sid = Token->IntegrityLevelSidValue;
        }
        else
        {
          UserAndGroups[v23].Sid = p_SidValuesStart;
          p_SidValuesStart += (4i64 * p_SidValuesStart[1] + 11) & 0xFFFFFFFCi64;
        }
        if( v23 )
          Attributes = Groups[v23 - 1].Attributes;
        else
          Attributes = *(_DWORD *)(v24 + 8);
        ++v23;
        Token->UserAndGroups[v26].Attributes = Attributes;
      }
      while( v23 < Token->UserAndGroupCount );
    }
  }
  return v14;
}

Referenced by:

SepCreateTokenEx