Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1346 lines
36 KiB

/* Copyright (c) 1995, Microsoft Corporation, all rights reserved
**
** pbuser.c
** User preference storage routines
** Listed alphabetically
**
** 10/31/95 Steve Cobb
*/
#include <windows.h> // Win32 root
#include <debug.h> // Trace/Assert library
#include <nouiutil.h> // Heap macros
#include <pbuser.h> // Our public header
#include <rasdlg.h> // RAS common dialog header for RASMD_*
/* Default user preference settings.
*/
static const PBUSER g_pbuserDefaults =
{
FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE,
0, 15, 1200, FALSE, TRUE, FALSE,
CBM_Maybe, NULL, NULL,
PBM_System, NULL, NULL, NULL,
NULL, FALSE,
NULL, NULL, NULL,
0x7FFFFFFF, 0x7FFFFFFF, NULL,
FALSE, FALSE
};
/*----------------------------------------------------------------------------
** Local prototypes (alphabetically)
**----------------------------------------------------------------------------
*/
VOID
GetCallbackList(
IN HKEY hkey,
OUT DTLLIST** ppListResult );
VOID
GetLocationList(
IN HKEY hkey,
OUT DTLLIST** ppListResult );
VOID
MoveLogonPreferences(
void );
VOID
MoveUserPreferences(
void );
DWORD
ReadUserPreferences(
IN HKEY hkey,
OUT PBUSER* pUser );
DWORD
SetCallbackList(
IN HKEY hkey,
IN DTLLIST* pList );
DWORD
SetDefaultUserPreferences(
OUT PBUSER* pUser,
IN DWORD dwMode );
DWORD
SetLocationList(
IN HKEY hkey,
IN DTLLIST* pList );
DWORD
WriteUserPreferences(
IN HKEY hkey,
IN PBUSER* pUser );
/*----------------------------------------------------------------------------
** Phonebook preference routines (alphabetically)
**----------------------------------------------------------------------------
*/
DTLNODE*
CreateLocationNode(
IN DWORD dwLocationId,
IN DWORD iPrefix,
IN DWORD iSuffix )
/* Returns a LOCATIONINFO node associated with TAPI location
** 'dwLocationId', prefix index 'iPrefix' and suffix index 'iSuffix'.
*/
{
DTLNODE* pNode;
LOCATIONINFO* pInfo;
pNode = DtlCreateSizedNode( sizeof(LOCATIONINFO), 0L );
if (!pNode)
return NULL;
pInfo = (LOCATIONINFO* )DtlGetData( pNode );
pInfo->dwLocationId = dwLocationId;
pInfo->iPrefix = iPrefix;
pInfo->iSuffix = iSuffix;
return pNode;
}
DTLNODE*
CreateCallbackNode(
IN TCHAR* pszPortName,
IN TCHAR* pszDeviceName,
IN TCHAR* pszNumber,
IN DWORD dwDeviceType )
/* Returns a CALLBACKINFO node containing a copy of 'pszPortName',
** 'pszDeviceName' and 'pszNumber' and 'dwDeviceType' or NULL on error.
** It is caller's responsibility to DestroyCallbackNode the returned node.
*/
{
DTLNODE* pNode;
CALLBACKINFO* pInfo;
pNode = DtlCreateSizedNode( sizeof(CALLBACKINFO), 0L );
if (!pNode)
return NULL;
pInfo = (CALLBACKINFO* )DtlGetData( pNode );
pInfo->pszPortName = StrDup( pszPortName );
pInfo->pszDeviceName = StrDup( pszDeviceName );
pInfo->pszNumber = StrDup( pszNumber );
pInfo->dwDeviceType = dwDeviceType;
if (!pInfo->pszPortName || !pInfo->pszDeviceName || !pInfo->pszNumber)
{
Free0( pInfo->pszPortName );
Free0( pInfo->pszDeviceName );
Free0( pInfo->pszNumber );
DtlDestroyNode( pNode );
return NULL;
}
return pNode;
}
VOID
DestroyLocationNode(
IN DTLNODE* pNode )
/* Release memory allociated with location node 'pNode'.
*/
{
DtlDestroyNode( pNode );
}
VOID
DestroyCallbackNode(
IN DTLNODE* pNode )
/* Release memory allociated with callback node 'pNode'.
*/
{
CALLBACKINFO* pInfo;
ASSERT(pNode);
pInfo = (CALLBACKINFO* )DtlGetData( pNode );
ASSERT(pInfo);
Free0( pInfo->pszPortName );
Free0( pInfo->pszDeviceName );
Free0( pInfo->pszNumber );
DtlDestroyNode( pNode );
}
VOID
DestroyUserPreferences(
IN PBUSER* pUser )
/* Releases memory allocated by GetUserPreferences and zeros the
** structure.
*/
{
if (pUser->fInitialized)
{
DtlDestroyList( pUser->pdtllistCallback, DestroyCallbackNode );
DtlDestroyList( pUser->pdtllistPhonebooks, DestroyPszNode );
DtlDestroyList( pUser->pdtllistAreaCodes, DestroyPszNode );
DtlDestroyList( pUser->pdtllistPrefixes, DestroyPszNode );
DtlDestroyList( pUser->pdtllistSuffixes, DestroyPszNode );
DtlDestroyList( pUser->pdtllistLocations, DestroyLocationNode );
Free0( pUser->pszPersonalFile );
Free0( pUser->pszAlternatePath );
Free0( pUser->pszLastCallbackByCaller );
Free0( pUser->pszDefaultEntry );
}
ZeroMemory( pUser, sizeof(*pUser) );
}
DTLNODE*
DuplicateLocationNode(
IN DTLNODE* pNode )
/* Duplicates LOCATIONINFO node 'pNode'. See DtlDuplicateList.
**
** Returns the address of the allocated node or NULL if out of memory. It
** is caller's responsibility to free the returned node.
*/
{
LOCATIONINFO* pInfo = (LOCATIONINFO* )DtlGetData( pNode );
return CreateLocationNode(
pInfo->dwLocationId, pInfo->iPrefix, pInfo->iSuffix );
}
DWORD
DwGetUserPreferences(
OUT PBUSER* pUser,
IN DWORD dwMode )
/* Load caller's 'pUser' with user phonebook preferences from the
** registry. 'DwMode' indicates the preferences to get, either the normal
** interactive user, the pre-logon, or router preferences.
**
** Returns 0 if successful or an error code. If successful, caller should
** eventually call DestroyUserPreferences to release the returned heap
** buffers.
*/
{
DWORD dwErr;
TRACE1("GetUserPreferences(m=%d)",dwMode);
/* Move the user preferences, if it's not already been done.
*/
if (dwMode == UPM_Normal)
MoveUserPreferences();
else if (dwMode == UPM_Logon)
MoveLogonPreferences();
dwErr = SetDefaultUserPreferences( pUser, dwMode );
if (dwErr == 0)
{
HKEY hkey;
DWORD dwErr2;
if (dwMode == UPM_Normal)
{
dwErr2 = RegOpenKeyEx(
HKEY_CURRENT_USER, (LPCTSTR )REGKEY_HkcuRas,
0, KEY_READ, &hkey );
}
else if (dwMode == UPM_Logon)
{
dwErr2 = RegOpenKeyEx(
HKEY_USERS, (LPCTSTR )REGKEY_HkuRasLogon,
0, KEY_READ, &hkey );
}
else
{
ASSERT(dwMode==UPM_Router);
dwErr2 = RegOpenKeyEx(
HKEY_LOCAL_MACHINE, (LPCTSTR )REGKEY_HklmRouter,
0, KEY_READ, &hkey );
}
if (dwErr2 == 0)
{
if (ReadUserPreferences( hkey, pUser ) != 0)
dwErr = SetDefaultUserPreferences( pUser, dwMode );
RegCloseKey( hkey );
}
else
{
TRACE1("RegOpenKeyEx=%d",dwErr2);
}
}
TRACE1("GetUserPreferences=%d",dwErr);
return dwErr;
}
DWORD
GetUserPreferences(HANDLE hConnection,
PBUSER *pUser,
DWORD dwMode)
{
RAS_RPC *pRasRpcConnection = (RAS_RPC *) hConnection;
DWORD dwError = ERROR_SUCCESS;
if( NULL == pRasRpcConnection
|| pRasRpcConnection->fLocal)
{
dwError = DwGetUserPreferences(pUser, dwMode);
}
else
{
dwError = RemoteGetUserPreferences(hConnection,
pUser,
dwMode);
}
return dwError;
}
DWORD
DwSetUserPreferences(
IN PBUSER* pUser,
IN DWORD dwMode )
/* Set current user phonebook preferences in the registry from caller's
** settings in 'pUser', if necessary. 'DwMode' indicates the preferences
** to get, either the normal interactive user, the pre-logon, or router
** preferences.
**
** Returns 0 if successful, or an error code. Caller's 'pUser' is marked
** clean if successful.
*/
{
DWORD dwErr;
DWORD dwDisposition;
HKEY hkey;
TRACE1("SetUserPreferences(m=%d)",dwMode);
if (!pUser->fDirty)
return 0;
/* Create the preference key, or if it exists just open it.
*/
if (dwMode == UPM_Normal)
{
dwErr = RegCreateKeyEx( HKEY_CURRENT_USER, REGKEY_HkcuRas,
0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hkey, &dwDisposition );
}
else if (dwMode == UPM_Logon)
{
dwErr = RegCreateKeyEx( HKEY_USERS, REGKEY_HkuRasLogon,
0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hkey, &dwDisposition );
}
else
{
ASSERT(dwMode==UPM_Router);
dwErr = RegCreateKeyEx( HKEY_LOCAL_MACHINE, REGKEY_HklmRouter,
0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hkey, &dwDisposition );
}
if (dwErr == 0)
{
dwErr = WriteUserPreferences( hkey, pUser );
RegCloseKey( hkey );
}
TRACE1("SetUserPreferences=%d",dwErr);
return dwErr;
}
DWORD
SetUserPreferences(HANDLE hConnection,
PBUSER *pUser,
DWORD dwMode)
{
DWORD dwError = ERROR_SUCCESS;
RAS_RPC *pRasRpcConnection = (RAS_RPC *) hConnection;
if( NULL == pRasRpcConnection
|| pRasRpcConnection->fLocal)
{
dwError = DwSetUserPreferences(pUser, dwMode);
}
else
{
dwError = RemoteSetUserPreferences(hConnection,
pUser,
dwMode);
}
return dwError;
}
// Reads the operator assisted dial user parameter directly from
// the registry.
DWORD SetUserManualDialEnabling (
IN OUT BOOL bEnable,
IN DWORD dwMode )
{
DWORD dwErr;
DWORD dwDisposition;
HKEY hkey;
TRACE2("SetUserManualDialEnabling (en=%d) (m=%d)",bEnable, dwMode);
/* Create the preference key, or if it exists just open it.
*/
if (dwMode == UPM_Normal)
{
dwErr = RegCreateKeyEx( HKEY_CURRENT_USER, REGKEY_HkcuRas,
0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hkey, &dwDisposition );
}
else if (dwMode == UPM_Logon)
{
dwErr = RegCreateKeyEx( HKEY_USERS, REGKEY_HkuRasLogon,
0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hkey, &dwDisposition );
}
else
return ERROR_INVALID_PARAMETER;
if (dwErr != 0)
return dwErr;
dwErr = SetRegDword( hkey, REGVAL_fOperatorDial,
!!bEnable );
RegCloseKey( hkey );
return dwErr;
}
// Sets the operator assisted dialing parameter directly in the
// registry.
DWORD GetUserManualDialEnabling (
IN PBOOL pbEnabled,
IN DWORD dwMode )
{
DWORD dwErr;
DWORD dwDisposition;
HKEY hkey;
TRACE1("GetUserManualDialEnabling (m=%d)", dwMode);
if (!pbEnabled)
return ERROR_INVALID_PARAMETER;
// Set defaults
*pbEnabled = g_pbuserDefaults.fOperatorDial;
/* Create the preference key, or if it exists just open it.
*/
if (dwMode == UPM_Normal)
{
dwErr = RegCreateKeyEx( HKEY_CURRENT_USER, REGKEY_HkcuRas,
0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hkey, &dwDisposition );
}
else if (dwMode == UPM_Logon)
{
dwErr = RegCreateKeyEx( HKEY_USERS, REGKEY_HkuRasLogon,
0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hkey, &dwDisposition );
}
else
return ERROR_INVALID_PARAMETER;
if (dwErr != 0)
return dwErr;
GetRegDword( hkey, REGVAL_fOperatorDial,
pbEnabled );
RegCloseKey( hkey );
return dwErr;
}
/*----------------------------------------------------------------------------
** Utilities (alphabetically)
**----------------------------------------------------------------------------
*/
VOID
GetCallbackList(
IN HKEY hkey,
OUT DTLLIST** ppListResult )
/* Replaces '*ppListResult' with a list containing a node for each device
** name under registry value "REGVAL_szCallback" of registry key 'hkey'.
** If no values exist *ppListResult' is replaced with an empty list.
**
** It is caller's responsibility to destroy the returned list if non-NULL.
*/
{
DWORD dwErr;
TCHAR szDP[ RAS_MaxDeviceName + 2 + MAX_PORT_NAME + 1 + 1 ];
TCHAR* pszDevice;
TCHAR* pszPort;
TCHAR* pszNumber;
DWORD dwDeviceType;
DWORD cb;
INT i;
DTLLIST* pList;
DTLNODE* pNode;
HKEY hkeyCb;
HKEY hkeyDP;
pList = DtlCreateList( 0 );
if (!pList)
return;
dwErr = RegOpenKeyEx( hkey, REGKEY_Callback, 0, KEY_READ, &hkeyCb );
if (dwErr == 0)
{
for (i = 0; TRUE; ++i)
{
cb = sizeof(szDP)/sizeof(TCHAR);
dwErr = RegEnumKeyEx(
hkeyCb, i, szDP, &cb, NULL, NULL, NULL, NULL );
if (dwErr == ERROR_NO_MORE_ITEMS)
break;
if (dwErr != 0)
continue;
/* Ignore keys not of the form "device (port)".
*/
if (!DeviceAndPortFromPsz( szDP, &pszDevice, &pszPort ))
continue;
dwErr = RegOpenKeyEx( hkeyCb, szDP, 0, KEY_READ, &hkeyDP );
if (dwErr == 0)
{
GetRegDword( hkeyDP, REGVAL_dwDeviceType, &dwDeviceType );
dwErr = GetRegSz( hkeyDP, REGVAL_szNumber, &pszNumber );
if (dwErr == 0)
{
pNode = CreateCallbackNode(
pszPort, pszDevice, pszNumber, dwDeviceType );
if (pNode)
DtlAddNodeLast( pList, pNode );
Free( pszNumber );
}
RegCloseKey( hkeyDP );
}
Free( pszDevice );
Free( pszPort );
}
RegCloseKey( hkeyCb );
}
DtlDestroyList( *ppListResult, DestroyCallbackNode );
*ppListResult = pList;
}
VOID
GetLocationList(
IN HKEY hkey,
OUT DTLLIST** ppListResult )
/* Replaces '*ppListResult' with a list containing a node for each
** location under registry value "REGVAL_szLocation" of registry key
** 'hkey'. If no values exist *ppListResult' is replaced with an empty
** list.
**
** It is caller's responsibility to destroy the returned list if non-NULL.
*/
{
DWORD dwErr;
TCHAR szId[ MAXLTOTLEN + 1 ];
DWORD cb;
INT i;
DTLLIST* pList;
DTLNODE* pNode;
HKEY hkeyL;
HKEY hkeyId;
pList = DtlCreateList( 0 );
if (!pList)
return;
dwErr = RegOpenKeyEx( hkey, REGKEY_Location, 0, KEY_READ, &hkeyL );
if (dwErr == 0)
{
for (i = 0; TRUE; ++i)
{
cb = MAXLTOTLEN + 1;
dwErr = RegEnumKeyEx( hkeyL, i, szId, &cb, NULL, NULL, NULL, NULL );
if (dwErr == ERROR_NO_MORE_ITEMS)
break;
if (dwErr != 0)
continue;
dwErr = RegOpenKeyEx( hkeyL, szId, 0, KEY_READ, &hkeyId );
if (dwErr == 0)
{
DWORD dwId;
DWORD iPrefix;
DWORD iSuffix;
dwId = (DWORD )TToL( szId );
iPrefix = 0;
GetRegDword( hkeyId, REGVAL_dwPrefix, &iPrefix );
iSuffix = 0;
GetRegDword( hkeyId, REGVAL_dwSuffix, &iSuffix );
pNode = CreateLocationNode( dwId, iPrefix, iSuffix );
if (!pNode)
continue;
DtlAddNodeLast( pList, pNode );
RegCloseKey( hkeyId );
}
}
RegCloseKey( hkeyL );
}
DtlDestroyList( *ppListResult, DestroyLocationNode );
*ppListResult = pList;
}
VOID
MoveLogonPreferences(
void )
/* Move logon preferences from the NT 4.0 location to a new unique
** position, if necessary. This manuever is added because in NT 4.0 user
** preference calls from LocalSystem service use the old logon location at
** HKU\.DEFAULT due to fallbacks in the registry APIs causing logon and
** LocalSystem settings to overwrite each other.
*/
{
DWORD dwErr;
HKEY hkeyOld;
HKEY hkeyNew;
PBUSER user;
dwErr = RegOpenKeyEx(
HKEY_USERS, (LPCTSTR )REGKEY_HkuOldRasLogon,
0, KEY_READ, &hkeyOld );
if (dwErr != 0)
return;
dwErr = RegOpenKeyEx(
HKEY_USERS, (LPCTSTR )REGKEY_HkuRasLogon,
0, KEY_READ, &hkeyNew );
if (dwErr == 0)
RegCloseKey( hkeyNew );
else
{
/* Old tree exists and new tree doesn't. Move a copy of the old tree
** to the new tree.
*/
dwErr = SetDefaultUserPreferences( &user, UPM_Logon );
if (dwErr == 0)
{
dwErr = ReadUserPreferences( hkeyOld, &user );
if (dwErr == 0)
dwErr = SetUserPreferences( NULL, &user, UPM_Logon );
}
DestroyUserPreferences( &user );
TRACE1("MoveLogonPreferences=%d",dwErr);
}
RegCloseKey( hkeyOld );
}
VOID
MoveUserPreferences(
void )
/* Move user preferences from their old net-tools registry location to the
** new location nearer the other RAS keys.
*/
{
DWORD dwErr;
HKEY hkeyOld;
HKEY hkeyNew;
/* See if the old current-user key exists.
*/
dwErr = RegOpenKeyEx(
HKEY_CURRENT_USER, (LPCTSTR )REGKEY_HkcuOldRas, 0,
KEY_ALL_ACCESS, &hkeyOld );
if (dwErr == 0)
{
PBUSER user;
/* Read the preferences at the old key.
*/
TRACE("Getting old prefs");
dwErr = SetDefaultUserPreferences( &user, UPM_Normal );
if (dwErr == 0)
{
dwErr = ReadUserPreferences( hkeyOld, &user );
if (dwErr == 0)
{
/* Write the preferences at the new key.
*/
user.fDirty = TRUE;
dwErr = SetUserPreferences( NULL, &user, FALSE );
if (dwErr == 0)
{
/* Blow away the old tree.
*/
dwErr = RegOpenKeyEx(
HKEY_CURRENT_USER, (LPCTSTR )REGKEY_HkcuOldRasParent,
0, KEY_ALL_ACCESS, &hkeyNew );
if (dwErr == 0)
{
TRACE("Delete old prefs");
dwErr = RegDeleteTree( hkeyNew, REGKEY_HkcuOldRasRoot );
RegCloseKey( hkeyNew );
}
}
}
}
RegCloseKey( hkeyOld );
TRACE1("MoveUserPreferences=%d",dwErr);
}
}
DWORD
ReadUserPreferences(
IN HKEY hkey,
OUT PBUSER* pUser )
/* Fill caller's 'pUser' buffer with user preferences from RAS-Phonebook
** registry tree 'hkey'.
**
** Returns 0 if successful, false otherwise.
*/
{
BOOL fOldSettings;
DWORD dwErr;
TRACE("ReadUserPreferences");
/* Read the values.
*/
{
DWORD dwMode;
/* Lack of a phonebook mode key indicates that we are updating old NT
** 3.51-style settings.
*/
dwMode = 0xFFFFFFFF;
GetRegDword( hkey, REGVAL_dwPhonebookMode, &dwMode );
if (dwMode != 0xFFFFFFFF)
{
pUser->dwPhonebookMode = dwMode;
fOldSettings = FALSE;
}
else
fOldSettings = TRUE;
}
GetRegDword( hkey, REGVAL_fOperatorDial,
&pUser->fOperatorDial );
GetRegDword( hkey, REGVAL_fPreviewPhoneNumber,
&pUser->fPreviewPhoneNumber );
GetRegDword( hkey, REGVAL_fUseLocation,
&pUser->fUseLocation );
GetRegDword( hkey, REGVAL_fShowLights,
&pUser->fShowLights );
GetRegDword( hkey, REGVAL_fShowConnectStatus,
&pUser->fShowConnectStatus );
GetRegDword( hkey, REGVAL_fNewEntryWizard,
&pUser->fNewEntryWizard );
GetRegDword( hkey, REGVAL_fCloseOnDial,
&pUser->fCloseOnDial );
GetRegDword( hkey, REGVAL_fAllowLogonPhonebookEdits,
&pUser->fAllowLogonPhonebookEdits );
GetRegDword( hkey, REGVAL_fAllowLogonLocationEdits,
&pUser->fAllowLogonLocationEdits );
GetRegDword( hkey, REGVAL_fSkipConnectComplete,
&pUser->fSkipConnectComplete );
GetRegDword( hkey, REGVAL_dwRedialAttempts,
&pUser->dwRedialAttempts );
GetRegDword( hkey, REGVAL_dwRedialSeconds,
&pUser->dwRedialSeconds );
GetRegDword( hkey, REGVAL_dwIdleDisconnectSeconds,
&pUser->dwIdleDisconnectSeconds );
GetRegDword( hkey, REGVAL_fRedialOnLinkFailure,
&pUser->fRedialOnLinkFailure );
GetRegDword( hkey, REGVAL_fPopupOnTopWhenRedialing,
&pUser->fPopupOnTopWhenRedialing );
GetRegDword( hkey, REGVAL_fExpandAutoDialQuery,
&pUser->fExpandAutoDialQuery );
GetRegDword( hkey, REGVAL_dwCallbackMode,
&pUser->dwCallbackMode );
GetRegDword( hkey, REGVAL_fUseAreaAndCountry,
&pUser->fUseAreaAndCountry );
GetRegDword( hkey, REGVAL_dwXWindow,
&pUser->dwXPhonebook );
GetRegDword( hkey, REGVAL_dwYWindow,
&pUser->dwYPhonebook );
//
// For NT5, we ignore the "require wizard" setting since
// we always require the user to use the wizard to create
// new connections
//
pUser->fNewEntryWizard = TRUE;
do
{
GetCallbackList( hkey, &pUser->pdtllistCallback );
dwErr = GetRegMultiSz( hkey, REGVAL_mszPhonebooks,
&pUser->pdtllistPhonebooks, NT_Psz );
if (dwErr != 0)
break;
dwErr = GetRegMultiSz( hkey, REGVAL_mszAreaCodes,
&pUser->pdtllistAreaCodes, NT_Psz );
if (dwErr != 0)
break;
/* If the prefixes key doesn't exist don't read an empty list over the
** defaults.
*/
if (RegValueExists( hkey, REGVAL_mszPrefixes ))
{
dwErr = GetRegMultiSz( hkey, REGVAL_mszPrefixes,
&pUser->pdtllistPrefixes, NT_Psz );
if (dwErr != 0)
break;
}
dwErr = GetRegMultiSz( hkey, REGVAL_mszSuffixes,
&pUser->pdtllistSuffixes, NT_Psz );
if (dwErr != 0)
break;
GetLocationList( hkey, &pUser->pdtllistLocations );
dwErr = GetRegSz( hkey, REGVAL_szLastCallbackByCaller,
&pUser->pszLastCallbackByCaller );
if (dwErr != 0)
break;
/* Get the personal phonebook file name, if any. In NT 3.51, the full
** path was stored, but now "<nt>\system32\ras" directory is assumed.
** This gives better (not perfect) behavior with user profiles rooted
** on different drive letters.
*/
{
TCHAR* psz;
dwErr = GetRegSz( hkey, REGVAL_szPersonalPhonebookPath, &psz );
if (dwErr != 0)
break;
if (*psz == TEXT('\0'))
{
Free(psz);
dwErr = GetRegSz( hkey, REGVAL_szPersonalPhonebookFile,
&pUser->pszPersonalFile );
if (dwErr != 0)
break;
}
else
{
pUser->pszPersonalFile = StrDup( StripPath( psz ) );
Free( psz );
if (!pUser->pszPersonalFile)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
}
}
dwErr = GetRegSz( hkey, REGVAL_szAlternatePhonebookPath,
&pUser->pszAlternatePath );
if (dwErr != 0)
break;
dwErr = GetRegSz( hkey, REGVAL_szDefaultEntry,
&pUser->pszDefaultEntry );
if (dwErr != 0)
break;
if (fOldSettings)
{
TCHAR* psz;
psz = NULL;
dwErr = GetRegSz( hkey, REGVAL_szUsePersonalPhonebook, &psz );
if (dwErr != 0)
break;
if (psz)
{
if (*psz == TEXT('1'))
pUser->dwPhonebookMode = PBM_Personal;
Free( psz );
}
}
}
while (FALSE);
if (dwErr != 0)
DestroyUserPreferences( pUser );
TRACE1("ReadUserPreferences=%d",dwErr);
return dwErr;
}
DWORD
SetCallbackList(
IN HKEY hkey,
IN DTLLIST* pList )
/* Sets callback tree under registry key 'hkey' to the list of callback
** nodes 'pList'.
**
** Returns 0 if successful or an error code.
*/
{
DWORD dwErr;
TCHAR szDP[ RAS_MaxDeviceName + 2 + MAX_PORT_NAME + 1 + 1 ];
DWORD cb;
DWORD i;
DWORD dwDisposition;
HKEY hkeyCb;
HKEY hkeyDP;
DTLNODE* pNode;
dwErr = RegCreateKeyEx( hkey, REGKEY_Callback,
0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hkeyCb, &dwDisposition );
if (dwErr != 0)
return dwErr;
/* Delete all keys and values under the callback key.
*/
for (;;)
{
cb = sizeof(szDP);
dwErr = RegEnumKeyEx(
hkeyCb, 0, szDP, &cb, NULL, NULL, NULL, NULL );
if (dwErr != 0)
break;
dwErr = RegDeleteKey( hkeyCb, szDP );
if (dwErr != 0)
break;
}
if (dwErr == ERROR_NO_MORE_ITEMS)
dwErr = 0;
if (dwErr == 0)
{
/* Add the new device/port sub-trees.
*/
for (pNode = DtlGetFirstNode( pList );
pNode;
pNode = DtlGetNextNode( pNode ))
{
CALLBACKINFO* pInfo;
TCHAR* psz;
pInfo = (CALLBACKINFO* )DtlGetData( pNode );
ASSERT(pInfo);
ASSERT(pInfo->pszPortName);
ASSERT(pInfo->pszDeviceName);
ASSERT(pInfo->pszNumber);
psz = PszFromDeviceAndPort(
pInfo->pszDeviceName, pInfo->pszPortName );
if (psz)
{
dwErr = RegCreateKeyEx( hkeyCb, psz, 0, TEXT(""),
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyDP,
&dwDisposition );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkeyDP, REGVAL_dwDeviceType,
pInfo->dwDeviceType );
if (dwErr == 0)
{
dwErr = SetRegSz( hkeyDP,
REGVAL_szNumber, pInfo->pszNumber );
}
RegCloseKey( hkeyDP );
}
else
dwErr = ERROR_NOT_ENOUGH_MEMORY;
if (dwErr != 0)
break;
}
}
RegCloseKey( hkeyCb );
return dwErr;
}
DWORD
SetDefaultUserPreferences(
OUT PBUSER* pUser,
IN DWORD dwMode )
/* Fill caller's 'pUser' buffer with default user preferences. 'DwMode'
** indicates the type of user preferences.
**
** Returns 0 if successful, false otherwise.
*/
{
DTLNODE* pNode;
/* Set defaults.
*/
CopyMemory( pUser, &g_pbuserDefaults, sizeof(*pUser) );
pUser->pdtllistCallback = DtlCreateList( 0L );
pUser->pdtllistPhonebooks = DtlCreateList( 0L );
pUser->pdtllistAreaCodes = DtlCreateList( 0L );
pUser->pdtllistPrefixes = DtlCreateList( 0L );
pUser->pdtllistSuffixes = DtlCreateList( 0L );
pUser->pdtllistLocations = DtlCreateList( 0L );
if (!pUser->pdtllistCallback
|| !pUser->pdtllistPhonebooks
|| !pUser->pdtllistAreaCodes
|| !pUser->pdtllistPrefixes
|| !pUser->pdtllistSuffixes
|| !pUser->pdtllistLocations)
{
/* Can't even get empty lists, so we're forced to return an error.
*/
DestroyUserPreferences( pUser );
return ERROR_NOT_ENOUGH_MEMORY;
}
/* Add the default prefixes.
*/
pNode = CreatePszNode( TEXT("0,") );
if (pNode)
DtlAddNodeLast( pUser->pdtllistPrefixes, pNode );
pNode = CreatePszNode( TEXT("9,") );
if (pNode)
DtlAddNodeLast( pUser->pdtllistPrefixes, pNode );
pNode = CreatePszNode( TEXT("8,") );
if (pNode)
DtlAddNodeLast( pUser->pdtllistPrefixes, pNode );
pNode = CreatePszNode( TEXT("70#") );
if (pNode)
DtlAddNodeLast( pUser->pdtllistPrefixes, pNode );
if (dwMode == UPM_Logon)
{
ASSERT(pUser->dwPhonebookMode!=PBM_Personal);
pUser->fShowLights = FALSE;
pUser->fSkipConnectComplete = TRUE;
}
if (dwMode == UPM_Router)
{
pUser->dwCallbackMode = CBM_No;
}
pUser->fInitialized = TRUE;
return 0;
}
DWORD
SetLocationList(
IN HKEY hkey,
IN DTLLIST* pList )
/* Sets by-location tree under registry key 'hkey' to the list of
** by-location nodes 'pList'.
**
** Returns 0 if successful or an error code.
*/
{
DWORD dwErr;
TCHAR szId[ MAXLTOTLEN + 1 ];
DWORD cb;
DWORD i;
DWORD dwDisposition;
HKEY hkeyL;
HKEY hkeyId;
DTLNODE* pNode;
dwErr = RegCreateKeyEx( hkey, REGKEY_Location,
0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hkeyL, &dwDisposition );
if (dwErr != 0)
return dwErr;
/* Delete all keys and values under the location key.
*/
for (;;)
{
cb = MAXLTOTLEN + 1;
dwErr = RegEnumKeyEx( hkeyL, 0, szId, &cb, NULL, NULL, NULL, NULL );
if (dwErr != 0)
break;
dwErr = RegDeleteKey( hkeyL, szId );
if (dwErr != 0)
break;
}
if (dwErr == ERROR_NO_MORE_ITEMS)
dwErr = 0;
if (dwErr == 0)
{
/* Add the new ID sub-trees.
*/
for (pNode = DtlGetFirstNode( pList );
pNode;
pNode = DtlGetNextNode( pNode ))
{
LOCATIONINFO* pInfo;
pInfo = (LOCATIONINFO* )DtlGetData( pNode );
ASSERT(pInfo);
LToT( pInfo->dwLocationId, szId, 10 );
dwErr = RegCreateKeyEx( hkeyL, szId, 0, TEXT(""),
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyId,
&dwDisposition );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkeyId, REGVAL_dwPrefix, pInfo->iPrefix );
if (dwErr == 0)
dwErr = SetRegDword( hkeyId, REGVAL_dwSuffix, pInfo->iSuffix );
RegCloseKey( hkeyId );
if (dwErr != 0)
break;
}
}
RegCloseKey( hkeyL );
return dwErr;
}
DWORD
WriteUserPreferences(
IN HKEY hkey,
IN PBUSER* pUser )
/* Write user preferences 'pUser' at RAS-Phonebook registry key 'hkey'.
**
** Returns 0 if successful or an error code.
*/
{
DWORD dwErr;
TRACE("WriteUserPreferences");
do
{
dwErr = SetRegDword( hkey, REGVAL_fOperatorDial,
pUser->fOperatorDial );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fPreviewPhoneNumber,
pUser->fPreviewPhoneNumber );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fUseLocation,
pUser->fUseLocation );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fShowLights,
pUser->fShowLights );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fShowConnectStatus,
pUser->fShowConnectStatus );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fNewEntryWizard,
pUser->fNewEntryWizard );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fCloseOnDial,
pUser->fCloseOnDial );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fAllowLogonPhonebookEdits,
pUser->fAllowLogonPhonebookEdits );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fAllowLogonLocationEdits,
pUser->fAllowLogonLocationEdits );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fSkipConnectComplete,
pUser->fSkipConnectComplete );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_dwRedialAttempts,
pUser->dwRedialAttempts );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_dwRedialSeconds,
pUser->dwRedialSeconds );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_dwIdleDisconnectSeconds,
pUser->dwIdleDisconnectSeconds );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fRedialOnLinkFailure,
pUser->fRedialOnLinkFailure );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fPopupOnTopWhenRedialing,
pUser->fPopupOnTopWhenRedialing );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fExpandAutoDialQuery,
pUser->fExpandAutoDialQuery );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_dwCallbackMode,
pUser->dwCallbackMode );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_dwPhonebookMode,
pUser->dwPhonebookMode );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_fUseAreaAndCountry,
pUser->fUseAreaAndCountry );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_dwXWindow,
pUser->dwXPhonebook );
if (dwErr != 0)
break;
dwErr = SetRegDword( hkey, REGVAL_dwYWindow,
pUser->dwYPhonebook );
dwErr = SetCallbackList( hkey, pUser->pdtllistCallback );
if (dwErr != 0)
break;
dwErr = SetRegMultiSz( hkey, REGVAL_mszPhonebooks,
pUser->pdtllistPhonebooks, NT_Psz );
if (dwErr != 0)
break;
dwErr = SetRegMultiSz( hkey, REGVAL_mszAreaCodes,
pUser->pdtllistAreaCodes, NT_Psz );
if (dwErr != 0)
break;
dwErr = SetRegMultiSz( hkey, REGVAL_mszPrefixes,
pUser->pdtllistPrefixes, NT_Psz );
if (dwErr != 0)
break;
dwErr = SetRegMultiSz( hkey, REGVAL_mszSuffixes,
pUser->pdtllistSuffixes, NT_Psz );
if (dwErr != 0)
break;
dwErr = SetLocationList( hkey, pUser->pdtllistLocations );
if (dwErr != 0)
break;
dwErr = SetRegSz( hkey, REGVAL_szLastCallbackByCaller,
pUser->pszLastCallbackByCaller );
if (dwErr != 0)
break;
dwErr = SetRegSz( hkey, REGVAL_szPersonalPhonebookFile,
pUser->pszPersonalFile );
if (dwErr != 0)
break;
dwErr = SetRegSz( hkey, REGVAL_szAlternatePhonebookPath,
pUser->pszAlternatePath );
if (dwErr != 0)
break;
dwErr = SetRegSz( hkey, REGVAL_szDefaultEntry,
pUser->pszDefaultEntry );
if (dwErr != 0)
break;
RegDeleteValue( hkey, REGVAL_szPersonalPhonebookPath );
}
while (FALSE);
if (dwErr == 0)
pUser->fDirty = FALSE;
TRACE1("WriteUserPreferences=%d",dwErr);
return dwErr;
}