Compare commits

...

3 Commits
15.11 ... 15.14

Author SHA1 Message Date
Igor Pavlov
c20d013055 15.14 2016-05-28 00:16:58 +01:00
Igor Pavlov
9608215ad8 15.13 2016-05-28 00:16:58 +01:00
Igor Pavlov
5de23c1deb 15.12 2016-05-28 00:16:58 +01:00
83 changed files with 2214 additions and 1175 deletions

80
C/7z.h
View File

@@ -1,5 +1,5 @@
/* 7z.h -- 7z interface
2014-02-08 : Igor Pavlov : Public domain */
2015-11-18 : Igor Pavlov : Public domain */
#ifndef __7Z_H
#define __7Z_H
@@ -48,21 +48,10 @@ typedef struct
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
UInt64 CodersUnpackSizes[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder;
/*
typedef struct
{
size_t CodersDataOffset;
size_t UnpackSizeDataOffset;
// UInt32 StartCoderUnpackSizesIndex;
UInt32 StartPackStreamIndex;
// UInt32 IndexOfMainOutStream;
} CSzFolder2;
*/
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes);
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
typedef struct
{
@@ -93,46 +82,24 @@ typedef struct
UInt32 NumFolders;
UInt64 *PackPositions; // NumPackStreams + 1
CSzBitUi32s FolderCRCs;
CSzBitUi32s FolderCRCs; // NumFolders
size_t *FoCodersOffsets;
size_t *FoSizesOffsets;
// UInt32 StartCoderUnpackSizesIndex;
UInt32 *FoStartPackStreamIndex;
size_t *FoCodersOffsets; // NumFolders + 1
UInt32 *FoStartPackStreamIndex; // NumFolders + 1
UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
Byte *FoToMainUnpackSizeIndex; // NumFolders
UInt64 *CoderUnpackSizes; // for all coders in all folders
// CSzFolder2 *Folders; // +1 item for sum values
Byte *CodersData;
Byte *UnpackSizesData;
size_t UnpackSizesDataSize;
// UInt64 *CoderUnpackSizes;
} CSzAr;
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain);
/*
SzExtract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
typedef struct
{
CSzAr db;
@@ -142,7 +109,7 @@ typedef struct
UInt32 NumFiles;
UInt64 *UnpackPositions;
UInt64 *UnpackPositions; // NumFiles + 1
// Byte *IsEmptyFiles;
Byte *IsDirs;
CSzBitUi32s CRCs;
@@ -152,9 +119,8 @@ typedef struct
CSzBitUi64s MTime;
CSzBitUi64s CTime;
// UInt32 *FolderStartPackStreamIndex;
UInt32 *FolderStartFileIndex; // + 1
UInt32 *FileIndexToFolderIndexMap;
UInt32 *FolderToFile; // NumFolders + 1
UInt32 *FileToFolder; // NumFiles
size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */
@@ -182,6 +148,28 @@ size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
*/
/*
SzArEx_Extract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
SRes SzArEx_Extract(
const CSzArEx *db,
ILookInStream *inStream,

View File

@@ -1,5 +1,5 @@
/* 7zArcIn.c -- 7z Input functions
2015-11-13 : Igor Pavlov : Public domain */
2015-11-18 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -11,15 +11,15 @@
#include "CpuArch.h"
#define MY_ALLOC(T, p, size, alloc) { \
if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = 0; else MY_ALLOC(T, p, size, alloc) }
#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
#define MY_ALLOC_AND_CPY(to, size, from, alloc) \
{ MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); }
#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \
{ if ((size) == 0) p = 0; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } }
{ if ((size) == 0) p = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } }
#define k7zMajorVersion 0
@@ -58,26 +58,14 @@ enum EIdEnum
const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
/*
static int SzFolder_FindBondForInStream(const CSzFolder *p, UInt32 inStreamIndex)
{
UInt32 i;
for (i = 0; i < p->NumBonds; i++)
if (p->Bonds[i].InIndex == inStreamIndex)
return i;
return -1;
}
*/
#define SzBitUi32s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; }
#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
{
if (num == 0)
{
p->Defs = 0;
p->Vals = 0;
p->Defs = NULL;
p->Vals = NULL;
}
else
{
@@ -89,49 +77,49 @@ static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)
{
IAlloc_Free(alloc, p->Defs); p->Defs = 0;
IAlloc_Free(alloc, p->Vals); p->Vals = 0;
IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
}
#define SzBitUi64s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; }
#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)
{
IAlloc_Free(alloc, p->Defs); p->Defs = 0;
IAlloc_Free(alloc, p->Vals); p->Vals = 0;
IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
}
static void SzAr_Init(CSzAr *p)
{
p->NumPackStreams = 0;
p->NumFolders = 0;
p->PackPositions = 0;
SzBitUi32s_Init(&p->FolderCRCs);
// p->Folders = 0;
p->FoCodersOffsets = 0;
p->FoSizesOffsets = 0;
p->FoStartPackStreamIndex = 0;
p->CodersData = 0;
// p->CoderUnpackSizes = 0;
p->UnpackSizesData = 0;
p->PackPositions = NULL;
SzBitUi32s_Init(&p->FolderCRCs);
p->FoCodersOffsets = NULL;
p->FoStartPackStreamIndex = NULL;
p->FoToCoderUnpackSizes = NULL;
p->FoToMainUnpackSizeIndex = NULL;
p->CoderUnpackSizes = NULL;
p->CodersData = NULL;
}
static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
{
IAlloc_Free(alloc, p->UnpackSizesData);
IAlloc_Free(alloc, p->CodersData);
// IAlloc_Free(alloc, p->CoderUnpackSizes);
IAlloc_Free(alloc, p->PackPositions);
// IAlloc_Free(alloc, p->Folders);
IAlloc_Free(alloc, p->FoCodersOffsets);
IAlloc_Free(alloc, p->FoSizesOffsets);
IAlloc_Free(alloc, p->FoStartPackStreamIndex);
SzBitUi32s_Free(&p->FolderCRCs, alloc);
IAlloc_Free(alloc, p->FoCodersOffsets);
IAlloc_Free(alloc, p->FoStartPackStreamIndex);
IAlloc_Free(alloc, p->FoToCoderUnpackSizes);
IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
IAlloc_Free(alloc, p->CoderUnpackSizes);
IAlloc_Free(alloc, p->CodersData);
SzAr_Init(p);
}
@@ -139,18 +127,19 @@ static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
void SzArEx_Init(CSzArEx *p)
{
SzAr_Init(&p->db);
p->NumFiles = 0;
p->dataPos = 0;
// p->Files = 0;
p->UnpackPositions = 0;
// p->IsEmptyFiles = 0;
p->IsDirs = 0;
// p->FolderStartPackStreamIndex = 0;
// p->PackStreamStartPositions = 0;
p->FolderStartFileIndex = 0;
p->FileIndexToFolderIndexMap = 0;
p->FileNameOffsets = 0;
p->FileNames = 0;
p->UnpackPositions = NULL;
p->IsDirs = NULL;
p->FolderToFile = NULL;
p->FileToFolder = NULL;
p->FileNameOffsets = NULL;
p->FileNames = NULL;
SzBitUi32s_Init(&p->CRCs);
SzBitUi32s_Init(&p->Attribs);
// SzBitUi32s_Init(&p->Parents);
@@ -160,29 +149,27 @@ void SzArEx_Init(CSzArEx *p)
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
{
// IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
// IAlloc_Free(alloc, p->PackStreamStartPositions);
IAlloc_Free(alloc, p->FolderStartFileIndex);
IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
IAlloc_Free(alloc, p->UnpackPositions);
IAlloc_Free(alloc, p->IsDirs);
IAlloc_Free(alloc, p->FolderToFile);
IAlloc_Free(alloc, p->FileToFolder);
IAlloc_Free(alloc, p->FileNameOffsets);
IAlloc_Free(alloc, p->FileNames);
SzBitUi64s_Free(&p->CTime, alloc);
SzBitUi64s_Free(&p->MTime, alloc);
SzBitUi32s_Free(&p->CRCs, alloc);
// SzBitUi32s_Free(&p->Parents, alloc);
SzBitUi32s_Free(&p->Attribs, alloc);
IAlloc_Free(alloc, p->IsDirs);
// IAlloc_Free(alloc, p->IsEmptyFiles);
IAlloc_Free(alloc, p->UnpackPositions);
// IAlloc_Free(alloc, p->Files);
// SzBitUi32s_Free(&p->Parents, alloc);
SzBitUi64s_Free(&p->MTime, alloc);
SzBitUi64s_Free(&p->CTime, alloc);
SzAr_Free(&p->db, alloc);
SzArEx_Init(p);
}
static int TestSignatureCandidate(Byte *testBytes)
static int TestSignatureCandidate(const Byte *testBytes)
{
unsigned i;
for (i = 0; i < k7zSignatureSize; i++)
@@ -191,16 +178,7 @@ static int TestSignatureCandidate(Byte *testBytes)
return 1;
}
#define SzData_Clear(p) { (p)->Data = 0; (p)->Size = 0; }
static SRes SzReadByte(CSzData *sd, Byte *b)
{
if (sd->Size == 0)
return SZ_ERROR_ARCHIVE;
sd->Size--;
*b = *sd->Data++;
return SZ_OK;
}
#define SzData_Clear(p) { (p)->Data = NULL; (p)->Size = 0; }
#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++;
#define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest)
@@ -249,57 +227,6 @@ static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
return SZ_OK;
}
/*
static MY_NO_INLINE const Byte *SzReadNumbers(const Byte *data, const Byte *dataLim, UInt64 *values, UInt32 num)
{
for (; num != 0; num--)
{
Byte firstByte;
Byte mask;
unsigned i;
UInt32 v;
UInt64 value;
if (data == dataLim)
return NULL;
firstByte = *data++;
if ((firstByte & 0x80) == 0)
{
*values++ = firstByte;
continue;
}
if (data == dataLim)
return NULL;
v = *data++;
if ((firstByte & 0x40) == 0)
{
*values++ = (((UInt32)firstByte & 0x3F) << 8) | v;
continue;
}
if (data == dataLim)
return NULL;
value = v | ((UInt32)*data++ << 8);
mask = 0x20;
for (i = 2; i < 8; i++)
{
if ((firstByte & mask) == 0)
{
UInt64 highPart = firstByte & (mask - 1);
value |= (highPart << (8 * i));
break;
}
if (data == dataLim)
return NULL;
value |= ((UInt64)*data++ << (8 * i));
mask >>= 1;
}
*values++ = value;
}
return data;
}
*/
static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value)
{
@@ -336,7 +263,7 @@ static SRes SkipData(CSzData *sd)
return SZ_OK;
}
static SRes WaitId(CSzData *sd, UInt64 id)
static SRes WaitId(CSzData *sd, UInt32 id)
{
for (;;)
{
@@ -384,7 +311,7 @@ static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, I
Byte *v2;
UInt32 numBytes = (numItems + 7) >> 3;
*v = NULL;
RINOK(SzReadByte(sd, &allAreDefined));
SZ_READ_BYTE(allAreDefined);
if (numBytes == 0)
return SZ_OK;
if (allAreDefined == 0)
@@ -438,7 +365,7 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
{
Byte allAreDefined;
UInt32 numDefined = numItems;
RINOK(SzReadByte(sd, &allAreDefined));
SZ_READ_BYTE(allAreDefined);
if (!allAreDefined)
{
size_t numBytes = (numItems + 7) >> 3;
@@ -502,7 +429,7 @@ static SRes SzReadSwitch(CSzData *sd)
#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
{
UInt32 numCoders, i;
UInt32 numInStreams = 0;
@@ -524,7 +451,7 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
unsigned idSize, j;
UInt64 id;
RINOK(SzReadByte(sd, &mainByte));
SZ_READ_BYTE(mainByte);
if ((mainByte & 0xC0) != 0)
return SZ_ERROR_UNSUPPORTED;
@@ -663,16 +590,12 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
}
}
for (i = 0; i < numCoders; i++)
{
RINOK(ReadNumber(sdSizes, f->CodersUnpackSizes + i));
}
f->NumCoders = numCoders;
return SZ_OK;
}
static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
{
CSzData sd;
@@ -703,9 +626,11 @@ static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
return SZ_OK;
}
#define k_Scan_NumCoders_MAX 64
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
static SRes ReadUnpackInfo(CSzAr *p,
CSzData *sd2,
UInt32 numFoldersMax,
@@ -739,8 +664,9 @@ static SRes ReadUnpackInfo(CSzAr *p,
}
MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc);
MY_ALLOC(size_t, p->FoSizesOffsets, (size_t)numFolders + 1, alloc);
MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc);
MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc);
MY_ALLOC(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc);
startBufPtr = sd.Data;
@@ -857,7 +783,8 @@ static SRes ReadUnpackInfo(CSzAr *p,
}
p->FoStartPackStreamIndex[fo] = packStreamIndex;
p->FoSizesOffsets[fo] = (numCoders << 8) | indexOfMainStream;
p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
p->FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
numCodersOutStreams += numCoders;
if (numCodersOutStreams < numCoders)
return SZ_ERROR_UNSUPPORTED;
@@ -871,6 +798,8 @@ static SRes ReadUnpackInfo(CSzAr *p,
}
}
p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
{
size_t dataSize = sd.Data - startBufPtr;
p->FoStartPackStreamIndex[fo] = packStreamIndex;
@@ -887,27 +816,13 @@ static SRes ReadUnpackInfo(CSzAr *p,
RINOK(WaitId(&sd, k7zIdCodersUnpackSize));
// MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
{
size_t dataSize = sd.Size;
/*
UInt32 i;
for (i = 0; i < numCodersOutStreams; i++)
{
RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i));
}
*/
RINOK(SkipNumbers(&sd, numCodersOutStreams));
dataSize -= sd.Size;
MY_ALLOC_ZE_AND_CPY(p->UnpackSizesData, dataSize, sd.Data - dataSize, alloc);
p->UnpackSizesDataSize = dataSize;
/*
const Byte *data = SzReadNumbers(sd.Data, sd.Data + sd.Size, p->CoderUnpackSizes, numCodersOutStreams);
if (data == NULL)
return SZ_ERROR_ARCHIVE;
sd.Size = sd.Data + sd.Size - data;
sd.Data = data;
*/
}
for (;;)
@@ -928,6 +843,13 @@ static SRes ReadUnpackInfo(CSzAr *p,
}
}
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)
{
return p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex] + p->FoToMainUnpackSizeIndex[folderIndex]];
}
typedef struct
{
UInt32 NumTotalSubStreams;
@@ -937,7 +859,6 @@ typedef struct
CSzData sdCRCs;
} CSubStreamInfo;
#define SzUi32IndexMax (((UInt32)1 << 31) - 2)
static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
{
@@ -1064,7 +985,6 @@ static SRes SzReadAndDecodePackedStreams(
UInt64 dataStartPos;
UInt32 fo;
CSubStreamInfo ssi;
CSzData sdCodersUnpSizes;
RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp));
@@ -1072,51 +992,24 @@ static SRes SzReadAndDecodePackedStreams(
if (p->NumFolders == 0)
return SZ_ERROR_ARCHIVE;
sdCodersUnpSizes.Data = p->UnpackSizesData;
sdCodersUnpSizes.Size = p->UnpackSizesDataSize;
for (fo = 0; fo < p->NumFolders; fo++)
Buf_Init(tempBufs + fo);
for (fo = 0; fo < p->NumFolders; fo++)
{
CBuf *tempBuf = tempBufs + fo;
// folder = p->Folders;
// unpackSize = SzAr_GetFolderUnpackSize(p, 0);
UInt32 mix = (UInt32)p->FoSizesOffsets[fo];
UInt32 mainIndex = mix & 0xFF;
UInt32 numOutStreams = mix >> 8;
UInt32 si;
UInt64 unpackSize = 0;
p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
for (si = 0; si < numOutStreams; si++)
{
UInt64 curSize;
RINOK(ReadNumber(&sdCodersUnpSizes, &curSize));
if (si == mainIndex)
{
unpackSize = curSize;
break;
}
}
if (si == numOutStreams)
return SZ_ERROR_FAIL;
UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo);
if ((size_t)unpackSize != unpackSize)
return SZ_ERROR_MEM;
if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))
return SZ_ERROR_MEM;
}
p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
for (fo = 0; fo < p->NumFolders; fo++)
{
const CBuf *tempBuf = tempBufs + fo;
RINOK(LookInStream_SeekTo(inStream, dataStartPos));
RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp));
if (SzBitWithVals_Check(&p->FolderCRCs, fo))
if (CrcCalc(tempBuf->data, tempBuf->size) != p->FolderCRCs.Vals[fo])
return SZ_ERROR_CRC;
}
return SZ_OK;
@@ -1164,7 +1057,7 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));
RINOK(SzReadByte(sd2, &external));
SZ_READ_BYTE_SD(sd2, external);
if (external == 0)
sd = *sd2;
else
@@ -1198,14 +1091,13 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
return SZ_OK;
}
#define NUM_ADDITIONAL_STREAMS_MAX 8
static SRes SzReadHeader2(
CSzArEx *p, /* allocMain */
CSzData *sd,
// Byte **emptyStreamVector, /* allocTemp */
// Byte **emptyFileVector, /* allocTemp */
// Byte **lwtVector, /* allocTemp */
ILookInStream *inStream,
CBuf *tempBufs, UInt32 *numTempBufs,
ISzAlloc *allocMain,
@@ -1216,8 +1108,8 @@ static SRes SzReadHeader2(
UInt32 numFiles = 0;
UInt32 numEmptyStreams = 0;
CSubStreamInfo ssi;
const Byte *emptyStreams = 0;
const Byte *emptyFiles = 0;
const Byte *emptyStreams = NULL;
const Byte *emptyFiles = NULL;
SzData_Clear(&ssi.sdSizes);
SzData_Clear(&ssi.sdCRCs);
@@ -1241,22 +1133,19 @@ static SRes SzReadHeader2(
RINOK(ReadID(sd, &type));
}
// if (type == k7zIdAdditionalStreamsInfo) return SZ_ERROR_UNSUPPORTED;
if (type == k7zIdAdditionalStreamsInfo)
{
CSzAr tempAr;
SRes res;
UInt32 numTempFolders;
SzAr_Init(&tempAr);
res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX,
p->startPosAfterHeader, &tempAr, allocTemp);
numTempFolders = tempAr.NumFolders;
*numTempBufs = tempAr.NumFolders;
SzAr_Free(&tempAr, allocTemp);
if (res != SZ_OK)
return res;
*numTempBufs = numTempFolders;
RINOK(ReadID(sd, &type));
}
@@ -1270,9 +1159,9 @@ static SRes SzReadHeader2(
if (type == k7zIdEnd)
{
// *sd2 = sd;
return SZ_OK;
}
if (type != k7zIdFilesInfo)
return SZ_ERROR_ARCHIVE;
@@ -1333,6 +1222,7 @@ static SRes SzReadHeader2(
{
RINOK(RememberBitVector(sd, numFiles, &emptyStreams));
numEmptyStreams = CountDefinedBits(emptyStreams, numFiles);
emptyFiles = NULL;
break;
}
case k7zIdEmptyFile:
@@ -1402,21 +1292,17 @@ static SRes SzReadHeader2(
UInt32 remSubStreams = 0;
UInt32 numSubStreams = 0;
UInt64 unpackPos = 0;
const Byte *digestsDefs = 0;
const Byte *digestsVals = 0;
const Byte *digestsDefs = NULL;
const Byte *digestsVals = NULL;
UInt32 digestsValsIndex = 0;
UInt32 digestIndex;
Byte allDigestsDefined = 0;
Byte isDirMask = 0;
Byte crcMask = 0;
Byte mask = 0x80;
CSzData sdCodersUnpSizes;
sdCodersUnpSizes.Data = p->db.UnpackSizesData;
sdCodersUnpSizes.Size = p->db.UnpackSizesDataSize;
MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders + 1, allocMain);
MY_ALLOC_ZE(UInt32, p->FileIndexToFolderIndexMap, p->NumFiles, allocMain);
MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain);
MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain);
MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain);
MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);
@@ -1424,7 +1310,7 @@ static SRes SzReadHeader2(
if (ssi.sdCRCs.Size != 0)
{
RINOK(SzReadByte(&ssi.sdCRCs, &allDigestsDefined));
SZ_READ_BYTE_SD(&ssi.sdCRCs, allDigestsDefined);
if (allDigestsDefined)
digestsVals = ssi.sdCRCs.Data;
else
@@ -1454,12 +1340,17 @@ static SRes SzReadHeader2(
if (emptyStreams && SzBitArray_Check(emptyStreams, i))
{
if (!emptyFiles || !SzBitArray_Check(emptyFiles, emptyFileIndex))
if (emptyFiles)
{
if (!SzBitArray_Check(emptyFiles, emptyFileIndex))
isDirMask |= mask;
emptyFileIndex++;
}
else
isDirMask |= mask;
if (remSubStreams == 0)
{
p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
p->FileToFolder[i] = (UInt32)-1;
continue;
}
}
@@ -1470,7 +1361,7 @@ static SRes SzReadHeader2(
{
if (folderIndex >= p->db.NumFolders)
return SZ_ERROR_ARCHIVE;
p->FolderStartFileIndex[folderIndex] = i;
p->FolderToFile[folderIndex] = i;
numSubStreams = 1;
if (ssi.sdNumSubStreams.Data)
{
@@ -1479,45 +1370,31 @@ static SRes SzReadHeader2(
remSubStreams = numSubStreams;
if (numSubStreams != 0)
break;
p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData;
{
UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
unpackPos += folderUnpackSize;
if (unpackPos < folderUnpackSize)
return SZ_ERROR_ARCHIVE;
}
folderIndex++;
}
}
p->FileIndexToFolderIndexMap[i] = folderIndex;
p->FileToFolder[i] = folderIndex;
if (emptyStreams && SzBitArray_Check(emptyStreams, i))
continue;
if (--remSubStreams == 0)
{
UInt64 folderUnpackSize = 0;
UInt64 startFolderUnpackPos;
{
UInt32 mix = (UInt32)p->db.FoSizesOffsets[folderIndex];
UInt32 mainIndex = mix & 0xFF;
UInt32 numOutStreams = mix >> 8;
UInt32 si;
p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData;
for (si = 0; si < numOutStreams; si++)
{
UInt64 curSize;
RINOK(ReadNumber(&sdCodersUnpSizes, &curSize));
if (si == mainIndex)
{
folderUnpackSize = curSize;
break;
}
}
if (si == numOutStreams)
return SZ_ERROR_FAIL;
}
// UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
startFolderUnpackPos = p->UnpackPositions[p->FolderStartFileIndex[folderIndex]];
UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]];
if (folderUnpackSize < unpackPos - startFolderUnpackPos)
return SZ_ERROR_ARCHIVE;
unpackPos = startFolderUnpackPos + folderUnpackSize;
if (unpackPos < folderUnpackSize)
return SZ_ERROR_ARCHIVE;
if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i))
{
@@ -1557,12 +1434,39 @@ static SRes SzReadHeader2(
}
p->UnpackPositions[i] = unpackPos;
p->FolderStartFileIndex[folderIndex] = i;
p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData;
if (remSubStreams != 0)
return SZ_ERROR_ARCHIVE;
for (;;)
{
p->FolderToFile[folderIndex] = i;
if (folderIndex >= p->db.NumFolders)
break;
if (!ssi.sdNumSubStreams.Data)
return SZ_ERROR_ARCHIVE;
RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));
if (numSubStreams != 0)
return SZ_ERROR_ARCHIVE;
/*
{
UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
unpackPos += folderUnpackSize;
if (unpackPos < folderUnpackSize)
return SZ_ERROR_ARCHIVE;
}
*/
folderIndex++;
}
if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)
return SZ_ERROR_ARCHIVE;
}
return SZ_OK;
}
static SRes SzReadHeader(
CSzArEx *p,
CSzData *sd,
@@ -1570,9 +1474,6 @@ static SRes SzReadHeader(
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
// Byte *emptyStreamVector = 0;
// Byte *emptyFileVector = 0;
// Byte *lwtVector = 0;
UInt32 i;
UInt32 numTempBufs = 0;
SRes res;
@@ -1580,55 +1481,22 @@ static SRes SzReadHeader(
for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
Buf_Init(tempBufs + i);
// SzBitUi32s_Init(&digests);
res = SzReadHeader2(p, sd,
// &emptyStreamVector,
// &emptyFileVector,
// &lwtVector,
inStream,
res = SzReadHeader2(p, sd, inStream,
tempBufs, &numTempBufs,
allocMain, allocTemp
);
allocMain, allocTemp);
for (i = 0; i < numTempBufs; i++)
for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
Buf_Free(tempBufs + i, allocTemp);
// IAlloc_Free(allocTemp, emptyStreamVector);
// IAlloc_Free(allocTemp, emptyFileVector);
// IAlloc_Free(allocTemp, lwtVector);
RINOK(res);
{
if (sd->Size != 0)
return SZ_ERROR_FAIL;
}
return res;
}
/*
static UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)
{
const CSzFolder2 *f = p->Folders + folderIndex;
// return p->CoderUnpackSizes[f->StartCoderUnpackSizesIndex + f->IndexOfMainOutStream];
UInt32 si;
CSzData sdCodersUnpSizes;
sdCodersUnpSizes.Data = p->UnpackSizesData + f->UnpackSizeDataOffset;
sdCodersUnpSizes.Size = p->UnpackSizesDataSize - f->UnpackSizeDataOffset;
for (si = 0; si < numOutStreams; si++)
{
UInt64 curSize;
ReadNumber(&sdCodersUnpSizes, &curSize);
if (si == mainIndex)
return curSize;
}
return 0;
}
*/
static SRes SzArEx_Open2(
CSzArEx *p,
ILookInStream *inStream,
@@ -1686,6 +1554,7 @@ static SRes SzArEx_Open2(
return SZ_ERROR_MEM;
res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT);
if (res == SZ_OK)
{
res = SZ_ERROR_ARCHIVE;
@@ -1695,7 +1564,9 @@ static SRes SzArEx_Open2(
UInt64 type;
sd.Data = buf.data;
sd.Size = buf.size;
res = ReadID(&sd, &type);
if (res == SZ_OK && type == k7zIdEncodedHeader)
{
CSzAr tempAr;
@@ -1720,6 +1591,7 @@ static SRes SzArEx_Open2(
res = ReadID(&sd, &type);
}
}
if (res == SZ_OK)
{
if (type == k7zIdHeader)
@@ -1743,11 +1615,11 @@ static SRes SzArEx_Open2(
}
}
}
Buf_Free(&buf, allocTemp);
return res;
}
// #include <stdio.h>
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAlloc *allocTemp)
@@ -1755,10 +1627,10 @@ SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
if (res != SZ_OK)
SzArEx_Free(p, allocMain);
// printf ("\nrrr=%d\n", rrr);
return res;
}
SRes SzArEx_Extract(
const CSzArEx *p,
ILookInStream *inStream,
@@ -1771,34 +1643,36 @@ SRes SzArEx_Extract(
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
UInt32 folderIndex = p->FileToFolder[fileIndex];
SRes res = SZ_OK;
*offset = 0;
*outSizeProcessed = 0;
if (folderIndex == (UInt32)-1)
{
IAlloc_Free(allocMain, *tempBuf);
*blockIndex = folderIndex;
*tempBuf = 0;
*tempBuf = NULL;
*outBufferSize = 0;
return SZ_OK;
}
if (*tempBuf == 0 || *blockIndex != folderIndex)
if (*tempBuf == NULL || *blockIndex != folderIndex)
{
// UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
/*
UInt64 unpackSizeSpec =
p->UnpackPositions[p->FolderStartFileIndex[folderIndex + 1]] -
p->UnpackPositions[p->FolderStartFileIndex[folderIndex]];
p->UnpackPositions[p->FolderToFile[folderIndex + 1]] -
p->UnpackPositions[p->FolderToFile[folderIndex]];
*/
size_t unpackSize = (size_t)unpackSizeSpec;
if (unpackSize != unpackSizeSpec)
return SZ_ERROR_MEM;
*blockIndex = folderIndex;
IAlloc_Free(allocMain, *tempBuf);
*tempBuf = 0;
// RINOK(LookInStream_SeekTo(inStream, startOffset));
*tempBuf = NULL;
if (res == SZ_OK)
{
@@ -1806,36 +1680,30 @@ SRes SzArEx_Extract(
if (unpackSize != 0)
{
*tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
if (*tempBuf == 0)
if (*tempBuf == NULL)
res = SZ_ERROR_MEM;
}
if (res == SZ_OK)
{
res = SzAr_DecodeFolder(&p->db, folderIndex,
inStream,
p->dataPos,
*tempBuf, unpackSize, allocTemp);
if (res == SZ_OK)
{
if (SzBitWithVals_Check(&p->db.FolderCRCs, folderIndex))
{
if (CrcCalc(*tempBuf, unpackSize) != p->db.FolderCRCs.Vals[folderIndex])
res = SZ_ERROR_CRC;
}
}
inStream, p->dataPos, *tempBuf, unpackSize, allocTemp);
}
}
}
if (res == SZ_OK)
{
UInt64 unpackPos = p->UnpackPositions[fileIndex];
*offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderStartFileIndex[folderIndex]]);
*offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
*outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);
if (*offset + *outSizeProcessed > *outBufferSize)
return SZ_ERROR_FAIL;
if (SzBitWithVals_Check(&p->CRCs, fileIndex) && CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex])
if (SzBitWithVals_Check(&p->CRCs, fileIndex))
if (CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex])
res = SZ_ERROR_CRC;
}
return res;
}

View File

@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder
2015-08-01 : Igor Pavlov : Public domain */
2015-11-18 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -8,6 +8,7 @@
/* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h"
#include "7zCrc.h"
#include "Bcj2.h"
#include "Bra.h"
@@ -160,14 +161,23 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
inSize -= inProcessed;
if (res != SZ_OK)
break;
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
if (state.dicBufSize != outSize || lookahead != 0 ||
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
if (outSize != state.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
break;
if (inProcessed == 0 && dicPos == state.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
@@ -213,13 +223,20 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
inSize -= inProcessed;
if (res != SZ_OK)
break;
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
(status != LZMA_STATUS_FINISHED_WITH_MARK))
if (outSize != state.decoder.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
if (inProcessed == 0 && dicPos == state.decoder.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
@@ -537,33 +554,38 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
SRes res;
CSzFolder folder;
CSzData sd;
CSzData sdSizes;
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data;
sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
sdSizes.Data = p->UnpackSizesData + p->FoSizesOffsets[folderIndex];
sdSizes.Size =
p->FoSizesOffsets[folderIndex + 1] -
p->FoSizesOffsets[folderIndex];
res = SzGetNextFolderItem(&folder, &sd, &sdSizes);
res = SzGetNextFolderItem(&folder, &sd);
if (res != SZ_OK)
return res;
if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.UnpackStream])
if (sd.Size != 0
|| folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
|| outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
return SZ_ERROR_FAIL;
{
unsigned i;
Byte *tempBuf[3] = { 0, 0, 0};
res = SzFolder_Decode2(&folder, data, folder.CodersUnpackSizes,
res = SzFolder_Decode2(&folder, data,
&p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]);
if (res == SZ_OK)
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
res = SZ_ERROR_CRC;
return res;
}
}

View File

@@ -1,9 +1,9 @@
#define MY_VER_MAJOR 15
#define MY_VER_MINOR 11
#define MY_VER_MINOR 14
#define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "15.11"
#define MY_VERSION "15.11 beta"
#define MY_DATE "2015-11-14"
#define MY_VERSION_NUMBERS "15.14"
#define MY_VERSION "15.14"
#define MY_DATE "2015-12-31"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
2015-10-31: Igor Pavlov : Public domain */
2015-12-01: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -78,7 +78,9 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
|| defined(__MIPSEB) \
|| defined(_MIPSEB) \
|| defined(__m68k__) \
|| defined(__s390__) \
|| defined(__s390x__) \
|| defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE
#endif

View File

@@ -73,4 +73,3 @@ Ppmd7Dec.o: ../../Ppmd7Dec.c
clean:
-$(RM) $(PROG) $(OBJS)

View File

@@ -1,5 +1,5 @@
/* 7zipInstall.c - 7-Zip Installer
2015-11-08 : Igor Pavlov : Public domain */
2015-12-09 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -571,6 +571,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
#endif
break;
}
default: return FALSE;
}
break;
@@ -1011,7 +1013,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
BOOL bRet;
MSG msg;
while ((bRet = GetMessage(&msg, g_HWND, 0, 0)) != 0)
// we need messages for all thread windows (including EDITTEXT window in dialog)
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
return retCode;

View File

@@ -1,5 +1,5 @@
/* 7zipUninstall.c - 7-Zip Uninstaller
2015-11-08 : Igor Pavlov : Public domain */
2015-12-26 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -542,7 +542,7 @@ static BOOL RemoveDir()
#define k_Lang L"Lang"
// NUM_LANG_TXT_FILES files are placed before en.ttt
#define NUM_LANG_TXT_FILES 86
#define NUM_LANG_TXT_FILES 87
#ifdef _64BIT_INSTALLER
#define NUM_EXTRA_FILES_64BIT 1
@@ -556,7 +556,7 @@ static const char *k_Names =
"af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext"
" fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky"
" lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru"
" sa si sk sl sq sr-spc sr-spl sv ta th tr tt ug uk uz va vi zh-cn zh-tw"
" sa si sk sl sq sr-spc sr-spl sv ta th tr tt ug uk uz va vi yo zh-cn zh-tw"
" en.ttt"
" descript.ion"
" History.txt"
@@ -771,6 +771,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
OnClose();
break;
}
default: return FALSE;
}
break;
@@ -1033,7 +1035,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
BOOL bRet;
MSG msg;
while ((bRet = GetMessage(&msg, g_HWND, 0, 0)) != 0)
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
return retCode;

View File

@@ -567,14 +567,17 @@ static const char *g_Exts =
" iso bin nrg mdf img pdi tar cpio xpi"
" vfd vhd vud vmc vsv"
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
" inl inc idl acf asa"
" h hpp hxx c cpp cxx m mm go swift"
" rc java cs rs pas bas vb cls ctl frm dlg def"
" f77 f f90 f95"
" asm sql manifest dep"
" asm s"
" sql manifest dep"
" mak clw csproj vcproj sln dsp dsw"
" class"
" bat cmd"
" bat cmd bash sh"
" xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
" awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs"
" awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs"
" text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
" sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
" abw afp cwk lwp wpd wps wpt wrf wri"

View File

@@ -572,6 +572,7 @@ public:
HRESULT FlushCorrupted(unsigned folderIndex);
HRESULT Unsupported();
bool NeedMoreWrite() const { return (m_FolderSize > m_PosInFolder); }
UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; }
UInt64 GetPosInFolder() const { return m_PosInFolder; }
};
@@ -781,6 +782,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
realProcessed += size;
if (processedSize)
*processedSize = realProcessed;
m_PosInFolder += size;
return S_OK;
// return E_FAIL;
}
@@ -830,9 +832,7 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
{
UInt64 remain = GetRemain();
if (remain == 0)
if (!NeedMoreWrite())
{
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
@@ -843,16 +843,16 @@ HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
return S_OK;
}
const unsigned kBufSize = (1 << 10);
const unsigned kBufSize = (1 << 12);
Byte buf[kBufSize];
for (unsigned i = 0; i < kBufSize; i++)
buf[i] = 0;
for (;;)
{
UInt64 remain = GetRemain();
if (remain == 0)
if (!NeedMoreWrite())
return S_OK;
UInt64 remain = GetRemain();
UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize);
UInt32 processedSizeLocal = 0;
RINOK(Write2(buf, size, &processedSizeLocal, false));
@@ -937,8 +937,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CRecordVector<bool> extractStatuses;
for (i = 0; i < numItems;)
for (i = 0;;)
{
lps->OutSize = totalUnPacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
if (i >= numItems)
break;
unsigned index = allFilesMode ? i : indices[i];
const CMvItem &mvItem = m_Database.Items[index];
@@ -1003,10 +1010,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
curUnpack = item.GetEndOffset();
}
lps->OutSize = totalUnPacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
@@ -1071,7 +1074,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
bool keepInputBuffer = false;
bool thereWasNotAlignedChunk = false;
for (UInt32 bl = 0; cabFolderOutStream->GetRemain() != 0;)
for (UInt32 bl = 0; cabFolderOutStream->NeedMoreWrite();)
{
if (volIndex >= m_Database.Volumes.Size())
{
@@ -1213,7 +1216,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
}
if (res != S_OK || cabFolderOutStream->GetRemain() != 0)
if (res != S_OK || cabFolderOutStream->NeedMoreWrite())
{
RINOK(cabFolderOutStream->FlushCorrupted(folderIndex2));
}

View File

@@ -67,6 +67,7 @@ void CInArchive::ReadOtherArc(COtherArc &oa)
ReadName(oa.DiskName);
}
struct CSignatureFinder
{
Byte *Buf;
@@ -100,6 +101,7 @@ struct CSignatureFinder
HRESULT Find();
};
HRESULT CSignatureFinder::Find()
{
for (;;)
@@ -156,6 +158,7 @@ HRESULT CSignatureFinder::Find()
}
}
bool CInArcInfo::Parse(const Byte *p)
{
if (Get32(p + 0x0C) != 0 ||
@@ -177,6 +180,7 @@ bool CInArcInfo::Parse(const Byte *p)
return true;
}
HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{
IsArc = false;
@@ -286,7 +290,9 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
if (ai.IsThereNext()) ReadOtherArc(ai.NextArc);
UInt32 i;
db.Folders.ClearAndReserve(ai.NumFolders);
for (i = 0; i < ai.NumFolders; i++)
{
Read(p, 8);
@@ -311,6 +317,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
}
db.Items.ClearAndReserve(ai.NumFiles);
for (i = 0; i < ai.NumFiles; i++)
{
Read(p, 16);
@@ -324,6 +331,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
item.Attributes = Get16(p + 14);
ReadName(item.Name);
if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size())
{
HeaderError = true;
@@ -336,6 +344,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
return S_OK;
}
HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{
try
@@ -370,6 +379,7 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
return MyCompare(p1->ItemIndex, p2->ItemIndex);
}
bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
{
const CMvItem *p1 = &Items[i1];
@@ -384,12 +394,15 @@ bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
&& item1.Name == item2.Name;
}
void CMvDatabaseEx::FillSortAndShrink()
{
Items.Clear();
StartFolderOfVol.Clear();
FolderStartFileIndex.Clear();
int offset = 0;
FOR_VECTOR (v, Volumes)
{
const CDatabaseEx &db = Volumes[v];
@@ -422,11 +435,12 @@ void CMvDatabaseEx::FillSortAndShrink()
FOR_VECTOR (i, Items)
{
int folderIndex = GetFolderIndex(&Items[i]);
if (folderIndex >= (int)FolderStartFileIndex.Size())
while (folderIndex >= (int)FolderStartFileIndex.Size())
FolderStartFileIndex.Add(i);
}
}
bool CMvDatabaseEx::Check()
{
for (unsigned v = 1; v < Volumes.Size(); v++)
@@ -444,9 +458,11 @@ bool CMvDatabaseEx::Check()
return false;
}
}
UInt32 beginPos = 0;
UInt64 endPos = 0;
int prevFolder = -2;
FOR_VECTOR (i, Items)
{
const CMvItem &mvItem = Items[i];
@@ -456,15 +472,19 @@ bool CMvDatabaseEx::Check()
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDir())
continue;
int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex != prevFolder)
prevFolder = folderIndex;
else if (item.Offset < endPos &&
(item.Offset != beginPos || item.GetEndOffset() != endPos))
return false;
beginPos = item.Offset;
endPos = item.GetEndOffset();
}
return true;
}

View File

@@ -25,6 +25,7 @@ struct COtherArc
}
};
struct CArchInfo
{
Byte VersionMinor; // cabinet file format version, minor
@@ -65,6 +66,7 @@ struct CArchInfo
}
};
struct CInArcInfo: public CArchInfo
{
UInt32 Size; // size of this cabinet file in bytes
@@ -105,17 +107,20 @@ struct CDatabase
}
};
struct CDatabaseEx: public CDatabase
{
CMyComPtr<IInStream> Stream;
};
struct CMvItem
{
unsigned VolumeIndex;
unsigned ItemIndex;
};
class CMvDatabaseEx
{
bool AreItemsEqual(unsigned i1, unsigned i2);

View File

@@ -571,6 +571,7 @@ HRESULT CDatabase::Open(IInStream *inStream)
RINOK(AddNode(-1, root.SonDid));
unsigned numCabs = 0;
FOR_VECTOR (i, Refs)
{
const CItem &item = Items[Refs[i].Did];
@@ -578,16 +579,20 @@ HRESULT CDatabase::Open(IInStream *inStream)
continue;
bool isMsiName;
UString msiName = ConvertName(item.Name, isMsiName);
if (isMsiName)
if (isMsiName && !msiName.IsEmpty())
{
bool isThereExt = (msiName.Find(L'.') >= 0);
bool isMsiSpec = (msiName[0] == k_Msi_SpecChar);
if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")
|| msiName.Len() >= 3 && msiName[0] != k_Msi_SpecChar && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe"))
|| !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")
|| !isMsiSpec && !isThereExt)
{
numCabs++;
MainSubfile = i;
}
}
}
if (numCabs > 1)
MainSubfile = -1;

View File

@@ -1118,7 +1118,7 @@ HRESULT CHandler::SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, siz
{
if (block == 0 || block >= _h.NumBlocks)
return S_FALSE;
if (((size + (1 << _h.BlockBits) + 1) >> _h.BlockBits) > _h.NumBlocks - block)
if (((size + ((size_t)1 << _h.BlockBits) - 1) >> _h.BlockBits) > _h.NumBlocks - block)
return S_FALSE;
RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL));
_totalRead += size;
@@ -1167,6 +1167,9 @@ HRESULT CHandler::Open2(IInStream *inStream)
RINOK(_openCallback->SetTotal(NULL, &_phySize));
}
UInt64 fileSize = 0;
RINOK(inStream->Seek(0, STREAM_SEEK_END, &fileSize));
CRecordVector<CGroupDescriptor> groups;
{
@@ -1214,6 +1217,21 @@ HRESULT CHandler::Open2(IInStream *inStream)
if (_h.NumInodes < _h.NumFreeInodes)
return S_FALSE;
UInt32 numNodes = _h.InodesPerGroup;
if (numNodes > _h.NumInodes)
numNodes = _h.NumInodes;
size_t nodesDataSize = (size_t)numNodes * _h.InodeSize;
if (nodesDataSize / _h.InodeSize != numNodes)
return S_FALSE;
// that code to reduce false detecting cases
if (nodesDataSize > fileSize)
{
if (numNodes > (1 << 24))
return S_FALSE;
}
UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1;
// numReserveInodes = _h.NumInodes + 1;
if (numReserveInodes != 0)
@@ -1222,13 +1240,6 @@ HRESULT CHandler::Open2(IInStream *inStream)
_refs.Reserve(numReserveInodes);
}
UInt32 numNodes = _h.InodesPerGroup;
if (numNodes > _h.NumInodes)
numNodes = _h.NumInodes;
size_t nodesDataSize = numNodes * _h.InodeSize;
if (nodesDataSize / _h.InodeSize != numNodes)
return S_FALSE;
CByteBuffer nodesData;
nodesData.Alloc(nodesDataSize);

View File

@@ -160,10 +160,13 @@ bool CHeader::Parse(const Byte *p)
if (NumFats < 1 || NumFats > 4)
return false;
// we also support images that contain 0 in offset field.
bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0));
UInt16 numRootDirEntries = Get16(p + 17);
if (numRootDirEntries == 0)
{
if (codeOffset < 90)
if (codeOffset < 90 && !isOkOffset)
return false;
NumFatBits = 32;
NumRootDirSectors = 0;
@@ -171,7 +174,7 @@ bool CHeader::Parse(const Byte *p)
else
{
// Some FAT12s don't contain VolFields
if (codeOffset < 62 - 24)
if (codeOffset < 62 - 24 && !isOkOffset)
return false;
NumFatBits = 0;
UInt32 mask = (1 << (SectorSizeLog - 5)) - 1;

View File

@@ -170,7 +170,7 @@ struct CBootInitialEntry
// Partition Table found in the boot image.
UInt16 SectorCount; // This is the number of virtual/emulated sectors the system
// will store at Load Segment during the initial boot procedure.
UInt32 LoadRBA; // This is the start address of the virtual disk. CD<EFBFBD>s use
UInt32 LoadRBA; // This is the start address of the virtual disk. CDs use
// Relative/Logical block addressing.
Byte VendorSpec[20];

View File

@@ -347,18 +347,24 @@ struct CSection
CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {}
// const UInt32 GetSize() const { return PSize; }
const UInt32 GetSize() const { return MyMin(PSize, VSize); }
void UpdateTotalSize(UInt32 &totalSize) const
{
UInt32 t = Pa + PSize;
if (totalSize < t)
totalSize = t;
}
void Parse(const Byte *p);
int Compare(const CSection &s) const
{
RINOZ(MyCompare(Pa, s.Pa));
return MyCompare(PSize, s.PSize);
UInt32 size1 = GetSize();
UInt32 size2 = s.GetSize();
return MyCompare(size1, size2);
}
};
@@ -1039,7 +1045,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch (propID)
{
case kpidPath: prop = MultiByteToUnicodeString(item.Name); break;
case kpidSize: prop = (UInt64)MyMin(item.PSize, item.VSize); break;
case kpidSize: prop = (UInt64)item.GetSize(); break;
case kpidPackSize: prop = (UInt64)item.PSize; break;
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
case kpidOffset: prop = item.Pa; break;
@@ -1883,14 +1889,17 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
}
f.CloseBlock(2);
}
f.CloseBlock(0);
return true;
}
HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback)
{
const CSection &sect = _sections[sectionIndex];
size_t fileSize = sect.PSize; // Maybe we need sect.VSize here !!!
const size_t fileSize = sect.GetSize();
if (fileSize > kFileSizeMax)
return S_FALSE;
{
@@ -2031,8 +2040,8 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
{
UInt32 mask = (1 << numBits) - 1;
size_t end = ((maxOffset + mask) & ~mask);
// 9.29: we use only PSize. PSize can be larger than VSize
if (/* end < sect.VSize && */ end <= sect.PSize)
if (/* end < sect.VSize && */ end <= sect.GetSize())
{
CSection sect2;
sect2.Flags = 0;
@@ -2050,7 +2059,8 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
// 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX
// the code for .rsrc_2 is commented.
sect2.PSize = sect.PSize - (UInt32)maxOffset;
sect2.PSize = sect.GetSize() - (UInt32)maxOffset;
if (sect2.PSize != 0)
{
sect2.VSize = sect2.PSize;
@@ -2463,7 +2473,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else if (mixItem.ResourceIndex >= 0)
size = _items[mixItem.ResourceIndex].GetSize();
else
size = _sections[mixItem.SectionIndex].PSize;
size = _sections[mixItem.SectionIndex].GetSize();
totalSize += size;
}
extractCallback->SetTotal(totalSize);
@@ -2539,7 +2549,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
else
{
currentItemSize = sect.PSize;
currentItemSize = sect.GetSize();
if (!testMode && !outStream)
continue;

View File

@@ -1,5 +1,5 @@
/* PpmdHandler.c -- PPMd format handler
2010-03-10 : Igor Pavlov : Public domain
/* PpmdHandler.cpp -- PPMd format handler
2015-11-30 : Igor Pavlov : Public domain
This code is based on:
PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -349,6 +349,7 @@ struct CPpmdCpp
}
};
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
@@ -386,13 +387,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CPpmdCpp ppmd(_item.Ver);
if (!ppmd.Alloc(_item.MemInMB))
return E_OUTOFMEMORY;
Int32 opRes = NExtract::NOperationResult::kUnsupportedMethod;
if (_item.IsSupported())
{
opRes = NExtract::NOperationResult::kDataError;
ppmd.Init(_item.Order, _item.Restor);
inBuf.Init();
UInt64 outSize = 0;
if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK)
for (;;)
{
@@ -431,6 +436,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
RINOK(WriteStream(realOutStream, outBuf.Buf, i));
}
if (inBuf.Extra)
{
opRes = NExtract::NOperationResult::kUnexpectedEnd;
break;
}
if (sym < 0)
{
if (sym == -1 && ppmd.IsFinishedOK())
@@ -438,12 +450,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
break;
}
}
RINOK(inBuf.Res);
}
realOutStream.Release();
return extractCallback->SetOperationResult(opRes);
}
static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 };
REGISTER_ARC_I(

View File

@@ -4,6 +4,7 @@
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/TimeUtils.h"
@@ -241,12 +242,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
const CItemEx &item = m_Items[index];
const CExtraBlock &extra = item.GetMainExtra();
switch (propID)
{
case kpidPath:
{
UString res;
item.GetUnicodeString(item.Name, res, _forceCodePage, _specifiedCodePage);
item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage);
NItemName::ConvertToOSName2(res);
prop = res;
break;
@@ -261,9 +264,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
FILETIME ft;
UInt32 unixTime;
UInt32 type;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
type = NFileTimeType::kWindows;
else if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
else if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
type = NFileTimeType::kUnix;
else
type = NFileTimeType::kDOS;
@@ -274,7 +277,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCTime:
{
FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
prop = ft;
break;
}
@@ -282,7 +285,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidATime:
{
FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
prop = ft;
break;
}
@@ -291,10 +294,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
FILETIME utc;
bool defined = true;
if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
{
UInt32 unixTime = 0;
if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
NTime::UnixTimeToFileTime(unixTime, utc);
else
{
@@ -328,7 +331,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (item.Comment.Size() != 0)
{
UString res;
item.GetUnicodeString(BytesToString(item.Comment), res, _forceCodePage, _specifiedCodePage);
item.GetUnicodeString(res, BytesToString(item.Comment), true, _forceCodePage, _specifiedCodePage);
prop = res;
}
break;
@@ -347,7 +350,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
m += kMethod_AES;
CWzAesExtra aesField;
if (item.CentralExtra.GetWzAes(aesField))
if (extra.GetWzAes(aesField))
{
char s[16];
s[0] = '-';
@@ -360,7 +363,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
CStrongCryptoExtra f;
f.AlgId = 0;
if (item.CentralExtra.GetStrongCrypto(f))
if (extra.GetStrongCrypto(f))
{
const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId);
if (s)
@@ -373,6 +376,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
ConvertUInt32ToString(f.AlgId, temp + 1);
m += temp;
}
if (f.CertificateIsUsed())
m += "-Cert";
}
else
m += kMethod_StrongCrypto;
@@ -425,6 +430,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = (UInt32)item.ExtractVersion.Version;
break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
@@ -615,7 +621,7 @@ HRESULT CZipDecoder::Decode(
if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES)
{
CWzAesExtra aesField;
if (item.CentralExtra.GetWzAes(aesField))
if (item.GetMainExtra().GetWzAes(aesField))
{
wzAesMode = true;
needCRC = aesField.NeedCrc();
@@ -651,7 +657,7 @@ HRESULT CZipDecoder::Decode(
if (wzAesMode)
{
CWzAesExtra aesField;
if (!item.CentralExtra.GetWzAes(aesField))
if (!item.GetMainExtra().GetWzAes(aesField))
return S_OK;
id = aesField.Method;
if (!_wzAesDecoder)

View File

@@ -84,6 +84,8 @@ namespace NFileHeader
kNTFS = 0x0A,
kStrongEncrypt = 0x17,
kUnixTime = 0x5455,
kIzUnicodeComment = 0x6375,
kIzUnicodeName = 0x7075,
kWzAES = 0x9901
};
}

View File

@@ -203,6 +203,7 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
const Byte *p2 = p + kLocalHeaderSize;
for (size_t i = 0; i < rem; i++)
if (p2[i] == 0)
if (i != nameSize - 1)
return k_IsArc_Res_NO;
}

View File

@@ -3,8 +3,10 @@
#include "StdAfx.h"
#include "../../../../C/CpuArch.h"
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h"
#include "../Common/ItemNameUtils.h"
@@ -80,6 +82,30 @@ bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res
return false;
}
bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kNTFS)
return sb.ExtractNtfsTime(index, ft);
}
return false;
}
bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
bool CLocalItem::IsDir() const
{
return NItemName::HasTailSlash(Name, GetCodePage());
@@ -89,12 +115,29 @@ bool CItem::IsDir() const
{
if (NItemName::HasTailSlash(Name, GetCodePage()))
return true;
Byte hostOS = GetHostOS();
if (Size == 0 && PackSize == 0 && !Name.IsEmpty() && Name.Back() == '\\')
{
// do we need to use CharPrevExA?
// .NET Framework 4.5 : System.IO.Compression::CreateFromDirectory() probably writes backslashes to headers?
// so we support that case
switch (hostOS)
{
case NHostOS::kFAT:
case NHostOS::kNTFS:
case NHostOS::kHPFS:
case NHostOS::kVFAT:
return true;
}
}
if (!FromCentral)
return false;
UInt16 highAttrib = (UInt16)((ExternalAttrib >> 16 ) & 0xFFFF);
Byte hostOS = GetHostOS();
switch (hostOS)
{
case NHostOS::kAMIGA:
@@ -158,4 +201,53 @@ bool CItem::GetPosixAttrib(UInt32 &attrib) const
return false;
}
void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const
{
bool isUtf8 = IsUtf8();
bool ignore_Utf8_Errors = true;
if (!isUtf8)
{
{
const unsigned id = isComment ?
NFileHeader::NExtraID::kIzUnicodeComment:
NFileHeader::NExtraID::kIzUnicodeName;
const CObjectVector<CExtraSubBlock> &subBlocks = GetMainExtra().SubBlocks;
FOR_VECTOR (i, subBlocks)
{
const CExtraSubBlock &sb = subBlocks[i];
if (sb.ID == id)
{
AString utf;
if (sb.ExtractIzUnicode(CrcCalc(s, s.Len()), utf))
if (ConvertUTF8ToUnicode(utf, res))
return;
break;
}
}
}
if (useSpecifiedCodePage)
isUtf8 = (codePage == CP_UTF8);
#ifdef _WIN32
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
{
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
We try to get name as UTF-8.
Do we need to do it in POSIX version also? */
isUtf8 = true;
ignore_Utf8_Errors = false;
}
#endif
}
if (isUtf8)
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
return;
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
}}

View File

@@ -7,7 +7,6 @@
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/UTFConvert.h"
#include "ZipHeader.h"
@@ -28,6 +27,23 @@ struct CExtraSubBlock
bool ExtractNtfsTime(unsigned index, FILETIME &ft) const;
bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
bool ExtractIzUnicode(UInt32 crc, AString &name) const
{
unsigned size = (unsigned)Data.Size();
if (size < 1 + 4)
return false;
const Byte *p = (const Byte *)Data;
if (p[0] > 1)
return false;
if (crc != GetUi32(p + 1))
return false;
size -= 5;
name.SetFrom_CalcLen((const char *)p + 5, size);
if (size != name.Len())
return false;
return CheckUTF8(name, false);
}
};
const unsigned k_WzAesExtra_Size = 7;
@@ -109,6 +125,8 @@ struct CStrongCryptoExtra
Flags = GetUi16(p + 6);
return (Format == 2);
}
bool CertificateIsUsed() const { return (Flags > 0x0001); }
};
struct CExtraBlock
@@ -155,27 +173,8 @@ struct CExtraBlock
}
*/
bool GetNtfsTime(unsigned index, FILETIME &ft) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kNTFS)
return sb.ExtractNtfsTime(index, ft);
}
return false;
}
bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
bool GetNtfsTime(unsigned index, FILETIME &ft) const;
bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
void RemoveUnknownSubBlocks()
{
@@ -272,45 +271,22 @@ public:
MadeByVersion.HostOS = 0;
}
const CExtraBlock &GetMainExtra() const { return *(FromCentral ? &CentralExtra : &LocalExtra); }
bool IsDir() const;
UInt32 GetWinAttrib() const;
bool GetPosixAttrib(UInt32 &attrib) const;
Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; }
void GetUnicodeString(const AString &s, UString &res, bool useSpecifiedCodePage, UINT codePage) const
{
bool isUtf8 = IsUtf8();
bool ignore_Utf8_Errors = true;
#ifdef _WIN32
if (!isUtf8)
{
if (useSpecifiedCodePage)
isUtf8 = (codePage == CP_UTF8);
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
{
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
We try to get name as UTF-8.
Do we need to do it in POSIX version also? */
isUtf8 = true;
ignore_Utf8_Errors = false;
}
}
#endif
if (isUtf8)
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
return;
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const;
bool IsThereCrc() const
{
if (Method == NFileHeader::NCompressionMethod::kWzAES)
{
CWzAesExtra aesField;
if (CentralExtra.GetWzAes(aesField))
if (GetMainExtra().GetWzAes(aesField))
return aesField.NeedCrc();
}
return (Crc != 0 || !IsDir());
@@ -320,8 +296,10 @@ public:
{
Byte hostOS = GetHostOS();
return (UINT)((
hostOS == NFileHeader::NHostOS::kFAT ||
hostOS == NFileHeader::NHostOS::kNTFS) ? CP_OEMCP : CP_ACP);
hostOS == NFileHeader::NHostOS::kFAT
|| hostOS == NFileHeader::NHostOS::kNTFS
|| hostOS == NFileHeader::NHostOS::kUnix // do we need it?
) ? CP_OEMCP : CP_ACP);
}
};

View File

@@ -325,14 +325,6 @@ SOURCE=..\..\UI\FileManager\ComboDialog.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\MessagesDialog.cpp
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\MessagesDialog.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp
# End Source File
# Begin Source File

View File

@@ -112,25 +112,87 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
if (algId * 64 + 128 != bitLen)
return E_NOTIMPL;
_key.KeySize = 16 + algId * 8;
if ((flags & 1) == 0)
return E_NOTIMPL;
bool cert = ((flags & 2) != 0);
if ((flags & 0x4000) != 0)
{
// Use 3DES
return E_NOTIMPL;
}
if (cert)
{
return E_NOTIMPL;
}
else
{
if ((flags & 1) == 0)
return E_NOTIMPL;
}
UInt32 rdSize = GetUi16(p + 8);
if ((rdSize & 0xF) != 0 || rdSize + 16 > _remSize)
return E_NOTIMPL;
memmove(p, p + 10, rdSize);
Byte *validData = p + rdSize + 16;
if (GetUi32(validData - 6) != 0) // reserved
return E_NOTIMPL;
UInt32 validSize = GetUi16(validData - 2);
if ((validSize & 0xF) != 0 || 16 + rdSize + validSize != _remSize)
if (rdSize + 16 > _remSize)
return E_NOTIMPL;
/*
if (cert)
{
// how to filter rd, if ((rdSize & 0xF) != 0) ?
/*
if ((rdSize & 0x7) != 0)
return E_NOTIMPL;
}
else
*/
{
if ((rdSize & 0xF) != 0)
return E_NOTIMPL;
}
memmove(p, p + 10, rdSize);
const Byte *p2 = p + rdSize + 10;
UInt32 reserved = GetUi32(p2);
p2 += 4;
/*
if (cert)
{
UInt32 numRecipients = reserved;
if (numRecipients == 0)
return E_NOTIMPL;
{
UInt32 hashAlg = GetUi16(p2);
hashAlg = hashAlg;
UInt32 hashSize = GetUi16(p2 + 2);
hashSize = hashSize;
p2 += 4;
reserved = reserved;
// return E_NOTIMPL;
for (unsigned r = 0; r < numRecipients; r++)
{
UInt32 specSize = GetUi16(p2);
p2 += 2;
p2 += specSize;
}
}
}
else
*/
{
if (reserved != 0)
return E_NOTIMPL;
}
UInt32 validSize = GetUi16(p2);
p2 += 2;
const size_t validOffset = p2 - p;
if ((validSize & 0xF) != 0 || validOffset + validSize != _remSize)
return E_NOTIMPL;
{
RINOK(SetKey(_key.MasterKey, _key.KeySize));
@@ -149,12 +211,14 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
RINOK(SetKey(fileKey, _key.KeySize));
RINOK(SetInitVector(_iv, 16));
Init();
Filter(validData, validSize);
memmove(p, p + validOffset, validSize);
Filter(p, validSize);
if (validSize < 4)
return E_NOTIMPL;
validSize -= 4;
if (GetUi32(validData + validSize) != CrcCalc(validData, validSize))
if (GetUi32(p + validSize) != CrcCalc(p, validSize))
return S_OK;
passwOK = true;
return S_OK;

View File

@@ -917,7 +917,7 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
if (parser[NKey::kAffinity].ThereIs)
{
const UString &s = us2fs(parser[NKey::kAffinity].PostStrings[0]);
const UString &s = parser[NKey::kAffinity].PostStrings[0];
if (!s.IsEmpty())
{
UInt32 v = 0;

View File

@@ -1265,7 +1265,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
CReparseAttr attr;
if (!attr.Parse(data, data.Size()))
{
RINOK(SendMessageError("Internal error for symbolic link file", _item.Path));
RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path)));
// return E_FAIL;
}
else

View File

@@ -2487,7 +2487,7 @@ HRESULT Bench(
#ifdef USE_WIN_FILE
NFile::NIO::CInFile file;
if (!file.Open(property.Value))
if (!file.Open(us2fs(property.Value)))
return E_INVALIDARG;
UInt64 len;
if (!file.GetLength(len))

View File

@@ -39,7 +39,7 @@
#endif
// increase it, if you need to support larger SFX stubs
static const UInt64 kMaxCheckStartPosition = 1 << 22;
static const UInt64 kMaxCheckStartPosition = 1 << 23;
/*
Open:

View File

@@ -42,6 +42,12 @@ static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
}
static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b)
{
b.Val = true;
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
}
namespace NExtract
{
@@ -112,9 +118,8 @@ void CInfo::Load()
OverwriteMode_Force = true;
}
Key_Get_BoolPair(key, kSplitDest, SplitDest);
if (!SplitDest.Def)
SplitDest.Val = true;
Key_Get_BoolPair_true(key, kSplitDest, SplitDest);
Key_Get_BoolPair(key, kElimDup, ElimDup);
// Key_Get_BoolPair(key, kAltStreams, AltStreams);
Key_Get_BoolPair(key, kNtSecur, NtSecurity);
@@ -348,27 +353,45 @@ void CInfo::Load()
static const TCHAR *kCascadedMenu = TEXT("CascadedMenu");
static const TCHAR *kContextMenu = TEXT("ContextMenu");
static const TCHAR *kMenuIcons = TEXT("MenuIcons");
static const TCHAR *kElimDup = TEXT("ElimDupExtract");
void CContextMenuInfo::Save() const
{
CS_LOCK
CKey key;
CreateMainKey(key, kOptionsInfoKeyName);
key.SetValue(kCascadedMenu, Cascaded);
key.SetValue(kMenuIcons, MenuIcons);
Key_Set_BoolPair(key, kCascadedMenu, Cascaded);
Key_Set_BoolPair(key, kMenuIcons, MenuIcons);
Key_Set_BoolPair(key, kElimDup, ElimDup);
if (Flags_Def)
key.SetValue(kContextMenu, Flags);
}
void CContextMenuInfo::Load()
{
MenuIcons = false;
Cascaded = true;
Cascaded.Val = true;
Cascaded.Def = false;
MenuIcons.Val = false;
MenuIcons.Def = false;
ElimDup.Val = true;
ElimDup.Def = false;
Flags = (UInt32)(Int32)-1;
Flags_Def = false;
CS_LOCK
CKey key;
if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS)
return;
key.GetValue_IfOk(kCascadedMenu, Cascaded);
key.GetValue_IfOk(kMenuIcons, MenuIcons);
key.GetValue_IfOk(kContextMenu, Flags);
Key_Get_BoolPair_true(key, kCascadedMenu, Cascaded);
Key_Get_BoolPair_true(key, kElimDup, ElimDup);
Key_Get_BoolPair(key, kMenuIcons, MenuIcons);
Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
}

View File

@@ -111,8 +111,11 @@ namespace NWorkDir
struct CContextMenuInfo
{
bool Cascaded;
bool MenuIcons;
CBoolPair Cascaded;
CBoolPair MenuIcons;
CBoolPair ElimDup;
bool Flags_Def;
UInt32 Flags;
void Save() const;

View File

@@ -33,3 +33,4 @@ UI_COMMON_OBJS = \
$O\UpdatePair.obj \
$O\UpdateProduce.obj \
#

View File

@@ -241,7 +241,7 @@ static const CHashCommand g_HashCommands[] =
static int FindCommand(CZipContextMenu::ECommandInternalID &id)
{
for (int i = 0; i < ARRAY_SIZE(g_Commands); i++)
for (unsigned i = 0; i < ARRAY_SIZE(g_Commands); i++)
if (g_Commands[i].CommandInternalID == id)
return i;
return -1;
@@ -287,12 +287,10 @@ static const char * const kArcExts[] =
, "zip"
};
static bool IsItArcExt(const UString &ext2)
static bool IsItArcExt(const UString &ext)
{
UString ext = ext2;
ext.MakeLower_Ascii();
for (unsigned i = 0; i < ARRAY_SIZE(kArcExts); i++)
if (ext.IsEqualTo(kArcExts[i]))
if (ext.IsEqualTo_Ascii_NoCase(kArcExts[i]))
return true;
return false;
}
@@ -429,6 +427,7 @@ void CZipContextMenu::AddMapItem_ForSubMenu(const wchar_t *verb)
_commandMap.Add(commandMapItem);
}
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UINT commandIDFirst, UINT commandIDLast, UINT flags)
{
@@ -451,12 +450,15 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
CContextMenuInfo ci;
ci.Load();
_elimDup = ci.ElimDup;
HBITMAP bitmap = NULL;
if (ci.MenuIcons)
if (ci.MenuIcons.Val)
bitmap = _bitmap;
UINT subIndex = indexMenu;
if (ci.Cascaded)
if (ci.Cascaded.Val)
{
if (!popupMenu.CreatePopup())
return E_FAIL;
@@ -473,15 +475,21 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
else
{
popupMenu.Attach(hMenu);
CMenuItem mi;
mi.fType = MFT_SEPARATOR;
mi.fMask = MIIM_TYPE;
popupMenu.InsertItem(subIndex++, true, mi);
}
UInt32 contextMenuFlags = ci.Flags;
NFind::CFileInfo fi0;
FString folderPrefix;
if (_fileNames.Size() > 0)
{
const UString &fileName = _fileNames.Front();
#if defined(_WIN32) && !defined(UNDER_CE)
if (NName::IsDevicePath(us2fs(fileName)))
{
@@ -505,6 +513,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
}
UString mainString;
if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast)
{
if (!fi0.IsDir() && DoNeedExtract(fi0.Name))
@@ -565,6 +574,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast)
{
bool needExtract = (!fi0.IsDir() && DoNeedExtract(fi0.Name));
if (!needExtract)
{
FOR_VECTOR (i, _fileNames)
@@ -579,7 +589,9 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
}
}
}
const UString &fileName = _fileNames.Front();
if (needExtract)
{
// Extract
@@ -629,6 +641,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
_commandMap.Add(commandMapItem);
}
// Test
if ((contextMenuFlags & NContextMenuFlags::kTest) != 0)
{
@@ -644,6 +657,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
arcName = CreateArchiveName(fi0, false);
else
arcName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
UString arcName7z = arcName + L".7z";
UString arcNameZip = arcName + L".zip";
@@ -745,7 +759,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
// PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension
// ID: Q214477
if (ci.Cascaded)
if (ci.Cascaded.Val)
{
CMenuItem mi;
mi.fType = MFT_STRING;
@@ -756,12 +770,20 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
mi.hSubMenu = popupMenu.Detach();
mi.StringValue.SetFromAscii("7-Zip"); // LangString(IDS_CONTEXT_POPUP_CAPTION);
mi.hbmpUnchecked = bitmap;
CMenu menu;
menu.Attach(hMenu);
menuDestroyer.Disable();
menu.InsertItem(indexMenu++, true, mi);
AddMapItem_ForSubMenu(kMainVerb);
}
else
{
popupMenu.Detach();
indexMenu = subIndex;
}
if (!_isMenuForFM &&
((contextMenuFlags & NContextMenuFlags::kCRC) != 0
@@ -771,6 +793,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
// CMenuDestroyer menuDestroyer_CRC;
UINT subIndex_CRC = 0;
if (subMenu.CreatePopup())
{
// menuDestroyer_CRC.Attach(subMenu);
@@ -783,13 +806,15 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
mi.hSubMenu = subMenu;
mi.StringValue.SetFromAscii("CRC SHA");
mi.hbmpUnchecked = bitmap;
CMenu menu;
menu.Attach(hMenu);
// menuDestroyer_CRC.Disable();
menu.InsertItem(indexMenu++, true, mi);
AddMapItem_ForSubMenu(kCheckSumCascadedVerb);
for (int i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{
const CHashCommand &hc = g_HashCommands[i];
CCommandMapItem commandMapItem;
@@ -799,6 +824,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, hc.UserName, bitmap);
_commandMap.Add(commandMapItem);
}
subMenu.Detach();
}
}
@@ -872,7 +898,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
{
ExtractArchives(_fileNames, commandMapItem.Folder,
(cmdID == kExtract), // showDialog
(cmdID == kExtractTo) // elimDup
(cmdID == kExtractTo) && _elimDup.Val // elimDup
);
break;
}
@@ -902,12 +928,14 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
_fileNames, email, showDialog, false);
break;
}
case kHash_CRC32:
case kHash_CRC64:
case kHash_SHA1:
case kHash_SHA256:
case kHash_All:
for (int i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{
const CHashCommand &hc = g_HashCommands[i];
if (hc.CommandInternalID == cmdID)
@@ -919,6 +947,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
break;
}
}
}
catch(...)
{
::MessageBoxW(0, L"Error", L"7-Zip", MB_ICONERROR);

View File

@@ -74,6 +74,8 @@ private:
HBITMAP _bitmap;
CBoolPair _elimDup;
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
int FindVerb(const UString &verb);
bool FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &commandMapItem);

View File

@@ -10,13 +10,11 @@
#include "../../../Common/MyWindows.h"
#include <ShlGuid.h>
#include <OleCtl.h>
#include "../../../Common/MyInitGuid.h"
#include "../../../Common/ComTry.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/DLL.h"
#include "../../../Windows/ErrorMsg.h"
@@ -24,11 +22,15 @@
#include "../../../Windows/Registry.h"
#include "../FileManager/IFolder.h"
#include "../FileManager/LangUtils.h"
#include "ContextMenu.h"
static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
static LPCTSTR k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
// {23170F69-40C1-278A-1000-000100020000}
static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
DEFINE_GUID(CLSID_CZipContextMenu,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
@@ -42,10 +44,6 @@ HWND g_HWND = 0;
LONG g_DllRefCount = 0; // Reference count of this DLL.
static LPCWSTR kShellExtName = L"7-Zip Shell Extension";
static LPCTSTR kClsidMask = TEXT("CLSID\\%s");
static LPCTSTR kClsidInprocMask = TEXT("CLSID\\%s\\InprocServer32");
static LPCTSTR kApprovedKeyPath = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
// #define ODS(sz) OutputDebugString(L#sz)
@@ -77,7 +75,7 @@ STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
shellExt = new CZipContextMenu();
}
catch(...) { return E_OUTOFMEMORY; }
if (shellExt == NULL)
if (!shellExt)
return E_OUTOFMEMORY;
HRESULT res = shellExt->QueryInterface(riid, ppvObj);
@@ -117,7 +115,7 @@ BOOL WINAPI DllMain(
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void)
@@ -138,7 +136,7 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
cf = new CShellExtClassFactory;
}
catch(...) { return E_OUTOFMEMORY; }
if (cf == 0)
if (!cf)
return E_OUTOFMEMORY;
HRESULT res = cf->QueryInterface(riid, ppv);
if (res != S_OK)
@@ -149,66 +147,28 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
// return _Module.GetClassObject(rclsid, riid, ppv);
}
static BOOL GetStringFromIID(CLSID clsid, LPTSTR s, int size)
{
LPWSTR pwsz;
if (StringFromIID(clsid, &pwsz) != S_OK)
return FALSE;
if (!pwsz)
return FALSE;
#ifdef UNICODE
for (int i = 0; i < size; i++)
{
s[i] = pwsz[i];
if (pwsz[i] == 0)
break;
}
s[size - 1] = 0;
#else
WideCharToMultiByte(CP_ACP, 0, pwsz, -1, s, size, NULL, NULL);
#endif
CoTaskMemFree(pwsz);
s[size - 1] = 0;
return TRUE;
}
typedef struct
static BOOL RegisterServer()
{
HKEY hRootKey;
LPCTSTR SubKey;
LPCWSTR ValueName;
LPCWSTR Data;
} CRegItem;
static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
{
TCHAR clsidString[MAX_PATH];
if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
return FALSE;
FString modulePath;
if (!NDLL::MyGetModuleFileName(modulePath))
return FALSE;
UString modulePathU = fs2us(modulePath);
const UString modulePathU = fs2us(modulePath);
CRegItem clsidEntries[] =
{
HKEY_CLASSES_ROOT, kClsidMask, NULL, title,
HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePathU,
HKEY_CLASSES_ROOT, kClsidInprocMask, L"ThreadingModel", L"Apartment",
NULL, NULL, NULL, NULL
};
CSysString clsidString = k_Clsid;
CSysString s = TEXT("CLSID\\");
s += clsidString;
//register the CLSID entries
for (int i = 0; clsidEntries[i].hRootKey; i++)
{
TCHAR subKey[MAX_PATH];
const CRegItem &r = clsidEntries[i];
wsprintf(subKey, r.SubKey, clsidString);
NRegistry::CKey key;
if (key.Create(r.hRootKey, subKey, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
if (key.Create(HKEY_CLASSES_ROOT, s, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
return FALSE;
key.SetValue(clsidEntries[i].ValueName, clsidEntries[i].Data);
key.SetValue(NULL, k_ShellExtName);
NRegistry::CKey keyInproc;
if (keyInproc.Create(key, TEXT("InprocServer32"), NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
return FALSE;
keyInproc.SetValue(NULL, modulePathU);
keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment"));
}
#if !defined(_WIN64) && !defined(UNDER_CE)
@@ -216,46 +176,45 @@ static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
#endif
{
NRegistry::CKey key;
if (key.Create(HKEY_LOCAL_MACHINE, kApprovedKeyPath, NULL,
REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
key.SetValue(GetUnicodeString(clsidString), title);
if (key.Create(HKEY_LOCAL_MACHINE, k_Approved, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
key.SetValue(clsidString, k_ShellExtName);
}
return TRUE;
}
STDAPI DllRegisterServer(void)
{
return RegisterServer(CLSID_CZipContextMenu, kShellExtName) ? S_OK: SELFREG_E_CLASS;
return RegisterServer() ? S_OK: SELFREG_E_CLASS;
}
static BOOL UnregisterServer(CLSID clsid)
static BOOL UnregisterServer()
{
TCHAR clsidString[MAX_PATH];
if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
return FALSE;
const CSysString clsidString = k_Clsid;
CSysString s = TEXT("CLSID\\");
s += clsidString;
CSysString s2 = s;
s2.AddAscii("\\InprocServer32");
TCHAR subKey[MAX_PATH];
wsprintf(subKey, kClsidInprocMask, clsidString);
RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
wsprintf (subKey, kClsidMask, clsidString);
RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
RegDeleteKey(HKEY_CLASSES_ROOT, s2);
RegDeleteKey(HKEY_CLASSES_ROOT, s);
#if !defined(_WIN64) && !defined(UNDER_CE)
if (IsItWindowsNT())
#endif
{
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, kApprovedKeyPath, 0, KEY_SET_VALUE, &hKey) == NOERROR)
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, k_Approved, 0, KEY_SET_VALUE, &hKey) == NOERROR)
{
RegDeleteValue(hKey, clsidString);
RegCloseKey(hKey);
}
}
return TRUE;
}
STDAPI DllUnregisterServer(void)
{
return UnregisterServer(CLSID_CZipContextMenu) ? S_OK: SELFREG_E_CLASS;
return UnregisterServer() ? S_OK: SELFREG_E_CLASS;
}

View File

@@ -538,13 +538,5 @@ SOURCE=".\7-zip.dll.manifest"
SOURCE=.\ContextMenuFlags.h
# End Source File
# Begin Source File
SOURCE=.\RegistryContextMenu.cpp
# End Source File
# Begin Source File
SOURCE=.\RegistryContextMenu.h
# End Source File
# End Target
# End Project

View File

@@ -2,114 +2,218 @@
#include "StdAfx.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/Registry.h"
#include "../../../Windows/Synchronization.h"
#include "RegistryContextMenu.h"
using namespace NWindows;
using namespace NRegistry;
namespace NZipRootRegistry {
#ifndef UNDER_CE
static NSynchronization::CCriticalSection g_CS;
// does extension can work, if Approved is removed ?
// CLISID (and Approved ?) items are separated for 32-bit and 64-bit code.
// shellex items shared by 32-bit and 64-bit code?
static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
static const TCHAR *kDragDropMenuKeyName = TEXT("\\shellex\\DragDropHandlers\\7-Zip");
static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
static const TCHAR *kExtensionCLSID = TEXT("{23170F69-40C1-278A-1000-000100020000}");
static LPCTSTR k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
static LPCTSTR k_Inproc = TEXT("InprocServer32");
static const TCHAR *kRootKeyNameForFile = TEXT("*");
static const TCHAR *kRootKeyNameForFolder = TEXT("Folder");
static const TCHAR *kRootKeyNameForDirectory = TEXT("Directory");
static const TCHAR *kRootKeyNameForDrive = TEXT("Drive");
static LPCTSTR k_KeyPostfix_ContextMenu = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
static LPCTSTR k_KeyPostfix_DragDrop = TEXT("\\shellex\\DragDropHandlers\\7-Zip");
static CSysString GetFullContextMenuKeyName(const CSysString &keyName)
{ return (keyName + kContextMenuKeyName); }
static LPCTSTR k_KeyName_File = TEXT("*");
static LPCTSTR k_KeyName_Folder = TEXT("Folder");
static LPCTSTR k_KeyName_Directory = TEXT("Directory");
static LPCTSTR k_KeyName_Drive = TEXT("Drive");
static CSysString GetFullDragDropMenuKeyName(const CSysString &keyName)
{ return (keyName + kDragDropMenuKeyName); }
static bool CheckHandlerCommon(const CSysString &keyName)
static LPCTSTR const k_shellex_Prefixes[] =
{
k_KeyName_File,
k_KeyName_Folder,
k_KeyName_Directory,
k_KeyName_Drive
};
static const bool k_shellex_Statuses[2][4] =
{
{ true, true, true, false },
{ false, false, true, true }
};
// can we use static RegDeleteKeyExW in _WIN64 mode?
// is it supported by Windows 2003 x64?
/*
#ifdef _WIN64
#define INIT_REG_WOW
#else
*/
typedef WINADVAPI LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved);
static Func_RegDeleteKeyExW func_RegDeleteKeyExW;
static void Init_RegDeleteKeyExW()
{
if (!func_RegDeleteKeyExW)
func_RegDeleteKeyExW = (Func_RegDeleteKeyExW)
GetProcAddress(GetModuleHandleW(L"advapi32.dll"), "RegDeleteKeyExW");
}
#define INIT_REG_WOW if (wow != 0) Init_RegDeleteKeyExW();
// #endif
static LONG MyRegistry_DeleteKey(HKEY parentKey, LPCTSTR name, UInt32 wow)
{
if (wow == 0)
return RegDeleteKey(parentKey, name);
/*
#ifdef _WIN64
return RegDeleteKeyExW
#else
*/
if (!func_RegDeleteKeyExW)
return E_NOTIMPL;
return func_RegDeleteKeyExW
// #endif
(parentKey, GetUnicodeString(name), wow, 0);
}
static LONG MyRegistry_DeleteKey_HKCR(LPCTSTR name, UInt32 wow)
{
return MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, name, wow);
}
// static NSynchronization::CCriticalSection g_CS;
static CSysString Get_ContextMenuHandler_KeyName(const CSysString &keyName)
{ return (keyName + k_KeyPostfix_ContextMenu); }
/*
static CSysString Get_DragDropHandler_KeyName(const CSysString &keyName)
{ return (keyName + k_KeyPostfix_DragDrop); }
*/
static bool CheckHandlerCommon(const CSysString &keyName, UInt32 wow)
{
NSynchronization::CCriticalSectionLock lock(g_CS);
CKey key;
if (key.Open(HKEY_CLASSES_ROOT, keyName, KEY_READ) != ERROR_SUCCESS)
if (key.Open(HKEY_CLASSES_ROOT, keyName, KEY_READ | wow) != ERROR_SUCCESS)
return false;
CSysString value;
if (key.QueryValue(NULL, value) != ERROR_SUCCESS)
return false;
return StringsAreEqualNoCase_Ascii(value, kExtensionCLSID);
return StringsAreEqualNoCase_Ascii(value, k_Clsid);
}
bool CheckContextMenuHandler()
bool CheckContextMenuHandler(const UString &path, UInt32 wow)
{
// NSynchronization::CCriticalSectionLock lock(g_CS);
CSysString s = TEXT("CLSID\\");
s += k_Clsid;
s.AddAscii("\\InprocServer32");
{
NRegistry::CKey key;
if (key.Open(HKEY_CLASSES_ROOT, s, KEY_READ | wow) != ERROR_SUCCESS)
return false;
UString regPath;
if (key.QueryValue(NULL, regPath) != ERROR_SUCCESS)
return false;
if (!path.IsEqualTo_NoCase(regPath))
return false;
}
return
// CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForFolder)) &&
CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForDirectory)) &&
CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForFile)) &&
CheckHandlerCommon(GetFullDragDropMenuKeyName(kRootKeyNameForDirectory)) &&
CheckHandlerCommon(GetFullDragDropMenuKeyName(kRootKeyNameForDrive));
CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_File), wow);
/*
&& CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_Directory), wow)
// && CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_Folder))
&& CheckHandlerCommon(Get_DragDropHandler_KeyName(k_KeyName_Directory), wow)
&& CheckHandlerCommon(Get_DragDropHandler_KeyName(k_KeyName_Drive), wow);
*/
}
static void DeleteContextMenuHandlerCommon(const CSysString &keyName)
static LONG MyCreateKey(CKey &key, HKEY parentKey, LPCTSTR keyName, UInt32 wow)
{
CKey rootKey;
rootKey.Attach(HKEY_CLASSES_ROOT);
rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(keyName));
rootKey.Detach();
return key.Create(parentKey, keyName, REG_NONE,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | wow);
}
static void DeleteDragDropMenuHandlerCommon(const CSysString &keyName)
LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow)
{
CKey rootKey;
rootKey.Attach(HKEY_CLASSES_ROOT);
rootKey.RecurseDeleteKey(GetFullDragDropMenuKeyName(keyName));
rootKey.Detach();
}
// NSynchronization::CCriticalSectionLock lock(g_CS);
void DeleteContextMenuHandler()
{
DeleteContextMenuHandlerCommon(kRootKeyNameForFile);
DeleteContextMenuHandlerCommon(kRootKeyNameForFolder);
DeleteContextMenuHandlerCommon(kRootKeyNameForDirectory);
DeleteContextMenuHandlerCommon(kRootKeyNameForDrive);
DeleteDragDropMenuHandlerCommon(kRootKeyNameForFile);
DeleteDragDropMenuHandlerCommon(kRootKeyNameForFolder);
DeleteDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
DeleteDragDropMenuHandlerCommon(kRootKeyNameForDrive);
}
INIT_REG_WOW
static void AddContextMenuHandlerCommon(const CSysString &keyName)
CSysString s = TEXT("CLSID\\");
s += k_Clsid;
LONG res;
if (setMode)
{
{
DeleteContextMenuHandlerCommon(keyName);
NSynchronization::CCriticalSectionLock lock(g_CS);
CKey key;
key.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName));
key.SetValue(NULL, kExtensionCLSID);
res = MyCreateKey(key, HKEY_CLASSES_ROOT, s, wow);
if (res == ERROR_SUCCESS)
{
key.SetValue(NULL, k_ShellExtName);
CKey keyInproc;
res = MyCreateKey(keyInproc, key, k_Inproc, wow);
if (res == ERROR_SUCCESS)
{
res = keyInproc.SetValue(NULL, path);
keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment"));
}
}
}
static void AddDragDropMenuHandlerCommon(const CSysString &keyName)
{
DeleteDragDropMenuHandlerCommon(keyName);
NSynchronization::CCriticalSectionLock lock(g_CS);
CKey key;
key.Create(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName));
key.SetValue(NULL, kExtensionCLSID);
if (MyCreateKey(key, HKEY_LOCAL_MACHINE, k_Approved, wow) == ERROR_SUCCESS)
key.SetValue(k_Clsid, k_ShellExtName);
}
}
else
{
CSysString s2 = s;
s2.AddAscii("\\InprocServer32");
MyRegistry_DeleteKey_HKCR(s2, wow);
res = MyRegistry_DeleteKey_HKCR(s, wow);
}
void AddContextMenuHandler()
// shellex items probably are shared beween 32-bit and 64-bit apps. So we don't delete items for delete operation.
if (setMode)
for (unsigned i = 0; i < 2; i++)
{
AddContextMenuHandlerCommon(kRootKeyNameForFile);
// AddContextMenuHandlerCommon(kRootKeyNameForFolder);
AddContextMenuHandlerCommon(kRootKeyNameForDirectory);
for (unsigned k = 0; k < ARRAY_SIZE(k_shellex_Prefixes); k++)
{
CSysString s = k_shellex_Prefixes[k];
s += (i == 0 ? k_KeyPostfix_ContextMenu : k_KeyPostfix_DragDrop);
if (k_shellex_Statuses[i][k])
{
CKey key;
MyCreateKey(key, HKEY_CLASSES_ROOT, s, wow);
key.SetValue(NULL, k_Clsid);
}
else
MyRegistry_DeleteKey_HKCR(s, wow);
}
}
AddDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
AddDragDropMenuHandlerCommon(kRootKeyNameForDrive);
return res;
}
#endif
}

View File

@@ -3,14 +3,11 @@
#ifndef __REGISTRY_CONTEXT_MENU_H
#define __REGISTRY_CONTEXT_MENU_H
namespace NZipRootRegistry {
#ifndef UNDER_CE
bool CheckContextMenuHandler();
void AddContextMenuHandler();
void DeleteContextMenuHandler();
#endif
}
bool CheckContextMenuHandler(const UString &path, UInt32 wow = 0);
LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow = 0);
#endif
#endif

View File

@@ -14,7 +14,6 @@ EXPLORER_OBJS = \
$O\DllExportsExplorer.obj \
$O\ContextMenu.obj \
$O\MyMessages.obj \
$O\RegistryContextMenu.obj \
COMMON_OBJS = \
$O\IntToString.obj \

View File

@@ -448,7 +448,7 @@ int PrintErrorMessage(const char *message, const char *text)
}
static void ReduceString(UString &s, unsigned size)
void ReduceString(UString &s, unsigned size)
{
if (s.Len() > size)
{

View File

@@ -190,6 +190,8 @@ int ShowLastErrorMessage();
bool WasEscPressed();
void ReduceString(UString &s, unsigned size);
}
#endif

View File

@@ -68,8 +68,17 @@ NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInf
SetFileInfoStrings(oldFileInfo, oldFileInfoStrings);
SetFileInfoStrings(newFileInfo, newFileInfoStrings);
AString oldName = UnicodeStringToMultiByte(oldFileInfo.Name, CP_OEMCP);
AString newName = UnicodeStringToMultiByte(newFileInfo.Name, CP_OEMCP);
UString oldName2 = oldFileInfo.Name;
UString newName2 = newFileInfo.Name;
{
const unsigned maxNameLen = kXSize - 9 - 2;
ReduceString(oldName2, maxNameLen);
ReduceString(newName2, maxNameLen);
}
AString oldName = UnicodeStringToMultiByte(oldName2);
AString newName = UnicodeStringToMultiByte(newName2);
struct CInitDialogItem initItems[]={
{ DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kOverwriteTitle, NULL, NULL },

View File

@@ -72,17 +72,18 @@ void CApp::ReloadLang()
void CApp::SetListSettings()
{
bool showDots = ReadShowDots();
bool showRealFileIcons = ReadShowRealFileIcons();
CFmSettings st;
st.Load();
ShowSystemMenu = st.ShowSystemMenu;
DWORD extendedStyle = LVS_EX_HEADERDRAGDROP;
if (ReadFullRow())
if (st.FullRow)
extendedStyle |= LVS_EX_FULLROWSELECT;
if (ReadShowGrid())
if (st.ShowGrid)
extendedStyle |= LVS_EX_GRIDLINES;
bool mySelectionMode = ReadAlternativeSelection();
if (ReadSingleClick())
if (st.SingleClick)
{
extendedStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT;
/*
@@ -91,16 +92,16 @@ void CApp::SetListSettings()
*/
}
for (int i = 0; i < kNumPanelsMax; i++)
for (unsigned i = 0; i < kNumPanelsMax; i++)
{
CPanel &panel = Panels[i];
panel._mySelectMode = mySelectionMode;
panel._showDots = showDots;
panel._showRealFileIcons = showRealFileIcons;
panel._mySelectMode = st.AlternativeSelection;
panel._showDots = st.ShowDots;
panel._showRealFileIcons = st.ShowRealFileIcons;
panel._exStyle = extendedStyle;
DWORD style = (DWORD)panel._listView.GetStyle();
if (mySelectionMode)
if (st.AlternativeSelection)
style |= LVS_SINGLESEL;
else
style &= ~LVS_SINGLESEL;
@@ -109,11 +110,6 @@ void CApp::SetListSettings()
}
}
void CApp::SetShowSystemMenu()
{
ShowSystemMenu = Read_ShowSystemMenu();
}
#ifndef ILC_COLOR32
#define ILC_COLOR32 0x0020
#endif
@@ -179,7 +175,7 @@ struct CButtonInfo
UString GetText() const { return LangString(StringResID); }
};
static CButtonInfo g_StandardButtons[] =
static const CButtonInfo g_StandardButtons[] =
{
{ IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY },
{ IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE },
@@ -187,16 +183,16 @@ static CButtonInfo g_StandardButtons[] =
{ IDM_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO }
};
static CButtonInfo g_ArchiveButtons[] =
static const CButtonInfo g_ArchiveButtons[] =
{
{ kMenuCmdID_Toolbar_Add, IDB_ADD, IDB_ADD2, IDS_ADD },
{ kMenuCmdID_Toolbar_Extract, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT },
{ kMenuCmdID_Toolbar_Test, IDB_TEST, IDB_TEST2, IDS_TEST }
};
static bool SetButtonText(int commandID, CButtonInfo *buttons, int numButtons, UString &s)
static bool SetButtonText(int commandID, const CButtonInfo *buttons, unsigned numButtons, UString &s)
{
for (int i = 0; i < numButtons; i++)
for (unsigned i = 0; i < numButtons; i++)
{
const CButtonInfo &b = buttons[i];
if (b.CommandID == commandID)
@@ -218,7 +214,7 @@ static void SetButtonText(int commandID, UString &s)
static void AddButton(
NControl::CImageList &imageList,
NControl::CToolBar &toolBar,
CButtonInfo &butInfo, bool showText, bool large)
const CButtonInfo &butInfo, bool showText, bool large)
{
TBBUTTON but;
but.iBitmap = 0;
@@ -258,7 +254,7 @@ void CApp::ReloadToolbars()
if (ShowArchiveToolbar || ShowStandardToolbar)
{
CreateToolbar(_window, _buttonsImageList, _toolBar, LargeButtons);
int i;
unsigned i;
if (ShowArchiveToolbar)
for (i = 0; i < ARRAY_SIZE(g_ArchiveButtons); i++)
AddButton(_buttonsImageList, _toolBar, g_ArchiveButtons[i], ShowButtonsLables, LargeButtons);
@@ -282,10 +278,13 @@ void MyLoadMenu();
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool &archiveIsOpened, bool &encrypted)
{
_window.Attach(hwnd);
#ifdef UNDER_CE
_commandBar.Create(g_hInstance, hwnd, 1);
#endif
MyLoadMenu();
#ifdef UNDER_CE
_commandBar.AutoSize();
#endif
@@ -298,14 +297,16 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
PanelsCreated[i] = false;
AppState.Read();
SetListSettings();
SetShowSystemMenu();
if (LastFocusedPanel >= kNumPanelsMax)
LastFocusedPanel = 0;
// ShowDeletedFiles = Read_ShowDeleted();
CListMode listMode;
listMode.Read();
for (i = 0; i < kNumPanelsMax; i++)
{
CPanel &panel = Panels[i];
@@ -313,6 +314,7 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
panel._xSize = xSizes[i];
panel._flatModeForArc = ReadFlatView(i);
}
for (i = 0; i < kNumPanelsMax; i++)
if (NumPanels > 1 || i == LastFocusedPanel)
{
@@ -328,6 +330,7 @@ HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcForma
encrypted = encrypted2;
}
}
SetFocusedPanel(LastFocusedPanel);
Panels[LastFocusedPanel].SetFocusToList();
return S_OK;
@@ -357,7 +360,8 @@ void CApp::Save()
{
AppState.Save();
CListMode listMode;
for (int i = 0; i < kNumPanelsMax; i++)
for (unsigned i = 0; i < kNumPanelsMax; i++)
{
const CPanel &panel = Panels[i];
UString path;
@@ -370,6 +374,7 @@ void CApp::Save()
listMode.Panels[i] = panel.GetListViewMode();
SaveFlatView(i, panel._flatModeForArc);
}
listMode.Save();
// Save_ShowDeleted(ShowDeletedFiles);
}
@@ -377,7 +382,7 @@ void CApp::Save()
void CApp::Release()
{
// It's for unloading COM dll's: don't change it.
for (int i = 0; i < kNumPanelsMax; i++)
for (unsigned i = 0; i < kNumPanelsMax; i++)
Panels[i].Release();
}
@@ -467,6 +472,7 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
UString info;
UInt64 numDirs, numFiles, filesSize, foldersSize;
numDirs = numFiles = filesSize = foldersSize = 0;
unsigned i;
for (i = 0; i < indices.Size(); i++)
{

View File

@@ -258,7 +258,6 @@ public:
*/
void SetListSettings();
void SetShowSystemMenu();
HRESULT SwitchOnOffOnePanel();
bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); }

View File

@@ -197,9 +197,11 @@ bool CBrowseDialog::OnInit()
#endif
#ifndef _SFX
if (ReadSingleClick())
CFmSettings st;
st.Load();
if (st.SingleClick)
_list.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
_showDots = ReadShowDots();
_showDots = st.ShowDots;
#endif
{
@@ -999,11 +1001,13 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
}
#else
bool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result)
{
result = path;
return true;
}
#endif
bool Dlg_CreateFolder(HWND wnd, UString &destName)

View File

@@ -27,48 +27,50 @@ static LPCWSTR kEditTopic = L"FM/options.htm#editor";
bool CEditPage::OnInit()
{
_initMode = true;
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon));
_viewer.Attach(GetItem(IDE_EDIT_VIEWER));
_editor.Attach(GetItem(IDE_EDIT_EDITOR));
_diff.Attach(GetItem(IDE_EDIT_DIFF));
_ctrls[0].Ctrl = IDE_EDIT_VIEWER; _ctrls[0].Button = IDB_EDIT_VIEWER;
_ctrls[1].Ctrl = IDE_EDIT_EDITOR; _ctrls[1].Button = IDB_EDIT_EDITOR;
_ctrls[2].Ctrl = IDE_EDIT_DIFF; _ctrls[2].Button = IDB_EDIT_DIFF;
for (unsigned i = 0; i < 3; i++)
{
CEditPageCtrl &c = _ctrls[i];
c.WasChanged = false;
c.Edit.Attach(GetItem(c.Ctrl));
UString path;
ReadRegEditor(false, path);
_viewer.SetText(path);
}
{
UString path;
ReadRegEditor(true, path);
_editor.SetText(path);
}
{
UString path;
if (i < 2)
ReadRegEditor(i > 0, path);
else
ReadRegDiff(path);
_diff.SetText(path);
c.Edit.SetText(path);
}
_initMode = false;
return CPropertyPage::OnInit();
}
LONG CEditPage::OnApply()
{
for (unsigned i = 0; i < 3; i++)
{
CEditPageCtrl &c = _ctrls[i];
if (c.WasChanged)
{
UString path;
_viewer.GetText(path);
SaveRegEditor(false, path);
}
{
UString path;
_editor.GetText(path);
SaveRegEditor(true, path);
}
{
UString path;
_diff.GetText(path);
c.Edit.GetText(path);
if (i < 2)
SaveRegEditor(i > 0, path);
else
SaveRegDiff(path);
c.WasChanged = false;
}
}
return PSNRET_NOERROR;
}
@@ -91,24 +93,34 @@ static void Edit_BrowseForFile(NWindows::NControl::CEdit &edit, HWND hwnd)
bool CEditPage::OnButtonClicked(int buttonID, HWND buttonHWND)
{
switch (buttonID)
for (unsigned i = 0; i < 3; i++)
{
case IDB_EDIT_VIEWER: Edit_BrowseForFile(_viewer, *this); return true;
case IDB_EDIT_EDITOR: Edit_BrowseForFile(_editor, *this); return true;
case IDB_EDIT_DIFF: Edit_BrowseForFile(_diff, *this); return true;
CEditPageCtrl &c = _ctrls[i];
if (buttonID == c.Button)
{
Edit_BrowseForFile(c.Edit, *this);
return true;
}
}
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}
bool CEditPage::OnCommand(int code, int itemID, LPARAM param)
{
if (code == EN_CHANGE && (
itemID == IDE_EDIT_VIEWER ||
itemID == IDE_EDIT_EDITOR ||
itemID == IDE_EDIT_DIFF))
if (!_initMode && code == EN_CHANGE)
{
for (unsigned i = 0; i < 3; i++)
{
CEditPageCtrl &c = _ctrls[i];
if (itemID == c.Ctrl)
{
c.WasChanged = true;
Changed();
return true;
}
}
}
return CPropertyPage::OnCommand(code, itemID, param);
}

View File

@@ -6,11 +6,19 @@
#include "../../../Windows/Control/PropertyPage.h"
#include "../../../Windows/Control/Edit.h"
struct CEditPageCtrl
{
NWindows::NControl::CEdit Edit;
bool WasChanged;
int Ctrl;
int Button;
};
class CEditPage: public NWindows::NControl::CPropertyPage
{
NWindows::NControl::CEdit _viewer;
NWindows::NControl::CEdit _editor;
NWindows::NControl::CEdit _diff;
CEditPageCtrl _ctrls[3];
bool _initMode;
public:
virtual bool OnInit();
virtual void OnNotifyHelp();

View File

@@ -324,42 +324,44 @@ static void GetCommands(const UString &aCommandLine, UString &aCommands)
}
*/
/*
#ifndef _WIN64
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
#if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE)
static bool IsWow64()
bool g_Is_Wow64;
typedef BOOL (WINAPI *Func_IsWow64Process)(HANDLE, PBOOL);
static void Set_Wow64()
{
g_Is_Wow64 = false;
Func_IsWow64Process fnIsWow64Process = (Func_IsWow64Process)GetProcAddress(
GetModuleHandleA("kernel32.dll"), "IsWow64Process");
if (fnIsWow64Process)
{
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
GetModuleHandle("kernel32"), "IsWow64Process");
if (fnIsWow64Process == NULL)
return false;
BOOL isWow;
if (!fnIsWow64Process(GetCurrentProcess(),&isWow))
return false;
return isWow != FALSE;
if (fnIsWow64Process(GetCurrentProcess(), &isWow))
g_Is_Wow64 = (isWow != FALSE);
}
}
#endif
*/
bool IsLargePageSupported()
{
#ifdef _WIN64
return true;
#else
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
if (!::GetVersionEx(&versionInfo))
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (!::GetVersionEx(&vi))
return false;
if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 5)
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
return false;
if (versionInfo.dwMajorVersion > 5)
return true;
if (versionInfo.dwMinorVersion < 1)
return false;
if (versionInfo.dwMinorVersion > 1)
return true;
// return IsWow64();
if (vi.dwMajorVersion < 5) return false;
if (vi.dwMajorVersion > 5) return true;
if (vi.dwMinorVersion < 1) return false;
if (vi.dwMinorVersion > 1) return true;
// return g_Is_Wow64;
return false;
#endif
}
@@ -382,11 +384,11 @@ bool g_SymLink_Supported = false;
static void Set_SymLink_Supported()
{
g_SymLink_Supported = false;
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
if (!::GetVersionEx(&versionInfo))
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (!::GetVersionEx(&vi))
return;
if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 6)
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT || vi.dwMajorVersion < 6)
return;
g_SymLink_Supported = true;
// if (g_SymLink_Supported)
@@ -468,6 +470,11 @@ static int WINAPI WinMain2(int nCmdShow)
g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4));
#endif
#if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE)
Set_Wow64();
#endif
g_IsSmallScreen = !NWindows::NControl::IsDialogSizeOK(200, 200);
// OleInitialize is required for drag and drop.
@@ -633,10 +640,18 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
{
g_hInstance = hInstance;
try
{
try
{
return WinMain2(nCmdShow);
}
catch (...)
{
g_ExitEventLauncher.Exit(true);
throw;
}
}
catch(const CNewException &)
{
ErrorMessage(LangString(IDS_MEM_ERROR));
@@ -855,15 +870,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
g_App.Save();
g_App.Release();
SaveWindowInfo(hWnd);
g_ExitEventLauncher.Exit(true);
PostQuitMessage(0);
break;
}
/*
case WM_MOVE:
{
break;
}
*/
// case WM_MOVE: break;
case WM_LBUTTONDOWN:
g_StartCaptureMousePos = LOWORD(lParam);
g_StartCaptureSplitterPos = g_Splitter.GetPos();
@@ -993,6 +1007,7 @@ void CApp::MoveSubWindows()
if (xSize == 0)
return;
int headerSize = 0;
#ifdef UNDER_CE
_commandBar.AutoSize();
{
@@ -1000,6 +1015,7 @@ void CApp::MoveSubWindows()
headerSize += _commandBar.Height();
}
#endif
if (_toolBar)
{
_toolBar.AutoSize();
@@ -1009,6 +1025,7 @@ void CApp::MoveSubWindows()
#endif
headerSize += Window_GetRealHeight(_toolBar);
}
int ySize = MyMax((int)(rect.bottom - headerSize), 0);
if (NumPanels > 1)

View File

@@ -208,7 +208,6 @@ struct CCopyState
{
CProgressInfo ProgressInfo;
IFolderOperationsExtractCallback *Callback;
UInt64 TotalSize;
bool MoveMode;
bool UseReadWriteMode;
@@ -423,7 +422,7 @@ static HRESULT CopyFile_Ask(
NFsFolder::CCopyStateIO state2;
state2.Progress = state.Callback;
state2.DeleteSrcFile = state.MoveMode;
state2.TotalSize = state.TotalSize;
state2.TotalSize = state.ProgressInfo.TotalSize;
state2.StartPos = state.ProgressInfo.StartPos;
RINOK(state2.MyCopyFile(srcPath, destPathNew));
if (state2.ErrorFileIndex >= 0)
@@ -460,10 +459,10 @@ static HRESULT CopyFile_Ask(
}
else
{
if (state.TotalSize >= srcFileInfo.Size)
if (state.ProgressInfo.TotalSize >= srcFileInfo.Size)
{
state.TotalSize -= srcFileInfo.Size;
RINOK(state.ProgressInfo.Progress->SetTotal(state.TotalSize));
state.ProgressInfo.TotalSize -= srcFileInfo.Size;
RINOK(state.ProgressInfo.Progress->SetTotal(state.ProgressInfo.TotalSize));
}
}
return state.CallProgress();

View File

@@ -27,10 +27,13 @@ static const int kWorkModeButtons[] =
IDR_FOLDERS_WORK_SPECIFIED
};
static const int kNumWorkModeButtons = ARRAY_SIZE(kWorkModeButtons);
static const unsigned kNumWorkModeButtons = ARRAY_SIZE(kWorkModeButtons);
bool CFoldersPage::OnInit()
{
_initMode = true;
_needSave = false;
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
m_WorkDirInfo.Load();
@@ -40,18 +43,18 @@ bool CFoldersPage::OnInit()
kWorkModeButtons[m_WorkDirInfo.Mode]);
m_WorkPath.Init(*this, IDE_FOLDERS_WORK_PATH);
m_ButtonSetWorkPath.Init(*this, IDB_FOLDERS_WORK_PATH);
m_WorkPath.SetText(fs2us(m_WorkDirInfo.Path));
MyEnableControls();
_initMode = false;
return CPropertyPage::OnInit();
}
int CFoldersPage::GetWorkMode() const
{
for (int i = 0; i < kNumWorkModeButtons; i++)
for (unsigned i = 0; i < kNumWorkModeButtons; i++)
if (IsButtonCheckedBool(kWorkModeButtons[i]))
return i;
throw 0;
@@ -61,7 +64,7 @@ void CFoldersPage::MyEnableControls()
{
bool enablePath = (GetWorkMode() == NWorkDir::NMode::kSpecified);
m_WorkPath.Enable(enablePath);
m_ButtonSetWorkPath.Enable(enablePath);
EnableItem(IDB_FOLDERS_WORK_PATH, enablePath);
}
void CFoldersPage::GetWorkDir(NWorkDir::CInfo &workDirInfo)
@@ -86,7 +89,11 @@ bool CFoldersPage::WasChanged()
void CFoldersPage::ModifiedEvent()
{
if (!_initMode)
{
_needSave = true;
Changed();
}
/*
if (WasChanged())
Changed();
@@ -97,23 +104,25 @@ void CFoldersPage::ModifiedEvent()
bool CFoldersPage::OnButtonClicked(int buttonID, HWND buttonHWND)
{
for (int i = 0; i < kNumWorkModeButtons; i++)
for (unsigned i = 0; i < kNumWorkModeButtons; i++)
if (buttonID == kWorkModeButtons[i])
{
MyEnableControls();
ModifiedEvent();
return true;
}
switch (buttonID)
{
case IDB_FOLDERS_WORK_PATH:
OnFoldersWorkButtonPath();
break;
return true;
case IDX_FOLDERS_WORK_FOR_REMOVABLE:
break;
default:
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}
ModifiedEvent();
return true;
}
@@ -139,9 +148,13 @@ void CFoldersPage::OnFoldersWorkButtonPath()
}
LONG CFoldersPage::OnApply()
{
if (_needSave)
{
GetWorkDir(m_WorkDirInfo);
m_WorkDirInfo.Save();
_needSave = false;
}
return PSNRET_NOERROR;
}

View File

@@ -10,11 +10,14 @@
class CFoldersPage : public NWindows::NControl::CPropertyPage
{
NWorkDir::CInfo m_WorkDirInfo;
NWindows::NControl::CDialogChildControl m_WorkPath;
bool _needSave;
bool _initMode;
void MyEnableControls();
void ModifiedEvent();
NWindows::NControl::CDialogChildControl m_WorkPath;
NWindows::NControl::CDialogChildControl m_ButtonSetWorkPath;
void OnFoldersWorkButtonPath();
int GetWorkMode() const;
void GetWorkDir(NWorkDir::CInfo &workDirInfo);

View File

@@ -84,14 +84,16 @@ bool CLangPage::OnInit()
}
if (!error.IsEmpty())
MessageBoxW(0, error, L"Error in Lang file", MB_OK | MB_ICONSTOP);
MessageBoxW(0, error, L"Error in Lang file", MB_ICONERROR);
return CPropertyPage::OnInit();
}
LONG CLangPage::OnApply()
{
int pathIndex = (int)_langCombo.GetItemData_of_CurSel();
if (_needSave)
SaveRegLang(_paths[pathIndex]);
_needSave = false;
ReloadLang();
LangWasChanged = true;
return PSNRET_NOERROR;
@@ -106,6 +108,7 @@ bool CLangPage::OnCommand(int code, int itemID, LPARAM param)
{
if (code == CBN_SELCHANGE && itemID == IDC_LANG_LANG)
{
_needSave = true;
Changed();
return true;
}

View File

@@ -10,10 +10,12 @@ class CLangPage: public NWindows::NControl::CPropertyPage
{
NWindows::NControl::CComboBox _langCombo;
UStringVector _paths;
bool _needSave;
public:
bool LangWasChanged;
CLangPage() { LangWasChanged = false; }
CLangPage(): _needSave(false), LangWasChanged(false) {}
virtual bool OnInit();
virtual void OnNotifyHelp();
virtual bool OnCommand(int code, int itemID, LPARAM param);

View File

@@ -140,13 +140,18 @@ void LangString_OnlyFromLangFile(UInt32 langID, UString &dest)
}
static const char *kLangs =
"ar.bg.ca.zh.-tw.-cn.cs.da.de.el.en.es.fi.fr.he.hu.is.it.ja.ko.nl.no.=nb.=nn."
"pl.pt.-br.rm.ro.ru.sr.=hr.-spl.-spc.sk.sq.sv.th.tr.ur.id.uk.be.sl.et.lv.lt.tg."
"fa.vi.hy.az.eu.hsb.mk...tn..xh.zu.af.ka.fo.hi.mt.se.ga."
".ms.kk.ky.sw.tk.uz.tt.bn.pa.-in.gu.or.ta.te.kn.ml.as.mr.sa.mn.=mn.=mng"
"bo.cy.kh.lo..gl.kok..sd.syr.si..iu.am.tzm.ks.ne.fy.ps.fil."
"dv...ha..yo.quz.nso.ba.lb.kl.ig...ti.....ii."
".arn..moh..br..ug.mi.oc.co.gsw.sah.qut.rw.wo....prs.";
"ar.bg.ca.zh.-tw.-cn.cs.da.de.el.en.es.fi.fr.he.hu.is."
"it.ja.ko.nl.no.=nb.=nn.pl.pt.-br.rm.ro.ru.sr.=hr.-spl.-spc.sk.sq.sv.th.tr."
"ur.id.uk.be.sl.et.lv.lt.tg.fa.vi.hy.az.eu.hsb.mk."
"st.ts.tn.ve.xh.zu.af.ka.fo.hi.mt.se.ga.yi.ms.kk."
"ky.sw.tk.uz.tt.bn.pa.-in.gu.or.ta.te.kn.ml.as.mr.sa."
"mn.=mn.=mng.bo.cy.kh.lo.my.gl.kok..sd.syr.si..iu.am.tzm."
"ks.ne.fy.ps.tl.dv..ff.ha..yo.qu.st.ba.lb.kl."
"ig.kr.om.ti.gn..la.so.ii..arn..moh..br.."
"ug.mi.oc.co."
// "gsw.sah.qut.rw.wo....prs...."
// ".gd."
;
static void FindShortNames(UInt32 primeLang, UStringVector &names)
{
@@ -158,10 +163,10 @@ static void FindShortNames(UInt32 primeLang, UStringVector &names)
bool isSub = (p[0] == '-' || p[0] == '=');
if (!isSub)
index++;
if (index >= primeLang)
{
if (index > primeLang)
break;
if (index == primeLang)
{
UString s;
if (isSub)
{
@@ -178,6 +183,33 @@ static void FindShortNames(UInt32 primeLang, UStringVector &names)
}
}
/*
#include "../../../Common/IntToString.h"
static struct CC1Lang
{
CC1Lang()
{
for (int i = 1; i < 150; i++)
{
UString s;
char ttt[32];
ConvertUInt32ToHex(i, ttt);
s.AddAscii(ttt);
UStringVector names;
FindShortNames(i, names);
FOR_VECTOR (k, names)
{
s.Add_Space();
s += names[k];
}
OutputDebugStringW(s);
}
}
} g_cc1;
*/
// typedef LANGID (WINAPI *GetUserDefaultUILanguageP)();
static void OpenDefaultLang()

View File

@@ -18,7 +18,9 @@ bool CListViewDialog::OnInit()
#endif
_listView.Attach(GetItem(IDL_LISTVIEW));
if (ReadSingleClick())
CFmSettings st;
st.Load();
if (st.SingleClick)
_listView.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
SetText(Title);

View File

@@ -4,25 +4,34 @@
#include "../Common/ZipRegistry.h"
#include "../../../Windows/DLL.h"
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/FileFind.h"
#include "../Explorer/ContextMenuFlags.h"
#include "../Explorer/RegistryContextMenu.h"
#include "../Explorer/resource.h"
#include "../FileManager/PropertyNameRes.h"
#include "../GUI/ExtractDialogRes.h"
#include "FormatUtils.h"
#include "HelpUtils.h"
#include "LangUtils.h"
#include "MenuPage.h"
#include "MenuPageRes.h"
#include "FormatUtils.h"
#include "../FileManager/PropertyNameRes.h"
using namespace NWindows;
using namespace NContextMenuFlags;
static const UInt32 kLangIDs[] =
{
IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU,
IDX_SYSTEM_INTEGRATE_TO_MENU,
IDX_SYSTEM_CASCADED_MENU,
IDX_SYSTEM_ICON_IN_MENU,
IDX_EXTRACT_ELIM_DUP,
IDT_SYSTEM_CONTEXT_MENU_ITEMS
};
@@ -34,7 +43,7 @@ struct CContextMenuItem
UInt32 Flag;
};
static CContextMenuItem kMenuItems[] =
static const CContextMenuItem kMenuItems[] =
{
{ IDS_CONTEXT_OPEN, kOpen },
{ IDS_CONTEXT_OPEN, kOpenAs },
@@ -46,52 +55,135 @@ static CContextMenuItem kMenuItems[] =
{ IDS_CONTEXT_COMPRESS, kCompress },
{ IDS_CONTEXT_COMPRESS_TO, kCompressTo7z },
{ IDS_CONTEXT_COMPRESS_TO, kCompressToZip }
{ IDS_CONTEXT_COMPRESS_TO, kCompressToZip },
#ifndef UNDER_CE
,
{ IDS_CONTEXT_COMPRESS_EMAIL, kCompressEmail },
{ IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressTo7zEmail },
{ IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressToZipEmail }
{ IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressToZipEmail },
#endif
, { IDS_PROP_CHECKSUM, kCRC }
{ IDS_PROP_CHECKSUM, kCRC }
};
#if !defined(_WIN64)
extern bool g_Is_Wow64;
#endif
bool CMenuPage::OnInit()
{
_initMode = true;
Clear_MenuChanged();
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
#ifdef UNDER_CE
EnableItem(IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, false);
HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU);
HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU_2);
#else
CheckButton(IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, NZipRootRegistry::CheckContextMenuHandler());
{
UString s;
{
CWindow window(GetItem(IDX_SYSTEM_INTEGRATE_TO_MENU));
window.GetText(s);
}
UString bit64 = LangString(IDS_PROP_BIT64);
if (bit64.IsEmpty())
bit64.SetFromAscii("64-bit");
#ifdef _WIN64
bit64.Replace(L"64", L"32");
#endif
s.Add_Space();
s += L'(';
s += bit64;
s += L')';
SetItemText(IDX_SYSTEM_INTEGRATE_TO_MENU_2, s);
}
const FString prefix = NDLL::GetModuleDirPrefix();
_dlls[0].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU;
_dlls[1].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU_2;
_dlls[0].wow = 0;
_dlls[1].wow =
#ifdef _WIN64
KEY_WOW64_32KEY
#else
KEY_WOW64_64KEY
#endif
;
for (unsigned d = 0; d < 2; d++)
{
CShellDll &dll = _dlls[d];
dll.wasChanged = false;
#ifndef _WIN64
if (d != 0 && !g_Is_Wow64)
{
HideItem(dll.ctrl);
continue;
}
#endif
FString &path = dll.Path;
path = prefix;
path.AddAscii(d == 0 ? "7-zip.dll" :
#ifdef _WIN64
"7-zip32.dll"
#else
"7-zip64.dll"
#endif
);
if (!NFile::NFind::DoesFileExist(path))
{
path.Empty();
EnableItem(dll.ctrl, false);
}
else
{
dll.prevValue = CheckContextMenuHandler(fs2us(path), dll.wow);
CheckButton(dll.ctrl, dll.prevValue);
}
}
#endif
CContextMenuInfo ci;
ci.Load();
CheckButton(IDX_SYSTEM_CASCADED_MENU, ci.Cascaded);
CheckButton(IDX_SYSTEM_ICON_IN_MENU, ci.MenuIcons);
CheckButton(IDX_SYSTEM_CASCADED_MENU, ci.Cascaded.Val);
CheckButton(IDX_SYSTEM_ICON_IN_MENU, ci.MenuIcons.Val);
CheckButton(IDX_EXTRACT_ELIM_DUP, ci.ElimDup.Val);
_listView.Attach(GetItem(IDL_SYSTEM_OPTIONS));
UInt32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
const UInt32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
_listView.SetExtendedListViewStyle(newFlags, newFlags);
_listView.InsertColumn(0, L"", 100);
_listView.InsertColumn(0, L"", 200);
for (int i = 0; i < ARRAY_SIZE(kMenuItems); i++)
for (unsigned i = 0; i < ARRAY_SIZE(kMenuItems); i++)
{
CContextMenuItem &menuItem = kMenuItems[i];
const CContextMenuItem &menuItem = kMenuItems[i];
UString s = LangString(menuItem.ControlID);
if (menuItem.Flag == kCRC)
s = L"CRC SHA";
s.SetFromAscii("CRC SHA");
if (menuItem.Flag == kOpenAs ||
menuItem.Flag == kCRC)
s += L" >";
s.AddAscii(" >");
switch (menuItem.ControlID)
{
@@ -108,11 +200,11 @@ bool CMenuPage::OnInit()
{
case kCompressTo7z:
case kCompressTo7zEmail:
s2 += L".7z";
s2.AddAscii(".7z");
break;
case kCompressToZip:
case kCompressToZipEmail:
s2 += L".zip";
s2.AddAscii(".zip");
break;
}
s = MyFormatNew(s, s2);
@@ -126,40 +218,69 @@ bool CMenuPage::OnInit()
_listView.SetColumnWidthAuto(0);
_initMode = false;
return CPropertyPage::OnInit();
}
#ifndef UNDER_CE
STDAPI DllRegisterServer(void);
STDAPI DllUnregisterServer(void);
HWND g_MenuPageHWND = 0;
static void ShowMenuErrorMessage(const wchar_t *m, HWND hwnd)
{
MessageBoxW(hwnd, m, L"7-Zip", MB_ICONERROR);
}
#endif
LONG CMenuPage::OnApply()
{
#ifndef UNDER_CE
g_MenuPageHWND = *this;
if (IsButtonCheckedBool(IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU))
for (unsigned d = 2; d != 0;)
{
DllRegisterServer();
NZipRootRegistry::AddContextMenuHandler();
}
else
d--;
CShellDll &dll = _dlls[d];
if (dll.wasChanged && !dll.Path.IsEmpty())
{
DllUnregisterServer();
NZipRootRegistry::DeleteContextMenuHandler();
bool newVal = IsButtonCheckedBool(dll.ctrl);
LONG res = SetContextMenuHandler(newVal, fs2us(dll.Path), dll.wow);
if (res != ERROR_SUCCESS && (dll.prevValue != newVal || newVal))
ShowMenuErrorMessage(NError::MyFormatMessage(res), *this);
dll.prevValue = CheckContextMenuHandler(fs2us(dll.Path), dll.wow);
CheckButton(dll.ctrl, dll.prevValue);
dll.wasChanged = false;
}
}
#endif
if (_cascaded_Changed || _menuIcons_Changed || _elimDup_Changed || _flags_Changed)
{
CContextMenuInfo ci;
ci.Cascaded = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU);
ci.MenuIcons = IsButtonCheckedBool(IDX_SYSTEM_ICON_IN_MENU);
ci.Cascaded.Val = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU);
ci.Cascaded.Def = _cascaded_Changed;
ci.MenuIcons.Val = IsButtonCheckedBool(IDX_SYSTEM_ICON_IN_MENU);
ci.MenuIcons.Def = _menuIcons_Changed;
ci.ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP);
ci.ElimDup.Def = _elimDup_Changed;
ci.Flags = 0;
for (int i = 0; i < ARRAY_SIZE(kMenuItems); i++)
for (unsigned i = 0; i < ARRAY_SIZE(kMenuItems); i++)
if (_listView.GetCheckState(i))
ci.Flags |= kMenuItems[i].Flag;
ci.Flags_Def = _flags_Changed;
ci.Save();
Clear_MenuChanged();
}
// UnChanged();
return PSNRET_NOERROR;
}
@@ -172,15 +293,31 @@ bool CMenuPage::OnButtonClicked(int buttonID, HWND buttonHWND)
{
switch (buttonID)
{
case IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU:
case IDX_SYSTEM_CASCADED_MENU:
case IDX_SYSTEM_ICON_IN_MENU:
#ifndef UNDER_CE
case IDX_SYSTEM_INTEGRATE_TO_MENU:
case IDX_SYSTEM_INTEGRATE_TO_MENU_2:
{
for (unsigned d = 0; d < 2; d++)
{
CShellDll &dll = _dlls[d];
if (buttonID == dll.ctrl && !dll.Path.IsEmpty())
dll.wasChanged = true;
}
break;
}
#endif
case IDX_SYSTEM_CASCADED_MENU: _cascaded_Changed = true; break;
case IDX_SYSTEM_ICON_IN_MENU: _menuIcons_Changed = true; break;
case IDX_EXTRACT_ELIM_DUP: _elimDup_Changed = true; break;
default:
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}
Changed();
return true;
}
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}
bool CMenuPage::OnNotify(UINT controlID, LPNMHDR lParam)
{
@@ -205,7 +342,10 @@ bool CMenuPage::OnItemChanged(const NMLISTVIEW *info)
UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK;
UINT newState = info->uNewState & LVIS_STATEIMAGEMASK;
if (oldState != newState)
{
_flags_Changed = true;
Changed();
}
}
return true;
}

View File

@@ -6,11 +6,38 @@
#include "../../../Windows/Control/PropertyPage.h"
#include "../../../Windows/Control/ListView.h"
#include "../Common/LoadCodecs.h"
struct CShellDll
{
FString Path;
bool wasChanged;
bool prevValue;
int ctrl;
UInt32 wow;
CShellDll(): wasChanged (false), prevValue(false), ctrl(0), wow(0) {}
};
class CMenuPage: public NWindows::NControl::CPropertyPage
{
bool _initMode;
bool _cascaded_Changed;
bool _menuIcons_Changed;
bool _elimDup_Changed;
bool _flags_Changed;
void Clear_MenuChanged()
{
_cascaded_Changed = false;
_menuIcons_Changed = false;
_elimDup_Changed = false;
_flags_Changed = false;
}
#ifndef UNDER_CE
CShellDll _dlls[2];
#endif
NWindows::NControl::CListView _listView;
virtual bool OnInit();

View File

@@ -2,7 +2,7 @@
#include "../../GuiCommon.rc"
#define xc 240
#define yc 196
#define yc 224
IDD_MENU MY_PAGE
#include "MenuPage2.rc"

View File

@@ -1,12 +1,16 @@
#define y 54
#include "../GUI/ExtractDialogRes.h"
#define y 82
CAPTION "7-Zip"
BEGIN
CONTROL "Integrate 7-Zip to shell context menu", IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, MY_CHECKBOX, m, m, xc, 10
CONTROL "Cascaded context menu", IDX_SYSTEM_CASCADED_MENU, MY_CHECKBOX, m, m + 14, xc, 10
CONTROL "Icons in context menu", IDX_SYSTEM_ICON_IN_MENU, MY_CHECKBOX, m, m + 28, xc, 10
CONTROL "Integrate 7-Zip to shell context menu", IDX_SYSTEM_INTEGRATE_TO_MENU, MY_CHECKBOX, m, m, xc, 10
CONTROL "(32-bit)", IDX_SYSTEM_INTEGRATE_TO_MENU_2, MY_CHECKBOX, m, m + 14, xc, 10
CONTROL "Cascaded context menu", IDX_SYSTEM_CASCADED_MENU, MY_CHECKBOX, m, m + 28, xc, 10
CONTROL "Icons in context menu", IDX_SYSTEM_ICON_IN_MENU, MY_CHECKBOX, m, m + 42, xc, 10
CONTROL "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, MY_CHECKBOX, m, m + 56, xc, 10
LTEXT "Context menu items:", IDT_SYSTEM_CONTEXT_MENU_ITEMS, m, m + 42, xc, 8
LTEXT "Context menu items:", IDT_SYSTEM_CONTEXT_MENU_ITEMS, m, m + 70, xc, 8
CONTROL "List", IDL_SYSTEM_OPTIONS, "SysListView32",
LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,
m, m + y, xc, yc - y

View File

@@ -1,9 +1,11 @@
#define IDD_MENU 2300
#define IDD_MENU_2 12300
#define IDX_SYSTEM_INTEGRATE_TO_CONTEXT_MENU 2301
#define IDX_SYSTEM_INTEGRATE_TO_MENU 2301
#define IDX_SYSTEM_CASCADED_MENU 2302
#define IDT_SYSTEM_CONTEXT_MENU_ITEMS 2303
#define IDX_SYSTEM_ICON_IN_MENU 2304
#define IDX_SYSTEM_INTEGRATE_TO_MENU_2 2310
#define IDL_SYSTEM_OPTIONS 100

View File

@@ -512,6 +512,7 @@ bool OnMenuCommand(HWND hWnd, int id)
// File
case IDCLOSE:
SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
g_ExitEventLauncher.Exit(false);
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;

View File

@@ -6,6 +6,7 @@
#include "../../../Windows/Control/PropertyPage.h"
#include "DialogSize.h"
#include "EditPage.h"
#include "EditPageRes.h"
#include "FoldersPage.h"
@@ -14,8 +15,6 @@
#include "LangPageRes.h"
#include "MenuPage.h"
#include "MenuPageRes.h"
// #include "PluginsPage.h"
// #include "PluginsPageRes.h"
#include "SettingsPage.h"
#include "SettingsPageRes.h"
#include "SystemPage.h"
@@ -29,90 +28,38 @@
using namespace NWindows;
#ifndef UNDER_CE
typedef UINT32 (WINAPI * DllRegisterServerPtr)();
extern HWND g_MenuPageHWND;
static void ShowMenuErrorMessage(const wchar_t *m)
{
MessageBoxW(g_MenuPageHWND, m, L"7-Zip", MB_ICONERROR);
}
static int DllRegisterServer2(const char *name)
{
NDLL::CLibrary lib;
FString prefix = NDLL::GetModuleDirPrefix();
if (!lib.Load(prefix + FTEXT("7-zip.dll")))
{
ShowMenuErrorMessage(L"7-Zip cannot load 7-zip.dll");
return E_FAIL;
}
DllRegisterServerPtr f = (DllRegisterServerPtr)lib.GetProc(name);
if (f == NULL)
{
ShowMenuErrorMessage(L"Incorrect plugin");
return E_FAIL;
}
HRESULT res = f();
if (res != S_OK)
ShowMenuErrorMessage(HResultToMessage(res));
return (int)res;
}
STDAPI DllRegisterServer(void)
{
#ifdef UNDER_CE
return S_OK;
#else
return DllRegisterServer2("DllRegisterServer");
#endif
}
STDAPI DllUnregisterServer(void)
{
#ifdef UNDER_CE
return S_OK;
#else
return DllRegisterServer2("DllUnregisterServer");
#endif
}
#endif
void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */)
{
CSystemPage systemPage;
// CPluginsPage pluginsPage;
CMenuPage menuPage;
CFoldersPage foldersPage;
CEditPage editPage;
CSettingsPage settingsPage;
CLangPage langPage;
CMenuPage menuPage;
CFoldersPage foldersPage;
CObjectVector<NControl::CPageInfo> pages;
BIG_DIALOG_SIZE(200, 200);
UINT pageIDs[] = {
const UINT pageIDs[] = {
SIZED_DIALOG(IDD_SYSTEM),
SIZED_DIALOG(IDD_MENU),
SIZED_DIALOG(IDD_FOLDERS),
SIZED_DIALOG(IDD_EDIT),
SIZED_DIALOG(IDD_SETTINGS),
SIZED_DIALOG(IDD_LANG) };
NControl::CPropertyPage *pagePinters[] = { &systemPage, &menuPage, &foldersPage, &editPage, &settingsPage, &langPage };
const int kNumPages = ARRAY_SIZE(pageIDs);
for (int i = 0; i < kNumPages; i++)
NControl::CPropertyPage *pagePointers[] = { &systemPage, &menuPage, &foldersPage, &editPage, &settingsPage, &langPage };
for (unsigned i = 0; i < ARRAY_SIZE(pageIDs); i++)
{
NControl::CPageInfo page;
NControl::CPageInfo &page = pages.AddNew();
page.ID = pageIDs[i];
LangString_OnlyFromLangFile(page.ID, page.Title);
page.Page = pagePinters[i];
pages.Add(page);
page.Page = pagePointers[i];
}
INT_PTR res = NControl::MyPropertySheet(pages, hwndOwner, LangString(IDS_OPTIONS));
if (res != -1 && res != 0)
{
if (langPage.LangWasChanged)
@@ -120,9 +67,10 @@ void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */)
// g_App._window.SetText(LangString(IDS_APP_TITLE, 0x03000000));
MyLoadMenu();
g_App.ReloadToolbars();
g_App.MoveSubWindows();
g_App.MoveSubWindows(); // we need it to change list window aafter _toolBar.AutoSize();
g_App.ReloadLang();
}
/*
if (systemPage.WasChanged)
{
@@ -130,8 +78,8 @@ void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */)
g_App.SysIconsWereChanged();
}
*/
g_App.SetListSettings();
g_App.SetShowSystemMenu();
g_App.RefreshAllPanels();
// ::PostMessage(hwndOwner, kLangWasChangedMessage, 0 , 0);
}

View File

@@ -841,4 +841,28 @@ public:
~CMyBuffer() { ::MidFree(_data); }
};
class CExitEventLauncher
{
public:
NWindows::NSynchronization::CManualResetEvent _exitEvent;
bool _needExit;
CRecordVector< ::CThread > _threads;
unsigned _numActiveThreads;
CExitEventLauncher()
{
_needExit = false;
if (_exitEvent.Create(false) != S_OK)
throw 9387173;
_needExit = true;
_numActiveThreads = 0;
};
~CExitEventLauncher() { Exit(true); }
void Exit(bool hardExit);
};
extern CExitEventLauncher g_ExitEventLauncher;
#endif

View File

@@ -209,7 +209,23 @@ STDMETHODIMP CDropSource::QueryContinueDrag(BOOL escapePressed, DWORD keyState)
{
CCopyToOptions options;
options.folder = Folder;
// 15.13: fixed problem with mouse cursor for password window.
// DoDragDrop() probably calls SetCapture() to some hidden window.
// But it's problem, if we show some modal window, like MessageBox.
// So we return capture to our window.
// If you know better way to solve the problem, please notify 7-Zip developer.
// MessageBoxW(*Panel, L"test", L"test", 0);
/* HWND oldHwnd = */ SetCapture(*Panel);
Result = Panel->CopyTo(options, Indices, &Messages);
// do we need to restore capture?
// ReleaseCapture();
// oldHwnd = SetCapture(oldHwnd);
if (Result != S_OK || !Messages.IsEmpty())
return DRAGDROP_S_CANCEL;
}
@@ -357,10 +373,14 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
effectsOK |= DROPEFFECT_MOVE;
DWORD effect;
_panelCallback->DragBegin();
HRESULT res = DoDragDrop(dataObject, dropSource, effectsOK, &effect);
_panelCallback->DragEnd();
bool canceled = (res == DRAGDROP_S_CANCEL);
CDisableNotify disableNotify(*this);
if (res == DRAGDROP_S_DROP)
{
res = dropSourceSpec->Result;

View File

@@ -6,6 +6,8 @@
#include <tlhelp32.h>
#include "../../../Common/IntToString.h"
#include "../../../Common/AutoPtr.h"
#include "../../../Common/StringConvert.h"
@@ -24,6 +26,7 @@
#include "FileFolderPluginOpen.h"
#include "FormatUtils.h"
#include "LangUtils.h"
#include "PropertyNameRes.h"
#include "RegistryUtils.h"
#include "UpdateCallback100.h"
@@ -45,6 +48,20 @@ extern bool g_IsNT;
static CFSTR kTempDirPrefix = FTEXT("7zO");
// #define SHOW_DEBUG_INFO
#ifdef SHOW_DEBUG_INFO
#define DEBUG_PRINT(s) OutputDebugStringA(s);
#define DEBUG_PRINT_W(s) OutputDebugStringW(s);
#define DEBUG_PRINT_NUM(s, num) { char ttt[32]; ConvertUInt32ToString(num, ttt); OutputDebugStringA(s); OutputDebugStringA(ttt); }
#else
#define DEBUG_PRINT(s)
#define DEBUG_PRINT_W(s)
#define DEBUG_PRINT_NUM(s, num)
#endif
#ifndef UNDER_CE
class CProcessSnapshot
@@ -76,17 +93,206 @@ public:
#endif
typedef DWORD (WINAPI *GetProcessIdFunc)(HANDLE process);
/*
struct COpenExtProg
{
const char *Ext;
const char *Prog;
};
static const COpenExtProg g_Progs[] =
{
{ "jpeg jpg png bmp gif", "Microsoft.Photos.exe" },
{ "html htm pdf", "MicrosoftEdge.exe" },
// , { "rrr", "notepad.exe" }
};
static bool FindExtProg(const char *exts, const char *ext)
{
unsigned len = (unsigned)strlen(ext);
for (;;)
{
const char *p = exts;
for (;; p++)
{
const char c = *p;
if (c == 0 || c == ' ')
break;
}
if (len == (unsigned)(p - exts) && IsString1PrefixedByString2(exts, ext))
return true;
if (*p == 0)
return false;
exts = p + 1;
}
}
class CPossibleProgs
{
public:
AStringVector ProgNames;
void SetFromExtension(const char *ext) // ext must be low case
{
ProgNames.Clear();
for (unsigned i = 0; i < ARRAY_SIZE(g_Progs); i++)
if (FindExtProg(g_Progs[i].Ext, ext))
{
ProgNames.Add(g_Progs[i].Prog);
}
}
bool IsFromList(const UString &progName) const
{
FOR_VECTOR (i, ProgNames)
if (progName.IsEqualTo_Ascii_NoCase(ProgNames[i]))
return true;
return false;
}
};
*/
#ifndef UNDER_CE
EXTERN_C_BEGIN
/*
GetProcessImageFileName
returns the path in device form, rather than drive letters:
\Device\HarddiskVolume1\WINDOWS\SysWOW64\notepad.exe
GetModuleFileNameEx works only after Sleep(something). Why?
returns the path
C:\WINDOWS\system32\NOTEPAD.EXE
*/
/* Kernel32.dll: Win7, Win2008R2;
Psapi.dll: (if PSAPI_VERSION=1) on Win7 and Win2008R2;
Psapi.dll: XP, Win2003, Vista, 2008;
*/
typedef DWORD (WINAPI *Func_GetProcessImageFileNameW)(
HANDLE hProcess, LPWSTR lpFilename, DWORD nSize);
typedef DWORD (WINAPI *Func_GetModuleFileNameExW)(
HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize);
typedef DWORD (WINAPI *Func_GetProcessId)(HANDLE process);
EXTERN_C_END
static HMODULE g_Psapi_dll_module;
/*
static void My_GetProcessFileName_2(HANDLE hProcess, UString &path)
{
path.Empty();
const unsigned maxPath = 1024;
WCHAR temp[maxPath + 1];
const char *func_name = "GetModuleFileNameExW";
Func_GetModuleFileNameExW my_func = (Func_GetModuleFileNameExW)
::GetProcAddress(::GetModuleHandleA("kernel32.dll"), func_name);
if (!my_func)
{
if (!g_Psapi_dll_module)
g_Psapi_dll_module = LoadLibraryW(L"Psapi.dll");
if (g_Psapi_dll_module)
my_func = (Func_GetModuleFileNameExW)::GetProcAddress(g_Psapi_dll_module, func_name);
}
if (my_func)
{
// DWORD num = GetModuleFileNameEx(hProcess, NULL, temp, maxPath);
DWORD num = my_func(hProcess, NULL, temp, maxPath);
if (num != 0)
path = temp;
}
// FreeLibrary(lib);
}
*/
static void My_GetProcessFileName(HANDLE hProcess, UString &path)
{
path.Empty();
const unsigned maxPath = 1024;
WCHAR temp[maxPath + 1];
const char *func_name = "GetProcessImageFileNameW";
Func_GetProcessImageFileNameW my_func = (Func_GetProcessImageFileNameW)
::GetProcAddress(::GetModuleHandleA("kernel32.dll"), func_name);
if (!my_func)
{
if (!g_Psapi_dll_module)
g_Psapi_dll_module = LoadLibraryW(L"Psapi.dll");
if (g_Psapi_dll_module)
my_func = (Func_GetProcessImageFileNameW)::GetProcAddress(g_Psapi_dll_module, func_name);
}
if (my_func)
{
// DWORD num = GetProcessImageFileNameW(hProcess, temp, maxPath);
DWORD num = my_func(hProcess, temp, maxPath);
if (num != 0)
path = temp;
}
// FreeLibrary(lib);
}
struct CSnapshotProcess
{
DWORD Id;
DWORD ParentId;
UString Name;
};
static void GetSnapshot(CObjectVector<CSnapshotProcess> &items)
{
items.Clear();
CProcessSnapshot snapshot;
if (!snapshot.Create())
return;
DEBUG_PRINT("snapshot.Create() OK");
PROCESSENTRY32 pe;
CSnapshotProcess item;
memset(&pe, 0, sizeof(pe));
pe.dwSize = sizeof(pe);
BOOL res = snapshot.GetFirstProcess(&pe);
while (res)
{
item.Id = pe.th32ProcessID;
item.ParentId = pe.th32ParentProcessID;
item.Name = GetUnicodeString(pe.szExeFile);
items.Add(item);
res = snapshot.GetNextProcess(&pe);
}
}
#endif
class CChildProcesses
{
#ifndef UNDER_CE
CRecordVector<DWORD> _ids;
#endif
public:
// bool ProgsWereUsed;
CRecordVector<HANDLE> Handles;
CRecordVector<bool> NeedWait;
// UStringVector Names;
#ifndef UNDER_CE
UString Path;
#endif
// CChildProcesses(): ProgsWereUsed(false) {}
~CChildProcesses() { CloseAll(); }
void DisableWait(unsigned index) { NeedWait[index] = false; }
@@ -98,68 +304,118 @@ public:
if (h != NULL)
CloseHandle(h);
}
Handles.Clear();
NeedWait.Clear();
// Names.Clear();
#ifndef UNDER_CE
// Path.Empty();
_ids.Clear();
#endif
}
void AddProcess(HANDLE h)
void SetMainProcess(HANDLE h)
{
#ifndef UNDER_CE
GetProcessIdFunc func = (GetProcessIdFunc)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "GetProcessId");
Func_GetProcessId func = (Func_GetProcessId)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "GetProcessId");
if (func)
_ids.AddToUniqueSorted(func(h));
{
DWORD id = func(h);
if (id != 0)
_ids.AddToUniqueSorted(id);
}
My_GetProcessFileName(h, Path);
DEBUG_PRINT_W(Path);
#endif
Handles.Add(h);
NeedWait.Add(true);
}
void Update()
{
#ifndef UNDER_CE
CRecordVector<DWORD> ids, parents;
void Update(bool needFindProcessByPath /* , const CPossibleProgs &progs */)
{
CProcessSnapshot snapshot;
if (snapshot.Create())
/*
if (_ids.IsEmpty())
return;
*/
CObjectVector<CSnapshotProcess> sps;
GetSnapshot(sps);
const int separ = Path.ReverseFind_PathSepar();
const UString mainName = Path.Ptr(separ + 1);
if (mainName.IsEmpty())
needFindProcessByPath = false;
const DWORD currentProcessId = GetCurrentProcessId();
for (;;)
{
PROCESSENTRY32 pe;
memset(&pe, 0, sizeof(pe));
pe.dwSize = sizeof(pe);
BOOL res = snapshot.GetFirstProcess(&pe);
while (res)
bool wasAdded = false;
FOR_VECTOR (i, sps)
{
ids.Add(pe.th32ProcessID);
parents.Add(pe.th32ParentProcessID);
res = snapshot.GetNextProcess(&pe);
const CSnapshotProcess &sp = sps[i];
const DWORD id = sp.Id;
if (id == currentProcessId)
continue;
if (_ids.FindInSorted(id) >= 0)
continue;
bool isSameName = false;
const UString &name = sp.Name;
if (needFindProcessByPath)
isSameName = mainName.IsEqualTo_NoCase(name);
bool needAdd = false;
// bool isFromProgs = false;
if (isSameName || _ids.FindInSorted(sp.ParentId) >= 0)
needAdd = true;
/*
else if (progs.IsFromList(name))
{
needAdd = true;
isFromProgs = true;
}
*/
if (needAdd)
{
DEBUG_PRINT("----- OpenProcess -----");
DEBUG_PRINT_W(name);
HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, id);
if (hProcess)
{
DEBUG_PRINT("----- OpenProcess OK -----");
// if (!isFromProgs)
_ids.AddToUniqueSorted(id);
Handles.Add(hProcess);
NeedWait.Add(true);
// Names.Add(name);
wasAdded = true;
// ProgsWereUsed = isFromProgs;
}
}
}
for (;;)
{
unsigned i;
for (i = 0; i < ids.Size(); i++)
{
DWORD id = ids[i];
if (_ids.FindInSorted(parents[i]) >= 0 &&
_ids.FindInSorted(id) < 0)
{
HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, id);
if (hProcess)
{
_ids.AddToUniqueSorted(id);
Handles.Add(hProcess);
NeedWait.Add(true);
if (!wasAdded)
break;
}
}
}
if (i == ids.Size())
break;
}
#endif
}
};
struct CTmpProcessInfo: public CTempFileInfo
{
CChildProcesses Processes;
@@ -168,9 +424,12 @@ struct CTmpProcessInfo: public CTempFileInfo
bool UsePassword;
UString Password;
CTmpProcessInfo(): UsePassword(false) {}
bool ReadOnly;
CTmpProcessInfo(): UsePassword(false), ReadOnly(false) {}
};
class CTmpProcessInfoRelease
{
CTmpProcessInfo *_tmpProcessInfo;
@@ -600,6 +859,9 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi
process.Attach(execInfo.hProcess);
}
DEBUG_PRINT_NUM("-- ShellExecuteEx -- execInfo.hInstApp = ", result)
if (result <= 32)
{
switch (result)
@@ -610,6 +872,8 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi
// L"There is no application associated with the given file name extension",
L"7-Zip", MB_OK | MB_ICONSTOP);
}
return E_FAIL; // fixed in 15.13. Can we use it for any Windows version?
}
return S_OK;
@@ -800,6 +1064,8 @@ HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
{
// DEBUG_PRINT_NUM("OnOpenItemChanged", GetCurrentThreadId());
CTmpProcessInfo &tpi = *(CTmpProcessInfo *)lParam;
if (tpi.FullPathFolderPrefix != _currentFolderPrefix)
return 0;
@@ -834,24 +1100,75 @@ LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
return 1;
}
class CExitEventLauncher
CExitEventLauncher g_ExitEventLauncher;
void CExitEventLauncher::Exit(bool hardExit)
{
public:
NWindows::NSynchronization::CManualResetEvent _exitEvent;
CExitEventLauncher()
if (_needExit)
{
if (_exitEvent.Create(false) != S_OK)
throw 9387173;
};
~CExitEventLauncher() { _exitEvent.Set(); }
} g_ExitEventLauncher;
_exitEvent.Set();
_needExit = false;
}
if (_numActiveThreads == 0)
return;
FOR_VECTOR (i, _threads)
{
::CThread &th = _threads[i];
DWORD wait = (hardExit ? 100 : INFINITE);
if (Thread_WasCreated(&th))
{
DWORD waitResult = WaitForSingleObject(th, wait);
// Thread_Wait(&th);
if (waitResult == WAIT_TIMEOUT)
wait = 1;
if (!hardExit && waitResult != WAIT_OBJECT_0)
continue;
Thread_Close(&th);
_numActiveThreads--;
}
}
}
static THREAD_FUNC_DECL MyThreadFunction(void *param)
{
DEBUG_PRINT("==== MyThreadFunction ====");
CMyAutoPtr<CTmpProcessInfo> tmpProcessInfoPtr((CTmpProcessInfo *)param);
CTmpProcessInfo *tpi = tmpProcessInfoPtr.get();
CChildProcesses &processes = tpi->Processes;
bool mainProcessWasSet = !processes.Handles.IsEmpty();
bool isComplexMode = true;
if (!processes.Handles.IsEmpty())
{
const DWORD startTime = GetTickCount();
/*
CPossibleProgs progs;
{
const UString &name = tpi->RelPath;
int slashPos = name.ReverseFind_PathSepar();
int dotPos = name.ReverseFind_Dot();
if (dotPos > slashPos)
{
const UString ext = name.Ptr(dotPos + 1);
AString extA = UnicodeStringToMultiByte(ext);
extA.MakeLower_Ascii();
progs.SetFromExtension(extA);
}
}
*/
bool firstPass = true;
for (;;)
{
CRecordVector<HANDLE> handles;
@@ -859,6 +1176,8 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
FOR_VECTOR (i, processes.Handles)
{
if (handles.Size() > 60)
break;
if (processes.NeedWait[i])
{
handles.Add(processes.Handles[i]);
@@ -866,43 +1185,150 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
}
}
if (handles.IsEmpty())
break;
bool needFindProcessByPath = false;
if (handles.IsEmpty())
{
if (!firstPass)
break;
}
else
{
handles.Add(g_ExitEventLauncher._exitEvent);
DWORD waitResult = ::WaitForMultipleObjects(handles.Size(), &handles.Front(), FALSE, INFINITE);
if (waitResult >= (DWORD)handles.Size() - 1)
waitResult -= WAIT_OBJECT_0;
if (waitResult >= handles.Size() - 1)
{
processes.CloseAll();
/*
if (waitResult == handles.Size() - 1)
{
// exit event
// we want to delete temp files, if progs were used
if (processes.ProgsWereUsed)
break;
}
*/
return waitResult >= (DWORD)handles.Size() ? 1 : 0;
}
processes.Update();
if (firstPass && indices.Size() == 1)
{
DWORD curTime = GetTickCount() - startTime;
/*
if (curTime > 5 * 1000)
progs.ProgNames.Clear();
*/
needFindProcessByPath = (curTime < 2 * 1000);
if (needFindProcessByPath)
{
NFind::CFileInfo newFileInfo;
if (newFileInfo.Find(tpi->FilePath))
if (tpi->WasChanged(newFileInfo))
needFindProcessByPath = false;
}
DEBUG_PRINT_NUM(" -- firstPass -- time = ", curTime)
}
processes.DisableWait(indices[waitResult]);
}
firstPass = false;
// Sleep(300);
#ifndef UNDER_CE
processes.Update(needFindProcessByPath /* , progs */);
#endif
}
DWORD curTime = GetTickCount() - startTime;
DEBUG_PRINT_NUM("after time = ", curTime)
processes.CloseAll();
isComplexMode = (curTime < 2 * 1000);
}
bool needCheckTimestamp = true;
for (;;)
{
NFind::CFileInfo newFileInfo;
if (newFileInfo.Find(tpi->FilePath))
if (!newFileInfo.Find(tpi->FilePath))
break;
if (mainProcessWasSet)
{
if (tpi->WasChanged(newFileInfo))
{
UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, tpi->RelPath);
UString m = MyFormatNew(IDS_CANNOT_UPDATE_FILE, fs2us(tpi->FilePath));
if (tpi->ReadOnly)
{
m.Add_LF();
AddLangString(m, IDS_PROP_READ_ONLY);
m.Add_LF();
m += tpi->FullPathFolderPrefix;
::MessageBoxW(g_HWND, m, L"7-Zip", MB_OK | MB_ICONSTOP);
return 0;
}
{
const UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, tpi->RelPath);
if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
{
// DEBUG_PRINT_NUM("SendMessage", GetCurrentThreadId());
if (SendMessage(tpi->Window, kOpenItemChanged, 0, (LONG_PTR)tpi) != 1)
{
::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE,
fs2us(tpi->FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP);
::MessageBoxW(g_HWND, m, L"7-Zip", MB_OK | MB_ICONSTOP);
return 0;
}
}
needCheckTimestamp = false;
break;
}
}
if (!isComplexMode)
break;
}
// DEBUG_PRINT("WaitForSingleObject");
DWORD waitResult = ::WaitForSingleObject(g_ExitEventLauncher._exitEvent, INFINITE);
// DEBUG_PRINT("---");
if (waitResult == WAIT_OBJECT_0)
break;
return 1;
}
{
NFind::CFileInfo newFileInfo;
bool finded = newFileInfo.Find(tpi->FilePath);
if (!needCheckTimestamp || !finded || !tpi->WasChanged(newFileInfo))
{
DEBUG_PRINT("Delete Temp file");
tpi->DeleteDirAndFile();
}
}
return 0;
}
#if defined(_WIN32) && !defined(UNDER_CE)
static const FChar *k_ZoneId_StreamName = FTEXT(":Zone.Identifier");
#endif
@@ -1284,6 +1710,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
tpi->NeedDelete = true;
tpi->UsePassword = usePassword;
tpi->Password = password;
tpi->ReadOnly = IsThereReadOnlyFolder();
if (!tpi->FileInfo.Find(tempFilePath))
return;
@@ -1291,29 +1718,41 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
CTmpProcessInfoRelease tmpProcessInfoRelease(*tpi);
CProcess process;
// HRESULT res;
HRESULT res;
if (editMode)
/* res = */ StartEditApplication(fs2us(tempFilePath), useEditor, (HWND)*this, process);
res = StartEditApplication(fs2us(tempFilePath), useEditor, (HWND)*this, process);
else
/* res = */ StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process);
res = StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process);
if ((HANDLE)process == 0)
if ((HANDLE)process == NULL)
{
// win7 / win10 work so for some extensions (pdf, html ..);
DEBUG_PRINT("#### (HANDLE)process == 0");
// return;
if (res != SZ_OK)
return;
}
tpi->Window = (HWND)(*this);
tpi->FullPathFolderPrefix = _currentFolderPrefix;
tpi->FileIndex = index;
tpi->RelPath = relPath;
tpi->Processes.AddProcess(process.Detach());
NWindows::CThread thread;
if (thread.Create(MyThreadFunction, tpi) != S_OK)
if ((HANDLE)process != 0)
tpi->Processes.SetMainProcess(process.Detach());
::CThread th;
if (Thread_Create(&th, MyThreadFunction, tpi) != 0)
throw 271824;
g_ExitEventLauncher._threads.Add(th);
g_ExitEventLauncher._numActiveThreads++;
tempDirectory.DisableDeleting();
tmpProcessInfoPtr.release();
tmpProcessInfoRelease._needDelete = false;
}
/*
static const UINT64 kTimeLimit = UINT64(10000000) * 3600 * 24;

View File

@@ -1097,6 +1097,7 @@ void CPanel::SaveListViewInfo()
viewInfo.SortID = sortPropID;
viewInfo.Ascending = _ascending;
viewInfo.IsLoaded = true;
if (!_listViewInfo.IsEqual(viewInfo))
{
viewInfo.Save(_typeIDString);

View File

@@ -18,7 +18,7 @@ struct CVKeyPropIDPair
PROPID PropID;
};
static CVKeyPropIDPair g_VKeyPropIDPairs[] =
static const CVKeyPropIDPair g_VKeyPropIDPairs[] =
{
{ VK_F3, kpidName },
{ VK_F4, kpidExtension },

View File

@@ -18,21 +18,24 @@ static const TCHAR *kCU_FMPath = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("F
// static const TCHAR *kLM_Path = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM");
static const WCHAR *kLangValueName = L"Lang";
static const WCHAR *kViewer = L"Viewer";
static const WCHAR *kEditor = L"Editor";
static const WCHAR *kDiff = L"Diff";
static const TCHAR *kShowDots = TEXT("ShowDots");
static const TCHAR *kShowRealFileIcons = TEXT("ShowRealFileIcons");
static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu");
static const TCHAR *kFullRow = TEXT("FullRow");
static const TCHAR *kShowGrid = TEXT("ShowGrid");
static const TCHAR *kAlternativeSelection = TEXT("AlternativeSelection");
// static const TCHAR *kLockMemoryAdd = TEXT("LockMemoryAdd");
static const TCHAR *kLargePagesEnable = TEXT("LargePages");
static const TCHAR *kSingleClick = TEXT("SingleClick");
static const TCHAR *kAlternativeSelection = TEXT("AlternativeSelection");
// static const TCHAR *kUnderline = TEXT("Underline");
static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu");
// static const TCHAR *kLockMemoryAdd = TEXT("LockMemoryAdd");
static const TCHAR *kLargePages = TEXT("LargePages");
static const TCHAR *kFlatViewName = TEXT("FlatViewArc");
// static const TCHAR *kShowDeletedFiles = TEXT("ShowDeleted");
@@ -86,16 +89,11 @@ static bool Read7ZipOption(const TCHAR *value, bool defaultValue)
return defaultValue;
}
static bool ReadOption(const TCHAR *value, bool defaultValue)
static void ReadOption(CKey &key, const TCHAR *value, bool &dest)
{
CKey key;
if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS)
{
bool enabled;
bool enabled = false;
if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
return enabled;
}
return defaultValue;
dest = enabled;
}
/*
@@ -119,37 +117,52 @@ static bool ReadLmOption(const TCHAR *value, bool defaultValue)
}
*/
void SaveShowDots(bool showDots) { SaveOption(kShowDots, showDots); }
bool ReadShowDots() { return ReadOption(kShowDots, false); }
void CFmSettings::Save() const
{
SaveOption(kShowDots, ShowDots);
SaveOption(kShowRealFileIcons, ShowRealFileIcons);
SaveOption(kFullRow, FullRow);
SaveOption(kShowGrid, ShowGrid);
SaveOption(kSingleClick, SingleClick);
SaveOption(kAlternativeSelection, AlternativeSelection);
// SaveOption(kUnderline, Underline);
void SaveShowRealFileIcons(bool show) { SaveOption(kShowRealFileIcons, show); }
bool ReadShowRealFileIcons() { return ReadOption(kShowRealFileIcons, false); }
SaveOption(kShowSystemMenu, ShowSystemMenu);
}
void Save_ShowSystemMenu(bool show) { SaveOption(kShowSystemMenu, show); }
bool Read_ShowSystemMenu(){ return ReadOption(kShowSystemMenu, false); }
void CFmSettings::Load()
{
ShowDots = false;
ShowRealFileIcons = false;
FullRow = false;
ShowGrid = false;
SingleClick = false;
AlternativeSelection = false;
// Underline = false;
void SaveFullRow(bool enable) { SaveOption(kFullRow, enable); }
bool ReadFullRow() { return ReadOption(kFullRow, false); }
ShowSystemMenu = false;
void SaveShowGrid(bool enable) { SaveOption(kShowGrid, enable); }
bool ReadShowGrid(){ return ReadOption(kShowGrid, false); }
CKey key;
if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS)
{
ReadOption(key, kShowDots, ShowDots);
ReadOption(key, kShowRealFileIcons, ShowRealFileIcons);
ReadOption(key, kFullRow, FullRow);
ReadOption(key, kShowGrid, ShowGrid);
ReadOption(key, kSingleClick, SingleClick);
ReadOption(key, kAlternativeSelection, AlternativeSelection);
// ReadOption(key, kUnderline, Underline);
void SaveAlternativeSelection(bool enable) { SaveOption(kAlternativeSelection, enable); }
bool ReadAlternativeSelection(){ return ReadOption(kAlternativeSelection, false); }
ReadOption(key, kShowSystemMenu, ShowSystemMenu );
}
}
void SaveSingleClick(bool enable) { SaveOption(kSingleClick, enable); }
bool ReadSingleClick(){ return ReadOption(kSingleClick, false); }
/*
void SaveUnderline(bool enable) { SaveOption(kUnderline, enable); }
bool ReadUnderline(){ return ReadOption(kUnderline, false); }
*/
// void SaveLockMemoryAdd(bool enable) { SaveLmOption(kLockMemoryAdd, enable); }
// bool ReadLockMemoryAdd() { return ReadLmOption(kLockMemoryAdd, true); }
void SaveLockMemoryEnable(bool enable) { Save7ZipOption(kLargePagesEnable, enable); }
bool ReadLockMemoryEnable() { return Read7ZipOption(kLargePagesEnable, false); }
void SaveLockMemoryEnable(bool enable) { Save7ZipOption(kLargePages, enable); }
bool ReadLockMemoryEnable() { return Read7ZipOption(kLargePages, false); }
static CSysString GetFlatViewName(UInt32 panelIndex)
{
@@ -159,7 +172,15 @@ static CSysString GetFlatViewName(UInt32 panelIndex)
}
void SaveFlatView(UInt32 panelIndex, bool enable) { SaveOption(GetFlatViewName(panelIndex), enable); }
bool ReadFlatView(UInt32 panelIndex) { return ReadOption(GetFlatViewName(panelIndex), false); }
bool ReadFlatView(UInt32 panelIndex)
{
bool enabled = false;
CKey key;
if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS)
ReadOption(key, GetFlatViewName(panelIndex), enabled);
return enabled;
}
/*
void Save_ShowDeleted(bool enable) { SaveOption(kShowDeletedFiles, enable); }

View File

@@ -15,23 +15,21 @@ void ReadRegEditor(bool useEditor, UString &path);
void SaveRegDiff(const UString &path);
void ReadRegDiff(UString &path);
void SaveShowDots(bool showDots);
bool ReadShowDots();
struct CFmSettings
{
bool ShowDots;
bool ShowRealFileIcons;
bool FullRow;
bool ShowGrid;
bool SingleClick;
bool AlternativeSelection;
// bool Underline;
void SaveShowRealFileIcons(bool show);
bool ReadShowRealFileIcons();
bool ShowSystemMenu;
void Save_ShowSystemMenu(bool showSystemMenu);
bool Read_ShowSystemMenu();
void SaveFullRow(bool enable);
bool ReadFullRow();
void SaveShowGrid(bool enable);
bool ReadShowGrid();
void SaveAlternativeSelection(bool enable);
bool ReadAlternativeSelection();
void Save() const;
void Load();
};
// void SaveLockMemoryAdd(bool enable);
// bool ReadLockMemoryAdd();
@@ -39,14 +37,6 @@ bool ReadAlternativeSelection();
bool ReadLockMemoryEnable();
void SaveLockMemoryEnable(bool enable);
void SaveSingleClick(bool enable);
bool ReadSingleClick();
/*
void SaveUnderline(bool enable);
bool ReadUnderline();
*/
void SaveFlatView(UInt32 panelIndex, bool enable);
bool ReadFlatView(UInt32 panelIndex);

View File

@@ -35,20 +35,28 @@ extern bool IsLargePageSupported();
bool CSettingsPage::OnInit()
{
_wasChanged = false;
_largePages_wasChanged = false;
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
CheckButton(IDX_SETTINGS_SHOW_DOTS, ReadShowDots());
CheckButton(IDX_SETTINGS_SHOW_SYSTEM_MENU, Read_ShowSystemMenu());
CheckButton(IDX_SETTINGS_SHOW_REAL_FILE_ICONS, ReadShowRealFileIcons());
CheckButton(IDX_SETTINGS_FULL_ROW, ReadFullRow());
CheckButton(IDX_SETTINGS_SHOW_GRID, ReadShowGrid());
CheckButton(IDX_SETTINGS_ALTERNATIVE_SELECTION, ReadAlternativeSelection());
CFmSettings st;
st.Load();
CheckButton(IDX_SETTINGS_SHOW_DOTS, st.ShowDots);
CheckButton(IDX_SETTINGS_SHOW_REAL_FILE_ICONS, st.ShowRealFileIcons);
CheckButton(IDX_SETTINGS_FULL_ROW, st.FullRow);
CheckButton(IDX_SETTINGS_SHOW_GRID, st.ShowGrid);
CheckButton(IDX_SETTINGS_SINGLE_CLICK, st.SingleClick);
CheckButton(IDX_SETTINGS_ALTERNATIVE_SELECTION, st.AlternativeSelection);
// CheckButton(IDX_SETTINGS_UNDERLINE, st.Underline);
CheckButton(IDX_SETTINGS_SHOW_SYSTEM_MENU, st.ShowSystemMenu);
if (IsLargePageSupported())
CheckButton(IDX_SETTINGS_LARGE_PAGES, ReadLockMemoryEnable());
else
EnableItem(IDX_SETTINGS_LARGE_PAGES, false);
CheckButton(IDX_SETTINGS_SINGLE_CLICK, ReadSingleClick());
// CheckButton(IDX_SETTINGS_UNDERLINE, ReadUnderline());
// EnableSubItems();
@@ -64,25 +72,37 @@ void CSettingsPage::EnableSubItems()
LONG CSettingsPage::OnApply()
{
SaveShowDots(IsButtonCheckedBool(IDX_SETTINGS_SHOW_DOTS));
Save_ShowSystemMenu(IsButtonCheckedBool(IDX_SETTINGS_SHOW_SYSTEM_MENU));
SaveShowRealFileIcons(IsButtonCheckedBool(IDX_SETTINGS_SHOW_REAL_FILE_ICONS));
if (_wasChanged)
{
CFmSettings st;
st.ShowDots = IsButtonCheckedBool(IDX_SETTINGS_SHOW_DOTS);
st.ShowRealFileIcons = IsButtonCheckedBool(IDX_SETTINGS_SHOW_REAL_FILE_ICONS);
st.FullRow = IsButtonCheckedBool(IDX_SETTINGS_FULL_ROW);
st.ShowGrid = IsButtonCheckedBool(IDX_SETTINGS_SHOW_GRID);
st.SingleClick = IsButtonCheckedBool(IDX_SETTINGS_SINGLE_CLICK);
st.AlternativeSelection = IsButtonCheckedBool(IDX_SETTINGS_ALTERNATIVE_SELECTION);
// st.Underline = IsButtonCheckedBool(IDX_SETTINGS_UNDERLINE);
st.ShowSystemMenu = IsButtonCheckedBool(IDX_SETTINGS_SHOW_SYSTEM_MENU);
st.Save();
_wasChanged = false;
}
SaveFullRow(IsButtonCheckedBool(IDX_SETTINGS_FULL_ROW));
SaveShowGrid(IsButtonCheckedBool(IDX_SETTINGS_SHOW_GRID));
SaveAlternativeSelection(IsButtonCheckedBool(IDX_SETTINGS_ALTERNATIVE_SELECTION));
#ifndef UNDER_CE
if (_largePages_wasChanged)
{
if (IsLargePageSupported())
{
bool enable = IsButtonCheckedBool(IDX_SETTINGS_LARGE_PAGES);
NSecurity::EnablePrivilege_LockMemory(enable);
SaveLockMemoryEnable(enable);
}
_largePages_wasChanged = false;
}
#endif
SaveSingleClick(IsButtonCheckedBool(IDX_SETTINGS_SINGLE_CLICK));
// SaveUnderline(IsButtonCheckedBool(IDX_SETTINGS_UNDERLINE));
return PSNRET_NOERROR;
}
@@ -106,9 +126,17 @@ bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND)
case IDX_SETTINGS_FULL_ROW:
case IDX_SETTINGS_SHOW_GRID:
case IDX_SETTINGS_ALTERNATIVE_SELECTION:
_wasChanged = true;
break;
case IDX_SETTINGS_LARGE_PAGES:
_largePages_wasChanged = true;
break;
default:
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}
Changed();
return true;
}
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}

View File

@@ -8,6 +8,10 @@
class CSettingsPage: public NWindows::NControl::CPropertyPage
{
bool _wasChanged;
bool _largePages_wasChanged;
// void EnableSubItems();
bool OnButtonClicked(int buttonID, HWND buttonHWND);
public:

View File

@@ -2,10 +2,12 @@ CAPTION "Settings"
BEGIN
CONTROL "Show "".."" item", IDX_SETTINGS_SHOW_DOTS, MY_CHECKBOX, m, 8, xc, 10
CONTROL "Show real file &icons", IDX_SETTINGS_SHOW_REAL_FILE_ICONS, MY_CHECKBOX, m, 22, xc, 10
CONTROL "Show system &menu", IDX_SETTINGS_SHOW_SYSTEM_MENU, MY_CHECKBOX, m, 36, xc, 10
CONTROL "&Full row select", IDX_SETTINGS_FULL_ROW, MY_CHECKBOX, m, 50, xc, 10
CONTROL "Show &grid lines", IDX_SETTINGS_SHOW_GRID, MY_CHECKBOX, m, 64, xc, 10
CONTROL "&Single-click to open an item", IDX_SETTINGS_SINGLE_CLICK, MY_CHECKBOX, m, 78, xc, 10
CONTROL "&Alternative selection mode", IDX_SETTINGS_ALTERNATIVE_SELECTION, MY_CHECKBOX, m, 92, xc, 10
CONTROL "Use &large memory pages", IDX_SETTINGS_LARGE_PAGES, MY_CHECKBOX, m, 106, xc, 10
CONTROL "&Full row select", IDX_SETTINGS_FULL_ROW, MY_CHECKBOX, m, 36, xc, 10
CONTROL "Show &grid lines", IDX_SETTINGS_SHOW_GRID, MY_CHECKBOX, m, 50, xc, 10
CONTROL "&Single-click to open an item", IDX_SETTINGS_SINGLE_CLICK, MY_CHECKBOX, m, 64, xc, 10
CONTROL "&Alternative selection mode", IDX_SETTINGS_ALTERNATIVE_SELECTION, MY_CHECKBOX, m, 78, xc, 10
CONTROL "Show system &menu", IDX_SETTINGS_SHOW_SYSTEM_MENU, MY_CHECKBOX, m, 100, xc, 10
CONTROL "Use &large memory pages", IDX_SETTINGS_LARGE_PAGES, MY_CHECKBOX, m, 122, xc, 10
END

View File

@@ -6,8 +6,8 @@
#include <ShlObj.h>
#include "../../../Common/StringConvert.h"
#include "../../../Common/Defs.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/DLL.h"
#include "../../../Windows/ErrorMsg.h"
@@ -43,13 +43,16 @@ CSysString CModifiedExtInfo::GetString() const
return ProgramKey;
};
int CSystemPage::AddIcon(const UString &iconPath, int iconIndex)
{
if (iconPath.IsEmpty())
return -1;
if (iconIndex == -1)
iconIndex = 0;
HICON hicon;
#ifdef UNDER_CE
ExtractIconExW(iconPath, iconIndex, NULL, &hicon, 1);
if (!hicon)
@@ -65,12 +68,14 @@ int CSystemPage::AddIcon(const UString &iconPath, int iconIndex)
if (num != 1 || !hicon)
#endif
return -1;
_imageList.AddIcon(hicon);
DestroyIcon(hicon);
return _numIcons++;
}
void CSystemPage::RefreshListItem(int group, int listIndex)
void CSystemPage::RefreshListItem(unsigned group, unsigned listIndex)
{
const CAssoc &assoc = _items[GetRealIndex(listIndex)];
_listView.SetSubItem(listIndex, group + 1, assoc.Pair[group].GetString());
@@ -82,13 +87,14 @@ void CSystemPage::RefreshListItem(int group, int listIndex)
_listView.SetItem(&newItem);
}
void CSystemPage::ChangeState(int group, const CIntVector &indices)
void CSystemPage::ChangeState(unsigned group, const CUIntVector &indices)
{
if (indices.IsEmpty())
return;
bool thereAreClearItems = false;
int counters[3] = { 0, 0, 0 };
unsigned counters[3] = { 0, 0, 0 };
unsigned i;
for (i = 0; i < indices.Size(); i++)
@@ -114,27 +120,34 @@ void CSystemPage::ChangeState(int group, const CIntVector &indices)
for (i = 0; i < indices.Size(); i++)
{
int listIndex = indices[i];
unsigned listIndex = indices[i];
CAssoc &assoc = _items[GetRealIndex(listIndex)];
CModifiedExtInfo &mi = assoc.Pair[group];
bool change = false;
switch (state)
{
case kExtState_Clear: change = true; break;
case kExtState_Other: change = mi.Other; break;
default: change = !(mi.Other && thereAreClearItems); break;
}
if (change)
{
mi.State = state;
RefreshListItem(group, listIndex);
}
}
_needSave = true;
Changed();
}
bool CSystemPage::OnInit()
{
_needSave = false;
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
_listView.Attach(GetItem(IDL_SYSTEM_ASSOCIATE));
@@ -159,6 +172,7 @@ bool CSystemPage::OnInit()
BOOL res;
DWORD size = kSize;
#ifndef _UNICODE
if (!g_IsNT)
{
@@ -218,7 +232,7 @@ bool CSystemPage::OnInit()
assoc.SevenZipImageIndex = AddIcon(plug.IconPath, plug.IconIndex);
CSysString texts[NUM_EXT_GROUPS];
int g;
unsigned g;
for (g = 0; g < NUM_EXT_GROUPS; g++)
{
CModifiedExtInfo &mi = assoc.Pair[g];
@@ -240,62 +254,83 @@ bool CSystemPage::OnInit()
return CPropertyPage::OnInit();
}
static UString GetProgramCommand()
{
return L"\"" + fs2us(NDLL::GetModuleDirPrefix()) + L"7zFM.exe\" \"%1\"";
UString s = L"\"";
s += fs2us(NDLL::GetModuleDirPrefix());
s.AddAscii("7zFM.exe\" \"%1\"");
return s;
}
LONG CSystemPage::OnApply()
{
if (!_needSave)
return PSNRET_NOERROR;
const UString command = GetProgramCommand();
LONG res = 0;
FOR_VECTOR (listIndex, _extDB.Exts)
{
int realIndex = GetRealIndex(listIndex);
unsigned realIndex = GetRealIndex(listIndex);
const CExtPlugins &extInfo = _extDB.Exts[realIndex];
CAssoc &assoc = _items[realIndex];
for (int g = 0; g < NUM_EXT_GROUPS; g++)
for (unsigned g = 0; g < NUM_EXT_GROUPS; g++)
{
CModifiedExtInfo &mi = assoc.Pair[g];
HKEY key = GetHKey(g);
if (mi.OldState != mi.State)
{
LONG res2 = 0;
if (mi.State == kExtState_7Zip)
{
UString title = extInfo.Ext + UString(L" Archive");
UString title = extInfo.Ext;
title.AddAscii(" Archive");
const CPluginToIcon &plug = extInfo.Plugins[0];
res2 = NRegistryAssoc::AddShellExtensionInfo(key, GetSystemString(extInfo.Ext),
title, command, plug.IconPath, plug.IconIndex);
}
else if (mi.State == kExtState_Clear)
res2 = NRegistryAssoc::DeleteShellExtensionInfo(key, GetSystemString(extInfo.Ext));
if (res == 0)
res = res2;
if (res2 == 0)
mi.OldState = mi.State;
mi.State = mi.OldState;
RefreshListItem(g, listIndex);
}
}
}
#ifndef UNDER_CE
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
WasChanged = true;
#endif
WasChanged = true;
_needSave = false;
if (res != 0)
MessageBoxW(*this, NError::MyFormatMessage(res), L"7-Zip", MB_ICONERROR);
return PSNRET_NOERROR;
}
void CSystemPage::OnNotifyHelp()
{
ShowHelpWindow(NULL, kSystemTopic);
}
bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND)
{
switch (buttonID)
@@ -313,6 +348,7 @@ bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND)
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}
bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
{
if (lParam->hwndFrom == HWND(_listView))
@@ -324,7 +360,7 @@ bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
ChangeState(0);
return true;
}
break;
case NM_CLICK:
{
#ifdef UNDER_CE
@@ -334,12 +370,12 @@ bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
if (item->uKeyFlags == 0)
#endif
{
int realIndex = GetRealIndex(item->iItem);
if (realIndex >= 0)
if (item->iItem >= 0)
{
// unsigned realIndex = GetRealIndex(item->iItem);
if (item->iSubItem >= 1 && item->iSubItem <= 2)
{
CIntVector indices;
CUIntVector indices;
indices.Add(item->iItem);
ChangeState(item->iSubItem < 2 ? 0 : 1, indices);
}
@@ -347,12 +383,14 @@ bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
}
break;
}
case LVN_KEYDOWN:
{
if (OnListKeyDown(LPNMLVKEYDOWN(lParam)))
return true;
break;
}
/*
case NM_RCLICK:
case NM_DBLCLK:
@@ -366,18 +404,23 @@ bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
return CPropertyPage::OnNotify(controlID, lParam);
}
void CSystemPage::ChangeState(int group)
void CSystemPage::ChangeState(unsigned group)
{
CIntVector indices;
CUIntVector indices;
int itemIndex = -1;
while ((itemIndex = _listView.GetNextSelectedItem(itemIndex)) != -1)
indices.Add(itemIndex);
if (indices.IsEmpty())
FOR_VECTOR (i, _items)
indices.Add(i);
ChangeState(group, indices);
}
bool CSystemPage::OnListKeyDown(LPNMLVKEYDOWN keyDownInfo)
{
bool ctrl = IsKeyDown(VK_CONTROL);
@@ -386,8 +429,8 @@ bool CSystemPage::OnListKeyDown(LPNMLVKEYDOWN keyDownInfo)
if (alt)
return false;
if ((ctrl && keyDownInfo->wVKey == 'A') ||
(!ctrl && keyDownInfo->wVKey == VK_MULTIPLY))
if ((ctrl && keyDownInfo->wVKey == 'A')
|| (!ctrl && keyDownInfo->wVKey == VK_MULTIPLY))
{
_listView.SelectAll();
return true;
@@ -400,15 +443,19 @@ bool CSystemPage::OnListKeyDown(LPNMLVKEYDOWN keyDownInfo)
case VK_SUBTRACT:
case VK_SEPARATOR:
case VK_DIVIDE:
#ifndef UNDER_CE
case VK_OEM_PLUS:
case VK_OEM_MINUS:
#endif
if (!ctrl)
{
ChangeState(keyDownInfo->wVKey == VK_SPACE ? 0 : 1);
return true;
}
break;
}
return false;
}

View File

@@ -59,7 +59,7 @@ struct CAssoc
int GetIconIndex() const
{
for (int i = 0; i < 2; i++)
for (unsigned i = 0; i < 2; i++)
{
const CModifiedExtInfo &pair = Pair[i];
if (pair.State == kExtState_Clear)
@@ -84,11 +84,13 @@ class CSystemPage: public NWindows::NControl::CPropertyPage
CExtDatabase _extDB;
CObjectVector<CAssoc> _items;
int _numIcons;
unsigned _numIcons;
NWindows::NControl::CImageList _imageList;
NWindows::NControl::CListView _listView;
const HKEY GetHKey(int
bool _needSave;
const HKEY GetHKey(unsigned
#if NUM_EXT_GROUPS != 1
group
#endif
@@ -102,15 +104,16 @@ class CSystemPage: public NWindows::NControl::CPropertyPage
}
int AddIcon(const UString &path, int iconIndex);
int GetRealIndex(int listIndex) const { return listIndex; }
void RefreshListItem(int group, int listIndex);
void ChangeState(int group, const CIntVector &indices);
void ChangeState(int group);
unsigned GetRealIndex(unsigned listIndex) const { return listIndex; }
void RefreshListItem(unsigned group, unsigned listIndex);
void ChangeState(unsigned group, const CUIntVector &indices);
void ChangeState(unsigned group);
bool OnListKeyDown(LPNMLVKEYDOWN keyDownInfo);
public:
bool WasChanged;
CSystemPage(): WasChanged(false) {}
virtual bool OnInit();

View File

@@ -175,6 +175,7 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil
AddValuePair(s, IDS_PROP_NUM_ERRORS, hb.NumErrors);
s.Add_LF();
}
if (hb.NumFiles == 1 && hb.NumDirs == 0 && !firstFileName.IsEmpty())
{
AddLangString(s, IDS_PROP_NAME);
@@ -197,6 +198,12 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil
AddSizeValuePair(s, IDS_PROP_ALT_STREAMS_SIZE, hb.AltStreamsSize);
}
if (hb.NumErrors == 0 && hb.Hashers.IsEmpty())
{
s.Add_LF();
AddLangString(s, IDS_MESSAGE_NO_ERRORS);
}
FOR_VECTOR (i, hb.Hashers)
{
s.Add_LF();

View File

@@ -303,7 +303,7 @@ public:
void SetFrom_CalcLen(const char *s, unsigned len);
// void SetFromAscii(const char *s) { operator+=(s); }
// AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
AString Left(unsigned count) const { return AString(count, *this); }
// void MakeUpper() { MyStringUpper(_chars); }

View File

@@ -4,23 +4,22 @@
#define __WINDOWS_CONTROL_TRACKBAR_H
#include "../Window.h"
#include "../Defs.h"
namespace NWindows {
namespace NControl {
class CTrackbar1: public CWindow
class CTrackbar: public CWindow
{
public:
void SetRange(int minimum, int maximum, bool redraw = true)
{ SendMessage(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); }
{ SendMsg(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); }
void SetPos(int pos, bool redraw = true)
{ SendMessage(TBM_SETPOS, BoolToBOOL(redraw), pos); }
{ SendMsg(TBM_SETPOS, BoolToBOOL(redraw), pos); }
void SetTicFreq(int freq)
{ SendMessage(TBM_SETTICFREQ, freq); }
{ SendMsg(TBM_SETTICFREQ, freq); }
int GetPos()
{ return (int)SendMessage(TBM_GETPOS); }
{ return (int)SendMsg(TBM_GETPOS); }
};
}}

View File

@@ -10,8 +10,8 @@ AppName = "7-Zip"
InstallDir = %CE1%\%AppName%
[Strings]
AppVer = "15.11"
AppDate = "2015-11-14"
AppVer = "15.14"
AppDate = "2015-12-31"
[CEDevice]
; ProcessorType = 2577 ; ARM

View File

@@ -2,8 +2,8 @@
;Defines
!define VERSION_MAJOR 15
!define VERSION_MINOR 11
!define VERSION_POSTFIX_FULL " beta"
!define VERSION_MINOR 14
!define VERSION_POSTFIX_FULL ""
!ifdef WIN64
!ifdef IA64
!define VERSION_SYS_POSTFIX_FULL " for Windows IA-64"
@@ -262,6 +262,7 @@ Section
File uz.txt
File va.txt
File vi.txt
File yo.txt
File zh-cn.txt
File zh-tw.txt
@@ -464,6 +465,7 @@ Section Uninstall
Delete $INSTDIR\Lang\va.txt
Delete $INSTDIR\Lang\vi.txt
Delete $INSTDIR\Lang\vr.txt
Delete $INSTDIR\Lang\yo.txt
Delete $INSTDIR\Lang\zh-cn.txt
Delete $INSTDIR\Lang\zh-tw.txt

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<?define VerMajor = "15" ?>
<?define VerMinor = "11" ?>
<?define VerMinor = "14" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?>
@@ -335,6 +335,7 @@
<File Id="uz.txt" Name="uz.txt" />
<File Id="va.txt" Name="va.txt" />
<File Id="vi.txt" Name="vi.txt" />
<File Id="yo.txt" Name="yo.txt" />
<File Id="zh_cn.txt" Name="zh-cn.txt" />
<File Id="zh_tw.txt" Name="zh-tw.txt" />
</Component>

View File

@@ -1,4 +1,4 @@
7-Zip 15.11 Sources
7-Zip 15.14 Sources
-------------------
7-Zip is a file archiver for Windows.

View File

@@ -1,6 +1,21 @@
HISTORY of the 7-Zip source code
--------------------------------
15.12 2015-11-19
-------------------------
- The BUG in C version of 7z decoder was fixed:
7zDec.c : SzDecodeLzma2()
7z decoder could mistakenly report about decoding error for some 7z archives
that use LZMA2 compression method.
The probability to get that mistaken decoding error report was about
one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size).
- The BUG (in 9.26-15.11) in C version of 7z decoder was fixed:
7zArcIn.c : SzReadHeader2()
7z decoder worked incorrectly for 7z archives that contain
empty solid blocks, that can be placed to 7z archive, if some file is
unavailable for reading during archive creation.
15.09 beta 2015-10-16
-------------------------
- The BUG in LZMA / LZMA2 encoding code was fixed.