  def ParseFileObject(self, parser_mediator, file_object):
    """Parses a .customDestinations-ms file-like object.

    Args:
      parser_mediator (ParserMediator): mediates interactions between parsers
          and other components, such as storage and dfvfs.
      file_object (dfvfs.FileIO): a file-like object.

    Raises:
      UnableToParseFile: when the file cannot be parsed.
    """
    file_entry = parser_mediator.GetFileEntry()
    display_name = parser_mediator.GetDisplayName()

    file_header_map = self._GetDataTypeMap('custom_file_header')

    try:
      file_header, file_offset = self._ReadStructureFromFileObject(
          file_object, 0, file_header_map)
    except (ValueError, errors.ParseError) as exception:
      raise errors.UnableToParseFile((
          'Invalid Custom Destination: {0:s} - unable to parse file header '
          'with error: {1!s}').format(display_name, exception))

    if file_header.unknown1 != 2:
      raise errors.UnableToParseFile((
          'Unsupported Custom Destination file: {0:s} - invalid unknown1: '
          '{1:d}.').format(display_name, file_header.unknown1))

    if file_header.header_values_type > 2:
      raise errors.UnableToParseFile((
          'Unsupported Custom Destination file: {0:s} - invalid header value '
          'type: {1:d}.').format(display_name, file_header.header_values_type))

    if file_header.header_values_type == 0:
      data_map_name = 'custom_file_header_value_type_0'
    else:
      data_map_name = 'custom_file_header_value_type_1_or_2'

    file_header_value_map = self._GetDataTypeMap(data_map_name)

    try:
      _, value_data_size = self._ReadStructureFromFileObject(
          file_object, file_offset, file_header_value_map)
    except (ValueError, errors.ParseError) as exception:
      raise errors.UnableToParseFile((
          'Invalid Custom Destination: {0:s} - unable to parse file header '
          'value with error: {1!s}').format(display_name, exception))

    file_offset += value_data_size
    file_size = file_object.get_size()
    remaining_file_size = file_size - file_offset

    entry_header_map = self._GetDataTypeMap('custom_entry_header')
    file_footer_map = self._GetDataTypeMap('custom_file_footer')

    # The Custom Destination file does not have a unique signature in
    # the file header that is why we use the first LNK class identifier (GUID)
    # as a signature.
    first_guid_checked = False
    while remaining_file_size > 4:
      try:
        entry_header, entry_data_size = self._ReadStructureFromFileObject(
            file_object, file_offset, entry_header_map)

      except (ValueError, errors.ParseError) as exception:
        if not first_guid_checked:
          raise errors.UnableToParseFile((
              'Invalid Custom Destination file: {0:s} - unable to parse '
              'entry header with error: {1!s}').format(
                  display_name, exception))

        parser_mediator.ProduceExtractionWarning(
            'unable to parse entry header with error: {0!s}'.format(
                exception))
        break

      if entry_header.guid != self._LNK_GUID:
        if not first_guid_checked:
          raise errors.UnableToParseFile((
              'Unsupported Custom Destination file: {0:s} - invalid entry '
              'header signature offset: 0x{1:08x}.').format(
                  display_name, file_offset))

        try:
          # Check if we found the footer instead of an entry header.
          file_footer, _ = self._ReadStructureFromFileObject(
              file_object, file_offset, file_footer_map)

          if file_footer.signature != self._FILE_FOOTER_SIGNATURE:
            parser_mediator.ProduceExtractionWarning(
                'invalid entry header signature at offset: 0x{0:08x}'.format(
                    file_offset))

        except (ValueError, errors.ParseError) as exception:
          parser_mediator.ProduceExtractionWarning((
              'unable to parse footer at offset: 0x{0:08x} with error: '
              '{1!s}').format(file_offset, exception))
          break

        # TODO: add support for Jump List LNK file recovery.
        break

      first_guid_checked = True
      file_offset += entry_data_size
      remaining_file_size -= entry_data_size

      lnk_file_size = self._ParseLNKFile(
          parser_mediator, file_entry, file_offset, remaining_file_size)

      file_offset += lnk_file_size
      remaining_file_size -= lnk_file_size

    try:
      file_footer, _ = self._ReadStructureFromFileObject(
          file_object, file_offset, file_footer_map)

      if file_footer.signature != self._FILE_FOOTER_SIGNATURE:
        parser_mediator.ProduceExtractionWarning(
            'invalid footer signature at offset: 0x{0:08x}'.format(file_offset))

    except (ValueError, errors.ParseError) as exception:
      parser_mediator.ProduceExtractionWarning((
          'unable to parse footer at offset: 0x{0:08x} with error: '
          '{1!s}').format(file_offset, exception))