bool ChunkedFile::loadFile(HANDLE mpq, std::string const& fileName, bool log) { free(); HANDLE file; if (!CascOpenFile(mpq, fileName.c_str(), CASC_LOCALE_ALL, 0, &file)) { if (log) printf("No such file %s\n", fileName.c_str()); return false; } data_size = CascGetFileSize(file, nullptr); data = new uint8[data_size]; CascReadFile(file, data, data_size, nullptr/*bytesRead*/); parseChunks(); if (prepareLoadedData()) { CascCloseFile(file); return true; } printf("Error loading %s\n", fileName.c_str()); CascCloseFile(file); free(); return false; }
static LPBYTE LoadFileToMemory(TCascStorage * hs, LPBYTE pbEncodingKey, DWORD * pcbFileData) { QUERY_KEY EncodingKey; LPBYTE pbFileData = NULL; HANDLE hFile; DWORD cbBytesRead = 0; DWORD cbFileData = 0; // Open the file by encoding key EncodingKey.pbData = pbEncodingKey; EncodingKey.cbData = MD5_HASH_SIZE; if(CascOpenFileByEncodingKey((HANDLE)hs, &EncodingKey, 0, &hFile)) { // Retrieve the file size cbFileData = CascGetFileSize(hFile, NULL); if(cbFileData > 0) { pbFileData = CASC_ALLOC(BYTE, cbFileData); if(pbFileData != NULL) { CascReadFile(hFile, pbFileData, cbFileData, &cbBytesRead); } } // Close the file CascCloseFile(hFile); } // Give the file to the caller if(pcbFileData != NULL) pcbFileData[0] = cbBytesRead; return pbFileData; }
void CascFile::close(){ QMutexLocker lock(&d->Storage->Lock); if(d->FileHandle){ CascCloseFile(d->FileHandle); d->FileHandle = 0; } QIODevice::close(); }
static int TestOpenStorage_OpenFile(const TCHAR * szStorage, const char * szFileName) { HANDLE hStorage; HANDLE hFile; DWORD dwBytesRead; BYTE Buffer[0x1000]; int nError = ERROR_SUCCESS; // Open the storage directory if(!CascOpenStorage(szStorage, 0, &hStorage)) { assert(GetLastError() != ERROR_SUCCESS); nError = GetLastError(); } DWORD dwFileCount = 0; if(CascGetStorageInfo(hStorage, CascStorageFileCount, &dwFileCount, sizeof(DWORD), NULL)) { printf("file count: %d\n", dwFileCount); } DWORD dwFeatures = 0; if(CascGetStorageInfo(hStorage, CascStorageFeatures, &dwFeatures, sizeof(DWORD), NULL)) { printf("support listfile? %s\n", (dwFeatures & CASC_FEATURE_LISTFILE) ? "YES" : "NO"); } if(nError == ERROR_SUCCESS) { // Open a file if(!CascOpenFile(hStorage, szFileName, CASC_LOCALE_ZHCN, 0, &hFile)) { assert(GetLastError() != ERROR_SUCCESS); nError = GetLastError(); } } // Read some data from the file if(nError == ERROR_SUCCESS) { DWORD dwFileSize, dwFileSizeHigh; dwFileSize = CascGetFileSize(hFile, &dwFileSizeHigh); printf("file name : %s, file size: %d\n", szFileName, dwFileSize); // Read data from the file CascReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead); CascCloseFile(hFile); } // Close storage and return if(hStorage != NULL) CascCloseStorage(hStorage); return nError; }
static void DumpIndexKey( FILE * fp, TCascStorage * hs, LPBYTE pbIndexKey, int nDumpLevel) { PCASC_INDEX_ENTRY pIndexEntry; TCascFile * hf; QUERY_KEY QueryKey; HANDLE hFile; BYTE HeaderArea[MAX_HEADER_AREA_SIZE]; char szBuffer[0x20]; QueryKey.pbData = pbIndexKey; QueryKey.cbData = MD5_HASH_SIZE; pIndexEntry = FindIndexEntry(hs, &QueryKey); if(pIndexEntry != NULL) { ULONGLONG FileOffset = ConvertBytesToInteger_5(pIndexEntry->FileOffsetBE); DWORD ArchIndex = (DWORD)(FileOffset >> 0x1E); DWORD FileSize = ConvertBytesToInteger_4_LE(pIndexEntry->FileSizeLE); // Mask the file offset FileOffset &= 0x3FFFFFFF; fprintf(fp, " data.%03u at 0x%08x (0x%lx bytes)\n", ArchIndex, (DWORD)FileOffset, FileSize); if(nDumpLevel > 2) { QueryKey.pbData = pIndexEntry->IndexKey; QueryKey.cbData = MD5_HASH_SIZE; if(CascOpenFileByIndexKey((HANDLE)hs, &QueryKey, 0, &hFile)) { // Make sure that the data file is open and frame header loaded CascGetFileSize(hFile, NULL); hf = IsValidFileHandle(hFile); assert(hf->pStream != NULL); // Read the header area FileOffset = hf->HeaderOffset - BLTE_HEADER_DELTA; FileStream_Read(hf->pStream, &FileOffset, HeaderArea, sizeof(HeaderArea)); CascCloseFile(hFile); // Dump the header area fprintf(fp, " FileSize: %X Rest: %s\n", ConvertBytesToInteger_4_LE(&HeaderArea[0x10]), StringFromBinary(&HeaderArea[0x14], 10, szBuffer)); } } }
CASC::FileHandle CASC::OpenFile(StorageHandle const& storage, char const* fileName, DWORD localeMask, bool printErrors /*= false*/) { HANDLE handle = nullptr; if (!::CascOpenFile(storage.get(), fileName, localeMask, 0, &handle)) { DWORD lastError = GetLastError(); // support checking error set by *Open* call, not the next *Close* if (printErrors) fprintf(stderr, "Failed to open '%s' in CASC storage: %s\n", fileName, HumanReadableCASCError(lastError)); CascCloseFile(handle); SetLastError(lastError); return FileHandle(); } return FileHandle(handle); }
uint32 ReadBuild(int locale) { // include build info file also std::string filename = std::string("component.wow-") + localeNames[locale] + ".txt"; //printf("Read %s file... ", filename.c_str()); HANDLE dbcFile; if (!CascOpenFile(CascStorage, filename.c_str(), CASC_LOCALE_ALL, 0, &dbcFile)) { printf("Locale %s not installed.\n", localeNames[locale]); return 0; } char buff[512]; DWORD readBytes = 0; CascReadFile(dbcFile, buff, 512, &readBytes); if (!readBytes) { printf("Fatal error: Not found %s file!\n", filename.c_str()); exit(1); } std::string text = std::string(buff, readBytes); CascCloseFile(dbcFile); size_t pos = text.find("version=\""); size_t pos1 = pos + strlen("version=\""); size_t pos2 = text.find("\"", pos1); if (pos == text.npos || pos2 == text.npos || pos1 >= pos2) { printf("Fatal error: Invalid %s file format!\n", filename.c_str()); exit(1); } std::string build_str = text.substr(pos1, pos2 - pos1); int build = atoi(build_str.c_str()); if (build <= 0) { printf("Fatal error: Invalid %s file format!\n", filename.c_str()); exit(1); } return build; }
static int TestOpenStorage_OpenFile(const TCHAR * szStorage, const char * szFileName) { HANDLE hStorage; HANDLE hFile; DWORD dwBytesRead; BYTE Buffer[0x1000]; int nError = ERROR_SUCCESS; // Open the storage directory if(!CascOpenStorage(szStorage, 0, &hStorage)) { assert(GetLastError() != ERROR_SUCCESS); nError = GetLastError(); } if(nError == ERROR_SUCCESS) { // Open a file if(!CascOpenFile(hStorage, szFileName, 0, 0, &hFile)) { assert(GetLastError() != ERROR_SUCCESS); nError = GetLastError(); } } // Read some data from the file if(nError == ERROR_SUCCESS) { // Read data from the file CascReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead); CascCloseFile(hFile); } // Close storage and return if(hStorage != NULL) CascCloseStorage(hStorage); return nError; }
// copied from src\tools\map_extractor\System.cpp void ReadLiquidTypeTableDBC() { printf("Read LiquidType.dbc file..."); HANDLE dbcFile; if (!CascOpenFile(CascStorage, "DBFilesClient\\LiquidType.db2", CASC_LOCALE_NONE, 0, &dbcFile)) { printf("Fatal error: Cannot find LiquidType.dbc in archive! %s\n", HumanReadableCASCError(GetLastError())); exit(1); } DB2FileLoader db2; if (!db2.Load(dbcFile, LiquidTypeMeta::Instance())) { printf("Fatal error: Invalid LiquidType.db2 file format!\n"); exit(1); } LiqType.resize(db2.GetMaxId() + 1, 0xFFFF); for (uint32 x = 0; x < db2.GetNumRows(); ++x) { uint32 liquidTypeId; if (LiquidTypeMeta::Instance()->HasIndexFieldInData()) liquidTypeId = db2.getRecord(x).getUInt(LiquidTypeMeta::Instance()->GetIndexField(), 0); else liquidTypeId = db2.getId(x); LiqType[liquidTypeId] = db2.getRecord(x).getUInt8(13, 0); } for (uint32 x = 0; x < db2.GetNumRowCopies(); ++x) LiqType[db2.GetRowCopy(x).second] = LiqType[db2.GetRowCopy(x).first]; CascCloseFile(dbcFile); printf("Done! (" SZFMTD " LiqTypes loaded)\n", LiqType.size()); }
static int ExtractFile(HANDLE hStorage, const char * szFileName, const TCHAR * szLocalPath, DWORD dwLocaleFlags) { TFileStream * pStream = NULL; HANDLE hFile = NULL; TCHAR szLocalFileName[MAX_PATH]; TCHAR * szNamePtr = szLocalFileName; BYTE Buffer[0x1000]; DWORD dwBytesRead; int nError = ERROR_SUCCESS; // Create the file path _tcscpy(szNamePtr, szLocalPath); szNamePtr += _tcslen(szLocalPath); *szNamePtr++ = _T('\\'); // Copy the plain file name CopyString(szNamePtr, szFileName, strlen(szFileName)); // Open the CASC file if(nError == ERROR_SUCCESS) { // Open a file if(!CascOpenFile(hStorage, szFileName, dwLocaleFlags, 0, &hFile)) { assert(GetLastError() != ERROR_SUCCESS); nError = GetLastError(); } } // Create the local file if(nError == ERROR_SUCCESS) { pStream = FileStream_CreateFile(szLocalFileName, 0); if(pStream == NULL) { // Try to create all directories and retry ForceCreatePath(szLocalFileName); pStream = FileStream_CreateFile(szLocalFileName, 0); if(pStream == NULL) nError = GetLastError(); } } // Read some data from the file if(nError == ERROR_SUCCESS) { for(;;) { // Read data from the file CascReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead); if(dwBytesRead == 0) break; // Write the local file FileStream_Write(pStream, NULL, Buffer, dwBytesRead); } } // Close handles if(pStream != NULL) FileStream_Close(pStream); if(hFile != NULL) CascCloseFile(hFile); return nError; }
int main(int argc, char ** argv) { Trinity::Banner::Show("VMAP data extractor", [](char const* text) { printf("%s\n", text); }, nullptr); bool success = true; const char *versionString = "V4.03 2015_05"; // Use command line arguments, when some if (!processArgv(argc, argv, versionString)) return 1; // some simple check if working dir is dirty else { std::string sdir = std::string(szWorkDirWmo) + "/dir"; std::string sdir_bin = std::string(szWorkDirWmo) + "/dir_bin"; struct stat status; if (!stat(sdir.c_str(), &status) || !stat(sdir_bin.c_str(), &status)) { printf("Your output directory seems to be polluted, please use an empty directory!\n"); printf("<press return to exit>"); char garbage[2]; return scanf("%c", garbage); } } printf("Extract %s. Beginning work ....\n\n", versionString); //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // Create the working directory if (mkdir(szWorkDirWmo #if defined(__linux__) || defined(__APPLE__) , 0711 #endif )) success = (errno == EEXIST); int FirstLocale = -1; for (int i = 0; i < TOTAL_LOCALES; ++i) { if (i == LOCALE_none) continue; if (!OpenCascStorage(i)) continue; FirstLocale = i; uint32 build = ReadBuild(i); if (!build) { CascCloseStorage(CascStorage); continue; } printf("Detected client build: %u\n\n", build); break; } if (FirstLocale == -1) { printf("FATAL ERROR: No locales defined, unable to continue.\n"); return 1; } if (!OpenCascStorage(FirstLocale)) { if (GetLastError() != ERROR_PATH_NOT_FOUND) printf("Unable to open storage!\n"); return 1; } // Extract models, listed in GameObjectDisplayInfo.dbc ExtractGameobjectModels(); ReadLiquidTypeTableDBC(); // extract data if (success) success = ExtractWmo(); //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //map.dbc if (success) { printf("Read Map.dbc file... "); HANDLE dbcFile; if (!CascOpenFile(CascStorage, "DBFilesClient\\Map.db2", CASC_LOCALE_NONE, 0, &dbcFile)) { printf("Fatal error: Cannot find Map.dbc in archive! %s\n", HumanReadableCASCError(GetLastError())); exit(1); } DB2FileLoader db2; if (!db2.Load(dbcFile, MapMeta::Instance())) { printf("Fatal error: Invalid Map.db2 file format! %s\n", HumanReadableCASCError(GetLastError())); exit(1); } map_ids.resize(db2.GetNumRows()); std::unordered_map<uint32, uint32> idToIndex; for (uint32 x = 0; x < db2.GetNumRows(); ++x) { if (MapMeta::Instance()->HasIndexFieldInData()) map_ids[x].id = db2.getRecord(x).getUInt(MapMeta::Instance()->GetIndexField(), 0); else map_ids[x].id = db2.getId(x); const char* map_name = db2.getRecord(x).getString(0, 0); size_t max_map_name_length = sizeof(map_ids[x].name); if (strlen(map_name) >= max_map_name_length) { printf("Fatal error: Map name too long!\n"); exit(1); } strncpy(map_ids[x].name, map_name, max_map_name_length); map_ids[x].name[max_map_name_length - 1] = '\0'; idToIndex[map_ids[x].id] = x; } for (uint32 x = 0; x < db2.GetNumRowCopies(); ++x) { uint32 from = db2.GetRowCopy(x).first; uint32 to = db2.GetRowCopy(x).second; auto itr = idToIndex.find(from); if (itr != idToIndex.end()) { map_id id; id.id = to; strcpy(id.name, map_ids[itr->second].name); map_ids.push_back(id); } } CascCloseFile(dbcFile); printf("Done! (" SZFMTD " maps loaded)\n", map_ids.size()); ParsMapFiles(); } CascCloseStorage(CascStorage); printf("\n"); if (!success) { printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n", versionString, preciseVectorData); getchar(); } printf("Extract %s. Work complete. No errors.\n", versionString); return 0; }