зеркало из https://github.com/mozilla/gecko-dev.git
fixes bug 291033 "Enable support for profile temp directory on local filesystem" aka "delete my cache please" r=bsmedberg a=chofmann
This commit is contained in:
Родитель
cd3e3741b8
Коммит
2c230c7743
|
@ -385,7 +385,8 @@ nsProfileMigrator::ImportRegistryProfiles(const nsACString& aAppName)
|
|||
if (NS_FAILED(rv)) continue;
|
||||
|
||||
nsCOMPtr<nsIToolkitProfile> tprofile;
|
||||
profileSvc->CreateProfile(profileFile, nsDependentCString(profileName),
|
||||
profileSvc->CreateProfile(profileFile, nsnull,
|
||||
nsDependentCString(profileName),
|
||||
getter_AddRefs(tprofile));
|
||||
migrated = PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -253,7 +253,8 @@ nsProfileMigrator::ImportRegistryProfiles(const nsACString& aAppName)
|
|||
if (NS_FAILED(rv)) continue;
|
||||
|
||||
nsCOMPtr<nsIToolkitProfile> tprofile;
|
||||
profileSvc->CreateProfile(profileFile, nsDependentCString(profileName),
|
||||
profileSvc->CreateProfile(profileFile, nsnull,
|
||||
nsDependentCString(profileName),
|
||||
getter_AddRefs(tprofile));
|
||||
migrated = PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ CPPSRCS += \
|
|||
nsDiskCacheEntry.cpp \
|
||||
nsDiskCacheMap.cpp \
|
||||
nsDiskCacheStreams.cpp \
|
||||
nsDeleteDir.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsDeleteDir.h"
|
||||
|
||||
|
||||
|
||||
|
@ -342,16 +343,34 @@ nsCacheProfilePrefObserver::ReadPrefs(nsIPrefBranch* branch)
|
|||
getter_AddRefs(directory));
|
||||
if (NS_FAILED(rv)) {
|
||||
// try to get the profile directory (there may not be a profile yet)
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(directory));
|
||||
#if DEBUG
|
||||
if (NS_FAILED(rv)) {
|
||||
// use current process directory during development
|
||||
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
getter_AddRefs(directory));
|
||||
nsCOMPtr<nsIFile> profDir;
|
||||
NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(profDir));
|
||||
NS_GetSpecialDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR,
|
||||
getter_AddRefs(directory));
|
||||
if (!directory)
|
||||
directory = profDir;
|
||||
else if (profDir) {
|
||||
PRBool same;
|
||||
if (NS_SUCCEEDED(profDir->Equals(directory, &same)) && !same) {
|
||||
// We no longer store the cache directory in the main
|
||||
// profile directory, so we should cleanup the old one.
|
||||
rv = profDir->AppendNative(NS_LITERAL_CSTRING("Cache"));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool exists;
|
||||
if (NS_SUCCEEDED(profDir->Exists(&exists)) && exists)
|
||||
DeleteDir(profDir, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if DEBUG
|
||||
if (!directory) {
|
||||
// use current process directory during development
|
||||
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
getter_AddRefs(directory));
|
||||
}
|
||||
#endif
|
||||
if (directory)
|
||||
mDiskCacheParentDirectory = do_QueryInterface(directory, &rv);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* ***** 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@meer.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either 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 "nsDeleteDir.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsString.h"
|
||||
#include "prthread.h"
|
||||
|
||||
PR_STATIC_CALLBACK(void) DeleteDirThreadFunc(void *arg)
|
||||
{
|
||||
nsIFile *dir = NS_STATIC_CAST(nsIFile *, arg);
|
||||
dir->Remove(PR_TRUE);
|
||||
NS_RELEASE(dir);
|
||||
}
|
||||
|
||||
nsresult DeleteDir(nsIFile *dirIn, PRBool moveToTrash)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> trash, dir;
|
||||
|
||||
// Need to make a clone of this since we don't want to modify the input
|
||||
// file object.
|
||||
rv = dirIn->Clone(getter_AddRefs(dir));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (moveToTrash)
|
||||
{
|
||||
rv = GetTrashDir(dir, &trash);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIFile> subDir;
|
||||
rv = trash->Clone(getter_AddRefs(subDir));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = subDir->AppendNative(NS_LITERAL_CSTRING("Trash"));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = subDir->CreateUnique(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = dir->MoveToNative(subDir, EmptyCString());
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we want to pass a clone of the original off to the worker thread.
|
||||
trash.swap(dir);
|
||||
}
|
||||
|
||||
// Steal ownership of trash directory; let the thread release it.
|
||||
nsIFile *trashRef = nsnull;
|
||||
trash.swap(trashRef);
|
||||
|
||||
// now, invoke the worker thread
|
||||
PRThread *thread = PR_CreateThread(PR_USER_THREAD,
|
||||
DeleteDirThreadFunc,
|
||||
trashRef,
|
||||
PR_PRIORITY_LOW,
|
||||
PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD,
|
||||
0);
|
||||
if (!thread)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetTrashDir(nsIFile *target, nsCOMPtr<nsIFile> *result)
|
||||
{
|
||||
nsresult rv = target->Clone(getter_AddRefs(*result));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCAutoString leaf;
|
||||
rv = (*result)->GetNativeLeafName(leaf);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
leaf.AppendLiteral(".Trash");
|
||||
|
||||
return (*result)->SetNativeLeafName(leaf);
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* ***** 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@meer.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either 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 ***** */
|
||||
|
||||
#ifndef nsDeleteDir_h__
|
||||
#define nsDeleteDir_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsIFile;
|
||||
|
||||
/**
|
||||
* This routine attempts to delete a directory that may contain some files that
|
||||
* are still in use. This later point is only an issue on Windows and a few
|
||||
* other systems.
|
||||
*
|
||||
* If the moveToTrash parameter is true, then the process for deleting the
|
||||
* directory creates a sibling directory of the same name with the ".Trash"
|
||||
* suffix. It then attempts to move the given directory into the corresponding
|
||||
* trash folder (moving individual files if necessary). Next, it proceeds to
|
||||
* delete each file in the trash folder on a low-priority background thread.
|
||||
*
|
||||
* If the moveToTrash parameter is false, then the given directory is deleted
|
||||
* directly.
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) DeleteDir(nsIFile *dir, PRBool moveToTrash);
|
||||
|
||||
/**
|
||||
* This routine returns the trash directory corresponding to the given
|
||||
* directory.
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) GetTrashDir(nsIFile *dir, nsCOMPtr<nsIFile> *result);
|
||||
|
||||
#endif // nsDeleteDir_h__
|
|
@ -64,8 +64,6 @@
|
|||
#include "private/pprio.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include "nsDiskCacheDevice.h"
|
||||
#include "nsDiskCacheEntry.h"
|
||||
#include "nsDiskCacheMap.h"
|
||||
|
@ -76,6 +74,8 @@
|
|||
#include "nsCacheService.h"
|
||||
#include "nsCache.h"
|
||||
|
||||
#include "nsDeleteDir.h"
|
||||
|
||||
#include "nsICacheVisitor.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
@ -335,7 +335,6 @@ nsDiskCacheDevice::nsDiskCacheDevice()
|
|||
: mCacheCapacity(0)
|
||||
, mCacheMap(nsnull)
|
||||
, mInitialized(PR_FALSE)
|
||||
, mFirstInit(PR_TRUE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -367,7 +366,6 @@ nsDiskCacheDevice::Init()
|
|||
}
|
||||
|
||||
mInitialized = PR_TRUE;
|
||||
mFirstInit = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
||||
error_exit:
|
||||
|
@ -814,22 +812,6 @@ nsDiskCacheDevice::EvictEntries(const char * clientID)
|
|||
#endif
|
||||
|
||||
|
||||
// "Cache.Trash" directory is a sibling of the "Cache" directory
|
||||
nsresult
|
||||
nsDiskCacheDevice::GetCacheTrashDirectory(nsIFile ** result)
|
||||
{
|
||||
nsCOMPtr<nsIFile> cacheTrashDir;
|
||||
nsresult rv = mCacheDirectory->Clone(getter_AddRefs(cacheTrashDir));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = cacheTrashDir->SetNativeLeafName(NS_LITERAL_CSTRING("Cache.Trash"));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*result = cacheTrashDir.get();
|
||||
NS_ADDREF(*result);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsDiskCacheDevice::OpenDiskCache()
|
||||
{
|
||||
|
@ -838,48 +820,46 @@ nsDiskCacheDevice::OpenDiskCache()
|
|||
// Try opening cache map file.
|
||||
NS_ASSERTION(mCacheMap == nsnull, "leaking mCacheMap");
|
||||
mCacheMap = new nsDiskCacheMap;
|
||||
if (!mCacheMap) {
|
||||
if (!mCacheMap)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// if we don't have a cache directory, create one and open it
|
||||
PRBool cacheDirExists;
|
||||
rv = mCacheDirectory->Exists(&cacheDirExists);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
PRBool exists;
|
||||
rv = mCacheDirectory->Exists(&exists);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (cacheDirExists) {
|
||||
PRBool trashing = PR_FALSE;
|
||||
if (exists) {
|
||||
rv = mCacheMap->Open(mCacheDirectory);
|
||||
// move "corrupt" caches to trash
|
||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
rv = MoveCacheToTrash(nsnull); // ignore returned dir name
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
cacheDirExists = PR_FALSE;
|
||||
|
||||
} else if (NS_FAILED(rv)) return rv;
|
||||
rv = DeleteDir(mCacheDirectory, PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
exists = PR_FALSE;
|
||||
trashing = PR_TRUE;
|
||||
}
|
||||
else if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
// if we don't have a cache directory, create one and open it
|
||||
if (!cacheDirExists) {
|
||||
if (!exists) {
|
||||
rv = InitializeCacheDirectory();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (! mFirstInit) return NS_OK; // we're done
|
||||
|
||||
// Empty Cache Trash
|
||||
PRBool trashDirExists;
|
||||
nsCOMPtr<nsIFile> trashDir;
|
||||
rv = GetCacheTrashDirectory(getter_AddRefs(trashDir));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = trashDir->Exists(&trashDirExists);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (trashDirExists) {
|
||||
nsCOMArray<nsIFile> * trashList;
|
||||
rv = ListTrashContents(&trashList);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = DeleteFiles(trashList); // spin up thread to delete contents
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!trashing) {
|
||||
// delete any trash files leftover from a previous run
|
||||
nsCOMPtr<nsIFile> trashDir;
|
||||
GetTrashDir(mCacheDirectory, &trashDir);
|
||||
if (trashDir) {
|
||||
PRBool exists;
|
||||
if (NS_SUCCEEDED(trashDir->Exists(&exists)) && exists)
|
||||
DeleteDir(trashDir, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -889,193 +869,18 @@ nsDiskCacheDevice::OpenDiskCache()
|
|||
nsresult
|
||||
nsDiskCacheDevice::ClearDiskCache()
|
||||
{
|
||||
if (mBindery.ActiveBindings()) return NS_ERROR_CACHE_IN_USE;
|
||||
if (mBindery.ActiveBindings())
|
||||
return NS_ERROR_CACHE_IN_USE;
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> trashDir;
|
||||
nsCOMArray<nsIFile> * deleteList = new nsCOMArray<nsIFile>;
|
||||
if (!deleteList) return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsresult rv = Shutdown_Private(PR_FALSE); // false: don't bother flushing
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = Shutdown_Private(PR_FALSE); // false = don't bother flushing
|
||||
if (NS_FAILED(rv)) goto error_exit;
|
||||
rv = DeleteDir(mCacheDirectory, PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = MoveCacheToTrash(getter_AddRefs(trashDir));
|
||||
if (NS_FAILED(rv)) goto error_exit;
|
||||
rv = deleteList->AppendObject(trashDir);
|
||||
if (NS_FAILED(rv)) goto error_exit;
|
||||
rv = DeleteFiles(deleteList);
|
||||
if (NS_FAILED(rv)) goto error_exit;
|
||||
|
||||
rv = Init();
|
||||
return rv;
|
||||
|
||||
error_exit:
|
||||
delete deleteList;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// function passed to PR_CreateThread
|
||||
static void PR_CALLBACK
|
||||
DoDeleteFileList(void *arg)
|
||||
{
|
||||
nsCOMArray<nsIFile> * fileList = NS_STATIC_CAST(nsCOMArray<nsIFile> *, arg);
|
||||
nsresult rv;
|
||||
|
||||
// iterate over items in fileList, recursively deleting each
|
||||
PRInt32 count = fileList->Count();
|
||||
for (PRInt32 i=0; i<count; i++) {
|
||||
nsIFile * item = fileList->ObjectAt(i);
|
||||
CACHE_LOG_PATH(PR_LOG_ALWAYS, "deleting: %s\n", item);
|
||||
|
||||
rv = item->Remove(PR_TRUE);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failure cleaning up cache");
|
||||
}
|
||||
|
||||
delete fileList; // destroy nsCOMArray
|
||||
}
|
||||
|
||||
|
||||
#define DEFAULT_STACK_SIZE 0
|
||||
|
||||
nsresult
|
||||
nsDiskCacheDevice::DeleteFiles(nsCOMArray<nsIFile> * fileList)
|
||||
{
|
||||
// start up another thread to delete deleteDir
|
||||
PRThread * thread;
|
||||
thread = PR_CreateThread(PR_USER_THREAD,
|
||||
DoDeleteFileList,
|
||||
fileList,
|
||||
PR_PRIORITY_NORMAL,
|
||||
PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD,
|
||||
DEFAULT_STACK_SIZE);
|
||||
|
||||
if (!thread) return NS_ERROR_UNEXPECTED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ListTrashContents - return pointer to array of nsIFile to delete
|
||||
*/
|
||||
nsresult
|
||||
nsDiskCacheDevice::ListTrashContents(nsCOMArray<nsIFile> ** result)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> trashDir;
|
||||
*result = nsnull;
|
||||
|
||||
// does "Cache.Trash" directory exist?
|
||||
rv = GetCacheTrashDirectory(getter_AddRefs(trashDir));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
PRBool exists;
|
||||
rv = trashDir->Exists(&exists);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!exists) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMArray<nsIFile> * array = new nsCOMArray<nsIFile>;
|
||||
if (!array) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// iterate over trash directory building array of directory objects
|
||||
nsCOMPtr<nsISimpleEnumerator> dirEntries;
|
||||
nsCOMPtr<nsIFile> item;
|
||||
PRBool more, success;
|
||||
|
||||
rv = trashDir->GetDirectoryEntries(getter_AddRefs(dirEntries));
|
||||
if (NS_FAILED(rv) || !dirEntries) goto error_exit; // !dirEntries returns NS_OK
|
||||
|
||||
rv = dirEntries->HasMoreElements(&more);
|
||||
if (NS_FAILED(rv)) goto error_exit;
|
||||
|
||||
while (more) {
|
||||
rv = dirEntries->GetNext(getter_AddRefs(item));
|
||||
if (NS_FAILED(rv)) goto error_exit;
|
||||
|
||||
success = array->AppendObject(item);
|
||||
if (!success) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
rv = dirEntries->HasMoreElements(&more);
|
||||
if (NS_FAILED(rv)) goto error_exit;
|
||||
}
|
||||
|
||||
// return resulting array
|
||||
*result = array;
|
||||
return NS_OK;
|
||||
|
||||
error_exit:
|
||||
delete array;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// Move 'Cache' dir into unique directory inside 'Cache.Trash', return name of unique directory
|
||||
nsresult
|
||||
nsDiskCacheDevice::MoveCacheToTrash(nsIFile ** result)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> trashDir;
|
||||
|
||||
if (result) *result = nsnull;
|
||||
|
||||
rv = GetCacheTrashDirectory(getter_AddRefs(trashDir));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// verify cache.trash exists and is a directory
|
||||
PRBool exists;
|
||||
rv = trashDir->Exists(&exists);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (exists) {
|
||||
PRBool isDirectory;
|
||||
rv = trashDir->IsDirectory(&isDirectory);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!isDirectory) {
|
||||
// delete file or fail
|
||||
rv = trashDir->Remove(PR_FALSE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
exists = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
// cache.trash doesn't exists, so create it
|
||||
rv = trashDir->Create(nsIFile::DIRECTORY_TYPE, 0777);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// create unique directory
|
||||
nsCOMPtr<nsIFile> uniqueDir;
|
||||
rv = trashDir->Clone(getter_AddRefs(uniqueDir));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = uniqueDir->AppendNative(NS_LITERAL_CSTRING("Trash"));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = uniqueDir->CreateUnique(nsIFile::DIRECTORY_TYPE, 0777);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// move cache directory into unique trash directory
|
||||
nsCOMPtr<nsIFile> parentDir;
|
||||
|
||||
rv = mCacheDirectory->GetParent(getter_AddRefs(parentDir));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mCacheDirectory->MoveToNative(uniqueDir, EmptyCString());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// set mCacheDirectory to point to parentDir/Cache/ again
|
||||
rv = parentDir->AppendNative(NS_LITERAL_CSTRING("Cache"));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mCacheDirectory = do_QueryInterface(parentDir);
|
||||
|
||||
// return unique directory, in case caller wants specifically delete it
|
||||
if (result)
|
||||
NS_ADDREF(*result = uniqueDir);
|
||||
return NS_OK;
|
||||
return Init();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -110,12 +110,8 @@ private:
|
|||
* Private methods
|
||||
*/
|
||||
|
||||
nsresult GetCacheTrashDirectory(nsIFile ** result);
|
||||
nsresult OpenDiskCache();
|
||||
nsresult ClearDiskCache();
|
||||
nsresult DeleteFiles(nsCOMArray<nsIFile> * fileList);
|
||||
nsresult ListTrashContents(nsCOMArray<nsIFile> ** result);
|
||||
nsresult MoveCacheToTrash(nsIFile ** result);
|
||||
nsresult InitializeCacheDirectory();
|
||||
|
||||
|
||||
|
@ -129,7 +125,6 @@ private:
|
|||
PRUint32 mCacheCapacity; // XXX need soft/hard limits, currentTotal
|
||||
nsDiskCacheMap * mCacheMap;
|
||||
PRPackedBool mInitialized;
|
||||
PRPackedBool mFirstInit;
|
||||
};
|
||||
|
||||
#endif // _nsDiskCacheDevice_h_
|
||||
|
|
|
@ -224,7 +224,7 @@ function onFinish()
|
|||
|
||||
// Create profile named profileName in profileRoot.
|
||||
try {
|
||||
profile = gProfileService.createProfile(gProfileRoot, profileName);
|
||||
profile = gProfileService.createProfile(gProfileRoot, null, profileName);
|
||||
}
|
||||
catch (e) {
|
||||
var profileCreationFailed =
|
||||
|
|
|
@ -45,11 +45,27 @@ interface nsIProfileUnlocker;
|
|||
* Hold on to a profile lock. Once you release the last reference to this
|
||||
* interface, the profile lock is released.
|
||||
*/
|
||||
[scriptable, uuid(6f987826-e4dd-453d-bb66-a1e46088fced)]
|
||||
[scriptable, uuid(50e07b0a-f338-4da3-bcdb-f4bb0db94dbe)]
|
||||
interface nsIProfileLock : nsISupports
|
||||
{
|
||||
/**
|
||||
* The main profile directory.
|
||||
*/
|
||||
readonly attribute nsILocalFile directory;
|
||||
|
||||
/**
|
||||
* A directory corresponding to the main profile directory that exists for
|
||||
* the purpose of storing data on the local filesystem, including cache
|
||||
* files or other data files that may not represent critical user data.
|
||||
* (e.g., this directory may not be included as part of a backup scheme.)
|
||||
*
|
||||
* In some cases, this directory may just be the main profile directory.
|
||||
*/
|
||||
readonly attribute nsILocalFile localDirectory;
|
||||
|
||||
/**
|
||||
* Unlock the profile.
|
||||
*/
|
||||
void unlock();
|
||||
};
|
||||
|
||||
|
@ -58,12 +74,32 @@ interface nsIProfileLock : nsISupports
|
|||
* @note THIS INTERFACE SHOULD BE IMPLEMENTED BY THE TOOLKIT CODE ONLY! DON'T
|
||||
* EVEN THINK ABOUT IMPLEMENTING THIS IN JAVASCRIPT!
|
||||
*/
|
||||
[scriptable, uuid(0008686a-ee99-4a27-8f1b-190596f535b1)]
|
||||
[scriptable, uuid(7422b090-4a86-4407-972e-75468a625388)]
|
||||
interface nsIToolkitProfile : nsISupports
|
||||
{
|
||||
/**
|
||||
* The location of the profile directory.
|
||||
*/
|
||||
readonly attribute nsILocalFile rootDir;
|
||||
|
||||
/**
|
||||
* The location of the profile local directory, which may be the same as
|
||||
* the root directory. See nsIProfileLock::localDirectory.
|
||||
*/
|
||||
readonly attribute nsILocalFile localDir;
|
||||
|
||||
/**
|
||||
* The name of the profile.
|
||||
*/
|
||||
attribute AUTF8String name;
|
||||
|
||||
/**
|
||||
* Removes the profile from the registry of profiles.
|
||||
*
|
||||
* @param removeFiles
|
||||
* Indicates whether or not the profile directory should be
|
||||
* removed in addition.
|
||||
*/
|
||||
void remove(in boolean removeFiles);
|
||||
|
||||
/**
|
||||
|
|
|
@ -64,17 +64,25 @@ interface nsIToolkitProfileService : nsISupports
|
|||
* Lock an arbitrary path as a profile. If the path does not exist, it
|
||||
* will be created and the defaults copied from the application directory.
|
||||
*/
|
||||
nsIProfileLock lockProfilePath(in nsILocalFile aDirectory);
|
||||
nsIProfileLock lockProfilePath(in nsILocalFile aDirectory,
|
||||
in nsILocalFile aTempDirectory);
|
||||
|
||||
/**
|
||||
* Create a new profile.
|
||||
*
|
||||
* @param rootDir The profile directory. May be null, in which case a suitable
|
||||
* default will be chosen based on the profile name.
|
||||
* @param name The profile name.
|
||||
* @param aRootDir
|
||||
* The profile directory. May be null, in which case a suitable
|
||||
* default will be chosen based on the profile name.
|
||||
* @param aTempDir
|
||||
* The profile temporary directory. May be null, in which case a
|
||||
* suitable default will be chosen based either on the profile name
|
||||
* if aRootDir is null or aRootDir itself.
|
||||
* @param aName
|
||||
* The profile name.
|
||||
*/
|
||||
nsIToolkitProfile createProfile(in nsILocalFile rootDir,
|
||||
in AUTF8String name);
|
||||
nsIToolkitProfile createProfile(in nsILocalFile aRootDir,
|
||||
in nsILocalFile aTempDir,
|
||||
in AUTF8String aName);
|
||||
|
||||
/**
|
||||
* Returns the number of profiles.
|
||||
|
|
|
@ -84,13 +84,16 @@ public:
|
|||
~nsToolkitProfile() { }
|
||||
|
||||
private:
|
||||
nsToolkitProfile(const nsACString& aName, nsILocalFile* aFile,
|
||||
nsToolkitProfile(const nsACString& aName,
|
||||
nsILocalFile* aRootDir,
|
||||
nsILocalFile* aLocalDir,
|
||||
nsToolkitProfile* aPrev);
|
||||
|
||||
friend class nsToolkitProfileLock;
|
||||
|
||||
nsCString mName;
|
||||
nsCOMPtr<nsILocalFile> mFile;
|
||||
nsCOMPtr<nsILocalFile> mRootDir;
|
||||
nsCOMPtr<nsILocalFile> mLocalDir;
|
||||
nsIProfileLock* mLock;
|
||||
};
|
||||
|
||||
|
@ -101,7 +104,8 @@ public:
|
|||
NS_DECL_NSIPROFILELOCK
|
||||
|
||||
nsresult Init(nsToolkitProfile* aProfile, nsIProfileUnlocker* *aUnlocker);
|
||||
nsresult Init(nsILocalFile* aDirectory, nsIProfileUnlocker* *aUnlocker);
|
||||
nsresult Init(nsILocalFile* aDirectory, nsILocalFile* aLocalDirectory,
|
||||
nsIProfileUnlocker* *aUnlocker);
|
||||
|
||||
nsToolkitProfileLock() { }
|
||||
~nsToolkitProfileLock();
|
||||
|
@ -109,6 +113,7 @@ public:
|
|||
private:
|
||||
nsCOMPtr<nsToolkitProfile> mProfile;
|
||||
nsCOMPtr<nsILocalFile> mDirectory;
|
||||
nsCOMPtr<nsILocalFile> mLocalDirectory;
|
||||
|
||||
nsProfileLock mLock;
|
||||
};
|
||||
|
@ -146,6 +151,7 @@ private:
|
|||
nsCOMPtr<nsToolkitProfile> mFirst;
|
||||
nsCOMPtr<nsToolkitProfile> mChosen;
|
||||
nsCOMPtr<nsILocalFile> mAppData;
|
||||
nsCOMPtr<nsILocalFile> mTempData;
|
||||
nsCOMPtr<nsILocalFile> mListFile;
|
||||
PRBool mDirty;
|
||||
PRBool mStartWithLast;
|
||||
|
@ -167,14 +173,17 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
nsToolkitProfile::nsToolkitProfile(const nsACString& aName, nsILocalFile* aFile,
|
||||
nsToolkitProfile::nsToolkitProfile(const nsACString& aName,
|
||||
nsILocalFile* aRootDir,
|
||||
nsILocalFile* aLocalDir,
|
||||
nsToolkitProfile* aPrev) :
|
||||
mPrev(aPrev),
|
||||
mName(aName),
|
||||
mFile(aFile),
|
||||
mRootDir(aRootDir),
|
||||
mLocalDir(aLocalDir),
|
||||
mLock(nsnull)
|
||||
{
|
||||
NS_ASSERTION(aFile, "No file!");
|
||||
NS_ASSERTION(aRootDir, "No file!");
|
||||
|
||||
if (aPrev)
|
||||
aPrev->mNext = this;
|
||||
|
@ -187,7 +196,14 @@ NS_IMPL_ISUPPORTS1(nsToolkitProfile, nsIToolkitProfile)
|
|||
NS_IMETHODIMP
|
||||
nsToolkitProfile::GetRootDir(nsILocalFile* *aResult)
|
||||
{
|
||||
NS_ADDREF(*aResult = mFile);
|
||||
NS_ADDREF(*aResult = mRootDir);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfile::GetLocalDir(nsILocalFile* *aResult)
|
||||
{
|
||||
NS_ADDREF(*aResult = mLocalDir);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -219,8 +235,19 @@ nsToolkitProfile::Remove(PRBool removeFiles)
|
|||
if (mLock)
|
||||
return NS_ERROR_FILE_IS_LOCKED;
|
||||
|
||||
if (removeFiles)
|
||||
mFile->Remove(PR_TRUE);
|
||||
if (removeFiles) {
|
||||
PRBool equals;
|
||||
nsresult rv = mRootDir->Equals(mLocalDir, &equals);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// The root dir might contain the temp dir, so remove
|
||||
// the temp dir first.
|
||||
if (!equals)
|
||||
mLocalDir->Remove(PR_TRUE);
|
||||
|
||||
mRootDir->Remove(PR_TRUE);
|
||||
}
|
||||
|
||||
if (mPrev)
|
||||
mPrev->mNext = mNext;
|
||||
|
@ -265,7 +292,7 @@ nsresult
|
|||
nsToolkitProfileLock::Init(nsToolkitProfile* aProfile, nsIProfileUnlocker* *aUnlocker)
|
||||
{
|
||||
nsresult rv;
|
||||
rv = Init(aProfile->mFile, aUnlocker);
|
||||
rv = Init(aProfile->mRootDir, aProfile->mLocalDir, aUnlocker);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mProfile = aProfile;
|
||||
|
||||
|
@ -273,14 +300,17 @@ nsToolkitProfileLock::Init(nsToolkitProfile* aProfile, nsIProfileUnlocker* *aUnl
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsToolkitProfileLock::Init(nsILocalFile* aDirectory, nsIProfileUnlocker* *aUnlocker)
|
||||
nsToolkitProfileLock::Init(nsILocalFile* aDirectory, nsILocalFile* aLocalDirectory,
|
||||
nsIProfileUnlocker* *aUnlocker)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = mLock.Lock(aDirectory, aUnlocker);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mDirectory = aDirectory;
|
||||
mLocalDirectory = aLocalDirectory;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -297,6 +327,18 @@ nsToolkitProfileLock::GetDirectory(nsILocalFile* *aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileLock::GetLocalDirectory(nsILocalFile* *aResult)
|
||||
{
|
||||
if (!mLocalDirectory) {
|
||||
NS_ERROR("Not initialized, or unlocked!");
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult = mLocalDirectory);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileLock::Unlock()
|
||||
{
|
||||
|
@ -312,6 +354,7 @@ nsToolkitProfileLock::Unlock()
|
|||
mProfile = nsnull;
|
||||
}
|
||||
mDirectory = nsnull;
|
||||
mLocalDirectory = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -339,6 +382,9 @@ nsToolkitProfileService::Init()
|
|||
rv = gDirServiceProvider->GetUserAppDataDirectory(getter_AddRefs(mAppData));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = gDirServiceProvider->GetUserLocalDataDirectory(getter_AddRefs(mTempData));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFile> listFile;
|
||||
rv = mAppData->Clone(getter_AddRefs(listFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -405,8 +451,20 @@ nsToolkitProfileService::Init()
|
|||
}
|
||||
if (NS_FAILED(rv)) continue;
|
||||
|
||||
nsCOMPtr<nsILocalFile> localDir;
|
||||
if (isRelative) {
|
||||
rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE,
|
||||
getter_AddRefs(localDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = localDir->SetRelativeDescriptor(mTempData, filePath);
|
||||
} else {
|
||||
localDir = rootDir;
|
||||
}
|
||||
|
||||
currentProfile = new nsToolkitProfile(nsDependentCString(parserBuf),
|
||||
rootDir, currentProfile);
|
||||
rootDir, localDir,
|
||||
currentProfile);
|
||||
NS_ENSURE_TRUE(currentProfile, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = parser.GetString(profileID, "Default", parserBuf, MAXPATHLEN);
|
||||
|
@ -521,19 +579,20 @@ nsToolkitProfileService::GetProfileByName(const nsACString& aName,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::LockProfilePath(nsILocalFile* aDirectory,
|
||||
nsILocalFile* aLocalDirectory,
|
||||
nsIProfileLock* *aResult)
|
||||
{
|
||||
return NS_LockProfilePath(aDirectory, nsnull, aResult);
|
||||
return NS_LockProfilePath(aDirectory, aLocalDirectory, nsnull, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_LockProfilePath(nsILocalFile* aPath, nsIProfileUnlocker* *aUnlocker,
|
||||
nsIProfileLock* *aResult)
|
||||
NS_LockProfilePath(nsILocalFile* aPath, nsILocalFile* aTempPath,
|
||||
nsIProfileUnlocker* *aUnlocker, nsIProfileLock* *aResult)
|
||||
{
|
||||
nsCOMPtr<nsToolkitProfileLock> lock = new nsToolkitProfileLock();
|
||||
if (!lock) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = lock->Init(aPath, aUnlocker);
|
||||
nsresult rv = lock->Init(aPath, aTempPath, aUnlocker);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_ADDREF(*aResult = lock);
|
||||
|
@ -566,6 +625,7 @@ static void SaltProfileName(nsACString& aName)
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::CreateProfile(nsILocalFile* aRootDir,
|
||||
nsILocalFile* aLocalDir,
|
||||
const nsACString& aName,
|
||||
nsIToolkitProfile* *aResult)
|
||||
{
|
||||
|
@ -576,6 +636,7 @@ nsToolkitProfileService::CreateProfile(nsILocalFile* aRootDir,
|
|||
|
||||
nsCOMPtr<nsILocalFile> rootDir (aRootDir);
|
||||
|
||||
nsCAutoString dirName;
|
||||
if (!rootDir) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
PRBool dummy;
|
||||
|
@ -586,12 +647,33 @@ nsToolkitProfileService::CreateProfile(nsILocalFile* aRootDir,
|
|||
rootDir = do_QueryInterface(file);
|
||||
NS_ENSURE_TRUE(rootDir, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCAutoString dirName(aName);
|
||||
dirName = aName;
|
||||
SaltProfileName(dirName);
|
||||
|
||||
rootDir->AppendNative(dirName);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILocalFile> localDir (aLocalDir);
|
||||
|
||||
if (!localDir) {
|
||||
if (aRootDir) {
|
||||
localDir = aRootDir;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
PRBool dummy;
|
||||
rv = gDirServiceProvider->GetFile(NS_APP_USER_PROFILES_LOCAL_ROOT_DIR,
|
||||
&dummy, getter_AddRefs(file));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
localDir = do_QueryInterface(file);
|
||||
NS_ENSURE_TRUE(localDir, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// use same salting
|
||||
localDir->AppendNative(dirName);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool exists;
|
||||
rv = rootDir->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -631,6 +713,14 @@ nsToolkitProfileService::CreateProfile(nsILocalFile* aRootDir,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = localDir->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!exists) {
|
||||
rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsToolkitProfile* last = mFirst;
|
||||
if (last) {
|
||||
while (last->mNext)
|
||||
|
@ -638,7 +728,7 @@ nsToolkitProfileService::CreateProfile(nsILocalFile* aRootDir,
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIToolkitProfile> profile =
|
||||
new nsToolkitProfile(aName, rootDir, last);
|
||||
new nsToolkitProfile(aName, rootDir, localDir, last);
|
||||
if (!profile) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aResult = profile);
|
||||
|
@ -691,13 +781,13 @@ nsToolkitProfileService::Flush()
|
|||
while (cur) {
|
||||
// if the profile dir is relative to appdir...
|
||||
PRBool isRelative;
|
||||
rv = mAppData->Contains(cur->mFile, PR_TRUE, &isRelative);
|
||||
rv = mAppData->Contains(cur->mRootDir, PR_TRUE, &isRelative);
|
||||
if (NS_SUCCEEDED(rv) && isRelative) {
|
||||
// we use a relative descriptor
|
||||
rv = cur->mFile->GetRelativeDescriptor(mAppData, path);
|
||||
rv = cur->mRootDir->GetRelativeDescriptor(mAppData, path);
|
||||
} else {
|
||||
// otherwise, a persistent descriptor
|
||||
rv = cur->mFile->GetPersistentDescriptor(path);
|
||||
rv = cur->mRootDir->GetPersistentDescriptor(path);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
|
|
@ -1054,7 +1054,8 @@ static const char kProfileProperties[] =
|
|||
"chrome://mozapps/locale/profile/profileSelection.properties";
|
||||
|
||||
static nsresult
|
||||
ProfileLockedDialog(nsILocalFile* aProfileDir, nsIProfileUnlocker* aUnlocker,
|
||||
ProfileLockedDialog(nsILocalFile* aProfileDir, nsILocalFile* aProfileLocalDir,
|
||||
nsIProfileUnlocker* aUnlocker,
|
||||
nsINativeAppSupport* aNative, nsIProfileLock* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -1113,7 +1114,7 @@ ProfileLockedDialog(nsILocalFile* aProfileDir, nsIProfileUnlocker* aUnlocker,
|
|||
rv = aUnlocker->Unlock(nsIProfileUnlocker::FORCE_QUIT);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return NS_LockProfilePath(aProfileDir, nsnull, aResult);
|
||||
return NS_LockProfilePath(aProfileDir, aProfileLocalDir, nsnull, aResult);
|
||||
}
|
||||
|
||||
return NS_ERROR_ABORT;
|
||||
|
@ -1129,7 +1130,7 @@ ShowProfileManager(nsIToolkitProfileService* aProfileSvc,
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsILocalFile> lf;
|
||||
nsCOMPtr<nsILocalFile> profD, profLD;
|
||||
|
||||
{
|
||||
ScopedXPCOMStartup xpcom;
|
||||
|
@ -1181,19 +1182,26 @@ ShowProfileManager(nsIToolkitProfileService* aProfileSvc,
|
|||
getter_AddRefs(lock));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = lock->GetDirectory(getter_AddRefs(lf));
|
||||
rv = lock->GetDirectory(getter_AddRefs(profD));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = lock->GetLocalDirectory(getter_AddRefs(profLD));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
lock->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
nsCAutoString path;
|
||||
lf->GetNativePath(path);
|
||||
nsCAutoString path1;
|
||||
nsCAutoString path2;
|
||||
profD->GetNativePath(path1);
|
||||
profLD->GetNativePath(path2);
|
||||
|
||||
static char kEnvVar[MAXPATHLEN];
|
||||
sprintf(kEnvVar, "XRE_PROFILE_PATH=%s", path.get());
|
||||
PR_SetEnv(kEnvVar);
|
||||
static char kEnvVar1[MAXPATHLEN], kEnvVar2[MAXPATHLEN];
|
||||
sprintf(kEnvVar1, "XRE_PROFILE_PATH=%s", path1.get());
|
||||
sprintf(kEnvVar2, "XRE_PROFILE_LOCAL_PATH=%s", path2.get());
|
||||
PR_SetEnv(kEnvVar1);
|
||||
PR_SetEnv(kEnvVar2);
|
||||
|
||||
PRBool offline = PR_FALSE;
|
||||
aProfileSvc->GetStartOffline(&offline);
|
||||
|
@ -1264,7 +1272,17 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
|
|||
getter_AddRefs(lf));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_LockProfilePath(lf, nsnull, aResult);
|
||||
nsCOMPtr<nsILocalFile> localDir;
|
||||
arg = PR_GetEnv("XRE_PROFILE_LOCAL_PATH");
|
||||
if (arg && *arg) {
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(arg), PR_TRUE,
|
||||
getter_AddRefs(localDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
localDir = lf;
|
||||
}
|
||||
|
||||
return NS_LockProfilePath(lf, localDir, nsnull, aResult);
|
||||
}
|
||||
|
||||
if (CheckArg("migration"))
|
||||
|
@ -1282,11 +1300,13 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
|
|||
|
||||
nsCOMPtr<nsIProfileUnlocker> unlocker;
|
||||
|
||||
rv = NS_LockProfilePath(lf, getter_AddRefs(unlocker), aResult);
|
||||
// If a profile path is specified directory on the command line, then
|
||||
// assume that the temp directory is the same as the given directory.
|
||||
rv = NS_LockProfilePath(lf, lf, getter_AddRefs(unlocker), aResult);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return rv;
|
||||
|
||||
return ProfileLockedDialog(lf, unlocker, aNative, aResult);
|
||||
return ProfileLockedDialog(lf, lf, unlocker, aNative, aResult);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIToolkitProfileService> profileSvc;
|
||||
|
@ -1311,10 +1331,12 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
|
|||
return rv;
|
||||
}
|
||||
|
||||
rv = profileSvc->CreateProfile(lf, nsDependentCSubstring(arg, delim),
|
||||
// As with -profile, assume that the given path will be used for both the
|
||||
// main profile directory and the temp profile directory.
|
||||
rv = profileSvc->CreateProfile(lf, lf, nsDependentCSubstring(arg, delim),
|
||||
getter_AddRefs(profile));
|
||||
} else {
|
||||
rv = profileSvc->CreateProfile(nsnull, nsDependentCString(arg),
|
||||
rv = profileSvc->CreateProfile(nsnull, nsnull, nsDependentCString(arg),
|
||||
getter_AddRefs(profile));
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -1332,6 +1354,7 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
|
|||
prefsJSFile->Exists(&exists);
|
||||
if (!exists)
|
||||
prefsJSFile->Create(nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
// XXXdarin perhaps 0600 would be better?
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -1340,9 +1363,11 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
|
|||
rv = profileSvc->GetProfileCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
arg = PR_GetEnv("XRE_IMPORT_PROFILES");
|
||||
if (!count && (!arg || !*arg)) {
|
||||
return ImportProfiles(profileSvc, aNative);
|
||||
if (gAppData->flags & NS_XRE_ENABLE_PROFILE_MIGRATOR) {
|
||||
arg = PR_GetEnv("XRE_IMPORT_PROFILES");
|
||||
if (!count && (!arg || !*arg)) {
|
||||
return ImportProfiles(profileSvc, aNative);
|
||||
}
|
||||
}
|
||||
|
||||
ar = CheckArg("p", &arg);
|
||||
|
@ -1363,7 +1388,12 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
|
|||
rv = profile->GetRootDir(getter_AddRefs(profileDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return ProfileLockedDialog(profileDir, unlocker, aNative, aResult);
|
||||
nsCOMPtr<nsILocalFile> profileLocalDir;
|
||||
rv = profile->GetLocalDir(getter_AddRefs(profileLocalDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return ProfileLockedDialog(profileDir, profileLocalDir, unlocker,
|
||||
aNative, aResult);
|
||||
}
|
||||
|
||||
return ShowProfileManager(profileSvc, aNative);
|
||||
|
@ -1379,6 +1409,7 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
|
|||
// create a default profile
|
||||
nsCOMPtr<nsIToolkitProfile> profile;
|
||||
nsresult rv = profileSvc->CreateProfile(nsnull, // choose a default dir for us
|
||||
nsnull, // choose a default dir for us
|
||||
NS_LITERAL_CSTRING("default"),
|
||||
getter_AddRefs(profile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -1407,7 +1438,12 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
|
|||
rv = profile->GetRootDir(getter_AddRefs(profileDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return ProfileLockedDialog(profileDir, unlocker, aNative, aResult);
|
||||
nsCOMPtr<nsILocalFile> profileLocalDir;
|
||||
rv = profile->GetRootDir(getter_AddRefs(profileLocalDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return ProfileLockedDialog(profileDir, profileLocalDir, unlocker,
|
||||
aNative, aResult);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1525,6 +1561,11 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
|||
nsresult rv;
|
||||
NS_TIMELINE_MARK("enter main");
|
||||
|
||||
#ifdef DEBUG
|
||||
if (PR_GetEnv("XRE_MAIN_BREAK"))
|
||||
NS_BREAK();
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN32
|
||||
// Suppress the "DLL Foo could not be found" dialog, such that if dependent
|
||||
// libraries (such as GDI+) are not preset, we gracefully fail to load those
|
||||
|
@ -1742,11 +1783,15 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
|||
rv == NS_ERROR_ABORT) return 0;
|
||||
if (NS_FAILED(rv)) return 1;
|
||||
|
||||
nsCOMPtr<nsILocalFile> lf;
|
||||
rv = profileLock->GetDirectory(getter_AddRefs(lf));
|
||||
nsCOMPtr<nsILocalFile> profD;
|
||||
rv = profileLock->GetDirectory(getter_AddRefs(profD));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = dirProvider.SetProfileDir(lf);
|
||||
nsCOMPtr<nsILocalFile> profLD;
|
||||
rv = profileLock->GetLocalDirectory(getter_AddRefs(profLD));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = dirProvider.SetProfile(profD, profLD);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
//////////////////////// NOW WE HAVE A PROFILE ////////////////////////
|
||||
|
@ -1758,7 +1803,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
|||
// profile was started with. The format of the version stamp is defined
|
||||
// by the BuildVersion function.
|
||||
char lastVersion[MAXPATHLEN];
|
||||
GetVersion(lf, lastVersion, MAXPATHLEN);
|
||||
GetVersion(profD, lastVersion, MAXPATHLEN);
|
||||
|
||||
// Build the version stamp for the running application.
|
||||
nsCAutoString version;
|
||||
|
@ -1772,13 +1817,13 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
|||
// re-generated to prevent mysterious component loading failures.
|
||||
//
|
||||
if (version.Equals(lastVersion)) {
|
||||
componentsListChanged = ComponentsListChanged(lf);
|
||||
componentsListChanged = ComponentsListChanged(profD);
|
||||
if (componentsListChanged) {
|
||||
// Remove compreg.dat and xpti.dat, forcing component re-registration,
|
||||
// with the new list of additional components directories specified
|
||||
// in "components.ini" which we have just discovered changed since the
|
||||
// last time the application was run.
|
||||
RemoveComponentRegistries(lf);
|
||||
RemoveComponentRegistries(profD);
|
||||
}
|
||||
// Nothing need be done for the normal startup case.
|
||||
}
|
||||
|
@ -1786,7 +1831,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
|||
// Remove compreg.dat and xpti.dat, forcing component re-registration
|
||||
// with the default set of components (this disables any potentially
|
||||
// troublesome incompatible XPCOM components).
|
||||
RemoveComponentRegistries(lf);
|
||||
RemoveComponentRegistries(profD);
|
||||
|
||||
// Tell the Extension Manager it should check for incompatible
|
||||
// Extensions and re-write the Components manifest ("components.ini")
|
||||
|
@ -1794,7 +1839,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
|||
upgraded = PR_TRUE;
|
||||
|
||||
// Write out version
|
||||
WriteVersion(lf, version);
|
||||
WriteVersion(profD, version);
|
||||
}
|
||||
|
||||
PRBool needsRestart = PR_FALSE;
|
||||
|
@ -1907,6 +1952,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
|||
// clear out any environment variables which may have been set
|
||||
// during the relaunch process now that we know we won't be relaunching.
|
||||
PR_SetEnv("XRE_PROFILE_PATH=");
|
||||
PR_SetEnv("XRE_PROFILE_TEMP_PATH=");
|
||||
PR_SetEnv("XRE_START_OFFLINE=");
|
||||
PR_SetEnv("XRE_IMPORT_PROFILES=");
|
||||
PR_SetEnv("NO_EM_RESTART=");
|
||||
|
@ -1997,12 +2043,15 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
|||
// After this restart, we don't want to restart any more!
|
||||
PR_SetEnv("NO_EM_RESTART=1");
|
||||
|
||||
nsCAutoString path;
|
||||
lf->GetNativePath(path);
|
||||
nsCAutoString path1, path2;
|
||||
profD->GetNativePath(path1);
|
||||
profLD->GetNativePath(path2);
|
||||
|
||||
static char kEnvVar[MAXPATHLEN];
|
||||
sprintf(kEnvVar, "XRE_PROFILE_PATH=%s", path.get());
|
||||
PR_SetEnv(kEnvVar);
|
||||
static char kEnvVar1[MAXPATHLEN], kEnvVar2[MAXPATHLEN];
|
||||
sprintf(kEnvVar1, "XRE_PROFILE_PATH=%s", path1.get());
|
||||
sprintf(kEnvVar2, "XRE_PROFILE_LOCAL_PATH=%s", path2.get());
|
||||
PR_SetEnv(kEnvVar1);
|
||||
PR_SetEnv(kEnvVar2);
|
||||
|
||||
return LaunchChild(nativeApp) == NS_ERROR_LAUNCHED_CHILD_PROCESS ? 0 : 1;
|
||||
}
|
||||
|
|
|
@ -87,9 +87,26 @@ nsresult NS_CreateNativeAppSupport(nsINativeAppSupport* *aResult);
|
|||
NS_HIDDEN_(nsresult)
|
||||
NS_NewToolkitProfileService(nsIToolkitProfileService* *aResult);
|
||||
|
||||
/**
|
||||
* Try to acquire exclusive access to the specified profile directory.
|
||||
*
|
||||
* @param aPath
|
||||
* The profile directory to lock.
|
||||
* @param aTempPath
|
||||
* The corresponding profile temporary directory.
|
||||
* @param aUnlocker
|
||||
* A callback interface used to attempt to unlock a profile that
|
||||
* appears to be locked.
|
||||
* @param aResult
|
||||
* The resulting profile lock object (or null if the profile could
|
||||
* not be locked).
|
||||
*
|
||||
* @return NS_ERROR_FILE_ACCESS_DENIED to indicate that the profile
|
||||
* directory cannot be unlocked.
|
||||
*/
|
||||
NS_HIDDEN_(nsresult)
|
||||
NS_LockProfilePath(nsILocalFile* aPath, nsIProfileUnlocker* *aUnlocker,
|
||||
nsIProfileLock* *aResult);
|
||||
NS_LockProfilePath(nsILocalFile* aPath, nsILocalFile* aTempPath,
|
||||
nsIProfileUnlocker* *aUnlocker, nsIProfileLock* *aResult);
|
||||
|
||||
#define NS_NATIVEAPPSUPPORT_CONTRACTID "@mozilla.org/toolkit/native-app-support;1"
|
||||
|
||||
|
|
|
@ -190,17 +190,29 @@ nsXREDirProvider::Initialize(nsIFile *aXULAppDir)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXREDirProvider::SetProfileDir(nsIFile* aDir)
|
||||
nsXREDirProvider::SetProfile(nsIFile* aDir, nsIFile* aLocalDir)
|
||||
{
|
||||
NS_ASSERTION(aDir, "We don't support no-profile apps yet!");
|
||||
NS_ASSERTION(aDir && aLocalDir, "We don't support no-profile apps yet!");
|
||||
|
||||
#ifdef DEBUG_bsmedberg
|
||||
nsCAutoString path;
|
||||
nsCAutoString path, path2;
|
||||
aDir->GetNativePath(path);
|
||||
printf("nsXREDirProvider::SetProfileDir('%s')\n", path.get());
|
||||
aLocalDir->GetNativePath(path2);
|
||||
printf("nsXREDirProvider::SetProfile('%s', '%s')\n", path.get(), path2.get());
|
||||
#endif
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = EnsureDirectoryExists(aDir);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = EnsureDirectoryExists(aLocalDir);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mProfileDir = aDir;
|
||||
mProfileLocalDir = aLocalDir;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -258,6 +270,16 @@ nsXREDirProvider::GetFile(const char* aProperty, PRBool* aPersistent,
|
|||
else if (!strcmp(aProperty, NS_APP_USER_PROFILES_ROOT_DIR)) {
|
||||
rv = GetUserAppDataDirectory((nsILocalFile**)(nsIFile**) getter_AddRefs(file));
|
||||
|
||||
#if !defined(XP_UNIX) || defined(XP_MACOSX)
|
||||
rv |= file->AppendNative(NS_LITERAL_CSTRING("Profiles"));
|
||||
#endif
|
||||
|
||||
// We must create the profile directory here if it does not exist.
|
||||
rv |= EnsureDirectoryExists(file);
|
||||
}
|
||||
else if (!strcmp(aProperty, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR)) {
|
||||
rv = GetUserLocalDataDirectory((nsILocalFile**)(nsIFile**) getter_AddRefs(file));
|
||||
|
||||
#if !defined(XP_UNIX) || defined(XP_MACOSX)
|
||||
rv |= file->AppendNative(NS_LITERAL_CSTRING("Profiles"));
|
||||
#endif
|
||||
|
@ -291,6 +313,9 @@ nsXREDirProvider::GetFile(const char* aProperty, PRBool* aPersistent,
|
|||
!strcmp(aProperty, NS_APP_PREFS_50_DIR)) {
|
||||
return mProfileDir->Clone(aFile);
|
||||
}
|
||||
else if (!strcmp(aProperty, NS_APP_USER_PROFILE_LOCAL_50_DIR)) {
|
||||
return mProfileLocalDir->Clone(aFile);
|
||||
}
|
||||
else if (!strcmp(aProperty, NS_APP_PREFS_50_FILE)) {
|
||||
rv = mProfileDir->Clone(getter_AddRefs(file));
|
||||
rv |= file->AppendNative(NS_LITERAL_CSTRING("prefs.js"));
|
||||
|
@ -641,7 +666,7 @@ GetProfileFolderName(char* aProfileFolderName, const char* aSource)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXREDirProvider::GetUserAppDataDirectory(nsILocalFile** aFile)
|
||||
nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
|
||||
{
|
||||
NS_ASSERTION(gAppData, "gAppData not initialized!");
|
||||
|
||||
|
@ -650,13 +675,19 @@ nsXREDirProvider::GetUserAppDataDirectory(nsILocalFile** aFile)
|
|||
nsCOMPtr<nsILocalFile> localDir;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
FSRef fsRef;
|
||||
FSRef fsRef;
|
||||
OSType folderType;
|
||||
if (aLocal) {
|
||||
folderType = kCachedDataFolderType;
|
||||
} else {
|
||||
#ifdef MOZ_THUNDERBIRD
|
||||
OSErr err = ::FSFindFolder(kUserDomain, kDomainLibraryFolderType, kCreateFolder, &fsRef);
|
||||
folderType = kDomainLibraryFolderType;
|
||||
#else
|
||||
OSErr err = ::FSFindFolder(kUserDomain, kApplicationSupportFolderType, kCreateFolder, &fsRef);
|
||||
folderType = kApplicationSupportFolderType;
|
||||
#endif
|
||||
if (err) return NS_ERROR_FAILURE;
|
||||
}
|
||||
OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
|
||||
NS_ENSURE_TRUE(err, NS_ERROR_FAILURE);
|
||||
|
||||
rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(localDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -681,7 +712,9 @@ nsXREDirProvider::GetUserAppDataDirectory(nsILocalFile** aFile)
|
|||
|
||||
char appDataPath[MAXPATHLEN];
|
||||
|
||||
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pItemIDList)) &&
|
||||
int folder = aLocal ? CSIDL_LOCAL_APPDATA : CSIDL_APPDATA;
|
||||
|
||||
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, folder, &pItemIDList)) &&
|
||||
SUCCEEDED(SHGetPathFromIDList(pItemIDList, appDataPath))) {
|
||||
} else {
|
||||
if (!GetWindowsDirectory(appDataPath, MAXPATHLEN)) {
|
||||
|
@ -804,7 +837,7 @@ nsXREDirProvider::EnsureDirectoryExists(nsIFile* aDirectory)
|
|||
nsresult rv = aDirectory->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!exists)
|
||||
rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0775);
|
||||
rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -64,23 +64,31 @@ public:
|
|||
// that is the responsibility of the toolkit profile service.
|
||||
// We also don't fire profile-changed notifications... that is
|
||||
// the responsibility of the apprunner.
|
||||
nsresult SetProfileDir(nsIFile* aProfileDir);
|
||||
nsresult SetProfile(nsIFile* aProfileDir, nsIFile* aProfileLocalDir);
|
||||
|
||||
void DoShutdown();
|
||||
|
||||
nsresult GetProfileDefaultsDir(nsIFile* *aResult);
|
||||
static nsresult GetUserAppDataDirectory(nsILocalFile* *aFile);
|
||||
|
||||
static nsresult GetUserAppDataDirectory(nsILocalFile* *aFile) {
|
||||
return GetUserDataDirectory(aFile, PR_FALSE);
|
||||
}
|
||||
static nsresult GetUserLocalDataDirectory(nsILocalFile* *aFile) {
|
||||
return GetUserDataDirectory(aFile, PR_TRUE);
|
||||
}
|
||||
|
||||
/* make sure you clone it, if you need to do stuff to it */
|
||||
nsIFile* GetAppDir() { return mAppDir; }
|
||||
|
||||
protected:
|
||||
static nsresult GetUserDataDirectory(nsILocalFile* *aFile, PRBool aLocal);
|
||||
static nsresult EnsureDirectoryExists(nsIFile* aDirectory);
|
||||
void EnsureProfileFileExists(nsIFile* aFile);
|
||||
|
||||
nsCOMPtr<nsILocalFile> mAppDir;
|
||||
nsCOMPtr<nsIFile> mXULAppDir;
|
||||
nsCOMPtr<nsIFile> mProfileDir;
|
||||
nsCOMPtr<nsIFile> mProfileLocalDir;
|
||||
PRBool mProfileNotified;
|
||||
};
|
||||
|
||||
|
|
|
@ -69,7 +69,8 @@
|
|||
// installed locale. Second choice
|
||||
// when above is not available.
|
||||
|
||||
#define NS_APP_USER_PROFILES_ROOT_DIR "DefProfRt" // The dir where user profile dirs get created.
|
||||
#define NS_APP_USER_PROFILES_ROOT_DIR "DefProfRt" // The dir where user profile dirs live.
|
||||
#define NS_APP_USER_PROFILES_LOCAL_ROOT_DIR "DefProfLRt" // The dir where user profile temp dirs live.
|
||||
|
||||
#define NS_APP_RES_DIR "ARes"
|
||||
#define NS_APP_CHROME_DIR "AChrom"
|
||||
|
@ -96,6 +97,7 @@
|
|||
#define NS_APP_PREFS_DEFAULTS_DIR_LIST "PrefDL"
|
||||
|
||||
#define NS_APP_USER_PROFILE_50_DIR "ProfD"
|
||||
#define NS_APP_USER_PROFILE_LOCAL_50_DIR "ProfLD"
|
||||
|
||||
#define NS_APP_USER_CHROME_DIR "UChrm"
|
||||
|
||||
|
|
|
@ -135,10 +135,21 @@ nsresult
|
|||
nsFastLoadService::NewFastLoadFile(const char* aBaseName, nsIFile* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> file;
|
||||
|
||||
nsCOMPtr<nsIFile> profFile;
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(profFile));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR,
|
||||
getter_AddRefs(file));
|
||||
if (NS_FAILED(rv))
|
||||
file = profFile;
|
||||
|
||||
PRBool sameDir;
|
||||
rv = file->Equals(profFile, &sameDir);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -149,6 +160,15 @@ nsFastLoadService::NewFastLoadFile(const char* aBaseName, nsIFile* *aResult)
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!sameDir) {
|
||||
// Cleanup any pre-existing fastload files that may live in the profile
|
||||
// directory from previous versions of the code that didn't store them
|
||||
// in the profile temp directory.
|
||||
rv = profFile->AppendNative(name);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
profFile->Remove(PR_FALSE); // OK if this fails
|
||||
}
|
||||
|
||||
*aResult = file;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
|
|
Загрузка…
Ссылка в новой задаче