mirror of
https://github.com/Obfuscator-Collections/VMProtect.git
synced 2026-08-31 20:04:42 +03:00
first commit
Version 3.x.x
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
#include "main.h"
|
||||
#include "initguid.h"
|
||||
#include "context_menu.h"
|
||||
#include <shlwapi.h>
|
||||
|
||||
long dll_ref_count = 0;
|
||||
HMODULE instance = NULL;
|
||||
|
||||
// {6416B534-5A38-47BA-A8DB-4253F49DC7D3}
|
||||
DEFINE_GUID(CLSID_VMPContextMenu,
|
||||
0x6416B534, 0x5A38, 0x47BA, 0xA8, 0xDB, 0x42, 0x53, 0xF4, 0x9D, 0xC7, 0xD3);
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
switch (dwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
instance = hModule;
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* export functions
|
||||
*/
|
||||
|
||||
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
|
||||
{
|
||||
if (IsEqualCLSID(CLSID_VMPContextMenu, rclsid)) {
|
||||
ClassFactory *class_factory;
|
||||
try {
|
||||
class_factory = new ClassFactory();
|
||||
} catch(...) {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (class_factory) {
|
||||
HRESULT res = class_factory->QueryInterface(riid, ppv);
|
||||
class_factory->Release();
|
||||
return res;
|
||||
} else {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
STDAPI DllCanUnloadNow(void)
|
||||
{
|
||||
return dll_ref_count ? S_FALSE : S_OK;
|
||||
}
|
||||
|
||||
static HRESULT SetRegistryKeyAndValue(HKEY root, PCWSTR sub_key, PCWSTR value_name, PCWSTR data)
|
||||
{
|
||||
HKEY key = NULL;
|
||||
HRESULT res = HRESULT_FROM_WIN32(RegCreateKeyExW(root, sub_key, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL));
|
||||
if (SUCCEEDED(res)) {
|
||||
if (data) {
|
||||
DWORD size = lstrlenW(data) * sizeof(*data);
|
||||
res = HRESULT_FROM_WIN32(RegSetValueExW(key, value_name, 0, REG_SZ, reinterpret_cast<const BYTE *>(data), size));
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static HRESULT GetRegistryKeyAndValue(HKEY root, PCWSTR sub_key, PCWSTR value_name, PWSTR data, DWORD size)
|
||||
{
|
||||
HKEY key = NULL;
|
||||
HRESULT res = HRESULT_FROM_WIN32(RegOpenKeyExW(root, sub_key, 0, KEY_READ, &key));
|
||||
if (SUCCEEDED(res)){
|
||||
res = HRESULT_FROM_WIN32(RegQueryValueExW(key, value_name, NULL, NULL, reinterpret_cast<BYTE *>(data), &size));
|
||||
RegCloseKey(key);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static wchar_t *shell_ext_name = L"VMProtect Shell Extension";
|
||||
static wchar_t *cls_id_mask = L"CLSID\\%s";
|
||||
static wchar_t *cls_id_inproc_mask = L"CLSID\\%s\\InprocServer32";
|
||||
static wchar_t *context_menu_key_name = L"*\\shellex\\ContextMenuHandlers\\VMProtect";
|
||||
|
||||
STDAPI DllRegisterServer(void)
|
||||
{
|
||||
wchar_t file_name[MAX_PATH];
|
||||
if (GetModuleFileNameW(instance, file_name, _countof(file_name)) == 0)
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
wchar_t cls_id[MAX_PATH];
|
||||
StringFromGUID2(CLSID_VMPContextMenu, cls_id, _countof(cls_id));
|
||||
|
||||
wchar_t sub_key[MAX_PATH];
|
||||
wsprintfW(sub_key, cls_id_mask, cls_id);
|
||||
HRESULT res = SetRegistryKeyAndValue(HKEY_CLASSES_ROOT, sub_key, NULL, shell_ext_name);
|
||||
if (SUCCEEDED(res)) {
|
||||
wsprintfW(sub_key, cls_id_inproc_mask, cls_id);
|
||||
res = SetRegistryKeyAndValue(HKEY_CLASSES_ROOT, sub_key, NULL, file_name);
|
||||
}
|
||||
if (SUCCEEDED(res))
|
||||
res = SetRegistryKeyAndValue(HKEY_CLASSES_ROOT, sub_key, L"ThreadingModel", L"Apartment");
|
||||
if (SUCCEEDED(res))
|
||||
res = SetRegistryKeyAndValue(HKEY_CLASSES_ROOT, context_menu_key_name, NULL, cls_id);
|
||||
return res;
|
||||
}
|
||||
|
||||
STDAPI DllUnregisterServer(void)
|
||||
{
|
||||
wchar_t cls_id[MAX_PATH];
|
||||
StringFromGUID2(CLSID_VMPContextMenu, cls_id, _countof(cls_id));
|
||||
|
||||
wchar_t sub_key[MAX_PATH];
|
||||
wsprintfW(sub_key, cls_id_inproc_mask, cls_id);
|
||||
HRESULT res = HRESULT_FROM_WIN32(RegDeleteKeyW(HKEY_CLASSES_ROOT, sub_key));
|
||||
if (SUCCEEDED(res)) {
|
||||
wsprintfW(sub_key, cls_id_mask, cls_id);
|
||||
res = HRESULT_FROM_WIN32(RegDeleteKeyW(HKEY_CLASSES_ROOT, sub_key));
|
||||
}
|
||||
if (SUCCEEDED(res))
|
||||
res = HRESULT_FROM_WIN32(RegDeleteKeyW(HKEY_CLASSES_ROOT, context_menu_key_name));
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* ClassFactory
|
||||
*/
|
||||
|
||||
ClassFactory::ClassFactory()
|
||||
: ref_count_(1)
|
||||
{
|
||||
InterlockedIncrement(&dll_ref_count);
|
||||
}
|
||||
|
||||
ClassFactory::~ClassFactory()
|
||||
{
|
||||
InterlockedDecrement(&dll_ref_count);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ClassFactory::QueryInterface(REFIID riid, void **ppv)
|
||||
{
|
||||
static const QITAB qit[] =
|
||||
{
|
||||
QITABENT(ClassFactory, IClassFactory), //-V221
|
||||
{ 0 },
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4838 )
|
||||
};
|
||||
#pragma warning( pop )
|
||||
return QISearch(this, qit, riid, ppv);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) ClassFactory::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&ref_count_);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) ClassFactory::Release()
|
||||
{
|
||||
ULONG res = InterlockedDecrement(&ref_count_);
|
||||
if (!res)
|
||||
delete this;
|
||||
return res;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
|
||||
{
|
||||
if (pUnkOuter)
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
ContextMenuExt *ext;
|
||||
try {
|
||||
ext = new ContextMenuExt();
|
||||
} catch (...) {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (ext) {
|
||||
HRESULT res = ext->QueryInterface(riid, ppv);
|
||||
ext->Release();
|
||||
return res;
|
||||
} else {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ClassFactory::LockServer(BOOL lock)
|
||||
{
|
||||
if (lock)
|
||||
InterlockedIncrement(&dll_ref_count);
|
||||
else
|
||||
InterlockedDecrement(&dll_ref_count);
|
||||
return S_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user