windows-nt/Source/XPSP1/NT/net/nwlink/spx/spxconn.h
2020-09-26 16:20:57 +08:00

1675 lines
51 KiB
C

/*++
Copyright (c) 1989-1993 Microsoft Corporation
Module Name:
spxconn.h
Abstract:
Author:
Nikhil Kamkolkar (nikhilk) 11-November-1993
Environment:
Kernel mode
Revision History:
Sanjay Anand (SanjayAn) 5-July-1995
Bug fixes - tagged [SA]
--*/
// Minimum value for RTT in ms.
// Have these be a derivate of registry values.
#define SPX_T1_MIN 200
#define MAX_RETRY_DELAY 5000 // 5 seconds
#define SPX_DEF_RENEG_RETRYCOUNT 1 // All reneg pkts except min sent once
// Some types
typedef enum
{
SPX_CALL_RECVLEVEL,
SPX_CALL_TDILEVEL
} SPX_CALL_LEVEL;
typedef enum
{
SPX_REQ_DATA,
SPX_REQ_ORDREL,
SPX_REQ_DISC
} SPX_SENDREQ_TYPE;
// This structure is pointed to by the FsContext field in the FILE_OBJECT
// for this Connection.
#define CFREF_CREATE 0
#define CFREF_VERIFY 1
#define CFREF_INDICATION 2
#define CFREF_BYCTX 3
#define CFREF_BYID 4
#define CFREF_ADDR 5
#define CFREF_REQ 6
#define CFREF_TIMER 7
#define CFREF_PKTIZE 8
#define CFREF_RECV 9
#define CFREF_ABORTPKT 10
#define CFREF_ERRORSTATE 11
#define CFREF_FINDROUTE 12
//
// New state added to reflect an SPXI connection which is waiting for
// a local disconnect after having indicated a RELEASE to AFD.
//
#define CFREF_DISCWAITSPX 13
#define CFREF_TOTAL 14
#define CFMAX_STATES 20
typedef struct _SPX_CONN_FILE
{
#if DBG
ULONG scf_RefTypes[CFREF_TOTAL];
#if 0
//
// Disabled for now - to enable logging of states, move this array *after* the Type/Size;
// a change in their offset can cause problems since we assume the offset to be less than
// the size of an AddressFile structure. (see SpxTdiQueryInformation)
//
ULONG scf_StateBuffer[CFMAX_STATES];
ULONG scf_NextStatePtr;
#endif
#endif
CSHORT scf_Type;
CSHORT scf_Size;
// number of references to this object.
ULONG scf_RefCount;
// Linkage in device address file list. The connection can be on the device
// connection list, address inactive/listen/active list.
struct _SPX_CONN_FILE * scf_Next;
struct _SPX_CONN_FILE * scf_AssocNext;
struct _SPX_CONN_FILE * scf_GlobalActiveNext;
// Queued in a global list, stays here from creation to destroy.
struct _SPX_CONN_FILE * scf_GlobalNext;
struct _SPX_CONN_FILE * scf_PktNext;
struct _SPX_CONN_FILE * scf_ProcessRecvNext;
// the current state of the connection. One main state and multiple substates.
ULONG scf_Flags;
// More information
ULONG scf_Flags2;
#if DBG
// Save the state of flags/flags2 before reinit. Overwritten every reinit.
ULONG scf_GhostFlags;
ULONG scf_GhostFlags2;
ULONG scf_GhostRefCount;
PREQUEST scf_GhostDiscReq;
#endif
// Connection retry counts, or watchdog timer count when the connection goes
// active
union
{
LONG scf_CRetryCount;
LONG scf_WRetryCount;
};
LONG scf_RRetryCount;
USHORT scf_RRetrySeqNum;
union
{
ULONG scf_CTimerId;
ULONG scf_RTimerId; // Only after we turn active
};
ULONG scf_WTimerId; // Watchdog timer
ULONG scf_TTimerId; // TDI Connect/Disconnect timer
ULONG scf_ATimerId; // Ack timer id
// Variables used to manage the Retry timer tick value
// Note our timer subsytem fires at 100ms granularity.
int scf_BaseT1;
int scf_AveT1;
int scf_DevT1;
// Stored in HOST-ORDER
// LOCAL variables
USHORT scf_LocalConnId;
USHORT scf_SendSeqNum; // Debug dw +9a
USHORT scf_SentAllocNum; // dw +9c
// REMOTE variables
USHORT scf_RecvSeqNum; // dw +9e
USHORT scf_RecdAckNum; // dw +a0
USHORT scf_RecdAllocNum; // dw +a2
// RETRY sequence number
USHORT scf_RetrySeqNum;
// Saved ack number to be used in building the reneg ack packet.
// Note that our RecvSeqNum which we normally use is overwritten
// when we receive a renegotiate request.
USHORT scf_RenegAckAckNum;
// Stored in NETWORK-ORDER. scf_RemAckAddr contains the remote address
// for a data packet that had the ack bit set, buildAck will use this
// address.
BYTE scf_RemAddr[12];
BYTE scf_RemAckAddr[12];
USHORT scf_RemConnId; // Debug dw +be
// Maximum packet size (or size of first) reneg packet.
USHORT scf_RenegMaxPktSize;
// Local target to use in when sending acks. This is set to received
// data's indicated local target.
IPX_LOCAL_TARGET scf_AckLocalTarget;
// Maximum packet size to use for this connection
USHORT scf_MaxPktSize;
UCHAR scf_DataType;
// Local target to use in sends, initialized upon connect indication
// or when find_route completes
IPX_LOCAL_TARGET scf_LocalTarget;
// Connection lock
CTELock scf_Lock;
// address to which we are bound
struct _SPX_ADDR_FILE * scf_AddrFile;
// Connection context
CONNECTION_CONTEXT scf_ConnCtx;
#ifdef ISN_NT
// easy backlink to file object.
PFILE_OBJECT scf_FileObject;
#endif
// LIST_ENTRY of disconnect irps waiting for completion. There could be
// multiple disconnect inform irps.
LIST_ENTRY scf_DiscLinkage;
// LIST_ENTRY of send requests (intially contains connect/listen/accept also)
// on this connection.
LIST_ENTRY scf_ReqLinkage;
// Queue for completed requests awaiting completion
LIST_ENTRY scf_ReqDoneLinkage;
LIST_ENTRY scf_RecvDoneLinkage;
// Queue for pending receives
LIST_ENTRY scf_RecvLinkage;
PREQUEST scf_CurRecvReq;
ULONG scf_CurRecvOffset;
ULONG scf_CurRecvSize;
// Current request packetize info
PREQUEST scf_ReqPkt;
ULONG scf_ReqPktOffset;
ULONG scf_ReqPktSize;
ULONG scf_ReqPktFlags;
SPX_SENDREQ_TYPE scf_ReqPktType;
// Single linked list of sequenced send/disc packets
PSPX_SEND_RESD scf_SendSeqListHead;
PSPX_SEND_RESD scf_SendSeqListTail;
// Single linked list of send (unsequenced) packets
PSPX_SEND_RESD scf_SendListHead;
PSPX_SEND_RESD scf_SendListTail;
// Single linked list of buffered recv packets.
PSPX_RECV_RESD scf_RecvListHead;
PSPX_RECV_RESD scf_RecvListTail;
// Connect request
PREQUEST scf_ConnectReq;
// This holds the request used to close this address file,
// for pended completion. We also pend cleanup requests for connections.
PREQUEST scf_CleanupReq;
PREQUEST scf_CloseReq;
#if DBG
// Packet being indicated, seq num, flags/flags2
USHORT scf_PktSeqNum;
ULONG scf_PktFlags;
ULONG scf_PktFlags2;
ULONG scf_IndBytes;
ULONG scf_IndLine;
#endif
#if DBG_WDW_CLOSE
// Keep track of how long the window was closed on this connection.
ULONG scf_WdwCloseAve;
LARGE_INTEGER scf_WdwCloseTime; // Time when wdw was closed
#endif
// device to which we are attached.
struct _DEVICE * scf_Device;
} SPX_CONN_FILE, *PSPX_CONN_FILE;
// Basic states
// Least significant byte of flags is used.
// Mutually exclusive states are coded as numbers, others are bit flags.
// Only main states are currently in form of numbers. Also, send and receive.
//
// Once we go active, we need SEND/RECEIVE/DISC substates to be mutually
// exclusive with each other. As all three could be active at the same time.
// Connection MAIN states. These are all mutually exclusive.
#define SPX_CONNFILE_MAINMASK 0x00000007
#define SPX_CONNFILE_ACTIVE 0x00000001
#define SPX_CONNFILE_CONNECTING 0x00000002
#define SPX_CONNFILE_LISTENING 0x00000003
#define SPX_CONNFILE_DISCONN 0x00000004
// Connecting states (VALID when CONNFILE_CONNECTING)
#define SPX_CONNECT_MASK 0x000000F0
#define SPX_CONNECT_SENTREQ 0x00000010
#define SPX_CONNECT_NEG 0x00000020
#define SPX_CONNECT_W_SETUP 0x00000030
// Listening states (VALID when CONNFILE_LISTENING)
#define SPX_LISTEN_MASK 0x000000F0
#define SPX_LISTEN_RECDREQ 0x00000010
#define SPX_LISTEN_SENTACK 0x00000020
#define SPX_LISTEN_NEGACK 0x00000030
#define SPX_LISTEN_SETUP 0x00000040
// Connection SUB states
// Send machine states (VALID when CONNFILE_ACTIVE)
#define SPX_SEND_MASK 0x000000F0
#define SPX_SEND_IDLE 0x00000000
#define SPX_SEND_PACKETIZE 0x00000010
#define SPX_SEND_RETRY 0x00000020
#define SPX_SEND_RETRYWD 0x00000030
#define SPX_SEND_RENEG 0x00000040
#define SPX_SEND_RETRY2 0x00000050
#define SPX_SEND_RETRY3 0x00000060
#define SPX_SEND_WD 0x00000070 // We dont reneg pkt size on wdog
// Also we change to this state only
// 2nd time wdog fires w/out ack.
#define SPX_SEND_NAK_RECD 0x00000080
// Receive machine states (VALID when CONNFILE_ACTIVE)
#define SPX_RECV_MASK 0x00000F00
#define SPX_RECV_IDLE 0x00000000
#define SPX_RECV_POSTED 0x00000100
#define SPX_RECV_PROCESS_PKTS 0x00000200
// Disconnect states (VALID when CONNFILE_DISCONN/CONNFILE_ACTIVE)
// These are valid when either ACTIVE/DISCONN is set. We use these when
// active for a orderly release, i.e. we receive pkt from remote, but we
// stay active (setting SPX_DISC_RECV_ORDREL) until our client posts a
// disconnect, which is when we move to disconnecting.
#define SPX_DISC_MASK 0x0000F000
#define SPX_DISC_IDLE 0x00000000
#define SPX_DISC_ABORT 0x00001000
#define SPX_DISC_SENT_IDISC 0x00002000
#define SPX_DISC_POST_ORDREL 0x00003000
#define SPX_DISC_SENT_ORDREL 0x00004000
#define SPX_DISC_ORDREL_ACKED 0x00005000
#define SPX_DISC_POST_IDISC 0x00006000
// [SA] bug #14655 added flag to indicate that SpxConnInactivate already called for
// this disconnecting connection
//
#define SPX_DISC_INACTIVATED 0x00007000
// The following are not mutually exclusive.
#define SPX_CONNFILE_RECVQ 0x00010000 // Process completed receives/pkts
#define SPX_CONNFILE_RENEG_SIZE 0x00020000 // Size changed in renegotiate pkt
#define SPX_CONNFILE_ACKQ 0x00040000 // Waiting to piggyback ack queue
#define SPX_CONNFILE_PKTQ 0x00080000 // Waiting to packetize queue
#define SPX_CONNFILE_ASSOC 0x00100000 // associated
#define SPX_CONNFILE_NEG 0x00200000 // CR had neg set (for delayed accept)
#define SPX_CONNFILE_SPX2 0x00400000
#define SPX_CONNFILE_STREAM 0x00800000
#define SPX_CONNFILE_R_TIMER 0x01000000 // Retry timer (only after ACTIVE)
#define SPX_CONNFILE_C_TIMER 0x01000000 // Connect timer
#define SPX_CONNFILE_W_TIMER 0x02000000 // Watchdog timer
#define SPX_CONNFILE_T_TIMER 0x04000000 // tdi connect/disc timer specified
#define SPX_CONNFILE_RENEG_PKT 0x08000000 // Renegotiate changed size, repacketize
#define SPX_CONNFILE_IND_IDISC 0x10000000 // Indicated abortive disc to afd
#define SPX_CONNFILE_IND_ODISC 0x20000000 // Indicated orderly release to afd
#define SPX_CONNFILE_STOPPING 0x40000000
#define SPX_CONNFILE_CLOSING 0x80000000 // closing
#define SPX_CONNFILE2_PKT_NOIND 0x00000001
#define SPX_CONNFILE2_RENEGRECD 0x00000002 // A renegotiate was received.
// scf_RenegAckAckNum set.
#define SPX_CONNFILE2_PKT 0x00000004
#define SPX_CONNFILE2_FINDROUTE 0x00000010 // A find route in progress on conn.
#define SPX_CONNFILE2_NOACKWAIT 0x00000020 // Dont delay acks on connection, option
#define SPX_CONNFILE2_IMMED_ACK 0x00000040 // Send an immediate ack,no back traffic
#define SPX_CONNFILE2_IPXHDR 0x00000080 // Pass ipxhdr in receives
//
// [SA] Saves the IDisc flag passed to AbortiveDisc; this is TRUE only if there was
// a remote disconnect on an SPX connection (in which case, we indicate TDI_DISCONNECT_RELEASE
// else we indicate TDI_DISCONNECT_ABORT)
//
#define SPX_CONNFILE2_IDISC 0x00000100
//
// Indicates an SPXI connfile waiting for a local disconnect in response
// to a TDI_DISCONNECT_RELEASE to AFD.
//
#define SPX_CONNFILE2_DISC_WAIT 0x00000200
// FindRoute request structure
typedef struct _SPX_FIND_ROUTE_REQUEST
{
// !!!!This must be the first element in the structure
IPX_FIND_ROUTE_REQUEST fr_FindRouteReq;
PVOID fr_Ctx;
} SPX_FIND_ROUTE_REQUEST, *PSPX_FIND_ROUTE_REQUEST;
typedef struct _SPX_CONNFILE_LIST
{
PSPX_CONN_FILE pcl_Head;
PSPX_CONN_FILE pcl_Tail;
} SPX_CONNFILE_LIST, *PSPX_CONNFILE_LIST;
// Exported routines
NTSTATUS
SpxConnOpen(
IN PDEVICE pDevice,
IN CONNECTION_CONTEXT pConnCtx,
IN PREQUEST pRequest);
NTSTATUS
SpxConnCleanup(
IN PDEVICE Device,
IN PREQUEST Request);
NTSTATUS
SpxConnClose(
IN PDEVICE Device,
IN PREQUEST Request);
NTSTATUS
SpxConnDisAssociate(
IN PDEVICE pDevice,
IN PREQUEST pRequest);
NTSTATUS
spxConnDisAssoc(
IN PSPX_CONN_FILE pSpxConnFile,
IN CTELockHandle LockHandleConn);
VOID
SpxConnStop(
IN PSPX_CONN_FILE pSpxConnFile);
NTSTATUS
SpxConnAssociate(
IN PDEVICE pDevice,
IN PREQUEST pRequest);
NTSTATUS
SpxConnConnect(
IN PDEVICE pDevice,
IN PREQUEST pRequest);
NTSTATUS
SpxConnListen(
IN PDEVICE pDevice,
IN PREQUEST pRequest);
NTSTATUS
SpxConnAccept(
IN PDEVICE pDevice,
IN PREQUEST pRequest);
NTSTATUS
SpxConnAction(
IN PDEVICE pDevice,
IN PREQUEST pRequest);
NTSTATUS
SpxConnDisconnect(
IN PDEVICE pDevice,
IN PREQUEST pRequest);
NTSTATUS
SpxConnSend(
IN PDEVICE pDevice,
IN PREQUEST pRequest);
NTSTATUS
SpxConnRecv(
IN PDEVICE pDevice,
IN PREQUEST pRequest);
VOID
SpxConnFileRefByCtxLock(
IN PSPX_ADDR_FILE pSpxAddrFile,
IN CONNECTION_CONTEXT Ctx,
OUT PSPX_CONN_FILE * ppSpxConnFile,
OUT NTSTATUS * pStatus);
NTSTATUS
SpxConnFileVerify (
IN PSPX_CONN_FILE pConnFile);
VOID
SpxConnFileDeref(
IN PSPX_CONN_FILE pSpxConnFile);
VOID
SpxConnConnectFindRouteComplete(
IN PSPX_CONN_FILE pSpxConnFile,
IN PSPX_FIND_ROUTE_REQUEST pFrReq,
IN BOOLEAN FoundRoute,
IN CTELockHandle LockHandle);
VOID
SpxConnActiveFindRouteComplete(
IN PSPX_CONN_FILE pSpxConnFile,
IN PSPX_FIND_ROUTE_REQUEST pFrReq,
IN BOOLEAN FoundRoute,
IN CTELockHandle LockHandle);
BOOLEAN
SpxConnPacketize(
IN PSPX_CONN_FILE pSpxConnFile,
IN BOOLEAN fNormalState,
IN CTELockHandle LockHandleConn);
#if DBG
VOID
SpxConnFileRef(
IN PSPX_CONN_FILE pSpxConnFile);
VOID
SpxConnFileLockRef(
IN PSPX_CONN_FILE pSpxConnFile);
#endif
VOID
SpxConnFileRefByIdLock (
IN USHORT ConnId,
OUT PSPX_CONN_FILE * ppSpxConnFile,
OUT PNTSTATUS pStatus);
BOOLEAN
SpxConnDequeuePktLock(
IN PSPX_CONN_FILE pSpxConnFile,
IN PNDIS_PACKET pPkt);
VOID
SpxConnSendAck(
IN PSPX_CONN_FILE pSpxConnFile,
IN CTELockHandle LockHandleConn);
VOID
SpxConnSendNack(
IN PSPX_CONN_FILE pSpxConnFile,
IN USHORT NumToSend,
IN CTELockHandle LockHandleConn);
BOOLEAN
SpxConnProcessAck(
IN PSPX_CONN_FILE pSpxConnFile,
IN PIPXSPX_HDR pAckHdr,
IN CTELockHandle lockHandle);
VOID
SpxConnProcessRenegReq(
IN PSPX_CONN_FILE pSpxConnFile,
IN PIPXSPX_HDR pIpxSpxHdr,
IN PIPX_LOCAL_TARGET pRemoteAddr,
IN CTELockHandle lockHandle);
VOID
SpxConnProcessIDisc(
IN PSPX_CONN_FILE pSpxConnFile,
IN CTELockHandle lockHandle);
VOID
SpxConnProcessOrdRel(
IN PSPX_CONN_FILE pSpxConnFile,
IN CTELockHandle lockHandle);
BOOLEAN
SpxConnDequeueRecvPktLock(
IN PSPX_CONN_FILE pSpxConnFile,
IN PNDIS_PACKET pPkt);
BOOLEAN
SpxConnDequeueSendPktLock(
IN PSPX_CONN_FILE pSpxConnFile,
IN PNDIS_PACKET pPkt);
// LOCAL functions
VOID
spxConnHandleConnReq(
IN PIPXSPX_HDR pIpxSpxHdr,
IN PIPX_LOCAL_TARGET pRemoteAddr);
VOID
spxConnHandleSessPktFromClient(
IN PIPXSPX_HDR pIpxSpxHdr,
IN PIPX_LOCAL_TARGET pRemoteAddr,
IN PSPX_CONN_FILE pSpxConnFile);
VOID
spxConnHandleSessPktFromSrv(
IN PIPXSPX_HDR pIpxSpxHdr,
IN PIPX_LOCAL_TARGET pRemoteAddr,
IN PSPX_CONN_FILE pSpxConnFile);
ULONG
spxConnConnectTimer(
IN PVOID Context,
IN BOOLEAN TimerShuttingDown);
ULONG
spxConnWatchdogTimer(
IN PVOID Context,
IN BOOLEAN TimerShuttingDown);
ULONG
spxConnRetryTimer(
IN PVOID Context,
IN BOOLEAN TimerShuttingDown);
ULONG
spxConnAckTimer(
IN PVOID Context,
IN BOOLEAN TimerShuttingDown);
VOID
spxConnCompletePended(
IN PSPX_CONN_FILE pSpxConnFile);
VOID
SpxConnQWaitAck(
IN PSPX_CONN_FILE pSpxConnFile);
USHORT
spxConnGetId(
VOID);
VOID
spxConnInsertIntoActiveList(
IN PSPX_ADDR pSpxAddr,
IN PSPX_CONN_FILE pSpxConnFile);
VOID
spxConnInsertIntoInactiveList(
IN PSPX_ADDR pSpxAddr,
IN PSPX_CONN_FILE pSpxConnFile);
NTSTATUS
spxConnRemoveFromGlobalList(
IN PSPX_CONN_FILE pSpxConnFile);
VOID
spxConnInsertIntoGlobalList(
IN PSPX_CONN_FILE pSpxConnFile);
NTSTATUS
spxConnRemoveFromGlobalActiveList(
IN PSPX_CONN_FILE pSpxConnFile);
VOID
spxConnPushIntoPktList(
IN PSPX_CONN_FILE pSpxConnFile);
VOID
spxConnPopFromPktList(
IN PSPX_CONN_FILE * ppSpxConnFile);
VOID
spxConnPushIntoRecvList(
IN PSPX_CONN_FILE pSpxConnFile);
VOID
spxConnPopFromRecvList(
IN PSPX_CONN_FILE * ppSpxConnFile);
VOID
spxConnInsertIntoGlobalActiveList(
IN PSPX_CONN_FILE pSpxConnFile);
VOID
spxConnInsertIntoListenList(
IN PSPX_ADDR pSpxAddr,
IN PSPX_CONN_FILE pSpxConnFile);
NTSTATUS
spxConnRemoveFromList(
IN PSPX_CONN_FILE * ppConnListHead,
IN PSPX_CONN_FILE pConnRemove);
NTSTATUS
spxConnRemoveFromAssocList(
IN PSPX_CONN_FILE * ppConnListHead,
IN PSPX_CONN_FILE pConnRemove);
VOID
spxConnInactivate(
IN PSPX_CONN_FILE pSpxConnFile);
BOOLEAN
spxConnGetPktByType(
IN PSPX_CONN_FILE pSpxConnFile,
IN ULONG PktType,
IN BOOLEAN fSeqList,
IN PNDIS_PACKET * ppPkt);
BOOLEAN
spxConnGetPktBySeqNum(
IN PSPX_CONN_FILE pSpxConnFile,
IN USHORT SeqNum,
IN PNDIS_PACKET * ppPkt);
VOID
spxConnResendPkts(
IN PSPX_CONN_FILE pSpxConnFile,
IN CTELockHandle LockHandleConn);
BOOLEAN
spxConnCheckNegSize(
IN PUSHORT pNegSize);
VOID
spxConnSetNegSize(
IN OUT PNDIS_PACKET pPkt,
IN ULONG Size);
BOOLEAN
spxConnAcceptCr(
IN PSPX_CONN_FILE pSpxConnFile,
IN PSPX_ADDR pSpxAddr,
IN CTELockHandle LockHandleDev,
IN CTELockHandle LockHandleAddr,
IN CTELockHandle LockHandleConn);
VOID
spxConnAbortConnect(
IN PSPX_CONN_FILE pSpxConnFile,
IN NTSTATUS Status,
IN CTELockHandle LockHandleDev,
IN CTELockHandle LockHandleAddr,
IN CTELockHandle LockHandleConn);
VOID
spxConnCompleteConnect(
IN PSPX_CONN_FILE pSpxConnFile,
IN CTELockHandle LockHandleDev,
IN CTELockHandle LockHandleAddr,
IN CTELockHandle LockHandleConn);
VOID
SpxConnQueueRecv(
IN PSPX_CONN_FILE pSpxConnFile,
IN PREQUEST pRequest);
NTSTATUS
spxConnProcessRecv(
IN PSPX_CONN_FILE pSpxConnFile,
IN PREQUEST pRequest,
IN SPX_CALL_LEVEL CallLevel,
IN CTELockHandle LockHandleConn);
VOID
spxConnProcessIndData(
IN PSPX_CONN_FILE pSpxConnFile,
IN SPX_CALL_LEVEL CallLevel,
IN CTELockHandle LockHandleConn);
NTSTATUS
spxConnOrderlyDisc(
IN PSPX_CONN_FILE pSpxConnFile,
IN NTSTATUS Status,
IN PREQUEST pRequest,
IN CTELockHandle LockHandleConn);
NTSTATUS
spxConnInformedDisc(
IN PSPX_CONN_FILE pSpxConnFile,
IN NTSTATUS Status,
IN PREQUEST pRequest,
IN CTELockHandle LockHandleConn);
VOID
spxConnAbortiveDisc(
IN PSPX_CONN_FILE pSpxConnFile,
IN NTSTATUS Status,
IN SPX_CALL_LEVEL CallLevel,
IN CTELockHandle LockHandleConn,
IN BOOLEAN Flag); // [SA] Bug #15249
VOID
spxConnAbortRecvs(
IN PSPX_CONN_FILE pSpxConnFile,
IN NTSTATUS Status,
IN SPX_CALL_LEVEL CallLevel,
IN CTELockHandle LockHandleConn);
VOID
spxConnAbortSends(
IN PSPX_CONN_FILE pSpxConnFile,
IN NTSTATUS Status,
IN SPX_CALL_LEVEL CallLevel,
IN CTELockHandle LockHandleConn);
VOID
spxConnResetSendQueue(
IN PSPX_CONN_FILE pSpxConnFile);
VOID
spxConnAbortSendPkt(
IN PSPX_CONN_FILE pSpxConnFile,
IN PSPX_SEND_RESD pSendResd,
IN SPX_CALL_LEVEL CallLevel,
IN CTELockHandle LockHandleConn);
BOOLEAN
CheckSentPacket(
PNDIS_PACKET npkt,
UINT hlen,
UINT len);
//
// MACROS
//
#define SHIFT100000 16
#define SPX_CONVERT100NSTOCENTISEC(Li) \
RtlExtendedMagicDivide((Li), Magic100000, SHIFT100000)
#define UNSIGNED_BETWEEN_WITH_WRAP(Low, High, Target) \
((Low <= High) ? ((Target >= Low) && (Target <= High)) : \
((Target >= Low) || (Target <= High)))
// This is with the assumption that the window size will never be greater
// than the difference of 0x8000 and 0x1000. If High is < 1000 and Low
// is > 8000 then we can assume a wrap happened. Otherwise, we assume no
// wrap and do a straight compare.
#define MAX_WINDOW_SIZE 0x6000
#define DEFAULT_WINDOW_SIZE 8
#define UNSIGNED_GREATER_WITH_WRAP(High, Low) \
(((High < 0x1000) && (Low > 0x8000)) ? TRUE : (High > Low))
#define SPX_SET_ACKNUM(pSpxConnFile, RecdAckNum, RecdAllocNum) \
{ \
DBGPRINT(SEND, DBG, \
("SPX_SET_ACKNUM: %lx.%lx = %lx.%lx (%s.%d)\n", \
(RecdAckNum), (RecdAllocNum), \
((pSpxConnFile)->scf_RecdAckNum), \
((pSpxConnFile)->scf_RecdAllocNum), \
__FILE__, __LINE__)); \
\
if (UNSIGNED_GREATER_WITH_WRAP((RecdAckNum), \
((pSpxConnFile)->scf_RecdAckNum))) \
{ \
(pSpxConnFile)->scf_RecdAckNum = (RecdAckNum); \
} \
\
if (UNSIGNED_GREATER_WITH_WRAP((RecdAllocNum), \
((pSpxConnFile)->scf_RecdAllocNum)))\
{ \
(pSpxConnFile)->scf_RecdAllocNum = (RecdAllocNum); \
} \
}
#define BEGIN_PROCESS_PACKET(pSpxConnFile, seqNum) \
{ \
SPX_CONN_SETFLAG2(pSpxConnFile, SPX_CONNFILE2_PKT); \
}
#define END_PROCESS_PACKET(pSpxConnFile, fBuffered, fSuccess) \
{ \
SPX_CONN_RESETFLAG2(pSpxConnFile, \
(SPX_CONNFILE2_PKT |SPX_CONNFILE2_RENEGRECD)); \
if (fSuccess) \
{ \
SPX_CONN_RESETFLAG2(pSpxConnFile, SPX_CONNFILE2_PKT_NOIND); \
SPX_SET_RECVNUM(pSpxConnFile, fBuffered); \
} \
}
#define INCREMENT_WINDOW(pSpxConnFile) \
((pSpxConnFile)->scf_SentAllocNum++)
#define ADD_TO_WINDOW(pSpxConnFile, numPkts) \
((pSpxConnFile)->scf_SentAllocNum += (numPkts))
#if DBG_WDW_CLOSE
#define SPX_SET_RECVNUM(pSpxConnFile, fBuffered) \
{ \
(pSpxConnFile)->scf_RecvSeqNum++; \
if (!fBuffered) \
(pSpxConnFile)->scf_SentAllocNum++; \
\
if (fBuffered && \
(UNSIGNED_GREATER_WITH_WRAP( \
(pSpxConnFile)->scf_RecvSeqNum, \
(pSpxConnFile)->scf_SentAllocNum))) \
{ \
KeQuerySystemTime( \
(PLARGE_INTEGER)&pSpxConnFile->scf_WdwCloseTime); \
} \
}
#else
#define SPX_SET_RECVNUM(pSpxConnFile, fBuffered) \
{ \
(pSpxConnFile)->scf_RecvSeqNum++; \
if (!fBuffered) \
(pSpxConnFile)->scf_SentAllocNum++; \
}
#endif
#define SPX_CONN_SETNEXT_CUR_RECV(pSpxConnFile, pRequest) \
{ \
RemoveEntryList(REQUEST_LINKAGE((pRequest))); \
pSpxConnFile->scf_CurRecvReq = NULL; \
pSpxConnFile->scf_CurRecvOffset = 0; \
pSpxConnFile->scf_CurRecvSize = 0; \
if (!IsListEmpty(&(pSpxConnFile)->scf_RecvLinkage)) \
{ \
PTDI_REQUEST_KERNEL_RECEIVE _p; \
DBGPRINT(RECEIVE, DBG, \
("spxConnProcessRecv: CURRECV %lx\n", pRequest)); \
\
(pSpxConnFile)->scf_CurRecvReq = \
LIST_ENTRY_TO_REQUEST( \
(pSpxConnFile)->scf_RecvLinkage.Flink); \
\
_p = (PTDI_REQUEST_KERNEL_RECEIVE) \
REQUEST_PARAMETERS((pSpxConnFile)->scf_CurRecvReq); \
\
(pSpxConnFile)->scf_CurRecvOffset = 0; \
(pSpxConnFile)->scf_CurRecvSize = (_p)->ReceiveLength; \
} \
if ((SPX_RECV_STATE(pSpxConnFile) == SPX_RECV_IDLE) || \
(SPX_RECV_STATE(pSpxConnFile) == SPX_RECV_POSTED)) \
{ \
SPX_RECV_SETSTATE( \
pSpxConnFile, \
(pSpxConnFile->scf_CurRecvReq == NULL) ? \
SPX_RECV_IDLE : SPX_RECV_POSTED); \
} \
}
#define SPX_INSERT_ADDR_ACTIVE(pSpxAddr, pSpxConnFile) \
{ \
(pSpxConnFile)->scf_Next = (pSpxAddr)->sa_ActiveConnList; \
(pSpxAddr)->sa_ActiveConnList = pSpxConnFile; \
}
#define SPX_INSERT_ADDR_INACTIVE(pSpxAddr, pSpxConnFile) \
{ \
(pSpxConnFile)->scf_Next = (pSpxAddr)->sa_InactiveConnList; \
(pSpxAddr)->sa_InactiveConnList = pSpxConnFile; \
}
#define SPX_INSERT_ADDR_LISTEN(pSpxAddr, pSpxConnFile) \
{ \
(pSpxConnFile)->scf_Next = (pSpxAddr)->sa_ListenConnList; \
(pSpxAddr)->sa_ListenConnList = pSpxConnFile; \
}
//
// STATE MANIPULATION
//
#if 0
//
// Disabled for now
//
#define SPX_STORE_LAST_STATE(pSpxConnFile) \
(pSpxConnFile)->scf_StateBuffer[(pSpxConnFile)->scf_NextStatePtr++] = \
(pSpxConnFile)->scf_Flags; \
(pSpxConnFile)->scf_NextStatePtr %= CFMAX_STATES;
#else
#define SPX_STORE_LAST_STATE(pSpxConnFile)
#endif
#define SPX_MAIN_STATE(pSpxConnFile) \
((pSpxConnFile)->scf_Flags & SPX_CONNFILE_MAINMASK)
// #define SPX_CONN_IDLE(pSpxConnFile) \
// ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == 0))
#define SPX_CONN_IDLE(pSpxConnFile) \
((BOOLEAN)((SPX_MAIN_STATE(pSpxConnFile) == 0) || \
((SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_DISCONN) && \
(SPX_DISC_STATE(pSpxConnFile) == SPX_DISC_INACTIVATED))))
#define SPX_CONN_ACTIVE(pSpxConnFile) \
((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_ACTIVE))
#define SPX_CONN_CONNECTING(pSpxConnFile) \
((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_CONNECTING))
#define SPX_CONN_LISTENING(pSpxConnFile) \
((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_LISTENING))
#define SPX_CONN_DISC(pSpxConnFile) \
((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_DISCONN))
#if DBG
#define SPX_MAIN_SETSTATE(pSpxConnFile, newState) \
{ \
SPX_STORE_LAST_STATE(pSpxConnFile) \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_CONNFILE_MAINMASK) | (newState));\
}
#else
#define SPX_MAIN_SETSTATE(pSpxConnFile, newState) \
{ \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_CONNFILE_MAINMASK) | (newState));\
}
#endif
#define SPX_CONN_FLAG(pSpxConnFile, Flag) \
((BOOLEAN)(((pSpxConnFile)->scf_Flags & (Flag)) != 0))
#define SPX_CONN_FLAG2(pSpxConnFile, Flag) \
((BOOLEAN)(((pSpxConnFile)->scf_Flags2 & (Flag)) != 0))
#if DBG
#define SPX_CONN_SETFLAG(pSpxConnFile, Flag) \
SPX_STORE_LAST_STATE(pSpxConnFile) \
((pSpxConnFile)->scf_Flags |= (Flag))
#else
#define SPX_CONN_SETFLAG(pSpxConnFile, Flag) \
((pSpxConnFile)->scf_Flags |= (Flag))
#endif
#define SPX_CONN_SETFLAG2(pSpxConnFile, Flag) \
((pSpxConnFile)->scf_Flags2 |= (Flag))
#define SPX_CONN_RESETFLAG(pSpxConnFile, Flag) \
((pSpxConnFile)->scf_Flags &= ~(Flag))
#define SPX_CONN_RESETFLAG2(pSpxConnFile, Flag) \
((pSpxConnFile)->scf_Flags2 &= ~(Flag))
#define SPX2_CONN(pSpxConnFile) \
(SPX_CONN_FLAG((pSpxConnFile), SPX_CONNFILE_SPX2))
#define SPX_CONN_STREAM(pSpxConnFile) \
(SPX_CONN_FLAG((pSpxConnFile), SPX_CONNFILE_STREAM))
#define SPX_CONN_MSG(pSpxConnFile) \
(!SPX_CONN_FLAG((pSpxConnFile), SPX_CONNFILE_STREAM))
#define SPX_LISTEN_STATE(pSpxConnFile) \
((pSpxConnFile)->scf_Flags & SPX_LISTEN_MASK)
#define SPX_CONNECT_STATE(pSpxConnFile) \
((pSpxConnFile)->scf_Flags & SPX_CONNECT_MASK)
#define SPX_SEND_STATE(pSpxConnFile) \
((pSpxConnFile)->scf_Flags & SPX_SEND_MASK)
#define SPX_RECV_STATE(pSpxConnFile) \
((pSpxConnFile)->scf_Flags & SPX_RECV_MASK)
#define SPX_DISC_STATE(pSpxConnFile) \
((pSpxConnFile)->scf_Flags & SPX_DISC_MASK)
#if DBG
#define SPX_LISTEN_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("LISTEN: %x -> %x\n", \
SPX_LISTEN_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
SPX_STORE_LAST_STATE(pSpxConnFile) \
pSpxConnFile->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_LISTEN_MASK) | (newState)); \
}
#define SPX_CONNECT_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("CONNECT: %x -> %x\n", \
SPX_CONNECT_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
SPX_STORE_LAST_STATE(pSpxConnFile) \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_CONNECT_MASK) | (newState)); \
}
#define SPX_SEND_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("SEND: %x -> %x\n", \
SPX_SEND_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
SPX_STORE_LAST_STATE(pSpxConnFile) \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_SEND_MASK) | (newState)); \
}
#define SPX_RECV_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("RECV: %x -> %x\n", \
SPX_RECV_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
SPX_STORE_LAST_STATE(pSpxConnFile) \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_RECV_MASK) | (newState)); \
}
#define SPX_DISC_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("DISC: %x -> %x\n", \
SPX_DISC_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
SPX_STORE_LAST_STATE(pSpxConnFile) \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_DISC_MASK) | (newState)); \
}
#else
#define SPX_LISTEN_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("LISTEN: %x -> %x\n", \
SPX_LISTEN_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
pSpxConnFile->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_LISTEN_MASK) | (newState)); \
}
#define SPX_CONNECT_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("CONNECT: %x -> %x\n", \
SPX_CONNECT_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_CONNECT_MASK) | (newState)); \
}
#define SPX_SEND_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("SEND: %x -> %x\n", \
SPX_SEND_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_SEND_MASK) | (newState)); \
}
#define SPX_RECV_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("RECV: %x -> %x\n", \
SPX_RECV_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_RECV_MASK) | (newState)); \
}
#define SPX_DISC_SETSTATE(pSpxConnFile, newState) \
{ \
DBGPRINT(STATE, INFO, \
("DISC: %x -> %x\n", \
SPX_DISC_STATE(pSpxConnFile), (newState))); \
DBGPRINT(STATE, INFO, \
("FILE: %s - %d\n", __FILE__, __LINE__)); \
(pSpxConnFile)->scf_Flags = \
(((pSpxConnFile)->scf_Flags & ~SPX_DISC_MASK) | (newState)); \
}
#endif //DBG
#define SpxConnQueueSendPktTail(pSpxConnFile, pPkt) \
{ \
PSPX_SEND_RESD _pSendResd; \
_pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \
_pSendResd->sr_Next = NULL; \
if ((pSpxConnFile)->scf_SendListTail != NULL) \
{ \
(pSpxConnFile)->scf_SendListTail->sr_Next = _pSendResd; \
(pSpxConnFile)->scf_SendListTail = _pSendResd;\
} \
else \
{ \
(pSpxConnFile)->scf_SendListTail = \
(pSpxConnFile)->scf_SendListHead = _pSendResd; \
} \
}
#define SpxConnQueueSendPktHead(pSpxConnFile, pPkt) \
{ \
PSPX_SEND_RESD _pSendResd; \
_pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \
_pSendResd->sr_Next = NULL; \
if ((pSpxConnFile)->scf_SendListTail != NULL) \
{ \
_pSendResd->sr_Next = (pSpxConnFile)->scf_SendListHead; \
} \
else \
{ \
(pSpxConnFile)->scf_SendListTail = _pSendResd; \
} \
(pSpxConnFile)->scf_SendListHead = _pSendResd; \
}
#define SpxConnQueueSendSeqPktTail(pSpxConnFile, pPkt) \
{ \
PSPX_SEND_RESD _pSendResd; \
_pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \
_pSendResd->sr_Next = NULL; \
if ((pSpxConnFile)->scf_SendSeqListTail != NULL) \
{ \
(pSpxConnFile)->scf_SendSeqListTail->sr_Next = _pSendResd;\
(pSpxConnFile)->scf_SendSeqListTail = _pSendResd;\
} \
else \
{ \
(pSpxConnFile)->scf_SendSeqListTail = \
(pSpxConnFile)->scf_SendSeqListHead = _pSendResd; \
} \
}
#define SpxConnQueueSendSeqPktHead(pSpxConnFile, pPkt) \
{ \
PSPX_SEND_RESD _pSendResd; \
_pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \
_pSendResd->sr_Next = NULL; \
if ((pSpxConnFile)->scf_SendSeqListTail != NULL) \
{ \
_pSendResd->sr_Next = (pSpxConnFile)->scf_SendSeqListHead;\
} \
else \
{ \
(pSpxConnFile)->scf_SendSeqListTail = _pSendResd; \
} \
(pSpxConnFile)->scf_SendSeqListHead = _pSendResd; \
}
#define SpxConnQueueRecvPktTail(pSpxConnFile, pPkt) \
{ \
PSPX_RECV_RESD _pRecvResd; \
_pRecvResd = (PSPX_RECV_RESD)((pPkt)->ProtocolReserved); \
_pRecvResd->rr_Next = NULL; \
if ((pSpxConnFile)->scf_RecvListTail != NULL) \
{ \
(pSpxConnFile)->scf_RecvListTail->rr_Next = _pRecvResd; \
(pSpxConnFile)->scf_RecvListTail = _pRecvResd;\
} \
else \
{ \
(pSpxConnFile)->scf_RecvListTail = \
(pSpxConnFile)->scf_RecvListHead = _pRecvResd; \
} \
}
#define SpxConnQueueRecvPktHead(pSpxConnFile, pPkt) \
{ \
PSPX_RECV_RESD _pRecvResd; \
_pRecvResd = (PSPX_RECV_RESD)((pPkt)->ProtocolReserved); \
_pRecvResd->rr_Next = NULL; \
if ((pSpxConnFile)->scf_RecvListTail != NULL) \
{ \
_pRecvResd->rr_Next = (pSpxConnFile)->scf_RecvListHead; \
} \
else \
{ \
(pSpxConnFile)->scf_RecvListTail = _pRecvResd; \
} \
(pSpxConnFile)->scf_RecvListHead = _pRecvResd; \
}
#if DBG
#define SpxConnFileReference(_ConnFile, _Type) \
{ \
(VOID)SPX_ADD_ULONG ( \
&(_ConnFile)->scf_RefTypes[_Type], \
1, \
&SpxGlobalInterlock); \
SpxConnFileRef (_ConnFile); \
}
#define SpxConnFileLockReference(_ConnFile, _Type) \
{ \
(VOID)SPX_ADD_ULONG ( \
&(_ConnFile)->scf_RefTypes[_Type], \
1, \
&SpxGlobalInterlock); \
SpxConnFileLockRef (_ConnFile); \
}
#define SpxConnFileDereference(_ConnFile, _Type) \
{ \
(VOID)SPX_ADD_ULONG ( \
&(_ConnFile)->scf_RefTypes[_Type], \
(ULONG)-1, \
&SpxGlobalInterlock); \
SpxConnFileDeref (_ConnFile); \
}
#define SpxConnFileReferenceByCtx(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \
{ \
CTELockHandle _lockHandle; \
CTEGetLock((_pAddrFile)->saf_AddrLock, &(_lockHandle)); \
SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));\
CTEFreeLock((_pAddrFile)->saf_AddrLock, (_lockHandle)); \
}
#define SpxConnFileReferenceByCtxLock(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \
SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));
#define SpxConnFileReferenceById(_ConnId, _ppConnFile, _pStatus) \
{ \
CTELockHandle _l; \
CTEGetLock(&SpxDevice->dev_Lock, &(_l)); \
SpxConnFileRefByIdLock(_ConnId, _ppConnFile, _pStatus); \
CTEFreeLock(&SpxDevice->dev_Lock, _l); \
}
#define SpxConnFileTransferReference(_ConnFile, _OldType, _NewType) \
{ \
(VOID)SPX_ADD_ULONG ( \
&(_ConnFile)->scf_RefTypes[_NewType], \
1, \
&SpxGlobalInterlock); \
(VOID)SPX_ADD_ULONG ( \
&(_ConnFile)->scf_RefTypes[_OldType], \
(ULONG)-1, \
&SpxGlobalInterlock); \
}
#else // DBG
#define SpxConnFileReference(_ConnFile, _Type) \
SPX_ADD_ULONG( \
&(_ConnFile)->scf_RefCount, \
1, \
&(_ConnFile)->scf_Lock)
#define SpxConnFileLockReference(_ConnFile, _Type) \
SPX_ADD_ULONG( \
&(_ConnFile)->scf_RefCount, \
1, \
&(_ConnFile)->scf_Lock);
#define SpxConnFileDereference(_ConnFile, _Type) \
{ \
SpxConnFileDeref(_ConnFile); \
}
#define SpxConnFileReferenceByCtx(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \
{ \
CTELockHandle _lockHandle; \
CTEGetLock((_pAddrFile)->saf_AddrLock, &(_lockHandle)); \
SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));\
CTEFreeLock((_pAddrFile)->saf_AddrLock, (_lockHandle)); \
}
#define SpxConnFileReferenceByCtxLock(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \
SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));
#define SpxConnFileReferenceById(_ConnId, _ppConnFile, _pStatus) \
{ \
CTELockHandle _lockHandle; \
CTEGetLock(&SpxDevice->dev_Lock, &(_lockHandle)); \
SpxConnFileRefByIdLock(_ConnId, _ppConnFile, _pStatus); \
CTEFreeLock(&SpxDevice->dev_Lock, (_lockHandle)); \
}
#define SpxConnFileTransferReference(_ConnFile, _OldType, _NewType)
#endif // DBG
// Set the packet size. If we are spx1 or spx2 and !neg, check if we are different
// nets, set to min then, else use the size indicated by IPX. If we are spx2, just
// set it to our local max.
//
// Also always even out packet size and round down. This solves an issue with
// data size needing to be even for some novell 802.2 clients.
//
// Fix after beta2 for tokring using receive size. Only if spx2 and neg.
#if defined(_PNP_POWER)
#define SPX_MAX_PKT_SIZE(pSpxConnFile, fSpx2Neg, fSpx2, pRemNet) \
{ \
if (!fSpx2 && PARAM(CONFIG_BACKCOMP_SPX)) { \
(pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
} \
else { \
IPX_LINE_INFO _i; \
\
(VOID)(*IpxQuery)( \
IPX_QUERY_LINE_INFO, \
&(pSpxConnFile)->scf_LocalTarget.NicHandle, \
&(_i), \
sizeof(IPX_LINE_INFO), \
NULL); \
\
(pSpxConnFile)->scf_MaxPktSize = (USHORT) (_i).MaximumPacketSize; \
if (!fSpx2Neg) \
{ \
(pSpxConnFile)->scf_MaxPktSize = (USHORT) (_i).MaximumSendSize; \
} \
\
if ((pSpxConnFile)->scf_MaxPktSize < SPX_MAX_PACKET) \
{ \
(pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
} \
\
DBGPRINT(CONNECT, DBG, \
("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \
(*(UNALIGNED ULONG *)(pRemNet)), \
*(UNALIGNED ULONG *)SpxDevice->dev_Network, \
(pSpxConnFile)->scf_MaxPktSize)); \
DBGPRINT(CONNECT, DBG, \
("%s : %d.%d\n", __FILE__, __LINE__, fSpx2Neg)); \
\
if ((!fSpx2Neg) && \
((*(UNALIGNED ULONG *)(pRemNet)) != 0) && \
((*(UNALIGNED ULONG *)SpxDevice->dev_Network) != 0) && \
((*(UNALIGNED ULONG *)(pRemNet)) != \
*(UNALIGNED ULONG *)SpxDevice->dev_Network)) \
{ \
if (PARAM(CONFIG_ROUTER_MTU) != 0) \
{ \
DBGPRINT(CONNECT, ERR, \
("SPX_MAX_PKT_SIZE: PARAM %lx Max Pkt %lx\n", \
PARAM(CONFIG_ROUTER_MTU), \
(pSpxConnFile)->scf_MaxPktSize)); \
\
(pSpxConnFile)->scf_MaxPktSize = \
(USHORT)(MIN(PARAM(CONFIG_ROUTER_MTU), \
(ULONG)((pSpxConnFile)->scf_MaxPktSize)));\
} \
else \
{ \
(pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
} \
\
DBGPRINT(CONNECT, DBG, \
("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \
(*(UNALIGNED ULONG *)(pRemNet)), \
*(UNALIGNED ULONG *)SpxDevice->dev_Network, \
(pSpxConnFile)->scf_MaxPktSize)); \
DBGPRINT(CONNECT, DBG, \
("SPX_MAX_PKT_SIZE: LineInfo Pkt %d\n", \
(_i).MaximumSendSize)); \
} \
} \
(pSpxConnFile)->scf_MaxPktSize &= ~((USHORT)1); \
DBGPRINT(CONNECT, DBG, \
("SPX_MAX_PKT_SIZE: %lx.%d\n", \
(pSpxConnFile)->scf_MaxPktSize, \
(pSpxConnFile)->scf_MaxPktSize)); \
}
#else
#define SPX_MAX_PKT_SIZE(pSpxConnFile, fSpx2Neg, fSpx2, pRemNet) \
{ \
if (!fSpx2 && PARAM(CONFIG_BACKCOMP_SPX)) { \
(pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
} \
else { \
IPX_LINE_INFO _i; \
\
(VOID)(*IpxQuery)( \
IPX_QUERY_LINE_INFO, \
(pSpxConnFile)->scf_LocalTarget.NicId, \
&(_i), \
sizeof(IPX_LINE_INFO), \
NULL); \
\
(pSpxConnFile)->scf_MaxPktSize = (_i).MaximumPacketSize; \
if (!fSpx2Neg) \
{ \
(pSpxConnFile)->scf_MaxPktSize = (_i).MaximumSendSize; \
} \
\
if ((pSpxConnFile)->scf_MaxPktSize < SPX_MAX_PACKET) \
{ \
(pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
} \
\
DBGPRINT(CONNECT, DBG, \
("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \
(*(UNALIGNED ULONG *)(pRemNet)), \
*(UNALIGNED ULONG *)SpxDevice->dev_Network, \
(pSpxConnFile)->scf_MaxPktSize)); \
DBGPRINT(CONNECT, DBG, \
("%s : %d.%d\n", __FILE__, __LINE__, fSpx2Neg)); \
\
if ((!fSpx2Neg) && \
((*(UNALIGNED ULONG *)(pRemNet)) != 0) && \
((*(UNALIGNED ULONG *)SpxDevice->dev_Network) != 0) && \
((*(UNALIGNED ULONG *)(pRemNet)) != \
*(UNALIGNED ULONG *)SpxDevice->dev_Network)) \
{ \
if (PARAM(CONFIG_ROUTER_MTU) != 0) \
{ \
DBGPRINT(CONNECT, ERR, \
("SPX_MAX_PKT_SIZE: PARAM %lx Max Pkt %lx\n", \
PARAM(CONFIG_ROUTER_MTU), \
(pSpxConnFile)->scf_MaxPktSize)); \
\
(pSpxConnFile)->scf_MaxPktSize = \
(USHORT)(MIN(PARAM(CONFIG_ROUTER_MTU), \
(ULONG)((pSpxConnFile)->scf_MaxPktSize)));\
} \
else \
{ \
(pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
} \
\
DBGPRINT(CONNECT, DBG, \
("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \
(*(UNALIGNED ULONG *)(pRemNet)), \
*(UNALIGNED ULONG *)SpxDevice->dev_Network, \
(pSpxConnFile)->scf_MaxPktSize)); \
DBGPRINT(CONNECT, DBG, \
("SPX_MAX_PKT_SIZE: LineInfo Pkt %d\n", \
(_i).MaximumSendSize)); \
} \
} \
(pSpxConnFile)->scf_MaxPktSize &= ~((USHORT)1); \
DBGPRINT(CONNECT, DBG, \
("SPX_MAX_PKT_SIZE: %lx.%d\n", \
(pSpxConnFile)->scf_MaxPktSize, \
(pSpxConnFile)->scf_MaxPktSize)); \
}
#endif _PNP_POWER
#if DBG
#define SPX_SENDPACKET(pSpxConnFile, pNdisPkt, pSendResd) \
{ \
NDIS_STATUS _n; \
\
++SpxDevice->dev_Stat.PacketsSent; \
\
_n = (*IpxSendPacket)( \
&(pSpxConnFile)->scf_LocalTarget, \
(pNdisPkt), \
(pSendResd)->sr_Len, \
(pSendResd)->sr_HdrLen); \
\
if (_n != NDIS_STATUS_PENDING) \
{ \
if (_n != NDIS_STATUS_SUCCESS) \
{ \
DBGPRINT(SEND, ERR, \
("SPX_SENDPACKET: Failed with %lx in %s.%lx\n", \
_n, __FILE__, __LINE__)); \
} \
\
SpxSendComplete( \
(pNdisPkt), \
_n); \
} \
}
#define SPX_SENDACK(pSpxConnFile, pNdisPkt, pSendResd) \
{ \
NDIS_STATUS _n; \
\
++SpxDevice->dev_Stat.PacketsSent; \
\
_n = (*IpxSendPacket)( \
&(pSpxConnFile)->scf_AckLocalTarget, \
(pNdisPkt), \
(pSendResd)->sr_Len, \
(pSendResd)->sr_HdrLen); \
\
if (_n != NDIS_STATUS_PENDING) \
{ \
if (_n != NDIS_STATUS_SUCCESS) \
{ \
DBGPRINT(SEND, ERR, \
("SPX_SENDPACKET: Failed with %lx in %s.%lx\n", \
_n, __FILE__, __LINE__)); \
} \
\
SpxSendComplete( \
(pNdisPkt), \
_n); \
} \
}
#else // DBG
#define SPX_SENDPACKET(pSpxConnFile, pNdisPkt, pSendResd) \
{ \
NDIS_STATUS _n; \
\
++SpxDevice->dev_Stat.PacketsSent; \
\
_n = (*IpxSendPacket)( \
&(pSpxConnFile)->scf_LocalTarget, \
(pNdisPkt), \
(pSendResd)->sr_Len, \
(pSendResd)->sr_HdrLen); \
\
if (_n != NDIS_STATUS_PENDING) \
{ \
SpxSendComplete( \
(pNdisPkt), \
_n); \
} \
}
#define SPX_SENDACK(pSpxConnFile, pNdisPkt, pSendResd) \
{ \
NDIS_STATUS _n; \
\
++SpxDevice->dev_Stat.PacketsSent; \
\
_n = (*IpxSendPacket)( \
&(pSpxConnFile)->scf_AckLocalTarget, \
(pNdisPkt), \
(pSendResd)->sr_Len, \
(pSendResd)->sr_HdrLen); \
\
if (_n != NDIS_STATUS_PENDING) \
{ \
SpxSendComplete( \
(pNdisPkt), \
_n); \
} \
}
#endif // DBG
#define SPX_QUEUE_FOR_RECV_COMPLETION(pSpxConnFile) \
{ \
if (!SPX_CONN_FLAG( \
(pSpxConnFile), \
SPX_CONNFILE_RECVQ)) \
{ \
SPX_CONN_SETFLAG((pSpxConnFile), SPX_CONNFILE_RECVQ); \
SpxConnFileLockReference(pSpxConnFile, CFREF_RECV); \
SPX_QUEUE_TAIL_RECVLIST(pSpxConnFile); \
} \
}
#define SPX_QUEUE_TAIL_PKTLIST(pSpxConnFile) \
{ \
if (SpxPktConnList.pcl_Tail) \
{ \
SpxPktConnList.pcl_Tail->scf_PktNext = pSpxConnFile; \
SpxPktConnList.pcl_Tail = pSpxConnFile; \
} \
else \
{ \
SpxPktConnList.pcl_Tail = \
SpxPktConnList.pcl_Head = pSpxConnFile; \
} \
}
#define SPX_QUEUE_TAIL_RECVLIST(pSpxConnFile) \
{ \
if (SpxRecvConnList.pcl_Tail) \
{ \
SpxRecvConnList.pcl_Tail->scf_ProcessRecvNext = pSpxConnFile; \
SpxRecvConnList.pcl_Tail = pSpxConnFile; \
} \
else \
{ \
SpxRecvConnList.pcl_Tail = \
SpxRecvConnList.pcl_Head = pSpxConnFile; \
} \
}