source: trunk/third/firefox/xpcom/obsolete/nsSpecialSystemDirectory.cpp @ 21695

Revision 21695, 33.0 KB checked in by rbasch, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21694, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * The contents of this file are subject to the Netscape Public
4 * License Version 1.1 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of
6 * the License at http://www.mozilla.org/NPL/
7 *
8 * Software distributed under the License is distributed on an "AS
9 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10 * implied. See the License for the specific language governing
11 * rights and limitations under the License.
12 *
13 * The Original Code is Mozilla Communicator client code,
14 * released March 31, 1998.
15 *
16 * The Initial Developer of the Original Code is Netscape Communications
17 * Corporation.  Portions created by Netscape are
18 * Copyright (C) 1998 Netscape Communications Corporation. All
19 * Rights Reserved.
20 *
21 * Contributor(s):
22 *     Doug Turner <dougt@netscape.com>
23 *     IBM Corp.
24 */
25
26#include "nsSpecialSystemDirectory.h"
27#include "nsDebug.h"
28
29#ifdef XP_MAC
30#include <Folders.h>
31#include <Files.h>
32#include <Memory.h>
33#include <Processes.h>
34#include <Gestalt.h>
35#include "nsIInternetConfigService.h"
36#ifdef DEBUG
37#include "prenv.h" // For PR_Getenv
38#endif
39#elif defined(XP_WIN)
40#include <windows.h>
41#include <shlobj.h>
42#include <stdlib.h>
43#include <stdio.h>
44#include <ctype.h>
45#include "nsNativeCharsetUtils.h"
46#elif defined(XP_OS2)
47#define MAX_PATH _MAX_PATH
48#define INCL_WINWORKPLACE
49#include <os2.h>
50#include <stdlib.h>
51#include <stdio.h>
52#include "prenv.h"
53#elif defined(XP_UNIX)
54#include <unistd.h>
55#include <stdlib.h>
56#include <sys/param.h>
57#include "prenv.h"
58#elif defined(XP_BEOS)
59#include <FindDirectory.h>
60#include <Path.h>
61#include <unistd.h>
62#include <stdlib.h>
63#include <sys/param.h>
64#include <OS.h>
65#include <image.h>
66#include "prenv.h"
67#endif
68
69#if defined(VMS)
70#include <unixlib.h>
71#endif
72
73#include "plstr.h"
74
75#include "nsHashtable.h"
76#include "prlog.h"
77
78#if defined (XP_MAC) && UNIVERSAL_INTERFACES_VERSION < 0x0340
79    enum {
80      kSystemDomain                 = -32766, /* Read-only system hierarchy.*/
81      kLocalDomain                  = -32765, /* All users of a single machine have access to these resources.*/
82      kNetworkDomain                = -32764, /* All users configured to use a common network server has access to these resources.*/
83      kUserDomain                   = -32763, /* Read/write. Resources that are private to the user.*/
84      kClassicDomain                = -32762, /* Domain referring to the currently configured Classic System Folder*/
85
86      kDomainLibraryFolderType      = FOUR_CHAR_CODE('dlib')
87    };
88#endif
89
90
91class SystemDirectoriesKey : public nsHashKey {
92public:
93
94    SystemDirectoriesKey(nsSpecialSystemDirectory::SystemDirectories newKey) : sdKey(newKey) {}
95
96    virtual PRUint32 HashCode(void) const
97    {
98        return PRUint32(sdKey);
99    }
100   
101    virtual PRBool Equals(const nsHashKey *aKey) const
102    {
103        nsSpecialSystemDirectory::SystemDirectories other =
104            ((SystemDirectoriesKey*)aKey)->sdKey;
105        return other == sdKey;
106    }
107   
108    virtual nsHashKey *Clone(void) const
109    {
110        return new SystemDirectoriesKey(sdKey);
111    }
112
113private:
114    nsSpecialSystemDirectory::SystemDirectories sdKey; // sd for SystemDirectories
115};
116
117PR_STATIC_CALLBACK(PRBool) DeleteSystemDirKeys(nsHashKey *aKey, void *aData, void* closure)
118{
119    delete ((nsFileSpec *)aData);
120    return PR_TRUE;
121}
122
123#define NS_SYSTEMDIR_HASH_NUM (10)
124static nsHashtable *systemDirectoriesLocations = NULL;
125#if defined (XP_WIN)
126typedef BOOL (WINAPI * GetSpecialPathProc) (HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
127GetSpecialPathProc gGetSpecialPathProc = NULL;
128static HINSTANCE gShell32DLLInst = NULL;
129#endif
130NS_COM_OBSOLETE void StartupSpecialSystemDirectory()
131{
132#if defined (XP_WIN)
133    /* On windows, the old method to get file locations is incredibly slow.
134       As of this writing, 3 calls to GetWindowsFolder accounts for 3% of mozilla
135       startup. Replacing these older calls with a single call to SHGetSpecialFolderPath
136       effectively removes these calls from the performace radar.  We need to
137       support the older way of file location lookup on systems that do not have
138       IE4. (Note: gets the ansi version: SHGetSpecialFolderPathA).
139    */
140    gShell32DLLInst = LoadLibrary("Shell32.dll");
141    if(gShell32DLLInst)
142    {
143        gGetSpecialPathProc  = (GetSpecialPathProc) GetProcAddress(gShell32DLLInst,
144                                                                   "SHGetSpecialFolderPathA");
145    }
146#endif
147}
148
149NS_COM_OBSOLETE void ShutdownSpecialSystemDirectory()
150{
151    if (systemDirectoriesLocations)
152    {
153        systemDirectoriesLocations->Reset(DeleteSystemDirKeys);
154        delete systemDirectoriesLocations;
155    }
156#if defined (XP_WIN)
157   if (gShell32DLLInst)
158   {
159       FreeLibrary(gShell32DLLInst);
160       gShell32DLLInst = NULL;
161       gGetSpecialPathProc = NULL;
162   }
163#endif
164}
165
166#if defined (XP_WIN)
167
168//----------------------------------------------------------------------------------------
169static char* MakeUpperCase(char* aPath)
170//----------------------------------------------------------------------------------------
171{
172  // windows does not care about case.  push to uppercase:
173  nsAutoString widePath;
174
175  if (NS_FAILED(NS_CopyNativeToUnicode(nsDependentCString(aPath), widePath))) {
176    NS_ASSERTION(0, "failed to convert a path to Unicode");
177    return aPath;
178  }
179
180  nsString::iterator start, end;
181  widePath.BeginWriting(start);
182  widePath.EndWriting(end);
183
184  while (start != end) {
185    *start = towupper(*start);
186    ++start;
187  }
188
189  nsCAutoString newCPath;
190  NS_CopyUnicodeToNative(widePath, newCPath);
191  // strncpy(aPath, newCPath.get(), strlen(aPath) + 1);
192  strcpy(aPath, newCPath.get());
193
194  return aPath;
195}
196
197//----------------------------------------------------------------------------------------
198static void GetWindowsFolder(int folder, nsFileSpec& outDirectory)
199//----------------------------------------------------------------------------------------
200{
201
202    if (gGetSpecialPathProc) {
203        TCHAR path[MAX_PATH];
204        HRESULT result = gGetSpecialPathProc(NULL, path, folder, true);
205       
206        if (!SUCCEEDED(result))
207            return;
208
209        // Append the trailing slash
210        int len = PL_strlen(path);
211        if (len>1 && path[len-1] != '\\')
212        {
213            path[len]   = '\\';
214            path[len + 1] = '\0';
215        }
216        outDirectory = path;
217        return;
218    }
219
220    LPMALLOC pMalloc = NULL;
221    LPSTR pBuffer = NULL;
222    LPITEMIDLIST pItemIDList = NULL;
223    int len;
224 
225    // Get the shell's allocator.
226    if (!SUCCEEDED(SHGetMalloc(&pMalloc)))
227        return;
228
229    // Allocate a buffer
230    if ((pBuffer = (LPSTR) pMalloc->Alloc(MAX_PATH + 2)) == NULL)
231        return;
232 
233    // Get the PIDL for the folder.
234    if (!SUCCEEDED(SHGetSpecialFolderLocation(
235            NULL, folder, &pItemIDList)))
236        goto Clean;
237 
238    if (!SUCCEEDED(SHGetPathFromIDList(pItemIDList, pBuffer)))
239        goto Clean;
240
241    // Append the trailing slash
242    len = PL_strlen(pBuffer);
243    pBuffer[len]   = '\\';
244    pBuffer[len + 1] = '\0';
245
246    // Assign the directory
247    outDirectory = pBuffer;
248
249Clean:
250    // Clean up.
251    if (pItemIDList)
252        pMalloc->Free(pItemIDList);
253    if (pBuffer)
254        pMalloc->Free(pBuffer);
255
256        pMalloc->Release();
257} // GetWindowsFolder
258#endif // XP_WIN
259
260//----------------------------------------------------------------------------------------
261static void GetCurrentWorkingDirectory(nsFileSpec& aFileSpec)
262//----------------------------------------------------------------------------------------
263{
264    aFileSpec = ".";
265    return;
266} // GetCurrentWorkingDirectory
267
268//----------------------------------------------------------------------------------------
269static void GetCurrentProcessDirectory(nsFileSpec& aFileSpec)
270//----------------------------------------------------------------------------------------
271{
272#if defined (XP_WIN)
273    char buf[MAX_PATH];
274    if ( ::GetModuleFileName(0, buf, sizeof(buf)) ) {
275        // chop of the executable name by finding the rightmost backslash
276        char* lastSlash = PL_strrchr(buf, '\\');
277        if (lastSlash)
278            *(lastSlash + 1) = '\0';
279
280        aFileSpec = buf;
281        return;
282    }
283
284#elif defined(XP_OS2)
285    PPIB ppib;
286    PTIB ptib;
287    char buffer[CCHMAXPATH];
288    DosGetInfoBlocks( &ptib, &ppib);
289    DosQueryModuleName( ppib->pib_hmte, CCHMAXPATH, buffer);
290    *strrchr( buffer, '\\') = '\0'; // XXX DBCS misery
291    aFileSpec = buffer;
292    return;
293
294
295#elif defined(XP_MAC)
296    // get info for the the current process to determine the directory
297    // its located in
298    OSErr err;
299        ProcessSerialNumber psn = {kNoProcess, kCurrentProcess};
300    ProcessInfoRec pInfo;
301    FSSpec         tempSpec;
302
303    // initialize ProcessInfoRec before calling
304    // GetProcessInformation() or die horribly.
305    pInfo.processName = nil;
306    pInfo.processAppSpec = &tempSpec;
307    pInfo.processInfoLength = sizeof(ProcessInfoRec);
308
309    if (!(err = GetProcessInformation(&psn, &pInfo)))
310    {
311        FSSpec appFSSpec = *(pInfo.processAppSpec);
312        long theDirID = appFSSpec.parID;
313
314        Str255 name;
315        CInfoPBRec catInfo;
316        catInfo.dirInfo.ioCompletion = NULL;
317        catInfo.dirInfo.ioNamePtr = (StringPtr)&name;
318        catInfo.dirInfo.ioVRefNum = appFSSpec.vRefNum;
319        catInfo.dirInfo.ioDrDirID = theDirID;
320        catInfo.dirInfo.ioFDirIndex = -1; // -1 = query dir in ioDrDirID
321
322        if (!(err = PBGetCatInfoSync(&catInfo)))
323        {
324            aFileSpec = nsFileSpec(appFSSpec.vRefNum,
325                                   catInfo.dirInfo.ioDrParID,
326                                   name,
327                                   PR_TRUE);
328            return;
329        }
330    }
331#if defined(DEBUG)
332    else
333    {
334        // In the absence of a good way to get the executable directory let
335        // us try this for unix:
336        //      - if MOZILLA_FIVE_HOME is defined, that is it
337        char *moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
338        if (moz5)
339        {
340            printf( "nsSpecialSystemDirectory::MOZILLA_FIVE_HOME is set to %s\n", moz5 );
341            aFileSpec = moz5;
342            return;
343        }
344        else
345        {
346            static PRBool firstWarning = PR_TRUE;
347
348            if(firstWarning) {
349                // Warn that MOZILLA_FIVE_HOME not set, once.
350                printf("***Warning: MOZILLA_FIVE_HOME not set.\n");
351                firstWarning = PR_FALSE;
352            }
353        }
354    }
355#endif /* DEBUG */
356
357#elif defined(XP_UNIX)
358
359    // In the absence of a good way to get the executable directory let
360    // us try this for unix:
361    //  - if MOZILLA_FIVE_HOME is defined, that is it
362    //  - else give the current directory
363    char buf[MAXPATHLEN];
364    char *moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
365    if (moz5)
366    {
367        aFileSpec = moz5;
368        return;
369    }
370    else
371    {
372#if defined(DEBUG)
373        static PRBool firstWarning = PR_TRUE;
374
375        if(firstWarning) {
376            // Warn that MOZILLA_FIVE_HOME not set, once.
377            printf("Warning: MOZILLA_FIVE_HOME not set.\n");
378            firstWarning = PR_FALSE;
379        }
380#endif /* DEBUG */
381
382        // Fall back to current directory.
383        if (getcwd(buf, sizeof(buf)))
384        {
385            aFileSpec = buf;
386            return;
387        }
388    }
389
390#elif defined(XP_BEOS)
391
392    char *moz5 = getenv("MOZILLA_FIVE_HOME");
393    if (moz5)
394    {
395        aFileSpec = moz5;
396        return;
397    }
398    else
399    {
400      static char buf[MAXPATHLEN];
401      int32 cookie = 0;
402      image_info info;
403      char *p;
404      *buf = 0;
405      if(get_next_image_info(0, &cookie, &info) == B_OK)
406      {
407        strcpy(buf, info.name);
408        if((p = strrchr(buf, '/')) != 0)
409        {
410          *p = 0;
411          aFileSpec = buf;
412          return;
413        }
414      }
415    }
416
417#endif
418
419    NS_ERROR("unable to get current process directory");
420} // GetCurrentProcessDirectory()
421
422//nsSpecialSystemDirectory::nsSpecialSystemDirectory()
423//:    nsFileSpec(nsnull)
424//{
425//}
426
427//----------------------------------------------------------------------------------------
428nsSpecialSystemDirectory::nsSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory)
429//----------------------------------------------------------------------------------------
430:    nsFileSpec(nsnull)
431{
432    *this = aSystemSystemDirectory;
433}
434
435//----------------------------------------------------------------------------------------
436nsSpecialSystemDirectory::~nsSpecialSystemDirectory()
437//----------------------------------------------------------------------------------------
438{
439}
440
441//----------------------------------------------------------------------------------------
442void nsSpecialSystemDirectory::operator = (SystemDirectories aSystemSystemDirectory)
443//----------------------------------------------------------------------------------------
444{
445    SystemDirectoriesKey dirKey(aSystemSystemDirectory);
446    SystemDirectoriesKey mozBinDirKey(Moz_BinDirectory);
447
448    // This flag is used to tell whether or not we need to append something
449    // onto the *this.  Search for needToAppend to how it's used.
450    // IT's VERY IMPORTANT that needToAppend is initialized to PR_TRUE.
451    PRBool needToAppend = PR_TRUE;
452
453#ifdef XP_MAC
454    OSErr err;
455    short vRefNum;
456    long dirID;
457#endif
458
459    *this = (const char*)nsnull;
460    switch (aSystemSystemDirectory)
461    {
462       
463        case OS_DriveDirectory:
464#if defined (XP_WIN)
465        {
466            char path[_MAX_PATH];
467            PRInt32 len = GetWindowsDirectory( path, _MAX_PATH );
468            if (len)
469            {
470                if ( path[1] == ':' && path[2] == '\\' )
471                    path[3] = 0;
472            }
473            *this = MakeUpperCase(path);
474        }
475#elif defined(XP_OS2)
476        {
477            // printf( "*** Warning warning OS_DriveDirectory called for");
478           
479            ULONG ulBootDrive = 0;
480            char  buffer[] = " :\\OS2\\";
481            DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
482                             &ulBootDrive, sizeof ulBootDrive);
483            buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
484            *this = buffer;
485#ifdef DEBUG
486            printf( "Got OS_DriveDirectory: %s\n", buffer);
487#endif
488        }
489#elif defined(XP_MAC)
490        {
491            *this = kVolumeRootFolderType;
492        }
493#else
494        *this = "/";
495#endif
496        break;
497
498           
499        case OS_TemporaryDirectory:
500#if defined (XP_WIN)
501        {
502            char path[_MAX_PATH];
503            DWORD len = GetTempPath(_MAX_PATH, path);
504            *this = MakeUpperCase(path);
505        }
506#elif defined(XP_OS2)
507          {
508             char buffer[CCHMAXPATH] = "";
509             char *c = getenv( "TMP");
510             if( c) strcpy( buffer, c);
511             else
512             {
513                c = getenv( "TEMP");
514                if( c) strcpy( buffer, c);
515             }
516             if( c) *this = buffer;
517             // use exe's directory if not set
518             else GetCurrentProcessDirectory(*this);
519          }
520#elif defined(XP_MAC)
521            *this = kTemporaryFolderType;
522       
523#elif defined(XP_UNIX) || defined(XP_BEOS)
524                {
525                        static const char *tPath = nsnull;
526                        if (!tPath) {
527                                tPath = PR_GetEnv("TMPDIR");
528                                if (!tPath || !*tPath) {
529                                        tPath = PR_GetEnv("TMP");
530                                        if (!tPath || !*tPath) {
531                                                tPath = PR_GetEnv("TEMP");
532                                                if (!tPath || !*tPath) {
533                                                        tPath = "/tmp/";
534                                                }
535                                        }
536                                }
537                        }
538                       
539                        *this = tPath;
540                }
541#endif
542        break;
543
544        case OS_CurrentProcessDirectory:
545            GetCurrentProcessDirectory(*this);
546            break;
547
548        case OS_CurrentWorkingDirectory:
549            GetCurrentWorkingDirectory(*this);
550            break;
551
552        case XPCOM_CurrentProcessComponentRegistry:
553            {
554                nsFileSpec *dirSpec = NULL;
555
556                // if someone has called nsSpecialSystemDirectory::Set()
557                if (systemDirectoriesLocations) {
558                    // look for the value for the argument key
559                    if (!(dirSpec = (nsFileSpec *)systemDirectoriesLocations->Get(&dirKey))) {
560                        // if not found, try Moz_BinDirectory
561                        dirSpec = (nsFileSpec *)
562                            systemDirectoriesLocations->Get(&mozBinDirKey);
563                    }
564                    else {
565                        // if the value is found for the argument key,
566                        // we don't need to append.
567                        needToAppend = PR_FALSE;
568                    }
569                }
570               
571                if (dirSpec)
572                {
573                    *this = *dirSpec;
574                }
575                else
576                {
577                    GetCurrentProcessDirectory(*this);
578                }
579
580                if (needToAppend) {
581                    // XXX We need to unify these names across all platforms
582#if defined(XP_MAC)
583                    *this += "Component Registry";
584#else
585                    *this += "component.reg";
586#endif /* XP_MAC */
587                }
588            }
589            break;
590
591        case XPCOM_CurrentProcessComponentDirectory:
592            {
593                nsFileSpec *dirSpec = NULL;
594                // if someone has called nsSpecialSystemDirectory::Set()
595                if (systemDirectoriesLocations) {
596                    // look for the value for the argument key
597                    if (!(dirSpec = (nsFileSpec *)systemDirectoriesLocations->Get(&dirKey))) {
598                        // if not found, try Moz_BinDirectory
599                        dirSpec = (nsFileSpec *)
600                            systemDirectoriesLocations->Get(&mozBinDirKey);
601                    }
602                    else {
603                        // if the value is found for the argument key,
604                        // we don't need to append.
605                        needToAppend = PR_FALSE;
606                    }
607                }
608                if (dirSpec)
609                {
610                    *this = *dirSpec;
611                }
612                else
613                {
614                    // <exedir>/Components
615                    GetCurrentProcessDirectory(*this);
616                }
617
618                if (needToAppend) {
619                    // XXX We need to unify these names across all platforms
620#if defined(XP_MAC)
621                    *this += "Components";
622#else
623                    *this += "components";
624#endif /* XP_MAC */
625                }
626            }
627            break;
628
629        case Moz_BinDirectory:
630            {
631                nsFileSpec *dirSpec = NULL;
632                // if someone has called nsSpecialSystemDirectory::Set()
633                if (systemDirectoriesLocations) {
634                    // look for the value for the argument key
635                    dirSpec = (nsFileSpec *)
636                        systemDirectoriesLocations->Get(&dirKey);
637                }
638                if (dirSpec) {
639                    *this = *dirSpec;
640                }
641                else {
642                    GetCurrentProcessDirectory(*this);
643                }
644            }
645            break;
646
647#if defined(XP_MAC)
648        case Mac_SystemDirectory:
649            *this = kSystemFolderType;
650            break;
651
652        case Mac_DesktopDirectory:
653            *this = kDesktopFolderType;
654            break;
655
656        case Mac_TrashDirectory:
657            *this = kTrashFolderType;
658            break;
659
660        case Mac_StartupDirectory:
661            *this = kStartupFolderType;
662            break;
663
664        case Mac_ShutdownDirectory:
665            *this = kShutdownFolderType;
666            break;
667
668        case Mac_AppleMenuDirectory:
669            *this = kAppleMenuFolderType;
670            break;
671
672        case Mac_ControlPanelDirectory:
673            *this = kControlPanelFolderType;
674            break;
675
676        case Mac_ExtensionDirectory:
677            *this = kExtensionFolderType;
678            break;
679
680        case Mac_FontsDirectory:
681            *this = kFontsFolderType;
682            break;
683
684        case Mac_ClassicPreferencesDirectory:
685        {
686                // whether Mac OS X or pre-Mac OS X, return Classic's Prefs folder
687            short domain;
688            long response;
689            err = ::Gestalt(gestaltSystemVersion, &response);
690            domain = (!err && response >= 0x00001000) ? kClassicDomain : kOnSystemDisk;
691            err = ::FindFolder(domain, kPreferencesFolderType, true, &vRefNum, &dirID);
692            if (!err) {
693                err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &mSpec);
694            }
695            mError = NS_FILE_RESULT(err);
696            break;
697        }
698
699        case Mac_PreferencesDirectory:
700                {
701                        // if Mac OS X, return Mac OS X's Prefs folder
702                        // if pre-Mac OS X, return Mac OS's Prefs folder
703            err = ::FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &vRefNum, &dirID);
704            if (!err) {
705                err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &mSpec);
706            }
707            mError = NS_FILE_RESULT(err);
708            break;
709                }
710
711        case Mac_DocumentsDirectory:
712            *this = kDocumentsFolderType;
713            break;
714
715        case Mac_InternetSearchDirectory:
716            *this = kInternetSearchSitesFolderType;
717            break;
718
719        case Mac_DefaultDownloadDirectory:
720            *this = kDefaultDownloadFolderType;
721            break;
722           
723        case Mac_UserLibDirectory:
724        {
725            err = ::FindFolder(kUserDomain, kDomainLibraryFolderType, true, &vRefNum, &dirID);
726            if (!err) {
727                err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &mSpec);
728            }
729            mError = NS_FILE_RESULT(err);
730            break;
731        }
732#endif
733           
734#if defined (XP_WIN)
735        case Win_SystemDirectory:
736        {   
737            char path[_MAX_PATH];
738            PRInt32 len = GetSystemDirectory( path, _MAX_PATH );
739       
740            // Need enough space to add the trailing backslash
741            if (len > _MAX_PATH-2)
742                break;
743            path[len]   = '\\';
744            path[len+1] = '\0';
745
746            *this = MakeUpperCase(path);
747
748            break;
749        }
750
751        case Win_WindowsDirectory:
752        {   
753            char path[_MAX_PATH];
754            PRInt32 len = GetWindowsDirectory( path, _MAX_PATH );
755           
756            // Need enough space to add the trailing backslash
757            if (len > _MAX_PATH-2)
758                break;
759           
760            path[len]   = '\\';
761            path[len+1] = '\0';
762
763            *this = MakeUpperCase(path);
764            break;
765        }
766
767        case Win_HomeDirectory:
768        {   
769            char path[_MAX_PATH];
770            if (GetEnvironmentVariable(TEXT("HOME"), path, _MAX_PATH) > 0)
771            {
772                PRInt32 len = PL_strlen(path);
773                // Need enough space to add the trailing backslash
774                if (len > _MAX_PATH - 2)
775                    break;
776               
777                path[len]   = '\\';
778                path[len+1] = '\0';
779               
780                *this = MakeUpperCase(path);
781                break;
782            }
783
784            if (GetEnvironmentVariable(TEXT("HOMEDRIVE"), path, _MAX_PATH) > 0)
785            {
786                char temp[_MAX_PATH];
787                if (GetEnvironmentVariable(TEXT("HOMEPATH"), temp, _MAX_PATH) > 0)
788                   PL_strcatn(path, _MAX_PATH, temp);
789       
790                PRInt32 len = PL_strlen(path);
791
792                // Need enough space to add the trailing backslash
793                if (len > _MAX_PATH - 2)
794                    break;
795           
796                path[len]   = '\\';
797                path[len+1] = '\0';
798               
799                *this = MakeUpperCase(path);
800                break;
801            }
802        }
803        case Win_Desktop:
804        {
805            GetWindowsFolder(CSIDL_DESKTOP, *this);
806            break;
807        }
808        case Win_Programs:
809        {
810            GetWindowsFolder(CSIDL_PROGRAMS, *this);
811            break;
812        }
813        case Win_Controls:
814        {
815            GetWindowsFolder(CSIDL_CONTROLS, *this);
816            break;
817        }
818        case Win_Printers:
819        {
820            GetWindowsFolder(CSIDL_PRINTERS, *this);
821            break;
822        }
823        case Win_Personal:
824        {
825            GetWindowsFolder(CSIDL_PERSONAL, *this);
826            break;
827        }
828        case Win_Favorites:
829        {
830            GetWindowsFolder(CSIDL_FAVORITES, *this);
831            break;
832        }
833        case Win_Startup:
834        {
835            GetWindowsFolder(CSIDL_STARTUP, *this);
836            break;
837        }
838        case Win_Recent:
839        {
840            GetWindowsFolder(CSIDL_RECENT, *this);
841            break;
842        }
843        case Win_Sendto:
844        {
845            GetWindowsFolder(CSIDL_SENDTO, *this);
846            break;
847        }
848        case Win_Bitbucket:
849        {
850            GetWindowsFolder(CSIDL_BITBUCKET, *this);
851            break;
852        }
853        case Win_Startmenu:
854        {
855            GetWindowsFolder(CSIDL_STARTMENU, *this);
856            break;
857        }
858        case Win_Desktopdirectory:
859        {
860            GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, *this);
861            break;
862        }
863        case Win_Drives:
864        {
865            GetWindowsFolder(CSIDL_DRIVES, *this);
866            break;
867        }
868        case Win_Network:
869        {
870            GetWindowsFolder(CSIDL_NETWORK, *this);
871            break;
872        }
873        case Win_Nethood:
874        {
875            GetWindowsFolder(CSIDL_NETHOOD, *this);
876            break;
877        }
878        case Win_Fonts:
879        {
880            GetWindowsFolder(CSIDL_FONTS, *this);
881            break;
882        }
883        case Win_Templates:
884        {
885            GetWindowsFolder(CSIDL_TEMPLATES, *this);
886            break;
887        }
888        case Win_Common_Startmenu:
889        {
890            GetWindowsFolder(CSIDL_COMMON_STARTMENU, *this);
891            break;
892        }
893        case Win_Common_Programs:
894        {
895            GetWindowsFolder(CSIDL_COMMON_PROGRAMS, *this);
896            break;
897        }
898        case Win_Common_Startup:
899        {
900            GetWindowsFolder(CSIDL_COMMON_STARTUP, *this);
901            break;
902        }
903        case Win_Common_Desktopdirectory:
904        {
905            GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, *this);
906            break;
907        }
908        case Win_Appdata:
909        {
910            GetWindowsFolder(CSIDL_APPDATA, *this);
911            break;
912        }
913        case Win_Printhood:
914        {
915            GetWindowsFolder(CSIDL_PRINTHOOD, *this);
916            break;
917        }
918        case Win_Cookies:
919        {
920            GetWindowsFolder(CSIDL_COOKIES, *this);
921            break;
922        }
923#endif  // XP_WIN
924
925#if defined(XP_UNIX)
926        case Unix_LocalDirectory:
927            *this = "/usr/local/netscape/";
928            break;
929
930        case Unix_LibDirectory:
931            *this = "/usr/local/lib/netscape/";
932            break;
933
934        case Unix_HomeDirectory:
935#ifdef VMS
936            {
937                char *pHome;
938                pHome = getenv("HOME");
939                if (*pHome == '/')
940                    *this = pHome;
941                else
942                    *this = decc$translate_vms(pHome);
943            }
944#else
945            *this = PR_GetEnv("HOME");
946#endif
947            break;
948
949#endif       
950
951#ifdef XP_BEOS
952        case BeOS_SettingsDirectory:
953                {
954            char path[MAXPATHLEN];
955                        find_directory(B_USER_SETTINGS_DIRECTORY, 0, 0, path, MAXPATHLEN);
956            // Need enough space to add the trailing backslash
957                        int len = strlen(path);
958            if (len > MAXPATHLEN-2)
959                break;
960            path[len]   = '/';
961            path[len+1] = '\0';
962                        *this = path;
963            break;
964                }
965
966        case BeOS_HomeDirectory:
967                {
968            char path[MAXPATHLEN];
969                        find_directory(B_USER_DIRECTORY, 0, 0, path, MAXPATHLEN);
970            // Need enough space to add the trailing backslash
971                        int len = strlen(path);
972            if (len > MAXPATHLEN-2)
973                break;
974            path[len]   = '/';
975            path[len+1] = '\0';
976                        *this = path;
977            break;
978                }
979
980        case BeOS_DesktopDirectory:
981                {
982            char path[MAXPATHLEN];
983                        find_directory(B_DESKTOP_DIRECTORY, 0, 0, path, MAXPATHLEN);
984            // Need enough space to add the trailing backslash
985                        int len = strlen(path);
986            if (len > MAXPATHLEN-2)
987                break;
988            path[len]   = '/';
989            path[len+1] = '\0';
990                        *this = path;
991            break;
992                }
993
994        case BeOS_SystemDirectory:
995                {
996            char path[MAXPATHLEN];
997                        find_directory(B_BEOS_DIRECTORY, 0, 0, path, MAXPATHLEN);
998            // Need enough space to add the trailing backslash
999                        int len = strlen(path);
1000            if (len > MAXPATHLEN-2)
1001                break;
1002            path[len]   = '/';
1003            path[len+1] = '\0';
1004                        *this = path;
1005            break;
1006                }
1007#endif       
1008#ifdef XP_OS2
1009        case OS2_SystemDirectory:
1010        {
1011            ULONG ulBootDrive = 0;
1012            char  buffer[] = " :\\OS2\\System\\";
1013            DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
1014                             &ulBootDrive, sizeof ulBootDrive);
1015            buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
1016            *this = buffer;
1017#ifdef DEBUG
1018            printf( "Got OS2_SystemDirectory: %s\n", buffer);
1019#endif
1020            break;
1021        }
1022
1023     case OS2_OS2Directory:
1024        {
1025            ULONG ulBootDrive = 0;
1026            char  buffer[] = " :\\OS2\\";
1027            DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
1028                             &ulBootDrive, sizeof ulBootDrive);
1029            buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
1030            *this = buffer;
1031#ifdef DEBUG
1032            printf( "Got OS2_OS2Directory: %s\n", buffer);
1033#endif
1034            break;
1035        }
1036
1037     case OS2_HomeDirectory:
1038        {
1039            char *tPath = PR_GetEnv("MOZILLA_HOME");
1040            /* If MOZILLA_HOME is not set, use GetCurrentProcessDirectory */
1041            /* To ensure we get a long filename system */
1042            if (!tPath || !*tPath)
1043              GetCurrentProcessDirectory(*this);
1044            else
1045              *this = tPath;
1046            PrfWriteProfileString(HINI_USERPROFILE, "Mozilla", "Home", *this);
1047            break;
1048        }
1049
1050        case OS2_DesktopDirectory:
1051        {
1052            char szPath[CCHMAXPATH + 1];       
1053            BOOL fSuccess;
1054            fSuccess = WinQueryActiveDesktopPathname (szPath, sizeof(szPath));
1055            int len = strlen (szPath);   
1056            if (len > CCHMAXPATH -1)
1057               break;
1058            szPath[len] = '\\';     
1059            szPath[len + 1] = '\0';
1060#ifdef DEBUG
1061            if (fSuccess) {
1062               printf ("Got OS2_DesktopDirectory: %s\n", szPath);
1063            } else {
1064               printf ("Failed getting OS2_DesktopDirectory: %s\n", szPath);
1065            }
1066#endif
1067            break;           
1068        }
1069
1070#endif
1071        default:
1072            break;   
1073    }
1074}
1075
1076void
1077nsSpecialSystemDirectory::Set(SystemDirectories dirToSet, nsFileSpec *dirSpec)
1078{
1079    SystemDirectoriesKey dirKey(dirToSet);
1080   
1081    PR_ASSERT(NULL != dirSpec);
1082   
1083    if (NULL == systemDirectoriesLocations) {
1084        systemDirectoriesLocations = new nsHashtable(NS_SYSTEMDIR_HASH_NUM);
1085    }
1086    PR_ASSERT(NULL != systemDirectoriesLocations);
1087   
1088    nsFileSpec *newSpec = new nsFileSpec(*dirSpec);
1089    if (NULL != newSpec) {
1090        systemDirectoriesLocations->Put(&dirKey, newSpec);
1091    }
1092   
1093    return;
1094}
1095
1096#if defined(XP_MAC)
1097//----------------------------------------------------------------------------------------
1098nsSpecialSystemDirectory::nsSpecialSystemDirectory(OSType folderType)
1099//----------------------------------------------------------------------------------------
1100{
1101        *this = folderType;
1102}
1103
1104//----------------------------------------------------------------------------------------
1105void nsSpecialSystemDirectory::operator = (OSType folderType)
1106//----------------------------------------------------------------------------------------
1107{
1108    CInfoPBRec cinfo;
1109    DirInfo *dipb=(DirInfo *)&cinfo;
1110   
1111    // hack: first check for kDefaultDownloadFolderType
1112    // if it is, get Internet Config Download folder, if that's
1113    // not availble use desktop folder
1114    if (folderType == kDefaultDownloadFolderType)
1115    {
1116      nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
1117      if (icService)
1118      {
1119        if (NS_SUCCEEDED(icService->GetDownloadFolder(&mSpec)))
1120          return;
1121        else
1122          folderType = kDesktopFolderType;
1123      }
1124      else
1125      {
1126        folderType = kDesktopFolderType;
1127      }
1128    }
1129    // Call FindFolder to fill in the vrefnum and dirid
1130    for (int attempts = 0; attempts < 2; attempts++)
1131    {
1132        mError = NS_FILE_RESULT(
1133            FindFolder(
1134                kOnSystemDisk,
1135                folderType,
1136                true,
1137                &dipb->ioVRefNum,
1138                &dipb->ioDrDirID));
1139        if (NS_SUCCEEDED(mError))
1140            break;
1141        if (attempts > 0)
1142                    return;
1143                switch (folderType)
1144                {
1145            case kDocumentsFolderType:
1146                // Find folder will find this, as long as it exists.
1147                // The "create" parameter, however, is sadly ignored.
1148                // How do we internationalize this?
1149                *this = kVolumeRootFolderType;
1150                *this += "Documents";
1151                CreateDirectory();
1152                break;
1153                } // switch
1154    } // for
1155    StrFileName filename;
1156    filename[0] = '\0';
1157    dipb->ioNamePtr = (StringPtr)&filename;
1158    dipb->ioFDirIndex = -1;
1159   
1160    mError = NS_FILE_RESULT(PBGetCatInfoSync(&cinfo));
1161    if (NS_SUCCEEDED(mError))
1162    {
1163            mError = NS_FILE_RESULT(FSMakeFSSpec(dipb->ioVRefNum, dipb->ioDrParID, filename, &mSpec));
1164    }
1165}
1166#endif // XP_MAC
Note: See TracBrowser for help on using the repository browser.