def GetTSKVsPartByPathSpec(tsk_volume, path_spec):
  """Retrieves the TSK volume system part object from the TSK volume object.

  Args:
    tsk_volume: a TSK volume object (instance of pytsk3.Volume_Info).
    path_spec: the path specification (instance of PathSpec).

  Returns:
    A tuple of the TSK volume system part object (instance of
    pytsk3.TSK_VS_PART_INFO) and the partition index. The partition index
    is None when not available. The function return or (None, None) on error.
  """
  location = getattr(path_spec, u'location', None)
  part_index = getattr(path_spec, u'part_index', None)
  start_offset = getattr(path_spec, u'start_offset', None)
  partition_index = None

  if part_index is None:
    if location is not None:
      if location.startswith(u'/p'):
        try:
          partition_index = int(location[2:], 10) - 1
        except __HOLE__:
          pass

      if partition_index is None or partition_index < 0:
        location = None

    if location is None and start_offset is None:
      return None, None

  bytes_per_sector = TSKVolumeGetBytesPerSector(tsk_volume)
  current_part_index = 0
  current_partition_index = 0
  tsk_vs_part = None

  # pytsk3 does not handle the Volume_Info iterator correctly therefore
  # the explicit cast to list is needed to prevent the iterator terminating
  # too soon or looping forever.
  tsk_vs_part_list = list(tsk_volume)
  number_of_tsk_vs_parts = len(tsk_vs_part_list)

  if number_of_tsk_vs_parts > 0:
    if (part_index is not None and
        (part_index < 0 or part_index >= number_of_tsk_vs_parts)):
      return None, None

    for tsk_vs_part in tsk_vs_part_list:
      if TSKVsPartIsAllocated(tsk_vs_part):
        if partition_index is not None:
          if partition_index == current_partition_index:
            break
        current_partition_index += 1

      if part_index is not None and part_index == current_part_index:
        break

      if start_offset is not None:
        start_sector = TSKVsPartGetStartSector(tsk_vs_part)

        if start_sector is not None:
          start_sector *= bytes_per_sector
          if start_sector == start_offset:
            break

      current_part_index += 1

  # Note that here we cannot solely rely on testing if tsk_vs_part is set
  # since the for loop will exit with tsk_vs_part set.
  if tsk_vs_part is None or current_part_index >= number_of_tsk_vs_parts:
    return None, None

  if not TSKVsPartIsAllocated(tsk_vs_part):
    current_partition_index = None
  return tsk_vs_part, current_partition_index
dataset/ETHPy150Open log2timeline/dfvfs/dfvfs/lib/tsk_partition.py/GetTSKVsPartByPathSpec