diff --git a/CMakeLists.txt b/CMakeLists.txt index ae8ea61..b255713 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,6 @@ project(libdicformat C) set(CMAKE_C_STANDARD 99) 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) + 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) include_directories(include include/dicformat) \ No newline at end of file diff --git a/include/dicformat.h b/include/dicformat.h index b307382..582213b 100644 --- a/include/dicformat.h +++ b/include/dicformat.h @@ -33,9 +33,14 @@ #ifndef LIBDICFORMAT_DICFORMAT_H #define LIBDICFORMAT_DICFORMAT_H +#define LIBDICFORMAT_MAJOR_VERSION 1 +#define LIBDICFORMAT_MINOR_VERSION 0 + +#include "dicformat/errors.h" #include "dicformat/consts.h" #include "dicformat/enums.h" #include "dicformat/decls.h" #include "dicformat/structs.h" +#include "dicformat/context.h" #endif //LIBDICFORMAT_DICFORMAT_H diff --git a/include/dicformat/context.h b/include/dicformat/context.h new file mode 100644 index 0000000..7b6ca19 --- /dev/null +++ b/include/dicformat/context.h @@ -0,0 +1,20 @@ +// +// Created by claunia on 17/03/19. +// + +#ifndef LIBDICFORMAT_CONTEXT_H +#define LIBDICFORMAT_CONTEXT_H + +#include +#include + +typedef struct dicformatContext +{ + uint64_t magic; + uint8_t libraryMajorVersion; + uint8_t libraryMinorVersion; + FILE *imageStream; + DicHeader header; +} dicformatContext; + +#endif //LIBDICFORMAT_CONTEXT_H diff --git a/include/dicformat/decls.h b/include/dicformat/decls.h index 537c9f4..2dfd745 100644 --- a/include/dicformat/decls.h +++ b/include/dicformat/decls.h @@ -37,4 +37,9 @@ int identify(const char *filename); int identifyStream(FILE *imageStream); +void *open(const char *filepath); + +int close(void *context) + + #endif //LIBDICFORMAT_DECLS_H diff --git a/include/dicformat/errors.h b/include/dicformat/errors.h new file mode 100644 index 0000000..574398d --- /dev/null +++ b/include/dicformat/errors.h @@ -0,0 +1,12 @@ +// +// Created by claunia on 17/03/19. +// + +#ifndef LIBDICFORMAT_ERRORS_H +#define LIBDICFORMAT_ERRORS_H + +#define DICF_ERROR_NOT_DICFORMAT -1 +#define DICF_ERROR_FILE_TOO_SMALL -2 +#define DICF_ERROR_INCOMPATIBLE_VERSION -2 + +#endif //LIBDICFORMAT_ERRORS_H diff --git a/src/close.c b/src/close.c new file mode 100644 index 0000000..423d1ae --- /dev/null +++ b/src/close.c @@ -0,0 +1,62 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : close.c +// Author(s) : Natalia Portillo +// +// Component : libdicformat. +// +// --[ Description ] ---------------------------------------------------------- +// +// Handles closing DiscImageChef format disk images. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2019 Natalia Portillo +// ****************************************************************************/ + +#include +#include +#include +#include + +int close(void *context) +{ + if(context == NULL) + { + errno = EINVAL; + return -1; + } + + dicformatContext *ctx = context; + + // TODO: Cast this field without casting the whole structure, as this can buffer overlow + // Not a libdicformat context + if(ctx->magic != DIC_MAGIC) + { + errno = EINVAL; + return -1; + } + + if(ctx->imageStream != NULL) + fclose(ctx->imageStream); + + free(context); + + return 0; +} \ No newline at end of file diff --git a/src/open.c b/src/open.c new file mode 100644 index 0000000..4d17914 --- /dev/null +++ b/src/open.c @@ -0,0 +1,95 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : open.c +// Author(s) : Natalia Portillo +// +// Component : libdicformat. +// +// --[ Description ] ---------------------------------------------------------- +// +// Handles opening DiscImageChef format disk images. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2019 Natalia Portillo +// ****************************************************************************/ + +#include +#include +#include +#include + +void *open(const char *filepath) +{ + dicformatContext *ctx = malloc(sizeof(dicformatContext)); + int errorNo; + size_t readBytes; + + if(ctx == NULL) + return NULL; + + ctx->imageStream = fopen(filepath, "rb"); + + if(ctx->imageStream == NULL) + { + errorNo = errno; + free(ctx); + errno = errorNo; + + return NULL; + } + + fseek(ctx->imageStream, 0, SEEK_SET); + readBytes = fread(&ctx->header, sizeof(DicHeader), 1, ctx->imageStream); + + if(readBytes != sizeof(DicHeader)) + { + free(ctx); + errno = DICF_ERROR_FILE_TOO_SMALL; + + return NULL; + } + + if(ctx->header.identifier != DIC_MAGIC) + { + free(ctx); + errno = DICF_ERROR_NOT_DICFORMAT; + + return NULL; + } + + if(ctx->header.imageMajorVersion > DICF_VERSION) + { + free(ctx); + errno = DICF_ERROR_INCOMPATIBLE_VERSION; + + return NULL; + } + + 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); + + return ctx; +} \ No newline at end of file