IopDecrementDeviceObjectRef
UINT8 __stdcall IopDecrementDeviceObjectRef(_DEVICE_OBJECT *DeviceObject, UINT8 AlwaysUnload, UINT8 OnCleanStack){
UINT8 v6;
UINT8 CurrentIrql;
volatile __int64 **v8;
int ReferenceCount;
_KSPIN_LOCK_QUEUE *v10;
_KSPIN_LOCK_QUEUE *Next;
UINT8 v13;
_DRIVER_OBJECT *DriverObject;
v6 = 0;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v8 = (volatile __int64 **)((char *)KeGetPcr()->NtTib.ArbitraryUserPointer + 160);
if( _InterlockedExchange64(v8[1], (__int64)v8) )
KxWaitForLockOwnerShip((INT64)v8);
ReferenceCount = DeviceObject->ReferenceCount - 1;
DeviceObject->ReferenceCount = ReferenceCount;
if( ReferenceCount < 0 )
{
DriverObject = DeviceObject->DriverObject;
if( DriverObject )
{
IoAddTriageDumpDataBlock(DriverObject, (_BYTE *)0x150);
IoAddTriageDumpDataBlock(
DeviceObject->DriverObject->DriverName.Buffer,
(_BYTE *)DeviceObject->DriverObject->DriverName.Length);
ReferenceCount = DeviceObject->ReferenceCount;
}
KeBugCheckEx(0x18u, 0i64, DeviceObject, (PVOID)6, (PVOID)ReferenceCount);
}
if( !ReferenceCount && (AlwaysUnload || (DeviceObject->DeviceObjectExtension->ExtensionFlags & 7) != 0) )
{
IopCompleteUnloadOrDelete(DeviceObject, OnCleanStack, CurrentIrql);
return v13;
}
v10 = (_KSPIN_LOCK_QUEUE *)((char *)KeGetPcr()->NtTib.ArbitraryUserPointer + 160);
_m_prefetchw(v10);
Next = v10->Next;
if( v10->Next )
goto LABEL_13;
if( v10 != (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)v10->Lock,
0i64,
(signed __int64)v10) )
{
Next = KxWaitForLockChainValid(v10);
LABEL_13:
v10->Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
}
__writecr8(CurrentIrql);
return v6;
}Referenced by:
IoCreateStreamFileObjectEx2
IopCheckVpbMounted
IopDecrementDeviceObjectHandleCount
IopDeleteFile
IopLoadFileSystemDriver
IopMountVolume
IopParseDevice
IopShutdownBaseFileSystems