PnpProcessQueryRemoveAndEject

__int64 __fastcall PnpProcessQueryRemoveAndEject(const void **a1){
  void *v1; 
  DOCK_INTERFACE *v2; 
  CHAR *v3; 
  INT64 v4; 
  unsigned int v5; 
  INT64 v6; 
  int v7; 
  int v8; 
  CHAR *VetoBuffer; 
  UINT64 **v10; 
  int v11; 
  CHAR v12; 
  INT64 v13; 
  INT64 v14; 
  PVOID v15; 
  __int128 *v16; 
  UINT v17; 
  int v18; 
  __int64 v19; 
  _DEVICE_OBJECT *v21; 
  __int64 v22; 
  UINT8 v23; 
  __int64 v24; 
  const WCHAR *v25; 
  INT64 v26; 
  _UNICODE_STRING *v27; 
  _PNP_VETO_TYPE v28; 
  char v29; 
  _UNICODE_STRING *v30; 
  _PNP_VETO_TYPE v31; 
  _PNP_VETO_TYPE v32; 
  __int64 v33; 
  _QWORD *v34; 
  __int64 v35; 
  __int64 v36; 
  WCHAR v37; 
  _DWORD *v38; 
  UNICODE_STRING *v39; 
  __int64 v40; 
  DOCK_INTERFACE *v41; 
  __int64 v42; 
  _PENDING_RELATIONS_LIST_ENTRY *PendingEjectRelations; 
  _PENDING_RELATIONS_LIST_ENTRY *v44; 
  UINT8 v45; 
  UINT8 v46; 
  int LightestSystemStateForEject; 
  PVOID P; 
  PVOID PdoListOut; 
  PCWSTR SourceString; 
  PVOID v51; 
  PDEVICE_OBJECT DeviceObject; 
  DOCK_INTERFACE *DockInterface; 
  __int64 a3; 
  PVOID v55; 
  struct _UNICODE_STRING DestinationString; 
  UINT8 WarmEjectSupporteda; 
  UINT8 DockBeingEjected; 
  int SubsumeExistingDeparture; 
  UINT PdoListCount; 
  int v62; 
  v1 = (void *)*a1;
  SourceString = 0i64;
  v2 = 0i64;
  DockInterface = 0i64;
  v3 = 0i64;
  v4 = *((_QWORD *)v1 + 19);
  PdoListOut = 0i64;
  v5 = 7;
  PdoListCount = 0;
  DockBeingEjected = 0;
  a3 = 0i64;
  v51 = 0i64;
  LOBYTE(SubsumeExistingDeparture) = 0;
  P = 0i64;
  v55 = 0i64;
  DeviceObject = (PDEVICE_OBJECT)v4;
  DestinationString = 0i64;
  if( v4 )
    v6 = *(_QWORD *)(*(_QWORD *)(v4 + 312) + 40i64);
  else
    v6 = 0i64;
  PpDevNodeLockTree(1);
  if( (unsigned int)(*(_DWORD *)(v6 + 300) - 787) <= 1 )
  {
    v8 = -1073741738;
    goto LABEL_53;
  }
  v7 = PiDetermineDeleteType((INT64)v1);
  v5 = v7;
  if( v7 != 4 )
    PnpRecordBlackboxPnpEventInformation((INT64)v1, v7, 0i64, 1);
  v8 = PiCheckRemovalPreconditions(v5, (INT64)v1);
  if( v8 < 0 )
    goto LABEL_53;
  if( v5 == 4 )
  {
    if( (*(_DWORD *)(v6 + 396) & 0x80000) != 0 )
    {
LABEL_52:
      v8 = 0;
LABEL_53:
      PpDevNodeUnlockTree(1);
      goto LABEL_54;
    }
    if( (unsigned int)(*(_DWORD *)(v6 + 568) - 3) <= 1 )
    {
      v29 = 0;
    }
    else
    {
      if( (*(_DWORD *)(v6 + 560) & 0x10) == 0 )
      {
        v8 = -2147483608;
        v27 = (_UNICODE_STRING *)(v6 + 40);
        v28 = PNP_VetoIllegalDeviceRequest;
        goto LABEL_134;
      }
      v29 = 1;
    }
    v8 = 0;
    if( !v29 )
      goto LABEL_53;
  }
  if( !v5 && !(unsigned int)PipAreDriversLoaded((_DEVICE_NODE *)v6) )
  {
    v8 = PiProcessQueryRemoveNoFdo((INT64)v1);
    goto LABEL_53;
  }
  VetoBuffer = PiEventAllocateVetoBuffer(v5);
  v3 = VetoBuffer;
  if( !VetoBuffer )
    goto LABEL_78;
  if( (int)PnpBuildRemovalRelationList(v4, v5, (INT64)VetoBuffer, (INT64 **)&v51) < 0 )
  {
LABEL_79:
    v31 = *(_DWORD *)v3;
    v30 = (_UNICODE_STRING *)(v3 + 8);
    goto LABEL_80;
  }
  v10 = (UINT64 **)v51;
  v8 = PiEventBuildPdoList(
         (_RELATION_LIST *)v51,
         (_PNP_DEVICE_DELETE_TYPE)v5,
         (_PNP_DEVICE_EVENT_ENTRY *)v1,
         &PdoListCount,
         (_DEVICE_OBJECT ***)&PdoListOut,
         &DockBeingEjected,
         (UINT8 *)&SubsumeExistingDeparture);
  if( v8 < 0 )
    goto LABEL_132;
  v11 = PnpResizeTargetDeviceBlock(a1, v5);
  v1 = (void *)*a1;
  v8 = v11;
  if( v11 < 0 )
    goto LABEL_132;
  v12 = PiEventAreDeviceRelationsExcluded(v5);
  v8 = PnpCompileDeviceInstancePaths(v13, v10, v12, 0, (CHAR **)&P);
  if( v5 == 3 )
    PnpBuildUnsafeRemovalDeviceList(v14, v10, (CHAR **)&v55);
  if( v8 < 0 )
  {
LABEL_132:
    IopFreeRelationList(v10);
    if( v8 == -2147483608 )
      goto LABEL_53;
    v27 = 0i64;
    v28 = PNP_VetoTypeUnknown;
LABEL_134:
    PnpFinalizeVetoedRemove((_PNP_DEVICE_EVENT_ENTRY *)v1, v28, v27);
    goto LABEL_53;
  }
  if( !DockBeingEjected )
    goto LABEL_17;
  PpProfileBeginHardwareProfileTransition(SubsumeExistingDeparture);
  v33 = (int)(PdoListCount - 1);
  if( (int)(PdoListCount - 1) >= 0 )
  {
    v34 = PdoListOut;
    do
    {
      v35 = v34[v33];
      if( v35 )
        v36 = *(_QWORD *)(*(_QWORD *)(v35 + 312) + 40i64);
      else
        v36 = 0i64;
      if( *(_DWORD *)(v36 + 568) == 1 )
        PpProfileIncludeInHardwareProfileTransition(v36, 3);
      --v33;
    }
    while( v33 >= 0 );
    v10 = (UINT64 **)v51;
  }
  if( v5 == 4 )
  {
    if( (int)IoGetLegacyVetoList((WCHAR **)&SourceString, (_PNP_VETO_TYPE *)v3) >= 0 && *(_DWORD *)v3 )
    {
      PpProfileCancelHardwareProfileTransition();
      IopFreeRelationList(v10);
      v38 = (_DWORD *)*((_QWORD *)v1 + 6);
      if( v38 )
        *v38 = *(_DWORD *)v3;
      if( *((_QWORD *)v1 + 7) )
      {
        RtlInitUnicodeString(&DestinationString, SourceString, v37);
        RtlCopyUnicodeString(*((UNICODE_STRING **)v1 + 7), &DestinationString, v39);
      }
      ExFreePoolWithTag((PVOID)SourceString, 0);
      SourceString = 0i64;
      goto LABEL_84;
    }
    if( (int)PpProfileQueryHardwareProfileChange(
                SubsumeExistingDeparture,
                0i64,
                (PNP_VETO_TYPE *)v3,
                (UNICODE_STRING *)(v3 + 8)) < 0 )
    {
      PpProfileCancelHardwareProfileTransition();
      IopFreeRelationList(v10);
      goto LABEL_79;
    }
  }
  else
  {
LABEL_17:
    if( (v5 & 0xFFFFFFFB) != 0 )
    {
      if( ((v5 - 3) & 0xFFFFFFFD) == 0 )
        PnpDeleteLockedDeviceNodes(DeviceObject, (_RELATION_LIST *)v10, SurpriseRemoveDevice, 0, 0, 0, 0i64, 0i64);
      goto LABEL_20;
    }
  }
  PnpTrackQueryRemoveDevices((unsigned int **)v10, 1);
  v8 = PiProcessQueryAndCancelRemoval(
         v5,
         (INT64)v1,
         v10,
         PdoListCount,
         (VOID **)PdoListOut,
         (INT64 *)v3,
         (const VOID **)&P);
  if( v8 < 0 )
  {
    if( DockBeingEjected )
      PpProfileCancelHardwareProfileTransition();
    if( *((_DWORD *)v1 + 4) == 54 )
      v8 = PiProcessCanceledRemoveForReset(v5, (INT64)v1, v10, (INT64 *)v3);
    PnpTrackQueryRemoveDevices((unsigned int **)v10, 0);
    IopFreeRelationList(v10);
    goto LABEL_53;
  }
LABEL_20:
  if( v5 == 3 )
  {
    v15 = v55;
    if( v55 )
    {
      PnpNotifyUserModeDeviceRemoval((__int64)v1, v55, (__int128 *)&GUID_DEVICE_SURPRISE_REMOVAL, 0i64, 0i64, 0i64);
      ExFreePoolWithTag(v15, 0x4B706E50u);
    }
    v16 = (__int128 *)&GUID_TARGET_DEVICE_REMOVE_COMPLETE;
  }
  else
  {
    v16 = (__int128 *)&GUID_DEVICE_REMOVE_PENDING;
  }
  PnpNotifyUserModeDeviceRemoval((__int64)v1, P, v16, 0i64, 0i64, 0i64);
  v17 = PdoListCount;
  PiSendTargetDeviceRemoveCompleteNotification(v5, (DEVICE_OBJECT **)PdoListOut, PdoListCount);
  if( ((v5 - 2) & 0xFFFFFFFC) != 0
    || v5 == 4
    || (PnpInvalidateRelationsInList((_RELATION_LIST *)v10, (_PNP_DEVICE_DELETE_TYPE)v5, 1u, 0),
        IopRemoveDeviceRelationsFromList((unsigned int **)v10),
        v5 != 3) )
  {
    if( v5 != 5 )
    {
      v21 = DeviceObject;
      if( *(_DWORD *)(v6 + 568) )
      {
        IopQueryDockRemovalInterface(DeviceObject, &DockInterface);
        v2 = DockInterface;
        if( DockInterface )
          DockInterface->ProfileDepartureSetMode(DockInterface->Context, PDS_UPDATE_ON_INTERFACE);
      }
      if( v5 )
      {
        if( v5 != 4 )
        {
          LOBYTE(v18) = 0;
LABEL_45:
          PnpDeleteLockedDeviceNodes(
            v21,
            (_RELATION_LIST *)v10,
            RemoveDevice,
            v18,
            *((_DWORD *)v1 + 4),
            *((_DWORD *)v1 + 5),
            0i64,
            0i64);
          v22 = *(_DWORD *)(v6 + 560) >> 3;
          LOBYTE(v22) = (*(_DWORD *)(v6 + 560) & 8) != 0;
          v23 = HIWORD(*(_DWORD *)(v6 + 560)) & 1;
          SubsumeExistingDeparture = v22;
          WarmEjectSupporteda = v23;
          if( v5 != 4 )
          {
            PiRestartRemovalRelations((INT64)v1, v10, v21);
            PnpUnlinkDeviceRemovalRelations(v24, (__int64)v10);
            if( v5 )
            {
LABEL_47:
              IopFreeRelationList(v10);
              if( v5 == 2 )
                PnpNotifyUserModeDeviceRemoval(
                  (__int64)v1,
                  P,
                  (__int128 *)&GUID_TARGET_DEVICE_REMOVE_COMPLETE,
                  0i64,
                  0i64,
                  0i64);
              if( !v5
                && (*((_DWORD *)v1 + 36) & 2) == 0
                && (*(_DWORD *)(v6 + 396) & 0x2000) != 0
                && *(_DWORD *)(v6 + 404) == 18 )
              {
                PipClearDevNodeProblem(v6, v25, v26);
                PnpRestartDeviceNode(v6);
                PnpRequestDeviceAction(*(_DEVICE_OBJECT **)(v6 + 32), StartDevice, 1u, 0i64, 0i64, 0i64);
              }
              if( v2 )
              {
                v2->ProfileDepartureSetMode(v2->Context, PDS_UPDATE_DEFAULT);
                v2->InterfaceDereference(v2->Context);
              }
              goto LABEL_52;
            }
LABEL_64:
            PnpTrackQueryRemoveDevices((unsigned int **)v10, 0);
            goto LABEL_47;
          }
          if( !(_BYTE)v22 && !v23 )
          {
            PnpUnlinkDeviceRemovalRelations(v22, (__int64)v10);
            goto LABEL_64;
          }
          v62 = 0;
          PdoListCount = 1;
          while( IopEnumerateRelations((unsigned int **)v10, (int *)&PdoListCount, &a3, 0i64, 0i64) )
          {
            if( a3 )
              v40 = *(_QWORD *)(*(_QWORD *)(a3 + 312) + 40i64);
            else
              v40 = 0i64;
            if( v40 )
            {
              PipSetDevNodeFlags(v40, 0x80000);
              v41 = *(DOCK_INTERFACE **)(v40 + 696);
              DockInterface = v41;
              if( v41 )
              {
                IopFreeRelationList(v41[1].InterfaceReference);
                DockInterface[1].InterfaceReference = 0i64;
                *(_QWORD *)(v40 + 696) = 0i64;
              }
            }
          }
          PnpUnlinkDeviceRemovalRelations(v42, (__int64)v10);
          PendingEjectRelations = (_PENDING_RELATIONS_LIST_ENTRY *)PiEventAllocatePendingEjectRelations(
                                                                     (INT64)v1,
                                                                     (INT64)v10,
                                                                     DockBeingEjected,
                                                                     (INT64)v2);
          v44 = PendingEjectRelations;
          if( PendingEjectRelations )
          {
            v45 = SubsumeExistingDeparture;
            v46 = DockBeingEjected;
            *(_QWORD *)(v6 + 696) = PendingEjectRelations;
            LightestSystemStateForEject = PoGetLightestSystemStateForEject(
                                            v46,
                                            v45,
                                            WarmEjectSupporteda,
                                            &PendingEjectRelations->LightestSleepState);
            if( LightestSystemStateForEject >= 0 )
            {
              PpDevNodeUnlockTree(1);
              IopEjectDevice(DeviceObject, v44);
              v8 = 259;
LABEL_54:
              if( v8 == -1073741738 )
                goto LABEL_32;
              goto LABEL_28;
            }
            v32 = PNP_VetoTypeUnknown;
            if( LightestSystemStateForEject == -1073741090 )
              v32 = PNP_VetoInsufficientPower;
            PnpFinalizeVetoedRemove((_PNP_DEVICE_EVENT_ENTRY *)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 )
          {
            v2->ProfileDepartureSetMode(v2->Context, PDS_UPDATE_DEFAULT);
            v2->InterfaceDereference(v2->Context);
          }
          if( DockBeingEjected )
            PpProfileCancelHardwareProfileTransition();
          PnpInvalidateRelationsInList((_RELATION_LIST *)v10, EjectDevice, 0, 1u);
          PnpTrackQueryRemoveDevices((unsigned int **)v10, 0);
          IopFreeRelationList(v10);
LABEL_78:
          v30 = 0i64;
          v31 = PNP_VetoTypeUnknown;
LABEL_80:
          PnpFinalizeVetoedRemove((_PNP_DEVICE_EVENT_ENTRY *)v1, v31, v30);
LABEL_84:
          v8 = -2147483608;
          goto LABEL_53;
        }
      }
      else
      {
        PipSetDevNodeFlags(v6, 0x2000000);
      }
      LOBYTE(v18) = 1;
      goto LABEL_45;
    }
  }
  PiEventRemovalPostSurpriseRemove();
  PpDevNodeUnlockTree(1);
  PnpIsChainDereferenced((_DEVICE_OBJECT **)PdoListOut, v17, 0i64, 1ui64, 0i64);
  v8 = 0;
LABEL_28:
  if( v5 != 4 )
  {
    if( v3 )
      v19 = (__int64)v3;
    else
      v19 = 0i64;
    PnpRecordBlackboxPnpEventInformation((INT64)v1, v5, v19, 0);
  }
LABEL_32:
  if( v3 && !PnpShutdownEvent.Header.SignalState )
  {
    ExFreePoolWithTag(*((PVOID *)v3 + 2), 0x4D706E50u);
    *((_QWORD *)v3 + 2) = 0i64;
    ExFreePoolWithTag(v3, 0x4D706E50u);
  }
  if( P )
    ExFreePoolWithTag(P, 0);
  if( PdoListOut )
    ExFreePoolWithTag(PdoListOut, 0);
  return(unsigned int)v8;
}

Referenced by:

PnpProcessTargetDeviceEvent
PnpShutdownDevices