IoReportTargetDeviceChangeAsynchronous

NTSTATUS __stdcall IoReportTargetDeviceChangeAsynchronous(
        PDEVICE_OBJECT PhysicalDeviceObject,
        PVOID NotificationStructure,
        PDEVICE_CHANGE_COMPLETE_CALLBACK Callback,
        PVOID Context){
  __int64 v8; 
  GUID *v9; 
  __int64 v10; 
  int v11; 
  char *PoolWithTag; 
  __int16 *v14; 
  _WORD *v15; 
  PVOID *v16; 
  PVOID *v17; 
  __int64 v18; 
  _WORD *v19; 
  __int64 v20; 
  _WORD *v21; 
  __int64 v22; 
  if( !PhysicalDeviceObject )
    goto LABEL_31;
  v8 = *(_QWORD *)(*((_QWORD *)PhysicalDeviceObject + 39) + 40i64);
  if( !v8 || (*(_DWORD *)(v8 + 396) & 0x20000) != 0 )
  {
    IoAddTriageDumpDataBlock(PhysicalDeviceObject, *((unsigned __int16 *)PhysicalDeviceObject + 1));
    v14 = (__int16 *)*((_QWORD *)PhysicalDeviceObject + 1);
    if( v14 )
    {
      IoAddTriageDumpDataBlock(v14, (unsigned int)v14[1]);
      v15 = (_WORD *)(*((_QWORD *)PhysicalDeviceObject + 1) + 56i64);
      if( *v15 )
      {
        IoAddTriageDumpDataBlock(v15, 2ui64);
        IoAddTriageDumpDataBlock(
          *(PVOID *)(*((_QWORD *)PhysicalDeviceObject + 1) + 64i64),
          *(unsigned __int16 *)(*((_QWORD *)PhysicalDeviceObject + 1) + 56i64));
      }
    }
    v16 = *(PVOID **)(*((_QWORD *)PhysicalDeviceObject + 39) + 40i64);
    if( v16 )
    {
      v17 = v16 + 5;
      IoAddTriageDumpDataBlock(v16, 0x310ui64);
      if( *(_WORD *)v17 )
      {
        IoAddTriageDumpDataBlock(v17, 2ui64);
        IoAddTriageDumpDataBlock(v17[1], *(unsigned __int16 *)v17);
      }
      v18 = *((_QWORD *)PhysicalDeviceObject + 39);
      v19 = (_WORD *)(*(_QWORD *)(v18 + 40) + 56i64);
      if( *v19 )
      {
        IoAddTriageDumpDataBlock(v19, 2ui64);
        IoAddTriageDumpDataBlock(
          *(PVOID *)(*(_QWORD *)(*((_QWORD *)PhysicalDeviceObject + 39) + 40i64) + 64i64),
          *(unsigned __int16 *)(*(_QWORD *)(*((_QWORD *)PhysicalDeviceObject + 39) + 40i64) + 56i64));
        v18 = *((_QWORD *)PhysicalDeviceObject + 39);
      }
      v20 = *(_QWORD *)(*(_QWORD *)(v18 + 40) + 16i64);
      if( v20 )
      {
        v21 = (_WORD *)(v20 + 56);
        if( *v21 )
        {
          IoAddTriageDumpDataBlock(v21, 2ui64);
          v22 = *(_QWORD *)(*(_QWORD *)(*((_QWORD *)PhysicalDeviceObject + 39) + 40i64) + 16i64);
          IoAddTriageDumpDataBlock(*(PVOID *)(v22 + 64), *(unsigned __int16 *)(v22 + 56));
        }
      }
    }
LABEL_31:
    KeBugCheckEx(0xCAu, 2ui64, (ULONG_PTR)PhysicalDeviceObject, 0i64, 0i64);
  }
  v9 = (GUID *)((char *)NotificationStructure + 4);
  if( (char *)NotificationStructure + 4 == (char *)&GUID_TARGET_DEVICE_QUERY_REMOVE )
    return -1073741808;
  if( RtlCompareMemory(v9, &GUID_TARGET_DEVICE_QUERY_REMOVE, 0x10ui64) == 16 )
    return -1073741808;
  if( v9 == (GUID *)GUID_TARGET_DEVICE_REMOVE_CANCELLED )
    return -1073741808;
  if( RtlCompareMemory(v9, GUID_TARGET_DEVICE_REMOVE_CANCELLED, 0x10ui64) == 16 )
    return -1073741808;
  if( v9 == &GUID_TARGET_DEVICE_REMOVE_COMPLETE )
    return -1073741808;
  if( RtlCompareMemory(v9, &GUID_TARGET_DEVICE_REMOVE_COMPLETE, 0x10ui64) == 16 )
    return -1073741808;
  v10 = *((unsigned __int16 *)NotificationStructure + 1);
  if( (unsigned __int16)v10 < 0x24u )
    return -1073741808;
  v11 = *((_DWORD *)NotificationStructure + 8);
  if( v11 != -1 && v11 > (int)v10 - 36 )
    return -1073741808;
  if( KeGetCurrentIrql() != 2 )
    return PnpSetCustomTargetEvent(
             PhysicalDeviceObject,
             0i64,
             0i64,
             Callback,
             Context,
             (PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure);
  PoolWithTag = (char *)ExAllocatePoolWithTag(NonPagedPoolNx, v10 + 64, 0x38706E50ui64);
  if( !PoolWithTag )
    return -1073741670;
  ObfReferenceObjectWithTag(PhysicalDeviceObject, 0x4E706E50u);
  *((_QWORD *)PoolWithTag + 4) = PhysicalDeviceObject;
  *((_QWORD *)PoolWithTag + 7) = PoolWithTag + 64;
  memmove((UINT8 *)PoolWithTag + 64, (UINT8 *)NotificationStructure, *((unsigned __int16 *)NotificationStructure + 1));
  *((_QWORD *)PoolWithTag + 5) = Callback;
  *((_QWORD *)PoolWithTag + 6) = Context;
  *((_QWORD *)PoolWithTag + 2) = PnpReportTargetDeviceChangeAsyncWorker;
  *((_QWORD *)PoolWithTag + 3) = PoolWithTag;
  *(_QWORD *)PoolWithTag = 0i64;
  ExQueueWorkItem((WORK_QUEUE_ITEM *)PoolWithTag, DelayedWorkQueue);
  return 259;
}

Referenced by:

FsRtlNotifyVolumeEventEx
PnpDeviceActionWorker