nsSpecialSystemDirectory.cpp revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/* -*- 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
*
* 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
#include <windows.h>
#include <shlobj.h>
#include <stdlib.h>
#include <stdio.h>
#define INCL_WINWORKPLACE
#include <os2.h>
#include <stdlib.h>
#include <stdio.h>
#include "prenv.h"
#include <unistd.h>
#include <stdlib.h>
#include "prenv.h"
#include <FindDirectory.h>
#include <Path.h>
#include <unistd.h>
#include <stdlib.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"
enum {
kNetworkDomain = -32764, /* All users configured to use a common network server has access to these resources.*/
};
#endif
class SystemDirectoriesKey : public nsHashKey {
public:
{
}
{
}
{
return new SystemDirectoriesKey(sdKey);
}
private:
};
{
delete ((nsFileSpec *)aData);
return PR_TRUE;
}
#define NS_SYSTEMDIR_HASH_NUM (10)
#if defined (XP_WIN)
typedef BOOL (WINAPI * GetSpecialPathProc) (HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
#endif
{
#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).
*/
if(gShell32DLLInst)
{
"SHGetSpecialFolderPathA");
}
#endif
}
{
{
delete systemDirectoriesLocations;
}
#if defined (XP_WIN)
if (gShell32DLLInst)
{
}
#endif
}
#if defined (XP_WIN)
//----------------------------------------------------------------------------------------
static char* MakeUpperCase(char* aPath)
//----------------------------------------------------------------------------------------
{
// check if the Windows is DBCSEnabled once.
if (PR_FALSE == gGlobalOSInitialized) {
}
// windows does not care about case. pu sh to uppercase:
int i = 0; /* C++ portability guide #20 */
if (!gGlobalDBCSEnabledOS) {
// for non-DBCS windows
for (i = 0; i < length; i++)
}
else {
// for DBCS windows
for (i = 0; i < length; i++) {
if (IsDBCSLeadByte(aPath[i])) {
// begining of the double bye char
i++;
}
else {
}
} //end of for loop
}
return aPath;
}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
{
if (gGetSpecialPathProc) {
return;
// Append the trailing slash
{
}
outDirectory = path;
return;
}
int len;
// Get the shell's allocator.
return;
// Allocate a buffer
return;
// Get the PIDL for the folder.
goto Clean;
goto Clean;
// Append the trailing slash
// Assign the directory
// Clean up.
if (pItemIDList)
if (pBuffer)
} // GetWindowsFolder
#endif // XP_WIN
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
{
aFileSpec = ".";
return;
} // GetCurrentWorkingDirectory
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
{
#if defined (XP_WIN)
// chop of the executable name by finding the rightmost backslash
if (lastSlash)
return;
}
char buffer[CCHMAXPATH];
return;
// get info for the the current process to determine the directory
// its located in
// initialize ProcessInfoRec before calling
// GetProcessInformation() or die horribly.
{
{
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 VBOX_XPCOM_HOME is defined, that is it
if (moz5)
{
return;
}
else
{
if(firstWarning) {
// Warn that VBOX_XPCOM_HOME not set, once.
printf("***Warning: VBOX_XPCOM_HOME not set.\n");
}
}
}
#endif /* DEBUG */
// In the absence of a good way to get the executable directory let
// us try this for unix:
// - if VBOX_XPCOM_HOME is defined, that is it
// - else give the current directory
char buf[MAXPATHLEN];
if (moz5)
{
return;
}
else
{
#if defined(DEBUG)
if(firstWarning) {
// Warn that VBOX_XPCOM_HOME not set, once.
printf("Warning: VBOX_XPCOM_HOME not set.\n");
}
#endif /* DEBUG */
// Fall back to current directory.
{
return;
}
}
if (moz5)
{
return;
}
else
{
static char buf[MAXPATHLEN];
char *p;
*buf = 0;
{
{
*p = 0;
return;
}
}
}
#endif
NS_ERROR("unable to get current process directory");
} // GetCurrentProcessDirectory()
//nsSpecialSystemDirectory::nsSpecialSystemDirectory()
//: nsFileSpec(nsnull)
//{
//}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
: nsFileSpec(nsnull)
{
*this = aSystemSystemDirectory;
}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
{
// 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.
#ifdef XP_MAC
short vRefNum;
long dirID;
#endif
*this = (const char*)nsnull;
switch (aSystemSystemDirectory)
{
case OS_DriveDirectory:
#if defined (XP_WIN)
{
if (len)
{
path[3] = 0;
}
*this = MakeUpperCase(path);
}
{
// printf( "*** Warning warning OS_DriveDirectory called for");
ULONG ulBootDrive = 0;
char buffer[] = " :\\OS2\\";
&ulBootDrive, sizeof ulBootDrive);
*this = buffer;
#ifdef DEBUG
#endif
}
{
*this = kVolumeRootFolderType;
}
#else
*this = "/";
#endif
break;
case OS_TemporaryDirectory:
#if defined (XP_WIN)
{
*this = MakeUpperCase(path);
}
{
char *c = getenv( "TMP");
else
{
c = getenv( "TEMP");
}
if( c) *this = buffer;
// use exe's directory if not set
else GetCurrentProcessDirectory(*this);
}
*this = kTemporaryFolderType;
{
if (!tPath) {
tPath = "/tmp/";
}
}
}
}
*this = tPath;
}
#endif
break;
GetCurrentProcessDirectory(*this);
break;
GetCurrentWorkingDirectory(*this);
break;
{
// if someone has called nsSpecialSystemDirectory::Set()
if (systemDirectoriesLocations) {
// look for the value for the argument key
// if not found, try Moz_BinDirectory
dirSpec = (nsFileSpec *)
}
else {
// if the value is found for the argument key,
// we don't need to append.
}
}
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;
{
// if someone has called nsSpecialSystemDirectory::Set()
if (systemDirectoriesLocations) {
// look for the value for the argument key
// if not found, try Moz_BinDirectory
dirSpec = (nsFileSpec *)
}
else {
// if the value is found for the argument key,
// we don't need to append.
}
}
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:
{
// if someone has called nsSpecialSystemDirectory::Set()
if (systemDirectoriesLocations) {
// look for the value for the argument key
dirSpec = (nsFileSpec *)
}
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;
*this = kControlPanelFolderType;
break;
case Mac_ExtensionDirectory:
*this = kExtensionFolderType;
break;
case Mac_FontsDirectory:
*this = kFontsFolderType;
break;
{
// whether Mac OS X or pre-Mac OS X, return Classic's Prefs folder
short domain;
long response;
if (!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
if (!err) {
}
break;
}
case Mac_DocumentsDirectory:
*this = kDocumentsFolderType;
break;
*this = kInternetSearchSitesFolderType;
break;
*this = kDefaultDownloadFolderType;
break;
case Mac_UserLibDirectory:
{
if (!err) {
}
break;
}
#endif
#if defined (XP_WIN)
case Win_SystemDirectory:
{
// Need enough space to add the trailing backslash
break;
*this = MakeUpperCase(path);
break;
}
case Win_WindowsDirectory:
{
// Need enough space to add the trailing backslash
break;
*this = MakeUpperCase(path);
break;
}
case Win_HomeDirectory:
{
{
// Need enough space to add the trailing backslash
break;
*this = MakeUpperCase(path);
break;
}
{
// Need enough space to add the trailing backslash
break;
*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;
}
{
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:
break;
case Unix_LibDirectory:
break;
case Unix_HomeDirectory:
#ifdef VMS
{
char *pHome;
if (*pHome == '/')
*this = pHome;
else
}
#else
*this = PR_GetEnv("HOME");
#endif
break;
#endif
#ifdef XP_BEOS
case BeOS_SettingsDirectory:
{
char path[MAXPATHLEN];
// Need enough space to add the trailing backslash
break;
*this = path;
break;
}
case BeOS_HomeDirectory:
{
char path[MAXPATHLEN];
// Need enough space to add the trailing backslash
break;
*this = path;
break;
}
case BeOS_DesktopDirectory:
{
char path[MAXPATHLEN];
// Need enough space to add the trailing backslash
break;
*this = path;
break;
}
case BeOS_SystemDirectory:
{
char path[MAXPATHLEN];
// Need enough space to add the trailing backslash
break;
*this = path;
break;
}
#endif
#ifdef XP_OS2
case OS2_SystemDirectory:
{
ULONG ulBootDrive = 0;
char buffer[] = " :\\OS2\\System\\";
&ulBootDrive, sizeof ulBootDrive);
*this = buffer;
#ifdef DEBUG
#endif
break;
}
case OS2_OS2Directory:
{
ULONG ulBootDrive = 0;
char buffer[] = " :\\OS2\\";
&ulBootDrive, sizeof ulBootDrive);
*this = buffer;
#ifdef DEBUG
#endif
break;
}
case OS2_HomeDirectory:
{
/* If MOZILLA_HOME is not set, use GetCurrentProcessDirectory */
/* To ensure we get a long filename system */
GetCurrentProcessDirectory(*this);
else
*this = tPath;
break;
}
case OS2_DesktopDirectory:
{
break;
#ifdef DEBUG
if (fSuccess) {
} else {
}
#endif
break;
}
#endif
default:
break;
}
}
void
{
if (NULL == systemDirectoriesLocations) {
}
}
return;
}
#if defined(XP_MAC)
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
{
*this = folderType;
}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
{
// hack: first check for kDefaultDownloadFolderType
// if it is, get Internet Config Download folder, if that's
// not availble use desktop folder
if (folderType == kDefaultDownloadFolderType)
{
if (icService)
{
return;
else
}
else
{
}
}
// Call FindFolder to fill in the vrefnum and dirid
{
true,
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";
break;
} // switch
} // for
filename[0] = '\0';
if (NS_SUCCEEDED(mError))
{
}
}
#endif // XP_MAC