4.50 beta

This commit is contained in:
Igor Pavlov
2007-07-24 00:00:00 +00:00
committed by Kornel Lesiński
parent 7038848692
commit 980e181dcc
104 changed files with 1419 additions and 4952 deletions

View File

@@ -6,9 +6,6 @@
#include "Common/StringConvert.h"
#include "Common/IntToString.h"
#include "../../Common/FileStreams.h"
#include "../../Archive/IArchive.h"
#include "../../IPassword.h"
#include "Windows/PropVariant.h"
#include "Windows/PropVariantConversions.h"
@@ -17,13 +14,24 @@
#include "Windows/FileName.h"
#include "Windows/FileFind.h"
#include "../../Common/FileStreams.h"
#include "../../Archive/IArchive.h"
#include "../../IPassword.h"
#include "../../MyVersion.h"
// {23170F69-40C1-278A-1000-000110070000}
DEFINE_GUID(CLSID_CFormat7z,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
using namespace NWindows;
static const char *kCopyrightString = "7-Zip (7za.DLL client example) (c) 1999-2007 Igor Pavlov 2007-03-30\n";
#define kDllName "7z.dll"
static const char *kCopyrightString = MY_7ZIP_VERSION
" (" kDllName " client) "
MY_COPYRIGHT " " MY_DATE;
static const char *kHelpString =
"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n"
"Examples:\n"
@@ -115,12 +123,12 @@ public:
CArchiveOpenCallback() : PasswordIsDefined(false) {}
};
STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 *files, const UInt64 *bytes)
STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
{
return S_OK;
}
STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 *files, const UInt64 *bytes)
STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)
{
return S_OK;
}
@@ -211,12 +219,12 @@ void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &di
NFile::NName::NormalizeDirPathPrefix(_directoryPath);
}
STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */)
{
return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)
STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)
{
return S_OK;
}
@@ -244,6 +252,9 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
_filePath = fullPath;
}
if (askExtractMode != NArchive::NExtract::NAskMode::kExtract)
return S_OK;
{
// Get Attributes
NCOM::CPropVariant propVariant;
@@ -481,23 +492,23 @@ public:
}
};
STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 /* size */)
{
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)
{
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **enumerator)
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG ** /* enumerator */)
{
return E_NOTIMPL;
}
STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */,
Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
{
if(newData != NULL)
@@ -602,7 +613,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)
{
m_NeedBeClosed = true;
return S_OK;
@@ -679,7 +690,7 @@ main(int argc, char* argv[])
return 1;
}
NWindows::NDLL::CLibrary library;
if (!library.Load(TEXT("7za.dll")))
if (!library.Load(TEXT(kDllName)))
{
PrintStringLn("Can not load library");
return 1;
@@ -843,7 +854,7 @@ main(int argc, char* argv[])
extractCallbackSpec->PasswordIsDefined = false;
// extractCallbackSpec->PasswordIsDefined = true;
// extractCallbackSpec->Password = L"1";
archive->Extract(0, (UInt32)(Int32)(-1), false, extractCallback);
archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);
}
}
return 0;

View File

@@ -36,7 +36,7 @@ OBJS = \
!include "../../../Build.mak"
$(CONSOLE_OBJS): $(*B).cpp
$(COMPL_O1_W3)
$(COMPL)
$(COMMON_OBJS): ../../../Common/$(*B).cpp
$(COMPL)
$(WIN_OBJS): ../../../Windows/$(*B).cpp

View File

@@ -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++)

View File

@@ -31,7 +31,7 @@ namespace NRecursedType { enum EEnum
{
kRecursed,
kWildCardOnlyRecursed,
kNonRecursed,
kNonRecursed
};}
struct CArchiveCommand

View File

@@ -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;
}
}
}

View File

@@ -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++;
}
}
}

View File

@@ -5,8 +5,6 @@
#include "Common/MyString.h"
UString GetCorrectFileName(const UString &path);
UString GetCorrectPath(const UString &path);
void MakeCorrectPath(UStringVector &pathParts);
#endif

View File

@@ -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));

View File

@@ -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);

View File

@@ -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]]);
}
*/

View File

@@ -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

View File

@@ -14,7 +14,7 @@ void CTempFiles::Clear()
{
while(!Paths.IsEmpty())
{
NDirectory::DeleteFileAlways(Paths.Back());
NDirectory::DeleteFileAlways((LPCWSTR)Paths.Back());
Paths.DeleteBack();
}
}

View File

@@ -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;

View File

@@ -335,6 +335,9 @@ HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,
else
{
UString s = ConvertPropertyToString(propVariant, fieldInfo.PropID);
s.Replace(wchar_t(0xA), L' ');
s.Replace(wchar_t(0xD), L' ');
if (techMode)
g_StdOut << s;
else
@@ -457,8 +460,19 @@ HRESULT ListArchives(
const UString defaultItemName = archiveLink.GetDefaultItemName();
if (enableHeaders)
{
g_StdOut << endl << kListing << archiveName << endl << endl;
NCOM::CPropVariant propVariant;
RINOK(archive->GetArchiveProperty(kpidComment, &propVariant));
if (propVariant.vt != VT_EMPTY)
{
UString s = ConvertPropertyToString(propVariant, kpidComment);
if (!s.IsEmpty())
g_StdOut << "Comment:\n" << s << "\n\n";
}
}
if (enableHeaders && !techMode)
{
fieldPrinter.PrintTitle();

View File

@@ -106,6 +106,7 @@ static const char *kHelpString =
" -si[{name}]: read data from stdin\n"
" -slt: show technical information for l (List) command\n"
" -so: write data to stdout\n"
" -ssc[-]: set sensitive case mode\n"
" -ssw: compress shared files\n"
" -t{Type}: Set type of archive\n"
" -v{Size}[b|k|m|g]: Create volumes\n"