www.pudn.com > dllregshex_src.zip > dllregshex.cpp


#include "dllreg_xhdr.h" 
#include  
#include "dllregshex.h" 
#include "dllreg_util.h" 
#include "resource.h" 
 
#ifndef __CLSID_NTSrv_Defined__ 
#define __CLSID_NTSrv_Defined__ 
DEFINE_GUID(CLSID_DLLRegisterer, 0x25d84cb0, 0x7345, 0x11d3, 0xa4, 0xa1, 0x0, 0x80, 0xc8, 0xec, 0xfe, 0xd4); 
#endif 
 
UINT      g_cRefThisDll = 0;     
HINSTANCE g_hmodThisDll = NULL;	 
 
HBITMAP hBmp_Install	= 0; 
HBITMAP hBmp_Uninstall  = 0; 
HBITMAP hBmp_About		= 0; 
HMENU	hSubMenu		= 0; 
 
typedef struct 
{ 
   HKEY  hRootKey; 
   LPTSTR lpszSubKey; 
   LPTSTR lpszValueName; 
   LPTSTR lpszData; 
} REGSTRUCT, *LPREGSTRUCT; 
 
STDAPI DllRegisterServer(void); 
STDAPI DllUnregisterServer(void); 
 
VOID   _LoadResources(); 
VOID   _UnloadResources(); 
 
STDAPI  
DllRegisterServer(void) 
{ 
	HINSTANCE hInst = g_hmodThisDll; 
 
	int      i; 
	HKEY     hKey; 
	LRESULT  lResult; 
	DWORD    dwDisp; 
	TCHAR    szSubKey[MAX_PATH]; 
	TCHAR    szCLSID[MAX_PATH]; 
	TCHAR    szModule[MAX_PATH]; 
	LPWSTR   pwszShellExt; 
 
	StringFromIID(CLSID_DLLRegisterer, &pwszShellExt); 
 
	if (pwszShellExt)  
	{ 
		WideCharToLocal(szCLSID, pwszShellExt, ARRAYSIZE(szCLSID)); 
 
		LPMALLOC pMalloc; 
		CoGetMalloc(1, &pMalloc); 
		if(pMalloc) 
		{ 
			pMalloc->Free(pwszShellExt); 
			pMalloc->Release(); 
		} 
	}															    
 
	GetModuleFileName(hInst, szModule, ARRAYSIZE(szModule)); 
	REGSTRUCT ShExClsidEntries[] =  
	{ 
		HKEY_CLASSES_ROOT,	TEXT("CLSID\\%s"),					NULL,                   TEXT(DLLREGUNREGNAME), 
		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; 
   }                                 
 
	REGSTRUCT OtherShExEntries[] =  
	{ 
			HKEY_LOCAL_MACHINE,	TEXT("software\\classes\\clsid\\"DLLREGUNREGNAME)			  , NULL,		TEXT("%s"), 
			HKEY_CLASSES_ROOT,	TEXT("dllfile\\shellex\\ContextMenuHandlers\\"DLLREGUNREGNAME), 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; 
	} 
 
	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, DLLREGUNREGNAME); 
			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_DLLRegisterer, &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("dllfile\\shellex\\ContextMenuHandlers\\"DLLREGUNREGNAME), 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)   
	{ 
		lstrcpy( szSubKey, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved\\"DLLREGUNREGNAME)); 
		lResult = RegDeleteKey(HKEY_LOCAL_MACHINE, szSubKey); 
	} 
 
	return S_OK; 
} 
 
extern "C"  
int APIENTRY 
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 
{ 
	_UNUSED_PARAMETER(lpReserved); 
 
    if (dwReason == DLL_PROCESS_ATTACH) 
	{ 
        g_hmodThisDll = hInstance; 
		_LoadResources(); 
	} 
	else 
		_UnloadResources(); 
 
    return 1; 
} 
 
VOID 
_LoadResources(VOID) 
{ 
	hBmp_Install	= LoadBitmap(g_hmodThisDll, MAKEINTRESOURCE(IDB_INSTALLA)); 
	hBmp_Uninstall  = LoadBitmap(g_hmodThisDll, MAKEINTRESOURCE(IDB_UNINSTALLA)); 
	hBmp_About		= LoadBitmap(g_hmodThisDll, MAKEINTRESOURCE(IDB_ABOUTA)); 
} 
 
VOID 
_UnloadResources(VOID) 
{ 
	DeleteObject(hBmp_Install); 
	DeleteObject(hBmp_Uninstall); 
	DeleteObject(hBmp_About); 
 
	DestroyMenu(hSubMenu); 
} 
 
STDAPI  
DllCanUnloadNow(void) 
{ 
    return (g_cRefThisDll == 0 ? S_OK : S_FALSE); 
} 
 
STDAPI  
DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut) 
{ 
    *ppvOut = NULL; 
 
    if (IsEqualIID(rclsid, CLSID_DLLRegisterer)) 
    { 
        CDllRegSxClassFactory *pcf = new CDllRegSxClassFactory; 
        return pcf->QueryInterface(riid, ppvOut); 
    } 
	 
    return CLASS_E_CLASSNOTAVAILABLE; 
} 
 
CDllRegSxClassFactory::CDllRegSxClassFactory() 
{ 
    m_cRef = 0L; 
    g_cRefThisDll++;	 
} 
																 
CDllRegSxClassFactory::~CDllRegSxClassFactory()				 
{ 
    g_cRefThisDll--; 
} 
 
STDMETHODIMP  
CDllRegSxClassFactory::QueryInterface(REFIID riid, LPVOID FAR *ppv) 
{ 
    *ppv = NULL; 
 
    if(IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) 
    { 
        *ppv = (LPCLASSFACTORY)this; 
        AddRef(); 
 
        return NOERROR; 
    } 
 
    return E_NOINTERFACE; 
}	 
 
STDMETHODIMP_(ULONG)  
CDllRegSxClassFactory::AddRef() 
{ 
    return ++m_cRef; 
} 
 
STDMETHODIMP_(ULONG)  
CDllRegSxClassFactory::Release() 
{ 
    if (--m_cRef) 
        return m_cRef; 
 
    delete this; 
    return 0L; 
} 
 
STDMETHODIMP  
CDllRegSxClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj) 
{ 
    *ppvObj = NULL; 
 
    if (pUnkOuter) 
    	return CLASS_E_NOAGGREGATION; 
 
    LPCSHELLEXT pShellExt = new CShellExt(); 
    if (NULL == pShellExt) 
    	return E_OUTOFMEMORY; 
 
    return pShellExt->QueryInterface(riid, ppvObj); 
} 
 
STDMETHODIMP  
CDllRegSxClassFactory::LockServer(BOOL fLock) 
{ 
	_UNUSED_PARAMETER(fLock); 
 
    return NOERROR; 
} 
 
CShellExt::CShellExt() 
{ 
    m_cRef = 0L; 
    m_pDataObj = NULL; 
 
    g_cRefThisDll++; 
} 
 
CShellExt::~CShellExt() 
{ 
    if (m_pDataObj) 
        m_pDataObj->Release(); 
 
    g_cRefThisDll--; 
} 
 
STDMETHODIMP  
CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv) 
{ 
    *ppv = NULL; 
    if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown)) 
    	*ppv = (LPSHELLEXTINIT)this; 
    else if (IsEqualIID(riid, IID_IContextMenu)) 
        *ppv = (LPCONTEXTMENU)this; 
 
    if(*ppv) 
    { 
        AddRef(); 
        return NOERROR; 
    } 
 
	return E_NOINTERFACE; 
} 
 
STDMETHODIMP_(ULONG)  
CShellExt::AddRef() 
{ 
    return ++m_cRef; 
} 
 
STDMETHODIMP_(ULONG)  
CShellExt::Release() 
{ 
    if(--m_cRef) 
        return m_cRef; 
 
    delete this; 
    return 0L; 
} 
 
STDMETHODIMP  
CShellExt::Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hRegKey) 
{ 
	_UNUSED_PARAMETER(hRegKey); 
	_UNUSED_PARAMETER(pIDFolder); 
 
	if (m_pDataObj) 
    	m_pDataObj->Release(); 
    if (pDataObj) 
    { 
    	m_pDataObj = pDataObj; 
    	pDataObj->AddRef(); 
    } 
    return NOERROR; 
}