#include "stdafx.h" #include "cTurbineFile.h" cTurbineFile::cTurbineFile() { TCHAR szEXEPathname[_MAX_PATH]; GetModuleFileName(NULL, szEXEPathname, _MAX_PATH); *(strrchr(szEXEPathname, '\\')+1) = 0; m_szACPath = szEXEPathname; m_hFile = 0; m_hMapping = 0; m_pData = 0; } cTurbineFile::~cTurbineFile() { CloseFile(); } void cTurbineFile::LoadFile( std::string Filename ) { m_szFilename = Filename; m_hFile = CreateFile( (m_szACPath + Filename).c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL ); if(m_hFile == INVALID_HANDLE_VALUE ) { MessageBox( NULL, "CreateFile failed", "AC2D", MB_OK | MB_ICONEXCLAMATION ); return; } m_hMapping = CreateFileMapping(m_hFile, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL ); if( m_hMapping == NULL ) { MessageBox( NULL, "CreateFileMapping failed", "AC2D", MB_OK | MB_ICONEXCLAMATION ); CloseHandle(m_hFile); return; //throw std::exception( "Could not create file mapping." ); } m_pData = (BYTE *) MapViewOfFileEx( m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL ); if( m_pData == NULL ) { MessageBox( NULL, "MapViewOfFileEx failed", "AC2D", MB_OK | MB_ICONEXCLAMATION ); CloseHandle(m_hMapping); CloseHandle(m_hFile); return; //throw std::exception( "Could not create file mapping." ); } memcpy(&m_FileHeader, m_pData + FILEHEADERLOC, sizeof(TODDatFileHeader)); bool bPreloaded = false; char prefile[128]; FILETIME ftCreate, ftAccess, ftWrite; GetFileTime(m_hFile, &ftCreate, &ftAccess, &ftWrite); sprintf(prefile, "%s.pre", Filename.c_str()); FILE *preload = fopen(prefile, "rb"); if (preload) { DWORD dwTimeLow, dwTimeHi; fread(&dwTimeLow, 4, 1, preload); fread(&dwTimeHi, 4, 1, preload); if ((dwTimeLow == ftWrite.dwLowDateTime) && (dwTimeHi == ftWrite.dwHighDateTime)) { bPreloaded = true; DWORD dwNum; fread(&dwNum, 4, 1, preload); DWORD *dwStuff = new DWORD[3*dwNum]; fread(dwStuff, dwNum, 4*3, preload); for (DWORD i=0; i LoadSet; FindFiles( m_FileHeader.dwRootOffset, &LoadSet ); //Try to store preload for next time... preload = fopen(prefile, "wb"); if (preload) { fwrite(&ftWrite.dwLowDateTime, 4, 1, preload); fwrite(&ftWrite.dwHighDateTime, 4, 1, preload); DWORD dwNum = m_mFileInfo.size(); // DWORD dwNum = (DWORD) m_TFMap.size();//m_mFileInfo.size(); fwrite(&dwNum, 4, 1, preload); for (InfoMap::iterator i = m_mFileInfo.begin(); i != m_mFileInfo.end(); i++) { DWORD dwID = i->first; fwrite(&dwID, 4, 1, preload); fwrite(&i->second, 8, 1, preload); } /*for (TFMapType::iterator i = m_TFMap.begin(); i != m_TFMap.end(); i++) { fwrite(&i->first, 4, 1, preload); fwrite(&i->second->Position, 4, 1, preload); fwrite(&i->second->Length, 4, 1, preload); }*/ fclose(preload); } } } void cTurbineFile::CloseFile() { if( m_pData ) UnmapViewOfFile( m_pData ); if( m_hMapping ) CloseHandle( m_hMapping ); if( m_hFile ) CloseHandle( m_hFile ); m_hFile = 0; m_hMapping = 0; m_pData = 0; //clean up file pool for( FileMap::iterator i = m_mPool.begin(); i != m_mPool.end(); ++i ) // for (TFMapType::iterator i = m_TFMap.begin(); i != m_TFMap.end(); i++) delete i->second; // m_mPool.clear(); // m_mFileInfo.clear(); } void cTurbineFile::LoadSection(DWORD offset, DWORD length, void * PlaceIn) { DWORD dataoffset = 0; while ((offset > 0) && (offset < m_FileHeader.dwFileSize/* - m_FileHeader.dwBlockSize*/)) { int lentocopy = m_FileHeader.dwBlockSize - 4; if (dataoffset + lentocopy > length) lentocopy = length - dataoffset; memcpy((BYTE *) PlaceIn + dataoffset, m_pData + offset + 4, lentocopy); dataoffset += lentocopy; offset = *((DWORD *) (m_pData + offset)); } } void cTurbineFile::FindFiles( DWORD dwDirPos, std::unordered_set * sLoadSet ) { // if (m_mLoadMap.find(dwDirPos) != m_mLoadMap.end()) if (sLoadSet->find(dwDirPos) != sLoadSet->end()) return; sLoadSet->insert(dwDirPos); // m_mLoadMap[dwDirPos] = true; TODDirectory TempDir; LoadSection(dwDirPos, sizeof(TODDirectory), &TempDir); for (int i=0; i<62; i++) { if ((TempDir.dwSubdirs[i]) && (TempDir.dwSubdirs[i] < m_FileHeader.dwFileSize) && (!(TempDir.dwSubdirs[i] & (m_FileHeader.dwBlockSize - 1)))) /// if ((TempDir.dwSubdirs[i] != 0xCDCDCDCD) && (TempDir.dwSubdirs[i])/* && ((TempDir.dwSubdirs[i] % m_FileHeader.dwBlockSize) == 0)*/) FindFiles(TempDir.dwSubdirs[i], sLoadSet); else i = 62; } for (DWORD i=0; isecond->Data != NULL) return it->second->Data; */ //form a new cportalfile and load it from the pool cPortalFile * pfNew = new cPortalFile(); pfNew->id = dwID; QWORD tp = m_mFileInfo[ dwID ]; pfNew->pos = (DWORD) tp; pfNew->length = (DWORD) (tp >> 32); // pfNew->pos = it->second->Position; // pfNew->length = it->second->Length; pfNew->data = new BYTE[pfNew->length]; LoadSection(pfNew->pos, pfNew->length, pfNew->data); //Add to the pool now m_mPool[ dwID ] = pfNew; // it->second->Data = pfNew; return pfNew; } void cTurbineFile::InsertEntry(cPortalFile * pfNew) { //theoretically, actually insert this file back into the file at some point... until then, just cache it for now :) m_mPool[pfNew->id] = pfNew; // m_TFMap[pfNew->id] = new stTFMap(0, 0, pfNew); } void cTurbineFile::CalcPoolSize() { m_dwPoolSize = 0; for (FileMap::iterator i = m_mPool.begin(); i != m_mPool.end(); i++) m_dwPoolSize += (*i).second->length; /* for (TFMapType::iterator i = m_TFMap.begin(); i != m_TFMap.end(); i++) { if (i->second->Data) m_dwPoolSize += i->second->Data->length; }*/ }