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.

1106 lines
28 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. ultdip.h
  5. Abstract:
  6. This module contains declarations private to the TDI component. These
  7. declarations are placed in a separate .H file to make it easier to access
  8. them from within the kernel debugger extension DLL.
  9. The TDI package manages two major object types: UL_ENDPOINT and
  10. UL_CONNECTION.
  11. A UL_ENDPOINT is basically a wrapper around a TDI address object. Each
  12. endpoint has two lists of associated UL_CONNECTION objects: one for
  13. idle (non-connected) connections and one for active (connected)
  14. connections. The active connections list is actually a 64-entry array
  15. for better multiprocessor partitioning.
  16. A UL_CONNECTION is basically a wrapper around a TDI connection object.
  17. Its main purpose is to manage TDI connection state. See the description
  18. of UL_CONNECTION_FLAGS below for the gory details.
  19. The relationship between these two objects is illustrated in the
  20. following diagram:
  21. +-----------+
  22. | |
  23. |UL_ENDPOINT|
  24. | |
  25. +---+----+--+
  26. | |
  27. | |
  28. | | Idle Connections
  29. | | +-------------+ +-------------+ +-------------+
  30. | | | | | | | |
  31. | +->|UL_CONNECTION|<->|UL_CONNECTION|<->|UL_CONNECTION|<-...
  32. | | | | | | |
  33. | +-------------+ +-------------+ +-------------+
  34. |
  35. |
  36. | Active Connections[0]
  37. | +-------------+ +-------------+ +-------------+
  38. | | | | | | |
  39. +------>|UL_CONNECTION|<->|UL_CONNECTION|<->|UL_CONNECTION|<-...
  40. | | | | | | |
  41. | +-------------+ +-------------+ +-------------+
  42. |
  43. :
  44. :
  45. | Active Connections[DEFAULT_MAX_CONNECTION_ACTIVE_LISTS-1]
  46. | +-------------+ +-------------+ +-------------+
  47. | | | | | | |
  48. +------>|UL_CONNECTION|<->|UL_CONNECTION|<->|UL_CONNECTION|<-...
  49. | | | | | |
  50. +-------------+ +-------------+ +-------------+
  51. Note: Idle connections do not hold references to their owning endpoint,
  52. but active connections do. When a listening endpoint is shutdown, all
  53. idle connections are simply purged, but active connections must be
  54. forcibly disconnected first.
  55. Author:
  56. Keith Moore (keithmo) 15-Jun-1998
  57. Revision History:
  58. --*/
  59. #ifndef _ULTDIP_H_
  60. #define _ULTDIP_H_
  61. #ifdef __cplusplus
  62. extern "C" {
  63. #endif
  64. //
  65. // Forward references.
  66. //
  67. typedef union _ENDPOINT_SYNCH *PENDPOINT_SYNCH;
  68. typedef struct _UL_ENDPOINT *PUL_ENDPOINT;
  69. typedef union _UL_CONNECTION_FLAGS *PUL_CONNECTION_FLAGS;
  70. typedef struct _UL_CONNECTION *PUL_CONNECTION;
  71. typedef struct _UL_RECEIVE_BUFFER *PUL_RECEIVE_BUFFER;
  72. //
  73. // Private constants.
  74. //
  75. #define MAX_ADDRESS_EA_BUFFER_LENGTH \
  76. sizeof(FILE_FULL_EA_INFORMATION) - 1 + \
  77. TDI_TRANSPORT_ADDRESS_LENGTH + 1 + \
  78. sizeof(TA_IP_ADDRESS)
  79. #define MAX_CONNECTION_EA_BUFFER_LENGTH \
  80. sizeof(FILE_FULL_EA_INFORMATION) - 1 + \
  81. TDI_CONNECTION_CONTEXT_LENGTH + 1 + \
  82. sizeof(CONNECTION_CONTEXT)
  83. #define TCP_DEVICE_NAME L"\\Device\\Tcp"
  84. #define TL_INSTANCE 0
  85. //
  86. // Private types.
  87. //
  88. //
  89. // A generic IRP context. This is useful for storing additional completion
  90. // information associated with a pending IRP.
  91. //
  92. // WARNING! All fields of this structure must be explicitly initialized.
  93. //
  94. typedef struct _UL_IRP_CONTEXT
  95. {
  96. //
  97. // This MUST be the first field in the structure. This is the linkage
  98. // used by the lookaside package for storing entries in the lookaside
  99. // list.
  100. //
  101. SINGLE_LIST_ENTRY LookasideEntry;
  102. //
  103. // Structure signature.
  104. //
  105. ULONG Signature;
  106. //
  107. // Either the endpoint or endpoint associated with the IRP.
  108. //
  109. PVOID pConnectionContext;
  110. //
  111. // Completion information.
  112. //
  113. PUL_COMPLETION_ROUTINE pCompletionRoutine;
  114. PVOID pCompletionContext;
  115. //
  116. // Our own allocated IRP if set.
  117. //
  118. PIRP pOwnIrp;
  119. } UL_IRP_CONTEXT, *PUL_IRP_CONTEXT;
  120. #define UL_IRP_CONTEXT_SIGNATURE ((ULONG)'CPRI')
  121. #define UL_IRP_CONTEXT_SIGNATURE_X MAKE_FREE_SIGNATURE(UL_IRP_CONTEXT_SIGNATURE)
  122. #define IS_VALID_IRP_CONTEXT(pIrpContext) \
  123. ( ((pIrpContext) != NULL) && \
  124. ((pIrpContext)->Signature == UL_IRP_CONTEXT_SIGNATURE) )
  125. //
  126. // The following union allows us to perform some spinlock-free synchronization
  127. // magic using UlInterlockedCompareExchange(). In this case, we can update
  128. // the number of idle connections that need to be added to an endpoint, *and*
  129. // update the "replenish scheduled" flag atomically.
  130. //
  131. typedef union _ENDPOINT_SYNCH
  132. {
  133. struct
  134. {
  135. LONG ReplenishScheduled:1;
  136. LONG IdleConnections:31;
  137. };
  138. LONG Value;
  139. } ENDPOINT_SYNCH;
  140. C_ASSERT( sizeof(ENDPOINT_SYNCH) == sizeof(LONG) );
  141. //
  142. // An endpoint is basically our wrapper around a TDI address object.
  143. //
  144. typedef struct _UL_ENDPOINT
  145. {
  146. //
  147. // Structure signature: UL_ENDPOINT_SIGNATURE
  148. //
  149. ULONG Signature;
  150. //
  151. // Reference count.
  152. //
  153. LONG ReferenceCount;
  154. //
  155. // Usage count. This is used by the "URL-site-to-endpoint" thingie.
  156. //
  157. LONG UsageCount;
  158. //
  159. // Links onto the global endpoint list.
  160. //
  161. // GlobalEndpointListEntry.Flink is NULL if the endpoint is not
  162. // on the global list, g_TdiEndpointListHead, or the
  163. // to-be-deleted-soon list, g_TdiDeletedEndpointListHead.
  164. //
  165. LIST_ENTRY GlobalEndpointListEntry;
  166. //
  167. // Heads of the per-endpoint connection lists.
  168. // Idle connections have a weak reference to 'this', the owning endpoint
  169. //
  170. SLIST_HEADER IdleConnectionSListHead;
  171. //
  172. // Use an array of active connections to improve partitioning on MP systems
  173. //
  174. LIST_ENTRY ActiveConnectionListHead[DEFAULT_MAX_CONNECTION_ACTIVE_LISTS];
  175. //
  176. // Index assigned to the next active connection.
  177. //
  178. LONG ActiveConnectionIndex;
  179. //
  180. // Spinlock protecting the IdleConnectionSLists.
  181. //
  182. UL_SPIN_LOCK IdleConnectionSpinLock;
  183. //
  184. // Spinlocks protecting the ActiveConnectionLists array.
  185. //
  186. UL_SPIN_LOCK ActiveConnectionSpinLock[DEFAULT_MAX_CONNECTION_ACTIVE_LISTS];
  187. //
  188. // Spinlock protecting the endpoint. Use sparingly.
  189. //
  190. UL_SPIN_LOCK EndpointSpinLock;
  191. //
  192. // The TDI address object.
  193. //
  194. UX_TDI_OBJECT AddressObject;
  195. //
  196. // Indication handlers & user context.
  197. //
  198. PUL_CONNECTION_REQUEST pConnectionRequestHandler;
  199. PUL_CONNECTION_COMPLETE pConnectionCompleteHandler;
  200. PUL_CONNECTION_DISCONNECT pConnectionDisconnectHandler;
  201. PUL_CONNECTION_DISCONNECT_COMPLETE pConnectionDisconnectCompleteHandler;
  202. PUL_CONNECTION_DESTROYED pConnectionDestroyedHandler;
  203. PUL_DATA_RECEIVE pDataReceiveHandler;
  204. PVOID pListeningContext;
  205. //
  206. // The local address we're bound to.
  207. //
  208. PTRANSPORT_ADDRESS pLocalAddress;
  209. ULONG LocalAddressLength;
  210. //
  211. // Is this a secure endpoint?
  212. //
  213. BOOLEAN Secure;
  214. //
  215. // Thread work item for deferred actions.
  216. //
  217. UL_WORK_ITEM WorkItem;
  218. //
  219. // Synchronizer for idle connection replenishment.
  220. //
  221. ENDPOINT_SYNCH EndpointSynch;
  222. //
  223. // An IRP context containing completion information necessary
  224. // while shutting down a listening endpoint.
  225. //
  226. UL_IRP_CONTEXT CleanupIrpContext;
  227. #if ENABLE_OWNER_REF_TRACE
  228. //
  229. // Track owners of the endpoint reference count
  230. //
  231. POWNER_REF_TRACELOG pOwnerRefTraceLog;
  232. PREF_OWNER pEndpointRefOwner;
  233. #endif // ENABLE_OWNER_REF_TRACE
  234. //
  235. // Has this endpoint been moved to the deleted list,
  236. // g_TdiDeletedEndpointListHead?
  237. //
  238. BOOLEAN Deleted;
  239. } UL_ENDPOINT;
  240. #define UL_ENDPOINT_SIGNATURE ((ULONG)'PDNE')
  241. #define UL_ENDPOINT_SIGNATURE_X MAKE_FREE_SIGNATURE(UL_ENDPOINT_SIGNATURE)
  242. #define IS_VALID_ENDPOINT(pEndpoint) \
  243. ( ((pEndpoint) != NULL) && \
  244. ((pEndpoint)->Signature == UL_ENDPOINT_SIGNATURE) )
  245. //
  246. // Connection flags/state. These flags indicate the current state of a
  247. // connection.
  248. //
  249. // Some of these flags may be simply updated directly. Others require
  250. // UlInterlockedCompareExchange() to avoid race conditions.
  251. //
  252. // The following flags may be updated directly:
  253. //
  254. // AcceptPending - SET in the TDI connection handler, just before the
  255. // accept IRP is returned to the transport. RESET only if the accept
  256. // IRP fails.
  257. //
  258. // The following flags must be updated using UlInterlockedCompareExchange():
  259. //
  260. // AcceptComplete - SET in the accept IRP completion handler if the IRP
  261. // completed successfully. Once this flag is set, the connection must
  262. // be either gracefully disconnected or aborted before the connection
  263. // can be closed or reused.
  264. //
  265. // DisconnectPending - SET just before a graceful disconnect IRP is
  266. // issued.
  267. //
  268. // DisconnectComplete - SET in the graceful disconnect IRP completion
  269. // handler.
  270. //
  271. // AbortPending - SET just before an abortive disconnect IRP is issued.
  272. //
  273. // AbortComplete - SET in the abortive disconnect IRP completion handler.
  274. //
  275. // DisconnectIndicated - SET in the TDI disconnect handler for graceful
  276. // disconnects issued by the remote client.
  277. //
  278. // AbortIndicated - SET in the TDI disconnect handler for abortive
  279. // disconnects issued by the remote client.
  280. //
  281. // CleanupPending - SET when cleanup is begun for a connection. This
  282. // is necessary to know when the final reference to the connection
  283. // can be removed.
  284. //
  285. // CODEWORK: We can get rid of the CleanupPending flag. It is
  286. // only set when either a graceful or abortive disconnect is
  287. // issued, and only tested in UlpRemoveFinalReference(). The
  288. // test in UlpRemoveFinalReference() can just test for either
  289. // (DisconnectPending | AbortPending) instead.
  290. //
  291. // FinalReferenceRemoved - SET when the final (i.e. "connected")
  292. // reference is removed from the connection.
  293. //
  294. // Note that the flags requiring UlInterlockedCompareExchange() are only SET,
  295. // never RESET. This makes the implementation a bit simpler.
  296. //
  297. // And now a few words about connection management, TDI, and other mysteries.
  298. //
  299. // Some of the more annoying "features" of TDI are related to connection
  300. // management and lifetime. Two of the most onerous issues are:
  301. //
  302. // 1. Knowing when a connection object handle can be closed without
  303. // causing an unwanted connection reset.
  304. //
  305. // 2. Knowing when TDI has given its last indication on a connection
  306. // so that resources can be released, reused, recycled, whatever.
  307. //
  308. // And, of course, this is further complicated by the inherent asynchronous
  309. // nature of the NT I/O architecture and the parallelism of SMP systems.
  310. //
  311. // There are a few points worth keeping in mind while reading/modifying this
  312. // source code or writing clients of this code:
  313. //
  314. // 1. As soon as an accept IRP is returned from the TDI connection
  315. // handler to the transport, the TDI client must be prepared for
  316. // any incoming indications, including data receive and disconnect.
  317. // In other words, incoming data & disconnect may occur *before* the
  318. // accept IRP actually completes.
  319. //
  320. // 2. A connection is considered "in use" until either both sides have
  321. // gracefully disconnected OR either side has aborted the connection.
  322. // Closing an "in use" connection will usually result in an abortive
  323. // disconnect.
  324. //
  325. // 3. The various flavors of disconnect (initiated by the local server,
  326. // initiated by the remote client, graceful, abortive, etc) may occur
  327. // in any order.
  328. //
  329. typedef union _UL_CONNECTION_FLAGS
  330. {
  331. //
  332. // This field overlays all of the settable flags. This allows us to
  333. // update all flags in a thread-safe manner using the
  334. // UlInterlockedCompareExchange() API.
  335. //
  336. LONG Value;
  337. struct
  338. {
  339. ULONG AcceptPending:1; // 00000001
  340. ULONG AcceptComplete:1; // 00000002
  341. ULONG :2;
  342. ULONG DisconnectPending:1; // 00000010
  343. ULONG DisconnectComplete:1; // 00000020
  344. ULONG :2;
  345. ULONG AbortPending:1; // 00000100
  346. ULONG AbortComplete:1; // 00000200
  347. ULONG :2;
  348. ULONG DisconnectIndicated:1; // 00001000
  349. ULONG AbortIndicated:1; // 00002000
  350. ULONG :2;
  351. ULONG CleanupBegun:1; // 00010000
  352. ULONG FinalReferenceRemoved:1; // 00020000
  353. ULONG :2;
  354. ULONG LocalAddressValid:1; // 00100000
  355. ULONG ReceivePending:1; // 00200000
  356. };
  357. } UL_CONNECTION_FLAGS;
  358. C_ASSERT( sizeof(UL_CONNECTION_FLAGS) == sizeof(LONG) );
  359. #define MAKE_CONNECTION_FLAG_ROUTINE(name) \
  360. __inline LONG Make##name##Flag() \
  361. { \
  362. UL_CONNECTION_FLAGS flags = { 0 }; \
  363. flags.name = 1; \
  364. return flags.Value; \
  365. }
  366. MAKE_CONNECTION_FLAG_ROUTINE( AcceptPending );
  367. MAKE_CONNECTION_FLAG_ROUTINE( AcceptComplete );
  368. MAKE_CONNECTION_FLAG_ROUTINE( DisconnectPending );
  369. MAKE_CONNECTION_FLAG_ROUTINE( DisconnectComplete );
  370. MAKE_CONNECTION_FLAG_ROUTINE( AbortPending );
  371. MAKE_CONNECTION_FLAG_ROUTINE( AbortComplete );
  372. MAKE_CONNECTION_FLAG_ROUTINE( DisconnectIndicated );
  373. MAKE_CONNECTION_FLAG_ROUTINE( AbortIndicated );
  374. MAKE_CONNECTION_FLAG_ROUTINE( CleanupBegun );
  375. MAKE_CONNECTION_FLAG_ROUTINE( FinalReferenceRemoved );
  376. //
  377. // A connection is basically our wrapper around a TDI connection object.
  378. //
  379. typedef struct _UL_CONNECTION
  380. {
  381. //
  382. // Link onto the per-endpoint idle connection list.
  383. //
  384. SINGLE_LIST_ENTRY IdleSListEntry;
  385. //
  386. // Structure signature: UL_CONNECTION_SIGNATURE
  387. //
  388. ULONG Signature;
  389. //
  390. // Reference count.
  391. //
  392. LONG ReferenceCount;
  393. //
  394. // Connection flags.
  395. //
  396. UL_CONNECTION_FLAGS ConnectionFlags;
  397. //
  398. // Cached Irp
  399. //
  400. PIRP pIrp;
  401. //
  402. // Addresses and ports. These are in host order.
  403. // CODEWORK: Make these transport independent for IPv6.
  404. //
  405. IPAddr RemoteAddress;
  406. USHORT RemotePort;
  407. USHORT LocalPort;
  408. IPAddr LocalAddress;
  409. //
  410. // Structure to get LocalAddress when Accept completes
  411. //
  412. TDI_CONNECTION_INFORMATION TdiConnectionInformation;
  413. TA_IP_ADDRESS IpAddress;
  414. //
  415. // Link onto the per-endpoint active connection list.
  416. //
  417. LIST_ENTRY ActiveListEntry;
  418. //
  419. // Index to the ActiveConnectionLists (a random number for better partition
  420. // on MP machines). Always zero on UP machines.
  421. //
  422. ULONG ActiveListIndex;
  423. //
  424. // The TDI connection object.
  425. //
  426. UX_TDI_OBJECT ConnectionObject;
  427. //
  428. // User context.
  429. //
  430. PVOID pConnectionContext;
  431. //
  432. // The endpoint associated with this connection. Note that this
  433. // ALWAYS points to a valid endpoint. For idle connections, it's
  434. // a weak (non referenced) pointer. For active connections, it's
  435. // a strong (referenced) pointer.
  436. //
  437. PUL_ENDPOINT pOwningEndpoint;
  438. //
  439. // Thread work item for deferred actions.
  440. //
  441. UL_WORK_ITEM WorkItem;
  442. //
  443. // Data captured from the listening endpoint at the time the
  444. // connection is created. This is captured to reduce references
  445. // to the listening endpoint.
  446. //
  447. PUL_CONNECTION_DESTROYED pConnectionDestroyedHandler;
  448. PVOID pListeningContext;
  449. //
  450. // To synchronize the RawCloseHandler
  451. //
  452. LONG Terminated;
  453. //
  454. // Pre-allocated IrpContext for disconnect.
  455. //
  456. UL_IRP_CONTEXT IrpContext;
  457. //
  458. // HTTP connection.
  459. //
  460. UL_HTTP_CONNECTION HttpConnection;
  461. //
  462. // Filter related info.
  463. //
  464. UX_FILTER_CONNECTION FilterInfo;
  465. //
  466. // We've had too many problems with orphaned UL_CONNECTIONs.
  467. // Let's make it easy to find them all in the debugger.
  468. //
  469. LIST_ENTRY GlobalConnectionListEntry;
  470. #if REFERENCE_DEBUG
  471. //
  472. // Private Reference trace log.
  473. //
  474. PTRACE_LOG pTraceLog;
  475. #endif // REFERENCE_DEBUG
  476. #if ENABLE_OWNER_REF_TRACE
  477. // For ownerref and connection recycling
  478. PREF_OWNER pConnRefOwner;
  479. LONG MonotonicId;
  480. #endif // ENABLE_OWNER_REF_TRACE
  481. } UL_CONNECTION, *PUL_CONNECTION;
  482. #define UL_CONNECTION_SIGNATURE ((ULONG)'NNOC')
  483. #define UL_CONNECTION_SIGNATURE_X MAKE_FREE_SIGNATURE(UL_CONNECTION_SIGNATURE)
  484. #define IS_VALID_CONNECTION(pConnection) \
  485. ( ((pConnection) != NULL) && \
  486. ((pConnection)->Signature == UL_CONNECTION_SIGNATURE) )
  487. //
  488. // A buffer, containing a precreated receive IRP, a precreated MDL, and
  489. // sufficient space for a partial MDL. These buffers are typically used
  490. // when passing a receive IRP back to the transport from within our receive
  491. // indication handler.
  492. //
  493. // The buffer structure, IRP, MDLs, and data area are all allocated in a
  494. // single pool block. The layout of the block is:
  495. //
  496. // +-------------------+
  497. // | |
  498. // | UL_RECEIVE_BUFFER |
  499. // | |
  500. // +-------------------+
  501. // | |
  502. // | IRP |
  503. // | |
  504. // +-------------------+
  505. // | |
  506. // | MDL |
  507. // | |
  508. // +-------------------+
  509. // | |
  510. // | Partial MDL |
  511. // | |
  512. // +-------------------+
  513. // | |
  514. // | Data Area |
  515. // | |
  516. // +-------------------+
  517. //
  518. // WARNING! All fields of this structure must be explicitly initialized.
  519. //
  520. typedef struct _UL_RECEIVE_BUFFER
  521. {
  522. //
  523. // This MUST be the first field in the structure. This is the linkage
  524. // used by the lookaside package for storing entries in the lookaside
  525. // list.
  526. //
  527. SINGLE_LIST_ENTRY LookasideEntry;
  528. //
  529. // Structure signature: UL_RECEIVE_BUFFER_SIGNATURE
  530. //
  531. ULONG Signature;
  532. //
  533. // Amount of unread data in the data area.
  534. //
  535. ULONG UnreadDataLength;
  536. //
  537. // The pre-built receive IRP.
  538. //
  539. PIRP pIrp;
  540. //
  541. // The pre-built MDL describing the entire data area.
  542. //
  543. PMDL pMdl;
  544. //
  545. // A secondary MDL describing part of the data area.
  546. //
  547. PMDL pPartialMdl;
  548. //
  549. // Pointer to the data area for this buffer.
  550. //
  551. PVOID pDataArea;
  552. //
  553. // Pointer to the connection referencing this buffer.
  554. //
  555. PVOID pConnectionContext;
  556. } UL_RECEIVE_BUFFER;
  557. #define UL_RECEIVE_BUFFER_SIGNATURE ((ULONG)'FUBR')
  558. #define UL_RECEIVE_BUFFER_SIGNATURE_X MAKE_FREE_SIGNATURE(UL_RECEIVE_BUFFER_SIGNATURE)
  559. #define IS_VALID_RECEIVE_BUFFER(pBuffer) \
  560. ( ((pBuffer) != NULL) && \
  561. ((pBuffer)->Signature == UL_RECEIVE_BUFFER_SIGNATURE) )
  562. //
  563. // Private prototypes.
  564. //
  565. VOID
  566. UlpDestroyEndpoint(
  567. IN PUL_ENDPOINT pEndpoint
  568. );
  569. VOID
  570. UlpDestroyConnection(
  571. IN PUL_CONNECTION pConnection
  572. );
  573. PUL_CONNECTION
  574. UlpDequeueIdleConnection(
  575. IN PUL_ENDPOINT pEndpoint,
  576. IN BOOLEAN ScheduleReplenish
  577. );
  578. BOOLEAN
  579. UlpEnqueueIdleConnection(
  580. IN PUL_CONNECTION pConnection,
  581. IN BOOLEAN Replenishing
  582. );
  583. VOID
  584. UlpEnqueueActiveConnection(
  585. IN PUL_CONNECTION pConnection
  586. );
  587. NTSTATUS
  588. UlpConnectHandler(
  589. IN PVOID pTdiEventContext,
  590. IN LONG RemoteAddressLength,
  591. IN PVOID pRemoteAddress,
  592. IN LONG UserDataLength,
  593. IN PVOID pUserData,
  594. IN LONG OptionsLength,
  595. IN PVOID pOptions,
  596. OUT CONNECTION_CONTEXT *pConnectionContext,
  597. OUT PIRP *pAcceptIrp
  598. );
  599. NTSTATUS
  600. UlpDisconnectHandler(
  601. IN PVOID pTdiEventContext,
  602. IN CONNECTION_CONTEXT ConnectionContext,
  603. IN LONG DisconnectDataLength,
  604. IN PVOID pDisconnectData,
  605. IN LONG DisconnectInformationLength,
  606. IN PVOID pDisconnectInformation,
  607. IN ULONG DisconnectFlags
  608. );
  609. NTSTATUS
  610. UlpCloseRawConnection(
  611. IN PVOID pConnection,
  612. IN BOOLEAN AbortiveDisconnect,
  613. IN PUL_COMPLETION_ROUTINE pCompletionRoutine,
  614. IN PVOID pCompletionContext
  615. );
  616. NTSTATUS
  617. UlpSendRawData(
  618. IN PVOID pObject,
  619. IN PMDL pMdlChain,
  620. IN ULONG Length,
  621. PUL_IRP_CONTEXT pIrpContext
  622. );
  623. NTSTATUS
  624. UlpReceiveRawData(
  625. IN PVOID pConnectionContext,
  626. IN PVOID pBuffer,
  627. IN ULONG BufferLength,
  628. IN PUL_COMPLETION_ROUTINE pCompletionRoutine,
  629. IN PVOID pCompletionContext
  630. );
  631. NTSTATUS
  632. UlpDummyReceiveHandler(
  633. IN PVOID pTdiEventContext,
  634. IN PVOID ConnectionContext,
  635. IN PVOID pTsdu,
  636. IN ULONG BytesIndicated,
  637. IN ULONG BytesUnreceived,
  638. OUT ULONG *pBytesTaken
  639. );
  640. NTSTATUS
  641. UlpReceiveHandler(
  642. IN PVOID pTdiEventContext,
  643. IN CONNECTION_CONTEXT ConnectionContext,
  644. IN ULONG ReceiveFlags,
  645. IN ULONG BytesIndicated,
  646. IN ULONG BytesAvailable,
  647. OUT ULONG *pBytesTaken,
  648. IN PVOID pTsdu,
  649. OUT PIRP *pIrp
  650. );
  651. NTSTATUS
  652. UlpReceiveExpeditedHandler(
  653. IN PVOID pTdiEventContext,
  654. IN CONNECTION_CONTEXT ConnectionContext,
  655. IN ULONG ReceiveFlags,
  656. IN ULONG BytesIndicated,
  657. IN ULONG BytesAvailable,
  658. OUT ULONG *pBytesTaken,
  659. IN PVOID pTsdu,
  660. OUT PIRP *pIrp
  661. );
  662. NTSTATUS
  663. UlpRestartAccept(
  664. IN PDEVICE_OBJECT pDeviceObject,
  665. IN PIRP pIrp,
  666. IN PVOID pContext
  667. );
  668. NTSTATUS
  669. UlpRestartSendData(
  670. IN PDEVICE_OBJECT pDeviceObject,
  671. IN PIRP pIrp,
  672. IN PVOID pContext
  673. );
  674. VOID
  675. UlpReferenceEndpoint(
  676. IN PUL_ENDPOINT pEndpoint
  677. OWNER_REFERENCE_DEBUG_FORMAL_PARAMS
  678. );
  679. VOID
  680. UlpDereferenceEndpoint(
  681. IN PUL_ENDPOINT pEndpoint
  682. OWNER_REFERENCE_DEBUG_FORMAL_PARAMS
  683. );
  684. #if REFERENCE_DEBUG
  685. # define REFERENCE_ENDPOINT(endp, action, sig, powner, pprefowner, monoid) \
  686. UlpReferenceEndpoint( (endp), (powner), (pprefowner), (sig), \
  687. action, monoid, (PSTR)__FILE__,(USHORT)__LINE__)
  688. # define DEREFERENCE_ENDPOINT(endp, action, sig, powner, pprefowner, monoid)\
  689. UlpDereferenceEndpoint( (endp), (powner), (pprefowner), (sig), \
  690. action, monoid, (PSTR)__FILE__,(USHORT)__LINE__)
  691. #else // !REFERENCE_DEBUG
  692. # define REFERENCE_ENDPOINT(endp, action, sig, powner, pprefowner, monoid) \
  693. UlpReferenceEndpoint( (endp) )
  694. # define DEREFERENCE_ENDPOINT(endp, action, sig, powner, pprefowner, monoid) \
  695. UlpDereferenceEndpoint( (endp) )
  696. #endif // !REFERENCE_DEBUG
  697. #define REFERENCE_ENDPOINT_SELF(endp, action) \
  698. REFERENCE_ENDPOINT( \
  699. (endp), \
  700. (action), \
  701. UL_ENDPOINT_SIGNATURE, \
  702. (endp), \
  703. &(endp)->pEndpointRefOwner, \
  704. -1)
  705. #define DEREFERENCE_ENDPOINT_SELF(endp, action) \
  706. DEREFERENCE_ENDPOINT( \
  707. (endp), \
  708. (action), \
  709. UL_ENDPOINT_SIGNATURE, \
  710. (endp), \
  711. &(endp)->pEndpointRefOwner, \
  712. -1)
  713. #define REFERENCE_ENDPOINT_CONNECTION(endp, action, pconn) \
  714. REFERENCE_ENDPOINT( \
  715. (endp), \
  716. (action), \
  717. UL_CONNECTION_SIGNATURE, \
  718. (pconn), \
  719. &(pconn)->pConnRefOwner, \
  720. (pconn)->MonotonicId)
  721. #define DEREFERENCE_ENDPOINT_CONNECTION(endp, action, pconn)\
  722. DEREFERENCE_ENDPOINT( \
  723. (endp), \
  724. (action), \
  725. UL_CONNECTION_SIGNATURE, \
  726. (pconn), \
  727. &(pconn)->pConnRefOwner, \
  728. (pconn)->MonotonicId)
  729. VOID
  730. UlpEndpointCleanupWorker(
  731. IN PUL_WORK_ITEM pWorkItem
  732. );
  733. VOID
  734. UlpCleanupConnectionId(
  735. IN PUL_WORK_ITEM pWorkItem
  736. );
  737. VOID
  738. UlpConnectionCleanupWorker(
  739. IN PUL_WORK_ITEM pWorkItem
  740. );
  741. NTSTATUS
  742. UlpAssociateConnection(
  743. IN PUL_CONNECTION pConnection,
  744. IN PUL_ENDPOINT pEndpoint
  745. );
  746. NTSTATUS
  747. UlpDisassociateConnection(
  748. IN PUL_CONNECTION pConnection
  749. );
  750. VOID
  751. UlpReplenishEndpoint(
  752. IN PUL_ENDPOINT pEndpoint
  753. );
  754. VOID
  755. UlpReplenishEndpointWorker(
  756. IN PUL_WORK_ITEM pWorkItem
  757. );
  758. BOOLEAN
  759. UlpDecrementIdleConnections(
  760. IN PUL_ENDPOINT pEndpoint
  761. );
  762. BOOLEAN
  763. UlpIncrementIdleConnections(
  764. IN PUL_ENDPOINT pEndpoint,
  765. IN BOOLEAN Replenishing
  766. );
  767. VOID
  768. UlpClearReplenishScheduledFlag(
  769. IN PUL_ENDPOINT pEndpoint
  770. );
  771. NTSTATUS
  772. UlpCreateConnection(
  773. IN PUL_ENDPOINT pEndpoint,
  774. IN ULONG AddressLength,
  775. OUT PUL_CONNECTION *ppConnection
  776. );
  777. NTSTATUS
  778. UlpInitializeConnection(
  779. IN PUL_CONNECTION pConnection
  780. );
  781. UL_CONNECTION_FLAGS
  782. UlpSetConnectionFlag(
  783. IN OUT PUL_CONNECTION pConnection,
  784. IN LONG NewFlag
  785. );
  786. NTSTATUS
  787. UlpBeginDisconnect(
  788. IN PUL_CONNECTION pConnection,
  789. IN PUL_COMPLETION_ROUTINE pCompletionRoutine,
  790. IN PVOID pCompletionContext
  791. );
  792. NTSTATUS
  793. UlpRestartDisconnect(
  794. IN PDEVICE_OBJECT pDeviceObject,
  795. IN PIRP pIrp,
  796. IN PVOID pContext
  797. );
  798. NTSTATUS
  799. UlpBeginAbort(
  800. IN PUL_CONNECTION pConnection,
  801. IN PUL_COMPLETION_ROUTINE pCompletionRoutine,
  802. IN PVOID pCompletionContext
  803. );
  804. NTSTATUS
  805. UlpRestartAbort(
  806. IN PDEVICE_OBJECT pDeviceObject,
  807. IN PIRP pIrp,
  808. IN PVOID pContext
  809. );
  810. VOID
  811. UlpRemoveFinalReference(
  812. IN PUL_CONNECTION pConnection,
  813. IN UL_CONNECTION_FLAGS Flags
  814. );
  815. NTSTATUS
  816. UlpRestartReceive(
  817. IN PDEVICE_OBJECT pDeviceObject,
  818. IN PIRP pIrp,
  819. IN PVOID pContext
  820. );
  821. NTSTATUS
  822. UlpRestartClientReceive(
  823. IN PDEVICE_OBJECT pDeviceObject,
  824. IN PIRP pIrp,
  825. IN PVOID pContext
  826. );
  827. NTSTATUS
  828. UlpDisconnectAllActiveConnections(
  829. IN PUL_ENDPOINT pEndpoint
  830. );
  831. VOID
  832. UlpUnbindConnectionFromEndpoint(
  833. IN PUL_CONNECTION pConnection
  834. );
  835. VOID
  836. UlpSynchronousIoComplete(
  837. IN PVOID pCompletionContext,
  838. IN NTSTATUS Status,
  839. IN ULONG_PTR Information
  840. );
  841. NTSTATUS
  842. UlpUrlToAddress(
  843. IN PWSTR pSiteUrl,
  844. OUT PTA_IP_ADDRESS pAddress,
  845. OUT PBOOLEAN pSecure
  846. );
  847. PUL_ENDPOINT
  848. UlpFindEndpointForAddress(
  849. IN PTRANSPORT_ADDRESS pAddress,
  850. IN ULONG AddressLength
  851. );
  852. NTSTATUS
  853. UlpSetNagling(
  854. IN PUX_TDI_OBJECT pTdiObject,
  855. IN BOOLEAN Flag
  856. );
  857. NTSTATUS
  858. UlpRestartQueryAddress(
  859. IN PDEVICE_OBJECT pDeviceObject,
  860. IN PIRP pIrp,
  861. IN PVOID pContext
  862. );
  863. VOID
  864. UlpCleanupEarlyConnection(
  865. IN PUL_WORK_ITEM pWorkItem
  866. );
  867. NTSTATUS
  868. UlpQueryTcpFastSend();
  869. NTSTATUS
  870. UlpBuildTdiReceiveBuffer(
  871. IN PUX_TDI_OBJECT pTdiObject,
  872. IN PUL_CONNECTION pConnection,
  873. OUT PIRP *pIrp
  874. );
  875. #ifdef __cplusplus
  876. }; // extern "C"
  877. #endif
  878. #endif // _ULTDIP_H_