Source code of Windows XP (NT5)
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.

906 lines
23 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. rpal.c
  5. Abstract:
  6. Routing protocols abstraction layer. It abstracts the RIP/SAP or NLSP routing
  7. protocols interface functions for the rest of the router manager system.
  8. Author:
  9. Stefan Solomon 04/24/1995
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. //
  15. // Service Table Manager Entry Points
  16. //
  17. PIS_SERVICE STM_IsService;
  18. PCREATE_SERVICE_ENUMERATION_HANDLE STM_CreateServiceEnumerationHandle;
  19. PENUMERATE_GET_NEXT_SERVICE STM_EnumerateGetNextService;
  20. PCLOSE_SERVICE_ENUMERATION_HANDLE STM_CloseServiceEnumerationHandle;
  21. PGET_SERVICE_COUNT STM_GetServiceCount;
  22. PCREATE_STATIC_SERVICE STM_CreateStaticService;
  23. PDELETE_STATIC_SERVICE STM_DeleteStaticService;
  24. PBLOCK_CONVERT_SERVICES_TO_STATIC STM_BlockConvertServicesToStatic;
  25. PBLOCK_DELETE_STATIC_SERVICES STM_BlockDeleteStaticServices;
  26. PGET_FIRST_ORDERED_SERVICE STM_GetFirstOrderedService;
  27. PGET_NEXT_ORDERED_SERVICE STM_GetNextOrderedService;
  28. //
  29. // Auto-Static Update Entry Points
  30. //
  31. ULONG UpdateRoutesProtId;
  32. PDO_UPDATE_ROUTES RP_UpdateRoutes;
  33. ULONG UpdateServicesProtId;
  34. PDO_UPDATE_SERVICES RP_UpdateServices;
  35. //
  36. // Router Manager Support Functions - Passed to routing protocols at Start
  37. //
  38. SUPPORT_FUNCTIONS RMSupportFunctions = {
  39. RoutingProtocolConnectionRequest,
  40. MibCreate,
  41. MibDelete,
  42. MibSet,
  43. MibGet,
  44. MibGetFirst,
  45. MibGetNext
  46. };
  47. //**************************************************************************
  48. // *
  49. // Routing Protocols Init/Start/Stop Functions *
  50. // *
  51. //**************************************************************************
  52. DWORD
  53. StartRoutingProtocols(LPVOID GlobalInfop,
  54. HANDLE RoutingProtocolsEvent)
  55. {
  56. DWORD rc, i, count, namelen, support;
  57. HINSTANCE moduleinstance;
  58. PRPCB rpcbp;
  59. LPVOID ProtocolGlobalInfop;
  60. PIPX_GLOBAL_INFO IpxGlobalInfop;
  61. MPR_PROTOCOL_0 *RtProtocolsp;
  62. DWORD NumRoutingProtocols;
  63. MPR_ROUTING_CHARACTERISTICS mrcRouting;
  64. MPR_SERVICE_CHARACTERISTICS mscService;
  65. // Initialize Routing Protocols List
  66. //
  67. InitializeListHead(&RoutingProtocolCBList);
  68. rc = MprSetupProtocolEnum (PID_IPX, (LPBYTE *)&RtProtocolsp, &NumRoutingProtocols);
  69. if (rc!=NO_ERROR) {
  70. Trace (RPAL_TRACE,
  71. "StartRoutingProtocols: failed to get routing protocol info: %d",
  72. rc);
  73. return ERROR_CAN_NOT_COMPLETE;
  74. }
  75. Trace (RPAL_TRACE, "StartRoutingProtocols: %d protocols installed.",
  76. NumRoutingProtocols);
  77. for (i=0; i<NumRoutingProtocols; i++) {
  78. if (GetInfoEntry(GlobalInfop, RtProtocolsp[i].dwProtocolId)==NULL)
  79. continue;
  80. // load library on the dll name provided
  81. //
  82. moduleinstance = LoadLibraryW (RtProtocolsp[i].wszDLLName) ;
  83. if (moduleinstance == NULL) {
  84. IF_LOG (EVENTLOG_ERROR_TYPE) {
  85. LPWSTR pname[1] = {RtProtocolsp[i].wszDLLName};
  86. RouterLogErrorW (RMEventLogHdl,
  87. ROUTERLOG_IPX_CANT_LOAD_PROTOCOL,
  88. 1, pname, rc);
  89. }
  90. Trace(RPAL_TRACE, "StartRoutingProtocols: %ls failed to load: %d\n", RtProtocolsp[i].wszDLLName, GetLastError());
  91. MprSetupProtocolFree (RtProtocolsp);
  92. return ERROR_CAN_NOT_COMPLETE;
  93. }
  94. namelen = sizeof(WCHAR) * (wcslen(RtProtocolsp[i].wszDLLName) + 1) ; // +1 for null character
  95. rpcbp = (PRPCB) GlobalAlloc (GPTR, sizeof(RPCB) + namelen) ;
  96. if (rpcbp == NULL) {
  97. FreeLibrary (moduleinstance) ;
  98. Trace(RPAL_TRACE, "StartRoutingProtocols: memory allocation failure\n");
  99. MprSetupProtocolFree (RtProtocolsp);
  100. return ERROR_CAN_NOT_COMPLETE;
  101. }
  102. ZeroMemory(rpcbp,
  103. sizeof(RPCB) + namelen);
  104. rpcbp->RP_DllName = (PWSTR)((PUCHAR)rpcbp + sizeof(RPCB));
  105. rpcbp->RP_DllHandle = moduleinstance;
  106. memcpy (rpcbp->RP_DllName, RtProtocolsp[i].wszDLLName, namelen) ;
  107. // Loading all entrypoints
  108. //
  109. rpcbp->RP_RegisterProtocol =
  110. (PREGISTER_PROTOCOL)GetProcAddress(moduleinstance,
  111. REGISTER_PROTOCOL_ENTRY_POINT_STRING)
  112. ;
  113. if(rpcbp->RP_RegisterProtocol == NULL)
  114. {
  115. //
  116. // Could not find the RegisterProtocol entry point
  117. // Nothing we can do - bail out
  118. //
  119. Sleep(0);
  120. MprSetupProtocolFree (RtProtocolsp);
  121. Trace(RPAL_TRACE, "StartRoutingProtocols: Could not find RegisterProtocol for %S",
  122. RtProtocolsp[i].wszDLLName);
  123. GlobalFree(rpcbp);
  124. FreeLibrary(moduleinstance);
  125. return ERROR_INVALID_FUNCTION;
  126. }
  127. ZeroMemory(&mrcRouting,
  128. sizeof(MPR_ROUTING_CHARACTERISTICS));
  129. ZeroMemory(&mscService,
  130. sizeof(MPR_SERVICE_CHARACTERISTICS));
  131. mrcRouting.dwVersion = MS_ROUTER_VERSION;
  132. mrcRouting.dwProtocolId = RtProtocolsp[i].dwProtocolId;
  133. mrcRouting.fSupportedFunctionality = ROUTING|DEMAND_UPDATE_ROUTES;
  134. mscService.dwVersion = MS_ROUTER_VERSION;
  135. mscService.dwProtocolId = RtProtocolsp[i].dwProtocolId;
  136. mscService.fSupportedFunctionality = SERVICES|DEMAND_UPDATE_SERVICES;
  137. rpcbp->RP_ProtocolId = RtProtocolsp[i].dwProtocolId;
  138. rc = rpcbp->RP_RegisterProtocol(&mrcRouting,
  139. &mscService);
  140. if(rc != NO_ERROR)
  141. {
  142. Sleep(0);
  143. IF_LOG (EVENTLOG_ERROR_TYPE) {
  144. CHAR num[8];
  145. LPSTR pnum[1] = {num};
  146. _ultoa (rpcbp->RP_ProtocolId, num, 16);
  147. RouterLogErrorA (RMEventLogHdl,
  148. ROUTERLOG_IPX_CANT_REGISTER_PROTOCOL,
  149. 1, pnum, rc);
  150. }
  151. FreeLibrary(moduleinstance);
  152. GlobalFree(rpcbp);
  153. Trace(RPAL_TRACE, "StartRoutingProtocols: %S returned error %d while registering",
  154. RtProtocolsp[i].wszDLLName,
  155. rc);
  156. MprSetupProtocolFree (RtProtocolsp);
  157. return rc;
  158. }
  159. rpcbp->RP_StartProtocol = mrcRouting.pfnStartProtocol;
  160. rpcbp->RP_StopProtocol = mrcRouting.pfnStopProtocol;
  161. rpcbp->RP_AddInterface = mrcRouting.pfnAddInterface;
  162. rpcbp->RP_DeleteInterface = mrcRouting.pfnDeleteInterface;
  163. rpcbp->RP_GetEventMessage = mrcRouting.pfnGetEventMessage;
  164. rpcbp->RP_GetIfConfigInfo = mrcRouting.pfnGetInterfaceInfo;
  165. rpcbp->RP_SetIfConfigInfo = mrcRouting.pfnSetInterfaceInfo;
  166. rpcbp->RP_BindInterface = mrcRouting.pfnBindInterface;
  167. rpcbp->RP_UnBindInterface = mrcRouting.pfnUnbindInterface;
  168. rpcbp->RP_EnableInterface = mrcRouting.pfnEnableInterface;
  169. rpcbp->RP_DisableInterface = mrcRouting.pfnDisableInterface;
  170. rpcbp->RP_GetGlobalInfo = mrcRouting.pfnGetGlobalInfo;
  171. rpcbp->RP_SetGlobalInfo = mrcRouting.pfnSetGlobalInfo;
  172. rpcbp->RP_MibCreate = mrcRouting.pfnMibCreateEntry;
  173. rpcbp->RP_MibDelete = mrcRouting.pfnMibDeleteEntry;
  174. rpcbp->RP_MibGet = mrcRouting.pfnMibGetEntry;
  175. rpcbp->RP_MibSet = mrcRouting.pfnMibSetEntry;
  176. rpcbp->RP_MibGetFirst = mrcRouting.pfnMibGetFirstEntry;
  177. rpcbp->RP_MibGetNext = mrcRouting.pfnMibGetNextEntry;
  178. if (!(rpcbp->RP_RegisterProtocol) ||
  179. !(rpcbp->RP_StartProtocol) ||
  180. !(rpcbp->RP_StopProtocol) ||
  181. !(rpcbp->RP_AddInterface) ||
  182. !(rpcbp->RP_DeleteInterface) ||
  183. !(rpcbp->RP_GetEventMessage) ||
  184. !(rpcbp->RP_GetIfConfigInfo) ||
  185. !(rpcbp->RP_SetIfConfigInfo) ||
  186. !(rpcbp->RP_BindInterface) ||
  187. !(rpcbp->RP_UnBindInterface) ||
  188. !(rpcbp->RP_EnableInterface) ||
  189. !(rpcbp->RP_DisableInterface) ||
  190. !(rpcbp->RP_GetGlobalInfo) ||
  191. !(rpcbp->RP_SetGlobalInfo) ||
  192. !(rpcbp->RP_MibCreate) ||
  193. !(rpcbp->RP_MibDelete) ||
  194. !(rpcbp->RP_MibSet) ||
  195. !(rpcbp->RP_MibGet) ||
  196. !(rpcbp->RP_MibGetFirst) ||
  197. !(rpcbp->RP_MibGetNext))
  198. {
  199. Trace(RPAL_TRACE, "StartRoutingProtocols: %ls failed to load entrypoints",
  200. RtProtocolsp[i].wszDLLName);
  201. GlobalFree(rpcbp);
  202. FreeLibrary (moduleinstance);
  203. MprSetupProtocolFree (RtProtocolsp);
  204. return ERROR_CAN_NOT_COMPLETE;
  205. }
  206. if(mscService.fSupportedFunctionality & SERVICES)
  207. {
  208. STM_IsService = mscService.pfnIsService;
  209. STM_CreateServiceEnumerationHandle = mscService.pfnCreateServiceEnumerationHandle;
  210. STM_EnumerateGetNextService = mscService.pfnEnumerateGetNextService;
  211. STM_CloseServiceEnumerationHandle = mscService.pfnCloseServiceEnumerationHandle;
  212. STM_GetServiceCount = mscService.pfnGetServiceCount;
  213. STM_CreateStaticService = mscService.pfnCreateStaticService;
  214. STM_DeleteStaticService = mscService.pfnDeleteStaticService;
  215. STM_BlockConvertServicesToStatic = mscService.pfnBlockConvertServicesToStatic;
  216. STM_BlockDeleteStaticServices = mscService.pfnBlockDeleteStaticServices;
  217. STM_GetFirstOrderedService = mscService.pfnGetFirstOrderedService;
  218. STM_GetNextOrderedService = mscService.pfnGetNextOrderedService;
  219. if(!(STM_IsService) ||
  220. !(STM_CreateServiceEnumerationHandle) ||
  221. !(STM_EnumerateGetNextService) ||
  222. !(STM_CloseServiceEnumerationHandle) ||
  223. !(STM_GetServiceCount) ||
  224. !(STM_CreateStaticService) ||
  225. !(STM_DeleteStaticService) ||
  226. !(STM_BlockConvertServicesToStatic) ||
  227. !(STM_BlockDeleteStaticServices) ||
  228. !(STM_GetFirstOrderedService) ||
  229. !(STM_GetNextOrderedService))
  230. {
  231. Trace(RPAL_TRACE, "StartRoutingProtocols: %ls failed to get STM entry points\n",
  232. RtProtocolsp[i].wszDLLName);
  233. GlobalFree(rpcbp);
  234. FreeLibrary (moduleinstance);
  235. MprSetupProtocolFree (RtProtocolsp);
  236. return ERROR_CAN_NOT_COMPLETE;
  237. }
  238. }
  239. if(mrcRouting.fSupportedFunctionality & DEMAND_UPDATE_ROUTES)
  240. {
  241. RP_UpdateRoutes = mrcRouting.pfnUpdateRoutes;
  242. if(!RP_UpdateRoutes)
  243. {
  244. Trace(RPAL_TRACE,
  245. "StartRoutingProtocols: %ls failed to get UpdateRoutes entry points\n",
  246. RtProtocolsp[i].wszDLLName);
  247. GlobalFree(rpcbp);
  248. FreeLibrary (moduleinstance);
  249. MprSetupProtocolFree (RtProtocolsp);
  250. return ERROR_CAN_NOT_COMPLETE;
  251. }
  252. UpdateRoutesProtId = rpcbp->RP_ProtocolId;
  253. }
  254. if(mscService.fSupportedFunctionality & DEMAND_UPDATE_SERVICES)
  255. {
  256. RP_UpdateServices = mscService.pfnUpdateServices;
  257. if(!RP_UpdateServices)
  258. {
  259. Trace(RPAL_TRACE,
  260. "StartRoutingProtocols: %ls failed to get UpdateServices entry points\n",
  261. RtProtocolsp[i].wszDLLName);
  262. GlobalFree(rpcbp);
  263. FreeLibrary (moduleinstance);
  264. MprSetupProtocolFree (RtProtocolsp);
  265. return ERROR_CAN_NOT_COMPLETE;
  266. }
  267. UpdateServicesProtId = rpcbp->RP_ProtocolId;
  268. }
  269. ProtocolGlobalInfop = GetInfoEntry(GlobalInfop, rpcbp->RP_ProtocolId);
  270. if ((rc = (*rpcbp->RP_StartProtocol)(RoutingProtocolsEvent,
  271. &RMSupportFunctions,
  272. ProtocolGlobalInfop)) != NO_ERROR) {
  273. IF_LOG (EVENTLOG_ERROR_TYPE) {
  274. CHAR num[8];
  275. LPSTR pnum[1] = {num};
  276. _ultoa (rpcbp->RP_ProtocolId, num, 16);
  277. RouterLogErrorA (RMEventLogHdl,
  278. ROUTERLOG_IPX_CANT_START_PROTOCOL,
  279. 1, pnum, rc);
  280. }
  281. Trace(RPAL_TRACE, "StartRoutingProtocols: %ls failed to start: %d\n",
  282. RtProtocolsp[i].wszDLLName, rc);
  283. GlobalFree(rpcbp);
  284. FreeLibrary (moduleinstance);
  285. MprSetupProtocolFree (RtProtocolsp);
  286. return ERROR_CAN_NOT_COMPLETE;
  287. }
  288. // Insert this routing protocol in the list of routing protocols
  289. //
  290. InsertTailList(&RoutingProtocolCBList, &rpcbp->RP_Linkage);
  291. RoutingProtocolActiveCount++;
  292. Trace(RPAL_TRACE, "StartRoutingProtocols: %ls successfully initialized",
  293. RtProtocolsp[i].wszDLLName);
  294. }
  295. if(!RP_UpdateRoutes || !RP_UpdateServices) {
  296. Trace(RPAL_TRACE, "StartRoutingProtocols: missing update entry point\n");
  297. MprSetupProtocolFree (RtProtocolsp);
  298. return ERROR_CAN_NOT_COMPLETE;
  299. }
  300. MprSetupProtocolFree (RtProtocolsp);
  301. Trace(RPAL_TRACE, "");
  302. return NO_ERROR;
  303. }
  304. VOID
  305. StopRoutingProtocols(VOID)
  306. {
  307. PLIST_ENTRY lep;
  308. PRPCB rpcbp;
  309. DWORD rc;
  310. lep = RoutingProtocolCBList.Flink;
  311. while(lep != &RoutingProtocolCBList) {
  312. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  313. (*rpcbp->RP_StopProtocol)();
  314. lep = lep->Flink;
  315. }
  316. }
  317. //**************************************************************************
  318. // *
  319. // Routing Protocols Interface Management Functions *
  320. // *
  321. //**************************************************************************
  322. DWORD
  323. CreateRoutingProtocolsInterfaces(PIPX_INFO_BLOCK_HEADER InterfaceInfop,
  324. PICB icbp)
  325. {
  326. PLIST_ENTRY lep;
  327. PRPCB rpcbp;
  328. LPVOID RpIfInfop;
  329. NET_INTERFACE_TYPE NetInterfaceType;
  330. DWORD rc;
  331. NetInterfaceType = MapIpxToNetInterfaceType(icbp);
  332. lep = RoutingProtocolCBList.Flink;
  333. while(lep != &RoutingProtocolCBList)
  334. {
  335. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  336. RpIfInfop = GetInfoEntry(InterfaceInfop, rpcbp->RP_ProtocolId);
  337. if(RpIfInfop == NULL) {
  338. return ERROR_CAN_NOT_COMPLETE;
  339. }
  340. rc = (*rpcbp->RP_AddInterface)(
  341. icbp->InterfaceNamep,
  342. icbp->InterfaceIndex,
  343. NetInterfaceType,
  344. RpIfInfop);
  345. if(rc != NO_ERROR) {
  346. return rc;
  347. }
  348. lep = lep->Flink;
  349. }
  350. return NO_ERROR;
  351. }
  352. DWORD
  353. DeleteRoutingProtocolsInterfaces(ULONG InterfaceIndex)
  354. {
  355. PLIST_ENTRY lep;
  356. PRPCB rpcbp;
  357. lep = RoutingProtocolCBList.Flink;
  358. while(lep != &RoutingProtocolCBList)
  359. {
  360. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  361. (*rpcbp->RP_DeleteInterface)(InterfaceIndex);
  362. lep = lep->Flink;
  363. }
  364. return NO_ERROR;
  365. }
  366. ULONG
  367. SizeOfRoutingProtocolsIfsInfo(ULONG InterfaceIndex)
  368. {
  369. PLIST_ENTRY lep;
  370. PRPCB rpcbp;
  371. ULONG TotalInfoSize = 0;
  372. ULONG RpIfInfoSize = 0;
  373. lep = RoutingProtocolCBList.Flink;
  374. while(lep != &RoutingProtocolCBList)
  375. {
  376. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  377. (*rpcbp->RP_GetIfConfigInfo)(InterfaceIndex, NULL, &RpIfInfoSize);
  378. // align size on double DWORD boundary - add two's complement for the last three bits
  379. RpIfInfoSize += ((~RpIfInfoSize) + 1) & 0x7;
  380. TotalInfoSize += RpIfInfoSize;
  381. RpIfInfoSize = 0;
  382. lep = lep->Flink;
  383. }
  384. return TotalInfoSize;
  385. }
  386. ULONG
  387. RoutingProtocolsTocCount(VOID)
  388. {
  389. return(RoutingProtocolActiveCount);
  390. }
  391. /*++
  392. Function: CreateRoutingProtocolsTocAndInfoEntries
  393. Descr: as it says
  394. Arguments: ibhp - ptr to the info block header
  395. InterfaceIndex
  396. current_tocepp - ptr to the location of the current TOC ptr; you have
  397. to increment this to get to the next TOC -> your TOC!
  398. current_NextInfoOffsetp - pointer to the location of the next info entry offset
  399. in the info block; you have to use this for your info
  400. entry and then to increment it for the next user.
  401. --*/
  402. DWORD
  403. CreateRoutingProtocolsTocAndInfoEntries(PIPX_INFO_BLOCK_HEADER ibhp,
  404. ULONG InterfaceIndex,
  405. PIPX_TOC_ENTRY *current_tocepp,
  406. PULONG current_NextInfoOffsetp)
  407. {
  408. PIPX_TOC_ENTRY tocep;
  409. ULONG NextInfoOffset;
  410. PLIST_ENTRY lep;
  411. PRPCB rpcbp;
  412. ULONG RpIfInfoSize;
  413. DWORD rc;
  414. lep = RoutingProtocolCBList.Flink;
  415. while(lep != &RoutingProtocolCBList)
  416. {
  417. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  418. // increment the current pointer to table of contents entries so it will
  419. // point to the next entry
  420. (*current_tocepp)++;
  421. tocep = *current_tocepp;
  422. // create the routing protocol and info toc entry
  423. tocep->InfoType = rpcbp->RP_ProtocolId;
  424. tocep->InfoSize = 0;
  425. tocep->Count = 1;
  426. tocep->Offset = *current_NextInfoOffsetp;
  427. rc = (*rpcbp->RP_GetIfConfigInfo)(InterfaceIndex,
  428. (LPVOID)((PUCHAR)ibhp + tocep->Offset),
  429. &tocep->InfoSize);
  430. if(rc != ERROR_INSUFFICIENT_BUFFER) {
  431. return rc;
  432. }
  433. rc = (*rpcbp->RP_GetIfConfigInfo)(InterfaceIndex,
  434. (LPVOID)((PUCHAR)ibhp + tocep->Offset),
  435. &tocep->InfoSize);
  436. if(rc != NO_ERROR) {
  437. return rc;
  438. }
  439. *current_NextInfoOffsetp += tocep->InfoSize;
  440. // align the next offset on DWORD boundary
  441. *current_NextInfoOffsetp += (~*current_NextInfoOffsetp + 1) & 0x7;
  442. lep = lep->Flink;
  443. }
  444. return NO_ERROR;
  445. }
  446. DWORD
  447. SetRoutingProtocolsInterfaces(PIPX_INFO_BLOCK_HEADER InterfaceInfop,
  448. ULONG InterfaceIndex)
  449. {
  450. PLIST_ENTRY lep;
  451. PRPCB rpcbp;
  452. LPVOID RpIfInfop;
  453. lep = RoutingProtocolCBList.Flink;
  454. while(lep != &RoutingProtocolCBList)
  455. {
  456. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  457. RpIfInfop = GetInfoEntry(InterfaceInfop, rpcbp->RP_ProtocolId);
  458. if(RpIfInfop == NULL) {
  459. return ERROR_CAN_NOT_COMPLETE;
  460. }
  461. (*rpcbp->RP_SetIfConfigInfo)(InterfaceIndex, RpIfInfop);
  462. lep = lep->Flink;
  463. }
  464. return NO_ERROR;
  465. }
  466. DWORD
  467. BindRoutingProtocolsIfsToAdapter(ULONG InterfaceIndex,
  468. PIPX_ADAPTER_BINDING_INFO abip)
  469. {
  470. PLIST_ENTRY lep;
  471. PRPCB rpcbp;
  472. lep = RoutingProtocolCBList.Flink;
  473. while(lep != &RoutingProtocolCBList)
  474. {
  475. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  476. (*rpcbp->RP_BindInterface)(InterfaceIndex, abip);
  477. lep = lep->Flink;
  478. }
  479. return NO_ERROR;
  480. }
  481. DWORD
  482. UnbindRoutingProtocolsIfsFromAdapter(ULONG InterfaceIndex)
  483. {
  484. PLIST_ENTRY lep;
  485. PRPCB rpcbp;
  486. lep = RoutingProtocolCBList.Flink;
  487. while(lep != &RoutingProtocolCBList)
  488. {
  489. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  490. (*rpcbp->RP_UnBindInterface)(InterfaceIndex);
  491. lep = lep->Flink;
  492. }
  493. return NO_ERROR;
  494. }
  495. DWORD
  496. RoutingProtocolsEnableIpxInterface(ULONG InterfaceIndex)
  497. {
  498. PLIST_ENTRY lep;
  499. PRPCB rpcbp;
  500. lep = RoutingProtocolCBList.Flink;
  501. while(lep != &RoutingProtocolCBList)
  502. {
  503. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  504. (*rpcbp->RP_EnableInterface)(InterfaceIndex);
  505. lep = lep->Flink;
  506. }
  507. return NO_ERROR;
  508. }
  509. DWORD
  510. RoutingProtocolsDisableIpxInterface(ULONG InterfaceIndex)
  511. {
  512. PLIST_ENTRY lep;
  513. PRPCB rpcbp;
  514. lep = RoutingProtocolCBList.Flink;
  515. while(lep != &RoutingProtocolCBList)
  516. {
  517. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  518. (*rpcbp->RP_DisableInterface)(InterfaceIndex);
  519. lep = lep->Flink;
  520. }
  521. return NO_ERROR;
  522. }
  523. //**************************************************************************
  524. // *
  525. // Routing Protocols Services Management Functions *
  526. // *
  527. //**************************************************************************
  528. DWORD
  529. GetFirstService(DWORD OrderingMethod,
  530. DWORD ExclusionFlags,
  531. PIPX_SERVICE Servicep)
  532. {
  533. return(*STM_GetFirstOrderedService)(OrderingMethod, ExclusionFlags, Servicep);
  534. }
  535. DWORD
  536. GetNextService(DWORD OrderingMethod,
  537. DWORD ExclusionFlags,
  538. PIPX_SERVICE Servicep)
  539. {
  540. return(*STM_GetNextOrderedService)(OrderingMethod, ExclusionFlags, Servicep);
  541. }
  542. DWORD
  543. CreateStaticService(PICB icbp,
  544. PIPX_STATIC_SERVICE_INFO ServiceEntry)
  545. {
  546. DWORD rc;
  547. rc = (*STM_CreateStaticService)(icbp->InterfaceIndex, ServiceEntry);
  548. return rc;
  549. }
  550. DWORD
  551. DeleteStaticService(ULONG InterfaceIndex,
  552. PIPX_STATIC_SERVICE_INFO ServiceEntry)
  553. {
  554. DWORD rc;
  555. rc = (*STM_DeleteStaticService)(InterfaceIndex, ServiceEntry);
  556. return rc;
  557. }
  558. HANDLE
  559. CreateStaticServicesEnumHandle(ULONG InterfaceIndex)
  560. {
  561. IPX_SERVICE CriteriaService;
  562. HANDLE EnumHandle;
  563. if(STM_CreateServiceEnumerationHandle == NULL) {
  564. return NULL;
  565. }
  566. memset(&CriteriaService, 0, sizeof(IPX_SERVICE));
  567. CriteriaService.InterfaceIndex = InterfaceIndex;
  568. CriteriaService.Protocol = IPX_PROTOCOL_STATIC;
  569. EnumHandle = (*STM_CreateServiceEnumerationHandle)(
  570. STM_ONLY_THIS_INTERFACE | STM_ONLY_THIS_PROTOCOL,
  571. &CriteriaService);
  572. return EnumHandle;
  573. }
  574. DWORD
  575. GetNextStaticService(HANDLE EnumHandle,
  576. PIPX_STATIC_SERVICE_INFO StaticSvInfop)
  577. {
  578. IPX_SERVICE Service;
  579. DWORD rc;
  580. if((rc = (*STM_EnumerateGetNextService)(EnumHandle,
  581. &Service)) == NO_ERROR) {
  582. // fill in the static service structure
  583. *StaticSvInfop = Service.Server;
  584. }
  585. return rc;
  586. }
  587. DWORD
  588. CloseStaticServicesEnumHandle(HANDLE EnumHandle)
  589. {
  590. DWORD rc = NO_ERROR;
  591. if(EnumHandle) {
  592. rc = (*STM_CloseServiceEnumerationHandle)(EnumHandle);
  593. }
  594. return rc;
  595. }
  596. DWORD
  597. DeleteAllStaticServices(ULONG InterfaceIndex)
  598. {
  599. if(!STM_BlockDeleteStaticServices) {
  600. return NO_ERROR;
  601. }
  602. return((*STM_BlockDeleteStaticServices)(InterfaceIndex));
  603. }
  604. DWORD
  605. GetServiceCount(VOID)
  606. {
  607. if(!STM_GetServiceCount) {
  608. return 0;
  609. }
  610. return((*STM_GetServiceCount)());
  611. }
  612. //**************************************************************************
  613. // *
  614. // Routing Protocols Auto-Static Update Functions *
  615. // *
  616. //**************************************************************************
  617. DWORD
  618. RtProtRequestRoutesUpdate(ULONG InterfaceIndex)
  619. {
  620. return((*RP_UpdateRoutes)(InterfaceIndex));
  621. }
  622. DWORD
  623. RtProtRequestServicesUpdate(ULONG InterfaceIndex)
  624. {
  625. return((*RP_UpdateServices)(InterfaceIndex));
  626. }
  627. VOID
  628. DestroyRoutingProtocolCB(PRPCB rpcbp)
  629. {
  630. RemoveEntryList(&rpcbp->RP_Linkage);
  631. FreeLibrary (rpcbp->RP_DllHandle);
  632. GlobalFree(rpcbp);
  633. RoutingProtocolActiveCount--;
  634. }
  635. VOID
  636. ConvertAllServicesToStatic(ULONG InterfaceIndex)
  637. {
  638. STM_BlockConvertServicesToStatic(InterfaceIndex);
  639. }
  640. DWORD
  641. GetStaticServicesCount(ULONG InterfaceIndex)
  642. {
  643. HANDLE EnumHandle;
  644. DWORD Count;
  645. IPX_STATIC_SERVICE_INFO StaticSvInfo;
  646. EnumHandle = CreateStaticServicesEnumHandle(InterfaceIndex);
  647. if(EnumHandle == NULL) {
  648. return 0;
  649. }
  650. Count = 0;
  651. while(GetNextStaticService(EnumHandle, &StaticSvInfo) == NO_ERROR) {
  652. Count++;
  653. }
  654. CloseStaticServicesEnumHandle(EnumHandle);
  655. return Count;
  656. }
  657. PRPCB
  658. GetRoutingProtocolCB(DWORD ProtocolId)
  659. {
  660. PRPCB rpcbp;
  661. PLIST_ENTRY lep;
  662. lep = RoutingProtocolCBList.Flink;
  663. while(lep != &RoutingProtocolCBList)
  664. {
  665. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  666. if(rpcbp->RP_ProtocolId == ProtocolId) {
  667. return rpcbp;
  668. }
  669. lep = lep->Flink;
  670. }
  671. return NULL;
  672. }
  673. BOOL
  674. IsService(USHORT SvType,
  675. PUCHAR SvName,
  676. PIPX_SERVICE Svp)
  677. {
  678. return(STM_IsService(SvType, SvName, Svp));
  679. }
  680. DWORD
  681. SetRoutingProtocolsGlobalInfo(PIPX_INFO_BLOCK_HEADER GlobalInfop)
  682. {
  683. PLIST_ENTRY lep;
  684. PRPCB rpcbp;
  685. LPVOID RpGlobalInfop;
  686. lep = RoutingProtocolCBList.Flink;
  687. while(lep != &RoutingProtocolCBList)
  688. {
  689. rpcbp = CONTAINING_RECORD(lep, RPCB, RP_Linkage);
  690. RpGlobalInfop = GetInfoEntry(GlobalInfop, rpcbp->RP_ProtocolId);
  691. if(RpGlobalInfop == NULL) {
  692. return NO_ERROR;
  693. }
  694. (*rpcbp->RP_SetGlobalInfo)(RpGlobalInfop);
  695. lep = lep->Flink;
  696. }
  697. return NO_ERROR;
  698. }