/* dvdisaster: Additional error correction for optical media. * Copyright (C) 2004-2017 Carsten Gnoerlich. * Copyright (C) 2019-2021 The dvdisaster development team. * * Email: support@dvdisaster.org * * This file is part of dvdisaster. * * dvdisaster 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 3 of the License, or * (at your option) any later version. * * dvdisaster 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 dvdisaster. If not, see . */ #ifndef DVDISASTER_H #define DVDISASTER_H /* "Dare to be gorgeous and unique. * But don't ever be cryptic or otherwise unfathomable. * Make it unforgettably great." * * From "A Final Note on Style", * Amiga Intuition Reference Manual, 1986, p. 231 */ /*** *** I'm too lazy to mess with #include dependencies. *** Everything #includeable is rolled up herein... */ #define _GNU_SOURCE #include #include #ifdef WITH_GUI_YES #include #else #include #endif #include #include #include #include #include /* PRId64 et. al */ #ifdef WITH_NLS_YES #include #include #endif #include #include #include #include #include #include #include #include #include #include "md5.h" #ifndef G_THREADS_ENABLED #error "need multithreading glib2" #endif #ifdef WITH_GUI_NO /* define some symbols normally coming from gtk and helper libs */ #define GTK_MESSAGE_QUESTION 0 #define GTK_MESSAGE_WARNING 0 #define GTK_MESSAGE_ERROR 0 #define GTK_BUTTONS_OK 0 #define GTK_BUTTONS_OK_CANCEL 0 #define GTK_BUTTONS_NONE 0 typedef int GtkButtonsType; typedef void GtkDialog; typedef void GtkLabel; typedef void GtkNotebook; typedef int GtkMessageType; typedef void GtkScrolledWindow; typedef void GtkTextBuffer; typedef void GtkTooltip; typedef void GtkWidget; typedef void GtkWindow; typedef void GdkRGBA; typedef void GdkDrawable; typedef void GdkGC; typedef void GdkPixbuf; typedef void PangoLayout; #endif /* under MinGW, __attribute__ format printf doesn't work and outputs warnings for %lld, * even if it's supported and doesn't output any warning under -Wformat when directly * used with the real printf() func. However 'gnu_printf' works, see * https://github.com/ocornut/imgui/issues/3592 */ #ifdef __MINGW32__ /* defined under 32 and 64 bits mingw */ # define PRINTF_FLAVOR gnu_printf #else # define PRINTF_FLAVOR printf #endif #define PRINTF_FORMAT2(ARG1,ARG2) __attribute__((format(PRINTF_FLAVOR, ARG1, ARG2))) #define PRINTF_FORMAT(ARG) PRINTF_FORMAT2(ARG,ARG+1) /* Phrase extraction for gettext() Note that these functions are even required when WITH_NLS_NO is set! */ #ifndef WITH_DEBUG_PRINTF_FORMAT_YES #define _(string) sgettext(string) #define _utf(string) sgettext_utf8(string) #else /* disable sgettext() calls so that the compiler can analyze printf format strings */ #define _(string) string #define _utf(string) string #endif /* File permissions for images */ #ifdef SYS_MINGW #define IMG_PERMS (S_IRUSR | S_IWUSR) #else #define IMG_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) #endif /* Using round() is preferred over rint() on systems which have it */ #ifndef HAVE_ROUND #define round(x) rint(x) #endif /* Some standard media sizes */ /* WARNING: These values affect RS03 in non-obvious ways. * If you create RS03 data with changed values, you MUST * keep a dvdisaster version with the changed values for * recovering images with that RS03 data. * dvdisaster compiled with default values may appear to * scan and verify such images correctly as long as they * are not damaged. But recovery WILL BREAK when * processing a damaged image. YOU HAVE BEEN WARNED. * * NOTE: If you compile a custom version with modified values, * you may then use `-n X --debug' (also works on an unmodified * version) to ensure a proper recovery. 'X' being the number * of sectors considered when augmenting the image, which is * the immediately higher #define close to the unaugmented image size. * HOWEVER you MUST to remember this 'X'! It's probably a good idea * to write it down directly on the media you're protecting. * This way you'll have it at hand when attempting repair. * You might be tempted to do it for BD-Rs, using more space * for parity data by disabling defect management. * Do it at your own risk. * * WARNING! (read above) */ #define CDR_SIZE (351*1024) #define DVD_SL_SIZE 2295104 /* DVD+R/RW size used as least common denominator */ #define DVD_DL_SIZE 4171712 /* also seen: 4148992 4173824 */ #define BD_SL_SIZE 11826176 #define BD_DL_SIZE 23652352 #define BDXL_TL_SIZE 47305728 #define BDXL_QL_SIZE 60403712 /* * Below are the BD-R sizes when defect management is disabled when burning. * This is a tradeoff between risking a coaster vs having more space for parity. * These values are NEVER used by default, we default on the values above, which * are smaller and will work with or without defect management. * We use these values for RS03 when --no-defect-management is explicitly specified, * don't forget to specify it again when attempting a repair! * NODM = No Defect Management */ #define BD_SL_SIZE_NODM 12219392 #define BD_DL_SIZE_NODM 24438784 #define BDXL_TL_SIZE_NODM 48878592 #define BDXL_QL_SIZE_NODM 62500864 /* Maximum accepted media sizes (in 2K sectors) */ #define MAX_CDR_SIZE (100*60*75) /* CDs can't have >100min w/o severe hacks */ #define MAX_DVD_SL_SIZE 2500000 /* I have to guess here */ #define MAX_DVD_DL_SIZE 4600000 /* I have to guess here */ /* Maximum number of parallel encoder/decoder threads */ #define MAX_CODEC_THREADS 1024 /* not including IO and GUI */ #define MAX_OLD_CACHE_SIZE 8096 /* old cache for RS01/RS02 */ #define MAX_PREFETCH_CACHE_SIZE (512*1024) /* up to 0.5TB RS03 */ /* Choices for I/O strategy */ #define IO_STRATEGY_READWRITE 0 #define IO_STRATEGY_MMAP 1 /* SCSI driver selection on Linux */ #define DRIVER_NONE 0 #define DRIVER_CDROM 1 #define DRIVER_SG 3 /* Definitions for Closure->eccTarget */ #define ECC_FILE 0 #define ECC_IMAGE 1 /* Definitions for Closure->stopActions */ #define STOP_CURRENT_ACTION 1 #define STOP_SHUTDOWN_ALL 2 /*** *** Our global closure (encapsulation of global variables) ***/ typedef struct _GlobalClosure { int version; /* Integer number representing current program version */ char *cookedVersion; /* version string formatted for GUI use */ gint8 releaseFlags; /* flags marking release status */ char *versionString; /* more detailed version string */ char *device; /* currently selected device to read from */ GPtrArray *deviceNames; /* List of drive names */ GPtrArray *deviceNodes; /* List of device nodes (C: or /dev/foo) */ char *imageName; /* complete path of current image file */ char *eccName; /* complete path of current ecc file */ GPtrArray *methodList; /* List of available methods */ char *methodName; /* Name of currently selected codec */ gint64 readStart; /* Range to read */ gint64 readEnd; gint64 cdSize; /* Maximum cd size (for RS02 type images) */ gint64 dvdSize1; /* Maximum 1-layer dvd size (for augmented images) */ gint64 dvdSize2; /* Maximum 2-layer dvd size (for augmented images) */ gint64 bdSize1; /* Maximum 1-layer bd size (for augmented images) */ gint64 bdSize2; /* Maximum 2-layer bd size (for augmented images) */ gint64 bdSize3; /* Maximum 3-layer bdxl size (for augmented images) */ gint64 bdSize4; /* Maximum 4-layer bdxl size (for augmented images) */ gint64 savedCDSize; /* Undo values for above */ gint64 savedDVDSize1; gint64 savedDVDSize2; gint64 savedBDSize1; gint64 savedBDSize2; gint64 savedBDSize3; gint64 savedBDSize4; gint64 mediumSize; /* Maximum medium size (for augmented images) */ int cacheMiB; /* Cache setting for the parity codec, in megabytes */ int prefetchSectors; /* Prefetch setting per encoder thread */ int codecThreads; /* Number of threads to use for RS encoders */ int encodingAlgorithm; /* Force a certain codec type for RS03 */ int encodingIOStrategy; /* Force a IO strategy for RS03 encoding */ int sectorSkip; /* Number of sectors to skip after read error occurs */ char *redundancy; /* Error correction code redundancy */ int eccTarget; /* 0=file; 1=augmented image */ int readRaw; /* Read CD sectors raw + verify them */ int rawMode; /* mode for mode page */ int minReadAttempts; /* minimum reading attempts */ int maxReadAttempts; /* maximal reading attempts */ int internalAttempts;/* read attempts by the drive itself */ int adaptiveRead; /* Use optimized strategy for reading defective images */ int speedWarning; /* Print warning if speed changes by more than given percentage */ int fillUnreadable; /* Byte value for filling unreadable sectors or -1 */ int spinupDelay; /* Seconds to wait for drive to spin up */ int truncate; /* confirms truncation of large images */ int noTruncate; /* do not truncate image at the end */ int noProgress; /* do not print the percentage progress indicator */ int dsmVersion; /* 1 means new style dead sector marker */ int unlinkImage; /* delete image after ecc file creation */ int confirmDeletion; /* do not ask whether files should be deleted */ int driveSpeed; /* currently unused */ int debugMode; /* may activate additional features */ int regtestMode; /* tweaks output for compatibility with regtests */ int debugCDump; /* dump as #include file instead of hexdump */ int verbose; /* may activate additional messages */ int quickVerify; /* do only non time-consuming verify actions */ int screenShotMode; /* screen shot mode */ int autoSuffix; /* automatically extend files with suffices .iso/.ecc */ int ignoreIsoSize; /* get size per READ CAPACITY; ignore all ISO/UDF meta data */ int examineRS02; /* perform deep search for RS02 structures */ int examineRS03; /* perform deep search for RS03 structures */ int readAndCreate; /* automatically create .ecc file after reading an image */ int enableCurveSwitch; /* TRUE in readAndCreateMode after reading is complete */ int welcomeMessage; /* just print dvdisaster logo if FALSE */ int dotFileVersion; /* version of dotfile */ int simulateDefects; /* if >0, this is the percentage of simulated media defects */ char *simulateCD; /* Simulate CD from given image */ int defectiveDump; /* dump non-recoverable sectors into given path */ char *dDumpDir; /* directory for above */ char *dDumpPrefix; /* file name prefix for above */ int eject; /* eject medium on success */ int readingPasses; /* try to read medium n times */ int pauseAfter; /* pause after given amount of minutes */ int pauseDuration; /* duration of pause in minutes */ int pauseEject; /* Eject medium during pause */ int ignoreFatalSense;/* Continue reading after potential fatal sense errors */ int useSSE2; /* TRUE means to use SSE2 version of the codec. */ int useAltiVec; /* TRUE means to use AltiVec version of the codec. */ int clSize; /* Bytesize of cache line */ int useSCSIDriver; /* Whether to use generic or sg driver on Linux */ int fixedSpeedValues;/* output fixed speed reading to make comparing debugging output easier */ int noBdrDefectManagement;/* if true, enable use of the BD*_NODM sizes, default: false */ int ignoreRS03header; /* if true, ignore the RS03 header when repairing, forcing a full search (debug only) */ int permissiveMediumType; /* if true, don't bail out on some UNSUPPORTED medium types (debug only) */ char *homeDir; /* path to users home dir */ char *dotFile; /* path to .dvdisaster file */ char *logFile; /* path to logfile */ int logFileEnabled; /* logfile enabled */ int logFileStamped; /* time stamp written to log file */ char *binDir; /* place where the binary resides */ char *docDir; /* place where our documentation resides */ GMutex progressLock; /* A mutex protected the stuff below */ char bs[256]; /* A string of 255 backspace characters */ char sp[256]; /* A string of 255 space characters */ int progressLength; /* Length of last progress msg printed */ GThread *mainThread; /* Thread of the main() routine */ void (*cleanupProc)(gpointer); /* Procedure to cleanup running threads after an error condition */ gpointer cleanupData; GThread *subThread; /* Wait for this thread to terminate after an abort action */ char *errorTitle; /* Title to show in error dialogs */ gint32 randomSeed; /* for the random number generator */ struct _CrcBuf *crcBuf; /* crcBuf of last image read */ /*** GUI-related things */ int guiMode; /* TRUE if GUI is active */ int stopActions; /* crude method to stop ongoing action(s) */ int noMissingWarnings; /* suppress warnings about inconsistent missing sectors */ GtkWidget *logWidget; /* Dialog for the log display */ GtkScrolledWindow *logScroll; /* and its scrolled window */ GtkTextBuffer *logBuffer; /* Text buffer for the log output */ GString *logString; /* holds logging output for current action */ GMutex *logLock; /* protects the logString */ /*** Widgets of the main window */ GtkWindow *window; /* main window */ GtkTooltip *tooltips; /* our global tooltips structure */ GdkPixbuf *windowIcon; /* main window icon */ GdkPixbuf *tooltipOn; /* pixbuf of the tooltip icon */ GdkPixbuf *tooltipOff; /* pixbuf of a fully transparent icon */ GtkWidget *fileMenuImage; /* Select image entry */ GtkWidget *fileMenuEcc; /* Select Parity File entry */ GtkWidget *toolMenuAnchor; /* Anchor of tool menu */ GtkWidget *driveCombo; /* combo box for drive selection */ GtkWidget *imageFileSel; /* image file selector */ GtkWidget *imageEntry; /* image name entry field */ GtkWidget *eccFileSel; /* ecc file selector */ GtkWidget *eccEntry; /* ecc name entry field */ GtkWidget *notebook; /* The notebook behind our central output area */ GtkWidget *status; /* The status label */ GtkWidget *prefsButton; GtkWidget *helpButton; GtkWidget *readButton; GtkWidget *createButton; GtkWidget *scanButton; GtkWidget *fixButton; GtkWidget *testButton; GtkWidget *stripButton; /*** The preferences window */ GtkWindow *prefsWindow; void *prefsContext; /* local data for the preferences window */ /*** The raw editor window */ void *rawEditorContext; /*** The medium info window */ GtkWidget *mediumWindow; /* Dialog for the medium info window */ GtkWidget *mediumDrive; void *mediumInfoContext; /* private data */ /*** Common stuff for drawing curves and spirals */ GdkRGBA *redText; char *redMarkup; GdkRGBA *greenText; char *greenMarkup; GdkRGBA *barColor; GdkRGBA *logColor; GdkRGBA *curveColor; GdkRGBA *redSector; GdkRGBA *yellowSector; GdkRGBA *greenSector; GdkRGBA *blueSector; GdkRGBA *whiteSector; GdkRGBA *darkSector; /*** Widgets for the linear reading/scanning action */ GtkWidget *readLinearHeadline; GtkWidget *readLinearCurveArea; struct _Curve *readLinearCurve; struct _Spiral *readLinearSpiral; GtkWidget *readLinearNotebook; GtkWidget *readLinearSpeed; GtkWidget *readLinearErrors; GtkWidget *readLinearFootline; GtkWidget *readLinearFootlineBox; gint64 crcErrors, readErrors; /* these are passed between threads and must therefore be global */ /*** Widgets for the adaptive reading action */ GtkWidget *readAdaptiveHeadline; GtkWidget *readAdaptiveDrawingArea; struct _Spiral *readAdaptiveSpiral; char *readAdaptiveSubtitle; char *readAdaptiveErrorMsg; int additionalSpiralColor; } GlobalClosure; extern GlobalClosure *Closure; /* these should be the only global variables! */ extern int exitCode; /* value to use on exit() */ #ifdef WITH_GUI_YES extern GdkRGBA transparent; #endif /* WITH_GUI_YES */ /*** *** ***/ #define MAX_FILE_SEGMENTS 100 typedef struct _LargeFile { int fileHandle; guint64 offset; char *path; guint64 size; int flags; } LargeFile; /*** *** Aligned 64bit data types *** * Needed to prevent 4 byte packing on 32bit systems. */ #define aligned_gint64 gint64 __attribute__((aligned(8))) #define aligned_guint64 guint64 __attribute__((aligned(8))) /*** *** The .ecc file header ***/ #define FINGERPRINT_SECTOR 16 /* Sector currently used to calculate the fingerprint. */ /* This is the ISO filesystem root sector which contains */ /* the volume label and creation time stamps. */ /* Versions up to 0.64 used sector 257, */ /* but that was not a wise choice for CD media.*/ #define MFLAG_DEVEL (1<<0) /* for methodFlags[3] */ #define MFLAG_RC (1<<1) #define MFLAG_DATA_MD5 (1<<0) /* RS03: md5sum for data part available */ #define MFLAG_ECC_FILE (1<<1) /* RS03: This is a ecc file */ typedef struct _EccHeader { gint8 cookie[12]; /* "*dvdisaster*" */ gint8 method[4]; /* e.g. "RS01" */ gint8 methodFlags[4]; /* 0-2 for free use by the respective methods; 3 see above */ guint8 mediumFP[16]; /* fingerprint of FINGERPRINT SECTOR */ guint8 mediumSum[16]; /* complete md5sum of whole medium */ guint8 eccSum[16]; /* md5sum of ecc code section of .ecc file */ guint8 sectors[8]; /* number of sectors medium is supposed to have w/o ecc */ gint32 dataBytes; /* data bytes per ecc block */ gint32 eccBytes; /* ecc bytes per ecc block */ gint32 creatorVersion; /* which dvdisaster version created this */ gint32 neededVersion; /* oldest version which can decode this file */ gint32 fpSector; /* sector used to calculate mediumFP */ guint32 selfCRC; /* CRC32 of EccHeader -- since V0.66 --*/ guint8 crcSum[16]; /* md5sum of crc code section of RS02 .iso file */ gint32 inLast; /* bytes contained in last sector */ aligned_guint64 sectorsPerLayer; /* layer size for RS03 */ aligned_guint64 sectorsAddedByEcc; /* sectors added by RS02/RS03 */ gint8 padding[3960]; /* pad to 4096 bytes: room for future expansion */ /* Note: Bytes 2048 and up are currently used by the RS02/RS03 codec for a copy of the first ecc blocks CRC sums. */ } EccHeader; /*** *** The CRC block data structure *** * RS03 uses this data structure in its CRC layer. */ typedef struct _CrcBlock { guint32 crc[256]; /* Checksum for the data sectors */ gint8 cookie[12]; /* "*dvdisaster*" */ gint8 method[4]; /* e.g. "RS03" */ gint8 methodFlags[4]; /* 0-2 for free use by the respective methods; 3 see above */ gint32 creatorVersion; /* which dvdisaster version created this */ gint32 neededVersion; /* oldest version which can decode this file */ gint32 fpSector; /* sector used to calculate mediumFP */ guint8 mediumFP[16]; /* fingerprint of FINGERPRINT SECTOR */ guint8 mediumSum[16]; /* complete md5sum of whole medium */ aligned_guint64 dataSectors;/* number of sectors of the payload (e.g. iso file sys) */ gint32 inLast; /* bytes contained in last sector */ gint32 dataBytes; /* data bytes per ecc block */ gint32 eccBytes; /* ecc bytes per ecc block */ aligned_guint64 sectorsPerLayer; /* for recalculation of layout */ guint32 selfCRC; /* CRC32 of ourself, zero padded to 2048 bytes */ } CrcBlock; /*** *** forward declarations ***/ extern struct _RawBuffer *rawbuffer_forward; extern struct _DefectiveSectorHeader *dsh_forward; extern struct _DeviceHandle *dh_forward; extern struct _Image *dh_image; /*** *** bitmap.c ***/ typedef struct _Bitmap { guint32 *bitmap; gint32 size; gint32 words; } Bitmap; Bitmap* CreateBitmap0(int); #define GetBit(bm,bit) (bm->bitmap[(bit)>>5] & (1<<((bit)&31))) #define SetBit(bm,bit) bm->bitmap[(bit)>>5] |= (1<<((bit)&31)) #define ClearBit(bm,bit) bm->bitmap[(bit)>>5] &= ~(1<<((bit)&31)) gint32 CountBits(Bitmap*); void FreeBitmap(Bitmap*); /*** *** build.h ***/ extern const char *const buildCount; /*** *** cacheprobe.h ***/ int ProbeCacheLineSize(); /*** *** closure.c ***/ void InitClosure(void); void LocalizedFileDefaults(void); void FreeClosure(void); void WriteSignature(void); int VerifySignature(void); #ifdef WITH_GUI_YES void GuiDefaultColors(void); void GuiReadDotfile(void); void GuiUpdateMarkup(char**, GdkRGBA*); #endif /*** *** crc32.c ***/ guint32 Crc32(unsigned char*, int); guint32 EDCCrc32(unsigned char*, int); /*** *** crcbuf.c ***/ /* Flags for CrcBuf->md5State */ #define MD5_INVALID 0 #define MD5_BUILDING (1<<0) #define MD5_DATA_COMPLETE (1<<1) #define MD5_IMAGE_COMPLETE (1<<2) #define MD5_COMPLETE (MD5_DATA_COMPLETE | MD5_IMAGE_COMPLETE) typedef struct _CrcBuf { /* CRC32 of image sectors */ guint32 *crcbuf; guint64 crcSize; Bitmap *valid; gint32 crcCached; /* CRC has been retrieved from ECC or previous run */ /* MD5 sum of image sectors */ struct MD5Context *md5Ctxt; /* context for building the image MD5 sum */ int md5State; /* state of md5 sum */ guint64 lastSector; /* tracking of sector sequence */ unsigned char dataMD5sum[16]; /* md5sum of data portion from last image read */ unsigned char imageMD5sum[16]; /* md5sum of last image read */ /* Characteristics of image */ char *imageName; /* file name of cached image */ guint64 dataSectors; /* number of data sectors (minus ecc sectors) */ guint64 coveredSectors; /* sectors covered by crc (EH, padding, ...) */ guint64 allSectors; /* number of all image sectors */ guint8 mediumFP[16]; /* fingerprint of image */ gint32 fpSector; /* sector which was fingerprinted */ gint32 fpValid; } CrcBuf; enum { CRC_UNKNOWN, CRC_BAD, CRC_GOOD, CRC_OUTSIDE_BOUND }; /* Modes for AddSectorToCrcBuffer */ #define CRCBUF_UPDATE_CRC 1<<0 #define CRCBUF_UPDATE_MD5 1<<1 #define CRCBUF_UPDATE_ALL 3 #define CRCBUF_UPDATE_CRC_AFTER_DATA 1<<2 /* Modes for CtcBufValid */ #define FULL_IMAGE 0 #define DATA_SECTORS_ONLY 1 CrcBuf *CreateCrcBuf(struct _Image*); void FreeCrcBuf(CrcBuf*); int CheckAgainstCrcBuffer(CrcBuf*, gint64, unsigned char*); int AddSectorToCrcBuffer(CrcBuf*, int, guint64, unsigned char*, int); int CrcBufValid(CrcBuf*, struct _Image*, int); void PrintCrcBuf(CrcBuf*); /*** *** curve.c ***/ enum { CURVE_PERCENT, CURVE_MEGABYTES }; typedef struct _Curve { GtkWidget *widget; /* drawing area which is hosting us */ PangoLayout *layout; gdouble *fvalue; /* floating point curve values */ gint *ivalue; /* integer bar curve values */ gint *lvalue; /* logarithmic integer curve */ gint enable; /* which of the above should be drawn */ gint lastValueIdx; /* end of value array */ gint leftX,rightX; /* Position of left and right y axis */ gint topY,bottomY; /* Top and bottom end of i/f y axes */ gint topLY,bottomLY; /* Top and bottom end of l y axes */ char *leftLabel; /* Label of left coordinate axis */ char *leftLogLabel; /* Label of left log coordinate axis */ char *leftFormat; /* Format of left coordinate axis numbering */ int bottomFormat; /* what kind of data are we displaying? */ int margin; int maxX,maxY,logMaxY; /* current max value at y axis */ } Curve; #define DRAW_ICURVE (1<<0) #define DRAW_FCURVE (1<<1) #define DRAW_LCURVE (1<<2) #ifdef WITH_GUI_YES Curve* GuiCreateCurve(GtkWidget*, char*, char*, int, int); void GuiZeroCurve(Curve*); void GuiFreeCurve(Curve*); void GuiUpdateCurveGeometry(Curve*, char*, int); int GuiCurveX(Curve*, gdouble); int GuiCurveY(Curve*, gdouble); int GuiCurveLogY(Curve*, gdouble); void GuiRedrawAxes(cairo_t *cr, Curve*); void GuiRedrawCurve(cairo_t *cr, Curve*, int); #endif /*** *** debug.c ***/ void HexDump(unsigned char*, int, int); void LaTeXify(gint32*, int, int); void AppendToTextFile(char*,char*, ...) PRINTF_FORMAT(2); void CopySector(char*); void Byteset(char*); void Erase(char*); void MergeImages(char*, int); void RandomError(char*); void RandomImage(char*, char*, int); void RawSector(char*); void ReadSector(char*); void SendCDB(char*); void ShowHeader(char*); void ShowSector(char*); Bitmap* SimulateDefects(gint64); void TruncateImageFile(char*); void ZeroUnreadable(void); /*** *** ds-marker.c ***/ enum { SECTOR_PRESENT, SECTOR_MISSING, SECTOR_MISSING_DISPLACED, SECTOR_MISSING_WRONG_FP, SECTOR_WITH_SIMULATION_HINT }; enum { SOURCE_MEDIUM, SOURCE_IMAGE, SOURCE_ECCFILE }; void CreateMissingSector(unsigned char*, guint64, unsigned char*, guint64, char*); void CreateDebuggingSector(unsigned char*, guint64, unsigned char*, guint64, char*, char*); int CheckForMissingSector(unsigned char*, guint64, unsigned char*, guint64); int CheckForMissingSectors(unsigned char*, guint64, unsigned char*, guint64, int, guint64*); void ExplainMissingSector(unsigned char*, guint64, int, int, int*); void CreatePaddingSector(unsigned char*, guint64, unsigned char*, guint64); char *GetSimulationHint(unsigned char*); /*** *** endian.c ***/ guint32 SwapBytes32(guint32); guint64 SwapBytes64(guint64); void SwapEccHeaderBytes(EccHeader*); void SwapDefectiveHeaderBytes(struct _DefectiveSectorHeader*); void SwapCrcBlockBytes(CrcBlock*); void PrintEccHeader(EccHeader*); /*** *** fix-window.c ***/ void CreateFixWindow(GtkWidget*); /*** *** galois.c *** * This is currently the hardcoded GF(2**8). * gint32 gives abundant space for the GF. * Squeezing it down to guint8 won't probably gain much, * so we implement this defensively here. * * Note that some performance critical stuff needs to * be #included from galois-inlines.h */ /* Galois field parameters for 8bit symbol Reed-Solomon code */ #define GF_SYMBOLSIZE 8 #define GF_FIELDSIZE (1<properties above */ { DSH_HAS_FINGERPRINT = (1<<0), DSH_XA_MODE = (1<<1) }; int SaveDefectiveSector(struct _RawBuffer*, int); int TryDefectiveSectorCache(struct _RawBuffer*, unsigned char*); void ReadDefectiveSectorFile(DefectiveSectorHeader *, struct _RawBuffer*, char*); /*** *** read-linear.c ***/ void ReadMediumLinear(gpointer); /*** *** read-linear-window.c ***/ #ifdef WITH_GUI_YES void GuiInitializeCurve(void*, int, int); void GuiAddCurveValues(void*, int, int, int); void GuiMarkExistingSectors(void); void GuiResetLinearReadWindow(); void GuiRedrawReadLinearWindow(void); void GuiCreateLinearReadWindow(GtkWidget*); #else #define GuiInitializeCurve(a, b, c) #define GuiAddCurveValues(a, b, c, d) #define GuiMarkExistingSectors() #define GuiRedrawReadLinearWindow() #endif /*** *** read-adaptive.c ***/ void GetReadingRange(gint64, gint64*, gint64*); void ReadMediumAdaptive(gpointer); /*** *** read-adaptive-window.c ***/ #define ADAPTIVE_READ_SPIRAL_SIZE 4800 #ifdef WITH_GUI_YES void GuiClipReadAdaptiveSpiral(int); void GuiChangeSegmentColor(GdkRGBA*, int); void GuiRemoveFillMarkers(); void GuiSetAdaptiveReadSubtitle(char*); void GuiSetAdaptiveReadFootline(char*, GdkRGBA*); void GuiSetAdaptiveReadMinimumPercentage(int); void GuiUpdateAdaptiveResults(gint64, gint64, gint64, int); void GuiResetAdaptiveReadWindow(); #else #define GuiClipReadAdaptiveSpiral(i) #define GuiChangeSegmentColor(g, i) #define GuiRemoveFillMarkers() #define GuiSetAdaptiveReadSubtitle(c) #define GuiSetAdaptiveReadFootline(c, d) #define GuiSetAdaptiveReadMinimumPercentage(i) #define GuiUpdateAdaptiveResults(a, b, c, d) #endif void GuiCreateAdaptiveReadWindow(GtkWidget*); /*** *** recover-raw.c ***/ #define MAX_RAW_TRANSFER_SIZE (2352+296) /* main channel plus C2 vector and mask */ #define CD_RAW_DUMP_SIZE MAX_RAW_TRANSFER_SIZE #define CD_RAW_SECTOR_SIZE 2352 #define CD_RAW_C2_SECTOR_SIZE (2352+294) /* main channel plus C2 vector */ typedef struct _RawBuffer { GaloisTables *gt; /* for L-EC Reed-Solomon */ ReedSolomonTables *rt; struct _AlignedBuffer *workBuf; /* working buffer for READ CD */ unsigned char *zeroSector; /* a raw sector containing just zeros. */ unsigned char **rawBuf; /* buffer for raw read attempts */ int samplesRead; /* number of samples read */ int samplesMax; /* maximum number of samples we can store */ int sampleSize; /* size of samples */ int dataOffset; /* offset to user data in frame */ int xaMode; /* frame is in XA21 mode */ int recommendedAttempts; /* number of retries recommended by reading heuristics */ unsigned char *recovered; /* working buffer for cd frame recovery */ unsigned char *byteState; /* state of error correction */ unsigned char *reference; /* NULL or the correct sector (for debugging purposes) */ unsigned char *byteCount; /* stores how many different bytes were read for each position in a sector */ gint64 lba; /* sector number were currently working on */ guint8 mediumFP[16]; /* medium fingerprint for raw sector cache validation */ int validFP; /* indicates valid fingerprint */ unsigned char *pParity1[N_P_VECTORS]; unsigned char *pParity2[N_P_VECTORS]; int pParityN[N_P_VECTORS][2]; unsigned char *qParity1[N_Q_VECTORS]; unsigned char *qParity2[N_Q_VECTORS]; int qParityN[N_Q_VECTORS][2]; int *pLoad,*qLoad; /* data structures for the smart_lec */ unsigned char **pList[N_P_VECTORS]; /* List of accepting P vectors */ int pn[N_P_VECTORS]; unsigned char **qList[N_Q_VECTORS]; /* List of accepting Q vectors */ int qn[N_Q_VECTORS]; int bestFrame; /* Frame with lowest failures */ int bestP1, bestP2, bestQ1, bestQ2; } RawBuffer; enum /* values for byteState */ { FRAME_BYTE_UNKNOWN, /* state of byte is unknown */ FRAME_BYTE_ERROR, /* byte is wrong (= erasure for ecc) */ FRAME_BYTE_GOOD /* byte is correct */ }; RawBuffer* CreateRawBuffer(int); void ReallocRawBuffer(RawBuffer*, int); void ResetRawBuffer(RawBuffer*); void FreeRawBuffer(RawBuffer*); void DumpSector(RawBuffer*, char*); #define STRICT_MSF_CHECK FALSE #define SLOPPY_MSF_CHECK TRUE int MSFtoLBA(unsigned char, unsigned char, unsigned char); int CheckEDC(unsigned char*, int); int CheckMSF(unsigned char*, int, int); void InitializeCDFrame(unsigned char*, int, int, int); void UpdateFrameStats(RawBuffer*); int ValidateRawSector(RawBuffer*, unsigned char*, char*); int IterativeLEC(RawBuffer*); int TryCDFrameRecovery(RawBuffer*, unsigned char*); /*** *** scsi-layer.c *** * Note that there is also a scsi-layer.h with more * scsi wrapper dependent declarations. */ /* Maximum number of sectors per request */ #define MAX_CLUSTER_SIZE (32*2048) #define MAX_CLUSTER_SECTORS 32 typedef struct _AlignedBuffer { unsigned char *base; unsigned char *buf; } AlignedBuffer; AlignedBuffer *CreateAlignedBuffer(int); void FreeAlignedBuffer(AlignedBuffer*); char* DefaultDevice(void); gint64 CurrentImageSize(void); gint64 CurrentImageCapacity(void); int SendReadCDB(char*, unsigned char*, unsigned char*, int, int); /*** *** scsi-simulated.c ***/ void InitSimulatedCD(void); /*** *** rs-decoder.c ***/ int TestErrorSyndromes(ReedSolomonTables*, unsigned char*); /*** *** rs-encoder.c and friends ***/ typedef enum { ENCODING_ALG_DEFAULT, ENCODING_ALG_INVALID, ENCODING_ALG_32BIT, ENCODING_ALG_64BIT, ENCODING_ALG_SSE2, ENCODING_ALG_ALTIVEC } CODEC_TYPE; void EncodeNextLayer(ReedSolomonTables*, unsigned char*, unsigned char*, guint64, int); void DescribeRSEncoder(char**, char**); int ProbeSSE2(void); int ProbeAltiVec(void); /*** *** show-manual.c ***/ void GuiShowURL(char*); /*** *** smart-lec.c ***/ #define SMART_LEC_MESSAGE_SIZE 256 void CollectGoodVectors(RawBuffer*); void PrintPQStats(RawBuffer*); int SmartLEC(RawBuffer*); void *PrepareIterativeSmartLEC(RawBuffer*); void SmartLECIteration(void*, char*); void EndIterativeSmartLEC(void*); /*** *** spiral.c ***/ typedef struct _Spiral { GtkWidget *widget; int mx, my; int startRadius; int segmentSize; int segmentCount; double *segmentPos; GdkRGBA **segmentColor; GdkRGBA **segmentOutline; int diameter; int segmentClipping; int cursorPos; gint lastRenderedCursorPos; /* use with atomic operations */ } Spiral; #ifdef WITH_GUI_YES Spiral* GuiCreateSpiral(GdkRGBA*, int, int, int); void GuiSetSpiralWidget(Spiral*, GtkWidget*); void GuiFreeSpiral(Spiral*); void GuiFillSpiral(Spiral*, GdkRGBA*); void GuiDrawSpiral(cairo_t *cr, Spiral*); void GuiDrawSpiralLabel(cairo_t *cr, Spiral*, PangoLayout*, char*, GdkRGBA*, int, int); void GuiChangeSpiralCursor(Spiral*, int); void GuiMoveSpiralCursor(Spiral*, int); void GuiSetSpiralSegmentColor(Spiral*, GdkRGBA*, GdkRGBA*, int); #else #define GuiChangeSpiralCursor(a, b) #define GuiFreeSpiral(s) #endif /*** *** welcome-window.c ***/ void GuiCreateWelcomePage(GtkNotebook*); void StripECCFromImageFile(void); #endif /* DVDISASTER_H */