mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Enhance logging and error handling across multiple modules
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
|
||||
void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
TRACE("Entering process_checksum_block(%p, %p)", ctx, entry);
|
||||
|
||||
int pos = 0;
|
||||
size_t readBytes = 0;
|
||||
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
|
||||
if(ctx == NULL || ctx->imageStream == NULL)
|
||||
{
|
||||
fprintf(stderr, "Invalid context or image stream.\n");
|
||||
FATAL("Invalid context or image stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -44,12 +46,13 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
TRACE("Allocating %u bytes for checksum block", checksum_header.length);
|
||||
data = (uint8_t *)malloc(checksum_header.length);
|
||||
|
||||
if(data == NULL)
|
||||
@@ -74,6 +78,7 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("Reading checksum block data at position %" PRIu64, entry->offset + sizeof(ChecksumHeader));
|
||||
readBytes = fread(data, 1, checksum_header.length, ctx->imageStream);
|
||||
|
||||
if(readBytes != checksum_header.length)
|
||||
@@ -85,6 +90,7 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
TRACE("Processing %u checksum entries", checksum_header.entries);
|
||||
for(j = 0; j < checksum_header.entries; j++)
|
||||
{
|
||||
checksum_entry = (ChecksumEntry *)(&data[pos]);
|
||||
@@ -92,21 +98,25 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
|
||||
if(checksum_entry->type == Md5)
|
||||
{
|
||||
TRACE("Found MD5 checksum");
|
||||
memcpy(ctx->checksums.md5, &data[pos], MD5_DIGEST_LENGTH);
|
||||
ctx->checksums.hasMd5 = true;
|
||||
}
|
||||
else if(checksum_entry->type == Sha1)
|
||||
{
|
||||
TRACE("Found SHA1 checksum");
|
||||
memcpy(ctx->checksums.sha1, &data[pos], SHA1_DIGEST_LENGTH);
|
||||
ctx->checksums.hasSha1 = true;
|
||||
}
|
||||
else if(checksum_entry->type == Sha256)
|
||||
{
|
||||
TRACE("Found SHA256 checksum");
|
||||
memcpy(ctx->checksums.sha256, &data[pos], SHA256_DIGEST_LENGTH);
|
||||
ctx->checksums.hasSha256 = true;
|
||||
}
|
||||
else if(checksum_entry->type == SpamSum)
|
||||
{
|
||||
TRACE("Found SpamSum checksum of size %u", checksum_entry->length);
|
||||
ctx->checksums.spamsum = malloc(checksum_entry->length + 1);
|
||||
|
||||
if(ctx->checksums.spamsum != NULL)
|
||||
@@ -123,4 +133,6 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
|
||||
checksum_entry = NULL;
|
||||
free(data);
|
||||
|
||||
TRACE("Exiting process_checksum_block()");
|
||||
}
|
||||
@@ -28,6 +28,7 @@
|
||||
// Process data blocks found while opening an AaruFormat file
|
||||
int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
{
|
||||
TRACE("Entering process_data_block(%p, %p)", ctx, entry);
|
||||
BlockHeader blockHeader;
|
||||
int pos = 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
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -52,7 +53,7 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||
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;
|
||||
}
|
||||
@@ -60,14 +61,18 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
// Even if those two checks shall have been done before
|
||||
|
||||
// NOP block, skip
|
||||
TRACE("NoData block found, exiting");
|
||||
TRACE("Exiting process_data_block() = 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -76,37 +81,43 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
// Unused, skip
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if(blockHeader.type != entry->dataType)
|
||||
{
|
||||
TRACE("Expected block with data type %4.4s at position %" PRIu64
|
||||
" but found data type %4.4s\n",
|
||||
(char *)&entry->blockType, entry->offset, (char *)&blockHeader.type);
|
||||
TRACE("Expected block with data type %4.4s at position %" PRIu64 " but found data type %4.4s",
|
||||
(char *)&entry->blockType, entry->offset, (char *)&blockHeader.type);
|
||||
|
||||
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
TRACE("Found data block with type %4.4s at position %" PRIu64 "\n",
|
||||
(char *)&entry->blockType, entry->offset);
|
||||
TRACE("Found data block with type %4.4s at position %" PRIu64, (char *)&entry->blockType, entry->offset);
|
||||
|
||||
if(blockHeader.compression == Lzma || blockHeader.compression == LzmaClauniaSubchannelTransform)
|
||||
{
|
||||
if(blockHeader.compression == LzmaClauniaSubchannelTransform && blockHeader.type != CdSectorSubchannel)
|
||||
{
|
||||
fprintf(stderr, "Invalid compression type %d for block with data type %d, continuing...\n",
|
||||
blockHeader.compression, blockHeader.type);
|
||||
TRACE("Invalid compression type %d for block with data type %d, continuing...", blockHeader.compression,
|
||||
blockHeader.type);
|
||||
|
||||
TRACE("Exiting process_data_block() = 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);
|
||||
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;
|
||||
}
|
||||
|
||||
data = (uint8_t *)malloc(blockHeader.length);
|
||||
if(data == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for block, continuing...\n");
|
||||
TRACE("Cannot allocate memory for block, continuing...");
|
||||
free(cmpData);
|
||||
|
||||
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
readBytes = fread(lzmaProperties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
|
||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
fprintf(stderr, "Could not read LZMA properties, continuing...\n");
|
||||
TRACE("Could not read LZMA properties, continuing...");
|
||||
free(cmpData);
|
||||
free(data);
|
||||
|
||||
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||
if(readBytes != lzmaSize)
|
||||
{
|
||||
fprintf(stderr, "Could not read compressed block, continuing...\n");
|
||||
TRACE("Could not read compressed block, continuing...");
|
||||
free(cmpData);
|
||||
free(data);
|
||||
|
||||
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
@@ -151,19 +170,21 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
|
||||
if(errorNo != 0)
|
||||
{
|
||||
fprintf(stderr, "Got error %d from LZMA, continuing...\n", errorNo);
|
||||
TRACE("Got error %d from LZMA, continuing...", errorNo);
|
||||
free(cmpData);
|
||||
free(data);
|
||||
|
||||
TRACE("Exiting process_data_block() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
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(data);
|
||||
|
||||
TRACE("Exiting process_data_block() = 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);
|
||||
if(cstData == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for block, continuing...\n");
|
||||
TRACE("Cannot allocate memory for block, continuing...");
|
||||
free(cmpData);
|
||||
free(data);
|
||||
|
||||
TRACE("Exiting process_data_block() = 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);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -202,15 +225,17 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
if(readBytes != blockHeader.length)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -223,9 +248,10 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
|
||||
if(crc64 != blockHeader.crc64)
|
||||
{
|
||||
TRACE("Incorrect CRC found: 0x%" PRIx64 " found, expected 0x%" PRIx64 ", continuing...\n",
|
||||
crc64, blockHeader.crc64);
|
||||
TRACE("Incorrect CRC found: 0x%" PRIx64 " found, expected 0x%" PRIx64 ", continuing...", crc64,
|
||||
blockHeader.crc64);
|
||||
|
||||
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
}
|
||||
@@ -274,7 +300,7 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
|
||||
if(mediaTag == NULL)
|
||||
{
|
||||
TRACE("Cannot allocate memory for media tag entry.\n");
|
||||
TRACE("Cannot allocate memory for media tag entry.");
|
||||
break;
|
||||
}
|
||||
memset(mediaTag, 0, sizeof(mediaTagEntry));
|
||||
@@ -287,7 +313,7 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
|
||||
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);
|
||||
oldMediaTag = NULL;
|
||||
@@ -296,5 +322,6 @@ int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry)
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
TRACE("Entering process_dumphw_block(%p, %p)", ctx, entry);
|
||||
int pos = 0;
|
||||
size_t readBytes = 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
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -43,33 +46,38 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
if(readBytes != 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;
|
||||
}
|
||||
|
||||
if(ctx->dumpHardwareHeader.identifier != DumpHardwareBlock)
|
||||
{
|
||||
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);
|
||||
|
||||
if(data == NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -85,8 +93,9 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
if(crc64 != ctx->dumpHardwareHeader.crc64)
|
||||
{
|
||||
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);
|
||||
TRACE("Exiting process_dumphw_block()");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -100,12 +109,14 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
if(ctx->dumpHardwareEntriesWithData == NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
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))
|
||||
{
|
||||
ctx->dumpHardwareHeader.entries = e;
|
||||
TRACE("Could not read dump hardware block entry, continuing...\n");
|
||||
TRACE("Could not read dump hardware block entry, continuing...");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -134,7 +145,7 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
free(ctx->dumpHardwareEntriesWithData[e].manufacturer);
|
||||
ctx->dumpHardwareEntriesWithData[e].entry.manufacturerLength = 0;
|
||||
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);
|
||||
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);
|
||||
ctx->dumpHardwareEntriesWithData[e].entry.revisionLength = 0;
|
||||
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);
|
||||
ctx->dumpHardwareEntriesWithData[e].entry.firmwareLength = 0;
|
||||
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);
|
||||
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);
|
||||
ctx->dumpHardwareEntriesWithData[e].entry.softwareNameLength = 0;
|
||||
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);
|
||||
ctx->dumpHardwareEntriesWithData[e].entry.softwareVersionLength = 0;
|
||||
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);
|
||||
ctx->dumpHardwareEntriesWithData[e].entry.softwareOperatingSystemLength = 0;
|
||||
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)
|
||||
{
|
||||
TRACE("Could not allocate memory for dump hardware block extents, "
|
||||
"continuing...\n");
|
||||
"continuing...");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -307,10 +318,11 @@ void process_dumphw_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
if(readBytes != ctx->dumpHardwareEntriesWithData->entry.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;
|
||||
}
|
||||
|
||||
// TODO: qsort()
|
||||
}
|
||||
TRACE("Exiting process_dumphw_block()");
|
||||
}
|
||||
@@ -27,40 +27,48 @@
|
||||
// Process the metadata block found while opening an AaruFormat file
|
||||
void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
TRACE("Entering process_metadata_block(%p, %p)", ctx, entry);
|
||||
int pos = 0;
|
||||
size_t readBytes = 0;
|
||||
|
||||
// Check if the context and image stream are valid
|
||||
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;
|
||||
}
|
||||
|
||||
// Seek to block
|
||||
TRACE("Seeking to metadata block at position %" PRIu64, entry->offset);
|
||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
if(readBytes != 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;
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.identifier != entry->blockType)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -71,24 +79,28 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
if(ctx->metadataBlock == NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if(readBytes != ctx->metadataBlockHeader.blockSize)
|
||||
{
|
||||
memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader));
|
||||
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)
|
||||
{
|
||||
ctx->imageInfo.MediaSequence = ctx->metadataBlockHeader.mediaSequence;
|
||||
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 &&
|
||||
@@ -97,10 +109,8 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.Creator = (uint8_t *)malloc(ctx->metadataBlockHeader.creatorLength);
|
||||
if(ctx->imageInfo.Creator != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.Creator, ctx->metadataBlock + ctx->metadataBlockHeader.creatorOffset,
|
||||
ctx->metadataBlockHeader.creatorLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.commentsLength > 0 &&
|
||||
@@ -109,10 +119,8 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.Comments = (uint8_t *)malloc(ctx->metadataBlockHeader.commentsLength);
|
||||
if(ctx->imageInfo.Comments != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.Comments, ctx->metadataBlock + ctx->metadataBlockHeader.commentsOffset,
|
||||
ctx->metadataBlockHeader.commentsLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.mediaTitleLength > 0 &&
|
||||
@@ -121,10 +129,8 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.MediaTitle = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaTitleLength);
|
||||
if(ctx->imageInfo.MediaTitle != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.MediaTitle, ctx->metadataBlock + ctx->metadataBlockHeader.mediaTitleOffset,
|
||||
ctx->metadataBlockHeader.mediaTitleLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.mediaManufacturerLength > 0 &&
|
||||
@@ -133,11 +139,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.MediaManufacturer = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaManufacturerLength);
|
||||
if(ctx->imageInfo.MediaManufacturer != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.MediaManufacturer,
|
||||
ctx->metadataBlock + ctx->metadataBlockHeader.mediaManufacturerOffset,
|
||||
ctx->metadataBlockHeader.mediaManufacturerLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.mediaModelLength > 0 &&
|
||||
@@ -146,10 +150,8 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.MediaModel = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaModelOffset);
|
||||
if(ctx->imageInfo.MediaModel != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.MediaModel, ctx->metadataBlock + ctx->metadataBlockHeader.mediaModelOffset,
|
||||
ctx->metadataBlockHeader.mediaModelLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.mediaSerialNumberLength > 0 &&
|
||||
@@ -158,11 +160,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.MediaSerialNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaSerialNumberLength);
|
||||
if(ctx->imageInfo.MediaSerialNumber != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.MediaSerialNumber,
|
||||
ctx->metadataBlock + ctx->metadataBlockHeader.mediaSerialNumberOffset,
|
||||
ctx->metadataBlockHeader.mediaManufacturerLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.mediaBarcodeLength > 0 &&
|
||||
@@ -171,10 +171,8 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.MediaBarcode = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaBarcodeLength);
|
||||
if(ctx->imageInfo.MediaBarcode != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.MediaBarcode, ctx->metadataBlock + ctx->metadataBlockHeader.mediaBarcodeOffset,
|
||||
ctx->metadataBlockHeader.mediaBarcodeLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.mediaPartNumberLength > 0 &&
|
||||
@@ -183,10 +181,8 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.MediaPartNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaPartNumberLength);
|
||||
if(ctx->imageInfo.MediaPartNumber != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.MediaPartNumber, ctx->metadataBlock + ctx->metadataBlockHeader.mediaPartNumberOffset,
|
||||
ctx->metadataBlockHeader.mediaPartNumberLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.driveManufacturerLength > 0 &&
|
||||
@@ -195,11 +191,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.DriveManufacturer = (uint8_t *)malloc(ctx->metadataBlockHeader.driveManufacturerLength);
|
||||
if(ctx->imageInfo.DriveManufacturer != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.DriveManufacturer,
|
||||
ctx->metadataBlock + ctx->metadataBlockHeader.driveManufacturerOffset,
|
||||
ctx->metadataBlockHeader.driveManufacturerLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.driveModelLength > 0 &&
|
||||
@@ -208,10 +202,8 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.DriveModel = (uint8_t *)malloc(ctx->metadataBlockHeader.driveModelLength);
|
||||
if(ctx->imageInfo.DriveModel != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.DriveModel, ctx->metadataBlock + ctx->metadataBlockHeader.driveModelOffset,
|
||||
ctx->metadataBlockHeader.driveModelLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.driveSerialNumberLength > 0 &&
|
||||
@@ -220,11 +212,9 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.DriveSerialNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.driveSerialNumberLength);
|
||||
if(ctx->imageInfo.DriveSerialNumber != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.DriveSerialNumber,
|
||||
ctx->metadataBlock + ctx->metadataBlockHeader.driveSerialNumberOffset,
|
||||
ctx->metadataBlockHeader.driveSerialNumberLength);
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->metadataBlockHeader.driveManufacturerLength > 0 &&
|
||||
@@ -233,96 +223,109 @@ void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
ctx->imageInfo.DriveFirmwareRevision = (uint8_t *)malloc(ctx->metadataBlockHeader.driveFirmwareRevisionLength);
|
||||
if(ctx->imageInfo.DriveFirmwareRevision != NULL)
|
||||
{
|
||||
memcpy(ctx->imageInfo.DriveFirmwareRevision,
|
||||
ctx->metadataBlock + 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
|
||||
void process_geometry_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
TRACE("Entering process_geometry_block(%p, %p)", ctx, entry);
|
||||
size_t readBytes = 0;
|
||||
|
||||
// Check if the context and image stream are valid
|
||||
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;
|
||||
}
|
||||
|
||||
// Seek to block
|
||||
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;
|
||||
}
|
||||
|
||||
TRACE("Reading geometry block header at position %" PRIu64, entry->offset);
|
||||
readBytes = fread(&ctx->geometryBlock, 1, sizeof(GeometryBlockHeader), ctx->imageStream);
|
||||
|
||||
if(readBytes != 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;
|
||||
}
|
||||
|
||||
if(ctx->geometryBlock.identifier != GeometryBlock)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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->imageInfo.Cylinders = ctx->geometryBlock.cylinders;
|
||||
ctx->imageInfo.Heads = ctx->geometryBlock.heads;
|
||||
ctx->imageInfo.SectorsPerTrack = ctx->geometryBlock.sectorsPerTrack;
|
||||
|
||||
TRACE("Exiting process_geometry_block()");
|
||||
}
|
||||
|
||||
// CICM XML metadata block
|
||||
void process_cicm_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
{
|
||||
TRACE("Entering process_cicm_block(%p, %p)", ctx, entry);
|
||||
int pos = 0;
|
||||
size_t readBytes = 0;
|
||||
|
||||
// Check if the context and image stream are valid
|
||||
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;
|
||||
}
|
||||
|
||||
// Seek to block
|
||||
TRACE("Seeking to CICM XML metadata block at position %" PRIu64, entry->offset);
|
||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
if(readBytes != 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;
|
||||
}
|
||||
|
||||
if(ctx->cicmBlockHeader.identifier != CicmBlock)
|
||||
{
|
||||
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;
|
||||
@@ -332,18 +335,24 @@ void process_cicm_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
if(ctx->cicmBlock == NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if(readBytes != ctx->metadataBlockHeader.blockSize)
|
||||
{
|
||||
memset(&ctx->cicmBlockHeader, 0, sizeof(CicmMetadataBlock));
|
||||
free(ctx->cicmBlock);
|
||||
TRACE("Could not read CICM XML metadata block, continuing...\n");
|
||||
TRACE("Could not read CICM XML metadata block, continuing...");
|
||||
}
|
||||
|
||||
TRACE("Found CICM XML metadata block %" PRIu64 ".\n", entry->offset);
|
||||
TRACE("Found CICM XML metadata block %" PRIu64 ".", entry->offset);
|
||||
|
||||
TRACE("Exiting process_cicm_block()");
|
||||
}
|
||||
@@ -34,7 +34,7 @@ void process_tracks_block(aaruformatContext *ctx, const IndexEntry *entry)
|
||||
// Check if the context and image stream are valid
|
||||
if(ctx == NULL || ctx->imageStream == NULL)
|
||||
{
|
||||
FATAL("Invalid context or image stream.\n");
|
||||
FATAL("Invalid context or image stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,16 +23,20 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "aaruformat.h"
|
||||
#include "log.h"
|
||||
|
||||
void *aaruf_ecc_cd_init()
|
||||
{
|
||||
TRACE("Entering aaruf_ecc_cd_init()");
|
||||
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));
|
||||
|
||||
if(context == NULL) return NULL;
|
||||
|
||||
TRACE("Allocating memory for ECC F table");
|
||||
context->eccFTable = (uint8_t *)malloc(sizeof(uint8_t) * 256);
|
||||
|
||||
if(context->eccFTable == NULL)
|
||||
@@ -41,6 +45,7 @@ void *aaruf_ecc_cd_init()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("Allocating memory for ECC B table");
|
||||
context->eccBTable = (uint8_t *)malloc(sizeof(uint8_t) * 256);
|
||||
|
||||
if(context->eccBTable == NULL)
|
||||
@@ -49,6 +54,9 @@ void *aaruf_ecc_cd_init()
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("Allocating memory for EDC table");
|
||||
|
||||
context->edcTable = (uint32_t *)malloc(sizeof(uint32_t) * 256);
|
||||
|
||||
if(context->edcTable == NULL)
|
||||
@@ -59,6 +67,7 @@ void *aaruf_ecc_cd_init()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("Initializing EDC tables");
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
edc = i;
|
||||
@@ -71,32 +80,52 @@ void *aaruf_ecc_cd_init()
|
||||
|
||||
context->initedEdc = true;
|
||||
|
||||
TRACE("Exiting aaruf_ecc_cd_init()");
|
||||
return context;
|
||||
}
|
||||
|
||||
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;
|
||||
uint32_t storedEdc, edc, calculatedEdc;
|
||||
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;
|
||||
|
||||
if(!ctx->initedEdc) return false;
|
||||
if(!ctx->initedEdc)
|
||||
{
|
||||
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct() without initialized context");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sector[0x814] != 0x00 ||
|
||||
// reserved (8 bytes)
|
||||
sector[0x815] != 0x00 || sector[0x816] != 0x00 || sector[0x817] != 0x00 || sector[0x818] != 0x00 ||
|
||||
sector[0x819] != 0x00 || sector[0x81A] != 0x00 || sector[0x81B] != 0x00)
|
||||
{
|
||||
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct() = false");
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
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];
|
||||
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];
|
||||
calculatedEdc = edc;
|
||||
|
||||
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct() = %u == %u", calculatedEdc, storedEdc);
|
||||
return calculatedEdc == storedEdc;
|
||||
}
|
||||
|
||||
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;
|
||||
uint32_t storedEdc, edc, calculatedEdc;
|
||||
int size, pos;
|
||||
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;
|
||||
|
||||
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));
|
||||
|
||||
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);
|
||||
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];
|
||||
edc = 0;
|
||||
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];
|
||||
calculatedEdc = edc;
|
||||
|
||||
TRACE("Exiting aaruf_ecc_cd_is_suffix_correct_mode2() = %u == %u", 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,
|
||||
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;
|
||||
uint32_t size, major, idx, minor;
|
||||
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;
|
||||
|
||||
if(!ctx->initedEdc) return false;
|
||||
if(!ctx->initedEdc)
|
||||
{
|
||||
TRACE("Exiting aaruf_ecc_cd_check() without initialized context");
|
||||
return false;
|
||||
}
|
||||
|
||||
size = majorCount * minorCount;
|
||||
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];
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
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;
|
||||
uint32_t size, major, idx, minor;
|
||||
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;
|
||||
|
||||
if(!ctx->initedEdc) return;
|
||||
if(!ctx->initedEdc)
|
||||
{
|
||||
TRACE("Exiting aaruf_ecc_cd_write() without initialized context");
|
||||
return;
|
||||
}
|
||||
|
||||
size = majorCount * minorCount;
|
||||
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 + 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,
|
||||
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, 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)
|
||||
{
|
||||
TRACE("Entering aaruf_cd_lba_to_msf(%lld, %p, %p, %p)", pos, minute, second, frame);
|
||||
|
||||
*minute = (uint8_t)((pos + 150) / 75 / 60);
|
||||
*second = (uint8_t)((pos + 150) / 75 % 60);
|
||||
*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
|
||||
uint8_t type, int64_t lba)
|
||||
{
|
||||
TRACE("Entering aaruf_ecc_cd_reconstruct_prefix(%p, %u, %lld)", sector, type, lba);
|
||||
|
||||
uint8_t minute, second, frame;
|
||||
|
||||
if(sector == NULL) return;
|
||||
@@ -282,22 +368,34 @@ void aaruf_ecc_cd_reconstruct_prefix(uint8_t *sector, // must point to a full 2
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("Exiting aaruf_ecc_cd_reconstruct_prefix()");
|
||||
}
|
||||
|
||||
void aaruf_ecc_cd_reconstruct(void *context,
|
||||
uint8_t *sector, // must point to a full 2352-byte sector
|
||||
uint8_t type)
|
||||
{
|
||||
TRACE("Entering aaruf_ecc_cd_reconstruct(%p, %p, %u)", context, sector, type);
|
||||
|
||||
uint32_t computedEdc;
|
||||
uint8_t zeroaddress[4];
|
||||
|
||||
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;
|
||||
|
||||
if(!ctx->initedEdc) return;
|
||||
if(!ctx->initedEdc)
|
||||
{
|
||||
TRACE("Exiting aaruf_ecc_cd_reconstruct() without initialized context");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
@@ -317,6 +415,7 @@ void aaruf_ecc_cd_reconstruct(void *context,
|
||||
memcpy(sector + 0x92C, &computedEdc, 4);
|
||||
break;
|
||||
default:
|
||||
TRACE("Exiting aaruf_ecc_cd_reconstruct() with unknown type %u", type);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -345,25 +444,38 @@ void aaruf_ecc_cd_reconstruct(void *context,
|
||||
aaruf_ecc_cd_write_sector(context, zeroaddress, sector, sector, 0, 0x10, 0x81C);
|
||||
break;
|
||||
default:
|
||||
TRACE("Exiting aaruf_ecc_cd_reconstruct() with unknown type %u", type);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// 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)
|
||||
{
|
||||
TRACE("Entering aaruf_edc_cd_compute(%p, %u, %p, %d, %d)", context, edc, src, size, pos);
|
||||
|
||||
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;
|
||||
|
||||
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];
|
||||
|
||||
TRACE("Exiting aaruf_edc_cd_compute() = 0x%08X", edc);
|
||||
return edc;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "aaruformat.h"
|
||||
#include "log.h"
|
||||
|
||||
#if defined(__x86_64__) || defined(__amd64) || defined(_M_AMD64) || defined(_M_X64) || defined(__I386__) || \
|
||||
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)
|
||||
{
|
||||
TRACE("Entering cpuid(%d, %d, %d, %d, %d)", info, *eax, *ebx, *ecx, *edx);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
unsigned int registers[4];
|
||||
__cpuid(registers, info);
|
||||
@@ -56,10 +59,14 @@ static void cpuid(int info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigne
|
||||
*ecx = _ecx;
|
||||
*edx = _edx;
|
||||
#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)
|
||||
{
|
||||
TRACE("Entering cpuidex(%d, %d, %d, %d, %d, %d)", info, count, *eax, *ebx, *ecx, *edx);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
unsigned int registers[4];
|
||||
__cpuidex(registers, info, count);
|
||||
@@ -79,10 +86,14 @@ static void cpuidex(int info, int count, unsigned *eax, unsigned *ebx, unsigned
|
||||
*ecx = _ecx;
|
||||
*edx = _edx;
|
||||
#endif
|
||||
|
||||
TRACE("Exiting cpuidex(%d, %d, %d, %d, %d, %d)", info, count, *eax, *ebx, *ecx, *edx);
|
||||
}
|
||||
|
||||
int have_clmul()
|
||||
{
|
||||
TRACE("Entering have_clmul()");
|
||||
|
||||
unsigned eax, ebx, ecx, edx;
|
||||
int has_pclmulqdq;
|
||||
int has_sse41;
|
||||
@@ -91,22 +102,27 @@ int have_clmul()
|
||||
has_pclmulqdq = ecx & 0x2; /* bit 1 */
|
||||
has_sse41 = ecx & 0x80000; /* bit 19 */
|
||||
|
||||
TRACE("Exiting have_clmul() = %d", has_pclmulqdq && has_sse41);
|
||||
return has_pclmulqdq && has_sse41;
|
||||
}
|
||||
|
||||
int have_ssse3()
|
||||
{
|
||||
TRACE("Entering have_ssse3()");
|
||||
unsigned eax, ebx, ecx, edx;
|
||||
cpuid(1 /* feature bits */, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
TRACE("Exiting have_ssse3() = %d", ecx & 0x200);
|
||||
return ecx & 0x200;
|
||||
}
|
||||
|
||||
int have_avx2()
|
||||
{
|
||||
TRACE("Entering have_avx2()");
|
||||
unsigned eax, ebx, ecx, edx;
|
||||
cpuidex(7 /* extended feature bits */, 0, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
TRACE("Exiting have_avx2() = %d", ebx & 0x20);
|
||||
return ebx & 0x20;
|
||||
}
|
||||
#endif
|
||||
@@ -123,26 +139,38 @@ int have_avx2()
|
||||
#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 value = 0;
|
||||
size_t len = sizeof(int);
|
||||
int ret = sysctlbyname("hw.optional.neon", &value, &len, NULL, 0);
|
||||
TRACE("Entering have_neon_apple()");
|
||||
int value = 0;
|
||||
size_t len = sizeof(int);
|
||||
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;
|
||||
}
|
||||
|
||||
int have_crc32_apple()
|
||||
{
|
||||
int value = 0;
|
||||
size_t len = sizeof(int);
|
||||
int ret = sysctlbyname("hw.optional.crc32", &value, &len, NULL, 0);
|
||||
TRACE("Entering have_crc32_apple()");
|
||||
int value = 0;
|
||||
size_t len = sizeof(int);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
20
src/close.c
20
src/close.c
@@ -27,15 +27,19 @@
|
||||
#include <aaruformat.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "log.h"
|
||||
|
||||
int aaruf_close(void *context)
|
||||
{
|
||||
TRACE("Entering aaruf_close(%p)", context);
|
||||
|
||||
int i = 0;
|
||||
mediaTagEntry *mediaTag = NULL;
|
||||
mediaTagEntry *tmpMediaTag = NULL;
|
||||
|
||||
if(context == NULL)
|
||||
{
|
||||
FATAL("Invalid context");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@@ -45,14 +49,20 @@ int aaruf_close(void *context)
|
||||
// Not a libaaruformat context
|
||||
if(ctx->magic != AARU_MAGIC)
|
||||
{
|
||||
FATAL("Invalid context");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ctx->isWriting)
|
||||
{
|
||||
TRACE("File is writing");
|
||||
|
||||
TRACE("Seeking to start of image");
|
||||
// Write the header at the beginning of the file
|
||||
fseek(ctx->imageStream, 0, SEEK_SET);
|
||||
|
||||
TRACE("Writing header at position 0");
|
||||
if(fwrite(&ctx->header, sizeof(AaruHeaderV2), 1, ctx->imageStream) != 1)
|
||||
{
|
||||
fclose(ctx->imageStream);
|
||||
@@ -62,6 +72,7 @@ int aaruf_close(void *context)
|
||||
}
|
||||
|
||||
// Close current block first
|
||||
TRACE("Closing current block if any");
|
||||
if(ctx->writingBuffer != NULL)
|
||||
{
|
||||
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
|
||||
if(ctx->imageStream != NULL)
|
||||
{
|
||||
@@ -90,17 +102,16 @@ int aaruf_close(void *context)
|
||||
free(ctx->mode2Subheaders);
|
||||
ctx->mode2Subheaders = NULL;
|
||||
|
||||
if(ctx->mediaTags != NULL)
|
||||
{
|
||||
HASH_ITER(hh, ctx->mediaTags, mediaTag, tmpMediaTag)
|
||||
TRACE("Freeing media tags");
|
||||
if(ctx->mediaTags != NULL) HASH_ITER(hh, ctx->mediaTags, mediaTag, tmpMediaTag)
|
||||
{
|
||||
HASH_DEL(ctx->mediaTags, mediaTag);
|
||||
free(mediaTag->data);
|
||||
free(mediaTag);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __linux__ // TODO: Implement
|
||||
TRACE("Unmapping user data DDT if it is not in memory");
|
||||
if(!ctx->inMemoryDdt)
|
||||
{
|
||||
munmap(ctx->userDataDdt, ctx->mappedMemoryDdtSize);
|
||||
@@ -159,5 +170,6 @@ int aaruf_close(void *context)
|
||||
|
||||
free(context);
|
||||
|
||||
TRACE("Exiting aaruf_close() = 0");
|
||||
return 0;
|
||||
}
|
||||
@@ -20,26 +20,37 @@
|
||||
|
||||
#include <aaruformat.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
AARU_EXPORT crc64_ctx *AARU_CALL aaruf_crc64_init(void)
|
||||
{
|
||||
TRACE("Entering aaruf_crc64_init()");
|
||||
crc64_ctx *ctx = (crc64_ctx *)malloc(sizeof(crc64_ctx));
|
||||
|
||||
if(!ctx) return NULL;
|
||||
|
||||
ctx->crc = CRC64_ECMA_SEED;
|
||||
|
||||
TRACE("Exiting aaruf_crc64_init()");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
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__) || \
|
||||
defined(__i386__) || defined(__THW_INTEL) || defined(_M_IX86)
|
||||
if(have_clmul())
|
||||
{
|
||||
ctx->crc = ~aaruf_crc64_clmul(~ctx->crc, data, len);
|
||||
|
||||
TRACE("Exiting aaruf_crc64_update() = 0");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -48,6 +59,8 @@ AARU_EXPORT int AARU_CALL aaruf_crc64_update(crc64_ctx *ctx, const uint8_t *data
|
||||
if(have_neon())
|
||||
{
|
||||
ctx->crc = ~aaruf_crc64_vmull(~ctx->crc, data, len);
|
||||
|
||||
TRACE("Exiting aaruf_crc64_update() = 0");
|
||||
return 0;
|
||||
}
|
||||
#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);
|
||||
|
||||
TRACE("Exiting aaruf_crc64_update() = 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <smmintrin.h>
|
||||
#include <wmmintrin.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#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)
|
||||
{
|
||||
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 k2 = 0xdabe95afc7875f40; // bitReflect(expMod65(128, 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 =
|
||||
_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)
|
||||
return ~_mm_extract_epi64(T2, 1);
|
||||
#else
|
||||
|
||||
@@ -51,6 +51,8 @@ TARGET_WITH_SIMD FORCE_INLINE uint64x2_t fold(uint64x2_t in, uint64x2_t foldCons
|
||||
|
||||
AARU_EXPORT TARGET_WITH_SIMD uint64_t AARU_CALL aaruf_crc64_vmull(uint64_t previous_crc, const uint8_t *data, long len)
|
||||
{
|
||||
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 k2 = 0xdabe95afc7875f40; // bitReflect(expMod65(128, 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(
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
31
src/create.c
31
src/create.c
@@ -24,42 +24,63 @@
|
||||
|
||||
#include "aaruformat.h"
|
||||
#include "internal.h"
|
||||
#include "log.h"
|
||||
|
||||
void *aaruf_create(const char *filepath, uint32_t mediaType, uint32_t sectorSize, uint64_t userSectors,
|
||||
uint64_t negativeSectors, uint64_t overflowSectors, const char *options,
|
||||
const uint8_t *applicationName, uint8_t applicationNameLength, uint8_t applicationMajorVersion,
|
||||
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
|
||||
TRACE("Parsing options");
|
||||
aaru_options parsedOptions = parse_options(options);
|
||||
|
||||
// Allocate context
|
||||
TRACE("Allocating memory for context");
|
||||
aaruformatContext *ctx = malloc(sizeof(aaruformatContext));
|
||||
if(ctx == NULL)
|
||||
{
|
||||
FATAL("Not enough memory to create context");
|
||||
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
TRACE("Exiting aaruf_create() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(ctx, 0, sizeof(aaruformatContext));
|
||||
|
||||
// Create the image file
|
||||
TRACE("Creating image file %s", filepath);
|
||||
ctx->imageStream = fopen(filepath, "wb+");
|
||||
if(ctx->imageStream == NULL)
|
||||
{
|
||||
FATAL("Error %d opening file %s for writing", errno, filepath);
|
||||
free(ctx);
|
||||
errno = AARUF_ERROR_CANNOT_CREATE_FILE;
|
||||
|
||||
TRACE("Exiting aaruf_create() = NULL");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
errno = AARUF_ERROR_INVALID_APP_NAME_LENGTH;
|
||||
|
||||
TRACE("Exiting aaruf_create() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Initialize header
|
||||
TRACE("Initializing header");
|
||||
ctx->header.identifier = AARU_MAGIC;
|
||||
memcpy(ctx->header.application, applicationName, applicationNameLength);
|
||||
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);
|
||||
|
||||
// Initilize image info
|
||||
// Initialize image info
|
||||
TRACE("Initializing image info");
|
||||
ctx->imageInfo.Application = ctx->header.application;
|
||||
ctx->imageInfo.ApplicationVersion = (uint8_t *)malloc(32);
|
||||
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;
|
||||
|
||||
// Initialize caches
|
||||
TRACE("Initializing caches");
|
||||
ctx->blockHeaderCache.cache = NULL;
|
||||
ctx->blockHeaderCache.max_items = MAX_CACHE_SIZE / (ctx->imageInfo.SectorSize * (1 << ctx->shift));
|
||||
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?
|
||||
|
||||
// Initialize ECC for Compact Disc
|
||||
TRACE("Initializing Compact Disc ECC");
|
||||
ctx->eccCdContext = (CdEccContext *)aaruf_ecc_cd_init();
|
||||
|
||||
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;
|
||||
|
||||
// Initialize DDT2
|
||||
TRACE("Initializing DDT2");
|
||||
ctx->inMemoryDdt = true;
|
||||
ctx->userDataDdtHeader.identifier = DeDuplicationTable2;
|
||||
ctx->userDataDdtHeader.type = UserData;
|
||||
@@ -142,4 +167,8 @@ void *aaruf_create(const char *filepath, uint32_t mediaType, uint32_t sectorSize
|
||||
|
||||
// Is writing
|
||||
ctx->isWriting = true;
|
||||
|
||||
TRACE("Exiting aaruf_create() = %p", ctx);
|
||||
// Return context
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUserDataDdt)
|
||||
{
|
||||
TRACE("Entering process_ddt_v1(%p, %p, %d)", ctx, entry, *foundUserDataDdt);
|
||||
|
||||
int pos = 0;
|
||||
size_t readBytes = 0;
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
// Seek to block
|
||||
TRACE("Seeking to DDT block at position %" PRIu64, entry->offset);
|
||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -86,14 +93,14 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||
if(cmpData == NULL)
|
||||
{
|
||||
TRACE("Cannot allocate memory for DDT, continuing...\n");
|
||||
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||
break;
|
||||
}
|
||||
|
||||
ctx->userDataDdt = (uint64_t *)malloc(ddtHeader.length);
|
||||
if(ctx->userDataDdt == NULL)
|
||||
{
|
||||
TRACE("Cannot allocate memory for DDT, continuing...\n");
|
||||
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||
free(cmpData);
|
||||
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);
|
||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
TRACE("Could not read LZMA properties, continuing...\n");
|
||||
TRACE("Could not read LZMA properties, continuing...");
|
||||
free(cmpData);
|
||||
free(ctx->userDataDdt);
|
||||
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);
|
||||
if(readBytes != lzmaSize)
|
||||
{
|
||||
TRACE("Could not read compressed block, continuing...\n");
|
||||
TRACE("Could not read compressed block, continuing...");
|
||||
free(cmpData);
|
||||
free(ctx->userDataDdt);
|
||||
ctx->userDataDdt = NULL;
|
||||
@@ -119,12 +126,13 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
}
|
||||
|
||||
readBytes = ddtHeader.length;
|
||||
errorNo = aaruf_lzma_decode_buffer((uint8_t *)ctx->userDataDdt, &readBytes, cmpData, &lzmaSize,
|
||||
lzmaProperties, LZMA_PROPERTIES_LENGTH);
|
||||
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||
errorNo = aaruf_lzma_decode_buffer((uint8_t *)ctx->userDataDdt, &readBytes, cmpData, &lzmaSize,
|
||||
lzmaProperties, LZMA_PROPERTIES_LENGTH);
|
||||
|
||||
if(errorNo != 0)
|
||||
{
|
||||
FATAL("Got error %d from LZMA, stopping...\n", errorNo);
|
||||
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||
free(cmpData);
|
||||
free(ctx->userDataDdt);
|
||||
ctx->userDataDdt = NULL;
|
||||
@@ -133,7 +141,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
|
||||
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(ctx->userDataDdt);
|
||||
ctx->userDataDdt = NULL;
|
||||
@@ -147,6 +155,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
// TODO: Check CRC
|
||||
case None:
|
||||
#ifdef __linux__
|
||||
TRACE("Memory mapping deduplication table at position %" PRIu64, entry->offset + sizeof(ddtHeader));
|
||||
ctx->mappedMemoryDdtSize = sizeof(uint64_t) * ddtHeader.entries;
|
||||
ctx->userDataDdt = mmap(NULL, ctx->mappedMemoryDdtSize, PROT_READ, MAP_SHARED, fileno(ctx->imageStream),
|
||||
entry->offset + sizeof(ddtHeader));
|
||||
@@ -154,19 +163,19 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
if(ctx->userDataDdt == MAP_FAILED)
|
||||
{
|
||||
*foundUserDataDdt = false;
|
||||
FATAL("Could not read map deduplication table.\n");
|
||||
FATAL("Could not read map deduplication table.");
|
||||
break;
|
||||
}
|
||||
|
||||
ctx->inMemoryDdt = false;
|
||||
break;
|
||||
#else // TODO: Implement
|
||||
TRACE("Uncompressed DDT not yet implemented...\n");
|
||||
TRACE("Uncompressed DDT not yet implemented...");
|
||||
*foundUserDataDdt = false;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
TRACE("Found unknown compression type %d, continuing...\n", ddtHeader.compression);
|
||||
TRACE("Found unknown compression type %d, continuing...", ddtHeader.compression);
|
||||
*foundUserDataDdt = false;
|
||||
break;
|
||||
}
|
||||
@@ -182,14 +191,14 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||
if(cmpData == NULL)
|
||||
{
|
||||
TRACE("Cannot allocate memory for DDT, continuing...\n");
|
||||
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||
break;
|
||||
}
|
||||
|
||||
cdDdt = (uint32_t *)malloc(ddtHeader.length);
|
||||
if(cdDdt == NULL)
|
||||
{
|
||||
TRACE("Cannot allocate memory for DDT, continuing...\n");
|
||||
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||
free(cmpData);
|
||||
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);
|
||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
TRACE("Could not read LZMA properties, continuing...\n");
|
||||
TRACE("Could not read LZMA properties, continuing...");
|
||||
free(cmpData);
|
||||
free(cdDdt);
|
||||
break;
|
||||
@@ -206,19 +215,20 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||
if(readBytes != lzmaSize)
|
||||
{
|
||||
TRACE("Could not read compressed block, continuing...\n");
|
||||
TRACE("Could not read compressed block, continuing...");
|
||||
free(cmpData);
|
||||
free(cdDdt);
|
||||
break;
|
||||
}
|
||||
|
||||
readBytes = ddtHeader.length;
|
||||
errorNo = aaruf_lzma_decode_buffer((uint8_t *)cdDdt, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||
LZMA_PROPERTIES_LENGTH);
|
||||
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||
errorNo = aaruf_lzma_decode_buffer((uint8_t *)cdDdt, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||
LZMA_PROPERTIES_LENGTH);
|
||||
|
||||
if(errorNo != 0)
|
||||
{
|
||||
FATAL("Got error %d from LZMA, stopping...\n", errorNo);
|
||||
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||
free(cmpData);
|
||||
free(cdDdt);
|
||||
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)
|
||||
{
|
||||
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(cdDdt);
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
@@ -247,7 +257,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
|
||||
if(cdDdt == NULL)
|
||||
{
|
||||
TRACE("Cannot allocate memory for deduplication table.\n");
|
||||
TRACE("Cannot allocate memory for deduplication table.");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -256,7 +266,7 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
if(readBytes != ddtHeader.entries * sizeof(uint32_t))
|
||||
{
|
||||
free(cdDdt);
|
||||
TRACE("Could not read deduplication table, continuing...\n");
|
||||
TRACE("Could not read deduplication table, continuing...");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -269,21 +279,25 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
|
||||
break;
|
||||
default:
|
||||
TRACE("Found unknown compression type %d, continuing...\n", ddtHeader.compression);
|
||||
TRACE("Found unknown compression type %d, continuing...", ddtHeader.compression);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Exiting process_ddt_v1() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
int32_t decode_ddt_entry_v1(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset, uint64_t *blockOffset,
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -298,5 +312,8 @@ int32_t decode_ddt_entry_v1(aaruformatContext *ctx, uint64_t sectorAddress, uint
|
||||
else
|
||||
*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;
|
||||
}
|
||||
186
src/ddt/ddt_v2.c
186
src/ddt/ddt_v2.c
@@ -27,6 +27,8 @@
|
||||
|
||||
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;
|
||||
size_t readBytes = 0;
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -49,19 +53,21 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -86,14 +92,14 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||
if(cmpData == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
||||
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = malloc(ddtHeader.length);
|
||||
if(buffer == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
||||
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||
free(cmpData);
|
||||
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);
|
||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
fprintf(stderr, "Could not read LZMA properties, continuing...\n");
|
||||
TRACE("Could not read LZMA properties, continuing...");
|
||||
free(cmpData);
|
||||
free(buffer);
|
||||
break;
|
||||
@@ -110,29 +116,32 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||
if(readBytes != lzmaSize)
|
||||
{
|
||||
fprintf(stderr, "Could not read compressed block, continuing...\n");
|
||||
TRACE("Could not read compressed block, continuing...");
|
||||
free(cmpData);
|
||||
free(buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
readBytes = ddtHeader.length;
|
||||
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||
LZMA_PROPERTIES_LENGTH);
|
||||
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||
LZMA_PROPERTIES_LENGTH);
|
||||
|
||||
if(errorNo != 0)
|
||||
{
|
||||
fprintf(stderr, "Got error %d from LZMA, stopping...\n", errorNo);
|
||||
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||
free(cmpData);
|
||||
free(buffer);
|
||||
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
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(buffer);
|
||||
TRACE("Exiting process_ddt_v2() = 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)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL("Could not initialize CRC64.");
|
||||
free(buffer);
|
||||
|
||||
TRACE("Exiting process_ddt_v2() = 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)
|
||||
{
|
||||
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);
|
||||
TRACE("Exiting process_ddt_v2() = 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)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
||||
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("Reading DDT of length %zu bytes", ddtHeader.length);
|
||||
readBytes = fread(buffer, 1, ddtHeader.length, ctx->imageStream);
|
||||
|
||||
if(readBytes != ddtHeader.length)
|
||||
{
|
||||
free(buffer);
|
||||
FATAL("Could not read deduplication table, continuing...\n");
|
||||
FATAL("Could not read deduplication table, continuing...");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -188,8 +201,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
|
||||
if(crc64_context == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL("Could not initialize CRC64.");
|
||||
free(buffer);
|
||||
TRACE("Exiting process_ddt_v2() = 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)
|
||||
{
|
||||
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);
|
||||
TRACE("Exiting process_ddt_v2() = 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;
|
||||
default:
|
||||
TRACE("Found unknown compression type %d, continuing...\n", ddtHeader.compression);
|
||||
TRACE("Found unknown compression type %d, continuing...", ddtHeader.compression);
|
||||
*foundUserDataDdt = false;
|
||||
break;
|
||||
}
|
||||
@@ -228,14 +243,14 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||
if(cmpData == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
||||
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = malloc(ddtHeader.length);
|
||||
if(buffer == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for DDT, continuing...\n");
|
||||
TRACE("Cannot allocate memory for DDT, continuing...");
|
||||
free(cmpData);
|
||||
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);
|
||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
fprintf(stderr, "Could not read LZMA properties, continuing...\n");
|
||||
TRACE("Could not read LZMA properties, continuing...");
|
||||
free(cmpData);
|
||||
free(buffer);
|
||||
break;
|
||||
@@ -252,29 +267,32 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||
if(readBytes != lzmaSize)
|
||||
{
|
||||
fprintf(stderr, "Could not read compressed block, continuing...\n");
|
||||
TRACE("Could not read compressed block, continuing...");
|
||||
free(cmpData);
|
||||
free(buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
readBytes = ddtHeader.length;
|
||||
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||
LZMA_PROPERTIES_LENGTH);
|
||||
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||
LZMA_PROPERTIES_LENGTH);
|
||||
|
||||
if(errorNo != 0)
|
||||
{
|
||||
fprintf(stderr, "Got error %d from LZMA, stopping...\n", errorNo);
|
||||
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||
free(cmpData);
|
||||
free(buffer);
|
||||
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
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(buffer);
|
||||
TRACE("Exiting process_ddt_v2() = 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)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL("Could not initialize CRC64.");
|
||||
free(buffer);
|
||||
TRACE("Exiting process_ddt_v2() = 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)
|
||||
{
|
||||
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);
|
||||
TRACE("Exiting process_ddt_v2() = 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)
|
||||
{
|
||||
TRACE("Cannot allocate memory for deduplication table.\n");
|
||||
TRACE("Cannot allocate memory for deduplication table.");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -330,7 +350,7 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
if(readBytes != ddtHeader.length)
|
||||
{
|
||||
free(buffer);
|
||||
FATAL("Could not read deduplication table, continuing...\n");
|
||||
FATAL("Could not read deduplication table, continuing...");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -338,8 +358,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
|
||||
if(crc64_context == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL(stderr, "Could not initialize CRC64.");
|
||||
free(buffer);
|
||||
TRACE("Exiting process_ddt_v2() = 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)
|
||||
{
|
||||
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);
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
@@ -372,21 +393,26 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *foundUse
|
||||
|
||||
break;
|
||||
default:
|
||||
TRACE("Found unknown compression type %d, continuing...\n", ddtHeader.compression);
|
||||
TRACE("Found unknown compression type %d, continuing...", ddtHeader.compression);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Exiting process_ddt_v2() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
int32_t decode_ddt_entry_v2(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset, uint64_t *blockOffset,
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
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;
|
||||
|
||||
// Check if the context and image stream are valid
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
sectorAddress += ctx->userDataDdtHeader.negative;
|
||||
@@ -420,7 +456,8 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sectorAddres
|
||||
ddtEntry = ctx->userDataDdtBig[sectorAddress];
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -429,6 +466,8 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sectorAddres
|
||||
*sectorStatus = SectorStatusNotDumped;
|
||||
*offset = 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;
|
||||
}
|
||||
|
||||
@@ -447,12 +486,17 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sectorAddres
|
||||
*offset = ddtEntry & offsetMask;
|
||||
*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;
|
||||
}
|
||||
|
||||
int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress, uint64_t *offset,
|
||||
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;
|
||||
uint8_t lzmaProperties[LZMA_PROPERTIES_LENGTH];
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
sectorAddress += ctx->userDataDdtHeader.negative;
|
||||
@@ -487,7 +538,8 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
||||
secondaryDdtOffset = ctx->userDataDdtBig[ddtPosition];
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -503,15 +555,15 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -524,14 +576,15 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
||||
cmpData = (uint8_t *)malloc(lzmaSize);
|
||||
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;
|
||||
}
|
||||
|
||||
buffer = malloc(ddtHeader.length);
|
||||
if(buffer == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for DDT, stopping...\n");
|
||||
FATAL("Cannot allocate memory for DDT, stopping...");
|
||||
free(cmpData);
|
||||
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);
|
||||
if(readBytes != LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
fprintf(stderr, "Could not read LZMA properties, stopping...\n");
|
||||
FATAL("Could not read LZMA properties, stopping...");
|
||||
free(cmpData);
|
||||
free(buffer);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||
if(readBytes != lzmaSize)
|
||||
{
|
||||
fprintf(stderr, "Could not read compressed block, stopping...\n");
|
||||
FATAL("Could not read compressed block, stopping...");
|
||||
free(cmpData);
|
||||
free(buffer);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
TRACE("Decompressing block of size %zu bytes", ddtHeader.length);
|
||||
readBytes = ddtHeader.length;
|
||||
errorNo = aaruf_lzma_decode_buffer(buffer, &readBytes, cmpData, &lzmaSize, lzmaProperties,
|
||||
LZMA_PROPERTIES_LENGTH);
|
||||
|
||||
if(errorNo != 0)
|
||||
{
|
||||
fprintf(stderr, "Got error %d from LZMA, stopping...\n", errorNo);
|
||||
FATAL("Got error %d from LZMA, stopping...", errorNo);
|
||||
free(cmpData);
|
||||
free(buffer);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
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(buffer);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = 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)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL("Could not initialize CRC64.");
|
||||
free(buffer);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = 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)
|
||||
{
|
||||
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);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -617,7 +678,8 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
||||
if(readBytes != ddtHeader.length)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -625,8 +687,9 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
||||
|
||||
if(crc64_context == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL("Could not initialize CRC64.");
|
||||
free(buffer);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = 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)
|
||||
{
|
||||
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);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -664,6 +729,9 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
||||
*sectorStatus = SectorStatusNotDumped;
|
||||
*offset = 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;
|
||||
}
|
||||
|
||||
@@ -682,5 +750,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sectorAddress
|
||||
*offset = ddtEntry & offsetMask;
|
||||
*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;
|
||||
}
|
||||
@@ -21,10 +21,13 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "aaruformat.h"
|
||||
#include "log.h"
|
||||
#include "utarray.h"
|
||||
|
||||
UT_array *process_index_v1(aaruformatContext *ctx)
|
||||
{
|
||||
TRACE("Entering process_index_v1(%p)", ctx);
|
||||
|
||||
UT_array *index_entries = NULL;
|
||||
IndexEntry entry;
|
||||
|
||||
@@ -36,6 +39,7 @@ UT_array *process_index_v1(aaruformatContext *ctx)
|
||||
utarray_new(index_entries, &index_entry_icd);
|
||||
|
||||
// Read the index header
|
||||
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||
IndexHeader idx_header;
|
||||
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
|
||||
if(idx_header.identifier != IndexBlock)
|
||||
{
|
||||
fprintf(stderr, "Incorrect index identifier.\n");
|
||||
FATAL("Incorrect index identifier.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting process_index_v1() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -54,44 +60,59 @@ UT_array *process_index_v1(aaruformatContext *ctx)
|
||||
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;
|
||||
}
|
||||
|
||||
int32_t verify_index_v1(aaruformatContext *ctx)
|
||||
{
|
||||
TRACE("Entering verify_index_v1(%p)", ctx);
|
||||
|
||||
size_t read_bytes = 0;
|
||||
IndexHeader index_header;
|
||||
uint64_t crc64 = 0;
|
||||
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
|
||||
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);
|
||||
|
||||
// Read the index header
|
||||
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||
read_bytes = fread(&index_header, 1, sizeof(IndexHeader), ctx->imageStream);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -99,8 +120,10 @@ int32_t verify_index_v1(aaruformatContext *ctx)
|
||||
|
||||
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);
|
||||
|
||||
TRACE("Exiting verify_index_v1() = 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)
|
||||
{
|
||||
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);
|
||||
|
||||
TRACE("Exiting verify_index_v1() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
TRACE("Exiting verify_index_v1() = AARUF_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
@@ -21,14 +21,17 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "aaruformat.h"
|
||||
#include "log.h"
|
||||
#include "utarray.h"
|
||||
|
||||
UT_array *process_index_v2(aaruformatContext *ctx)
|
||||
{
|
||||
TRACE("Entering process_index_v2(%p)", ctx);
|
||||
|
||||
UT_array *index_entries = NULL;
|
||||
IndexEntry entry;
|
||||
|
||||
if(ctx == NULL || ctx->imageStream == NULL) return NULL;
|
||||
if(ctx == NULL || ctx->imageStream == NULL) {return NULL;}
|
||||
|
||||
// Initialize the index entries array
|
||||
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);
|
||||
|
||||
// Read the index header
|
||||
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||
IndexHeader2 idx_header;
|
||||
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
|
||||
if(idx_header.identifier != IndexBlock2)
|
||||
{
|
||||
fprintf(stderr, "Incorrect index identifier.\n");
|
||||
FATAL("Incorrect index identifier.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting process_index_v2() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -54,44 +60,60 @@ UT_array *process_index_v2(aaruformatContext *ctx)
|
||||
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;
|
||||
}
|
||||
|
||||
int32_t verify_index_v2(aaruformatContext *ctx)
|
||||
{
|
||||
TRACE("Entering verify_index_v2(%p)", ctx);
|
||||
|
||||
size_t read_bytes = 0;
|
||||
IndexHeader2 index_header;
|
||||
uint64_t crc64 = 0;
|
||||
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
|
||||
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);
|
||||
|
||||
// Read the index header
|
||||
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||
read_bytes = fread(&index_header, 1, sizeof(IndexHeader2), ctx->imageStream);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -99,8 +121,10 @@ int32_t verify_index_v2(aaruformatContext *ctx)
|
||||
|
||||
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);
|
||||
|
||||
TRACE("Exiting verify_index_v2() = 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)
|
||||
{
|
||||
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);
|
||||
|
||||
TRACE("Exiting verify_index_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
TRACE("Exiting verify_index_v2() = AARUF_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
@@ -22,11 +22,14 @@
|
||||
|
||||
#include "aaruformat.h"
|
||||
#include "internal.h"
|
||||
#include "log.h"
|
||||
#include "utarray.h"
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
// Read the index header
|
||||
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||
fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||
IndexHeader3 idx_header;
|
||||
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
|
||||
if(idx_header.identifier != IndexBlock3)
|
||||
{
|
||||
fprintf(stderr, "Incorrect index identifier.\n");
|
||||
FATAL("Incorrect index identifier.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting process_index_v3() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -61,12 +67,15 @@ UT_array *process_index_v3(aaruformatContext *ctx)
|
||||
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;
|
||||
}
|
||||
|
||||
// Add entries from a subindex to the array of index entries
|
||||
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;
|
||||
IndexEntry entry;
|
||||
|
||||
@@ -81,7 +90,9 @@ void add_subindex_entries(aaruformatContext *ctx, UT_array *index_entries, Index
|
||||
// Check if the subindex header is valid
|
||||
if(subindex_header.identifier != IndexBlock3)
|
||||
{
|
||||
fprintf(stderr, "Incorrect subindex identifier.\n");
|
||||
FATAL("Incorrect subindex identifier.");
|
||||
|
||||
TRACE("Exiting add_subindex_entries() without adding entries");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -97,43 +108,60 @@ void add_subindex_entries(aaruformatContext *ctx, UT_array *index_entries, Index
|
||||
}
|
||||
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)
|
||||
{
|
||||
TRACE("Entering verify_index_v3(%p)", ctx);
|
||||
|
||||
size_t read_bytes = 0;
|
||||
IndexHeader3 index_header;
|
||||
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
|
||||
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);
|
||||
|
||||
// Read the index header
|
||||
TRACE("Reading index header at position %llu", ctx->header.indexOffset);
|
||||
read_bytes = fread(&index_header, 1, sizeof(IndexHeader3), ctx->imageStream);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -141,8 +169,10 @@ int32_t verify_index_v3(aaruformatContext *ctx)
|
||||
|
||||
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);
|
||||
|
||||
TRACE("Exiting verify_index_v2() = 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)
|
||||
{
|
||||
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);
|
||||
|
||||
TRACE("Exiting verify_index_v3() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
TRACE("Exiting verify_index_v3() = AARUF_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
54
src/open.c
54
src/open.c
@@ -44,48 +44,65 @@ void *aaruf_open(const char *filepath)
|
||||
slog_init("aaruformat.log", SLOG_FLAGS_ALL, 0);
|
||||
#endif
|
||||
|
||||
TRACE("Logging initialized");
|
||||
|
||||
TRACE("Entering aaruf_open(%s)", filepath);
|
||||
|
||||
TRACE("Allocating memory for context");
|
||||
ctx = (aaruformatContext *)malloc(sizeof(aaruformatContext));
|
||||
memset(ctx, 0, sizeof(aaruformatContext));
|
||||
|
||||
if(ctx == NULL)
|
||||
{
|
||||
FATAL("Not enough memory to create context");
|
||||
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
TRACE("Exiting aaruf_open() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("Opening file %s", filepath);
|
||||
ctx->imageStream = fopen(filepath, "rb");
|
||||
|
||||
if(ctx->imageStream == NULL)
|
||||
{
|
||||
FATAL("Error %d opening file %s for reading", errno, filepath);
|
||||
errorNo = errno;
|
||||
free(ctx);
|
||||
errno = errorNo;
|
||||
|
||||
TRACE("Exiting aaruf_open() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("Reading header at position 0");
|
||||
fseek(ctx->imageStream, 0, SEEK_SET);
|
||||
readBytes = fread(&ctx->header, 1, sizeof(AaruHeader), ctx->imageStream);
|
||||
|
||||
if(readBytes != sizeof(AaruHeader))
|
||||
{
|
||||
FATAL("Could not read header");
|
||||
free(ctx);
|
||||
errno = AARUF_ERROR_FILE_TOO_SMALL;
|
||||
|
||||
TRACE("Exiting aaruf_open() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
errno = AARUF_ERROR_NOT_AARUFORMAT;
|
||||
|
||||
TRACE("Exiting aaruf_open() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Read new header version
|
||||
if(ctx->header.imageMajorVersion >= AARUF_VERSION_V2)
|
||||
{
|
||||
TRACE("Reading new header version at position 0");
|
||||
fseek(ctx->imageStream, 0, SEEK_SET);
|
||||
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)
|
||||
{
|
||||
FATAL("Incompatible AaruFormat version %d.%d found, maximum supported is %d.%d", ctx->header.imageMajorVersion,
|
||||
ctx->header.imageMinorVersion, AARUF_VERSION_V2, 0);
|
||||
free(ctx);
|
||||
errno = AARUF_ERROR_INCOMPATIBLE_VERSION;
|
||||
|
||||
TRACE("Exiting aaruf_open() = 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);
|
||||
|
||||
if(ctx->readableSectorTags == NULL)
|
||||
{
|
||||
FATAL("Could not allocate memory for readable sector tags bitmap");
|
||||
free(ctx);
|
||||
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
TRACE("Exiting aaruf_open() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(ctx->readableSectorTags, 0, sizeof(bool) * MaxSectorTag);
|
||||
|
||||
TRACE("Setting up image info");
|
||||
ctx->imageInfo.Application = ctx->header.application;
|
||||
ctx->imageInfo.ApplicationVersion = (uint8_t *)malloc(32);
|
||||
if(ctx->imageInfo.ApplicationVersion != NULL)
|
||||
@@ -137,6 +161,7 @@ void *aaruf_open(const char *filepath)
|
||||
ctx->imageInfo.MediaType = ctx->header.mediaType;
|
||||
|
||||
// Read the index header
|
||||
TRACE("Reading index header at position %" PRIu64, ctx->header.indexOffset);
|
||||
pos = fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_SET);
|
||||
if(pos < 0)
|
||||
{
|
||||
@@ -160,9 +185,11 @@ void *aaruf_open(const char *filepath)
|
||||
if(readBytes != sizeof(uint32_t) ||
|
||||
(signature != IndexBlock && signature != IndexBlock2 && signature != IndexBlock3))
|
||||
{
|
||||
FATAL("Could not read index header or incorrect identifier %4.4s", (char *)&signature);
|
||||
free(ctx);
|
||||
errno = AARUF_ERROR_CANNOT_READ_INDEX;
|
||||
|
||||
TRACE("Exiting aaruf_open() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -175,20 +202,21 @@ void *aaruf_open(const char *filepath)
|
||||
|
||||
if(index_entries == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not process index.\n");
|
||||
FATAL("Could not process index.");
|
||||
utarray_free(index_entries);
|
||||
free(ctx);
|
||||
errno = AARUF_ERROR_CANNOT_READ_INDEX;
|
||||
|
||||
TRACE("Exiting aaruf_open() = 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++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -201,13 +229,13 @@ void *aaruf_open(const char *filepath)
|
||||
|
||||
if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"libaaruformat: Could not seek to %" PRIu64 " as indicated by index entry %d, continuing...\n",
|
||||
entry->offset, i);
|
||||
TRACE("Could not seek to %" PRIu64 " as indicated by index entry %d, continuing...", entry->offset, i);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACE("Processing block type %4.4s with data type %d at position %" PRIu64 "", (char *)&entry->blockType,
|
||||
entry->dataType, entry->offset);
|
||||
switch(entry->blockType)
|
||||
{
|
||||
case DataBlock:
|
||||
@@ -276,9 +304,8 @@ void *aaruf_open(const char *filepath)
|
||||
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"libaaruformat: Unhandled block type %4.4s with data type %d is indexed to be at %" PRIu64 "\n",
|
||||
(char *)&entry->blockType, entry->dataType, entry->offset);
|
||||
TRACE("Unhandled block type %4.4s with data type %d is indexed to be at %" PRIu64 "",
|
||||
(char *)&entry->blockType, entry->dataType, entry->offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -287,8 +314,10 @@ void *aaruf_open(const char *filepath)
|
||||
|
||||
if(!foundUserDataDdt)
|
||||
{
|
||||
FATAL("Could not find user data deduplication table, aborting...\n");
|
||||
FATAL("Could not find user data deduplication table, aborting...");
|
||||
aaruf_close(ctx);
|
||||
|
||||
TRACE("Exiting aaruf_open() = NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -304,6 +333,7 @@ void *aaruf_open(const char *filepath)
|
||||
}
|
||||
|
||||
// Initialize caches
|
||||
TRACE("Initializing caches");
|
||||
ctx->blockHeaderCache.cache = NULL;
|
||||
ctx->blockHeaderCache.max_items = MAX_CACHE_SIZE / (ctx->imageInfo.SectorSize * (1 << ctx->shift));
|
||||
ctx->blockCache.cache = NULL;
|
||||
@@ -312,11 +342,13 @@ void *aaruf_open(const char *filepath)
|
||||
// TODO: Cache tracks and sessions?
|
||||
|
||||
// Initialize ECC for Compact Disc
|
||||
TRACE("Initializing ECC for Compact Disc");
|
||||
ctx->eccCdContext = (CdEccContext *)aaruf_ecc_cd_init();
|
||||
|
||||
ctx->magic = AARU_MAGIC;
|
||||
ctx->libraryMajorVersion = LIBAARUFORMAT_MAJOR_VERSION;
|
||||
ctx->libraryMinorVersion = LIBAARUFORMAT_MINOR_VERSION;
|
||||
|
||||
TRACE("Exiting aaruf_open() = %p", ctx);
|
||||
return ctx;
|
||||
}
|
||||
@@ -25,8 +25,12 @@
|
||||
#include "internal.h"
|
||||
#include "structs/options.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
aaru_options parse_options(const char *options)
|
||||
{
|
||||
TRACE("Entering aaruf_open(%s)", options);
|
||||
|
||||
aaru_options parsed = {.compress = true,
|
||||
.deduplicate = true,
|
||||
.dictionary = 33554432,
|
||||
@@ -93,5 +97,9 @@ aaru_options parse_options(const char *options)
|
||||
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;
|
||||
}
|
||||
299
src/read.c
299
src/read.c
@@ -22,41 +22,65 @@
|
||||
#include <aaruformat.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "log.h"
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
if(item == NULL)
|
||||
{
|
||||
TRACE("Media tag not found");
|
||||
*length = 0;
|
||||
|
||||
TRACE("Exiting aaruf_read_media_tag() = AARUF_ERROR_MEDIA_TAG_NOT_PRESENT");
|
||||
return AARUF_ERROR_MEDIA_TAG_NOT_PRESENT;
|
||||
}
|
||||
|
||||
if(data == NULL || *length < item->length)
|
||||
{
|
||||
TRACE("Buffer too small for media tag %d, required %u bytes", tag, item->length);
|
||||
*length = item->length;
|
||||
|
||||
TRACE("Exiting aaruf_read_media_tag() = AARUF_ERROR_BUFFER_TOO_SMALL");
|
||||
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
*length = 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;
|
||||
}
|
||||
|
||||
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;
|
||||
uint64_t offset = 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;
|
||||
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;
|
||||
|
||||
// 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)
|
||||
errorNo = decode_ddt_entry_v1(ctx, sectorAddress, &offset, &blockOffset, §orStatus);
|
||||
else if(ctx->ddtVersion == 2)
|
||||
errorNo = decode_ddt_entry_v2(ctx, sectorAddress, &offset, &blockOffset, §orStatus);
|
||||
|
||||
if(errorNo != AARUF_STATUS_OK) return errorNo;
|
||||
if(errorNo != AARUF_STATUS_OK)
|
||||
{
|
||||
FATAL("Error %d decoding DDT entry", errorNo);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = %d", errorNo);
|
||||
return errorNo;
|
||||
}
|
||||
|
||||
// Partially written image... as we can't know the real sector size just assume it's common :/
|
||||
if(sectorStatus == SectorStatusNotDumped)
|
||||
{
|
||||
memset(data, 0, ctx->imageInfo.SectorSize);
|
||||
*length = ctx->imageInfo.SectorSize;
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = AARUF_STATUS_SECTOR_NOT_DUMPED");
|
||||
return AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||
}
|
||||
|
||||
// Check if block header is cached
|
||||
TRACE("Checking if block header is cached");
|
||||
blockHeader = find_in_cache_uint64(&ctx->blockHeaderCache, blockOffset);
|
||||
|
||||
// Read block header
|
||||
if(blockHeader == NULL)
|
||||
{
|
||||
TRACE("Allocating memory for block header");
|
||||
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);
|
||||
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);
|
||||
}
|
||||
else
|
||||
@@ -114,17 +180,24 @@ int32_t aaruf_read_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
||||
|
||||
if(data == NULL || *length < blockHeader->sectorSize)
|
||||
{
|
||||
TRACE("Buffer too small for sector, required %u bytes", blockHeader->sectorSize);
|
||||
*length = blockHeader->sectorSize;
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_BUFFER_TOO_SMALL");
|
||||
return AARUF_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
// Check if block is cached
|
||||
TRACE("Checking if block is cached");
|
||||
block = find_in_cache_uint64(&ctx->blockCache, blockOffset);
|
||||
|
||||
if(block != NULL)
|
||||
{
|
||||
TRACE("Getting data from cache");
|
||||
memcpy(data, block + offset, blockHeader->sectorSize);
|
||||
*length = blockHeader->sectorSize;
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = 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)
|
||||
{
|
||||
case None:
|
||||
TRACE("Allocating memory for block");
|
||||
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);
|
||||
|
||||
if(readBytes != blockHeader->length)
|
||||
{
|
||||
FATAL("Could not read block");
|
||||
free(block);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||
}
|
||||
|
||||
break;
|
||||
case Lzma:
|
||||
lzmaSize = blockHeader->cmpLength - LZMA_PROPERTIES_LENGTH;
|
||||
cmpData = malloc(lzmaSize);
|
||||
TRACE("Allocating memory for compressed data of size %zu bytes", lzmaSize);
|
||||
cmpData = malloc(lzmaSize);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
TRACE("Allocating memory for block of size %zu bytes", blockHeader->length);
|
||||
block = malloc(blockHeader->length);
|
||||
if(block == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for block...\n");
|
||||
FATAL("Cannot allocate memory for block...");
|
||||
free(cmpData);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = 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)
|
||||
{
|
||||
fprintf(stderr, "Could not read LZMA properties...\n");
|
||||
FATAL("Could not read LZMA properties...");
|
||||
free(block);
|
||||
free(cmpData);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
readBytes = fread(cmpData, 1, lzmaSize, ctx->imageStream);
|
||||
if(readBytes != lzmaSize)
|
||||
{
|
||||
fprintf(stderr, "Could not read compressed block...\n");
|
||||
FATAL("Could not read compressed block...");
|
||||
free(cmpData);
|
||||
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;
|
||||
errorNo =
|
||||
aaruf_lzma_decode_buffer(block, &readBytes, cmpData, &lzmaSize, lzmaProperties, LZMA_PROPERTIES_LENGTH);
|
||||
|
||||
if(errorNo != 0)
|
||||
{
|
||||
fprintf(stderr, "Got error %d from LZMA...\n", errorNo);
|
||||
FATAL("Got error %d from LZMA...", errorNo);
|
||||
free(cmpData);
|
||||
free(block);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
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(block);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = 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;
|
||||
case Flac:
|
||||
TRACE("Allocating memory for compressed data of size %zu bytes", blockHeader->cmpLength);
|
||||
cmpData = malloc(blockHeader->cmpLength);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
TRACE("Allocating memory for block of size %zu bytes", blockHeader->length);
|
||||
block = malloc(blockHeader->length);
|
||||
if(block == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for block...\n");
|
||||
FATAL("Cannot allocate memory for block...");
|
||||
free(cmpData);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = 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);
|
||||
if(readBytes != blockHeader->cmpLength)
|
||||
{
|
||||
fprintf(stderr, "Could not read compressed block...\n");
|
||||
FATAL("Could not read compressed block...");
|
||||
free(cmpData);
|
||||
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);
|
||||
|
||||
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(block);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = 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;
|
||||
default:
|
||||
FATAL("Unsupported compression %d", blockHeader->compression);
|
||||
TRACE("Exiting aaruf_read_sector() = AARUF_ERROR_UNSUPPORTED_COMPRESSION");
|
||||
return AARUF_ERROR_UNSUPPORTED_COMPRESSION;
|
||||
}
|
||||
|
||||
// Add block to cache
|
||||
TRACE("Adding block to cache");
|
||||
add_to_cache_uint64(&ctx->blockCache, blockOffset, block);
|
||||
|
||||
memcpy(data, block + (offset * blockHeader->sectorSize), blockHeader->sectorSize);
|
||||
*length = blockHeader->sectorSize;
|
||||
|
||||
TRACE("Exiting aaruf_read_sector() = 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)
|
||||
{
|
||||
TRACE("Entering aaruf_read_track_sector(%p, %p, %" PRIu64 ", %u, %d)", context, data, sectorAddress, *length,
|
||||
track);
|
||||
|
||||
aaruformatContext *ctx;
|
||||
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;
|
||||
|
||||
// Not a libaaruformat context
|
||||
if(ctx->magic != AARU_MAGIC) return AARUF_ERROR_NOT_AARUFORMAT;
|
||||
|
||||
if(ctx->imageInfo.XmlMediaType != OpticalDisc) return AARUF_ERROR_INCORRECT_MEDIA_TYPE;
|
||||
|
||||
for(i = 0; i < ctx->numberOfDataTracks; i++)
|
||||
if(ctx->magic != AARU_MAGIC)
|
||||
{
|
||||
if(ctx->dataTracks[i].sequence == track)
|
||||
{
|
||||
return aaruf_read_sector(context, ctx->dataTracks[i].start + sectorAddress, data, length);
|
||||
}
|
||||
FATAL("Invalid context");
|
||||
|
||||
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++)
|
||||
if(ctx->dataTracks[i].sequence == track)
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
uint32_t bareLength = 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;
|
||||
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;
|
||||
|
||||
// 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)
|
||||
{
|
||||
@@ -304,6 +453,9 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
||||
if(*length < 2352 || data == NULL)
|
||||
{
|
||||
*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;
|
||||
}
|
||||
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;
|
||||
aaruf_read_sector(context, sectorAddress, NULL, &bareLength);
|
||||
|
||||
TRACE("Allocating memory for bare data");
|
||||
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);
|
||||
|
||||
if(res < AARUF_STATUS_OK)
|
||||
{
|
||||
free(bareData);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = %d", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
trkFound = false;
|
||||
|
||||
for(i = 0; i < ctx->numberOfDataTracks; i++)
|
||||
{
|
||||
if(sectorAddress >= ctx->dataTracks[i].start && sectorAddress <= ctx->dataTracks[i].end)
|
||||
{
|
||||
trkFound = true;
|
||||
trk = ctx->dataTracks[i];
|
||||
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)
|
||||
{
|
||||
@@ -358,19 +523,18 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
||||
res = AARUF_STATUS_OK;
|
||||
}
|
||||
else if((ctx->sectorPrefixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
||||
{
|
||||
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(data,
|
||||
ctx->sectorPrefixCorrected +
|
||||
((ctx->sectorPrefixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 16,
|
||||
16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
|
||||
return AARUF_ERROR_REACHED_UNREACHABLE_CODE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
else if((ctx->sectorSuffixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
||||
{
|
||||
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(data + 2064,
|
||||
ctx->sectorSuffixCorrected +
|
||||
((ctx->sectorSuffixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 288,
|
||||
288);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
|
||||
return AARUF_ERROR_REACHED_UNREACHABLE_CODE;
|
||||
}
|
||||
|
||||
return res;
|
||||
case CdMode2Formless:
|
||||
@@ -412,19 +575,18 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
||||
res = AARUF_STATUS_OK;
|
||||
}
|
||||
else if((ctx->sectorPrefixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
||||
{
|
||||
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(data,
|
||||
ctx->sectorPrefixCorrected +
|
||||
((ctx->sectorPrefixDdt[sectorAddress] & CD_DFIX_MASK) - 1) * 16,
|
||||
16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
|
||||
return AARUF_ERROR_REACHED_UNREACHABLE_CODE;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else if((ctx->sectorSuffixDdt[sectorAddress] & CD_XFIX_MASK) == NotDumped)
|
||||
{
|
||||
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
|
||||
}
|
||||
else
|
||||
// Mode 2 where ECC failed
|
||||
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;
|
||||
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;
|
||||
}
|
||||
case BlockMedia:
|
||||
@@ -490,6 +654,9 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
||||
tagLength = 24;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -498,27 +665,51 @@ int32_t aaruf_read_sector_long(void *context, uint64_t sectorAddress, uint8_t *d
|
||||
if(*length < tagLength + bareLength || data == NULL)
|
||||
{
|
||||
*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;
|
||||
}
|
||||
|
||||
TRACE("Allocating memory for bare data of size %u bytes", 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);
|
||||
|
||||
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, bareData, 512);
|
||||
|
||||
free(bareData);
|
||||
|
||||
TRACE("Exiting aaruf_read_sector_long() = %d", res);
|
||||
return res;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
126
src/verify.c
126
src/verify.c
@@ -20,67 +20,97 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "log.h"
|
||||
#include "utarray.h"
|
||||
|
||||
#define VERIFY_SIZE 1048576
|
||||
|
||||
int32_t aaruf_verify_image(void *context)
|
||||
{
|
||||
TRACE("Entering aaruf_verify_image(%p)", context);
|
||||
|
||||
aaruformatContext *ctx = NULL;
|
||||
uint64_t crc64 = 0;
|
||||
size_t read_bytes = 0;
|
||||
void * buffer = NULL;
|
||||
crc64_ctx * crc64_context = NULL;
|
||||
void *buffer = NULL;
|
||||
crc64_ctx *crc64_context = NULL;
|
||||
BlockHeader block_header;
|
||||
uint64_t verified_bytes = 0;
|
||||
DdtHeader ddt_header;
|
||||
DdtHeader2 ddt2_header;
|
||||
TracksHeader tracks_header;
|
||||
uint32_t signature = 0;
|
||||
UT_array * index_entries = NULL;
|
||||
UT_array *index_entries = NULL;
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
TRACE("Reading index signature at position %llu", ctx->header.indexOffset);
|
||||
read_bytes = fread(&signature, 1, sizeof(uint32_t), ctx->imageStream);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Check if the index is correct
|
||||
if(signature == IndexBlock) err = verify_index_v1(ctx);
|
||||
else if(signature == IndexBlock2) err = verify_index_v2(ctx);
|
||||
else if(signature == IndexBlock3) err = verify_index_v3(ctx);
|
||||
if(signature == IndexBlock)
|
||||
err = verify_index_v1(ctx);
|
||||
else if(signature == IndexBlock2)
|
||||
err = verify_index_v2(ctx);
|
||||
else if(signature == IndexBlock3)
|
||||
err = verify_index_v3(ctx);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Process the index
|
||||
if(signature == IndexBlock) index_entries = process_index_v1(ctx);
|
||||
else if(signature == IndexBlock2) index_entries = process_index_v2(ctx);
|
||||
else if(signature == IndexBlock3) index_entries = process_index_v3(ctx);
|
||||
if(signature == IndexBlock)
|
||||
index_entries = process_index_v1(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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -88,27 +118,31 @@ int32_t aaruf_verify_image(void *context)
|
||||
|
||||
if(buffer == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot allocate memory for buffer.\n");
|
||||
FATAL("Cannot allocate memory for buffer.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
|
||||
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
for(int i = 0; i < utarray_len(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,
|
||||
entry->offset);
|
||||
TRACE("Checking block with type %4.4s at position %" PRIu64 "", (char *)&entry->blockType, entry->offset);
|
||||
|
||||
fseek(ctx->imageStream, entry->offset, SEEK_SET);
|
||||
|
||||
switch(entry->blockType)
|
||||
{
|
||||
case DataBlock:
|
||||
TRACE("Reading block header");
|
||||
read_bytes = fread(&block_header, 1, sizeof(BlockHeader), ctx->imageStream);
|
||||
if(read_bytes != sizeof(BlockHeader))
|
||||
{
|
||||
fprintf(stderr, "Could not read block header.\n");
|
||||
FATAL("Could not read block header.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = 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)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL("Could not initialize CRC64.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||
}
|
||||
|
||||
verified_bytes = 0;
|
||||
|
||||
TRACE("Calculating CRC64...");
|
||||
while(verified_bytes + VERIFY_SIZE < block_header.cmpLength)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
break;
|
||||
case DeDuplicationTable:
|
||||
TRACE("Reading DDT header");
|
||||
read_bytes = fread(&ddt_header, 1, sizeof(DdtHeader), ctx->imageStream);
|
||||
if(read_bytes != sizeof(DdtHeader))
|
||||
{
|
||||
fprintf(stderr, "Could not read DDT header.\n");
|
||||
FATAL("Could not read DDT header.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = 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)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL("Could not initialize CRC64.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||
}
|
||||
|
||||
verified_bytes = 0;
|
||||
|
||||
TRACE("Calculating DDT CRC64...");
|
||||
while(verified_bytes + VERIFY_SIZE < ddt_header.cmpLength)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
break;
|
||||
case DeDuplicationTable2:
|
||||
TRACE("Reading DDT2 header");
|
||||
read_bytes = fread(&ddt2_header, 1, sizeof(DdtHeader2), ctx->imageStream);
|
||||
if(read_bytes != sizeof(DdtHeader2))
|
||||
{
|
||||
fprintf(stderr, "Could not read DDT header.\n");
|
||||
FATAL("Could not read DDT header.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = 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)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL("Could not initialize CRC64.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||
}
|
||||
|
||||
verified_bytes = 0;
|
||||
|
||||
TRACE("Calculating DDT2 CRC64...");
|
||||
while(verified_bytes + VERIFY_SIZE < ddt2_header.cmpLength)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
break;
|
||||
case TracksBlock:
|
||||
TRACE("Reading tracks header");
|
||||
read_bytes = fread(&tracks_header, 1, sizeof(TracksHeader), ctx->imageStream);
|
||||
if(read_bytes != sizeof(TracksHeader))
|
||||
{
|
||||
fprintf(stderr, "Could not read tracks header.\n");
|
||||
FATAL("Could not read tracks header.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = 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)
|
||||
{
|
||||
fprintf(stderr, "Could not initialize CRC64.\n");
|
||||
FATAL("Could not initialize CRC64.");
|
||||
utarray_free(index_entries);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = 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);
|
||||
aaruf_crc64_update(crc64_context, buffer, read_bytes);
|
||||
|
||||
@@ -257,17 +318,20 @@ int32_t aaruf_verify_image(void *context)
|
||||
|
||||
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);
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Ignoring block type %4.4s.\n", (char *)&entry->blockType);
|
||||
TRACE("Ignoring block type %4.4s.", (char *)&entry->blockType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Exiting aaruf_verify_image() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
59
src/write.c
59
src/write.c
@@ -24,19 +24,41 @@
|
||||
|
||||
#include "aaruformat.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)
|
||||
{
|
||||
TRACE("Entering aaruf_write_sector(%p, %" PRIu64 ", %p, %u, %u)", context, sectorAddress, data, sectorStatus,
|
||||
length);
|
||||
|
||||
// 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;
|
||||
|
||||
// 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
|
||||
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
|
||||
|
||||
@@ -51,29 +73,47 @@ int32_t aaruf_write_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
||||
// TODO: Implement compression
|
||||
))
|
||||
{
|
||||
TRACE("Closing current block before writing new data");
|
||||
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
|
||||
if(ctx->writingBufferPosition == 0)
|
||||
{
|
||||
TRACE("Creating new writing block");
|
||||
ctx->currentBlockHeader.identifier = DataBlock;
|
||||
ctx->currentBlockHeader.type = UserData;
|
||||
ctx->currentBlockHeader.compression = None; // TODO: Compression
|
||||
ctx->currentBlockHeader.sectorSize = length;
|
||||
|
||||
// TODO: Optical discs
|
||||
|
||||
uint32_t maxBufferSize = (1 << ctx->userDataDdtHeader.dataShift) * ctx->currentBlockHeader.sectorSize;
|
||||
ctx->writingBuffer = (uint8_t *)malloc(maxBufferSize);
|
||||
if(ctx->writingBuffer == NULL) return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||
TRACE("Setting max buffer size to %u bytes", maxBufferSize);
|
||||
|
||||
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();
|
||||
|
||||
// Get current file position
|
||||
long pos = ftell(ctx->imageStream);
|
||||
TRACE("Saving current file position as next block position: %ld", pos);
|
||||
|
||||
// Calculate and save next block aligned position
|
||||
ctx->nextBlockPosition =
|
||||
@@ -82,11 +122,16 @@ int32_t aaruf_write_sector(void *context, uint64_t sectorAddress, uint8_t *data,
|
||||
|
||||
// TODO: DDT entry
|
||||
|
||||
TRACE("Copying data to writing buffer at position %zu", ctx->writingBufferPosition);
|
||||
memcpy(ctx->writingBuffer, data, length);
|
||||
TRACE("Advancing writing buffer position to %zu", ctx->writingBufferPosition + length);
|
||||
ctx->writingBufferPosition += length;
|
||||
TRACE("Updating CRC64");
|
||||
aaruf_crc64_update(ctx->crc64Context, data, length);
|
||||
TRACE("Advancing current block offset to %zu", ctx->currentBlockOffset + 1);
|
||||
ctx->currentBlockOffset++;
|
||||
|
||||
TRACE("Exiting aaruf_write_sector() = AARUF_STATUS_OK");
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user