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:
sspitzer%netscape.com 1999-12-06 18:27:26 +00:00
parent 0ed0a6ba1a
commit ff7a3079f8
2 changed files with 1040 additions and 0 deletions

View 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);
}

View 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___