#include #include #include "ClassFactoryContextMenuExt.h" #include "ClassFactoryShellExtSynced.h" #include "ClassFactoryShellExtPending.h" #include "ClassFactoryShellExtSyncing.h" #include "RegUtils.h" #include STDAPI DllRegisterServer(void); STDAPI DllUnregisterServer(void); // {0229E5E7-09E9-45CF-9228-0228EC7D5F17} const CLSID CLSID_ContextMenuExt = { 0x229e5e7, 0x9e9, 0x45cf, { 0x92, 0x28, 0x2, 0x28, 0xec, 0x7d, 0x5f, 0x17 } }; const TCHAR ContextMenuExtFriendlyNameOld[] = L"###MegaContextMenuExt"; const TCHAR ContextMenuExtFriendlyName[] = L"MEGA (Context menu)"; // {05B38830-F4E9-4329-978B-1DD28605D202} const CLSID CLSID_ShellExtSynced = { 0x5B38830, 0xF4E9, 0x4329, { 0x97, 0x8B, 0x1D, 0xD2, 0x86, 0x05, 0xD2, 0x02 } }; const TCHAR ShellExtSyncedFriendlyNameOld[] = L"###MegaShellExtSynced"; const TCHAR ShellExtSyncedFriendlyName[] = L"\x01 MEGA (Synced)"; //{056D528D-CE28-4194-9BA3-BA2E9197FF8C} const CLSID CLSID_ShellExtPending = { 0x56D528D, 0xCE28, 0x4194, { 0x9B, 0xA3, 0xBA, 0x2E, 0x91, 0x97, 0xFF, 0x8C } }; const TCHAR ShellExtPendingFriendlyNameOld[] = L"###MegaShellExtPending"; const TCHAR ShellExtPendingFriendlyName[] = L"\x01 MEGA (Pending)"; // {0596C850-7BDD-4C9D-AFDF-873BE6890637} const CLSID CLSID_ShellExtSyncing = { 0x596c850, 0x7bdd, 0x4c9d, { 0xaf, 0xdf, 0x87, 0x3b, 0xe6, 0x89, 0x6, 0x37 } }; const TCHAR ShellExtSyncingFriendlyNameOld[] = L"###MegaShellExtSyncing"; const TCHAR ShellExtSyncingFriendlyName[] = L"\x01 MEGA (Syncing)"; HINSTANCE g_hInst = NULL; long g_cDllRef = 0; BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: g_hInst = hModule; DisableThreadLibraryCalls(hModule); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) { HRESULT hr = CLASS_E_CLASSNOTAVAILABLE; ClassFactory *pClassFactory = NULL; if (ppv == NULL) { return E_POINTER; } *ppv = NULL; if (IsEqualCLSID(CLSID_ContextMenuExt, rclsid)) { hr = E_OUTOFMEMORY; pClassFactory = new (std::nothrow) ClassFactoryContextMenuExt(); } else if (IsEqualCLSID(CLSID_ShellExtSynced, rclsid)) { hr = E_OUTOFMEMORY; pClassFactory = new (std::nothrow) ClassFactoryShellExtSynced(); } else if (IsEqualCLSID(CLSID_ShellExtPending, rclsid)) { hr = E_OUTOFMEMORY; pClassFactory = new (std::nothrow) ClassFactoryShellExtPending(); } else if (IsEqualCLSID(CLSID_ShellExtSyncing, rclsid)) { hr = E_OUTOFMEMORY; pClassFactory = new (std::nothrow) ClassFactoryShellExtSyncing(); } if (pClassFactory) { hr = pClassFactory->QueryInterface(riid, ppv); pClassFactory->Release(); } return hr; } // // FUNCTION: DllCanUnloadNow // // PURPOSE: Check if we can unload the component from the memory. // // NOTE: The component can be unloaded from the memory when its reference // count is zero (i.e. nobody is still using the component). // STDAPI DllCanUnloadNow(void) { return g_cDllRef > 0 ? S_FALSE : S_OK; } // // FUNCTION: DllRegisterServer // // PURPOSE: Register the COM server and the context menu handler. // STDAPI DllRegisterServer(void) { __try { DllUnregisterServer(); HRESULT hr = S_OK; TCHAR szModule[MAX_PATH]; if (GetModuleFileName(g_hInst, szModule, MAX_PATH) == 0) { hr = HRESULT_FROM_WIN32(GetLastError()); return hr; } // Register the component. hr = RegisterInprocServer(szModule, CLSID_ContextMenuExt, ContextMenuExtFriendlyName, L"Apartment"); if (!SUCCEEDED(hr)) return hr; // Register the context menu handler. The context menu handler is // associated with the .cpp file class. hr = RegisterShellExtContextMenuHandler(L"*", CLSID_ContextMenuExt, ContextMenuExtFriendlyName); if (!SUCCEEDED(hr)) return hr; hr = RegisterShellExtContextMenuHandler(L"AllFilesystemObjects", CLSID_ContextMenuExt, ContextMenuExtFriendlyName); if (!SUCCEEDED(hr)) return hr; hr = RegisterShellExtContextMenuHandler(L"Drive", CLSID_ContextMenuExt, ContextMenuExtFriendlyName); if (!SUCCEEDED(hr)) return hr; hr = RegisterInprocServer(szModule, CLSID_ShellExtSynced, ShellExtSyncedFriendlyName, L"Apartment"); if (!SUCCEEDED(hr)) return hr; hr = RegisterShellExtIconHandler(CLSID_ShellExtSynced, ShellExtSyncedFriendlyName); if (!SUCCEEDED(hr)) return hr; hr = RegisterInprocServer(szModule, CLSID_ShellExtPending, ShellExtPendingFriendlyName, L"Apartment"); if (!SUCCEEDED(hr)) return hr; hr = RegisterShellExtIconHandler(CLSID_ShellExtPending, ShellExtPendingFriendlyName); if (!SUCCEEDED(hr)) return hr; hr = RegisterInprocServer(szModule, CLSID_ShellExtSyncing, ShellExtSyncingFriendlyName, L"Apartment"); if (!SUCCEEDED(hr)) return hr; hr = RegisterShellExtIconHandler(CLSID_ShellExtSyncing, ShellExtSyncingFriendlyName); return hr; } __except(EXCEPTION_EXECUTE_HANDLER) { } return E_UNEXPECTED; } // // FUNCTION: DllUnregisterServer // // PURPOSE: Unregister the COM server and the context menu handler. // STDAPI DllUnregisterServer(void) { __try { HRESULT hr = S_OK; TCHAR szModule[MAX_PATH]; if (GetModuleFileName(g_hInst, szModule, MAX_PATH) == 0) { hr = HRESULT_FROM_WIN32(GetLastError()); return hr; } // Unregister the component. hr = UnregisterInprocServer(CLSID_ContextMenuExt); if (!SUCCEEDED(hr)) return hr; hr = UnregisterInprocServer(CLSID_ShellExtSynced); if (!SUCCEEDED(hr)) return hr;; hr = UnregisterInprocServer(CLSID_ShellExtPending); if (!SUCCEEDED(hr)) return hr; hr = UnregisterInprocServer(CLSID_ShellExtSyncing); if (!SUCCEEDED(hr)) return hr; UnregisterShellExtContextMenuHandler(L"*", CLSID_ContextMenuExt, ContextMenuExtFriendlyNameOld); UnregisterShellExtContextMenuHandler(L"*", CLSID_ContextMenuExt, ContextMenuExtFriendlyName); UnregisterShellExtContextMenuHandler(L"AllFilesystemObjects", CLSID_ContextMenuExt, ContextMenuExtFriendlyName); UnregisterShellExtContextMenuHandler(L"Drive", CLSID_ContextMenuExt, ContextMenuExtFriendlyName); UnregisterShellExtIconHandler(CLSID_ShellExtSynced, ShellExtSyncedFriendlyNameOld); UnregisterShellExtIconHandler(CLSID_ShellExtSynced, ShellExtSyncedFriendlyName); UnregisterShellExtIconHandler(CLSID_ShellExtPending, ShellExtPendingFriendlyNameOld); UnregisterShellExtIconHandler(CLSID_ShellExtPending, ShellExtPendingFriendlyName); UnregisterShellExtIconHandler(CLSID_ShellExtSyncing, ShellExtSyncingFriendlyNameOld); UnregisterShellExtIconHandler(CLSID_ShellExtSyncing, ShellExtSyncingFriendlyName); return hr; } __except(EXCEPTION_EXECUTE_HANDLER) { } return E_UNEXPECTED; }