mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 11:14:58 -06:00
4.50 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
7038848692
commit
980e181dcc
@@ -24,6 +24,8 @@
|
||||
#include "SortUtils.h"
|
||||
#include "EnumDirItems.h"
|
||||
|
||||
extern bool g_CaseSensitive;
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
#define MY_isatty_fileno(x) _isatty(_fileno(x))
|
||||
#else
|
||||
@@ -67,7 +69,8 @@ enum Enum
|
||||
kLargePages,
|
||||
kCharSet,
|
||||
kTechMode,
|
||||
kShareForWrite
|
||||
kShareForWrite,
|
||||
kCaseSensitive
|
||||
};
|
||||
|
||||
}
|
||||
@@ -131,7 +134,8 @@ static const CSwitchForm kSwitchForms[] =
|
||||
{ L"SLP", NSwitchType::kUnLimitedPostString, false, 0},
|
||||
{ L"SCS", NSwitchType::kUnLimitedPostString, false, 0},
|
||||
{ L"SLT", NSwitchType::kSimple, false },
|
||||
{ L"SSW", NSwitchType::kSimple, false }
|
||||
{ L"SSW", NSwitchType::kSimple, false },
|
||||
{ L"SSC", NSwitchType::kPostChar, false, 0, 0, L"-" }
|
||||
};
|
||||
|
||||
static const CCommandForm g_CommandForms[] =
|
||||
@@ -746,6 +750,9 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
|
||||
options.TechMode = parser[NKey::kTechMode].ThereIs;
|
||||
|
||||
if (parser[NKey::kCaseSensitive].ThereIs)
|
||||
g_CaseSensitive = (parser[NKey::kCaseSensitive].PostCharIndex < 0);
|
||||
|
||||
NRecursedType::EEnum recursedType;
|
||||
if (parser[NKey::kRecursed].ThereIs)
|
||||
recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
|
||||
@@ -865,7 +872,7 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
archivePathsFull.Add(fullPath);
|
||||
}
|
||||
CIntVector indices;
|
||||
SortStringsToIndices(archivePathsFull, indices);
|
||||
SortFileNames(archivePathsFull, indices);
|
||||
options.ArchivePathsSorted.Reserve(indices.Size());
|
||||
options.ArchivePathsFullSorted.Reserve(indices.Size());
|
||||
for (i = 0; i < indices.Size(); i++)
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace NRecursedType { enum EEnum
|
||||
{
|
||||
kRecursed,
|
||||
kWildCardOnlyRecursed,
|
||||
kNonRecursed,
|
||||
kNonRecursed
|
||||
};}
|
||||
|
||||
struct CArchiveCommand
|
||||
|
||||
@@ -118,21 +118,9 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
_isSplit = false;
|
||||
|
||||
UString fullPath;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
|
||||
|
||||
if(prop.vt == VT_EMPTY)
|
||||
fullPath = _itemDefaultName;
|
||||
else
|
||||
{
|
||||
if(prop.vt != VT_BSTR)
|
||||
return E_FAIL;
|
||||
fullPath = prop.bstrVal;
|
||||
}
|
||||
}
|
||||
|
||||
// UString fullPathCorrect = GetCorrectPath(fullPath);
|
||||
RINOK(GetArchiveItemPath(_archiveHandler, index, _itemDefaultName, fullPath));
|
||||
|
||||
_filePath = fullPath;
|
||||
|
||||
{
|
||||
@@ -147,14 +135,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidEncrypted, &prop));
|
||||
if (prop.vt == VT_BOOL)
|
||||
_encrypted = VARIANT_BOOLToBool(prop.boolVal);
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
return E_FAIL;
|
||||
}
|
||||
RINOK(IsArchiveItemProp(_archiveHandler, index, kpidEncrypted, _encrypted));
|
||||
|
||||
if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
|
||||
{
|
||||
@@ -176,7 +157,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
else
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
throw "incorrect item";
|
||||
return E_FAIL;
|
||||
_processedFileInfo.Attributes = prop.ulVal;
|
||||
_processedFileInfo.AttributesAreDefined = true;
|
||||
}
|
||||
@@ -202,54 +183,45 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
}
|
||||
|
||||
bool isAnti = false;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &prop));
|
||||
if (prop.vt == VT_BOOL)
|
||||
isAnti = VARIANT_BOOLToBool(prop.boolVal);
|
||||
}
|
||||
RINOK(IsArchiveItemProp(_archiveHandler, index, kpidIsAnti, isAnti));
|
||||
|
||||
UStringVector pathParts;
|
||||
SplitPathToParts(fullPath, pathParts);
|
||||
|
||||
if(pathParts.IsEmpty())
|
||||
return E_FAIL;
|
||||
UString processedPath;
|
||||
int numRemovePathParts = 0;
|
||||
switch(_pathMode)
|
||||
{
|
||||
case NExtract::NPathMode::kFullPathnames:
|
||||
{
|
||||
processedPath = fullPath;
|
||||
break;
|
||||
}
|
||||
case NExtract::NPathMode::kCurrentPathnames:
|
||||
{
|
||||
// for incorrect paths: "/dir1/dir2/file"
|
||||
int numRemovePathParts = _removePathParts.Size();
|
||||
if(pathParts.Size() <= numRemovePathParts)
|
||||
numRemovePathParts = _removePathParts.Size();
|
||||
if (pathParts.Size() <= numRemovePathParts)
|
||||
return E_FAIL;
|
||||
for(int i = 0; i < numRemovePathParts; i++)
|
||||
if(_removePathParts[i].CompareNoCase(pathParts[i]) != 0)
|
||||
for (int i = 0; i < numRemovePathParts; i++)
|
||||
if (_removePathParts[i].CompareNoCase(pathParts[i]) != 0)
|
||||
return E_FAIL;
|
||||
pathParts.Delete(0, numRemovePathParts);
|
||||
processedPath = MakePathNameFromParts(pathParts);
|
||||
break;
|
||||
}
|
||||
case NExtract::NPathMode::kNoPathnames:
|
||||
{
|
||||
processedPath = pathParts.Back();
|
||||
pathParts.Delete(0, pathParts.Size() - 1); // Test it!!
|
||||
numRemovePathParts = pathParts.Size() - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
processedPath = GetCorrectPath(processedPath);
|
||||
if(!_processedFileInfo.IsDirectory)
|
||||
pathParts.DeleteBack();
|
||||
|
||||
pathParts.Delete(0, numRemovePathParts);
|
||||
MakeCorrectPath(pathParts);
|
||||
|
||||
UString processedPath = MakePathNameFromParts(pathParts);
|
||||
if (!isAnti)
|
||||
{
|
||||
if (!_processedFileInfo.IsDirectory)
|
||||
{
|
||||
if (!pathParts.IsEmpty())
|
||||
pathParts.DeleteBack();
|
||||
}
|
||||
|
||||
if (!pathParts.IsEmpty())
|
||||
{
|
||||
UString fullPathNew;
|
||||
@@ -309,7 +281,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
_overwriteMode = NExtract::NOverwriteMode::kAutoRename;
|
||||
break;
|
||||
default:
|
||||
throw 20413;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,10 +313,10 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
else
|
||||
if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
|
||||
{
|
||||
UString message = UString(kCantDeleteOutputFile) +
|
||||
fullProcessedPath;
|
||||
UString message = UString(kCantDeleteOutputFile) + fullProcessedPath;
|
||||
RINOK(_extractCallback2->MessageError(message));
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
// return E_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,74 +5,76 @@
|
||||
|
||||
static UString ReplaceIncorrectChars(const UString &s)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
UString res;
|
||||
for (int i = 0; i < s.Length(); i++)
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
#ifdef _WIN32
|
||||
if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == ':' || c == '"')
|
||||
c = '_';
|
||||
#endif
|
||||
res += c;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void ReplaceDisk(UString &s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < s.Length(); i++)
|
||||
if (s[i] != ' ')
|
||||
break;
|
||||
if (s.Length() > i + 1)
|
||||
{
|
||||
if (s[i + 1] == L':')
|
||||
{
|
||||
s.Delete(i + 1);
|
||||
// s.Insert(i + 1, L'_');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UString GetCorrectFileName(const UString &path)
|
||||
{
|
||||
UString result = path;
|
||||
{
|
||||
UString test = path;
|
||||
test.Trim();
|
||||
if (test == L"..")
|
||||
result.Replace(L"..", L"");
|
||||
}
|
||||
ReplaceDisk(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
UString GetCorrectPath(const UString &path)
|
||||
{
|
||||
UString result = path;
|
||||
int first;
|
||||
for (first = 0; first < result.Length(); first++)
|
||||
if (result[first] != ' ')
|
||||
break;
|
||||
while(result.Length() > first)
|
||||
{
|
||||
if (
|
||||
#ifdef _WIN32
|
||||
result[first] == L'\\' ||
|
||||
#endif
|
||||
result[first] == L'/')
|
||||
{
|
||||
result.Delete(first);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
result.Replace(L"..\\", L"");
|
||||
#else
|
||||
return s;
|
||||
#endif
|
||||
result.Replace(L"../", L"");
|
||||
}
|
||||
|
||||
ReplaceDisk(result);
|
||||
#ifdef _WIN32
|
||||
static const wchar_t *g_ReservedNames[] =
|
||||
{
|
||||
L"CON", L"PRN", L"AUX", L"NUL"
|
||||
};
|
||||
|
||||
static bool CheckTail(const UString &name, int len)
|
||||
{
|
||||
int dotPos = name.Find(L'.');
|
||||
if (dotPos < 0)
|
||||
dotPos = name.Length();
|
||||
UString s = name.Left(dotPos);
|
||||
s.TrimRight();
|
||||
return (s.Length() != len);
|
||||
}
|
||||
|
||||
static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
|
||||
{
|
||||
int len = MyStringLen(reservedName);
|
||||
if (name.Length() <= len)
|
||||
return true;
|
||||
if (name.Left(len).CompareNoCase(reservedName) != 0)
|
||||
return true;
|
||||
wchar_t c = name[len];
|
||||
if (c < L'0' || c > L'9')
|
||||
return true;
|
||||
return CheckTail(name, len + 1);
|
||||
}
|
||||
|
||||
static bool IsSupportedName(const UString &name)
|
||||
{
|
||||
for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++)
|
||||
{
|
||||
const wchar_t *reservedName = g_ReservedNames[i];
|
||||
int len = MyStringLen(reservedName);
|
||||
if (name.Length() < len)
|
||||
continue;
|
||||
if (name.Left(len).CompareNoCase(reservedName) != 0)
|
||||
continue;
|
||||
if (!CheckTail(name, len))
|
||||
return false;
|
||||
}
|
||||
if (!CheckNameNum(name, L"COM"))
|
||||
return false;
|
||||
return CheckNameNum(name, L"LPT");
|
||||
}
|
||||
#endif
|
||||
|
||||
static UString GetCorrectFileName(const UString &path)
|
||||
{
|
||||
UString result = path;
|
||||
UString test = path;
|
||||
// test.Trim();
|
||||
if (test == L"..")
|
||||
result.Replace(L"..", L"");
|
||||
return ReplaceIncorrectChars(result);
|
||||
}
|
||||
|
||||
@@ -85,6 +87,13 @@ void MakeCorrectPath(UStringVector &pathParts)
|
||||
if (s.IsEmpty())
|
||||
pathParts.Delete(i);
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!IsSupportedName(s))
|
||||
s = (UString)L"_" + s;
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include "Common/MyString.h"
|
||||
|
||||
UString GetCorrectFileName(const UString &path);
|
||||
UString GetCorrectPath(const UString &path);
|
||||
void MakeCorrectPath(UStringVector &pathParts);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -55,7 +55,7 @@ HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
|
||||
HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(archive->GetProperty(index, propID, &prop));
|
||||
|
||||
@@ -14,6 +14,7 @@ HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result);
|
||||
HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result);
|
||||
HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
|
||||
const FILETIME &defaultFileTime, FILETIME &fileTime);
|
||||
HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);
|
||||
HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
|
||||
HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result);
|
||||
|
||||
|
||||
@@ -3,60 +3,15 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "SortUtils.h"
|
||||
#include "Common/Types.h"
|
||||
|
||||
/*
|
||||
template <class T>
|
||||
void TSortRefDown(T *p, UInt32 k, UInt32 size, int (*compare)(const T*, const T*, void *), void *param)
|
||||
{
|
||||
T temp = p[k];
|
||||
for (;;)
|
||||
{
|
||||
UInt32 s = (k << 1);
|
||||
if (s > size)
|
||||
break;
|
||||
if (s < size && compare(p + s + 1, p + s, param) > 0)
|
||||
s++;
|
||||
if (compare(&temp, p + s, param) >= 0)
|
||||
break;
|
||||
p[k] = p[s];
|
||||
k = s;
|
||||
}
|
||||
p[k] = temp;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void TSort(T* p, UInt32 size, int (*compare)(const T*, const T*, void *), void *param)
|
||||
{
|
||||
if (size <= 1)
|
||||
return;
|
||||
p--;
|
||||
{
|
||||
UInt32 i = size / 2;
|
||||
do
|
||||
TSortRefDown(p, i, size, compare, param);
|
||||
while(--i != 0);
|
||||
}
|
||||
do
|
||||
{
|
||||
T temp = p[size];
|
||||
p[size--] = p[1];
|
||||
p[1] = temp;
|
||||
TSortRefDown(p, 1, size, compare, param);
|
||||
}
|
||||
while (size > 1);
|
||||
}
|
||||
*/
|
||||
#include "Common/Wildcard.h"
|
||||
|
||||
static int CompareStrings(const int *p1, const int *p2, void *param)
|
||||
{
|
||||
const UStringVector &strings = *(const UStringVector *)param;
|
||||
const UString &s1 = strings[*p1];
|
||||
const UString &s2 = strings[*p2];
|
||||
return s1.CompareNoCase(s2);
|
||||
return CompareFileNames(strings[*p1], strings[*p2]);
|
||||
}
|
||||
|
||||
void SortStringsToIndices(const UStringVector &strings, CIntVector &indices)
|
||||
void SortFileNames(const UStringVector &strings, CIntVector &indices)
|
||||
{
|
||||
indices.Clear();
|
||||
int numItems = strings.Size();
|
||||
@@ -64,17 +19,4 @@ void SortStringsToIndices(const UStringVector &strings, CIntVector &indices)
|
||||
for(int i = 0; i < numItems; i++)
|
||||
indices.Add(i);
|
||||
indices.Sort(CompareStrings, (void *)&strings);
|
||||
// TSort(&indices.Front(), indices.Size(), CompareStrings, (void *)&strings);
|
||||
}
|
||||
|
||||
/*
|
||||
void SortStrings(const UStringVector &src, UStringVector &dest)
|
||||
{
|
||||
CIntVector indices;
|
||||
SortStringsToIndices(src, indices);
|
||||
dest.Clear();
|
||||
dest.Reserve(indices.Size());
|
||||
for (int i = 0; i < indices.Size(); i++)
|
||||
dest.Add(src[indices[i]]);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "Common/MyString.h"
|
||||
|
||||
void SortStringsToIndices(const UStringVector &strings, CIntVector &indices);
|
||||
// void SortStrings(const UStringVector &src, UStringVector &dest);
|
||||
void SortFileNames(const UStringVector &strings, CIntVector &indices);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@ void CTempFiles::Clear()
|
||||
{
|
||||
while(!Paths.IsEmpty())
|
||||
{
|
||||
NDirectory::DeleteFileAlways(Paths.Back());
|
||||
NDirectory::DeleteFileAlways((LPCWSTR)Paths.Back());
|
||||
Paths.DeleteBack();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "Windows/Time.h"
|
||||
|
||||
#include "UpdatePair.h"
|
||||
@@ -60,20 +61,10 @@ static const char *kSameTimeChangedSizeCollisionMessaged =
|
||||
"Collision between files with same date/time and different sizes:\n";
|
||||
*/
|
||||
|
||||
static inline int MyFileNameCompare(const UString &s1, const UString &s2)
|
||||
{
|
||||
return
|
||||
#ifdef _WIN32
|
||||
s1.CompareNoCase(s2);
|
||||
#else
|
||||
s1.Compare(s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
|
||||
{
|
||||
for(int i = 0; i + 1 < indices.Size(); i++)
|
||||
if (MyFileNameCompare(strings[indices[i]], strings[indices[i + 1]]) == 0)
|
||||
if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0)
|
||||
{
|
||||
UString message = kDuplicateFileNameMessage;
|
||||
message += L"\n";
|
||||
@@ -97,13 +88,13 @@ void GetUpdatePairInfoList(
|
||||
int i;
|
||||
for(i = 0; i < numDirItems; i++)
|
||||
dirNames.Add(dirItems[i].Name);
|
||||
SortStringsToIndices(dirNames, dirIndices);
|
||||
SortFileNames(dirNames, dirIndices);
|
||||
TestDuplicateString(dirNames, dirIndices);
|
||||
|
||||
int numArchiveItems = archiveItems.Size();
|
||||
for(i = 0; i < numArchiveItems; i++)
|
||||
archiveNames.Add(archiveItems[i].Name);
|
||||
SortStringsToIndices(archiveNames, archiveIndices);
|
||||
SortFileNames(archiveNames, archiveIndices);
|
||||
TestDuplicateString(archiveNames, archiveIndices);
|
||||
|
||||
int dirItemIndex = 0, archiveItemIndex = 0;
|
||||
@@ -114,7 +105,7 @@ void GetUpdatePairInfoList(
|
||||
archiveItemIndex2 = archiveIndices[archiveItemIndex];
|
||||
const CDirItem &dirItem = dirItems[dirItemIndex2];
|
||||
const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2];
|
||||
int compareResult = MyFileNameCompare(dirItem.Name, archiveItem.Name);
|
||||
int compareResult = CompareFileNames(dirItem.Name, archiveItem.Name);
|
||||
if (compareResult < 0)
|
||||
{
|
||||
pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
|
||||
|
||||
Reference in New Issue
Block a user