windows-nt/Source/XPSP1/NT/net/rras/upgrade/steelhead2nt5/sap.c
2020-09-26 16:20:57 +08:00

489 lines
12 KiB
C

/*
File: sap.c
Performs an upgrade of ipx sap to nt5 router
by munging registry values.
Paul Mayfield, 9/3/97
*/
#include "upgrade.h"
// Structure for data passed to the enumeration
// function.
typedef struct _SAP_ENUM_DATA {
PSAP_IF_CONFIG pDefaults;
} SAP_ENUM_DATA;
// Globals
static WCHAR szIpxSapKey[] =
L"System\\CurrentControlSet\\Services\\RemoteAccess\\RouterManagers\\IPX\\RoutingProtocols\\IPXSAP\\Parameters";
static WCHAR szTempKey[] = L"DeleteMe";
static HKEY hkRouter = NULL;
static HKEY hkTemp = NULL;
static HKEY hkIpxSap = NULL;
static PWCHAR IpxSapParams[] =
{
L"SendTime",
L"EntryTimeout",
L"WANFilter",
L"WANUpdateTime",
L"MaxRecvBufferLookAhead",
L"RespondForInternalServers",
L"DelayRespondToGeneral",
L"DelayChangeBroadcast",
L"NameTableReservedHeapSize",
L"NameTableSortLatency",
L"MaxUnsortedNames",
L"TriggeredUpdateCheckInterval",
L"MaxTriggeredUpdateRequests",
L"ShutdownBroadcastTimeout",
L"RequestsPerInterface",
L"MinimumRequests"
};
//
// Restore the registry from from backup and make sure
// all global handles are opened
//
DWORD SapPrepareRegistry(
IN PWCHAR BackupFileName)
{
DWORD dwErr, dwDisposition;
// Get access to the router registry key
dwErr = UtlAccessRouterKey(&hkRouter);
if (dwErr != ERROR_SUCCESS) {
PrintMessage(L"Unable to access router key.\n");
return dwErr;
}
// Restore the router key from backup
__try {
// Open up the temporary key
dwErr = RegCreateKeyEx(
hkRouter,
szTempKey,
0,
NULL,
0,
KEY_ALL_ACCESS,
NULL,
&hkTemp,
&dwDisposition);
if (dwErr != ERROR_SUCCESS)
return dwErr;
// Restore the saved registry information
// to the temp key
UtlSetupRestorePrivilege(TRUE);
dwErr = RegRestoreKeyW(
hkTemp,
BackupFileName,
0);
if (dwErr != ERROR_SUCCESS)
return dwErr;
// Open up the ipx sap params key
dwErr = RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
szIpxSapKey,
0,
NULL,
0,
KEY_ALL_ACCESS,
NULL,
&hkIpxSap,
&dwDisposition);
if (dwErr != ERROR_SUCCESS)
return dwErr;
}
__finally {
UtlSetupRestorePrivilege(FALSE);
}
return NO_ERROR;
}
//
// Cleanup the work done in the registry
//
DWORD SapCleanupRegistry() {
if (hkIpxSap)
RegCloseKey(hkIpxSap);
if (hkTemp)
RegCloseKey(hkTemp);
if (hkRouter) {
RegDeleteKey(hkRouter,szTempKey);
RegCloseKey(hkRouter);
}
hkIpxSap = NULL;
hkTemp = NULL;
hkRouter = NULL;
return NO_ERROR;
}
//
// Restores the sap parameters that were saved before upgrade.
// Assumes those parameters are being stored temporarily in hkTemp
//
DWORD SapRestoreParameters() {
DWORD dwErr, dwVal;
PWCHAR* IpxSapParamPtr = IpxSapParams;
dwt NwSapParams;
// Load in the parameters that were set for nwsap
__try {
dwErr = dwtLoadRegistyTable(&NwSapParams, hkTemp);
if (dwErr != NO_ERROR)
return dwErr;
// Loop through the ipx params copying over any that applied
// to nwsap
while (IpxSapParamPtr && *IpxSapParamPtr) {
dwErr = dwtGetValue(&NwSapParams, *IpxSapParamPtr, &dwVal);
if (dwErr == NO_ERROR) {
dwErr = RegSetValueEx(
hkIpxSap,
*IpxSapParamPtr,
0,
REG_DWORD,
(LPBYTE)&dwVal,
sizeof(DWORD));
if (dwErr != ERROR_SUCCESS)
return dwErr;
}
IpxSapParamPtr++;
}
}
__finally {
dwtCleanup(&NwSapParams);
}
return NO_ERROR;
}
//
// Installs sap in the router by initializing the
// sap global info blob.
//
DWORD SapInstallTransportInfo(
IN SAP_GLOBAL_INFO * pGlobal,
IN SAP_IF_CONFIG * pIfDefaults)
{
LPBYTE pGlobalInfo = NULL, pDialinInfo = NULL;
LPBYTE pNewGlobalInfo = NULL, pNewDialinInfo = NULL;
HANDLE hConfig = NULL, hTrans = NULL;
SAP_IF_CONFIG SapCfg, *pDialinCfg = &SapCfg;
DWORD dwErr, dwGlobalInfoSize = 0, dwDialinInfoSize = 0;
DWORD dwNewGlobSize = 0, dwNewDialSize = 0;
do {
// Connect to config server
dwErr = MprConfigServerConnect(NULL, &hConfig);
if (dwErr != NO_ERROR)
break;
// Get handle to global ipx tranport info
dwErr = MprConfigTransportGetHandle (
hConfig,
PID_IPX,
&hTrans);
if (dwErr != NO_ERROR)
break;
// Get global ipx tranport info
dwErr = MprConfigTransportGetInfo(
hConfig,
hTrans,
&pGlobalInfo,
&dwGlobalInfoSize,
&pDialinInfo,
&dwDialinInfoSize,
NULL);
if (dwErr != NO_ERROR)
break;
// Initialize the global info blob
dwErr = UtlUpdateInfoBlock(
FALSE,
pGlobalInfo,
IPX_PROTOCOL_SAP,
sizeof(SAP_GLOBAL_INFO),
1,
(LPBYTE)pGlobal,
&pNewGlobalInfo,
&dwNewGlobSize);
if (dwErr != NO_ERROR) {
if (dwErr != ERROR_ALREADY_EXISTS)
break;
pNewGlobalInfo = NULL;
dwNewGlobSize = 0;
}
// Initialize the dialin info blob
CopyMemory(pDialinCfg, pIfDefaults, sizeof(SAP_IF_CONFIG));
pDialinCfg->SapIfInfo.UpdateMode = IPX_NO_UPDATE;
dwErr = UtlUpdateInfoBlock(
FALSE,
pDialinInfo,
IPX_PROTOCOL_SAP,
sizeof(SAP_IF_CONFIG),
1,
(LPBYTE)pDialinCfg,
&pNewDialinInfo,
&dwNewDialSize);
if (dwErr != NO_ERROR) {
if (dwErr != ERROR_ALREADY_EXISTS)
break;
pNewDialinInfo = NULL;
dwNewDialSize = 0;
}
// Set global ipx tranport info
dwErr = MprConfigTransportSetInfo(
hConfig,
hTrans,
pNewGlobalInfo,
dwNewGlobSize,
pNewDialinInfo,
dwNewDialSize,
NULL);
if (dwErr != NO_ERROR)
break;
} while (FALSE);
// Cleanup
{
if (hConfig)
MprConfigServerDisconnect(hConfig);
if (pGlobalInfo)
MprConfigBufferFree(pGlobalInfo);
if (pDialinInfo)
MprConfigBufferFree(pDialinInfo);
if (pNewDialinInfo)
MprConfigBufferFree(pNewDialinInfo);
if (pNewGlobalInfo)
MprConfigBufferFree(pNewGlobalInfo);
}
return dwErr;
}
//
// Callback function takes an interface and updates
// its ipx sap configuration.
//
// Returns TRUE to continue the enumerate, FALSE to
// stop it
//
DWORD SapUpgradeInterface(
IN HANDLE hConfig,
IN MPR_INTERFACE_0 * pIf,
IN HANDLE hUserData)
{
SAP_ENUM_DATA* pData = (SAP_ENUM_DATA*)hUserData;
SAP_IF_CONFIG SapCfg, *pConfig = &SapCfg;
LPBYTE pTransInfo=NULL, pNewTransInfo=NULL;
HANDLE hTransport = NULL;
DWORD dwErr, dwSize, dwNewSize = 0;
// Validate input
if ((hConfig == NULL) ||
(pIf == NULL) ||
(pData == NULL))
{
return FALSE;
}
// Initalize the config blob
CopyMemory(pConfig, pData->pDefaults, sizeof(SAP_IF_CONFIG));
// Customize the update mode for the router interface
// type
switch (pIf->dwIfType) {
case ROUTER_IF_TYPE_DEDICATED:
pConfig->SapIfInfo.UpdateMode = IPX_STANDARD_UPDATE;
break;
case ROUTER_IF_TYPE_INTERNAL:
case ROUTER_IF_TYPE_CLIENT:
pConfig->SapIfInfo.UpdateMode = IPX_NO_UPDATE;
break;
case ROUTER_IF_TYPE_HOME_ROUTER:
case ROUTER_IF_TYPE_FULL_ROUTER:
pConfig->SapIfInfo.UpdateMode = IPX_AUTO_STATIC_UPDATE;
break;
case ROUTER_IF_TYPE_LOOPBACK:
case ROUTER_IF_TYPE_TUNNEL1:
default:
return TRUE;
}
do {
// Get the handle to ipx info associated with this if
dwErr = MprConfigInterfaceTransportGetHandle(
hConfig,
pIf->hInterface,
PID_IPX,
&hTransport);
if (dwErr != NO_ERROR)
break;
// Get the ipx info associated with this if
dwErr = MprConfigInterfaceTransportGetInfo(
hConfig,
pIf->hInterface,
hTransport,
&pTransInfo,
&dwSize);
if (dwErr != NO_ERROR)
break;
// Update the info block
dwErr = UtlUpdateInfoBlock(
FALSE,
pTransInfo,
IPX_PROTOCOL_SAP,
dwSize,
1,
(LPBYTE)pConfig,
&pNewTransInfo,
&dwNewSize);
if (dwErr != NO_ERROR) {
if (dwErr != ERROR_ALREADY_EXISTS)
break;
pNewTransInfo = NULL;
dwNewSize = 0;
}
// Commit the change
dwErr = MprConfigInterfaceTransportSetInfo(
hConfig,
pIf->hInterface,
hTransport,
pNewTransInfo,
dwNewSize);
if (dwErr != NO_ERROR)
break;
} while (FALSE);
// Cleanup
{
if (pNewTransInfo)
MprConfigBufferFree(pNewTransInfo);
if (pTransInfo)
MprConfigBufferFree(pTransInfo);
}
return TRUE;
}
//
// Installs ipx sap in the router registry tree.
//
DWORD SapInstallInRouter()
{
DWORD dwErr;
SAP_IF_CONFIG SapConfig, * pSap = &SapConfig;
SAP_ENUM_DATA SapBlobs =
{
pSap
};
SAP_GLOBAL_INFO SapGlobal =
{
EVENTLOG_ERROR_TYPE // event log mask
};
// Clear all structures
ZeroMemory (pSap, sizeof(SAP_IF_CONFIG));
// Default lan configuration
pSap->SapIfInfo.AdminState = ADMIN_STATE_ENABLED;
pSap->SapIfInfo.UpdateMode = IPX_STANDARD_UPDATE;
pSap->SapIfInfo.PacketType = IPX_STANDARD_PACKET_TYPE;
pSap->SapIfInfo.Supply = ADMIN_STATE_ENABLED;
pSap->SapIfInfo.Listen = ADMIN_STATE_ENABLED;
pSap->SapIfInfo.GetNearestServerReply = ADMIN_STATE_ENABLED;
pSap->SapIfInfo.PeriodicUpdateInterval = 60;
pSap->SapIfInfo.AgeIntervalMultiplier = 3;
pSap->SapIfFilters.SupplyFilterAction = IPX_SERVICE_FILTER_DENY;
pSap->SapIfFilters.SupplyFilterCount = 0;
pSap->SapIfFilters.ListenFilterAction = IPX_SERVICE_FILTER_DENY;
pSap->SapIfFilters.ListenFilterCount = 0;
// Install default sap global info
dwErr = SapInstallTransportInfo(&SapGlobal, pSap);
if (dwErr != NO_ERROR)
return dwErr;
// Enumerate the interfaces, updating each one with
// sap config as you go.
dwErr = UtlEnumerateInterfaces(
SapUpgradeInterface,
&SapBlobs);
if (dwErr != NO_ERROR)
return dwErr;
return NO_ERROR;
}
//
// Performs all of the registry updating associated with an
// upgrade from ipx sap to router.
//
// These are the steps:
// 1. Restore the parameters saved in FileName to szIpxSapKey.
// 2. Remove all parameters that ipx sap does not implement.
//
DWORD SapToRouterUpgrade(
IN PWCHAR FileName)
{
DWORD dwErr;
__try {
// Restore the registry from the backup file
dwErr = SapPrepareRegistry(FileName);
if (dwErr != NO_ERROR)
return dwErr;
// Set the new registry parameters
dwErr = SapRestoreParameters();
if (dwErr != NO_ERROR)
return dwErr;
// Install default sap global config and set default
// values in all router interfaces.
dwErr = SapInstallInRouter();
if (dwErr != NO_ERROR)
return dwErr;
// Mark the computer as having been configured
//
dwErr = UtlMarkRouterConfigured();
if (dwErr != NO_ERROR)
{
PrintMessage(L"Unable to mark router as configured.\n");
return dwErr;
}
}
__finally {
SapCleanupRegistry();
}
return NO_ERROR;
}