mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-11 06:07:12 -06:00
4.24 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
ac2b563958
commit
47f4915611
@@ -228,7 +228,7 @@ static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
|
||||
recursed = false;
|
||||
break;
|
||||
}
|
||||
wildcardCensor.AddItem(name, include, recursed);
|
||||
wildcardCensor.AddItem(include, name, recursed);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -374,6 +374,72 @@ static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// This code converts all short file names to long file names.
|
||||
|
||||
static void ConvertToLongName(const UString &prefix, UString &name)
|
||||
{
|
||||
if (name.IsEmpty() || DoesNameContainWildCard(name))
|
||||
return;
|
||||
NFind::CFileInfoW fileInfo;
|
||||
if (NFind::FindFile(prefix + name, fileInfo))
|
||||
name = fileInfo.Name;
|
||||
}
|
||||
|
||||
static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
|
||||
{
|
||||
for (int i = 0; i < items.Size(); i++)
|
||||
{
|
||||
NWildcard::CItem &item = items[i];
|
||||
if (item.Recursive || item.PathParts.Size() != 1)
|
||||
continue;
|
||||
ConvertToLongName(prefix, item.PathParts.Front());
|
||||
}
|
||||
}
|
||||
|
||||
static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
|
||||
{
|
||||
ConvertToLongNames(prefix, node.IncludeItems);
|
||||
ConvertToLongNames(prefix, node.ExcludeItems);
|
||||
int i;
|
||||
for (i = 0; i < node.SubNodes.Size(); i++)
|
||||
ConvertToLongName(prefix, node.SubNodes[i].Name);
|
||||
// mix folders with same name
|
||||
for (i = 0; i < node.SubNodes.Size(); i++)
|
||||
{
|
||||
NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
|
||||
for (int j = i + 1; j < node.SubNodes.Size();)
|
||||
{
|
||||
const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
|
||||
if (nextNode1.Name.CollateNoCase(nextNode2.Name) == 0)
|
||||
{
|
||||
nextNode1.IncludeItems += nextNode2.IncludeItems;
|
||||
nextNode1.ExcludeItems += nextNode2.ExcludeItems;
|
||||
node.SubNodes.Delete(j);
|
||||
}
|
||||
else
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < node.SubNodes.Size(); i++)
|
||||
{
|
||||
NWildcard::CCensorNode &nextNode = node.SubNodes[i];
|
||||
ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode);
|
||||
}
|
||||
}
|
||||
|
||||
static void ConvertToLongNames(NWildcard::CCensor &censor)
|
||||
{
|
||||
for (int i = 0; i < censor.Pairs.Size(); i++)
|
||||
{
|
||||
NWildcard::CPair &pair = censor.Pairs[i];
|
||||
ConvertToLongNames(pair.Prefix, pair.Head);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
|
||||
{
|
||||
switch(i)
|
||||
@@ -718,6 +784,10 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
if (thereIsArchiveName)
|
||||
AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
|
||||
|
||||
#ifdef _WIN32
|
||||
ConvertToLongNames(archiveWildcardCensor);
|
||||
#endif
|
||||
|
||||
CObjectVector<CDirItem> dirItems;
|
||||
UString errorPath;
|
||||
if (EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPath) != S_OK)
|
||||
@@ -826,6 +896,10 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
throw kTerminalOutError;
|
||||
if(updateOptions.StdInMode)
|
||||
updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
|
||||
|
||||
#ifdef _WIN32
|
||||
ConvertToLongNames(options.WildcardCensor);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
throw kUserErrorMessage;
|
||||
|
||||
@@ -12,12 +12,10 @@ using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NName;
|
||||
|
||||
// using namespace NUpdateArchive;
|
||||
|
||||
void AddDirFileInfo(
|
||||
const UString &prefix,
|
||||
const UString &fullPathName,
|
||||
NFind::CFileInfoW &fileInfo,
|
||||
const UString &prefix, // prefix for logical path
|
||||
const UString &fullPathName, // path on disk: can be relative to some basePrefix
|
||||
const NFind::CFileInfoW &fileInfo,
|
||||
CObjectVector<CDirItem> &dirItems)
|
||||
{
|
||||
CDirItem item;
|
||||
@@ -32,9 +30,9 @@ void AddDirFileInfo(
|
||||
}
|
||||
|
||||
static HRESULT EnumerateDirectory(
|
||||
const UString &baseFolderPrefix,
|
||||
const UString &directory,
|
||||
const UString &prefix,
|
||||
const UString &baseFolderPrefix, // base (disk) prefix for scanning
|
||||
const UString &directory, // additional disk prefix starting from baseFolderPrefix
|
||||
const UString &prefix, // logical prefix
|
||||
CObjectVector<CDirItem> &dirItems,
|
||||
UString &errorPath)
|
||||
{
|
||||
@@ -51,8 +49,7 @@ static HRESULT EnumerateDirectory(
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo,
|
||||
dirItems);
|
||||
AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems);
|
||||
if (fileInfo.IsDirectory())
|
||||
{
|
||||
RINOK(EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter),
|
||||
@@ -63,8 +60,8 @@ static HRESULT EnumerateDirectory(
|
||||
}
|
||||
|
||||
HRESULT EnumerateDirItems(
|
||||
const UString &baseFolderPrefix,
|
||||
const UStringVector &fileNames,
|
||||
const UString &baseFolderPrefix, // base (disk) prefix for scanning
|
||||
const UStringVector &fileNames, // names relative to baseFolderPrefix
|
||||
const UString &archiveNamePrefix,
|
||||
CObjectVector<CDirItem> &dirItems,
|
||||
UString &errorPath)
|
||||
@@ -74,7 +71,11 @@ HRESULT EnumerateDirItems(
|
||||
const UString &fileName = fileNames[i];
|
||||
NFind::CFileInfoW fileInfo;
|
||||
if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo))
|
||||
throw 1081736;
|
||||
{
|
||||
HRESULT error = ::GetLastError();
|
||||
errorPath = baseFolderPrefix + fileName;
|
||||
return error;
|
||||
}
|
||||
AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems);
|
||||
if (fileInfo.IsDirectory())
|
||||
{
|
||||
@@ -88,9 +89,9 @@ HRESULT EnumerateDirItems(
|
||||
|
||||
static HRESULT EnumerateDirItems(
|
||||
const NWildcard::CCensorNode &curNode,
|
||||
const UString &diskPrefix,
|
||||
const UString &archivePrefix,
|
||||
const UString &addArchivePrefix,
|
||||
const UString &diskPrefix, // full disk path prefix
|
||||
const UString &archivePrefix, // prefix from root
|
||||
const UStringVector &addArchivePrefix, // prefix from curNode
|
||||
CObjectVector<CDirItem> &dirItems,
|
||||
bool enterToSubFolders,
|
||||
IEnumDirItemCallback *callback,
|
||||
@@ -101,6 +102,107 @@ static HRESULT EnumerateDirItems(
|
||||
enterToSubFolders = true;
|
||||
if (callback)
|
||||
RINOK(callback->CheckBreak());
|
||||
|
||||
// try direct_names case at first
|
||||
if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
|
||||
{
|
||||
// check that all names are direct
|
||||
int i;
|
||||
for (i = 0; i < curNode.IncludeItems.Size(); i++)
|
||||
{
|
||||
const NWildcard::CItem &item = curNode.IncludeItems[i];
|
||||
if (item.Recursive || item.PathParts.Size() != 1)
|
||||
break;
|
||||
const UString &name = item.PathParts.Front();
|
||||
if (name.IsEmpty() || DoesNameContainWildCard(name))
|
||||
break;
|
||||
}
|
||||
if (i == curNode.IncludeItems.Size())
|
||||
{
|
||||
// all names are direct (no wildcards)
|
||||
// so we don't need file_system's dir enumerator
|
||||
CRecordVector<bool> needEnterVector;
|
||||
for (i = 0; i < curNode.IncludeItems.Size(); i++)
|
||||
{
|
||||
const NWildcard::CItem &item = curNode.IncludeItems[i];
|
||||
const UString &name = item.PathParts.Front();
|
||||
const UString fullPath = diskPrefix + name;
|
||||
NFind::CFileInfoW fileInfo;
|
||||
if (!NFind::FindFile(fullPath, fileInfo))
|
||||
{
|
||||
HRESULT error = ::GetLastError();
|
||||
errorPath = fullPath;
|
||||
return error;
|
||||
}
|
||||
bool isDir = fileInfo.IsDirectory();
|
||||
if (isDir && !item.ForDir || !isDir && !item.ForFile)
|
||||
{
|
||||
errorPath = fullPath;
|
||||
return E_FAIL;
|
||||
}
|
||||
const UString realName = fileInfo.Name;
|
||||
const UString realDiskPath = diskPrefix + realName;
|
||||
{
|
||||
UStringVector pathParts;
|
||||
pathParts.Add(fileInfo.Name);
|
||||
if (curNode.CheckPathToRoot(false, pathParts, !isDir))
|
||||
continue;
|
||||
}
|
||||
AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems);
|
||||
if (!isDir)
|
||||
continue;
|
||||
|
||||
UStringVector addArchivePrefixNew;
|
||||
const NWildcard::CCensorNode *nextNode = 0;
|
||||
int index = curNode.FindSubNode(name);
|
||||
if (index >= 0)
|
||||
{
|
||||
for (int t = needEnterVector.Size(); t <= index; t++)
|
||||
needEnterVector.Add(true);
|
||||
needEnterVector[index] = false;
|
||||
nextNode = &curNode.SubNodes[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNode = &curNode;
|
||||
addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support
|
||||
}
|
||||
RINOK(EnumerateDirItems(*nextNode,
|
||||
realDiskPath + wchar_t(kDirDelimiter),
|
||||
archivePrefix + realName + wchar_t(kDirDelimiter),
|
||||
addArchivePrefixNew, dirItems, true, callback, errorPath));
|
||||
}
|
||||
for (i = 0; i < curNode.SubNodes.Size(); i++)
|
||||
{
|
||||
if (i < needEnterVector.Size())
|
||||
if (!needEnterVector[i])
|
||||
continue;
|
||||
const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
|
||||
const UString fullPath = diskPrefix + nextNode.Name;
|
||||
NFind::CFileInfoW fileInfo;
|
||||
if (!NFind::FindFile(fullPath, fileInfo))
|
||||
{
|
||||
if (!nextNode.AreThereIncludeItems())
|
||||
continue;
|
||||
HRESULT error = ::GetLastError();
|
||||
errorPath = fullPath;
|
||||
return error;
|
||||
}
|
||||
if (!fileInfo.IsDirectory())
|
||||
{
|
||||
errorPath = fullPath;
|
||||
return E_FAIL;
|
||||
}
|
||||
RINOK(EnumerateDirItems(nextNode,
|
||||
diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter),
|
||||
archivePrefix + fileInfo.Name + wchar_t(kDirDelimiter),
|
||||
UStringVector(), dirItems, false, callback, errorPath));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard));
|
||||
while (true)
|
||||
{
|
||||
@@ -117,13 +219,17 @@ static HRESULT EnumerateDirItems(
|
||||
|
||||
if (callback)
|
||||
RINOK(callback->CheckBreak());
|
||||
UString name = fileInfo.Name;
|
||||
const UString &name = fileInfo.Name;
|
||||
bool enterToSubFolders2 = enterToSubFolders;
|
||||
if (curNode.CheckPathToRoot(addArchivePrefix + name, !fileInfo.IsDirectory()))
|
||||
UStringVector addArchivePrefixNew = addArchivePrefix;
|
||||
addArchivePrefixNew.Add(name);
|
||||
if (curNode.CheckPathToRoot(false, UStringVector(addArchivePrefixNew), !fileInfo.IsDirectory()))
|
||||
continue;
|
||||
if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory()))
|
||||
{
|
||||
AddDirFileInfo(archivePrefix, diskPrefix + fileInfo.Name, fileInfo, dirItems);
|
||||
AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems);
|
||||
if (fileInfo.IsDirectory())
|
||||
enterToSubFolders2 = true;;
|
||||
enterToSubFolders2 = true;
|
||||
}
|
||||
if (!fileInfo.IsDirectory())
|
||||
continue;
|
||||
@@ -138,20 +244,16 @@ static HRESULT EnumerateDirItems(
|
||||
if (!enterToSubFolders2 && nextNode == 0)
|
||||
continue;
|
||||
|
||||
UString archivePrefixNew = archivePrefix;
|
||||
UString addArchivePrefixNew = addArchivePrefix;
|
||||
addArchivePrefixNew = addArchivePrefix;
|
||||
if (nextNode == 0)
|
||||
{
|
||||
nextNode = &curNode;
|
||||
addArchivePrefixNew += name;
|
||||
addArchivePrefixNew += wchar_t(kDirDelimiter);
|
||||
addArchivePrefixNew.Add(name);
|
||||
}
|
||||
archivePrefixNew += name;
|
||||
archivePrefixNew += wchar_t(kDirDelimiter);
|
||||
RINOK(EnumerateDirItems(*nextNode,
|
||||
diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter),
|
||||
archivePrefixNew, addArchivePrefixNew,
|
||||
dirItems, enterToSubFolders2, callback, errorPath));
|
||||
diskPrefix + name + wchar_t(kDirDelimiter),
|
||||
archivePrefix + name + wchar_t(kDirDelimiter),
|
||||
addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPath));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@@ -167,7 +269,7 @@ HRESULT EnumerateItems(
|
||||
if (callback)
|
||||
RINOK(callback->CheckBreak());
|
||||
const NWildcard::CPair &pair = censor.Pairs[i];
|
||||
RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", L"", dirItems, false, callback, errorPath));
|
||||
RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", UStringVector(), dirItems, false, callback, errorPath));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
void AddDirFileInfo(
|
||||
const UString &prefix,
|
||||
const UString &fullPathName,
|
||||
NWindows::NFile::NFind::CFileInfoW &fileInfo,
|
||||
const NWindows::NFile::NFind::CFileInfoW &fileInfo,
|
||||
CObjectVector<CDirItem> &dirItems);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user