mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Enhance logging and error handling across multiple modules
This commit is contained in:
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_checksum_block(%p, %p)", ctx, entry);
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
size_t readBytes = 0;
|
size_t readBytes = 0;
|
||||||
ChecksumHeader checksum_header;
|
ChecksumHeader checksum_header;
|
||||||
@@ -36,7 +38,7 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,12 +46,13 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||||
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
||||||
{
|
{
|
||||||
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...\n", entry->offset);
|
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even if those two checks shall have been done before
|
// Even if those two checks shall have been done before
|
||||||
|
TRACE("Reading checksum block header at position %" PRIu64, entry->offset);
|
||||||
readBytes = fread(&checksum_header, 1, sizeof(ChecksumHeader), ctx->imageStream);
|
readBytes = fread(&checksum_header, 1, sizeof(ChecksumHeader), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(ChecksumHeader))
|
if(readBytes != sizeof(ChecksumHeader))
|
||||||
@@ -65,6 +68,7 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
FATAL("Incorrect identifier for checksum block at position %" PRIu64 "\n", entry->offset);
|
FATAL("Incorrect identifier for checksum block at position %" PRIu64 "\n", entry->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Allocating %u bytes for checksum block", checksum_header.length);
|
||||||
data = (uint8_t *)malloc(checksum_header.length);
|
data = (uint8_t *)malloc(checksum_header.length);
|
||||||
|
|
||||||
if(data == NULL)
|
if(data == NULL)
|
||||||
@@ -74,6 +78,7 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Reading checksum block data at position %" PRIu64, entry->offset + sizeof(ChecksumHeader));
|
||||||
readBytes = fread(data, 1, checksum_header.length, ctx->imageStream);
|
readBytes = fread(data, 1, checksum_header.length, ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != checksum_header.length)
|
if(readBytes != checksum_header.length)
|
||||||
@@ -85,6 +90,7 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
|
TRACE("Processing %u checksum entries", checksum_header.entries);
|
||||||
for(j = 0; j < checksum_header.entries; j++)
|
for(j = 0; j < checksum_header.entries; j++)
|
||||||
{
|
{
|
||||||
checksum_entry = (ChecksumEntry *)(&data[pos]);
|
checksum_entry = (ChecksumEntry *)(&data[pos]);
|
||||||
@@ -92,21 +98,25 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
|
|
||||||
if(checksum_entry->type == Md5)
|
if(checksum_entry->type == Md5)
|
||||||
{
|
{
|
||||||
|
TRACE("Found MD5 checksum");
|
||||||
memcpy(ctx->checksums.md5, &data[pos], MD5_DIGEST_LENGTH);
|
memcpy(ctx->checksums.md5, &data[pos], MD5_DIGEST_LENGTH);
|
||||||
ctx->checksums.hasMd5 = true;
|
ctx->checksums.hasMd5 = true;
|
||||||
}
|
}
|
||||||
else if(checksum_entry->type == Sha1)
|
else if(checksum_entry->type == Sha1)
|
||||||
{
|
{
|
||||||
|
TRACE("Found SHA1 checksum");
|
||||||
memcpy(ctx->checksums.sha1, &data[pos], SHA1_DIGEST_LENGTH);
|
memcpy(ctx->checksums.sha1, &data[pos], SHA1_DIGEST_LENGTH);
|
||||||
ctx->checksums.hasSha1 = true;
|
ctx->checksums.hasSha1 = true;
|
||||||
}
|
}
|
||||||
else if(checksum_entry->type == Sha256)
|
else if(checksum_entry->type == Sha256)
|
||||||
{
|
{
|
||||||
|
TRACE("Found SHA256 checksum");
|
||||||
memcpy(ctx->checksums.sha256, &data[pos], SHA256_DIGEST_LENGTH);
|
memcpy(ctx->checksums.sha256, &data[pos], SHA256_DIGEST_LENGTH);
|
||||||
ctx->checksums.hasSha256 = true;
|
ctx->checksums.hasSha256 = true;
|
||||||
}
|
}
|
||||||
else if(checksum_entry->type == SpamSum)
|
else if(checksum_entry->type == SpamSum)
|
||||||
{
|
{
|
||||||
|
TRACE("Found SpamSum checksum of size %u", checksum_entry->length);
|
||||||
ctx->checksums.spamsum = malloc(checksum_entry->length + 1);
|
ctx->checksums.spamsum = malloc(checksum_entry->length + 1);
|
||||||
|
|
||||||
if(ctx->checksums.spamsum != NULL)
|
if(ctx->checksums.spamsum != NULL)
|
||||||
@@ -123,4 +133,6 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
|
|
||||||
checksum_entry = NULL;
|
checksum_entry = NULL;
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
|
TRACE("Exiting process_checksum_block()");
|
||||||
}
|
}
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
// Process data blocks found while opening an AaruFormat file
|
// Process data blocks found while opening an AaruFormat file
|
||||||
int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_data_block(%p, %p)", ctx, entry);
|
||||||
BlockHeader blockHeader;
|
BlockHeader blockHeader;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
size_t readBytes = 0;
|
size_t readBytes = 0;
|
||||||
@@ -44,7 +45,7 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||||
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
||||||
{
|
{
|
||||||
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...\n", entry->offset);
|
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
|
||||||
|
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
@@ -60,14 +61,18 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
// Even if those two checks shall have been done before
|
// Even if those two checks shall have been done before
|
||||||
|
|
||||||
// NOP block, skip
|
// NOP block, skip
|
||||||
|
TRACE("NoData block found, exiting");
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
if(entry->dataType == NoData) return AARUF_STATUS_OK;
|
if(entry->dataType == NoData) return AARUF_STATUS_OK;
|
||||||
|
|
||||||
|
TRACE("Reading block header at position %" PRIu64, entry->offset);
|
||||||
readBytes = fread(&blockHeader, 1, sizeof(BlockHeader), ctx->imageStream);
|
readBytes = fread(&blockHeader, 1, sizeof(BlockHeader), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(BlockHeader))
|
if(readBytes != sizeof(BlockHeader))
|
||||||
{
|
{
|
||||||
FATAL("Could not read block header at %" PRIu64 "\n", entry->offset);
|
FATAL("Could not read block header at %" PRIu64, entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,37 +81,43 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
// Unused, skip
|
// Unused, skip
|
||||||
if(entry->dataType == UserData)
|
if(entry->dataType == UserData)
|
||||||
{
|
{
|
||||||
if(blockHeader.sectorSize > ctx->imageInfo.SectorSize) ctx->imageInfo.SectorSize = blockHeader.sectorSize;
|
if(blockHeader.sectorSize > ctx->imageInfo.SectorSize)
|
||||||
|
{
|
||||||
|
TRACE("Setting sector size to %" PRIu64 " bytes", blockHeader.sectorSize);
|
||||||
|
ctx->imageInfo.SectorSize = blockHeader.sectorSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(blockHeader.identifier != entry->blockType)
|
if(blockHeader.identifier != entry->blockType)
|
||||||
{
|
{
|
||||||
TRACE("Incorrect identifier for data block at position %" PRIu64 "\n", entry->offset);
|
TRACE("Incorrect identifier for data block at position %" PRIu64, entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(blockHeader.type != entry->dataType)
|
if(blockHeader.type != entry->dataType)
|
||||||
{
|
{
|
||||||
TRACE("Expected block with data type %4.4s at position %" PRIu64
|
TRACE("Expected block with data type %4.4s at position %" PRIu64 " but found data type %4.4s",
|
||||||
" but found data type %4.4s\n",
|
|
||||||
(char *)&entry->blockType, entry->offset, (char *)&blockHeader.type);
|
(char *)&entry->blockType, entry->offset, (char *)&blockHeader.type);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Found data block with type %4.4s at position %" PRIu64 "\n",
|
TRACE("Found data block with type %4.4s at position %" PRIu64, (char *)&entry->blockType, entry->offset);
|
||||||
(char *)&entry->blockType, entry->offset);
|
|
||||||
|
|
||||||
if(blockHeader.compression == Lzma || blockHeader.compression == LzmaClauniaSubchannelTransform)
|
if(blockHeader.compression == Lzma || blockHeader.compression == LzmaClauniaSubchannelTransform)
|
||||||
{
|
{
|
||||||
if(blockHeader.compression == LzmaClauniaSubchannelTransform && blockHeader.type != CdSectorSubchannel)
|
if(blockHeader.compression == LzmaClauniaSubchannelTransform && blockHeader.type != CdSectorSubchannel)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid compression type %d for block with data type %d, continuing...\n",
|
TRACE("Invalid compression type %d for block with data type %d, continuing...", blockHeader.compression,
|
||||||
blockHeader.compression, blockHeader.type);
|
blockHeader.type);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,33 +126,41 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||||
if(cmpData == NULL)
|
if(cmpData == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for block, continuing...\n");
|
TRACE("Cannot allocate memory for block, continuing...");
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (uint8_t *)malloc(blockHeader.length);
|
data = (uint8_t *)malloc(blockHeader.length);
|
||||||
if(data == NULL)
|
if(data == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for block, continuing...\n");
|
TRACE("Cannot allocate memory for block, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
||||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read LZMA properties, continuing...\n");
|
TRACE("Could not read LZMA properties, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||||
if(readBytes != lzmaSize)
|
if(readBytes != lzmaSize)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read compressed block, continuing...\n");
|
TRACE("Could not read compressed block, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,19 +170,21 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
|
|
||||||
if(errorNo != 0)
|
if(errorNo != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Got error %d from LZMA, continuing...\n", errorNo);
|
TRACE("Got error %d from LZMA, continuing...", errorNo);
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(readBytes != blockHeader.length)
|
if(readBytes != blockHeader.length)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error decompressing block, should be {0} bytes but got {1} bytes., continuing...\n");
|
TRACE("Error decompressing block, should be {0} bytes but got {1} bytes., continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,10 +193,11 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
cstData = malloc(blockHeader.length);
|
cstData = malloc(blockHeader.length);
|
||||||
if(cstData == NULL)
|
if(cstData == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for block, continuing...\n");
|
TRACE("Cannot allocate memory for block, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,8 +214,9 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
data = (uint8_t *)malloc(blockHeader.length);
|
data = (uint8_t *)malloc(blockHeader.length);
|
||||||
if(data == NULL)
|
if(data == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for block, continuing...\n");
|
fprintf(stderr, "Cannot allocate memory for block, continuing...");
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,15 +225,17 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
if(readBytes != blockHeader.length)
|
if(readBytes != blockHeader.length)
|
||||||
{
|
{
|
||||||
free(data);
|
free(data);
|
||||||
fprintf(stderr, "Could not read block, continuing...\n");
|
fprintf(stderr, "Could not read block, continuing...");
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACE("Found unknown compression type %d, continuing...\n", blockHeader.compression);
|
TRACE("Found unknown compression type %d, continuing...", blockHeader.compression);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,9 +248,10 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
|
|
||||||
if(crc64 != blockHeader.crc64)
|
if(crc64 != blockHeader.crc64)
|
||||||
{
|
{
|
||||||
TRACE("Incorrect CRC found: 0x%" PRIx64 " found, expected 0x%" PRIx64 ", continuing...\n",
|
TRACE("Incorrect CRC found: 0x%" PRIx64 " found, expected 0x%" PRIx64 ", continuing...", crc64,
|
||||||
crc64, blockHeader.crc64);
|
blockHeader.crc64);
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,7 +300,7 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
|
|
||||||
if(mediaTag == NULL)
|
if(mediaTag == NULL)
|
||||||
{
|
{
|
||||||
TRACE("Cannot allocate memory for media tag entry.\n");
|
TRACE("Cannot allocate memory for media tag entry.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
memset(mediaTag, 0, sizeof(mediaTagEntry));
|
memset(mediaTag, 0, sizeof(mediaTagEntry));
|
||||||
@@ -287,7 +313,7 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
|
|
||||||
if(oldMediaTag != NULL)
|
if(oldMediaTag != NULL)
|
||||||
{
|
{
|
||||||
TRACE("Replaced media tag with type %d\n", oldMediaTag->type);
|
TRACE("Replaced media tag with type %d", oldMediaTag->type);
|
||||||
free(oldMediaTag->data);
|
free(oldMediaTag->data);
|
||||||
free(oldMediaTag);
|
free(oldMediaTag);
|
||||||
oldMediaTag = NULL;
|
oldMediaTag = NULL;
|
||||||
@@ -296,5 +322,6 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_dumphw_block(%p, %p)", ctx, entry);
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
size_t readBytes = 0;
|
size_t readBytes = 0;
|
||||||
uint64_t crc64 = 0;
|
uint64_t crc64 = 0;
|
||||||
@@ -35,7 +36,9 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
FATAL("Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting process_dumphw_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,33 +46,38 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||||
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
||||||
{
|
{
|
||||||
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...\n", entry->offset);
|
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_dumphw_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even if those two checks shall have been done before
|
// Even if those two checks shall have been done before
|
||||||
|
TRACE("Reading dump hardware block header at position %" PRIu64, entry->offset);
|
||||||
readBytes = fread(&ctx->dumpHardwareHeader, 1, sizeof(DumpHardwareHeader), ctx->imageStream);
|
readBytes = fread(&ctx->dumpHardwareHeader, 1, sizeof(DumpHardwareHeader), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(DumpHardwareHeader))
|
if(readBytes != sizeof(DumpHardwareHeader))
|
||||||
{
|
{
|
||||||
memset(&ctx->dumpHardwareHeader, 0, sizeof(DumpHardwareHeader));
|
memset(&ctx->dumpHardwareHeader, 0, sizeof(DumpHardwareHeader));
|
||||||
TRACE("Could not read dump hardware block header, continuing...\n");
|
TRACE("Could not read dump hardware block header, continuing...");
|
||||||
|
TRACE("Exiting process_dumphw_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->dumpHardwareHeader.identifier != DumpHardwareBlock)
|
if(ctx->dumpHardwareHeader.identifier != DumpHardwareBlock)
|
||||||
{
|
{
|
||||||
memset(&ctx->dumpHardwareHeader, 0, sizeof(DumpHardwareHeader));
|
memset(&ctx->dumpHardwareHeader, 0, sizeof(DumpHardwareHeader));
|
||||||
TRACE("Incorrect identifier for data block at position %" PRIu64 "\n", entry->offset);
|
TRACE("Incorrect identifier for data block at position %" PRIu64, entry->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Allocating memory for dump hardware block of length %u", ctx->dumpHardwareHeader.length);
|
||||||
data = (uint8_t *)malloc(ctx->dumpHardwareHeader.length);
|
data = (uint8_t *)malloc(ctx->dumpHardwareHeader.length);
|
||||||
|
|
||||||
if(data == NULL)
|
if(data == NULL)
|
||||||
{
|
{
|
||||||
memset(&ctx->dumpHardwareHeader, 0, sizeof(DumpHardwareHeader));
|
memset(&ctx->dumpHardwareHeader, 0, sizeof(DumpHardwareHeader));
|
||||||
TRACE("Could not allocate memory for dump hardware block, continuing...\n");
|
TRACE("Could not allocate memory for dump hardware block, continuing...");
|
||||||
|
TRACE("Exiting process_dumphw_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,8 +93,9 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
if(crc64 != ctx->dumpHardwareHeader.crc64)
|
if(crc64 != ctx->dumpHardwareHeader.crc64)
|
||||||
{
|
{
|
||||||
free(data);
|
free(data);
|
||||||
TRACE("Incorrect CRC found: 0x%" PRIx64 " found, expected 0x%" PRIx64 ", continuing...\n", crc64,
|
TRACE("Incorrect CRC found: 0x%" PRIx64 " found, expected 0x%" PRIx64 ", continuing...", crc64,
|
||||||
ctx->dumpHardwareHeader.crc64);
|
ctx->dumpHardwareHeader.crc64);
|
||||||
|
TRACE("Exiting process_dumphw_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,12 +109,14 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
if(ctx->dumpHardwareEntriesWithData == NULL)
|
if(ctx->dumpHardwareEntriesWithData == NULL)
|
||||||
{
|
{
|
||||||
memset(&ctx->dumpHardwareHeader, 0, sizeof(DumpHardwareHeader));
|
memset(&ctx->dumpHardwareHeader, 0, sizeof(DumpHardwareHeader));
|
||||||
TRACE("Could not allocate memory for dump hardware block, continuing...\n");
|
TRACE("Could not allocate memory for dump hardware block, continuing...");
|
||||||
|
TRACE("Exiting process_dumphw_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(ctx->dumpHardwareEntriesWithData, 0, sizeof(DumpHardwareEntriesWithData) * ctx->dumpHardwareHeader.entries);
|
memset(ctx->dumpHardwareEntriesWithData, 0, sizeof(DumpHardwareEntriesWithData) * ctx->dumpHardwareHeader.entries);
|
||||||
|
|
||||||
|
TRACE("Processing %u dump hardware block entries", ctx->dumpHardwareHeader.entries);
|
||||||
for(e = 0; e < ctx->dumpHardwareHeader.entries; e++)
|
for(e = 0; e < ctx->dumpHardwareHeader.entries; e++)
|
||||||
{
|
{
|
||||||
readBytes = fread(&ctx->dumpHardwareEntriesWithData[e].entry, 1, sizeof(DumpHardwareEntry), ctx->imageStream);
|
readBytes = fread(&ctx->dumpHardwareEntriesWithData[e].entry, 1, sizeof(DumpHardwareEntry), ctx->imageStream);
|
||||||
@@ -113,7 +124,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
if(readBytes != sizeof(DumpHardwareEntry))
|
if(readBytes != sizeof(DumpHardwareEntry))
|
||||||
{
|
{
|
||||||
ctx->dumpHardwareHeader.entries = e;
|
ctx->dumpHardwareHeader.entries = e;
|
||||||
TRACE("Could not read dump hardware block entry, continuing...\n");
|
TRACE("Could not read dump hardware block entry, continuing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +145,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
free(ctx->dumpHardwareEntriesWithData[e].manufacturer);
|
free(ctx->dumpHardwareEntriesWithData[e].manufacturer);
|
||||||
ctx->dumpHardwareEntriesWithData[e].entry.manufacturerLength = 0;
|
ctx->dumpHardwareEntriesWithData[e].entry.manufacturerLength = 0;
|
||||||
TRACE("Could not read dump hardware block entry manufacturer, "
|
TRACE("Could not read dump hardware block entry manufacturer, "
|
||||||
"continuing...\n");
|
"continuing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +165,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
free(ctx->dumpHardwareEntriesWithData[e].model);
|
free(ctx->dumpHardwareEntriesWithData[e].model);
|
||||||
ctx->dumpHardwareEntriesWithData[e].entry.modelLength = 0;
|
ctx->dumpHardwareEntriesWithData[e].entry.modelLength = 0;
|
||||||
TRACE("Could not read dump hardware block entry model, continuing...\n");
|
TRACE("Could not read dump hardware block entry model, continuing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,7 +187,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
free(ctx->dumpHardwareEntriesWithData[e].revision);
|
free(ctx->dumpHardwareEntriesWithData[e].revision);
|
||||||
ctx->dumpHardwareEntriesWithData[e].entry.revisionLength = 0;
|
ctx->dumpHardwareEntriesWithData[e].entry.revisionLength = 0;
|
||||||
TRACE("Could not read dump hardware block entry revision, "
|
TRACE("Could not read dump hardware block entry revision, "
|
||||||
"continuing...\n");
|
"continuing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,7 +209,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
free(ctx->dumpHardwareEntriesWithData[e].firmware);
|
free(ctx->dumpHardwareEntriesWithData[e].firmware);
|
||||||
ctx->dumpHardwareEntriesWithData[e].entry.firmwareLength = 0;
|
ctx->dumpHardwareEntriesWithData[e].entry.firmwareLength = 0;
|
||||||
TRACE("Could not read dump hardware block entry firmware, "
|
TRACE("Could not read dump hardware block entry firmware, "
|
||||||
"continuing...\n");
|
"continuing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,7 +229,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
free(ctx->dumpHardwareEntriesWithData[e].serial);
|
free(ctx->dumpHardwareEntriesWithData[e].serial);
|
||||||
ctx->dumpHardwareEntriesWithData[e].entry.serialLength = 0;
|
ctx->dumpHardwareEntriesWithData[e].entry.serialLength = 0;
|
||||||
TRACE("Could not read dump hardware block entry serial, continuing...\n");
|
TRACE("Could not read dump hardware block entry serial, continuing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,7 +251,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
free(ctx->dumpHardwareEntriesWithData[e].softwareName);
|
free(ctx->dumpHardwareEntriesWithData[e].softwareName);
|
||||||
ctx->dumpHardwareEntriesWithData[e].entry.softwareNameLength = 0;
|
ctx->dumpHardwareEntriesWithData[e].entry.softwareNameLength = 0;
|
||||||
TRACE("Could not read dump hardware block entry software name, "
|
TRACE("Could not read dump hardware block entry software name, "
|
||||||
"continuing...\n");
|
"continuing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,7 +273,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
free(ctx->dumpHardwareEntriesWithData[e].softwareVersion);
|
free(ctx->dumpHardwareEntriesWithData[e].softwareVersion);
|
||||||
ctx->dumpHardwareEntriesWithData[e].entry.softwareVersionLength = 0;
|
ctx->dumpHardwareEntriesWithData[e].entry.softwareVersionLength = 0;
|
||||||
TRACE("Could not read dump hardware block entry software version, "
|
TRACE("Could not read dump hardware block entry software version, "
|
||||||
"continuing...\n");
|
"continuing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,7 +297,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
free(ctx->dumpHardwareEntriesWithData[e].softwareOperatingSystem);
|
free(ctx->dumpHardwareEntriesWithData[e].softwareOperatingSystem);
|
||||||
ctx->dumpHardwareEntriesWithData[e].entry.softwareOperatingSystemLength = 0;
|
ctx->dumpHardwareEntriesWithData[e].entry.softwareOperatingSystemLength = 0;
|
||||||
TRACE("Could not read dump hardware block entry manufacturer, "
|
TRACE("Could not read dump hardware block entry manufacturer, "
|
||||||
"continuing...\n");
|
"continuing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,7 +308,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
if(ctx->dumpHardwareEntriesWithData[e].extents == NULL)
|
if(ctx->dumpHardwareEntriesWithData[e].extents == NULL)
|
||||||
{
|
{
|
||||||
TRACE("Could not allocate memory for dump hardware block extents, "
|
TRACE("Could not allocate memory for dump hardware block extents, "
|
||||||
"continuing...\n");
|
"continuing...");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,10 +318,11 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
if(readBytes != ctx->dumpHardwareEntriesWithData->entry.extents)
|
if(readBytes != ctx->dumpHardwareEntriesWithData->entry.extents)
|
||||||
{
|
{
|
||||||
free(ctx->dumpHardwareEntriesWithData[e].extents);
|
free(ctx->dumpHardwareEntriesWithData[e].extents);
|
||||||
TRACE("Could not read dump hardware block extents, continuing...\n");
|
TRACE("Could not read dump hardware block extents, continuing...");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: qsort()
|
// TODO: qsort()
|
||||||
}
|
}
|
||||||
|
TRACE("Exiting process_dumphw_block()");
|
||||||
}
|
}
|
||||||
@@ -27,40 +27,48 @@
|
|||||||
// Process the metadata block found while opening an AaruFormat file
|
// Process the metadata block found while opening an AaruFormat file
|
||||||
void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_metadata_block(%p, %p)", ctx, entry);
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
size_t readBytes = 0;
|
size_t readBytes = 0;
|
||||||
|
|
||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
|
TRACE("Exiting process_metadata_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek to block
|
// Seek to block
|
||||||
|
TRACE("Seeking to metadata block at position %" PRIu64, entry->offset);
|
||||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||||
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
||||||
{
|
{
|
||||||
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...\n", entry->offset);
|
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_metadata_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even if those two checks shall have been done before
|
// Even if those two checks shall have been done before
|
||||||
|
TRACE("Reading metadata block header at position %" PRIu64, entry->offset);
|
||||||
readBytes = fread(&ctx->metadataBlockHeader, 1, sizeof(MetadataBlockHeader), ctx->imageStream);
|
readBytes = fread(&ctx->metadataBlockHeader, 1, sizeof(MetadataBlockHeader), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(MetadataBlockHeader))
|
if(readBytes != sizeof(MetadataBlockHeader))
|
||||||
{
|
{
|
||||||
memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader));
|
memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader));
|
||||||
FATAL("Could not read metadata block header, continuing...\n");
|
FATAL("Could not read metadata block header, continuing...");
|
||||||
|
|
||||||
|
TRACE("Exiting process_metadata_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.identifier != entry->blockType)
|
if(ctx->metadataBlockHeader.identifier != entry->blockType)
|
||||||
{
|
{
|
||||||
memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader));
|
memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader));
|
||||||
TRACE("Incorrect identifier for data block at position %" PRIu64 "\n", entry->offset);
|
TRACE("Incorrect identifier for data block at position %" PRIu64 "", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_metadata_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,24 +79,28 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
if(ctx->metadataBlock == NULL)
|
if(ctx->metadataBlock == NULL)
|
||||||
{
|
{
|
||||||
memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader));
|
memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader));
|
||||||
FATAL("Could not allocate memory for metadata block, continuing...\n");
|
FATAL("Could not allocate memory for metadata block, continuing...");
|
||||||
|
|
||||||
|
TRACE("Exiting process_metadata_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Reading metadata block of size %u at position %" PRIu64, ctx->metadataBlockHeader.blockSize,
|
||||||
|
entry->offset + sizeof(MetadataBlockHeader));
|
||||||
readBytes = fread(ctx->metadataBlock, 1, ctx->metadataBlockHeader.blockSize, ctx->imageStream);
|
readBytes = fread(ctx->metadataBlock, 1, ctx->metadataBlockHeader.blockSize, ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != ctx->metadataBlockHeader.blockSize)
|
if(readBytes != ctx->metadataBlockHeader.blockSize)
|
||||||
{
|
{
|
||||||
memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader));
|
memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader));
|
||||||
free(ctx->metadataBlock);
|
free(ctx->metadataBlock);
|
||||||
FATAL("Could not read metadata block, continuing...\n");
|
FATAL("Could not read metadata block, continuing...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.mediaSequence > 0 && ctx->metadataBlockHeader.lastMediaSequence > 0)
|
if(ctx->metadataBlockHeader.mediaSequence > 0 && ctx->metadataBlockHeader.lastMediaSequence > 0)
|
||||||
{
|
{
|
||||||
ctx->imageInfo.MediaSequence = ctx->metadataBlockHeader.mediaSequence;
|
ctx->imageInfo.MediaSequence = ctx->metadataBlockHeader.mediaSequence;
|
||||||
ctx->imageInfo.LastMediaSequence = ctx->metadataBlockHeader.lastMediaSequence;
|
ctx->imageInfo.LastMediaSequence = ctx->metadataBlockHeader.lastMediaSequence;
|
||||||
TRACE("Setting media sequence as %d of %d\n", ctx->imageInfo.MediaSequence, ctx->imageInfo.LastMediaSequence);
|
TRACE("Setting media sequence as %d of %d", ctx->imageInfo.MediaSequence, ctx->imageInfo.LastMediaSequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.creatorLength > 0 &&
|
if(ctx->metadataBlockHeader.creatorLength > 0 &&
|
||||||
@@ -97,11 +109,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.Creator = (uint8_t *)malloc(ctx->metadataBlockHeader.creatorLength);
|
ctx->imageInfo.Creator = (uint8_t *)malloc(ctx->metadataBlockHeader.creatorLength);
|
||||||
if(ctx->imageInfo.Creator != NULL)
|
if(ctx->imageInfo.Creator != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.Creator, ctx->metadataBlock + ctx->metadataBlockHeader.creatorOffset,
|
memcpy(ctx->imageInfo.Creator, ctx->metadataBlock + ctx->metadataBlockHeader.creatorOffset,
|
||||||
ctx->metadataBlockHeader.creatorLength);
|
ctx->metadataBlockHeader.creatorLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.commentsLength > 0 &&
|
if(ctx->metadataBlockHeader.commentsLength > 0 &&
|
||||||
ctx->metadataBlockHeader.commentsOffset + ctx->metadataBlockHeader.commentsLength <=
|
ctx->metadataBlockHeader.commentsOffset + ctx->metadataBlockHeader.commentsLength <=
|
||||||
@@ -109,11 +119,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.Comments = (uint8_t *)malloc(ctx->metadataBlockHeader.commentsLength);
|
ctx->imageInfo.Comments = (uint8_t *)malloc(ctx->metadataBlockHeader.commentsLength);
|
||||||
if(ctx->imageInfo.Comments != NULL)
|
if(ctx->imageInfo.Comments != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.Comments, ctx->metadataBlock + ctx->metadataBlockHeader.commentsOffset,
|
memcpy(ctx->imageInfo.Comments, ctx->metadataBlock + ctx->metadataBlockHeader.commentsOffset,
|
||||||
ctx->metadataBlockHeader.commentsLength);
|
ctx->metadataBlockHeader.commentsLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.mediaTitleLength > 0 &&
|
if(ctx->metadataBlockHeader.mediaTitleLength > 0 &&
|
||||||
ctx->metadataBlockHeader.mediaTitleOffset + ctx->metadataBlockHeader.mediaTitleLength <=
|
ctx->metadataBlockHeader.mediaTitleOffset + ctx->metadataBlockHeader.mediaTitleLength <=
|
||||||
@@ -121,11 +129,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.MediaTitle = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaTitleLength);
|
ctx->imageInfo.MediaTitle = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaTitleLength);
|
||||||
if(ctx->imageInfo.MediaTitle != NULL)
|
if(ctx->imageInfo.MediaTitle != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.MediaTitle, ctx->metadataBlock + ctx->metadataBlockHeader.mediaTitleOffset,
|
memcpy(ctx->imageInfo.MediaTitle, ctx->metadataBlock + ctx->metadataBlockHeader.mediaTitleOffset,
|
||||||
ctx->metadataBlockHeader.mediaTitleLength);
|
ctx->metadataBlockHeader.mediaTitleLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.mediaManufacturerLength > 0 &&
|
if(ctx->metadataBlockHeader.mediaManufacturerLength > 0 &&
|
||||||
ctx->metadataBlockHeader.mediaManufacturerOffset + ctx->metadataBlockHeader.mediaManufacturerLength <=
|
ctx->metadataBlockHeader.mediaManufacturerOffset + ctx->metadataBlockHeader.mediaManufacturerLength <=
|
||||||
@@ -133,12 +139,10 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.MediaManufacturer = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaManufacturerLength);
|
ctx->imageInfo.MediaManufacturer = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaManufacturerLength);
|
||||||
if(ctx->imageInfo.MediaManufacturer != NULL)
|
if(ctx->imageInfo.MediaManufacturer != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.MediaManufacturer,
|
memcpy(ctx->imageInfo.MediaManufacturer,
|
||||||
ctx->metadataBlock + ctx->metadataBlockHeader.mediaManufacturerOffset,
|
ctx->metadataBlock + ctx->metadataBlockHeader.mediaManufacturerOffset,
|
||||||
ctx->metadataBlockHeader.mediaManufacturerLength);
|
ctx->metadataBlockHeader.mediaManufacturerLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.mediaModelLength > 0 &&
|
if(ctx->metadataBlockHeader.mediaModelLength > 0 &&
|
||||||
ctx->metadataBlockHeader.mediaModelOffset + ctx->metadataBlockHeader.mediaModelLength <=
|
ctx->metadataBlockHeader.mediaModelOffset + ctx->metadataBlockHeader.mediaModelLength <=
|
||||||
@@ -146,11 +150,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.MediaModel = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaModelOffset);
|
ctx->imageInfo.MediaModel = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaModelOffset);
|
||||||
if(ctx->imageInfo.MediaModel != NULL)
|
if(ctx->imageInfo.MediaModel != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.MediaModel, ctx->metadataBlock + ctx->metadataBlockHeader.mediaModelOffset,
|
memcpy(ctx->imageInfo.MediaModel, ctx->metadataBlock + ctx->metadataBlockHeader.mediaModelOffset,
|
||||||
ctx->metadataBlockHeader.mediaModelLength);
|
ctx->metadataBlockHeader.mediaModelLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.mediaSerialNumberLength > 0 &&
|
if(ctx->metadataBlockHeader.mediaSerialNumberLength > 0 &&
|
||||||
ctx->metadataBlockHeader.mediaSerialNumberOffset + ctx->metadataBlockHeader.mediaSerialNumberLength <=
|
ctx->metadataBlockHeader.mediaSerialNumberOffset + ctx->metadataBlockHeader.mediaSerialNumberLength <=
|
||||||
@@ -158,12 +160,10 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.MediaSerialNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaSerialNumberLength);
|
ctx->imageInfo.MediaSerialNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaSerialNumberLength);
|
||||||
if(ctx->imageInfo.MediaSerialNumber != NULL)
|
if(ctx->imageInfo.MediaSerialNumber != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.MediaSerialNumber,
|
memcpy(ctx->imageInfo.MediaSerialNumber,
|
||||||
ctx->metadataBlock + ctx->metadataBlockHeader.mediaSerialNumberOffset,
|
ctx->metadataBlock + ctx->metadataBlockHeader.mediaSerialNumberOffset,
|
||||||
ctx->metadataBlockHeader.mediaManufacturerLength);
|
ctx->metadataBlockHeader.mediaManufacturerLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.mediaBarcodeLength > 0 &&
|
if(ctx->metadataBlockHeader.mediaBarcodeLength > 0 &&
|
||||||
ctx->metadataBlockHeader.mediaBarcodeOffset + ctx->metadataBlockHeader.mediaBarcodeLength <=
|
ctx->metadataBlockHeader.mediaBarcodeOffset + ctx->metadataBlockHeader.mediaBarcodeLength <=
|
||||||
@@ -171,11 +171,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.MediaBarcode = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaBarcodeLength);
|
ctx->imageInfo.MediaBarcode = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaBarcodeLength);
|
||||||
if(ctx->imageInfo.MediaBarcode != NULL)
|
if(ctx->imageInfo.MediaBarcode != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.MediaBarcode, ctx->metadataBlock + ctx->metadataBlockHeader.mediaBarcodeOffset,
|
memcpy(ctx->imageInfo.MediaBarcode, ctx->metadataBlock + ctx->metadataBlockHeader.mediaBarcodeOffset,
|
||||||
ctx->metadataBlockHeader.mediaBarcodeLength);
|
ctx->metadataBlockHeader.mediaBarcodeLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.mediaPartNumberLength > 0 &&
|
if(ctx->metadataBlockHeader.mediaPartNumberLength > 0 &&
|
||||||
ctx->metadataBlockHeader.mediaPartNumberOffset + ctx->metadataBlockHeader.mediaPartNumberLength <=
|
ctx->metadataBlockHeader.mediaPartNumberOffset + ctx->metadataBlockHeader.mediaPartNumberLength <=
|
||||||
@@ -183,11 +181,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.MediaPartNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaPartNumberLength);
|
ctx->imageInfo.MediaPartNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaPartNumberLength);
|
||||||
if(ctx->imageInfo.MediaPartNumber != NULL)
|
if(ctx->imageInfo.MediaPartNumber != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.MediaPartNumber, ctx->metadataBlock + ctx->metadataBlockHeader.mediaPartNumberOffset,
|
memcpy(ctx->imageInfo.MediaPartNumber, ctx->metadataBlock + ctx->metadataBlockHeader.mediaPartNumberOffset,
|
||||||
ctx->metadataBlockHeader.mediaPartNumberLength);
|
ctx->metadataBlockHeader.mediaPartNumberLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.driveManufacturerLength > 0 &&
|
if(ctx->metadataBlockHeader.driveManufacturerLength > 0 &&
|
||||||
ctx->metadataBlockHeader.driveManufacturerOffset + ctx->metadataBlockHeader.driveManufacturerLength <=
|
ctx->metadataBlockHeader.driveManufacturerOffset + ctx->metadataBlockHeader.driveManufacturerLength <=
|
||||||
@@ -195,12 +191,10 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.DriveManufacturer = (uint8_t *)malloc(ctx->metadataBlockHeader.driveManufacturerLength);
|
ctx->imageInfo.DriveManufacturer = (uint8_t *)malloc(ctx->metadataBlockHeader.driveManufacturerLength);
|
||||||
if(ctx->imageInfo.DriveManufacturer != NULL)
|
if(ctx->imageInfo.DriveManufacturer != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.DriveManufacturer,
|
memcpy(ctx->imageInfo.DriveManufacturer,
|
||||||
ctx->metadataBlock + ctx->metadataBlockHeader.driveManufacturerOffset,
|
ctx->metadataBlock + ctx->metadataBlockHeader.driveManufacturerOffset,
|
||||||
ctx->metadataBlockHeader.driveManufacturerLength);
|
ctx->metadataBlockHeader.driveManufacturerLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.driveModelLength > 0 &&
|
if(ctx->metadataBlockHeader.driveModelLength > 0 &&
|
||||||
ctx->metadataBlockHeader.driveModelOffset + ctx->metadataBlockHeader.driveModelLength <=
|
ctx->metadataBlockHeader.driveModelOffset + ctx->metadataBlockHeader.driveModelLength <=
|
||||||
@@ -208,11 +202,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.DriveModel = (uint8_t *)malloc(ctx->metadataBlockHeader.driveModelLength);
|
ctx->imageInfo.DriveModel = (uint8_t *)malloc(ctx->metadataBlockHeader.driveModelLength);
|
||||||
if(ctx->imageInfo.DriveModel != NULL)
|
if(ctx->imageInfo.DriveModel != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.DriveModel, ctx->metadataBlock + ctx->metadataBlockHeader.driveModelOffset,
|
memcpy(ctx->imageInfo.DriveModel, ctx->metadataBlock + ctx->metadataBlockHeader.driveModelOffset,
|
||||||
ctx->metadataBlockHeader.driveModelLength);
|
ctx->metadataBlockHeader.driveModelLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.driveSerialNumberLength > 0 &&
|
if(ctx->metadataBlockHeader.driveSerialNumberLength > 0 &&
|
||||||
ctx->metadataBlockHeader.driveSerialNumberOffset + ctx->metadataBlockHeader.driveSerialNumberLength <=
|
ctx->metadataBlockHeader.driveSerialNumberOffset + ctx->metadataBlockHeader.driveSerialNumberLength <=
|
||||||
@@ -220,12 +212,10 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.DriveSerialNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.driveSerialNumberLength);
|
ctx->imageInfo.DriveSerialNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.driveSerialNumberLength);
|
||||||
if(ctx->imageInfo.DriveSerialNumber != NULL)
|
if(ctx->imageInfo.DriveSerialNumber != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.DriveSerialNumber,
|
memcpy(ctx->imageInfo.DriveSerialNumber,
|
||||||
ctx->metadataBlock + ctx->metadataBlockHeader.driveSerialNumberOffset,
|
ctx->metadataBlock + ctx->metadataBlockHeader.driveSerialNumberOffset,
|
||||||
ctx->metadataBlockHeader.driveSerialNumberLength);
|
ctx->metadataBlockHeader.driveSerialNumberLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->metadataBlockHeader.driveManufacturerLength > 0 &&
|
if(ctx->metadataBlockHeader.driveManufacturerLength > 0 &&
|
||||||
ctx->metadataBlockHeader.driveFirmwareRevisionOffset + ctx->metadataBlockHeader.driveManufacturerLength <=
|
ctx->metadataBlockHeader.driveFirmwareRevisionOffset + ctx->metadataBlockHeader.driveManufacturerLength <=
|
||||||
@@ -233,96 +223,109 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
{
|
{
|
||||||
ctx->imageInfo.DriveFirmwareRevision = (uint8_t *)malloc(ctx->metadataBlockHeader.driveFirmwareRevisionLength);
|
ctx->imageInfo.DriveFirmwareRevision = (uint8_t *)malloc(ctx->metadataBlockHeader.driveFirmwareRevisionLength);
|
||||||
if(ctx->imageInfo.DriveFirmwareRevision != NULL)
|
if(ctx->imageInfo.DriveFirmwareRevision != NULL)
|
||||||
{
|
|
||||||
memcpy(ctx->imageInfo.DriveFirmwareRevision,
|
memcpy(ctx->imageInfo.DriveFirmwareRevision,
|
||||||
ctx->metadataBlock + ctx->metadataBlockHeader.driveFirmwareRevisionLength,
|
ctx->metadataBlock + ctx->metadataBlockHeader.driveFirmwareRevisionLength,
|
||||||
ctx->metadataBlockHeader.driveFirmwareRevisionLength);
|
ctx->metadataBlockHeader.driveFirmwareRevisionLength);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
TRACE("Exiting process_metadata_block()");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logical geometry block. It doesn't have a CRC coz, well, it's not so important
|
// Logical geometry block. It doesn't have a CRC coz, well, it's not so important
|
||||||
void process_geometry_block(aaruformatContext *ctx, const IndexEntry *entry)
|
void process_geometry_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_geometry_block(%p, %p)", ctx, entry);
|
||||||
size_t readBytes = 0;
|
size_t readBytes = 0;
|
||||||
|
|
||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
FATAL("Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting process_geometry_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek to block
|
// Seek to block
|
||||||
if(fseek(ctx->imageStream, entry->offset, SEEK_SET) != 0)
|
if(fseek(ctx->imageStream, entry->offset, SEEK_SET) != 0)
|
||||||
{
|
{
|
||||||
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...\n", entry->offset);
|
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_geometry_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Reading geometry block header at position %" PRIu64, entry->offset);
|
||||||
readBytes = fread(&ctx->geometryBlock, 1, sizeof(GeometryBlockHeader), ctx->imageStream);
|
readBytes = fread(&ctx->geometryBlock, 1, sizeof(GeometryBlockHeader), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(GeometryBlockHeader))
|
if(readBytes != sizeof(GeometryBlockHeader))
|
||||||
{
|
{
|
||||||
memset(&ctx->geometryBlock, 0, sizeof(GeometryBlockHeader));
|
memset(&ctx->geometryBlock, 0, sizeof(GeometryBlockHeader));
|
||||||
TRACE("Could not read geometry block header, continuing...\n");
|
TRACE("Could not read geometry block header, continuing...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->geometryBlock.identifier != GeometryBlock)
|
if(ctx->geometryBlock.identifier != GeometryBlock)
|
||||||
{
|
{
|
||||||
memset(&ctx->geometryBlock, 0, sizeof(GeometryBlockHeader));
|
memset(&ctx->geometryBlock, 0, sizeof(GeometryBlockHeader));
|
||||||
TRACE("Incorrect identifier for geometry block at position %" PRIu64 "\n", entry->offset);
|
TRACE("Incorrect identifier for geometry block at position %" PRIu64 "", entry->offset);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->imageInfo.ImageSize += sizeof(GeometryBlockHeader);
|
ctx->imageInfo.ImageSize += sizeof(GeometryBlockHeader);
|
||||||
|
|
||||||
TRACE("Geometry set to %d cylinders %d heads %d sectors per track\n", ctx->geometryBlock.cylinders,
|
TRACE("Geometry set to %d cylinders %d heads %d sectors per track", ctx->geometryBlock.cylinders,
|
||||||
ctx->geometryBlock.heads, ctx->geometryBlock.sectorsPerTrack);
|
ctx->geometryBlock.heads, ctx->geometryBlock.sectorsPerTrack);
|
||||||
|
|
||||||
ctx->imageInfo.Cylinders = ctx->geometryBlock.cylinders;
|
ctx->imageInfo.Cylinders = ctx->geometryBlock.cylinders;
|
||||||
ctx->imageInfo.Heads = ctx->geometryBlock.heads;
|
ctx->imageInfo.Heads = ctx->geometryBlock.heads;
|
||||||
ctx->imageInfo.SectorsPerTrack = ctx->geometryBlock.sectorsPerTrack;
|
ctx->imageInfo.SectorsPerTrack = ctx->geometryBlock.sectorsPerTrack;
|
||||||
|
|
||||||
|
TRACE("Exiting process_geometry_block()");
|
||||||
}
|
}
|
||||||
|
|
||||||
// CICM XML metadata block
|
// CICM XML metadata block
|
||||||
void process_cicm_block(aaruformatContext *ctx, const IndexEntry *entry)
|
void process_cicm_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_cicm_block(%p, %p)", ctx, entry);
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
size_t readBytes = 0;
|
size_t readBytes = 0;
|
||||||
|
|
||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
FATAL("Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting process_cicm_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek to block
|
// Seek to block
|
||||||
|
TRACE("Seeking to CICM XML metadata block at position %" PRIu64, entry->offset);
|
||||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||||
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
||||||
{
|
{
|
||||||
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...\n", entry->offset);
|
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_cicm_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even if those two checks shall have been done before
|
// Even if those two checks shall have been done before
|
||||||
|
TRACE("Reading CICM XML metadata block header at position %" PRIu64, entry->offset);
|
||||||
readBytes = fread(&ctx->cicmBlockHeader, 1, sizeof(CicmMetadataBlock), ctx->imageStream);
|
readBytes = fread(&ctx->cicmBlockHeader, 1, sizeof(CicmMetadataBlock), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(CicmMetadataBlock))
|
if(readBytes != sizeof(CicmMetadataBlock))
|
||||||
{
|
{
|
||||||
memset(&ctx->cicmBlockHeader, 0, sizeof(CicmMetadataBlock));
|
memset(&ctx->cicmBlockHeader, 0, sizeof(CicmMetadataBlock));
|
||||||
TRACE("Could not read CICM XML metadata header, continuing...\n");
|
TRACE("Could not read CICM XML metadata header, continuing...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->cicmBlockHeader.identifier != CicmBlock)
|
if(ctx->cicmBlockHeader.identifier != CicmBlock)
|
||||||
{
|
{
|
||||||
memset(&ctx->cicmBlockHeader, 0, sizeof(CicmMetadataBlock));
|
memset(&ctx->cicmBlockHeader, 0, sizeof(CicmMetadataBlock));
|
||||||
TRACE("Incorrect identifier for data block at position %" PRIu64 "\n", entry->offset);
|
TRACE("Incorrect identifier for data block at position %" PRIu64 "", entry->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->imageInfo.ImageSize += ctx->cicmBlockHeader.length;
|
ctx->imageInfo.ImageSize += ctx->cicmBlockHeader.length;
|
||||||
@@ -332,18 +335,24 @@ void process_cicm_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
if(ctx->cicmBlock == NULL)
|
if(ctx->cicmBlock == NULL)
|
||||||
{
|
{
|
||||||
memset(&ctx->cicmBlockHeader, 0, sizeof(CicmMetadataBlock));
|
memset(&ctx->cicmBlockHeader, 0, sizeof(CicmMetadataBlock));
|
||||||
TRACE("Could not allocate memory for CICM XML metadata block, continuing...\n");
|
TRACE("Could not allocate memory for CICM XML metadata block, continuing...");
|
||||||
|
|
||||||
|
TRACE("Exiting process_cicm_block()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Reading CICM XML metadata block of size %u at position %" PRIu64, ctx->cicmBlockHeader.length,
|
||||||
|
entry->offset + sizeof(CicmMetadataBlock));
|
||||||
readBytes = fread(ctx->cicmBlock, 1, ctx->cicmBlockHeader.length, ctx->imageStream);
|
readBytes = fread(ctx->cicmBlock, 1, ctx->cicmBlockHeader.length, ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != ctx->metadataBlockHeader.blockSize)
|
if(readBytes != ctx->metadataBlockHeader.blockSize)
|
||||||
{
|
{
|
||||||
memset(&ctx->cicmBlockHeader, 0, sizeof(CicmMetadataBlock));
|
memset(&ctx->cicmBlockHeader, 0, sizeof(CicmMetadataBlock));
|
||||||
free(ctx->cicmBlock);
|
free(ctx->cicmBlock);
|
||||||
TRACE("Could not read CICM XML metadata block, continuing...\n");
|
TRACE("Could not read CICM XML metadata block, continuing...");
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Found CICM XML metadata block %" PRIu64 ".\n", entry->offset);
|
TRACE("Found CICM XML metadata block %" PRIu64 ".", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_cicm_block()");
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ void process_tracks_block(aaruformatContext *ctx, const IndexEntry *entry)
|
|||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
FATAL("Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,16 +23,20 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "aaruformat.h"
|
#include "aaruformat.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
void *aaruf_ecc_cd_init()
|
void *aaruf_ecc_cd_init()
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_ecc_cd_init()");
|
||||||
CdEccContext *context = NULL;
|
CdEccContext *context = NULL;
|
||||||
uint32_t edc = 0, i = 0, j = 0;
|
uint32_t edc = 0, i = 0, j = 0;
|
||||||
|
|
||||||
|
TRACE("Creating context");
|
||||||
context = (CdEccContext *)malloc(sizeof(CdEccContext));
|
context = (CdEccContext *)malloc(sizeof(CdEccContext));
|
||||||
|
|
||||||
if(context == NULL) return NULL;
|
if(context == NULL) return NULL;
|
||||||
|
|
||||||
|
TRACE("Allocating memory for ECC F table");
|
||||||
context->eccFTable = (uint8_t *)malloc(sizeof(uint8_t) * 256);
|
context->eccFTable = (uint8_t *)malloc(sizeof(uint8_t) * 256);
|
||||||
|
|
||||||
if(context->eccFTable == NULL)
|
if(context->eccFTable == NULL)
|
||||||
@@ -41,6 +45,7 @@ void *aaruf_ecc_cd_init()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Allocating memory for ECC B table");
|
||||||
context->eccBTable = (uint8_t *)malloc(sizeof(uint8_t) * 256);
|
context->eccBTable = (uint8_t *)malloc(sizeof(uint8_t) * 256);
|
||||||
|
|
||||||
if(context->eccBTable == NULL)
|
if(context->eccBTable == NULL)
|
||||||
@@ -49,6 +54,9 @@ void *aaruf_ecc_cd_init()
|
|||||||
free(context);
|
free(context);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Allocating memory for EDC table");
|
||||||
|
|
||||||
context->edcTable = (uint32_t *)malloc(sizeof(uint32_t) * 256);
|
context->edcTable = (uint32_t *)malloc(sizeof(uint32_t) * 256);
|
||||||
|
|
||||||
if(context->edcTable == NULL)
|
if(context->edcTable == NULL)
|
||||||
@@ -59,6 +67,7 @@ void *aaruf_ecc_cd_init()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Initializing EDC tables");
|
||||||
for(i = 0; i < 256; i++)
|
for(i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
edc = i;
|
edc = i;
|
||||||
@@ -71,32 +80,52 @@ void *aaruf_ecc_cd_init()
|
|||||||
|
|
||||||
context->initedEdc = true;
|
context->initedEdc = true;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_init()");
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool aaruf_ecc_cd_is_suffix_correct(void *context, const uint8_t *sector)
|
bool aaruf_ecc_cd_is_suffix_correct(void *context, const uint8_t *sector)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_ecc_cd_is_suffix_correct(%p, %p)", context, sector);
|
||||||
CdEccContext *ctx;
|
CdEccContext *ctx;
|
||||||
uint32_t storedEdc, edc, calculatedEdc;
|
uint32_t storedEdc, edc, calculatedEdc;
|
||||||
int size, pos;
|
int size, pos;
|
||||||
|
|
||||||
if(context == NULL || sector == NULL) return false;
|
if(context == NULL || sector == NULL)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct() without initialized context");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = (CdEccContext *)context;
|
ctx = (CdEccContext *)context;
|
||||||
|
if(!ctx->initedEdc)
|
||||||
if(!ctx->initedEdc) return false;
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct() without initialized context");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(sector[0x814] != 0x00 ||
|
if(sector[0x814] != 0x00 ||
|
||||||
// reserved (8 bytes)
|
// reserved (8 bytes)
|
||||||
sector[0x815] != 0x00 || sector[0x816] != 0x00 || sector[0x817] != 0x00 || sector[0x818] != 0x00 ||
|
sector[0x815] != 0x00 || sector[0x816] != 0x00 || sector[0x817] != 0x00 || sector[0x818] != 0x00 ||
|
||||||
sector[0x819] != 0x00 || sector[0x81A] != 0x00 || sector[0x81B] != 0x00)
|
sector[0x819] != 0x00 || sector[0x81A] != 0x00 || sector[0x81B] != 0x00)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct() = false");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool correctEccP = aaruf_ecc_cd_check(context, sector, sector, 86, 24, 2, 86, sector, 0xC, 0x10, 0x81C);
|
bool correctEccP = aaruf_ecc_cd_check(context, sector, sector, 86, 24, 2, 86, sector, 0xC, 0x10, 0x81C);
|
||||||
if(!correctEccP) return false;
|
if(!correctEccP)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct() = false");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool correctEccQ = aaruf_ecc_cd_check(context, sector, sector, 52, 43, 86, 88, sector, 0xC, 0x10, 0x81C + 0xAC);
|
bool correctEccQ = aaruf_ecc_cd_check(context, sector, sector, 52, 43, 86, 88, sector, 0xC, 0x10, 0x81C + 0xAC);
|
||||||
if(!correctEccQ) return false;
|
if(!correctEccQ)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct() = false");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
storedEdc = (sector[0x813] << 24) + (sector[0x812] << 16) + (sector[0x811] << 8) + sector[0x810];
|
storedEdc = (sector[0x813] << 24) + (sector[0x812] << 16) + (sector[0x811] << 8) + sector[0x810];
|
||||||
edc = 0;
|
edc = 0;
|
||||||
@@ -105,30 +134,46 @@ bool aaruf_ecc_cd_is_suffix_correct(void *context, const uint8_t *sector)
|
|||||||
for(; size > 0; size--) edc = (edc >> 8) ^ ctx->edcTable[(edc ^ sector[pos++]) & 0xFF];
|
for(; size > 0; size--) edc = (edc >> 8) ^ ctx->edcTable[(edc ^ sector[pos++]) & 0xFF];
|
||||||
calculatedEdc = edc;
|
calculatedEdc = edc;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct() = %u == %u", calculatedEdc, storedEdc);
|
||||||
return calculatedEdc == storedEdc;
|
return calculatedEdc == storedEdc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool aaruf_ecc_cd_is_suffix_correct_mode2(void *context, const uint8_t *sector)
|
bool aaruf_ecc_cd_is_suffix_correct_mode2(void *context, const uint8_t *sector)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_ecc_cd_is_suffix_correct_mode2(%p, %p)", context, sector);
|
||||||
CdEccContext *ctx;
|
CdEccContext *ctx;
|
||||||
uint32_t storedEdc, edc, calculatedEdc;
|
uint32_t storedEdc, edc, calculatedEdc;
|
||||||
int size, pos;
|
int size, pos;
|
||||||
uint8_t zeroaddress[4];
|
uint8_t zeroaddress[4];
|
||||||
|
|
||||||
if(context == NULL || sector == NULL) return false;
|
if(context == NULL || sector == NULL)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct_mode2() without initialized context");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = (CdEccContext *)context;
|
ctx = (CdEccContext *)context;
|
||||||
|
|
||||||
if(!ctx->initedEdc) return false;
|
if(!ctx->initedEdc)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct_mode2() without initialized context");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&zeroaddress, 4, sizeof(uint8_t));
|
memset(&zeroaddress, 4, sizeof(uint8_t));
|
||||||
|
|
||||||
bool correctEccP = aaruf_ecc_cd_check(context, zeroaddress, sector, 86, 24, 2, 86, sector, 0, 0x10, 0x81C);
|
bool correctEccP = aaruf_ecc_cd_check(context, zeroaddress, sector, 86, 24, 2, 86, sector, 0, 0x10, 0x81C);
|
||||||
if(!correctEccP) return false;
|
if(!correctEccP)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct_mode2() = false");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool correctEccQ = aaruf_ecc_cd_check(context, zeroaddress, sector, 52, 43, 86, 88, sector, 0, 0x10, 0x81C + 0xAC);
|
bool correctEccQ = aaruf_ecc_cd_check(context, zeroaddress, sector, 52, 43, 86, 88, sector, 0, 0x10, 0x81C + 0xAC);
|
||||||
if(!correctEccQ) return false;
|
if(!correctEccQ)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct_mode2() = false");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
storedEdc = (sector[0x81B] << 24) + (sector[0x81A] << 16) + (sector[0x819] << 8) + sector[0x818];
|
storedEdc = (sector[0x81B] << 24) + (sector[0x81A] << 16) + (sector[0x819] << 8) + sector[0x818];
|
||||||
edc = 0;
|
edc = 0;
|
||||||
size = 0x808;
|
size = 0x808;
|
||||||
@@ -136,6 +181,7 @@ bool aaruf_ecc_cd_is_suffix_correct_mode2(void *context, const uint8_t *sector)
|
|||||||
for(; size > 0; size--) edc = (edc >> 8) ^ ctx->edcTable[(edc ^ sector[pos++]) & 0xFF];
|
for(; size > 0; size--) edc = (edc >> 8) ^ ctx->edcTable[(edc ^ sector[pos++]) & 0xFF];
|
||||||
calculatedEdc = edc;
|
calculatedEdc = edc;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct_mode2() = %u == %u", calculatedEdc, storedEdc);
|
||||||
return calculatedEdc == storedEdc;
|
return calculatedEdc == storedEdc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,15 +189,26 @@ bool aaruf_ecc_cd_check(void *context, const uint8_t *address, const uint8_t *da
|
|||||||
uint32_t minorCount, uint32_t majorMult, uint32_t minorInc, const uint8_t *ecc,
|
uint32_t minorCount, uint32_t majorMult, uint32_t minorInc, const uint8_t *ecc,
|
||||||
int32_t addressOffset, int32_t dataOffset, int32_t eccOffset)
|
int32_t addressOffset, int32_t dataOffset, int32_t eccOffset)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_ecc_cd_check(%p, %p, %p, %u, %u, %u, %u, %p, %d, %d, %d)", context, address, data, majorCount,
|
||||||
|
minorCount, majorMult, minorInc, ecc, addressOffset, dataOffset, eccOffset);
|
||||||
|
|
||||||
CdEccContext *ctx;
|
CdEccContext *ctx;
|
||||||
uint32_t size, major, idx, minor;
|
uint32_t size, major, idx, minor;
|
||||||
uint8_t eccA, eccB, temp;
|
uint8_t eccA, eccB, temp;
|
||||||
|
|
||||||
if(context == NULL || address == NULL || data == NULL || ecc == NULL) return false;
|
if(context == NULL || address == NULL || data == NULL || ecc == NULL)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_check() with missing data");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = (CdEccContext *)context;
|
ctx = (CdEccContext *)context;
|
||||||
|
|
||||||
if(!ctx->initedEdc) return false;
|
if(!ctx->initedEdc)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_check() without initialized context");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
size = majorCount * minorCount;
|
size = majorCount * minorCount;
|
||||||
for(major = 0; major < majorCount; major++)
|
for(major = 0; major < majorCount; major++)
|
||||||
@@ -170,9 +227,14 @@ bool aaruf_ecc_cd_check(void *context, const uint8_t *address, const uint8_t *da
|
|||||||
}
|
}
|
||||||
|
|
||||||
eccA = ctx->eccBTable[ctx->eccFTable[eccA] ^ eccB];
|
eccA = ctx->eccBTable[ctx->eccFTable[eccA] ^ eccB];
|
||||||
if(ecc[major + eccOffset] != eccA || ecc[major + majorCount + eccOffset] != (eccA ^ eccB)) return false;
|
if(ecc[major + eccOffset] != eccA || ecc[major + majorCount + eccOffset] != (eccA ^ eccB))
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_check() = false, ECC mismatch at major %u", major);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_check() = true, ECC matches");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,15 +242,26 @@ void aaruf_ecc_cd_write(void *context, const uint8_t *address, const uint8_t *da
|
|||||||
uint32_t minorCount, uint32_t majorMult, uint32_t minorInc, uint8_t *ecc, int32_t addressOffset,
|
uint32_t minorCount, uint32_t majorMult, uint32_t minorInc, uint8_t *ecc, int32_t addressOffset,
|
||||||
int32_t dataOffset, int32_t eccOffset)
|
int32_t dataOffset, int32_t eccOffset)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_ecc_cd_write(%p, %p, %p, %u, %u, %u, %u, %p, %d, %d, %d)", context, address, data, majorCount,
|
||||||
|
minorCount, majorMult, minorInc, ecc, addressOffset, dataOffset, eccOffset);
|
||||||
|
|
||||||
CdEccContext *ctx;
|
CdEccContext *ctx;
|
||||||
uint32_t size, major, idx, minor;
|
uint32_t size, major, idx, minor;
|
||||||
uint8_t eccA, eccB, temp;
|
uint8_t eccA, eccB, temp;
|
||||||
|
|
||||||
if(context == NULL || address == NULL || data == NULL || ecc == NULL) return;
|
if(context == NULL || address == NULL || data == NULL || ecc == NULL)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_write() with missing data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = (CdEccContext *)context;
|
ctx = (CdEccContext *)context;
|
||||||
|
|
||||||
if(!ctx->initedEdc) return;
|
if(!ctx->initedEdc)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_write() without initialized context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
size = majorCount * minorCount;
|
size = majorCount * minorCount;
|
||||||
for(major = 0; major < majorCount; major++)
|
for(major = 0; major < majorCount; major++)
|
||||||
@@ -211,25 +284,38 @@ void aaruf_ecc_cd_write(void *context, const uint8_t *address, const uint8_t *da
|
|||||||
ecc[major + eccOffset] = eccA;
|
ecc[major + eccOffset] = eccA;
|
||||||
ecc[major + majorCount + eccOffset] = (eccA ^ eccB);
|
ecc[major + majorCount + eccOffset] = (eccA ^ eccB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_write()");
|
||||||
}
|
}
|
||||||
|
|
||||||
void aaruf_ecc_cd_write_sector(void *context, const uint8_t *address, const uint8_t *data, uint8_t *ecc,
|
void aaruf_ecc_cd_write_sector(void *context, const uint8_t *address, const uint8_t *data, uint8_t *ecc,
|
||||||
int32_t addressOffset, int32_t dataOffset, int32_t eccOffset)
|
int32_t addressOffset, int32_t dataOffset, int32_t eccOffset)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_ecc_cd_write_sector(%p, %p, %p, %p, %d, %d, %d)", context, address, data, ecc, addressOffset,
|
||||||
|
dataOffset, eccOffset);
|
||||||
|
|
||||||
aaruf_ecc_cd_write(context, address, data, 86, 24, 2, 86, ecc, addressOffset, dataOffset, eccOffset); // P
|
aaruf_ecc_cd_write(context, address, data, 86, 24, 2, 86, ecc, addressOffset, dataOffset, eccOffset); // P
|
||||||
aaruf_ecc_cd_write(context, address, data, 52, 43, 86, 88, ecc, addressOffset, dataOffset, eccOffset + 0xAC); // Q
|
aaruf_ecc_cd_write(context, address, data, 52, 43, 86, 88, ecc, addressOffset, dataOffset, eccOffset + 0xAC); // Q
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_write_sector()");
|
||||||
}
|
}
|
||||||
|
|
||||||
void aaruf_cd_lba_to_msf(int64_t pos, uint8_t *minute, uint8_t *second, uint8_t *frame)
|
void aaruf_cd_lba_to_msf(int64_t pos, uint8_t *minute, uint8_t *second, uint8_t *frame)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_cd_lba_to_msf(%lld, %p, %p, %p)", pos, minute, second, frame);
|
||||||
|
|
||||||
*minute = (uint8_t)((pos + 150) / 75 / 60);
|
*minute = (uint8_t)((pos + 150) / 75 / 60);
|
||||||
*second = (uint8_t)((pos + 150) / 75 % 60);
|
*second = (uint8_t)((pos + 150) / 75 % 60);
|
||||||
*frame = (uint8_t)((pos + 150) % 75);
|
*frame = (uint8_t)((pos + 150) % 75);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_cd_lba_to_msf() = %u:%u:%u", *minute, *second, *frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void aaruf_ecc_cd_reconstruct_prefix(uint8_t *sector, // must point to a full 2352-byte sector
|
void aaruf_ecc_cd_reconstruct_prefix(uint8_t *sector, // must point to a full 2352-byte sector
|
||||||
uint8_t type, int64_t lba)
|
uint8_t type, int64_t lba)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_ecc_cd_reconstruct_prefix(%p, %u, %lld)", sector, type, lba);
|
||||||
|
|
||||||
uint8_t minute, second, frame;
|
uint8_t minute, second, frame;
|
||||||
|
|
||||||
if(sector == NULL) return;
|
if(sector == NULL) return;
|
||||||
@@ -282,22 +368,34 @@ void aaruf_ecc_cd_reconstruct_prefix(uint8_t *sector, // must point to a full 2
|
|||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_reconstruct_prefix()");
|
||||||
}
|
}
|
||||||
|
|
||||||
void aaruf_ecc_cd_reconstruct(void *context,
|
void aaruf_ecc_cd_reconstruct(void *context,
|
||||||
uint8_t *sector, // must point to a full 2352-byte sector
|
uint8_t *sector, // must point to a full 2352-byte sector
|
||||||
uint8_t type)
|
uint8_t type)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_ecc_cd_reconstruct(%p, %p, %u)", context, sector, type);
|
||||||
|
|
||||||
uint32_t computedEdc;
|
uint32_t computedEdc;
|
||||||
uint8_t zeroaddress[4];
|
uint8_t zeroaddress[4];
|
||||||
|
|
||||||
CdEccContext *ctx;
|
CdEccContext *ctx;
|
||||||
|
|
||||||
if(context == NULL || sector == NULL) return;
|
if(context == NULL || sector == NULL)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_reconstruct() with missing data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = (CdEccContext *)context;
|
ctx = (CdEccContext *)context;
|
||||||
|
|
||||||
if(!ctx->initedEdc) return;
|
if(!ctx->initedEdc)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_reconstruct() without initialized context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
@@ -317,6 +415,7 @@ void aaruf_ecc_cd_reconstruct(void *context,
|
|||||||
memcpy(sector + 0x92C, &computedEdc, 4);
|
memcpy(sector + 0x92C, &computedEdc, 4);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_reconstruct() with unknown type %u", type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,25 +444,38 @@ void aaruf_ecc_cd_reconstruct(void *context,
|
|||||||
aaruf_ecc_cd_write_sector(context, zeroaddress, sector, sector, 0, 0x10, 0x81C);
|
aaruf_ecc_cd_write_sector(context, zeroaddress, sector, sector, 0, 0x10, 0x81C);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_reconstruct() with unknown type %u", type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Done
|
// Done
|
||||||
//
|
//
|
||||||
|
TRACE("Exiting aaruf_ecc_cd_reconstruct()");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t aaruf_edc_cd_compute(void *context, uint32_t edc, const uint8_t *src, int size, int pos)
|
uint32_t aaruf_edc_cd_compute(void *context, uint32_t edc, const uint8_t *src, int size, int pos)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_edc_cd_compute(%p, %u, %p, %d, %d)", context, edc, src, size, pos);
|
||||||
|
|
||||||
CdEccContext *ctx;
|
CdEccContext *ctx;
|
||||||
|
|
||||||
if(context == NULL || src == NULL) return 0;
|
if(context == NULL || src == NULL)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_edc_cd_compute() with missing data");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = (CdEccContext *)context;
|
ctx = (CdEccContext *)context;
|
||||||
|
|
||||||
if(!ctx->initedEdc) return 0;
|
if(!ctx->initedEdc)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_edc_cd_compute() without initialized context");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for(; size > 0; size--) edc = (edc >> 8) ^ ctx->edcTable[(edc ^ src[pos++]) & 0xFF];
|
for(; size > 0; size--) edc = (edc >> 8) ^ ctx->edcTable[(edc ^ src[pos++]) & 0xFF];
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_edc_cd_compute() = 0x%08X", edc);
|
||||||
return edc;
|
return edc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "aaruformat.h"
|
#include "aaruformat.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__amd64) || defined(_M_AMD64) || defined(_M_X64) || defined(__I386__) || \
|
#if defined(__x86_64__) || defined(__amd64) || defined(_M_AMD64) || defined(_M_X64) || defined(__I386__) || \
|
||||||
defined(__i386__) || defined(__THW_INTEL) || defined(_M_IX86)
|
defined(__i386__) || defined(__THW_INTEL) || defined(_M_IX86)
|
||||||
@@ -37,6 +38,8 @@
|
|||||||
|
|
||||||
static void cpuid(int info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
|
static void cpuid(int info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering cpuid(%d, %d, %d, %d, %d)", info, *eax, *ebx, *ecx, *edx);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
unsigned int registers[4];
|
unsigned int registers[4];
|
||||||
__cpuid(registers, info);
|
__cpuid(registers, info);
|
||||||
@@ -56,10 +59,14 @@ static void cpuid(int info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigne
|
|||||||
*ecx = _ecx;
|
*ecx = _ecx;
|
||||||
*edx = _edx;
|
*edx = _edx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TRACE("Exiting cpuid(%d, %d, %d, %d, %d)", info, *eax, *ebx, *ecx, *edx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpuidex(int info, int count, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
|
static void cpuidex(int info, int count, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering cpuidex(%d, %d, %d, %d, %d, %d)", info, count, *eax, *ebx, *ecx, *edx);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
unsigned int registers[4];
|
unsigned int registers[4];
|
||||||
__cpuidex(registers, info, count);
|
__cpuidex(registers, info, count);
|
||||||
@@ -79,10 +86,14 @@ static void cpuidex(int info, int count, unsigned *eax, unsigned *ebx, unsigned
|
|||||||
*ecx = _ecx;
|
*ecx = _ecx;
|
||||||
*edx = _edx;
|
*edx = _edx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TRACE("Exiting cpuidex(%d, %d, %d, %d, %d, %d)", info, count, *eax, *ebx, *ecx, *edx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int have_clmul()
|
int have_clmul()
|
||||||
{
|
{
|
||||||
|
TRACE("Entering have_clmul()");
|
||||||
|
|
||||||
unsigned eax, ebx, ecx, edx;
|
unsigned eax, ebx, ecx, edx;
|
||||||
int has_pclmulqdq;
|
int has_pclmulqdq;
|
||||||
int has_sse41;
|
int has_sse41;
|
||||||
@@ -91,22 +102,27 @@ int have_clmul()
|
|||||||
has_pclmulqdq = ecx & 0x2; /* bit 1 */
|
has_pclmulqdq = ecx & 0x2; /* bit 1 */
|
||||||
has_sse41 = ecx & 0x80000; /* bit 19 */
|
has_sse41 = ecx & 0x80000; /* bit 19 */
|
||||||
|
|
||||||
|
TRACE("Exiting have_clmul() = %d", has_pclmulqdq && has_sse41);
|
||||||
return has_pclmulqdq && has_sse41;
|
return has_pclmulqdq && has_sse41;
|
||||||
}
|
}
|
||||||
|
|
||||||
int have_ssse3()
|
int have_ssse3()
|
||||||
{
|
{
|
||||||
|
TRACE("Entering have_ssse3()");
|
||||||
unsigned eax, ebx, ecx, edx;
|
unsigned eax, ebx, ecx, edx;
|
||||||
cpuid(1 /* feature bits */, &eax, &ebx, &ecx, &edx);
|
cpuid(1 /* feature bits */, &eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
TRACE("Exiting have_ssse3() = %d", ecx & 0x200);
|
||||||
return ecx & 0x200;
|
return ecx & 0x200;
|
||||||
}
|
}
|
||||||
|
|
||||||
int have_avx2()
|
int have_avx2()
|
||||||
{
|
{
|
||||||
|
TRACE("Entering have_avx2()");
|
||||||
unsigned eax, ebx, ecx, edx;
|
unsigned eax, ebx, ecx, edx;
|
||||||
cpuidex(7 /* extended feature bits */, 0, &eax, &ebx, &ecx, &edx);
|
cpuidex(7 /* extended feature bits */, 0, &eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
TRACE("Exiting have_avx2() = %d", ebx & 0x20);
|
||||||
return ebx & 0x20;
|
return ebx & 0x20;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -126,23 +142,35 @@ int have_avx2()
|
|||||||
#if (defined(__aarch64__) || defined(_M_ARM64) || defined(__arm__) || defined(_M_ARM)) && defined(__APPLE__)
|
#if (defined(__aarch64__) || defined(_M_ARM64) || defined(__arm__) || defined(_M_ARM)) && defined(__APPLE__)
|
||||||
int have_neon_apple()
|
int have_neon_apple()
|
||||||
{
|
{
|
||||||
|
TRACE("Entering have_neon_apple()");
|
||||||
int value = 0;
|
int value = 0;
|
||||||
size_t len = sizeof(int);
|
size_t len = sizeof(int);
|
||||||
int ret = sysctlbyname("hw.optional.neon", &value, &len, NULL, 0);
|
int ret = sysctlbyname("hw.optional.neon", &value, &len, NULL, 0);
|
||||||
|
|
||||||
if(ret != 0) return 0;
|
if(ret != 0)
|
||||||
|
{
|
||||||
|
TRACE("Exiting have_neon_apple() = 0");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting have_neon_apple() = %d", value == 1);
|
||||||
return value == 1;
|
return value == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int have_crc32_apple()
|
int have_crc32_apple()
|
||||||
{
|
{
|
||||||
|
TRACE("Entering have_crc32_apple()");
|
||||||
int value = 0;
|
int value = 0;
|
||||||
size_t len = sizeof(int);
|
size_t len = sizeof(int);
|
||||||
int ret = sysctlbyname("hw.optional.crc32", &value, &len, NULL, 0);
|
int ret = sysctlbyname("hw.optional.crc32", &value, &len, NULL, 0);
|
||||||
|
|
||||||
if(ret != 0) return 0;
|
if(ret != 0)
|
||||||
|
{
|
||||||
|
TRACE("Exiting have_crc32_apple() = 0");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting have_crc32_apple() = %d", value == 1);
|
||||||
return value == 1;
|
return value == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
20
src/close.c
20
src/close.c
@@ -27,15 +27,19 @@
|
|||||||
#include <aaruformat.h>
|
#include <aaruformat.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
int aaruf_close(void *context)
|
int aaruf_close(void *context)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_close(%p)", context);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
mediaTagEntry *mediaTag = NULL;
|
mediaTagEntry *mediaTag = NULL;
|
||||||
mediaTagEntry *tmpMediaTag = NULL;
|
mediaTagEntry *tmpMediaTag = NULL;
|
||||||
|
|
||||||
if(context == NULL)
|
if(context == NULL)
|
||||||
{
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -45,14 +49,20 @@ int aaruf_close(void *context)
|
|||||||
// Not a libaaruformat context
|
// Not a libaaruformat context
|
||||||
if(ctx->magic != AARU_MAGIC)
|
if(ctx->magic != AARU_MAGIC)
|
||||||
{
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->isWriting)
|
if(ctx->isWriting)
|
||||||
{
|
{
|
||||||
|
TRACE("File is writing");
|
||||||
|
|
||||||
|
TRACE("Seeking to start of image");
|
||||||
// Write the header at the beginning of the file
|
// Write the header at the beginning of the file
|
||||||
fseek(ctx->imageStream, 0, SEEK_SET);
|
fseek(ctx->imageStream, 0, SEEK_SET);
|
||||||
|
|
||||||
|
TRACE("Writing header at position 0");
|
||||||
if(fwrite(&ctx->header, sizeof(AaruHeaderV2), 1, ctx->imageStream) != 1)
|
if(fwrite(&ctx->header, sizeof(AaruHeaderV2), 1, ctx->imageStream) != 1)
|
||||||
{
|
{
|
||||||
fclose(ctx->imageStream);
|
fclose(ctx->imageStream);
|
||||||
@@ -62,6 +72,7 @@ int aaruf_close(void *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Close current block first
|
// Close current block first
|
||||||
|
TRACE("Closing current block if any");
|
||||||
if(ctx->writingBuffer != NULL)
|
if(ctx->writingBuffer != NULL)
|
||||||
{
|
{
|
||||||
int error = aaruf_close_current_block(ctx);
|
int error = aaruf_close_current_block(ctx);
|
||||||
@@ -70,6 +81,7 @@ int aaruf_close(void *context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Freeing memory pointers");
|
||||||
// This may do nothing if imageStream is NULL, but as the behaviour is undefined, better sure than sorry
|
// This may do nothing if imageStream is NULL, but as the behaviour is undefined, better sure than sorry
|
||||||
if(ctx->imageStream != NULL)
|
if(ctx->imageStream != NULL)
|
||||||
{
|
{
|
||||||
@@ -90,17 +102,16 @@ int aaruf_close(void *context)
|
|||||||
free(ctx->mode2Subheaders);
|
free(ctx->mode2Subheaders);
|
||||||
ctx->mode2Subheaders = NULL;
|
ctx->mode2Subheaders = NULL;
|
||||||
|
|
||||||
if(ctx->mediaTags != NULL)
|
TRACE("Freeing media tags");
|
||||||
{
|
if(ctx->mediaTags != NULL) HASH_ITER(hh, ctx->mediaTags, mediaTag, tmpMediaTag)
|
||||||
HASH_ITER(hh, ctx->mediaTags, mediaTag, tmpMediaTag)
|
|
||||||
{
|
{
|
||||||
HASH_DEL(ctx->mediaTags, mediaTag);
|
HASH_DEL(ctx->mediaTags, mediaTag);
|
||||||
free(mediaTag->data);
|
free(mediaTag->data);
|
||||||
free(mediaTag);
|
free(mediaTag);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __linux__ // TODO: Implement
|
#ifdef __linux__ // TODO: Implement
|
||||||
|
TRACE("Unmapping user data DDT if it is not in memory");
|
||||||
if(!ctx->inMemoryDdt)
|
if(!ctx->inMemoryDdt)
|
||||||
{
|
{
|
||||||
munmap(ctx->userDataDdt, ctx->mappedMemoryDdtSize);
|
munmap(ctx->userDataDdt, ctx->mappedMemoryDdtSize);
|
||||||
@@ -159,5 +170,6 @@ int aaruf_close(void *context)
|
|||||||
|
|
||||||
free(context);
|
free(context);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_close() = 0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -20,26 +20,37 @@
|
|||||||
|
|
||||||
#include <aaruformat.h>
|
#include <aaruformat.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
AARU_EXPORT crc64_ctx *AARU_CALL aaruf_crc64_init(void)
|
AARU_EXPORT crc64_ctx *AARU_CALL aaruf_crc64_init(void)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_crc64_init()");
|
||||||
crc64_ctx *ctx = (crc64_ctx *)malloc(sizeof(crc64_ctx));
|
crc64_ctx *ctx = (crc64_ctx *)malloc(sizeof(crc64_ctx));
|
||||||
|
|
||||||
if(!ctx) return NULL;
|
if(!ctx) return NULL;
|
||||||
|
|
||||||
ctx->crc = CRC64_ECMA_SEED;
|
ctx->crc = CRC64_ECMA_SEED;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_crc64_init()");
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
AARU_EXPORT int AARU_CALL aaruf_crc64_update(crc64_ctx *ctx, const uint8_t *data, uint32_t len)
|
AARU_EXPORT int AARU_CALL aaruf_crc64_update(crc64_ctx *ctx, const uint8_t *data, uint32_t len)
|
||||||
{
|
{
|
||||||
if(!ctx || !data) return -1;
|
TRACE("Entering aaruf_crc64_update(%p, %p, %u)", ctx, data, len);
|
||||||
|
if(!ctx || !data)
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_crc64_update() = -1");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__amd64) || defined(_M_AMD64) || defined(_M_X64) || defined(__I386__) || \
|
#if defined(__x86_64__) || defined(__amd64) || defined(_M_AMD64) || defined(_M_X64) || defined(__I386__) || \
|
||||||
defined(__i386__) || defined(__THW_INTEL) || defined(_M_IX86)
|
defined(__i386__) || defined(__THW_INTEL) || defined(_M_IX86)
|
||||||
if(have_clmul())
|
if(have_clmul())
|
||||||
{
|
{
|
||||||
ctx->crc = ~aaruf_crc64_clmul(~ctx->crc, data, len);
|
ctx->crc = ~aaruf_crc64_clmul(~ctx->crc, data, len);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_crc64_update() = 0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -48,6 +59,8 @@ AARU_EXPORT int AARU_CALL aaruf_crc64_update(crc64_ctx *ctx, const uint8_t *data
|
|||||||
if(have_neon())
|
if(have_neon())
|
||||||
{
|
{
|
||||||
ctx->crc = ~aaruf_crc64_vmull(~ctx->crc, data, len);
|
ctx->crc = ~aaruf_crc64_vmull(~ctx->crc, data, len);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_crc64_update() = 0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -58,6 +71,7 @@ AARU_EXPORT int AARU_CALL aaruf_crc64_update(crc64_ctx *ctx, const uint8_t *data
|
|||||||
|
|
||||||
aaruf_crc64_slicing(&ctx->crc, data, len);
|
aaruf_crc64_slicing(&ctx->crc, data, len);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_crc64_update() = 0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#include <smmintrin.h>
|
#include <smmintrin.h>
|
||||||
#include <wmmintrin.h>
|
#include <wmmintrin.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -82,6 +84,8 @@ CLMUL static __m128i fold(__m128i in, __m128i foldConstants)
|
|||||||
|
|
||||||
AARU_EXPORT CLMUL uint64_t AARU_CALL aaruf_crc64_clmul(uint64_t crc, const uint8_t *data, long length)
|
AARU_EXPORT CLMUL uint64_t AARU_CALL aaruf_crc64_clmul(uint64_t crc, const uint8_t *data, long length)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_crc64_clmul(%" PRIu64 ", %p, %ld)", crc, data, length);
|
||||||
|
|
||||||
const uint64_t k1 = 0xe05dd497ca393ae4; // bitReflect(expMod65(128 + 64, poly, 1)) << 1;
|
const uint64_t k1 = 0xe05dd497ca393ae4; // bitReflect(expMod65(128 + 64, poly, 1)) << 1;
|
||||||
const uint64_t k2 = 0xdabe95afc7875f40; // bitReflect(expMod65(128, poly, 1)) << 1;
|
const uint64_t k2 = 0xdabe95afc7875f40; // bitReflect(expMod65(128, poly, 1)) << 1;
|
||||||
const uint64_t mu = 0x9c3e466c172963d5; // (bitReflect(div129by65(poly)) << 1) | 1;
|
const uint64_t mu = 0x9c3e466c172963d5; // (bitReflect(div129by65(poly)) << 1) | 1;
|
||||||
@@ -197,6 +201,8 @@ AARU_EXPORT CLMUL uint64_t AARU_CALL aaruf_crc64_clmul(uint64_t crc, const uint8
|
|||||||
const __m128i T2 =
|
const __m128i T2 =
|
||||||
_mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(T1, foldConstants2, 0x10), _mm_slli_si128(T1, 8)), R);
|
_mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(T1, foldConstants2, 0x10), _mm_slli_si128(T1, 8)), R);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_crc64_clmul()");
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
return ~_mm_extract_epi64(T2, 1);
|
return ~_mm_extract_epi64(T2, 1);
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ TARGET_WITH_SIMD FORCE_INLINE uint64x2_t fold(uint64x2_t in, uint64x2_t foldCons
|
|||||||
|
|
||||||
AARU_EXPORT TARGET_WITH_SIMD uint64_t AARU_CALL aaruf_crc64_vmull(uint64_t previous_crc, const uint8_t *data, long len)
|
AARU_EXPORT TARGET_WITH_SIMD uint64_t AARU_CALL aaruf_crc64_vmull(uint64_t previous_crc, const uint8_t *data, long len)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_crc64_vmull(%llu, %p, %ld)", previous_crc, data, len);
|
||||||
|
|
||||||
const uint64_t k1 = 0xe05dd497ca393ae4; // bitReflect(expMod65(128 + 64, poly, 1)) << 1;
|
const uint64_t k1 = 0xe05dd497ca393ae4; // bitReflect(expMod65(128 + 64, poly, 1)) << 1;
|
||||||
const uint64_t k2 = 0xdabe95afc7875f40; // bitReflect(expMod65(128, poly, 1)) << 1;
|
const uint64_t k2 = 0xdabe95afc7875f40; // bitReflect(expMod65(128, poly, 1)) << 1;
|
||||||
const uint64_t mu = 0x9c3e466c172963d5; // (bitReflect(div129by65(poly)) << 1) | 1;
|
const uint64_t mu = 0x9c3e466c172963d5; // (bitReflect(div129by65(poly)) << 1) | 1;
|
||||||
@@ -172,6 +174,8 @@ AARU_EXPORT TARGET_WITH_SIMD uint64_t AARU_CALL aaruf_crc64_vmull(uint64_t previ
|
|||||||
const uint64x2_t T2 = veorq_u64(
|
const uint64x2_t T2 = veorq_u64(
|
||||||
veorq_u64(sse2neon_vmull_p64(vget_low_u64(T1), vget_high_u64(foldConstants2)), mm_slli_si128(T1, 8)), R);
|
veorq_u64(sse2neon_vmull_p64(vget_low_u64(T1), vget_high_u64(foldConstants2)), mm_slli_si128(T1, 8)), R);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_crc64_vmull()");
|
||||||
|
|
||||||
return ~vgetq_lane_u64(T2, 1);
|
return ~vgetq_lane_u64(T2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
31
src/create.c
31
src/create.c
@@ -24,42 +24,63 @@
|
|||||||
|
|
||||||
#include "aaruformat.h"
|
#include "aaruformat.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
void *aaruf_create(const char *filepath, uint32_t mediaType, uint32_t sectorSize, uint64_t userSectors,
|
void *aaruf_create(const char *filepath, uint32_t mediaType, uint32_t sectorSize, uint64_t userSectors,
|
||||||
uint64_t negativeSectors, uint64_t overflowSectors, const char *options,
|
uint64_t negativeSectors, uint64_t overflowSectors, const char *options,
|
||||||
const uint8_t *applicationName, uint8_t applicationNameLength, uint8_t applicationMajorVersion,
|
const uint8_t *applicationName, uint8_t applicationNameLength, uint8_t applicationMajorVersion,
|
||||||
uint8_t applicationMinorVersion)
|
uint8_t applicationMinorVersion)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_create(%s, %u, %u, %llu, %llu, %llu, %s, %s, %u, %u, %u)", filepath, mediaType, sectorSize,
|
||||||
|
userSectors, negativeSectors, overflowSectors, options,
|
||||||
|
applicationName ? (const char *)applicationName : "NULL", applicationNameLength, applicationMajorVersion,
|
||||||
|
applicationMinorVersion);
|
||||||
|
|
||||||
// Parse the options
|
// Parse the options
|
||||||
|
TRACE("Parsing options");
|
||||||
aaru_options parsedOptions = parse_options(options);
|
aaru_options parsedOptions = parse_options(options);
|
||||||
|
|
||||||
// Allocate context
|
// Allocate context
|
||||||
|
TRACE("Allocating memory for context");
|
||||||
aaruformatContext *ctx = malloc(sizeof(aaruformatContext));
|
aaruformatContext *ctx = malloc(sizeof(aaruformatContext));
|
||||||
if(ctx == NULL)
|
if(ctx == NULL)
|
||||||
{
|
{
|
||||||
|
FATAL("Not enough memory to create context");
|
||||||
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_create() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(aaruformatContext));
|
memset(ctx, 0, sizeof(aaruformatContext));
|
||||||
|
|
||||||
// Create the image file
|
// Create the image file
|
||||||
|
TRACE("Creating image file %s", filepath);
|
||||||
ctx->imageStream = fopen(filepath, "wb+");
|
ctx->imageStream = fopen(filepath, "wb+");
|
||||||
if(ctx->imageStream == NULL)
|
if(ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
|
FATAL("Error %d opening file %s for writing", errno, filepath);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
errno = AARUF_ERROR_CANNOT_CREATE_FILE;
|
errno = AARUF_ERROR_CANNOT_CREATE_FILE;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_create() = NULL");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(applicationNameLength > AARU_HEADER_APP_NAME_LEN)
|
if(applicationNameLength > AARU_HEADER_APP_NAME_LEN)
|
||||||
{
|
{
|
||||||
|
FATAL("Application name too long (%u bytes, maximum %u bytes)", applicationNameLength,
|
||||||
|
AARU_HEADER_APP_NAME_LEN);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
errno = AARUF_ERROR_INVALID_APP_NAME_LENGTH;
|
errno = AARUF_ERROR_INVALID_APP_NAME_LENGTH;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_create() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize header
|
// Initialize header
|
||||||
|
TRACE("Initializing header");
|
||||||
ctx->header.identifier = AARU_MAGIC;
|
ctx->header.identifier = AARU_MAGIC;
|
||||||
memcpy(ctx->header.application, applicationName, applicationNameLength);
|
memcpy(ctx->header.application, applicationName, applicationNameLength);
|
||||||
ctx->header.imageMajorVersion = AARUF_VERSION_V2;
|
ctx->header.imageMajorVersion = AARUF_VERSION_V2;
|
||||||
@@ -83,7 +104,8 @@ void *aaruf_create(const char *filepath, uint32_t mediaType, uint32_t sectorSize
|
|||||||
|
|
||||||
memset(ctx->readableSectorTags, 0, sizeof(bool) * MaxSectorTag);
|
memset(ctx->readableSectorTags, 0, sizeof(bool) * MaxSectorTag);
|
||||||
|
|
||||||
// Initilize image info
|
// Initialize image info
|
||||||
|
TRACE("Initializing image info");
|
||||||
ctx->imageInfo.Application = ctx->header.application;
|
ctx->imageInfo.Application = ctx->header.application;
|
||||||
ctx->imageInfo.ApplicationVersion = (uint8_t *)malloc(32);
|
ctx->imageInfo.ApplicationVersion = (uint8_t *)malloc(32);
|
||||||
if(ctx->imageInfo.ApplicationVersion != NULL)
|
if(ctx->imageInfo.ApplicationVersion != NULL)
|
||||||
@@ -106,6 +128,7 @@ void *aaruf_create(const char *filepath, uint32_t mediaType, uint32_t sectorSize
|
|||||||
ctx->imageInfo.SectorSize = sectorSize;
|
ctx->imageInfo.SectorSize = sectorSize;
|
||||||
|
|
||||||
// Initialize caches
|
// Initialize caches
|
||||||
|
TRACE("Initializing caches");
|
||||||
ctx->blockHeaderCache.cache = NULL;
|
ctx->blockHeaderCache.cache = NULL;
|
||||||
ctx->blockHeaderCache.max_items = MAX_CACHE_SIZE / (ctx->imageInfo.SectorSize * (1 << ctx->shift));
|
ctx->blockHeaderCache.max_items = MAX_CACHE_SIZE / (ctx->imageInfo.SectorSize * (1 << ctx->shift));
|
||||||
ctx->blockCache.cache = NULL;
|
ctx->blockCache.cache = NULL;
|
||||||
@@ -114,6 +137,7 @@ void *aaruf_create(const char *filepath, uint32_t mediaType, uint32_t sectorSize
|
|||||||
// TODO: Cache tracks and sessions?
|
// TODO: Cache tracks and sessions?
|
||||||
|
|
||||||
// Initialize ECC for Compact Disc
|
// Initialize ECC for Compact Disc
|
||||||
|
TRACE("Initializing Compact Disc ECC");
|
||||||
ctx->eccCdContext = (CdEccContext *)aaruf_ecc_cd_init();
|
ctx->eccCdContext = (CdEccContext *)aaruf_ecc_cd_init();
|
||||||
|
|
||||||
ctx->magic = AARU_MAGIC;
|
ctx->magic = AARU_MAGIC;
|
||||||
@@ -121,6 +145,7 @@ void *aaruf_create(const char *filepath, uint32_t mediaType, uint32_t sectorSize
|
|||||||
ctx->libraryMinorVersion = LIBAARUFORMAT_MINOR_VERSION;
|
ctx->libraryMinorVersion = LIBAARUFORMAT_MINOR_VERSION;
|
||||||
|
|
||||||
// Initialize DDT2
|
// Initialize DDT2
|
||||||
|
TRACE("Initializing DDT2");
|
||||||
ctx->inMemoryDdt = true;
|
ctx->inMemoryDdt = true;
|
||||||
ctx->userDataDdtHeader.identifier = DeDuplicationTable2;
|
ctx->userDataDdtHeader.identifier = DeDuplicationTable2;
|
||||||
ctx->userDataDdtHeader.type = UserData;
|
ctx->userDataDdtHeader.type = UserData;
|
||||||
@@ -142,4 +167,8 @@ void *aaruf_create(const char *filepath, uint32_t mediaType, uint32_t sectorSize
|
|||||||
|
|
||||||
// Is writing
|
// Is writing
|
||||||
ctx->isWriting = true;
|
ctx->isWriting = true;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_create() = %p", ctx);
|
||||||
|
// Return context
|
||||||
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUserDataDdt)
|
int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUserDataDdt)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_ddt_v1(%p, %p, %d)", ctx, entry, *foundUserDataDdt);
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
size_t readBytes = 0;
|
size_t readBytes = 0;
|
||||||
DdtHeader ddtHeader;
|
DdtHeader ddtHeader;
|
||||||
@@ -42,27 +44,32 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting process_ddt_v1() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek to block
|
// Seek to block
|
||||||
|
TRACE("Seeking to DDT block at position %" PRIu64, entry->offset);
|
||||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||||
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
||||||
{
|
{
|
||||||
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...\n", entry->offset);
|
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_ddt_v1() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even if those two checks shall have been done before
|
// Even if those two checks shall have been done before
|
||||||
|
TRACE("Reading DDT block header at position %" PRIu64, entry->offset);
|
||||||
readBytes = fread(&ddtHeader, 1, sizeof(DdtHeader), ctx->imageStream);
|
readBytes = fread(&ddtHeader, 1, sizeof(DdtHeader), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(DdtHeader))
|
if(readBytes != sizeof(DdtHeader))
|
||||||
{
|
{
|
||||||
FATAL("Could not read block header at %" PRIu64 "\n", entry->offset);
|
FATAL("Could not read block header at %" PRIu64 "", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_ddt_v1() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,14 +93,14 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||||
if(cmpData == NULL)
|
if(cmpData == NULL)
|
||||||
{
|
{
|
||||||
TRACE("Cannot allocate memory for DDT, continuing...\n");
|
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->userDataDdt = (uint64_t *)malloc(ddtHeader.length);
|
ctx->userDataDdt = (uint64_t *)malloc(ddtHeader.length);
|
||||||
if(ctx->userDataDdt == NULL)
|
if(ctx->userDataDdt == NULL)
|
||||||
{
|
{
|
||||||
TRACE("Cannot allocate memory for DDT, continuing...\n");
|
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -101,7 +108,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
||||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||||
{
|
{
|
||||||
TRACE("Could not read LZMA properties, continuing...\n");
|
TRACE("Could not read LZMA properties, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(ctx->userDataDdt);
|
free(ctx->userDataDdt);
|
||||||
ctx->userDataDdt = NULL;
|
ctx->userDataDdt = NULL;
|
||||||
@@ -111,7 +118,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||||
if(readBytes != lzmaSize)
|
if(readBytes != lzmaSize)
|
||||||
{
|
{
|
||||||
TRACE("Could not read compressed block, continuing...\n");
|
TRACE("Could not read compressed block, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(ctx->userDataDdt);
|
free(ctx->userDataDdt);
|
||||||
ctx->userDataDdt = NULL;
|
ctx->userDataDdt = NULL;
|
||||||
@@ -119,12 +126,13 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
}
|
}
|
||||||
|
|
||||||
readBytes = ddtHeader.length;
|
readBytes = ddtHeader.length;
|
||||||
|
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||||
errorNo = aaruf_lzma_decode_buffer((uint8_t *)ctx->userDataDdt, &readBytes, cmpData, &lzmaSize,
|
errorNo = aaruf_lzma_decode_buffer((uint8_t *)ctx->userDataDdt, &readBytes, cmpData, &lzmaSize,
|
||||||
lzmaProperties, LZMA_PROPERTIES_LENGTH);
|
lzmaProperties, LZMA_PROPERTIES_LENGTH);
|
||||||
|
|
||||||
if(errorNo != 0)
|
if(errorNo != 0)
|
||||||
{
|
{
|
||||||
FATAL("Got error %d from LZMA, stopping...\n", errorNo);
|
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(ctx->userDataDdt);
|
free(ctx->userDataDdt);
|
||||||
ctx->userDataDdt = NULL;
|
ctx->userDataDdt = NULL;
|
||||||
@@ -133,7 +141,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(readBytes != ddtHeader.length)
|
if(readBytes != ddtHeader.length)
|
||||||
{
|
{
|
||||||
FATAL("Error decompressing block, should be {0} bytes but got {1} bytes., stopping...\n");
|
FATAL("Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(ctx->userDataDdt);
|
free(ctx->userDataDdt);
|
||||||
ctx->userDataDdt = NULL;
|
ctx->userDataDdt = NULL;
|
||||||
@@ -147,6 +155,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
// TODO: Check CRC
|
// TODO: Check CRC
|
||||||
case None:
|
case None:
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
TRACE("Memory mapping deduplication table at position %" PRIu64, entry->offset + sizeof(ddtHeader));
|
||||||
ctx->mappedMemoryDdtSize = sizeof(uint64_t) * ddtHeader.entries;
|
ctx->mappedMemoryDdtSize = sizeof(uint64_t) * ddtHeader.entries;
|
||||||
ctx->userDataDdt = mmap(NULL, ctx->mappedMemoryDdtSize, PROT_READ, MAP_SHARED, fileno(ctx->imageStream),
|
ctx->userDataDdt = mmap(NULL, ctx->mappedMemoryDdtSize, PROT_READ, MAP_SHARED, fileno(ctx->imageStream),
|
||||||
entry->offset + sizeof(ddtHeader));
|
entry->offset + sizeof(ddtHeader));
|
||||||
@@ -154,19 +163,19 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
if(ctx->userDataDdt == MAP_FAILED)
|
if(ctx->userDataDdt == MAP_FAILED)
|
||||||
{
|
{
|
||||||
*foundUserDataDdt = false;
|
*foundUserDataDdt = false;
|
||||||
FATAL("Could not read map deduplication table.\n");
|
FATAL("Could not read map deduplication table.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->inMemoryDdt = false;
|
ctx->inMemoryDdt = false;
|
||||||
break;
|
break;
|
||||||
#else // TODO: Implement
|
#else // TODO: Implement
|
||||||
TRACE("Uncompressed DDT not yet implemented...\n");
|
TRACE("Uncompressed DDT not yet implemented...");
|
||||||
*foundUserDataDdt = false;
|
*foundUserDataDdt = false;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
TRACE("Found unknown compression type %d, continuing...\n", ddtHeader.compression);
|
TRACE("Found unknown compression type %d, continuing...", ddtHeader.compression);
|
||||||
*foundUserDataDdt = false;
|
*foundUserDataDdt = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -182,14 +191,14 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||||
if(cmpData == NULL)
|
if(cmpData == NULL)
|
||||||
{
|
{
|
||||||
TRACE("Cannot allocate memory for DDT, continuing...\n");
|
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdDdt = (uint32_t *)malloc(ddtHeader.length);
|
cdDdt = (uint32_t *)malloc(ddtHeader.length);
|
||||||
if(cdDdt == NULL)
|
if(cdDdt == NULL)
|
||||||
{
|
{
|
||||||
TRACE("Cannot allocate memory for DDT, continuing...\n");
|
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -197,7 +206,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
||||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||||
{
|
{
|
||||||
TRACE("Could not read LZMA properties, continuing...\n");
|
TRACE("Could not read LZMA properties, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(cdDdt);
|
free(cdDdt);
|
||||||
break;
|
break;
|
||||||
@@ -206,19 +215,20 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||||
if(readBytes != lzmaSize)
|
if(readBytes != lzmaSize)
|
||||||
{
|
{
|
||||||
TRACE("Could not read compressed block, continuing...\n");
|
TRACE("Could not read compressed block, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(cdDdt);
|
free(cdDdt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
readBytes = ddtHeader.length;
|
readBytes = ddtHeader.length;
|
||||||
|
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||||
errorNo = aaruf_lzma_decode_buffer((uint8_t *)cdDdt, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
errorNo = aaruf_lzma_decode_buffer((uint8_t *)cdDdt, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||||
LZMA_PROPERTIES_LENGTH);
|
LZMA_PROPERTIES_LENGTH);
|
||||||
|
|
||||||
if(errorNo != 0)
|
if(errorNo != 0)
|
||||||
{
|
{
|
||||||
FATAL("Got error %d from LZMA, stopping...\n", errorNo);
|
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(cdDdt);
|
free(cdDdt);
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
@@ -226,7 +236,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(readBytes != ddtHeader.length)
|
if(readBytes != ddtHeader.length)
|
||||||
{
|
{
|
||||||
FATAL("Error decompressing block, should be {0} bytes but got {1} bytes., stopping...\n");
|
FATAL("Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(cdDdt);
|
free(cdDdt);
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
@@ -247,7 +257,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(cdDdt == NULL)
|
if(cdDdt == NULL)
|
||||||
{
|
{
|
||||||
TRACE("Cannot allocate memory for deduplication table.\n");
|
TRACE("Cannot allocate memory for deduplication table.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +266,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
if(readBytes != ddtHeader.entries * sizeof(uint32_t))
|
if(readBytes != ddtHeader.entries * sizeof(uint32_t))
|
||||||
{
|
{
|
||||||
free(cdDdt);
|
free(cdDdt);
|
||||||
TRACE("Could not read deduplication table, continuing...\n");
|
TRACE("Could not read deduplication table, continuing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,21 +279,25 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE("Found unknown compression type %d, continuing...\n", ddtHeader.compression);
|
TRACE("Found unknown compression type %d, continuing...", ddtHeader.compression);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting process_ddt_v1() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t decode_ddt_entry_v1(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset, uint64_t *blockOffset,
|
int32_t decode_ddt_entry_v1(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset, uint64_t *blockOffset,
|
||||||
uint8_t *sectorStatus)
|
uint8_t *sectorStatus)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering decode_ddt_entry_v1(%p, %" PRIu64 ", %llu, %llu, %d)", ctx, sectorAddress, *offset, *blockOffset,
|
||||||
|
*sectorStatus);
|
||||||
|
|
||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,5 +312,8 @@ int32_t decode_ddt_entry_v1(aaruformatContext *ctx, uint64_t sectorAddress, uint
|
|||||||
else
|
else
|
||||||
*sectorStatus = SectorStatusDumped;
|
*sectorStatus = SectorStatusDumped;
|
||||||
|
|
||||||
|
TRACE("Exiting decode_ddt_entry_v1(%p, %" PRIu64 ", %llu, %llu, %d) = AARUF_STATUS_OK", ctx, sectorAddress, *offset,
|
||||||
|
*blockOffset, *sectorStatus);
|
||||||
|
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
178
src/ddt/ddt_v2.c
178
src/ddt/ddt_v2.c
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUserDataDdt)
|
int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUserDataDdt)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_ddt_v2(%p, %p, %d)", ctx, entry, *foundUserDataDdt);
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
size_t readBytes = 0;
|
size_t readBytes = 0;
|
||||||
DdtHeader2 ddtHeader;
|
DdtHeader2 ddtHeader;
|
||||||
@@ -41,7 +43,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,19 +53,21 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||||
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
||||||
{
|
{
|
||||||
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...\n", entry->offset);
|
FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even if those two checks shall have been done before
|
// Even if those two checks shall have been done before
|
||||||
|
TRACE("Reading DDT block header at position %" PRIu64, entry->offset);
|
||||||
readBytes = fread(&ddtHeader, 1, sizeof(DdtHeader2), ctx->imageStream);
|
readBytes = fread(&ddtHeader, 1, sizeof(DdtHeader2), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(DdtHeader2))
|
if(readBytes != sizeof(DdtHeader2))
|
||||||
{
|
{
|
||||||
FATAL("Could not read block header at %" PRIu64 "\n", entry->offset);
|
FATAL("Could not read block header at %" PRIu64 "", entry->offset);
|
||||||
|
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,14 +92,14 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||||
if(cmpData == NULL)
|
if(cmpData == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = malloc(ddtHeader.length);
|
buffer = malloc(ddtHeader.length);
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -101,7 +107,7 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
||||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read LZMA properties, continuing...\n");
|
TRACE("Could not read LZMA properties, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
break;
|
break;
|
||||||
@@ -110,29 +116,32 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||||
if(readBytes != lzmaSize)
|
if(readBytes != lzmaSize)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read compressed block, continuing...\n");
|
TRACE("Could not read compressed block, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
readBytes = ddtHeader.length;
|
readBytes = ddtHeader.length;
|
||||||
|
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||||
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||||
LZMA_PROPERTIES_LENGTH);
|
LZMA_PROPERTIES_LENGTH);
|
||||||
|
|
||||||
if(errorNo != 0)
|
if(errorNo != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Got error %d from LZMA, stopping...\n", errorNo);
|
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(readBytes != ddtHeader.length)
|
if(readBytes != ddtHeader.length)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error decompressing block, should be {0} bytes but got {1} bytes., stopping...\n");
|
FATAL("Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,8 +151,10 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL("Could not initialize CRC64.");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,8 +163,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(crc64 != ddtHeader.crc64)
|
if(crc64 != ddtHeader.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected DDT CRC 0x%16lX but got 0x%16lX.\n", ddtHeader.crc64, crc64);
|
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,16 +183,17 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Reading DDT of length %zu bytes", ddtHeader.length);
|
||||||
readBytes = fread(buffer, 1, ddtHeader.length, ctx->imageStream);
|
readBytes = fread(buffer, 1, ddtHeader.length, ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != ddtHeader.length)
|
if(readBytes != ddtHeader.length)
|
||||||
{
|
{
|
||||||
free(buffer);
|
free(buffer);
|
||||||
FATAL("Could not read deduplication table, continuing...\n");
|
FATAL("Could not read deduplication table, continuing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,8 +201,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL("Could not initialize CRC64.");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,8 +212,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(crc64 != ddtHeader.crc64)
|
if(crc64 != ddtHeader.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected DDT CRC 0x%16lX but got 0x%16lX.\n", ddtHeader.crc64, crc64);
|
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +228,7 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE("Found unknown compression type %d, continuing...\n", ddtHeader.compression);
|
TRACE("Found unknown compression type %d, continuing...", ddtHeader.compression);
|
||||||
*foundUserDataDdt = false;
|
*foundUserDataDdt = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -228,14 +243,14 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||||
if(cmpData == NULL)
|
if(cmpData == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = malloc(ddtHeader.length);
|
buffer = malloc(ddtHeader.length);
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -243,7 +258,7 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
||||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read LZMA properties, continuing...\n");
|
TRACE("Could not read LZMA properties, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
break;
|
break;
|
||||||
@@ -252,29 +267,32 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||||
if(readBytes != lzmaSize)
|
if(readBytes != lzmaSize)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read compressed block, continuing...\n");
|
TRACE("Could not read compressed block, continuing...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
readBytes = ddtHeader.length;
|
readBytes = ddtHeader.length;
|
||||||
|
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||||
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||||
LZMA_PROPERTIES_LENGTH);
|
LZMA_PROPERTIES_LENGTH);
|
||||||
|
|
||||||
if(errorNo != 0)
|
if(errorNo != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Got error %d from LZMA, stopping...\n", errorNo);
|
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(readBytes != ddtHeader.length)
|
if(readBytes != ddtHeader.length)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error decompressing block, should be {0} bytes but got {1} bytes., stopping...\n");
|
FATAL("Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,8 +300,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL("Could not initialize CRC64.");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,8 +311,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(crc64 != ddtHeader.crc64)
|
if(crc64 != ddtHeader.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected DDT CRC 0x%16lX but got 0x%16lX.\n", ddtHeader.crc64, crc64);
|
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +341,7 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
TRACE("Cannot allocate memory for deduplication table.\n");
|
TRACE("Cannot allocate memory for deduplication table.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +350,7 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
if(readBytes != ddtHeader.length)
|
if(readBytes != ddtHeader.length)
|
||||||
{
|
{
|
||||||
free(buffer);
|
free(buffer);
|
||||||
FATAL("Could not read deduplication table, continuing...\n");
|
FATAL("Could not read deduplication table, continuing...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,8 +358,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL(stderr, "Could not initialize CRC64.");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,7 +369,7 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
if(crc64 != ddtHeader.crc64)
|
if(crc64 != ddtHeader.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected DDT CRC 0x%16lX but got 0x%16lX.\n", ddtHeader.crc64, crc64);
|
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
@@ -372,21 +393,26 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE("Found unknown compression type %d, continuing...\n", ddtHeader.compression);
|
TRACE("Found unknown compression type %d, continuing...", ddtHeader.compression);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting process_ddt_v2() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t decode_ddt_entry_v2(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset, uint64_t *blockOffset,
|
int32_t decode_ddt_entry_v2(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset, uint64_t *blockOffset,
|
||||||
uint8_t *sectorStatus)
|
uint8_t *sectorStatus)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering decode_ddt_entry_v2(%p, %" PRIu64 ", %llu, %llu, %d)", ctx, sectorAddress, *offset, *blockOffset,
|
||||||
|
*sectorStatus);
|
||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting decode_ddt_entry_v2() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,17 +425,27 @@ int32_t decode_ddt_entry_v2(aaruformatContext *ctx, uint64_t sectorAddress, uint
|
|||||||
int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset,
|
int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset,
|
||||||
uint64_t *blockOffset, uint8_t *sectorStatus)
|
uint64_t *blockOffset, uint8_t *sectorStatus)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering decode_ddt_single_level_v2(%p, %" PRIu64 ", %llu, %llu, %d)", ctx, sectorAddress, *offset,
|
||||||
|
*blockOffset, *sectorStatus);
|
||||||
|
|
||||||
uint64_t ddtEntry = 0;
|
uint64_t ddtEntry = 0;
|
||||||
|
|
||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting decode_ddt_single_level_v2() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should not really be here
|
// Should not really be here
|
||||||
if(ctx->userDataDdtHeader.tableShift != 0) return AARUF_ERROR_CANNOT_READ_BLOCK;
|
if(ctx->userDataDdtHeader.tableShift != 0)
|
||||||
|
{
|
||||||
|
FATAL("DDT table shift is not zero, but we are in single-level DDT decoding.");
|
||||||
|
TRACE("Exiting decode_ddt_single_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Take into account the negative and overflow blocks, library-wide
|
// TODO: Take into account the negative and overflow blocks, library-wide
|
||||||
sectorAddress += ctx->userDataDdtHeader.negative;
|
sectorAddress += ctx->userDataDdtHeader.negative;
|
||||||
@@ -420,7 +456,8 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sectorAddres
|
|||||||
ddtEntry = ctx->userDataDdtBig[sectorAddress];
|
ddtEntry = ctx->userDataDdtBig[sectorAddress];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACE("Unknown DDT size type %d.\n", ctx->userDataDdtHeader.sizeType);
|
FATAL("Unknown DDT size type %d.", ctx->userDataDdtHeader.sizeType);
|
||||||
|
TRACE("Exiting decode_ddt_single_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,6 +466,8 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sectorAddres
|
|||||||
*sectorStatus = SectorStatusNotDumped;
|
*sectorStatus = SectorStatusNotDumped;
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
*blockOffset = 0;
|
*blockOffset = 0;
|
||||||
|
TRACE("Exiting decode_ddt_single_level_v2(%p, %" PRIu64 ", %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
|
||||||
|
sectorAddress, *offset, *blockOffset, *sectorStatus);
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,12 +486,17 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sectorAddres
|
|||||||
*offset = ddtEntry & offsetMask;
|
*offset = ddtEntry & offsetMask;
|
||||||
*blockOffset = (ddtEntry >> ctx->userDataDdtHeader.dataShift) * (1 << ctx->userDataDdtHeader.blockAlignmentShift);
|
*blockOffset = (ddtEntry >> ctx->userDataDdtHeader.dataShift) * (1 << ctx->userDataDdtHeader.blockAlignmentShift);
|
||||||
|
|
||||||
|
TRACE("Exiting decode_ddt_single_level_v2(%p, %" PRIu64 ", %llu, %llu, %d) = AARUF_STATUS_OK", ctx, sectorAddress,
|
||||||
|
*offset, *blockOffset, *sectorStatus);
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset,
|
int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset,
|
||||||
uint64_t *blockOffset, uint8_t *sectorStatus)
|
uint64_t *blockOffset, uint8_t *sectorStatus)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering decode_ddt_multi_level_v2(%p, %" PRIu64 ", %llu, %llu, %d)", ctx, sectorAddress, *offset,
|
||||||
|
*blockOffset, *sectorStatus);
|
||||||
|
|
||||||
uint64_t ddtEntry = 0;
|
uint64_t ddtEntry = 0;
|
||||||
uint8_t lzmaProperties[LZMA_PROPERTIES_LENGTH];
|
uint8_t lzmaProperties[LZMA_PROPERTIES_LENGTH];
|
||||||
size_t lzmaSize = 0;
|
size_t lzmaSize = 0;
|
||||||
@@ -468,12 +512,19 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
// Check if the context and image stream are valid
|
// Check if the context and image stream are valid
|
||||||
if(ctx == NULL || ctx->imageStream == NULL)
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid context or image stream.\n");
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should not really be here
|
// Should not really be here
|
||||||
if(ctx->userDataDdtHeader.tableShift == 0) return AARUF_ERROR_CANNOT_READ_BLOCK;
|
if(ctx->userDataDdtHeader.tableShift == 0)
|
||||||
|
{
|
||||||
|
FATAL("DDT table shift is zero, but we are in multi-level DDT decoding.");
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Take into account the negative and overflow blocks, library-wide
|
// TODO: Take into account the negative and overflow blocks, library-wide
|
||||||
sectorAddress += ctx->userDataDdtHeader.negative;
|
sectorAddress += ctx->userDataDdtHeader.negative;
|
||||||
@@ -487,7 +538,8 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
secondaryDdtOffset = ctx->userDataDdtBig[ddtPosition];
|
secondaryDdtOffset = ctx->userDataDdtBig[ddtPosition];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACE("Unknown DDT size type %d.\n", ctx->userDataDdtHeader.sizeType);
|
FATAL("Unknown DDT size type %d.", ctx->userDataDdtHeader.sizeType);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,15 +555,15 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
|
|
||||||
if(readBytes != sizeof(DdtHeader2))
|
if(readBytes != sizeof(DdtHeader2))
|
||||||
{
|
{
|
||||||
FATAL("Could not read block header at %" PRIu64 "\n", secondaryDdtOffset);
|
FATAL("Could not read block header at %" PRIu64 "", secondaryDdtOffset);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ddtHeader.identifier != DeDuplicationTable2 || ddtHeader.type != UserData)
|
if(ddtHeader.identifier != DeDuplicationTable2 || ddtHeader.type != UserData)
|
||||||
{
|
{
|
||||||
TRACE("Invalid block header at %" PRIu64 "\n", secondaryDdtOffset);
|
FATAL("Invalid block header at %" PRIu64 "", secondaryDdtOffset);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,14 +576,15 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||||
if(cmpData == NULL)
|
if(cmpData == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for DDT, stopping...\n");
|
FATAL("Cannot allocate memory for DDT, stopping...");
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = malloc(ddtHeader.length);
|
buffer = malloc(ddtHeader.length);
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for DDT, stopping...\n");
|
FATAL("Cannot allocate memory for DDT, stopping...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
@@ -539,38 +592,43 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
||||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read LZMA properties, stopping...\n");
|
FATAL("Could not read LZMA properties, stopping...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||||
if(readBytes != lzmaSize)
|
if(readBytes != lzmaSize)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read compressed block, stopping...\n");
|
FATAL("Could not read compressed block, stopping...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||||
readBytes = ddtHeader.length;
|
readBytes = ddtHeader.length;
|
||||||
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||||
LZMA_PROPERTIES_LENGTH);
|
LZMA_PROPERTIES_LENGTH);
|
||||||
|
|
||||||
if(errorNo != 0)
|
if(errorNo != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Got error %d from LZMA, stopping...\n", errorNo);
|
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(readBytes != ddtHeader.length)
|
if(readBytes != ddtHeader.length)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error decompressing block, should be {0} bytes but got {1} bytes., stopping...\n");
|
FATAL("Error decompressing block, should be {0} bytes but got {1} bytes., stopping...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,8 +638,9 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL("Could not initialize CRC64.");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,8 +649,9 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
|
|
||||||
if(crc64 != ddtHeader.crc64)
|
if(crc64 != ddtHeader.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected DDT CRC 0x%16lX but got 0x%16lX.\n", ddtHeader.crc64, crc64);
|
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,7 +668,8 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
|
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for DDT, stopping...\n");
|
FATAL(stderr, "Cannot allocate memory for DDT, stopping...");
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,7 +678,8 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
if(readBytes != ddtHeader.length)
|
if(readBytes != ddtHeader.length)
|
||||||
{
|
{
|
||||||
free(buffer);
|
free(buffer);
|
||||||
FATAL("Could not read deduplication table, stopping...\n");
|
FATAL("Could not read deduplication table, stopping...");
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,8 +687,9 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL("Could not initialize CRC64.");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,8 +698,9 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
|
|
||||||
if(crc64 != ddtHeader.crc64)
|
if(crc64 != ddtHeader.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected DDT CRC 0x%16lX but got 0x%16lX.\n", ddtHeader.crc64, crc64);
|
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,7 +713,8 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE("Found unknown compression type %d, stopping...\n", ddtHeader.compression);
|
FATAL("Found unknown compression type %d, stopping...", ddtHeader.compression);
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -664,6 +729,9 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
*sectorStatus = SectorStatusNotDumped;
|
*sectorStatus = SectorStatusNotDumped;
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
*blockOffset = 0;
|
*blockOffset = 0;
|
||||||
|
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2(%p, %" PRIu64 ", %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
|
||||||
|
sectorAddress, *offset, *blockOffset, *sectorStatus);
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,5 +750,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
|||||||
*offset = ddtEntry & offsetMask;
|
*offset = ddtEntry & offsetMask;
|
||||||
*blockOffset = (ddtEntry >> ctx->userDataDdtHeader.dataShift) * (1 << ctx->userDataDdtHeader.blockAlignmentShift);
|
*blockOffset = (ddtEntry >> ctx->userDataDdtHeader.dataShift) * (1 << ctx->userDataDdtHeader.blockAlignmentShift);
|
||||||
|
|
||||||
|
TRACE("Exiting decode_ddt_multi_level_v2(%p, %" PRIu64 ", %llu, %llu, %d) = AARUF_STATUS_OK", ctx, sectorAddress,
|
||||||
|
*offset, *blockOffset, *sectorStatus);
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
@@ -21,10 +21,13 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "aaruformat.h"
|
#include "aaruformat.h"
|
||||||
|
#include "log.h"
|
||||||
#include "utarray.h"
|
#include "utarray.h"
|
||||||
|
|
||||||
UT_array *process_index_v1(aaruformatContext *ctx)
|
UT_array *process_index_v1(aaruformatContext *ctx)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_index_v1(%p)", ctx);
|
||||||
|
|
||||||
UT_array *index_entries = NULL;
|
UT_array *index_entries = NULL;
|
||||||
IndexEntry entry;
|
IndexEntry entry;
|
||||||
|
|
||||||
@@ -36,6 +39,7 @@ UT_array *process_index_v1(aaruformatContext *ctx)
|
|||||||
utarray_new(index_entries, &index_entry_icd);
|
utarray_new(index_entries, &index_entry_icd);
|
||||||
|
|
||||||
// Read the index header
|
// Read the index header
|
||||||
|
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||||
IndexHeader idx_header;
|
IndexHeader idx_header;
|
||||||
fread(&idx_header, sizeof(IndexHeader), 1, ctx->imageStream);
|
fread(&idx_header, sizeof(IndexHeader), 1, ctx->imageStream);
|
||||||
@@ -43,8 +47,10 @@ UT_array *process_index_v1(aaruformatContext *ctx)
|
|||||||
// Check if the index header is valid
|
// Check if the index header is valid
|
||||||
if(idx_header.identifier != IndexBlock)
|
if(idx_header.identifier != IndexBlock)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Incorrect index identifier.\n");
|
FATAL("Incorrect index identifier.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting process_index_v1() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,44 +60,59 @@ UT_array *process_index_v1(aaruformatContext *ctx)
|
|||||||
utarray_push_back(index_entries, &entry);
|
utarray_push_back(index_entries, &entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Read %d index entries from index block at position %llu", idx_header.entries, ctx->header.indexOffset);
|
||||||
return index_entries;
|
return index_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t verify_index_v1(aaruformatContext *ctx)
|
int32_t verify_index_v1(aaruformatContext *ctx)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering verify_index_v1(%p)", ctx);
|
||||||
|
|
||||||
size_t read_bytes = 0;
|
size_t read_bytes = 0;
|
||||||
IndexHeader index_header;
|
IndexHeader index_header;
|
||||||
uint64_t crc64 = 0;
|
uint64_t crc64 = 0;
|
||||||
IndexEntry *index_entries = NULL;
|
IndexEntry *index_entries = NULL;
|
||||||
|
|
||||||
if(ctx == NULL || ctx->imageStream == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v1() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
// This will traverse all blocks and check their CRC64 without uncompressing them
|
// This will traverse all blocks and check their CRC64 without uncompressing them
|
||||||
fprintf(stderr, "Checking index integrity at %llu.\n", ctx->header.indexOffset);
|
TRACE("Checking index integrity at %llu.", ctx->header.indexOffset);
|
||||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||||
|
|
||||||
// Read the index header
|
// Read the index header
|
||||||
|
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||||
read_bytes = fread(&index_header, 1, sizeof(IndexHeader), ctx->imageStream);
|
read_bytes = fread(&index_header, 1, sizeof(IndexHeader), ctx->imageStream);
|
||||||
|
|
||||||
if(read_bytes != sizeof(IndexHeader))
|
if(read_bytes != sizeof(IndexHeader))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read index header.\n");
|
FATAL("Could not read index header.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v1() = AARUF_ERROR_CANNOT_READ_HEADER");
|
||||||
return AARUF_ERROR_CANNOT_READ_HEADER;
|
return AARUF_ERROR_CANNOT_READ_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index_header.identifier != IndexBlock)
|
if(index_header.identifier != IndexBlock)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Incorrect index identifier.\n");
|
FATAL("Incorrect index identifier.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v1() = AARUF_ERROR_CANNOT_READ_INDEX");
|
||||||
return AARUF_ERROR_CANNOT_READ_INDEX;
|
return AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Index at %llu contains %d entries.\n", ctx->header.indexOffset, index_header.entries);
|
TRACE("Index at %llu contains %d entries.", ctx->header.indexOffset, index_header.entries);
|
||||||
|
fprintf(stderr, "Index at %llu contains %d entries.", ctx->header.indexOffset, index_header.entries);
|
||||||
|
|
||||||
index_entries = malloc(sizeof(IndexEntry) * index_header.entries);
|
index_entries = malloc(sizeof(IndexEntry) * index_header.entries);
|
||||||
|
|
||||||
if(index_entries == NULL)
|
if(index_entries == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for index entries.\n");
|
FATAL("Cannot allocate memory for index entries.");
|
||||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,8 +120,10 @@ int32_t verify_index_v1(aaruformatContext *ctx)
|
|||||||
|
|
||||||
if(read_bytes != sizeof(IndexEntry) * index_header.entries)
|
if(read_bytes != sizeof(IndexEntry) * index_header.entries)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read index entries.\n");
|
FATAL("Could not read index entries.");
|
||||||
free(index_entries);
|
free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v1() = AARUF_ERROR_CANNOT_READ_INDEX");
|
||||||
return AARUF_ERROR_CANNOT_READ_INDEX;
|
return AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,10 +134,13 @@ int32_t verify_index_v1(aaruformatContext *ctx)
|
|||||||
|
|
||||||
if(crc64 != index_header.crc64)
|
if(crc64 != index_header.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected index CRC 0x%16llX but got 0x%16llX.\n", index_header.crc64, crc64);
|
FATAL("Expected index CRC 0x%16llX but got 0x%16llX.", index_header.crc64, crc64);
|
||||||
free(index_entries);
|
free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v1() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v1() = AARUF_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
@@ -21,14 +21,17 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "aaruformat.h"
|
#include "aaruformat.h"
|
||||||
|
#include "log.h"
|
||||||
#include "utarray.h"
|
#include "utarray.h"
|
||||||
|
|
||||||
UT_array *process_index_v2(aaruformatContext *ctx)
|
UT_array *process_index_v2(aaruformatContext *ctx)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_index_v2(%p)", ctx);
|
||||||
|
|
||||||
UT_array *index_entries = NULL;
|
UT_array *index_entries = NULL;
|
||||||
IndexEntry entry;
|
IndexEntry entry;
|
||||||
|
|
||||||
if(ctx == NULL || ctx->imageStream == NULL) return NULL;
|
if(ctx == NULL || ctx->imageStream == NULL) {return NULL;}
|
||||||
|
|
||||||
// Initialize the index entries array
|
// Initialize the index entries array
|
||||||
UT_icd index_entry_icd = {sizeof(IndexEntry), NULL, NULL, NULL};
|
UT_icd index_entry_icd = {sizeof(IndexEntry), NULL, NULL, NULL};
|
||||||
@@ -36,6 +39,7 @@ UT_array *process_index_v2(aaruformatContext *ctx)
|
|||||||
utarray_new(index_entries, &index_entry_icd);
|
utarray_new(index_entries, &index_entry_icd);
|
||||||
|
|
||||||
// Read the index header
|
// Read the index header
|
||||||
|
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||||
IndexHeader2 idx_header;
|
IndexHeader2 idx_header;
|
||||||
fread(&idx_header, sizeof(IndexHeader2), 1, ctx->imageStream);
|
fread(&idx_header, sizeof(IndexHeader2), 1, ctx->imageStream);
|
||||||
@@ -43,8 +47,10 @@ UT_array *process_index_v2(aaruformatContext *ctx)
|
|||||||
// Check if the index header is valid
|
// Check if the index header is valid
|
||||||
if(idx_header.identifier != IndexBlock2)
|
if(idx_header.identifier != IndexBlock2)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Incorrect index identifier.\n");
|
FATAL("Incorrect index identifier.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting process_index_v2() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,44 +60,60 @@ UT_array *process_index_v2(aaruformatContext *ctx)
|
|||||||
utarray_push_back(index_entries, &entry);
|
utarray_push_back(index_entries, &entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Read %d index entries from index block at position %llu", idx_header.entries, ctx->header.indexOffset);
|
||||||
return index_entries;
|
return index_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t verify_index_v2(aaruformatContext *ctx)
|
int32_t verify_index_v2(aaruformatContext *ctx)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering verify_index_v2(%p)", ctx);
|
||||||
|
|
||||||
size_t read_bytes = 0;
|
size_t read_bytes = 0;
|
||||||
IndexHeader2 index_header;
|
IndexHeader2 index_header;
|
||||||
uint64_t crc64 = 0;
|
uint64_t crc64 = 0;
|
||||||
IndexEntry *index_entries = NULL;
|
IndexEntry *index_entries = NULL;
|
||||||
|
|
||||||
if(ctx == NULL || ctx->imageStream == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v2() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
// This will traverse all blocks and check their CRC64 without uncompressing them
|
// This will traverse all blocks and check their CRC64 without uncompressing them
|
||||||
fprintf(stderr, "Checking index integrity at %llu.\n", ctx->header.indexOffset);
|
TRACE("Checking index integrity at %llu.", ctx->header.indexOffset);
|
||||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||||
|
|
||||||
// Read the index header
|
// Read the index header
|
||||||
|
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||||
read_bytes = fread(&index_header, 1, sizeof(IndexHeader2), ctx->imageStream);
|
read_bytes = fread(&index_header, 1, sizeof(IndexHeader2), ctx->imageStream);
|
||||||
|
|
||||||
if(read_bytes != sizeof(IndexHeader2))
|
if(read_bytes != sizeof(IndexHeader2))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read index header.\n");
|
FATAL("Could not read index header.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v2() = AARUF_ERROR_CANNOT_READ_HEADER");
|
||||||
return AARUF_ERROR_CANNOT_READ_HEADER;
|
return AARUF_ERROR_CANNOT_READ_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index_header.identifier != IndexBlock2)
|
if(index_header.identifier != IndexBlock2)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Incorrect index identifier.\n");
|
FATAL("Incorrect index identifier.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v2() = AARUF_ERROR_CANNOT_READ_INDEX");
|
||||||
return AARUF_ERROR_CANNOT_READ_INDEX;
|
return AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Index at %llu contains %d entries.\n", ctx->header.indexOffset, index_header.entries);
|
TRACE("Index at %llu contains %d entries.", ctx->header.indexOffset, index_header.entries);
|
||||||
|
|
||||||
index_entries = malloc(sizeof(IndexEntry) * index_header.entries);
|
index_entries = malloc(sizeof(IndexEntry) * index_header.entries);
|
||||||
|
|
||||||
if(index_entries == NULL)
|
if(index_entries == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for index entries.\n");
|
FATAL("Cannot allocate memory for index entries.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v2() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,8 +121,10 @@ int32_t verify_index_v2(aaruformatContext *ctx)
|
|||||||
|
|
||||||
if(read_bytes != sizeof(IndexEntry) * index_header.entries)
|
if(read_bytes != sizeof(IndexEntry) * index_header.entries)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read index entries.\n");
|
FATAL("Could not read index entries.");
|
||||||
free(index_entries);
|
free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v2() = AARUF_ERROR_CANNOT_READ_INDEX");
|
||||||
return AARUF_ERROR_CANNOT_READ_INDEX;
|
return AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,10 +135,13 @@ int32_t verify_index_v2(aaruformatContext *ctx)
|
|||||||
|
|
||||||
if(crc64 != index_header.crc64)
|
if(crc64 != index_header.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected index CRC 0x%16llX but got 0x%16llX.\n", index_header.crc64, crc64);
|
FATAL("Expected index CRC 0x%16llX but got 0x%16llX.", index_header.crc64, crc64);
|
||||||
free(index_entries);
|
free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v2() = AARUF_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
@@ -22,10 +22,13 @@
|
|||||||
|
|
||||||
#include "aaruformat.h"
|
#include "aaruformat.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "log.h"
|
||||||
#include "utarray.h"
|
#include "utarray.h"
|
||||||
|
|
||||||
UT_array *process_index_v3(aaruformatContext *ctx)
|
UT_array *process_index_v3(aaruformatContext *ctx)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering process_index_v3(%p)", ctx);
|
||||||
|
|
||||||
UT_array *index_entries = NULL;
|
UT_array *index_entries = NULL;
|
||||||
IndexEntry entry;
|
IndexEntry entry;
|
||||||
|
|
||||||
@@ -37,6 +40,7 @@ UT_array *process_index_v3(aaruformatContext *ctx)
|
|||||||
utarray_new(index_entries, &index_entry_icd);
|
utarray_new(index_entries, &index_entry_icd);
|
||||||
|
|
||||||
// Read the index header
|
// Read the index header
|
||||||
|
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||||
IndexHeader3 idx_header;
|
IndexHeader3 idx_header;
|
||||||
fread(&idx_header, sizeof(IndexHeader3), 1, ctx->imageStream);
|
fread(&idx_header, sizeof(IndexHeader3), 1, ctx->imageStream);
|
||||||
@@ -44,8 +48,10 @@ UT_array *process_index_v3(aaruformatContext *ctx)
|
|||||||
// Check if the index header is valid
|
// Check if the index header is valid
|
||||||
if(idx_header.identifier != IndexBlock3)
|
if(idx_header.identifier != IndexBlock3)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Incorrect index identifier.\n");
|
FATAL("Incorrect index identifier.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting process_index_v3() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,12 +67,15 @@ UT_array *process_index_v3(aaruformatContext *ctx)
|
|||||||
utarray_push_back(index_entries, &entry);
|
utarray_push_back(index_entries, &entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Read %d index entries from index block at position %llu", idx_header.entries, ctx->header.indexOffset);
|
||||||
return index_entries;
|
return index_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add entries from a subindex to the array of index entries
|
// Add entries from a subindex to the array of index entries
|
||||||
void add_subindex_entries(aaruformatContext *ctx, UT_array *index_entries, IndexEntry *subindex_entry)
|
void add_subindex_entries(aaruformatContext *ctx, UT_array *index_entries, IndexEntry *subindex_entry)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering add_subindex_entries(%p, %p, %p)", ctx, index_entries, subindex_entry);
|
||||||
|
|
||||||
IndexHeader3 subindex_header;
|
IndexHeader3 subindex_header;
|
||||||
IndexEntry entry;
|
IndexEntry entry;
|
||||||
|
|
||||||
@@ -81,7 +90,9 @@ void add_subindex_entries(aaruformatContext *ctx, UT_array *index_entries, Index
|
|||||||
// Check if the subindex header is valid
|
// Check if the subindex header is valid
|
||||||
if(subindex_header.identifier != IndexBlock3)
|
if(subindex_header.identifier != IndexBlock3)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Incorrect subindex identifier.\n");
|
FATAL("Incorrect subindex identifier.");
|
||||||
|
|
||||||
|
TRACE("Exiting add_subindex_entries() without adding entries");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,43 +108,60 @@ void add_subindex_entries(aaruformatContext *ctx, UT_array *index_entries, Index
|
|||||||
}
|
}
|
||||||
utarray_push_back(index_entries, &entry);
|
utarray_push_back(index_entries, &entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting add_subindex_entries() after adding %d entries", subindex_header.entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t verify_index_v3(aaruformatContext *ctx)
|
int32_t verify_index_v3(aaruformatContext *ctx)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering verify_index_v3(%p)", ctx);
|
||||||
|
|
||||||
size_t read_bytes = 0;
|
size_t read_bytes = 0;
|
||||||
IndexHeader3 index_header;
|
IndexHeader3 index_header;
|
||||||
uint64_t crc64 = 0;
|
uint64_t crc64 = 0;
|
||||||
IndexEntry *index_entries = NULL;
|
IndexEntry *index_entries = NULL;
|
||||||
|
|
||||||
if(ctx == NULL || ctx->imageStream == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(ctx == NULL || ctx->imageStream == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context or image stream.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v2() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
// This will traverse all blocks and check their CRC64 without uncompressing them
|
// This will traverse all blocks and check their CRC64 without uncompressing them
|
||||||
fprintf(stderr, "Checking index integrity at %llu.\n", ctx->header.indexOffset);
|
TRACE("Checking index integrity at %llu.", ctx->header.indexOffset);
|
||||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||||
|
|
||||||
// Read the index header
|
// Read the index header
|
||||||
|
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||||
read_bytes = fread(&index_header, 1, sizeof(IndexHeader3), ctx->imageStream);
|
read_bytes = fread(&index_header, 1, sizeof(IndexHeader3), ctx->imageStream);
|
||||||
|
|
||||||
if(read_bytes != sizeof(IndexHeader3))
|
if(read_bytes != sizeof(IndexHeader3))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read index header.\n");
|
FATAL("Could not read index header.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v3() = AARUF_ERROR_CANNOT_READ_HEADER");
|
||||||
return AARUF_ERROR_CANNOT_READ_HEADER;
|
return AARUF_ERROR_CANNOT_READ_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index_header.identifier != IndexBlock3)
|
if(index_header.identifier != IndexBlock3)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Incorrect index identifier.\n");
|
FATAL("Incorrect index identifier.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v3() = AARUF_ERROR_CANNOT_READ_INDEX");
|
||||||
return AARUF_ERROR_CANNOT_READ_INDEX;
|
return AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Index at %llu contains %d entries.\n", ctx->header.indexOffset, index_header.entries);
|
TRACE("Index at %llu contains %d entries.", ctx->header.indexOffset, index_header.entries);
|
||||||
|
|
||||||
index_entries = malloc(sizeof(IndexEntry) * index_header.entries);
|
index_entries = malloc(sizeof(IndexEntry) * index_header.entries);
|
||||||
|
|
||||||
if(index_entries == NULL)
|
if(index_entries == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for index entries.\n");
|
FATAL("Cannot allocate memory for index entries.");
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v3() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,8 +169,10 @@ int32_t verify_index_v3(aaruformatContext *ctx)
|
|||||||
|
|
||||||
if(read_bytes != sizeof(IndexEntry) * index_header.entries)
|
if(read_bytes != sizeof(IndexEntry) * index_header.entries)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read index entries.\n");
|
FATAL("Could not read index entries.");
|
||||||
free(index_entries);
|
free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v2() = AARUF_ERROR_CANNOT_READ_INDEX");
|
||||||
return AARUF_ERROR_CANNOT_READ_INDEX;
|
return AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,10 +183,13 @@ int32_t verify_index_v3(aaruformatContext *ctx)
|
|||||||
|
|
||||||
if(crc64 != index_header.crc64)
|
if(crc64 != index_header.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected index CRC 0x%16llX but got 0x%16llX.\n", index_header.crc64, crc64);
|
FATAL("Expected index CRC 0x%16llX but got 0x%16llX.", index_header.crc64, crc64);
|
||||||
free(index_entries);
|
free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v3() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting verify_index_v3() = AARUF_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
52
src/open.c
52
src/open.c
@@ -44,48 +44,65 @@ void *aaruf_open(const char *filepath)
|
|||||||
slog_init("aaruformat.log", SLOG_FLAGS_ALL, 0);
|
slog_init("aaruformat.log", SLOG_FLAGS_ALL, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TRACE("Logging initialized");
|
||||||
|
|
||||||
|
TRACE("Entering aaruf_open(%s)", filepath);
|
||||||
|
|
||||||
|
TRACE("Allocating memory for context");
|
||||||
ctx = (aaruformatContext *)malloc(sizeof(aaruformatContext));
|
ctx = (aaruformatContext *)malloc(sizeof(aaruformatContext));
|
||||||
memset(ctx, 0, sizeof(aaruformatContext));
|
memset(ctx, 0, sizeof(aaruformatContext));
|
||||||
|
|
||||||
if(ctx == NULL)
|
if(ctx == NULL)
|
||||||
{
|
{
|
||||||
|
FATAL("Not enough memory to create context");
|
||||||
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Opening file %s", filepath);
|
||||||
ctx->imageStream = fopen(filepath, "rb");
|
ctx->imageStream = fopen(filepath, "rb");
|
||||||
|
|
||||||
if(ctx->imageStream == NULL)
|
if(ctx->imageStream == NULL)
|
||||||
{
|
{
|
||||||
|
FATAL("Error %d opening file %s for reading", errno, filepath);
|
||||||
errorNo = errno;
|
errorNo = errno;
|
||||||
free(ctx);
|
free(ctx);
|
||||||
errno = errorNo;
|
errno = errorNo;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Reading header at position 0");
|
||||||
fseek(ctx->imageStream, 0, SEEK_SET);
|
fseek(ctx->imageStream, 0, SEEK_SET);
|
||||||
readBytes = fread(&ctx->header, 1, sizeof(AaruHeader), ctx->imageStream);
|
readBytes = fread(&ctx->header, 1, sizeof(AaruHeader), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(AaruHeader))
|
if(readBytes != sizeof(AaruHeader))
|
||||||
{
|
{
|
||||||
|
FATAL("Could not read header");
|
||||||
free(ctx);
|
free(ctx);
|
||||||
errno = AARUF_ERROR_FILE_TOO_SMALL;
|
errno = AARUF_ERROR_FILE_TOO_SMALL;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->header.identifier != DIC_MAGIC && ctx->header.identifier != AARU_MAGIC)
|
if(ctx->header.identifier != DIC_MAGIC && ctx->header.identifier != AARU_MAGIC)
|
||||||
{
|
{
|
||||||
|
FATAL("Incorrect identifier for AaruFormat file: %8.8s", (char *)&ctx->header.identifier);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
errno = AARUF_ERROR_NOT_AARUFORMAT;
|
errno = AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read new header version
|
// Read new header version
|
||||||
if(ctx->header.imageMajorVersion >= AARUF_VERSION_V2)
|
if(ctx->header.imageMajorVersion >= AARUF_VERSION_V2)
|
||||||
{
|
{
|
||||||
|
TRACE("Reading new header version at position 0");
|
||||||
fseek(ctx->imageStream, 0, SEEK_SET);
|
fseek(ctx->imageStream, 0, SEEK_SET);
|
||||||
readBytes = fread(&ctx->header, 1, sizeof(AaruHeaderV2), ctx->imageStream);
|
readBytes = fread(&ctx->header, 1, sizeof(AaruHeaderV2), ctx->imageStream);
|
||||||
|
|
||||||
@@ -100,26 +117,33 @@ void *aaruf_open(const char *filepath)
|
|||||||
|
|
||||||
if(ctx->header.imageMajorVersion > AARUF_VERSION)
|
if(ctx->header.imageMajorVersion > AARUF_VERSION)
|
||||||
{
|
{
|
||||||
|
FATAL("Incompatible AaruFormat version %d.%d found, maximum supported is %d.%d", ctx->header.imageMajorVersion,
|
||||||
|
ctx->header.imageMinorVersion, AARUF_VERSION_V2, 0);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
errno = AARUF_ERROR_INCOMPATIBLE_VERSION;
|
errno = AARUF_ERROR_INCOMPATIBLE_VERSION;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Opening image version %d.%d\n", ctx->header.imageMajorVersion, ctx->header.imageMinorVersion);
|
TRACE("Opening image version %d.%d", ctx->header.imageMajorVersion, ctx->header.imageMinorVersion);
|
||||||
|
|
||||||
|
TRACE("Allocating memory for readable sector tags bitmap");
|
||||||
ctx->readableSectorTags = (bool *)malloc(sizeof(bool) * MaxSectorTag);
|
ctx->readableSectorTags = (bool *)malloc(sizeof(bool) * MaxSectorTag);
|
||||||
|
|
||||||
if(ctx->readableSectorTags == NULL)
|
if(ctx->readableSectorTags == NULL)
|
||||||
{
|
{
|
||||||
|
FATAL("Could not allocate memory for readable sector tags bitmap");
|
||||||
free(ctx);
|
free(ctx);
|
||||||
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(ctx->readableSectorTags, 0, sizeof(bool) * MaxSectorTag);
|
memset(ctx->readableSectorTags, 0, sizeof(bool) * MaxSectorTag);
|
||||||
|
|
||||||
|
TRACE("Setting up image info");
|
||||||
ctx->imageInfo.Application = ctx->header.application;
|
ctx->imageInfo.Application = ctx->header.application;
|
||||||
ctx->imageInfo.ApplicationVersion = (uint8_t *)malloc(32);
|
ctx->imageInfo.ApplicationVersion = (uint8_t *)malloc(32);
|
||||||
if(ctx->imageInfo.ApplicationVersion != NULL)
|
if(ctx->imageInfo.ApplicationVersion != NULL)
|
||||||
@@ -137,6 +161,7 @@ void *aaruf_open(const char *filepath)
|
|||||||
ctx->imageInfo.MediaType = ctx->header.mediaType;
|
ctx->imageInfo.MediaType = ctx->header.mediaType;
|
||||||
|
|
||||||
// Read the index header
|
// Read the index header
|
||||||
|
TRACE("Reading index header at position %" PRIu64, ctx->header.indexOffset);
|
||||||
pos = fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
pos = fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||||
if(pos < 0)
|
if(pos < 0)
|
||||||
{
|
{
|
||||||
@@ -160,9 +185,11 @@ void *aaruf_open(const char *filepath)
|
|||||||
if(readBytes != sizeof(uint32_t) ||
|
if(readBytes != sizeof(uint32_t) ||
|
||||||
(signature != IndexBlock && signature != IndexBlock2 && signature != IndexBlock3))
|
(signature != IndexBlock && signature != IndexBlock2 && signature != IndexBlock3))
|
||||||
{
|
{
|
||||||
|
FATAL("Could not read index header or incorrect identifier %4.4s", (char *)&signature);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
errno = AARUF_ERROR_CANNOT_READ_INDEX;
|
errno = AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,20 +202,21 @@ void *aaruf_open(const char *filepath)
|
|||||||
|
|
||||||
if(index_entries == NULL)
|
if(index_entries == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not process index.\n");
|
FATAL("Could not process index.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
errno = AARUF_ERROR_CANNOT_READ_INDEX;
|
errno = AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Index at %" PRIu64 " contains %d entries\n", ctx->header.indexOffset, utarray_len(index_entries));
|
TRACE("Index at %" PRIu64 " contains %d entries", ctx->header.indexOffset, utarray_len(index_entries));
|
||||||
|
|
||||||
for(i = 0; i < utarray_len(index_entries); i++)
|
for(i = 0; i < utarray_len(index_entries); i++)
|
||||||
{
|
{
|
||||||
IndexEntry *entry = (IndexEntry *)utarray_eltptr(index_entries, i);
|
IndexEntry *entry = (IndexEntry *)utarray_eltptr(index_entries, i);
|
||||||
TRACE("Block type %4.4s with data type %d is indexed to be at %" PRIu64 "\n", (char *)&entry->blockType,
|
TRACE("Block type %4.4s with data type %d is indexed to be at %" PRIu64 "", (char *)&entry->blockType,
|
||||||
entry->dataType, entry->offset);
|
entry->dataType, entry->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,13 +229,13 @@ void *aaruf_open(const char *filepath)
|
|||||||
|
|
||||||
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
TRACE("Could not seek to %" PRIu64 " as indicated by index entry %d, continuing...", entry->offset, i);
|
||||||
"libaaruformat: Could not seek to %" PRIu64 " as indicated by index entry %d, continuing...\n",
|
|
||||||
entry->offset, i);
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Processing block type %4.4s with data type %d at position %" PRIu64 "", (char *)&entry->blockType,
|
||||||
|
entry->dataType, entry->offset);
|
||||||
switch(entry->blockType)
|
switch(entry->blockType)
|
||||||
{
|
{
|
||||||
case DataBlock:
|
case DataBlock:
|
||||||
@@ -276,8 +304,7 @@ void *aaruf_open(const char *filepath)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,
|
TRACE("Unhandled block type %4.4s with data type %d is indexed to be at %" PRIu64 "",
|
||||||
"libaaruformat: Unhandled block type %4.4s with data type %d is indexed to be at %" PRIu64 "\n",
|
|
||||||
(char *)&entry->blockType, entry->dataType, entry->offset);
|
(char *)&entry->blockType, entry->dataType, entry->offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -287,8 +314,10 @@ void *aaruf_open(const char *filepath)
|
|||||||
|
|
||||||
if(!foundUserDataDdt)
|
if(!foundUserDataDdt)
|
||||||
{
|
{
|
||||||
FATAL("Could not find user data deduplication table, aborting...\n");
|
FATAL("Could not find user data deduplication table, aborting...");
|
||||||
aaruf_close(ctx);
|
aaruf_close(ctx);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,6 +333,7 @@ void *aaruf_open(const char *filepath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize caches
|
// Initialize caches
|
||||||
|
TRACE("Initializing caches");
|
||||||
ctx->blockHeaderCache.cache = NULL;
|
ctx->blockHeaderCache.cache = NULL;
|
||||||
ctx->blockHeaderCache.max_items = MAX_CACHE_SIZE / (ctx->imageInfo.SectorSize * (1 << ctx->shift));
|
ctx->blockHeaderCache.max_items = MAX_CACHE_SIZE / (ctx->imageInfo.SectorSize * (1 << ctx->shift));
|
||||||
ctx->blockCache.cache = NULL;
|
ctx->blockCache.cache = NULL;
|
||||||
@@ -312,11 +342,13 @@ void *aaruf_open(const char *filepath)
|
|||||||
// TODO: Cache tracks and sessions?
|
// TODO: Cache tracks and sessions?
|
||||||
|
|
||||||
// Initialize ECC for Compact Disc
|
// Initialize ECC for Compact Disc
|
||||||
|
TRACE("Initializing ECC for Compact Disc");
|
||||||
ctx->eccCdContext = (CdEccContext *)aaruf_ecc_cd_init();
|
ctx->eccCdContext = (CdEccContext *)aaruf_ecc_cd_init();
|
||||||
|
|
||||||
ctx->magic = AARU_MAGIC;
|
ctx->magic = AARU_MAGIC;
|
||||||
ctx->libraryMajorVersion = LIBAARUFORMAT_MAJOR_VERSION;
|
ctx->libraryMajorVersion = LIBAARUFORMAT_MAJOR_VERSION;
|
||||||
ctx->libraryMinorVersion = LIBAARUFORMAT_MINOR_VERSION;
|
ctx->libraryMinorVersion = LIBAARUFORMAT_MINOR_VERSION;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = %p", ctx);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
@@ -25,8 +25,12 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "structs/options.h"
|
#include "structs/options.h"
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
aaru_options parse_options(const char *options)
|
aaru_options parse_options(const char *options)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_open(%s)", options);
|
||||||
|
|
||||||
aaru_options parsed = {.compress = true,
|
aaru_options parsed = {.compress = true,
|
||||||
.deduplicate = true,
|
.deduplicate = true,
|
||||||
.dictionary = 33554432,
|
.dictionary = 33554432,
|
||||||
@@ -93,5 +97,9 @@ aaru_options parse_options(const char *options)
|
|||||||
token = strtok(NULL, ";");
|
token = strtok(NULL, ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = {compress: %d, deduplicate: %d, dictionary: %u, table_shift: %u, "
|
||||||
|
"data_shift: %u, block_alignment: %u, md5: %d, sha1: %d, sha256: %d, blake3: %d, spamsum: %d}",
|
||||||
|
parsed.compress, parsed.deduplicate, parsed.dictionary, parsed.table_shift, parsed.data_shift,
|
||||||
|
parsed.block_alignment, parsed.md5, parsed.sha1, parsed.sha256, parsed.blake3, parsed.spamsum);
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
291
src/read.c
291
src/read.c
@@ -22,41 +22,65 @@
|
|||||||
#include <aaruformat.h>
|
#include <aaruformat.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
int32_t aaruf_read_media_tag(void *context, uint8_t *data, int32_t tag, uint32_t *length)
|
int32_t aaruf_read_media_tag(void *context, uint8_t *data, int32_t tag, uint32_t *length)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_read_media_tag(%p, %p, %d, %u)", context, data, tag, *length);
|
||||||
|
|
||||||
aaruformatContext *ctx;
|
aaruformatContext *ctx;
|
||||||
mediaTagEntry *item;
|
mediaTagEntry *item;
|
||||||
|
|
||||||
if(context == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(context == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
TRACE("Exiting aaruf_read_media_tag() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = context;
|
ctx = context;
|
||||||
|
|
||||||
// Not a libaaruformat context
|
// Not a libaaruformat context
|
||||||
if(ctx->magic != AARU_MAGIC) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(ctx->magic != AARU_MAGIC)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
TRACE("Exiting aaruf_read_media_tag() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Finding media tag %d", tag);
|
||||||
HASH_FIND_INT(ctx->mediaTags, &tag, item);
|
HASH_FIND_INT(ctx->mediaTags, &tag, item);
|
||||||
|
|
||||||
if(item == NULL)
|
if(item == NULL)
|
||||||
{
|
{
|
||||||
|
TRACE("Media tag not found");
|
||||||
*length = 0;
|
*length = 0;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_media_tag() = AARUF_ERROR_MEDIA_TAG_NOT_PRESENT");
|
||||||
return AARUF_ERROR_MEDIA_TAG_NOT_PRESENT;
|
return AARUF_ERROR_MEDIA_TAG_NOT_PRESENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data == NULL || *length < item->length)
|
if(data == NULL || *length < item->length)
|
||||||
{
|
{
|
||||||
|
TRACE("Buffer too small for media tag %d, required %u bytes", tag, item->length);
|
||||||
*length = item->length;
|
*length = item->length;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_media_tag() = AARUF_ERROR_BUFFER_TOO_SMALL");
|
||||||
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*length = item->length;
|
*length = item->length;
|
||||||
memcpy(data, item->data, item->length);
|
memcpy(data, item->data, item->length);
|
||||||
|
|
||||||
|
TRACE("Media tag %d read successfully, length %u", tag, *length);
|
||||||
|
TRACE("Exiting aaruf_read_media_tag() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t aaruf_read_sector(void *context, uint64_t sectorAddress, uint8_t *data, uint32_t *length)
|
int32_t aaruf_read_sector(void *context, uint64_t sectorAddress, uint8_t *data, uint32_t *length)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_read_sector(%p, %" PRIu64 ", %p, %u)", context, sectorAddress, data, *length);
|
||||||
|
|
||||||
aaruformatContext *ctx = NULL;
|
aaruformatContext *ctx = NULL;
|
||||||
uint64_t offset = 0;
|
uint64_t offset = 0;
|
||||||
uint64_t blockOffset = 0;
|
uint64_t blockOffset = 0;
|
||||||
@@ -69,44 +93,86 @@ int32_t aaruf_read_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
|||||||
int errorNo = 0;
|
int errorNo = 0;
|
||||||
uint8_t sectorStatus = 0;
|
uint8_t sectorStatus = 0;
|
||||||
|
|
||||||
if(context == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(context == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = context;
|
ctx = context;
|
||||||
|
|
||||||
// Not a libaaruformat context
|
// Not a libaaruformat context
|
||||||
if(ctx->magic != AARU_MAGIC) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(ctx->magic != AARU_MAGIC)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
if(sectorAddress > ctx->imageInfo.Sectors - 1) return AARUF_ERROR_SECTOR_OUT_OF_BOUNDS;
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sectorAddress > ctx->imageInfo.Sectors - 1)
|
||||||
|
{
|
||||||
|
FATAL("Sector address out of bounds");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
|
||||||
|
return AARUF_ERROR_SECTOR_OUT_OF_BOUNDS;
|
||||||
|
}
|
||||||
|
|
||||||
if(ctx->ddtVersion == 1)
|
if(ctx->ddtVersion == 1)
|
||||||
errorNo = decode_ddt_entry_v1(ctx, sectorAddress, &offset, &blockOffset, §orStatus);
|
errorNo = decode_ddt_entry_v1(ctx, sectorAddress, &offset, &blockOffset, §orStatus);
|
||||||
else if(ctx->ddtVersion == 2)
|
else if(ctx->ddtVersion == 2)
|
||||||
errorNo = decode_ddt_entry_v2(ctx, sectorAddress, &offset, &blockOffset, §orStatus);
|
errorNo = decode_ddt_entry_v2(ctx, sectorAddress, &offset, &blockOffset, §orStatus);
|
||||||
|
|
||||||
if(errorNo != AARUF_STATUS_OK) return errorNo;
|
if(errorNo != AARUF_STATUS_OK)
|
||||||
|
{
|
||||||
|
FATAL("Error %d decoding DDT entry", errorNo);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = %d", errorNo);
|
||||||
|
return errorNo;
|
||||||
|
}
|
||||||
|
|
||||||
// Partially written image... as we can't know the real sector size just assume it's common :/
|
// Partially written image... as we can't know the real sector size just assume it's common :/
|
||||||
if(sectorStatus == SectorStatusNotDumped)
|
if(sectorStatus == SectorStatusNotDumped)
|
||||||
{
|
{
|
||||||
memset(data, 0, ctx->imageInfo.SectorSize);
|
memset(data, 0, ctx->imageInfo.SectorSize);
|
||||||
*length = ctx->imageInfo.SectorSize;
|
*length = ctx->imageInfo.SectorSize;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_STATUS_SECTOR_NOT_DUMPED");
|
||||||
return AARUF_STATUS_SECTOR_NOT_DUMPED;
|
return AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if block header is cached
|
// Check if block header is cached
|
||||||
|
TRACE("Checking if block header is cached");
|
||||||
blockHeader = find_in_cache_uint64(&ctx->blockHeaderCache, blockOffset);
|
blockHeader = find_in_cache_uint64(&ctx->blockHeaderCache, blockOffset);
|
||||||
|
|
||||||
// Read block header
|
// Read block header
|
||||||
if(blockHeader == NULL)
|
if(blockHeader == NULL)
|
||||||
{
|
{
|
||||||
|
TRACE("Allocating memory for block header");
|
||||||
blockHeader = malloc(sizeof(BlockHeader));
|
blockHeader = malloc(sizeof(BlockHeader));
|
||||||
if(blockHeader == NULL) return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
if(blockHeader == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Not enough memory for block header");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Reading block header");
|
||||||
fseek(ctx->imageStream, blockOffset, SEEK_SET);
|
fseek(ctx->imageStream, blockOffset, SEEK_SET);
|
||||||
readBytes = fread(blockHeader, 1, sizeof(BlockHeader), ctx->imageStream);
|
readBytes = fread(blockHeader, 1, sizeof(BlockHeader), ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != sizeof(BlockHeader)) return AARUF_ERROR_CANNOT_READ_HEADER;
|
if(readBytes != sizeof(BlockHeader))
|
||||||
|
{
|
||||||
|
FATAL("Error reading block header");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_HEADER");
|
||||||
|
return AARUF_ERROR_CANNOT_READ_HEADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Adding block header to cache");
|
||||||
add_to_cache_uint64(&ctx->blockHeaderCache, blockOffset, blockHeader);
|
add_to_cache_uint64(&ctx->blockHeaderCache, blockOffset, blockHeader);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -114,17 +180,24 @@ int32_t aaruf_read_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
|||||||
|
|
||||||
if(data == NULL || *length < blockHeader->sectorSize)
|
if(data == NULL || *length < blockHeader->sectorSize)
|
||||||
{
|
{
|
||||||
|
TRACE("Buffer too small for sector, required %u bytes", blockHeader->sectorSize);
|
||||||
*length = blockHeader->sectorSize;
|
*length = blockHeader->sectorSize;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_BUFFER_TOO_SMALL");
|
||||||
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if block is cached
|
// Check if block is cached
|
||||||
|
TRACE("Checking if block is cached");
|
||||||
block = find_in_cache_uint64(&ctx->blockCache, blockOffset);
|
block = find_in_cache_uint64(&ctx->blockCache, blockOffset);
|
||||||
|
|
||||||
if(block != NULL)
|
if(block != NULL)
|
||||||
{
|
{
|
||||||
|
TRACE("Getting data from cache");
|
||||||
memcpy(data, block + offset, blockHeader->sectorSize);
|
memcpy(data, block + offset, blockHeader->sectorSize);
|
||||||
*length = blockHeader->sectorSize;
|
*length = blockHeader->sectorSize;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,33 +205,50 @@ int32_t aaruf_read_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
|||||||
switch(blockHeader->compression)
|
switch(blockHeader->compression)
|
||||||
{
|
{
|
||||||
case None:
|
case None:
|
||||||
|
TRACE("Allocating memory for block");
|
||||||
block = (uint8_t *)malloc(blockHeader->length);
|
block = (uint8_t *)malloc(blockHeader->length);
|
||||||
if(block == NULL) return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
if(block == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Not enough memory for block");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Reading block into memory");
|
||||||
readBytes = fread(block, 1, blockHeader->length, ctx->imageStream);
|
readBytes = fread(block, 1, blockHeader->length, ctx->imageStream);
|
||||||
|
|
||||||
if(readBytes != blockHeader->length)
|
if(readBytes != blockHeader->length)
|
||||||
{
|
{
|
||||||
|
FATAL("Could not read block");
|
||||||
free(block);
|
free(block);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Lzma:
|
case Lzma:
|
||||||
lzmaSize = blockHeader->cmpLength - LZMA_PROPERTIES_LENGTH;
|
lzmaSize = blockHeader->cmpLength - LZMA_PROPERTIES_LENGTH;
|
||||||
|
TRACE("Allocating memory for compressed data of size %zu bytes", lzmaSize);
|
||||||
cmpData = malloc(lzmaSize);
|
cmpData = malloc(lzmaSize);
|
||||||
|
|
||||||
if(cmpData == NULL)
|
if(cmpData == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for block...\n");
|
FATAL("Cannot allocate memory for block...");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Allocating memory for block of size %zu bytes", blockHeader->length);
|
||||||
block = malloc(blockHeader->length);
|
block = malloc(blockHeader->length);
|
||||||
if(block == NULL)
|
if(block == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for block...\n");
|
FATAL("Cannot allocate memory for block...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,38 +256,47 @@ int32_t aaruf_read_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
|||||||
|
|
||||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read LZMA properties...\n");
|
FATAL("Could not read LZMA properties...");
|
||||||
free(block);
|
free(block);
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||||
if(readBytes != lzmaSize)
|
if(readBytes != lzmaSize)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read compressed block...\n");
|
FATAL("Could not read compressed block...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(block);
|
free(block);
|
||||||
break;
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Decompressing block of size %zu bytes", blockHeader->length);
|
||||||
readBytes = blockHeader->length;
|
readBytes = blockHeader->length;
|
||||||
errorNo =
|
errorNo =
|
||||||
aaruf_lzma_decode_buffer(block, &readBytes, cmpData, &lzmaSize, lzmaProperties, LZMA_PROPERTIES_LENGTH);
|
aaruf_lzma_decode_buffer(block, &readBytes, cmpData, &lzmaSize, lzmaProperties, LZMA_PROPERTIES_LENGTH);
|
||||||
|
|
||||||
if(errorNo != 0)
|
if(errorNo != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Got error %d from LZMA...\n", errorNo);
|
FATAL("Got error %d from LZMA...", errorNo);
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(block);
|
free(block);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(readBytes != blockHeader->length)
|
if(readBytes != blockHeader->length)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error decompressing block, should be {0} bytes but got {1} bytes...\n");
|
FATAL("Error decompressing block, should be {0} bytes but got {1} bytes...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(block);
|
free(block);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,38 +304,50 @@ int32_t aaruf_read_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case Flac:
|
case Flac:
|
||||||
|
TRACE("Allocating memory for compressed data of size %zu bytes", blockHeader->cmpLength);
|
||||||
cmpData = malloc(blockHeader->cmpLength);
|
cmpData = malloc(blockHeader->cmpLength);
|
||||||
|
|
||||||
if(cmpData == NULL)
|
if(cmpData == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for block...\n");
|
FATAL("Cannot allocate memory for block...");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Allocating memory for block of size %zu bytes", blockHeader->length);
|
||||||
block = malloc(blockHeader->length);
|
block = malloc(blockHeader->length);
|
||||||
if(block == NULL)
|
if(block == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for block...\n");
|
FATAL("Cannot allocate memory for block...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Reading compressed data into memory");
|
||||||
readBytes = fread(cmpData, 1, blockHeader->cmpLength, ctx->imageStream);
|
readBytes = fread(cmpData, 1, blockHeader->cmpLength, ctx->imageStream);
|
||||||
if(readBytes != blockHeader->cmpLength)
|
if(readBytes != blockHeader->cmpLength)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read compressed block...\n");
|
FATAL("Could not read compressed block...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(block);
|
free(block);
|
||||||
break;
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Decompressing block of size %zu bytes", blockHeader->length);
|
||||||
readBytes = aaruf_flac_decode_redbook_buffer(block, blockHeader->length, cmpData, blockHeader->cmpLength);
|
readBytes = aaruf_flac_decode_redbook_buffer(block, blockHeader->length, cmpData, blockHeader->cmpLength);
|
||||||
|
|
||||||
if(readBytes != blockHeader->length)
|
if(readBytes != blockHeader->length)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error decompressing block, should be {0} bytes but got {1} bytes...\n");
|
FATAL("Error decompressing block, should be {0} bytes but got {1} bytes...");
|
||||||
free(cmpData);
|
free(cmpData);
|
||||||
free(block);
|
free(block);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,44 +355,70 @@ int32_t aaruf_read_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
FATAL("Unsupported compression %d", blockHeader->compression);
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_UNSUPPORTED_COMPRESSION");
|
||||||
return AARUF_ERROR_UNSUPPORTED_COMPRESSION;
|
return AARUF_ERROR_UNSUPPORTED_COMPRESSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add block to cache
|
// Add block to cache
|
||||||
|
TRACE("Adding block to cache");
|
||||||
add_to_cache_uint64(&ctx->blockCache, blockOffset, block);
|
add_to_cache_uint64(&ctx->blockCache, blockOffset, block);
|
||||||
|
|
||||||
memcpy(data, block + (offset * blockHeader->sectorSize), blockHeader->sectorSize);
|
memcpy(data, block + (offset * blockHeader->sectorSize), blockHeader->sectorSize);
|
||||||
*length = blockHeader->sectorSize;
|
*length = blockHeader->sectorSize;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t aaruf_read_track_sector(void *context, uint8_t *data, uint64_t sectorAddress, uint32_t *length, uint8_t track)
|
int32_t aaruf_read_track_sector(void *context, uint8_t *data, uint64_t sectorAddress, uint32_t *length, uint8_t track)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_read_track_sector(%p, %p, %" PRIu64 ", %u, %d)", context, data, sectorAddress, *length,
|
||||||
|
track);
|
||||||
|
|
||||||
aaruformatContext *ctx;
|
aaruformatContext *ctx;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(context == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(context == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_track_sector() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = context;
|
ctx = context;
|
||||||
|
|
||||||
// Not a libaaruformat context
|
// Not a libaaruformat context
|
||||||
if(ctx->magic != AARU_MAGIC) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(ctx->magic != AARU_MAGIC)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
if(ctx->imageInfo.XmlMediaType != OpticalDisc) return AARUF_ERROR_INCORRECT_MEDIA_TYPE;
|
TRACE("Exiting aaruf_read_track_sector() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx->imageInfo.XmlMediaType != OpticalDisc)
|
||||||
|
{
|
||||||
|
FATAL("Incorrect media type %d, expected OpticalDisc", ctx->imageInfo.XmlMediaType);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_track_sector() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
|
||||||
|
return AARUF_ERROR_INCORRECT_MEDIA_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
for(i = 0; i < ctx->numberOfDataTracks; i++)
|
for(i = 0; i < ctx->numberOfDataTracks; i++)
|
||||||
{
|
|
||||||
if(ctx->dataTracks[i].sequence == track)
|
if(ctx->dataTracks[i].sequence == track)
|
||||||
{
|
|
||||||
return aaruf_read_sector(context, ctx->dataTracks[i].start + sectorAddress, data, length);
|
return aaruf_read_sector(context, ctx->dataTracks[i].start + sectorAddress, data, length);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
TRACE("Track %d not found", track);
|
||||||
|
TRACE("Exiting aaruf_read_track_sector() = AARUF_ERROR_TRACK_NOT_FOUND");
|
||||||
return AARUF_ERROR_TRACK_NOT_FOUND;
|
return AARUF_ERROR_TRACK_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *data, uint32_t *length)
|
int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *data, uint32_t *length)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_read_sector_long(%p, %" PRIu64 ", %p, %u)", context, sectorAddress, data, *length);
|
||||||
|
|
||||||
aaruformatContext *ctx = NULL;
|
aaruformatContext *ctx = NULL;
|
||||||
uint32_t bareLength = 0;
|
uint32_t bareLength = 0;
|
||||||
uint32_t tagLength = 0;
|
uint32_t tagLength = 0;
|
||||||
@@ -291,12 +428,24 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
bool trkFound = false;
|
bool trkFound = false;
|
||||||
|
|
||||||
if(context == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(context == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = context;
|
ctx = context;
|
||||||
|
|
||||||
// Not a libaaruformat context
|
// Not a libaaruformat context
|
||||||
if(ctx->magic != AARU_MAGIC) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(ctx->magic != AARU_MAGIC)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
switch(ctx->imageInfo.XmlMediaType)
|
switch(ctx->imageInfo.XmlMediaType)
|
||||||
{
|
{
|
||||||
@@ -304,6 +453,9 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
if(*length < 2352 || data == NULL)
|
if(*length < 2352 || data == NULL)
|
||||||
{
|
{
|
||||||
*length = 2352;
|
*length = 2352;
|
||||||
|
FATAL("Buffer too small for sector, required %u bytes", *length);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
|
||||||
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
if((ctx->sectorSuffix == NULL || ctx->sectorPrefix == NULL) &&
|
if((ctx->sectorSuffix == NULL || ctx->sectorPrefix == NULL) &&
|
||||||
@@ -313,31 +465,44 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
bareLength = 0;
|
bareLength = 0;
|
||||||
aaruf_read_sector(context, sectorAddress, NULL, &bareLength);
|
aaruf_read_sector(context, sectorAddress, NULL, &bareLength);
|
||||||
|
|
||||||
|
TRACE("Allocating memory for bare data");
|
||||||
bareData = (uint8_t *)malloc(bareLength);
|
bareData = (uint8_t *)malloc(bareLength);
|
||||||
|
|
||||||
if(bareData == NULL) return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
if(bareData == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Could not allocate memory for bare data");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
res = aaruf_read_sector(context, sectorAddress, bareData, &bareLength);
|
res = aaruf_read_sector(context, sectorAddress, bareData, &bareLength);
|
||||||
|
|
||||||
if(res < AARUF_STATUS_OK)
|
if(res < AARUF_STATUS_OK)
|
||||||
{
|
{
|
||||||
free(bareData);
|
free(bareData);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = %d", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
trkFound = false;
|
trkFound = false;
|
||||||
|
|
||||||
for(i = 0; i < ctx->numberOfDataTracks; i++)
|
for(i = 0; i < ctx->numberOfDataTracks; i++)
|
||||||
{
|
|
||||||
if(sectorAddress >= ctx->dataTracks[i].start && sectorAddress <= ctx->dataTracks[i].end)
|
if(sectorAddress >= ctx->dataTracks[i].start && sectorAddress <= ctx->dataTracks[i].end)
|
||||||
{
|
{
|
||||||
trkFound = true;
|
trkFound = true;
|
||||||
trk = ctx->dataTracks[i];
|
trk = ctx->dataTracks[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(!trkFound) return AARUF_ERROR_TRACK_NOT_FOUND;
|
if(!trkFound)
|
||||||
|
{
|
||||||
|
FATAL("Track not found");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_TRACK_NOT_FOUND");
|
||||||
|
return AARUF_ERROR_TRACK_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
switch(trk.type)
|
switch(trk.type)
|
||||||
{
|
{
|
||||||
@@ -358,19 +523,18 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
res = AARUF_STATUS_OK;
|
res = AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
else if((ctx->sectorPrefixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
else if((ctx->sectorPrefixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
||||||
{
|
|
||||||
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
memcpy(data,
|
memcpy(data,
|
||||||
ctx->sectorPrefixCorrected +
|
ctx->sectorPrefixCorrected +
|
||||||
((ctx->sectorPrefixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 16,
|
((ctx->sectorPrefixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 16,
|
||||||
16);
|
16);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
|
||||||
return AARUF_ERROR_REACHED_UNREACHABLE_CODE;
|
return AARUF_ERROR_REACHED_UNREACHABLE_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
if(res != AARUF_STATUS_OK) return res;
|
if(res != AARUF_STATUS_OK) return res;
|
||||||
|
|
||||||
@@ -384,19 +548,18 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
res = AARUF_STATUS_OK;
|
res = AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
else if((ctx->sectorSuffixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
else if((ctx->sectorSuffixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
||||||
{
|
|
||||||
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
memcpy(data + 2064,
|
memcpy(data + 2064,
|
||||||
ctx->sectorSuffixCorrected +
|
ctx->sectorSuffixCorrected +
|
||||||
((ctx->sectorSuffixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 288,
|
((ctx->sectorSuffixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 288,
|
||||||
288);
|
288);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
|
||||||
return AARUF_ERROR_REACHED_UNREACHABLE_CODE;
|
return AARUF_ERROR_REACHED_UNREACHABLE_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
case CdMode2Formless:
|
case CdMode2Formless:
|
||||||
@@ -412,19 +575,18 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
res = AARUF_STATUS_OK;
|
res = AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
else if((ctx->sectorPrefixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
else if((ctx->sectorPrefixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
||||||
{
|
|
||||||
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
memcpy(data,
|
memcpy(data,
|
||||||
ctx->sectorPrefixCorrected +
|
ctx->sectorPrefixCorrected +
|
||||||
((ctx->sectorPrefixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 16,
|
((ctx->sectorPrefixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 16,
|
||||||
16);
|
16);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
|
||||||
return AARUF_ERROR_REACHED_UNREACHABLE_CODE;
|
return AARUF_ERROR_REACHED_UNREACHABLE_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
if(res != AARUF_STATUS_OK) return res;
|
if(res != AARUF_STATUS_OK) return res;
|
||||||
|
|
||||||
@@ -445,9 +607,7 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
aaruf_ecc_cd_reconstruct(ctx->eccCdContext, data, CdMode2Form2);
|
aaruf_ecc_cd_reconstruct(ctx->eccCdContext, data, CdMode2Form2);
|
||||||
}
|
}
|
||||||
else if((ctx->sectorSuffixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
else if((ctx->sectorSuffixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
||||||
{
|
|
||||||
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
// Mode 2 where ECC failed
|
// Mode 2 where ECC failed
|
||||||
memcpy(data + 24, bareData, 2328);
|
memcpy(data + 24, bareData, 2328);
|
||||||
@@ -462,6 +622,10 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
default:
|
default:
|
||||||
|
FATAL("Invalid track type %d", trk.type);
|
||||||
|
free(bareData);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_INVALID_TRACK_FORMAT");
|
||||||
return AARUF_ERROR_INVALID_TRACK_FORMAT;
|
return AARUF_ERROR_INVALID_TRACK_FORMAT;
|
||||||
}
|
}
|
||||||
case BlockMedia:
|
case BlockMedia:
|
||||||
@@ -490,6 +654,9 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
tagLength = 24;
|
tagLength = 24;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
FATAL("Unsupported media type %d", ctx->imageInfo.MediaType);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
|
||||||
return AARUF_ERROR_INCORRECT_MEDIA_TYPE;
|
return AARUF_ERROR_INCORRECT_MEDIA_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,27 +665,51 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
|||||||
if(*length < tagLength + bareLength || data == NULL)
|
if(*length < tagLength + bareLength || data == NULL)
|
||||||
{
|
{
|
||||||
*length = tagLength + bareLength;
|
*length = tagLength + bareLength;
|
||||||
|
FATAL("Buffer too small for sector, required %u bytes", *length);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
|
||||||
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Allocating memory for bare data of size %u bytes", bareLength);
|
||||||
bareData = malloc(bareLength);
|
bareData = malloc(bareLength);
|
||||||
|
|
||||||
if(bareData == NULL) return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
if(bareData == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Could not allocate memory for bare data");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
res = aaruf_read_sector(context, sectorAddress, bareData, &bareLength);
|
res = aaruf_read_sector(context, sectorAddress, bareData, &bareLength);
|
||||||
|
|
||||||
if(bareLength != 512) return res;
|
if(bareLength != 512)
|
||||||
|
{
|
||||||
|
FATAL("Bare data length is %u, expected 512", bareLength);
|
||||||
|
free(bareData);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = %d", res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(data, ctx->sectorSubchannel + sectorAddress * tagLength, tagLength);
|
memcpy(data, ctx->sectorSubchannel + sectorAddress * tagLength, tagLength);
|
||||||
memcpy(data, bareData, 512);
|
memcpy(data, bareData, 512);
|
||||||
|
|
||||||
free(bareData);
|
free(bareData);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = %d", res);
|
||||||
return res;
|
return res;
|
||||||
default:
|
default:
|
||||||
|
FATAL("Incorrect media type %d for long sector reading", ctx->imageInfo.MediaType);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
|
||||||
return AARUF_ERROR_INCORRECT_MEDIA_TYPE;
|
return AARUF_ERROR_INCORRECT_MEDIA_TYPE;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
FATAL("Incorrect media type %d for long sector reading", ctx->imageInfo.MediaType);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
|
||||||
return AARUF_ERROR_INCORRECT_MEDIA_TYPE;
|
return AARUF_ERROR_INCORRECT_MEDIA_TYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
120
src/verify.c
120
src/verify.c
@@ -20,12 +20,15 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "log.h"
|
||||||
#include "utarray.h"
|
#include "utarray.h"
|
||||||
|
|
||||||
#define VERIFY_SIZE 1048576
|
#define VERIFY_SIZE 1048576
|
||||||
|
|
||||||
int32_t aaruf_verify_image(void *context)
|
int32_t aaruf_verify_image(void *context)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_verify_image(%p)", context);
|
||||||
|
|
||||||
aaruformatContext *ctx = NULL;
|
aaruformatContext *ctx = NULL;
|
||||||
uint64_t crc64 = 0;
|
uint64_t crc64 = 0;
|
||||||
size_t read_bytes = 0;
|
size_t read_bytes = 0;
|
||||||
@@ -40,47 +43,74 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
UT_array *index_entries = NULL;
|
UT_array *index_entries = NULL;
|
||||||
int32_t err = 0;
|
int32_t err = 0;
|
||||||
|
|
||||||
if(context == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(context == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = context;
|
ctx = context;
|
||||||
|
|
||||||
// Not a libaaruformat context
|
// Not a libaaruformat context
|
||||||
if(ctx->magic != AARU_MAGIC) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(ctx->magic != AARU_MAGIC)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||||
|
|
||||||
|
TRACE("Reading index signature at position %llu", ctx->header.indexOffset);
|
||||||
read_bytes = fread(&signature, 1, sizeof(uint32_t), ctx->imageStream);
|
read_bytes = fread(&signature, 1, sizeof(uint32_t), ctx->imageStream);
|
||||||
if(read_bytes != sizeof(uint32_t))
|
if(read_bytes != sizeof(uint32_t))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read index signature.\n");
|
FATAL("Could not read index signature.");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_HEADER");
|
||||||
return AARUF_ERROR_CANNOT_READ_HEADER;
|
return AARUF_ERROR_CANNOT_READ_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(signature != IndexBlock && signature != IndexBlock2 && signature != IndexBlock3)
|
if(signature != IndexBlock && signature != IndexBlock2 && signature != IndexBlock3)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Incorrect index signature.\n");
|
FATAL("Incorrect index signature %4.4s", (char *)&signature);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_INDEX");
|
||||||
return AARUF_ERROR_CANNOT_READ_INDEX;
|
return AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the index is correct
|
// Check if the index is correct
|
||||||
if(signature == IndexBlock) err = verify_index_v1(ctx);
|
if(signature == IndexBlock)
|
||||||
else if(signature == IndexBlock2) err = verify_index_v2(ctx);
|
err = verify_index_v1(ctx);
|
||||||
else if(signature == IndexBlock3) err = verify_index_v3(ctx);
|
else if(signature == IndexBlock2)
|
||||||
|
err = verify_index_v2(ctx);
|
||||||
|
else if(signature == IndexBlock3)
|
||||||
|
err = verify_index_v3(ctx);
|
||||||
|
|
||||||
if(err != AARUF_STATUS_OK)
|
if(err != AARUF_STATUS_OK)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Index verification failed with error code %d.\n", err);
|
FATAL("Index verification failed with error code %d.", err);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the index
|
// Process the index
|
||||||
if(signature == IndexBlock) index_entries = process_index_v1(ctx);
|
if(signature == IndexBlock)
|
||||||
else if(signature == IndexBlock2) index_entries = process_index_v2(ctx);
|
index_entries = process_index_v1(ctx);
|
||||||
else if(signature == IndexBlock3) index_entries = process_index_v3(ctx);
|
else if(signature == IndexBlock2)
|
||||||
|
index_entries = process_index_v2(ctx);
|
||||||
|
else if(signature == IndexBlock3)
|
||||||
|
index_entries = process_index_v3(ctx);
|
||||||
|
|
||||||
if(index_entries == NULL)
|
if(index_entries == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not process index.\n");
|
FATAL("Could not process index.");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_INDEX");
|
||||||
return AARUF_ERROR_CANNOT_READ_INDEX;
|
return AARUF_ERROR_CANNOT_READ_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,27 +118,31 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
|
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot allocate memory for buffer.\n");
|
FATAL("Cannot allocate memory for buffer.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < utarray_len(index_entries); i++)
|
for(int i = 0; i < utarray_len(index_entries); i++)
|
||||||
{
|
{
|
||||||
IndexEntry *entry = (IndexEntry *)utarray_eltptr(index_entries, i);
|
IndexEntry *entry = (IndexEntry *)utarray_eltptr(index_entries, i);
|
||||||
fprintf(stderr, "Checking block with type %4.4s at position %" PRIu64 "\n", (char *)&entry->blockType,
|
TRACE("Checking block with type %4.4s at position %" PRIu64 "", (char *)&entry->blockType, entry->offset);
|
||||||
entry->offset);
|
|
||||||
|
|
||||||
fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||||
|
|
||||||
switch(entry->blockType)
|
switch(entry->blockType)
|
||||||
{
|
{
|
||||||
case DataBlock:
|
case DataBlock:
|
||||||
|
TRACE("Reading block header");
|
||||||
read_bytes = fread(&block_header, 1, sizeof(BlockHeader), ctx->imageStream);
|
read_bytes = fread(&block_header, 1, sizeof(BlockHeader), ctx->imageStream);
|
||||||
if(read_bytes != sizeof(BlockHeader))
|
if(read_bytes != sizeof(BlockHeader))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read block header.\n");
|
FATAL("Could not read block header.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,13 +150,16 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL("Could not initialize CRC64.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
verified_bytes = 0;
|
verified_bytes = 0;
|
||||||
|
|
||||||
|
TRACE("Calculating CRC64...");
|
||||||
while(verified_bytes + VERIFY_SIZE < block_header.cmpLength)
|
while(verified_bytes + VERIFY_SIZE < block_header.cmpLength)
|
||||||
{
|
{
|
||||||
read_bytes = fread(buffer, 1, VERIFY_SIZE, ctx->imageStream);
|
read_bytes = fread(buffer, 1, VERIFY_SIZE, ctx->imageStream);
|
||||||
@@ -140,18 +177,23 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
|
|
||||||
if(crc64 != block_header.cmpCrc64)
|
if(crc64 != block_header.cmpCrc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected block CRC 0x%16llX but got 0x%16llX.\n", block_header.cmpCrc64, crc64);
|
FATAL("Expected block CRC 0x%16llX but got 0x%16llX.", block_header.cmpCrc64, crc64);
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DeDuplicationTable:
|
case DeDuplicationTable:
|
||||||
|
TRACE("Reading DDT header");
|
||||||
read_bytes = fread(&ddt_header, 1, sizeof(DdtHeader), ctx->imageStream);
|
read_bytes = fread(&ddt_header, 1, sizeof(DdtHeader), ctx->imageStream);
|
||||||
if(read_bytes != sizeof(DdtHeader))
|
if(read_bytes != sizeof(DdtHeader))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read DDT header.\n");
|
FATAL("Could not read DDT header.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,13 +201,16 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL("Could not initialize CRC64.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
verified_bytes = 0;
|
verified_bytes = 0;
|
||||||
|
|
||||||
|
TRACE("Calculating DDT CRC64...");
|
||||||
while(verified_bytes + VERIFY_SIZE < ddt_header.cmpLength)
|
while(verified_bytes + VERIFY_SIZE < ddt_header.cmpLength)
|
||||||
{
|
{
|
||||||
read_bytes = fread(buffer, 1, VERIFY_SIZE, ctx->imageStream);
|
read_bytes = fread(buffer, 1, VERIFY_SIZE, ctx->imageStream);
|
||||||
@@ -183,18 +228,23 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
|
|
||||||
if(crc64 != ddt_header.cmpCrc64)
|
if(crc64 != ddt_header.cmpCrc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected DDT CRC 0x%16llX but got 0x%16llX.\n", ddt_header.cmpCrc64, crc64);
|
FATAL("Expected DDT CRC 0x%16llX but got 0x%16llX.", ddt_header.cmpCrc64, crc64);
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DeDuplicationTable2:
|
case DeDuplicationTable2:
|
||||||
|
TRACE("Reading DDT2 header");
|
||||||
read_bytes = fread(&ddt2_header, 1, sizeof(DdtHeader2), ctx->imageStream);
|
read_bytes = fread(&ddt2_header, 1, sizeof(DdtHeader2), ctx->imageStream);
|
||||||
if(read_bytes != sizeof(DdtHeader2))
|
if(read_bytes != sizeof(DdtHeader2))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read DDT header.\n");
|
FATAL("Could not read DDT header.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,13 +252,16 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL("Could not initialize CRC64.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
verified_bytes = 0;
|
verified_bytes = 0;
|
||||||
|
|
||||||
|
TRACE("Calculating DDT2 CRC64...");
|
||||||
while(verified_bytes + VERIFY_SIZE < ddt2_header.cmpLength)
|
while(verified_bytes + VERIFY_SIZE < ddt2_header.cmpLength)
|
||||||
{
|
{
|
||||||
read_bytes = fread(buffer, 1, VERIFY_SIZE, ctx->imageStream);
|
read_bytes = fread(buffer, 1, VERIFY_SIZE, ctx->imageStream);
|
||||||
@@ -223,18 +276,23 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
|
|
||||||
if(crc64 != ddt2_header.cmpCrc64)
|
if(crc64 != ddt2_header.cmpCrc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected DDT CRC 0x%16llX but got 0x%16llX.\n", ddt2_header.cmpCrc64, crc64);
|
FATAL("Expected DDT CRC 0x%16llX but got 0x%16llX.", ddt2_header.cmpCrc64, crc64);
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TracksBlock:
|
case TracksBlock:
|
||||||
|
TRACE("Reading tracks header");
|
||||||
read_bytes = fread(&tracks_header, 1, sizeof(TracksHeader), ctx->imageStream);
|
read_bytes = fread(&tracks_header, 1, sizeof(TracksHeader), ctx->imageStream);
|
||||||
if(read_bytes != sizeof(TracksHeader))
|
if(read_bytes != sizeof(TracksHeader))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not read tracks header.\n");
|
FATAL("Could not read tracks header.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,11 +300,14 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
|
|
||||||
if(crc64_context == NULL)
|
if(crc64_context == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
FATAL("Could not initialize CRC64.");
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Calculating tracks CRC64...");
|
||||||
read_bytes = fread(buffer, 1, tracks_header.entries * sizeof(TrackEntry), ctx->imageStream);
|
read_bytes = fread(buffer, 1, tracks_header.entries * sizeof(TrackEntry), ctx->imageStream);
|
||||||
aaruf_crc64_update(crc64_context, buffer, read_bytes);
|
aaruf_crc64_update(crc64_context, buffer, read_bytes);
|
||||||
|
|
||||||
@@ -257,17 +318,20 @@ int32_t aaruf_verify_image(void *context)
|
|||||||
|
|
||||||
if(crc64 != tracks_header.crc64)
|
if(crc64 != tracks_header.crc64)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Expected DDT CRC 0x%16llX but got 0x%16llX.\n", tracks_header.crc64, crc64);
|
FATAL("Expected DDT CRC 0x%16llX but got 0x%16llX.", tracks_header.crc64, crc64);
|
||||||
utarray_free(index_entries);
|
utarray_free(index_entries);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Ignoring block type %4.4s.\n", (char *)&entry->blockType);
|
TRACE("Ignoring block type %4.4s.", (char *)&entry->blockType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_verify_image() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
59
src/write.c
59
src/write.c
@@ -24,19 +24,41 @@
|
|||||||
|
|
||||||
#include "aaruformat.h"
|
#include "aaruformat.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
int32_t aaruf_write_sector(void *context, uint64_t sectorAddress, uint8_t *data, uint8_t sectorStatus, uint32_t length)
|
int32_t aaruf_write_sector(void *context, uint64_t sectorAddress, uint8_t *data, uint8_t sectorStatus, uint32_t length)
|
||||||
{
|
{
|
||||||
|
TRACE("Entering aaruf_write_sector(%p, %" PRIu64 ", %p, %u, %u)", context, sectorAddress, data, sectorStatus,
|
||||||
|
length);
|
||||||
|
|
||||||
// Check context is correct AaruFormat context
|
// Check context is correct AaruFormat context
|
||||||
if(context == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(context == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_write_sector() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
aaruformatContext *ctx = context;
|
aaruformatContext *ctx = context;
|
||||||
|
|
||||||
// Not a libaaruformat context
|
// Not a libaaruformat context
|
||||||
if(ctx->magic != AARU_MAGIC) return AARUF_ERROR_NOT_AARUFORMAT;
|
if(ctx->magic != AARU_MAGIC)
|
||||||
|
{
|
||||||
|
FATAL("Invalid context");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_write_sector() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||||
|
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
// Check we are writing
|
// Check we are writing
|
||||||
if(!ctx->isWriting) return AARUF_READ_ONLY;
|
if(!ctx->isWriting)
|
||||||
|
{
|
||||||
|
FATAL("Trying to write a read-only image");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_write_sector() = AARUF_READ_ONLY");
|
||||||
|
return AARUF_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Check not trying to write beyond media limits
|
// TODO: Check not trying to write beyond media limits
|
||||||
|
|
||||||
@@ -51,29 +73,47 @@ int32_t aaruf_write_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
|||||||
// TODO: Implement compression
|
// TODO: Implement compression
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
|
TRACE("Closing current block before writing new data");
|
||||||
int error = aaruf_close_current_block(ctx);
|
int error = aaruf_close_current_block(ctx);
|
||||||
|
|
||||||
if(error != AARUF_STATUS_OK) return error;
|
if(error != AARUF_STATUS_OK)
|
||||||
|
{
|
||||||
|
FATAL("Error closing current block: %d", error);
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_write_sector() = %d", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No block set
|
// No block set
|
||||||
if(ctx->writingBufferPosition == 0)
|
if(ctx->writingBufferPosition == 0)
|
||||||
{
|
{
|
||||||
|
TRACE("Creating new writing block");
|
||||||
ctx->currentBlockHeader.identifier = DataBlock;
|
ctx->currentBlockHeader.identifier = DataBlock;
|
||||||
ctx->currentBlockHeader.type = UserData;
|
ctx->currentBlockHeader.type = UserData;
|
||||||
ctx->currentBlockHeader.compression = None; // TODO: Compression
|
ctx->currentBlockHeader.compression = None; // TODO: Compression
|
||||||
ctx->currentBlockHeader.sectorSize = length;
|
ctx->currentBlockHeader.sectorSize = length;
|
||||||
|
|
||||||
// TODO: Optical discs
|
// TODO: Optical discs
|
||||||
|
|
||||||
uint32_t maxBufferSize = (1 << ctx->userDataDdtHeader.dataShift) * ctx->currentBlockHeader.sectorSize;
|
uint32_t maxBufferSize = (1 << ctx->userDataDdtHeader.dataShift) * ctx->currentBlockHeader.sectorSize;
|
||||||
ctx->writingBuffer = (uint8_t *)malloc(maxBufferSize);
|
TRACE("Setting max buffer size to %u bytes", maxBufferSize);
|
||||||
if(ctx->writingBuffer == NULL) return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
|
||||||
|
|
||||||
|
TRACE("Allocating memory for writing buffer");
|
||||||
|
ctx->writingBuffer = (uint8_t *)malloc(maxBufferSize);
|
||||||
|
if(ctx->writingBuffer == NULL)
|
||||||
|
{
|
||||||
|
FATAL("Could not allocate memory");
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_write_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||||
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Initializing CRC64 context");
|
||||||
ctx->crc64Context = aaruf_crc64_init();
|
ctx->crc64Context = aaruf_crc64_init();
|
||||||
|
|
||||||
// Get current file position
|
// Get current file position
|
||||||
long pos = ftell(ctx->imageStream);
|
long pos = ftell(ctx->imageStream);
|
||||||
|
TRACE("Saving current file position as next block position: %ld", pos);
|
||||||
|
|
||||||
// Calculate and save next block aligned position
|
// Calculate and save next block aligned position
|
||||||
ctx->nextBlockPosition =
|
ctx->nextBlockPosition =
|
||||||
@@ -82,11 +122,16 @@ int32_t aaruf_write_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
|||||||
|
|
||||||
// TODO: DDT entry
|
// TODO: DDT entry
|
||||||
|
|
||||||
|
TRACE("Copying data to writing buffer at position %zu", ctx->writingBufferPosition);
|
||||||
memcpy(ctx->writingBuffer, data, length);
|
memcpy(ctx->writingBuffer, data, length);
|
||||||
|
TRACE("Advancing writing buffer position to %zu", ctx->writingBufferPosition + length);
|
||||||
ctx->writingBufferPosition += length;
|
ctx->writingBufferPosition += length;
|
||||||
|
TRACE("Updating CRC64");
|
||||||
aaruf_crc64_update(ctx->crc64Context, data, length);
|
aaruf_crc64_update(ctx->crc64Context, data, length);
|
||||||
|
TRACE("Advancing current block offset to %zu", ctx->currentBlockOffset + 1);
|
||||||
ctx->currentBlockOffset++;
|
ctx->currentBlockOffset++;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_write_sector() = AARUF_STATUS_OK");
|
||||||
return AARUF_STATUS_OK;
|
return AARUF_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user