PnpNotifyTargetDeviceChange

__int64 __fastcall PnpNotifyTargetDeviceChange(VOID *Source1, _DEVICE_OBJECT *pdo, __int64 a3, _QWORD *a4){
  unsigned int v6; 
  _QWORD *DeviceNode; 
  _QWORD *v9; 
  __int64 v10; 
  _EJOB *CurrentServerSilo; 
  _ETHREAD *CurrentThread; 
  INT64 v14; 
  __int128 *v15; 
  int v16; 
  int v17; 
  __int128 v18; 
  void *v19; 
  int v20; 
  void *v21; 
  _EJOB *v22; 
  _ETHREAD *v23; 
  INT64 v24; 
  char v25; 
  int v26; 
  int SessionIdFromPDO; 
  _QWORD *v28; 
  PVOID P; 
  _QWORD *v30; 
  __int128 v31[2]; 

  v30 = a4;
  v6 = 0;
  v26 = 0;
  SessionIdFromPDO = -1;
  memset(v31, 0, sizeof(v31));
  ObfReferenceObjectWithTag(pdo, 0x4E706E50ui64);
  DeviceNode = pdo->DeviceObjectExtension->DeviceNode;
  if( a3 )
  {
    *(_WORD *)a3 = 1;
  }
  else
  {
    v18 = *(_OWORD *)Source1;
    LODWORD(v31[0]) = 2097153;
    *(__int128 *)((char *)v31 + 4) = v18;
  }
  KeAcquireGuardedMutex((PKGUARDED_MUTEX)((char *)&stru_140C452E0 + 256));
  if( Source1 == &GUID_TARGET_DEVICE_REMOVE_CANCELLED
    || RtlCompareMemory(Source1, &GUID_TARGET_DEVICE_REMOVE_CANCELLED, 16) == (_SIZE_T *)16 )
  {
    v9 = (_QWORD *)DeviceNode[60];
    v25 = 1;
  }
  else
  {
    v9 = (_QWORD *)DeviceNode[59];
    v25 = 0;
  }
  v10 = (__int64)(DeviceNode + 59);
  v28 = (_QWORD *)v10;
  while( v9 != (_QWORD *)v10 )
  {
    P = v9;
    CurrentServerSilo = PsGetCurrentServerSilo();
    if( *((_DWORD *)v9 + 5) != PsGetServerSiloServiceSessionId((INT64)CurrentServerSilo) )
      SessionIdFromPDO = IopGetSessionIdFromPDO(pdo);
    ++*((_WORD *)v9 + 28);
    KeReleaseGuardedMutex((PKGUARDED_MUTEX)((char *)&stru_140C452E0 + 256));
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    --CurrentThread->Tcb.KernelApcDisable;
    ExAcquireResourceExclusiveLite(v9[9], 1, v14);
    if( (SessionIdFromPDO == -1 || *((_DWORD *)v9 + 5) == SessionIdFromPDO) && !*((_BYTE *)v9 + 58) )
    {
      if( a3 )
      {
        *(_QWORD *)(a3 + 24) = v9[10];
        v15 = (__int128 *)a3;
      }
      else
      {
        *((_QWORD *)&v31[1] + 1) = v9[10];
        v15 = v31;
      }
      v16 = PnpNotifyDriverCallback((__int64)v9, (__int64)v15, &v26);
      ExReleaseResourceLite((PERESOURCE)v9[9]);
      KeLeaveCriticalRegion();
      v17 = v26;
      if( v16 < 0 )
        v17 = 0;
      v26 = v17;
      if( v17 < 0
        && (Source1 == &GUID_TARGET_DEVICE_QUERY_REMOVE
         || RtlCompareMemory(Source1, &GUID_TARGET_DEVICE_QUERY_REMOVE, 16) == (_SIZE_T *)16) )
      {
        if( v30 )
          *v30 = v9[6];
        v19 = v9;
        *(GUID *)((char *)v31 + 4) = GUID_TARGET_DEVICE_REMOVE_CANCELLED;
        KeAcquireGuardedMutex((PKGUARDED_MUTEX)((char *)&stru_140C452E0 + 256));
        do
        {
          v20 = -1;
          v21 = v9;
          v22 = PsGetCurrentServerSilo();
          if( *((_DWORD *)v9 + 5) != PsGetServerSiloServiceSessionId((INT64)v22) )
            v20 = IopGetSessionIdFromPDO(pdo);
          ++*((_WORD *)v9 + 28);
          KeReleaseGuardedMutex((PKGUARDED_MUTEX)((char *)&stru_140C452E0 + 256));
          v23 = (_ETHREAD *)KeGetCurrentThread();
          --v23->Tcb.KernelApcDisable;
          ExAcquireResourceExclusiveLite(v9[9], 1, v24);
          if( (v20 == -1 || *((_DWORD *)v9 + 5) == v20) && !*((_BYTE *)v9 + 58) )
          {
            *((_QWORD *)&v31[1] + 1) = v9[10];
            PnpNotifyDriverCallback((__int64)v9, (__int64)v31, 0i64);
          }
          ExReleaseResourceLite((PERESOURCE)v9[9]);
          KeLeaveCriticalRegion();
          KeAcquireGuardedMutex((PKGUARDED_MUTEX)((char *)&stru_140C452E0 + 256));
          v9 = (_QWORD *)v9[1];
          PnpDereferenceNotify(v21);
          if( v21 == v19 )
            PnpDereferenceNotify(v19);
        }
        while( v9 != v28 );
        v6 = v26;
        break;
      }
      v10 = (__int64)v28;
    }
    else
    {
      ExReleaseResourceLite((PERESOURCE)v9[9]);
      KeLeaveCriticalRegion();
    }
    KeAcquireGuardedMutex((PKGUARDED_MUTEX)((char *)&stru_140C452E0 + 256));
    if( v25 )
      v9 = (_QWORD *)v9[1];
    else
      v9 = (_QWORD *)*v9;
    PnpDereferenceNotify(P);
  }
  KeReleaseGuardedMutex((PKGUARDED_MUTEX)((char *)&stru_140C452E0 + 256));
  ObfDereferenceObjectWithTag(pdo, 0x4E706E50ui64);
  return v6;
}

Referenced by:

PiSendTargetDeviceRemoveCanceledNotification
PiSendTargetDeviceRemoveCompleteNotification
PipSendTargetDeviceQueryRemoveNotification
PnpCancelRemoveOnHungDevices
PnpProcessCustomDeviceEvent