File: threadcompress.cpp

package info (click to toggle)
guymager 0.4.2-2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 932 kB
  • ctags: 1,580
  • sloc: cpp: 8,522; ansic: 2,571; makefile: 49; sh: 23
file content (179 lines) | stat: -rw-r--r-- 7,005 bytes parent folder | download
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
// ****************************************************************************
//  Project:        GUYMAGER
// ****************************************************************************
//  Programmer:     Guy Voncken
//                  Police Grand-Ducale
//                  Service de Police Judiciaire
//                  Section Nouvelles Technologies
// ****************************************************************************
//  Module:         Multi-threaded compression
// ****************************************************************************


#include <QtCore>

#include "libewf.h"

#include "common.h"
#include "device.h"
#include "threadcompress.h"
#include "threadwrite.h"
#include "config.h"
#include "aaff.h"

class t_ThreadCompressLocal
{
   public:
      t_pDevice pDevice;
      int        ThreadNr;
};

t_ThreadCompress::t_ThreadCompress (void)
{
   CHK_EXIT (ERROR_THREADCOMPRESS_CONSTRUCTOR_NOT_SUPPORTED)
} //lint !e1401 not initialised


t_ThreadCompress::t_ThreadCompress (t_pDevice pDevice, int ThreadNr)
{
   static bool Initialised = false;

   if (!Initialised)
   {
      CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_THREADCOMPRESS_CONSTRUCTOR_NOT_SUPPORTED))
      CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_THREADCOMPRESS_ZLIB_FAILED))
      CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_THREADCOMPRESS_LIBEWF_FAILED))
      CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_THREADCOMPRESS_COMPRESSION_BUFFER_TOO_SMALL))
      CHK_EXIT (TOOL_ERROR_REGISTER_CODE (ERROR_THREADCOMPRESS_INVALID_FORMAT))

      Initialised = true;
   }

   pOwn = new t_ThreadCompressLocal;
   pOwn->pDevice  = pDevice;
   pOwn->ThreadNr = ThreadNr;

   CHK_QT_EXIT (connect (this, SIGNAL(finished()), this, SLOT(SlotFinished())))
}

t_ThreadCompress::~t_ThreadCompress (void)
{
   delete pOwn;
}


void t_ThreadCompress::run (void)
{
   t_pDevice      pDevice;
   t_pFifoStd     pFifoIn;
   t_pFifoStd     pFifoOut;
   t_pFifoBlock   pFifoBlockIn;
   t_pFifoBlock   pFifoBlockOut;
   bool            Finished  = false;
   quint64         Blocks    = 0;
   const int       SubFifoNr = pOwn->ThreadNr;
   size_t          CompressedMaxSize = 0;
   size_t          CompressedSize    = 0;
   LIBEWF_HANDLE *pEwfHandle;
   ssize_t         rc;

   LOG_INFO ("Acquisition of %s: Compression thread #%d started", QSTR_TO_PSZ (pOwn->pDevice->LinuxDevice), pOwn->ThreadNr)

   pDevice  = pOwn->pDevice;

   if (pDevice->Acquisition.Format == t_File::EWF)
   {
      CompressedMaxSize = (size_t) (pDevice->FifoBlockSize *1.001) + 12; // see zlib documentation
      if (CompressedMaxSize > t_Fifo::GetCompressionOptimisedBufferSize (pDevice->FifoBlockSize))
         CHK_EXIT (ERROR_THREADCOMPRESS_COMPRESSION_BUFFER_TOO_SMALL)
   }

   CHK_EXIT (pDevice->pThreadWrite->GetpFileHandle ((void **)&pEwfHandle))
   CHK_EXIT (pDevice->pFifoCompressIn ->GetSubFifo (SubFifoNr, pFifoIn ))
   CHK_EXIT (pDevice->pFifoCompressOut->GetSubFifo (SubFifoNr, pFifoOut))

   while (!Finished && !pDevice->AbortRequest)
   {
      CHK_EXIT (pFifoIn->Get (pFifoBlockIn))
      if (pFifoBlockIn)
      {
         Blocks++;
         switch (pDevice->Acquisition.Format)
         {
            case t_File::EWF:
               CHK_EXIT (t_Fifo::CreateCompressionOptimised (pFifoBlockOut, pDevice->FifoBlockSize))

               CompressedSize          = CompressedMaxSize;   // Must be initialised with the max buffer size (we use this one instead of MULTITHREADED_COMPRESSION_FIFO_BLOCK_SIZE in order to check if ti works as tols in the zlib docu)
               pFifoBlockOut->Nr       = pFifoBlockIn->Nr;
               pFifoBlockOut->DataSize = pFifoBlockIn->DataSize;

               rc = libewf_raw_write_prepare_buffer (pEwfHandle, pFifoBlockIn ->Buffer, pFifoBlockIn->DataSize,
                                                                 pFifoBlockOut->Buffer, &CompressedSize,
                                                                &pFifoBlockOut->EwfCompressionUsed,
                                                                &pFifoBlockOut->EwfChunkCRC,
                                                                &pFifoBlockOut->EwfWriteCRC);
               if (pFifoBlockOut->EwfCompressionUsed)
               {
                  pFifoBlockOut->EwfDataSize = CompressedSize;   // Data to be forwarded is contained in
                  CHK_EXIT (t_Fifo::Destroy (pFifoBlockIn))      // pFifoBlockOut, pFifoBlockIn no longer needed.
               }
               else
               {
                  pFifoBlockIn->EwfDataSize        = pFifoBlockIn ->DataSize;
                  pFifoBlockIn->EwfCompressionUsed = pFifoBlockOut->EwfCompressionUsed;
                  pFifoBlockIn->EwfChunkCRC        = pFifoBlockOut->EwfChunkCRC;
                  pFifoBlockIn->EwfWriteCRC        = pFifoBlockOut->EwfWriteCRC;
                  CHK_EXIT (t_Fifo::Destroy (pFifoBlockOut))                     // No compression, we'll forward the
                  pFifoBlockOut = pFifoBlockIn;                                  // original block we received
               }

               if (rc != (ssize_t) pFifoBlockOut->EwfDataSize)
               {
                  LOG_INFO ("libewf_raw_write_prepare_buffer returned %d. DataSize=%u, CompressedMaxSize=%zd, CompressedSize=%zd, EwfCompressionUsed=%d", (int)rc,
                            pFifoBlockOut->DataSize, CompressedMaxSize, CompressedSize, pFifoBlockOut->EwfCompressionUsed)
                  CHK_EXIT (ERROR_THREADCOMPRESS_LIBEWF_FAILED)
               }
               pFifoBlockOut->EwfPreprocessed = true;
               break;

            case t_File::AFF:
//               LOG_ERROR ("AaffPreprocess")
               CHK_EXIT (t_Fifo::CreateCompressionOptimised (pFifoBlockOut, pDevice->FifoBlockSize))
               pFifoBlockOut->Nr       = pFifoBlockIn->Nr;
               pFifoBlockOut->DataSize = pFifoBlockIn->DataSize;

               CHK_EXIT (AaffPreprocess (&pFifoBlockOut->pAaffPreprocess, pFifoBlockIn->Buffer, pFifoBlockIn->DataSize, pFifoBlockOut->Buffer, pFifoBlockOut->BufferSize))

               if (pFifoBlockOut->pAaffPreprocess->Compressed)
               {
                  CHK_EXIT (t_Fifo::Destroy (pFifoBlockIn))
               }
               else
               {
                  pFifoBlockIn->pAaffPreprocess = pFifoBlockOut->pAaffPreprocess;
                  CHK_EXIT (t_Fifo::Destroy (pFifoBlockOut))
                  pFifoBlockOut = pFifoBlockIn;
               }
               break;

            default:
               CHK_EXIT (ERROR_THREADCOMPRESS_INVALID_FORMAT)
         }
         CHK_EXIT (pFifoOut->Insert (pFifoBlockOut))
      }
      else
      {
         LOG_INFO ("Dummy block")
         Finished = true;
      }
   }

   LOG_INFO ("Compression thread #%d exits now (device %s, %Ld blocks processed)", pOwn->ThreadNr, QSTR_TO_PSZ (pOwn->pDevice->LinuxDevice), Blocks)
}


void t_ThreadCompress::SlotFinished (void)
{
   emit SignalEnded (pOwn->pDevice, pOwn->ThreadNr);
}