IoUnregisterPriorityCallback

VOID __stdcall IoUnregisterPriorityCallback(_DRIVER_OBJECT *DriverObject){
  _ETHREAD *CurrentThread; 
  __int64 v3; 
  signed __int64 *i; 
  struct EX_RUNDOWN_REF *v5; 
  struct EX_RUNDOWN_REF *v6; 
  signed __int64 v7; 
  signed __int64 v8; 
  signed __int64 v9; 
  signed __int64 v10; 
  if( (DriverObject->Flags & 0x200) == 0 )
    return;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)CurrentThread + 242);
  v3 = 0i64;
  for( i = IopUpdatePriorityCallbackRoutine; ; ++i )
  {
    v5 = ExReferenceCallBackBlock(&IopUpdatePriorityCallbackRoutine[v3]);
    v6 = v5;
    if( v5 )
    {
      if( (_DRIVER_OBJECT *)v5[4].Count != DriverObject )
      {
        _m_prefetchw(i);
        v9 = *i;
        while( ((unsigned __int64)v6 ^ v9) < 0xF )
        {
          v10 = v9;
          v9 = _InterlockedCompareExchange64(i, v9 + 1, v9);
          if( v10 == v9 )
            goto LABEL_15;
        }
        ExReleaseRundownProtection(v6);
        goto LABEL_15;
      }
      if( ExCompareExchangeCallBack(&IopUpdatePriorityCallbackRoutine[v3], 0i64, (INT64)v5) )
        break;
    }
LABEL_15:
    v3 = (unsigned int)(v3 + 1);
    if( (unsigned int)v3 >= 8 )
    {
      KeLeaveCriticalRegionThread((__int64)CurrentThread);
      return;
    }
  }
  _InterlockedDecrement(&IopUpdatePriorityCallbackRoutineCount);
  _m_prefetchw(&IopUpdatePriorityCallbackRoutine[v3]);
  v7 = IopUpdatePriorityCallbackRoutine[v3];
  if( ((unsigned __int64)v6 ^ v7) >= 0xF )
  {
LABEL_9:
    ExReleaseRundownProtection(v6);
  }
  else
  {
    while( 1 )
    {
      v8 = v7;
      v7 = _InterlockedCompareExchange64(&IopUpdatePriorityCallbackRoutine[v3], v7 + 1, v7);
      if( v8 == v7 )
        break;
      if( ((unsigned __int64)v6 ^ v7) >= 0xF )
        goto LABEL_9;
    }
  }
  KeLeaveCriticalRegionThread((__int64)CurrentThread);
  ExWaitForCallBacks(v6);
  SC_ENV::Free(v6);
  DriverObject->Flags &= ~0x200u;
}

Referenced by:

IopDeleteDriver