const uint64_t AEWF_DEFAULT_THREADS = 4; // There normally is no sense in using higher values, as - according to out statistics - we never get called for reading
// more than 128k of data (there's only 1 exception: the very 1st read request from xmount itself). With the default EWF
// chunk size of 32K, 4 threads are enough for running the whole decompression in parallel.
// ----------------------------
// Logging and error handling
// ----------------------------
#define LOG_HEADER_LEN 80
int LogvEntry (const char *pLogFileName, uint8_t LogStdout, const char *pFileName, const char *pFunctionName, int LineNr, const char *pFormat, va_list pArguments)
LOG ("Maybe some segment files are missing. Perhaps you specified E01 instead of E?? or the segments continue beyond extension .EZZ.");
return AEWF_WRONG_CHUNK_COUNT;
}
pAewf->ChunkBuffSize = pAewf->ChunkSize + 4096; // reserve some extra space (for CRC and as compressed data might be slightly larger than uncompressed data with some imagers)
FILE *pFile; // NULL if file is not opened (never read or kicked out form cache)
time_t LastUsed;
} t_Segment, *t_pSegment;
typedef struct
{
uint64_t Nr; // The table's position in the pAewf->pTableArr, for debug output only
uint64_t ChunkFrom; // Number of the chunk referred to by the first entry of this table (very first chunk has number 0)
uint64_t ChunkTo; // Number of the chunk referred to by the last entry of this table
t_pSegment pSegment; // The file segment where the table is located
uint64_t Offset; // The offset of the table inside the segment file (start of t_AewfSectionTable, not of the preceding t_AewfSection)
unsigned long Size; // The length of the table (same as allocated length for pEwfTable)
uint32_t ChunkCount; // The number of chunk; this is the same as pTableData->Chunkcount, however, pTableData might not be available (NULL)
uint32_t SectionSectorsSize; // Silly EWF format has no clean way of knowing size of the last (possibly compressed) chunk of a table
time_t LastUsed; // Last usage of this table, for cache management
t_pAewfSectionTable pEwfTable; // Contains the original EWF table section or NULL, if never read or kicked out from cache
} t_Table, *t_pTable;
#define AEWF_NONE UINT64_MAX
enum
{
READSIZE_32K = 0,
READSIZE_64K,
READSIZE_128K,
READSIZE_256K,
READSIZE_512K,
READSIZE_1M,
READSIZE_ABOVE_1M,
READSIZE_ARRLEN
};
typedef struct _t_Aewf *t_pAewf;
typedef struct _t_Aewf const *t_pcAewf;
typedef enum
{
AEWF_IDLE = 0,
AEWF_LAUNCHED
} t_AewfThreadState;
typedef struct _t_AewfThread
{
t_AewfThreadState State;
t_pcAewf pAewf; // Give the threads access to some Aewf constants - make sure the threads only have read access
pthread_t ID;
char *pChunkBuffCompressed;
uint64_t ChunkBuffCompressedDataLen;
char *pChunkBuffUncompressed; // This buffer serves as cache as well. ChunkInBuff contains the absolute chunk number whose data is stored here
uint64_t ChunkBuffUncompressedDataLen; // This normally always is equal to the chunk size (32K), except maybe for the last chunk, if the image's total size is not a multiple of the chunk size
uint64_t ChunkInBuff;
char *pBuf; // Job arguments to the thread: Copy the uncompressed
uint64_t Ofs; // chunk data starting at chunk offset Ofs to pBuf, Len
uint64_t Len; // bytes in total.
int ReturnCode;
} t_AewfThread, *t_pAewfThread;
typedef struct _t_Aewf
{
t_pSegment pSegmentArr; // Array of all segment files (in correct order)
t_pTable pTableArr; // Array of all chunk offset tables found in the segment files (in correct order)
uint64_t Segments;
uint64_t Tables;
uint64_t Chunks; // Total number of chunks in all tables
uint64_t TotalTableSize; // Total size of all tables
uint64_t TableCache; // Current amount RAM used by tables, in bytes
uint64_t OpenSegments; // Current number of open segment files
uint64_t SectorSize;
uint64_t Sectors;
uint64_t ChunkSize;
uint64_t ImageSize; // Equals to Sectors * SectorSize
char *pChunkBuffCompressed;
char *pChunkBuffUncompressed;
uint64_t ChunkBuffUncompressedDataLen; // This normally always is equal to the chunk size (32K), except maybe for the last chunk, if the image's total size is not a multiple of the chunk size
uint32_t ChunkBuffSize;
uint64_t ChunkInBuff; // Chunk currently residing in pChunkBuffUncompressed (AEWF_NONE if none)
char *pErrorText; // Used for assembling error text during option parsing
time_t LastStatsUpdate;
char *pInfo;
t_pAewfThread pThreadArr;
// Statistics
uint64_t SegmentCacheHits;
uint64_t SegmentCacheMisses;
uint64_t TableCacheHits;
uint64_t TableCacheMisses;
uint64_t ChunkCacheHits;
uint64_t ChunkCacheMisses;
uint64_t ReadOperations; // How many times did xmount call the function AewfRead
uint64_t DataReadFromImage; // The data (in bytes) read from the image
uint64_t DataReadFromImageRaw; // The same data (in bytes), after uncompression (if any)
uint64_t DataRequestedByCaller; // How much data was given back to the caller
uint64_t TablesReadFromImage; // The overhead of the table read operations (in bytes)
uint64_t ChunksRead;
uint64_t BytesRead;
uint64_t ReadSizesArr[READSIZE_ARRLEN]; // Distribution of the requested block sites to be read
uint64_t Errors;
int LastError;
// Options
uint64_t MaxTableCache; // Max. amount of bytes in pTableArr[x].pTableData, in bytes
uint64_t MaxOpenSegments; // Max. number of open files in pSegmentArr
char *pStatsFilename; // Statistics file
uint64_t StatsRefresh; // The time in seconds between update of the stats file
char *pLogFilename;
uint8_t LogStdout;
uint64_t Threads; // Max. number of threads to be used in parallel actions. Currently only used for uncompression
} t_Aewf;
// ----------------
// Error codes
// ----------------
// AEWF Error codes are automatically mapped to errno codes by means of the groups
// below. AEWF uses these errno codes:
// ENOMEM memory allocation errors
// EINVAL wrong parameter(s) passed to an AEWF function
// EIO all others: AEWF function errors, EWF image errors