gecko-dev/xpcom/obsolete/nsSpecialSystemDirectory.cpp
2004-04-18 14:21:17 +00:00

1190 lines
34 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@netscape.com>
* IBM Corp.
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsSpecialSystemDirectory.h"
#include "nsDebug.h"
#ifdef XP_MAC
#include <Folders.h>
#include <Files.h>
#include <Memory.h>
#include <Processes.h>
#include <Gestalt.h>
#include "nsIInternetConfigService.h"
#ifdef DEBUG
#include "prenv.h" // For PR_Getenv
#endif
#elif defined(XP_WIN)
#include <windows.h>
#include <shlobj.h>
#include <stdlib.h>
#include <stdio.h>
#elif defined(XP_OS2)
#define MAX_PATH _MAX_PATH
#define INCL_WINWORKPLACE
#include <os2.h>
#include <stdlib.h>
#include <stdio.h>
#include "prenv.h"
#elif defined(XP_UNIX)
#include <unistd.h>
#include <stdlib.h>
#include <sys/param.h>
#include "prenv.h"
#elif defined(XP_BEOS)
#include <FindDirectory.h>
#include <Path.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/param.h>
#include <OS.h>
#include <image.h>
#include "prenv.h"
#endif
#if defined(VMS)
#include <unixlib.h>
#endif
#include "plstr.h"
#include "nsHashtable.h"
#include "prlog.h"
#if defined (XP_MAC) && UNIVERSAL_INTERFACES_VERSION < 0x0340
enum {
kSystemDomain = -32766, /* Read-only system hierarchy.*/
kLocalDomain = -32765, /* All users of a single machine have access to these resources.*/
kNetworkDomain = -32764, /* All users configured to use a common network server has access to these resources.*/
kUserDomain = -32763, /* Read/write. Resources that are private to the user.*/
kClassicDomain = -32762, /* Domain referring to the currently configured Classic System Folder*/
kDomainLibraryFolderType = FOUR_CHAR_CODE('dlib')
};
#endif
class SystemDirectoriesKey : public nsHashKey {
public:
SystemDirectoriesKey(nsSpecialSystemDirectory::SystemDirectories newKey) : sdKey(newKey) {}
virtual PRUint32 HashCode(void) const
{
return PRUint32(sdKey);
}
virtual PRBool Equals(const nsHashKey *aKey) const
{
nsSpecialSystemDirectory::SystemDirectories other =
((SystemDirectoriesKey*)aKey)->sdKey;
return other == sdKey;
}
virtual nsHashKey *Clone(void) const
{
return new SystemDirectoriesKey(sdKey);
}
private:
nsSpecialSystemDirectory::SystemDirectories sdKey; // sd for SystemDirectories
};
PR_STATIC_CALLBACK(PRBool) DeleteSystemDirKeys(nsHashKey *aKey, void *aData, void* closure)
{
delete ((nsFileSpec *)aData);
return PR_TRUE;
}
#define NS_SYSTEMDIR_HASH_NUM (10)
static nsHashtable *systemDirectoriesLocations = NULL;
#if defined (XP_WIN)
typedef BOOL (WINAPI * GetSpecialPathProc) (HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
GetSpecialPathProc gGetSpecialPathProc = NULL;
static HINSTANCE gShell32DLLInst = NULL;
#endif
NS_COM_OBSOLETE void StartupSpecialSystemDirectory()
{
#if defined (XP_WIN)
/* On windows, the old method to get file locations is incredibly slow.
As of this writing, 3 calls to GetWindowsFolder accounts for 3% of mozilla
startup. Replacing these older calls with a single call to SHGetSpecialFolderPath
effectively removes these calls from the performace radar. We need to
support the older way of file location lookup on systems that do not have
IE4. (Note: gets the ansi version: SHGetSpecialFolderPathA).
*/
gShell32DLLInst = LoadLibrary("Shell32.dll");
if(gShell32DLLInst)
{
gGetSpecialPathProc = (GetSpecialPathProc) GetProcAddress(gShell32DLLInst,
"SHGetSpecialFolderPathA");
}
#endif
}
NS_COM_OBSOLETE void ShutdownSpecialSystemDirectory()
{
if (systemDirectoriesLocations)
{
systemDirectoriesLocations->Reset(DeleteSystemDirKeys);
delete systemDirectoriesLocations;
}
#if defined (XP_WIN)
if (gShell32DLLInst)
{
FreeLibrary(gShell32DLLInst);
gShell32DLLInst = NULL;
gGetSpecialPathProc = NULL;
}
#endif
}
#if defined (XP_WIN)
static PRBool gGlobalOSInitialized = PR_FALSE;
static PRBool gGlobalDBCSEnabledOS = PR_FALSE;
//----------------------------------------------------------------------------------------
static char* MakeUpperCase(char* aPath)
//----------------------------------------------------------------------------------------
{
// check if the Windows is DBCSEnabled once.
if (PR_FALSE == gGlobalOSInitialized) {
if (GetSystemMetrics(SM_DBCSENABLED))
gGlobalDBCSEnabledOS = PR_TRUE;
gGlobalOSInitialized = PR_TRUE;
}
// windows does not care about case. pu sh to uppercase:
int length = strlen(aPath);
int i = 0; /* C++ portability guide #20 */
if (!gGlobalDBCSEnabledOS) {
// for non-DBCS windows
for (i = 0; i < length; i++)
if (islower(aPath[i]))
aPath[i] = _toupper(aPath[i]);
}
else {
// for DBCS windows
for (i = 0; i < length; i++) {
if (IsDBCSLeadByte(aPath[i])) {
// begining of the double bye char
i++;
}
else {
if ( islower(aPath[i]))
aPath[i] = _toupper(aPath[i]);
}
} //end of for loop
}
return aPath;
}
//----------------------------------------------------------------------------------------
static void GetWindowsFolder(int folder, nsFileSpec& outDirectory)
//----------------------------------------------------------------------------------------
{
if (gGetSpecialPathProc) {
TCHAR path[MAX_PATH];
HRESULT result = gGetSpecialPathProc(NULL, path, folder, true);
if (!SUCCEEDED(result))
return;
// Append the trailing slash
int len = PL_strlen(path);
if (len>1 && path[len-1] != '\\')
{
path[len] = '\\';
path[len + 1] = '\0';
}
outDirectory = path;
return;
}
LPMALLOC pMalloc = NULL;
LPSTR pBuffer = NULL;
LPITEMIDLIST pItemIDList = NULL;
int len;
// Get the shell's allocator.
if (!SUCCEEDED(SHGetMalloc(&pMalloc)))
return;
// Allocate a buffer
if ((pBuffer = (LPSTR) pMalloc->Alloc(MAX_PATH + 2)) == NULL)
return;
// Get the PIDL for the folder.
if (!SUCCEEDED(SHGetSpecialFolderLocation(
NULL, folder, &pItemIDList)))
goto Clean;
if (!SUCCEEDED(SHGetPathFromIDList(pItemIDList, pBuffer)))
goto Clean;
// Append the trailing slash
len = PL_strlen(pBuffer);
pBuffer[len] = '\\';
pBuffer[len + 1] = '\0';
// Assign the directory
outDirectory = pBuffer;
Clean:
// Clean up.
if (pItemIDList)
pMalloc->Free(pItemIDList);
if (pBuffer)
pMalloc->Free(pBuffer);
pMalloc->Release();
} // GetWindowsFolder
#endif // XP_WIN
//----------------------------------------------------------------------------------------
static void GetCurrentWorkingDirectory(nsFileSpec& aFileSpec)
//----------------------------------------------------------------------------------------
{
aFileSpec = ".";
return;
} // GetCurrentWorkingDirectory
//----------------------------------------------------------------------------------------
static void GetCurrentProcessDirectory(nsFileSpec& aFileSpec)
//----------------------------------------------------------------------------------------
{
#if defined (XP_WIN)
char buf[MAX_PATH];
if ( ::GetModuleFileName(0, buf, sizeof(buf)) ) {
// chop of the executable name by finding the rightmost backslash
char* lastSlash = PL_strrchr(buf, '\\');
if (lastSlash)
*(lastSlash + 1) = '\0';
aFileSpec = buf;
return;
}
#elif defined(XP_OS2)
PPIB ppib;
PTIB ptib;
char buffer[CCHMAXPATH];
DosGetInfoBlocks( &ptib, &ppib);
DosQueryModuleName( ppib->pib_hmte, CCHMAXPATH, buffer);
*strrchr( buffer, '\\') = '\0'; // XXX DBCS misery
aFileSpec = buffer;
return;
#elif defined(XP_MAC)
// get info for the the current process to determine the directory
// its located in
OSErr err;
ProcessSerialNumber psn = {kNoProcess, kCurrentProcess};
ProcessInfoRec pInfo;
FSSpec tempSpec;
// initialize ProcessInfoRec before calling
// GetProcessInformation() or die horribly.
pInfo.processName = nil;
pInfo.processAppSpec = &tempSpec;
pInfo.processInfoLength = sizeof(ProcessInfoRec);
if (!(err = GetProcessInformation(&psn, &pInfo)))
{
FSSpec appFSSpec = *(pInfo.processAppSpec);
long theDirID = appFSSpec.parID;
Str255 name;
CInfoPBRec catInfo;
catInfo.dirInfo.ioCompletion = NULL;
catInfo.dirInfo.ioNamePtr = (StringPtr)&name;
catInfo.dirInfo.ioVRefNum = appFSSpec.vRefNum;
catInfo.dirInfo.ioDrDirID = theDirID;
catInfo.dirInfo.ioFDirIndex = -1; // -1 = query dir in ioDrDirID
if (!(err = PBGetCatInfoSync(&catInfo)))
{
aFileSpec = nsFileSpec(appFSSpec.vRefNum,
catInfo.dirInfo.ioDrParID,
name,
PR_TRUE);
return;
}
}
#if defined(DEBUG)
else
{
// In the absence of a good way to get the executable directory let
// us try this for unix:
// - if MOZILLA_FIVE_HOME is defined, that is it
char *moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
if (moz5)
{
printf( "nsSpecialSystemDirectory::MOZILLA_FIVE_HOME is set to %s\n", moz5 );
aFileSpec = moz5;
return;
}
else
{
static PRBool firstWarning = PR_TRUE;
if(firstWarning) {
// Warn that MOZILLA_FIVE_HOME not set, once.
printf("***Warning: MOZILLA_FIVE_HOME not set.\n");
firstWarning = PR_FALSE;
}
}
}
#endif /* DEBUG */
#elif defined(XP_UNIX)
// In the absence of a good way to get the executable directory let
// us try this for unix:
// - if MOZILLA_FIVE_HOME is defined, that is it
// - else give the current directory
char buf[MAXPATHLEN];
char *moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
if (moz5)
{
aFileSpec = moz5;
return;
}
else
{
#if defined(DEBUG)
static PRBool firstWarning = PR_TRUE;
if(firstWarning) {
// Warn that MOZILLA_FIVE_HOME not set, once.
printf("Warning: MOZILLA_FIVE_HOME not set.\n");
firstWarning = PR_FALSE;
}
#endif /* DEBUG */
// Fall back to current directory.
if (getcwd(buf, sizeof(buf)))
{
aFileSpec = buf;
return;
}
}
#elif defined(XP_BEOS)
char *moz5 = getenv("MOZILLA_FIVE_HOME");
if (moz5)
{
aFileSpec = moz5;
return;
}
else
{
static char buf[MAXPATHLEN];
int32 cookie = 0;
image_info info;
char *p;
*buf = 0;
if(get_next_image_info(0, &cookie, &info) == B_OK)
{
strcpy(buf, info.name);
if((p = strrchr(buf, '/')) != 0)
{
*p = 0;
aFileSpec = buf;
return;
}
}
}
#endif
NS_ERROR("unable to get current process directory");
} // GetCurrentProcessDirectory()
//nsSpecialSystemDirectory::nsSpecialSystemDirectory()
//: nsFileSpec(nsnull)
//{
//}
//----------------------------------------------------------------------------------------
nsSpecialSystemDirectory::nsSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory)
//----------------------------------------------------------------------------------------
: nsFileSpec(nsnull)
{
*this = aSystemSystemDirectory;
}
//----------------------------------------------------------------------------------------
nsSpecialSystemDirectory::~nsSpecialSystemDirectory()
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
void nsSpecialSystemDirectory::operator = (SystemDirectories aSystemSystemDirectory)
//----------------------------------------------------------------------------------------
{
SystemDirectoriesKey dirKey(aSystemSystemDirectory);
SystemDirectoriesKey mozBinDirKey(Moz_BinDirectory);
// This flag is used to tell whether or not we need to append something
// onto the *this. Search for needToAppend to how it's used.
// IT's VERY IMPORTANT that needToAppend is initialized to PR_TRUE.
PRBool needToAppend = PR_TRUE;
#ifdef XP_MAC
OSErr err;
short vRefNum;
long dirID;
#endif
*this = (const char*)nsnull;
switch (aSystemSystemDirectory)
{
case OS_DriveDirectory:
#if defined (XP_WIN)
{
char path[_MAX_PATH];
PRInt32 len = GetWindowsDirectory( path, _MAX_PATH );
if (len)
{
if ( path[1] == ':' && path[2] == '\\' )
path[3] = 0;
}
*this = MakeUpperCase(path);
}
#elif defined(XP_OS2)
{
// printf( "*** Warning warning OS_DriveDirectory called for");
ULONG ulBootDrive = 0;
char buffer[] = " :\\OS2\\";
DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
&ulBootDrive, sizeof ulBootDrive);
buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
*this = buffer;
#ifdef DEBUG
printf( "Got OS_DriveDirectory: %s\n", buffer);
#endif
}
#elif defined(XP_MAC)
{
*this = kVolumeRootFolderType;
}
#else
*this = "/";
#endif
break;
case OS_TemporaryDirectory:
#if defined (XP_WIN)
{
char path[_MAX_PATH];
DWORD len = GetTempPath(_MAX_PATH, path);
*this = MakeUpperCase(path);
}
#elif defined(XP_OS2)
{
char buffer[CCHMAXPATH] = "";
char *c = getenv( "TMP");
if( c) strcpy( buffer, c);
else
{
c = getenv( "TEMP");
if( c) strcpy( buffer, c);
}
if( c) *this = buffer;
// use exe's directory if not set
else GetCurrentProcessDirectory(*this);
}
#elif defined(XP_MAC)
*this = kTemporaryFolderType;
#elif defined(XP_UNIX) || defined(XP_BEOS)
{
static const char *tPath = nsnull;
if (!tPath) {
tPath = PR_GetEnv("TMPDIR");
if (!tPath || !*tPath) {
tPath = PR_GetEnv("TMP");
if (!tPath || !*tPath) {
tPath = PR_GetEnv("TEMP");
if (!tPath || !*tPath) {
tPath = "/tmp/";
}
}
}
}
*this = tPath;
}
#endif
break;
case OS_CurrentProcessDirectory:
GetCurrentProcessDirectory(*this);
break;
case OS_CurrentWorkingDirectory:
GetCurrentWorkingDirectory(*this);
break;
case XPCOM_CurrentProcessComponentRegistry:
{
nsFileSpec *dirSpec = NULL;
// if someone has called nsSpecialSystemDirectory::Set()
if (systemDirectoriesLocations) {
// look for the value for the argument key
if (!(dirSpec = (nsFileSpec *)systemDirectoriesLocations->Get(&dirKey))) {
// if not found, try Moz_BinDirectory
dirSpec = (nsFileSpec *)
systemDirectoriesLocations->Get(&mozBinDirKey);
}
else {
// if the value is found for the argument key,
// we don't need to append.
needToAppend = PR_FALSE;
}
}
if (dirSpec)
{
*this = *dirSpec;
}
else
{
GetCurrentProcessDirectory(*this);
}
if (needToAppend) {
// XXX We need to unify these names across all platforms
#if defined(XP_MAC)
*this += "Component Registry";
#else
*this += "component.reg";
#endif /* XP_MAC */
}
}
break;
case XPCOM_CurrentProcessComponentDirectory:
{
nsFileSpec *dirSpec = NULL;
// if someone has called nsSpecialSystemDirectory::Set()
if (systemDirectoriesLocations) {
// look for the value for the argument key
if (!(dirSpec = (nsFileSpec *)systemDirectoriesLocations->Get(&dirKey))) {
// if not found, try Moz_BinDirectory
dirSpec = (nsFileSpec *)
systemDirectoriesLocations->Get(&mozBinDirKey);
}
else {
// if the value is found for the argument key,
// we don't need to append.
needToAppend = PR_FALSE;
}
}
if (dirSpec)
{
*this = *dirSpec;
}
else
{
// <exedir>/Components
GetCurrentProcessDirectory(*this);
}
if (needToAppend) {
// XXX We need to unify these names across all platforms
#if defined(XP_MAC)
*this += "Components";
#else
*this += "components";
#endif /* XP_MAC */
}
}
break;
case Moz_BinDirectory:
{
nsFileSpec *dirSpec = NULL;
// if someone has called nsSpecialSystemDirectory::Set()
if (systemDirectoriesLocations) {
// look for the value for the argument key
dirSpec = (nsFileSpec *)
systemDirectoriesLocations->Get(&dirKey);
}
if (dirSpec) {
*this = *dirSpec;
}
else {
GetCurrentProcessDirectory(*this);
}
}
break;
#if defined(XP_MAC)
case Mac_SystemDirectory:
*this = kSystemFolderType;
break;
case Mac_DesktopDirectory:
*this = kDesktopFolderType;
break;
case Mac_TrashDirectory:
*this = kTrashFolderType;
break;
case Mac_StartupDirectory:
*this = kStartupFolderType;
break;
case Mac_ShutdownDirectory:
*this = kShutdownFolderType;
break;
case Mac_AppleMenuDirectory:
*this = kAppleMenuFolderType;
break;
case Mac_ControlPanelDirectory:
*this = kControlPanelFolderType;
break;
case Mac_ExtensionDirectory:
*this = kExtensionFolderType;
break;
case Mac_FontsDirectory:
*this = kFontsFolderType;
break;
case Mac_ClassicPreferencesDirectory:
{
// whether Mac OS X or pre-Mac OS X, return Classic's Prefs folder
short domain;
long response;
err = ::Gestalt(gestaltSystemVersion, &response);
domain = (!err && response >= 0x00001000) ? kClassicDomain : kOnSystemDisk;
err = ::FindFolder(domain, kPreferencesFolderType, true, &vRefNum, &dirID);
if (!err) {
err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &mSpec);
}
mError = NS_FILE_RESULT(err);
break;
}
case Mac_PreferencesDirectory:
{
// if Mac OS X, return Mac OS X's Prefs folder
// if pre-Mac OS X, return Mac OS's Prefs folder
err = ::FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &vRefNum, &dirID);
if (!err) {
err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &mSpec);
}
mError = NS_FILE_RESULT(err);
break;
}
case Mac_DocumentsDirectory:
*this = kDocumentsFolderType;
break;
case Mac_InternetSearchDirectory:
*this = kInternetSearchSitesFolderType;
break;
case Mac_DefaultDownloadDirectory:
*this = kDefaultDownloadFolderType;
break;
case Mac_UserLibDirectory:
{
err = ::FindFolder(kUserDomain, kDomainLibraryFolderType, true, &vRefNum, &dirID);
if (!err) {
err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &mSpec);
}
mError = NS_FILE_RESULT(err);
break;
}
#endif
#if defined (XP_WIN)
case Win_SystemDirectory:
{
char path[_MAX_PATH];
PRInt32 len = GetSystemDirectory( path, _MAX_PATH );
// Need enough space to add the trailing backslash
if (len > _MAX_PATH-2)
break;
path[len] = '\\';
path[len+1] = '\0';
*this = MakeUpperCase(path);
break;
}
case Win_WindowsDirectory:
{
char path[_MAX_PATH];
PRInt32 len = GetWindowsDirectory( path, _MAX_PATH );
// Need enough space to add the trailing backslash
if (len > _MAX_PATH-2)
break;
path[len] = '\\';
path[len+1] = '\0';
*this = MakeUpperCase(path);
break;
}
case Win_HomeDirectory:
{
char path[_MAX_PATH];
if (GetEnvironmentVariable(TEXT("HOME"), path, _MAX_PATH) > 0)
{
PRInt32 len = PL_strlen(path);
// Need enough space to add the trailing backslash
if (len > _MAX_PATH - 2)
break;
path[len] = '\\';
path[len+1] = '\0';
*this = MakeUpperCase(path);
break;
}
if (GetEnvironmentVariable(TEXT("HOMEDRIVE"), path, _MAX_PATH) > 0)
{
char temp[_MAX_PATH];
if (GetEnvironmentVariable(TEXT("HOMEPATH"), temp, _MAX_PATH) > 0)
PL_strcatn(path, _MAX_PATH, temp);
PRInt32 len = PL_strlen(path);
// Need enough space to add the trailing backslash
if (len > _MAX_PATH - 2)
break;
path[len] = '\\';
path[len+1] = '\0';
*this = MakeUpperCase(path);
break;
}
}
case Win_Desktop:
{
GetWindowsFolder(CSIDL_DESKTOP, *this);
break;
}
case Win_Programs:
{
GetWindowsFolder(CSIDL_PROGRAMS, *this);
break;
}
case Win_Controls:
{
GetWindowsFolder(CSIDL_CONTROLS, *this);
break;
}
case Win_Printers:
{
GetWindowsFolder(CSIDL_PRINTERS, *this);
break;
}
case Win_Personal:
{
GetWindowsFolder(CSIDL_PERSONAL, *this);
break;
}
case Win_Favorites:
{
GetWindowsFolder(CSIDL_FAVORITES, *this);
break;
}
case Win_Startup:
{
GetWindowsFolder(CSIDL_STARTUP, *this);
break;
}
case Win_Recent:
{
GetWindowsFolder(CSIDL_RECENT, *this);
break;
}
case Win_Sendto:
{
GetWindowsFolder(CSIDL_SENDTO, *this);
break;
}
case Win_Bitbucket:
{
GetWindowsFolder(CSIDL_BITBUCKET, *this);
break;
}
case Win_Startmenu:
{
GetWindowsFolder(CSIDL_STARTMENU, *this);
break;
}
case Win_Desktopdirectory:
{
GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, *this);
break;
}
case Win_Drives:
{
GetWindowsFolder(CSIDL_DRIVES, *this);
break;
}
case Win_Network:
{
GetWindowsFolder(CSIDL_NETWORK, *this);
break;
}
case Win_Nethood:
{
GetWindowsFolder(CSIDL_NETHOOD, *this);
break;
}
case Win_Fonts:
{
GetWindowsFolder(CSIDL_FONTS, *this);
break;
}
case Win_Templates:
{
GetWindowsFolder(CSIDL_TEMPLATES, *this);
break;
}
case Win_Common_Startmenu:
{
GetWindowsFolder(CSIDL_COMMON_STARTMENU, *this);
break;
}
case Win_Common_Programs:
{
GetWindowsFolder(CSIDL_COMMON_PROGRAMS, *this);
break;
}
case Win_Common_Startup:
{
GetWindowsFolder(CSIDL_COMMON_STARTUP, *this);
break;
}
case Win_Common_Desktopdirectory:
{
GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, *this);
break;
}
case Win_Appdata:
{
GetWindowsFolder(CSIDL_APPDATA, *this);
break;
}
case Win_Printhood:
{
GetWindowsFolder(CSIDL_PRINTHOOD, *this);
break;
}
case Win_Cookies:
{
GetWindowsFolder(CSIDL_COOKIES, *this);
break;
}
#endif // XP_WIN
#if defined(XP_UNIX)
case Unix_LocalDirectory:
*this = "/usr/local/netscape/";
break;
case Unix_LibDirectory:
*this = "/usr/local/lib/netscape/";
break;
case Unix_HomeDirectory:
#ifdef VMS
{
char *pHome;
pHome = getenv("HOME");
if (*pHome == '/')
*this = pHome;
else
*this = decc$translate_vms(pHome);
}
#else
*this = PR_GetEnv("HOME");
#endif
break;
#endif
#ifdef XP_BEOS
case BeOS_SettingsDirectory:
{
char path[MAXPATHLEN];
find_directory(B_USER_SETTINGS_DIRECTORY, 0, 0, path, MAXPATHLEN);
// Need enough space to add the trailing backslash
int len = strlen(path);
if (len > MAXPATHLEN-2)
break;
path[len] = '/';
path[len+1] = '\0';
*this = path;
break;
}
case BeOS_HomeDirectory:
{
char path[MAXPATHLEN];
find_directory(B_USER_DIRECTORY, 0, 0, path, MAXPATHLEN);
// Need enough space to add the trailing backslash
int len = strlen(path);
if (len > MAXPATHLEN-2)
break;
path[len] = '/';
path[len+1] = '\0';
*this = path;
break;
}
case BeOS_DesktopDirectory:
{
char path[MAXPATHLEN];
find_directory(B_DESKTOP_DIRECTORY, 0, 0, path, MAXPATHLEN);
// Need enough space to add the trailing backslash
int len = strlen(path);
if (len > MAXPATHLEN-2)
break;
path[len] = '/';
path[len+1] = '\0';
*this = path;
break;
}
case BeOS_SystemDirectory:
{
char path[MAXPATHLEN];
find_directory(B_BEOS_DIRECTORY, 0, 0, path, MAXPATHLEN);
// Need enough space to add the trailing backslash
int len = strlen(path);
if (len > MAXPATHLEN-2)
break;
path[len] = '/';
path[len+1] = '\0';
*this = path;
break;
}
#endif
#ifdef XP_OS2
case OS2_SystemDirectory:
{
ULONG ulBootDrive = 0;
char buffer[] = " :\\OS2\\System\\";
DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
&ulBootDrive, sizeof ulBootDrive);
buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
*this = buffer;
#ifdef DEBUG
printf( "Got OS2_SystemDirectory: %s\n", buffer);
#endif
break;
}
case OS2_OS2Directory:
{
ULONG ulBootDrive = 0;
char buffer[] = " :\\OS2\\";
DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
&ulBootDrive, sizeof ulBootDrive);
buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
*this = buffer;
#ifdef DEBUG
printf( "Got OS2_OS2Directory: %s\n", buffer);
#endif
break;
}
case OS2_HomeDirectory:
{
char *tPath = PR_GetEnv("MOZILLA_HOME");
/* If MOZILLA_HOME is not set, use GetCurrentProcessDirectory */
/* To ensure we get a long filename system */
if (!tPath || !*tPath)
GetCurrentProcessDirectory(*this);
else
*this = tPath;
PrfWriteProfileString(HINI_USERPROFILE, "Mozilla", "Home", *this);
break;
}
case OS2_DesktopDirectory:
{
char szPath[CCHMAXPATH + 1];
BOOL fSuccess;
fSuccess = WinQueryActiveDesktopPathname (szPath, sizeof(szPath));
int len = strlen (szPath);
if (len > CCHMAXPATH -1)
break;
szPath[len] = '\\';
szPath[len + 1] = '\0';
#ifdef DEBUG
if (fSuccess) {
printf ("Got OS2_DesktopDirectory: %s\n", szPath);
} else {
printf ("Failed getting OS2_DesktopDirectory: %s\n", szPath);
}
#endif
break;
}
#endif
default:
break;
}
}
void
nsSpecialSystemDirectory::Set(SystemDirectories dirToSet, nsFileSpec *dirSpec)
{
SystemDirectoriesKey dirKey(dirToSet);
PR_ASSERT(NULL != dirSpec);
if (NULL == systemDirectoriesLocations) {
systemDirectoriesLocations = new nsHashtable(NS_SYSTEMDIR_HASH_NUM);
}
PR_ASSERT(NULL != systemDirectoriesLocations);
nsFileSpec *newSpec = new nsFileSpec(*dirSpec);
if (NULL != newSpec) {
systemDirectoriesLocations->Put(&dirKey, newSpec);
}
return;
}
#if defined(XP_MAC)
//----------------------------------------------------------------------------------------
nsSpecialSystemDirectory::nsSpecialSystemDirectory(OSType folderType)
//----------------------------------------------------------------------------------------
{
*this = folderType;
}
//----------------------------------------------------------------------------------------
void nsSpecialSystemDirectory::operator = (OSType folderType)
//----------------------------------------------------------------------------------------
{
CInfoPBRec cinfo;
DirInfo *dipb=(DirInfo *)&cinfo;
// hack: first check for kDefaultDownloadFolderType
// if it is, get Internet Config Download folder, if that's
// not availble use desktop folder
if (folderType == kDefaultDownloadFolderType)
{
nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
if (icService)
{
if (NS_SUCCEEDED(icService->GetDownloadFolder(&mSpec)))
return;
else
folderType = kDesktopFolderType;
}
else
{
folderType = kDesktopFolderType;
}
}
// Call FindFolder to fill in the vrefnum and dirid
for (int attempts = 0; attempts < 2; attempts++)
{
mError = NS_FILE_RESULT(
FindFolder(
kOnSystemDisk,
folderType,
true,
&dipb->ioVRefNum,
&dipb->ioDrDirID));
if (NS_SUCCEEDED(mError))
break;
if (attempts > 0)
return;
switch (folderType)
{
case kDocumentsFolderType:
// Find folder will find this, as long as it exists.
// The "create" parameter, however, is sadly ignored.
// How do we internationalize this?
*this = kVolumeRootFolderType;
*this += "Documents";
CreateDirectory();
break;
} // switch
} // for
StrFileName filename;
filename[0] = '\0';
dipb->ioNamePtr = (StringPtr)&filename;
dipb->ioFDirIndex = -1;
mError = NS_FILE_RESULT(PBGetCatInfoSync(&cinfo));
if (NS_SUCCEEDED(mError))
{
mError = NS_FILE_RESULT(FSMakeFSSpec(dipb->ioVRefNum, dipb->ioDrParID, filename, &mSpec));
}
}
#endif // XP_MAC