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

📄 main.cpp

📁 7z一个高压缩比的压缩程序源代码,重要的是里面的算法值得学习
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Test Align for updating !!!!!!!!!!!!!!!!!!

#include "StdAfx.h"

// #include <locale.h>
#include <initguid.h>

#include "Plugin.h"

#include "Common/Wildcard.h"
#include "Common/DynamicBuffer.h"
#include "Common/StringConvert.h"
#include "Common/Defs.h"

#include "Windows/FileFind.h"
#include "Windows/FileIO.h"
#include "Windows/FileDir.h"
#include "Windows/Defs.h"

#include "../../IPassword.h"
#include "../../Common/FileStreams.h"

#include "../Common/DefaultName.h"
#include "../Common/OpenArchive.h"
#include "../Agent/Agent.h"

#include "ProgressBox.h"
#include "FarUtils.h"
#include "Messages.h"

using namespace NWindows;
using namespace NFar;

static const char *kCommandPrefix = "7-zip";

static const char *kRegisrtryMainKeyName = "";

static const char *kRegisrtryValueNameEnabled = "UsedByDefault3";
static bool kPluginEnabledDefault = true;

static const char *kHelpTopicConfig =  "Config";

extern "C"
{
  void WINAPI SetStartupInfo(struct PluginStartupInfo *info);
  HANDLE WINAPI OpenFilePlugin(char *name, const unsigned char *Data,
      unsigned int DataSize);
  HANDLE WINAPI OpenPlugin(int openFrom, int item);
  void WINAPI ClosePlugin(HANDLE plugin);
  int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelItems,
      int *itemsNumber, int OpMode);
  void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems,
    int itemsNumber);
  int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems,
    int itemsNumber, int move, char *destPath, int opMode);
  int WINAPI SetDirectory(HANDLE plugin, char *dir, int opMode);
  void WINAPI GetPluginInfo(struct PluginInfo *info);
  int WINAPI Configure(int itemNumber);
  void WINAPI GetOpenPluginInfo(HANDLE plugin, struct OpenPluginInfo *info);
  int WINAPI PutFiles(HANDLE plugin, struct PluginPanelItem *panelItems,
      int itemsNumber, int move, int opMode);
  int WINAPI DeleteFiles(HANDLE plugin, PluginPanelItem *panelItems,
      int itemsNumber, int opMode);
  int WINAPI ProcessKey(HANDLE plugin, int key, unsigned int controlState);
};

HINSTANCE g_hInstance;
#ifndef _UNICODE
bool g_IsNT = false;
static bool IsItWindowsNT()
{
  OSVERSIONINFO versionInfo;
  versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
  if (!::GetVersionEx(&versionInfo))
    return false;
  return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
#endif

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
{
  if (dwReason == DLL_PROCESS_ATTACH)
  {
    g_hInstance = hInstance;
    #ifndef _UNICODE
    g_IsNT = IsItWindowsNT();
    #endif
  }
  return TRUE;
}

static struct COptions
{
  bool Enabled;
} g_Options;

static const char *kPliginNameForRegestry = "7-ZIP";

void WINAPI SetStartupInfo(struct PluginStartupInfo *info)
{
  MY_TRY_BEGIN;
  g_StartupInfo.Init(*info, kPliginNameForRegestry);
  g_Options.Enabled = g_StartupInfo.QueryRegKeyValue(
      HKEY_CURRENT_USER, kRegisrtryMainKeyName,
      kRegisrtryValueNameEnabled, kPluginEnabledDefault);
  MY_TRY_END1("SetStartupInfo");
}

class COpenArchiveCallback:
  public IArchiveOpenCallback,
  public IArchiveOpenVolumeCallback,
  public IProgress,
  public ICryptoGetTextPassword,
  public CMyUnknownImp
{
  DWORD m_StartTickValue;
  bool m_MessageBoxIsShown;

  CProgressBox _progressBox;

  UInt64 _numFilesTotal;
  UInt64 _numFilesCur;
  UInt64 _numBytesTotal;
  UInt64 _numBytesCur;

  bool _numFilesTotalDefined;
  bool _numFilesCurDefined;
  bool _numBytesTotalDefined;
  bool _numBytesCurDefined;

  DWORD m_PrevTickCount;

  NWindows::NFile::NFind::CFileInfoW _fileInfo;
public:
  bool PasswordIsDefined;
  UString Password;

  UString _folderPrefix;

public:
  MY_UNKNOWN_IMP3(
     IArchiveOpenVolumeCallback,
     IProgress,
     ICryptoGetTextPassword
    )

  // IProgress
  STDMETHOD(SetTotal)(UInt64 total);
  STDMETHOD(SetCompleted)(const UInt64 *aCompleteValue);

  // IArchiveOpenCallback
  STDMETHOD(SetTotal)(const UInt64 *numFiles, const UInt64 *numBytes);
  STDMETHOD(SetCompleted)(const UInt64 *numFiles, const UInt64 *numBytes);

  // IArchiveOpenVolumeCallback
  STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
  STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);

  // ICryptoGetTextPassword
  STDMETHOD(CryptoGetTextPassword)(BSTR *password);

  void Init()
  {
    PasswordIsDefined = false;

    _numFilesTotalDefined = false;
    _numFilesCurDefined = false;
    _numBytesTotalDefined = false;
    _numBytesCurDefined = false;

    m_MessageBoxIsShown = false;
    m_PrevTickCount = GetTickCount();
  }
  void ShowMessage();

  void LoadFileInfo(const UString &folderPrefix,
      const UString &fileName)
  {
    _folderPrefix = folderPrefix;
    if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
      throw 1;
  }
};

void COpenArchiveCallback::ShowMessage()
{
  DWORD currentTime = GetTickCount();
  if (!m_MessageBoxIsShown)
  {
    if (currentTime - m_PrevTickCount < 100)
      return;
    _progressBox.Init(
        // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
        g_StartupInfo.GetMsgString(NMessageID::kReading), 48);

    m_MessageBoxIsShown = true;
  }
  else
  {
    if (currentTime - m_PrevTickCount < 200)
      return;
  }
  m_PrevTickCount = currentTime;

  UInt64 total = 0, cur = 0;
  bool curIsDefined = false, totalIsDefined = false;

  char message[256] = { 0 };
  if (_numFilesCurDefined)
    ConvertUInt64ToStringAligned(_numFilesCur, message, 5);

  if (_numFilesTotalDefined)
  {
    strcat(message, " / ");
    ConvertUInt64ToStringAligned(_numFilesTotal, message + strlen(message), 5);
    total = _numFilesTotal;
    totalIsDefined = true;
    if (_numFilesCurDefined)
    {
      cur = _numFilesCur;
      curIsDefined = true;
    }
  }
  else if (_numBytesTotalDefined)
  {
    total = _numBytesTotal;
    totalIsDefined = true;
    if (_numBytesCurDefined)
    {
      cur = _numBytesCur;
      curIsDefined = true;
    }
  }
  _progressBox.Progress(
      totalIsDefined ? &total: NULL,
      curIsDefined ? &cur: NULL,
      message);
}

STDMETHODIMP COpenArchiveCallback::SetTotal(const UInt64 *numFiles, const UInt64 *numBytes)
{
  if (WasEscPressed())
    return E_ABORT;
  
  _numFilesTotalDefined = (numFiles != NULL);
  if (_numFilesTotalDefined)
    _numFilesTotal = *numFiles;

  _numBytesTotalDefined = (numBytes != NULL);
  if (_numBytesTotalDefined)
    _numBytesTotal = *numBytes;

  return S_OK;
}

STDMETHODIMP COpenArchiveCallback::SetCompleted(const UInt64 *numFiles, const UInt64 *numBytes)
{
  if (WasEscPressed())
    return E_ABORT;

  _numFilesCurDefined = (numFiles != NULL);
  if (_numFilesCurDefined)
    _numFilesCur = *numFiles;

  _numBytesCurDefined = (numBytes != NULL);
  if (_numBytesCurDefined)
    _numBytesCur = *numBytes;

  // if (*numFiles % 100 != 0)
  //   return S_OK;
  ShowMessage();
  return S_OK;
}


STDMETHODIMP COpenArchiveCallback::SetTotal(const UInt64 /* total */)
{
  if (WasEscPressed())
    return E_ABORT;
  return S_OK;
}

STDMETHODIMP COpenArchiveCallback::SetCompleted(const UInt64 *completed)
{
  if (WasEscPressed())
    return E_ABORT;
  if (completed == NULL)
    return S_OK;
  ShowMessage();
  return S_OK;
}

STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name,
    IInStream **inStream)
{
  if (WasEscPressed())
    return E_ABORT;
  *inStream = NULL;
  UString fullPath = _folderPrefix + name;
  if (!NWindows::NFile::NFind::FindFile(fullPath, _fileInfo))
    return S_FALSE;
  if (_fileInfo.IsDir())
    return S_FALSE;
  CInFileStream *inFile = new CInFileStream;
  CMyComPtr<IInStream> inStreamTemp = inFile;
  if (!inFile->Open(fullPath))
    return ::GetLastError();
  *inStream = inStreamTemp.Detach();
  return S_OK;
}


STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value)
{
  NWindows::NCOM::CPropVariant prop;
  switch(propID)
  {

⌨️ 快捷键说明

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