/********************************************************************/ /** Microsoft LAN Manager **/ /** Copyright(c) Microsoft Corp., 1990-1993 **/ /********************************************************************/ /* :ts=4 */ //** TCPDELIV.H - TCP data delivery definitions. // // This file contains the definitions for structures used by the data // delivery code. // extern void FreeRcvReq(struct TCPRcvReq *FreedReq); extern uint IndicateData(struct TCB *RcvTCB, uint RcvFlags, IPRcvBuf *InBuffer, uint Size); extern uint BufferData(struct TCB *RcvTCB, uint RcvFlags, IPRcvBuf *InBuffer, uint Size); extern uint PendData(struct TCB *RcvTCB, uint RcvFlags, IPRcvBuf *InBuffer, uint Size); extern void IndicatePendingData(struct TCB *RcvTCB, struct TCPRcvReq *RcvReq, CTELockHandle TCBHandle); extern void HandleUrgent(struct TCB *RcvTCB, struct TCPRcvInfo *RcvInfo, IPRcvBuf *RcvBuf, uint *Size); extern TDI_STATUS TdiReceive(PTDI_REQUEST Request, ushort *Flags, uint *RcvLength, PNDIS_BUFFER Buffer); extern IPRcvBuf *FreePartialRB(IPRcvBuf *RB, uint Size); extern void FreeRBChain(IPRcvBuf * RBChain); extern void PushData(struct TCB *PushTCB, BOOLEAN PushAll); extern HANDLE TcprBufferPool; #if !MILLEN #define TCP_FIXED_SIZE_IPR_SIZE 1460 #define TCP_UNUSED_PEND_BUF_LIMIT 2920 extern HANDLE TcprBufferPool; #ifdef DBG extern ULONG SlistAllocates, NPPAllocates; #endif // This data structure embeds the generic IPRcvBuf structure as well as holds // a pointer to the TCB for which this buffer has been allocated for. // typedef struct _TCPRcvBuf{ IPRcvBuf tcpr_ipr; PVOID tcpr_tcb; } TCPRcvBuf, *PTCPRcvBuf; // This macro calculates the unused bytes in a TcpRcvBuf structure. // #define IPR_BUF_UNUSED_BYTES(_Tcpr) \ (TCP_FIXED_SIZE_IPR_SIZE - (_Tcpr)->tcpr_ipr.ipr_size - \ ((PCHAR)((_Tcpr)->tcpr_ipr.ipr_buffer) - (PCHAR)(_Tcpr) - sizeof(TCPRcvBuf))) //* InitTcpIpr - Initializes the IPRcvBuffer. // // Input: Tcpr - Pointer to the TCPRcvBuf. // BufferSize - Number of bytes that are used. // PendTCB - Pointer to the TCB for which this allocation is being made. // // Returns: None. // __inline void InitTcpIpr(TCPRcvBuf *Tcpr, ULONG BufferSize, TCB* PendTCB) { Tcpr->tcpr_ipr.ipr_owner = IPR_OWNER_TCP; Tcpr->tcpr_ipr.ipr_next = NULL; Tcpr->tcpr_ipr.ipr_buffer = (PUCHAR) Tcpr + sizeof(TCPRcvBuf); Tcpr->tcpr_ipr.ipr_size = BufferSize; Tcpr->tcpr_tcb = PendTCB; } //* AllocTcpIpr - Allocates the IPRcvBuffer from NPP. // // A utility routine to allocate a TCP owned IPRcvBuffer. This routine // allocates the IPR from NPP and initializes appropriate fields. // // Input: BufferSize - Size of data to buffer. // Tag - Tag to be used if allocation is done from NPP. // // Returns: Pointer to allocated IPR. // __inline IPRcvBuf * AllocTcpIpr(ULONG BufferSize, ULONG Tag) { TCPRcvBuf *Tcpr; ULONG AllocateSize; // Real size that we need. AllocateSize = BufferSize + sizeof(TCPRcvBuf); Tcpr = CTEAllocMemLow(AllocateSize, Tag); if (Tcpr != NULL) { #ifdef DBG InterlockedIncrement((PLONG)&NPPAllocates); #endif InitTcpIpr(Tcpr, BufferSize, NULL); } return &Tcpr->tcpr_ipr; } //* AllocTcpIprFromSlist - Allocates the IPRcvBuffer from NPP. // // A utility routine to allocate a TCP owned IPRcvBuffer. This routine // allocates the IPR from an SLIST and initializes appropriate fields. // // Input: Tcb - Pointer to the TCB for which this allocation is being made. // BufferSize - Size of data buffer required. // Tag - Tag to be used if allocation is done from NPP. // // Returns: Pointer to allocated IPR. // __inline IPRcvBuf * AllocTcpIprFromSlist(TCB* PendTCB, ULONG BufferSize, ULONG Tag) { TCPRcvBuf* Tcpr; LOGICAL FromList; if ((BufferSize <= TCP_FIXED_SIZE_IPR_SIZE) && (PendTCB->tcb_unusedpendbuf + TCP_FIXED_SIZE_IPR_SIZE - BufferSize <= TCP_UNUSED_PEND_BUF_LIMIT)) { Tcpr = PplAllocate(TcprBufferPool, &FromList); if (NULL != Tcpr) { #ifdef DBG InterlockedIncrement((PLONG)&SlistAllocates); #endif // Set up IPR fields appropriately. InitTcpIpr(Tcpr, BufferSize, PendTCB); ASSERT(PendTCB->tcb_unusedpendbuf >= 0); PendTCB->tcb_unusedpendbuf += (short)IPR_BUF_UNUSED_BYTES(Tcpr); ASSERT(PendTCB->tcb_unusedpendbuf <= TCP_UNUSED_PEND_BUF_LIMIT); return &Tcpr->tcpr_ipr; } } return AllocTcpIpr(BufferSize, Tag); } //* FreeTcpIpr - Frees the IPRcvBuffer.. // // A utility routine to free a TCP owned IPRcvBuffer. // // Input: Ipr - Pointer the IPR. // // Returns: None. // __inline VOID FreeTcpIpr(IPRcvBuf *Ipr) { TCB *PendTCB; PTCPRcvBuf Tcpr = (PTCPRcvBuf)Ipr; if (Tcpr->tcpr_tcb) { PendTCB = (TCB*)(Tcpr->tcpr_tcb); ASSERT(PendTCB->tcb_unusedpendbuf <= TCP_UNUSED_PEND_BUF_LIMIT); PendTCB->tcb_unusedpendbuf -= (short)IPR_BUF_UNUSED_BYTES(Tcpr); ASSERT(PendTCB->tcb_unusedpendbuf >= 0); PplFree(TcprBufferPool, Tcpr); #ifdef DBG InterlockedDecrement((PLONG)&SlistAllocates); #endif } else { CTEFreeMem(Tcpr); #ifdef DBG InterlockedDecrement((PLONG)&NPPAllocates); #endif } } #else // MILLEN IPRcvBuf *AllocTcpIpr(ULONG BufferSize, ULONG Tag); VOID FreeTcpIpr(IPRcvBuf *Ipr); #endif // MILLEN