Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2015-12-31 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:58 +0300
commit9608215ad8deb58355bae27692669fda067c4f43 (patch)
tree1227131a3f19bc36e5da4ba11791154d05cc08af
parent5de23c1deb52b8be4c43ad9f694c64bbddd0c38a (diff)
15.1315.13
-rw-r--r--C/7zVersion.h8
-rw-r--r--C/CpuArch.h4
-rw-r--r--C/Util/7zipInstall/7zipInstall.c7
-rw-r--r--C/Util/7zipUninstall/7zipUninstall.c10
-rw-r--r--CPP/7zip/Archive/7z/7zUpdate.cpp11
-rw-r--r--CPP/7zip/Archive/Cab/CabHandler.cpp16
-rw-r--r--CPP/7zip/Archive/Cab/CabIn.cpp22
-rw-r--r--CPP/7zip/Archive/Cab/CabIn.h5
-rw-r--r--CPP/7zip/Archive/ComHandler.cpp9
-rw-r--r--CPP/7zip/Archive/ExtHandler.cpp27
-rw-r--r--CPP/7zip/Archive/FatHandler.cpp7
-rw-r--r--CPP/7zip/Archive/Iso/IsoIn.h2
-rw-r--r--CPP/7zip/Archive/PeHandler.cpp26
-rw-r--r--CPP/7zip/Archive/PpmdHandler.cpp19
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandler.cpp28
-rw-r--r--CPP/7zip/Archive/Zip/ZipHeader.h2
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.cpp3
-rw-r--r--CPP/7zip/Archive/Zip/ZipItem.cpp94
-rw-r--r--CPP/7zip/Archive/Zip/ZipItem.h78
-rw-r--r--CPP/7zip/Bundles/SFXWin/SFXWin.dsp8
-rw-r--r--CPP/7zip/UI/Common/ArchiveCommandLine.cpp2
-rw-r--r--CPP/7zip/UI/Common/ArchiveExtractCallback.cpp2
-rw-r--r--CPP/7zip/UI/Common/Bench.cpp2
-rw-r--r--CPP/7zip/UI/Common/OpenArchive.cpp2
-rw-r--r--CPP/7zip/UI/Common/ZipRegistry.cpp45
-rw-r--r--CPP/7zip/UI/Common/ZipRegistry.h7
-rw-r--r--CPP/7zip/UI/Explorer/ContextMenu.cpp51
-rw-r--r--CPP/7zip/UI/Explorer/ContextMenu.h2
-rw-r--r--CPP/7zip/UI/Explorer/DllExportsExplorer.cpp111
-rw-r--r--CPP/7zip/UI/Explorer/Explorer.dsp8
-rw-r--r--CPP/7zip/UI/Explorer/RegistryContextMenu.cpp248
-rw-r--r--CPP/7zip/UI/Explorer/RegistryContextMenu.h11
-rw-r--r--CPP/7zip/UI/Explorer/makefile1
-rw-r--r--CPP/7zip/UI/Far/FarUtils.cpp2
-rw-r--r--CPP/7zip/UI/Far/FarUtils.h2
-rw-r--r--CPP/7zip/UI/Far/OverwriteDialogFar.cpp13
-rw-r--r--CPP/7zip/UI/FileManager/App.cpp56
-rw-r--r--CPP/7zip/UI/FileManager/App.h1
-rw-r--r--CPP/7zip/UI/FileManager/BrowseDialog.cpp8
-rw-r--r--CPP/7zip/UI/FileManager/EditPage.cpp90
-rw-r--r--CPP/7zip/UI/FileManager/EditPage.h14
-rw-r--r--CPP/7zip/UI/FileManager/FM.cpp87
-rw-r--r--CPP/7zip/UI/FileManager/FSFolderCopy.cpp9
-rw-r--r--CPP/7zip/UI/FileManager/FoldersPage.cpp31
-rw-r--r--CPP/7zip/UI/FileManager/FoldersPage.h7
-rw-r--r--CPP/7zip/UI/FileManager/LangPage.cpp7
-rw-r--r--CPP/7zip/UI/FileManager/LangPage.h4
-rw-r--r--CPP/7zip/UI/FileManager/LangUtils.cpp52
-rw-r--r--CPP/7zip/UI/FileManager/ListViewDialog.cpp4
-rw-r--r--CPP/7zip/UI/FileManager/MenuPage.cpp240
-rw-r--r--CPP/7zip/UI/FileManager/MenuPage.h29
-rw-r--r--CPP/7zip/UI/FileManager/MenuPage.rc2
-rw-r--r--CPP/7zip/UI/FileManager/MenuPage2.rc14
-rw-r--r--CPP/7zip/UI/FileManager/MenuPageRes.h10
-rw-r--r--CPP/7zip/UI/FileManager/MyLoadMenu.cpp3
-rw-r--r--CPP/7zip/UI/FileManager/OptionsDialog.cpp80
-rw-r--r--CPP/7zip/UI/FileManager/Panel.h24
-rw-r--r--CPP/7zip/UI/FileManager/PanelDrag.cpp20
-rw-r--r--CPP/7zip/UI/FileManager/PanelItemOpen.cpp575
-rw-r--r--CPP/7zip/UI/FileManager/PanelKey.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/RegistryUtils.cpp97
-rw-r--r--CPP/7zip/UI/FileManager/RegistryUtils.h40
-rw-r--r--CPP/7zip/UI/FileManager/SettingsPage.cpp80
-rw-r--r--CPP/7zip/UI/FileManager/SettingsPage.h4
-rw-r--r--CPP/7zip/UI/FileManager/SettingsPage2.rc14
-rw-r--r--CPP/7zip/UI/FileManager/SystemPage.cpp85
-rw-r--r--CPP/7zip/UI/FileManager/SystemPage.h17
-rw-r--r--CPP/Common/MyString.h2
-rw-r--r--CPP/Windows/Control/Trackbar.h11
-rw-r--r--DOC/7zip.inf4
-rw-r--r--DOC/7zip.nsi4
-rw-r--r--DOC/7zip.wxs3
-rw-r--r--DOC/readme.txt2
73 files changed, 1849 insertions, 778 deletions
diff --git a/C/7zVersion.h b/C/7zVersion.h
index 2975c81f..3e5c9bd5 100644
--- a/C/7zVersion.h
+++ b/C/7zVersion.h
@@ -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"
diff --git a/C/CpuArch.h b/C/CpuArch.h
index fa44160a..f6a28ba7 100644
--- a/C/CpuArch.h
+++ b/C/CpuArch.h
@@ -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
diff --git a/C/Util/7zipInstall/7zipInstall.c b/C/Util/7zipInstall/7zipInstall.c
index f3263988..41aab71e 100644
--- a/C/Util/7zipInstall/7zipInstall.c
+++ b/C/Util/7zipInstall/7zipInstall.c
@@ -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;
diff --git a/C/Util/7zipUninstall/7zipUninstall.c b/C/Util/7zipUninstall/7zipUninstall.c
index d0bfd4cc..cd66002a 100644
--- a/C/Util/7zipUninstall/7zipUninstall.c
+++ b/C/Util/7zipUninstall/7zipUninstall.c
@@ -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;
diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp
index c2478a29..7e9478fc 100644
--- a/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -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"
diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp
index 711bfdf7..e31de4fe 100644
--- a/CPP/7zip/Archive/Cab/CabHandler.cpp
+++ b/CPP/7zip/Archive/Cab/CabHandler.cpp
@@ -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);
diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp
index a72e05f7..ca0052bf 100644
--- a/CPP/7zip/Archive/Cab/CabIn.cpp
+++ b/CPP/7zip/Archive/Cab/CabIn.cpp
@@ -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;
}
diff --git a/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h
index baeeb7b2..a1fc6bdc 100644
--- a/CPP/7zip/Archive/Cab/CabIn.h
+++ b/CPP/7zip/Archive/Cab/CabIn.h
@@ -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);
diff --git a/CPP/7zip/Archive/ComHandler.cpp b/CPP/7zip/Archive/ComHandler.cpp
index 3a4834cd..e39dbab5 100644
--- a/CPP/7zip/Archive/ComHandler.cpp
+++ b/CPP/7zip/Archive/ComHandler.cpp
@@ -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;
diff --git a/CPP/7zip/Archive/ExtHandler.cpp b/CPP/7zip/Archive/ExtHandler.cpp
index a9d0facb..606aeed1 100644
--- a/CPP/7zip/Archive/ExtHandler.cpp
+++ b/CPP/7zip/Archive/ExtHandler.cpp
@@ -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;
{
@@ -1213,6 +1216,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;
@@ -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);
diff --git a/CPP/7zip/Archive/FatHandler.cpp b/CPP/7zip/Archive/FatHandler.cpp
index e8340f1d..9c37c062 100644
--- a/CPP/7zip/Archive/FatHandler.cpp
+++ b/CPP/7zip/Archive/FatHandler.cpp
@@ -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;
diff --git a/CPP/7zip/Archive/Iso/IsoIn.h b/CPP/7zip/Archive/Iso/IsoIn.h
index 5c1a4bcf..4000fc92 100644
--- a/CPP/7zip/Archive/Iso/IsoIn.h
+++ b/CPP/7zip/Archive/Iso/IsoIn.h
@@ -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’s use
+ UInt32 LoadRBA; // This is the start address of the virtual disk. CDs use
// Relative/Logical block addressing.
Byte VendorSpec[20];
diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp
index 9cbc7c3c..28562007 100644
--- a/CPP/7zip/Archive/PeHandler.cpp
+++ b/CPP/7zip/Archive/PeHandler.cpp
@@ -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;
diff --git a/CPP/7zip/Archive/PpmdHandler.cpp b/CPP/7zip/Archive/PpmdHandler.cpp
index 86927f8f..528c5ceb 100644
--- a/CPP/7zip/Archive/PpmdHandler.cpp
+++ b/CPP/7zip/Archive/PpmdHandler.cpp
@@ -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(
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index a65c9e32..092dcbc9 100644
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -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)
diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h
index 18ba064a..82e46eb6 100644
--- a/CPP/7zip/Archive/Zip/ZipHeader.h
+++ b/CPP/7zip/Archive/Zip/ZipHeader.h
@@ -84,6 +84,8 @@ namespace NFileHeader
kNTFS = 0x0A,
kStrongEncrypt = 0x17,
kUnixTime = 0x5455,
+ kIzUnicodeComment = 0x6375,
+ kIzUnicodeName = 0x7075,
kWzAES = 0x9901
};
}
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index 77ca89ea..2ba7e3fa 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -203,7 +203,8 @@ 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)
- return k_IsArc_Res_NO;
+ if (i != nameSize - 1)
+ return k_IsArc_Res_NO;
}
if (size < extraOffset)
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
index 9e1f5e00..e732df7c 100644
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -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());
+}
+
}}
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index c01ede8d..5f078b60 100644
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -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);
}
};
diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
index 944feb4d..1f3d88d1 100644
--- a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
+++ b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
@@ -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
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index f39cf162..1bd202ed 100644
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -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;
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
index fe9c3366..62da5e9f 100644
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
@@ -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
diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp
index f861f503..fb69b544 100644
--- a/CPP/7zip/UI/Common/Bench.cpp
+++ b/CPP/7zip/UI/Common/Bench.cpp
@@ -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))
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
index a6afaf1c..e323abd2 100644
--- a/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -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:
diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp
index 4c48bd70..74660186 100644
--- a/CPP/7zip/UI/Common/ZipRegistry.cpp
+++ b/CPP/7zip/UI/Common/ZipRegistry.cpp
@@ -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.SetValue(kContextMenu, Flags);
+
+ 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);
}
diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h
index cd2ea67d..935f97bb 100644
--- a/CPP/7zip/UI/Common/ZipRegistry.h
+++ b/CPP/7zip/UI/Common/ZipRegistry.h
@@ -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;
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp
index 68af4a1e..d94e28e6 100644
--- a/CPP/7zip/UI/Explorer/ContextMenu.cpp
+++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp
@@ -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)
@@ -917,6 +945,7 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
}
}
break;
+ }
}
}
catch(...)
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.h b/CPP/7zip/UI/Explorer/ContextMenu.h
index 90ca0e64..53bf18de 100644
--- a/CPP/7zip/UI/Explorer/ContextMenu.h
+++ b/CPP/7zip/UI/Explorer/ContextMenu.h
@@ -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);
diff --git a/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp b/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
index 3b04e7be..d02af9ef 100644
--- a/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
+++ b/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
@@ -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
-{
- HKEY hRootKey;
- LPCTSTR SubKey;
- LPCWSTR ValueName;
- LPCWSTR Data;
-} CRegItem;
-static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
+static BOOL RegisterServer()
{
- 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;
}
diff --git a/CPP/7zip/UI/Explorer/Explorer.dsp b/CPP/7zip/UI/Explorer/Explorer.dsp
index 84e2a6a4..2a6166ee 100644
--- a/CPP/7zip/UI/Explorer/Explorer.dsp
+++ b/CPP/7zip/UI/Explorer/Explorer.dsp
@@ -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
diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
index da6ecf38..d0c9189d 100644
--- a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
+++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
@@ -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;
-
-static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
-static const TCHAR *kDragDropMenuKeyName = TEXT("\\shellex\\DragDropHandlers\\7-Zip");
+// 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 *kExtensionCLSID = TEXT("{23170F69-40C1-278A-1000-000100020000}");
+static LPCTSTR k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}");
+static LPCTSTR k_ShellExtName = TEXT("7-Zip Shell Extension");
-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_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
+static LPCTSTR k_Inproc = TEXT("InprocServer32");
-static CSysString GetFullContextMenuKeyName(const CSysString &keyName)
- { return (keyName + kContextMenuKeyName); }
+static LPCTSTR k_KeyPostfix_ContextMenu = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
+static LPCTSTR k_KeyPostfix_DragDrop = TEXT("\\shellex\\DragDropHandlers\\7-Zip");
-static CSysString GetFullDragDropMenuKeyName(const CSysString &keyName)
- { return (keyName + kDragDropMenuKeyName); }
+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 bool CheckHandlerCommon(const CSysString &keyName)
+static LPCTSTR const k_shellex_Prefixes[] =
{
- NSynchronization::CCriticalSectionLock lock(g_CS);
- CKey key;
- if (key.Open(HKEY_CLASSES_ROOT, keyName, KEY_READ) != ERROR_SUCCESS)
- return false;
- CSysString value;
- if (key.QueryValue(NULL, value) != ERROR_SUCCESS)
- return false;
- return StringsAreEqualNoCase_Ascii(value, kExtensionCLSID);
-}
+ k_KeyName_File,
+ k_KeyName_Folder,
+ k_KeyName_Directory,
+ k_KeyName_Drive
+};
-bool CheckContextMenuHandler()
+static const bool k_shellex_Statuses[2][4] =
{
- return
- // CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForFolder)) &&
- CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForDirectory)) &&
- CheckHandlerCommon(GetFullContextMenuKeyName(kRootKeyNameForFile)) &&
- CheckHandlerCommon(GetFullDragDropMenuKeyName(kRootKeyNameForDirectory)) &&
- CheckHandlerCommon(GetFullDragDropMenuKeyName(kRootKeyNameForDrive));
-}
+ { 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
-static void DeleteContextMenuHandlerCommon(const CSysString &keyName)
+#else
+*/
+
+typedef WINADVAPI LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved);
+static Func_RegDeleteKeyExW func_RegDeleteKeyExW;
+
+static void Init_RegDeleteKeyExW()
{
- CKey rootKey;
- rootKey.Attach(HKEY_CLASSES_ROOT);
- rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(keyName));
- rootKey.Detach();
+ if (!func_RegDeleteKeyExW)
+ func_RegDeleteKeyExW = (Func_RegDeleteKeyExW)
+ GetProcAddress(GetModuleHandleW(L"advapi32.dll"), "RegDeleteKeyExW");
}
-static void DeleteDragDropMenuHandlerCommon(const CSysString &keyName)
+#define INIT_REG_WOW if (wow != 0) Init_RegDeleteKeyExW();
+
+// #endif
+
+static LONG MyRegistry_DeleteKey(HKEY parentKey, LPCTSTR name, UInt32 wow)
{
- CKey rootKey;
- rootKey.Attach(HKEY_CLASSES_ROOT);
- rootKey.RecurseDeleteKey(GetFullDragDropMenuKeyName(keyName));
- rootKey.Detach();
+ 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);
}
-void DeleteContextMenuHandler()
+static LONG MyRegistry_DeleteKey_HKCR(LPCTSTR name, UInt32 wow)
{
- DeleteContextMenuHandlerCommon(kRootKeyNameForFile);
- DeleteContextMenuHandlerCommon(kRootKeyNameForFolder);
- DeleteContextMenuHandlerCommon(kRootKeyNameForDirectory);
- DeleteContextMenuHandlerCommon(kRootKeyNameForDrive);
- DeleteDragDropMenuHandlerCommon(kRootKeyNameForFile);
- DeleteDragDropMenuHandlerCommon(kRootKeyNameForFolder);
- DeleteDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
- DeleteDragDropMenuHandlerCommon(kRootKeyNameForDrive);
+ return MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, name, wow);
}
-static void AddContextMenuHandlerCommon(const CSysString &keyName)
+// 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)
{
- DeleteContextMenuHandlerCommon(keyName);
- NSynchronization::CCriticalSectionLock lock(g_CS);
CKey key;
- key.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName));
- key.SetValue(NULL, kExtensionCLSID);
+ 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, k_Clsid);
}
-static void AddDragDropMenuHandlerCommon(const CSysString &keyName)
+bool CheckContextMenuHandler(const UString &path, UInt32 wow)
{
- DeleteDragDropMenuHandlerCommon(keyName);
- NSynchronization::CCriticalSectionLock lock(g_CS);
- CKey key;
- key.Create(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName));
- key.SetValue(NULL, kExtensionCLSID);
+ // 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(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);
+ */
}
-void AddContextMenuHandler()
+
+static LONG MyCreateKey(CKey &key, HKEY parentKey, LPCTSTR keyName, UInt32 wow)
{
- AddContextMenuHandlerCommon(kRootKeyNameForFile);
- // AddContextMenuHandlerCommon(kRootKeyNameForFolder);
- AddContextMenuHandlerCommon(kRootKeyNameForDirectory);
+ return key.Create(parentKey, keyName, REG_NONE,
+ REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | wow);
+}
- AddDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
- AddDragDropMenuHandlerCommon(kRootKeyNameForDrive);
+LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow)
+{
+ // NSynchronization::CCriticalSectionLock lock(g_CS);
+
+ INIT_REG_WOW
+
+ CSysString s = TEXT("CLSID\\");
+ s += k_Clsid;
+
+ LONG res;
+ if (setMode)
+ {
+ {
+ CKey key;
+ 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"));
+ }
+ }
+ }
+
+ {
+ CKey key;
+ 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);
+ }
+
+ // 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++)
+ {
+ 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);
+ }
+ }
+
+ return res;
}
#endif
-
-}
diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.h b/CPP/7zip/UI/Explorer/RegistryContextMenu.h
index 139526a8..8c2acc42 100644
--- a/CPP/7zip/UI/Explorer/RegistryContextMenu.h
+++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.h
@@ -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
diff --git a/CPP/7zip/UI/Explorer/makefile b/CPP/7zip/UI/Explorer/makefile
index 02a4cd6f..1c8639be 100644
--- a/CPP/7zip/UI/Explorer/makefile
+++ b/CPP/7zip/UI/Explorer/makefile
@@ -14,7 +14,6 @@ EXPLORER_OBJS = \
$O\DllExportsExplorer.obj \
$O\ContextMenu.obj \
$O\MyMessages.obj \
- $O\RegistryContextMenu.obj \
COMMON_OBJS = \
$O\IntToString.obj \
diff --git a/CPP/7zip/UI/Far/FarUtils.cpp b/CPP/7zip/UI/Far/FarUtils.cpp
index 1875a189..cc058ef9 100644
--- a/CPP/7zip/UI/Far/FarUtils.cpp
+++ b/CPP/7zip/UI/Far/FarUtils.cpp
@@ -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)
{
diff --git a/CPP/7zip/UI/Far/FarUtils.h b/CPP/7zip/UI/Far/FarUtils.h
index edec4cf9..5617c6c8 100644
--- a/CPP/7zip/UI/Far/FarUtils.h
+++ b/CPP/7zip/UI/Far/FarUtils.h
@@ -190,6 +190,8 @@ int ShowLastErrorMessage();
bool WasEscPressed();
+void ReduceString(UString &s, unsigned size);
+
}
#endif
diff --git a/CPP/7zip/UI/Far/OverwriteDialogFar.cpp b/CPP/7zip/UI/Far/OverwriteDialogFar.cpp
index a7fb495e..e950f695 100644
--- a/CPP/7zip/UI/Far/OverwriteDialogFar.cpp
+++ b/CPP/7zip/UI/Far/OverwriteDialogFar.cpp
@@ -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 },
diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp
index b6a66975..a262029f 100644
--- a/CPP/7zip/UI/FileManager/App.cpp
+++ b/CPP/7zip/UI/FileManager/App.cpp
@@ -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++)
{
diff --git a/CPP/7zip/UI/FileManager/App.h b/CPP/7zip/UI/FileManager/App.h
index 190864cb..dedbd821 100644
--- a/CPP/7zip/UI/FileManager/App.h
+++ b/CPP/7zip/UI/FileManager/App.h
@@ -258,7 +258,6 @@ public:
*/
void SetListSettings();
- void SetShowSystemMenu();
HRESULT SwitchOnOffOnePanel();
bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); }
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
index 1c2f6374..066ac219 100644
--- a/CPP/7zip/UI/FileManager/BrowseDialog.cpp
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
@@ -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)
diff --git a/CPP/7zip/UI/FileManager/EditPage.cpp b/CPP/7zip/UI/FileManager/EditPage.cpp
index 627088b9..b88c0f68 100644
--- a/CPP/7zip/UI/FileManager/EditPage.cpp
+++ b/CPP/7zip/UI/FileManager/EditPage.cpp
@@ -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));
-
- {
- UString path;
- ReadRegEditor(false, path);
- _viewer.SetText(path);
- }
- {
- UString path;
- ReadRegEditor(true, path);
- _editor.SetText(path);
- }
+ _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;
- ReadRegDiff(path);
- _diff.SetText(path);
+ if (i < 2)
+ ReadRegEditor(i > 0, path);
+ else
+ ReadRegDiff(path);
+ c.Edit.SetText(path);
}
+
+ _initMode = false;
+
return CPropertyPage::OnInit();
}
LONG CEditPage::OnApply()
{
+ for (unsigned i = 0; i < 3; i++)
{
- UString path;
- _viewer.GetText(path);
- SaveRegEditor(false, path);
- }
- {
- UString path;
- _editor.GetText(path);
- SaveRegEditor(true, path);
- }
- {
- UString path;
- _diff.GetText(path);
- SaveRegDiff(path);
+ CEditPageCtrl &c = _ctrls[i];
+ if (c.WasChanged)
+ {
+ UString 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)
{
- Changed();
- return true;
+ 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);
}
diff --git a/CPP/7zip/UI/FileManager/EditPage.h b/CPP/7zip/UI/FileManager/EditPage.h
index c11e613b..208edd8d 100644
--- a/CPP/7zip/UI/FileManager/EditPage.h
+++ b/CPP/7zip/UI/FileManager/EditPage.h
@@ -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();
diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp
index a320c016..f91dda09 100644
--- a/CPP/7zip/UI/FileManager/FM.cpp
+++ b/CPP/7zip/UI/FileManager/FM.cpp
@@ -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)
+
+bool g_Is_Wow64;
-static bool IsWow64()
+typedef BOOL (WINAPI *Func_IsWow64Process)(HANDLE, PBOOL);
+
+static void Set_Wow64()
{
- 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;
+ g_Is_Wow64 = false;
+ Func_IsWow64Process fnIsWow64Process = (Func_IsWow64Process)GetProcAddress(
+ GetModuleHandleA("kernel32.dll"), "IsWow64Process");
+ if (fnIsWow64Process)
+ {
+ BOOL isWow;
+ 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.
@@ -635,7 +642,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
try
{
- return WinMain2(nCmdShow);
+ try
+ {
+ return WinMain2(nCmdShow);
+ }
+ catch (...)
+ {
+ g_ExitEventLauncher.Exit(true);
+ throw;
+ }
}
catch(const CNewException &)
{
@@ -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)
diff --git a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
index af0cd8cc..c91deb07 100644
--- a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
+++ b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
@@ -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();
diff --git a/CPP/7zip/UI/FileManager/FoldersPage.cpp b/CPP/7zip/UI/FileManager/FoldersPage.cpp
index 8719dd2c..42662153 100644
--- a/CPP/7zip/UI/FileManager/FoldersPage.cpp
+++ b/CPP/7zip/UI/FileManager/FoldersPage.cpp
@@ -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()
{
- Changed();
+ 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;
}
@@ -140,8 +149,12 @@ void CFoldersPage::OnFoldersWorkButtonPath()
LONG CFoldersPage::OnApply()
{
- GetWorkDir(m_WorkDirInfo);
- m_WorkDirInfo.Save();
+ if (_needSave)
+ {
+ GetWorkDir(m_WorkDirInfo);
+ m_WorkDirInfo.Save();
+ _needSave = false;
+ }
return PSNRET_NOERROR;
}
diff --git a/CPP/7zip/UI/FileManager/FoldersPage.h b/CPP/7zip/UI/FileManager/FoldersPage.h
index 7aaa80f7..71c7bfce 100644
--- a/CPP/7zip/UI/FileManager/FoldersPage.h
+++ b/CPP/7zip/UI/FileManager/FoldersPage.h
@@ -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);
diff --git a/CPP/7zip/UI/FileManager/LangPage.cpp b/CPP/7zip/UI/FileManager/LangPage.cpp
index d9dc6c52..cb1bbaab 100644
--- a/CPP/7zip/UI/FileManager/LangPage.cpp
+++ b/CPP/7zip/UI/FileManager/LangPage.cpp
@@ -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();
- SaveRegLang(_paths[pathIndex]);
+ 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;
}
diff --git a/CPP/7zip/UI/FileManager/LangPage.h b/CPP/7zip/UI/FileManager/LangPage.h
index 589941b2..b8062573 100644
--- a/CPP/7zip/UI/FileManager/LangPage.h
+++ b/CPP/7zip/UI/FileManager/LangPage.h
@@ -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);
diff --git a/CPP/7zip/UI/FileManager/LangUtils.cpp b/CPP/7zip/UI/FileManager/LangUtils.cpp
index 9723704a..761319b5 100644
--- a/CPP/7zip/UI/FileManager/LangUtils.cpp
+++ b/CPP/7zip/UI/FileManager/LangUtils.cpp
@@ -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)
- break;
- if (index == primeLang)
+ if (index >= primeLang)
{
+ if (index > primeLang)
+ break;
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()
diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp
index 58468816..80cdd7f6 100644
--- a/CPP/7zip/UI/FileManager/ListViewDialog.cpp
+++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp
@@ -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);
diff --git a/CPP/7zip/UI/FileManager/MenuPage.cpp b/CPP/7zip/UI/FileManager/MenuPage.cpp
index 0784f92c..8852ce35 100644
--- a/CPP/7zip/UI/FileManager/MenuPage.cpp
+++ b/CPP/7zip/UI/FileManager/MenuPage.cpp
@@ -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,64 +43,147 @@ struct CContextMenuItem
UInt32 Flag;
};
-static CContextMenuItem kMenuItems[] =
+static const CContextMenuItem kMenuItems[] =
{
- { IDS_CONTEXT_OPEN, kOpen},
- { IDS_CONTEXT_OPEN, kOpenAs},
- { IDS_CONTEXT_EXTRACT, kExtract},
+ { IDS_CONTEXT_OPEN, kOpen },
+ { IDS_CONTEXT_OPEN, kOpenAs },
+ { IDS_CONTEXT_EXTRACT, kExtract },
{ IDS_CONTEXT_EXTRACT_HERE, kExtractHere },
{ IDS_CONTEXT_EXTRACT_TO, kExtractTo },
- { IDS_CONTEXT_TEST, kTest},
+ { IDS_CONTEXT_TEST, kTest },
{ 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,39 +218,68 @@ 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();
+ d--;
+ CShellDll &dll = _dlls[d];
+ if (dll.wasChanged && !dll.Path.IsEmpty())
+ {
+ 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;
+ }
}
- else
+
+ #endif
+
+ if (_cascaded_Changed || _menuIcons_Changed || _elimDup_Changed || _flags_Changed)
{
- DllUnregisterServer();
- NZipRootRegistry::DeleteContextMenuHandler();
+ CContextMenuInfo ci;
+ 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 (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();
}
- #endif
- CContextMenuInfo ci;
- ci.Cascaded = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU);
- ci.MenuIcons = IsButtonCheckedBool(IDX_SYSTEM_ICON_IN_MENU);
- ci.Flags = 0;
- for (int i = 0; i < ARRAY_SIZE(kMenuItems); i++)
- if (_listView.GetCheckState(i))
- ci.Flags |= kMenuItems[i].Flag;
- ci.Save();
+ // UnChanged();
return PSNRET_NOERROR;
}
@@ -172,14 +293,30 @@ 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:
- Changed();
- return true;
+ #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);
}
- return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
-
+
+ Changed();
+ return true;
}
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;
}
diff --git a/CPP/7zip/UI/FileManager/MenuPage.h b/CPP/7zip/UI/FileManager/MenuPage.h
index 1363687f..3807d9dd 100644
--- a/CPP/7zip/UI/FileManager/MenuPage.h
+++ b/CPP/7zip/UI/FileManager/MenuPage.h
@@ -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();
diff --git a/CPP/7zip/UI/FileManager/MenuPage.rc b/CPP/7zip/UI/FileManager/MenuPage.rc
index f20c574e..dd32898f 100644
--- a/CPP/7zip/UI/FileManager/MenuPage.rc
+++ b/CPP/7zip/UI/FileManager/MenuPage.rc
@@ -2,7 +2,7 @@
#include "../../GuiCommon.rc"
#define xc 240
-#define yc 196
+#define yc 224
IDD_MENU MY_PAGE
#include "MenuPage2.rc"
diff --git a/CPP/7zip/UI/FileManager/MenuPage2.rc b/CPP/7zip/UI/FileManager/MenuPage2.rc
index 442d1bdd..af86226d 100644
--- a/CPP/7zip/UI/FileManager/MenuPage2.rc
+++ b/CPP/7zip/UI/FileManager/MenuPage2.rc
@@ -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
diff --git a/CPP/7zip/UI/FileManager/MenuPageRes.h b/CPP/7zip/UI/FileManager/MenuPageRes.h
index 91f75710..ae0bf66d 100644
--- a/CPP/7zip/UI/FileManager/MenuPageRes.h
+++ b/CPP/7zip/UI/FileManager/MenuPageRes.h
@@ -1,9 +1,11 @@
#define IDD_MENU 2300
#define IDD_MENU_2 12300
-#define IDX_SYSTEM_INTEGRATE_TO_CONTEXT_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 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
diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
index b9dbf232..d3031f5a 100644
--- a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
+++ b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
@@ -512,7 +512,8 @@ bool OnMenuCommand(HWND hWnd, int id)
// File
case IDCLOSE:
SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
- SendMessage (hWnd, WM_CLOSE, 0, 0);
+ g_ExitEventLauncher.Exit(false);
+ SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
// Edit
diff --git a/CPP/7zip/UI/FileManager/OptionsDialog.cpp b/CPP/7zip/UI/FileManager/OptionsDialog.cpp
index fa2ab922..66e6f3c4 100644
--- a/CPP/7zip/UI/FileManager/OptionsDialog.cpp
+++ b/CPP/7zip/UI/FileManager/OptionsDialog.cpp
@@ -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);
}
diff --git a/CPP/7zip/UI/FileManager/Panel.h b/CPP/7zip/UI/FileManager/Panel.h
index 709ef0f5..fc74d556 100644
--- a/CPP/7zip/UI/FileManager/Panel.h
+++ b/CPP/7zip/UI/FileManager/Panel.h
@@ -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
diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp
index e20ddd63..0cd08d4c 100644
--- a/CPP/7zip/UI/FileManager/PanelDrag.cpp
+++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp
@@ -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;
diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
index c37ac64f..cfbc5770 100644
--- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
@@ -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,90 +93,329 @@ 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; }
void CloseAll()
{
- FOR_VECTOR (i, Handles)
+ FOR_VECTOR (i, Handles)
{
HANDLE h = Handles[i];
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
+
+ void Update(bool needFindProcessByPath /* , const CPossibleProgs &progs */)
{
- #ifndef UNDER_CE
- CRecordVector<DWORD> ids, parents;
+ /*
+ 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 (;;)
{
- CProcessSnapshot snapshot;
- if (snapshot.Create())
+ bool wasAdded = false;
+
+ FOR_VECTOR (i, sps)
{
- PROCESSENTRY32 pe;
- memset(&pe, 0, sizeof(pe));
- pe.dwSize = sizeof(pe);
- BOOL res = snapshot.GetFirstProcess(&pe);
- while (res)
+ 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))
{
- ids.Add(pe.th32ProcessID);
- parents.Add(pe.th32ParentProcessID);
- res = snapshot.GetNextProcess(&pe);
+ needAdd = true;
+ isFromProgs = true;
}
- }
- }
+ */
- for (;;)
- {
- unsigned i;
- for (i = 0; i < ids.Size(); i++)
- {
- DWORD id = ids[i];
- if (_ids.FindInSorted(parents[i]) >= 0 &&
- _ids.FindInSorted(id) < 0)
+ if (needAdd)
{
+ DEBUG_PRINT("----- OpenProcess -----");
+ DEBUG_PRINT_W(name);
HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, id);
if (hProcess)
{
- _ids.AddToUniqueSorted(id);
+ DEBUG_PRINT("----- OpenProcess OK -----");
+ // if (!isFromProgs)
+ _ids.AddToUniqueSorted(id);
Handles.Add(hProcess);
NeedWait.Add(true);
- break;
+ // Names.Add(name);
+ wasAdded = true;
+ // ProgsWereUsed = isFromProgs;
}
}
}
- if (i == ids.Size())
+
+ if (!wasAdded)
break;
}
- #endif
}
+
+ #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)
}
}
+ bool needFindProcessByPath = false;
+
if (handles.IsEmpty())
- break;
+ {
+ if (!firstPass)
+ break;
+ }
+ else
+ {
+ handles.Add(g_ExitEventLauncher._exitEvent);
+
+ DWORD waitResult = ::WaitForMultipleObjects(handles.Size(), &handles.Front(), FALSE, INFINITE);
+
+ 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;
+ }
- handles.Add(g_ExitEventLauncher._exitEvent);
+ if (firstPass && indices.Size() == 1)
+ {
+ DWORD curTime = GetTickCount() - startTime;
- DWORD waitResult = ::WaitForMultipleObjects(handles.Size(), &handles.Front(), FALSE, INFINITE);
+ /*
+ if (curTime > 5 * 1000)
+ progs.ProgNames.Clear();
+ */
- if (waitResult >= (DWORD)handles.Size() - 1)
- {
- processes.CloseAll();
- return waitResult >= (DWORD)handles.Size() ? 1 : 0;
+ 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]);
}
- processes.Update();
- processes.DisableWait(indices[waitResult]);
+
+ firstPass = false;
+
+ // Sleep(300);
+ #ifndef UNDER_CE
+ processes.Update(needFindProcessByPath /* , progs */);
+ #endif
}
- NFind::CFileInfo newFileInfo;
- if (newFileInfo.Find(tpi->FilePath))
+
+ DWORD curTime = GetTickCount() - startTime;
+
+ DEBUG_PRINT_NUM("after time = ", curTime)
+
+ processes.CloseAll();
+
+ isComplexMode = (curTime < 2 * 1000);
+
+ }
+
+ bool needCheckTimestamp = true;
+
+ for (;;)
{
- if (tpi->WasChanged(newFileInfo))
+ NFind::CFileInfo newFileInfo;
+
+ if (!newFileInfo.Find(tpi->FilePath))
+ break;
+
+ if (mainProcessWasSet)
{
- UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, tpi->RelPath);
- if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
+ if (tpi->WasChanged(newFileInfo))
{
- if (SendMessage(tpi->Window, kOpenItemChanged, 0, (LONG_PTR)tpi) != 1)
+ UString m = MyFormatNew(IDS_CANNOT_UPDATE_FILE, fs2us(tpi->FilePath));
+ if (tpi->ReadOnly)
{
- ::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE,
- fs2us(tpi->FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP);
+ 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, 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;
}
- tpi->DeleteDirAndFile();
+
+ {
+ 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)
- return;
+ 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());
+
+ if ((HANDLE)process != 0)
+ tpi->Processes.SetMainProcess(process.Detach());
- NWindows::CThread thread;
- if (thread.Create(MyThreadFunction, tpi) != S_OK)
+ ::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;
diff --git a/CPP/7zip/UI/FileManager/PanelKey.cpp b/CPP/7zip/UI/FileManager/PanelKey.cpp
index c87d04e1..26aa0b2f 100644
--- a/CPP/7zip/UI/FileManager/PanelKey.cpp
+++ b/CPP/7zip/UI/FileManager/PanelKey.cpp
@@ -18,7 +18,7 @@ struct CVKeyPropIDPair
PROPID PropID;
};
-static CVKeyPropIDPair g_VKeyPropIDPairs[] =
+static const CVKeyPropIDPair g_VKeyPropIDPairs[] =
{
{ VK_F3, kpidName },
{ VK_F4, kpidExtension },
diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.cpp b/CPP/7zip/UI/FileManager/RegistryUtils.cpp
index 84dada2b..9cc76c36 100644
--- a/CPP/7zip/UI/FileManager/RegistryUtils.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryUtils.cpp
@@ -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;
- if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
- return enabled;
- }
- return defaultValue;
+ bool enabled = false;
+ if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
+ 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 SaveShowRealFileIcons(bool show) { SaveOption(kShowRealFileIcons, show); }
-bool ReadShowRealFileIcons() { return ReadOption(kShowRealFileIcons, false); }
-
-void Save_ShowSystemMenu(bool show) { SaveOption(kShowSystemMenu, show); }
-bool Read_ShowSystemMenu(){ return ReadOption(kShowSystemMenu, false); }
-
-void SaveFullRow(bool enable) { SaveOption(kFullRow, enable); }
-bool ReadFullRow() { return ReadOption(kFullRow, 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);
+
+ SaveOption(kShowSystemMenu, ShowSystemMenu);
+}
-void SaveShowGrid(bool enable) { SaveOption(kShowGrid, enable); }
-bool ReadShowGrid(){ return ReadOption(kShowGrid, false); }
+void CFmSettings::Load()
+{
+ ShowDots = false;
+ ShowRealFileIcons = false;
+ FullRow = false;
+ ShowGrid = false;
+ SingleClick = false;
+ AlternativeSelection = false;
+ // Underline = false;
-void SaveAlternativeSelection(bool enable) { SaveOption(kAlternativeSelection, enable); }
-bool ReadAlternativeSelection(){ return ReadOption(kAlternativeSelection, false); }
+ ShowSystemMenu = false;
-void SaveSingleClick(bool enable) { SaveOption(kSingleClick, enable); }
-bool ReadSingleClick(){ return ReadOption(kSingleClick, 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);
+
+ ReadOption(key, kShowSystemMenu, ShowSystemMenu );
+ }
+}
-/*
-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); }
diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.h b/CPP/7zip/UI/FileManager/RegistryUtils.h
index 678a3375..b731778b 100644
--- a/CPP/7zip/UI/FileManager/RegistryUtils.h
+++ b/CPP/7zip/UI/FileManager/RegistryUtils.h
@@ -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();
-
-void SaveShowRealFileIcons(bool show);
-bool ReadShowRealFileIcons();
-
-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();
+struct CFmSettings
+{
+ bool ShowDots;
+ bool ShowRealFileIcons;
+ bool FullRow;
+ bool ShowGrid;
+ bool SingleClick;
+ bool AlternativeSelection;
+ // bool Underline;
+
+ bool ShowSystemMenu;
+
+ 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);
diff --git a/CPP/7zip/UI/FileManager/SettingsPage.cpp b/CPP/7zip/UI/FileManager/SettingsPage.cpp
index cecaf808..07121b28 100644
--- a/CPP/7zip/UI/FileManager/SettingsPage.cpp
+++ b/CPP/7zip/UI/FileManager/SettingsPage.cpp
@@ -35,21 +35,29 @@ 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();
return CPropertyPage::OnInit();
@@ -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));
-
- SaveFullRow(IsButtonCheckedBool(IDX_SETTINGS_FULL_ROW));
- SaveShowGrid(IsButtonCheckedBool(IDX_SETTINGS_SHOW_GRID));
- SaveAlternativeSelection(IsButtonCheckedBool(IDX_SETTINGS_ALTERNATIVE_SELECTION));
+ 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;
+ }
+
#ifndef UNDER_CE
- if (IsLargePageSupported())
+ if (_largePages_wasChanged)
{
- bool enable = IsButtonCheckedBool(IDX_SETTINGS_LARGE_PAGES);
- NSecurity::EnablePrivilege_LockMemory(enable);
- SaveLockMemoryEnable(enable);
+ 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:
- Changed();
- return true;
+ _largePages_wasChanged = true;
+ break;
+
+ default:
+ return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}
- return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
+
+ Changed();
+ return true;
}
diff --git a/CPP/7zip/UI/FileManager/SettingsPage.h b/CPP/7zip/UI/FileManager/SettingsPage.h
index e7e5d73e..77cc67b9 100644
--- a/CPP/7zip/UI/FileManager/SettingsPage.h
+++ b/CPP/7zip/UI/FileManager/SettingsPage.h
@@ -8,6 +8,10 @@
class CSettingsPage: public NWindows::NControl::CPropertyPage
{
+ bool _wasChanged;
+
+ bool _largePages_wasChanged;
+
// void EnableSubItems();
bool OnButtonClicked(int buttonID, HWND buttonHWND);
public:
diff --git a/CPP/7zip/UI/FileManager/SettingsPage2.rc b/CPP/7zip/UI/FileManager/SettingsPage2.rc
index 66629612..277f45d5 100644
--- a/CPP/7zip/UI/FileManager/SettingsPage2.rc
+++ b/CPP/7zip/UI/FileManager/SettingsPage2.rc
@@ -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
diff --git a/CPP/7zip/UI/FileManager/SystemPage.cpp b/CPP/7zip/UI/FileManager/SystemPage.cpp
index d60d7b4f..5214a55c 100644
--- a/CPP/7zip/UI/FileManager/SystemPage.cpp
+++ b/CPP/7zip/UI/FileManager/SystemPage.cpp
@@ -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;
}
diff --git a/CPP/7zip/UI/FileManager/SystemPage.h b/CPP/7zip/UI/FileManager/SystemPage.h
index d38bd1b0..761a49ac 100644
--- a/CPP/7zip/UI/FileManager/SystemPage.h
+++ b/CPP/7zip/UI/FileManager/SystemPage.h
@@ -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();
diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h
index 2430230b..02308555 100644
--- a/CPP/Common/MyString.h
+++ b/CPP/Common/MyString.h
@@ -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); }
diff --git a/CPP/Windows/Control/Trackbar.h b/CPP/Windows/Control/Trackbar.h
index c6d31112..313e0c85 100644
--- a/CPP/Windows/Control/Trackbar.h
+++ b/CPP/Windows/Control/Trackbar.h
@@ -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); }
};
}}
diff --git a/DOC/7zip.inf b/DOC/7zip.inf
index 2e6f722a..aabe2246 100644
--- a/DOC/7zip.inf
+++ b/DOC/7zip.inf
@@ -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
diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi
index 55d7af41..b166b429 100644
--- a/DOC/7zip.nsi
+++ b/DOC/7zip.nsi
@@ -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
diff --git a/DOC/7zip.wxs b/DOC/7zip.wxs
index 8f430923..2f9e01fc 100644
--- a/DOC/7zip.wxs
+++ b/DOC/7zip.wxs
@@ -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>
diff --git a/DOC/readme.txt b/DOC/readme.txt
index db7b229d..b1f8d93f 100644
--- a/DOC/readme.txt
+++ b/DOC/readme.txt
@@ -1,4 +1,4 @@
-7-Zip 15.12 Sources
+7-Zip 15.13 Sources
-------------------
7-Zip is a file archiver for Windows.