489 lines
12 KiB
C
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|