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>2021-07-23 01:00:14 +0300
committerKornel <kornel@geekhood.net>2021-07-23 01:00:14 +0300
commit585698650f7257d2cefa6a3a2a49d5bbe84fd9b2 (patch)
tree8900be42e892a440bbd1063804b0557288c2f97f /CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
parent4a960640a340a848a2d2c27f19b339c2c3d3f734 (diff)
21.0221.02
Diffstat (limited to 'CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp')
-rw-r--r--CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp232
1 files changed, 203 insertions, 29 deletions
diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
index 4e964628..a7873fe5 100644
--- a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
+++ b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
@@ -8,10 +8,14 @@
#include "../../../Windows/Thread.h"
#include "../Agent/Agent.h"
+#include "../GUI/ExtractRes.h"
+#include "FileFolderPluginOpen.h"
+#include "FormatUtils.h"
#include "LangUtils.h"
#include "OpenCallback.h"
#include "PluginLoader.h"
+#include "PropertyName.h"
#include "RegistryPlugins.h"
using namespace NWindows;
@@ -69,18 +73,165 @@ static void SplitNameToPureNameAndExtension(const FString &fullName,
{
pureName.SetFrom(fullName, index);
extensionDelimiter = '.';
- extension = fullName.Ptr(index + 1);
+ extension = fullName.Ptr((unsigned)index + 1);
}
}
-HRESULT OpenFileFolderPlugin(
- IInStream *inStream,
- const FString &path,
- const UString &arcFormat,
- HMODULE *module,
- IFolderFolder **resultFolder,
- HWND parentWindow,
- bool &encrypted, UString &password)
+
+struct CArcLevelInfo
+{
+ UString Error;
+ UString Path;
+ UString Type;
+ UString ErrorType;
+ UString ErrorFlags;
+};
+
+
+struct CArcLevelsInfo
+{
+ CObjectVector<CArcLevelInfo> Levels; // LastLevel Is NON-OPEN
+};
+
+
+UString GetOpenArcErrorMessage(UInt32 errorFlags);
+
+
+static void GetFolderLevels(CMyComPtr<IFolderFolder> &folder, CArcLevelsInfo &levels)
+{
+ levels.Levels.Clear();
+
+ CMyComPtr<IGetFolderArcProps> getFolderArcProps;
+ folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps);
+
+ if (!getFolderArcProps)
+ return;
+ CMyComPtr<IFolderArcProps> arcProps;
+ getFolderArcProps->GetFolderArcProps(&arcProps);
+ if (!arcProps)
+ return;
+
+ UInt32 numLevels;
+ if (arcProps->GetArcNumLevels(&numLevels) != S_OK)
+ numLevels = 0;
+
+ for (UInt32 level = 0; level <= numLevels; level++)
+ {
+ const PROPID propIDs[] = { kpidError, kpidPath, kpidType, kpidErrorType };
+
+ CArcLevelInfo lev;
+
+ for (Int32 i = 0; i < 4; i++)
+ {
+ CMyComBSTR name;
+ NCOM::CPropVariant prop;
+ if (arcProps->GetArcProp(level, propIDs[i], &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_EMPTY)
+ {
+ UString *s = NULL;
+ switch (propIDs[i])
+ {
+ case kpidError: s = &lev.Error; break;
+ case kpidPath: s = &lev.Path; break;
+ case kpidType: s = &lev.Type; break;
+ case kpidErrorType: s = &lev.ErrorType; break;
+ }
+ *s = (prop.vt == VT_BSTR) ? prop.bstrVal : L"?";
+ }
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ if (arcProps->GetArcProp(level, kpidErrorFlags, &prop) == S_OK)
+ {
+ UInt32 flags = GetOpenArcErrorFlags(prop);
+ if (flags != 0)
+ lev.ErrorFlags = GetOpenArcErrorMessage(flags);
+ }
+ }
+
+ levels.Levels.Add(lev);
+ }
+}
+
+static UString GetBracedType(const wchar_t *type)
+{
+ UString s ('[');
+ s += type;
+ s += ']';
+ return s;
+}
+
+static void GetFolderError(CMyComPtr<IFolderFolder> &folder, UString &open_Errors, UString &nonOpen_Errors)
+{
+ CArcLevelsInfo levs;
+ GetFolderLevels(folder, levs);
+ open_Errors.Empty();
+ nonOpen_Errors.Empty();
+
+ FOR_VECTOR (i, levs.Levels)
+ {
+ bool isNonOpenLevel = (i == 0);
+ const CArcLevelInfo &lev = levs.Levels[levs.Levels.Size() - 1 - i];
+
+ UString m;
+
+ if (!lev.ErrorType.IsEmpty())
+ {
+ m = MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(lev.ErrorType));
+ if (!isNonOpenLevel)
+ {
+ m.Add_LF();
+ m += MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(lev.Type));
+ }
+ }
+
+ if (!lev.Error.IsEmpty())
+ {
+ if (!m.IsEmpty())
+ m.Add_LF();
+ m += GetBracedType(lev.Type);
+ m += " : ";
+ m += GetNameOfProperty(kpidError, L"Error");
+ m += " : ";
+ m += lev.Error;
+ }
+
+ if (!lev.ErrorFlags.IsEmpty())
+ {
+ if (!m.IsEmpty())
+ m.Add_LF();
+ m += GetNameOfProperty(kpidErrorFlags, L"Errors");
+ m += ": ";
+ m += lev.ErrorFlags;
+ }
+
+ if (!m.IsEmpty())
+ {
+ if (isNonOpenLevel)
+ {
+ UString &s = nonOpen_Errors;
+ s += lev.Path;
+ s.Add_LF();
+ s += m;
+ }
+ else
+ {
+ UString &s = open_Errors;
+ if (!s.IsEmpty())
+ s += "--------------------\n";
+ s += lev.Path;
+ s.Add_LF();
+ s += m;
+ }
+ }
+ }
+}
+
+
+HRESULT CFfpOpen::OpenFileFolderPlugin(IInStream *inStream,
+ const FString &path, const UString &arcFormat, HWND parentWindow)
{
CObjectVector<CPluginInfo> plugins;
ReadFileFolderPluginInfoList(plugins);
@@ -92,8 +243,8 @@ HRESULT OpenFileFolderPlugin(
FString fileName;
if (slashPos >= 0)
{
- dirPrefix.SetFrom(path, slashPos + 1);
- fileName = path.Ptr(slashPos + 1);
+ dirPrefix.SetFrom(path, (unsigned)(slashPos + 1));
+ fileName = path.Ptr((unsigned)(slashPos + 1));
}
else
fileName = path;
@@ -120,6 +271,8 @@ HRESULT OpenFileFolderPlugin(
}
*/
+ ErrorMessage.Empty();
+
FOR_VECTOR (i, plugins)
{
const CPluginInfo &plugin = plugins[i];
@@ -136,24 +289,29 @@ HRESULT OpenFileFolderPlugin(
t.OpenCallbackSpec = new COpenArchiveCallback;
t.OpenCallback = t.OpenCallbackSpec;
- t.OpenCallbackSpec->PasswordIsDefined = encrypted;
- t.OpenCallbackSpec->Password = password;
+ t.OpenCallbackSpec->PasswordIsDefined = Encrypted;
+ t.OpenCallbackSpec->Password = Password;
t.OpenCallbackSpec->ParentWindow = parentWindow;
if (inStream)
t.OpenCallbackSpec->SetSubArchiveName(fs2us(fileName));
else
- t.OpenCallbackSpec->LoadFileInfo(dirPrefix, fileName);
+ {
+ RINOK(t.OpenCallbackSpec->LoadFileInfo2(dirPrefix, fileName));
+ }
t.InStream = inStream;
t.Path = fs2us(path);
t.ArcFormat = arcFormat;
- UString progressTitle = LangString(IDS_OPENNING);
- t.OpenCallbackSpec->ProgressDialog.MainWindow = parentWindow;
- t.OpenCallbackSpec->ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
- t.OpenCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + L' ';
- t.OpenCallbackSpec->ProgressDialog.WaitMode = true;
+ const UString progressTitle = LangString(IDS_OPENNING);
+ {
+ CProgressDialog &pd = t.OpenCallbackSpec->ProgressDialog;
+ pd.MainWindow = parentWindow;
+ pd.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
+ pd.MainAddTitle = progressTitle + L' ';
+ pd.WaitMode = true;
+ }
{
NWindows::CThread thread;
@@ -161,23 +319,39 @@ HRESULT OpenFileFolderPlugin(
t.OpenCallbackSpec->StartProgressDialog(progressTitle, thread);
}
- if (t.Result == E_ABORT)
+ if (t.Result != S_FALSE && t.Result != S_OK)
return t.Result;
- encrypted = t.OpenCallbackSpec->PasswordIsDefined;
- if (t.Result == S_OK)
+ if (t.Folder)
{
- // if (openCallbackSpec->PasswordWasAsked)
+ UString open_Errors, nonOpen_Errors;
+ GetFolderError(t.Folder, open_Errors, nonOpen_Errors);
+ if (!nonOpen_Errors.IsEmpty())
{
- password = t.OpenCallbackSpec->Password;
+ ErrorMessage = nonOpen_Errors;
+ // if (t.Result != S_OK) return t.Result;
+ /* if there are good open leves, and non0open level,
+ we could force error as critical error and return error here
+ but it's better to allow to open such rachives */
+ // return S_FALSE;
}
- *module = library.Detach();
- *resultFolder = t.Folder.Detach();
- return S_OK;
+ }
+
+ // if (openCallbackSpec->PasswordWasAsked)
+ {
+ Encrypted = t.OpenCallbackSpec->PasswordIsDefined;
+ Password = t.OpenCallbackSpec->Password;
+ }
+
+ if (t.Result == S_OK)
+ {
+ Library.Attach(library.Detach());
+ // Folder.Attach(t.Folder.Detach());
+ Folder = t.Folder;
}
- if (t.Result != S_FALSE)
- return t.Result;
+ return t.Result;
}
+
return S_FALSE;
}