diff options
Diffstat (limited to '')
-rw-r--r-- | private/nw/vwipxspx/dll/vwipxspx.h | 586 |
1 files changed, 586 insertions, 0 deletions
diff --git a/private/nw/vwipxspx/dll/vwipxspx.h b/private/nw/vwipxspx/dll/vwipxspx.h new file mode 100644 index 000000000..01ad6ec5a --- /dev/null +++ b/private/nw/vwipxspx/dll/vwipxspx.h @@ -0,0 +1,586 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + vwipxspx.h + +Abstract: + + Contains manifests, typedefs, structures, macros for NTVDM IPX/SPX support + +Author: + + Richard L Firth (rfirth) 30-Sep-1993 + +Environment: + + Structures are expected to live in segmented VDM address space, but be + accessible from flat 32-bit protect mode. The VDM can be in real or protect + mode + +Revision History: + + 30-Sep-1993 rfirth + Created + +--*/ + +#ifndef _VWIPXSPX_H_ +#define _VWIPXSPX_H_ + +// +// FREE_OBJECT - in free version, just calls LocalFree. For debug version, fills +// memory with some arbitrary value, then frees the pointer and checks that what +// LocalFree thought that the pointer pointed at a valid, freeable object +// + +#if DBG + +#define FREE_OBJECT(p) {\ + FillMemory(p, sizeof(*p), 0xFF);\ + VWASSERT(LocalFree((HLOCAL)(p)), NULL);\ + } +#else + +#define FREE_OBJECT(p) VWASSERT(LocalFree((HLOCAL)(p)), NULL) + +#endif + +// +// simple function macros +// + +//#define AllocateXecb() (LPXECB)LocalAlloc(LPTR, sizeof(XECB)) +//#define DeallocateXecb(p) FREE_OBJECT(p) +#define AllocateBuffer(s) (LPVOID)LocalAlloc(LMEM_FIXED, (s)) +#define DeallocateBuffer(p) FREE_OBJECT(p) + +// +// pseudo-types for 16-bit addresses +// + +#define ESR_ADDRESS DWORD +#define ECB_ADDRESS DWORD + +// +// from Novell documentation, the default maximum open sockets. Max max is 150 +// + +#ifndef DEFAULT_MAX_OPEN_SOCKETS +#define DEFAULT_MAX_OPEN_SOCKETS 20 +#endif + +#ifndef MAX_OPEN_SOCKETS +#define MAX_OPEN_SOCKETS 150 +#endif + +#define SPX_INSTALLED 0xFF + +#define MAX_LISTEN_QUEUE_SIZE 5 // ? + +// +// misc. macros +// + +// +// B2LW, L2Bx - big-endian to little-endian macros +// + +#define B2LW(w) (WORD)(((WORD)(w) << 8) | ((WORD)(w) >> 8)) +#define B2LD(d) (DWORD)(B2LW((DWORD)(d) << 16) | B2LW((DWORD)(d) >> 16)) +#define L2BW(w) B2LW(w) +#define L2BD(d) B2LD(d) + +// +// miscellaneous manifests +// + +#define ONE_TICK (1000/18) // 1/18 sec in milliseconds (55.55 mSec) +#define SLEEP_TIME ONE_TICK // amount of time we Sleep() during IPXRelinquishControl + +// +// options for IPXGetInformation +// + +#define IPX_ODI 0x0001 +#define IPX_CHECKSUM_FUNCTIONS 0x0002 + +// +// IPX/SPX structures. The following structures are in VDM format, and should +// be packed on a byte-boundary +// +// Netware maintains certain structure fields in network (big-endian) format +// + +#include <packon.h> + +// +// INTERNET_ADDRESS - structure returned by IPXGetInternetworkAddress +// + +typedef struct { + BYTE Net[4]; + BYTE Node[6]; +} INTERNET_ADDRESS ; + +typedef INTERNET_ADDRESS UNALIGNED *LPINTERNET_ADDRESS; + +// +// NETWARE_ADDRESS - address of an application on the network, as defined by +// its network segment, node address and socket number +// + +typedef struct { + BYTE Net[4]; // hi-lo + BYTE Node[6]; // hi-lo + WORD Socket; // hi-lo +} NETWARE_ADDRESS ; + +typedef NETWARE_ADDRESS UNALIGNED *LPNETWARE_ADDRESS; + +// +// FRAGMENT - ECB/IPX/SPX buffers are split into 'fragments' +// + +typedef struct { + LPVOID Address; // offset-segment + WORD Length; // hi-lo +} FRAGMENT ; + +typedef FRAGMENT UNALIGNED *LPFRAGMENT; + +// +// IPX_PACKET - format of packet submitted to IPX for sending. The maximum +// size of an IPX packet is 576 bytes, 30 bytes header, 546 bytes data +// + +typedef struct { + WORD Checksum; // always set to 0xFFFF + WORD Length; // set by IPX - header + data + BYTE TransportControl; // set by IPX to 0. Used by routers + + // + // for IPX, PacketType is 0 (Unknown Packet Type) or 4 (Packet Exchange + // Packet) + // + + BYTE PacketType; + NETWARE_ADDRESS Destination; + NETWARE_ADDRESS Source; + BYTE Data[]; // 546 bytes max. +} IPX_PACKET ; + +typedef IPX_PACKET UNALIGNED *LPIPX_PACKET; + +#define IPX_HEADER_LENGTH sizeof(IPX_PACKET) +#define MAXIMUM_IPX_PACKET_LENGTH 576 +#define MAXIMUM_IPX_DATA_LENGTH (MAXIMUM_IPX_PACKET_LENGTH - IPX_HEADER_LENGTH) + +#define IPX_PACKET_TYPE 4 + +// +// SPX_PACKET - format of packet submitted to SPX for sending. The maximum +// size of an SPX packet is 576 bytes, 42 bytes header, 534 bytes data +// + +typedef struct { + WORD Checksum; // always set to 0xFFFF + WORD Length; // set by IPX - header + data + BYTE TransportControl; // set by IPX to 0. Used by routers + + // + // for SPX, PacketType is set to 5 (Sequenced Packet Protocol Packet) + // + + BYTE PacketType; + NETWARE_ADDRESS Destination; + NETWARE_ADDRESS Source; + + // + // ConnectionControl is a bitmap which control bi-directional flow over a + // link. The bits are defined (by Xerox SPP) as: + // + // 0-3 undefined + // 4 end-of-message + // This is the only bit which can be directly manipulated by an + // app. The bit is passed through unchanged by SPX + // 5 attention + // Ignored by SPX, but passed through + // 6 acknowledge + // Set by SPX if an ack is required + // 7 system packet + // Set by SPX if the packet is internal control. An app should + // never see this bit (i.e. should never see a system packet) + // + + BYTE ConnectionControl; + + // + // DataStreamType defines the type of data in the packet: + // + // 0x00 - 0xFD client-defined. + // Ignored by SPX + // 0xFE end-of-connection. + // When active connection is terminated, SPX + // generates and sends a packet with this bit set. + // This will be the last packet sent on the connection + // 0xFF end-of-connection acknowledgement + // SPX generates a system packet to acknowledge an + // end-of-connection packet + // + + BYTE DataStreamType; + WORD SourceConnectId; // assigned by SPX + WORD DestinationConnectId; + WORD SequenceNumber; // managed by SPX + WORD AckNumber; // managed by SPX + WORD AllocationNumber; // managed by SPX + BYTE Data[]; // 534 bytes max. + +} SPX_PACKET ; + +typedef SPX_PACKET UNALIGNED *LPSPX_PACKET; + +#define SPX_HEADER_LENGTH sizeof(SPX_PACKET) +#define MAXIMUM_SPX_PACKET_LENGTH MAXIMUM_IPX_PACKET_LENGTH +#define MAXIMUM_SPX_DATA_LENGTH (MAXIMUM_SPX_PACKET_LENGTH - SPX_HEADER_LENGTH) + +#define SPX_PACKET_TYPE 5 + +// +// ConnectionControl flags +// + +#define SPX_CONNECTION_RESERVED 0x0F +#define SPX_END_OF_MESSAGE 0x10 +#define SPX_ATTENTION 0x20 +#define SPX_ACK_REQUIRED 0x40 +#define SPX_SYSTEM_PACKET 0x80 + +// +// DataStreamType values +// + +#define SPX_DS_ESTABLISH 0x00 +#define SPX_DS_TERMINATE 0xfe + +// +// IPX_ECB - Event Control Block. This structure is used by most IPX/SPX APIs, +// especially when deferred IPX/AES processing is required. The following +// structure is a socket-based ECB +// + +typedef struct { + + // + // LinkAddress is reserved for use by IPX. We use it to link the ECB onto + // a queue. We appropriate the space used for an x86 segmented address + // (real or protect mode) as a flat 32-bit pointer + // + + ULPVOID LinkAddress; // offset-segment + + // + // EsrAddress is non-NULL if an Event Service Routine will be called when + // the event described by the ECB completes. This will always be an x86 + // segmented address (real or protect mode) + // + + ESR_ADDRESS EsrAddress; // offset-segment + + // + // IPX uses the InUse field to mark the ECB as owned by IPX (!0) or by the + // app (0): + // + // 0xF8 App tried to send a packet while IPX was busy; IPX queued + // the ECB + // 0xFA IPX is processing the ECB + // 0xFB IPX has used the ECB for some event and put it on a queue + // for processing + // 0xFC the ECB is waiting for an AES event to occur + // 0xFD the ECB is waiting for an IPX event to occur + // 0xFE IPX is listening on a socket for incoming packets + // 0xFF IPX is using the ECB to send a packet + // + + BYTE InUse; + + // + // CompletionCode is used to return a status from a deferred request. This + // field is not valid until InUse has been set to 0 + // + // NOTE: We have to differentiate between AES and IPX ECBs on callbacks: due + // to their different sizes, we store the 16-bit segment and offset in + // different places. In order to differentiate the ECBs, we use CompletionCode + // field (AesWorkspace[0]) as the owner. The real CompletionCode for IPX ECBs + // goes in IPX_ECB_COMPLETE (DriverWorkspace[7]). But only for completed ECBs + // that have an ESR + // + + BYTE CompletionCode; + WORD SocketNumber; // hi-lo + + // + // the first word of IpxWorkspace is used to return the connection ID of + // an SPX connection + // + + DWORD IpxWorkspace; + BYTE DriverWorkspace[12]; + + // + // ImmediateAddress is the local network node at the remote end of this + // connection. It is either the node address of the remote machine if it + // is on this LAN, or it is the node address of the router if the remote + // machine is on a different LAN + // + // This field must be initialized when talking over IPX, but not SPX + // + + BYTE ImmediateAddress[6]; + + // + // FragmentCount - number of FRAGMENT structures that comprise the request. + // Must be at least 1 + // + + WORD FragmentCount; + + // + // FragmentCount fragments start here + // + +} IPX_ECB ; + +typedef IPX_ECB UNALIGNED *LPIPX_ECB; + +// +// ECB InUse values +// + +#define ECB_IU_NOT_IN_USE 0x00 +#define ECB_IU_TEMPORARY 0xCC +#define ECB_IU_LISTENING_SPX 0xF7 // same as win16 (by observation) +#define ECB_IU_SEND_QUEUED 0xF8 +#define ECB_IU_AWAITING_CONNECTION 0xF9 // same as win16 (by observation) +#define ECB_IU_BEING_PROCESSED 0xFA +#define ECB_IU_AWAITING_PROCESSING 0xFB +#define ECB_IU_AWAITING_AES_EVENT 0xFC +#define ECB_IU_AWAITING_IPX_EVENT 0xFD +#define ECB_IU_LISTENING 0xFE +#define ECB_IU_SENDING 0xFF + +// +// ECB CompletionCode values +// + +#define ECB_CC_SUCCESS 0x00 +#define ECB_CC_CONNECTION_TERMINATED 0xEC +#define ECB_CC_CONNECTION_ABORTED 0xED +#define ECB_CC_INVALID_CONNECTION 0xEE +#define ECB_CC_CONNECTION_TABLE_FULL 0xEF +#define ECB_CC_CANNOT_CANCEL 0xF9 +#define ECB_CC_CANCELLED 0xFC +#define ECB_CC_BAD_REQUEST 0xFD +#define ECB_CC_BAD_SEND_REQUEST 0xFD +#define ECB_CC_PACKET_OVERFLOW 0xFD +#define ECB_CC_UNDELIVERABLE 0xFE +#define ECB_CC_SOCKET_TABLE_FULL 0xFE +#define ECB_CC_BAD_LISTEN_REQUEST 0xFF +#define ECB_CC_HARDWARE_ERROR 0xFF +#define ECB_CC_NON_EXISTENT_SOCKET 0xFF + +// +// we commandeer certain (reserved) fields for our own internal use: +// +// LPECB EcbLink LinkAddress +// PVOID Buffer32 DriverWorkspace[0] +// WORD Length32 DriverWorkspace[4] +// WORD Flags32 DriverWorkspace[6] +// WORD OriginalEs DriverWorkspace[8] +// WORD OriginalSi DriverWorkspace[10] +// + +#define ECB_TYPE(p) (((LPIPX_ECB)(p))->CompletionCode) +#define IPX_ECB_SEGMENT(p) (WORD)*((ULPWORD)&(((LPIPX_ECB)(p))->IpxWorkspace)+0) +#define IPX_ECB_OFFSET(p) (WORD)*((ULPWORD)&(((LPIPX_ECB)(p))->IpxWorkspace)+2) +#define IPX_ECB_BUFFER32(p) (ULPVOID)*(ULPVOID*)&(((LPIPX_ECB)(p))->DriverWorkspace[0]) +#define IPX_ECB_LENGTH32(p) (WORD)*(ULPWORD)&(((LPIPX_ECB)(p))->DriverWorkspace[4]) +#define IPX_ECB_FLAGS32(p) (((LPIPX_ECB)(p))->DriverWorkspace[6]) +#define IPX_ECB_COMPLETE(p) (((LPIPX_ECB)(p))->DriverWorkspace[7]) + +#define SPX_ECB_CONNECTION_ID(p) (WORD)*(ULPWORD)&(((LPIPX_ECB)(p))->IpxWorkspace) + +// +// ECB Flags32 flags +// + +#define ECB_FLAG_BUFFER_ALLOCATED 0x01 + +// +// ECB types +// + +#define ECB_TYPE_AES 0 +#define ECB_TYPE_IPX 1 +#define ECB_TYPE_SPX 2 + +// +// ECB owners +// + +#define ECB_OWNER_IPX 0xFF +#define ECB_OWNER_AES 0x00 + +// +// ECB_FRAGMENT - macro which gives the address of the first fragment structure +// within a socket-based ECB +// + +#define ECB_FRAGMENT(p, n) ((LPFRAGMENT)(((LPIPX_ECB)(p) + 1)) + (n)) + +// +// AES_ECB - used by AES, these socket-less ECBs are used to schedule events +// + +typedef struct { + ULPVOID LinkAddress; // offset-segment + ESR_ADDRESS EsrAddress; // offset-segment + BYTE InUse; + + // + // first 3 bytes overlay CompletionCode (1) and SocketNumber (2) fields of + // IPX_ECB. Last 2 bytes overlay first 2 bytes of IpxWorkspace (4) field of + // IPX_ECB. We use the 1st byte of the common unused fields as the ECB type + // (send/receive/timed-event) + // + + BYTE AesWorkspace[5]; +} AES_ECB ; + +typedef AES_ECB UNALIGNED *LPAES_ECB; + +// +// as with IPX_ECB, we 'borrow' some of the reserved fields for our own use +// + +#define AES_ECB_SEGMENT(p) (WORD)*(ULPWORD)&(((LPAES_ECB)(p))->AesWorkspace[1]) +#define AES_ECB_OFFSET(p) (WORD)*(ULPWORD)&(((LPAES_ECB)(p))->AesWorkspace[3]) + +// +// LPECB - points to either IPX_ECB or AES_ECB. Both in VDM workspace +// + +#define LPECB LPIPX_ECB + +// +// SPX_CONNECTION_STATS - returned by SPXGetConnectionStatus. All WORD fields +// are to be returned HiLo (ie to Hawaii). All fields come back from NT SPX +// transport in HiLo format also (this was changed recently, used to be in +// Intel order). +// + +typedef struct { + BYTE State; + BYTE WatchDog; + WORD LocalConnectionId; + WORD RemoteConnectionId; + WORD LocalSequenceNumber; + WORD LocalAckNumber; + WORD LocalAllocNumber; + WORD RemoteAckNumber; + WORD RemoteAllocNumber; + WORD LocalSocket; + BYTE ImmediateAddress[6]; + BYTE RemoteNetwork[4]; + BYTE RemoteNode[6]; + WORD RemoteSocket; + WORD RetransmissionCount; + WORD EstimatedRoundTripDelay; + WORD RetransmittedPackets; + WORD SuppressedPackets; +} SPX_CONNECTION_STATS ; + +typedef SPX_CONNECTION_STATS UNALIGNED* LPSPX_CONNECTION_STATS; + +#include <packoff.h> + +// +// 16-bit parameter get/set macros. These may change depending on requirements +// of real/protect mode parameters (e.g. stack based vs. register based) +// + +#define IPX_GET_AES_ECB(p) (p) = (LPAES_ECB)POINTER_FROM_WORDS(getES(), getSI(), sizeof(AES_ECB)) +#define IPX_GET_IPX_ECB(p) (p) = (LPIPX_ECB)POINTER_FROM_WORDS(getES(), getSI(), sizeof(IPX_ECB)) +#define IPX_GET_SOCKET(s) (s) = (WORD)getDX() +#define IPX_GET_SOCKET_LIFE(l) (l) = (BYTE)getBP() +#define IPX_GET_SOCKET_OWNER(o) (o) = (WORD)getCX() +#define IPX_GET_BUFFER(p, s) (p) = (ULPBYTE)POINTER_FROM_WORDS(getES(), getSI(), (s)) +#define IPX_GET_ECB_SEGMENT() getES() +#define IPX_GET_ECB_OFFSET() getSI() + +#define IPX_SET_STATUS(s) setAL((BYTE)(s)) +#define IPX_SET_SOCKET(s) setDX((WORD)(s)) +#define IPX_SET_INFORMATION(v) setDX((WORD)(v)) + +#define SPX_SET_STATUS(s) setAL((BYTE)(s)) +#define SPX_SET_CONNECTION_ID(i) setDX((WORD)(i)) + +// +// macros returning 16-bit API parameters - may fetch register contents or values +// from stack/memory +// + +#define ECB_PARM_SEGMENT() getES() +#define ECB_PARM_OFFSET() getSI() +#define ECB_PARM_ADDRESS() (ECB_ADDRESS)MAKELONG(getSI(), getES()) + +#define AES_ECB_PARM() RetrieveEcb(ECB_TYPE_AES) + +#define IPX_ECB_PARM() RetrieveEcb(ECB_TYPE_IPX) +#define IPX_SOCKET_PARM() getDX() +#define IPX_SOCKET_LIFE_PARM() (BYTE)getBP() +#define IPX_SOCKET_OWNER_PARM() getCX() +#define IPX_BUFFER_PARM(s) (ULPBYTE)POINTER_FROM_WORDS(getES(), getSI(), (s)) +#define IPX_TICKS_PARM() getBP() + +#define SPX_RETRY_COUNT_PARM() (BYTE)getBP() +#define SPX_WATCHDOG_FLAG_PARM() ((BYTE)(getBP() >> 8)) +#define SPX_ECB_PARM() RetrieveEcb(ECB_TYPE_IPX) +#define SPX_CONNECTION_PARM() getDX() +#define SPX_BUFFER_PARM(s) (ULPBYTE)POINTER_FROM_WORDS(getES(), getSI(), (s)) + +// +// IPX error codes - same codes used in different circumstances +// + +#define IPX_SUCCESS 0x00 +#define IPX_CANNOT_CANCEL 0xF9 +#define IPX_NO_PATH_TO_DESTINATION 0xFA +#define IPX_CANCELLED 0xFC +#define IPX_BAD_REQUEST 0xFD +#define IPX_SOCKET_TABLE_FULL 0xFE +#define IPX_UNDELIVERABLE 0xFE +#define IPX_SOCKET_ALREADY_OPEN 0xFF +#define IPX_HARDWARE_ERROR 0xFF +#define IPX_NON_EXISTENT_SOCKET 0xFF +#define IPX_ECB_NOT_IN_USE 0xFF + +// +// SPX error codes - same codes used in different circumstances +// + +#define SPX_SUCCESS 0x00 +#define SPX_CONNECTION_TERMINATED 0xEC +#define SPX_CONNECTION_ABORTED 0xED +#define SPX_INVALID_CONNECTION 0xEE +#define SPX_CONNECTION_TABLE_FULL 0xEF +#define SPX_SOCKET_CLOSED 0xFC +#define SPX_PACKET_OVERFLOW 0xFD +#define SPX_BAD_SEND_REQUEST 0xFD // malformed packet +#define SPX_BAD_LISTEN_REQUEST 0xFF +#define SPX_NON_EXISTENT_SOCKET 0xFF + +#endif // _VWIPXSPX_H_ |