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:
Diffstat (limited to 'CPP/7zip/UI/Explorer')
-rw-r--r--CPP/7zip/UI/Explorer/ContextMenu.cpp596
-rw-r--r--CPP/7zip/UI/Explorer/ContextMenu.h72
-rw-r--r--CPP/7zip/UI/Explorer/ContextMenuFlags.h1
-rw-r--r--CPP/7zip/UI/Explorer/DllExportsExplorer.cpp27
-rw-r--r--CPP/7zip/UI/Explorer/Explorer.dsp20
-rw-r--r--CPP/7zip/UI/Explorer/MyExplorerCommand.h173
-rw-r--r--CPP/7zip/UI/Explorer/makefile1
-rw-r--r--CPP/7zip/UI/Explorer/resource.rc2
8 files changed, 851 insertions, 41 deletions
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp
index 0334942a..8a0842e1 100644
--- a/CPP/7zip/UI/Explorer/ContextMenu.cpp
+++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp
@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include "../../../Common/ComTry.h"
+#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/COM.h"
@@ -15,12 +16,15 @@
#include "../../../Windows/ProcessUtils.h"
#include "../../../Windows/Shell.h"
+#include "../../PropID.h"
+
#include "../Common/ArchiveName.h"
#include "../Common/CompressCall.h"
#include "../Common/ExtractingFilePath.h"
#include "../Common/ZipRegistry.h"
#include "../FileManager/FormatUtils.h"
+#include "../FileManager/PropertyName.h"
#ifdef LANG
#include "../FileManager/LangUtils.h"
@@ -52,16 +56,65 @@ extern LONG g_DllRefCount;
extern HINSTANCE g_hInstance;
#endif
+#ifdef SHOW_DEBUG_CTX_MENU
+
+void Print_Ptr(void *p, char *s)
+{
+ char temp[64];
+ ConvertUInt64ToHex((UInt64)(void *)p, temp);
+ AString s2;
+ s2 += temp;
+ s2.Add_Space();
+ s2 += s;
+ OutputDebugStringA(s2);
+}
+
+void Print_Number(UInt32 number, char *s)
+{
+ char temp[64];
+ ConvertUInt64ToString(number, temp);
+ AString s2;
+ s2 += temp;
+ s2.Add_Space();
+ s2 += s;
+ OutputDebugStringA(s2);
+}
+
+#define ODS(sz) Print_Ptr(this, sz)
+#define ODS_U(s) OutputDebugStringW(s);
+// #define ODS(sz)
+// #define ODS_U(s)
+
+#define ODS2(sz) Print_Ptr(this, sz)
+
+#else
+
+#define Print_Number(number, s)
+#define ODS(sz)
+#define ODS_U(s)
+#define ODS2(sz)
+
+#endif
+
+
+
CZipContextMenu::CZipContextMenu():
_isMenuForFM(false),
- _bitmap(NULL)
+ _dropMode(false),
+ _bitmap(NULL),
+ IsSeparator(false),
+ IsRoot(true),
+ CurrentSubCommand(0)
{
+ ODS("-- CZipContextMenu()");
+
InterlockedIncrement(&g_DllRefCount);
_bitmap = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_MENU_LOGO));
}
CZipContextMenu::~CZipContextMenu()
{
+ ODS("== ~CZipContextMenu");
if (_bitmap != NULL)
DeleteObject(_bitmap);
InterlockedDecrement(&g_DllRefCount);
@@ -184,7 +237,9 @@ static const CHashCommand g_HashCommands[] =
{ CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" },
{ CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" },
{ CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" },
- { CZipContextMenu::kHash_All, "*", "*" }
+ { CZipContextMenu::kHash_All, "*", "*" },
+ { CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" },
+ { CZipContextMenu::kHash_TestArc, "Checksum : Test", "Hash" }
};
@@ -209,9 +264,19 @@ void CZipContextMenu::FillCommand(ECommandInternalID id, UString &mainString, CC
cmi.Verb += command.Verb;
// cmi.HelpString = cmi.Verb;
LangString(command.ResourceID, mainString);
+ cmi.UserString = mainString;
// return true;
}
+
+static UString LangStringAlt(UInt32 id, const char *altString)
+{
+ UString s = LangString(id);
+ if (s.IsEmpty())
+ s = altString;
+ return s;
+}
+
void CZipContextMenu::AddCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi)
{
@@ -222,6 +287,8 @@ void CZipContextMenu::AddCommand(ECommandInternalID id, UString &mainString, CCo
static void MyInsertMenu(CMenu &menu, int pos, UINT id, const UString &s, HBITMAP bitmap)
{
+ if (!menu)
+ return;
CMenuItem mi;
mi.fType = MFT_STRING;
mi.fMask = MIIM_TYPE | MIIM_ID;
@@ -247,9 +314,14 @@ static void MyAddSubMenu(
CZipContextMenu::CCommandMapItem cmi;
cmi.CommandInternalID = CZipContextMenu::kCommandNULL;
cmi.Verb = verb;
+ cmi.IsPopup = true;
// cmi.HelpString = verb;
+ cmi.UserString = s;
_commandMap.Add(cmi);
+ if (!menu)
+ return;
+
CMenuItem mi;
mi.fType = MFT_STRING;
mi.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
@@ -329,7 +401,7 @@ static void MyFormatNew_ReducedName(UString &s, const UString &name)
s = MyFormatNew(s, GetQuotedReducedString(name));
}
-static const char * const kExtractExludeExtensions =
+static const char * const kExtractExcludeExtensions =
" 3gp"
" aac ans ape asc asm asp aspx avi awk"
" bas bat bmp"
@@ -403,7 +475,7 @@ static bool FindExt(const char *p, const FString &name)
static bool DoNeedExtract(const FString &name)
{
- return !FindExt(kExtractExludeExtensions, name);
+ return !FindExt(kExtractExcludeExtensions, name);
}
// we must use diferent Verbs for Popup subMenu.
@@ -427,12 +499,12 @@ static HRESULT RETURN_WIN32_LastError_AS_HRESULT()
/*
- we add CCommandMapItem to _commandMap for each new Mene ID.
+ we add CCommandMapItem to _commandMap for each new Menu ID.
so then we use _commandMap[offset].
That way we can execute commands that have menu item.
Another non-implemented way:
- We can return the number off all possible commnad in QueryContextMenu().
- so the caller could call InvokeCommand() via string verb aven
+ We can return the number off all possible commands in QueryContextMenu().
+ so the caller could call InvokeCommand() via string verb even
without using menu items.
*/
@@ -441,6 +513,7 @@ static HRESULT RETURN_WIN32_LastError_AS_HRESULT()
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UINT commandIDFirst, UINT commandIDLast, UINT flags)
{
+ ODS("+ QueryContextMenu()");
COM_TRY_BEGIN
try {
@@ -493,9 +566,12 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
bitmap = _bitmap;
UINT subIndex = indexMenu;
+
+ ODS("### 50");
if (ci.Cascaded.Val)
{
+ if (hMenu)
if (!popupMenu.CreatePopup())
return RETURN_WIN32_LastError_AS_HRESULT();
menuDestroyer.Attach(popupMenu);
@@ -514,6 +590,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
CMenuItem mi;
mi.fType = MFT_SEPARATOR;
mi.fMask = MIIM_TYPE;
+ if (hMenu)
popupMenu.InsertItem(subIndex++, true, mi);
}
@@ -551,6 +628,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
}
}
+ ODS("### 100");
+
UString mainString;
if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast)
@@ -567,13 +646,15 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
}
if ((contextMenuFlags & NContextMenuFlags::kOpenAs) != 0
// && (!thereIsMainOpenItem || !FindExt(kNoOpenAsExtensions, fi0.Name))
+ && hMenu // we want to reduce number of menu items below 16
)
{
CMenu subMenu;
- if (subMenu.CreatePopup())
+ if (!hMenu || subMenu.CreatePopup())
{
MyAddSubMenu(_commandMap, kOpenCascadedVerb, popupMenu, subIndex++, currentCommandID++, LangString(IDS_CONTEXT_OPEN), subMenu, bitmap);
-
+ _commandMap.Back().CtxCommandType = CtxCommandType_OpenRoot;
+
UINT subIndex2 = 0;
for (unsigned i = (thereIsMainOpenItem ? 1 : 0); i < ARRAY_SIZE(kOpenTypes); i++)
{
@@ -589,8 +670,10 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
cmi.Verb += mainString;
// cmi.HelpString = cmi.Verb;
cmi.ArcType = mainString;
+ cmi.CtxCommandType = CtxCommandType_OpenChild;
}
_commandMap.Add(cmi);
+ Set_UserString_in_LastCommand(mainString);
MyInsertMenu(subMenu, subIndex2++, currentCommandID++, mainString, bitmap);
}
@@ -662,6 +745,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
cmi.Folder = baseFolder + specFolder;
AddCommand(kExtractTo, s, cmi);
MyFormatNew_ReducedName(s, specFolder);
+ Set_UserString_in_LastCommand(s);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
}
}
@@ -720,6 +804,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
cmi.ArcType = "7z";
AddCommand(kCompressTo7z, s, cmi);
MyFormatNew_ReducedName(s, arcName7z);
+ Set_UserString_in_LastCommand(s);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
}
@@ -733,6 +818,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
cmi.ArcType = "7z";
AddCommand(kCompressTo7zEmail, s, cmi);
MyFormatNew_ReducedName(s, arcName7z);
+ Set_UserString_in_LastCommand(s);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
}
#endif
@@ -751,6 +837,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
cmi.ArcType = "zip";
AddCommand(kCompressToZip, s, cmi);
MyFormatNew_ReducedName(s, arcNameZip);
+ Set_UserString_in_LastCommand(s);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
}
@@ -764,6 +851,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
cmi.ArcType = "zip";
AddCommand(kCompressToZipEmail, s, cmi);
MyFormatNew_ReducedName(s, arcNameZip);
+ Set_UserString_in_LastCommand(s);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap);
}
#endif
@@ -779,32 +867,56 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
CMenu menu;
menu.Attach(hMenu);
menuDestroyer.Disable();
- MyAddSubMenu(_commandMap, kMainVerb, menu, indexMenu++, currentCommandID++, (UString)"7-Zip", popupMenu.Detach(), bitmap);
+ MyAddSubMenu(_commandMap, kMainVerb, menu, indexMenu++, currentCommandID++, (UString)"7-Zip",
+ popupMenu, // popupMenu.Detach(),
+ bitmap);
}
else
{
- popupMenu.Detach();
+ // popupMenu.Detach();
indexMenu = subIndex;
}
+ const bool needCrc = ((contextMenuFlags &
+ (NContextMenuFlags::kCRC |
+ NContextMenuFlags::kCRC_Cascaded)) != 0);
- if (!_isMenuForFM &&
- ((contextMenuFlags & NContextMenuFlags::kCRC) != 0
- && currentCommandID + 1 < commandIDLast))
+ if (
+ // !_isMenuForFM && // 21.04: we don't hide CRC SHA menu in 7-Zip FM
+ needCrc
+ && currentCommandID + 1 < commandIDLast)
{
CMenu subMenu;
// CMenuDestroyer menuDestroyer_CRC;
-
+
UINT subIndex_CRC = 0;
- if (subMenu.CreatePopup())
+ if (!hMenu || subMenu.CreatePopup())
{
// menuDestroyer_CRC.Attach(subMenu);
+ const bool insertHashMenuTo7zipMenu = (ci.Cascaded.Val
+ && (contextMenuFlags & NContextMenuFlags::kCRC_Cascaded) != 0);
CMenu menu;
- menu.Attach(hMenu);
- // menuDestroyer_CRC.Disable();
- MyAddSubMenu(_commandMap, kCheckSumCascadedVerb, menu, indexMenu++, currentCommandID++, (UString)"CRC SHA", subMenu, bitmap);
+ {
+ int indexInParent;
+ if (insertHashMenuTo7zipMenu)
+ {
+ indexInParent = subIndex;
+ menu.Attach(popupMenu);
+ }
+ else
+ {
+ indexInParent = indexMenu;
+ menu.Attach(hMenu);
+ // menuDestroyer_CRC.Disable();
+ }
+ MyAddSubMenu(_commandMap, kCheckSumCascadedVerb, menu, indexInParent++, currentCommandID++, (UString)"CRC SHA", subMenu,
+ /* insertHashMenuTo7zipMenu ? NULL : */ bitmap);
+ _commandMap.Back().CtxCommandType = CtxCommandType_CrcRoot;
+ if (!insertHashMenuTo7zipMenu)
+ indexMenu = indexInParent;
+ }
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{
@@ -816,15 +928,57 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
cmi.Verb = kCheckSumCascadedVerb;
cmi.Verb += '.';
cmi.Verb += hc.MethodName;
+ UString s;
+ s += hc.UserName;
+
+ if (hc.CommandInternalID == kHash_Generate_SHA256)
+ {
+ {
+ popupMenu.Attach(hMenu);
+ CMenuItem mi;
+ mi.fType = MFT_SEPARATOR;
+ mi.fMask = MIIM_TYPE;
+ subMenu.InsertItem(subIndex_CRC++, true, mi);
+ }
+
+ UString name;
+ if (_fileNames.Size() > 1)
+ name = CreateArchiveName(_fileNames, _fileNames.Size() == 1 ? &fi0 : NULL);
+ else
+ name = fs2us(fi0.Name);
+ name += ".sha256";
+ cmi.Folder= folderPrefix;
+ cmi.ArcName = name;
+ s = "SHA-256 -> ";
+ s += name;
+ }
+ else if (hc.CommandInternalID == kHash_TestArc)
+ {
+ s = LangStringAlt(IDS_CONTEXT_TEST, "Test archive");
+ s += " : ";
+ s += GetNameOfProperty(kpidChecksum, UString("Checksum"));
+ }
+
// cmi.HelpString = cmi.Verb;
+ cmi.UserString = s;
+ cmi.CtxCommandType = CtxCommandType_CrcChild;
_commandMap.Add(cmi);
- MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, (UString)hc.UserName, bitmap);
+ MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, s, bitmap);
}
subMenu.Detach();
}
}
+ popupMenu.Detach();
+
+ /*
+ if (!ci.Cascaded.Val)
+ indexMenu = subIndex;
+ */
+
+ ODS("### 400");
+
#ifdef SHOW_DEBUG_CTX_MENU
{ char s[256]; sprintf(s, "Commands=%d currentCommandID - commandIDFirst = %d",
_commandMap.Size(), currentCommandID - commandIDFirst); OutputDebugStringA(s); }
@@ -981,9 +1135,15 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
if (commandOffset < 0 || (unsigned)commandOffset >= _commandMap.Size())
return E_INVALIDARG;
-
const CCommandMapItem &cmi = _commandMap[(unsigned)commandOffset];
- ECommandInternalID cmdID = cmi.CommandInternalID;
+ return InvokeCommandCommon(cmi);
+ COM_TRY_END
+}
+
+
+HRESULT CZipContextMenu::InvokeCommandCommon(const CCommandMapItem &cmi)
+{
+ const ECommandInternalID cmdID = cmi.CommandInternalID;
try
{
@@ -1023,18 +1183,20 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
case kCompressToZip:
case kCompressToZipEmail:
{
- bool email =
+ const bool email =
(cmdID == kCompressEmail) ||
(cmdID == kCompressTo7zEmail) ||
(cmdID == kCompressToZipEmail);
- bool showDialog =
+ const bool showDialog =
(cmdID == kCompress) ||
(cmdID == kCompressEmail);
- bool addExtension = (cmdID == kCompress || cmdID == kCompressEmail);
+ const bool addExtension = (cmdID == kCompress || cmdID == kCompressEmail);
CompressFiles(cmi.Folder,
cmi.ArcName, cmi.ArcType,
addExtension,
- _fileNames, email, showDialog, false);
+ _fileNames, email, showDialog,
+ false // waitFinish
+ );
break;
}
@@ -1043,13 +1205,24 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
case kHash_SHA1:
case kHash_SHA256:
case kHash_All:
+ case kHash_Generate_SHA256:
+ case kHash_TestArc:
{
for (unsigned i = 0; i < ARRAY_SIZE(g_HashCommands); i++)
{
const CHashCommand &hc = g_HashCommands[i];
if (hc.CommandInternalID == cmdID)
{
- CalcChecksum(_fileNames, (UString)hc.MethodName);
+ if (cmdID == kHash_TestArc)
+ {
+ TestArchives(_fileNames, true); // hashMode
+ break;
+ }
+ UString generateName;
+ if (cmdID == kHash_Generate_SHA256)
+ generateName = cmi.ArcName;
+ CalcChecksum(_fileNames, (UString)hc.MethodName,
+ cmi.Folder, generateName);
break;
}
}
@@ -1064,7 +1237,6 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
::MessageBoxW(0, L"Error", L"7-Zip", MB_ICONERROR);
}
return S_OK;
- COM_TRY_END
}
@@ -1136,3 +1308,371 @@ STDMETHODIMP CZipContextMenu::GetCommandString(UINT_PTR commandOffset, UINT uTyp
COM_TRY_END
}
+
+
+
+// ---------- IExplorerCommand ----------
+
+static HRESULT WINAPI My_SHStrDupW(LPCWSTR src, LPWSTR *dest)
+{
+ if (src)
+ {
+ const SIZE_T size = (wcslen(src) + 1) * sizeof(WCHAR);
+ WCHAR *p = (WCHAR *)CoTaskMemAlloc(size);
+ if (p)
+ {
+ memcpy(p, src, size);
+ *dest = p;
+ return S_OK;
+ }
+ }
+ *dest = NULL;
+ return E_OUTOFMEMORY;
+}
+
+
+#define CZipExplorerCommand CZipContextMenu
+
+class CCoTaskWSTR
+{
+ LPWSTR m_str;
+ CLASS_NO_COPY(CCoTaskWSTR)
+public:
+ CCoTaskWSTR(): m_str(NULL) {}
+ ~CCoTaskWSTR() { ::CoTaskMemFree(m_str); }
+ LPWSTR* operator&() { return &m_str; }
+ operator LPCWSTR () const { return m_str; }
+ // operator LPCOLESTR() const { return m_str; }
+ operator bool() const { return m_str != NULL; }
+ // bool operator!() const { return m_str == NULL; }
+
+ /*
+ void Wipe_and_Free()
+ {
+ if (m_str)
+ {
+ memset(m_str, 0, ::SysStringLen(m_str) * sizeof(*m_str));
+ Empty();
+ }
+ }
+ */
+
+private:
+ /*
+ CCoTaskWSTR(LPCOLESTR src) { m_str = ::CoTaskMemAlloc(src); }
+
+ CCoTaskWSTR& operator=(LPCOLESTR src)
+ {
+ ::CoTaskMemFree(m_str);
+ m_str = ::SysAllocString(src);
+ return *this;
+ }
+
+
+ void Empty()
+ {
+ ::CoTaskMemFree(m_str);
+ m_str = NULL;
+ }
+ */
+};
+
+static void LoadPaths(IShellItemArray *psiItemArray, UStringVector &paths)
+{
+ if (psiItemArray)
+ {
+ DWORD numItems = 0;
+ if (psiItemArray->GetCount(&numItems) == S_OK)
+ {
+ for (DWORD i = 0; i < numItems; i++)
+ {
+ CMyComPtr<IShellItem> item;
+ if (psiItemArray->GetItemAt(i, &item) == S_OK && item)
+ {
+ CCoTaskWSTR displayName;
+ if (item->GetDisplayName(SIGDN_FILESYSPATH, &displayName) == S_OK
+ && (bool)displayName)
+ {
+ OutputDebugStringW(displayName);
+ paths.Add((LPCWSTR)displayName);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void CZipExplorerCommand::LoadItems(IShellItemArray *psiItemArray)
+{
+ SubCommands.Clear();
+
+ UStringVector paths;
+ LoadPaths(psiItemArray, paths);
+ _fileNames = paths;
+
+ HRESULT res = QueryContextMenu(
+ NULL, // hMenu,
+ 0, // indexMenu,
+ 0, // commandIDFirst,
+ 0 + 999, // commandIDLast,
+ CMF_NORMAL);
+
+ if (FAILED(res))
+ return /* res */;
+
+
+ CZipExplorerCommand *crcHandler = NULL;
+ CZipExplorerCommand *openHandler = NULL;
+
+ bool useCascadedCrc = true; // false;
+ bool useCascadedOpen = true; // false;
+
+ for (unsigned i = 0; i < _commandMap.Size(); i++)
+ {
+ const CCommandMapItem &cmi = _commandMap[i];
+
+
+ if (cmi.IsPopup)
+ if (!cmi.IsSubMenu())
+ continue;
+
+ // if (cmi.IsSubMenu()) continue // for debug
+
+ CZipContextMenu *shellExt = new CZipContextMenu();
+ shellExt->IsRoot = false;
+
+ if (cmi.CtxCommandType == CtxCommandType_CrcRoot && !useCascadedCrc)
+ shellExt->IsSeparator = true;
+
+ {
+ CZipExplorerCommand *handler = this;
+ if (cmi.CtxCommandType == CtxCommandType_CrcChild && crcHandler)
+ handler = crcHandler;
+ else if (cmi.CtxCommandType == CtxCommandType_OpenChild && openHandler)
+ handler = openHandler;
+ handler->SubCommands.AddNew() = shellExt;
+ }
+
+ shellExt->_commandMap_Cur.Add(cmi);
+
+ ODS_U(cmi.UserString);
+
+ if (cmi.CtxCommandType == CtxCommandType_CrcRoot && useCascadedCrc)
+ crcHandler = shellExt;
+ if (cmi.CtxCommandType == CtxCommandType_OpenRoot && useCascadedOpen)
+ {
+ // ODS2("cmi.CtxCommandType == CtxCommandType_OpenRoot");
+ openHandler = shellExt;
+ }
+ }
+}
+
+
+STDMETHODIMP CZipExplorerCommand::GetTitle(IShellItemArray *psiItemArray, LPWSTR *ppszName)
+{
+ ODS("- GetTitle()");
+ // COM_TRY_BEGIN
+ if (IsSeparator)
+ {
+ *ppszName = NULL;
+ return S_FALSE;
+ }
+
+ UString name;
+ if (IsRoot)
+ {
+ LoadItems(psiItemArray);
+ name = "7-Zip"; // "New"
+ }
+ else
+ name = "7-Zip item";
+
+ if (!_commandMap_Cur.IsEmpty())
+ {
+ const CCommandMapItem &mi = _commandMap_Cur[0];
+ // s += mi.Verb;
+ // s += " : ";
+ name = mi.UserString;
+ }
+
+ return My_SHStrDupW(name, ppszName);
+ // return S_OK;
+ // COM_TRY_END
+}
+
+
+STDMETHODIMP CZipExplorerCommand::GetIcon(IShellItemArray * /* psiItemArray */, LPWSTR *ppszIcon)
+{
+ ODS("- GetIcon()");
+ // COM_TRY_BEGIN
+ *ppszIcon = NULL;
+ // return E_NOTIMPL;
+ UString imageName = fs2us(NWindows::NDLL::GetModuleDirPrefix());
+ // imageName += "7zG.exe";
+ imageName += "7-zip.dll";
+ // imageName += ",190";
+ return My_SHStrDupW(imageName, ppszIcon);
+ // COM_TRY_END
+}
+
+
+STDMETHODIMP CZipExplorerCommand::GetToolTip (IShellItemArray * /* psiItemArray */, LPWSTR *ppszInfotip)
+{
+ // COM_TRY_BEGIN
+ ODS("- GetToolTip()");
+ *ppszInfotip = NULL;
+ return E_NOTIMPL;
+ // COM_TRY_END
+}
+
+
+STDMETHODIMP CZipExplorerCommand::GetCanonicalName(GUID *pguidCommandName)
+{
+ // COM_TRY_BEGIN
+ ODS("- GetCanonicalName()");
+ *pguidCommandName = GUID_NULL;
+ return E_NOTIMPL;
+ // COM_TRY_END
+}
+
+
+STDMETHODIMP CZipExplorerCommand::GetState(IShellItemArray * /* psiItemArray */, BOOL /* fOkToBeSlow */, EXPCMDSTATE *pCmdState)
+{
+ // COM_TRY_BEGIN
+ ODS("- GetState()");
+ *pCmdState = ECS_ENABLED;
+ return S_OK;
+ // COM_TRY_END
+}
+
+
+
+
+STDMETHODIMP CZipExplorerCommand::Invoke(IShellItemArray *psiItemArray, IBindCtx * /* pbc */)
+{
+ COM_TRY_BEGIN
+
+ if (_commandMap_Cur.IsEmpty())
+ return E_INVALIDARG;
+
+ ODS("- Invoke()");
+ UStringVector paths;
+ LoadPaths(psiItemArray, paths);
+ _fileNames = paths;
+ return InvokeCommandCommon(_commandMap_Cur[0]);
+
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CZipExplorerCommand::GetFlags(EXPCMDFLAGS *pFlags)
+{
+ ODS("- GetFlags()");
+ // COM_TRY_BEGIN
+ EXPCMDFLAGS f = ECF_DEFAULT;
+ if (IsSeparator)
+ f = ECF_ISSEPARATOR;
+ else if (IsRoot)
+ f = ECF_HASSUBCOMMANDS;
+ else
+ {
+ if (!_commandMap_Cur.IsEmpty())
+ {
+ // const CCommandMapItem &cmi = ;
+ if (_commandMap_Cur[0].IsSubMenu())
+ {
+ // ODS("ECF_HASSUBCOMMANDS");
+ f = ECF_HASSUBCOMMANDS;
+ }
+ }
+ }
+ *pFlags = f;
+ return S_OK;
+ // COM_TRY_END
+}
+
+
+STDMETHODIMP CZipExplorerCommand::EnumSubCommands(IEnumExplorerCommand **ppEnum)
+{
+ ODS("- EnumSubCommands()");
+ // COM_TRY_BEGIN
+ *ppEnum = NULL;
+
+ if (!_commandMap_Cur.IsEmpty() && _commandMap_Cur[0].IsSubMenu())
+ {
+ }
+ else
+ {
+ if (!IsRoot)
+ return E_NOTIMPL;
+ if (SubCommands.IsEmpty())
+ {
+ return E_NOTIMPL;
+ }
+ }
+
+ // shellExt->
+ return QueryInterface(IID_IEnumExplorerCommand, (void **)ppEnum);
+
+ // return S_OK;
+ // COM_TRY_END
+}
+
+
+STDMETHODIMP CZipContextMenu::Next(ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched)
+{
+ ODS("CZipContextMenu::Next()");
+ Print_Number(celt, "celt");
+ Print_Number(CurrentSubCommand, "CurrentSubCommand");
+ Print_Number(SubCommands.Size(), "SubCommands.Size()");
+
+ COM_TRY_BEGIN
+ ULONG fetched = 0;
+
+ ULONG i;
+ for (i = 0; i < celt; i++)
+ {
+ pUICommand[i] = NULL;
+ }
+
+ for (i = 0; i < celt && CurrentSubCommand < SubCommands.Size(); i++)
+ {
+ pUICommand[i] = SubCommands[CurrentSubCommand++];
+ pUICommand[i]->AddRef();
+ fetched++;
+ }
+
+ if (pceltFetched)
+ *pceltFetched = fetched;
+
+ ODS(fetched == celt ? " === OK === " : "=== ERROR ===");
+
+ // we return S_FALSE for (fetched == 0)
+ return (fetched == celt) ? S_OK : S_FALSE;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CZipContextMenu::Skip(ULONG celt)
+{
+ ODS("CZipContextMenu::Skip()");
+ celt = celt;
+ return E_NOTIMPL;
+}
+
+
+STDMETHODIMP CZipContextMenu::Reset(void)
+{
+ ODS("CZipContextMenu::Reset()");
+ CurrentSubCommand = 0;
+ return S_OK;
+}
+
+
+STDMETHODIMP CZipContextMenu::Clone(IEnumExplorerCommand **ppenum)
+{
+ ODS("CZipContextMenu::Clone()");
+ *ppenum = NULL;
+ return E_NOTIMPL;
+}
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.h b/CPP/7zip/UI/Explorer/ContextMenu.h
index dddb9fd1..285044e7 100644
--- a/CPP/7zip/UI/Explorer/ContextMenu.h
+++ b/CPP/7zip/UI/Explorer/ContextMenu.h
@@ -7,13 +7,27 @@
#include <ShlObj.h>
+#include "MyExplorerCommand.h"
+
#include "../../../Common/MyString.h"
#include "../FileManager/MyCom2.h"
+enum ECtxCommandType
+{
+ CtxCommandType_Normal,
+ CtxCommandType_OpenRoot,
+ CtxCommandType_OpenChild,
+ CtxCommandType_CrcRoot,
+ CtxCommandType_CrcChild,
+};
+
+
class CZipContextMenu:
public IContextMenu,
public IShellExtInit,
+ public IExplorerCommand,
+ public IEnumExplorerCommand,
public CMyUnknownImp
{
public:
@@ -36,10 +50,17 @@ public:
kHash_CRC64,
kHash_SHA1,
kHash_SHA256,
- kHash_All
+ kHash_All,
+ kHash_Generate_SHA256,
+ kHash_TestArc
};
- MY_UNKNOWN_IMP2_MT(IContextMenu, IShellExtInit)
+ MY_UNKNOWN_IMP4_MT(
+ IContextMenu,
+ IShellExtInit,
+ IExplorerCommand,
+ IEnumExplorerCommand
+ )
// IShellExtInit
STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY hkeyProgID);
@@ -51,6 +72,24 @@ public:
HRESULT InitContextMenu(const wchar_t *folder, const wchar_t * const *names, unsigned numFiles);
+ void LoadItems(IShellItemArray *psiItemArray);
+
+ // IExplorerCommand
+ STDMETHOD (GetTitle) (IShellItemArray *psiItemArray, LPWSTR *ppszName);
+ STDMETHOD (GetIcon) (IShellItemArray *psiItemArray, LPWSTR *ppszIcon);
+ STDMETHOD (GetToolTip) (IShellItemArray *psiItemArray, LPWSTR *ppszInfotip);
+ STDMETHOD (GetCanonicalName) (GUID *pguidCommandName);
+ STDMETHOD (GetState) (IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState);
+ STDMETHOD (Invoke) (IShellItemArray *psiItemArray, IBindCtx *pbc);
+ STDMETHOD (GetFlags) (EXPCMDFLAGS *pFlags);
+ STDMETHOD (EnumSubCommands) (IEnumExplorerCommand **ppEnum);
+
+ // IEnumExplorerCommand
+ STDMETHOD (Next) (ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched);
+ STDMETHOD (Skip) (ULONG celt);
+ STDMETHOD (Reset) (void);
+ STDMETHOD (Clone) (IEnumExplorerCommand **ppenum);
+
CZipContextMenu();
~CZipContextMenu();
@@ -58,10 +97,25 @@ public:
{
ECommandInternalID CommandInternalID;
UString Verb;
+ UString UserString;
// UString HelpString;
UString Folder;
UString ArcName;
UString ArcType;
+ bool IsPopup;
+ ECtxCommandType CtxCommandType;
+
+ CCommandMapItem():
+ IsPopup(false),
+ CtxCommandType(CtxCommandType_Normal)
+ {}
+
+ bool IsSubMenu() const
+ {
+ return
+ CtxCommandType == CtxCommandType_CrcRoot ||
+ CtxCommandType == CtxCommandType_OpenRoot;
+ }
};
private:
@@ -71,16 +125,28 @@ private:
bool _dropMode;
UString _dropPath;
CObjectVector<CCommandMapItem> _commandMap;
+ CObjectVector<CCommandMapItem> _commandMap_Cur;
HBITMAP _bitmap;
-
CBoolPair _elimDup;
+ bool IsSeparator;
+ bool IsRoot;
+ CObjectVector< CMyComPtr<IExplorerCommand> > SubCommands;
+ ULONG CurrentSubCommand;
+
+ void Set_UserString_in_LastCommand(const UString &s)
+ {
+ _commandMap.Back().UserString = s;
+ }
+
HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
int FindVerb(const UString &verb);
void FillCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi);
void AddCommand(ECommandInternalID id, UString &mainString, CCommandMapItem &cmi);
void AddMapItem_ForSubMenu(const char *ver);
+
+ HRESULT InvokeCommandCommon(const CCommandMapItem &cmi);
};
#endif
diff --git a/CPP/7zip/UI/Explorer/ContextMenuFlags.h b/CPP/7zip/UI/Explorer/ContextMenuFlags.h
index f739cdc6..42b25f3a 100644
--- a/CPP/7zip/UI/Explorer/ContextMenuFlags.h
+++ b/CPP/7zip/UI/Explorer/ContextMenuFlags.h
@@ -20,6 +20,7 @@ namespace NContextMenuFlags
const UInt32 kCompressToZip = 1 << 12;
const UInt32 kCompressToZipEmail = 1 << 13;
+ const UInt32 kCRC_Cascaded = (UInt32)1 << 30;
const UInt32 kCRC = (UInt32)1 << 31;
}
diff --git a/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp b/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
index cb4da016..91b0da52 100644
--- a/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
+++ b/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
@@ -9,6 +9,7 @@
#include "StdAfx.h"
#include "../../../Common/MyWindows.h"
+// #include "../../../Common/IntToString.h"
#include <OleCtl.h>
@@ -52,7 +53,8 @@ LONG g_DllRefCount;
LONG g_DllRefCount = 0; // Reference count of this DLL.
-// #define ODS(sz) OutputDebugString(L#sz)
+// #define ODS(sz) OutputDebugStringW(L#sz)
+#define ODS(sz)
class CShellExtClassFactory:
public IClassFactory,
@@ -71,7 +73,12 @@ public:
STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid, void **ppvObj)
{
- // ODS("CShellExtClassFactory::CreateInstance()\r\n");
+ ODS("CShellExtClassFactory::CreateInstance()\r\n");
+ /*
+ char s[64];
+ ConvertUInt32ToHex(riid.Data1, s);
+ OutputDebugStringA(s);
+ */
*ppvObj = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
@@ -123,12 +130,12 @@ BOOL WINAPI DllMain(
if (dwReason == DLL_PROCESS_ATTACH)
{
g_hInstance = (HINSTANCE)hInstance;
- // ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n");
+ ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n");
NT_CHECK
}
else if (dwReason == DLL_PROCESS_DETACH)
{
- // ODS("In DLLMain, DLL_PROCESS_DETACH\r\n");
+ ODS("In DLLMain, DLL_PROCESS_DETACH\r\n");
}
return TRUE;
}
@@ -138,13 +145,19 @@ BOOL WINAPI DllMain(
STDAPI DllCanUnloadNow(void)
{
- // ODS("In DLLCanUnloadNow\r\n");
+ ODS("In DLLCanUnloadNow\r\n");
+ /*
+ if (g_DllRefCount == 0)
+ ODS( "g_DllRefCount == 0");
+ else
+ ODS( "g_DllRefCount != 0");
+ */
return (g_DllRefCount == 0 ? S_OK : S_FALSE);
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
- // ODS("In DllGetClassObject\r\n");
+ ODS("In DllGetClassObject\r\n");
*ppv = NULL;
if (IsEqualIID(rclsid, CLSID_CZipContextMenu))
{
@@ -168,6 +181,7 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
static BOOL RegisterServer()
{
+ ODS("RegisterServer\r\n");
FString modulePath;
if (!NDLL::MyGetModuleFileName(modulePath))
return FALSE;
@@ -197,6 +211,7 @@ static BOOL RegisterServer()
key.SetValue(k_Clsid, k_ShellExtName);
}
+ ODS("RegisterServer :: return TRUE");
return TRUE;
}
diff --git a/CPP/7zip/UI/Explorer/Explorer.dsp b/CPP/7zip/UI/Explorer/Explorer.dsp
index bd91e546..e3909176 100644
--- a/CPP/7zip/UI/Explorer/Explorer.dsp
+++ b/CPP/7zip/UI/Explorer/Explorer.dsp
@@ -55,7 +55,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Util\7-Zip.dll" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "Explorer - Win32 Debug"
@@ -82,7 +82,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\7-Zip.dll" /pdbtype:sept
!ELSEIF "$(CFG)" == "Explorer - Win32 ReleaseU"
@@ -110,7 +110,7 @@ BSC32=bscmake.exe
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98
# SUBTRACT BASE LINK32 /pdb:none
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zipn.dll" /opt:NOWIN98
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Util\7-Zip.dll" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "Explorer - Win32 DebugU"
@@ -138,7 +138,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\7-Zip.dll" /pdbtype:sept
!ENDIF
@@ -226,6 +226,10 @@ SOURCE=.\ContextMenu.h
# End Source File
# Begin Source File
+SOURCE=.\MyExplorerCommand.h
+# End Source File
+# Begin Source File
+
SOURCE=.\MyMessages.cpp
# End Source File
# Begin Source File
@@ -274,6 +278,14 @@ SOURCE=..\FileManager\ProgramLocation.h
# End Source File
# Begin Source File
+SOURCE=..\FileManager\PropertyName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\FileManager\PropertyName.h
+# End Source File
+# Begin Source File
+
SOURCE=..\FileManager\RegistryUtils.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/UI/Explorer/MyExplorerCommand.h b/CPP/7zip/UI/Explorer/MyExplorerCommand.h
new file mode 100644
index 00000000..6004d929
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/MyExplorerCommand.h
@@ -0,0 +1,173 @@
+// MyExplorerCommand.h
+
+#ifndef __MY_EXPLORER_COMMAND_H
+#define __MY_EXPLORER_COMMAND_H
+
+#if _MSC_VER >= 1910
+#define USE_SYS_shobjidl_core
+#endif
+
+#ifdef USE_SYS_shobjidl_core
+
+// #include <shobjidl_core.h>
+
+#else
+
+#ifndef __IShellItemArray_INTERFACE_DEFINED__
+#define __IShellItemArray_INTERFACE_DEFINED__
+
+// propsys.h
+
+typedef /* [v1_enum] */
+enum GETPROPERTYSTOREFLAGS
+{
+ GPS_DEFAULT = 0,
+ GPS_HANDLERPROPERTIESONLY = 0x1,
+ GPS_READWRITE = 0x2,
+ GPS_TEMPORARY = 0x4,
+ GPS_FASTPROPERTIESONLY = 0x8,
+ GPS_OPENSLOWITEM = 0x10,
+ GPS_DELAYCREATION = 0x20,
+ GPS_BESTEFFORT = 0x40,
+ GPS_NO_OPLOCK = 0x80,
+ GPS_PREFERQUERYPROPERTIES = 0x100,
+ GPS_EXTRINSICPROPERTIES = 0x200,
+ GPS_EXTRINSICPROPERTIESONLY = 0x400,
+ GPS_VOLATILEPROPERTIES = 0x800,
+ GPS_VOLATILEPROPERTIESONLY = 0x1000,
+ GPS_MASK_VALID = 0x1fff
+} GETPROPERTYSTOREFLAGS;
+
+// DEFINE_ENUM_FLAG_OPERATORS(GETPROPERTYSTOREFLAGS)
+
+
+#ifndef PROPERTYKEY_DEFINED
+#define PROPERTYKEY_DEFINED
+
+typedef
+struct _tagpropertykey
+{
+ GUID fmtid;
+ DWORD pid;
+} PROPERTYKEY;
+
+#endif // PROPERTYKEY_DEFINED
+
+// propkeydef.h
+#define REFPROPERTYKEY const PROPERTYKEY &
+
+#ifdef INITGUID
+#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
+#else
+#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY name
+#endif // INITGUID
+
+
+// <shobjidl_core.h>
+typedef /* [v1_enum] */
+enum SIATTRIBFLAGS
+{
+ SIATTRIBFLAGS_AND = 0x1,
+ SIATTRIBFLAGS_OR = 0x2,
+ SIATTRIBFLAGS_APPCOMPAT = 0x3,
+ SIATTRIBFLAGS_MASK = 0x3,
+ SIATTRIBFLAGS_ALLITEMS = 0x4000
+} SIATTRIBFLAGS;
+
+// DEFINE_ENUM_FLAG_OPERATORS(SIATTRIBFLAGS)
+
+
+// MIDL_INTERFACE("70629033-e363-4a28-a567-0db78006e6d7")
+DEFINE_GUID(IID_IEnumShellItems, 0x70629033, 0xe363, 0xe363, 0xa5, 0x67, 0x0d, 0xb7, 0x80, 0x06, 0xe6, 0xd7);
+
+struct IEnumShellItems : public IUnknown
+{
+ STDMETHOD (Next) (ULONG celt, IShellItem **rgelt, ULONG *pceltFetched) = 0;
+ STDMETHOD (Skip) (ULONG celt) = 0;
+ STDMETHOD (Reset) (void) = 0;
+ STDMETHOD (Clone) (IEnumShellItems **ppenum) = 0;
+};
+
+
+// MIDL_INTERFACE("b63ea76d-1f85-456f-a19c-48159efa858b")
+DEFINE_GUID(IID_IShellItemArray, 0xb63ea76d, 0x1f85, 0x456f, 0xa1, 0x9c, 0x48, 0x15, 0x9e, 0xfa, 0x85, 0x8b);
+
+struct IShellItemArray : public IUnknown
+{
+ STDMETHOD (BindToHandler) (IBindCtx *pbc, REFGUID bhid, REFIID riid, void **ppvOut) = 0;
+ STDMETHOD (GetPropertyStore) (GETPROPERTYSTOREFLAGS flags, REFIID riid, void **ppv) = 0;
+ STDMETHOD (GetPropertyDescriptionList) (REFPROPERTYKEY keyType, REFIID riid, void **ppv) = 0;
+ STDMETHOD (GetAttributes) ( SIATTRIBFLAGS AttribFlags, SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs) = 0;
+ STDMETHOD (GetCount) (DWORD *pdwNumItems) = 0;
+ STDMETHOD (GetItemAt) (DWORD dwIndex, IShellItem **ppsi) = 0;
+ STDMETHOD (EnumItems) (IEnumShellItems **ppenumShellItems) = 0;
+};
+
+
+#ifndef __IEnumExplorerCommand_INTERFACE_DEFINED__
+#define __IEnumExplorerCommand_INTERFACE_DEFINED__
+
+struct IExplorerCommand;
+
+// MIDL_INTERFACE("a88826f8-186f-4987-aade-ea0cef8fbfe8")
+DEFINE_GUID(IID_IEnumExplorerCommand , 0xa88826f8, 0x186f, 0x4987, 0xaa, 0xde, 0xea, 0x0c, 0xef, 0x8f, 0xbf, 0xe8);
+
+struct IEnumExplorerCommand : public IUnknown
+{
+ STDMETHOD (Next) (ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched) = 0;
+ STDMETHOD (Skip) (ULONG celt) = 0;
+ STDMETHOD (Reset) (void) = 0;
+ STDMETHOD (Clone) (IEnumExplorerCommand **ppenum) = 0;
+};
+
+
+enum _EXPCMDSTATE
+{
+ ECS_ENABLED = 0,
+ ECS_DISABLED = 0x1,
+ ECS_HIDDEN = 0x2,
+ ECS_CHECKBOX = 0x4,
+ ECS_CHECKED = 0x8,
+ ECS_RADIOCHECK = 0x10
+};
+
+typedef DWORD EXPCMDSTATE;
+
+/* [v1_enum] */
+enum _EXPCMDFLAGS
+{
+ ECF_DEFAULT = 0,
+ ECF_HASSUBCOMMANDS = 0x1,
+ ECF_HASSPLITBUTTON = 0x2,
+ ECF_HIDELABEL = 0x4,
+ ECF_ISSEPARATOR = 0x8,
+ ECF_HASLUASHIELD = 0x10,
+ ECF_SEPARATORBEFORE = 0x20,
+ ECF_SEPARATORAFTER = 0x40,
+ ECF_ISDROPDOWN = 0x80,
+ ECF_TOGGLEABLE = 0x100,
+ ECF_AUTOMENUICONS = 0x200
+};
+typedef DWORD EXPCMDFLAGS;
+
+
+// MIDL_INTERFACE("a08ce4d0-fa25-44ab-b57c-c7b1c323e0b9")
+DEFINE_GUID(IID_IExplorerCommand, 0xa08ce4d0, 0xfa25, 0x44ab, 0xb5, 0x7c, 0xc7, 0xb1, 0xc3, 0x23, 0xe0, 0xb9);
+
+struct IExplorerCommand : public IUnknown
+{
+ STDMETHOD (GetTitle) (IShellItemArray *psiItemArray, LPWSTR *ppszName) = 0;
+ STDMETHOD (GetIcon) (IShellItemArray *psiItemArray, LPWSTR *ppszIcon) = 0;
+ STDMETHOD (GetToolTip) (IShellItemArray *psiItemArray, LPWSTR *ppszInfotip) = 0;
+ STDMETHOD (GetCanonicalName) (GUID *pguidCommandName) = 0;
+ STDMETHOD (GetState) (IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState) = 0;
+ STDMETHOD (Invoke) (IShellItemArray *psiItemArray, IBindCtx *pbc) = 0;
+ STDMETHOD (GetFlags) (EXPCMDFLAGS *pFlags) = 0;
+ STDMETHOD (EnumSubCommands) (IEnumExplorerCommand **ppEnum) = 0;
+};
+
+#endif // IShellItemArray
+#endif // __IEnumExplorerCommand_INTERFACE_DEFINED__
+#endif // USE_SYS_shobjidl_core
+
+#endif // __MY_EXPLORER_COMMAND_H
diff --git a/CPP/7zip/UI/Explorer/makefile b/CPP/7zip/UI/Explorer/makefile
index 541122ab..1e79cc82 100644
--- a/CPP/7zip/UI/Explorer/makefile
+++ b/CPP/7zip/UI/Explorer/makefile
@@ -65,6 +65,7 @@ FM_OBJS = \
$O\HelpUtils.obj \
$O\LangUtils.obj \
$O\ProgramLocation.obj \
+ $O\PropertyName.obj \
$O\RegistryUtils.obj \
C_OBJS = \
diff --git a/CPP/7zip/UI/Explorer/resource.rc b/CPP/7zip/UI/Explorer/resource.rc
index 80018b45..66592908 100644
--- a/CPP/7zip/UI/Explorer/resource.rc
+++ b/CPP/7zip/UI/Explorer/resource.rc
@@ -6,3 +6,5 @@ MY_VERSION_INFO_DLL("7-Zip Shell Extension", "7-zip")
#ifndef UNDER_CE
1 24 MOVEABLE PURE "7-zip.dll.manifest"
#endif
+
+IDI_ICON ICON "..\FileManager\FM.ico"