PnpQueuePendingSurpriseRemoval

VOID __fastcall PnpQueuePendingSurpriseRemoval(
        _DEVICE_OBJECT *DeviceObject,
        _RELATION_LIST **List,
        UINT64 Problem,
        _PNP_DEVICE_DELETE_TYPE DeleteType){
  CHAR *CriticalMemory; 
  _RELATION_LIST *v6; 
  int v7; 
  _ETHREAD *CurrentThread; 
  _RELATION_LIST *v10; 
  PVOID *v11; 
  CHAR **v12; 
  CHAR v13; 
  __int64 v14; 
  __int64 v15; 
  unsigned int ***v16; 
  _RELATION_LIST *RelationList; 
  unsigned int **v18; 
  unsigned int ****v19; 
  int a2[2]; 
  __int64 a3; 
  a3 = 0i64;
  CriticalMemory = 0i64;
  *(_QWORD *)a2 = 0i64;
  v6 = *List;
  v7 = Problem;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  *List = 0i64;
  v10 = v6;
  --*((_WORD *)CurrentThread + 242);
  ExAcquireResourceExclusiveLite(&IopSurpriseRemoveListLock, 1u);
  PnpAcquireDependencyRelationsLock(1u);
  v11 = (PVOID *)IopPendingSurpriseRemovals;
  while( v11 != &IopPendingSurpriseRemovals )
  {
    v16 = (unsigned int ***)v11;
    v11 = (PVOID *)*v11;
    if( v16[7] == (unsigned int **)DeviceObject )
    {
      CriticalMemory = (CHAR *)v16;
      v10 = (_RELATION_LIST *)v16[8];
      break;
    }
    if( IopCheckIfMergeRequired(v16[8], (int **)v10) )
    {
      if( v10 == v6 )
      {
        CriticalMemory = (CHAR *)v16;
        RelationList = (_RELATION_LIST *)IopAllocateRelationList(3i64);
        v10 = RelationList;
        if( !RelationList )
        {
          v10 = v6;
          break;
        }
        IopMergeRelationLists(RelationList, v6, 0);
      }
      IopMergeRelationLists(v10, (_RELATION_LIST *)v16[8], 1u);
      IopFreeRelationList(v16[8]);
      if( CriticalMemory == (CHAR *)v16 )
      {
        *((_QWORD *)CriticalMemory + 8) = 0i64;
      }
      else
      {
        v18 = *v16;
        if( (*v16)[1] != (unsigned int *)v16 )
          goto LABEL_28;
        v19 = (unsigned int ****)v16[1];
        if( *v19 != v16 )
          goto LABEL_28;
        *v19 = (unsigned int ***)v18;
        v18[1] = (unsigned int *)v19;
        ExFreePoolWithTag(v16, 0);
      }
    }
  }
  ExReleaseResourceLite(&PiDependencyRelationsLock);
  PpDevNodeUnlockTree(0);
  if( v6 == v10 )
  {
    CriticalMemory = PnpAllocateCriticalMemory(3i64, NonPagedPoolNx, 0x70ui64, 0x54706E50ui64);
    v12 = (CHAR **)qword_140C44A28;
    if( *(PVOID **)qword_140C44A28 != &IopPendingSurpriseRemovals )
LABEL_28:
      __fastfail(3u);
    *(_QWORD *)CriticalMemory = &IopPendingSurpriseRemovals;
    *((_QWORD *)CriticalMemory + 1) = v12;
    *v12 = CriticalMemory;
    qword_140C44A28 = (__int64)CriticalMemory;
  }
  else
  {
    IopFreeRelationList(v6);
  }
  while( IopEnumerateRelations((unsigned int **)v10, a2, &a3, 0i64, 0i64) )
  {
    if( a3 )
      v14 = *(_QWORD *)(*(_QWORD *)(a3 + 312) + 40i64);
    else
      v14 = 0i64;
    if( (*(_BYTE *)(v14 + 648) & 1) != 0 )
    {
      if( IopIsDescendantNode((int **)v10, a3) )
      {
        *(_QWORD *)(v15 + 648) &= ~1ui64;
        --*(_DWORD *)(*(_QWORD *)(v15 + 648) + 656i64);
      }
    }
  }
  *((_QWORD *)CriticalMemory + 7) = DeviceObject;
  *((_DWORD *)CriticalMemory + 21) = v7;
  CriticalMemory[88] = v13;
  *((_QWORD *)CriticalMemory + 8) = v10;
  *((_DWORD *)CriticalMemory + 27) = DeleteType;
  CriticalMemory[104] = v13;
  ExReleaseResourceLite(&IopSurpriseRemoveListLock);
  KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
}

Referenced by:

PiEventRemovalPostSurpriseRemove