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

📄 list.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
字号:
// List.cpp#include "StdAfx.h"#include "List.h"#include "ConsoleClose.h"#include "Common/StringConvert.h"#include "Common/StdOutStream.h"#include "Common/IntToString.h"#include "Common/MyCom.h"#include "Windows/PropVariant.h"#include "Windows/Defs.h"#include "Windows/PropVariantConversions.h"#include "Windows/FileDir.h"#include "../../Archive/IArchive.h"#include "../Common/PropIDUtils.h"#include "../Common/OpenArchive.h"#include "OpenCallbackConsole.h"using namespace NWindows;struct CPropIdToName{  PROPID PropID;  const wchar_t *Name;};static CPropIdToName kPropIdToName[] =  {  { kpidPath, L"Path" },  { kpidName, L"Name" },  { kpidIsFolder, L"Folder" },   { kpidSize, L"Size" },  { kpidPackedSize, L"Packed Size" },  { kpidAttributes, L"Attributes" },  { kpidCreationTime, L"Created" },  { kpidLastAccessTime, L"Accessed" },  { kpidLastWriteTime, L"Modified" },  { kpidSolid, L"Solid" },  { kpidCommented, L"Commented" },  { kpidEncrypted, L"Encrypted" },  { kpidSplitBefore, L"Split Before" },  { kpidSplitAfter, L"Split After" },  { kpidDictionarySize, L"Dictionary Size" },  { kpidCRC, L"CRC" },  { kpidType, L"Type" },  { kpidIsAnti, L"Anti" },  { kpidMethod, L"Method" },  { kpidHostOS, L"Host OS" },  { kpidFileSystem, L"File System" },  { kpidUser, L"User" },  { kpidGroup, L"Group" },  { kpidBlock, L"Block" },  { kpidComment, L"Comment" },  { kpidPosition, L"Position" }};static const char kEmptyAttributeChar = '.';static const char kDirectoryAttributeChar = 'D';static const char kReadonlyAttributeChar  = 'R';static const char kHiddenAttributeChar    = 'H';static const char kSystemAttributeChar    = 'S';static const char kArchiveAttributeChar   = 'A';static const char *kListing = "Listing archive: ";static const wchar_t *kFilesMessage = L"files";static void GetAttributesString(DWORD wa, bool directory, char *s){  s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ?       kDirectoryAttributeChar: kEmptyAttributeChar;  s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)?       kReadonlyAttributeChar: kEmptyAttributeChar;  s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ?       kHiddenAttributeChar: kEmptyAttributeChar;  s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ?       kSystemAttributeChar: kEmptyAttributeChar;  s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ?       kArchiveAttributeChar: kEmptyAttributeChar;  s[5] = '\0';}enum EAdjustment{  kLeft,  kCenter,  kRight};struct CFieldInfo{  PROPID PropID;  UString Name;  EAdjustment TitleAdjustment;  EAdjustment TextAdjustment;  int PrefixSpacesWidth;  int Width;};struct CFieldInfoInit{  PROPID PropID;  const wchar_t *Name;  EAdjustment TitleAdjustment;  EAdjustment TextAdjustment;  int PrefixSpacesWidth;  int Width;};CFieldInfoInit kStandardFieldTable[] = {  { kpidLastWriteTime, L"   Date      Time", kLeft, kLeft, 0, 19 },  { kpidAttributes, L"Attr", kRight, kCenter, 1, 5 },  { kpidSize, L"Size", kRight, kRight, 1, 12 },  { kpidPackedSize, L"Compressed", kRight, kRight, 1, 12 },  { kpidPath, L"Name", kLeft, kLeft, 2, 12 }};void PrintSpaces(int numSpaces){  for (int i = 0; i < numSpaces; i++)    g_StdOut << ' ';}void PrintString(EAdjustment adjustment, int width, const UString &textString){  const int numSpaces = width - textString.Length();  int numLeftSpaces;  switch (adjustment)  {    case kLeft:      numLeftSpaces = 0;      break;    case kCenter:      numLeftSpaces = numSpaces / 2;      break;    case kRight:      numLeftSpaces = numSpaces;      break;  }  PrintSpaces(numLeftSpaces);  g_StdOut << textString;  PrintSpaces(numSpaces - numLeftSpaces);}class CFieldPrinter{  CObjectVector<CFieldInfo> _fields;public:  void Clear() { _fields.Clear(); }  void Init(const CFieldInfoInit *standardFieldTable, int numItems);  HRESULT Init(IInArchive *archive);  void PrintTitle();  void PrintTitleLines();  HRESULT PrintItemInfo(IInArchive *archive,       const UString &defaultItemName,      const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,      UInt32 index,      bool techMode);  HRESULT PrintSummaryInfo(UInt64 numFiles, const UInt64 *size,       const UInt64 *compressedSize);};void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems){  Clear();  for (int i = 0; i < numItems; i++)  {    CFieldInfo fieldInfo;    const CFieldInfoInit &fieldInfoInit = standardFieldTable[i];    fieldInfo.PropID = fieldInfoInit.PropID;    fieldInfo.Name = fieldInfoInit.Name;    fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment;    fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment;    fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth;    fieldInfo.Width = fieldInfoInit.Width;    _fields.Add(fieldInfo);  }}HRESULT CFieldPrinter::Init(IInArchive *archive){  Clear();  UInt32 numProps;  RINOK(archive->GetNumberOfProperties(&numProps));  for (UInt32 i = 0; i < numProps; i++)  {    CMyComBSTR name;    PROPID propID;    VARTYPE vt;    RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt));    CFieldInfo fieldInfo;    fieldInfo.PropID = propID;    if (name != NULL)      fieldInfo.Name = name;    else    {      fieldInfo.Name = L"Unknown";      for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++)      {        const CPropIdToName &propIdToName = kPropIdToName[i];        if (propIdToName.PropID == propID)        {          fieldInfo.Name = propIdToName.Name;          break;        }      }    }    _fields.Add(fieldInfo);  }  return S_OK;}void CFieldPrinter::PrintTitle(){  for (int i = 0; i < _fields.Size(); i++)  {    const CFieldInfo &fieldInfo = _fields[i];    PrintSpaces(fieldInfo.PrefixSpacesWidth);    PrintString(fieldInfo.TitleAdjustment,       ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);  }}void CFieldPrinter::PrintTitleLines(){  for (int i = 0; i < _fields.Size(); i++)  {    const CFieldInfo &fieldInfo = _fields[i];    PrintSpaces(fieldInfo.PrefixSpacesWidth);    for (int i = 0; i < fieldInfo.Width; i++)      g_StdOut << '-';  }}BOOL IsFileTimeZero(CONST FILETIME *lpFileTime){  return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);}static const char *kEmptyTimeString = "                   ";void PrintTime(const NCOM::CPropVariant &propVariant){  if (propVariant.vt != VT_FILETIME)    throw "incorrect item";  if (IsFileTimeZero(&propVariant.filetime))    g_StdOut << kEmptyTimeString;  else  {    FILETIME localFileTime;    if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))      throw "FileTimeToLocalFileTime error";    char s[32];    if (ConvertFileTimeToString(localFileTime, s, true, true))      g_StdOut << s;    else      g_StdOut << kEmptyTimeString;  }}HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,     const UString &defaultItemName,     const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,    UInt32 index,    bool techMode){  /*  if (techMode)  {    g_StdOut << "Index = ";    g_StdOut << (UInt64)index;    g_StdOut << endl;  }  */  for (int i = 0; i < _fields.Size(); i++)  {    const CFieldInfo &fieldInfo = _fields[i];    if (!techMode)      PrintSpaces(fieldInfo.PrefixSpacesWidth);    NCOM::CPropVariant propVariant;    RINOK(archive->GetProperty(index, fieldInfo.PropID, &propVariant));    if (techMode)    {      g_StdOut << fieldInfo.Name << " = ";    }    int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width;    if (propVariant.vt == VT_EMPTY)    {      switch(fieldInfo.PropID)      {        case kpidPath:          propVariant = defaultItemName;          break;        case kpidLastWriteTime:          propVariant = archiveFileInfo.LastWriteTime;          break;        default:          if (techMode)            g_StdOut << endl;          else            PrintSpaces(width);          continue;      }    }    if (fieldInfo.PropID == kpidLastWriteTime)    {      PrintTime(propVariant);    }    else if (fieldInfo.PropID == kpidAttributes)    {      if (propVariant.vt != VT_UI4)        throw "incorrect item";      UInt32 attributes = propVariant.ulVal;      bool isFolder;      RINOK(IsArchiveItemFolder(archive, index, isFolder));      char s[8];      GetAttributesString(attributes, isFolder, s);      g_StdOut << s;    }    else if (propVariant.vt == VT_BSTR)    {      if (techMode)        g_StdOut << propVariant.bstrVal;      else        PrintString(fieldInfo.TextAdjustment, width, propVariant.bstrVal);    }    else    {      UString s = ConvertPropertyToString(propVariant, fieldInfo.PropID);      if (techMode)        g_StdOut << s;      else        PrintString(fieldInfo.TextAdjustment, width, s);    }    if (techMode)      g_StdOut << endl;  }  return S_OK;}void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value){  wchar_t textString[32] = { 0 };  if (value != NULL)    ConvertUInt64ToString(*value, textString);  PrintString(adjustment, width, textString);}HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles,     const UInt64 *size, const UInt64 *compressedSize){  for (int i = 0; i < _fields.Size(); i++)  {    const CFieldInfo &fieldInfo = _fields[i];    PrintSpaces(fieldInfo.PrefixSpacesWidth);    NCOM::CPropVariant propVariant;    if (fieldInfo.PropID == kpidSize)      PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size);    else if (fieldInfo.PropID == kpidPackedSize)      PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize);    else if (fieldInfo.PropID == kpidPath)    {      wchar_t textString[32];      ConvertUInt64ToString(numFiles, textString);      UString temp = textString;      temp += L" ";      temp += kFilesMessage;      PrintString(fieldInfo.TextAdjustment, 0, temp);    }    else       PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L"");  }  return S_OK;}bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value){  NCOM::CPropVariant propVariant;  if (archive->GetProperty(index, propID, &propVariant) != S_OK)    throw "GetPropertyValue error";  if (propVariant.vt == VT_EMPTY)    return false;  value = ConvertPropVariantToUInt64(propVariant);  return true;}HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull,    const NWildcard::CCensorNode &wildcardCensor,    bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password){  CFieldPrinter fieldPrinter;  if (!techMode)    fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));  UInt64 numFiles2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;  UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;  int numErrors = 0;  for (int i = 0; i < archivePaths.Size(); i++)  {    const UString &archiveName = archivePaths[i];    NFile::NFind::CFileInfoW archiveFileInfo;    if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())    {      g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl;      numErrors++;      continue;    }    if (archiveFileInfo.IsDirectory())    {      g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;      numErrors++;      continue;    }    CArchiveLink archiveLink;    COpenCallbackConsole openCallback;    openCallback.OutStream = &g_StdOut;    openCallback.PasswordIsDefined = passwordEnabled;    openCallback.Password = password;    HRESULT result = MyOpenArchive(archiveName, archiveLink, &openCallback);    if (result != S_OK)    {      g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl;      numErrors++;      continue;    }    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)    {      int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);      if (index >= 0 && index > i)      {        archivePaths.Delete(index);        archivePathsFull.Delete(index);      }    }    IInArchive *archive = archiveLink.GetArchive();    const UString defaultItemName = archiveLink.GetDefaultItemName();    if (enableHeaders)      g_StdOut << endl << kListing << archiveName << endl << endl;    if (enableHeaders && !techMode)    {      fieldPrinter.PrintTitle();      g_StdOut << endl;      fieldPrinter.PrintTitleLines();      g_StdOut << endl;    }    if (techMode)    {      RINOK(fieldPrinter.Init(archive));    }    UInt64 numFiles = 0, totalPackSize = 0, totalUnPackSize = 0;    UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;    UInt32 numItems;    RINOK(archive->GetNumberOfItems(&numItems));    for(UInt32 i = 0; i < numItems; i++)    {      if (NConsoleClose::TestBreakSignal())        return E_ABORT;      UString filePath;      RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath));      bool isFolder;      RINOK(IsArchiveItemFolder(archive, i, isFolder));      if (!wildcardCensor.CheckPath(filePath, !isFolder))        continue;            fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode);            UInt64 packSize, unpackSize;      if (!GetUInt64Value(archive, i, kpidSize, unpackSize))        unpackSize = 0;      else        totalUnPackSizePointer = &totalUnPackSize;      if (!GetUInt64Value(archive, i, kpidPackedSize, packSize))        packSize = 0;      else        totalPackSizePointer = &totalPackSize;            g_StdOut << endl;            numFiles++;      totalPackSize += packSize;      totalUnPackSize += unpackSize;    }    if (enableHeaders && !techMode)    {      fieldPrinter.PrintTitleLines();      g_StdOut << endl;      fieldPrinter.PrintSummaryInfo(numFiles, totalUnPackSizePointer, totalPackSizePointer);      g_StdOut << endl;    }    if (totalPackSizePointer != 0)    {      totalPackSizePointer2 = &totalPackSize2;      totalPackSize2 += totalPackSize;    }    if (totalUnPackSizePointer != 0)    {      totalUnPackSizePointer2 = &totalUnPackSize2;      totalUnPackSize2 += totalUnPackSize;    }    numFiles2 += numFiles;  }  if (enableHeaders && !techMode && archivePaths.Size() > 1)  {    g_StdOut << endl;    fieldPrinter.PrintTitleLines();    g_StdOut << endl;    fieldPrinter.PrintSummaryInfo(numFiles2, totalUnPackSizePointer2, totalPackSizePointer2);    g_StdOut << endl;    g_StdOut << "Archives: " << archivePaths.Size() << endl;  }  if (numErrors > 0)    g_StdOut << endl << "Errors: " << numErrors;  return S_OK;}

⌨️ 快捷键说明

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