IopCompleteUnloadOrDelete
UINT8 __stdcall IopCompleteUnloadOrDelete(_DEVICE_OBJECT *DeviceObject, UINT8 OnCleanStack, UINT8 Irql){
UINT8 v3;
__int64 v4;
UINT8 v7;
char v8;
int v9;
__int64 v10;
void *v11;
__int64 v13;
void(__fastcall *v14)(DEVICE_OBJECT *, _DEVICE_OBJECT *);
void *v15;
__int64 v16;
__int64 v17;
int v18;
_DEVICE_OBJECT *v19;
DEVICE_OBJECT **v20;
int v21;
int IsAnyDeviceInUse;
INT64 v23;
INT64 v24;
struct _WORK_QUEUE_ITEM WorkItem;
char Object[4];
int v27;
__int64 v28[5];
DEVICE_OBJECT *DeviceObjects;
UINT8 v30;
v30 = OnCleanStack;
v3 = 0;
v4 = *((_QWORD *)DeviceObject + 1);
v7 = 0;
v8 = 1;
v9 = *(_DWORD *)(*((_QWORD *)DeviceObject + 39) + 32i64);
if( (v9 & 4) == 0 )
{
if( (v9 & 2) != 0 )
{
if( (v9 & 1) == 0 || (*(_DWORD *)(v4 + 16) & 1) != 0 )
v8 = 0;
v10 = *((_QWORD *)DeviceObject + 3);
DeviceObjects = (DEVICE_OBJECT *)v10;
if( v10 )
{
v13 = *(_QWORD *)(*(_QWORD *)(v10 + 8) + 80i64);
IopIncrementDeviceObjectRefCount(DeviceObject, 0);
KeReleaseQueuedSpinLock(0xAui64, Irql);
if( v13 )
{
if( *(_DWORD *)v13 > 0x68u )
{
v14 = *(void(__fastcall **)(DEVICE_OBJECT *, _DEVICE_OBJECT *))(v13 + 104);
if( v14 )
{
v15 = (MmVerifierData & 0x10) != 0 ? VfFastIoSnapState() : 0i64;
v14(DeviceObjects, DeviceObject);
if( v15 )
VfFastIoCheckState(v15, v14);
}
}
}
Irql = KeAcquireQueuedSpinLock(0xAui64);
IopDecrementDeviceObjectRefCount(DeviceObject, 0);
if( *((_QWORD *)DeviceObject + 3) || *((_DWORD *)DeviceObject + 1) )
goto LABEL_18;
}
KeReleaseQueuedSpinLock(0xAui64, Irql);
v11 = (void *)*((_QWORD *)DeviceObject + 34);
if( v11 )
ObDereferenceSecurityDescriptor(v11, 1ui64);
IopInsertRemoveDevice(*((_DRIVER_OBJECT **)DeviceObject + 1), DeviceObject, 0);
ObfDereferenceObjectWithTag(DeviceObject, 0x746C6644ui64);
v7 = 1;
if( !v8 )
return v7;
Irql = KeAcquireQueuedSpinLock(0xAui64);
if( (*(_DWORD *)(v4 + 16) & 1) != 0 )
{
v3 = 1;
LABEL_18:
KeReleaseQueuedSpinLock(0xAui64, Irql);
return v3;
}
}
v16 = *(_QWORD *)(v4 + 8);
v17 = v16;
if( v16 )
{
while( !*(_DWORD *)(v17 + 4) && !*(_QWORD *)(v17 + 24) && (*(_DWORD *)(*(_QWORD *)(v17 + 312) + 32i64) & 6) == 0 )
{
v17 = *(_QWORD *)(v17 + 16);
if( !v17 )
goto LABEL_24;
}
v8 = 0;
}
LABEL_24:
v18 = *(_DWORD *)(v4 + 16);
if( (v18 & 0x80u) != 0 && v16 )
v8 = 0;
if( v8 )
*(_DWORD *)(v4 + 16) = v18 | 1;
KeReleaseQueuedSpinLock(0xAui64, Irql);
if( v8 )
{
memset((INT64)&WorkItem, 0i64);
Object[2] = 6;
v28[1] = (__int64)v28;
v27 = 0;
v28[0] = (__int64)v28;
v28[2] = v4;
if( v30 )
{
IopLoadUnloadDriver(&WorkItem);
}
else
{
WorkItem.List.Flink = 0i64;
WorkItem.WorkerRoutine = (void(__fastcall *)(void *))IopLoadUnloadDriver;
WorkItem.Parameter = &WorkItem;
ExQueueWorkItem(&WorkItem, DelayedWorkQueue);
KeWaitForSingleObject(Object, Executive, 0, 0, 0i64);
}
ObMakeTemporaryObject((PVOID)v4);
ObfDereferenceObjectWithTag((PVOID)v4, 0x746C6644ui64);
}
return v7;
}
DeviceObjects = IopGetDeviceAttachmentBase(DeviceObject);
v19 = DeviceObjects;
IsAnyDeviceInUse = PnpIsAnyDeviceInUse(&DeviceObjects, v20);
KeReleaseQueuedSpinLock((unsigned int)(v21 + 10), Irql);
if( IsAnyDeviceInUse != 1 )
PnpChainDereferenceComplete(v19, v30, v23, v24);
return 0;
}Referenced by:
IoDeleteDevice
IoDetachDevice
IopDecrementDeviceObjectRef