windows-nt/Source/XPSP1/NT/windows/winstate/v1/loadras/loadras.cxx
2020-09-26 16:20:57 +08:00

1580 lines
38 KiB
C++

//--------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1999 - 2000.
//
//
// File: loadras
//
// Contents: Load system settings.
//
// chrisab 24-Mar-00 Created
//
//---------------------------------------------------------------
#include "loadhead.cxx"
#pragma hdrstop
#undef WINVER
#define WINVER 0x0500
#include <common.hxx>
#include <stdlib.h>
#include <winsock.h>
#include <objerror.h>
#include <loadstate.hxx>
#include <bothchar.hxx>
#include <winnetwk.h>
#include <ras.h>
#include <raserror.h>
#include <loadras.hxx>
extern "C" {
#include "tstr.h"
#include <pbk.h> // Ras phone book include
}
#define PRIVATE_RAS // Access the RAS phone book directly instead of using
// the public RAS APIs.
#define SIZEOF_STRUCT(structname, uptomember) ((int)((LPBYTE)(&((structname*)0)->uptomember) - ((LPBYTE)((structname*)0))))
//
// TRUE when rasman.dll has been
// successfully loaded and initailized.
// See LoadRasmanDllAndInit().
//
DWORD FRasInitialized = FALSE;
BOOL g_FRunningInAppCompatMode = FALSE;
DWORD DwRasInitializeError;
CRITICAL_SECTION PhonebookLock;
// Debugging only
#ifdef NEVER
DWORD RasDumpEntry(TCHAR *strEntryName, RASENTRY *pInRasEntry)
{
DWORD dwErr = ERROR_SUCCESS;
DWORD dwSize = sizeof(RASENTRY);
RASENTRY RasEntry, *pRasEntry;
RASDIALPARAMS RasDialParams;
// If no name passed in, print what pInRasEntry pts to
if( strEntryName == NULL )
{
if( pInRasEntry == NULL )
{
return ERROR_INVALID_HANDLE;
}
pRasEntry = pInRasEntry;
}
// Otherwise, if there's a buffer passed in, use that.
else
{
if( pInRasEntry == NULL )
{
pRasEntry = &RasEntry;
}
else
{
pRasEntry = pInRasEntry;
}
ZeroMemory( pRasEntry, sizeof(RASENTRY) );
pRasEntry->dwSize = sizeof(RASENTRY);
dwErr = RasGetEntryPropertiesW(NULL,
strEntryName,
pRasEntry,
&dwSize,
NULL,
NULL);
if( dwErr )
return dwErr;
}
if( strEntryName )
{
printf( "--- Dumping Ras entry %ls ---\n", strEntryName);
}
else
{
printf( "--- Dumping Ras entry at %p ---\n", pRasEntry);
}
printf( "dwfOptions = %x\n", pRasEntry->dwfOptions);
printf( "dwFramingProtocol = %d\n", pRasEntry->dwFramingProtocol);
printf( " Win2k Extended Info\n");
printf( "dwType = %d\n", pRasEntry->dwType);
printf( "dwEncryptionType = %d\n", pRasEntry->dwEncryptionType);
printf( "dwCustomAuthKey = %d\n", pRasEntry->dwCustomAuthKey);
printf( "szCustomDialDll = [%ls]\n", pRasEntry->szCustomDialDll);
printf( "dwVpnStrategy = %d\n", pRasEntry->dwVpnStrategy);
printf( "\n\n");
return dwErr;
}
DWORD RasDumpPhoneBookEntry(TCHAR *tszEntryName, PBENTRY *pEntry)
{
DWORD dwErr;
PBFILE pbfile;
DTLNODE *pdtlnode;
BOOL fCreated;
if( !pEntry && !tszEntryName )
return ERROR_INVALID_PARAMETER;
if( tszEntryName )
{
// Check and see if the entry name already exists in the phone book
dwErr = GetPbkAndEntryName(NULL,
tszEntryName,
0,
&pbfile,
&pdtlnode);
// if failed for some other reason than the entry doesn't exist, bail.
if( (dwErr != SUCCESS) && (dwErr != ERROR_CANNOT_FIND_PHONEBOOK_ENTRY) )
{
return dwErr;
}
if( pdtlnode == NULL )
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
return dwErr;
}
pEntry = (PBENTRY *) DtlGetData(pdtlnode);
printf( "--- Dumping Phonebook Entry %ls ---\n", tszEntryName);
}
else
{
printf( "--- Dumping Phonebook Entry at %p ---\n", pEntry);
}
printf( " pszEntryName = %ls\n", pEntry->pszEntryName);
printf( " dwType = %d\n", pEntry->dwType);
printf( " fSharedPhoneNum = %d\n", pEntry->fSharedPhoneNumbers);
printf( " dwDataEncryption = 0x%x\n", pEntry->dwDataEncryption);
printf( " dwAuthRestrictions = 0x%x\n", pEntry->dwAuthRestrictions);
printf( " dwTypicalAuth = 0x%x\n", pEntry->dwTypicalAuth);
printf( " dwCustomAuthKey = 0x%x\n", pEntry->dwCustomAuthKey);
printf( " fAutoLogon = %d\n", pEntry->fAutoLogon);
printf( " fPreviewUserPw = %d\n", pEntry->fPreviewUserPw);
printf( " fPreviewDomain = %d\n", pEntry->fPreviewDomain);
printf( "\n\n");
return 0;
}
#endif // NEVER - Debugging only
DWORD InitializeLoadRAS(DWORD dwReason)
{
DWORD dwErr = ERROR_SUCCESS;
if( dwReason == DLL_PROCESS_ATTACH )
{
InitializeCriticalSection(&PhonebookLock);
if( InitializePbk() != 0 )
return FALSE;
}
else if( dwReason == DLL_PROCESS_DETACH )
{
TerminatePbk();
}
return dwErr;
}
BOOL
FRunningInAppCompatMode()
{
BOOL fResult = FALSE;
TCHAR *pszCommandLine = NULL;
TCHAR *psz;
pszCommandLine = StrDup(GetCommandLine());
if(NULL == pszCommandLine)
{
goto done;
}
psz = pszCommandLine + lstrlen(pszCommandLine);
while( (TEXT('\\') != *psz)
&& (psz != pszCommandLine))
{
psz--;
}
if(TEXT('\\') == *psz)
{
psz++;
}
if( (0 == lstrcmpi(psz, TEXT("INETINFO.EXE")))
|| (0 == lstrcmpi(psz, TEXT("WSPSRV.EXE"))))
{
fResult = TRUE;
}
done:
if(NULL != pszCommandLine)
{
Free(pszCommandLine);
}
return fResult;
}
DWORD
LoadRasmanDllAndInit()
{
if (FRasInitialized)
{
return 0;
}
if (LoadRasmanDll())
{
return GetLastError();
}
//
// Success is returned if RasInitialize fails, in which
// case none of the APIs will ever do anything but report
// that RasInitialize failed. All this is to avoid the
// ugly system popup if RasMan service can't start.
//
if ((DwRasInitializeError = g_pRasInitialize()) != 0)
{
return DwRasInitializeError;
}
FRasInitialized = TRUE;
g_FRunningInAppCompatMode = FRunningInAppCompatMode();
// pmay: 300166
//
// We don't start rasauto automatically anymore.
//
// g_pRasStartRasAutoIfRequired();
return 0;
}
DWORD
IpAddrToString(
IN RASIPADDR* pipaddr,
OUT LPTSTR* ppszIpAddr
)
{
DWORD dwErr;
PCHAR psz;
LPTSTR pszIpAddr;
PULONG pul = (PULONG)pipaddr;
struct in_addr in_addr;
pszIpAddr = (TCHAR *) Malloc(17 * sizeof(TCHAR));
if (pszIpAddr == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
in_addr.s_addr = *pul;
psz = inet_ntoa(in_addr);
if (psz == NULL)
{
DbgPrint("IpAddrToString: inet_ntoa failed!\n");
Free(pszIpAddr);
return WSAGetLastError();
}
strcpyAtoT(pszIpAddr, psz);
*ppszIpAddr = pszIpAddr;
return 0;
}
VOID
GetDevicePortName(
IN TCHAR *pszDevicePortName,
OUT TCHAR *pszDeviceName,
OUT TCHAR *pszPortName
)
{
DWORD i, dwStart;
//
// Copy the device name.
//
lstrcpy(pszDeviceName, pszDevicePortName);
//
// Check to see if there is a NULL
// within MAX_PORT_NAME characters
// after the device name's NULL.If
// there is, the copy the characters
// between the NULLs as the port name.
//
*pszPortName = TEXT('\0');
dwStart = lstrlen(pszDeviceName) + 1;
for (i = 0; i < MAX_PORT_NAME; i++)
{
if (pszDevicePortName[dwStart + i] == TEXT('\0'))
{
lstrcpy(
pszPortName,
&pszDevicePortName[dwStart]);
break;
}
}
}
DWORD
CreateAndInitializePhone(
LPTSTR lpszAreaCode,
DWORD dwCountryCode,
DWORD dwCountryID,
LPTSTR lpszPhoneNumber,
BOOL fUseDialingRules,
LPTSTR lpszComment,
DTLNODE** ppdtlnode)
{
DWORD dwRetCode = ERROR_SUCCESS;
PBPHONE* pPhone;
DTLNODE* pdtlnode;
pdtlnode = CreatePhoneNode();
if (pdtlnode == NULL)
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
goto done;
}
pPhone = (PBPHONE *) DtlGetData(pdtlnode);
if(lpszAreaCode)
{
pPhone->pszAreaCode = StrDup(lpszAreaCode);
if(NULL == pPhone->pszAreaCode)
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
goto done;
}
}
else
{
pPhone->pszAreaCode = NULL;
}
pPhone->dwCountryCode = dwCountryCode;
pPhone->dwCountryID = dwCountryID;
pPhone->fUseDialingRules = fUseDialingRules;
if(lpszPhoneNumber)
{
pPhone->pszPhoneNumber = StrDup(lpszPhoneNumber);
if(NULL == pPhone->pszPhoneNumber)
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
goto done;
}
}
else
{
pPhone->pszPhoneNumber = NULL;
}
if(pPhone->pszComment)
{
pPhone->pszComment = StrDup(lpszComment);
if(NULL == pPhone->pszComment)
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
goto done;
}
}
else
{
pPhone->pszComment = NULL;
}
*ppdtlnode = pdtlnode;
done:
return dwRetCode;
}
void
SetBogusPortInformation(PBLINK *pLink, DWORD dwType)
{
PBPORT *pPort = &pLink->pbport;
if (dwType == RASET_Phone)
{
pPort->pszMedia = StrDup( TEXT(SERIAL_TXT) );
pPort->pbdevicetype = PBDT_Modem;
pPort->dwFlags |= PBP_F_BogusDevice;
}
else if (dwType == RASET_Vpn)
{
pPort->pszMedia = StrDup( TEXT("rastapi") );
pPort->pbdevicetype = PBDT_Vpn;
}
else
{
pPort->pszMedia = StrDup( TEXT(SERIAL_TXT) );
pPort->pbdevicetype = PBDT_Null;
pPort->dwFlags |= PBP_F_BogusDevice;
}
}
DWORD
WinState_RasEntryToPhonebookEntry(
IN LPCTSTR lpszEntry,
IN LPRASENTRY lpRasEntry,
IN DWORD dwcb,
IN LPBYTE lpbDeviceConfig,
IN DWORD dwcbDeviceConfig,
OUT PBENTRY *pEntry
)
{
DWORD dwErr, dwcbStr;
DTLNODE *pdtlnode;
PBDEVICETYPE pbdevicetype;
PBLINK *pLink;
DTLLIST *pdtllistPorts;
PBPORT *pPort;
DWORD i, cwDevices;
RASMAN_DEVICE *pDevices;
TCHAR szDeviceName[RAS_MaxDeviceName + 1];
TCHAR szPortName[MAX_PORT_NAME];
DTLNODE *pNodePhone;
LPTSTR pszAreaCode;
PBPHONE *pPhone;
BOOL fScriptBefore;
BOOL fScriptBeforeTerminal = FALSE;
LPTSTR pszScriptBefore;
BOOL fNewEntry = FALSE;
//
// Set up to access information for the first link.
//
pdtlnode = DtlGetFirstNode(pEntry->pdtllistLinks);
pLink = (PBLINK *)DtlGetData(pdtlnode);
ASSERT(NULL != pLink);
fScriptBefore = pLink->pbport.fScriptBeforeTerminal;
pszScriptBefore = pLink->pbport.pszScriptBefore;
if(NULL == pEntry->pszEntryName)
{
fNewEntry = TRUE;
}
//
// Get entry name.
//
Free0( pEntry->pszEntryName );
pEntry->pszEntryName = StrDup(lpszEntry);
//
// Get dwfOptions.
//
pEntry->dwIpAddressSource =
lpRasEntry->dwfOptions & RASEO_SpecificIpAddr ?
ASRC_RequireSpecific : ASRC_ServerAssigned;
pEntry->dwIpNameSource =
lpRasEntry->dwfOptions & RASEO_SpecificNameServers ?
ASRC_RequireSpecific : ASRC_ServerAssigned;
switch (lpRasEntry->dwFramingProtocol)
{
case RASFP_Ppp:
//
// Get PPP-based information.
//
pEntry->dwBaseProtocol = BP_Ppp;
#if AMB
pEntry->dwAuthentication = AS_PppThenAmb;
#endif
pEntry->fIpHeaderCompression =
(BOOL)lpRasEntry->dwfOptions & RASEO_IpHeaderCompression;
pEntry->fIpPrioritizeRemote =
(BOOL)lpRasEntry->dwfOptions & RASEO_RemoteDefaultGateway;
//
// Get specified IP addresses.
//
if (pEntry->dwIpAddressSource == ASRC_RequireSpecific)
{
dwErr = IpAddrToString(
&lpRasEntry->ipaddr,
&pEntry->pszIpAddress);
if (dwErr)
return dwErr;
}
else
{
pEntry->pszIpAddress = NULL;
}
if (pEntry->dwIpNameSource == ASRC_RequireSpecific)
{
dwErr = IpAddrToString(
&lpRasEntry->ipaddrDns,
&pEntry->pszIpDnsAddress);
if (dwErr)
{
return dwErr;
}
dwErr = IpAddrToString(
&lpRasEntry->ipaddrDnsAlt,
&pEntry->pszIpDns2Address);
if (dwErr)
{
return dwErr;
}
dwErr = IpAddrToString(
&lpRasEntry->ipaddrWins,
&pEntry->pszIpWinsAddress);
if (dwErr)
{
return dwErr;
}
dwErr = IpAddrToString(
&lpRasEntry->ipaddrWinsAlt,
&pEntry->pszIpWins2Address);
if (dwErr)
{
return dwErr;
}
}
else
{
pEntry->pszIpDnsAddress = NULL;
pEntry->pszIpDns2Address = NULL;
pEntry->pszIpWinsAddress = NULL;
pEntry->pszIpWins2Address = NULL;
}
//
// Get protocol information.
//
pEntry->dwfExcludedProtocols = 0;
if (!(lpRasEntry->dwfNetProtocols & RASNP_NetBEUI))
{
pEntry->dwfExcludedProtocols |= NP_Nbf;
}
if (!(lpRasEntry->dwfNetProtocols & RASNP_Ipx))
{
pEntry->dwfExcludedProtocols |= NP_Ipx;
}
if (!(lpRasEntry->dwfNetProtocols & RASNP_Ip))
{
pEntry->dwfExcludedProtocols |= NP_Ip;
}
break;
case RASFP_Slip:
//
// Get SLIP-based information.
//
pEntry->dwBaseProtocol = BP_Slip;
#if AMB
pEntry->dwAuthentication = AS_PppThenAmb;
#endif
pEntry->dwFrameSize = lpRasEntry->dwFrameSize;
pEntry->fIpHeaderCompression =
(BOOL)lpRasEntry->dwfOptions & RASEO_IpHeaderCompression;
pEntry->fIpPrioritizeRemote =
(BOOL)lpRasEntry->dwfOptions & RASEO_RemoteDefaultGateway;
//
// Get protocol information.
//
pEntry->dwfExcludedProtocols = (NP_Nbf|NP_Ipx);
if (pEntry->dwIpAddressSource == ASRC_RequireSpecific)
{
dwErr = IpAddrToString(
&lpRasEntry->ipaddr,
&pEntry->pszIpAddress);
if (dwErr)
{
return dwErr;
}
}
else
{
pEntry->pszIpAddress = NULL;
}
if (pEntry->dwIpNameSource == ASRC_RequireSpecific)
{
dwErr = IpAddrToString(
&lpRasEntry->ipaddrDns,
&pEntry->pszIpDnsAddress);
if (dwErr)
{
return dwErr;
}
dwErr = IpAddrToString(
&lpRasEntry->ipaddrDnsAlt,
&pEntry->pszIpDns2Address);
if (dwErr)
{
return dwErr;
}
dwErr = IpAddrToString(
&lpRasEntry->ipaddrWins,
&pEntry->pszIpWinsAddress);
if (dwErr)
{
return dwErr;
}
dwErr = IpAddrToString(
&lpRasEntry->ipaddrWinsAlt,
&pEntry->pszIpWins2Address);
if (dwErr)
{
return dwErr;
}
}
else
{
pEntry->pszIpDnsAddress = NULL;
pEntry->pszIpDns2Address = NULL;
pEntry->pszIpWinsAddress = NULL;
pEntry->pszIpWins2Address = NULL;
}
break;
case RASFP_Ras:
//
// Get AMB-based information.
//
pEntry->dwBaseProtocol = BP_Ras;
#if AMB
pEntry->dwAuthentication = AS_AmbOnly;
#endif
break;
}
pEntry->fLcpExtensions =
(BOOL)!(lpRasEntry->dwfOptions & RASEO_DisableLcpExtensions);
//
// If terminal before/after dial options are set,
// then update the entry. Otherwise, leave it as it
// is.
//
if(lpRasEntry->dwfOptions & RASEO_TerminalBeforeDial)
{
fScriptBeforeTerminal = TRUE;
}
if(lpRasEntry->dwfOptions & RASEO_TerminalAfterDial)
{
pEntry->fScriptAfterTerminal = TRUE;
}
else
{
pEntry->fScriptAfterTerminal = FALSE;
}
pEntry->fShowMonitorIconInTaskBar =
(BOOL) (lpRasEntry->dwfOptions & RASEO_ModemLights);
pEntry->fSwCompression =
(BOOL)(lpRasEntry->dwfOptions & RASEO_SwCompression);
if (lpRasEntry->dwfOptions & RASEO_RequireMsEncryptedPw)
{
pEntry->dwAuthRestrictions = AR_F_AuthMSCHAP;
}
else if (lpRasEntry->dwfOptions & RASEO_RequireEncryptedPw)
{
pEntry->dwAuthRestrictions = AR_F_AuthSPAP
| AR_F_AuthMD5CHAP
| AR_F_AuthMSCHAP;
}
else
{
pEntry->dwAuthRestrictions = AR_F_TypicalUnsecure;
}
pEntry->dwDataEncryption =
(lpRasEntry->dwfOptions & RASEO_RequireDataEncryption)
? DE_Mppe40bit
: DE_None;
pEntry->fAutoLogon =
(BOOL)(lpRasEntry->dwfOptions & RASEO_UseLogonCredentials);
pLink->fPromoteAlternates =
(BOOL)(lpRasEntry->dwfOptions & RASEO_PromoteAlternates);
pEntry->fShareMsFilePrint = pEntry->fBindMsNetClient =
(BOOL) !(lpRasEntry->dwfOptions & RASEO_SecureLocalFiles);
//
// Make sure that the network components section in the
// phonebook correspond to the values user is setting.
//
EnableOrDisableNetComponent(
pEntry,
TEXT("ms_msclient"),
pEntry->fBindMsNetClient);
EnableOrDisableNetComponent(
pEntry,
TEXT("ms_server"),
pEntry->fShareMsFilePrint);
if (*lpRasEntry->szAreaCode != TEXT('\0'))
{
//
// Make sure the area code does not contain
// non-numeric characters.
//
if (!ValidateAreaCode(lpRasEntry->szAreaCode))
{
return ERROR_INVALID_PARAMETER;
}
pszAreaCode = StrDup(lpRasEntry->szAreaCode);
}
else
{
pszAreaCode = NULL;
}
//
// Get script information.
//
if (lpRasEntry->szScript[0] == TEXT('['))
{
//
// Verify the switch is valid.
//
dwErr = GetRasSwitches(NULL, &pDevices, &cwDevices);
if (!dwErr)
{
CHAR szScriptA[MAX_PATH];
strcpyTtoA(szScriptA, lpRasEntry->szScript);
for (i = 0; i < cwDevices; i++)
{
if (!_stricmp(pDevices[i].D_Name, &szScriptA[1]))
{
pEntry->fScriptAfter = TRUE;
pEntry->pszScriptAfter =
StrDup(&lpRasEntry->szScript[1]);
if (pEntry->pszScriptAfter == NULL)
{
dwErr = GetLastError();
}
break;
}
}
Free(pDevices);
if (dwErr)
{
return dwErr;
}
}
}
else if (lpRasEntry->szScript[0] != TEXT('\0'))
{
pEntry->fScriptAfter = TRUE;
pEntry->pszScriptAfter = StrDup(lpRasEntry->szScript);
if (pEntry->pszScriptAfter == NULL)
{
return GetLastError();
}
}
else
{
if(pEntry->pszScriptAfter)
{
Free(pEntry->pszScriptAfter);
pEntry->pszScriptAfter = NULL;
}
pEntry->fScriptAfter = FALSE;
if(pLink->pbport.pszScriptBefore)
{
Free(pLink->pbport.pszScriptBefore);
pLink->pbport.pszScriptBefore = NULL;
pszScriptBefore = NULL;
}
pLink->pbport.fScriptBefore = FALSE;
fScriptBefore = FALSE;
}
//
// Get X.25 information.
//
pEntry->pszX25Network = NULL;
if (*lpRasEntry->szX25PadType != TEXT('\0'))
{
//
// Verify the X25 network is valid.
//
dwErr = GetRasPads(&pDevices, &cwDevices);
if (!dwErr)
{
CHAR szX25PadTypeA[RAS_MaxPadType + 1];
strcpyTtoA(szX25PadTypeA, lpRasEntry->szX25PadType);
for (i = 0; i < cwDevices; i++)
{
if (!_stricmp(pDevices[i].D_Name, szX25PadTypeA))
{
pEntry->pszX25Network = StrDup(lpRasEntry->szX25PadType);
break;
}
}
Free(pDevices);
}
}
pEntry->pszX25Address =
lstrlen(lpRasEntry->szX25Address)
? StrDup(lpRasEntry->szX25Address)
: NULL;
pEntry->pszX25Facilities =
lstrlen(lpRasEntry->szX25Facilities)
? StrDup(lpRasEntry->szX25Facilities)
: NULL;
pEntry->pszX25UserData =
lstrlen(lpRasEntry->szX25UserData)
? StrDup(lpRasEntry->szX25UserData)
: NULL;
//
// Get custom dial UI information.
//
pEntry->pszCustomDialDll =
lstrlen(lpRasEntry->szAutodialDll)
? StrDup(lpRasEntry->szAutodialDll)
: NULL;
pEntry->pszCustomDialFunc =
lstrlen(lpRasEntry->szAutodialFunc)
? StrDup(lpRasEntry->szAutodialFunc)
: NULL;
//
// Get primary phone number. Clear out any existing
// numbers.
//
DtlDestroyList(pLink->pdtllistPhones, DestroyPhoneNode);
pLink->pdtllistPhones = DtlCreateList(0);
if(NULL == pLink->pdtllistPhones)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
if (*lpRasEntry->szLocalPhoneNumber != '\0')
{
if(CreateAndInitializePhone(
pszAreaCode,
lpRasEntry->dwCountryCode,
lpRasEntry->dwCountryID,
lpRasEntry->szLocalPhoneNumber,
!!(lpRasEntry->dwfOptions
& RASEO_UseCountryAndAreaCodes),
lpRasEntry->szDeviceName,
&pdtlnode))
{
return ERROR_NOT_ENOUGH_MEMORY;
}
DtlAddNodeFirst(pLink->pdtllistPhones, pdtlnode);
}
//
// Get the alternate phone numbers.
//
if (lpRasEntry->dwAlternateOffset)
{
PTCHAR UNALIGNED pszPhoneNumber =
(PTCHAR)((ULONG_PTR)lpRasEntry
+ lpRasEntry->dwAlternateOffset);
while (*pszPhoneNumber != TEXT('\0'))
{
if(CreateAndInitializePhone(
pszAreaCode,
lpRasEntry->dwCountryCode,
lpRasEntry->dwCountryID,
pszPhoneNumber,
!!(lpRasEntry->dwfOptions
& RASEO_UseCountryAndAreaCodes),
lpRasEntry->szDeviceName,
&pdtlnode))
{
return ERROR_NOT_ENOUGH_MEMORY;
}
DtlAddNodeLast(pLink->pdtllistPhones, pdtlnode);
pszPhoneNumber += lstrlen(pszPhoneNumber) + 1;
}
}
//
// Get device information.
//
dwErr = LoadPortsList(&pdtllistPorts);
if (dwErr)
{
return ERROR_INVALID_PARAMETER;
}
//
// Get the encoded device name/port
// and check for a match.
//
GetDevicePortName(
lpRasEntry->szDeviceName,
szDeviceName, szPortName);
pPort = PpbportFromPortAndDeviceName(
pdtllistPorts,
szPortName,
((szDeviceName[ 0 ]) ? szDeviceName : NULL) );
if (pPort != NULL)
{
if (CopyToPbport(&pLink->pbport, pPort))
{
pPort = NULL;
}
}
//
// Search for a device name match.
//
if (pPort == NULL)
{
for (pdtlnode = DtlGetFirstNode(pdtllistPorts);
pdtlnode != NULL;
pdtlnode = DtlGetNextNode(pdtlnode))
{
PBPORT *pPortTmp = (PBPORT *)DtlGetData(pdtlnode);
if ( (pPortTmp->pszDevice != NULL)
&& (!lstrcmpi(pPortTmp->pszDevice, szDeviceName))
&& (!CopyToPbport(&pLink->pbport, pPortTmp)))
{
pPort = pPortTmp;
break;
}
}
}
//
// If we don't have a match, then
// pick the first device of the
// same type.
//
if (pPort == NULL)
{
pbdevicetype = PbdevicetypeFromPszType(
lpRasEntry->szDeviceType
);
//
// Initialize dwErr in case
// we fall through the loop
// without finding a match.
//
// dwErr = ERROR_INVALID_PARAMETER;
//
// Look for a port with the same
// device type.
//
for (pdtlnode = DtlGetFirstNode(pdtllistPorts);
pdtlnode != NULL;
pdtlnode = DtlGetNextNode(pdtlnode))
{
pPort = (PBPORT *)DtlGetData(pdtlnode);
if (pPort->pbdevicetype == pbdevicetype)
{
dwErr = CopyToPbport(&pLink->pbport, pPort);
break;
}
}
if( (NULL == pdtlnode)
&& (fNewEntry))
{
//
// Hack to make CM connections work.
// Remove this code after beta
// and just return an error in this case. The api
// should not be setting bogus information.
//
SetBogusPortInformation(pLink, pEntry->dwType);
}
//
// If the device is a modem,
// then set the default modem settings.
//
if (pbdevicetype == PBDT_Modem)
{
SetDefaultModemSettings(pLink);
}
}
// pmay: 401682
//
// Update the preferred device. Whenever this api is called,
// we can assume that the user wants the given device to
// be sticky.
//
if (pPort)
{
Free0(pEntry->pszPreferredDevice);
pEntry->pszPreferredDevice = StrDup(pPort->pszDevice);
Free0(pEntry->pszPreferredPort);
pEntry->pszPreferredPort = StrDup(pPort->pszPort);;
}
//
// Copy the remembered values
//
pLink->pbport.fScriptBefore = fScriptBefore;
pLink->pbport.fScriptBeforeTerminal = fScriptBeforeTerminal;
pLink->pbport.pszScriptBefore = pszScriptBefore;
DtlDestroyList(pdtllistPorts, DestroyPortNode);
if (dwErr)
{
return dwErr;
}
//
// Copy the TAPI configuration blob.
//
if (lpbDeviceConfig != NULL && dwcbDeviceConfig)
{
Free0(pLink->pTapiBlob);
pLink->pTapiBlob = (unsigned char *) Malloc(dwcbDeviceConfig);
if (pLink->pTapiBlob == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
memcpy(pLink->pTapiBlob,
lpbDeviceConfig,
dwcbDeviceConfig);
pLink->cbTapiBlob = dwcbDeviceConfig;
}
//
// Copy the following fields over only for
// a V401 structure or above.
//
// Winstate only supporting NT5 and above.
//
if ( lpRasEntry->dwSize == sizeof (RASENTRY) )
{
//
// Get multilink and idle timeout information.
//
pEntry->dwDialMode = lpRasEntry->dwDialMode
== RASEDM_DialAsNeeded
? RASEDM_DialAsNeeded
: RASEDM_DialAll;
pEntry->dwDialPercent =
lpRasEntry->dwDialExtraPercent;
pEntry->dwDialSeconds =
lpRasEntry->dwDialExtraSampleSeconds;
pEntry->dwHangUpPercent =
lpRasEntry->dwHangUpExtraPercent;
pEntry->dwHangUpSeconds =
lpRasEntry->dwHangUpExtraSampleSeconds;
//
// Get idle disconnect information.
//
pEntry->lIdleDisconnectSeconds =
lpRasEntry->dwIdleDisconnectSeconds;
//
// if the user is setting the dwIdleDisconnect
// Seconds through apis then override the user
// preferences.
//
if (pEntry->lIdleDisconnectSeconds)
{
pEntry->dwfOverridePref |= RASOR_IdleDisconnectSeconds;
}
//
// CustomScript
//
pEntry->dwCustomScript = !!( RASEO_CustomScript
& lpRasEntry->dwfOptions);
}
if(RASET_Phone != lpRasEntry->dwType)
{
pEntry->fPreviewPhoneNumber = FALSE;
pEntry->fSharedPhoneNumbers = FALSE;
}
//
// Copy the following information only if its nt5
//
if(lpRasEntry->dwSize == sizeof(RASENTRY))
{
//
// Connection type
//
pEntry->dwType = lpRasEntry->dwType;
//
// Clear the Encryption type. We set it below
// for nt5 - default to Mppe40Bit.
//
pEntry->dwDataEncryption = 0;
/*
if( (ET_40Bit & lpRasEntry->dwEncryptionType)
|| ( (0 == lpRasEntry->dwEncryptionType)
&& ( RASEO_RequireDataEncryption
& lpRasEntry->dwfOptions)))
{
pEntry->dwDataEncryption |= DE_Mppe40bit;
}
if(ET_128Bit & lpRasEntry->dwEncryptionType)
{
pEntry->dwDataEncryption |= DE_Mppe128bit;
}
*/
if( (ET_Require == lpRasEntry->dwEncryptionType)
|| ( (0 == lpRasEntry->dwEncryptionType)
&& ( RASEO_RequireDataEncryption
& lpRasEntry->dwfOptions)))
{
pEntry->dwDataEncryption = DE_Require;
}
else if (ET_RequireMax == lpRasEntry->dwEncryptionType)
{
pEntry->dwDataEncryption = DE_RequireMax;
}
else if (ET_Optional == lpRasEntry->dwEncryptionType)
{
pEntry->dwDataEncryption = DE_IfPossible;
}
//
// Clear the authrestrictions for nt5 if the user didn't
// specify any authentication protocol.
//
if( (!(lpRasEntry->dwfOptions & RASEO_RequireMsEncryptedPw))
&& (!(lpRasEntry->dwfOptions & RASEO_RequireEncryptedPw)))
{
pEntry->dwAuthRestrictions = 0;
}
//
// Set the new authentication bits based on options defined
// in NT5.
//
if(RASEO_RequireCHAP & lpRasEntry->dwfOptions)
{
pEntry->dwAuthRestrictions |= AR_F_AuthMD5CHAP;
}
if(RASEO_RequireMsCHAP & lpRasEntry->dwfOptions)
{
pEntry->dwAuthRestrictions |= AR_F_AuthMSCHAP;
}
if(RASEO_RequireMsCHAP2 & lpRasEntry->dwfOptions)
{
pEntry->dwAuthRestrictions |= AR_F_AuthMSCHAP2;
}
if(RASEO_RequireW95MSCHAP & lpRasEntry->dwfOptions)
{
pEntry->dwAuthRestrictions |= (AR_F_AuthW95MSCHAP | AR_F_AuthCustom);
}
if(RASEO_RequirePAP & lpRasEntry->dwfOptions)
{
pEntry->dwAuthRestrictions |= AR_F_AuthPAP;
}
if(RASEO_RequireSPAP & lpRasEntry->dwfOptions)
{
pEntry->dwAuthRestrictions |= AR_F_AuthSPAP;
}
if(RASEO_RequireEAP & lpRasEntry->dwfOptions)
{
pEntry->dwAuthRestrictions |= AR_F_AuthEAP;
if( (0 != lpRasEntry->dwCustomAuthKey)
&& (-1 != lpRasEntry->dwCustomAuthKey))
{
pEntry->dwCustomAuthKey =
lpRasEntry->dwCustomAuthKey;
}
}
if(RASEO_Custom & lpRasEntry->dwfOptions)
{
pEntry->dwAuthRestrictions |= AR_F_AuthCustom;
}
if(0 == pEntry->dwAuthRestrictions)
{
pEntry->dwAuthRestrictions = AR_F_TypicalUnsecure;
}
//
// Get custom dial UI information.
//
pEntry->pszCustomDialerName =
lstrlen(lpRasEntry->szCustomDialDll)
? StrDup(lpRasEntry->szCustomDialDll)
: NULL;
//
// Set fSharedPhoneNumbers/fPreviewPhoneNumbers
//
pEntry->fSharedPhoneNumbers = !!( RASEO_SharedPhoneNumbers
& lpRasEntry->dwfOptions);
pEntry->fPreviewPhoneNumber = !!( RASEO_PreviewPhoneNumber
& lpRasEntry->dwfOptions);
pEntry->fPreviewUserPw = !!( RASEO_PreviewUserPw
& lpRasEntry->dwfOptions);
pEntry->fPreviewDomain = !!( RASEO_PreviewDomain
& lpRasEntry->dwfOptions);
pEntry->fShowDialingProgress = !!( RASEO_ShowDialingProgress
& lpRasEntry->dwfOptions);
//
// Vpn strategy
//
pEntry->dwVpnStrategy = lpRasEntry->dwVpnStrategy;
}
//
// The following are "adjustments" made for State Migration.
// chrisab 2-Apr-00
//
// Bug 90555 and 90561
//
if( (lpRasEntry->dwfOptions & RASEO_RequireEncryptedPw) ||
(lpRasEntry->dwfOptions & RASEO_RequireMsEncryptedPw) )
{
pEntry->dwTypicalAuth = TA_Secure;
}
else
{
pEntry->dwTypicalAuth = TA_Unsecure;
}
//
// Bug #90554
// Set log on to network option
//
if( lpRasEntry->dwfOptions & RASEO_NetworkLogon )
{
pEntry->fPreviewDomain = TRUE;
}
//
// Set dirty bit so this entry will get written out.
//
pEntry->fDirty = TRUE;
return 0;
}
//
// WinState_RasSetEntryProperties()
//
// This function replaces the Win32 RAS API RasSetEntryProperties().
// If the define PRIvATE_RAS
//
DWORD WinState_RasSetEntryPropertiesW(
IN LPCWSTR lpszPhonebook,
IN LPCWSTR lpszEntry,
IN LPRASENTRYW lpRasEntry,
IN DWORD dwcbRasEntry,
IN LPBYTE lpbDeviceConfig,
IN DWORD dwcbDeviceConfig
)
{
#ifndef PRIVATE_RAS
return RasSetEntryProperties(lpszPhonebook,
lpszEntry,
lpRasEntry,
dwcbRasEntry,
lpbDeviceConfig,
dwcbDeviceConfig);
#else
DWORD dwErr;
PBFILE pbfile;
DTLNODE *pdtlnode;
PBENTRY *pEntry;
BOOL fCreated;
// Initialize RASMAN.DLL for stuff needed by phonebook APIs.
dwErr = LoadRasmanDllAndInit();
if( dwErr )
{
return dwErr;
}
if( DwRasInitializeError )
{
return DwRasInitializeError;
}
// Parameter validation.
if( lpRasEntry == NULL )
{
return ERROR_INVALID_PARAMETER;
}
// WinState only supporting NT5 and above.
if ( (lpRasEntry->dwSize != sizeof (RASENTRYW))
&& (lpRasEntry->dwSize != SIZEOF_STRUCT (RASENTRYW, dwType))
&& (lpRasEntry->dwSize != SIZEOF_STRUCT (RASENTRYW, dwSubEntries)))
{
return ERROR_INVALID_SIZE;
}
if (dwcbRasEntry < lpRasEntry->dwSize)
{
return ERROR_BUFFER_TOO_SMALL;
}
//
// Load the phonebook file.
//
EnterCriticalSection(&PhonebookLock);
// Check and see if the entry name already exists in the phone book
dwErr = GetPbkAndEntryName(lpszPhonebook,
lpszEntry,
0,
&pbfile,
&pdtlnode);
// if failed for some other reason than the entry doesn't exist, bail.
if( (dwErr != SUCCESS) && (dwErr != ERROR_CANNOT_FIND_PHONEBOOK_ENTRY) )
{
return dwErr;
}
// If the entry already exists...
if( pdtlnode != NULL )
{
DTLNODE *pdtlnodeNew = DuplicateEntryNode(pdtlnode);
DtlRemoveNode(pbfile.pdtllistEntries, pdtlnode);
DestroyEntryNode(pdtlnode);
pdtlnode = pdtlnodeNew;
}
// New Entry
else
{
dwErr = ReadPhonebookFile(lpszPhonebook,
NULL,
NULL,
0,
&pbfile);
if( dwErr )
{
return ERROR_CANNOT_OPEN_PHONEBOOK;
}
pdtlnode = CreateEntryNode(TRUE);
fCreated = TRUE;
}
if( pdtlnode == NULL )
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
//
// Add the node to the list of entries
//
DtlAddNodeLast(pbfile.pdtllistEntries, pdtlnode);
pEntry = (PBENTRY *) DtlGetData(pdtlnode);
//
// Convert the RASENTRY to a PBENTRY
// (Call our private version of this)
//
dwErr = WinState_RasEntryToPhonebookEntry(
lpszEntry,
lpRasEntry,
dwcbRasEntry,
lpbDeviceConfig,
dwcbDeviceConfig,
pEntry);
if( dwErr )
{
goto cleanup;
}
//
// Write out the phonebook file
//
dwErr = WritePhonebookFile(&pbfile, NULL);
if( dwErr == ERROR_SUCCESS )
{
dwErr = DwSendRasNotification(
(fCreated) ?
ENTRY_ADDED :
ENTRY_MODIFIED,
pEntry,
pbfile.pszPath);
dwErr = ERROR_SUCCESS;
}
cleanup:
ClosePhonebookFile(&pbfile);
LeaveCriticalSection(&PhonebookLock);
return dwErr;
#endif
}
//
// DllMain()
//
BOOL
DllMain(
HANDLE hinstDll,
DWORD fdwReason,
LPVOID lpReserved )
{
if( InitializeLoadRAS(fdwReason) == ERROR_SUCCESS )
return TRUE;
return FALSE;
}