diff --git a/CMakeLists.txt b/CMakeLists.txt index b255713..6343562 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.13) project(libdicformat C) set(CMAKE_C_STANDARD 99) +add_compile_definitions(__STDC_FORMAT_MACROS=1) add_library(libdicformat SHARED include/dicformat/consts.h include/dicformat/enums.h include/dic.h include/dicformat.h include/dicformat/decls.h include/dicformat/structs.h src/identify.c src/open.c include/dicformat/context.h src/close.c include/dicformat/errors.h) diff --git a/include/dicformat/context.h b/include/dicformat/context.h index 7b6ca19..15f7c86 100644 --- a/include/dicformat/context.h +++ b/include/dicformat/context.h @@ -10,11 +10,21 @@ typedef struct dicformatContext { - uint64_t magic; - uint8_t libraryMajorVersion; - uint8_t libraryMinorVersion; - FILE *imageStream; - DicHeader header; + uint64_t magic; + uint8_t libraryMajorVersion; + uint8_t libraryMinorVersion; + FILE *imageStream; + DicHeader header; + struct dataLinkedList *mediaTagsHead; + struct dataLinkedList *mediaTagsTail; } dicformatContext; +typedef struct dataLinkedList +{ + struct dataLinkedList *previous; + struct dataLinkedList *next; + unsigned char *data; + int type; +} dataLinkedList; + #endif //LIBDICFORMAT_CONTEXT_H diff --git a/include/dicformat/enums.h b/include/dicformat/enums.h index b8915a4..6535c07 100644 --- a/include/dicformat/enums.h +++ b/include/dicformat/enums.h @@ -183,21 +183,21 @@ typedef enum typedef enum { /** Block containing data */ - DataBlock = 0x4B4C4244, + DataBlock = 0x4B4C4244, /** Block containing a deduplication table */ - DeDuplicationTable = 0X2A544444, + DeDuplicationTable = 0X2A544444, /** Block containing the index */ - Index = 0X58444E49, + IndexBlock = 0X58444E49, /** Block containing logical geometry */ - GeometryBlock = 0x4D4F4547, + GeometryBlock = 0x4D4F4547, /** Block containing metadata */ - MetadataBlock = 0x4154454D, + MetadataBlock = 0x4154454D, /** Block containing optical disc tracks */ - TracksBlock = 0x534B5254, + TracksBlock = 0x534B5254, /** Block containing CICM XML metadata */ - CicmBlock = 0x4D434943, + CicmBlock = 0x4D434943, /** Block containing contents checksums */ - ChecksumBlock = 0x4D534B43, + ChecksumBlock = 0x4D534B43, /** TODO: Block containing data position measurements */ DataPositionMeasurementBlock = 0x2A4D5044, /** TODO: Block containing a snapshot index */ diff --git a/include/dicformat/errors.h b/include/dicformat/errors.h index 574398d..a01323b 100644 --- a/include/dicformat/errors.h +++ b/include/dicformat/errors.h @@ -7,6 +7,7 @@ #define DICF_ERROR_NOT_DICFORMAT -1 #define DICF_ERROR_FILE_TOO_SMALL -2 -#define DICF_ERROR_INCOMPATIBLE_VERSION -2 +#define DICF_ERROR_INCOMPATIBLE_VERSION -3 +#define DICF_ERROR_CANNOT_READ_INDEX -4 #endif //LIBDICFORMAT_ERRORS_H diff --git a/include/dicformat/structs.h b/include/dicformat/structs.h index 1ed029b..2a76a14 100644 --- a/include/dicformat/structs.h +++ b/include/dicformat/structs.h @@ -104,7 +104,7 @@ typedef struct IndexHeader typedef struct IndexEntry { /**Type of item pointed by this entry */ - uint32_t uint32_t; + uint32_t blockType; /**Type of data contained by the block pointed by this entry */ uint16_t dataType; /**Offset in file where item is stored */ diff --git a/src/open.c b/src/open.c index 4d17914..3a7f933 100644 --- a/src/open.c +++ b/src/open.c @@ -34,12 +34,21 @@ #include #include #include +#include +#include +// TODO: Check CRC64 on structures +// TODO: ImageInfo void *open(const char *filepath) { dicformatContext *ctx = malloc(sizeof(dicformatContext)); int errorNo; size_t readBytes; + long pos; + IndexHeader idxHeader; + IndexEntry *idxEntries; + + memset(ctx, 0, sizeof(dicformatContext)); if(ctx == NULL) return NULL; @@ -82,14 +91,78 @@ void *open(const char *filepath) return NULL; } + fprintf(stderr, + "libdicformat: Opening image version %d.%d", + ctx->header.imageMajorVersion, + ctx->header.imageMinorVersion); + + // Read the index header + pos = fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_CUR); + if(pos < 0) + { + free(ctx); + errno = DICF_ERROR_CANNOT_READ_INDEX; + + return NULL; + } + + pos = ftell(ctx->imageStream); + if(pos != ctx->header.indexOffset) + { + free(ctx); + errno = DICF_ERROR_CANNOT_READ_INDEX; + + return NULL; + } + + readBytes = fread(&idxHeader, sizeof(IndexHeader), 1, ctx->imageStream); + + if(readBytes != sizeof(IndexHeader) || idxHeader.identifier != IndexBlock) + { + free(ctx); + errno = DICF_ERROR_CANNOT_READ_INDEX; + + return NULL; + } + + fprintf(stderr, "libdicformat: Index at %"PRIu64" contains %d entries", ctx->header.indexOffset, idxHeader.entries); + + idxEntries = malloc(sizeof(IndexEntry) * idxHeader.entries); + + if(idxEntries == NULL) + { + errorNo = errno; + free(ctx); + errno = errorNo; + + return NULL; + } + + memset(idxEntries, 0, sizeof(IndexEntry) * idxHeader.entries); + readBytes = fread(idxEntries, sizeof(IndexEntry), idxHeader.entries, ctx->imageStream); + + if(readBytes != sizeof(IndexEntry) * idxHeader.entries) + { + free(idxEntries); + free(ctx); + errno = DICF_ERROR_CANNOT_READ_INDEX; + + return NULL; + } + + for(int i = 0; i < idxHeader.entries; i++) + { + fprintf(stderr, + "libdicformat: Block type %4s with data type %4s is indexed to be at %"PRIu64"", + (char *)&idxEntries[i].blockType, + (char *)&idxEntries[i].dataType, + idxEntries[i].offset); + } + ctx->magic = DIC_MAGIC; ctx->libraryMajorVersion = LIBDICFORMAT_MAJOR_VERSION; ctx->libraryMinorVersion = LIBDICFORMAT_MINOR_VERSION; - fprintf(stderr, - "libdicformat: Opened image version %d.%d", - ctx->header.imageMajorVersion, - ctx->header.imageMinorVersion); - + free(idxEntries); return ctx; } \ No newline at end of file