summaryrefslogtreecommitdiffstats
path: root/private/nw/vwipxspx/dll/vwipxspx.h
blob: 01ad6ec5a9b57112f29dfa07d85b60ce5aad58c2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
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_