windows-nt/Source/XPSP1/NT/net/tcpip/apis/iphlpapi/dll/compare.c
2020-09-26 16:20:57 +08:00

434 lines
8.9 KiB
C

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
Abstract:
File contains the functions used to compare to MIB_XXXROW. They are passed
as arguments to CRTs qsort(). They have to be of the form
int __cdecl Compare(Elem1, Elem2)
All these functions behave like strcmp. They return values are:
< 0 if Row1 is less than Row2
== 0 if Row1 is equal to Row2
> 0 if Row1 is greater than Row2
Revision History:
Amritansh Raghav 6/8/95 Created
--*/
#include "inc.h"
#pragma hdrstop
// The following structures are used to sort the output of GetIpAddrTable
// and GetIfTable. The adapter order is specified under Tcpip\Linkage key
// in the 'Bind' value as a list of device GUID values. The mapping from
// this ordering to active interfaces is constructed by GetAdapterOrderMap
// which fills an array with interface-indices in the order corresponding
// to the adapter order.
// Our comparison routines require this map for each comparison,
// so we use a global variable to store the map before attempting to sort
// on adapter order, and protect the map using the critical section 'g_ifLock'.
// See 'CompareIfIndex' for the use of this map.
extern PIP_ADAPTER_ORDER_MAP g_adapterOrderMap;
int
CompareIfIndex(
ULONG index1,
ULONG index2
);
int
__cdecl
CompareIfRow(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
PMIB_IFROW pRow1 = (PMIB_IFROW)pvElem1;
PMIB_IFROW pRow2 = (PMIB_IFROW)pvElem2;
if(pRow1->dwIndex < pRow2->dwIndex)
{
return -1;
}
else
{
if(pRow1->dwIndex > pRow2->dwIndex)
{
return 1;
}
}
return 0;
}
int
__cdecl
CompareIfRow2(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
PMIB_IFROW pRow1 = (PMIB_IFROW)pvElem1;
PMIB_IFROW pRow2 = (PMIB_IFROW)pvElem2;
return CompareIfIndex(pRow1->dwIndex, pRow2->dwIndex);
}
int
__cdecl
CompareIpAddrRow(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
int iRes;
PMIB_IPADDRROW pRow1 = (PMIB_IPADDRROW)pvElem1;
PMIB_IPADDRROW pRow2 = (PMIB_IPADDRROW)pvElem2;
InetCmp(pRow1->dwAddr,
pRow2->dwAddr,
iRes);
return iRes;
}
int
__cdecl
CompareIpAddrRow2(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
int iRes;
PMIB_IPADDRROW pRow1 = (PMIB_IPADDRROW)pvElem1;
PMIB_IPADDRROW pRow2 = (PMIB_IPADDRROW)pvElem2;
return CompareIfIndex(pRow1->dwIndex, pRow2->dwIndex);
}
int
__cdecl
CompareTcpRow(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
LONG lResult;
PMIB_TCPROW pRow1 = (PMIB_TCPROW)pvElem1;
PMIB_TCPROW pRow2 = (PMIB_TCPROW)pvElem2;
if(InetCmp(pRow1->dwLocalAddr,
pRow2->dwLocalAddr,
lResult) isnot 0)
{
return lResult;
}
if(PortCmp(pRow1->dwLocalPort,
pRow2->dwLocalPort,
lResult) isnot 0)
{
return lResult;
}
if(InetCmp(pRow1->dwRemoteAddr,
pRow2->dwRemoteAddr,
lResult) isnot 0)
{
return lResult;
}
return PortCmp(pRow1->dwRemotePort,
pRow2->dwRemotePort,
lResult);
}
int
__cdecl
CompareTcp6Row(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
LONG lResult;
TCP6ConnTableEntry *pRow1 = (TCP6ConnTableEntry *)pvElem1;
TCP6ConnTableEntry *pRow2 = (TCP6ConnTableEntry *)pvElem2;
lResult = memcmp(&pRow1->tct_localaddr, &pRow2->tct_localaddr,
sizeof(pRow1->tct_localaddr));
if (lResult isnot 0)
{
return lResult;
}
if (pRow1->tct_localscopeid != pRow2->tct_localscopeid) {
return pRow1->tct_localscopeid - pRow2->tct_localscopeid;
}
if(PortCmp(pRow1->tct_localport,
pRow2->tct_localport,
lResult) isnot 0)
{
return lResult;
}
lResult = memcmp(&pRow1->tct_remoteaddr, &pRow2->tct_remoteaddr,
sizeof(pRow1->tct_remoteaddr));
if (lResult isnot 0)
{
return lResult;
}
if (pRow1->tct_remotescopeid != pRow2->tct_remotescopeid) {
return pRow1->tct_remotescopeid - pRow2->tct_remotescopeid;
}
return PortCmp(pRow1->tct_remoteport,
pRow2->tct_remoteport,
lResult);
}
int
__cdecl
CompareUdpRow(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
LONG lResult;
PMIB_UDPROW pRow1 = (PMIB_UDPROW)pvElem1;
PMIB_UDPROW pRow2 = (PMIB_UDPROW)pvElem2;
if(InetCmp(pRow1->dwLocalAddr,
pRow2->dwLocalAddr,
lResult) isnot 0)
{
return lResult;
}
return PortCmp(pRow1->dwLocalPort,
pRow2->dwLocalPort,
lResult);
}
int
__cdecl
CompareUdp6Row(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
LONG lResult;
UDP6ListenerEntry *pRow1 = (UDP6ListenerEntry *)pvElem1;
UDP6ListenerEntry *pRow2 = (UDP6ListenerEntry *)pvElem2;
lResult = memcmp(&pRow1->ule_localaddr, &pRow2->ule_localaddr,
sizeof(pRow1->ule_localaddr));
if (lResult isnot 0)
{
return lResult;
}
if (pRow1->ule_localscopeid != pRow2->ule_localscopeid)
{
return pRow1->ule_localscopeid - pRow2->ule_localscopeid;
}
return PortCmp(pRow1->ule_localport,
pRow2->ule_localport,
lResult);
}
int
__cdecl
CompareIpNetRow(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
LONG lResult;
PMIB_IPNETROW pRow1 = (PMIB_IPNETROW)pvElem1;
PMIB_IPNETROW pRow2 = (PMIB_IPNETROW)pvElem2;
if(Cmp(pRow1->dwIndex,
pRow2->dwIndex,
lResult) isnot 0)
{
return lResult;
}
return InetCmp(pRow1->dwAddr,
pRow2->dwAddr,
lResult);
}
int
__cdecl
CompareIpForwardRow(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
LONG lResult;
PMIB_IPFORWARDROW pRow1 = (PMIB_IPFORWARDROW)pvElem1;
PMIB_IPFORWARDROW pRow2 = (PMIB_IPFORWARDROW)pvElem2;
if(InetCmp(pRow1->dwForwardDest,
pRow2->dwForwardDest,
lResult) isnot 0)
{
return lResult;
}
if(Cmp(pRow1->dwForwardProto,
pRow2->dwForwardProto,
lResult) isnot 0)
{
return lResult;
}
if(Cmp(pRow1->dwForwardPolicy,
pRow2->dwForwardPolicy,
lResult) isnot 0)
{
return lResult;
}
return InetCmp(pRow1->dwForwardNextHop,
pRow2->dwForwardNextHop,
lResult);
}
int
__cdecl
NhiCompareIfInfoRow(
CONST VOID *pvElem1,
CONST VOID *pvElem2
)
{
PIP_INTERFACE_NAME_INFO pRow1 = (PIP_INTERFACE_NAME_INFO)pvElem1;
PIP_INTERFACE_NAME_INFO pRow2 = (PIP_INTERFACE_NAME_INFO)pvElem2;
if(pRow1->Index < pRow2->Index)
{
return -1;
}
else
{
if(pRow1->Index > pRow2->Index)
{
return 1;
}
}
return 0;
}
DWORD
OpenTcpipKey(
PHKEY Key
)
{
DWORD dwResult;
CHAR keyName[sizeof("SYSTEM\\CurrentControlSet\\Services\\Tcpip")];
//
// open the handle to this adapter's TCPIP parameter key
//
strcpy(keyName, "SYSTEM\\CurrentControlSet\\Services\\Tcpip");
Trace1(ERR,"OpenTcpipKey: %s", keyName);
dwResult = RegOpenKey(HKEY_LOCAL_MACHINE,
keyName,
Key);
return dwResult;
}
PIP_INTERFACE_INFO
GetAdapterNameAndIndexInfo(
VOID
)
{
PIP_INTERFACE_INFO pInfo;
ULONG dwSize, dwError;
dwSize = 0; pInfo = NULL;
while( 1 ) {
dwError = GetInterfaceInfo( pInfo, &dwSize );
if( ERROR_INSUFFICIENT_BUFFER != dwError ) break;
if( NULL != pInfo ) HeapFree(g_hPrivateHeap,0, pInfo);
if( 0 == dwSize ) return NULL;
pInfo = HeapAlloc(g_hPrivateHeap,0, dwSize);
if( NULL == pInfo ) return NULL;
}
if( ERROR_SUCCESS != dwError || (pInfo && 0 == pInfo->NumAdapters) ) {
if( NULL != pInfo ) HeapFree(g_hPrivateHeap,0, pInfo);
return NULL;
}
return pInfo;
}
int
CompareIfIndex(
ULONG Index1,
ULONG Index2
)
{
ULONG i;
#define MAXORDER (MAXLONG/2)
ULONG Order1 = MAXORDER;
ULONG Order2 = MAXORDER;
// Determine the adapter-order for each interface-index,
// using 'MAXLONG/2' as the default for unspecified indices
// so that such interfaces all appear at the end of the array.
// We then return an unsigned comparison of the resulting orders.
for (i = 0; i < g_adapterOrderMap->NumAdapters; i++) {
if (Index1 == g_adapterOrderMap->AdapterOrder[i]) {
Order1 = i; if (Order2 != MAXORDER) { break; }
}
if (Index2 == g_adapterOrderMap->AdapterOrder[i]) {
Order2 = i; if (Order1 != MAXORDER) { break; }
}
}
return (ULONG)Order1 - (ULONG)Order2;
}