diff --git a/include/aaruformat/consts.h b/include/aaruformat/consts.h index e0e8ffe..58480ae 100644 --- a/include/aaruformat/consts.h +++ b/include/aaruformat/consts.h @@ -30,7 +30,15 @@ #define AARU_MAGIC 0x544D524655524141 /** Image format version. A change in this number indicates an incompatible change to the format that prevents older * implementations from reading it correctly, if at all. */ -#define AARUF_VERSION 1 +#define AARUF_VERSION 2 +/** First version of AaruFormat, created in C#. + * CRC64 was byte-swapped + */ +#define AARUF_VERSION_V1 1 +/** Second version of AaruFormat, created in C. + * Introduced new header, many new features, and blocks. + */ +#define AARUF_VERSION_V2 2 /** Maximum read cache size, 512MiB. */ #define MAX_CACHE_SIZE 536870912 /** Size in bytes of LZMA properties. */ diff --git a/include/aaruformat/context.h b/include/aaruformat/context.h index b6beeb7..9998b0f 100644 --- a/include/aaruformat/context.h +++ b/include/aaruformat/context.h @@ -34,16 +34,18 @@ #define SHA256_DIGEST_LENGTH 32 #endif -typedef struct Crc64Context { +typedef struct Crc64Context +{ uint64_t finalSeed; uint64_t table[256]; uint64_t hashInt; } Crc64Context; -typedef struct CdEccContext { - bool initedEdc; - uint8_t *eccBTable; - uint8_t *eccFTable; +typedef struct CdEccContext +{ + bool initedEdc; + uint8_t *eccBTable; + uint8_t *eccFTable; uint32_t *edcTable; } CdEccContext; @@ -73,7 +75,7 @@ typedef struct aaruformatContext uint8_t libraryMajorVersion; uint8_t libraryMinorVersion; FILE *imageStream; - AaruHeader header; + AaruHeaderV2 header; uint8_t *sectorPrefix; uint8_t *sectorPrefixCorrected; uint8_t *sectorSuffix; diff --git a/src/blocks/data.c b/src/blocks/data.c index a78abf1..1bc9c3e 100644 --- a/src/blocks/data.c +++ b/src/blocks/data.c @@ -219,7 +219,7 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry) crc64 = aaruf_crc64_data(data, blockHeader.length); // Due to how C# wrote it, it is effectively reversed - if(ctx->header.imageMajorVersion <= AARUF_VERSION) crc64 = bswap_64(crc64); + if(ctx->header.imageMajorVersion <= AARUF_VERSION_V1) crc64 = bswap_64(crc64); if(crc64 != blockHeader.crc64) { diff --git a/src/blocks/dump.c b/src/blocks/dump.c index 6aa106d..d489cb7 100644 --- a/src/blocks/dump.c +++ b/src/blocks/dump.c @@ -79,7 +79,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry) crc64 = aaruf_crc64_data(data, ctx->dumpHardwareHeader.length); // Due to how C# wrote it, it is effectively reversed - if(ctx->header.imageMajorVersion <= AARUF_VERSION) crc64 = bswap_64(crc64); + if(ctx->header.imageMajorVersion <= AARUF_VERSION_V1) crc64 = bswap_64(crc64); if(crc64 != ctx->dumpHardwareHeader.crc64) { diff --git a/src/blocks/optical.c b/src/blocks/optical.c index 830fd46..a979fd5 100644 --- a/src/blocks/optical.c +++ b/src/blocks/optical.c @@ -87,7 +87,7 @@ void process_tracks_block(aaruformatContext *ctx, const IndexEntry *entry) crc64 = aaruf_crc64_data((const uint8_t *)ctx->trackEntries, ctx->tracksHeader.entries * sizeof(TrackEntry)); // Due to how C# wrote it, it is effectively reversed - if(ctx->header.imageMajorVersion <= AARUF_VERSION) crc64 = bswap_64(crc64); + if(ctx->header.imageMajorVersion <= AARUF_VERSION_V1) crc64 = bswap_64(crc64); if(crc64 != ctx->tracksHeader.crc64) { diff --git a/src/index/index_v1.c b/src/index/index_v1.c index fadd419..de27bfb 100644 --- a/src/index/index_v1.c +++ b/src/index/index_v1.c @@ -107,7 +107,7 @@ int32_t verify_index_v1(aaruformatContext *ctx) crc64 = aaruf_crc64_data((const uint8_t *)index_entries, sizeof(IndexEntry) * index_header.entries); // Due to how C# wrote it, it is effectively reversed - if(ctx->header.imageMajorVersion <= AARUF_VERSION) crc64 = bswap_64(crc64); + if(ctx->header.imageMajorVersion <= AARUF_VERSION_V1) crc64 = bswap_64(crc64); if(crc64 != index_header.crc64) { diff --git a/src/index/index_v2.c b/src/index/index_v2.c index aef0987..8570ca9 100644 --- a/src/index/index_v2.c +++ b/src/index/index_v2.c @@ -107,7 +107,7 @@ int32_t verify_index_v2(aaruformatContext *ctx) crc64 = aaruf_crc64_data((const uint8_t *)index_entries, sizeof(IndexEntry) * index_header.entries); // Due to how C# wrote it, it is effectively reversed - if(ctx->header.imageMajorVersion <= AARUF_VERSION) crc64 = bswap_64(crc64); + if(ctx->header.imageMajorVersion <= AARUF_VERSION_V1) crc64 = bswap_64(crc64); if(crc64 != index_header.crc64) { diff --git a/src/open.c b/src/open.c index 45fc588..61cbd92 100644 --- a/src/open.c +++ b/src/open.c @@ -76,6 +76,21 @@ void *aaruf_open(const char *filepath) return NULL; } + // Read new header version + if(ctx->header.imageMajorVersion >= AARUF_VERSION_V2) + { + fseek(ctx->imageStream, 0, SEEK_SET); + readBytes = fread(&ctx->header, 1, sizeof(AaruHeaderV2), ctx->imageStream); + + if(readBytes != sizeof(AaruHeaderV2)) + { + free(ctx); + errno = AARUF_ERROR_FILE_TOO_SMALL; + + return NULL; + } + } + if(ctx->header.imageMajorVersion > AARUF_VERSION) { free(ctx); diff --git a/src/verify.c b/src/verify.c index 83bd8b1..002ac1e 100644 --- a/src/verify.c +++ b/src/verify.c @@ -137,7 +137,7 @@ int32_t aaruf_verify_image(void *context) aaruf_crc64_final(crc64_context, &crc64); // Due to how C# wrote it, it is effectively reversed - if(ctx->header.imageMajorVersion <= AARUF_VERSION) crc64 = bswap_64(crc64); + if(ctx->header.imageMajorVersion <= AARUF_VERSION_V1) crc64 = bswap_64(crc64); if(crc64 != block_header.cmpCrc64) { @@ -180,7 +180,7 @@ int32_t aaruf_verify_image(void *context) aaruf_crc64_final(crc64_context, &crc64); // Due to how C# wrote it, it is effectively reversed - if(ctx->header.imageMajorVersion <= AARUF_VERSION) crc64 = bswap_64(crc64); + if(ctx->header.imageMajorVersion <= AARUF_VERSION_V1) crc64 = bswap_64(crc64); if(crc64 != ddt_header.cmpCrc64) { @@ -214,7 +214,7 @@ int32_t aaruf_verify_image(void *context) aaruf_crc64_final(crc64_context, &crc64); // Due to how C# wrote it, it is effectively reversed - if(ctx->header.imageMajorVersion <= AARUF_VERSION) crc64 = bswap_64(crc64); + if(ctx->header.imageMajorVersion <= AARUF_VERSION_V1) crc64 = bswap_64(crc64); if(crc64 != tracks_header.crc64) { diff --git a/tool/info.c b/tool/info.c index 33c9677..dcafc33 100644 --- a/tool/info.c +++ b/tool/info.c @@ -29,13 +29,13 @@ int info(char *path) { - aaruformatContext *ctx = NULL; - char *strBuffer = NULL; - UErrorCode u_error_code = U_ZERO_ERROR; - uint i = 0, j = 0; - mediaTagEntry const *mediaTag = NULL; + aaruformatContext *ctx = NULL; + char *strBuffer = NULL; + UErrorCode u_error_code = U_ZERO_ERROR; + uint i = 0, j = 0; + mediaTagEntry const *mediaTag = NULL; mediaTagEntry const *tmpMediaTag = NULL; - UChar ustr[128]; + UChar ustr[128]; ctx = aaruf_open(path); @@ -59,7 +59,7 @@ int info(char *path) printf("\tApplication version: %d.%d\n", ctx->header.applicationMajorVersion, ctx->header.applicationMinorVersion); printf("\tImage format version: %d.%d\n", ctx->header.imageMajorVersion, ctx->header.imageMinorVersion); - printf("\tMedia type: %d\n", ctx->header.mediaType); + printf("\tMedia type: %u\n", ctx->header.mediaType); printf("\tIndex offset: %llu\n", ctx->header.indexOffset); printf("\tCreation time: %lld\n", ctx->header.creationTime); printf("\tLast written time: %lld\n", ctx->header.lastWrittenTime); @@ -103,8 +103,8 @@ int info(char *path) if(ctx->metadataBlockHeader.creatorLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.creatorLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.creatorLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.creatorLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.creatorLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.creatorOffset), @@ -115,8 +115,8 @@ int info(char *path) if(ctx->metadataBlockHeader.commentsLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.commentsLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.commentsLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.commentsLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.commentsLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.commentsOffset), @@ -127,8 +127,8 @@ int info(char *path) if(ctx->metadataBlockHeader.mediaTitleLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.mediaTitleLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.mediaTitleLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.mediaTitleLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.mediaTitleLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.mediaTitleOffset), @@ -139,8 +139,8 @@ int info(char *path) if(ctx->metadataBlockHeader.mediaManufacturerLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.mediaManufacturerLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.mediaManufacturerLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.mediaManufacturerLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.mediaManufacturerLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.mediaManufacturerOffset), @@ -151,8 +151,8 @@ int info(char *path) if(ctx->metadataBlockHeader.mediaModelLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.mediaModelLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.mediaModelLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.mediaModelLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.mediaModelLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.mediaModelOffset), @@ -163,8 +163,8 @@ int info(char *path) if(ctx->metadataBlockHeader.mediaSerialNumberLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.mediaSerialNumberLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.mediaSerialNumberLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.mediaSerialNumberLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.mediaSerialNumberLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.mediaSerialNumberOffset), @@ -175,8 +175,8 @@ int info(char *path) if(ctx->metadataBlockHeader.mediaBarcodeLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.mediaBarcodeLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.mediaBarcodeLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.mediaBarcodeLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.mediaBarcodeLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.mediaBarcodeOffset), @@ -187,8 +187,8 @@ int info(char *path) if(ctx->metadataBlockHeader.mediaPartNumberLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.mediaPartNumberLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.mediaPartNumberLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.mediaPartNumberLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.mediaPartNumberLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.mediaPartNumberOffset), @@ -199,8 +199,8 @@ int info(char *path) if(ctx->metadataBlockHeader.driveManufacturerLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.driveManufacturerLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.driveManufacturerLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.driveManufacturerLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.driveManufacturerLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.driveManufacturerOffset), @@ -211,8 +211,8 @@ int info(char *path) if(ctx->metadataBlockHeader.driveModelLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.driveModelLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.driveModelLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.driveModelLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.driveModelLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.driveModelOffset), @@ -223,8 +223,8 @@ int info(char *path) if(ctx->metadataBlockHeader.driveSerialNumberLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.driveSerialNumberLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.driveSerialNumberLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.driveSerialNumberLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.driveSerialNumberLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.driveSerialNumberOffset), @@ -235,8 +235,8 @@ int info(char *path) if(ctx->metadataBlockHeader.driveFirmwareRevisionLength > 0) { - u_error_code = U_ZERO_ERROR; // Reset error code before conversion - strBuffer = malloc(ctx->metadataBlockHeader.driveFirmwareRevisionLength + 1); + u_error_code = U_ZERO_ERROR; // Reset error code before conversion + strBuffer = malloc(ctx->metadataBlockHeader.driveFirmwareRevisionLength + 1); memset(strBuffer, 0, ctx->metadataBlockHeader.driveFirmwareRevisionLength + 1); ucnv_convert(NULL, "UTF-16LE", strBuffer, (int)ctx->metadataBlockHeader.driveFirmwareRevisionLength, (char *)(ctx->metadataBlock + ctx->metadataBlockHeader.driveFirmwareRevisionOffset),