Back to index

lightning-sunbird  0.9+nobinonly
nsMapiRegistryUtils.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.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Srilatha Moturi <srilatha@netscape.com>
00023  *   Jungshik Shin <jshin@mailaps.org>
00024  *   Scott MacGregor <mscott@mozilla.org>
00025  *   David Bienvenu < bienvenu@mozilla.org>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 /***************************************************************************
00042 *
00043 * This File is no longer used by Thunderbird. Seamonkey is the only consumer.
00044 * See mozilla/mail/components/shell for the Thunderbird registry code
00045 *
00046 *****************************************************************************/
00047 
00048 #undef UNICODE
00049 #undef _UNICODE
00050 
00051 #include "nsIServiceManager.h"
00052 #include "msgMapiImp.h"
00053 #include "msgMapiMain.h"
00054 #include "nsMapiRegistryUtils.h"
00055 #include "nsString.h"
00056 #include "nsIStringBundle.h"
00057 #include "nsIPromptService.h"
00058 #include "nsXPIDLString.h"
00059 #include "nsSpecialSystemDirectory.h"
00060 #include "nsDirectoryService.h"
00061 #include "nsDirectoryServiceDefs.h"
00062 #include "nsAppDirectoryServiceDefs.h"
00063 #include "nsNativeCharsetUtils.h"
00064 #include "nsEmbedCID.h"
00065 #include "nsIMapiSupport.h"
00066 #include <mbstring.h>
00067 
00068 #define EXE_EXTENSION ".EXE" 
00069 #define MOZ_HWND_BROADCAST_MSG_TIMEOUT 5000
00070 #define MOZ_CLIENT_MAIL_KEY "Software\\Clients\\Mail"
00071 #define MOZ_CLIENT_NEWS_KEY "Software\\Clients\\News"
00072 
00073 nsMapiRegistryUtils::nsMapiRegistryUtils()
00074 {
00075    m_mapiStringBundle = nsnull ;
00076 
00077    mRestrictedRegAccess = verifyRestrictedAccess();
00078 }
00079     
00080 const char * nsMapiRegistryUtils::thisApplication()
00081 {
00082     if (m_thisApp.IsEmpty()) {
00083         char buffer[MAX_PATH] = {0};
00084         DWORD len = ::GetModuleFileName(NULL, buffer, MAX_PATH);
00085         if (!len) return nsnull ; 
00086         len = ::GetShortPathName(buffer, buffer, MAX_PATH);
00087         if (!len) return nsnull ; 
00088         m_thisApp = buffer;
00089         ToUpperCase(m_thisApp);
00090     }
00091 
00092     return m_thisApp.get() ;
00093 }
00094 
00095 void nsMapiRegistryUtils::getVarValue(const PRUnichar * varName, nsAutoString & result)
00096 {
00097     nsresult rv;
00098     nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(
00099                                          NS_STRINGBUNDLE_CONTRACTID, &rv));
00100     if (NS_SUCCEEDED(rv) && bundleService) {
00101         nsCOMPtr<nsIStringBundle> brandBundle;
00102         rv = bundleService->CreateBundle(
00103                     "chrome://branding/locale/brand.properties",
00104                     getter_AddRefs(brandBundle));
00105         if (NS_SUCCEEDED(rv)) {
00106             nsXPIDLString value;
00107             rv = brandBundle->GetStringFromName(
00108                        varName,
00109                        getter_Copies(value));
00110             if (NS_SUCCEEDED(rv))
00111                 result = value;
00112         }
00113     }
00114 }
00115 
00116 const PRUnichar * nsMapiRegistryUtils::brandName() 
00117 {
00118     if (m_brand.IsEmpty())
00119         getVarValue(NS_LITERAL_STRING("brandFullName").get(), m_brand);
00120     return m_brand.get();
00121 }
00122 
00123 const nsString& nsMapiRegistryUtils::vendorName() 
00124 {
00125     if (m_vendor.IsEmpty())
00126         getVarValue(NS_LITERAL_STRING("vendorShortName").get(), m_vendor);
00127     return m_vendor;
00128 }
00129 
00130 
00131 PRBool nsMapiRegistryUtils::verifyRestrictedAccess() {
00132     char   subKey[] = "Software\\Mozilla - Test Key";
00133     PRBool result = PR_FALSE;
00134     DWORD  dwDisp = 0;
00135     HKEY   key;
00136     // Try to create/open a subkey under HKLM.
00137     DWORD rc = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE,
00138                                 subKey,
00139                                 0,
00140                                 NULL,
00141                                 REG_OPTION_NON_VOLATILE,
00142                                 KEY_WRITE,
00143                                 NULL,
00144                                 &key,
00145                                 &dwDisp);
00146 
00147     if (rc == ERROR_SUCCESS) {
00148         // Key was opened; first close it.
00149         ::RegCloseKey(key);
00150         // Delete it if we just created it.
00151         switch(dwDisp) {
00152             case REG_CREATED_NEW_KEY:
00153                 ::RegDeleteKey(HKEY_LOCAL_MACHINE, subKey);
00154                 break;
00155             case REG_OPENED_EXISTING_KEY:
00156                 break;
00157         }
00158     } else {
00159         // Can't create/open it; we don't have access.
00160         result = PR_TRUE;
00161     }
00162     return result;
00163 }
00164 
00165 nsresult nsMapiRegistryUtils::SetRegistryKey(HKEY baseKey, const char * keyName, 
00166                         const char * valueName, char * value)
00167 {
00168     nsresult result = NS_ERROR_FAILURE;
00169     HKEY   key;
00170     LONG   rc = ::RegCreateKey(baseKey, keyName, &key);
00171   
00172     if (rc == ERROR_SUCCESS) {
00173         rc = ::RegSetValueEx(key, valueName, NULL, REG_SZ, 
00174                                  (LPBYTE)(const char*)value, strlen(value));
00175         if (rc == ERROR_SUCCESS) {
00176             result = NS_OK;
00177         }
00178         ::RegCloseKey(key);
00179     }
00180     return result;
00181 }
00182 
00183 nsresult nsMapiRegistryUtils::DeleteRegistryValue(HKEY baseKey, const char * keyName, 
00184                         const char * valueName)
00185 {
00186     nsresult result = NS_ERROR_FAILURE;
00187     HKEY   key;
00188     LONG   rc = ::RegOpenKey(baseKey, keyName, &key);
00189   
00190     if (rc == ERROR_SUCCESS) {
00191         rc = ::RegDeleteValue(key, valueName);
00192         if (rc == ERROR_SUCCESS)
00193             result = NS_OK;
00194         ::RegCloseKey(key);
00195     }
00196     return result;
00197 }
00198 
00199 void nsMapiRegistryUtils::GetRegistryKey(HKEY baseKey, const char * keyName, 
00200                          const char * valueName, nsCAutoString & value)
00201 {
00202     HKEY   key;
00203     LONG   rc = ::RegOpenKey(baseKey, keyName, &key);
00204     if (rc == ERROR_SUCCESS) {
00205         char buffer[MAX_PATH] = {0};
00206         DWORD len = sizeof buffer;
00207         rc = ::RegQueryValueEx(key, valueName, NULL, NULL, 
00208                                (LPBYTE)buffer, &len);
00209         if (rc == ERROR_SUCCESS) {
00210             if (len)
00211                 value = buffer;
00212         }
00213         ::RegCloseKey(key);
00214      }
00215 }
00216 
00217 nsresult nsMapiRegistryUtils::recursiveDeleteKey(HKEY hKeyParent, const char* lpszKeyChild)
00218 {
00219     // Open the child.
00220     HKEY hKeyChild ;
00221     nsresult rv = NS_OK;
00222 
00223     LONG lRes = ::RegOpenKeyEx(hKeyParent, lpszKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild);
00224     if (lRes != ERROR_SUCCESS)
00225         return NS_ERROR_FAILURE;
00226 
00227     // Enumerate all of the decendents of this child.
00228     FILETIME time;
00229     char szBuffer[MAX_PATH+1];
00230     DWORD dwSize = MAX_PATH+1;
00231     while (::RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time) == S_OK)
00232     {
00233         // Delete the decendents of this child.
00234         rv = recursiveDeleteKey(hKeyChild, szBuffer);
00235         if (NS_FAILED(rv))
00236         {
00237             // Cleanup before exiting.
00238             ::RegCloseKey(hKeyChild);
00239             return rv;
00240         }
00241         
00242         dwSize = MAX_PATH+1;
00243     }
00244 
00245     // Close the child.
00246     ::RegCloseKey(hKeyChild);
00247 
00248     // Delete this child.
00249     ::RegDeleteKey(hKeyParent, lpszKeyChild);
00250     return rv;
00251 }
00252 
00253 /* static */
00254 void nsMapiRegistryUtils::RegCopyKey(HKEY aSrcKey, HKEY aDestKey, const char* aSubKeyName)
00255 {
00256   HKEY srcSubKey, destSubKey;
00257   char valueName[MAX_PATH + 1], keyName[MAX_PATH + 1];
00258   BYTE valueData[MAX_PATH + 1];
00259   DWORD nameSize, dataSize, keySize, valueType;
00260 
00261   // open source key
00262   if (::RegOpenKeyEx(aSrcKey, aSubKeyName, NULL, KEY_ALL_ACCESS, &srcSubKey) != ERROR_SUCCESS)
00263     return;
00264 
00265   // create target key
00266   if (::RegCreateKeyEx(aDestKey, aSubKeyName, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &destSubKey, NULL) == ERROR_SUCCESS) {
00267     for (DWORD valueIndex = 0;
00268          nameSize = MAX_PATH + 1,
00269          dataSize = MAX_PATH + 1,
00270          ::RegEnumValue(srcSubKey, valueIndex, valueName, &nameSize, NULL, &valueType, valueData, &dataSize) == ERROR_SUCCESS;
00271          valueIndex++)
00272       ::RegSetValueEx(destSubKey, valueName, NULL, valueType, valueData, dataSize);
00273 
00274     for (DWORD keyIndex = 0;
00275          keySize = MAX_PATH + 1,
00276          ::RegEnumKeyEx(srcSubKey, keyIndex, keyName, &keySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
00277          keyIndex++)
00278       RegCopyKey(srcSubKey, destSubKey, keyName);
00279 
00280     ::RegCloseKey(destSubKey);
00281   }
00282   ::RegCloseKey(srcSubKey);
00283 }
00284 
00285 PRBool nsMapiRegistryUtils::IsDefaultMailClient()
00286 {
00287     if (!isSmartDll() && !isMozDll()) 
00288         return PR_FALSE;
00289 
00290     //first try to get the users default mail client
00291     nsCAutoString name; 
00292     // old mail clients like netscape 4.x never channge the current user key, so it is possible for them to become
00293     // the default mail client and we don't notice because we see that thunderbird still owns the HKCU key...
00294     // doh!
00295     // GetRegistryKey(HKEY_CURRENT_USER, "Software\\Clients\\Mail", "", name);
00296 
00297     //if that fails then get the machine's default client
00298     GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\Mail", "", name);
00299 
00300     if (!name.IsEmpty()) {
00301          nsCAutoString keyName("Software\\Clients\\Mail\\");
00302          keyName += name.get(); 
00303          keyName += "\\Protocols\\mailto\\shell\\open\\command";
00304 
00305          nsCAutoString result;
00306          GetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", result);
00307          if (!result.IsEmpty()) {
00308              nsCAutoString strExtension;
00309              strExtension.Assign(EXE_EXTENSION);
00310              ToUpperCase(result);
00311              PRInt32 index = result.RFind(strExtension.get());
00312              if (index != kNotFound) {
00313                  result.Truncate(index + strExtension.Length());
00314              }
00315              
00316              nsCAutoString thisApp (thisApplication());             
00317              // if result == thisApp, that by itself isn't a strong enough indication that everything
00318              // is ok...also check HKLM\Software\Classes\mailto\shell\open\command
00319              if (result == thisApp)
00320              {
00321                keyName = "Software\\Classes\\mailto\\shell\\open\\command";
00322                nsCAutoString result;
00323                GetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", result);
00324                if (!result.IsEmpty()) {
00325                   nsCAutoString strExtension;
00326                   strExtension.Assign(EXE_EXTENSION);
00327                   ToUpperCase(result);
00328                   PRInt32 index = result.RFind(strExtension.get());
00329                   if (index != kNotFound)
00330                     result.Truncate(index + strExtension.Length());    
00331                   return (result == thisApp);
00332                }
00333              }
00334         }
00335     }
00336     return PR_FALSE;
00337 
00338 }
00339 
00340 PRBool nsMapiRegistryUtils::IsDefaultNewsClient()
00341 {
00342     //first try to get the users default news client
00343     nsCAutoString name; 
00344     GetRegistryKey(HKEY_CURRENT_USER, "Software\\Clients\\News", "", name);
00345 
00346      //if that fails then get the machine's default client
00347     if(name.IsEmpty()) {
00348         GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\News", "", name);  
00349     }     
00350 
00351     if (!name.IsEmpty()) {
00352          nsCAutoString keyName("Software\\Clients\\News\\");
00353          keyName += name.get(); 
00354 
00355          // let's only check news and instead of news, nntp and snews.
00356          keyName += "\\Protocols\\news\\shell\\open\\command";
00357          nsCAutoString result;
00358          GetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", result);
00359          if (!result.IsEmpty()) {
00360              nsCAutoString strExtension;
00361              strExtension.Assign(EXE_EXTENSION);
00362              ToUpperCase(result);
00363              PRInt32 index = result.RFind(strExtension.get());
00364              if (index != kNotFound) {
00365                  result.Truncate(index + strExtension.Length());
00366              }
00367              nsCAutoString thisApp (thisApplication()) ;
00368              return (result == thisApp);
00369         }
00370     }
00371 
00372     return PR_FALSE;
00373 }
00374 
00375 nsresult nsMapiRegistryUtils::saveDefaultNewsClient()
00376 {
00377     nsCAutoString name ;
00378     GetRegistryKey(HKEY_LOCAL_MACHINE,"Software\\Clients\\News", "", name);
00379     return SetRegistryKey(HKEY_LOCAL_MACHINE, 
00380                             kAppDesktopKey, 
00381                             "HKEY_LOCAL_MACHINE\\Software\\Clients\\News", 
00382                             name.IsEmpty() ? "" : (char *)name.get());
00383 }
00384 
00385 nsresult nsMapiRegistryUtils::saveDefaultMailClient()
00386 {
00387     nsCAutoString name ;
00388     GetRegistryKey(HKEY_LOCAL_MACHINE,"Software\\Clients\\Mail", "", name);
00389     return SetRegistryKey(HKEY_LOCAL_MACHINE, 
00390                             kAppDesktopKey, 
00391                             "HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail", 
00392                             name.IsEmpty() ? "" : (char *)name.get());
00393 } 
00394 
00395 nsresult nsMapiRegistryUtils::saveUserDefaultNewsClient()
00396 {
00397     nsCAutoString name ;
00398     GetRegistryKey(HKEY_CURRENT_USER,"Software\\Clients\\News", "", name);
00399     return SetRegistryKey(HKEY_LOCAL_MACHINE, 
00400                             kAppDesktopKey, 
00401                             "HKEY_CURRENT_USER\\Software\\Clients\\News", 
00402                             name.IsEmpty() ? "" : (char *)name.get());
00403 }
00404 
00405 nsresult nsMapiRegistryUtils::saveUserDefaultMailClient()
00406 {
00407     nsCAutoString name ;
00408     GetRegistryKey(HKEY_CURRENT_USER,"Software\\Clients\\Mail", "", name);
00409     return SetRegistryKey(HKEY_LOCAL_MACHINE, 
00410                             kAppDesktopKey, 
00411                             "HKEY_CURRENT_USER\\Software\\Clients\\Mail", 
00412                             name.IsEmpty() ? "" : (char *)name.get());
00413 }
00414 
00422 typedef HRESULT (FAR PASCAL GetOutlookVersionFunc)(); 
00423 PRBool nsMapiRegistryUtils::isSmartDll() 
00424 { 
00425     char buffer[MAX_PATH] = {0};
00426     if (GetSystemDirectory(buffer, sizeof(buffer)) == 0) 
00427         return PR_FALSE;
00428     PL_strcatn(buffer, sizeof(buffer), "\\Mapi32.dll");
00429     
00430     HINSTANCE hInst; 
00431     GetOutlookVersionFunc *doesExist = nsnull;
00432     hInst = LoadLibrary(buffer); 
00433     if (hInst == nsnull) 
00434         return PR_FALSE;
00435         
00436     doesExist = (GetOutlookVersionFunc *) GetProcAddress (hInst, "GetOutlookVersion"); 
00437     FreeLibrary(hInst); 
00438 
00439     return (doesExist != nsnull); 
00440 } 
00441 
00442 typedef HRESULT (FAR PASCAL GetMapiDllVersion)(); 
00447 PRBool nsMapiRegistryUtils::isMozDll() 
00448 { 
00449     char buffer[MAX_PATH] = {0};
00450     if (GetSystemDirectory(buffer, sizeof(buffer)) == 0) 
00451         return PR_FALSE;
00452     PL_strcatn(buffer, sizeof(buffer), "\\Mapi32.dll"); 
00453 
00454     HINSTANCE hInst; 
00455     GetMapiDllVersion *doesExist = nsnull;
00456     hInst = LoadLibrary(buffer); 
00457     if (hInst == nsnull) 
00458         return PR_FALSE;
00459         
00460     doesExist = (GetMapiDllVersion *) GetProcAddress (hInst, "GetMapiDllVersion"); 
00461     FreeLibrary(hInst); 
00462 
00463     return (doesExist != nsnull); 
00464 } 
00465 
00469 nsresult nsMapiRegistryUtils::CopyMozMapiToWinSysDir()
00470 {
00471     nsresult rv;
00472     char buffer[MAX_PATH] = {0};
00473     if (GetSystemDirectory(buffer, sizeof(buffer)) == 0) 
00474         return NS_ERROR_FAILURE;
00475 
00476     nsCAutoString filePath(buffer);
00477     filePath.AppendLiteral("\\Mapi32_moz_bak.dll");
00478 
00479     nsCOMPtr<nsILocalFile> pCurrentMapiFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv);
00480     if (NS_FAILED(rv) || !pCurrentMapiFile) return rv;        
00481     pCurrentMapiFile->InitWithNativePath(filePath);
00482 
00483     nsCOMPtr<nsIFile> pMozMapiFile;
00484     nsCOMPtr<nsIProperties> directoryService =
00485           do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
00486     if (!directoryService) return NS_ERROR_FAILURE;
00487     rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR,
00488                               NS_GET_IID(nsIFile),
00489                               getter_AddRefs(pMozMapiFile));
00490 
00491     if (NS_FAILED(rv)) return rv;
00492     pMozMapiFile->AppendNative(NS_LITERAL_CSTRING("mozMapi32.dll"));
00493 
00494     PRBool bExist;
00495     rv = pMozMapiFile->Exists(&bExist);
00496     if (NS_FAILED(rv) || !bExist) return rv;
00497 
00498     rv = pCurrentMapiFile->Exists(&bExist);
00499     if (NS_SUCCEEDED(rv) && bExist)
00500     {
00501         rv = pCurrentMapiFile->Remove(PR_FALSE);
00502     }
00503     if (NS_FAILED(rv)) return rv;
00504     filePath.Assign(buffer);
00505     filePath.AppendLiteral("\\Mapi32.dll");
00506     pCurrentMapiFile->InitWithNativePath(filePath);
00507     rv = pCurrentMapiFile->Exists(&bExist);
00508     if (NS_SUCCEEDED(rv) && bExist)
00509     {
00510         rv = pCurrentMapiFile->MoveToNative(nsnull, NS_LITERAL_CSTRING("Mapi32_moz_bak.dll"));
00511         if (NS_FAILED(rv)) return rv;
00512         nsCAutoString fullFilePath(buffer);
00513         fullFilePath.AppendLiteral("\\Mapi32_moz_bak.dll");
00514         rv = SetRegistryKey(HKEY_LOCAL_MACHINE, 
00515                             kAppDesktopKey, 
00516                             "Mapi_backup_dll", 
00517                             (char *)fullFilePath.get());
00518         if (NS_FAILED(rv)) {
00519              RestoreBackedUpMapiDll();
00520              return rv;
00521         }
00522     }
00523     
00524     NS_NAMED_LITERAL_CSTRING(fileName, "Mapi32.dll");
00525     filePath.Assign(buffer);
00526     pCurrentMapiFile->InitWithNativePath(filePath);
00527     rv = pMozMapiFile->CopyToNative(pCurrentMapiFile, fileName);
00528     if (NS_FAILED(rv))
00529         RestoreBackedUpMapiDll();
00530     return rv;
00531 }
00532 
00536 nsresult nsMapiRegistryUtils::RestoreBackedUpMapiDll()
00537 {
00538     nsresult rv;
00539     char buffer[MAX_PATH] = {0};
00540     if (GetSystemDirectory(buffer, sizeof(buffer)) == 0) 
00541         return NS_ERROR_FAILURE;
00542 
00543     nsCAutoString filePath(buffer);
00544     nsCAutoString previousFileName(buffer);
00545     filePath.AppendLiteral("\\Mapi32.dll");
00546     previousFileName.AppendLiteral("\\Mapi32_moz_bak.dll");
00547 
00548     nsCOMPtr <nsILocalFile> pCurrentMapiFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
00549     if (NS_FAILED(rv) || !pCurrentMapiFile) return NS_ERROR_FAILURE;        
00550     pCurrentMapiFile->InitWithNativePath(filePath);
00551     
00552     nsCOMPtr<nsILocalFile> pPreviousMapiFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv);
00553     if (NS_FAILED(rv) || !pPreviousMapiFile) return NS_ERROR_FAILURE;       
00554     pPreviousMapiFile->InitWithNativePath(previousFileName);
00555 
00556     PRBool bExist;
00557     rv = pCurrentMapiFile->Exists(&bExist);
00558     if (NS_SUCCEEDED(rv) && bExist) {
00559         rv = pCurrentMapiFile->Remove(PR_FALSE);
00560         if (NS_FAILED(rv)) return rv;
00561     }
00562 
00563     rv = pPreviousMapiFile->Exists(&bExist);
00564     if (NS_SUCCEEDED(rv) && bExist)
00565         rv = pPreviousMapiFile->MoveToNative(nsnull, NS_LITERAL_CSTRING("Mapi32.dll"));
00566     if (NS_SUCCEEDED(rv))
00567         DeleteRegistryValue(HKEY_LOCAL_MACHINE,
00568                             kAppDesktopKey, 
00569                             "Mapi_backup_dll");
00570     return rv;
00571 }
00572 
00573 // aDefaultAppRegKey points to something like Software\Clients\News\Mozilla\Protocols
00574 // we will copy the keys into Software\Clases
00575 nsresult nsMapiRegistryUtils::setProtocolHandler(const char * aDefaultAppRegKey, const char * protocolName)
00576 {
00577     HKEY srcKey;
00578     HKEY trgKey;
00579 
00580     ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, aDefaultAppRegKey, 0, KEY_READ, &srcKey);
00581     ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Classes", 0, KEY_READ, &trgKey);
00582 
00583     RegCopyKey(srcKey, trgKey, protocolName);
00584 
00585     RegCloseKey(srcKey);
00586     RegCloseKey(trgKey);
00587     return NS_OK;
00588 }
00589 
00590 nsresult nsMapiRegistryUtils::setupFileExtension(const char * aDefaultAppRegKey, const char * aExtension)
00591 {
00592 
00593   // aDefaultAppRegKey is "Software\\Classes\\"
00594     nsCAutoString keyName;
00595     keyName = aDefaultAppRegKey;
00596     keyName.Append(aExtension);
00597    
00598 
00599     nsCAutoString appName;
00600     appName.AssignWithConversion(brandName());
00601 
00602     // save the current file extension settings to HKEY_LOCAL_MACHINE\Software\Clients\Thunderbird<extension>
00603 
00604     nsCAutoString saveKeyName("Software\\Clients\\Mail\\");
00605     saveKeyName.Append(appName);
00606     saveKeyName.AppendLiteral("\\");
00607 
00608     HKEY srcKey;
00609     HKEY trgKey;
00610     ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, aDefaultAppRegKey, 0, KEY_READ, &srcKey);
00611     ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,saveKeyName.get(), 0, KEY_READ, &trgKey);
00612 
00613     RegCopyKey(srcKey, trgKey, aExtension);
00614 
00615     nsresult rv = SetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", "");
00616 
00617 
00618     if (NS_SUCCEEDED(rv)) 
00619     {
00620       // Classes<extension>\shell\open\command value
00621       nsCAutoString appPath (thisApplication());
00622 
00623       appPath += " ";
00624       
00625       appPath += "\"%1\"";
00626       nsCAutoString shellOpenKey (keyName);
00627       shellOpenKey.AppendLiteral("\\shell\\open\\command");
00628 
00629       rv = SetRegistryKey(HKEY_LOCAL_MACHINE, shellOpenKey.get(), "", (char *)appPath.get());
00630 
00631       // Classes<extension>\DefaultIcon value
00632       nsCAutoString iconPath(thisApplication());
00633       iconPath += ",0";
00634       nsCAutoString iconKey (keyName);
00635       iconKey.AppendLiteral("\\DefaultIcon");
00636       rv = SetRegistryKey(HKEY_LOCAL_MACHINE, iconKey.get(), "", (char *)iconPath.get());
00637     }
00638 
00639     return rv;
00640 }
00641 
00642 nsresult nsMapiRegistryUtils::restoreFileExtension(const char * aDefaultAppRegKey, const char * aExtension)
00643 {
00644 
00645   // aDefaultAppRegKey is "Software\\Classes\\"
00646   nsCAutoString keyName;
00647   keyName = aDefaultAppRegKey;
00648   keyName.Append(aExtension);
00649  
00650 
00651   nsCAutoString appName;
00652   appName.AssignWithConversion(brandName());
00653 
00654   // restore the file extension settings from HKEY_LOCAL_MACHINE\Software\Clients\Mail\Mail & News<extension>
00655 
00656   nsCAutoString saveKeyName("Software\\Clients\\Mail\\");
00657   saveKeyName.Append(appName);
00658   saveKeyName.AppendLiteral("\\");
00659 
00660   recursiveDeleteKey(HKEY_LOCAL_MACHINE, keyName.get()); 
00661   nsresult rv = SetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", "");
00662 
00663   HKEY srcKey;
00664   HKEY trgKey;
00665   ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, saveKeyName.get(), 0, KEY_READ, &srcKey);
00666   ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, aDefaultAppRegKey, 0, KEY_READ, &trgKey);
00667 
00668   RegCopyKey(srcKey, trgKey, aExtension);
00669 
00670   return rv;
00671 }
00672 
00673 
00674 nsresult nsMapiRegistryUtils::setupDefaultProtocolKey(const char * aDefaultAppRegKey, const char * aProtocol, const char * aProtocolEntryValue, const char * aCmdLineText)
00675 {
00676     nsCAutoString keyName;
00677     keyName = aDefaultAppRegKey;
00678     keyName.Append(aProtocol);
00679 
00680     nsCAutoString temp; 
00681     temp = aProtocolEntryValue;  // XXX this is bogus. SetRegistryKey should not require a char *..it should take a const char *
00682    
00683     // Protocols<proto scheme> default value (i.e. URL:News Protocol)
00684     nsresult rv = SetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", (char *) temp.get());
00685     
00686     SetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "URL Protocol", "");
00687 
00688 
00689     if (NS_SUCCEEDED(rv)) 
00690     {
00691       // Protocols<protocol scheme>\shell\open\command value
00692       nsCAutoString appPath (thisApplication());
00693 
00694       appPath += " -osint ";
00695       appPath += aCmdLineText;
00696       appPath += " \"%1\"";
00697       nsCAutoString shellOpenKey (keyName);
00698       shellOpenKey.AppendLiteral("\\shell\\open\\command");
00699 
00700       rv = SetRegistryKey(HKEY_LOCAL_MACHINE, shellOpenKey.get(), "", (char *)appPath.get());
00701 
00702       // Protocols<protocol scheme>\DefaultIcon value
00703       nsCAutoString iconPath(thisApplication());
00704       iconPath += ",0";
00705       nsCAutoString iconKey (keyName);
00706       iconKey.AppendLiteral("\\DefaultIcon");
00707       rv = SetRegistryKey(HKEY_LOCAL_MACHINE, iconKey.get(),"", (char *)iconPath.get());
00708     }
00709 
00710     return rv;
00711 }
00712 
00713 nsresult nsMapiRegistryUtils::registerMailApp(PRBool aForceRegistration)
00714 {
00715     nsCAutoString keyName("Software\\Clients\\Mail\\");
00716     nsCAutoString appName;
00717     NS_CopyUnicodeToNative(vendorName(), appName);
00718     nsresult rv = NS_OK;
00719 
00720     if (mRestrictedRegAccess) 
00721       return NS_ERROR_FAILURE;
00722 
00723     // Be SMART! If we have already set these keys up, don't do it again. Check the registeredAsNewsApp flag
00724     // that we stored in our desktop registry scratchpad
00725     nsCAutoString registeredAsMailApp;
00726     GetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, "registeredAsMailApp", registeredAsMailApp);
00727     
00728     if (!aForceRegistration && registeredAsMailApp.Equals("1")) 
00729         return NS_OK;
00730     
00731     // (1) Add our app to the list of keys under Software\\Clients\\Mail so we show up as a possible News application
00732     if (!appName.IsEmpty()) {
00733         keyName.Append(appName.get());
00734 
00735         nsCOMPtr<nsIStringBundle> bundle;
00736         rv = MakeMapiStringBundle (getter_AddRefs (bundle)) ;
00737         if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
00738 
00739         nsXPIDLString defaultMailTitle;
00740         // Use vendorName instead of brandname since brandName is product name
00741         // and has more than just the name of the application
00742         const PRUnichar *keyValuePrefixStr[] = { vendorName().get() };
00743         NS_NAMED_LITERAL_STRING(defaultMailTitleTag, "defaultMailDisplayTitle");
00744         rv = bundle->FormatStringFromName(defaultMailTitleTag.get(), keyValuePrefixStr, 1, getter_Copies(defaultMailTitle));
00745         if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
00746 
00747         nsCAutoString nativeTitle;
00748         NS_CopyUnicodeToNative(defaultMailTitle, nativeTitle);
00749         rv = SetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", NS_CONST_CAST(char *, nativeTitle.get()) ); 
00750     }
00751     else
00752         rv = NS_ERROR_FAILURE;
00753 
00754     if (NS_SUCCEEDED(rv)) {
00755         nsCAutoString thisApp (thisApplication()) ;
00756         nsCAutoString dllPath (thisApp) ;
00757         char* pathSep = (char *) _mbsrchr((const unsigned char *) thisApp.get(), '\\');
00758         if (pathSep) 
00759             dllPath.Truncate(pathSep - thisApp.get() + 1);
00760         dllPath += "mozMapi32.dll";
00761         
00762         // (2) set the DllPath attribute on our new entry for MAPI
00763         SetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "DLLPath", (char *)dllPath.get());
00764         
00765         // (3) now that we have added Software\\Clients\\Mail\<app name> add subkeys for each protocol mail supports
00766         setupDefaultProtocolKey(nsCString(keyName + NS_LITERAL_CSTRING("\\Protocols\\")).get(), "mailto", "URL:MailTo Protocol", "-compose");
00767 
00768 
00769         setupFileExtension("Software\\Classes\\", ".eml");
00770 
00771         // (4) Software\Clients\News<app name>\shell\open\command value 
00772         nsCAutoString appKeyName;
00773         appKeyName.Assign(keyName);
00774         appKeyName.AppendLiteral("\\shell\\open\\command");
00775         nsCAutoString mailAppPath(thisApp);
00776         mailAppPath += " -mail";
00777         SetRegistryKey(HKEY_LOCAL_MACHINE, appKeyName.get(), "", (char *)mailAppPath.get());
00778 
00779         // (5) Add a properties key that launches our options chrome
00780 #ifdef MOZ_THUNDERBIRD
00781         appKeyName.Assign(keyName);
00782         appKeyName.AppendLiteral("\\shell\\properties\\command");
00783         nsCAutoString optionsPath(thisApp);
00784         optionsPath += " -options";
00785         SetRegistryKey(HKEY_LOCAL_MACHINE, appKeyName.get(), "", (char *)optionsPath.get());
00786 
00787         nsCOMPtr<nsIStringBundle> bundle;
00788         rv = MakeMapiStringBundle (getter_AddRefs (bundle));
00789         if (bundle)
00790         {
00791           appKeyName.Assign(keyName);
00792           appKeyName.AppendLiteral("\\shell\\properties");
00793 
00794           nsAutoString brandShortName;
00795           getVarValue(NS_LITERAL_STRING("brandShortName").get(), brandShortName);
00796 
00797           const PRUnichar* brandNameStrings[] = { brandShortName.get() };
00798 
00799           nsXPIDLString optionsTitle;
00800           bundle->FormatStringFromName(NS_LITERAL_STRING("optionsLabel").get(),
00801                                        brandNameStrings, 1, getter_Copies(optionsTitle));
00802           nsCAutoString nativeOptionsTitle;
00803           NS_CopyUnicodeToNative(optionsTitle, nativeOptionsTitle);
00804           SetRegistryKey(HKEY_LOCAL_MACHINE, appKeyName.get(), "", (char *) nativeOptionsTitle.get());
00805         }
00806 #endif
00807                         
00808         // (5) add a default icon entry to Software\\Clients\\Mail\<app name>
00809         nsCAutoString iconPath(thisApp);
00810         iconPath += ",0";
00811         nsCAutoString iconKeyName (keyName);
00812         iconKeyName.AppendLiteral("\\DefaultIcon");
00813         SetRegistryKey(HKEY_LOCAL_MACHINE, iconKeyName.get(),"", (char *)iconPath.get());
00814 
00815         // if we got this far, set a flag in the registry so we know we have registered ourself as a default mail application
00816         SetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, "registeredAsMailApp", "1");
00817     }
00818 
00819     return rv;
00820 }
00821 
00822 nsresult nsMapiRegistryUtils::registerNewsApp(PRBool aForceRegistration)
00823 {
00824     nsresult rv = NS_OK;
00825     nsCAutoString keyName("Software\\Clients\\News\\");
00826     nsCAutoString appName;
00827     NS_CopyUnicodeToNative(vendorName(), appName);
00828 
00829     // Be SMART! If we have already set these keys up, don't do it again. Check the registeredAsNewsApp flag
00830     // that we stored in our desktop registry scratchpad
00831     nsCAutoString registeredAsNewsApp;
00832     GetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, "registeredAsNewsApp", registeredAsNewsApp);
00833 
00834     if (!aForceRegistration && registeredAsNewsApp.Equals("1")) 
00835         return NS_OK;
00836 
00837     // (1) Add our app to the list of keys under Software\\Clients\\News so we show up as a possible News application  
00838     if (!appName.IsEmpty()) {
00839         keyName.Append(appName.get());
00840 
00841         nsCOMPtr<nsIStringBundle> bundle;
00842         rv = MakeMapiStringBundle (getter_AddRefs (bundle)) ;
00843         if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
00844 
00845         nsXPIDLString defaultMailTitle;
00846         // Use vendorName instead of brandname since brandName is product name
00847         // and has more than just the name of the application
00848         const PRUnichar *keyValuePrefixStr[] = { vendorName().get() };
00849         NS_NAMED_LITERAL_STRING(defaultMailTitleTag, "defaultMailDisplayTitle");
00850         rv = bundle->FormatStringFromName(defaultMailTitleTag.get(),
00851                                       keyValuePrefixStr, 1,
00852                                       getter_Copies(defaultMailTitle));
00853         if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
00854         nsCAutoString nativeTitle;
00855         NS_CopyUnicodeToNative(defaultMailTitle, nativeTitle);
00856 
00857         rv = SetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", NS_CONST_CAST(char *, nativeTitle.get()) );  
00858     }
00859     else
00860         rv = NS_ERROR_FAILURE;
00861 
00862     if (NS_SUCCEEDED(rv)) {
00863         nsCAutoString thisApp (thisApplication());
00864         if (NS_SUCCEEDED(rv)) {
00865 
00866             // (3) now that we have added Software\\Clients\\News\<app name>
00867             //     add subkeys for each protocol news supports
00868             nsCString protocolKeyName(keyName + NS_LITERAL_CSTRING("\\Protocols\\"));
00869             setupDefaultProtocolKey(protocolKeyName.get(), "news", "URL:News Protocol", "-mail");
00870             setupDefaultProtocolKey(protocolKeyName.get(), "nntp", "URL:NNTP Protocol", "-mail");
00871             setupDefaultProtocolKey(protocolKeyName.get(), "snews", "URL:Snews Protocol", "-mail");
00872 
00873             // (4) Software\Clients\News<app name>\shell\open\command value 
00874             nsCAutoString appKeyName;
00875             appKeyName.Assign(keyName);
00876             appKeyName.AppendLiteral("\\shell\\open\\command");
00877             rv = SetRegistryKey(HKEY_LOCAL_MACHINE, appKeyName.get(), "", (char *)thisApp.get());
00878                         
00879             // (5) add a default icon entry to Software\\Clients\\News\<app name>
00880                 if (NS_SUCCEEDED(rv)) {
00881                     nsCAutoString iconPath(thisApp);
00882                     iconPath += ",0";
00883                  nsCAutoString iconKeyName (keyName);
00884                     iconKeyName.AppendLiteral("\\DefaultIcon");
00885                  rv = SetRegistryKey(HKEY_LOCAL_MACHINE, iconKeyName.get(),"", (char *)iconPath.get());
00886                 }
00887             }            
00888 
00889         // if we got this far, set a flag in the registry so we know we have registered ourself as a default news application
00890         SetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, "registeredAsNewsApp", "1");
00891                 }
00892 
00893     return rv;
00894 }            
00895 
00898 nsresult nsMapiRegistryUtils::setDefaultNewsClient()
00899 {
00900     nsresult rv;
00901     nsresult mailKeySet=NS_ERROR_FAILURE;
00902 
00903     if (mRestrictedRegAccess) 
00904       return NS_ERROR_FAILURE;
00905 
00906     rv = saveDefaultNewsClient();
00907 
00908     if (NS_FAILED(saveUserDefaultNewsClient()) || NS_FAILED(rv)) 
00909       return NS_ERROR_FAILURE;
00910     
00911     // make sure we have already registered ourself as a potential news application with the OS:
00912     registerNewsApp(PR_TRUE);
00913 
00914     // give Software\Clients\News a default value of our application name.
00915     nsCAutoString appName;
00916     NS_CopyUnicodeToNative(vendorName(), appName);
00917 
00918     SetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\News", "", (char *)appName.get());
00919 
00920     // delete the existing news related protocol keys from HKEY_LOCAL_MACHINE\Classes
00921     recursiveDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\news"); 
00922     recursiveDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\nntp"); 
00923     recursiveDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\snews"); 
00924 
00925     // copy our protocol handlers out to HKEY_LOCAL_MACHINE\Classes<protocol>
00926     nsCAutoString keyName("Software\\Clients\\News\\");
00927     keyName.Append(appName);
00928     keyName.AppendLiteral("\\Protocols\\");
00929 
00930     rv = setProtocolHandler(keyName.get(), "news"); 
00931     rv = setProtocolHandler(keyName.get(), "snews"); 
00932     rv = setProtocolHandler(keyName.get(), "nntp"); 
00933 
00934     rv = SetRegistryKey(HKEY_CURRENT_USER, "Software\\Clients\\News", "", (char *)appName.get());
00935 
00936     // send out a system notifcation to let everyone know the default news client has changed
00937     ::SendMessageTimeout( HWND_BROADCAST,
00938                           WM_SETTINGCHANGE,
00939                           0,
00940                           (LPARAM)MOZ_CLIENT_NEWS_KEY,
00941                           SMTO_NORMAL|SMTO_ABORTIFHUNG,
00942                           MOZ_HWND_BROADCAST_MSG_TIMEOUT,
00943                           NULL);
00944     return rv;
00945 }
00946 
00947 nsresult nsMapiRegistryUtils::setDefaultFeedClient()
00948 {
00949     return setupDefaultProtocolKey("Software\\Classes\\", "feed", "URL:Feed Protocol", "-mail");
00950 }
00951 
00952 nsresult nsMapiRegistryUtils::unsetDefaultFeedClient()
00953 {
00954     // delete the existing mail related protocol keys from HKEY_LOCAL_MACHINE\Software\Classes
00955     return recursiveDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\feed"); 
00956 }
00957 
00958 PRBool nsMapiRegistryUtils::IsDefaultFeedClient()
00959 {  
00960     //first try to get the users default news client
00961     nsCAutoString result; 
00962     GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\feed\\shell\\open\\command", "", result);     
00963 
00964     if (!result.IsEmpty()) {
00965        nsCAutoString strExtension;
00966        strExtension.Assign(EXE_EXTENSION);
00967        ToUpperCase(result);
00968        PRInt32 index = result.RFind(strExtension.get());
00969        if (index != kNotFound) 
00970            result.Truncate(index + strExtension.Length());
00971 
00972        nsCAutoString thisApp (thisApplication()) ;
00973        return (result == thisApp);
00974     }
00975 
00976     return PR_FALSE;
00977 }
00978 
00981 nsresult nsMapiRegistryUtils::setDefaultMailClient()
00982 {
00983     nsresult rv = NS_OK;    
00984     if (mRestrictedRegAccess) 
00985       return NS_ERROR_FAILURE;
00986     
00987     if (!isSmartDll()) {
00988         if (NS_FAILED(CopyMozMapiToWinSysDir())) 
00989           return NS_ERROR_FAILURE;
00990     }
00991 
00992     rv = saveDefaultMailClient();
00993     if (NS_SUCCEEDED(rv))
00994       rv = saveUserDefaultMailClient();
00995     
00996     NS_ENSURE_SUCCESS(rv, rv);
00997     
00998     // make sure we have already registered ourself as a potential mail application with the OS:
00999     registerMailApp(PR_TRUE);
01000 
01001     // give Software\Clients\Mail a default value of our application name.
01002     nsCAutoString appName;
01003     NS_CopyUnicodeToNative(vendorName(), appName);
01004     SetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\Mail", "", (char *)appName.get());
01005 
01006     // if we succeeded in setting ourselves as the default mapi client, then 
01007      // make sure we also set ourselves as the mailto protocol handler for the user...
01008      nsCAutoString keyName("Software\\Clients\\Mail\\");
01009      keyName.Append(appName);
01010      keyName.AppendLiteral("\\Protocols\\");
01011         
01012     // delete the existing mail related protocol keys from HKEY_LOCAL_MACHINE\Software\Classes
01013     recursiveDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\mailto"); 
01014     rv = setProtocolHandler(keyName.get(), "mailto");
01015 
01016     rv = SetRegistryKey(HKEY_CURRENT_USER, "Software\\Clients\\Mail", "", (char *)appName.get());
01017 
01018     // We are now the default mail client so set defaultMailHasBeenSet
01019     if (NS_SUCCEEDED(rv))
01020       rv = SetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, "defaultMailHasBeenSet", "1");
01021 
01022      // now notify anyone listening that there is a new default mail client in town
01023         ::SendMessageTimeout( HWND_BROADCAST,
01024                               WM_SETTINGCHANGE,
01025                               0,
01026                               (LPARAM)MOZ_CLIENT_MAIL_KEY,
01027                               SMTO_NORMAL|SMTO_ABORTIFHUNG,
01028                               MOZ_HWND_BROADCAST_MSG_TIMEOUT,
01029                               NULL);
01030 
01031     // Tell the MAPI Service to register the mapi proxy dll now that we are the default mail application
01032     nsCOMPtr<nsIMapiSupport> mapiService (do_GetService(NS_IMAPISUPPORT_CONTRACTID, &rv));
01033     NS_ENSURE_SUCCESS(rv, rv);
01034     return mapiService->RegisterServer();
01035 }
01036 
01037 nsresult nsMapiRegistryUtils::unsetDefaultNewsClient() {
01038     nsresult rv = NS_OK;
01039     nsresult mailKeySet = NS_ERROR_FAILURE;
01040 
01041     if (mRestrictedRegAccess) 
01042       return NS_ERROR_FAILURE;
01043     
01044     nsCAutoString name ;
01045 
01046     // get the name of the default news client
01047     GetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, "HKEY_LOCAL_MACHINE\\Software\\Clients\\News", name);
01048     
01049     // Use vendorName instead of brandname since brandName is product name
01050     // and has more than just the name of the application
01051     nsCAutoString appName;
01052     NS_CopyUnicodeToNative(vendorName(), appName);
01053     
01054     // if we are the current default client....
01055     if (!name.IsEmpty() && !appName.IsEmpty() && name.Equals(appName))  
01056     {
01057       // XXX Do we need to do anything here? Maybe we want to clear out name. If we were the previous default news client
01058       // and the user is trying to unset us as the current default news client, we probably don't want to re-store ourselves
01059       // again?
01060 
01061       name = "";
01062     }
01063 
01064     // delete the protocol keys we copied to HKEY_LOCAL_MACHINE\Classes when we were made the default news application
01065 
01066     recursiveDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\news"); 
01067     recursiveDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\nntp"); 
01068     recursiveDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\snews"); 
01069 
01070     // set HKEY_LOCAL_MACHINE\Software\Clients\News
01071     if (!name.IsEmpty()) 
01072     {
01073       mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\News", "", (char *)name.get());
01074 
01075       // copy the protocol handlers for the original default news app out to HKEY_LOCAL_MACHINE\Classes<protocol>
01076       nsCAutoString keyName("Software\\Clients\\News\\");
01077       keyName.Append(name);
01078       keyName.AppendLiteral("\\Protocols\\");
01079 
01080       rv = setProtocolHandler(keyName.get(), "news"); 
01081       rv = setProtocolHandler(keyName.get(), "snews"); 
01082       rv = setProtocolHandler(keyName.get(), "nntp"); 
01083     }
01084     else {
01085         mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\News","", "");
01086     }
01087     
01088     // change HKEY_CURRENT_USER\\Software\\Clients\\News 
01089     nsCAutoString userAppName ;
01090     GetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, "HKEY_CURRENT_USER\\Software\\Clients\\News", userAppName);
01091 
01092     if (!userAppName.IsEmpty()) 
01093         SetRegistryKey(HKEY_CURRENT_USER, "Software\\Clients\\News", "", (char *)userAppName.get());
01094     else 
01095         DeleteRegistryValue(HKEY_CURRENT_USER, "Software\\Clients\\News", "");
01096 
01097     
01098      // send out a system notifcation to let everyone know the default news client has changed
01099     ::SendMessageTimeout( HWND_BROADCAST,
01100                           WM_SETTINGCHANGE,
01101                           0,
01102                           (LPARAM)MOZ_CLIENT_NEWS_KEY,
01103                           SMTO_NORMAL|SMTO_ABORTIFHUNG,
01104                           MOZ_HWND_BROADCAST_MSG_TIMEOUT,
01105                           NULL);
01106     return mailKeySet;
01107 }
01108 
01111 nsresult nsMapiRegistryUtils::unsetDefaultMailClient() {
01112     nsresult result = NS_OK;
01113     nsresult mailKeySet = NS_ERROR_FAILURE;
01114     
01115     if (mRestrictedRegAccess) 
01116       return NS_ERROR_FAILURE;
01117 
01118     if (!isSmartDll()) 
01119     {
01120       result = RestoreBackedUpMapiDll();
01121       NS_ENSURE_SUCCESS(result, result);
01122     }
01123 
01124     nsCAutoString name ;
01125     GetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, "HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail", name);
01126 
01127     // Use vendorName instead of brandname since brandName is product name
01128     // and has more than just the name of the application
01129     nsCAutoString appName;
01130     NS_CopyUnicodeToNative(vendorName(), appName);
01131 
01132     if (!name.IsEmpty() && !appName.IsEmpty() && name.Equals(appName)) {
01133         nsCAutoString keyName("HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail\\");
01134         keyName.Append(appName.get());
01135         keyName.AppendLiteral("\\Protocols\\mailto\\shell\\open\\command");
01136         nsCAutoString appPath ;
01137         GetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, keyName.get(), appPath);
01138         if (!appPath.IsEmpty()) {
01139             keyName.Assign("Software\\Clients\\Mail\\");
01140             keyName.Append(appName.get());
01141             keyName.AppendLiteral("\\Protocols\\mailto\\shell\\open\\command");
01142             result = SetRegistryKey(HKEY_LOCAL_MACHINE, 
01143                        keyName.get(), 
01144                        "", (char *)appPath.get());
01145             if (NS_SUCCEEDED(result)) {
01146                 char* pathSep = (char *)
01147                     _mbsrchr((const unsigned char *) appPath.get(), '\\');
01148                 if (pathSep) 
01149                     appPath.Truncate(pathSep - appPath.get() + 1);
01150                 appPath += "mozMapi32.dll";
01151                 keyName.Assign("Software\\Clients\\Mail\\");
01152                 keyName.Append(appName.get());
01153                 result = SetRegistryKey(HKEY_LOCAL_MACHINE, 
01154                                         keyName.get(), 
01155                                         "DLLPath", (char *) appPath.get());
01156             }
01157         }
01158     }
01159 
01160     recursiveDeleteKey(HKEY_LOCAL_MACHINE, "Software\\Classes\\mailto"); 
01161 
01162     if (!name.IsEmpty())  // Restore the previous default app for Software\Clients\Mail
01163     {
01164         // copy the protocol handlers for the original default mail app out to HKEY_LOCAL_MACHINE\Classes<protocol>
01165 
01166         nsCAutoString keyName("Software\\Clients\\Mail\\");
01167         keyName.Append(name);
01168         keyName.AppendLiteral("\\Protocols\\");
01169         setProtocolHandler(keyName.get(), "mailto"); 
01170 
01171         mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\Mail", "", (char *)name.get());
01172     }
01173     else
01174         mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\Mail", "", "");
01175 
01176     // change HKEY_CURRENT_USER\\Software\\Clients\\Mail 
01177     nsCAutoString userAppName ;
01178     GetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, "HKEY_CURRENT_USER\\Software\\Clients\\Mail", userAppName);
01179     
01180     restoreFileExtension("Software\\Classes\\", ".eml");
01181 
01182     if (!userAppName.IsEmpty()) 
01183         SetRegistryKey(HKEY_CURRENT_USER, "Software\\Clients\\Mail", "", (char *)userAppName.get());
01184     else 
01185         DeleteRegistryValue(HKEY_CURRENT_USER, "Software\\Clients\\Mail", "");
01186 
01187     SetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey,"defaultMailHasBeenSet", "0");
01188 
01189     ::SendMessageTimeout( HWND_BROADCAST,
01190                           WM_SETTINGCHANGE,
01191                           0,
01192                           (LPARAM)MOZ_CLIENT_MAIL_KEY,
01193                           SMTO_NORMAL|SMTO_ABORTIFHUNG,
01194                           MOZ_HWND_BROADCAST_MSG_TIMEOUT,
01195                           NULL);
01196     // Tell the MAPI Service to register the mapi proxy dll now that we are the default mail application
01197     nsCOMPtr<nsIMapiSupport> mapiService (do_GetService(NS_IMAPISUPPORT_CONTRACTID, &result));
01198     NS_ENSURE_SUCCESS(result, result);
01199     mapiService->UnRegisterServer();
01200     return mailKeySet;
01201 }
01202 
01210 PRBool nsMapiRegistryUtils::getShowDialog() {
01211     PRBool rv = PR_FALSE;
01212     nsCAutoString showDialog ;
01213     GetRegistryKey(HKEY_LOCAL_MACHINE, kAppDesktopKey, 
01214                                         "showMapiDialog", showDialog);
01215     // if the user has not selected the checkbox, show dialog 
01216     if (showDialog.IsEmpty() || showDialog.Equals("1"))
01217       rv = PR_TRUE;
01218 
01219     if (!rv) 
01220     {
01221         // even if the user has selected the checkbox
01222         // show it if some other application has changed the 
01223         // default setting.
01224         nsCAutoString setMailDefault ;
01225         GetRegistryKey(HKEY_LOCAL_MACHINE,kAppDesktopKey, 
01226                                        "defaultMailHasBeenSet", setMailDefault);
01227         if (setMailDefault.Equals("1")) 
01228         {
01229             // need to reset the defaultMailHasBeenSet to "0"
01230             // so that after the dialog is displayed once,
01231             // we do not keep displaying this dialog after the user has
01232             // selected the checkbox
01233             rv = SetRegistryKey(HKEY_LOCAL_MACHINE, 
01234                                 kAppDesktopKey, 
01235                                 "defaultMailHasBeenSet", "0");
01236             rv = PR_TRUE;
01237         }
01238     }
01239     return rv;
01240 }
01241 
01242 nsresult nsMapiRegistryUtils::MakeMapiStringBundle(nsIStringBundle ** aMapiStringBundle)
01243 {
01244     nsresult rv = NS_OK ;
01245 
01246     if (m_mapiStringBundle)
01247     {
01248         *aMapiStringBundle = m_mapiStringBundle ;
01249         NS_ADDREF(*aMapiStringBundle);
01250         return rv ;
01251     }
01252 
01253     nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(
01254                                      NS_STRINGBUNDLE_CONTRACTID, &rv));
01255     if (NS_FAILED(rv) || !bundleService) return NS_ERROR_FAILURE;
01256 
01257     rv = bundleService->CreateBundle(
01258                     MAPI_PROPERTIES_CHROME,
01259                     getter_AddRefs(m_mapiStringBundle));
01260     NS_ENSURE_SUCCESS(rv, rv);
01261 
01262     NS_ADDREF(*aMapiStringBundle = m_mapiStringBundle) ;
01263 
01264     return rv ;
01265 }
01266 
01267 nsresult nsMapiRegistryUtils::ShowMapiErrorDialog(PRBool aForMail) 
01268 {
01269     nsresult rv;
01270     nsCOMPtr<nsIPromptService> promptService(do_GetService(
01271                   NS_PROMPTSERVICE_CONTRACTID, &rv));
01272     if (NS_SUCCEEDED(rv) && promptService)
01273     {
01274         nsCOMPtr<nsIStringBundle> bundle;
01275         rv = MakeMapiStringBundle (getter_AddRefs (bundle)) ;
01276         NS_ENSURE_SUCCESS(rv, rv);
01277 
01278         nsXPIDLString dialogTitle;
01279         const PRUnichar *brandStrings[] = { brandName() };
01280         NS_NAMED_LITERAL_STRING(dialogTitlePropertyTag, "errorMessageTitle");
01281         rv = bundle->FormatStringFromName(dialogTitlePropertyTag.get(),
01282                                           brandStrings, 1,
01283                                           getter_Copies(dialogTitle));
01284         NS_ENSURE_SUCCESS(rv, rv);
01285 
01286         nsXPIDLString dialogText;
01287 
01288         NS_NAMED_LITERAL_STRING(dialogTextPropertyTag, "errorMessage");
01289         NS_NAMED_LITERAL_STRING(dialogTextPropertyTagForNews, "errorMessageNews");
01290 
01291 
01292         rv = bundle->FormatStringFromName(aForMail ? dialogTextPropertyTag.get() : dialogTextPropertyTagForNews.get(),
01293                                           brandStrings, 1,
01294                                           getter_Copies(dialogText));
01295         NS_ENSURE_SUCCESS(rv, rv);
01296 
01297         rv = promptService->Alert(nsnull, dialogTitle, dialogText);
01298     }
01299     return rv;
01300 }
01301