Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

432 lines
9.3 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. File contains the functions used to compare to MIB_XXXROW. They are passed
  6. as arguments to CRTs qsort(). They have to be of the form
  7. int __cdecl Compare(Elem1, Elem2)
  8. All these functions behave like strcmp. They return values are:
  9. < 0 if Row1 is less than Row2
  10. == 0 if Row1 is equal to Row2
  11. > 0 if Row1 is greater than Row2
  12. Revision History:
  13. Amritansh Raghav 6/8/95 Created
  14. --*/
  15. #include "inc.h"
  16. #pragma hdrstop
  17. #pragma warning(disable:4706)
  18. // The following structures are used to sort the output of GetIpAddrTable
  19. // and GetIfTable. The adapter order is specified under Tcpip\Linkage key
  20. // in the 'Bind' value as a list of device GUID values. The mapping from
  21. // this ordering to active interfaces is constructed by GetAdapterOrderMap
  22. // which fills an array with interface-indices in the order corresponding
  23. // to the adapter order.
  24. // Our comparison routines require this map for each comparison,
  25. // so we use a global variable to store the map before attempting to sort
  26. // on adapter order, and protect the map using the critical section 'g_ifLock'.
  27. // See 'CompareIfIndex' for the use of this map.
  28. extern PIP_ADAPTER_ORDER_MAP g_adapterOrderMap;
  29. int
  30. CompareIfIndex(
  31. ULONG index1,
  32. ULONG index2
  33. );
  34. int
  35. __cdecl
  36. CompareIfRow(
  37. CONST VOID *pvElem1,
  38. CONST VOID *pvElem2
  39. )
  40. {
  41. PMIB_IFROW pRow1 = (PMIB_IFROW)pvElem1;
  42. PMIB_IFROW pRow2 = (PMIB_IFROW)pvElem2;
  43. if(pRow1->dwIndex < pRow2->dwIndex)
  44. {
  45. return -1;
  46. }
  47. else
  48. {
  49. if(pRow1->dwIndex > pRow2->dwIndex)
  50. {
  51. return 1;
  52. }
  53. }
  54. return 0;
  55. }
  56. int
  57. __cdecl
  58. CompareIfRow2(
  59. CONST VOID *pvElem1,
  60. CONST VOID *pvElem2
  61. )
  62. {
  63. PMIB_IFROW pRow1 = (PMIB_IFROW)pvElem1;
  64. PMIB_IFROW pRow2 = (PMIB_IFROW)pvElem2;
  65. return CompareIfIndex(pRow1->dwIndex, pRow2->dwIndex);
  66. }
  67. int
  68. __cdecl
  69. CompareIpAddrRow(
  70. CONST VOID *pvElem1,
  71. CONST VOID *pvElem2
  72. )
  73. {
  74. int iRes;
  75. PMIB_IPADDRROW pRow1 = (PMIB_IPADDRROW)pvElem1;
  76. PMIB_IPADDRROW pRow2 = (PMIB_IPADDRROW)pvElem2;
  77. InetCmp(pRow1->dwAddr,
  78. pRow2->dwAddr,
  79. iRes);
  80. return iRes;
  81. }
  82. int
  83. __cdecl
  84. CompareIpAddrRow2(
  85. CONST VOID *pvElem1,
  86. CONST VOID *pvElem2
  87. )
  88. {
  89. PMIB_IPADDRROW pRow1 = (PMIB_IPADDRROW)pvElem1;
  90. PMIB_IPADDRROW pRow2 = (PMIB_IPADDRROW)pvElem2;
  91. return CompareIfIndex(pRow1->dwIndex, pRow2->dwIndex);
  92. }
  93. int
  94. __cdecl
  95. CompareTcpRow(
  96. CONST VOID *pvElem1,
  97. CONST VOID *pvElem2
  98. )
  99. {
  100. LONG lResult;
  101. PMIB_TCPROW pRow1 = (PMIB_TCPROW)pvElem1;
  102. PMIB_TCPROW pRow2 = (PMIB_TCPROW)pvElem2;
  103. if(InetCmp(pRow1->dwLocalAddr,
  104. pRow2->dwLocalAddr,
  105. lResult) isnot 0)
  106. {
  107. return lResult;
  108. }
  109. if(PortCmp(pRow1->dwLocalPort,
  110. pRow2->dwLocalPort,
  111. lResult) isnot 0)
  112. {
  113. return lResult;
  114. }
  115. if(InetCmp(pRow1->dwRemoteAddr,
  116. pRow2->dwRemoteAddr,
  117. lResult) isnot 0)
  118. {
  119. return lResult;
  120. }
  121. return PortCmp(pRow1->dwRemotePort,
  122. pRow2->dwRemotePort,
  123. lResult);
  124. }
  125. int
  126. __cdecl
  127. CompareTcp6Row(
  128. CONST VOID *pvElem1,
  129. CONST VOID *pvElem2
  130. )
  131. {
  132. LONG lResult;
  133. TCP6ConnTableEntry *pRow1 = (TCP6ConnTableEntry *)pvElem1;
  134. TCP6ConnTableEntry *pRow2 = (TCP6ConnTableEntry *)pvElem2;
  135. lResult = memcmp(&pRow1->tct_localaddr, &pRow2->tct_localaddr,
  136. sizeof(pRow1->tct_localaddr));
  137. if (lResult isnot 0)
  138. {
  139. return lResult;
  140. }
  141. if (pRow1->tct_localscopeid != pRow2->tct_localscopeid) {
  142. return pRow1->tct_localscopeid - pRow2->tct_localscopeid;
  143. }
  144. if(PortCmp(pRow1->tct_localport,
  145. pRow2->tct_localport,
  146. lResult) isnot 0)
  147. {
  148. return lResult;
  149. }
  150. lResult = memcmp(&pRow1->tct_remoteaddr, &pRow2->tct_remoteaddr,
  151. sizeof(pRow1->tct_remoteaddr));
  152. if (lResult isnot 0)
  153. {
  154. return lResult;
  155. }
  156. if (pRow1->tct_remotescopeid != pRow2->tct_remotescopeid) {
  157. return pRow1->tct_remotescopeid - pRow2->tct_remotescopeid;
  158. }
  159. return PortCmp(pRow1->tct_remoteport,
  160. pRow2->tct_remoteport,
  161. lResult);
  162. }
  163. int
  164. __cdecl
  165. CompareUdpRow(
  166. CONST VOID *pvElem1,
  167. CONST VOID *pvElem2
  168. )
  169. {
  170. LONG lResult;
  171. PMIB_UDPROW pRow1 = (PMIB_UDPROW)pvElem1;
  172. PMIB_UDPROW pRow2 = (PMIB_UDPROW)pvElem2;
  173. if(InetCmp(pRow1->dwLocalAddr,
  174. pRow2->dwLocalAddr,
  175. lResult) isnot 0)
  176. {
  177. return lResult;
  178. }
  179. return PortCmp(pRow1->dwLocalPort,
  180. pRow2->dwLocalPort,
  181. lResult);
  182. }
  183. int
  184. __cdecl
  185. CompareUdp6Row(
  186. CONST VOID *pvElem1,
  187. CONST VOID *pvElem2
  188. )
  189. {
  190. LONG lResult;
  191. UDP6ListenerEntry *pRow1 = (UDP6ListenerEntry *)pvElem1;
  192. UDP6ListenerEntry *pRow2 = (UDP6ListenerEntry *)pvElem2;
  193. lResult = memcmp(&pRow1->ule_localaddr, &pRow2->ule_localaddr,
  194. sizeof(pRow1->ule_localaddr));
  195. if (lResult isnot 0)
  196. {
  197. return lResult;
  198. }
  199. if (pRow1->ule_localscopeid != pRow2->ule_localscopeid)
  200. {
  201. return pRow1->ule_localscopeid - pRow2->ule_localscopeid;
  202. }
  203. return PortCmp(pRow1->ule_localport,
  204. pRow2->ule_localport,
  205. lResult);
  206. }
  207. int
  208. __cdecl
  209. CompareIpNetRow(
  210. CONST VOID *pvElem1,
  211. CONST VOID *pvElem2
  212. )
  213. {
  214. LONG lResult;
  215. PMIB_IPNETROW pRow1 = (PMIB_IPNETROW)pvElem1;
  216. PMIB_IPNETROW pRow2 = (PMIB_IPNETROW)pvElem2;
  217. if(Cmp(pRow1->dwIndex,
  218. pRow2->dwIndex,
  219. lResult) isnot 0)
  220. {
  221. return lResult;
  222. }
  223. return InetCmp(pRow1->dwAddr,
  224. pRow2->dwAddr,
  225. lResult);
  226. }
  227. int
  228. __cdecl
  229. CompareIpForwardRow(
  230. CONST VOID *pvElem1,
  231. CONST VOID *pvElem2
  232. )
  233. {
  234. LONG lResult;
  235. PMIB_IPFORWARDROW pRow1 = (PMIB_IPFORWARDROW)pvElem1;
  236. PMIB_IPFORWARDROW pRow2 = (PMIB_IPFORWARDROW)pvElem2;
  237. if(InetCmp(pRow1->dwForwardDest,
  238. pRow2->dwForwardDest,
  239. lResult) isnot 0)
  240. {
  241. return lResult;
  242. }
  243. if(Cmp(pRow1->dwForwardProto,
  244. pRow2->dwForwardProto,
  245. lResult) isnot 0)
  246. {
  247. return lResult;
  248. }
  249. if(Cmp(pRow1->dwForwardPolicy,
  250. pRow2->dwForwardPolicy,
  251. lResult) isnot 0)
  252. {
  253. return lResult;
  254. }
  255. return InetCmp(pRow1->dwForwardNextHop,
  256. pRow2->dwForwardNextHop,
  257. lResult);
  258. }
  259. int
  260. __cdecl
  261. NhiCompareIfInfoRow(
  262. CONST VOID *pvElem1,
  263. CONST VOID *pvElem2
  264. )
  265. {
  266. PIP_INTERFACE_NAME_INFO pRow1 = (PIP_INTERFACE_NAME_INFO)pvElem1;
  267. PIP_INTERFACE_NAME_INFO pRow2 = (PIP_INTERFACE_NAME_INFO)pvElem2;
  268. if(pRow1->Index < pRow2->Index)
  269. {
  270. return -1;
  271. }
  272. else
  273. {
  274. if(pRow1->Index > pRow2->Index)
  275. {
  276. return 1;
  277. }
  278. }
  279. return 0;
  280. }
  281. DWORD
  282. OpenTcpipKey(
  283. PHKEY Key
  284. )
  285. {
  286. DWORD dwResult;
  287. CHAR keyName[sizeof("SYSTEM\\CurrentControlSet\\Services\\Tcpip")];
  288. //
  289. // open the handle to this adapter's TCPIP parameter key
  290. //
  291. strcpy(keyName, "SYSTEM\\CurrentControlSet\\Services\\Tcpip");
  292. Trace1(ERR,"OpenTcpipKey: %s", keyName);
  293. dwResult = RegOpenKey(HKEY_LOCAL_MACHINE,
  294. keyName,
  295. Key);
  296. return dwResult;
  297. }
  298. PIP_INTERFACE_INFO
  299. GetAdapterNameAndIndexInfo(
  300. VOID
  301. )
  302. {
  303. PIP_INTERFACE_INFO pInfo;
  304. ULONG dwSize, dwError;
  305. dwSize = 0; pInfo = NULL;
  306. for (;;) {
  307. dwError = GetInterfaceInfo( pInfo, &dwSize );
  308. if( ERROR_INSUFFICIENT_BUFFER != dwError ) break;
  309. if( NULL != pInfo ) HeapFree(g_hPrivateHeap,0, pInfo);
  310. if( 0 == dwSize ) return NULL;
  311. pInfo = HeapAlloc(g_hPrivateHeap,0, dwSize);
  312. if( NULL == pInfo ) return NULL;
  313. }
  314. if( ERROR_SUCCESS != dwError || (pInfo && 0 == pInfo->NumAdapters) ) {
  315. if( NULL != pInfo ) HeapFree(g_hPrivateHeap,0, pInfo);
  316. return NULL;
  317. }
  318. return pInfo;
  319. }
  320. int
  321. CompareIfIndex(
  322. ULONG Index1,
  323. ULONG Index2
  324. )
  325. {
  326. ULONG i;
  327. #define MAXORDER (MAXLONG/2)
  328. ULONG Order1 = MAXORDER;
  329. ULONG Order2 = MAXORDER;
  330. // Determine the adapter-order for each interface-index,
  331. // using 'MAXLONG/2' as the default for unspecified indices
  332. // so that such interfaces all appear at the end of the array.
  333. // We then return an unsigned comparison of the resulting orders.
  334. for (i = 0; i < g_adapterOrderMap->NumAdapters; i++) {
  335. if (Index1 == g_adapterOrderMap->AdapterOrder[i]) {
  336. Order1 = i; if (Order2 != MAXORDER) { break; }
  337. }
  338. if (Index2 == g_adapterOrderMap->AdapterOrder[i]) {
  339. Order2 = i; if (Order1 != MAXORDER) { break; }
  340. }
  341. }
  342. return (ULONG)Order1 - (ULONG)Order2;
  343. }