New upstream version 0.79.6

This commit is contained in:
Carlos Maddela
2017-12-21 05:31:58 +11:00
parent 9ad5d25d65
commit ccc2d79dd4
592 changed files with 18076 additions and 7311 deletions

211
crcbuf.c
View File

@@ -1,5 +1,5 @@
/* dvdisaster: Additional error correction for optical media.
* Copyright (C) 2004-2015 Carsten Gnoerlich.
* Copyright (C) 2004-2017 Carsten Gnoerlich.
*
* Email: carsten@dvdisaster.org -or- cgnoerlich@fsfe.org
* Project homepage: http://www.dvdisaster.org
@@ -26,27 +26,133 @@
#include "rs02-includes.h"
/***
*** Create an uninitialized CRC buffer
*** Create a CRC buffer ready for accumulating CRC and MD5 sums
***/
CrcBuf *CreateCrcBuf(guint64 sectors)
{ CrcBuf *cb = g_malloc(sizeof(CrcBuf));
CrcBuf *CreateCrcBuf(Image *image)
{ CrcBuf *cb = g_malloc0(sizeof(CrcBuf));
cb->crcbuf = g_malloc(sectors * sizeof(guint32));
cb->size = sectors;
cb->valid = CreateBitmap0(sectors);
/* MD5 sum related data */
cb->md5Ctxt = g_malloc(sizeof(struct MD5Context));
MD5Init(cb->md5Ctxt);
cb->md5State = MD5_BUILDING;
cb->lastSector = 0;
memset(cb->dataMD5sum, 0, 16);
memset(cb->imageMD5sum, 0, 16);
/* image identification */
if(image->type == IMAGE_FILE)
cb->imageName = g_strdup(image->file->path);
/* For augmented images we need both the pure data size and the full size
in order to compute MD5 sums for both. Depending on what the user wants
to do with the image (create an ecc file or re-augment the image) we'll
need the first or the last version.
There's one catch, though: If the augmented image is accompanied with
an ecc file, we must treat the image as raw data; e.g. do not set
the data size to the portion protected by the augmented ecc.
Otherwise, the CRC sums from the ecc file which do also protect
the augmented ecc part will become unreachable. */
if(image->eccHeader && !image->eccFileHeader) /* augmented image, and no ecc file? */
{ cb->dataSectors = uchar_to_gint64(image->eccHeader->sectors);
if(image->type == IMAGE_FILE)
cb->allSectors = image->sectorSize;
else cb->allSectors = image->dh->sectors;
}
else
{ if(image->type == IMAGE_FILE)
cb->dataSectors = cb->allSectors = image->sectorSize;
else cb->dataSectors = cb->allSectors = image->dh->sectors;
}
/* Note: The following statement is not correct for RS03.
It does not hurt since RS03 will set the correct value when
the CrcBuf is created via RS03GetCrcBuf(), and in all other
cases it does currently not matter. Especially, CRC sums
created during an image read are not used when subsequently
creating new ecc data. */
cb->coveredSectors = cb->dataSectors;
/* Extract the fingerprint */
if(image->fpState == FP_PRESENT)
{ memcpy(cb->mediumFP, image->imageFP, 16);
cb->fpValid = TRUE;
}
cb->fpSector = image->fpSector;
/* CRC sum array */
cb->crcbuf = g_malloc(cb->allSectors * sizeof(guint32));
cb->crcSize = cb->allSectors;
cb->valid = CreateBitmap0(cb->allSectors);
image->crcCache = cb;
return cb;
}
/***
*** Test a 2048 byte block against the checksum in the buffer
***/
/*
* Add a 2048 byte block into the checksum buffer
*/
int AddSectorToCrcBuffer(CrcBuf *cb, int mode, guint64 idx, unsigned char *buf, int buf_size)
{ guint32 crc;
if(idx < 0 || idx >= cb->crcSize)
return CRC_OUTSIDE_BOUND;
/* Update the CRC sums */
if( (mode & CRCBUF_UPDATE_CRC)
|| ((mode & CRCBUF_UPDATE_CRC_AFTER_DATA) && idx >= cb->coveredSectors))
{ crc = Crc32(buf, 2048); /* should be buf_size, but remains at 2048 for backwards compatibility. */
cb->crcbuf[idx] = crc; /* does not harm except that the last sector is padded with the contents */
SetBit(cb->valid, idx); /* of the previous sector when reading an image file whole size is not */
} /* a multiple of 2048 */
/* Update the MD5 sums */
if(!(mode & CRCBUF_UPDATE_MD5))
return CRC_GOOD;
if(cb->lastSector != idx) /* sector out of order -> md5sum dead */
{ cb->md5State = MD5_INVALID;
return CRC_BAD;
}
cb->lastSector++;
if(idx <= cb->allSectors-1)
MD5Update(cb->md5Ctxt, buf, buf_size);
if(idx == cb->dataSectors-1)
{ MD5Context *dataCtxt = alloca(sizeof(MD5Context));
memcpy(dataCtxt, cb->md5Ctxt, sizeof(MD5Context));
MD5Final(cb->dataMD5sum, dataCtxt);
cb->md5State |= MD5_DATA_COMPLETE;
}
if(idx == cb->allSectors-1)
{ MD5Final(cb->imageMD5sum, cb->md5Ctxt);
cb->md5State |= MD5_IMAGE_COMPLETE;
cb->md5State &= ~MD5_BUILDING;
}
return CRC_GOOD;
}
/*
* Test a 2048 byte block against the checksum in the buffer
*/
int CheckAgainstCrcBuffer(CrcBuf *cb, gint64 idx, unsigned char *buf)
{ guint32 crc;
if(idx < 0 || idx >= cb->size)
if(idx < 0 || idx >= cb->crcSize)
return CRC_OUTSIDE_BOUND;
crc = Crc32(buf, 2048);
@@ -60,6 +166,36 @@ int CheckAgainstCrcBuffer(CrcBuf *cb, gint64 idx, unsigned char *buf)
return CRC_BAD;
}
/*
* Make sure that the current image and ecc file match the
* cached CRC and md5 informaton
*/
int CrcBufValid(CrcBuf *crcbuf, Image *image, EccHeader *eh)
{
if(!crcbuf)
{ Verbose("CrcBufValid: crcbuf==NULL\n");
return FALSE;
}
/* if still in building state we do not have all CRC sums */
if(crcbuf->md5State & MD5_BUILDING)
{ Verbose("CrcBufValid: NO, still building\n");
return FALSE;
}
/* presence of one MD5 sum suffices (data md5sum may not be present
under some circumstances) */
if((!(crcbuf->md5State & MD5_COMPLETE)))
{ Verbose("CrcBufValid: NOT complete\n");
return FALSE;
}
Verbose("CrcBufValid: buffer VALID\n");
return TRUE;
}
/***
*** Clean up
@@ -67,7 +203,60 @@ int CheckAgainstCrcBuffer(CrcBuf *cb, gint64 idx, unsigned char *buf)
void FreeCrcBuf(CrcBuf *cb)
{
if(!cb)
{ Verbose("FreeCrcBuf - nothing to do\n");
return;
}
g_free(cb->crcbuf);
FreeBitmap(cb->valid);
if(cb->imageName)
g_free(cb->imageName);
if(cb->md5Ctxt)
g_free(cb->md5Ctxt);
g_free(cb);
Verbose("FreeCrcBuf - buffer cleared\n");
}
/***
*** Debugging output
***/
void PrintCrcBuf(CrcBuf *cb)
{ char digest[33];
guint64 i,missing=0;
if(!Closure->verbose)
return;
PrintLog("CrcBuf contents, image path %s:\n", cb->imageName ? cb->imageName : "none (medium)" );
PrintLog(" crcSize: %lld, dataSectors: %lld, coveredSectors: %lld, allSectors: %lld\n",
cb->crcSize, cb->dataSectors, cb->coveredSectors, cb->allSectors);
PrintLog(" md5State:");
if(cb->md5State)
{ if(cb->md5State & MD5_BUILDING) PrintLog(" building");
if(cb->md5State & MD5_DATA_COMPLETE) PrintLog(" data_complete");
if(cb->md5State & MD5_IMAGE_COMPLETE) PrintLog(" image_complete");
}
else PrintLog(" invalid");
PrintLog("\n");
if(cb->md5State & MD5_COMPLETE)
{ AsciiDigest(digest, cb->dataMD5sum);
PrintLog(" data: %s\n", digest);
AsciiDigest(digest, cb->imageMD5sum);
PrintLog(" full: %s\n", digest);
}
AsciiDigest(digest, cb->mediumFP);
if(cb->fpValid)
PrintLog(" fp sector: %d; %s\n", cb->fpSector, digest);
else PrintLog(" fp sector: %d; invalid\n", cb->fpSector);
for(i=0; i<cb->crcSize; i++)
if(!GetBit(cb->valid, i))
{ missing++;
}
PrintLog(" missing crcs: %lld\n", missing);
}