Пример #1
0
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive number (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	if (pdrv < CTR_DISK_COUNT)
	{
		ctr_fatfs_disk *disk = &ctr_fatfs_disks[pdrv];
		switch (cmd)
		{
		case GET_SECTOR_COUNT:
			if (!(disk->status & STA_NOINIT))
			{
				*(DWORD*)buff = disk->sectors;
				return RES_OK;
			}
			return RES_NOTRDY;

		case GET_SECTOR_SIZE:
			if (!(disk->status & STA_NOINIT))
			{
				*(WORD*)buff = ctr_io_sector_size(disk->io);
				return RES_OK;
			}
			return RES_NOTRDY;
		case GET_BLOCK_SIZE:
			*(DWORD*)buff = 1; //Not sure what the block size for SD is...
		case CTRL_TRIM:
		case CTRL_SYNC:
			return RES_OK;
		case CTR_SETUP_DISK:
			{
				ctr_setup_disk_parameters *params = (ctr_setup_disk_parameters*)buff;
				ctr_fatfs_disk_initialize(disk, params->io, params->sector_offset, params->sectors);
			}
			return RES_OK;
		default:
			return RES_PARERR;
		}
		return RES_NOTRDY;
	}

	return RES_PARERR;
}
Пример #2
0
int ctr_crypto_interface_write_sector(void *io, const void *buffer, size_t buffer_size, size_t sector)
{
	int res = 0;
	ctr_crypto_interface *crypto_io = io;
	const size_t sector_size = ctr_io_sector_size(crypto_io->lower_io);
	const size_t number_of_sectors = FLOOR(buffer_size, sector_size);
	const size_t block_size = AES_BLOCK_SIZE;
	size_t sectors_per_block = block_size / sector_size;

	if (!sectors_per_block)
		sectors_per_block = 1;

	if (number_of_sectors)
	{
		size_t block_sector_lcm = lcm(sector_size, block_size);

		uint8_t window_buffer[4 * block_sector_lcm + sectors_per_block * sector_size];
		write_window window =
		{
			.window = window_buffer,
			.window_size = sizeof(window_buffer),
			.window_offset = 0,
			.buffer = buffer,
			.buffer_size = buffer_size,
			.buffer_offset = 0,
			.current_sector = sector
		};

		setup_window(io, &window, sector, sector_size, block_size);

		res = process_window(io, &window, sector_size, block_size, input, output);
		while(!res)
		{
			res = process_window(io, &window, sector_size, block_size, input, output);
		}
	}
	return res == 1 ? 0 : res;
}
Пример #3
0
int ctr_crypto_interface_read_sector(void *io, void *buffer, size_t buffer_size, size_t sector, size_t count)
{
	int res = 0;
	ctr_crypto_interface *crypto_io = io;
	const size_t sector_size = ctr_io_sector_size(crypto_io->lower_io);
	const size_t block_size = AES_BLOCK_SIZE;

	size_t result_count = count < buffer_size/sector_size ? count : buffer_size/sector_size;

	void (*block_function)(void *io, void *buffer, uint64_t block, size_t block_count);
	block_function = output;

	if (result_count)
	{
		size_t result_size = result_count * sector_size;
		uint8_t *current_processed = buffer;
		size_t current_block = get_prev_relative_chunk(sector, sector_size, block_size);

		res = ctr_io_read_sector(crypto_io->lower_io, buffer, buffer_size, sector, result_count);
		if (res)
			return res;

		//Part 1, deal with misaligned first block
		size_t sectors_to_copy_prior = get_chunks_to_complete_relative_chunk_backwards(sector, sector_size, block_size);
		if (sectors_to_copy_prior)
		{
			uint8_t buf[block_size];
			res = get_misaligned_block(crypto_io, sector, sector_size, block_size, buf, block_function);
			if (res)
				return res;

			//We now have the full block-- we now need to figure out which part of it to copy
			uint64_t sector_pos = get_chunk_position(sector, sector_size);
			uint64_t block_pos = get_chunk_position(current_block, block_size);

			size_t amount_to_copy = block_size - (sector_pos - block_pos);
			amount_to_copy = amount_to_copy < buffer_size ? amount_to_copy : buffer_size;
			memcpy(buffer, buf + (sector_pos - block_pos), amount_to_copy);
			current_processed += amount_to_copy;

			current_block++;
		}

		//Part 2, Deal with all intermediate blocks
		size_t bytes_left = result_size - (size_t)(current_processed - (uint8_t*)buffer);
		size_t blocks = FLOOR(bytes_left, block_size);
		if (blocks)
		{
			block_function(io, current_processed, current_block, blocks);
			current_block += blocks;
			current_processed += blocks * block_size;
			bytes_left -= blocks * block_size;
		}

		//Part 3, deal with the final block
		//FIXME what if we need to deal with a block that actually continues past the end of the disk? pad with zero?
		if (bytes_left)
		{
			uint8_t buf[block_size];
			//size_t current_sector = get_next_relative_block
			size_t block_sector = get_prev_relative_chunk(current_block, block_size, sector_size);
			res = get_misaligned_block(crypto_io, block_sector, sector_size, block_size, buf, block_function);
			if (res)
				return res;

			//We now have the full block-- we now need to figure out which part of it to copy
			uint64_t sector_pos = get_chunk_position(block_sector, sector_size);
			uint64_t block_pos = get_chunk_position(current_block, block_size);

			size_t amount_to_copy = block_size - (sector_pos - block_pos);
			amount_to_copy = amount_to_copy < bytes_left ? amount_to_copy : bytes_left;
			memcpy(current_processed, buf + (sector_pos - block_pos), amount_to_copy);
		}

	}
	return res;
}