home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 June / Chip_2002-06_cd1.bin / zkuste / wincom / download / mltwcx.1.0.0.8-src.cab / mltwcx-src / ArchiverEngine.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  19.4 KB  |  844 lines

  1. #include "stdafx.h"
  2. #include "ArchiverEngine.h"
  3. #include "ArcItem.h"
  4. #include "config.h"
  5.  
  6. // Some changes was make by: 
  7. // Igor Glucksmann (IG)
  8. // Mateusz Brzostek (MB)
  9.  
  10. CArchiverEngine::CArchiverEngine(CArchiveDescription *pad,tOpenArchiveData *data,BOOL bCreate)
  11. {
  12.     m_bAlreadyTested=false;
  13.     m_pad=pad;
  14.     m_pDeferedNames=0;
  15. //MB>>
  16.   m_pDestPath = NULL;
  17.   m_pStripPath = NULL;
  18. //MB<<
  19.     strcpy(m_szArcPathName,data->ArcName);
  20.     if(m_pad)
  21.     {
  22.         if(bCreate)
  23.         {
  24.             m_pArcItemsList=NULL;
  25.             m_pCurItem=NULL;
  26.             m_iOpenMode=data->OpenMode;
  27.         }
  28.         else
  29.         {
  30.             if(ParseNExecuteCommand(LISTCMD_IDX))
  31.             {
  32.                 AdjustBounds();
  33.                 m_pArcItemsList=CArcItem::LoadFromList(m_coList.GetOutputData()+m_iBeginOff,m_iEndOff-m_iBeginOff,m_pad);
  34.                 m_pCurItem=(CArcItem *)-1;
  35.                 m_iOpenMode=data->OpenMode;
  36.             }
  37.             else
  38.             {
  39.                 m_pArcItemsList=NULL;
  40.                 m_pCurItem=NULL;
  41.                 m_iOpenMode=data->OpenMode;
  42.             }
  43.         }
  44.     }
  45. }
  46.  
  47. CArchiverEngine::~CArchiverEngine()
  48. {
  49.     delete m_pDeferedNames;
  50.   delete m_pDestPath;
  51.   delete m_pStripPath;
  52. // 02-09-2001: MB: Stack overflow fixed
  53.   while(m_pArcItemsList)
  54.   {
  55.     CArcItem *p = m_pArcItemsList->m_pNext;
  56.     delete m_pArcItemsList;
  57.     m_pArcItemsList = p;
  58.   }
  59. }
  60.  
  61. void CArchiverEngine::AdjustBounds()
  62. {
  63.     LPCSTR lpList=m_coList.GetOutputData();
  64.  
  65.     LPCSTR lpStart=m_pad->String(START_IDX);
  66.     LPCSTR lpEnd=m_pad->String(END_IDX);
  67.  
  68.     m_iBeginOff=0;
  69.     m_iEndOff=lstrlen(lpList);
  70.  
  71.     if(!lpStart && !lpEnd)
  72.         return;
  73.  
  74.     LPCSTR lpB=lpList,lpE=lpList;
  75.  
  76.     if(lpStart)
  77.     {
  78.         char *lpStr=new char[lstrlen(lpStart)+3];
  79.         bool bFromBeg;
  80.         if(bFromBeg=(bool)(*lpStart=='^'))
  81.         {
  82.             lstrcpy(lpStr,"\r\n");
  83.             lstrcat(lpStr,lpStart+1);
  84.         }
  85.         else
  86.             lstrcpy(lpStr,lpStart);
  87.  
  88.         LPSTR lpBTmp=strstr(lpList,lpStr);
  89.         if(lpBTmp)
  90.         {
  91.             if(bFromBeg)
  92.                 lpBTmp+=2;
  93.  
  94.             while(*lpBTmp && *lpBTmp!='\n')lpBTmp++;
  95.             if(*lpBTmp)
  96.             {
  97.                 lpBTmp++;
  98.                 m_iBeginOff=lpBTmp-lpList;
  99.             }
  100.  
  101.                 // AIN specific code begin 8-)
  102.             LPCSTR lp=0;
  103.             if(IsArchiveType("AIN"))
  104.             {
  105.                 while(*lpBTmp && *lpBTmp!='\n')lpBTmp++;
  106.                 if(*lpBTmp)
  107.                 {
  108.                     lpBTmp++;
  109.                     m_iBeginOff=lpBTmp-lpList;
  110.                 }
  111.             }
  112.         }
  113.         delete[] lpStr;
  114.     }
  115.  
  116.     if(lpEnd)
  117.     {
  118.         char *lpStr=new char[lstrlen(lpEnd)+3];
  119.         bool bFromBeg;
  120.         if(bFromBeg=(bool)(*lpEnd=='^'))
  121.         {
  122.             lstrcpy(lpStr,"\r\n");
  123.             lstrcat(lpStr,lpEnd+1);
  124.         }
  125.         else
  126.             lstrcpy(lpStr,lpEnd);
  127.  
  128.         LPSTR lpETmp=strstr(&lpList[m_iBeginOff],lpStr);
  129.         if(lpETmp)
  130.         {
  131.             if(!bFromBeg)
  132.                 while(lpETmp>lpList && *lpETmp!='\r')lpETmp--;
  133.  
  134.             if(*lpETmp)
  135.                 m_iEndOff=lpETmp-lpList;
  136.         }
  137.         delete[] lpStr;
  138.     }
  139. }
  140.  
  141. int CArchiverEngine::ReadHeader(tHeaderData *hdrData)
  142. {
  143.     if(!m_pArcItemsList)
  144.         return E_END_ARCHIVE;
  145.  
  146.     if(m_pCurItem == (CArcItem *)-1)
  147.         m_pCurItem=m_pArcItemsList;
  148.     else
  149.     {
  150.         m_pCurItem=m_pCurItem->GetNext();
  151.         if(!m_pCurItem)
  152.             return E_END_ARCHIVE;
  153.     }
  154.     strcpy(hdrData->FileName,m_pCurItem->m_szFilePath);
  155.     hdrData->PackSize=m_pCurItem->m_iPackedSize;
  156.     hdrData->UnpSize=m_pCurItem->m_iUnpackedSize;
  157.     hdrData->FileTime=m_pCurItem->m_iFileTime;
  158.     hdrData->FileAttr=m_pCurItem->m_iFileAttr;
  159.     return 0;
  160. }
  161.  
  162. // returns length of string list NOT including last \0
  163. int lst_strlen(char *str)
  164. {
  165.     int l=0;
  166.     for(char *pp=str;l=strlen(pp);pp+=l+1);
  167.     return (pp - str);
  168. }
  169.  
  170. //MB>>
  171. int StrniCmp( const char *s1, const char *s2, int n )
  172. {
  173.     return 2 - CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE|SORT_STRINGSORT, s2, n, s1, n );
  174. }
  175.  
  176. static int MakePaths( char *DestName, char *FileName, char **DestPath, unsigned *lStrip )
  177. {
  178.   char buf[ 260 ], *p, *p1;
  179.   int w, i;
  180.  
  181.   if( GetFullPathName( DestName, 260, buf, &p ) < 4 )
  182.     return 0;
  183.   p = strchr( buf + 2, '\\' );           // buf starts with 'c:\'
  184.   if( p == NULL )                        // or '\\CompName\DriveName\'
  185.     return 0;
  186.   if( buf[ 0 ] == '\\' )                 // case '\\CompName\DriveName\'
  187.   {
  188.     p = strchr( p + 1, '\\' );
  189.     if( p == NULL )
  190.       return 0;
  191.   }
  192.  
  193.   p1 = FileName;
  194.   w = strlen( p1 );
  195.   i = strlen( ++p );
  196.   while( w > i )
  197.   {
  198.     p1 = strchr( p1, '\\' );
  199.     if( p1 == NULL )
  200.       return 0;
  201.     w = strlen( ++p1 );
  202.   }
  203.   p += i - w;
  204.  
  205.   while( w > 0 )
  206.   {
  207.      if( p[ -1 ] == '\\' && StrniCmp( p, p1, -1 ) == 0 )
  208.      {
  209.       i = p - buf;
  210.       *DestPath = (char*)malloc( i + 1 );
  211.       if( *DestPath == NULL )
  212.         return 0;
  213.       memcpy( *DestPath, buf, i );
  214.       (*DestPath)[ i ] = 0;
  215.       *lStrip = p1 - FileName;
  216.       return 1;
  217.     }
  218.     p1 = strchr( p1, '\\' );
  219.     if( p1 == NULL )
  220.       return 0;
  221.     i = strlen( ++p1 );
  222.     p += w - i;
  223.     w = i;
  224.   }
  225.  
  226.   return 0;
  227. }
  228. //MB<<
  229.  
  230. //MB: a lot of changes in following function ...
  231. bool CArchiverEngine::ExtractFile(LPSTR lpDestPath,LPSTR lpDestName)
  232. {
  233.     if(m_iOpenMode == PK_OM_LIST)
  234.         return true;
  235.  
  236.     if(m_pad->BatchUnpack())
  237.     {
  238.  
  239.         if( m_pDeferedNames )
  240.     { //TODO - merge this with below code!
  241.       int length = lst_strlen( m_pDeferedNames );
  242.       int add_length = strlen( m_pCurItem->m_szFilePath );
  243.  
  244.       m_pDeferedNames = (char *)realloc( m_pDeferedNames, length + add_length + 2 );
  245.       memcpy( m_pDeferedNames + length, m_pCurItem->m_szFilePath, add_length );
  246.       memset( m_pDeferedNames + length + add_length, 0, 2 );
  247.     }
  248.         else
  249.         {
  250.       int len = strlen( m_pCurItem->m_szFilePath );
  251.       unsigned lStrip;
  252.  
  253.       m_pDeferedNames = (char *)malloc( len + 2 );
  254.       memcpy( m_pDeferedNames, m_pCurItem->m_szFilePath, len );
  255.       memset( m_pDeferedNames + len, 0, 2 );
  256.  
  257.       if( MakePaths( lpDestName, m_pCurItem->m_szFilePath, &m_pDestPath, &lStrip ) )
  258.       {
  259.         if( lStrip )
  260.         {
  261.           m_pStripPath = (char*)malloc( lStrip + 1 );
  262.           memcpy( m_pStripPath, m_pCurItem->m_szFilePath, lStrip );
  263.           m_pStripPath[ lStrip ] = 0;
  264.         }
  265.       }
  266.       else
  267.         return false; /// ??????
  268.         }
  269.  
  270.         return true;
  271.     }
  272.  
  273.     //CConsoleOutput co(m_pad->Debug()); 
  274.     char szCurPath[MAX_PATH];
  275.  
  276.     char szFileList[MAX_PATH];
  277.     char szTempFile[MAX_PATH];
  278.     lstrcpy(szTempFile,g_szMultiarcTempPath);
  279.     strcpy(szFileList,m_pCurItem->m_szFilePath);
  280.     szFileList[lstrlen(szFileList)+1]=0;
  281.  
  282.     GetCurrentDirectory(MAX_PATH,szCurPath);
  283.     CreateDirectory(szTempFile,0);
  284.     SetCurrentDirectory(szTempFile);
  285.  
  286.     if(ParseNExecuteCommand(EXTRACT_IDX,szFileList))
  287.     {
  288.         SetCurrentDirectory(szCurPath);
  289.  
  290.         char szFNameExt[_MAX_FNAME];
  291.         char szFName[_MAX_FNAME];
  292.         char szFExt[_MAX_EXT];
  293.         _splitpath(m_pCurItem->m_szFilePath,0,0,szFName,szFExt);
  294.         _makepath(szFNameExt,0,0,szFName,szFExt);
  295.         lstrcat(szTempFile,"\\");
  296.         lstrcat(szTempFile,szFNameExt);
  297.  
  298.         LPSTR lpFileNameTo=lpDestName;
  299.  
  300.         if(!lpFileNameTo)
  301.         {
  302.             if(lpDestPath)
  303.                 lstrcpy(szCurPath,lpDestPath);
  304.  
  305.             lstrcat(szCurPath,"\\");
  306.             lstrcat(szCurPath,szFNameExt);
  307.             lpFileNameTo=szCurPath;
  308.         }
  309.  
  310.         char szPath[MAX_PATH];    
  311.         char szDrive[_MAX_DRIVE];    
  312.         char szPathNDrive[MAX_PATH];    
  313.         _splitpath(lpFileNameTo,szDrive,szPath,0,0);
  314.         _makepath(szPathNDrive,szDrive,szPath,0,0);
  315.         
  316.         int iLen=lstrlen(szPathNDrive);
  317.         for(int i=0;i<iLen;i++)
  318.         {
  319.             if(szPathNDrive[i]=='\\')
  320.             {
  321.                 szPathNDrive[i]=0;
  322.                 if(GetFileAttributes(szPathNDrive)==0xFFFFFFFF)
  323.                     CreateDirectory(szPathNDrive,0);
  324.                 szPathNDrive[i]='\\';
  325.             }
  326.         }
  327.  
  328.         MoveFile(szTempFile,lpFileNameTo);
  329.         return true;
  330.     }
  331.     return false;
  332. }
  333.  
  334. bool CArchiverEngine::TestArchive()
  335. {
  336.     if(!m_bAlreadyTested)
  337.     {
  338.         CConsoleOutput co(m_pad->Debug());
  339.         if(ParseNExecuteCommand(TEST_IDX))
  340.             m_bAlreadyTested=true;
  341.         else
  342.             return false;
  343.     }
  344.     return true;
  345. }
  346.  
  347. bool CArchiverEngine::DeleteFiles(char *DeleteList)
  348. {
  349.     int iAICount=0;
  350.     for(CArcItem *p=m_pArcItemsList;p->m_pNext;iAICount++,p=p->m_pNext);
  351.  
  352.     int patcnt=0,l,idx=0;
  353.     for(char *pp=DeleteList;l=strlen(pp);patcnt++,pp+=l+1);
  354.  
  355.     char **pattarray=new char *[iAICount+patcnt+1];
  356.     ZeroMemory(pattarray,sizeof(char *)*(iAICount+patcnt+1));
  357.     
  358.     while(DeleteList && *DeleteList)
  359.     {
  360.         int iLen=lstrlen(DeleteList);
  361.         if(!lstrcmp(DeleteList+iLen-3,"*.*"))
  362.         {
  363.             p=m_pArcItemsList;
  364.             while(p)
  365.             {
  366.                 if(!StrniCmp(p->m_szFilePath,DeleteList,iLen-3))
  367.                     pattarray[idx++]=p->m_szFilePath;
  368.                 p=p->m_pNext;
  369.             }
  370.         }
  371.         else
  372.             pattarray[idx++]=DeleteList;
  373.  
  374.         DeleteList+=lstrlen(DeleteList)+1;
  375.     }
  376.  
  377.     int iListLen=0;
  378.     for(idx=0;pattarray[idx];iListLen+=lstrlen(pattarray[idx++])+1);
  379.  
  380.     char *pRealDeleteList=new char[iListLen+1];
  381.     ZeroMemory(pRealDeleteList,iListLen+1);
  382.  
  383.     pp=pRealDeleteList;
  384.     for(idx=0;pattarray[idx];strcpy(pp,pattarray[idx]),pp+=lstrlen(pattarray[idx++])+1);
  385.     *pp=0;
  386.  
  387.     bool bRet=(ParseNExecuteCommand(DELETE_IDX,pRealDeleteList));
  388.     
  389.     delete[] pRealDeleteList;
  390.     delete[] pattarray;
  391.  
  392.     return bRet;
  393. }
  394.  
  395. bool CArchiverEngine::PackFiles(char *szSubPath, char *szSrcPath, char *AddList, int Flags)
  396. {
  397.     //int iRet=0;
  398.     char szCurPath[MAX_PATH];
  399.     //CConsoleOutput co(m_pad->Debug());
  400.     GetCurrentDirectory(MAX_PATH,szCurPath);
  401.  
  402.     if(szSrcPath)
  403.         SetCurrentDirectory(szSrcPath);
  404. //02-09-2001 : MB : added support for packing to directories in archive
  405.   m_SubPath = szSubPath ? szSubPath : "";
  406.  
  407.     bool bRet=ParseNExecuteCommand((Flags&PK_PACK_MOVE_FILES)?MOVE_IDX:ADD_IDX,AddList);
  408.  
  409.     SetCurrentDirectory(szCurPath);
  410.     return bRet;
  411. }
  412.  
  413. void Modify(char *szAdd,const char *lpStr,char **p)
  414. {
  415.     int i=0;
  416.     while((*p)[i] && !isspace((*p)[i]) && (*p)[i]!='}')i++;
  417.     char sz[10];
  418.     strncpy(sz,*p,i);
  419.     sz[i]=0;
  420.     *p+=i;
  421.  
  422.     char szTmp[MAX_PATH];
  423.     strcpy(szTmp,lpStr);
  424.  
  425.     if(strchr(sz,'W') || strchr(sz,'P'))
  426.     {
  427.         char szPath[MAX_PATH],szName[_MAX_FNAME],szExt[_MAX_EXT];
  428.         _splitpath(szTmp,0,szPath,szName,szExt);
  429.         if(strchr(sz,'P'))
  430.             _makepath(szTmp,0,szPath,0,0);
  431.         else
  432.             _makepath(szTmp,0,0,szName,szExt);
  433.     }
  434.  
  435.     if(strchr(sz,'q') || (strchr(sz,'Q') && strchr(szTmp,' ')))
  436.     {
  437.         strcpy(szAdd,"\\\"");
  438.         strcat(szAdd,szTmp);
  439.         strcat(szAdd,"\\\"");
  440.     }
  441.     else
  442.         strcpy(szAdd,szTmp);
  443.  
  444.     if(!strchr(sz,'A'))
  445.         CharToOem(szAdd,szAdd);
  446. }
  447.  
  448. DWORD SafeGetShortPathName(LPCTSTR lpszLongPath,LPTSTR lpszShortPath,DWORD cchBuffer)
  449. {
  450.     int ifile=-1;
  451.     if(_access(lpszLongPath,0) == -1)
  452.         ifile=_open(lpszLongPath,_O_CREAT,_S_IREAD|_S_IWRITE);
  453.  
  454.     DWORD dwRet=GetShortPathName(lpszLongPath,lpszShortPath,cchBuffer);
  455.  
  456.     if(ifile!=-1)
  457.     {
  458.         _close(ifile);
  459.         _unlink(lpszLongPath);
  460.     }
  461.  
  462.     return dwRet;
  463. }
  464.                          
  465.  
  466. bool CArchiverEngine::ParseNExecuteCommand(int idx, LPCSTR lpFileOrList)
  467. {
  468.     LPCSTR lpFmtStr=m_pad->String(idx);
  469.  
  470.     if(!lpFmtStr)
  471.     {
  472.         MessageBox(GetFocus(),"Format string for this command is not defined. "
  473.       "Current command can't be executed. "
  474.             "Check you multiarc.ini settings for this archiver type.","Warning",MB_ICONWARNING);
  475.  
  476.         return false;
  477.     }
  478.  
  479.     LPCSTR lpArchiver=m_pad->String(ARCHIVER_IDX);
  480.  
  481.     char *pszCommand=new char[MAX_PATH*2];
  482.  
  483.     int idxCmd=0;
  484.     int iErrorLevel=0;
  485.     char *p=(char *)lpFmtStr;
  486.     char *apFileListMod[2];
  487.     BOOL bShort=FALSE;
  488.     BOOL bList=FALSE;
  489.     char cMod=0;
  490.     //BOOL bFileListPassed=FALSE;
  491.     int iflmIdx=0;
  492.     bool bAvoidOem2Ansi=false;
  493.  
  494.   bool bHasNonEmptyFields = false;
  495.   int idxBraceBegin = -1;
  496.  
  497. // 9-2-01 : IG : fix AV when this stay uninitialized 
  498.   apFileListMod[0] = NULL;
  499.  
  500.     while(*p)
  501.     {
  502.         char ch=*p++;
  503.         //if(ch=='%')
  504.     switch(ch)
  505.         {
  506.     case '%':
  507.       {
  508.               char szAdd[MAX_PATH];
  509.               szAdd[0]=0;
  510.               ch=*p++;
  511.               switch(ch)
  512.               {
  513.   // 02-09-2001: MB : support for adding files to subdirectory
  514.               case 'R':
  515.                   Modify(szAdd,m_SubPath,&p);
  516.           if(m_SubPath && strlen(m_SubPath))
  517.             bHasNonEmptyFields = true;
  518.                   break;
  519.   // MB: end
  520.               case 'P':
  521.                   Modify(szAdd,lpArchiver,&p);
  522.                   break;
  523.               case 'p':
  524.                   GetShortPathName(lpArchiver,szAdd,MAX_PATH);
  525.                   Modify(szAdd,szAdd,&p);
  526.                   break;
  527.               case 'A':
  528.                   Modify(szAdd,m_szArcPathName,&p);
  529.                   break;
  530.               case 'a': 
  531.                   SafeGetShortPathName(m_szArcPathName,szAdd,MAX_PATH);
  532.                   Modify(szAdd,szAdd,&p);
  533.                   break;
  534.               case 'L':case 'l':case 'F':case 'f':
  535.                   //if(!bFileListPassed)
  536.                   if(iflmIdx<2)
  537.                   {
  538.                       bList=(ch =='L' || ch == 'l');
  539.                       bShort=(ch == 'l' || ch == 'f');
  540.                       pszCommand[idxCmd++]='%';
  541.                       pszCommand[idxCmd++]='s';
  542.                       pszCommand[idxCmd]=0;
  543.                       apFileListMod[iflmIdx++]=p;
  544.                       //bFileListPassed=TRUE;
  545.                   }
  546.                   else
  547.             MessageBox(GetFocus(),"You specified multiple entries for file/filelist for this command. Only first one will be accepted."
  548.             "To avoid this message remove extra file/filelist entries from format string.","Warning",MB_ICONWARNING);
  549.  
  550.  
  551.                   while(*p && !isspace(*p))p++;
  552.                   continue;
  553.               case 'E':
  554.                   iErrorLevel=atoi(p);
  555.                   while(*p && !isspace(*p))p++;
  556.                   continue;
  557.               case 'O':
  558.                   bAvoidOem2Ansi=true;
  559.                   //p++;
  560.                   while(*p && !isspace(*p))p++;
  561.                   continue;
  562.               case '\0':
  563.                   p--;
  564.                   continue;
  565.         }
  566.  
  567.               if(szAdd[0])
  568.               {
  569.                   strcpy(pszCommand+idxCmd,szAdd);
  570.                   idxCmd+=strlen(szAdd);
  571.               }
  572.           }
  573.       break;
  574.  
  575.     case '{':
  576.       idxBraceBegin = idxCmd;
  577.       bHasNonEmptyFields = false;
  578.       break;
  579.  
  580.     case '}':
  581.       if(idxBraceBegin >= 0 && !bHasNonEmptyFields)
  582.           idxCmd = idxBraceBegin;
  583.       break;
  584.  
  585.     default:
  586.             pszCommand[idxCmd++]=ch;
  587.       break;
  588.     }
  589.     }
  590.     pszCommand[idxCmd]=0;
  591.  
  592.     char szCurPath[MAX_PATH];
  593.     GetCurrentDirectory(MAX_PATH,szCurPath);
  594.  
  595.     bool bRet=true;
  596.     if(idx == LISTCMD_IDX || idx == TEST_IDX)
  597.     {
  598.         m_coList.SetOemConversion(!bAvoidOem2Ansi);
  599.         int iRet=m_coList.ExecuteCommand(pszCommand,m_pad->String(INPUT_IDX));
  600.         m_pad->DebugOutput(pszCommand,m_coList.GetOutputData(),iRet,szCurPath);
  601.         if(!m_pad->IgnoreErrors())
  602.         {
  603.             if(iRet == -1 || iRet > iErrorLevel)
  604.             {
  605.                 static char sz[MAX_PATH*2];
  606.         wsprintf(sz,"Executing command ' %s ' returned errorlevel %d. "
  607.           "Possibly an error occure. Archive listing wasn't retrieved.",pszCommand,iRet);
  608.         MessageBox(GetFocus(),sz,"Warning", MB_ICONWARNING);
  609.                 bRet=false;
  610.             }
  611.         }
  612.     }
  613.     else
  614.     {
  615.         char *pCurFile=(char *)lpFileOrList;
  616.         do{
  617.             static char szListPath[MAX_PATH];
  618.             szListPath[0]=0;
  619.             static char sz_UglyPath[MAX_PATH];
  620.             static char sz_UglyPath2[MAX_PATH];
  621.             char *pszCommand2=new char[MAX_PATH*2];
  622.             char *pAlmostName=0;
  623.             if(bList)
  624.             {
  625.                 GetTempFileName(g_szMultiarcTempPath,"lst",0,szListPath);
  626.                 HANDLE hFile=CreateFile(szListPath,GENERIC_WRITE,FILE_SHARE_READ,
  627.                                         0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
  628.                 for(char *pp=(char *)lpFileOrList;*pp;pp+=lstrlen(pp)+1)
  629.                 {
  630.                     if(!(m_pad->SkipDirsInFileList() && pp[lstrlen(pp)-1] == '\\'))
  631.                     {
  632.                         DWORD dwWritten;
  633.                         if(bShort)
  634.                         {
  635.                             static char path[MAX_PATH];
  636.                             if(!SafeGetShortPathName(pp,path,MAX_PATH))
  637.                                 strcpy(path,pp);
  638.                             WriteFile(hFile,path,lstrlen(path),&dwWritten,0);
  639.                         }
  640.                         else
  641.                         {
  642.                             static char anotherPath[MAX_PATH];
  643.                             if(strchr(apFileListMod[0],'q') || (strchr(apFileListMod[0],'Q') && strchr(pp,' ')))
  644.                                 wsprintf(anotherPath,"\"%s\"",pp);
  645.                             else
  646.                                 strcpy(anotherPath,pp);
  647.  
  648.                             if(!strchr(apFileListMod[0],'A'))
  649.                                 CharToOem(anotherPath,anotherPath);
  650.  
  651.                             WriteFile(hFile,anotherPath,lstrlen(anotherPath),&dwWritten,0);
  652.                         }
  653.  
  654.                         WriteFile(hFile,"\r\n",2,&dwWritten,0);
  655.                     }
  656.                 }
  657.                 CloseHandle(hFile);
  658.                 pAlmostName=szListPath;
  659.             }
  660.             else
  661.             {
  662.                 if(bShort)
  663.                 {
  664.                     GetShortPathName(pCurFile,sz_UglyPath,MAX_PATH);
  665.                     pAlmostName=sz_UglyPath;
  666.                 }
  667.                 else
  668.                     pAlmostName=pCurFile;
  669.                 
  670.                 pCurFile+=lstrlen(pCurFile)+1;
  671.             }
  672.  
  673.             char *pp=apFileListMod[0];
  674.  
  675.       if(pp)
  676.               Modify(sz_UglyPath2,pAlmostName,&pp);
  677.  
  678.             if(iflmIdx==2)
  679.             {
  680.                 static char sz_UglyPath3[MAX_PATH];
  681.                 pp=apFileListMod[1];
  682.                 Modify(sz_UglyPath3,pAlmostName,&pp);
  683.                 wsprintf(pszCommand2,pszCommand,sz_UglyPath2,sz_UglyPath3);
  684.             }
  685.             else
  686.                 wsprintf(pszCommand2,pszCommand,sz_UglyPath2);
  687.  
  688.             CConsoleOutput co(m_pad->Debug());
  689.             co.SetOemConversion(!bAvoidOem2Ansi);
  690.  
  691.             int iRet=co.ExecuteCommand(pszCommand2,m_pad->String(INPUT_IDX));
  692.             m_pad->DebugOutput(pszCommand2,co.GetOutputData(),iRet,szCurPath);
  693.  
  694.             if(szListPath[0] && !m_pad->Debug())
  695.                 DeleteFile(szListPath);
  696.  
  697.             if(!m_pad->IgnoreErrors())
  698.             {
  699.                 if(iRet == -1 || iRet > iErrorLevel)
  700.                 {
  701.                     static char sz[MAX_PATH*2];
  702.           wsprintf(sz,"Executed command ' %s ' returned errorlevel %d, "
  703.             "wich is higher than configured as normal for this command. "
  704.             "Probably error occure. Check your configuration, please...",pszCommand2,iRet);
  705.                     MessageBox(GetFocus(),sz,"Warning", MB_ICONWARNING);
  706.                     bRet=false;
  707.                 }
  708.             }
  709.             delete[] pszCommand2;
  710.  
  711.         }while(!bList && *pCurFile);
  712.     }
  713.  
  714.     delete[] pszCommand;
  715.  
  716.     return bRet;
  717. }
  718.  
  719. bool CArchiverEngine::IsArchiveType(LPCSTR lpcType)
  720. {
  721.     LPCSTR lp=0;
  722.     return (lp=m_pad->String(TYPENAME_IDX)) && !strcmp(lp,lpcType);
  723. }
  724.  
  725. //MB>>
  726. static int MakeDir( char *Path )
  727. {
  728.   int l;
  729.   char buf[ 260 ], *p;
  730.  
  731.   l = GetFullPathName( Path, 260, buf, &p );  // t/k\../z\a.c => c:\t\z\a.c
  732.   if( l < 3 )                                 // min 'c:\'
  733.     return 0;
  734.   if( p )                                     // exclude file part
  735.   {
  736.     p[ 0 ] = 0;
  737.     l = p - buf;
  738.   }
  739.   if( l < 3 || buf[ l - 1 ] != '\\' )         // min 'c:\' and ends at '\'
  740.     return 0;
  741.   p = strchr( buf + 2, '\\' );                // buf starts with 'c:\'
  742.   if( p == NULL )                             // or '\\CompName\DriveName\'
  743.     return 0;
  744.   if( buf[ 0 ] == '\\' )                      // case '\\CompName\DriveName\'
  745.   {
  746.     p = strchr( p + 1, '\\' );
  747.     if( p == NULL )
  748.       return 0;
  749.   }
  750.  
  751.   l = 0;
  752.   while( (p = strchr( p + 1, '\\' )) != NULL )
  753.   {
  754.     p[ 0 ] = 0;
  755.     l = _mkdir( buf );
  756.     p[ 0 ] = '\\';
  757.   }
  758.  
  759.   if( l == -1 && (errno == EEXIST || errno == EACCES) )
  760.     l = 0;
  761.   return l + 1;
  762. }
  763.  
  764. static void move_files( char *tmp, char *StripPath, char *DestPath )
  765. {
  766.   SHFILEOPSTRUCT shF;
  767.   char buf[ MAX_PATH + 1 ];
  768.  
  769.   strcpy( buf, tmp );
  770.   strcat( buf, "\\" );
  771.   strcat( buf, StripPath );
  772.   strcat( buf, "*.*" );
  773.   buf[ strlen( buf ) + 1 ] = 0;
  774.   shF.hwnd = NULL;
  775.   shF.wFunc = FO_MOVE;
  776.   shF.pFrom = buf;
  777.   shF.pTo = DestPath;
  778.   shF.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOCONFIRMMKDIR;
  779.   SHFileOperation( &shF );
  780. }
  781.  
  782. static void delete_files( char *tmp )
  783. {
  784.   SHFILEOPSTRUCT shF;
  785.   char buf[ MAX_PATH + 1 ];
  786.  
  787.   strcpy( buf, tmp );
  788.   buf[ strlen( buf ) + 1 ] = 0;
  789.   shF.hwnd = NULL;
  790.   shF.wFunc = FO_DELETE;
  791.   shF.pFrom = buf;
  792.   shF.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
  793.   SHFileOperation( &shF );
  794. }
  795. //MB<<
  796.  
  797. bool CArchiverEngine::OnClose()
  798. {
  799.     if(m_pad->BatchUnpack() && m_pDeferedNames)
  800.     {
  801.     char szCurPath[ MAX_PATH ], *tmp;
  802.         GetCurrentDirectory(MAX_PATH,szCurPath);
  803.  
  804.         if( m_pStripPath )
  805.     {
  806.       tmp = _tempnam( g_szMultiarcTempPath, "" );
  807.  
  808.       if( tmp == NULL )
  809.         return false;
  810.  
  811.       if( _mkdir( tmp ) != 0 )
  812.       {
  813.         free( tmp );
  814.         return false;
  815.       }
  816.  
  817.       SetCurrentDirectory( tmp );
  818.     }
  819.     else
  820.     {
  821.       if( !MakeDir( m_pDestPath ) )
  822.         return false; // ???? for waht ????
  823.       SetCurrentDirectory( m_pDestPath );
  824.     }
  825.  
  826.         bool bRet=ParseNExecuteCommand(EXTRACT_WITH_PATH_IDX,m_pDeferedNames);
  827.  
  828.     if( m_pStripPath )
  829.     {
  830.       if( bRet )
  831.       {
  832.         move_files( tmp, m_pStripPath, m_pDestPath );
  833.         delete_files( tmp );
  834.       }
  835.       free( tmp );
  836.     }
  837.  
  838.         SetCurrentDirectory(szCurPath);
  839.         return bRet;
  840.     }
  841.  
  842.     return true;
  843. }
  844.