コード例 #1
0
static int process_chunk(struct sparse_file *s, int fd, off64_t offset,
		unsigned int chunk_hdr_sz, chunk_header_t *chunk_header,
		unsigned int cur_block, uint32_t *crc_ptr)
{
	int ret;
	unsigned int chunk_data_size;

	chunk_data_size = chunk_header->total_sz - chunk_hdr_sz;

	switch (chunk_header->chunk_type) {
		case CHUNK_TYPE_RAW:
			ret = process_raw_chunk(s, chunk_data_size, fd, offset,
					chunk_header->chunk_sz, cur_block, crc_ptr);
			if (ret < 0) {
				verbose_error(s->verbose, ret, "data block at %" PRId64, offset);
				return ret;
			}
			return chunk_header->chunk_sz;
		case CHUNK_TYPE_FILL:
			ret = process_fill_chunk(s, chunk_data_size, fd,
					chunk_header->chunk_sz, cur_block, crc_ptr);
			if (ret < 0) {
				verbose_error(s->verbose, ret, "fill block at %" PRId64, offset);
				return ret;
			}
			return chunk_header->chunk_sz;
		case CHUNK_TYPE_DONT_CARE:
			ret = process_skip_chunk(s, chunk_data_size, fd,
					chunk_header->chunk_sz, cur_block, crc_ptr);
			if (chunk_data_size != 0) {
				if (ret < 0) {
					verbose_error(s->verbose, ret, "skip block at %" PRId64, offset);
					return ret;
				}
			}
			return chunk_header->chunk_sz;
		case CHUNK_TYPE_CRC32:
			ret = process_crc32_chunk(fd, chunk_data_size, *crc_ptr);
			if (ret < 0) {
				verbose_error(s->verbose, -EINVAL, "crc block at %" PRId64,
						offset);
				return ret;
			}
			return 0;
		default:
			verbose_error(s->verbose, -EINVAL, "unknown block %04X at %" PRId64,
					chunk_header->chunk_type, offset);
	}

	return 0;
}
コード例 #2
0
ファイル: simg2img.c プロジェクト: dhs-shine/sprd_project
/* -1 : error; x : buf is finished to write */
int write_simg2emmc(char* interface, int  dev, wchar_t* partname, u8* buf, unsigned long length)
{
	unsigned int i;

	chunk_header_t chunk_header;
	u32 crc32 = 0;
	int ret;
	unsigned int bufferindex = 0;
	g_buf_index = 0;
	
	g_emmc_handle.pdev = get_dev(interface, dev);
	if (g_emmc_handle.pdev == NULL) {
		printf("Block device %s %d not supported\n", interface, dev);
		goto fail;
	}
	if (get_partition_info_by_name(g_emmc_handle.pdev, partname, &g_emmc_handle.info))
		goto fail;
	g_emmc_handle.cardPartiton = 0;
	
	g_emmc_handle.startBlock = g_emmc_handle.info.start;
	//printf("download_status = %d  current_chunks = %d length = %d\n", download_status, current_chunks, length);
	if (download_status == END) {
		current_chunks = 0;
		total_blocks = 0;
		g_emmc_handle.offset = 0;
		gbufindex = 0;
		memset(&sparse_header, 0, sizeof(sparse_header_t));
		ret = read_all(buf, g_buf_index, &sparse_header, sizeof(sparse_header));
		//printf("sparse_header file_hdr_sz = %d chunk_hdr_sz = %d blk_sz = %d total_blks = %d total_chunks = %d\n", sparse_header.file_hdr_sz, sparse_header.chunk_hdr_sz, sparse_header.blk_sz, sparse_header.total_blks, sparse_header.total_chunks);
		if (ret != sizeof(sparse_header)) {
			printf("Error reading sparse file header\n");
			goto fail;
		}
		if (sparse_header.magic != SPARSE_HEADER_MAGIC) {
			printf("Bad magic\n");
			goto fail;
		}

		if (sparse_header.major_version != SPARSE_HEADER_MAJOR_VER) {
			printf("Unknown major version number\n");
			goto fail;
		}

		if (sparse_header.file_hdr_sz > SPARSE_HEADER_LEN) {
			/* Skip the remaining bytes in a header that is longer than
		 	* we expected.
			 */
			g_buf_index += (sparse_header.file_hdr_sz - SPARSE_HEADER_LEN);
		}
		download_status = START;
	}

	for (i=current_chunks; i<sparse_header.total_chunks; i++) {
		/////////////////////////////////////////////////////////////////////////////////
		memset(&chunk_header, 0, sizeof(chunk_header_t));
		bufferindex = g_buf_index;
		if ((bufferindex + sizeof(chunk_header)) > length) {
			current_chunks = i;
			break;
		}

		preread_chunk((void*)buf, bufferindex, &chunk_header, sizeof(chunk_header));

		/*if (gbufindex)
			printf("i = %d bufferindex = %d chunk_type = 0x%04x chunk_sz = %d total_sz = %d  currentoffset = %d\n", i, gbufindex + bufferindex, chunk_header.chunk_type, chunk_header.chunk_sz, chunk_header.total_sz, g_emmc_handle.offset * EMMC_BLOCK_SIZE);
		else
			printf("i = %d bufferindex = %d chunk_type = 0x%04x chunk_sz = %d total_sz = %d  currentoffset = %d\n", i, bufferindex, chunk_header.chunk_type, chunk_header.chunk_sz, chunk_header.total_sz, g_emmc_handle.offset * EMMC_BLOCK_SIZE);*/

		if (sparse_header.chunk_hdr_sz > CHUNK_HEADER_LEN) {
			bufferindex += sparse_header.chunk_hdr_sz - CHUNK_HEADER_LEN;
		}
		ret = 0;
		switch (chunk_header.chunk_type) {
			case CHUNK_TYPE_RAW:
			case CHUNK_TYPE_FILL:
			case CHUNK_TYPE_DONT_CARE:
			case CHUNK_TYPE_CRC32:
			if ((bufferindex + chunk_header.total_sz) > length) {
				printf("type : 0x%04x exceed  %d : %d\n", chunk_header.chunk_type, bufferindex + chunk_header.total_sz, length);
				ret = 1;
			}
			break;
			default:
			printf("Unknown chunk type 0x%4.4x\n", chunk_header.chunk_type);
		}

		if (ret == 1) {
			current_chunks = i;
			break;
		}
		/////////////////////////////////////////////////////////////////////////////////

		memset(&chunk_header, 0, sizeof(chunk_header_t));
		ret = read_all((void*)buf, g_buf_index, &chunk_header, sizeof(chunk_header));

		/*if (gbufindex)
			printf("i = %d g_buf_index = %d chunk_type = 0x%04x chunk_sz = %d total_sz = %d currentoffset = %d\n", i, gbufindex + g_buf_index, chunk_header.chunk_type, chunk_header.chunk_sz, chunk_header.total_sz, g_emmc_handle.offset * EMMC_BLOCK_SIZE);
		else
			printf("i = %d g_buf_index = %d chunk_type = 0x%04x chunk_sz = %d total_sz = %d currentoffset = %d\n", i, g_buf_index, chunk_header.chunk_type, chunk_header.chunk_sz, chunk_header.total_sz, g_emmc_handle.offset * EMMC_BLOCK_SIZE);*/

		if (ret != sizeof(chunk_header)) {
			printf("Error reading chunk header\n");
			goto fail;
		}
 
		if (sparse_header.chunk_hdr_sz > CHUNK_HEADER_LEN) {
			/* Skip the remaining bytes in a header that is longer than
			 * we expected.
			 */
			g_buf_index += sparse_header.chunk_hdr_sz - CHUNK_HEADER_LEN;			 
		}

		switch (chunk_header.chunk_type) {
			case CHUNK_TYPE_RAW:
			if (chunk_header.total_sz != (sparse_header.chunk_hdr_sz +
				 (chunk_header.chunk_sz * sparse_header.blk_sz)) ) {
				printf("Bogus chunk size for chunk %d, type Raw\n", i);
				goto fail;
			}
			total_blocks += process_raw_chunk((void*)buf, &g_emmc_handle,
					 chunk_header.chunk_sz, sparse_header.blk_sz, &crc32);
			break;
			case CHUNK_TYPE_FILL:
			if (chunk_header.total_sz != (sparse_header.chunk_hdr_sz + sizeof(u32)) ) {
				printf("Bogus chunk size for chunk %d, type Fill\n", i);
				goto fail;
			}
			total_blocks += process_fill_chunk((void*)buf, &g_emmc_handle,
					 chunk_header.chunk_sz, sparse_header.blk_sz, &crc32);
			break;
			case CHUNK_TYPE_DONT_CARE:
			if (chunk_header.total_sz != sparse_header.chunk_hdr_sz) {
				printf("Bogus chunk size for chunk %d, type Dont Care\n", i);
				goto fail;
			}
			total_blocks += process_skip_chunk(&g_emmc_handle,
					 chunk_header.chunk_sz, sparse_header.blk_sz, &crc32);
			break;
			case CHUNK_TYPE_CRC32:
			if(process_crc32_chunk((void*)buf, crc32) != 0){
				goto fail;
			}
			break;
			default:
			printf("Unknown chunk type 0x%4.4x\n", chunk_header.chunk_type);
		}

	}

	//printf("offset = %d g_buf_index = %d  length = %d  Wrote %d blocks, expected to write %d blocks\n", g_emmc_handle.offset, g_buf_index, length, total_blocks, sparse_header.total_blks);
	if (sparse_header.total_blks != total_blocks) {
		gbufindex += g_buf_index;
		return g_buf_index;
	} else {
		download_status = END;
		current_chunks = 0;
		g_emmc_handle.offset = 0;
		total_blocks = 0;
		gbufindex = 0;
		return 0;
	}

fail:
	return -1;
}
コード例 #3
0
ファイル: simg2img.c プロジェクト: 543872407/Linux_SourceCode
int main(int argc, char *argv[])
{
	FILE *in, *out;
	unsigned int i;
	sparse_header_t sparse_header;
	chunk_header_t chunk_header;
	u32 crc32 = 0;
	u32 total_blocks = 0;

	if (argc != 3) {
		usage();
		exit(-1);
	}

	if ( (copybuf = malloc(COPY_BUF_SIZE)) == 0) {
		fprintf(stderr, "Cannot malloc copy buf\n");
		exit(-1);
	}

	if ((in = fopen(argv[1], "rb")) == 0) {
		fprintf(stderr, "Cannot open input file %s\n", argv[1]);
		exit(-1);
	}

	if ((out = fopen(argv[2], "wb")) == 0) {
		fprintf(stderr, "Cannot open output file %s\n", argv[2]);
		exit(-1);
	}

	if (fread(&sparse_header, sizeof(sparse_header), 1, in) != 1) {
		fprintf(stderr, "Error reading sparse file header\n");
		exit(-1);
	}

	if (sparse_header.magic != SPARSE_HEADER_MAGIC) {
		fprintf(stderr, "Bad magic\n");
		exit(-1);
	}

	if (sparse_header.major_version != SPARSE_HEADER_MAJOR_VER) {
		fprintf(stderr, "Unknown major version number\n");
		exit(-1);
	}

	if (sparse_header.file_hdr_sz > SPARSE_HEADER_LEN) {
		/* Skip the remaining bytes in a header that is longer than
		 * we expected.
		 */
		fseek(in, sparse_header.file_hdr_sz - SPARSE_HEADER_LEN, SEEK_CUR);
	}

	if ( (zerobuf = malloc(sparse_header.blk_sz)) == 0) {
		fprintf(stderr, "Cannot malloc zero buf\n");
		exit(-1);
	}

	for (i=0; i<sparse_header.total_chunks; i++) {
		if (fread(&chunk_header, sizeof(chunk_header), 1, in) != 1) {
			fprintf(stderr, "Error reading chunk header\n");
			exit(-1);
		}
 
		if (sparse_header.chunk_hdr_sz > CHUNK_HEADER_LEN) {
			/* Skip the remaining bytes in a header that is longer than
			 * we expected.
			 */
			fseek(in, sparse_header.chunk_hdr_sz - CHUNK_HEADER_LEN, SEEK_CUR);
		}

		switch (chunk_header.chunk_type) {
		    case CHUNK_TYPE_RAW:
			if (chunk_header.total_sz != (sparse_header.chunk_hdr_sz +
				 (chunk_header.chunk_sz * sparse_header.blk_sz)) ) {
				fprintf(stderr, "Bogus chunk size for chunk %d, type Raw\n", i);
				exit(-1);
			}
			total_blocks += process_raw_chunk(in, out,
					 chunk_header.chunk_sz, sparse_header.blk_sz, &crc32);
			break;
		    case CHUNK_TYPE_DONT_CARE:
			if (chunk_header.total_sz != sparse_header.chunk_hdr_sz) {
				fprintf(stderr, "Bogus chunk size for chunk %d, type Dont Care\n", i);
				exit(-1);
			}
			total_blocks += process_skip_chunk(out,
					 chunk_header.chunk_sz, sparse_header.blk_sz, &crc32);
			break;
		    default:
			fprintf(stderr, "Unknown chunk type 0x%4.4x\n", chunk_header.chunk_type);
			exit(-1);
		}

	}

	/* If the last chunk was a skip, then the code just did a seek, but
	 * no write, and the file won't actually be the correct size.  This
	 * will make the file the correct size.  Make sure the offset is
	 * computed in 64 bits, and the function called can handle 64 bits.
	 */
	if (ftruncate(fileno(out), (u64)total_blocks * sparse_header.blk_sz)) {
		fprintf(stderr, "Error calling ftruncate() to set the image size\n");
		exit(-1);
	}

	fclose(in);
	fclose(out);

	if (sparse_header.total_blks != total_blocks) {
		fprintf(stderr, "Wrote %d blocks, expected to write %d blocks\n",
			 total_blocks, sparse_header.total_blks);
		exit(-1);
	}

	if (sparse_header.image_checksum != crc32) {
		fprintf(stderr, "computed crc32 of 0x%8.8x, expected 0x%8.8x\n",
			 crc32, sparse_header.image_checksum);
		exit(-1);
	}

	exit(0);
}