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

📄 x86_2.cpp

📁 sleuthit-2.09 一个磁盘的工具集
💻 CPP
字号:
// x86_2.cpp#include "StdAfx.h"#include "x86_2.h"#include "../../../Common/Alloc.h"static const int kBufferSize = 1 << 17;inline bool IsJcc(Byte b0, Byte b1){  return (b0 == 0x0F && (b1 & 0xF0) == 0x80);}#ifndef EXTRACT_ONLYstatic bool inline Test86MSByte(Byte b){  return (b == 0 || b == 0xFF);}bool CBCJ2_x86_Encoder::Create(){  if (!_mainStream.Create(1 << 16))    return false;  if (!_callStream.Create(1 << 20))    return false;  if (!_jumpStream.Create(1 << 20))    return false;  if (!_rangeEncoder.Create(1 << 20))    return false;  if (_buffer == 0)  {    _buffer = (Byte *)MidAlloc(kBufferSize);    if (_buffer == 0)      return false;  }  return true;}CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder(){  ::MidFree(_buffer);}HRESULT CBCJ2_x86_Encoder::Flush(){  RINOK(_mainStream.Flush());  RINOK(_callStream.Flush());  RINOK(_jumpStream.Flush());  _rangeEncoder.FlushData();  return _rangeEncoder.FlushStream();}const UInt32 kDefaultLimit = (1 << 24);HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,      const UInt64 **inSizes,      UInt32 numInStreams,      ISequentialOutStream **outStreams,      const UInt64 **outSizes,      UInt32 numOutStreams,      ICompressProgressInfo *progress){  if (numInStreams != 1 || numOutStreams != 4)    return E_INVALIDARG;  if (!Create())    return E_OUTOFMEMORY;  bool sizeIsDefined = false;  UInt64 inSize;  if (inSizes != NULL)    if (inSizes[0] != NULL)    {      inSize = *inSizes[0];      if (inSize <= kDefaultLimit)        sizeIsDefined = true;    }  ISequentialInStream *inStream = inStreams[0];  _mainStream.SetStream(outStreams[0]);  _mainStream.Init();  _callStream.SetStream(outStreams[1]);  _callStream.Init();  _jumpStream.SetStream(outStreams[2]);  _jumpStream.Init();  _rangeEncoder.SetStream(outStreams[3]);  _rangeEncoder.Init();  for (int i = 0; i < 256; i++)    _statusE8Encoder[i].Init();  _statusE9Encoder.Init();  _statusJccEncoder.Init();  CCoderReleaser releaser(this);  CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;  {    inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);  }  UInt32 nowPos = 0;  UInt64 nowPos64 = 0;  UInt32 bufferPos = 0;  Byte prevByte = 0;  UInt64 subStreamIndex = 0;  UInt64 subStreamStartPos  = 0;  UInt64 subStreamEndPos = 0;  while(true)  {    UInt32 processedSize = 0;    while(true)    {      UInt32 size = kBufferSize - (bufferPos + processedSize);      UInt32 processedSizeLoc;      if (size == 0)        break;      RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));      if (processedSizeLoc == 0)        break;      processedSize += processedSizeLoc;    }    UInt32 endPos = bufferPos + processedSize;        if (endPos < 5)    {      // change it       for (bufferPos = 0; bufferPos < endPos; bufferPos++)      {        Byte b = _buffer[bufferPos];        _mainStream.WriteByte(b);        if (b == 0xE8)          _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);        else if (b == 0xE9)          _statusE9Encoder.Encode(&_rangeEncoder, 0);        else if (IsJcc(prevByte, b))          _statusJccEncoder.Encode(&_rangeEncoder, 0);        prevByte = b;      }      return Flush();    }    bufferPos = 0;    UInt32 limit = endPos - 5;    while(bufferPos <= limit)    {      Byte b = _buffer[bufferPos];      _mainStream.WriteByte(b);      if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))      {        bufferPos++;        prevByte = b;        continue;      }      Byte nextByte = _buffer[bufferPos + 4];      UInt32 src =         (UInt32(nextByte) << 24) |        (UInt32(_buffer[bufferPos + 3]) << 16) |        (UInt32(_buffer[bufferPos + 2]) << 8) |        (_buffer[bufferPos + 1]);      UInt32 dest = (nowPos + bufferPos + 5) + src;      // if (Test86MSByte(nextByte))      bool convert;      if (getSubStreamSize != NULL)      {        UInt64 currentPos = (nowPos64 + bufferPos);        while (subStreamEndPos < currentPos)        {          UInt64 subStreamSize;          HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);          if (result == S_OK)          {            subStreamStartPos = subStreamEndPos;            subStreamEndPos += subStreamSize;                      subStreamIndex++;          }          else if (result == S_FALSE || result == E_NOTIMPL)          {            getSubStreamSize.Release();            subStreamStartPos = 0;            subStreamEndPos = subStreamStartPos - 1;                    }          else            return result;        }        if (getSubStreamSize == NULL)        {          if (sizeIsDefined)            convert = (dest < inSize);          else            convert = Test86MSByte(nextByte);        }        else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)          convert = Test86MSByte(nextByte);        else        {          UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));          convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);        }      }      else if (sizeIsDefined)        convert = (dest < inSize);      else        convert = Test86MSByte(nextByte);      if (convert)      {        if (b == 0xE8)          _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1);        else if (b == 0xE9)          _statusE9Encoder.Encode(&_rangeEncoder, 1);        else           _statusJccEncoder.Encode(&_rangeEncoder, 1);        bufferPos += 5;        if (b == 0xE8)        {          _callStream.WriteByte((Byte)(dest >> 24));          _callStream.WriteByte((Byte)(dest >> 16));          _callStream.WriteByte((Byte)(dest >> 8));          _callStream.WriteByte((Byte)(dest));        }        else         {          _jumpStream.WriteByte((Byte)(dest >> 24));          _jumpStream.WriteByte((Byte)(dest >> 16));          _jumpStream.WriteByte((Byte)(dest >> 8));          _jumpStream.WriteByte((Byte)(dest));        }        prevByte = nextByte;      }      else      {        if (b == 0xE8)          _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);        else if (b == 0xE9)          _statusE9Encoder.Encode(&_rangeEncoder, 0);        else          _statusJccEncoder.Encode(&_rangeEncoder, 0);        bufferPos++;        prevByte = b;      }    }    nowPos += bufferPos;    nowPos64 += bufferPos;    if (progress != NULL)    {      RINOK(progress->SetRatioInfo(&nowPos64, NULL));    }     UInt32 i = 0;    while(bufferPos < endPos)      _buffer[i++] = _buffer[bufferPos++];    bufferPos = i;  }}STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,      const UInt64 **inSizes,      UInt32 numInStreams,      ISequentialOutStream **outStreams,      const UInt64 **outSizes,      UInt32 numOutStreams,      ICompressProgressInfo *progress){  try  {    return CodeReal(inStreams, inSizes, numInStreams,      outStreams, outSizes,numOutStreams, progress);  }  catch(const COutBufferException &e) { return e.ErrorCode; }  catch(...) { return S_FALSE; }}#endifHRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,      const UInt64 **inSizes,      UInt32 numInStreams,      ISequentialOutStream **outStreams,      const UInt64 **outSizes,      UInt32 numOutStreams,      ICompressProgressInfo *progress){  if (numInStreams != 4 || numOutStreams != 1)    return E_INVALIDARG;  if (!_mainInStream.Create(1 << 16))    return E_OUTOFMEMORY;  if (!_callStream.Create(1 << 20))    return E_OUTOFMEMORY;  if (!_jumpStream.Create(1 << 16))    return E_OUTOFMEMORY;  if (!_rangeDecoder.Create(1 << 20))    return E_OUTOFMEMORY;  if (!_outStream.Create(1 << 16))    return E_OUTOFMEMORY;  _mainInStream.SetStream(inStreams[0]);  _callStream.SetStream(inStreams[1]);  _jumpStream.SetStream(inStreams[2]);  _rangeDecoder.SetStream(inStreams[3]);  _outStream.SetStream(outStreams[0]);  _mainInStream.Init();  _callStream.Init();  _jumpStream.Init();  _rangeDecoder.Init();  _outStream.Init();  for (int i = 0; i < 256; i++)    _statusE8Decoder[i].Init();  _statusE9Decoder.Init();  _statusJccDecoder.Init();  CCoderReleaser releaser(this);  Byte prevByte = 0;  UInt32 processedBytes = 0;  while(true)  {    if (processedBytes > (1 << 20) && progress != NULL)    {      UInt64 nowPos64 = _outStream.GetProcessedSize();      RINOK(progress->SetRatioInfo(NULL, &nowPos64));      processedBytes = 0;    }    processedBytes++;    Byte b;    if (!_mainInStream.ReadByte(b))      return Flush();    _outStream.WriteByte(b);    if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))    {      prevByte = b;      continue;    }    bool status;    if (b == 0xE8)      status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1);    else if (b == 0xE9)      status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1);    else      status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);    if (status)    {      UInt32 src;      if (b == 0xE8)      {        Byte b0;        if(!_callStream.ReadByte(b0))          return S_FALSE;        src = ((UInt32)b0) << 24;        if(!_callStream.ReadByte(b0))          return S_FALSE;        src |= ((UInt32)b0) << 16;        if(!_callStream.ReadByte(b0))          return S_FALSE;        src |= ((UInt32)b0) << 8;        if(!_callStream.ReadByte(b0))          return S_FALSE;        src |= ((UInt32)b0);      }      else      {        Byte b0;        if(!_jumpStream.ReadByte(b0))          return S_FALSE;        src = ((UInt32)b0) << 24;        if(!_jumpStream.ReadByte(b0))          return S_FALSE;        src |= ((UInt32)b0) << 16;        if(!_jumpStream.ReadByte(b0))          return S_FALSE;        src |= ((UInt32)b0) << 8;        if(!_jumpStream.ReadByte(b0))          return S_FALSE;        src |= ((UInt32)b0);      }      UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;      _outStream.WriteByte((Byte)(dest));      _outStream.WriteByte((Byte)(dest >> 8));      _outStream.WriteByte((Byte)(dest >> 16));      _outStream.WriteByte((Byte)(dest >> 24));      prevByte = (dest >> 24);      processedBytes += 4;    }    else      prevByte = b;  }}STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,      const UInt64 **inSizes,      UInt32 numInStreams,      ISequentialOutStream **outStreams,      const UInt64 **outSizes,      UInt32 numOutStreams,      ICompressProgressInfo *progress){  try  {    return CodeReal(inStreams, inSizes, numInStreams,        outStreams, outSizes,numOutStreams, progress);  }  catch(const COutBufferException &e) { return e.ErrorCode; }  catch(...) { return S_FALSE; }}

⌨️ 快捷键说明

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