misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
branchui-scaling
changeset 15283 c4fd2813b127
parent 13390 0135e64c6c66
parent 15279 7ab5cf405686
child 15663 d92eeb468dad
--- a/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandler.cpp	Wed May 16 18:22:28 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,793 +0,0 @@
-// 7zHandler.cpp
-
-#include "StdAfx.h"
-
-#include "7zHandler.h"
-#include "7zProperties.h"
-
-#include "../../../Common/IntToString.h"
-#include "../../../Common/ComTry.h"
-#include "../../../Windows/Defs.h"
-
-#include "../Common/ItemNameUtils.h"
-#ifdef _7Z_VOL
-#include "../Common/MultiStream.h"
-#endif
-
-#ifdef __7Z_SET_PROPERTIES
-#ifdef EXTRACT_ONLY
-#include "../Common/ParseProperties.h"
-#endif
-#endif
-
-#ifdef COMPRESS_MT
-#include "../../../Windows/System.h"
-#endif
-
-using namespace NWindows;
-
-extern UString ConvertMethodIdToString(UInt64 id);
-
-namespace NArchive {
-namespace N7z {
-
-CHandler::CHandler()
-{
-  _crcSize = 4;
-
-  #ifdef EXTRACT_ONLY
-  #ifdef COMPRESS_MT
-  _numThreads = NWindows::NSystem::GetNumberOfProcessors();
-  #endif
-  #else
-  Init();
-  #endif
-}
-
-STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
-{
-  *numItems = 
-  #ifdef _7Z_VOL
-  _refs.Size();
-  #else
-  *numItems = _database.Files.Size();
-  #endif
-  return S_OK;
-}
-
-#ifdef _SFX
-
-IMP_IInArchive_ArcProps_NO
-
-STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
-{
-  return E_NOTIMPL;
-}
-
-STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,     
-      BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
-{
-  return E_NOTIMPL;
-}
-
-
-#else
-
-STATPROPSTG kArcProps[] = 
-{
-  { NULL, kpidMethod, VT_BSTR},
-  { NULL, kpidSolid, VT_BOOL},
-  { NULL, kpidNumBlocks, VT_UI4}
-};
-
-STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
-{
-  COM_TRY_BEGIN
-  NWindows::NCOM::CPropVariant prop;
-  switch(propID)
-  {
-    case kpidMethod:
-    {
-      UString resString;
-      CRecordVector<UInt64> ids;
-      int i;
-      for (i = 0; i < _database.Folders.Size(); i++)
-      {
-        const CFolder &f = _database.Folders[i];
-        for (int j = f.Coders.Size() - 1; j >= 0; j--)
-          ids.AddToUniqueSorted(f.Coders[j].MethodID);
-      }
-
-      for (i = 0; i < ids.Size(); i++)
-      {
-        UInt64 id = ids[i];
-        UString methodName;
-        /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
-        if (methodName.IsEmpty())
-          methodName = ConvertMethodIdToString(id);
-        if (!resString.IsEmpty())
-          resString += L' ';
-        resString += methodName;
-      }
-      prop = resString; 
-      break;
-    }
-    case kpidSolid: prop = _database.IsSolid(); break;
-    case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break;
-  }
-  prop.Detach(value);
-  return S_OK;
-  COM_TRY_END
-}
-
-IMP_IInArchive_ArcProps
-
-#endif
-
-static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
-{
-  if (timeDefined)
-    prop = unixTime;
-}
-
-#ifndef _SFX
-
-static UString ConvertUInt32ToString(UInt32 value)
-{
-  wchar_t buffer[32];
-  ConvertUInt64ToString(value, buffer);
-  return buffer;
-}
-
-static UString GetStringForSizeValue(UInt32 value)
-{
-  for (int i = 31; i >= 0; i--)
-    if ((UInt32(1) << i) == value)
-      return ConvertUInt32ToString(i);
-  UString result;
-  if (value % (1 << 20) == 0)
-  {
-    result += ConvertUInt32ToString(value >> 20);
-    result += L"m";
-  }
-  else if (value % (1 << 10) == 0)
-  {
-    result += ConvertUInt32ToString(value >> 10);
-    result += L"k";
-  }
-  else
-  {
-    result += ConvertUInt32ToString(value);
-    result += L"b";
-  }
-  return result;
-}
-
-static const UInt64 k_Copy = 0x0;
-static const UInt64 k_LZMA  = 0x030101;
-static const UInt64 k_PPMD  = 0x030401;
-
-static wchar_t GetHex(Byte value)
-{
-  return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
-}
-static inline UString GetHex2(Byte value)
-{
-  UString result;
-  result += GetHex((Byte)(value >> 4));
-  result += GetHex((Byte)(value & 0xF));
-  return result;
-}
-
-#endif
-
-static const UInt64 k_AES  = 0x06F10701;
-
-#ifndef _SFX
-static inline UInt32 GetUInt32FromMemLE(const Byte *p)
-{
-  return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
-}
-#endif
-
-bool CHandler::IsEncrypted(UInt32 index2) const
-{
-  CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
-  if (folderIndex != kNumNoIndex)
-  {
-    const CFolder &folderInfo = _database.Folders[folderIndex];
-    for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
-      if (folderInfo.Coders[i].MethodID == k_AES)
-        return true;
-  }
-  return false;
-}
-
-STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID,  PROPVARIANT *value)
-{
-  COM_TRY_BEGIN
-  NWindows::NCOM::CPropVariant prop;
-  
-  /*
-  const CRef2 &ref2 = _refs[index];
-  if (ref2.Refs.IsEmpty())
-    return E_FAIL;
-  const CRef &ref = ref2.Refs.Front();
-  */
-  
-  #ifdef _7Z_VOL
-  const CRef &ref = _refs[index];
-  const CVolume &volume = _volumes[ref.VolumeIndex];
-  const CArchiveDatabaseEx &_database = volume.Database;
-  UInt32 index2 = ref.ItemIndex;
-  const CFileItem &item = _database.Files[index2];
-  #else
-  const CFileItem &item = _database.Files[index];
-  UInt32 index2 = index;
-  #endif
-
-  switch(propID)
-  {
-    case kpidPath:
-    {
-      if (!item.Name.IsEmpty())
-        prop = NItemName::GetOSName(item.Name);
-      break;
-    }
-    case kpidIsFolder:
-      prop = item.IsDirectory;
-      break;
-    case kpidSize:
-    {
-      prop = item.UnPackSize;
-      // prop = ref2.UnPackSize;
-      break;
-    }
-    case kpidPosition:
-    {
-      /*
-      if (ref2.Refs.Size() > 1)
-        prop = ref2.StartPos;
-      else
-      */
-        if (item.IsStartPosDefined)
-          prop = item.StartPos;
-      break;
-    }
-    case kpidPackedSize:
-    {
-      // prop = ref2.PackSize;
-      {
-        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
-        if (folderIndex != kNumNoIndex)
-        {
-          if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
-            prop = _database.GetFolderFullPackSize(folderIndex);
-          /*
-          else
-            prop = (UInt64)0;
-          */
-        }
-        else
-          prop = (UInt64)0;
-      }
-      break;
-    }
-    case kpidLastAccessTime:
-      MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
-      break;
-    case kpidCreationTime:
-      MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
-      break;
-    case kpidLastWriteTime:
-      MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
-      break;
-    case kpidAttributes:
-      if (item.AreAttributesDefined)
-        prop = item.Attributes;
-      break;
-    case kpidCRC:
-      if (item.IsFileCRCDefined)
-        prop = item.FileCRC;
-      break;
-    case kpidEncrypted:
-    {
-      prop = IsEncrypted(index2);
-      break;
-    }
-    #ifndef _SFX
-    case kpidMethod:
-      {
-        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
-        if (folderIndex != kNumNoIndex)
-        {
-          const CFolder &folderInfo = _database.Folders[folderIndex];
-          UString methodsString;
-          for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
-          {
-            const CCoderInfo &coderInfo = folderInfo.Coders[i];
-            if (!methodsString.IsEmpty())
-              methodsString += L' ';
-
-            {
-              UString methodName;
-              bool methodIsKnown = FindMethod(
-                  EXTERNAL_CODECS_VARS 
-                  coderInfo.MethodID, methodName);
-
-              if (methodIsKnown)
-              {
-                methodsString += methodName;
-                if (coderInfo.MethodID == k_LZMA)
-                {
-                  if (coderInfo.Properties.GetCapacity() >= 5)
-                  {
-                    methodsString += L":";
-                    UInt32 dicSize = GetUInt32FromMemLE(
-                      ((const Byte *)coderInfo.Properties + 1));
-                    methodsString += GetStringForSizeValue(dicSize);
-                  }
-                }
-                else if (coderInfo.MethodID == k_PPMD)
-                {
-                  if (coderInfo.Properties.GetCapacity() >= 5)
-                  {
-                    Byte order = *(const Byte *)coderInfo.Properties;
-                    methodsString += L":o";
-                    methodsString += ConvertUInt32ToString(order);
-                    methodsString += L":mem";
-                    UInt32 dicSize = GetUInt32FromMemLE(
-                      ((const Byte *)coderInfo.Properties + 1));
-                    methodsString += GetStringForSizeValue(dicSize);
-                  }
-                }
-                else if (coderInfo.MethodID == k_AES)
-                {
-                  if (coderInfo.Properties.GetCapacity() >= 1)
-                  {
-                    methodsString += L":";
-                    const Byte *data = (const Byte *)coderInfo.Properties;
-                    Byte firstByte = *data++;
-                    UInt32 numCyclesPower = firstByte & 0x3F;
-                    methodsString += ConvertUInt32ToString(numCyclesPower);
-                    /*
-                    if ((firstByte & 0xC0) != 0)
-                    {
-                      methodsString += L":";
-                      return S_OK;
-                      UInt32 saltSize = (firstByte >> 7) & 1;
-                      UInt32 ivSize = (firstByte >> 6) & 1;
-                      if (coderInfo.Properties.GetCapacity() >= 2)
-                      {
-                        Byte secondByte = *data++;
-                        saltSize += (secondByte >> 4);
-                        ivSize += (secondByte & 0x0F);
-                      }
-                    }
-                    */
-                  }
-                }
-                else
-                {
-                  if (coderInfo.Properties.GetCapacity() > 0)
-                  {
-                    methodsString += L":[";
-                    for (size_t bi = 0; bi < coderInfo.Properties.GetCapacity(); bi++)
-                    {
-                      if (bi > 5 && bi + 1 < coderInfo.Properties.GetCapacity())
-                      {
-                        methodsString += L"..";
-                        break;
-                      }
-                      else
-                        methodsString += GetHex2(coderInfo.Properties[bi]);
-                    }
-                    methodsString += L"]";
-                  }
-                }
-              }
-              else
-              {
-                methodsString += ConvertMethodIdToString(coderInfo.MethodID);
-              }
-            }
-          }
-          prop = methodsString;
-        }
-      }
-      break;
-    case kpidBlock:
-      {
-        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
-        if (folderIndex != kNumNoIndex)
-          prop = (UInt32)folderIndex;
-      }
-      break;
-    case kpidPackedSize0:
-    case kpidPackedSize1:
-    case kpidPackedSize2:
-    case kpidPackedSize3:
-    case kpidPackedSize4:
-      {
-        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
-        if (folderIndex != kNumNoIndex)
-        {
-          const CFolder &folderInfo = _database.Folders[folderIndex];
-          if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
-              folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
-          {
-            prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
-          }
-          else
-            prop = (UInt64)0;
-        }
-        else
-          prop = (UInt64)0;
-      }
-      break;
-    #endif
-    case kpidIsAnti:
-      prop = item.IsAnti;
-      break;
-  }
-  prop.Detach(value);
-  return S_OK;
-  COM_TRY_END
-}
-
-#ifdef _7Z_VOL
-
-static const wchar_t *kExt = L"7z";
-static const wchar_t *kAfterPart = L".7z";
-
-class CVolumeName
-{
-  bool _first;
-  UString _unchangedPart;
-  UString _changedPart;    
-  UString _afterPart;    
-public:
-  bool InitName(const UString &name)
-  {
-    _first = true;
-    int dotPos = name.ReverseFind('.');
-    UString basePart = name;
-    if (dotPos >= 0)
-    {
-      UString ext = name.Mid(dotPos + 1);
-      if (ext.CompareNoCase(kExt)==0 || 
-        ext.CompareNoCase(L"EXE") == 0)
-      {
-        _afterPart = kAfterPart;
-        basePart = name.Left(dotPos);
-      }
-    }
-
-    int numLetters = 1;
-    bool splitStyle = false;
-    if (basePart.Right(numLetters) == L"1")
-    {
-      while (numLetters < basePart.Length())
-      {
-        if (basePart[basePart.Length() - numLetters - 1] != '0')
-          break;
-        numLetters++;
-      }
-    }
-    else 
-      return false;
-    _unchangedPart = basePart.Left(basePart.Length() - numLetters);
-    _changedPart = basePart.Right(numLetters);
-    return true;
-  }
-
-  UString GetNextName()
-  {
-    UString newName; 
-    // if (_newStyle || !_first)
-    {
-      int i;
-      int numLetters = _changedPart.Length();
-      for (i = numLetters - 1; i >= 0; i--)
-      {
-        wchar_t c = _changedPart[i];
-        if (c == L'9')
-        {
-          c = L'0';
-          newName = c + newName;
-          if (i == 0)
-            newName = UString(L'1') + newName;
-          continue;
-        }
-        c++;
-        newName = UString(c) + newName;
-        i--;
-        for (; i >= 0; i--)
-          newName = _changedPart[i] + newName;
-        break;
-      }
-      _changedPart = newName;
-    }
-    _first = false;
-    return _unchangedPart + _changedPart + _afterPart;
-  }
-};
-
-#endif
-
-STDMETHODIMP CHandler::Open(IInStream *stream,
-    const UInt64 *maxCheckStartPosition, 
-    IArchiveOpenCallback *openArchiveCallback)
-{
-  COM_TRY_BEGIN
-  Close();
-  #ifndef _SFX
-  _fileInfoPopIDs.Clear();
-  #endif
-  try
-  {
-    CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
-    #ifdef _7Z_VOL
-    CVolumeName seqName;
-
-    CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
-    #endif
-
-    #ifndef _NO_CRYPTO
-    CMyComPtr<ICryptoGetTextPassword> getTextPassword;
-    if (openArchiveCallback)
-    {
-      openArchiveCallbackTemp.QueryInterface(
-          IID_ICryptoGetTextPassword, &getTextPassword);
-    }
-    #endif
-    #ifdef _7Z_VOL
-    if (openArchiveCallback)
-    {
-      openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
-    }
-    for (;;)
-    {
-      CMyComPtr<IInStream> inStream;
-      if (!_volumes.IsEmpty())
-      {
-        if (!openVolumeCallback)
-          break;
-        if(_volumes.Size() == 1)
-        {
-          UString baseName;
-          {
-            NCOM::CPropVariant prop;
-            RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
-            if (prop.vt != VT_BSTR)
-              break;
-            baseName = prop.bstrVal;
-          }
-          seqName.InitName(baseName);
-        }
-
-        UString fullName = seqName.GetNextName();
-        HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
-        if (result == S_FALSE)
-          break;
-        if (result != S_OK)
-          return result;
-        if (!stream)
-          break;
-      }
-      else
-        inStream = stream;
-
-      CInArchive archive;
-      RINOK(archive.Open(inStream, maxCheckStartPosition));
-
-      _volumes.Add(CVolume());
-      CVolume &volume = _volumes.Back();
-      CArchiveDatabaseEx &database = volume.Database;
-      volume.Stream = inStream;
-      volume.StartRef2Index = _refs.Size();
-
-      HRESULT result = archive.ReadDatabase(database
-          #ifndef _NO_CRYPTO
-          , getTextPassword
-          #endif
-          );
-      if (result != S_OK)
-      {
-        _volumes.Clear();
-        return result;
-      }
-      database.Fill();
-      for(int i = 0; i < database.Files.Size(); i++)
-      {
-        CRef refNew;
-        refNew.VolumeIndex = _volumes.Size() - 1;
-        refNew.ItemIndex = i;
-        _refs.Add(refNew);
-        /*
-        const CFileItem &file = database.Files[i];
-        int j;
-        */
-        /*
-        for (j = _refs.Size() - 1; j >= 0; j--)
-        {
-          CRef2 &ref2 = _refs[j];
-          const CRef &ref = ref2.Refs.Back();
-          const CVolume &volume2 = _volumes[ref.VolumeIndex];
-          const CArchiveDatabaseEx &database2 = volume2.Database;
-          const CFileItem &file2 = database2.Files[ref.ItemIndex];
-          if (file2.Name.CompareNoCase(file.Name) == 0)
-          {
-            if (!file.IsStartPosDefined)
-              continue;
-            if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
-              continue;
-            ref2.Refs.Add(refNew);
-            break;
-          }
-        }
-        */
-        /*
-        j = -1;
-        if (j < 0)
-        {
-          CRef2 ref2New;
-          ref2New.Refs.Add(refNew);
-          j = _refs.Add(ref2New);
-        }
-        CRef2 &ref2 = _refs[j];
-        ref2.UnPackSize += file.UnPackSize;
-        ref2.PackSize += database.GetFilePackSize(i);
-        if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
-          ref2.StartPos = file.StartPos;
-        */
-      }
-      if (database.Files.Size() != 1)
-        break;
-      const CFileItem &file = database.Files.Front();
-      if (!file.IsStartPosDefined)
-        break;
-    }
-    #else
-    CInArchive archive;
-    RINOK(archive.Open(stream, maxCheckStartPosition));
-    HRESULT result = archive.ReadDatabase(
-      EXTERNAL_CODECS_VARS
-      _database
-      #ifndef _NO_CRYPTO
-      , getTextPassword
-      #endif
-      );
-    RINOK(result);
-    _database.Fill();
-    _inStream = stream;
-    #endif
-  }
-  catch(...)
-  {
-    Close();
-    return S_FALSE;
-  }
-  // _inStream = stream;
-  #ifndef _SFX
-  FillPopIDs();
-  #endif
-  return S_OK;
-  COM_TRY_END
-}
-
-STDMETHODIMP CHandler::Close()
-{
-  COM_TRY_BEGIN
-  #ifdef _7Z_VOL
-  _volumes.Clear();
-  _refs.Clear();
-  #else
-  _inStream.Release();
-  _database.Clear();
-  #endif
-  return S_OK;
-  COM_TRY_END
-}
-
-#ifdef _7Z_VOL
-STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
-{
-  if (index != 0)
-    return E_INVALIDARG;
-  *stream = 0;
-  CMultiStream *streamSpec = new CMultiStream;
-  CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
-  
-  UInt64 pos = 0;
-  const UString *fileName;
-  for (int i = 0; i < _refs.Size(); i++)
-  {
-    const CRef &ref = _refs[i];
-    const CVolume &volume = _volumes[ref.VolumeIndex];
-    const CArchiveDatabaseEx &database = volume.Database;
-    const CFileItem &file = database.Files[ref.ItemIndex];
-    if (i == 0)
-      fileName = &file.Name;
-    else
-      if (fileName->Compare(file.Name) != 0)
-        return S_FALSE;
-    if (!file.IsStartPosDefined)
-      return S_FALSE;
-    if (file.StartPos != pos)
-      return S_FALSE;
-    CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
-    if (folderIndex == kNumNoIndex)
-    {
-      if (file.UnPackSize != 0)
-        return E_FAIL;
-      continue;
-    }
-    if (database.NumUnPackStreamsVector[folderIndex] != 1)
-      return S_FALSE;
-    const CFolder &folder = database.Folders[folderIndex];
-    if (folder.Coders.Size() != 1)
-      return S_FALSE;
-    const CCoderInfo &coder = folder.Coders.Front();
-    if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
-      return S_FALSE;
-    if (coder.MethodID != k_Copy)
-      return S_FALSE;
-
-    pos += file.UnPackSize;
-    CMultiStream::CSubStreamInfo subStreamInfo;
-    subStreamInfo.Stream = volume.Stream;
-    subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
-    subStreamInfo.Size = file.UnPackSize;
-    streamSpec->Streams.Add(subStreamInfo);
-  }
-  streamSpec->Init();
-  *stream = streamTemp.Detach();
-  return S_OK;
-}
-#endif
-
-
-#ifdef __7Z_SET_PROPERTIES
-#ifdef EXTRACT_ONLY
-
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
-{
-  COM_TRY_BEGIN
-  #ifdef COMPRESS_MT
-  const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
-  _numThreads = numProcessors;
-  #endif
-
-  for (int i = 0; i < numProperties; i++)
-  {
-    UString name = names[i];
-    name.MakeUpper();
-    if (name.IsEmpty())
-      return E_INVALIDARG;
-    const PROPVARIANT &value = values[i];
-    UInt32 number;
-    int index = ParseStringToUInt32(name, number);
-    if (index == 0)
-    {
-      if(name.Left(2).CompareNoCase(L"MT") == 0)
-      {
-        #ifdef COMPRESS_MT
-        RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
-        #endif
-        continue;
-      }
-      else
-        return E_INVALIDARG;
-    }
-  }
-  return S_OK;
-  COM_TRY_END
-}  
-
-#endif
-#endif
-
-IMPL_ISetCompressCodecsInfo
-
-}}