コード例 #1
0
ファイル: libsmdev_scsi.c プロジェクト: eaas-framework/xmount
/* Sends a SCSI read track information to the file descriptor
 * Returns the number of bytes read if successful or -1 on error
 */
ssize_t libsmdev_scsi_read_track_information(
         int file_descriptor,
         uint32_t offset,
         uint8_t *response,
         size_t response_size,
         liberror_error_t **error )
{
	libsmdev_scsi_read_track_information_cdb_t command;

	uint8_t sense[ LIBSMDEV_SCSI_SENSE_SIZE ];

	static char *function  = "libsmdev_scsi_read_track_information";
	ssize_t response_count = 0;

	if( file_descriptor == -1 )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file descriptor.",
		 function );

		return( -1 );
	}
	if( response == NULL )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid response.",
		 function );

		return( -1 );
	}
	if( response_size > (size_t) SSIZE_MAX )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid response size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( memory_set(
	     &command,
	     0,
	     sizeof( libsmdev_scsi_read_track_information_cdb_t ) ) == NULL )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_MEMORY,
		 LIBERROR_MEMORY_ERROR_SET_FAILED,
		 "%s: unable to clear command.",
		 function );

		return( -1 );
	}
	command.operation_code = LIBSMDEV_SCSI_OPERATION_CODE_READ_TRACK_INFORMATION;
	command.address_type   = LIBSMDEV_SCSI_TRACK_INFORMATION_ADDRESS_TYPE_LBA;

	byte_stream_copy_from_uint32_big_endian(
	 command.offset,
	 offset );

	byte_stream_copy_from_uint16_big_endian(
	 command.receive_size,
	 response_size );

	if( libsmdev_scsi_command(
	     file_descriptor,
	     (uint8_t *) &command,
	     sizeof( libsmdev_scsi_read_track_information_cdb_t ),
	     response,
	     response_size,
	     sense,
	     LIBSMDEV_SCSI_SENSE_SIZE,
	     error ) != 1 )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_IO,
		 LIBERROR_IO_ERROR_GENERIC,
		 "%s: SCSI READ TRACK INFORMATION command failed.",
		 function );

		return( -1 );
	}
	byte_stream_copy_to_uint16_big_endian(
	 response,
	 response_count );

	if( response_count > (ssize_t) response_size )
	{
		liberror_error_set(
		 error,
		 LIBERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
		 "%s: response too small.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libnotify_verbose != 0 )
	{
		libnotify_printf(
		 "%s: response:\n",
		 function );
		libnotify_print_data(
		 response,
		 response_count,
		 0 );
	}
#endif
	return( response_count );
}
コード例 #2
0
/* Copies a base16 stream from a byte stream
 * Returns 1 if successful or -1 on error
 */
int libuna_base16_stream_with_index_copy_from_byte_stream(
     uint8_t *base16_stream,
     size_t base16_stream_size,
     size_t *base16_stream_index,
     const uint8_t *byte_stream,
     size_t byte_stream_size,
     uint32_t base16_variant,
     libcerror_error_t **error )
{
	static char *function                = "libuna_base16_stream_with_index_copy_from_byte_stream";
	size_t calculated_base16_stream_size = 0;
	size_t base16_character_size         = 0;
	size_t stream_index                  = 0;
	size_t byte_stream_index             = 0;
	size_t number_of_characters          = 0;
	size_t whitespace_size               = 0;
	uint32_t a_character_value           = 0;
	uint32_t base16_character            = 0;
	uint8_t character_limit              = 0;

	if( base16_stream == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid base16 stream.",
		 function );

		return( -1 );
	}
	if( base16_stream_size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid base16 stream size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( base16_stream_index == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid base16 stream index.",
		 function );

		return( -1 );
	}
	if( *base16_stream_index >= base16_stream_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
		 "%s: base16 stream string too small.",
		 function );

		return( -1 );
	}
	if( byte_stream == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid byte stream.",
		 function );

		return( -1 );
	}
	if( byte_stream_size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid byte stream size value exceeds maximum.",
		 function );

		return( -1 );
	}
	switch( base16_variant & 0x000000ffUL )
	{
		case LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE:
			character_limit = 0;
			break;

		case LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_64:
			character_limit = 64;
			break;

		case LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_76:
			character_limit = 76;
			break;

		default:
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
			 "%s: unsupported base16 variant.",
			 function );

			return( -1 );
	}
	switch( base16_variant & 0x000f0000UL )
	{
		case LIBUNA_BASE16_VARIANT_CASE_LOWER:
			a_character_value = (uint32_t) 'a' - 10;
			break;

		case LIBUNA_BASE16_VARIANT_CASE_MIXED:
		case LIBUNA_BASE16_VARIANT_CASE_UPPER:
			a_character_value = (uint32_t) 'A' - 10;
			break;

		default:
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
			 "%s: unsupported base16 variant.",
			 function );

			return( -1 );
	}
	switch( base16_variant & 0xf0000000UL )
	{
		case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM:
			base16_character_size = 1;
			break;

		case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
		case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
			base16_character_size = 2;
			break;

		case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
		case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
			base16_character_size = 4;
			break;

		default:
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
			 "%s: unsupported base16 variant.",
			 function );

			return( -1 );
	}
	stream_index = *base16_stream_index;

	/* Make sure the base16 stream is able to hold
	 * at least 2 bytes for each byte
	 */
	calculated_base16_stream_size = byte_stream_size * 2;

	if( character_limit != 0 )
	{
		whitespace_size = calculated_base16_stream_size / character_limit;

		if( ( calculated_base16_stream_size % character_limit ) != 0 )
		{
			whitespace_size += 1;
		}
		calculated_base16_stream_size += whitespace_size;
	}
	calculated_base16_stream_size *= base16_character_size;

	if( base16_stream_size < calculated_base16_stream_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
		 "%s: base16 stream is too small.",
		 function );

		return( -1 );
	}
	while( byte_stream_index < byte_stream_size )
	{
		base16_character = byte_stream[ byte_stream_index ] >> 4;

		if( base16_character <= 9 )
		{
			base16_character += (uint32_t) '0';
		}
		else
		{
			base16_character += a_character_value;
		}
		switch( base16_variant & 0xf0000000UL )
		{
			case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM:
				base16_stream[ stream_index ] = (uint8_t) base16_character;
				break;

			case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
				byte_stream_copy_from_uint16_big_endian(
				 &( base16_stream[ stream_index ] ),
				 base16_character );
				break;

			case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
				byte_stream_copy_from_uint16_little_endian(
				 &( base16_stream[ stream_index ] ),
				 base16_character );
				break;

			case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
				byte_stream_copy_from_uint32_big_endian(
				 &( base16_stream[ stream_index ] ),
				 base16_character );
				break;

			case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
				byte_stream_copy_from_uint32_little_endian(
				 &( base16_stream[ stream_index ] ),
				 base16_character );
				break;
		}
		stream_index += base16_character_size;

		base16_character = byte_stream[ byte_stream_index ] & 0x0f;

		if( base16_character <= 9 )
		{
			base16_character += (uint32_t) '0';
		}
		else
		{
			base16_character += a_character_value;
		}
		switch( base16_variant & 0xf0000000UL )
		{
			case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM:
				base16_stream[ stream_index ] = (uint8_t) base16_character;
				break;

			case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
				byte_stream_copy_from_uint16_big_endian(
				 &( base16_stream[ stream_index ] ),
				 base16_character );
				break;

			case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
				byte_stream_copy_from_uint16_little_endian(
				 &( base16_stream[ stream_index ] ),
				 base16_character );
				break;

			case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
				byte_stream_copy_from_uint32_big_endian(
				 &( base16_stream[ stream_index ] ),
				 base16_character );
				break;

			case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
				byte_stream_copy_from_uint32_little_endian(
				 &( base16_stream[ stream_index ] ),
				 base16_character );
				break;
		}
		stream_index += base16_character_size;

		if( character_limit != 0 )
		{
			number_of_characters += 2;

			if( number_of_characters >= (size_t) character_limit )
			{
				base16_character = (uint32_t) '\n';

				switch( base16_variant & 0xf0000000UL )
				{
					case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM:
						base16_stream[ stream_index ] = (uint8_t) base16_character;
						break;

					case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
						byte_stream_copy_from_uint16_big_endian(
						 &( base16_stream[ stream_index ] ),
						 base16_character );
						break;

					case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
						byte_stream_copy_from_uint16_little_endian(
						 &( base16_stream[ stream_index ] ),
						 base16_character );
						break;

					case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
						byte_stream_copy_from_uint32_big_endian(
						 &( base16_stream[ stream_index ] ),
						 base16_character );
						break;

					case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
						byte_stream_copy_from_uint32_little_endian(
						 &( base16_stream[ stream_index ] ),
						 base16_character );
						break;
				}
				stream_index += base16_character_size;

				number_of_characters = 0;
			}
		}
		byte_stream_index++;
	}
	if( character_limit != 0 )
	{
		if( number_of_characters != 0 )
		{
			base16_character = (uint32_t) '\n';

			switch( base16_variant & 0xf0000000UL )
			{
				case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM:
					base16_stream[ stream_index ] = (uint8_t) base16_character;
					break;

				case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
					byte_stream_copy_from_uint16_big_endian(
					 &( base16_stream[ stream_index ] ),
					 base16_character );
					break;

				case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
					byte_stream_copy_from_uint16_little_endian(
					 &( base16_stream[ stream_index ] ),
					 base16_character );
					break;

				case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
					byte_stream_copy_from_uint32_big_endian(
					 &( base16_stream[ stream_index ] ),
					 base16_character );
					break;

				case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
					byte_stream_copy_from_uint32_little_endian(
					 &( base16_stream[ stream_index ] ),
					 base16_character );
					break;
			}
			stream_index += base16_character_size;
		}
	}
	*base16_stream_index = stream_index;

	return( 1 );
}