diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/tdi/isnp/spx/h | |
download | NT4.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.h | 28 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/globals.h | 67 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/isnspx.h | 363 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxaddr.h | 426 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxbind.h | 32 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxconn.h | 1666 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxdev.h | 204 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxerror.h | 246 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxmem.h | 142 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxntdef.h | 72 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxpkt.h | 466 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxquery.h | 54 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxrecv.h | 89 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxreg.h | 65 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxsend.h | 34 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxtimer.h | 101 | ||||
-rw-r--r-- | private/ntos/tdi/isnp/spx/h/spxutils.h | 178 |
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); |