⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nsisin.cpp

📁 著名的7zip的压缩算法,压缩比最高,但是压缩时间也比较长!
💻 CPP
📖 第 1 页 / 共 3 页
字号:

      /*
      case EW_SENDMESSAGE:
      {
        Script += " ";
        Script += IntToString(e.Params[0]);
        Script += " ";
        Script += GetVar(e.Params[1]);
        Script += " ";
        Script += ReadString2(e.Params[2]);
        Script += " ";
        Script += UIntToString(e.Params[3]);
        Script += " ";
        Script += IntToString(e.Params[4]);
        Script += " ";
        Script += UIntToString(e.Params[5]);
        break;
      }
      */

      case EW_REGISTERDLL:
      {
        Script += " ";
        Script += ReadString2(e.Params[0]);
        Script += " ";
        Script += ReadString2(e.Params[1]);
        Script += " ";
        Script += UIntToString(e.Params[2]);
        break;
      }

      case EW_CREATESHORTCUT:
      {
        AString s;

        Script += " ";
        Script += " \"";
        Script += ReadString2(e.Params[0]);
        Script += " \"";

        Script += " ";
        Script += " \"";
        Script += ReadString2(e.Params[1]);
        Script += " \"";

        for (int j = 2; j < 5; j++)
        {
          Script += " ";
          Script += UIntToString(e.Params[j]);
        }
        break;
      }

      /*
      case EW_DELREG:
      {
        AString keyName, valueName;
        keyName = ReadString2(e.Params[1]);
        bool isValue = (e.Params[2] != -1);
        if (isValue)
        {
          valueName = ReadString2(e.Params[2]);
          Script += "Key";
        }
        else
          Script += "Value";
        Script += " ";
        Script += UIntToString(e.Params[0]);
        Script += " ";
        Script += keyName;
        if (isValue)
        {
          Script += " ";
          Script += valueName;
        }
        Script += " ";
        Script += UIntToString(e.Params[3]);
        break;
      }
      */

      case EW_WRITEUNINSTALLER:
      {
        Script += " ";
        Script += ReadString2(e.Params[0]);
        for (int j = 1; j < 3; j++)
        {
          Script += " ";
          Script += UIntToString(e.Params[j]);
        }
        break;
      }

      default:
      {
        int numParams = kNumEntryParams;
        if (e.Which < sizeof(kCommandPairs) / sizeof(kCommandPairs[0]))
        {
          const CCommandPair &pair = kCommandPairs[e.Which];
          // Script += pair.Name;
          numParams = pair.NumParams;
        }
        else
        {
          Script += "Unknown";
          Script += UIntToString(e.Which);
        }
        Script += e.GetParamsString(numParams);
      }
      #endif
    }
    #ifdef NSIS_SCRIPT
    Script += kCrLf;
    #endif
  }

  {
    Items.Sort(CompareItems, 0);
    int i;
    for (i = 0; i + 1 < Items.Size();)
    {
      if (Items[i].Pos == Items[i + 1].Pos)
        Items.Delete(i + 1);
      else
        i++;
    }
    for (i = 0; i + 1 < Items.Size(); i++)
    {
      CItem &item = Items[i];
      item.EstimatedSizeIsDefined = true;
      item.EstimatedSize = Items[i + 1].Pos - item.Pos - 4;
    }
    if (!IsSolid)
    {
      for (i = 0; i < Items.Size(); i++)
      {
        CItem &item = Items[i];
        RINOK(_stream->Seek(GetPosOfNonSolidItem(i), STREAM_SEEK_SET, NULL));
        const UInt32 kSigSize = 4 + 1 + 5;
        BYTE sig[kSigSize];
        UInt32 processedSize;
        RINOK(ReadStream(_stream, sig, kSigSize, &processedSize));
        if (processedSize < 4)
          return S_FALSE;
        UInt32 size = GetUInt32FromMemLE(sig);
        if ((size & 0x80000000) != 0)
        {
          item.IsCompressed = true;
          // is compressed;
          size &= ~0x80000000;
          if (Method == NMethodType::kLZMA)
          {
            if (processedSize < 9)
              return S_FALSE;
            if (FilterFlag)
              item.UseFilter = (sig[4] != 0);
            item.DictionarySize = GetUInt32FromMemLE(sig + 5 + (FilterFlag ? 1 : 0));
          }
        }
        else
        {
          item.IsCompressed = false;
          item.Size = size;
          item.SizeIsDefined = true;
        }
        item.CompressedSize = size;
        item.CompressedSizeIsDefined = true;
      }
    }
  }
  return S_OK;
}

HRESULT CInArchive::Parse()
{
  // UInt32 offset = ReadUInt32();
  // ???? offset == FirstHeader.HeaderLength
  UInt32 ehFlags = ReadUInt32();
  CBlockHeader bhPages, bhSections, bhEntries, bhStrings, bhLangTables, bhCtlColors, bhData;
  // CBlockHeader bgFont;
  ReadBlockHeader(bhPages);
  ReadBlockHeader(bhSections);
  ReadBlockHeader(bhEntries);
  ReadBlockHeader(bhStrings);
  ReadBlockHeader(bhLangTables);
  ReadBlockHeader(bhCtlColors);
  // ReadBlockHeader(bgFont);
  ReadBlockHeader(bhData);

  _stringsPos = bhStrings.Offset;

  return ReadEntries(bhEntries);
}

static bool IsLZMA(const Byte *p, UInt32 &dictionary)
{
  dictionary = GetUInt32FromMemLE(p + 1);
  return (p[0] == 0x5D && p[1] == 0x00 && p[2] == 0x00 && p[5] == 0x00);
}

static bool IsLZMA(const Byte *p, UInt32 &dictionary, bool &thereIsFlag)
{
  if (IsLZMA(p, dictionary))
  {
    thereIsFlag = false;
    return true;
  }
  if (IsLZMA(p + 1, dictionary))
  {
    thereIsFlag = true;
    return true;
  }
  return false;
}

HRESULT CInArchive::Open2()
{
  RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &StreamOffset));

  const UInt32 kSigSize = 4 + 1 + 5 + 1; // size, flag, lzma props, lzma first byte
  BYTE sig[kSigSize];
  UInt32 processedSize;
  RINOK(ReadStream(_stream, sig, kSigSize, &processedSize));
  if (processedSize != kSigSize)
    return S_FALSE;
  UInt64 position;
  RINOK(_stream->Seek(StreamOffset, STREAM_SEEK_SET, &position));

  _headerIsCompressed = true;
  IsSolid = true;
  FilterFlag = false;

  UInt32 compressedHeaderSize = GetUInt32FromMemLE(sig);
  
  if (compressedHeaderSize == FirstHeader.HeaderLength)
  {
    _headerIsCompressed = false;
    IsSolid = false;
    Method = NMethodType::kCopy;
  }
  else if (IsLZMA(sig, DictionarySize, FilterFlag))
  {
    Method = NMethodType::kLZMA;
  }
  else if (IsLZMA(sig + 4, DictionarySize, FilterFlag))
  {
    IsSolid = false;
    Method = NMethodType::kLZMA;
  }
  else if (sig[3] == 0x80)
  {
    IsSolid = false;
    Method = NMethodType::kDeflate;
  }
  else
  {
    Method = NMethodType::kDeflate;
  }

  _posInData = 0;
  if (!IsSolid)
  {
    if (_headerIsCompressed = ((compressedHeaderSize & 0x80000000) != 0))
      compressedHeaderSize &= ~0x80000000;
    _nonSolidStartOffset = compressedHeaderSize;
    RINOK(_stream->Seek(StreamOffset + 4, STREAM_SEEK_SET, NULL));
  }
  UInt32 unpackSize = FirstHeader.HeaderLength;
  if (_headerIsCompressed)
  {
    // unpackSize = (1 << 23);
    _data.SetCapacity(unpackSize);
    RINOK(Decoder.Init(_stream, Method, FilterFlag, UseFilter));
    UInt32 processedSize;
    RINOK(Decoder.Read(_data, unpackSize, &processedSize));
    if (processedSize != unpackSize)
      return S_FALSE;
    _size = (size_t)processedSize;
    if (IsSolid)
    {
      UInt32 size2 = ReadUInt32();
      if (size2 < _size)
        _size = size2;
    }
  }
  else
  {
    _data.SetCapacity(unpackSize);
    _size = (size_t)unpackSize;
    RINOK(ReadStream(_stream, (Byte *)_data, unpackSize, &processedSize));
    if (processedSize != unpackSize)
      return S_FALSE;
  }
  return Parse();
}

/*
NsisExe = 
{
  ExeStub
  Archive  // must start from 512 * N
  #ifndef NSIS_CONFIG_CRC_ANAL
  {
    Some additional data
  }
}

Archive
{
  FirstHeader
  Data
  #ifdef NSIS_CONFIG_CRC_SUPPORT && FirstHeader.ThereIsCrc()
  {
    CRC
  }
}

FirstHeader
{
  UInt32 Flags;
  Byte Signature[16];
  // points to the header+sections+entries+stringtable in the datablock
  UInt32 HeaderLength;
  UInt32 ArchiveSize;
}
*/

HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition)
{
  Clear();
  UInt64 pos;
  RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &pos));
  RINOK(inStream->Seek(0, STREAM_SEEK_END, &_archiveSize));
  UInt64 position;
  RINOK(inStream->Seek(pos, STREAM_SEEK_SET, &position));
  UInt64 maxSize = (maxCheckStartPosition != 0) ? *maxCheckStartPosition : (1 << 20);
  const UInt32 kStep = 512;
  const UInt32 kStartHeaderSize = 4 * 7;
  Byte buffer[kStep];
  bool found = false;
  
  UInt64 headerPosition;
  while (position <= maxSize)
  {
    UInt32 processedSize;
    RINOK(ReadStream(inStream, buffer, kStartHeaderSize, &processedSize));
    if (processedSize != kStartHeaderSize)
      return S_FALSE;
    headerPosition = position;
    position += processedSize;
    if(memcmp(buffer + 4, kSignature, kSignatureSize) == 0)
    {
      found = true;
      break;
    }
    const UInt32 kRem = kStep - kStartHeaderSize;
    RINOK(ReadStream(inStream, buffer + kStartHeaderSize, kRem, &processedSize));
    if (processedSize != kRem)
      return S_FALSE;
    position += processedSize;
  }
  if (!found)
    return S_FALSE;
  FirstHeader.Flags = GetUInt32FromMemLE(buffer);
  FirstHeader.HeaderLength = GetUInt32FromMemLE(buffer + kSignatureSize + 4);
  FirstHeader.ArchiveSize = GetUInt32FromMemLE(buffer + kSignatureSize + 8);
  if (_archiveSize - headerPosition < FirstHeader.ArchiveSize)
    return S_FALSE;

  _stream = inStream;
  HRESULT res = S_FALSE;
  try { res = Open2(); }
  catch(...) { Clear(); res = S_FALSE; }
  _stream.Release();
  return res;
}

void CInArchive::Clear()
{
  #ifdef NSIS_SCRIPT
  Script.Empty();
  #endif
  Items.Clear();
}

}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -