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/DllExports.cpp')
-rwxr-xr-xCPP/7zip/UI/Explorer/DllExports.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/CPP/7zip/UI/Explorer/DllExports.cpp b/CPP/7zip/UI/Explorer/DllExports.cpp
new file mode 100755
index 00000000..fb7daf04
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/DllExports.cpp
@@ -0,0 +1,315 @@
+// DLLExports.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 <locale.h>
+
+#include <initguid.h>
+#include <windows.h>
+#include <ShlGuid.h>
+#include <OleCtl.h>
+
+#include "Common/ComTry.h"
+#include "Common/StringConvert.h"
+#include "Windows/DLL.h"
+#include "Windows/Registry.h"
+
+#include "../../IPassword.h"
+#include "../../FileManager/LangUtils.h"
+#include "../Agent/Agent.h"
+
+#include "ContextMenu.h"
+#include "OptionsDialog.h"
+
+using namespace NWindows;
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+#endif
+
+LONG g_DllRefCount = 0; // Reference count of this DLL.
+
+static LPCWSTR kShellExtName = L"7-Zip Shell Extension";
+static LPCTSTR kClsidMask = TEXT("CLSID\\%s");
+static LPCTSTR kClsidInprocMask = TEXT("CLSID\\%s\\InprocServer32");
+static LPCTSTR kApprovedKeyPath = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
+
+// #define ODS(sz) OutputDebugString(L#sz)
+
+class CShellExtClassFactory:
+ public IClassFactory,
+ public CMyUnknownImp
+{
+public:
+ CShellExtClassFactory() { InterlockedIncrement(&g_DllRefCount); }
+ ~CShellExtClassFactory() { InterlockedDecrement(&g_DllRefCount); }
+
+
+ MY_UNKNOWN_IMP1_MT(IClassFactory)
+
+ STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, void**);
+ STDMETHODIMP LockServer(BOOL);
+};
+
+STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
+ REFIID riid, void **ppvObj)
+{
+ // ODS("CShellExtClassFactory::CreateInstance()\r\n");
+ *ppvObj = NULL;
+ if (pUnkOuter)
+ return CLASS_E_NOAGGREGATION;
+
+ CZipContextMenu *shellExt;
+ try
+ {
+ shellExt = new CZipContextMenu();
+ }
+ catch(...) { return E_OUTOFMEMORY; }
+ if (shellExt == NULL)
+ return E_OUTOFMEMORY;
+
+ HRESULT res = shellExt->QueryInterface(riid, ppvObj);
+ if (res != S_OK)
+ delete shellExt;
+ return res;
+}
+
+
+STDMETHODIMP CShellExtClassFactory::LockServer(BOOL /* fLock */)
+{
+ return S_OK; // Check it
+}
+
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
+{
+ // setlocale(LC_COLLATE, ".ACP");
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ // ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n");
+ #ifdef _UNICODE
+ if (!IsItWindowsNT())
+ return FALSE;
+ #else
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ 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");
+ 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 == 0)
+ return E_OUTOFMEMORY;
+ HRESULT res = cf->QueryInterface(riid, ppv);
+ if (res != S_OK)
+ delete cf;
+ return res;
+ }
+ return CLASS_E_CLASSNOTAVAILABLE;
+ // return _Module.GetClassObject(rclsid, riid, ppv);
+}
+
+static BOOL GetStringFromIID(CLSID clsid, LPTSTR s, int size)
+{
+ LPWSTR pwsz;
+ if (StringFromIID(clsid, &pwsz) != S_OK)
+ return FALSE;
+ if(!pwsz)
+ return FALSE;
+ #ifdef UNICODE
+ lstrcpyn(s, pwsz, size);
+ #else
+ WideCharToMultiByte(CP_ACP, 0, pwsz, -1, s, size, NULL, NULL);
+ #endif
+ CoTaskMemFree(pwsz);
+ s[size - 1] = 0;
+ return TRUE;
+}
+
+typedef struct
+{
+ HKEY hRootKey;
+ LPCTSTR SubKey;
+ LPCWSTR ValueName;
+ LPCWSTR Data;
+} CRegItem;
+
+static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
+{
+ TCHAR clsidString[MAX_PATH];
+ if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
+ return FALSE;
+
+ UString modulePath;
+ if (!NDLL::MyGetModuleFileName(g_hInstance, modulePath))
+ return FALSE;
+
+ CRegItem clsidEntries[] =
+ {
+ HKEY_CLASSES_ROOT, kClsidMask, NULL, title,
+ HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePath,
+ HKEY_CLASSES_ROOT, kClsidInprocMask, L"ThreadingModel", L"Apartment",
+ NULL, NULL, NULL, NULL
+ };
+
+ //register the CLSID entries
+ for(int i = 0; clsidEntries[i].hRootKey; i++)
+ {
+ TCHAR subKey[MAX_PATH];
+ wsprintf(subKey, clsidEntries[i].SubKey, clsidString);
+ NRegistry::CKey key;
+ if (key.Create(clsidEntries[i].hRootKey, subKey, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
+ return FALSE;
+ key.SetValue(clsidEntries[i].ValueName, clsidEntries[i].Data);
+ }
+
+ if(IsItWindowsNT())
+ {
+ NRegistry::CKey key;
+ if (key.Create(HKEY_LOCAL_MACHINE, kApprovedKeyPath, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
+ key.SetValue(GetUnicodeString(clsidString), title);
+ }
+ return TRUE;
+}
+
+STDAPI DllRegisterServer(void)
+{
+ return RegisterServer(CLSID_CZipContextMenu, kShellExtName) ? S_OK: SELFREG_E_CLASS;
+}
+
+static BOOL UnregisterServer(CLSID clsid)
+{
+ TCHAR clsidString[MAX_PATH];
+ if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
+ return FALSE;
+
+ TCHAR subKey[MAX_PATH];
+ wsprintf(subKey, kClsidInprocMask, clsidString);
+ RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
+
+ wsprintf (subKey, kClsidMask, clsidString);
+ RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
+
+ if(IsItWindowsNT())
+ {
+ HKEY hKey;
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, kApprovedKeyPath, 0, KEY_SET_VALUE, &hKey) == NOERROR)
+ {
+ RegDeleteValue(hKey, clsidString);
+ RegCloseKey(hKey);
+ }
+ }
+ return TRUE;
+}
+
+STDAPI DllUnregisterServer(void)
+{
+ return UnregisterServer(CLSID_CZipContextMenu) ? S_OK: SELFREG_E_CLASS;
+}
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ LoadLangOneTime();
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID == CLSID_CAgentArchiveHandler)
+ {
+ if (*interfaceID == IID_IFolderManager)
+ {
+ CMyComPtr<IFolderManager> manager = new CArchiveFolderManager;
+ *outObject = manager.Detach();
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+ }
+ if (*classID == CLSID_CSevenZipOptions)
+ {
+ if (*interfaceID == IID_IPluginOptions)
+ {
+ CMyComPtr<IPluginOptions> options = new CSevenZipOptions;
+ *outObject = options.Detach();
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+ }
+ return CLASS_E_CLASSNOTAVAILABLE;
+ COM_TRY_END
+}
+
+STDAPI GetPluginProperty(PROPID propID, PROPVARIANT *value)
+{
+ ::VariantClear((tagVARIANT *)value);
+ switch(propID)
+ {
+ case NPlugin::kName:
+ if ((value->bstrVal = ::SysAllocString(L"7-Zip")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NPlugin::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CAgentArchiveHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NPlugin::kOptionsClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CSevenZipOptions, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ /*
+ case NArchive::kType:
+ propVariant = UINT32(0);
+ break;
+ */
+ }
+ return S_OK;
+}