summaryrefslogtreecommitdiffstats
path: root/private/ntos/tdi/isnp/spx/h
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/tdi/isnp/spx/h
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/tdi/isnp/spx/h')
-rw-r--r--private/ntos/tdi/isnp/spx/h/fwddecls.h28
-rw-r--r--private/ntos/tdi/isnp/spx/h/globals.h67
-rw-r--r--private/ntos/tdi/isnp/spx/h/isnspx.h363
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxaddr.h426
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxbind.h32
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxconn.h1666
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxdev.h204
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxerror.h246
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxmem.h142
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxntdef.h72
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxpkt.h466
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxquery.h54
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxrecv.h89
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxreg.h65
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxsend.h34
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxtimer.h101
-rw-r--r--private/ntos/tdi/isnp/spx/h/spxutils.h178
17 files changed, 4233 insertions, 0 deletions
diff --git a/private/ntos/tdi/isnp/spx/h/fwddecls.h b/private/ntos/tdi/isnp/spx/h/fwddecls.h
new file mode 100644
index 000000000..feda4e76b
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/fwddecls.h
@@ -0,0 +1,28 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ fwddecls.h
+
+Abstract:
+
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+struct _SPX_ADDR ;
+struct _SPX_ADDR_FILE ;
+struct _SPX_CONN_FILE ;
+struct _SPX_SEND_RESD ;
diff --git a/private/ntos/tdi/isnp/spx/h/globals.h b/private/ntos/tdi/isnp/spx/h/globals.h
new file mode 100644
index 000000000..e4fcf39a8
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/globals.h
@@ -0,0 +1,67 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ globals.h
+
+Abstract:
+
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+
+extern PDEVICE SpxDevice;
+extern UNICODE_STRING IpxDeviceName;
+extern HANDLE IpxHandle;
+
+extern LARGE_INTEGER Magic100000;
+
+#if 1 // DBG
+extern ULONG SpxDebugDump;
+extern LONG SpxDumpInterval;
+extern ULONG SpxDebugLevel;
+extern ULONG SpxDebugSystems;
+
+#endif
+
+// More IPX info.
+extern IPX_LINE_INFO IpxLineInfo;
+extern USHORT IpxMacHdrNeeded;
+extern USHORT IpxInclHdrOffset;
+
+// Entry Points into the IPX stack
+extern IPX_INTERNAL_SEND IpxSendPacket;
+extern IPX_INTERNAL_FIND_ROUTE IpxFindRoute;
+extern IPX_INTERNAL_QUERY IpxQuery;
+extern IPX_INTERNAL_TRANSFER_DATA IpxTransferData;
+
+// Unload event
+extern KEVENT SpxUnloadEvent;
+
+extern ULONG SpxMaxPktSize[];
+extern ULONG SpxMaxPktSizeIndex;
+
+extern CTELock SpxGlobalInterlock;
+
+
+extern CTELock SpxGlobalQInterlock;
+extern PSPX_CONN_FILE SpxGlobalConnList;
+extern PSPX_ADDR_FILE SpxGlobalAddrList;
+
+extern SPX_CONNFILE_LIST SpxPktConnList;
+extern SPX_CONNFILE_LIST SpxRecvConnList;
+
+extern LONG SpxTimerCurrentTime;
diff --git a/private/ntos/tdi/isnp/spx/h/isnspx.h b/private/ntos/tdi/isnp/spx/h/isnspx.h
new file mode 100644
index 000000000..6080b0423
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/isnspx.h
@@ -0,0 +1,363 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ isnspx.h
+
+Abstract:
+
+ This module contains definitions specific to the
+ SPX module of the ISN transport.
+
+Author:
+
+ Adam Barr (adamba) 2-September-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+#define ISN_NT 1
+
+//
+// These are needed for CTE
+//
+
+#if DBG
+#define DEBUG 1
+#endif
+
+#define NT 1
+
+
+#include <ntddk.h>
+#include <tdikrnl.h>
+#include <ndis.h>
+#ifndef CTE_TYPEDEFS_DEFINED
+#include <cxport.h>
+#endif
+#include <bind.h>
+
+#include "wsnwlink.h"
+
+#define SPX_DEVICE_SIGNATURE (USHORT)(*(PUSHORT)"SD")
+#define SPX_ADDRESS_SIGNATURE (USHORT)(*(PUSHORT)"AD")
+#define SPX_ADDRESSFILE_SIGNATURE (USHORT)(*(PUSHORT)"AF")
+#define SPX_CONNFILE_SIGNATURE (USHORT)(*(PUSHORT)"CF")
+
+#define SPX_FILE_TYPE_CONTROL (ULONG)0x4701 // file is type control
+
+#define SPX_ADD_ULONG(_Pulong, _Ulong, _Lock) InterlockedExchangeAdd(_Pulong, _Ulong)
+
+typedef UCHAR BYTE, *PBYTE;
+typedef ULONG DWORD, *PDWORD;
+
+//
+// These definitions are for abstracting IRPs from the
+// transport for portability.
+//
+
+#if ISN_NT
+
+typedef IRP REQUEST, *PREQUEST;
+
+//
+// PREQUEST
+// SpxAllocateRequest(
+// IN PDEVICE Device,
+// IN PIRP Irp
+// );
+//
+// Allocates a request for the system-specific request structure.
+//
+
+#define SpxAllocateRequest(_Device,_Irp) \
+ (_Irp)
+
+//
+// BOOLEAN
+// IF_NOT_ALLOCATED(
+// IN PREQUEST Request
+// );
+//
+// Checks if a request was not successfully allocated.
+//
+
+#define IF_NOT_ALLOCATED(_Request) \
+ if (0)
+
+
+//
+// VOID
+// SpxFreeRequest(
+// IN PDEVICE Device,
+// IN PREQUEST Request
+// );
+//
+// Frees a previously allocated request.
+//
+
+#define SpxFreeRequest(_Device,_Request) \
+ ;
+
+
+//
+// VOID
+// MARK_REQUEST_PENDING(
+// IN PREQUEST Request
+// );
+//
+// Marks that a request will pend.
+//
+
+#define MARK_REQUEST_PENDING(_Request) \
+ IoMarkIrpPending(_Request)
+
+
+//
+// VOID
+// UNMARK_REQUEST_PENDING(
+// IN PREQUEST Request
+// );
+//
+// Marks that a request will not pend.
+//
+
+#define UNMARK_REQUEST_PENDING(_Request) \
+ (((IoGetCurrentIrpStackLocation(_Request))->Control) &= ~SL_PENDING_RETURNED)
+
+
+//
+// UCHAR
+// REQUEST_MAJOR_FUNCTION
+// IN PREQUEST Request
+// );
+//
+// Returns the major function code of a request.
+//
+
+#define REQUEST_MAJOR_FUNCTION(_Request) \
+ ((IoGetCurrentIrpStackLocation(_Request))->MajorFunction)
+
+
+//
+// UCHAR
+// REQUEST_MINOR_FUNCTION
+// IN PREQUEST Request
+// );
+//
+// Returns the minor function code of a request.
+//
+
+#define REQUEST_MINOR_FUNCTION(_Request) \
+ ((IoGetCurrentIrpStackLocation(_Request))->MinorFunction)
+
+
+//
+// PNDIS_BUFFER
+// REQUEST_NDIS_BUFFER
+// IN PREQUEST Request
+// );
+//
+// Returns the NDIS buffer chain associated with a request.
+//
+
+#define REQUEST_NDIS_BUFFER(_Request) \
+ ((PNDIS_BUFFER)((_Request)->MdlAddress))
+
+
+//
+// PVOID
+// REQUEST_TDI_BUFFER
+// IN PREQUEST Request
+// );
+//
+// Returns the TDI buffer chain associated with a request.
+//
+
+#define REQUEST_TDI_BUFFER(_Request) \
+ ((PVOID)((_Request)->MdlAddress))
+
+
+//
+// PVOID
+// REQUEST_OPEN_CONTEXT(
+// IN PREQUEST Request
+// );
+//
+// Gets the context associated with an opened address/connection/control channel.
+//
+
+#define REQUEST_OPEN_CONTEXT(_Request) \
+ (((IoGetCurrentIrpStackLocation(_Request))->FileObject)->FsContext)
+
+
+//
+// PVOID
+// REQUEST_OPEN_TYPE(
+// IN PREQUEST Request
+// );
+//
+// Gets the type associated with an opened address/connection/control channel.
+//
+
+#define REQUEST_OPEN_TYPE(_Request) \
+ (((IoGetCurrentIrpStackLocation(_Request))->FileObject)->FsContext2)
+
+
+//
+// PFILE_FULL_EA_INFORMATION
+// OPEN_REQUEST_EA_INFORMATION(
+// IN PREQUEST Request
+// );
+//
+// Returns the EA information associated with an open/close request.
+//
+
+#define OPEN_REQUEST_EA_INFORMATION(_Request) \
+ ((PFILE_FULL_EA_INFORMATION)((_Request)->AssociatedIrp.SystemBuffer))
+
+
+//
+// PTDI_REQUEST_KERNEL
+// REQUEST_PARAMETERS(
+// IN PREQUEST Request
+// );
+//
+// Obtains a pointer to the parameters of a request.
+//
+
+#define REQUEST_PARAMETERS(_Request) \
+ (&((IoGetCurrentIrpStackLocation(_Request))->Parameters))
+
+
+//
+// PLIST_ENTRY
+// REQUEST_LINKAGE(
+// IN PREQUEST Request
+// );
+//
+// Returns a pointer to a linkage field in the request.
+//
+
+#define REQUEST_LINKAGE(_Request) \
+ (&((_Request)->Tail.Overlay.ListEntry))
+
+
+//
+// PREQUEST
+// LIST_ENTRY_TO_REQUEST(
+// IN PLIST_ENTRY ListEntry
+// );
+//
+// Returns a request given a linkage field in it.
+//
+
+#define LIST_ENTRY_TO_REQUEST(_ListEntry) \
+ ((PREQUEST)(CONTAINING_RECORD(_ListEntry, REQUEST, Tail.Overlay.ListEntry)))
+
+
+//
+// PUNICODE_STRING
+// REQUEST_OPEN_NAME(
+// IN PREQUEST Request
+// );
+//
+// Used to access the RemainingName field of a request.
+//
+
+#define REQUEST_OPEN_NAME(_Request) \
+ (&((IoGetCurrentIrpStackLocation(_Request))->FileObject->FileName))
+
+//
+// NTSTATUS
+// REQUEST_STATUS(
+// IN PREQUEST Request
+// );
+//
+// Used to access the status field of a request.
+//
+
+#define REQUEST_STATUS(_Request) \
+ (_Request)->IoStatus.Status
+
+
+//
+// ULONG
+// REQUEST_INFORMATION(
+// IN PREQUEST Request)
+// );
+//
+// Used to access the information field of a request.
+//
+
+#define REQUEST_INFORMATION(_Request) \
+ (_Request)->IoStatus.Information
+
+
+//
+// VOID
+// SpxCompleteRequest(
+// IN PREQUEST Request
+// );
+//
+// Completes a request whose status and information fields have
+// been filled in.
+//
+
+#define SpxCompleteRequest(_Request) \
+ { \
+ CTELockHandle _CancelIrql; \
+ DBGPRINT(TDI, INFO, \
+ ("SpxCompleteRequest: Completing %lx with %lx\n", \
+ (_Request), REQUEST_STATUS(_Request))); \
+ \
+ IoAcquireCancelSpinLock( &_CancelIrql ); \
+ (_Request)->CancelRoutine = NULL; \
+ IoReleaseCancelSpinLock( _CancelIrql ); \
+ IoCompleteRequest (_Request, IO_NETWORK_INCREMENT); \
+ }
+
+#else
+
+//
+// These routines must be defined for portability to a VxD.
+//
+
+#endif
+
+#include "fwddecls.h"
+
+// BUGBUG: This should go in ntddk.h?
+#ifndef _NTIOAPI_
+#include "spxntdef.h"
+#endif
+
+#include "spxreg.h"
+#include "spxdev.h"
+#include "spxbind.h"
+#include "spxtimer.h"
+#include "spxpkt.h"
+#include "spxerror.h"
+#include "spxaddr.h"
+#include "spxconn.h"
+#include "spxrecv.h"
+#include "spxsend.h"
+#include "spxquery.h"
+#include "spxmem.h"
+#include "spxutils.h"
+
+
+// Globals
+#include "globals.h"
+
+
+
+
diff --git a/private/ntos/tdi/isnp/spx/h/spxaddr.h b/private/ntos/tdi/isnp/spx/h/spxaddr.h
new file mode 100644
index 000000000..b49a4791e
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxaddr.h
@@ -0,0 +1,426 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxaddr.h
+
+Abstract:
+
+
+Author:
+
+ Adam Barr (adamba ) Original Version
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+#define DYNSKT_RANGE_START 0x4000
+#define DYNSKT_RANGE_END 0x7FFF
+#define SOCKET_UNIQUENESS 1
+
+// This structure is pointed to by the FsContext field in the FILE_OBJECT
+// for this Address. This structure is the base for all activities on
+// the open file object within the transport provider. All active connections
+// on the address point to this structure, although no queues exist here to do
+// work from. This structure also maintains a reference to an ADDRESS
+// structure, which describes the address that it is bound to.
+
+#define AFREF_CREATE 0
+#define AFREF_VERIFY 1
+#define AFREF_INDICATION 2
+#define AFREF_CONN_ASSOC 3
+
+#define AFREF_TOTAL 4
+
+typedef struct _SPX_ADDR_FILE {
+
+#if DBG
+ ULONG saf_RefTypes[AFREF_TOTAL];
+#endif
+
+ CSHORT saf_Type;
+ CSHORT saf_Size;
+
+ // number of references to this object.
+ ULONG saf_RefCount;
+
+ // Linkage in address list.
+ struct _SPX_ADDR_FILE * saf_Next;
+ struct _SPX_ADDR_FILE * saf_GlobalNext;
+
+ // List of associated connection/active or otherwise
+ struct _SPX_CONN_FILE * saf_AssocConnList;
+
+ // the current state of the address file structure; this is either open or
+ // closing
+ USHORT saf_Flags;
+
+ // address to which we are bound, pointer to its lock.
+ struct _SPX_ADDR * saf_Addr;
+ CTELock * saf_AddrLock;
+
+#ifdef ISN_NT
+ // easy backlink to file object.
+ PFILE_OBJECT saf_FileObject;
+#endif
+
+ // device to which we are attached.
+ struct _DEVICE * saf_Device;
+
+ // This holds the request used to close this address file,
+ // for pended completion.
+ PREQUEST saf_CloseReq;
+
+ // This function pointer points to a connection indication handler for this
+ // Address. Any time a connect request is received on the address, this
+ // routine is invoked.
+ PTDI_IND_CONNECT saf_ConnHandler;
+ PVOID saf_ConnHandlerCtx;
+
+ // The following function pointer always points to a TDI_IND_DISCONNECT
+ // handler for the address.
+ PTDI_IND_DISCONNECT saf_DiscHandler;
+ PVOID saf_DiscHandlerCtx;
+
+ // The following function pointer always points to a TDI_IND_RECEIVE
+ // event handler for connections on this address.
+ PTDI_IND_RECEIVE saf_RecvHandler;
+ PVOID saf_RecvHandlerCtx;
+
+ // Send possible handler
+ PTDI_IND_SEND_POSSIBLE saf_SendPossibleHandler;
+ PVOID saf_SendPossibleHandlerCtx;
+
+ // !!!We do not do datagrams or expedited data!!!
+
+ // The following function pointer always points to a TDI_IND_ERROR
+ // handler for the address.
+ PTDI_IND_ERROR saf_ErrHandler;
+ PVOID saf_ErrHandlerCtx;
+ PVOID saf_ErrHandlerOwner;
+
+
+} SPX_ADDR_FILE, *PSPX_ADDR_FILE;
+
+#define SPX_ADDRFILE_OPENING 0x0000 // not yet open for business
+#define SPX_ADDRFILE_OPEN 0x0001 // open for business
+#define SPX_ADDRFILE_CLOSING 0x0002 // closing
+#define SPX_ADDRFILE_STREAM 0x0004 // Opened for stream mode operation
+#define SPX_ADDRFILE_CONNIND 0x0008 // Connect ind in progress
+#define SPX_ADDRFILE_SPX2 0x0010 // Attempt SPX2 address file
+#define SPX_ADDRFILE_NOACKWAIT 0x0020 // Dont delay acks on assoc connections
+#define SPX_ADDRFILE_IPXHDR 0x0040 // Pass ipx hdr on all assoc connections
+// ***STOP*** ***STOP*** ***STOP*** ***STOP*** ***STOP*** ***STOP*** ***STOP***
+// If you are adding any more states to this beyond 0x0080, MAKE SURE to go
+// in code and change statements like (Flags & SPX_***) to
+// ((Flags & SPX_**) != 0)!!! I dont want to make that change that at this stage.
+// ***STOP*** ***STOP*** ***STOP*** ***STOP*** ***STOP*** ***STOP*** ***STOP***
+
+// This structure defines an ADDRESS, or active transport address,
+// maintained by the transport provider. It contains all the visible
+// components of the address (such as the TSAP and network name components),
+// and it also contains other maintenance parts, such as a reference count,
+// ACL, and so on.
+
+#define AREF_ADDR_FILE 0
+#define AREF_LOOKUP 1
+#define AREF_RECEIVE 2
+
+#define AREF_TOTAL 4
+
+typedef struct _SPX_ADDR {
+
+#if DBG
+ ULONG sa_RefTypes[AREF_TOTAL];
+#endif
+
+ USHORT sa_Size;
+ CSHORT sa_Type;
+
+ // number of references to this object.
+ ULONG sa_RefCount;
+
+ // next address/this device object.
+ struct _SPX_ADDR * sa_Next;
+
+ // The following fields are used to maintain state about this address.
+ // attributes of the address.
+ ULONG sa_Flags;
+
+ // Next addressfile for this address
+ struct _SPX_ADDR_FILE * sa_AddrFileList;
+
+ // List of inactive connections and active connections on this address file.
+ struct _SPX_CONN_FILE * sa_InactiveConnList;
+ struct _SPX_CONN_FILE * sa_ActiveConnList;
+
+ // This is the list of connections which have a POST_LISTEN on them. They
+ // do not have a local connection id at this point. But will, when they move
+ // from here to the ActiveConnList, when the listen is satisfied (no matter
+ // if the accept has not been posted yet, in the case of non-autoaccept listens)
+ struct _SPX_CONN_FILE * sa_ListenConnList;
+
+ CTELock sa_Lock;
+
+ // the socket this address corresponds to.
+ USHORT sa_Socket;
+
+ // device context to which we are attached.
+ struct _DEVICE * sa_Device;
+ CTELock * sa_DeviceLock;
+
+#ifdef ISN_NT
+
+ // These two can be a union because they are not used
+ // concurrently.
+ union {
+
+ // This structure is used for checking share access.
+ SHARE_ACCESS sa_ShareAccess;
+
+ // Used for delaying NbfDestroyAddress to a thread so
+ // we can access the security descriptor.
+ WORK_QUEUE_ITEM sa_DestroyAddrQueueItem;
+
+ } u;
+
+ // This structure is used to hold ACLs on the address.
+ PSECURITY_DESCRIPTOR sa_SecurityDescriptor;
+
+#endif
+
+} SPX_ADDR, *PSPX_ADDR;
+
+#define SPX_ADDR_CLOSING 0x00000001
+
+
+// ROUTINE PROTOTYPES
+
+VOID
+SpxAddrRef(
+ IN PSPX_ADDR Address);
+
+VOID
+SpxAddrLockRef(
+ IN PSPX_ADDR Address);
+
+VOID
+SpxAddrDeref(
+ IN PSPX_ADDR Address);
+
+VOID
+SpxAddrFileRef(
+ IN PSPX_ADDR_FILE pAddrFile);
+
+VOID
+SpxAddrFileLockRef(
+ IN PSPX_ADDR_FILE pAddrFile);
+
+VOID
+SpxAddrFileDeref(
+ IN PSPX_ADDR_FILE pAddrFile);
+
+PSPX_ADDR
+SpxAddrCreate(
+ IN PDEVICE Device,
+ IN USHORT Socket);
+
+NTSTATUS
+SpxAddrFileCreate(
+ IN PDEVICE Device,
+ IN PREQUEST Request,
+ OUT PSPX_ADDR_FILE * ppAddrFile);
+
+NTSTATUS
+SpxAddrOpen(
+ IN PDEVICE Device,
+ IN PREQUEST Request);
+
+NTSTATUS
+SpxAddrSetEventHandler(
+ IN PDEVICE Device,
+ IN PREQUEST pRequest);
+
+NTSTATUS
+SpxAddrFileVerify(
+ IN PSPX_ADDR_FILE pAddrFile);
+
+NTSTATUS
+SpxAddrFileStop(
+ IN PSPX_ADDR_FILE pAddrFile,
+ IN PSPX_ADDR Address);
+
+NTSTATUS
+SpxAddrFileCleanup(
+ IN PDEVICE Device,
+ IN PREQUEST Request);
+
+NTSTATUS
+SpxAddrFileClose(
+ IN PDEVICE Device,
+ IN PREQUEST Request);
+
+PSPX_ADDR
+SpxAddrLookup(
+ IN PDEVICE Device,
+ IN USHORT Socket);
+
+NTSTATUS
+SpxAddrConnByRemoteIdAddrLock(
+ IN PSPX_ADDR pSpxAddr,
+ IN USHORT SrcConnId,
+ IN PBYTE SrcIpxAddr,
+ OUT struct _SPX_CONN_FILE **ppSpxConnFile);
+
+NTSTATUS
+SpxAddrFileDestroy(
+ IN PSPX_ADDR_FILE pAddrFile);
+
+VOID
+SpxAddrDestroy(
+ IN PVOID Parameter);
+
+USHORT
+SpxAddrAssignSocket(
+ IN PDEVICE Device);
+
+BOOLEAN
+SpxAddrExists(
+ IN PDEVICE Device,
+ IN USHORT Socket);
+
+NTSTATUS
+spxAddrRemoveFromGlobalList(
+ IN PSPX_ADDR_FILE pSpxAddrFile);
+
+VOID
+spxAddrInsertIntoGlobalList(
+ IN PSPX_ADDR_FILE pSpxAddrFile);
+
+#if DBG
+#define SpxAddrReference(_Address, _Type) \
+ { \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_Address)->sa_RefTypes[_Type],\
+ 1, \
+ &SpxGlobalInterlock); \
+ SpxAddrRef (_Address); \
+ }
+
+#define SpxAddrLockReference(_Address, _Type) \
+ { \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_Address)->sa_RefTypes[_Type], \
+ 1, \
+ &SpxGlobalInterlock); \
+ SpxAddrLockRef (_Address); \
+ }
+
+#define SpxAddrDereference(_Address, _Type) \
+ { \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_Address)->sa_RefTypes[_Type], \
+ (ULONG)-1, \
+ &SpxGlobalInterlock); \
+ if (SPX_ADD_ULONG( \
+ &(_Address)->sa_RefCount, \
+ (ULONG)-1, \
+ &(_Address)->sa_Lock) == 1) { \
+ SpxAddrDestroy (_Address); \
+ }\
+ }
+
+
+#define SpxAddrFileReference(_AddressFile, _Type) \
+ { \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_AddressFile)->saf_RefTypes[_Type], \
+ 1, \
+ &SpxGlobalInterlock); \
+ SpxAddrFileRef (_AddressFile); \
+ }
+
+#define SpxAddrFileLockReference(_AddressFile, _Type) \
+ { \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_AddressFile)->saf_RefTypes[_Type], \
+ 1, \
+ &SpxGlobalInterlock); \
+ SpxAddrFileLockRef (_AddressFile); \
+ }
+
+#define SpxAddrFileDereference(_AddressFile, _Type) \
+ { \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_AddressFile)->saf_RefTypes[_Type], \
+ (ULONG)-1, \
+ &SpxGlobalInterlock); \
+ SpxAddrFileDeref (_AddressFile); \
+ }
+
+#define SpxAddrFileTransferReference(_AddressFile, _OldType, _NewType) \
+ { \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_AddressFile)->saf_RefTypes[_NewType], \
+ 1, \
+ &SpxGlobalInterlock); \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_AddressFile)->saf_RefTypes[_OldType], \
+ (ULONG)-1, \
+ &SpxGlobalInterlock); \
+ }
+
+#else // DBG
+
+#define SpxAddrReference(_Address, _Type) \
+ SPX_ADD_ULONG( \
+ &(_Address)->sa_RefCount, \
+ 1, \
+ (_Address)->sa_DeviceLock)
+
+#define SpxAddrLockReference(_Address, _Type) \
+ SPX_ADD_ULONG( \
+ &(_Address)->sa_RefCount, \
+ 1, \
+ (_Address)->sa_DeviceLock);
+
+#define SpxAddrDereference(_Address, _Type) \
+ if (SPX_ADD_ULONG( \
+ &(_Address)->sa_RefCount, \
+ (ULONG)-1, \
+ &(_Address)->sa_Lock) == 1) { \
+ SpxAddrDestroy (_Address); \
+ }
+
+#define SpxAddrFileReference(_AddressFile, _Type) \
+ SPX_ADD_ULONG( \
+ &(_AddressFile)->saf_RefCount, \
+ 1, \
+ (_AddressFile)->saf_AddrLock)
+
+#define SpxAddrFileLockReference(_AddressFile, _Type) \
+ SPX_ADD_ULONG( \
+ &(_AddressFile)->saf_RefCount, \
+ 1, \
+ (_AddressFile)->saf_AddrLock);
+
+#define SpxAddrFileDereference(_AddressFile, _Type) \
+ if (SPX_ADD_ULONG( \
+ &(_AddressFile)->saf_RefCount, \
+ (ULONG)-1, \
+ (_AddressFile)->saf_AddrLock) == 1) { \
+ SpxAddrFileDestroy (_AddressFile); \
+ }
+
+#define SpxAddrFileTransferReference(_AddressFile, _OldType, _NewType)
+
+#endif // DBG
diff --git a/private/ntos/tdi/isnp/spx/h/spxbind.h b/private/ntos/tdi/isnp/spx/h/spxbind.h
new file mode 100644
index 000000000..81ad6ac58
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxbind.h
@@ -0,0 +1,32 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxbind.h
+
+Abstract:
+
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+NTSTATUS
+SpxInitBindToIpx(
+ VOID);
+
+VOID
+SpxUnbindFromIpx(
+ VOID);
+
diff --git a/private/ntos/tdi/isnp/spx/h/spxconn.h b/private/ntos/tdi/isnp/spx/h/spxconn.h
new file mode 100644
index 000000000..bb1173432
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxconn.h
@@ -0,0 +1,1666 @@
+/*++
+
+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.
+// BUGBUG: 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);
+
+//
+// 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 = (_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)); \
+ }
+#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; \
+ } \
+ }
+
+
diff --git a/private/ntos/tdi/isnp/spx/h/spxdev.h b/private/ntos/tdi/isnp/spx/h/spxdev.h
new file mode 100644
index 000000000..30c0adae5
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxdev.h
@@ -0,0 +1,204 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxdev.h
+
+Abstract:
+
+ This module contains definitions specific to the
+ SPX module of the ISN transport.
+
+Author:
+
+ Adam Barr (adamba ) Original Version
+ Nikhil Kamkolkar (nikhilk) 17-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+
+// Hash buckets for SPX_ADDR done using socket number
+#define NUM_SPXADDR_HASH_BUCKETS 8
+#define NUM_SPXADDR_HASH_MASK 7
+#define NUM_SPXCONN_HASH_BUCKETS 8
+#define NUM_SPXCONN_HASH_MASK 7
+
+// This structure defines the per-device structure for SPX
+// (one of these is allocated globally).
+#define DREF_CREATE 0
+#define DREF_LOADED 1
+#define DREF_ADAPTER 2
+#define DREF_ADDRESS 3
+#define DREF_ORPHAN 4
+
+#define DREF_TOTAL 5
+
+typedef struct _DEVICE {
+
+ DEVICE_OBJECT dev_DevObj; // the I/O system's device object.
+
+#if DBG
+ ULONG dev_RefTypes[DREF_TOTAL];
+#endif
+
+ CSHORT dev_Type; // type of this structure
+ USHORT dev_Size; // size of this structure
+
+#if DBG
+ UCHAR dev_Signature1[4]; // contains "SPX1"
+#endif
+
+ // activity count/this provider.
+ LONG dev_RefCount;
+ UCHAR dev_State;
+
+ // number of adapters IPX is bound to.
+ USHORT dev_Adapters;
+
+ // GLOBAL lock for reference count (used in ExInterlockedXxx calls).
+ CTELock dev_Interlock;
+ CTELock dev_Lock;
+
+ // Hash table of lists of addresses opened on this device
+ struct _SPX_ADDR * dev_AddrHashTable[NUM_SPXADDR_HASH_BUCKETS];
+
+ // List of all active connections, later this be a tree.
+ struct _SPX_CONN_FILE * dev_GlobalActiveConnList[NUM_SPXCONN_HASH_BUCKETS];
+ USHORT dev_NextConnId;
+
+ // Other configuration parameters.
+ // Where the current socket allocation is.
+ USHORT dev_CurrentSocket;
+
+ // Our node and network.
+ UCHAR dev_Network[4];
+ UCHAR dev_Node[6];
+
+ // Pointer to the config information from registry
+ PCONFIG dev_ConfigInfo;
+
+ // Control channel identifier
+ ULONG dev_CcId;
+
+ // These are kept around for error logging, and stored right
+ // after this structure.
+ PWCHAR dev_DeviceName;
+#if defined(_PNP_POWER)
+ USHORT dev_DeviceNameLen;
+#else
+ ULONG dev_DeviceNameLen;
+#endif _PNP_POWER
+
+#if DBG
+ UCHAR dev_Signature2[4]; // contains "SPX2"
+#endif
+
+ // Handle to ndis buffer pool for spx stack.
+ NDIS_HANDLE dev_NdisBufferPoolHandle;
+
+ // registration handle with tdi clients.
+#if defined(_PNP_POWER)
+ HANDLE dev_TdiRegistrationHandle;
+#endif _PNP_POWER
+
+ // This interlock is used to guard access to the statistics
+ // define below.
+ KSPIN_LOCK dev_StatInterlock; // for ULONG quantities
+ KSPIN_LOCK dev_StatSpinLock; // for LARGE_INTEGER quantities
+
+ // Counters for most of the statistics that SPX maintains;
+ // some of these are kept elsewhere. Including the structure
+ // itself wastes a little space but ensures that the alignment
+ // inside the structure is correct.
+ TDI_PROVIDER_STATISTICS dev_Stat;
+
+ // This resource guards access to the ShareAccess
+ // and SecurityDescriptor fields in addresses.
+ ERESOURCE dev_AddrResource;
+
+ // The following structure contains statistics counters for use
+ // by TdiQueryInformation and TdiSetInformation. They should not
+ // be used for maintenance of internal data structures.
+ TDI_PROVIDER_INFO dev_ProviderInfo; // information about this provider.
+
+} DEVICE, * PDEVICE;
+
+// device state definitions
+#if defined(_PNP_POWER)
+#define DEVICE_STATE_CLOSED 0x00 // Initial state
+#define DEVICE_STATE_LOADED 0x01 // Loaded and bound to IPX but no adapters
+#define DEVICE_STATE_OPEN 0x02 // Fully operational
+#define DEVICE_STATE_STOPPING 0x03 // Unload has been initiated, The I/O system
+ // will not call us until nobody above has Netbios open.
+#else
+#define DEVICE_STATE_CLOSED 0x00
+#define DEVICE_STATE_OPEN 0x01
+#define DEVICE_STATE_STOPPING 0x02
+#endif _PNP_POWER
+
+
+// SPX device name
+#define SPX_DEVICE_NAME L"\\Device\\NwlnkSpx"
+
+#define SPX_TDI_RESOURCES 9
+
+
+// MACROS
+#if DBG
+
+#define SpxReferenceDevice(_Device, _Type) \
+ { \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_Device)->dev_RefTypes[_Type], \
+ 1, \
+ &SpxGlobalInterlock); \
+ \
+ (VOID)InterlockedIncrement ( \
+ &(_Device)->dev_RefCount); \
+ }
+
+#define SpxDereferenceDevice(_Device, _Type) \
+ { \
+ (VOID)SPX_ADD_ULONG ( \
+ &(_Device)->dev_RefTypes[_Type], \
+ (ULONG)-1, \
+ &SpxGlobalInterlock); \
+ SpxDerefDevice (_Device); \
+ }
+
+#else
+
+#define SpxReferenceDevice(_Device, _Type) \
+ { \
+ (VOID)InterlockedIncrement ( \
+ &(_Device)->dev_RefCount); \
+ }
+
+#define SpxDereferenceDevice(_Device, _Type) \
+ SpxDerefDevice (_Device)
+
+#endif
+
+// EXPORTED ROUTINES
+
+VOID
+SpxDestroyDevice(
+ IN PDEVICE Device);
+
+VOID
+SpxDerefDevice(
+ IN PDEVICE Device);
+
+NTSTATUS
+SpxInitCreateDevice(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING DeviceName,
+ IN OUT PDEVICE *DevicePtr);
diff --git a/private/ntos/tdi/isnp/spx/h/spxerror.h b/private/ntos/tdi/isnp/spx/h/spxerror.h
new file mode 100644
index 000000000..761342512
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxerror.h
@@ -0,0 +1,246 @@
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ spxerror.h
+
+Abstract:
+
+ This module contains some error definitions for spx.
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk@microsoft.com)
+
+Revision History:
+
+Notes: Tab stop: 4
+--*/
+
+// Define the modules names for SPX - use the high bits.
+#define SPXDRVR 0x00010000
+#define SPXREG 0x00020000
+#define SPXDEV 0x00030000
+#define SPXBIND 0x00040000
+#define SPXRECV 0x00050000
+#define SPXSEND 0x00060000
+#define SPXTIMER 0x00070000
+#define SPXERROR 0x00080000
+#define SPXPKT 0x00090000
+#define SPXUTILS 0x000a0000
+#define SPXCPKT 0x000b0000
+#define SPXCONN 0x000c0000
+#define SPXADDR 0x000d0000
+#define SPXCUTIL 0x000e0000
+#define SPXINIT 0x000f0000
+#define SPXMEM 0x00100000
+#define SPXQUERY 0x00200000
+
+
+// DEBUGGING SUPPORT:
+// Debugging messages are provided per-subsystem defined here, and within
+// the subsystems, there are 4 levels of messages.
+//
+// The four levels of debug messages are:
+//
+// INFO: Informational messages, eg., entry exit in routines
+// DBG: Used when debugging some msgs are turned from info to dbg
+// WARN: Something went wrong, but its not an error, eg., packet was not ours
+// ERR: Error situations, but we can still run if a retry happens
+// FATAL: In this situation, the driver is not operational
+
+#define DBG_LEVEL_INFO 0x4000
+#define DBG_LEVEL_DBG 0x5000
+#define DBG_LEVEL_DBG1 0x5001
+#define DBG_LEVEL_DBG2 0x5002
+#define DBG_LEVEL_DBG3 0x5003
+#define DBG_LEVEL_WARN 0x6000
+#define DBG_LEVEL_ERR 0x7000
+#define DBG_LEVEL_FATAL 0x8000
+
+// SUBSYSTEMS
+#define DBG_COMP_DEVICE 0x00000001
+#define DBG_COMP_CREATE 0x00000002
+#define DBG_COMP_ADDRESS 0x00000004
+#define DBG_COMP_SEND 0x00000008
+#define DBG_COMP_NDIS 0x00000010
+#define DBG_COMP_RECEIVE 0x00000020
+#define DBG_COMP_CONFIG 0x00000040
+#define DBG_COMP_PACKET 0x00000080
+#define DBG_COMP_RESOURCES 0x00000100
+#define DBG_COMP_BIND 0x00000200
+#define DBG_COMP_UNLOAD 0x00000400
+#define DBG_COMP_DUMP 0x00000800
+#define DBG_COMP_REFCOUNTS 0x00001000
+#define DBG_COMP_SYSTEM 0x00002000
+#define DBG_COMP_CRITSEC 0x00004000
+#define DBG_COMP_UTILS 0x00008000
+#define DBG_COMP_TDI 0x00010000
+#define DBG_COMP_CONNECT 0x00020000
+#define DBG_COMP_DISC 0x00040000
+#define DBG_COMP_ACTION 0x00080000
+#define DBG_COMP_STATE 0x00100000
+
+#define DBG_COMP_MOST (DBG_COMP_DEVICE | \
+ DBG_COMP_CREATE | \
+ DBG_COMP_ADDRESS | \
+ DBG_COMP_SEND | \
+ DBG_COMP_NDIS | \
+ DBG_COMP_RECEIVE | \
+ DBG_COMP_CONFIG | \
+ DBG_COMP_PACKET | \
+ DBG_COMP_RESOURCES | \
+ DBG_COMP_BIND | \
+ DBG_COMP_UNLOAD | \
+ DBG_COMP_DUMP | \
+ DBG_COMP_REFCOUNTS | \
+ DBG_COMP_SYSTEM | \
+ DBG_COMP_CRITSEC | \
+ DBG_COMP_UTILS | \
+ DBG_COMP_TDI | \
+ DBG_COMP_CONNECT | \
+ DBG_COMP_DISC | \
+ DBG_COMP_ACTION | \
+ DBG_COMP_STATE)
+
+
+// More debugging support. These values define the dumping components.
+// There are a max of 32 such components that can be defined. Each of
+// these are associated with a dump routine. It one is specified and
+// enabled, periodically it is called. It is upto that component to
+// decide what it wants to do
+
+#define DBG_DUMP_DEF_INTERVAL 30 // In Seconds
+
+// This defines the number of times an error has to happen consecutively before
+// it gets logged again.
+#define ERROR_CONSEQ_FREQ 200
+#define ERROR_CONSEQ_TIME (60*30) // 30 minutes
+
+#ifdef DBG
+typedef VOID (*DUMP_ROUTINE)(VOID);
+
+extern
+BOOLEAN
+SpxDumpComponents(
+ IN PVOID Context);
+
+#endif
+
+//
+// PROTOTYPES
+//
+
+BOOLEAN
+SpxFilterErrorLogEntry(
+ IN NTSTATUS UniqueErrorCode,
+ IN NTSTATUS NtStatusCode,
+ IN PVOID RawDataBuf OPTIONAL,
+ IN LONG RawDataLen);
+VOID
+SpxWriteResourceErrorLog(
+ IN PDEVICE Device,
+ IN ULONG BytesNeeded,
+ IN ULONG UniqueErrorValue);
+
+VOID
+SpxWriteGeneralErrorLog(
+ IN PDEVICE Device,
+ IN NTSTATUS ErrorCode,
+ IN ULONG UniqueErrorValue,
+ IN NTSTATUS FinalStatus,
+ IN PWSTR SecondString,
+ IN PVOID RawDataBuf OPTIONAL,
+ IN LONG RawDataLen);
+
+
+//
+// MACROS
+//
+
+#if DBG
+#define LOG_ERROR(Error, NtStatus, SecondString, RawData, RawDataLen) \
+ { \
+ SpxWriteGeneralErrorLog( \
+ SpxDevice, \
+ Error, \
+ FILENUM | __LINE__, \
+ NtStatus, \
+ SecondString, \
+ RawData, \
+ RawDataLen); \
+ }
+
+#define RES_LOG_ERROR(BytesNeeded) \
+ { \
+ SpxWriteResourceErrorLog( \
+ SpxDevice, \
+ BytesNeeded, \
+ FILENUM | __LINE__); \
+ }
+
+#else
+
+#define LOG_ERROR(Error, NtStatus, SecondString, RawData, RawDataLen) \
+ { \
+ SpxWriteGeneralErrorLog( \
+ SpxDevice, \
+ Error, \
+ FILENUM | __LINE__, \
+ NtStatus, \
+ SecondString, \
+ RawData, \
+ RawDataLen); \
+ }
+
+#define RES_LOG_ERROR(BytesNeeded) \
+ { \
+ SpxWriteResourceErrorLog( \
+ SpxDevice, \
+ BytesNeeded, \
+ FILENUM | __LINE__); \
+ }
+
+#endif
+
+
+#if DBG
+
+#define DBGPRINT(Component, Level, Fmt) \
+ { \
+ if (((DBG_LEVEL_ ## Level) >= SpxDebugLevel) && \
+ (SpxDebugSystems & (DBG_COMP_ ## Component))) \
+ { \
+ DbgPrint("SPX: "); \
+ DbgPrint Fmt; \
+ } \
+ }
+
+#define DBGBRK(Level) \
+ { \
+ if ((DBG_LEVEL_ ## Level) >= SpxDebugLevel) \
+ DbgBreakPoint(); \
+ }
+
+#define TMPLOGERR() \
+ { \
+ DBGPRINT(MOST, ERR, \
+ ("TempErrLog: %s, Line %ld\n", __FILE__, __LINE__)); \
+ }
+
+#else
+#define DBGPRINT(Component, Level, Fmt)
+#define DBGBRK(Level)
+#define TMPLOGERR()
+#endif
+
+extern
+VOID
+SpxWriteErrorLogEntry(
+ IN NTSTATUS UniqueErrorCode,
+ IN ULONG UniqueErrorValue,
+ IN NTSTATUS NtStatusCode,
+ IN PVOID RawDataBuf OPTIONAL,
+ IN LONG RawDataLen);
diff --git a/private/ntos/tdi/isnp/spx/h/spxmem.h b/private/ntos/tdi/isnp/spx/h/spxmem.h
new file mode 100644
index 000000000..717c69a6b
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxmem.h
@@ -0,0 +1,142 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxmem.h
+
+Abstract:
+
+ This module contains memory management routines.
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 17-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+
+
+#define QWORDSIZEBLOCK(Size) (((Size)+sizeof(LARGE_INTEGER)-1) & ~(sizeof(LARGE_INTEGER)-1))
+#define SPX_MEMORY_SIGNATURE *(PULONG)"SPXM"
+#define ZEROED_MEMORY_TAG 0xF0000000
+#define SPX_TAG *((PULONG)"SPX ")
+
+//
+// Definitions for the block management package
+//
+typedef UCHAR BLKID;
+
+// Add a BLKID_xxx and an entry to atalkBlkSize for every block client
+#define BLKID_TIMERLIST (BLKID)0
+#define BLKID_NDISSEND (BLKID)1
+#define BLKID_NDISRECV (BLKID)2
+#define NUM_BLKIDS (BLKID)3
+
+typedef struct _BLK_CHUNK
+{
+ struct _BLK_CHUNK * bc_Next; // Pointer to next in the link
+ SHORT bc_NumFrees; // Number of free blocks in the chunk
+ UCHAR bc_Age; // Number of invocations since the chunk free
+ BLKID bc_BlkId; // Id of the block
+ struct _BLK_HDR * bc_FreeHead; // Head of the list of free blocks
+
+#ifndef SPX_OWN_PACKETS
+ PVOID bc_ChunkCtx; // Used to store pool header if not own
+ // packets
+#else
+ PVOID bc_Padding; // Keep the header 16 bytes
+#endif
+
+ // This is followed by an array of N blks of size M such that the block header
+ // is exactly spxChunkSize[i]
+
+} BLK_CHUNK, *PBLK_CHUNK;
+
+typedef struct _BLK_HDR
+{
+ union
+ {
+ struct _BLK_HDR * bh_Next; // Valid when it is free
+ struct _BLK_CHUNK * bh_pChunk; // The parent chunk to which this blocks belong
+ // valid when it is allocated
+ };
+ PVOID bh_Padding; // Make the header 8 bytes
+} BLK_HDR, *PBLK_HDR;
+
+#define BC_OVERHEAD (8+8) // LARGE_INTEGER for SpxAllocMemory() header and
+ // POOL_HEADER for ExAllocatePool() header
+
+#define BLOCK_POOL_TIMER 1000 // Check interval (1 sec)
+#define MAX_BLOCK_POOL_AGE 3 // # of timer invocations before free
+
+ULONG
+spxBPAgePool(
+ IN PVOID Context,
+ IN BOOLEAN TimerShuttingDown);
+
+
+#ifdef TRACK_MEMORY_USAGE
+
+#define SpxAllocateMemory(Size) SpxAllocMem((Size), FILENUM | __LINE__)
+
+extern
+PVOID
+SpxAllocMem(
+ IN ULONG Size,
+ IN ULONG FileLine
+);
+
+extern
+VOID
+SpxTrackMemoryUsage(
+ IN PVOID pMem,
+ IN BOOLEAN Alloc,
+ IN ULONG FileLine
+);
+
+#else
+
+#define SpxAllocateMemory(Size) SpxAllocMem(Size)
+#define SpxTrackMemoryUsage(pMem, Alloc, FileLine)
+
+extern
+PVOID
+SpxAllocMem(
+ IN ULONG Size
+);
+
+#endif // TRACK_MEMORY_USAGE
+
+VOID
+SpxFreeMemory(
+ IN PVOID pBuf);
+
+#define SpxAllocateZeroedMemory(Size) SpxAllocateMemory((Size) | ZEROED_MEMORY_TAG)
+
+
+extern
+NTSTATUS
+SpxInitMemorySystem(
+ IN PDEVICE pSpxDevice);
+
+extern
+VOID
+SpxDeInitMemorySystem(
+ IN PDEVICE pSpxDevice);
+
+PVOID
+SpxBPAllocBlock(
+ IN BLKID BlockId);
+
+VOID
+SpxBPFreeBlock(
+ IN PVOID pBlock,
+ IN BLKID BlockId);
+
diff --git a/private/ntos/tdi/isnp/spx/h/spxntdef.h b/private/ntos/tdi/isnp/spx/h/spxntdef.h
new file mode 100644
index 000000000..60f9c9e54
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxntdef.h
@@ -0,0 +1,72 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxntdef.h
+
+Abstract:
+
+ Missing nt definitions in ntddk.h
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+
+NTSTATUS
+NTAPI
+NtCreateFile(
+ OUT PHANDLE FileHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN PLARGE_INTEGER AllocationSize OPTIONAL,
+ IN ULONG FileAttributes,
+ IN ULONG ShareAccess,
+ IN ULONG CreateDisposition,
+ IN ULONG CreateOptions,
+ IN PVOID EaBuffer OPTIONAL,
+ IN ULONG EaLength
+ );
+
+NTSTATUS
+NTAPI
+NtClose(
+ IN HANDLE Handle
+ );
+
+NTSTATUS
+NTAPI
+NtDeviceIoControlFile(
+ IN HANDLE FileHandle,
+ IN HANDLE Event OPTIONAL,
+ IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
+ IN PVOID ApcContext OPTIONAL,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN ULONG IoControlCode,
+ IN PVOID InputBuffer OPTIONAL,
+ IN ULONG InputBufferLength,
+ OUT PVOID OutputBuffer OPTIONAL,
+ IN ULONG OutputBufferLength
+ );
+
+NTSTATUS
+NTAPI
+NtWaitForSingleObject(
+ IN HANDLE Handle,
+ IN BOOLEAN Alertable,
+ IN PLARGE_INTEGER Timeout OPTIONAL
+ );
+
+
diff --git a/private/ntos/tdi/isnp/spx/h/spxpkt.h b/private/ntos/tdi/isnp/spx/h/spxpkt.h
new file mode 100644
index 000000000..b643ed95b
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxpkt.h
@@ -0,0 +1,466 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxpkt.h
+
+Abstract:
+
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+// Use our own NDIS packets
+#define SPX_OWN_PACKETS 1
+
+// Offsets into the IPX header
+#define IPX_HDRSIZE 30 // Size of the IPX header
+#define IPX_CHECKSUM 0 // Checksum
+#define IPX_LENGTH 2 // Length
+#define IPX_XPORTCTL 4 // Transport Control
+#define IPX_PKTTYPE 5 // Packet Type
+#define IPX_DESTADDR 6 // Dest. Address (Total)
+#define IPX_DESTNET 6 // Dest. Network Address
+#define IPX_DESTNODE 10 // Dest. Node Address
+#define IPX_DESTSOCK 16 // Dest. Socket Number
+#define IPX_SRCADDR 18 // Source Address (Total)
+#define IPX_SRCNET 18 // Source Network Address
+#define IPX_SRCNODE 22 // Source Node Address
+#define IPX_SRCSOCK 28 // Source Socket Number
+
+#define IPX_NET_LEN 4
+#define IPX_NODE_LEN 6
+
+
+#include <packon.h>
+
+// Definition of the IPX/SPX header.
+typedef struct _IPXSPX_HEADER
+{
+ USHORT hdr_CheckSum;
+ USHORT hdr_PktLen;
+ UCHAR hdr_XportCtrl;
+ UCHAR hdr_PktType;
+ UCHAR hdr_DestNet[4];
+ UCHAR hdr_DestNode[6];
+ USHORT hdr_DestSkt;
+ UCHAR hdr_SrcNet[4];
+ UCHAR hdr_SrcNode[6];
+ USHORT hdr_SrcSkt;
+
+ // SPX Header Elements
+ UCHAR hdr_ConnCtrl;
+ UCHAR hdr_DataType;
+ USHORT hdr_SrcConnId;
+ USHORT hdr_DestConnId;
+ USHORT hdr_SeqNum;
+ USHORT hdr_AckNum;
+ USHORT hdr_AllocNum;
+
+ // For non-CR SPXII packets only
+ USHORT hdr_NegSize;
+
+} IPXSPX_HDR, *PIPXSPX_HDR;
+
+#include <packoff.h>
+
+// NDIS Packet size
+#define NDIS_PACKET_SIZE 48
+
+// Minimum header size (doesnt include neg size)
+#define MIN_IPXSPX_HDRSIZE (sizeof(IPXSPX_HDR) - sizeof(USHORT))
+#define MIN_IPXSPX2_HDRSIZE sizeof(IPXSPX_HDR)
+#define SPX_CR_PKTLEN 42
+
+// SPX packet type
+#define SPX_PKT_TYPE 0x5
+
+// Connection control fields
+#define SPX_CC_XHD 0x01
+#define SPX_CC_RES1 0x02
+#define SPX_CC_NEG 0x04
+#define SPX_CC_SPX2 0x08
+#define SPX_CC_EOM 0x10
+#define SPX_CC_ATN 0x20
+#define SPX_CC_ACK 0x40
+#define SPX_CC_SYS 0x80
+
+#define SPX_CC_CR (SPX_CC_ACK | SPX_CC_SYS)
+
+// Data stream types
+#define SPX2_DT_ORDREL 0xFD
+#define SPX2_DT_IDISC 0xFE
+#define SPX2_DT_IDISC_ACK 0xFF
+
+// Negotiation size
+#define SPX_MAX_PACKET 576
+#define SPX_NEG_MIN SPX_MAX_PACKET
+#define SPX_NEG_MAX 65535
+
+// No packet references connection. But if the sends are being aborted, and
+// the packet happens to be owned by ipx at the time, the pkt is dequeued from
+// conn, the ABORT flag is set and conn is referenced for packet.
+//
+// Send packet states
+// ABORT : Used for aborted packet. Calls AbortSendPkt().
+// IPXOWNS : Currently owned by ipx
+// FREEDATA: Frees the data associated with second ndis buffer desc
+// ACKREQ : Only for sequenced packets. Set by retry timer in packets it wants
+// resent (1 for spx1, all pending for spx2) with ack bit set.
+// DESTROY : Only for non-sequenced packets, dequeue packet from list and free.
+// REQ : For both seq/non-seq. A request is associated with the packet
+// SEQ : Packet is a sequenced packet.
+// LASTPKT : Packet is last packet comprising the request, if acked req is done.
+// EOM : Send EOM with the last packet for this request
+// ACKEDPKT: Send completion must only deref req with pkt and complete if zero.
+//
+
+#define SPX_SENDPKT_IDLE 0
+#define SPX_SENDPKT_ABORT 0x0002
+#define SPX_SENDPKT_IPXOWNS 0x0004
+#define SPX_SENDPKT_FREEDATA 0x0008
+#define SPX_SENDPKT_ACKREQ 0x0010
+#define SPX_SENDPKT_DESTROY 0x0020
+#define SPX_SENDPKT_REQ 0x0040
+#define SPX_SENDPKT_SEQ 0x0080
+#define SPX_SENDPKT_LASTPKT 0x0100
+#define SPX_SENDPKT_ACKEDPKT 0x0200
+#define SPX_SENDPKT_EOM 0x0400
+#define SPX_SENDPKT_REXMIT 0x0800
+
+// Packet types
+#define SPX_TYPE_CR 0x01
+#define SPX_TYPE_CRACK 0x02
+#define SPX_TYPE_SN 0x03
+#define SPX_TYPE_SNACK 0x04
+#define SPX_TYPE_SS 0x05
+#define SPX_TYPE_SSACK 0x06
+#define SPX_TYPE_RR 0x07
+#define SPX_TYPE_RRACK 0x08
+#define SPX_TYPE_IDISC 0x09
+#define SPX_TYPE_IDISCACK 0x0a
+#define SPX_TYPE_ORDREL 0x0b
+#define SPX_TYPE_ORDRELACK 0x0c
+#define SPX_TYPE_DATA 0x0d
+#define SPX_TYPE_DATAACK 0x0e
+#define SPX_TYPE_DATANACK 0x0f
+#define SPX_TYPE_PROBE 0x10
+
+// Definition of the protocol reserved field of a send packet.
+// BUGBUG: Make Len/HdrLen USHORTS, move to the end before the
+// sr_SentTime so we dont use padding space.
+typedef struct _SPX_SEND_RESD
+{
+ UCHAR sr_Id; // Set to SPX
+ UCHAR sr_Type; // What kind of packet
+ USHORT sr_State; // State of send packet
+ PVOID sr_Reserved1; // Needed by IPX
+ PVOID sr_Reserved2; // Needed by IPX
+#if defined(_PNP_POWER)
+ PVOID sr_Reserved[SEND_RESERVED_COMMON_SIZE-2]; // needed by IPX for local target
+#endif _PNP_POWER
+ ULONG sr_Len; // Length of packet
+ ULONG sr_HdrLen; // Included header length
+
+ struct _SPX_SEND_RESD * sr_Next; // Points to next packet
+ // in send queue in conn.
+ PREQUEST sr_Request; // request associated
+ ULONG sr_Offset; // Offset in mdl for sends
+
+#ifndef SPX_OWN_PACKETS
+ PVOID sr_FreePtr; // Ptr to use in free chunk
+#endif
+
+ struct _SPX_CONN_FILE * sr_ConnFile; // that this send is on
+ USHORT sr_SeqNum; // Seq num for seq pkts
+
+ // Quad word aligned.
+ LARGE_INTEGER sr_SentTime; // Time packet was sent
+ // Only valid for data pkt
+ // with ACKREQ set.
+
+} SPX_SEND_RESD, *PSPX_SEND_RESD;
+
+
+
+// Recv packet states
+#define SPX_RECVPKT_IDLE 0
+#define SPX_RECVPKT_BUFFERING 0x0001
+#define SPX_RECVPKT_IDISC 0x0002
+#define SPX_RECVPKT_ORD_DISC 0x0004
+#define SPX_RECVPKT_INDICATED 0x0008
+#define SPX_RECVPKT_SENDACK 0x0010
+#define SPX_RECVPKT_EOM 0x0020
+#define SPX_RECVPKT_IMMEDACK 0x0040
+
+#define SPX_RECVPKT_DISCMASK (SPX_RECVPKT_ORD_DISC | SPX_RECVPKT_IDISC)
+
+// Definition of the protocol reserved field of a receive packet.
+typedef struct _SPX_RECV_RESD
+{
+ UCHAR rr_Id; // Set to SPX
+ USHORT rr_State; // State of receive packet
+ struct _SPX_RECV_RESD * rr_Next; // Points to next packet
+ ULONG rr_DataOffset; // To indicate/copy from
+
+#ifndef SPX_OWN_PACKETS
+ PVOID rr_FreePtr; // Ptr to use in free chunk
+#endif
+
+#if DBG
+ USHORT rr_SeqNum; // Seq num of packet
+#endif
+
+ PREQUEST rr_Request; // request waiting on xfer
+ struct _SPX_CONN_FILE * rr_ConnFile; // that this recv is on
+
+} SPX_RECV_RESD, *PSPX_RECV_RESD;
+
+
+// Destination built as an assign of 3 ulongs.
+#define SpxBuildIpxHdr(pIpxSpxHdr, PktLen, pRemAddr, SrcSkt) \
+ { \
+ PBYTE pDestIpxAddr = (PBYTE)pIpxSpxHdr->hdr_DestNet; \
+ (pIpxSpxHdr)->hdr_CheckSum = 0xFFFF; \
+ PUTSHORT2SHORT((PUSHORT)(&(pIpxSpxHdr)->hdr_PktLen), (PktLen)); \
+ (pIpxSpxHdr)->hdr_XportCtrl = 0; \
+ (pIpxSpxHdr)->hdr_PktType = SPX_PKT_TYPE; \
+ *((UNALIGNED ULONG *)pDestIpxAddr) = \
+ *((UNALIGNED ULONG *)pRemAddr); \
+ *((UNALIGNED ULONG *)(pDestIpxAddr+4)) = \
+ *((UNALIGNED ULONG *)(pRemAddr+4)); \
+ *((UNALIGNED ULONG *)(pDestIpxAddr+8)) = \
+ *((UNALIGNED ULONG *)(pRemAddr+8)); \
+ *((UNALIGNED ULONG *)((pIpxSpxHdr)->hdr_SrcNet))= \
+ *((UNALIGNED ULONG *)(SpxDevice->dev_Network)); \
+ *((UNALIGNED ULONG *)((pIpxSpxHdr)->hdr_SrcNode)) = \
+ *((UNALIGNED ULONG *)SpxDevice->dev_Node); \
+ *((UNALIGNED USHORT *)((pIpxSpxHdr)->hdr_SrcNode+4)) = \
+ *((UNALIGNED USHORT *)(SpxDevice->dev_Node+4)); \
+ *((UNALIGNED USHORT *)&((pIpxSpxHdr)->hdr_SrcSkt)) = \
+ SrcSkt; \
+ }
+
+#define SpxCopyIpxAddr(pIpxSpxHdr, pDestIpxAddr) \
+ { \
+ PBYTE pRemAddr = (PBYTE)pIpxSpxHdr->hdr_SrcNet; \
+ *((UNALIGNED ULONG *)pDestIpxAddr) = \
+ *((UNALIGNED ULONG *)pRemAddr); \
+ *((UNALIGNED ULONG *)(pDestIpxAddr+4)) = \
+ *((UNALIGNED ULONG *)(pRemAddr+4)); \
+ *((UNALIGNED ULONG *)(pDestIpxAddr+8)) = \
+ *((UNALIGNED ULONG *)(pRemAddr+8)); \
+ }
+
+#ifndef SPX_OWN_PACKETS
+#define SpxAllocSendPacket(_Device,_SendPacket,_Status) \
+ { \
+ NDIS_HANDLE _Handle; \
+ NdisAllocatePacketPool(_Status, &(_Handle),1,sizeof(SPX_SEND_RESD));\
+ if (*(_Status) == NDIS_STATUS_SUCCESS) { \
+ NdisAllocatePacket(_Status, &(_SendPacket), (_Handle)); \
+ SEND_RESD(_SendPacket)->sr_PoolHandle = (_Handle); \
+ } \
+ }
+
+#define SpxAllocRecvPacket(_Device,_RecvPacket,_Status) \
+ { \
+ NDIS_HANDLE _Handle; \
+ NdisAllocatePacketPool(_Status, &(_Handle),1,sizeof(SPX_RECV_RESD));\
+ if (*(_Status) == NDIS_STATUS_SUCCESS) { \
+ NdisAllocatePacket(_Status, &(_RecvPacket), (_Handle)); \
+ RECV_RESD(_RecvPacket)->sr_PoolHandle = (_Handle); \
+ } \
+ }
+
+#define SpxFreeSendPacket(_Device,_Packet) \
+ { \
+ NDIS_HANDLE _Handle = SEND_RESD(_Packet)->sr_PoolHandle; \
+ NdisFreePacket(_Packet); \
+ NdisFreePacketPool(_Handle); \
+ }
+
+#define SpxFreeRecvPacket(_Device,_Packet) \
+ { \
+ NDIS_HANDLE _Handle = RECV_RESD(_Packet)->rr_PoolHandle; \
+ NdisFreePacket(_Packet); \
+ NdisFreePacketPool(_Handle); \
+ }
+
+#define SpxReInitSendPacket(_Packet)
+ {
+ NDIS_HANDLE _Handle = SEND_RESD(_Packet)->sr_PoolHandle;
+ NdisReInitializePacket(_Packet);
+ SEND_RESD(_Packet)->sr_PoolHandle = (_Handle);
+ }
+
+#define SpxReInitRecvPacket(_Packet)
+ {
+ NDIS_HANDLE _Handle = RECV_RESD(_Packet)->rr_PoolHandle;
+ NdisReInitializePacket(_Packet);
+ RECV_RESD(_Packet)->rr_PoolHandle = (_Handle);
+ }
+
+#define SEND_RESD(_Packet) ((PSPX_SEND_RESD)((_Packet)->ProtocolReserved))
+#define RECV_RESD(_Packet) ((PSPX_RECV_RESD)((_Packet)->ProtocolReserved))
+
+#else
+
+#define SpxAllocSendPacket(_Device, _SendPacket, _Status) \
+ { \
+ if (*(_SendPacket) = SpxBPAllocBlock(BLKID_NDISSEND)) \
+ *(_Status) = NDIS_STATUS_SUCCESS; \
+ else \
+ *(_Status) = NDIS_STATUS_RESOURCES; \
+ }
+
+#define SpxAllocRecvPacket(_Device,_RecvPacket,_Status) \
+ { \
+ if (*(_RecvPacket) = SpxBPAllocBlock(BLKID_NDISRECV)) \
+ *(_Status) = NDIS_STATUS_SUCCESS; \
+ else \
+ *(_Status) = NDIS_STATUS_RESOURCES; \
+ }
+
+#define SpxFreeSendPacket(_Device,_Packet) \
+ { \
+ SpxBPFreeBlock(_Packet, BLKID_NDISSEND); \
+ }
+
+#define SpxFreeRecvPacket(_Device,_Packet) \
+ { \
+ SpxBPFreeBlock(_Packet, BLKID_NDISRECV); \
+ }
+
+#define SpxReInitSendPacket(_Packet) \
+ { \
+ }
+
+#define SpxReInitRecvPacket(_Packet) \
+ { \
+ }
+
+#define SEND_RESD(_Packet) ((PSPX_SEND_RESD)((_Packet)->ProtocolReserved))
+#define RECV_RESD(_Packet) ((PSPX_RECV_RESD)((_Packet)->ProtocolReserved))
+
+#endif
+
+
+//
+// Routine Prototypes
+//
+
+VOID
+SpxPktBuildCr(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ IN struct _SPX_ADDR * pSpxAddr,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State,
+ IN BOOLEAN fSpx2);
+
+VOID
+SpxPktBuildCrAck(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ IN struct _SPX_ADDR * pSpxAddr,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State,
+ IN BOOLEAN fNeg,
+ IN BOOLEAN fSpx2);
+
+VOID
+SpxPktBuildSn(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State);
+
+VOID
+SpxPktBuildSs(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State);
+
+VOID
+SpxPktBuildSsAck(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State);
+
+VOID
+SpxPktBuildSnAck(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State);
+
+VOID
+SpxPktBuildRr(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT SeqNum,
+ IN USHORT State);
+
+VOID
+SpxPktBuildRrAck(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State,
+ IN USHORT MaxPktSize);
+
+VOID
+SpxPktBuildProbe(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State,
+ IN BOOLEAN fSpx2);
+
+VOID
+SpxPktBuildData(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State,
+ IN USHORT Length);
+
+VOID
+SpxCopyBufferChain(
+ OUT PNDIS_STATUS Status,
+ OUT PNDIS_BUFFER * TargetChain,
+ IN NDIS_HANDLE PoolHandle,
+ IN PNDIS_BUFFER SourceChain,
+ IN UINT Offset,
+ IN UINT Length
+ );
+
+VOID
+SpxPktBuildAck(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State,
+ IN BOOLEAN fBuildNack,
+ IN USHORT NumToResend);
+
+VOID
+SpxPktBuildDisc(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ IN PREQUEST pRequest,
+ OUT PNDIS_PACKET * ppPkt,
+ IN USHORT State,
+ IN UCHAR DataType);
+
+VOID
+SpxPktRecvRelease(
+ IN PNDIS_PACKET pPkt);
+
+VOID
+SpxPktSendRelease(
+ IN PNDIS_PACKET pPkt);
diff --git a/private/ntos/tdi/isnp/spx/h/spxquery.h b/private/ntos/tdi/isnp/spx/h/spxquery.h
new file mode 100644
index 000000000..68e0a1ca8
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxquery.h
@@ -0,0 +1,54 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxquery.h
+
+Abstract:
+
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+#define SPX_TDI_PROVIDERINFO_VERSION 0x0001
+#define SPX_PINFOSENDSIZE 0xFFFFFFFF
+#define SPX_PINFOMINMAXLOOKAHEAD 128
+
+//
+// Bug #14498: Indicate to AFD that we are capable of orderly disc so AFD can follow
+// these semantics.
+// In order to have SPXI connections work correctly, we OR this bit in at query time.
+// (see SpxTdiQueryInformation)
+//
+#define SPX_PINFOSERVICEFLAGS ( TDI_SERVICE_CONNECTION_MODE | \
+ TDI_SERVICE_DELAYED_ACCEPTANCE | \
+ TDI_SERVICE_MESSAGE_MODE | \
+ TDI_SERVICE_ERROR_FREE_DELIVERY) // | \
+ // TDI_SERVICE_ORDERLY_RELEASE )
+
+VOID
+SpxQueryInitProviderInfo(
+ PTDI_PROVIDER_INFO ProviderInfo);
+
+NTSTATUS
+SpxTdiQueryInformation(
+ IN PDEVICE Device,
+ IN PREQUEST Request);
+
+NTSTATUS
+SpxTdiSetInformation(
+ IN PDEVICE Device,
+ IN PREQUEST Request);
+
diff --git a/private/ntos/tdi/isnp/spx/h/spxrecv.h b/private/ntos/tdi/isnp/spx/h/spxrecv.h
new file mode 100644
index 000000000..0ce382990
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxrecv.h
@@ -0,0 +1,89 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxrecv.h
+
+Abstract:
+
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+VOID
+SpxReceive(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN PIPX_LOCAL_TARGET RemoteAddress,
+ IN ULONG MacOptions,
+ IN PUCHAR LookaheadBuffer,
+ IN UINT LookaheadBufferSize,
+ IN UINT LookaheadBufferOffset,
+ IN UINT PacketSize);
+
+VOID
+SpxTransferDataComplete(
+ IN PNDIS_PACKET pNdisPkt,
+ IN NDIS_STATUS NdisStatus,
+ IN UINT BytesTransferred);
+
+VOID
+SpxReceiveComplete(
+ IN USHORT NicId);
+
+VOID
+SpxRecvDataPacket(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN PIPX_LOCAL_TARGET RemoteAddress,
+ IN ULONG MacOptions,
+ IN PUCHAR LookaheadBuffer,
+ IN UINT LookaheadBufferSize,
+ IN UINT LookaheadBufferOffset,
+ IN UINT PacketSize);
+
+VOID
+SpxRecvDiscPacket(
+ IN PUCHAR LookaheadBuffer,
+ IN PIPX_LOCAL_TARGET pRemoteAddr,
+ IN UINT LookaheadSize);
+
+VOID
+SpxRecvSysPacket(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN PIPX_LOCAL_TARGET pRemoteAddr,
+ IN ULONG MacOptions,
+ IN PUCHAR LookaheadBuffer,
+ IN UINT LookaheadBufferSize,
+ IN UINT LookaheadBufferOffset,
+ IN UINT PacketSize);
+
+VOID
+SpxRecvFlushBytes(
+ IN PSPX_CONN_FILE pSpxConnFile,
+ IN ULONG BytesToFlush,
+ IN CTELockHandle LockHandleConn);
+
+VOID
+SpxRecvProcessPkts(
+ IN PSPX_CONN_FILE pSpxConnFile,
+ IN CTELockHandle LockHandleConn);
+
+BOOLEAN
+SpxRecvIndicatePendingData(
+ IN PSPX_CONN_FILE pSpxConnFile,
+ IN CTELockHandle LockHandleConn);
+
diff --git a/private/ntos/tdi/isnp/spx/h/spxreg.h b/private/ntos/tdi/isnp/spx/h/spxreg.h
new file mode 100644
index 000000000..4e0cb469b
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxreg.h
@@ -0,0 +1,65 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxreg.h
+
+Abstract:
+
+ Private include file for the ISN SPX module.
+ file defines all constants and structures necessary for support of
+ the dynamic configuration of ST.
+
+Revision History:
+
+--*/
+
+#define HALFSEC_TO_MS_FACTOR 500
+#define IPX_REG_PATH L"NwlnkIpx\\Linkage"
+
+// These are used to index into the Parameters array in CONFIG.
+#define CONFIG_CONNECTION_COUNT 0
+#define CONFIG_CONNECTION_TIMEOUT 1
+#define CONFIG_INIT_PACKETS 2
+#define CONFIG_MAX_PACKETS 3
+#define CONFIG_INITIAL_RETRANSMIT_TIMEOUT 4
+#define CONFIG_KEEPALIVE_COUNT 5
+#define CONFIG_KEEPALIVE_TIMEOUT 6
+#define CONFIG_WINDOW_SIZE 7
+#define CONFIG_SOCKET_RANGE_START 8
+#define CONFIG_SOCKET_RANGE_END 9
+#define CONFIG_SOCKET_UNIQUENESS 10
+#define CONFIG_MAX_PACKET_SIZE 11
+#define CONFIG_REXMIT_COUNT 12
+
+// Hidden parameters
+#define CONFIG_DISABLE_SPX2 13
+#define CONFIG_ROUTER_MTU 14
+#define CONFIG_BACKCOMP_SPX 15
+
+#define CONFIG_PARAMETERS 16
+
+// Main configuration structure.
+typedef struct _CONFIG {
+
+ ULONG cf_Parameters[CONFIG_PARAMETERS]; // index defined above
+ NDIS_STRING cf_DeviceName; // device name exported
+ PWSTR cf_RegistryPathBuffer; // path to config info
+
+} CONFIG, * PCONFIG;
+
+
+#define PARAM(x) (SpxDevice->dev_ConfigInfo->cf_Parameters[(x)])
+
+
+NTSTATUS
+SpxInitGetConfiguration (
+ IN PUNICODE_STRING RegistryPath,
+ OUT PCONFIG * ConfigPtr);
+
+VOID
+SpxInitFreeConfiguration (
+ IN PCONFIG Config);
+
diff --git a/private/ntos/tdi/isnp/spx/h/spxsend.h b/private/ntos/tdi/isnp/spx/h/spxsend.h
new file mode 100644
index 000000000..40ef810ea
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxsend.h
@@ -0,0 +1,34 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxsend.h
+
+Abstract:
+
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+
+VOID
+SpxSendComplete(
+ IN PNDIS_PACKET NdisPacket,
+ IN NDIS_STATUS NdisStatus);
+
+VOID
+SpxSendPktRelease(
+ IN PNDIS_PACKET pPkt,
+ IN UINT BufCount);
diff --git a/private/ntos/tdi/isnp/spx/h/spxtimer.h b/private/ntos/tdi/isnp/spx/h/spxtimer.h
new file mode 100644
index 000000000..225037bd2
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxtimer.h
@@ -0,0 +1,101 @@
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ spxtimer.h
+
+Abstract:
+
+ This module contains routines to schedule timer events.
+
+Author:
+
+ Jameel Hyder (jameelh@microsoft.com)
+ Nikhil Kamkolkar (nikhilk@microsoft.com)
+
+Revision History:
+ 19 Jun 1992 Initial Version
+
+Notes: Tab stop: 4
+--*/
+
+#define TIMER_DONT_REQUEUE 0
+#define TIMER_REQUEUE_CUR_VALUE 1
+
+typedef ULONG (*TIMER_ROUTINE)(IN PVOID Context, IN BOOLEAN TimerShuttingDown);
+
+extern
+NTSTATUS
+SpxTimerInit(
+ VOID);
+
+extern
+ULONG
+SpxTimerScheduleEvent(
+ IN TIMER_ROUTINE Worker, // Routine to invoke when time expires
+ IN ULONG DeltaTime, // Schedule after this much time
+ IN PVOID pContext); // Context to pass to the routine
+
+extern
+VOID
+SpxTimerFlushAndStop(
+ VOID);
+
+extern
+BOOLEAN
+SpxTimerCancelEvent(
+ IN ULONG TimerId,
+ IN BOOLEAN ReEnqueue);
+
+#define TMR_SIGNATURE *(PULONG)"ATMR"
+#if DBG
+#define VALID_TMR(pTmr) (((pTmr) != NULL) && \
+ ((pTmr)->tmr_Signature == TMR_SIGNATURE))
+#else
+#define VALID_TMR(pTmr) ((pTmr) != NULL)
+#endif
+typedef struct _TimerList
+{
+#if DBG
+ ULONG tmr_Signature;
+#endif
+ struct _TimerList * tmr_Next; // Link to next
+ struct _TimerList ** tmr_Prev; // Link to prev
+ struct _TimerList * tmr_Overflow; // Link to overflow entry in hash table
+ ULONG tmr_AbsTime; // Absolute time, for re-enqueue
+ ULONG tmr_RelDelta; // Relative to the previous entry
+ ULONG tmr_Id; // Unique Id for this event
+ BOOLEAN tmr_Cancelled; // Was the timer cancelled?
+ TIMER_ROUTINE tmr_Worker; // Real Worker
+ PVOID tmr_Context; // Real context
+} TIMERLIST, *PTIMERLIST;
+
+
+#define SpxGetCurrentTime() (SpxTimerCurrentTime/SPX_TIMER_FACTOR)
+#define SpxGetCurrentTick() SpxTimerCurrentTime
+
+// Keep this at a ONE second level.
+#define SPX_TIMER_FACTOR 10 // i.e. 10 ticks per second
+#define SPX_MS_TO_TICKS 100 // Divide ms by this to get ticks
+#define SPX_TIMER_TICK -1000000L // 100ms in 100ns units
+#define SPX_TIMER_WAIT 50 // Time to wait in FlushAndStop in ms
+#define TIMER_HASH_TABLE 32
+
+VOID
+spxTimerDpcRoutine(
+ IN PKDPC pKDpc,
+ IN PVOID pContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2);
+
+VOID
+spxTimerWorker(
+ IN PTIMERLIST pList);
+
+VOID
+spxTimerEnqueue(
+ PTIMERLIST pListNew);
+
+
diff --git a/private/ntos/tdi/isnp/spx/h/spxutils.h b/private/ntos/tdi/isnp/spx/h/spxutils.h
new file mode 100644
index 000000000..074a1649b
--- /dev/null
+++ b/private/ntos/tdi/isnp/spx/h/spxutils.h
@@ -0,0 +1,178 @@
+/*++
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ spxutils.h
+
+Abstract:
+
+
+Author:
+
+ Nikhil Kamkolkar (nikhilk) 11-November-1993
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+
+// For PROTO_SPX, i'd return a device name from the dll of the form
+// \Device\NwlnkSpx\SpxStream (for SOCK_STREAM) or
+// \Device\NwlnkSpx\Spx (for SOCK_SEQPKT)
+//
+// and for PROTO_SPXII (the more common case we hope, even if
+// internally we degrade to SPX1 cause of the remote client's
+// limitations)
+// \Device\NwlnkSpx\Stream (for SOCK_STREAM) or
+// \Device\NwlnkSpx (for SOCK_SEQPKT)
+
+#define SOCKET1STREAM_SUFFIX L"\\SpxStream"
+#define SOCKET1_SUFFIX L"\\Spx"
+#define SOCKET2STREAM_SUFFIX L"\\Stream"
+#define SOCKET1_TYPE_SEQPKT 0
+#define SOCKET2_TYPE_SEQPKT 1
+#define SOCKET1_TYPE_STREAM 2
+#define SOCKET2_TYPE_STREAM 3
+
+#define IN_RANGE(_S, _RangeStart, _RangeEnd) \
+ ((_S >= _RangeStart) && (_S <= _RangeEnd))
+
+
+//
+// The following macros deal with on-the-wire integer and long values
+//
+// On the wire format is big-endian i.e. a long value of 0x01020304 is
+// represented as 01 02 03 04. Similarly an int value of 0x0102 is
+// represented as 01 02.
+//
+// The host format is not assumed since it will vary from processor to
+// processor.
+//
+
+// Get a byte from on-the-wire format to a short in the host format
+#define GETBYTE2SHORT(DstPtr, SrcPtr) \
+ *(PUSHORT)(DstPtr) = (USHORT) (*(PBYTE)(SrcPtr))
+
+// Get a byte from on-the-wire format to a short in the host format
+#define GETBYTE2ULONG(DstPtr, SrcPtr) \
+ *(PULONG)(DstPtr) = (ULONG) (*(PBYTE)(SrcPtr))
+
+// Get a short from on-the-wire format to a dword in the host format
+#define GETSHORT2ULONG(DstPtr, SrcPtr) \
+ *(PULONG)(DstPtr) = ((*((PBYTE)(SrcPtr)+0) << 8) + \
+ (*((PBYTE)(SrcPtr)+1) ))
+
+// Get a short from on-the-wire format to a dword in the host format
+#define GETSHORT2SHORT(DstPtr, SrcPtr) \
+ *(PUSHORT)(DstPtr) = ((*((PBYTE)(SrcPtr)+0) << 8) + \
+ (*((PBYTE)(SrcPtr)+1) ))
+
+// Get a dword from on-the-wire format to a dword in the host format
+#define GETULONG2ULONG(DstPtr, SrcPtr) \
+ *(PULONG)(DstPtr) = ((*((PBYTE)(SrcPtr)+0) << 24) + \
+ (*((PBYTE)(SrcPtr)+1) << 16) + \
+ (*((PBYTE)(SrcPtr)+2) << 8) + \
+ (*((PBYTE)(SrcPtr)+3) ))
+
+// Get a dword from on-the-wire format to a dword in the same format but
+// also watch out for alignment
+#define GETULONG2ULONG_NOCONV(DstPtr, SrcPtr) \
+ *((PBYTE)(DstPtr)+0) = *((PBYTE)(SrcPtr)+0); \
+ *((PBYTE)(DstPtr)+1) = *((PBYTE)(SrcPtr)+1); \
+ *((PBYTE)(DstPtr)+2) = *((PBYTE)(SrcPtr)+2); \
+ *((PBYTE)(DstPtr)+3) = *((PBYTE)(SrcPtr)+3);
+
+// Put a dword from the host format to a short to on-the-wire format
+#define PUTBYTE2BYTE(DstPtr, Src) \
+ *((PBYTE)(DstPtr)) = (BYTE)(Src)
+
+// Put a dword from the host format to a short to on-the-wire format
+#define PUTSHORT2BYTE(DstPtr, Src) \
+ *((PBYTE)(DstPtr)) = ((USHORT)(Src) % 256)
+
+// Put a dword from the host format to a short to on-the-wire format
+#define PUTSHORT2SHORT(DstPtr, Src) \
+ *((PBYTE)(DstPtr)+0) = (BYTE) ((USHORT)(Src) >> 8), \
+ *((PBYTE)(DstPtr)+1) = (BYTE)(Src)
+
+// Put a dword from the host format to a byte to on-the-wire format
+#define PUTULONG2BYTE(DstPtr, Src) \
+ *(PBYTE)(DstPtr) = (BYTE)(Src)
+
+// Put a dword from the host format to a short to on-the-wire format
+#define PUTULONG2SHORT(DstPtr, Src) \
+ *((PBYTE)(DstPtr)+0) = (BYTE) ((ULONG)(Src) >> 8), \
+ *((PBYTE)(DstPtr)+1) = (BYTE) (Src)
+
+// Put a dword from the host format to a dword to on-the-wire format
+#define PUTULONG2ULONG(DstPtr, Src) \
+ *((PBYTE)(DstPtr)+0) = (BYTE) ((ULONG)(Src) >> 24), \
+ *((PBYTE)(DstPtr)+1) = (BYTE) ((ULONG)(Src) >> 16), \
+ *((PBYTE)(DstPtr)+2) = (BYTE) ((ULONG)(Src) >> 8), \
+ *((PBYTE)(DstPtr)+3) = (BYTE) (Src)
+
+// Put a BYTE[4] array into another BYTE4 array.
+#define PUTBYTE42BYTE4(DstPtr, SrcPtr) \
+ *((PBYTE)(DstPtr)+0) = *((PBYTE)(SrcPtr)+0), \
+ *((PBYTE)(DstPtr)+1) = *((PBYTE)(SrcPtr)+1), \
+ *((PBYTE)(DstPtr)+2) = *((PBYTE)(SrcPtr)+2), \
+ *((PBYTE)(DstPtr)+3) = *((PBYTE)(SrcPtr)+3)
+
+// MIN/MAX macros
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+
+
+
+// Exported prototypes
+
+UINT
+SpxUtilWstrLength(
+ IN PWSTR Wstr);
+
+LONG
+SpxRandomNumber(
+ VOID);
+
+NTSTATUS
+SpxUtilGetSocketType(
+ PUNICODE_STRING RemainingFileName,
+ PBYTE SocketType);
+
+VOID
+SpxSleep(
+ IN ULONG TimeInMs);
+
+ULONG
+SpxBuildTdiAddress(
+ IN PVOID AddressBuffer,
+ IN ULONG AddressBufferLength,
+ IN UCHAR Network[4],
+ IN UCHAR Node[6],
+ IN USHORT Socket);
+
+VOID
+SpxBuildTdiAddressFromIpxAddr(
+ IN PVOID AddressBuffer,
+ IN PBYTE pIpxAddr);
+
+TDI_ADDRESS_IPX UNALIGNED *
+SpxParseTdiAddress(
+ IN TRANSPORT_ADDRESS UNALIGNED * TransportAddress);
+
+BOOLEAN
+SpxValidateTdiAddress(
+ IN TRANSPORT_ADDRESS UNALIGNED * TransportAddress,
+ IN ULONG TransportAddressLength);
+
+VOID
+SpxCalculateNewT1(
+ IN struct _SPX_CONN_FILE * pSpxConnFile,
+ IN int NewT1);