This commit is contained in:
Igor Pavlov 2026-02-12 00:00:00 +00:00
parent 5e96a82794
commit 839151eaaa
56 changed files with 1764 additions and 984 deletions

View file

@ -142,8 +142,8 @@ MY_MKDIR=mkdir
DEL_OBJ_EXE = -$(RM) $(O)\*.o $(O)\$(PROG).exe $(O)\$(PROG).dll
endif
LIB2_GUI = -lOle32 -lGdi32 -lComctl32 -lComdlg32 -lShell32 $(LIB_HTMLHELP)
LIB2 = -loleaut32 -luuid -ladvapi32 -lUser32 $(LIB2_GUI)
LIB2_GUI = -lole32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 $(LIB_HTMLHELP)
LIB2 = -loleaut32 -luuid -ladvapi32 -luser32 $(LIB2_GUI)
# v24.00: -DUNICODE and -D_UNICODE are defined in precompilation header files
# CXXFLAGS_EXTRA = -DUNICODE -D_UNICODE

View file

@ -721,7 +721,7 @@ static int CompareEmptyItems(const unsigned *p1, const unsigned *p2, void *param
return (u1.IsDir && u1.IsAnti) ? -n : n;
}
static const char *g_Exts =
static const char * const g_Exts =
" 7z xz lzma ace arc arj bz tbz bz2 tbz2 cab deb gz tgz ha lha lzh lzo lzx pak rar rpm sit zoo"
" zip jar ear war msi"
" 3gp avi mov mpeg mpg mpe wmv"

File diff suppressed because it is too large Load diff

View file

@ -927,7 +927,7 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
#ifdef _WIN32
UString u;
ConvertUTF8ToUnicode(item.Name, u);
ConvertUTF8ToUnicode(s, u);
#else
const UString u = MultiByteToUnicodeString(s, CP_OEMCP);
#endif

View file

@ -482,6 +482,10 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
if (_phySize < headerSize)
_phySize = headerSize;
// we use 32 MiB limit for L1 size, as QEMU with QCOW_MAX_L1_SIZE limit.
if (l1Size > (1u << 22)) // if (l1Size > (1u << (sizeof(size_t) * 8 - 4)))
return S_FALSE;
_isArc = true;
{
const UInt64 backOffset = Get64((const Byte *)(const void *)buf64 + 8);
@ -519,7 +523,6 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
}
CObjArray<UInt64> table64(l1Size);
{
// if ((t1SizeBytes >> 3) != l1Size) return S_FALSE;
RINOK(InStream_SeekSet(stream, l1Offset))
RINOK(ReadStream_FALSE(stream, table64, t1SizeBytes))
}

View file

@ -8,6 +8,7 @@
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/MyBuffer2.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Windows/PropVariantUtils.h"
@ -1184,7 +1185,15 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz
const UInt64 processedSize = outStream->GetPos();
if (res == S_OK && !lastItem.Is_UnknownSize() && processedSize != lastItem.Size)
res = S_FALSE;
{
// rar_v7.13-: linux archive contains symLink with (packSize == 0 && lastItem.Size != 0)
// v25.02: we ignore such record in rar headers:
if (packSize != 0
|| method != 0
|| lastItem.HostOS != kHost_Unix
|| !MY_LIN_S_ISLNK(lastItem.Attrib))
res = S_FALSE;
}
// if (res == S_OK)
{

View file

@ -7,6 +7,7 @@
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/MyBuffer2.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Windows/PropVariantUtils.h"
@ -70,8 +71,14 @@ bool CItem::IsDir() const
case NHeader::NFile::kHostMSDOS:
case NHeader::NFile::kHostOS2:
case NHeader::NFile::kHostWin32:
if ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
if (Attrib & FILE_ATTRIBUTE_DIRECTORY)
return true;
break;
case NHeader::NFile::kHostUnix:
case NHeader::NFile::kHostBeOS:
if (MY_LIN_S_ISDIR(Attrib))
return true;
break;
}
return false;
}
@ -86,11 +93,20 @@ UInt32 CItem::GetWinAttrib() const
case NHeader::NFile::kHostWin32:
a = Attrib;
break;
case NHeader::NFile::kHostUnix:
case NHeader::NFile::kHostBeOS:
a = Attrib << 16;
a |= 0x8000; // add posix mode marker
break;
// case NHeader::NFile::kHostMacOS:
// kHostMacOS was used only by some very old rare case rar.
// New rar4-rar7 for macos probably uses kHostUnix.
// So we process kHostMacOS without attribute parsing:
default:
a = 0; // must be converted from unix value;
a = 0;
}
if (IsDir())
a |= NHeader::NFile::kWinFileDirectoryAttributeMask;
a |= FILE_ATTRIBUTE_DIRECTORY;
return a;
}

View file

@ -65,7 +65,7 @@ static const Byte kArcProps[] =
kpidComment
};
static const char *k_Characts_Prefix = "PREFIX";
static const char * const k_Characts_Prefix = "PREFIX";
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
@ -684,10 +684,14 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
s.Add_OptSpaced("SCHILY.fflags=");
s += item->SCHILY_fflags;
}
if (item->Is_Sparse())
s.Add_OptSpaced("SPARSE");
if (item->IsThereWarning())
s.Add_OptSpaced("WARNING");
if (item->HeaderError)
s.Add_OptSpaced("ERROR");
if (item->Method_Error)
s.Add_OptSpaced("METHOD_ERROR");
if (item->Pax_Error)
s.Add_OptSpaced("PAX_error");
if (!item->PaxExtra.RawLines.IsEmpty())
@ -812,11 +816,16 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
inStream2 = inStream;
else
{
GetStream(index, &inStream2);
if (!inStream2)
return E_FAIL;
const HRESULT hres = GetStream(index, &inStream2);
if (hres == E_NOTIMPL)
opRes = NExtract::NOperationResult::kHeadersError; // kUnsupportedMethod
else if (!inStream2)
{
opRes = NExtract::NOperationResult::kDataError;
// return E_FAIL;
}
}
if (opRes == NExtract::NOperationResult::kOK)
{
if (item->Is_SymLink())
{
@ -855,9 +864,9 @@ Z7_CLASS_IMP_IInStream(
bool _needStartSeek;
public:
unsigned ItemIndex;
CHandler *Handler;
CMyComPtr<IUnknown> HandlerRef;
unsigned ItemIndex;
CRecordVector<UInt64> PhyOffsets;
void Init()
@ -879,7 +888,7 @@ Z7_COM7F_IMF(CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)
if (_virtPos >= item.Size)
return S_OK;
{
UInt64 rem = item.Size - _virtPos;
const UInt64 rem = item.Size - _virtPos;
if (size > rem)
size = (UInt32)rem;
}
@ -903,17 +912,17 @@ Z7_COM7F_IMF(CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)
}
const CSparseBlock &sb = item.SparseBlocks[left];
UInt64 relat = _virtPos - sb.Offset;
const UInt64 relat = _virtPos - sb.Offset;
if (_virtPos >= sb.Offset && relat < sb.Size)
{
UInt64 rem = sb.Size - relat;
const UInt64 rem = sb.Size - relat;
if (size > rem)
size = (UInt32)rem;
UInt64 phyPos = PhyOffsets[left] + relat;
const UInt64 phyPos = PhyOffsets[left] + relat;
if (_needStartSeek || _phyPos != phyPos)
{
RINOK(InStream_SeekSet(Handler->_stream, (item.Get_DataPos() + phyPos)))
RINOK(InStream_SeekSet(Handler->_stream, item.Get_DataPos() + phyPos))
_needStartSeek = false;
_phyPos = phyPos;
}
@ -927,7 +936,7 @@ Z7_COM7F_IMF(CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)
next = sb.Offset;
else if (left + 1 < item.SparseBlocks.Size())
next = item.SparseBlocks[left + 1].Offset;
UInt64 rem = next - _virtPos;
const UInt64 rem = next - _virtPos;
if (size > rem)
size = (UInt32)rem;
memset(data, 0, size);
@ -965,6 +974,8 @@ Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream))
if (item.Is_Sparse())
{
if (item.Method_Error)
return E_NOTIMPL; // S_FALSE
CSparseStream *streamSpec = new CSparseStream;
CMyComPtr<IInStream> streamTemp = streamSpec;
streamSpec->Init();

View file

@ -181,6 +181,7 @@ HRESULT CArchive::GetNextItemReal(CItemEx &item)
{
char buf[NFileHeader::kRecordSize];
item.Method_Error = false;
error = k_ErrorType_OK;
filled = false;
@ -218,10 +219,7 @@ HRESULT CArchive::GetNextItemReal(CItemEx &item)
break;
item.HeaderSize += NFileHeader::kRecordSize;
thereAreEmptyRecords = true;
if (OpenCallback)
{
RINOK(Progress(item, 0))
}
RINOK(Progress(item, 0))
}
if (thereAreEmptyRecords)
{
@ -335,37 +333,60 @@ HRESULT CArchive::GetNextItemReal(CItemEx &item)
if (item.LinkFlag == NFileHeader::NLinkFlag::kSparse)
{
Byte isExtended = (Byte)buf[482];
if (isExtended != 0 && isExtended != 1)
return S_OK;
// OLD GNU format: parse sparse file information:
// PackSize = cumulative size of all non-empty blocks of the file.
// We read actual file size from 'realsize' member of oldgnu_header:
RIF(ParseSize(buf + 483, item.Size, item.Size_IsBin))
UInt64 min = 0;
for (unsigned i = 0; i < 4; i++)
{
p = buf + 386 + 24 * i;
if (GetBe32(p) == 0)
{
if (isExtended != 0)
return S_OK;
break;
}
CSparseBlock sb;
RIF(ParseSize(p, sb.Offset))
RIF(ParseSize(p + 12, sb.Size))
item.SparseBlocks.Add(sb);
if (sb.Offset < min || sb.Offset > item.Size)
return S_OK;
if ((sb.Offset & 0x1FF) != 0 || (sb.Size & 0x1FF) != 0)
return S_OK;
min = sb.Offset + sb.Size;
if (min < sb.Offset)
return S_OK;
}
if (min > item.Size)
if (item.Size < item.PackSize) // additional check
return S_OK;
while (isExtended != 0)
p = buf + 386;
UInt64 end = 0, packSum = 0;
unsigned numRecords = 4;
unsigned isExtended = (Byte)p[4 * 24]; // (Byte)p[numRecords * 24];
// the list of blocks contains non-empty blocks. All another data is empty.
for (;;)
{
// const unsigned isExtended = (Byte)p[numRecords * 24];
if (isExtended > 1)
return S_OK;
do
{
if (GetBe32(p) == 0)
{
if (isExtended)
return S_OK;
break;
}
CSparseBlock sb;
RIF(ParseSize(p, sb.Offset))
RIF(ParseSize(p + 12, sb.Size))
p += 24;
/* for all non-last blocks we expect :
((sb.Size & 0x1ff) == 0) && ((sb.Offset & 0x1ff) == 0)
for last block : (sb.Size == 0) is possible.
*/
if (sb.Offset < end
|| item.Size < sb.Offset
|| item.Size - sb.Offset < sb.Size)
return S_OK;
// optional check:
if (sb.Size && ((end & 0x1ff) || (sb.Offset & 0x1ff)))
{
item.Method_Error = true; // relaxed check
// return S_OK;
}
end = sb.Offset + sb.Size;
packSum += sb.Size;
item.SparseBlocks.Add(sb);
}
while (--numRecords);
if (!isExtended)
break;
size_t processedSize = NFileHeader::kRecordSize;
RINOK(ReadStream(SeqStream, buf, &processedSize))
if (processedSize != NFileHeader::kRecordSize)
@ -373,46 +394,22 @@ HRESULT CArchive::GetNextItemReal(CItemEx &item)
error = k_ErrorType_UnexpectedEnd;
return S_OK;
}
item.HeaderSize += NFileHeader::kRecordSize;
if (OpenCallback)
{
RINOK(Progress(item, 0))
}
isExtended = (Byte)buf[21 * 24];
if (isExtended != 0 && isExtended != 1)
return S_OK;
for (unsigned i = 0; i < 21; i++)
{
p = buf + 24 * i;
if (GetBe32(p) == 0)
{
if (isExtended != 0)
return S_OK;
break;
}
CSparseBlock sb;
RIF(ParseSize(p, sb.Offset))
RIF(ParseSize(p + 12, sb.Size))
item.SparseBlocks.Add(sb);
if (sb.Offset < min || sb.Offset > item.Size)
return S_OK;
if ((sb.Offset & 0x1FF) != 0 || (sb.Size & 0x1FF) != 0)
return S_OK;
min = sb.Offset + sb.Size;
if (min < sb.Offset)
return S_OK;
}
RINOK(Progress(item, 0))
p = buf;
numRecords = 21;
isExtended = (Byte)p[21 * 24]; // (Byte)p[numRecords * 24];
}
// optional checks for strict size consistency:
if (end != item.Size || packSum != item.PackSize)
{
item.Method_Error = true; // relaxed check
// return S_OK;
}
if (min > item.Size)
return S_OK;
}
if (item.PackSize >= (UInt64)1 << 63)
if (item.PackSize >= (UInt64)1 << 63) // optional check. It was checked in ParseSize() already
return S_OK;
filled = true;
error = k_ErrorType_OK;
return S_OK;
@ -421,6 +418,8 @@ HRESULT CArchive::GetNextItemReal(CItemEx &item)
HRESULT CArchive::Progress(const CItemEx &item, UInt64 posOffset)
{
if (!OpenCallback)
return S_OK;
const UInt64 pos = item.Get_DataPos() + posOffset;
if (NumFiles - NumFiles_Prev < (1 << 16)
// && NumRecords - NumRecords_Prev < (1 << 16)
@ -500,10 +499,7 @@ HRESULT CArchive::ReadDataToBuffer(const CItemEx &item,
do
{
if (OpenCallback)
{
RINOK(Progress(item, pos))
}
RINOK(Progress(item, pos))
unsigned size = kBufSize;
if (size > packSize)
@ -813,6 +809,7 @@ HRESULT CArchive::ReadItem2(CItemEx &item)
item.LongLink_WasUsed_2 = false;
item.HeaderError = false;
item.Method_Error = false;
item.IsSignedChecksum = false;
item.Prefix_WasUsed = false;
@ -838,13 +835,8 @@ HRESULT CArchive::ReadItem2(CItemEx &item)
for (;;)
{
if (OpenCallback)
{
RINOK(Progress(item, 0))
}
RINOK(Progress(item, 0))
RINOK(GetNextItemReal(item))
// NumRecords++;
if (!filled)
@ -1064,9 +1056,14 @@ HRESULT CArchive::ReadItem2(CItemEx &item)
// GNU TAR ignores (item.Size) in that case
if (item.Size != 0 && item.Size != piSize)
item.Pax_Error = true;
item.Size = piSize;
item.PackSize = piSize;
item.pax_size_WasUsed = true;
if (piSize >= ((UInt64)1 << 63))
item.Pax_Error = true;
else
{
item.Size = piSize;
item.PackSize = piSize;
item.pax_size_WasUsed = true;
}
}
item.PaxTimes = paxInfo;

View file

@ -322,6 +322,7 @@ struct CPaxExtra
struct CItemEx: public CItem
{
bool HeaderError;
bool Method_Error;
bool IsSignedChecksum;
bool Prefix_WasUsed;

View file

@ -500,10 +500,15 @@ size_t CFileId::Parse(const Byte *p, size_t size)
processed += impLen;
Id.Parse(p + processed, idLen);
processed += idLen;
// const size_t processed2 = processed;
for (;(processed & 3) != 0; processed++)
if (p[processed] != 0)
return 0;
if ((size_t)tag.CrcLen + 16 != processed) return 0;
// some program can create non-standard UDF file where CrcLen doesn't include Padding data
if ((size_t)tag.CrcLen + 16 != processed
// && (size_t)tag.CrcLen + 16 != processed2 // we can enable this check to support non-standard UDF
)
return 0;
return (processed <= size) ? processed : 0;
}
@ -577,15 +582,20 @@ HRESULT CInArchive::ReadItem(unsigned volIndex, int fsIndex, const CLongAllocDes
item.IcbTag.Parse(p + 16);
// maybe another FileType values are possible in rare cases.
// Shoud we ignore FileType here?
if (fsIndex < 0)
{
// if (item.IcbTag.FileType == ICB_FILE_TYPE_DIR) return S_FALSE;
if (item.IcbTag.FileType != ICB_FILE_TYPE_METADATA &&
item.IcbTag.FileType != ICB_FILE_TYPE_METADATA_MIRROR)
item.IcbTag.FileType != ICB_FILE_TYPE_METADATA_MIRROR &&
item.IcbTag.FileType != ICB_FILE_TYPE_METADATA_BITMAP)
return S_FALSE;
}
else if (
item.IcbTag.FileType != ICB_FILE_TYPE_DIR &&
item.IcbTag.FileType != ICB_FILE_TYPE_FILE)
item.IcbTag.FileType != ICB_FILE_TYPE_FILE &&
item.IcbTag.FileType != ICB_FILE_TYPE_REAL_TIME_FILE) // M2TS files in /BDMV/STREAM/ in Blu-ray movie
return S_FALSE;
item.Parse(p);
@ -1210,7 +1220,7 @@ HRESULT CInArchive::Open2()
if (tag.Id != DESC_TYPE_FileSet)
return S_FALSE;
PRF(printf("\n FileSet", volIndex));
PRF(printf("\n FileSet"));
CFileSet fs;
fs.RecordingTime.Parse(p + 16);
// fs.InterchangeLevel = Get16(p + 18);

View file

@ -250,9 +250,10 @@ enum EIcbFileType
{
ICB_FILE_TYPE_DIR = 4,
ICB_FILE_TYPE_FILE = 5,
ICB_FILE_TYPE_METADATA = 250, // 2.2.13.1 Metadata File
ICB_FILE_TYPE_METADATA_MIRROR = 251
ICB_FILE_TYPE_REAL_TIME_FILE = 249, // 2.3.5.2.1
ICB_FILE_TYPE_METADATA = 250, // 2.2.13.1
ICB_FILE_TYPE_METADATA_MIRROR = 251, // 2.2.13.1
ICB_FILE_TYPE_METADATA_BITMAP = 252 // 2.2.13.2
};
enum EIcbDescriptorType

View file

@ -1718,61 +1718,49 @@ HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo)
HRESULT CInArchive::FindCd(bool checkOffsetMode)
{
CCdInfo &cdInfo = Vols.ecd;
UInt64 endPos;
// There are no useful data in cache in most cases here.
// So here we don't use cache data from previous operations .
// So here we don't use cache data from previous operations.
InitBuf();
UInt64 endPos;
RINOK(InStream_GetSize_SeekToEnd(Stream, endPos))
_streamPos = endPos;
// const UInt32 kBufSizeMax2 = ((UInt32)1 << 16) + kEcdSize + kEcd64Locator_Size + kEcd64_FullSize;
const size_t kBufSizeMax = ((size_t)1 << 17); // must be larger than kBufSizeMax2
const size_t kBufSizeMax = (size_t)1 << 17; // must be larger than
// (1 << 16) + kEcdSize + kEcd64Locator_Size + kEcd64_FullSize
const size_t bufSize = (endPos < kBufSizeMax) ? (size_t)endPos : kBufSizeMax;
if (bufSize < kEcdSize)
return S_FALSE;
// CByteArr byteBuffer(bufSize);
RINOK(AllocateBuffer(kBufSizeMax))
{
RINOK(Seek_SavePos(endPos - bufSize))
size_t processed = bufSize;
const HRESULT res = ReadStream(Stream, Buffer, &processed);
_streamPos += processed;
_bufCached = processed;
_bufPos = 0;
_cnt += processed;
if (res != S_OK)
return res;
if (processed != bufSize)
return S_FALSE;
}
RINOK(Seek_SavePos(endPos - bufSize))
size_t processed = bufSize;
HRESULT res = ReadStream(Stream, Buffer, &processed);
_streamPos += processed;
_bufCached = processed;
_bufPos = 0;
_cnt += processed;
if (res != S_OK)
return res;
if (processed != bufSize)
return S_FALSE;
CCdInfo &cdInfo = Vols.ecd;
for (size_t i = bufSize - kEcdSize + 1;;)
{
if (i == 0)
return S_FALSE;
const Byte *buf = Buffer;
for (;;)
{
i--;
if (buf[i] == 0x50)
break;
if (i == 0)
return S_FALSE;
}
if (Get32(buf + i) != NSignature::kEcd)
continue;
const Byte *p = buf + i;
do
if (p == buf)
return S_FALSE;
while (*(--p) != 0x50);
cdInfo.ParseEcd32(buf + i);
i = (size_t)(p - buf);
if (Get32(p) != NSignature::kEcd)
continue;
cdInfo.ParseEcd32(p);
}
if (i >= kEcd64Locator_Size)
{
@ -1793,29 +1781,24 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
// Most of the zip64 use fixed size Zip64 ECD
// we try relative backward reading.
UInt64 absEcd64 = endPos - bufSize + i - (kEcd64Locator_Size + kEcd64_FullSize);
const UInt64 absEcd64 = endPos - bufSize + i - (kEcd64Locator_Size + kEcd64_FullSize);
if (locatorIndex >= kEcd64_FullSize)
if (checkOffsetMode || absEcd64 == locator.Ecd64Offset)
{
const Byte *ecd64 = buf + locatorIndex - kEcd64_FullSize;
if (Get32(ecd64) == NSignature::kEcd64)
if (Get32(ecd64) == NSignature::kEcd64 &&
Get64(ecd64 + 4) == kEcd64_MainSize)
{
UInt64 mainEcd64Size = Get64(ecd64 + 4);
if (mainEcd64Size == kEcd64_MainSize)
{
cdInfo.ParseEcd64e(ecd64 + 12);
ArcInfo.Base = (Int64)(absEcd64 - locator.Ecd64Offset);
// ArcInfo.BaseVolIndex = cdInfo.ThisDisk;
return S_OK;
}
cdInfo.ParseEcd64e(ecd64 + 12);
ArcInfo.Base = (Int64)(absEcd64 - locator.Ecd64Offset);
// ArcInfo.BaseVolIndex = cdInfo.ThisDisk;
return S_OK;
}
}
// some zip64 use variable size Zip64 ECD.
// we try to use absolute offset from locator.
if (absEcd64 != locator.Ecd64Offset)
{
if (TryEcd64(locator.Ecd64Offset, cdInfo) == S_OK)
@ -1881,6 +1864,9 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
items.Clear();
IsCdUnsorted = false;
if ((Int64)cdOffset < 0)
return S_FALSE;
// _startLocalFromCd_Disk = (UInt32)(Int32)-1;
// _startLocalFromCd_Offset = (UInt64)(Int64)-1;

View file

@ -49,42 +49,54 @@ void COutArchive::SeekToCurPos()
// #define DOES_NEED_ZIP64(v) (v >= 0)
Z7_NO_INLINE
void COutArchive::WriteBytes(const void *data, size_t size)
{
m_OutBuffer.WriteBytes(data, size);
m_CurPos += size;
}
Z7_NO_INLINE
void COutArchive::Write8(Byte b)
{
m_OutBuffer.WriteByte(b);
m_CurPos++;
}
Z7_NO_INLINE
void COutArchive::Write16(UInt16 val)
{
Write8((Byte)val);
Write8((Byte)(val >> 8));
}
Z7_NO_INLINE
void COutArchive::Write32(UInt32 val)
{
for (int i = 0; i < 4; i++)
{
Write8((Byte)val);
// Write8((Byte)val);
m_OutBuffer.WriteByte((Byte)val);
val >>= 8;
}
m_CurPos += 4;
}
#define WRITE_CONST_PAIR_16_16(a, b) { Write32((a) | ((UInt32)(b) << 16)); }
Z7_NO_INLINE
void COutArchive::Write64(UInt64 val)
{
for (int i = 0; i < 8; i++)
{
Write8((Byte)val);
// Write8((Byte)val);
m_OutBuffer.WriteByte((Byte)val);
val >>= 8;
}
m_CurPos += 8;
}
Z7_NO_INLINE
void COutArchive::WriteExtra(const CExtraBlock &extra)
{
FOR_VECTOR (i, extra.SubBlocks)
@ -134,11 +146,9 @@ void COutArchive::WriteTimeExtra(const CItemOut &item, bool writeNtfs)
if (writeNtfs)
{
// windows explorer ignores that extra
Write16(NFileHeader::NExtraID::kNTFS);
Write16(k_Ntfs_ExtraSize);
WRITE_CONST_PAIR_16_16(NFileHeader::NExtraID::kNTFS, k_Ntfs_ExtraSize)
Write32(0); // reserved
Write16(NFileHeader::NNtfsExtra::kTagTime);
Write16(8 * 3);
WRITE_CONST_PAIR_16_16(NFileHeader::NNtfsExtra::kTagTime, 8 * 3)
WriteNtfsTime(item.Ntfs_MTime);
WriteNtfsTime(item.Ntfs_ATime);
WriteNtfsTime(item.Ntfs_CTime);
@ -148,8 +158,7 @@ void COutArchive::WriteTimeExtra(const CItemOut &item, bool writeNtfs)
{
// windows explorer ignores that extra
// by specification : should we write to local header also?
Write16(NFileHeader::NExtraID::kUnixTime);
Write16(k_UnixTime_ExtraSize);
WRITE_CONST_PAIR_16_16(NFileHeader::NExtraID::kUnixTime, k_UnixTime_ExtraSize)
const Byte flags = (Byte)((unsigned)1 << NFileHeader::NUnixTime::kMTime);
Write8(flags);
UInt32 unixTime;
@ -217,8 +226,7 @@ void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
if (isZip64)
{
Write16(NFileHeader::NExtraID::kZip64);
Write16(8 + 8);
WRITE_CONST_PAIR_16_16(NFileHeader::NExtraID::kZip64, 8 + 8)
Write64(size);
Write64(packSize);
}
@ -357,8 +365,9 @@ HRESULT COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const
const UInt64 cdSize = cd64EndOffset - cdOffset;
const bool cdOffset64 = DOES_NEED_ZIP64(cdOffset);
const bool cdSize64 = DOES_NEED_ZIP64(cdSize);
const bool items64 = items.Size() >= 0xFFFF;
const bool isZip64 = (cdOffset64 || cdSize64 || items64);
const bool need_Items_64 = items.Size() >= 0xFFFF;
const unsigned items16 = (UInt16)(need_Items_64 ? 0xFFFF: items.Size());
const bool isZip64 = (cdOffset64 || cdSize64 || need_Items_64);
// isZip64 = true; // to test Zip64
@ -371,8 +380,8 @@ HRESULT COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const
// const UInt32 extraSize = 1 << 26;
// Write64(kEcd64_MainSize + extraSize);
Write16(45); // made by version
Write16(45); // extract version
WRITE_CONST_PAIR_16_16(45, // made by version
45) // extract version
Write32(0); // ThisDiskNumber
Write32(0); // StartCentralDirectoryDiskNumber
Write64((UInt64)items.Size());
@ -389,10 +398,9 @@ HRESULT COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const
}
Write32(NSignature::kEcd);
Write16(0); // ThisDiskNumber
Write16(0); // StartCentralDirectoryDiskNumber
Write16((UInt16)(items64 ? 0xFFFF: items.Size()));
Write16((UInt16)(items64 ? 0xFFFF: items.Size()));
WRITE_CONST_PAIR_16_16(0, 0) // ThisDiskNumber, StartCentralDirectoryDiskNumber
Write16((UInt16)items16);
Write16((UInt16)items16);
WRITE_32_VAL_SPEC(cdSize, cdSize64)
WRITE_32_VAL_SPEC(cdOffset, cdOffset64)

View file

@ -153,7 +153,7 @@ namespace NCommandType
};
}
static const char *g_Commands = "txl";
static const char * const g_Commands = "txl";
struct CArchiveCommand
{

View file

@ -48,72 +48,60 @@ static bool ReadDataString(CFSTR fileName, LPCSTR startID,
NIO::CInFile inFile;
if (!inFile.Open(fileName))
return false;
const size_t kBufferSize = (1 << 12);
const size_t kBufferSize = 1 << 12;
Byte buffer[kBufferSize];
const unsigned signatureStartSize = MyStringLen(startID);
const unsigned signatureEndSize = MyStringLen(endID);
const size_t signatureStartSize = MyStringLen(startID + 1);
const size_t signatureEndSize = MyStringLen(endID + 1);
size_t numBytesPrev = 0;
bool writeMode = false;
UInt64 posTotal = 0;
UInt32 posTotal = 0;
for (;;)
{
if (posTotal > (1 << 20))
return (stringResult.IsEmpty());
const size_t numReadBytes = kBufferSize - numBytesPrev;
size_t processedSize;
if (!inFile.ReadFull(buffer + numBytesPrev, numReadBytes, processedSize))
return false;
if (processedSize == 0)
return true;
const size_t numBytesInBuffer = numBytesPrev + processedSize;
UInt32 pos = 0;
numBytesPrev += processedSize;
size_t pos = 0;
for (;;)
{
if (writeMode)
{
if (pos + signatureEndSize > numBytesInBuffer)
if (pos + signatureEndSize > numBytesPrev)
break;
if (memcmp(buffer + pos, endID, signatureEndSize) == 0)
return true;
const Byte b = buffer[pos];
const Byte b = buffer[pos++];
if (b == 0)
return false;
if (b == ';' && memcmp(buffer + pos, endID + 1, signatureEndSize) == 0)
return true;
stringResult += (char)b;
pos++;
}
else
{
if (pos + signatureStartSize > numBytesInBuffer)
if (pos + signatureStartSize > numBytesPrev)
break;
if (memcmp(buffer + pos, startID, signatureStartSize) == 0)
const Byte b = buffer[pos++];
if (b == ';' && memcmp(buffer + pos, startID + 1, signatureStartSize) == 0)
{
writeMode = true;
pos += signatureStartSize;
}
else
pos++;
}
}
numBytesPrev = numBytesInBuffer - pos;
posTotal += pos;
posTotal += (UInt32)pos;
if (posTotal > (1 << 21))
return stringResult.IsEmpty();
numBytesPrev -= pos;
memmove(buffer, buffer + pos, numBytesPrev);
}
}
static char kStartID[] = { ',','!','@','I','n','s','t','a','l','l','@','!','U','T','F','-','8','!', 0 };
static char kEndID[] = { ',','!','@','I','n','s','t','a','l','l','E','n','d','@','!', 0 };
static struct CInstallIDInit
{
CInstallIDInit()
{
kStartID[0] = ';';
kEndID[0] = ';';
}
} g_CInstallIDInit;
static const char * const kStartID = ",!@Install@!UTF-8!";
static const char * const kEndID = ",!@InstallEnd@!";
#if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
#define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return 1;

View file

@ -753,7 +753,7 @@ Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value))
{
if (StoreOwnerName)
{
const uid_t gid = st.st_gid;
const gid_t gid = st.st_gid;
{
if (!OwnerGroup.IsEmpty() && _gid == gid)
prop = OwnerGroup;

View file

@ -84,8 +84,8 @@ public:
BY_HANDLE_FILE_INFORMATION _info;
#else
struct stat _info;
UInt32 _uid;
UInt32 _gid;
uid_t _uid; // uid_t can be unsigned or signed int
gid_t _gid;
UString OwnerName;
UString OwnerGroup;
bool StoreOwnerId;

View file

@ -426,7 +426,7 @@ static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
}
}
static const char *g_Commands = "audtexlbih";
static const char * const g_Commands = "audtexlbih";
static bool ParseArchiveCommand(const UString &commandString, CArcCommand &command)
{

View file

@ -17,14 +17,14 @@ using namespace NWindows;
using namespace NFile;
static const char *g_ArcExts =
static const char * const g_ArcExts =
"7z"
"\0" "zip"
"\0" "tar"
"\0" "wim"
"\0";
static const char *g_HashExts =
static const char * const g_HashExts =
"sha256"
"\0";

View file

@ -3038,7 +3038,7 @@ AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti)
FOR_VECTOR (i, ti.Groups.GroupSizes)
{
if (i != 0)
s.Add_Char(' ');
s.Add_Space();
s.Add_UInt32(ti.Groups.GroupSizes[i]);
}
}
@ -3773,10 +3773,11 @@ HRESULT Bench(
#ifndef Z7_ST
if (threadsInfo.Get() && threadsInfo.GetNumProcessThreads() != 0)
numCPUs = threadsInfo.GetNumProcessThreads();
else
if (!threadsInfo.Get()
|| (numCPUs = threadsInfo.GetNumProcessThreads()) == 0)
numCPUs = NSystem::GetNumberOfProcessors();
// numCPUs : is number of threads assigned to process with affinity,
// or it's total number of threads in all groups, if IsGroupMode == true, and there is default affinity.
#endif

View file

@ -201,8 +201,8 @@ static const CFieldInfoInit kStandardFieldTable[] =
{ kpidPath, "Name", kLeft, kLeft, 2, 24 }
};
const unsigned kNumSpacesMax = 32; // it must be larger than max CFieldInfoInit.Width
static const char *g_Spaces =
static const unsigned kNumSpacesMax = 32; // it must be larger than max CFieldInfoInit.Width
static const char * const g_Spaces =
" " ;
static void PrintSpaces(unsigned numSpaces)

View file

@ -9,6 +9,7 @@
#include <windowsx.h>
#include "../../../Common/IntToString.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/Wildcard.h"
@ -19,6 +20,7 @@
#include "../../../Windows/Menu.h"
#include "../../../Windows/ProcessUtils.h"
#include "../../../Windows/PropVariantConv.h"
#include "../../../Windows/Shell.h"
#include "../../../Windows/Control/ComboBox.h"
#include "../../../Windows/Control/Dialog.h"
#include "../../../Windows/Control/Edit.h"
@ -57,7 +59,7 @@ static const int kParentIndex = -1;
// static const UINT k_Message_RefreshPathEdit = WM_APP + 1;
static const wchar_t *k_Message_Link_operation_was_Blocked =
static const wchar_t * const k_Message_Link_operation_was_Blocked =
L"link openning was blocked by 7-Zip";
extern UString HResultToMessage(HRESULT errorCode);
@ -978,35 +980,61 @@ void CBrowseDialog2::OnHelp()
#endif
HRESULT ShellFolder_ParseDisplayName(IShellFolder *shellFolder,
HWND hwnd, const UString &path, LPITEMIDLIST *ppidl);
HRESULT StartApplication(const UString &dir, const UString &path, HWND window, CProcess &process);
HRESULT StartApplication(const UString &dir, const UString &path, HWND window, CProcess &process)
{
UString path2 = path;
#ifdef _WIN32
UINT32 result;
{
#ifdef _WIN32
NShell::CItemIDList pidl;
// SHELLEXECUTEINFO::pidl is more accurate way than SHELLEXECUTEINFO::lpFile
{
CMyComPtr<IShellFolder> desktop;
if (SHGetDesktopFolder(&desktop) == S_OK && desktop)
if (ShellFolder_ParseDisplayName(desktop,
NULL, // HWND : do we need (window) or NULL here?
path,
&pidl) != S_OK)
pidl.Detach();
}
{
const int dot = path2.ReverseFind_Dot();
const int separ = path2.ReverseFind_PathSepar();
if (dot < 0 || dot < separ)
path2.Add_Dot();
if (separ != (int)path2.Len() - 1)
if (dot < 0 || dot < separ)
path2.Add_Dot();
}
#endif
#endif // _WIN32
UINT32 result;
#ifndef _UNICODE
if (g_IsNT)
{
SHELLEXECUTEINFOW execInfo;
memset(&execInfo, 0, sizeof(execInfo));
// execInfo.hwnd = NULL;
// execInfo.lpVerb = NULL;
// execInfo.lpFile = NULL;
// execInfo.lpDirectory = NULL;
// execInfo.lpParameters = NULL;
// execInfo.hProcess = NULL;
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
execInfo.hwnd = NULL;
execInfo.lpVerb = NULL;
execInfo.lpFile = path2;
execInfo.lpParameters = NULL;
execInfo.lpDirectory = dir.IsEmpty() ? NULL : (LPCWSTR)dir;
if (!dir.IsEmpty())
execInfo.lpDirectory = dir;
execInfo.nShow = SW_SHOWNORMAL;
execInfo.hProcess = NULL;
if ((LPCITEMIDLIST)pidl)
{
execInfo.lpIDList = pidl;
execInfo.fMask |= SEE_MASK_IDLIST;
}
else
execInfo.lpFile = path2;
typedef BOOL (WINAPI * Func_ShellExecuteExW)(LPSHELLEXECUTEINFOW lpExecInfo);
Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
const
@ -1024,34 +1052,40 @@ Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
#endif
{
SHELLEXECUTEINFO execInfo;
memset(&execInfo, 0, sizeof(execInfo));
// execInfo.hwnd = NULL;
// execInfo.lpVerb = NULL;
// execInfo.lpFile = NULL;
// execInfo.lpDirectory = NULL;
// execInfo.lpParameters = NULL;
// execInfo.hProcess = NULL;
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS
#ifndef UNDER_CE
| SEE_MASK_FLAG_DDEWAIT
#endif
;
execInfo.hwnd = NULL;
execInfo.lpVerb = NULL;
execInfo.nShow = SW_SHOWNORMAL;
const CSysString sysPath (GetSystemString(path2));
const CSysString sysDir (GetSystemString(dir));
execInfo.lpFile = sysPath;
execInfo.lpParameters = NULL;
execInfo.lpDirectory =
#ifdef UNDER_CE
NULL
#else
sysDir.IsEmpty() ? NULL : (LPCTSTR)sysDir
#endif
;
execInfo.nShow = SW_SHOWNORMAL;
execInfo.hProcess = NULL;
#ifndef UNDER_CE
if (!sysDir.IsEmpty())
execInfo.lpDirectory = sysDir;
#endif
if ((LPCITEMIDLIST)pidl)
{
execInfo.lpIDList = pidl;
execInfo.fMask |= SEE_MASK_IDLIST;
}
else
execInfo.lpFile = sysPath;
::ShellExecuteEx(&execInfo);
result = (UINT32)(UINT_PTR)execInfo.hInstApp;
process.Attach(execInfo.hProcess);
}
// DEBUG_PRINT_NUM("-- ShellExecuteEx -- execInfo.hInstApp = ", result)
}
if (result <= 32)
{
switch (result)
@ -1063,10 +1097,8 @@ Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
// L"There is no application associated with the given file name extension",
);
}
return E_FAIL; // fixed in 15.13. Can we use it for any Windows version?
}
return S_OK;
}

View file

@ -748,8 +748,8 @@ Z7_COM7F_IMF2(Int32, CFSFolder::CompareItems(UInt32 index1, UInt32 index2, PROPI
case kpidMTime: return CompareFileTime(&fi1.MTime, &fi2.MTime);
case kpidIsDir:
{
bool isDir1 = /* ss1 ? false : */ fi1.IsDir();
bool isDir2 = /* ss2 ? false : */ fi2.IsDir();
const bool isDir1 = /* ss1 ? false : */ fi1.IsDir();
const bool isDir2 = /* ss2 ? false : */ fi2.IsDir();
if (isDir1 == isDir2)
return 0;
return isDir1 ? -1 : 1;
@ -798,7 +798,9 @@ Z7_COM7F_IMF2(Int32, CFSFolder::CompareItems(UInt32 index1, UInt32 index2, PROPI
return MyStringCompareNoCase(comment1, comment2);
}
case kpidPrefix:
if (fi1.Parent < 0) return (fi2.Parent < 0) ? 0 : -1;
if (fi1.Parent == fi2.Parent)
return 0;
if (fi1.Parent < 0) return -1;
if (fi2.Parent < 0) return 1;
return CompareFileNames_ForFolderList(
Folders[fi1.Parent],

View file

@ -253,8 +253,7 @@ bool CLangPage::OnInit()
temp += " ";
temp += rec.Mark;
}
const int index = (int)_langCombo.AddString(temp);
_langCombo.SetItemData(index, (LPARAM)rec.LangInfoIndex);
const int index = (int)_langCombo.AddString_SetItemData(temp, (LPARAM)rec.LangInfoIndex);
if (rec.IsSelected)
_langCombo.SetCurSel(index);
}

View file

@ -222,8 +222,7 @@ bool CMenuPage::OnInit()
s.Add_UInt32(val);
if (i == 0)
s.Insert(0, L"* ");
const int index = (int)_zoneCombo.AddString(s);
_zoneCombo.SetItemData(index, (LPARAM)val);
const int index = (int)_zoneCombo.AddString_SetItemData(s, (LPARAM)val);
if (val == wz)
_zoneCombo.SetCurSel(index);
}

View file

@ -825,7 +825,10 @@ void CPanel::EditItem(unsigned index, bool useEditor)
return;
}
CProcess process;
StartEditApplication(GetItemFullPath(index), useEditor, (HWND)*this, process);
StartEditApplication(GetItemFullPath(index), useEditor,
// (HWND)*this,
GetParent(),
process);
}
@ -854,7 +857,10 @@ void CPanel::OpenFolderExternal(unsigned index)
path.Add_PathSepar();
}
StartApplicationDontWait(prefix, path, (HWND)*this);
StartApplicationDontWait(prefix, path,
// (HWND)*this
GetParent()
);
}
@ -981,7 +987,10 @@ void CPanel::OpenItem(unsigned index, bool tryInternal, bool tryExternal, const
{
// SetCurrentDirectory opens HANDLE to folder!!!
// NDirectory::MySetCurrentDirectory(prefix);
StartApplicationDontWait(prefix, fullPath, (HWND)*this);
StartApplicationDontWait(prefix, fullPath,
// (HWND)*this
GetParent()
);
}
}
@ -1732,9 +1741,15 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna
CProcess process;
HRESULT res;
if (editMode)
res = StartEditApplication(fs2us(tempFilePath), useEditor, (HWND)*this, process);
res = StartEditApplication(fs2us(tempFilePath), useEditor,
// (HWND)*this,
GetParent(),
process);
else
res = StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process);
res = StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath),
// (HWND)*this,
GetParent(),
process);
if ((HANDLE)process == NULL)
{

View file

@ -488,7 +488,9 @@ struct CFolderPidls
};
static HRESULT ShellFolder_ParseDisplayName(IShellFolder *shellFolder,
HRESULT ShellFolder_ParseDisplayName(IShellFolder *shellFolder,
HWND hwnd, const UString &path, LPITEMIDLIST *ppidl);
HRESULT ShellFolder_ParseDisplayName(IShellFolder *shellFolder,
HWND hwnd, const UString &path, LPITEMIDLIST *ppidl)
{
ULONG eaten = 0;

View file

@ -82,7 +82,7 @@ static inline const wchar_t *GetExtensionPtr(const UString &name)
void CPanel::SetSortRawStatus()
{
_isRawSortProp = false;
_isRawSortProp = 0; // false;
FOR_VECTOR (i, _columns)
{
const CPropColumn &prop = _columns[i];
@ -95,21 +95,15 @@ void CPanel::SetSortRawStatus()
}
static int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
static int CALLBACK CompareItems2(const LPARAM lParam1, const LPARAM lParam2,
const CPanel * const panel, const PROPID propID, const Int32 isRawProp)
{
if (lpData == 0)
return 0;
CPanel *panel = (CPanel*)lpData;
PROPID propID = panel->_sortID;
if (propID == kpidNoProperty)
return MyCompare(lParam1, lParam2);
if (panel->_isRawSortProp)
if (isRawProp)
{
// Sha1, NtSecurity, NtReparse
// Sha1, Checksum, NtSecurity, NtReparse
const void *data1;
const void *data2;
UInt32 dataSize1;
@ -135,7 +129,7 @@ static int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
}
if (panel->_folderCompare)
return panel->_folderCompare->CompareItems((UInt32)lParam1, (UInt32)lParam2, propID, panel->_isRawSortProp);
return panel->_folderCompare->CompareItems((UInt32)lParam1, (UInt32)lParam2, propID, isRawProp);
switch (propID)
{
@ -189,16 +183,41 @@ int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
if (lParam1 == (int)kParentIndex) return -1;
if (lParam2 == (int)kParentIndex) return 1;
CPanel *panel = (CPanel*)lpData;
const CPanel *panel = (CPanel*)lpData;
const bool isDir1 = panel->IsItem_Folder((unsigned)lParam1);
const bool isDir2 = panel->IsItem_Folder((unsigned)lParam2);
if (isDir1 && !isDir2) return -1;
if (isDir2 && !isDir1) return 1;
if (isDir1 != isDir2)
return isDir1 ? -1 : 1;
const int result = CompareItems2(lParam1, lParam2, lpData);
return panel->_ascending ? result: (-result);
/*
we have up to 3 iterations:
1: prop,
2: kpidName, kpidPrefix
3: prop, kpidName, kpidPrefix
3: kpidPrefix, kpidName, kpidPrefix : is some rare case
*/
PROPID propID = panel->_sortID;
int res = 0;
for (unsigned iter = 0; iter < 3; iter++)
{
res = CompareItems2(lParam1, lParam2, panel, propID,
iter ? 0 : panel->_isRawSortProp);
if (res)
break;
if (propID == kpidName)
{
// if (!_flatMode.IsEmpty()) break; // !_flatMode ;
propID = kpidPrefix;
continue;
}
if (iter)
break;
propID = kpidName;
}
if (res == 0)
res = MyCompare(lParam1, lParam2); // order of LoadSubItems()
return panel->_ascending ? res: -res;
}

View file

@ -440,11 +440,9 @@ static const size_t kMaxDicSize = (size_t)1 << (22 + sizeof(size_t) / 4 * 5);
static int ComboBox_Add_UInt32(NWindows::NControl::CComboBox &cb, UInt32 v)
{
TCHAR s[16];
WCHAR s[16];
ConvertUInt32ToString(v, s);
const int index = (int)cb.AddString(s);
cb.SetItemData(index, (LPARAM)v);
return index;
return (int)cb.AddString_SetItemData(s, (LPARAM)v);
}
@ -481,21 +479,17 @@ bool CBenchmarkDialog::OnInit()
_consoleEdit.SendMsg(WM_SETFONT, (WPARAM)_font._font, TRUE);
}
UInt32 numCPUs = 1;
UInt32 numCPUs = 1; // process threads
UInt32 numCPUs_Sys = 1; // system threads
{
AString s ("/ ");
NSystem::CProcessAffinity threadsInfo;
threadsInfo.InitST();
#ifndef Z7_ST
threadsInfo.Get_and_return_NumProcessThreads_and_SysThreads(numCPUs, numCPUs_Sys);
#endif
#ifndef Z7_ST
if (threadsInfo.Get() && threadsInfo.processAffinityMask != 0)
numCPUs = threadsInfo.GetNumProcessThreads();
else
numCPUs = NSystem::GetNumberOfProcessors();
#endif
AString s ("/ ");
s.Add_UInt32(numCPUs);
s += GetProcessThreadsInfo(threadsInfo);
SetItemTextA(IDT_BENCH_HARDWARE_THREADS, s);
@ -506,10 +500,8 @@ bool CBenchmarkDialog::OnInit()
SetItemTextA(IDT_BENCH_SYS1, s);
if (s != s2 && !s2.IsEmpty())
SetItemTextA(IDT_BENCH_SYS2, s2);
}
{
AString registers;
GetCpuName_MultiLine(s, registers);
GetCpuName_MultiLine(s, s2); // s2==registers
SetItemTextA(IDT_BENCH_CPU, s);
}
{
@ -526,22 +518,18 @@ bool CBenchmarkDialog::OnInit()
// ----- Num Threads ----------
if (numCPUs < 1)
numCPUs = 1;
numCPUs = MyMin(numCPUs, (UInt32)(1 << 6)); // it's WIN32 limit
UInt32 numThreads = Sync.NumThreads;
if (numThreads == (UInt32)(Int32)-1)
numThreads = numCPUs;
if (numThreads > 1)
numThreads &= ~(UInt32)1;
const UInt32 kNumThreadsMax = (1 << 12);
if (numThreads > kNumThreadsMax)
numThreads = kNumThreadsMax;
numThreads &= ~(UInt32)1;
if (numThreads == 0)
numThreads = 1;
numThreads = MyMin(numThreads, (UInt32)(1u << 14));
m_NumThreads.Attach(GetItem(IDC_BENCH_NUM_THREADS));
const UInt32 numTheads_Combo = numCPUs * 2;
if (numCPUs_Sys == 0)
numCPUs_Sys = 1;
const UInt32 numTheads_Combo = numCPUs_Sys * 2;
UInt32 v = 1;
int cur = 0;
for (; v <= numTheads_Combo;)
@ -1069,16 +1057,17 @@ static void AddUsageString(UString &s, const CTotalBenchRes &info)
numIter = 1000000;
UInt64 usage = GetUsagePercents(info.Usage / numIter);
wchar_t w[64];
ConvertUInt64ToString(usage, w);
unsigned len = MyStringLen(w);
wchar_t w[32];
wchar_t *p = ConvertUInt64ToString(usage, w);
p[0] = '%';
p[1] = 0;
unsigned len = (unsigned)(size_t)(p - w);
while (len < 5)
{
s.Add_Space();
len++;
}
s += w;
s += "%";
}

View file

@ -506,8 +506,7 @@ bool CCompressDialog::OnInit()
{
const unsigned arcIndex = ArcIndices[i];
const CArcInfoEx &ai = (*ArcFormats)[arcIndex];
const int index = (int)m_Format.AddString(ai.Name);
m_Format.SetItemData(index, (LPARAM)arcIndex);
const int index = (int)m_Format.AddString_SetItemData(ai.Name, (LPARAM)arcIndex);
if (!needSetMain)
{
if (Info.FormatIndex == (int)arcIndex)
@ -540,11 +539,6 @@ bool CCompressDialog::OnInit()
AddComboItems(m_PathMode, k_PathMode_IDs, Z7_ARRAY_SIZE(k_PathMode_IDs),
k_PathMode_Vals, Info.PathMode);
TCHAR s[32] = { TEXT('/'), TEXT(' '), 0 };
ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2);
SetItemText(IDT_COMPRESS_HARDWARE_THREADS, s);
CheckButton(IDX_COMPRESS_SHARED, Info.OpenShareForWrite);
CheckButton(IDX_COMPRESS_DEL, Info.DeleteAfterCompressing);
@ -653,7 +647,19 @@ void CCompressDialog::EnableMultiCombo(unsigned id)
EnableItem(id, enable);
}
static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s);
static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s)
{
return cb.AddString((CSysString)s);
}
static LRESULT ComboBox_AddStringAscii_SetItemData(NControl::CComboBox &cb,
const char *s, LPARAM lParam)
{
const LRESULT index = ComboBox_AddStringAscii(cb, s);
if (index >= 0) // optional check
cb.SetItemData((int)index, lParam);
return index;
}
static void Combine_Two_BoolPairs(const CBoolPair &b1, const CBoolPair &b2, CBool1 &res)
{
@ -1604,20 +1610,14 @@ void CCompressDialog::SetLevel2()
AddLangString(s, langID);
}
}
const int index = (int)m_Level.AddString(s);
m_Level.SetItemData(index, (LPARAM)i);
m_Level.AddString_SetItemData(s, (LPARAM)i);
}
}
SetNearestSelectComboBox(m_Level, level);
}
static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s)
{
return cb.AddString((CSysString)s);
}
static const char *k_Auto_Prefix = "* ";
static const char * const k_Auto_Prefix = "* ";
static void Modify_Auto(AString &s)
{
@ -1690,8 +1690,8 @@ void CCompressDialog::SetMethod2(int keepMethodId)
writtenMethodId = -1;
Modify_Auto(s);
}
const int itemIndex = (int)ComboBox_AddStringAscii(m_Method, s);
m_Method.SetItemData(itemIndex, writtenMethodId);
const int itemIndex = (int)ComboBox_AddStringAscii_SetItemData(m_Method,
s, writtenMethodId);
if (keepMethodId == methodID)
{
m_Method.SetCurSel(itemIndex);
@ -1731,7 +1731,7 @@ void CCompressDialog::SetEncryptionMethod()
}
else if (ai.Is_Zip())
{
int index = FindRegistryFormat(ai.Name);
const int index = FindRegistryFormat(ai.Name);
UString encryptionMethod;
if (index >= 0)
{
@ -1836,9 +1836,7 @@ static int Combo_AddDict2(NWindows::NControl::CComboBox &cb, size_t sizeReal, si
s.Add_Char('B');
if (sizeReal == k_Auto_Dict)
Modify_Auto(s);
const int index = (int)ComboBox_AddStringAscii(cb, s);
cb.SetItemData(index, (LPARAM)sizeReal);
return index;
return (int)ComboBox_AddStringAscii_SetItemData(cb, s, (LPARAM)sizeReal);
}
int CCompressDialog::AddDict2(size_t sizeReal, size_t sizeShow)
@ -2201,9 +2199,7 @@ int CCompressDialog::AddOrder(UInt32 size)
{
char s[32];
ConvertUInt32ToString(size, s);
const int index = (int)ComboBox_AddStringAscii(m_Order, s);
m_Order.SetItemData(index, (LPARAM)size);
return index;
return (int)ComboBox_AddStringAscii_SetItemData(m_Order, s, (LPARAM)size);
}
int CCompressDialog::AddOrder_Auto()
@ -2211,9 +2207,7 @@ int CCompressDialog::AddOrder_Auto()
AString s;
s.Add_UInt32(_auto_Order);
Modify_Auto(s);
int index = (int)ComboBox_AddStringAscii(m_Order, s);
m_Order.SetItemData(index, (LPARAM)(INT_PTR)(-1));
return index;
return (int)ComboBox_AddStringAscii_SetItemData(m_Order, s, (LPARAM)(INT_PTR)(-1));
}
void CCompressDialog::SetOrder2()
@ -2490,9 +2484,7 @@ void CCompressDialog::SetSolidBlockSize2()
AString s;
Add_Size(s, _auto_Solid);
Modify_Auto(s);
const int index = (int)ComboBox_AddStringAscii(m_Solid, s);
m_Solid.SetItemData(index, (LPARAM)(UInt32)(Int32)-1);
curSel = index;
curSel = (int)ComboBox_AddStringAscii_SetItemData(m_Solid, s, (LPARAM)(UInt32)(Int32)-1);
}
if (is7z)
@ -2501,8 +2493,7 @@ void CCompressDialog::SetSolidBlockSize2()
// kSolidLog_NoSolid = 0 for xz means default blockSize
if (is7z)
LangString(IDS_COMPRESS_NON_SOLID, s);
const int index = (int)m_Solid.AddString(s);
m_Solid.SetItemData(index, (LPARAM)(UInt32)kSolidLog_NoSolid);
const int index = (int)m_Solid.AddString_SetItemData(s, (LPARAM)(UInt32)kSolidLog_NoSolid);
if (defaultBlockSize == kSolidLog_NoSolid)
curSel = index;
}
@ -2511,16 +2502,15 @@ void CCompressDialog::SetSolidBlockSize2()
{
AString s;
Add_Size(s, (UInt64)1 << i);
const int index = (int)ComboBox_AddStringAscii(m_Solid, s);
m_Solid.SetItemData(index, (LPARAM)(UInt32)i);
const int index = (int)ComboBox_AddStringAscii_SetItemData(m_Solid, s, (LPARAM)(UInt32)i);
if (defaultBlockSize != (UInt32)(Int32)-1)
if (i <= defaultBlockSize || index <= 1)
curSel = index;
}
{
const int index = (int)m_Solid.AddString(LangString(IDS_COMPRESS_SOLID));
m_Solid.SetItemData(index, (LPARAM)kSolidLog_FullSolid);
const int index = (int)m_Solid.AddString_SetItemData(
LangString(IDS_COMPRESS_SOLID), (LPARAM)kSolidLog_FullSolid);
if (defaultBlockSize == kSolidLog_FullSolid)
curSel = index;
}
@ -2564,7 +2554,7 @@ static bool Is_Zstd_Mt_Supported()
}
*/
static const char *k_ST_Threads = " (ST)";
static const char * const k_ST_Threads = " (ST)";
void CCompressDialog::SetNumThreads2()
{
@ -2575,15 +2565,31 @@ void CCompressDialog::SetNumThreads2()
if (!fi.MultiThread_())
return;
const UInt32 numHardwareThreads = NSystem::GetNumberOfProcessors();
// 64; // for debug:
UInt32 numCPUs = 1; // process threads
UInt32 numHardwareThreads = 1; // system threads
NSystem::CProcessAffinity threadsInfo;
threadsInfo.InitST();
#ifndef Z7_ST
threadsInfo.Get_and_return_NumProcessThreads_and_SysThreads(numCPUs, numHardwareThreads);
#endif
UInt32 defaultValue = numHardwareThreads;
AString s ("/ ");
{
s.Add_UInt32(numCPUs);
if (numCPUs != numHardwareThreads)
{
s += " / ";
s.Add_UInt32(numHardwareThreads);
}
SetItemTextA(IDT_COMPRESS_HARDWARE_THREADS, s.Ptr());
}
UInt32 defaultValue = numCPUs;
bool useAutoThreads = true;
{
const CArcInfoEx &ai = Get_ArcInfoEx();
int index = FindRegistryFormat(ai.Name);
const int index = FindRegistryFormat(ai.Name);
if (index >= 0)
{
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
@ -2597,19 +2603,19 @@ void CCompressDialog::SetNumThreads2()
// const UInt32 num_ZSTD_threads_MAX = Is_Zstd_Mt_Supported() ? MY_ZSTDMT_NBWORKERS_MAX : 0;
UInt32 numAlgoThreadsMax = numHardwareThreads * 2;
const int methodID = GetMethodID();
const bool isZip = IsZipFormat();
UInt32 numAlgoThreadsMax = numHardwareThreads * 2; // for unknow methods
if (isZip)
numAlgoThreadsMax =
8 << (sizeof(size_t) / 2); // 32 threads for 32-bit : 128 threads for 64-bit
else if (IsXzFormat())
numAlgoThreadsMax = 256 * 2;
numAlgoThreadsMax = 256 * 2; // MTCODER_THREADS_MAX * 2
else switch (methodID)
{
case kLZMA: numAlgoThreadsMax = 2; break;
case kLZMA2: numAlgoThreadsMax = 256; break;
case kLZMA2: numAlgoThreadsMax = 256 * 2; break; // MTCODER_THREADS_MAX * 2
case kBZip2: numAlgoThreadsMax = 64; break;
// case kZSTD: numAlgoThreadsMax = num_ZSTD_threads_MAX; break;
case kCopy:
@ -2619,9 +2625,9 @@ void CCompressDialog::SetNumThreads2()
case kPPMdZip:
numAlgoThreadsMax = 1;
}
UInt32 autoThreads = numHardwareThreads;
UInt32 autoThreads = numCPUs;
if (autoThreads > numAlgoThreadsMax)
autoThreads = numAlgoThreadsMax;
autoThreads = numAlgoThreadsMax;
const UInt64 memUse_Limit = Get_MemUse_Bytes();
@ -2676,13 +2682,12 @@ void CCompressDialog::SetNumThreads2()
int curSel = -1;
{
AString s;
s.Empty();
s.Add_UInt32(autoThreads);
if (autoThreads == 0) s += k_ST_Threads;
Modify_Auto(s);
const int index = (int)ComboBox_AddStringAscii(m_NumThreads, s);
m_NumThreads.SetItemData(index, (LPARAM)(INT_PTR)(-1));
// m_NumThreads.SetItemData(index, autoThreads);
const int index = (int)ComboBox_AddStringAscii_SetItemData(m_NumThreads,
s, (LPARAM)(INT_PTR)(-1));
if (useAutoThreads)
curSel = index;
}
@ -2693,11 +2698,11 @@ void CCompressDialog::SetNumThreads2()
1;
i <= numHardwareThreads * 2 && i <= numAlgoThreadsMax; i++)
{
AString s;
s.Empty();
s.Add_UInt32(i);
if (i == 0) s += k_ST_Threads;
const int index = (int)ComboBox_AddStringAscii(m_NumThreads, s);
m_NumThreads.SetItemData(index, (LPARAM)(UInt32)i);
const int index = (int)ComboBox_AddStringAscii_SetItemData(m_NumThreads,
s, (LPARAM)(UInt32)i);
if (!useAutoThreads && i == defaultValue)
curSel = index;
}
@ -2754,9 +2759,7 @@ int CCompressDialog::AddMemComboItem(UInt64 val, bool isPercent, bool isDefault)
sRegistry.DeleteBack();
}
const unsigned dataIndex = _memUse_Strings.Add(sRegistry);
const int index = (int)m_MemUse.AddString(sUser);
m_MemUse.SetItemData(index, (LPARAM)dataIndex);
return index;
return (int)m_MemUse.AddString_SetItemData(sUser, (LPARAM)dataIndex);
}
@ -3439,11 +3442,7 @@ static const unsigned kTimePrec_1ns = 3;
static void AddTimeOption(UString &s, UInt32 val, const UString &unit, const char *sys = NULL)
{
// s += " : ";
{
AString s2;
s2.Add_UInt32(val);
s += s2;
}
s.Add_UInt32(val);
s.Add_Space();
s += unit;
if (sys)
@ -3476,9 +3475,7 @@ int COptionsDialog::AddPrec(unsigned prec, bool isDefault)
}
else
s.Add_UInt32(prec);
const int index = (int)m_Prec.AddString(s);
m_Prec.SetItemData(index, (LPARAM)writePrec);
return index;
return (int)m_Prec.AddString_SetItemData(s, (LPARAM)writePrec);
}

View file

@ -87,8 +87,8 @@ BEGIN
COMBOBOX IDC_COMPRESS_SOLID, g1x, 144, g1xs, 140, MY_COMBO
LTEXT "Number of CPU &threads:", IDT_COMPRESS_THREADS, m, 167, g0xs, 8
COMBOBOX IDC_COMPRESS_THREADS, g1x, 165, g1xs - 35, 140, MY_COMBO
RTEXT "", IDT_COMPRESS_HARDWARE_THREADS, g1x + g1xs - 35 + 10, 167, 25, MY_TEXT_NOPREFIX
COMBOBOX IDC_COMPRESS_THREADS, g1x, 165, g1xs - 40, 140, MY_COMBO
RTEXT "", IDT_COMPRESS_HARDWARE_THREADS, g1x + g1xs - 40, 167, 40, 16, SS_NOPREFIX
LTEXT "Memory usage for Compressing:", IDT_COMPRESS_MEMORY, m, 184, g2xs, 8

View file

@ -102,8 +102,7 @@ void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned n
{
UString s = LangString(langIDs[i]);
s.RemoveChar(L'&');
const int index = (int)combo.AddString(s);
combo.SetItemData(index, (LPARAM)i);
combo.AddString_SetItemData(s, (LPARAM)i);
if (values[i] == curVal)
curSel = i;
}

View file

@ -126,8 +126,9 @@ if compiled with new GCC libstdc++, GCC libstdc++ can use:
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
#if defined(Z7_LLVM_CLANG_VERSION) && __clang_major__ >= 18 // 18.1.0RC
#pragma GCC diagnostic ignored "-Wswitch-default"
#if defined(Z7_LLVM_CLANG_VERSION) && __clang_major__ >= 18 /* 18.1.0RC */ \
|| defined(Z7_APPLE_CLANG_VERSION) && __clang_major__ >= 16 // for APPLE=17 (LLVM=19)
#pragma GCC diagnostic ignored "-Wswitch-default"
#endif
// #pragma GCC diagnostic ignored "-Wunused-private-field"
// #pragma GCC diagnostic ignored "-Wnonportable-system-include-path"

View file

@ -202,7 +202,53 @@ public:
}
};
typedef CObjArray<Byte> CByteArr;
/* CSmallObjArray can be used for Byte arrays
or for arrays whose total size in bytes does not exceed size_t ranges.
So there is no need to use Z7_ARRAY_NEW macro in CSmallObjArray code. */
template <class T> class CSmallObjArray
{
protected:
T *_items;
private:
// we disable copy
CSmallObjArray(const CSmallObjArray &buffer);
void operator=(const CSmallObjArray &buffer);
public:
void Free()
{
delete []_items;
_items = NULL;
}
CSmallObjArray(size_t size): _items(NULL)
{
if (size != 0)
{
// Z7_ARRAY_NEW(_items, T, size)
_items = new T[size];
}
}
CSmallObjArray(): _items(NULL) {}
~CSmallObjArray() { delete []_items; }
operator T *() { return _items; }
operator const T *() const { return _items; }
const T* ConstData() const { return _items; }
T* NonConstData() const { return _items; }
T* NonConstData() { return _items; }
// const T* Data() const { return _items; }
// T* Data() { return _items; }
void Alloc(size_t newSize)
{
delete []_items;
_items = NULL;
// Z7_ARRAY_NEW(_items, T, newSize)
_items = new T[newSize];
}
};
typedef CSmallObjArray<Byte> CByteArr;
typedef CObjArray<bool> CBoolArr;
typedef CObjArray<int> CIntArr;
typedef CObjArray<unsigned> CUIntArr;

View file

@ -63,4 +63,13 @@ LRESULT CComboBox::GetLBText(int index, UString &s)
}
#endif
LRESULT CComboBox::AddString_SetItemData(LPCWSTR s, LPARAM lParam)
{
const LRESULT index = AddString(s);
// NOTE: SetItemData((int)-1, lParam) works as unexpected.
if (index >= 0) // optional check, because (index < 0) is not expected for normal inputs
SetItemData((int)index, lParam);
return index;
}
}}

View file

@ -21,6 +21,8 @@ public:
LRESULT AddString(LPCWSTR s);
#endif
LRESULT AddString_SetItemData(LPCWSTR s, LPARAM lParam);
/* If this parameter is -1, any current selection in the list is removed and the edit control is cleared.*/
LRESULT SetCurSel(int index) { return SendMsg(CB_SETCURSEL, MY_int_TO_WPARAM(index), 0); }
LRESULT SetCurSel(unsigned index) { return SendMsg(CB_SETCURSEL, index, 0); }

View file

@ -1162,6 +1162,15 @@ void CFileInfoBase::SetFrom_stat(const struct stat &st)
MTime = st.st_mtimespec;
ATime = st.st_atimespec;
#elif defined(__QNXNTO__) && defined(__ARM__) && !defined(__aarch64__)
// CTime = ST_CTIME(st);
// MTime = ST_MTIME(st);
// ATime = ST_ATIME(st);
CTime.tv_sec = st.st_ctime; CTime.tv_nsec = 0;
MTime.tv_sec = st.st_mtime; MTime.tv_nsec = 0;
ATime.tv_sec = st.st_atime; ATime.tv_nsec = 0;
#else
// timespec_To_FILETIME(st.st_ctim, CTime, &CTime_ns100);
// timespec_To_FILETIME(st.st_mtim, MTime, &MTime_ns100);
@ -1312,7 +1321,7 @@ bool CDirEntry::IsDots() const throw()
/* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN)
we can call fstatat() for that case, but we use only (Name) check here */
#if !defined(_AIX) && !defined(__sun)
#if !defined(_AIX) && !defined(__sun) && !defined(__QNXNTO__)
if (Type != DT_DIR && Type != DT_UNKNOWN)
return false;
#endif
@ -1352,7 +1361,7 @@ bool CEnumerator::NextAny(CDirEntry &fi, bool &found)
fi.iNode = de->d_ino;
#if !defined(_AIX) && !defined(__sun)
#if !defined(_AIX) && !defined(__sun) && !defined(__QNXNTO__)
fi.Type = de->d_type;
/* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN)
we can set (Type) from fstatat() in that case.

View file

@ -277,13 +277,13 @@ typedef CFileInfo CDirEntry;
struct CDirEntry
{
ino_t iNode;
#if !defined(_AIX) && !defined(__sun)
#if !defined(_AIX) && !defined(__sun) && !defined(__QNXNTO__)
Byte Type;
#endif
FString Name;
/*
#if !defined(_AIX) && !defined(__sun)
#if !defined(_AIX) && !defined(__sun) && !defined(__QNXNTO__)
bool IsDir() const
{
// (Type == DT_UNKNOWN) on some systems
@ -310,7 +310,7 @@ public:
bool Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool followLink) const;
bool DirEntry_IsDir(const CDirEntry &de, bool followLink) const
{
#if !defined(_AIX) && !defined(__sun)
#if !defined(_AIX) && !defined(__sun) && !defined(__QNXNTO__)
if (de.Type == DT_DIR)
return true;
if (de.Type != DT_UNKNOWN)

View file

@ -3,7 +3,11 @@
#ifndef ZIP7_INC_WINDOWS_SECURITY_UTILS_H
#define ZIP7_INC_WINDOWS_SECURITY_UTILS_H
#if defined(__MINGW32__) || defined(__MINGW64__)
#include <ntsecapi.h>
#else
#include <NTSecAPI.h>
#endif
#include "Defs.h"

View file

@ -5,8 +5,9 @@
#ifndef _WIN32
#include <unistd.h>
#include <limits.h>
#if defined(__APPLE__) || defined(__DragonFly__) || \
defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#if defined(__APPLE__) || defined(__DragonFly__) \
|| defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
|| defined(__QNXNTO__)
#include <sys/sysctl.h>
#else
#include <sys/sysinfo.h>
@ -299,8 +300,9 @@ bool GetRamSize(size_t &size)
size = (size_t)sizeof(size_t) << 29;
size64 = size;
#if defined(__APPLE__) || defined(__DragonFly__) || \
defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#if defined(__APPLE__) || defined(__DragonFly__) \
|| defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
|| defined(__QNXNTO__)
uint64_t val = 0;
int mib[2];

View file

@ -15,6 +15,8 @@
namespace NWindows {
namespace NSystem {
UInt32 GetNumberOfProcessors();
#ifdef _WIN32
struct CCpuGroups
@ -103,6 +105,25 @@ struct CProcessAffinity
return CountAffinity(systemAffinityMask);
}
// it returns normilized number of threads
void Get_and_return_NumProcessThreads_and_SysThreads(UInt32 &numProcessThreads, UInt32 &numSysThreads)
{
UInt32 num1 = 0, num2 = 0;
if (Get())
{
num1 = GetNumProcessThreads();
num2 = GetNumSystemThreads();
}
if (num1 == 0)
num1 = NSystem::GetNumberOfProcessors();
if (num1 == 0)
num1 = 1;
if (num2 < num1)
num2 = num1;
numProcessThreads = num1;
numSysThreads = num2;
}
BOOL Get();
BOOL SetProcAffinity() const
@ -177,8 +198,6 @@ struct CProcessAffinity
#endif // _WIN32
UInt32 GetNumberOfProcessors();
bool GetRamSize(size_t &size); // returns false, if unknown ram size
unsigned long Get_File_OPEN_MAX();

View file

@ -22,7 +22,7 @@
#if defined(__GLIBC__) && (__GLIBC__ * 100 + __GLIBC_MINOR__ >= 216)
#define Z7_GETAUXV_AVAILABLE
#else
#elif !defined(__QNXNTO__)
// #pragma message("=== is not NEW GLIBC === ")
#if defined __has_include
#if __has_include (<sys/auxv.h>)
@ -58,7 +58,7 @@
#ifdef USE_HWCAP
#if defined(__FreeBSD__)
#if defined(__FreeBSD__) || defined(__OpenBSD__)
// #if (__FreeBSD__ >= 13) // (FreeBSD 12.01 is required for elf_aux_info() ???)
static unsigned long MY_getauxval(int aux)

View file

@ -65,6 +65,14 @@ inline bool FILETIME_IsZero(const FILETIME &ft)
#define ST_MTIME(st) st.st_mtimespec
#define ST_ATIME(st) st.st_atimespec
#define ST_CTIME(st) st.st_ctimespec
#elif defined(__QNXNTO__) && defined(__ARM__) && !defined(__aarch64__)
// QNX armv7le (32-bit) for "struct stat" timestamps uses time_t instead of timespec
inline CFiTime ST_MTIME(const struct stat &st)
{ timespec ts; ts.tv_sec = st.st_mtime; ts.tv_nsec = 0; return ts; }
inline CFiTime ST_ATIME(const struct stat &st)
{ timespec ts; ts.tv_sec = st.st_atime; ts.tv_nsec = 0; return ts; }
inline CFiTime ST_CTIME(const struct stat &st)
{ timespec ts; ts.tv_sec = st.st_ctime; ts.tv_nsec = 0; return ts; }
#else
#define ST_MTIME(st) st.st_mtim
#define ST_ATIME(st) st.st_atim