MiCreatePerSessionProtos

NTSTATUS __stdcall MiCreatePerSessionProtos(_CONTROL_AREA *ControlArea, UINT64 SessionId){
  unsigned int v2; 
  _ETHREAD *CurrentThread; 
  __int64 v5; 
  volatile INT64 *v6; 
  char *v7; 
  char *v8; 
  __int64 *SessionProtosInSubsection; 
  __int64 v11; 
  NTSTATUS PerSessionProtos; 
  _MI_PER_SESSION_PROTOS *v13; 
  _MI_PER_SESSION_PROTOS *Protos; 
  SINGLE_LIST_ENTRY ProtosToProcess; 
  v2 = SessionId;
  if( (unsigned int)(SessionId - 0x7FFFF) <= 0xFFF7FFFF )
    return -1073741618;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v5 = *(_QWORD *)ControlArea;
  --*((_WORD *)CurrentThread + 243);
  v6 = (volatile INT64 *)(v5 + 40);
  ExAcquirePushLockExclusiveEx((UINT64)v6, 0i64);
  v7 = (char *)ControlArea + 128;
  v8 = (char *)ControlArea + 128;
  if( ControlArea == (_CONTROL_AREA *)-128i64 )
  {
LABEL_5:
    if( (_InterlockedExchangeAdd64(v6, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(v6);
    KeAbPostRelease((PVOID)v6);
    KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
    return 0;
  }
  while( (v8[34] & 2) == 0 )
  {
LABEL_4:
    v8 = (char *)*((_QWORD *)v8 + 2);
    if( !v8 )
      goto LABEL_5;
  }
  SessionProtosInSubsection = MiLocateSessionProtosInSubsection((__int64)v8, v2);
  Protos = (_MI_PER_SESSION_PROTOS *)SessionProtosInSubsection;
  if( SessionProtosInSubsection )
  {
    ++*((_DWORD *)SessionProtosInSubsection + 20);
    goto LABEL_4;
  }
  PerSessionProtos = MiAllocatePerSessionProtos(v11, 0i64, 0, 0i64, (__int64 **)&Protos);
  if( PerSessionProtos >= 0 )
  {
    v13 = Protos;
    *((_DWORD *)Protos + 16) = v2;
    MiUpdatePerSessionProto(ControlArea, (_SUBSECTION *)v8, v13, 1ui64);
    goto LABEL_4;
  }
  ProtosToProcess.Next = 0i64;
  while( v7 != v8 )
  {
    MiDereferenceSubsectionProtos((__int64)v7, v2, (__int64 *)&ProtosToProcess);
    v7 = (char *)*((_QWORD *)v7 + 2);
  }
  if( (_InterlockedExchangeAdd64(v6, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(v6);
  KeAbPostRelease((PVOID)v6);
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  MiFreeSubsectionProtos(&ProtosToProcess);
  return PerSessionProtos;
}

Referenced by:

MiCloneImageVad
MiFinishCreateSection
MiInsertInSystemSpace
MiMapSystemImage
MiMapViewOfImageSection
MiValidateSectionCreate