| 2350 | } |
| 2351 | |
| 2352 | static int BuildFileTable_Classic(TMPQArchive * ha) |
| 2353 | { |
| 2354 | TMPQHeader * pHeader = ha->pHeader; |
| 2355 | TMPQBlock * pBlockTable; |
| 2356 | int nError = ERROR_SUCCESS; |
| 2357 | |
| 2358 | // Sanity checks |
| 2359 | assert(ha->pHashTable != NULL); |
| 2360 | assert(ha->pFileTable != NULL); |
| 2361 | |
| 2362 | // If the MPQ has no block table, do nothing |
| 2363 | if(pHeader->dwBlockTableSize == 0) |
| 2364 | return ERROR_SUCCESS; |
| 2365 | assert(ha->dwFileTableSize >= pHeader->dwBlockTableSize); |
| 2366 | |
| 2367 | // Load the block table |
| 2368 | // WARNING! ha->pFileTable can change in the process!! |
| 2369 | pBlockTable = (TMPQBlock *)LoadBlockTable(ha); |
| 2370 | if(pBlockTable != NULL) |
| 2371 | { |
| 2372 | nError = BuildFileTableFromBlockTable(ha, pBlockTable); |
| 2373 | STORM_FREE(pBlockTable); |
| 2374 | } |
| 2375 | else |
| 2376 | { |
| 2377 | nError = ERROR_NOT_ENOUGH_MEMORY; |
| 2378 | } |
| 2379 | |
| 2380 | // Load the hi-block table |
| 2381 | if(nError == ERROR_SUCCESS && pHeader->HiBlockTablePos64 != 0) |
| 2382 | { |
| 2383 | ULONGLONG ByteOffset; |
| 2384 | USHORT * pHiBlockTable = NULL; |
| 2385 | DWORD dwTableSize = pHeader->dwBlockTableSize * sizeof(USHORT); |
| 2386 | |
| 2387 | // Allocate space for the hi-block table |
| 2388 | // Note: pHeader->dwBlockTableSize can be zero !!! |
| 2389 | pHiBlockTable = STORM_ALLOC(USHORT, pHeader->dwBlockTableSize + 1); |
| 2390 | if(pHiBlockTable != NULL) |
| 2391 | { |
| 2392 | // Load the hi-block table. It is not encrypted, nor compressed |
| 2393 | ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64; |
| 2394 | if(!FileStream_Read(ha->pStream, &ByteOffset, pHiBlockTable, dwTableSize)) |
| 2395 | nError = GetLastError(); |
| 2396 | |
| 2397 | // Now merge the hi-block table to the file table |
| 2398 | if(nError == ERROR_SUCCESS) |
| 2399 | { |
| 2400 | TFileEntry * pFileEntry = ha->pFileTable; |
| 2401 | |
| 2402 | // Swap the hi-block table |
| 2403 | BSWAP_ARRAY16_UNSIGNED(pHiBlockTable, dwTableSize); |
| 2404 | |
| 2405 | // Add the high file offset to the base file offset. |
| 2406 | for(DWORD i = 0; i < pHeader->dwBlockTableSize; i++, pFileEntry++) |
| 2407 | pFileEntry->ByteOffset = MAKE_OFFSET64(pHiBlockTable[i], pFileEntry->ByteOffset); |
| 2408 | } |
| 2409 |
no test coverage detected