PnpProcessQueryRemoveAndEject

__int64 __fastcall PnpProcessQueryRemoveAndEject(const VOID **a1){
  const VOID *v1; 
  __int64 v2; 
  char *v3; 
  _DEVICE_OBJECT *v4; 
  unsigned int v5; 
  __int64 DeviceNode; 
  int v7; 
  PNP_VETO_TYPE **v8; 
  int v9; 
  _UNICODE_STRING **v10; 
  char *VetoBuffer; 
  _RELATION_LIST *v12; 
  int v13; 
  char v14; 
  int v15; 
  __int64 v16; 
  PVOID v17; 
  __int128 *v18; 
  unsigned int v19; 
  __int64 v20; 
  _DEVICE_OBJECT *v22; 
  char v23; 
  __int64 v24; 
  UINT8 v25; 
  __int64 v26; 
  _UNICODE_STRING *v27; 
  int v28; 
  char v29; 
  _UNICODE_STRING *v30; 
  int v31; 
  int v32; 
  INT64 v33; 
  INT64 v34; 
  __int64 v35; 
  _QWORD *v36; 
  __int64 v37; 
  __int64 v38; 
  _DWORD *v39; 
  _DEVICE_NODE *v40; 
  __int64 PendingEjectRelations; 
  __int64 v42; 
  VOID **v43; 
  _PENDING_RELATIONS_LIST_ENTRY *v44; 
  UINT8 v45; 
  UINT8 v46; 
  NTSTATUS LightestSystemStateForEject; 
  INT64 v48; 
  INT64 v49; 
  INT64 v50; 
  INT64 v51; 
  INT64 v52; 
  INT64 v53; 
  INT64 v54; 
  PVOID P; 
  PVOID v56; 
  WCHAR *VetoList; 
  _RELATION_LIST *List; 
  _DEVICE_OBJECT *v59; 
  __int64 v60; 
  _DEVICE_OBJECT *DeviceObject; 
  PVOID v62; 
  _UNICODE_STRING DestinationString[5]; 
  UINT8 WarmEjectSupporteda; 
  INT64 v66; 
  int SubsumeExistingDeparture; 
  UINT64 v68; 

  v1 = *a1;
  VetoList = 0i64;
  v2 = 0i64;
  v60 = 0i64;
  v3 = 0i64;
  v4 = (_DEVICE_OBJECT *)*((_QWORD *)v1 + 19);
  v56 = 0i64;
  v5 = 7;
  LODWORD(v68) = 0;
  LOBYTE(v66) = 0;
  DeviceObject = 0i64;
  List = 0i64;
  LOBYTE(SubsumeExistingDeparture) = 0;
  P = 0i64;
  v62 = 0i64;
  v59 = v4;
  DestinationString[0] = 0i64;
  if( v4 )
    DeviceNode = (__int64)v4->DeviceObjectExtension->DeviceNode;
  else
    DeviceNode = 0i64;
  PpDevNodeLockTree(PPL_TREEOP_ALLOW_READS);
  if( (unsigned int)(*(_DWORD *)(DeviceNode + 300) - 787) <= 1 )
  {
    v9 = -1073741738;
    goto LABEL_53;
  }
  v7 = PiDetermineDeleteType((INT64)v1);
  v5 = v7;
  if( v7 != 4 )
    PnpRecordBlackboxPnpEventInformation((INT64)v1, v7, 0i64, 1);
  v9 = PiCheckRemovalPreconditions(v5, (INT64)v1);
  if( v9 < 0 )
    goto LABEL_53;
  if( v5 == 4 )
  {
    if( (*(_DWORD *)(DeviceNode + 396) & 0x80000) != 0 )
    {
LABEL_52:
      v9 = 0;
LABEL_53:
      PpDevNodeUnlockTree(PPL_TREEOP_ALLOW_READS);
      goto LABEL_54;
    }
    if( (unsigned int)(*(_DWORD *)(DeviceNode + 568) - 3) <= 1 )
    {
      v29 = 0;
    }
    else
    {
      if( (*(_DWORD *)(DeviceNode + 560) & 0x10) == 0 )
      {
        v9 = -2147483608;
        v27 = (_UNICODE_STRING *)(DeviceNode + 40);
        v28 = 8;
        goto LABEL_134;
      }
      v29 = 1;
    }
    v9 = 0;
    if( !v29 )
      goto LABEL_53;
  }
  if( !v5 && !(unsigned int)PipAreDriversLoaded(DeviceNode) )
  {
    v9 = PiProcessQueryRemoveNoFdo((INT64)v1);
    goto LABEL_53;
  }
  VetoBuffer = (char *)PiEventAllocateVetoBuffer((PNP_DEVICE_DELETE_TYPE)v5, v8, v10);
  v3 = VetoBuffer;
  if( !VetoBuffer )
    goto LABEL_78;
  if( (int)PnpBuildRemovalRelationList((__int64)v4, v5, (__int64)VetoBuffer, &List) < 0 )
  {
LABEL_79:
    v31 = *(_DWORD *)v3;
    v30 = (_UNICODE_STRING *)(v3 + 8);
    goto LABEL_80;
  }
  v12 = List;
  v9 = PiEventBuildPdoList(
         List,
         v5,
         (__int64)v1,
         &v68,
         (__int64)&v56,
         (_RELATION_LIST_MARKER)&v66,
         (__int64)&SubsumeExistingDeparture);
  if( v9 < 0 )
    goto LABEL_132;
  v13 = PnpResizeTargetDeviceBlock(a1, v5);
  v1 = *a1;
  v9 = v13;
  if( v13 < 0 )
    goto LABEL_132;
  v14 = PiEventAreDeviceRelationsExcluded(v5);
  v9 = PnpCompileDeviceInstancePaths(v15, v12, v14, 0, &P);
  if( v5 == 3 )
    PnpBuildUnsafeRemovalDeviceList(v16, v12, &v62);
  if( v9 < 0 )
  {
LABEL_132:
    IopFreeRelationList(v12);
    if( v9 == -2147483608 )
      goto LABEL_53;
    v27 = 0i64;
    v28 = 0;
LABEL_134:
    PnpFinalizeVetoedRemove((__int64)v1, v28, v27);
    goto LABEL_53;
  }
  if( !(_BYTE)v66 )
    goto LABEL_17;
  PpProfileBeginHardwareProfileTransition(SubsumeExistingDeparture);
  v35 = (int)v68 - 1;
  if( (int)v68 - 1 >= 0 )
  {
    v36 = v56;
    do
    {
      v37 = v36[v35];
      if( v37 )
        v38 = *(_QWORD *)(*(_QWORD *)(v37 + 312) + 40i64);
      else
        v38 = 0i64;
      if( *(_DWORD *)(v38 + 568) == 1 )
        PpProfileIncludeInHardwareProfileTransition((_DEVICE_NODE *)v38, DOCK_DEPARTING);
      --v35;
    }
    while( v35 >= 0 );
    v12 = List;
  }
  if( v5 == 4 )
  {
    if( IoGetLegacyVetoList(&VetoList, (PNP_VETO_TYPE *)v3, v33, v34, v48, v50, v52, v54) >= 0 && *(_DWORD *)v3 )
    {
      PpProfileCancelHardwareProfileTransition();
      IopFreeRelationList(v12);
      v39 = (_DWORD *)*((_QWORD *)v1 + 6);
      if( v39 )
        *v39 = *(_DWORD *)v3;
      if( *((_QWORD *)v1 + 7) )
      {
        RtlInitUnicodeString(DestinationString, VetoList);
        RtlCopyUnicodeString(*((PUNICODE_STRING *)v1 + 7), DestinationString);
      }
      ExFreePoolWithTag(VetoList, 0);
      VetoList = 0i64;
      goto LABEL_84;
    }
    if( PpProfileQueryHardwareProfileChange(
           SubsumeExistingDeparture,
           PROFILE_IN_PNPEVENT,
           (PNP_VETO_TYPE *)v3,
           (_UNICODE_STRING *)(v3 + 8)) < 0 )
    {
      PpProfileCancelHardwareProfileTransition();
      IopFreeRelationList(v12);
      goto LABEL_79;
    }
  }
  else
  {
LABEL_17:
    if( (v5 & 0xFFFFFFFB) != 0 )
    {
      if( ((v5 - 3) & 0xFFFFFFFD) == 0 )
        PnpDeleteLockedDeviceNodes(v59, v12, 3, 0, 0, 0, 0i64, 0i64);
      goto LABEL_20;
    }
  }
  PnpTrackQueryRemoveDevices(v12, 1);
  v9 = PiProcessQueryAndCancelRemoval(
         v5,
         (INT64)v1,
         (UINT64 **)v12,
         (unsigned int)v68,
         (VOID **)v56,
         (INT64 *)v3,
         (const VOID **)&P);
  if( v9 < 0 )
  {
    if( (_BYTE)v66 )
      PpProfileCancelHardwareProfileTransition();
    if( *((_DWORD *)v1 + 4) == 54 )
      v9 = PiProcessCanceledRemoveForReset(v5, (INT64)v1, (UINT64 **)v12, (INT64 *)v3);
    PnpTrackQueryRemoveDevices(v12, 0);
    IopFreeRelationList(v12);
    goto LABEL_53;
  }
LABEL_20:
  if( v5 == 3 )
  {
    v17 = v62;
    if( v62 )
    {
      PnpNotifyUserModeDeviceRemoval((__int64)v1, v62, (__int128 *)&GUID_DEVICE_SURPRISE_REMOVAL, 0i64, 0i64, 0i64);
      ExFreePoolWithTag(v17, 0x4B706E50u);
    }
    v18 = (__int128 *)&GUID_TARGET_DEVICE_REMOVE_COMPLETE;
  }
  else
  {
    v18 = (__int128 *)&GUID_DEVICE_REMOVE_PENDING;
  }
  PnpNotifyUserModeDeviceRemoval((__int64)v1, P, v18, 0i64, 0i64, 0i64);
  v19 = v68;
  PiSendTargetDeviceRemoveCompleteNotification(v5, (_DEVICE_OBJECT **)v56, v68);
  if( ((v5 - 2) & 0xFFFFFFFC) != 0
    || v5 == 4
    || (PnpInvalidateRelationsInList(v12, (PNP_DEVICE_DELETE_TYPE)v5, 1, 0),
        IopRemoveDeviceRelationsFromList(v12),
        v5 != 3) )
  {
    if( v5 != 5 )
    {
      v22 = v59;
      if( *(_DWORD *)(DeviceNode + 568) )
      {
        IopQueryDockRemovalInterface(v59, &v60);
        v2 = v60;
        if( v60 )
          (*(void(__fastcall **)(_QWORD, __int64))(v60 + 32))(*(_QWORD *)(v60 + 8), 3i64);
      }
      if( v5 )
      {
        if( v5 != 4 )
        {
          v23 = 0;
LABEL_45:
          PnpDeleteLockedDeviceNodes(v22, v12, 2, v23, *((_DWORD *)v1 + 4), *((_DWORD *)v1 + 5), 0i64, 0i64);
          v24 = *(_DWORD *)(DeviceNode + 560) >> 3;
          LOBYTE(v24) = (*(_DWORD *)(DeviceNode + 560) & 8) != 0;
          v25 = HIWORD(*(_DWORD *)(DeviceNode + 560)) & 1;
          SubsumeExistingDeparture = v24;
          WarmEjectSupporteda = v25;
          if( v5 != 4 )
          {
            PiRestartRemovalRelations((INT64)v1, (UINT64 **)v12, v22);
            PnpUnlinkDeviceRemovalRelations(v26, v12);
            if( v5 )
            {
LABEL_47:
              IopFreeRelationList(v12);
              if( v5 == 2 )
                PnpNotifyUserModeDeviceRemoval(
                  (__int64)v1,
                  P,
                  (__int128 *)&GUID_TARGET_DEVICE_REMOVE_COMPLETE,
                  0i64,
                  0i64,
                  0i64);
              if( !v5
                && (*((_DWORD *)v1 + 36) & 2) == 0
                && (*(_DWORD *)(DeviceNode + 396) & 0x2000) != 0
                && *(_DWORD *)(DeviceNode + 404) == 18 )
              {
                PipClearDevNodeProblem((_DEVICE_NODE *)DeviceNode);
                PnpRestartDeviceNode((_DEVICE_NODE *)DeviceNode);
                PnpRequestDeviceAction(*(PVOID *)(DeviceNode + 32), 16, 1, 0i64, 0i64, 0i64, 0i64);
              }
              if( v2 )
              {
                (*(void(__fastcall **)(_QWORD, __int64))(v2 + 32))(*(_QWORD *)(v2 + 8), 1i64);
                (*(void(__fastcall **)(_QWORD))(v2 + 24))(*(_QWORD *)(v2 + 8));
              }
              goto LABEL_52;
            }
LABEL_64:
            PnpTrackQueryRemoveDevices(v12, 0);
            goto LABEL_47;
          }
          if( !(_BYTE)v24 && !v25 )
          {
            PnpUnlinkDeviceRemovalRelations(v24, v12);
            goto LABEL_64;
          }
          v68 = 1i64;
          while( IopEnumerateRelations(v12, (_RELATION_LIST_MARKER *)&v68, &DeviceObject, 0i64, 0i64) )
          {
            if( DeviceObject )
              v40 = (_DEVICE_NODE *)DeviceObject->DeviceObjectExtension->DeviceNode;
            else
              v40 = 0i64;
            if( v40 )
            {
              PipSetDevNodeFlags(v40, 0x80000ui64);
              PendingEjectRelations = (__int64)v40->PendingEjectRelations;
              v60 = PendingEjectRelations;
              if( PendingEjectRelations )
              {
                IopFreeRelationList(*(_RELATION_LIST **)(PendingEjectRelations + 64));
                *(_QWORD *)(v60 + 64) = 0i64;
                v40->PendingEjectRelations = 0i64;
              }
            }
          }
          PnpUnlinkDeviceRemovalRelations(v42, v12);
          v43 = PiEventAllocatePendingEjectRelations((__int64)v1, (__int64)v12, v66, v2);
          v44 = (_PENDING_RELATIONS_LIST_ENTRY *)v43;
          if( v43 )
          {
            v45 = SubsumeExistingDeparture;
            v46 = v66;
            *(_QWORD *)(DeviceNode + 696) = v43;
            LightestSystemStateForEject = PoGetLightestSystemStateForEject(
                                            v46,
                                            v45,
                                            WarmEjectSupporteda,
                                            (_SYSTEM_POWER_STATE *)v43 + 23,
                                            v49,
                                            v51,
                                            v53);
            if( LightestSystemStateForEject >= 0 )
            {
              PpDevNodeUnlockTree(PPL_TREEOP_ALLOW_READS);
              IopEjectDevice(v59, v44);
              v9 = 259;
LABEL_54:
              if( v9 == -1073741738 )
                goto LABEL_32;
              goto LABEL_28;
            }
            v32 = 0;
            if( LightestSystemStateForEject == -1073741090 )
              v32 = 9;
            PnpFinalizeVetoedRemove((__int64)v1, v32, 0i64);
            v44->DeviceEvent = 0i64;
            v44->DisplaySafeRemovalDialog = 0;
            v44->Link.Blink = &v44->Link;
            v44->Link.Flink = &v44->Link;
            PnpProcessCompletedEject(v44);
            goto LABEL_84;
          }
          if( v2 )
          {
            (*(void(__fastcall **)(_QWORD, __int64))(v2 + 32))(*(_QWORD *)(v2 + 8), 1i64);
            (*(void(__fastcall **)(_QWORD))(v2 + 24))(*(_QWORD *)(v2 + 8));
          }
          if( (_BYTE)v66 )
            PpProfileCancelHardwareProfileTransition();
          PnpInvalidateRelationsInList(v12, EjectDevice, 0, 1);
          PnpTrackQueryRemoveDevices(v12, 0);
          IopFreeRelationList(v12);
LABEL_78:
          v30 = 0i64;
          v31 = 0;
LABEL_80:
          PnpFinalizeVetoedRemove((__int64)v1, v31, v30);
LABEL_84:
          v9 = -2147483608;
          goto LABEL_53;
        }
      }
      else
      {
        PipSetDevNodeFlags((_DEVICE_NODE *)DeviceNode, 0x2000000ui64);
      }
      v23 = 1;
      goto LABEL_45;
    }
  }
  PiEventRemovalPostSurpriseRemove((__int64)v1, v5, &List);
  PpDevNodeUnlockTree(PPL_TREEOP_ALLOW_READS);
  PnpIsChainDereferenced((PDEVICE_OBJECT *)v56, v19, 0i64, 1i64, 0i64);
  v9 = 0;
LABEL_28:
  if( v5 != 4 )
  {
    if( v3 )
      v20 = (__int64)v3;
    else
      v20 = 0i64;
    PnpRecordBlackboxPnpEventInformation((INT64)v1, v5, v20, 0);
  }
LABEL_32:
  if( v3 && !*(&PnpReplaceEvent + 1665) )
  {
    ExFreePoolWithTag(*((PVOID *)v3 + 2), 0x4D706E50u);
    *((_QWORD *)v3 + 2) = 0i64;
    ExFreePoolWithTag(v3, 0x4D706E50u);
  }
  if( P )
    ExFreePoolWithTag(P, 0);
  if( v56 )
    ExFreePoolWithTag(v56, 0);
  return(unsigned int)v9;
}

Referenced by:

PnpProcessTargetDeviceEvent
PnpShutdownDevices