windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/w95upg/sysmig/ras.c

1258 lines
38 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997-2001 Microsoft Corporation
Module Name:
ras.c
Abstract:
ras.c runs as a part of w95upg.dll in winnt32.exe during Win9x migrations.
Saves connectoid information for later retrieval during Guimode setup.
Author:
Marc R. Whitten (marcw) 23-Nov-1997
Revision History:
Marc R. Whitten marcw 23-Jul-1998 - Major cleanup.
Jeff Sigman 09-Apr-2001 - Whistler cleanup.
Whistler bugs:
34270 Win9x: Upgrade: Require Data Encryption setting for VPN
connections is not migrated
125693 UpgLab9x: DUN Connectoids don't migrate selected modem properly
from Win9x
208318 Win9x Upg: Username and Password for DUN connectoid not migrated
from Win9x to Whistler
--*/
#include "pch.h" // Pre-compiled
//
// Macros
//
#define PAESMMCFG(pAE) ((PSMMCFG)(((PBYTE)pAE)+(pAE->uOffSMMCfg)))
#define PAESMM(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffSMM)))
#define PAEDI(pAE) ((PDEVICEINFO)(((PBYTE)pAE)+(pAE->uOffDI )))
#define PAEAREA(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffArea)))
#define PAEPHONE(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffPhone)))
#define DECRYPTENTRY(x, y, z) EnDecryptEntry(x, (LPBYTE)y, z)
typedef LPVOID HPWL;
typedef HPWL* LPHPWL;
typedef struct {
DWORD Size;
DWORD Unknown1;
DWORD ModemUiOptions; // num seconds in high byte.
DWORD Unknown3; // 0 = Not Set.
DWORD Unknown4;
DWORD Unknown5;
DWORD ConnectionSpeed;
DWORD UnknownFlowControlData; //Somehow related to flow control.
DWORD Unknown8;
DWORD Unknown9;
DWORD Unknown10;
DWORD Unknown11;
DWORD Unknown12;
DWORD Unknown13;
DWORD Unknown14;
DWORD Unknown15;
DWORD Unknown16;
DWORD Unknown17;
DWORD Unknown18;
DWORD dwCallSetupFailTimer; // Num seconds to wait before cancel if not
// connected. (0xFF equals off.)
DWORD dwInactivityTimeout; // 0 = Not Set.
DWORD Unknown21;
DWORD SpeakerVolume; // 0|1
DWORD ConfigOptions;
DWORD Unknown24;
DWORD Unknown25;
DWORD Unknown26;
} MODEMDEVINFO, *PMODEMDEVINFO;
DEFINE_GUID(GUID_DEVCLASS_MODEM,
0x4d36e96dL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
//
// Globals
//
POOLHANDLE g_RasPool;
BOOL g_RasInstalled = FALSE;
BOOL g_MultilinkEnabled;
HINSTANCE g_RasApi32 = NULL;
DWORD (* g_RnaGetDefaultAutodialConnection) (
LPBYTE lpBuf,
DWORD cb,
LPDWORD lpdwOptions
);
//
// Routines and structures for dealing with the Addresses\<entry> blob..
//
// AddrEntry serves as a header for the entire block of data in the <entry>
// blob. entries in it are offsets to the strings which follow it..in many
// cases (i.e. all of the *Off* members...)
//
typedef struct _AddrEntry {
DWORD dwVersion;
DWORD dwCountryCode;
UINT uOffArea;
UINT uOffPhone;
DWORD dwCountryID;
UINT uOffSMMCfg;
UINT uOffSMM;
UINT uOffDI;
} ADDRENTRY, *PADDRENTRY;
typedef struct _SubConnEntry {
DWORD dwSize;
DWORD dwFlags;
char szDeviceType[RAS_MaxDeviceType+1];
char szDeviceName[RAS_MaxDeviceName+1];
char szLocal[RAS_MaxPhoneNumber+1];
} SUBCONNENTRY, *PSUBCONNENTRY;
typedef struct _IPData {
DWORD dwSize;
DWORD fdwTCPIP;
DWORD dwIPAddr;
DWORD dwDNSAddr;
DWORD dwDNSAddrAlt;
DWORD dwWINSAddr;
DWORD dwWINSAddrAlt;
} IPDATA, *PIPDATA;
typedef struct _DEVICEINFO {
DWORD dwVersion;
UINT uSize;
char szDeviceName[RAS_MaxDeviceName+1];
char szDeviceType[RAS_MaxDeviceType+1];
} DEVICEINFO, *PDEVICEINFO;
typedef struct _SMMCFG {
DWORD dwSize;
DWORD fdwOptions;
DWORD fdwProtocols;
} SMMCFG, *PSMMCFG;
static BYTE NEAR PASCAL GenerateEncryptKey (LPSTR szKey)
{
BYTE bKey;
LPBYTE lpKey;
for (bKey = 0, lpKey = (LPBYTE)szKey; *lpKey != 0; lpKey++)
{
bKey += *lpKey;
};
return bKey;
}
DWORD NEAR PASCAL
EnDecryptEntry (
LPSTR szEntry,
LPBYTE lpEnt,
DWORD cb
)
{
BYTE bKey;
//
// Generate the encryption key from the entry name
//
bKey = GenerateEncryptKey(szEntry);
//
// Encrypt the address entry one byte at a time
//
for (;cb > 0; cb--, lpEnt++)
{
*lpEnt ^= bKey;
};
return ERROR_SUCCESS;
}
//
// Find out if current connection is the default connection for current user
//
// Whistler 417479 RAS upgrade code does not migrate the default
// internet connection setting from WinME to XP
//
BOOL
IsDefInternetCon(
IN PCTSTR szEntry
)
{
BOOL bRet = FALSE;
if (g_RnaGetDefaultAutodialConnection && szEntry)
{
DWORD dwAutodialOptions;
UCHAR szDefEntry[MAX_PATH + 1];
//
// Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,Domain,
// Passwrds to not be migrated for DUN
//
if (!g_RnaGetDefaultAutodialConnection(szDefEntry, MAX_PATH,
&dwAutodialOptions) && StringIMatch (szEntry, szDefEntry))
{
bRet = TRUE;
}
}
return bRet;
}
HKEY
FindCurrentKey (
IN HKEY hkKey,
IN PCTSTR pszString,
IN PCTSTR pszPath
)
{
HKEY hkResult = NULL;
HKEY hkTemp = hkKey;
TCHAR szPath[MAX_PATH + 1];
PTSTR pszTemp = NULL;
REGKEY_ENUM e;
do
{
pszTemp = GetRegValueString (hkTemp, S_FRIENDLYNAME);
if (pszTemp && StringIMatch (pszString, pszTemp))
{
hkResult = hkTemp;
hkTemp = NULL;
break;
}
if (!EnumFirstRegKey (&e, hkTemp)) {break;}
do
{
if (pszTemp)
{
MemFree (g_hHeap, 0, pszTemp);
pszTemp = NULL;
}
if (hkResult)
{
CloseRegKey(hkResult);
hkResult = NULL;
}
sprintf(szPath, "%s\\%s", pszPath, e.SubKeyName );
hkResult = OpenRegKeyStr (szPath);
if (!hkResult) {break;}
pszTemp = GetRegValueString (hkResult, S_FRIENDLYNAME);
if (pszTemp && StringIMatch (pszString, pszTemp))
{
// Success
break;
}
else
{
CloseRegKey(hkResult);
hkResult = NULL;
}
} while (EnumNextRegKey (&e));
} while (FALSE);
//
// Clean up
//
if (pszTemp)
{
MemFree (g_hHeap, 0, pszTemp);
}
if (hkTemp)
{
CloseRegKey(hkTemp);
}
return hkResult;
}
PTSTR
GetInfoFromFriendlyName (
IN PCTSTR pszFriendlyName,
IN BOOL bType
)
{
HKEY hkEnum = NULL;
DWORD i = 0;
TCHAR szData[MAX_PATH + 1];
TCHAR szPath[MAX_PATH + 1];
PTSTR pszTemp = NULL;
PTSTR pszReturn = NULL;
LPGUID pguidModem = (LPGUID)&GUID_DEVCLASS_MODEM;
HDEVINFO hdi;
SP_DEVINFO_DATA devInfoData = {sizeof (devInfoData), 0};
hdi = SetupDiGetClassDevs (pguidModem, NULL, NULL, DIGCF_PRESENT);
if (INVALID_HANDLE_VALUE == hdi)
{
return NULL;
}
while (SetupDiEnumDeviceInfo (hdi, i++, &devInfoData))
{
if (!SetupDiGetDeviceRegistryProperty (
hdi, &devInfoData, SPDRP_FRIENDLYNAME,
NULL, (PBYTE)szData, MAX_PATH, NULL) ||
lstrcmp (szData, pszFriendlyName) )
{
continue;
}
if (!SetupDiGetDeviceRegistryProperty (
hdi, &devInfoData, SPDRP_HARDWAREID,
NULL, (PBYTE)szData, MAX_PATH, NULL) )
{
break;
}
sprintf(szPath, "%s\\%s", S_ENUM, szData );
hkEnum = OpenRegKeyStr (szPath);
if (!hkEnum) {break;}
hkEnum = FindCurrentKey (hkEnum, pszFriendlyName, szPath);
if (!hkEnum) {break;}
if (bType)
{
pszTemp = GetRegValueString (hkEnum, S_PARENTDEVNODE);
if (pszTemp)
{
pszReturn = PoolMemDuplicateString (g_RasPool, pszTemp);
break;
}
pszReturn = PoolMemDuplicateString (g_RasPool, szData);
break;
}
else
{
pszTemp = GetRegValueString (hkEnum, S_ATTACHEDTO);
if (pszTemp)
{
pszReturn = PoolMemDuplicateString (g_RasPool, pszTemp);
break;
}
pszTemp = GetRegValueString (hkEnum, S_DRIVER);
if (pszTemp)
{
HKEY key = NULL;
PTSTR pszAttach = NULL;
sprintf(szPath, "%s\\%s", S_SERVICECLASS, pszTemp);
key = OpenRegKeyStr (szPath);
if (!key) {break;}
pszAttach = GetRegValueString (key, S_ATTACHEDTO);
if (!pszAttach)
{
CloseRegKey(key);
break;
}
pszReturn = PoolMemDuplicateString (g_RasPool, pszAttach);
MemFree (g_hHeap, 0, pszAttach);
CloseRegKey(key);
}
break;
}
}
//
// Clean up
//
if (bType && pszReturn)
{
BOOL bFisrt = FALSE;
PTSTR p;
for (p = pszReturn; '\0' != *p; p++ )
{
if (*p != '\\') {continue;}
if (!bFisrt)
{
bFisrt = TRUE;
}
else
{
//
// Remove rest of PnpId string, not needed
//
*p = '\0';
break;
}
}
}
if (pszTemp)
{
MemFree (g_hHeap, 0, pszTemp);
}
if (hkEnum)
{
CloseRegKey(hkEnum);
}
if (INVALID_HANDLE_VALUE != hdi)
{
SetupDiDestroyDeviceInfoList (hdi);
}
return pszReturn;
}
PTSTR
GetComPort (
IN PCTSTR DriverDesc
)
{
PTSTR rPort = NULL;
rPort = GetInfoFromFriendlyName(DriverDesc, FALSE);
if (!rPort)
{
rPort = S_EMPTY;
DEBUGMSG ((DBG_WARNING, "Could not find com port for device %s."));
}
return rPort;
}
VOID
pInitLibs (
VOID
)
{
do {
//
// Load in rasapi32.dll, not fatal if we fail
//
// Whistler 417479 RAS upgrade code does not migrate the default
// internet connection setting from WinME to XP
//
g_RasApi32 = LoadLibrary(S_RASAPI32LIB);
if (!g_RasApi32) {
g_RnaGetDefaultAutodialConnection = NULL;
DEBUGMSG((S_DBG_RAS,"Migrate Ras: could not load library %s. Default Internet Connection will not be migrated.",
S_RASAPI32LIB));
}
//
// RASAPI32 was loaded..now, get the relevant apis, not fatal if we fail
//
else
{
(FARPROC) g_RnaGetDefaultAutodialConnection = GetProcAddress(
g_RasApi32,
S_RNAGETDEFAUTODIALCON
);
if (!g_RnaGetDefaultAutodialConnection) {
DEBUGMSG((S_DBG_RAS,"Migrate Ras: could not load Procedure %s. Default Internet Connection will not be migrated.",
S_RNAGETDEFAUTODIALCON));
}
}
} while ( FALSE );
return;
}
VOID
pCleanUpLibs (
VOID
)
{
//
// Whistler 417479 RAS upgrade code does not migrate the default
// internet connection setting from WinME to XP
//
if (g_RasApi32) {
FreeLibrary(g_RasApi32);
}
}
VOID
pSaveConnectionDataToMemDb (
IN PCTSTR User,
IN PCTSTR Entry,
IN PCTSTR ValueName,
IN DWORD ValueType,
IN PBYTE Value
)
{
DWORD offset;
TCHAR key[MEMDB_MAX];
MemDbBuildKey (key, MEMDB_CATEGORY_RAS_INFO, User, Entry, ValueName);
switch (ValueType) {
case REG_SZ:
case REG_MULTI_SZ:
case REG_EXPAND_SZ:
DEBUGMSG ((S_DBG_RAS, "String Data - %s = %s", ValueName,
(PCTSTR) Value));
if (!MemDbSetValueEx (MEMDB_CATEGORY_RAS_DATA, (PCTSTR) Value,
NULL, NULL, 0, &offset)) {
DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
}
if (!MemDbSetValueAndFlags (key, offset, (WORD) REG_SZ, 0)) {
DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
}
break;
case REG_DWORD:
DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", ValueName,
(DWORD) Value));
if (!MemDbSetValueAndFlags (key, (DWORD)Value, (WORD)ValueType,0)){
DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
}
break;
case REG_BINARY:
DEBUGMSG ((S_DBG_RAS, "Binary data for %s.", ValueName));
if (StringIMatch (S_IPINFO, ValueName)) {
//
// Save IP address information.
//
pSaveConnectionDataToMemDb (User, Entry, S_IP_FTCPIP,
REG_DWORD, (PBYTE) ((PIPDATA) Value)->fdwTCPIP);
pSaveConnectionDataToMemDb (User, Entry, S_IP_IPADDR,
REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwIPAddr);
pSaveConnectionDataToMemDb (User, Entry, S_IP_DNSADDR,
REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwDNSAddr);
pSaveConnectionDataToMemDb (User, Entry, S_IP_DNSADDR2,
REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwDNSAddrAlt);
pSaveConnectionDataToMemDb (User, Entry, S_IP_WINSADDR,
REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwWINSAddr);
pSaveConnectionDataToMemDb (User, Entry, S_IP_WINSADDR2,
REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwWINSAddrAlt);
} else if (StringIMatch (S_TERMINAL, ValueName)) {
//
// save information on the showcmd state. This will tell us how
// to set the ui display.
//
pSaveConnectionDataToMemDb (User, Entry, ValueName, REG_DWORD,
(PBYTE) ((PWINDOWPLACEMENT) Value)->showCmd);
} else if (StringIMatch (S_MODE, ValueName)) {
//
// This value tells what to do with scripting.
//
pSaveConnectionDataToMemDb (User, Entry, ValueName, REG_DWORD,
(PBYTE) *((PDWORD) Value));
} else if (StringIMatch (S_MULTILINK, ValueName)) {
//
// Save wether or not multilink is enabled.
//
pSaveConnectionDataToMemDb (User, Entry, ValueName, REG_DWORD,
(PBYTE) *((PDWORD) Value));
//
// Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,
// Domain, Passwrds to not be migrated for DUN
//
} else if (StringIMatch (S_PBE_REDIALATTEMPTS, ValueName)) {
//
// Save the number of redial attempts
//
pSaveConnectionDataToMemDb (User, Entry, S_REDIAL_TRY, REG_DWORD,
(PBYTE) *((PDWORD) Value));
//
// Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,
// Domain, Passwrds to not be migrated for DUN
//
} else if (StringIMatch (S_REDIAL_WAIT, ValueName)) {
//
// Save the number of seconds to wait for redial
//
pSaveConnectionDataToMemDb (User, Entry, ValueName, REG_DWORD,
(PBYTE) *((PDWORD) Value));
} ELSE_DEBUGMSG ((DBG_WARNING, "Don't know how to handle binary data %s. It will be ignored.",
ValueName));
break;
default:
DEBUGMSG ((DBG_WHOOPS, "Unknown type of registry data found in RAS settings. %s",
ValueName));
break;
}
}
BOOL
pGetRasEntrySettings (
IN PUSERENUM EnumPtr,
IN HKEY Key,
IN PCTSTR EntryName
)
{
REGVALUE_ENUM e;
PBYTE curData = NULL;
BOOL rSuccess = TRUE;
DEBUGMSG ((S_DBG_RAS, "---Processing %s's entry settings: %s---",
EnumPtr->FixedUserName, EntryName));
if (EnumFirstRegValue (&e, Key)) {
do {
//
// Get the data for this entry.
//
curData = GetRegValueData (Key, e.ValueName);
if (curData) {
//
// Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,
// Domain, Passwrds to not be migrated for DUN
//
if (StringIMatch (S_MULTILINK, e.ValueName) &&
!g_MultilinkEnabled) {
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
EntryName, e.ValueName, REG_DWORD, 0);
}
else {
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, e.ValueName, e.Type,
e.Type == REG_DWORD ? (PBYTE) (*((PDWORD)curData)) :
curData);
}
MemFree (g_hHeap, 0, curData);
}
} while (EnumNextRegValue (&e));
}
return rSuccess;
}
BOOL
pGetRasEntryAddressInfo (
IN PUSERENUM EnumPtr,
IN HKEY Key,
IN PCTSTR EntryName
)
{
BOOL rSuccess = TRUE;
HKEY subEntriesKey = NULL;
UINT count = 0, type = 0, sequencer = 0;
PBYTE data = NULL;
PTSTR subEntriesKeyStr = NULL;
TCHAR buffer[MAX_TCHAR_PATH];
PCTSTR group;
PSMMCFG smmCfg = NULL;
PADDRENTRY entry = NULL;
PDEVICEINFO devInfo = NULL;
REGVALUE_ENUM e, eSubEntries;
PSUBCONNENTRY subEntry = NULL;
PMODEMDEVINFO modemInfo;
//
// First we have to get the real entry name. It must match exactly even
// case. Unfortunately, it isn't neccessarily a given that the case between
// HKR\RemoteAccess\Profiles\<Foo> and HKR\RemoteAccess\Addresses\[Foo] is
// the same. The registry apis will of course work fine because they work
// case insensitively. However, I will be unable to decrypt the value if I
// use the wrong name.
//
if (EnumFirstRegValue (&e, Key)) {
do {
if (StringIMatch (e.ValueName, EntryName)) {
//
// Found the correct entry. Use it.
//
data = GetRegValueBinary (Key, e.ValueName);
if (data) {
DEBUGMSG ((S_DBG_RAS, "-----Processing entry: %s-----",
e.ValueName));
//
// Whistler 417479 RAS upgrade code does not migrate the default
// internet connection setting from WinME to XP
//
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_DEFINTERNETCON,
REG_DWORD, (PBYTE) IsDefInternetCon(EntryName));
entry = (PADDRENTRY) data;
DECRYPTENTRY(e.ValueName, entry, e.DataSize);
smmCfg = PAESMMCFG(entry);
devInfo = PAEDI(entry);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_PHONE_NUMBER,
REG_SZ, (PBYTE) PAEPHONE(entry));
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_AREA_CODE, REG_SZ,
(PBYTE) PAEAREA(entry));
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_SMM, REG_SZ,
(PBYTE) PAESMM(entry));
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_COUNTRY_CODE,
REG_DWORD, (PBYTE) entry->dwCountryCode);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_COUNTRY_ID,
REG_DWORD, (PBYTE) entry->dwCountryID);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_DEVICE_NAME,
REG_SZ, (PBYTE) devInfo->szDeviceName);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_DEVICE_TYPE,
REG_SZ, (PBYTE) devInfo->szDeviceType);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_PROTOCOLS,
REG_DWORD, (PBYTE) smmCfg->fdwProtocols);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, S_SMM_OPTIONS,
REG_DWORD, (PBYTE) smmCfg->fdwOptions);
//
// Save device information away.
//
if (StringIMatch (devInfo->szDeviceType, S_MODEM)) {
PTSTR pszPnpId = NULL;
pszPnpId = GetInfoFromFriendlyName(
devInfo->szDeviceName, TRUE);
if (pszPnpId)
{
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName,
S_DEVICE_ID, REG_SZ, (PBYTE) pszPnpId);
}
modemInfo = (PMODEMDEVINFO) (devInfo->szDeviceType +
RAS_MaxDeviceType + 3);
if (modemInfo->Size >= sizeof (MODEMDEVINFO)) {
DEBUGMSG_IF ((modemInfo->Size >
sizeof (MODEMDEVINFO), S_DBG_RAS,
"Structure size larger than our known size."));
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
EntryName, S_MODEM_UI_OPTIONS, REG_DWORD,
(PBYTE) modemInfo->ModemUiOptions);
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
EntryName, S_MODEM_SPEED, REG_DWORD,
(PBYTE) modemInfo->ConnectionSpeed);
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
EntryName, S_MODEM_SPEAKER_VOLUME, REG_DWORD,
(PBYTE) modemInfo->SpeakerVolume);
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
EntryName, S_MODEM_IDLE_DISCONNECT_SECONDS,
REG_DWORD,
(PBYTE) modemInfo->dwInactivityTimeout);
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
EntryName, S_MODEM_CANCEL_SECONDS, REG_DWORD,
(PBYTE) modemInfo->dwCallSetupFailTimer);
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
EntryName, S_MODEM_CFG_OPTIONS, REG_DWORD,
(PBYTE) modemInfo->ConfigOptions);
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
EntryName, S_MODEM_COM_PORT, REG_SZ,
(PBYTE) GetComPort (devInfo->szDeviceName));
}
ELSE_DEBUGMSG ((DBG_WHOOPS, "No modem configuration data saved. Size smaller than known structure. Investigate."));
}
//
// If SMM is not SLIP, CSLIP or PPP, we need to add a
// message to the upgrade report.
//
if (!StringIMatch (PAESMM(entry), S_SLIP)&&
!StringIMatch (PAESMM(entry), S_PPP) &&
!StringIMatch (PAESMM(entry), S_CSLIP)) {
//
// Add message for this connection entry.
//
group = BuildMessageGroup (
MSG_LOSTSETTINGS_ROOT,
MSG_CONNECTION_BADPROTOCOL_SUBGROUP,
EntryName
);
if (group) {
MsgMgr_ObjectMsg_Add (
EntryName,
group,
S_EMPTY
);
FreeText (group);
}
}
}
//
// Check to see if there are any sub-entries for this
// connection (MULTILINK settings..)
//
// Luckily, we don't have to do the same enumeration of these
// entries as we had to above to get around the case
// sensitivity bug. the 9x code uses the address key name above
// for encryption/decryption.
//
sequencer = 1;
g_MultilinkEnabled = FALSE;
if (data && !StringIMatch (PAESMM(entry), S_PPP))
{
DEBUGMSG ((S_DBG_RAS, "Not using PPP, disabling Multi-Link"));
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
EntryName, S_DEVICECOUNT, REG_DWORD,
(PBYTE) sequencer);
MemFree (g_hHeap, 0, data);
data = NULL;
break;
}
subEntriesKeyStr = JoinPaths (S_SUBENTRIES, e.ValueName);
if (subEntriesKeyStr)
{
subEntriesKey = OpenRegKey (Key, subEntriesKeyStr);
FreePathString (subEntriesKeyStr);
}
if (subEntriesKey) {
DEBUGMSG ((S_DBG_RAS, "Multi-Link Subentries found for entry %s. Processing.",
e.ValueName));
g_MultilinkEnabled = TRUE;
if (EnumFirstRegValue (&eSubEntries, subEntriesKey)) {
do {
data = GetRegValueBinary (subEntriesKey,
eSubEntries.ValueName);
if (data) {
PTSTR pszPnpId = NULL;
subEntry = (PSUBCONNENTRY) data;
DECRYPTENTRY (e.ValueName, subEntry,
eSubEntries.DataSize);
wsprintf (buffer, "ml%d%s",sequencer,
S_DEVICE_TYPE);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, buffer,
REG_SZ, (PBYTE) subEntry->szDeviceType);
wsprintf (buffer, "ml%d%s",sequencer,
S_DEVICE_NAME);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, buffer,
REG_SZ, (PBYTE) subEntry->szDeviceName);
pszPnpId = GetInfoFromFriendlyName(
subEntry->szDeviceName, TRUE);
if (pszPnpId)
{
wsprintf (buffer, "ml%d%s",sequencer,
S_DEVICE_ID);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName,
buffer, REG_SZ, (PBYTE) pszPnpId);
}
wsprintf (buffer, "ml%d%s",sequencer,
S_PHONE_NUMBER);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, buffer,
REG_SZ, (PBYTE) subEntry->szLocal);
wsprintf (buffer, "ml%d%s",sequencer,
S_MODEM_COM_PORT);
pSaveConnectionDataToMemDb (
EnumPtr->FixedUserName, EntryName, buffer,
REG_SZ, (PBYTE)
GetComPort (subEntry->szDeviceName));
MemFree (g_hHeap, 0, data);
data = NULL;
}
sequencer++;
} while (EnumNextRegValue (&eSubEntries));
}
CloseRegKey (subEntriesKey);
}
//
// Save away the number of devices associated with this
// connection
//
pSaveConnectionDataToMemDb (EnumPtr->FixedUserName, EntryName,
S_DEVICECOUNT, REG_DWORD, (PBYTE) sequencer);
//
// We're done. Break out of the enumeration.
//
break;
}
} while (EnumNextRegValue (&e));
}
return rSuccess;
}
BOOL
pGetPerConnectionSettings (
IN PUSERENUM EnumPtr
)
{
HKEY profileKey;
HKEY entryKey = NULL;
HKEY addressKey = NULL;
BOOL rSuccess = TRUE;
REGVALUE_ENUM e;
DEBUGMSG((S_DBG_RAS, "Gathering per-connection RAS Setting Information"));
//
// Open needed registry keys.
//
profileKey = OpenRegKey (EnumPtr->UserRegKey, S_PROFILE_KEY);
addressKey = OpenRegKey (EnumPtr->UserRegKey, S_ADDRESSES_KEY);
if (addressKey) {
//
// Enumerate each entry for this user.
//
if (EnumFirstRegValue (&e, addressKey)) {
do {
//
// Get base connection info -- stored as binary blob under
// address key. All connections will have this info -- It
// contains such things as the phone number, area code, dialing
// rules, etc.. It does not matter wether the connection has
// been used or not.
//
rSuccess &= pGetRasEntryAddressInfo (EnumPtr,
addressKey, e.ValueName );
if (profileKey) {
//
// Under the profile key are negotiated options for the
// connection. This key will only exist if the entry has
// actually been connected to by the user.
//
entryKey = OpenRegKey (profileKey, e.ValueName);
if (entryKey) {
rSuccess &= pGetRasEntrySettings ( EnumPtr, entryKey,
e.ValueName );
CloseRegKey (entryKey);
}
}
} while (EnumNextRegValue (&e));
}
}
ELSE_DEBUGMSG ((DBG_WARNING, "pGetPerConnectionSettings: Unable to access needed registry info for user %s.",
EnumPtr->FixedUserName));
//
// Clean up resources.
//
if (addressKey) {
CloseRegKey (addressKey);
}
if (profileKey) {
CloseRegKey (profileKey);
}
return rSuccess;
}
BOOL
pGetPerUserSettings (
IN PUSERENUM EnumPtr
)
{
HKEY settingsKey;
PDWORD data;
BOOL rSuccess = TRUE;
DEBUGMSG ((S_DBG_RAS, "Gathering per-user RAS data for %s.",
EnumPtr->UserName));
settingsKey = OpenRegKey (EnumPtr->UserRegKey, S_REMOTE_ACCESS_KEY);
if (settingsKey) {
//
// Get UI settings.
//
data = (PDWORD) GetRegValueBinary (settingsKey, S_DIALUI);
//
// Save Dial User Interface info into memdb for this user.
//
if (data) {
DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_DIALUI, *data));
rSuccess &= MemDbSetValueEx (
MEMDB_CATEGORY_RAS_INFO,
MEMDB_FIELD_USER_SETTINGS,
EnumPtr->FixedUserName,
S_DIALUI,
*data,
NULL
);
MemFree (g_hHeap, 0, data);
}
ELSE_DEBUGMSG ((S_DBG_RAS, "No user UI settings found for %s.",
EnumPtr->UserName));
//
// Get Redial information.
//
data = (PDWORD) GetRegValueBinary (settingsKey, S_ENABLE_REDIAL);
if (data) {
DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_ENABLE_REDIAL,
*data));
rSuccess &= MemDbSetValueEx (
MEMDB_CATEGORY_RAS_INFO,
MEMDB_FIELD_USER_SETTINGS,
EnumPtr->FixedUserName,
S_ENABLE_REDIAL,
*data,
NULL
);
MemFree (g_hHeap, 0, data);
}
ELSE_DEBUGMSG ((S_DBG_RAS, "No user redial information found for %s.",
EnumPtr->UserName));
data = (PDWORD) GetRegValueBinary (settingsKey, S_REDIAL_TRY);
if (data) {
DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_REDIAL_TRY,
*data));
rSuccess &= MemDbSetValueEx (
MEMDB_CATEGORY_RAS_INFO,
MEMDB_FIELD_USER_SETTINGS,
EnumPtr->FixedUserName,
S_REDIAL_TRY,
*data,
NULL
);
MemFree (g_hHeap, 0, data);
}
ELSE_DEBUGMSG ((S_DBG_RAS, "No user redial information found for %s.",
EnumPtr->UserName));
data = (PDWORD) GetRegValueBinary (settingsKey, S_REDIAL_WAIT);
if (data) {
DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_REDIAL_WAIT,
HIWORD(*data) * 60 + LOWORD(*data)));
MemDbSetValueEx (
MEMDB_CATEGORY_RAS_INFO,
MEMDB_FIELD_USER_SETTINGS,
EnumPtr->FixedUserName,
S_REDIAL_WAIT,
HIWORD(*data) * 60 + LOWORD(*data),
NULL
);
MemFree (g_hHeap, 0, data);
}
ELSE_DEBUGMSG ((S_DBG_RAS, "No user redial information found for %s.",
EnumPtr->UserName));
//
// Get implicit connection information. (Controls wether connection ui
// should be displayed or not)
//
data = (PDWORD) GetRegValueBinary (settingsKey, S_ENABLE_IMPLICIT);
if (data) {
DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_ENABLE_IMPLICIT,
*data));
MemDbSetValueEx (
MEMDB_CATEGORY_RAS_INFO,
MEMDB_FIELD_USER_SETTINGS,
EnumPtr->FixedUserName,
S_ENABLE_IMPLICIT,
*data,
NULL
);
MemFree(g_hHeap,0,data);
}
ELSE_DEBUGMSG ((S_DBG_RAS, "No user implicit connection information found for %s.",
EnumPtr->UserName));
CloseRegKey(settingsKey);
}
return rSuccess;
}
DWORD
ProcessRasSettings (
IN DWORD Request,
IN PUSERENUM EnumPtr
)
{
DWORD rc = ERROR_SUCCESS;
switch (Request) {
case REQUEST_QUERYTICKS:
return TICKS_RAS_PREPARE_REPORT;
case REQUEST_BEGINUSERPROCESSING:
//
// We are about to be called for each user. Do necessary
// initialization.
//
// Initialize our pool and get information from libraries.
//
g_RasPool = PoolMemInitNamedPool (TEXT("RAS - Win9x Side"));
MYASSERT( g_RasPool);
pInitLibs();
g_RasInstalled = IsRasInstalled();
return ERROR_SUCCESS;
case REQUEST_RUN:
//
// Gather RAS information for this user.
//
if (g_RasInstalled && EnumPtr -> AccountType & NAMED_USER) {
__try {
pGetPerUserSettings (EnumPtr);
pGetPerConnectionSettings (EnumPtr);
}
__except (TRUE) {
DEBUGMSG ((DBG_WHOOPS, "Caught an exception while processing ras settings."));
}
}
return ERROR_SUCCESS;
case REQUEST_ENDUSERPROCESSING:
//
// Clean up our resources.
//
pCleanUpLibs();
PoolMemDestroyPool(g_RasPool);
return ERROR_SUCCESS;
default:
DEBUGMSG ((DBG_ERROR, "Bad parameter in Ras_PrepareReport"));
}
return 0;
}
BOOL
IsRasInstalled (
void
)
{
HKEY testKey = NULL;
BOOL rf = FALSE;
testKey = OpenRegKeyStr(S_SERVICEREMOTEACCESS);
if (testKey) {
//
// Open key succeeded. Assume RAS is installed.
//
rf = TRUE;
CloseRegKey(testKey);
}
return rf;
}
BOOL
WINAPI
Ras_Entry (
IN HINSTANCE hinstDLL,
IN DWORD dwReason,
IN LPVOID lpv
)
{
BOOL rSuccess = TRUE;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
//
// Clean up resources that we used.
//
break;
}
return rSuccess;
}