PnpRemoveLockedDeviceNode

VOID __stdcall PnpRemoveLockedDeviceNode(_DEVICE_NODE *DeviceNode, UINT64 Problem, INT64 ProblemStatus){
  __int64 v3; 
  int v4; 
  int v6; 
  UINT64 v7; 
  _PNP_DEVNODE_STATE *v8; 
  __int64 v9; 
  __int64 v10; 
  int v11; 
  __int64 v12; 
  _QWORD *PoolWithTag; 
  _QWORD *v14; 
  unsigned int v15; 
  _QWORD *v16; 
  _QWORD *v17; 
  _QWORD *v18; 
  KIRQL v19; 
  __int64 *v20; 
  __int64 i; 
  __int64 v22; 
  PADAPTER_OBJECT *v23; 
  KIRQL v24; 
  KIRQL v25; 
  _PNP_DEVNODE_STATE *v26; 
  _PNP_DEVNODE_STATE v27; 
  const WCHAR *v28; 
  INT64 v29; 
  int v30; 
  __int64 v31; 
  __int64 v32; 
  int v33; 
  __int64 v34; 
  __int64 v35; 
  int v36; 
  int v37; 
  v37 = ProblemStatus;
  v36 = Problem;
  v3 = *((_QWORD *)DeviceNode + 4);
  v4 = Problem;
  v6 = 0;
  PpHotSwapInitRemovalPolicy((__int64)DeviceNode);
  v10 = *(_QWORD *)(v9 + 8);
  if( v10 )
  {
    do
    {
      v33 = *(_DWORD *)(v10 + 396);
      v34 = *(_QWORD *)v10;
      if( (v33 & 0x10) != 0 )
      {
        v33 &= ~0x10u;
        *(_DWORD *)(v10 + 396) = v33;
      }
      if( *(_QWORD *)(v10 + 416) || *(_QWORD *)(v10 + 544) || (v33 & 0x40) != 0 )
      {
        IopRemoveDevice(*(DEVICE_OBJECT **)(v10 + 32), 2ui64);
        IopReleaseDeviceResources(v10, 0);
      }
      PipSetDevNodeState((_DEVICE_NODE *)v10, DeviceNodeDeleted, v8);
      v10 = v34;
    }
    while( v34 );
  }
  v11 = *((_DWORD *)DeviceNode + 75);
  if( v11 == 783 || v11 == 782 )
  {
    if( *((_DWORD *)DeviceNode + 76) == 785 )
      return;
    PipRestoreDevNodeState((__int64)DeviceNode, v7);
    v11 = *((_DWORD *)DeviceNode + 75);
  }
  if( v11 != 788 )
    JUMPOUT(0x14036F156i64);
  v12 = *(_QWORD *)(v3 + 24);
  while( v12 )
  {
    v12 = *(_QWORD *)(v12 + 24);
    ++v6;
  }
  PoolWithTag = 0i64;
  v14 = 0i64;
  if( v6 )
  {
    v15 = 8 * v6 + 16;
    PoolWithTag = ExAllocatePoolWithTag(NonPagedPoolNx, v15, 0x65647050ui64);
    if( PoolWithTag )
    {
      v14 = ExAllocatePoolWithTag(PagedPool, v15, 0x65647050ui64);
      if( v14 )
      {
        memset((INT64)PoolWithTag, 0i64);
        memset((INT64)v14, 0i64);
        v16 = *(_QWORD **)(v3 + 24);
        v17 = PoolWithTag;
        v18 = v14;
        while( v16 )
        {
          ObfReferenceObject(v16);
          *v17++ = v16;
          *v18++ = v16[1];
          v16 = (_QWORD *)v16[3];
        }
        v4 = v36;
      }
      else
      {
        ExFreePoolWithTag(PoolWithTag, 0);
        PoolWithTag = 0i64;
      }
    }
  }
  v19 = KeAcquireQueuedSpinLock(0xAui64);
  v20 = PoolWithTag;
  if( PoolWithTag )
  {
    for( i = *PoolWithTag; i; i = *v20 )
    {
      *(_DWORD *)(*(_QWORD *)(i + 312) + 32i64) &= ~4u;
      v22 = *v20++;
      *(_DWORD *)(*(_QWORD *)(v22 + 312) + 32i64) |= 8u;
    }
  }
  *(_DWORD *)(*(_QWORD *)(v3 + 312) + 32i64) &= ~4u;
  *(_DWORD *)(*(_QWORD *)(v3 + 312) + 32i64) |= 8u;
  KeReleaseQueuedSpinLock(0xAui64, v19);
  if( (*((_DWORD *)DeviceNode + 99) & 0x10) == 0 && (unsigned int)(*((_DWORD *)DeviceNode + 142) - 3) <= 1 )
    PpProfileCommitTransitioningDock(DeviceNode, DOCK_DEPARTING);
  v23 = (PADAPTER_OBJECT *)PoolWithTag;
  if( PoolWithTag )
  {
    if( *PoolWithTag )
    {
      do
      {
        v24 = KeAcquireQueuedSpinLock(0xAui64);
        LODWORD((*v23)[19].DmaOperations->AllocateAdapterChannel) &= ~8u;
        LODWORD((*v23)[19].DmaOperations->AllocateAdapterChannel) |= 0x10u;
        KeReleaseQueuedSpinLock(0xAui64, v24);
        PnpUnloadAttachedDriver(*(DRIVER_OBJECT **)((char *)v23 + (char *)v14 - (char *)PoolWithTag));
        HalPutDmaAdapter(*v23++);
      }
      while( *v23 );
    }
    ExFreePoolWithTag(PoolWithTag, 0);
    ExFreePoolWithTag(v14, 0);
  }
  v25 = KeAcquireQueuedSpinLock(0xAui64);
  *(_DWORD *)(*(_QWORD *)(v3 + 312) + 32i64) &= ~8u;
  *(_DWORD *)(*(_QWORD *)(v3 + 312) + 32i64) |= 0x10u;
  KeReleaseQueuedSpinLock(0xAui64, v25);
  v27 = DeviceNodeRemoved;
  if( (*((_DWORD *)DeviceNode + 99) & 0x10) == 0 )
    v27 = DeviceNodeDeleted;
  PipSetDevNodeState(DeviceNode, v27, v26);
  if( v4
    && ((*((_DWORD *)DeviceNode + 99) & 0x6000) == 0
     || ((v4 - 22) & 0xFFFFFFFD) == 0
     || (unsigned int)PipIsProblemReadonly((__int64)DeviceNode, v4)
     && !(unsigned int)PipIsProblemReadonly(v35, *((_DWORD *)DeviceNode + 101))) )
  {
    PipClearDevNodeProblem((INT64)DeviceNode, v28, v29);
    v30 = v37;
    if( !v37 )
      v30 = *((_DWORD *)DeviceNode + 98);
    PipSetDevNodeProblem((__int64)DeviceNode, v4, v30);
  }
  if( (*((_DWORD *)DeviceNode + 99) & 0x10) == 0 )
    PnpDeleteAllDependencyRelations((DEVICE_OBJECT *)v3);
  PiDmaGuardProcessPostRemove((UINT32)DeviceNode);
  v32 = *((_QWORD *)DeviceNode + 6);
  if( v32 )
    PnpRaiseNtPlugPlayDevicePropertyChangeEvent(v31, v32, 23);
}

Referenced by:

PnpDeleteLockedDeviceNode