PnpRemoveLockedDeviceNode

void __fastcall PnpRemoveLockedDeviceNode(PVOID BugCheckParameter4, UINT64 Problem, NTSTATUS a3){
  _DEVICE_OBJECT *v3; 
  unsigned int v4; 
  int v6; 
  INT64 v7; 
  __int64 v8; 
  _DEVICE_NODE *v9; 
  int v10; 
  INT64 v11; 
  _DEVICE_OBJECT *AttachedDevice; 
  VOID **PoolWithTag; 
  VOID **v14; 
  size_t v15; 
  _DEVICE_OBJECT *v16; 
  VOID **v17; 
  VOID **v18; 
  UINT8 v19; 
  VOID **v20; 
  _QWORD *i; 
  __int64 v22; 
  INT64 v23; 
  INT64 v24; 
  PADAPTER_OBJECT *v25; 
  UINT8 v26; 
  UINT8 v27; 
  _PNP_DEVNODE_STATE v28; 
  INT64 v29; 
  NTSTATUS v30; 
  INT64 v31; 
  WCHAR *v32; 
  unsigned int Flags; 
  _DEVICE_NODE *Sibling; 
  _DEVICE_NODE *v35; 
  unsigned int v36; 

  v36 = Problem;
  v3 = (_DEVICE_OBJECT *)*((_QWORD *)BugCheckParameter4 + 4);
  v4 = Problem;
  v6 = 0;
  PpHotSwapInitRemovalPolicy((_DEVICE_NODE *)BugCheckParameter4);
  v9 = *(_DEVICE_NODE **)(v8 + 8);
  if( v9 )
  {
    do
    {
      Flags = v9->Flags;
      Sibling = v9->Sibling;
      if( (Flags & 0x10) != 0 )
      {
        Flags &= ~0x10u;
        v9->Flags = Flags;
      }
      if( v9->ResourceList || v9->BootResources || (Flags & 0x40) != 0 )
      {
        IopRemoveDevice(v9->PhysicalDeviceObject, 2ui64);
        IopReleaseDeviceResources((PDEVICE_NODE)v9, 0);
      }
      PipSetDevNodeState(v9, DeviceNodeDeleted);
      v9 = Sibling;
    }
    while( Sibling );
  }
  v10 = *((_DWORD *)BugCheckParameter4 + 75);
  if( v10 == 783 || v10 == 782 )
  {
    if( *((_DWORD *)BugCheckParameter4 + 76) == 785 )
      return;
    PipRestoreDevNodeState((_DEVICE_NODE *)BugCheckParameter4);
    v10 = *((_DWORD *)BugCheckParameter4 + 75);
  }
  v11 = 0x140000000ui64;
  if( v10 != 788 )
    JUMPOUT(0x14036F156i64);
  AttachedDevice = v3->AttachedDevice;
  while( AttachedDevice )
  {
    AttachedDevice = AttachedDevice->AttachedDevice;
    ++v6;
  }
  PoolWithTag = 0i64;
  v14 = 0i64;
  if( v6 )
  {
    v15 = 8 * v6 + 16;
    PoolWithTag = ExAllocatePoolWithTag(0x200ui64, v15, 1701081168i64);
    if( PoolWithTag )
    {
      v14 = ExAllocatePoolWithTag(1ui64, v15, 1701081168i64);
      if( v14 )
      {
        memset(PoolWithTag, 0i64, v15);
        memset(v14, 0i64, v15);
        v16 = v3->AttachedDevice;
        v17 = PoolWithTag;
        v18 = v14;
        while( v16 )
        {
          ObfReferenceObject(v16);
          *v17++ = v16;
          *v18++ = v16->DriverObject;
          v16 = v16->AttachedDevice;
        }
        v4 = v36;
      }
      else
      {
        ExFreePoolWithTag(PoolWithTag, 0);
        PoolWithTag = 0i64;
      }
    }
  }
  v19 = KeAcquireQueuedSpinLock(10i64, v11, v7);
  v20 = PoolWithTag;
  if( PoolWithTag )
  {
    for( i = *PoolWithTag; i; i = *v20 )
    {
      *(_DWORD *)(i[39] + 32i64) &= ~4u;
      v22 = (__int64)*v20++;
      *(_DWORD *)(*(_QWORD *)(v22 + 312) + 32i64) |= 8u;
    }
  }
  v3->DeviceObjectExtension->ExtensionFlags &= ~4u;
  v3->DeviceObjectExtension->ExtensionFlags |= 8u;
  KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, v19);
  if( (*((_DWORD *)BugCheckParameter4 + 99) & 0x10) == 0 )
  {
    v23 = 3i64;
    if( (unsigned int)(*((_DWORD *)BugCheckParameter4 + 142) - 3) <= 1 )
      PpProfileCommitTransitioningDock((_DEVICE_NODE *)BugCheckParameter4, DOCK_DEPARTING);
  }
  v25 = (PADAPTER_OBJECT *)PoolWithTag;
  if( PoolWithTag )
  {
    if( *PoolWithTag )
    {
      do
      {
        v26 = KeAcquireQueuedSpinLock(10i64, v23, v24);
        *(_DWORD *)((*v25)->ExpiredLock._bf_0 + 32) &= ~8u;
        *(_DWORD *)((*v25)->ExpiredLock._bf_0 + 32) |= 0x10u;
        KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, v26);
        PnpUnloadAttachedDriver(*(PADAPTER_OBJECT *)((char *)v25 + (char *)v14 - (char *)PoolWithTag));
        HalPutDmaAdapter(*v25++);
      }
      while( *v25 );
    }
    ExFreePoolWithTag(PoolWithTag, 0);
    ExFreePoolWithTag(v14, 0);
  }
  v27 = KeAcquireQueuedSpinLock(10i64, v23, v24);
  v3->DeviceObjectExtension->ExtensionFlags &= ~8u;
  v3->DeviceObjectExtension->ExtensionFlags |= 0x10u;
  KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, v27);
  v28 = DeviceNodeRemoved;
  if( (*((_DWORD *)BugCheckParameter4 + 99) & 0x10) == 0 )
    v28 = DeviceNodeDeleted;
  PipSetDevNodeState((_DEVICE_NODE *)BugCheckParameter4, v28);
  if( v4
    && ((*((_DWORD *)BugCheckParameter4 + 99) & 0x6000) == 0
     || ((v4 - 22) & 0xFFFFFFFD) == 0
     || (unsigned int)PipIsProblemReadonly((_DEVICE_NODE *)BugCheckParameter4, v4)
     && !(unsigned int)PipIsProblemReadonly(v35, *((unsigned int *)BugCheckParameter4 + 101))) )
  {
    PipClearDevNodeProblem((_DEVICE_NODE *)BugCheckParameter4);
    v30 = a3;
    if( !a3 )
      v30 = *((_DWORD *)BugCheckParameter4 + 98);
    PipSetDevNodeProblem((_DEVICE_NODE *)BugCheckParameter4, v4, v30);
  }
  if( (*((_DWORD *)BugCheckParameter4 + 99) & 0x10) == 0 )
    PnpDeleteAllDependencyRelations(v3);
  LOBYTE(v29) = 1;
  PiDmaGuardProcessPostRemove(BugCheckParameter4, v4, v29);
  v32 = (WCHAR *)*((_QWORD *)BugCheckParameter4 + 6);
  if( v32 )
    PnpRaiseNtPlugPlayDevicePropertyChangeEvent(v31, v32, 23);
}

Referenced by:

PnpDeleteLockedDeviceNode