IPXMGR.H (19793B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: F:\projects\c&c\vcs\code\ipxmgr.h_v 1.10 16 Oct 1995 16:47:34 JOE_BOSTIC $ */ 17 /*************************************************************************** 18 ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ** 19 *************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : IPXMGR.H * 24 * * 25 * Programmer : Bill Randolph * 26 * * 27 * Start Date : December 19, 1994 * 28 * * 29 * Last Update : April 3, 1995 [BR] * 30 * * 31 *-------------------------------------------------------------------------* 32 * * 33 * This is the Connection Manager for IPX network communications. It * 34 * creates, manages, & orchestrates multiple IPX connections, as well as * 35 * the "global" connection ("Global Channel"), which can talk to any * 36 * system on the net. * 37 * * 38 * Use the Global Channel to query systems for their names, ID's, & * 39 * IPX addresses. Then, create a Private Connection with each system * 40 * that joins your game, and use the Private Channel to send game packets * 41 * (the private channel will perform somewhat faster, & gives you better * 42 * control than the Global Channel; it can detect retries, and the Global * 43 * Channel can't). * 44 * * 45 * HOW THIS CLASS WORKS: * 46 * This class has to set up an IPX Event Service Routine in low (DOS) * 47 * memory. So, it uses DPMI to allocate & lock a chunk of DOS memory; * 48 * this memory is used for all incoming packet buffers, the outgoing * 49 * packet buffer, and the actual code for the event handler. The real- * 50 * mode handler code & this class share a portion of memory that's mapped * 51 * into a "RealModeDataType" structure. As packets come in, the handler * 52 * points IPX to the next available packet buffer & restarts listening; * 53 * it sets a flag to tell this class that a packet is present at that * 54 * buffer slot. This class must read all the packets & determine which * 55 * connection they go with (the Global Channel, or one of the Private * 56 * Channels). This parsing is done in the Service routine for this class. * 57 * * 58 * Constructor: Just inits some variables, checks to see if IPX is there * 59 * Destructor: Complete shutdown; stops IPX listening, frees all memory * 60 * Init: Should only be called once (but can be called more); * 61 * allocates all memory, creates the Global Channel * 62 * connection, starts IPX listening. By not placing this * 63 * step in the constructor, the app can control when * 64 * listening actually starts; also, you don't get a bunch * 65 * of allocations just by declaring an IPXManagerClass * 66 * instance. You have to call Init() for the allocations * 67 * to occur. * 68 * Connection utilities: Create & manage Private Connections. Each * 69 * connection has its own IPX address, numerical ID, and * 70 * character name (presumably the name of the other * 71 * player). * 72 * Send/Get_Global_Message: adds a packet to the Global Connection queue, * 73 * or reads from the queue. The caller should check the * 74 * ProductID value from returned packets to be sure it's * 75 * talking to the right product. * 76 * Send/Get_Private_Message: adds a packet to a Private Connection queue, * 77 * or reads from the queue * 78 * Service: Checks the Real-Mode-Memory packet array to see if any * 79 * new packets have come in; if they have, it parses them * 80 * & distributes them to the right connection queue. The * 81 * queue's Service routine handles ACK'ing or Resending * 82 * packets. * 83 * * 84 * Here's a memory map of the Real-Mode memory block. 'N' is the number * 85 * of packet buffers allocated in low memory: * 86 * * 87 * ---------------------------------- * 88 * | Shared-memory data | * 89 * |--------------------------------| * 90 * | Real-mode event handler code | * 91 * |--------------------------------| * 92 * | IPX Header & Packet Buffer 0 | * 93 * |--------------------------------| * 94 * | IPX Header & Packet Buffer 1 | * 95 * |--------------------------------| * 96 * | IPX Header & Packet Buffer 2 | * 97 * |--------------------------------| * 98 * | . . . | * 99 * |--------------------------------| * 100 * | IPX Header & Packet Buffer N | * 101 * |--------------------------------| * 102 * | Send Event Control Block | * 103 * |--------------------------------| * 104 * | Send IPX Header | * 105 * |--------------------------------| * 106 * | Send Packet Buffer | * 107 * |--------------------------------| * 108 * | Flags Array [N] | * 109 * ---------------------------------- * 110 * * 111 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 112 113 #ifndef IPXMANAGER_H 114 #define IPXMANAGER_H 115 116 117 /* 118 ********************************* Includes ********************************** 119 */ 120 #include "ipxconn.h" 121 #include "ipxgconn.h" 122 #include "ipxaddr.h" 123 #include "connmgr.h" 124 125 /* 126 ********************************** Defines ********************************** 127 */ 128 /*--------------------------------------------------------------------------- 129 This is Virgin Interactive Entertainment's registered socket ID. 130 ---------------------------------------------------------------------------*/ 131 #define VIRGIN_SOCKET 0x8813 132 133 /*--------------------------------------------------------------------------- 134 This is the maximum number of IPX connections supported. Just change this 135 value to support more. 136 ---------------------------------------------------------------------------*/ 137 #define CONNECT_MAX 6 138 139 /*--------------------------------------------------------------------------- 140 These routines report the location & length of the real-mode routine, as 141 it's stored in protected-mode memory. 142 ---------------------------------------------------------------------------*/ 143 extern "C" { 144 void *Get_RM_IPX_Address(void); 145 long Get_RM_IPX_Size(void); 146 } 147 148 /* 149 ***************************** Class Declaration ***************************** 150 */ 151 class IPXManagerClass : public ConnManClass 152 { 153 /* 154 ---------------------------- Public Interface ---------------------------- 155 */ 156 public: 157 /*..................................................................... 158 Constructor/destructor. 159 .....................................................................*/ 160 IPXManagerClass (int glb_maxlen, int pvt_maxlen, int glb_num_packets, 161 int pvt_num_packets, unsigned short socket, unsigned short product_id); 162 virtual ~IPXManagerClass (); // stop listening 163 164 /*..................................................................... 165 Initialization routines. 166 .....................................................................*/ 167 int Init (void); 168 int Is_IPX(void); 169 virtual void Set_Timing (unsigned long retrydelta, unsigned long maxretries, 170 unsigned long timeout); 171 void Set_Bridge(NetNumType bridge); 172 173 /*..................................................................... 174 These routines control creation of the "Connections" (data queues) for 175 each remote system. 176 .....................................................................*/ 177 bool Create_Connection(int id, char *name, IPXAddressClass *address); 178 bool Delete_Connection(int id); 179 virtual int Num_Connections(void); 180 virtual int Connection_ID(int index); 181 char *Connection_Name(int id); 182 IPXAddressClass * Connection_Address(int id); 183 virtual int Connection_Index(int id); 184 185 /*..................................................................... 186 This is how the application sends & receives messages. 187 .....................................................................*/ 188 int Send_Global_Message (void *buf, int buflen, int ack_req = 0, 189 IPXAddressClass *address = NULL); 190 int Get_Global_Message (void *buf, int *buflen, IPXAddressClass *address, 191 unsigned short *product_id); 192 193 virtual int Send_Private_Message (void *buf, int buflen, 194 int ack_req = 1, int conn_id = CONNECTION_NONE); 195 virtual int Get_Private_Message (void *buf, int *buflen, int *conn_id); 196 197 /*..................................................................... 198 The main polling routine; should be called as often as possible. 199 .....................................................................*/ 200 virtual int Service (void); 201 202 /*..................................................................... 203 This routine reports which connection has an error on it. 204 .....................................................................*/ 205 int Get_Bad_Connection(void); 206 207 /*..................................................................... 208 Queue utility routines. The application can determine how many 209 messages are in the send/receive queues. 210 .....................................................................*/ 211 virtual int Global_Num_Send(void); 212 virtual int Global_Num_Receive(void); 213 virtual int Private_Num_Send(int id = CONNECTION_NONE); 214 virtual int Private_Num_Receive(int id = CONNECTION_NONE); 215 216 /*..................................................................... 217 This routine changes the socket ID assigned the IPX Manager when it 218 was constructed. Do not call this function after calling Init()! 219 The Socket ID should be known by both ends of the communications before 220 any packets are sent. 221 .....................................................................*/ 222 void Set_Socket(unsigned short socket); 223 224 /*..................................................................... 225 Routines to return the largest average queue response time, and to 226 reset the response time for all queues. 227 .....................................................................*/ 228 virtual unsigned long Response_Time(void); 229 unsigned long Global_Response_Time(void); 230 virtual void Reset_Response_Time(void); 231 232 /*..................................................................... 233 This routine returns a pointer to the oldest non-ACK'd buffer I've sent. 234 .....................................................................*/ 235 void * Oldest_Send(void); 236 237 /*..................................................................... 238 Debug routines 239 .....................................................................*/ 240 virtual void Configure_Debug(int index, int offset, int size, 241 char **names, int maxnames); 242 virtual void Mono_Debug_Print(int index, int refresh = 0); 243 244 /* 245 --------------------------- Private Interface ---------------------------- 246 */ 247 private: 248 /*..................................................................... 249 These routines allocate & free the DOS Real-mode memory block. 250 .....................................................................*/ 251 int Alloc_RealMode_Mem(void); 252 int Free_RealMode_Mem(void); 253 254 /*..................................................................... 255 Misc variables 256 .....................................................................*/ 257 unsigned int IPXStatus : 1; // 0 = no IPX, 1 = IPX found 258 unsigned int Listening : 1; // 1 = Listening is on 259 unsigned int RealMemAllocd : 1; // 1 = Real-mode memory has been alloc'd 260 261 /*..................................................................... 262 Packet Sizes, used for allocating real-mode memory 263 .....................................................................*/ 264 int Glb_MaxPacketLen; // Global Channel maximum packet size 265 int Glb_NumPackets; // # Global send/receive packets 266 int Pvt_MaxPacketLen; // Private Channel maximum packet size 267 int Pvt_NumPackets; // # Private send/receive packets 268 269 /*..................................................................... 270 The ProductID is used in the Global Channel's packet header, and it's 271 used for the Private Channels' Magic Number. 272 .....................................................................*/ 273 unsigned short ProductID; // product ID 274 275 /*..................................................................... 276 The Socket ID, and local Novell Connection Number 277 .....................................................................*/ 278 unsigned short Socket; // Our socket ID for sending/receiving 279 int ConnectionNum; // local connection #, 0=not logged in 280 281 /*..................................................................... 282 Array of connection queues 283 .....................................................................*/ 284 IPXConnClass * Connection[CONNECT_MAX]; // array of connection object ptrs 285 int NumConnections; // # connection objects in use 286 IPXGlobalConnClass *GlobalChannel; // the Global Channel 287 288 /*..................................................................... 289 Current queue for polling for received packets 290 .....................................................................*/ 291 int CurConnection; 292 293 /*..................................................................... 294 Timing parameters for all connections 295 .....................................................................*/ 296 unsigned long RetryDelta; 297 unsigned long MaxRetries; 298 unsigned long Timeout; 299 300 /*--------------------------------------------------------------------- 301 Real-mode memory pointers and such 302 ---------------------------------------------------------------------*/ 303 /*..................................................................... 304 This is a structure that mirrors data in real-mode memory: 305 .....................................................................*/ 306 typedef struct { 307 short Marker1; // the byte ID marker 308 ECBType ListenECB; // the Listening ECB 309 short NumBufs; // # of buffers we're giving to the handler 310 char *BufferFlags; // array of buffer-avail flags 311 short PacketSize; // size of packet including IPX header 312 IPXHeaderType *FirstPacketBuf; // ptr to 1st packet buffer 313 short CurIndex; // handler's current packet index 314 IPXHeaderType *CurPacketBuf; // handler's current packet buf 315 short FuncOffset; // contains offset of code 316 char Semaphore; // prevents re-entrancy 317 short ReEntrantCount; // times we've been called re-entrantly 318 short StackPtr; // real-mode stack pointer 319 short StackSeg; // real-mode stack segment 320 short StackPtr_int; // internal stack pointer 321 short StackSeg_int; // internal stack segment 322 short StackCheck; // stack check value (0x1234) 323 short Stack[256]; // actual stack space 324 short StackSpace; // label for top of stack 325 short Marker2; // the byte ID marker 326 } RealModeDataType; 327 328 /*..................................................................... 329 The number & size of packet buffers in low memory 330 .....................................................................*/ 331 int NumBufs; // # packet buffers allocated 332 int PacketLen; // size of packet without IPX header 333 int FullPacketLen; // size of packet including IPX header 334 335 /*..................................................................... 336 Selector & Segment of the DOS allocation; 337 Size of the allocation; 338 Ptr to the real-mode assembly data area 339 .....................................................................*/ 340 unsigned short Selector; // selector of DOS allocation pointer 341 unsigned short Segment; // real-mode segment of DOS allocation 342 int RealMemSize; // size of real mode memory allocated 343 RealModeDataType *RealModeData; // assembly routine & its data 344 345 /*..................................................................... 346 This is a real-mode pointer to the address of the real-mode assembly 347 entry point. 348 .....................................................................*/ 349 long Handler; 350 351 /*..................................................................... 352 Event Control Block for listening; contained within the real-mode 353 assembly routine's data area 354 .....................................................................*/ 355 ECBType *ListenECB; // ECB for listening 356 357 /*..................................................................... 358 ptr to the 1st header & data buffers in the packet buffer array 359 .....................................................................*/ 360 IPXHeaderType *FirstHeaderBuf; // array of packet headers & buffers 361 char *FirstDataBuf; // 1st data buffer area 362 363 /*..................................................................... 364 Current packet index & ptrs for parsing packets 365 .....................................................................*/ 366 int CurIndex; // Current packet index, for reading 367 IPXHeaderType *CurHeaderBuf; // Current packet ptr, for reading 368 char *CurDataBuf; // Current actual data ptr 369 370 /*..................................................................... 371 ECB, header, & buffer for sending 372 .....................................................................*/ 373 ECBType *SendECB; // ECB for sending 374 IPXHeaderType *SendHeader; // Header for sending 375 char *SendBuf; // buffer for sending 376 377 /*..................................................................... 378 Flags indicating whether a buffer contains data or not (1 = full) 379 The IPXManager must clear this flag; the real-mode routine will set it. 380 .....................................................................*/ 381 char *BufferFlags; // array of rx-buffer-avail flags 382 383 /*..................................................................... 384 Various Statistics 385 .....................................................................*/ 386 int SendOverflows; 387 int ReceiveOverflows; 388 int BadConnection; 389 }; 390 391 #endif 392 /*************************** end of ipxmgr.h *******************************/