TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
CascReadFile.cpp File Reference
#include "CascLib.h"
#include "CascCommon.h"
+ Include dependency graph for CascReadFile.cpp:

Classes

struct  _BLTE_FRAME
 

Macros

#define __CASCLIB_SELF__
 

Typedefs

typedef struct _BLTE_FRAME BLTE_FRAME
 
typedef struct _BLTE_FRAMEPBLTE_FRAME
 

Functions

TCascFileIsValidFileHandle (HANDLE hFile)
 
static int EnsureDataStreamIsOpen (TCascFile *hf)
 
static int LoadFileFrames (TCascFile *hf)
 
static int EnsureHeaderAreaIsLoaded (TCascFile *hf)
 
static int EnsureFrameHeadersLoaded (TCascFile *hf)
 
static PCASC_FILE_FRAME FindFileFrame (TCascFile *hf, DWORD FilePointer)
 
static int ProcessFileFrame (LPBYTE pbOutBuffer, DWORD cbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer, DWORD dwFrameIndex)
 
DWORD WINAPI CascGetFileSize (HANDLE hFile, PDWORD pdwFileSizeHigh)
 
DWORD WINAPI CascSetFilePointer (HANDLE hFile, LONG lFilePos, LONG *plFilePosHigh, DWORD dwMoveMethod)
 
bool WINAPI CascReadFile (HANDLE hFile, void *pvBuffer, DWORD dwBytesToRead, PDWORD pdwBytesRead)
 

Macro Definition Documentation

#define __CASCLIB_SELF__

Typedef Documentation

typedef struct _BLTE_FRAME BLTE_FRAME
typedef struct _BLTE_FRAME * PBLTE_FRAME

Function Documentation

DWORD WINAPI CascGetFileSize ( HANDLE  hFile,
PDWORD  pdwFileSizeHigh 
)
368 {
369  TCascFile * hf;
370  int nError;
371 
372  CASCLIB_UNUSED(pdwFileSizeHigh);
373 
374  // Validate the file handle
375  if((hf = IsValidFileHandle(hFile)) == NULL)
376  {
378  return CASC_INVALID_SIZE;
379  }
380 
381  // Make sure that the file header area is loaded
382  nError = EnsureFrameHeadersLoaded(hf);
383  if(nError != ERROR_SUCCESS)
384  {
385  SetLastError(nError);
386  return CASC_INVALID_SIZE;
387  }
388 
389  // Give the file size to the caller
390  if(pdwFileSizeHigh != NULL)
391  *pdwFileSizeHigh = 0;
392  return hf->FileSize;
393 }
arena_t NULL
Definition: jemalloc_internal.h:624
DWORD FileSize
Definition: CascCommon.h:240
#define CASCLIB_UNUSED(p)
Definition: CascCommon.h:75
static int EnsureFrameHeadersLoaded(TCascFile *hf)
Definition: CascReadFile.cpp:202
#define ERROR_INVALID_HANDLE
Definition: CascPort.h:207
void SetLastError(int nError)
Definition: Common.cpp:75
#define CASC_INVALID_SIZE
Definition: CascLib.h:118
TCascFile * IsValidFileHandle(HANDLE hFile)
Definition: CascOpenFile.cpp:18
Definition: CascCommon.h:227
#define ERROR_SUCCESS
Definition: CascPort.h:204

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool WINAPI CascReadFile ( HANDLE  hFile,
void *  pvBuffer,
DWORD  dwBytesToRead,
PDWORD  pdwBytesRead 
)
460 {
461  PCASC_FILE_FRAME pFrame = NULL;
462  ULONGLONG StreamSize;
463  ULONGLONG FileOffset;
464  TCascFile * hf;
465  LPBYTE pbBuffer = (LPBYTE)pvBuffer;
466  DWORD dwStartPointer = 0;
467  DWORD dwFilePointer = 0;
468  DWORD dwEndPointer = 0;
469  DWORD dwFrameSize;
470  bool bReadResult;
471  int nError = ERROR_SUCCESS;
472 
473  // The buffer must be valid
474  if(pvBuffer == NULL)
475  {
477  return false;
478  }
479 
480  // Validate the file handle
481  if((hf = IsValidFileHandle(hFile)) == NULL)
482  {
484  return false;
485  }
486 
487  // If the file frames are not loaded yet, do it now
488  if(nError == ERROR_SUCCESS)
489  {
490  nError = EnsureFrameHeadersLoaded(hf);
491  }
492 
493  // If the file position is at or beyond end of file, do nothing
494  if(nError == ERROR_SUCCESS && hf->FilePointer >= hf->FileSize)
495  {
496  *pdwBytesRead = 0;
497  return ERROR_SUCCESS;
498  }
499 
500  // Find the file frame where to read from
501  if(nError == ERROR_SUCCESS)
502  {
503  // Get the frame
504  pFrame = FindFileFrame(hf, hf->FilePointer);
505  if(pFrame == NULL || pFrame->CompressedSize < 1)
506  nError = ERROR_FILE_CORRUPT;
507  }
508 
509  // Perform the read
510  if(nError == ERROR_SUCCESS)
511  {
512  // If not enough bytes in the file remaining, cut them
513  dwStartPointer = dwFilePointer = hf->FilePointer;
514  dwEndPointer = dwStartPointer + dwBytesToRead;
515  if(dwEndPointer > hf->FileSize)
516  dwEndPointer = hf->FileSize;
517 
518  // Perform block read from each file frame
519  while(dwFilePointer < dwEndPointer)
520  {
521  LPBYTE pbFrameData = NULL;
522  DWORD dwFrameStart = pFrame->FrameFileOffset;
523  DWORD dwFrameEnd = pFrame->FrameFileOffset + pFrame->FrameSize;
524 
525  // Shall we populate the cache with a new data?
526  if(dwFrameStart != hf->CacheStart || hf->CacheEnd != dwFrameEnd)
527  {
528  // Shall we reallocate the cache buffer?
529  if(pFrame->FrameSize > hf->cbFileCache)
530  {
531  if(hf->pbFileCache != NULL)
532  CASC_FREE(hf->pbFileCache);
533 
534  hf->pbFileCache = CASC_ALLOC(BYTE, pFrame->FrameSize);
535  hf->cbFileCache = pFrame->FrameSize;
536  }
537 
538  // We also need to allocate buffer for the raw data
539  pbFrameData = CASC_ALLOC(BYTE, pFrame->CompressedSize);
540  if(pbFrameData == NULL)
541  {
542  nError = ERROR_NOT_ENOUGH_MEMORY;
543  break;
544  }
545 
546  // Load the raw file data to memory
547  FileOffset = pFrame->FrameArchiveOffset;
548  bReadResult = FileStream_Read(hf->pStream, &FileOffset, pbFrameData, pFrame->CompressedSize);
549 
550  // Note: The raw file data size could be less than expected
551  // Happened in WoW build 19342 with the ROOT file. MD5 in the frame header
552  // is zeroed, which means it should not be checked
553  // Frame File: data.029
554  // Frame Offs: 0x013ED9F0 size 0x01325B32
555  // Frame End: 0x02713522
556  // File Size: 0x027134FC
557  if(bReadResult == false && GetLastError() == ERROR_HANDLE_EOF && !IsValidMD5(pFrame->md5))
558  {
559  // Get the size of the remaining file
560  FileStream_GetSize(hf->pStream, &StreamSize);
561  dwFrameSize = (DWORD)(StreamSize - FileOffset);
562 
563  // If the frame offset is before EOF and frame end is beyond EOF, correct it
564  if(FileOffset < StreamSize && dwFrameSize < pFrame->CompressedSize)
565  {
566  memset(pbFrameData + dwFrameSize, 0, (pFrame->CompressedSize - dwFrameSize));
567  bReadResult = true;
568  }
569  }
570 
571  // If the read result failed, we cannot finish reading it
572  if(bReadResult && VerifyDataBlockHash(pbFrameData, pFrame->CompressedSize, pFrame->md5))
573  {
574  // Convert the source frame to the file cache
575  nError = ProcessFileFrame(hf->pbFileCache,
576  pFrame->FrameSize,
577  pbFrameData,
578  pFrame->CompressedSize,
579  (DWORD)(pFrame - hf->pFrames));
580  if(nError == ERROR_SUCCESS)
581  {
582  // Set the start and end of the cache
583  hf->CacheStart = dwFrameStart;
584  hf->CacheEnd = dwFrameEnd;
585  }
586  }
587  else
588  {
589  nError = ERROR_FILE_CORRUPT;
590  }
591 
592  // Free the raw frame data
593  CASC_FREE(pbFrameData);
594  }
595 
596  // Copy the decompressed data
597  if(dwFrameEnd > dwEndPointer)
598  dwFrameEnd = dwEndPointer;
599  memcpy(pbBuffer, hf->pbFileCache + (dwFilePointer - dwFrameStart), (dwFrameEnd - dwFilePointer));
600  pbBuffer += (dwFrameEnd - dwFilePointer);
601 
602  // Move pointers
603  dwFilePointer = dwFrameEnd;
604  pFrame++;
605  }
606  }
607 
608  // Update the file position
609  if(nError == ERROR_SUCCESS)
610  {
611  if(pdwBytesRead != NULL)
612  *pdwBytesRead = (dwFilePointer - dwStartPointer);
613  hf->FilePointer = dwFilePointer;
614  }
615 
616  if(nError != ERROR_SUCCESS)
617  SetLastError(nError);
618  return (nError == ERROR_SUCCESS);
619 }
DWORD CacheEnd
Definition: CascCommon.h:249
DWORD FrameSize
Definition: CascCommon.h:131
#define CASC_ALLOC(type, count)
Definition: CascCommon.h:302
unsigned long long ULONGLONG
Definition: CascPort.h:144
bool IsValidMD5(LPBYTE pbMd5)
Definition: Common.cpp:484
bool FileStream_Read(TFileStream *pStream, ULONGLONG *pByteOffset, void *pvBuffer, DWORD dwBytesToRead)
Definition: FileStream.cpp:2551
#define ERROR_NOT_ENOUGH_MEMORY
Definition: CascPort.h:208
bool FileStream_GetSize(TFileStream *pStream, ULONGLONG *pFileSize)
Definition: FileStream.cpp:2595
#define ERROR_FILE_CORRUPT
Definition: CascPort.h:218
arena_t NULL
Definition: jemalloc_internal.h:624
DWORD FileSize
Definition: CascCommon.h:240
static int EnsureFrameHeadersLoaded(TCascFile *hf)
Definition: CascReadFile.cpp:202
BYTE * LPBYTE
Definition: CascPort.h:152
LPBYTE pbFileCache
Definition: CascCommon.h:246
static int ProcessFileFrame(LPBYTE pbOutBuffer, DWORD cbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer, DWORD dwFrameIndex)
Definition: CascReadFile.cpp:268
#define CASC_FREE(ptr)
Definition: CascCommon.h:303
#define ERROR_INVALID_HANDLE
Definition: CascPort.h:207
bool VerifyDataBlockHash(void *pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5)
Definition: Common.cpp:494
void SetLastError(int nError)
Definition: Common.cpp:75
PCASC_FILE_FRAME pFrames
Definition: CascCommon.h:243
DWORD cbFileCache
Definition: CascCommon.h:247
BYTE md5[MD5_HASH_SIZE]
Definition: CascCommon.h:132
unsigned int DWORD
Definition: CascPort.h:139
int GetLastError()
Definition: Common.cpp:70
DWORD CacheStart
Definition: CascCommon.h:248
static PCASC_FILE_FRAME FindFileFrame(TCascFile *hf, DWORD FilePointer)
Definition: CascReadFile.cpp:244
DWORD FrameArchiveOffset
Definition: CascCommon.h:128
TCascFile * IsValidFileHandle(HANDLE hFile)
Definition: CascOpenFile.cpp:18
Definition: CascCommon.h:126
DWORD FrameFileOffset
Definition: CascCommon.h:129
#define ERROR_INVALID_PARAMETER
Definition: CascPort.h:210
#define ERROR_HANDLE_EOF
Definition: CascPort.h:216
unsigned char BYTE
Definition: CascPort.h:136
Definition: CascCommon.h:227
DWORD FilePointer
Definition: CascCommon.h:233
TFileStream * pStream
Definition: CascCommon.h:230
#define ERROR_SUCCESS
Definition: CascPort.h:204
DWORD CompressedSize
Definition: CascCommon.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

DWORD WINAPI CascSetFilePointer ( HANDLE  hFile,
LONG  lFilePos,
LONG plFilePosHigh,
DWORD  dwMoveMethod 
)
396 {
397  TCascFile * hf;
398  ULONGLONG FilePosition;
399  ULONGLONG MoveOffset;
400  DWORD dwFilePosHi;
401 
402  // If the hFile is not a valid file handle, return an error.
403  hf = IsValidFileHandle(hFile);
404  if(hf == NULL)
405  {
407  return CASC_INVALID_POS;
408  }
409 
410  // Get the relative point where to move from
411  switch(dwMoveMethod)
412  {
413  case FILE_BEGIN:
414  FilePosition = 0;
415  break;
416 
417  case FILE_CURRENT:
418  FilePosition = hf->FilePointer;
419  break;
420 
421  case FILE_END:
422  FilePosition = hf->FileSize;
423  break;
424 
425  default:
427  return CASC_INVALID_POS;
428  }
429 
430  // Now get the move offset. Note that both values form
431  // a signed 64-bit value (a file pointer can be moved backwards)
432  if(plFilePosHigh != NULL)
433  dwFilePosHi = *plFilePosHigh;
434  else
435  dwFilePosHi = (lFilePos & 0x80000000) ? 0xFFFFFFFF : 0;
436  MoveOffset = MAKE_OFFSET64(dwFilePosHi, lFilePos);
437 
438  // Now calculate the new file pointer
439  // Do not allow the file pointer to overflow
440  FilePosition = ((FilePosition + MoveOffset) >= FilePosition) ? (FilePosition + MoveOffset) : 0;
441 
442  // CASC files can't be bigger than 4 GB.
443  // We don't allow to go past 4 GB
444  if(FilePosition >> 32)
445  {
447  return CASC_INVALID_POS;
448  }
449 
450  // Change the file position
451  hf->FilePointer = (DWORD)FilePosition;
452 
453  // Return the new file position
454  if(plFilePosHigh != NULL)
455  *plFilePosHigh = 0;
456  return hf->FilePointer;
457 }
unsigned long long ULONGLONG
Definition: CascPort.h:144
#define FILE_END
Definition: CascPort.h:167
arena_t NULL
Definition: jemalloc_internal.h:624
DWORD FileSize
Definition: CascCommon.h:240
#define CASC_INVALID_POS
Definition: CascLib.h:119
#define ERROR_INVALID_HANDLE
Definition: CascPort.h:207
void SetLastError(int nError)
Definition: Common.cpp:75
#define FILE_BEGIN
Definition: CascPort.h:165
unsigned int DWORD
Definition: CascPort.h:139
TCascFile * IsValidFileHandle(HANDLE hFile)
Definition: CascOpenFile.cpp:18
#define ERROR_INVALID_PARAMETER
Definition: CascPort.h:210
Definition: CascCommon.h:227
DWORD FilePointer
Definition: CascCommon.h:233
#define MAKE_OFFSET64(hi, lo)
Definition: Common.h:18
#define FILE_CURRENT
Definition: CascPort.h:166

+ Here is the call graph for this function:

static int EnsureDataStreamIsOpen ( TCascFile hf)
static
32 {
33  TCascStorage * hs = hf->hs;
34  TFileStream * pStream = NULL;
35  TCHAR * szDataFile;
36  TCHAR szPlainName[0x40];
37 
38  // If the file is not open yet, do it
39  if(hs->DataFileArray[hf->ArchiveIndex] == NULL)
40  {
41  // Prepare the name of the data file
42  _stprintf(szPlainName, _T("data.%03u"), hf->ArchiveIndex);
43  szDataFile = CombinePath(hs->szIndexPath, szPlainName);
44 
45  // Open the data file
46  if(szDataFile != NULL)
47  {
48  // Open the stream
50  hs->DataFileArray[hf->ArchiveIndex] = pStream;
51  CASC_FREE(szDataFile);
52  }
53  }
54 
55  // Return error or success
56  hf->pStream = hs->DataFileArray[hf->ArchiveIndex];
57  return (hf->pStream != NULL) ? ERROR_SUCCESS : ERROR_FILE_NOT_FOUND;
58 }
arena_t NULL
Definition: jemalloc_internal.h:624
char TCHAR
Definition: CascPort.h:148
#define _T(x)
Definition: CascPort.h:171
#define CASC_FREE(ptr)
Definition: CascCommon.h:303
DWORD ArchiveIndex
Definition: CascCommon.h:235
TCHAR * CombinePath(const TCHAR *szDirectory, const TCHAR *szSubDir)
Definition: Common.cpp:157
#define ERROR_FILE_NOT_FOUND
Definition: CascPort.h:205
Definition: CascCommon.h:186
TCascStorage * hs
Definition: CascCommon.h:229
TCHAR * szIndexPath
Definition: CascCommon.h:193
#define STREAM_PROVIDER_FLAT
Definition: CascLib.h:50
TFileStream * FileStream_OpenFile(const TCHAR *szFileName, DWORD dwStreamFlags)
Definition: FileStream.cpp:2384
#define BASE_PROVIDER_FILE
Definition: CascLib.h:45
Definition: FileStream.h:153
#define _stprintf
Definition: CascPort.h:181
TFileStream * DataFileArray[CASC_MAX_DATA_FILES]
Definition: CascCommon.h:214
#define STREAM_FLAG_READ_ONLY
Definition: CascLib.h:56
TFileStream * pStream
Definition: CascCommon.h:230
#define ERROR_SUCCESS
Definition: CascPort.h:204

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int EnsureFrameHeadersLoaded ( TCascFile hf)
static
203 {
204  int nError;
205 
206  // Make sure we have header area loaded
207  nError = EnsureHeaderAreaIsLoaded(hf);
208  if(nError != ERROR_SUCCESS)
209  return nError;
210 
211  // If the frame headers are not loaded yet, do it
212  if(hf->pFrames == NULL)
213  {
214  // Allocate the frame array
216  if(hf->pFrames != NULL)
217  {
218  // Either load the frames from the file or supply them on our own
219  if(hf->HeaderSize != 0)
220  {
221  hf->FramesOffset = hf->HeaderOffset + sizeof(DWORD) + sizeof(DWORD) + sizeof(DWORD);
222  nError = LoadFileFrames(hf);
223  }
224  else
225  {
226  // Offset of the first frame is right after the file frames
227  hf->FramesOffset = hf->HeaderOffset + sizeof(DWORD) + sizeof(DWORD);
228 
230  hf->pFrames[0].FrameFileOffset = 0;
232  hf->pFrames[0].FrameSize = hf->FileSize;
233  memset(hf->pFrames[0].md5, 0, MD5_HASH_SIZE);
234  }
235  }
236 
237  // Return result
238  return (hf->pFrames != NULL) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
239  }
240 
241  return ERROR_SUCCESS;
242 }
DWORD FrameSize
Definition: CascCommon.h:131
DWORD HeaderOffset
Definition: CascCommon.h:236
#define CASC_ALLOC(type, count)
Definition: CascCommon.h:302
#define ERROR_FILE_CORRUPT
Definition: CascPort.h:218
arena_t NULL
Definition: jemalloc_internal.h:624
DWORD FileSize
Definition: CascCommon.h:240
DWORD FrameCount
Definition: CascCommon.h:244
DWORD FramesOffset
Definition: CascCommon.h:238
#define MD5_HASH_SIZE
Definition: CascLib.h:105
PCASC_FILE_FRAME pFrames
Definition: CascCommon.h:243
DWORD HeaderSize
Definition: CascCommon.h:237
BYTE md5[MD5_HASH_SIZE]
Definition: CascCommon.h:132
unsigned int DWORD
Definition: CascPort.h:139
DWORD FrameArchiveOffset
Definition: CascCommon.h:128
Definition: CascCommon.h:126
DWORD FrameFileOffset
Definition: CascCommon.h:129
DWORD CompressedSize
Definition: CascCommon.h:239
static int EnsureHeaderAreaIsLoaded(TCascFile *hf)
Definition: CascReadFile.cpp:119
static int LoadFileFrames(TCascFile *hf)
Definition: CascReadFile.cpp:60
#define ERROR_SUCCESS
Definition: CascPort.h:204
DWORD CompressedSize
Definition: CascCommon.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int EnsureHeaderAreaIsLoaded ( TCascFile hf)
static
120 {
121  TCascStorage * hs = hf->hs;
122  ULONGLONG FileOffset = hf->HeaderOffset;
123  LPBYTE pbHeaderArea;
124  DWORD FileSignature;
125  DWORD FileSize;
126  BYTE HeaderArea[MAX_HEADER_AREA_SIZE];
127  int nError;
128 
129  // We need the data file to be open
130  nError = EnsureDataStreamIsOpen(hf);
131  if(nError != ERROR_SUCCESS)
132  return nError;
133 
134  // Make sure that we already know the shift
135  // to the begin of file data.
136  // Note that older builds of Heroes of the Storm have entries pointing
137  // to the beginning of the header area.
138  // Newer versions of HOTS have encoding entries pointing directly to
139  // the BLTE header
140  if(hs->dwFileBeginDelta == 0xFFFFFFFF)
141  {
142  FileSignature = 0;
143  FileOffset = hf->HeaderOffset;
144  if(!FileStream_Read(hf->pStream, &FileOffset, &FileSignature, sizeof(DWORD)))
145  return ERROR_FILE_CORRUPT;
146 
147  hs->dwFileBeginDelta = (FileSignature == BLTE_HEADER_SIGNATURE) ? BLTE_HEADER_DELTA : 0;
148  }
149 
150  // If the file size is not loaded yet, do it
151  if(hf->FrameCount == 0)
152  {
153  // Load the part before BLTE header + header itself
154  FileOffset = hf->HeaderOffset - hs->dwFileBeginDelta;
155  if(!FileStream_Read(hf->pStream, &FileOffset, HeaderArea, sizeof(HeaderArea)))
156  return ERROR_FILE_CORRUPT;
157 
158  // Copy the MD5 hash of the frame array
159  memcpy(hf->FrameArrayHash, HeaderArea, MD5_HASH_SIZE);
160  pbHeaderArea = HeaderArea + MD5_HASH_SIZE;
161 
162  // Copy the file size
163  FileSize = ConvertBytesToInteger_4_LE(pbHeaderArea);
164  pbHeaderArea += 0x0E;
165 
166  // Verify the BLTE signature
168  return ERROR_BAD_FORMAT;
169  pbHeaderArea += sizeof(DWORD);
170 
171  // Load the size of the frame headers
172  hf->HeaderSize = ConvertBytesToInteger_4(pbHeaderArea);
173  if(hf->HeaderSize & 0x80000000)
174  return ERROR_BAD_FORMAT;
175  pbHeaderArea += sizeof(DWORD);
176 
177  // Read the header size
178  assert(hs->dwFileBeginDelta <= BLTE_HEADER_DELTA);
180  hf->FrameCount = 1;
181 
182  // Retrieve the frame count, if different from 1
183  if(hf->HeaderSize != 0)
184  {
185  // The next byte must be 0x0F
186  if(pbHeaderArea[0] != 0x0F)
187  return ERROR_BAD_FORMAT;
188  pbHeaderArea++;
189 
190  // Next three bytes form number of frames
191  hf->FrameCount = ConvertBytesToInteger_3(pbHeaderArea);
192  }
193 
194 #ifdef CASCLIB_TEST
195  hf->FileSize_HdrArea = FileSize;
196 #endif
197  }
198 
199  return ERROR_SUCCESS;
200 }
DWORD HeaderOffset
Definition: CascCommon.h:236
unsigned long long ULONGLONG
Definition: CascPort.h:144
bool FileStream_Read(TFileStream *pStream, ULONGLONG *pByteOffset, void *pvBuffer, DWORD dwBytesToRead)
Definition: FileStream.cpp:2551
#define ERROR_FILE_CORRUPT
Definition: CascPort.h:218
BYTE * LPBYTE
Definition: CascPort.h:152
DWORD dwFileBeginDelta
Definition: CascCommon.h:198
DWORD ConvertBytesToInteger_3(LPBYTE ValueAsBytes)
Definition: CascCommon.cpp:19
DWORD FrameCount
Definition: CascCommon.h:244
#define MD5_HASH_SIZE
Definition: CascLib.h:105
DWORD HeaderSize
Definition: CascCommon.h:237
BYTE FrameArrayHash[MD5_HASH_SIZE]
Definition: CascCommon.h:241
Definition: CascCommon.h:186
#define MAX_HEADER_AREA_SIZE
Definition: CascCommon.h:59
TCascStorage * hs
Definition: CascCommon.h:229
unsigned int DWORD
Definition: CascPort.h:139
#define BLTE_HEADER_SIGNATURE
Definition: CascCommon.h:57
DWORD ConvertBytesToInteger_4_LE(LPBYTE ValueAsBytes)
Definition: CascCommon.cpp:43
#define ERROR_BAD_FORMAT
Definition: CascPort.h:214
static int EnsureDataStreamIsOpen(TCascFile *hf)
Definition: CascReadFile.cpp:31
unsigned char BYTE
Definition: CascPort.h:136
DWORD ConvertBytesToInteger_4(LPBYTE ValueAsBytes)
Definition: CascCommon.cpp:31
#define BLTE_HEADER_DELTA
Definition: CascCommon.h:58
TFileStream * pStream
Definition: CascCommon.h:230
#define ERROR_SUCCESS
Definition: CascPort.h:204

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static PCASC_FILE_FRAME FindFileFrame ( TCascFile hf,
DWORD  FilePointer 
)
static
245 {
246  PCASC_FILE_FRAME pFrame = hf->pFrames;
247  DWORD FrameBegin;
248  DWORD FrameEnd;
249 
250  // Sanity checks
251  assert(hf->pFrames != NULL);
252  assert(hf->FrameCount != 0);
253 
254  // Find the frame where to read from
255  for(DWORD i = 0; i < hf->FrameCount; i++, pFrame++)
256  {
257  // Does the read request fit into the current frame?
258  FrameBegin = pFrame->FrameFileOffset;
259  FrameEnd = FrameBegin + pFrame->FrameSize;
260  if(FrameBegin <= FilePointer && FilePointer < FrameEnd)
261  return pFrame;
262  }
263 
264  // Not found, sorry
265  return NULL;
266 }
DWORD FrameSize
Definition: CascCommon.h:131
arena_t NULL
Definition: jemalloc_internal.h:624
DWORD FrameCount
Definition: CascCommon.h:244
PCASC_FILE_FRAME pFrames
Definition: CascCommon.h:243
unsigned int DWORD
Definition: CascPort.h:139
Definition: CascCommon.h:126
DWORD FrameFileOffset
Definition: CascCommon.h:129

+ Here is the caller graph for this function:

TCascFile* IsValidFileHandle ( HANDLE  hFile)
19 {
20  TCascFile * hf = (TCascFile *)hFile;
21 
22  return (hf != NULL && hf->hs != NULL && hf->szClassName != NULL && !strcmp(hf->szClassName, "TCascFile")) ? hf : NULL;
23 }
const char * szClassName
Definition: CascCommon.h:231
arena_t NULL
Definition: jemalloc_internal.h:624
TCascStorage * hs
Definition: CascCommon.h:229
Definition: CascCommon.h:227

+ Here is the caller graph for this function:

static int LoadFileFrames ( TCascFile hf)
static
61 {
62  PBLTE_FRAME pFileFrames;
63  PBLTE_FRAME pFileFrame;
64  ULONGLONG ArchiveFileOffset;
65  DWORD FrameOffset = 0;
66  DWORD FileSize = 0;
67  int nError = ERROR_SUCCESS;
68 
69  assert(hf != NULL);
70  assert(hf->pStream != NULL);
71  assert(hf->pFrames != NULL);
72 
73  // Allocate frame array
74  pFileFrames = pFileFrame = CASC_ALLOC(BLTE_FRAME, hf->FrameCount);
75  if(pFileFrames != NULL)
76  {
77  // Load the frame array
78  ArchiveFileOffset = hf->FramesOffset;
79  if(FileStream_Read(hf->pStream, &ArchiveFileOffset, pFileFrames, hf->FrameCount * sizeof(BLTE_FRAME)))
80  {
81  // Move the raw archive offset
82  ArchiveFileOffset += (hf->FrameCount * sizeof(BLTE_FRAME));
83 
84  // Copy the frames to the file structure
85  for(DWORD i = 0; i < hf->FrameCount; i++, pFileFrame++)
86  {
87  hf->pFrames[i].FrameArchiveOffset = (DWORD)ArchiveFileOffset;
88  hf->pFrames[i].FrameFileOffset = FrameOffset;
90  hf->pFrames[i].FrameSize = ConvertBytesToInteger_4(pFileFrame->FrameSize);
91  memcpy(hf->pFrames[i].md5, pFileFrame->md5, MD5_HASH_SIZE);
92 
93  ArchiveFileOffset += hf->pFrames[i].CompressedSize;
94  FrameOffset += hf->pFrames[i].FrameSize;
95  FileSize += hf->pFrames[i].FrameSize;
96  }
97  }
98  else
99  nError = GetLastError();
100 
101  // Note: on ENCODING file, this value is almost always bigger
102  // then the real size of ENCODING. We handle this problem
103  // by calculating size of the ENCODIG file from its header.
104  hf->FileSize = FileSize;
105 
106 #ifdef CASCLIB_TEST
107  hf->FileSize_FrameSum = FileSize;
108 #endif
109 
110  // Free the array
111  CASC_FREE(pFileFrames);
112  }
113  else
114  nError = ERROR_NOT_ENOUGH_MEMORY;
115 
116  return nError;
117 }
DWORD FrameSize
Definition: CascCommon.h:131
#define CASC_ALLOC(type, count)
Definition: CascCommon.h:302
unsigned long long ULONGLONG
Definition: CascPort.h:144
bool FileStream_Read(TFileStream *pStream, ULONGLONG *pByteOffset, void *pvBuffer, DWORD dwBytesToRead)
Definition: FileStream.cpp:2551
#define ERROR_NOT_ENOUGH_MEMORY
Definition: CascPort.h:208
arena_t NULL
Definition: jemalloc_internal.h:624
DWORD FileSize
Definition: CascCommon.h:240
BYTE CompressedSize[4]
Definition: CascReadFile.cpp:20
DWORD FrameCount
Definition: CascCommon.h:244
#define CASC_FREE(ptr)
Definition: CascCommon.h:303
Definition: CascReadFile.cpp:18
DWORD FramesOffset
Definition: CascCommon.h:238
#define MD5_HASH_SIZE
Definition: CascLib.h:105
PCASC_FILE_FRAME pFrames
Definition: CascCommon.h:243
BYTE md5[MD5_HASH_SIZE]
Definition: CascCommon.h:132
BYTE md5[MD5_HASH_SIZE]
Definition: CascReadFile.cpp:22
unsigned int DWORD
Definition: CascPort.h:139
BYTE FrameSize[4]
Definition: CascReadFile.cpp:21
int GetLastError()
Definition: Common.cpp:70
DWORD FrameArchiveOffset
Definition: CascCommon.h:128
DWORD FrameFileOffset
Definition: CascCommon.h:129
DWORD ConvertBytesToInteger_4(LPBYTE ValueAsBytes)
Definition: CascCommon.cpp:31
struct _BLTE_FRAME BLTE_FRAME
TFileStream * pStream
Definition: CascCommon.h:230
#define ERROR_SUCCESS
Definition: CascPort.h:204
DWORD CompressedSize
Definition: CascCommon.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int ProcessFileFrame ( LPBYTE  pbOutBuffer,
DWORD  cbOutBuffer,
LPBYTE  pbInBuffer,
DWORD  cbInBuffer,
DWORD  dwFrameIndex 
)
static
274 {
275  LPBYTE pbTempBuffer;
276  LPBYTE pbWorkBuffer;
277  DWORD cbTempBuffer = CASCLIB_MAX(cbInBuffer, cbOutBuffer);
278  DWORD cbWorkBuffer = cbOutBuffer + 1;
279  DWORD dwStepCount = 0;
280  bool bWorkComplete = false;
281  int nError = ERROR_SUCCESS;
282 
283  // Allocate the temporary buffer that will serve as output
284  pbWorkBuffer = pbTempBuffer = CASC_ALLOC(BYTE, cbTempBuffer);
285  if(pbWorkBuffer == NULL)
287 
288  // Perform the loop
289  for(;;)
290  {
291  // Set the output buffer.
292  // Even operations: extract to temporary buffer
293  // Odd operations: extract to output buffer
294  pbWorkBuffer = (dwStepCount & 0x01) ? pbOutBuffer : pbTempBuffer;
295  cbWorkBuffer = (dwStepCount & 0x01) ? cbOutBuffer : cbTempBuffer;
296 
297  // Perform the operation specific to the operation ID
298  switch(pbInBuffer[0])
299  {
300  case 'E': // Encrypted files
301  nError = CascDecrypt(pbWorkBuffer, &cbWorkBuffer, pbInBuffer + 1, cbInBuffer - 1, dwFrameIndex);
302  bWorkComplete = (nError != ERROR_SUCCESS);
303  break;
304 
305  case 'Z': // ZLIB compressed files
306  nError = CascDecompress(pbWorkBuffer, &cbWorkBuffer, pbInBuffer + 1, cbInBuffer - 1);
307  bWorkComplete = true;
308  break;
309 
310  case 'N': // Normal stored files
311  nError = CascDirectCopy(pbWorkBuffer, &cbWorkBuffer, pbInBuffer + 1, cbInBuffer - 1);
312  bWorkComplete = true;
313  break;
314 
315  case 'F': // Recursive frames - not supported
316  default: // Unrecognized - if we unpacked something, we consider it done
317  nError = ERROR_NOT_SUPPORTED;
318  bWorkComplete = true;
319  assert(false);
320  break;
321  }
322 
323  // Are we done?
324  if(bWorkComplete)
325  break;
326 
327  // Set the input buffer to the work buffer
328  pbInBuffer = pbWorkBuffer;
329  cbInBuffer = cbWorkBuffer;
330  dwStepCount++;
331  }
332 
333  // If the data are currently in the temporary buffer,
334  // we need to copy them to output buffer
335  if(nError == ERROR_SUCCESS && pbWorkBuffer != pbOutBuffer)
336  {
337  if(cbWorkBuffer != cbOutBuffer)
338  nError = ERROR_INSUFFICIENT_BUFFER;
339  memcpy(pbOutBuffer, pbWorkBuffer, cbOutBuffer);
340  }
341 
342  // Free the temporary buffer
343  CASC_FREE(pbTempBuffer);
344  return nError;
345 }
int CascDirectCopy(LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer)
Definition: CascDecrypt.cpp:289
#define CASC_ALLOC(type, count)
Definition: CascCommon.h:302
int CascDecrypt(LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer, DWORD dwFrameIndex)
Definition: CascDecrypt.cpp:205
#define ERROR_NOT_ENOUGH_MEMORY
Definition: CascPort.h:208
#define ERROR_INSUFFICIENT_BUFFER
Definition: CascPort.h:213
arena_t NULL
Definition: jemalloc_internal.h:624
BYTE * LPBYTE
Definition: CascPort.h:152
#define CASC_FREE(ptr)
Definition: CascCommon.h:303
unsigned int DWORD
Definition: CascPort.h:139
int CascDecompress(LPBYTE pvOutBuffer, PDWORD pcbOutBuffer, LPBYTE pvInBuffer, DWORD cbInBuffer)
Definition: CascDecompress.cpp:18
#define CASCLIB_MAX(a, b)
Definition: CascCommon.h:74
#define ERROR_NOT_SUPPORTED
Definition: CascPort.h:209
unsigned char BYTE
Definition: CascPort.h:136
#define ERROR_SUCCESS
Definition: CascPort.h:204

+ Here is the call graph for this function:

+ Here is the caller graph for this function: