Bug 396209 - "Allow applications to specify a profile directory from application.ini". r=luser, a=bsmedberg. Also fixes bugs 396486, 396199, and 386164.
This commit is contained in:
Родитель
e89341d757
Коммит
540f0153bf
|
@ -561,17 +561,17 @@ nsresult nsProfileLock::Lock(nsILocalFile* aProfileDir,
|
|||
}
|
||||
|
||||
#elif defined(XP_WIN)
|
||||
nsCAutoString filePath;
|
||||
rv = lockFile->GetNativePath(filePath);
|
||||
nsAutoString filePath;
|
||||
rv = lockFile->GetPath(filePath);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
mLockFileHandle = CreateFile(filePath.get(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0, // no sharing - of course
|
||||
nsnull,
|
||||
OPEN_ALWAYS,
|
||||
FILE_FLAG_DELETE_ON_CLOSE,
|
||||
nsnull);
|
||||
mLockFileHandle = CreateFileW(filePath.get(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0, // no sharing - of course
|
||||
nsnull,
|
||||
OPEN_ALWAYS,
|
||||
FILE_FLAG_DELETE_ON_CLOSE,
|
||||
nsnull);
|
||||
if (mLockFileHandle == INVALID_HANDLE_VALUE) {
|
||||
// XXXbsmedberg: provide a profile-unlocker here!
|
||||
return NS_ERROR_FILE_ACCESS_DENIED;
|
||||
|
|
|
@ -413,9 +413,22 @@ int main(int argc, char** argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
string product = queryParameters["ProductName"];
|
||||
string vendor = queryParameters["Vendor"];
|
||||
if (!UIGetSettingsPath(vendor, product, gSettingsPath)) {
|
||||
// Hopefully the settings path exists in the environment. Try that before
|
||||
// asking the platform-specific code to guess.
|
||||
static const char kDataDirKey[] = "MOZ_CRASHREPORTER_DATA_DIRECTORY";
|
||||
const char *settingsPath = getenv(kDataDirKey);
|
||||
if (settingsPath && *settingsPath) {
|
||||
gSettingsPath = settingsPath;
|
||||
}
|
||||
else {
|
||||
string product = queryParameters["ProductName"];
|
||||
string vendor = queryParameters["Vendor"];
|
||||
if (!UIGetSettingsPath(vendor, product, gSettingsPath)) {
|
||||
gSettingsPath.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (gSettingsPath.empty() || !UIEnsurePathExists(gSettingsPath)) {
|
||||
UIError(gStrings[ST_ERROR_NOSETTINGSPATH]);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -296,7 +296,7 @@ static void TryInitGnome()
|
|||
gnomeuiLib = dlopen("libgnomeui-2.so.0", RTLD_LAZY);
|
||||
if (!gnomeuiLib)
|
||||
return;
|
||||
|
||||
|
||||
_gnome_program_init_fn gnome_program_init =
|
||||
(_gnome_program_init_fn)(dlsym(gnomeLib, "gnome_program_init"));
|
||||
_libgnomeui_module_info_get_fn libgnomeui_module_info_get =
|
||||
|
@ -495,7 +495,7 @@ bool UIGetSettingsPath(const string& vendor,
|
|||
string& settingsPath)
|
||||
{
|
||||
char* home = getenv("HOME");
|
||||
|
||||
|
||||
if (!home)
|
||||
return false;
|
||||
|
||||
|
@ -504,14 +504,14 @@ bool UIGetSettingsPath(const string& vendor,
|
|||
if (!vendor.empty()) {
|
||||
string lc_vendor;
|
||||
std::transform(vendor.begin(), vendor.end(), back_inserter(lc_vendor),
|
||||
(int(*)(int)) std::tolower);
|
||||
(int(*)(int)) std::tolower);
|
||||
settingsPath += lc_vendor + "/";
|
||||
}
|
||||
string lc_product;
|
||||
std::transform(product.begin(), product.end(), back_inserter(lc_product),
|
||||
(int(*)(int)) std::tolower);
|
||||
(int(*)(int)) std::tolower);
|
||||
settingsPath += lc_product + "/Crash Reports";
|
||||
return UIEnsurePathExists(settingsPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UIEnsurePathExists(const string& path)
|
||||
|
@ -553,4 +553,3 @@ std::ofstream* UIOpenWrite(const string& filename)
|
|||
{
|
||||
return new std::ofstream(filename.c_str(), std::ios::out);
|
||||
}
|
||||
|
||||
|
|
|
@ -494,9 +494,6 @@ bool UIGetSettingsPath(const string& vendor,
|
|||
|
||||
settingsPath = [destPath UTF8String];
|
||||
|
||||
if (!UIEnsurePathExists(settingsPath))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -697,9 +697,11 @@ void UIShowCrashUI(const string& dumpFile,
|
|||
}
|
||||
|
||||
if (gQueryParameters.find(L"Vendor") != gQueryParameters.end()) {
|
||||
gCrashReporterKey = L"Software\\" +
|
||||
gQueryParameters[L"Vendor"] +
|
||||
L"\\Crash Reporter";
|
||||
gCrashReporterKey = L"Software\\";
|
||||
if (!gQueryParameters[L"Vendor"].empty()) {
|
||||
gCrashReporterKey += gQueryParameters[L"Vendor"] + L"\\";
|
||||
}
|
||||
gCrashReporterKey += gQueryParameters[L"Name"] + L"\\Crash Reporter";
|
||||
}
|
||||
|
||||
gRestartArgs = restartArgs;
|
||||
|
@ -749,8 +751,6 @@ bool UIGetSettingsPath(const string& vendor,
|
|||
}
|
||||
PathAppend(path, UTF8ToWide(product).c_str());
|
||||
PathAppend(path, L"Crash Reports");
|
||||
// in case it doesn't exist
|
||||
CreateDirectory(path, NULL);
|
||||
settings_path = WideToUTF8(path);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ bool MinidumpCallback(const XP_CHAR* dump_path,
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(XP_WIN32)
|
||||
XP_CHAR cmdLine[CMDLINE_SIZE];
|
||||
size = CMDLINE_SIZE;
|
||||
|
@ -484,7 +484,7 @@ typedef nsresult (*InitDataFunc)(nsACString&);
|
|||
// Attempt to read aFile's contents into aContents, if aFile
|
||||
// does not exist, create it and initialize its contents
|
||||
// by calling aInitFunc for the data.
|
||||
static nsresult
|
||||
static nsresult
|
||||
GetOrInit(nsIFile* aDir, const nsACString& filename,
|
||||
nsACString& aContents, InitDataFunc aInitFunc)
|
||||
{
|
||||
|
@ -537,7 +537,7 @@ InitUserID(nsACString& aUserID)
|
|||
CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
|
||||
if (!uuid)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid);
|
||||
memcpy(&id, &bytes, sizeof(nsID));
|
||||
|
||||
|
@ -553,7 +553,7 @@ InitUserID(nsACString& aUserID)
|
|||
|
||||
nsCAutoString id_str(id.ToString());
|
||||
aUserID = Substring(id_str, 1, id_str.Length()-2);
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -566,7 +566,7 @@ InitInstallTime(nsACString& aInstallTime)
|
|||
char buf[16];
|
||||
sprintf(buf, "%ld", t);
|
||||
aInstallTime = buf;
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -594,6 +594,28 @@ nsresult SetupExtraData(nsILocalFile* aAppDataDirectory,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Save this path in the environment for the crash reporter application.
|
||||
nsCAutoString dataDirEnv("MOZ_CRASHREPORTER_DATA_DIRECTORY=");
|
||||
|
||||
#if defined(XP_WIN32)
|
||||
nsAutoString dataDirectoryPath;
|
||||
rv = dataDirectory->GetPath(dataDirectoryPath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
AppendUTF16toUTF8(dataDirectoryPath, dataDirEnv);
|
||||
#else
|
||||
nsCAutoString dataDirectoryPath;
|
||||
rv = dataDirectory->GetNativePath(dataDirectoryPath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
dataDirEnv.Append(dataDirectoryPath);
|
||||
#endif
|
||||
|
||||
char* env = ToNewCString(dataDirEnv);
|
||||
NS_ENSURE_TRUE(env, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
PR_SetEnv(env);
|
||||
|
||||
nsCAutoString data;
|
||||
if(NS_SUCCEEDED(GetOrInit(dataDirectory, NS_LITERAL_CSTRING("UserID"),
|
||||
data, InitUserID)))
|
||||
|
@ -668,7 +690,7 @@ static void ReplaceChar(nsCString& str, const nsACString& character,
|
|||
const nsACString& replacement)
|
||||
{
|
||||
nsCString::const_iterator start, end;
|
||||
|
||||
|
||||
str.BeginReading(start);
|
||||
str.EndReading(end);
|
||||
|
||||
|
@ -713,7 +735,7 @@ nsresult AnnotateCrashReport(const nsACString &key, const nsACString &data)
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCString escapedData(data);
|
||||
|
||||
|
||||
// escape backslashes
|
||||
ReplaceChar(escapedData, NS_LITERAL_CSTRING("\\"),
|
||||
NS_LITERAL_CSTRING("\\\\"));
|
||||
|
|
|
@ -78,6 +78,7 @@ ScopedAppData::ScopedAppData(const nsXREAppData* aAppData)
|
|||
SetAllocatedString(this->buildID, aAppData->buildID);
|
||||
SetAllocatedString(this->ID, aAppData->ID);
|
||||
SetAllocatedString(this->copyright, aAppData->copyright);
|
||||
SetAllocatedString(this->profile, aAppData->profile);
|
||||
SetStrongPtr(this->directory, aAppData->directory);
|
||||
this->flags = aAppData->flags;
|
||||
|
||||
|
@ -100,6 +101,7 @@ ScopedAppData::~ScopedAppData()
|
|||
SetAllocatedString(this->buildID, nsnull);
|
||||
SetAllocatedString(this->ID, nsnull);
|
||||
SetAllocatedString(this->copyright, nsnull);
|
||||
SetAllocatedString(this->profile, nsnull);
|
||||
|
||||
NS_IF_RELEASE(this->directory);
|
||||
|
||||
|
@ -208,6 +210,7 @@ XRE_ParseAppData(nsILocalFile* aINIFile, nsXREAppData *aAppData)
|
|||
{ "App", "BuildID", &aAppData->buildID },
|
||||
{ "App", "ID", &aAppData->ID },
|
||||
{ "App", "Copyright", &aAppData->copyright },
|
||||
{ "App", "Profile", &aAppData->profile },
|
||||
{ nsnull }
|
||||
};
|
||||
ReadStrings(parser, strings);
|
||||
|
|
|
@ -62,13 +62,14 @@
|
|||
#include "nsCOMArray.h"
|
||||
#include "nsArrayEnumerator.h"
|
||||
#include "nsEnumeratorUtils.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
// This is not defined by VC6.
|
||||
// This is not defined by VC6.
|
||||
#ifndef CSIDL_LOCAL_APPDATA
|
||||
#define CSIDL_LOCAL_APPDATA 0x001C
|
||||
#endif
|
||||
|
@ -132,7 +133,7 @@ nsXREDirProvider::SetProfile(nsIFile* aDir, nsIFile* aLocalDir)
|
|||
NS_ASSERTION(aDir && aLocalDir, "We don't support no-profile apps yet!");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
|
||||
rv = EnsureDirectoryExists(aDir);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -507,7 +508,7 @@ nsXREDirProvider::GetFiles(const char* aProperty, nsISimpleEnumerator** aResult)
|
|||
|
||||
static void
|
||||
LoadExtensionDirectories(nsINIParser &parser,
|
||||
const char *aSection,
|
||||
const char *aSection,
|
||||
nsCOMArray<nsIFile> &aDirectories)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -583,7 +584,7 @@ nsXREDirProvider::LoadAppBundleDirs()
|
|||
nsresult rv = mXULAppDir->Clone(getter_AddRefs(dir));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
|
||||
dir->AppendNative(NS_LITERAL_CSTRING("distribution"));
|
||||
dir->AppendNative(NS_LITERAL_CSTRING("bundles"));
|
||||
|
||||
|
@ -633,7 +634,7 @@ nsXREDirProvider::GetFilesInternal(const char* aProperty,
|
|||
|
||||
if (!strcmp(aProperty, XRE_EXTENSIONS_DIR_LIST)) {
|
||||
nsCOMArray<nsIFile> directories;
|
||||
|
||||
|
||||
static const char *const kAppendNothing[] = { nsnull };
|
||||
|
||||
LoadBundleDirectories();
|
||||
|
@ -712,7 +713,7 @@ nsXREDirProvider::GetFilesInternal(const char* aProperty,
|
|||
manifests);
|
||||
|
||||
rv = NS_NewArrayEnumerator(aResult, manifests);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(aProperty, NS_SKIN_MANIFESTS_FILE_LIST)) {
|
||||
nsCOMArray<nsIFile> manifests;
|
||||
|
||||
|
@ -850,29 +851,26 @@ nsXREDirProvider::DoShutdown()
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GetProfileFolderName(char* aProfileFolderName, const char* aSource)
|
||||
{
|
||||
const char* reading = aSource;
|
||||
|
||||
while (*reading) {
|
||||
*aProfileFolderName = tolower(*reading);
|
||||
++aProfileFolderName; ++reading;
|
||||
}
|
||||
*aProfileFolderName = '\0';
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
static nsresult
|
||||
GetShellFolderPath(int folder, char result[MAXPATHLEN])
|
||||
GetShellFolderPath(int folder, nsAString& _retval)
|
||||
{
|
||||
LPITEMIDLIST pItemIDList = NULL;
|
||||
|
||||
PRUnichar* buf;
|
||||
PRUint32 bufLength = _retval.GetMutableData(&buf, MAXPATHLEN);
|
||||
NS_ENSURE_TRUE(bufLength >= MAXPATHLEN, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv;
|
||||
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, folder, &pItemIDList)) &&
|
||||
SUCCEEDED(SHGetPathFromIDList(pItemIDList, result))) {
|
||||
SHGetPathFromIDListW(pItemIDList, buf)) {
|
||||
// We're going to use wcslen (wcsnlen not available in msvc7.1) so make
|
||||
// sure to null terminate.
|
||||
buf[bufLength - 1] = L'\0';
|
||||
_retval.SetLength(wcslen(buf));
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
_retval.SetLength(0);
|
||||
rv = NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
|
@ -885,18 +883,23 @@ nsresult
|
|||
nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
|
||||
{
|
||||
nsCOMPtr<nsIFile> appDir = GetAppDir();
|
||||
nsCAutoString appPath;
|
||||
nsresult rv = appDir->GetNativePath(appPath);
|
||||
|
||||
nsAutoString appPath;
|
||||
nsresult rv = appDir->GetPath(appPath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// AppDir may be a short path. Convert to long path to make sure
|
||||
// the consistency of the update folder location
|
||||
nsCString longPath;
|
||||
char *buf;
|
||||
longPath.GetMutableData(&buf, MAXPATHLEN);
|
||||
DWORD len = GetLongPathName(appPath.get(), buf, MAXPATHLEN);
|
||||
nsString longPath;
|
||||
PRUnichar* buf;
|
||||
|
||||
PRUint32 bufLength = longPath.GetMutableData(&buf, MAXPATHLEN);
|
||||
NS_ENSURE_TRUE(bufLength >= MAXPATHLEN, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
DWORD len = GetLongPathNameW(appPath.get(), buf, bufLength);
|
||||
|
||||
// Failing GetLongPathName() is not fatal.
|
||||
if (len <= 0 || len >= MAXPATHLEN)
|
||||
if (len <= 0 || len >= bufLength)
|
||||
longPath.Assign(appPath);
|
||||
else
|
||||
longPath.SetLength(len);
|
||||
|
@ -904,25 +907,24 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
|
|||
// Use <UserLocalDataDir>\updates\<relative path to app dir from
|
||||
// Program Files> if app dir is under Program Files to avoid the
|
||||
// folder virtualization mess on Windows Vista
|
||||
char programFiles[MAXPATHLEN];
|
||||
nsAutoString programFiles;
|
||||
rv = GetShellFolderPath(CSIDL_PROGRAM_FILES, programFiles);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 programFilesLen = strlen(programFiles);
|
||||
programFiles[programFilesLen++] = '\\';
|
||||
programFiles[programFilesLen] = '\0';
|
||||
programFiles.AppendLiteral("\\");
|
||||
PRUint32 programFilesLen = programFiles.Length();
|
||||
|
||||
if (longPath.Length() < programFilesLen)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (_strnicmp(programFiles, longPath.get(), programFilesLen) != 0)
|
||||
if (_wcsnicmp(programFiles.get(), longPath.get(), programFilesLen) != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsILocalFile> updRoot;
|
||||
rv = GetUserLocalDataDirectory(getter_AddRefs(updRoot));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = updRoot->AppendRelativeNativePath(Substring(longPath, programFilesLen));
|
||||
rv = updRoot->AppendRelativePath(Substring(longPath, programFilesLen));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*aResult = updRoot);
|
||||
|
@ -988,11 +990,11 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
|
|||
if (aLocal) {
|
||||
folderType = kCachedDataFolderType;
|
||||
} else {
|
||||
#ifdef MOZ_THUNDERBIRD
|
||||
#ifdef MOZ_THUNDERBIRD
|
||||
folderType = kDomainLibraryFolderType;
|
||||
#else
|
||||
folderType = kApplicationSupportFolderType;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
|
||||
NS_ENSURE_FALSE(err, NS_ERROR_FAILURE);
|
||||
|
@ -1006,39 +1008,16 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
|
|||
rv = dirFileMac->InitWithFSRef(&fsRef);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Note that MacOS ignores the vendor when creating the profile hierarchy - all
|
||||
// application preferences directories live alongside one another in
|
||||
// ~/Library/Application Support/
|
||||
rv = dirFileMac->AppendNative(nsDependentCString(gAppData->name));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
localDir = do_QueryInterface(dirFileMac, &rv);
|
||||
#elif defined(XP_WIN)
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
// CSIDL_LOCAL_APPDATA is only defined on newer versions of Windows. If the
|
||||
// OS does not understand it, then we'll fallback to the regular APPDATA
|
||||
// location. If neither is defined, then we fallback to the Windows folder.
|
||||
|
||||
nsString path;
|
||||
if (aLocal)
|
||||
rv = GetShellFolderPath(CSIDL_LOCAL_APPDATA, path);
|
||||
if (!aLocal || NS_FAILED(rv))
|
||||
rv = GetShellFolderPath(CSIDL_APPDATA, path);
|
||||
|
||||
if (NS_FAILED(rv) && !GetWindowsDirectory(path, sizeof(path))) {
|
||||
NS_WARNING("Aaah, no windows directory!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(path),
|
||||
PR_TRUE, getter_AddRefs(localDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (gAppData->vendor) {
|
||||
rv = localDir->AppendNative(nsDependentCString(gAppData->vendor));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
rv = localDir->AppendNative(nsDependentCString(gAppData->name));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = NS_NewLocalFile(path, PR_TRUE, getter_AddRefs(localDir));
|
||||
#elif defined(XP_OS2)
|
||||
#if 0 /* For OS/2 we want to always use MOZILLA_HOME */
|
||||
// we want an environment variable of the form
|
||||
|
@ -1061,15 +1040,6 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
|
|||
*strrchr(appDir, '\\') = '\0';
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(appDir), PR_TRUE, getter_AddRefs(localDir));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (gAppData->vendor) {
|
||||
rv = localDir->AppendNative(nsDependentCString(gAppData->vendor));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
rv = localDir->AppendNative(nsDependentCString(gAppData->name));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#elif defined(XP_BEOS)
|
||||
char appDir[MAXPATHLEN];
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, NULL, true, appDir, MAXPATHLEN))
|
||||
|
@ -1081,15 +1051,6 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
|
|||
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(appDir), PR_TRUE,
|
||||
getter_AddRefs(localDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (gAppData->vendor) {
|
||||
rv = localDir->AppendNative(nsDependentCString(gAppData->vendor));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
rv = localDir->AppendNative(nsDependentCString(gAppData->name));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
const char* homeDir = getenv("HOME");
|
||||
if (!homeDir || !*homeDir)
|
||||
|
@ -1097,32 +1058,13 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
|
|||
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), PR_TRUE,
|
||||
getter_AddRefs(localDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
char* appNameFolder = nsnull;
|
||||
char profileFolderName[MAXPATHLEN] = ".";
|
||||
|
||||
// Offset 1 for the outermost folder to make it hidden (i.e. using the ".")
|
||||
char* writing = profileFolderName + 1;
|
||||
if (gAppData->vendor) {
|
||||
GetProfileFolderName(writing, gAppData->vendor);
|
||||
|
||||
rv = localDir->AppendNative(nsDependentCString(profileFolderName));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
char temp[MAXPATHLEN];
|
||||
GetProfileFolderName(temp, gAppData->name);
|
||||
appNameFolder = temp;
|
||||
}
|
||||
else {
|
||||
GetProfileFolderName(writing, gAppData->name);
|
||||
appNameFolder = profileFolderName;
|
||||
}
|
||||
rv = localDir->AppendNative(nsDependentCString(appNameFolder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
#else
|
||||
#error dont_know_how_to_get_product_dir_on_your_platform
|
||||
#error "Don't know how to get product dir on your platform"
|
||||
#endif
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = AppendProfilePath(localDir);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef DEBUG_jungshik
|
||||
nsCAutoString cwd;
|
||||
|
@ -1132,8 +1074,7 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
|
|||
rv = EnsureDirectoryExists(localDir);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aFile = localDir;
|
||||
NS_ADDREF(*aFile);
|
||||
NS_ADDREF(*aFile = localDir);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1165,10 +1106,10 @@ nsXREDirProvider::EnsureProfileFileExists(nsIFile *aFile)
|
|||
{
|
||||
nsresult rv;
|
||||
PRBool exists;
|
||||
|
||||
|
||||
rv = aFile->Exists(&exists);
|
||||
if (NS_FAILED(rv) || exists) return;
|
||||
|
||||
|
||||
nsCAutoString leafName;
|
||||
rv = aFile->GetNativeLeafName(leafName);
|
||||
if (NS_FAILED(rv)) return;
|
||||
|
@ -1179,7 +1120,7 @@ nsXREDirProvider::EnsureProfileFileExists(nsIFile *aFile)
|
|||
|
||||
rv = defaultsFile->AppendNative(leafName);
|
||||
if (NS_FAILED(rv)) return;
|
||||
|
||||
|
||||
defaultsFile->CopyToNative(mProfileDir, EmptyCString());
|
||||
}
|
||||
|
||||
|
@ -1196,10 +1137,107 @@ nsXREDirProvider::GetProfileDefaultsDir(nsIFile* *aResult)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = defaultsDir->AppendNative(NS_LITERAL_CSTRING("defaults"));
|
||||
rv |= defaultsDir->AppendNative(NS_LITERAL_CSTRING("profile"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = defaultsDir->AppendNative(NS_LITERAL_CSTRING("profile"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*aResult = defaultsDir);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXREDirProvider::AppendProfilePath(nsIFile* aFile)
|
||||
{
|
||||
NS_ASSERTION(aFile, "Null pointer!");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
#if defined (XP_MACOSX)
|
||||
if (gAppData->profile) {
|
||||
rv = AppendProfileString(aFile, gAppData->profile);
|
||||
}
|
||||
else {
|
||||
// Note that MacOS ignores the vendor when creating the profile hierarchy -
|
||||
// all application preferences directories live alongside one another in
|
||||
// ~/Library/Application Support/
|
||||
rv = aFile->AppendNative(nsDependentCString(gAppData->name));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#elif defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
|
||||
if (gAppData->profile) {
|
||||
rv = AppendProfileString(aFile, gAppData->profile);
|
||||
}
|
||||
else {
|
||||
if (gAppData->vendor) {
|
||||
rv = aFile->AppendNative(nsDependentCString(gAppData->vendor));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
rv = aFile->AppendNative(nsDependentCString(gAppData->name));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
// Make it hidden (i.e. using the ".")
|
||||
nsCAutoString folder(".");
|
||||
|
||||
if (gAppData->profile) {
|
||||
// Skip any leading path characters
|
||||
const char* profileStart = gAppData->profile;
|
||||
while (*profileStart == '/' || *profileStart == '\\')
|
||||
profileStart++;
|
||||
|
||||
// On the off chance that someone wanted their folder to be hidden don't
|
||||
// let it become ".."
|
||||
if (*profileStart == '.')
|
||||
profileStart++;
|
||||
|
||||
folder.Append(profileStart);
|
||||
ToLowerCase(folder);
|
||||
|
||||
rv = AppendProfileString(aFile, folder.BeginReading());
|
||||
}
|
||||
else {
|
||||
if (gAppData->vendor) {
|
||||
folder.Append(gAppData->vendor);
|
||||
ToLowerCase(folder);
|
||||
|
||||
rv = aFile->AppendNative(folder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
folder.Truncate();
|
||||
}
|
||||
|
||||
folder.Append(gAppData->name);
|
||||
ToLowerCase(folder);
|
||||
|
||||
rv = aFile->AppendNative(folder);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#else
|
||||
#error "Don't know how to get profile path on your platform"
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXREDirProvider::AppendProfileString(nsIFile* aFile, const char* aPath)
|
||||
{
|
||||
NS_ASSERTION(aFile, "Null file!");
|
||||
NS_ASSERTION(aPath, "Null path!");
|
||||
|
||||
nsCAutoString pathDup(aPath);
|
||||
|
||||
char* path = pathDup.BeginWriting();
|
||||
|
||||
nsresult rv;
|
||||
char* subdir;
|
||||
while ((subdir = NS_strtok("/\\", &path))) {
|
||||
rv = aFile->AppendNative(nsDependentCString(subdir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
|
||||
/* make sure you clone it, if you need to do stuff to it */
|
||||
nsIFile* GetGREDir() { return mGREDir; }
|
||||
nsIFile* GetAppDir() {
|
||||
nsIFile* GetAppDir() {
|
||||
if (mXULAppDir)
|
||||
return mXULAppDir;
|
||||
return mGREDir;
|
||||
|
@ -119,6 +119,14 @@ protected:
|
|||
static nsresult EnsureDirectoryExists(nsIFile* aDirectory);
|
||||
void EnsureProfileFileExists(nsIFile* aFile);
|
||||
|
||||
// Determine the profile path within the UAppData directory. This is different
|
||||
// on every major platform.
|
||||
static nsresult AppendProfilePath(nsIFile* aFile);
|
||||
|
||||
// Internal helper that splits a path into components using the '/' and '\\'
|
||||
// delimiters.
|
||||
static inline nsresult AppendProfileString(nsIFile* aFile, const char* aPath);
|
||||
|
||||
// Calculate all bundle directories, including distribution bundles,
|
||||
// extensions, and themes
|
||||
void LoadBundleDirectories();
|
||||
|
|
|
@ -94,7 +94,7 @@ struct nsXREAppData
|
|||
*/
|
||||
const char *version;
|
||||
|
||||
/**
|
||||
/**
|
||||
* The application's build identifier, e.g. "2004051604"
|
||||
*/
|
||||
const char *buildID;
|
||||
|
@ -138,6 +138,23 @@ struct nsXREAppData
|
|||
* The server URL to send crash reports to.
|
||||
*/
|
||||
const char *crashReporterURL;
|
||||
|
||||
/**
|
||||
* The profile directory that will be used. Optional (may be null). Must not
|
||||
* be the empty string, must be ASCII. The path is split into components
|
||||
* along the path separator characters '/' and '\'.
|
||||
*
|
||||
* The application data directory ("UAppData", see below) is normally
|
||||
* composed as follows, where $HOME is platform-specific:
|
||||
*
|
||||
* UAppData = $HOME[/$vendor]/$name
|
||||
*
|
||||
* If present, the 'profile' string will be used instead of the combination of
|
||||
* vendor and name as follows:
|
||||
*
|
||||
* UAppData = $HOME/$profile
|
||||
*/
|
||||
const char *profile;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -164,11 +181,33 @@ struct nsXREAppData
|
|||
"@mozilla.org/xre/app-info;1"
|
||||
|
||||
/**
|
||||
* A directory service key which provides the platform-correct
|
||||
* "application data" directory.
|
||||
* Windows: Documents and Settings\<User>\Application Data\<Vendor>\<Application>
|
||||
* Unix: ~/.<vendor>/<application>
|
||||
* Mac: ~/Library/Application Supports/<Application>
|
||||
* A directory service key which provides the platform-correct "application
|
||||
* data" directory as follows, where $name and $vendor are as defined above and
|
||||
* $vendor is optional:
|
||||
*
|
||||
* Windows:
|
||||
* HOME = Documents and Settings\$USER\Application Data
|
||||
* UAppData = $HOME[\$vendor]\$name
|
||||
*
|
||||
* Unix:
|
||||
* HOME = ~
|
||||
* UAppData = $HOME/.[$vendor/]$name
|
||||
*
|
||||
* Mac:
|
||||
* HOME = ~
|
||||
* UAppData = $HOME/Library/Application Support/$name
|
||||
*
|
||||
* Note that the "profile" member above will change the value of UAppData as
|
||||
* follows:
|
||||
*
|
||||
* Windows:
|
||||
* UAppData = $HOME\$profile
|
||||
*
|
||||
* Unix:
|
||||
* UAppData = $HOME/.$profile
|
||||
*
|
||||
* Mac:
|
||||
* UAppData = $HOME/Library/Application Support/$profile
|
||||
*/
|
||||
#define XRE_USER_APP_DATA_DIR "UAppData"
|
||||
|
||||
|
@ -222,7 +261,7 @@ struct nsXREAppData
|
|||
*
|
||||
* @return A native result code suitable for returning from main().
|
||||
*
|
||||
* @note If the binary is linked against the standalone XPCOM glue,
|
||||
* @note If the binary is linked against the standalone XPCOM glue,
|
||||
* XPCOMGlueStartup() should be called before this method.
|
||||
*
|
||||
* @note XXXbsmedberg Nobody uses the glue yet, but there is a
|
||||
|
|
Загрузка…
Ссылка в новой задаче