www.pudn.com > ctxmenu_src.rar > ShellExtReg.cpp


 
#include "stdafx.h" 
#include "resource.h" 
#include "CtxMenu.h" 
#include  
#include  
#include  
#include  
#include  
#include "SHUtils.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////// 
// registry key util struct 
typedef struct 
{ 
   HKEY  hRootKey; 
   LPTSTR lpszSubKey; 
   LPTSTR lpszValueName; 
   LPTSTR lpszData; 
}REGSTRUCT, *LPREGSTRUCT; 
 
STDAPI RegisterFileMenu(); 
STDAPI UnregisterFileMenu(); 
 
/************************************************************************** 
 
	STDAPI DllRegisterServer(void) 
 
	Set the Registry keys for this set of shell/namespace extensions 
 
**************************************************************************/ 
STDAPI DllRegisterServer(void) 
{ 
	// if we do MFC stuff in an exported fn, call this first! 
	AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 
 
	HRESULT h = RegisterFileMenu(); 
 
	return h; 
} 
 
 
STDAPI DllUnregisterServer(void) 
{ 
	// if we do MFC stuff in an exported fn, call this first! 
	AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 
 
	HRESULT h = UnregisterFileMenu(); 
 
	return h; 
} 
 
 
STDAPI RegisterFileMenu() 
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 
	 
	HINSTANCE hInst = AfxGetInstanceHandle(); 
	 
	int      i; 
	HKEY     hKey; 
	LRESULT  lResult; 
	DWORD    dwDisp; 
	TCHAR    szSubKey[MAX_PATH]; 
	TCHAR    szCLSID[MAX_PATH]; 
	TCHAR    szModule[MAX_PATH]; 
	LPWSTR   pwszShellExt; 
	 
	//get the CLSID in string form 
	StringFromIID(CLSID_MyFileCtxMenuID, &pwszShellExt);			     
	 
	if (pwszShellExt) { 
		WideCharToLocal(szCLSID, pwszShellExt, ARRAYSIZE(szCLSID)); 
		 
		//free the string 
		LPMALLOC pMalloc; 
		CoGetMalloc(1, &pMalloc); 
		if(pMalloc) 
		{ 
			pMalloc->Free(pwszShellExt); 
			pMalloc->Release(); 
		} 
	}															    
	 
	//get this DLL's path and file name																     
	GetModuleFileName(hInst, szModule, ARRAYSIZE(szModule)); 
	 
	// these entries have their %s's replaced with CLSID strings, 
	// their second entries are replaced with the module's path. 
	//register the CLSID entries 
	REGSTRUCT ShExClsidEntries[] = {   
		 
		// this is the 	HKEY_CLASSES_ROOT/CLSID/ entry. this is where we place info about our shell ext. 
		// our CLSID (generated by GUIDGEN) is how the system refers to our shell extension. 
		HKEY_CLASSES_ROOT,	TEXT("CLSID\\%s"),					NULL,                   TEXT(SHELLEXNAME), 
			 
			// HKEY_CLASSES_ROOT/CLSID//InProcServer . here, we tell the system where our DLL is located 
			HKEY_CLASSES_ROOT,	TEXT("CLSID\\%s\\InProcServer32"),	NULL,                   TEXT("%s"), 
			 
			// HKEY_CLASSES_ROOT/CLSID//InProcServer/ThreadingModel = Apartment . this is a standard thing. don't modify it 
			HKEY_CLASSES_ROOT,	TEXT("CLSID\\%s\\InProcServer32"),	TEXT("ThreadingModel"), TEXT("Apartment"), 
			 
			// end the array 
			NULL,                NULL,								NULL,                   NULL}; 
		 
		for(i = 0; ShExClsidEntries[i].hRootKey; i++)  
		{ 
			//Create the sub key string. 
			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]; 
				 
				//if necessary, create the value string 
				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; 
		}                                 
		 
		// these entries have their %s's replaced with CLSID strings - one per entry, please 
		REGSTRUCT OtherShExEntries[] = {   
			// HKEY_CLASSES_ROOT/*/shellex/ContextMenuHandlers/SHELLEXNAME. tell the system that we want our 
			// shell extension to handle all files: note the "*". ex. we could easily limit it to JPG files by 
			// changing the "*" to ".jpg". 
			// our CLSID is placed in the "%s", and so, explorer will take that CLSID, look in HKEY_CLASSES_ROOT/CLSID 
			// to find a matching CLSID and use the info in there to find our DLL... whew.  
			HKEY_CLASSES_ROOT,	TEXT("*\\shellex\\ContextMenuHandlers\\"SHELLEXNAME), NULL,		TEXT("%s"), 
				 
				// end the array 
				NULL, NULL, NULL, NULL}; 
			 
			for (i = 0; OtherShExEntries[i].hRootKey; i++)  
			{ 
				//Create the sub key string. 
				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]; 
					 
					//if necessary, create the value string 
					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; 
			} 
			 
			//If running on NT, register the extension as approved. 
			OSVERSIONINFO  osvi; 
			 
			osvi.dwOSVersionInfoSize = sizeof(osvi); 
			GetVersionEx(&osvi); 
			 
			// NT needs to have shell extensions "approved". 
			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]; 
					 
					//Create the value string. 
					lstrcpy(szData, TEXT(SHELLEXNAME)); 
					 
					lResult = RegSetValueEx(   hKey, 
						szCLSID, 
						0, 
						REG_SZ, 
						(LPBYTE)szData, 
						lstrlen(szData) + 1); 
					 
					RegCloseKey(hKey); 
				} else 
					return SELFREG_E_CLASS; 
			} 
			 
			return S_OK; 
} 
 
 
/************************************************************************** 
**************************************************************************/ 
STDAPI UnregisterFileMenu(void) 
{ 
	// if we do MFC stuff in an exported fn, call this first! 
	AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 
 
	HINSTANCE hInst = AfxGetInstanceHandle(); 
 
	int      i; 
	LRESULT  lResult; 
	TCHAR    szSubKey[MAX_PATH]; 
	TCHAR    szCLSID[MAX_PATH]; 
	LPWSTR   pwszShellExt; 
 
	//get the CLSID in string form 
	StringFromIID(CLSID_MyFileCtxMenuID, &pwszShellExt);			     
 
	if (pwszShellExt) { 
		WideCharToLocal(szCLSID, pwszShellExt, ARRAYSIZE(szCLSID)); 
 
		//free the string 
		LPMALLOC pMalloc;						   
		CoGetMalloc(1, &pMalloc); 
		if(pMalloc) 
		{ 
			pMalloc->Free(pwszShellExt); 
			pMalloc->Release(); 
		} 
	}															    
					     
	// these entries have their %s's replaced with CLSID strings, 
	// their second entries are replaced with the module's path. 
	//register the CLSID entries 
	REGSTRUCT ShExClsidEntries[] = {   
 
		// HKEY_CLASSES_ROOT/CLSID//InProcServer . here, we tell the system where our DLL is located 
		HKEY_CLASSES_ROOT,	TEXT("CLSID\\%s\\InProcServer32"),	NULL,                   NULL, 
 
		// this is the 	HKEY_CLASSES_ROOT/CLSID/ entry. this is where we place info about our shell ext. 
		// our CLSID (generated by GUIDGEN) is how the system refers to our shell extension. 
		HKEY_CLASSES_ROOT,	TEXT("CLSID\\%s"),					NULL,                   NULL, 
 
		// end the array 
		NULL,                NULL,								NULL,                   NULL}; 
 
	for(i = 0; ShExClsidEntries[i].hRootKey; i++) { 
		//Create the sub key string. 
		wsprintf(szSubKey, ShExClsidEntries[i].lpszSubKey, szCLSID); 
 
		lResult = RegDeleteKey(  ShExClsidEntries[i].hRootKey, 
								  szSubKey); 
																			  
		if(NOERROR == lResult) { 
		} else 
			return SELFREG_E_CLASS; 
	} 
 
	// these entries have their %s's replaced with CLSID strings - one per entry, please 
	REGSTRUCT OtherShExEntries[] = {   
			// HKEY_CLASSES_ROOT/*/shellex/ContextMenuHandlers/SHELLEXNAME. tell the system that we want our 
			// shell extension to handle all files: note the "*". ex. we could easily limit it to JPG files by 
			// changing the "*" to ".jpg". 
			// our CLSID is placed in the "%s", and so, explorer will take that CLSID, look in HKEY_CLASSES_ROOT/CLSID 
			// to find a matching CLSID and use the info in there to find our DLL... whew.  
			HKEY_CLASSES_ROOT,	TEXT("*\\shellex\\ContextMenuHandlers\\"SHELLEXNAME), NULL,		NULL, 
 
			// end the array 
			NULL,					NULL,								NULL,                   NULL}; 
 
	for (i = 0; OtherShExEntries[i].hRootKey; i++) { 
		//Create the sub key string. 
		wsprintf(szSubKey, OtherShExEntries[i].lpszSubKey, szCLSID); 
 
		lResult = RegDeleteKey(  OtherShExEntries[i].hRootKey, 
								  szSubKey); 
 
		if(NOERROR == lResult) { 
		} else 
			return SELFREG_E_CLASS; 
	} 
					     
	//If running on NT, register the extension as approved. 
	OSVERSIONINFO  osvi; 
 
	osvi.dwOSVersionInfoSize = sizeof(osvi); 
	GetVersionEx(&osvi); 
 
	// NT needs to have shell extensions "approved". 
	if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)  { 
		lstrcpy( szSubKey, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved\\"SHELLEXNAME)); 
 
 
		lResult = RegDeleteKey( HKEY_LOCAL_MACHINE, 
								 szSubKey); 
	} 
 
	return S_OK; 
 
}