|
|
#include "precomp.h"
#pragma hdrstop
TOKEN_VALUE InterfaceTypes[ 5 ] = { { VAL_CLIENT, ROUTER_IF_TYPE_CLIENT }, { VAL_HOMEROUTER, ROUTER_IF_TYPE_HOME_ROUTER }, { VAL_WANROUTER, ROUTER_IF_TYPE_FULL_ROUTER }, { VAL_DEDICATED, ROUTER_IF_TYPE_DEDICATED }, { VAL_INTERNAL, ROUTER_IF_TYPE_INTERNAL } };
TOKEN_VALUE InterfaceStates[ 3 ] = { { VAL_DOWN, ROUTER_IF_STATE_DISCONNECTED }, { VAL_DOWN, ROUTER_IF_STATE_CONNECTING }, { VAL_UP, ROUTER_IF_STATE_CONNECTED } };
TOKEN_VALUE InterfaceEnableStatus[ 2 ] = { { VAL_ENABLED, FALSE }, { VAL_DISABLED, TRUE } };
TOKEN_VALUE AdminStates[ 2 ] = { { VAL_DISABLED, ADMIN_STATE_DISABLED }, { VAL_ENABLED, ADMIN_STATE_ENABLED } };
TOKEN_VALUE OperStates[ 3 ] = { { VAL_DOWN, OPER_STATE_DOWN }, { VAL_UP, OPER_STATE_UP }, { VAL_SLEEPING, OPER_STATE_SLEEPING } };
TOKEN_VALUE IpxInterfaceTypes[ 8 ] = { { VAL_OTHER, IF_TYPE_OTHER }, { VAL_DEDICATED, IF_TYPE_LAN }, { VAL_WANROUTER, IF_TYPE_WAN_ROUTER }, { VAL_CLIENT, IF_TYPE_WAN_WORKSTATION }, { VAL_INTERNAL, IF_TYPE_INTERNAL }, { VAL_HOMEROUTER, IF_TYPE_PERSONAL_WAN_ROUTER }, { VAL_DIALOUT, IF_TYPE_ROUTER_WORKSTATION_DIALOUT }, { VAL_DIALOUT, IF_TYPE_STANDALONE_WORKSTATION_DIALOUT } };
TOKEN_VALUE RouterInterfaceTypes[ 5 ] = { { VAL_CLIENT, ROUTER_IF_TYPE_CLIENT }, { VAL_HOMEROUTER, ROUTER_IF_TYPE_HOME_ROUTER }, { VAL_WANROUTER, ROUTER_IF_TYPE_FULL_ROUTER }, { VAL_DEDICATED, ROUTER_IF_TYPE_DEDICATED }, { VAL_INTERNAL, ROUTER_IF_TYPE_INTERNAL } };
TOKEN_VALUE NbDeliverStates[ 4 ] = { { VAL_DISABLED, ADMIN_STATE_DISABLED }, { VAL_ENABLED, ADMIN_STATE_DISABLED }, { VAL_STATICONLY, ADMIN_STATE_ENABLED_ONLY_FOR_NETBIOS_STATIC_ROUTING }, { VAL_ONLYWHENUP, ADMIN_STATE_ENABLED_ONLY_FOR_OPER_STATE_UP} };
TOKEN_VALUE UpdateModes[ 3 ] = { { VAL_STANDARD, IPX_STANDARD_UPDATE }, { VAL_NONE, IPX_NO_UPDATE }, { VAL_AUTOSTATIC, IPX_AUTO_STATIC_UPDATE } };
TOKEN_VALUE IpxProtocols[ 4 ] = { { VAL_LOCAL, IPX_PROTOCOL_LOCAL }, { VAL_STATIC, IPX_PROTOCOL_STATIC }, { VAL_RIP, IPX_PROTOCOL_RIP }, { VAL_SAP, IPX_PROTOCOL_SAP } };
TOKEN_VALUE TfFilterActions[ 2 ] = { { VAL_PERMIT, IPX_TRAFFIC_FILTER_ACTION_PERMIT }, { VAL_DENY, IPX_TRAFFIC_FILTER_ACTION_DENY } };
TOKEN_VALUE RipFilterActions[ 2 ] = { { VAL_PERMIT, IPX_ROUTE_FILTER_PERMIT }, { VAL_DENY, IPX_ROUTE_FILTER_DENY } };
TOKEN_VALUE SapFilterActions[ 2 ] = { { VAL_PERMIT, IPX_SERVICE_FILTER_PERMIT }, { VAL_DENY, IPX_SERVICE_FILTER_DENY } };
TOKEN_VALUE WANProtocols[ 2 ] = { { VAL_PPP, ADMIN_STATE_DISABLED }, { VAL_IPXWAN, ADMIN_STATE_ENABLED } };
TOKEN_VALUE FilterModes[ 2 ] = { { VAL_INPUT, INPUT_FILTER }, { VAL_OUTPUT, OUTPUT_FILTER } };
TOKEN_VALUE LogLevels[ 4 ] = { { VAL_NONE , 0 }, { VAL_ERRORS_ONLY , EVENTLOG_ERROR_TYPE }, { VAL_ERRORS_AND_WARNINGS, EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE }, { VAL_MAXINFO, EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE } };
DWORD GetIpxInterfaceIndex( IN MIB_SERVER_HANDLE hRouterMIB, IN LPCWSTR InterfaceName, OUT ULONG *InterfaceIndex ) /*++
Routine Description :
This routine retrives the index of an interface given its name.
Arguments :
hRouterMIB - Handle to the router service
InterfaceName - Name of interface for which index is required
InterfaceIndex - On return contains the interface of the interface if found.
Return values :
--*/ {
IPX_MIB_GET_INPUT_DATA MibGetInputData; DWORD IfSize = sizeof(IPX_INTERFACE); PIPX_INTERFACE Ifp; DWORD rc; UCHAR InterfaceNameA[ MAX_INTERFACE_NAME_LEN + 1 ];
//
// Convert interface name to Ansi
//
wcstombs( InterfaceNameA, InterfaceName, MAX_INTERFACE_NAME_LEN );
MibGetInputData.TableId = IPX_INTERFACE_TABLE;
//
// Begin enumerating interfaces
//
rc = MprAdminMIBEntryGetFirst( hRouterMIB, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData, sizeof( IPX_MIB_GET_INPUT_DATA ), (LPVOID *) &Ifp, &IfSize );
//
// until a match is found or there are no more interfaces
//
while ( rc == NO_ERROR ) { //
// Is this the interface
//
if ( _stricmp( (LPSTR)InterfaceNameA, (LPSTR) Ifp->InterfaceName) == 0 ) { *InterfaceIndex = Ifp->InterfaceIndex; MprAdminMIBBufferFree (Ifp); break; } else { MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex = Ifp->InterfaceIndex; MprAdminMIBBufferFree (Ifp); } rc = MprAdminMIBEntryGetNext( hRouterMIB, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData, sizeof(IPX_MIB_GET_INPUT_DATA), (LPVOID *)&Ifp, &IfSize ); }
if ( rc == ERROR_NO_MORE_ITEMS ) { rc = ERROR_NO_SUCH_INTERFACE; } return rc; }
DWORD GetIpxInterfaceName ( IN MIB_SERVER_HANDLE hRouterMIB, IN ULONG InterfaceIndex, OUT LPWSTR InterfaceName ) /*++
Routine Description :
This routine retrives the index of an interface given its name.
Arguments :
hRouterMIB - Handle to the router service
InterfaceName - Name of interface for which index is required
InterfaceIndex - On return contains the interface of the interface if found.
Return values :
--*/ { IPX_MIB_GET_INPUT_DATA MibGetInputData; DWORD IfSize = sizeof( IPX_INTERFACE ); PIPX_INTERFACE Ifp; DWORD rc;
MibGetInputData.TableId = IPX_INTERFACE_TABLE; MibGetInputData.MibIndex.InterfaceTableIndex.InterfaceIndex = InterfaceIndex; rc = MprAdminMIBEntryGet( hRouterMIB, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData, sizeof(IPX_MIB_GET_INPUT_DATA), (LPVOID *)&Ifp, &IfSize ); if ( rc == NO_ERROR ) { mbstowcs( InterfaceName, (LPSTR)Ifp->InterfaceName, IPX_INTERFACE_ANSI_NAME_LEN );
MprAdminMIBBufferFree( Ifp ); } else if ( rc == ERROR_NO_MORE_ITEMS ) { rc = ERROR_NO_SUCH_INTERFACE; } return rc; }
/*++
******************************************************************* G e t I P X T o c E n t r y
Routine Description: Returns pointer to entry in Router Table Of Context Arguments: pInterfaceInfo - pointer to table of content InfoEntryType - type of entry to look for Return Value: Pointer to entry in table of content NULL if there is no such entry in the table Remarks: ******************************************************************* --*/ PIPX_TOC_ENTRY GetIPXTocEntry( IN PIPX_INFO_BLOCK_HEADER pInterfaceInfo, IN ULONG InfoEntryType ) { UINT i; PIPX_TOC_ENTRY pTocEntry;
if (pInterfaceInfo) { for ( i = 0, pTocEntry = pInterfaceInfo->TocEntry; i < pInterfaceInfo->TocEntriesCount; i++, pTocEntry++) { if (pTocEntry->InfoType == InfoEntryType) { return pTocEntry; } } }
SetLastError( ERROR_FILE_NOT_FOUND ); return NULL; }
DWORD AddIPXInfoEntry ( IN PIPX_INFO_BLOCK_HEADER pOldBlock, IN ULONG InfoType, IN ULONG InfoSize, IN PVOID Info, IN PINFO_CMP_PROC InfoEqualCB OPTIONAL, OUT PIPX_INFO_BLOCK_HEADER *pNewBlock ) { ULONG i, entriesCount = 1; PIPX_TOC_ENTRY pTocEntry; PIPX_INFO_BLOCK_HEADER pBlock; ULONG newBlockSize = InfoSize + sizeof( IPX_INFO_BLOCK_HEADER ); BOOLEAN done = FALSE; DWORD rc;
if ( pOldBlock != NULL ) { ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1); for ( i=0, pTocEntry = pOldBlock->TocEntry; i < pOldBlock->TocEntriesCount; i++, pTocEntry++) { newBlockSize += pTocEntry->InfoSize*pTocEntry->Count; if (pTocEntry->InfoType == InfoType) { ULONG j; LPBYTE pInfo = (LPBYTE)pOldBlock+pTocEntry->Offset;
ASSERT (pTocEntry->InfoSize == InfoSize); for (j=0; j<pTocEntry->Count; j++, pInfo+=InfoSize) { BOOL found; if (InfoEqualCB!=NULL) { found = (*InfoEqualCB) (pInfo, Info); } else { found = memcmp (pInfo, Info, InfoSize)==0; } if (found) { return ERROR_ALREADY_EXISTS; } } } else { entriesCount += 1; newBlockSize += sizeof (IPX_TOC_ENTRY); } } } pBlock = (PIPX_INFO_BLOCK_HEADER)GlobalAlloc (GPTR, newBlockSize); if ( pBlock != NULL ) { ULONG dstOffset = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER,TocEntry[entriesCount]); PIPX_TOC_ENTRY dstToc = pBlock->TocEntry;
pBlock->Version = IPX_ROUTER_VERSION_1; pBlock->Size = newBlockSize; pBlock->TocEntriesCount = entriesCount; if (pOldBlock!=NULL) { for (i=0, pTocEntry = pOldBlock->TocEntry; i<pOldBlock->TocEntriesCount; i++, pTocEntry++) { *dstToc = *pTocEntry; dstToc->Offset = dstOffset;
memcpy ((PUCHAR)pBlock+dstOffset, (PUCHAR)pOldBlock+pTocEntry->Offset, pTocEntry->InfoSize*pTocEntry->Count);
dstOffset += dstToc->InfoSize*dstToc->Count;
if (dstToc->InfoType==InfoType) { memcpy ((PUCHAR)pBlock+dstOffset, Info, InfoSize); dstToc->Count += 1; dstOffset += InfoSize; done = TRUE; } dstToc += 1; } }
if (!done) { dstToc->InfoType = InfoType; dstToc->InfoSize = InfoSize; dstToc->Count = 1; dstToc->Offset = dstOffset; memcpy ((PUCHAR)pBlock+dstOffset, Info, InfoSize); } *pNewBlock = pBlock; rc = NO_ERROR; } else { rc = ERROR_NOT_ENOUGH_MEMORY; } return rc; }
DWORD DeleteIPXInfoEntry ( IN PIPX_INFO_BLOCK_HEADER pOldBlock, IN ULONG InfoType, IN ULONG InfoSize, IN PVOID Info, IN PINFO_CMP_PROC InfoEqualCB OPTIONAL, IN PIPX_INFO_BLOCK_HEADER *pNewBlock ) { ULONG i, entriesCount = 1, j; PIPX_TOC_ENTRY pTocEntry, dstToc; ULONG newBlockSize = sizeof (IPX_INFO_BLOCK_HEADER)-InfoSize; ULONG dstOffset; BOOLEAN found = FALSE; if (pOldBlock == NULL) { return ERROR_INVALID_PARAMETER; } ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1);
for ( i=0, pTocEntry = pOldBlock->TocEntry; i<pOldBlock->TocEntriesCount; i++, pTocEntry++) { newBlockSize += pTocEntry->InfoSize*pTocEntry->Count; if (pTocEntry->InfoType == InfoType) { LPBYTE pInfo = (LPBYTE)pOldBlock+pTocEntry->Offset;
ASSERT (pTocEntry->InfoSize == InfoSize); for (j=0; j<pTocEntry->Count; j++, pInfo+=InfoSize) { if ( InfoEqualCB != NULL ) { found = (BOOLEAN) (*InfoEqualCB) (pInfo, Info); } else { found = memcmp (pInfo, Info, InfoSize)==0; } if (found) { if (pTocEntry->Count==1) { entriesCount -= 1; newBlockSize -= sizeof (IPX_TOC_ENTRY); } break; } }
if (!found) { return ERROR_FILE_NOT_FOUND; } }
else { entriesCount += 1; newBlockSize += sizeof (IPX_TOC_ENTRY); } }
if (!found) { return ERROR_FILE_NOT_FOUND; }
for ( i=0, dstToc = pTocEntry = pOldBlock->TocEntry; i < pOldBlock->TocEntriesCount; i++, pTocEntry++) { if (pTocEntry->InfoType==InfoType) { if (pTocEntry->Count>1) { pTocEntry->Count -= 1; dstToc += 1; } } else { if (dstToc!=pTocEntry) { ASSERT (dstToc<pTocEntry); *dstToc = *pTocEntry; } dstToc += 1; } }
dstOffset = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER,TocEntry[entriesCount]); for (i=0, pTocEntry = pOldBlock->TocEntry; i<entriesCount; i++, pTocEntry++) { if (pTocEntry->InfoType==InfoType) { ULONG newInfoSize = InfoSize*j;
if ( j > 0 ) { if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((PUCHAR)pOldBlock+dstOffset, (PUCHAR)pOldBlock+pTocEntry->Offset, newInfoSize); } }
if ( j < pTocEntry->Count ) { memmove ((PUCHAR)pOldBlock+dstOffset+newInfoSize, (PUCHAR)pOldBlock+pTocEntry->Offset+newInfoSize+InfoSize, InfoSize*(pTocEntry->Count-j)); newInfoSize += InfoSize*(pTocEntry->Count-j); } pTocEntry->Offset = dstOffset; dstOffset += newInfoSize; } else { if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((PUCHAR)pOldBlock+dstOffset, (PUCHAR)pOldBlock+pTocEntry->Offset, pTocEntry->InfoSize*pTocEntry->Count); pTocEntry->Offset = dstOffset; } dstOffset += pTocEntry->InfoSize*pTocEntry->Count; } }
pOldBlock->Size = newBlockSize; pOldBlock->TocEntriesCount = entriesCount;
*pNewBlock = pOldBlock; return NO_ERROR; } DWORD UpdateIPXInfoEntry ( IN PIPX_INFO_BLOCK_HEADER pOldBlock, IN ULONG InfoType, IN ULONG InfoSize, IN PVOID OldInfo OPTIONAL, IN PVOID NewInfo, IN PINFO_CMP_PROC InfoEqualCB OPTIONAL, OUT PIPX_INFO_BLOCK_HEADER *pNewBlock ) { ULONG i, j, entriesCount = 1; PIPX_TOC_ENTRY pTocEntry; PIPX_INFO_BLOCK_HEADER pBlock; ULONG newBlockSize = InfoSize+sizeof (IPX_INFO_BLOCK_HEADER); BOOLEAN done = FALSE; DWORD rc;
ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1);
for ( i=0, pTocEntry = pOldBlock->TocEntry; i < pOldBlock->TocEntriesCount; i++, pTocEntry++) { if (pTocEntry->InfoType == InfoType) { LPBYTE pInfo = (LPBYTE)pOldBlock+pTocEntry->Offset; if (OldInfo!=NULL) { ASSERT (pTocEntry->InfoSize == InfoSize); for (j=0; j<pTocEntry->Count; j++, pInfo+=InfoSize) { BOOLEAN found;
if (InfoEqualCB!=NULL) { found = (BOOLEAN) (*InfoEqualCB) (pInfo, OldInfo); } else { found = memcmp (pInfo, OldInfo, InfoSize)==0; }
if (found) { memcpy (pInfo, NewInfo, InfoSize); *pNewBlock = pOldBlock; return NO_ERROR; } } } else { ASSERT (pTocEntry->Count==1);
if (pTocEntry->InfoSize==InfoSize) { memcpy (pInfo, NewInfo, InfoSize); *pNewBlock = pOldBlock; return NO_ERROR; }
newBlockSize -= pTocEntry->InfoSize+sizeof (IPX_INFO_BLOCK_HEADER); } } else { entriesCount += 1; newBlockSize += sizeof (IPX_TOC_ENTRY)+pTocEntry->InfoSize*pTocEntry->Count; } }
pBlock = (PIPX_INFO_BLOCK_HEADER)GlobalAlloc (GPTR, newBlockSize);
if ( pBlock != NULL ) { ULONG dstOffset = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER,TocEntry[entriesCount]); PIPX_TOC_ENTRY dstToc = pBlock->TocEntry;
pBlock->Version = IPX_ROUTER_VERSION_1; pBlock->Size = newBlockSize; pBlock->TocEntriesCount = entriesCount; for (i=0, pTocEntry = pOldBlock->TocEntry; i<pOldBlock->TocEntriesCount; i++, pTocEntry++) { *dstToc = *pTocEntry; dstToc->Offset = dstOffset;
if (dstToc->InfoType==InfoType) { if (pTocEntry->InfoSize==InfoSize) { memcpy ((PUCHAR)pBlock+dstOffset, (PUCHAR)pOldBlock+pTocEntry->Offset, pTocEntry->InfoSize*pTocEntry->Count);
dstOffset += dstToc->InfoSize*dstToc->Count;
memcpy ((PUCHAR)pBlock+dstOffset, NewInfo, InfoSize);
dstOffset += InfoSize; dstToc->Count += 1; } else { memcpy ((PUCHAR)pBlock+dstOffset, NewInfo, InfoSize); dstToc->InfoSize = InfoSize; dstOffset += InfoSize; } done = TRUE; } else { memcpy ((PUCHAR)pBlock+dstOffset, (PUCHAR)pOldBlock+pTocEntry->Offset, pTocEntry->InfoSize*pTocEntry->Count);
dstOffset += dstToc->InfoSize*dstToc->Count; } dstToc += 1; }
if (!done) { dstToc->InfoType = InfoType; dstToc->InfoSize = InfoSize; dstToc->Count = 1; dstToc->Offset = dstOffset; memcpy ((PUCHAR)pBlock+dstOffset, NewInfo, InfoSize); } *pNewBlock = pBlock; rc = NO_ERROR; } else { rc = ERROR_NOT_ENOUGH_MEMORY; } return rc; }
DWORD UpdateRipFilter ( IN PIPX_INFO_BLOCK_HEADER pOldBlock, IN BOOLEAN Output, IN PRIP_ROUTE_FILTER_INFO pOldFilter OPTIONAL, IN PRIP_ROUTE_FILTER_INFO pNewFilter OPTIONAL, OUT PIPX_INFO_BLOCK_HEADER *pNewBlock ) { ULONG i,j; PIPX_TOC_ENTRY pTocEntry, dstToc; PIPX_INFO_BLOCK_HEADER pBlock; ULONG newBlockSize = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER, TocEntry); BOOLEAN found = FALSE; PRIP_ROUTE_FILTER_INFO pRfInfo; ULONG supplyCount, listenCount, count, newCount; PRIP_IF_CONFIG pRipCfg; ULONG dstOffset;
ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1);
for (i=0, pTocEntry = pOldBlock->TocEntry; i<pOldBlock->TocEntriesCount; i++, pTocEntry++) { if (pTocEntry->InfoType == IPX_PROTOCOL_RIP) { found = TRUE; pRipCfg = (PRIP_IF_CONFIG)((LPBYTE)pOldBlock+pTocEntry->Offset); supplyCount = pRipCfg->RipIfFilters.SupplyFilterCount; listenCount = pRipCfg->RipIfFilters.ListenFilterCount;
if (Output) { pRfInfo = &pRipCfg->RipIfFilters.RouteFilter[0]; count = supplyCount; } else { pRfInfo = &pRipCfg->RipIfFilters.RouteFilter[ pRipCfg->RipIfFilters.SupplyFilterCount]; count = listenCount; } newCount = count;
if (ARGUMENT_PRESENT (pNewFilter)) { for (j=0; j<count; j++) { if (memcmp (&pRfInfo[j],pNewFilter,sizeof (*pNewFilter))==0) return ERROR_ALREADY_EXISTS; } newBlockSize += sizeof (*pNewFilter); newCount += 1; }
if (ARGUMENT_PRESENT (pOldFilter)) { for (j=0; j<count; j++) { if (memcmp (&pRfInfo[j],pOldFilter,sizeof (*pOldFilter))==0) break; } if (j>=count) return ERROR_FILE_NOT_FOUND; newBlockSize -= sizeof (*pNewFilter); newCount -= 1; } else j = count;
}
newBlockSize += sizeof (IPX_TOC_ENTRY)+pTocEntry->InfoSize*pTocEntry->Count; }
if (!found) return ERROR_FILE_NOT_FOUND;
if ((newBlockSize>pOldBlock->Size) || !ARGUMENT_PRESENT (pOldFilter)) { pBlock = (PIPX_INFO_BLOCK_HEADER)GlobalAlloc (GPTR, newBlockSize); if (pBlock==NULL) return ERROR_NOT_ENOUGH_MEMORY; pBlock->Version = IPX_ROUTER_VERSION_1; pBlock->TocEntriesCount = pOldBlock->TocEntriesCount; dstToc = pBlock->TocEntry; } else pBlock = pOldBlock;
dstOffset = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER, TocEntry[pBlock->TocEntriesCount]); for (i=0, pTocEntry = pOldBlock->TocEntry; i<pOldBlock->TocEntriesCount; i++, pTocEntry++, dstToc++) { if (pTocEntry->InfoType == IPX_PROTOCOL_RIP) { ULONG curOffset = FIELD_OFFSET (RIP_IF_CONFIG, RipIfFilters.RouteFilter); if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset, pRipCfg, curOffset); } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset, pRipCfg, curOffset); }
if (Output) { if (j>0) { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, pRfInfo, j*sizeof (pRfInfo[0])); } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, pRfInfo, j*sizeof (pRfInfo[0])); } curOffset += j*sizeof (pRfInfo[0]); } if (ARGUMENT_PRESENT (pNewFilter)) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, pNewFilter, sizeof (*pNewFilter)); curOffset += sizeof (*pNewFilter); }
if (ARGUMENT_PRESENT (pOldFilter)) j += 1;
if (j<count) { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, &pRfInfo[j], (count-j)*sizeof (pRfInfo[0])); } else if ((dstOffset!=pTocEntry->Offset) || !ARGUMENT_PRESENT (pNewFilter)) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, &pRfInfo[j], (count-j)*sizeof (pRfInfo[0])); } curOffset += (count-j)*sizeof (pRfInfo[0]); } if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, &pRipCfg->RipIfFilters.RouteFilter[supplyCount], listenCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0])); } else if ((dstOffset!=pTocEntry->Offset) || !ARGUMENT_PRESENT (pNewFilter)) { memmove ((LPBYTE)pBlock+dstOffset+curOffset, &pRipCfg->RipIfFilters.RouteFilter[supplyCount], listenCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0])); } curOffset += listenCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0]); ((PRIP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->RipIfFilters.SupplyFilterCount = newCount; if ((newCount==1) && (count==0)) ((PRIP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->RipIfFilters.SupplyFilterAction = IPX_ROUTE_FILTER_DENY;
} else { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, &pRipCfg->RipIfFilters.RouteFilter[0], supplyCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0])); } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, &pRipCfg->RipIfFilters.RouteFilter[0], supplyCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0])); } curOffset += supplyCount*sizeof (pRipCfg->RipIfFilters.RouteFilter[0]); if (j>0) { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, pRfInfo, j*sizeof (pRfInfo[0])); } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, pRfInfo, j*sizeof (pRfInfo[0])); } curOffset += j*sizeof (pRfInfo[0]); }
if (ARGUMENT_PRESENT (pNewFilter)) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, pNewFilter, sizeof (*pNewFilter)); curOffset += sizeof (*pNewFilter); }
if (ARGUMENT_PRESENT (pOldFilter)) j += 1;
if (j<count) { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, &pRfInfo[j], (count-j)*sizeof (pRfInfo[0])); } else if ((dstOffset!=pTocEntry->Offset) || !ARGUMENT_PRESENT (pNewFilter)) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, &pRfInfo[j], (count-j)*sizeof (pRfInfo[0])); } curOffset += (count-j)*sizeof (pRfInfo[0]); } ((PRIP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->RipIfFilters.ListenFilterCount = newCount; if ((newCount==1) && (count==0)) ((PRIP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->RipIfFilters.ListenFilterAction = IPX_ROUTE_FILTER_DENY; }
if (pBlock!=pOldBlock) { *dstToc = *pTocEntry; dstToc->Offset = dstOffset; dstToc->InfoSize = curOffset; } else { pTocEntry->Offset = dstOffset; pTocEntry->InfoSize = curOffset; }
dstOffset += curOffset; } else { if (pBlock!=pOldBlock) { memcpy ((PUCHAR)pBlock+dstOffset, (PUCHAR)pOldBlock+pTocEntry->Offset, pTocEntry->InfoSize*pTocEntry->Count); *dstToc = *pTocEntry; dstToc->Offset = dstOffset; } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((PUCHAR)pBlock+dstOffset, (PUCHAR)pOldBlock+pTocEntry->Offset, pTocEntry->InfoSize*pTocEntry->Count); pTocEntry->Offset = dstOffset; } dstOffset += pTocEntry->InfoSize*pTocEntry->Count; } }
pBlock->Size = newBlockSize; *pNewBlock = pBlock; return NO_ERROR; }
DWORD UpdateSapFilter ( IN PIPX_INFO_BLOCK_HEADER pOldBlock, IN BOOLEAN Output, IN PSAP_SERVICE_FILTER_INFO pOldFilter OPTIONAL, IN PSAP_SERVICE_FILTER_INFO pNewFilter OPTIONAL, OUT PIPX_INFO_BLOCK_HEADER *pNewBlock ) { ULONG i,j; PIPX_TOC_ENTRY pTocEntry, dstToc; PIPX_INFO_BLOCK_HEADER pBlock; ULONG newBlockSize = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER, TocEntry); BOOLEAN found = FALSE; PSAP_SERVICE_FILTER_INFO pSfInfo; ULONG supplyCount, listenCount, count, newCount; PSAP_IF_CONFIG pSapCfg; ULONG dstOffset;
ASSERT (pOldBlock->Version==IPX_ROUTER_VERSION_1);
for (i=0, pTocEntry = pOldBlock->TocEntry; i<pOldBlock->TocEntriesCount; i++, pTocEntry++) { if (pTocEntry->InfoType == IPX_PROTOCOL_SAP) { found = TRUE; pSapCfg = (PSAP_IF_CONFIG)((LPBYTE)pOldBlock+pTocEntry->Offset); supplyCount = pSapCfg->SapIfFilters.SupplyFilterCount; listenCount = pSapCfg->SapIfFilters.ListenFilterCount;
if (Output) { pSfInfo = &pSapCfg->SapIfFilters.ServiceFilter[0]; count = supplyCount; } else { pSfInfo = &pSapCfg->SapIfFilters.ServiceFilter[ pSapCfg->SapIfFilters.SupplyFilterCount]; count = listenCount; } newCount = count;
if (ARGUMENT_PRESENT (pNewFilter)) { for (j=0; j<count; j++) { if ((pSfInfo[j].ServiceType==pNewFilter->ServiceType) && (strncmp ((LPSTR)pSfInfo[j].ServiceName, (LPSTR)pNewFilter->ServiceName, sizeof (pNewFilter->ServiceName))==0)) break; } if (j<count) return ERROR_CAN_NOT_COMPLETE; newBlockSize += sizeof (*pNewFilter); newCount += 1; }
if (ARGUMENT_PRESENT (pOldFilter)) { for (j=0; j<count; j++) { if ((pSfInfo[j].ServiceType==pOldFilter->ServiceType) && (strncmp ((LPSTR)pSfInfo[j].ServiceName, (LPSTR)pOldFilter->ServiceName, sizeof (pOldFilter->ServiceName))==0)) break; } if (j>=count) return ERROR_CAN_NOT_COMPLETE; newBlockSize -= sizeof (*pNewFilter); newCount -= 1; } else j = count; }
newBlockSize += sizeof (IPX_TOC_ENTRY)+pTocEntry->InfoSize*pTocEntry->Count; }
if (!found) return ERROR_CAN_NOT_COMPLETE;
if ((newBlockSize>pOldBlock->Size) || !ARGUMENT_PRESENT (pOldFilter)) { pBlock = (PIPX_INFO_BLOCK_HEADER)GlobalAlloc (GPTR, newBlockSize); if (pBlock==NULL) return ERROR_NOT_ENOUGH_MEMORY; pBlock->Version = IPX_ROUTER_VERSION_1; pBlock->TocEntriesCount = pOldBlock->TocEntriesCount; dstToc = pBlock->TocEntry; } else pBlock = pOldBlock;
dstOffset = FIELD_OFFSET (IPX_INFO_BLOCK_HEADER, TocEntry[pBlock->TocEntriesCount]); for (i=0, pTocEntry = pOldBlock->TocEntry; i<pOldBlock->TocEntriesCount; i++, pTocEntry++, dstToc++) { if (pTocEntry->InfoType == IPX_PROTOCOL_SAP) { ULONG curOffset = FIELD_OFFSET (SAP_IF_CONFIG, SapIfFilters.ServiceFilter); if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset, pSapCfg, curOffset); } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset, pSapCfg, curOffset); }
if (Output) { if (j>0) { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, pSfInfo, j*sizeof (pSfInfo[0])); } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, pSfInfo, j*sizeof (pSfInfo[0])); } curOffset += j*sizeof (pSfInfo[0]); } if (ARGUMENT_PRESENT (pNewFilter)) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, pNewFilter, sizeof (*pNewFilter)); curOffset += sizeof (*pNewFilter); }
if (ARGUMENT_PRESENT (pOldFilter)) j += 1;
if (j<count) { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, &pSfInfo[j], (count-j)*sizeof (pSfInfo[0])); } else if ((dstOffset!=pTocEntry->Offset) || !ARGUMENT_PRESENT (pNewFilter)) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, &pSfInfo[j], (count-j)*sizeof (pSfInfo[0])); } curOffset += (count-j)*sizeof (pSfInfo[0]); } if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, &pSapCfg->SapIfFilters.ServiceFilter[supplyCount], listenCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0])); } else if ((dstOffset!=pTocEntry->Offset) || !ARGUMENT_PRESENT (pNewFilter)) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, &pSapCfg->SapIfFilters.ServiceFilter[supplyCount], listenCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0])); } curOffset += listenCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0]); ((PSAP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->SapIfFilters.SupplyFilterCount = newCount; if ((newCount==1) && (count==0)) ((PSAP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->SapIfFilters.SupplyFilterAction = IPX_SERVICE_FILTER_DENY; } else { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, &pSapCfg->SapIfFilters.ServiceFilter[0], supplyCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0])); } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, &pSapCfg->SapIfFilters.ServiceFilter[0], supplyCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0])); } curOffset += supplyCount*sizeof (pSapCfg->SapIfFilters.ServiceFilter[0]); if (j>0) { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, pSfInfo, j*sizeof (pSfInfo[0])); } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, pSfInfo, j*sizeof (pSfInfo[0])); } curOffset += j*sizeof (pSfInfo[0]); }
if (ARGUMENT_PRESENT (pNewFilter)) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, pNewFilter, sizeof (*pNewFilter)); curOffset += sizeof (*pNewFilter); }
if (ARGUMENT_PRESENT (pOldFilter)) j += 1;
if (j<count) { if (pBlock!=pOldBlock) { memcpy ((LPBYTE)pBlock+dstOffset+curOffset, &pSfInfo[j], (count-j)*sizeof (pSfInfo[0])); } else if ((dstOffset!=pTocEntry->Offset) || !ARGUMENT_PRESENT (pNewFilter)) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((LPBYTE)pBlock+dstOffset+curOffset, &pSfInfo[j], (count-j)*sizeof (pSfInfo[0])); } curOffset += (count-j)*sizeof (pSfInfo[0]); } ((PSAP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->SapIfFilters.ListenFilterCount = newCount; if ((newCount==1) && (count==0)) ((PSAP_IF_CONFIG)((LPBYTE)pBlock+dstOffset))->SapIfFilters.ListenFilterAction = IPX_SERVICE_FILTER_DENY; }
if (pBlock!=pOldBlock) { *dstToc = *pTocEntry; dstToc->Offset = dstOffset; dstToc->InfoSize = curOffset; } else { pTocEntry->Offset = dstOffset; pTocEntry->InfoSize = curOffset; }
dstOffset += curOffset; } else { if (pBlock!=pOldBlock) { memcpy ((PUCHAR)pBlock+dstOffset, (PUCHAR)pOldBlock+pTocEntry->Offset, pTocEntry->InfoSize*pTocEntry->Count); *dstToc = *pTocEntry; dstToc->Offset = dstOffset; } else if (dstOffset!=pTocEntry->Offset) { ASSERT (dstOffset<pTocEntry->Offset); memmove ((PUCHAR)pBlock+dstOffset, (PUCHAR)pOldBlock+pTocEntry->Offset, pTocEntry->InfoSize*pTocEntry->Count); pTocEntry->Offset = dstOffset; } dstOffset += pTocEntry->InfoSize*pTocEntry->Count; } }
pBlock->Size = newBlockSize; *pNewBlock = pBlock; return NO_ERROR; }
|