diff --git a/include/dicformat/context.h b/include/dicformat/context.h index 3ded6f1..7ce2359 100644 --- a/include/dicformat/context.h +++ b/include/dicformat/context.h @@ -50,6 +50,10 @@ typedef struct dicformatContext unsigned char *sectorSuffixCorrected; unsigned char *sectorSubchannel; unsigned char *mode2Subheaders; + byte shift; + bool inMemoryDdt; + uint64_t *userDataDdt; + size_t mappedMemoryDdtSize; } dicformatContext; typedef struct dataLinkedList diff --git a/src/close.c b/src/close.c index b4d5cf0..7179db3 100644 --- a/src/close.c +++ b/src/close.c @@ -34,6 +34,7 @@ #include #include #include +#include int close(void *context) { @@ -82,6 +83,10 @@ int close(void *context) free(ctx->mediaTagsHead); } + if(!ctx->inMemoryDdt) + { + munmap(ctx->userDataDdt, ctx->mappedMemoryDdtSize); + } free(context); return 0; diff --git a/src/open.c b/src/open.c index e45ae91..823e467 100644 --- a/src/open.c +++ b/src/open.c @@ -37,6 +37,7 @@ #include #include #include +#include // TODO: Check CRC64 on structures // TODO: ImageInfo @@ -178,6 +179,9 @@ void *open(const char *filepath) continue; } + BlockHeader blockHeader; + DdtHeader ddtHeader; + switch(idxEntries[i].blockType) { case DataBlock: @@ -185,8 +189,6 @@ void *open(const char *filepath) if(idxEntries[i].dataType == NoData) break; - BlockHeader blockHeader; - readBytes = fread(&blockHeader, sizeof(BlockHeader), 1, ctx->imageStream); if(readBytes != sizeof(BlockHeader)) @@ -376,8 +378,51 @@ void *open(const char *filepath) } break; - case DeDuplicationTable: - // TODO + case DeDuplicationTable:readBytes = fread(&ddtHeader, sizeof(DdtHeader), 1, ctx->imageStream); + + if(readBytes != sizeof(DdtHeader)) + { + fprintf(stderr, "libdicformat: Could not read block header at %"PRIu64"", idxEntries[i].offset); + + break; + } + + foundUserDataDdt = true; + + if(idxEntries[i].dataType == UserData) + { + ctx->shift = ddtHeader.shift; + + // Check for DDT compression + switch(ddtHeader.compression) + { + case None:ctx->mappedMemoryDdtSize = sizeof(uint64_t) * ddtHeader.entries; + ctx->userDataDdt = + mmap(NULL, + ctx->mappedMemoryDdtSize, + PROT_READ, + MAP_SHARED, + fileno(ctx->imageStream), + idxEntries[i].offset + sizeof(ddtHeader)); + + if(ctx->userDataDdt == MAP_FAILED) + { + foundUserDataDdt = false; + fprintf(stderr, "libdicformat: Could not read map deduplication table."); + break; + } + + ctx->inMemoryDdt = false; + break; + default: + fprintf(stderr, + "libdicformat: Found unknown compression type %d, continuing...", + blockHeader.compression); + foundUserDataDdt = false; + break; + + } + } break; case GeometryBlock: // TODO