Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

679 lines
18 KiB

  1. /*+++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ddp.h
  5. Abstract:
  6. This module contains the DDP address object and ddp related definitions
  7. Author:
  8. Jameel Hyder (jameelh@microsoft.com)
  9. Nikhil Kamkolkar (nikhilk@microsoft.com)
  10. Revision History:
  11. 19 Jun 1992 Initial Version
  12. Notes: Tab stop: 4
  13. --*/
  14. #ifndef _DDP_
  15. #define _DDP_
  16. // Network number information.
  17. #define FIRST_VALID_NETWORK 0x0001
  18. #define LAST_VALID_NETWORK 0xFFFE
  19. #define FIRST_STARTUP_NETWORK 0xFF00
  20. #define LAST_STARTUP_NETWORK 0xFFFE
  21. #define NULL_NETWORK 0x0000
  22. #define UNKNOWN_NETWORK NULL_NETWORK
  23. #define CABLEWIDE_BROADCAST_NETWORK NULL_NETWORK
  24. // Appletalk Sockets Definitions
  25. #define UNKNOWN_SOCKET 0
  26. #define DYNAMIC_SOCKET UNKNOWN_SOCKET
  27. #define LAST_VALID_SOCKET 254
  28. #define FIRST_DYNAMIC_SOCKET 128
  29. #define LAST_DYNAMIC_SOCKET LAST_VALID_SOCKET
  30. #define FIRST_STATIC_SOCKET 1
  31. #define FIRST_VALID_SOCKET FIRST_STATIC_SOCKET
  32. #define LAST_STATIC_SOCKET 127
  33. // "Well known" sockets:
  34. #define RTMP_SOCKET 1 // RTMP
  35. #define NAMESINFORMATION_SOCKET 2 // NBP
  36. #define ECHOER_SOCKET 4 // EP
  37. #define ZONESINFORMATION_SOCKET 6 // ZIP
  38. #define LAST_APPLE_RESD_SOCKET 0x3F // Apple reserves 1 thru 0x3F
  39. // DDP Datagram Definitions
  40. #define MAX_DGRAM_SIZE 586
  41. #define MAX_LDDP_PKT_SIZE 600 // Really 599, but even is nicer
  42. #define MAX_SDDP_PKT_SIZE 592 // Again, really 591
  43. // Define temporary buffer sizes, these must be big enough to hold both all
  44. // of the packet data plus any link/hardware headers...
  45. #define MAX_PKT_SIZE (MAX_HDR_LEN + MAX_LDDP_PKT_SIZE)
  46. #define DDP_LEN_MASK1 0x03 // High order 3 bits of length
  47. #define DDP_LEN_MASK2 0xFF // Next byte of length
  48. // DDP packet offsets (skipping Link/Hardware headers):
  49. #define SDDP_HDR_LEN 5
  50. #define SDDP_LEN_OFFSET 0
  51. #define SDDP_DEST_SOCKET_OFFSET 2
  52. #define SDDP_SRC_SOCKET_OFFSET 3
  53. #define SDDP_PROTO_TYPE_OFFSET 4
  54. #define SDDP_DGRAM_OFFSET 5
  55. #define LDDP_HDR_LEN 13
  56. #define LDDP_LEN_OFFSET 0
  57. #define LDDP_CHECKSUM_OFFSET 2
  58. #define LDDP_DEST_NETWORK_OFFSET 4
  59. #define LDDP_SRC_NETWORK_OFFSET 6
  60. #define LDDP_DEST_NODE_OFFSET 8
  61. #define LDDP_SRC_NODE_OFFSET 9
  62. #define LDDP_DEST_SOCKET_OFFSET 10
  63. #define LDDP_SRC_SOCKET_OFFSET 11
  64. #define LDDP_PROTO_TYPE_OFFSET 12
  65. #define LDDP_DGRAM_OFFSET 13
  66. #define LEADING_UNCHECKSUMED_BYTES 4
  67. #define LDDP_HOPCOUNT_MASK 0x3C
  68. #define DECIMAL_BASE 10
  69. // DDP protocol types:
  70. #define DDPPROTO_ANY 0 // Used to allow any protocol packet
  71. #define DDPPROTO_DDP 0
  72. #define DDPPROTO_RTMPRESPONSEORDATA 1
  73. #define DDPPROTO_NBP 2
  74. #define DDPPROTO_ATP 3
  75. #define DDPPROTO_EP 4
  76. #define DDPPROTO_RTMPREQUEST 5
  77. #define DDPPROTO_ZIP 6
  78. #define DDPPROTO_ADSP 7
  79. #define DDPPROTO_MAX 255
  80. typedef struct _DDPEVENT_INFO
  81. {
  82. // Event handler routines: DDP Only has RecvDatagram/Error handlers
  83. // The following function pointer always points to a TDI_IND_RECEIVE_DATAGRAM
  84. // event handler for the address.
  85. PTDI_IND_RECEIVE_DATAGRAM ev_RcvDgramHandler;
  86. PVOID ev_RcvDgramCtx;
  87. // The following function pointer always points to a TDI_IND_ERROR
  88. // handler for the address.
  89. PTDI_IND_ERROR ev_ErrHandler;
  90. PVOID ev_ErrCtx;
  91. PVOID ev_ErrOwner;
  92. // Winsock assumes a buffering transport. So we buffer the last datagram
  93. // indicated that was not accepted.
  94. BYTE ev_IndDgram[MAX_DGRAM_SIZE];
  95. int ev_IndDgramLen;
  96. int ev_IndProto;
  97. // Source address of buffered datagram
  98. ATALK_ADDR ev_IndSrc;
  99. } DDPEVENT_INFO, *PDDPEVENT_INFO;
  100. // Handler type for the DDP address object
  101. typedef VOID (*DDPAO_HANDLER)(
  102. IN PPORT_DESCRIPTOR pPortDesc,
  103. IN struct _DDP_ADDROBJ *pAddr,
  104. IN PBYTE pPkt,
  105. IN USHORT pPktLen,
  106. IN PATALK_ADDR pSrcAddr,
  107. IN PATALK_ADDR pActDest,
  108. IN ATALK_ERROR ErrorCode,
  109. IN BYTE pDdpType,
  110. IN PVOID pHandlerCtx,
  111. IN BOOLEAN OptimizedPath,
  112. IN PVOID OptimizeCtx);
  113. // DDP Address Object
  114. // This is the basic address object in the stack. All other address objects
  115. // eventually resolve to this one. It also holds the AppletalkSocket opened
  116. // as its actual address. One address object corresponds to one address.
  117. // DDP ADDRESS OBJECT STATES
  118. #define DDPAO_DGRAM_EVENT 0x00000001
  119. #define DDPAO_DGRAM_ACTIVE 0x00000002
  120. #define DDPAO_DGRAM_PENDING 0x00000004
  121. #define DDPAO_SOCK_INTERNAL 0x00000008
  122. #define DDPAO_SOCK_PNPZOMBIE 0x00000010
  123. #define DDPAO_CLOSING 0x80000000
  124. #define DDPAO_SIGNATURE (*(PULONG)"DDPA")
  125. #define VALID_DDP_ADDROBJ(pDdpAddr) (((pDdpAddr) != NULL) && \
  126. (((struct _DDP_ADDROBJ *)(pDdpAddr))->ddpao_Signature == DDPAO_SIGNATURE))
  127. typedef struct _DDP_ADDROBJ
  128. {
  129. ULONG ddpao_Signature;
  130. // This will be a hash overflow list. Hash on the internet address.
  131. // List of address objects on the node linkage
  132. struct _DDP_ADDROBJ * ddpao_Next;
  133. ULONG ddpao_RefCount;
  134. // State of the address object
  135. ULONG ddpao_Flags;
  136. // Backpointer to the node on which this socket exists
  137. struct _ATALK_NODE * ddpao_Node;
  138. // The Appletalk address number for this object
  139. ATALK_ADDR ddpao_Addr;
  140. // List of NBP names registered on this socket
  141. struct _REGD_NAME * ddpao_RegNames;
  142. // List of NBP names being looked up, registered or confirmed on
  143. // this socket.
  144. struct _PEND_NAME * ddpao_PendNames;
  145. // Linked list of pending ddp reads
  146. LIST_ENTRY ddpao_ReadLinkage;
  147. // The protocol type to use for datagrams sent on this socket and
  148. // which can be received on this socket. 0 => no restrictions.
  149. BYTE ddpao_Protocol;
  150. ATALK_SPIN_LOCK ddpao_Lock;
  151. PATALK_DEV_CTX ddpao_DevCtx;
  152. // The handler below is an listener for the upper layers. Note that
  153. // this will take precedence over a incoming datagram event handler
  154. // which would be set in ddpao_EventInfo.
  155. DDPAO_HANDLER ddpao_Handler;
  156. PVOID ddpao_HandlerCtx;
  157. // This structure is allocated when setting an event handler
  158. // on this socket. All the event handler addresses are part of this
  159. // structure.
  160. PDDPEVENT_INFO ddpao_EventInfo;
  161. // Completion routine to be called when socket is closed
  162. GENERIC_COMPLETION ddpao_CloseComp;
  163. PVOID ddpao_CloseCtx;
  164. } DDP_ADDROBJ, *PDDP_ADDROBJ;
  165. // Receive datagram completion: This will return the mdl we pass in along
  166. // with the received length written into the mdl. Also, the protocol type
  167. // and the RemoteAddress are passed back. The receive context will be the
  168. // irp for the request. As will be the send context.
  169. typedef VOID (*RECEIVE_COMPLETION)(
  170. IN ATALK_ERROR ErrorCode,
  171. IN PAMDL OpaqueBuffer,
  172. IN USHORT LengthReceived,
  173. IN PATALK_ADDR RemoteAddress,
  174. IN PVOID ReceiveContext);
  175. typedef VOID (FASTCALL *WRITE_COMPLETION)(
  176. IN NDIS_STATUS Status,
  177. IN PVOID Ctx);
  178. typedef VOID (FASTCALL *TRANSMIT_COMPLETION)(
  179. IN NDIS_STATUS Status,
  180. IN struct _SEND_COMPL_INFO * pInfo);
  181. // If the above routine was set in the AtalkDdpSend(), then
  182. // then context values would be:
  183. // Ctx1 = pddp address object
  184. // Ctx2 = pbuffer descriptor
  185. // Ctx3 = Only for DdpWrite calls, this will be a pointer to the
  186. // write structure enqueued in the ddp address object.
  187. //
  188. // If the above routine was set in the AtalkDdpTransmit(), then
  189. // the context values would be (as specified by the client of
  190. // course):
  191. // Ctx1 = pport descriptor
  192. // Ctx2 = pbuffer descriptor
  193. // Ctx3 = not used.
  194. //
  195. // These are only suggested ideas, but probably is what the internal
  196. // stack routines will use.
  197. // This is used to store a pending read on a particular socket.
  198. typedef struct _DDP_READ
  199. {
  200. // Linkage chain for reads on a socket.
  201. LIST_ENTRY dr_Linkage;
  202. PAMDL dr_OpBuf;
  203. USHORT dr_OpBufLen;
  204. RECEIVE_COMPLETION dr_RcvCmp;
  205. PVOID dr_RcvCtx;
  206. } DDP_READ, *PDDP_READ;
  207. // This is used to store a pending write on a particular socket
  208. // DDP will create a buffer descriptor for the header
  209. // and will chain it in front of the buffer descriptor passed in.
  210. // A pointer to this structure will then be passed as a completion
  211. // context to DdpSend.
  212. typedef struct _DDP_WRITE
  213. {
  214. // Linkage chain for writes on a socket.
  215. LIST_ENTRY dw_Linkage;
  216. // The buffer descriptor chain, including the ddp buffer
  217. // descriptor containing the ddp/optional/link headers.
  218. PBUFFER_DESC dw_BufferDesc;
  219. // Write completion
  220. // This will be called with the context (which will be a pointer
  221. // to the write irp) after the write completes.
  222. WRITE_COMPLETION dw_WriteRoutine;
  223. PVOID dw_WriteCtx;
  224. } DDP_WRITE, *PDDP_WRITE;
  225. //
  226. // CANCEL IRP Functionality for NT:
  227. //
  228. // We have decided that if we receive a cancel irp for a particular request,
  229. // we will shutdown the file object associated with that request, whether it
  230. // be a connection object or an address object. This implies that the socket/
  231. // connection/listener will be closed, thus cancelling *all* pending requests.
  232. //
  233. ATALK_ERROR
  234. AtalkDdpOpenAddress(
  235. IN PPORT_DESCRIPTOR pPortDesc,
  236. IN BYTE Socket,
  237. IN OUT PATALK_NODEADDR pDesiredNode OPTIONAL,
  238. IN DDPAO_HANDLER pSktHandler OPTIONAL,
  239. IN PVOID pSktCtx OPTIONAL,
  240. IN BYTE ProtoType OPTIONAL,
  241. IN PATALK_DEV_CTX pDevCtx,
  242. OUT PDDP_ADDROBJ * pAddr);
  243. ATALK_ERROR
  244. AtalkDdpCloseAddress(
  245. IN PDDP_ADDROBJ pAddr,
  246. IN GENERIC_COMPLETION pCloseCmp OPTIONAL,
  247. IN PVOID pCloseCtx OPTIONAL);
  248. ATALK_ERROR
  249. AtalkDdpPnPSuspendAddress(
  250. IN PDDP_ADDROBJ pDdpAddr);
  251. ATALK_ERROR
  252. AtalkDdpCleanupAddress(
  253. IN PDDP_ADDROBJ pAddr);
  254. ATALK_ERROR
  255. AtalkDdpInitCloseAddress(
  256. IN PPORT_DESCRIPTOR pPortDesc,
  257. IN PATALK_ADDR pAtalkAddr);
  258. ATALK_ERROR
  259. AtalkInitDdpOpenStaticSockets(
  260. IN PPORT_DESCRIPTOR pPortDesc,
  261. IN OUT PATALK_NODE pNode);
  262. ATALK_ERROR
  263. AtalkDdpReceive(
  264. IN PDDP_ADDROBJ pAddr,
  265. IN PAMDL pAmdl,
  266. IN USHORT AmdlLen,
  267. IN ULONG RecvFlags,
  268. IN RECEIVE_COMPLETION pRcvCmp,
  269. IN PVOID pRcvCtx);
  270. ATALK_ERROR
  271. AtalkDdpSend(
  272. IN PDDP_ADDROBJ pDdpAddr,
  273. IN PATALK_ADDR DestAddr,
  274. IN BYTE ProtoType,
  275. IN BOOLEAN DefinitelyRemoteAddr,
  276. IN PBUFFER_DESC pBufDesc,
  277. IN PBYTE pOptHdr OPTIONAL,
  278. IN USHORT OptHdrLen OPTIONAL,
  279. IN PBYTE pZoneMcastAddr OPTIONAL,
  280. IN struct _SEND_COMPL_INFO * pInfo OPTIONAL);
  281. ATALK_ERROR
  282. AtalkDdpTransmit(
  283. IN PPORT_DESCRIPTOR pPortDesc,
  284. IN PATALK_ADDR SrcAddr,
  285. IN PATALK_ADDR DestAddr,
  286. IN BYTE ProtoType,
  287. IN PBUFFER_DESC pBufDesc,
  288. IN PBYTE pOptHdr OPTIONAL,
  289. IN USHORT OptHdrLen OPTIONAL,
  290. IN USHORT HopCnt,
  291. IN PBYTE pMcastAddr OPTIONAL,
  292. IN PATALK_NODEADDR pXmitDestNode OPTIONAL,
  293. IN struct _SEND_COMPL_INFO * pInfo OPTIONAL);
  294. VOID
  295. AtalkDdpSendComplete(
  296. IN NDIS_STATUS Status,
  297. IN PBUFFER_DESC pBufDesc,
  298. IN struct _SEND_COMPL_INFO * pInfo OPTIONAL);
  299. VOID
  300. AtalkDdpPacketIn(
  301. IN PPORT_DESCRIPTOR pPortDesc,
  302. IN PBYTE pLinkHdr,
  303. IN PBYTE pPkt,
  304. IN USHORT PktLen,
  305. IN BOOLEAN fWanPkt);
  306. VOID
  307. AtalkDdpQuery(
  308. IN PDDP_ADDROBJ pDdpAddr,
  309. IN PAMDL pAmdl,
  310. OUT PULONG BytesWritten);
  311. VOID
  312. AtalkDdpRefByAddr(
  313. IN PPORT_DESCRIPTOR pPortDesc,
  314. IN PATALK_ADDR pAtalkAddr,
  315. OUT PDDP_ADDROBJ * ppDdpAddr,
  316. OUT PATALK_ERROR pErr);
  317. VOID
  318. AtalkDdpRefByAddrNode(
  319. IN PPORT_DESCRIPTOR pPortDesc,
  320. IN PATALK_ADDR pAtalkAddr,
  321. IN PATALK_NODE pAtalkNode,
  322. OUT PDDP_ADDROBJ * ppDdpAddr,
  323. OUT PATALK_ERROR pErr);
  324. VOID
  325. AtalkDdpRefNextNc(
  326. IN PDDP_ADDROBJ pDdpAddr,
  327. IN PDDP_ADDROBJ * ppDdpAddr,
  328. OUT PATALK_ERROR pErr);
  329. VOID FASTCALL
  330. AtalkDdpDeref(
  331. IN OUT PDDP_ADDROBJ pDdpAddr,
  332. IN BOOLEAN AtDpc);
  333. VOID
  334. AtalkDdpOutBufToNodesOnPort(
  335. IN PPORT_DESCRIPTOR pPortDesc,
  336. IN PATALK_ADDR pSrc,
  337. IN PATALK_ADDR pDest,
  338. IN BYTE ProtoType,
  339. IN PBUFFER_DESC pBufDesc,
  340. IN PBYTE pOptHdr,
  341. IN USHORT OptHdrLen,
  342. OUT PBOOLEAN Delivered);
  343. VOID
  344. AtalkDdpInPktToNodesOnPort(
  345. IN PPORT_DESCRIPTOR pPortDesc,
  346. IN PATALK_ADDR pDest,
  347. IN PATALK_ADDR pSrc,
  348. IN BYTE ProtoType,
  349. IN PBYTE pPkt,
  350. IN USHORT PktLen,
  351. OUT PBOOLEAN Routed);
  352. VOID
  353. AtalkDdpInvokeHandlerBufDesc(
  354. IN PPORT_DESCRIPTOR pPortDesc,
  355. IN PDDP_ADDROBJ pDdpAddr,
  356. IN PATALK_ADDR pSrcAddr,
  357. IN PATALK_ADDR pActDest,
  358. IN BYTE ProtoType,
  359. IN PBUFFER_DESC pBufDesc,
  360. IN PBYTE pOptHdr,
  361. IN USHORT OptHdrLen);
  362. VOID
  363. AtalkDdpInvokeHandler(
  364. IN PPORT_DESCRIPTOR pPortDesc,
  365. IN PDDP_ADDROBJ pDdpAddr,
  366. IN PATALK_ADDR pSrcAddr,
  367. IN PATALK_ADDR pActDest,
  368. IN BYTE ProtoType,
  369. IN PBYTE pPkt,
  370. IN USHORT PktLen);
  371. USHORT
  372. AtalkDdpCheckSumBuffer(
  373. IN PBYTE Buffer,
  374. IN USHORT BufLen,
  375. IN USHORT CurrentCheckSum);
  376. USHORT
  377. AtalkDdpCheckSumBufferDesc(
  378. IN PBUFFER_DESC pBuffDesc,
  379. IN USHORT Offset);
  380. USHORT
  381. AtalkDdpCheckSumPacket(
  382. IN PBYTE pHdr,
  383. IN USHORT HdrLen,
  384. IN PBYTE pPkt,
  385. IN USHORT PktLen);
  386. VOID
  387. AtalkDdpNewHandlerForSocket(
  388. IN PDDP_ADDROBJ pDdpAddr,
  389. IN DDPAO_HANDLER pSktHandler,
  390. IN PVOID pSktHandlerCtx);
  391. // MACROS
  392. #define DDP_MSB_LEN(L) (((L) >> 8) & 0x03)
  393. #define DDP_GET_LEN(P) ((((*P) & 0x03) << 8) + *(P+1))
  394. #define DDP_GET_HOP_COUNT(P) (((*P) >> 2) & 0x0F)
  395. #define DDP_HOP_COUNT(H) (((H) & 0x0F) << 2)
  396. #if DBG
  397. #define AtalkDdpReferenceByPtr(pDdpAddr, pErr) \
  398. { \
  399. KIRQL OldIrql; \
  400. \
  401. ACQUIRE_SPIN_LOCK(&(pDdpAddr)->ddpao_Lock, &OldIrql); \
  402. AtalkDdpRefByPtrNonInterlock(pDdpAddr, pErr); \
  403. RELEASE_SPIN_LOCK(&(pDdpAddr)->ddpao_Lock, OldIrql); \
  404. DBGPRINT(DBG_COMP_DDP, DBG_LEVEL_REFDDP, \
  405. ("AtalkDdpReferenceByPtr: %s %d PostCount %d\n",\
  406. __FILE__, __LINE__,pDdpAddr->ddpao_RefCount)); \
  407. }
  408. #define AtalkDdpReferenceByPtrDpc(pDdpAddr, pErr) \
  409. { \
  410. ACQUIRE_SPIN_LOCK_DPC(&(pDdpAddr)->ddpao_Lock); \
  411. AtalkDdpRefByPtrNonInterlock(pDdpAddr, pErr); \
  412. RELEASE_SPIN_LOCK_DPC(&(pDdpAddr)->ddpao_Lock); \
  413. DBGPRINT(DBG_COMP_DDP, DBG_LEVEL_REFDDP, \
  414. ("AtalkDdpReferenceByPtr: %s %d PostCount %d\n",\
  415. __FILE__, __LINE__,pDdpAddr->ddpao_RefCount)); \
  416. }
  417. #define AtalkDdpRefByPtrNonInterlock(pDdpAddr, pErr) \
  418. { \
  419. ASSERT (VALID_DDP_ADDROBJ(pDdpAddr)); \
  420. \
  421. *pErr = ATALK_DDP_CLOSING; \
  422. \
  423. if ((pDdpAddr->ddpao_Flags & DDPAO_CLOSING) == 0) \
  424. { \
  425. pDdpAddr->ddpao_RefCount++; \
  426. *pErr = ATALK_NO_ERROR; \
  427. } \
  428. DBGPRINT(DBG_COMP_DDP, DBG_LEVEL_REFDDP, \
  429. ("AtalkDdpReferenceByPtrNonInterlock: %s %d PostCount %d\n",\
  430. __FILE__, __LINE__, \
  431. pDdpAddr->ddpao_RefCount)); \
  432. }
  433. #define AtalkDdpReferenceNextNc(pDdpAddr, ppDdpAddr, pErr) \
  434. { \
  435. AtalkDdpRefNextNc(pDdpAddr, ppDdpAddr, pErr); \
  436. if (ATALK_SUCCESS(*pErr)) \
  437. { \
  438. DBGPRINT(DBG_COMP_DDP, DBG_LEVEL_REFDDP, \
  439. ("DdpRefNextNc : %s %d PostCount %d\n", \
  440. __FILE__, __LINE__, \
  441. (*ppDdpAddr)->ddpao_RefCount)); \
  442. } \
  443. }
  444. #define AtalkDdpReferenceByAddr(pPortDesc, pAddr, ppDdpAddr, pErr) \
  445. { \
  446. AtalkDdpRefByAddr(pPortDesc, pAddr, ppDdpAddr, pErr); \
  447. if (ATALK_SUCCESS(*pErr)) \
  448. { \
  449. DBGPRINT(DBG_COMP_DDP, DBG_LEVEL_REFDDP, \
  450. ("AtalkDdpReferenceByAddr: %s %d PostCount %d\n",\
  451. __FILE__, __LINE__, \
  452. (*ppDdpAddr)->ddpao_RefCount)); \
  453. } \
  454. }
  455. #define AtalkDdpDereference(pDdpAddr) \
  456. { \
  457. DBGPRINT(DBG_COMP_DDP, DBG_LEVEL_REFDDP, \
  458. ("AtalkDdpDereference: %s %d PreCount %d\n", \
  459. __FILE__, __LINE__,pDdpAddr->ddpao_RefCount)); \
  460. AtalkDdpDeref(pDdpAddr, FALSE); \
  461. }
  462. #define AtalkDdpDereferenceDpc(pDdpAddr) \
  463. { \
  464. DBGPRINT(DBG_COMP_DDP, DBG_LEVEL_REFDDP, \
  465. ("AtalkDdpDereferenceDpc: %s %d PreCount %d\n", \
  466. __FILE__, __LINE__,pDdpAddr->ddpao_RefCount)); \
  467. AtalkDdpDeref(pDdpAddr, TRUE); \
  468. }
  469. #else
  470. #define AtalkDdpReferenceByPtr(pDdpAddr, pErr) \
  471. { \
  472. KIRQL OldIrql; \
  473. \
  474. ACQUIRE_SPIN_LOCK(&(pDdpAddr)->ddpao_Lock, &OldIrql); \
  475. AtalkDdpRefByPtrNonInterlock(pDdpAddr, pErr); \
  476. RELEASE_SPIN_LOCK(&(pDdpAddr)->ddpao_Lock, OldIrql); \
  477. }
  478. #define AtalkDdpReferenceByPtrDpc(pDdpAddr, pErr) \
  479. { \
  480. ACQUIRE_SPIN_LOCK_DPC(&(pDdpAddr)->ddpao_Lock); \
  481. AtalkDdpRefByPtrNonInterlock(pDdpAddr, pErr); \
  482. RELEASE_SPIN_LOCK_DPC(&(pDdpAddr)->ddpao_Lock); \
  483. }
  484. #define AtalkDdpRefByPtrNonInterlock(pDdpAddr, pErr) \
  485. { \
  486. *pErr = ATALK_DDP_CLOSING; \
  487. \
  488. if ((pDdpAddr->ddpao_Flags & DDPAO_CLOSING) == 0) \
  489. { \
  490. pDdpAddr->ddpao_RefCount++; \
  491. *pErr = ATALK_NO_ERROR; \
  492. } \
  493. }
  494. #define AtalkDdpReferenceByAddr(pPortDesc, pAddr, ppDdpAddr, pErr) \
  495. AtalkDdpRefByAddr(pPortDesc, pAddr, ppDdpAddr, pErr)
  496. #define AtalkDdpReferenceNextNc(pDdpAddr, ppDdpAddr, pErr) \
  497. AtalkDdpRefNextNc(pDdpAddr, ppDdpAddr, pErr)
  498. #define AtalkDdpDereference(pDdpAddr) \
  499. AtalkDdpDeref(pDdpAddr, FALSE)
  500. #define AtalkDdpDereferenceDpc(pDdpAddr) \
  501. AtalkDdpDeref(pDdpAddr, TRUE)
  502. #endif
  503. #define NET_ON_NONEXTPORT(pPort) \
  504. (pPort->pd_LtNetwork)
  505. #define NODE_ON_NONEXTPORT(pPort) \
  506. (((pPort)->pd_Nodes != NULL) ? \
  507. (pPort)->pd_Nodes->an_NodeAddr.atn_Node : 0)
  508. ATALK_ERROR
  509. atalkDdpAllocSocketOnNode(
  510. IN PPORT_DESCRIPTOR pPortDesc,
  511. IN BYTE Socket,
  512. IN PATALK_NODE pAtalkNode,
  513. IN DDPAO_HANDLER pSktHandler OPTIONAL,
  514. IN PVOID pSktCtx OPTIONAL,
  515. IN BYTE ProtoType OPTIONAL,
  516. IN PATALK_DEV_CTX pDevCtx,
  517. OUT PDDP_ADDROBJ pDdpAddr);
  518. VOID
  519. atalkDdpInitCloseComplete(
  520. IN ATALK_ERROR Error,
  521. IN PVOID Ctx);
  522. /*
  523. PBRE
  524. atalkDdpFindInBrc(
  525. IN PPORT_DESCRIPTOR pPortDesc,
  526. IN PATALK_NODEADDR pDestNodeAddr);
  527. */
  528. #define atalkDdpFindInBrc(_pPortDesc, _Network, _ppBre) \
  529. { \
  530. USHORT index; \
  531. KIRQL OldIrql; \
  532. PBRE pBre; \
  533. \
  534. index = (_Network) & (PORT_BRC_HASH_SIZE - 1); \
  535. \
  536. ACQUIRE_SPIN_LOCK(&(_pPortDesc)->pd_Lock, &OldIrql); \
  537. \
  538. for (pBre = (_pPortDesc)->pd_Brc[index]; \
  539. pBre != NULL; \
  540. pBre = pBre->bre_Next) \
  541. { \
  542. if ((_Network) == pBre->bre_Network) \
  543. { \
  544. break; \
  545. } \
  546. } \
  547. \
  548. RELEASE_SPIN_LOCK(&(_pPortDesc)->pd_Lock, OldIrql); \
  549. \
  550. *(_ppBre) = pBre; \
  551. }
  552. BOOLEAN
  553. atalkDdpFindAddrOnList(
  554. IN PATALK_NODE pAtalkNode,
  555. IN ULONG Index,
  556. IN BYTE Socket,
  557. OUT PDDP_ADDROBJ * ppDdpAddr);
  558. #define IS_VALID_SOCKET(Socket) \
  559. ((Socket == DYNAMIC_SOCKET) || \
  560. (Socket == LAST_DYNAMIC_SOCKET) || \
  561. ((Socket >= FIRST_STATIC_SOCKET) && \
  562. (Socket <= LAST_STATIC_SOCKET)))
  563. #endif // _DDP_