/*=========================================================================== * * Name : DetermineAllDirectories * * Purpose : Finds all the subdirectories under the root path. * * * Return value : TRUE - browse completed * FALSE- either not valid root path or >1 root path * * Special notes: * * Implicit Input : * Implicit Input/Output: * Implicit Output: * * date / author revision * ----------------- -------- * 18-Nov-1998 SFK Created * 06-Jul-1999 SFK Version 2.04 - changed check for FILE_ATTRIBUTE_DIRECTORY to check * ` if that bit is set rather than having the patterns match exactly * ===========================================================================*/ BOOL DetermineAllDirectories(char *pDlgPath, CGFmtStr *pAllPaths, unsigned int *puiNumPaths) { char szTemp[PATH_LEN+1]; unsigned int uiNumFound; unsigned int ui; int iLen; int iDum, iDum1; int status; long lAttributes; CGFmtStr szMsg; int iTemp; GUI_ACTION response; HCURSOR OldCur = ::SetCursor(LoadCursor(NULL, IDC_WAIT)); // Determine how many valid paths are in the pDlgPath entry. status = CountPathsAndFiles(pDlgPath, "*.*", (int *)puiNumPaths, &iDum, &iDum1); ::SetCursor(OldCur); if (status != TRUE) return(FALSE); if (*puiNumPaths != 1) return(FALSE); // only allow one path for the browse OldCur = ::SetCursor(LoadCursor(NULL, IDC_WAIT)); CGStrPtrDynaArray *pResult = BrowseDirectory("*.", pDlgPath, TRUE); ::SetCursor(OldCur); OldCur = ::SetCursor(LoadCursor(NULL, IDC_WAIT)); uiNumFound = pResult->size(); pAllPaths->Printf("%s;", pDlgPath); // always include the root *puiNumPaths = 1; for (ui=0; ui<uiNumFound; ui++) { MyStrnCpy(szTemp, (*pResult)[ui]->Get_sz(), PATH_LEN); // char * to work with iLen = strlen(szTemp); lAttributes = GetFileAttributes(szTemp); // address of the name of a file or directory if ((lAttributes &FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { // only examine the subdirectories if ((szTemp[iLen-1] != '.') && // skip all . and .. paths (strstr((strupr(szTemp)), "ARCHIVE") == NULL)) { // skip folders named archive if ((strlen(pAllPaths->Get_sz()) + strlen(szTemp)) >= PATHS) { szMsg.Printf("The subfolder list generated with the root path of %s contains %d ", pDlgPath, uiNumFound); iTemp = PATHS; szMsg.PrintfAppend("files and is too long. Do you want to proceed using only the first %d characters?", iTemp); response = GUI_MsgBox(szMsg, GUI_ICON_QUESTION, GUI_NOYES); if (response == GUI_YES) break; *puiNumPaths = 0; ::SetCursor(OldCur); return(FALSE); } pAllPaths->PrintfAppend("%s;", szTemp); (*puiNumPaths)++; } } } ::SetCursor(OldCur); BrowseCleanup(pResult); return(TRUE); }
void CMpqPackGen::DoPacking() { // 日志文件 CHAR szTempFile[MAX_PATH] = {0}; ::GetCurrentDirectory( MAX_PATH, szTempFile ); ::PathAppend( szTempFile, "PackGen.log" ); m_pGenLogFile = fopen( szTempFile, "w" ); if( !m_pGenLogFile ) { char szMsg[ MAX_PATH ]; _snprintf(szMsg, MAX_PATH, "日志文件%s创建失败!", szTempFile); MessageBox(NULL, szMsg, "ERROR", MB_OK|MB_ICONSTOP); return; } CHAR szTempErrFile[MAX_PATH] = {0}; ::GetCurrentDirectory( MAX_PATH, szTempErrFile ); ::PathAppend( szTempErrFile, "PackGenError.log" ); m_pErrorLogFile = fopen( szTempErrFile, "w" ); if( !m_pErrorLogFile ) { char szMsg[ MAX_PATH ]; _snprintf(szMsg, MAX_PATH, "文件错误日志 %s创建失败!", szTempFile); MessageBox(NULL, szMsg, "ERROR", MB_OK|MB_ICONSTOP); return; } for( int i=0;i<m_iPackTotal;i++ ) { if ( m_iPackPotion == 0 || m_iPackPotion == i+1 ) { int FileNum = 0; //统计文件个数,以决定HashTable大小 vector<string>::iterator it = m_vecPackInfo[i].vecPackPath.begin(); for ( ;it!= m_vecPackInfo[i].vecPackPath.end();it++ ) { int num = BrowseDirectory(NULL,*it, m_vecPackInfo[i].vecExt,false); FileNum += num; } FileNum = FileNum * 1.5; //Hash表大小是文件实际个数的1.5倍 if ( FileNum<MIN_HASH_TABLE_SIZE ) FileNum = MIN_HASH_TABLE_SIZE; if (FileNum>MAX_HASH_TABLE_SIZE) { MessageBox(NULL, "Hash表太大,请检查文件个数", "ERROR", MB_OK|MB_ICONSTOP); return; } DWORD R = 0; string PackName = m_vecPackInfo[i].strPackName + ".mpq"; TKPMArchive* pArchive = KPM_CreateArchive( PackName.c_str(), R,FileNum , USE_TYPE_PATCH); printf( "\n ==============================" ); printf( "\n PackName: %s", PackName.c_str() ); printf( "\n" ); it = m_vecPackInfo[i].vecPackPath.begin(); for ( ;it!= m_vecPackInfo[i].vecPackPath.end();it++ ) { int num = BrowseDirectory(pArchive,*it, m_vecPackInfo[i].vecExt,true); FileNum += num; } KPM_CloseArchive(pArchive); } } printf( "\n PackGen OK!" ); }//DoPacking end
//递归遍历文件夹 //pArchive: MPQ包指针 strDir:原资源目录 VecExt:扩展名集合 int CMpqPackGen::BrowseDirectory(TKPMArchive* pArchive,string &strDir,vector<string> &VecExt,bool IsPack) { int FileNum = 0; intptr_t ptrFile; struct _finddata_t file; string strFindTemp = ""; if ( strDir == "./" || strDir =="/" || strDir == "../" ) strFindTemp = strDir + "*.*"; else strFindTemp = strDir + "/*.*"; if ( strDir == "./" || strDir =="/" ) strDir = "."; if ( strDir == "../" ) strDir = ".."; bool bAddFileTag = false; if( (ptrFile = _findfirst( strFindTemp.c_str(), &file )) != -1L ) { while( _findnext( ptrFile, &file ) == 0 ) { if (file.name[0] == '.') continue; //忽略 _mbslwr((byte*)file.name); string FilePath = strDir + "/" + file.name; if( PathIsDirectory( FilePath.c_str() ) ) { //如果是目录,进入此目录进行递归 FileNum = FileNum + BrowseDirectory(pArchive,strDir+"/"+file.name,VecExt,IsPack); } else { //得到文件扩展名 string::size_type ExtPos = FilePath.find_last_of("."); string::size_type TmpPos = FilePath.find_last_of("/"); if ( ExtPos != string::npos ) { string Ext = FilePath.substr(ExtPos,FilePath.size()-ExtPos); if (Ext == ".exe") { // } string tmp = FilePath.substr(TmpPos+1,tmp.size()-TmpPos); //转为小写 if ( find(VecExt.begin(),VecExt.end(),Ext) != VecExt.end() || VecExt.at(0) == "*.*" || find(VecExt.begin(),VecExt.end(),tmp) != VecExt.end() ) { //指定KPM_FILE_IMPLODE/KPM_FILE_COMPRESS:表示使用压缩算法(同时指定速度较慢) //遇有已压缩的数据时,不要指定KPM_FILE_IMPLODE/KPM_FILE_COMPRESS //KPM_FILE_ENCRYPTED:表示加密 //KPM_FILE_REPLACEEXISTING:表示有同名文件时替换,有同名文件但未指定此参数,则返回错误 //FILE_TYPE_DATA:目前只支持两种格式:普通数据/WAVE数据,今后需扩展 DWORD Flags = KPM_FILE_COMPRESS; DWORD FileType = FILE_TYPE_DATA; if( ".wav" == Ext ) { FileType = FILE_TYPE_WAVE; } else if( ".mp3" == Ext || ".zip" == Ext || ".rar" == Ext || ".mpq" == Ext || ".jpg" == Ext || ".dds" == Ext ) { Flags &= ~KPM_FILE_COMPRESS; } else if( ".db" == Ext ) { continue; } FileNum++; if ( IsPack && pArchive ) { m_iFileNum++; if ( !m_bTestVersion ) { //最终的发行版不带路径信息 bAddFileTag = KPM_AddFile( pArchive, FilePath.c_str(), file.name, Flags, 0, FileType ); } else { //内部调试版带路径信息 bAddFileTag = KPM_AddFile( pArchive, FilePath.c_str(), FilePath.c_str(), Flags, 0, FileType ); } if( bAddFileTag ) { printf( "\n AddFile PackPath: %s", FilePath.c_str() ); fprintf( m_pGenLogFile, "%d: AddFile ( %s ) \n", m_iFileNum, FilePath.c_str() ); m_vFilePath.push_back( FilePath ); } else { string str = "无"; vector<string>::iterator it = m_vFilePath.begin(); for( ; it != m_vFilePath.end(); it++ ) { if( string::npos != (*it).find( file.name ) ) { str = (*it); break; } } fprintf( m_pErrorLogFile, "%d: Error ( %s 已经存在 %s ) \n", m_iFileNum, FilePath.c_str(), str.c_str() ); // assert(false); } } } } } }//while end //关闭查找句柄 _findclose( ptrFile ); }//if end return FileNum; }//BrowseDirectory end