diff --git a/include/dicformat/context.h b/include/dicformat/context.h index 15f7c86..3ded6f1 100644 --- a/include/dicformat/context.h +++ b/include/dicformat/context.h @@ -1,7 +1,34 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- // -// Created by claunia on 17/03/19. +// Filename : context.h +// Author(s) : Natalia Portillo // - +// Component : libdicformat. +// +// --[ Description ] ---------------------------------------------------------- +// +// Describes context to be passed between libdicformat functions. +// +// --[ 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 +// ****************************************************************************/ #ifndef LIBDICFORMAT_CONTEXT_H #define LIBDICFORMAT_CONTEXT_H @@ -17,6 +44,12 @@ typedef struct dicformatContext DicHeader header; struct dataLinkedList *mediaTagsHead; struct dataLinkedList *mediaTagsTail; + unsigned char *sectorPrefix; + unsigned char *sectorPrefixCorrected; + unsigned char *sectorSuffix; + unsigned char *sectorSuffixCorrected; + unsigned char *sectorSubchannel; + unsigned char *mode2Subheaders; } dicformatContext; typedef struct dataLinkedList diff --git a/src/close.c b/src/close.c index 423d1ae..505a499 100644 --- a/src/close.c +++ b/src/close.c @@ -53,9 +53,17 @@ int close(void *context) return -1; } + // This may do nothing if imageStream is NULL, but as the behaviour is undefined, better sure than sorry if(ctx->imageStream != NULL) fclose(ctx->imageStream); + free(ctx->sectorPrefix); + free(ctx->sectorPrefixCorrected); + free(ctx->sectorSuffix); + free(ctx->sectorSuffixCorrected); + free(ctx->sectorSubchannel); + free(ctx->mode2Subheaders); + free(context); return 0; diff --git a/src/open.c b/src/open.c index 037addb..9ad9127 100644 --- a/src/open.c +++ b/src/open.c @@ -49,6 +49,7 @@ void *open(const char *filepath) IndexHeader idxHeader; IndexEntry *idxEntries; uint64_t ImageSize; // TODO: This should be in ImageInfo + unsigned char *data; memset(ctx, 0, sizeof(dicformatContext)); @@ -162,6 +163,7 @@ void *open(const char *filepath) } bool foundUserDataDdt = false; + ImageSize = 0; for(int i = 0; i < idxHeader.entries; i++) { pos = fseek(ctx->imageStream, idxEntries[i].offset, SEEK_SET); @@ -179,7 +181,149 @@ void *open(const char *filepath) switch(idxEntries[i].blockType) { case DataBlock: - // TODO + // NOP block, skip + if(idxEntries[i].dataType == NoData) + break; + + BlockHeader blockHeader; + + readBytes = fread(&blockHeader, sizeof(BlockHeader), 1, ctx->imageStream); + + if(readBytes != sizeof(BlockHeader)) + { + fprintf(stderr, "libdicformat: Could not read block header at %"PRIu64"", idxEntries[i].offset); + + break; + } + + ImageSize += blockHeader.cmpLength; + + // Unused, skip + if(idxEntries[i].dataType == UserData) + { + // TODO: ImageInfo + //if(blockHeader.sectorSize > imageInfo.SectorSize) + // imageInfo.SectorSize = blockHeader.sectorSize; + + break; + } + + if(blockHeader.identifier != idxEntries[i].blockType) + { + fprintf(stderr, + "libdicformat: Incorrect identifier for data block at position %"PRIu64"", + idxEntries[i].offset); + break; + } + + if(blockHeader.type != idxEntries[i].dataType) + { + fprintf(stderr, + "libdicformat: Expected block with data type %4s at position %"PRIu64" but found data type %4s", + (char *)&idxEntries[i].blockType, + idxEntries[i].offset, + (char *)&blockHeader.type); + break; + } + + fprintf(stderr, + "libdicformat: Found data block with type %4s at position %"PRIu64"", + (char *)&idxEntries[i].blockType, + idxEntries[i].offset); + + if(blockHeader.compression == None) + { + data = malloc(blockHeader.length); + if(data == NULL) + { + fprintf(stderr, "Cannot allocate memory for block, continuing..."); + break; + } + + readBytes = fread(data, blockHeader.length, 1, ctx->imageStream); + + if(readBytes != blockHeader.length) + { + free(data); + fprintf(stderr, "Could not read block, continuing..."); + break; + } + } + else + { + fprintf(stderr, + "libdicformat: Found unknown compression type %d, continuing...", + blockHeader.compression); + break; + } + + // TODO: Check CRC, if not correct, skip it + + // Check if it's not a media tag, but a sector tag, and fill the appropriate table then + switch(idxEntries[i].dataType) + { + case CdSectorPrefix: + case CdSectorPrefixCorrected: + if(idxEntries[i].dataType == CdSectorPrefixCorrected) + { + ctx->sectorPrefixCorrected = data; + } + else + ctx->sectorPrefix = data; + + // TODO: ReadableSectorTags + /* + if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSync)) + imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSync); + if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorHeader)) + imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorHeader); + */ + + break; + case CdSectorSuffix: + case CdSectorSuffixCorrected: + if(idxEntries[i].dataType == CdSectorSuffixCorrected) + ctx->sectorSuffixCorrected = data; + else + ctx->sectorSuffix = data; + + // TODO: ReadableSectorTags + /* + if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSubHeader)) + imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSubHeader); + if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorEcc)) + imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEcc); + if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorEccP)) + imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEccP); + if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorEccQ)) + imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEccQ); + if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorEdc)) + imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEdc); + */ + break; + case CdSectorSubchannel:ctx->sectorSubchannel = data; + // TODO: ReadableSectorTags + /* + if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSubchannel)) + imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSubchannel); + */ + break; + case AppleProfileTag: + case AppleSonyTag: + case PriamDataTowerTag:ctx->sectorSubchannel = data; + // TODO: ReadableSectorTags + /* + if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag)) + imageInfo.ReadableSectorTags.Add(SectorTagType.AppleSectorTag); + */ + break; + case CompactDiscMode2Subheader:ctx->mode2Subheaders = data; + break; + default: + // TODO: MediaTags + break; + } + break; case DeDuplicationTable: // TODO