Back to index

lightning-sunbird  0.9+nobinonly
Registry.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corp.
00018  * Portions created by the Initial Developer are Copyright (C) 2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s): Krishna Mohan Khandrika <kkhandrika@netscape.com>
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #undef _UNICODE
00038 #undef UNICODE
00039 
00040 #include <objbase.h>
00041 #include "nsString.h"
00042 #include "Registry.h"
00043 
00044 #define MAPI_PROXY_DLL_NAME   "MapiProxy.dll"
00045 #define MAPI_STARTUP_ARG      " /MAPIStartUp"
00046 #define MAX_SIZE              2048
00047 
00048 // Size of a CLSID as a string
00049 const int CLSID_STRING_SIZE = 39;
00050 
00051 // Proxy/Stub Dll Routines
00052 
00053 typedef HRESULT (__stdcall ProxyServer)();
00054 
00055 
00056 // Convert a CLSID to a char string.
00057 
00058 BOOL CLSIDtochar(const CLSID& clsid, char* szCLSID,
00059                  int length)
00060 {
00061     LPOLESTR wszCLSID = NULL;
00062 
00063     // Get CLSID
00064     HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
00065     if (FAILED(hr))
00066         return FALSE;
00067 
00068     // Covert from wide characters to non-wide.
00069     wcstombs(szCLSID, wszCLSID, length);
00070 
00071     // Free memory.
00072     CoTaskMemFree(wszCLSID);
00073 
00074     return TRUE;
00075 }
00076 
00077 // Create a key and set its value.
00078 
00079 BOOL setKeyAndValue(nsCAutoString keyName, const char* subKey,
00080                     const char* theValue)
00081 {
00082     HKEY hKey;
00083     BOOL retValue = TRUE;
00084 
00085     nsCAutoString theKey(keyName);
00086     if (subKey != NULL)
00087     {
00088         theKey += "\\";
00089         theKey += subKey;
00090     }
00091 
00092     // Create and open key and subkey.
00093     long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, theKey.get(), 
00094                                   0, NULL, REG_OPTION_NON_VOLATILE,
00095                                   KEY_ALL_ACCESS, NULL, &hKey, NULL);
00096     if (lResult != ERROR_SUCCESS)
00097         return FALSE ;
00098 
00099     // Set the Value.
00100     if (theValue != NULL)
00101     {
00102        lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)theValue, 
00103                       strlen(theValue)+1);
00104        if (lResult != ERROR_SUCCESS)
00105            retValue = FALSE;
00106     }
00107 
00108     RegCloseKey(hKey);
00109     return TRUE;
00110 }
00111 
00112 // Delete a key and all of its descendents.
00113 
00114 LONG recursiveDeleteKey(HKEY hKeyParent,           // Parent of key to delete
00115                         const char* lpszKeyChild)  // Key to delete
00116 {
00117     // Open the child.
00118     HKEY hKeyChild ;
00119     LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
00120                              KEY_ALL_ACCESS, &hKeyChild) ;
00121     if (lRes != ERROR_SUCCESS)
00122     {
00123         return lRes ;
00124     }
00125 
00126     // Enumerate all of the decendents of this child.
00127     FILETIME time ;
00128     char szBuffer[MAX_SIZE] ;
00129     DWORD dwSize = MAX_SIZE ;
00130     while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
00131                         NULL, NULL, &time) == S_OK)
00132     {
00133         // Delete the decendents of this child.
00134         lRes = recursiveDeleteKey(hKeyChild, szBuffer) ;
00135         if (lRes != ERROR_SUCCESS)
00136         {
00137             // Cleanup before exiting.
00138             RegCloseKey(hKeyChild) ;
00139             return lRes;
00140         }
00141         dwSize = MAX_SIZE;
00142     }
00143 
00144     // Close the child.
00145     RegCloseKey(hKeyChild) ;
00146 
00147     // Delete this child.
00148     return RegDeleteKey(hKeyParent, lpszKeyChild) ;
00149 }
00150 
00151 void RegisterProxy()
00152 {
00153     HINSTANCE h = NULL;
00154     ProxyServer *RegisterFunc = NULL;
00155 
00156     char szModule[MAX_SIZE];
00157     char *pTemp = NULL;
00158 
00159     HMODULE hModule = GetModuleHandle(NULL);
00160     DWORD dwResult  = ::GetModuleFileName(hModule, szModule,
00161                                           sizeof(szModule)/sizeof(char));
00162     if (dwResult == 0)
00163         return;
00164 
00165     pTemp = strrchr(szModule, '\\');
00166     if (pTemp == NULL)
00167         return;
00168 
00169     *pTemp = '\0';
00170     nsCAutoString proxyPath(szModule);
00171 
00172     proxyPath += "\\";
00173     proxyPath += MAPI_PROXY_DLL_NAME;
00174 
00175     h = LoadLibrary(proxyPath.get());
00176     if (h == NULL)
00177         return;
00178 
00179     RegisterFunc = (ProxyServer *) GetProcAddress(h, "DllRegisterServer");
00180     if (RegisterFunc)
00181         RegisterFunc();
00182 
00183     FreeLibrary(h);
00184 }
00185 
00186 void UnRegisterProxy()
00187 {
00188     HINSTANCE h = NULL;
00189     ProxyServer *UnRegisterFunc = NULL;
00190 
00191     char szModule[MAX_SIZE];
00192     char *pTemp = NULL;
00193 
00194     HMODULE hModule = GetModuleHandle(NULL);
00195     DWORD dwResult  = ::GetModuleFileName(hModule, szModule,
00196                                           sizeof(szModule)/sizeof(char));
00197     if (dwResult == 0)
00198         return;
00199 
00200     pTemp = strrchr(szModule, '\\');
00201     if (pTemp == NULL)
00202         return;
00203 
00204     *pTemp = '\0';
00205     nsCAutoString proxyPath(szModule);
00206 
00207     proxyPath += "\\";
00208     proxyPath += MAPI_PROXY_DLL_NAME;
00209 
00210     h = LoadLibrary(proxyPath.get());
00211     if (h == NULL)
00212         return;
00213 
00214     UnRegisterFunc = (ProxyServer *) GetProcAddress(h, "DllUnregisterServer");
00215     if (UnRegisterFunc)
00216         UnRegisterFunc();
00217 
00218     FreeLibrary(h);
00219 }
00220 
00221 // Register the component in the registry.
00222 
00223 HRESULT RegisterServer(const CLSID& clsid,         // Class ID
00224                        const char* szFriendlyName, // Friendly Name
00225                        const char* szVerIndProgID, // Programmatic
00226                        const char* szProgID)       //   IDs
00227 {
00228     HMODULE hModule = GetModuleHandle(NULL);
00229     char szModuleName[MAX_SIZE];
00230     char szCLSID[CLSID_STRING_SIZE];
00231 
00232     nsCAutoString independentProgId(szVerIndProgID);
00233     nsCAutoString progId(szProgID);
00234 
00235     DWORD dwResult = ::GetModuleFileName(hModule, szModuleName,
00236                               sizeof(szModuleName)/sizeof(char));
00237 
00238     if (dwResult == 0)
00239         return S_FALSE;
00240 
00241     nsCAutoString moduleName(szModuleName);
00242     nsCAutoString registryKey("CLSID\\");
00243 
00244     moduleName += MAPI_STARTUP_ARG;
00245 
00246     // Convert the CLSID into a char.
00247 
00248     if (!CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)))
00249         return S_FALSE;
00250     registryKey += szCLSID;
00251 
00252     // Add the CLSID to the registry.
00253     if (!setKeyAndValue(registryKey, NULL, szFriendlyName))
00254         return S_FALSE;
00255 
00256     if (!setKeyAndValue(registryKey, "LocalServer32", moduleName.get()))
00257         return S_FALSE;
00258 
00259     // Add the ProgID subkey under the CLSID key.
00260     if (!setKeyAndValue(registryKey, "ProgID", szProgID))
00261         return S_FALSE;
00262 
00263     // Add the version-independent ProgID subkey under CLSID key.
00264     if (!setKeyAndValue(registryKey, "VersionIndependentProgID", szVerIndProgID))
00265         return S_FALSE;
00266 
00267     // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
00268     if (!setKeyAndValue(independentProgId, NULL, szFriendlyName))
00269         return S_FALSE; 
00270     if (!setKeyAndValue(independentProgId, "CLSID", szCLSID))
00271         return S_FALSE;
00272     if (!setKeyAndValue(independentProgId, "CurVer", szProgID))
00273         return S_FALSE;
00274 
00275     // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
00276     if (!setKeyAndValue(progId, NULL, szFriendlyName))
00277         return S_FALSE; 
00278     if (!setKeyAndValue(progId, "CLSID", szCLSID))
00279         return S_FALSE;
00280 
00281     RegisterProxy();
00282 
00283     return S_OK;
00284 }
00285 
00286 LONG UnregisterServer(const CLSID& clsid,         // Class ID
00287                       const char* szVerIndProgID, // Programmatic
00288                       const char* szProgID)       //   IDs
00289 {
00290     LONG lResult = S_OK;
00291 
00292     // Convert the CLSID into a char.
00293 
00294     char szCLSID[CLSID_STRING_SIZE];
00295     if (!CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)))
00296         return S_FALSE;
00297 
00298     UnRegisterProxy();
00299 
00300     nsCAutoString registryKey("CLSID\\");
00301     registryKey += szCLSID;
00302 
00303     lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, registryKey.get());
00304     if (lResult == ERROR_SUCCESS || lResult == ERROR_FILE_NOT_FOUND)
00305         return lResult;
00306 
00307     registryKey += "\\LocalServer32";
00308 
00309     // Delete only the path for this server.
00310 
00311     lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, registryKey.get());
00312     if (lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND)
00313         return lResult;
00314 
00315     // Delete the version-independent ProgID Key.
00316     lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID);
00317     if (lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND)
00318         return lResult;
00319 
00320     lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID);
00321 
00322     return lResult;
00323 }