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-06-15 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:54 +0300
commit54490d51d5c6b0d794dcbad2d634d4c95fc25b6c (patch)
treec3c413656432c0ef87b2841c80e42b55ad17d4e8 /CPP/7zip/UI/FileManager
parent0713a3ab803e57401f18432148b4139e5fe6e5dd (diff)
15.0515.05
Diffstat (limited to 'CPP/7zip/UI/FileManager')
-rw-r--r--CPP/7zip/UI/FileManager/AboutDialog.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/AltStreamsFolder.cpp839
-rw-r--r--CPP/7zip/UI/FileManager/AltStreamsFolder.h100
-rw-r--r--CPP/7zip/UI/FileManager/App.cpp201
-rw-r--r--CPP/7zip/UI/FileManager/App.h2
-rw-r--r--CPP/7zip/UI/FileManager/BrowseDialog.cpp26
-rw-r--r--CPP/7zip/UI/FileManager/BrowseDialog.h2
-rw-r--r--CPP/7zip/UI/FileManager/EditPage.rc2
-rw-r--r--CPP/7zip/UI/FileManager/ExtractCallback.cpp453
-rw-r--r--CPP/7zip/UI/FileManager/ExtractCallback.h49
-rw-r--r--CPP/7zip/UI/FileManager/FM.cpp48
-rw-r--r--CPP/7zip/UI/FileManager/FM.dsp20
-rw-r--r--CPP/7zip/UI/FileManager/FM.mak1
-rw-r--r--CPP/7zip/UI/FileManager/FSDrives.cpp101
-rw-r--r--CPP/7zip/UI/FileManager/FSDrives.h8
-rw-r--r--CPP/7zip/UI/FileManager/FSFolder.cpp88
-rw-r--r--CPP/7zip/UI/FileManager/FSFolder.h30
-rw-r--r--CPP/7zip/UI/FileManager/FSFolderCopy.cpp576
-rw-r--r--CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp8
-rw-r--r--CPP/7zip/UI/FileManager/FilePlugins.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/FoldersPage.rc2
-rw-r--r--CPP/7zip/UI/FileManager/IFolder.h17
-rw-r--r--CPP/7zip/UI/FileManager/LangPage.cpp5
-rw-r--r--CPP/7zip/UI/FileManager/LangPage.rc2
-rw-r--r--CPP/7zip/UI/FileManager/LangUtils.cpp7
-rw-r--r--CPP/7zip/UI/FileManager/LangUtils.h4
-rw-r--r--CPP/7zip/UI/FileManager/LinkDialog.cpp4
-rw-r--r--CPP/7zip/UI/FileManager/MenuPage.rc2
-rw-r--r--CPP/7zip/UI/FileManager/MyLoadMenu.cpp59
-rw-r--r--CPP/7zip/UI/FileManager/MyLoadMenu.h24
-rw-r--r--CPP/7zip/UI/FileManager/NetFolder.cpp16
-rw-r--r--CPP/7zip/UI/FileManager/OverwriteDialog.cpp10
-rw-r--r--CPP/7zip/UI/FileManager/Panel.cpp117
-rw-r--r--CPP/7zip/UI/FileManager/Panel.h131
-rw-r--r--CPP/7zip/UI/FileManager/PanelCopy.cpp72
-rw-r--r--CPP/7zip/UI/FileManager/PanelCrc.cpp105
-rw-r--r--CPP/7zip/UI/FileManager/PanelDrag.cpp23
-rw-r--r--CPP/7zip/UI/FileManager/PanelFolderChange.cpp421
-rw-r--r--CPP/7zip/UI/FileManager/PanelItemOpen.cpp74
-rw-r--r--CPP/7zip/UI/FileManager/PanelItems.cpp87
-rw-r--r--CPP/7zip/UI/FileManager/PanelListNotify.cpp252
-rw-r--r--CPP/7zip/UI/FileManager/PanelMenu.cpp179
-rw-r--r--CPP/7zip/UI/FileManager/PanelOperations.cpp99
-rw-r--r--CPP/7zip/UI/FileManager/PanelSelect.cpp32
-rw-r--r--CPP/7zip/UI/FileManager/PanelSort.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/PanelSplitFile.cpp32
-rw-r--r--CPP/7zip/UI/FileManager/PluginInterface.h2
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog2.cpp70
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog2.h13
-rw-r--r--CPP/7zip/UI/FileManager/PropertyName.rc2
-rw-r--r--CPP/7zip/UI/FileManager/PropertyNameRes.h2
-rw-r--r--CPP/7zip/UI/FileManager/RegistryAssociations.cpp3
-rw-r--r--CPP/7zip/UI/FileManager/RootFolder.cpp93
-rw-r--r--CPP/7zip/UI/FileManager/RootFolder.h12
-rw-r--r--CPP/7zip/UI/FileManager/SettingsPage.rc2
-rw-r--r--CPP/7zip/UI/FileManager/SplitDialog.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/StringUtils.cpp5
-rw-r--r--CPP/7zip/UI/FileManager/SystemPage.cpp48
-rw-r--r--CPP/7zip/UI/FileManager/SystemPage.h2
-rw-r--r--CPP/7zip/UI/FileManager/SystemPage.rc17
-rw-r--r--CPP/7zip/UI/FileManager/SystemPageRes.h1
-rw-r--r--CPP/7zip/UI/FileManager/TextPairs.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/TextPairs.h2
-rw-r--r--CPP/7zip/UI/FileManager/UpdateCallback100.cpp75
-rw-r--r--CPP/7zip/UI/FileManager/UpdateCallback100.h24
-rw-r--r--CPP/7zip/UI/FileManager/ViewSettings.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/makefile1
-rw-r--r--CPP/7zip/UI/FileManager/resource.h1
-rw-r--r--CPP/7zip/UI/FileManager/resource.rc2
69 files changed, 3368 insertions, 1351 deletions
diff --git a/CPP/7zip/UI/FileManager/AboutDialog.cpp b/CPP/7zip/UI/FileManager/AboutDialog.cpp
index 10d76671..35e67753 100644
--- a/CPP/7zip/UI/FileManager/AboutDialog.cpp
+++ b/CPP/7zip/UI/FileManager/AboutDialog.cpp
@@ -29,7 +29,7 @@ bool CAboutDialog::OnInit()
UString s = L"7-Zip " LLL(MY_VERSION);
#ifdef MY_CPU_64BIT
s += L" [";
- s += LangString(IDS_PROP_BIT64);
+ AddLangString(s, IDS_PROP_BIT64);
s += L']';
#endif
diff --git a/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp b/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
new file mode 100644
index 00000000..c209bf35
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
@@ -0,0 +1,839 @@
+// AltStreamsFolder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/Wildcard.h"
+
+#include "../../../Windows/ErrorMsg.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileIO.h"
+#include "../../../Windows/FileName.h"
+#include "../../../Windows/PropVariant.h"
+
+#include "../Common/ExtractingFilePath.h"
+
+#include "../Agent/IFolderArchive.h"
+
+#include "AltStreamsFolder.h"
+#include "FSDrives.h"
+#include "FSFolder.h"
+
+#include "SysIconUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+using namespace NDir;
+using namespace NName;
+
+#ifndef USE_UNICODE_FSTRING
+int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2);
+#endif
+
+#ifndef UNDER_CE
+
+namespace NFsFolder
+{
+bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size);
+}
+
+#endif
+
+namespace NAltStreamsFolder {
+
+static const Byte kProps[] =
+{
+ kpidName,
+ kpidSize,
+ kpidPackSize
+};
+
+static unsigned GetFsParentPrefixSize(const FString &path)
+{
+ if (IsNetworkShareRootPath(path))
+ return 0;
+ unsigned prefixSize = GetRootPrefixSize(path);
+ if (prefixSize == 0 || prefixSize >= path.Len())
+ return 0;
+ FString parentPath = path;
+ int pos = parentPath.ReverseFind_PathSepar();
+ if (pos < 0)
+ return 0;
+ if (pos == (int)parentPath.Len() - 1)
+ {
+ parentPath.DeleteBack();
+ pos = parentPath.ReverseFind_PathSepar();
+ if (pos < 0)
+ return 0;
+ }
+ if ((unsigned)pos + 1 < prefixSize)
+ return 0;
+ return pos + 1;
+}
+
+HRESULT CAltStreamsFolder::Init(const FString &path /* , IFolderFolder *parentFolder */)
+{
+ // _parentFolder = parentFolder;
+ if (path.Back() != ':')
+ return E_FAIL;
+
+ _pathPrefix = path;
+ _pathBaseFile = path;
+ _pathBaseFile.DeleteBack();
+
+ {
+ CFileInfo fi;
+ if (!fi.Find(_pathBaseFile))
+ return GetLastError();
+ }
+
+ unsigned prefixSize = GetFsParentPrefixSize(_pathBaseFile);
+ if (prefixSize == 0)
+ return S_OK;
+ FString parentPath = _pathBaseFile;
+ parentPath.DeleteFrom(prefixSize);
+
+ _findChangeNotification.FindFirst(parentPath, false,
+ FILE_NOTIFY_CHANGE_FILE_NAME
+ | FILE_NOTIFY_CHANGE_DIR_NAME
+ | FILE_NOTIFY_CHANGE_ATTRIBUTES
+ | FILE_NOTIFY_CHANGE_SIZE
+ | FILE_NOTIFY_CHANGE_LAST_WRITE
+ /*
+ | FILE_NOTIFY_CHANGE_LAST_ACCESS
+ | FILE_NOTIFY_CHANGE_CREATION
+ | FILE_NOTIFY_CHANGE_SECURITY
+ */
+ );
+ /*
+ if (_findChangeNotification.IsHandleAllocated())
+ return S_OK;
+ return GetLastError();
+ */
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::LoadItems()
+{
+ Int32 dummy;
+ WasChanged(&dummy);
+ Clear();
+
+ CStreamEnumerator enumerator(_pathBaseFile);
+
+ CStreamInfo si;
+ for (;;)
+ {
+ bool found;
+ if (!enumerator.Next(si, found))
+ {
+ // if (GetLastError() == ERROR_ACCESS_DENIED)
+ // break;
+ // return E_FAIL;
+ break;
+ }
+ if (!found)
+ break;
+ if (si.IsMainStream())
+ continue;
+ CAltStream ss;
+ ss.Name = si.GetReducedName();
+ if (!ss.Name.IsEmpty() && ss.Name[0] == ':')
+ ss.Name.Delete(0);
+
+ ss.Size = si.Size;
+ ss.PackSize_Defined = false;
+ ss.PackSize = si.Size;
+ Streams.Add(ss);
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = Streams.Size();
+ return S_OK;
+}
+
+#ifdef USE_UNICODE_FSTRING
+
+STDMETHODIMP CAltStreamsFolder::GetItemPrefix(UInt32 /* index */, const wchar_t **name, unsigned *len)
+{
+ *name = 0;
+ *len = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len)
+{
+ *name = 0;
+ *len = 0;
+ {
+ const CAltStream &ss = Streams[index];
+ *name = ss.Name;
+ *len = ss.Name.Len();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt64) CAltStreamsFolder::GetItemSize(UInt32 index)
+{
+ return Streams[index].Size;
+}
+
+#endif
+
+
+STDMETHODIMP CAltStreamsFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant prop;
+ {
+ CAltStream &ss = Streams[index];
+ switch (propID)
+ {
+ case kpidIsDir: prop = false; break;
+ case kpidIsAltStream: prop = true; break;
+ case kpidName: prop = ss.Name; break;
+ case kpidSize: prop = ss.Size; break;
+ case kpidPackSize:
+ #ifdef UNDER_CE
+ prop = ss.Size;
+ #else
+ if (!ss.PackSize_Defined)
+ {
+ ss.PackSize_Defined = true;
+ if (!NFsFolder::MyGetCompressedFileSizeW(_pathPrefix + us2fs(ss.Name), ss.PackSize))
+ ss.PackSize = ss.Size;
+ }
+ prop = ss.PackSize;
+ #endif
+ break;
+ }
+ }
+
+ prop.Detach(value);
+ return S_OK;
+}
+
+
+// returns Position of extension including '.'
+
+static inline const wchar_t *GetExtensionPtr(const UString &name)
+{
+ int dotPos = name.ReverseFind_Dot();
+ return name.Ptr((dotPos < 0) ? name.Len() : dotPos);
+}
+
+STDMETHODIMP_(Int32) CAltStreamsFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 /* propIsRaw */)
+{
+ const CAltStream &ss1 = Streams[index1];
+ const CAltStream &ss2 = Streams[index2];
+
+ switch (propID)
+ {
+ case kpidName:
+ {
+ return CompareFileNames_ForFolderList(ss1.Name, ss2.Name);
+ // return MyStringCompareNoCase(ss1.Name, ss2.Name);
+ }
+ case kpidSize:
+ return MyCompare(ss1.Size, ss2.Size);
+ case kpidPackSize:
+ {
+ #ifdef UNDER_CE
+ return MyCompare(ss1.Size, ss2.Size);
+ #else
+ // PackSize can be undefined here
+ return MyCompare(
+ ss1.PackSize,
+ ss2.PackSize);
+ #endif
+ }
+
+ case kpidExtension:
+ return CompareFileNames_ForFolderList(
+ GetExtensionPtr(ss1.Name),
+ GetExtensionPtr(ss2.Name));
+ }
+
+ return 0;
+}
+
+STDMETHODIMP CAltStreamsFolder::BindToFolder(UInt32 /* index */, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ return E_INVALIDARG;
+}
+
+STDMETHODIMP CAltStreamsFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ return E_INVALIDARG;
+}
+
+static const CFSTR kSuperPrefix = FTEXT("\\\\?\\");
+
+STDMETHODIMP CAltStreamsFolder::BindToParentFolder(IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ /*
+ if (_parentFolder)
+ {
+ CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
+ *resultFolder = parentFolder.Detach();
+ return S_OK;
+ }
+ */
+
+ if (IsDriveRootPath_SuperAllowed(_pathBaseFile))
+ {
+ CFSDrives *drivesFolderSpec = new CFSDrives;
+ CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
+ drivesFolderSpec->Init();
+ *resultFolder = drivesFolder.Detach();
+ return S_OK;
+ }
+
+ /*
+ parentPath.DeleteFrom(pos + 1);
+
+ if (parentPath == kSuperPrefix)
+ {
+ #ifdef UNDER_CE
+ *resultFolder = 0;
+ #else
+ CFSDrives *drivesFolderSpec = new CFSDrives;
+ CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
+ drivesFolderSpec->Init(false, true);
+ *resultFolder = drivesFolder.Detach();
+ #endif
+ return S_OK;
+ }
+
+ FString parentPathReduced = parentPath.Left(pos);
+
+ #ifndef UNDER_CE
+ pos = parentPathReduced.ReverseFind_PathSepar();
+ if (pos == 1)
+ {
+ if (!IS_PATH_SEPAR_CHAR(parentPath[0]))
+ return E_FAIL;
+ CNetFolder *netFolderSpec = new CNetFolder;
+ CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
+ netFolderSpec->Init(fs2us(parentPath));
+ *resultFolder = netFolder.Detach();
+ return S_OK;
+ }
+ #endif
+
+ CFSFolder *parentFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
+ RINOK(parentFolderSpec->Init(parentPath, 0));
+ *resultFolder = parentFolder.Detach();
+ */
+
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = ARRAY_SIZE(kProps);
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::GetPropertyInfo IMP_IFolderFolder_GetProp(kProps)
+
+STDMETHODIMP CAltStreamsFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ switch (propID)
+ {
+ case kpidType: prop = "AltStreamsFolder"; break;
+ case kpidPath: prop = fs2us(_pathPrefix); break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CAltStreamsFolder::WasChanged(Int32 *wasChanged)
+{
+ bool wasChangedMain = false;
+ for (;;)
+ {
+ if (!_findChangeNotification.IsHandleAllocated())
+ {
+ *wasChanged = BoolToInt(false);
+ return S_OK;
+ }
+
+ DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0);
+ bool wasChangedLoc = (waitResult == WAIT_OBJECT_0);
+ if (wasChangedLoc)
+ {
+ _findChangeNotification.FindNext();
+ wasChangedMain = true;
+ }
+ else
+ break;
+ }
+ *wasChanged = BoolToInt(wasChangedMain);
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::Clone(IFolderFolder **resultFolder)
+{
+ CAltStreamsFolder *folderSpec = new CAltStreamsFolder;
+ CMyComPtr<IFolderFolder> folderNew = folderSpec;
+ folderSpec->Init(_pathPrefix);
+ *resultFolder = folderNew.Detach();
+ return S_OK;
+}
+
+void CAltStreamsFolder::GetAbsPath(const wchar_t *name, FString &absPath)
+{
+ absPath.Empty();
+ if (!IsAbsolutePath(name))
+ absPath += _pathPrefix;
+ absPath += us2fs(name);
+}
+
+
+
+static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
+ const wchar_t *message, const FString &fileName)
+{
+ UString s = message;
+ s += L" : ";
+ s += fs2us(fileName);
+ return callback->ShowMessage(s);
+}
+
+static HRESULT SendMessageError(IFolderArchiveUpdateCallback *callback,
+ const wchar_t *message, const FString &fileName)
+{
+ UString s = message;
+ s += L" : ";
+ s += fs2us(fileName);
+ return callback->UpdateErrorMessage(s);
+}
+
+static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
+ const char *message, const FString &fileName)
+{
+ return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
+}
+
+/*
+static HRESULT SendMessageError(IFolderArchiveUpdateCallback *callback,
+ const char *message, const FString &fileName)
+{
+ return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
+}
+*/
+
+STDMETHODIMP CAltStreamsFolder::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CAltStreamsFolder::CreateFile(const wchar_t *name, IProgress * /* progress */)
+{
+ FString absPath;
+ GetAbsPath(name, absPath);
+ NIO::COutFile outFile;
+ if (!outFile.Create(absPath, false))
+ return ::GetLastError();
+ return S_OK;
+}
+
+static DWORD Return_LastError_or_FAIL()
+{
+ DWORD errorCode = GetLastError();
+ if (errorCode == 0)
+ errorCode = (DWORD)E_FAIL;
+ return errorCode;
+}
+
+static UString GetLastErrorMessage()
+{
+ return NError::MyFormatMessage(Return_LastError_or_FAIL());
+}
+
+static HRESULT UpdateFile(NFsFolder::CCopyStateIO &state, CFSTR inPath, CFSTR outPath, IFolderArchiveUpdateCallback *callback)
+{
+ if (NFind::DoesFileOrDirExist(outPath))
+ {
+ RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), outPath));
+ CFileInfo fi;
+ if (fi.Find(inPath))
+ {
+ if (state.TotalSize >= fi.Size)
+ state.TotalSize -= fi.Size;
+ }
+ return S_OK;
+ }
+
+ {
+ if (callback)
+ RINOK(callback->CompressOperation(fs2us(inPath)));
+ RINOK(state.MyCopyFile(inPath, outPath));
+ if (state.ErrorFileIndex >= 0)
+ {
+ if (state.ErrorMessage.IsEmpty())
+ state.ErrorMessage = GetLastErrorMessage();
+ FString errorName;
+ if (state.ErrorFileIndex == 0)
+ errorName = inPath;
+ else
+ errorName = outPath;
+ if (callback)
+ RINOK(SendMessageError(callback, state.ErrorMessage, errorName));
+ }
+ if (callback)
+ RINOK(callback->OperationResult(0));
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress)
+{
+ CMyComPtr<IFolderArchiveUpdateCallback> callback;
+ if (progress)
+ {
+ RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback));
+ }
+
+ FString destPath = _pathPrefix + us2fs(newName);
+
+ const CAltStream &ss = Streams[index];
+
+ if (callback)
+ {
+ RINOK(callback->SetNumFiles(1));
+ RINOK(callback->SetTotal(ss.Size));
+ }
+
+ NFsFolder::CCopyStateIO state;
+ state.Progress = progress;
+ state.TotalSize = 0;
+ state.DeleteSrcFile = true;
+
+ return UpdateFile(state, _pathPrefix + us2fs(ss.Name), destPath, callback);
+}
+
+STDMETHODIMP CAltStreamsFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress)
+{
+ RINOK(progress->SetTotal(numItems));
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ const CAltStream &ss = Streams[indices[i]];
+ const FString fullPath = _pathPrefix + us2fs(ss.Name);
+ bool result = DeleteFileAlways(fullPath);
+ if (!result)
+ return Return_LastError_or_FAIL();
+ UInt64 completed = i;
+ RINOK(progress->SetCompleted(&completed));
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::SetProperty(UInt32 /* index */, PROPID /* propID */,
+ const PROPVARIANT * /* value */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CAltStreamsFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)
+{
+ const CAltStream &ss = Streams[index];
+ *iconIndex = 0;
+ int iconIndexTemp;
+ if (GetRealIconIndex(_pathPrefix + us2fs(ss.Name),
+ 0 // fi.Attrib
+ , iconIndexTemp) != 0)
+ {
+ *iconIndex = iconIndexTemp;
+ return S_OK;
+ }
+ return Return_LastError_or_FAIL();
+}
+
+/*
+class CGetProp:
+ public IGetProp,
+ public CMyUnknownImp
+{
+public:
+ // const CArc *Arc;
+ // UInt32 IndexInArc;
+ UString Name; // relative path
+ UInt64 Size;
+
+ MY_UNKNOWN_IMP1(IGetProp)
+ INTERFACE_IGetProp(;)
+};
+
+STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value)
+{
+ if (propID == kpidName)
+ {
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop = Name;
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+ }
+ if (propID == kpidSize)
+ {
+ NCOM::CPropVariant prop = Size;
+ prop.Detach(value);
+ return S_OK;
+ }
+ NCOM::CPropVariant prop;
+ prop.Detach(value);
+ return S_OK;
+}
+*/
+
+static HRESULT CopyStream(
+ NFsFolder::CCopyStateIO &state,
+ const FString &srcPath,
+ const CFileInfo &srcFileInfo,
+ const CAltStream &srcAltStream,
+ const FString &destPathSpec,
+ IFolderOperationsExtractCallback *callback)
+{
+ FString destPath = destPathSpec;
+ if (CompareFileNames(destPath, srcPath) == 0)
+ {
+ RINOK(SendMessageError(callback, "can not copy file onto itself", destPath));
+ return E_ABORT;
+ }
+
+ Int32 writeAskResult;
+ CMyComBSTR destPathResult;
+ RINOK(callback->AskWrite(
+ fs2us(srcPath),
+ BoolToInt(false),
+ &srcFileInfo.MTime, &srcAltStream.Size,
+ fs2us(destPath),
+ &destPathResult,
+ &writeAskResult));
+
+ if (IntToBool(writeAskResult))
+ {
+ RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
+ FString destPathNew = us2fs((LPCOLESTR)destPathResult);
+ RINOK(state.MyCopyFile(srcPath, destPathNew));
+ if (state.ErrorFileIndex >= 0)
+ {
+ if (state.ErrorMessage.IsEmpty())
+ state.ErrorMessage = GetLastErrorMessage();
+ FString errorName;
+ if (state.ErrorFileIndex == 0)
+ errorName = srcPath;
+ else
+ errorName = destPathNew;
+ RINOK(SendMessageError(callback, state.ErrorMessage, errorName));
+ return E_ABORT;
+ }
+ state.StartPos += state.CurrentSize;
+ }
+ else
+ {
+ if (state.TotalSize >= srcAltStream.Size)
+ {
+ state.TotalSize -= srcAltStream.Size;
+ RINOK(state.Progress->SetTotal(state.TotalSize));
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
+ Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback)
+{
+ if (numItems == 0)
+ return S_OK;
+
+ /*
+ CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
+ RINOK(callback->QueryInterface(IID_IFolderExtractToStreamCallback, (void **)&ExtractToStreamCallback));
+ if (ExtractToStreamCallback)
+ {
+ Int32 useStreams = 0;
+ if (ExtractToStreamCallback->UseExtractToStream(&useStreams) != S_OK)
+ useStreams = 0;
+ if (useStreams == 0)
+ ExtractToStreamCallback.Release();
+ }
+ */
+
+ UInt64 totalSize = 0;
+ {
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ totalSize += Streams[indices[i]].Size;
+ }
+ RINOK(callback->SetTotal(totalSize));
+ RINOK(callback->SetNumFiles(numItems));
+ }
+
+ /*
+ if (ExtractToStreamCallback)
+ {
+ CGetProp *GetProp_Spec = new CGetProp;
+ CMyComPtr<IGetProp> GetProp= GetProp_Spec;
+
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt32 index = indices[i];
+ const CAltStream &ss = Streams[index];
+ GetProp_Spec->Name = ss.Name;
+ GetProp_Spec->Size = ss.Size;
+ CMyComPtr<ISequentialOutStream> outStream;
+ RINOK(ExtractToStreamCallback->GetStream7(GetProp_Spec->Name, BoolToInt(false), &outStream,
+ NArchive::NExtract::NAskMode::kExtract, GetProp)); // isDir
+ FString srcPath;
+ GetFullPath(ss, srcPath);
+ RINOK(ExtractToStreamCallback->PrepareOperation7(NArchive::NExtract::NAskMode::kExtract));
+ RINOK(ExtractToStreamCallback->SetOperationResult7(NArchive::NExtract::NOperationResult::kOK, BoolToInt(false))); // _encrypted
+ // RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback, completedSize));
+ }
+ return S_OK;
+ }
+ */
+
+ FString destPath = us2fs(path);
+ if (destPath.IsEmpty() /* && !ExtractToStreamCallback */)
+ return E_INVALIDARG;
+
+ bool isAltDest = NName::IsAltPathPrefix(destPath);;
+ bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
+
+ if (isDirectPath)
+ {
+ if (numItems > 1)
+ return E_INVALIDARG;
+ }
+
+ CFileInfo fi;
+ if (!fi.Find(_pathBaseFile))
+ return GetLastError();
+
+ NFsFolder::CCopyStateIO state;
+ state.Progress = callback;
+ state.DeleteSrcFile = IntToBool(moveMode);
+ state.TotalSize = totalSize;
+
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt32 index = indices[i];
+ const CAltStream &ss = Streams[index];
+ FString destPath2 = destPath;
+ if (!isDirectPath)
+ destPath2 += us2fs(Get_Correct_FsFile_Name(ss.Name));
+ FString srcPath;
+ GetFullPath(ss, srcPath);
+ RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback));
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP CAltStreamsFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
+ const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
+{
+ /*
+ if (numItems == 0)
+ return S_OK;
+
+ CMyComPtr<IFolderArchiveUpdateCallback> callback;
+ if (progress)
+ {
+ RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback));
+ }
+
+ if (CompareFileNames(fromFolderPath, fs2us(_pathPrefix)) == 0)
+ {
+ RINOK(SendMessageError(callback, "can not copy file onto itself", _pathPrefix));
+ return E_ABORT;
+ }
+
+ if (callback)
+ RINOK(callback->SetNumFiles(numItems));
+
+ UInt64 totalSize = 0;
+
+ UInt32 i;
+
+ FString path;
+ for (i = 0; i < numItems; i++)
+ {
+ path = us2fs(fromFolderPath);
+ path += us2fs(itemsPaths[i]);
+
+ CFileInfo fi;
+ if (!fi.Find(path))
+ return ::GetLastError();
+ if (fi.IsDir())
+ return E_NOTIMPL;
+ totalSize += fi.Size;
+ }
+
+ RINOK(progress->SetTotal(totalSize));
+
+ // UInt64 completedSize = 0;
+
+ NFsFolder::CCopyStateIO state;
+ state.Progress = progress;
+ state.DeleteSrcFile = IntToBool(moveMode);
+ state.TotalSize = totalSize;
+
+ // we need to clear READ-ONLY of parent before creating alt stream
+ {
+ DWORD attrib = GetFileAttrib(_pathBaseFile);
+ if (attrib != INVALID_FILE_ATTRIBUTES
+ && (attrib & FILE_ATTRIBUTE_READONLY) != 0)
+ {
+ if (!SetFileAttrib(_pathBaseFile, attrib & ~FILE_ATTRIBUTE_READONLY))
+ {
+ if (callback)
+ {
+ RINOK(SendMessageError(callback, GetLastErrorMessage(), _pathBaseFile));
+ return S_OK;
+ }
+ return Return_LastError_or_FAIL();
+ }
+ }
+ }
+
+ for (i = 0; i < numItems; i++)
+ {
+ path = us2fs(fromFolderPath);
+ path += us2fs(itemsPaths[i]);
+
+ FString destPath = _pathPrefix + us2fs(itemsPaths[i]);
+
+ RINOK(UpdateFile(state, path, destPath, callback));
+ }
+
+ return S_OK;
+ */
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CAltStreamsFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
+
+}
diff --git a/CPP/7zip/UI/FileManager/AltStreamsFolder.h b/CPP/7zip/UI/FileManager/AltStreamsFolder.h
new file mode 100644
index 00000000..ccd0a58f
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/AltStreamsFolder.h
@@ -0,0 +1,100 @@
+// AltStreamsFolder.h
+
+#ifndef __ALT_STREAMS_FOLDER_H
+#define __ALT_STREAMS_FOLDER_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../../Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "IFolder.h"
+
+namespace NAltStreamsFolder {
+
+class CAltStreamsFolder;
+
+struct CAltStream
+{
+ UInt64 Size;
+ UInt64 PackSize;
+ bool PackSize_Defined;
+ UString Name;
+};
+
+
+class CAltStreamsFolder:
+ public IFolderFolder,
+ public IFolderCompare,
+ #ifdef USE_UNICODE_FSTRING
+ public IFolderGetItemName,
+ #endif
+ public IFolderWasChanged,
+ public IFolderOperations,
+ // public IFolderOperationsDeleteToRecycleBin,
+ public IFolderClone,
+ public IFolderGetSystemIconIndex,
+ public CMyUnknownImp
+{
+public:
+ MY_QUERYINTERFACE_BEGIN2(IFolderFolder)
+ MY_QUERYINTERFACE_ENTRY(IFolderCompare)
+ #ifdef USE_UNICODE_FSTRING
+ MY_QUERYINTERFACE_ENTRY(IFolderGetItemName)
+ #endif
+ MY_QUERYINTERFACE_ENTRY(IFolderWasChanged)
+ // MY_QUERYINTERFACE_ENTRY(IFolderOperationsDeleteToRecycleBin)
+ MY_QUERYINTERFACE_ENTRY(IFolderOperations)
+ MY_QUERYINTERFACE_ENTRY(IFolderClone)
+ MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex)
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+
+ INTERFACE_FolderFolder(;)
+ INTERFACE_FolderOperations(;)
+
+ STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
+
+ #ifdef USE_UNICODE_FSTRING
+ INTERFACE_IFolderGetItemName(;)
+ #endif
+ STDMETHOD(WasChanged)(Int32 *wasChanged);
+ STDMETHOD(Clone)(IFolderFolder **resultFolder);
+
+ STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex);
+
+private:
+ FString _pathBaseFile; // folder
+ FString _pathPrefix; // folder:
+
+ CObjectVector<CAltStream> Streams;
+ // CMyComPtr<IFolderFolder> _parentFolder;
+
+ NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification;
+
+ HRESULT GetItemFullSize(unsigned index, UInt64 &size, IProgress *progress);
+ void GetAbsPath(const wchar_t *name, FString &absPath);
+
+public:
+ // path must be with ':' at tail
+ HRESULT Init(const FString &path /* , IFolderFolder *parentFolder */);
+
+ CAltStreamsFolder() {}
+
+ void GetFullPath(const CAltStream &item, FString &path) const
+ {
+ path = _pathPrefix;
+ path += us2fs(item.Name);
+ }
+
+ void Clear()
+ {
+ Streams.Clear();
+ }
+};
+
+}
+
+#endif
diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp
index 51c8d2db..b6a66975 100644
--- a/CPP/7zip/UI/FileManager/App.cpp
+++ b/CPP/7zip/UI/FileManager/App.cpp
@@ -140,8 +140,8 @@ HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UStr
}
static void CreateToolbar(HWND parent,
- NWindows::NControl::CImageList &imageList,
- NWindows::NControl::CToolBar &toolBar,
+ NControl::CImageList &imageList,
+ NControl::CToolBar &toolBar,
bool largeButtons)
{
toolBar.Attach(::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, 0
@@ -364,7 +364,8 @@ void CApp::Save()
if (panel._parentFolders.IsEmpty())
path = panel._currentFolderPrefix;
else
- path = GetFolderPath(panel._parentFolders[0].ParentFolder);
+ path = panel._parentFolders[0].ParentFolderPath;
+ // GetFolderPath(panel._parentFolders[0].ParentFolder);
SavePanelPath(i, path);
listMode.Panels[i] = panel.GetListViewMode();
SaveFlatView(i, panel._flatModeForArc);
@@ -380,9 +381,12 @@ void CApp::Release()
Panels[i].Release();
}
-// reduces path to part that exists on disk
+// reduces path to part that exists on disk (or root prefix of path)
+// output path is normalized (with WCHAR_PATH_SEPARATOR)
static void ReducePathToRealFileSystemPath(UString &path)
{
+ unsigned prefixSize = GetRootPrefixSize(path);
+
while (!path.IsEmpty())
{
if (NFind::DoesDirExist(us2fs(path)))
@@ -390,63 +394,59 @@ static void ReducePathToRealFileSystemPath(UString &path)
NName::NormalizeDirPathPrefix(path);
break;
}
- int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
+ int pos = path.ReverseFind_PathSepar();
if (pos < 0)
{
path.Empty();
break;
}
path.DeleteFrom(pos + 1);
- if (path.Len() == 3 && path[1] == L':')
+ if ((unsigned)pos + 1 == prefixSize)
break;
- if (path.Len() > 2 && path[0] == '\\' && path[1] == '\\')
- {
- int nextPos = path.Find(WCHAR_PATH_SEPARATOR, 2); // pos after \\COMPNAME
- if (nextPos > 0 && path.Find(WCHAR_PATH_SEPARATOR, nextPos + 1) == pos)
- break;
- }
path.DeleteFrom(pos);
}
}
-// return true for dir\, if dir exist
+// returns: true, if such dir exists or is root
+/*
static bool CheckFolderPath(const UString &path)
{
UString pathReduced = path;
ReducePathToRealFileSystemPath(pathReduced);
return (pathReduced == path);
}
+*/
extern UString ConvertSizeToString(UInt64 value);
-static UString AddSizeValue(UInt64 size)
+static void AddSizeValue(UString &s, UInt64 size)
{
- return MyFormatNew(IDS_FILE_SIZE, ConvertSizeToString(size));
+ s += MyFormatNew(IDS_FILE_SIZE, ConvertSizeToString(size));
}
static void AddValuePair1(UString &s, UINT resourceID, UInt64 size)
{
- s += LangString(resourceID);
+ AddLangString(s, resourceID);
s += L": ";
- s += AddSizeValue(size);
- s += L'\n';
+ AddSizeValue(s, size);
+ s.Add_LF();
}
void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size)
{
if (num == 0)
return;
- s += LangString(resourceID);
+ AddLangString(s, resourceID);
s += L": ";
s += ConvertSizeToString(num);
if (size != (UInt64)(Int64)-1)
{
s += L" ( ";
- s += AddSizeValue(size);
+ AddSizeValue(s, size);
s += L" )";
}
- s += L'\n';
+ s.Add_LF();
}
static void AddPropValueToSum(IFolderFolder *folder, int index, PROPID propID, UInt64 &sum)
@@ -490,7 +490,7 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
if (numDefined == 2)
AddValuePair1(info, IDS_PROP_SIZE, filesSize + foldersSize);
- info += L"\n";
+ info.Add_LF();
info += _currentFolderPrefix;
for (i = 0; i < indices.Size() && (int)i < (int)kCopyDialog_NumInfoLines - 6; i++)
@@ -499,7 +499,7 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
int index = indices[i];
info += GetItemRelPath(index);
if (IsItem_Folder(index))
- info += WCHAR_PATH_SEPARATOR;
+ info.Add_PathSepar();
}
if (i != indices.Size())
info += L"\n ...";
@@ -508,6 +508,20 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
bool IsCorrectFsName(const UString &name);
+
+
+/* Returns true, if path is path that can be used as path for File System functions
+*/
+
+/*
+static bool IsFsPath(const FString &path)
+{
+ if (!IsAbsolutePath(path))
+ return false;
+ unsigned prefixSize = GetRootPrefixSize(path);
+}
+*/
+
void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
{
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
@@ -517,7 +531,12 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel);
CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel);
- if (!srcPanel.DoesItSupportOperations())
+ if (move)
+ {
+ if (!srcPanel.CheckBeforeUpdate(IDS_MOVE))
+ return;
+ }
+ else if (!srcPanel.DoesItSupportOperations())
{
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
return;
@@ -544,13 +563,15 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
srcPanel.GetOperatedIndicesSmart(indices);
if (indices.Size() == 0)
return;
- destPath = destPanel._currentFolderPrefix;
+ destPath = destPanel.GetFsPath();
if (NumPanels == 1)
ReducePathToRealFileSystemPath(destPath);
}
}
+
UStringVector copyFolders;
ReadCopyHistory(copyFolders);
+
{
CCopyDialog copyDialog;
@@ -583,10 +604,10 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
if (IsAbsolutePath(destPath))
destPath.Empty();
else
- destPath = srcPanel._currentFolderPrefix;
+ destPath = srcPanel.GetFsPath();
destPath += correctName;
- #ifndef UNDER_CE
+ #if defined(_WIN32) && !defined(UNDER_CE)
if (destPath.Len() > 0 && destPath[0] == '\\')
if (destPath.Len() == 1 || destPath[1] != '\\')
{
@@ -595,59 +616,112 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
}
#endif
- if (indices.Size() > 1 ||
- (!destPath.IsEmpty() && destPath.Back() == WCHAR_PATH_SEPARATOR) ||
- NFind::DoesDirExist(us2fs(destPath)) ||
- srcPanel.IsArcFolder())
+ bool possibleToUseDestPanel = false;
+
+ if (CompareFileNames(destPath, destPanel.GetFsPath()) == 0)
{
- CreateComplexDir(us2fs(destPath));
- NName::NormalizeDirPathPrefix(destPath);
- if (!CheckFolderPath(destPath))
+ if (NumPanels == 1 || CompareFileNames(destPath, srcPanel.GetFsPath()) == 0)
{
- if (NumPanels < 2 || destPath != destPanel._currentFolderPrefix || !destPanel.DoesItSupportOperations())
- {
- srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
- return;
- }
- useDestPanel = true;
+ srcPanel.MessageBoxMyError(L"Can not copy files onto itself");
+ return;
}
+
+ if (destPanel.DoesItSupportOperations())
+ possibleToUseDestPanel = true;
}
- else
+
+ bool destIsFsPath = false;
+
+ if (possibleToUseDestPanel)
{
- if (!IsCorrectFsName(destPath))
+ if (destPanel.IsFSFolder() || destPanel.IsAltStreamsFolder())
+ destIsFsPath = true;
+ else if (destPanel.IsFSDrivesFolder() || destPanel.IsRootFolder())
{
- srcPanel.MessageBoxError(E_INVALIDARG);
+ srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
return;
}
- int pos = destPath.ReverseFind(WCHAR_PATH_SEPARATOR);
- if (pos >= 0)
+ }
+ else
+ {
+ if (IsAltPathPrefix(us2fs(destPath)))
{
- UString prefix = destPath.Left(pos + 1);
- CreateComplexDir(us2fs(prefix));
- if (!CheckFolderPath(prefix))
+ // we allow alt streams dest only to alt stream folder in second panel
+ srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
+ return;
+ /*
+ FString basePath = us2fs(destPath);
+ basePath.DeleteBack();
+ if (!DoesFileOrDirExist(basePath))
{
- srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
+ srcPanel.MessageBoxError2Lines(basePath, ERROR_FILE_NOT_FOUND); // GetLastError()
return;
}
+ destIsFsPath = true;
+ */
+ }
+ else
+ {
+ if (indices.Size() == 1 &&
+ !destPath.IsEmpty() && destPath.Back() != WCHAR_PATH_SEPARATOR)
+ {
+ int pos = destPath.ReverseFind_PathSepar();
+ if (pos < 0)
+ {
+ srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
+ return;
+ }
+ {
+ /*
+ #ifdef _WIN32
+ UString name = destPath.Ptr(pos + 1);
+ if (name.Find(L':') >= 0)
+ {
+ srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
+ return;
+ }
+ #endif
+ */
+ UString prefix = destPath.Left(pos + 1);
+ if (!CreateComplexDir(us2fs(prefix)))
+ {
+ srcPanel.MessageBoxError2Lines(prefix, GetLastError());
+ return;
+ }
+ }
+ // bool isFolder = srcPanael.IsItem_Folder(indices[0]);
+ }
+ else
+ {
+ NName::NormalizeDirPathPrefix(destPath);
+ if (!CreateComplexDir(us2fs(destPath)))
+ {
+ srcPanel.MessageBoxError2Lines(destPath, GetLastError());
+ return;
+ }
+ }
+ destIsFsPath = true;
}
}
+ if (!destIsFsPath)
+ useDestPanel = true;
+
AddUniqueStringToHeadOfList(copyFolders, destPath);
while (copyFolders.Size() > 20)
copyFolders.DeleteBack();
SaveCopyHistory(copyFolders);
}
- /*
- if (destPath == destPanel._currentFolderPrefix)
- {
- if (destPanel.GetFolderTypeID() == L"PhysDrive")
- useDestPanel = true;
- }
- */
+ bool useSrcPanel = !useDestPanel || !srcPanel.Is_IO_FS_Folder();
- bool useSrcPanel = (!useDestPanel || !srcPanel.IsFsOrDrivesFolder() || destPanel.IsFSFolder());
bool useTemp = useSrcPanel && useDestPanel;
+ if (useTemp && NumPanels == 1)
+ {
+ srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
+ return;
+ }
+
CTempDir tempDirectory;
FString tempDirPrefix;
if (useTemp)
@@ -666,6 +740,7 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
CPanel::CDisableNotify disableNotify2(srcPanel);
HRESULT result = S_OK;
+
if (useSrcPanel)
{
CCopyToOptions options;
@@ -685,12 +760,13 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
if (useTemp)
folderPrefix = fs2us(tempDirPrefix);
else
- folderPrefix = srcPanel._currentFolderPrefix;
+ folderPrefix = srcPanel.GetFsPath();
filePaths.ClearAndReserve(indices.Size());
FOR_VECTOR (i, indices)
- filePaths.AddInReserved(srcPanel.GetItemRelPath(indices[i]));
+ filePaths.AddInReserved(srcPanel.GetItemRelPath2(indices[i]));
result = destPanel.CopyFrom(move, folderPrefix, filePaths, true, 0);
}
+
if (result != S_OK)
{
// disableNotify1.Restore();
@@ -705,15 +781,18 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
}
RefreshTitleAlways();
+
if (copyToSame || move)
{
srcPanel.RefreshListCtrl(srcSelState);
}
+
if (!copyToSame)
{
destPanel.RefreshListCtrl(destSelState);
srcPanel.KillSelection();
}
+
disableNotify1.Restore();
disableNotify2.Restore();
srcPanel.SetFocusToList();
@@ -831,7 +910,7 @@ void CApp::RefreshTitle(int panelIndex, bool always)
void AddUniqueStringToHead(UStringVector &list, const UString &s)
{
for (unsigned i = 0; i < list.Size();)
- if (s.IsEqualToNoCase(list[i]))
+ if (s.IsEqualTo_NoCase(list[i]))
list.Delete(i);
else
i++;
@@ -848,7 +927,7 @@ void CFolderHistory::Normalize()
void CFolderHistory::AddString(const UString &s)
{
- NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ NSynchronization::CCriticalSectionLock lock(_criticalSection);
AddUniqueStringToHead(Strings, s);
Normalize();
}
diff --git a/CPP/7zip/UI/FileManager/App.h b/CPP/7zip/UI/FileManager/App.h
index c775cc2e..5fe95e0b 100644
--- a/CPP/7zip/UI/FileManager/App.h
+++ b/CPP/7zip/UI/FileManager/App.h
@@ -195,6 +195,7 @@ public:
void CopyTo() { OnCopy(false, false, GetFocusedPanelIndex()); }
void MoveTo() { OnCopy(true, false, GetFocusedPanelIndex()); }
void Delete(bool toRecycleBin) { GetFocusedPanel().DeleteItems(toRecycleBin); }
+ HRESULT CalculateCrc2(const UString &methodName);
void CalculateCrc(const UString &methodName);
void DiffFiles();
void Split();
@@ -204,6 +205,7 @@ public:
#ifndef UNDER_CE
void Link();
+ void OpenAltStreams() { GetFocusedPanel().OpenAltStreams(); }
#endif
void CreateFolder() { GetFocusedPanel().CreateFolder(); }
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
index 32db8f8f..89a6b45a 100644
--- a/CPP/7zip/UI/FileManager/BrowseDialog.cpp
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
@@ -77,7 +77,7 @@ static void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *nam
UString s = HResultToMessage(errorCode);
if (name)
{
- s += L'\n';
+ s.Add_LF();
s += name;
}
MessageBox_Error_Global(wnd, s);
@@ -209,7 +209,7 @@ bool CBrowseDialog::OnInit()
FOR_VECTOR (i, Filters)
{
if (i != 0)
- s += L' ';
+ s.Add_Space();
s += Filters[i];
}
}
@@ -256,14 +256,16 @@ bool CBrowseDialog::OnInit()
_topDirPrefix.Empty();
{
int rootSize = GetRootPrefixSize(FilePath);
+ #if defined(_WIN32) && !defined(UNDER_CE)
// We can go up from root folder to drives list
- if (NName::IsDrivePath(FilePath))
+ if (IsDrivePath(FilePath))
rootSize = 0;
else if (IsSuperPath(FilePath))
{
- if (NName::IsDrivePath(&FilePath[kSuperPathPrefixSize]))
+ if (IsDrivePath(FilePath.Ptr(kSuperPathPrefixSize)))
rootSize = kSuperPathPrefixSize;
}
+ #endif
_topDirPrefix.SetFrom(FilePath, rootSize);
}
@@ -466,7 +468,7 @@ bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, US
return false;
if (s.Back() == WCHAR_PATH_SEPARATOR)
return false;
- int pos = s.ReverseFind(WCHAR_PATH_SEPARATOR);
+ int pos = s.ReverseFind_PathSepar();
parentPrefix.SetFrom(s, pos + 1);
name = s.Ptr(pos + 1);
return true;
@@ -856,7 +858,7 @@ bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path,
return false;
{
UString s = errorMessage;
- s += L"\n";
+ s.Add_LF();
s += path;
MessageBox_Error_Global(owner, s);
}
@@ -904,27 +906,32 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
result.Empty();
UString path = path2;
- path.Replace('/', WCHAR_PATH_SEPARATOR);
+ path.Replace(L'/', WCHAR_PATH_SEPARATOR);
unsigned start = 0;
UString base;
- if (NName::IsAbsolutePath(path))
+
+ if (IsAbsolutePath(path))
{
+ #if defined(_WIN32) && !defined(UNDER_CE)
if (IsSuperOrDevicePath(path))
{
result = path;
return true;
}
+ #endif
int pos = GetRootPrefixSize(path);
if (pos > 0)
start = pos;
}
else
{
+ #if defined(_WIN32) && !defined(UNDER_CE)
if (IsSuperOrDevicePath(relBase))
{
result = path;
return true;
}
+ #endif
base = relBase;
}
@@ -954,6 +961,7 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
result += path.Left(start);
bool checkExist = true;
UString cur;
+
for (;;)
{
if (start == path.Len())
@@ -979,7 +987,7 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
result += cur;
if (slashPos < 0)
break;
- result += WCHAR_PATH_SEPARATOR;
+ result.Add_PathSepar();
start = slashPos + 1;
}
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.h b/CPP/7zip/UI/FileManager/BrowseDialog.h
index 77c749b5..957af2e2 100644
--- a/CPP/7zip/UI/FileManager/BrowseDialog.h
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.h
@@ -9,7 +9,7 @@ bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultP
bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path, LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath);
/* CorrectFsPath removes undesirable characters in names (dots and spaces at the end of file)
- But it doesn't change "bad" name in any of the following caes:
+ But it doesn't change "bad" name in any of the following cases:
- path is Super Path (with \\?\ prefix)
- path is relative and relBase is Super Path
- there is file or dir in filesystem with specified "bad" name */
diff --git a/CPP/7zip/UI/FileManager/EditPage.rc b/CPP/7zip/UI/FileManager/EditPage.rc
index f5618d04..38f74ea1 100644
--- a/CPP/7zip/UI/FileManager/EditPage.rc
+++ b/CPP/7zip/UI/FileManager/EditPage.rc
@@ -1,7 +1,7 @@
#include "EditPageRes.h"
#include "../../GuiCommon.rc"
-#define xc 200
+#define xc 240
#define yc 80
IDD_EDIT MY_PAGE
diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
index ed4bb884..50c43163 100644
--- a/CPP/7zip/UI/FileManager/ExtractCallback.cpp
+++ b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
@@ -22,6 +22,7 @@
#endif
#include "../GUI/ExtractRes.h"
+#include "resourceGui.h"
#include "ExtractCallback.h"
#include "FormatUtils.h"
@@ -30,6 +31,7 @@
#ifndef _NO_CRYPTO
#include "PasswordDialog.h"
#endif
+#include "PropertyName.h"
using namespace NWindows;
using namespace NFile;
@@ -39,6 +41,10 @@ CExtractCallbackImp::~CExtractCallbackImp() {}
void CExtractCallbackImp::Init()
{
+ _lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING);
+ _lang_Testing = LangString(IDS_PROGRESS_TESTING);
+ _lang_Skipping = LangString(IDS_PROGRESS_SKIPPING);
+
NumArchiveErrors = 0;
ThereAreMessageErrors = false;
#ifndef _SFX
@@ -97,6 +103,11 @@ HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, co
return ProgressDialog->Sync.CheckStop();
}
+HRESULT CExtractCallbackImp::Open_Finished()
+{
+ return ProgressDialog->Sync.CheckStop();
+}
+
#ifndef _NO_CRYPTO
HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password)
@@ -104,6 +115,7 @@ HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password)
return CryptoGetTextPassword(password);
}
+/*
HRESULT CExtractCallbackImp::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password)
{
passwordIsDefined = PasswordIsDefined;
@@ -116,10 +128,11 @@ bool CExtractCallbackImp::Open_WasPasswordAsked()
return PasswordWasAsked;
}
-void CExtractCallbackImp::Open_ClearPasswordWasAskedFlag()
+void CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag()
{
PasswordWasAsked = false;
}
+*/
#endif
@@ -179,10 +192,21 @@ STDMETHODIMP CExtractCallbackImp::AskOverwrite(
}
-STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, bool isFolder, Int32 /* askExtractMode */, const UInt64 * /* position */)
+STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */)
{
- _isFolder = isFolder;
- return SetCurrentFilePath2(name);
+ _isFolder = IntToBool(isFolder);
+ _currentFilePath = name;
+
+ const UString *msg = &_lang_Empty;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break;
+ case NArchive::NExtract::NAskMode::kTest: msg = &_lang_Testing; break;
+ case NArchive::NExtract::NAskMode::kSkip: msg = &_lang_Skipping; break;
+ // default: s = "Unknown operation";
+ }
+
+ return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder));
}
STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *s)
@@ -208,101 +232,108 @@ STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *s)
#endif
-STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, bool encrypted)
+void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s)
{
+ s.Empty();
+
+ if (opRes == NArchive::NExtract::NOperationResult::kOK)
+ return;
+
+ UINT messageID = 0;
+ UINT id = 0;
+
switch (opRes)
{
- case NArchive::NExtract::NOperationResult::kOK:
+ case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
+ messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD;
+ id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ messageID = encrypted ?
+ IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED:
+ IDS_EXTRACT_MESSAGE_DATA_ERROR;
+ id = IDS_EXTRACT_MSG_DATA_ERROR;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ messageID = encrypted ?
+ IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED:
+ IDS_EXTRACT_MESSAGE_CRC_ERROR;
+ id = IDS_EXTRACT_MSG_CRC_ERROR;
+ break;
+ case NArchive::NExtract::NOperationResult::kUnavailable:
+ id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA;
+ break;
+ case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
+ id = IDS_EXTRACT_MSG_UEXPECTED_END;
break;
+ case NArchive::NExtract::NOperationResult::kDataAfterEnd:
+ id = IDS_EXTRACT_MSG_DATA_AFTER_END;
+ break;
+ case NArchive::NExtract::NOperationResult::kIsNotArc:
+ id = IDS_EXTRACT_MSG_IS_NOT_ARC;
+ break;
+ case NArchive::NExtract::NOperationResult::kHeadersError:
+ id = IDS_EXTRACT_MSG_HEADERS_ERROR;
+ break;
+ case NArchive::NExtract::NOperationResult::kWrongPassword:
+ id = IDS_EXTRACT_MSG_WRONG_PSW_CLAIM;
+ break;
+ /*
default:
- {
- UINT messageID = 0;
- UINT id = 0;
-
- switch (opRes)
- {
- case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
- messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD;
- id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD;
- break;
- case NArchive::NExtract::NOperationResult::kDataError:
- messageID = encrypted ?
- IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED:
- IDS_EXTRACT_MESSAGE_DATA_ERROR;
- id = IDS_EXTRACT_MSG_DATA_ERROR;
- break;
- case NArchive::NExtract::NOperationResult::kCRCError:
- messageID = encrypted ?
- IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED:
- IDS_EXTRACT_MESSAGE_CRC_ERROR;
- id = IDS_EXTRACT_MSG_CRC_ERROR;
- break;
- case NArchive::NExtract::NOperationResult::kUnavailable:
- id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA;
- break;
- case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
- id = IDS_EXTRACT_MSG_UEXPECTED_END;
- break;
- case NArchive::NExtract::NOperationResult::kDataAfterEnd:
- id = IDS_EXTRACT_MSG_DATA_AFTER_END;
- break;
- case NArchive::NExtract::NOperationResult::kIsNotArc:
- id = IDS_EXTRACT_MSG_IS_NOT_ARC;
- break;
- case NArchive::NExtract::NOperationResult::kHeadersError:
- id = IDS_EXTRACT_MSG_HEADERS_ERROR;
- break;
- /*
- default:
- messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR;
- break;
- */
- }
- if (_needWriteArchivePath)
- {
- if (!_currentArchivePath.IsEmpty())
- AddError_Message(_currentArchivePath);
- _needWriteArchivePath = false;
- }
+ messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR;
+ break;
+ */
+ }
- UString msg;
- UString msgOld;
+ UString msg;
+ UString msgOld;
- #ifndef _SFX
- if (id != 0)
- LangString_OnlyFromLangFile(id, msg);
- if (messageID != 0 && msg.IsEmpty())
- LangString_OnlyFromLangFile(messageID, msgOld);
- #endif
+ #ifndef _SFX
+ if (id != 0)
+ LangString_OnlyFromLangFile(id, msg);
+ if (messageID != 0 && msg.IsEmpty())
+ LangString_OnlyFromLangFile(messageID, msgOld);
+ #endif
- UString s;
- if (msg.IsEmpty() && !msgOld.IsEmpty())
- s = MyFormatNew(msgOld, _currentFilePath);
- else
- {
- if (msg.IsEmpty())
- LangString(id, msg);
- if (!msg.IsEmpty())
- s += msg;
- else
- {
- wchar_t temp[16];
- ConvertUInt32ToString(opRes, temp);
- s += L"Error #";
- s += temp;
- }
+ if (msg.IsEmpty() && !msgOld.IsEmpty())
+ s = MyFormatNew(msgOld, fileName);
+ else
+ {
+ if (msg.IsEmpty() && id != 0)
+ LangString(id, msg);
+ if (!msg.IsEmpty())
+ s += msg;
+ else
+ {
+ char temp[16];
+ ConvertUInt32ToString(opRes, temp);
+ s.AddAscii("Error #");
+ s.AddAscii(temp);
+ }
- if (encrypted)
- {
- // s += L" : ";
- // s += LangString(IDS_EXTRACT_MSG_ENCRYPTED);
- s += L" : ";
- s += LangString(IDS_EXTRACT_MSG_WRONG_PSW);
- }
- s += L" : ";
- s += _currentFilePath;
- }
+ if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword)
+ {
+ // s.AddAscii(" : ");
+ // AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED);
+ s.AddAscii(" : ");
+ AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
+ }
+ s.AddAscii(" : ");
+ s += fileName;
+ }
+}
+STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted)
+{
+ switch (opRes)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ break;
+ default:
+ {
+ UString s;
+ SetExtractErrorMessage(opRes, encrypted, _currentFilePath, s);
+ Add_ArchiveName_Error();
AddError_Message(s);
}
}
@@ -318,10 +349,22 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, bool encrypted
return S_OK;
}
+STDMETHODIMP CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)
+{
+ if (opRes != NArchive::NExtract::NOperationResult::kOK)
+ {
+ UString s;
+ SetExtractErrorMessage(opRes, encrypted, name, s);
+ Add_ArchiveName_Error();
+ AddError_Message(s);
+ }
+ return S_OK;
+}
+
////////////////////////////////////////
// IExtractCallbackUI
-HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name)
+HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */)
{
#ifndef _SFX
RINOK(ProgressDialog->Sync.CheckStop());
@@ -357,27 +400,6 @@ HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path)
UString HResultToMessage(HRESULT errorCode);
-HRESULT CExtractCallbackImp::OpenResult(const wchar_t *name, HRESULT result, bool encrypted)
-{
- if (result != S_OK)
- {
- UString s;
- if (result == S_FALSE)
- s = MyFormatNew(encrypted ? IDS_CANT_OPEN_ENCRYPTED_ARCHIVE : IDS_CANT_OPEN_ARCHIVE, name);
- else
- {
- s = name;
- s += L": ";
- s += HResultToMessage(result);
- }
- MessageError(s);
- NumArchiveErrors++;
- }
- _currentArchivePath = name;
- _needWriteArchivePath = true;
- return S_OK;
-}
-
static const UInt32 k_ErrorFlagsIds[] =
{
IDS_EXTRACT_MSG_IS_NOT_ARC,
@@ -393,9 +415,16 @@ static const UInt32 k_ErrorFlagsIds[] =
IDS_EXTRACT_MSG_CRC_ERROR
};
+static void AddNewLineString(UString &s, const UString &m)
+{
+ s += m;
+ s.Add_LF();
+}
+
UString GetOpenArcErrorMessage(UInt32 errorFlags)
{
UString s;
+
for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsIds); i++)
{
UInt32 f = ((UInt32)1 << i);
@@ -407,14 +436,15 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
continue;
if (f == kpv_ErrorFlags_EncryptedHeadersError)
{
- m += L" : ";
- m += LangString(IDS_EXTRACT_MSG_WRONG_PSW);
+ m.AddAscii(" : ");
+ AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
}
if (!s.IsEmpty())
- s += L'\n';
+ s.Add_LF();
s += m;
errorFlags &= ~f;
}
+
if (errorFlags != 0)
{
char sz[16];
@@ -422,76 +452,153 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
sz[1] = 'x';
ConvertUInt32ToHex(errorFlags, sz + 2);
if (!s.IsEmpty())
- s += L'\n';
- s += GetUnicodeString(AString(sz));
+ s.Add_LF();
+ s.AddAscii(sz);
}
+
return s;
}
-HRESULT CExtractCallbackImp::SetError(int level, const wchar_t *name,
- UInt32 errorFlags, const wchar_t *errors,
- UInt32 warningFlags, const wchar_t *warnings)
+static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
{
- NumArchiveErrors++;
+ UInt32 errorFlags = er.GetErrorFlags();
+ UInt32 warningFlags = er.GetWarningFlags();
- if (_needWriteArchivePath)
+ if (errorFlags != 0)
+ AddNewLineString(s, GetOpenArcErrorMessage(errorFlags));
+
+ if (!er.ErrorMessage.IsEmpty())
+ AddNewLineString(s, er.ErrorMessage);
+
+ if (warningFlags != 0)
{
- if (!_currentArchivePath.IsEmpty())
- AddError_Message(_currentArchivePath);
- _needWriteArchivePath = false;
+ s += GetNameOfProperty(kpidWarningFlags, L"Warnings");
+ s.AddAscii(":");
+ s.Add_LF();
+ AddNewLineString(s, GetOpenArcErrorMessage(warningFlags));
}
-
- if (level != 0)
+
+ if (!er.WarningMessage.IsEmpty())
{
- UString s;
- s += name;
- s += L": ";
- MessageError(s);
+ s += GetNameOfProperty(kpidWarning, L"Warning");
+ s.AddAscii(": ");
+ s += er.WarningMessage;
+ s.Add_LF();
}
+}
- if (errorFlags != 0)
- MessageError(GetOpenArcErrorMessage(errorFlags));
+static UString GetBracedType(const wchar_t *type)
+{
+ UString s = L'[';
+ s += type;
+ s += L']';
+ return s;
+}
- if (errors && wcslen(errors) != 0)
- MessageError(errors);
+void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
+{
+ FOR_VECTOR (level, arcLink.Arcs)
+ {
+ const CArc &arc = arcLink.Arcs[level];
+ const CArcErrorInfo &er = arc.ErrorInfo;
- if (warningFlags != 0)
- MessageError((UString)L"Warnings: " + GetOpenArcErrorMessage(warningFlags));
+ if (!er.IsThereErrorOrWarning() && er.ErrorFormatIndex < 0)
+ continue;
- if (warnings && wcslen(warnings) != 0)
- MessageError((UString)L"Warnings: " + warnings);
+ if (s.IsEmpty())
+ {
+ s += name;
+ s.Add_LF();
+ }
+
+ if (level != 0)
+ {
+ AddNewLineString(s, arc.Path);
+ }
+
+ ErrorInfo_Print(s, er);
- return S_OK;
-}
+ if (er.ErrorFormatIndex >= 0)
+ {
+ AddNewLineString(s, GetNameOfProperty(kpidWarning, L"Warning"));
+ if (arc.FormatIndex == er.ErrorFormatIndex)
+ {
+ AddNewLineString(s, LangString(IDS_IS_OPEN_WITH_OFFSET));
+ }
+ else
+ {
+ AddNewLineString(s, MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(er.ErrorFormatIndex))));
+ AddNewLineString(s, MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(arc.FormatIndex))));
+ }
+ }
+ }
-HRESULT CExtractCallbackImp::OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType)
-{
- UString s = L"Warning:\n";
- s += name;
- s += L"\n";
- if (wcscmp(okType, errorType) == 0)
+ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result != S_OK)
{
- s += L"The archive is open with offset";
+ s += name;
+ s.Add_LF();
+ if (!arcLink.Arcs.IsEmpty())
+ AddNewLineString(s, arcLink.NonOpen_ArcPath);
+
+ if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result == S_FALSE)
+ {
+ UINT id = IDS_CANT_OPEN_ARCHIVE;
+ UString param;
+ if (arcLink.PasswordWasAsked)
+ id = IDS_CANT_OPEN_ENCRYPTED_ARCHIVE;
+ else if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
+ {
+ id = IDS_CANT_OPEN_AS_TYPE;
+ param = GetBracedType(codecs->GetFormatNamePtr(arcLink.NonOpen_ErrorInfo.ErrorFormatIndex));
+ }
+ UString s2 = MyFormatNew(id, param);
+ s2.Replace(L" ''", L"");
+ s2.Replace(L"''", L"");
+ s += s2;
+ }
+ else
+ s += HResultToMessage(result);
+
+ s.Add_LF();
+ ErrorInfo_Print(s, arcLink.NonOpen_ErrorInfo);
}
- else
+
+ if (!s.IsEmpty() && s.Back() == '\n')
+ s.DeleteBack();
+}
+
+HRESULT CExtractCallbackImp::OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
+{
+ _currentArchivePath = name;
+ _needWriteArchivePath = true;
+
+ UString s;
+ OpenResult_GUI(s, codecs, arcLink, name, result);
+ if (!s.IsEmpty())
{
- s += L"Can not open the file as [";
- s += errorType;
- s += L"] archive\n";
- s += L"The file is open as [";
- s += okType;
- s += L"] archive";
+ NumArchiveErrors++;
+ AddError_Message(s);
+ _needWriteArchivePath = false;
}
- MessageError(s);
- NumArchiveErrors++;
+
return S_OK;
}
-
+
HRESULT CExtractCallbackImp::ThereAreNoFiles()
{
return S_OK;
}
+void CExtractCallbackImp::Add_ArchiveName_Error()
+{
+ if (_needWriteArchivePath)
+ {
+ if (!_currentArchivePath.IsEmpty())
+ AddError_Message(_currentArchivePath);
+ _needWriteArchivePath = false;
+ }
+}
+
HRESULT CExtractCallbackImp::ExtractResult(HRESULT result)
{
if (result == S_OK)
@@ -499,7 +606,10 @@ HRESULT CExtractCallbackImp::ExtractResult(HRESULT result)
NumArchiveErrors++;
if (result == E_ABORT || result == ERROR_DISK_FULL)
return result;
- MessageError(_currentFilePath);
+
+ Add_ArchiveName_Error();
+ if (!_currentFilePath.IsEmpty())
+ MessageError(_currentFilePath);
MessageError(NError::MyFormatMessage(result));
return S_OK;
}
@@ -564,7 +674,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
{
if (!destFileInfo.IsDir())
{
- RINOK(MessageError("can not replace file with folder with same name: ", destPathSys));
+ RINOK(MessageError("can not replace file with folder with same name", destPathSys));
return E_ABORT;
}
*writeAnswer = BoolToInt(false);
@@ -573,8 +683,9 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
if (destFileInfo.IsDir())
{
- RINOK(MessageError("can not replace folder with file with same name: ", destPathSys));
- return E_FAIL;
+ RINOK(MessageError("can not replace folder with file with same name", destPathSys));
+ *writeAnswer = BoolToInt(false);
+ return S_OK;
}
switch (OverwriteMode)
@@ -583,13 +694,9 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
return S_OK;
case NExtract::NOverwriteMode::kAsk:
{
- Int32 overwiteResult;
+ Int32 overwriteResult;
UString destPathSpec = destPath;
- int slashPos = destPathSpec.ReverseFind(L'/');
- #ifdef _WIN32
- int slash1Pos = destPathSpec.ReverseFind(L'\\');
- slashPos = MyMax(slashPos, slash1Pos);
- #endif
+ int slashPos = destPathSpec.ReverseFind_PathSepar();
destPathSpec.DeleteFrom(slashPos + 1);
destPathSpec += fs2us(destFileInfo.Name);
@@ -598,9 +705,9 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
&destFileInfo.MTime, &destFileInfo.Size,
srcPath,
srcTime, srcSize,
- &overwiteResult));
+ &overwriteResult));
- switch (overwiteResult)
+ switch (overwriteResult)
{
case NOverwriteAnswer::kCancel: return E_ABORT;
case NOverwriteAnswer::kNo: return S_OK;
@@ -618,7 +725,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
{
if (!AutoRenamePath(destPathSys))
{
- RINOK(MessageError("can not create name for file: ", destPathSys));
+ RINOK(MessageError("can not create name for file", destPathSys));
return E_ABORT;
}
destPathResultTemp = fs2us(destPathSys);
@@ -626,7 +733,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
else
if (!NDir::DeleteFileAlways(destPathSys))
{
- RINOK(MessageError("can not delete output file: ", destPathSys));
+ RINOK(MessageError("can not delete output file", destPathSys));
return E_ABORT;
}
}
@@ -783,7 +890,7 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode)
COM_TRY_END
}
-STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, bool encrypted)
+STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypted)
{
COM_TRY_BEGIN
if (VirtFileSystem && _newVirtFileWasAdded)
@@ -865,7 +972,7 @@ HRESULT CVirtFileSystem::FlushToDisk(bool closeLast)
while (_numFlushed < Files.Size())
{
const CVirtFile &file = Files[_numFlushed];
- const FString path = DirPrefix + us2fs(GetCorrectFsPath(file.Name));
+ const FString path = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.Name));
if (!_fileIsOpen)
{
if (!_outFileStreamSpec->Create(path, false))
diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.h b/CPP/7zip/UI/FileManager/ExtractCallback.h
index 71e48e5e..1654bcd6 100644
--- a/CPP/7zip/UI/FileManager/ExtractCallback.h
+++ b/CPP/7zip/UI/FileManager/ExtractCallback.h
@@ -36,8 +36,7 @@ class CGrowBuf
Byte *_items;
size_t _size;
- CGrowBuf(const CGrowBuf &buffer);
- void operator=(const CGrowBuf &buffer);
+ CLASS_NO_COPY(CGrowBuf);
public:
bool ReAlloc_KeepData(size_t newSize, size_t keepSize)
@@ -45,7 +44,8 @@ public:
void *buf = MyAlloc(newSize);
if (!buf)
return false;
- memcpy(buf, _items, keepSize);
+ if (keepSize != 0)
+ memcpy(buf, _items, keepSize);
MyFree(_items);
_items = (Byte *)buf;
_size = newSize;
@@ -55,8 +55,8 @@ public:
CGrowBuf(): _items(0), _size(0) {}
~CGrowBuf() { MyFree(_items); }
- operator Byte *() { return _items; };
- operator const Byte *() const { return _items; };
+ operator Byte *() { return _items; }
+ operator const Byte *() const { return _items; }
size_t Size() const { return _size; }
};
@@ -135,10 +135,11 @@ public:
{
if (_fileMode)
return false;
- if (Files.Size() < 1 || Files[0].IsAltStream || Files[0].IsDir)
+ if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir)
return false;
return true;
}
+
size_t GetMemStreamWrittenSize() const { return _pos; }
CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {}
@@ -165,6 +166,7 @@ public:
class CExtractCallbackImp:
public IExtractCallbackUI, // it includes IFolderArchiveExtractCallback
public IOpenCallbackUI,
+ public IFolderArchiveExtractCallback2,
#ifndef _SFX
public IFolderOperationsExtractCallback,
public IFolderExtractToStreamCallback,
@@ -176,8 +178,10 @@ class CExtractCallbackImp:
public CMyUnknownImp
{
HRESULT MessageError(const char *message, const FString &path);
+ void Add_ArchiveName_Error();
public:
MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback)
+ MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2)
#ifndef _SFX
MY_QUERYINTERFACE_ENTRY(IFolderOperationsExtractCallback)
MY_QUERYINTERFACE_ENTRY(IFolderExtractToStreamCallback)
@@ -191,33 +195,12 @@ public:
INTERFACE_IProgress(;)
INTERFACE_IOpenCallbackUI(;)
-
- // IFolderArchiveExtractCallback
+ INTERFACE_IFolderArchiveExtractCallback(;)
+ INTERFACE_IFolderArchiveExtractCallback2(;)
// STDMETHOD(SetTotalFiles)(UInt64 total);
// STDMETHOD(SetCompletedFiles)(const UInt64 *value);
- STDMETHOD(AskOverwrite)(
- const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
- const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
- Int32 *answer);
- STDMETHOD (PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position);
- STDMETHOD(MessageError)(const wchar_t *message);
- STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);
-
- // IExtractCallbackUI
-
- HRESULT BeforeOpen(const wchar_t *name);
- HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
- HRESULT SetError(int level, const wchar_t *name,
- UInt32 errorFlags, const wchar_t *errors,
- UInt32 warningFlags, const wchar_t *warnings);
- HRESULT ThereAreNoFiles();
- HRESULT ExtractResult(HRESULT result);
- HRESULT OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType);
-
- #ifndef _NO_CRYPTO
- HRESULT SetPassword(const UString &password);
- #endif
+ INTERFACE_IExtractCallbackUI(;)
#ifndef _SFX
// IFolderOperationsExtractCallback
@@ -295,6 +278,12 @@ public:
UString Password;
#endif
+
+ UString _lang_Extracting;
+ UString _lang_Testing;
+ UString _lang_Skipping;
+ UString _lang_Empty;
+
CExtractCallbackImp():
#ifndef _NO_CRYPTO
PasswordIsDefined(false),
diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp
index 537103ae..00b152c8 100644
--- a/CPP/7zip/UI/FileManager/FM.cpp
+++ b/CPP/7zip/UI/FileManager/FM.cpp
@@ -49,6 +49,9 @@ static UString g_MainPath;
static UString g_ArcFormat;
static bool g_Maximized = false;
+// HRESULT LoadGlobalCodecs();
+void FreeGlobalCodecs();
+
#ifndef UNDER_CE
DWORD g_ComCtl32Version;
@@ -568,6 +571,13 @@ static int WINAPI WinMain2(int nCmdShow)
if (!InitInstance (nCmdShow))
return FALSE;
+ // we will load Global_Codecs at first use instead.
+ /*
+ OutputDebugStringW(L"Before LoadGlobalCodecs");
+ LoadGlobalCodecs();
+ OutputDebugStringW(L"After LoadGlobalCodecs");
+ */
+
#ifndef _UNICODE
if (g_IsNT)
{
@@ -597,6 +607,10 @@ static int WINAPI WinMain2(int nCmdShow)
}
}
+ // Destructor of g_CodecsReleaser can release DLLs.
+ // But we suppose that it's better to release DLLs here (before destructor).
+ FreeGlobalCodecs();
+
g_HWND = 0;
#ifndef UNDER_CE
OleUninitialize();
@@ -780,35 +794,45 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
xSizes[1] = 0;
g_App.CreateDragTarget();
+
bool archiveIsOpened;
bool encrypted;
bool needOpenFile = false;
- if (!g_MainPath.IsEmpty() /* && g_OpenArchive */)
+
+ UString fullPath = g_MainPath;
+ if (!fullPath.IsEmpty() /* && g_OpenArchive */)
{
- if (NFile::NFind::DoesFileExist(us2fs(g_MainPath)))
+ if (!NFile::NName::IsAbsolutePath(fullPath))
+ {
+ FString fullPathF;
+ if (NFile::NName::GetFullPath(us2fs(fullPath), fullPathF))
+ fullPath = fs2us(fullPathF);
+ }
+ if (NFile::NFind::DoesFileExist(us2fs(fullPath)))
needOpenFile = true;
}
- HRESULT res = g_App.Create(hWnd, g_MainPath, g_ArcFormat, xSizes, archiveIsOpened, encrypted);
+
+ HRESULT res = g_App.Create(hWnd, fullPath, g_ArcFormat, xSizes, archiveIsOpened, encrypted);
if (res == E_ABORT)
- {
return -1;
- }
+
if (needOpenFile && !archiveIsOpened || res != S_OK)
{
UString message = L"Error";
if (res == S_FALSE || res == S_OK)
{
message = MyFormatNew(encrypted ?
- IDS_CANT_OPEN_ENCRYPTED_ARCHIVE :
- IDS_CANT_OPEN_ARCHIVE,
- g_MainPath);
+ IDS_CANT_OPEN_ENCRYPTED_ARCHIVE :
+ IDS_CANT_OPEN_ARCHIVE,
+ fullPath);
}
else if (res != S_OK)
message = HResultToMessage(res);
ErrorMessage(message);
return -1;
}
+
// g_SplitterPos = 0;
// ::DragAcceptFiles(hWnd, TRUE);
@@ -816,6 +840,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
}
+
case WM_DESTROY:
{
// ::DragAcceptFiles(hWnd, FALSE);
@@ -839,11 +864,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
g_StartCaptureSplitterPos = g_Splitter.GetPos();
::SetCapture(hWnd);
break;
+
case WM_LBUTTONUP:
{
::ReleaseCapture();
break;
}
+
case WM_MOUSEMOVE:
{
if ((wParam & MK_LBUTTON) != 0 && ::GetCapture() == hWnd)
@@ -880,10 +907,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
break;
}
+
case WM_SETFOCUS:
// g_App.SetFocus(g_App.LastFocusedPanel);
g_App.SetFocusToLastItem();
break;
+
/*
case WM_ACTIVATE:
{
@@ -900,6 +929,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
}
*/
+
/*
case kLangWasChangedMessage:
MyLoadMenu();
@@ -910,11 +940,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_SETTINGCHANGE:
break;
*/
+
case WM_NOTIFY:
{
g_App.OnNotify((int)wParam, (LPNMHDR)lParam);
break;
}
+
/*
case WM_DROPFILES:
{
diff --git a/CPP/7zip/UI/FileManager/FM.dsp b/CPP/7zip/UI/FileManager/FM.dsp
index 4a7f16a6..f18e5441 100644
--- a/CPP/7zip/UI/FileManager/FM.dsp
+++ b/CPP/7zip/UI/FileManager/FM.dsp
@@ -219,6 +219,14 @@ SOURCE=.\Test.bmp
# PROP Default_Filter ""
# Begin Source File
+SOURCE=.\AltStreamsFolder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AltStreamsFolder.h
+# End Source File
+# Begin Source File
+
SOURCE=.\FSDrives.cpp
# End Source File
# Begin Source File
@@ -1026,6 +1034,10 @@ SOURCE=..\..\..\Windows\Window.h
# PROP Default_Filter ""
# Begin Source File
+SOURCE=..\..\..\Common\Common.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\ComTry.h
# End Source File
# Begin Source File
@@ -1399,6 +1411,14 @@ SOURCE=..\GUI\HashGUI.cpp
SOURCE=..\GUI\HashGUI.h
# End Source File
+# Begin Source File
+
+SOURCE=..\GUI\UpdateCallbackGUI2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\GUI\UpdateCallbackGUI2.h
+# End Source File
# End Group
# End Group
# Begin Group "Compress"
diff --git a/CPP/7zip/UI/FileManager/FM.mak b/CPP/7zip/UI/FileManager/FM.mak
index 234a5920..6a85ea2f 100644
--- a/CPP/7zip/UI/FileManager/FM.mak
+++ b/CPP/7zip/UI/FileManager/FM.mak
@@ -60,6 +60,7 @@ FM_OBJS = \
!IFNDEF UNDER_CE
FM_OBJS = $(FM_OBJS) \
+ $O\AltStreamsFolder.obj \
$O\FSDrives.obj \
$O\LinkDialog.obj \
$O\NetFolder.obj \
diff --git a/CPP/7zip/UI/FileManager/FSDrives.cpp b/CPP/7zip/UI/FileManager/FSDrives.cpp
index 84639de7..69f89325 100644
--- a/CPP/7zip/UI/FileManager/FSDrives.cpp
+++ b/CPP/7zip/UI/FileManager/FSDrives.cpp
@@ -11,6 +11,7 @@
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileIO.h"
+#include "../../../Windows/FileName.h"
#include "../../../Windows/FileSystem.h"
#include "../../../Windows/PropVariant.h"
@@ -27,8 +28,8 @@ using namespace NWindows;
using namespace NFile;
using namespace NFind;
-static CFSTR kVolPrefix = FTEXT("\\\\.\\");
-static CFSTR kLongPrefix = FTEXT("\\\\?\\");
+static const CFSTR kVolPrefix = FTEXT("\\\\.\\");
+static const CFSTR kSuperPrefix = FTEXT("\\\\?\\");
FString CDriveInfo::GetDeviceFileIoName() const
{
@@ -53,6 +54,7 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt
if (!inFile.GetLength(fileSize))
::GetLastError();
}
+
NIO::COutFile outFile;
if (writeToDisk)
{
@@ -62,6 +64,7 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt
else
if (!outFile.Create(toPath, true))
return GetLastError();
+
CPhysTempBuffer tempBuffer;
tempBuffer.buffer = MidAlloc(bufferSize);
if (!tempBuffer.buffer)
@@ -93,12 +96,14 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt
return E_FAIL;
pos += curSize;
}
+
return S_OK;
}
static const PROPID kProps[] =
{
kpidName,
+ // kpidOutName,
kpidTotalSize,
kpidFreeSpace,
kpidType,
@@ -107,7 +112,7 @@ static const PROPID kProps[] =
kpidClusterSize
};
-static const char *kDriveTypes[] =
+static const char * const kDriveTypes[] =
{
"Unknown"
, "No Root Dir"
@@ -219,6 +224,16 @@ STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT
{
case kpidIsDir: prop = !_volumeMode; break;
case kpidName: prop = di.Name; break;
+ case kpidOutName:
+ if (!di.Name.IsEmpty() && di.Name.Back() == ':')
+ {
+ FString s = di.Name;
+ s.DeleteBack();
+ AddExt(s, itemIndex);
+ prop = s;
+ }
+ break;
+
case kpidTotalSize: if (di.KnownSize) prop = di.DriveSize; break;
case kpidFreeSpace: if (di.KnownSizes) prop = di.FreeSpace; break;
case kpidClusterSize: if (di.KnownSizes) prop = di.ClusterSize; break;
@@ -240,14 +255,11 @@ HRESULT CFSDrives::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder)
return S_OK;
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
- if (_longMode)
- {
- RINOK(fsFolderSpec->Init((FString)kLongPrefix + name, 0));
- }
- else
- {
- RINOK(fsFolderSpec->Init(name, 0));
- }
+ FString path;
+ if (_superMode)
+ path = kSuperPrefix;
+ path += name;
+ RINOK(fsFolderSpec->Init(path));
*resultFolder = subFolder.Detach();
return S_OK;
}
@@ -295,8 +307,8 @@ STDMETHODIMP CFSDrives::GetFolderProperty(PROPID propID, PROPVARIANT *value)
case kpidPath:
if (_volumeMode)
prop = kVolPrefix;
- else if (_longMode)
- prop = kLongPrefix;
+ else if (_superMode)
+ prop = kSuperPrefix;
else
prop = (UString)LangString(IDS_COMPUTER) + WCHAR_PATH_SEPARATOR;
break;
@@ -322,19 +334,20 @@ STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)
return GetLastError();
}
-const wchar_t *CFSDrives::GetExt(unsigned index) const
+void CFSDrives::AddExt(FString &s, unsigned index) const
{
+ s += FTEXT('.');
const CDriveInfo &di = _drives[index];
- const wchar_t *ext;
+ const char *ext;
if (di.DriveType == DRIVE_CDROM)
- ext = L"iso";
- else if (di.FileSystemName.Find(L"NTFS") >= 0)
- ext = L"ntfs";
- else if (di.FileSystemName.Find(L"FAT") >= 0)
- ext = L"fat";
+ ext = "iso";
+ else if (di.FileSystemName.IsPrefixedBy_Ascii_NoCase("NTFS"))
+ ext = "ntfs";
+ else if (di.FileSystemName.IsPrefixedBy_Ascii_NoCase("FAT"))
+ ext = "fat";
else
- ext = L"img";
- return ext;
+ ext = "img";
+ s.AddAscii(ext);
}
HRESULT CFSDrives::GetFileSize(unsigned index, UInt64 &fileSize) const
@@ -352,12 +365,12 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */,
const wchar_t *path, IFolderOperationsExtractCallback *callback)
{
- if (moveMode)
- return E_NOTIMPL;
-
if (numItems == 0)
return S_OK;
+ if (moveMode)
+ return E_NOTIMPL;
+
if (!_volumeMode)
return E_NOTIMPL;
@@ -372,11 +385,14 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
RINOK(callback->SetTotal(totalSize));
RINOK(callback->SetNumFiles(numItems));
- UString destPath = path;
+ FString destPath = us2fs(path);
if (destPath.IsEmpty())
return E_INVALIDARG;
- bool directName = (destPath.Back() != WCHAR_PATH_SEPARATOR);
- if (directName)
+
+ bool isAltDest = NName::IsAltPathPrefix(destPath);
+ bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
+
+ if (isDirectPath)
{
if (numItems > 1)
return E_INVALIDARG;
@@ -389,19 +405,19 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
{
unsigned index = indices[i];
const CDriveInfo &di = _drives[index];
- UString destPath2 = destPath;
- UString name = fs2us(di.Name);
- if (!directName)
+ FString destPath2 = destPath;
+
+ if (!isDirectPath)
{
- UString destName = name;
- if (!destName.IsEmpty() && destName.Back() == L':')
+ FString destName = di.Name;
+ if (!destName.IsEmpty() && destName.Back() == ':')
{
destName.DeleteBack();
- destName += L'.';
- destName += GetExt(index);
+ AddExt(destName, index);
}
destPath2 += destName;
}
+
FString srcPath = di.GetDeviceFileIoName();
UInt64 fileSize = 0;
@@ -410,15 +426,23 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
return E_FAIL;
}
if (!di.KnownSize)
+ {
totalSize += fileSize;
- RINOK(callback->SetTotal(totalSize));
+ RINOK(callback->SetTotal(totalSize));
+ }
Int32 writeAskResult;
CMyComBSTR destPathResult;
RINOK(callback->AskWrite(fs2us(srcPath), BoolToInt(false), NULL, &fileSize,
- destPath2, &destPathResult, &writeAskResult));
+ fs2us(destPath2), &destPathResult, &writeAskResult));
+
if (!IntToBool(writeAskResult))
+ {
+ if (totalSize >= fileSize)
+ totalSize -= fileSize;
+ RINOK(callback->SetTotal(totalSize));
continue;
+ }
RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
@@ -427,11 +451,12 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
RINOK(CopyFileSpec(srcPath, us2fs(destPathResult), false, fileSize, bufferSize, completedSize, callback));
completedSize += fileSize;
}
+
return S_OK;
}
STDMETHODIMP CFSDrives::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
- const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
+ const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
{
return E_NOTIMPL;
}
diff --git a/CPP/7zip/UI/FileManager/FSDrives.h b/CPP/7zip/UI/FileManager/FSDrives.h
index a8e25d7d..f12e4da8 100644
--- a/CPP/7zip/UI/FileManager/FSDrives.h
+++ b/CPP/7zip/UI/FileManager/FSDrives.h
@@ -36,10 +36,10 @@ class CFSDrives:
{
CObjectVector<CDriveInfo> _drives;
bool _volumeMode;
- bool _longMode;
+ bool _superMode;
HRESULT BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder);
- const wchar_t *GetExt(unsigned index) const;
+ void AddExt(FString &s, unsigned index) const;
HRESULT GetFileSize(unsigned index, UInt64 &fileSize) const;
public:
MY_UNKNOWN_IMP2(IFolderGetSystemIconIndex, IFolderOperations)
@@ -49,10 +49,10 @@ public:
STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex);
- void Init(bool volMode = false, bool longMode = false)
+ void Init(bool volMode = false, bool superMode = false)
{
_volumeMode = volMode;
- _longMode = longMode;
+ _superMode = superMode;
}
};
diff --git a/CPP/7zip/UI/FileManager/FSFolder.cpp b/CPP/7zip/UI/FileManager/FSFolder.cpp
index a27066c3..e46afb9e 100644
--- a/CPP/7zip/UI/FileManager/FSFolder.cpp
+++ b/CPP/7zip/UI/FileManager/FSFolder.cpp
@@ -29,7 +29,7 @@
// But real support version for that function is NT 3.1 (probably)
// So we must define GetCompressedFileSizeW
EXTERN_C_BEGIN
-WINBASEAPI DWORD WINAPI GetCompressedFileSizeW(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh );
+WINBASEAPI DWORD WINAPI GetCompressedFileSizeW(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh);
EXTERN_C_END
#endif
#endif
@@ -68,20 +68,23 @@ static const Byte kProps[] =
kpidPrefix
};
-HRESULT CFSFolder::Init(const FString &path, IFolderFolder *parentFolder)
+HRESULT CFSFolder::Init(const FString &path /* , IFolderFolder *parentFolder */)
{
- _parentFolder = parentFolder;
+ // _parentFolder = parentFolder;
_path = path;
_findChangeNotification.FindFirst(_path, false,
- FILE_NOTIFY_CHANGE_FILE_NAME |
- FILE_NOTIFY_CHANGE_DIR_NAME |
- FILE_NOTIFY_CHANGE_ATTRIBUTES |
- FILE_NOTIFY_CHANGE_SIZE |
- FILE_NOTIFY_CHANGE_LAST_WRITE /*|
- FILE_NOTIFY_CHANGE_LAST_ACCESS |
- FILE_NOTIFY_CHANGE_CREATION |
- FILE_NOTIFY_CHANGE_SECURITY */);
+ FILE_NOTIFY_CHANGE_FILE_NAME
+ | FILE_NOTIFY_CHANGE_DIR_NAME
+ | FILE_NOTIFY_CHANGE_ATTRIBUTES
+ | FILE_NOTIFY_CHANGE_SIZE
+ | FILE_NOTIFY_CHANGE_LAST_WRITE
+ /*
+ | FILE_NOTIFY_CHANGE_LAST_ACCESS
+ | FILE_NOTIFY_CHANGE_CREATION
+ | FILE_NOTIFY_CHANGE_SECURITY
+ */
+ );
if (!_findChangeNotification.IsHandleAllocated())
{
DWORD lastError = GetLastError();
@@ -99,7 +102,7 @@ HRESULT CFsFolderStat::Enumerate()
{
RINOK(Progress->SetCompleted(NULL));
}
- Path += FCHAR_PATH_SEPARATOR;
+ Path.Add_PathSepar();
unsigned len = Path.Len();
Path += FCHAR_ANY_MASK;
CEnumerator enumerator(Path);
@@ -124,7 +127,7 @@ HRESULT CFsFolderStat::Enumerate()
#ifndef UNDER_CE
-static bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size)
+bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size)
{
DWORD highPart;
DWORD lowPart = INVALID_FILE_SIZE;
@@ -140,10 +143,10 @@ static bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size)
#ifdef WIN_LONG_PATH
if (USE_SUPER_PATH)
{
- UString longPath;
- if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
{
- lowPart = ::GetCompressedFileSizeW(longPath, &highPart);
+ lowPart = ::GetCompressedFileSizeW(superPath, &highPart);
if (lowPart != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR)
{
size = ((UInt64)highPart << 32) | lowPart;
@@ -279,11 +282,10 @@ bool CFSFolder::LoadComments()
if (len >= (1 << 28))
return false;
AString s;
- char *p = s.GetBuffer((unsigned)((size_t)len + 1));
+ char *p = s.GetBuf((unsigned)(size_t)len);
UInt32 processedSize;
file.Read(p, (UInt32)len, processedSize);
- p[len] = 0;
- s.ReleaseBuffer();
+ s.ReleaseBuf_CalcLen((unsigned)(size_t)len);
if (processedSize != len)
return false;
file.Close();
@@ -293,14 +295,6 @@ bool CFSFolder::LoadComments()
return _comments.ReadFromString(unicodeString);
}
-static bool IsAscii(const AString &s)
-{
- for (unsigned i = 0; i < s.Len(); i++)
- if ((Byte)s[i] >= 0x80)
- return false;
- return true;
-}
-
bool CFSFolder::SaveComments()
{
AString utf;
@@ -309,7 +303,7 @@ bool CFSFolder::SaveComments()
_comments.SaveToString(unicode);
ConvertUnicodeToUTF8(unicode, utf);
}
- if (!IsAscii(utf))
+ if (!utf.IsAscii())
utf.Insert(0, "\xEF\xBB\xBF" "\r\n");
FString path = _path + kDescriptionFileName;
@@ -576,7 +570,7 @@ STDMETHODIMP CFSFolder::GetRawProp(UInt32
static inline CFSTR GetExtensionPtr(const FString &name)
{
- int dotPos = name.ReverseFind(FTEXT('.'));
+ int dotPos = name.ReverseFind_Dot();
return name.Ptr((dotPos < 0) ? name.Len() : dotPos);
}
@@ -686,7 +680,7 @@ HRESULT CFSFolder::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder)
*resultFolder = 0;
CFSFolder *folderSpec = new CFSFolder;
CMyComPtr<IFolderFolder> subFolder = folderSpec;
- RINOK(folderSpec->Init(_path + name + FCHAR_PATH_SEPARATOR, 0));
+ RINOK(folderSpec->Init(_path + name + FCHAR_PATH_SEPARATOR));
*resultFolder = subFolder.Detach();
return S_OK;
}
@@ -700,6 +694,7 @@ void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const
prefix.Empty();
}
*/
+
/*
void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const
{
@@ -714,20 +709,17 @@ void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const
parent = cur.Parent;
}
- unsigned totalLen = len;
- wchar_t *p = prefix.GetBuffer(len);
+ wchar_t *p = prefix.GetBuf_SetEnd(len) + len;
parent = item.Parent;
while (parent >= 0)
{
const CDirItem &cur = Files[parent];
- // path = cur->Name + FCHAR_PATH_SEPARATOR + path;
- MyStringCopy(p + len - cur.Name.Len() - 1, (const wchar_t *)cur.Name);
- p[--len] = FCHAR_PATH_SEPARATOR;
- len -= cur.Name.Len();
+ *(--p) = FCHAR_PATH_SEPARATOR;
+ p -= cur.Name.Len();
+ wmemcpy(p, cur.Name, cur.Name.Len());
parent = cur.Parent;
}
- prefix.ReleaseBuffer(totalLen);
}
*/
@@ -752,24 +744,26 @@ STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **result
return BindToFolderSpec(us2fs(name), resultFolder);
}
-static CFSTR kLongPrefix = FTEXT("\\\\?\\");
+static const CFSTR kSuperPrefix = FTEXT("\\\\?\\");
STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
{
*resultFolder = 0;
+ /*
if (_parentFolder)
{
CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
*resultFolder = parentFolder.Detach();
return S_OK;
}
+ */
if (_path.IsEmpty())
return E_INVALIDARG;
- int pos = _path.ReverseFind(FCHAR_PATH_SEPARATOR);
+ int pos = _path.ReverseFind_PathSepar();
if (pos < 0 || pos != (int)_path.Len() - 1)
return E_FAIL;
FString parentPath = _path.Left(pos);
- pos = parentPath.ReverseFind(FCHAR_PATH_SEPARATOR);
+ pos = parentPath.ReverseFind_PathSepar();
if (pos < 0)
{
#ifdef UNDER_CE
@@ -783,9 +777,10 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
return S_OK;
}
+ /*
parentPath.DeleteFrom(pos + 1);
- if (parentPath == kLongPrefix)
+ if (parentPath == kSuperPrefix)
{
#ifdef UNDER_CE
*resultFolder = 0;
@@ -801,10 +796,10 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
FString parentPathReduced = parentPath.Left(pos);
#ifndef UNDER_CE
- pos = parentPathReduced.ReverseFind(FCHAR_PATH_SEPARATOR);
+ pos = parentPathReduced.ReverseFind_PathSepar();
if (pos == 1)
{
- if (parentPath[0] != FCHAR_PATH_SEPARATOR)
+ if (!IS_PATH_SEPAR_CHAR(parentPath[0]))
return E_FAIL;
CNetFolder *netFolderSpec = new CNetFolder;
CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
@@ -818,6 +813,7 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
RINOK(parentFolderSpec->Init(parentPath, 0));
*resultFolder = parentFolder.Detach();
+ */
return S_OK;
}
@@ -837,7 +833,7 @@ STDMETHODIMP CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
NWindows::NCOM::CPropVariant prop;
switch (propID)
{
- case kpidType: prop = L"FSFolder"; break;
+ case kpidType: prop = "FSFolder"; break;
case kpidPath: prop = fs2us(_path); break;
}
prop.Detach(value);
@@ -874,7 +870,7 @@ STDMETHODIMP CFSFolder::Clone(IFolderFolder **resultFolder)
{
CFSFolder *fsFolderSpec = new CFSFolder;
CMyComPtr<IFolderFolder> folderNew = fsFolderSpec;
- fsFolderSpec->Init(_path, 0);
+ fsFolderSpec->Init(_path);
*resultFolder = folderNew.Detach();
return S_OK;
}
@@ -1060,7 +1056,7 @@ STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID,
CTextPair pair;
pair.ID = filename;
pair.ID.Trim();
- pair.Value = value->bstrVal;
+ pair.Value.SetFromBstr(value->bstrVal);
pair.Value.Trim();
if (pair.Value.IsEmpty())
_comments.DeletePair(filename);
diff --git a/CPP/7zip/UI/FileManager/FSFolder.h b/CPP/7zip/UI/FileManager/FSFolder.h
index cb0d4ec2..057ba14c 100644
--- a/CPP/7zip/UI/FileManager/FSFolder.h
+++ b/CPP/7zip/UI/FileManager/FSFolder.h
@@ -8,9 +8,10 @@
#include "../../../Windows/FileFind.h"
+#include "../../Archive/IArchive.h"
+
#include "IFolder.h"
#include "TextPairs.h"
-#include "..\..\Archive\IArchive.h"
namespace NFsFolder {
@@ -133,7 +134,7 @@ private:
CObjectVector<CDirItem> Files;
FStringVector Folders;
// CObjectVector<CAltStream> Streams;
- CMyComPtr<IFolderFolder> _parentFolder;
+ // CMyComPtr<IFolderFolder> _parentFolder;
bool _commentsAreLoaded;
CPairsStorage _comments;
@@ -158,9 +159,9 @@ private:
#endif
public:
- HRESULT Init(const FString &path, IFolderFolder *parentFolder);
- #ifdef UNDER_CE
- HRESULT InitToRoot() { return Init(FTEXT("\\"), NULL); }
+ HRESULT Init(const FString &path /* , IFolderFolder *parentFolder */);
+ #if !defined(_WIN32) || defined(UNDER_CE)
+ HRESULT InitToRoot() { return Init(FSTRING_PATH_SEPARATOR /* , NULL */); }
#endif
CFSFolder() : _flatMode(false)
@@ -178,6 +179,7 @@ public:
}
// void GetPrefix(const CDirItem &item, FString &prefix) const;
+
FString GetRelPath(const CDirItem &item) const;
void Clear()
@@ -188,6 +190,24 @@ public:
}
};
+struct CCopyStateIO
+{
+ IProgress *Progress;
+ UInt64 TotalSize;
+ UInt64 StartPos;
+ UInt64 CurrentSize;
+ bool DeleteSrcFile;
+
+ int ErrorFileIndex;
+ UString ErrorMessage;
+
+ CCopyStateIO(): DeleteSrcFile(false), TotalSize(0), StartPos(0) {}
+
+ HRESULT MyCopyFile(CFSTR inPath, CFSTR outPath);
+};
+
+HRESULT SendLastErrorMessage(IFolderOperationsExtractCallback *callback, const FString &fileName);
+
}
#endif
diff --git a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
index 3f2fc9af..54dabc57 100644
--- a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
+++ b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
@@ -29,6 +29,75 @@ extern bool g_IsNT;
namespace NFsFolder {
+HRESULT CCopyStateIO::MyCopyFile(CFSTR inPath, CFSTR outPath)
+{
+ ErrorFileIndex = -1;
+ ErrorMessage.Empty();
+ CurrentSize = 0;
+
+ {
+ const size_t kBufSize = 1 << 16;
+ CByteArr buf(kBufSize);
+
+ NIO::CInFile inFile;
+ NIO::COutFile outFile;
+
+ if (!inFile.Open(inPath))
+ {
+ ErrorFileIndex = 0;
+ return S_OK;
+ }
+
+ if (!outFile.Create(outPath, true))
+ {
+ ErrorFileIndex = 1;
+ return S_OK;
+ }
+
+ for (;;)
+ {
+ UInt32 num;
+ if (!inFile.Read(buf, kBufSize, num))
+ {
+ ErrorFileIndex = 0;
+ return S_OK;
+ }
+ if (num == 0)
+ break;
+
+ UInt32 written = 0;
+ if (!outFile.Write(buf, num, written))
+ {
+ ErrorFileIndex = 1;
+ return S_OK;
+ }
+ if (written != num)
+ {
+ ErrorMessage = L"Write error";
+ return S_OK;
+ }
+ CurrentSize += num;
+ if (Progress)
+ {
+ UInt64 completed = StartPos + CurrentSize;
+ RINOK(Progress->SetCompleted(&completed));
+ }
+ }
+ }
+
+ if (DeleteSrcFile)
+ {
+ if (!DeleteFileAlways(inPath))
+ {
+ ErrorFileIndex = 0;
+ return S_OK;
+ }
+ }
+
+ return S_OK;
+}
+
+
/*
static bool IsItWindows2000orHigher()
{
@@ -43,8 +112,13 @@ static bool IsItWindows2000orHigher()
struct CProgressInfo
{
+ UInt64 TotalSize;
UInt64 StartPos;
+ UInt64 FileSize;
IProgress *Progress;
+ HRESULT ProgressResult;
+
+ void Init() { ProgressResult = S_OK; }
};
#ifndef PROGRESS_CONTINUE
@@ -71,7 +145,7 @@ DWORD
#endif
static DWORD CALLBACK CopyProgressRoutine(
- LARGE_INTEGER /* TotalFileSize */, // file size
+ LARGE_INTEGER TotalFileSize, // file size
LARGE_INTEGER TotalBytesTransferred, // bytes transferred
LARGE_INTEGER /* StreamSize */, // bytes in stream
LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream
@@ -82,14 +156,27 @@ static DWORD CALLBACK CopyProgressRoutine(
LPVOID lpData // from CopyFileEx
)
{
- CProgressInfo &progressInfo = *(CProgressInfo *)lpData;
- UInt64 completed = progressInfo.StartPos + TotalBytesTransferred.QuadPart;
- if (progressInfo.Progress->SetCompleted(&completed) != S_OK)
- return PROGRESS_CANCEL;
- return PROGRESS_CONTINUE;
+ TotalFileSize = TotalFileSize;
+ // TotalBytesTransferred = TotalBytesTransferred;
+ // StreamSize = StreamSize;
+ // StreamBytesTransferred = StreamBytesTransferred;
+ // dwStreamNumber = dwStreamNumber;
+ // dwCallbackReason = dwCallbackReason;
+
+ CProgressInfo &pi = *(CProgressInfo *)lpData;
+
+ if ((UInt64)TotalFileSize.QuadPart > pi.FileSize)
+ {
+ pi.TotalSize += (UInt64)TotalFileSize.QuadPart - pi.FileSize;
+ pi.FileSize = (UInt64)TotalFileSize.QuadPart;
+ pi.ProgressResult = pi.Progress->SetTotal(pi.TotalSize);
+ }
+ UInt64 completed = pi.StartPos + TotalBytesTransferred.QuadPart;
+ pi.ProgressResult = pi.Progress->SetCompleted(&completed);
+ return (pi.ProgressResult == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL);
}
-typedef BOOL (WINAPI * CopyFileExPointer)(
+typedef BOOL (WINAPI * Func_CopyFileExA)(
IN LPCSTR lpExistingFileName,
IN LPCSTR lpNewFileName,
IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
@@ -98,7 +185,7 @@ typedef BOOL (WINAPI * CopyFileExPointer)(
IN DWORD dwCopyFlags
);
-typedef BOOL (WINAPI * CopyFileExPointerW)(
+typedef BOOL (WINAPI * Func_CopyFileExW)(
IN LPCWSTR lpExistingFileName,
IN LPCWSTR lpNewFileName,
IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
@@ -107,110 +194,152 @@ typedef BOOL (WINAPI * CopyFileExPointerW)(
IN DWORD dwCopyFlags
);
-static bool FsCopyFile(CFSTR oldFile, CFSTR newFile, IProgress *progress, UInt64 &completedSize)
+typedef BOOL (WINAPI * Func_MoveFileWithProgressW)(
+ IN LPCWSTR lpExistingFileName,
+ IN LPCWSTR lpNewFileName,
+ IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
+ IN LPVOID lpData OPTIONAL,
+ IN DWORD dwFlags
+ );
+
+struct CCopyState
{
- CProgressInfo progressInfo;
- progressInfo.Progress = progress;
- progressInfo.StartPos = completedSize;
- BOOL CancelFlag = FALSE;
+ CProgressInfo ProgressInfo;
+ IFolderOperationsExtractCallback *Callback;
+ UInt64 TotalSize;
+ bool MoveMode;
+ bool UseReadWriteMode;
+
+ Func_CopyFileExW my_CopyFileExW;
+ #ifndef UNDER_CE
+ Func_MoveFileWithProgressW my_MoveFileWithProgressW;
+ #endif
#ifndef _UNICODE
- if (g_IsNT)
+ Func_CopyFileExA my_CopyFileExA;
+ #endif
+
+ void Prepare();
+ bool CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile);
+ bool CopyFile_Sys(CFSTR oldFile, CFSTR newFile);
+ bool MoveFile_Sys(CFSTR oldFile, CFSTR newFile);
+
+ HRESULT CallProgress();
+
+ bool IsCallbackProgressError() { return ProgressInfo.ProgressResult != S_OK; }
+};
+
+HRESULT CCopyState::CallProgress()
+{
+ return ProgressInfo.Progress->SetCompleted(&ProgressInfo.StartPos);
+}
+
+void CCopyState::Prepare()
+{
+ my_CopyFileExW = NULL;
+ #ifndef UNDER_CE
+ my_MoveFileWithProgressW = NULL;
#endif
+ #ifndef _UNICODE
+ my_CopyFileExA = NULL;
+ if (!g_IsNT)
{
- const wchar_t *k_DllName =
- #ifdef UNDER_CE
+ my_CopyFileExA = (Func_CopyFileExA)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "CopyFileExA");
+ }
+ else
+ #endif
+ {
+ HMODULE module = ::GetModuleHandleW(
+ #ifdef UNDER_CE
L"coredll.dll"
- #else
+ #else
L"kernel32.dll"
- #endif
- ;
- CopyFileExPointerW copyFunctionW = (CopyFileExPointerW)
- My_GetProcAddress(::GetModuleHandleW(k_DllName), "CopyFileExW");
-
+ #endif
+ );
+ my_CopyFileExW = (Func_CopyFileExW)My_GetProcAddress(module, "CopyFileExW");
+ #ifndef UNDER_CE
+ my_MoveFileWithProgressW = (Func_MoveFileWithProgressW)My_GetProcAddress(module, "MoveFileWithProgressW");
+ #endif
+ }
+}
+
+/* WinXP-64:
+ CopyFileW(fromFile, toFile:altStream)
+ OK - there are NO alt streams in fromFile
+ ERROR_INVALID_PARAMETER - there are alt streams in fromFile
+*/
+
+bool CCopyState::CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile)
+{
+ BOOL cancelFlag = FALSE;
+ if (my_CopyFileExW)
+ return BOOLToBool(my_CopyFileExW(oldFile, newFile, CopyProgressRoutine,
+ &ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS));
+ return BOOLToBool(::CopyFileW(oldFile, newFile, TRUE));
+}
+
+bool CCopyState::CopyFile_Sys(CFSTR oldFile, CFSTR newFile)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ if (my_CopyFileExA)
+ {
+ BOOL cancelFlag = FALSE;
+ if (my_CopyFileExA(fs2fas(oldFile), fs2fas(newFile),
+ CopyProgressRoutine, &ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ }
+ return BOOLToBool(::CopyFile(fs2fas(oldFile), fs2fas(newFile), TRUE));
+ }
+ else
+ #endif
+ {
IF_USE_MAIN_PATH_2(oldFile, newFile)
{
- if (copyFunctionW == 0)
- return BOOLToBool(::CopyFileW(fs2us(oldFile), fs2us(newFile), TRUE));
- if (copyFunctionW(fs2us(oldFile), fs2us(newFile), CopyProgressRoutine,
- &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
+ if (CopyFile_NT(fs2us(oldFile), fs2us(newFile)))
return true;
}
#ifdef WIN_LONG_PATH
if (USE_SUPER_PATH_2)
{
- UString longPathExisting, longPathNew;
- if (!GetSuperPaths(oldFile, newFile, longPathExisting, longPathNew, USE_MAIN_PATH_2))
+ if (IsCallbackProgressError())
+ return false;
+ UString superPathOld, superPathNew;
+ if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2))
return false;
- if (copyFunctionW(longPathExisting, longPathNew, CopyProgressRoutine,
- &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
+ if (CopyFile_NT(superPathOld, superPathNew))
return true;
}
#endif
return false;
}
- #ifndef _UNICODE
- else
- {
- CopyFileExPointer copyFunction = (CopyFileExPointer)
- ::GetProcAddress(::GetModuleHandleA("kernel32.dll"),
- "CopyFileExA");
- if (copyFunction != 0)
- {
- if (copyFunction(fs2fas(oldFile), fs2fas(newFile),
- CopyProgressRoutine,&progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
- return true;
- if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return false;
- }
- return BOOLToBool(::CopyFile(fs2fas(oldFile), fs2fas(newFile), TRUE));
- }
- #endif
}
-typedef BOOL (WINAPI * MoveFileWithProgressPointer)(
- IN LPCWSTR lpExistingFileName,
- IN LPCWSTR lpNewFileName,
- IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
- IN LPVOID lpData OPTIONAL,
- IN DWORD dwFlags
- );
-
-#ifdef UNDER_CE
-#define NON_CE_VAR(_v_)
-#else
-#define NON_CE_VAR(_v_) _v_
-#endif
-
-static bool FsMoveFile(CFSTR oldFile, CFSTR newFile,
- IProgress * NON_CE_VAR(progress),
- UInt64 & NON_CE_VAR(completedSize))
+bool CCopyState::MoveFile_Sys(CFSTR oldFile, CFSTR newFile)
{
#ifndef UNDER_CE
// if (IsItWindows2000orHigher())
// {
- CProgressInfo progressInfo;
- progressInfo.Progress = progress;
- progressInfo.StartPos = completedSize;
-
- MoveFileWithProgressPointer moveFunction = (MoveFileWithProgressPointer)
- My_GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
- "MoveFileWithProgressW");
- if (moveFunction != 0)
+ if (my_MoveFileWithProgressW)
{
IF_USE_MAIN_PATH_2(oldFile, newFile)
{
- if (moveFunction(fs2us(oldFile), fs2us(newFile), CopyProgressRoutine,
- &progressInfo, MOVEFILE_COPY_ALLOWED))
+ if (my_MoveFileWithProgressW(fs2us(oldFile), fs2us(newFile), CopyProgressRoutine,
+ &ProgressInfo, MOVEFILE_COPY_ALLOWED))
return true;
}
#ifdef WIN_LONG_PATH
if ((!(USE_MAIN_PATH_2) || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) && USE_SUPER_PATH_2)
{
- UString longPathExisting, longPathNew;
- if (!GetSuperPaths(oldFile, newFile, longPathExisting, longPathNew, USE_MAIN_PATH_2))
+ if (IsCallbackProgressError())
+ return false;
+ UString superPathOld, superPathNew;
+ if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2))
return false;
- if (moveFunction(longPathExisting, longPathNew, CopyProgressRoutine,
- &progressInfo, MOVEFILE_COPY_ALLOWED))
+ if (my_MoveFileWithProgressW(superPathOld, superPathNew, CopyProgressRoutine,
+ &ProgressInfo, MOVEFILE_COPY_ALLOWED))
return true;
}
#endif
@@ -226,7 +355,10 @@ static bool FsMoveFile(CFSTR oldFile, CFSTR newFile,
static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
const wchar_t *message, const FString &fileName)
{
- return callback->ShowMessage(message + fs2us(fileName));
+ UString s = message;
+ s += L" : ";
+ s += fs2us(fileName);
+ return callback->ShowMessage(s);
}
static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
@@ -235,41 +367,104 @@ static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
}
-static HRESULT FsCopyFile(
+static DWORD Return_LastError_or_FAIL()
+{
+ DWORD errorCode = GetLastError();
+ if (errorCode == 0)
+ errorCode = (DWORD)E_FAIL;
+ return errorCode;
+}
+
+static UString GetLastErrorMessage()
+{
+ return NError::MyFormatMessage(Return_LastError_or_FAIL());
+}
+
+HRESULT SendLastErrorMessage(IFolderOperationsExtractCallback *callback, const FString &fileName)
+{
+ return SendMessageError(callback, GetLastErrorMessage(), fileName);
+}
+
+static HRESULT CopyFile_Ask(
+ CCopyState &state,
const FString &srcPath,
const CFileInfo &srcFileInfo,
- const FString &destPathSpec,
- IFolderOperationsExtractCallback *callback,
- UInt64 &completedSize)
+ const FString &destPath)
{
- FString destPath = destPathSpec;
if (CompareFileNames(destPath, srcPath) == 0)
{
- RINOK(SendMessageError(callback, "can not copy file onto itself: ", destPath));
+ RINOK(SendMessageError(state.Callback,
+ state.MoveMode ?
+ "can not move file onto itself" :
+ "can not copy file onto itself"
+ , destPath));
return E_ABORT;
}
Int32 writeAskResult;
CMyComBSTR destPathResult;
- RINOK(callback->AskWrite(
+ RINOK(state.Callback->AskWrite(
fs2us(srcPath),
BoolToInt(false),
&srcFileInfo.MTime, &srcFileInfo.Size,
fs2us(destPath),
&destPathResult,
&writeAskResult));
+
if (IntToBool(writeAskResult))
{
- FString destPathNew = us2fs((const wchar_t *)(BSTR)destPathResult);
- RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
- if (!FsCopyFile(srcPath, destPathNew, callback, completedSize))
+ FString destPathNew = us2fs((LPCOLESTR)destPathResult);
+ RINOK(state.Callback->SetCurrentFilePath(fs2us(srcPath)));
+
+ if (state.UseReadWriteMode)
{
- RINOK(SendMessageError(callback, NError::MyFormatMessage(GetLastError()) + L" : ", destPathNew));
- return E_ABORT;
+ NFsFolder::CCopyStateIO state2;
+ state2.Progress = state.Callback;
+ state2.DeleteSrcFile = state.MoveMode;
+ state2.TotalSize = state.TotalSize;
+ state2.StartPos = state.ProgressInfo.StartPos;
+ RINOK(state2.MyCopyFile(srcPath, destPathNew));
+ if (state2.ErrorFileIndex >= 0)
+ {
+ if (state2.ErrorMessage.IsEmpty())
+ state2.ErrorMessage = GetLastErrorMessage();
+ FString errorName;
+ if (state2.ErrorFileIndex == 0)
+ errorName = srcPath;
+ else
+ errorName = destPathNew;
+ RINOK(SendMessageError(state.Callback, state2.ErrorMessage, errorName));
+ return E_ABORT;
+ }
+ state.ProgressInfo.StartPos += state2.CurrentSize;
+ }
+ else
+ {
+ state.ProgressInfo.FileSize = srcFileInfo.Size;
+ bool res;
+ if (state.MoveMode)
+ res = state.MoveFile_Sys(srcPath, destPathNew);
+ else
+ res = state.CopyFile_Sys(srcPath, destPathNew);
+ RINOK(state.ProgressInfo.ProgressResult);
+ if (!res)
+ {
+ // GetLastError() is ERROR_REQUEST_ABORTED in case of PROGRESS_CANCEL.
+ RINOK(SendMessageError(state.Callback, GetLastErrorMessage(), destPathNew));
+ return E_ABORT;
+ }
+ state.ProgressInfo.StartPos += state.ProgressInfo.FileSize;
}
}
- completedSize += srcFileInfo.Size;
- return callback->SetCompleted(&completedSize);
+ else
+ {
+ if (state.TotalSize >= srcFileInfo.Size)
+ {
+ state.TotalSize -= srcFileInfo.Size;
+ RINOK(state.ProgressInfo.Progress->SetTotal(state.TotalSize));
+ }
+ }
+ return state.CallProgress();
}
static FString CombinePath(const FString &folderPath, const FString &fileName)
@@ -288,123 +483,70 @@ static bool IsDestChild(const FString &src, const FString &dest)
}
static HRESULT CopyFolder(
- const FString &srcPath,
- const FString &destPath,
- IFolderOperationsExtractCallback *callback,
- UInt64 &completedSize)
+ CCopyState &state,
+ const FString &srcPath, // without TAIL separator
+ const FString &destPath) // without TAIL separator
{
- RINOK(callback->SetCompleted(&completedSize));
+ RINOK(state.CallProgress());
if (IsDestChild(srcPath, destPath))
{
- RINOK(SendMessageError(callback, "can not copy folder onto itself: ", destPath));
+ RINOK(SendMessageError(state.Callback,
+ state.MoveMode ?
+ "can not copy folder onto itself" :
+ "can not move folder onto itself"
+ , destPath));
return E_ABORT;
}
+ if (state.MoveMode)
+ {
+ if (state.MoveFile_Sys(srcPath, destPath))
+ return S_OK;
+
+ // MSDN: MoveFile() fails for dirs on different volumes.
+ }
+
if (!CreateComplexDir(destPath))
{
- RINOK(SendMessageError(callback, "can not create folder: ", destPath));
+ RINOK(SendMessageError(state.Callback, "can not create folder", destPath));
return E_ABORT;
}
+
CEnumerator enumerator(CombinePath(srcPath, FSTRING_ANY_MASK));
- CDirItem fi;
- while (enumerator.Next(fi))
+
+ for (;;)
{
+ NFind::CFileInfo fi;
+ bool found;
+ if (!enumerator.Next(fi, found))
+ {
+ SendLastErrorMessage(state.Callback, srcPath);
+ return S_OK;
+ }
+ if (!found)
+ break;
const FString srcPath2 = CombinePath(srcPath, fi.Name);
const FString destPath2 = CombinePath(destPath, fi.Name);
if (fi.IsDir())
{
- RINOK(CopyFolder(srcPath2, destPath2, callback, completedSize))
+ RINOK(CopyFolder(state, srcPath2, destPath2))
}
else
{
- RINOK(FsCopyFile(srcPath2, fi, destPath2, callback, completedSize));
+ RINOK(CopyFile_Ask(state, srcPath2, fi, destPath2));
}
}
- return S_OK;
-}
-
-/////////////////////////////////////////////////
-// Move Operations
-
-static HRESULT FsMoveFile(
- const FString &srcPath,
- const CFileInfo &srcFileInfo,
- const FString &destPath,
- IFolderOperationsExtractCallback *callback,
- UInt64 &completedSize)
-{
- if (CompareFileNames(destPath, srcPath) == 0)
- {
- RINOK(SendMessageError(callback, "can not move file onto itself: ", srcPath));
- return E_ABORT;
- }
-
- Int32 writeAskResult;
- CMyComBSTR destPathResult;
- RINOK(callback->AskWrite(
- fs2us(srcPath),
- BoolToInt(false),
- &srcFileInfo.MTime, &srcFileInfo.Size,
- fs2us(destPath),
- &destPathResult,
- &writeAskResult));
- if (IntToBool(writeAskResult))
- {
- FString destPathNew = us2fs((const wchar_t *)(BSTR)destPathResult);
- RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
- if (!FsMoveFile(srcPath, destPathNew, callback, completedSize))
- {
- RINOK(SendMessageError(callback, "can not move to file: ", destPathNew));
- }
- }
- completedSize += srcFileInfo.Size;
- RINOK(callback->SetCompleted(&completedSize));
- return S_OK;
-}
-
-static HRESULT FsMoveFolder(
- const FString &srcPath,
- const FString &destPath,
- IFolderOperationsExtractCallback *callback,
- UInt64 &completedSize)
-{
- if (IsDestChild(srcPath, destPath))
- {
- RINOK(SendMessageError(callback, "can not move folder onto itself: ", destPath));
- return E_ABORT;
- }
- if (FsMoveFile(srcPath, destPath, callback, completedSize))
- return S_OK;
-
- if (!CreateComplexDir(destPath))
+ if (state.MoveMode)
{
- RINOK(SendMessageError(callback, "can not create folder: ", destPath));
- return E_ABORT;
- }
- {
- CEnumerator enumerator(CombinePath(srcPath, FSTRING_ANY_MASK));
- CDirItem fi;
- while (enumerator.Next(fi))
+ if (!RemoveDir(srcPath))
{
- const FString srcPath2 = CombinePath(srcPath, fi.Name);
- const FString destPath2 = CombinePath(destPath, fi.Name);
- if (fi.IsDir())
- {
- RINOK(FsMoveFolder(srcPath2, destPath2, callback, completedSize));
- }
- else
- {
- RINOK(FsMoveFile(srcPath2, fi, destPath2, callback, completedSize));
- }
+ RINOK(SendMessageError(state.Callback, "can not remove folder", srcPath));
+ return E_ABORT;
}
}
- if (!RemoveDir(srcPath))
- {
- RINOK(SendMessageError(callback, "can not remove folder: ", srcPath));
- return E_ABORT;
- }
+
return S_OK;
}
@@ -415,33 +557,44 @@ STDMETHODIMP CFSFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
if (numItems == 0)
return S_OK;
- CFsFolderStat stat;
- stat.Progress = callback;
- RINOK(GetItemsFullSize(indices, numItems, stat));
- RINOK(callback->SetTotal(stat.Size));
- RINOK(callback->SetNumFiles(stat.NumFiles));
-
FString destPath = us2fs(path);
if (destPath.IsEmpty())
return E_INVALIDARG;
- bool directName = (destPath.Back() != FCHAR_PATH_SEPARATOR);
- if (directName)
+
+ bool isAltDest = NName::IsAltPathPrefix(destPath);;
+ bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
+
+ if (isDirectPath)
{
if (numItems > 1)
return E_INVALIDARG;
}
- else
- {
- // Does CreateComplexDir work in network ?
- if (!CreateComplexDir(destPath))
- {
- RINOK(SendMessageError(callback, "can not create folder: ", destPath));
- return E_ABORT;
- }
- }
+
+ CFsFolderStat stat;
+ stat.Progress = callback;
+ RINOK(GetItemsFullSize(indices, numItems, stat));
+
+ if (stat.NumFolders != 0 && isAltDest)
+ return E_NOTIMPL;
+
+ RINOK(callback->SetTotal(stat.Size));
+ RINOK(callback->SetNumFiles(stat.NumFiles));
UInt64 completedSize = 0;
RINOK(callback->SetCompleted(&completedSize));
+
+ CCopyState state;
+ state.ProgressInfo.TotalSize = stat.Size;
+ state.ProgressInfo.TotalSize = stat.Size;
+ state.ProgressInfo.StartPos = 0;
+ state.ProgressInfo.Progress = callback;
+ state.ProgressInfo.Init();
+ state.Callback = callback;
+ state.MoveMode = IntToBool(moveMode);
+ state.UseReadWriteMode = isAltDest;
+ state.Prepare();
+ state.TotalSize = stat.Size;
+
for (UInt32 i = 0; i < numItems; i++)
{
UInt32 index = indices[i];
@@ -449,38 +602,25 @@ STDMETHODIMP CFSFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
continue;
const CDirItem &fi = Files[index];
FString destPath2 = destPath;
- if (!directName)
+ if (!isDirectPath)
destPath2 += fi.Name;
FString srcPath;
GetFullPath(fi, srcPath);
+
if (fi.IsDir())
{
- if (moveMode)
- {
- RINOK(FsMoveFolder(srcPath, destPath2, callback, completedSize));
- }
- else
- {
- RINOK(CopyFolder(srcPath, destPath2, callback, completedSize));
- }
+ RINOK(CopyFolder(state, srcPath, destPath2));
}
else
{
- if (moveMode)
- {
- RINOK(FsMoveFile(srcPath, fi, destPath2, callback, completedSize));
- }
- else
- {
- RINOK(FsCopyFile(srcPath, fi, destPath2, callback, completedSize));
- }
+ RINOK(CopyFile_Ask(state, srcPath, fi, destPath2));
}
}
return S_OK;
}
STDMETHODIMP CFSFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
- const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
+ const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
{
/*
UInt64 numFolders, numFiles, totalSize;
diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
index 2d3b1d92..dc46ff5b 100644
--- a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
+++ b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
@@ -55,12 +55,10 @@ static int FindPlugin(const CObjectVector<CPluginInfo> &plugins, const UString &
}
*/
-static const FChar kExtensionDelimiter = FTEXT('.');
-
static void SplitNameToPureNameAndExtension(const FString &fullName,
FString &pureName, FString &extensionDelimiter, FString &extension)
{
- int index = fullName.ReverseFind(kExtensionDelimiter);
+ int index = fullName.ReverseFind_Dot();
if (index < 0)
{
pureName = fullName;
@@ -70,7 +68,7 @@ static void SplitNameToPureNameAndExtension(const FString &fullName,
else
{
pureName.SetFrom(fullName, index);
- extensionDelimiter = kExtensionDelimiter;
+ extensionDelimiter = FTEXT('.');
extension = fullName.Ptr(index + 1);
}
}
@@ -89,7 +87,7 @@ HRESULT OpenFileFolderPlugin(
FString extension, name, pureName, dot;
- int slashPos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
+ int slashPos = path.ReverseFind_PathSepar();
FString dirPrefix;
FString fileName;
if (slashPos >= 0)
diff --git a/CPP/7zip/UI/FileManager/FilePlugins.cpp b/CPP/7zip/UI/FileManager/FilePlugins.cpp
index 556c54fd..46000301 100644
--- a/CPP/7zip/UI/FileManager/FilePlugins.cpp
+++ b/CPP/7zip/UI/FileManager/FilePlugins.cpp
@@ -11,7 +11,7 @@
int CExtDatabase::FindExt(const UString &ext)
{
FOR_VECTOR (i, Exts)
- if (Exts[i].Ext.IsEqualToNoCase(ext))
+ if (Exts[i].Ext.IsEqualTo_NoCase(ext))
return i;
return -1;
}
diff --git a/CPP/7zip/UI/FileManager/FoldersPage.rc b/CPP/7zip/UI/FileManager/FoldersPage.rc
index fb48ee6e..cb345ea6 100644
--- a/CPP/7zip/UI/FileManager/FoldersPage.rc
+++ b/CPP/7zip/UI/FileManager/FoldersPage.rc
@@ -1,7 +1,7 @@
#include "FoldersPageRes.h"
#include "../../GuiCommon.rc"
-#define xc 196
+#define xc 240
#define yc 100
IDD_FOLDERS MY_PAGE
diff --git a/CPP/7zip/UI/FileManager/IFolder.h b/CPP/7zip/UI/FileManager/IFolder.h
index 60991a71..c5cff06e 100644
--- a/CPP/7zip/UI/FileManager/IFolder.h
+++ b/CPP/7zip/UI/FileManager/IFolder.h
@@ -36,6 +36,21 @@ FOLDER_INTERFACE(IFolderFolder, 0x00)
INTERFACE_FolderFolder(PURE)
};
+/*
+ IFolderAltStreams::
+ BindToAltStreams((UInt32)(Int32)-1, ... ) means alt streams of that folder
+*/
+
+#define INTERFACE_FolderAltStreams(x) \
+ STDMETHOD(BindToAltStreams)(UInt32 index, IFolderFolder **resultFolder) x; \
+ STDMETHOD(BindToAltStreams)(const wchar_t *name, IFolderFolder **resultFolder) x; \
+ STDMETHOD(AreAltStreamsSupported)(UInt32 index, Int32 *isSupported) x; \
+
+FOLDER_INTERFACE(IFolderAltStreams, 0x17)
+{
+ INTERFACE_FolderAltStreams(PURE)
+};
+
FOLDER_INTERFACE(IFolderWasChanged, 0x04)
{
STDMETHOD(WasChanged)(Int32 *wasChanged) PURE;
@@ -67,7 +82,7 @@ FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x0B)
Int32 includeAltStreams, Int32 replaceAltStreamCharsMode, \
const wchar_t *path, IFolderOperationsExtractCallback *callback) x; \
STDMETHOD(CopyFrom)(Int32 moveMode, const wchar_t *fromFolderPath, \
- const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress) x; \
+ const wchar_t * const *itemsPaths, UInt32 numItems, IProgress *progress) x; \
STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) x; \
STDMETHOD(CopyFromFile)(UInt32 index, const wchar_t *fullFilePath, IProgress *progress) x; \
diff --git a/CPP/7zip/UI/FileManager/LangPage.cpp b/CPP/7zip/UI/FileManager/LangPage.cpp
index 54253295..d9dc6c52 100644
--- a/CPP/7zip/UI/FileManager/LangPage.cpp
+++ b/CPP/7zip/UI/FileManager/LangPage.cpp
@@ -63,8 +63,7 @@ bool CLangPage::OnInit()
if (!LangOpen(lang, dirPrefix + fi.Name))
{
- if (!error.IsEmpty())
- error += L' ';
+ error.Add_Space_if_NotEmpty();
error += fs2us(fi.Name);
continue;
}
@@ -80,7 +79,7 @@ bool CLangPage::OnInit()
index = (int)_langCombo.AddString(s);
_langCombo.SetItemData(index, _paths.Size());
_paths.Add(shortName);
- if (g_LangID.IsEqualToNoCase(shortName))
+ if (g_LangID.IsEqualTo_NoCase(shortName))
_langCombo.SetCurSel(index);
}
diff --git a/CPP/7zip/UI/FileManager/LangPage.rc b/CPP/7zip/UI/FileManager/LangPage.rc
index 5aeaf406..164e2d30 100644
--- a/CPP/7zip/UI/FileManager/LangPage.rc
+++ b/CPP/7zip/UI/FileManager/LangPage.rc
@@ -1,7 +1,7 @@
#include "LangPageRes.h"
#include "../../GuiCommon.rc"
-#define xc 148
+#define xc 160
#define yc 100
IDD_LANG DIALOG 0, 0, xs, ys MY_PAGE_STYLE MY_FONT
diff --git a/CPP/7zip/UI/FileManager/LangUtils.cpp b/CPP/7zip/UI/FileManager/LangUtils.cpp
index 15d68f43..9723704a 100644
--- a/CPP/7zip/UI/FileManager/LangUtils.cpp
+++ b/CPP/7zip/UI/FileManager/LangUtils.cpp
@@ -115,6 +115,11 @@ UString LangString(UInt32 langID)
return MyLoadString(langID);
}
+void AddLangString(UString &s, UInt32 langID)
+{
+ s += LangString(langID);
+}
+
void LangString(UInt32 langID, UString &dest)
{
const wchar_t *s = g_Lang.Get(langID);
@@ -166,7 +171,7 @@ static void FindShortNames(UInt32 primeLang, UStringVector &names)
p++;
}
while (p != p2)
- s += (wchar_t)*p++;
+ s += (wchar_t)(Byte)*p++;
names.Add(s);
}
p = p2 + 1;
diff --git a/CPP/7zip/UI/FileManager/LangUtils.h b/CPP/7zip/UI/FileManager/LangUtils.h
index 509a5ae3..d63a443c 100644
--- a/CPP/7zip/UI/FileManager/LangUtils.h
+++ b/CPP/7zip/UI/FileManager/LangUtils.h
@@ -25,13 +25,15 @@ void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems);
void LangSetWindowText(HWND window, UInt32 langID);
UString LangString(UInt32 langID);
+void AddLangString(UString &s, UInt32 langID);
void LangString(UInt32 langID, UString &dest);
void LangString_OnlyFromLangFile(UInt32 langID, UString &dest);
-
+
#else
inline UString LangString(UInt32 langID) { return NWindows::MyLoadString(langID); }
inline void LangString(UInt32 langID, UString &dest) { NWindows::MyLoadString(langID, dest); }
+inline void AddLangString(UString &s, UInt32 langID) { s += NWindows::MyLoadString(langID); }
#endif
diff --git a/CPP/7zip/UI/FileManager/LinkDialog.cpp b/CPP/7zip/UI/FileManager/LinkDialog.cpp
index a24ec601..bc482e4b 100644
--- a/CPP/7zip/UI/FileManager/LinkDialog.cpp
+++ b/CPP/7zip/UI/FileManager/LinkDialog.cpp
@@ -321,14 +321,14 @@ void CApp::Link()
int index = indices[0];
const UString itemName = srcPanel.GetItemName(index);
- UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index);
+ UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index);
UString path = srcPath;
{
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
CPanel &destPanel = Panels[destPanelIndex];
if (NumPanels > 1)
if (destPanel.IsFSFolder())
- path = destPanel._currentFolderPrefix;
+ path = destPanel.GetFsPath();
}
CLinkDialog dlg;
diff --git a/CPP/7zip/UI/FileManager/MenuPage.rc b/CPP/7zip/UI/FileManager/MenuPage.rc
index 626f415e..f20c574e 100644
--- a/CPP/7zip/UI/FileManager/MenuPage.rc
+++ b/CPP/7zip/UI/FileManager/MenuPage.rc
@@ -1,7 +1,7 @@
#include "MenuPageRes.h"
#include "../../GuiCommon.rc"
-#define xc 196
+#define xc 240
#define yc 196
IDD_MENU MY_PAGE
diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
index 401e48ef..b0f6615e 100644
--- a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
+++ b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
@@ -13,6 +13,7 @@
#include "App.h"
#include "HelpUtils.h"
#include "LangUtils.h"
+#include "MyLoadMenu.h"
#include "RegistryUtils.h"
#include "resource.h"
@@ -100,19 +101,19 @@ public:
#define MIIM_FTYPE 0x00000100
#endif
-static UINT Get_fMaskForString()
+static UINT Get_fMask_for_String()
{
return g_IsNew_fMask ? MIIM_STRING : MIIM_TYPE;
}
-static UINT Get_fMaskForFTypeAndString()
+static UINT Get_fMask_for_FType_and_String()
{
return g_IsNew_fMask ? (MIIM_STRING | MIIM_FTYPE) : MIIM_TYPE;
}
*/
-static inline UINT Get_fMaskForString() { return MIIM_TYPE; }
-static inline UINT Get_fMaskForFTypeAndString() { return MIIM_TYPE; }
+static inline UINT Get_fMask_for_String() { return MIIM_TYPE; }
+static inline UINT Get_fMask_for_FType_and_String() { return MIIM_TYPE; }
static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
{
@@ -121,7 +122,7 @@ static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
for (int i = 0;; i++)
{
CMenuItem item;
- item.fMask = Get_fMaskForString() | MIIM_SUBMENU | MIIM_ID;
+ item.fMask = Get_fMask_for_String() | MIIM_SUBMENU | MIIM_ID;
item.fType = MFT_STRING;
if (!menu.GetItem(i, true, item))
break;
@@ -157,14 +158,13 @@ static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
if (newString.IsEmpty())
continue;
- UString shorcutString = item.StringValue;
- int tabPos = shorcutString.ReverseFind(wchar_t('\t'));
+ int tabPos = item.StringValue.ReverseFind(L'\t');
if (tabPos >= 0)
- newString += shorcutString.Ptr(tabPos);
+ newString += item.StringValue.Ptr(tabPos);
}
{
item.StringValue = newString;
- item.fMask = Get_fMaskForString();
+ item.fMask = Get_fMask_for_String();
item.fType = MFT_STRING;
menu.SetItem(i, true, item);
}
@@ -203,7 +203,7 @@ static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec)
for (int i = 0;; i++)
{
CMenuItem item;
- item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString();
+ item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMask_for_FType_and_String();
item.fType = MFT_STRING;
if (!srcMenu.GetItem(i, true, item))
@@ -307,13 +307,14 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
subMenu.Attach(menu.GetSubMenu(0));
subMenu.RemoveAllItems();
int i;
+
for (i = 0; i < 10; i++)
{
UString s = LangString(IDS_BOOKMARK);
- s += L' ';
+ s.Add_Space();
wchar_t c = (wchar_t)(L'0' + i);
s += c;
- s += L"\tAlt+Shift+";
+ s.AddAscii("\tAlt+Shift+");
s += c;
subMenu.AppendItem(MF_STRING, kSetBookmarkMenuID + i, s);
}
@@ -332,7 +333,7 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
}
if (s.IsEmpty())
s = L'-';
- s += L"\tAlt+";
+ s.AddAscii("\tAlt+");
s += (wchar_t)(L'0' + i);
menu.AppendItem(MF_STRING, kOpenBookmarkMenuID + i, s);
}
@@ -348,8 +349,7 @@ void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id)
}
*/
-void LoadFileMenu(HMENU hMenu, int startPos, bool programMenu,
- bool isFsFolder, int numItems, bool allAreFiles)
+void CFileMenu::Load(HMENU hMenu, unsigned startPos)
{
CMenu destMenu;
destMenu.Attach(hMenu);
@@ -357,15 +357,17 @@ void LoadFileMenu(HMENU hMenu, int startPos, bool programMenu,
UString diffPath;
ReadRegDiff(diffPath);
- int numRealItems = startPos;
- for (int i = 0;; i++)
+ unsigned numRealItems = startPos;
+ for (unsigned i = 0;; i++)
{
CMenuItem item;
- item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString();
+ item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMask_for_FType_and_String();
item.fType = MFT_STRING;
+
if (!g_FileMenu.GetItem(i, true, item))
break;
+
{
if (!programMenu && item.wID == IDCLOSE)
continue;
@@ -376,6 +378,26 @@ void LoadFileMenu(HMENU hMenu, int startPos, bool programMenu,
bool isOneFsFile = (isFsFolder && numItems == 1 && allAreFiles);
bool disable = (!isOneFsFile && (item.wID == IDM_SPLIT || item.wID == IDM_COMBINE));
+ if (readOnly)
+ {
+ switch (item.wID)
+ {
+ case IDM_RENAME:
+ case IDM_MOVE_TO:
+ case IDM_DELETE:
+ case IDM_COMMENT:
+ case IDM_CREATE_FOLDER:
+ case IDM_CREATE_FILE:
+ disable = true;
+ }
+ }
+
+ if (item.wID == IDM_LINK && numItems != 1)
+ disable = true;
+
+ if (item.wID == IDM_ALT_STREAMS)
+ disable = !isAltStreamsSupported;
+
bool isBigScreen = NControl::IsDialogSizeOK(40, 200);
if (!isBigScreen && (disable || item.IsSeparator()))
@@ -434,6 +456,7 @@ bool ExecuteFileCommand(int id)
case IDM_CREATE_FILE: g_App.CreateFile(); break;
#ifndef UNDER_CE
case IDM_LINK: g_App.Link(); break;
+ case IDM_ALT_STREAMS: g_App.OpenAltStreams(); break;
#endif
default: return false;
}
diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.h b/CPP/7zip/UI/FileManager/MyLoadMenu.h
index 53e9d0ef..02569e52 100644
--- a/CPP/7zip/UI/FileManager/MyLoadMenu.h
+++ b/CPP/7zip/UI/FileManager/MyLoadMenu.h
@@ -9,8 +9,28 @@ void OnMenuActivating(HWND hWnd, HMENU hMenu, int position);
bool OnMenuCommand(HWND hWnd, int id);
void MyLoadMenu();
-void LoadFileMenu(HMENU hMenu, int startPos, bool programMenu,
- bool isFsFolder, int numItems, bool allAreFiles);
+
+struct CFileMenu
+{
+ bool programMenu;
+ bool readOnly;
+ bool isFsFolder;
+ bool allAreFiles;
+ bool isAltStreamsSupported;
+ int numItems;
+
+ CFileMenu():
+ programMenu(false),
+ readOnly(false),
+ isFsFolder(false),
+ allAreFiles(false),
+ isAltStreamsSupported(true),
+ numItems(0)
+ {}
+
+ void Load(HMENU hMenu, unsigned startPos);
+};
+
bool ExecuteFileCommand(int id);
#endif
diff --git a/CPP/7zip/UI/FileManager/NetFolder.cpp b/CPP/7zip/UI/FileManager/NetFolder.cpp
index f3d531ab..bfccc353 100644
--- a/CPP/7zip/UI/FileManager/NetFolder.cpp
+++ b/CPP/7zip/UI/FileManager/NetFolder.cpp
@@ -73,7 +73,15 @@ void CNetFolder::Init(const NWindows::NNet::CResourceW *netResource,
_netResourcePointer = &_netResource;
// if (_netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER)
- _path = _netResource.RemoteName + WCHAR_PATH_SEPARATOR;
+ _path = _netResource.RemoteName;
+
+ /* WinXP-64: When we move UP from Network share without _parentFolder chain,
+ we can get empty _netResource.RemoteName. Do we need to use Provider there ? */
+ if (_path.IsEmpty())
+ _path = _netResource.Provider;
+
+ if (!_path.IsEmpty())
+ _path.Add_PathSepar();
}
_parentFolder = parentFolder;
}
@@ -111,7 +119,7 @@ STDMETHODIMP CNetFolder::LoadItems()
if (!resource.RemoteNameIsDefined) // For Win 98, I don't know what's wrong
resource.RemoteName = resource.Comment;
resource.Name = resource.RemoteName;
- int pos = resource.Name.ReverseFind(WCHAR_PATH_SEPARATOR);
+ int pos = resource.Name.ReverseFind_PathSepar();
if (pos >= 0)
{
// _path = resource.Name.Left(pos + 1);
@@ -186,7 +194,7 @@ STDMETHODIMP CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder
{
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
- RINOK(fsFolderSpec->Init(us2fs(resource.RemoteName + WCHAR_PATH_SEPARATOR), this));
+ RINOK(fsFolderSpec->Init(us2fs(resource.RemoteName + WCHAR_PATH_SEPARATOR))); // , this
*resultFolder = subFolder.Detach();
}
else
@@ -237,7 +245,7 @@ STDMETHODIMP CNetFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
- case kpidType: prop = L"NetFolder"; break;
+ case kpidType: prop = "NetFolder"; break;
case kpidPath: prop = _path; break;
}
prop.Detach(value);
diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
index a657bc90..c6feb902 100644
--- a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
+++ b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
@@ -50,7 +50,7 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
sizeString = MyFormatNew(IDS_FILE_SIZE, NumberToString(fileInfo.Size));
const UString &fileName = fileInfo.Name;
- int slashPos = fileName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ int slashPos = fileName.ReverseFind_PathSepar();
UString s1 = fileName.Left(slashPos + 1);
UString s2 = fileName.Ptr(slashPos + 1);
@@ -58,18 +58,18 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
ReduceString(s2);
UString s = s1;
- s += L'\n';
+ s.Add_LF();
s += s2;
- s += L'\n';
+ s.Add_LF();
s += sizeString;
- s += L'\n';
+ s.Add_LF();
if (fileInfo.TimeIsDefined)
{
FILETIME localFileTime;
if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime))
throw 4190402;
- s += LangString(IDS_PROP_MTIME);
+ AddLangString(s, IDS_PROP_MTIME);
s += L": ";
wchar_t t[32];
ConvertFileTimeToString(localFileTime, t);
diff --git a/CPP/7zip/UI/FileManager/Panel.cpp b/CPP/7zip/UI/FileManager/Panel.cpp
index d63bdc17..a7416a4c 100644
--- a/CPP/7zip/UI/FileManager/Panel.cpp
+++ b/CPP/7zip/UI/FileManager/Panel.cpp
@@ -477,7 +477,7 @@ bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */)
_comboBoxEdit.SetUserDataLongPtr(LONG_PTR(&_comboBoxEdit));
_comboBoxEdit._panel = this;
#ifndef _UNICODE
- if(g_IsNT)
+ if (g_IsNT)
_comboBoxEdit._origWindowProc =
(WNDPROC)_comboBoxEdit.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc));
else
@@ -675,7 +675,7 @@ void CPanel::MessageBoxError2Lines(LPCWSTR message, HRESULT errorCode)
UString m = message;
if (errorCode != 0)
{
- m += L'\n';
+ m.Add_LF();
m += HResultToMessage(errorCode);
}
MessageBoxMyError(m);
@@ -708,29 +708,32 @@ void CPanel::SetFocusToLastRememberedItem()
UString CPanel::GetFolderTypeID() const
{
- NCOM::CPropVariant prop;
- if (_folder->GetFolderProperty(kpidType, &prop) == S_OK)
- if (prop.vt == VT_BSTR)
- return (const wchar_t *)prop.bstrVal;
- return L"";
+ {
+ NCOM::CPropVariant prop;
+ if (_folder->GetFolderProperty(kpidType, &prop) == S_OK)
+ if (prop.vt == VT_BSTR)
+ return (const wchar_t *)prop.bstrVal;
+ }
+ return UString();
}
-bool CPanel::IsFolderTypeEqTo(const wchar_t *s) const
+bool CPanel::IsFolderTypeEqTo(const char *s) const
{
- return GetFolderTypeID() == s;
+ return StringsAreEqual_Ascii(GetFolderTypeID(), s);
}
-bool CPanel::IsRootFolder() const { return IsFolderTypeEqTo(L"RootFolder"); }
-bool CPanel::IsFSFolder() const { return IsFolderTypeEqTo(L"FSFolder"); }
-bool CPanel::IsFSDrivesFolder() const { return IsFolderTypeEqTo(L"FSDrives"); }
+bool CPanel::IsRootFolder() const { return IsFolderTypeEqTo("RootFolder"); }
+bool CPanel::IsFSFolder() const { return IsFolderTypeEqTo("FSFolder"); }
+bool CPanel::IsFSDrivesFolder() const { return IsFolderTypeEqTo("FSDrives"); }
+bool CPanel::IsAltStreamsFolder() const { return IsFolderTypeEqTo("AltStreamsFolder"); }
bool CPanel::IsArcFolder() const
{
- return GetFolderTypeID().IsPrefixedBy(L"7-Zip");
+ return GetFolderTypeID().IsPrefixedBy_Ascii_NoCase("7-Zip");
}
UString CPanel::GetFsPath() const
{
- if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix())
+ if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix() && !IsSuperDrivesPrefix())
return UString();
return _currentFolderPrefix;
}
@@ -744,12 +747,6 @@ UString CPanel::GetDriveOrNetworkPrefix() const
return drive;
}
-bool CPanel::DoesItSupportOperations() const
-{
- CMyComPtr<IFolderOperations> folderOperations;
- return _folder.QueryInterface(IID_IFolderOperations, &folderOperations) == S_OK;
-}
-
void CPanel::SetListViewMode(UInt32 index)
{
if (index >= 4)
@@ -805,7 +802,7 @@ void CPanel::AddToArchive()
{
CRecordVector<UInt32> indices;
GetOperatedItemIndices(indices);
- if (!IsFsOrDrivesFolder())
+ if (!Is_IO_FS_Folder())
{
MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
return;
@@ -817,20 +814,16 @@ void CPanel::AddToArchive()
}
UStringVector names;
- UString curPrefix = _currentFolderPrefix;
- UString destCurDirPrefix = _currentFolderPrefix;
+ const UString curPrefix = GetFsPath();
+ UString destCurDirPrefix = curPrefix;
if (IsFSDrivesFolder())
- {
destCurDirPrefix = ROOT_FS_FOLDER;
- if (!IsDeviceDrivesPrefix())
- curPrefix.Empty();
- }
FOR_VECTOR (i, indices)
- names.Add(curPrefix + GetItemRelPath(indices[i]));
+ names.Add(curPrefix + GetItemRelPath2(indices[i]));
bool fromPrev = (names.Size() > 1);
- const UString archiveName = CreateArchiveName(names.Front(), fromPrev, false);
- HRESULT res = CompressFiles(destCurDirPrefix, archiveName, L"",
+ const UString arcName = CreateArchiveName(names.Front(), fromPrev, false);
+ HRESULT res = CompressFiles(destCurDirPrefix, arcName, L"",
true, // addExtension
names, false, true, false);
if (res != S_OK)
@@ -841,23 +834,24 @@ void CPanel::AddToArchive()
// KillSelection();
}
-static UString GetSubFolderNameForExtract(const UString &archiveName)
+static UString GetSubFolderNameForExtract(const UString &arcPath)
{
- UString res = archiveName;
- int slashPos = res.ReverseFind(WCHAR_PATH_SEPARATOR);
- int dotPos = res.ReverseFind(L'.');
- if (dotPos < 0 || slashPos > dotPos)
- res += L'~';
+ UString s = arcPath;
+ int slashPos = s.ReverseFind_PathSepar();
+ int dotPos = s.ReverseFind_Dot();
+ if (dotPos <= slashPos + 1)
+ s += L'~';
else
{
- res.DeleteFrom(dotPos);
- res.TrimRight();
+ s.DeleteFrom(dotPos);
+ s.TrimRight();
}
- return res;
+ return s;
}
void CPanel::GetFilePaths(const CRecordVector<UInt32> &indices, UStringVector &paths, bool allowFolders)
{
+ const UString prefix = GetFsPath();
FOR_VECTOR (i, indices)
{
int index = indices[i];
@@ -866,7 +860,7 @@ void CPanel::GetFilePaths(const CRecordVector<UInt32> &indices, UStringVector &p
paths.Clear();
break;
}
- paths.Add(GetItemFullPath(index));
+ paths.Add(prefix + GetItemRelPath2(index));
}
if (paths.Size() == 0)
{
@@ -888,26 +882,31 @@ void CPanel::ExtractArchives()
GetFilePaths(indices, paths);
if (paths.IsEmpty())
return;
- UString folderName;
+
+ UString outFolder = GetFsPath();
if (indices.Size() == 1)
- folderName = GetSubFolderNameForExtract(GetItemRelPath(indices[0]));
+ outFolder += GetSubFolderNameForExtract(GetItemRelPath(indices[0]));
else
- folderName = L"*";
- ::ExtractArchives(paths, _currentFolderPrefix + folderName + UString(WCHAR_PATH_SEPARATOR)
+ outFolder += L'*';
+ outFolder.Add_PathSepar();
+
+ ::ExtractArchives(paths, outFolder
, true // showDialog
, false // elimDup
);
}
-void AddValuePair(UINT resourceID, UInt64 value, UString &s)
+/*
+static void AddValuePair(UINT resourceID, UInt64 value, UString &s)
{
- wchar_t sz[32];
- s += LangString(resourceID);
+ AddLangString(s, resourceID);
+ char sz[32];
s += L": ";
ConvertUInt64ToString(value, sz);
- s += sz;
- s += L'\n';
+ s.AddAsciiStr(sz);
+ s.Add_LF();
}
+*/
class CThreadTest: public CProgressThreadVirt
{
@@ -939,8 +938,8 @@ HRESULT CThreadTest::ProcessVirt()
AddValuePair(IDS_PROP_FILES, ExtractCallbackSpec->NumFiles, s);
// AddValuePair(IDS_PROP_SIZE, ExtractCallbackSpec->UnpackSize, s);
// AddSizePair(IDS_COMPRESSED_COLON, Stat.PackSize, s);
- s += L'\n';
- s += LangString(IDS_MESSAGE_NO_ERRORS);
+ s.Add_LF();
+ AddLangString(s, IDS_MESSAGE_NO_ERRORS);
FinalMessage.OkMessage.Message = s;
}
return S_OK;
@@ -948,18 +947,18 @@ HRESULT CThreadTest::ProcessVirt()
*/
/*
-static void AddSizePair(UINT resourceID, UInt32 langID, UInt64 value, UString &s)
+static void AddSizePair(UInt32 langID, UInt64 value, UString &s)
{
- wchar_t sz[32];
- s += LangString(resourceID, langID);
+ char sz[32];
+ AddLangString(s, langID);
s += L' ';
ConvertUInt64ToString(value, sz);
- s += sz;
+ s.AddAsciiStr(sz);
ConvertUInt64ToString(value >> 20, sz);
- s += L" (";
- s += sz;
- s += L" MB)";
- s += L'\n';
+ s.AddAsciiStr(" (");
+ s.AddAsciiStr(sz);
+ s.AddAsciiStr(" MB)");
+ s.Add_LF();
}
*/
diff --git a/CPP/7zip/UI/FileManager/Panel.h b/CPP/7zip/UI/FileManager/Panel.h
index dc293729..39915a27 100644
--- a/CPP/7zip/UI/FileManager/Panel.h
+++ b/CPP/7zip/UI/FileManager/Panel.h
@@ -11,6 +11,7 @@
#include "../../../Windows/DLL.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileFind.h"
+#include "../../../Windows/FileName.h"
#include "../../../Windows/Handle.h"
#include "../../../Windows/Synchronization.h"
@@ -43,10 +44,10 @@ const int kParentFolderID = 100;
const int kParentIndex = -1;
-#ifdef UNDER_CE
+#if !defined(_WIN32) || defined(UNDER_CE)
#define ROOT_FS_FOLDER L"\\"
#else
-#define ROOT_FS_FOLDER L"C:\\\\"
+#define ROOT_FS_FOLDER L"C:\\"
#endif
struct CPanelCallback
@@ -117,12 +118,13 @@ struct CTempFileInfo
struct CFolderLink: public CTempFileInfo
{
NWindows::NDLL::CLibrary Library;
- CMyComPtr<IFolderFolder> ParentFolder;
+ CMyComPtr<IFolderFolder> ParentFolder; // can be NULL, if parent is FS folder (in _parentFolders[0])
+ UString ParentFolderPath; // including tail slash (doesn't include paths parts of parent in next level)
bool UsePassword;
UString Password;
bool IsVirtual;
- UString VirtualPath;
+ UString VirtualPath; // without tail slash
CFolderLink(): UsePassword(false), IsVirtual(false) {}
bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const
@@ -146,7 +148,7 @@ enum MyMessages
#endif
};
-UString GetFolderPath(IFolderFolder * folder);
+UString GetFolderPath(IFolderFolder *folder);
class CPanel;
@@ -380,27 +382,11 @@ public:
CMyComPtr<IFolderCompare> _folderCompare;
CMyComPtr<IFolderGetItemName> _folderGetItemName;
CMyComPtr<IArchiveGetRawProps> _folderRawProps;
+ CMyComPtr<IFolderAltStreams> _folderAltStreams;
+ CMyComPtr<IFolderOperations> _folderOperations;
- void ReleaseFolder()
- {
- _folderCompare.Release();
- _folderGetItemName.Release();
- _folderRawProps.Release();
- _folder.Release();
- _thereAreDeletedItems = false;
- }
-
- void SetNewFolder(IFolderFolder *newFolder)
- {
- ReleaseFolder();
- _folder = newFolder;
- if (_folder)
- {
- _folder.QueryInterface(IID_IFolderCompare, &_folderCompare);
- _folder.QueryInterface(IID_IFolderGetItemName, &_folderGetItemName);
- _folder.QueryInterface(IID_IArchiveGetRawProps, &_folderRawProps);
- }
- }
+ void ReleaseFolder();
+ void SetNewFolder(IFolderFolder *newFolder);
// CMyComPtr<IFolderGetSystemIconIndex> _folderGetSystemIconIndex;
@@ -417,9 +403,11 @@ public:
bool IsItem_AltStream(int itemIndex) const;
UString GetItemName(int itemIndex) const;
- void GetItemNameFast(int itemIndex, UString &s) const;
+ UString GetItemName_for_Copy(int itemIndex) const;
+ void GetItemName(int itemIndex, UString &s) const;
UString GetItemPrefix(int itemIndex) const;
UString GetItemRelPath(int itemIndex) const;
+ UString GetItemRelPath2(int itemIndex) const;
UString GetItemFullPath(int itemIndex) const;
UInt64 GetItemSize(int itemIndex) const;
@@ -438,6 +426,7 @@ public:
void LoadFullPathAndShow();
void FoldersHistory();
void OpenParentFolder();
+ void CloseOneLevel();
void CloseOpenFolders();
void OpenRootFolder();
@@ -554,19 +543,65 @@ public:
void KillSelection();
UString GetFolderTypeID() const;
- bool IsFolderTypeEqTo(const wchar_t *s) const;
+
+ bool IsFolderTypeEqTo(const char *s) const;
bool IsRootFolder() const;
bool IsFSFolder() const;
bool IsFSDrivesFolder() const;
+ bool IsAltStreamsFolder() const;
bool IsArcFolder() const;
- bool IsFsOrDrivesFolder() const { return IsFSFolder() || IsFSDrivesFolder(); }
+
+ /*
+ c:\Dir
+ Computer\
+ \\?\
+ \\.\
+ */
+ bool Is_IO_FS_Folder() const
+ {
+ return IsFSFolder() || IsFSDrivesFolder() || IsAltStreamsFolder();
+ }
+
+ bool Is_Slow_Icon_Folder() const
+ {
+ return IsFSFolder() || IsAltStreamsFolder();
+ }
+
+ // bool IsFsOrDrivesFolder() const { return IsFSFolder() || IsFSDrivesFolder(); }
bool IsDeviceDrivesPrefix() const { return _currentFolderPrefix == L"\\\\.\\"; }
+ bool IsSuperDrivesPrefix() const { return _currentFolderPrefix == L"\\\\?\\"; }
+
+ /*
+ c:\Dir
+ Computer\
+ \\?\
+ */
bool IsFsOrPureDrivesFolder() const { return IsFSFolder() || (IsFSDrivesFolder() && !IsDeviceDrivesPrefix()); }
+ /*
+ c:\Dir
+ Computer\
+ \\?\
+ \\SERVER\
+ */
+ bool IsFolder_with_FsItems() const
+ {
+ if (IsFsOrPureDrivesFolder())
+ return true;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ FString prefix = us2fs(GetFsPath());
+ return (prefix.Len() == NWindows::NFile::NName::GetNetworkServerPrefixSize(prefix));
+ #else
+ return false;
+ #endif
+ }
+
UString GetFsPath() const;
UString GetDriveOrNetworkPrefix() const;
- bool DoesItSupportOperations() const;
+ bool DoesItSupportOperations() const { return _folderOperations != NULL; }
+ bool IsThereReadOnlyFolder() const;
+ bool CheckBeforeUpdate(UINT resourceID);
bool _processTimer;
bool _processNotify;
@@ -574,37 +609,35 @@ public:
class CDisableTimerProcessing
{
- bool _processTimerMem;
-
- CPanel &_panel;
+ CLASS_NO_COPY(CDisableTimerProcessing);
- CDisableTimerProcessing(const CDisableTimerProcessing &);
- CDisableTimerProcessing& operator=(const CDisableTimerProcessing &);
+ bool _processTimer;
+ CPanel &_panel;
+
public:
CDisableTimerProcessing(CPanel &panel): _panel(panel) { Disable(); }
~CDisableTimerProcessing() { Restore(); }
void Disable()
{
- _processTimerMem = _panel._processTimer;
+ _processTimer = _panel._processTimer;
_panel._processTimer = false;
}
void Restore()
{
- _panel._processTimer = _processTimerMem;
+ _panel._processTimer = _processTimer;
}
};
class CDisableNotify
{
- bool _processNotifyMem;
- bool _processStatusBarMem;
+ CLASS_NO_COPY(CDisableNotify);
- CPanel &_panel;
+ bool _processNotify;
+ bool _processStatusBar;
- CDisableNotify(const CDisableNotify &);
- CDisableNotify& operator=(const CDisableNotify &);
+ CPanel &_panel;
public:
@@ -612,20 +645,20 @@ public:
~CDisableNotify() { Restore(); }
void Disable()
{
- _processNotifyMem = _panel._processNotify;
- _processStatusBarMem = _panel._processStatusBar;
+ _processNotify = _panel._processNotify;
+ _processStatusBar = _panel._processStatusBar;
_panel._processNotify = false;
_panel._processStatusBar = false;
}
void SetMemMode_Enable()
{
- _processNotifyMem = true;
- _processStatusBarMem = true;
+ _processNotify = true;
+ _processStatusBar = true;
}
void Restore()
{
- _panel._processNotify = _processNotifyMem;
- _panel._processStatusBar = _processStatusBarMem;
+ _panel._processNotify = _processNotify;
+ _panel._processStatusBar = _processStatusBar;
}
};
@@ -647,10 +680,12 @@ public:
void MessageBoxLastError(LPCWSTR caption);
void MessageBoxLastError();
- void MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID);
+ // void MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID);
void MessageBoxErrorLang(UINT resourceID);
+ void OpenAltStreams();
+
void OpenFocusedItemAsInternal();
void OpenSelectedItems(bool internal);
diff --git a/CPP/7zip/UI/FileManager/PanelCopy.cpp b/CPP/7zip/UI/FileManager/PanelCopy.cpp
index d11368cf..fb418963 100644
--- a/CPP/7zip/UI/FileManager/PanelCopy.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCopy.cpp
@@ -1,4 +1,4 @@
-/// PanelExtract.cpp
+/// PanelCopy.cpp
#include "StdAfx.h"
@@ -79,18 +79,25 @@ HRESULT CPanelCopyThread::ProcessVirt()
return Result;
}
+
+/*
+#ifdef EXTERNAL_CODECS
+
static void ThrowException_if_Error(HRESULT res)
{
if (res != S_OK)
throw CSystemException(res);
}
+#endif
+*/
+
+
HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &indices,
UStringVector *messages,
bool &usePassword, UString &password)
{
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ if (!_folderOperations)
{
UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED);
if (options.showErrorMessages)
@@ -100,8 +107,17 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
return E_FAIL;
}
- HRESULT res;
+ HRESULT res = S_OK;
+
{
+ /*
+ #ifdef EXTERNAL_CODECS
+ CExternalCodecs g_ExternalCodecs;
+ #endif
+ */
+ /* extracter.Hash uses g_ExternalCodecs
+ extracter must be declared after g_ExternalCodecs for correct destructor order !!! */
+
CPanelCopyThread extracter;
extracter.ExtractCallbackSpec = new CExtractCallbackImp;
@@ -113,11 +129,6 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
extracter.ExtractCallbackSpec->StreamMode = options.streamMode;
- #ifdef EXTERNAL_CODECS
- CExternalCodecs __externalCodecs;
- #else
- CMyComPtr<IUnknown> compressCodecsInfo;
- #endif
if (indices.Size() == 1)
extracter.FirstFilePath = GetItemRelPath(indices[0]);
@@ -131,19 +142,16 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
if (!options.hashMethods.IsEmpty())
{
- {
- CCodecs *codecs = new CCodecs;
- ThrowException_if_Error(codecs->Load());
- #ifdef EXTERNAL_CODECS
- __externalCodecs.GetCodecs = codecs;
- __externalCodecs.GetHashers = codecs;
- ThrowException_if_Error(__externalCodecs.LoadCodecs());
- #else
- compressCodecsInfo = codecs;
- #endif
- }
+ /* this code is used when we call CRC calculation for files in side archive
+ But new code uses global codecs so we don't need to call LoadGlobalCodecs again */
+
+ /*
+ #ifdef EXTERNAL_CODECS
+ ThrowException_if_Error(LoadGlobalCodecs());
+ #endif
+ */
- extracter.Hash.SetMethods(EXTERNAL_CODECS_VARS options.hashMethods);
+ extracter.Hash.SetMethods(EXTERNAL_CODECS_VARS_G options.hashMethods);
extracter.ExtractCallbackSpec->SetHashMethods(&extracter.Hash);
}
else if (options.testMode)
@@ -153,7 +161,6 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
extracter.Hash.Init();
-
UString title;
{
UInt32 titleID = IDS_COPYING;
@@ -185,7 +192,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAsk;
extracter.ExtractCallbackSpec->Init();
extracter.Indices = indices;
- extracter.FolderOperations = folderOperations;
+ extracter.FolderOperations = _folderOperations;
extracter.ExtractCallbackSpec->PasswordIsDefined = usePassword;
extracter.ExtractCallbackSpec->Password = password;
@@ -244,10 +251,8 @@ struct CThreadUpdate
HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStringVector &filePaths,
bool showErrorMessages, UStringVector *messages)
{
- CMyComPtr<IFolderOperations> folderOperations;
- _folder.QueryInterface(IID_IFolderOperations, &folderOperations);
HRESULT res;
- if (!folderOperations)
+ if (!_folderOperations)
res = E_NOINTERFACE;
else
{
@@ -255,6 +260,7 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
updater.MoveMode = moveMode;
updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
updater.UpdateCallback = updater.UpdateCallbackSpec;
+ updater.UpdateCallbackSpec->Init();
updater.UpdateCallbackSpec->ProgressDialog = &updater.ProgressDialog;
@@ -263,10 +269,18 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
updater.ProgressDialog.MainWindow = GetParent();
updater.ProgressDialog.MainTitle = progressWindowTitle;
- updater.ProgressDialog.MainAddTitle = title + UString(L' ');
+ updater.ProgressDialog.MainAddTitle = title + L' ';
- updater.UpdateCallbackSpec->Init(false, L"");
- updater.FolderOperations = folderOperations;
+ {
+ if (!_parentFolders.IsEmpty())
+ {
+ const CFolderLink &fl = _parentFolders.Back();
+ updater.UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword;
+ updater.UpdateCallbackSpec->Password = fl.Password;
+ }
+ }
+
+ updater.FolderOperations = _folderOperations;
updater.FolderPrefix = folderPrefix;
updater.FileNames.ClearAndReserve(filePaths.Size());
unsigned i;
diff --git a/CPP/7zip/UI/FileManager/PanelCrc.cpp b/CPP/7zip/UI/FileManager/PanelCrc.cpp
index ab93ecba..3b0ee052 100644
--- a/CPP/7zip/UI/FileManager/PanelCrc.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCrc.cpp
@@ -6,6 +6,7 @@
#include "../../../Windows/FileFind.h"
#include "../../../Windows/FileIO.h"
+#include "../../../Windows/FileName.h"
#include "../Common/LoadCodecs.h"
@@ -19,12 +20,18 @@
using namespace NWindows;
using namespace NFile;
+#ifdef EXTERNAL_CODECS
+extern CExternalCodecs g_ExternalCodecs;
+HRESULT LoadGlobalCodecs();
+#endif
+
static const UInt32 kBufSize = (1 << 15);
struct CDirEnumerator
{
bool EnterToDirs;
FString BasePrefix;
+ FString BasePrefix_for_Open;
FStringVector FilePaths;
CObjectVector<NFind::CEnumerator> Enumerators;
@@ -54,22 +61,27 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
{
filled = false;
resPath.Empty();
+
for (;;)
{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ bool isRootPrefix = (BasePrefix.IsEmpty() || (NName::IsSuperPath(BasePrefix) && BasePrefix[NName::kSuperPathPrefixSize] == 0));
+ #endif
+
if (Enumerators.IsEmpty())
{
if (Index >= FilePaths.Size())
return S_OK;
const FString &path = FilePaths[Index++];
- int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
+ int pos = path.ReverseFind_PathSepar();
if (pos >= 0)
resPath.SetFrom(path, pos + 1);
- #ifdef _WIN32
- if (BasePrefix.IsEmpty() && path.Len() == 2 && path[1] == ':')
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (isRootPrefix && path.Len() == 2 && NName::IsDrivePath2(path))
{
// we use "c:" item as directory item
- fi.Clear();
+ fi.ClearBase();
fi.Name = path;
fi.SetAsDir();
fi.Size = 0;
@@ -82,9 +94,12 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
resPath = path;
return error;
}
+
break;
}
+
bool found;
+
if (Enumerators.Back().Next(fi, found))
{
if (found)
@@ -101,18 +116,22 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
Prefixes.DeleteBack();
return error;
}
+
Enumerators.DeleteBack();
Prefixes.DeleteBack();
}
+
resPath += fi.Name;
+
if (EnterToDirs && fi.IsDir())
{
FString s = resPath;
- s += FCHAR_PATH_SEPARATOR;
+ s.Add_PathSepar();
Prefixes.Add(s);
s += FCHAR_ANY_MASK;
Enumerators.Add(NFind::CEnumerator(BasePrefix + s));
}
+
filled = true;
return S_OK;
}
@@ -137,10 +156,9 @@ void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name)
void CThreadCrc::SetStatus(const UString &s2)
{
UString s = s2;
- if (Enumerator.BasePrefix)
+ if (!Enumerator.BasePrefix.IsEmpty())
{
- if (!s.IsEmpty())
- s += L' ';
+ s.Add_Space_if_NotEmpty();
s += fs2us(Enumerator.BasePrefix);
}
ProgressDialog.Sync.Set_Status(s);
@@ -201,10 +219,10 @@ HRESULT CThreadCrc::ProcessVirt()
*/
if (needPrint)
{
- RINOK(sync.ScanProgress(numFiles, totalSize, fs2us(path), fi.IsDir()));
+ RINOK(sync.ScanProgress(numFiles, totalSize, path, fi.IsDir()));
}
}
- RINOK(sync.ScanProgress(numFiles, totalSize, L"", false));
+ RINOK(sync.ScanProgress(numFiles, totalSize, FString(), false));
// sync.SetNumFilesTotal(numFiles);
// sync.SetProgress(totalSize, 0);
// SetStatus(LangString(IDS_CHECKSUM_CALCULATING));
@@ -235,7 +253,7 @@ HRESULT CThreadCrc::ProcessVirt()
if (!fi.IsDir())
{
NIO::CInFile inFile;
- tempPath = Enumerator.BasePrefix;
+ tempPath = Enumerator.BasePrefix_for_Open;
tempPath += path;
if (!inFile.Open(tempPath))
{
@@ -289,13 +307,8 @@ HRESULT CThreadCrc::ProcessVirt()
return S_OK;
}
-static void ThrowException_if_Error(HRESULT res)
-{
- if (res != S_OK)
- throw CSystemException(res);
-}
-void CApp::CalculateCrc(const UString &methodName)
+HRESULT CApp::CalculateCrc2(const UString &methodName)
{
int srcPanelIndex = GetFocusedPanelIndex();
CPanel &srcPanel = Panels[srcPanelIndex];
@@ -303,9 +316,9 @@ void CApp::CalculateCrc(const UString &methodName)
CRecordVector<UInt32> indices;
srcPanel.GetOperatedIndicesSmart(indices);
if (indices.IsEmpty())
- return;
+ return S_OK;
- if (!srcPanel.IsFsOrDrivesFolder())
+ if (!srcPanel.Is_IO_FS_Folder())
{
CCopyToOptions options;
options.streamMode = true;
@@ -313,27 +326,13 @@ void CApp::CalculateCrc(const UString &methodName)
options.hashMethods.Add(methodName);
UStringVector messages;
- HRESULT res = srcPanel.CopyTo(options, indices, &messages);
- if (res != S_OK)
- {
- if (res != E_ABORT)
- srcPanel.MessageBoxError(res);
- }
- return;
+ return srcPanel.CopyTo(options, indices, &messages);
}
- CCodecs *codecs = new CCodecs;
#ifdef EXTERNAL_CODECS
- CExternalCodecs __externalCodecs;
- __externalCodecs.GetCodecs = codecs;
- __externalCodecs.GetHashers = codecs;
- #else
- CMyComPtr<IUnknown> compressCodecsInfo = codecs;
- #endif
- ThrowException_if_Error(codecs->Load());
- #ifdef EXTERNAL_CODECS
- ThrowException_if_Error(__externalCodecs.LoadCodecs());
+ LoadGlobalCodecs();
+
#endif
{
@@ -341,11 +340,23 @@ void CApp::CalculateCrc(const UString &methodName)
{
UStringVector methods;
methods.Add(methodName);
- t.Hash.SetMethods(EXTERNAL_CODECS_VARS methods);
+ RINOK(t.Hash.SetMethods(EXTERNAL_CODECS_VARS_G methods));
}
FOR_VECTOR (i, indices)
t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i])));
- t.Enumerator.BasePrefix = us2fs(srcPanel.GetFsPath());
+
+ UString basePrefix = srcPanel.GetFsPath();
+ UString basePrefix2 = basePrefix;
+ if (basePrefix2.Back() == ':')
+ {
+ int pos = basePrefix2.ReverseFind_PathSepar();
+ if (pos >= 0)
+ basePrefix2.DeleteFrom(pos + 1);
+ }
+
+ t.Enumerator.BasePrefix = us2fs(basePrefix);
+ t.Enumerator.BasePrefix_for_Open = us2fs(basePrefix2);
+
t.Enumerator.EnterToDirs = !GetFlatMode();
t.ProgressDialog.ShowCompressionInfo = false;
@@ -354,10 +365,22 @@ void CApp::CalculateCrc(const UString &methodName)
t.ProgressDialog.MainWindow = _window;
t.ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
- t.ProgressDialog.MainAddTitle = title + UString(L' ');
+ t.ProgressDialog.MainAddTitle = title;
+ t.ProgressDialog.MainAddTitle.Add_Space();
- if (t.Create(title, _window) != S_OK)
- return;
+ RINOK(t.Create(title, _window));
}
RefreshTitleAlways();
+ return S_OK;
+}
+
+void CApp::CalculateCrc(const UString &methodName)
+{
+ HRESULT res = CalculateCrc2(methodName);
+ if (res != S_OK && res != E_ABORT)
+ {
+ int srcPanelIndex = GetFocusedPanelIndex();
+ CPanel &srcPanel = Panels[srcPanelIndex];
+ srcPanel.MessageBoxError(res);
+ }
}
diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp
index 9434d156..e20ddd63 100644
--- a/CPP/7zip/UI/FileManager/PanelDrag.cpp
+++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp
@@ -296,9 +296,11 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na
void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
{
- CDisableTimerProcessing disableTimerProcessing2(*this);
if (!DoesItSupportOperations())
return;
+
+ CDisableTimerProcessing disableTimerProcessing2(*this);
+
CRecordVector<UInt32> indices;
GetOperatedItemIndices(indices);
if (indices.Size() == 0)
@@ -312,7 +314,7 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
bool isFSFolder = IsFSFolder();
if (isFSFolder)
- dirPrefix = us2fs(_currentFolderPrefix);
+ dirPrefix = us2fs(GetFsPath());
else
{
tempDirectory.Create(kTempDirPrefix);
@@ -580,7 +582,9 @@ bool CDropTarget::IsItSameDrive() const
return false;
if (!IsFsFolderPath())
return false;
+
UString drive;
+
if (m_Panel->IsFSFolder())
{
drive = m_Panel->GetDriveOrNetworkPrefix();
@@ -594,13 +598,14 @@ bool CDropTarget::IsItSameDrive() const
if (m_SourcePaths.Size() == 0)
return false;
+
FOR_VECTOR (i, m_SourcePaths)
{
- if (MyStringCompareNoCase_N(m_SourcePaths[i], drive, drive.Len()) != 0)
+ if (!m_SourcePaths[i].IsPrefixedBy_NoCase(drive))
return false;
}
+
return true;
-
}
DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect)
@@ -635,13 +640,11 @@ UString CDropTarget::GetTargetPath() const
{
if (!IsFsFolderPath())
return UString();
- UString path = m_Panel->_currentFolderPrefix;
- if (m_Panel->IsFSDrivesFolder())
- path.Empty();
+ UString path = m_Panel->GetFsPath();
if (m_SubFolderIndex >= 0 && !m_SubFolderName.IsEmpty())
{
path += m_SubFolderName;
- path += WCHAR_PATH_SEPARATOR;
+ path.Add_PathSepar();
}
return path;
}
@@ -728,7 +731,7 @@ STDMETHODIMP CDropTarget::Drop(IDataObject *dataObject, DWORD keyState,
UString path = GetTargetPath();
if (m_IsAppTarget && m_Panel)
if (m_Panel->IsFSFolder())
- path = m_Panel->_currentFolderPrefix;
+ path = m_Panel->GetFsPath();
m_Panel->DropObject(dataObject, path);
}
}
@@ -779,7 +782,7 @@ static bool AreThereNamesFromTemp(const UStringVector &fileNames)
if (tempPath.IsEmpty())
return false;
FOR_VECTOR (i, fileNames)
- if (MyStringCompareNoCase_N(fileNames[i], tempPath, tempPath.Len()) == 0)
+ if (fileNames[i].IsPrefixedBy_NoCase(tempPath))
return true;
return false;
}
diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
index 83993bb1..cd70c727 100644
--- a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
+++ b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
@@ -28,10 +28,38 @@ using namespace NWindows;
using namespace NFile;
using namespace NFind;
+void CPanel::ReleaseFolder()
+{
+ _folder.Release();
+
+ _folderCompare.Release();
+ _folderGetItemName.Release();
+ _folderRawProps.Release();
+ _folderAltStreams.Release();
+ _folderOperations.Release();
+
+ _thereAreDeletedItems = false;
+}
+
+void CPanel::SetNewFolder(IFolderFolder *newFolder)
+{
+ ReleaseFolder();
+ _folder = newFolder;
+ if (_folder)
+ {
+ _folder.QueryInterface(IID_IFolderCompare, &_folderCompare);
+ _folder.QueryInterface(IID_IFolderGetItemName, &_folderGetItemName);
+ _folder.QueryInterface(IID_IArchiveGetRawProps, &_folderRawProps);
+ _folder.QueryInterface(IID_IFolderAltStreams, &_folderAltStreams);
+ _folder.QueryInterface(IID_IFolderOperations, &_folderOperations);
+ }
+}
+
void CPanel::SetToRootFolder()
{
ReleaseFolder();
_library.Free();
+
CRootFolder *rootFolderSpec = new CRootFolder;
SetNewFolder(rootFolderSpec);
rootFolderSpec->Init();
@@ -39,105 +67,188 @@ void CPanel::SetToRootFolder()
HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted)
{
+ UString path = fullPath;
+ #ifdef _WIN32
+ path.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ #endif
+
archiveIsOpened = false;
encrypted = false;
+
CDisableTimerProcessing disableTimerProcessing(*this);
CDisableNotify disableNotify(*this);
- if (_parentFolders.Size() > 0)
+ for (; !_parentFolders.IsEmpty(); CloseOneLevel())
{
- const UString &virtPath = _parentFolders.Back().VirtualPath;
- if (fullPath.IsPrefixedBy(virtPath))
+ // ---------- we try to use open archive ----------
+
+ const CFolderLink &link = _parentFolders.Back();
+ const UString &virtPath = link.VirtualPath;
+ if (!path.IsPrefixedBy(virtPath))
+ continue;
+ UString relatPath = path.Ptr(virtPath.Len());
+ if (!relatPath.IsEmpty())
{
- for (;;)
- {
- CMyComPtr<IFolderFolder> newFolder;
- HRESULT res = _folder->BindToParentFolder(&newFolder);
- if (!newFolder || res != S_OK)
- break;
- SetNewFolder(newFolder);
- }
- UStringVector parts;
- SplitPathToParts(fullPath.Ptr(virtPath.Len()), parts);
- FOR_VECTOR (i, parts)
+ if (!IS_PATH_SEPAR(relatPath[0]))
+ continue;
+ else
+ relatPath.Delete(0);
+ }
+
+ UString relatPath2 = relatPath;
+ if (!relatPath2.IsEmpty() && !IS_PATH_SEPAR(relatPath2.Back()))
+ relatPath2.Add_PathSepar();
+
+ for (;;)
+ {
+ const UString foldPath = GetFolderPath(_folder);
+ if (relatPath2 == foldPath)
+ break;
+ if (relatPath.IsPrefixedBy(foldPath))
{
- const UString &s = parts[i];
- if ((i == 0 || i == parts.Size() - 1) && s.IsEmpty())
- continue;
- CMyComPtr<IFolderFolder> newFolder;
- HRESULT res = _folder->BindToFolder(s, &newFolder);
- if (!newFolder || res != S_OK)
- break;
- SetNewFolder(newFolder);
+ path = relatPath.Ptr(foldPath.Len());
+ break;
}
- return S_OK;
+ CMyComPtr<IFolderFolder> newFolder;
+ if (_folder->BindToParentFolder(&newFolder) != S_OK)
+ throw 20140918;
+ if (!newFolder) // we exit from loop above if (relatPath.IsPrefixedBy(empty path for root folder)
+ throw 20140918;
+ SetNewFolder(newFolder);
}
+ break;
}
- CloseOpenFolders();
- UString sysPath = fullPath;
- CFileInfo fileInfo;
- UStringVector reducedParts;
- while (!sysPath.IsEmpty())
+ if (_parentFolders.IsEmpty())
{
- if (fileInfo.Find(us2fs(sysPath)))
- break;
- int pos = sysPath.ReverseFind(WCHAR_PATH_SEPARATOR);
- if (pos < 0)
+ // ---------- we open file or folder from file system ----------
+
+ CloseOpenFolders();
+ UString sysPath = path;
+
+ unsigned prefixSize = NName::GetRootPrefixSize(sysPath);
+ if (prefixSize == 0 || sysPath[prefixSize] == 0)
sysPath.Empty();
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (!sysPath.IsEmpty() && sysPath.Back() == ':' &&
+ (sysPath.Len() != 2 || !NName::IsDrivePath2(sysPath)))
+ {
+ UString baseFile = sysPath;
+ baseFile.DeleteBack();
+ if (NFind::DoesFileOrDirExist(us2fs(baseFile)))
+ sysPath.Empty();
+ }
+ #endif
+
+ CFileInfo fileInfo;
+
+ while (!sysPath.IsEmpty())
+ {
+ if (fileInfo.Find(us2fs(sysPath)))
+ break;
+ int pos = sysPath.ReverseFind_PathSepar();
+ if (pos < 0)
+ sysPath.Empty();
+ else
+ {
+ /*
+ if (reducedParts.Size() > 0 || pos < (int)sysPath.Len() - 1)
+ reducedParts.Add(sysPath.Ptr(pos + 1));
+ */
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (pos == 2 && NName::IsDrivePath2(sysPath) && sysPath.Len() > 3)
+ pos++;
+ #endif
+
+ sysPath.DeleteFrom(pos);
+ }
+ }
+
+ SetToRootFolder();
+
+ CMyComPtr<IFolderFolder> newFolder;
+
+ if (sysPath.IsEmpty())
+ {
+ _folder->BindToFolder(path, &newFolder);
+ }
+ else if (fileInfo.IsDir())
+ {
+ NName::NormalizeDirPathPrefix(sysPath);
+ _folder->BindToFolder(sysPath, &newFolder);
+ }
else
{
- if (reducedParts.Size() > 0 || pos < (int)sysPath.Len() - 1)
- reducedParts.Add(sysPath.Ptr(pos + 1));
- sysPath.DeleteFrom(pos);
+ FString dirPrefix, fileName;
+ NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
+ HRESULT res;
+ // = OpenItemAsArchive(fs2us(fileName), arcFormat, encrypted);
+ {
+ CTempFileInfo tfi;
+ tfi.RelPath = fs2us(fileName);
+ tfi.FolderPath = dirPrefix;
+ tfi.FilePath = us2fs(sysPath);
+ res = OpenItemAsArchive(NULL, tfi, sysPath, arcFormat, encrypted);
+ }
+
+ if (res == S_FALSE)
+ _folder->BindToFolder(fs2us(dirPrefix), &newFolder);
+ else
+ {
+ RINOK(res);
+ archiveIsOpened = true;
+ _parentFolders.Back().ParentFolderPath = fs2us(dirPrefix);
+ path.DeleteFrontal(sysPath.Len());
+ if (!path.IsEmpty() && IS_PATH_SEPAR(path[0]))
+ path.Delete(0);
+ }
}
- }
- SetToRootFolder();
- CMyComPtr<IFolderFolder> newFolder;
- if (sysPath.IsEmpty())
- {
- if (_folder->BindToFolder(fullPath, &newFolder) == S_OK)
- SetNewFolder(newFolder);
- }
- else if (fileInfo.IsDir())
- {
- NName::NormalizeDirPathPrefix(sysPath);
- if (_folder->BindToFolder(sysPath, &newFolder) == S_OK)
+ if (newFolder)
+ {
SetNewFolder(newFolder);
+ // LoadFullPath();
+ return S_OK;
+ }
}
- else
+
{
- FString dirPrefix, fileName;
- NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
- if (_folder->BindToFolder(fs2us(dirPrefix), &newFolder) == S_OK)
+ // ---------- we open folder remPath in archive and sub archives ----------
+
+ for (unsigned curPos = 0; curPos != path.Len();)
{
- SetNewFolder(newFolder);
- LoadFullPath();
+ UString s = path.Ptr(curPos);
+ int slashPos = NName::FindSepar(s);
+ unsigned skipLen = s.Len();
+ if (slashPos >= 0)
{
- HRESULT res = OpenItemAsArchive(fs2us(fileName), arcFormat, encrypted);
- if (res != S_FALSE)
- {
- RINOK(res);
- }
- /*
- if (res == E_ABORT)
- return res;
- */
- if (res == S_OK)
+ s.DeleteFrom(slashPos);
+ skipLen = slashPos + 1;
+ }
+
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToFolder(s, &newFolder);
+ if (newFolder)
+ curPos += skipLen;
+ else if (_folderAltStreams)
+ {
+ int pos = s.Find(L':');
+ if (pos >= 0)
{
- archiveIsOpened = true;
- for (int i = reducedParts.Size() - 1; i >= 0; i--)
- {
- CMyComPtr<IFolderFolder> newFolder;
- _folder->BindToFolder(reducedParts[i], &newFolder);
- if (!newFolder)
- break;
- SetNewFolder(newFolder);
- }
+ UString baseName = s;
+ baseName.DeleteFrom(pos);
+ if (_folderAltStreams->BindToAltStreams(baseName, &newFolder) == S_OK && newFolder)
+ curPos += pos + 1;
}
}
+
+ if (!newFolder)
+ break;
+
+ SetNewFolder(newFolder);
}
}
+
return S_OK;
}
@@ -163,10 +274,12 @@ void CPanel::OpenBookmark(int index)
UString GetFolderPath(IFolderFolder *folder)
{
- NCOM::CPropVariant prop;
- if (folder->GetFolderProperty(kpidPath, &prop) == S_OK)
- if (prop.vt == VT_BSTR)
- return (wchar_t *)prop.bstrVal;
+ {
+ NCOM::CPropVariant prop;
+ if (folder->GetFolderProperty(kpidPath, &prop) == S_OK)
+ if (prop.vt == VT_BSTR)
+ return (wchar_t *)prop.bstrVal;
+ }
return UString();
}
@@ -176,9 +289,10 @@ void CPanel::LoadFullPath()
FOR_VECTOR (i, _parentFolders)
{
const CFolderLink &folderLink = _parentFolders[i];
- _currentFolderPrefix += GetFolderPath(folderLink.ParentFolder);
+ _currentFolderPrefix += folderLink.ParentFolderPath;
+ // GetFolderPath(folderLink.ParentFolder);
_currentFolderPrefix += folderLink.RelPath;
- _currentFolderPrefix += WCHAR_PATH_SEPARATOR;
+ _currentFolderPrefix.Add_PathSepar();
}
if (_folder)
_currentFolderPrefix += GetFolderPath(_folder);
@@ -364,7 +478,7 @@ bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result)
{
UString name = pathParts[i];
sumPass += name;
- sumPass += WCHAR_PATH_SEPARATOR;
+ sumPass.Add_PathSepar();
CFileInfo info;
DWORD attrib = FILE_ATTRIBUTE_DIRECTORY;
if (info.Find(us2fs(sumPass)))
@@ -496,73 +610,104 @@ void CPanel::FoldersHistory()
void CPanel::OpenParentFolder()
{
LoadFullPath(); // Maybe we don't need it ??
- UString focucedName;
- if (!_currentFolderPrefix.IsEmpty() &&
- _currentFolderPrefix.Back() == WCHAR_PATH_SEPARATOR)
+
+ UString parentFolderPrefix;
+ UString focusedName;
+
+ if (!_currentFolderPrefix.IsEmpty())
{
- focucedName = _currentFolderPrefix;
- focucedName.DeleteBack();
- if (focucedName != L"\\\\.")
+ wchar_t c = _currentFolderPrefix.Back();
+ if (c == WCHAR_PATH_SEPARATOR || c == ':')
{
- int pos = focucedName.ReverseFind(WCHAR_PATH_SEPARATOR);
- if (pos >= 0)
- focucedName.DeleteFrontal(pos + 1);
+ focusedName = _currentFolderPrefix;
+ focusedName.DeleteBack();
+ /*
+ if (c == ':' && !focusedName.IsEmpty() && focusedName.Back() == WCHAR_PATH_SEPARATOR)
+ {
+ focusedName.DeleteBack();
+ }
+ else
+ */
+ if (focusedName != L"\\\\." &&
+ focusedName != L"\\\\?")
+ {
+ int pos = focusedName.ReverseFind_PathSepar();
+ if (pos >= 0)
+ {
+ parentFolderPrefix = focusedName;
+ parentFolderPrefix.DeleteFrom(pos + 1);
+ focusedName.DeleteFrontal(pos + 1);
+ }
+ }
}
}
CDisableTimerProcessing disableTimerProcessing(*this);
CDisableNotify disableNotify(*this);
+
CMyComPtr<IFolderFolder> newFolder;
_folder->BindToParentFolder(&newFolder);
+
+ // newFolder.Release(); // for test
+
if (newFolder)
SetNewFolder(newFolder);
else
{
- if (_parentFolders.IsEmpty())
+ bool needSetFolder = true;
+ if (!_parentFolders.IsEmpty())
{
- SetToRootFolder();
- if (focucedName.IsEmpty())
- focucedName = GetItemName(0);
+ {
+ const CFolderLink &link = _parentFolders.Back();
+ parentFolderPrefix = link.ParentFolderPath;
+ focusedName = link.RelPath;
+ }
+ CloseOneLevel();
+ needSetFolder = (!_folder);
}
- else
+
+ if (needSetFolder)
{
- ReleaseFolder();
- _library.Free();
- CFolderLink &link = _parentFolders.Back();
- SetNewFolder(link.ParentFolder);
- _library.Attach(link.Library.Detach());
- focucedName = link.RelPath;
- if (_parentFolders.Size() > 1)
- OpenParentArchiveFolder();
- _parentFolders.DeleteBack();
- if (_parentFolders.IsEmpty())
- _flatMode = _flatModeForDisk;
+ {
+ bool archiveIsOpened;
+ bool encrypted;
+ BindToPath(parentFolderPrefix, UString(), archiveIsOpened, encrypted);
+ }
}
}
-
+
UStringVector selectedItems;
/*
- if (!focucedName.IsEmpty())
- selectedItems.Add(focucedName);
+ if (!focusedName.IsEmpty())
+ selectedItems.Add(focusedName);
*/
LoadFullPath();
// ::SetCurrentDirectory(::_currentFolderPrefix);
- RefreshListCtrl(focucedName, -1, true, selectedItems);
+ RefreshListCtrl(focusedName, -1, true, selectedItems);
// _listView.EnsureVisible(_listView.GetFocusedItem(), false);
}
-void CPanel::CloseOpenFolders()
+void CPanel::CloseOneLevel()
{
- while (_parentFolders.Size() > 0)
+ ReleaseFolder();
+ _library.Free();
{
- ReleaseFolder();
- _library.Free();
- SetNewFolder(_parentFolders.Back().ParentFolder);
- _library.Attach(_parentFolders.Back().Library.Detach());
- if (_parentFolders.Size() > 1)
- OpenParentArchiveFolder();
- _parentFolders.DeleteBack();
+ CFolderLink &link = _parentFolders.Back();
+ if (link.ParentFolder)
+ SetNewFolder(link.ParentFolder);
+ _library.Attach(link.Library.Detach());
}
+ if (_parentFolders.Size() > 1)
+ OpenParentArchiveFolder();
+ _parentFolders.DeleteBack();
+ if (_parentFolders.IsEmpty())
+ _flatMode = _flatModeForDisk;
+}
+
+void CPanel::CloseOpenFolders()
+{
+ while (!_parentFolders.IsEmpty())
+ CloseOneLevel();
_flatMode = _flatModeForDisk;
ReleaseFolder();
_library.Free();
@@ -618,3 +763,45 @@ void CPanel::OpenFolder(int index)
_listView.SetItemState_Selected(_listView.GetFocusedItem());
_listView.EnsureVisible(_listView.GetFocusedItem(), false);
}
+
+void CPanel::OpenAltStreams()
+{
+ CRecordVector<UInt32> indices;
+ GetOperatedItemIndices(indices);
+ Int32 realIndex = -1;
+ if (indices.Size() > 1)
+ return;
+ if (indices.Size() == 1)
+ realIndex = indices[0];
+
+ if (_folderAltStreams)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ _folderAltStreams->BindToAltStreams(realIndex, &newFolder);
+ if (newFolder)
+ {
+ CDisableTimerProcessing disableTimerProcessing(*this);
+ CDisableNotify disableNotify(*this);
+ SetNewFolder(newFolder);
+ RefreshListCtrl(UString(), -1, true, UStringVector());
+ return;
+ }
+ return;
+ }
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ UString path;
+ if (realIndex >= 0)
+ path = GetItemFullPath(realIndex);
+ else
+ {
+ path = GetFsPath();
+ if (!NName::IsDriveRootPath_SuperAllowed(us2fs(path)))
+ if (!path.IsEmpty() && IS_PATH_SEPAR(path.Back()))
+ path.DeleteBack();
+ }
+
+ path += L':';
+ BindToPathAndRefresh(path);
+ #endif
+}
diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
index d9beedb8..a485522f 100644
--- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
@@ -157,7 +157,8 @@ public:
static bool IsNameVirus(const UString &name)
{
- return (name.Find(L" ") >= 0);
+ // return (name.Find(L" ") >= 0);
+ return (wcsstr(name, L" ") != NULL);
}
struct CTmpProcessInfo: public CTempFileInfo
@@ -223,7 +224,13 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
folderLink.Password = password;
folderLink.UsePassword = encrypted;
- folderLink.ParentFolder = _folder;
+ if (_folder)
+ folderLink.ParentFolderPath = GetFolderPath(_folder);
+ else
+ folderLink.ParentFolderPath = _currentFolderPrefix;
+ if (!_parentFolders.IsEmpty())
+ folderLink.ParentFolder = _folder;
+
_parentFolders.Add(folderLink);
_parentFolders.Back().Library.Attach(_library.Detach());
@@ -272,7 +279,7 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
if (!values[0].IsEmpty())
{
if (!s2.IsEmpty())
- s2 += L"\n";
+ s2.Add_LF();
s2 += L"[";
s2 += values[2];
s2 += L"] Error: ";
@@ -283,7 +290,7 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
if (!s.IsEmpty())
s += L"--------------------\n";
s += values[1];
- s += L"\n";
+ s.Add_LF();
s += s2;
}
}
@@ -305,8 +312,8 @@ HRESULT CPanel::OpenItemAsArchive(const UString &relPath, const UString &arcForm
{
CTempFileInfo tfi;
tfi.RelPath = relPath;
- tfi.FolderPath = us2fs(_currentFolderPrefix);
- const UString fullPath = _currentFolderPrefix + relPath;
+ tfi.FolderPath = us2fs(GetFsPath());
+ const UString fullPath = GetFsPath() + relPath;
tfi.FilePath = us2fs(fullPath);
return OpenItemAsArchive(NULL, tfi, fullPath, arcFormat, encrypted);
}
@@ -316,7 +323,7 @@ HRESULT CPanel::OpenItemAsArchive(int index)
CDisableTimerProcessing disableTimerProcessing1(*this);
CDisableNotify disableNotify(*this);
bool encrypted;
- HRESULT res = OpenItemAsArchive(GetItemRelPath(index), UString(), encrypted);
+ HRESULT res = OpenItemAsArchive(GetItemRelPath2(index), UString(), encrypted);
if (res != S_OK)
{
RefreshTitle(true); // in case of error we must refresh changed title of 7zFM
@@ -379,7 +386,7 @@ static const char *kStartExtensions =
static bool FindExt(const char *p, const UString &name)
{
- int dotPos = name.ReverseFind('.');
+ int dotPos = name.ReverseFind_Dot();
if (dotPos < 0 || dotPos == (int)name.Len() - 1)
return false;
@@ -409,10 +416,7 @@ static bool DoItemAlwaysStart(const UString &name)
return FindExt(kStartExtensions, name);
}
-static UString GetQuotedString(const UString &s)
-{
- return UString(L'\"') + s + UString(L'\"');
-}
+UString GetQuotedString(const UString &s);
static HRESULT StartEditApplication(const UString &path, bool useEditor, HWND window, CProcess &process)
{
@@ -455,13 +459,17 @@ void CApp::DiffFiles()
{
const CPanel &destPanel = Panels[1 - LastFocusedPanel];
path1 = panel.GetItemFullPath(indices[0]);
- const UString relPath = panel.GetItemRelPath(indices[0]);
CRecordVector<UInt32> indices2;
destPanel.GetSelectedItemsIndices(indices2);
if (indices2.Size() == 1)
path2 = destPanel.GetItemFullPath(indices2[0]);
else
+ {
+ UString relPath = panel.GetItemRelPath2(indices[0]);
+ if (panel._flatMode && !destPanel._flatMode)
+ relPath = panel.GetItemName(indices[0]);
path2 = destPanel._currentFolderPrefix + relPath;
+ }
}
else
return;
@@ -471,7 +479,9 @@ void CApp::DiffFiles()
if (command.IsEmpty())
return;
- UString param = GetQuotedString(path1) + L' ' + GetQuotedString(path2);
+ UString param = GetQuotedString(path1);
+ param.Add_Space();
+ param += GetQuotedString(path2);
HRESULT res = MyCreateProcess(command, param);
if (res == SZ_OK)
@@ -573,11 +583,11 @@ void CPanel::OpenFolderExternal(int index)
UString name;
if (index == kParentIndex)
{
- int pos = fsPrefix.ReverseFind(WCHAR_PATH_SEPARATOR);
+ int pos = fsPrefix.ReverseFind_PathSepar();
if (pos >= 0 && pos == (int)fsPrefix.Len() - 1)
{
UString s = fsPrefix.Left(pos);
- pos = s.ReverseFind(WCHAR_PATH_SEPARATOR);
+ pos = s.ReverseFind_PathSepar();
if (pos >= 0)
fsPrefix.SetFrom(s, pos + 1);
}
@@ -591,7 +601,7 @@ void CPanel::OpenFolderExternal(int index)
void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal)
{
CDisableTimerProcessing disableTimerProcessing(*this);
- UString name = GetItemRelPath(index);
+ UString name = GetItemRelPath2(index);
if (IsNameVirus(name))
{
MessageBoxErrorLang(IDS_VIRUS);
@@ -650,8 +660,7 @@ HRESULT CThreadCopyFrom::ProcessVirt()
HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
bool usePassword, const UString &password)
{
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ if (!_folderOperations)
{
MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
return E_FAIL;
@@ -663,8 +672,13 @@ HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
t.UpdateCallbackSpec->ProgressDialog = &t.ProgressDialog;
t.ItemIndex = index;
t.FullPath = fullFilePath;
- t.FolderOperations = folderOperations;
- t.UpdateCallbackSpec->Init(usePassword, password);
+ t.FolderOperations = _folderOperations;
+
+ t.UpdateCallbackSpec->Init();
+ t.UpdateCallbackSpec->PasswordIsDefined = usePassword;
+ t.UpdateCallbackSpec->Password = password;
+
+
RINOK(t.Create(GetItemName(index), (HWND)*this));
return t.Result;
}
@@ -862,8 +876,11 @@ STDMETHODIMP CBufSeqOutStream_WithFile::Write(const void *data, UInt32 size, UIn
{
if (_size - _pos >= size)
{
- memcpy(_buffer + _pos, data, size);
- _pos += size;
+ if (size != 0)
+ {
+ memcpy(_buffer + _pos, data, size);
+ _pos += size;
+ }
if (processedSize)
*processedSize = (UInt32)size;
return S_OK;
@@ -931,8 +948,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
return;
}
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ if (!_folderOperations)
{
MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
return;
@@ -951,7 +967,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
FString tempDir = tempDirectory.GetPath();
FString tempDirNorm = tempDir;
NName::NormalizeDirPathPrefix(tempDirNorm);
- const FString tempFilePath = tempDirNorm + us2fs(GetCorrectFsPath(name));
+ const FString tempFilePath = tempDirNorm + us2fs(Get_Correct_FsFile_Name(name));
CTempFileInfo tempFileInfo;
tempFileInfo.FileIndex = index;
@@ -1029,7 +1045,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
bool isAltStream = IsItem_AltStream(index);
CCopyToOptions options;
- options.includeAltStreams = false;
+ options.includeAltStreams = true;
options.replaceAltStreamChars = isAltStream;
if (tryAsArchive)
@@ -1137,11 +1153,11 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
return;
CProcess process;
- /* HRESULT res; */
+ // HRESULT res;
if (editMode)
/* 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;
diff --git a/CPP/7zip/UI/FileManager/PanelItems.cpp b/CPP/7zip/UI/FileManager/PanelItems.cpp
index 8d74b8cd..491a36ad 100644
--- a/CPP/7zip/UI/FileManager/PanelItems.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItems.cpp
@@ -4,6 +4,7 @@
#include "../../../../C/Sort.h"
+#include "../../../Windows/FileName.h"
#include "../../../Windows/Menu.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/PropVariantConv.h"
@@ -103,7 +104,7 @@ HRESULT CPanel::InitColumns()
_properties.Clear();
_needSaveInfo = true;
- bool isFsFolder = IsFSFolder();
+ bool isFsFolder = IsFSFolder() || IsAltStreamsFolder();
{
UInt32 numProps;
@@ -401,7 +402,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
int cursorIndex = -1;
CMyComPtr<IFolderGetSystemIconIndex> folderGetSystemIconIndex;
- if (!IsFSFolder() || _showRealFileIcons)
+ if (!Is_Slow_Icon_Folder() || _showRealFileIcons)
_folder.QueryInterface(IID_IFolderGetSystemIconIndex, &folderGetSystemIconIndex);
if (!IsFSFolder())
@@ -436,7 +437,8 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
int subItem = 0;
item.iSubItem = subItem++;
item.lParam = kParentIndex;
- item.pszText = const_cast<wchar_t *>((const wchar_t *)itemName);
+ // item.pszText = const_cast<wchar_t *>((const wchar_t *)itemName);
+ item.pszText = LPSTR_TEXTCALLBACKW;
UInt32 attrib = FILE_ATTRIBUTE_DIRECTORY;
item.iImage = _extToIconMap.GetIconIndex(attrib, itemName);
if (item.iImage < 0)
@@ -451,19 +453,23 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
UString correctedName;
UString itemName;
UString relPath;
+
for (UInt32 i = 0; i < numItems; i++)
{
const wchar_t *name = NULL;
unsigned nameLen = 0;
+
if (_folderGetItemName)
_folderGetItemName->GetItemName(i, &name, &nameLen);
- if (name == NULL)
+ if (!name)
{
- GetItemNameFast(i, itemName);
+ GetItemName(i, itemName);
name = itemName;
nameLen = itemName.Len();
}
+
bool selected = false;
+
if (!focusedName.IsEmpty() || !selectedNames.IsEmpty())
{
relPath.Empty();
@@ -495,6 +501,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
if (selectedNames.FindInSorted(relPath) >= 0)
selected = true;
}
+
_selectedStatusVector.AddInReserved(selected);
item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
@@ -567,6 +574,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
// }
bool defined = false;
+
if (folderGetSystemIconIndex)
{
folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage);
@@ -585,6 +593,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
item.iImage = _extToIconMap.GetIconIndex(attrib, name);
}
}
+
if (item.iImage < 0)
item.iImage = 0;
@@ -592,6 +601,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
return E_FAIL;
listViewItemCount++;
}
+
// OutputDebugStringA("End2\n");
if (_listView.GetItemCount() > 0 && cursorIndex >= 0)
@@ -831,7 +841,24 @@ UString CPanel::GetItemName(int itemIndex) const
return prop.bstrVal;
}
-void CPanel::GetItemNameFast(int itemIndex, UString &s) const
+UString CPanel::GetItemName_for_Copy(int itemIndex) const
+{
+ if (itemIndex == kParentIndex)
+ return L"..";
+ {
+ NCOM::CPropVariant prop;
+ if (_folder->GetProperty(itemIndex, kpidOutName, &prop) == S_OK)
+ {
+ if (prop.vt == VT_BSTR)
+ return prop.bstrVal;
+ if (prop.vt != VT_EMPTY)
+ throw 2723401;
+ }
+ }
+ return GetItemName(itemIndex);
+}
+
+void CPanel::GetItemName(int itemIndex, UString &s) const
{
if (itemIndex == kParentIndex)
{
@@ -843,8 +870,7 @@ void CPanel::GetItemNameFast(int itemIndex, UString &s) const
throw 2723400;
if (prop.vt != VT_BSTR)
throw 2723401;
- s.Empty();
- s += prop.bstrVal;
+ s.SetFromBstr(prop.bstrVal);
}
UString CPanel::GetItemPrefix(int itemIndex) const
@@ -856,7 +882,7 @@ UString CPanel::GetItemPrefix(int itemIndex) const
throw 2723400;
UString prefix;
if (prop.vt == VT_BSTR)
- prefix = prop.bstrVal;
+ prefix.SetFromBstr(prop.bstrVal);
return prefix;
}
@@ -865,9 +891,22 @@ UString CPanel::GetItemRelPath(int itemIndex) const
return GetItemPrefix(itemIndex) + GetItemName(itemIndex);
}
+UString CPanel::GetItemRelPath2(int itemIndex) const
+{
+ UString s = GetItemRelPath(itemIndex);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (s.Len() == 2 && NFile::NName::IsDrivePath2(s))
+ {
+ if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix())
+ s.Add_PathSepar();
+ }
+ #endif
+ return s;
+}
+
UString CPanel::GetItemFullPath(int itemIndex) const
{
- return _currentFolderPrefix + GetItemRelPath(itemIndex);
+ return GetFsPath() + GetItemRelPath2(itemIndex);
}
bool CPanel::GetItem_BoolProp(UInt32 itemIndex, PROPID propID) const
@@ -928,6 +967,7 @@ void CPanel::ReadListViewInfo()
void CPanel::SaveListViewInfo()
{
unsigned i;
+
for (i = 0; i < _visibleProperties.Size(); i++)
{
CItemProperty &prop = _visibleProperties[i];
@@ -945,6 +985,7 @@ void CPanel::SaveListViewInfo()
PROPID sortPropID = _sortID;
_visibleProperties.Sort();
+
for (i = 0; i < _visibleProperties.Size(); i++)
{
const CItemProperty &prop = _visibleProperties[i];
@@ -954,6 +995,7 @@ void CPanel::SaveListViewInfo()
columnInfo.Width = prop.Width;
viewInfo.Columns.Add(columnInfo);
}
+
for (i = 0; i < _properties.Size(); i++)
{
const CItemProperty &prop = _properties[i];
@@ -1025,21 +1067,24 @@ void CPanel::ShowColumnsContextMenu(int x, int y)
else
{
int visibleIndex = _visibleProperties.FindItemWithID(prop.ID);
- _visibleProperties.Delete(visibleIndex);
- /*
- if (_sortIndex == index)
+ if (visibleIndex >= 0)
{
+ _visibleProperties.Delete(visibleIndex);
+ /*
+ if (_sortIndex == index)
+ {
_sortIndex = 0;
_ascending = true;
+ }
+ */
+ if (_sortID == prop.ID)
+ {
+ _sortID = kpidName;
+ _ascending = true;
+ }
+
+ _listView.DeleteColumn(visibleIndex);
}
- */
- if (_sortID == prop.ID)
- {
- _sortID = kpidName;
- _ascending = true;
- }
-
- _listView.DeleteColumn(visibleIndex);
}
}
}
diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
index 7be6aa62..2f37db14 100644
--- a/CPP/7zip/UI/FileManager/PanelListNotify.cpp
+++ b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
@@ -19,30 +19,57 @@
using namespace NWindows;
-static void ConvertSizeToString(UInt64 value, wchar_t *dest)
+#define INT_TO_STR_SPEC(v) \
+ while (v >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(v % 10)); v /= 10; } \
+ *s++ = (unsigned char)('0' + (unsigned)v);
+
+static void ConvertSizeToString(UInt64 val, wchar_t *s) throw()
{
- char s[32];
- ConvertUInt64ToString(value, s);
- unsigned i = MyStringLen(s);
- unsigned pos = ARRAY_SIZE(s);
- s[--pos] = 0;
- while (i > 3)
+ unsigned char temp[32];
+ unsigned i = 0;
+
+ if (val <= (UInt32)0xFFFFFFFF)
+ {
+ UInt32 val32 = (UInt32)val;
+ INT_TO_STR_SPEC(val32)
+ }
+ else
{
- s[--pos] = s[--i];
- s[--pos] = s[--i];
- s[--pos] = s[--i];
- s[--pos] = L' ';
+ INT_TO_STR_SPEC(val)
}
- while (i > 0)
- s[--pos] = s[--i];
- for (;;)
+ if (i < 3)
{
- char c = s[pos++];
- *dest++ = (unsigned char)c;
- if (c == 0)
- break;
+ if (i != 0)
+ {
+ *s++ = temp[i - 1];
+ if (i == 2)
+ *s++ = temp[0];
+ }
+ *s = 0;
+ return;
+ }
+
+ unsigned r = i % 3;
+ if (r != 0)
+ {
+ s[0] = temp[--i];
+ if (r == 2)
+ s[1] = temp[--i];
+ s += r;
}
+
+ do
+ {
+ s[0] = ' ';
+ s[1] = temp[i - 1];
+ s[2] = temp[i - 2];
+ s[3] = temp[i - 3];
+ s += 4;
+ }
+ while (i -= 3);
+
+ *s = 0;
}
UString ConvertSizeToString(UInt64 value)
@@ -52,29 +79,62 @@ UString ConvertSizeToString(UInt64 value)
return s;
}
-static inline char GetHex(Byte value)
+static inline unsigned GetHex(unsigned v)
{
- return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+ return (v < 10) ? ('0' + v) : ('A' + (v - 10));
}
-void HexToString(char *dest, const Byte *data, UInt32 size)
+/*
+static void HexToString(char *dest, const Byte *data, UInt32 size)
{
for (UInt32 i = 0; i < size; i++)
{
- Byte b = data[i];
- dest[0] = GetHex((Byte)((b >> 4) & 0xF));
- dest[1] = GetHex((Byte)(b & 0xF));
+ unsigned b = data[i];
+ dest[0] = GetHex((b >> 4) & 0xF);
+ dest[1] = GetHex(b & 0xF);
dest += 2;
}
*dest = 0;
}
+*/
-LRESULT CPanel::SetItemText(LVITEMW &item)
+bool IsSizeProp(UINT propID) throw()
{
+ switch (propID)
+ {
+ case kpidSize:
+ case kpidPackSize:
+ case kpidNumSubDirs:
+ case kpidNumSubFiles:
+ case kpidOffset:
+ case kpidLinks:
+ case kpidNumBlocks:
+ case kpidNumVolumes:
+ case kpidPhySize:
+ case kpidHeadersSize:
+ case kpidTotalSize:
+ case kpidFreeSpace:
+ case kpidClusterSize:
+ case kpidNumErrors:
+ case kpidNumStreams:
+ case kpidNumAltStreams:
+ case kpidAltStreamsSize:
+ case kpidVirtualSize:
+ case kpidUnpackSize:
+ case kpidTotalPhySize:
+ case kpidTailSize:
+ case kpidEmbeddedStubSize:
+ return true;
+ }
+ return false;
+}
+LRESULT CPanel::SetItemText(LVITEMW &item)
+{
if (_dontShowMode)
return 0;
UInt32 realIndex = GetRealIndex(item);
+
/*
if ((item.mask & LVIF_IMAGE) != 0)
{
@@ -107,10 +167,31 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
if ((item.mask & LVIF_TEXT) == 0)
return 0;
- if (realIndex == kParentIndex)
+ LPWSTR text = item.pszText;
+
+ if (item.cchTextMax > 0)
+ text[0] = 0;
+
+ if (item.cchTextMax <= 1)
return 0;
+
const CItemProperty &property = _visibleProperties[item.iSubItem];
PROPID propID = property.ID;
+
+ if (realIndex == kParentIndex)
+ {
+ if (propID == kpidName)
+ {
+ if (item.cchTextMax > 2)
+ {
+ text[0] = '.';
+ text[1] = '.';
+ text[2] = 0;
+ }
+ }
+ return 0;
+ }
+
if (property.IsRawProp)
{
@@ -118,10 +199,10 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
UInt32 dataSize;
UInt32 propType;
RINOK(_folderRawProps->GetRawProp(realIndex, propID, &data, &dataSize, &propType));
- int limit = item.cchTextMax - 1;
+ unsigned limit = item.cchTextMax - 1;
if (dataSize == 0)
{
- item.pszText[0] = 0;
+ text[0] = 0;
return 0;
}
@@ -131,15 +212,15 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
ConvertNtReparseToString((const Byte *)data, dataSize, s);
if (!s.IsEmpty())
{
- int i;
+ unsigned i;
for (i = 0; i < limit; i++)
{
wchar_t c = s[i];
if (c == 0)
break;
- item.pszText[i] = c;
+ text[i] = c;
}
- item.pszText[i] = 0;
+ text[i] = 0;
return 0;
}
}
@@ -149,45 +230,45 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
ConvertNtSecureToString((const Byte *)data, dataSize, s);
if (!s.IsEmpty())
{
- int i;
+ unsigned i;
for (i = 0; i < limit; i++)
{
- wchar_t c = s[i];
+ wchar_t c = (Byte)s[i];
if (c == 0)
break;
- item.pszText[i] = c;
+ text[i] = c;
}
- item.pszText[i] = 0;
+ text[i] = 0;
return 0;
}
}
{
- const UInt32 kMaxDataSize = 64;
+ const unsigned kMaxDataSize = 64;
if (dataSize > kMaxDataSize)
{
- char temp[64];
+ char temp[32];
MyStringCopy(temp, "data:");
ConvertUInt32ToString(dataSize, temp + 5);
- int i;
+ unsigned i;
for (i = 0; i < limit; i++)
{
- wchar_t c = temp[i];
+ wchar_t c = (Byte)temp[i];
if (c == 0)
break;
- item.pszText[i] = c;
+ text[i] = c;
}
- item.pszText[i] = 0;
+ text[i] = 0;
}
else
{
- if ((int)dataSize > limit)
+ if (dataSize > limit)
dataSize = limit;
- WCHAR *dest = item.pszText;
+ WCHAR *dest = text;
for (UInt32 i = 0; i < dataSize; i++)
{
- Byte b = ((const Byte *)data)[i];
- dest[0] = GetHex((Byte)((b >> 4) & 0xF));
- dest[1] = GetHex((Byte)(b & 0xF));
+ unsigned b = ((const Byte *)data)[i];
+ dest[0] = (WCHAR)GetHex((b >> 4) & 0xF);
+ dest[1] = (WCHAR)GetHex(b & 0xF);
dest += 2;
}
*dest = 0;
@@ -230,11 +311,7 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
*/
if (item.cchTextMax < 32)
- {
- if (item.cchTextMax > 0)
- item.pszText[0] = 0;
return 0;
- }
if (propID == kpidName)
{
@@ -245,35 +322,36 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
_folderGetItemName->GetItemName(realIndex, &name, &nameLen);
if (name)
{
- int dest = 0;
- int limit = item.cchTextMax - 1;
- for (int i = 0; dest < limit;)
+ unsigned dest = 0;
+ unsigned limit = item.cchTextMax - 1;
+ for (unsigned i = 0; dest < limit;)
{
wchar_t c = name[i++];
if (c == 0)
break;
- item.pszText[dest++] = c;
+ text[dest++] = c;
if (c != ' ')
continue;
if (name[i + 1] != ' ')
continue;
- int t = 2;
+ unsigned t = 2;
for (; name[i + t] == ' '; t++);
if (t >= 4 && dest + 4 <= limit)
{
- item.pszText[dest++] = '.';
- item.pszText[dest++] = '.';
- item.pszText[dest++] = '.';
- item.pszText[dest++] = ' ';
+ text[dest++] = '.';
+ text[dest++] = '.';
+ text[dest++] = '.';
+ text[dest++] = ' ';
i += t;
}
}
- item.pszText[dest] = 0;
+ text[dest] = 0;
return 0;
}
}
}
+
if (propID == kpidPrefix)
{
if (_folderGetItemName)
@@ -283,73 +361,65 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
_folderGetItemName->GetItemPrefix(realIndex, &name, &nameLen);
if (name)
{
- int dest = 0;
- int limit = item.cchTextMax - 1;
- for (int i = 0; dest < limit;)
+ unsigned dest = 0;
+ unsigned limit = item.cchTextMax - 1;
+ for (unsigned i = 0; dest < limit;)
{
wchar_t c = name[i++];
if (c == 0)
break;
- item.pszText[dest++] = c;
+ text[dest++] = c;
}
- item.pszText[dest] = 0;
+ text[dest] = 0;
return 0;
}
}
}
+
HRESULT res = _folder->GetProperty(realIndex, propID, &prop);
+
if (res != S_OK)
{
- MyStringCopy(item.pszText, L"Error: ");
+ MyStringCopy(text, L"Error: ");
// s = UString(L"Error: ") + HResultToMessage(res);
}
- else if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && (
- propID == kpidSize ||
- propID == kpidPackSize ||
- propID == kpidNumSubDirs ||
- propID == kpidNumSubFiles ||
- propID == kpidPosition ||
- propID == kpidNumBlocks ||
- propID == kpidClusterSize ||
- propID == kpidTotalSize ||
- propID == kpidFreeSpace ||
- propID == kpidUnpackSize
- ))
+ else if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && IsSizeProp(propID))
{
UInt64 v = 0;
ConvertPropVariantToUInt64(prop, v);
- ConvertSizeToString(v, item.pszText);
+ ConvertSizeToString(v, text);
}
else if (prop.vt == VT_BSTR)
{
- int limit = item.cchTextMax - 1;
+ unsigned limit = item.cchTextMax - 1;
const wchar_t *src = prop.bstrVal;
- int i;
+ unsigned i;
for (i = 0; i < limit; i++)
{
wchar_t c = src[i];
if (c == 0) break;
if (c == 0xA) c = ' ';
if (c == 0xD) c = ' ';
- item.pszText[i] = c;
+ text[i] = c;
}
- item.pszText[i] = 0;
+ text[i] = 0;
}
else
{
char temp[64];
ConvertPropertyToShortString(temp, prop, propID, false);
- int i;
- int limit = item.cchTextMax - 1;
+ unsigned i;
+ unsigned limit = item.cchTextMax - 1;
for (i = 0; i < limit; i++)
{
- wchar_t c = temp[i];
+ wchar_t c = (Byte)temp[i];
if (c == 0)
break;
- item.pszText[i] = c;
+ text[i] = c;
}
- item.pszText[i] = 0;
+ text[i] = 0;
}
+
return 0;
}
@@ -606,7 +676,7 @@ void CPanel::Refresh_StatusBar()
if (indices.Size() > 0)
{
- // for (int ttt = 0; ttt < 1000; ttt++) {
+ // for (unsigned ttt = 0; ttt < 1000; ttt++) {
UInt64 totalSize = 0;
FOR_VECTOR (i, indices)
totalSize += GetItemSize(indices[i]);
@@ -632,10 +702,10 @@ void CPanel::Refresh_StatusBar()
char dateString2[32];
dateString2[0] = 0;
ConvertPropertyToShortString(dateString2, prop, kpidMTime, false);
- for (int i = 0;; i++)
+ for (unsigned i = 0;; i++)
{
char c = dateString2[i];
- dateString[i] = c;
+ dateString[i] = (Byte)c;
if (c == 0)
break;
}
diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp
index d7108204..5a527cb4 100644
--- a/CPP/7zip/UI/FileManager/PanelMenu.cpp
+++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp
@@ -49,11 +49,12 @@ void CPanel::InvokeSystemCommand(const char *command)
contextMenu->InvokeCommand(&ci);
}
-static const wchar_t *kSeparator = L"----------------------------\n";
-static const wchar_t *kSeparatorSmall = L"----\n";
-static const wchar_t *kPropValueSeparator = L": ";
+static const char *kSeparator = "----------------------------\n";
+static const char *kSeparatorSmall = "----\n";
+static const char *kPropValueSeparator = ": ";
-extern UString ConvertSizeToString(UInt64 value);
+extern UString ConvertSizeToString(UInt64 value) throw();
+bool IsSizeProp(UINT propID) throw();
UString GetOpenArcErrorMessage(UInt32 errorFlags);
@@ -74,20 +75,7 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
val = GetOpenArcErrorMessage(flags);
}
if (val.IsEmpty())
- if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && (
- propID == kpidSize ||
- propID == kpidPackSize ||
- propID == kpidNumSubDirs ||
- propID == kpidNumSubFiles ||
- propID == kpidNumBlocks ||
- propID == kpidClusterSize ||
- propID == kpidTotalSize ||
- propID == kpidFreeSpace ||
- propID == kpidPhySize ||
- propID == kpidHeadersSize ||
- propID == kpidFreeSpace ||
- propID == kpidUnpackSize
- ))
+ if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && IsSizeProp(propID))
{
UInt64 v = 0;
ConvertPropVariantToUInt64(prop, v);
@@ -99,13 +87,13 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
if (!val.IsEmpty())
{
s += GetNameOfProperty(propID, nameBSTR);
- s += kPropValueSeparator;
+ s.AddAscii(kPropValueSeparator);
/*
if (propID == kpidComment)
- s += L'\n';
+ s.Add_LF();
*/
s += val;
- s += L'\n';
+ s.Add_LF();
}
}
}
@@ -210,21 +198,21 @@ void CPanel::Properties()
}
}
message += GetNameOfProperty(propID, name);
- message += kPropValueSeparator;
- message += GetUnicodeString(s);
- message += L'\n';
+ message.AddAscii(kPropValueSeparator);
+ message.AddAscii(s);
+ message.Add_LF();
}
}
}
- message += kSeparator;
+ message.AddAscii(kSeparator);
}
/*
- message += LangString(IDS_PROP_FILE_TYPE, 0x02000214);
+ AddLangString(message, IDS_PROP_FILE_TYPE);
message += kPropValueSeparator;
message += GetFolderTypeID();
- message += L"\n";
+ message.Add_LF();
*/
{
@@ -277,7 +265,7 @@ void CPanel::Properties()
{
const int kNumSpecProps = ARRAY_SIZE(kSpecProps);
- message += kSeparator;
+ message.AddAscii(kSeparator);
for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++)
{
@@ -302,7 +290,7 @@ void CPanel::Properties()
UInt32 numProps;
if (getProps->GetArcNumProps2(level, &numProps) == S_OK)
{
- message += kSeparatorSmall;
+ message.AddAscii(kSeparatorSmall);
for (Int32 i = 0; i < (Int32)numProps; i++)
{
CMyComBSTR name;
@@ -414,9 +402,7 @@ HRESULT CPanel::CreateShellContextMenu(
FOR_VECTOR (i, operatedIndices)
{
LPITEMIDLIST pidl;
- UString fileName = GetItemRelPath(operatedIndices[i]);
- if (IsFSDrivesFolder())
- fileName += WCHAR_PATH_SEPARATOR;
+ UString fileName = GetItemRelPath2(operatedIndices[i]);
RINOK(parentFolder->ParseDisplayName(GetParent(), 0,
(wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0));
pidls.AddInReserved(pidl);
@@ -574,11 +560,11 @@ void CPanel::CreateSevenZipMenu(HMENU menuSpec,
if (contextMenu.QueryInterface(IID_IInitContextMenu, &initContextMenu) != S_OK)
return;
*/
- UString currentFolderUnicode = _currentFolderPrefix;
+ UString currentFolderUnicode = GetFsPath();
UStringVector names;
unsigned i;
for (i = 0; i < operatedIndices.Size(); i++)
- names.Add(currentFolderUnicode + GetItemRelPath(operatedIndices[i]));
+ names.Add(currentFolderUnicode + GetItemRelPath2(operatedIndices[i]));
CRecordVector<const wchar_t *> namePointers;
for (i = 0; i < operatedIndices.Size(); i++)
namePointers.Add(names[i]);
@@ -598,6 +584,74 @@ void CPanel::CreateSevenZipMenu(HMENU menuSpec,
}
}
+static bool IsReadOnlyFolder(IFolderFolder *folder)
+{
+ if (!folder)
+ return false;
+
+ bool res = false;
+ {
+ NCOM::CPropVariant prop;
+ if (folder->GetFolderProperty(kpidReadOnly, &prop) == S_OK)
+ if (prop.vt == VT_BOOL)
+ res = VARIANT_BOOLToBool(prop.boolVal);
+ }
+ return res;
+}
+
+bool CPanel::IsThereReadOnlyFolder() const
+{
+ if (!_folderOperations)
+ return true;
+ if (IsReadOnlyFolder(_folder))
+ return true;
+ FOR_VECTOR (i, _parentFolders)
+ {
+ if (IsReadOnlyFolder(_parentFolders[i].ParentFolder))
+ return true;
+ }
+ return false;
+}
+
+bool CPanel::CheckBeforeUpdate(UINT resourceID)
+{
+ if (!_folderOperations)
+ {
+ MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
+ // resourceID = resourceID;
+ // MessageBoxErrorForUpdate(E_NOINTERFACE, resourceID);
+ return false;
+ }
+
+ for (int i = (int)_parentFolders.Size(); i >= 0; i--)
+ {
+ IFolderFolder *folder;
+ if (i == (int)_parentFolders.Size())
+ folder = _folder;
+ else
+ folder = _parentFolders[i].ParentFolder;
+
+ if (!IsReadOnlyFolder(folder))
+ continue;
+
+ UString s;
+ AddLangString(s, resourceID);
+ s.Add_LF();
+ AddLangString(s, IDS_OPERATION_IS_NOT_SUPPORTED);
+ s.Add_LF();
+ if (i == 0)
+ s += GetFolderPath(folder);
+ else
+ s += _parentFolders[i - 1].VirtualPath;
+ s.Add_LF();
+ AddLangString(s, IDS_PROP_READ_ONLY);
+ MessageBoxMyError(s);
+ return false;
+ }
+
+ return true;
+}
+
void CPanel::CreateFileMenu(HMENU menuSpec,
CMyComPtr<IContextMenu> &sevenZipContextMenu,
CMyComPtr<IContextMenu> &systemContextMenu,
@@ -631,8 +685,38 @@ void CPanel::CreateFileMenu(HMENU menuSpec,
if (IsItem_Folder(operatedIndices[i]))
break;
bool allAreFiles = (i == operatedIndices.Size());
- LoadFileMenu(menu, menu.GetItemCount(), programMenu,
- IsFSFolder(), operatedIndices.Size(), allAreFiles);
+
+ CFileMenu fm;
+
+ fm.readOnly = IsThereReadOnlyFolder();
+ fm.isFsFolder = Is_IO_FS_Folder();
+ fm.programMenu = programMenu;
+ fm.allAreFiles = allAreFiles;
+ fm.numItems = operatedIndices.Size();
+
+ fm.isAltStreamsSupported = false;
+
+ if (_folderAltStreams)
+ {
+ if (operatedIndices.Size() <= 1)
+ {
+ Int32 realIndex = -1;
+ if (operatedIndices.Size() == 1)
+ realIndex = operatedIndices[0];
+ Int32 val = 0;
+ if (_folderAltStreams->AreAltStreamsSupported(realIndex, &val) == S_OK)
+ fm.isAltStreamsSupported = IntToBool(val);
+ }
+ }
+ else
+ {
+ if (fm.numItems == 0)
+ fm.isAltStreamsSupported = IsFSFolder();
+ else
+ fm.isAltStreamsSupported = IsFolder_with_FsItems();
+ }
+
+ fm.Load(menu, menu.GetItemCount());
}
bool CPanel::InvokePluginCommand(int id)
@@ -654,26 +738,31 @@ bool CPanel::InvokePluginCommand(int id,
else
offset = id - kSevenZipStartMenuID;
- #ifndef use_CMINVOKECOMMANDINFOEXR
- CMINVOKECOMMANDINFO
+ #ifdef use_CMINVOKECOMMANDINFOEX
+ CMINVOKECOMMANDINFOEX
#else
- CMINVOKECOMMANDINFOEX
+ CMINVOKECOMMANDINFO
#endif
- commandInfo;
+ commandInfo;
+
memset(&commandInfo, 0, sizeof(commandInfo));
commandInfo.cbSize = sizeof(commandInfo);
+
commandInfo.fMask = 0
- #ifdef use_CMINVOKECOMMANDINFOEXR
- | CMIC_MASK_UNICODE
+ #ifdef use_CMINVOKECOMMANDINFOEX
+ | CMIC_MASK_UNICODE
#endif
- ;
+ ;
+
commandInfo.hwnd = GetParent();
commandInfo.lpVerb = (LPCSTR)(MAKEINTRESOURCE(offset));
commandInfo.lpParameters = NULL;
CSysString currentFolderSys = GetSystemString(_currentFolderPrefix);
commandInfo.lpDirectory = (LPCSTR)(LPCTSTR)(currentFolderSys);
commandInfo.nShow = SW_SHOW;
- #ifdef use_CMINVOKECOMMANDINFOEXR
+
+ #ifdef use_CMINVOKECOMMANDINFOEX
+
commandInfo.lpParametersW = NULL;
commandInfo.lpTitle = "";
commandInfo.lpVerbW = (LPCWSTR)(MAKEINTRESOURCEW(offset));
@@ -684,7 +773,9 @@ bool CPanel::InvokePluginCommand(int id,
// commandInfo.ptInvoke.y = yPos;
commandInfo.ptInvoke.x = 0;
commandInfo.ptInvoke.y = 0;
+
#endif
+
HRESULT result;
if (isSystemMenu)
result = systemContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo));
diff --git a/CPP/7zip/UI/FileManager/PanelOperations.cpp b/CPP/7zip/UI/FileManager/PanelOperations.cpp
index 28c945e5..62a08e13 100644
--- a/CPP/7zip/UI/FileManager/PanelOperations.cpp
+++ b/CPP/7zip/UI/FileManager/PanelOperations.cpp
@@ -85,16 +85,15 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
ProgressDialog.Sync.FinalMessage.ErrorMessage.Title = titleError;
Result = S_OK;
- bool usePassword = false;
- UString password;
+ UpdateCallbackSpec->Init();
+
if (panel._parentFolders.Size() > 0)
{
const CFolderLink &fl = panel._parentFolders.Back();
- usePassword = fl.UsePassword;
- password = fl.Password;
+ UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword;
+ UpdateCallbackSpec->Password = fl.Password;
}
- UpdateCallbackSpec->Init(usePassword, password);
ProgressDialog.MainWindow = panel._mainWindow; // panel.GetParent()
ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
@@ -108,6 +107,7 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
typedef int (WINAPI * SHFileOperationWP)(LPSHFILEOPSTRUCTW lpFileOp);
#endif
+/*
void CPanel::MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID)
{
if (errorCode == E_NOINTERFACE)
@@ -115,6 +115,7 @@ void CPanel::MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID)
else
MessageBoxError(errorCode, LangString(resourceID));
}
+*/
void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
{
@@ -137,8 +138,8 @@ void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
CDynamicBuffer<CHAR> buffer;
FOR_VECTOR (i, indices)
{
- const AString path = GetSystemString(GetFsPath() + GetItemRelPath(indices[i]));
- memcpy(buffer.GetCurPtrAndGrow(path.Len() + 1), (const CHAR *)path, (path.Len() + 1) * sizeof(CHAR));
+ const AString path = GetSystemString(GetItemFullPath(indices[i]));
+ buffer.AddData(path, path.Len() + 1);
}
*buffer.GetCurPtrAndGrow(1) = 0;
SHFILEOPSTRUCTA fo;
@@ -163,13 +164,14 @@ void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
{
CDynamicBuffer<WCHAR> buffer;
unsigned maxLen = 0;
+ const UString prefix = GetFsPath();
FOR_VECTOR (i, indices)
{
// L"\\\\?\\") doesn't work here.
- const UString path = GetFsPath() + GetItemRelPath(indices[i]);
+ const UString path = prefix + GetItemRelPath2(indices[i]);
if (path.Len() > maxLen)
maxLen = path.Len();
- memcpy(buffer.GetCurPtrAndGrow(path.Len() + 1), (const WCHAR *)path, (path.Len() + 1) * sizeof(WCHAR));
+ buffer.AddData(path, path.Len() + 1);
}
*buffer.GetCurPtrAndGrow(1) = 0;
if (maxLen >= MAX_PATH)
@@ -220,19 +222,15 @@ void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
// DeleteItemsInternal
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
- {
- MessageBoxErrorForUpdate(E_NOINTERFACE, IDS_ERROR_DELETING);
+ if (!CheckBeforeUpdate(IDS_ERROR_DELETING))
return;
- }
UInt32 titleID, messageID;
UString messageParam;
if (indices.Size() == 1)
{
int index = indices[0];
- messageParam = GetItemRelPath(index);
+ messageParam = GetItemRelPath2(index);
if (IsItem_Folder(index))
{
titleID = IDS_CONFIRM_FOLDER_DELETE;
@@ -256,7 +254,7 @@ void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
CDisableNotify disableNotify(*this);
{
CThreadFolderOperations op(FOLDER_TYPE_DELETE);
- op.FolderOperations = folderOperations;
+ op.FolderOperations = _folderOperations;
op.Indices = indices;
op.DoOperation(*this,
LangString(IDS_DELETING),
@@ -271,25 +269,14 @@ BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh)
int realIndex = GetRealIndex(lpnmh->item);
if (realIndex == kParentIndex)
return TRUE;
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ if (IsThereReadOnlyFolder())
return TRUE;
return FALSE;
}
-static UString GetLastPart(const UString name)
-{
- int slashPos = name.ReverseFind(L'/');
- #ifdef _WIN32
- int slash1Pos = name.ReverseFind(L'\\');
- slashPos = MyMax(slashPos, slash1Pos);
- #endif
- return name.Ptr(slashPos + 1);
-}
-
bool IsCorrectFsName(const UString &name)
{
- const UString lastPart = GetLastPart(name);
+ const UString lastPart = name.Ptr(name.ReverseFind_PathSepar() + 1);
return
lastPart != L"." &&
lastPart != L"..";
@@ -299,7 +286,7 @@ bool CorrectFsPath(const UString &relBase, const UString &path, UString &result)
bool CPanel::CorrectFsPath(const UString &path2, UString &result)
{
- return ::CorrectFsPath(_currentFolderPrefix, path2, result);
+ return ::CorrectFsPath(GetFsPath(), path2, result);
}
BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
@@ -307,12 +294,10 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
if (lpnmh->item.pszText == NULL)
return FALSE;
CDisableTimerProcessing disableTimerProcessing2(*this);
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
- {
- MessageBoxErrorForUpdate(E_NOINTERFACE, IDS_ERROR_RENAMING);
+
+ if (!CheckBeforeUpdate(IDS_ERROR_RENAMING))
return FALSE;
- }
+
UString newName = lpnmh->item.pszText;
if (!IsCorrectFsName(newName))
{
@@ -342,7 +327,7 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
CDisableNotify disableNotify(*this);
{
CThreadFolderOperations op(FOLDER_TYPE_RENAME);
- op.FolderOperations = folderOperations;
+ op.FolderOperations = _folderOperations;
op.Index = realIndex;
op.Name = newName;
/* HRESULTres = */ op.DoOperation(*this,
@@ -377,12 +362,9 @@ bool Dlg_CreateFolder(HWND wnd, UString &destName);
void CPanel::CreateFolder()
{
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
- {
- MessageBoxErrorForUpdate(E_NOINTERFACE, IDS_CREATE_FOLDER_ERROR);
+ if (!CheckBeforeUpdate(IDS_CREATE_FOLDER_ERROR))
return;
- }
+
CDisableTimerProcessing disableTimerProcessing2(*this);
CSelectedState state;
SaveSelectedState(state);
@@ -412,7 +394,7 @@ void CPanel::CreateFolder()
CDisableNotify disableNotify(*this);
{
CThreadFolderOperations op(FOLDER_TYPE_CREATE_FOLDER);
- op.FolderOperations = folderOperations;
+ op.FolderOperations = _folderOperations;
op.Name = newName;
res = op.DoOperation(*this,
LangString(IDS_CREATE_FOLDER),
@@ -439,12 +421,9 @@ void CPanel::CreateFolder()
void CPanel::CreateFile()
{
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
- {
- MessageBoxErrorForUpdate(E_NOINTERFACE, IDS_CREATE_FILE_ERROR);
+ if (!CheckBeforeUpdate(IDS_CREATE_FILE_ERROR))
return;
- }
+
CDisableTimerProcessing disableTimerProcessing2(*this);
CSelectedState state;
SaveSelectedState(state);
@@ -471,10 +450,11 @@ void CPanel::CreateFile()
newName = correctName;
}
- HRESULT result = folderOperations->CreateFile(newName, 0);
+ HRESULT result = _folderOperations->CreateFile(newName, 0);
if (result != S_OK)
{
- MessageBoxErrorForUpdate(result, IDS_CREATE_FILE_ERROR);
+ MessageBoxError(result, LangString(IDS_CREATE_FILE_ERROR));
+ // MessageBoxErrorForUpdate(result, IDS_CREATE_FILE_ERROR);
return;
}
int pos = newName.Find(WCHAR_PATH_SEPARATOR);
@@ -489,6 +469,8 @@ void CPanel::CreateFile()
void CPanel::RenameFile()
{
+ if (!CheckBeforeUpdate(IDS_ERROR_RENAMING))
+ return;
int index = _listView.GetFocusedItem();
if (index >= 0)
_listView.EditLabel(index);
@@ -496,6 +478,8 @@ void CPanel::RenameFile()
void CPanel::ChangeComment()
{
+ if (!CheckBeforeUpdate(IDS_COMMENT))
+ return;
CDisableTimerProcessing disableTimerProcessing2(*this);
int index = _listView.GetFocusedItem();
if (index < 0)
@@ -505,13 +489,6 @@ void CPanel::ChangeComment()
return;
CSelectedState state;
SaveSelectedState(state);
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
- {
- MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
- return;
- }
-
UString comment;
{
NCOM::CPropVariant propVariant;
@@ -522,17 +499,19 @@ void CPanel::ChangeComment()
else if (propVariant.vt != VT_EMPTY)
return;
}
- UString name = GetItemRelPath(realIndex);
+ UString name = GetItemRelPath2(realIndex);
CComboDialog dlg;
- dlg.Title = name + L' ' + LangString(IDS_COMMENT);
+ dlg.Title = name;
+ dlg.Title += L" : ";
+ AddLangString(dlg.Title, IDS_COMMENT);
dlg.Value = comment;
LangString(IDS_COMMENT2, dlg.Static);
if (dlg.Create(GetParent()) != IDOK)
return;
- NCOM::CPropVariant propVariant = (const wchar_t *)dlg.Value;
+ NCOM::CPropVariant propVariant = dlg.Value.Ptr();
CDisableNotify disableNotify(*this);
- HRESULT result = folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL);
+ HRESULT result = _folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL);
if (result != S_OK)
{
if (result == E_NOINTERFACE)
diff --git a/CPP/7zip/UI/FileManager/PanelSelect.cpp b/CPP/7zip/UI/FileManager/PanelSelect.cpp
index a40997c2..7b53eb00 100644
--- a/CPP/7zip/UI/FileManager/PanelSelect.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSelect.cpp
@@ -22,7 +22,9 @@ void CPanel::OnShiftSelectMessage()
return;
int startItem = MyMin(focusedItem, _prevFocusedItem);
int finishItem = MyMax(focusedItem, _prevFocusedItem);
- for (int i = 0; i < _listView.GetItemCount(); i++)
+
+ int numItems = _listView.GetItemCount();
+ for (int i = 0; i < numItems; i++)
{
int realIndex = GetRealItemIndex(i);
if (realIndex == kParentIndex)
@@ -34,6 +36,7 @@ void CPanel::OnShiftSelectMessage()
_listView.RedrawItem(i);
}
}
+
_prevFocusedItem = focusedItem;
}
@@ -45,6 +48,7 @@ void CPanel::OnArrowWithShift()
if (focusedItem < 0)
return;
int realIndex = GetRealItemIndex(focusedItem);
+
if (_selectionIsDefined)
{
if (realIndex != kParentIndex)
@@ -64,6 +68,7 @@ void CPanel::OnArrowWithShift()
_selectedStatusVector[realIndex] = _selectMark;
}
}
+
_prevFocusedItem = focusedItem;
PostMessage(kShiftSelectMessage);
_listView.RedrawItem(focusedItem);
@@ -165,13 +170,6 @@ void CPanel::SelectByType(bool selectMode)
UString name = GetItemName(realIndex);
bool isItemFolder = IsItem_Folder(realIndex);
- /*
- UInt32 numItems;
- _folder->GetNumberOfItems(&numItems);
- if ((UInt32)_selectedStatusVector.Size() != numItems)
- throw 11111;
- */
-
if (isItemFolder)
{
FOR_VECTOR (i, _selectedStatusVector)
@@ -180,11 +178,11 @@ void CPanel::SelectByType(bool selectMode)
}
else
{
- int pos = name.ReverseFind(L'.');
+ int pos = name.ReverseFind_Dot();
if (pos < 0)
{
FOR_VECTOR (i, _selectedStatusVector)
- if (IsItem_Folder(i) == isItemFolder && GetItemName(i).ReverseFind(L'.') < 0)
+ if (IsItem_Folder(i) == isItemFolder && GetItemName(i).ReverseFind_Dot() < 0)
_selectedStatusVector[i] = selectMode;
}
else
@@ -196,6 +194,7 @@ void CPanel::SelectByType(bool selectMode)
_selectedStatusVector[i] = selectMode;
}
}
+
UpdateSelection();
}
@@ -253,10 +252,11 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate)
{
if (itemActivate->hdr.hwndFrom != HWND(_listView))
return;
- // It will be work only for Version 4.71 (IE 4);
+ // It will work only for Version 4.71 (IE 4);
int indexInList = itemActivate->iItem;
if (indexInList < 0)
return;
+
#ifndef UNDER_CE
if ((itemActivate->uKeyFlags & LVKF_SHIFT) != 0)
{
@@ -264,9 +264,11 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate)
int focusedIndex = _startGroupSelect;
if (focusedIndex < 0)
return;
- unsigned startItem = MyMin((unsigned)focusedIndex, (unsigned)indexInList);
- unsigned finishItem = MyMax((unsigned)focusedIndex, (unsigned)indexInList);
- FOR_VECTOR (i, _selectedStatusVector)
+ int startItem = MyMin(focusedIndex, indexInList);
+ int finishItem = MyMax(focusedIndex, indexInList);
+
+ int numItems = _listView.GetItemCount();
+ for (int i = 0; i < numItems; i++)
{
int realIndex = GetRealItemIndex(i);
if (realIndex == kParentIndex)
@@ -283,6 +285,7 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate)
#endif
{
_startGroupSelect = indexInList;
+
#ifndef UNDER_CE
if ((itemActivate->uKeyFlags & LVKF_CONTROL) != 0)
{
@@ -295,5 +298,6 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate)
}
#endif
}
+
return;
}
diff --git a/CPP/7zip/UI/FileManager/PanelSort.cpp b/CPP/7zip/UI/FileManager/PanelSort.cpp
index fe5d3ffd..82d6756e 100644
--- a/CPP/7zip/UI/FileManager/PanelSort.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSort.cpp
@@ -76,7 +76,7 @@ static int CompareFileNames_Le16(const Byte *s1, unsigned size1, const Byte *s2,
static inline const wchar_t *GetExtensionPtr(const UString &name)
{
- int dotPos = name.ReverseFind(L'.');
+ int dotPos = name.ReverseFind_Dot();
return name.Ptr((dotPos < 0) ? name.Len() : dotPos);
}
diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
index ce15fcc5..a8c0d352 100644
--- a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
@@ -138,7 +138,7 @@ HRESULT CThreadSplit::ProcessVirt()
if (!outFile.Create(name, false))
{
HRESULT res = GetLastError();
- SetErrorPath1(name);
+ AddErrorPath(name);
return res;
}
}
@@ -165,7 +165,7 @@ void CApp::Split()
{
int srcPanelIndex = GetFocusedPanelIndex();
CPanel &srcPanel = Panels[srcPanelIndex];
- if (!srcPanel.IsFSFolder())
+ if (!srcPanel.Is_IO_FS_Folder())
{
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
return;
@@ -187,13 +187,13 @@ void CApp::Split()
}
const UString itemName = srcPanel.GetItemName(index);
- UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index);
+ UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index);
UString path = srcPath;
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
CPanel &destPanel = Panels[destPanelIndex];
if (NumPanels > 1)
if (destPanel.IsFSFolder())
- path = destPanel._currentFolderPrefix;
+ path = destPanel.GetFsPath();
CSplitDialog splitDialog;
splitDialog.FilePath = srcPanel.GetItemRelPath(index);
splitDialog.Path = path;
@@ -243,12 +243,13 @@ void CApp::Split()
progressDialog.MainWindow = _window;
progressDialog.MainTitle = progressWindowTitle;
- progressDialog.MainAddTitle = title + L' ';
+ progressDialog.MainAddTitle = title;
+ progressDialog.MainAddTitle.Add_Space();
progressDialog.Sync.Set_TitleFileName(itemName);
spliter.FilePath = us2fs(srcPath + itemName);
- spliter.VolBasePath = us2fs(path + itemName);
+ spliter.VolBasePath = us2fs(path + srcPanel.GetItemName_for_Copy(index));
spliter.VolumeSizes = splitDialog.VolumeSizes;
// if (splitDialog.VolumeSizes.Size() == 0) return;
@@ -285,7 +286,7 @@ HRESULT CThreadCombine::ProcessVirt()
if (!outFile.Create(OutputPath, false))
{
HRESULT res = GetLastError();
- SetErrorPath1(OutputPath);
+ AddErrorPath(OutputPath);
return res;
}
@@ -304,7 +305,7 @@ HRESULT CThreadCombine::ProcessVirt()
if (!inFile.Open(nextName))
{
HRESULT res = GetLastError();
- SetErrorPath1(nextName);
+ AddErrorPath(nextName);
return res;
}
sync.Set_FilePath(fs2us(nextName));
@@ -314,7 +315,7 @@ HRESULT CThreadCombine::ProcessVirt()
if (!inFile.Read(buffer, kBufSize, processedSize))
{
HRESULT res = GetLastError();
- SetErrorPath1(nextName);
+ AddErrorPath(nextName);
return res;
}
if (processedSize == 0)
@@ -323,7 +324,7 @@ HRESULT CThreadCombine::ProcessVirt()
if (!outFile.Write(buffer, needSize, processedSize))
{
HRESULT res = GetLastError();
- SetErrorPath1(OutputPath);
+ AddErrorPath(OutputPath);
return res;
}
if (needSize != processedSize)
@@ -364,13 +365,13 @@ void CApp::Combine()
}
const UString itemName = srcPanel.GetItemName(index);
- UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index);
+ UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index);
UString path = srcPath;
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
CPanel &destPanel = Panels[destPanelIndex];
if (NumPanels > 1)
if (destPanel.IsFSFolder())
- path = destPanel._currentFolderPrefix;
+ path = destPanel.GetFsPath();
CVolSeqName volSeqName;
if (!volSeqName.ParseName(itemName))
@@ -408,7 +409,7 @@ void CApp::Combine()
UString info;
AddValuePair2(info, IDS_PROP_FILES, combiner.Names.Size(), combiner.TotalSize);
- info += L"\n";
+ info.Add_LF();
info += srcPath;
unsigned i;
@@ -425,7 +426,7 @@ void CApp::Combine()
CCopyDialog copyDialog;
copyDialog.Value = path;
LangString(IDS_COMBINE, copyDialog.Title);
- copyDialog.Title += ' ';
+ copyDialog.Title.Add_Space();
copyDialog.Title += srcPanel.GetItemRelPath(index);
LangString(IDS_COMBINE_TO, copyDialog.Static);
copyDialog.Info = info;
@@ -468,7 +469,8 @@ void CApp::Combine()
progressDialog.MainWindow = _window;
progressDialog.MainTitle = progressWindowTitle;
- progressDialog.MainAddTitle = title + L' ';
+ progressDialog.MainAddTitle = title;
+ progressDialog.MainAddTitle.Add_Space();
combiner.InputDirPrefix = us2fs(srcPath);
diff --git a/CPP/7zip/UI/FileManager/PluginInterface.h b/CPP/7zip/UI/FileManager/PluginInterface.h
index 3ce5fa8e..37654a03 100644
--- a/CPP/7zip/UI/FileManager/PluginInterface.h
+++ b/CPP/7zip/UI/FileManager/PluginInterface.h
@@ -11,7 +11,7 @@
PLUGIN_INTERFACE(IInitContextMenu, 0x00)
{
- STDMETHOD(InitContextMenu)(const wchar_t *folder, const wchar_t **names, UInt32 numFiles) PURE;
+ STDMETHOD(InitContextMenu)(const wchar_t *folder, const wchar_t * const *names, UInt32 numFiles) PURE;
};
PLUGIN_INTERFACE(IPluginOptionsCallback, 0x01)
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
index c9ca3942..231d0ace 100644
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
@@ -28,7 +28,7 @@ static const UINT kTimerElapse =
#ifdef UNDER_CE
500
#else
- 100
+ 200
#endif
;
@@ -104,13 +104,13 @@ HRESULT CProgressSync::CheckStop()
}
}
-HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const UString &fileName, bool isDir)
+HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir)
{
{
CRITICAL_LOCK
_totalFiles = numFiles;
_totalBytes = totalSize;
- _filePath = fileName;
+ _filePath = fs2us(fileName);
_isDir = isDir;
// _completedBytes = 0;
CHECK_STOP
@@ -118,10 +118,14 @@ HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const USt
return CheckStop();
}
-void CProgressSync::Set_NumFilesTotal(UInt64 val)
+HRESULT CProgressSync::Set_NumFilesTotal(UInt64 val)
{
- CRITICAL_LOCK
- _totalFiles = val;
+ {
+ CRITICAL_LOCK
+ _totalFiles = val;
+ CHECK_STOP
+ }
+ return CheckStop();
}
void CProgressSync::Set_NumBytesTotal(UInt64 val)
@@ -171,16 +175,34 @@ void CProgressSync::Set_TitleFileName(const UString &fileName)
CRITICAL_LOCK
_titleFileName = fileName;
}
+
void CProgressSync::Set_Status(const UString &s)
{
CRITICAL_LOCK
_status = s;
}
-void CProgressSync::Set_FilePath(const UString &path, bool isDir)
+HRESULT CProgressSync::Set_Status2(const UString &s, const wchar_t *path, bool isDir)
+{
+ {
+ CRITICAL_LOCK
+ _status = s;
+ if (path)
+ _filePath = path;
+ else
+ _filePath.Empty();
+ _isDir = isDir;
+ }
+ return CheckStop();
+}
+
+void CProgressSync::Set_FilePath(const wchar_t *path, bool isDir)
{
CRITICAL_LOCK
- _filePath = path;
+ if (path)
+ _filePath = path;
+ else
+ _filePath.Empty();
_isDir = isDir;
}
@@ -199,7 +221,7 @@ void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t
if (message && *message != 0 )
{
if (!s.IsEmpty())
- s += L'\n';
+ s.Add_LF();
s += message;
if (!s.IsEmpty() && s.Back() == L'\n')
s.DeleteBack();
@@ -633,7 +655,6 @@ static unsigned GetPower64(UInt64 val)
if (high == 0)
return GetPower32((UInt32)val);
return GetPower32(high) + 32;
-
}
static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider)
@@ -867,7 +888,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
s1 = _filePath;
else
{
- int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);
+ int slashPos = _filePath.ReverseFind_PathSepar();
if (slashPos >= 0)
{
s1.SetFrom(_filePath, slashPos + 1);
@@ -878,7 +899,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
}
ReduceString(s1, _numReduceSymbols);
ReduceString(s2, _numReduceSymbols);
- s1 += L'\n';
+ s1.Add_LF();
s1 += s2;
SetItemText(IDT_PROGRESS_FILE_NAME, s1);
}
@@ -1025,22 +1046,22 @@ void CProgressDialog::SetTitleText()
if (Sync.Get_Paused())
{
s += _paused_String;
- s += L' ';
+ s.Add_Space();
}
if (IS_DEFINED_VAL(_prevPercentValue))
{
- wchar_t temp[32];
+ char temp[32];
ConvertUInt64ToString(_prevPercentValue, temp);
- s += temp;
+ s.AddAscii(temp);
s += L'%';
}
if (!_foreground)
{
- s += L' ';
+ s.Add_Space();
s += _backgrounded_String;
}
- s += L' ';
+ s.Add_Space();
#ifndef _SFX
{
unsigned len = s.Len();
@@ -1055,7 +1076,7 @@ void CProgressDialog::SetTitleText()
{
UString fileName = _titleFileName;
ReduceString(fileName, kTitleFileNameSizeLimit);
- s += L' ';
+ s.Add_Space();
s += fileName;
}
SetText(s);
@@ -1239,7 +1260,7 @@ static void AddMessageToString(UString &dest, const UString &src)
if (!src.IsEmpty())
{
if (!dest.IsEmpty())
- dest += L'\n';
+ dest.Add_LF();
dest += src;
}
}
@@ -1266,8 +1287,15 @@ void CProgressThreadVirt::Process()
m = HResultToMessage(Result);
}
AddMessageToString(m, FinalMessage.ErrorMessage.Message);
- AddMessageToString(m, fs2us(ErrorPath1));
- AddMessageToString(m, fs2us(ErrorPath2));
+
+ {
+ FOR_VECTOR(i, ErrorPaths)
+ {
+ if (i >= 32)
+ break;
+ AddMessageToString(m, fs2us(ErrorPaths[i]));
+ }
+ }
CProgressSync &sync = ProgressDialog.Sync;
NSynchronization::CCriticalSectionLock lock(sync._cs);
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h
index ea1559a7..03f836da 100644
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.h
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h
@@ -80,9 +80,9 @@ public:
}
HRESULT CheckStop();
- HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const UString &fileName, bool isDir = false);
+ HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false);
- void Set_NumFilesTotal(UInt64 val);
+ HRESULT Set_NumFilesTotal(UInt64 val);
void Set_NumBytesTotal(UInt64 val);
void Set_NumFilesCur(UInt64 val);
HRESULT Set_NumBytesCur(const UInt64 *val);
@@ -91,7 +91,8 @@ public:
void Set_TitleFileName(const UString &fileName);
void Set_Status(const UString &s);
- void Set_FilePath(const UString &path, bool isDir = false);
+ HRESULT Set_Status2(const UString &s, const wchar_t *path, bool isDir = false);
+ void Set_FilePath(const wchar_t *path, bool isDir = false);
void AddError_Message(const wchar_t *message);
void AddError_Message_Name(const wchar_t *message, const wchar_t *name);
@@ -274,9 +275,8 @@ public:
class CProgressThreadVirt
{
- FString ErrorPath1;
- FString ErrorPath2;
protected:
+ FStringVector ErrorPaths;
CProgressFinalMessage FinalMessage;
// error if any of HRESULT, ErrorMessage, ErrorPath
@@ -299,8 +299,7 @@ public:
return 0;
}
- void SetErrorPath1(const FString &path) { ErrorPath1 = path; }
- void SetErrorPath2(const FString &path) { ErrorPath2 = path; }
+ void AddErrorPath(const FString &path) { ErrorPaths.Add(path); }
HRESULT Create(const UString &title, HWND parentWindow = 0);
CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
diff --git a/CPP/7zip/UI/FileManager/PropertyName.rc b/CPP/7zip/UI/FileManager/PropertyName.rc
index 43c4584f..8b8c7899 100644
--- a/CPP/7zip/UI/FileManager/PropertyName.rc
+++ b/CPP/7zip/UI/FileManager/PropertyName.rc
@@ -94,4 +94,6 @@ BEGIN
IDS_PROP_HARD_LINK "Hard Link"
IDS_PROP_INODE "iNode"
IDS_PROP_STREAM_ID "Stream ID"
+ IDS_PROP_READ_ONLY "Read-only"
+ IDS_PROP_OUT_NAME "Out Name"
END
diff --git a/CPP/7zip/UI/FileManager/PropertyNameRes.h b/CPP/7zip/UI/FileManager/PropertyNameRes.h
index 199aa6da..3696ed2e 100644
--- a/CPP/7zip/UI/FileManager/PropertyNameRes.h
+++ b/CPP/7zip/UI/FileManager/PropertyNameRes.h
@@ -90,3 +90,5 @@
#define IDS_PROP_HARD_LINK 1090
#define IDS_PROP_INODE 1091
#define IDS_PROP_STREAM_ID 1092
+#define IDS_PROP_READ_ONLY 1093
+#define IDS_PROP_OUT_NAME 1094
diff --git a/CPP/7zip/UI/FileManager/RegistryAssociations.cpp b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
index ee944350..93ba40c2 100644
--- a/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
@@ -86,8 +86,7 @@ bool CShellExtInfo::ReadFromRegistry(HKEY hkey, const CSysString &ext)
bool CShellExtInfo::IsIt7Zip() const
{
- UString s = GetUnicodeString(k7zipPrefix);
- return MyStringCompareNoCase_N(GetUnicodeString(ProgramKey), s, s.Len()) == 0;
+ return IsString1PrefixedByString2_NoCase(GetUnicodeString(ProgramKey), GetUnicodeString(k7zipPrefix));
}
LONG DeleteShellExtensionInfo(HKEY hkey, const CSysString &ext)
diff --git a/CPP/7zip/UI/FileManager/RootFolder.cpp b/CPP/7zip/UI/FileManager/RootFolder.cpp
index 234c51dd..c5b57821 100644
--- a/CPP/7zip/UI/FileManager/RootFolder.cpp
+++ b/CPP/7zip/UI/FileManager/RootFolder.cpp
@@ -10,11 +10,25 @@
#include "../../PropID.h"
+#if defined(_WIN32) && !defined(UNDER_CE)
+#define USE_WIN_PATHS
+#endif
+
+static const unsigned kNumRootFolderItems =
+ #ifdef USE_WIN_PATHS
+ 4
+ #else
+ 1
+ #endif
+ ;
+
+
#include "FSFolder.h"
#include "LangUtils.h"
-#ifndef UNDER_CE
+#ifdef USE_WIN_PATHS
#include "NetFolder.h"
#include "FSDrives.h"
+#include "AltStreamsFolder.h"
#endif
#include "RootFolder.h"
#include "SysIconUtils.h"
@@ -30,10 +44,10 @@ static const PROPID kProps[] =
UString RootFolder_GetName_Computer(int &iconIndex)
{
- #ifdef UNDER_CE
- GetRealIconIndex(FTEXT("\\"), FILE_ATTRIBUTE_DIRECTORY, iconIndex);
- #else
+ #ifdef USE_WIN_PATHS
iconIndex = GetIconIndexForCSIDL(CSIDL_DRIVES);
+ #else
+ GetRealIconIndex(FSTRING_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY, iconIndex);
#endif
return LangString(IDS_COMPUTER);
}
@@ -53,21 +67,21 @@ UString RootFolder_GetName_Documents(int &iconIndex)
enum
{
ROOT_INDEX_COMPUTER = 0
- #ifndef UNDER_CE
+ #ifdef USE_WIN_PATHS
, ROOT_INDEX_DOCUMENTS
, ROOT_INDEX_NETWORK
, ROOT_INDEX_VOLUMES
#endif
};
-#ifndef UNDER_CE
+#ifdef USE_WIN_PATHS
static const wchar_t *kVolPrefix = L"\\\\.";
#endif
void CRootFolder::Init()
{
_names[ROOT_INDEX_COMPUTER] = RootFolder_GetName_Computer(_iconIndices[ROOT_INDEX_COMPUTER]);
- #ifndef UNDER_CE
+ #ifdef USE_WIN_PATHS
_names[ROOT_INDEX_DOCUMENTS] = RootFolder_GetName_Documents(_iconIndices[ROOT_INDEX_DOCUMENTS]);
_names[ROOT_INDEX_NETWORK] = RootFolder_GetName_Network(_iconIndices[ROOT_INDEX_NETWORK]);
_names[ROOT_INDEX_VOLUMES] = kVolPrefix;
@@ -124,8 +138,7 @@ UString GetMyDocsPath()
us = GetUnicodeString(s2);
}
#endif
- if (us.Len() > 0 && us.Back() != WCHAR_PATH_SEPARATOR)
- us += WCHAR_PATH_SEPARATOR;
+ NFile::NName::NormalizeDirPathPrefix(us);
return us;
}
@@ -133,14 +146,8 @@ STDMETHODIMP CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolde
{
*resultFolder = NULL;
CMyComPtr<IFolderFolder> subFolder;
- #ifdef UNDER_CE
- if (index == ROOT_INDEX_COMPUTER)
- {
- NFsFolder::CFSFolder *fsFolder = new NFsFolder::CFSFolder;
- subFolder = fsFolder;
- fsFolder->InitToRoot();
- }
- #else
+
+ #ifdef USE_WIN_PATHS
if (index == ROOT_INDEX_COMPUTER || index == ROOT_INDEX_VOLUMES)
{
CFSDrives *fsDrivesSpec = new CFSDrives;
@@ -160,12 +167,20 @@ STDMETHODIMP CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolde
{
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
subFolder = fsFolderSpec;
- RINOK(fsFolderSpec->Init(us2fs(s), NULL));
+ RINOK(fsFolderSpec->Init(us2fs(s)));
}
}
+ #else
+ if (index == ROOT_INDEX_COMPUTER)
+ {
+ NFsFolder::CFSFolder *fsFolder = new NFsFolder::CFSFolder;
+ subFolder = fsFolder;
+ fsFolder->InitToRoot();
+ }
#endif
else
return E_INVALIDARG;
+
*resultFolder = subFolder.Detach();
return S_OK;
}
@@ -185,6 +200,7 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
*resultFolder = 0;
UString name2 = name;
name2.Trim();
+
if (name2.IsEmpty())
{
CRootFolder *rootFolderSpec = new CRootFolder;
@@ -193,21 +209,25 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
*resultFolder = rootFolder.Detach();
return S_OK;
}
- for (int i = 0; i < kNumRootFolderItems; i++)
+
+ for (unsigned i = 0; i < kNumRootFolderItems; i++)
if (AreEqualNames(name2, _names[i]))
return BindToFolder((UInt32)i, resultFolder);
- #ifdef UNDER_CE
- if (name2 == L"\\")
- return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder);
- #else
+
+ #ifdef USE_WIN_PATHS
if (AreEqualNames(name2, L"My Documents") ||
AreEqualNames(name2, L"Documents"))
return BindToFolder((UInt32)ROOT_INDEX_DOCUMENTS, resultFolder);
+ #else
+ if (name2 == WSTRING_PATH_SEPARATOR)
+ return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder);
#endif
+
if (AreEqualNames(name2, L"My Computer") ||
AreEqualNames(name2, L"Computer"))
return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder);
- if (name2 == UString(WCHAR_PATH_SEPARATOR))
+
+ if (name2 == WSTRING_PATH_SEPARATOR)
{
CMyComPtr<IFolderFolder> subFolder = this;
*resultFolder = subFolder.Detach();
@@ -219,7 +239,7 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
CMyComPtr<IFolderFolder> subFolder;
- #ifndef UNDER_CE
+ #ifdef USE_WIN_PATHS
if (name2.IsPrefixedBy(kVolPrefix))
{
CFSDrives *folderSpec = new CFSDrives;
@@ -232,16 +252,22 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
subFolder = folderSpec;
folderSpec->Init(false, true);
}
+ else if (name2.Back() == ':')
+ {
+ NAltStreamsFolder::CAltStreamsFolder *folderSpec = new NAltStreamsFolder::CAltStreamsFolder;
+ subFolder = folderSpec;
+ if (folderSpec->Init(us2fs(name2)) != S_OK)
+ return E_INVALIDARG;
+ }
else
#endif
{
- if (name2[name2.Len() - 1] != WCHAR_PATH_SEPARATOR)
- name2 += WCHAR_PATH_SEPARATOR;
+ NFile::NName::NormalizeDirPathPrefix(name2);
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
subFolder = fsFolderSpec;
- if (fsFolderSpec->Init(us2fs(name2), 0) != S_OK)
+ if (fsFolderSpec->Init(us2fs(name2)) != S_OK)
{
- #ifndef UNDER_CE
+ #ifdef USE_WIN_PATHS
if (name2[0] == WCHAR_PATH_SEPARATOR)
{
CNetFolder *netFolderSpec = new CNetFolder;
@@ -253,6 +279,7 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
return E_INVALIDARG;
}
}
+
*resultFolder = subFolder.Detach();
return S_OK;
}
@@ -267,11 +294,11 @@ IMP_IFolderFolder_Props(CRootFolder)
STDMETHODIMP CRootFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
{
- NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ NCOM::CPropVariant prop;
+ switch (propID)
{
- case kpidType: prop = L"RootFolder"; break;
- case kpidPath: prop = L""; break;
+ case kpidType: prop = "RootFolder"; break;
+ case kpidPath: prop = ""; break;
}
prop.Detach(value);
return S_OK;
diff --git a/CPP/7zip/UI/FileManager/RootFolder.h b/CPP/7zip/UI/FileManager/RootFolder.h
index e9ef2d8c..e2537837 100644
--- a/CPP/7zip/UI/FileManager/RootFolder.h
+++ b/CPP/7zip/UI/FileManager/RootFolder.h
@@ -7,21 +7,15 @@
#include "IFolder.h"
-const int kNumRootFolderItems =
- #ifdef UNDER_CE
- 1
- #else
- 4
- #endif
- ;
+const unsigned kNumRootFolderItems_Max = 4;
class CRootFolder:
public IFolderFolder,
public IFolderGetSystemIconIndex,
public CMyUnknownImp
{
- UString _names[kNumRootFolderItems];
- int _iconIndices[kNumRootFolderItems];
+ UString _names[kNumRootFolderItems_Max];
+ int _iconIndices[kNumRootFolderItems_Max];
public:
MY_UNKNOWN_IMP1(IFolderGetSystemIconIndex)
diff --git a/CPP/7zip/UI/FileManager/SettingsPage.rc b/CPP/7zip/UI/FileManager/SettingsPage.rc
index 3e4a611e..c724fcb7 100644
--- a/CPP/7zip/UI/FileManager/SettingsPage.rc
+++ b/CPP/7zip/UI/FileManager/SettingsPage.rc
@@ -1,7 +1,7 @@
#include "SettingsPageRes.h"
#include "../../GuiCommon.rc"
-#define xc 200
+#define xc 240
#define yc 120
IDD_SETTINGS MY_PAGE
diff --git a/CPP/7zip/UI/FileManager/SplitDialog.cpp b/CPP/7zip/UI/FileManager/SplitDialog.cpp
index d35d76c9..d7d14d7c 100644
--- a/CPP/7zip/UI/FileManager/SplitDialog.cpp
+++ b/CPP/7zip/UI/FileManager/SplitDialog.cpp
@@ -38,7 +38,7 @@ bool CSplitDialog::OnInit()
{
UString title;
GetText(title);
- title += L' ';
+ title.Add_Space();
title += FilePath;
SetText(title);
}
diff --git a/CPP/7zip/UI/FileManager/StringUtils.cpp b/CPP/7zip/UI/FileManager/StringUtils.cpp
index fb38a735..10056549 100644
--- a/CPP/7zip/UI/FileManager/StringUtils.cpp
+++ b/CPP/7zip/UI/FileManager/StringUtils.cpp
@@ -54,14 +54,17 @@ void SplitString(const UString &srcString, UStringVector &destStrings)
destStrings.Add(s);
}
+/*
UString JoinStrings(const UStringVector &srcStrings)
{
+
UString s;
FOR_VECTOR (i, srcStrings)
{
if (i != 0)
- s += L' ';
+ s.Add_Space();
s += srcStrings[i];
}
return s;
}
+*/
diff --git a/CPP/7zip/UI/FileManager/SystemPage.cpp b/CPP/7zip/UI/FileManager/SystemPage.cpp
index a40c4e3d..a7f0c3fb 100644
--- a/CPP/7zip/UI/FileManager/SystemPage.cpp
+++ b/CPP/7zip/UI/FileManager/SystemPage.cpp
@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include "../../../Common/StringConvert.h"
+#include "../../../Common/Defs.h"
#include "../../../Windows/DLL.h"
#include "../../../Windows/ErrorMsg.h"
@@ -16,6 +17,10 @@
using namespace NWindows;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
static const UInt32 kLangIDs[] =
{
IDT_SYSTEM_ASSOCIATE
@@ -48,8 +53,8 @@ int CSystemPage::AddIcon(const UString &iconPath, int iconIndex)
// we expand path from REG_EXPAND_SZ registry item.
UString path;
DWORD size = MAX_PATH + 10;
- DWORD needLen = ::ExpandEnvironmentStringsW(iconPath, path.GetBuffer((int)size + 1), size);
- path.ReleaseBuffer();
+ DWORD needLen = ::ExpandEnvironmentStringsW(iconPath, path.GetBuf(size + 2), size);
+ path.ReleaseBuf_CalcLen(size);
if (needLen == 0 || needLen >= size)
path = iconPath;
int num = ExtractIconExW(path, iconIndex, NULL, &hicon, 1);
@@ -140,32 +145,49 @@ bool CSystemPage::OnInit()
_listView.InsertColumn(0, LangString(IDS_PROP_FILE_TYPE), 72);
- CSysString s;
+ UString s;
#if NUM_EXT_GROUPS == 1
- s = TEXT("Program");
+ s.SetFromAscii("Program");
#else
#ifndef UNDER_CE
- DWORD size = 256;
- BOOL res = GetUserName(s.GetBuffer(size), &size);
- s.ReleaseBuffer();
+ const unsigned kSize = 256;
+ BOOL res;
+
+ DWORD size = kSize;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ AString s2;
+ res = GetUserNameA(s2.GetBuf(size), &size);
+ s2.ReleaseBuf_CalcLen(MyMin((unsigned)size, kSize));
+ s = GetUnicodeString(s2);
+ }
+ else
+ #endif
+ {
+ res = GetUserNameW(s.GetBuf(size), &size);
+ s.ReleaseBuf_CalcLen(MyMin((unsigned)size, kSize));
+ }
+
if (!res)
#endif
- s = TEXT("Current User");
+ s.SetFromAscii("Current User");
#endif
- LVCOLUMN ci;
+ LV_COLUMNW ci;
ci.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
- ci.cx = 100;
- ci.pszText = (TCHAR *)(const TCHAR *)s;
- ci.iSubItem = 1;
+ ci.cx = 128;
ci.fmt = LVCFMT_CENTER;
+ ci.pszText = (WCHAR *)(const WCHAR *)s;
+ ci.iSubItem = 1;
_listView.InsertColumn(1, &ci);
#if NUM_EXT_GROUPS > 1
{
+ LangString(IDS_SYSTEM_ALL_USERS, s);
+ ci.pszText = (WCHAR *)(const WCHAR *)s;
ci.iSubItem = 2;
- ci.pszText = (LPTSTR)TEXT("All Users");
_listView.InsertColumn(2, &ci);
}
#endif
diff --git a/CPP/7zip/UI/FileManager/SystemPage.h b/CPP/7zip/UI/FileManager/SystemPage.h
index 0bf6aae7..d38bd1b0 100644
--- a/CPP/7zip/UI/FileManager/SystemPage.h
+++ b/CPP/7zip/UI/FileManager/SystemPage.h
@@ -40,7 +40,7 @@ struct CModifiedExtInfo: public NRegistryAssoc::CShellExtInfo
Other = true;
if (IsIt7Zip())
{
- Other7Zip = !iconPath.IsEqualToNoCase(IconPath);
+ Other7Zip = !iconPath.IsEqualTo_NoCase(IconPath);
if (!Other7Zip)
{
State = kExtState_7Zip;
diff --git a/CPP/7zip/UI/FileManager/SystemPage.rc b/CPP/7zip/UI/FileManager/SystemPage.rc
index 42e72cf1..3bb143a4 100644
--- a/CPP/7zip/UI/FileManager/SystemPage.rc
+++ b/CPP/7zip/UI/FileManager/SystemPage.rc
@@ -1,18 +1,18 @@
#include "SystemPageRes.h"
#include "../../GuiCommon.rc"
-#define xc 200
-#define yc 250
+#define xc 240
+#define yc 252
IDD_SYSTEM DIALOG 0, 0, xs, ys MY_PAGE_STYLE MY_FONT
CAPTION "System"
BEGIN
LTEXT "Associate 7-Zip with:", IDT_SYSTEM_ASSOCIATE, m, m, xc, 8
- PUSHBUTTON "+", IDB_SYSTEM_CURRENT, 72, m + 12, 40, bys
- PUSHBUTTON "+", IDB_SYSTEM_ALL, 140, m + 12, 40, bys
+ PUSHBUTTON "+", IDB_SYSTEM_CURRENT, 80, m + 12, 40, bys
+ PUSHBUTTON "+", IDB_SYSTEM_ALL, 166, m + 12, 40, bys
CONTROL "List1", IDL_SYSTEM_ASSOCIATE, "SysListView32",
LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,
- m, m + 32, xc, (yc - m - 32 - 1)
+ m, m + 32, xc, (yc - 32)
END
#ifdef UNDER_CE
@@ -32,7 +32,12 @@ BEGIN
PUSHBUTTON "+", IDB_SYSTEM_CURRENT, 60, m + 12, 40, bys
CONTROL "List1", IDL_SYSTEM_ASSOCIATE, "SysListView32",
LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,
- m, m + 32, xc, (yc - m - 32 - 1 - 8)
+ m, m + 32, xc, (yc - 32)
END
#endif
+
+STRINGTABLE
+BEGIN
+ IDS_SYSTEM_ALL_USERS "All users"
+END
diff --git a/CPP/7zip/UI/FileManager/SystemPageRes.h b/CPP/7zip/UI/FileManager/SystemPageRes.h
index edc576f7..c8944482 100644
--- a/CPP/7zip/UI/FileManager/SystemPageRes.h
+++ b/CPP/7zip/UI/FileManager/SystemPageRes.h
@@ -2,6 +2,7 @@
#define IDD_SYSTEM_2 12200
#define IDT_SYSTEM_ASSOCIATE 2201
+#define IDS_SYSTEM_ALL_USERS 2202
#define IDL_SYSTEM_ASSOCIATE 100
#define IDB_SYSTEM_CURRENT 101
diff --git a/CPP/7zip/UI/FileManager/TextPairs.cpp b/CPP/7zip/UI/FileManager/TextPairs.cpp
index 354b479f..0fac2506 100644
--- a/CPP/7zip/UI/FileManager/TextPairs.cpp
+++ b/CPP/7zip/UI/FileManager/TextPairs.cpp
@@ -185,6 +185,6 @@ void CPairsStorage::SaveToString(UString &text) const
text += L' ';
text += pair.Value;
text += L'\x0D';
- text += L'\n';
+ text.Add_LF();
}
}
diff --git a/CPP/7zip/UI/FileManager/TextPairs.h b/CPP/7zip/UI/FileManager/TextPairs.h
index d27cd97c..0a71d044 100644
--- a/CPP/7zip/UI/FileManager/TextPairs.h
+++ b/CPP/7zip/UI/FileManager/TextPairs.h
@@ -19,7 +19,7 @@ class CPairsStorage
int FindID(const UString &id) const;
void Sort();
public:
- void Clear() { Pairs.Clear(); };
+ void Clear() { Pairs.Clear(); }
bool ReadFromString(const UString &text);
void SaveToString(UString &text) const;
diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.cpp b/CPP/7zip/UI/FileManager/UpdateCallback100.cpp
index 4141f01d..67e70fb7 100644
--- a/CPP/7zip/UI/FileManager/UpdateCallback100.cpp
+++ b/CPP/7zip/UI/FileManager/UpdateCallback100.cpp
@@ -2,15 +2,29 @@
#include "StdAfx.h"
-#include "PasswordDialog.h"
+#include "../../../Windows/ErrorMsg.h"
+
+#include "../GUI/resource3.h"
+
+#include "LangUtils.h"
#include "UpdateCallback100.h"
-STDMETHODIMP CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles)
+STDMETHODIMP CUpdateCallback100Imp::ScanProgress(UInt64 /* numFolders */, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 /* isDir */)
+{
+ return ProgressDialog->Sync.ScanProgress(numFiles, totalSize, us2fs(path));
+}
+
+STDMETHODIMP CUpdateCallback100Imp::ScanError(const wchar_t *path, HRESULT errorCode)
{
- ProgressDialog->Sync.Set_NumFilesTotal(numFiles);
+ ProgressDialog->Sync.AddError_Code_Name(errorCode, path);
return S_OK;
}
+STDMETHODIMP CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles)
+{
+ return ProgressDialog->Sync.Set_NumFilesTotal(numFiles);
+}
+
STDMETHODIMP CUpdateCallback100Imp::SetTotal(UInt64 size)
{
ProgressDialog->Sync.Set_NumBytesTotal(size);
@@ -30,35 +44,63 @@ STDMETHODIMP CUpdateCallback100Imp::SetRatioInfo(const UInt64 *inSize, const UIn
STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *name)
{
- ProgressDialog->Sync.Set_FilePath(name);
- return S_OK;
+ return SetOperation_Base(NUpdateNotifyOp::kAdd, name, false);
}
STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t *name)
{
- ProgressDialog->Sync.Set_FilePath(name);
- return S_OK;
+ return SetOperation_Base(NUpdateNotifyOp::kDelete, name, false);
}
STDMETHODIMP CUpdateCallback100Imp::OperationResult(Int32 /* operationResult */)
{
- ProgressDialog->Sync.Set_NumFilesCur(++_numFiles);
+ ProgressDialog->Sync.Set_NumFilesCur(++NumFiles);
+ return S_OK;
+}
+
+void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s);
+
+HRESULT CUpdateCallback100Imp::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name)
+{
+ if (opRes != NArchive::NExtract::NOperationResult::kOK)
+ {
+ UString s;
+ SetExtractErrorMessage(opRes, isEncrypted, name, s);
+ ProgressDialog->Sync.AddError_Message(s);
+ }
return S_OK;
}
+HRESULT CUpdateCallback100Imp::ReportUpdateOperation(UInt32 notifyOp, const wchar_t *name, Int32 isDir)
+{
+ return SetOperation_Base(notifyOp, name, IntToBool(isDir));
+}
+
STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message)
{
ProgressDialog->Sync.AddError_Message(message);
return S_OK;
}
+HRESULT CUpdateCallback100Imp::OpenFileError(const wchar_t *path, HRESULT errorCode)
+{
+ ProgressDialog->Sync.AddError_Code_Name(errorCode, path);
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::ReadingFileError(const wchar_t *path, HRESULT errorCode)
+{
+ ProgressDialog->Sync.AddError_Code_Name(errorCode, path);
+ return S_OK;
+}
+
STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
{
*password = NULL;
- *passwordIsDefined = BoolToInt(_passwordIsDefined);
- if (!_passwordIsDefined)
+ *passwordIsDefined = BoolToInt(PasswordIsDefined);
+ if (!PasswordIsDefined)
return S_OK;
- return StringToBstr(_password, password);
+ return StringToBstr(Password, password);
}
STDMETHODIMP CUpdateCallback100Imp::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
@@ -74,14 +116,9 @@ STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UInt64 * /* files */, con
STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)
{
*password = NULL;
- if (!_passwordIsDefined)
+ if (!PasswordIsDefined)
{
- CPasswordDialog dialog;
- ProgressDialog->WaitCreating();
- if (dialog.Create(*ProgressDialog) != IDOK)
- return E_ABORT;
- _password = dialog.Password;
- _passwordIsDefined = true;
+ RINOK(ShowAskPasswordDialog())
}
- return StringToBstr(_password, password);
+ return StringToBstr(Password, password);
}
diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.h b/CPP/7zip/UI/FileManager/UpdateCallback100.h
index 944453a1..7cbc11e3 100644
--- a/CPP/7zip/UI/FileManager/UpdateCallback100.h
+++ b/CPP/7zip/UI/FileManager/UpdateCallback100.h
@@ -9,26 +9,29 @@
#include "../Agent/IFolderArchive.h"
+#include "../GUI/UpdateCallbackGUI2.h"
+
#include "ProgressDialog2.h"
class CUpdateCallback100Imp:
public IFolderArchiveUpdateCallback,
+ public IFolderArchiveUpdateCallback2,
+ public IFolderScanProgress,
public ICryptoGetTextPassword2,
public ICryptoGetTextPassword,
public IArchiveOpenCallback,
public ICompressProgressInfo,
+ public CUpdateCallbackGUI2,
public CMyUnknownImp
{
- bool _passwordIsDefined;
- UString _password;
- UInt64 _numFiles;
public:
- CProgressDialog *ProgressDialog;
- CUpdateCallback100Imp(): ProgressDialog(0) {}
+ // CUpdateCallback100Imp() {}
- MY_UNKNOWN_IMP5(
+ MY_UNKNOWN_IMP7(
IFolderArchiveUpdateCallback,
+ IFolderArchiveUpdateCallback2,
+ IFolderScanProgress,
ICryptoGetTextPassword2,
ICryptoGetTextPassword,
IArchiveOpenCallback,
@@ -37,18 +40,13 @@ public:
INTERFACE_IProgress(;)
INTERFACE_IArchiveOpenCallback(;)
INTERFACE_IFolderArchiveUpdateCallback(;)
+ INTERFACE_IFolderArchiveUpdateCallback2(;)
+ INTERFACE_IFolderScanProgress(;)
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
-
- void Init(bool passwordIsDefined, const UString &password)
- {
- _passwordIsDefined = passwordIsDefined;
- _password = password;
- _numFiles = 0;
- }
};
#endif
diff --git a/CPP/7zip/UI/FileManager/ViewSettings.cpp b/CPP/7zip/UI/FileManager/ViewSettings.cpp
index 9688a4a5..2818d0f3 100644
--- a/CPP/7zip/UI/FileManager/ViewSettings.cpp
+++ b/CPP/7zip/UI/FileManager/ViewSettings.cpp
@@ -302,7 +302,7 @@ void ReadCopyHistory(UStringVector &folders)
void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s)
{
for (unsigned i = 0; i < list.Size();)
- if (s.IsEqualToNoCase(list[i]))
+ if (s.IsEqualTo_NoCase(list[i]))
list.Delete(i);
else
i++;
diff --git a/CPP/7zip/UI/FileManager/makefile b/CPP/7zip/UI/FileManager/makefile
index 96ae902f..d9e81780 100644
--- a/CPP/7zip/UI/FileManager/makefile
+++ b/CPP/7zip/UI/FileManager/makefile
@@ -97,6 +97,7 @@ EXPLORER_OBJS = \
GUI_OBJS = \
$O\HashGUI.obj \
+ $O\UpdateCallbackGUI2.obj \
COMPRESS_OBJS = \
$O\CopyCoder.obj \
diff --git a/CPP/7zip/UI/FileManager/resource.h b/CPP/7zip/UI/FileManager/resource.h
index 55af3555..23e64edc 100644
--- a/CPP/7zip/UI/FileManager/resource.h
+++ b/CPP/7zip/UI/FileManager/resource.h
@@ -45,6 +45,7 @@
#define IDM_CREATE_FILE 556
// #define IDM_EXIT 557
#define IDM_LINK 558
+#define IDM_ALT_STREAMS 559
#define IDM_SELECT_ALL 600
#define IDM_DESELECT_ALL 601
diff --git a/CPP/7zip/UI/FileManager/resource.rc b/CPP/7zip/UI/FileManager/resource.rc
index 61cf33e8..fb57e4f0 100644
--- a/CPP/7zip/UI/FileManager/resource.rc
+++ b/CPP/7zip/UI/FileManager/resource.rc
@@ -48,6 +48,7 @@ BEGIN
MENUITEM "Create File\tCtrl+N", IDM_CREATE_FILE
MENUITEM SEPARATOR
MENUITEM "&Link...", IDM_LINK
+ MENUITEM "&Alternate streams", IDM_ALT_STREAMS
MENUITEM SEPARATOR
MENUITEM "E&xit\tAlt+F4", IDCLOSE
END
@@ -252,5 +253,6 @@ END
#include "SplitDialog.rc"
#include "SystemPage.rc"
#include "../GUI/Extract.rc"
+#include "../GUI/resource3.rc"
#include "../Explorer/resource2.rc"
#include "resourceGui.rc"