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_
|
|||
|
|
|||
|
|