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.

586 lines
17 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. vwipxspx.h
  5. Abstract:
  6. Contains manifests, typedefs, structures, macros for NTVDM IPX/SPX support
  7. Author:
  8. Richard L Firth (rfirth) 30-Sep-1993
  9. Environment:
  10. Structures are expected to live in segmented VDM address space, but be
  11. accessible from flat 32-bit protect mode. The VDM can be in real or protect
  12. mode
  13. Revision History:
  14. 30-Sep-1993 rfirth
  15. Created
  16. --*/
  17. #ifndef _VWIPXSPX_H_
  18. #define _VWIPXSPX_H_
  19. //
  20. // FREE_OBJECT - in free version, just calls LocalFree. For debug version, fills
  21. // memory with some arbitrary value, then frees the pointer and checks that what
  22. // LocalFree thought that the pointer pointed at a valid, freeable object
  23. //
  24. #if DBG
  25. #define FREE_OBJECT(p) {\
  26. FillMemory(p, sizeof(*p), 0xFF);\
  27. VWASSERT(LocalFree((HLOCAL)(p)), NULL);\
  28. }
  29. #else
  30. #define FREE_OBJECT(p) VWASSERT(LocalFree((HLOCAL)(p)), NULL)
  31. #endif
  32. //
  33. // simple function macros
  34. //
  35. //#define AllocateXecb() (LPXECB)LocalAlloc(LPTR, sizeof(XECB))
  36. //#define DeallocateXecb(p) FREE_OBJECT(p)
  37. #define AllocateBuffer(s) (LPVOID)LocalAlloc(LMEM_FIXED, (s))
  38. #define DeallocateBuffer(p) FREE_OBJECT(p)
  39. //
  40. // pseudo-types for 16-bit addresses
  41. //
  42. #define ESR_ADDRESS DWORD
  43. #define ECB_ADDRESS DWORD
  44. //
  45. // from Novell documentation, the default maximum open sockets. Max max is 150
  46. //
  47. #ifndef DEFAULT_MAX_OPEN_SOCKETS
  48. #define DEFAULT_MAX_OPEN_SOCKETS 20
  49. #endif
  50. #ifndef MAX_OPEN_SOCKETS
  51. #define MAX_OPEN_SOCKETS 150
  52. #endif
  53. #define SPX_INSTALLED 0xFF
  54. #define MAX_LISTEN_QUEUE_SIZE 5 // ?
  55. //
  56. // misc. macros
  57. //
  58. //
  59. // B2LW, L2Bx - big-endian to little-endian macros
  60. //
  61. #define B2LW(w) (WORD)(((WORD)(w) << 8) | ((WORD)(w) >> 8))
  62. #define B2LD(d) (DWORD)(B2LW((DWORD)(d) << 16) | B2LW((DWORD)(d) >> 16))
  63. #define L2BW(w) B2LW(w)
  64. #define L2BD(d) B2LD(d)
  65. //
  66. // miscellaneous manifests
  67. //
  68. #define ONE_TICK (1000/18) // 1/18 sec in milliseconds (55.55 mSec)
  69. #define SLEEP_TIME ONE_TICK // amount of time we Sleep() during IPXRelinquishControl
  70. //
  71. // options for IPXGetInformation
  72. //
  73. #define IPX_ODI 0x0001
  74. #define IPX_CHECKSUM_FUNCTIONS 0x0002
  75. //
  76. // IPX/SPX structures. The following structures are in VDM format, and should
  77. // be packed on a byte-boundary
  78. //
  79. // Netware maintains certain structure fields in network (big-endian) format
  80. //
  81. #include <packon.h>
  82. //
  83. // INTERNET_ADDRESS - structure returned by IPXGetInternetworkAddress
  84. //
  85. typedef struct {
  86. BYTE Net[4];
  87. BYTE Node[6];
  88. } INTERNET_ADDRESS ;
  89. typedef INTERNET_ADDRESS UNALIGNED *LPINTERNET_ADDRESS;
  90. //
  91. // NETWARE_ADDRESS - address of an application on the network, as defined by
  92. // its network segment, node address and socket number
  93. //
  94. typedef struct {
  95. BYTE Net[4]; // hi-lo
  96. BYTE Node[6]; // hi-lo
  97. WORD Socket; // hi-lo
  98. } NETWARE_ADDRESS ;
  99. typedef NETWARE_ADDRESS UNALIGNED *LPNETWARE_ADDRESS;
  100. //
  101. // FRAGMENT - ECB/IPX/SPX buffers are split into 'fragments'
  102. //
  103. typedef struct {
  104. LPVOID Address; // offset-segment
  105. WORD Length; // hi-lo
  106. } FRAGMENT ;
  107. typedef FRAGMENT UNALIGNED *LPFRAGMENT;
  108. //
  109. // IPX_PACKET - format of packet submitted to IPX for sending. The maximum
  110. // size of an IPX packet is 576 bytes, 30 bytes header, 546 bytes data
  111. //
  112. typedef struct {
  113. WORD Checksum; // always set to 0xFFFF
  114. WORD Length; // set by IPX - header + data
  115. BYTE TransportControl; // set by IPX to 0. Used by routers
  116. //
  117. // for IPX, PacketType is 0 (Unknown Packet Type) or 4 (Packet Exchange
  118. // Packet)
  119. //
  120. BYTE PacketType;
  121. NETWARE_ADDRESS Destination;
  122. NETWARE_ADDRESS Source;
  123. BYTE Data[]; // 546 bytes max.
  124. } IPX_PACKET ;
  125. typedef IPX_PACKET UNALIGNED *LPIPX_PACKET;
  126. #define IPX_HEADER_LENGTH sizeof(IPX_PACKET)
  127. #define MAXIMUM_IPX_PACKET_LENGTH 576
  128. #define MAXIMUM_IPX_DATA_LENGTH (MAXIMUM_IPX_PACKET_LENGTH - IPX_HEADER_LENGTH)
  129. #define IPX_PACKET_TYPE 4
  130. //
  131. // SPX_PACKET - format of packet submitted to SPX for sending. The maximum
  132. // size of an SPX packet is 576 bytes, 42 bytes header, 534 bytes data
  133. //
  134. typedef struct {
  135. WORD Checksum; // always set to 0xFFFF
  136. WORD Length; // set by IPX - header + data
  137. BYTE TransportControl; // set by IPX to 0. Used by routers
  138. //
  139. // for SPX, PacketType is set to 5 (Sequenced Packet Protocol Packet)
  140. //
  141. BYTE PacketType;
  142. NETWARE_ADDRESS Destination;
  143. NETWARE_ADDRESS Source;
  144. //
  145. // ConnectionControl is a bitmap which control bi-directional flow over a
  146. // link. The bits are defined (by Xerox SPP) as:
  147. //
  148. // 0-3 undefined
  149. // 4 end-of-message
  150. // This is the only bit which can be directly manipulated by an
  151. // app. The bit is passed through unchanged by SPX
  152. // 5 attention
  153. // Ignored by SPX, but passed through
  154. // 6 acknowledge
  155. // Set by SPX if an ack is required
  156. // 7 system packet
  157. // Set by SPX if the packet is internal control. An app should
  158. // never see this bit (i.e. should never see a system packet)
  159. //
  160. BYTE ConnectionControl;
  161. //
  162. // DataStreamType defines the type of data in the packet:
  163. //
  164. // 0x00 - 0xFD client-defined.
  165. // Ignored by SPX
  166. // 0xFE end-of-connection.
  167. // When active connection is terminated, SPX
  168. // generates and sends a packet with this bit set.
  169. // This will be the last packet sent on the connection
  170. // 0xFF end-of-connection acknowledgement
  171. // SPX generates a system packet to acknowledge an
  172. // end-of-connection packet
  173. //
  174. BYTE DataStreamType;
  175. WORD SourceConnectId; // assigned by SPX
  176. WORD DestinationConnectId;
  177. WORD SequenceNumber; // managed by SPX
  178. WORD AckNumber; // managed by SPX
  179. WORD AllocationNumber; // managed by SPX
  180. BYTE Data[]; // 534 bytes max.
  181. } SPX_PACKET ;
  182. typedef SPX_PACKET UNALIGNED *LPSPX_PACKET;
  183. #define SPX_HEADER_LENGTH sizeof(SPX_PACKET)
  184. #define MAXIMUM_SPX_PACKET_LENGTH MAXIMUM_IPX_PACKET_LENGTH
  185. #define MAXIMUM_SPX_DATA_LENGTH (MAXIMUM_SPX_PACKET_LENGTH - SPX_HEADER_LENGTH)
  186. #define SPX_PACKET_TYPE 5
  187. //
  188. // ConnectionControl flags
  189. //
  190. #define SPX_CONNECTION_RESERVED 0x0F
  191. #define SPX_END_OF_MESSAGE 0x10
  192. #define SPX_ATTENTION 0x20
  193. #define SPX_ACK_REQUIRED 0x40
  194. #define SPX_SYSTEM_PACKET 0x80
  195. //
  196. // DataStreamType values
  197. //
  198. #define SPX_DS_ESTABLISH 0x00
  199. #define SPX_DS_TERMINATE 0xfe
  200. //
  201. // IPX_ECB - Event Control Block. This structure is used by most IPX/SPX APIs,
  202. // especially when deferred IPX/AES processing is required. The following
  203. // structure is a socket-based ECB
  204. //
  205. typedef struct {
  206. //
  207. // LinkAddress is reserved for use by IPX. We use it to link the ECB onto
  208. // a queue. We appropriate the space used for an x86 segmented address
  209. // (real or protect mode) as a flat 32-bit pointer
  210. //
  211. ULPVOID LinkAddress; // offset-segment
  212. //
  213. // EsrAddress is non-NULL if an Event Service Routine will be called when
  214. // the event described by the ECB completes. This will always be an x86
  215. // segmented address (real or protect mode)
  216. //
  217. ESR_ADDRESS EsrAddress; // offset-segment
  218. //
  219. // IPX uses the InUse field to mark the ECB as owned by IPX (!0) or by the
  220. // app (0):
  221. //
  222. // 0xF8 App tried to send a packet while IPX was busy; IPX queued
  223. // the ECB
  224. // 0xFA IPX is processing the ECB
  225. // 0xFB IPX has used the ECB for some event and put it on a queue
  226. // for processing
  227. // 0xFC the ECB is waiting for an AES event to occur
  228. // 0xFD the ECB is waiting for an IPX event to occur
  229. // 0xFE IPX is listening on a socket for incoming packets
  230. // 0xFF IPX is using the ECB to send a packet
  231. //
  232. BYTE InUse;
  233. //
  234. // CompletionCode is used to return a status from a deferred request. This
  235. // field is not valid until InUse has been set to 0
  236. //
  237. // NOTE: We have to differentiate between AES and IPX ECBs on callbacks: due
  238. // to their different sizes, we store the 16-bit segment and offset in
  239. // different places. In order to differentiate the ECBs, we use CompletionCode
  240. // field (AesWorkspace[0]) as the owner. The real CompletionCode for IPX ECBs
  241. // goes in IPX_ECB_COMPLETE (DriverWorkspace[7]). But only for completed ECBs
  242. // that have an ESR
  243. //
  244. BYTE CompletionCode;
  245. WORD SocketNumber; // hi-lo
  246. //
  247. // the first word of IpxWorkspace is used to return the connection ID of
  248. // an SPX connection
  249. //
  250. DWORD IpxWorkspace;
  251. BYTE DriverWorkspace[12];
  252. //
  253. // ImmediateAddress is the local network node at the remote end of this
  254. // connection. It is either the node address of the remote machine if it
  255. // is on this LAN, or it is the node address of the router if the remote
  256. // machine is on a different LAN
  257. //
  258. // This field must be initialized when talking over IPX, but not SPX
  259. //
  260. BYTE ImmediateAddress[6];
  261. //
  262. // FragmentCount - number of FRAGMENT structures that comprise the request.
  263. // Must be at least 1
  264. //
  265. WORD FragmentCount;
  266. //
  267. // FragmentCount fragments start here
  268. //
  269. } IPX_ECB ;
  270. typedef IPX_ECB UNALIGNED *LPIPX_ECB;
  271. //
  272. // ECB InUse values
  273. //
  274. #define ECB_IU_NOT_IN_USE 0x00
  275. #define ECB_IU_TEMPORARY 0xCC
  276. #define ECB_IU_LISTENING_SPX 0xF7 // same as win16 (by observation)
  277. #define ECB_IU_SEND_QUEUED 0xF8
  278. #define ECB_IU_AWAITING_CONNECTION 0xF9 // same as win16 (by observation)
  279. #define ECB_IU_BEING_PROCESSED 0xFA
  280. #define ECB_IU_AWAITING_PROCESSING 0xFB
  281. #define ECB_IU_AWAITING_AES_EVENT 0xFC
  282. #define ECB_IU_AWAITING_IPX_EVENT 0xFD
  283. #define ECB_IU_LISTENING 0xFE
  284. #define ECB_IU_SENDING 0xFF
  285. //
  286. // ECB CompletionCode values
  287. //
  288. #define ECB_CC_SUCCESS 0x00
  289. #define ECB_CC_CONNECTION_TERMINATED 0xEC
  290. #define ECB_CC_CONNECTION_ABORTED 0xED
  291. #define ECB_CC_INVALID_CONNECTION 0xEE
  292. #define ECB_CC_CONNECTION_TABLE_FULL 0xEF
  293. #define ECB_CC_CANNOT_CANCEL 0xF9
  294. #define ECB_CC_CANCELLED 0xFC
  295. #define ECB_CC_BAD_REQUEST 0xFD
  296. #define ECB_CC_BAD_SEND_REQUEST 0xFD
  297. #define ECB_CC_PACKET_OVERFLOW 0xFD
  298. #define ECB_CC_UNDELIVERABLE 0xFE
  299. #define ECB_CC_SOCKET_TABLE_FULL 0xFE
  300. #define ECB_CC_BAD_LISTEN_REQUEST 0xFF
  301. #define ECB_CC_HARDWARE_ERROR 0xFF
  302. #define ECB_CC_NON_EXISTENT_SOCKET 0xFF
  303. //
  304. // we commandeer certain (reserved) fields for our own internal use:
  305. //
  306. // LPECB EcbLink LinkAddress
  307. // PVOID Buffer32 DriverWorkspace[0]
  308. // WORD Length32 DriverWorkspace[4]
  309. // WORD Flags32 DriverWorkspace[6]
  310. // WORD OriginalEs DriverWorkspace[8]
  311. // WORD OriginalSi DriverWorkspace[10]
  312. //
  313. #define ECB_TYPE(p) (((LPIPX_ECB)(p))->CompletionCode)
  314. #define IPX_ECB_SEGMENT(p) (WORD)*((ULPWORD)&(((LPIPX_ECB)(p))->IpxWorkspace)+0)
  315. #define IPX_ECB_OFFSET(p) (WORD)*((ULPWORD)&(((LPIPX_ECB)(p))->IpxWorkspace)+2)
  316. #define IPX_ECB_BUFFER32(p) (ULPVOID)*(ULPVOID*)&(((LPIPX_ECB)(p))->DriverWorkspace[0])
  317. #define IPX_ECB_LENGTH32(p) (WORD)*(ULPWORD)&(((LPIPX_ECB)(p))->DriverWorkspace[4])
  318. #define IPX_ECB_FLAGS32(p) (((LPIPX_ECB)(p))->DriverWorkspace[6])
  319. #define IPX_ECB_COMPLETE(p) (((LPIPX_ECB)(p))->DriverWorkspace[7])
  320. #define SPX_ECB_CONNECTION_ID(p) (WORD)*(ULPWORD)&(((LPIPX_ECB)(p))->IpxWorkspace)
  321. //
  322. // ECB Flags32 flags
  323. //
  324. #define ECB_FLAG_BUFFER_ALLOCATED 0x01
  325. //
  326. // ECB types
  327. //
  328. #define ECB_TYPE_AES 0
  329. #define ECB_TYPE_IPX 1
  330. #define ECB_TYPE_SPX 2
  331. //
  332. // ECB owners
  333. //
  334. #define ECB_OWNER_IPX 0xFF
  335. #define ECB_OWNER_AES 0x00
  336. //
  337. // ECB_FRAGMENT - macro which gives the address of the first fragment structure
  338. // within a socket-based ECB
  339. //
  340. #define ECB_FRAGMENT(p, n) ((LPFRAGMENT)(((LPIPX_ECB)(p) + 1)) + (n))
  341. //
  342. // AES_ECB - used by AES, these socket-less ECBs are used to schedule events
  343. //
  344. typedef struct {
  345. ULPVOID LinkAddress; // offset-segment
  346. ESR_ADDRESS EsrAddress; // offset-segment
  347. BYTE InUse;
  348. //
  349. // first 3 bytes overlay CompletionCode (1) and SocketNumber (2) fields of
  350. // IPX_ECB. Last 2 bytes overlay first 2 bytes of IpxWorkspace (4) field of
  351. // IPX_ECB. We use the 1st byte of the common unused fields as the ECB type
  352. // (send/receive/timed-event)
  353. //
  354. BYTE AesWorkspace[5];
  355. } AES_ECB ;
  356. typedef AES_ECB UNALIGNED *LPAES_ECB;
  357. //
  358. // as with IPX_ECB, we 'borrow' some of the reserved fields for our own use
  359. //
  360. #define AES_ECB_SEGMENT(p) (WORD)*(ULPWORD)&(((LPAES_ECB)(p))->AesWorkspace[1])
  361. #define AES_ECB_OFFSET(p) (WORD)*(ULPWORD)&(((LPAES_ECB)(p))->AesWorkspace[3])
  362. //
  363. // LPECB - points to either IPX_ECB or AES_ECB. Both in VDM workspace
  364. //
  365. #define LPECB LPIPX_ECB
  366. //
  367. // SPX_CONNECTION_STATS - returned by SPXGetConnectionStatus. All WORD fields
  368. // are to be returned HiLo (ie to Hawaii). All fields come back from NT SPX
  369. // transport in HiLo format also (this was changed recently, used to be in
  370. // Intel order).
  371. //
  372. typedef struct {
  373. BYTE State;
  374. BYTE WatchDog;
  375. WORD LocalConnectionId;
  376. WORD RemoteConnectionId;
  377. WORD LocalSequenceNumber;
  378. WORD LocalAckNumber;
  379. WORD LocalAllocNumber;
  380. WORD RemoteAckNumber;
  381. WORD RemoteAllocNumber;
  382. WORD LocalSocket;
  383. BYTE ImmediateAddress[6];
  384. BYTE RemoteNetwork[4];
  385. BYTE RemoteNode[6];
  386. WORD RemoteSocket;
  387. WORD RetransmissionCount;
  388. WORD EstimatedRoundTripDelay;
  389. WORD RetransmittedPackets;
  390. WORD SuppressedPackets;
  391. } SPX_CONNECTION_STATS ;
  392. typedef SPX_CONNECTION_STATS UNALIGNED* LPSPX_CONNECTION_STATS;
  393. #include <packoff.h>
  394. //
  395. // 16-bit parameter get/set macros. These may change depending on requirements
  396. // of real/protect mode parameters (e.g. stack based vs. register based)
  397. //
  398. #define IPX_GET_AES_ECB(p) (p) = (LPAES_ECB)POINTER_FROM_WORDS(getES(), getSI(), sizeof(AES_ECB))
  399. #define IPX_GET_IPX_ECB(p) (p) = (LPIPX_ECB)POINTER_FROM_WORDS(getES(), getSI(), sizeof(IPX_ECB))
  400. #define IPX_GET_SOCKET(s) (s) = (WORD)getDX()
  401. #define IPX_GET_SOCKET_LIFE(l) (l) = (BYTE)getBP()
  402. #define IPX_GET_SOCKET_OWNER(o) (o) = (WORD)getCX()
  403. #define IPX_GET_BUFFER(p, s) (p) = (ULPBYTE)POINTER_FROM_WORDS(getES(), getSI(), (s))
  404. #define IPX_GET_ECB_SEGMENT() getES()
  405. #define IPX_GET_ECB_OFFSET() getSI()
  406. #define IPX_SET_STATUS(s) setAL((BYTE)(s))
  407. #define IPX_SET_SOCKET(s) setDX((WORD)(s))
  408. #define IPX_SET_INFORMATION(v) setDX((WORD)(v))
  409. #define SPX_SET_STATUS(s) setAL((BYTE)(s))
  410. #define SPX_SET_CONNECTION_ID(i) setDX((WORD)(i))
  411. //
  412. // macros returning 16-bit API parameters - may fetch register contents or values
  413. // from stack/memory
  414. //
  415. #define ECB_PARM_SEGMENT() getES()
  416. #define ECB_PARM_OFFSET() getSI()
  417. #define ECB_PARM_ADDRESS() (ECB_ADDRESS)MAKELONG(getSI(), getES())
  418. #define AES_ECB_PARM() RetrieveEcb(ECB_TYPE_AES)
  419. #define IPX_ECB_PARM() RetrieveEcb(ECB_TYPE_IPX)
  420. #define IPX_SOCKET_PARM() getDX()
  421. #define IPX_SOCKET_LIFE_PARM() (BYTE)getBP()
  422. #define IPX_SOCKET_OWNER_PARM() getCX()
  423. #define IPX_BUFFER_PARM(s) (ULPBYTE)POINTER_FROM_WORDS(getES(), getSI(), (s))
  424. #define IPX_TICKS_PARM() getBP()
  425. #define SPX_RETRY_COUNT_PARM() (BYTE)getBP()
  426. #define SPX_WATCHDOG_FLAG_PARM() ((BYTE)(getBP() >> 8))
  427. #define SPX_ECB_PARM() RetrieveEcb(ECB_TYPE_IPX)
  428. #define SPX_CONNECTION_PARM() getDX()
  429. #define SPX_BUFFER_PARM(s) (ULPBYTE)POINTER_FROM_WORDS(getES(), getSI(), (s))
  430. //
  431. // IPX error codes - same codes used in different circumstances
  432. //
  433. #define IPX_SUCCESS 0x00
  434. #define IPX_CANNOT_CANCEL 0xF9
  435. #define IPX_NO_PATH_TO_DESTINATION 0xFA
  436. #define IPX_CANCELLED 0xFC
  437. #define IPX_BAD_REQUEST 0xFD
  438. #define IPX_SOCKET_TABLE_FULL 0xFE
  439. #define IPX_UNDELIVERABLE 0xFE
  440. #define IPX_SOCKET_ALREADY_OPEN 0xFF
  441. #define IPX_HARDWARE_ERROR 0xFF
  442. #define IPX_NON_EXISTENT_SOCKET 0xFF
  443. #define IPX_ECB_NOT_IN_USE 0xFF
  444. //
  445. // SPX error codes - same codes used in different circumstances
  446. //
  447. #define SPX_SUCCESS 0x00
  448. #define SPX_CONNECTION_TERMINATED 0xEC
  449. #define SPX_CONNECTION_ABORTED 0xED
  450. #define SPX_INVALID_CONNECTION 0xEE
  451. #define SPX_CONNECTION_TABLE_FULL 0xEF
  452. #define SPX_SOCKET_CLOSED 0xFC
  453. #define SPX_PACKET_OVERFLOW 0xFD
  454. #define SPX_BAD_SEND_REQUEST 0xFD // malformed packet
  455. #define SPX_BAD_LISTEN_REQUEST 0xFF
  456. #define SPX_NON_EXISTENT_SOCKET 0xFF
  457. #endif // _VWIPXSPX_H_