This commit is contained in:
Igor Pavlov
2022-01-22 18:43:09 +00:00
committed by Kornel
parent 52eeaf1ad6
commit c3529a41f5
88 changed files with 3474 additions and 435 deletions

View File

@@ -1,9 +1,20 @@
; 7zAsm.asm -- ASM macros
; 2021-08-29 : Igor Pavlov : Public domain
; 2021-12-25 : Igor Pavlov : Public domain
ifdef @wordsize
; @wordsize is defined only in JWASM and ASMC and is not defined in MASM
; @wordsize eq 8 for 64-bit x64
; @wordsize eq 2 for 32-bit x86
if @wordsize eq 8
x64 equ 1
endif
else
ifdef RAX
x64 equ 1
endif
endif
ifdef x64
IS_X64 equ 1

View File

@@ -1,10 +1,18 @@
; AesOpt.asm -- AES optimized code for x86 AES hardware instructions
; 2021-03-10 : Igor Pavlov : Public domain
; 2021-12-25 : Igor Pavlov : Public domain
include 7zAsm.asm
ifdef __ASMC__
use_vaes_256 equ 1
else
ifdef ymm0
use_vaes_256 equ 1
endif
endif
ifdef use_vaes_256
ECHO "++ VAES 256"
else
ECHO "-- NO VAES 256"

View File

@@ -1,5 +1,5 @@
/* 7zTypes.h -- Basic types
2021-07-13 : Igor Pavlov : Public domain */
2021-12-25 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
@@ -105,6 +105,7 @@ typedef int WRes;
// we use errno equivalents for some WIN32 errors:
#define ERROR_INVALID_PARAMETER EINVAL
#define ERROR_INVALID_FUNCTION EINVAL
#define ERROR_ALREADY_EXISTS EEXIST
#define ERROR_FILE_EXISTS EEXIST

View File

@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 21
#define MY_VER_MINOR 06
#define MY_VER_MINOR 07
#define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "21.06"
#define MY_VERSION_NUMBERS "21.07"
#define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME
@@ -10,7 +10,7 @@
#define MY_VERSION_CPU MY_VERSION
#endif
#define MY_DATE "2021-11-24"
#define MY_DATE "2021-12-26"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"

View File

@@ -1,5 +1,5 @@
/* DllSecur.c -- DLL loading security
2021-11-18 : Igor Pavlov : Public domain */
2021-12-25 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -33,17 +33,19 @@ static const char * const g_Dlls =
#endif
// #define MY_CAST_FUNC (void(*)())
#define MY_CAST_FUNC
void My_SetDefaultDllDirectories()
{
#ifndef UNDER_CE
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
GetVersionEx(&vi);
if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0)
{
Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories)
(void(*)())GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories");
MY_CAST_FUNC GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories");
if (setDllDirs)
if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS))
return;
@@ -66,7 +68,7 @@ void LoadSecurityDlls()
if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0)
{
Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories)
(void(*)())GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories");
MY_CAST_FUNC GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories");
if (setDllDirs)
if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS))
return;

View File

@@ -1,5 +1,5 @@
/* LzFind.c -- Match finder for LZ algorithms
2021-09-03 : Igor Pavlov : Public domain */
2021-11-29 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -600,7 +600,9 @@ static
#ifdef ATTRIB_SSE41
ATTRIB_SSE41
#endif
void LzFind_SaturSub_128(UInt32 subValue, CLzRef *items, const CLzRef *lim)
void
MY_FAST_CALL
LzFind_SaturSub_128(UInt32 subValue, CLzRef *items, const CLzRef *lim)
{
v128 sub2 =
#ifdef MY_CPU_ARM_OR_ARM64
@@ -632,7 +634,9 @@ static
#ifdef ATTRIB_AVX2
ATTRIB_AVX2
#endif
void LzFind_SaturSub_256(UInt32 subValue, CLzRef *items, const CLzRef *lim)
void
MY_FAST_CALL
LzFind_SaturSub_256(UInt32 subValue, CLzRef *items, const CLzRef *lim)
{
__m256i sub2 = _mm256_set_epi32(
(Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue,
@@ -669,7 +673,10 @@ static LZFIND_SATUR_SUB_CODE_FUNC g_LzFind_SaturSub;
#define DEFAULT_SaturSub LzFind_SaturSub_32
MY_NO_INLINE
static void LzFind_SaturSub_32(UInt32 subValue, CLzRef *items, const CLzRef *lim)
static
void
MY_FAST_CALL
LzFind_SaturSub_32(UInt32 subValue, CLzRef *items, const CLzRef *lim)
{
do
{

View File

@@ -1,5 +1,5 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
2021-07-12 : Igor Pavlov : Public domain */
2021-12-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -832,8 +832,8 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc)
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
static THREAD_FUNC_DECL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
static THREAD_FUNC_DECL BtThreadFunc2(void *p)
{
Byte allocaDummy[0x180];
unsigned i = 0;

View File

@@ -1,5 +1,5 @@
/* MtCoder.c -- Multi-thread Coder
2021-07-12 : Igor Pavlov : Public domain */
2021-12-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -44,7 +44,7 @@ static WRes ArEvent_OptCreate_And_Reset(CEvent *p)
}
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp);
static THREAD_FUNC_DECL ThreadFunc(void *pp);
static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t)
@@ -335,7 +335,7 @@ static SRes ThreadFunc2(CMtCoderThread *t)
}
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp)
static THREAD_FUNC_DECL ThreadFunc(void *pp)
{
CMtCoderThread *t = (CMtCoderThread *)pp;
for (;;)

View File

@@ -1,5 +1,5 @@
/* MtDec.c -- Multi-thread Decoder
2021-02-27 : Igor Pavlov : Public domain */
2021-12-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -102,7 +102,7 @@ typedef struct __CMtDecBufLink CMtDecBufLink;
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp);
static THREAD_FUNC_DECL ThreadFunc(void *pp);
static WRes MtDecThread_CreateEvents(CMtDecThread *t)
@@ -836,7 +836,7 @@ static WRes ThreadFunc2(CMtDecThread *t)
#endif
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc1(void *pp)
static THREAD_FUNC_DECL ThreadFunc1(void *pp)
{
WRes res;
@@ -862,7 +862,7 @@ static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc1(void *pp)
return (THREAD_FUNC_RET_TYPE)(UINT_PTR)res;
}
static MY_NO_INLINE THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp)
static MY_NO_INLINE THREAD_FUNC_DECL ThreadFunc(void *pp)
{
#ifdef USE_ALLOCA
CMtDecThread *t = (CMtDecThread *)pp;

View File

@@ -1,11 +1,11 @@
/* Threads.c -- multithreading library
2021-07-12 : Igor Pavlov : Public domain */
2021-12-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
#ifdef _WIN32
#ifndef UNDER_CE
#ifndef USE_THREADS_CreateThread
#include <process.h>
#endif
@@ -63,10 +63,10 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
{
/* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
#ifdef UNDER_CE
#ifdef USE_THREADS_CreateThread
DWORD threadId;
*p = CreateThread(0, 0, func, param, 0, &threadId);
*p = CreateThread(NULL, 0, func, param, 0, &threadId);
#else
@@ -82,7 +82,7 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity)
{
#ifdef UNDER_CE
#ifdef USE_THREADS_CreateThread
UNUSED_VAR(affinity)
return Thread_Create(p, func, param);

View File

@@ -1,5 +1,5 @@
/* Threads.h -- multithreading library
2021-07-12 : Igor Pavlov : Public domain */
2021-12-21 : Igor Pavlov : Public domain */
#ifndef __7Z_THREADS_H
#define __7Z_THREADS_H
@@ -38,8 +38,14 @@ typedef HANDLE CThread;
#define Thread_Close(p) HandlePtr_Close(p)
// #define Thread_Wait(p) Handle_WaitObject(*(p))
#ifdef UNDER_CE
// if (USE_THREADS_CreateThread is defined), we use _beginthreadex()
// if (USE_THREADS_CreateThread is not definned), we use CreateThread()
#define USE_THREADS_CreateThread
#endif
typedef
#ifdef UNDER_CE
#ifdef USE_THREADS_CreateThread
DWORD
#else
unsigned
@@ -90,7 +96,30 @@ typedef UInt64 CCpuSet;
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
#if defined(_WIN32) && defined(__GNUC__)
/* GCC compiler for x86 32-bit uses the rule:
the stack is 16-byte aligned before CALL instruction for function calling.
But only root function main() contains instructions that
set 16-byte alignment for stack pointer. And another functions
just keep alignment, if it was set in some parent function.
The problem:
if we create new thread in MinGW (GCC) 32-bit x86 via _beginthreadex() or CreateThread(),
the root function of thread doesn't set 16-byte alignment.
And stack frames in all child functions also will be unaligned in that case.
Here we set (force_align_arg_pointer) attribute for root function of new thread.
Do we need (force_align_arg_pointer) also for another systems? */
#define THREAD_FUNC_ATTRIB_ALIGN_ARG __attribute__((force_align_arg_pointer))
// #define THREAD_FUNC_ATTRIB_ALIGN_ARG // for debug : bad alignment in SSE functions
#else
#define THREAD_FUNC_ATTRIB_ALIGN_ARG
#endif
#define THREAD_FUNC_DECL THREAD_FUNC_ATTRIB_ALIGN_ARG THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);
WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity);

View File

@@ -3,11 +3,15 @@
# IS_X64 = 1
# MY_ARCH =
# USE_ASM=
# USE_JWASM=1
MY_ARCH_2 = $(MY_ARCH)
MY_ASM = jwasm
MY_ASM = asmc
ifdef USE_JWASM
MY_ASM = jwasm
endif
PROGPATH = $(O)/$(PROG)
PROGPATH_STATIC = $(O)/$(PROG)s
@@ -95,7 +99,8 @@ ifdef IS_MINGW
RM = del
MY_MKDIR=mkdir
LIB2 = -loleaut32 -luuid -ladvapi32 -lUser32
LIB2_GUI = -lOle32 -lGdi32 -lComctl32 -lComdlg32
LIB2 = -loleaut32 -luuid -ladvapi32 -lUser32 $(LIB2_GUI)
CXXFLAGS_EXTRA = -DUNICODE -D_UNICODE
# -Wno-delete-non-virtual-dtor
@@ -126,7 +131,7 @@ CFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(CC_SHARED)
ifdef IS_MINGW
AFLAGS_ABI = -coff -DABI_CDECL
AFLAGS = $(AFLAGS_ABI) -Fo$(O)/$(basename $(<F)).o
AFLAGS = -nologo $(AFLAGS_ABI) -Fo$(O)/$(basename $(<F)).o
else
ifdef IS_X64
AFLAGS_ABI = -elf64 -DABI_LINUX
@@ -136,7 +141,7 @@ AFLAGS_ABI = -elf -DABI_LINUX -DABI_CDECL
# -DABI_LINUX
# -DABI_CDECL
endif
AFLAGS = $(AFLAGS_ABI) -Fo$(O)/
AFLAGS = -nologo $(AFLAGS_ABI) -Fo$(O)/
endif
ifdef USE_ASM
@@ -455,6 +460,8 @@ $O/VdiHandler.o: ../../Archive/VdiHandler.cpp
$(CXX) $(CXXFLAGS) $<
$O/VhdHandler.o: ../../Archive/VhdHandler.cpp
$(CXX) $(CXXFLAGS) $<
$O/VhdxHandler.o: ../../Archive/VhdxHandler.cpp
$(CXX) $(CXXFLAGS) $<
$O/VmdkHandler.o: ../../Archive/VmdkHandler.cpp
$(CXX) $(CXXFLAGS) $<
$O/XarHandler.o: ../../Archive/XarHandler.cpp
@@ -996,6 +1003,8 @@ $O/TextPairs.o: ../../UI/FileManager/TextPairs.cpp
$(CXX) $(CXXFLAGS) $<
$O/UpdateCallback100.o: ../../UI/FileManager/UpdateCallback100.cpp
$(CXX) $(CXXFLAGS) $<
$O/VerCtrl.o: ../../UI/FileManager/VerCtrl.cpp
$(CXX) $(CXXFLAGS) $<
$O/ViewSettings.o: ../../UI/FileManager/ViewSettings.cpp
$(CXX) $(CXXFLAGS) $<
@@ -1123,12 +1132,15 @@ $O/7zCrcOpt.o: ../../../../Asm/x86/7zCrcOpt.asm
$(MY_ASM) $(AFLAGS) $<
$O/XzCrc64Opt.o: ../../../../Asm/x86/XzCrc64Opt.asm
$(MY_ASM) $(AFLAGS) $<
$O/AesOpt.o: ../../../../Asm/x86/AesOpt.asm
$(MY_ASM) $(AFLAGS) $<
$O/Sha1Opt.o: ../../../../Asm/x86/Sha1Opt.asm
$(MY_ASM) $(AFLAGS) $<
$O/Sha256Opt.o: ../../../../Asm/x86/Sha256Opt.asm
$(MY_ASM) $(AFLAGS) $<
ifndef USE_JWASM
USE_X86_ASM_AES=1
endif
else
$O/7zCrcOpt.o: ../../../../C/7zCrcOpt.c
$(CC) $(CFLAGS) $<
@@ -1138,10 +1150,18 @@ $O/Sha1Opt.o: ../../../../C/Sha1Opt.c
$(CC) $(CFLAGS) $<
$O/Sha256Opt.o: ../../../../C/Sha256Opt.c
$(CC) $(CFLAGS) $<
endif
ifdef USE_X86_ASM_AES
$O/AesOpt.o: ../../../../Asm/x86/AesOpt.asm
$(MY_ASM) $(AFLAGS) $<
else
$O/AesOpt.o: ../../../../C/AesOpt.c
$(CC) $(CFLAGS) $<
endif
ifdef USE_X64_ASM
$O/LzFindOpt.o: ../../../../Asm/x86/LzFindOpt.asm
$(MY_ASM) $(AFLAGS) $<

View File

@@ -130,8 +130,10 @@ HRESULT CHandler::SetMainMethod(CCompressionMethodMode &methodMode)
CMethodFull &methodFull = methodMode.Methods.AddNew();
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
#ifndef _7ZIP_ST
methodFull.Set_NumThreads = true;
methodFull.NumThreads = methodMode.NumThreads;
#endif
if (methodFull.Id != k_Copy)
needSolid = true;

View File

@@ -320,7 +320,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
}
case kpidBlock: prop = (Int32)m_Database.GetFolderIndex(&mvItem); break;
case kpidBlock: prop.Set_Int32((Int32)m_Database.GetFolderIndex(&mvItem)); break;
#ifdef _CAB_DETAILS

View File

@@ -120,6 +120,15 @@ static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value)
m.AddProp32(propID, value);
}
void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
{
UInt32 level = _level;
if (level != (UInt32)(Int32)-1)
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
}
#ifndef _7ZIP_ST
static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value)
{
const int i = m.FindProp(propID);
@@ -132,14 +141,6 @@ static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value
m.AddProp32(propID, value);
}
void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
{
UInt32 level = _level;
if (level != (UInt32)(Int32)-1)
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
}
#ifndef _7ZIP_ST
void CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreads)
{
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
@@ -149,7 +150,9 @@ void CMultiMethodProps::SetMethodThreadsTo_Replace(CMethodProps &oneMethodInfo,
{
SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
}
#endif
#endif // _7ZIP_ST
void CMultiMethodProps::InitMulti()
{

View File

@@ -234,6 +234,7 @@ static const CAppleName k_Names[] =
{ true, "hfs", "Apple_HFS" },
{ true, "hfsx", "Apple_HFSX" },
{ true, "ufs", "Apple_UFS" },
{ true, "apfs", "Apple_APFS" },
// efi_sys partition is FAT32, but it's not main file. So we use (IsFs = false)
{ false, "efi_sys", "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" },

View File

@@ -935,7 +935,10 @@ HRESULT CHandler::ParseDir(const Byte *p, size_t size, unsigned iNodeDir)
return S_FALSE;
if (_isUTF)
_isUTF = CheckUTF8_AString(item.Name);
{
// 21.07 : we force UTF8
// _isUTF = CheckUTF8_AString(item.Name);
}
if (iNode == 0)
{
@@ -1835,7 +1838,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidRevision: prop = _h.RevLevel; break;
case kpidINodeSize: prop = _h.InodeSize; break;
case kpidINodeSize: prop = (UInt32)_h.InodeSize; break;
case kpidId:
{

View File

@@ -112,6 +112,7 @@ static const CPartType kPartTypes[] =
{ 0x516E7CB8, "zfs", "FreeBSD ZFS" },
{ 0x48465300, "hfsx", "HFS+" },
{ 0x7C3457EF, "apfs", "APFS" },
};
static int FindPartType(const Byte *guid)

View File

@@ -105,10 +105,9 @@ STDMETHODIMP CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream)
CHandlerImg::CHandlerImg():
_imgExt(NULL)
CHandlerImg::CHandlerImg()
{
ClearStreamVars();
Clear_HandlerImg_Vars();
}
STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
@@ -121,7 +120,11 @@ STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosit
default: return STG_E_INVALIDFUNCTION;
}
if (offset < 0)
{
if (newPosition)
*newPosition = _virtPos;
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
}
_virtPos = offset;
if (newPosition)
*newPosition = offset;
@@ -130,6 +133,7 @@ STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosit
static const Byte k_GDP_Signature[] = { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' };
static const char *GetImgExt(ISequentialInStream *stream)
{
const size_t kHeaderSize = 1 << 10;
@@ -151,6 +155,15 @@ void CHandlerImg::CloseAtError()
Stream.Release();
}
void CHandlerImg::Clear_HandlerImg_Vars()
{
_imgExt = NULL;
_size = 0;
ClearStreamVars();
Reset_VirtPos();
Reset_PosInArc();
}
STDMETHODIMP CHandlerImg::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * openCallback)
@@ -165,9 +178,16 @@ STDMETHODIMP CHandlerImg::Open(IInStream *stream,
if (res == S_OK)
{
CMyComPtr<ISequentialInStream> inStream;
HRESULT res2 = GetStream(0, &inStream);
const HRESULT res2 = GetStream(0, &inStream);
if (res2 == S_OK && inStream)
_imgExt = GetImgExt(inStream);
// _imgExt = GetImgExt(this); // for debug
/* we reset (_virtPos) to support cases, if some code will
call Read() from Handler object instead of GetStream() object. */
Reset_VirtPos();
// optional: we reset (_posInArc). if real seek position of stream will be changed in external code
Reset_PosInArc();
// optional: here we could also reset seek positions in parent streams..
return S_OK;
}
}

View File

@@ -78,6 +78,9 @@ protected:
// bool _stream_UsePackSize;
// UInt64 _stream_PackSize;
void Reset_PosInArc() { _posInArc = (UInt64)0 - 1; }
void Reset_VirtPos() { _virtPos = (UInt64)0; }
void ClearStreamVars()
{
_stream_unavailData = false;
@@ -87,6 +90,7 @@ protected:
// _stream_PackSize = 0;
}
void Clear_HandlerImg_Vars(); // it doesn't Release (Stream) var.
virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) = 0;
virtual void CloseAtError();

View File

@@ -601,7 +601,6 @@ STDMETHODIMP CHandler::Close()
_table.Free();
_dir.Free();
_phySize = 0;
_size = 0;
_cacheCluster = (UInt64)(Int64)-1;
_comprPos = 0;
@@ -611,7 +610,8 @@ STDMETHODIMP CHandler::Close()
_isArc = false;
_unsupported = false;
_imgExt = NULL;
// CHandlerImg:
Clear_HandlerImg_Vars();
Stream.Release();
return S_OK;
}

View File

@@ -28,12 +28,12 @@ public:
{
_needChangeForNext = true;
_after.Empty();
UString base = name;
int dotPos = name.ReverseFind_Dot();
UString base (name);
const int dotPos = name.ReverseFind_Dot();
if (dotPos >= 0)
{
const UString ext = name.Ptr(dotPos + 1);
const UString ext (name.Ptr(dotPos + 1));
if (ext.IsEqualTo_Ascii_NoCase("rar"))
{
_after = name.Ptr(dotPos);

View File

@@ -21,13 +21,21 @@
#include "../Compress/CopyCoder.h"
#include "../Compress/LzmaDecoder.h"
#include "../Compress/LzmaEncoder.h"
#include "../Compress/ZlibDecoder.h"
#include "../Compress/ZlibEncoder.h"
#include "Common/DummyOutStream.h"
// #define SWF_UPDATE
#ifdef SWF_UPDATE
#include "../Compress/LzmaEncoder.h"
#include "../Compress/ZlibEncoder.h"
#include "Common/HandlerOut.h"
#endif
using namespace NWindows;
namespace NArchive {
@@ -152,8 +160,10 @@ struct CItem
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
#ifdef SWF_UPDATE
public IOutArchive,
public ISetProperties,
#endif
public CMyUnknownImp
{
CItem _item;
@@ -162,16 +172,22 @@ class CHandler:
CMyComPtr<ISequentialInStream> _seqStream;
CMyComPtr<IInStream> _stream;
#ifdef SWF_UPDATE
CSingleMethodProps _props;
bool _lzmaMode;
#endif
public:
CHandler(): _lzmaMode(false) {}
#ifdef SWF_UPDATE
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
INTERFACE_IInArchive(;)
CHandler(): _lzmaMode(false) {}
INTERFACE_IOutArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#else
MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq)
#endif
INTERFACE_IInArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
};
static const Byte kProps[] =
@@ -416,6 +432,9 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
COM_TRY_END
}
#ifdef SWF_UPDATE
static HRESULT UpdateArchive(ISequentialOutStream *outStream, UInt64 size,
bool lzmaMode, const CSingleMethodProps &props,
IArchiveUpdateCallback *updateCallback)
@@ -576,11 +595,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
return S_OK;
}
#endif
static const Byte k_Signature[] = {
3, 'C', 'W', 'S',
3, 'Z', 'W', 'S' };
REGISTER_ARC_IO(
REGISTER_ARC_I(
"SWFc", "swf", "~.swf", 0xD8,
k_Signature,
0,

View File

@@ -107,8 +107,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidCharacts:
{
AString s = _encodingCharacts.GetCharactsString();
prop = s;
prop = _encodingCharacts.GetCharactsString();
break;
}
}

View File

@@ -130,8 +130,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
else
ui.Mode = prop.ulVal;
// FIXME : we can clear high file type bits to be more compatible with tars created by GNU TAR.
// ui.Mode &= ~(UInt32)MY_LIN_S_IFMT;
// 21.07 : we clear high file type bits as GNU TAR.
ui.Mode &= ~(UInt32)MY_LIN_S_IFMT;
}
{

View File

@@ -17,7 +17,10 @@ namespace NFileHeader {
// const char * const kUsTar = "ustar"; // 5 chars
// const char * const kGNUTar = "GNUtar "; // 7 chars and a null
// const char * const kEmpty = "\0\0\0\0\0\0\0\0";
const char kUsTar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ;
// 7-Zip used kUsTar_00 before 21.07:
// const char kUsTar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ;
// GNU TAR uses such header:
const char kUsTar_GNU[8] = { 'u', 's', 't', 'a', 'r', ' ', ' ', 0 } ;
}
}}}

View File

@@ -76,7 +76,8 @@ namespace NFileHeader
// extern const char * const kUsTar; // = "ustar"; // 5 chars
// extern const char * const kGNUTar; // = "GNUtar "; // 7 chars and a null
// extern const char * const kEmpty; // = "\0\0\0\0\0\0\0\0"
extern const char kUsTar_00[8];
// extern const char kUsTar_00[8];
extern const char kUsTar_GNU[8];
}
}

View File

@@ -72,10 +72,7 @@ static bool IsRecordLast(const char *buf)
static void ReadString(const char *s, unsigned size, AString &result)
{
char temp[NFileHeader::kRecordSize + 1];
MyStrNCpy(temp, s, size);
temp[size] = '\0';
result = temp;
result.SetFrom_CalcLen(s, size);
}
static bool ParseInt64(const char *p, Int64 &val)

View File

@@ -43,6 +43,15 @@ struct CItem
CRecordVector<CSparseBlock> SparseBlocks;
void SetDefaultWriteFields()
{
DeviceMajorDefined = false;
DeviceMinorDefined = false;
UID = 0;
GID = 0;
memcpy(Magic, NFileHeader::NMagic::kUsTar_GNU, 8);
}
bool IsSymLink() const { return LinkFlag == NFileHeader::NLinkFlag::kSymLink && (Size == 0); }
bool IsHardLink() const { return LinkFlag == NFileHeader::NLinkFlag::kHardLink; }
bool IsSparse() const { return LinkFlag == NFileHeader::NLinkFlag::kSparse; }
@@ -103,7 +112,7 @@ struct CItem
bool IsUstarMagic() const
{
for (int i = 0; i < 5; i++)
if (Magic[i] != NFileHeader::NMagic::kUsTar_00[i])
if (Magic[i] != NFileHeader::NMagic::kUsTar_GNU[i])
return false;
return true;
}

View File

@@ -15,17 +15,6 @@ HRESULT COutArchive::WriteBytes(const void *data, unsigned size)
return WriteStream(m_Stream, data, size);
}
static void MyStrNCpy(char *dest, const char *src, unsigned size)
{
for (unsigned i = 0; i < size; i++)
{
char c = src[i];
dest[i] = c;
if (c == 0)
break;
}
}
static bool WriteOctal_8(char *s, UInt32 val)
{
const unsigned kNumDigits = 8 - 1;
@@ -39,6 +28,12 @@ static bool WriteOctal_8(char *s, UInt32 val)
return true;
}
static void WriteBin_64bit(char *s, UInt64 val)
{
for (unsigned i = 0; i < 8; i++, val <<= 8)
s[i] = (char)(val >> 56);
}
static void WriteOctal_12(char *s, UInt64 val)
{
const unsigned kNumDigits = 12 - 1;
@@ -47,8 +42,7 @@ static void WriteOctal_12(char *s, UInt64 val)
// GNU extension;
s[0] = (char)(Byte)0x80;
s[1] = s[2] = s[3] = 0;
for (unsigned i = 0; i < 8; i++, val <<= 8)
s[4 + i] = (char)(val >> 56);
WriteBin_64bit(s + 4, val);
return;
}
for (unsigned i = 0; i < kNumDigits; i++)
@@ -66,57 +60,67 @@ static void WriteOctal_12_Signed(char *s, Int64 val)
return;
}
s[0] = s[1] = s[2] = s[3] = (char)(Byte)0xFF;
for (unsigned i = 0; i < 8; i++, val <<= 8)
s[4 + i] = (char)(val >> 56);
WriteBin_64bit(s + 4, val);
}
static bool CopyString(char *dest, const AString &src, unsigned maxSize)
static void CopyString(char *dest, const AString &src, unsigned maxSize)
{
if (src.Len() >= maxSize)
return false;
MyStringCopy(dest, (const char *)src);
return true;
unsigned len = src.Len();
if (len == 0)
return;
// 21.07: we don't require additional 0 character at the end
if (len > maxSize)
{
len = maxSize;
// return false;
}
memcpy(dest, src.Ptr(), len);
// return true;
}
#define RETURN_IF_NOT_TRUE(x) { if (!(x)) return E_FAIL; }
#define COPY_STRING_CHECK(dest, src, size) \
CopyString(dest, src, size); dest += (size);
#define WRITE_OCTAL_8_CHECK(dest, src) \
RETURN_IF_NOT_TRUE(WriteOctal_8(dest, src));
HRESULT COutArchive::WriteHeaderReal(const CItem &item)
{
char record[NFileHeader::kRecordSize];
memset(record, 0, NFileHeader::kRecordSize);
char *cur = record;
if (item.Name.Len() > NFileHeader::kNameSize)
return E_FAIL;
MyStrNCpy(cur, item.Name, NFileHeader::kNameSize);
cur += NFileHeader::kNameSize;
COPY_STRING_CHECK (cur, item.Name, NFileHeader::kNameSize);
RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.Mode)); cur += 8;
RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.UID)); cur += 8;
RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.GID)); cur += 8;
WRITE_OCTAL_8_CHECK (cur, item.Mode); cur += 8;
WRITE_OCTAL_8_CHECK (cur, item.UID); cur += 8;
WRITE_OCTAL_8_CHECK (cur, item.GID); cur += 8;
WriteOctal_12(cur, item.PackSize); cur += 12;
WriteOctal_12_Signed(cur, item.MTime); cur += 12;
memset(cur, ' ', 8);
memset(cur, ' ', 8); // checksum field
cur += 8;
*cur++ = item.LinkFlag;
RETURN_IF_NOT_TRUE(CopyString(cur, item.LinkName, NFileHeader::kNameSize));
cur += NFileHeader::kNameSize;
COPY_STRING_CHECK (cur, item.LinkName, NFileHeader::kNameSize);
memcpy(cur, item.Magic, 8);
cur += 8;
RETURN_IF_NOT_TRUE(CopyString(cur, item.User, NFileHeader::kUserNameSize));
cur += NFileHeader::kUserNameSize;
RETURN_IF_NOT_TRUE(CopyString(cur, item.Group, NFileHeader::kGroupNameSize));
cur += NFileHeader::kGroupNameSize;
COPY_STRING_CHECK (cur, item.User, NFileHeader::kUserNameSize);
COPY_STRING_CHECK (cur, item.Group, NFileHeader::kGroupNameSize);
if (item.DeviceMajorDefined) RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMajor)); cur += 8;
if (item.DeviceMinorDefined) RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMinor)); cur += 8;
if (item.DeviceMajorDefined)
WRITE_OCTAL_8_CHECK (cur, item.DeviceMajor);
cur += 8;
if (item.DeviceMinorDefined)
WRITE_OCTAL_8_CHECK (cur, item.DeviceMinor);
cur += 8;
if (item.IsSparse())
{
@@ -140,7 +144,7 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
/* we use GNU TAR scheme:
checksum field is formatted differently from the
other fields: it has [6] digits, a null, then a space. */
// RETURN_IF_NOT_TRUE(WriteOctal_8(record + 148, checkSum));
// WRITE_OCTAL_8_CHECK(record + 148, checkSum);
const unsigned kNumDigits = 6;
for (unsigned i = 0; i < kNumDigits; i++)
{
@@ -172,27 +176,42 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
return S_OK;
}
/* OLD_GNU_TAR: writes short name with zero at the end
NEW_GNU_TAR: writes short name without zero at the end */
static const unsigned kNameSize_Max =
NFileHeader::kNameSize; // NEW_GNU_TAR / 7-Zip 21.07
// NFileHeader::kNameSize - 1; // OLD_GNU_TAR / old 7-Zip
#define DOES_NAME_FIT_IN_FIELD(name) ((name).Len() <= kNameSize_Max)
HRESULT COutArchive::WriteHeader(const CItem &item)
{
unsigned nameSize = item.Name.Len();
unsigned linkSize = item.LinkName.Len();
/* There two versions of GNU tar:
OLDGNU_FORMAT: it writes short name and zero at the end
GNU_FORMAT: it writes only short name without zero at the end
we write it as OLDGNU_FORMAT with zero at the end */
if (nameSize < NFileHeader::kNameSize &&
linkSize < NFileHeader::kNameSize)
if (DOES_NAME_FIT_IN_FIELD(item.Name) &&
DOES_NAME_FIT_IN_FIELD(item.LinkName))
return WriteHeaderReal(item);
// here we can get all fields from main (item) or create new empty item
/*
CItem mi;
mi.SetDefaultWriteFields();
*/
CItem mi = item;
mi.Name = NFileHeader::kLongLink;
mi.LinkName.Empty();
// SparseBlocks will be ignored by IsSparse()
// mi.SparseBlocks.Clear();
mi.Name = NFileHeader::kLongLink;
// 21.07 : we set Mode and MTime props as in GNU TAR:
mi.Mode = 0644; // octal
mi.MTime = 0;
for (int i = 0; i < 2; i++)
{
const AString *name;
// We suppose that GNU tar also writes item for long link before item for LongName?
// We suppose that GNU TAR also writes item for long link before item for LongName?
if (i == 0)
{
mi.LinkFlag = NFileHeader::NLinkFlag::kGnu_LongLink;
@@ -203,21 +222,26 @@ HRESULT COutArchive::WriteHeader(const CItem &item)
mi.LinkFlag = NFileHeader::NLinkFlag::kGnu_LongName;
name = &item.Name;
}
if (name->Len() < NFileHeader::kNameSize)
if (DOES_NAME_FIT_IN_FIELD(*name))
continue;
unsigned nameStreamSize = name->Len() + 1;
// GNU TAR writes null character after NAME to file. We do same here:
const unsigned nameStreamSize = name->Len() + 1;
mi.PackSize = nameStreamSize;
RINOK(WriteHeaderReal(mi));
RINOK(WriteBytes((const char *)*name, nameStreamSize));
RINOK(WriteBytes(name->Ptr(), nameStreamSize));
RINOK(FillDataResidual(nameStreamSize));
}
// 21.07: WriteHeaderReal() writes short part of (Name) and (LinkName).
return WriteHeaderReal(item);
/*
mi = item;
if (mi.Name.Len() >= NFileHeader::kNameSize)
mi.Name.SetFrom(item.Name, NFileHeader::kNameSize - 1);
if (mi.LinkName.Len() >= NFileHeader::kNameSize)
mi.LinkName.SetFrom(item.LinkName, NFileHeader::kNameSize - 1);
if (!DOES_NAME_FIT_IN_FIELD(mi.Name))
mi.Name.SetFrom(item.Name, kNameSize_Max);
if (!DOES_NAME_FIT_IN_FIELD(mi.LinkName))
mi.LinkName.SetFrom(item.LinkName, kNameSize_Max);
return WriteHeaderReal(mi);
*/
}
HRESULT COutArchive::FillDataResidual(UInt64 dataSize)
@@ -235,7 +259,17 @@ HRESULT COutArchive::WriteFinishHeader()
{
Byte record[NFileHeader::kRecordSize];
memset(record, 0, NFileHeader::kRecordSize);
for (unsigned i = 0; i < 2; i++)
const unsigned kNumFinishRecords = 2;
/* GNU TAR by default uses --blocking-factor=20 (512 * 20 = 10 KiB)
we also can use cluster alignment:
const unsigned numBlocks = (unsigned)(Pos / NFileHeader::kRecordSize) + kNumFinishRecords;
const unsigned kNumClusterBlocks = (1 << 3); // 8 blocks = 4 KiB
const unsigned numFinishRecords = kNumFinishRecords + ((kNumClusterBlocks - numBlocks) & (kNumClusterBlocks - 1));
*/
for (unsigned i = 0; i < kNumFinishRecords; i++)
{
RINOK(WriteBytes(record, NFileHeader::kRecordSize));
}

View File

@@ -68,6 +68,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
if (ui.NewProps)
{
item.SetDefaultWriteFields();
item.Mode = ui.Mode;
item.Name = ui.Name;
item.User = ui.User;
@@ -85,11 +86,6 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
}
item.MTime = ui.MTime;
item.DeviceMajorDefined = false;
item.DeviceMinorDefined = false;
item.UID = 0;
item.GID = 0;
memcpy(item.Magic, NFileHeader::NMagic::kUsTar_00, 8);
}
else
item = inputItems[(unsigned)ui.IndexInArc];

View File

@@ -403,14 +403,14 @@ STDMETHODIMP CHandler::Close()
{
_table.Free();
_phySize = 0;
_size = 0;
_isArc = false;
_unsupported = false;
for (unsigned i = 0; i < kNumGuids; i++)
memset(Guids[i], 0, 16);
_imgExt = NULL;
// CHandlerImg:
Clear_HandlerImg_Vars();
Stream.Release();
return S_OK;
}

View File

@@ -226,9 +226,9 @@ class CHandler: public CHandlerImg
CByteBuffer BitMap;
UInt32 BitMapTag;
UInt32 NumUsedBlocks;
// CMyComPtr<IInStream> Stream;
CMyComPtr<IInStream> ParentStream;
CHandler *Parent;
UInt64 NumLevels;
UString _errorMessage;
// bool _unexpectedEnd;
@@ -604,11 +604,12 @@ enum
static const CStatProp kArcProps[] =
{
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidOffset, VT_UI8},
{ NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidClusterSize, VT_UI8},
{ NULL, kpidMethod, VT_BSTR},
{ NULL, kpidNumVolumes, VT_UI4},
{ NULL, kpidTotalPhySize, VT_UI8},
{ "Parent", kpidParent, VT_BSTR},
{ NULL, kpidCreatorApp, VT_BSTR},
{ NULL, kpidHostOS, VT_BSTR},
@@ -734,6 +735,21 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidParent: if (NeedParent()) prop = GetParentSequence(); break;
case kpidOffset: prop = _startOffset; break;
case kpidPhySize: prop = _phySize; break;
case kpidTotalPhySize:
{
const CHandler *p = this;
UInt64 sum = 0;
do
{
sum += p->_phySize;
p = p->Parent;
}
while (p);
prop = sum;
break;
}
case kpidNumVolumes: if (NumLevels != 1) prop = (UInt32)NumLevels; break;
/*
case kpidErrorFlags:
{
@@ -762,6 +778,7 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
RINOK(Open3());
NumLevels = 1;
if (child && memcmp(child->Dyn.ParentId, Footer.Id, 16) != 0)
return S_FALSE;
if (Footer.Type != kDiskType_Diff)
@@ -826,6 +843,10 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
// we must show that error code
}
}
if (res == S_OK)
{
NumLevels = Parent->NumLevels + 1;
}
}
{
const CHandler *p = this;
@@ -845,16 +866,19 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
void CHandler::CloseAtError()
{
// CHandlerImg:
Stream.Release();
Clear_HandlerImg_Vars();
_phySize = 0;
NumLevels = 0;
Bat.Clear();
NumUsedBlocks = 0;
Parent = NULL;
Stream.Release();
ParentStream.Release();
Dyn.Clear();
_errorMessage.Empty();
// _unexpectedEnd = false;
_imgExt = NULL;
}
STDMETHODIMP CHandler::Close()
@@ -891,7 +915,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)
{
COM_TRY_BEGIN
*stream = 0;
*stream = NULL;
if (Footer.IsFixed())
{
CLimitedInStream *streamSpec = new CLimitedInStream;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1430,7 +1430,6 @@ HRESULT CExtent::Open3(IInStream *stream, IArchiveOpenCallback *openCallback,
STDMETHODIMP CHandler::Close()
{
_phySize = 0;
_size = 0;
_cacheCluster = (UInt64)(Int64)-1;
_cacheExtent = (unsigned)(int)-1;
@@ -1450,8 +1449,10 @@ STDMETHODIMP CHandler::Close()
_descriptorBuf.Free();
_descriptor.Clear();
_imgExt = NULL;
Stream.Release(); // Stream vriable is unused
// CHandlerImg:
Clear_HandlerImg_Vars();
Stream.Release();
_extents.Clear();
return S_OK;
}

View File

@@ -1942,10 +1942,6 @@ SOURCE=..\..\..\..\C\Threads.c
SOURCE=..\..\..\..\C\Threads.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Types.h
# End Source File
# End Group
# Begin Group "Crypto"

View File

@@ -3,5 +3,5 @@
STRINGTABLE
BEGIN
100 "7z zip rar 001 cab iso xz txz lzma tar cpio bz2 bzip2 tbz2 tbz gz gzip tgz tpz z taz lzh lha rpm deb arj vhd wim swm esd fat ntfs dmg hfs xar squashfs"
100 "7z zip rar 001 cab iso xz txz lzma tar cpio bz2 bzip2 tbz2 tbz gz gzip tgz tpz z taz lzh lha rpm deb arj vhd vhdx wim swm esd fat ntfs dmg hfs xar squashfs"
END

View File

@@ -89,6 +89,7 @@ AR_OBJS = \
$O\UefiHandler.obj \
$O\VdiHandler.obj \
$O\VhdHandler.obj \
$O\VhdxHandler.obj \
$O\VmdkHandler.obj \
$O\XarHandler.obj \
$O\XzHandler.obj \

View File

@@ -118,6 +118,7 @@ AR_OBJS = \
$O/UefiHandler.o \
$O/VdiHandler.o \
$O/VhdHandler.o \
$O/VhdxHandler.o \
$O/VmdkHandler.o \
$O/XarHandler.o \
$O/XzHandler.o \
@@ -175,10 +176,14 @@ NSIS_OBJS = \
$O/NsisIn.o \
$O/NsisRegister.o \
ifndef DISABLE_RAR
RAR_OBJS = \
$O/RarHandler.o \
$O/Rar5Handler.o \
endif
TAR_OBJS = \
$O/TarHandler.o \
$O/TarHandlerOut.o \
@@ -245,12 +250,6 @@ COMPRESS_OBJS = \
$O/PpmdRegister.o \
$O/PpmdZip.o \
$O/QuantumDecoder.o \
$O/Rar1Decoder.o \
$O/Rar2Decoder.o \
$O/Rar3Decoder.o \
$O/Rar3Vm.o \
$O/Rar5Decoder.o \
$O/RarCodecsRegister.o \
$O/ShrinkDecoder.o \
$O/XpressDecoder.o \
$O/XzDecoder.o \
@@ -259,6 +258,20 @@ COMPRESS_OBJS = \
$O/ZlibEncoder.o \
$O/ZDecoder.o \
ifdef DISABLE_RAR
DISABLE_RAR_COMPRESS=1
endif
ifndef DISABLE_RAR_COMPRESS
COMPRESS_OBJS += \
$O/Rar1Decoder.o \
$O/Rar2Decoder.o \
$O/Rar3Decoder.o \
$O/Rar3Vm.o \
$O/Rar5Decoder.o \
$O/RarCodecsRegister.o \
endif
CRYPTO_OBJS = \
$O/7zAes.o \
@@ -269,13 +282,18 @@ CRYPTO_OBJS = \
$O/MyAesReg.o \
$O/Pbkdf2HmacSha1.o \
$O/RandGen.o \
$O/Rar20Crypto.o \
$O/Rar5Aes.o \
$O/RarAes.o \
$O/WzAes.o \
$O/ZipCrypto.o \
$O/ZipStrong.o \
ifndef DISABLE_RAR
CRYPTO_OBJS += \
$O/Rar20Crypto.o \
$O/Rar5Aes.o \
$O/RarAes.o \
endif
C_OBJS = \
$O/7zBuf2.o \
@@ -323,7 +341,7 @@ C_OBJS = \
$O/Sha1Opt.o \
ARC_OBJS = \
$(LZMA_DEC_OPT_OBJS) \
$(LZMA_DEC_OPT_OBJS) \
$(C_OBJS) \
$(MT_OBJS) \
$(COMMON_OBJS) \

View File

@@ -2929,6 +2929,10 @@ SOURCE=..\..\Archive\VhdHandler.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\VhdxHandler.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Archive\VmdkHandler.cpp
# End Source File
# Begin Source File

View File

@@ -33,5 +33,5 @@ MY_VERSION_INFO_DLL("7z Plugin" , "7z")
STRINGTABLE
BEGIN
100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 z:5 taz:5 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 wim:15 swm:15 esd:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24"
100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 z:5 taz:5 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 vhdx:20 wim:15 swm:15 esd:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24"
END

View File

@@ -208,7 +208,7 @@ static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
if (!IsWildcardFilePathLegal(name))
return false;
*/
bool isWildcard = DoesNameContainWildcard(name);
const bool isWildcard = DoesNameContainWildcard(name);
bool recursed = false;
switch (type)
@@ -223,7 +223,10 @@ static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
recursed = false;
break;
}
wildcardCensor.AddPreItem(include, name, recursed, true);
NWildcard::CCensorPathProps props;
props.Recursive = recursed;
wildcardCensor.AddPreItem(include, name, props);
return true;
}

View File

@@ -178,7 +178,7 @@ static int APIENTRY WinMain2()
v1.Add(fs2us(fullPath));
v2.Add(fs2us(fullPath));
NWildcard::CCensorNode wildcardCensor;
wildcardCensor.AddItem(true, L"*", true, true, true, true);
wildcardCensor.Add_Wildcard();
bool messageWasDisplayed = false;
result = ExtractGUI(codecs,

View File

@@ -263,8 +263,13 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos
}
#endif
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
UInt64 realNewPosition = 0;
const bool result = File.Seek(offset, seekOrigin, realNewPosition);
const HRESULT hres = ConvertBoolToHRESULT(result);
/* 21.07: new File.Seek() in 21.07 already returns correct (realNewPosition)
in case of error. So we don't need additional code below */
// if (!result) { realNewPosition = 0; File.GetPosition(realNewPosition); }
#ifdef SUPPORT_DEVICE_FILE
PhyPos = VirtPos = realNewPosition;
@@ -272,13 +277,19 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos
if (newPosition)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
return hres;
#else
off_t res = File.seek((off_t)offset, (int)seekOrigin);
const off_t res = File.seek((off_t)offset, (int)seekOrigin);
if (res == -1)
return GetLastError_HRESULT();
{
const HRESULT hres = GetLastError_HRESULT();
if (newPosition)
*newPosition = (UInt64)File.seekToCur();
return hres;
}
if (newPosition)
*newPosition = (UInt64)res;
return S_OK;
@@ -435,15 +446,15 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
#ifdef USE_WIN_FILE
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
UInt64 realNewPosition = 0;
const bool result = File.Seek(offset, seekOrigin, realNewPosition);
if (newPosition)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
#else
off_t res = File.seek((off_t)offset, (int)seekOrigin);
const off_t res = File.seek((off_t)offset, (int)seekOrigin);
if (res == -1)
return GetLastError_HRESULT();
if (newPosition)
@@ -455,24 +466,7 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)
{
#ifdef USE_WIN_FILE
UInt64 currentPos;
if (!File.Seek(0, FILE_CURRENT, currentPos))
return E_FAIL;
bool result = File.SetLength(newSize);
UInt64 currentPos2;
result = result && File.Seek(currentPos, currentPos2);
return result ? S_OK : E_FAIL;
#else
// SetLength() uses ftruncate() that doesn't change file offset
if (!File.SetLength(newSize))
return GetLastError_HRESULT();
return S_OK;
#endif
return ConvertBoolToHRESULT(File.SetLength_KeepPosition(newSize));
}
HRESULT COutFileStream::GetSize(UInt64 *size)

View File

@@ -37,12 +37,34 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
for (;;)
{
UInt32 size = kBufSize;
if (outSize && size > *outSize - TotalSize)
size = (UInt32)(*outSize - TotalSize);
if (size == 0)
return S_OK;
if (outSize)
{
const UInt64 rem = *outSize - TotalSize;
if (size > rem)
{
size = (UInt32)rem;
if (size == 0)
return S_OK;
}
}
HRESULT readRes = inStream->Read(_buf, size, &size);
HRESULT readRes;
{
UInt32 pos = 0;
do
{
const UInt32 curSize = size - pos;
UInt32 processed = 0;
readRes = inStream->Read(_buf + pos, curSize, &processed);
if (processed > curSize)
return E_FAIL; // internal code failure
pos += processed;
if (readRes != S_OK || processed == 0)
break;
}
while (pos < kBufSize);
size = pos;
}
if (size == 0)
return readRes;
@@ -52,12 +74,15 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
UInt32 pos = 0;
do
{
UInt32 curSize = size - pos;
HRESULT res = outStream->Write(_buf + pos, curSize, &curSize);
pos += curSize;
TotalSize += curSize;
const UInt32 curSize = size - pos;
UInt32 processed = 0;
const HRESULT res = outStream->Write(_buf + pos, curSize, &processed);
if (processed > curSize)
return E_FAIL; // internal code failure
pos += processed;
TotalSize += processed;
RINOK(res);
if (curSize == 0)
if (processed == 0)
return E_FAIL;
}
while (pos < size);
@@ -67,7 +92,10 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
RINOK(readRes);
if (progress)
if (size != kBufSize)
return S_OK;
if (progress && (TotalSize & (((UInt32)1 << 22) - 1)) == 0)
{
RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
}

View File

@@ -169,6 +169,7 @@ Handler GUIDs:
0C xz
0D ppmd
C4 Vhdx
C5 Base64
C6 COFF
C7 Ext

View File

@@ -1887,23 +1887,23 @@ STDMETHODIMP CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)
break;
case kpidErrorFlags:
{
UInt32 flags = arc.ErrorInfo.GetErrorFlags();
const UInt32 flags = arc.ErrorInfo.GetErrorFlags();
if (flags != 0)
prop = flags;
break;
}
case kpidWarningFlags:
{
UInt32 flags = arc.ErrorInfo.GetWarningFlags();
const UInt32 flags = arc.ErrorInfo.GetWarningFlags();
if (flags != 0)
prop = flags;
break;
}
case kpidOffset:
{
Int64 v = arc.GetGlobalOffset();
const Int64 v = arc.GetGlobalOffset();
if (v != 0)
prop = v;
prop.Set_Int64(v);
break;
}
case kpidTailSize:

View File

@@ -151,6 +151,7 @@ enum Enum
kCaseSensitive,
kArcNameMode,
kUseSlashMark,
kDisableWildcardParsing,
kElimDup,
kFullPathMode,
@@ -294,6 +295,7 @@ static const CSwitchForm kSwitchForms[] =
{ "ssc", SWFRM_MINUS },
{ "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet },
{ "spm", SWFRM_STRING_SINGL(0) },
{ "spd", SWFRM_SIMPLE },
{ "spe", SWFRM_MINUS },
{ "spf", SWFRM_STRING_SINGL(0) },
@@ -407,12 +409,28 @@ static bool ParseArchiveCommand(const UString &commandString, CArcCommand &comma
// ------------------------------------------------------------------
// filenames functions
struct CNameOption
{
bool Include;
bool WildcardMatching;
Byte MarkMode;
NRecursedType::EEnum RecursedType;
CNameOption():
Include(true),
WildcardMatching(true),
MarkMode(NWildcard::kMark_FileOrDir),
RecursedType(NRecursedType::kNonRecursed)
{}
};
static void AddNameToCensor(NWildcard::CCensor &censor,
const UString &name, bool include, NRecursedType::EEnum type, bool wildcardMatching)
const CNameOption &nop, const UString &name)
{
bool recursed = false;
switch (type)
switch (nop.RecursedType)
{
case NRecursedType::kWildcardOnlyRecursed:
recursed = DoesNameContainWildcard(name);
@@ -423,7 +441,12 @@ static void AddNameToCensor(NWildcard::CCensor &censor,
default:
break;
}
censor.AddPreItem(include, name, recursed, wildcardMatching);
NWildcard::CCensorPathProps props;
props.Recursive = recursed;
props.WildcardMatching = nop.WildcardMatching;
props.MarkMode = nop.MarkMode;
censor.AddPreItem(nop.Include, name, props);
}
static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
@@ -454,7 +477,7 @@ static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
static void AddToCensorFromListFile(
CObjectVector<CRenamePair> *renamePairs,
NWildcard::CCensor &censor,
LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, UInt32 codePage)
const CNameOption &nop, LPCWSTR fileName, UInt32 codePage)
{
UStringVector names;
/*
@@ -481,12 +504,12 @@ static void AddToCensorFromListFile(
for (unsigned i = 0; i < names.Size(); i += 2)
{
// change type !!!!
AddRenamePair(renamePairs, names[i], names[i + 1], type, wildcardMatching);
AddRenamePair(renamePairs, names[i], names[i + 1], nop.RecursedType, nop.WildcardMatching);
}
}
else
FOR_VECTOR (i, names)
AddNameToCensor(censor, names[i], include, type, wildcardMatching);
AddNameToCensor(censor, nop, names[i]);
}
static void AddToCensorFromNonSwitchesStrings(
@@ -495,14 +518,27 @@ static void AddToCensorFromNonSwitchesStrings(
NWildcard::CCensor &censor,
const UStringVector &nonSwitchStrings,
int stopSwitchIndex,
NRecursedType::EEnum type,
bool wildcardMatching,
const CNameOption &nop,
bool thereAreSwitchIncludes, UInt32 codePage)
{
// another default
if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes)
AddNameToCensor(censor, UString(kUniversalWildcard), true, type,
true // wildcardMatching
);
{
/* for rename command: -i switch sets the mask for archive item reading.
if (thereAreSwitchIncludes), { we don't use UniversalWildcard. }
also for non-rename command: we set UniversalWildcard, only if there are no nonSwitches. */
// we use default fileds in (CNameOption) for UniversalWildcard.
CNameOption nop2;
// recursive mode is not important for UniversalWildcard (*)
// nop2.RecursedType = nop.RecursedType; // we don't need it
/*
nop2.RecursedType = NRecursedType::kNonRecursed;
nop2.Include = true;
nop2.WildcardMatching = true;
nop2.MarkMode = NWildcard::kMark_FileOrDir;
*/
AddNameToCensor(censor, nop2, UString(kUniversalWildcard));
}
int oldIndex = -1;
@@ -515,7 +551,7 @@ static void AddToCensorFromNonSwitchesStrings(
if (s.IsEmpty())
throw CArcCmdLineException(kEmptyFilePath);
if (i < (unsigned)stopSwitchIndex && s[0] == kFileListID)
AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage);
AddToCensorFromListFile(renamePairs, censor, nop, s.Ptr(1), codePage);
else if (renamePairs)
{
if (oldIndex == -1)
@@ -523,13 +559,13 @@ static void AddToCensorFromNonSwitchesStrings(
else
{
// NRecursedType::EEnum type is used for global wildcard (-i! switches)
AddRenamePair(renamePairs, nonSwitchStrings[(unsigned)oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching);
AddRenamePair(renamePairs, nonSwitchStrings[(unsigned)oldIndex], s, NRecursedType::kNonRecursed, nop.WildcardMatching);
// AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type);
oldIndex = -1;
}
}
else
AddNameToCensor(censor, s, true, type, wildcardMatching);
AddNameToCensor(censor, nop, s);
}
if (oldIndex != -1)
@@ -557,9 +593,8 @@ static const char * const k_IncorrectMapCommand = "Incorrect Map command";
static const char *ParseMapWithPaths(
NWildcard::CCensor &censor,
const UString &s2, bool include,
NRecursedType::EEnum commonRecursedType,
bool wildcardMatching)
const UString &s2,
const CNameOption &nop)
{
UString s (s2);
int pos = s.Find(L':');
@@ -598,7 +633,7 @@ static const char *ParseMapWithPaths(
if (c == 0)
{
// MessageBoxW(0, name, L"7-Zip", 0);
AddNameToCensor(censor, name, include, commonRecursedType, wildcardMatching);
AddNameToCensor(censor, nop, name);
name.Empty();
}
else
@@ -614,9 +649,8 @@ static const char *ParseMapWithPaths(
static void AddSwitchWildcardsToCensor(
NWildcard::CCensor &censor,
const UStringVector &strings, bool include,
NRecursedType::EEnum commonRecursedType,
bool wildcardMatching,
const UStringVector &strings,
const CNameOption &nop,
UInt32 codePage)
{
const char *errorMessage = NULL;
@@ -624,7 +658,6 @@ static void AddSwitchWildcardsToCensor(
for (i = 0; i < strings.Size(); i++)
{
const UString &name = strings[i];
NRecursedType::EEnum recursedType;
unsigned pos = 0;
if (name.Len() < kSomeCludePostStringMinSize)
@@ -633,7 +666,7 @@ static void AddSwitchWildcardsToCensor(
break;
}
if (!include)
if (!nop.Include)
{
if (name.IsEqualTo_Ascii_NoCase("td"))
{
@@ -647,19 +680,84 @@ static void AddSwitchWildcardsToCensor(
}
}
if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar)
CNameOption nop2 = nop;
bool type_WasUsed = false;
bool recursed_WasUsed = false;
bool matching_WasUsed = false;
bool error = false;
for (;;)
{
pos++;
wchar_t c = name[pos];
int index = -1;
if (c <= 0x7F)
index = FindCharPosInString(kRecursedPostCharSet, (char)c);
recursedType = GetRecursedTypeFromIndex(index);
if (index >= 0)
wchar_t c = ::MyCharLower_Ascii(name[pos]);
if (c == kRecursedIDChar)
{
if (recursed_WasUsed)
{
error = true;
break;
}
recursed_WasUsed = true;
pos++;
c = name[pos];
int index = -1;
if (c <= 0x7F)
index = FindCharPosInString(kRecursedPostCharSet, (char)c);
nop2.RecursedType = GetRecursedTypeFromIndex(index);
if (index >= 0)
{
pos++;
continue;
}
}
if (c == 'w')
{
if (matching_WasUsed)
{
error = true;
break;
}
matching_WasUsed = true;
nop2.WildcardMatching = true;
pos++;
if (name[pos] == '-')
{
nop2.WildcardMatching = false;
pos++;
}
}
else if (c == 'm')
{
if (type_WasUsed)
{
error = true;
break;
}
type_WasUsed = true;
pos++;
nop2.MarkMode = NWildcard::kMark_StrictFile;
c = name[pos];
if (c == '-')
{
nop2.MarkMode = NWildcard::kMark_FileOrDir;
pos++;
}
else if (c == '2')
{
nop2.MarkMode = NWildcard::kMark_StrictFile_IfWildcard;
pos++;
}
}
else
break;
}
if (error)
{
errorMessage = "inorrect switch";
break;
}
else
recursedType = commonRecursedType;
if (name.Len() < pos + kSomeCludeAfterRecursedPostStringMinSize)
{
@@ -669,14 +767,16 @@ static void AddSwitchWildcardsToCensor(
const UString tail = name.Ptr(pos + 1);
if (name[pos] == kImmediateNameID)
AddNameToCensor(censor, tail, include, recursedType, wildcardMatching);
else if (name[pos] == kFileListID)
AddToCensorFromListFile(NULL, censor, tail, include, recursedType, wildcardMatching, codePage);
const wchar_t c = name[pos];
if (c == kImmediateNameID)
AddNameToCensor(censor, nop2, tail);
else if (c == kFileListID)
AddToCensorFromListFile(NULL, censor, nop2, tail, codePage);
#ifdef _WIN32
else if (name[pos] == kMapNameID)
else if (c == kMapNameID)
{
errorMessage = ParseMapWithPaths(censor, tail, include, recursedType, wildcardMatching);
errorMessage = ParseMapWithPaths(censor, tail, nop2);
if (errorMessage)
break;
}
@@ -687,6 +787,7 @@ static void AddSwitchWildcardsToCensor(
break;
}
}
if (i != strings.Size())
throw CArcCmdLineException(errorMessage, strings[i]);
}
@@ -1165,15 +1266,27 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (parser[NKey::kNameTrailReplace].ThereIs)
g_PathTrailReplaceMode = !parser[NKey::kNameTrailReplace].WithMinus;
NRecursedType::EEnum recursedType;
if (parser[NKey::kRecursed].ThereIs)
recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
else
recursedType = NRecursedType::kNonRecursed;
CNameOption nop;
if (parser[NKey::kRecursed].ThereIs)
nop.RecursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
bool wildcardMatching = true;
if (parser[NKey::kDisableWildcardParsing].ThereIs)
wildcardMatching = false;
nop.WildcardMatching = false;
if (parser[NKey::kUseSlashMark].ThereIs)
{
const UString &s = parser[NKey::kUseSlashMark].PostStrings[0];
if (s.IsEmpty())
nop.MarkMode = NWildcard::kMark_StrictFile;
else if (s.IsEqualTo_Ascii_NoCase("-"))
nop.MarkMode = NWildcard::kMark_FileOrDir;
else if (s.IsEqualTo_Ascii_NoCase("2"))
nop.MarkMode = NWildcard::kMark_StrictFile_IfWildcard;
else
throw CArcCmdLineException("Unsupported -spm:", s);
}
options.ConsoleCodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1);
@@ -1184,13 +1297,17 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (parser[NKey::kInclude].ThereIs)
{
thereAreSwitchIncludes = true;
nop.Include = true;
AddSwitchWildcardsToCensor(options.Censor,
parser[NKey::kInclude].PostStrings, true, recursedType, wildcardMatching, codePage);
parser[NKey::kInclude].PostStrings, nop, codePage);
}
if (parser[NKey::kExclude].ThereIs)
{
nop.Include = false;
AddSwitchWildcardsToCensor(options.Censor,
parser[NKey::kExclude].PostStrings, false, recursedType, wildcardMatching, codePage);
parser[NKey::kExclude].PostStrings, nop, codePage);
}
unsigned curCommandIndex = kCommandIndex + 1;
bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs &&
@@ -1198,9 +1315,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
options.Command.CommandType != NCommandType::kInfo &&
options.Command.CommandType != NCommandType::kHash;
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList;
bool isRename = options.Command.CommandType == NCommandType::kRename;
const bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
const bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList;
const bool isRename = options.Command.CommandType == NCommandType::kRename;
if ((isExtractOrList || isRename) && options.StdInMode)
thereIsArchiveName = false;
@@ -1220,10 +1337,11 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
#endif
}
nop.Include = true;
AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL,
curCommandIndex, options.Censor,
nonSwitchStrings, parser.StopSwitchIndex,
recursedType, wildcardMatching,
nop,
thereAreSwitchIncludes, codePage);
options.YesToAll = parser[NKey::kYes].ThereIs;
@@ -1317,13 +1435,28 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
NWildcard::CCensor &arcCensor = options.arcCensor;
CNameOption nopArc;
// nopArc.RecursedType = NRecursedType::kNonRecursed; // default: we don't want recursing for archives, if -r specified
// is it OK, external switches can disable WildcardMatching and MarcMode for arc.
nopArc.WildcardMatching = nop.WildcardMatching;
nopArc.MarkMode = nop.MarkMode;
if (parser[NKey::kArInclude].ThereIs)
AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, wildcardMatching, codePage);
{
nopArc.Include = true;
AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, nopArc, codePage);
}
if (parser[NKey::kArExclude].ThereIs)
AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, wildcardMatching, codePage);
{
nopArc.Include = false;
AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, nopArc, codePage);
}
if (thereIsArchiveName)
AddNameToCensor(arcCensor, options.ArchiveName, true, NRecursedType::kNonRecursed, wildcardMatching);
{
nopArc.Include = true;
AddNameToCensor(arcCensor, nopArc, options.ArchiveName);
}
arcCensor.AddPathsToCensor(NWildcard::k_RelatPath);
@@ -1515,7 +1648,7 @@ FString GetModuleDirPrefix()
{
FString s;
s = g_ModuleDirPrefix;
s = fas2fs(g_ModuleDirPrefix);
if (s.IsEmpty())
s = FTEXT(".") FSTRING_PATH_SEPARATOR;
return s;

View File

@@ -1000,8 +1000,8 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool
if (_overwriteMode == NExtract::NOverwriteMode::kAsk)
{
int slashPos = fullProcessedPath.ReverseFind_PathSepar();
FString realFullProcessedPath (fullProcessedPath.Left((unsigned)(slashPos + 1)) + fileInfo.Name);
const int slashPos = fullProcessedPath.ReverseFind_PathSepar();
const FString realFullProcessedPath = fullProcessedPath.Left((unsigned)(slashPos + 1)) + fileInfo.Name;
/* (fileInfo) can be symbolic link.
we can show final file properties here. */

View File

@@ -48,7 +48,7 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
else
switch (propID)
{
case kpidName: prop = _fileInfo.Name; break;
case kpidName: prop = fs2us(_fileInfo.Name); break;
case kpidIsDir: prop = _fileInfo.IsDir(); break;
case kpidSize: prop = _fileInfo.Size; break;
case kpidAttrib: prop = (UInt32)_fileInfo.Attrib; break;
@@ -103,12 +103,20 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
if (!IsSafePath(name2))
return S_FALSE;
// #ifdef _WIN32
// we don't want to support wildcards in names here here
if (name2.Find(L'?') >= 0 ||
name2.Find(L'*') >= 0)
#ifdef _WIN32
/* WIN32 allows wildcards in Find() function
and doesn't allow wildcard in File.Open()
so we can work without the following wildcard check here */
if (name2.Find(L'*') >= 0)
return S_FALSE;
// #endif
{
int startPos = 0;
if (name2.IsPrefixedBy_Ascii_NoCase("\\\\?\\"))
startPos = 3;
if (name2.Find(L'?', startPos) >= 0)
return S_FALSE;
}
#endif
#endif

View File

@@ -866,7 +866,7 @@ struct CAffinityMode
DWORD_PTR GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const;
bool NeedAffinity() const { return NumBundleThreads != 0; }
WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter, UInt32 bundleIndex) const
WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_TYPE startAddress, LPVOID parameter, UInt32 bundleIndex) const
{
if (NeedAffinity())
{

View File

@@ -33,12 +33,16 @@ using namespace NWindows;
#define k7zGui "7zG.exe"
// 21.07 : we can disable wildcard
// #define ISWITCH_NO_WILDCARD_POSTFIX "w-"
#define ISWITCH_NO_WILDCARD_POSTFIX
#define kShowDialogSwitch " -ad"
#define kEmailSwitch " -seml."
#define kIncludeSwitch " -i"
#define kArchiveTypeSwitch " -t"
#define kArcIncludeSwitches " -an -ai"
#define kHashIncludeSwitches " -i"
#define kIncludeSwitch " -i" ISWITCH_NO_WILDCARD_POSTFIX
#define kArcIncludeSwitches " -an -ai" ISWITCH_NO_WILDCARD_POSTFIX
#define kHashIncludeSwitches kIncludeSwitch
#define kStopSwitchParsing " --"
extern HWND g_HWND;

View File

@@ -124,7 +124,7 @@ HRESULT CompressFiles(
NWildcard::CCensor censor;
FOR_VECTOR (i, names)
{
censor.AddPreItem(names[i]);
censor.AddPreItem_NoWildcard(names[i]);
}
bool messageWasDisplayed = false;
@@ -178,7 +178,7 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
NWildcard::CCensor arcCensor;
FOR_VECTOR (i, arcPaths)
{
arcCensor.AddPreItem(arcPaths[i]);
arcCensor.AddPreItem_NoWildcard(arcPaths[i]);
}
arcCensor.AddPathsToCensor(NWildcard::k_RelatPath);
CDirItemsStat st;
@@ -268,7 +268,7 @@ void CalcChecksum(const UStringVector &paths,
NWildcard::CCensor censor;
FOR_VECTOR (i, paths)
{
censor.AddPreItem(paths[i]);
censor.AddPreItem_NoWildcard(paths[i]);
}
censor.AddPathsToCensor(NWildcard::k_RelatPath);

View File

@@ -767,6 +767,15 @@ static HRESULT EnumerateDirItems(
const UString &name = item.PathParts.Front();
FString fullPath = phyPrefix + us2fs(name);
/*
// not possible now
if (!item.ForDir && !item.ForFile)
{
RINOK(dirItems.AddError(fullPath, ERROR_INVALID_PARAMETER));
continue;
}
*/
#if defined(_WIN32) && !defined(UNDER_CE)
bool needAltStreams = true;
#endif
@@ -823,9 +832,20 @@ static HRESULT EnumerateDirItems(
continue;
}
/*
#ifdef _WIN32
#define MY_ERROR_IS_DIR ERROR_FILE_NOT_FOUND
#define MY_ERROR_NOT_DIR DI_DEFAULT_ERROR
#else
#define MY_ERROR_IS_DIR EISDIR
#define MY_ERROR_NOT_DIR ENOTDIR
#endif
*/
const bool isDir = fi.IsDir();
if ((isDir && !item.ForDir) || (!isDir && !item.ForFile))
if (isDir ? !item.ForDir : !item.ForFile)
{
// RINOK(dirItems.AddError(fullPath, isDir ? MY_ERROR_IS_DIR: MY_ERROR_NOT_DIR));
RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR));
continue;
}

View File

@@ -900,7 +900,7 @@ bool CHashPair::Parse(const char *s)
return false;
if (escape)
{
AString temp = Name;
const AString temp (Name);
return CSum_Name_EscapeToOriginal(temp, Name);
}
return true;

View File

@@ -974,6 +974,17 @@ static HRESULT Compress(
static bool Censor_AreAllAllowed(const NWildcard::CCensor &censor)
{
if (censor.Pairs.Size() != 1)
return false;
const NWildcard::CPair &pair = censor.Pairs[0];
/* Censor_CheckPath() ignores (CPair::Prefix).
So we also ignore (CPair::Prefix) here */
// if (!pair.Prefix.IsEmpty()) return false;
return pair.Head.AreAllAllowed();
}
bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include);
static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcItem &item)
@@ -981,9 +992,13 @@ static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcIte
bool finded = false;
FOR_VECTOR (i, censor.Pairs)
{
/* (CPair::Prefix) in not used for matching items in archive.
So we ignore (CPair::Prefix) here */
bool include;
if (CensorNode_CheckPath2(censor.Pairs[i].Head, item, include))
{
// Check it and FIXME !!!!
// here we can exclude item via some Pair, that is still allowed by another Pair
if (!include)
return false;
finded = true;
@@ -1006,6 +1021,8 @@ static HRESULT EnumerateInArchiveItems(
CReadArcItem item;
const bool allFilesAreAllowed = Censor_AreAllAllowed(censor);
for (UInt32 i = 0; i < numItems; i++)
{
CArcItem ai;
@@ -1024,7 +1041,10 @@ static HRESULT EnumerateInArchiveItems(
if (!storeStreamsMode && ai.IsAltStream)
continue;
*/
ai.Censored = Censor_CheckPath(censor, item);
if (allFilesAreAllowed)
ai.Censored = true;
else
ai.Censored = Censor_CheckPath(censor, item);
RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));
RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined));
@@ -1418,7 +1438,7 @@ HRESULT UpdateArchive(
UString s;
s = "It is not allowed to include archive to itself";
s.Add_LF();
s += path;
s += fs2us(path);
throw s;
}
}

View File

@@ -138,7 +138,7 @@ static unsigned GetColumnWidth(unsigned digestSize)
AString CHashCallbackConsole::GetFields() const
{
AString s = PrintFields;
AString s (PrintFields);
if (s.IsEmpty())
s = "hsn";
s.MakeLower_Ascii();
@@ -313,7 +313,7 @@ HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBun
s = kEmptyFileAlias;
else
{
UString temp = _fileName;
UString temp (_fileName);
_so->Normalize_UString(temp);
_so->Convert_UString_to_AString(temp, s);
}

View File

@@ -840,7 +840,7 @@ static void UString_Replace_CRLF_to_LF(UString &s)
static void PrintPropVal_MultiLine(CStdOutStream &so, const wchar_t *val)
{
UString s = val;
UString s (val);
if (s.Find(L'\n') >= 0)
{
so << endl;
@@ -869,7 +869,7 @@ static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *va
PrintPropVal_MultiLine(so, val);
return;
}
UString s = val;
UString s (val);
so.Normalize_UString(s);
so << s;
so << endl;

View File

@@ -947,7 +947,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
else
name = fs2us(fi0.Name);
name += ".sha256";
cmi.Folder= folderPrefix;
cmi.Folder = fs2us(folderPrefix);
cmi.ArcName = name;
s = "SHA-256 -> ";
s += name;

View File

@@ -13,6 +13,48 @@
#else
/* IShellItem is defined:
ShObjIdl.h : old Windows SDK
ShObjIdl_core.h : new Windows 10 SDK */
#include <ShObjIdl.h>
#ifndef __IShellItem_INTERFACE_DEFINED__
#define __IShellItem_INTERFACE_DEFINED__
// For MINGW we define IShellItem
// #error Stop_Compiling__NOT_DEFINED__IShellItem_INTERFACE_DEFINED__
typedef
enum
{ SIGDN_NORMALDISPLAY = 0,
SIGDN_PARENTRELATIVEPARSING = 0x80018001,
SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000,
SIGDN_PARENTRELATIVEEDITING = 0x80031001,
SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000,
SIGDN_FILESYSPATH = 0x80058000,
SIGDN_URL = 0x80068000
} SIGDN;
typedef DWORD SICHINTF;
typedef ULONG SFGAOF;
struct IShellItem : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut) = 0;
virtual HRESULT STDMETHODCALLTYPE GetParent(IShellItem **ppsi) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDisplayName(SIGDN sigdnName, LPOLESTR *ppszName) = 0;
virtual HRESULT STDMETHODCALLTYPE GetAttributes(SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs) = 0;
virtual HRESULT STDMETHODCALLTYPE Compare(IShellItem *psi, SICHINTF hint, int *piOrder) = 0;
};
#endif // __IShellItem_INTERFACE_DEFINED__
#ifndef __IShellItemArray_INTERFACE_DEFINED__
#define __IShellItemArray_INTERFACE_DEFINED__

View File

@@ -213,7 +213,7 @@ void CStartupInfo::RestoreScreen(HANDLE handle)
CSysString CStartupInfo::GetFullKeyName(const char *keyName) const
{
AString s = m_RegistryPath;
AString s (m_RegistryPath);
if (keyName && *keyName)
{
s += kRegistryKeyDelimiter;

View File

@@ -224,14 +224,14 @@ STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT
switch (propID)
{
case kpidIsDir: prop = !_volumeMode; break;
case kpidName: prop = di.Name; break;
case kpidName: prop = fs2us(di.Name); break;
case kpidOutName:
if (!di.Name.IsEmpty() && di.Name.Back() == ':')
{
FString s = di.Name;
s.DeleteBack();
AddExt(s, itemIndex);
prop = s;
prop = fs2us(s);
}
break;

View File

@@ -515,7 +515,7 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
}
case kpidPrefix:
if (fi.Parent >= 0)
prop = Folders[fi.Parent];
prop = fs2us(Folders[fi.Parent]);
break;
case kpidNumSubDirs: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFolders; break;
case kpidNumSubFiles: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFiles; break;

View File

@@ -473,7 +473,10 @@ static HRESULT CopyFile_Ask(
static FString CombinePath(const FString &folderPath, const FString &fileName)
{
return folderPath + FCHAR_PATH_SEPARATOR + fileName;
FString s (folderPath);
s.Add_PathSepar(); // FCHAR_PATH_SEPARATOR
s += fileName;
return s;
}
static bool IsDestChild(const FString &src, const FString &dest)

View File

@@ -487,6 +487,8 @@ void CFileMenu::Load(HMENU hMenu, unsigned startPos)
unsigned numRealItems = startPos;
const bool isBigScreen = NControl::IsDialogSizeOK(40, 200, g_HWND);
for (unsigned i = 0;; i++)
{
CMenuItem item;
@@ -568,8 +570,6 @@ void CFileMenu::Load(HMENU hMenu, unsigned startPos)
if (item.wID == IDM_ALT_STREAMS)
disable = !isAltStreamsSupported;
bool isBigScreen = NControl::IsDialogSizeOK(40, 200);
if (!isBigScreen && (disable || item.IsSeparator()))
continue;

View File

@@ -69,7 +69,7 @@ STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value
{
switch (propID)
{
case kpidName: prop = _fileInfo.Name; break;
case kpidName: prop = fs2us(_fileInfo.Name); break;
case kpidIsDir: prop = _fileInfo.IsDir(); break;
case kpidSize: prop = _fileInfo.Size; break;
case kpidAttrib: prop = (UInt32)_fileInfo.Attrib; break;

View File

@@ -289,7 +289,7 @@ HRESULT CThreadCrc::ProcessVirt()
}
if (isFirstFile)
{
Hash.FirstFileName = path;
Hash.FirstFileName = fs2us(path);
isFirstFile = false;
}
sync.Set_FilePath(fs2us(path));
@@ -375,7 +375,7 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i])));
if (t.Enumerator.FilePaths.Size() == 1)
t.Hash.MainName = t.Enumerator.FilePaths[0];
t.Hash.MainName = fs2us(t.Enumerator.FilePaths[0]);
UString basePrefix = srcPanel.GetFsPath();
UString basePrefix2 = basePrefix;

View File

@@ -511,7 +511,7 @@ void CPanel::ChangeComment()
LangString(IDS_COMMENT2, dlg.Static);
if (dlg.Create(GetParent()) != IDOK)
return;
NCOM::CPropVariant propVariant = dlg.Value.Ptr();
NCOM::CPropVariant propVariant (dlg.Value);
CDisableNotify disableNotify(*this);
HRESULT result = _folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL);

View File

@@ -65,7 +65,7 @@ CAPTION "Progress"
RTEXT "", IDT_PROGRESS_ELAPSED_VAL, x1, y0, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_REMAINING_VAL, x1, y1, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_FILES_VAL, x1, y2, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_FILES_TOTAL x1, y3, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_FILES_TOTAL, x1, y3, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_ERRORS_VAL, x1, y4, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_TOTAL_VAL, x3, y0, x3s, MY_TEXT_NOPREFIX

View File

@@ -389,11 +389,11 @@ void CApp::VerCtrl(unsigned id)
dialog.OldFileInfo.SetTime(&fdi.Info.ftLastWriteTime);
dialog.OldFileInfo.SetSize(fdi.GetSize());
dialog.OldFileInfo.Name = path;
dialog.OldFileInfo.Name = fs2us(path);
dialog.NewFileInfo.SetTime(&fdi2.Info.ftLastWriteTime);
dialog.NewFileInfo.SetSize(fdi2.GetSize());
dialog.NewFileInfo.Name = path2;
dialog.NewFileInfo.Name = fs2us(path2);
dialog.ShowExtraButtons = false;
dialog.DefaultButton_is_NO = true;

View File

@@ -341,10 +341,10 @@ public:
CBenchmarkDialog():
_timer(0),
TotalMode(false),
WasStopped_in_GUI(false),
ExitWasAsked_in_GUI(false),
NeedRestart(false)
NeedRestart(false),
TotalMode(false)
{}
~CBenchmarkDialog();

View File

@@ -1436,7 +1436,7 @@ UString CCompressDialog::GetMethodSpec(UString &estimatedName)
UString s;
if (methodId >= 0)
{
if (methodId < ARRAY_SIZE(kMethodsNames))
if ((unsigned)methodId < ARRAY_SIZE(kMethodsNames))
estimatedName = kMethodsNames[methodId];
else
estimatedName = ExternalMethods[methodId - ARRAY_SIZE(kMethodsNames)];

View File

@@ -112,9 +112,13 @@ static void ParseAndAddPropertires(CObjectVector<CProperty> &properties,
SplitString(propertiesString, strings);
FOR_VECTOR (i, strings)
{
const UString &s = strings[i];
UString s = strings[i];
if (s.Len() > 2
&& s[0] == '-'
&& MyCharLower_Ascii(s[1]) == 'm')
s.DeleteFrontal(2);
CProperty property;
int index = s.Find(L'=');
const int index = s.Find(L'=');
if (index < 0)
property.Name = s;
else

View File

@@ -1096,14 +1096,14 @@ UString::UString(char c)
UString::UString(const wchar_t *s)
{
unsigned len = MyStringLen(s);
const unsigned len = MyStringLen(s);
SetStartLen(len);
wmemcpy(_chars, s, len + 1);
}
UString::UString(const char *s)
{
unsigned len = MyStringLen(s);
const unsigned len = MyStringLen(s);
SetStartLen(len);
wchar_t *chars = _chars;
for (unsigned i = 0; i < len; i++)
@@ -1111,6 +1111,17 @@ UString::UString(const char *s)
chars[len] = 0;
}
UString::UString(const AString &s)
{
const unsigned len = s.Len();
SetStartLen(len);
wchar_t *chars = _chars;
const char *s2 = s.Ptr();
for (unsigned i = 0; i < len; i++)
chars[i] = (unsigned char)s2[i];
chars[len] = 0;
}
UString::UString(const UString &s)
{
SetStartLen(s._len);

View File

@@ -1,7 +1,7 @@
// Common/String.h
// Common/MyString.h
#ifndef __COMMON_STRING_H
#define __COMMON_STRING_H
#ifndef __COMMON_MY_STRING_H
#define __COMMON_MY_STRING_H
#include <string.h>
@@ -15,6 +15,17 @@
#include "MyVector.h"
/* if (DEBUG_FSTRING_INHERITS_ASTRING is defined), then
FString inherits from AString, so we can find bugs related to FString at compile time.
DON'T define DEBUG_FSTRING_INHERITS_ASTRING in release code */
// #define DEBUG_FSTRING_INHERITS_ASTRING
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
class FString;
#endif
#ifdef _MSC_VER
#ifdef _NATIVE_WCHAR_T_DEFINED
#define MY_NATIVE_WCHAR_T_DEFINED
@@ -290,6 +301,12 @@ class AString
FORBID_STRING_OPS_AString(long)
FORBID_STRING_OPS_AString(unsigned long)
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
AString(const FString &s);
AString &operator=(const FString &s);
AString &operator+=(const FString &s);
#endif
public:
explicit AString();
explicit AString(char c);
@@ -550,12 +567,18 @@ class UString
FORBID_STRING_OPS_2(UString, char)
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
UString(const FString &s);
UString &operator=(const FString &s);
UString &operator+=(const FString &s);
#endif
public:
UString();
explicit UString(wchar_t c);
explicit UString(char c);
explicit UString(const char *s);
// UString(const AString &s);
explicit UString(const AString &s);
UString(const wchar_t *s);
UString(const UString &s);
~UString() { MY_STRING_DELETE(_chars); }
@@ -795,7 +818,16 @@ class UString2
FORBID_STRING_OPS_UString2(short)
UString2 &operator=(wchar_t c);
UString2(wchar_t c);
UString2(const AString &s);
UString2 &operator=(const AString &s);
UString2 &operator+=(const AString &s);
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
UString2(const FString &s);
UString2 &operator=(const FString &s);
UString2 &operator+=(const FString &s);
#endif
public:
UString2(): _chars(NULL), _len(0) {}
@@ -871,9 +903,11 @@ typedef CObjectVector<CSysString> CSysStringVector;
// ---------- FString ----------
#ifndef DEBUG_FSTRING_INHERITS_ASTRING
#ifdef _WIN32
#define USE_UNICODE_FSTRING
#endif
#endif
#ifdef USE_UNICODE_FSTRING
@@ -893,12 +927,55 @@ typedef CObjectVector<CSysString> CSysStringVector;
#define __FTEXT(quote) quote
typedef char FChar;
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
class FString: public AString
{
// FString &operator=(const char *s);
FString &operator=(const AString &s);
// FString &operator+=(const AString &s);
public:
FString(const AString &s): AString(s.Ptr()) {}
FString(const FString &s): AString(s.Ptr()) {}
FString(const char *s): AString(s) {}
FString() {}
FString &operator=(const FString &s) { AString::operator=((const AString &)s); return *this; }
FString &operator=(char c) { AString::operator=(c); return *this; }
FString &operator+=(char c) { AString::operator+=(c); return *this; }
FString &operator+=(const FString &s) { AString::operator+=((const AString &)s); return *this; }
FString Left(unsigned count) const { return FString(AString::Left(count)); }
};
void operator+(const AString &s1, const FString &s2);
void operator+(const FString &s1, const AString &s2);
inline FString operator+(const FString &s1, const FString &s2)
{
AString s =(const AString &)s1 + (const AString &)s2;
return FString(s.Ptr());
// return FString((const AString &)s1 + (const AString &)s2);
}
inline FString operator+(const FString &s1, const FChar *s2)
{
return s1 + (FString)s2;
}
/*
inline FString operator+(const FChar *s1, const FString &s2)
{
return (FString)s1 + s2;
}
*/
inline FString fas2fs(const char *s) { return FString(s); }
#else // DEBUG_FSTRING_INHERITS_ASTRING
typedef AString FString;
#define fas2fs(_x_) (_x_)
#endif // DEBUG_FSTRING_INHERITS_ASTRING
UString fs2us(const FChar *s);
UString fs2us(const FString &s);
FString us2fs(const wchar_t *s);
#define fas2fs(_x_) (_x_)
#define fs2fas(_x_) (_x_)
#endif

View File

@@ -29,6 +29,70 @@ bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
// #include <stdio.h>
/*
static int MyStringCompare_PathLinux(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
if (c1 != c2)
{
if (c1 == 0) return -1;
if (c2 == 0) return 1;
if (c1 == '/') c1 = 0;
if (c2 == '/') c2 = 0;
if (c1 < c2) return -1;
if (c1 > c2) return 1;
continue;
}
if (c1 == 0) return 0;
}
}
*/
static int MyStringCompare_Path(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
if (c1 != c2)
{
if (c1 == 0) return -1;
if (c2 == 0) return 1;
if (IS_PATH_SEPAR(c1)) c1 = 0;
if (IS_PATH_SEPAR(c2)) c2 = 0;
if (c1 < c2) return -1;
if (c1 > c2) return 1;
continue;
}
if (c1 == 0) return 0;
}
}
static int MyStringCompareNoCase_Path(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
wchar_t c1 = *s1++;
wchar_t c2 = *s2++;
if (c1 != c2)
{
if (c1 == 0) return -1;
if (c2 == 0) return 1;
if (IS_PATH_SEPAR(c1)) c1 = 0;
if (IS_PATH_SEPAR(c2)) c2 = 0;
c1 = MyCharUpper(c1);
c2 = MyCharUpper(c2);
if (c1 < c2) return -1;
if (c1 > c2) return 1;
continue;
}
if (c1 == 0) return 0;
}
}
int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
{
/*
@@ -37,9 +101,10 @@ int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
printf("\n S2: %ls", s2);
printf("\n");
*/
// 21.07 : we parse PATH_SEPARATOR so: 0 < PATH_SEPARATOR < 1
if (g_CaseSensitive)
return MyStringCompare(s1, s2);
return MyStringCompareNoCase(s1, s2);
return MyStringCompare_Path(s1, s2);
return MyStringCompareNoCase_Path(s1, s2);
}
#ifndef USE_UNICODE_FSTRING
@@ -47,9 +112,7 @@ int CompareFileNames(const char *s1, const char *s2)
{
const UString u1 = fs2us(s1);
const UString u2 = fs2us(s2);
if (g_CaseSensitive)
return MyStringCompare(u1, u2);
return MyStringCompareNoCase(u1, u2);
return CompareFileNames(u1, u2);
}
#endif
@@ -312,16 +375,18 @@ void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex)
subNode.AddItem(include, item, ignoreWildcardIndex - 1);
}
void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching)
/*
void CCensorNode::AddItem(bool include, const UString &path, const CCensorPathProps &props)
{
CItem item;
SplitPathToParts(path, item.PathParts);
item.Recursive = recursive;
item.ForFile = forFile;
item.ForDir = forDir;
item.WildcardMatching = wildcardMatching;
item.Recursive = props.Recursive;
item.ForFile = props.ForFile;
item.ForDir = props.ForDir;
item.WildcardMatching = props.WildcardMatching;
AddItem(include, item);
}
*/
bool CCensorNode::NeedCheckSubDirs() const
{
@@ -439,21 +504,6 @@ bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile
}
*/
void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching)
{
if (path.IsEmpty())
return;
bool forFile = true;
bool forFolder = true;
UString path2 (path);
if (IsPathSepar(path.Back()))
{
path2.DeleteBack();
forFile = false;
}
AddItem(include, path2, recursive, forFile, forFolder, wildcardMatching);
}
void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
{
ExcludeItems += fromNodes.ExcludeItems;
@@ -510,6 +560,9 @@ static unsigned GetNumPrefixParts(const UStringVector &pathParts)
if (pathParts.IsEmpty())
return 0;
/* empty last part could be removed already from (pathParts),
if there was tail path separator (slash) in original full path string. */
#ifdef _WIN32
if (IsDriveColonName(pathParts[0]))
@@ -552,7 +605,8 @@ static unsigned GetNumPrefixParts(const UStringVector &pathParts)
#endif
}
void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching)
void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path,
const CCensorPathProps &props)
{
if (path.IsEmpty())
throw "Empty file path";
@@ -560,12 +614,26 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
UStringVector pathParts;
SplitPathToParts(path, pathParts);
CCensorPathProps props2 = props;
bool forFile = true;
if (pathParts.Back().IsEmpty())
bool forDir = true;
const UString &back = pathParts.Back();
if (back.IsEmpty())
{
// we have tail path separator. So it's directory.
// we delete tail path separator here even for "\" and "c:\"
forFile = false;
pathParts.DeleteBack();
}
else
{
if (props.MarkMode == kMark_StrictFile
|| (props.MarkMode == kMark_StrictFile_IfWildcard
&& DoesNameContainWildcard(back)))
forDir = false;
}
UString prefix;
@@ -582,6 +650,7 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
if (pathMode != k_AbsPath)
{
// detection of the number of Skip Parts for prefix
ignoreWildcardIndex = -1;
const unsigned numPrefixParts = GetNumPrefixParts(pathParts);
@@ -589,6 +658,7 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
if (pathMode != k_FullPath)
{
// if absolute path, then all parts before last part will be in prefix
if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts)
numSkipParts = pathParts.Size() - 1;
}
@@ -610,12 +680,13 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
}
}
// we split (pathParts) to (prefix) and (pathParts).
for (unsigned i = 0; i < numSkipParts; i++)
{
{
const UString &front = pathParts.Front();
// WIN32 doesn't support wildcards in file names
if (wildcardMatching)
if (props.WildcardMatching)
if (i >= numPrefixParts && DoesNameContainWildcard(front))
break;
prefix += front;
@@ -640,17 +711,29 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
pathParts.Clear();
pathParts.Add(UString("*"));
forFile = true;
wildcardMatching = true;
recursive = false;
forDir = true;
props2.WildcardMatching = true;
props2.Recursive = false;
}
}
/*
// not possible now
if (!forDir && !forFile)
{
UString s ("file path was blocked for files and directories: ");
s += path;
throw s;
// return; // for debug : ignore item (don't create Item)
}
*/
CItem item;
item.PathParts = pathParts;
item.ForDir = true;
item.ForDir = forDir;
item.ForFile = forFile;
item.Recursive = recursive;
item.WildcardMatching = wildcardMatching;
item.Recursive = props2.Recursive;
item.WildcardMatching = props2.WildcardMatching;
Pairs[(unsigned)index].Head.AddItem(include, item, ignoreWildcardIndex);
}
@@ -691,18 +774,17 @@ void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode)
FOR_VECTOR(i, CensorPaths)
{
const CCensorPath &cp = CensorPaths[i];
AddItem(censorPathMode, cp.Include, cp.Path, cp.Recursive, cp.WildcardMatching);
AddItem(censorPathMode, cp.Include, cp.Path, cp.Props);
}
CensorPaths.Clear();
}
void CCensor::AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching)
void CCensor::AddPreItem(bool include, const UString &path, const CCensorPathProps &props)
{
CCensorPath &cp = CensorPaths.AddNew();
cp.Path = path;
cp.Include = include;
cp.Recursive = recursive;
cp.WildcardMatching = wildcardMatching;
cp.Props = props;
}
}

View File

@@ -52,6 +52,25 @@ struct CItem
};
const Byte kMark_FileOrDir = 0;
const Byte kMark_StrictFile = 1;
const Byte kMark_StrictFile_IfWildcard = 2;
struct CCensorPathProps
{
bool Recursive;
bool WildcardMatching;
Byte MarkMode;
CCensorPathProps():
Recursive(false),
WildcardMatching(true),
MarkMode(kMark_FileOrDir)
{}
};
class CCensorNode MY_UNCOPYABLE
{
CCensorNode *Parent;
@@ -94,8 +113,19 @@ public:
int FindSubNode(const UString &path) const;
void AddItem(bool include, CItem &item, int ignoreWildcardIndex = -1);
void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching);
void AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching);
// void AddItem(bool include, const UString &path, const CCensorPathProps &props);
void Add_Wildcard()
{
CItem item;
item.PathParts.Add(L"*");
item.Recursive = false;
item.ForFile = true;
item.ForDir = true;
item.WildcardMatching = true;
AddItem(
true // include
, item);
}
// NeedCheckSubDirs() returns true, if there are IncludeItems rules that affect items in subdirs
bool NeedCheckSubDirs() const;
@@ -144,14 +174,11 @@ struct CCensorPath
{
UString Path;
bool Include;
bool Recursive;
bool WildcardMatching;
CCensorPathProps Props;
CCensorPath():
Include(true),
Recursive(false),
WildcardMatching(true)
{}
Include(true)
{}
};
@@ -174,19 +201,28 @@ public:
bool AllAreRelative() const
{ return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); }
void AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching);
void AddItem(ECensorPathMode pathMode, bool include, const UString &path, const CCensorPathProps &props);
// bool CheckPath(bool isAltStream, const UString &path, bool isFile) const;
void ExtendExclude();
void AddPathsToCensor(NWildcard::ECensorPathMode censorPathMode);
void AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching);
void AddPreItem(const UString &path)
void AddPreItem(bool include, const UString &path, const CCensorPathProps &props);
void AddPreItem_NoWildcard(const UString &path)
{
AddPreItem(true, path, false, false);
CCensorPathProps props;
props.WildcardMatching = false;
AddPreItem(
true, // include
path, props);
}
void AddPreItem_Wildcard()
{
AddPreItem(true, UString("*"), false, true);
CCensorPathProps props;
// props.WildcardMatching = true;
AddPreItem(
true, // include
UString("*"), props);
}
};

View File

@@ -2,6 +2,8 @@
#include "StdAfx.h"
// #include "../../Windows/DLL.h"
#ifndef _UNICODE
#include "../../Common/StringConvert.h"
#endif
@@ -88,23 +90,55 @@ bool CDialog::OnButtonClicked(int buttonID, HWND /* buttonHWND */)
return true;
}
static bool GetWorkAreaRect(RECT *rect)
static bool GetWorkAreaRect(RECT *rect, HWND hwnd)
{
// use another function for multi-monitor.
if (hwnd)
{
#ifndef UNDER_CE
/* MonitorFromWindow() is supported in Win2000+
MonitorFromWindow() : retrieves a handle to the display monitor that has the
largest area of intersection with the bounding rectangle of a specified window.
dwFlags: Determines the function's return value if the window does not intersect any display monitor.
MONITOR_DEFAULTTONEAREST : Returns display that is nearest to the window.
MONITOR_DEFAULTTONULL : Returns NULL.
MONITOR_DEFAULTTOPRIMARY : Returns the primary display monitor.
*/
const HMONITOR hmon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
if (hmon)
{
MONITORINFO mi;
memset(&mi, 0, sizeof(mi));
mi.cbSize = sizeof(mi);
if (GetMonitorInfoA(hmon, &mi))
{
*rect = mi.rcWork;
return true;
}
}
#endif
}
/* Retrieves the size of the work area on the primary display monitor.
The work area is the portion of the screen not obscured
by the system taskbar or by application desktop toolbars.
Any DPI virtualization mode of the caller has no effect on this output. */
return BOOLToBool(::SystemParametersInfo(SPI_GETWORKAREA, 0, rect, 0));
}
bool IsDialogSizeOK(int xSize, int ySize)
bool IsDialogSizeOK(int xSize, int ySize, HWND hwnd)
{
// it returns for system font. Real font uses another values
LONG v = GetDialogBaseUnits();
int x = LOWORD(v);
int y = HIWORD(v);
const LONG v = GetDialogBaseUnits();
const int x = LOWORD(v);
const int y = HIWORD(v);
RECT rect;
GetWorkAreaRect(&rect);
int wx = RECT_SIZE_X(rect);
int wy = RECT_SIZE_Y(rect);
GetWorkAreaRect(&rect, hwnd);
const int wx = RECT_SIZE_X(rect);
const int wy = RECT_SIZE_Y(rect);
return
xSize / 4 * x <= wx &&
ySize / 8 * y <= wy;
@@ -159,47 +193,167 @@ bool CDialog::MoveItem(int id, int x, int y, int width, int height, bool repaint
return BOOLToBool(::MoveWindow(GetItem(id), x, y, width, height, BoolToBOOL(repaint)));
}
/*
typedef BOOL (WINAPI * Func_DwmGetWindowAttribute)(
HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute);
static bool GetWindowsRect_DWM(HWND hwnd, RECT *rect)
{
// dll load and free is too slow : 300 calls in second.
NDLL::CLibrary dll;
if (!dll.Load(FTEXT("dwmapi.dll")))
return false;
Func_DwmGetWindowAttribute f = (Func_DwmGetWindowAttribute)dll.GetProc("DwmGetWindowAttribute" );
if (f)
{
#define MY__DWMWA_EXTENDED_FRAME_BOUNDS 9
// 30000 per second
RECT r;
if (f(hwnd, MY__DWMWA_EXTENDED_FRAME_BOUNDS, &r, sizeof(RECT)) == S_OK)
{
*rect = r;
return true;
}
}
return false;
}
*/
static bool IsRect_Small_Inside_Big(const RECT &sm, const RECT &big)
{
return sm.left >= big.left
&& sm.right <= big.right
&& sm.top >= big.top
&& sm.bottom <= big.bottom;
}
static bool AreRectsOverlapped(const RECT &r1, const RECT &r2)
{
return r1.left < r2.right
&& r1.right > r2.left
&& r1.top < r2.bottom
&& r1.bottom > r2.top;
}
static bool AreRectsEqual(const RECT &r1, const RECT &r2)
{
return r1.left == r2.left
&& r1.right == r2.right
&& r1.top == r2.top
&& r1.bottom == r2.bottom;
}
void CDialog::NormalizeSize(bool fullNormalize)
{
RECT workRect;
GetWorkAreaRect(&workRect);
int xSize = RECT_SIZE_X(workRect);
int ySize = RECT_SIZE_Y(workRect);
if (!GetWorkAreaRect(&workRect, *this))
return;
RECT rect;
GetWindowRect(&rect);
int xSize2 = RECT_SIZE_X(rect);
int ySize2 = RECT_SIZE_Y(rect);
bool needMove = (xSize2 > xSize || ySize2 > ySize);
if (xSize2 > xSize || (needMove && fullNormalize))
if (!GetWindowRect(&rect))
return;
int xs = RECT_SIZE_X(rect);
int ys = RECT_SIZE_Y(rect);
// we don't want to change size using workRect, if window is outside of WorkArea
if (!AreRectsOverlapped(rect, workRect))
return;
/* here rect and workRect are overlapped, but it can be false
overlapping of small shadow when window in another display. */
const int xsW = RECT_SIZE_X(workRect);
const int ysW = RECT_SIZE_Y(workRect);
if (xs <= xsW && ys <= ysW)
return; // size of window is OK
if (fullNormalize)
{
rect.left = workRect.left;
rect.right = workRect.right;
xSize2 = xSize;
}
if (ySize2 > ySize || (needMove && fullNormalize))
{
rect.top = workRect.top;
rect.bottom = workRect.bottom;
ySize2 = ySize;
}
if (needMove)
{
if (fullNormalize)
Show(SW_SHOWMAXIMIZED);
else
Move(rect.left, rect.top, xSize2, ySize2, true);
Show(SW_SHOWMAXIMIZED);
return;
}
int x = workRect.left;
int y = workRect.top;
if (xs < xsW) x += (xsW - xs) / 2; else xs = xsW;
if (ys < ysW) y += (ysW - ys) / 2; else ys = ysW;
Move(x, y, xs, ys, true);
}
void CDialog::NormalizePosition()
{
RECT workRect, rect;
GetWorkAreaRect(&workRect);
GetWindowRect(&rect);
if (rect.bottom > workRect.bottom && rect.top > workRect.top)
Move(rect.left, workRect.top, RECT_SIZE_X(rect), RECT_SIZE_Y(rect), true);
RECT workRect;
if (!GetWorkAreaRect(&workRect, *this))
return;
RECT rect2 = workRect;
bool useWorkArea = true;
const HWND parentHWND = GetParent();
if (parentHWND)
{
RECT workRectParent;
if (!GetWorkAreaRect(&workRectParent, parentHWND))
return;
// if windows are in different monitors, we use only workArea of current window
if (AreRectsEqual(workRectParent, workRect))
{
// RECT rect3; if (GetWindowsRect_DWM(parentHWND, &rect3)) {}
CWindow wnd(parentHWND);
if (wnd.GetWindowRect(&rect2))
{
// it's same monitor. So we try to use parentHWND rect.
/* we don't want to change position, if parent window is not inside work area.
In Win10 : parent window rect is 8 pixels larger for each corner than window size for shadow.
In maximize mode : window is outside of workRect.
if parent window is inside workRect, we will use parent window instead of workRect */
if (IsRect_Small_Inside_Big(rect2, workRect))
useWorkArea = false;
}
}
}
RECT rect;
if (!GetWindowRect(&rect))
return;
if (useWorkArea)
{
// we don't want to move window, if it's already inside.
if (IsRect_Small_Inside_Big(rect, workRect))
return;
// we don't want to move window, if it's outside of workArea
if (!AreRectsOverlapped(rect, workRect))
return;
rect2 = workRect;
}
{
const int xs = RECT_SIZE_X(rect);
const int ys = RECT_SIZE_Y(rect);
const int xs2 = RECT_SIZE_X(rect2);
const int ys2 = RECT_SIZE_Y(rect2);
// we don't want to change position if parent is smaller.
if (xs <= xs2 && ys <= ys2)
{
const int x = rect2.left + (xs2 - xs) / 2;
const int y = rect2.top + (ys2 - ys) / 2;
if (x != rect.left || y != rect.top)
Move(x, y, xs, ys, true);
// SetWindowPos(*this, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
return;
}
}
}
bool CModelessDialog::Create(LPCTSTR templateName, HWND parentWindow)
{
HWND aHWND = CreateDialogParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);

View File

@@ -183,7 +183,7 @@ public:
}
};
bool IsDialogSizeOK(int xSize, int ySize);
bool IsDialogSizeOK(int xSize, int ySize, HWND hwnd = NULL);
}}

View File

@@ -139,11 +139,6 @@ bool CFileBase::Close() throw()
return true;
}
bool CFileBase::GetPosition(UInt64 &position) const throw()
{
return Seek(0, FILE_CURRENT, position);
}
bool CFileBase::GetLength(UInt64 &length) const throw()
{
#ifdef SUPPORT_DEVICE_FILE
@@ -154,13 +149,64 @@ bool CFileBase::GetLength(UInt64 &length) const throw()
}
#endif
DWORD sizeHigh;
DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);
if (sizeLow == 0xFFFFFFFF)
DWORD high = 0;
const DWORD low = ::GetFileSize(_handle, &high);
if (low == INVALID_FILE_SIZE)
if (::GetLastError() != NO_ERROR)
return false;
length = (((UInt64)sizeHigh) << 32) + sizeLow;
length = (((UInt64)high) << 32) + low;
return true;
/*
LARGE_INTEGER fileSize;
// GetFileSizeEx() is unsupported in 98/ME/NT, and supported in Win2000+
if (!GetFileSizeEx(_handle, &fileSize))
return false;
length = (UInt64)fileSize.QuadPart;
return true;
*/
}
/* Specification for SetFilePointer():
If a new file pointer is a negative value,
{
the function fails,
the file pointer is not moved,
the code returned by GetLastError() is ERROR_NEGATIVE_SEEK.
}
If the hFile handle is opened with the FILE_FLAG_NO_BUFFERING flag set
{
an application can move the file pointer only to sector-aligned positions.
A sector-aligned position is a position that is a whole number multiple of
the volume sector size.
An application can obtain a volume sector size by calling the GetDiskFreeSpace.
}
It is not an error to set a file pointer to a position beyond the end of the file.
The size of the file does not increase until you call the SetEndOfFile, WriteFile, or WriteFileEx function.
If the return value is INVALID_SET_FILE_POINTER and if lpDistanceToMoveHigh is non-NULL,
an application must call GetLastError to determine whether or not the function has succeeded or failed.
*/
bool CFileBase::GetPosition(UInt64 &position) const throw()
{
LONG high = 0;
const DWORD low = ::SetFilePointer(_handle, 0, &high, FILE_CURRENT);
if (low == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
// for error case we can set (position) to (-1) or (0) or leave (position) unchanged.
// position = (UInt64)(Int64)-1; // for debug
position = 0;
return false;
}
position = (((UInt64)(UInt32)high) << 32) + low;
return true;
// we don't want recursed GetPosition()
// return Seek(0, FILE_CURRENT, position);
}
bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw()
@@ -174,10 +220,18 @@ bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition
#endif
LONG high = (LONG)(distanceToMove >> 32);
DWORD low = ::SetFilePointer(_handle, (LONG)(distanceToMove & 0xFFFFFFFF), &high, moveMethod);
if (low == 0xFFFFFFFF)
if (::GetLastError() != NO_ERROR)
const DWORD low = ::SetFilePointer(_handle, (LONG)(distanceToMove & 0xFFFFFFFF), &high, moveMethod);
if (low == INVALID_SET_FILE_POINTER)
{
const DWORD lastError = ::GetLastError();
if (lastError != NO_ERROR)
{
// 21.07: we set (newPosition) to real position even after error.
GetPosition(newPosition);
SetLastError(lastError); // restore LastError
return false;
}
}
newPosition = (((UInt64)(UInt32)high) << 32) + low;
return true;
}
@@ -189,8 +243,8 @@ bool CFileBase::Seek(UInt64 position, UInt64 &newPosition) const throw()
bool CFileBase::SeekToBegin() const throw()
{
UInt64 newPosition;
return Seek(0, newPosition);
UInt64 newPosition = 0;
return Seek(0, newPosition) && (newPosition == 0);
}
bool CFileBase::SeekToEnd(UInt64 &newPosition) const throw()
@@ -531,6 +585,22 @@ bool COutFile::SetLength(UInt64 length) throw()
return SetEndOfFile();
}
bool COutFile::SetLength_KeepPosition(UInt64 length) throw()
{
UInt64 currentPos = 0;
if (!GetPosition(currentPos))
return false;
DWORD lastError = 0;
const bool result = SetLength(length);
if (!result)
lastError = GetLastError();
UInt64 currentPos2;
const bool result2 = Seek(currentPos, currentPos2);
if (lastError != 0)
SetLastError(lastError);
return (result && result2);
}
}}}
#else // _WIN32
@@ -573,7 +643,9 @@ bool CFileBase::Close()
bool CFileBase::GetLength(UInt64 &length) const
{
const off_t curPos = seek(0, SEEK_CUR);
length = 0;
// length = (UInt64)(Int64)-1; // for debug
const off_t curPos = seekToCur();
if (curPos == -1)
return false;
const off_t lengthTemp = seek(0, SEEK_END);
@@ -596,6 +668,11 @@ off_t CFileBase::seekToBegin() const throw()
return seek(0, SEEK_SET);
}
off_t CFileBase::seekToCur() const throw()
{
return seek(0, SEEK_CUR);
}
/*
bool CFileBase::SeekToBegin() const throw()
{
@@ -705,6 +782,7 @@ bool COutFile::SetLength(UInt64 length) throw()
SetLastError(EFBIG);
return false;
}
// The value of the seek pointer shall not be modified by a call to ftruncate().
int iret = ftruncate(_handle, len2);
return (iret == 0);
}

View File

@@ -247,6 +247,7 @@ public:
bool WriteFull(const void *data, size_t size) throw();
bool SetEndOfFile() throw();
bool SetLength(UInt64 length) throw();
bool SetLength_KeepPosition(UInt64 length) throw();
};
}
@@ -279,6 +280,7 @@ public:
bool GetLength(UInt64 &length) const;
off_t seek(off_t distanceToMove, int moveMethod) const;
off_t seekToBegin() const throw();
off_t seekToCur() const throw();
// bool SeekToBegin() throw();
int my_fstat(struct stat *st) const { return fstat(_handle, st); }
};
@@ -327,6 +329,10 @@ public:
}
bool SetLength(UInt64 length) throw();
bool SetLength_KeepPosition(UInt64 length) throw()
{
return SetLength(length);
}
bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
bool SetMTime(const FILETIME *mTime) throw();
};

View File

@@ -192,17 +192,29 @@ BSTR CPropVariant::AllocBstr(unsigned numChars)
return bstrVal;
}
#define SET_PROP_id_dest(id, dest) \
if (vt != id) { InternalClear(); vt = id; } dest = value;
void CPropVariant::Set_Int32(Int32 value) throw()
{
SET_PROP_id_dest(VT_I4, lVal);
}
void CPropVariant::Set_Int64(Int64 value) throw()
{
SET_PROP_id_dest(VT_I8, hVal.QuadPart);
}
#define SET_PROP_FUNC(type, id, dest) \
CPropVariant& CPropVariant::operator=(type value) throw() \
{ if (vt != id) { InternalClear(); vt = id; } \
dest = value; return *this; }
{ SET_PROP_id_dest(id, dest); return *this; }
SET_PROP_FUNC(Byte, VT_UI1, bVal)
// SET_PROP_FUNC(Int16, VT_I2, iVal)
SET_PROP_FUNC(Int32, VT_I4, lVal)
// SET_PROP_FUNC(Int32, VT_I4, lVal)
SET_PROP_FUNC(UInt32, VT_UI4, ulVal)
SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
// SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()

View File

@@ -45,6 +45,14 @@ inline void PropVarEm_Set_Bool(PROPVARIANT *p, bool b) throw()
class CPropVariant : public tagPROPVARIANT
{
// ---------- forbidden functions ----------
CPropVariant(const char *s);
// CPropVariant(const UString &s);
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
CPropVariant(const FString &s);
CPropVariant& operator=(const FString &s);
#endif
public:
CPropVariant()
{
@@ -64,13 +72,14 @@ public:
CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
private:
CPropVariant(UInt16 value); // { vt = VT_UI2; wReserved1 = 0; uiVal = value; }
CPropVariant(Int16 value); // { vt = VT_I2; wReserved1 = 0; iVal = value; }
CPropVariant(Int32 value); // { vt = VT_I4; wReserved1 = 0; lVal = value; }
CPropVariant(Int64 value); // { vt = VT_I8; wReserved1 = 0; hVal.QuadPart = value; }
public:
CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; }
CPropVariant(Int64 value) { vt = VT_I8; wReserved1 = 0; hVal.QuadPart = value; }
CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
CPropVariant& operator=(const CPropVariant &varSrc);
@@ -88,14 +97,18 @@ public:
private:
CPropVariant& operator=(Int16 value) throw();
CPropVariant& operator=(UInt16 value) throw();
CPropVariant& operator=(Int32 value) throw();
CPropVariant& operator=(Int64 value) throw();
public:
CPropVariant& operator=(Int32 value) throw();
CPropVariant& operator=(UInt32 value) throw();
CPropVariant& operator=(UInt64 value) throw();
CPropVariant& operator=(Int64 value) throw();
CPropVariant& operator=(const FILETIME &value) throw();
void Set_Int32(Int32 value) throw();
void Set_Int64(Int64 value) throw();
BSTR AllocBstr(unsigned numChars);
HRESULT Clear() throw();

View File

@@ -20,11 +20,11 @@ public:
// WRes Wait() { return Thread_Wait(&thread); }
WRes Wait_Close() { return Thread_Wait_Close(&thread); }
WRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID param)
WRes Create(THREAD_FUNC_TYPE startAddress, LPVOID param)
{ return Thread_Create(&thread, startAddress, param); }
WRes Create_With_Affinity(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID param, CAffinityMask affinity)
WRes Create_With_Affinity(THREAD_FUNC_TYPE startAddress, LPVOID param, CAffinityMask affinity)
{ return Thread_Create_With_Affinity(&thread, startAddress, param, affinity); }
WRes Create_With_CpuSet(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID param, const CCpuSet *cpuSet)
WRes Create_With_CpuSet(THREAD_FUNC_TYPE startAddress, LPVOID param, const CCpuSet *cpuSet)
{ return Thread_Create_With_CpuSet(&thread, startAddress, param, cpuSet); }
#ifdef _WIN32

View File

@@ -58,6 +58,7 @@ cmdline\switches\shared.htm
cmdline\switches\sni.htm
cmdline\switches\sns.htm
cmdline\switches\spf.htm
cmdline\switches\spm.htm
cmdline\switches\ssc.htm
cmdline\switches\stdin.htm
cmdline\switches\stdout.htm

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<?define VerMajor = "21" ?>
<?define VerMinor = "06" ?>
<?define VerMinor = "07" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?>

View File

@@ -1,4 +1,4 @@
7-Zip 21.05 Sources
7-Zip 21.07 Sources
-------------------
7-Zip is a file archiver for Windows.
@@ -148,6 +148,28 @@ Also you can change some compiler options in the mak files:
var_gcc.mak
warn_gcc.mak
makefile.gcc supports some variables that can change compile options
USE_JWASM=1
use JWasm assembler instead of Asmc.
Note that JWasm doesn't support AES instructions. So AES code from C version AesOpt.c
will be used instead of assembler code from AesOpt.asm.
DISABLE_RAR=1
removes whole RAR related code from compilation.
DISABLE_RAR_COMPRESS=1
removes "not fully free" code of RAR decompression codecs from compilation.
RAR decompression codecs in 7-Zip code has some additional license restrictions,
that can be treated as not fully compatible with free-software licenses.
DISABLE_RAR_COMPRESS=1 allows to exclude such "not-fully-free" RAR code from compilation.
if DISABLE_RAR_COMPRESS=1 is specified, 7-zip will not be able to decompress files
from rar archives, but 7-zip still will be able to open rar archives to get list of
files or to extract files that are stored without compression.
if DISABLE_RAR=1 is specified, 7-zip will not be able to work with RAR archives.
7-Zip and p7zip
===============

View File

@@ -1,6 +1,14 @@
HISTORY of the 7-Zip source code
--------------------------------
21.07 2021-12-26
-------------------------
- The sorting order of files in archives was slightly changed to be more consistent
for cases where the name of some directory is the same as the prefix part of the name
of another directory or file.
- TAR archives created by 7-Zip now are more consistent with archives created by GNU TAR program.
21.06 2021-11-24
-------------------------
- Bug in LZMA encoder in file LzmaEnc.c was fixed: