gecko-dev/cmd/winfe/profile.cpp
1998-03-28 02:44:41 +00:00

538 lines
13 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "stdafx.h"
#include "property.h"
#include "styles.h"
#include "helper.h"
#include "display.h"
#include "dialog.h"
#include "secnav.h"
#include "custom.h"
#include "cxabstra.h"
#include "setupwiz.h"
#include "logindg.h"
#include "prefapi.h"
#include "profile.h"
#include <ctype.h>
#define BUFSZ MAX_PATH+1
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
CUserProfileDB::CUserProfileDB( )
{
#ifdef XP_WIN
m_hUser.Empty();
#else
#endif
m_csUserAddr.Empty();
m_csProfileDirectory.Empty();
OpenUserProfileDB();
}
CUserProfileDB::~CUserProfileDB( )
{
// m_cslProfiles->RemoveAll();
CloseUserProfileDB();
}
HPROFILE CUserProfileDB::OpenUserProfileDB( /* Handle Mac Parms somehow */ )
{
//============================================================================
#ifdef XP_WIN32
CString csTmp = "SOFTWARE\\Netscape\\Netscape Navigator\\Users\\";
int result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, csTmp, NULL,
KEY_READ | KEY_WRITE, &m_hProfileDB);
if ( result != ERROR_SUCCESS )
m_hProfileDB = NULL;
//============================================================================
#else // XP_WIN16
login_GetIniFilePath(m_hProfileDB);
#endif
return m_hProfileDB;
}
int CUserProfileDB::CloseUserProfileDB( )
{
int ret = TRUE;
//============================================================================
#ifdef XP_WIN32
if (m_hProfileDB)
ret = RegCloseKey(m_hProfileDB);
m_hProfileDB = NULL;
//============================================================================
#else
m_hProfileDB = "";
#endif
return ret;
}
void CUserProfileDB::GetUserProfilesList( CStringList *cslProfiles )
{
int idx = 0;
char lpBuf[MAX_PATH + 1];
// Loop and delete entries?
cslProfiles->RemoveAll();
if (!m_hProfileDB)
OpenUserProfileDB();
//============================================================================
#ifdef XP_WIN32
while(RegEnumKey(m_hProfileDB,idx,lpBuf,MAX_PATH+1) == ERROR_SUCCESS) {
cslProfiles->AddHead(lpBuf);
idx++;
}
//============================================================================
#else
auto char ca_iniBuff[_MAX_PATH];
// load the user list from the ini file
::GetPrivateProfileString("Users", NULL, "", ca_iniBuff, _MAX_PATH, m_hProfileDB);
while (ca_iniBuff[idx]) {
XP_STRCPY(lpBuf, &ca_iniBuff[idx]);
cslProfiles->AddHead(lpBuf);
idx += XP_STRLEN(lpBuf) + 1; // skip the single null and the prof we just read
}
#endif
}
//-----------------------------------------------
// Returns string allocated with XP_ALLOC or NULL
//
LPSTR CUserProfileDB::GetUserProfileValue(
HUSER hUser,
CString csName )
{
//============================================================================
#ifdef XP_WIN32
HKEY hKeyRet = NULL;
CString csSub = "SOFTWARE\\Netscape\\Netscape Navigator\\Users\\" + hUser;
DWORD type, size = 0;
char *pString = NULL;
int result;
// Unfortunately, this open is _necessary_!
result = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
csSub,
NULL,
KEY_QUERY_VALUE,
&hKeyRet);
if(result != ERROR_SUCCESS)
goto Fail;
result = RegQueryValueEx(hKeyRet, (const char *) csName,
NULL, &type, NULL, &size);
if ( result != ERROR_SUCCESS || size == 0 )
goto Fail;
// allocate space to hold the string
pString = (char *) XP_ALLOC((size + 1) * sizeof(char));
// actually load the string now that we have the space
result = RegQueryValueEx(hKeyRet, (const char *) csName, NULL,
&type, (LPBYTE) pString, &size);
if ( result != ERROR_SUCCESS || size == 0 )
{
XP_FREE(pString);
pString = NULL;
goto Fail;
}
pString[size] = '\0';
Fail:
if (hKeyRet) RegCloseKey(hKeyRet);
//============================================================================
#else // XP_WIN16
CString csSection;
CString csResource;
char * pString = NULL;
auto char ca_iniBuff[_MAX_PATH];
if ( csName == "DirRoot" )
{
// This one comes from the base [Users] section, <user>=value
csSection = "Users";
csResource = hUser;
}
else
{
// These come from the [<username>] section, name=value
csSection = hUser;
csResource = csName;
}
if (::GetPrivateProfileString( csSection, csResource, "",
ca_iniBuff, _MAX_PATH,
m_hProfileDB) )
{
// allocate space to hold the string
pString = XP_STRDUP(ca_iniBuff);
}
#endif
return pString;
}
int CUserProfileDB::SetUserProfileValue(
HUSER hUser,
CString csName,
CString csValue )
{
int result;
//============================================================================
#ifdef XP_WIN32
HKEY hKeyRet = NULL;
CString csSub = "SOFTWARE\\Netscape\\Netscape Navigator\\Users\\" + hUser;
const char *pValue = (const char *) csValue;
// Unfortunately, this open is _necessary_!
result = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
csSub,
NULL,
KEY_QUERY_VALUE,
&hKeyRet);
if(result == ERROR_SUCCESS)
result = RegSetValueEx( m_hProfileDB, csName, NULL,
REG_SZ,
(const BYTE *) pValue,
strlen(pValue) );
if (hKeyRet) RegCloseKey(hKeyRet);
//============================================================================
#else // XP_WIN16
CString csSection;
CString csResource;
if ( csName == "DirRoot" )
{
// This one comes from the base [Users] section, <user>=value
csSection = "Users";
csResource = hUser;
}
else
{
// These come from the [<username>] section, name=value
csSection = hUser;
csResource = csName;
}
result = ::WritePrivateProfileString( csSection, csResource,
(const char *) csValue,
m_hProfileDB);
#endif
return result;
}
void CUserProfileDB::GetUserProfile( HUSER hUser )
{
char *pString;
//============================================================================
#ifdef XP_WIN
m_hUser = hUser;
/*
** munge user name to profile name
*/
int iAtSign = m_hUser.Find('@');
if (iAtSign != -1)
m_hUser = m_hUser.Left(iAtSign);
#endif
// Find the profile directory
pString = GetUserProfileValue( m_hUser, "DirRoot" );
if (pString)
{
m_csProfileDirectory = pString;
XP_FREE(pString);
}
else
m_csProfileDirectory.Empty();
// Find the EMail Address
pString = GetUserProfileValue( m_hUser, "EmailAddr" );
if (pString)
{
m_csUserAddr = pString;
XP_FREE(pString);
}
else
m_csUserAddr.Empty();
// Add filling in any new profile members here...
return ;
}
int CUserProfileDB::BuildDirectoryPath( const char *path )
{
int ret;
XP_StatStruct statinfo;
ret = _stat((char *) path, &statinfo);
if(ret == -1) {
// see if we can just create it
char * slash = strchr(path,'\\');
while (slash) {
slash[0] = NULL;
ret = _mkdir(path);
slash[0] = '\\';
if (slash+1) slash = strchr(slash+1,'\\');
}
ret = _mkdir(path);
if ( ret == -1 ) return FALSE;
// ERROR: Create Directory failed
}
// If directory exists already, then what?
return TRUE;
}
int CUserProfileDB::AddNewProfile(
HUSER hUser,
CString csProfileDirectory,
int iUpgradeOption )
{
int ret;
// Using _mkdir for win16/win32 compatibility
// Do we need new error constants if this gets incorporated into the setupwiz dialogs?
m_hUser = hUser;
m_csProfileDirectory = csProfileDirectory;
/*
** Create the directory if necessary
*/
BuildDirectoryPath( (const char *) csProfileDirectory );
/*
** Handle upgrades. The Move operation moves data and leaves links behind.
** The Copy operation copies the data and changes are not reflected to old
** space. Ignore leaves old space alone and creates new profile.
*/
if (iUpgradeOption == UPGRADE_MOVE || iUpgradeOption == UPGRADE_COPY) {
ret = login_UpdateFilesToNewLocation( csProfileDirectory, NULL,
(iUpgradeOption == UPGRADE_COPY) );
// ret value is hosed, doesn't actually do any checking!
if ( !ret ) return NULL;
// ERROR: Couldn't Move/Copy old profile
ret = login_UpdatePreferencesToJavaScript( csProfileDirectory );
// ret value is hosed, doesn't actually do any checking!
if ( !ret ) return NULL;
// ERROR: Couldn't update old preferences to JS
} else {
// just create the directories --
login_CreateEmptyProfileDir( csProfileDirectory, NULL, FALSE);
}
/*
** Create the user and add the profile directory to the user's registry entry
** !! Don't do this until all other operations have succeeded!
*/
ret = login_CreateNewUserKey( hUser, csProfileDirectory );
if ( ret != ERROR_SUCCESS ) return NULL;
// ERROR: Create User Entry failed
/*
** Now that we've done all this work, let's fill the profile up with stuff
**/
PREF_SavePrefFile();
// ERROR: ?
return 1;
}
int CUserProfileDB::DeleteUserProfile( HUSER hUser )
{
char *pString;
pString = GetUserProfileValue( hUser, "DirRoot" );
if (pString)
{
XP_RemoveDirectoryRecursive(pString, xpURL);
XP_FREE(pString);
}
if (m_hUser && hUser == m_hUser)
m_csProfileDirectory.Empty();
return login_DeleteUserKey( hUser );
}
// Given a profile name, return a profile directory path in Program Files
BOOL CUserProfileDB::AssignProfileDirectoryName(HUSER hUser, CString &csUserDirectory)
{
CString install("");
CString userDir = "\\Users\\";
// first chance of default is based on any existing user dir
char *pExistingUser = NULL;
pExistingUser = login_GetCurrentUser();
if (pExistingUser) {
char *pDir = login_GetUserProfileDir();
if (pDir && *pDir) {
install = pDir;
int iLastSlash = -1;
iLastSlash = install.ReverseFind('\\');
if (iLastSlash > 2) {
int iPos = install.GetLength()-iLastSlash;
install= install.Left(install.GetLength()-iPos+1);
}
// already have the user dir as part of the path so empty out the string
userDir.Empty();
XP_FREE(pDir);
}
}
if (install.IsEmpty())
{
// Try to find the official install directory value in the registry
#ifdef XP_WIN32
CString csProduct;
csProduct.LoadString(IDS_NETHELP_REGISTRY);
csProduct = FEU_GetCurrentRegistry(csProduct);
if (!csProduct.IsEmpty())
install = FEU_GetInstallationDirectory(csProduct, szLoadString(IDS_INSTALL_DIRECTORY));
#else
install = FEU_GetInstallationDirectory(szLoadString(IDS_NETSCAPE_REGISTRY), szLoadString(IDS_INSTALL_DIRECTORY));
if (!install.IsEmpty())
{
// Assuming we got a name back, remove the Program part - which is only there for 16 bit, not for 32 bit.
int iLastSlash = install.ReverseFind('\\');
if (iLastSlash != -1)
{
CString subdir = install.Mid(iLastSlash+1);
if (!subdir.CompareNoCase("Program"))
install = install.Left(iLastSlash);
}
}
#endif
}
// If we can't get it from the registry, try the program name
if (install.IsEmpty())
{
char aPath[_MAX_PATH];
if (::GetModuleFileName(theApp.m_hInstance, aPath, sizeof(aPath)))
{
// WIN16 default: c:\Netscape\Comm\Program\netscape.exe
// WIN32 default: c:\Program Files\Netscape\Communicator\Program\netscape.exe
// Remove the trailing netscape.exe stuff
char *pSlash = ::strrchr(aPath, '\\');
if(pSlash)
*pSlash = '\0';
// Remove the Program part
pSlash = ::strrchr(aPath, '\\');
if (pSlash)
*pSlash = '\0';
install = aPath;
}
}
// If we still can't get it, use these defaults
if (install.IsEmpty())
{
#ifdef XP_WIN32
install = "C:\\Program Files\\Netscape";
#else
install = "C:\\Netscape";
#endif
}
else
{
// Assuming we got a name back somehow, remove the Comm[unicator] part
int iLastSlash = install.ReverseFind('\\');
if (iLastSlash != -1)
{
CString subdir = install.Mid(iLastSlash+1);
#ifdef XP_WIN32
if ((!subdir.CompareNoCase("Communicator")) || (!subdir.CompareNoCase("Commun~1")))
#else
if (!subdir.CompareNoCase("Comm"))
#endif
install = install.Left(iLastSlash);
}
}
//we need to make sure that the hUser is valid characters
int idx =0;
for (idx =0; idx < hUser.GetLength(); idx++) {
if (!__iscsym(hUser.GetAt(idx)))
hUser.SetAt(idx,'_');
}
#ifdef XP_WIN32
csUserDirectory = install + userDir + hUser;
#else
csUserDirectory = install + userDir + hUser.Left(8);
#endif
return TRUE;
}