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.

1512 lines
27 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. vwdos.c
  5. Abstract:
  6. ntVdm netWare (Vw) IPX/SPX Functions
  7. Vw: The peoples' network
  8. Contains handlers for DOS IPX/SPX calls (netware functions). The IPX APIs
  9. use WinSock to perform the actual operations
  10. Contents:
  11. VwIPXCancelEvent
  12. VwIPXCloseSocket
  13. VwIPXDisconnectFromTarget
  14. VwIPXGenerateChecksum
  15. VwIPXGetInformation
  16. VwIPXGetInternetworkAddress
  17. VwIPXGetIntervalMarker
  18. VwIPXGetLocalTarget
  19. VwIPXGetLocalTargetAsync
  20. VwIPXGetMaxPacketSize
  21. VwIPXInitialize
  22. VwIPXListenForPacket
  23. VwIPXOpenSocket
  24. VwIPXRelinquishControl
  25. VwIPXScheduleAESEvent
  26. VwIPXScheduleIPXEvent
  27. VwIPXSendPacket
  28. VwIPXSendWithChecksum
  29. VwIPXSPXDeinit
  30. VwIPXVerifyChecksum
  31. VwSPXAbortConnection
  32. VwSPXEstablishConnection
  33. VwSPXGetConnectionStatus
  34. VwSPXInitialize
  35. VwSPXListenForConnection
  36. VwSPXListenForSequencedPacket
  37. VwSPXSendSequencedPacket
  38. VwSPXTerminateConnection
  39. Author:
  40. Richard L Firth (rfirth) 30-Sep-1993
  41. Environment:
  42. User-mode Win32
  43. Revision History:
  44. 30-Sep-1993 rfirth
  45. Created
  46. --*/
  47. #include "vw.h"
  48. #pragma hdrstop
  49. //
  50. // functions
  51. //
  52. VOID
  53. VwIPXCancelEvent(
  54. VOID
  55. )
  56. /*++
  57. Routine Description:
  58. Cancels event described by an ECB
  59. This call is Synchronous
  60. Arguments:
  61. Inputs
  62. BX 06h
  63. ES:SI ECB
  64. Outputs
  65. AL Completion code:
  66. 00h Success
  67. F9h Can't cancel ECB
  68. FFh ECB not in use
  69. Return Value:
  70. None.
  71. --*/
  72. {
  73. LPECB pEcb;
  74. WORD status;
  75. CHECK_INTERRUPTS("VwIPXCancelEvent");
  76. IPXDBGPRINT((__FILE__, __LINE__,
  77. FUNCTION_IPXCancelEvent,
  78. IPXDBG_LEVEL_INFO,
  79. "VwIPXCancelEvent(%04x:%04x)\n",
  80. getES(),
  81. getSI()
  82. ));
  83. IPX_GET_IPX_ECB(pEcb);
  84. status = _VwIPXCancelEvent( pEcb );
  85. IPX_SET_STATUS(status);
  86. }
  87. VOID
  88. VwIPXCloseSocket(
  89. VOID
  90. )
  91. /*++
  92. Routine Description:
  93. Closes a socket and cancels any outstanding events on the socket.
  94. Closing an unopened socket does not return an error
  95. ESRs in cancelled ECBs are not called
  96. This call is Synchronous
  97. Arguments:
  98. Inputs
  99. BX 01h
  100. DX Socket Number
  101. Outputs
  102. Nothing
  103. Return Value:
  104. None.
  105. --*/
  106. {
  107. WORD socketNumber;
  108. CHECK_INTERRUPTS("VwIPXCloseSocket");
  109. IPXDBGPRINT((__FILE__, __LINE__,
  110. FUNCTION_IPXCloseSocket,
  111. IPXDBG_LEVEL_INFO,
  112. "VwIPXCloseSocket(%#x)\n",
  113. B2LW(IPX_SOCKET_PARM())
  114. ));
  115. IPX_GET_SOCKET(socketNumber);
  116. _VwIPXCloseSocket( socketNumber );
  117. }
  118. VOID
  119. VwIPXDisconnectFromTarget(
  120. VOID
  121. )
  122. /*++
  123. Routine Description:
  124. Performs no action for NTVDM IPX
  125. This call is Synchronous
  126. Arguments:
  127. Inputs
  128. BX 0Bh
  129. ES:SI Request buffer:
  130. Destination Network DB 4 DUP (?)
  131. Destination Node DB 6 DUP (?)
  132. Destination Socket DB 2 DUP (?)
  133. Outputs
  134. Nothing
  135. Return Value:
  136. None.
  137. --*/
  138. {
  139. CHECK_INTERRUPTS("VwIPXDisconnectFromTarget");
  140. IPXDBGPRINT((__FILE__, __LINE__,
  141. FUNCTION_IPXDisconnectFromTarget,
  142. IPXDBG_LEVEL_INFO,
  143. "VwIPXDisconnectFromTarget\n"
  144. ));
  145. }
  146. VOID
  147. VwIPXGenerateChecksum(
  148. VOID
  149. )
  150. /*++
  151. Routine Description:
  152. Generates checksum for a transmit ECB
  153. This call is Synchronous
  154. Arguments:
  155. Inputs
  156. BX 21h
  157. ES:SI ECB address
  158. Outputs
  159. No registers
  160. ECB checksum field is updated
  161. Return Value:
  162. None.
  163. --*/
  164. {
  165. CHECK_INTERRUPTS("VwIPXGenerateChecksum");
  166. IPXDBGPRINT((__FILE__, __LINE__,
  167. FUNCTION_IPXGenerateChecksum,
  168. IPXDBG_LEVEL_INFO,
  169. "VwIPXGenerateChecksum\n"
  170. ));
  171. }
  172. VOID
  173. VwIPXGetInformation(
  174. VOID
  175. )
  176. /*++
  177. Routine Description:
  178. Returns a bit-map of supported functions
  179. This call is Synchronous
  180. Arguments:
  181. Inputs
  182. BX 1Fh
  183. DX 0000h
  184. Outputs
  185. DX Bit map:
  186. 0001h Set if IPX is IPXODI.COM, not dedicated IPX
  187. 0002h Set if checksum functions (20h, 21h, 22h) supported
  188. Return Value:
  189. None.
  190. --*/
  191. {
  192. CHECK_INTERRUPTS("VwIPXGetInformation");
  193. IPXDBGPRINT((__FILE__, __LINE__,
  194. FUNCTION_IPXGetInformation,
  195. IPXDBG_LEVEL_INFO,
  196. "VwIPXGetInformation\n"
  197. ));
  198. IPX_SET_INFORMATION(IPX_ODI);
  199. }
  200. VOID
  201. VwIPXGetInternetworkAddress(
  202. VOID
  203. )
  204. /*++
  205. Routine Description:
  206. Returns a buffer containing the net number and node number for this
  207. station.
  208. This function cannot return an error (!)
  209. Assumes: 1. GetInternetAddress has been successfully called in the
  210. DLL initialization phase
  211. This call is Synchronous
  212. Arguments:
  213. Inputs
  214. BX 09h
  215. Outputs
  216. ES:SI Buffer
  217. Network Address DB 4 DUP (?)
  218. Node Address DB 6 DUP (?)
  219. Return Value:
  220. None.
  221. --*/
  222. {
  223. LPINTERNET_ADDRESS pAddr;
  224. CHECK_INTERRUPTS("VwIPXGetInternetworkAddress");
  225. IPXDBGPRINT((__FILE__, __LINE__,
  226. FUNCTION_IPXGetInternetworkAddress,
  227. IPXDBG_LEVEL_INFO,
  228. "VwIPXGetInternetworkAddress(%04x:%04x)\n",
  229. getES(),
  230. getSI()
  231. ));
  232. pAddr = (LPINTERNET_ADDRESS)IPX_BUFFER_PARM(sizeof(*pAddr));
  233. if (pAddr) {
  234. _VwIPXGetInternetworkAddress( pAddr );
  235. }
  236. }
  237. VOID
  238. VwIPXGetIntervalMarker(
  239. VOID
  240. )
  241. /*++
  242. Routine Description:
  243. Just returns the tick count maintained by Asynchronous Event Scheduler
  244. This call is Synchronous
  245. Arguments:
  246. Inputs
  247. BX 08h
  248. Outputs
  249. AX Interval marker
  250. Return Value:
  251. None.
  252. --*/
  253. {
  254. CHECK_INTERRUPTS("VwIPXGetIntervalMarker");
  255. setAX( _VwIPXGetIntervalMarker() );
  256. IPXDBGPRINT((__FILE__, __LINE__,
  257. FUNCTION_IPXGetIntervalMarker,
  258. IPXDBG_LEVEL_INFO,
  259. "VwIPXGetIntervalMarker: Returning %04x\n",
  260. getAX()
  261. ));
  262. }
  263. VOID
  264. VwIPXGetLocalTarget(
  265. VOID
  266. )
  267. /*++
  268. Routine Description:
  269. Given a target address of the form (network address {4}, node address {6}),
  270. returns the node address of the target if on the same network, or the node
  271. address of the router which knows how to get to the next hop in reaching the
  272. eventual target
  273. This call is Synchronous
  274. Arguments:
  275. Inputs
  276. BX 02h
  277. ES:SI Request buffer
  278. Destination Network DB 4 DUP (?)
  279. Destination Node DB 6 DUP (?)
  280. Destination Socket DB 2 DUP (?)
  281. ES:DI Response buffer
  282. Local Target DB 6 DUP (?)
  283. Outputs
  284. AL Completion code
  285. 00h Success
  286. FAh No path to destination node found
  287. AH Number of hops to destination
  288. CX Transport time
  289. Return Value:
  290. None.
  291. --*/
  292. {
  293. LPBYTE pImmediateAddress;
  294. LPBYTE pNetworkAddress;
  295. WORD transportTime;
  296. WORD status;
  297. CHECK_INTERRUPTS("VwIPXGetLocalTarget");
  298. IPXDBGPRINT((__FILE__, __LINE__,
  299. FUNCTION_IPXGetLocalTarget,
  300. IPXDBG_LEVEL_INFO,
  301. "VwIPXGetLocalTarget(target buf @ %04x:%04x, local buf @ %04x:%04x)\n",
  302. getES(),
  303. getSI(),
  304. getES(),
  305. getDI()
  306. ));
  307. pImmediateAddress = POINTER_FROM_WORDS(getES(), getDI(), 6);
  308. pNetworkAddress = POINTER_FROM_WORDS(getES(), getSI(), 12);
  309. if (pImmediateAddress && pNetworkAddress) {
  310. status = _VwIPXGetLocalTarget( pNetworkAddress,
  311. pImmediateAddress,
  312. &transportTime );
  313. }
  314. else {
  315. status = IPX_BAD_REQUEST;
  316. }
  317. setCX( transportTime );
  318. setAH(1);
  319. IPX_SET_STATUS(status);
  320. }
  321. VOID
  322. VwIPXGetLocalTargetAsync(
  323. VOID
  324. )
  325. /*++
  326. Routine Description:
  327. description-of-function.
  328. This call is Asynchronous
  329. Arguments:
  330. None.
  331. Return Value:
  332. None.
  333. --*/
  334. {
  335. CHECK_INTERRUPTS("VwIPXGetLocalTargetAsync");
  336. IPXDBGPRINT((__FILE__, __LINE__,
  337. FUNCTION_ANY,
  338. IPXDBG_LEVEL_INFO,
  339. "VwIPXGetLocalTargetAsync\n"
  340. ));
  341. }
  342. VOID
  343. VwIPXGetMaxPacketSize(
  344. VOID
  345. )
  346. /*++
  347. Routine Description:
  348. Returns the maximum packet size the underlying network can handle
  349. Assumes: 1. A successfull call to GetMaxPacketSize has been made during
  350. DLL initialization
  351. 2. Maximum packet size is constant
  352. This call is Synchronous
  353. Arguments:
  354. Inputs
  355. BX 1Ah
  356. Outputs
  357. AX Maximum packet size
  358. CX IPX retry count
  359. Return Value:
  360. None.
  361. --*/
  362. {
  363. WORD maxPacketSize;
  364. WORD retryCount;
  365. CHECK_INTERRUPTS("VwIPXGetMaxPacketSize");
  366. maxPacketSize = _VwIPXGetMaxPacketSize( &retryCount );
  367. setAX(maxPacketSize);
  368. //
  369. // The DOS Assembly and C manuals differ slightly here: DOS says
  370. // we return the IPX retry count in CX. There is no corresponding parameter
  371. // in the C interface?
  372. //
  373. setCX(retryCount);
  374. IPXDBGPRINT((__FILE__, __LINE__,
  375. FUNCTION_IPXGetMaxPacketSize,
  376. IPXDBG_LEVEL_INFO,
  377. "VwIPXGetMaxPacketSize: PacketSize=%d, RetryCount=%d\n",
  378. getAX(),
  379. getCX()
  380. ));
  381. }
  382. VOID
  383. VwIPXInitialize(
  384. VOID
  385. )
  386. /*++
  387. Routine Description:
  388. description-of-function.
  389. Arguments:
  390. None.
  391. Return Value:
  392. None.
  393. --*/
  394. {
  395. CHECK_INTERRUPTS("VwIPXInitialize");
  396. IPXDBGPRINT((__FILE__, __LINE__,
  397. FUNCTION_ANY,
  398. IPXDBG_LEVEL_INFO,
  399. "VwIPXInitialize\n"
  400. ));
  401. }
  402. VOID
  403. VwIPXListenForPacket(
  404. VOID
  405. )
  406. /*++
  407. Routine Description:
  408. Queue a listen request against a socket. All listen requests will be
  409. completed asynchronously, unless cancelled by app
  410. This call is Asynchronous
  411. Arguments:
  412. Inputs
  413. BX 04h
  414. ES:SI ECB address
  415. Outputs
  416. AL Completion code
  417. FFh Socket doesn't exist
  418. Return Value:
  419. None.
  420. --*/
  421. {
  422. LPECB pEcb;
  423. WORD status;
  424. CHECK_INTERRUPTS("VwIPXListenForPacket");
  425. IPXDBGPRINT((__FILE__, __LINE__,
  426. FUNCTION_IPXListenForPacket,
  427. IPXDBG_LEVEL_INFO,
  428. "VwIPXListenForPacket(%04x:%04x)\n",
  429. getES(),
  430. getSI()
  431. ));
  432. IPX_GET_IPX_ECB(pEcb);
  433. status = _VwIPXListenForPacket( pEcb, ECB_PARM_ADDRESS() );
  434. IPX_SET_STATUS(status);
  435. }
  436. VOID
  437. VwIPXOpenSocket(
  438. VOID
  439. )
  440. /*++
  441. Routine Description:
  442. Opens a socket for use by IPX or SPX. Puts the socket into non-blocking mode.
  443. The socket will be bound to IPX
  444. This call is Synchronous
  445. Arguments:
  446. Inputs
  447. AL Socket Longevity flag
  448. This parameter is actually in BP - AX has been sequestered
  449. by the VDD dispatcher
  450. BX 00h
  451. DX Requested Socket Number
  452. CX DOS PDB. This parameter is not part of the IPX API.
  453. Added because we need to remember which DOS executable created
  454. the socket: we need to clean-up short-lived sockets when the
  455. executable terminates
  456. Outputs
  457. AL Completion code:
  458. 00h Success
  459. FFh Socket already open
  460. FEh Socket table full
  461. DX Assigned socket number
  462. Return Value:
  463. None.
  464. --*/
  465. {
  466. BYTE socketLife;
  467. WORD socketNumber;
  468. WORD status;
  469. CHECK_INTERRUPTS("VwIPXOpenSocket");
  470. IPX_GET_SOCKET_LIFE(socketLife);
  471. IPX_GET_SOCKET(socketNumber);
  472. IPXDBGPRINT((__FILE__, __LINE__,
  473. FUNCTION_IPXOpenSocket,
  474. IPXDBG_LEVEL_INFO,
  475. "VwIPXOpenSocket(Life=%02x, Socket=%04x, Owner=%04x)\n",
  476. socketLife,
  477. B2LW(socketNumber),
  478. IPX_SOCKET_OWNER_PARM()
  479. ));
  480. status = _VwIPXOpenSocket( &socketNumber,
  481. socketLife,
  482. IPX_SOCKET_OWNER_PARM() );
  483. if ( status == IPX_SUCCESS )
  484. IPX_SET_SOCKET(socketNumber);
  485. IPX_SET_STATUS(status);
  486. }
  487. VOID
  488. VwIPXRelinquishControl(
  489. VOID
  490. )
  491. /*++
  492. Routine Description:
  493. Just sleep for a nominal amount. Netware seems to be dependent on the
  494. default setting of the PC clock, so one timer tick (1/18 second) would
  495. seem to be a good value
  496. This call is Synchronous
  497. Arguments:
  498. Inputs
  499. BX 0Ah
  500. Outputs
  501. Nothing
  502. Return Value:
  503. None.
  504. --*/
  505. {
  506. CHECK_INTERRUPTS("VwIPXRelinquishControl");
  507. IPXDBGPRINT((__FILE__, __LINE__,
  508. FUNCTION_IPXRelinquishControl,
  509. IPXDBG_LEVEL_INFO,
  510. "VwIPXRelinquishControl\n"
  511. ));
  512. _VwIPXRelinquishControl();
  513. }
  514. VOID
  515. VwIPXScheduleAESEvent(
  516. VOID
  517. )
  518. /*++
  519. Routine Description:
  520. Schedules a an event to occur in some number of ticks. When the tick count
  521. reaches 0, the ECB InUse field is cleared and any ESR called
  522. This call is Asynchronous
  523. Arguments:
  524. Inputs
  525. BX 07h
  526. AX Delay time - number of 1/18 second ticks
  527. ES:SI ECB address
  528. Outputs
  529. Nothing
  530. Return Value:
  531. None.
  532. --*/
  533. {
  534. LPXECB pXecb = AES_ECB_PARM();
  535. WORD ticks = IPX_TICKS_PARM();
  536. if (pXecb == NULL) {
  537. return;
  538. }
  539. CHECK_INTERRUPTS("VwIPXScheduleAESEvent");
  540. IPXDBGPRINT((__FILE__, __LINE__,
  541. FUNCTION_IPXScheduleAESEvent,
  542. IPXDBG_LEVEL_INFO,
  543. "VwIPXScheduleAESEvent(%04x:%04x, %04x)\n",
  544. getES(),
  545. getSI(),
  546. ticks
  547. ));
  548. ScheduleEvent(pXecb, ticks);
  549. }
  550. VOID
  551. VwIPXScheduleIPXEvent(
  552. VOID
  553. )
  554. /*++
  555. Routine Description:
  556. Schedules a an event to occur in some number of ticks. When the tick count
  557. reaches 0, the ECB InUse field is cleared and any ESR called
  558. This call is Asynchronous
  559. Arguments:
  560. Inputs
  561. BX 05h
  562. AX Delay time - number of 1/18 second ticks
  563. ES:SI ECB address
  564. Outputs
  565. Nothing
  566. Return Value:
  567. None.
  568. --*/
  569. {
  570. LPECB pEcb;
  571. WORD ticks = IPX_TICKS_PARM();
  572. CHECK_INTERRUPTS("VwIPXScheduleIPXEvent");
  573. IPX_GET_IPX_ECB(pEcb);
  574. IPXDBGPRINT((__FILE__, __LINE__,
  575. FUNCTION_IPXScheduleIPXEvent,
  576. IPXDBG_LEVEL_INFO,
  577. "VwIPXScheduleIPXEvent(%04x:%04x, %04x)\n",
  578. getES(),
  579. getSI(),
  580. ticks
  581. ));
  582. _VwIPXScheduleIPXEvent( ticks, pEcb, ECB_PARM_ADDRESS() );
  583. }
  584. VOID
  585. VwIPXSendPacket(
  586. VOID
  587. )
  588. /*++
  589. Routine Description:
  590. Sends a packet to the target machine/router. This call can be made on a
  591. socket that is not open
  592. The app must have filled in the following IPX_ECB fields:
  593. EsrAddress
  594. Socket
  595. ImmediateAddress
  596. FragmentCount
  597. fragment descriptor fields
  598. and the following IPX_PACKET fields:
  599. PacketType
  600. Destination.Net
  601. Destination.Node
  602. Destination.Socket
  603. This call is Asynchronous
  604. Arguments:
  605. Inputs
  606. BX 03h
  607. CX DOS PDB. This parameter is not part of the IPX API.
  608. Added because we need to remember which DOS executable owns the
  609. socket IF WE MUST CREATE A TEMPORTARY SOCKET: we need to clean-up
  610. short-lived sockets when the executable terminates
  611. ES:SI ECB Address
  612. Outputs
  613. Nothing
  614. Return Value:
  615. None.
  616. --*/
  617. {
  618. LPECB pEcb;
  619. WORD owner;
  620. CHECK_INTERRUPTS("VwIPXSendPacket");
  621. IPX_GET_IPX_ECB(pEcb);
  622. IPXDBGPRINT((__FILE__, __LINE__,
  623. FUNCTION_IPXSendPacket,
  624. IPXDBG_LEVEL_INFO,
  625. "VwIPXSendPacket(%04x:%04x), owner = %04x\n",
  626. getES(),
  627. getSI(),
  628. IPX_SOCKET_OWNER_PARM()
  629. ));
  630. _VwIPXSendPacket(pEcb,
  631. ECB_PARM_ADDRESS(),
  632. IPX_SOCKET_OWNER_PARM()
  633. );
  634. }
  635. VOID
  636. VwIPXSendWithChecksum(
  637. VOID
  638. )
  639. /*++
  640. Routine Description:
  641. description-of-function.
  642. This call is Asynchronous
  643. Arguments:
  644. None.
  645. Return Value:
  646. None.
  647. --*/
  648. {
  649. CHECK_INTERRUPTS("VwIPXSendWithChecksum");
  650. IPXDBGPRINT((__FILE__, __LINE__,
  651. FUNCTION_IPXSendWithChecksum,
  652. IPXDBG_LEVEL_INFO,
  653. "VwIPXSendWithChecksum\n"
  654. ));
  655. }
  656. VOID
  657. VwIPXSPXDeinit(
  658. VOID
  659. )
  660. /*++
  661. Routine Description:
  662. description-of-function.
  663. This call is Synchronous
  664. Arguments:
  665. None.
  666. Return Value:
  667. None.
  668. --*/
  669. {
  670. CHECK_INTERRUPTS("VwIPXSPXDeinit");
  671. IPXDBGPRINT((__FILE__, __LINE__,
  672. FUNCTION_ANY,
  673. IPXDBG_LEVEL_INFO,
  674. "VwIPXSPXDeinit\n"
  675. ));
  676. }
  677. VOID
  678. VwIPXVerifyChecksum(
  679. VOID
  680. )
  681. /*++
  682. Routine Description:
  683. description-of-function.
  684. This call is Synchronous
  685. Arguments:
  686. None.
  687. Return Value:
  688. None.
  689. --*/
  690. {
  691. CHECK_INTERRUPTS("VwIPXVerifyChecksum");
  692. IPXDBGPRINT((__FILE__, __LINE__,
  693. FUNCTION_IPXVerifyChecksum,
  694. IPXDBG_LEVEL_INFO,
  695. "VwIPXVerifyChecksum\n"
  696. ));
  697. }
  698. VOID
  699. VwSPXAbortConnection(
  700. VOID
  701. )
  702. /*++
  703. Routine Description:
  704. Aborts this end of a connection
  705. This call is Asynchronous
  706. Arguments:
  707. Inputs
  708. BX 14h
  709. DX Connection ID
  710. Outputs
  711. Nothing
  712. Return Value:
  713. None.
  714. --*/
  715. {
  716. WORD connectionId = SPX_CONNECTION_PARM();
  717. CHECK_INTERRUPTS("VwSPXAbortConnection");
  718. IPXDBGPRINT((__FILE__, __LINE__,
  719. FUNCTION_SPXAbortConnection,
  720. IPXDBG_LEVEL_INFO,
  721. "VwSPXAbortConnection(%04x)\n",
  722. connectionId
  723. ));
  724. _VwSPXAbortConnection(connectionId);
  725. }
  726. VOID
  727. VwSPXEstablishConnection(
  728. VOID
  729. )
  730. /*++
  731. Routine Description:
  732. Creates a connection with a remote SPX socket. The remote end can be on
  733. this machine (i.e. same app in DOS world)
  734. This call is Asynchronous
  735. Arguments:
  736. Inputs
  737. BX 11h
  738. AL Retry count
  739. AH WatchDog flag
  740. ES:SI ECB Address
  741. Outputs
  742. AL Completion code:
  743. 00h Attempting to talk to remote
  744. EFh Local connection table full
  745. FDh Fragment count not 1; buffer size not 42
  746. FFh Send socket not open
  747. DX Connection ID
  748. Return Value:
  749. None.
  750. --*/
  751. {
  752. WORD status;
  753. BYTE retryCount = SPX_RETRY_COUNT_PARM();
  754. BYTE watchDogFlag = SPX_WATCHDOG_FLAG_PARM();
  755. WORD connectionId = 0;
  756. LPECB pEcb;
  757. CHECK_INTERRUPTS("VwSPXEstablishConnection");
  758. IPXDBGPRINT((__FILE__, __LINE__,
  759. FUNCTION_SPXEstablishConnection,
  760. IPXDBG_LEVEL_INFO,
  761. "VwSPXEstablishConnection(%02x, %02x, %04x:%04x)\n",
  762. retryCount,
  763. watchDogFlag,
  764. ECB_PARM_SEGMENT(),
  765. ECB_PARM_OFFSET()
  766. ));
  767. IPX_GET_IPX_ECB( pEcb );
  768. IPXDUMPECB((pEcb, getES(), getSI(), ECB_TYPE_SPX, TRUE, TRUE, FALSE));
  769. status = _VwSPXEstablishConnection( retryCount,
  770. watchDogFlag,
  771. &connectionId,
  772. pEcb,
  773. ECB_PARM_ADDRESS() );
  774. SPX_SET_CONNECTION_ID( connectionId );
  775. SPX_SET_STATUS( status );
  776. }
  777. VOID
  778. VwSPXGetConnectionStatus(
  779. VOID
  780. )
  781. /*++
  782. Routine Description:
  783. Returns buffer crammed full of useful statistics or something (hu hu huh)
  784. This call is Synchronous
  785. Arguments:
  786. Inputs
  787. BX 15h
  788. DX Connection ID
  789. ES:SI Buffer address
  790. Outputs
  791. AL Completion code:
  792. 00h Connection is active
  793. EEh No such connection
  794. on output, buffer in ES:SI contains:
  795. BYTE ConnectionStatus
  796. BYTE WatchDogActive
  797. WORD LocalConnectionID
  798. WORD RemoteConnectionID
  799. WORD SequenceNumber
  800. WORD LocalAckNumber
  801. WORD LocalAllocationNumber
  802. WORD RemoteAckNumber
  803. WORD RemoteAllocationNumber
  804. WORD LocalSocket
  805. BYTE ImmediateAddress[6]
  806. BYTE RemoteNetwork[4]
  807. WORD RetransmissionCount
  808. WORD RetransmittedPackets
  809. WORD SuppressedPackets
  810. Return Value:
  811. None.
  812. --*/
  813. {
  814. WORD status;
  815. WORD connectionId = SPX_CONNECTION_PARM();
  816. LPSPX_CONNECTION_STATS pStats = (LPSPX_CONNECTION_STATS)SPX_BUFFER_PARM(sizeof(*pStats));
  817. CHECK_INTERRUPTS("VwSPXGetConnectionStatus");
  818. IPXDBGPRINT((__FILE__, __LINE__,
  819. FUNCTION_SPXGetConnectionStatus,
  820. IPXDBG_LEVEL_INFO,
  821. "VwSPXGetConnectionStatus: connectionId=%04x\n",
  822. connectionId
  823. ));
  824. status = _VwSPXGetConnectionStatus( connectionId,
  825. pStats );
  826. SPX_SET_STATUS(status);
  827. }
  828. VOID
  829. VwSPXInitialize(
  830. VOID
  831. )
  832. /*++
  833. Routine Description:
  834. Informs the app that SPX is present on this station
  835. This call is Synchronous
  836. Arguments:
  837. Inputs
  838. BX 10h
  839. AL 00h
  840. Outputs
  841. AL Installation flag:
  842. 00h Not installed
  843. FFh Installed
  844. BH SPX Major revision number
  845. BL SPX Minor revision number
  846. CX Maximum SPX connections supported
  847. normally from SHELL.CFG
  848. DX Available SPX connections
  849. Return Value:
  850. None.
  851. --*/
  852. {
  853. WORD status;
  854. BYTE majorRevisionNumber;
  855. BYTE minorRevisionNumber;
  856. WORD maxConnections;
  857. WORD availableConnections;
  858. CHECK_INTERRUPTS("VwSPXInitialize");
  859. IPXDBGPRINT((__FILE__, __LINE__,
  860. FUNCTION_SPXInitialize,
  861. IPXDBG_LEVEL_INFO,
  862. "VwSPXInitialize\n"
  863. ));
  864. status = _VwSPXInitialize( &majorRevisionNumber,
  865. &minorRevisionNumber,
  866. &maxConnections,
  867. &availableConnections );
  868. setBH( majorRevisionNumber );
  869. setBL( minorRevisionNumber );
  870. setCX( maxConnections );
  871. setDX( availableConnections );
  872. SPX_SET_STATUS(status);
  873. }
  874. VOID
  875. VwSPXListenForConnection(
  876. VOID
  877. )
  878. /*++
  879. Routine Description:
  880. Listens for an incoming connection request
  881. This call is Asynchronous
  882. Arguments:
  883. Inputs
  884. BX 12h
  885. AL Retry count
  886. AH SPX WatchDog flag
  887. ES:SI ECB Address
  888. Outputs
  889. Nothing
  890. Return Value:
  891. None.
  892. --*/
  893. {
  894. BYTE retryCount = SPX_RETRY_COUNT_PARM();
  895. BYTE watchDogFlag = SPX_WATCHDOG_FLAG_PARM();
  896. LPECB pEcb;
  897. CHECK_INTERRUPTS("VwSPXListenForConnection");
  898. IPXDBGPRINT((__FILE__, __LINE__,
  899. FUNCTION_SPXListenForConnection,
  900. IPXDBG_LEVEL_INFO,
  901. "VwSPXListenForConnection(%02x, %02x, %04x:%04x)\n",
  902. retryCount,
  903. watchDogFlag,
  904. ECB_PARM_SEGMENT(),
  905. ECB_PARM_OFFSET()
  906. ));
  907. IPX_GET_IPX_ECB( pEcb );
  908. IPXDUMPECB((pEcb, getES(), getSI(), ECB_TYPE_SPX, TRUE, FALSE, FALSE));
  909. _VwSPXListenForConnection( retryCount,
  910. watchDogFlag,
  911. pEcb,
  912. ECB_PARM_ADDRESS() );
  913. }
  914. VOID
  915. VwSPXListenForSequencedPacket(
  916. VOID
  917. )
  918. /*++
  919. Routine Description:
  920. Attempts to receive an SPX packet. This call is made against the top-level
  921. socket (the socket in SPX-speak, not the connection). We can receive a
  922. packet from any connection assigned to this socket. In this function, we
  923. just queue the ECB (since there is no return status, we expect that the
  924. app has supplied an ESR) and let AES handle it
  925. This call is Asynchronous
  926. Arguments:
  927. Inputs
  928. BX 17h
  929. ES:SI ECB Address
  930. Outputs
  931. Nothing
  932. Return Value:
  933. None.
  934. --*/
  935. {
  936. LPECB pEcb;
  937. CHECK_INTERRUPTS("VwSPXListenForSequencedPacket");
  938. IPXDBGPRINT((__FILE__, __LINE__,
  939. FUNCTION_SPXListenForSequencedPacket,
  940. IPXDBG_LEVEL_INFO,
  941. "VwSPXListenForSequencedPacket(%04x:%04x)\n",
  942. ECB_PARM_SEGMENT(),
  943. ECB_PARM_OFFSET()
  944. ));
  945. IPX_GET_IPX_ECB( pEcb );
  946. IPXDUMPECB((pEcb, getES(), getSI(), ECB_TYPE_SPX, TRUE, FALSE, FALSE));
  947. _VwSPXListenForSequencedPacket( pEcb,
  948. ECB_PARM_ADDRESS());
  949. }
  950. VOID
  951. VwSPXSendSequencedPacket(
  952. VOID
  953. )
  954. /*++
  955. Routine Description:
  956. Sends a packet on an SPX connection
  957. This call is Asynchronous
  958. Arguments:
  959. Inputs
  960. BX 16h
  961. DX Connection ID
  962. ES:SI ECB address
  963. Outputs
  964. Nothing
  965. Return Value:
  966. None.
  967. --*/
  968. {
  969. WORD connectionId = SPX_CONNECTION_PARM();
  970. LPECB pEcb;
  971. CHECK_INTERRUPTS("VwSPXSendSequencedPacket""VwSPXSendSequencedPacket");
  972. IPXDBGPRINT((__FILE__, __LINE__,
  973. FUNCTION_SPXSendSequencedPacket,
  974. IPXDBG_LEVEL_INFO,
  975. "VwSPXSendSequencedPacket(%04x, %04x:%04x)\n",
  976. connectionId,
  977. getES(),
  978. getSI()
  979. ));
  980. IPX_GET_IPX_ECB( pEcb );
  981. IPXDUMPECB((pEcb, getES(), getSI(), ECB_TYPE_SPX, TRUE, TRUE, FALSE));
  982. _VwSPXSendSequencedPacket( connectionId,
  983. pEcb,
  984. ECB_PARM_ADDRESS() );
  985. }
  986. VOID
  987. VwSPXTerminateConnection(
  988. VOID
  989. )
  990. /*++
  991. Routine Description:
  992. Terminates a connection
  993. This call is Asynchronous
  994. Arguments:
  995. Inputs
  996. BX 13h
  997. DX Connection ID
  998. ES:SI ECB Address
  999. Outputs
  1000. Nothing
  1001. Return Value:
  1002. None.
  1003. --*/
  1004. {
  1005. WORD connectionId = SPX_CONNECTION_PARM();
  1006. LPECB pEcb;
  1007. CHECK_INTERRUPTS("VwSPXTerminateConnection");
  1008. IPX_GET_IPX_ECB( pEcb );
  1009. IPXDBGPRINT((__FILE__, __LINE__,
  1010. FUNCTION_SPXTerminateConnection,
  1011. IPXDBG_LEVEL_INFO,
  1012. "VwSPXTerminateConnection(%04x, %04x:%04x)\n",
  1013. connectionId,
  1014. ECB_PARM_SEGMENT(),
  1015. ECB_PARM_OFFSET()
  1016. ));
  1017. _VwSPXTerminateConnection(connectionId, pEcb, ECB_PARM_ADDRESS());
  1018. }