WmipReceiveNotifications

__int64 __fastcall WmipReceiveNotifications(unsigned int *a1, unsigned int *a2, __int64 a3){
  __int64 v4; 
  unsigned int *v5; 
  unsigned int v6; 
  int v7; 
  struct _KEVENT **PoolWithTag; 
  int v9; 
  __int64 v10; 
  int v11; 
  __int64 v12; 
  void **v13; 
  void *v14; 
  _DWORD *v15; 
  unsigned int v16; 
  PVOID *v17; 
  __int64 v18; 
  int v19; 
  unsigned int v20; 
  char v21; 
  __int64 v22; 
  unsigned int v23; 
  struct _KEVENT *v24; 
  __int64 *p_WaitListHead; 
  __int64 **v26; 
  __int64 v27; 
  char v28; 
  PVOID *v29; 
  int v31; 
  unsigned int v32; 
  int v33; 
  INT64 *v34; 
  __int64 v35; 
  unsigned int v36; 
  NTSTATUS v37; 
  unsigned int v38; 
  int v39; 
  int v40; 
  unsigned int v41; 
  int v42; 
  int v43; 
  __int64 v44; 
  PVOID Object; 
  unsigned int *v46; 
  unsigned int *v47; 
  struct _KLOCK_QUEUE_HANDLE LockHandle; 
  char P[256]; 
  v44 = 0i64;
  v36 = 0;
  v4 = *a1;
  v5 = a1;
  v6 = *a2;
  v7 = 1;
  v47 = a2;
  v37 = -1073741811;
  v46 = a1 + 2;
  if( (unsigned int)v4 > 0x10 )
  {
    PoolWithTag = (struct _KEVENT **)ExAllocatePoolWithTag(PagedPool, 16 * v4, 0x70696D57ui64);
    if( !PoolWithTag )
      return 3221225626i64;
  }
  else
  {
    PoolWithTag = (struct _KEVENT **)P;
  }
  KeWaitForSingleObject(&WmipSMMutex, Executive, 0, 0, 0i64);
  v9 = 0;
  LOBYTE(v42) = 0;
  v10 = 0i64;
  v40 = 0;
  v38 = 0;
  LOBYTE(v7) = 0;
  LOBYTE(v11) = 0;
  v43 = v7;
  v12 = 0i64;
  v39 = v11;
  v41 = 0;
  if( (_DWORD)v4 )
  {
    v13 = (void **)(v5 + 2);
    while( 1 )
    {
      v14 = *v13;
      Object = 0i64;
      v37 = ObReferenceObjectByHandle(v14, 4u, WmipGuidObjectType, 1, &Object, 0i64);
      if( v37 < 0 )
        break;
      v15 = Object;
      v16 = 0;
      if( (_DWORD)v10 )
      {
        v17 = (PVOID *)PoolWithTag;
        while( Object != *v17 )
        {
          ++v16;
          v17 += 2;
          if( v16 >= (unsigned int)v10 )
            goto LABEL_10;
        }
        ObfDereferenceObjectWithTag(Object, 0x746C6644ui64);
        LOBYTE(v11) = v39;
        v9 = v40;
        v12 = v41;
      }
      else
      {
LABEL_10:
        v11 = (unsigned __int8)v39;
        if( *((_QWORD *)Object + 9) )
          v11 = 1;
        v18 = 2i64 * (unsigned int)v10;
        v10 = (unsigned int)(v10 + 1);
        v39 = v11;
        PoolWithTag[v18] = (struct _KEVENT *)Object;
        if( *((_QWORD *)v15 + 12) )
        {
          v7 = (unsigned __int8)v7;
          if( v15[29] )
            v7 = 1;
          v43 = v7;
        }
        if( *((_QWORD *)v15 + 16) )
        {
          v31 = (unsigned __int8)v42;
          if( v15[37] )
            v31 = 1;
          v42 = v31;
        }
        v9 = ((v15[29] + 7) & 0xFFFFFFF8) + v40;
        v19 = v15[37] + 7;
        v40 = v9;
        v19 &= 0xFFFFFFF8;
        v12 = v19 + v41;
        v41 += v19;
      }
      v13 = (void **)(v46 + 2);
      ++v38;
      v46 += 2;
      if( v38 >= (unsigned int)v4 )
        goto LABEL_16;
    }
  }
  else
  {
LABEL_16:
    v20 = v12 + v9;
    v38 = v12 + v9;
    if( (_BYTE)v11 == 1 && (_DWORD)v10 )
    {
      v34 = (INT64 *)PoolWithTag;
      v35 = (unsigned int)v10;
      do
      {
        if( *(_QWORD *)(*v34 + 72) )
          WmipCompleteGuidIrpWithError(*v34);
        v34 += 2;
        --v35;
      }
      while( v35 );
      v20 = v38;
      LOBYTE(v7) = v43;
    }
    v21 = v42;
    if( (unsigned __int8)v42 | (unsigned __int8)v7 )
    {
      if( v20 > v6 )
      {
        v33 = 56;
        v5[11] = 32;
        *v5 = 56;
        v5[12] = v20;
      }
      else
      {
        v32 = v6;
        if( (_BYTE)v7 )
        {
          WmipCopyFromEventQueues(PoolWithTag, (unsigned int)v10, v5, v12, &v36, &v44, 1);
          v5 = (unsigned int *)((char *)v5 + v36);
          v32 = v6 - v36;
        }
        if( v21 )
        {
          WmipCopyFromEventQueues(PoolWithTag, (unsigned int)v10, v5, v12, &v36, &v44, 0);
          v32 -= v36;
        }
        if( v44 )
          *(_DWORD *)(v44 + 12) = 0;
        v33 = v6 - v32;
      }
      *v47 = v33;
    }
    else
    {
      v22 = a3 + 120;
      v23 = 0;
      *(_QWORD *)&LockHandle.OldIrql = 0i64;
      *(_QWORD *)(a3 + 128) = a3 + 120;
      *(_QWORD *)(a3 + 120) = a3 + 120;
      for( LockHandle.LockQueue = 0i64; v23 < (unsigned int)v10; *(_QWORD *)(a3 + 128) = p_WaitListHead )
      {
        v24 = PoolWithTag[2 * v23];
        *(_QWORD *)&v24[3].Header.Lock = a3;
        p_WaitListHead = (__int64 *)&v24[3].Header.WaitListHead;
        v26 = *(__int64 ***)(a3 + 128);
        if( *v26 != (__int64 *)v22 )
          __fastfail(3u);
        *p_WaitListHead = v22;
        ++v23;
        p_WaitListHead[1] = (__int64)v26;
        *v26 = p_WaitListHead;
      }
      v27 = *(_QWORD *)(a3 + 184);
      v37 = 259;
      v28 = 0;
      *(_BYTE *)(v27 + 3) |= 1u;
      KeAcquireInStackQueuedSpinLock(&WmipCancelSpinLock, &LockHandle);
      _InterlockedExchange64((volatile __int64 *)(a3 + 104), (__int64)WmipNotificationIrpCancel);
      if( *(_BYTE *)(a3 + 68) )
      {
        WmipClearIrpObjectList((IRP *)a3);
        v28 = 0;
        v37 = -1073741536;
        if( _InterlockedExchange64((volatile __int64 *)(a3 + 104), 0i64) )
          v28 = 1;
      }
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
      __writecr8(LockHandle.OldIrql);
      if( v28 )
      {
        *(_QWORD *)(a3 + 56) = 0i64;
        *(_DWORD *)(a3 + 48) = -1073741536;
        IofCompleteRequest((_IRP *)a3, 0);
      }
      *v47 = 0;
    }
  }
  KeReleaseMutex(&WmipSMMutex, 0);
  if( (_DWORD)v10 )
  {
    v29 = (PVOID *)PoolWithTag;
    do
    {
      ObfDereferenceObjectWithTag(*v29, 0x746C6644ui64);
      v29 += 2;
      --v10;
    }
    while( v10 );
  }
  if( PoolWithTag != (struct _KEVENT **)P )
    ExFreePoolWithTag(PoolWithTag, 0);
  return(unsigned int)v37;
}

Referenced by:

WmipIoControl