|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
pap.h
Abstract:
This module contains definitions for the PAP code.
Author:
Jameel Hyder (jameelh@microsoft.com) Nikhil Kamkolkar (nikhilk@microsoft.com)
Revision History: 19 Jun 1992 Initial Version
Notes: Tab stop: 4 --*/
#ifndef _PAP_
#define _PAP_
// PAP command type bytes:
#define PAP_OPEN_CONN 1
#define PAP_OPEN_CONNREPLY 2
#define PAP_SEND_DATA 3
#define PAP_DATA 4
#define PAP_TICKLE 5
#define PAP_CLOSE_CONN 6
#define PAP_CLOSE_CONN_REPLY 7
#define PAP_SEND_STATUS 8
#define PAP_STATUS_REPLY 9
// Error codes for OpenConnectionReply:
#define PAP_NO_ERROR 0x0000
#define PAP_PRINTER_BUSY 0xFFFF
// PAP sizes:
#define PAP_MAX_DATA_PACKET_SIZE 512
#define PAP_SEND_USER_BYTES_ALL TRUE
#define PAP_MAX_STATUS_SIZE 255
#define PAP_MAX_FLOW_QUANTUM 8
#define PAP_MAX_ATP_BYTES_TO_SL 4
// PAP timer values:
#define PAP_OPENCONN_REQ_RETRYCOUNT 5
#define PAP_OPENCONN_INTERVAL 20 // In 100ms units
#define PAP_TICKLE_INTERVAL 600 // In 100ms units
#define PAP_CONNECTION_INTERVAL 1200 // In 100ms units
#define PAP_MIN_SENDDATA_REQ_INTERVAL 10 // In 100ms units
#define PAP_MAX_SENDDATA_REQ_INTERVAL 150 // In 100ms units
#define PAP_INIT_SENDDATA_REQ_INTERVAL 10 // In 100ms units
// The following aren't documented... so we'll take a wild guess...
#define PAP_GETSTATUS_REQ_RETRYCOUNT 5
#define PAP_GETSTATUS_ATP_INTERVAL 20 // In 100ms units
// Offsets within ATP userBytes and data buffer for the various fields of the
// PAP header:
#define PAP_CONNECTIONID_OFF 0
#define PAP_CMDTYPE_OFF 1
#define PAP_EOFFLAG_OFF 2
#define PAP_SEQNUM_OFF 2
#define PAP_RESP_SOCKET_OFF 0
#define PAP_FLOWQUANTUM_OFF 1
#define PAP_WAITTIME_OFF 2
#define PAP_RESULT_OFF 2
#define PAP_STATUS_OFF 4
#define PAP_MAX_WAIT_TIMEOUT 0x80 // Pretty randomly chosen
// For resolving forward references
struct _PAP_ADDROBJ; struct _PAP_CONNOBJ;
// PAP Address Object
// This is created whenever an address object is created on the Pap device.
// This represents either a client or a server side pap address. The server
// side address is represented by PAPAO_LISTENER flag.
#define PAP_CONN_HASH_SIZE 7
// PAP ADDRESS OBJECT STATES
#define PAPAO_LISTENER 0x00000001
#define PAPAO_CONNECT 0x00000002
#define PAPAO_UNBLOCKED 0x00000004
#define PAPAO_SLS_QUEUED 0x00000008
#define PAPAO_CLEANUP 0x01000000
#define PAPAO_BLOCKING 0x02000000
#define PAPAO_BLOCKING 0x02000000
#define PAPAO_CLOSING 0x80000000
#define PAPAO_SIGNATURE (*(PULONG)"PAAO")
#define VALID_PAPAO(pPapAddr) (((pPapAddr) != NULL) && \
(((struct _PAP_ADDROBJ *)(pPapAddr))->papao_Signature == PAPAO_SIGNATURE))
typedef struct _PAP_ADDROBJ { ULONG papao_Signature;
// Global list of address objects.
struct _PAP_ADDROBJ * papao_Next; struct _PAP_ADDROBJ ** papao_Prev;
ULONG papao_Flags; ULONG papao_RefCount;
// List of connections associated with this address object.
// Potentially greater than one if this address object is a listener.
struct _PAP_CONNOBJ * papao_pAssocConn;
// List of connections that are associated, but also have a listen/connect
// posted on them.
union { struct _PAP_CONNOBJ * papao_pListenConn; struct _PAP_CONNOBJ * papao_pConnectConn; };
// Lookup list of all active connections hashed by connId and remote
// address.
struct _PAP_CONNOBJ * papao_pActiveHash[PAP_CONN_HASH_SIZE];
// Next connection to use.
BYTE papao_NextConnId;
// The following are valid only if this is a listener.
SHORT papao_SrvQuantum; SHORT papao_StatusSize; PBYTE papao_pStatusBuf;
// Event support routines.
//
// 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 papao_ConnHandler; PVOID papao_ConnHandlerCtx;
// The following function pointer always points to a TDI_IND_DISCONNECT
// handler for the address. If the NULL handler is specified in a
// TdiSetEventHandler, this this points to an internal routine which
// simply returns successfully.
PTDI_IND_DISCONNECT papao_DisconnectHandler; PVOID papao_DisconnectHandlerCtx;
// The following function pointer always points to a TDI_IND_RECEIVE
// event handler for connections on this address. If the NULL handler
// is specified in a TdiSetEventHandler, then this points to an internal
// routine which does not accept the incoming data.
PTDI_IND_RECEIVE papao_RecvHandler; PVOID papao_RecvHandlerCtx;
// The following function pointer always points to a TDI_IND_SEND_POSSIBLE
// handler for the address. If the NULL handler is specified in a
// TdiSetEventHandler, this this points to an internal routine which
// simply returns successfully.
PTDI_IND_SEND_POSSIBLE papao_SendPossibleHandler; PVOID papao_SendPossibleHandlerCtx;
// ATP Address for this pap address. If this is a listener, then the ATP
// address will be what the listens effectively will be posted on, if this
// is a connect address object, then this atp address will be what the
// associated connection be active over.
PATP_ADDROBJ papao_pAtpAddr;
// Completion routine to be called when address is closed
GENERIC_COMPLETION papao_CloseComp; PVOID papao_CloseCtx;
PATALK_DEV_CTX papao_pDevCtx; ATALK_SPIN_LOCK papao_Lock; } PAP_ADDROBJ, *PPAP_ADDROBJ;
#define PAPCO_ASSOCIATED 0x00000001
#define PAPCO_LISTENING 0x00000002
#define PAPCO_CONNECTING 0x00000004
#define PAPCO_ACTIVE 0x00000008
#define PAPCO_SENDDATA_RECD 0x00000010
#define PAPCO_WRITEDATA_WAITING 0x00000020
#define PAPCO_SEND_EOF_WRITE 0x00000040
#define PAPCO_READDATA_PENDING 0x00000080
#define PAPCO_DISCONNECTING 0x00000100
#define PAPCO_LOCAL_DISCONNECT 0x00000200
#define PAPCO_REMOTE_DISCONNECT 0x00000400
#define PAPCO_SERVER_JOB 0x00000800
#define PAPCO_REMOTE_CLOSE 0x00001000
#define PAPCO_NONBLOCKING_READ 0x00002000
#define PAPCO_READDATA_WAITING 0x00004000
#define PAPCO_DELAYED_DISCONNECT 0x00008000
#define PAPCO_RECVD_DISCONNECT 0x00010000
#define PAPCO_ADDR_ACTIVE 0x00020000
#define PAPCO_REJECT_READS 0x00040000
#if DBG
#define PAPCO_CLEANUP 0x01000000
#define PAPCO_INDICATE_AFD_DISC 0x02000000
#endif
#define PAPCO_STOPPING 0x40000000
#define PAPCO_CLOSING 0x80000000
#define PAPCO_SIGNATURE (*(PULONG)"PACO")
#define VALID_PAPCO(pPapConn) (((pPapConn) != NULL) && \
(((struct _PAP_CONNOBJ *)(pPapConn))->papco_Signature == PAPCO_SIGNATURE))
// This will represent a 'job' on the Pap address. This could either be a
// workstation job or a server job. In the latter case it could either
// be in a 'listen' state or active state. In the former case it is either
// active or 'waiting'
typedef struct _PAP_CONNOBJ { ULONG papco_Signature;
// Global list of connection objects.
struct _PAP_CONNOBJ * papco_Next; struct _PAP_CONNOBJ ** papco_Prev;
ULONG papco_Flags; ULONG papco_RefCount;
// Backpointer to the associated address
struct _PAP_ADDROBJ * papco_pAssocAddr;
// The address this connection uses for itself. In the case of a connect
// this will be the same as the address object's ATP address.
PATP_ADDROBJ papco_pAtpAddr;
// Used to queue into the address object's associated list.
struct _PAP_CONNOBJ * papco_pNextAssoc;
// Used to queue into the address object's listen/connect list. When it
// is removed from the listen/connect, it goes into the active list of the
// address object. When active, pNextActive will be the overflow list.
union { struct _PAP_CONNOBJ * papco_pNextListen; struct _PAP_CONNOBJ * papco_pNextConnect; struct _PAP_CONNOBJ * papco_pNextActive; };
// Address of remote end of the connection
ATALK_ADDR papco_RemoteAddr;
// Connection id
BYTE papco_ConnId;
// WaitTime value for PapConnect call. We start with 0 and increment by 2
// till we either succeed or reach PAP_MAX_WAIT_TIMEOUT
BYTE papco_WaitTimeOut;
// Max size we can write to the remote end. This is dictated by the
// remote end. Our recv flow quantum will always be PAP_MAX_FLOW_QUANTUM.
SHORT papco_SendFlowQuantum;
LONG papco_LastContactTime; USHORT papco_TickleTid;
// Adaptive Retry time support
RT papco_RT;
// Connection context
PVOID papco_ConnCtx;
// PAP handles only one read and one write per job at a time. So we
// explicitly have the relevant information for the two cases in here.
// PAPWRITE():
// If the remote end did a papread() and we are waiting for our client
// to do a papwrite(), then the PAPCO_SENDDATA_RECD will be true and the
// following will be used for our papwrite() response. Note
// that we will assume all send data responses to be exactly-once.
PATP_RESP papco_pAtpResp;
// Next expected sequence number of send data.
USHORT papco_NextIncomingSeqNum;
// Where did the senddata request come from. NOTE this may not be the
// same as papco_RemoteAddr!!!
ATALK_ADDR papco_SendDataSrc;
// If the remote end has not done a send data, then our write will pend
// and the PAPCO_WRITEDATA_WAITING will be set. Even if send credit is
// available the write will pend until all the data is sent out. But in
// that case both the PAPCO_WRITEDATA_WAITING and the PAPCO_SENDDATA_RECD will
// be set. Note that whenever PAPCO_WRITEDATA_WAITING is set, no new writes
// will be accepted by PAP for this job.
PAMDL papco_pWriteBuf; SHORT papco_WriteLen;
GENERIC_WRITE_COMPLETION papco_WriteCompletion; PVOID papco_WriteCtx;
// PAPREAD():
// In the case where we are doing a PapRead(). Pap only allows one read
// at a time per connection. The last seq num we used for an outgoing senddata.
// While a PAPREAD() is active, the PAPCO_READDATA_PENDING will be set.
// NOTE: The user's buffer is passed on to ATP as a response buffer. For
// nonblocking reads we prime with the users buffers which are stored here.
ULONG papco_NbReadFlags; PACTREQ papco_NbReadActReq; USHORT papco_NbReadLen; // Number of bytes read
USHORT papco_ReadDataTid; USHORT papco_NextOutgoingSeqNum; GENERIC_READ_COMPLETION papco_ReadCompletion; PVOID papco_ReadCtx;
// The connection object can have either a CONNECT or a LISTEN posted
// on it, but not both.
union { struct { // Pending Listen routine.
GENERIC_COMPLETION papco_ListenCompletion; PVOID papco_ListenCtx; };
struct { // Pending Connect routine. The status buffer is remembered and
// returned via socket options. The pConnectRespBuf is remembered
// to avoid having to get the system address for it. It is freed
// when connection is taken off the connectlist.
GENERIC_COMPLETION papco_ConnectCompletion; PVOID papco_ConnectCtx; PBYTE papco_pConnectRespBuf; PBYTE papco_pConnectOpenBuf; USHORT papco_ConnectRespLen; USHORT papco_ConnectTid; }; };
// Disconnect inform routine
GENERIC_COMPLETION papco_DisconnectInform; PVOID papco_DisconnectInformCtx;
// Disconnect request completion
ATALK_ERROR papco_DisconnectStatus; GENERIC_COMPLETION papco_DisconnectCompletion; PVOID papco_DisconnectCtx;
// Completion routine to be called when socket cleanup is called
GENERIC_COMPLETION papco_CleanupComp; PVOID papco_CleanupCtx;
// Completion routine to be called when socket is closed
GENERIC_COMPLETION papco_CloseComp; PVOID papco_CloseCtx;
PATALK_DEV_CTX papco_pDevCtx; ATALK_SPIN_LOCK papco_Lock; } PAP_CONNOBJ, *PPAP_CONNOBJ;
// Used for sending a status reply to a send status command.
typedef struct _PAP_SEND_STATUS_REL { PPAP_ADDROBJ papss_pPapAddr; PATP_RESP papss_pAtpResp; PAMDL papss_pAmdl; BYTE papss_StatusBuf[PAP_STATUS_OFF + 1]; // This will be followed by the actual status.
} PAP_SEND_STATUS_REL, *PPAP_SEND_STATUS_REL;
// Used for sending a open reply
typedef struct _PAP_OPEN_REPLY_REL { PAMDL papor_pRespAmdl; PATP_RESP papor_pAtpResp; BYTE papor_pRespPkt[PAP_MAX_DATA_PACKET_SIZE]; } PAP_OPEN_REPLY_REL, *PPAP_OPEN_REPLY_REL;
// Routine prototypes
VOID AtalkInitPapInitialize( VOID);
ATALK_ERROR AtalkPapCreateAddress( IN PATALK_DEV_CTX pDevCtx OPTIONAL, OUT PPAP_ADDROBJ * ppPapAddr);
ATALK_ERROR AtalkPapCleanupAddress( IN PPAP_ADDROBJ pPapAddr);
ATALK_ERROR AtalkPapCloseAddress( IN PPAP_ADDROBJ pPapAddr, IN GENERIC_COMPLETION CompletionRoutine, IN PVOID pCloseCtx);
ATALK_ERROR AtalkPapCreateConnection( IN PVOID pConnCtx, // Context to associate with the session
IN PATALK_DEV_CTX pDevCtx OPTIONAL, OUT PPAP_CONNOBJ * ppPapConn);
ATALK_ERROR AtalkPapCleanupConnection( IN PPAP_CONNOBJ pPapConn);
ATALK_ERROR AtalkPapCloseConnection( IN PPAP_CONNOBJ pPapConn, IN GENERIC_COMPLETION CompletionRoutine, IN PVOID pCloseCtx);
ATALK_ERROR AtalkPapConnStop( IN PPAP_CONNOBJ pPapConn);
ATALK_ERROR AtalkPapAssociateAddress( IN PPAP_ADDROBJ pPapAddr, IN PPAP_CONNOBJ pPapConn);
ATALK_ERROR AtalkPapDissociateAddress( IN PPAP_CONNOBJ pPapConn);
ATALK_ERROR AtalkPapPostListen( IN PPAP_CONNOBJ pPapConn, IN PVOID pListenCtx, IN GENERIC_COMPLETION CompletionRoutine);
ATALK_ERROR AtalkPapPrimeListener( IN PPAP_ADDROBJ pPapAddr);
ATALK_ERROR AtalkPapCancelListen( IN PPAP_CONNOBJ pPapConn);
ATALK_ERROR AtalkPapPostConnect( IN PPAP_CONNOBJ pPapConn, IN PATALK_ADDR pRemoteAddr, IN PVOID pConnectCtx, IN GENERIC_COMPLETION CompletionRoutine);
ATALK_ERROR AtalkPapDisconnect( IN PPAP_CONNOBJ pPapConn, IN ATALK_DISCONNECT_TYPE DisconnectType, IN PVOID pDisconnectCtx, IN GENERIC_COMPLETION CompletionRoutine);
ATALK_ERROR AtalkPapRead( IN PPAP_CONNOBJ pPapConn, IN PAMDL pReadBuf, IN USHORT ReadBufLen, IN ULONG ReadFlags, IN PVOID pReadCtx, IN GENERIC_READ_COMPLETION CompletionRoutine);
ATALK_ERROR AtalkPapPrimeRead( IN PPAP_CONNOBJ pPapConn, IN PACTREQ pActReq);
ATALK_ERROR AtalkPapWrite( IN PPAP_CONNOBJ pPapConn, IN PAMDL pWriteBuf, IN USHORT WriteBufLen, IN ULONG SendFlags, IN PVOID pWriteCtx, IN GENERIC_WRITE_COMPLETION CompletionRoutine);
ATALK_ERROR AtalkPapSetStatus( IN PPAP_ADDROBJ pPapAddr, IN PAMDL pStatusMdl, IN PACTREQ pActReq);
ATALK_ERROR AtalkPapGetStatus( IN PPAP_ADDROBJ pPapAddr, IN PATALK_ADDR pRemoteAddr, IN PAMDL pStatusAmdl, IN USHORT AmdlSize, IN PACTREQ pActReq);
VOID AtalkPapQuery( IN PVOID pObject, IN ULONG ObjectType, IN PAMDL pAmdl, OUT PULONG BytesWritten);
VOID FASTCALL atalkPapAddrDeref( IN PPAP_ADDROBJ pPapAddr);
VOID FASTCALL atalkPapConnRefByPtrNonInterlock( IN PPAP_CONNOBJ pPapConn, OUT PATALK_ERROR pError);
VOID atalkPapConnRefNextNc( IN PPAP_CONNOBJ pPapConn, IN PPAP_CONNOBJ * ppPapConnNext, OUT PATALK_ERROR pError);
VOID atalkPapConnRefByCtx( IN PPAP_ADDROBJ pPapAddr, IN CONNECTION_CONTEXT pCtx, OUT PPAP_CONNOBJ * pPapConn, OUT PATALK_ERROR pError);
VOID FASTCALL atalkPapConnDeref( IN PPAP_CONNOBJ pPapConn);
// MACROS
#define AtalkPapAddrReferenceNonInterlock(_pPapAddr, _pError) \
{ \ if (((_pPapAddr)->papao_Flags & PAPAO_CLOSING) == 0) \ { \ ASSERT((_pPapAddr)->papao_RefCount >= 1); \ (_pPapAddr)->papao_RefCount++; \ *(_pError) = ATALK_NO_ERROR; \ } \ else \ { \ *(_pError) = ATALK_PAP_ADDR_CLOSING; \ } \ if (ATALK_SUCCESS(*(_pError))) \ { \ DBGPRINT(DBG_COMP_PAP, DBG_LEVEL_REFPAPADDR, \ ("RefAddr %lx at %s(%d) = %d\n", \ _pPapAddr, __FILE__, __LINE__, \ ((_pPapAddr)->papao_RefCount))); \ } \ }
#define AtalkPapAddrReference(pPapAddr, pError) \
{ \ KIRQL OldIrql; \ \ ACQUIRE_SPIN_LOCK(&(pPapAddr)->papao_Lock, &OldIrql); \ AtalkPapAddrReferenceNonInterlock(pPapAddr, pError); \ RELEASE_SPIN_LOCK(&(pPapAddr)->papao_Lock, OldIrql); \ }
#define AtalkPapAddrDereference(pPapAddr) \
{ \ DBGPRINT(DBG_COMP_PAP, DBG_LEVEL_REFPAPADDR, \ ("DerefAddr %lx at %s %d = %d\n", \ pPapAddr, __FILE__, __LINE__, \ ((pPapAddr)->papao_RefCount-1))); \ atalkPapAddrDeref(pPapAddr); \ }
#define AtalkPapConnReferenceByPtr(pPapConn, pError) \
{ \ KIRQL OldIrql; \ \ ACQUIRE_SPIN_LOCK(&(pPapConn)->papco_Lock, &OldIrql); \ AtalkPapConnReferenceByPtrNonInterlock(pPapConn, pError); \ RELEASE_SPIN_LOCK(&(pPapConn)->papco_Lock, OldIrql); \ }
#define AtalkPapConnReferenceByPtrDpc(pPapConn, pError) \
{ \ ACQUIRE_SPIN_LOCK_DPC(&(pPapConn)->papco_Lock); \ AtalkPapConnReferenceByPtrNonInterlock(pPapConn, pError); \ RELEASE_SPIN_LOCK_DPC(&(pPapConn)->papco_Lock); \ }
#define AtalkPapConnReferenceByPtrNonInterlock(pPapConn, pError) \
{ \ atalkPapConnRefByPtrNonInterlock(pPapConn, pError); \ if (ATALK_SUCCESS(*pError)) \ { \ DBGPRINT(DBG_COMP_PAP, DBG_LEVEL_REFPAPCONN, \ ("RefConn %lx at %s (%ld): + 1 = %ld\n", \ pPapConn, __FILE__, __LINE__, \ (pPapConn)->papco_RefCount)); \ } \ else \ { \ DBGPRINT(DBG_COMP_PAP, DBG_LEVEL_REFPAPCONN, \ ("RefConn %lx at %s (%ld): FAILED, Flags %lx\n",\ pPapConn, __FILE__, __LINE__, \ (pPapConn)->papco_Flags)); \ } \ }
#define AtalkPapConnReferenceByCtxNonInterlock(pPapAddr, Ctx, ppPapConn, pError) \
{ \ atalkPapConnRefByCtxNonInterlock(pPapAddr, Ctx, ppPapConn, pError); \ if (ATALK_SUCCESS(*pError)) \ { \ DBGPRINT(DBG_COMP_PAP, DBG_LEVEL_REFPAPCONN, \ ("RefConnByCtx %lx at %s(%ld) = %ld\n", \ *ppPapConn, __FILE__, __LINE__, \ ((*ppPapConn)->papco_RefCount))); \ } \ }
#define AtalkPapConnDereference(pPapConn) \
{ \ DBGPRINT(DBG_COMP_PAP, DBG_LEVEL_REFPAPCONN, \ ("DerefConn %lx at %s(%ld) = %ld\n", \ pPapConn, __FILE__, __LINE__, \ (pPapConn)->papco_RefCount-1)); \ atalkPapConnDeref(pPapConn); \ }
#define AtalkPapGetDdpAddress(pPapAddr) \
AtalkAtpGetDdpAddress((pPapAddr)->papao_pAtpAddr)
#define PAPCONN_DDPSOCKET(pPapConn) \
AtalkAtpGetDdpAddress((pPapConn)->papco_pAtpAddr)->ddpao_Addr.ata_Socket
#define PAPADDR_DDPSOCKET(pPapAddr) \
AtalkAtpGetDdpAddress((pPapAddr)->papao_pAtpAddr)->ddpao_Addr.ata_Socket
// List of all pap address/connection objects.
extern PPAP_ADDROBJ atalkPapAddrList; extern PPAP_CONNOBJ atalkPapConnList; extern TIMERLIST atalkPapCMTTimer; extern ATALK_SPIN_LOCK atalkPapLock;
#define PAP_HASH_ID_ADDR(_id, _pAddr) \
(((_pAddr)->ata_Node+((_pAddr)->ata_Network & 0xFF)+_id)%PAP_CONN_HASH_SIZE)
LOCAL ATALK_ERROR atalkPapRepostConnect( IN PPAP_CONNOBJ pPapConn, IN PAMDL pOpenAmdl, IN PAMDL pRespAmdl );
LOCAL VOID atalkPapSlsHandler( IN ATALK_ERROR ErrorCode, IN PPAP_ADDROBJ pPapAddr, // Listener (our context)
IN PVOID RespContext, // CancelResp/PostResp will need this
IN PATALK_ADDR pSrcAddr, // Address of requestor
IN USHORT PktLen, IN PBYTE pPkt, IN PBYTE pUserBytes);
LOCAL VOID atalkPapIncomingReadComplete( IN ATALK_ERROR ErrorCode, IN PPAP_CONNOBJ pPapConn, // Our context
IN PAMDL pReqAmdl, IN PAMDL pReadAmdl, IN USHORT ReadLen, IN PBYTE ReadUserBytes);
LOCAL VOID atalkPapPrimedReadComplete( IN ATALK_ERROR ErrorCode, IN PPAP_CONNOBJ pPapConn, // Our context
IN PAMDL pReqAmdl, IN PAMDL pReadAmdl, IN USHORT ReadLen, IN PBYTE ReadUserBytes);
LOCAL VOID atalkPapIncomingStatus( IN ATALK_ERROR ErrorCode, IN PACTREQ pActReq, // Our Ctx
IN PAMDL pReqAmdl, IN PAMDL pStatusAmdl, IN USHORT StatusLen, IN PBYTE ReadUserBytes);
LOCAL VOID atalkPapIncomingReq( IN ATALK_ERROR ErrorCode, IN PPAP_CONNOBJ pPapConn, // Connection (our context)
IN PVOID RespContext, // CancelResp/PostResp will need this
IN PATALK_ADDR pSrcAddr, // Address of requestor
IN USHORT PktLen, IN PBYTE pPkt, IN PBYTE pUserBytes);
LOCAL VOID atalkPapIncomingOpenReply( IN ATALK_ERROR ErrorCode, IN PPAP_CONNOBJ pPapConn, // Our context
IN PAMDL pReqAmdl, IN PAMDL pReadAmdl, IN USHORT ReadLen, IN PBYTE ReadUserBytes);
LOCAL VOID FASTCALL atalkPapIncomingRel( IN ATALK_ERROR ErrorCode, IN PPAP_OPEN_REPLY_REL pOpenReply);
LOCAL VOID FASTCALL atalkPapStatusRel( IN ATALK_ERROR ErrorCode, IN PPAP_SEND_STATUS_REL pSendSts);
LOCAL ATALK_ERROR FASTCALL atalkPapPostSendDataResp( IN PPAP_CONNOBJ pPapConn);
LOCAL BOOLEAN atalkPapConnAccept( IN PPAP_ADDROBJ pPapAddr, // Listener
IN PATALK_ADDR pSrcAddr, // Address of requestor
IN PBYTE pPkt, IN BYTE ConnId, IN PATP_RESP pAtpResp);
LOCAL LONG FASTCALL atalkPapConnMaintenanceTimer( IN PTIMERLIST pTimer, IN BOOLEAN TimerShuttingDown);
LOCAL VOID FASTCALL atalkPapSendDataRel( IN ATALK_ERROR ErrorCode, IN PPAP_CONNOBJ pPapConn);
LOCAL BYTE atalkPapGetNextConnId( IN PPAP_ADDROBJ pPapAddr, OUT PATALK_ERROR pError);
LOCAL VOID atalkPapQueueAddrGlobalList( IN PPAP_ADDROBJ pPapAddr);
LOCAL VOID atalkPapConnDeQueueAssocList( IN PPAP_ADDROBJ pPapAddr, IN PPAP_CONNOBJ pPapConn);
LOCAL VOID atalkPapConnDeQueueConnectList( IN PPAP_ADDROBJ pPapAddr, IN PPAP_CONNOBJ pPapConn);
LOCAL BOOLEAN atalkPapConnDeQueueListenList( IN PPAP_ADDROBJ pPapAddr, IN PPAP_CONNOBJ pPapConn);
LOCAL VOID atalkPapConnDeQueueActiveList( IN PPAP_ADDROBJ pPapAddr, IN PPAP_CONNOBJ pPapConn);
LOCAL VOID atalkPapConnRefByCtxNonInterlock( IN PPAP_ADDROBJ pPapAddr, IN CONNECTION_CONTEXT Ctx, OUT PPAP_CONNOBJ * pPapConn, OUT PATALK_ERROR pError);
#endif // _PAP_
|