Leaked source code of windows server 2003
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.

1765 lines
66 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. afdstr.h
  5. Abstract:
  6. This module contains typedefs for structures used by AFD.
  7. Author:
  8. David Treadwell (davidtr) 21-Feb-1992
  9. Revision History:
  10. --*/
  11. #ifndef _AFDSTR_
  12. #define _AFDSTR_
  13. //
  14. // This field defines the layout of a 32-bit pointer.
  15. // This must be ULONG as wow64 support 4gb address on win64.
  16. // You shouldn't POINTER_32 as this will sign-extend addresses when converting
  17. // it to a 64-bit pointer and will end up having the wrong address.
  18. //
  19. typedef ULONG AFD_POINTER_32;
  20. //
  21. // Make sure that queued spinlocks are not used with
  22. // regular spinlock functions by wrapping them into
  23. // a different structure.
  24. //
  25. typedef struct _AFD_QSPIN_LOCK {
  26. KSPIN_LOCK ActualSpinLock;
  27. } AFD_QSPIN_LOCK, *PAFD_QSPIN_LOCK;
  28. #if DBG
  29. #ifndef REFERENCE_DEBUG
  30. #define REFERENCE_DEBUG 1
  31. #endif
  32. #ifndef GLOBAL_REFERENCE_DEBUG
  33. #define GLOBAL_REFERENCE_DEBUG 0
  34. #endif
  35. //
  36. // Debug aid for queued spinlocks
  37. // Allows us to verify that spinlock is released using
  38. // the same handle as it was taken with.
  39. //
  40. typedef struct _AFD_LOCK_QUEUE_HANDLE {
  41. KLOCK_QUEUE_HANDLE LockHandle;
  42. PAFD_QSPIN_LOCK SpinLock;
  43. } AFD_LOCK_QUEUE_HANDLE, *PAFD_LOCK_QUEUE_HANDLE;
  44. #else
  45. #ifndef REFERENCE_DEBUG
  46. #define REFERENCE_DEBUG 0
  47. #endif
  48. #ifndef GLOBAL_REFERENCE_DEBUG
  49. #define GLOBAL_REFERENCE_DEBUG 0
  50. #endif
  51. #define AFD_LOCK_QUEUE_HANDLE KLOCK_QUEUE_HANDLE
  52. #define PAFD_LOCK_QUEUE_HANDLE PKLOCK_QUEUE_HANDLE
  53. #endif // DBG
  54. #if REFERENCE_DEBUG
  55. #define AFD_REF_SHIFT 6
  56. #define AFD_REF_MASK ((1<<AFD_REF_SHIFT)-1)
  57. #define AFD_MAX_REF (1<<AFD_REF_SHIFT)
  58. #define AFD_REF_TIME_BITS 16
  59. #define AFD_MAX_REF_TIME ((1<<AFD_REF_TIME_BITS)-1)
  60. #define AFD_TIME_EXP_SHIFT 4
  61. #define AFD_TIME_EXP_BITS 2
  62. #define AFD_REF_CNT_BITS 4
  63. #define AFD_REF_LOC_BITS (32-AFD_REF_CNT_BITS-AFD_REF_TIME_BITS-AFD_TIME_EXP_BITS)
  64. C_ASSERT (32-AFD_REF_SHIFT-AFD_REF_TIME_BITS <=
  65. AFD_TIME_EXP_SHIFT*((1<<AFD_TIME_EXP_BITS)-1));
  66. typedef union _AFD_REFERENCE_DEBUG {
  67. struct {
  68. ULONGLONG NewCount:AFD_REF_CNT_BITS;
  69. ULONGLONG LocationId:AFD_REF_LOC_BITS;
  70. ULONGLONG TimeExp:AFD_TIME_EXP_BITS;
  71. ULONGLONG TimeDif:AFD_REF_TIME_BITS;
  72. ULONGLONG Param:32;
  73. };
  74. ULONGLONG QuadPart;
  75. } AFD_REFERENCE_DEBUG, *PAFD_REFERENCE_DEBUG;
  76. C_ASSERT (sizeof (AFD_REFERENCE_DEBUG)==sizeof (ULONGLONG));
  77. typedef struct _AFD_REFERENCE_LOCATION {
  78. PCHAR Format;
  79. PVOID Address;
  80. } AFD_REFERENCE_LOCATION, *PAFD_REFERENCE_LOCATION;
  81. LONG
  82. AfdFindReferenceLocation (
  83. IN PCHAR Format,
  84. OUT PLONG LocationId
  85. );
  86. #define AFD_GET_ARL(_s) (_arl ? _arl : AfdFindReferenceLocation((_s),&_arl))
  87. #define AFD_UPDATE_REFERENCE_DEBUG(_rd,_r,_l,_p) \
  88. do { \
  89. LONG _n, _n1; \
  90. ULONGLONG _t = KeQueryInterruptTime (); \
  91. _n = (_rd)->CurrentReferenceSlot; \
  92. _n1 = (((LONG)(_t>>13))<<AFD_REF_SHIFT) + ((_n+1)&AFD_REF_MASK);\
  93. if (InterlockedCompareExchange (&(_rd)->CurrentReferenceSlot, \
  94. _n1,_n)==_n) { \
  95. PAFD_REFERENCE_DEBUG _s; \
  96. LONG _d,_e=0; \
  97. (_rd)->CurrentTimeHigh = (LONG)(_t>>(13+32-AFD_REF_SHIFT)); \
  98. _s = &(_rd)->ReferenceDebug[_n & AFD_REF_MASK]; \
  99. _s->NewCount = _r; \
  100. _s->LocationId = _l; \
  101. _s->Param = _p; \
  102. _d = (_n1-1-_n) >> AFD_REF_SHIFT; \
  103. while (_d>=AFD_MAX_REF_TIME) { \
  104. _e += 1; \
  105. _d >>= _e*AFD_TIME_EXP_SHIFT; \
  106. } \
  107. _s->TimeDif = _d; \
  108. _s->TimeExp = _e; \
  109. break; \
  110. } \
  111. } while (1)
  112. #if GLOBAL_REFERENCE_DEBUG
  113. #define MAX_GLOBAL_REFERENCE 4096
  114. typedef struct _AFD_GLOBAL_REFERENCE_DEBUG {
  115. PVOID Info1;
  116. PVOID Info2;
  117. PVOID Connection;
  118. ULONG_PTR Action;
  119. LARGE_INTEGER TickCounter;
  120. ULONG NewCount;
  121. ULONG Dummy;
  122. } AFD_GLOBAL_REFERENCE_DEBUG, *PAFD_GLOBAL_REFERENCE_DEBUG;
  123. #endif
  124. #endif
  125. //
  126. // A structure for maintaining work queue information in AFD.
  127. //
  128. typedef struct _AFD_WORK_ITEM {
  129. LIST_ENTRY WorkItemListEntry;
  130. PWORKER_THREAD_ROUTINE AfdWorkerRoutine;
  131. PVOID Context;
  132. } AFD_WORK_ITEM, *PAFD_WORK_ITEM;
  133. //
  134. // Structures for holding connect data pointers and lengths. This is
  135. // kept separate from the normal structures to save space in those
  136. // structures for transports that do not support and applications
  137. // which do not use connect data.
  138. //
  139. typedef struct _AFD_CONNECT_DATA_INFO {
  140. PVOID Buffer;
  141. ULONG BufferLength;
  142. } AFD_CONNECT_DATA_INFO, *PAFD_CONNECT_DATA_INFO;
  143. typedef struct _AFD_CONNECT_DATA_BUFFERS {
  144. AFD_CONNECT_DATA_INFO SendConnectData;
  145. AFD_CONNECT_DATA_INFO SendConnectOptions;
  146. AFD_CONNECT_DATA_INFO ReceiveConnectData;
  147. AFD_CONNECT_DATA_INFO ReceiveConnectOptions;
  148. AFD_CONNECT_DATA_INFO SendDisconnectData;
  149. AFD_CONNECT_DATA_INFO SendDisconnectOptions;
  150. AFD_CONNECT_DATA_INFO ReceiveDisconnectData;
  151. AFD_CONNECT_DATA_INFO ReceiveDisconnectOptions;
  152. TDI_CONNECTION_INFORMATION RequestConnectionInfo;
  153. TDI_CONNECTION_INFORMATION ReturnConnectionInfo;
  154. ULONG Flags;
  155. } AFD_CONNECT_DATA_BUFFERS, *PAFD_CONNECT_DATA_BUFFERS;
  156. //
  157. // Structure used for holding disconnect context information.
  158. //
  159. typedef struct _AFD_ENDPOINT AFD_ENDPOINT, *PAFD_ENDPOINT;
  160. typedef struct _AFD_CONNECTION AFD_CONNECTION, *PAFD_CONNECTION;
  161. typedef struct _AFD_TPACKETS_INFO_INTERNAL
  162. AFD_TPACKETS_INFO_INTERNAL,
  163. *PAFD_TPACKETS_INFO_INTERNAL;
  164. typedef DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
  165. struct _AFD_BUFFER
  166. AFD_BUFFER,
  167. *PAFD_BUFFER;
  168. typedef struct _AFD_DISCONNECT_CONTEXT {
  169. LARGE_INTEGER Timeout;
  170. PIRP Irp;
  171. } AFD_DISCONNECT_CONTEXT, *PAFD_DISCONNECT_CONTEXT;
  172. typedef struct _AFD_LR_LIST_ITEM AFD_LR_LIST_ITEM, *PAFD_LR_LIST_ITEM;
  173. typedef BOOLEAN (* PAFD_LR_LIST_ROUTINE) (PAFD_LR_LIST_ITEM Item);
  174. struct _AFD_LR_LIST_ITEM {
  175. SLIST_ENTRY SListLink; // Link in the list
  176. PAFD_LR_LIST_ROUTINE Routine; // Processing routine;
  177. };
  178. //
  179. // Endpoint and connection structures and related informaion.
  180. //
  181. //
  182. // Block types that identify which fields are
  183. // available in the strucutures.
  184. //
  185. #define AfdBlockTypeEndpoint 0xAFD0 // VC endpoint before connect/accept/listen
  186. #define AfdBlockTypeDatagram 0xAFD1 // Datagram endpoint in any state
  187. #define AfdBlockTypeVcConnecting 0xAFD2 // VC endpoint after connect/accept
  188. #define AfdBlockTypeVcListening 0xAFD4 // VC endpoint after listen
  189. #define AfdBlockTypeVcBoth 0xAFD6 // VC endpoint after connect+listen
  190. // (used in multipoint root cases)
  191. #define AfdBlockTypeHelper 0xAAFD // Regular helper endpoint
  192. #define AfdBlockTypeSanHelper 0x0AFD // SAN helper endpoint
  193. #define AfdBlockTypeSanEndpoint 0x1AFD // SAN endpoint
  194. #define AfdBlockTypeInvalidEndpoint 0xCAFD // Right before we call ExFreePool
  195. #define AfdBlockTypeConnection 0xAFD8 // Connection object
  196. #define AfdBlockTypeInvalidConnection 0xEAFD // Right before we call ExFreePool
  197. #if DBG
  198. #define IS_AFD_ENDPOINT_TYPE( endpoint ) \
  199. ( (endpoint)->Type == AfdBlockTypeEndpoint || \
  200. (endpoint)->Type == AfdBlockTypeDatagram || \
  201. (endpoint)->Type == AfdBlockTypeVcConnecting || \
  202. (endpoint)->Type == AfdBlockTypeVcListening || \
  203. (endpoint)->Type == AfdBlockTypeVcBoth || \
  204. (endpoint)->Type == AfdBlockTypeHelper || \
  205. (endpoint)->Type == AfdBlockTypeSanHelper || \
  206. (endpoint)->Type == AfdBlockTypeSanEndpoint )
  207. #endif
  208. enum {
  209. AfdConnectionStateFree = 0, // On free/AcceptEx/DelayedAccept list
  210. AfdConnectionStateUnaccepted = 1, // On unaccepted list
  211. AfdConnectionStateReturned = 2, // On returned list
  212. AfdConnectionStateConnected = 3, // Accepted or connected
  213. AfdConnectionStateClosing = 4 // Not used anymore
  214. };
  215. //
  216. // Flags that further qualify the state of the connection
  217. //
  218. typedef struct AFD_CONNECTION_STATE_FLAGS {
  219. union {
  220. struct {
  221. LOGICAL TdiBufferring:1, // (Does not really belon here)
  222. :3, // This spacing makes strcutures
  223. // much more readable (hex) in the
  224. // debugger and has no effect
  225. // on the generated code as long
  226. // as number of flags is less than
  227. // 8 (we still take up full 32 bits
  228. // because of aligment requiremens
  229. // of most other fields)
  230. Aborted:1,
  231. AbortIndicated:1,
  232. AbortFailed:1,
  233. :1,
  234. DisconnectIndicated:1,
  235. :3,
  236. ConnectedReferenceAdded:1,
  237. :3,
  238. SpecialCondition:1,
  239. :3,
  240. CleanupBegun:1,
  241. :3,
  242. ClosePendedTransmit:1,
  243. :3,
  244. OnLRList:1, // Low-resource list
  245. SanConnection:1,
  246. RcvInitiated:1, // AFD initiated receive to transport.
  247. :1;
  248. };
  249. LOGICAL ConnectionStateFlags;
  250. };
  251. } AFD_CONNECTION_STATE_FLAGS;
  252. C_ASSERT (sizeof (AFD_CONNECTION_STATE_FLAGS)==sizeof (LOGICAL));
  253. struct _AFD_CONNECTION {
  254. // *** Frequently used, mostly read-only fields (state/type/flag changes are rare).
  255. USHORT Type;
  256. USHORT State;
  257. AFD_CONNECTION_STATE_FLAGS
  258. #ifdef __cplusplus
  259. StateFlags
  260. #endif
  261. ;
  262. PAFD_ENDPOINT Endpoint;
  263. PFILE_OBJECT FileObject;
  264. PDEVICE_OBJECT DeviceObject;
  265. PEPROCESS OwningProcess;
  266. union {
  267. LONGLONG ConnectTime; // After connection is accepted.
  268. PIRP AcceptIrp; // For AcceptEx
  269. PIRP ListenIrp; // For delayed accept
  270. PIRP ConnectIrp; // for SAN
  271. };
  272. // *** Frequently used volatile fields.
  273. volatile LONG ReferenceCount;
  274. union {
  275. struct {
  276. LARGE_INTEGER ReceiveBytesIndicated;
  277. LARGE_INTEGER ReceiveBytesTaken;
  278. LARGE_INTEGER ReceiveBytesOutstanding;
  279. LARGE_INTEGER ReceiveExpeditedBytesIndicated;
  280. LARGE_INTEGER ReceiveExpeditedBytesTaken;
  281. LARGE_INTEGER ReceiveExpeditedBytesOutstanding;
  282. BOOLEAN NonBlockingSendPossible;
  283. BOOLEAN ZeroByteReceiveIndicated;
  284. } Bufferring;
  285. struct {
  286. LIST_ENTRY ReceiveIrpListHead;
  287. LIST_ENTRY ReceiveBufferListHead;
  288. ULONG BufferredReceiveBytes;
  289. ULONG BufferredExpeditedBytes;
  290. USHORT BufferredReceiveCount;
  291. USHORT BufferredExpeditedCount;
  292. ULONG ReceiveBytesInTransport;
  293. LIST_ENTRY SendIrpListHead;
  294. ULONG BufferredSendBytes;
  295. ULONG BufferredSendCount;
  296. PIRP DisconnectIrp;
  297. LONG ReceiveIrpsInTransport; // debug only.
  298. } NonBufferring;
  299. } Common;
  300. ULONG MaxBufferredReceiveBytes;
  301. ULONG MaxBufferredSendBytes;
  302. PTRANSPORT_ADDRESS RemoteAddress;
  303. ULONG RemoteAddressLength;
  304. LONG Sequence;
  305. HANDLE Handle; // Ref count protection
  306. union {
  307. AFD_WORK_ITEM WorkItem; // Work item to free the connection
  308. // Connection has to be at ref 0 to be
  309. // on the work queue, so it cannot be
  310. // on the lists below or being disconnected
  311. // because when on any of these lists the
  312. // ref count is above 0.
  313. struct {
  314. union {
  315. AFD_DISCONNECT_CONTEXT DisconnectContext;
  316. // Disconnect operation context, we cannot be
  317. // on the listening endpoint list
  318. SLIST_ENTRY SListEntry;
  319. // Links for listening endpoint lists
  320. LIST_ENTRY ListEntry;
  321. };
  322. AFD_LR_LIST_ITEM LRListItem; // Link for low resource list. When on this
  323. // list connection is referenced, but it can
  324. // also be on the listening endpoint list or
  325. // in the process of disconnecting.
  326. };
  327. };
  328. PAFD_CONNECT_DATA_BUFFERS ConnectDataBuffers;
  329. #if REFERENCE_DEBUG
  330. LONG CurrentTimeHigh;
  331. volatile LONG CurrentReferenceSlot;
  332. AFD_REFERENCE_DEBUG ReferenceDebug[AFD_MAX_REF];
  333. #endif
  334. #ifdef _AFD_VERIFY_DATA_
  335. ULONGLONG VerifySequenceNumber;
  336. #endif // _AFD_VERIFY_DATA_
  337. };
  338. // Fields of the AFD_CONNECTION are protected by the endpoint
  339. // spinlock, except:
  340. // Type, FileObject, DeviceObject, OwningProcess, Handle which are
  341. // only set once and cleared when reference count goes to 0
  342. // Endpoint field itself (and thus the spinlock) can change though.
  343. // - it is NULL when connection is on listening endpoint backlog
  344. // and connection cannot be referenced outside of listening endpoint.
  345. // - when it is assigned to listening endpoint it cannot change outside
  346. // of listening endpoint spinlock
  347. // - when it is assigned to connecting/accepting endpoint, it cannot
  348. // change at all until reference count drops to 0 and
  349. // connection is again placed on listening endpoint backlog or
  350. // destroyed.
  351. // ReferenceCount only updated via interlocked operations.
  352. //
  353. #ifdef _AFD_VERIFY_DATA_
  354. VOID
  355. AfdVerifyBuffer (
  356. PAFD_CONNECTION Connection,
  357. PVOID Buffer,
  358. ULONG Length
  359. );
  360. VOID
  361. AfdVerifyMdl (
  362. PAFD_CONNECTION Connection,
  363. PMDL Mdl,
  364. ULONG Offset,
  365. ULONG Length
  366. );
  367. VOID
  368. AfdVerifyAddress (
  369. PAFD_CONNECTION Connection,
  370. PTRANSPORT_ADDRESS Address
  371. );
  372. #define AFD_VERIFY_BUFFER(_connection,_buffer,_length) \
  373. AfdVerifyBuffer(_connection,_buffer,_length)
  374. #define AFD_VERIFY_MDL(_connection,_mdl,_offset,_length) \
  375. AfdVerifyMdl(_connection,_mdl,_offset,_length)
  376. #define AFD_VERIFY_ADDRESS(_connection,_address) \
  377. AfdVerifyAddress(_connection,_address)
  378. #else
  379. #define AFD_VERIFY_BUFFER(_connection,_buffer,_length)
  380. #define AFD_VERIFY_MDL(_connection,_mdl,_offset,_length)
  381. #define AFD_VERIFY_ADDRESS(_connection,_address)
  382. #endif // _AFD_VERIFY_DATA_
  383. //
  384. // Some macros that make code more readable.
  385. //
  386. #define VcNonBlockingSendPossible Common.Bufferring.NonBlockingSendPossible
  387. #define VcZeroByteReceiveIndicated Common.Bufferring.ZeroByteReceiveIndicated
  388. #define VcReceiveIrpListHead Common.NonBufferring.ReceiveIrpListHead
  389. #define VcReceiveBufferListHead Common.NonBufferring.ReceiveBufferListHead
  390. #define VcSendIrpListHead Common.NonBufferring.SendIrpListHead
  391. #define VcBufferredReceiveBytes Common.NonBufferring.BufferredReceiveBytes
  392. #define VcBufferredExpeditedBytes Common.NonBufferring.BufferredExpeditedBytes
  393. #define VcBufferredReceiveCount Common.NonBufferring.BufferredReceiveCount
  394. #define VcBufferredExpeditedCount Common.NonBufferring.BufferredExpeditedCount
  395. #define VcReceiveBytesInTransport Common.NonBufferring.ReceiveBytesInTransport
  396. #if DBG
  397. #define VcReceiveIrpsInTransport Common.NonBufferring.ReceiveIrpsInTransport
  398. #endif
  399. #define VcBufferredSendBytes Common.NonBufferring.BufferredSendBytes
  400. #define VcBufferredSendCount Common.NonBufferring.BufferredSendCount
  401. #define VcDisconnectIrp Common.NonBufferring.DisconnectIrp
  402. //
  403. // Information stored about each transport device name for which there
  404. // is an open endpoint.
  405. //
  406. typedef
  407. NTSTATUS
  408. (FASTCALL *PIO_CALL_DRIVER) (
  409. IN PDEVICE_OBJECT DeviceObject,
  410. IN PIRP Irp
  411. );
  412. typedef
  413. PAFD_BUFFER
  414. (FASTCALL *PAFD_GET_BUFFER) (
  415. IN ULONG BufferDataSize,
  416. IN ULONG AddressSize,
  417. IN PEPROCESS Process
  418. );
  419. typedef
  420. PAFD_TPACKETS_INFO_INTERNAL
  421. (FASTCALL *PAFD_GET_TPINFO) (
  422. IN ULONG ElementCount
  423. );
  424. typedef struct _AFD_TRANSPORT_INFO {
  425. LIST_ENTRY TransportInfoListEntry;
  426. volatile LONG ReferenceCount;
  427. BOOLEAN InfoValid;
  428. #ifdef _AFD_VARIABLE_STACK_
  429. CCHAR StackSize;
  430. PAFD_GET_BUFFER GetBuffer;
  431. PAFD_GET_TPINFO GetTpInfo;
  432. PIO_CALL_DRIVER CallDriver;
  433. #endif // _AFD_VARIABLE_STACK_
  434. UNICODE_STRING TransportDeviceName;
  435. TDI_PROVIDER_INFO ProviderInfo;
  436. //WCHAR TransportDeviceNameStructure;
  437. } AFD_TRANSPORT_INFO, *PAFD_TRANSPORT_INFO;
  438. //
  439. // Endpoint state definitions (can't be <=0 or state change
  440. // macros won't work correctly).
  441. //
  442. enum {
  443. AfdEndpointStateOpen =1, // Socket created but no yet bound
  444. AfdEndpointStateBound =2,
  445. AfdEndpointStateConnected =3,
  446. AfdEndpointStateCleanup =4, // Not used anymore
  447. AfdEndpointStateClosing =5,
  448. AfdEndpointStateTransmitClosing =6, // TransmitFile with reuse
  449. AfdEndpointStateInvalid =7 // Helper endpoints
  450. };
  451. //
  452. // Flags that further qualify the state of the endpoint
  453. //
  454. typedef struct AFD_ENDPOINT_STATE_FLAGS {
  455. union {
  456. struct {
  457. LOGICAL Listening:1,
  458. DelayedAcceptance:1,
  459. :2, // This spacing makes strcutures
  460. // much more readable (hex) in the
  461. // debugger and has no effect
  462. // on the generated code as long
  463. // as number of flags is less than
  464. // 8 (we still take up full 32 bits
  465. // because of aligment requiremens
  466. // of most other fields)
  467. NonBlocking:1,
  468. :3,
  469. InLine:1,
  470. :3,
  471. EndpointCleanedUp:1,
  472. :3,
  473. PollCalled:1,
  474. :3,
  475. RoutingQueryReferenced:1,
  476. RoutingQueryIPv6:1,
  477. :2,
  478. DisableFastIoSend:1,
  479. EnableSendEvent:1,
  480. :2,
  481. DisableFastIoRecv:1,
  482. :3;
  483. };
  484. LOGICAL EndpointStateFlags;
  485. };
  486. } AFD_ENDPOINT_STATE_FLAGS;
  487. C_ASSERT (sizeof (AFD_ENDPOINT_STATE_FLAGS)==sizeof (LOGICAL));
  488. struct _AFD_ENDPOINT {
  489. // *** Frequently used, mostly read-only fields (state/type/flag changes are rare).
  490. USHORT Type;
  491. UCHAR State;
  492. BOOLEAN AdminAccessGranted;
  493. ULONG TdiServiceFlags; // Tdi transport flags cached for quick access.
  494. AFD_ENDPOINT_FLAGS __f; // As requested by the application through the
  495. // Winsock2 provider flags and/or socket type
  496. AFD_ENDPOINT_STATE_FLAGS
  497. #ifdef __cplusplus
  498. StateFlags
  499. #endif
  500. ;
  501. PFILE_OBJECT AddressFileObject;
  502. union {
  503. PDEVICE_OBJECT AddressDeviceObject;
  504. PSECURITY_DESCRIPTOR SecurityDescriptor; // Only
  505. };
  506. PEPROCESS OwningProcess;
  507. // *** Frequently used volatile fields.
  508. AFD_QSPIN_LOCK SpinLock; // Pointer sized.
  509. volatile LONG ReferenceCount;
  510. ULONG EventsActive;
  511. //
  512. // Use a union to overlap the fields that are exclusive to datagram
  513. // connecting, or listening endpoints. Since many fields are
  514. // relevant to only one type of socket, it makes no sense to
  515. // maintain the fields for all sockets--instead, save some nonpaged
  516. // pool by combining them.
  517. //
  518. union {
  519. //
  520. // Information for circuit-based endpoints
  521. //
  522. struct {
  523. union {
  524. struct {
  525. // These members are valid for listening endpoints
  526. // (AfdBlockTypeVcListening).
  527. LIST_ENTRY UnacceptedConnectionListHead;
  528. LIST_ENTRY ReturnedConnectionListHead;
  529. LIST_ENTRY ListeningIrpListHead;
  530. // The below lists have their own lock which gets
  531. // used on the machines that do not support 64-bit
  532. // interlocked compare and exchange. On these machines
  533. // using endpoint spinlock to synchronize causes all kinds
  534. // of nasty deadlock conditions.
  535. union {
  536. LIST_ENTRY ListenConnectionListHead; // Delayed accept
  537. SLIST_HEADER FreeConnectionListHead;
  538. };
  539. SLIST_HEADER PreacceptedConnectionsListHead;
  540. LONG FailedConnectionAdds;
  541. LONG TdiAcceptPendingCount;
  542. LONG Sequence;
  543. BOOLEAN EnableDynamicBacklog;
  544. BOOLEAN BacklogReplenishActive; // Worker is scheduled
  545. USHORT MaxExtraConnections; // Extra connections we keep in the free queue
  546. // based on maximum number of AcceptEx requests
  547. } Listening;
  548. struct {
  549. KAPC Apc;
  550. USHORT RemoteSocketAddressOffset; // Offset inside of socket context
  551. // pointing to remote address.
  552. USHORT RemoteSocketAddressLength; // Length of the address.
  553. #ifndef i386
  554. BOOLEAN FixAddressAlignment; // Fix address alignment in
  555. // SuperAccept
  556. #endif
  557. };
  558. };
  559. // These members are valid for all vc endpoints (but
  560. // can be NULL)
  561. PAFD_CONNECTION Connection;
  562. struct _AFD_ENDPOINT *ListenEndpoint;
  563. PAFD_CONNECT_DATA_BUFFERS ConnectDataBuffers;
  564. } VirtualCircuit;
  565. #define VcConnecting VirtualCircuit
  566. #define VcListening VirtualCircuit.Listening
  567. #define VcConnection VirtualCircuit.Connection
  568. //
  569. // Information for datagram endpoints. Note that different
  570. // information is kept depending on whether the underlying
  571. // transport buffers internally.
  572. //
  573. struct {
  574. LIST_ENTRY ReceiveIrpListHead;
  575. LIST_ENTRY PeekIrpListHead;
  576. LIST_ENTRY ReceiveBufferListHead;
  577. ULONG BufferredReceiveBytes;
  578. ULONG BufferredReceiveCount;
  579. ULONG MaxBufferredReceiveBytes;
  580. ULONG BufferredSendBytes;
  581. ULONG MaxBufferredSendBytes;
  582. ULONG RemoteAddressLength;
  583. PTRANSPORT_ADDRESS RemoteAddress;
  584. union {
  585. struct {
  586. LOGICAL CircularQueueing:1,
  587. :3,
  588. HalfConnect:1,
  589. :3,
  590. DisablePUError:1,
  591. :3,
  592. AddressDrop:1,
  593. ResourceDrop:1,
  594. BufferDrop:1,
  595. ErrorDrop:1;
  596. };
  597. LOGICAL Flags;
  598. };
  599. } Datagram;
  600. struct {
  601. LIST_ENTRY SanListLink;
  602. PVOID IoCompletionPort;
  603. PKEVENT IoCompletionEvent;
  604. LONG Plsn; // Provider list sequence number
  605. LONG PendingRequests; // Number of pending requests to this process
  606. } SanHlpr;
  607. struct {
  608. struct _AFD_ENDPOINT *SanHlpr;
  609. PFILE_OBJECT FileObject;
  610. union {
  611. //
  612. // We can only have either one of two at any given time.
  613. //
  614. PAFD_SWITCH_CONTEXT SwitchContext;
  615. PVOID SavedContext;
  616. };
  617. PAFD_SWITCH_CONTEXT LocalContext;
  618. LIST_ENTRY IrpList;
  619. ULONG SavedContextLength;
  620. ULONG RequestId;
  621. ULONG SelectEventsActive;
  622. NTSTATUS CtxTransferStatus;
  623. BOOLEAN ImplicitDup; // Dup-ed into another process without
  624. // explicit request from the applicaiton
  625. } SanEndp;
  626. } Common;
  627. volatile PVOID Context;
  628. ULONG ContextLength;
  629. ULONG LocalAddressLength;
  630. PTRANSPORT_ADDRESS LocalAddress;
  631. ULONG DisconnectMode;
  632. LONG OutstandingIrpCount;
  633. HANDLE AddressHandle; // TDI transport address object
  634. PAFD_TRANSPORT_INFO TransportInfo;
  635. LIST_ENTRY RoutingNotifications; // For non-blocking sockets
  636. LIST_ENTRY RequestList; // For misc requests
  637. LIST_ENTRY GlobalEndpointListEntry;
  638. AFD_WORK_ITEM WorkItem;
  639. PIRP Irp; // AcceptEx or TransmitPackets IRP
  640. //
  641. // Non-zero when state change such as binding, accepting,
  642. // conntecting, and transmit file are in progress.
  643. LONG StateChangeInProgress;
  644. //
  645. // EventSelect info.
  646. //
  647. ULONG EventsEnabled;
  648. NTSTATUS EventStatus[AFD_NUM_POLL_EVENTS]; // Currently 13 events
  649. PKEVENT EventObject;
  650. //
  651. // Socket grouping.
  652. //
  653. LONG GroupID;
  654. AFD_GROUP_TYPE GroupType;
  655. LIST_ENTRY ConstrainedEndpointListEntry;
  656. //
  657. // Debug stuff.
  658. //
  659. #if REFERENCE_DEBUG
  660. LONG CurrentTimeHigh;
  661. LONG CurrentReferenceSlot;
  662. AFD_REFERENCE_DEBUG ReferenceDebug[AFD_MAX_REF];
  663. #endif
  664. #if DBG
  665. LIST_ENTRY OutstandingIrpListHead;
  666. LONG ObReferenceBias;
  667. #endif
  668. };
  669. // Fields AFD_ENDPOINT structure are protected by the embedded
  670. // spinlock, except:
  671. // AdminAccessGranted, TdiServiceFlags, __f, OwningProcess, TransportInfo,
  672. // IoCompletionPort, IoCompletionEvent, AddressHandle which are
  673. // set once and are not touched until reference count goes to 0
  674. // Type, State, LocalAddress, LocalAddressLength, AddressFileObject,
  675. // AddressDeviceObject, AddressHandle, TdiServiceFlags are protected by the
  676. // StateChange interlocked mutex (AddressHandle and TdiServiceFlags can only be set
  677. // once under the mutex).
  678. // AddressFileObject,AddressDeviceObject,LocalAddress, LocalAddressLength can only be
  679. // reset to NULL under the endpoint spinlock in case of TransmitFile (REUSE) on
  680. // accepting endpoint (StateChange protection still applies).
  681. // Counters: ReferenceCount, FailedConnectionAdds, TdiAcceptPendingCount,
  682. // Sequence, PendingRequests, SelectEventsActive are accessed with interlocked operations.
  683. // Context, ContextLength, SwitchContext, SavedContext, LocalContext,
  684. // SavedContextLength, RemoveSocketAddressOffset, RemoteSocketAddressLength
  685. // are protected by the context lock (AfdLockContext).
  686. typedef struct _AFD_POLL_ENDPOINT_INFO {
  687. PAFD_ENDPOINT Endpoint;
  688. PFILE_OBJECT FileObject;
  689. HANDLE Handle;
  690. ULONG PollEvents;
  691. } AFD_POLL_ENDPOINT_INFO, *PAFD_POLL_ENDPOINT_INFO;
  692. typedef struct _AFD_POLL_INFO_INTERNAL {
  693. LIST_ENTRY PollListEntry;
  694. ULONG NumberOfEndpoints;
  695. PIRP Irp;
  696. union {
  697. struct {
  698. KDPC Dpc;
  699. KTIMER Timer;
  700. };
  701. KAPC Apc; // for SAN
  702. };
  703. BOOLEAN Unique;
  704. BOOLEAN TimerStarted;
  705. BOOLEAN SanPoll;
  706. AFD_POLL_ENDPOINT_INFO EndpointInfo[1];
  707. } AFD_POLL_INFO_INTERNAL, *PAFD_POLL_INFO_INTERNAL;
  708. //
  709. // A couple of useful manifests that make code more readable.
  710. //
  711. #define ReceiveDatagramIrpListHead Common.Datagram.ReceiveIrpListHead
  712. #define PeekDatagramIrpListHead Common.Datagram.PeekIrpListHead
  713. #define ReceiveDatagramBufferListHead Common.Datagram.ReceiveBufferListHead
  714. #define DgBufferredReceiveCount Common.Datagram.BufferredReceiveCount
  715. #define DgBufferredReceiveBytes Common.Datagram.BufferredReceiveBytes
  716. #define DgBufferredSendBytes Common.Datagram.BufferredSendBytes
  717. #define AFD_CONNECTION_FROM_ENDPOINT( endpoint ) ( \
  718. (((endpoint)->Type & AfdBlockTypeVcConnecting)==AfdBlockTypeVcConnecting) \
  719. ? (endpoint)->Common.VirtualCircuit.Connection \
  720. : (PAFD_CONNECTION)NULL \
  721. )
  722. //
  723. // A structure which describes buffers used by AFD to perform bufferring
  724. // for TDI providers which do not perform internal bufferring.
  725. // It is also used in other code path as buffer descriptors.
  726. //
  727. typedef struct _AFD_BUFFER_HEADER AFD_BUFFER_HEADER, *PAFD_BUFFER_HEADER;
  728. #define _AFD_BUFFER_HEADER_ \
  729. union { \
  730. TDI_CONNECTION_INFORMATION TdiInfo; /*holds info for TDI requests */ \
  731. /*with remote address */ \
  732. struct { \
  733. union { /* Links */ \
  734. struct { \
  735. union { \
  736. SINGLE_LIST_ENTRY SList; /* for buffer lookaside lists */ \
  737. PAFD_BUFFER_HEADER Next; /* for transmit packet lists */ \
  738. }; \
  739. PFILE_OBJECT FileObject; /* for cached file in transmit file */ \
  740. }; \
  741. LIST_ENTRY BufferListEntry; /* for endpoint/connection lists */ \
  742. }; \
  743. union { \
  744. struct { \
  745. ULONG DataOffset; /* offset in buffer to start of unread data*/\
  746. union { \
  747. ULONG DatagramFlags;/* flags for datagrams with control info */\
  748. LONG RefCount; /* Permit partial copy outside the lock*/ \
  749. }; \
  750. }; \
  751. LARGE_INTEGER FileOffset;/* data offset from the start of the file */\
  752. }; \
  753. UCHAR _Test; /* used to test relative field pos in the union */ \
  754. }; \
  755. }; \
  756. union { \
  757. PVOID Context; /* stores context info (endp/conn/etc)*/ \
  758. NTSTATUS Status;/* stores status of completed operation */ \
  759. }; \
  760. PMDL Mdl; /* pointer to an MDL describing the buffer*/ \
  761. ULONG DataLength; /* actual data in the buffer */ \
  762. ULONG BufferLength; /* amount of space allocated for the buffer */\
  763. union { \
  764. struct { \
  765. /* Flags that describe data in the buffer */ \
  766. UCHAR ExpeditedData:1, /* The buffer contains expedited data*/ \
  767. :3, \
  768. PartialMessage:1,/* This is a partial message*/ \
  769. :3; \
  770. /* Flags that keep allocation information */ \
  771. UCHAR NdisPacket:1, /* Context is a packet to return to NDIS/TDI*/\
  772. :3, \
  773. Placement:2, /* Relative placement of the pieces */ \
  774. AlignmentAdjusted:1, /* MM block alignment was adjusted to */ \
  775. /* meet AFD buffer alignment requirement */ \
  776. Lookaside:1; /* Poped from Slist (no quota charge)*/ \
  777. }; \
  778. USHORT Flags; \
  779. }; \
  780. USHORT AllocatedAddressLength/* length allocated for address */ \
  781. struct _AFD_BUFFER_HEADER {
  782. _AFD_BUFFER_HEADER_ ;
  783. };
  784. //
  785. // The buffer management code makes the following assumptions
  786. // about the union at the top the buffer header so that list
  787. // links and DataOffset field are not in conflict with
  788. // RemoteAddress fields of the TDI_CONNECTION_INFORMATION.
  789. //
  790. C_ASSERT (FIELD_OFFSET (AFD_BUFFER_HEADER, TdiInfo.RemoteAddress) >=
  791. FIELD_OFFSET (AFD_BUFFER_HEADER, _Test));
  792. C_ASSERT (FIELD_OFFSET (AFD_BUFFER_HEADER, TdiInfo.RemoteAddressLength)>=
  793. FIELD_OFFSET (AFD_BUFFER_HEADER, _Test));
  794. C_ASSERT(FIELD_OFFSET (AFD_BUFFER_HEADER, AllocatedAddressLength)==
  795. FIELD_OFFSET(AFD_BUFFER_HEADER, Flags)+sizeof (USHORT));
  796. typedef struct AFD_BUFFER_TAG {
  797. union {
  798. struct {
  799. _AFD_BUFFER_HEADER_; // easy access to individual members
  800. };
  801. AFD_BUFFER_HEADER Header; // access to the header as a whole
  802. };
  803. #if DBG
  804. PVOID Caller;
  805. PVOID CallersCaller;
  806. #endif
  807. // UCHAR Address[]; // address of datagram sender
  808. } AFD_BUFFER_TAG, *PAFD_BUFFER_TAG;
  809. struct _AFD_BUFFER {
  810. union {
  811. struct {
  812. _AFD_BUFFER_HEADER_; // easy access to individual members
  813. };
  814. AFD_BUFFER_HEADER Header; // access to the header as a whole
  815. };
  816. PIRP Irp; // pointer to the IRP associated w/the buffer
  817. PVOID Buffer; // a pointer to the actual data buffer
  818. #if DBG
  819. LIST_ENTRY DebugListEntry;
  820. PVOID Caller;
  821. PVOID CallersCaller;
  822. #endif
  823. // IRP Irp; // the IRP follows this structure
  824. // MDL Mdl; // the MDL follows the IRP
  825. // UCHAR Address[]; // address of datagram sender
  826. // UCHAR Buffer[BufferLength]; // the actual data buffer is last
  827. } ;
  828. //
  829. // Placement of pieces that comprise the AFD_BUFFER.
  830. // We have four pieces: header, IRP, MDL, data buffer
  831. // and use 2 bits to encode each.
  832. // We need to save the first piece so we know where the memory block
  833. // starts when we need to return it to the memory manager.
  834. //
  835. enum {
  836. AFD_PLACEMENT_HDR =0,
  837. AFD_PLACEMENT_IRP =1,
  838. AFD_PLACEMENT_MDL =2,
  839. AFD_PLACEMENT_BUFFER =3,
  840. AFD_PLACEMENT_HDR_IRP =(AFD_PLACEMENT_HDR|(AFD_PLACEMENT_IRP<<2)),
  841. AFD_PLACEMENT_HDR_MDL =(AFD_PLACEMENT_HDR|(AFD_PLACEMENT_MDL<<2)),
  842. AFD_PLACEMENT_IRP_MDL =(AFD_PLACEMENT_IRP|(AFD_PLACEMENT_MDL<<2)),
  843. AFD_PLACEMENT_HDR_IRP_MDL=(AFD_PLACEMENT_HDR|(AFD_PLACEMENT_IRP<<2)|(AFD_PLACEMENT_MDL<<4))
  844. };
  845. //
  846. // ALIGN_DOWN_A aligns to given alignment requirement
  847. // (as opposed to the type in the original ALIGN_DOWN macro)
  848. //
  849. #define ALIGN_DOWN_A(length,alignment) \
  850. (((ULONG)(length)) & ~ ((alignment)-1))
  851. //
  852. // ALIGN_DOWN_A for pointers.
  853. //
  854. #define ALIGN_DOWN_A_POINTER(address,alignment) \
  855. ((PVOID)(((ULONG_PTR)(address)) & ~ ((ULONG_PTR)(alignment)-1)))
  856. //
  857. // ALIGN_UP_A aligns to given alignment requirement
  858. // (as opposed to the type in the original ALIGN_UP macro)
  859. //
  860. #define ALIGN_UP_A(length,alignment) \
  861. ((((ULONG)(length)) + (alignment)-1) & ~ ((alignment)-1))
  862. //
  863. // ALIGN_UP_A for pointers.
  864. //
  865. #define ALIGN_UP_A_POINTER(address,alignment) \
  866. ALIGN_DOWN_A_POINTER(((ULONG_PTR)(address) + alignment-1), alignment)
  867. //
  868. // ALIGN_UP_TO_TYPE aligns size to make sure it meets
  869. // the type alignment requirement
  870. //
  871. #define ALIGN_UP_TO_TYPE(length,type) \
  872. ALIGN_UP_A(length,TYPE_ALIGNMENT(type))
  873. //
  874. // ALIGN_UP_TO_TYPE for pointers.
  875. //
  876. #define ALIGN_UP_TO_TYPE_POINTER(address,type) \
  877. ALIGN_UP_A_POINTER(address,TYPE_ALIGNMENT(type))
  878. #if DBG
  879. #define IS_VALID_AFD_BUFFER(b) ( \
  880. ((b)->Placement==AFD_PLACEMENT_HDR) \
  881. ? ((PUCHAR)b<(PUCHAR)(b)->Buffer && (PUCHAR)b<(PUCHAR)(b)->Mdl && (PUCHAR)b<(PUCHAR)(b)->Irp) \
  882. : (((b)->Placement==AFD_PLACEMENT_MDL) \
  883. ? ((PUCHAR)(b)->Mdl<(PUCHAR)(b)->Buffer && (PUCHAR)(b)->Mdl<(PUCHAR)b && (PUCHAR)(b)->Mdl<(PUCHAR)(b)->Irp) \
  884. : ((b->Placement==AFD_PLACEMENT_IRP) \
  885. ? ((PUCHAR)(b)->Irp<(PUCHAR)(b)->Buffer && (PUCHAR)(b)->Irp<(PUCHAR)b && (PUCHAR)(b)->Irp<(PUCHAR)(b)->Mdl) \
  886. : ((PUCHAR)(b)->Buffer<(PUCHAR)(b)->Irp && (PUCHAR)(b)->Buffer<(PUCHAR)b && (PUCHAR)(b)->Buffer<(PUCHAR)(b)->Mdl)) \
  887. ) \
  888. ) \
  889. #endif
  890. //
  891. // Pointer to an IRP cleanup routine. This is used as a parameter to
  892. // AfdCompleteIrpList().
  893. //
  894. typedef
  895. BOOLEAN
  896. (NTAPI * PAFD_IRP_CLEANUP_ROUTINE)(
  897. IN PIRP Irp
  898. );
  899. //
  900. // Debug statistics.
  901. //
  902. typedef struct _AFD_QUOTA_STATS {
  903. LARGE_INTEGER Charged;
  904. LARGE_INTEGER Returned;
  905. } AFD_QUOTA_STATS;
  906. typedef struct _AFD_HANDLE_STATS {
  907. LONG AddrOpened;
  908. LONG AddrClosed;
  909. LONG AddrRef;
  910. LONG AddrDeref;
  911. LONG ConnOpened;
  912. LONG ConnClosed;
  913. LONG ConnRef;
  914. LONG ConnDeref;
  915. LONG FileRef;
  916. LONG FileDeref;
  917. } AFD_HANDLE_STATS;
  918. typedef struct _AFD_QUEUE_STATS {
  919. LONG AfdWorkItemsQueued;
  920. LONG ExWorkItemsQueued;
  921. LONG WorkerEnter;
  922. LONG WorkerLeave;
  923. LONG AfdWorkItemsProcessed;
  924. PETHREAD AfdWorkerThread;
  925. } AFD_QUEUE_STATS;
  926. typedef struct _AFD_CONNECTION_STATS {
  927. LONG ConnectedReferencesAdded;
  928. LONG ConnectedReferencesDeleted;
  929. LONG GracefulDisconnectsInitiated;
  930. LONG GracefulDisconnectsCompleted;
  931. LONG GracefulDisconnectIndications;
  932. LONG AbortiveDisconnectsInitiated;
  933. LONG AbortiveDisconnectsCompleted;
  934. LONG AbortiveDisconnectIndications;
  935. LONG ConnectionIndications;
  936. LONG ConnectionsDropped;
  937. LONG ConnectionsAccepted;
  938. LONG ConnectionsPreaccepted;
  939. LONG ConnectionsReused;
  940. LONG EndpointsReused;
  941. } AFD_CONNECTION_STATS;
  942. //
  943. // Global data. Resouces and lookaside list descriptors
  944. // cannot be statically allocated, as they need to ALWAYS be nonpageable,
  945. // even when the entire driver is paged out.
  946. // Alignment table is variable-size and also cannot be statically allocated.
  947. //
  948. enum {
  949. AFD_LARGE_BUFFER_LIST=0,
  950. AFD_MEDIUM_BUFFER_LIST,
  951. AFD_SMALL_BUFFER_LIST,
  952. AFD_BUFFER_TAG_LIST,
  953. AFD_TP_INFO_LIST,
  954. AFD_REMOTE_ADDR_LIST,
  955. AFD_NUM_LOOKASIDE_LISTS
  956. } AFD_LOOKASIDE_LISTS_INDEX;
  957. typedef struct _AFD_GLOBAL_DATA {
  958. ERESOURCE Resource;
  959. NPAGED_LOOKASIDE_LIST List[AFD_NUM_LOOKASIDE_LISTS];
  960. #define LargeBufferList List[AFD_LARGE_BUFFER_LIST]
  961. #define MediumBufferList List[AFD_MEDIUM_BUFFER_LIST]
  962. #define SmallBufferList List[AFD_SMALL_BUFFER_LIST]
  963. #define BufferTagList List[AFD_BUFFER_TAG_LIST]
  964. #define TpInfoList List[AFD_TP_INFO_LIST]
  965. #define RemoteAddrList List[AFD_REMOTE_ADDR_LIST]
  966. LONG TrimFlags;
  967. KTIMER Timer;
  968. KDPC Dpc;
  969. UCHAR BufferAlignmentTable[ANYSIZE_ARRAY];
  970. } AFD_GLOBAL_DATA, *PAFD_GLOBAL_DATA;
  971. //
  972. // Context structure for misc requests pended in AFD.
  973. //
  974. typedef struct _AFD_REQUEST_CONTEXT AFD_REQUEST_CONTEXT, *PAFD_REQUEST_CONTEXT;
  975. //
  976. // The routine is called after request is removed from endpoint list
  977. // for cleanup purposes
  978. //
  979. typedef BOOLEAN (* PAFD_REQUEST_CLEANUP) (
  980. PAFD_ENDPOINT Endpoint,
  981. PAFD_REQUEST_CONTEXT NotifyCtx
  982. );
  983. //
  984. // This structure has to no more 16 bytes long so we can
  985. // reuse IrpSp->Parameters for it.
  986. //
  987. struct _AFD_REQUEST_CONTEXT {
  988. LIST_ENTRY EndpointListLink; // Link in endpoint list
  989. PAFD_REQUEST_CLEANUP CleanupRoutine; // Routine to call to cancel
  990. PVOID Context; // Request dependent context
  991. // (PIRP)
  992. };
  993. //
  994. // We use list entry fields to synchronize completion with cleanup/cancel
  995. // routine assuming that as long as the entry is in the list
  996. // both Flink and Blink fields cannot be NULL. (using these
  997. // fields for synchronization allows us to cut down on
  998. // cancel spinlock usage)
  999. //
  1000. #define AfdEnqueueRequest(Endpoint,Request) \
  1001. ExInterlockedInsertTailList(&(Endpoint)->RequestList, \
  1002. &(Request)->EndpointListLink, \
  1003. &(Endpoint)->SpinLock)
  1004. #define AfdIsRequestInQueue(Request) \
  1005. ((Request)->EndpointListLink.Flink!=NULL)
  1006. #define AfdMarkRequestCompleted(Request) \
  1007. (Request)->EndpointListLink.Blink = NULL
  1008. #define AfdIsRequestCompleted(Request) \
  1009. ((Request)->EndpointListLink.Blink==NULL)
  1010. typedef struct _ROUTING_NOTIFY {
  1011. LIST_ENTRY NotifyListLink;
  1012. PIRP NotifyIrp;
  1013. PVOID NotifyContext;
  1014. } ROUTING_NOTIFY, *PROUTING_NOTIFY;
  1015. typedef struct _AFD_ADDRESS_ENTRY {
  1016. LIST_ENTRY AddressListLink;
  1017. UNICODE_STRING DeviceName;
  1018. TA_ADDRESS Address;
  1019. } AFD_ADDRESS_ENTRY, *PAFD_ADDRESS_ENTRY;
  1020. typedef struct _AFD_ADDRESS_CHANGE {
  1021. LIST_ENTRY ChangeListLink;
  1022. union {
  1023. PAFD_ENDPOINT Endpoint;
  1024. PIRP Irp;
  1025. };
  1026. USHORT AddressType;
  1027. BOOLEAN NonBlocking;
  1028. } AFD_ADDRESS_CHANGE, *PAFD_ADDRESS_CHANGE;
  1029. typedef
  1030. NTSTATUS
  1031. (* PAFD_IMMEDIATE_CALL) (
  1032. IN PFILE_OBJECT FileObject,
  1033. IN ULONG IoctlCode,
  1034. IN KPROCESSOR_MODE RequestorMode,
  1035. IN PVOID InputBuffer,
  1036. IN ULONG InputBufferLength,
  1037. IN PVOID OutputBuffer,
  1038. IN ULONG OutputBufferLength,
  1039. OUT PULONG_PTR Information
  1040. );
  1041. typedef
  1042. NTSTATUS
  1043. (FASTCALL * PAFD_IRP_CALL) (
  1044. IN PIRP Irp,
  1045. IN PIO_STACK_LOCATION IrpSp
  1046. );
  1047. typedef struct _AFD_TRANSMIT_PACKETS_ELEMENT {
  1048. #define TP_MDL 0x80000000
  1049. #define TP_COMBINE 0x40000000
  1050. ULONG Flags;
  1051. ULONG Length;
  1052. union {
  1053. struct {
  1054. LARGE_INTEGER FileOffset;
  1055. PFILE_OBJECT FileObject;
  1056. };
  1057. struct {
  1058. PVOID Buffer;
  1059. PMDL Mdl;
  1060. };
  1061. };
  1062. } AFD_TRANSMIT_PACKETS_ELEMENT, *PAFD_TRANSMIT_PACKETS_ELEMENT;
  1063. //
  1064. // Structure to keep track of transmit packets request
  1065. //
  1066. struct _AFD_TPACKETS_INFO_INTERNAL {
  1067. union {
  1068. SINGLE_LIST_ENTRY SListEntry; // Link on S-List
  1069. PFILE_OBJECT TdiFileObject; // Tdi objects (sending to)
  1070. };
  1071. PDEVICE_OBJECT TdiDeviceObject;
  1072. PMDL HeadMdl; // Ready to send chain
  1073. PMDL *TailMdl;
  1074. PAFD_BUFFER_HEADER HeadPd; // Corresponding packet chain
  1075. PAFD_BUFFER_HEADER *TailPd;
  1076. PIRP ReadIrp; // Irp used for file reads.
  1077. PAFD_TRANSMIT_PACKETS_ELEMENT
  1078. ElementArray; // Packet array
  1079. ULONG NextElement; // Next element to send.
  1080. ULONG ElementCount; // Total number of elements in the array
  1081. ULONG RemainingPkts; // Number of packets remaining to be sent.
  1082. USHORT NumSendIrps; // Actual number of send IRPs
  1083. BOOLEAN ArrayAllocated; // Element array is allocated (not built-in).
  1084. BOOLEAN PdNeedsPps; // Packet descriptor being built needs post-
  1085. // processing after completion.
  1086. ULONG PdLength; // Currently accumulated send length
  1087. ULONG SendPacketLength; // Maximum length of the packet
  1088. // APC/Work item for worker scheduling
  1089. union {
  1090. KAPC Apc;
  1091. WORK_QUEUE_ITEM WorkItem;
  1092. };
  1093. #if REFERENCE_DEBUG
  1094. LONG CurrentTimeHigh;
  1095. LONG CurrentReferenceSlot;
  1096. AFD_REFERENCE_DEBUG ReferenceDebug[AFD_MAX_REF];
  1097. #endif
  1098. #if AFD_PERF_DBG
  1099. LONG WorkersExecuted;
  1100. #endif
  1101. #define AFD_TP_MIN_SEND_IRPS 2 // Need at least two to keep transport busy
  1102. #define AFD_TP_MAX_SEND_IRPS 8 // Max is based on current flags layout below
  1103. PIRP SendIrp[AFD_TP_MAX_SEND_IRPS];
  1104. // ElementArray
  1105. // SendIrp1
  1106. // SendIrp2
  1107. };
  1108. //
  1109. // Structure maintained in driver context of the TPackets IRP
  1110. //
  1111. typedef struct _AFD_TPACKETS_IRP_CTX AFD_TPACKETS_IRP_CTX, *PAFD_TPACKETS_IRP_CTX;
  1112. #define AFD_GET_TPIC(_i) ((PAFD_TPACKETS_IRP_CTX)&(_i)->Tail.Overlay.DriverContext)
  1113. struct _AFD_TPACKETS_IRP_CTX {
  1114. PAFD_TPACKETS_IRP_CTX Next; // Next TPackets IRP in the list
  1115. LONG Flags; // Application flags.
  1116. volatile LONG ReferenceCount; // IRP reference count
  1117. volatile LONG StateFlags; // TPackets state flags
  1118. };
  1119. #define AFD_GET_TPIRP(_i) CONTAINING_RECORD(_i,IRP,Tail.Overlay.DriverContext)
  1120. #define AFD_TP_ABORT_PENDING 0x00000001 // Request is being aborted
  1121. #define AFD_TP_WORKER_SCHEDULED 0x00000002 // Worker is scheduled or active
  1122. #define AFD_TP_SENDS_POSTED 0x00000010 // All sends have been posted.
  1123. #define AFD_TP_QUEUED 0x00000020 // Irp is in the queue.
  1124. #define AFD_TP_SEND 0x00000100 // This is a plain send in TP queue.
  1125. #define AFD_TP_AFD_SEND 0x00000200 // This is AFD send IRP.
  1126. #ifdef TDI_SERVICE_SEND_AND_DISCONNECT
  1127. #define AFD_TP_SEND_AND_DISCONNECT 0x00000400 // S&D is enabled
  1128. #endif // TDI_SERVICE_SEND_AND_DISCONNECT
  1129. #define AFD_TP_READ_CALL_PENDING 0x00001000 // MDL_READ call is imminent or in progress on ReadIrp
  1130. #define AFD_TP_READ_COMP_PENDING 0x00002000 // Read completion is expected on ReadIrp
  1131. #define AFD_TP_READ_BUSY (AFD_TP_READ_CALL_PENDING|AFD_TP_READ_COMP_PENDING)
  1132. // TDI_SEND call is imminent or in progress on send Irp i
  1133. #define AFD_TP_SEND_CALL_PENDING(i) (0x00010000<<((i)*2))
  1134. // Send completion is expected on send Irp i
  1135. #define AFD_TP_SEND_COMP_PENDING(i) (0x00020000<<((i)*2))
  1136. #define AFD_TP_SEND_BUSY(i) (0x00030000<<((i)*2))
  1137. #define AFD_TP_SEND_MASK (0x55550000)
  1138. #if DBG
  1139. //
  1140. // N.B. This structure MUST be alligned on memory allocation boundary
  1141. //
  1142. typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _AFD_POOL_HEADER {
  1143. SIZE_T Size;
  1144. PCHAR FileName;
  1145. ULONG LineNumber;
  1146. LONG InUse;
  1147. } AFD_POOL_HEADER, *PAFD_POOL_HEADER;
  1148. #define AFD_POOL_OVERHEAD (sizeof(AFD_POOL_HEADER))
  1149. #else
  1150. #define AFD_POOL_OVERHEAD 0
  1151. #endif
  1152. //
  1153. // This macro verifies that the 32-bit mapping of the structures in 64-bit
  1154. // compiler match original 32-bit structures. Note, that the verification is
  1155. // performed when this file is compiled by 32 bit compiler, but
  1156. // the actual structures are used by 64 bit code.
  1157. //
  1158. #ifdef _WIN64
  1159. #define AFD_CHECK32on64(_str,_fld)
  1160. #define AFD_MAX_NATURAL_ALIGNMENT32 sizeof(ULONG)
  1161. #else
  1162. #define AFD_CHECK32on64(_str,_fld) \
  1163. C_ASSERT (FIELD_OFFSET (_str,_fld)==FIELD_OFFSET(_str##32,_fld))
  1164. #endif
  1165. //
  1166. // Structures for mapping IOCTL parameters for 32-bit clients on 64-bit
  1167. // platform.
  1168. //
  1169. typedef UNALIGNED struct _WSABUF32 {
  1170. ULONG len;
  1171. AFD_POINTER_32 buf;
  1172. } WSABUF32, *LPWSABUF32;
  1173. AFD_CHECK32on64(WSABUF,len);
  1174. AFD_CHECK32on64(WSABUF,buf);
  1175. typedef UNALIGNED struct _QualityOfService32 {
  1176. FLOWSPEC SendingFlowspec; /* the flow spec for data sending */
  1177. FLOWSPEC ReceivingFlowspec; /* the flow spec for data receiving */
  1178. WSABUF32 ProviderSpecific; /* additional provider specific stuff */
  1179. } QOS32, * LPQOS32;
  1180. AFD_CHECK32on64(QOS,SendingFlowspec);
  1181. AFD_CHECK32on64(QOS,ReceivingFlowspec);
  1182. AFD_CHECK32on64(QOS,ProviderSpecific);
  1183. typedef UNALIGNED struct _AFD_ACCEPT_INFO32 {
  1184. BOOLEAN SanActive;
  1185. LONG Sequence;
  1186. VOID * POINTER_32 AcceptHandle;
  1187. } AFD_ACCEPT_INFO32, *PAFD_ACCEPT_INFO32;
  1188. AFD_CHECK32on64(AFD_ACCEPT_INFO,SanActive);
  1189. AFD_CHECK32on64(AFD_ACCEPT_INFO,Sequence);
  1190. AFD_CHECK32on64(AFD_ACCEPT_INFO,AcceptHandle);
  1191. typedef UNALIGNED struct _AFD_SUPER_ACCEPT_INFO32 {
  1192. BOOLEAN SanActive;
  1193. BOOLEAN FixAddressAlignment;
  1194. VOID * POINTER_32 AcceptHandle;
  1195. ULONG ReceiveDataLength;
  1196. ULONG LocalAddressLength;
  1197. ULONG RemoteAddressLength;
  1198. } AFD_SUPER_ACCEPT_INFO32, *PAFD_SUPER_ACCEPT_INFO32;
  1199. AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,SanActive);
  1200. AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,FixAddressAlignment);
  1201. AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,AcceptHandle);
  1202. AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,ReceiveDataLength);
  1203. AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,LocalAddressLength);
  1204. AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,RemoteAddressLength);
  1205. typedef UNALIGNED struct _AFD_POLL_HANDLE_INFO32 {
  1206. VOID * POINTER_32 Handle;
  1207. ULONG PollEvents;
  1208. NTSTATUS Status;
  1209. } AFD_POLL_HANDLE_INFO32, *PAFD_POLL_HANDLE_INFO32;
  1210. AFD_CHECK32on64(AFD_POLL_HANDLE_INFO,Handle);
  1211. AFD_CHECK32on64(AFD_POLL_HANDLE_INFO,PollEvents);
  1212. AFD_CHECK32on64(AFD_POLL_HANDLE_INFO,Status);
  1213. typedef UNALIGNED struct _AFD_POLL_INFO32 {
  1214. LARGE_INTEGER Timeout;
  1215. ULONG NumberOfHandles;
  1216. BOOLEAN Unique;
  1217. AFD_POLL_HANDLE_INFO32 Handles[1];
  1218. } AFD_POLL_INFO32, *PAFD_POLL_INFO32;
  1219. AFD_CHECK32on64(AFD_POLL_INFO,Timeout);
  1220. AFD_CHECK32on64(AFD_POLL_INFO,NumberOfHandles);
  1221. AFD_CHECK32on64(AFD_POLL_INFO,Unique);
  1222. AFD_CHECK32on64(AFD_POLL_INFO,Handles);
  1223. typedef UNALIGNED struct _AFD_HANDLE_INFO632 {
  1224. VOID * POINTER_32 TdiAddressHandle;
  1225. VOID * POINTER_32 TdiConnectionHandle;
  1226. } AFD_HANDLE_INFO32, *PAFD_HANDLE_INFO32;
  1227. AFD_CHECK32on64(AFD_HANDLE_INFO,TdiAddressHandle);
  1228. AFD_CHECK32on64(AFD_HANDLE_INFO,TdiConnectionHandle);
  1229. typedef UNALIGNED struct _AFD_TRANSMIT_FILE_INFO32 {
  1230. LARGE_INTEGER Offset;
  1231. LARGE_INTEGER WriteLength;
  1232. ULONG SendPacketLength;
  1233. VOID * POINTER_32 FileHandle;
  1234. AFD_POINTER_32 Head;
  1235. ULONG HeadLength;
  1236. AFD_POINTER_32 Tail;
  1237. ULONG TailLength;
  1238. ULONG Flags;
  1239. } AFD_TRANSMIT_FILE_INFO32, *PAFD_TRANSMIT_FILE_INFO32;
  1240. AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,Offset);
  1241. AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,WriteLength);
  1242. AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,SendPacketLength);
  1243. AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,FileHandle);
  1244. AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,Head);
  1245. AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,HeadLength);
  1246. AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,Tail);
  1247. AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,TailLength);
  1248. AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,Flags);
  1249. typedef UNALIGNED struct _AFD_SEND_INFO32 {
  1250. AFD_POINTER_32 BufferArray;
  1251. ULONG BufferCount;
  1252. ULONG AfdFlags;
  1253. ULONG TdiFlags;
  1254. } AFD_SEND_INFO32, *PAFD_SEND_INFO32;
  1255. AFD_CHECK32on64(AFD_SEND_INFO,BufferArray);
  1256. AFD_CHECK32on64(AFD_SEND_INFO,BufferCount);
  1257. AFD_CHECK32on64(AFD_SEND_INFO,AfdFlags);
  1258. AFD_CHECK32on64(AFD_SEND_INFO,TdiFlags);
  1259. typedef UNALIGNED struct _TDI_REQUEST32 {
  1260. union {
  1261. VOID * POINTER_32 AddressHandle;
  1262. VOID * POINTER_32 ConnectionContext;
  1263. VOID * POINTER_32 ControlChannel;
  1264. } Handle;
  1265. VOID * POINTER_32 RequestNotifyObject;
  1266. VOID * POINTER_32 RequestContext;
  1267. TDI_STATUS TdiStatus;
  1268. } TDI_REQUEST32, *PTDI_REQUEST32;
  1269. AFD_CHECK32on64(TDI_REQUEST,Handle);
  1270. AFD_CHECK32on64(TDI_REQUEST,RequestNotifyObject);
  1271. AFD_CHECK32on64(TDI_REQUEST,RequestContext);
  1272. AFD_CHECK32on64(TDI_REQUEST,TdiStatus);
  1273. typedef UNALIGNED struct _TDI_CONNECTION_INFORMATION32 {
  1274. LONG UserDataLength; // length of user data buffer
  1275. AFD_POINTER_32 UserData; // pointer to user data buffer
  1276. LONG OptionsLength; // length of follwoing buffer
  1277. AFD_POINTER_32 Options; // pointer to buffer containing options
  1278. LONG RemoteAddressLength; // length of following buffer
  1279. AFD_POINTER_32 RemoteAddress; // buffer containing the remote address
  1280. } TDI_CONNECTION_INFORMATION32, *PTDI_CONNECTION_INFORMATION32;
  1281. AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,UserDataLength);
  1282. AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,UserData);
  1283. AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,OptionsLength);
  1284. AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,Options);
  1285. AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,RemoteAddressLength);
  1286. AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,RemoteAddress);
  1287. typedef UNALIGNED struct _TDI_REQUEST_SEND_DATAGRAM32 {
  1288. TDI_REQUEST32 Request;
  1289. AFD_POINTER_32 SendDatagramInformation;
  1290. } TDI_REQUEST_SEND_DATAGRAM32, *PTDI_REQUEST_SEND_DATAGRAM32;
  1291. AFD_CHECK32on64(TDI_REQUEST_SEND_DATAGRAM,Request);
  1292. AFD_CHECK32on64(TDI_REQUEST_SEND_DATAGRAM,SendDatagramInformation);
  1293. typedef UNALIGNED struct _AFD_SEND_DATAGRAM_INFO32 {
  1294. AFD_POINTER_32 BufferArray;
  1295. ULONG BufferCount;
  1296. ULONG AfdFlags;
  1297. TDI_REQUEST_SEND_DATAGRAM32 TdiRequest;
  1298. TDI_CONNECTION_INFORMATION32 TdiConnInfo;
  1299. } AFD_SEND_DATAGRAM_INFO32, *PAFD_SEND_DATAGRAM_INFO32;
  1300. AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,BufferArray);
  1301. AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,BufferCount);
  1302. AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,AfdFlags);
  1303. AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,TdiRequest);
  1304. AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,TdiConnInfo);
  1305. typedef UNALIGNED struct _AFD_RECV_INFO32 {
  1306. AFD_POINTER_32 BufferArray;
  1307. ULONG BufferCount;
  1308. ULONG AfdFlags;
  1309. ULONG TdiFlags;
  1310. } AFD_RECV_INFO32, *PAFD_RECV_INFO32;
  1311. AFD_CHECK32on64(AFD_RECV_INFO,BufferArray);
  1312. AFD_CHECK32on64(AFD_RECV_INFO,BufferCount);
  1313. AFD_CHECK32on64(AFD_RECV_INFO,AfdFlags);
  1314. AFD_CHECK32on64(AFD_RECV_INFO,TdiFlags);
  1315. typedef UNALIGNED struct _AFD_RECV_DATAGRAM_INFO32 {
  1316. AFD_POINTER_32 BufferArray;
  1317. ULONG BufferCount;
  1318. ULONG AfdFlags;
  1319. ULONG TdiFlags;
  1320. AFD_POINTER_32 Address;
  1321. AFD_POINTER_32 AddressLength;
  1322. } AFD_RECV_DATAGRAM_INFO32, *PAFD_RECV_DATAGRAM_INFO32;
  1323. AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,BufferArray);
  1324. AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,BufferCount);
  1325. AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,AfdFlags);
  1326. AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,TdiFlags);
  1327. AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,Address);
  1328. AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,AddressLength);
  1329. typedef UNALIGNED struct _AFD_CONNECT_JOIN_INFO32 {
  1330. BOOLEAN SanActive;
  1331. VOID * POINTER_32 RootEndpoint; // Root endpoint for joins
  1332. VOID * POINTER_32 ConnectEndpoint;// Connect/leaf endpoint for async connects
  1333. TRANSPORT_ADDRESS RemoteAddress; // Remote address
  1334. } AFD_CONNECT_JOIN_INFO32, *PAFD_CONNECT_JOIN_INFO32;
  1335. AFD_CHECK32on64(AFD_CONNECT_JOIN_INFO,SanActive);
  1336. AFD_CHECK32on64(AFD_CONNECT_JOIN_INFO,RootEndpoint);
  1337. AFD_CHECK32on64(AFD_CONNECT_JOIN_INFO,ConnectEndpoint);
  1338. AFD_CHECK32on64(AFD_CONNECT_JOIN_INFO,RemoteAddress);
  1339. typedef UNALIGNED struct _AFD_EVENT_SELECT_INFO32 {
  1340. VOID * POINTER_32 Event;
  1341. ULONG PollEvents;
  1342. } AFD_EVENT_SELECT_INFO32, *PAFD_EVENT_SELECT_INFO32;
  1343. AFD_CHECK32on64(AFD_EVENT_SELECT_INFO,Event);
  1344. AFD_CHECK32on64(AFD_EVENT_SELECT_INFO,PollEvents);
  1345. typedef UNALIGNED struct _AFD_QOS_INFO32 {
  1346. QOS32 Qos;
  1347. BOOLEAN GroupQos;
  1348. } AFD_QOS_INFO32, *PAFD_QOS_INFO32;
  1349. AFD_CHECK32on64(AFD_QOS_INFO,Qos);
  1350. AFD_CHECK32on64(AFD_QOS_INFO,GroupQos);
  1351. typedef UNALIGNED struct _AFD_TRANSPORT_IOCTL_INFO32 {
  1352. VOID * POINTER_32 Handle;
  1353. AFD_POINTER_32 InputBuffer;
  1354. ULONG InputBufferLength;
  1355. ULONG IoControlCode;
  1356. ULONG AfdFlags;
  1357. ULONG PollEvent;
  1358. } AFD_TRANSPORT_IOCTL_INFO32, *PAFD_TRANSPORT_IOCTL_INFO32;
  1359. AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,Handle);
  1360. AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,InputBuffer);
  1361. AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,InputBufferLength);
  1362. AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,IoControlCode);
  1363. AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,AfdFlags);
  1364. AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,PollEvent);
  1365. typedef UNALIGNED struct _TRANSMIT_PACKETS_ELEMENT32 {
  1366. ULONG dwElFlags;
  1367. #define TP_MEMORY 1
  1368. #define TP_FILE 2
  1369. #define TP_EOP 4
  1370. ULONG cLength;
  1371. union {
  1372. struct {
  1373. LARGE_INTEGER nFileOffset;
  1374. VOID * POINTER_32 hFile;
  1375. };
  1376. AFD_POINTER_32 pBuffer;
  1377. };
  1378. } TRANSMIT_PACKETS_ELEMENT32, *LPTRANSMIT_PACKETS_ELEMENT32;
  1379. AFD_CHECK32on64(TRANSMIT_PACKETS_ELEMENT,dwElFlags);
  1380. AFD_CHECK32on64(TRANSMIT_PACKETS_ELEMENT,nFileOffset);
  1381. AFD_CHECK32on64(TRANSMIT_PACKETS_ELEMENT,hFile);
  1382. AFD_CHECK32on64(TRANSMIT_PACKETS_ELEMENT,pBuffer);
  1383. typedef UNALIGNED struct _AFD_TPACKETS_INFO32 {
  1384. AFD_POINTER_32 ElementArray;
  1385. ULONG ElementCount;
  1386. ULONG SendSize;
  1387. ULONG Flags;
  1388. } AFD_TPACKETS_INFO32, *PAFD_TPACKETS_INFO32;
  1389. AFD_CHECK32on64(AFD_TPACKETS_INFO,ElementArray);
  1390. AFD_CHECK32on64(AFD_TPACKETS_INFO,ElementCount);
  1391. AFD_CHECK32on64(AFD_TPACKETS_INFO,SendSize);
  1392. AFD_CHECK32on64(AFD_TPACKETS_INFO,Flags);
  1393. typedef UNALIGNED struct _AFD_RECV_MESSAGE_INFO32 {
  1394. AFD_RECV_DATAGRAM_INFO32 dgi;
  1395. AFD_POINTER_32 ControlBuffer;
  1396. AFD_POINTER_32 ControlLength;
  1397. AFD_POINTER_32 MsgFlags;
  1398. } AFD_RECV_MESSAGE_INFO32, *PAFD_RECV_MESSAGE_INFO32;
  1399. AFD_CHECK32on64(AFD_RECV_MESSAGE_INFO,dgi);
  1400. AFD_CHECK32on64(AFD_RECV_MESSAGE_INFO,MsgFlags);
  1401. AFD_CHECK32on64(AFD_RECV_MESSAGE_INFO,ControlBuffer);
  1402. AFD_CHECK32on64(AFD_RECV_MESSAGE_INFO,ControlLength);
  1403. typedef UNALIGNED struct _AFD_SWITCH_OPEN_PACKET32 {
  1404. VOID * POINTER_32 CompletionPort;
  1405. VOID * POINTER_32 CompletionEvent;
  1406. } AFD_SWITCH_OPEN_PACKET32, *PAFD_SWITCH_OPEN_PACKET32;
  1407. AFD_CHECK32on64(AFD_SWITCH_OPEN_PACKET,CompletionPort);
  1408. AFD_CHECK32on64(AFD_SWITCH_OPEN_PACKET,CompletionEvent);
  1409. typedef UNALIGNED struct _AFD_SWITCH_CONTEXT_INFO32 {
  1410. VOID * POINTER_32 SocketHandle;
  1411. AFD_POINTER_32 SwitchContext;
  1412. } AFD_SWITCH_CONTEXT_INFO32, *PAFD_SWITCH_CONTEXT_INFO32;
  1413. AFD_CHECK32on64(AFD_SWITCH_CONTEXT_INFO,SocketHandle);
  1414. AFD_CHECK32on64(AFD_SWITCH_CONTEXT_INFO,SwitchContext);
  1415. typedef UNALIGNED struct _AFD_SWITCH_CONNECT_INFO32 {
  1416. VOID * POINTER_32 ListenHandle;
  1417. AFD_POINTER_32 SwitchContext;
  1418. TRANSPORT_ADDRESS RemoteAddress;
  1419. } AFD_SWITCH_CONNECT_INFO32, *PAFD_SWITCH_CONNECT_INFO32;
  1420. AFD_CHECK32on64(AFD_SWITCH_CONNECT_INFO,ListenHandle);
  1421. AFD_CHECK32on64(AFD_SWITCH_CONNECT_INFO,SwitchContext);
  1422. AFD_CHECK32on64(AFD_SWITCH_CONNECT_INFO,RemoteAddress);
  1423. typedef UNALIGNED struct _AFD_SWITCH_ACCEPT_INFO32 {
  1424. VOID * POINTER_32 AcceptHandle;
  1425. ULONG ReceiveLength;
  1426. } AFD_SWITCH_ACCEPT_INFO32, *PAFD_SWITCH_ACCEPT_INFO32;
  1427. AFD_CHECK32on64(AFD_SWITCH_ACCEPT_INFO,AcceptHandle);
  1428. AFD_CHECK32on64(AFD_SWITCH_ACCEPT_INFO,ReceiveLength);
  1429. typedef UNALIGNED struct _AFD_SWITCH_EVENT_INFO32 {
  1430. VOID * POINTER_32 SocketHandle;
  1431. AFD_POINTER_32 SwitchContext;
  1432. ULONG EventBit;
  1433. NTSTATUS Status;
  1434. } AFD_SWITCH_EVENT_INFO32, *PAFD_SWITCH_EVENT_INFO32;
  1435. AFD_CHECK32on64(AFD_SWITCH_EVENT_INFO,SocketHandle);
  1436. AFD_CHECK32on64(AFD_SWITCH_EVENT_INFO,SwitchContext);
  1437. AFD_CHECK32on64(AFD_SWITCH_EVENT_INFO,EventBit);
  1438. AFD_CHECK32on64(AFD_SWITCH_EVENT_INFO,Status);
  1439. typedef UNALIGNED struct _AFD_SWITCH_REQUEST_INFO32 {
  1440. VOID * POINTER_32 SocketHandle;
  1441. AFD_POINTER_32 SwitchContext;
  1442. AFD_POINTER_32 RequestContext;
  1443. NTSTATUS RequestStatus;
  1444. ULONG DataOffset;
  1445. } AFD_SWITCH_REQUEST_INFO32, *PAFD_SWITCH_REQUEST_INFO32;
  1446. AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,SocketHandle);
  1447. AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,SwitchContext);
  1448. AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,RequestContext);
  1449. AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,RequestStatus);
  1450. AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,DataOffset);
  1451. typedef UNALIGNED struct _AFD_SWITCH_ACQUIRE_CTX_INFO32 {
  1452. VOID * POINTER_32 SocketHandle;
  1453. AFD_POINTER_32 SwitchContext;
  1454. AFD_POINTER_32 SocketCtxBuf;
  1455. ULONG SocketCtxBufSize;
  1456. } AFD_SWITCH_ACQUIRE_CTX_INFO32, *PAFD_SWITCH_ACQUIRE_CTX_INFO32;
  1457. AFD_CHECK32on64(AFD_SWITCH_ACQUIRE_CTX_INFO,SocketHandle);
  1458. AFD_CHECK32on64(AFD_SWITCH_ACQUIRE_CTX_INFO,SwitchContext);
  1459. AFD_CHECK32on64(AFD_SWITCH_ACQUIRE_CTX_INFO,SocketCtxBuf);
  1460. AFD_CHECK32on64(AFD_SWITCH_ACQUIRE_CTX_INFO,SocketCtxBufSize);
  1461. typedef UNALIGNED struct _AFD_SWITCH_TRANSFER_CTX_INFO32 {
  1462. VOID * POINTER_32 SocketHandle;
  1463. AFD_POINTER_32 SwitchContext;
  1464. AFD_POINTER_32 RequestContext;
  1465. AFD_POINTER_32 SocketCtxBuf;
  1466. ULONG SocketCtxBufSize;
  1467. AFD_POINTER_32 RcvBufferArray;
  1468. ULONG RcvBufferCount;
  1469. NTSTATUS Status;
  1470. } AFD_SWITCH_TRANSFER_CTX_INFO32, *PAFD_SWITCH_TRANSFER_CTX_INFO32;
  1471. AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,SocketHandle);
  1472. AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,SwitchContext);
  1473. AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,RequestContext);
  1474. AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,SocketCtxBuf);
  1475. AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,SocketCtxBufSize);
  1476. AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,RcvBufferArray);
  1477. AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,RcvBufferCount);
  1478. AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,Status);
  1479. typedef UNALIGNED struct _AFD_PARTIAL_DISCONNECT_INFO32 {
  1480. ULONG DisconnectMode;
  1481. LARGE_INTEGER Timeout;
  1482. } AFD_PARTIAL_DISCONNECT_INFO32, *PAFD_PARTIAL_DISCONNECT_INFO32;
  1483. AFD_CHECK32on64(AFD_PARTIAL_DISCONNECT_INFO,DisconnectMode);
  1484. AFD_CHECK32on64(AFD_PARTIAL_DISCONNECT_INFO,Timeout);
  1485. typedef UNALIGNED struct _AFD_SUPER_DISCONNECT_INFO32 {
  1486. ULONG Flags;
  1487. } AFD_SUPER_DISCONNECT_INFO32, *PAFD_SUPER_DISCONNECT_INFO32;
  1488. AFD_CHECK32on64(AFD_SUPER_DISCONNECT_INFO,Flags);
  1489. typedef UNALIGNED struct _AFD_INFORMATION32 {
  1490. ULONG InformationType;
  1491. union {
  1492. BOOLEAN Boolean;
  1493. ULONG Ulong;
  1494. LARGE_INTEGER LargeInteger;
  1495. } Information;
  1496. } AFD_INFORMATION32, *PAFD_INFORMATION32;
  1497. AFD_CHECK32on64(AFD_INFORMATION,InformationType);
  1498. AFD_CHECK32on64(AFD_INFORMATION,Information);
  1499. AFD_CHECK32on64(AFD_INFORMATION,Information.Boolean);
  1500. AFD_CHECK32on64(AFD_INFORMATION,Information.Ulong);
  1501. AFD_CHECK32on64(AFD_INFORMATION,Information.LargeInteger);
  1502. typedef UNALIGNED struct _TDI_CMSGHDR32 {
  1503. ULONG cmsg_len;
  1504. LONG cmsg_level;
  1505. LONG cmsg_type;
  1506. /* followed by UCHAR cmsg_data[] */
  1507. } TDI_CMSGHDR32, *PTDI_CMSGHDR32;
  1508. AFD_CHECK32on64(TDI_CMSGHDR,cmsg_len);
  1509. AFD_CHECK32on64(TDI_CMSGHDR,cmsg_level);
  1510. AFD_CHECK32on64(TDI_CMSGHDR,cmsg_type);
  1511. #ifdef _WIN64
  1512. #define TDI_CMSGHDR_ALIGN32(length) \
  1513. ( ((length) + TYPE_ALIGNMENT(TDI_CMSGHDR32)-1) &\
  1514. (~(TYPE_ALIGNMENT(TDI_CMSGHDR32)-1)) ) \
  1515. #define TDI_CMSGDATA_ALIGN32(length) \
  1516. ( ((length) + AFD_MAX_NATURAL_ALIGNMENT32-1) & \
  1517. (~(AFD_MAX_NATURAL_ALIGNMENT32-1)) )
  1518. #endif //_WIN64
  1519. #endif // ndef _AFDSTR_