#include "stdafx.h" #include #include #include #include "EtFileSystem.h" #include "SundriesFunc.h" #include "StringUtil.h" #ifdef _x86 #include //lz4!! #endif #include "Crypt.h" /* #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__) #endif */ bool g_bUseCompress= true; using namespace std; typedef list CValueFileHandleList; typedef list::iterator CValueFileHandleList_It; //------------------------------------------------------------------------------------- const DWORD ET_SEED_CNT = 50; const DWORD ET_ENCRYPT_SEED[ET_SEED_CNT] = { 0x67184865, 0x722c3d4a, 0x6d165f69, 0xa126415a, 0x15122e0b, 0xf39f397e, 0x49443001, 0x54154d4d, 0x4d072d39, 0x26426664, 0x767a5d70, 0x1e3b1245, 0x6b631a6e, 0x324e7f7f, 0xd36b2622, 0x57560b30, 0x22237501, 0x5c6b584b, 0x3b5f1a3e, 0x7d5f793a, 0x4d5e314c, 0x1c132e49, 0x7e426636, 0x54152c60, 0x4059083e, 0x73127912, 0x49362658, 0x7013577b, 0x16184a69, 0x40133c68, 0x4823335d, 0x3c5c6057, 0x946a2f0f, 0x5d365442, 0x2c467579, 0x286c2f3c, 0x267d223a, 0x6119485e, 0x7140326b, 0x36497f03, 0x506b1844, 0xcf6b1954, 0x78285f0e, 0x5d112b24, 0x5f4c5a6a, 0x97181220, 0x2e1a6d67, 0x3a0e0146, 0x69455760, 0x25591937, }; //------------------------------------------------------------------------------------- CEtFileSystemLog g_DummyLog; CEtFileHandle::CEtFileHandle() { memset( &m_FileInfo, 0, sizeof( SPackingFileInfo ) ); m_pData = NULL; m_dwCurPos = 0; } CEtFileHandle::~CEtFileHandle() { SAFE_DELETEA( m_pData ); } DWORD CEtFileHandle::Read(void* pBuff, DWORD nSize) { if(!m_pData) return 0; if(m_FileInfo.dwOriginalSize <= m_dwCurPos) return 0; if(m_FileInfo.dwOriginalSize < m_dwCurPos+nSize) nSize = m_FileInfo.dwOriginalSize-m_dwCurPos; memcpy(pBuff,m_pData+m_dwCurPos,nSize); m_dwCurPos += nSize; return nSize; } int CEtFileHandle::Seek(int lOffset, int iOrigin) { if(!m_pData) return -1; DWORD lPos; switch(iOrigin) { case SEEK_SET: lPos = lOffset; break; case SEEK_CUR: lPos = lOffset+m_dwCurPos; break; case SEEK_END: lPos = m_FileInfo.dwOriginalSize+lOffset; break; default: return -1; } if(lPos > m_FileInfo.dwOriginalSize) return -1; m_dwCurPos = lPos; return m_dwCurPos; } bool CEtFileHandle::ExportFile() { HANDLE hFile = INVALID_HANDLE_VALUE; char szName[ _MAX_PATH ]; _GetFullFileName( szName, _countof(szName), m_FileInfo.szFileName ); DWORD dwAttr = ::GetFileAttributes( _T( szName ) ); if( dwAttr & FILE_ATTRIBUTE_READONLY ) { dwAttr &= ~FILE_ATTRIBUTE_READONLY; ::SetFileAttributes( _T( szName ), dwAttr ); } hFile = CreateFile(szName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL ); if( hFile == INVALID_HANDLE_VALUE ) return false; DWORD nWriteSize = 0; if( WriteFile(hFile, m_pData, m_FileInfo.dwOriginalSize, &nWriteSize, NULL) == false ) { CloseHandle(hFile); return false; } CloseHandle(hFile); return true; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // CEtPackingFile ////////////////////////////////////////////////////////////////////////////////////////////////////// CEtPackingFile::CEtPackingFile() { m_hFile = INVALID_HANDLE_VALUE; ZeroMemory(m_strCurDir, sizeof(m_strCurDir)); memset( &m_PackingFileHeader, 0, sizeof( SPackingFileHeader ) ); m_PackingFileHeader.dwFileInfoOffset = PACKING_HEADER_RESERVED + sizeof( SPackingFileHeader ); m_bIsReadOnly = true; m_pLog = &g_DummyLog; CloseFileSystem(); } CEtPackingFile::~CEtPackingFile() { CloseFileSystem(); } LONGLONG CEtPackingFile::_Seek(HANDLE hFile, LONGLONG nDistance, DWORD SeekType) { if( hFile == INVALID_HANDLE_VALUE ) return -1; LARGE_INTEGER li; li.QuadPart = nDistance; li.LowPart = SetFilePointer (hFile, li.LowPart, &li.HighPart, SeekType); if(li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) { li.QuadPart = -1; } return li.QuadPart; } bool CEtPackingFile::_Read(HANDLE hFile, IN void* pBuffer, DWORD ToReadSize) { if( hFile == INVALID_HANDLE_VALUE ) return false; DWORD nReadSize = 0; if( ReadFile(hFile, pBuffer, ToReadSize, &nReadSize, NULL ) == false ) return false; if( ToReadSize > 0 && nReadSize < 1 ) return false; return true; } bool CEtPackingFile::_Write(HANDLE hFile, IN void* pBuffer, DWORD ToWriteSize) { if( hFile == INVALID_HANDLE_VALUE ) return false; DWORD nWriteSize = 0; if( WriteFile(hFile, pBuffer, ToWriteSize, &nWriteSize, NULL ) == false ) return false; return true; } void CEtPackingFile::SetCurDir(const char* pTok) { if( strcmp( pTok, "." ) == 0 ) return; if( strcmp( pTok, ".." ) == 0 ) { if(strlen(m_strCurDir) == 1 && m_strCurDir[0] == '\\') return; char strCurDir[_MAX_PATH] = { 0, }; strcpy_s(strCurDir,m_strCurDir); int iLen = (int)strlen(strCurDir); if(strCurDir[iLen-1] == '\\' ) strCurDir[iLen-1] = '\0'; for(int i=0;i<_MAX_PATH;i++) { char* cp = strCurDir+(_MAX_PATH-1-i); if(*cp == '\\') break; *cp = '\0'; } strcpy(m_strCurDir,strCurDir); return; } strcat(m_strCurDir,pTok); strcat(m_strCurDir,"\\"); } void CEtPackingFile::GetSafeName(char* strDst,const char* strName) { ZeroMemory(strDst, _MAX_FNAME); int iLen = (int)strlen(strName); if(iLen >= _MAX_FNAME) iLen = _MAX_FNAME-1; strncpy(strDst,strName,iLen); } DWORD CEtPackingFile::CalcChecksum( int nFileIndex ) { char *pBuffer; int i, nSize; DWORD dwChecksum = 0, *pdwBuffer; // nSize¸¦ 4ÀÇ ¹è¼ö·Î ¹Ù²Û´Ù.. nSize = m_vecPackingFileInfo[ nFileIndex ].dwCompressSize / 4; if( m_vecPackingFileInfo[ nFileIndex ].dwCompressSize % 4 ) { nSize++; } nSize *= 4; pBuffer = new char[ nSize ]; memset( pBuffer, 0, nSize ); pdwBuffer = ( DWORD * )pBuffer; for( i = 0; i < nSize / 4; i++ ) { dwChecksum = pdwBuffer[ i ] ^ dwChecksum; } delete [] pBuffer; return dwChecksum; } void CEtPackingFile::GenerateChecksum() { int i; int nSize = ( int )m_vecPackingFileInfo.size(); for( i = 0; i < nSize; i++ ) { if( m_vecPackingFileInfo[ i ].dwCompressSize == 0 ) { continue; } m_vecPackingFileInfo[ i ].dwChecksum = CalcChecksum( i ); } } void CEtPackingFile::CloseFileSystem() { m_strCurDir[ 0 ] = '\0'; if( m_hFile != INVALID_HANDLE_VALUE ) { if( ( !m_bIsReadOnly ) && ( m_PackingFileHeader.nFileCount != m_vecPackingFileInfo.size() ) ) { if( m_PackingFileHeader.nVersion <= PACKING_FILE_NOCHECKSUM_VERSION ) { GenerateChecksum(); m_PackingFileHeader.bRequireHeaderWrite = true; m_PackingFileHeader.nVersion = PACKING_FILE_VERSION; } m_PackingFileHeader.nFileCount = ( int )m_vecPackingFileInfo.size(); _Seek( m_hFile, 0, SEEK_SET ); _Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) ); } if( ( !m_bIsReadOnly ) && ( m_PackingFileHeader.bRequireHeaderWrite ) ) { _Seek( m_hFile, m_PackingFileHeader.dwFileInfoOffset, SEEK_SET ); _Write( m_hFile, &m_vecPackingFileInfo[ 0 ], ( DWORD )m_vecPackingFileInfo.size() * sizeof( SPackingFileInfo ) ); m_PackingFileHeader.bRequireHeaderWrite = false; _Seek( m_hFile, 0, SEEK_SET ); _Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) ); } } m_vecPackingFileInfo.clear(); m_mapPackingFileIndex.clear(); if( m_hFile != INVALID_HANDLE_VALUE ) { CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; } } void CEtPackingFile::_Encode(IN BYTE* pBuffer, int nBufSize, DWORD nCode) { return; for ( int i = 0 ; i < nBufSize ; i+=8 ) { pBuffer[i] ^= nCode; } } void CEtPackingFile::_Decode(IN BYTE* pBuffer, int nBufSize, DWORD nCode) { return; for ( int i = 0 ; i < nBufSize ; i+=8 ) { pBuffer[i] ^= nCode; } } bool CEtPackingFile::OpenFileSystem(const char* strPath, bool bReadOnly /* = false */ ) { CloseFileSystem(); m_bIsReadOnly = bReadOnly; if( bReadOnly ) { m_hFile = CreateFile(strPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, // Áߺ¹ Read °¡´ÉÇÏ°Ô ¼öÁ¤. FILE_ATTRIBUTE_NORMAL,NULL); } else { m_hFile = CreateFile(strPath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); } DWORD nError; if( m_hFile == INVALID_HANDLE_VALUE ) { nError = GetLastError(); return false; } // ÆÄÀÏ ½Ã½ºÅÛ Çì´õ¸¦ ·ÎµåÇÑ´Ù. _Read( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) ); /*if( ( m_PackingFileHeader.nVersion < PACKING_FILE_NOCHECKSUM_VERSION ) || ( m_PackingFileHeader.nVersion > PACKING_FILE_VERSION ) ) { return false; }*/ if (m_PackingFileHeader.nVersion < PACKING_FILE_VERSION) return false; // ±¸¹öÀü ÆÄÀϽýºÅÛ¿¡´Â ÆÄÀÏÀÎÆ÷ ¿É¼ÂÀÌ ¾Èµé¾î À־ ÆÄÀϳ¡¿¡¼­ SeekÀ¸·Î ã¾Æ¾ß ÇÑ´Ù. if( m_PackingFileHeader.nVersion > PACKING_FILE_NOCHECKSUM_VERSION ) { // bRequireHeaderWrite °ªÀÌ ¼ÂÆÃ µÅ ÀÖÀ¸¸é ÆÐÄ¡¶§ Á¦´ë·Î Á¾·á ¾ÈµÆ°ÍÀÓ.. À߸øµÈ ÆÄÀÏ ½Ã½ºÅÛÀ¸·Î ÀÎÁ¤.. if( m_PackingFileHeader.bRequireHeaderWrite == true ) { //rlkt_pak //MessageBoxA(NULL, FormatA(" Open File System nVersion >PACKING_FILE_NOCHECKSUM_VERSION").c_str(), "AddPackingFile", MB_OK); return false; } _Seek( m_hFile, m_PackingFileHeader.dwFileInfoOffset, SEEK_SET ); } else { m_PackingFileHeader.dwFileInfoOffset = ( DWORD )_Seek( m_hFile, -( LONGLONG )( m_PackingFileHeader.nFileCount * sizeof( SPackingFileInfo ) ), SEEK_END ); } if( m_PackingFileHeader.nFileCount ) { m_vecPackingFileInfo.resize( m_PackingFileHeader.nFileCount ); _Read( m_hFile, &m_vecPackingFileInfo[ 0 ], sizeof( SPackingFileInfo ) * m_PackingFileHeader.nFileCount ); int i; for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ ) { if( m_vecPackingFileInfo[ i ].dwCompressSize > m_vecPackingFileInfo[ i ].dwAllocSize ) { //rlkt_pak TEST ONLY!! //m_vecPackingFileInfo[i].dwAllocSize = m_vecPackingFileInfo[i].dwCompressSize; //MessageBoxA(NULL, FormatA("File ID: %d\nFile offset : %X read size: %X Size of Array : %d\n file count: %d\n CompressSize > DWAllocSize (%d - %d)\n\nFile:%s\nOrig size: %d\noffset : %X",i, m_PackingFileHeader.dwFileInfoOffset, sizeof(SPackingFileInfo)* m_PackingFileHeader.nFileCount, m_vecPackingFileInfo.size() , m_PackingFileHeader.nFileCount, m_vecPackingFileInfo[i].dwCompressSize, m_vecPackingFileInfo[i].dwAllocSize, m_vecPackingFileInfo[i].szFileName, m_vecPackingFileInfo[i].dwOriginalSize, m_vecPackingFileInfo[i].dwOffset).c_str(), "AddPackingFile", MB_OK); return false; } } } GeneratePackingMap(); // ÇöÀç µð·ºÅ丮¸¦ ÃÖ»óÀ§ µð·ºÅ丮·Î ¹Ù²Û´Ù. ChangeDir("\\"); m_strPackingFileName = strPath; return true; } bool CEtPackingFile::NewFileSystem(const char* strPath) { CloseFileSystem(); m_hFile = CreateFile(strPath, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); DWORD nError; if( m_hFile == INVALID_HANDLE_VALUE ) { nError = GetLastError(); return false; } // Çì´õ Á¤º¸ ¸¸µé±â memset( &m_PackingFileHeader, 0, sizeof( SPackingFileHeader ) ); strcpy_s( m_PackingFileHeader.szHeaderString, 256, PACKING_FILE_STRING ); m_PackingFileHeader.nVersion = PACKING_FILE_VERSION; m_PackingFileHeader.nFileCount = 0; m_PackingFileHeader.dwFileInfoOffset = PACKING_HEADER_RESERVED + sizeof( SPackingFileHeader ); // Çì´õ ±â·Ï if( _Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) ) == false ) { return false; } char cReserved[ PACKING_HEADER_RESERVED ]; memset( cReserved, 0, PACKING_HEADER_RESERVED ); _Write( m_hFile, cReserved, PACKING_HEADER_RESERVED ); m_bIsReadOnly = false; return true; } bool CEtPackingFile::OptimizeFileSystem(const char* strPath) { if( m_hFile == INVALID_HANDLE_VALUE) return false; CEtPackingFile FileSystem; if( !FileSystem.NewFileSystem(strPath) ) return false; int i; int nFileCount = GetFileCount(); for( i = 0; i < nFileCount; i++ ) { SPackingFileInfo *pPackingFileInfo = GetFileInfo( i ); if( pPackingFileInfo == NULL ) { continue; } CEtFileHandle *pFileHandle = OpenFile( pPackingFileInfo->szFileName ); if( pFileHandle == NULL ) { continue; } AddFile( pPackingFileInfo->szFileName, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwCompressSize ); CloseFile( pFileHandle ); } return true; } DWORD CEtPackingFile::GetFileSystemSize() { LARGE_INTEGER liSeekCur, liSeekEnd; liSeekCur.QuadPart = _Seek( m_hFile, 0, SEEK_CUR ); liSeekEnd.QuadPart = _Seek( m_hFile, 0, SEEK_END ); _Seek( m_hFile, liSeekCur.QuadPart, SEEK_SET ); return liSeekEnd.LowPart; } void CEtPackingFile::SetRootPath( const char *szPath ) { m_szRootPath = szPath; ToLowerA( m_szRootPath ); } CEtFileHandle *CEtPackingFile::OpenFile( const char *strPath ) { if( m_hFile == INVALID_HANDLE_VALUE) return NULL; int nFindIndex = FindFile( strPath ); if( nFindIndex == -1 ) { return NULL; } SPackingFileInfo *pFileInfo = GetFileInfo( nFindIndex ); if( pFileInfo == NULL ) { return NULL; } _Seek( m_hFile, pFileInfo->dwOffset, SEEK_SET ); char *pCompressBuffer = new char[ pFileInfo->dwCompressSize ]; _Read( m_hFile, pCompressBuffer, pFileInfo->dwCompressSize ); DWORD dwSeed = ET_ENCRYPT_SEED[ pFileInfo->dwSeedValue ]; _Decode( ( BYTE * )pCompressBuffer, pFileInfo->dwCompressSize, dwSeed ); DWORD dwOriginalSize = pFileInfo->dwOriginalSize; char *pUncompressBuffer = new char[ dwOriginalSize ]; if( g_bUseCompress ) { //rlkt_CRYPT if (pFileInfo->dwCrypted) { Crypt::GetInstance().Decrypt((BYTE*)pCompressBuffer, pFileInfo->dwCompressSize); } //rlkt_pak 2016 added custom !!! DWORD dwOrigin = dwOriginalSize; /*int result = LZ4_decompress_fast(pCompressBuffer, pUncompressBuffer, dwOriginalSize); //MessageBoxA(NULL, FormatA("Decompress %s\ndwOriginalSize %d\ndwCompressSize %d\nResult %d",pFileInfo->szFileName,dwOriginalSize,pFileInfo->dwCompressSize,result).c_str(), "OK!", MB_OK); if (result < 0) { delete[] pCompressBuffer; delete[] pUncompressBuffer; return NULL; }*/ if( uncompress( ( BYTE * )pUncompressBuffer, ( uLongf * )&dwOriginalSize, ( BYTE * )pCompressBuffer, pFileInfo->dwCompressSize ) != Z_OK ) { delete [] pCompressBuffer; delete [] pUncompressBuffer; return NULL; } ASSERT( dwOrigin == dwOriginalSize ); } else { CopyMemory( pUncompressBuffer, pCompressBuffer, pFileInfo->dwCompressSize ); } delete [] pCompressBuffer; CEtFileHandle *pFileHandle = new CEtFileHandle; pFileHandle->m_FileInfo = *pFileInfo; pFileHandle->m_pData = pUncompressBuffer; pFileHandle->m_dwCurPos = 0; return pFileHandle; } CEtFileHandle *CEtPackingFile::OpenOnly( const char *strPath ) { if( m_hFile == INVALID_HANDLE_VALUE) return NULL; int nFindIndex = FindFile( strPath ); if( nFindIndex == -1 ) { return NULL; } SPackingFileInfo *pFileInfo = GetFileInfo( nFindIndex ); if( pFileInfo == NULL ) { return NULL; } _Seek( m_hFile, pFileInfo->dwOffset, SEEK_SET ); char *pCompressBuffer = new char[ pFileInfo->dwCompressSize ]; _Read( m_hFile, pCompressBuffer, pFileInfo->dwCompressSize ); CEtFileHandle *pFileHandle = new CEtFileHandle; pFileHandle->m_FileInfo = *pFileInfo; pFileHandle->m_pData = pCompressBuffer; pFileHandle->m_dwCurPos = 0; return pFileHandle; } void CEtPackingFile::_Tokenize( const std::string& str, std::vector& tokens, const std::string& delimiters /* = " " */ ) { // ¸Ç ù ±ÛÀÚ°¡ ±¸ºÐÀÚÀÎ °æ¿ì ¹«½Ã std::string::size_type lastPos = str.find_first_not_of( delimiters, 0 ); // ±¸ºÐÀÚ°¡ ¾Æ´Ñ ù ±ÛÀÚ¸¦ ã´Â´Ù std::string::size_type pos = str.find_first_of( delimiters, lastPos ); while( std::string::npos != pos || std::string::npos != lastPos ) { // tokenÀ» ã¾ÒÀ¸´Ï vector¿¡ Ãß°¡ÇÑ´Ù tokens.push_back( str.substr( lastPos, pos - lastPos ) ); // ±¸ºÐÀÚ¸¦ ¶Ù¾î³Ñ´Â´Ù. "not_of"¿¡ ÁÖÀÇÇ϶ó lastPos = str.find_first_not_of( delimiters, pos ); // ´ÙÀ½ ±¸ºÐÀÚ°¡ ¾Æ´Ñ ±ÛÀÚ¸¦ ã´Â´Ù pos = str.find_first_of( delimiters, lastPos ); } } // str ¹®ÀÚ¿­ Áß¿¡¼­ szOld °¡ ÀÖÀ¸¸é ÀüºÎ szNew ·Î º¯°æÇÑ´Ù. void CEtPackingFile::_AllReplace( std::string& str, std::string& szOld, std::string& szNew ) { while (true) { std::string::size_type npos = str.find(szOld); if( npos < str.size() ) { str.replace(npos, szOld.size(), szNew); } else break; } } int CEtPackingFile::FindFile( const char *pFileName ) { char szName[ _MAX_PATH ]; _GetFullFileName( szName, _countof(szName), pFileName ); _strlwr( szName ); TrimString( szName ); INT64 ulHashCode = GetHashCode64( szName ); std::map< INT64, int >::iterator it = m_mapPackingFileIndex.find( ulHashCode ); while( it != m_mapPackingFileIndex.end() ) { char szFindName[ _MAX_PATH ]; DWORD dwIndex = it->second; if( m_vecPackingFileInfo[ dwIndex ].dwCompressSize != 0 ) { _GetFullFileName( szFindName, _countof(szFindName), m_vecPackingFileInfo[ dwIndex ].szFileName ); if( _stricmp( szName, szFindName ) == 0 ) { char szPath[ _MAX_PATH ]; _GetPath( szPath, _countof(szPath), pFileName ); _strlwr( szPath ); TrimString( szPath ); if( szPath[ 0 ] == 0 ) { return dwIndex; } else { char szFindPath[ _MAX_PATH ]; _GetPath( szFindPath, _countof(szFindPath), m_vecPackingFileInfo[ dwIndex ].szFileName ); if( _stricmp( szPath, szFindPath ) == 0 ) { return dwIndex; } } } } ulHashCode++; it = m_mapPackingFileIndex.find( ulHashCode ); } return -1; } void CEtPackingFile::AddPackingMap( int nFileInfoIndex ) { if( ( nFileInfoIndex < 0 ) || ( nFileInfoIndex >= ( int )m_vecPackingFileInfo.size() ) ) { return; } char szName[ _MAX_PATH ], szPath[ _MAX_PATH ]; _GetFullFileName( szName, _countof(szName), m_vecPackingFileInfo[ nFileInfoIndex ].szFileName ); _strlwr( szName ); TrimString( szName ); _GetPath( szPath, _countof(szPath), m_vecPackingFileInfo[ nFileInfoIndex ].szFileName ); INT64 ulHashCode = GetHashCode64( szName ); std::map< INT64, int >::iterator it = m_mapPackingFileIndex.find( ulHashCode ); while( it != m_mapPackingFileIndex.end() ) { ulHashCode++; it = m_mapPackingFileIndex.find( ulHashCode ); } m_mapPackingFileIndex.insert( std::make_pair( ulHashCode, nFileInfoIndex ) ); } void CEtPackingFile::RemovePackingMap( int nFileInfoIndex ) { if( ( nFileInfoIndex < 0 ) || ( nFileInfoIndex >= ( int )m_vecPackingFileInfo.size() ) ) { return; } char szName[ _MAX_PATH ]; _GetFullFileName( szName, _countof(szName), m_vecPackingFileInfo[ nFileInfoIndex ].szFileName ); _strlwr( szName ); TrimString( szName ); INT64 ulHashCode = GetHashCode64( szName ); std::map< INT64, int >::iterator it = m_mapPackingFileIndex.find( ulHashCode ); while( it != m_mapPackingFileIndex.end() ) { if( it->second == nFileInfoIndex ) { m_mapPackingFileIndex.erase( it ); break; } ulHashCode++; it = m_mapPackingFileIndex.find( ulHashCode ); } } void CEtPackingFile::GeneratePackingMap() { int i; m_mapPackingFileIndex.clear(); for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ ) { AddPackingMap( i ); } } int CEtPackingFile::FindSuitableEmptySpace( DWORD dwSize ) { int i, nMinAllocIndex = -1; DWORD dwMinAllocSize = ULONG_MAX; for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ ) { if( m_vecPackingFileInfo[ i ].dwCompressSize != 0 ) { continue; } if( m_vecPackingFileInfo[ i ].dwAllocSize < dwSize ) { continue; } if( m_vecPackingFileInfo[ i ].dwAllocSize == dwSize ) { return i; } if( m_vecPackingFileInfo[ i ].dwAllocSize * 0.8f > dwSize ) { continue; } if( m_vecPackingFileInfo[ i ].dwAllocSize < dwMinAllocSize ) { dwMinAllocSize = m_vecPackingFileInfo[ i ].dwAllocSize; nMinAllocIndex = i; } } return nMinAllocIndex; } bool CEtPackingFile::AddFile(const char* strPath) { if( m_hFile == INVALID_HANDLE_VALUE) return false; // Ãß°¡ÇÒ ½ÇÁ¦ ÆÄÀÏ ·Îµå HANDLE hFile = INVALID_HANDLE_VALUE; hFile = CreateFile( strPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL ); if( hFile == INVALID_HANDLE_VALUE ) return false; // ÆÄÀÏ Å©±â¸¦ ¾Ë¾Æ³»¼­. DWORD dwFileSize = GetFileSize(hFile, NULL); if( dwFileSize == INVALID_FILE_SIZE ) { CloseHandle(hFile); return true; } _Seek(hFile, 0, FILE_BEGIN); char *pData = new char[dwFileSize]; _Read(hFile, pData, dwFileSize); CloseHandle(hFile); char strName[_MAX_FNAME] = { 0, }; char szFullName[ _MAX_PATH ]; GetNameOnly(strName,strPath); strcpy_s( szFullName, _MAX_PATH, m_strCurDir ); strcat_s( szFullName, _MAX_PATH, strName ); if(!AddFile(szFullName,pData,dwFileSize)) { delete[] pData; return false; } delete[] pData; return true; } bool CEtPackingFile::AddFile(const char* strName, char *pData, DWORD nSize) { if( m_hFile == INVALID_HANDLE_VALUE) return false; if(nSize <= 0) return true; DWORD lDstSize = nSize + 12 + max( 1, ( nSize + 12 ) / 1000 ); char *pDstData = new char[lDstSize]; if( g_bUseCompress ) { // ¾ÐÃàÇÑ´Ù. if(compress2( ( BYTE * )pDstData, (uLongf*)&lDstSize, ( BYTE * )pData, nSize, Z_BEST_SPEED) != Z_OK) { delete[] pDstData; return false; } } else { CopyMemory(pDstData, pData, nSize); lDstSize = nSize; } DWORD nSeedKey = 0; CopyMemory(&nSeedKey, pDstData, sizeof(DWORD)); // Àû´çÇÑ ½Ãµå À妽º¸¦ Çϳª °ñ¶ó¼­.. DWORD nSeedCnt = nSeedKey%ET_SEED_CNT; DWORD nSeed = ET_ENCRYPT_SEED[nSeedCnt]; // Àû´çÈ÷.. XOR ·Î º¯°æÇÏÀÚ -_- _Encode( ( BYTE * )pDstData, lDstSize, nSeed ); char szName[ _MAX_PATH ]; strcpy_s( szName, _MAX_PATH, strName ); _strlwr( szName ); TrimString( szName ); int nFindFileIndex = FindFile( szName ); if( nFindFileIndex != -1 ) { Remove( szName ); } int nFindEmptyIndex = FindSuitableEmptySpace( lDstSize ); SPackingFileInfo PackingFileInfo; if( nFindEmptyIndex == -1 ) { memset( &PackingFileInfo, 0, sizeof( SPackingFileInfo ) ); strcpy_s( PackingFileInfo.szFileName, _MAX_FNAME, szName ); PackingFileInfo.dwCompressSize = lDstSize; PackingFileInfo.dwOriginalSize = nSize; PackingFileInfo.dwAllocSize = lDstSize; PackingFileInfo.dwOffset = m_PackingFileHeader.dwFileInfoOffset; PackingFileInfo.dwSeedValue = nSeedCnt; m_vecPackingFileInfo.push_back( PackingFileInfo ); nFindEmptyIndex = ( int )m_vecPackingFileInfo.size() - 1; _Seek( m_hFile, m_vecPackingFileInfo[ nFindEmptyIndex ].dwOffset, SEEK_SET ); _Write( m_hFile, pDstData,lDstSize ); // ÆÄÀÏ Çì´õ ¾²´Âµ¥ ½Ã°£ ¸¹ÀÌ °É·Á¼­ Ç¥½Ã¸¸ ÇØµÎ°í CloseFileSystem()¿¡¼­ Çì´õ ÇѲ¨¹ø¿¡ WriteÇÑ´Ù m_PackingFileHeader.bRequireHeaderWrite = true; m_PackingFileHeader.dwFileInfoOffset = ( DWORD )_Seek( m_hFile, 0, SEEK_CUR ); } else { PackingFileInfo = m_vecPackingFileInfo[ nFindEmptyIndex ]; strcpy_s( PackingFileInfo.szFileName, _MAX_FNAME, szName ); PackingFileInfo.dwCompressSize = lDstSize; PackingFileInfo.dwOriginalSize = nSize; PackingFileInfo.dwSeedValue = nSeedCnt; m_vecPackingFileInfo[ nFindEmptyIndex ] = PackingFileInfo; _Seek( m_hFile, m_vecPackingFileInfo[ nFindEmptyIndex ].dwOffset, SEEK_SET ); _Write( m_hFile, pDstData,lDstSize ); LONGLONG nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindEmptyIndex ); _Seek( m_hFile, nFindFileOffset, SEEK_SET ); _Write( m_hFile, &m_vecPackingFileInfo[ nFindEmptyIndex ], sizeof( SPackingFileInfo ) ); } m_PackingFileHeader.nFileCount = ( int )m_vecPackingFileInfo.size(); _Seek( m_hFile, 0, SEEK_SET ); _Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) ); delete [] pDstData; AddPackingMap( nFindEmptyIndex ); CalcChecksum( nFindEmptyIndex ); return true; } void CEtPackingFile::WriteReserveFileInfo() { if( ( !m_bIsReadOnly ) && ( m_PackingFileHeader.bRequireHeaderWrite ) ) { _Seek( m_hFile, m_PackingFileHeader.dwFileInfoOffset, SEEK_SET ); _Write( m_hFile, &m_vecPackingFileInfo[ 0 ], ( DWORD )m_vecPackingFileInfo.size() * sizeof( SPackingFileInfo ) ); m_PackingFileHeader.bRequireHeaderWrite = false; _Seek( m_hFile, 0, SEEK_SET ); _Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) ); m_PackingFileHeader.bRequireHeaderWrite = false; } } void CEtPackingFile::RemoveFileInfo( int nFileIndex ) { if( nFileIndex < 0 || nFileIndex >= static_cast(m_vecPackingFileInfo.size()) ) return; m_vecPackingFileInfo[ nFileIndex ].dwCompressSize = 0; m_vecPackingFileInfo[ nFileIndex ].dwOriginalSize = 0; LONGLONG nFindFileOffset; nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFileIndex ); _Seek( m_hFile, nFindFileOffset, SEEK_SET ); _Write( m_hFile, &m_vecPackingFileInfo[ nFileIndex ], sizeof( SPackingFileInfo ) ); } int CEtPackingFile::ReservePatchFile( SPackingFileInfo *pFileInfo ) { if( m_hFile == INVALID_HANDLE_VALUE) return -1; if( pFileInfo->dwOriginalSize <= 0 ) return -1; SPackingFileInfo PackingFileInfo; PackingFileInfo = *pFileInfo; PackingFileInfo.dwAllocSize = pFileInfo->dwCompressSize; PackingFileInfo.dwOffset = m_PackingFileHeader.dwFileInfoOffset; m_vecPackingFileInfo.push_back( PackingFileInfo ); // ¿¹¾à¸¸ °É°í Çì´õ Write´Â ¿¹¾àÀÌ ´Ù ³¡³­ ÈÄ ÆÐÄ¡ Àü ½ÇÇà m_PackingFileHeader.bRequireHeaderWrite = true; m_PackingFileHeader.dwFileInfoOffset += PackingFileInfo.dwCompressSize; return static_cast( m_vecPackingFileInfo.size() - 1 ); } bool CEtPackingFile::PatchFileIndex( CEtFileHandle *pFileHandle, int nFileIndex, BOOL bSaveFileInfo ) { if( m_hFile == INVALID_HANDLE_VALUE || nFileIndex < 0 || nFileIndex >= static_cast( m_vecPackingFileInfo.size() ) ) return false; if( pFileHandle->m_FileInfo.dwOriginalSize <= 0 ) return true; if( pFileHandle->GetFileContext()->dwCompressSize > m_vecPackingFileInfo[ nFileIndex ].dwAllocSize ) return false; if( bSaveFileInfo ) { char szName[ _MAX_PATH ]; strcpy_s( szName, _MAX_PATH, pFileHandle->m_FileInfo.szFileName ); _strlwr( szName ); TrimString( szName ); SPackingFileInfo PackingFileInfo; PackingFileInfo = m_vecPackingFileInfo[ nFileIndex ]; strcpy_s( PackingFileInfo.szFileName, _MAX_FNAME, szName ); PackingFileInfo.dwCompressSize = pFileHandle->m_FileInfo.dwCompressSize; PackingFileInfo.dwOriginalSize = pFileHandle->m_FileInfo.dwOriginalSize; PackingFileInfo.dwSeedValue = pFileHandle->m_FileInfo.dwSeedValue; m_vecPackingFileInfo[ nFileIndex ] = PackingFileInfo; } // File Write _Seek( m_hFile, m_vecPackingFileInfo[ nFileIndex ].dwOffset, SEEK_SET ); _Write( m_hFile, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwCompressSize ); // FileInfo Write LONGLONG nFindFileOffset; nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFileIndex ); _Seek( m_hFile, nFindFileOffset, SEEK_SET ); _Write( m_hFile, &m_vecPackingFileInfo[ nFileIndex ], sizeof( SPackingFileInfo ) ); return true; } bool CEtPackingFile::PatchFile( CEtFileHandle *pFileHandle ) { if( m_hFile == INVALID_HANDLE_VALUE) return false; if( pFileHandle->m_FileInfo.dwOriginalSize <= 0) return true; char szName[ _MAX_PATH ]; strcpy_s( szName, _MAX_PATH, pFileHandle->m_FileInfo.szFileName ); _strlwr( szName ); TrimString( szName ); int nFindFileIndex = FindFile( szName ); if( nFindFileIndex != -1 ) { m_vecPackingFileInfo[ nFindFileIndex ].dwCompressSize = 0; m_vecPackingFileInfo[ nFindFileIndex ].dwOriginalSize = 0; } int nFindEmptyIndex = FindSuitableEmptySpace( pFileHandle->m_FileInfo.dwCompressSize ); SPackingFileInfo PackingFileInfo; if( nFindEmptyIndex == -1 ) { PackingFileInfo = pFileHandle->m_FileInfo; PackingFileInfo.dwAllocSize = pFileHandle->m_FileInfo.dwCompressSize; PackingFileInfo.dwOffset = m_PackingFileHeader.dwFileInfoOffset; m_vecPackingFileInfo.push_back( PackingFileInfo ); nFindEmptyIndex = ( int )m_vecPackingFileInfo.size() - 1; _Seek( m_hFile, m_vecPackingFileInfo[ nFindEmptyIndex ].dwOffset, SEEK_SET ); _Write( m_hFile, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwCompressSize ); // ÆÄÀÏ Çì´õ ¾²´Âµ¥ ½Ã°£ ¸¹ÀÌ °É·Á¼­ Ç¥½Ã¸¸ ÇØµÎ°í CloseFileSystem()¿¡¼­ Çì´õ ÇѲ¨¹ø¿¡ WriteÇÑ´Ù m_PackingFileHeader.bRequireHeaderWrite = true; m_PackingFileHeader.dwFileInfoOffset = ( DWORD )_Seek( m_hFile, 0, SEEK_CUR ); } else { PackingFileInfo = m_vecPackingFileInfo[ nFindEmptyIndex ]; strcpy_s( PackingFileInfo.szFileName, _MAX_FNAME, szName ); PackingFileInfo.dwCompressSize = pFileHandle->m_FileInfo.dwCompressSize; PackingFileInfo.dwOriginalSize = pFileHandle->m_FileInfo.dwOriginalSize; PackingFileInfo.dwSeedValue = pFileHandle->m_FileInfo.dwSeedValue; m_vecPackingFileInfo[ nFindEmptyIndex ] = PackingFileInfo; _Seek( m_hFile, m_vecPackingFileInfo[ nFindEmptyIndex ].dwOffset, SEEK_SET ); _Write( m_hFile, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwCompressSize ); LONGLONG nFindFileOffset; if( ( nFindFileIndex != -1 ) && ( nFindFileIndex != nFindEmptyIndex ) ) { nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindFileIndex ); _Seek( m_hFile, nFindFileOffset, SEEK_SET ); _Write( m_hFile, &m_vecPackingFileInfo[ nFindFileIndex ], sizeof( SPackingFileInfo ) ); } nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindEmptyIndex ); _Seek( m_hFile, nFindFileOffset, SEEK_SET ); _Write( m_hFile, &m_vecPackingFileInfo[ nFindEmptyIndex ], sizeof( SPackingFileInfo ) ); } return true; } bool CEtPackingFile::Remove(const char* strName) { if( m_hFile == INVALID_HANDLE_VALUE) return false; char szFileName[ _MAX_PATH ]; if( strName[ 0 ] == '\\' ) { strcpy_s( szFileName, _MAX_PATH, strName ); } else { strcpy_s( szFileName, _MAX_PATH, m_strCurDir ); strcat_s( szFileName, _MAX_PATH, strName ); } int nFindFileIndex = FindFile( szFileName ); if( nFindFileIndex != -1 ) { m_vecPackingFileInfo[ nFindFileIndex ].dwCompressSize = 0; m_vecPackingFileInfo[ nFindFileIndex ].dwOriginalSize = 0; LONGLONG nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindFileIndex ); _Seek( m_hFile, nFindFileOffset, SEEK_SET ); _Write( m_hFile, &m_vecPackingFileInfo[ nFindFileIndex ], sizeof( SPackingFileInfo ) ); _Seek( m_hFile, 0, SEEK_SET ); RemovePackingMap( nFindFileIndex ); AddPackingMap( nFindFileIndex ); return true; } return false; } bool CEtPackingFile::Rename(const char* strName,const char* strRename) { if( m_hFile == INVALID_HANDLE_VALUE) return false; int nFindFileIndex = FindFile( strName ); if( nFindFileIndex != -1 ) { strcpy_s( m_vecPackingFileInfo[ nFindFileIndex ].szFileName, _MAX_FNAME, strRename ); LONGLONG nFindFileOffset = m_PackingFileHeader.dwFileInfoOffset + ( sizeof( SPackingFileInfo ) * nFindFileIndex ); _Seek( m_hFile, nFindFileOffset, SEEK_SET ); _Write( m_hFile, &m_vecPackingFileInfo[ nFindFileIndex ], sizeof( SPackingFileInfo ) ); _Seek( m_hFile, 0, SEEK_SET ); RemovePackingMap( nFindFileIndex ); AddPackingMap( nFindFileIndex ); return true; } return false; } bool CEtPackingFile::ChangeDir(const char* strPath) { if( m_hFile == INVALID_HANDLE_VALUE ) return false; if( strPath[ 0 ] == '\\' ) { strcpy_s( m_strCurDir, _MAX_PATH, strPath ); return true; } if( _stricmp( strPath, "." ) == 0 ) { return true; } if( _stricmp( strPath, ".." ) == 0 ) { int nStrLength = ( int )strlen( m_strCurDir ); if( nStrLength == 1 ) { return false; } m_strCurDir[ nStrLength - 1 ] = 0; char *pFindPtr = strrchr( m_strCurDir, '\\' ); if( pFindPtr ) { *( pFindPtr + 1 ) = 0; } return true; } strcat_s( m_strCurDir, _MAX_PATH, strPath ); if( strPath[ strlen( strPath ) - 1 ] != '\\' ) { strcat_s( m_strCurDir, _MAX_PATH, "\\" ); } return true; } void CEtPackingFile::GetNameOnly(char* strDst,const char* strPath) { char strTemp[_MAX_PATH] = { 0, }; strcpy_s(strTemp,strPath); _strrev(strTemp); char* cp = strtok(strTemp, "\\/\x0\n\r\t"); strcpy_s(strTemp,cp); _strrev(strTemp); GetSafeName(strDst,strTemp); } void CEtPackingFile::GetPathOnly(char* strDst, const char* strPath) { char strName[_MAX_FNAME] = { 0, }; GetNameOnly(strName,strPath); size_t iLen = strlen(strPath)-strlen(strName); if(!iLen) { strDst[0] = '\0'; } else { //_tcsncpy_s(strDst, sizeof(strDst), strPath,iLen); strncpy(strDst, strPath,iLen); strDst[iLen] = '\0'; } } void CEtPackingFile::GetFileInfoListCurDir( std::vector< SPackingFileInfo * > &vecFileInfo ) { int i; for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ ) { if( m_vecPackingFileInfo[ i ].dwCompressSize == 0 ) { continue; } char szPath[ _MAX_PATH ]; _GetPath( szPath, _countof(szPath), m_vecPackingFileInfo[ i ].szFileName ); if( _stricmp( szPath, m_strCurDir ) == 0 ) { vecFileInfo.push_back( &m_vecPackingFileInfo[ i ] ); } } } void CEtPackingFile::GetDirListCurDir( std::vector< std::string > &vecDirList ) { int i, nStrLength; vecDirList.push_back( "." ); if( _stricmp( m_strCurDir, "\\" ) != 0 ) { vecDirList.push_back( ".." ); } nStrLength = ( int )strlen( m_strCurDir ); for( i = 0; i < ( int )m_vecPackingFileInfo.size(); i++ ) { char szPath[ _MAX_PATH ], szFindPath[ _MAX_PATH]; _GetPath( szPath, _countof(szPath), m_vecPackingFileInfo[ i ].szFileName ); if( strstr( szPath, m_strCurDir ) != szPath ) { continue; } char *pFindPtr = strchr( szPath + nStrLength, '\\' ); if( pFindPtr == NULL ) { continue; } *pFindPtr = 0; strcpy_s( szFindPath, _MAX_PATH, szPath + nStrLength ); std::vector< std::string >::iterator it; it = std::find( vecDirList.begin(), vecDirList.end(), szFindPath ); if( it == vecDirList.end() ) { vecDirList.push_back( szFindPath ); } } } bool CEtPackingFile::Patch( const char* strPatchPath, CPatchCallback* pCallpack, std::vector< CFileNameString > *pvecSkipList ) { CEtPackingFile srcPack; bool bResult = srcPack.OpenFileSystem(strPatchPath, true); m_pLog->Log( "srcPack.OpenFileSystem : %s " , strPatchPath ); if( bResult == false ) { if( pCallpack ) { pCallpack->OnError( CPatchCallback::SrcPackOpenFailed, CFileNameString("SrcPackOpenFailed") ); } m_pLog->Log( "OnError.SrcPackOpenFailed "); return false; } int nSrcFileCount = srcPack.GetFileCount(); m_pLog->Log( "Get srcFileList : %u " , nSrcFileCount ); if( nSrcFileCount <= 0 ) { if( pCallpack ) { pCallpack->OnError( CPatchCallback::SrcPackFileSizeZero, CFileNameString("SrcPackFileSizeZero") ); } m_pLog->Log( "OnError SrcPackFileSizeZero "); return false; } int i; for( i = 0; i < nSrcFileCount; i++ ) { SPackingFileInfo *pPackingFileInfo = srcPack.GetFileInfo( i ); if( pPackingFileInfo == NULL ) { continue; } bool bSkip = false; if( pvecSkipList ) { int j; for( j = 0; j < ( int )pvecSkipList->size(); j++ ) { // ÆÄÀÏÀ̸§ ¾Õ¿¡.. \ ºÙ¾î À־ ±×°Å Á¦¿ÜÇÑ À̸§À¸·Î ºñ±³ÇØ¾ß Á¦´ë·Î µÈ´Ù. if( _stricmp( pPackingFileInfo->szFileName + 1, ( *pvecSkipList )[ j ].c_str() ) == 0 ) { bSkip = true; break; } } } if( bSkip ) { continue; } CEtFileHandle *pFileHandle = srcPack.OpenOnly( pPackingFileInfo->szFileName ); if( pFileHandle == NULL ) { continue; } bool bResultInner = PatchFile( pFileHandle ); // bool bResult = AddFile( pPackingFileInfo->szFileName, pFileHandle->m_pData, pFileHandle->m_FileInfo.dwOriginalSize ); CloseFile( pFileHandle ); if( ( !bResultInner ) && ( pCallpack ) ) { pCallpack->OnError( CPatchCallback::DstPackAddFailed, pPackingFileInfo->szFileName ); } if( pCallpack ) { pCallpack->OnPatch( i, nSrcFileCount, pPackingFileInfo->szFileName ); } } m_PackingFileHeader.nFileCount = ( int )m_vecPackingFileInfo.size(); _Seek( m_hFile, 0, SEEK_SET ); _Write( m_hFile, &m_PackingFileHeader, sizeof( SPackingFileHeader ) ); return true; } //----------------------------------------------------------------------------------------------------------------- CEtFileSystem::CEtFileSystem( bool bDynamicPath ) { m_bDynamicPath = bDynamicPath; } CEtFileSystem::~CEtFileSystem() { RemoveAll(); } void CEtFileSystem::AddPackingFolder( const char* szPackingFileName, const char* szExt ) { WIN32_FIND_DATA FindFileData; HANDLE hFind; CFileNameString szFindFile; szFindFile = szPackingFileName; szFindFile += "\\*."; szFindFile += szExt; hFind = FindFirstFile( szFindFile.c_str() , &FindFileData ); while( hFind != INVALID_HANDLE_VALUE ) { if( !( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) { CFileNameString szFullPath; szFullPath = szPackingFileName; szFullPath += "\\"; szFullPath += FindFileData.cFileName; CEtFileSystem::AddPackingFile(szFullPath.c_str(), szPackingFileName); } if( !FindNextFile( hFind, &FindFileData ) ) break; } FindClose( hFind ); } void CEtFileSystem::AddPackingFolder( const WCHAR* szPackingFileName, const char* szExt ) { //rlkt_pak //MessageBoxA(NULL, FormatA(" AddPackingFolder szPackingFileName: %s ext: %s", szPackingFileName, szExt).c_str(), "AddPackingFolder", MB_OK); WIN32_FIND_DATAW FindFileData; HANDLE hFind; std::wstring szFindFile; szFindFile = szPackingFileName; szFindFile += L"\\*."; std::string szTempExt = szExt; std::wstring wszTempExt; ToWideString(szTempExt, wszTempExt); szFindFile += wszTempExt; hFind = FindFirstFileW( szFindFile.c_str() , &FindFileData ); while( hFind != INVALID_HANDLE_VALUE ) { if( !( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) { std::wstring szFullPath; szFullPath = szPackingFileName; szFullPath += L"\\"; szFullPath += FindFileData.cFileName; std::string szTempBufferPath; std::string szTempBufferName; ToMultiString( szFullPath, szTempBufferPath ); ToMultiString( std::wstring(szPackingFileName), szTempBufferName ); CEtFileSystem::AddPackingFile(szTempBufferPath.c_str(), szTempBufferName.c_str()); } if( !FindNextFileW( hFind, &FindFileData ) ) break; } FindClose( hFind ); } bool CEtFileSystem::AddPackingFile(const char* szPackingFileName, const char *szRootPath) { //rlkt_pak //MessageBoxA(NULL, FormatA(" AddPackingFile szPackingFileName: %s szRootPath: %s", szPackingFileName, szRootPath).c_str(), "AddPackingFile", MB_OK); std::map::iterator it = m_PackingFileMap.find( CFileNameString(szPackingFileName) ); if( it != m_PackingFileMap.end() ) return false; CEtPackingFile* pPackingFile = new CEtPackingFile(); pPackingFile->SetRootPath( szRootPath ); bool bResult = pPackingFile->OpenFileSystem(szPackingFileName, true); if( !bResult ) { //rlkt_pak //MessageBoxA(NULL, FormatA(" OpenFileSystem read only false szPackingFileName: %s szRootPath: %s", szPackingFileName, szRootPath).c_str(), "AddPackingFile", MB_OK); delete pPackingFile; return false; } m_PackingFileMap.insert(make_pair(CFileNameString(szPackingFileName), pPackingFile)); return true; } void CEtFileSystem::RemoveAll() { std::map::iterator it = m_PackingFileMap.begin(); for ( ; it != m_PackingFileMap.end() ; it++ ) { CEtPackingFile* pPackingFile = it->second; delete pPackingFile; } m_PackingFileMap.clear(); } CEtFileHandle *CEtFileSystem::OpenFile( const char* strPath, bool bOpenOnly ) { int nFindIndex = -1; CEtPackingFile *pFindPacking = FindFile( strPath, nFindIndex ); if( pFindPacking ) { if( bOpenOnly ) { return pFindPacking->OpenOnly( strPath ); } else { return pFindPacking->OpenFile( strPath ); } } return NULL; } void CEtFileSystem::CloseFile( CEtFileHandle* pFileHandle ) { SAFE_DELETE( pFileHandle ); } CEtPackingFile *CEtFileSystem::FindFile( const char *pFileName, int &nFindIndex ) { std::map< CFileNameString, CEtPackingFile * >::iterator it = m_PackingFileMap.begin(); for ( ; it != m_PackingFileMap.end() ; it++ ) { CEtPackingFile *pPackingFile = it->second; if( pPackingFile == NULL ) { continue; } nFindIndex = pPackingFile->FindFile( pFileName ); if( nFindIndex != -1 ) { return pPackingFile; } } return NULL; } void CEtFileSystem::AddResourcePath( const char *szPath, bool bIncludeSubDir ) { } void CEtFileSystem::RemoveResourcePath( const char *szPath, bool bIncludeSubDir ) { } void CEtFileSystem::CacheFileList( int nIndex, bool bAdd ) { } CFileNameString CEtFileSystem::GetFullName( const char *szFileName, bool *bFind ) { ScopeLock Lock(m_SyncLock, m_bDynamicPath); if( bFind ) *bFind = false; char szName[_MAX_PATH] = { 0, }; if( ( szFileName[ 0 ] == '\\' ) || ( IsFullName( szFileName ) ) ) { strcpy_s( szName, szFileName ); } else { _GetFullFileName( szName, _countof(szName), szFileName ); } int nFindIndex = -1; CEtPackingFile *pFindPacking = FindFile( szName, nFindIndex ); if( pFindPacking ) { if( bFind ) *bFind = true; return pFindPacking->GetFileInfo( nFindIndex )->szFileName; } return szFileName; } CFileNameString CEtFileSystem::GetFullPath( const char *szPath ) { ScopeLock Lock(m_SyncLock, m_bDynamicPath); CFileNameString szTemp = szPath; ToLowerA( szTemp ); std::map< CFileNameString, CEtPackingFile * >::iterator it; for ( it = m_PackingFileMap.begin(); it != m_PackingFileMap.end(); it++ ) { CEtPackingFile *pPackingFile = it->second; if( pPackingFile == NULL ) { continue; } int i; int nFileCount = pPackingFile->GetFileCount(); for( i = 0; i < nFileCount; i++ ) { SPackingFileInfo *pPackingFileInfo = pPackingFile->GetFileInfo( i ); if( pPackingFileInfo == NULL ) { continue; } char *pFindPtr = strstr( pPackingFileInfo->szFileName, szTemp.c_str() ); if( pFindPtr == NULL ) { continue; } pFindPtr = strchr( pFindPtr, '\\' ); if( pFindPtr ) { char szReturnPath[ _MAX_PATH ]; *pFindPtr = 0; strcpy_s( szReturnPath, _MAX_PATH, pPackingFileInfo->szFileName ); *pFindPtr = '\\'; return szReturnPath; } } } return szPath; } void CEtFileSystem::FindFullPathList( const char *szPath, std::vector &szVecResult ) { ScopeLock Lock(m_SyncLock, m_bDynamicPath); CFileNameString szTemp = "\\"; szTemp += szPath; ToLowerA( szTemp ); std::map< CFileNameString, CEtPackingFile * >::iterator it; for ( it = m_PackingFileMap.begin(); it != m_PackingFileMap.end(); it++ ) { CEtPackingFile *pPackingFile = it->second; if( pPackingFile == NULL ) { continue; } int i; int nFileCount = pPackingFile->GetFileCount(); for( i = 0; i < nFileCount; i++ ) { SPackingFileInfo *pPackingFileInfo = pPackingFile->GetFileInfo( i ); if( pPackingFileInfo == NULL ) { continue; } char *pFindPtr = strstr( pPackingFileInfo->szFileName, szTemp.c_str() ); if( pFindPtr == NULL ) { continue; } pFindPtr = strchr( pPackingFileInfo->szFileName, '\\' ); if( pFindPtr ) { char szReturnPath[ _MAX_PATH ]; /* *pFindPtr = 0; strcpy_s( szReturnPath, _MAX_PATH, pPackingFileInfo->szFileName ); *pFindPtr = '\\'; */ _GetPath( szReturnPath, _countof(szReturnPath), pPackingFileInfo->szFileName ); szReturnPath[ strlen(szReturnPath)-1] = 0; bool bExist = false; for( DWORD j=0; j &szVecResult) { ScopeLock Lock(m_SyncLock, m_bDynamicPath); std::string strFolder = szFolderName; strFolder += "\\"; /* UINT nCodePage = CEtResourceMng::GetInstance().GetCodePage(); CFileNameString sztemp; const char *szCodePage = CEtResourceMng::GetInstance().FindCodePageString(nCodePage); strFolder += szCodePage; */ std::vector ResultArray; std::map< std::string, std::vector >::iterator iterFind = m_szMapCacheFileListInFolder.find( strFolder ); if( iterFind != m_szMapCacheFileListInFolder.end() ) { ResultArray = iterFind->second; } else { std::map< CFileNameString, CEtPackingFile * >::iterator it = m_PackingFileMap.begin(); for ( ; it != m_PackingFileMap.end() ; it++ ) { int i; CEtPackingFile *pPackingFile = it->second; if( pPackingFile == NULL ) { continue; } int nFileCount = pPackingFile->GetFileCount(); for( i = 0; i < nFileCount; i++ ) { SPackingFileInfo *pPackingFileInfo = pPackingFile->GetFileInfo( i ); if( pPackingFileInfo == NULL || pPackingFileInfo->dwCompressSize == 0 || pPackingFileInfo->dwOriginalSize == 0 ) { continue; } std::string szFolderKey = pPackingFileInfo->szFileName; if( szFolderKey.find(strFolder.c_str()) < szFolderKey.size() ) { RemoveStringA(szFolderKey, strFolder); ResultArray.push_back(szFolderKey); } } } // ÆÐÅ·ÆÄÀÏ ¾È¿¡ ÀÖ´Â ÆÄÀÏÁß¿¡ \resource\ext·Î ½ÃÀÛÇÏ´Â ÆÄÀÏÀ» ¾ò¾î¿À´Â ·çƾÀε¥, // ¸ðµç ÆÄÀÏÀ» ´Ù µÚÁö±â¶§¹®¿¡, ¸Å¹ø 150msÀÇ µô·¹À̰¡ »ý±ä´Ù. // ÀÌ°Ô Á¡Á¡ ÆÐÅ·ÆÄÀϾȿ¡ ÆÄÀÏÀÌ ´Ã¾î³ª°í, extÀÇ °³¼ö°¡ ¸¹¾ÆÁú¼ö·Ï ´õ ¸¹Àº ¼öÇà½Ã°£ÀÌ ÇÊ¿äÇϹǷÎ, // ÀÌ·¸°Ô ij½Ã¸¦ µÖ¼­ ¾ò¾î¿À´Â ÇüÅ·ΠÇϰڴÙ. // ÀÌ·¸°Ô ÇÏ´Ï ÆÑ¾È¾²´Â °Í°ú ºñ½ÁÇÑ ·Îµù¼Óµµ¸¦ º¸¿©ÁØ´Ù.(TableDB·Îµå ºÎºÐ) m_szMapCacheFileListInFolder.insert( make_pair( strFolder, ResultArray ) ); } /* std::string strExt = szExt; RemoveStringA(strExt, std::string("*")); for ( size_t i = 0 ; i < ResultArray.size() ; i++ ) { std::string str = ResultArray[i]; if( str.find( strExt ) < str.size() ) { szVecResult.push_back(str); } } */ std::vector szVecNameStr; std::vector szVecExtStr; char szTemp[256]; sprintf_s( szTemp, szExt ); _strlwr_s( szTemp ); char szNameTemp[256]; char szExtTemp[64]; _GetFileName( szNameTemp, _countof(szNameTemp), szTemp ); _GetExt( szExtTemp, _countof(szExtTemp), szTemp ); for( int i=0; ; i++ ) { const char *szStr = _GetSubStrByCount( i, szNameTemp, '*' ); if( szStr == NULL || strlen(szStr) < 1 ) break; szVecNameStr.push_back( szStr ); } for( int i=0; ; i++ ) { const char *szStr = _GetSubStrByCount( i, szExtTemp, '*' ); if( szStr == NULL || strlen(szStr) < 1 ) break; szVecExtStr.push_back( szStr ); } for ( size_t i = 0 ; i < ResultArray.size() ; i++ ) { std::string str = ResultArray[i]; bool bResult = true; char *pPtr; for( DWORD j=0; j= str.size() ) { bResult = false; break; } if( j == 0 && pPtr != str.c_str() ) { bResult = false; break; } } if( !bResult ) continue; bResult = true; for( DWORD j=0; j= str.size() ) { if( pPtr == NULL ) { bResult = false; break; } } if( !bResult ) continue; szVecResult.push_back(str); } }