Back to index

lightning-sunbird  0.9+nobinonly
nsSpecialSystemDirectory.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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  *   Doug Turner <dougt@netscape.com>
00025  *   IBM Corp.
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 "nsSpecialSystemDirectory.h"
00042 #include "nsDebug.h"
00043 
00044 #ifdef XP_MAC
00045 #include <Folders.h>
00046 #include <Files.h>
00047 #include <Memory.h>
00048 #include <Processes.h>
00049 #include <Gestalt.h>
00050 #include "nsIInternetConfigService.h"
00051 #ifdef DEBUG
00052 #include "prenv.h" // For PR_Getenv
00053 #endif
00054 #elif defined(XP_WIN)
00055 #include <windows.h>
00056 #include <shlobj.h>
00057 #include <stdlib.h>
00058 #include <stdio.h>
00059 #include <ctype.h>
00060 #include "nsNativeCharsetUtils.h"
00061 #elif defined(XP_OS2)
00062 #define MAX_PATH _MAX_PATH
00063 #define INCL_WINWORKPLACE
00064 #include <os2.h>
00065 #include <stdlib.h>
00066 #include <stdio.h>
00067 #include "prenv.h"
00068 #elif defined(XP_UNIX)
00069 #include <unistd.h>
00070 #include <stdlib.h>
00071 #include <sys/param.h>
00072 #include "prenv.h"
00073 #elif defined(XP_BEOS)
00074 #include <FindDirectory.h>
00075 #include <Path.h>
00076 #include <unistd.h>
00077 #include <stdlib.h>
00078 #include <sys/param.h>
00079 #include <OS.h>
00080 #include <image.h>
00081 #include "prenv.h"
00082 #endif
00083 
00084 #if defined(VMS)
00085 #include <unixlib.h>
00086 #endif
00087 
00088 #include "plstr.h"
00089 
00090 #include "nsHashtable.h"
00091 #include "prlog.h"
00092 
00093 class SystemDirectoriesKey : public nsHashKey {
00094 public:
00095 
00096     SystemDirectoriesKey(nsSpecialSystemDirectory::SystemDirectories newKey) : sdKey(newKey) {}
00097 
00098     virtual PRUint32 HashCode(void) const
00099     {
00100         return PRUint32(sdKey);
00101     }
00102     
00103     virtual PRBool Equals(const nsHashKey *aKey) const
00104     {
00105         nsSpecialSystemDirectory::SystemDirectories other = 
00106             ((SystemDirectoriesKey*)aKey)->sdKey;
00107         return other == sdKey;
00108     }
00109     
00110     virtual nsHashKey *Clone(void) const
00111     {
00112         return new SystemDirectoriesKey(sdKey);
00113     }
00114 
00115 private:
00116     nsSpecialSystemDirectory::SystemDirectories sdKey; // sd for SystemDirectories
00117 };
00118 
00119 PR_STATIC_CALLBACK(PRBool) DeleteSystemDirKeys(nsHashKey *aKey, void *aData, void* closure)
00120 {
00121     delete ((nsFileSpec *)aData);
00122     return PR_TRUE;
00123 }
00124 
00125 #define NS_SYSTEMDIR_HASH_NUM (10)
00126 static nsHashtable *systemDirectoriesLocations = NULL;
00127 #if defined (XP_WIN)
00128 typedef BOOL (WINAPI * GetSpecialPathProc) (HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
00129 GetSpecialPathProc gGetSpecialPathProc = NULL;
00130 static HINSTANCE gShell32DLLInst = NULL;
00131 #endif
00132 
00133 #if defined (XP_WIN)
00134 
00135 //----------------------------------------------------------------------------------------
00136 static char* MakeUpperCase(char* aPath)
00137 //----------------------------------------------------------------------------------------
00138 {
00139   // windows does not care about case.  push to uppercase:
00140   nsAutoString widePath;
00141   nsDependentCString path(aPath);
00142   nsresult rv = NS_CopyNativeToUnicode(path, widePath);
00143   if (NS_FAILED(rv)) {
00144       NS_ERROR("failed to convert a path to Unicode");
00145       return aPath;
00146   }
00147 
00148   PRUnichar *start = widePath.BeginWriting();
00149   PRUnichar *end = widePath.EndWriting();
00150 
00151   while (start != end) {
00152       // XXX this doesn't change any non-ASCII character 
00153       *start = towupper(*start);
00154       ++start;
00155   }
00156 
00157   nsCAutoString newCPath;
00158   NS_CopyUnicodeToNative(widePath, newCPath); 
00159   NS_ASSERTION(path.Length() >= newCPath.Length(), 
00160                "uppercased string is longer than original");
00161   ::strcpy(aPath, newCPath.get());
00162 
00163   return aPath;
00164 }
00165 
00166 //----------------------------------------------------------------------------------------
00167 static void GetWindowsFolder(int folder, nsFileSpec& outDirectory)
00168 //----------------------------------------------------------------------------------------
00169 {
00170 
00171     if (gGetSpecialPathProc) {
00172         TCHAR path[MAX_PATH];
00173         HRESULT result = gGetSpecialPathProc(NULL, path, folder, true);
00174         
00175         if (!SUCCEEDED(result)) 
00176             return;
00177 
00178         // Append the trailing slash
00179         int len = PL_strlen(path);
00180         if (len>1 && path[len-1] != '\\') 
00181         {
00182             path[len]   = '\\';
00183             path[len + 1] = '\0';
00184         }
00185         outDirectory = path;
00186         return;
00187     }
00188 
00189     LPMALLOC pMalloc = NULL;
00190     LPSTR pBuffer = NULL;
00191     LPITEMIDLIST pItemIDList = NULL;
00192     int len;
00193  
00194     // Get the shell's allocator. 
00195     if (!SUCCEEDED(SHGetMalloc(&pMalloc))) 
00196         return;
00197 
00198     // Allocate a buffer
00199     if ((pBuffer = (LPSTR) pMalloc->Alloc(MAX_PATH + 2)) == NULL) 
00200         return; 
00201  
00202     // Get the PIDL for the folder. 
00203     if (!SUCCEEDED(SHGetSpecialFolderLocation( 
00204             NULL, folder, &pItemIDList)))
00205         goto Clean;
00206  
00207     if (!SUCCEEDED(SHGetPathFromIDList(pItemIDList, pBuffer)))
00208         goto Clean;
00209 
00210     // Append the trailing slash
00211     len = PL_strlen(pBuffer);
00212     pBuffer[len]   = '\\';
00213     pBuffer[len + 1] = '\0';
00214 
00215     // Assign the directory
00216     outDirectory = pBuffer;
00217 
00218 Clean:
00219     // Clean up. 
00220     if (pItemIDList)
00221         pMalloc->Free(pItemIDList); 
00222     if (pBuffer)
00223         pMalloc->Free(pBuffer); 
00224 
00225        pMalloc->Release();
00226 } // GetWindowsFolder
00227 #endif // XP_WIN
00228 
00229 //----------------------------------------------------------------------------------------
00230 static void GetCurrentWorkingDirectory(nsFileSpec& aFileSpec)
00231 //----------------------------------------------------------------------------------------
00232 {
00233     aFileSpec = ".";
00234     return;
00235 } // GetCurrentWorkingDirectory
00236 
00237 //----------------------------------------------------------------------------------------
00238 static void GetCurrentProcessDirectory(nsFileSpec& aFileSpec)
00239 //----------------------------------------------------------------------------------------
00240 {
00241 #if defined (XP_WIN)
00242     char buf[MAX_PATH];
00243     if ( ::GetModuleFileName(0, buf, sizeof(buf)) ) {
00244         // chop of the executable name by finding the rightmost backslash
00245         char* lastSlash = PL_strrchr(buf, '\\');
00246         if (lastSlash)
00247             *(lastSlash + 1) = '\0';
00248 
00249         aFileSpec = buf;
00250         return;
00251     }
00252 
00253 #elif defined(XP_OS2)
00254     PPIB ppib;
00255     PTIB ptib;
00256     char buffer[CCHMAXPATH];
00257     DosGetInfoBlocks( &ptib, &ppib);
00258     DosQueryModuleName( ppib->pib_hmte, CCHMAXPATH, buffer);
00259     *strrchr( buffer, '\\') = '\0'; // XXX DBCS misery
00260     aFileSpec = buffer;
00261     return;
00262 
00263 #elif defined(XP_UNIX)
00264 
00265     // In the absence of a good way to get the executable directory let
00266     // us try this for unix:
00267     // - if MOZILLA_FIVE_HOME is defined, that is it
00268     // - else give the current directory
00269     char buf[MAXPATHLEN];
00270     char *moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
00271     if (moz5)
00272     {
00273         aFileSpec = moz5;
00274         return;
00275     }
00276     else
00277     {
00278 #if defined(DEBUG)
00279         static PRBool firstWarning = PR_TRUE;
00280 
00281         if(firstWarning) {
00282             // Warn that MOZILLA_FIVE_HOME not set, once.
00283             printf("Warning: MOZILLA_FIVE_HOME not set.\n");
00284             firstWarning = PR_FALSE;
00285         }
00286 #endif /* DEBUG */
00287 
00288         // Fall back to current directory.
00289         if (getcwd(buf, sizeof(buf)))
00290         {
00291             aFileSpec = buf;
00292             return;
00293         }
00294     }
00295 
00296 #elif defined(XP_BEOS)
00297 
00298     char *moz5 = getenv("MOZILLA_FIVE_HOME");
00299     if (moz5)
00300     {
00301         aFileSpec = moz5;
00302         return;
00303     }
00304     else
00305     {
00306       static char buf[MAXPATHLEN];
00307       int32 cookie = 0;
00308       image_info info;
00309       char *p;
00310       *buf = 0;
00311       if(get_next_image_info(0, &cookie, &info) == B_OK)
00312       {
00313         strcpy(buf, info.name);
00314         if((p = strrchr(buf, '/')) != 0)
00315         {
00316           *p = 0;
00317           aFileSpec = buf;
00318           return;
00319         }
00320       }
00321     }
00322 
00323 #endif
00324 
00325     NS_ERROR("unable to get current process directory");
00326 } // GetCurrentProcessDirectory()
00327 
00328 //nsSpecialSystemDirectory::nsSpecialSystemDirectory()
00329 //:    nsFileSpec(nsnull)
00330 //{
00331 //}
00332 
00333 //----------------------------------------------------------------------------------------
00334 nsSpecialSystemDirectory::nsSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory)
00335 //----------------------------------------------------------------------------------------
00336 :    nsFileSpec(nsnull)
00337 {
00338     *this = aSystemSystemDirectory;
00339 }
00340 
00341 //----------------------------------------------------------------------------------------
00342 nsSpecialSystemDirectory::~nsSpecialSystemDirectory()
00343 //----------------------------------------------------------------------------------------
00344 {
00345 }
00346 
00347 //----------------------------------------------------------------------------------------
00348 void nsSpecialSystemDirectory::operator = (SystemDirectories aSystemSystemDirectory)
00349 //----------------------------------------------------------------------------------------
00350 {
00351     SystemDirectoriesKey dirKey(aSystemSystemDirectory);
00352     SystemDirectoriesKey mozBinDirKey(Moz_BinDirectory);
00353 
00354     // This flag is used to tell whether or not we need to append something
00355     // onto the *this.  Search for needToAppend to how it's used.
00356     // IT's VERY IMPORTANT that needToAppend is initialized to PR_TRUE.
00357     PRBool needToAppend = PR_TRUE;
00358 
00359     *this = (const char*)nsnull;
00360     switch (aSystemSystemDirectory)
00361     {
00362         
00363         case OS_DriveDirectory:
00364 #if defined (XP_WIN)
00365         {
00366             char path[_MAX_PATH];
00367             PRInt32 len = GetWindowsDirectory( path, _MAX_PATH );
00368             if (len)
00369             {
00370                 if ( path[1] == ':' && path[2] == '\\' )
00371                     path[3] = 0;
00372             }
00373             *this = MakeUpperCase(path);
00374         }
00375 #elif defined(XP_OS2)
00376         {
00377             // printf( "*** Warning warning OS_DriveDirectory called for");
00378             
00379             ULONG ulBootDrive = 0;
00380             char  buffer[] = " :\\OS2\\";
00381             DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
00382                              &ulBootDrive, sizeof ulBootDrive);
00383             buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
00384             *this = buffer;
00385 #ifdef DEBUG
00386             printf( "Got OS_DriveDirectory: %s\n", buffer);
00387 #endif
00388         }
00389 #else
00390         *this = "/";
00391 #endif
00392         break;
00393 
00394             
00395         case OS_TemporaryDirectory:
00396 #if defined (WINCE)
00397             {
00398                 *this = "\\TEMP";
00399             }
00400 #elif defined (XP_WIN)
00401         {
00402             char path[_MAX_PATH];
00403             DWORD len = GetTempPath(_MAX_PATH, path);
00404             *this = MakeUpperCase(path);
00405         }
00406 #elif defined(XP_OS2)
00407           {
00408              char buffer[CCHMAXPATH] = "";
00409              char *c = getenv( "TMP");
00410              if( c) strcpy( buffer, c);
00411              else
00412              {
00413                 c = getenv( "TEMP");
00414                 if( c) strcpy( buffer, c);
00415              }
00416              if( c) *this = buffer;
00417              // use exe's directory if not set
00418              else GetCurrentProcessDirectory(*this);
00419           }        
00420 #elif defined(XP_UNIX) || defined(XP_BEOS)
00421               {
00422                      static const char *tPath = nsnull;
00423                      if (!tPath) {
00424                             tPath = PR_GetEnv("TMPDIR");
00425                             if (!tPath || !*tPath) {
00426                                    tPath = PR_GetEnv("TMP");
00427                                    if (!tPath || !*tPath) {
00428                                           tPath = PR_GetEnv("TEMP");
00429                                           if (!tPath || !*tPath) {
00430                                                  tPath = "/tmp/";
00431                                           }
00432                                    }
00433                             }
00434                      }
00435                      
00436                      *this = tPath;
00437               }
00438 #endif
00439         break;
00440 
00441         case OS_CurrentProcessDirectory:
00442             GetCurrentProcessDirectory(*this);
00443             break;
00444 
00445         case OS_CurrentWorkingDirectory:
00446             GetCurrentWorkingDirectory(*this);
00447             break;
00448 
00449         case XPCOM_CurrentProcessComponentRegistry:
00450             {
00451                 nsFileSpec *dirSpec = NULL;
00452 
00453                 // if someone has called nsSpecialSystemDirectory::Set()
00454                 if (systemDirectoriesLocations) {
00455                     // look for the value for the argument key
00456                     if (!(dirSpec = (nsFileSpec *)systemDirectoriesLocations->Get(&dirKey))) {
00457                         // if not found, try Moz_BinDirectory
00458                         dirSpec = (nsFileSpec *)
00459                             systemDirectoriesLocations->Get(&mozBinDirKey);
00460                     }
00461                     else {
00462                         // if the value is found for the argument key,
00463                         // we don't need to append.
00464                         needToAppend = PR_FALSE;
00465                     }
00466                 }
00467                 
00468                 if (dirSpec)
00469                 {
00470                     *this = *dirSpec;
00471                 }
00472                 else
00473                 {
00474                     GetCurrentProcessDirectory(*this);
00475                 }
00476 
00477                 if (needToAppend) {
00478                     // XXX We need to unify these names across all platforms
00479                     *this += "component.reg";
00480                 }
00481             }
00482             break;
00483 
00484         case XPCOM_CurrentProcessComponentDirectory:
00485             {
00486                 nsFileSpec *dirSpec = NULL;
00487                 // if someone has called nsSpecialSystemDirectory::Set()
00488                 if (systemDirectoriesLocations) {
00489                     // look for the value for the argument key
00490                     if (!(dirSpec = (nsFileSpec *)systemDirectoriesLocations->Get(&dirKey))) {
00491                         // if not found, try Moz_BinDirectory
00492                         dirSpec = (nsFileSpec *)
00493                             systemDirectoriesLocations->Get(&mozBinDirKey);
00494                     }
00495                     else {
00496                         // if the value is found for the argument key,
00497                         // we don't need to append.
00498                         needToAppend = PR_FALSE;
00499                     }
00500                 }
00501                 if (dirSpec)
00502                 {
00503                     *this = *dirSpec;
00504                 }
00505                 else
00506                 {
00507                     // <exedir>/Components
00508                     GetCurrentProcessDirectory(*this);
00509                 }
00510 
00511                 if (needToAppend) {
00512                     // XXX We need to unify these names across all platforms
00513                     *this += "components";
00514                 }
00515             }
00516             break;
00517 
00518         case Moz_BinDirectory:
00519             {
00520                 nsFileSpec *dirSpec = NULL;
00521                 // if someone has called nsSpecialSystemDirectory::Set()
00522                 if (systemDirectoriesLocations) {
00523                     // look for the value for the argument key
00524                     dirSpec = (nsFileSpec *)
00525                         systemDirectoriesLocations->Get(&dirKey);
00526                 }
00527                 if (dirSpec) {
00528                     *this = *dirSpec;
00529                 }
00530                 else {
00531                     GetCurrentProcessDirectory(*this);
00532                 }
00533             }
00534             break;
00535             
00536 #if defined (XP_WIN)
00537         case Win_SystemDirectory:
00538         {    
00539             char path[_MAX_PATH];
00540             PRInt32 len = GetSystemDirectory( path, _MAX_PATH );
00541         
00542             // Need enough space to add the trailing backslash
00543             if (len > _MAX_PATH-2)
00544                 break;
00545             path[len]   = '\\';
00546             path[len+1] = '\0';
00547 
00548             *this = MakeUpperCase(path);
00549 
00550             break;
00551         }
00552 
00553         case Win_WindowsDirectory:
00554         {    
00555             char path[_MAX_PATH];
00556             PRInt32 len = GetWindowsDirectory( path, _MAX_PATH );
00557             
00558             // Need enough space to add the trailing backslash
00559             if (len > _MAX_PATH-2)
00560                 break;
00561             
00562             path[len]   = '\\';
00563             path[len+1] = '\0';
00564 
00565             *this = MakeUpperCase(path);
00566             break;
00567         }
00568 
00569         case Win_HomeDirectory:
00570         {    
00571             char path[_MAX_PATH];
00572             if (GetEnvironmentVariable(TEXT("HOME"), path, _MAX_PATH) > 0)
00573             {
00574                 PRInt32 len = PL_strlen(path);
00575                 // Need enough space to add the trailing backslash
00576                 if (len > _MAX_PATH - 2)
00577                     break;
00578                
00579                 path[len]   = '\\';
00580                 path[len+1] = '\0';
00581                 
00582                 *this = MakeUpperCase(path);
00583                 break;
00584             }
00585 
00586             if (GetEnvironmentVariable(TEXT("HOMEDRIVE"), path, _MAX_PATH) > 0)
00587             {
00588                 char temp[_MAX_PATH];
00589                 if (GetEnvironmentVariable(TEXT("HOMEPATH"), temp, _MAX_PATH) > 0)
00590                    PL_strcatn(path, _MAX_PATH, temp);
00591         
00592                 PRInt32 len = PL_strlen(path);
00593 
00594                 // Need enough space to add the trailing backslash
00595                 if (len > _MAX_PATH - 2)
00596                     break;
00597             
00598                 path[len]   = '\\';
00599                 path[len+1] = '\0';
00600                 
00601                 *this = MakeUpperCase(path);
00602                 break;
00603             }
00604         }
00605         case Win_Desktop:
00606         {
00607             GetWindowsFolder(CSIDL_DESKTOP, *this);
00608             break;
00609         }
00610         case Win_Programs:
00611         {
00612             GetWindowsFolder(CSIDL_PROGRAMS, *this);
00613             break;
00614         }
00615         case Win_Controls:
00616         {
00617             GetWindowsFolder(CSIDL_CONTROLS, *this);
00618             break;
00619         }
00620         case Win_Printers:
00621         {
00622             GetWindowsFolder(CSIDL_PRINTERS, *this);
00623             break;
00624         }
00625         case Win_Personal:
00626         {
00627             GetWindowsFolder(CSIDL_PERSONAL, *this);
00628             break;
00629         }
00630         case Win_Favorites:
00631         {
00632             GetWindowsFolder(CSIDL_FAVORITES, *this);
00633             break;
00634         }
00635         case Win_Startup:
00636         {
00637             GetWindowsFolder(CSIDL_STARTUP, *this);
00638             break;
00639         }
00640         case Win_Recent:
00641         {
00642             GetWindowsFolder(CSIDL_RECENT, *this);
00643             break;
00644         }
00645         case Win_Sendto:
00646         {
00647             GetWindowsFolder(CSIDL_SENDTO, *this);
00648             break;
00649         }
00650         case Win_Bitbucket:
00651         {
00652             GetWindowsFolder(CSIDL_BITBUCKET, *this);
00653             break;
00654         }
00655         case Win_Startmenu:
00656         {
00657             GetWindowsFolder(CSIDL_STARTMENU, *this);
00658             break;
00659         }
00660         case Win_Desktopdirectory:
00661         {
00662             GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, *this);
00663             break;
00664         }
00665         case Win_Drives:
00666         {
00667             GetWindowsFolder(CSIDL_DRIVES, *this);
00668             break;
00669         }
00670         case Win_Network:
00671         {
00672             GetWindowsFolder(CSIDL_NETWORK, *this);
00673             break;
00674         }
00675         case Win_Nethood:
00676         {
00677             GetWindowsFolder(CSIDL_NETHOOD, *this);
00678             break;
00679         }
00680         case Win_Fonts:
00681         {
00682             GetWindowsFolder(CSIDL_FONTS, *this);
00683             break;
00684         }
00685         case Win_Templates:
00686         {
00687             GetWindowsFolder(CSIDL_TEMPLATES, *this);
00688             break;
00689         }
00690 #ifndef WINCE
00691         case Win_Common_Startmenu:
00692         {
00693             GetWindowsFolder(CSIDL_COMMON_STARTMENU, *this);
00694             break;
00695         }
00696         case Win_Common_Programs:
00697         {
00698             GetWindowsFolder(CSIDL_COMMON_PROGRAMS, *this);
00699             break;
00700         }
00701         case Win_Common_Startup:
00702         {
00703             GetWindowsFolder(CSIDL_COMMON_STARTUP, *this);
00704             break;
00705         }
00706         case Win_Common_Desktopdirectory:
00707         {
00708             GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, *this);
00709             break;
00710         }
00711         case Win_Printhood:
00712         {
00713             GetWindowsFolder(CSIDL_PRINTHOOD, *this);
00714             break;
00715         }
00716         case Win_Cookies:
00717         {
00718             GetWindowsFolder(CSIDL_COOKIES, *this);
00719             break;
00720         }
00721 #endif // WINCE
00722 
00723         case Win_Appdata:
00724         {
00725             GetWindowsFolder(CSIDL_APPDATA, *this);
00726             break;
00727         }
00728 #endif  // XP_WIN
00729 
00730 #if defined(XP_UNIX)
00731         case Unix_LocalDirectory:
00732             *this = "/usr/local/netscape/";
00733             break;
00734 
00735         case Unix_LibDirectory:
00736             *this = "/usr/local/lib/netscape/";
00737             break;
00738 
00739         case Unix_HomeDirectory:
00740 #ifdef VMS
00741            {
00742                char *pHome;
00743                pHome = getenv("HOME");
00744               if (*pHome == '/')
00745                   *this = pHome;
00746               else
00747                   *this = decc$translate_vms(pHome);
00748            }
00749 #else
00750             *this = PR_GetEnv("HOME");
00751 #endif
00752             break;
00753 
00754 #endif        
00755 
00756 #ifdef XP_BEOS
00757         case BeOS_SettingsDirectory:
00758               {
00759             char path[MAXPATHLEN];
00760                      find_directory(B_USER_SETTINGS_DIRECTORY, 0, 0, path, MAXPATHLEN);
00761             // Need enough space to add the trailing backslash
00762                      int len = strlen(path);
00763             if (len > MAXPATHLEN-2)
00764                 break;
00765             path[len]   = '/';
00766             path[len+1] = '\0';
00767                      *this = path;
00768             break;
00769               }
00770 
00771         case BeOS_HomeDirectory:
00772               {
00773             char path[MAXPATHLEN];
00774                      find_directory(B_USER_DIRECTORY, 0, 0, path, MAXPATHLEN);
00775             // Need enough space to add the trailing backslash
00776                      int len = strlen(path);
00777             if (len > MAXPATHLEN-2)
00778                 break;
00779             path[len]   = '/';
00780             path[len+1] = '\0';
00781                      *this = path;
00782             break;
00783               }
00784 
00785         case BeOS_DesktopDirectory:
00786               {
00787             char path[MAXPATHLEN];
00788                      find_directory(B_DESKTOP_DIRECTORY, 0, 0, path, MAXPATHLEN);
00789             // Need enough space to add the trailing backslash
00790                      int len = strlen(path);
00791             if (len > MAXPATHLEN-2)
00792                 break;
00793             path[len]   = '/';
00794             path[len+1] = '\0';
00795                      *this = path;
00796             break;
00797               }
00798 
00799         case BeOS_SystemDirectory:
00800               {
00801             char path[MAXPATHLEN];
00802                      find_directory(B_BEOS_DIRECTORY, 0, 0, path, MAXPATHLEN);
00803             // Need enough space to add the trailing backslash
00804                      int len = strlen(path);
00805             if (len > MAXPATHLEN-2)
00806                 break;
00807             path[len]   = '/';
00808             path[len+1] = '\0';
00809                      *this = path;
00810             break;
00811               }
00812 #endif        
00813 #ifdef XP_OS2
00814         case OS2_SystemDirectory:
00815         {
00816             ULONG ulBootDrive = 0;
00817             char  buffer[] = " :\\OS2\\System\\";
00818             DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
00819                              &ulBootDrive, sizeof ulBootDrive);
00820             buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
00821             *this = buffer;
00822 #ifdef DEBUG
00823             printf( "Got OS2_SystemDirectory: %s\n", buffer);
00824 #endif
00825             break;
00826         }
00827 
00828      case OS2_OS2Directory:
00829         {
00830             ULONG ulBootDrive = 0;
00831             char  buffer[] = " :\\OS2\\";
00832             DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
00833                              &ulBootDrive, sizeof ulBootDrive);
00834             buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
00835             *this = buffer;
00836 #ifdef DEBUG
00837             printf( "Got OS2_OS2Directory: %s\n", buffer);
00838 #endif
00839             break;
00840         }
00841 
00842      case OS2_HomeDirectory:
00843         {
00844             char *tPath = PR_GetEnv("MOZILLA_HOME");
00845             /* If MOZILLA_HOME is not set, use GetCurrentProcessDirectory */
00846             /* To ensure we get a long filename system */
00847             if (!tPath || !*tPath)
00848               GetCurrentProcessDirectory(*this);
00849             else
00850               *this = tPath;
00851             PrfWriteProfileString(HINI_USERPROFILE, "Mozilla", "Home", *this);
00852             break;
00853         }
00854 
00855         case OS2_DesktopDirectory:
00856         {
00857             char szPath[CCHMAXPATH + 1];        
00858             BOOL fSuccess;
00859             fSuccess = WinQueryActiveDesktopPathname (szPath, sizeof(szPath));
00860             int len = strlen (szPath);   
00861             if (len > CCHMAXPATH -1)
00862                break;
00863             szPath[len] = '\\';     
00864             szPath[len + 1] = '\0';
00865 #ifdef DEBUG
00866             if (fSuccess) {
00867                printf ("Got OS2_DesktopDirectory: %s\n", szPath);
00868             } else {
00869                printf ("Failed getting OS2_DesktopDirectory: %s\n", szPath);
00870             }
00871 #endif
00872             break;           
00873         }
00874 
00875 #endif
00876         default:
00877             break;    
00878     }
00879 }
00880 
00881 void
00882 nsSpecialSystemDirectory::Set(SystemDirectories dirToSet, nsFileSpec *dirSpec)
00883 {
00884     SystemDirectoriesKey dirKey(dirToSet);
00885     
00886     PR_ASSERT(NULL != dirSpec);
00887     
00888     if (NULL == systemDirectoriesLocations) {
00889         systemDirectoriesLocations = new nsHashtable(NS_SYSTEMDIR_HASH_NUM);
00890     }
00891     PR_ASSERT(NULL != systemDirectoriesLocations);
00892     
00893     nsFileSpec *newSpec = new nsFileSpec(*dirSpec);
00894     if (NULL != newSpec) {
00895         systemDirectoriesLocations->Put(&dirKey, newSpec);
00896     }
00897     
00898     return;
00899 }