Back to index

lightning-sunbird  0.9+nobinonly
nsInstallFolder.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Daniel Veditz <dveditz@netscape.com>
00025  *   Douglas Turner <dougt@netscape.com>
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 #include "nsInstall.h"
00042 #include "nsInstallFolder.h"
00043 
00044 #include "nscore.h"
00045 #include "prtypes.h"
00046 #include "nsIComponentManager.h"
00047 
00048 #include "nsString.h"
00049 #include "nsUnicharUtils.h"
00050 #include "nsNativeCharsetUtils.h"
00051 #include "nsXPIDLString.h"
00052 #include "nsFileSpec.h"
00053 #include "nsIFileSpec.h"
00054 #include "nsIFile.h"
00055 #include "nsILocalFile.h"
00056 #include "nsDirectoryService.h"
00057 #include "nsDirectoryServiceDefs.h"
00058 #include "nsAppDirectoryServiceDefs.h"
00059 
00060 #ifdef XP_WIN
00061 #include <stdarg.h>
00062 #include <winbase.h>
00063 #include <winreg.h>
00064 #endif
00065 
00066 struct DirectoryTable
00067 {
00068        const char * directoryName;        /* The formal directory name */
00069        PRInt32 folderEnum;                 /* Directory ID */
00070 };
00071 
00072 struct DirectoryTable DirectoryTable[] = 
00073 {
00074   {"Plugins",                       PLUGIN_DIR                       },
00075   {"Program",                       PROGRAM_DIR                      },
00076   {"Communicator",                  PROGRAM_DIR                      }, // "Communicator" is deprecated
00077 
00078   {"Temporary",                     TEMP_DIR                         },
00079   {"OS Home",                       OS_HOME_DIR                      },
00080   {"Profile",                       PROFILE_DIR                      },
00081   {"Current User",                  PROFILE_DIR                      }, // "Current User" is deprecated
00082   {"Preferences",                   PREFERENCES_DIR                  },
00083   {"OS Drive",                      OS_DRIVE                         },
00084   {"file:///",                      FILE_TARGET                      },
00085           
00086   {"Components",                    COMPONENTS_DIR                   },
00087   {"Chrome",                        CHROME_DIR                       },
00088 
00089   {"Win System",                    WIN_SYS_DIR                      },
00090   {"Windows",                       WINDOWS_DIR                      },
00091   {"Win Desktop",                   WIN_DESKTOP_DIR                  },
00092   {"Win Desktop Common",            WIN_DESKTOP_COMMON               },
00093   {"Win StartMenu",                 WIN_STARTMENU                    },
00094   {"Win StartMenu Common",          WIN_STARTMENU_COMMON             },
00095   {"Win Programs",                  WIN_PROGRAMS_DIR                 },
00096   {"Win Programs Common",           WIN_PROGRAMS_COMMON              },
00097   {"Win Startup",                   WIN_STARTUP_DIR                  },
00098   {"Win Startup Common",            WIN_STARTUP_COMMON               },
00099   {"Win AppData",                   WIN_APPDATA_DIR                  },
00100   {"Win Program Files",             WIN_PROGRAM_FILES                },
00101   {"Win Common Files",              WIN_COMMON_FILES                 },
00102 
00103   {"Mac System",                    MAC_SYSTEM                       },
00104   {"Mac Desktop",                   MAC_DESKTOP                      },
00105   {"Mac Trash",                     MAC_TRASH                        },
00106   {"Mac Startup",                   MAC_STARTUP                      },                                        
00107   {"Mac Shutdown",                  MAC_SHUTDOWN                     },
00108   {"Mac Apple Menu",                MAC_APPLE_MENU                   },
00109   {"Mac Control Panel",             MAC_CONTROL_PANEL                },
00110   {"Mac Extension",                 MAC_EXTENSION                    },
00111   {"Mac Fonts",                     MAC_FONTS                        },
00112   {"Mac Preferences",               MAC_PREFERENCES                  },
00113   {"Mac Documents",                 MAC_DOCUMENTS                    },
00114 
00115   {"MacOSX Home",                   MACOSX_HOME                      },
00116   {"MacOSX Default Download",       MACOSX_DEFAULT_DOWNLOAD          },
00117   {"MacOSX User Desktop",           MACOSX_USER_DESKTOP              },
00118   {"MacOSX Local Desktop",          MACOSX_LOCAL_DESKTOP             },
00119   {"MacOSX User Applications",      MACOSX_USER_APPLICATIONS         },
00120   {"MacOSX Local Applications",     MACOSX_LOCAL_APPLICATIONS        },
00121   {"MacOSX User Documents",         MACOSX_USER_DOCUMENTS            },
00122   {"MacOSX Local Documents",        MACOSX_LOCAL_DOCUMENTS           },
00123   {"MacOSX User Internet PlugIn",   MACOSX_USER_INTERNET_PLUGIN      },
00124   {"MacOSX Local Internet PlugIn",  MACOSX_LOCAL_INTERNET_PLUGIN     },
00125   {"MacOSX User Frameworks",        MACOSX_USER_FRAMEWORKS           },
00126   {"MacOSX Local Frameworks",       MACOSX_LOCAL_FRAMEWORKS          },
00127   {"MacOSX User Preferences",       MACOSX_USER_PREFERENCES          },
00128   {"MacOSX Local Preferences",      MACOSX_LOCAL_PREFERENCES         },
00129   {"MacOSX Picture Documents",      MACOSX_PICTURE_DOCUMENTS         },
00130   {"MacOSX Movie Documents",        MACOSX_MOVIE_DOCUMENTS           },
00131   {"MacOSX Music Documents",        MACOSX_MUSIC_DOCUMENTS           },
00132   {"MacOSX Internet Sites",         MACOSX_INTERNET_SITES            },
00133 
00134   {"Unix Local",                    UNIX_LOCAL                       },
00135   {"Unix Lib",                      UNIX_LIB                         },
00136 
00137   {"",                              -1                               }
00138 };
00139 
00140 
00141 MOZ_DECL_CTOR_COUNTER(nsInstallFolder)
00142 
00143 nsInstallFolder::nsInstallFolder()
00144 {
00145     MOZ_COUNT_CTOR(nsInstallFolder);
00146 }
00147 
00148 nsresult
00149 nsInstallFolder::Init(nsIFile* rawIFile, const nsString& aRelativePath)
00150 {
00151     mFileSpec = rawIFile;
00152 
00153     if (!aRelativePath.IsEmpty())
00154         AppendXPPath(aRelativePath);
00155 
00156     return NS_OK;
00157 }
00158 
00159 nsresult
00160 nsInstallFolder::Init(const nsAString& aFolderID, const nsString& aRelativePath)
00161 {
00162     SetDirectoryPath( aFolderID, aRelativePath );
00163 
00164     if (mFileSpec)
00165         return NS_OK;
00166 
00167     return NS_ERROR_FAILURE;
00168 }
00169 
00170 nsresult
00171 nsInstallFolder::Init(nsInstallFolder& inFolder, const nsString& subString)
00172 {
00173     if (!inFolder.mFileSpec)
00174         return NS_ERROR_NULL_POINTER;
00175 
00176     inFolder.mFileSpec->Clone(getter_AddRefs(mFileSpec));
00177     
00178     if (!mFileSpec)
00179         return NS_ERROR_FAILURE;
00180 
00181     if(!subString.IsEmpty())
00182         AppendXPPath(subString);
00183 
00184     return NS_OK;
00185 }
00186 
00187 
00188 nsInstallFolder::~nsInstallFolder()
00189 {
00190    MOZ_COUNT_DTOR(nsInstallFolder);
00191 }
00192 
00193 void 
00194 nsInstallFolder::GetDirectoryPath(nsCString& aDirectoryPath)
00195 {
00196   PRBool flagIsDir;
00197   nsCAutoString thePath;
00198   
00199   aDirectoryPath.SetLength(0);
00200 
00201     if (mFileSpec != nsnull)
00202     {
00203       // We want the NATIVE path.
00204       mFileSpec->GetNativePath(thePath);
00205       aDirectoryPath.Assign(thePath);
00206 
00207       mFileSpec->IsDirectory(&flagIsDir);
00208       if (flagIsDir)
00209       {
00210         if (aDirectoryPath.Last() != FILESEP)
00211             aDirectoryPath.Append(FILESEP);
00212       }
00213     }
00214 }
00215 
00216 void
00217 nsInstallFolder::SetDirectoryPath(const nsAString& aFolderID, const nsString& aRelativePath)
00218 {
00219     nsresult rv = NS_OK;
00220 
00221     // reset mFileSpec in case of error
00222     mFileSpec = nsnull;
00223     
00224     nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
00225     if (!directoryService)
00226           return;
00227 
00228     PRInt32 dirID = MapNameToEnum(aFolderID);
00229     switch ( dirID )
00230     {
00231         case PLUGIN_DIR:
00232             if (!nsSoftwareUpdate::GetProgramDirectory())
00233                 directoryService->Get(NS_APP_PLUGINS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mFileSpec));
00234             else
00235             {
00236                 rv = nsSoftwareUpdate::GetProgramDirectory()->Clone(getter_AddRefs(mFileSpec));
00237 
00238                 if (NS_SUCCEEDED(rv))
00239                     mFileSpec->AppendNative(INSTALL_PLUGINS_DIR);
00240                 else
00241                     mFileSpec = nsnull;
00242             }
00243             break; 
00244 
00245 
00246         case PROGRAM_DIR:
00247             if (!nsSoftwareUpdate::GetProgramDirectory())  //Not in stub installer
00248                 directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mFileSpec));
00249             else //In stub installer.  mProgram has been set so 
00250                 rv = nsSoftwareUpdate::GetProgramDirectory()->Clone(getter_AddRefs(mFileSpec));
00251             break;
00252 
00253         
00254         case TEMP_DIR:
00255             directoryService->Get(NS_OS_TEMP_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mFileSpec));
00256             break;
00257 
00258 
00259         case PROFILE_DIR:
00260             directoryService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mFileSpec));
00261             break;
00262             
00263         case OS_HOME_DIR:
00264             directoryService->Get(NS_OS_HOME_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mFileSpec));
00265             break;
00266 
00267         case PREFERENCES_DIR:
00268                 directoryService->Get(NS_APP_PREFS_50_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mFileSpec));
00269             break;
00270 
00271         case OS_DRIVE:
00272             directoryService->Get(NS_OS_DRIVE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mFileSpec));
00273             break;
00274 
00275         case FILE_TARGET:
00276             {
00277                 if (!aRelativePath.IsEmpty())
00278                 {
00279                     nsFileSpec             tmpSpec;
00280                     nsCAutoString          tmpPath("file:///");
00281                     nsCAutoString          nativePath;
00282                     nsCOMPtr<nsILocalFile> localFile;
00283 
00284                     NS_CopyUnicodeToNative(aRelativePath, nativePath);
00285                     tmpPath.Append(nativePath);
00286                     tmpSpec =  nsFileURL(tmpPath.get());
00287 
00288                     rv = NS_FileSpecToIFile( &tmpSpec, getter_AddRefs(localFile) );
00289                     if (NS_SUCCEEDED(rv))
00290                     {
00291                         mFileSpec = do_QueryInterface(localFile);
00292                     }
00293                 }
00294 
00295                 // file:// is a special case where it returns and does not
00296                 // go to the standard relative path code below.  This is
00297                 // so that nsFile(Spec|Path) will work properly.  (ie. Passing
00298                 // just "file://" to the nsFileSpec && nsFileURL is wrong).
00299 
00300                 return;
00301             }
00302             break;
00303 
00304         case COMPONENTS_DIR:
00305             if (!nsSoftwareUpdate::GetProgramDirectory())
00306             {
00307                 directoryService->Get(NS_XPCOM_COMPONENT_DIR, 
00308                                        NS_GET_IID(nsIFile), 
00309                                        getter_AddRefs(mFileSpec));
00310             }
00311             else
00312             {
00313                 rv = nsSoftwareUpdate::GetProgramDirectory()->Clone(getter_AddRefs(mFileSpec));
00314 
00315                 if (NS_SUCCEEDED(rv))
00316                     mFileSpec->AppendNative(INSTALL_COMPONENTS_DIR);
00317                 else
00318                     mFileSpec = nsnull;
00319             }
00320             break;
00321         
00322         case CHROME_DIR:
00323             if (!nsSoftwareUpdate::GetProgramDirectory())
00324             { 
00325                 directoryService->Get(NS_APP_CHROME_DIR, 
00326                                       NS_GET_IID(nsIFile), 
00327                                       getter_AddRefs(mFileSpec));
00328             }
00329             else
00330             {
00331                 rv = nsSoftwareUpdate::GetProgramDirectory()->Clone(getter_AddRefs(mFileSpec));
00332                 if (NS_SUCCEEDED(rv))
00333                     mFileSpec->AppendNative(INSTALL_CHROME_DIR);
00334             }
00335             break;
00336 
00337 #if defined(XP_WIN)
00338         case WIN_SYS_DIR:
00339             directoryService->Get(NS_OS_SYSTEM_DIR, 
00340                                   NS_GET_IID(nsIFile), 
00341                                   getter_AddRefs(mFileSpec));
00342 
00343             break;
00344 
00345         case WINDOWS_DIR:
00346             directoryService->Get(NS_WIN_WINDOWS_DIR, 
00347                                   NS_GET_IID(nsIFile), 
00348                                   getter_AddRefs(mFileSpec));
00349             break;
00350 
00351         case WIN_DESKTOP_DIR:
00352             directoryService->Get( NS_WIN_DESKTOP_DIRECTORY,
00353                                    NS_GET_IID(nsIFile),
00354                                    getter_AddRefs(mFileSpec) );
00355             break;
00356 
00357         case WIN_DESKTOP_COMMON:
00358             directoryService->Get( NS_WIN_COMMON_DESKTOP_DIRECTORY,
00359                                    NS_GET_IID(nsIFile),
00360                                    getter_AddRefs(mFileSpec) );
00361             break;
00362 
00363         case WIN_STARTMENU:
00364             directoryService->Get( NS_WIN_STARTMENU_DIR,
00365                                    NS_GET_IID(nsIFile),
00366                                    getter_AddRefs(mFileSpec) );
00367             break;
00368 
00369         case WIN_STARTMENU_COMMON:
00370             directoryService->Get( NS_WIN_COMMON_STARTMENU_DIR,
00371                                    NS_GET_IID(nsIFile),
00372                                    getter_AddRefs(mFileSpec) );
00373             break;
00374 
00375         case WIN_PROGRAMS_DIR:
00376             directoryService->Get( NS_WIN_PROGRAMS_DIR,
00377                                    NS_GET_IID(nsIFile),
00378                                    getter_AddRefs(mFileSpec) );
00379             break;
00380 
00381         case WIN_PROGRAMS_COMMON:
00382             directoryService->Get( NS_WIN_COMMON_PROGRAMS_DIR,
00383                                    NS_GET_IID(nsIFile),
00384                                    getter_AddRefs(mFileSpec) );
00385             break;
00386 
00387         case WIN_STARTUP_DIR:
00388             directoryService->Get( NS_WIN_STARTUP_DIR,
00389                                    NS_GET_IID(nsIFile),
00390                                    getter_AddRefs(mFileSpec) );
00391             break;
00392 
00393         case WIN_STARTUP_COMMON:
00394             directoryService->Get( NS_WIN_COMMON_STARTUP_DIR,
00395                                    NS_GET_IID(nsIFile),
00396                                    getter_AddRefs(mFileSpec) );
00397             break;
00398 
00399         case WIN_APPDATA_DIR:
00400             directoryService->Get( NS_WIN_APPDATA_DIR,
00401                                    NS_GET_IID(nsIFile),
00402                                    getter_AddRefs(mFileSpec) );
00403             break;
00404 
00405         case WIN_PROGRAM_FILES:
00406         case WIN_COMMON_FILES:
00407             {
00408                 HKEY key;
00409                 LONG result = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
00410                     "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
00411                     0, KEY_QUERY_VALUE, &key );
00412 
00413                 if ( result != ERROR_SUCCESS )
00414                     break;
00415 
00416                 BYTE path[_MAX_PATH + 1] = { 0 };
00417                 DWORD type;
00418                 DWORD pathlen = sizeof(path);
00419                 const char *value = (dirID==WIN_PROGRAM_FILES) ?
00420                                 "ProgramFilesDir" :
00421                                 "CommonFilesDir";
00422                 result = RegQueryValueEx( key, value, 0, &type, path, &pathlen );
00423                 if ( result == ERROR_SUCCESS && type == REG_SZ )
00424                 {
00425                     nsCOMPtr<nsILocalFile> tmp;
00426                     NS_NewNativeLocalFile( nsDependentCString((char*)path),
00427                                            PR_FALSE, getter_AddRefs(tmp) );
00428                     mFileSpec = do_QueryInterface(tmp);
00429                 }
00430            }
00431            break;
00432 #endif
00433 
00434 #if defined (XP_MACOSX)
00435         case MAC_SYSTEM:
00436             directoryService->Get(NS_OS_SYSTEM_DIR, 
00437                                   NS_GET_IID(nsIFile), 
00438                                   getter_AddRefs(mFileSpec));
00439             break;
00440 
00441         case MAC_DESKTOP:
00442             directoryService->Get(NS_MAC_DESKTOP_DIR, 
00443                                   NS_GET_IID(nsIFile), 
00444                                   getter_AddRefs(mFileSpec));
00445             break;
00446 
00447         case MAC_TRASH:
00448             directoryService->Get(NS_MAC_TRASH_DIR, 
00449                                   NS_GET_IID(nsIFile), 
00450                                   getter_AddRefs(mFileSpec));
00451             break;
00452 
00453         case MAC_STARTUP:
00454             directoryService->Get(NS_MAC_STARTUP_DIR, 
00455                                   NS_GET_IID(nsIFile), 
00456                                   getter_AddRefs(mFileSpec));
00457             break;
00458 
00459         case MAC_SHUTDOWN:
00460             directoryService->Get(NS_MAC_SHUTDOWN_DIR, 
00461                                   NS_GET_IID(nsIFile), 
00462                                   getter_AddRefs(mFileSpec));
00463             break;
00464 
00465         case MAC_APPLE_MENU:
00466             directoryService->Get(NS_MAC_APPLE_MENU_DIR, 
00467                                   NS_GET_IID(nsIFile), 
00468                                   getter_AddRefs(mFileSpec));
00469             break;
00470 
00471         case MAC_CONTROL_PANEL:
00472             directoryService->Get(NS_MAC_CONTROL_PANELS_DIR, 
00473                                   NS_GET_IID(nsIFile), 
00474                                   getter_AddRefs(mFileSpec));
00475             break;
00476 
00477         case MAC_EXTENSION:
00478             directoryService->Get(NS_MAC_EXTENSIONS_DIR, 
00479                                   NS_GET_IID(nsIFile), 
00480                                   getter_AddRefs(mFileSpec));
00481             break;
00482 
00483         case MAC_FONTS:
00484             directoryService->Get(NS_MAC_FONTS_DIR, 
00485                                   NS_GET_IID(nsIFile), 
00486                                   getter_AddRefs(mFileSpec));
00487             break;
00488 
00489         case MAC_PREFERENCES:
00490             directoryService->Get(NS_MAC_PREFS_DIR, 
00491                                   NS_GET_IID(nsIFile), 
00492                                   getter_AddRefs(mFileSpec));
00493             break;
00494                 
00495         case MAC_DOCUMENTS:
00496             directoryService->Get(NS_MAC_DOCUMENTS_DIR, 
00497                                   NS_GET_IID(nsIFile), 
00498                                   getter_AddRefs(mFileSpec));
00499             break;
00500 
00501         case MACOSX_HOME:
00502             directoryService->Get(NS_OSX_HOME_DIR, 
00503                                   NS_GET_IID(nsIFile), 
00504                                   getter_AddRefs(mFileSpec));
00505             break;
00506 
00507         case MACOSX_DEFAULT_DOWNLOAD:
00508             directoryService->Get(NS_OSX_DEFAULT_DOWNLOAD_DIR, 
00509                                   NS_GET_IID(nsIFile), 
00510                                   getter_AddRefs(mFileSpec));
00511             break;
00512 
00513         case MACOSX_USER_DESKTOP:
00514             directoryService->Get(NS_OSX_USER_DESKTOP_DIR, 
00515                                   NS_GET_IID(nsIFile), 
00516                                   getter_AddRefs(mFileSpec));
00517             break;
00518 
00519         case MACOSX_LOCAL_DESKTOP:
00520             directoryService->Get(NS_OSX_LOCAL_DESKTOP_DIR, 
00521                                   NS_GET_IID(nsIFile), 
00522                                   getter_AddRefs(mFileSpec));
00523             break;
00524 
00525         case MACOSX_USER_APPLICATIONS:
00526             directoryService->Get(NS_OSX_USER_APPLICATIONS_DIR, 
00527                                   NS_GET_IID(nsIFile), 
00528                                   getter_AddRefs(mFileSpec));
00529             break;
00530 
00531         case MACOSX_LOCAL_APPLICATIONS:
00532             directoryService->Get(NS_OSX_LOCAL_APPLICATIONS_DIR, 
00533                                   NS_GET_IID(nsIFile), 
00534                                   getter_AddRefs(mFileSpec));
00535             break;
00536 
00537         case MACOSX_USER_DOCUMENTS:
00538             directoryService->Get(NS_OSX_USER_DOCUMENTS_DIR, 
00539                                   NS_GET_IID(nsIFile), 
00540                                   getter_AddRefs(mFileSpec));
00541             break;
00542 
00543         case MACOSX_LOCAL_DOCUMENTS:
00544             directoryService->Get(NS_OSX_LOCAL_DOCUMENTS_DIR, 
00545                                   NS_GET_IID(nsIFile), 
00546                                   getter_AddRefs(mFileSpec));
00547             break;
00548 
00549         case MACOSX_USER_INTERNET_PLUGIN:
00550             directoryService->Get(NS_OSX_USER_INTERNET_PLUGIN_DIR, 
00551                                   NS_GET_IID(nsIFile), 
00552                                   getter_AddRefs(mFileSpec));
00553             break;
00554 
00555         case MACOSX_LOCAL_INTERNET_PLUGIN:
00556             directoryService->Get(NS_OSX_LOCAL_INTERNET_PLUGIN_DIR, 
00557                                   NS_GET_IID(nsIFile), 
00558                                   getter_AddRefs(mFileSpec));
00559             break;
00560 
00561         case MACOSX_USER_FRAMEWORKS:
00562             directoryService->Get(NS_OSX_USER_FRAMEWORKS_DIR, 
00563                                   NS_GET_IID(nsIFile), 
00564                                   getter_AddRefs(mFileSpec));
00565             break;
00566 
00567         case MACOSX_LOCAL_FRAMEWORKS:
00568             directoryService->Get(NS_OSX_LOCAL_FRAMEWORKS_DIR, 
00569                                   NS_GET_IID(nsIFile), 
00570                                   getter_AddRefs(mFileSpec));
00571             break;
00572 
00573         case MACOSX_USER_PREFERENCES:
00574             directoryService->Get(NS_OSX_USER_PREFERENCES_DIR, 
00575                                   NS_GET_IID(nsIFile), 
00576                                   getter_AddRefs(mFileSpec));
00577             break;
00578 
00579         case MACOSX_LOCAL_PREFERENCES:
00580             directoryService->Get(NS_OSX_LOCAL_PREFERENCES_DIR, 
00581                                   NS_GET_IID(nsIFile), 
00582                                   getter_AddRefs(mFileSpec));
00583             break;
00584 
00585         case MACOSX_PICTURE_DOCUMENTS:
00586             directoryService->Get(NS_OSX_PICTURE_DOCUMENTS_DIR, 
00587                                   NS_GET_IID(nsIFile), 
00588                                   getter_AddRefs(mFileSpec));
00589             break;
00590 
00591         case MACOSX_MOVIE_DOCUMENTS:
00592             directoryService->Get(NS_OSX_MOVIE_DOCUMENTS_DIR, 
00593                                   NS_GET_IID(nsIFile), 
00594                                   getter_AddRefs(mFileSpec));
00595             break;
00596                 
00597         case MACOSX_MUSIC_DOCUMENTS:
00598             directoryService->Get(NS_OSX_MUSIC_DOCUMENTS_DIR, 
00599                                   NS_GET_IID(nsIFile), 
00600                                   getter_AddRefs(mFileSpec));
00601             break;
00602 
00603         case MACOSX_INTERNET_SITES:
00604             directoryService->Get(NS_OSX_INTERNET_SITES_DIR, 
00605                                   NS_GET_IID(nsIFile), 
00606                                   getter_AddRefs(mFileSpec));
00607             break;
00608 #endif
00609 
00610 #if defined(XP_UNIX) && !defined(XP_MACOSX)                
00611         case UNIX_LOCAL:
00612             directoryService->Get(NS_UNIX_LOCAL_DIR, 
00613                                   NS_GET_IID(nsIFile), 
00614                                   getter_AddRefs(mFileSpec));
00615             break;
00616 
00617         case UNIX_LIB:
00618             directoryService->Get(NS_UNIX_LIB_DIR, 
00619                                   NS_GET_IID(nsIFile), 
00620                                   getter_AddRefs(mFileSpec));
00621             break;
00622 #endif
00623 
00624         case -1:
00625         default:
00626             mFileSpec = nsnull;
00627             break;
00628     }
00629 
00630     if (mFileSpec && !aRelativePath.IsEmpty())
00631     {
00632         AppendXPPath(aRelativePath);
00633     }
00634 }
00635 
00636 
00637 void
00638 nsInstallFolder::AppendXPPath(const nsString& aRelativePath)
00639 {
00640     nsAutoString segment;
00641     PRUint32 start = 0;
00642     PRUint32 curr;
00643 
00644     NS_ASSERTION(!aRelativePath.IsEmpty(),"InstallFolder appending null path");
00645     do {
00646         curr = aRelativePath.FindChar('/',start);
00647         if ( curr == start )
00648         {
00649             // illegal, two slashes in a row (or not a relative path)
00650             mFileSpec = nsnull;
00651             break;
00652         }
00653         else if ( curr == kNotFound )
00654         {
00655             // last segment
00656             aRelativePath.Right(segment,aRelativePath.Length() - start);
00657             start = aRelativePath.Length();
00658         }
00659         else
00660         {
00661             // found a segment
00662             aRelativePath.Mid(segment,start,curr-start);
00663             start = curr+1;
00664         }
00665             
00666         nsresult rv = mFileSpec->Append(segment);
00667         if (NS_FAILED(rv))
00668         {
00669             // Unicode converters not present (likely wizard case)
00670             // so do our best with the vanilla conversion.
00671             mFileSpec->AppendNative(NS_LossyConvertUCS2toASCII(segment));
00672         }
00673     } while ( start < aRelativePath.Length() );
00674 }
00675 
00676 
00677 /* MapNameToEnum
00678  * maps name from the directory table to its enum */
00679 PRInt32 
00680 nsInstallFolder::MapNameToEnum(const nsAString& name)
00681 {
00682        int i = 0;
00683 
00684        if ( name.IsEmpty())
00685         return -1;
00686 
00687        while ( DirectoryTable[i].directoryName[0] != 0 )
00688        {
00689     // safe compare because all strings in DirectoryTable are ASCII
00690     if ( name.Equals(NS_ConvertASCIItoUCS2(DirectoryTable[i].directoryName), nsCaseInsensitiveStringComparator()) )
00691                      return DirectoryTable[i].folderEnum;
00692               i++;
00693        }
00694        return -1;
00695 }
00696 
00697 
00698 
00699 nsIFile*
00700 nsInstallFolder::GetFileSpec()
00701 {
00702   return mFileSpec;
00703 }
00704 
00705 PRInt32
00706 nsInstallFolder::ToString(nsAutoString* outString)
00707 {
00708   //XXX: May need to fix. Native charset paths will be converted into Unicode when the get to JS
00709   //     This will appear to work on Latin-1 charsets but won't work on Mac or other charsets.
00710   //     On the other hand doing it right requires intl charset converters
00711   //     which we don't yet have in the initial install case.
00712   //
00713   //     However, nsLocalFile now uses the native charset conversion implementation, so this
00714   //     code should always work.
00715 
00716   if (!mFileSpec || !outString)
00717       return NS_ERROR_NULL_POINTER;
00718 
00719   nsresult rv = mFileSpec->GetPath(*outString);
00720   if (NS_FAILED(rv))
00721   {
00722     // converters not present, most likely in wizard case;
00723     // do best we can with stock ASCII conversion
00724 
00725     // Since bug 100676 was fixed we should never get here
00726 
00727     // XXX NOTE we can make sure our filenames are ASCII, but we have no
00728     // control over the directory name which might be localized!!!
00729     NS_ASSERTION(PR_FALSE, "Couldn't get Unicode path, using broken conversion!");
00730     nsCAutoString temp;
00731     rv = mFileSpec->GetNativePath(temp);
00732     CopyASCIItoUTF16(temp, *outString);
00733   }
00734 
00735   PRBool flagIsFile = PR_FALSE;
00736   mFileSpec->IsFile(&flagIsFile);
00737   if (!flagIsFile)
00738   {
00739       // assume directory, thus end with slash.
00740       outString->Append(PRUnichar(FILESEP));
00741   }
00742 
00743   return rv;
00744 }
00745