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.

2517 lines
78 KiB

  1. /*++
  2. Copyright (c) 1989 - 1999 Microsoft Corporation
  3. Module Name:
  4. poll.c
  5. Abstract:
  6. Contains AfdPoll to handle IOCTL_AFD_POLL and code to process
  7. and signal poll events.
  8. Author:
  9. David Treadwell (davidtr) 4-Apr-1992
  10. Revision History:
  11. Vadim Eydelman (vadime)
  12. 1998-1999 NT5.0 Optimizations and 32/64 support
  13. --*/
  14. #include "afdp.h"
  15. VOID
  16. AfdCancelPoll (
  17. IN PDEVICE_OBJECT DeviceObject,
  18. IN PIRP Irp
  19. );
  20. VOID
  21. AfdFreePollInfo (
  22. IN PAFD_POLL_INFO_INTERNAL PollInfoInternal
  23. );
  24. VOID
  25. AfdTimeoutPoll (
  26. IN struct _KDPC *Dpc,
  27. IN PVOID DeferredContext,
  28. IN PVOID SystemArgument1,
  29. IN PVOID SystemArgument2
  30. );
  31. #ifdef _WIN64
  32. NTSTATUS
  33. AfdPoll32 (
  34. IN PIRP Irp,
  35. IN PIO_STACK_LOCATION IrpSp
  36. );
  37. #endif
  38. VOID
  39. AfdSanPollApcKernelRoutine (
  40. IN struct _KAPC *Apc,
  41. IN OUT PKNORMAL_ROUTINE *NormalRoutine,
  42. IN OUT PVOID *NormalContext,
  43. IN OUT PVOID *SystemArgument1,
  44. IN OUT PVOID *SystemArgument2
  45. );
  46. VOID
  47. AfdSanPollApcRundownRoutine (
  48. IN struct _KAPC *Apc
  49. );
  50. #ifdef ALLOC_PRAGMA
  51. #pragma alloc_text( PAGEAFD, AfdPoll )
  52. #ifdef _WIN64
  53. #pragma alloc_text( PAGEAFD, AfdPoll32 )
  54. #endif
  55. #pragma alloc_text( PAGEAFD, AfdCancelPoll )
  56. #pragma alloc_text( PAGEAFD, AfdFreePollInfo )
  57. #pragma alloc_text( PAGEAFD, AfdTimeoutPoll )
  58. #pragma alloc_text( PAGE, AfdSanPollApcKernelRoutine )
  59. #pragma alloc_text( PAGE, AfdSanPollApcRundownRoutine )
  60. #endif
  61. NTSTATUS
  62. FASTCALL
  63. AfdPoll (
  64. IN PIRP Irp,
  65. IN PIO_STACK_LOCATION IrpSp
  66. )
  67. {
  68. NTSTATUS status;
  69. PAFD_POLL_INFO pollInfo;
  70. PAFD_POLL_HANDLE_INFO pollHandleInfo;
  71. PAFD_POLL_INFO_INTERNAL pollInfoInternal;
  72. PAFD_POLL_INFO_INTERNAL freePollInfo = NULL;
  73. PAFD_POLL_ENDPOINT_INFO pollEndpointInfo;
  74. ULONG i;
  75. AFD_LOCK_QUEUE_HANDLE pollLockHandle, endpointLockHandle;
  76. PIRP oldIrp = NULL;
  77. #ifdef _WIN64
  78. if (IoIs32bitProcess (Irp)) {
  79. return AfdPoll32 (Irp, IrpSp);
  80. }
  81. #endif
  82. //
  83. // Set up locals.
  84. //
  85. pollInfo = Irp->AssociatedIrp.SystemBuffer;
  86. if ((IrpSp->Parameters.DeviceIoControl.InputBufferLength<
  87. (ULONG)FIELD_OFFSET (AFD_POLL_INFO, Handles[0])) ||
  88. ((IrpSp->Parameters.DeviceIoControl.InputBufferLength -
  89. FIELD_OFFSET (AFD_POLL_INFO, Handles[0]))/
  90. sizeof(pollInfo->Handles[0]) < pollInfo->NumberOfHandles) ||
  91. (IrpSp->Parameters.DeviceIoControl.OutputBufferLength<
  92. IrpSp->Parameters.DeviceIoControl.InputBufferLength)) {
  93. status = STATUS_INVALID_PARAMETER;
  94. goto complete;
  95. }
  96. IF_DEBUG(POLL) {
  97. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  98. "AfdPoll: poll IRP %p, IrpSp %p, handles %ld, "
  99. "TO %lx,%lx\n",
  100. Irp, IrpSp,
  101. pollInfo->NumberOfHandles,
  102. pollInfo->Timeout.HighPart, pollInfo->Timeout.LowPart ));
  103. }
  104. Irp->IoStatus.Information = 0;
  105. //
  106. // Determine how large the internal poll information structure will
  107. // be and allocate space for it from nonpaged pool. It must be
  108. // nonpaged since this will be accesses in event handlers.
  109. //
  110. try {
  111. pollInfoInternal = AFD_ALLOCATE_POOL_WITH_QUOTA (
  112. NonPagedPool,
  113. FIELD_OFFSET (AFD_POLL_INFO_INTERNAL,
  114. EndpointInfo[pollInfo->NumberOfHandles]),
  115. AFD_POLL_POOL_TAG
  116. );
  117. // AFD_ALLOCATE_POOL_WITH_QUOTA macro sets POOL_RAISE_IF_ALLOCATION_FAILURE
  118. }
  119. except (EXCEPTION_EXECUTE_HANDLER) {
  120. status = GetExceptionCode ();
  121. pollInfoInternal = NULL;
  122. goto complete;
  123. }
  124. //
  125. // Initialize the internal information buffer.
  126. //
  127. pollInfoInternal->Irp = Irp;
  128. pollInfoInternal->NumberOfEndpoints = 0;
  129. pollInfoInternal->Unique = pollInfo->Unique;
  130. pollInfoInternal->SanPoll = FALSE;
  131. pollHandleInfo = pollInfo->Handles;
  132. pollEndpointInfo = pollInfoInternal->EndpointInfo;
  133. for ( i = 0; i < pollInfo->NumberOfHandles; i++ ) {
  134. status = ObReferenceObjectByHandle(
  135. pollHandleInfo->Handle,
  136. (IrpSp->Parameters.DeviceIoControl.IoControlCode>>14) & 3,
  137. // DesiredAccess
  138. *IoFileObjectType,
  139. Irp->RequestorMode,
  140. (PVOID *)&pollEndpointInfo->FileObject,
  141. NULL
  142. );
  143. if ( !NT_SUCCESS(status) ) {
  144. AfdFreePollInfo( pollInfoInternal );
  145. goto complete;
  146. }
  147. //
  148. // Make sure that this is an AFD endpoint and not some other
  149. // random file handle.
  150. //
  151. if ( pollEndpointInfo->FileObject->DeviceObject != AfdDeviceObject ) {
  152. //
  153. // Dereference last referenced object
  154. // The rest will be dereferenced in AfdFreePollInfo
  155. // as determined by NumberOfEndpoints counter which
  156. // is incremented below.
  157. //
  158. ObDereferenceObject( pollEndpointInfo->FileObject );
  159. status = STATUS_INVALID_HANDLE;
  160. AfdFreePollInfo( pollInfoInternal );
  161. goto complete;
  162. }
  163. pollEndpointInfo->PollEvents = pollHandleInfo->PollEvents;
  164. pollEndpointInfo->Handle = pollHandleInfo->Handle;
  165. pollEndpointInfo->Endpoint = pollEndpointInfo->FileObject->FsContext;
  166. if (IS_SAN_ENDPOINT (pollEndpointInfo->Endpoint)) {
  167. ASSERT (pollEndpointInfo->Endpoint->State==AfdEndpointStateConnected);
  168. status = AfdSanPollBegin (pollEndpointInfo->Endpoint,
  169. pollEndpointInfo->PollEvents);
  170. if (!NT_SUCCESS (status)) {
  171. AfdFreePollInfo (pollInfoInternal);
  172. goto complete;
  173. }
  174. pollEndpointInfo->PollEvents |= AFD_POLL_SANCOUNTS_UPDATED;
  175. pollInfoInternal->SanPoll = TRUE;
  176. }
  177. ASSERT( InterlockedIncrement( &pollEndpointInfo->Endpoint->ObReferenceBias ) > 0 );
  178. IF_DEBUG(POLL) {
  179. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  180. "AfdPoll: event %lx, endp %p, conn %p, handle %p, "
  181. "info %p\n",
  182. pollEndpointInfo->PollEvents,
  183. pollEndpointInfo->Endpoint,
  184. AFD_CONNECTION_FROM_ENDPOINT( pollEndpointInfo->Endpoint ),
  185. pollEndpointInfo->Handle,
  186. pollEndpointInfo ));
  187. }
  188. REFERENCE_ENDPOINT( pollEndpointInfo->Endpoint );
  189. //
  190. // Increment pointers in the poll info structures.
  191. //
  192. pollHandleInfo++;
  193. pollEndpointInfo++;
  194. pollInfoInternal->NumberOfEndpoints++;
  195. }
  196. restart_poll:
  197. //
  198. // Hold the AFD spin lock while we check for endpoints that already
  199. // satisfy a condition to synchronize between this operation and
  200. // a call to AfdIndicatePollEvent. We release the spin lock
  201. // after all the endpoints have been checked and the internal
  202. // poll info structure is on the global list so AfdIndicatePollEvent
  203. // can find it if necessary.
  204. //
  205. AfdAcquireSpinLock( &AfdPollListLock, &pollLockHandle );
  206. //
  207. // Set up a cancel routine in the IRP so that the IRP will be
  208. // completed correctly if it gets canceled. Also check whether the
  209. // IRP has already been canceled.
  210. //
  211. IoSetCancelRoutine( Irp, AfdCancelPoll );
  212. if ( Irp->Cancel ) {
  213. //
  214. // The IRP has already been canceled. Free the internal
  215. // poll information structure and complete the IRP.
  216. //
  217. AfdReleaseSpinLock( &AfdPollListLock, &pollLockHandle );
  218. if (IoSetCancelRoutine( Irp, NULL ) == NULL) {
  219. KIRQL cancelIrql;
  220. //
  221. // If the cancel routine was NULL then cancel routine
  222. // may be running. Wait on the cancel spinlock until
  223. // the cancel routine is done.
  224. //
  225. // Note: The cancel routine will not find the IRP
  226. // since it is not in the list.
  227. //
  228. IoAcquireCancelSpinLock( &cancelIrql );
  229. IoReleaseCancelSpinLock( cancelIrql );
  230. }
  231. AfdFreePollInfo( pollInfoInternal );
  232. status = STATUS_CANCELLED;
  233. goto complete;
  234. }
  235. //
  236. // If this is a unique poll, determine whether there is another
  237. // unique poll on this endpoint. If there is an existing unique
  238. // poll, cancel it. This request will supercede the existing
  239. // request.
  240. //
  241. if ( pollInfo->Unique ) {
  242. PLIST_ENTRY listEntry;
  243. for ( listEntry = AfdPollListHead.Flink;
  244. listEntry != &AfdPollListHead;
  245. listEntry = listEntry->Flink ) {
  246. PAFD_POLL_INFO_INTERNAL testInfo;
  247. BOOLEAN timerCancelSucceeded;
  248. testInfo = CONTAINING_RECORD(
  249. listEntry,
  250. AFD_POLL_INFO_INTERNAL,
  251. PollListEntry
  252. );
  253. if ( testInfo->Unique &&
  254. testInfo->EndpointInfo[0].FileObject ==
  255. pollInfoInternal->EndpointInfo[0].FileObject ) {
  256. IF_DEBUG(POLL) {
  257. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  258. "AfdPoll: found existing unique poll IRP %p "
  259. "for file object %p, context %p, cancelling.\n",
  260. testInfo->Irp,
  261. testInfo->EndpointInfo[0].FileObject,
  262. testInfo ));
  263. }
  264. //
  265. // Cancel the IRP manually rather than calling
  266. // AfdCancelPoll because we already hold the
  267. // AfdSpinLock, we can't acquire it recursively, and we
  268. // don't want to release it. Remove the poll structure
  269. // from the global list.
  270. //
  271. RemoveEntryList( &testInfo->PollListEntry );
  272. //
  273. // Cancel the timer.
  274. //
  275. if ( testInfo->TimerStarted ) {
  276. timerCancelSucceeded = KeCancelTimer( &testInfo->Timer );
  277. } else {
  278. timerCancelSucceeded = TRUE;
  279. }
  280. //
  281. // Complete the IRP with STATUS_CANCELLED as the status.
  282. //
  283. testInfo->Irp->IoStatus.Information = 0;
  284. testInfo->Irp->IoStatus.Status = STATUS_CANCELLED;
  285. oldIrp = testInfo->Irp;
  286. //
  287. // Remember the poll info structure so that we'll free
  288. // before we exit. We cannot free it now because we're
  289. // holding the AfdSpinLock. Note that if cancelling the
  290. // timer failed, then the timer is already running and
  291. // it will free the poll info structure, but not
  292. // complete the IRP since we complete it and NULL it
  293. // here.
  294. //
  295. if ( timerCancelSucceeded ) {
  296. freePollInfo = testInfo;
  297. } else {
  298. pollInfoInternal->Irp = NULL;
  299. }
  300. //
  301. // There should be only one outstanding unique poll IRP
  302. // on any given file object, so quit looking for another
  303. // now that we've found one.
  304. //
  305. break;
  306. }
  307. }
  308. }
  309. //
  310. // We're done with the input structure provided by the caller. Now
  311. // walk through the internal structure and determine whether any of
  312. // the specified endpoints are ready for the specified condition.
  313. //
  314. pollInfo->NumberOfHandles = 0;
  315. pollHandleInfo = pollInfo->Handles;
  316. pollEndpointInfo = pollInfoInternal->EndpointInfo;
  317. for ( i = 0; i < pollInfoInternal->NumberOfEndpoints; i++ ) {
  318. BOOLEAN found;
  319. PAFD_ENDPOINT endpoint;
  320. PAFD_CONNECTION connection;
  321. found = FALSE;
  322. endpoint = pollEndpointInfo->Endpoint;
  323. ASSERT( IS_AFD_ENDPOINT_TYPE( endpoint ) );
  324. AfdAcquireSpinLockAtDpcLevel (&endpoint->SpinLock, &endpointLockHandle);
  325. //
  326. // Remember that there has been a poll on this endpoint. This flag
  327. // allows us to optimize AfdIndicatePollEvent() for endpoints that have
  328. // never been polled, which is a common case.
  329. //
  330. endpoint->PollCalled = TRUE;
  331. connection = AFD_CONNECTION_FROM_ENDPOINT( endpoint );
  332. ASSERT( connection == NULL || connection->Type == AfdBlockTypeConnection );
  333. pollHandleInfo->PollEvents = 0;
  334. pollHandleInfo->Status = STATUS_SUCCESS;
  335. if (IS_SAN_ENDPOINT (endpoint)) {
  336. if (endpoint->Common.SanEndp.SelectEventsActive & pollEndpointInfo->PollEvents) {
  337. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  338. pollHandleInfo->PollEvents = pollEndpointInfo->PollEvents
  339. & endpoint->Common.SanEndp.SelectEventsActive;
  340. found = TRUE;
  341. }
  342. else if (!found &&
  343. (pollEndpointInfo->PollEvents & AFD_POLL_SANCOUNTS_UPDATED)==0) {
  344. //
  345. // OOPS, endpoint has been converted too SAN while we were looping,
  346. // need to release the spinlock, update switch counts, and restart
  347. // the loop. We don't do this is we are about to return anyway.
  348. //
  349. AfdReleaseSpinLockFromDpcLevel (&endpoint->SpinLock, &endpointLockHandle);
  350. AfdReleaseSpinLock (&AfdPollListLock, &pollLockHandle);
  351. //
  352. // First see if IRP was cancelled.
  353. //
  354. if (IoSetCancelRoutine( Irp, NULL ) == NULL) {
  355. KIRQL cancelIrql;
  356. //
  357. // If the cancel routine was NULL then cancel routine
  358. // may be running. Wait on the cancel spinlock until
  359. // the cancel routine is done.
  360. //
  361. // Note: The cancel routine will not find the IRP
  362. // since it is not in the list.
  363. //
  364. IoAcquireCancelSpinLock( &cancelIrql );
  365. IoReleaseCancelSpinLock( cancelIrql );
  366. AfdFreePollInfo( pollInfoInternal );
  367. status = STATUS_CANCELLED;
  368. goto complete;
  369. }
  370. ASSERT (endpoint->State==AfdEndpointStateConnected);
  371. status = AfdSanPollBegin (endpoint,
  372. pollEndpointInfo->PollEvents);
  373. if (!NT_SUCCESS (status)) {
  374. AfdFreePollInfo (pollInfoInternal);
  375. goto complete;
  376. }
  377. pollEndpointInfo->PollEvents |= AFD_POLL_SANCOUNTS_UPDATED;
  378. pollInfoInternal->SanPoll = TRUE;
  379. //
  380. // Complete any old poll irps.
  381. //
  382. if ( oldIrp != NULL ) {
  383. if (IoSetCancelRoutine( oldIrp, NULL ) == NULL) {
  384. KIRQL cancelIrql;
  385. //
  386. // If the cancel routine was NULL then cancel routine
  387. // may be running. Wait on the cancel spinlock until
  388. // the cancel routine is done.
  389. //
  390. // Note: The cancel routine will not find the IRP
  391. // since it is not in the list.
  392. //
  393. IoAcquireCancelSpinLock( &cancelIrql );
  394. ASSERT( oldIrp->Cancel );
  395. IoReleaseCancelSpinLock( cancelIrql );
  396. }
  397. if (freePollInfo->SanPoll &&
  398. (oldIrp->Tail.Overlay.Thread!=PsGetCurrentThread ())) {
  399. KeInitializeApc (&freePollInfo->Apc,
  400. PsGetThreadTcb (oldIrp->Tail.Overlay.Thread),
  401. oldIrp->ApcEnvironment,
  402. AfdSanPollApcKernelRoutine,
  403. AfdSanPollApcRundownRoutine,
  404. (PKNORMAL_ROUTINE)-1,
  405. KernelMode,
  406. NULL);
  407. if (KeInsertQueueApc (&freePollInfo->Apc,
  408. freePollInfo,
  409. oldIrp,
  410. AfdPriorityBoost)) {
  411. return STATUS_PENDING;
  412. }
  413. else {
  414. freePollInfo->SanPoll = FALSE;
  415. }
  416. }
  417. //
  418. // If we need to free a cancelled poll info structure, do it now.
  419. //
  420. if ( freePollInfo != NULL ) {
  421. AfdFreePollInfo( freePollInfo );
  422. }
  423. IoCompleteRequest( oldIrp, AfdPriorityBoost );
  424. oldIrp = NULL;
  425. }
  426. goto restart_poll;
  427. }
  428. }
  429. else {
  430. //
  431. // Check each possible event and, if it is being polled, whether
  432. // the endpoint is ready for that event. If the endpoint is
  433. // ready, write information about the endpoint into the output
  434. // buffer.
  435. //
  436. if ( (pollEndpointInfo->PollEvents & AFD_POLL_RECEIVE) != 0 ) {
  437. //
  438. // For most endpoints, a receive poll is completed when
  439. // data arrived that does not have a posted receive.
  440. // For listening endpoints, however, a receive poll
  441. // completes when there is a connection available to be
  442. // accepted.
  443. //
  444. if ( !endpoint->Listening ) {
  445. if ( (connection != NULL &&
  446. IS_DATA_ON_CONNECTION( connection )) ||
  447. (IS_DGRAM_ENDPOINT(endpoint) &&
  448. ARE_DATAGRAMS_ON_ENDPOINT( endpoint )) ) {
  449. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  450. pollHandleInfo->PollEvents |= AFD_POLL_RECEIVE;
  451. found = TRUE;
  452. }
  453. //
  454. // If the endpoint is set up for inline reception of
  455. // expedited data, then any expedited data should
  456. // be indicated as normal data.
  457. //
  458. if ( connection != NULL && endpoint->InLine &&
  459. IS_EXPEDITED_DATA_ON_CONNECTION( connection ) ) {
  460. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  461. pollHandleInfo->PollEvents |= AFD_POLL_RECEIVE;
  462. found = TRUE;
  463. }
  464. } else {
  465. if (!pollInfo->Unique) {
  466. //
  467. // This is really a poll to see whether a connection is
  468. // available for an immediate accept. Convert the events
  469. // and do the check below in the accept poll handling.
  470. //
  471. pollEndpointInfo->PollEvents &= ~AFD_POLL_RECEIVE;
  472. pollEndpointInfo->PollEvents |= AFD_POLL_ACCEPT;
  473. }
  474. //
  475. // Unique polls (e.g. WSAAsyncSelect) set poll necessary
  476. // bits themselves.
  477. //
  478. }
  479. }
  480. if ( (pollEndpointInfo->PollEvents & AFD_POLL_RECEIVE_EXPEDITED) != 0 ) {
  481. //
  482. // If the endpoint is set up for inline reception of
  483. // expedited data, do not indicate as expedited data.
  484. //
  485. if ( connection != NULL && !endpoint->InLine &&
  486. IS_EXPEDITED_DATA_ON_CONNECTION( connection ) ) {
  487. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  488. pollHandleInfo->PollEvents |= AFD_POLL_RECEIVE_EXPEDITED;
  489. found = TRUE;
  490. }
  491. }
  492. if ( (pollEndpointInfo->PollEvents & AFD_POLL_SEND) != 0 ) {
  493. //
  494. // For unconnected non-datagram endpoints, a send poll
  495. // should complete when a connect operation completes.
  496. // Therefore, if this is an non-datagram endpoint which is
  497. // not connected, do not complete the poll until the connect
  498. // completes.
  499. //
  500. if ( endpoint->State == AfdEndpointStateConnected ||
  501. IS_DGRAM_ENDPOINT(endpoint) ) {
  502. //
  503. // For nonbufferring VC
  504. // endpoints, check whether a blocking error has
  505. // occurred. If so, it will not be possible to do a
  506. // nonblocking send until a send possible indication
  507. // arrives.
  508. //
  509. // For bufferring endpoints (TDI provider does not
  510. // buffer), check whether we have too much send data
  511. // outstanding.
  512. //
  513. if ( (IS_DGRAM_ENDPOINT(endpoint) &&
  514. (endpoint->DgBufferredSendBytes <
  515. endpoint->Common.Datagram.MaxBufferredSendBytes ||
  516. endpoint->DgBufferredSendBytes == 0))
  517. ||
  518. ((connection!=NULL) &&
  519. (( IS_TDI_BUFFERRING(endpoint) &&
  520. connection->VcNonBlockingSendPossible )
  521. ||
  522. ( !IS_TDI_BUFFERRING(endpoint) &&
  523. (connection->VcBufferredSendBytes <
  524. connection->MaxBufferredSendBytes ||
  525. connection->VcBufferredSendBytes == 0))
  526. ||
  527. connection->AbortIndicated )) ){
  528. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  529. pollHandleInfo->PollEvents |= AFD_POLL_SEND;
  530. found = TRUE;
  531. }
  532. }
  533. }
  534. if ( (pollEndpointInfo->PollEvents & AFD_POLL_ACCEPT) != 0 ) {
  535. if ( (endpoint->Type & AfdBlockTypeVcListening) == AfdBlockTypeVcListening &&
  536. !IsListEmpty( &endpoint->Common.VcListening.UnacceptedConnectionListHead ) ) {
  537. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  538. pollHandleInfo->PollEvents |= AFD_POLL_ACCEPT;
  539. found = TRUE;
  540. }
  541. }
  542. if ( (pollEndpointInfo->PollEvents & AFD_POLL_CONNECT) != 0 ) {
  543. //
  544. // If the endpoint is now connected, complete this event.
  545. //
  546. if ( endpoint->State == AfdEndpointStateConnected ) {
  547. ASSERT( NT_SUCCESS(endpoint->EventStatus[AFD_POLL_CONNECT_FAIL_BIT]) );
  548. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  549. pollHandleInfo->PollEvents |= AFD_POLL_CONNECT;
  550. found = TRUE;
  551. }
  552. }
  553. if ( (pollEndpointInfo->PollEvents & AFD_POLL_CONNECT_FAIL) != 0 ) {
  554. //
  555. // This is a poll to see whether a connect has failed
  556. // recently. The connect status must indicate an error.
  557. //
  558. if ( endpoint->State == AfdEndpointStateBound &&
  559. !NT_SUCCESS(endpoint->EventStatus[AFD_POLL_CONNECT_FAIL_BIT]) ) {
  560. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  561. pollHandleInfo->PollEvents |= AFD_POLL_CONNECT_FAIL;
  562. pollHandleInfo->Status =
  563. endpoint->EventStatus[AFD_POLL_CONNECT_FAIL_BIT];
  564. found = TRUE;
  565. }
  566. }
  567. if ( (pollEndpointInfo->PollEvents & AFD_POLL_DISCONNECT) != 0 ) {
  568. if ( connection != NULL && connection->DisconnectIndicated ) {
  569. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  570. pollHandleInfo->PollEvents |= AFD_POLL_DISCONNECT;
  571. found = TRUE;
  572. }
  573. }
  574. if ( (pollEndpointInfo->PollEvents & AFD_POLL_ABORT) != 0 ) {
  575. if ( connection != NULL && connection->AbortIndicated ) {
  576. pollHandleInfo->Handle = pollEndpointInfo->Handle;
  577. pollHandleInfo->PollEvents |= AFD_POLL_ABORT;
  578. found = TRUE;
  579. }
  580. }
  581. }
  582. AfdReleaseSpinLockFromDpcLevel (&endpoint->SpinLock, &endpointLockHandle);
  583. //
  584. // If the handle had a current event that was requested, update
  585. // the count of handles in the output buffer and increment the
  586. // pointer to the output buffer.
  587. //
  588. if ( found ) {
  589. pollInfo->NumberOfHandles++;
  590. pollHandleInfo++;
  591. }
  592. pollEndpointInfo++;
  593. }
  594. //
  595. // If we found any endpoints that are ready, free the poll information
  596. // structure and complete the request.
  597. //
  598. if ( pollInfo->NumberOfHandles > 0 ) {
  599. AfdReleaseSpinLock( &AfdPollListLock, &pollLockHandle );
  600. AfdFreePollInfo( pollInfoInternal );
  601. Irp->IoStatus.Information = (PUCHAR)pollHandleInfo - (PUCHAR)pollInfo;
  602. status = STATUS_SUCCESS;
  603. goto complete;
  604. }
  605. //
  606. // None of the endpoints are in the correct state. If a timeout was
  607. // specified, place the poll information on the global list and set
  608. // up a DPC and timer so that we know when to complete the IRP.
  609. //
  610. if ( pollInfo->Timeout.LowPart != 0 && pollInfo->Timeout.HighPart != 0 ) {
  611. IF_DEBUG(POLL) {
  612. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  613. "AfdPoll: no current events for poll IRP %p, "
  614. "info %p\n", Irp, pollInfoInternal ));
  615. }
  616. //
  617. // Set up the information field of the IO status block to indicate
  618. // that an output buffer with no handles should be returned.
  619. // AfdIndicatePollEvent will modify this if necessary.
  620. //
  621. Irp->IoStatus.Information = (PUCHAR)pollHandleInfo - (PUCHAR)pollInfo;
  622. //
  623. // Put a pointer to the internal poll info struct into the IRP
  624. // so that the cancel routine can find it.
  625. //
  626. IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = pollInfoInternal;
  627. //
  628. // Place the internal poll info struct on the global list.
  629. //
  630. InsertTailList( &AfdPollListHead, &pollInfoInternal->PollListEntry );
  631. //
  632. // If the timeout is infinite, then don't set up a timer and
  633. // DPC. Otherwise, set up a timer so we can timeout the poll
  634. // request if appropriate.
  635. //
  636. if ( pollInfo->Timeout.HighPart != 0x7FFFFFFF ) {
  637. pollInfoInternal->TimerStarted = TRUE;
  638. KeInitializeDpc(
  639. &pollInfoInternal->Dpc,
  640. AfdTimeoutPoll,
  641. pollInfoInternal
  642. );
  643. KeInitializeTimer( &pollInfoInternal->Timer );
  644. KeSetTimer(
  645. &pollInfoInternal->Timer,
  646. pollInfo->Timeout,
  647. &pollInfoInternal->Dpc
  648. );
  649. } else {
  650. pollInfoInternal->TimerStarted = FALSE;
  651. }
  652. } else {
  653. //
  654. // A timeout equal to 0 was specified; free the internal
  655. // structure and complete the request with no endpoints in the
  656. // output buffer.
  657. //
  658. IF_DEBUG(POLL) {
  659. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  660. "AfdPoll: zero timeout on poll IRP %p and no "
  661. "current events--completing.\n", Irp ));
  662. }
  663. AfdReleaseSpinLock( &AfdPollListLock, &pollLockHandle );
  664. AfdFreePollInfo( pollInfoInternal );
  665. Irp->IoStatus.Information = (PUCHAR)pollHandleInfo - (PUCHAR)pollInfo;
  666. status = STATUS_SUCCESS;
  667. goto complete;
  668. }
  669. //
  670. // Mark the IRP pending and release the spin locks. At this
  671. // point the IRP may get completed or cancelled.
  672. //
  673. IoMarkIrpPending( Irp );
  674. AfdReleaseSpinLock( &AfdPollListLock, &pollLockHandle );
  675. //
  676. // Complete any old poll irps.
  677. //
  678. if ( oldIrp != NULL ) {
  679. if (IoSetCancelRoutine( oldIrp, NULL ) == NULL) {
  680. KIRQL cancelIrql;
  681. //
  682. // If the cancel routine was NULL then cancel routine
  683. // may be running. Wait on the cancel spinlock until
  684. // the cancel routine is done.
  685. //
  686. // Note: The cancel routine will not find the IRP
  687. // since it is not in the list.
  688. //
  689. IoAcquireCancelSpinLock( &cancelIrql );
  690. ASSERT( oldIrp->Cancel );
  691. IoReleaseCancelSpinLock( cancelIrql );
  692. }
  693. if (freePollInfo->SanPoll &&
  694. (oldIrp->Tail.Overlay.Thread!=PsGetCurrentThread ())) {
  695. KeInitializeApc (&freePollInfo->Apc,
  696. PsGetThreadTcb (oldIrp->Tail.Overlay.Thread),
  697. oldIrp->ApcEnvironment,
  698. AfdSanPollApcKernelRoutine,
  699. AfdSanPollApcRundownRoutine,
  700. (PKNORMAL_ROUTINE)-1,
  701. KernelMode,
  702. NULL);
  703. if (KeInsertQueueApc (&freePollInfo->Apc,
  704. freePollInfo,
  705. oldIrp,
  706. AfdPriorityBoost)) {
  707. return STATUS_PENDING;
  708. }
  709. else {
  710. freePollInfo->SanPoll = FALSE;
  711. }
  712. }
  713. //
  714. // If we need to free a cancelled poll info structure, do it now.
  715. //
  716. if ( freePollInfo != NULL ) {
  717. AfdFreePollInfo( freePollInfo );
  718. }
  719. IoCompleteRequest( oldIrp, AfdPriorityBoost );
  720. }
  721. //
  722. // Return pending. The IRP will be completed when an appropriate
  723. // event is indicated by the TDI provider, when the timeout is hit,
  724. // or when the IRP is cancelled.
  725. //
  726. return STATUS_PENDING;
  727. complete:
  728. //
  729. // Complete any old poll irps.
  730. //
  731. if ( oldIrp != NULL ) {
  732. if (IoSetCancelRoutine( oldIrp, NULL ) == NULL) {
  733. KIRQL cancelIrql;
  734. //
  735. // If the cancel routine was NULL then cancel routine
  736. // may be running. Wait on the cancel spinlock until
  737. // the cancel routine is done.
  738. //
  739. // Note: The cancel routine will not find the IRP
  740. // since it is not in the list.
  741. //
  742. IoAcquireCancelSpinLock( &cancelIrql );
  743. ASSERT( oldIrp->Cancel );
  744. IoReleaseCancelSpinLock( cancelIrql );
  745. }
  746. if (freePollInfo->SanPoll &&
  747. (oldIrp->Tail.Overlay.Thread!=PsGetCurrentThread ())) {
  748. KeInitializeApc (&freePollInfo->Apc,
  749. PsGetThreadTcb (oldIrp->Tail.Overlay.Thread),
  750. oldIrp->ApcEnvironment,
  751. AfdSanPollApcKernelRoutine,
  752. AfdSanPollApcRundownRoutine,
  753. (PKNORMAL_ROUTINE)-1,
  754. KernelMode,
  755. NULL);
  756. if (KeInsertQueueApc (&freePollInfo->Apc,
  757. freePollInfo,
  758. oldIrp,
  759. AfdPriorityBoost)) {
  760. goto continue_complete;
  761. }
  762. else {
  763. freePollInfo->SanPoll = FALSE;
  764. }
  765. }
  766. //
  767. // If we need to free a cancelled poll info structure, do it now.
  768. //
  769. if ( freePollInfo != NULL ) {
  770. AfdFreePollInfo( freePollInfo );
  771. }
  772. IoCompleteRequest( oldIrp, AfdPriorityBoost );
  773. }
  774. continue_complete:
  775. Irp->IoStatus.Status = status;
  776. if (IoSetCancelRoutine( Irp, NULL ) == NULL) {
  777. KIRQL cancelIrql;
  778. //
  779. // If the cancel routine was NULL then cancel routine
  780. // may be running. Wait on the cancel spinlock until
  781. // the cancel routine is done.
  782. //
  783. // Note: The cancel routine will not find the IRP
  784. // since it is not in the list.
  785. //
  786. IoAcquireCancelSpinLock( &cancelIrql );
  787. // ASSERT( Irp->Cancel ); the cancel routine may have not been set
  788. IoReleaseCancelSpinLock( cancelIrql );
  789. }
  790. IoCompleteRequest( Irp, AfdPriorityBoost );
  791. return status;
  792. } // AfdPoll
  793. #ifdef _WIN64
  794. NTSTATUS
  795. AfdPoll32 (
  796. IN PIRP Irp,
  797. IN PIO_STACK_LOCATION IrpSp
  798. )
  799. {
  800. NTSTATUS status;
  801. PAFD_POLL_INFO32 pollInfo;
  802. PAFD_POLL_HANDLE_INFO32 pollHandleInfo;
  803. PAFD_POLL_INFO_INTERNAL pollInfoInternal;
  804. PAFD_POLL_INFO_INTERNAL freePollInfo = NULL;
  805. PAFD_POLL_ENDPOINT_INFO pollEndpointInfo;
  806. ULONG i;
  807. AFD_LOCK_QUEUE_HANDLE pollLockHandle, endpointLockHandle;
  808. PIRP oldIrp = NULL;
  809. //
  810. // Set up locals.
  811. //
  812. pollInfo = Irp->AssociatedIrp.SystemBuffer;
  813. if ((IrpSp->Parameters.DeviceIoControl.InputBufferLength<
  814. (ULONG)FIELD_OFFSET (AFD_POLL_INFO32, Handles[0])) ||
  815. ((IrpSp->Parameters.DeviceIoControl.InputBufferLength -
  816. FIELD_OFFSET (AFD_POLL_INFO32, Handles[0]))/
  817. sizeof(pollInfo->Handles[0]) < pollInfo->NumberOfHandles) ||
  818. (IrpSp->Parameters.DeviceIoControl.OutputBufferLength<
  819. IrpSp->Parameters.DeviceIoControl.InputBufferLength)) {
  820. status = STATUS_INVALID_PARAMETER;
  821. goto complete;
  822. }
  823. IF_DEBUG(POLL) {
  824. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  825. "AfdPoll32: poll IRP %p, IrpSp %p, handles %ld, "
  826. "TO %lx,%lx\n",
  827. Irp, IrpSp,
  828. pollInfo->NumberOfHandles,
  829. pollInfo->Timeout.HighPart, pollInfo->Timeout.LowPart ));
  830. }
  831. Irp->IoStatus.Information = 0;
  832. //
  833. // Determine how large the internal poll information structure will
  834. // be and allocate space for it from nonpaged pool. It must be
  835. // nonpaged since this will be accesses in event handlers.
  836. //
  837. try {
  838. pollInfoInternal = AFD_ALLOCATE_POOL_WITH_QUOTA(
  839. NonPagedPool,
  840. FIELD_OFFSET (AFD_POLL_INFO_INTERNAL,
  841. EndpointInfo[pollInfo->NumberOfHandles]),
  842. AFD_POLL_POOL_TAG
  843. );
  844. // AFD_ALLOCATE_POOL_WITH_QUOTA macro sets POOL_RAISE_IF_ALLOCATION_FAILURE
  845. }
  846. except (EXCEPTION_EXECUTE_HANDLER) {
  847. status = GetExceptionCode ();
  848. pollInfoInternal = NULL;
  849. goto complete;
  850. }
  851. //
  852. // Initialize the internal information buffer.
  853. //
  854. pollInfoInternal->Irp = Irp;
  855. pollInfoInternal->NumberOfEndpoints = 0;
  856. pollInfoInternal->Unique = pollInfo->Unique;
  857. pollInfoInternal->SanPoll = FALSE;
  858. pollHandleInfo = pollInfo->Handles;
  859. pollEndpointInfo = pollInfoInternal->EndpointInfo;
  860. for ( i = 0; i < pollInfo->NumberOfHandles; i++ ) {
  861. status = ObReferenceObjectByHandle(
  862. pollHandleInfo->Handle,
  863. (IrpSp->Parameters.DeviceIoControl.IoControlCode>>14) & 3,
  864. // DesiredAccess
  865. *IoFileObjectType,
  866. Irp->RequestorMode,
  867. (PVOID *)&pollEndpointInfo->FileObject,
  868. NULL
  869. );
  870. if ( !NT_SUCCESS(status) ) {
  871. AfdFreePollInfo( pollInfoInternal );
  872. goto complete;
  873. }
  874. //
  875. // Make sure that this is an AFD endpoint and not some other
  876. // random file handle.
  877. //
  878. if ( pollEndpointInfo->FileObject->DeviceObject != AfdDeviceObject ) {
  879. //
  880. // Dereference last referenced object
  881. // The rest will be dereferenced in AfdFreePollInfo
  882. // as determined by NumberOfEndpoints counter which
  883. // is incremented below.
  884. //
  885. ObDereferenceObject( pollEndpointInfo->FileObject );
  886. status = STATUS_INVALID_HANDLE;
  887. AfdFreePollInfo( pollInfoInternal );
  888. goto complete;
  889. }
  890. pollEndpointInfo->PollEvents = pollHandleInfo->PollEvents;
  891. pollEndpointInfo->Handle = pollHandleInfo->Handle;
  892. pollEndpointInfo->Endpoint = pollEndpointInfo->FileObject->FsContext;
  893. ASSERT( InterlockedIncrement( &pollEndpointInfo->Endpoint->ObReferenceBias ) > 0 );
  894. IF_DEBUG(POLL) {
  895. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  896. "AfdPoll32: event %lx, endp %p, conn %p, handle %p, "
  897. "info %p\n",
  898. pollEndpointInfo->PollEvents,
  899. pollEndpointInfo->Endpoint,
  900. AFD_CONNECTION_FROM_ENDPOINT( pollEndpointInfo->Endpoint ),
  901. pollEndpointInfo->Handle,
  902. pollEndpointInfo ));
  903. }
  904. REFERENCE_ENDPOINT( pollEndpointInfo->Endpoint );
  905. //
  906. // Increment pointers in the poll info structures.
  907. //
  908. pollHandleInfo++;
  909. pollEndpointInfo++;
  910. pollInfoInternal->NumberOfEndpoints++;
  911. }
  912. //
  913. // Hold the AFD spin lock while we check for endpoints that already
  914. // satisfy a condition to synchronize between this operation and
  915. // a call to AfdIndicatePollEvent. We release the spin lock
  916. // after all the endpoints have been checked and the internal
  917. // poll info structure is on the global list so AfdIndicatePollEvent
  918. // can find it if necessary.
  919. //
  920. AfdAcquireSpinLock( &AfdPollListLock, &pollLockHandle );
  921. //
  922. // Set up a cancel routine in the IRP so that the IRP will be
  923. // completed correctly if it gets canceled. Also check whether the
  924. // IRP has already been canceled.
  925. //
  926. IoSetCancelRoutine( Irp, AfdCancelPoll );
  927. if ( Irp->Cancel ) {
  928. //
  929. // The IRP has already been canceled. Free the internal
  930. // poll information structure and complete the IRP.
  931. //
  932. AfdReleaseSpinLock( &AfdPollListLock, &pollLockHandle );
  933. if (IoSetCancelRoutine( Irp, NULL ) == NULL) {
  934. KIRQL cancelIrql;
  935. //
  936. // If the cancel routine was NULL then cancel routine
  937. // may be running. Wait on the cancel spinlock until
  938. // the cancel routine is done.
  939. //
  940. // Note: The cancel routine will not find the IRP
  941. // since it is not in the list.
  942. //
  943. IoAcquireCancelSpinLock( &cancelIrql );
  944. IoReleaseCancelSpinLock( cancelIrql );
  945. }
  946. AfdFreePollInfo( pollInfoInternal );
  947. status = STATUS_CANCELLED;
  948. goto complete;
  949. }
  950. //
  951. // If this is a unique poll, determine whether there is another
  952. // unique poll on this endpoint. If there is an existing unique
  953. // poll, cancel it. This request will supercede the existing
  954. // request.
  955. //
  956. if ( pollInfo->Unique ) {
  957. PLIST_ENTRY listEntry;
  958. for ( listEntry = AfdPollListHead.Flink;
  959. listEntry != &AfdPollListHead;
  960. listEntry = listEntry->Flink ) {
  961. PAFD_POLL_INFO_INTERNAL testInfo;
  962. BOOLEAN timerCancelSucceeded;
  963. testInfo = CONTAINING_RECORD(
  964. listEntry,
  965. AFD_POLL_INFO_INTERNAL,
  966. PollListEntry
  967. );
  968. if ( testInfo->Unique &&
  969. testInfo->EndpointInfo[0].FileObject ==
  970. pollInfoInternal->EndpointInfo[0].FileObject ) {
  971. IF_DEBUG(POLL) {
  972. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  973. "AfdPoll32: found existing unique poll IRP %p "
  974. "for file object %p, context %p, cancelling.\n",
  975. testInfo->Irp,
  976. testInfo->EndpointInfo[0].FileObject,
  977. testInfo ));
  978. }
  979. //
  980. // Cancel the IRP manually rather than calling
  981. // AfdCancelPoll because we already hold the
  982. // AfdSpinLock, we can't acquire it recursively, and we
  983. // don't want to release it. Remove the poll structure
  984. // from the global list.
  985. //
  986. RemoveEntryList( &testInfo->PollListEntry );
  987. //
  988. // Cancel the timer.
  989. //
  990. if ( testInfo->TimerStarted ) {
  991. timerCancelSucceeded = KeCancelTimer( &testInfo->Timer );
  992. } else {
  993. timerCancelSucceeded = TRUE;
  994. }
  995. //
  996. // Complete the IRP with STATUS_CANCELLED as the status.
  997. //
  998. testInfo->Irp->IoStatus.Information = 0;
  999. testInfo->Irp->IoStatus.Status = STATUS_CANCELLED;
  1000. oldIrp = testInfo->Irp;
  1001. //
  1002. // Remember the poll info structure so that we'll free
  1003. // before we exit. We cannot free it now because we're
  1004. // holding the AfdSpinLock. Note that if cancelling the
  1005. // timer failed, then the timer is already running and
  1006. // it will free the poll info structure, but not
  1007. // complete the IRP since we complete it and NULL it
  1008. // here.
  1009. //
  1010. if ( timerCancelSucceeded ) {
  1011. freePollInfo = testInfo;
  1012. } else {
  1013. pollInfoInternal->Irp = NULL;
  1014. }
  1015. //
  1016. // There should be only one outstanding unique poll IRP
  1017. // on any given file object, so quit looking for another
  1018. // now that we've found one.
  1019. //
  1020. break;
  1021. }
  1022. }
  1023. }
  1024. //
  1025. // We're done with the input structure provided by the caller. Now
  1026. // walk through the internal structure and determine whether any of
  1027. // the specified endpoints are ready for the specified condition.
  1028. //
  1029. pollInfo->NumberOfHandles = 0;
  1030. pollHandleInfo = pollInfo->Handles;
  1031. pollEndpointInfo = pollInfoInternal->EndpointInfo;
  1032. for ( i = 0; i < pollInfoInternal->NumberOfEndpoints; i++ ) {
  1033. BOOLEAN found;
  1034. PAFD_ENDPOINT endpoint;
  1035. PAFD_CONNECTION connection;
  1036. found = FALSE;
  1037. endpoint = pollEndpointInfo->Endpoint;
  1038. ASSERT( IS_AFD_ENDPOINT_TYPE( endpoint ) );
  1039. AfdAcquireSpinLockAtDpcLevel (&endpoint->SpinLock, &endpointLockHandle);
  1040. //
  1041. // Remember that there has been a poll on this endpoint. This flag
  1042. // allows us to optimize AfdIndicatePollEvent() for endpoints that have
  1043. // never been polled, which is a common case.
  1044. //
  1045. endpoint->PollCalled = TRUE;
  1046. connection = AFD_CONNECTION_FROM_ENDPOINT( endpoint );
  1047. ASSERT( connection == NULL || connection->Type == AfdBlockTypeConnection );
  1048. pollHandleInfo->PollEvents = 0;
  1049. pollHandleInfo->Status = STATUS_SUCCESS;
  1050. //
  1051. // Check each possible event and, if it is being polled, whether
  1052. // the endpoint is ready for that event. If the endpoint is
  1053. // ready, write information about the endpoint into the output
  1054. // buffer.
  1055. //
  1056. if ( (pollEndpointInfo->PollEvents & AFD_POLL_RECEIVE) != 0 ) {
  1057. //
  1058. // For most endpoints, a receive poll is completed when
  1059. // data arrived that does not have a posted receive.
  1060. // For listening endpoints, however, a receive poll
  1061. // completes when there is a connection available to be
  1062. // accepted.
  1063. //
  1064. if ( !endpoint->Listening ) {
  1065. if ( (connection != NULL &&
  1066. IS_DATA_ON_CONNECTION( connection )) ||
  1067. (IS_DGRAM_ENDPOINT(endpoint) &&
  1068. ARE_DATAGRAMS_ON_ENDPOINT( endpoint )) ) {
  1069. pollHandleInfo->Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1070. pollHandleInfo->PollEvents |= AFD_POLL_RECEIVE;
  1071. found = TRUE;
  1072. }
  1073. //
  1074. // If the endpoint is set up for inline reception of
  1075. // expedited data, then any expedited data should
  1076. // be indicated as normal data.
  1077. //
  1078. if ( connection != NULL && endpoint->InLine &&
  1079. IS_EXPEDITED_DATA_ON_CONNECTION( connection ) ) {
  1080. pollHandleInfo->Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1081. pollHandleInfo->PollEvents |= AFD_POLL_RECEIVE;
  1082. found = TRUE;
  1083. }
  1084. } else {
  1085. if (!pollInfo->Unique) {
  1086. //
  1087. // This is really a poll to see whether a connection is
  1088. // available for an immediate accept. Convert the events
  1089. // and do the check below in the accept poll handling.
  1090. //
  1091. pollEndpointInfo->PollEvents &= ~AFD_POLL_RECEIVE;
  1092. pollEndpointInfo->PollEvents |= AFD_POLL_ACCEPT;
  1093. }
  1094. //
  1095. // Unique polls (e.g. WSAAsyncSelect) set poll necessary
  1096. // bits themselves.
  1097. //
  1098. }
  1099. }
  1100. if ( (pollEndpointInfo->PollEvents & AFD_POLL_RECEIVE_EXPEDITED) != 0 ) {
  1101. //
  1102. // If the endpoint is set up for inline reception of
  1103. // expedited data, do not indicate as expedited data.
  1104. //
  1105. if ( connection != NULL && !endpoint->InLine &&
  1106. IS_EXPEDITED_DATA_ON_CONNECTION( connection ) ) {
  1107. pollHandleInfo->Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1108. pollHandleInfo->PollEvents |= AFD_POLL_RECEIVE_EXPEDITED;
  1109. found = TRUE;
  1110. }
  1111. }
  1112. if ( (pollEndpointInfo->PollEvents & AFD_POLL_SEND) != 0 ) {
  1113. //
  1114. // For unconnected non-datagram endpoints, a send poll
  1115. // should complete when a connect operation completes.
  1116. // Therefore, if this is an non-datagram endpoint which is
  1117. // not connected, do not complete the poll until the connect
  1118. // completes.
  1119. //
  1120. if ( endpoint->State == AfdEndpointStateConnected ||
  1121. IS_DGRAM_ENDPOINT(endpoint) ) {
  1122. //
  1123. // It should always be possible to do a nonblocking send
  1124. // on a datagram endpoint. For nonbufferring VC
  1125. // endpoints, check whether a blocking error has
  1126. // occurred. If so, it will not be possible to do a
  1127. // nonblocking send until a send possible indication
  1128. // arrives.
  1129. //
  1130. // For bufferring endpoints (TDI provider does not
  1131. // buffer), check whether we have too much send data
  1132. // outstanding.
  1133. //
  1134. if ( (IS_DGRAM_ENDPOINT(endpoint) &&
  1135. (endpoint->DgBufferredSendBytes <
  1136. endpoint->Common.Datagram.MaxBufferredSendBytes ||
  1137. endpoint->DgBufferredSendBytes == 0))
  1138. ||
  1139. ((connection!=NULL) &&
  1140. (( IS_TDI_BUFFERRING(endpoint) &&
  1141. connection->VcNonBlockingSendPossible )
  1142. ||
  1143. ( !IS_TDI_BUFFERRING(endpoint) &&
  1144. (connection->VcBufferredSendBytes <
  1145. connection->MaxBufferredSendBytes ||
  1146. connection->VcBufferredSendBytes == 0))
  1147. ||
  1148. connection->AbortIndicated )) ){
  1149. pollHandleInfo->Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1150. pollHandleInfo->PollEvents |= AFD_POLL_SEND;
  1151. found = TRUE;
  1152. }
  1153. }
  1154. }
  1155. if ( (pollEndpointInfo->PollEvents & AFD_POLL_ACCEPT) != 0 ) {
  1156. if ( (endpoint->Type & AfdBlockTypeVcListening) == AfdBlockTypeVcListening &&
  1157. !IsListEmpty( &endpoint->Common.VcListening.UnacceptedConnectionListHead ) ) {
  1158. pollHandleInfo->Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1159. pollHandleInfo->PollEvents |= AFD_POLL_ACCEPT;
  1160. found = TRUE;
  1161. }
  1162. }
  1163. if ( (pollEndpointInfo->PollEvents & AFD_POLL_CONNECT) != 0 ) {
  1164. //
  1165. // If the endpoint is now connected, complete this event.
  1166. //
  1167. if ( endpoint->State == AfdEndpointStateConnected ) {
  1168. ASSERT( NT_SUCCESS(endpoint->EventStatus[AFD_POLL_CONNECT_FAIL_BIT]) );
  1169. pollHandleInfo->Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1170. pollHandleInfo->PollEvents |= AFD_POLL_CONNECT;
  1171. found = TRUE;
  1172. }
  1173. }
  1174. if ( (pollEndpointInfo->PollEvents & AFD_POLL_CONNECT_FAIL) != 0 ) {
  1175. //
  1176. // This is a poll to see whether a connect has failed
  1177. // recently. The connect status must indicate an error.
  1178. //
  1179. if ( endpoint->State == AfdEndpointStateBound &&
  1180. !NT_SUCCESS(endpoint->EventStatus[AFD_POLL_CONNECT_FAIL_BIT]) ) {
  1181. pollHandleInfo->Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1182. pollHandleInfo->PollEvents |= AFD_POLL_CONNECT_FAIL;
  1183. pollHandleInfo->Status =
  1184. endpoint->EventStatus[AFD_POLL_CONNECT_FAIL_BIT];
  1185. found = TRUE;
  1186. }
  1187. }
  1188. if ( (pollEndpointInfo->PollEvents & AFD_POLL_DISCONNECT) != 0 ) {
  1189. if ( connection != NULL && connection->DisconnectIndicated ) {
  1190. pollHandleInfo->Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1191. pollHandleInfo->PollEvents |= AFD_POLL_DISCONNECT;
  1192. found = TRUE;
  1193. }
  1194. }
  1195. if ( (pollEndpointInfo->PollEvents & AFD_POLL_ABORT) != 0 ) {
  1196. if ( connection != NULL && connection->AbortIndicated ) {
  1197. pollHandleInfo->Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1198. pollHandleInfo->PollEvents |= AFD_POLL_ABORT;
  1199. found = TRUE;
  1200. }
  1201. }
  1202. AfdReleaseSpinLockFromDpcLevel (&endpoint->SpinLock, &endpointLockHandle);
  1203. //
  1204. // If the handle had a current event that was requested, update
  1205. // the count of handles in the output buffer and increment the
  1206. // pointer to the output buffer.
  1207. //
  1208. if ( found ) {
  1209. pollInfo->NumberOfHandles++;
  1210. pollHandleInfo++;
  1211. }
  1212. pollEndpointInfo++;
  1213. }
  1214. //
  1215. // If we found any endpoints that are ready, free the poll information
  1216. // structure and complete the request.
  1217. //
  1218. if ( pollInfo->NumberOfHandles > 0 ) {
  1219. AfdReleaseSpinLock( &AfdPollListLock, &pollLockHandle );
  1220. AfdFreePollInfo( pollInfoInternal );
  1221. Irp->IoStatus.Information = (PUCHAR)pollHandleInfo - (PUCHAR)pollInfo;
  1222. status = STATUS_SUCCESS;
  1223. goto complete;
  1224. }
  1225. //
  1226. // None of the endpoints are in the correct state. If a timeout was
  1227. // specified, place the poll information on the global list and set
  1228. // up a DPC and timer so that we know when to complete the IRP.
  1229. //
  1230. if ( pollInfo->Timeout.LowPart != 0 && pollInfo->Timeout.HighPart != 0 ) {
  1231. IF_DEBUG(POLL) {
  1232. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1233. "AfdPoll32: no current events for poll IRP %p, "
  1234. "info %p\n", Irp, pollInfoInternal ));
  1235. }
  1236. //
  1237. // Set up the information field of the IO status block to indicate
  1238. // that an output buffer with no handles should be returned.
  1239. // AfdIndicatePollEvent will modify this if necessary.
  1240. //
  1241. Irp->IoStatus.Information = (PUCHAR)pollHandleInfo - (PUCHAR)pollInfo;
  1242. //
  1243. // Put a pointer to the internal poll info struct into the IRP
  1244. // so that the cancel routine can find it.
  1245. //
  1246. IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = pollInfoInternal;
  1247. //
  1248. // Place the internal poll info struct on the global list.
  1249. //
  1250. InsertTailList( &AfdPollListHead, &pollInfoInternal->PollListEntry );
  1251. //
  1252. // If the timeout is infinite, then don't set up a timer and
  1253. // DPC. Otherwise, set up a timer so we can timeout the poll
  1254. // request if appropriate.
  1255. //
  1256. if ( pollInfo->Timeout.HighPart != 0x7FFFFFFF ) {
  1257. pollInfoInternal->TimerStarted = TRUE;
  1258. KeInitializeDpc(
  1259. &pollInfoInternal->Dpc,
  1260. AfdTimeoutPoll,
  1261. pollInfoInternal
  1262. );
  1263. KeInitializeTimer( &pollInfoInternal->Timer );
  1264. KeSetTimer(
  1265. &pollInfoInternal->Timer,
  1266. pollInfo->Timeout,
  1267. &pollInfoInternal->Dpc
  1268. );
  1269. } else {
  1270. pollInfoInternal->TimerStarted = FALSE;
  1271. }
  1272. } else {
  1273. //
  1274. // A timeout equal to 0 was specified; free the internal
  1275. // structure and complete the request with no endpoints in the
  1276. // output buffer.
  1277. //
  1278. IF_DEBUG(POLL) {
  1279. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1280. "AfdPoll32: zero timeout on poll IRP %p and no "
  1281. "current events--completing.\n", Irp ));
  1282. }
  1283. AfdReleaseSpinLock( &AfdPollListLock, &pollLockHandle );
  1284. AfdFreePollInfo( pollInfoInternal );
  1285. Irp->IoStatus.Information = (PUCHAR)pollHandleInfo - (PUCHAR)pollInfo;
  1286. status = STATUS_SUCCESS;
  1287. goto complete;
  1288. }
  1289. //
  1290. // Mark the IRP pending and release the spin locks. At this
  1291. // point the IRP may get completed or cancelled.
  1292. //
  1293. IoMarkIrpPending( Irp );
  1294. AfdReleaseSpinLock( &AfdPollListLock, &pollLockHandle );
  1295. //
  1296. // Complete any old poll irps.
  1297. //
  1298. if ( oldIrp != NULL ) {
  1299. //
  1300. // If we need to free a cancelled poll info structure, do it now.
  1301. //
  1302. if ( freePollInfo != NULL ) {
  1303. AfdFreePollInfo( freePollInfo );
  1304. }
  1305. if (IoSetCancelRoutine( oldIrp, NULL ) == NULL) {
  1306. KIRQL cancelIrql;
  1307. //
  1308. // If the cancel routine was NULL then cancel routine
  1309. // may be running. Wait on the cancel spinlock until
  1310. // the cancel routine is done.
  1311. //
  1312. // Note: The cancel routine will not find the IRP
  1313. // since it is not in the list.
  1314. //
  1315. IoAcquireCancelSpinLock( &cancelIrql );
  1316. ASSERT( oldIrp->Cancel );
  1317. IoReleaseCancelSpinLock( cancelIrql );
  1318. }
  1319. IoCompleteRequest( oldIrp, AfdPriorityBoost );
  1320. }
  1321. //
  1322. // Return pending. The IRP will be completed when an appropriate
  1323. // event is indicated by the TDI provider, when the timeout is hit,
  1324. // or when the IRP is cancelled.
  1325. //
  1326. return STATUS_PENDING;
  1327. complete:
  1328. //
  1329. // Complete any old poll irps.
  1330. //
  1331. if ( oldIrp != NULL ) {
  1332. //
  1333. // If we need to free a cancelled poll info structure, do it now.
  1334. //
  1335. if ( freePollInfo != NULL ) {
  1336. AfdFreePollInfo( freePollInfo );
  1337. }
  1338. if (IoSetCancelRoutine( oldIrp, NULL ) == NULL) {
  1339. KIRQL cancelIrql;
  1340. //
  1341. // If the cancel routine was NULL then cancel routine
  1342. // may be running. Wait on the cancel spinlock until
  1343. // the cancel routine is done.
  1344. //
  1345. // Note: The cancel routine will not find the IRP
  1346. // since it is not in the list.
  1347. //
  1348. IoAcquireCancelSpinLock( &cancelIrql );
  1349. ASSERT( oldIrp->Cancel );
  1350. IoReleaseCancelSpinLock( cancelIrql );
  1351. }
  1352. IoCompleteRequest( oldIrp, AfdPriorityBoost );
  1353. }
  1354. Irp->IoStatus.Status = status;
  1355. if (IoSetCancelRoutine( Irp, NULL ) == NULL) {
  1356. KIRQL cancelIrql;
  1357. //
  1358. // If the cancel routine was NULL then cancel routine
  1359. // may be running. Wait on the cancel spinlock until
  1360. // the cancel routine is done.
  1361. //
  1362. // Note: The cancel routine will not find the IRP
  1363. // since it is not in the list.
  1364. //
  1365. IoAcquireCancelSpinLock( &cancelIrql );
  1366. // ASSERT( Irp->Cancel ); the cancel routine may have not been set
  1367. IoReleaseCancelSpinLock( cancelIrql );
  1368. }
  1369. IoCompleteRequest( Irp, AfdPriorityBoost );
  1370. return status;
  1371. } // AfdPoll32
  1372. #endif //_WIN64
  1373. VOID
  1374. AfdCancelPoll (
  1375. IN PDEVICE_OBJECT DeviceObject,
  1376. IN PIRP Irp
  1377. )
  1378. {
  1379. PAFD_POLL_INFO_INTERNAL pollInfoInternal;
  1380. PLIST_ENTRY listEntry;
  1381. BOOLEAN found = FALSE;
  1382. BOOLEAN timerCancelSucceeded;
  1383. PIO_STACK_LOCATION irpSp;
  1384. AFD_LOCK_QUEUE_HANDLE lockHandle;
  1385. irpSp = IoGetCurrentIrpStackLocation( Irp );
  1386. pollInfoInternal =
  1387. (PAFD_POLL_INFO_INTERNAL)irpSp->Parameters.DeviceIoControl.Type3InputBuffer;
  1388. IF_DEBUG(POLL) {
  1389. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1390. "AfdCancelPoll called for IRP %p\n", Irp ));
  1391. }
  1392. //
  1393. // Get the AFD spin lock and attempt to find the poll structure on
  1394. // the list of outstanding polls.
  1395. // Note the afdspinlock must be acquired befor the cancel spinlock
  1396. // is released so that the pollInfoInternal does not get reused
  1397. // before we have had a chance to look at the queue.
  1398. //
  1399. AfdAcquireSpinLockAtDpcLevel( &AfdPollListLock, &lockHandle);
  1400. for ( listEntry = AfdPollListHead.Flink;
  1401. listEntry != &AfdPollListHead;
  1402. listEntry = listEntry->Flink ) {
  1403. PAFD_POLL_INFO_INTERNAL testInfo;
  1404. testInfo = CONTAINING_RECORD(
  1405. listEntry,
  1406. AFD_POLL_INFO_INTERNAL,
  1407. PollListEntry
  1408. );
  1409. if ( testInfo == pollInfoInternal ) {
  1410. found = TRUE;
  1411. break;
  1412. }
  1413. }
  1414. //
  1415. // If we didn't find the poll structure on the list, then the
  1416. // indication handler got called prior to the spinlock acquisition
  1417. // above and it is already off the list. Just return and do
  1418. // nothing, as the indication handler completed the IRP.
  1419. //
  1420. if ( !found ) {
  1421. AfdReleaseSpinLockFromDpcLevel( &AfdPollListLock, &lockHandle);
  1422. IoReleaseCancelSpinLock( Irp->CancelIrql );
  1423. IF_DEBUG(POLL) {
  1424. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1425. "AfdCancelPoll: poll info %p not found on list.\n",
  1426. pollInfoInternal ));
  1427. }
  1428. return;
  1429. }
  1430. //
  1431. // Remove the poll structure from the global list.
  1432. //
  1433. IF_DEBUG(POLL) {
  1434. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1435. "AfdCancelPoll: poll info %p found on list, completing.\n",
  1436. pollInfoInternal ));
  1437. }
  1438. RemoveEntryList( &pollInfoInternal->PollListEntry );
  1439. //
  1440. // Cancel the timer and reset the IRP pointer in the internal
  1441. // poll information structure. NULLing the IRP field
  1442. // prevents the timer routine from completing the IRP.
  1443. //
  1444. if ( pollInfoInternal->TimerStarted ) {
  1445. timerCancelSucceeded = KeCancelTimer( &pollInfoInternal->Timer );
  1446. } else {
  1447. timerCancelSucceeded = TRUE;
  1448. }
  1449. //
  1450. // Complete the IRP with STATUS_CANCELLED as the status.
  1451. //
  1452. Irp->IoStatus.Information = 0;
  1453. Irp->IoStatus.Status = STATUS_CANCELLED;
  1454. AfdReleaseSpinLockFromDpcLevel( &AfdPollListLock, &lockHandle);
  1455. IoReleaseCancelSpinLock( Irp->CancelIrql );
  1456. if (timerCancelSucceeded) {
  1457. if (pollInfoInternal->SanPoll &&
  1458. (Irp->CancelIrql>APC_LEVEL ||
  1459. (Irp->Tail.Overlay.Thread!=PsGetCurrentThread ()))) {
  1460. KeInitializeApc (&pollInfoInternal->Apc,
  1461. PsGetThreadTcb (Irp->Tail.Overlay.Thread),
  1462. Irp->ApcEnvironment,
  1463. AfdSanPollApcKernelRoutine,
  1464. AfdSanPollApcRundownRoutine,
  1465. (PKNORMAL_ROUTINE)-1,
  1466. KernelMode,
  1467. NULL);
  1468. if (KeInsertQueueApc (&pollInfoInternal->Apc,
  1469. pollInfoInternal,
  1470. Irp,
  1471. AfdPriorityBoost)) {
  1472. return ;
  1473. }
  1474. else {
  1475. pollInfoInternal->SanPoll = FALSE;
  1476. }
  1477. }
  1478. //
  1479. // Free the poll information structure if the cancel succeeded. If
  1480. // the cancel of the timer did not succeed, then the timer is
  1481. // already running and the timer DPC will free the internal
  1482. // poll info.
  1483. //
  1484. AfdFreePollInfo( pollInfoInternal );
  1485. IoCompleteRequest( Irp, AfdPriorityBoost );
  1486. }
  1487. return;
  1488. } // AfdCancelPoll
  1489. VOID
  1490. AfdFreePollInfo (
  1491. IN PAFD_POLL_INFO_INTERNAL PollInfoInternal
  1492. )
  1493. {
  1494. ULONG i;
  1495. PAFD_POLL_ENDPOINT_INFO pollEndpointInfo;
  1496. IF_DEBUG(POLL) {
  1497. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1498. "AfdFreePollInfo: freeing info struct at %p\n",
  1499. PollInfoInternal ));
  1500. }
  1501. // *** Note that this routine does not remove the poll information
  1502. // structure from the global list--that is the responsibility
  1503. // of the caller!
  1504. //
  1505. // Walk the list of endpoints in the poll information structure and
  1506. // dereference each one.
  1507. //
  1508. pollEndpointInfo = PollInfoInternal->EndpointInfo;
  1509. for ( i = 0; i < PollInfoInternal->NumberOfEndpoints; i++ ) {
  1510. ASSERT( InterlockedDecrement( &pollEndpointInfo->Endpoint->ObReferenceBias ) >= 0 );
  1511. if (PollInfoInternal->SanPoll) {
  1512. ASSERT (PollInfoInternal->Irp!=NULL);
  1513. ASSERT (PsGetCurrentThread ()==PollInfoInternal->Irp->Tail.Overlay.Thread);
  1514. if (pollEndpointInfo->PollEvents & AFD_POLL_SANCOUNTS_UPDATED) {
  1515. ASSERT (IS_SAN_ENDPOINT (pollEndpointInfo->Endpoint));
  1516. AfdSanPollEnd (pollEndpointInfo->Endpoint,
  1517. pollEndpointInfo->PollEvents);
  1518. }
  1519. }
  1520. DEREFERENCE_ENDPOINT( pollEndpointInfo->Endpoint );
  1521. ObDereferenceObject( pollEndpointInfo->FileObject );
  1522. pollEndpointInfo++;
  1523. }
  1524. //
  1525. // Free the structure itself and return.
  1526. //
  1527. AFD_FREE_POOL(
  1528. PollInfoInternal,
  1529. AFD_POLL_POOL_TAG
  1530. );
  1531. return;
  1532. } // AfdFreePollInfo
  1533. VOID
  1534. AfdIndicatePollEventReal (
  1535. IN PAFD_ENDPOINT Endpoint,
  1536. IN ULONG PollEventMask,
  1537. IN NTSTATUS Status
  1538. )
  1539. /*++
  1540. Routine Description:
  1541. Called to complete polls with a specific event or events.
  1542. Arguments:
  1543. Endpoint - the endpoint on which the action occurred.
  1544. PollEventMask - the mask of the events which occurred.
  1545. Status - the status of the event, if any.
  1546. Return Value:
  1547. None.
  1548. --*/
  1549. {
  1550. LIST_ENTRY completePollListHead;
  1551. PLIST_ENTRY listEntry;
  1552. AFD_LOCK_QUEUE_HANDLE lockHandle;
  1553. PAFD_POLL_INFO_INTERNAL pollInfoInternal;
  1554. union {
  1555. PAFD_POLL_INFO PollInfo;
  1556. PAFD_POLL_INFO32 PollInfo32;
  1557. } u;
  1558. #define pollInfo u.PollInfo
  1559. #define pollInfo32 u.PollInfo32
  1560. PIRP irp;
  1561. PIO_STACK_LOCATION irpSp;
  1562. ASSERT (PollEventMask!=0);
  1563. ASSERT (((~((1<<AFD_NUM_POLL_EVENTS)-1)) & PollEventMask)==0);
  1564. //
  1565. // Note that AFD_POLL_ABORT implies AFD_POLL_SEND.
  1566. //
  1567. if( PollEventMask & AFD_POLL_ABORT ) {
  1568. PollEventMask |= AFD_POLL_SEND;
  1569. }
  1570. //
  1571. // Initialize the list of poll info structures that we'll be
  1572. // completing for this event.
  1573. //
  1574. InitializeListHead( &completePollListHead );
  1575. //
  1576. // Walk the global list of polls, searching for any the are waiting
  1577. // for the specified event on the specified endpoint.
  1578. //
  1579. AfdAcquireSpinLock( &AfdPollListLock, &lockHandle );
  1580. for ( listEntry = AfdPollListHead.Flink;
  1581. listEntry != &AfdPollListHead;
  1582. listEntry = listEntry->Flink ) {
  1583. PAFD_POLL_ENDPOINT_INFO pollEndpointInfo;
  1584. ULONG i;
  1585. ULONG foundCount = 0;
  1586. pollInfoInternal = CONTAINING_RECORD(
  1587. listEntry,
  1588. AFD_POLL_INFO_INTERNAL,
  1589. PollListEntry
  1590. );
  1591. pollInfo = pollInfoInternal->Irp->AssociatedIrp.SystemBuffer;
  1592. irp = pollInfoInternal->Irp;
  1593. irpSp = IoGetCurrentIrpStackLocation( irp );
  1594. IF_DEBUG(POLL) {
  1595. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1596. "AfdIndicatePollEvent: pollInfoInt %p "
  1597. "IRP %p pollInfo %p event mask %lx status %lx\n",
  1598. pollInfoInternal, irp, pollInfo,
  1599. PollEventMask, Status ));
  1600. }
  1601. //
  1602. // Walk the poll structure looking for matching endpoints.
  1603. //
  1604. pollEndpointInfo = pollInfoInternal->EndpointInfo;
  1605. for ( i = 0; i < pollInfoInternal->NumberOfEndpoints; i++ ) {
  1606. IF_DEBUG(POLL) {
  1607. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1608. "AfdIndicatePollEvent: pollEndpointInfo = %p, "
  1609. "comparing %p, %p\n",
  1610. pollEndpointInfo, pollEndpointInfo->Endpoint,
  1611. Endpoint ));
  1612. }
  1613. //
  1614. // Update the counts for the polls that were issued before
  1615. // the endpoint was converted to SAN.
  1616. //
  1617. if (Endpoint==pollEndpointInfo->Endpoint &&
  1618. IS_SAN_ENDPOINT (Endpoint) &&
  1619. !(pollEndpointInfo->PollEvents & AFD_POLL_SANCOUNTS_UPDATED) &&
  1620. Endpoint->Common.SanEndp.LocalContext!=NULL) {
  1621. AfdSanPollUpdate (Endpoint, pollEndpointInfo->PollEvents);
  1622. pollEndpointInfo->PollEvents |= AFD_POLL_SANCOUNTS_UPDATED;
  1623. }
  1624. //
  1625. // Regardless of whether the caller requested to be told about
  1626. // local closes, we'll complete the IRP if an endpoint
  1627. // is being closed. When they close an endpoint, all IO on
  1628. // the endpoint must be completed.
  1629. //
  1630. if ( Endpoint == pollEndpointInfo->Endpoint &&
  1631. ( (PollEventMask & pollEndpointInfo->PollEvents) != 0
  1632. ||
  1633. (PollEventMask & AFD_POLL_LOCAL_CLOSE) ) ) {
  1634. #ifdef _WIN64
  1635. if (IoIs32bitProcess (irp)) {
  1636. ASSERT( pollInfo32->NumberOfHandles == foundCount );
  1637. IF_DEBUG(POLL) {
  1638. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1639. "AfdIndicatePollEvent32: endpoint %p found "
  1640. " for event %lx\n",
  1641. pollEndpointInfo->Endpoint, PollEventMask ));
  1642. }
  1643. pollInfo32->NumberOfHandles++;
  1644. pollInfo32->Handles[foundCount].Handle = (VOID * POINTER_32)pollEndpointInfo->Handle;
  1645. pollInfo32->Handles[foundCount].PollEvents =
  1646. (PollEventMask &
  1647. (pollEndpointInfo->PollEvents | AFD_POLL_LOCAL_CLOSE));
  1648. pollInfo32->Handles[foundCount].Status = Status;
  1649. }
  1650. else
  1651. #endif // _WIN64
  1652. {
  1653. ASSERT( pollInfo->NumberOfHandles == foundCount );
  1654. IF_DEBUG(POLL) {
  1655. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1656. "AfdIndicatePollEvent: endpoint %p found "
  1657. " for event %lx\n",
  1658. pollEndpointInfo->Endpoint, PollEventMask ));
  1659. }
  1660. pollInfo->NumberOfHandles++;
  1661. pollInfo->Handles[foundCount].Handle = pollEndpointInfo->Handle;
  1662. pollInfo->Handles[foundCount].PollEvents =
  1663. (PollEventMask &
  1664. (pollEndpointInfo->PollEvents | AFD_POLL_LOCAL_CLOSE));
  1665. pollInfo->Handles[foundCount].Status = Status;
  1666. }
  1667. foundCount++;
  1668. }
  1669. pollEndpointInfo++;
  1670. }
  1671. //
  1672. // If we found any matching endpoints, remove the poll information
  1673. // structure from the global list, complete the IRP, and free the
  1674. // poll information structure.
  1675. //
  1676. if ( foundCount != 0 ) {
  1677. BOOLEAN timerCancelSucceeded;
  1678. //
  1679. // We need to release the spin lock to call AfdFreePollInfo,
  1680. // since it calls AfdDereferenceEndpoint which in turn needs
  1681. // to acquire the spin lock, and recursive spin lock
  1682. // acquisitions result in deadlock. However, we can't
  1683. // release the lock of else the state of the poll list could
  1684. // change, e.g. the next entry could get freed. Remove
  1685. // this entry from the global list and place it on a local
  1686. // list. We'll complete all the poll IRPs after walking
  1687. // the entire list.
  1688. //
  1689. RemoveEntryList( &pollInfoInternal->PollListEntry );
  1690. //
  1691. // Set up the IRP for completion now, since we have all needed
  1692. // information here.
  1693. //
  1694. #ifdef _WIN64
  1695. if (IoIs32bitProcess (irp)) {
  1696. irp->IoStatus.Information =
  1697. (PUCHAR)&pollInfo32->Handles[foundCount] - (PUCHAR)pollInfo32;
  1698. }
  1699. else
  1700. #endif
  1701. {
  1702. irp->IoStatus.Information =
  1703. (PUCHAR)&pollInfo->Handles[foundCount] - (PUCHAR)pollInfo;
  1704. }
  1705. irp->IoStatus.Status = STATUS_SUCCESS;
  1706. //
  1707. // Cancel the timer on the poll so that it does not fire.
  1708. //
  1709. if ( pollInfoInternal->TimerStarted ) {
  1710. timerCancelSucceeded = KeCancelTimer( &pollInfoInternal->Timer );
  1711. } else {
  1712. timerCancelSucceeded = TRUE;
  1713. }
  1714. //
  1715. // If the cancel of the timer failed, then we don't want to
  1716. // free this structure since the timer routine is running.
  1717. // Let the timer routine free the structure.
  1718. //
  1719. if ( timerCancelSucceeded ) {
  1720. InsertTailList(
  1721. &completePollListHead,
  1722. &irp->Tail.Overlay.ListEntry
  1723. );
  1724. }
  1725. }
  1726. }
  1727. AfdReleaseSpinLock( &AfdPollListLock, &lockHandle );
  1728. //
  1729. // Now walk the list of polls we need to actually complete. Free
  1730. // the poll info structures as we go.
  1731. //
  1732. while ( !IsListEmpty( &completePollListHead ) ) {
  1733. listEntry = RemoveHeadList( &completePollListHead );
  1734. ASSERT( listEntry != &completePollListHead );
  1735. irp = CONTAINING_RECORD(
  1736. listEntry,
  1737. IRP,
  1738. Tail.Overlay.ListEntry
  1739. );
  1740. irpSp = IoGetCurrentIrpStackLocation( irp );
  1741. pollInfoInternal =
  1742. irpSp->Parameters.DeviceIoControl.Type3InputBuffer;
  1743. if (IoSetCancelRoutine( irp, NULL ) == NULL) {
  1744. KIRQL cancelIrql;
  1745. //
  1746. // If the cancel routine was NULL then cancel routine
  1747. // may be running. Wait on the cancel spinlock until
  1748. // the cancel routine is done.
  1749. //
  1750. // Note: The cancel routine will not find the IRP
  1751. // since it is not in the list.
  1752. //
  1753. IoAcquireCancelSpinLock( &cancelIrql );
  1754. ASSERT( irp->Cancel );
  1755. IoReleaseCancelSpinLock( cancelIrql );
  1756. }
  1757. if (pollInfoInternal->SanPoll &&
  1758. ((irp->Tail.Overlay.Thread!=PsGetCurrentThread ()) ||
  1759. (KeGetCurrentIrql() > APC_LEVEL)) ) {
  1760. KeInitializeApc (&pollInfoInternal->Apc,
  1761. PsGetThreadTcb (irp->Tail.Overlay.Thread),
  1762. irp->ApcEnvironment,
  1763. AfdSanPollApcKernelRoutine,
  1764. AfdSanPollApcRundownRoutine,
  1765. (PKNORMAL_ROUTINE)-1,
  1766. KernelMode,
  1767. NULL);
  1768. if (KeInsertQueueApc (&pollInfoInternal->Apc,
  1769. pollInfoInternal,
  1770. irp,
  1771. AfdPriorityBoost)) {
  1772. continue ;
  1773. }
  1774. else {
  1775. pollInfoInternal->SanPoll = FALSE;
  1776. }
  1777. }
  1778. //
  1779. // Free the poll info structure.
  1780. //
  1781. AfdFreePollInfo( pollInfoInternal );
  1782. IoCompleteRequest( irp, AfdPriorityBoost );
  1783. }
  1784. return;
  1785. } // AfdIndicatePollEvent
  1786. VOID
  1787. AfdTimeoutPoll (
  1788. IN PKDPC Dpc,
  1789. IN PVOID DeferredContext,
  1790. IN PVOID SystemArgument1,
  1791. IN PVOID SystemArgument2
  1792. )
  1793. {
  1794. PAFD_POLL_INFO_INTERNAL pollInfoInternal = DeferredContext;
  1795. PIRP irp;
  1796. PLIST_ENTRY listEntry;
  1797. AFD_LOCK_QUEUE_HANDLE lockHandle;
  1798. //
  1799. // Get the AFD spin lock and attempt to find the poll structure on
  1800. // the list of outstanding polls.
  1801. //
  1802. AfdAcquireSpinLock( &AfdPollListLock, &lockHandle );
  1803. for ( listEntry = AfdPollListHead.Flink;
  1804. listEntry != &AfdPollListHead;
  1805. listEntry = listEntry->Flink ) {
  1806. PAFD_POLL_INFO_INTERNAL testInfo;
  1807. testInfo = CONTAINING_RECORD(
  1808. listEntry,
  1809. AFD_POLL_INFO_INTERNAL,
  1810. PollListEntry
  1811. );
  1812. if ( testInfo == pollInfoInternal ) {
  1813. //
  1814. // Remove the poll structure from the global list.
  1815. //
  1816. IF_DEBUG(POLL) {
  1817. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL, "AfdTimeoutPoll: poll info %p found on list, completing.\n",
  1818. pollInfoInternal ));
  1819. }
  1820. RemoveEntryList( &pollInfoInternal->PollListEntry );
  1821. break;
  1822. }
  1823. }
  1824. ASSERT( pollInfoInternal->TimerStarted );
  1825. //
  1826. // If we didn't find the poll structure on the list, then the
  1827. // indication handler got called prior to the spinlock acquisition
  1828. // above and it is already off the list. It must have setup
  1829. // the IRP completion code already.
  1830. //
  1831. // We must free the internal information structure in this case,
  1832. // since the indication handler will not free it. The indication
  1833. // handler cannot free the structure because the structure contains
  1834. // the timer object, which must remain intact until this routine
  1835. // is entered.
  1836. //
  1837. //
  1838. // The IRP should not have been completed at this point.
  1839. //
  1840. ASSERT( pollInfoInternal->Irp != NULL );
  1841. irp = pollInfoInternal->Irp;
  1842. //
  1843. // Remove the poll structure from the global list.
  1844. //
  1845. IF_DEBUG(POLL) {
  1846. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_TRACE_LEVEL,
  1847. "AfdTimeoutPoll: poll info %p found on list, completing.\n",
  1848. pollInfoInternal ));
  1849. }
  1850. AfdReleaseSpinLock( &AfdPollListLock, &lockHandle );
  1851. //
  1852. // Complete the IRP pointed to in the poll structure. The
  1853. // Information field has already been set up by AfdPoll, as well as
  1854. // the output buffer.
  1855. //
  1856. if (IoSetCancelRoutine( irp, NULL ) == NULL) {
  1857. KIRQL cancelIrql;
  1858. //
  1859. // If the cancel routine was NULL then cancel routine
  1860. // may be running. Wait on the cancel spinlock until
  1861. // the cancel routine is done.
  1862. //
  1863. // Note: The cancel routine will not find the IRP
  1864. // since it is not in the list.
  1865. //
  1866. IoAcquireCancelSpinLock( &cancelIrql );
  1867. ASSERT( irp->Cancel );
  1868. IoReleaseCancelSpinLock( cancelIrql );
  1869. }
  1870. if (pollInfoInternal->SanPoll) {
  1871. KeInitializeApc (&pollInfoInternal->Apc,
  1872. PsGetThreadTcb (irp->Tail.Overlay.Thread),
  1873. irp->ApcEnvironment,
  1874. AfdSanPollApcKernelRoutine,
  1875. AfdSanPollApcRundownRoutine,
  1876. (PKNORMAL_ROUTINE)-1,
  1877. KernelMode,
  1878. NULL);
  1879. if (KeInsertQueueApc (&pollInfoInternal->Apc,
  1880. pollInfoInternal,
  1881. irp,
  1882. AfdPriorityBoost)) {
  1883. return;
  1884. }
  1885. else {
  1886. pollInfoInternal->SanPoll = FALSE;
  1887. }
  1888. }
  1889. IoCompleteRequest( irp, AfdPriorityBoost );
  1890. //
  1891. // Free the poll information structure.
  1892. //
  1893. AfdFreePollInfo( pollInfoInternal );
  1894. return;
  1895. } // AfdTimeoutPoll
  1896. VOID
  1897. AfdSanPollApcKernelRoutine (
  1898. IN struct _KAPC *Apc,
  1899. IN OUT PKNORMAL_ROUTINE *NormalRoutine,
  1900. IN OUT PVOID *NormalContext,
  1901. IN OUT PVOID *SystemArgument1,
  1902. IN OUT PVOID *SystemArgument2
  1903. )
  1904. /*++
  1905. Routine Description:
  1906. Special kernel apc routine. Executed in the context of
  1907. the target thread at APC_LEVEL
  1908. Arguments:
  1909. NormalRoutine - pointer containing address of normal routine (it will
  1910. be NULL for special kernel APC and not NULL for normal
  1911. kernel APC)
  1912. SystemArgument1 - pointer to the address of worker routine to execute
  1913. SyetemArgument2 - pointer to the argument to pass to worker routine
  1914. Return Value:
  1915. None.
  1916. --*/
  1917. {
  1918. PAFD_POLL_INFO_INTERNAL pollInfoInternal;
  1919. PIRP irp;
  1920. PAGED_CODE ();
  1921. pollInfoInternal = *SystemArgument1;
  1922. irp = *SystemArgument2;
  1923. ASSERT (pollInfoInternal->Irp==irp);
  1924. //
  1925. // Normal APC, but we are requested to run in its special
  1926. // routine which avoids raising and lowering IRQL
  1927. //
  1928. ASSERT (*NormalRoutine==(PKNORMAL_ROUTINE)-1);
  1929. *NormalRoutine = NULL;
  1930. AfdFreePollInfo (pollInfoInternal);
  1931. IoCompleteRequest (irp, IO_NO_INCREMENT);
  1932. }
  1933. VOID
  1934. AfdSanPollApcRundownRoutine (
  1935. IN struct _KAPC *Apc
  1936. )
  1937. /*++
  1938. Routine Description:
  1939. APC rundown routine. Executed if APC cannot be delivered for
  1940. some reason (thread exiting).
  1941. Arguments:
  1942. Apc - APC structure
  1943. Return Value:
  1944. None.
  1945. --*/
  1946. {
  1947. PAFD_POLL_INFO_INTERNAL pollInfoInternal;
  1948. PIRP irp;
  1949. PAGED_CODE ();
  1950. pollInfoInternal = Apc->SystemArgument1;
  1951. irp = Apc->SystemArgument2;
  1952. ASSERT (pollInfoInternal->Irp==irp);
  1953. AfdFreePollInfo (pollInfoInternal);
  1954. IoCompleteRequest (irp, IO_NO_INCREMENT);
  1955. }