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