783 lines
22 KiB
C
783 lines
22 KiB
C
/*++
|
||
|
||
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_
|
||
|
||
|