I had a CD image generate by Clone CD with some corrupted files, but I also had good versions of the files. Instead of extracting the files and making a new ISO, I decided to try to fix the original image.
/* cdrdao - write audio CD-Rs in disc-at-once mode
*
* Copyright (C) 1998-2002 Andreas Mueller
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include
#include
#include
#include
#include
#define GF8_PRIM_POLY 0x11d /* x^8 + x^4 + x^3 + x^2 + 1 */
#define EDC_POLY 0x8001801b /* (x^16 + x^15 + x^2 + 1) (x^16 + x^2 + x + 1) */
#define LEC_HEADER_OFFSET 12
#define LEC_DATA_OFFSET 16
#define LEC_MODE1_DATA_LEN 2048
#define LEC_MODE1_EDC_OFFSET 2064
#define LEC_MODE1_INTERMEDIATE_OFFSET 2068
#define LEC_MODE1_P_PARITY_OFFSET 2076
#define LEC_MODE1_Q_PARITY_OFFSET 2248
#define LEC_MODE2_FORM1_DATA_LEN (2048+8)
#define LEC_MODE2_FORM1_EDC_OFFSET 2072
#define LEC_MODE2_FORM2_DATA_LEN (2324+8)
#define LEC_MODE2_FORM2_EDC_OFFSET 2348
typedef u_int8_t gf8_t;
static const class CrcTable {
private:
u_int32_t table[256];
public:
CrcTable();
~CrcTable() {}
u_int32_t operator[](int i) const { return table[i]; }
operator const u_int32_t *() const { return table; }
} CRCTABLE;
/* Reverses the bits in 'd'. 'bits' defines the bit width of 'd'.
*/
static u_int32_t mirror_bits(u_int32_t d, int bits)
{
int i;
u_int32_t r = 0;
for (i = 0; i <>
r <<= 1;
if ((d & 0x1) != 0)
r |= 0x1;
d >>= 1;
}
return r;
}
/* Build the CRC lookup table for EDC_POLY poly. The CRC is 32 bit wide
* and reversed (i.e. the bit stream is divided by the EDC_POLY with the
* LSB first order).
*/
CrcTable::CrcTable ()
{
u_int32_t i, j;
u_int32_t r;
for (i = 0; i <>
r = mirror_bits(i, 8);
r <<= 24;
for (j = 0; j <>
if ((r & 0x80000000) != 0) {
r <<= 1;
r ^= EDC_POLY;
}
else {
r <<= 1;
}
}
r = mirror_bits(r, 32);
table[i] = r;
}
}
/* Calculates the CRC of given data with given lengths based on the
* table lookup algorithm.
*/
static u_int32_t calc_edc(u_int8_t *data, int len)
{
u_int32_t crc = 0;
while (len--) {
crc = CRCTABLE[(int)(crc ^ *data++) & 0xff] ^ (crc >> 8);
}
return crc;
}
/* Encodes a MODE 1 sector.
* 'adr' is the current physical sector address
* 'sector' must be 2352 byte wide containing 2048 bytes user data at
* offset 16
*/
struct mode1 {
unsigned char sync[12];
unsigned char sectorId[4];
unsigned char data[2048];
unsigned int crc;
unsigned char blank[8];
unsigned char ecc[276];
};
int main(int argc, char *argv[]) {
FILE *fp;
mode1 block;
size_t length;
unsigned int crc;
unsigned int sector = 0;
unsigned int first_bad;
int currently_bad = 0;
if (argc <>
fprintf(stderr, "not enough arguments\n");
return -1;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "Error opening %s\n", argv[1]);
return -1;
}
while ((length = fread(&block, sizeof(block), 1, fp)) == 1) {
crc = calc_edc ((unsigned char *)&block,
sizeof(block.sync) + sizeof(block.sectorId) +
sizeof(block.data));
if (crc != block.crc) {
printf("%d\n", sector);
if (!currently_bad) {
currently_bad = 1;
first_bad = sector;
}
} else if (currently_bad) {
currently_bad = 0;
// printf("Sector range is bad: 0x%x - 0x%x (%u - %u)\n",
// first_bad, sector - 1, first_bad, sector - 1);
}
sector++;
}
return 0;
}
bb
Hide
Expand
No comments:
Post a Comment