Enhance logging and error handling across multiple modules

This commit is contained in:
2025-08-14 00:38:28 +01:00
parent d62e3119c2
commit bed8b75491
22 changed files with 1125 additions and 347 deletions

View File

@@ -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()");
} }

View File

@@ -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;
} }

View File

@@ -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()");
} }

View File

@@ -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()");
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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
@@ -123,26 +139,38 @@ int have_avx2()
#endif #endif
#endif #endif
#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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -22,11 +22,14 @@
#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)
{ {
UT_array * index_entries = NULL; TRACE("Entering process_index_v3(%p)", ctx);
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;
@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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, &sectorStatus); errorNo = decode_ddt_entry_v1(ctx, sectorAddress, &offset, &blockOffset, &sectorStatus);
else if(ctx->ddtVersion == 2) else if(ctx->ddtVersion == 2)
errorNo = decode_ddt_entry_v2(ctx, sectorAddress, &offset, &blockOffset, &sectorStatus); errorNo = decode_ddt_entry_v2(ctx, sectorAddress, &offset, &blockOffset, &sectorStatus);
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;
} }
} }

View File

@@ -20,67 +20,97 @@
#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;
void * buffer = NULL; void *buffer = NULL;
crc64_ctx * crc64_context = NULL; crc64_ctx *crc64_context = NULL;
BlockHeader block_header; BlockHeader block_header;
uint64_t verified_bytes = 0; uint64_t verified_bytes = 0;
DdtHeader ddt_header; DdtHeader ddt_header;
DdtHeader2 ddt2_header; DdtHeader2 ddt2_header;
TracksHeader tracks_header; TracksHeader tracks_header;
uint32_t signature = 0; uint32_t signature = 0;
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;
} }

View File

@@ -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;
} }