1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
|
// ****************************************************************************
// Project: GUYMAGER
// ****************************************************************************
// Programmer: Guy Voncken
// Police Grand-Ducale
// Service de Police Judiciaire
// Section Nouvelles Technologies
// ****************************************************************************
#ifndef __DEVICE_H__
#define __DEVICE_H__
#include "hash.h"
#include <parted/parted.h>
#include <QMetaType>
#include <QReadWriteLock>
#include <QMutex>
#include <QTime>
#include "fifo.h"
#include "info.h"
#include "file.h"
class t_ThreadRead;
class t_ThreadHash;
class t_ThreadCompress;
class t_ThreadWrite;
#define DEVICE_DEFAULT_SECTOR_SIZE ((size_t)512)
class t_Device
{
public:
typedef enum
{
Idle,
Acquire,
AcquirePaused,
Verify,
VerifyPaused,
Cleanup,
Finished,
Aborted
} t_State;
typedef enum
{
None,
UserRequest,
ThreadWriteFileError,
ThreadReadFileError
} t_AbortReason;
static const int AutoFracLen = -1; // Use up to 2 digits after decimal point (min. 3 significant digits)
static const int AutoUnitThreshold = -1;
class t_Acquisition
{
public:
QString ImagePath; // Always end with /
QString InfoPath; // Always end with /
QString ImageFilename; // Image filename, without extension
QString InfoFilename; // Info filename, without extension
t_File::Format Format;
bool CalcHashes;
bool VerifySource;
QString CaseNumber;
QString EvidenceNumber;
QString Examiner;
QString Description;
QString Notes;
};
public:
t_Device (const QString &SerialNumber=QString(), const PedDevice *pPedDev=NULL);
t_Device (const QString &SerialNumber, const QString &LinuxDevice, const QString &Model,
quint64 SectorSize, quint64 SectorSizePhys, quint64 Size=0);
~t_Device ();
static QVariant GetSerialNumber (t_pDevice pDevice);
static QVariant GetLinuxDevice (t_pDevice pDevice);
static QVariant GetModel (t_pDevice pDevice);
static QVariant GetState (t_pDevice pDevice);
static QVariant GetSectorSize (t_pDevice pDevice);
static QVariant GetSectorSizePhys (t_pDevice pDevice);
static QVariant GetBadSectorCount (t_pDevice pDevice);
static QVariant GetBadSectorCountVerify(t_pDevice pDevice);
static QVariant GetSize (t_pDevice pDevice);
static QVariant GetSizeHuman (t_pDevice pDevice);
static QVariant GetSizeHumanFrac (t_pDevice pDevice, bool SI=true, int FracLen=AutoFracLen, int UnitThreshold=AutoUnitThreshold);
static QVariant GetProgress (t_pDevice pDevice);
static QVariant GetCurrentSpeed (t_pDevice pDevice);
static QVariant GetAverageSpeed (t_pDevice pDevice);
static QVariant GetRemaining (t_pDevice pDevice);
static QVariant GetFifoStatus (t_pDevice pDevice);
inline void SetCurrentWritePos (quint64 Pos)
{
SemCurrentWritePos.lockForWrite ();
CurrentWritePos = Pos;
SemCurrentWritePos.unlock ();
}
inline void IncCurrentWritePos (int Inc)
{
SemCurrentWritePos.lockForWrite ();
CurrentWritePos += Inc; //lint !e737 Loss of sign
SemCurrentWritePos.unlock ();
}
inline quint64 GetCurrentWritePos (void)
{
quint64 Pos;
SemCurrentWritePos.lockForRead ();
Pos = CurrentWritePos;
SemCurrentWritePos.unlock ();
return Pos;
}
inline void SetCurrentVerifyPos (quint64 Pos)
{
SemCurrentVerifyPos.lockForWrite ();
CurrentVerifyPos = Pos;
SemCurrentVerifyPos.unlock ();
}
inline void IncCurrentVerifyPos (int Inc)
{
SemCurrentVerifyPos.lockForWrite ();
CurrentVerifyPos += Inc; //lint !e737 Loss of sign
SemCurrentVerifyPos.unlock ();
}
inline quint64 GetCurrentVerifyPos (void)
{
quint64 Pos;
SemCurrentVerifyPos.lockForRead ();
Pos = CurrentVerifyPos;
SemCurrentVerifyPos.unlock ();
return Pos;
}
inline void AddBadSector (quint64 Sector)
{
SemBadSectors.lock ();
if (State == Acquire)
BadSectors .append(Sector);
else BadSectorsVerify.append(Sector);
SemBadSectors.unlock ();
}
APIRET GetBadSectors (QList<quint64> &BadSectorsCopy, bool Verify)
{
SemBadSectors.lock ();
if (Verify)
BadSectorsCopy = BadSectorsVerify;
else BadSectorsCopy = BadSectors;
SemBadSectors.unlock ();
return NO_ERROR;
}
quint64 GetBadSectorCount (bool Verify)
{
quint64 Count;
SemBadSectors.lock ();
if (Verify)
Count = BadSectorsVerify.count(); //lint !e732 Loss of sign
else Count = BadSectors .count(); //lint !e732 Loss of sign
SemBadSectors.unlock ();
return Count;
}
APIRET ClearBadSectors (void)
{
SemBadSectors.lock ();
BadSectorsVerify.clear();
BadSectors .clear();
SemBadSectors.unlock ();
return NO_ERROR;
}
APIRET GetMessage (QString &MessageCopy)
{
SemMessage.lock ();
MessageCopy = Message;
SemMessage.unlock ();
return NO_ERROR;
}
APIRET SetMessage (const QString &NewMessage)
{
SemMessage.lock ();
Message = NewMessage;
SemMessage.unlock ();
return NO_ERROR;
}
bool HasHashThread (void) const;
bool HasCompressionThreads (void) const;
const char *StateStr (void);
private:
void Initialise (void);
void InitialiseDeviceSpecific (const QString &SerialNumber, const QString &LinuxDevice, const QString &Model,
quint64 SectorSize, quint64 SectorSizePhys, quint64 Size);
public: QString SerialNumber;
QString Model;
QString LinuxDevice; // for instance /dev/hda
bool Local; // it's a local device (cannot be acquired)
quint64 SectorSize;
quint64 SectorSizePhys;
quint64 Size;
bool Removable;
t_State State;
private: QString Message; // Used by the threads to communicate messages displayed in spreadsheet field "state"
public: bool AbortRequest;
t_AbortReason AbortReason;
bool DeleteAfterAbort;
t_Acquisition Acquisition;
t_Info Info; // Must only be used if Aqcuisition.InfoFilename is valid!
FILE *pFileSrc;
quint64 CurrentReadPos; // Accessed from different threads, but never at the same time. During acquisition, it is exclusively accessed by the read threads. Using a mutex would be nicer, but could decrease performance.
private: quint64 CurrentVerifyPos; // Accessed concurrently, use appropriate functions
private: quint64 CurrentWritePos; // Accessed concurrently, use appropriate functions
private: QList<quint64> BadSectors; // Accessed concurrently, use appropriate functions
private: QList<quint64> BadSectorsVerify; // Accessed concurrently, use appropriate functions
public: bool FallbackMode; // Set if an error occurs while reading a large block. If set, sectors are read individually until the next large block boundary.
QDateTime StartTimestamp;
QDateTime StartTimestampVerify;
QDateTime StopTimestamp;
public: t_ThreadRead *pThreadRead;
t_ThreadHash *pThreadHash;
t_ThreadWrite *pThreadWrite;
QList<t_ThreadCompress *> ThreadCompressList;
public: t_pFifo pFifoRead; // Pointers to the Fifos used by the different
t_pFifo pFifoHashIn; // threads. Some of them point to the same Fifos,
t_pFifo pFifoHashOut; // for instance pFifoRead and pFifoHashIn.
t_pFifo pFifoWrite;
t_pFifoCompressIn pFifoCompressIn;
t_pFifoCompressOut pFifoCompressOut;
int FifoMaxBlocks;
unsigned int FifoBlockSize;
t_HashMD5Digest MD5Digest;
t_HashMD5Digest MD5DigestVerify;
t_HashSHA256Digest SHA256Digest;
t_HashSHA256Digest SHA256DigestVerify;
public: quint64 PrevPos; // Some variables for
QTime PrevTimestamp; // the current speed
double PrevSpeed; // calculation.
bool Checked; // Helper variable for matching algorithm in SlotScanFinished, not used elsewhere.
private: QReadWriteLock SemCurrentWritePos;
private: QReadWriteLock SemCurrentVerifyPos;
private: QMutex SemBadSectors;
private: QMutex SemMessage;
};
class t_DeviceList: public QList<t_pDevice>
{
public:
t_DeviceList (void);
~t_DeviceList ();
t_pDevice AppendNew (const QString &SerialNumber, const PedDevice *pPedDev);
t_pDevice AppendNew (const QString &SerialNumber, const QString &LinuxDevice, const QString &Model,
quint64 SectorSize, quint64 SectorSizePhys, quint64 Size=0);
APIRET MatchDevice (t_pcDevice pDevCmp, t_pDevice &pDeviceMatch);
};
typedef t_DeviceList *t_pDeviceList;
Q_DECLARE_METATYPE(t_pDeviceList); //lint !e19 Useless declaration
// ------------------------------------
// Error codes
// ------------------------------------
enum
{
ERROR_DEVICE_SERNR_MATCH_MODEL_MISMATCH = ERROR_BASE_DEVICE + 1,
ERROR_DEVICE_SERNR_MATCH_LENGTH_MISMATCH,
ERROR_DEVICE_BAD_STATE,
ERROR_DEVICE_BAD_ABORTREASON,
ERROR_DEVICE_NOT_CLEAN
};
#endif
|