PnpQueuePendingSurpriseRemoval

void __fastcall PnpQueuePendingSurpriseRemoval(_RELATION_LIST *a1, _RELATION_LIST **a2, INT64 a3, int a4){
  VOID **CriticalMemory; 
  _RELATION_LIST *v6; 
  int v7; 
  _ETHREAD *CurrentThread; 
  _RELATION_LIST *v10; 
  _RELATION_LIST *v11; 
  VOID ***v12; 
  char v13; 
  _BYTE *DeviceNode; 
  __int64 v15; 
  _RELATION_LIST **v16; 
  _RELATION_LIST *RelationList; 
  _RELATION_LIST *v18; 
  _RELATION_LIST ***v19; 
  _RELATION_LIST_MARKER Marker; 
  _DEVICE_OBJECT *DeviceObject; 

  DeviceObject = 0i64;
  CriticalMemory = 0i64;
  Marker = 0i64;
  v6 = *a2;
  v7 = a3;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  *a2 = 0i64;
  v10 = v6;
  --CurrentThread->Tcb.KernelApcDisable;
  ExAcquireResourceExclusiveLite((UINT64)&PnpReplaceEvent + 6176, 1, a3);
  PnpAcquireDependencyRelationsLock(1);
  v11 = (_RELATION_LIST *)*(&PnpReplaceEvent + 788);
  while( v11 != (_RELATION_LIST *)((char *)&PnpReplaceEvent + 6304) )
  {
    v16 = (_RELATION_LIST **)v11;
    v11 = (_RELATION_LIST *)v11->DeviceObjectList;
    if( v16[7] == a1 )
    {
      CriticalMemory = (VOID **)v16;
      v10 = v16[8];
      break;
    }
    if( IopCheckIfMergeRequired(v16[8], v10) )
    {
      if( v10 == v6 )
      {
        CriticalMemory = (VOID **)v16;
        RelationList = IopAllocateRelationList(SurpriseRemoveDevice);
        v10 = RelationList;
        if( !RelationList )
        {
          v10 = v6;
          break;
        }
        IopMergeRelationLists(RelationList, v6, 0);
      }
      IopMergeRelationLists(v10, v16[8], 1u);
      IopFreeRelationList(v16[8]);
      if( CriticalMemory == (VOID **)v16 )
      {
        CriticalMemory[8] = 0i64;
      }
      else
      {
        v18 = *v16;
        if( *(_RELATION_LIST ***)&(*v16)->Sorted != v16 )
          goto LABEL_28;
        v19 = (_RELATION_LIST ***)v16[1];
        if( *v19 != v16 )
          goto LABEL_28;
        *v19 = (_RELATION_LIST **)v18;
        *(_QWORD *)&v18->Sorted = v19;
        ExFreePoolWithTag(v16, 0);
      }
    }
  }
  ExReleaseResourceLite((PERESOURCE)((char *)&stru_140C452E0 + 384));
  PpDevNodeUnlockTree(PPL_SIMPLE_READ);
  if( v6 == v10 )
  {
    CriticalMemory = PnpAllocateCriticalMemory(3, NonPagedPoolNx, 0x70ui64, 0x54706E50u);
    v12 = (VOID ***)*(&PnpReplaceEvent + 789);
    if( (_UNKNOWN *)**(&PnpReplaceEvent + 789) != (_UNKNOWN *)((char *)&PnpReplaceEvent + 6304) )
LABEL_28:
      __fastfail(3u);
    *CriticalMemory = (char *)&PnpReplaceEvent + 6304;
    CriticalMemory[1] = v12;
    *v12 = CriticalMemory;
    *(&PnpReplaceEvent + 789) = CriticalMemory;
  }
  else
  {
    IopFreeRelationList(v6);
  }
  while( IopEnumerateRelations(v10, &Marker, &DeviceObject, 0i64, 0i64) )
  {
    if( DeviceObject )
      DeviceNode = DeviceObject->DeviceObjectExtension->DeviceNode;
    else
      DeviceNode = 0i64;
    if( (DeviceNode[648] & 1) != 0 )
    {
      if( IopIsDescendantNode(v10, DeviceObject) )
      {
        *(_QWORD *)(v15 + 648) &= ~1ui64;
        --*(_DWORD *)(*(_QWORD *)(v15 + 648) + 656i64);
      }
    }
  }
  CriticalMemory[7] = a1;
  *((_DWORD *)CriticalMemory + 21) = v7;
  *((_BYTE *)CriticalMemory + 88) = v13;
  CriticalMemory[8] = v10;
  *((_DWORD *)CriticalMemory + 27) = a4;
  *((_BYTE *)CriticalMemory + 104) = v13;
  ExReleaseResourceLite((PERESOURCE)((char *)&PnpReplaceEvent + 6176));
  KeLeaveCriticalRegionThread(KeGetCurrentThread());
}

Referenced by:

PiEventRemovalPostSurpriseRemove