IoBuildPoDeviceNotifyList

VOID __stdcall IoBuildPoDeviceNotifyList(PO_DEVICE_NOTIFY_ORDER *Order){
  unsigned int v1; 
  unsigned int v2; 
  __int64 **v3; 
  INT64 v5; 
  _LIST_ENTRY **p_Blink; 
  INT64 v7; 
  _QWORD *v8; 
  __int64 *v9; 
  __int64 *i; 
  __int64 ***v11; 
  __int64 v12; 
  WCHAR *v13; 
  VOID *v14; 
  WCHAR *v15; 
  void *v16; 
  __int64 **v17; 
  __int64 *j; 
  __int64 **v19; 
  __int64 *v20; 
  __int64 **v21; 
  __int64 v22; 
  __int64 **v23; 
  __int64 *k; 
  __int64 *v25; 
  char v26; 
  __int64 *m; 
  __int64 *v28; 
  __int64 *v29; 
  __int64 *v30; 
  __int64 *v31; 
  __int64 *v32; 
  __int64 *n; 
  __int64 *v34; 
  __int64 *ii; 
  __int64 *v36; 
  __int64 *jj; 
  __int64 *v38; 
  __int64 *v39; 
  char v40; 
  _DWORD *v41; 
  _DWORD *LowerDeviceObjectWithTag; 
  __int64 *v43; 
  char v44; 
  __int64 *v45; 
  __int64 **v46; 
  __int64 v47; 
  unsigned __int8 v48; 
  __int64 *kk; 
  __int64 *mm; 
  __int64 *nn; 
  __int64 *v52; 
  __int64 *i1; 
  __int64 v54; 
  unsigned __int8 v55; 
  __int64 **v56; 
  __int64 v57; 
  __int64 *v58; 
  __int64 i2; 
  __int64 v60; 
  __int64 i3; 
  char *v62; 
  char **v63; 
  __int64 *v64; 
  __int64 *v65; 
  __int64 v66; 
  __int64 *v67; 
  __int64 v68; 
  char v69; 
  _LIST_ENTRY *Blink; 
  __int64 *v71; 
  __int64 **v72; 
  _LIST_ENTRY ListHead; 

  v2 = v1;
  v72 = &v71;
  ListHead.Blink = &ListHead;
  ListHead.Flink = &ListHead;
  v3 = &v71;
  v71 = (__int64 *)&v71;
  if( (v1 & 1) == 0 )
  {
    PnpLockDeviceActionQueue();
    v3 = (__int64 **)v71;
  }
  memset(Order, 0i64, sizeof(PO_DEVICE_NOTIFY_ORDER));
  p_Blink = &Order->OrderLevel[0].ReadySleep.Blink;
  Order->Flags = v2;
  v7 = 5i64;
  do
  {
    *(p_Blink - 2) = (_LIST_ENTRY *)(p_Blink - 3);
    *(p_Blink - 3) = (_LIST_ENTRY *)(p_Blink - 3);
    *p_Blink = (_LIST_ENTRY *)(p_Blink - 1);
    *(p_Blink - 1) = (_LIST_ENTRY *)(p_Blink - 1);
    p_Blink[2] = (_LIST_ENTRY *)(p_Blink + 1);
    p_Blink[1] = (_LIST_ENTRY *)(p_Blink + 1);
    v8 = p_Blink + 3;
    p_Blink[4] = (_LIST_ENTRY *)(p_Blink + 3);
    p_Blink += 9;
    *v8 = v8;
    --v7;
  }
  while( v7 );
  v9 = (__int64 *)*(&PnpReplaceEvent + 831);
  for( i = *(__int64 **)(*(&PnpReplaceEvent + 831) + 8i64); i; i = (__int64 *)i[1] )
    v9 = i;
  if( v9 == (__int64 *)*(&PnpReplaceEvent + 831) )
    goto LABEL_27;
  do
  {
    v11 = (__int64 ***)(v9 + 20);
    *((_DWORD *)v9 + 62) = 0;
    *((_DWORD *)v9 + 63) = 0;
    *((_DWORD *)v9 + 64) = 0;
    *((_DWORD *)v9 + 65) = 0;
    *((_BYTE *)v9 + 216) = 0;
    v9[28] = v9[4];
    LODWORD(v12) = IoGetAttachedDeviceReference(v9[4], v7, v5);
    v9[26] = v12;
    v13 = IopCaptureObjectName(*(VOID **)(v12 + 8));
    v14 = (VOID *)v9[26];
    v9[30] = (__int64)v13;
    v15 = IopCaptureObjectName(v14);
    v16 = (void *)v9[28];
    v9[29] = (__int64)v15;
    ObfReferenceObject(v16);
    *((_BYTE *)v9 + 216) = 0;
    if( IopCheckDeviceFlags((PO_DEVICE_NOTIFY *)(v9 + 20), 0x2000ui64) )
      *((_BYTE *)v9 + 216) |= 2u;
    v17 = (__int64 **)(v9 + 2);
    if( v9[2] == *(&PnpReplaceEvent + 831) && *((_DWORD *)v9 + 112) && (*((_DWORD *)v9 + 99) & 4) == 0 )
    {
      v19 = v72;
      if( *v72 != (__int64 *)&v71 )
LABEL_136:
        __fastfail(3u);
      v9[21] = (__int64)v72;
      v7 = (INT64)&v71;
      *v11 = &v71;
      *v19 = (__int64 *)v11;
      v72 = (__int64 **)(v9 + 20);
    }
    v9 = (__int64 *)*v9;
    if( v9 )
    {
      for( j = (__int64 *)v9[1]; j; j = (__int64 *)j[1] )
        v9 = j;
    }
    else
    {
      v9 = *v17;
    }
  }
  while( v9 != (__int64 *)*(&PnpReplaceEvent + 831) );
  while( 1 )
  {
    v3 = (__int64 **)v71;
LABEL_27:
    if( v3 == &v71 )
      break;
    if( v3[1] != (__int64 *)&v71 )
      goto LABEL_136;
    v22 = (__int64)*v3;
    if( (__int64 **)(*v3)[1] != v3 )
      goto LABEL_136;
    v71 = *v3;
    *(_QWORD *)(v22 + 8) = &v71;
    *((_BYTE *)v3 + 56) |= 1u;
    v23 = v3 - 20;
    v21 = v23;
    for( k = v23[1]; k; k = (__int64 *)k[1] )
      v21 = (__int64 **)k;
    while( v21 != v23 )
    {
      *((_BYTE *)v21 + 216) |= 1u;
      v20 = *v21;
      if( *v21 )
      {
        do
        {
          v21 = (__int64 **)v20;
          v20 = (__int64 *)v20[1];
        }
        while( v20 );
      }
      else
      {
        v21 = (__int64 **)v21[2];
      }
    }
  }
  do
  {
    v25 = (__int64 *)*(&PnpReplaceEvent + 831);
    v26 = 0;
    for( m = *(__int64 **)(*(&PnpReplaceEvent + 831) + 8i64); m; m = (__int64 *)m[1] )
      v25 = m;
    while( 1 )
    {
      v28 = (__int64 *)*(&PnpReplaceEvent + 831);
      if( v25 == (__int64 *)*(&PnpReplaceEvent + 831) )
        break;
      if( (v25[27] & 2) != 0 )
      {
        v30 = (__int64 *)v25[1];
        v31 = v25;
        while( v30 )
        {
          v31 = v30;
          v30 = (__int64 *)v30[1];
        }
        while( v31 != v25 )
        {
          *((_BYTE *)v31 + 216) |= 2u;
          v32 = (__int64 *)*v31;
          if( *v31 )
          {
            do
            {
              v31 = v32;
              v32 = (__int64 *)v32[1];
            }
            while( v32 );
          }
          else
          {
            v31 = (__int64 *)v31[2];
          }
        }
      }
      v29 = (__int64 *)*v25;
      if( *v25 )
      {
        do
        {
          v25 = v29;
          v29 = (__int64 *)v29[1];
        }
        while( v29 );
      }
      else
      {
        v25 = (__int64 *)v25[2];
      }
    }
    for( n = *(__int64 **)(*(&PnpReplaceEvent + 831) + 8i64); n; n = (__int64 *)n[1] )
      v28 = n;
    v34 = (__int64 *)*(&PnpReplaceEvent + 831);
    if( v28 == (__int64 *)*(&PnpReplaceEvent + 831) )
      break;
    do
    {
      if( (v28[27] & 2) != 0 )
      {
        for( ii = (__int64 *)v28[22]; ii != v28 + 22; ii = (__int64 *)*ii )
        {
          v68 = *(ii - 1);
          v69 = *(_BYTE *)(v68 + 56);
          if( (v69 & 2) == 0 )
          {
            v26 = 1;
            *(_BYTE *)(v68 + 56) = v69 | 2;
          }
        }
      }
      v36 = (__int64 *)*v28;
      if( *v28 )
      {
        do
        {
          v28 = v36;
          v36 = (__int64 *)v36[1];
        }
        while( v36 );
      }
      else
      {
        v28 = (__int64 *)v28[2];
      }
      v34 = (__int64 *)*(&PnpReplaceEvent + 831);
    }
    while( v28 != (__int64 *)*(&PnpReplaceEvent + 831) );
  }
  while( v26 );
  for( jj = (__int64 *)v34[1]; jj; jj = (__int64 *)jj[1] )
    v34 = jj;
  while( 1 )
  {
    v39 = (__int64 *)*(&PnpReplaceEvent + 831);
    if( v34 == (__int64 *)*(&PnpReplaceEvent + 831) )
      break;
    v40 = *((_BYTE *)v34 + 216);
    if( (v40 & 2) != 0 )
    {
      v41 = (_DWORD *)v34[26];
      *((_BYTE *)v34 + 216) = v40 + 1;
      ObfReferenceObjectWithTag(v41, 0x70506F50ui64);
      if( v41 )
      {
        while( v41[18] != 7 )
        {
          LowerDeviceObjectWithTag = IoGetLowerDeviceObjectWithTag((INT64)v41, 0x70506F50ui64);
          ObfDereferenceObjectWithTag(v41, 0x70506F50ui64);
          v41 = LowerDeviceObjectWithTag;
          if( !LowerDeviceObjectWithTag )
            goto LABEL_70;
        }
        ObfDereferenceObjectWithTag(v41, 0x70506F50ui64);
        if( IopCheckDeviceFlags((PO_DEVICE_NOTIFY *)(v34 + 20), 0x100ui64) )
          *((_BYTE *)v34 + 216) = 2;
      }
    }
LABEL_70:
    v38 = (__int64 *)*v34;
    if( *v34 )
    {
      do
      {
        v34 = v38;
        v38 = (__int64 *)v38[1];
      }
      while( v38 );
    }
    else
    {
      v34 = (__int64 *)v34[2];
    }
  }
  do
  {
    v43 = (__int64 *)v39[1];
    v44 = 0;
    while( v43 )
    {
      v39 = v43;
      v43 = (__int64 *)v43[1];
    }
    while( 1 )
    {
      v45 = (__int64 *)*(&PnpReplaceEvent + 831);
      if( v39 == (__int64 *)*(&PnpReplaceEvent + 831) )
        break;
      v46 = (__int64 **)(v39 + 2);
      v47 = v39[2];
      if( v47 != *(&PnpReplaceEvent + 831) )
      {
        v48 = *((_BYTE *)v39 + 216);
        if( *(_BYTE *)(v47 + 216) > v48 )
          *(_BYTE *)(v47 + 216) = v48;
      }
      v39 = (__int64 *)*v39;
      if( v39 )
      {
        for( kk = (__int64 *)v39[1]; kk; kk = (__int64 *)kk[1] )
          v39 = kk;
      }
      else
      {
        v39 = *v46;
      }
    }
    for( mm = *(__int64 **)(*(&PnpReplaceEvent + 831) + 8i64); mm; mm = (__int64 *)mm[1] )
      v45 = mm;
    v39 = (__int64 *)*(&PnpReplaceEvent + 831);
    if( v45 == (__int64 *)*(&PnpReplaceEvent + 831) )
      break;
    do
    {
      for( nn = (__int64 *)v45[24]; nn != v45 + 24; nn = (__int64 *)*nn )
      {
        v54 = nn[5];
        v55 = *((_BYTE *)v45 + 216);
        if( *(_BYTE *)(v54 + 56) > v55 )
        {
          v44 = 1;
          *(_BYTE *)(v54 + 56) = v55;
        }
      }
      v52 = (__int64 *)*v45;
      if( *v45 )
      {
        do
        {
          v45 = v52;
          v52 = (__int64 *)v52[1];
        }
        while( v52 );
      }
      else
      {
        v45 = (__int64 *)v45[2];
      }
      v39 = (__int64 *)*(&PnpReplaceEvent + 831);
    }
    while( v45 != (__int64 *)*(&PnpReplaceEvent + 831) );
  }
  while( v44 );
  for( i1 = (__int64 *)v39[1]; i1; i1 = (__int64 *)i1[1] )
    v39 = i1;
  while( v39 != (__int64 *)*(&PnpReplaceEvent + 831) )
  {
    if( IopIsNotifyInBroadcast(Order->Flags, (INT64)(v39 + 20)) )
    {
      ++Order->OrderLevel[*(unsigned __int8 *)(v57 + 56)].DeviceCount;
      v65 = v56[2];
      if( v65 != (__int64 *)*(&PnpReplaceEvent + 831) && IopIsNotifyInBroadcast(Order->Flags, (INT64)(v65 + 20)) )
      {
        ++*(_DWORD *)(v57 + 96);
        ++*((_DWORD *)v56[2] + 62);
      }
      v66 = v57 + 32;
      for( i2 = *(_QWORD *)(v57 + 32); i2 != v66; i2 = *v58 )
      {
        if( IopIsNotifyInBroadcast(Order->Flags, *(_QWORD *)(i2 + 40)) )
          ++*(_DWORD *)(v57 + 96);
      }
      v60 = v57 + 16;
      for( i3 = *(_QWORD *)(v57 + 16); i3 != v60; i3 = *v67 )
      {
        if( IopIsNotifyInBroadcast(Order->Flags, *(_QWORD *)(i3 - 8)) )
          ++*(_DWORD *)(v57 + 88);
      }
      v62 = (char *)&Order->OrderLevel[0].WaitSleep
          + 64 * *(unsigned __int8 *)(v57 + 56)
          + 8 * *(unsigned __int8 *)(v57 + 56);
      v63 = (char **)*((_QWORD *)v62 + 1);
      if( *v63 != v62 )
        goto LABEL_136;
      *(_QWORD *)v57 = v62;
      *(_QWORD *)(v57 + 8) = v63;
      *v63 = (char *)v57;
      *((_QWORD *)v62 + 1) = v57;
    }
    else
    {
      Blink = ListHead.Blink;
      if( ListHead.Blink->Flink != &ListHead )
        goto LABEL_136;
      *(_QWORD *)(v57 + 8) = ListHead.Blink;
      *(_QWORD *)v57 = &ListHead;
      Blink->Flink = (_LIST_ENTRY *)v57;
      ListHead.Blink = (_LIST_ENTRY *)v57;
    }
    v64 = *v56;
    if( *v56 )
    {
      do
      {
        v39 = v64;
        v64 = (__int64 *)v64[1];
      }
      while( v64 );
    }
    else
    {
      v39 = v56[2];
    }
  }
  IopFreePoDeviceNotifyListHead(&ListHead);
  Order->WarmEjectPdoPointer = (_DEVICE_OBJECT **)((char *)&PnpReplaceEvent + 6592);
  Order->Locked = 1;
}

Referenced by:

PopBuildDeviceNotifyList