Exemplo n.º 1
0
//process the current window, and advance to the next one.
//Returns a negative number on a failure, a zero when there are still more windows to go, and a 1 when done.
static inline int process_window(ctr_crypto_interface *io, write_window *window, size_t sector_size, size_t block_size, void (*input_function)(void *io, void *buffer, uint64_t block, size_t block_count), void (*output_function)(void *io, void *buffer, uint64_t block, size_t block_count))
{
	//FIXME what if we try to read more than there is disk? Return zeros?
	size_t sectors_to_read = (window->window_size - window->window_offset) / sector_size;
	int res = ctr_io_read_sector(io->lower_io, window->window + window->window_offset, window->window_size - window->window_offset, window->current_sector, sectors_to_read);
	if (res)
		return -1;

	size_t block_start_offset = window->block_offset;
	uint8_t *pos = window->window + block_start_offset;

	size_t amount_to_copy = window->window_size - window->window_offset;
	if (amount_to_copy > window->buffer_size - window->buffer_offset)
		amount_to_copy = window->buffer_size - window->buffer_offset;

	//In the case that blocks are aligned to sectors, this is not necessary... FIXME
	//only process parts that won't be overwritten completely
	//	from block_start_offset to window->window_offset
	size_t blocks_to_process = CEIL(window->window_offset - block_start_offset, block_size);
	if (!blocks_to_process) blocks_to_process = 1;
	output_function(io, pos, window->block, blocks_to_process);

	//now copy data from buffer
	memcpy(window->window + window->window_offset, window->buffer + window->buffer_offset, amount_to_copy);
	window->buffer_offset += amount_to_copy;

	blocks_to_process = CEIL(amount_to_copy + window->window_offset - block_start_offset, block_size);
	input_function(io, pos, window->block, blocks_to_process);

	//We need to write out the full blocks processed actually, not just the sectors
	size_t sectors_processed = (amount_to_copy + window->window_offset) / sector_size;
	size_t sectors_to_copy = CEIL(blocks_to_process * block_size, sector_size);
	res = ctr_io_write_sector(io->lower_io, window->window, sectors_to_copy * sector_size, window->sector);
	if (res)
		return -2;

	//Copy sector that contain part of next block
	update_window(window, sectors_processed);

	return window->buffer_offset >= window->buffer_size;
}
Exemplo n.º 2
0
DRESULT disk_write (
	BYTE pdrv,			/* Physical drive number to identify the drive */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address in LBA */
	UINT count			/* Number of sectors to write */
)
{
	DRESULT res = RES_PARERR;
	if (pdrv < CTR_DISK_COUNT)
	{
		ctr_fatfs_disk *disk = &ctr_fatfs_disks[pdrv];

		if (!(disk->status & STA_NOINIT))
		{
			int result = ctr_io_write_sector(disk->io, buff, count * 0x200, sector + disk->sector_offset);
			res = result ? RES_ERROR : RES_OK;
		}
	}

	return res;
}