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