Back to index

lightning-sunbird  0.9+nobinonly
SpecialSystemDirectory.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  *   Fredrik Holmqvist <thesuckiestemail@yahoo.se>
00027  *   Jungshik Shin <jshin@i18nl10n.com>
00028  *
00029  * Alternatively, the contents of this file may be used under the terms of
00030  * either of the GNU General Public License Version 2 or later (the "GPL"),
00031  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00032  * in which case the provisions of the GPL or the LGPL are applicable instead
00033  * of those above. If you wish to allow use of your version of this file only
00034  * under the terms of either the GPL or the LGPL, and not to allow others to
00035  * use your version of this file under the terms of the MPL, indicate your
00036  * decision by deleting the provisions above and replace them with the notice
00037  * and other provisions required by the GPL or the LGPL. If you do not delete
00038  * the provisions above, a recipient may use your version of this file under
00039  * the terms of any one of the MPL, the GPL or the LGPL.
00040  *
00041  * ***** END LICENSE BLOCK ***** */
00042 
00043 #include "SpecialSystemDirectory.h"
00044 #include "nsString.h"
00045 #include "nsDependentString.h"
00046 
00047 #if defined(XP_WIN)
00048 
00049 #include "nsNativeCharsetUtils.h"
00050 #include "nsWinAPIs.h"
00051 #include <windows.h>
00052 #include <shlobj.h>
00053 #include <stdlib.h>
00054 #include <stdio.h>
00055 #include <string.h>
00056 #include <direct.h>
00057 
00058 // These are not defined by VC6. 
00059 #ifndef CSIDL_LOCAL_APPDATA
00060 #define CSIDL_LOCAL_APPDATA             0x001C
00061 #endif
00062 #ifndef CSIDL_PROGRAM_FILES
00063 #define CSIDL_PROGRAM_FILES             0x0026
00064 #endif
00065 
00066 #elif defined(XP_OS2)
00067 
00068 #define MAX_PATH _MAX_PATH
00069 #define INCL_WINWORKPLACE
00070 #define INCL_DOSMISC
00071 #define INCL_DOSMODULEMGR
00072 #define INCL_DOSPROCESS
00073 #define INCL_WINSHELLDATA
00074 #include <os2.h>
00075 #include <stdlib.h>
00076 #include <stdio.h>
00077 #include "prenv.h"
00078 
00079 #elif defined(XP_UNIX)
00080 
00081 #include <unistd.h>
00082 #include <stdlib.h>
00083 #include <sys/param.h>
00084 #include "prenv.h"
00085 
00086 #elif defined(XP_BEOS)
00087 
00088 #include <FindDirectory.h>
00089 #include <fs_info.h>
00090 #include <Path.h>
00091 #include <unistd.h>
00092 #include <stdlib.h>
00093 #include <sys/param.h>
00094 #include <OS.h>
00095 #include <image.h>
00096 #include "prenv.h"
00097 
00098 #endif
00099 
00100 #if defined(VMS)
00101 #include <unixlib.h>
00102 #endif
00103 
00104 #ifndef MAXPATHLEN
00105 #ifdef MAX_PATH
00106 #define MAXPATHLEN MAX_PATH
00107 #elif defined(_MAX_PATH)
00108 #define MAXPATHLEN _MAX_PATH
00109 #elif defined(CCHMAXPATH)
00110 #define MAXPATHLEN CCHMAXPATH
00111 #else
00112 #define MAXPATHLEN 1024
00113 #endif
00114 #endif
00115 
00116 #if defined (XP_WIN)
00117 typedef BOOL (WINAPI * GetSpecialPathProc) (HWND hwndOwner, LPSTR lpszPath,
00118                                             int nFolder, BOOL fCreate);
00119 typedef BOOL (WINAPI * nsGetSpecialFolderPathW) (HWND hwndOwner, 
00120                                                  LPWSTR lpszPath,
00121                                                  int nFolder, BOOL fCreate);
00122 typedef BOOL (WINAPI * nsGetSpecialFolderPathA) (HWND hwndOwner,
00123                                                  LPSTR lpszPath, int nFolder,
00124                                                  BOOL fCreate);
00125 
00126 
00127 static GetSpecialPathProc gGetSpecialPathProc = NULL;
00128 static nsGetSpecialFolderPathA gGetSpecialFolderPathA = NULL;
00129 static nsGetSpecialFolderPathW gGetSpecialFolderPath  = NULL;
00130 
00131 static HINSTANCE gShell32DLLInst = NULL;
00132 
00133 static BOOL WINAPI NS_GetSpecialFolderPath(HWND hwndOwner, LPWSTR aPath,
00134                                            int aFolder, BOOL fCreate);
00135 #endif
00136 NS_COM void StartupSpecialSystemDirectory()
00137 {
00138 #if defined (XP_WIN) && !defined (WINCE)
00139     /* On windows, the old method to get file locations is incredibly slow.
00140        As of this writing, 3 calls to GetWindowsFolder accounts for 3% of mozilla
00141        startup. Replacing these older calls with a single call to SHGetSpecialFolderPath
00142        effectively removes these calls from the performace radar.  We need to 
00143        support the older way of file location lookup on systems that do not have
00144        IE4. 
00145     */ 
00146     gShell32DLLInst = LoadLibrary("Shell32.dll");
00147     if(gShell32DLLInst)
00148     {
00149         if (NS_UseUnicode())
00150         {
00151             gGetSpecialFolderPath = (nsGetSpecialFolderPathW) 
00152                 GetProcAddress(gShell32DLLInst, "SHGetSpecialFolderPathW");
00153         }
00154         else 
00155         {
00156             gGetSpecialFolderPathA = (nsGetSpecialFolderPathA)
00157                 GetProcAddress(gShell32DLLInst, "SHGetSpecialFolderPathA");
00158             // need to check because it's not available on Win95 without IE.
00159             if (gGetSpecialFolderPathA)
00160                 gGetSpecialFolderPath = NS_GetSpecialFolderPath;
00161         }
00162     }
00163 #endif
00164 }
00165 
00166 NS_COM void ShutdownSpecialSystemDirectory()
00167 {
00168 #if defined (XP_WIN)
00169     if (gShell32DLLInst)
00170     {
00171         FreeLibrary(gShell32DLLInst);
00172         gShell32DLLInst = NULL;
00173         gGetSpecialFolderPath = NULL;
00174     }
00175 #endif
00176 }
00177 
00178 #if defined (XP_WIN)
00179 
00180 //----------------------------------------------------------------------------------------
00181 static nsresult GetWindowsFolder(int folder, nsILocalFile** aFile)
00182 //----------------------------------------------------------------------------------------
00183 {
00184     if (gGetSpecialFolderPath) { // With MS IE 4.0 or higher
00185         WCHAR path[MAX_PATH + 2];
00186         HRESULT result = gGetSpecialFolderPath(NULL, path, folder, true);
00187         
00188         if (!SUCCEEDED(result)) 
00189             return NS_ERROR_FAILURE;
00190 
00191         // Append the trailing slash
00192         int len = wcslen(path);
00193         if (len > 1 && path[len - 1] != L'\\') 
00194         {
00195             path[len]   = L'\\';
00196             path[++len] = L'\0';
00197         }
00198 
00199         return NS_NewLocalFile(nsDependentString(path, len), PR_TRUE, aFile);
00200     }
00201 
00202     nsresult rv = NS_ERROR_FAILURE;
00203     LPMALLOC pMalloc = NULL;
00204     LPWSTR pBuffer = NULL;
00205     LPITEMIDLIST pItemIDList = NULL;
00206     int len;
00207  
00208     // Get the shell's allocator. 
00209     if (!SUCCEEDED(SHGetMalloc(&pMalloc))) 
00210         return NS_ERROR_FAILURE;
00211 
00212     // Allocate a buffer
00213     if ((pBuffer = (LPWSTR) pMalloc->Alloc(MAX_PATH + 2)) == NULL)
00214         return NS_ERROR_OUT_OF_MEMORY;
00215  
00216     // Get the PIDL for the folder. 
00217     if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, folder, &pItemIDList)))
00218         goto Clean;
00219  
00220     if (!SUCCEEDED(nsWinAPIs::mSHGetPathFromIDList(pItemIDList, pBuffer)))
00221         goto Clean;
00222 
00223     // Append the trailing slash
00224     len = wcslen(pBuffer);
00225     pBuffer[len] = L'\\';
00226     pBuffer[++len] = L'\0';
00227 
00228     // Assign the directory
00229     rv = NS_NewLocalFile(nsDependentString(pBuffer, len), 
00230                          PR_TRUE, 
00231                          aFile);
00232 
00233 Clean:
00234     // Clean up. 
00235     if (pItemIDList)
00236         pMalloc->Free(pItemIDList); 
00237     if (pBuffer)
00238         pMalloc->Free(pBuffer); 
00239 
00240        pMalloc->Release();
00241     
00242     return rv;
00243 } 
00244 
00245 // Assume that this function is always invoked with aPath with the capacity
00246 // no smaller than MAX_PATH. It's possible because it's only referred to in 
00247 // this file and we have made sure that they're indeed.
00248 
00249 static BOOL WINAPI NS_GetSpecialFolderPath(HWND hwndOwner,
00250                                            LPWSTR aPath, 
00251                                            int aFolder, BOOL fCreate)
00252 {
00253     char path[MAX_PATH];
00254     if (gGetSpecialFolderPathA(hwndOwner, path, aFolder, fCreate))
00255     {
00256         if (NS_ConvertAtoW(path, 0, aPath) > MAX_PATH)
00257         {
00258             SetLastError(ERROR_INSUFFICIENT_BUFFER);
00259             return FALSE;
00260         }
00261         return NS_ConvertAtoW(path, MAX_PATH, aPath) ? TRUE : FALSE;
00262     }
00263     return FALSE;
00264 }
00265 
00266 #endif // XP_WIN
00267 
00268 #if defined (XP_BEOS)                                            
00269 static nsresult
00270 GetBeOSFolder( directory_which which, dev_t volume, nsILocalFile** aFile)
00271 {
00272     char path[MAXPATHLEN];
00273     if (volume < 0)
00274         return NS_ERROR_FAILURE;
00275         
00276     status_t result = find_directory(which, volume, false, path, MAXPATHLEN - 2);
00277     if (result != B_OK)
00278         return NS_ERROR_FAILURE;
00279         
00280     int len = strlen(path);
00281     if (len == 0)
00282         return NS_ERROR_FAILURE;
00283 
00284     if (path[len-1] != '/') 
00285     {
00286         path[len]   = '/';
00287         path[len+1] = '\0';            
00288     }
00289     return NS_NewNativeLocalFile(nsDependentCString(path), PR_TRUE, aFile);
00290 }
00291 #endif // XP_BEOS
00292 
00293 #if defined(XP_UNIX)
00294 static nsresult
00295 GetUnixHomeDir(nsILocalFile** aFile)
00296 {
00297 #ifdef VMS
00298     char *pHome;
00299     pHome = getenv("HOME");
00300     if (*pHome == '/') {
00301         return NS_NewNativeLocalFile(nsDependentCString(pHome), 
00302                                      PR_TRUE, 
00303                                      aFile);
00304     } else {
00305         return NS_NewNativeLocalFile(nsDependentCString(decc$translate_vms(pHome)), 
00306                                      PR_TRUE, 
00307                                      aFile);
00308     }
00309 #else
00310     return NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), 
00311                                  PR_TRUE, aFile);
00312 #endif
00313 }
00314 #endif
00315 
00316 nsresult
00317 GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
00318                           nsILocalFile** aFile)
00319 {
00320 #if defined(XP_WIN)
00321     WCHAR path[MAX_PATH];
00322 #else
00323     char path[MAXPATHLEN];
00324 #endif
00325 
00326     switch (aSystemSystemDirectory)
00327     {
00328         case OS_CurrentWorkingDirectory:
00329 #if defined(XP_WIN)
00330             if (!nsWinAPIs::mGetCwd(path, MAX_PATH))
00331                 return NS_ERROR_FAILURE;
00332             return NS_NewLocalFile(nsDependentString(path), 
00333                                    PR_TRUE, 
00334                                    aFile);
00335 #elif defined(XP_OS2)
00336             if (DosQueryPathInfo( ".", FIL_QUERYFULLNAME, path, MAXPATHLEN))
00337                 return NS_ERROR_FAILURE;
00338 #else
00339             if(!getcwd(path, MAXPATHLEN))
00340                 return NS_ERROR_FAILURE;
00341 #endif
00342 
00343 #if !defined(XP_WIN)
00344             return NS_NewNativeLocalFile(nsDependentCString(path), 
00345                                          PR_TRUE, 
00346                                          aFile);
00347 #endif
00348 
00349         case OS_DriveDirectory:
00350 #if defined (XP_WIN)
00351         {
00352             PRInt32 len = nsWinAPIs::mGetWindowsDirectory(path, MAX_PATH);
00353             if (len == 0)
00354                 break;
00355             if (path[1] == PRUnichar(':') && path[2] == PRUnichar('\\'))
00356                 path[3] = 0;
00357 
00358             return NS_NewLocalFile(nsDependentString(path),
00359                                    PR_TRUE, 
00360                                    aFile);
00361         }
00362 #elif defined(XP_OS2)
00363         {
00364             ULONG ulBootDrive = 0;
00365             char  buffer[] = " :\\OS2\\";
00366             DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
00367                              &ulBootDrive, sizeof ulBootDrive);
00368             buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
00369 
00370             return NS_NewNativeLocalFile(nsDependentCString(buffer),
00371                                          PR_TRUE, 
00372                                          aFile);
00373         }
00374 #else
00375         return NS_NewNativeLocalFile(nsDependentCString("/"), 
00376                                      PR_TRUE, 
00377                                      aFile);
00378 
00379 #endif
00380             
00381         case OS_TemporaryDirectory:
00382 #if defined (XP_WIN) && !defined (WINCE)
00383         {
00384             DWORD len = nsWinAPIs::mGetTempPath(MAX_PATH, path);
00385             if (len == 0)
00386                 break;
00387             return NS_NewLocalFile(nsDependentString(path, len), 
00388                                    PR_TRUE, 
00389                                    aFile);
00390         }
00391 #elif defined (WINCE)
00392         {
00393             return NS_NewNativeLocalFile(NS_LITERAL_CSTRING("\\Temp"), 
00394                                          PR_TRUE, 
00395                                          aFile);
00396         }
00397 #elif defined(XP_OS2)
00398         {
00399             char buffer[CCHMAXPATH] = "";
00400             char *c = getenv( "TMP");
00401             if( c) strcpy( buffer, c);
00402             else
00403             {
00404                 c = getenv( "TEMP");
00405                 if( c) strcpy( buffer, c);
00406             }
00407 
00408             nsCString tString = nsDependentCString(buffer);
00409             if (tString.Find("/", PR_FALSE, 0, -1)) {
00410                 tString.ReplaceChar('/','\\');
00411             }
00412             return NS_NewNativeLocalFile(tString, PR_TRUE, aFile);
00413         } 
00414 #elif defined(XP_MACOSX)
00415         {
00416             return GetOSXFolderType(kUserDomain, kTemporaryFolderType, aFile);
00417         }
00418 
00419 #elif defined(XP_UNIX) || defined(XP_BEOS)
00420         {
00421             static const char *tPath = nsnull;
00422             if (!tPath) {
00423                 tPath = PR_GetEnv("TMPDIR");
00424                 if (!tPath || !*tPath) {
00425                     tPath = PR_GetEnv("TMP");
00426                     if (!tPath || !*tPath) {
00427                         tPath = PR_GetEnv("TEMP");
00428                         if (!tPath || !*tPath) {
00429                             tPath = "/tmp/";
00430                         }
00431                     }
00432                 }
00433             }
00434             return NS_NewNativeLocalFile(nsDependentCString(tPath), 
00435                                          PR_TRUE, 
00436                                          aFile);
00437         }
00438 #else
00439         break;
00440 #endif            
00441 #if defined (XP_WIN)
00442         case Win_SystemDirectory:
00443         {    
00444             PRInt32 len = nsWinAPIs::mGetSystemDirectory(path, MAX_PATH);
00445         
00446             // Need enough space to add the trailing backslash
00447             if (!len || len > MAX_PATH - 2)
00448                 break;
00449             path[len]   = L'\\';
00450             path[++len] = L'\0';
00451 
00452             return NS_NewLocalFile(nsDependentString(path, len), 
00453                                    PR_TRUE, 
00454                                    aFile);
00455         }
00456 
00457         case Win_WindowsDirectory:
00458         {    
00459             PRInt32 len = nsWinAPIs::mGetWindowsDirectory(path, MAX_PATH);
00460             
00461             // Need enough space to add the trailing backslash
00462             if (!len || len > MAX_PATH - 2)
00463                 break;
00464             
00465             path[len]   = L'\\';
00466             path[++len] = L'\0';
00467 
00468             return NS_NewLocalFile(nsDependentString(path, len), 
00469                                    PR_TRUE, 
00470                                    aFile);
00471         }
00472 
00473         case Win_ProgramFiles:
00474         {
00475             return GetWindowsFolder(CSIDL_PROGRAM_FILES, aFile);
00476         }
00477 
00478         case Win_HomeDirectory:
00479         {    
00480             PRInt32 len;
00481             if ((len = 
00482                  nsWinAPIs::mGetEnvironmentVariable(L"HOME", path, 
00483                                                     MAX_PATH)) > 0)
00484             {
00485                 // Need enough space to add the trailing backslash
00486                 if (len > MAX_PATH - 2)
00487                     break;
00488                
00489                 path[len]   = L'\\';
00490                 path[++len] = L'\0';
00491 
00492                 return NS_NewLocalFile(nsDependentString(path, len), 
00493                                        PR_TRUE, 
00494                                        aFile);
00495             }
00496 
00497             len = nsWinAPIs::mGetEnvironmentVariable(L"HOMEDRIVE", 
00498                                                      path, MAX_PATH);
00499             if (0 < len && len < MAX_PATH)
00500             {
00501                 WCHAR temp[MAX_PATH];
00502                 DWORD len2 = nsWinAPIs::mGetEnvironmentVariable(L"HOMEPATH", 
00503                                                                 temp,
00504                                                                 MAX_PATH);
00505                 if (0 < len2 && len + len2 < MAX_PATH)
00506                     wcsncat(path, temp, len2);
00507         
00508                 len = wcslen(path);
00509 
00510                 // Need enough space to add the trailing backslash
00511                 if (len > MAX_PATH - 2)
00512                     break;
00513             
00514                 path[len]   = L'\\';
00515                 path[++len] = L'\0';
00516                 
00517                 return NS_NewLocalFile(nsDependentString(path, len), 
00518                                        PR_TRUE, 
00519                                        aFile);
00520             }
00521         }
00522         case Win_Desktop:
00523         {
00524             return GetWindowsFolder(CSIDL_DESKTOP, aFile);
00525         }
00526         case Win_Programs:
00527         {
00528             return GetWindowsFolder(CSIDL_PROGRAMS, aFile);
00529         }
00530         case Win_Controls:
00531         {
00532             return GetWindowsFolder(CSIDL_CONTROLS, aFile);
00533         }
00534         case Win_Printers:
00535         {
00536             return GetWindowsFolder(CSIDL_PRINTERS, aFile);
00537         }
00538         case Win_Personal:
00539         {
00540             return GetWindowsFolder(CSIDL_PERSONAL, aFile);
00541         }
00542         case Win_Favorites:
00543         {
00544             return GetWindowsFolder(CSIDL_FAVORITES, aFile);
00545         }
00546         case Win_Startup:
00547         {
00548             return GetWindowsFolder(CSIDL_STARTUP, aFile);
00549         }
00550         case Win_Recent:
00551         {
00552             return GetWindowsFolder(CSIDL_RECENT, aFile);
00553         }
00554         case Win_Sendto:
00555         {
00556             return GetWindowsFolder(CSIDL_SENDTO, aFile);
00557         }
00558         case Win_Bitbucket:
00559         {
00560             return GetWindowsFolder(CSIDL_BITBUCKET, aFile);
00561         }
00562         case Win_Startmenu:
00563         {
00564             return GetWindowsFolder(CSIDL_STARTMENU, aFile);
00565         }
00566         case Win_Desktopdirectory:
00567         {
00568             return GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, aFile);
00569         }
00570         case Win_Drives:
00571         {
00572             return GetWindowsFolder(CSIDL_DRIVES, aFile);
00573         }
00574         case Win_Network:
00575         {
00576             return GetWindowsFolder(CSIDL_NETWORK, aFile);
00577         }
00578         case Win_Nethood:
00579         {
00580             return GetWindowsFolder(CSIDL_NETHOOD, aFile);
00581         }
00582         case Win_Fonts:
00583         {
00584             return GetWindowsFolder(CSIDL_FONTS, aFile);
00585         }
00586         case Win_Templates:
00587         {
00588             return GetWindowsFolder(CSIDL_TEMPLATES, aFile);
00589         }
00590 #ifndef WINCE
00591         case Win_Common_Startmenu:
00592         {
00593             return GetWindowsFolder(CSIDL_COMMON_STARTMENU, aFile);
00594         }
00595         case Win_Common_Programs:
00596         {
00597             return GetWindowsFolder(CSIDL_COMMON_PROGRAMS, aFile);
00598         }
00599         case Win_Common_Startup:
00600         {
00601             return GetWindowsFolder(CSIDL_COMMON_STARTUP, aFile);
00602         }
00603         case Win_Common_Desktopdirectory:
00604         {
00605             return GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, aFile);
00606         }
00607         case Win_Printhood:
00608         {
00609             return GetWindowsFolder(CSIDL_PRINTHOOD, aFile);
00610         }
00611         case Win_Cookies:
00612         {
00613             return GetWindowsFolder(CSIDL_COOKIES, aFile);
00614         }
00615 #endif
00616         case Win_Appdata:
00617         {
00618             return GetWindowsFolder(CSIDL_APPDATA, aFile);
00619         }
00620 
00621         case Win_LocalAppdata:
00622         {
00623             return GetWindowsFolder(CSIDL_LOCAL_APPDATA, aFile);
00624         }
00625 #endif  // XP_WIN
00626 
00627 #if defined(XP_UNIX)
00628         case Unix_LocalDirectory:
00629             return NS_NewNativeLocalFile(nsDependentCString("/usr/local/netscape/"), 
00630                                          PR_TRUE, 
00631                                          aFile);
00632         case Unix_LibDirectory:
00633             return NS_NewNativeLocalFile(nsDependentCString("/usr/local/lib/netscape/"), 
00634                                          PR_TRUE, 
00635                                          aFile);
00636 
00637         case Unix_HomeDirectory:
00638             return GetUnixHomeDir(aFile);
00639 
00640         case Unix_DesktopDirectory:
00641         {
00642             nsCOMPtr<nsILocalFile> home;
00643             nsresult rv = GetUnixHomeDir(getter_AddRefs(home));
00644             if (NS_FAILED(rv))
00645                 return rv;
00646             rv = home->AppendNative(NS_LITERAL_CSTRING("Desktop"));
00647             if (NS_FAILED(rv))
00648                 return rv;
00649             PRBool exists;
00650             rv = home->Exists(&exists);
00651             if (NS_FAILED(rv))
00652                 return rv;
00653             if (!exists)
00654                 return GetUnixHomeDir(aFile);
00655               
00656             NS_ADDREF(*aFile = home);
00657             return NS_OK;
00658         }
00659 #endif
00660 
00661 #ifdef XP_BEOS
00662         case BeOS_SettingsDirectory:
00663         {
00664             return GetBeOSFolder(B_USER_SETTINGS_DIRECTORY,0, aFile);
00665         }
00666 
00667         case BeOS_HomeDirectory:
00668         {
00669             return GetBeOSFolder(B_USER_DIRECTORY,0, aFile);
00670         }
00671 
00672         case BeOS_DesktopDirectory:
00673         {
00674             /* Get the user's desktop folder, which in the future may differ from the boot desktop */
00675             char path[MAXPATHLEN];
00676             if (find_directory(B_USER_DIRECTORY, 0, false, path, MAXPATHLEN) != B_OK )
00677                 break;
00678             return GetBeOSFolder(B_DESKTOP_DIRECTORY, dev_for_path(path), aFile);
00679         }
00680 
00681         case BeOS_SystemDirectory:
00682         {
00683             return GetBeOSFolder(B_BEOS_DIRECTORY,0, aFile);
00684         }
00685 #endif        
00686 #ifdef XP_OS2
00687         case OS2_SystemDirectory:
00688         {
00689             ULONG ulBootDrive = 0;
00690             char  buffer[] = " :\\OS2\\System\\";
00691             DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
00692                              &ulBootDrive, sizeof ulBootDrive);
00693             buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
00694 
00695             return NS_NewNativeLocalFile(nsDependentCString(buffer), 
00696                                          PR_TRUE, 
00697                                          aFile);
00698         }
00699 
00700      case OS2_OS2Directory:
00701         {
00702             ULONG ulBootDrive = 0;
00703             char  buffer[] = " :\\OS2\\";
00704             DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
00705                              &ulBootDrive, sizeof ulBootDrive);
00706             buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
00707 
00708             return NS_NewNativeLocalFile(nsDependentCString(buffer), 
00709                                          PR_TRUE, 
00710                                          aFile);
00711         }
00712 
00713      case OS2_HomeDirectory:
00714         {
00715             nsresult rv;
00716             char *tPath = PR_GetEnv("MOZILLA_HOME");
00717             char buffer[CCHMAXPATH];
00718             /* If MOZILLA_HOME is not set, use GetCurrentProcessDirectory */
00719             /* To ensure we get a long filename system */
00720             if (!tPath || !*tPath) {
00721                 PPIB ppib;
00722                 PTIB ptib;
00723                 DosGetInfoBlocks( &ptib, &ppib);
00724                 DosQueryModuleName( ppib->pib_hmte, CCHMAXPATH, buffer);
00725                 *strrchr( buffer, '\\') = '\0'; // XXX DBCS misery
00726                 tPath = buffer;
00727             }
00728             rv = NS_NewNativeLocalFile(nsDependentCString(tPath),
00729                                        PR_TRUE, 
00730                                        aFile);
00731 
00732             PrfWriteProfileString(HINI_USERPROFILE, "Mozilla", "Home", tPath);
00733             return rv;
00734         }
00735 
00736         case OS2_DesktopDirectory:
00737         {
00738             char szPath[CCHMAXPATH + 1];        
00739             BOOL fSuccess;
00740             fSuccess = WinQueryActiveDesktopPathname (szPath, sizeof(szPath));
00741             if (!fSuccess) {
00742                 // this could happen if we are running without the WPS, return
00743                 // the Home directory instead
00744                 return GetSpecialSystemDirectory(OS2_HomeDirectory, aFile);
00745             }
00746             int len = strlen (szPath);   
00747             if (len > CCHMAXPATH -1)
00748                 break;
00749             szPath[len] = '\\';     
00750             szPath[len + 1] = '\0';
00751 
00752             return NS_NewNativeLocalFile(nsDependentCString(szPath),
00753                                          PR_TRUE, 
00754                                          aFile);
00755         }
00756 #endif
00757         default:
00758             break;
00759     }
00760     return NS_ERROR_NOT_AVAILABLE;
00761 }
00762 
00763 #if defined (XP_MACOSX)
00764 nsresult
00765 GetOSXFolderType(short aDomain, OSType aFolderType, nsILocalFile **localFile)
00766 {
00767     OSErr err;
00768     FSRef fsRef;
00769     nsresult rv = NS_ERROR_FAILURE;
00770 
00771     err = ::FSFindFolder(aDomain, aFolderType, kCreateFolder, &fsRef);
00772     if (err == noErr)
00773     {
00774         NS_NewLocalFile(EmptyString(), PR_TRUE, localFile);
00775         nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(*localFile));
00776         if (localMacFile)
00777             rv = localMacFile->InitWithFSRef(&fsRef);
00778     }
00779     return rv;
00780 }                                                                      
00781 #endif
00782