PnpProcessRelation

INT64 __stdcall PnpProcessRelation(
        _DEVICE_NODE *DeviceNode,
        _PNP_DEVICE_DELETE_TYPE OperationCode,
        _DEVICE_RELATION_LEVEL RelationLevel,
        _PNP_VETO_TYPE *VetoType,
        _UNICODE_STRING *VetoName,
        _RELATION_LIST *RelationsList){
  __int64 v6; 
  _UNICODE_STRING *v11; 
  int v12; 
  ULONG_PTR BugCheckParameter4; 
  INT64 result; 
  int v15; 
  _QWORD *v16; 
  unsigned int v17; 
  struct _DMA_ADAPTER *v18; 
  _DMA_OPERATIONS *DmaOperations; 
  unsigned __int8(__fastcall *v20)(_DMA_ADAPTER *, _MDL *, void *, void *, unsigned int, unsigned __int8); 
  int v21; 
  int v22; 
  __int16 *v23; 
  void(__fastcall **p_FreeMapRegisters)(_DMA_ADAPTER *, void *, unsigned int); 
  PVOID *FlushAdapterBuffers; 
  PVOID *v26; 
  _DMA_OPERATIONS *v27; 
  _WORD *v28; 
  __int64 v29; 
  _WORD *v30; 
  __int64 v31; 
  unsigned int v32; 
  struct _DMA_ADAPTER *v33; 
  _DMA_OPERATIONS *v34; 
  unsigned __int8(__fastcall *v35)(_DMA_ADAPTER *, _MDL *, void *, void *, unsigned int, unsigned __int8); 
  __int16 *v36; 
  void(__fastcall **v37)(_DMA_ADAPTER *, void *, unsigned int); 
  PVOID *v38; 
  PVOID *v39; 
  _DMA_OPERATIONS *v40; 
  _WORD *v41; 
  __int64 v42; 
  _WORD *v43; 
  __int64 v44; 
  __int64 v45; 
  int **v46; 
  void *v47; 
  void *v48; 
  void *v49; 
  ULONG_PTR v50; 
  __int16 *v51; 
  _WORD *v52; 
  __int64 v53; 
  __int64 v54; 
  void *v55; 
  ULONG_PTR v56; 
  __int64 v57; 
  __int64 v58; 
  __int64 v59; 
  __int64 v60; 
  __int64 v61; 
  __int64 v62; 
  __int64 v63; 
  __int64 v64; 
  __int64 v65; 
  __int64 v66; 
  __int64 v67; 
  ULONG_PTR v68; 
  __int16 *v69; 
  _WORD *v70; 
  __int64 v71; 
  __int64 v72; 
  void *v73; 
  ULONG_PTR v74; 
  __int64 v75; 
  __int64 v76; 
  __int64 v77; 
  __int64 v78; 
  __int64 v79; 
  __int64 v80; 
  __int64 v81; 
  __int64 v82; 
  __int64 v83; 
  __int64 v84; 
  _RELATION_LIST *v85; 
  _RELATION_LIST *v86; 
  PVOID P[2]; 
  v6 = 0i64;
  P[0] = 0i64;
  if( (OperationCode & 0xFFFFFFFB) == 0 )
  {
    v22 = *((_DWORD *)DeviceNode + 75);
    if( (unsigned int)(v22 - 782) <= 1 || v22 == 788 )
    {
      *VetoType = PNP_VetoAlreadyRemoved;
    }
    else
    {
      if( *((int *)DeviceNode + 164) <= 0 && ((v22 - 785) & 0xFFFFFFFD) != 0 )
      {
        if( (unsigned int)(v22 - 778) <= 1 )
          return 3221225488i64;
        goto LABEL_3;
      }
      *VetoType = PNP_VetoOutstandingOpen;
    }
    RtlCopyUnicodeString(
      (UNICODE_STRING *)(VetoType + 2),
      (UNICODE_STRING *)((char *)DeviceNode + 40),
      *(UNICODE_STRING **)&RelationLevel);
    return 3221225473i64;
  }
  if( *((_DWORD *)DeviceNode + 75) == 788 )
    return 0i64;
LABEL_3:
  v11 = VetoName;
  v12 = IopAddRelationToList((INT64)VetoName, *((_QWORD *)DeviceNode + 4), *(INT64 *)&RelationLevel, 0i64);
  BugCheckParameter4 = v12;
  if( v12 )
  {
    if( v12 == -1073741771 )
    {
      LODWORD(BugCheckParameter4) = PnpProcessBusRelations(
                                      DeviceNode,
                                      OperationCode,
                                      RelationLevel,
                                      VetoType,
                                      VetoName,
                                      v85);
    }
    else if( v12 != -1073741670 )
    {
      v68 = *((_QWORD *)DeviceNode + 4);
      if( v68 )
      {
        IoAddTriageDumpDataBlock(*((PVOID *)DeviceNode + 4), *(unsigned __int16 *)(v68 + 2));
        v68 = *((_QWORD *)DeviceNode + 4);
        v69 = *(__int16 **)(v68 + 8);
        if( v69 )
        {
          IoAddTriageDumpDataBlock(v69, (unsigned int)v69[1]);
          v68 = *((_QWORD *)DeviceNode + 4);
          v70 = (_WORD *)(*(_QWORD *)(v68 + 8) + 56i64);
          if( *v70 )
          {
            IoAddTriageDumpDataBlock(v70, 2ui64);
            IoAddTriageDumpDataBlock(
              *(PVOID *)(*(_QWORD *)(*((_QWORD *)DeviceNode + 4) + 8i64) + 64i64),
              *(unsigned __int16 *)(*(_QWORD *)(*((_QWORD *)DeviceNode + 4) + 8i64) + 56i64));
            v68 = *((_QWORD *)DeviceNode + 4);
          }
        }
        if( v68 )
          v71 = *(_QWORD *)(*(_QWORD *)(v68 + 312) + 40i64);
        else
          v71 = 0i64;
        if( v71 )
        {
          if( v68 )
            v72 = *(_QWORD *)(*(_QWORD *)(v68 + 312) + 40i64);
          else
            v72 = 0i64;
          if( v68 )
            v73 = *(void **)(*(_QWORD *)(v68 + 312) + 40i64);
          else
            v73 = 0i64;
          IoAddTriageDumpDataBlock(v73, 0x310ui64);
          if( *(_WORD *)(v72 + 40) )
          {
            IoAddTriageDumpDataBlock((PVOID)(v72 + 40), 2ui64);
            IoAddTriageDumpDataBlock(*(PVOID *)(v72 + 48), *(unsigned __int16 *)(v72 + 40));
          }
          v74 = *((_QWORD *)DeviceNode + 4);
          if( v74 )
            v75 = *(_QWORD *)(*(_QWORD *)(v74 + 312) + 40i64);
          else
            v75 = 0i64;
          if( *(_WORD *)(v75 + 56) )
          {
            if( v74 )
              v76 = *(_QWORD *)(*(_QWORD *)(v74 + 312) + 40i64);
            else
              v76 = 0i64;
            IoAddTriageDumpDataBlock((PVOID)(v76 + 56), 2ui64);
            v77 = *((_QWORD *)DeviceNode + 4);
            if( v77 )
              v78 = *(_QWORD *)(*(_QWORD *)(v77 + 312) + 40i64);
            else
              v78 = 0i64;
            if( v77 )
              v79 = *(_QWORD *)(*(_QWORD *)(v77 + 312) + 40i64);
            else
              v79 = 0i64;
            IoAddTriageDumpDataBlock(*(PVOID *)(v79 + 64), *(unsigned __int16 *)(v78 + 56));
            v74 = *((_QWORD *)DeviceNode + 4);
          }
          if( v74 )
            v80 = *(_QWORD *)(*(_QWORD *)(v74 + 312) + 40i64);
          else
            v80 = 0i64;
          v68 = v74;
          if( *(_QWORD *)(v80 + 16) )
          {
            v81 = v74 ? *(_QWORD *)(*(_QWORD *)(v74 + 312) + 40i64) : 0i64;
            if( *(_WORD *)(*(_QWORD *)(v81 + 16) + 56i64) )
            {
              if( v74 )
                v82 = *(_QWORD *)(*(_QWORD *)(v74 + 312) + 40i64);
              else
                v82 = 0i64;
              IoAddTriageDumpDataBlock((PVOID)(*(_QWORD *)(v82 + 16) + 56i64), 2ui64);
              v83 = *((_QWORD *)DeviceNode + 4);
              if( v83 )
                v84 = *(_QWORD *)(*(_QWORD *)(v83 + 312) + 40i64);
              else
                v84 = 0i64;
              if( v83 )
                v6 = *(_QWORD *)(*(_QWORD *)(v83 + 312) + 40i64);
              IoAddTriageDumpDataBlock(
                *(PVOID *)(*(_QWORD *)(v6 + 16) + 64i64),
                *(unsigned __int16 *)(*(_QWORD *)(v84 + 16) + 56i64));
              v68 = *((_QWORD *)DeviceNode + 4);
            }
          }
        }
      }
      KeBugCheckEx(0xCAu, 7ui64, v68, (ULONG_PTR)VetoName, BugCheckParameter4);
    }
    return(unsigned int)BugCheckParameter4;
  }
  if( (*((_DWORD *)DeviceNode + 99) & 0x80000) != 0 )
  {
    v45 = IopPendingEjects;
    if( (__int64 *)IopPendingEjects == &IopPendingEjects )
      goto LABEL_80;
    while( 1 )
    {
      v46 = *(int ***)(v45 + 64);
      if( v46 )
      {
        if( IopIsRelationInList(v46, *((_QWORD *)DeviceNode + 4)) )
          break;
      }
      v45 = *(_QWORD *)v45;
      if( (__int64 *)v45 == &IopPendingEjects )
        goto LABEL_79;
    }
    if( OperationCode == EjectDevice )
    {
      LODWORD(BugCheckParameter4) = IopRemoveRelationFromList((__int64 *)VetoName, *((_QWORD *)DeviceNode + 4));
      IopCancelPendingEject(v45, v47, v48, v49);
      IopMergeRelationLists((_RELATION_LIST *)VetoName, *(_RELATION_LIST **)(v45 + 64), 0);
      if( RelationLevel == RELATION_LEVEL_DIRECT_DESCENDANT )
        IopAddRelationToList((INT64)VetoName, *((_QWORD *)DeviceNode + 4), 2i64, 0i64);
LABEL_79:
      if( (__int64 *)v45 != &IopPendingEjects )
        return(unsigned int)BugCheckParameter4;
LABEL_80:
      v50 = *((_QWORD *)DeviceNode + 4);
      if( v50 )
      {
        IoAddTriageDumpDataBlock(*((PVOID *)DeviceNode + 4), *(unsigned __int16 *)(v50 + 2));
        v50 = *((_QWORD *)DeviceNode + 4);
        v51 = *(__int16 **)(v50 + 8);
        if( v51 )
        {
          IoAddTriageDumpDataBlock(v51, (unsigned int)v51[1]);
          v50 = *((_QWORD *)DeviceNode + 4);
          v52 = (_WORD *)(*(_QWORD *)(v50 + 8) + 56i64);
          if( *v52 )
          {
            IoAddTriageDumpDataBlock(v52, 2ui64);
            IoAddTriageDumpDataBlock(
              *(PVOID *)(*(_QWORD *)(*((_QWORD *)DeviceNode + 4) + 8i64) + 64i64),
              *(unsigned __int16 *)(*(_QWORD *)(*((_QWORD *)DeviceNode + 4) + 8i64) + 56i64));
            v50 = *((_QWORD *)DeviceNode + 4);
          }
        }
        if( v50 )
          v53 = *(_QWORD *)(*(_QWORD *)(v50 + 312) + 40i64);
        else
          v53 = 0i64;
        if( v53 )
        {
          if( v50 )
            v54 = *(_QWORD *)(*(_QWORD *)(v50 + 312) + 40i64);
          else
            v54 = 0i64;
          if( v50 )
            v55 = *(void **)(*(_QWORD *)(v50 + 312) + 40i64);
          else
            v55 = 0i64;
          IoAddTriageDumpDataBlock(v55, 0x310ui64);
          if( *(_WORD *)(v54 + 40) )
          {
            IoAddTriageDumpDataBlock((PVOID)(v54 + 40), 2ui64);
            IoAddTriageDumpDataBlock(*(PVOID *)(v54 + 48), *(unsigned __int16 *)(v54 + 40));
          }
          v56 = *((_QWORD *)DeviceNode + 4);
          if( v56 )
            v57 = *(_QWORD *)(*(_QWORD *)(v56 + 312) + 40i64);
          else
            v57 = 0i64;
          if( *(_WORD *)(v57 + 56) )
          {
            if( v56 )
              v58 = *(_QWORD *)(*(_QWORD *)(v56 + 312) + 40i64);
            else
              v58 = 0i64;
            IoAddTriageDumpDataBlock((PVOID)(v58 + 56), 2ui64);
            v59 = *((_QWORD *)DeviceNode + 4);
            if( v59 )
              v60 = *(_QWORD *)(*(_QWORD *)(v59 + 312) + 40i64);
            else
              v60 = 0i64;
            if( v59 )
              v61 = *(_QWORD *)(*(_QWORD *)(v59 + 312) + 40i64);
            else
              v61 = 0i64;
            IoAddTriageDumpDataBlock(*(PVOID *)(v61 + 64), *(unsigned __int16 *)(v60 + 56));
            v56 = *((_QWORD *)DeviceNode + 4);
          }
          if( v56 )
            v62 = *(_QWORD *)(*(_QWORD *)(v56 + 312) + 40i64);
          else
            v62 = 0i64;
          v50 = v56;
          if( *(_QWORD *)(v62 + 16) )
          {
            v63 = v56 ? *(_QWORD *)(*(_QWORD *)(v56 + 312) + 40i64) : 0i64;
            if( *(_WORD *)(*(_QWORD *)(v63 + 16) + 56i64) )
            {
              if( v56 )
                v64 = *(_QWORD *)(*(_QWORD *)(v56 + 312) + 40i64);
              else
                v64 = 0i64;
              IoAddTriageDumpDataBlock((PVOID)(*(_QWORD *)(v64 + 16) + 56i64), 2ui64);
              v65 = *((_QWORD *)DeviceNode + 4);
              if( v65 )
                v66 = *(_QWORD *)(*(_QWORD *)(v65 + 312) + 40i64);
              else
                v66 = 0i64;
              if( v65 )
                v67 = *(_QWORD *)(*(_QWORD *)(v65 + 312) + 40i64);
              else
                v67 = 0i64;
              IoAddTriageDumpDataBlock(
                *(PVOID *)(*(_QWORD *)(v67 + 16) + 64i64),
                *(unsigned __int16 *)(*(_QWORD *)(v66 + 16) + 56i64));
              v50 = *((_QWORD *)DeviceNode + 4);
            }
          }
        }
      }
      KeBugCheckEx(0xCAu, 6ui64, v50, 0i64, 0i64);
    }
    if( OperationCode )
    {
      LODWORD(BugCheckParameter4) = IopRemoveRelationFromList(*(__int64 **)(v45 + 64), *((_QWORD *)DeviceNode + 4));
      PipClearDevNodeFlags(DeviceNode, 0x80000ui64);
      goto LABEL_79;
    }
    return 3221225473i64;
  }
  result = PnpProcessBusRelations(DeviceNode, OperationCode, RelationLevel, VetoType, VetoName, v85);
  if( (int)result >= 0 )
  {
    v15 = *((_DWORD *)DeviceNode + 75);
    if( (unsigned int)(v15 - 782) <= 1 )
      v15 = *((_DWORD *)DeviceNode + 76);
    if( ((unsigned int)(v15 - 775) <= 1 || (unsigned int)(v15 - 778) <= 1)
      && PnpQueryDeviceRelations(*((PDEVICE_OBJECT *)DeviceNode + 4), RemovalRelations, 0i64, P) >= 0 )
    {
      v16 = P[0];
      if( P[0] )
      {
        v17 = 0;
        if( *(_DWORD *)P[0] )
        {
          do
          {
            v18 = (struct _DMA_ADAPTER *)v16[v17 + 1];
            DmaOperations = v18[19].DmaOperations;
            if( ((__int64)DmaOperations->AllocateAdapterChannel & 2) != 0
              || (v20 = DmaOperations->FlushAdapterBuffers) == 0i64
              || !*((_QWORD *)v20 + 2) )
            {
              IoAddTriageDumpDataBlock(v18, v18->Size);
              v23 = (__int16 *)v18->DmaOperations;
              if( v23 )
              {
                IoAddTriageDumpDataBlock(v23, (unsigned int)v23[1]);
                p_FreeMapRegisters = &v18->DmaOperations->FreeMapRegisters;
                if( *(_WORD *)p_FreeMapRegisters )
                {
                  IoAddTriageDumpDataBlock(p_FreeMapRegisters, 2ui64);
                  IoAddTriageDumpDataBlock(
                    v18->DmaOperations->MapTransfer,
                    LOWORD(v18->DmaOperations->FreeMapRegisters));
                }
              }
              FlushAdapterBuffers = (PVOID *)v18[19].DmaOperations->FlushAdapterBuffers;
              if( FlushAdapterBuffers )
              {
                v26 = FlushAdapterBuffers + 5;
                IoAddTriageDumpDataBlock(FlushAdapterBuffers, 0x310ui64);
                if( *(_WORD *)v26 )
                {
                  IoAddTriageDumpDataBlock(v26, 2ui64);
                  IoAddTriageDumpDataBlock(v26[1], *(unsigned __int16 *)v26);
                }
                v27 = v18[19].DmaOperations;
                v28 = (_WORD *)((char *)v27->FlushAdapterBuffers + 56);
                if( *v28 )
                {
                  IoAddTriageDumpDataBlock(v28, 2ui64);
                  IoAddTriageDumpDataBlock(
                    *((PVOID *)v18[19].DmaOperations->FlushAdapterBuffers + 8),
                    *((unsigned __int16 *)v18[19].DmaOperations->FlushAdapterBuffers + 28));
                  v27 = v18[19].DmaOperations;
                }
                v29 = *((_QWORD *)v27->FlushAdapterBuffers + 2);
                if( v29 )
                {
                  v30 = (_WORD *)(v29 + 56);
                  if( *v30 )
                  {
                    IoAddTriageDumpDataBlock(v30, 2ui64);
                    v31 = *((_QWORD *)v18[19].DmaOperations->FlushAdapterBuffers + 2);
                    IoAddTriageDumpDataBlock(*(PVOID *)(v31 + 64), *(unsigned __int16 *)(v31 + 56));
                  }
                }
              }
              KeBugCheckEx(0xCAu, 0xBui64, (ULONG_PTR)v18, 3ui64, 0i64);
            }
            v21 = PnpProcessRelation(
                    (_DEVICE_NODE *)v20,
                    OperationCode,
                    RELATION_LEVEL_REMOVE_EJECT,
                    VetoType,
                    v11,
                    v86);
            HalPutDmaAdapter(v18);
            v16 = P[0];
            if( v21 < 0 )
              goto LABEL_36;
            v11 = VetoName;
          }
          while( ++v17 < *(_DWORD *)P[0] );
        }
        ExFreePoolWithTag(v16, 0);
      }
    }
    if( (unsigned int)(OperationCode - 5) > 1 )
    {
      if( OperationCode )
      {
        if( PnpQueryDeviceRelations(*((PDEVICE_OBJECT *)DeviceNode + 4), EjectionRelations, 0i64, P) >= 0 )
        {
          v16 = P[0];
          if( P[0] )
          {
            v32 = 0;
            if( *(_DWORD *)P[0] )
            {
              while( 1 )
              {
                v33 = (struct _DMA_ADAPTER *)v16[v32 + 1];
                v34 = v33[19].DmaOperations;
                if( ((__int64)v34->AllocateAdapterChannel & 2) != 0
                  || (v35 = v34->FlushAdapterBuffers) == 0i64
                  || !*((_QWORD *)v35 + 2) )
                {
                  IoAddTriageDumpDataBlock(v33, v33->Size);
                  v36 = (__int16 *)v33->DmaOperations;
                  if( v36 )
                  {
                    IoAddTriageDumpDataBlock(v36, (unsigned int)v36[1]);
                    v37 = &v33->DmaOperations->FreeMapRegisters;
                    if( *(_WORD *)v37 )
                    {
                      IoAddTriageDumpDataBlock(v37, 2ui64);
                      IoAddTriageDumpDataBlock(
                        v33->DmaOperations->MapTransfer,
                        LOWORD(v33->DmaOperations->FreeMapRegisters));
                    }
                  }
                  v38 = (PVOID *)v33[19].DmaOperations->FlushAdapterBuffers;
                  if( v38 )
                  {
                    v39 = v38 + 5;
                    IoAddTriageDumpDataBlock(v38, 0x310ui64);
                    if( *(_WORD *)v39 )
                    {
                      IoAddTriageDumpDataBlock(v39, 2ui64);
                      IoAddTriageDumpDataBlock(v39[1], *(unsigned __int16 *)v39);
                    }
                    v40 = v33[19].DmaOperations;
                    v41 = (_WORD *)((char *)v40->FlushAdapterBuffers + 56);
                    if( *v41 )
                    {
                      IoAddTriageDumpDataBlock(v41, 2ui64);
                      IoAddTriageDumpDataBlock(
                        *((PVOID *)v33[19].DmaOperations->FlushAdapterBuffers + 8),
                        *((unsigned __int16 *)v33[19].DmaOperations->FlushAdapterBuffers + 28));
                      v40 = v33[19].DmaOperations;
                    }
                    v42 = *((_QWORD *)v40->FlushAdapterBuffers + 2);
                    if( v42 )
                    {
                      v43 = (_WORD *)(v42 + 56);
                      if( *v43 )
                      {
                        IoAddTriageDumpDataBlock(v43, 2ui64);
                        v44 = *((_QWORD *)v33[19].DmaOperations->FlushAdapterBuffers + 2);
                        IoAddTriageDumpDataBlock(*(PVOID *)(v44 + 64), *(unsigned __int16 *)(v44 + 56));
                      }
                    }
                  }
                  KeBugCheckEx(0xCAu, 0xBui64, (ULONG_PTR)v33, 1ui64, 0i64);
                }
                v21 = PnpProcessRelation(
                        (_DEVICE_NODE *)v35,
                        OperationCode,
                        RELATION_LEVEL_REMOVE_EJECT,
                        VetoType,
                        v11,
                        v86);
                HalPutDmaAdapter(v33);
                v16 = P[0];
                if( v21 < 0 )
                  break;
                v11 = VetoName;
                if( ++v32 >= *(_DWORD *)P[0] )
                  goto LABEL_56;
              }
LABEL_36:
              ExFreePoolWithTag(v16, 0);
              return(unsigned int)v21;
            }
LABEL_56:
            ExFreePoolWithTag(v16, 0);
          }
        }
      }
    }
    result = PnpProcessDependencyRelations(
               DeviceNode,
               OperationCode,
               (_DEVICE_RELATION_LEVEL)(RelationLevel != RELATION_LEVEL_REMOVE_EJECT),
               VetoType,
               VetoName,
               v86);
    if( (int)result >= 0 )
    {
      LODWORD(BugCheckParameter4) = 0;
      return(unsigned int)BugCheckParameter4;
    }
  }
  return result;
}

Referenced by:

PnpBuildRemovalRelationList
PnpProcessBusRelations
PnpProcessDependencyRelations
PnpProcessRelation