windows-nt/Source/XPSP1/NT/net/rras/ipx/rtrmgr/rpal.c
2020-09-26 16:20:57 +08:00

907 lines
23 KiB
C

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
rpal.c
Abstract:
Routing protocols abstraction layer. It abstracts the RIP/SAP or NLSP routing
protocols interface functions for the rest of the router manager system.
Author:
Stefan Solomon 04/24/1995
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
//
// Service Table Manager Entry Points
//
PIS_SERVICE STM_IsService;
PCREATE_SERVICE_ENUMERATION_HANDLE STM_CreateServiceEnumerationHandle;
PENUMERATE_GET_NEXT_SERVICE STM_EnumerateGetNextService;
PCLOSE_SERVICE_ENUMERATION_HANDLE STM_CloseServiceEnumerationHandle;
PGET_SERVICE_COUNT STM_GetServiceCount;
PCREATE_STATIC_SERVICE STM_CreateStaticService;
PDELETE_STATIC_SERVICE STM_DeleteStaticService;
PBLOCK_CONVERT_SERVICES_TO_STATIC STM_BlockConvertServicesToStatic;
PBLOCK_DELETE_STATIC_SERVICES STM_BlockDeleteStaticServices;
PGET_FIRST_ORDERED_SERVICE STM_GetFirstOrderedService;
PGET_NEXT_ORDERED_SERVICE STM_GetNextOrderedService;
//
// Auto-Static Update Entry Points
//
ULONG UpdateRoutesProtId;
PDO_UPDATE_ROUTES RP_UpdateRoutes;
ULONG UpdateServicesProtId;
PDO_UPDATE_SERVICES RP_UpdateServices;
//
// Router Manager Support Functions - Passed to routing protocols at Start
//
SUPPORT_FUNCTIONS RMSupportFunctions = {
RoutingProtocolConnectionRequest,
MibCreate,
MibDelete,
MibSet,
MibGet,
MibGetFirst,
MibGetNext
};
//**************************************************************************
// *
// Routing Protocols Init/Start/Stop Functions *
// *
//**************************************************************************
DWORD
StartRoutingProtocols(LPVOID GlobalInfop,
HANDLE RoutingProtocolsEvent)
{
DWORD rc, i, count, namelen, support;
HINSTANCE moduleinstance;
PRPCB rpcbp;
LPVOID ProtocolGlobalInfop;
PIPX_GLOBAL_INFO IpxGlobalInfop;
MPR_PROTOCOL_0 *RtProtocolsp;
DWORD NumRoutingProtocols;
MPR_ROUTING_CHARACTERISTICS mrcRouting;
MPR_SERVICE_CHARACTERISTICS mscService;
// Initialize Routing Protocols List
//
InitializeListHead(&RoutingProtocolCBList);
rc = MprSetupProtocolEnum (PID_IPX, (LPBYTE *)&RtProtocolsp, &NumRoutingProtocols);
if (rc!=NO_ERROR) {
Trace (RPAL_TRACE,
"StartRoutingProtocols: failed to get routing protocol info: %d",
rc);
return ERROR_CAN_NOT_COMPLETE;
}
Trace (RPAL_TRACE, "StartRoutingProtocols: %d protocols installed.",
NumRoutingProtocols);
for (i=0; i<NumRoutingProtocols; i++) {
if (GetInfoEntry(GlobalInfop, RtProtocolsp[i].dwProtocolId)==NULL)
continue;
// load library on the dll name provided
//
moduleinstance = LoadLibraryW (RtProtocolsp[i].wszDLLName) ;
if (moduleinstance == NULL) {
IF_LOG (EVENTLOG_ERROR_TYPE) {
LPWSTR pname[1] = {RtProtocolsp[i].wszDLLName};
RouterLogErrorW (RMEventLogHdl,
ROUTERLOG_IPX_CANT_LOAD_PROTOCOL,
1, pname, rc);
}
Trace(RPAL_TRACE, "StartRoutingProtocols: %ls failed to load: %d\n", RtProtocolsp[i].wszDLLName, GetLastError());
MprSetupProtocolFree (RtProtocolsp);
return ERROR_CAN_NOT_COMPLETE;
}
namelen = sizeof(WCHAR) * (wcslen(RtProtocolsp[i].wszDLLName) + 1) ; // +1 for null character
rpcbp = (PRPCB) GlobalAlloc (GPTR, sizeof(RPCB) + namelen) ;
if (rpcbp == NULL) {
FreeLibrary (moduleinstance) ;
Trace(RPAL_TRACE, "StartRoutingProtocols: memory allocation failure\n");
MprSetupProtocolFree (RtProtocolsp);
return ERROR_CAN_NOT_COMPLETE;
}
ZeroMemory(rpcbp,
sizeof(RPCB) + namelen);
rpcbp->RP_DllName = (PWSTR)((PUCHAR)rpcbp + sizeof(RPCB));
rpcbp->RP_DllHandle = moduleinstance;
memcpy (rpcbp->RP_DllName, RtProtocolsp[i].wszDLLName, namelen) ;
// Loading all entrypoints
//
rpcbp->RP_RegisterProtocol =
(PREGISTER_PROTOCOL)GetProcAddress(moduleinstance,
REGISTER_PROTOCOL_ENTRY_POINT_STRING)
;
if(rpcbp->RP_RegisterProtocol == NULL)
{
//
// Could not find the RegisterProtocol entry point
// Nothing we can do - bail out
//
Sleep(0);
MprSetupProtocolFree (RtProtocolsp);
Trace(RPAL_TRACE, "StartRoutingProtocols: Could not find RegisterProtocol for %S",
RtProtocolsp[i].wszDLLName);
GlobalFree(rpcbp);
FreeLibrary(moduleinstance);
return ERROR_INVALID_FUNCTION;
}
ZeroMemory(&mrcRouting,
sizeof(MPR_ROUTING_CHARACTERISTICS));
ZeroMemory(&mscService,
sizeof(MPR_SERVICE_CHARACTERISTICS));
mrcRouting.dwVersion = MS_ROUTER_VERSION;
mrcRouting.dwProtocolId = RtProtocolsp[i].dwProtocolId;
mrcRouting.fSupportedFunctionality = ROUTING|DEMAND_UPDATE_ROUTES;
mscService.dwVersion = MS_ROUTER_VERSION;
mscService.dwProtocolId = RtProtocolsp[i].dwProtocolId;
mscService.fSupportedFunctionality = SERVICES|DEMAND_UPDATE_SERVICES;
rpcbp->RP_ProtocolId = RtProtocolsp[i].dwProtocolId;
rc = rpcbp->RP_RegisterProtocol(&mrcRouting,
&mscService);
if(rc != NO_ERROR)
{
Sleep(0);
IF_LOG (EVENTLOG_ERROR_TYPE) {
CHAR num[8];
LPSTR pnum[1] = {num};
_ultoa (rpcbp->RP_ProtocolId, num, 16);
RouterLogErrorA (RMEventLogHdl,
ROUTERLOG_IPX_CANT_REGISTER_PROTOCOL,
1, pnum, rc);
}
FreeLibrary(moduleinstance);
GlobalFree(rpcbp);
Trace(RPAL_TRACE, "StartRoutingProtocols: %S returned error %d while registering",
RtProtocolsp[i].wszDLLName,
rc);
MprSetupProtocolFree (RtProtocolsp);
return rc;
}
rpcbp->RP_StartProtocol = mrcRouting.pfnStartProtocol;
rpcbp->RP_StopProtocol = mrcRouting.pfnStopProtocol;
rpcbp->RP_AddInterface = mrcRouting.pfnAddInterface;
rpcbp->RP_DeleteInterface = mrcRouting.pfnDeleteInterface;
rpcbp->RP_GetEventMessage = mrcRouting.pfnGetEventMessage;
rpcbp->RP_GetIfConfigInfo = mrcRouting.pfnGetInterfaceInfo;
rpcbp->RP_SetIfConfigInfo = mrcRouting.pfnSetInterfaceInfo;
rpcbp->RP_BindInterface = mrcRouting.pfnBindInterface;
rpcbp->RP_UnBindInterface = mrcRouting.pfnUnbindInterface;
rpcbp->RP_EnableInterface = mrcRouting.pfnEnableInterface;
rpcbp->RP_DisableInterface = mrcRouting.pfnDisableInterface;
rpcbp->RP_GetGlobalInfo = mrcRouting.pfnGetGlobalInfo;
rpcbp->RP_SetGlobalInfo = mrcRouting.pfnSetGlobalInfo;
rpcbp->RP_MibCreate = mrcRouting.pfnMibCreateEntry;
rpcbp->RP_MibDelete = mrcRouting.pfnMibDeleteEntry;
rpcbp->RP_MibGet = mrcRouting.pfnMibGetEntry;
rpcbp->RP_MibSet = mrcRouting.pfnMibSetEntry;
rpcbp->RP_MibGetFirst = mrcRouting.pfnMibGetFirstEntry;
rpcbp->RP_MibGetNext = mrcRouting.pfnMibGetNextEntry;
if (!(rpcbp->RP_RegisterProtocol) ||
!(rpcbp->RP_StartProtocol) ||
!(rpcbp->RP_StopProtocol) ||
!(rpcbp->RP_AddInterface) ||
!(rpcbp->RP_DeleteInterface) ||
!(rpcbp->RP_GetEventMessage) ||
!(rpcbp->RP_GetIfConfigInfo) ||
!(rpcbp->RP_SetIfConfigInfo) ||
!(rpcbp->RP_BindInterface) ||
!(rpcbp->RP_UnBindInterface) ||
!(rpcbp->RP_EnableInterface) ||
!(rpcbp->RP_DisableInterface) ||
!(rpcbp->RP_GetGlobalInfo) ||
!(rpcbp->RP_SetGlobalInfo) ||
!(rpcbp->RP_MibCreate) ||
!(rpcbp->RP_MibDelete) ||
!(rpcbp->RP_MibSet) ||
!(rpcbp->RP_MibGet) ||
!(rpcbp->RP_MibGetFirst) ||
!(rpcbp->RP_MibGetNext))
{
Trace(RPAL_TRACE, "StartRoutingProtocols: %ls failed to load entrypoints",
RtProtocolsp[i].wszDLLName);
GlobalFree(rpcbp);
FreeLibrary (moduleinstance);
MprSetupProtocolFree (RtProtocolsp);
return ERROR_CAN_NOT_COMPLETE;
}
if(mscService.fSupportedFunctionality & SERVICES)
{
STM_IsService = mscService.pfnIsService;
STM_CreateServiceEnumerationHandle = mscService.pfnCreateServiceEnumerationHandle;
STM_EnumerateGetNextService = mscService.pfnEnumerateGetNextService;
STM_CloseServiceEnumerationHandle = mscService.pfnCloseServiceEnumerationHandle;
STM_GetServiceCount = mscService.pfnGetServiceCount;
STM_CreateStaticService = mscService.pfnCreateStaticService;
STM_DeleteStaticService = mscService.pfnDeleteStaticService;
STM_BlockConvertServicesToStatic = mscService.pfnBlockConvertServicesToStatic;
STM_BlockDeleteStaticServices = mscService.pfnBlockDeleteStaticServices;
STM_GetFirstOrderedService = mscService.pfnGetFirstOrderedService;
STM_GetNextOrderedService = mscService.pfnGetNextOrderedService;
if(!(STM_IsService) ||
!(STM_CreateServiceEnumerationHandle) ||
!(STM_EnumerateGetNextService) ||
!(STM_CloseServiceEnumerationHandle) ||
!(STM_GetServiceCount) ||
!(STM_CreateStaticService) ||
!(STM_DeleteStaticService) ||
!(STM_BlockConvertServicesToStatic) ||
!(STM_BlockDeleteStaticServices) ||
!(STM_GetFirstOrderedService) ||
!(STM_GetNextOrderedService))
{
Trace(RPAL_TRACE, "StartRoutingProtocols: %ls failed to get STM entry points\n",
RtProtocolsp[i].wszDLLName);
GlobalFree(rpcbp);
FreeLibrary (moduleinstance);
MprSetupProtocolFree (RtProtocolsp);
return ERROR_CAN_NOT_COMPLETE;
}
}
if(mrcRouting.fSupportedFunctionality & DEMAND_UPDATE_ROUTES)
{
RP_UpdateRoutes = mrcRouting.pfnUpdateRoutes;
if(!RP_UpdateRoutes)
{
Trace(RPAL_TRACE,
"StartRoutingProtocols: %ls failed to get UpdateRoutes entry points\n",
RtProtocolsp[i].wszDLLName);
GlobalFree(rpcbp);
FreeLibrary (moduleinstance);
MprSetupProtocolFree (RtProtocolsp);
return ERROR_CAN_NOT_COMPLETE;
}
UpdateRoutesProtId = rpcbp->RP_ProtocolId;
}
if(mscService.fSupportedFunctionality & DEMAND_UPDATE_SERVICES)
{
RP_UpdateServices = mscService.pfnUpdateServices;
if(!RP_UpdateServices)
{
Trace(RPAL_TRACE,
"StartRoutingProtocols: %ls failed to get UpdateServices entry points\n",
RtProtocolsp[i].wszDLLName);
GlobalFree(rpcbp);
FreeLibrary (moduleinstance);
MprSetupProtocolFree (RtProtocolsp);
return ERROR_CAN_NOT_COMPLETE;
}
UpdateServicesProtId = rpcbp->RP_ProtocolId;
}
ProtocolGlobalInfop = GetInfoEntry(GlobalInfop, rpcbp->RP_ProtocolId);
if ((rc = (*rpcbp->RP_StartProtocol)(RoutingProtocolsEvent,
&RMSupportFunctions,
ProtocolGlobalInfop)) != NO_ERROR) {
IF_LOG (EVENTLOG_ERROR_TYPE) {
CHAR num[8];
LPSTR pnum[1] = {num};
_ultoa (rpcbp->RP_ProtocolId, num, 16);
RouterLogErrorA (RMEventLogHdl,
ROUTERLOG_IPX_CANT_START_PROTOCOL,
1, pnum, rc);
}
Trace(RPAL_TRACE, "StartRoutingProtocols: %ls failed to start: %d\n",
RtProtocolsp[i].wszDLLName, rc);
GlobalFree(rpcbp);
FreeLibrary (moduleinstance);
MprSetupProtocolFree (RtProtocolsp);
return ERROR_CAN_NOT_COMPLETE;
}
// Insert this routing protocol in the list of routing protocols
//
InsertTailList(&RoutingProtocolCBList, &rpcbp->RP_Linkage);
RoutingProtocolActiveCount++;
Trace(RPAL_TRACE, "StartRoutingProtocols: %ls successfully initialized",
RtProtocolsp[i].wszDLLName);
}
if(!RP_UpdateRoutes || !RP_UpdateServices) {
Trace(RPAL_TRACE, "StartRoutingProtocols: missing update entry point\n");
MprSetupProtocolFree (RtProtocolsp);
return ERROR_CAN_NOT_COMPLETE;
}
MprSetupProtocolFree (RtProtocolsp);
Trace(RPAL_TRACE, "");
return NO_ERROR;
}
VOID
StopRoutingProtocols(VOID)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
DWORD rc;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList) {
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
(*rpcbp->RP_StopProtocol)();
lep = lep->Flink;
}
}
//**************************************************************************
// *
// Routing Protocols Interface Management Functions *
// *
//**************************************************************************
DWORD
CreateRoutingProtocolsInterfaces(PIPX_INFO_BLOCK_HEADER InterfaceInfop,
PICB icbp)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
LPVOID RpIfInfop;
NET_INTERFACE_TYPE NetInterfaceType;
DWORD rc;
NetInterfaceType = MapIpxToNetInterfaceType(icbp);
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
RpIfInfop = GetInfoEntry(InterfaceInfop, rpcbp->RP_ProtocolId);
if(RpIfInfop == NULL) {
return ERROR_CAN_NOT_COMPLETE;
}
rc = (*rpcbp->RP_AddInterface)(
icbp->InterfaceNamep,
icbp->InterfaceIndex,
NetInterfaceType,
RpIfInfop);
if(rc != NO_ERROR) {
return rc;
}
lep = lep->Flink;
}
return NO_ERROR;
}
DWORD
DeleteRoutingProtocolsInterfaces(ULONG InterfaceIndex)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
(*rpcbp->RP_DeleteInterface)(InterfaceIndex);
lep = lep->Flink;
}
return NO_ERROR;
}
ULONG
SizeOfRoutingProtocolsIfsInfo(ULONG InterfaceIndex)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
ULONG TotalInfoSize = 0;
ULONG RpIfInfoSize = 0;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
(*rpcbp->RP_GetIfConfigInfo)(InterfaceIndex, NULL, &RpIfInfoSize);
// align size on double DWORD boundary - add two's complement for the last three bits
RpIfInfoSize += ((~RpIfInfoSize) + 1) & 0x7;
TotalInfoSize += RpIfInfoSize;
RpIfInfoSize = 0;
lep = lep->Flink;
}
return TotalInfoSize;
}
ULONG
RoutingProtocolsTocCount(VOID)
{
return(RoutingProtocolActiveCount);
}
/*++
Function: CreateRoutingProtocolsTocAndInfoEntries
Descr: as it says
Arguments: ibhp - ptr to the info block header
InterfaceIndex
current_tocepp - ptr to the location of the current TOC ptr; you have
to increment this to get to the next TOC -> your TOC!
current_NextInfoOffsetp - pointer to the location of the next info entry offset
in the info block; you have to use this for your info
entry and then to increment it for the next user.
--*/
DWORD
CreateRoutingProtocolsTocAndInfoEntries(PIPX_INFO_BLOCK_HEADER ibhp,
ULONG InterfaceIndex,
PIPX_TOC_ENTRY *current_tocepp,
PULONG current_NextInfoOffsetp)
{
PIPX_TOC_ENTRY tocep;
ULONG NextInfoOffset;
PLIST_ENTRY lep;
PRPCB rpcbp;
ULONG RpIfInfoSize;
DWORD rc;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
// increment the current pointer to table of contents entries so it will
// point to the next entry
(*current_tocepp)++;
tocep = *current_tocepp;
// create the routing protocol and info toc entry
tocep->InfoType = rpcbp->RP_ProtocolId;
tocep->InfoSize = 0;
tocep->Count = 1;
tocep->Offset = *current_NextInfoOffsetp;
rc = (*rpcbp->RP_GetIfConfigInfo)(InterfaceIndex,
(LPVOID)((PUCHAR)ibhp + tocep->Offset),
&tocep->InfoSize);
if(rc != ERROR_INSUFFICIENT_BUFFER) {
return rc;
}
rc = (*rpcbp->RP_GetIfConfigInfo)(InterfaceIndex,
(LPVOID)((PUCHAR)ibhp + tocep->Offset),
&tocep->InfoSize);
if(rc != NO_ERROR) {
return rc;
}
*current_NextInfoOffsetp += tocep->InfoSize;
// align the next offset on DWORD boundary
*current_NextInfoOffsetp += (~*current_NextInfoOffsetp + 1) & 0x7;
lep = lep->Flink;
}
return NO_ERROR;
}
DWORD
SetRoutingProtocolsInterfaces(PIPX_INFO_BLOCK_HEADER InterfaceInfop,
ULONG InterfaceIndex)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
LPVOID RpIfInfop;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
RpIfInfop = GetInfoEntry(InterfaceInfop, rpcbp->RP_ProtocolId);
if(RpIfInfop == NULL) {
return ERROR_CAN_NOT_COMPLETE;
}
(*rpcbp->RP_SetIfConfigInfo)(InterfaceIndex, RpIfInfop);
lep = lep->Flink;
}
return NO_ERROR;
}
DWORD
BindRoutingProtocolsIfsToAdapter(ULONG InterfaceIndex,
PIPX_ADAPTER_BINDING_INFO abip)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
(*rpcbp->RP_BindInterface)(InterfaceIndex, abip);
lep = lep->Flink;
}
return NO_ERROR;
}
DWORD
UnbindRoutingProtocolsIfsFromAdapter(ULONG InterfaceIndex)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
(*rpcbp->RP_UnBindInterface)(InterfaceIndex);
lep = lep->Flink;
}
return NO_ERROR;
}
DWORD
RoutingProtocolsEnableIpxInterface(ULONG InterfaceIndex)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
(*rpcbp->RP_EnableInterface)(InterfaceIndex);
lep = lep->Flink;
}
return NO_ERROR;
}
DWORD
RoutingProtocolsDisableIpxInterface(ULONG InterfaceIndex)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
(*rpcbp->RP_DisableInterface)(InterfaceIndex);
lep = lep->Flink;
}
return NO_ERROR;
}
//**************************************************************************
// *
// Routing Protocols Services Management Functions *
// *
//**************************************************************************
DWORD
GetFirstService(DWORD OrderingMethod,
DWORD ExclusionFlags,
PIPX_SERVICE Servicep)
{
return(*STM_GetFirstOrderedService)(OrderingMethod, ExclusionFlags, Servicep);
}
DWORD
GetNextService(DWORD OrderingMethod,
DWORD ExclusionFlags,
PIPX_SERVICE Servicep)
{
return(*STM_GetNextOrderedService)(OrderingMethod, ExclusionFlags, Servicep);
}
DWORD
CreateStaticService(PICB icbp,
PIPX_STATIC_SERVICE_INFO ServiceEntry)
{
DWORD rc;
rc = (*STM_CreateStaticService)(icbp->InterfaceIndex, ServiceEntry);
return rc;
}
DWORD
DeleteStaticService(ULONG InterfaceIndex,
PIPX_STATIC_SERVICE_INFO ServiceEntry)
{
DWORD rc;
rc = (*STM_DeleteStaticService)(InterfaceIndex, ServiceEntry);
return rc;
}
HANDLE
CreateStaticServicesEnumHandle(ULONG InterfaceIndex)
{
IPX_SERVICE CriteriaService;
HANDLE EnumHandle;
if(STM_CreateServiceEnumerationHandle == NULL) {
return NULL;
}
memset(&CriteriaService, 0, sizeof(IPX_SERVICE));
CriteriaService.InterfaceIndex = InterfaceIndex;
CriteriaService.Protocol = IPX_PROTOCOL_STATIC;
EnumHandle = (*STM_CreateServiceEnumerationHandle)(
STM_ONLY_THIS_INTERFACE | STM_ONLY_THIS_PROTOCOL,
&CriteriaService);
return EnumHandle;
}
DWORD
GetNextStaticService(HANDLE EnumHandle,
PIPX_STATIC_SERVICE_INFO StaticSvInfop)
{
IPX_SERVICE Service;
DWORD rc;
if((rc = (*STM_EnumerateGetNextService)(EnumHandle,
&Service)) == NO_ERROR) {
// fill in the static service structure
*StaticSvInfop = Service.Server;
}
return rc;
}
DWORD
CloseStaticServicesEnumHandle(HANDLE EnumHandle)
{
DWORD rc = NO_ERROR;
if(EnumHandle) {
rc = (*STM_CloseServiceEnumerationHandle)(EnumHandle);
}
return rc;
}
DWORD
DeleteAllStaticServices(ULONG InterfaceIndex)
{
if(!STM_BlockDeleteStaticServices) {
return NO_ERROR;
}
return((*STM_BlockDeleteStaticServices)(InterfaceIndex));
}
DWORD
GetServiceCount(VOID)
{
if(!STM_GetServiceCount) {
return 0;
}
return((*STM_GetServiceCount)());
}
//**************************************************************************
// *
// Routing Protocols Auto-Static Update Functions *
// *
//**************************************************************************
DWORD
RtProtRequestRoutesUpdate(ULONG InterfaceIndex)
{
return((*RP_UpdateRoutes)(InterfaceIndex));
}
DWORD
RtProtRequestServicesUpdate(ULONG InterfaceIndex)
{
return((*RP_UpdateServices)(InterfaceIndex));
}
VOID
DestroyRoutingProtocolCB(PRPCB rpcbp)
{
RemoveEntryList(&rpcbp->RP_Linkage);
FreeLibrary (rpcbp->RP_DllHandle);
GlobalFree(rpcbp);
RoutingProtocolActiveCount--;
}
VOID
ConvertAllServicesToStatic(ULONG InterfaceIndex)
{
STM_BlockConvertServicesToStatic(InterfaceIndex);
}
DWORD
GetStaticServicesCount(ULONG InterfaceIndex)
{
HANDLE EnumHandle;
DWORD Count;
IPX_STATIC_SERVICE_INFO StaticSvInfo;
EnumHandle = CreateStaticServicesEnumHandle(InterfaceIndex);
if(EnumHandle == NULL) {
return 0;
}
Count = 0;
while(GetNextStaticService(EnumHandle, &StaticSvInfo) == NO_ERROR) {
Count++;
}
CloseStaticServicesEnumHandle(EnumHandle);
return Count;
}
PRPCB
GetRoutingProtocolCB(DWORD ProtocolId)
{
PRPCB rpcbp;
PLIST_ENTRY lep;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
if(rpcbp->RP_ProtocolId == ProtocolId) {
return rpcbp;
}
lep = lep->Flink;
}
return NULL;
}
BOOL
IsService(USHORT SvType,
PUCHAR SvName,
PIPX_SERVICE Svp)
{
return(STM_IsService(SvType, SvName, Svp));
}
DWORD
SetRoutingProtocolsGlobalInfo(PIPX_INFO_BLOCK_HEADER GlobalInfop)
{
PLIST_ENTRY lep;
PRPCB rpcbp;
LPVOID RpGlobalInfop;
lep = RoutingProtocolCBList.Flink;
while(lep != &RoutingProtocolCBList)
{
rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
RpGlobalInfop = GetInfoEntry(GlobalInfop, rpcbp->RP_ProtocolId);
if(RpGlobalInfop == NULL) {
return NO_ERROR;
}
(*rpcbp->RP_SetGlobalInfo)(RpGlobalInfop);
lep = lep->Flink;
}
return NO_ERROR;
}