This commit is contained in:
Igor Pavlov
2015-12-31 00:00:00 +00:00
committed by Kornel Lesiński
parent 5de23c1deb
commit 9608215ad8
73 changed files with 1854 additions and 783 deletions

View File

@@ -1,9 +1,9 @@
#define MY_VER_MAJOR 15
#define MY_VER_MINOR 12
#define MY_VER_MINOR 13
#define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "15.12"
#define MY_VERSION "15.12"
#define MY_DATE "2015-11-19"
#define MY_VERSION_NUMBERS "15.13"
#define MY_VERSION "15.13"
#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

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

@@ -781,6 +781,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;
}
@@ -843,7 +844,7 @@ 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;
@@ -937,8 +938,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 +1011,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);

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)
@@ -427,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
@@ -617,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();
@@ -653,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;
@@ -157,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()
{
@@ -274,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());
@@ -322,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

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

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

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

@@ -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.12"
AppDate = "2015-11-19"
AppVer = "15.13"
AppDate = "2015-12-31"
[CEDevice]
; ProcessorType = 2577 ; ARM

View File

@@ -2,7 +2,7 @@
;Defines
!define VERSION_MAJOR 15
!define VERSION_MINOR 12
!define VERSION_MINOR 13
!define VERSION_POSTFIX_FULL ""
!ifdef WIN64
!ifdef IA64
@@ -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 = "12" ?>
<?define VerMinor = "13" ?>
<?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.12 Sources
7-Zip 15.13 Sources
-------------------
7-Zip is a file archiver for Windows.