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; }