From 6ed0f67abb451cbfb78e7cf819ecdab120fe1e91 Mon Sep 17 00:00:00 2001 From: Tu Dinh Date: Sun, 31 Aug 2025 05:41:19 +0200 Subject: [PATCH] Add NanaZip.LegacyShellExtension drag drop handler. Signed-off-by: Tu Dinh --- BuildAllTargets.proj | 2 + .../NanaZip.LegacyShellExtension.def | 6 + .../NanaZip.LegacyShellExtension.manifest | 14 + .../NanaZip.LegacyShellExtension.vcxproj | 169 +++++ ...naZip.LegacyShellExtension.vcxproj.filters | 688 ++++++++++++++++++ .../7zip/UI/Explorer/DllExportsExplorer.cpp | 270 +++++++ NanaZip.sln | 10 + NanaZipPackage/NanaZipPackage.wapproj | 5 +- NanaZipPackage/Package.appxmanifest | 14 +- 9 files changed, 1175 insertions(+), 3 deletions(-) create mode 100644 NanaZip.UI.Modern/NanaZip.LegacyShellExtension.def create mode 100644 NanaZip.UI.Modern/NanaZip.LegacyShellExtension.manifest create mode 100644 NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj create mode 100644 NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj.filters create mode 100644 NanaZip.UI.Modern/SevenZip/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp diff --git a/BuildAllTargets.proj b/BuildAllTargets.proj index 238b652cc..c7102e4e7 100644 --- a/BuildAllTargets.proj +++ b/BuildAllTargets.proj @@ -80,6 +80,7 @@ + @@ -88,6 +89,7 @@ + diff --git a/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.def b/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.def new file mode 100644 index 000000000..733b8692c --- /dev/null +++ b/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.def @@ -0,0 +1,6 @@ +LIBRARY + +EXPORTS + +DllCanUnloadNow PRIVATE +DllGetClassObject PRIVATE diff --git a/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.manifest b/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.manifest new file mode 100644 index 000000000..f0dc4ff8c --- /dev/null +++ b/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.manifest @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj b/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj new file mode 100644 index 000000000..7ccdc7cec --- /dev/null +++ b/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj @@ -0,0 +1,169 @@ + + + + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2} + NanaZip.LegacyShellExtension + DynamicLibrary + NanaZip.LegacyShellExtension.manifest + 10.0.19041.0 + true + true + false + true + M2-Team + NanaZip Legacy Shell Extension + NanaZip.LegacyShellExtension + © M2-Team and Contributors. All rights reserved. + NanaZip.LegacyShellExtension.dll + NanaZip + + + + + + + + + %(AdditionalOptions) /Wv:18 + LANG;WIN_LONG_PATH;WINRT_NO_SOURCE_LOCATION;%(PreprocessorDefinitions) + + + true + NanaZip.LegacyShellExtension.def + 10.0 + runtimeobject.lib;%(AdditionalDependencies) + + + + + MultiThreadedDebug + MultiThreaded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.2.410 + + + + diff --git a/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj.filters b/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj.filters new file mode 100644 index 000000000..86fceb383 --- /dev/null +++ b/NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj.filters @@ -0,0 +1,688 @@ + + + + + {af758b5f-a415-41fa-9780-2611dee425a9} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {40d384a3-6347-4446-9abd-682016b4f847} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {4dabdb87-f751-4d01-a42e-ca36ddb5d0e1} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Source Files + + + diff --git a/NanaZip.UI.Modern/SevenZip/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp b/NanaZip.UI.Modern/SevenZip/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp new file mode 100644 index 000000000..ba5b139db --- /dev/null +++ b/NanaZip.UI.Modern/SevenZip/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp @@ -0,0 +1,270 @@ +// DLLExportsExplorer.cpp +// +// Notes: +// Win2000: +// If I register at HKCR\Folder\ShellEx then DLL is locked. +// otherwise it unloads after explorer closing. +// but if I call menu for desktop items it's locked all the time + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#if defined(__clang__) && __clang_major__ >= 4 +#pragma GCC diagnostic ignored "-Wnonportable-system-include-path" +#endif +// : in new Windows Kit 10.0.2**** (NTDDI_WIN10_MN is defined) +// : in another Windows Kit versions +#if defined(NTDDI_WIN10_MN) || defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../../Common/MyInitGuid.h" + +#include "../../../Common/ComTry.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/NtCheck.h" +#include "../../../Windows/Registry.h" + +#include "../FileManager/IFolder.h" + +#include "ContextMenu.h" + +// **************** NanaZip Modification Start **************** +static LPCTSTR const k_ShellExtName = TEXT("NanaZip Legacy Shell Extension"); +static LPCTSTR const k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"); + +// {23170F69-40C1-278A-1000-00FE00020000} +static LPCTSTR const k_Clsid = TEXT("{23170F69-40C1-278A-1000-00FE00020000}"); + +DEFINE_GUID(CLSID_CZipContextMenu, + k_7zip_GUID_Data1, + k_7zip_GUID_Data2, + k_7zip_GUID_Data3_Common, + 0x10, 0x00, 0x00, 0xFE, 0x00, 0x02, 0x00, 0x00); +// **************** NanaZip Modification End **************** + +using namespace NWindows; + +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; + +extern +HWND g_HWND; +HWND g_HWND = NULL; + +extern +LONG g_DllRefCount; +LONG g_DllRefCount = 0; // Reference count of this DLL. + +extern +bool g_DisableUserQuestions; +bool g_DisableUserQuestions; + + +// #define ODS(sz) OutputDebugStringW(L#sz) +#define ODS(sz) + +class CShellExtClassFactory final: + public IClassFactory, + public CMyUnknownImp +{ + MY_UNKNOWN_IMP1(IClassFactory) + + STDMETHOD(CreateInstance)(LPUNKNOWN, REFIID, void**) override final; + STDMETHOD(LockServer)(BOOL) override final; +public: + CShellExtClassFactory() { InterlockedIncrement(&g_DllRefCount); } + ~CShellExtClassFactory() { InterlockedDecrement(&g_DllRefCount); } +}; + +STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, + REFIID riid, void **ppvObj) +{ + ODS("CShellExtClassFactory::CreateInstance()\r\n"); + /* + char s[64]; + ConvertUInt32ToHex(riid.Data1, s); + OutputDebugStringA(s); + */ + *ppvObj = NULL; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + CZipContextMenu *shellExt; + try + { + shellExt = new CZipContextMenu(); + } + catch(...) { return E_OUTOFMEMORY; } + if (!shellExt) + return E_OUTOFMEMORY; + + IContextMenu *ctxm = shellExt; + const HRESULT res = ctxm->QueryInterface(riid, ppvObj); + if (res != S_OK) + delete shellExt; + return res; +} + + +STDMETHODIMP CShellExtClassFactory::LockServer(BOOL /* fLock */) +{ + return S_OK; // Check it +} + + +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION return FALSE; +#endif + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE hInstance + #else + HINSTANCE hInstance + #endif + , DWORD dwReason, LPVOID); + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE hInstance + #else + HINSTANCE hInstance + #endif + , DWORD dwReason, LPVOID) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = (HINSTANCE)hInstance; + ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n"); + NT_CHECK + } + else if (dwReason == DLL_PROCESS_DETACH) + { + ODS("In DLLMain, DLL_PROCESS_DETACH\r\n"); + } + return TRUE; +} + + +// Used to determine whether the DLL can be unloaded by OLE + +STDAPI DllCanUnloadNow(void) +{ + 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"); + *ppv = NULL; + if (IsEqualIID(rclsid, CLSID_CZipContextMenu)) + { + CShellExtClassFactory *cf; + try + { + cf = new CShellExtClassFactory; + } + catch(...) { return E_OUTOFMEMORY; } + if (!cf) + return E_OUTOFMEMORY; + IClassFactory *cf2 = cf; + const HRESULT res = cf2->QueryInterface(riid, ppv); + if (res != S_OK) + delete cf; + return res; + } + return CLASS_E_CLASSNOTAVAILABLE; + // return _Module.GetClassObject(rclsid, riid, ppv); +} + + +static BOOL RegisterServer() +{ + ODS("RegisterServer\r\n"); + FString modulePath; + if (!NDLL::MyGetModuleFileName(modulePath)) + return FALSE; + const UString modulePathU = fs2us(modulePath); + + CSysString s ("CLSID\\"); + s += k_Clsid; + + { + NRegistry::CKey key; + if (key.Create(HKEY_CLASSES_ROOT, s, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR) + return FALSE; + key.SetValue(NULL, k_ShellExtName); + NRegistry::CKey keyInproc; + if (keyInproc.Create(key, TEXT("InprocServer32"), NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR) + return FALSE; + keyInproc.SetValue(NULL, modulePathU); + keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment")); + } + + #if !defined(_WIN64) && !defined(UNDER_CE) + if (IsItWindowsNT()) + #endif + { + NRegistry::CKey key; + if (key.Create(HKEY_LOCAL_MACHINE, k_Approved, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR) + key.SetValue(k_Clsid, k_ShellExtName); + } + + ODS("RegisterServer :: return TRUE"); + return TRUE; +} + +STDAPI DllRegisterServer(void) +{ + return RegisterServer() ? S_OK: SELFREG_E_CLASS; +} + +static BOOL UnregisterServer() +{ + CSysString s ("CLSID\\"); + s += k_Clsid; + + RegDeleteKey(HKEY_CLASSES_ROOT, s + TEXT("\\InprocServer32")); + RegDeleteKey(HKEY_CLASSES_ROOT, s); + + #if !defined(_WIN64) && !defined(UNDER_CE) + if (IsItWindowsNT()) + #endif + { + HKEY hKey; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, k_Approved, 0, KEY_SET_VALUE, &hKey) == NOERROR) + { + RegDeleteValue(hKey, k_Clsid); + RegCloseKey(hKey); + } + } + + return TRUE; +} + +STDAPI DllUnregisterServer(void) +{ + return UnregisterServer() ? S_OK: SELFREG_E_CLASS; +} diff --git a/NanaZip.sln b/NanaZip.sln index 0dfe70a2f..e33256650 100644 --- a/NanaZip.sln +++ b/NanaZip.sln @@ -55,6 +55,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NanaZip.Codecs.Sfx.Shared", EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NanaZip.Modern", "NanaZip.Modern\NanaZip.Modern.vcxproj", "{1AB11057-1F48-44D2-A913-C945BFC1AA93}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NanaZip.LegacyShellExtension", "NanaZip.UI.Modern\NanaZip.LegacyShellExtension.vcxproj", "{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM64 = Debug|ARM64 @@ -217,6 +219,14 @@ Global {1AB11057-1F48-44D2-A913-C945BFC1AA93}.Release|ARM64.Build.0 = Release|ARM64 {1AB11057-1F48-44D2-A913-C945BFC1AA93}.Release|x64.ActiveCfg = Release|x64 {1AB11057-1F48-44D2-A913-C945BFC1AA93}.Release|x64.Build.0 = Release|x64 + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|ARM64.Build.0 = Debug|ARM64 + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|x64.ActiveCfg = Debug|x64 + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|x64.Build.0 = Debug|x64 + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|ARM64.ActiveCfg = Release|ARM64 + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|ARM64.Build.0 = Release|ARM64 + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|x64.ActiveCfg = Release|x64 + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/NanaZipPackage/NanaZipPackage.wapproj b/NanaZipPackage/NanaZipPackage.wapproj index 2c83533ed..5ba540644 100644 --- a/NanaZipPackage/NanaZipPackage.wapproj +++ b/NanaZipPackage/NanaZipPackage.wapproj @@ -1,4 +1,4 @@ - + @@ -69,6 +69,9 @@ {3E5B58DE-4FDC-4F45-93A4-8AA3D61C614D} + + {F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2} + diff --git a/NanaZipPackage/Package.appxmanifest b/NanaZipPackage/Package.appxmanifest index 9e333a184..f5e3c08fc 100644 --- a/NanaZipPackage/Package.appxmanifest +++ b/NanaZipPackage/Package.appxmanifest @@ -1,4 +1,4 @@ - + + IgnorableNamespaces="uap rescap desktop uap2 uap3 com desktop4 desktop5 desktop9 desktop10 uap8 uap10 virtualization uap16 uap17"> + + + + + + + + +