IopCompleteUnloadOrDelete

VOID __fastcall IopCompleteUnloadOrDelete(_DEVICE_OBJECT *DeviceObject, UINT8 OnCleanStack, UINT8 Irql){
  _DRIVER_OBJECT *DriverObject; 
  char v6; 
  unsigned int ExtensionFlags; 
  _DEVICE_OBJECT *AttachedDevice; 
  void *SecurityDescriptor; 
  INT64 v10; 
  INT64 v11; 
  _FAST_IO_DISPATCH *FastIoDispatch; 
  INT64 v13; 
  INT64 v14; 
  void(__fastcall *FastIoDetachDevice)(_DEVICE_OBJECT *, _DEVICE_OBJECT *); 
  VOID *v16; 
  _DEVICE_OBJECT *v17; 
  _DEVICE_OBJECT *v18; 
  unsigned int Flags; 
  _DEVICE_OBJECT *v20; 
  __int64 v21; 
  int v22; 
  int v23; 
  int v24; 
  INT64 v25; 
  _BYTE Parameter[80]; 
  _DEVICE_OBJECT *DeviceAttachmentBase; 
  UINT8 v28; 

  v28 = OnCleanStack;
  DriverObject = DeviceObject->DriverObject;
  v6 = 1;
  ExtensionFlags = DeviceObject->DeviceObjectExtension->ExtensionFlags;
  if( (ExtensionFlags & 4) != 0 )
  {
    DeviceAttachmentBase = IopGetDeviceAttachmentBase(DeviceObject);
    v20 = DeviceAttachmentBase;
    LOBYTE(v22) = PnpIsAnyDeviceInUse((__int64 *)&DeviceAttachmentBase, v21, 0i64);
    v24 = v22;
    KeReleaseQueuedSpinLock((_KSPIN_LOCK_QUEUE_NUMBER)(v23 + 10), Irql);
    if( v24 != 1 )
      PnpChainDereferenceComplete(v20, v28, v25);
    return;
  }
  if( (ExtensionFlags & 2) == 0 )
    goto LABEL_21;
  if( (ExtensionFlags & 1) == 0 || (DriverObject->Flags & 1) != 0 )
    v6 = 0;
  AttachedDevice = DeviceObject->AttachedDevice;
  DeviceAttachmentBase = AttachedDevice;
  if( AttachedDevice )
  {
    FastIoDispatch = AttachedDevice->DriverObject->FastIoDispatch;
    IopIncrementDeviceObjectRefCount(DeviceObject, 0);
    KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, Irql);
    if( FastIoDispatch )
    {
      if( FastIoDispatch->SizeOfFastIoDispatch > 0x68 )
      {
        FastIoDetachDevice = FastIoDispatch->FastIoDetachDevice;
        if( FastIoDetachDevice )
        {
          v16 = (MmVerifierData & 0x10) != 0 ? VfFastIoSnapState() : 0i64;
          FastIoDetachDevice(DeviceAttachmentBase, DeviceObject);
          if( v16 )
            VfFastIoCheckState(v16, FastIoDetachDevice);
        }
      }
    }
    Irql = KeAcquireQueuedSpinLock(10i64, v13, v14);
    IopDecrementDeviceObjectRefCount(DeviceObject, 0);
    if( DeviceObject->AttachedDevice || DeviceObject->ReferenceCount )
      goto LABEL_18;
  }
  KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, Irql);
  SecurityDescriptor = DeviceObject->SecurityDescriptor;
  if( SecurityDescriptor )
    ObDereferenceSecurityDescriptor(SecurityDescriptor, 1ui64);
  IopInsertRemoveDevice(DeviceObject->DriverObject, DeviceObject, 0);
  ObfDereferenceObjectWithTag(DeviceObject, 0x746C6644ui64);
  if( v6 )
  {
    Irql = KeAcquireQueuedSpinLock(10i64, v10, v11);
    if( (DriverObject->Flags & 1) != 0 )
    {
LABEL_18:
      KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, Irql);
      return;
    }
LABEL_21:
    v17 = DriverObject->DeviceObject;
    v18 = v17;
    if( v17 )
    {
      while( !v18->ReferenceCount && !v18->AttachedDevice && (v18->DeviceObjectExtension->ExtensionFlags & 6) == 0 )
      {
        v18 = v18->NextDevice;
        if( !v18 )
          goto LABEL_24;
      }
      v6 = 0;
    }
LABEL_24:
    Flags = DriverObject->Flags;
    if( (Flags & 0x80u) != 0 && v17 )
      v6 = 0;
    if( v6 )
      DriverObject->Flags = Flags | 1;
    KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, Irql);
    if( v6 )
    {
      memset(Parameter, 0i64, sizeof(Parameter));
      Parameter[34] = 6;
      *(_QWORD *)&Parameter[48] = &Parameter[40];
      *(_DWORD *)&Parameter[36] = 0;
      *(_QWORD *)&Parameter[40] = &Parameter[40];
      *(_QWORD *)&Parameter[56] = DriverObject;
      if( v28 )
      {
        IopLoadUnloadDriver(Parameter);
      }
      else
      {
        *(_QWORD *)Parameter = 0i64;
        *(_QWORD *)&Parameter[16] = IopLoadUnloadDriver;
        *(_QWORD *)&Parameter[24] = Parameter;
        ExQueueWorkItem((PWORK_QUEUE_ITEM)Parameter, DelayedWorkQueue);
        KeWaitForSingleObject((UINT64)&Parameter[32], 0, 0, 0, 0i64);
      }
      ObMakeTemporaryObject(DriverObject);
      ObfDereferenceObjectWithTag(DriverObject, 0x746C6644ui64);
    }
  }
}

Referenced by:

IoDeleteDevice
IoDetachDevice
IopDecrementDeviceObjectRef