new files. not part of the build yet.
git-svn-id: svn://10.0.0.236/trunk@55428 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
0ed0a6ba1a
commit
ff7a3079f8
944
mozilla/profile/src/nsProfileAccess.cpp
Normal file
944
mozilla/profile/src/nsProfileAccess.cpp
Normal file
@ -0,0 +1,944 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsProfileAccess.h"
|
||||
#include "nsProfile.h"
|
||||
|
||||
#include "pratom.h"
|
||||
#include "prmem.h"
|
||||
#include "plstr.h"
|
||||
#include "prenv.h"
|
||||
|
||||
#include "NSReg.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "prprf.h"
|
||||
#include "nsSpecialSystemDirectory.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIFileSpec.h"
|
||||
#include "nsFileStream.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
// kill me now.
|
||||
#define REGISTRY_YES_STRING "yes"
|
||||
#define REGISTRY_NO_STRING "no"
|
||||
|
||||
// strings for items in the registry we'll be getting or setting
|
||||
#define REGISTRY_PROFILE_SUBTREE_STRING "Profiles"
|
||||
#define REGISTRY_CURRENT_PROFILE_STRING "CurrentProfile"
|
||||
#define REGISTRY_NC_SERVICE_DENIAL_STRING "NCServiceDenial"
|
||||
#define REGISTRY_NC_PROFILE_NAME_STRING "NCProfileName"
|
||||
#define REGISTRY_HAVE_PREG_INFO_STRING "HavePregInfo"
|
||||
#define REGISTRY_MIGRATED_STRING "migrated"
|
||||
#define REGISTRY_DIRECTORY_STRING "directory"
|
||||
#define REGISTRY_NEED_MIGRATION_STRING "NeedMigration"
|
||||
|
||||
#define REGISTRY_VERSION_STRING "Version"
|
||||
#define REGISTRY_VERSION_1_0 "1.0"
|
||||
|
||||
#define MAX_PERSISTENT_DATA_SIZE 1000
|
||||
#define NUM_HEX_BYTES 8
|
||||
#define ISHEX(c) ( ((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F') )
|
||||
|
||||
#if defined (XP_UNIX)
|
||||
#define USER_ENVIRONMENT_VARIABLE "USER"
|
||||
#define HOME_ENVIRONMENT_VARIABLE "HOME"
|
||||
#define PROFILE_NAME_ENVIRONMENT_VARIABLE "PROFILE_NAME"
|
||||
#define PROFILE_HOME_ENVIRONMENT_VARIABLE "PROFILE_HOME"
|
||||
#elif defined (XP_BEOS)
|
||||
#endif
|
||||
|
||||
// IID and CIDs of all the services needed
|
||||
static NS_DEFINE_CID(kRegistryCID, NS_REGISTRY_CID);
|
||||
|
||||
/*
|
||||
* Constructor/Destructor
|
||||
* FillProfileInfo reads the registry and fills profileStructs
|
||||
*/
|
||||
nsProfileAccess::nsProfileAccess()
|
||||
{
|
||||
m_registry = null_nsCOMPtr();
|
||||
mCount = 0;
|
||||
mNumProfiles = 0;
|
||||
mNumOldProfiles = 0;
|
||||
m4xCount = 0;
|
||||
mCurrentProfile = nsnull;
|
||||
mVersion = nsnull;
|
||||
mHavePREGInfo = nsnull;
|
||||
mFixRegEntries = PR_FALSE;
|
||||
mProfileDataChanged = PR_FALSE;
|
||||
mForgetProfileCalled = PR_FALSE;
|
||||
|
||||
FillProfileInfo();
|
||||
}
|
||||
|
||||
// On the way out, close the registry if it is
|
||||
// still opened and free up the resources.
|
||||
nsProfileAccess::~nsProfileAccess()
|
||||
{
|
||||
|
||||
PRBool openalready = PR_FALSE;
|
||||
|
||||
m_registry->IsOpen( &openalready);
|
||||
if (openalready)
|
||||
m_registry->Close();
|
||||
|
||||
// Release all resources.
|
||||
CRTFREEIF(mCurrentProfile);
|
||||
CRTFREEIF(mVersion);
|
||||
CRTFREEIF(mHavePREGInfo);
|
||||
|
||||
FreeProfileMembers(mProfiles, mCount);
|
||||
FreeProfileMembers(m4xProfiles, m4xCount);
|
||||
}
|
||||
|
||||
// Free up the member profile structs
|
||||
void
|
||||
nsProfileAccess::FreeProfileMembers(ProfileStruct *profiles[], PRInt32 numElems)
|
||||
{
|
||||
PRInt32 index = 0;
|
||||
|
||||
for (index=0; index < numElems; index++)
|
||||
{
|
||||
CRTFREEIF(profiles[index]->profileName);
|
||||
CRTFREEIF(profiles[index]->profileLocation);
|
||||
CRTFREEIF(profiles[index]->isMigrated);
|
||||
CRTFREEIF(profiles[index]->NCProfileName);
|
||||
CRTFREEIF(profiles[index]->NCDeniedService);
|
||||
|
||||
PR_FREEIF(profiles[index]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Close the registry.
|
||||
nsresult
|
||||
nsProfileAccess::CloseRegistry()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
rv = m_registry->Close();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Open the registry.
|
||||
// If already opened, just use it.
|
||||
nsresult
|
||||
nsProfileAccess::OpenRegistry()
|
||||
{
|
||||
nsresult rv;
|
||||
PRBool openalready = PR_FALSE;
|
||||
|
||||
|
||||
if (!m_registry) {
|
||||
rv = nsComponentManager::CreateInstance(kRegistryCID,
|
||||
nsnull,
|
||||
nsIRegistry::GetIID(),
|
||||
getter_AddRefs(m_registry));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!m_registry) return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Open the registry
|
||||
rv = m_registry->IsOpen( &openalready);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!openalready)
|
||||
rv = m_registry->OpenDefault();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Given the name of the profile, the structure that
|
||||
// contains the relavant profile information will be filled.
|
||||
// Caller must free up the profile struct.
|
||||
nsresult
|
||||
nsProfileAccess::GetValue(const char* profileName, ProfileStruct** aProfile)
|
||||
{
|
||||
PRInt32 index = 0;
|
||||
|
||||
index = FindProfileIndex(profileName);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
*aProfile = (ProfileStruct *) PR_Malloc(sizeof(ProfileStruct));
|
||||
if (!*aProfile)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
(*aProfile)->profileName = nsnull;
|
||||
(*aProfile)->profileLocation = nsnull;
|
||||
(*aProfile)->isMigrated = nsnull;
|
||||
(*aProfile)->NCProfileName = nsnull;
|
||||
(*aProfile)->NCDeniedService = nsnull;
|
||||
|
||||
(*aProfile)->profileName = nsCRT::strdup(mProfiles[index]->profileName);
|
||||
(*aProfile)->profileLocation = nsCRT::strdup(mProfiles[index]->profileLocation);
|
||||
(*aProfile)->isMigrated = nsCRT::strdup(mProfiles[index]->isMigrated);
|
||||
|
||||
if (mProfiles[index]->NCProfileName)
|
||||
(*aProfile)->NCProfileName = nsCRT::strdup(mProfiles[index]->NCProfileName);
|
||||
if (mProfiles[index]->NCDeniedService)
|
||||
(*aProfile)->NCProfileName = nsCRT::strdup(mProfiles[index]->NCDeniedService);
|
||||
}
|
||||
else
|
||||
*aProfile = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This method writes all changes to the array of the
|
||||
// profile structs. If it is an existing profile, it
|
||||
// will be updated. If it is a new profile, it gets added
|
||||
// to the list.
|
||||
nsresult
|
||||
nsProfileAccess::SetValue(ProfileStruct* aProfile)
|
||||
{
|
||||
PRInt32 index = 0;
|
||||
|
||||
index = FindProfileIndex(aProfile->profileName);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
PRInt32 length = PL_strlen(aProfile->profileLocation);
|
||||
mProfiles[index]->profileLocation = (char *) PR_Realloc(mProfiles[index]->profileLocation, length+1);
|
||||
PL_strcpy(mProfiles[index]->profileLocation, aProfile->profileLocation);
|
||||
|
||||
length = PL_strlen(aProfile->isMigrated);
|
||||
mProfiles[index]->isMigrated = (char *) PR_Realloc(mProfiles[index]->isMigrated, length+1);
|
||||
PL_strcpy(mProfiles[index]->isMigrated, aProfile->isMigrated);
|
||||
|
||||
mProfiles[index]->updateProfileEntry = PR_TRUE;
|
||||
|
||||
if (aProfile->NCProfileName)
|
||||
{
|
||||
length = PL_strlen(aProfile->NCProfileName);
|
||||
mProfiles[index]->NCProfileName = (char *) PR_Realloc(mProfiles[index]->NCProfileName, length+1);
|
||||
PL_strcpy(mProfiles[index]->NCProfileName, aProfile->NCProfileName);
|
||||
}
|
||||
if (aProfile->NCDeniedService)
|
||||
{
|
||||
length = PL_strlen(aProfile->NCDeniedService);
|
||||
mProfiles[index]->NCDeniedService = (char *) PR_Realloc(mProfiles[index]->NCDeniedService, length+1);
|
||||
PL_strcpy(mProfiles[mCount]->NCDeniedService, aProfile->NCDeniedService);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mProfiles[mCount] = (ProfileStruct *) PR_Malloc(sizeof(ProfileStruct));
|
||||
if (!mProfiles[mCount])
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mProfiles[mCount]->profileName = nsnull;
|
||||
mProfiles[mCount]->profileLocation = nsnull;
|
||||
mProfiles[mCount]->isMigrated = nsnull;
|
||||
mProfiles[mCount]->NCProfileName = nsnull;
|
||||
mProfiles[mCount]->NCDeniedService = nsnull;
|
||||
|
||||
mProfiles[mCount]->profileName = nsCRT::strdup(aProfile->profileName);
|
||||
mProfiles[mCount]->profileLocation = nsCRT::strdup(aProfile->profileLocation);
|
||||
mProfiles[mCount]->isMigrated = nsCRT::strdup(aProfile->isMigrated);
|
||||
mProfiles[mCount]->updateProfileEntry = PR_TRUE;
|
||||
|
||||
if (aProfile->NCProfileName)
|
||||
mProfiles[index]->NCProfileName = nsCRT::strdup(aProfile->NCProfileName);
|
||||
if (aProfile->NCDeniedService)
|
||||
mProfiles[mCount]->NCProfileName = nsCRT::strdup(aProfile->NCDeniedService);
|
||||
|
||||
mCount++;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Enumerates through the registry for profile
|
||||
// information. Reads in the data into the array
|
||||
// of profile structs. After this, all the callers
|
||||
// requesting profile info will get thier data from
|
||||
// profiles array. All the udates will be done to this
|
||||
// data structure to reflect the latest status.
|
||||
// Data will be flushed at the end.
|
||||
nsresult
|
||||
nsProfileAccess::FillProfileInfo()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Make the fail: thing work
|
||||
mProfiles[0] = nsnull;
|
||||
|
||||
rv = OpenRegistry();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Enumerate all subkeys (immediately) under the given node.
|
||||
nsCOMPtr<nsIEnumerator> enumKeys;
|
||||
nsRegistryKey profilesTreeKey;
|
||||
|
||||
rv = m_registry->GetSubtree(nsIRegistry::Common, REGISTRY_PROFILE_SUBTREE_STRING, &profilesTreeKey);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
rv = m_registry->AddSubtree(nsIRegistry::Common, REGISTRY_PROFILE_SUBTREE_STRING, &profilesTreeKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// Get the current profile
|
||||
rv = m_registry->GetString(profilesTreeKey, REGISTRY_CURRENT_PROFILE_STRING, &mCurrentProfile);
|
||||
|
||||
// Get the profile version
|
||||
rv = m_registry->GetString(profilesTreeKey, REGISTRY_VERSION_STRING, &mVersion);
|
||||
|
||||
if (mVersion == nsnull)
|
||||
{
|
||||
mFixRegEntries = PR_TRUE;
|
||||
mVersion = nsCRT::strdup(REGISTRY_VERSION_1_0);
|
||||
mProfileDataChanged = PR_TRUE;
|
||||
}
|
||||
|
||||
// Get the preg info
|
||||
rv = m_registry->GetString(profilesTreeKey, REGISTRY_HAVE_PREG_INFO_STRING, &mHavePREGInfo);
|
||||
|
||||
if (mHavePREGInfo == nsnull)
|
||||
{
|
||||
mHavePREGInfo = nsCRT::strdup(REGISTRY_NO_STRING);
|
||||
mProfileDataChanged = PR_TRUE;
|
||||
}
|
||||
|
||||
rv = m_registry->EnumerateSubtrees( profilesTreeKey, getter_AddRefs(enumKeys));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = enumKeys->First();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mCount = 0;
|
||||
mNumProfiles = 0;
|
||||
mNumOldProfiles = 0;
|
||||
|
||||
while( (NS_OK != enumKeys->IsDone()) )
|
||||
{
|
||||
nsCOMPtr<nsISupports> base;
|
||||
|
||||
rv = enumKeys->CurrentItem( getter_AddRefs(base) );
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get specific interface.
|
||||
nsCOMPtr <nsIRegistryNode> node;
|
||||
nsIID nodeIID = NS_IREGISTRYNODE_IID;
|
||||
|
||||
rv = base->QueryInterface( nodeIID, getter_AddRefs(node));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get node name.
|
||||
nsXPIDLCString profile;
|
||||
nsXPIDLCString isMigrated;
|
||||
nsXPIDLCString NCProfileName;
|
||||
nsXPIDLCString NCDeniedService;
|
||||
char* directory = nsnull;
|
||||
|
||||
rv = node->GetName( getter_Copies(profile) );
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (profile)
|
||||
{
|
||||
nsRegistryKey profKey;
|
||||
|
||||
rv = m_registry->GetSubtree(profilesTreeKey, profile, &profKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = m_registry->GetString(profKey, REGISTRY_DIRECTORY_STRING, &directory);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mFixRegEntries)
|
||||
FixRegEntry(&directory);
|
||||
|
||||
rv = m_registry->GetString(profKey, REGISTRY_MIGRATED_STRING, getter_Copies(isMigrated));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = m_registry->GetString(profKey, REGISTRY_NC_PROFILE_NAME_STRING, getter_Copies(NCProfileName));
|
||||
rv = m_registry->GetString(profKey, REGISTRY_NC_SERVICE_DENIAL_STRING, getter_Copies(NCDeniedService));
|
||||
|
||||
mProfiles[mCount] = (ProfileStruct *) PR_Malloc(sizeof(ProfileStruct));
|
||||
if (!mProfiles[mCount])
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mProfiles[mCount]->profileName = nsnull;
|
||||
mProfiles[mCount]->profileLocation = nsnull;
|
||||
mProfiles[mCount]->isMigrated = nsnull;
|
||||
mProfiles[mCount]->NCProfileName = nsnull;
|
||||
mProfiles[mCount]->NCDeniedService = nsnull;
|
||||
mProfiles[mCount]->updateProfileEntry = PR_TRUE;
|
||||
|
||||
mProfiles[mCount]->profileName = nsCRT::strdup(profile);
|
||||
mProfiles[mCount]->profileLocation = nsCRT::strdup(directory);
|
||||
mProfiles[mCount]->isMigrated = nsCRT::strdup(isMigrated);
|
||||
|
||||
if (NCProfileName)
|
||||
mProfiles[mCount]->NCProfileName = nsCRT::strdup(NCProfileName);
|
||||
if (NCDeniedService)
|
||||
mProfiles[mCount]->NCDeniedService = nsCRT::strdup(NCDeniedService);
|
||||
|
||||
|
||||
if (PL_strcmp(isMigrated, REGISTRY_YES_STRING) == 0)
|
||||
mNumProfiles++;
|
||||
else if (PL_strcmp(isMigrated, REGISTRY_NO_STRING) == 0)
|
||||
mNumOldProfiles++;
|
||||
|
||||
mCount++;
|
||||
CRTFREEIF(directory);
|
||||
}
|
||||
rv = enumKeys->Next();
|
||||
}
|
||||
|
||||
mFixRegEntries = PR_FALSE;
|
||||
rv = CloseRegistry();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Return the number of 5x profiles.
|
||||
// A member variable mNumProfiles is used
|
||||
// to keep track of 5x profiles.
|
||||
void
|
||||
nsProfileAccess::GetNumProfiles(PRInt32 *numProfiles)
|
||||
{
|
||||
*numProfiles = mNumProfiles;
|
||||
}
|
||||
|
||||
// Return the number of 4x (>=4.5 & < 5.0) profiles.
|
||||
// A member variable mNumOldProfiles is used
|
||||
// to keep track of 4x profiles.
|
||||
void
|
||||
nsProfileAccess::GetNum4xProfiles(PRInt32 *numProfiles)
|
||||
{
|
||||
*numProfiles = mNumOldProfiles;
|
||||
}
|
||||
|
||||
// If the application can't find the current profile,
|
||||
// the first profile will be used as the current profile.
|
||||
// This routine returns the first 5x profile.
|
||||
// Caller must free up the string (firstProfile).
|
||||
void
|
||||
nsProfileAccess::GetFirstProfile(char **firstProfile)
|
||||
{
|
||||
PRInt32 index = 0;
|
||||
|
||||
*firstProfile = nsnull;
|
||||
|
||||
for(index = 0; index < mCount; index++)
|
||||
{
|
||||
if (PL_strcmp(mProfiles[index]->isMigrated, REGISTRY_YES_STRING) == 0)
|
||||
{
|
||||
*firstProfile = nsCRT::strdup(mProfiles[index]->profileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the current profile. Opearting directly on the tree.
|
||||
// A separate struct should be maintained for the top level info.
|
||||
// That way we can eliminate additional registry access. For
|
||||
// now, we depend on registry operations.
|
||||
// Capture the current profile information into mCurrentProfile.
|
||||
void
|
||||
nsProfileAccess::SetCurrentProfile(const char *profileName)
|
||||
{
|
||||
mCurrentProfile = nsCRT::strdup(profileName);
|
||||
mProfileDataChanged = PR_TRUE;
|
||||
}
|
||||
|
||||
// Return the current profile value.
|
||||
// If mCurrent profile is already set, that value is returned.
|
||||
// If there is only one profile that value is set to CurrentProfile.
|
||||
void
|
||||
nsProfileAccess::GetCurrentProfile(char **profileName)
|
||||
{
|
||||
|
||||
*profileName = nsnull;
|
||||
|
||||
if (mCurrentProfile)
|
||||
{
|
||||
if ((PL_strcmp(mCurrentProfile,"") != 0) || mForgetProfileCalled)
|
||||
{
|
||||
*profileName = nsCRT::strdup(mCurrentProfile);
|
||||
}
|
||||
}
|
||||
|
||||
// If there are profiles and profileName is not
|
||||
// set yet. Get the first one and set it as Current Profile.
|
||||
if (mNumProfiles > 0 && (*profileName == nsnull))
|
||||
{
|
||||
GetFirstProfile(profileName);
|
||||
SetCurrentProfile(*profileName);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete a profile from profile structs
|
||||
void
|
||||
nsProfileAccess::RemoveSubTree(const char* profileName)
|
||||
{
|
||||
// delete this entry from the mProfiles array
|
||||
// by moving the pointers with something like memmove
|
||||
// decrement mCount if it works.
|
||||
PRInt32 index = 0;
|
||||
PRInt32 i = 0;
|
||||
PRBool isOldProfile = PR_FALSE;
|
||||
|
||||
index = FindProfileIndex(profileName);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
if (PL_strcmp(mProfiles[index]->isMigrated, REGISTRY_NO_STRING) == 0)
|
||||
isOldProfile = PR_TRUE;
|
||||
|
||||
PRInt32 movePositions = mCount - index;
|
||||
for (i=0; i < movePositions; i++,index++)
|
||||
nsCRT::memmove(&mProfiles[index], &mProfiles[index+1], sizeof(ProfileStruct *));
|
||||
|
||||
mCount--;
|
||||
if (isOldProfile)
|
||||
mNumOldProfiles--;
|
||||
else
|
||||
mNumProfiles--;
|
||||
|
||||
if (PL_strcmp(profileName, mCurrentProfile) == 0)
|
||||
PL_strcpy(mCurrentProfile,"");
|
||||
}
|
||||
}
|
||||
|
||||
// Fix registry incompatabilities with previous builds
|
||||
void
|
||||
nsProfileAccess::FixRegEntry(char** dirName)
|
||||
{
|
||||
nsSimpleCharString decodedDirName;
|
||||
PRBool haveHexBytes = PR_TRUE;
|
||||
|
||||
// Decode the directory name to return the ordinary string
|
||||
nsInputStringStream stream(*dirName);
|
||||
nsPersistentFileDescriptor descriptor;
|
||||
|
||||
char bigBuffer[MAX_PERSISTENT_DATA_SIZE + 1];
|
||||
// The first 8 bytes of the data should be a hex version of the data size to follow.
|
||||
PRInt32 bytesRead = NUM_HEX_BYTES;
|
||||
bytesRead = stream.read(bigBuffer, bytesRead);
|
||||
if (bytesRead != NUM_HEX_BYTES)
|
||||
haveHexBytes = PR_FALSE;
|
||||
|
||||
if (haveHexBytes)
|
||||
{
|
||||
bigBuffer[NUM_HEX_BYTES] = '\0';
|
||||
|
||||
for (int i = 0; i < NUM_HEX_BYTES; i++)
|
||||
{
|
||||
if (!(ISHEX(bigBuffer[i])))
|
||||
{
|
||||
haveHexBytes = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (haveHexBytes)
|
||||
{
|
||||
//stream(dirName);
|
||||
PR_sscanf(bigBuffer, "%x", (PRUint32*)&bytesRead);
|
||||
if (bytesRead > MAX_PERSISTENT_DATA_SIZE)
|
||||
{
|
||||
// Try to tolerate encoded values with no length header
|
||||
bytesRead = NUM_HEX_BYTES + stream.read(bigBuffer + NUM_HEX_BYTES, MAX_PERSISTENT_DATA_SIZE - NUM_HEX_BYTES);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Now we know how many bytes to read, do it.
|
||||
bytesRead = stream.read(bigBuffer, bytesRead);
|
||||
}
|
||||
// Make sure we are null terminated
|
||||
bigBuffer[bytesRead]='\0';
|
||||
descriptor.SetData(bigBuffer, bytesRead);
|
||||
descriptor.GetData(decodedDirName);
|
||||
|
||||
*dirName = nsCRT::strdup(decodedDirName);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the index of a given profiel from the arraf of profile structs.
|
||||
PRInt32
|
||||
nsProfileAccess::FindProfileIndex(const char* profileName)
|
||||
{
|
||||
PRInt32 retval = -1;
|
||||
PRInt32 index = 0;
|
||||
|
||||
for (index=0; index < mCount; index++)
|
||||
{
|
||||
if (PL_strcmp(profileName, mProfiles[index]->profileName) == 0)
|
||||
{
|
||||
retval = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Flush profile information from the data structure to the registry.
|
||||
nsresult
|
||||
nsProfileAccess::UpdateRegistry()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!mProfileDataChanged)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = OpenRegistry();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Enumerate all subkeys (immediately) under the given node.
|
||||
nsCOMPtr<nsIEnumerator> enumKeys;
|
||||
nsRegistryKey profilesTreeKey;
|
||||
|
||||
// Get the major subtree
|
||||
rv = m_registry->GetSubtree(nsIRegistry::Common, REGISTRY_PROFILE_SUBTREE_STRING, &profilesTreeKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get the current profile
|
||||
rv = m_registry->SetString(profilesTreeKey, REGISTRY_CURRENT_PROFILE_STRING, mCurrentProfile);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get the current profile
|
||||
rv = m_registry->SetString(profilesTreeKey, REGISTRY_VERSION_STRING, mVersion);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get the current profile
|
||||
rv = m_registry->SetString(profilesTreeKey, REGISTRY_HAVE_PREG_INFO_STRING, mHavePREGInfo);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = m_registry->EnumerateSubtrees(profilesTreeKey, getter_AddRefs(enumKeys));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = enumKeys->First();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
while( (NS_OK != enumKeys->IsDone()) )
|
||||
{
|
||||
nsCOMPtr<nsISupports> base;
|
||||
|
||||
rv = enumKeys->CurrentItem( getter_AddRefs(base) );
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get specific interface.
|
||||
nsCOMPtr <nsIRegistryNode> node;
|
||||
nsIID nodeIID = NS_IREGISTRYNODE_IID;
|
||||
|
||||
rv = base->QueryInterface( nodeIID, getter_AddRefs(node));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get node name.
|
||||
nsXPIDLCString profile;
|
||||
nsXPIDLCString isMigrated;
|
||||
nsXPIDLCString directory;
|
||||
|
||||
rv = node->GetName( getter_Copies(profile) );
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRInt32 index = 0;
|
||||
|
||||
index = FindProfileIndex(profile);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
// This profile is deleted.
|
||||
rv = m_registry->RemoveSubtree(profilesTreeKey, profile);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsRegistryKey profKey;
|
||||
|
||||
rv = m_registry->GetSubtree(profilesTreeKey, profile, &profKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = m_registry->SetString(profKey, REGISTRY_DIRECTORY_STRING, mProfiles[index]->profileLocation);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = m_registry->SetString(profKey, REGISTRY_MIGRATED_STRING, mProfiles[index]->isMigrated);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = m_registry->SetString(profKey, REGISTRY_NC_PROFILE_NAME_STRING, mProfiles[index]->NCProfileName);
|
||||
rv = m_registry->SetString(profKey, REGISTRY_NC_SERVICE_DENIAL_STRING, mProfiles[index]->NCDeniedService);
|
||||
|
||||
mProfiles[index]->updateProfileEntry = PR_FALSE;
|
||||
}
|
||||
rv = enumKeys->Next();
|
||||
}
|
||||
|
||||
// Take care of new nodes
|
||||
for (int i = 0; i < mCount; i++)
|
||||
{
|
||||
if (mProfiles[i]->updateProfileEntry)
|
||||
{
|
||||
nsRegistryKey profKey;
|
||||
|
||||
rv = m_registry->AddSubtree(profilesTreeKey, mProfiles[i]->profileName, &profKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = m_registry->SetString(profKey, REGISTRY_DIRECTORY_STRING, mProfiles[i]->profileLocation);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = m_registry->SetString(profKey, REGISTRY_MIGRATED_STRING, mProfiles[i]->isMigrated);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mProfiles[i]->updateProfileEntry = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
rv = CloseRegistry();
|
||||
mProfileDataChanged = PR_FALSE;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Return the list of profiles, 4x and 5x.
|
||||
// For 4x profiles text "- migrate" is appended
|
||||
// to inform the JavaScript about the migration status.
|
||||
void
|
||||
nsProfileAccess::GetProfileList(char **profileListStr)
|
||||
{
|
||||
nsCAutoString profileList("");
|
||||
|
||||
for (PRInt32 index=0; index < mCount; index++)
|
||||
{
|
||||
if (index != 0)
|
||||
{
|
||||
profileList += ",";
|
||||
}
|
||||
profileList += mProfiles[index]->profileName;
|
||||
|
||||
if (PL_strcmp(mProfiles[index]->isMigrated, REGISTRY_NO_STRING) == 0)
|
||||
profileList += " - migrate";
|
||||
}
|
||||
|
||||
*profileListStr = nsCRT::strdup((const char *)profileList);
|
||||
}
|
||||
|
||||
// Return a boolean based on the profile existence.
|
||||
PRBool
|
||||
nsProfileAccess::ProfileExists(const char *profileName)
|
||||
{
|
||||
PRBool exists = PR_FALSE;
|
||||
|
||||
for (PRInt32 index=0; index < mCount; index++)
|
||||
{
|
||||
if (PL_strcmp(mProfiles[index]->profileName, profileName) == 0)
|
||||
{
|
||||
exists = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
// Capture the 4x profile information from the old registry (4x)
|
||||
nsresult
|
||||
nsProfileAccess::Get4xProfileInfo(const char *registryName)
|
||||
{
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
mNumOldProfiles = 0;
|
||||
|
||||
#if defined(XP_PC) || defined(XP_MAC)
|
||||
nsCOMPtr <nsIRegistry> oldReg;
|
||||
rv = nsComponentManager::CreateInstance(kRegistryCID,
|
||||
nsnull,
|
||||
nsIRegistry::GetIID(),
|
||||
getter_AddRefs(oldReg));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = oldReg->Open(registryName);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Enumerate 4x tree and create an array of that information.
|
||||
// Enumerate all subkeys (immediately) under the given node.
|
||||
nsCOMPtr<nsIEnumerator> enumKeys;
|
||||
|
||||
rv = oldReg->EnumerateSubtrees(nsIRegistry::Users,
|
||||
getter_AddRefs(enumKeys));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = enumKeys->First();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Enumerate subkeys till done.
|
||||
while( (NS_OK != enumKeys->IsDone()))
|
||||
{
|
||||
nsCOMPtr<nsISupports> base;
|
||||
rv = enumKeys->CurrentItem(getter_AddRefs(base));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Get specific interface.
|
||||
nsCOMPtr <nsIRegistryNode> node;
|
||||
nsIID nodeIID = NS_IREGISTRYNODE_IID;
|
||||
rv = base->QueryInterface( nodeIID, getter_AddRefs(node));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
char *profile = nsnull;
|
||||
rv = node->GetName(&profile);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsRegistryKey key;
|
||||
|
||||
rv = oldReg->GetSubtree(nsIRegistry::Users, profile, &key);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLCString profLoc;
|
||||
|
||||
rv = oldReg->GetString( key, "ProfileLocation", getter_Copies(profLoc));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
#if defined(DEBUG_profile)
|
||||
printf("oldProflie Location = %s\n", profLoc);
|
||||
#endif
|
||||
|
||||
m4xProfiles[mNumOldProfiles] = (ProfileStruct *) PR_Malloc(sizeof(ProfileStruct));
|
||||
if (!m4xProfiles[mNumOldProfiles])
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
m4xProfiles[mNumOldProfiles]->profileName = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->profileLocation = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->isMigrated = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->NCProfileName = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->NCDeniedService = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->updateProfileEntry = PR_TRUE;
|
||||
|
||||
m4xProfiles[mNumOldProfiles]->profileName = nsCRT::strdup(nsUnescape(profile));
|
||||
m4xProfiles[mNumOldProfiles]->profileLocation = nsCRT::strdup(profLoc);
|
||||
m4xProfiles[mNumOldProfiles]->isMigrated = nsCRT::strdup(REGISTRY_NO_STRING);
|
||||
|
||||
mNumOldProfiles++;
|
||||
|
||||
rv = enumKeys->Next();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
oldReg->Close();
|
||||
|
||||
#elif defined (XP_BEOS)
|
||||
#else
|
||||
/* XP_UNIX */
|
||||
char *unixProfileName = PR_GetEnv(PROFILE_NAME_ENVIRONMENT_VARIABLE);
|
||||
char *unixProfileDirectory = PR_GetEnv(PROFILE_HOME_ENVIRONMENT_VARIABLE);
|
||||
|
||||
if (!unixProfileName || !unixProfileDirectory || (PL_strlen(unixProfileName) == 0) || (PL_strlen(unixProfileDirectory) == 0)) {
|
||||
unixProfileName = PR_GetEnv(USER_ENVIRONMENT_VARIABLE);
|
||||
unixProfileDirectory = PR_GetEnv(HOME_ENVIRONMENT_VARIABLE);
|
||||
}
|
||||
|
||||
if (unixProfileName && unixProfileDirectory) {
|
||||
|
||||
m4xProfiles[mNumOldProfiles] = (ProfileStruct *) PR_Malloc(sizeof(ProfileStruct));
|
||||
if (!m4xProfiles[mNumOldProfiles])
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
m4xProfiles[mNumOldProfiles]->profileName = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->profileLocation = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->isMigrated = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->NCProfileName = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->NCDeniedService = nsnull;
|
||||
m4xProfiles[mNumOldProfiles]->updateProfileEntry = PR_TRUE;
|
||||
|
||||
m4xProfiles[mNumOldProfiles]->profileName = nsCRT::strdup(nsUnescape(unixProfileName));
|
||||
m4xProfiles[mNumOldProfiles]->profileLocation = nsCRT::strdup(unixProfileDirectory);
|
||||
|
||||
PRInt32 length = PL_strlen(unixProfileDirectory) + PL_strlen("/.netscape");
|
||||
m4xProfiles[mNumOldProfiles]->profileLocation = (char *) PR_Realloc(m4xProfiles[mNumOldProfiles]->profileLocation, length+1);
|
||||
PL_strcpy(m4xProfiles[mNumOldProfiles]->profileLocation, unixProfileDirectory);
|
||||
PL_strcat(m4xProfiles[mNumOldProfiles]->profileLocation, "/.netscape");
|
||||
|
||||
m4xProfiles[mNumOldProfiles]->isMigrated = nsCRT::strdup(REGISTRY_NO_STRING);
|
||||
|
||||
mNumOldProfiles++;
|
||||
}
|
||||
#endif
|
||||
|
||||
m4xCount = mNumOldProfiles;
|
||||
|
||||
if (m4xCount > 0) {
|
||||
UpdateProfileArray();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Update the mozregistry with the 4x profile names
|
||||
// and thier locations. Entry REGISTRY_MIGRATED_STRING is set to REGISTRY_NO_STRING
|
||||
// to differentiate these profiles from 5x profiles.
|
||||
nsresult
|
||||
nsProfileAccess::UpdateProfileArray()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
for (PRInt32 idx = 0; idx < m4xCount; idx++)
|
||||
{
|
||||
nsFileSpec profileDir(m4xProfiles[idx]->profileLocation);
|
||||
|
||||
PRBool exists;
|
||||
exists = ProfileExists(m4xProfiles[idx]->profileName);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// That profile already exists...
|
||||
// move on.....
|
||||
if (exists) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsXPIDLCString profileDirString;
|
||||
nsCOMPtr<nsIFileSpec>spec;
|
||||
rv = NS_NewFileSpecWithSpec(profileDir, getter_AddRefs(spec));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = spec->GetPersistentDescriptorString(getter_Copies(profileDirString));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && profileDirString)
|
||||
{
|
||||
|
||||
PRInt32 length = PL_strlen(profileDirString);
|
||||
m4xProfiles[idx]->profileLocation = (char *) PR_Realloc(m4xProfiles[idx]->profileLocation, length+1);
|
||||
|
||||
PL_strcpy(m4xProfiles[idx]->profileLocation, profileDirString);
|
||||
|
||||
SetValue(m4xProfiles[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
mProfileDataChanged = PR_TRUE;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Set the PREG flag to indicate if that info exists
|
||||
void
|
||||
nsProfileAccess::SetPREGInfo(const char* pregInfo)
|
||||
{
|
||||
mHavePREGInfo = nsCRT::strdup(pregInfo);
|
||||
}
|
||||
|
||||
//Get the for PREG info.
|
||||
void
|
||||
nsProfileAccess::GetPREGInfo(char **info)
|
||||
{
|
||||
*info = nsnull;
|
||||
|
||||
if (mHavePREGInfo)
|
||||
*info = nsCRT::strdup(mHavePREGInfo);
|
||||
}
|
||||
|
||||
96
mozilla/profile/src/nsProfileAccess.h
Normal file
96
mozilla/profile/src/nsProfileAccess.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef __nsProfileAccess_h___
|
||||
#define __nsProfileAccess_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIRegistry.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#define _MAX_NUM_PROFILES 100
|
||||
#define _MAX_4X_PROFILES 50
|
||||
|
||||
//typedef struct _profile_struct ProfileStruct;
|
||||
typedef struct _profile_struct {
|
||||
char* profileName;
|
||||
char* profileLocation;
|
||||
char* isMigrated;
|
||||
char* NCProfileName;
|
||||
char* NCDeniedService;
|
||||
PRBool updateProfileEntry;
|
||||
}ProfileStruct;
|
||||
|
||||
class nsProfileAccess
|
||||
{
|
||||
|
||||
private:
|
||||
nsCOMPtr <nsIRegistry> m_registry;
|
||||
|
||||
ProfileStruct *mProfiles[_MAX_NUM_PROFILES];
|
||||
PRInt32 mCount;
|
||||
char* mCurrentProfile;
|
||||
char* mVersion;
|
||||
PRBool mFixRegEntries;
|
||||
char* mHavePREGInfo;
|
||||
PRInt32 m4xCount;
|
||||
|
||||
nsresult OpenRegistry();
|
||||
nsresult CloseRegistry();
|
||||
|
||||
public:
|
||||
PRBool mProfileDataChanged;
|
||||
PRBool mForgetProfileCalled;
|
||||
PRInt32 mNumProfiles;
|
||||
PRInt32 mNumOldProfiles;
|
||||
ProfileStruct *m4xProfiles[_MAX_4X_PROFILES];
|
||||
|
||||
nsProfileAccess();
|
||||
virtual ~nsProfileAccess();
|
||||
|
||||
nsresult SetValue(ProfileStruct* aProfile);
|
||||
nsresult FillProfileInfo();
|
||||
|
||||
void GetNumProfiles(PRInt32 *numProfiles);
|
||||
void GetNum4xProfiles(PRInt32 *numProfiles);
|
||||
void GetFirstProfile(char **firstProfile);
|
||||
|
||||
void SetCurrentProfile(const char *profileName);
|
||||
void GetCurrentProfile(char **profileName);
|
||||
|
||||
void RemoveSubTree(const char* profileName);
|
||||
void FixRegEntry(char** dirName);
|
||||
|
||||
nsresult HavePregInfo(char **info);
|
||||
nsresult GetValue(const char* profileName, ProfileStruct** aProfile);
|
||||
PRInt32 FindProfileIndex(const char* profileName);
|
||||
|
||||
nsresult UpdateRegistry();
|
||||
void GetProfileList(char **profileListStr);
|
||||
PRBool ProfileExists(const char *profileName);
|
||||
nsresult Get4xProfileInfo(const char *registryName);
|
||||
nsresult UpdateProfileArray();
|
||||
void SetPREGInfo(const char* pregInfo);
|
||||
void GetPREGInfo(char** pregInfo);
|
||||
void FreeProfileMembers(ProfileStruct *aProfile[], PRInt32 numElems);
|
||||
};
|
||||
|
||||
#endif // __nsProfileAccess_h___
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user