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.

1698 lines
45 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\routing\ipx\sap\routerif.c
  5. Abstract:
  6. SAP interface with router (APIs for protocol dll under
  7. NT/Cairo router, SNMP MIB support, IPX Service Table Manager)
  8. Author:
  9. Vadim Eydelman 05-15-1995
  10. Revision History:
  11. --*/
  12. #include "sapp.h"
  13. DWORD (WINAPI *MIBEntryGet)(
  14. IN DWORD dwRoutingPid,
  15. IN DWORD dwInEntrySize,
  16. IN LPVOID lpInEntry,
  17. IN OUT LPDWORD lpOutEntrySize,
  18. OUT LPVOID lpOutEntry);
  19. /*++
  20. *******************************************************************
  21. S T A R T _ P R O T O C O L _ E N T R Y _ P O I N T
  22. Routine Description:
  23. Starts sap agent
  24. Arguments:
  25. NotificationEvent - this event will be used to notify router manager
  26. of completion of lengthly operation
  27. GlobalInfo - empty
  28. Return Value:
  29. NO_ERROR - SAP agent was started OK
  30. ERROR_CAN_NOT_COMPLETE - operation can not be completed
  31. ERROR_INVALID_PARAMETER - one or more parameters are invalid
  32. *******************************************************************
  33. --*/
  34. DWORD WINAPI
  35. StartProtocol(
  36. IN HANDLE NotificationEvent,
  37. IN PSUPPORT_FUNCTIONS SupportFunctions,
  38. IN LPVOID GlobalInfo
  39. ) {
  40. #define sapGlobalInfo ((PSAP_GLOBAL_INFO)GlobalInfo)
  41. DWORD status;
  42. EnterCriticalSection (&OperationalStateLock);
  43. if (!RouterIfActive) {
  44. RouterIfActive = TRUE;
  45. EventLogMask = sapGlobalInfo->EventLogMask;
  46. status = CreateResultQueue (NotificationEvent);
  47. if (status==NO_ERROR) {
  48. if (!ServiceIfActive) {
  49. status = CreateAllComponents (NotificationEvent);
  50. if (status==NO_ERROR) {
  51. status = StartSAP ();
  52. if (status==NO_ERROR) {
  53. MIBEntryGet = SupportFunctions->MIBEntryGet;
  54. status = NO_ERROR;
  55. goto Success;
  56. }
  57. DeleteAllComponents ();
  58. }
  59. }
  60. else {
  61. StopInterfaces ();
  62. StopSAP ();
  63. MIBEntryGet = SupportFunctions->MIBEntryGet;
  64. goto Success;
  65. }
  66. }
  67. else
  68. status = ERROR_CAN_NOT_COMPLETE;
  69. RouterIfActive = FALSE;
  70. }
  71. else {
  72. Trace (DEBUG_FAILURES, "File: %s, line %ld."
  73. " SAP is already running.",
  74. __FILE__, __LINE__);
  75. status = ERROR_CAN_NOT_COMPLETE;
  76. }
  77. Success:
  78. LeaveCriticalSection (&OperationalStateLock);
  79. return status;
  80. #undef sapGlobalInfo
  81. }
  82. /*++
  83. *******************************************************************
  84. G E T _ G L O B A L _ I N F O _ E N T R Y _ P O I N T
  85. Routine Description:
  86. Gets SAP global filter info
  87. Arguments:
  88. GlobalInfo - buffer to receive global info
  89. GlobalInfoSize - on input: size of the buffer
  90. on output: size of global info or size of the
  91. required buffer if ERROR_INSUFFICIENT_BUFFER
  92. is returned
  93. Return Value:
  94. NO_ERROR
  95. ERROR_CAN_NOT_COMPLETE
  96. ERROR_INVALID_PARAMETER
  97. ERROR_INSUFFICIENT_BUFFER
  98. *******************************************************************
  99. --*/
  100. DWORD WINAPI
  101. GetGlobalInfo(
  102. IN PVOID GlobalInfo,
  103. IN OUT PULONG GlobalInfoSize
  104. ) {
  105. DWORD status;
  106. EnterCriticalSection (&OperationalStateLock);
  107. if (OperationalState==OPER_STATE_UP) {
  108. if ((*GlobalInfoSize>=sizeof (SAP_GLOBAL_INFO))
  109. && (GlobalInfo!=NULL)) {
  110. #define sapGlobalInfo ((PSAP_GLOBAL_INFO)GlobalInfo)
  111. sapGlobalInfo->EventLogMask = EventLogMask;
  112. #undef sapGlobalInfo
  113. }
  114. *GlobalInfoSize = sizeof (SAP_GLOBAL_INFO);
  115. status = NO_ERROR;
  116. }
  117. else
  118. status = ERROR_CAN_NOT_COMPLETE;
  119. LeaveCriticalSection (&OperationalStateLock);
  120. return status;
  121. }
  122. /*++
  123. *******************************************************************
  124. S E T _ G L O B A L _ I N F O _ E N T R Y _ P O I N T
  125. Routine Description:
  126. Sets SAP global filter info
  127. Arguments:
  128. GlobalInfo - buffer with receive global info
  129. Return Value:
  130. NO_ERROR
  131. ERROR_CAN_NOT_COMPLETE
  132. ERROR_INVALID_PARAMETER
  133. *******************************************************************
  134. --*/
  135. DWORD WINAPI
  136. SetGlobalInfo(
  137. IN PVOID GlobalInfo
  138. ) {
  139. #define sapGlobalInfo ((PSAP_GLOBAL_INFO)GlobalInfo)
  140. DWORD status;
  141. EnterCriticalSection (&OperationalStateLock);
  142. if (OperationalState==OPER_STATE_UP) {
  143. EventLogMask = sapGlobalInfo->EventLogMask;
  144. status = NO_ERROR;
  145. }
  146. else
  147. status = ERROR_CAN_NOT_COMPLETE;
  148. LeaveCriticalSection (&OperationalStateLock);
  149. return status;
  150. #undef sapGlobalInfo
  151. }
  152. /*++
  153. *******************************************************************
  154. S T O P _ P R O T O C O L _ E N T R Y _ P O I N T
  155. Routine Description:
  156. Shutdown SAP agent
  157. Arguments:
  158. None
  159. Return Value:
  160. NO_ERROR - SAP agent was stopped OK
  161. ERROR_STOP_PENDING - for asynchronous completion.
  162. *******************************************************************
  163. --*/
  164. DWORD WINAPI
  165. StopProtocol(
  166. void
  167. ) {
  168. DWORD status;
  169. EnterCriticalSection (&OperationalStateLock);
  170. if (OperationalState==OPER_STATE_STOPPING) {
  171. Trace (DEBUG_FAILURES, "File: %s, line %ld."
  172. " SAP is stopping already.",
  173. __FILE__, __LINE__);
  174. status = ERROR_PROTOCOL_STOP_PENDING;
  175. }
  176. else if (OperationalState==OPER_STATE_DOWN) {
  177. Trace (DEBUG_FAILURES, "File: %s, line %ld."
  178. " SAP already stopped or not started.",
  179. __FILE__, __LINE__);
  180. status = NO_ERROR;
  181. }
  182. else if (!RouterIfActive) {
  183. Trace (DEBUG_FAILURES, "File: %s, line %ld."
  184. " Router interface is not active.",
  185. __FILE__, __LINE__);
  186. status = ERROR_CAN_NOT_COMPLETE;
  187. }
  188. else {
  189. RouterIfActive = FALSE;
  190. StopSAP ();
  191. status = ERROR_PROTOCOL_STOP_PENDING;
  192. }
  193. LeaveCriticalSection (&OperationalStateLock);
  194. return status;
  195. }
  196. /*++
  197. *******************************************************************
  198. G E T _ E V E N T _ M E S S A G E _ E N T R Y _ P O I N T
  199. Routine Description:
  200. Dequeues message associated with completion of asynchronous
  201. operation signalled by notification event
  202. Arguments:
  203. Event - buffer to store event id that produced this message
  204. Result - buffer to store results specific to completed operation
  205. Return Value:
  206. NO_ERROR
  207. ERROR_NO_MORE_ITEMS - no more messages in the queue to report
  208. *******************************************************************
  209. --*/
  210. DWORD WINAPI
  211. GetEventMessage(
  212. OUT ROUTING_PROTOCOL_EVENTS *Event,
  213. OUT MESSAGE *Result
  214. ) {
  215. DWORD status;
  216. EnterCriticalSection (&OperationalStateLock);
  217. if ((OperationalState==OPER_STATE_UP)
  218. || (OperationalState==OPER_STATE_STOPPING)
  219. || (OperationalState==OPER_STATE_STARTING)
  220. )
  221. status = SapGetEventResult (Event, Result);
  222. else
  223. status = ERROR_CAN_NOT_COMPLETE;
  224. LeaveCriticalSection (&OperationalStateLock);
  225. return status;
  226. }
  227. /*++
  228. *******************************************************************
  229. A D D _ I N T E R F A C E _ E N T R Y _ P O I N T
  230. Routine Description:
  231. Add interface to sap interface table
  232. Arguments:
  233. InterfaceIndex - unique number identifying interface to add
  234. InterfacInfo - interface parameters
  235. Return Value:
  236. NO_ERROR
  237. ERROR_CAN_NOT_COMPLETE
  238. ERROR_INVALID_PARAMETER
  239. *******************************************************************
  240. --*/
  241. DWORD WINAPI
  242. AddInterface(
  243. IN LPWSTR InterfaceName,
  244. IN ULONG InterfaceIndex,
  245. IN NET_INTERFACE_TYPE InterfaceType,
  246. IN PVOID InterfaceInfo
  247. ) {
  248. #define sapInfo (&((PSAP_IF_CONFIG)InterfaceInfo)->SapIfInfo)
  249. #define sapFilters (&((PSAP_IF_CONFIG)InterfaceInfo)->SapIfFilters)
  250. DWORD status;
  251. UNREFERENCED_PARAMETER(InterfaceType);
  252. EnterCriticalSection (&OperationalStateLock);
  253. if (OperationalState==OPER_STATE_UP) {
  254. status = SapCreateSapInterface (
  255. InterfaceName,
  256. InterfaceIndex,
  257. InterfaceType,
  258. sapInfo);
  259. if ((status==NO_ERROR)
  260. && ((sapFilters->SupplyFilterCount
  261. +sapFilters->ListenFilterCount)>0))
  262. status = SapSetInterfaceFilters (InterfaceIndex, sapFilters);
  263. switch (status) {
  264. case NO_ERROR:
  265. case ERROR_INVALID_PARAMETER:
  266. break;
  267. case ERROR_ALREADY_EXISTS:
  268. status = ERROR_INVALID_PARAMETER;
  269. break;
  270. default:
  271. status = ERROR_CAN_NOT_COMPLETE;
  272. }
  273. }
  274. else
  275. status = ERROR_CAN_NOT_COMPLETE;
  276. LeaveCriticalSection (&OperationalStateLock);
  277. return status;
  278. #undef sapIfInfo
  279. #undef sapIfFilters
  280. }
  281. /*++
  282. *******************************************************************
  283. D E L E T E _ I N T E R F A C E _ E N T R Y _ P O I N T
  284. Routine Description:
  285. Deletes interface from sap interface table and associated services
  286. from sap service table
  287. Arguments:
  288. InterfaceIndex - unique number identifying interface to delete
  289. Return Value:
  290. NO_ERROR
  291. ERROR_CAN_NOT_COMPLETE
  292. ERROR_INVALID_PARAMETER
  293. *******************************************************************
  294. --*/
  295. DWORD WINAPI
  296. DeleteInterface(
  297. IN ULONG InterfaceIndex
  298. ) {
  299. DWORD status;
  300. EnterCriticalSection (&OperationalStateLock);
  301. if (OperationalState==OPER_STATE_UP) {
  302. status = SapDeleteSapInterface (InterfaceIndex);
  303. switch (status) {
  304. case NO_ERROR:
  305. case ERROR_INVALID_PARAMETER:
  306. case ERROR_NO_MORE_ITEMS:
  307. case ERROR_CAN_NOT_COMPLETE:
  308. break;
  309. default:
  310. status = ERROR_CAN_NOT_COMPLETE;
  311. }
  312. }
  313. else
  314. status = ERROR_CAN_NOT_COMPLETE;
  315. LeaveCriticalSection (&OperationalStateLock);
  316. return status;
  317. }
  318. /*++
  319. *******************************************************************
  320. G E T _ I N T E R F A C E _ C O N F I G _ I N F O _ E N T R Y _ P O I N T
  321. Routine Description:
  322. Gets interface configuration info from sap interface table
  323. Arguments:
  324. InterfaceIndex - unique index identifying interface to get info
  325. InterfaceInfo - buffer to receive interface info
  326. InterfaceInfoSize - on input: size of the buffer
  327. on output: size of interface info or size of the
  328. required buffer if ERROR_INSUFFICIENT_BUFFER
  329. is returned
  330. Return Value:
  331. NO_ERROR
  332. ERROR_CAN_NOT_COMPLETE
  333. ERROR_INVALID_PARAMETER
  334. ERROR_INSUFFICIENT_BUFFER
  335. *******************************************************************
  336. --*/
  337. DWORD WINAPI
  338. GetInterfaceConfigInfo(
  339. IN ULONG InterfaceIndex,
  340. IN PVOID InterfaceInfo,
  341. IN OUT PULONG InterfaceInfoSize
  342. ) {
  343. #define sapInfo (&((PSAP_IF_CONFIG)InterfaceInfo)->SapIfInfo)
  344. #define sapFilters (&((PSAP_IF_CONFIG)InterfaceInfo)->SapIfFilters)
  345. DWORD status;
  346. EnterCriticalSection (&OperationalStateLock);
  347. if (OperationalState==OPER_STATE_UP) {
  348. if (*InterfaceInfoSize>=sizeof(SAP_IF_INFO)) {
  349. *InterfaceInfoSize -= sizeof (SAP_IF_INFO);
  350. status = SapGetSapInterface (InterfaceIndex,
  351. sapInfo,
  352. NULL);
  353. if (status==NO_ERROR)
  354. status = SapGetInterfaceFilters (InterfaceIndex,
  355. sapFilters,
  356. InterfaceInfoSize);
  357. switch (status) {
  358. case NO_ERROR:
  359. case ERROR_INVALID_PARAMETER:
  360. case ERROR_CAN_NOT_COMPLETE:
  361. case ERROR_INSUFFICIENT_BUFFER:
  362. break;
  363. default:
  364. status = ERROR_CAN_NOT_COMPLETE;
  365. }
  366. }
  367. else {
  368. *InterfaceInfoSize = 0;
  369. status = SapGetInterfaceFilters (InterfaceIndex,
  370. NULL, InterfaceInfoSize);
  371. if (status==NO_ERROR)
  372. status = ERROR_INSUFFICIENT_BUFFER;
  373. }
  374. *InterfaceInfoSize += sizeof (SAP_IF_INFO);
  375. }
  376. else
  377. status = ERROR_CAN_NOT_COMPLETE;
  378. LeaveCriticalSection (&OperationalStateLock);
  379. return status;
  380. #undef sapIfInfo
  381. #undef sapIfFilters
  382. }
  383. /*++
  384. *******************************************************************
  385. S E T _ I N T E R F A C E _ C O N F I G _ I N F O _ E N T R Y _ P O I N T
  386. Routine Description:
  387. Sets interface configuration info in sap interface table
  388. Arguments:
  389. InterfaceIndex - unique index identifying interface to get info
  390. InterfaceInfo - buffer with interface info
  391. Return Value:
  392. NO_ERROR
  393. ERROR_CAN_NOT_COMPLETE
  394. ERROR_INVALID_PARAMETER
  395. *******************************************************************
  396. --*/
  397. DWORD WINAPI
  398. SetInterfaceConfigInfo(
  399. IN ULONG InterfaceIndex,
  400. IN PVOID InterfaceInfo
  401. ) {
  402. #define sapInfo (&((PSAP_IF_CONFIG)InterfaceInfo)->SapIfInfo)
  403. #define sapFilters (&((PSAP_IF_CONFIG)InterfaceInfo)->SapIfFilters)
  404. DWORD status;
  405. EnterCriticalSection (&OperationalStateLock);
  406. if (OperationalState==OPER_STATE_UP) {
  407. status = SapSetSapInterface (InterfaceIndex, sapInfo);
  408. if (status==NO_ERROR)
  409. status = SapSetInterfaceFilters (InterfaceIndex, sapFilters);
  410. switch (status) {
  411. case NO_ERROR:
  412. case ERROR_INVALID_PARAMETER:
  413. case ERROR_NO_MORE_ITEMS:
  414. case ERROR_CAN_NOT_COMPLETE:
  415. break;
  416. default:
  417. status = ERROR_CAN_NOT_COMPLETE;
  418. }
  419. }
  420. else
  421. status = ERROR_CAN_NOT_COMPLETE;
  422. LeaveCriticalSection (&OperationalStateLock);
  423. return status;
  424. #undef sapIfInfo
  425. #undef sapIfFilters
  426. }
  427. /*++
  428. *******************************************************************
  429. B I N D _ I N T E R F A C E _ E N T R Y _ P O I N T
  430. Routine Description:
  431. Activates sap interface and binds it to the adapter
  432. Start SAP if interface is configured for standart update mode
  433. Arguments:
  434. InterfaceIndex - unique index identifying interface to activate
  435. BindingInfo - bound adpater info
  436. Return Value:
  437. NO_ERROR
  438. ERROR_CAN_NOT_COMPLETE
  439. ERROR_INVALID_PARAMETER
  440. *******************************************************************
  441. --*/
  442. DWORD WINAPI
  443. BindInterface(
  444. IN ULONG InterfaceIndex,
  445. IN PVOID BindingInfo
  446. ) {
  447. DWORD status;
  448. EnterCriticalSection (&OperationalStateLock);
  449. if (OperationalState==OPER_STATE_UP) {
  450. status = SapBindSapInterfaceToAdapter (InterfaceIndex,
  451. (PIPX_ADAPTER_BINDING_INFO)BindingInfo);
  452. switch (status) {
  453. case NO_ERROR:
  454. case ERROR_INVALID_PARAMETER:
  455. case ERROR_NO_MORE_ITEMS:
  456. case ERROR_CAN_NOT_COMPLETE:
  457. break;
  458. default:
  459. status = ERROR_CAN_NOT_COMPLETE;
  460. }
  461. }
  462. else
  463. status = ERROR_CAN_NOT_COMPLETE;
  464. LeaveCriticalSection (&OperationalStateLock);
  465. return status;
  466. }
  467. /*++
  468. *******************************************************************
  469. U N B I N D _ I N T E R F A C E _ E N T R Y _ P O I N T
  470. Routine Description:
  471. Deactivates sap interface and unbinds it to the adapter
  472. Stops SAP on interface and deletes all services obtained
  473. through SAP on this interface form the service table
  474. Arguments:
  475. InterfaceIndex - unique index identifying interface to deactivate
  476. Return Value:
  477. NO_ERROR
  478. ERROR_CAN_NOT_COMPLETE
  479. ERROR_INVALID_PARAMETER
  480. *******************************************************************
  481. --*/
  482. DWORD WINAPI
  483. UnbindInterface(
  484. IN ULONG InterfaceIndex
  485. ) {
  486. DWORD status;
  487. EnterCriticalSection (&OperationalStateLock);
  488. if (OperationalState==OPER_STATE_UP) {
  489. status = SapUnbindSapInterfaceFromAdapter (InterfaceIndex);
  490. switch (status) {
  491. case NO_ERROR:
  492. case ERROR_INVALID_PARAMETER:
  493. case ERROR_NO_MORE_ITEMS:
  494. case ERROR_CAN_NOT_COMPLETE:
  495. break;
  496. default:
  497. status = ERROR_CAN_NOT_COMPLETE;
  498. }
  499. }
  500. else
  501. status = ERROR_CAN_NOT_COMPLETE;
  502. LeaveCriticalSection (&OperationalStateLock);
  503. return status;
  504. }
  505. /*++
  506. *******************************************************************
  507. E N A B L E _ I N T E R F A C E _ E N T R Y _ P O I N T
  508. Routine Description:
  509. Reenables SAP operation over the interface
  510. Arguments:
  511. InterfaceIndex - unique index identifying interface to deactivate
  512. Return Value:
  513. NO_ERROR
  514. ERROR_CAN_NOT_COMPLETE
  515. ERROR_INVALID_PARAMETER
  516. *******************************************************************
  517. --*/
  518. DWORD WINAPI
  519. EnableInterface(
  520. IN ULONG InterfaceIndex
  521. ) {
  522. DWORD status;
  523. EnterCriticalSection (&OperationalStateLock);
  524. if (OperationalState==OPER_STATE_UP) {
  525. status = SapSetInterfaceEnable (InterfaceIndex, TRUE);
  526. switch (status) {
  527. case NO_ERROR:
  528. case ERROR_INVALID_PARAMETER:
  529. case ERROR_CAN_NOT_COMPLETE:
  530. break;
  531. default:
  532. status = ERROR_CAN_NOT_COMPLETE;
  533. }
  534. }
  535. else
  536. status = ERROR_CAN_NOT_COMPLETE;
  537. LeaveCriticalSection (&OperationalStateLock);
  538. return status;
  539. }
  540. /*++
  541. *******************************************************************
  542. D I S A B L E _ I N T E R F A C E _ E N T R Y _ P O I N T
  543. Routine Description:
  544. Disables SAP operation over the interface
  545. Arguments:
  546. InterfaceIndex - unique index identifying interface to deactivate
  547. Return Value:
  548. NO_ERROR
  549. ERROR_CAN_NOT_COMPLETE
  550. ERROR_INVALID_PARAMETER
  551. *******************************************************************
  552. --*/
  553. DWORD WINAPI
  554. DisableInterface(
  555. IN ULONG InterfaceIndex
  556. ) {
  557. DWORD status;
  558. EnterCriticalSection (&OperationalStateLock);
  559. if (OperationalState==OPER_STATE_UP) {
  560. status = SapSetInterfaceEnable (InterfaceIndex, FALSE);
  561. switch (status) {
  562. case NO_ERROR:
  563. case ERROR_INVALID_PARAMETER:
  564. case ERROR_CAN_NOT_COMPLETE:
  565. break;
  566. default:
  567. status = ERROR_CAN_NOT_COMPLETE;
  568. }
  569. }
  570. else
  571. status = ERROR_CAN_NOT_COMPLETE;
  572. LeaveCriticalSection (&OperationalStateLock);
  573. return status;
  574. }
  575. /*++
  576. *******************************************************************
  577. D O _ U P D A T E _ S E R V I C E S _ E N T R Y _ P O I N T
  578. Routine Description:
  579. Initiates update of services information over the interface
  580. Completion of this update will be indicated by signalling
  581. NotificationEvent passed at StartProtocol. GetEventMessage
  582. can be used then to get the results of autostatic update
  583. Arguments:
  584. InterfaceIndex - unique index identifying interface to do
  585. update on
  586. Return Value:
  587. NO_ERROR
  588. ERROR_CAN_NOT_COMPLETE
  589. ERROR_INVALID_PARAMETER
  590. *******************************************************************
  591. --*/
  592. DWORD WINAPI
  593. UpdateServices(
  594. IN ULONG InterfaceIndex
  595. ) {
  596. DWORD status;
  597. EnterCriticalSection (&OperationalStateLock);
  598. if (OperationalState==OPER_STATE_UP) {
  599. status = SapRequestUpdate (InterfaceIndex);
  600. switch (status) {
  601. case NO_ERROR:
  602. case ERROR_INVALID_PARAMETER:
  603. case ERROR_CAN_NOT_COMPLETE:
  604. break;
  605. default:
  606. status = ERROR_CAN_NOT_COMPLETE;
  607. }
  608. }
  609. else
  610. status = ERROR_CAN_NOT_COMPLETE;
  611. LeaveCriticalSection (&OperationalStateLock);
  612. return status;
  613. }
  614. /*++
  615. *******************************************************************
  616. M I B _ C R E A T E _ E N T R Y _ P O I N T
  617. Routine Description:
  618. Entry point used by SNMP agent to create entries in SAP
  619. tables. Currently the only table supported is Interface Table
  620. (service table is accessed through router manager)
  621. Arguments:
  622. InputDataSize - must be size of sap interface info
  623. InputData - SAP interface info
  624. Return Value:
  625. NO_ERROR
  626. ERROR_CAN_NOT_COMPLETE
  627. ERROR_INVALID_PARAMETER
  628. *******************************************************************
  629. --*/
  630. DWORD WINAPI
  631. MibCreate(
  632. IN ULONG InputDataSize,
  633. IN PVOID InputData
  634. ) {
  635. return ERROR_CAN_NOT_COMPLETE;
  636. }
  637. /*++
  638. *******************************************************************
  639. M I B _ D E L E T E _ E N T R Y _ P O I N T
  640. Routine Description:
  641. Entry point used by SNMP agent to delete entries in SAP
  642. tables. Currently the only table supported is Interface Table
  643. (service table is accessed through router manager)
  644. Arguments:
  645. InputDataSize - must be size of sap interface info
  646. InputData - SAP interface info
  647. Return Value:
  648. NO_ERROR
  649. ERROR_CAN_NOT_COMPLETE
  650. ERROR_INVALID_PARAMETER
  651. *******************************************************************
  652. --*/
  653. DWORD WINAPI
  654. MibDelete(
  655. IN ULONG InputDataSize,
  656. IN PVOID InputData
  657. ) {
  658. #define sapInputData ((PSAP_MIB_SET_INPUT_DATA)InputData)
  659. DWORD status;
  660. if (InputDataSize!=sizeof (SAP_MIB_SET_INPUT_DATA))
  661. return ERROR_INVALID_PARAMETER;
  662. EnterCriticalSection (&OperationalStateLock);
  663. if (OperationalState==OPER_STATE_UP) {
  664. switch (sapInputData->TableId) {
  665. case SAP_INTERFACE_TABLE:
  666. status = SapDeleteSapInterface (
  667. sapInputData->SapInterface.InterfaceIndex);
  668. switch (status) {
  669. case NO_ERROR:
  670. case ERROR_INVALID_PARAMETER:
  671. break;
  672. case ERROR_ALREADY_EXISTS:
  673. status = ERROR_INVALID_PARAMETER;
  674. break;
  675. default:
  676. status = ERROR_CAN_NOT_COMPLETE;
  677. }
  678. break;
  679. default:
  680. status = ERROR_INVALID_PARAMETER;
  681. break;
  682. }
  683. }
  684. else
  685. status = ERROR_CAN_NOT_COMPLETE;
  686. LeaveCriticalSection (&OperationalStateLock);
  687. #undef sapInputData
  688. return status;
  689. }
  690. /*++
  691. *******************************************************************
  692. M I B _ S E T _ E N T R Y _ P O I N T
  693. Routine Description:
  694. Entry point used by SNMP agent to set entries in SAP
  695. tables. Currently the only table supported is Interface Table
  696. (service table is accessed through router manager)
  697. Arguments:
  698. InputDataSize - must be size of sap interface info
  699. InputData - SAP interface info
  700. Return Value:
  701. NO_ERROR
  702. ERROR_CAN_NOT_COMPLETE
  703. ERROR_INVALID_PARAMETER
  704. *******************************************************************
  705. --*/
  706. DWORD WINAPI
  707. MibSet(
  708. IN ULONG InputDataSize,
  709. IN PVOID InputData
  710. ) {
  711. #define sapInputData ((PSAP_MIB_SET_INPUT_DATA)InputData)
  712. DWORD status;
  713. if (InputDataSize!=sizeof (SAP_MIB_SET_INPUT_DATA))
  714. return ERROR_INVALID_PARAMETER;
  715. EnterCriticalSection (&OperationalStateLock);
  716. if (OperationalState==OPER_STATE_UP) {
  717. switch (sapInputData->TableId) {
  718. case SAP_INTERFACE_TABLE:
  719. status = SapSetSapInterface (
  720. sapInputData->SapInterface.InterfaceIndex,
  721. &sapInputData->SapInterface.SapIfInfo);
  722. switch (status) {
  723. case NO_ERROR:
  724. case ERROR_INVALID_PARAMETER:
  725. break;
  726. case ERROR_ALREADY_EXISTS:
  727. status = ERROR_INVALID_PARAMETER;
  728. break;
  729. default:
  730. status = ERROR_CAN_NOT_COMPLETE;
  731. }
  732. break;
  733. default:
  734. status = ERROR_INVALID_PARAMETER;
  735. break;
  736. }
  737. }
  738. else
  739. status = ERROR_CAN_NOT_COMPLETE;
  740. LeaveCriticalSection (&OperationalStateLock);
  741. #undef sapInputData
  742. return status;
  743. }
  744. /*++
  745. *******************************************************************
  746. M I B _ G E T _ E N T R Y _ P O I N T
  747. Routine Description:
  748. Entry point used by SNMP agent to get entries from SAP
  749. tables. Currently the only table supported is Interface Table
  750. (service table is accessed through router manager)
  751. Arguments:
  752. InputDataSize - must be size of SAP_MIB_GET_INPUT_DATA
  753. InputData - SAP mib get input data
  754. OutputDataSize - on input: size of the output buffer
  755. on output : size of output info or required
  756. size of output buffer
  757. if ERROR_INSUFFICIENT_BUFFER returned
  758. OutputData - buffer to receive output data
  759. Return Value:
  760. NO_ERROR
  761. ERROR_CAN_NOT_COMPLETE
  762. ERROR_INVALID_PARAMETER
  763. ERROR_INSUFFICIENT_BUFFER
  764. *******************************************************************
  765. --*/
  766. DWORD WINAPI
  767. MibGet(
  768. IN ULONG InputDataSize,
  769. IN PVOID InputData,
  770. IN OUT PULONG OutputDataSize,
  771. OUT PVOID OutputData
  772. ) {
  773. #define sapInputData ((PSAP_MIB_GET_INPUT_DATA)InputData)
  774. DWORD status;
  775. if (InputDataSize!=sizeof (SAP_MIB_GET_INPUT_DATA))
  776. return ERROR_INVALID_PARAMETER;
  777. EnterCriticalSection (&OperationalStateLock);
  778. if (OperationalState==OPER_STATE_UP) {
  779. switch (sapInputData->TableId) {
  780. case SAP_BASE_ENTRY:
  781. if (*OutputDataSize>=sizeof (SAP_MIB_BASE)) {
  782. #define sapOutputData ((PSAP_MIB_BASE)OutputData)
  783. sapOutputData->SapOperState = OperationalState;
  784. status = NO_ERROR;
  785. #undef sapOutputData
  786. }
  787. else
  788. status = ERROR_INSUFFICIENT_BUFFER;
  789. *OutputDataSize = sizeof (SAP_MIB_BASE);
  790. break;
  791. case SAP_INTERFACE_TABLE:
  792. if (*OutputDataSize>=sizeof (SAP_INTERFACE)) {
  793. #define sapOutputData ((PSAP_INTERFACE)OutputData)
  794. status = SapGetSapInterface (
  795. sapInputData->InterfaceIndex,
  796. &sapOutputData->SapIfInfo,
  797. &sapOutputData->SapIfStats);
  798. switch (status) {
  799. case NO_ERROR:
  800. sapOutputData->InterfaceIndex
  801. = sapInputData->InterfaceIndex;
  802. break;
  803. case ERROR_INVALID_PARAMETER:
  804. break;
  805. case ERROR_ALREADY_EXISTS:
  806. status = ERROR_INVALID_PARAMETER;
  807. break;
  808. default:
  809. status = ERROR_CAN_NOT_COMPLETE;
  810. }
  811. #undef sapOutputData
  812. }
  813. else
  814. status = ERROR_INSUFFICIENT_BUFFER;
  815. *OutputDataSize = sizeof (SAP_INTERFACE);
  816. break;
  817. default:
  818. status = ERROR_INVALID_PARAMETER;
  819. break;
  820. }
  821. }
  822. else
  823. status = ERROR_CAN_NOT_COMPLETE;
  824. LeaveCriticalSection (&OperationalStateLock);
  825. #undef sapInputData
  826. return status;
  827. }
  828. /*++
  829. *******************************************************************
  830. M I B _ G E T _ F I R S T _ E N T R Y _ P O I N T
  831. Routine Description:
  832. Entry point used by SNMP agent to get first entries from SAP
  833. tables. Currently the only table supported is Interface Table
  834. (service table is accessed through router manager)
  835. Arguments:
  836. InputDataSize - must be size of SAP_MIB_GET_INPUT_DATA
  837. InputData - SAP mib get input data
  838. OutputDataSize - on input: size of the output buffer
  839. on output : size of output info or required
  840. size of output buffer
  841. if ERROR_INSUFFICIENT_BUFFER returned
  842. OutputData - buffer to receive output data
  843. Return Value:
  844. NO_ERROR
  845. ERROR_CAN_NOT_COMPLETE
  846. ERROR_INVALID_PARAMETER
  847. ERROR_INSUFFICIENT_BUFFER
  848. *******************************************************************
  849. --*/
  850. DWORD WINAPI
  851. MibGetFirst(
  852. IN ULONG InputDataSize,
  853. IN PVOID InputData,
  854. IN OUT PULONG OutputDataSize,
  855. OUT PVOID OutputData
  856. ) {
  857. #define sapInputData ((PSAP_MIB_GET_INPUT_DATA)InputData)
  858. DWORD status;
  859. if (InputDataSize!=sizeof (SAP_MIB_GET_INPUT_DATA))
  860. return ERROR_INVALID_PARAMETER;
  861. EnterCriticalSection (&OperationalStateLock);
  862. if (OperationalState==OPER_STATE_UP) {
  863. switch (sapInputData->TableId) {
  864. case SAP_INTERFACE_TABLE:
  865. if (*OutputDataSize>=sizeof (SAP_INTERFACE)) {
  866. #define sapOutputData ((PSAP_INTERFACE)OutputData)
  867. status = SapGetFirstSapInterface (
  868. &sapOutputData->InterfaceIndex,
  869. &sapOutputData->SapIfInfo,
  870. &sapOutputData->SapIfStats);
  871. switch (status) {
  872. case NO_ERROR:
  873. case ERROR_INVALID_PARAMETER:
  874. case ERROR_NO_MORE_ITEMS:
  875. break;
  876. default:
  877. status = ERROR_CAN_NOT_COMPLETE;
  878. break;
  879. }
  880. #undef sapOutputData
  881. }
  882. else
  883. status = ERROR_INSUFFICIENT_BUFFER;
  884. *OutputDataSize = sizeof (SAP_INTERFACE);
  885. break;
  886. default:
  887. status = ERROR_INVALID_PARAMETER;
  888. break;
  889. }
  890. }
  891. else
  892. status = ERROR_CAN_NOT_COMPLETE;
  893. LeaveCriticalSection (&OperationalStateLock);
  894. #undef sapInputData
  895. return status;
  896. }
  897. /*++
  898. *******************************************************************
  899. M I B _ G E T _ N E X T _ E N T R Y _ P O I N T
  900. Routine Description:
  901. Entry point used by SNMP agent to get next entries from SAP
  902. tables. Currently the only table supported is Interface Table
  903. (service table is accessed through router manager)
  904. Arguments:
  905. InputDataSize - must be size of SAP_MIB_GET_INPUT_DATA
  906. InputData - SAP mib get input data
  907. OutputDataSize - on input: size of the output buffer
  908. on output : size of output info or required
  909. size of output buffer
  910. if ERROR_INSUFFICIENT_BUFFER returned
  911. OutputData - buffer to receive output data
  912. Return Value:
  913. NO_ERROR
  914. ERROR_CAN_NOT_COMPLETE
  915. ERROR_INVALID_PARAMETER
  916. ERROR_INSUFFICIENT_BUFFER
  917. *******************************************************************
  918. --*/
  919. DWORD WINAPI
  920. MibGetNext(
  921. IN ULONG InputDataSize,
  922. IN PVOID InputData,
  923. IN OUT PULONG OutputDataSize,
  924. OUT PVOID OutputData
  925. ) {
  926. #define sapInputData ((PSAP_MIB_GET_INPUT_DATA)InputData)
  927. DWORD status;
  928. if (InputDataSize!=sizeof (SAP_MIB_GET_INPUT_DATA))
  929. return ERROR_INVALID_PARAMETER;
  930. EnterCriticalSection (&OperationalStateLock);
  931. if (OperationalState==OPER_STATE_UP) {
  932. switch (sapInputData->TableId) {
  933. case SAP_INTERFACE_TABLE:
  934. if (*OutputDataSize>=sizeof (SAP_INTERFACE)) {
  935. #define sapOutputData ((PSAP_INTERFACE)OutputData)
  936. sapOutputData->InterfaceIndex
  937. = sapInputData->InterfaceIndex;
  938. status = SapGetNextSapInterface (
  939. &sapOutputData->InterfaceIndex,
  940. &sapOutputData->SapIfInfo,
  941. &sapOutputData->SapIfStats);
  942. switch (status) {
  943. case NO_ERROR:
  944. case ERROR_INVALID_PARAMETER:
  945. case ERROR_NO_MORE_ITEMS:
  946. break;
  947. default:
  948. status = ERROR_CAN_NOT_COMPLETE;
  949. break;
  950. }
  951. #undef sapOutputData
  952. }
  953. else
  954. status = ERROR_INSUFFICIENT_BUFFER;
  955. *OutputDataSize = sizeof (SAP_INTERFACE);
  956. break;
  957. default:
  958. status = ERROR_INVALID_PARAMETER;
  959. break;
  960. }
  961. }
  962. else
  963. status = ERROR_CAN_NOT_COMPLETE;
  964. LeaveCriticalSection (&OperationalStateLock);
  965. #undef sapInputData
  966. return status;
  967. }
  968. DWORD WINAPI
  969. MibSetTrapInfo(
  970. IN HANDLE Event,
  971. IN ULONG InputDataSize,
  972. IN PVOID InputData,
  973. OUT PULONG OutputDataSize,
  974. OUT PVOID OutputData
  975. ) {
  976. return ERROR_CAN_NOT_COMPLETE;
  977. }
  978. DWORD WINAPI
  979. MibGetTrapInfo(
  980. IN ULONG InputDataSize,
  981. IN PVOID InputData,
  982. OUT PULONG OutputDataSize,
  983. OUT PVOID OutputData
  984. ) {
  985. return ERROR_CAN_NOT_COMPLETE;
  986. }
  987. /*++
  988. *******************************************************************
  989. C R E A T E _ S T A T I C _ S E R V I C E _ E N T R Y _ P O I N T
  990. Routine Description:
  991. Adds service of IPX_PROTOCOL_STATIC to the table
  992. Arguments:
  993. InterfaceIndex - interface on which this server can be reached
  994. ServiceEntry - server info
  995. Return Value:
  996. NO_ERROR - server was added ok
  997. ERROR_CAN_NOT_COMPLETE - SAP agent is down
  998. other - windows error code
  999. *******************************************************************
  1000. --*/
  1001. DWORD WINAPI
  1002. CreateStaticService(
  1003. IN ULONG InterfaceIndex,
  1004. IN PIPX_STATIC_SERVICE_INFO ServiceEntry
  1005. ) {
  1006. DWORD status;
  1007. IPX_SERVER_ENTRY_P Server;
  1008. IpxServerCpy (&Server, ServiceEntry);
  1009. EnterCriticalSection (&OperationalStateLock);
  1010. if (OperationalState==OPER_STATE_UP) {
  1011. SAP_IF_STATS ifStats;
  1012. status = SapGetSapInterface (InterfaceIndex, NULL, &ifStats);
  1013. if (status==NO_ERROR) {
  1014. status = UpdateServer (&Server,
  1015. InterfaceIndex,
  1016. IPX_PROTOCOL_STATIC,
  1017. INFINITE,
  1018. IPX_BCAST_NODE,
  1019. (ifStats.SapIfOperState!=OPER_STATE_DOWN)
  1020. ? 0
  1021. : SDB_DISABLED_NODE_FLAG,
  1022. NULL);
  1023. }
  1024. }
  1025. else
  1026. status = ERROR_CAN_NOT_COMPLETE;
  1027. LeaveCriticalSection (&OperationalStateLock);
  1028. return status;
  1029. }
  1030. /*++
  1031. *******************************************************************
  1032. D E L E T E _ S T A T I C _ S E R V I C E _ E N T R Y _ P O I N T
  1033. Routine Description:
  1034. Deletes service of IPX_PROTOCOL_STATIC from the table
  1035. Arguments:
  1036. InterfaceIndex - interface on which this server can be reached
  1037. ServiceEntry - server info
  1038. Return Value:
  1039. NO_ERROR - service was deleted ok
  1040. ERROR_CAN_NOT_COMPLETE - SAP agent is down
  1041. other - windows error code
  1042. *******************************************************************
  1043. --*/
  1044. DWORD WINAPI
  1045. DeleteStaticService(
  1046. IN ULONG InterfaceIndex,
  1047. IN PIPX_STATIC_SERVICE_INFO ServiceEntry
  1048. ) {
  1049. DWORD status;
  1050. EnterCriticalSection (&OperationalStateLock);
  1051. if (OperationalState==OPER_STATE_UP) {
  1052. IPX_SERVER_ENTRY_P Server;
  1053. IpxServerCpy (&Server, ServiceEntry); // Make local copy
  1054. Server.HopCount = IPX_MAX_HOP_COUNT; // because we need to change
  1055. // one of the fields
  1056. status = UpdateServer (&Server, InterfaceIndex,
  1057. IPX_PROTOCOL_STATIC, INFINITE, IPX_BCAST_NODE, 0, NULL);
  1058. }
  1059. else
  1060. status = ERROR_CAN_NOT_COMPLETE;
  1061. LeaveCriticalSection (&OperationalStateLock);
  1062. return status;
  1063. }
  1064. /*++
  1065. *******************************************************************
  1066. B L O C K _ D E L E T E _ S T A T I C _ S E R V I C E S _ E N T R Y _ P O I N T
  1067. Routine Description:
  1068. Delete all services of IPX_PROTOCOL_STATIC
  1069. associated with given interface from the table
  1070. Arguments:
  1071. InterfaceIndex - interface index of interest
  1072. Return Value:
  1073. NO_ERROR - service was deleted ok
  1074. ERROR_CAN_NOT_COMPLETE - SAP agent is down
  1075. other - windows error code
  1076. *******************************************************************
  1077. --*/
  1078. DWORD WINAPI
  1079. BlockDeleteStaticServices(
  1080. IN ULONG InterfaceIndex
  1081. ) {
  1082. DWORD status;
  1083. EnterCriticalSection (&OperationalStateLock);
  1084. if (OperationalState==OPER_STATE_UP) {
  1085. HANDLE enumHdl = NULL;
  1086. enumHdl = CreateListEnumerator (
  1087. SDB_INTF_LIST_LINK,
  1088. 0xFFFF,
  1089. NULL,
  1090. InterfaceIndex,
  1091. IPX_PROTOCOL_STATIC,
  1092. SDB_DISABLED_NODE_FLAG);
  1093. if (enumHdl!=NULL) {
  1094. EnumerateServers (enumHdl, DeleteAllServersCB, enumHdl);
  1095. status = GetLastError ();
  1096. DeleteListEnumerator (enumHdl);
  1097. }
  1098. else
  1099. status = ERROR_CAN_NOT_COMPLETE;
  1100. }
  1101. else
  1102. status = ERROR_CAN_NOT_COMPLETE;
  1103. LeaveCriticalSection (&OperationalStateLock);
  1104. return status;
  1105. }
  1106. /*++
  1107. *******************************************************************
  1108. B L O C K _ C O N V E R T _ S E R V I C E S _ T O _ S T A T I C _ ENTRY_POINT
  1109. Routine Description:
  1110. Converts protocol iof all services associated with given interface to
  1111. IPX_PROTOCOL_STATIC
  1112. Arguments:
  1113. InterfaceIndex - interface index of interest
  1114. Return Value:
  1115. NO_ERROR - service was deleted ok
  1116. ERROR_CAN_NOT_COMPLETE - SAP agent is down
  1117. other - windows error code
  1118. *******************************************************************
  1119. --*/
  1120. DWORD WINAPI
  1121. BlockConvertServicesToStatic(
  1122. IN ULONG InterfaceIndex
  1123. ) {
  1124. DWORD status;
  1125. EnterCriticalSection (&OperationalStateLock);
  1126. if (OperationalState==OPER_STATE_UP) {
  1127. HANDLE enumHdl = NULL;
  1128. enumHdl = CreateListEnumerator (
  1129. SDB_INTF_LIST_LINK,
  1130. 0xFFFF,
  1131. NULL,
  1132. InterfaceIndex,
  1133. 0xFFFFFFFF,
  1134. 0);
  1135. if (enumHdl!=NULL) {
  1136. EnumerateServers (enumHdl, ConvertToStaticCB, enumHdl);
  1137. status = GetLastError ();
  1138. DeleteListEnumerator (enumHdl);
  1139. }
  1140. else
  1141. status = ERROR_CAN_NOT_COMPLETE;
  1142. }
  1143. else
  1144. status = ERROR_CAN_NOT_COMPLETE;
  1145. LeaveCriticalSection (&OperationalStateLock);
  1146. return status;
  1147. }
  1148. /*++
  1149. *******************************************************************
  1150. I S _ S E R V I C E _ E N T R Y _ P O I N T
  1151. Routine Description:
  1152. Check if service with given type and type is in the service table
  1153. and opianally return parameters of best entry for this service
  1154. Arguments:
  1155. Type - IPX Service type
  1156. Name - IPX Service name
  1157. Service - buffer that will be filled with the server info
  1158. Return Value:
  1159. TRUE - server was found
  1160. FALSE - server was not found or operation failed (call GetLastError()
  1161. to find out the reason for failure if any)
  1162. *******************************************************************
  1163. --*/
  1164. BOOL WINAPI
  1165. IsService(
  1166. IN USHORT Type,
  1167. IN PUCHAR Name,
  1168. OUT PIPX_SERVICE Service OPTIONAL
  1169. ) {
  1170. DWORD status;
  1171. BOOL res;
  1172. IPX_SERVER_ENTRY_P Server;
  1173. ULONG InterfaceIndex;
  1174. ULONG Protocol;
  1175. EnterCriticalSection (&OperationalStateLock);
  1176. if (OperationalState==OPER_STATE_UP) {
  1177. res = QueryServer (Type, Name,
  1178. &Server, &InterfaceIndex, &Protocol, NULL);
  1179. if (res) {
  1180. if (ARGUMENT_PRESENT (Service)) {
  1181. Service->InterfaceIndex = InterfaceIndex;
  1182. Service->Protocol = Protocol;
  1183. IpxServerCpy (&Service->Server, &Server);
  1184. }
  1185. status = NO_ERROR;
  1186. }
  1187. else
  1188. status = GetLastError ();
  1189. }
  1190. else {
  1191. status = ERROR_CAN_NOT_COMPLETE;
  1192. res = FALSE;
  1193. }
  1194. LeaveCriticalSection (&OperationalStateLock);
  1195. SetLastError (status);
  1196. return res;
  1197. }
  1198. /*++
  1199. *******************************************************************
  1200. C R E A T E _ S E R V I C E _ E N U M E R A T I O N_ H A N D L E_ENTRY_POINT
  1201. Routine Description:
  1202. Create handle to start enumeration of the services in the STM table.
  1203. Arguments:
  1204. ExclusionFlags - Flags to limit enumeration to certain
  1205. types of servers
  1206. CriteriaService - Criteria for exclusion flags
  1207. Return Value:
  1208. Enumeration handle
  1209. NULL - if operation failed (call GetLastError () to get reason
  1210. failure)
  1211. *******************************************************************
  1212. --*/
  1213. HANDLE WINAPI
  1214. CreateServiceEnumerationHandle(
  1215. IN DWORD ExclusionFlags,
  1216. IN PIPX_SERVICE CriteriaService
  1217. ) {
  1218. HANDLE handle;
  1219. DWORD status;
  1220. EnterCriticalSection (&OperationalStateLock);
  1221. if (OperationalState==OPER_STATE_UP) {
  1222. INT idx;
  1223. if (ExclusionFlags & STM_ONLY_THIS_NAME)
  1224. idx = SDB_HASH_TABLE_LINK;
  1225. else if (ExclusionFlags & STM_ONLY_THIS_TYPE)
  1226. idx = SDB_TYPE_LIST_LINK;
  1227. else if (ExclusionFlags & STM_ONLY_THIS_INTERFACE)
  1228. idx = SDB_INTF_LIST_LINK;
  1229. else
  1230. idx = SDB_HASH_TABLE_LINK;
  1231. handle = CreateListEnumerator (idx,
  1232. (USHORT)((ExclusionFlags & STM_ONLY_THIS_TYPE)
  1233. ? CriteriaService->Server.Type : 0xFFFF),
  1234. ((ExclusionFlags & STM_ONLY_THIS_NAME)
  1235. ? CriteriaService->Server.Name : NULL),
  1236. ((ExclusionFlags & STM_ONLY_THIS_INTERFACE)
  1237. ? CriteriaService->InterfaceIndex
  1238. : INVALID_INTERFACE_INDEX),
  1239. ((ExclusionFlags & STM_ONLY_THIS_PROTOCOL)
  1240. ? CriteriaService->Protocol : 0xFFFFFFFFL),
  1241. SDB_DISABLED_NODE_FLAG);
  1242. if (handle!=NULL)
  1243. status = NO_ERROR;
  1244. else
  1245. status = GetLastError ();
  1246. }
  1247. else {
  1248. status = ERROR_CAN_NOT_COMPLETE;
  1249. handle = NULL;
  1250. }
  1251. LeaveCriticalSection (&OperationalStateLock);
  1252. SetLastError (status);
  1253. return handle;
  1254. }
  1255. /*++
  1256. *******************************************************************
  1257. E N U M E R A T E _ G E T _ N E X T _ S E R V I C E _ E N T R Y _ P O I N T
  1258. Routine Description:
  1259. Get next service in the enumeration started by
  1260. CreateServiceEnumerationHandle
  1261. Arguments:
  1262. EnumerationHandle - Handle that identifies this
  1263. enumeration
  1264. Service - buffer to place parameters of next service entry
  1265. to be returned by enumeration
  1266. Return Value:
  1267. NO_ERROR - next service was placed in provided buffer or
  1268. ERROR_NO_MORE_ITEMS - there are no more services to be
  1269. returned in the enumeration
  1270. ERROR_CAN_NOT_COMPLETE - operation failed.
  1271. *******************************************************************
  1272. --*/
  1273. DWORD WINAPI
  1274. EnumerateGetNextService(
  1275. IN HANDLE EnumerationHandle,
  1276. OUT PIPX_SERVICE Service
  1277. ) {
  1278. DWORD status;
  1279. EnterCriticalSection (&OperationalStateLock);
  1280. if (OperationalState==OPER_STATE_UP) {
  1281. if (EnumerateServers (EnumerationHandle, GetOneCB, Service))
  1282. status = NO_ERROR;
  1283. else {
  1284. if (GetLastError()==NO_ERROR)
  1285. status = ERROR_NO_MORE_ITEMS;
  1286. else
  1287. status = ERROR_CAN_NOT_COMPLETE;
  1288. }
  1289. }
  1290. else
  1291. status = ERROR_CAN_NOT_COMPLETE;
  1292. LeaveCriticalSection (&OperationalStateLock);
  1293. return status;
  1294. }
  1295. /*++
  1296. *******************************************************************
  1297. C L O S E _ S E R V I C E _ E N U M E R A T I O N _ H A N D L E _ENTRY_POINT
  1298. Routine Description:
  1299. Frees resources associated with enumeration.
  1300. Arguments:
  1301. EnumerationHandle - Handle that identifies this
  1302. enumeration
  1303. Return Value:
  1304. NO_ERROR - operation succeded
  1305. ERROR_CAN_NOT_COMPLETE - operation failed.
  1306. *******************************************************************
  1307. --*/
  1308. DWORD WINAPI
  1309. CloseServiceEnumerationHandle(
  1310. IN HANDLE EnumerationHandle
  1311. ) {
  1312. DWORD status;
  1313. EnterCriticalSection (&OperationalStateLock);
  1314. if (OperationalState==OPER_STATE_UP) {
  1315. DeleteListEnumerator (EnumerationHandle);
  1316. status = NO_ERROR;
  1317. }
  1318. else
  1319. status = ERROR_CAN_NOT_COMPLETE;
  1320. LeaveCriticalSection (&OperationalStateLock);
  1321. return status;
  1322. }
  1323. /*++
  1324. *******************************************************************
  1325. G E T _ F I R S T _ O R D E R E D _ S E R V I C E _ E N T R Y _ P O I N T
  1326. Routine Description:
  1327. Find and return first service in the order specified by the ordering method.
  1328. Search is limited only to certain types of services as specified by the
  1329. exclusion flags end corresponding fields in Server parameter.
  1330. Returns ERROR_NO_MORE_ITEMS if there are no services in the
  1331. table that meet specified criteria.
  1332. Arguments:
  1333. OrderingMethod - which ordering to consider in determining what is
  1334. the first server
  1335. ExclusionFlags - flags to limit search to certain servers according
  1336. to specified criteria
  1337. Server - On input: criteria for exclusion flags
  1338. On output: first service entry in the specified order
  1339. Return Value:
  1340. NO_ERROR - server was found that meets specified criteria
  1341. ERROR_NO_MORE_ITEMS - no server exist with specified criteria
  1342. other - operation failed (windows error code)
  1343. *******************************************************************
  1344. --*/
  1345. DWORD WINAPI
  1346. GetFirstOrderedService(
  1347. IN DWORD OrderingMethod,
  1348. IN DWORD ExclusionFlags,
  1349. IN OUT PIPX_SERVICE Service
  1350. ) {
  1351. DWORD status;
  1352. IPX_SERVER_ENTRY_P Server;
  1353. IpxServerCpy (&Server, &Service->Server);
  1354. EnterCriticalSection (&OperationalStateLock);
  1355. if (OperationalState==OPER_STATE_UP) {
  1356. status = GetFirstServer (OrderingMethod, ExclusionFlags,
  1357. &Server, &Service->InterfaceIndex, &Service->Protocol);
  1358. }
  1359. else
  1360. status = ERROR_CAN_NOT_COMPLETE;
  1361. LeaveCriticalSection (&OperationalStateLock);
  1362. if (status==NO_ERROR)
  1363. IpxServerCpy (&Service->Server, &Server);
  1364. return status;
  1365. }
  1366. /*++
  1367. *******************************************************************
  1368. G E T _ N E X T _ O R D E R E D _ S E R V I C E _ E N T R Y _ P O I N T
  1369. Routine Description:
  1370. Find and return next service in the order specified by the ordering method.
  1371. Search starts from specified service and is limited only to certain types
  1372. of services as specified by the exclusion flags and corresponding fields
  1373. in Server parameter.
  1374. Arguments:
  1375. OrderingMethod - which ordering to consider in determining what is
  1376. the first server
  1377. ExclusionFlags - flags to limit search to certain servers according
  1378. to fields of Server
  1379. Server - On input server entry from which to compute the next
  1380. On output: first service entry in the specified order
  1381. Return Value:
  1382. NO_ERROR - server was found that meets specified criteria
  1383. ERROR_NO_MORE_ITEMS - no server exist with specified criteria
  1384. other - operation failed (windows error code)
  1385. *******************************************************************
  1386. --*/
  1387. DWORD WINAPI
  1388. GetNextOrderedService(
  1389. IN DWORD OrderingMethod,
  1390. IN DWORD ExclusionFlags,
  1391. IN OUT PIPX_SERVICE Service
  1392. ) {
  1393. DWORD status;
  1394. IPX_SERVER_ENTRY_P Server;
  1395. IpxServerCpy (&Server, &Service->Server);
  1396. EnterCriticalSection (&OperationalStateLock);
  1397. if (OperationalState==OPER_STATE_UP) {
  1398. status = GetNextServer (OrderingMethod, ExclusionFlags,
  1399. &Server, &Service->InterfaceIndex, &Service->Protocol);
  1400. }
  1401. else
  1402. status = ERROR_CAN_NOT_COMPLETE;
  1403. LeaveCriticalSection (&OperationalStateLock);
  1404. if (status==NO_ERROR)
  1405. IpxServerCpy (&Service->Server, &Server);
  1406. return status;
  1407. }
  1408. /*++
  1409. *******************************************************************
  1410. G E T _ S E R V I C E _ C O U N T _ E N T R Y _ P O I N T
  1411. Routine Description:
  1412. Returns total number of services is the table
  1413. Arguments:
  1414. None
  1415. Return Value:
  1416. Number of services in the table
  1417. *******************************************************************
  1418. --*/
  1419. ULONG WINAPI WINAPI
  1420. GetServiceCount(
  1421. void
  1422. ) {
  1423. DWORD status;
  1424. ULONG count;
  1425. EnterCriticalSection (&OperationalStateLock);
  1426. if (OperationalState==OPER_STATE_UP) {
  1427. count = ServerTable.ST_ServerCnt;
  1428. status = ERROR_CAN_NOT_COMPLETE;
  1429. }
  1430. else {
  1431. count = 0;
  1432. status = ERROR_CAN_NOT_COMPLETE;
  1433. }
  1434. LeaveCriticalSection (&OperationalStateLock);
  1435. SetLastError (status);
  1436. return count;
  1437. }
  1438. DWORD
  1439. GetRouteMetric (
  1440. IN UCHAR Network[4],
  1441. OUT PUSHORT Metric
  1442. ) {
  1443. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  1444. IPX_ROUTE Route;
  1445. DWORD RtSize;
  1446. DWORD rc;
  1447. RtSize = sizeof(IPX_ROUTE);
  1448. MibGetInputData.TableId = IPX_DEST_TABLE;
  1449. IpxNetCpy (MibGetInputData.MibIndex.RoutingTableIndex.Network, Network);
  1450. rc = (*MIBEntryGet) (IPX_PROTOCOL_BASE,
  1451. sizeof(IPX_MIB_GET_INPUT_DATA),
  1452. &MibGetInputData,
  1453. &RtSize,
  1454. &Route);
  1455. if (rc==NO_ERROR)
  1456. *Metric = Route.TickCount;
  1457. return rc;
  1458. }
  1459. /*++
  1460. *******************************************************************
  1461. R E G I S T E R _ P R O T O C O L _ E N T R Y _ P O I N T
  1462. Routine Description:
  1463. Register protocol dll with router manager
  1464. Identifies protocol handled by the dll and supported functionality
  1465. Arguments:
  1466. Protocol - buffer to return protocol ID
  1467. SupportedFunctionality - buffer to set flags indicating functionality
  1468. supported by the dll
  1469. Return Value:
  1470. NO_ERROR - SAP agent was started OK
  1471. ERROR_CAN_NOT_COMPLETE - operation can not be completed
  1472. *******************************************************************
  1473. --*/
  1474. DWORD WINAPI
  1475. RegisterProtocol(
  1476. IN OUT PMPR_ROUTING_CHARACTERISTICS pRoutingChar,
  1477. IN OUT PMPR_SERVICE_CHARACTERISTICS pServiceChar
  1478. )
  1479. {
  1480. if(pRoutingChar->dwProtocolId != IPX_PROTOCOL_SAP)
  1481. {
  1482. return ERROR_NOT_SUPPORTED;
  1483. }
  1484. pRoutingChar->fSupportedFunctionality = 0;
  1485. pServiceChar->fSupportedFunctionality = SERVICES|DEMAND_UPDATE_SERVICES;
  1486. pRoutingChar->pfnStartProtocol = StartProtocol;
  1487. pRoutingChar->pfnStopProtocol = StopProtocol;
  1488. pRoutingChar->pfnAddInterface = AddInterface;
  1489. pRoutingChar->pfnDeleteInterface = DeleteInterface;
  1490. pRoutingChar->pfnGetEventMessage = GetEventMessage;
  1491. pRoutingChar->pfnGetInterfaceInfo = GetInterfaceConfigInfo;
  1492. pRoutingChar->pfnSetInterfaceInfo = SetInterfaceConfigInfo;
  1493. pRoutingChar->pfnBindInterface = BindInterface;
  1494. pRoutingChar->pfnUnbindInterface = UnbindInterface;
  1495. pRoutingChar->pfnEnableInterface = EnableInterface;
  1496. pRoutingChar->pfnDisableInterface = DisableInterface;
  1497. pRoutingChar->pfnGetGlobalInfo = GetGlobalInfo;
  1498. pRoutingChar->pfnSetGlobalInfo = SetGlobalInfo;
  1499. pRoutingChar->pfnMibCreateEntry = MibCreate;
  1500. pRoutingChar->pfnMibDeleteEntry = MibDelete;
  1501. pRoutingChar->pfnMibGetEntry = MibGet;
  1502. pRoutingChar->pfnMibSetEntry = MibSet;
  1503. pRoutingChar->pfnMibGetFirstEntry = MibGetFirst;
  1504. pRoutingChar->pfnMibGetNextEntry = MibGetNext;
  1505. pRoutingChar->pfnUpdateRoutes = NULL;
  1506. pServiceChar->pfnIsService = IsService;
  1507. pServiceChar->pfnUpdateServices = UpdateServices;
  1508. pServiceChar->pfnCreateServiceEnumerationHandle = CreateServiceEnumerationHandle;
  1509. pServiceChar->pfnEnumerateGetNextService = EnumerateGetNextService;
  1510. pServiceChar->pfnCloseServiceEnumerationHandle = CloseServiceEnumerationHandle;
  1511. pServiceChar->pfnGetServiceCount = GetServiceCount;
  1512. pServiceChar->pfnCreateStaticService = CreateStaticService;
  1513. pServiceChar->pfnDeleteStaticService = DeleteStaticService;
  1514. pServiceChar->pfnBlockConvertServicesToStatic = BlockConvertServicesToStatic;
  1515. pServiceChar->pfnBlockDeleteStaticServices = BlockDeleteStaticServices;
  1516. pServiceChar->pfnGetFirstOrderedService = GetFirstOrderedService;
  1517. pServiceChar->pfnGetNextOrderedService = GetNextOrderedService;
  1518. return NO_ERROR;
  1519. }