IopDestroyDeviceNode

VOID __stdcall IopDestroyDeviceNode(_DEVICE_NODE *DeviceNode){
  _DEVICE_OBJECT *PhysicalDeviceObject; 
  _DEVICE_OBJECT *DuplicatePDO; 
  _IO_RESOURCE_REQUIREMENTS_LIST *ResourceRequirements; 
  _LIST_ENTRY *p_PendedSetInterfaceState; 
  _LIST_ENTRY *Flink; 
  _PNP_REBALANCE_TRACE_CONTEXT *RebalanceContext; 
  _UNICODE_STRING *p_InstancePath; 
  _DEVICE_NODE *Parent; 
  _UNICODE_STRING *v10; 
  _DEVICE_NODE *v11; 
  _LIST_ENTRY *v12; 

  if( DeviceNode )
  {
    if( DeviceNode->IommuExtension )
    {
      p_InstancePath = &DeviceNode->InstancePath;
      IoAddTriageDumpDataBlock(DeviceNode, (_BYTE *)0x310);
      if( p_InstancePath->Length )
      {
        IoAddTriageDumpDataBlock(p_InstancePath, (_BYTE *)2);
        IoAddTriageDumpDataBlock(p_InstancePath->Buffer, (_BYTE *)p_InstancePath->Length);
      }
      if( DeviceNode->ServiceName.Length )
      {
        IoAddTriageDumpDataBlock(&DeviceNode->ServiceName, (_BYTE *)2);
        IoAddTriageDumpDataBlock(DeviceNode->ServiceName.Buffer, (_BYTE *)DeviceNode->ServiceName.Length);
      }
      Parent = DeviceNode->Parent;
      if( Parent && Parent->ServiceName.Length )
      {
        IoAddTriageDumpDataBlock(&Parent->ServiceName, (_BYTE *)2);
        IoAddTriageDumpDataBlock(
          DeviceNode->Parent->ServiceName.Buffer,
          (_BYTE *)DeviceNode->Parent->ServiceName.Length);
      }
      KeBugCheckEx(0xCAu, (PVOID)5, DeviceNode->PhysicalDeviceObject, DeviceNode->IommuExtension, (PVOID)0x11);
    }
    PhysicalDeviceObject = DeviceNode->PhysicalDeviceObject;
    if( (PhysicalDeviceObject->Flags & 0x1000) != 0 && DeviceNode->Parent )
    {
      v10 = &DeviceNode->InstancePath;
      IoAddTriageDumpDataBlock(DeviceNode, (_BYTE *)0x310);
      if( v10->Length )
      {
        IoAddTriageDumpDataBlock(v10, (_BYTE *)2);
        IoAddTriageDumpDataBlock(v10->Buffer, (_BYTE *)v10->Length);
      }
      if( DeviceNode->ServiceName.Length )
      {
        IoAddTriageDumpDataBlock(&DeviceNode->ServiceName, (_BYTE *)2);
        IoAddTriageDumpDataBlock(DeviceNode->ServiceName.Buffer, (_BYTE *)DeviceNode->ServiceName.Length);
      }
      v11 = DeviceNode->Parent;
      if( v11 && v11->ServiceName.Length )
      {
        IoAddTriageDumpDataBlock(&v11->ServiceName, (_BYTE *)2);
        IoAddTriageDumpDataBlock(
          DeviceNode->Parent->ServiceName.Buffer,
          (_BYTE *)DeviceNode->Parent->ServiceName.Length);
      }
      KeBugCheckEx(0xCAu, (PVOID)5, DeviceNode->PhysicalDeviceObject, 0i64, 0i64);
    }
    if( (DeviceNode->Flags & 0x20000) != 0 )
    {
      IopLegacyResourceAllocation(ArbiterRequestUndefined, *(&PnpReplaceEvent + 823), PhysicalDeviceObject, 0i64, 0i64);
    }
    else
    {
      DuplicatePDO = DeviceNode->DuplicatePDO;
      if( DuplicatePDO )
        HalPutDmaAdapter((PADAPTER_OBJECT)DuplicatePDO);
      if( DeviceNode->ServiceName.Length )
        ExFreePoolWithTag(DeviceNode->ServiceName.Buffer, 0);
      PnpFreeDeviceInstancePath((__int64)DeviceNode);
      ExAcquireFastMutex((PFAST_MUTEX)((char *)&PnpReplaceEvent + 6336));
      ResourceRequirements = DeviceNode->ResourceRequirements;
      if( ResourceRequirements )
        ExFreePoolWithTag(ResourceRequirements, 0);
      KeReleaseGuardedMutex((PKGUARDED_MUTEX)((char *)&PnpReplaceEvent + 6336));
      IopUncacheInterfaceInformation(DeviceNode->PhysicalDeviceObject, 0);
      p_PendedSetInterfaceState = &DeviceNode->PendedSetInterfaceState;
      while( 1 )
      {
        Flink = p_PendedSetInterfaceState->Flink;
        if( p_PendedSetInterfaceState->Flink == p_PendedSetInterfaceState )
          break;
        if( Flink->Blink != p_PendedSetInterfaceState || (v12 = Flink->Flink, Flink->Flink->Blink != Flink) )
          __fastfail(3u);
        p_PendedSetInterfaceState->Flink = v12;
        v12->Blink = p_PendedSetInterfaceState;
        ExFreePoolWithTag(Flink[1].Blink, 0);
        ExFreePoolWithTag(Flink, 0);
      }
      RebalanceContext = DeviceNode->RebalanceContext;
      if( RebalanceContext )
        ExFreePoolWithTag(RebalanceContext, 0x62655250u);
      DeviceNode->PhysicalDeviceObject->DeviceObjectExtension->DeviceNode = 0i64;
      ExFreePoolWithTag(DeviceNode, 0);
      _InterlockedDecrement((_DWORD *)&PnpReplaceEvent + 1500);
    }
  }
}

Referenced by:

IopDeleteDevice
IopLegacyResourceAllocation
IopRemoveLegacyDeviceNode