Clone of Akilla's ac2d @ https://github.com/deregtd/AC2D

cTurbineFile.cpp 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #include "stdafx.h"
  2. #include "cTurbineFile.h"
  3. cTurbineFile::cTurbineFile()
  4. {
  5. TCHAR szEXEPathname[_MAX_PATH];
  6. GetModuleFileName(NULL, szEXEPathname, _MAX_PATH);
  7. *(strrchr(szEXEPathname, '\\')+1) = 0;
  8. m_szACPath = szEXEPathname;
  9. m_hFile = 0;
  10. m_hMapping = 0;
  11. m_pData = 0;
  12. }
  13. cTurbineFile::~cTurbineFile()
  14. {
  15. CloseFile();
  16. }
  17. void cTurbineFile::LoadFile( std::string Filename )
  18. {
  19. m_szFilename = Filename;
  20. 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 );
  21. if(m_hFile == INVALID_HANDLE_VALUE )
  22. {
  23. MessageBox( NULL, "CreateFile failed", "AC2D", MB_OK | MB_ICONEXCLAMATION );
  24. return;
  25. }
  26. m_hMapping = CreateFileMapping(m_hFile, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL );
  27. if( m_hMapping == NULL )
  28. {
  29. MessageBox( NULL, "CreateFileMapping failed", "AC2D", MB_OK | MB_ICONEXCLAMATION );
  30. CloseHandle(m_hFile);
  31. return;
  32. //throw std::exception( "Could not create file mapping." );
  33. }
  34. m_pData = (BYTE *) MapViewOfFileEx( m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL );
  35. if( m_pData == NULL )
  36. {
  37. MessageBox( NULL, "MapViewOfFileEx failed", "AC2D", MB_OK | MB_ICONEXCLAMATION );
  38. CloseHandle(m_hMapping);
  39. CloseHandle(m_hFile);
  40. return;
  41. //throw std::exception( "Could not create file mapping." );
  42. }
  43. memcpy(&m_FileHeader, m_pData + FILEHEADERLOC, sizeof(TODDatFileHeader));
  44. bool bPreloaded = false;
  45. char prefile[128];
  46. FILETIME ftCreate, ftAccess, ftWrite;
  47. GetFileTime(m_hFile, &ftCreate, &ftAccess, &ftWrite);
  48. sprintf(prefile, "%s.pre", Filename.c_str());
  49. FILE *preload = fopen(prefile, "rb");
  50. if (preload)
  51. {
  52. DWORD dwTimeLow, dwTimeHi;
  53. fread(&dwTimeLow, 4, 1, preload);
  54. fread(&dwTimeHi, 4, 1, preload);
  55. if ((dwTimeLow == ftWrite.dwLowDateTime) && (dwTimeHi == ftWrite.dwHighDateTime))
  56. {
  57. bPreloaded = true;
  58. DWORD dwNum;
  59. fread(&dwNum, 4, 1, preload);
  60. DWORD *dwStuff = new DWORD[3*dwNum];
  61. fread(dwStuff, dwNum, 4*3, preload);
  62. for (DWORD i=0; i<dwNum; i++)
  63. // m_TFMap[dwStuff[3*i]] = new stTFMap(dwStuff[3*i+1], dwStuff[3*i+2]);
  64. m_mFileInfo[ dwStuff[3*i] ] = *((QWORD *) &dwStuff[3*i+1]);
  65. delete []dwStuff;
  66. }
  67. fclose(preload);
  68. }
  69. if (!bPreloaded)
  70. {
  71. //Load it up!
  72. std::unordered_set<DWORD> LoadSet;
  73. FindFiles( m_FileHeader.dwRootOffset, &LoadSet );
  74. //Try to store preload for next time...
  75. preload = fopen(prefile, "wb");
  76. if (preload)
  77. {
  78. fwrite(&ftWrite.dwLowDateTime, 4, 1, preload);
  79. fwrite(&ftWrite.dwHighDateTime, 4, 1, preload);
  80. DWORD dwNum = m_mFileInfo.size();
  81. // DWORD dwNum = (DWORD) m_TFMap.size();//m_mFileInfo.size();
  82. fwrite(&dwNum, 4, 1, preload);
  83. for (InfoMap::iterator i = m_mFileInfo.begin(); i != m_mFileInfo.end(); i++)
  84. {
  85. DWORD dwID = i->first;
  86. fwrite(&dwID, 4, 1, preload);
  87. fwrite(&i->second, 8, 1, preload);
  88. }
  89. /*for (TFMapType::iterator i = m_TFMap.begin(); i != m_TFMap.end(); i++)
  90. {
  91. fwrite(&i->first, 4, 1, preload);
  92. fwrite(&i->second->Position, 4, 1, preload);
  93. fwrite(&i->second->Length, 4, 1, preload);
  94. }*/
  95. fclose(preload);
  96. }
  97. }
  98. }
  99. void cTurbineFile::CloseFile()
  100. {
  101. if( m_pData )
  102. UnmapViewOfFile( m_pData );
  103. if( m_hMapping )
  104. CloseHandle( m_hMapping );
  105. if( m_hFile )
  106. CloseHandle( m_hFile );
  107. m_hFile = 0;
  108. m_hMapping = 0;
  109. m_pData = 0;
  110. //clean up file pool
  111. for( FileMap::iterator i = m_mPool.begin(); i != m_mPool.end(); ++i )
  112. // for (TFMapType::iterator i = m_TFMap.begin(); i != m_TFMap.end(); i++)
  113. delete i->second;
  114. // m_mPool.clear();
  115. // m_mFileInfo.clear();
  116. }
  117. void cTurbineFile::LoadSection(DWORD offset, DWORD length, void * PlaceIn)
  118. {
  119. DWORD dataoffset = 0;
  120. while ((offset > 0) && (offset < m_FileHeader.dwFileSize/* - m_FileHeader.dwBlockSize*/))
  121. {
  122. int lentocopy = m_FileHeader.dwBlockSize - 4;
  123. if (dataoffset + lentocopy > length)
  124. lentocopy = length - dataoffset;
  125. memcpy((BYTE *) PlaceIn + dataoffset, m_pData + offset + 4, lentocopy);
  126. dataoffset += lentocopy;
  127. offset = *((DWORD *) (m_pData + offset));
  128. }
  129. }
  130. void cTurbineFile::FindFiles( DWORD dwDirPos, std::unordered_set<DWORD> * sLoadSet )
  131. {
  132. // if (m_mLoadMap.find(dwDirPos) != m_mLoadMap.end())
  133. if (sLoadSet->find(dwDirPos) != sLoadSet->end())
  134. return;
  135. sLoadSet->insert(dwDirPos);
  136. // m_mLoadMap[dwDirPos] = true;
  137. TODDirectory TempDir;
  138. LoadSection(dwDirPos, sizeof(TODDirectory), &TempDir);
  139. for (int i=0; i<62; i++)
  140. {
  141. if ((TempDir.dwSubdirs[i]) && (TempDir.dwSubdirs[i] < m_FileHeader.dwFileSize) && (!(TempDir.dwSubdirs[i] & (m_FileHeader.dwBlockSize - 1))))
  142. /// if ((TempDir.dwSubdirs[i] != 0xCDCDCDCD) && (TempDir.dwSubdirs[i])/* && ((TempDir.dwSubdirs[i] % m_FileHeader.dwBlockSize) == 0)*/)
  143. FindFiles(TempDir.dwSubdirs[i], sLoadSet);
  144. else
  145. i = 62;
  146. }
  147. for (DWORD i=0; i<TempDir.dwEntryCount && i < 62; i++)
  148. {
  149. if (TempDir.feEntries[i].dwID == 0)
  150. break;
  151. // m_TFMap[ TempDir.feEntries[i].dwID ] = new stTFMap(TempDir.feEntries[i].dwFileOffset, TempDir.feEntries[i].dwFileSize);
  152. m_mFileInfo[ TempDir.feEntries[i].dwID ] = ((QWORD) TempDir.feEntries[i].dwFileOffset) | (((QWORD) TempDir.feEntries[i].dwFileSize) << 32);
  153. }
  154. }
  155. cPortalFile * cTurbineFile::OpenEntry(DWORD dwID)
  156. {
  157. //check if it's in the pool already
  158. if( m_mPool.find(dwID) != m_mPool.end() )
  159. return m_mPool[ dwID ];
  160. //check to make sure it's actually in our dat file
  161. if( m_mFileInfo.find(dwID) == m_mFileInfo.end() )
  162. return 0; //shit, it's not downloaded...
  163. //Pull its info
  164. /* TFMapType::iterator it = m_TFMap.find(dwID);
  165. //If it's not even in there, we don't even have it at all...
  166. if (it == m_TFMap.end())
  167. return 0;
  168. //We have it, now to see if it's loaded
  169. if (it->second->Data != NULL)
  170. return it->second->Data;
  171. */
  172. //form a new cportalfile and load it from the pool
  173. cPortalFile * pfNew = new cPortalFile();
  174. pfNew->id = dwID;
  175. QWORD tp = m_mFileInfo[ dwID ];
  176. pfNew->pos = (DWORD) tp;
  177. pfNew->length = (DWORD) (tp >> 32);
  178. // pfNew->pos = it->second->Position;
  179. // pfNew->length = it->second->Length;
  180. pfNew->data = new BYTE[pfNew->length];
  181. LoadSection(pfNew->pos, pfNew->length, pfNew->data);
  182. //Add to the pool now
  183. m_mPool[ dwID ] = pfNew;
  184. // it->second->Data = pfNew;
  185. return pfNew;
  186. }
  187. void cTurbineFile::InsertEntry(cPortalFile * pfNew)
  188. {
  189. //theoretically, actually insert this file back into the file at some point... until then, just cache it for now :)
  190. m_mPool[pfNew->id] = pfNew;
  191. // m_TFMap[pfNew->id] = new stTFMap(0, 0, pfNew);
  192. }
  193. void cTurbineFile::CalcPoolSize()
  194. {
  195. m_dwPoolSize = 0;
  196. for (FileMap::iterator i = m_mPool.begin(); i != m_mPool.end(); i++)
  197. m_dwPoolSize += (*i).second->length;
  198. /* for (TFMapType::iterator i = m_TFMap.begin(); i != m_TFMap.end(); i++)
  199. {
  200. if (i->second->Data)
  201. m_dwPoolSize += i->second->Data->length;
  202. }*/
  203. }