TrinityCore
ListFile.cpp File Reference
#include "../CascLib.h"
#include "../CascCommon.h"
+ Include dependency graph for ListFile.cpp:

Classes

struct  _LISTFILE_CACHE
 

Macros

#define __CASCLIB_SELF__
 
#define LISTFILE_FLAG_USES_FILEDATAID   0x0001
 

Typedefs

typedef struct _LISTFILE_CACHE LISTFILE_CACHE
 
typedef struct _LISTFILE_CACHEPLISTFILE_CACHE
 

Functions

static PLISTFILE_CACHE ListFile_CreateCache (DWORD dwFileSize)
 
static char * ListFile_SkipSpaces (PLISTFILE_CACHE pCache)
 
static void ListFile_CheckFormat (PLISTFILE_CACHE pCache)
 
static int ListFile_GetFileDataId (PLISTFILE_CACHE pCache, PDWORD PtrFileDataId)
 
void * ListFile_OpenExternal (LPCTSTR szListFile)
 
void * ListFile_FromBuffer (LPBYTE pbBuffer, DWORD cbBuffer)
 
bool ListFile_VerifyMD5 (void *pvListFile, LPBYTE pbHashMD5)
 
size_t ListFile_GetNextLine (void *pvListFile, const char **pszLineBegin, const char **pszLineEnd)
 
size_t ListFile_GetNextLine (void *pvListFile, char *szBuffer, size_t nMaxChars)
 
size_t ListFile_GetNext (void *pvListFile, char *szBuffer, size_t nMaxChars, PDWORD PtrFileDataId)
 
LPBYTE ListFile_GetData (void *pvListFile, PDWORD PtrDataSize)
 

Macro Definition Documentation

◆ __CASCLIB_SELF__

#define __CASCLIB_SELF__

◆ LISTFILE_FLAG_USES_FILEDATAID

#define LISTFILE_FLAG_USES_FILEDATAID   0x0001

Typedef Documentation

◆ LISTFILE_CACHE

◆ PLISTFILE_CACHE

typedef struct _LISTFILE_CACHE * PLISTFILE_CACHE

Function Documentation

◆ ListFile_CheckFormat()

static void ListFile_CheckFormat ( PLISTFILE_CACHE  pCache)
static
64 {
65  // Only if the listfile is greatger than 2 MB
66  if((pCache->pEnd - pCache->pBegin) > 0x100000)
67  {
68  char * szPtr = pCache->pBegin;
69  size_t nDigitCount = 0;
70 
71  // Calculate the amount of digits
72  while(nDigitCount <= 20 && '0' <= szPtr[nDigitCount] && szPtr[nDigitCount] <= '9')
73  nDigitCount++;
74 
75  // There must be a semicolon after
76  if(nDigitCount <= 10 && szPtr[nDigitCount] == ';')
77  {
79  }
80  }
81 }
char * pEnd
Definition: ListFile.cpp:24
char * pBegin
Definition: ListFile.cpp:22
#define LISTFILE_FLAG_USES_FILEDATAID
Definition: ListFile.cpp:18
DWORD Flags
Definition: ListFile.cpp:25
+ Here is the caller graph for this function:

◆ ListFile_CreateCache()

static PLISTFILE_CACHE ListFile_CreateCache ( DWORD  dwFileSize)
static
35 {
36  PLISTFILE_CACHE pCache;
37 
38  // Allocate cache for one file block
39  pCache = (PLISTFILE_CACHE)CASC_ALLOC<BYTE>(sizeof(LISTFILE_CACHE) + dwFileSize);
40  if(pCache != NULL)
41  {
42  // Set the initial pointers
43  pCache->pBegin =
44  pCache->pPos = (char *)(pCache + 1);
45  pCache->pEnd = pCache->pBegin + dwFileSize;
46  pCache->Flags = 0;
47  }
48 
49  // Return the cache
50  return pCache;
51 }
char * pEnd
Definition: ListFile.cpp:24
struct _LISTFILE_CACHE * PLISTFILE_CACHE
char * pBegin
Definition: ListFile.cpp:22
DWORD Flags
Definition: ListFile.cpp:25
char * pPos
Definition: ListFile.cpp:23
Definition: ListFile.cpp:20
+ Here is the caller graph for this function:

◆ ListFile_FromBuffer()

void* ListFile_FromBuffer ( LPBYTE  pbBuffer,
DWORD  cbBuffer 
)
162 {
163  PLISTFILE_CACHE pCache = NULL;
164 
165  // Create the in-memory cache for the entire listfile
166  // The listfile does not have any data loaded yet
167  pCache = ListFile_CreateCache(cbBuffer);
168  if(pCache != NULL)
169  memcpy(pCache->pBegin, pbBuffer, cbBuffer);
170 
171  return pCache;
172 }
static PLISTFILE_CACHE ListFile_CreateCache(DWORD dwFileSize)
Definition: ListFile.cpp:34
char * pBegin
Definition: ListFile.cpp:22
Definition: ListFile.cpp:20
+ Here is the call graph for this function:

◆ ListFile_GetData()

LPBYTE ListFile_GetData ( void *  pvListFile,
PDWORD  PtrDataSize 
)
300 {
301  PLISTFILE_CACHE pCache = (PLISTFILE_CACHE)pvListFile;
302  LPBYTE pbData = NULL;
303  DWORD cbData = 0;
304 
305  // Get data from the list file cache
306  if (pvListFile != NULL)
307  {
308  pbData = (LPBYTE)pCache->pBegin;
309  cbData = (DWORD)(pCache->pEnd - pCache->pBegin);
310  }
311 
312  // Give the data to the caller
313  if (PtrDataSize != NULL)
314  PtrDataSize[0] = cbData;
315  return pbData;
316 }
char * pEnd
Definition: ListFile.cpp:24
BYTE * LPBYTE
Definition: CascPort.h:173
struct _LISTFILE_CACHE * PLISTFILE_CACHE
char * pBegin
Definition: ListFile.cpp:22
unsigned int DWORD
Definition: CascPort.h:162
Definition: ListFile.cpp:20

◆ ListFile_GetFileDataId()

static int ListFile_GetFileDataId ( PLISTFILE_CACHE  pCache,
PDWORD  PtrFileDataId 
)
static
84 {
85  char * szLineBegin = ListFile_SkipSpaces(pCache);
86  char * szLineEnd;
87  DWORD dwNewInt32 = 0;
88  DWORD dwInt32 = 0;
89 
90  // Set the limit for loading the number
91  szLineEnd = CASCLIB_MIN((szLineBegin + 20), pCache->pEnd);
92 
93  // Extract decimal digits from the string
94  while(szLineBegin < szLineEnd && '0' <= szLineBegin[0] && szLineBegin[0] <= '9')
95  {
96  // Check integer overflow
97  dwNewInt32 = (dwInt32 * 10) + (szLineBegin[0] - '0');
98  if(dwNewInt32 < dwInt32)
99  return ERROR_BAD_FORMAT;
100 
101  dwInt32 = dwNewInt32;
102  szLineBegin++;
103  }
104 
105  // There must still be some space
106  if(szLineBegin < szLineEnd)
107  {
108  // There must be a semicolon after the decimal integer
109  // The decimal integer must be smaller than 10 MB (files)
110  if(szLineBegin[0] != ';' || dwInt32 >= 0xA00000)
111  return ERROR_BAD_FORMAT;
112 
113  pCache->pPos = szLineBegin + 1;
114  PtrFileDataId[0] = dwInt32;
115  return ERROR_SUCCESS;
116  }
117 
118  return ERROR_NO_MORE_FILES;
119 }
char * pEnd
Definition: ListFile.cpp:24
#define CASCLIB_MIN(a, b)
Definition: Common.h:26
static char * ListFile_SkipSpaces(PLISTFILE_CACHE pCache)
Definition: ListFile.cpp:53
#define ERROR_NO_MORE_FILES
Definition: CascPort.h:242
unsigned int DWORD
Definition: CascPort.h:162
char * pPos
Definition: ListFile.cpp:23
#define ERROR_BAD_FORMAT
Definition: CascPort.h:241
#define ERROR_SUCCESS
Definition: CascPort.h:230
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ListFile_GetNext()

size_t ListFile_GetNext ( void *  pvListFile,
char *  szBuffer,
size_t  nMaxChars,
PDWORD  PtrFileDataId 
)
253 {
254  PLISTFILE_CACHE pCache = (PLISTFILE_CACHE)pvListFile;
255  const char * szTemp;
256  size_t nLength = 0;
257  DWORD dwErrCode = ERROR_SUCCESS;
258 
259  // Check for parameters
260  for(;;)
261  {
262  DWORD FileDataId = CASC_INVALID_ID;
263 
264  // If this is a CSV-format listfile, we need to extract the FileDataId
265  // Lines that contain bogus data, invalid numbers or too big values will be skipped
267  {
268  // Retrieve the data ID from the current position
269  dwErrCode = ListFile_GetFileDataId(pCache, &FileDataId);
270  if(dwErrCode == ERROR_NO_MORE_FILES)
271  break;
272 
273  // If there was an error, skip the current line
274  if(dwErrCode != ERROR_SUCCESS || FileDataId == CASC_INVALID_ID)
275  {
276  ListFile_GetNextLine(pvListFile, &szTemp, &szTemp);
277  continue;
278  }
279  }
280 
281  // Read the (next) line
282  nLength = ListFile_GetNextLine(pvListFile, szBuffer, nMaxChars);
283  if(nLength == 0)
284  {
285  dwErrCode = GetCascError();
286  break;
287  }
288 
289  // Give the file data id and return true
290  PtrFileDataId[0] = FileDataId;
291  return nLength;
292  }
293 
294  if(dwErrCode != ERROR_SUCCESS)
295  SetCascError(dwErrCode);
296  return nLength;
297 }
void SetCascError(DWORD dwErrCode)
Definition: Common.cpp:91
static int ListFile_GetFileDataId(PLISTFILE_CACHE pCache, PDWORD PtrFileDataId)
Definition: ListFile.cpp:83
#define ERROR_NO_MORE_FILES
Definition: CascPort.h:242
#define CASC_INVALID_ID
Definition: CascLib.h:129
size_t ListFile_GetNextLine(void *pvListFile, const char **pszLineBegin, const char **pszLineEnd)
Definition: ListFile.cpp:186
struct _LISTFILE_CACHE * PLISTFILE_CACHE
#define LISTFILE_FLAG_USES_FILEDATAID
Definition: ListFile.cpp:18
DWORD Flags
Definition: ListFile.cpp:25
unsigned int DWORD
Definition: CascPort.h:162
Definition: ListFile.cpp:20
DWORD GetCascError()
Definition: Common.cpp:82
#define ERROR_SUCCESS
Definition: CascPort.h:230
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ListFile_GetNextLine() [1/2]

size_t ListFile_GetNextLine ( void *  pvListFile,
const char **  pszLineBegin,
const char **  pszLineEnd 
)
187 {
188  PLISTFILE_CACHE pCache = (PLISTFILE_CACHE)pvListFile;
189  char * szExtraString = NULL;
190  char * szLineBegin;
191  char * szLineEnd;
192 
193  // Skip newlines, spaces, tabs and another non-printable stuff
194  // Remember the begin of the line
195  szLineBegin = ListFile_SkipSpaces(pCache);
196 
197  // Copy the remaining characters
198  while(pCache->pPos < pCache->pEnd)
199  {
200  // If we have found a newline, stop loading
201  // Note: the 0x85 char came from Overwatch build 24919
202  if(pCache->pPos[0] == '\x0A' || pCache->pPos[0] == '\x0D' || pCache->pPos[0] == '\x85')
203  break;
204 
205  // Blizzard listfiles can also contain information about patch:
206  // Pass1\Files\MacOS\unconditional\user\Background Downloader.app\Contents\Info.plist~Patch(Data#frFR#base-frFR,1326)
207  if(pCache->pPos[0] == '~')
208  szExtraString = pCache->pPos;
209 
210  // Move the position by one character forward
211  pCache->pPos++;
212  }
213 
214  // Remember the end of the line
215  szLineEnd = (szExtraString != NULL && szExtraString[0] == '~' && szExtraString[1] == 'P') ? szExtraString : pCache->pPos;
216 
217  // Give the caller the positions of the begin and end of the line
218  pszLineBegin[0] = szLineBegin;
219  pszLineEnd[0] = szLineEnd;
220  return (size_t)(szLineEnd - szLineBegin);
221 }
char * pEnd
Definition: ListFile.cpp:24
static char * ListFile_SkipSpaces(PLISTFILE_CACHE pCache)
Definition: ListFile.cpp:53
struct _LISTFILE_CACHE * PLISTFILE_CACHE
char * pPos
Definition: ListFile.cpp:23
Definition: ListFile.cpp:20
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ListFile_GetNextLine() [2/2]

size_t ListFile_GetNextLine ( void *  pvListFile,
char *  szBuffer,
size_t  nMaxChars 
)
224 {
225  const char * szLineBegin = NULL;
226  const char * szLineEnd = NULL;
227  size_t nLength;
228  DWORD dwErrCode = ERROR_SUCCESS;
229 
230  // Retrieve the next line
231  nLength = ListFile_GetNextLine(pvListFile, &szLineBegin, &szLineEnd);
232 
233  // Check the length
234  if(nLength < nMaxChars)
235  {
236  // Copy the line to the user buffer
237  memcpy(szBuffer, szLineBegin, nLength);
238  szBuffer[nLength] = 0;
239  }
240  else
241  {
242  dwErrCode = ERROR_INSUFFICIENT_BUFFER;
243  nLength = 0;
244  }
245 
246  // If we didn't read anything, set the error code
247  if(nLength == 0)
248  SetCascError(dwErrCode);
249  return nLength;
250 }
void SetCascError(DWORD dwErrCode)
Definition: Common.cpp:91
#define ERROR_INSUFFICIENT_BUFFER
Definition: CascPort.h:240
size_t ListFile_GetNextLine(void *pvListFile, const char **pszLineBegin, const char **pszLineEnd)
Definition: ListFile.cpp:186
unsigned int DWORD
Definition: CascPort.h:162
#define ERROR_SUCCESS
Definition: CascPort.h:230
+ Here is the call graph for this function:

◆ ListFile_OpenExternal()

void* ListFile_OpenExternal ( LPCTSTR  szListFile)
125 {
126  PLISTFILE_CACHE pCache = NULL;
127  TFileStream * pStream;
128  ULONGLONG FileSize = 0;
129 
130  // Open the external listfile
131  pStream = FileStream_OpenFile(szListFile, STREAM_FLAG_READ_ONLY);
132  if(pStream != NULL)
133  {
134  // Retrieve the size of the external listfile
135  FileStream_GetSize(pStream, &FileSize);
136  if(0 < FileSize && FileSize <= 0x30000000)
137  {
138  // Create the in-memory cache for the entire listfile
139  // The listfile does not have any data loaded yet
140  pCache = ListFile_CreateCache((DWORD)FileSize);
141  if(pCache != NULL)
142  {
143  if(FileStream_Read(pStream, NULL, pCache->pBegin, (DWORD)FileSize))
144  {
145  ListFile_CheckFormat(pCache);
146  }
147  else
148  {
149  CASC_FREE(pCache);
150  }
151  }
152  }
153 
154  // Close the file stream
155  FileStream_Close(pStream);
156  }
157 
158  return pCache;
159 }
static PLISTFILE_CACHE ListFile_CreateCache(DWORD dwFileSize)
Definition: ListFile.cpp:34
unsigned long long ULONGLONG
Definition: CascPort.h:166
bool FileStream_Read(TFileStream *pStream, ULONGLONG *pByteOffset, void *pvBuffer, DWORD dwBytesToRead)
Definition: FileStream.cpp:2577
bool FileStream_GetSize(TFileStream *pStream, ULONGLONG *pFileSize)
Definition: FileStream.cpp:2613
TFileStream * FileStream_OpenFile(LPCTSTR szFileName, DWORD dwStreamFlags)
Definition: FileStream.cpp:2402
#define STREAM_FLAG_READ_ONLY
Definition: FileStream.h:29
char * pBegin
Definition: ListFile.cpp:22
void FileStream_Close(TFileStream *pStream)
Definition: FileStream.cpp:2725
unsigned int DWORD
Definition: CascPort.h:162
Definition: ListFile.cpp:20
Definition: FileStream.h:184
static void ListFile_CheckFormat(PLISTFILE_CACHE pCache)
Definition: ListFile.cpp:63
void CASC_FREE(T *&ptr)
Definition: Common.h:162
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ListFile_SkipSpaces()

static char* ListFile_SkipSpaces ( PLISTFILE_CACHE  pCache)
static
54 {
55  // Skip newlines, spaces, tabs and another non-printable stuff
56  while(pCache->pPos < pCache->pEnd && pCache->pPos[0] <= 0x20)
57  pCache->pPos++;
58 
59  // Remember the begin of the line
60  return pCache->pPos;
61 }
char * pEnd
Definition: ListFile.cpp:24
char * pPos
Definition: ListFile.cpp:23
+ Here is the caller graph for this function:

◆ ListFile_VerifyMD5()

bool ListFile_VerifyMD5 ( void *  pvListFile,
LPBYTE  pbHashMD5 
)
176 {
177  PLISTFILE_CACHE pCache = (PLISTFILE_CACHE)pvListFile;
178 
179  // Must be at the beginning
180  assert(pCache->pPos == pCache->pBegin);
181 
182  // Verify the MD5 hash for the entire block
183  return CascVerifyDataBlockHash(pCache->pBegin, (DWORD)(pCache->pEnd - pCache->pBegin), pbHashMD5);
184 }
#define assert(e)
Definition: assert.h:9
char * pEnd
Definition: ListFile.cpp:24
struct _LISTFILE_CACHE * PLISTFILE_CACHE
char * pBegin
Definition: ListFile.cpp:22
unsigned int DWORD
Definition: CascPort.h:162
char * pPos
Definition: ListFile.cpp:23
Definition: ListFile.cpp:20
bool CascVerifyDataBlockHash(void *pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5)
Definition: Common.cpp:656
+ Here is the call graph for this function:
+ Here is the caller graph for this function: