#include "mkexesvc.h"
#include "SvcEx.h"
#include "SvcUtils.h"
#include "resource.h"
#include <olectl.h>
typedef struct _REGSTRUCT
{
HKEY hRootKey;
LPTSTR lpszSubKey;
LPTSTR lpszValueName;
LPTSTR lpszData;
} REGSTRUCT, *LPREGSTRUCT;
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
extern ULONG g_cDllRef = 0L;
extern HINSTANCE g_hDll = (HINSTANCE)NULL;
extern HMENU g_hSubMenu = (HMENU)NULL;
extern HMENU g_hLVDepsFloatMenu = (HMENU)NULL;
extern HIMAGELIST g_hDepsImageList = (HIMAGELIST)NULL;
extern DWORD g_dwLastError = 0L;
// {ED7F189F-F6CA-4513-9356-8454B8017525}
#ifndef __CLSID_MkExeSvc_Defined__
#define __CLSID_MkExeSvc_Defined__
DEFINE_GUID(CLSID_MkExeSvc, 0xed7f189f, 0xf6ca, 0x4513, 0x93, 0x56, 0x84, 0x54, 0xb8, 0x1, 0x75, 0x25);
#endif
extern "C"
int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
g_hDll = hInstance;
LoadResources();
}
else if (dwReason == DLL_PROCESS_DETACH)
{
UnloadResources();
}
return 1;
}
STDAPI
DllCanUnloadNow(void)
{
return g_cDllRef == 0 ? S_OK : S_FALSE;
}
STDAPI
DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
{
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
*ppvOut = NULL;
if (IsEqualIID(rclsid, CLSID_MkExeSvc))
{
ISvcExClassFactory *pcf = new ISvcExClassFactory;
hr = pcf->QueryInterface(riid, ppvOut);
}
return hr;
}
STDAPI
DllRegisterServer(void)
{
HINSTANCE hInst = g_hDll;
int i;
HKEY hKey;
LRESULT lResult;
DWORD dwDisp;
TCHAR szSubKey[MAX_PATH];
TCHAR szCLSID[MAX_PATH];
TCHAR szModule[MAX_PATH];
LPWSTR pwszShellExt;
StringFromIID(CLSID_MkExeSvc, &pwszShellExt);
if (pwszShellExt)
{
WideCharToLocal(szCLSID, pwszShellExt, ARRAYSIZE(szCLSID));
LPMALLOC pMalloc;
CoGetMalloc(1, &pMalloc);
if(pMalloc)
{
pMalloc->Free(pwszShellExt);
pMalloc->Release();
}
}
GetModuleFileName(hInst, szModule, _MAX_PATH + 1);
REGSTRUCT ShExClsidEntries[] =
{
HKEY_CLASSES_ROOT, TEXT("CLSID\\%s"), NULL, TEXT(DLLDESCNAME),
HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InProcServer32"), NULL, TEXT("%s"),
HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InProcServer32"), TEXT("ThreadingModel"), TEXT("Apartment"),
NULL, NULL, NULL, NULL
};
for(i = 0; ShExClsidEntries[i].hRootKey; i++)
{
wsprintf(szSubKey, ShExClsidEntries[i].lpszSubKey, szCLSID);
lResult = RegCreateKeyEx(ShExClsidEntries[i].hRootKey, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &hKey, &dwDisp);
if(NOERROR == lResult)
{
TCHAR szData[MAX_PATH];
wsprintf(szData, ShExClsidEntries[i].lpszData, szModule);
lResult = RegSetValueEx(hKey, ShExClsidEntries[i].lpszValueName, 0, REG_SZ,
(LPBYTE)szData, lstrlen(szData) + 1);
RegCloseKey(hKey);
}
else
return SELFREG_E_CLASS;
}
// Other necessary registry entries.
REGSTRUCT OtherShExEntries[] =
{
HKEY_LOCAL_MACHINE, TEXT("software\\classes\\clsid\\"DLLDESCNAME) , NULL, TEXT("%s"),
HKEY_CLASSES_ROOT, TEXT("exefile\\shellex\\ContextMenuHandlers\\"DLLDESCNAME), NULL, TEXT("%s"),
NULL, NULL, NULL, NULL
};
for (i = 0; OtherShExEntries[i].hRootKey; i++)
{
wsprintf(szSubKey, OtherShExEntries[i].lpszSubKey, szCLSID);
lResult = RegCreateKeyEx(OtherShExEntries[i].hRootKey, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &hKey, &dwDisp);
if(NOERROR == lResult)
{
TCHAR szData[MAX_PATH];
wsprintf(szData, OtherShExEntries[i].lpszData, szCLSID);
lResult = RegSetValueEx(hKey, OtherShExEntries[i].lpszValueName, 0, REG_SZ,
(LPBYTE)szData, lstrlen(szData) + 1);
RegCloseKey(hKey);
}
else
return SELFREG_E_CLASS;
}
// Register extension as 'Approved' under WindowsNT.
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)
{
lstrcpy( szSubKey, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"));
lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE,
NULL, &hKey, &dwDisp);
if(NOERROR == lResult)
{
TCHAR szData[MAX_PATH];
lstrcpy(szData, DLLDESCNAME);
lResult = RegSetValueEx(hKey, szCLSID, 0, REG_SZ, (LPBYTE)szData, lstrlen(szData) + 1);
RegCloseKey(hKey);
}
else
return SELFREG_E_CLASS;
}
return S_OK;
}
STDAPI
DllUnregisterServer(void)
{
int i;
LRESULT lResult;
TCHAR szSubKey[MAX_PATH];
TCHAR szCLSID[MAX_PATH];
LPWSTR pwszShellExt;
StringFromIID(CLSID_MkExeSvc, &pwszShellExt);
if (pwszShellExt)
{
WideCharToLocal(szCLSID, pwszShellExt, ARRAYSIZE(szCLSID));
LPMALLOC pMalloc;
CoGetMalloc(1, &pMalloc);
if(pMalloc)
{
pMalloc->Free(pwszShellExt);
pMalloc->Release();
}
}
REGSTRUCT ShExClsidEntries[] =
{
HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InProcServer32"), NULL, NULL,
HKEY_CLASSES_ROOT, TEXT("CLSID\\%s"), NULL, NULL,
NULL, NULL, NULL, NULL
};
for(i = 0; ShExClsidEntries[i].hRootKey; i++)
{
wsprintf(szSubKey, ShExClsidEntries[i].lpszSubKey, szCLSID);
lResult = RegDeleteKey(ShExClsidEntries[i].hRootKey, szSubKey);
if(lResult != NOERROR)
return SELFREG_E_CLASS;
}
REGSTRUCT OtherShExEntries[] =
{
HKEY_CLASSES_ROOT, TEXT("exefile\\shellex\\ContextMenuHandlers\\"DLLDESCNAME), NULL, NULL,
NULL, NULL, NULL, NULL
};
for(i = 0; OtherShExEntries[i].hRootKey; i++)
{
wsprintf(szSubKey, OtherShExEntries[i].lpszSubKey, szCLSID);
lResult = RegDeleteKey(OtherShExEntries[i].hRootKey, szSubKey);
if(lResult != NOERROR)
return SELFREG_E_CLASS;
}
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
if(VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)
{
HKEY hkShExApproved;
lResult = RegOpenKey(HKEY_LOCAL_MACHINE,
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), &hkShExApproved);
if(lResult == NO_ERROR)
{
lResult = RegDeleteValue(hkShExApproved, szCLSID);
RegCloseKey(hkShExApproved);
}
if(lResult != NOERROR)
return SELFREG_E_CLASS;
}
return S_OK;
}
void
LoadResources(void)
{
INITCOMMONCONTROLSEX iccEx;
iccEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccEx.dwICC =
ICC_LISTVIEW_CLASSES | // list view
ICC_PROGRESS_CLASS | // progress bar
ICC_TREEVIEW_CLASSES | // tree view & tooltip
ICC_BAR_CLASSES | // toolbar, status bar, trackbar & tooltip
ICC_UPDOWN_CLASS | // up-down
ICC_USEREX_CLASSES | // extended combo box
ICC_TAB_CLASSES | // tab & tooltip
ICC_COOL_CLASSES | // rebar
0;
InitCommonControlsEx(&iccEx);
if(g_hSubMenu == (HMENU)NULL)
{
g_hSubMenu = CreateMenu();
}
if(g_hLVDepsFloatMenu == (HMENU)NULL)
{
g_hLVDepsFloatMenu = LoadMenu(g_hDll, MAKEINTRESOURCE(IDM_LVDEPSUPDOWN));
}
if(g_hDepsImageList == (HIMAGELIST)NULL)
{
g_hDepsImageList =
ImageList_LoadImage
(
g_hDll,
MAKEINTRESOURCE(IDB_DEPS),
16,
0,
(COLORREF)(RGB(255, 255, 255)),
IMAGE_BITMAP,
LR_LOADTRANSPARENT
);
}
}
void
UnloadResources(void)
{
if(g_hSubMenu)
{
DestroyMenu(g_hSubMenu);
g_hSubMenu = (HMENU)NULL;
}
if(g_hLVDepsFloatMenu)
{
DestroyMenu(g_hLVDepsFloatMenu);
g_hLVDepsFloatMenu = (HMENU)NULL;
}
if(g_hDepsImageList)
{
ImageList_Destroy(g_hDepsImageList);
g_hDepsImageList = (HIMAGELIST)NULL;
}
}