ReactOS 0.4.17-dev-966-gf06eace
read.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/net/afd/afd/read.c
5 * PURPOSE: Ancillary functions driver
6 * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
7 * UPDATE HISTORY:
8 * 20040708 Created
9 */
10
11#include "afd.h"
12
14{
15 /* Make sure nothing's in flight first */
16 if (FCB->ReceiveIrp.InFlightRequest) return;
17
18 /* Now ensure that receive is still allowed */
19 if (FCB->TdiReceiveClosed) return;
20
21 /* Check if the buffer is full */
22 if (FCB->Recv.Content == FCB->Recv.Size)
23 {
24 /* If there are bytes used, we can solve this problem */
25 if (FCB->Recv.BytesUsed != 0)
26 {
27 /* Reposition the unused portion to the beginning of the receive window */
28 RtlMoveMemory(FCB->Recv.Window,
29 FCB->Recv.Window + FCB->Recv.BytesUsed,
30 FCB->Recv.Content - FCB->Recv.BytesUsed);
31
32 FCB->Recv.Content -= FCB->Recv.BytesUsed;
33 FCB->Recv.BytesUsed = 0;
34 }
35 else
36 {
37 /* No space in the buffer to receive */
38 return;
39 }
40 }
41
42 AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
43
44 TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
45 FCB->Connection.Object,
47 FCB->Recv.Window + FCB->Recv.Content,
48 FCB->Recv.Size - FCB->Recv.Content,
50 FCB );
51}
52
54{
55 FCB->LastReceiveStatus = Status;
56
57 /* We got closed while the receive was in progress */
58 if (FCB->TdiReceiveClosed)
59 {
60 /* The received data is discarded */
61 }
62 /* Receive successful */
63 else if (Status == STATUS_SUCCESS)
64 {
65 FCB->Recv.Content += Information;
66 ASSERT(FCB->Recv.Content <= FCB->Recv.Size);
67
68 /* Check for graceful closure */
69 if (Information == 0)
70 {
71 /* Receive is closed */
72 FCB->TdiReceiveClosed = TRUE;
73 }
74 else
75 {
76 /* Issue another receive IRP to keep the buffer well stocked */
78 }
79 }
80 /* Receive failed with no data (unexpected closure) */
81 else
82 {
83 /* Previously received data remains intact */
84 FCB->TdiReceiveClosed = TRUE;
85 }
86}
87
89 UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
90
91 return !BytesAvailable && FCB->TdiReceiveClosed;
92}
93
95 PAFD_RECV_INFO RecvReq,
96 PUINT TotalBytesCopied ) {
97 UINT i, BytesToCopy = 0, FcbBytesCopied = FCB->Recv.BytesUsed,
98 BytesAvailable =
99 FCB->Recv.Content - FCB->Recv.BytesUsed;
100 PAFD_MAPBUF Map;
101 *TotalBytesCopied = 0;
102
103
104 AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %u\n", BytesAvailable));
105
106 if( CantReadMore(FCB) ) return STATUS_SUCCESS;
107 if( !BytesAvailable ) return STATUS_PENDING;
108
109 Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
110
111 AFD_DbgPrint(MID_TRACE,("Buffer Count: %u @ %p\n",
112 RecvReq->BufferCount,
113 RecvReq->BufferArray));
114 for( i = 0;
115 RecvReq->BufferArray &&
116 BytesAvailable &&
117 i < RecvReq->BufferCount;
118 i++ ) {
120 MIN( RecvReq->BufferArray[i].len, BytesAvailable );
121
122 if( Map[i].Mdl ) {
124
125 AFD_DbgPrint(MID_TRACE,("Buffer %u: %p:%u\n",
126 i,
127 Map[i].BufferAddress,
128 BytesToCopy));
129
131 FCB->Recv.Window + FcbBytesCopied,
132 BytesToCopy );
133
134 MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl );
135
136 *TotalBytesCopied += BytesToCopy;
137 FcbBytesCopied += BytesToCopy;
138 BytesAvailable -= BytesToCopy;
139
140 if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
141 FCB->Recv.BytesUsed += BytesToCopy;
142 }
143 }
144
145 /* Issue another receive IRP to keep the buffer well stocked */
147
148 return STATUS_SUCCESS;
149}
150
152 PLIST_ENTRY NextIrpEntry;
153 PIRP NextIrp;
154 PIO_STACK_LOCATION NextIrpSp;
155 PAFD_RECV_INFO RecvReq;
156 UINT TotalBytesCopied = 0;
158
159 AFD_DbgPrint(MID_TRACE,("%p %p\n", FCB, Irp));
160
161 AFD_DbgPrint(MID_TRACE,("FCB %p Receive data waiting %u\n",
162 FCB, FCB->Recv.Content));
163
164 if( CantReadMore( FCB ) ) {
165 /* Success here means that we got an EOF. Complete a pending read
166 * with zero bytes if we haven't yet overread, then kill the others.
167 */
168 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
169 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
170 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
171 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
172 RecvReq = GetLockedData(NextIrp, NextIrpSp);
173
174 AFD_DbgPrint(MID_TRACE,("Completing recv %p (%u)\n", NextIrp,
175 TotalBytesCopied));
176 UnlockBuffers( RecvReq->BufferArray,
177 RecvReq->BufferCount, FALSE );
178
179 /* Unexpected disconnect by the remote host or graceful disconnect */
180 Status = FCB->LastReceiveStatus;
181
182 NextIrp->IoStatus.Status = Status;
183 NextIrp->IoStatus.Information = 0;
184 if( NextIrp == Irp ) RetStatus = Status;
185 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
186 (void)IoSetCancelRoutine(NextIrp, NULL);
188 }
189 } else {
190 /* Kick the user that receive would be possible now */
191 /* XXX Not implemented yet */
192
193 AFD_DbgPrint(MID_TRACE,("FCB %p Receive data waiting %u\n",
194 FCB, FCB->Recv.Content));
195 /*OskitDumpBuffer( FCB->Recv.Window, FCB->Recv.Content );*/
196
197 /* Try to clear some requests */
198 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
199 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
200 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
201 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
202 RecvReq = GetLockedData(NextIrp, NextIrpSp);
203
204 AFD_DbgPrint(MID_TRACE,("RecvReq @ %p\n", RecvReq));
205
207 ( FCB, RecvReq, &TotalBytesCopied );
208
209 if( Status == STATUS_PENDING ) {
210 AFD_DbgPrint(MID_TRACE,("Ran out of data for %p\n", NextIrp));
211 InsertHeadList(&FCB->PendingIrpList[FUNCTION_RECV],
212 &NextIrp->Tail.Overlay.ListEntry);
213 break;
214 } else {
215 AFD_DbgPrint(MID_TRACE,("Completing recv %p (%u)\n", NextIrp,
216 TotalBytesCopied));
217 UnlockBuffers( RecvReq->BufferArray,
218 RecvReq->BufferCount, FALSE );
219 NextIrp->IoStatus.Status = Status;
220 NextIrp->IoStatus.Information = TotalBytesCopied;
221 if( NextIrp == Irp ) {
222 RetStatus = Status;
223 }
224 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
225 (void)IoSetCancelRoutine(NextIrp, NULL);
227 }
228 }
229 }
230
231 if( FCB->Recv.Content - FCB->Recv.BytesUsed &&
232 IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]) ) {
233 FCB->PollState |= AFD_EVENT_RECEIVE;
234 FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
235 PollReeval( FCB->DeviceExt, FCB->FileObject );
236 }
237 else
238 {
239 FCB->PollState &= ~AFD_EVENT_RECEIVE;
240 }
241
242 /* Signal FD_CLOSE if no buffered data remains and the socket can't receive any more */
243 if (CantReadMore(FCB))
244 {
245 if (FCB->LastReceiveStatus == STATUS_SUCCESS)
246 {
247 FCB->PollState |= AFD_EVENT_DISCONNECT;
248 }
249 else
250 {
251 FCB->PollState |= AFD_EVENT_CLOSE;
252 }
253 FCB->PollStatus[FD_CLOSE_BIT] = FCB->LastReceiveStatus;
254 PollReeval(FCB->DeviceExt, FCB->FileObject);
255 }
256
257 AFD_DbgPrint(MID_TRACE,("RetStatus for irp %p is %x\n", Irp, RetStatus));
258
259 return RetStatus;
260}
261
264{
266
268 return STATUS_FILE_CLOSED;
269
270 ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
271 ASSERT(FCB->AcceptIrp != NULL);
272 FCB->ReceiveIrp.InFlightRequest = NULL;
273 FCB->SharedData.State = SOCKET_STATE_CONNECTED;
274
275 /* Complete the AcceptEx IRP as the data has been received */
276 MmUnlockPages((PMDL)FCB->AcceptIrp->Tail.Overlay.DriverContext[3]);
277 IoFreeMdl((PMDL)FCB->AcceptIrp->Tail.Overlay.DriverContext[3]);
278 FCB->AcceptIrp->IoStatus.Information = Irp->IoStatus.Information;
279 FCB->AcceptIrp->IoStatus.Status = Irp->IoStatus.Status;
280 if (FCB->AcceptIrp->MdlAddress)
281 UnlockRequest(FCB->AcceptIrp, IoGetCurrentIrpStackLocation(FCB->AcceptIrp));
282 (void)IoSetCancelRoutine(FCB->AcceptIrp, NULL);
284 FCB->AcceptIrp = NULL;
285
286 /* Continue receive activity */
288
290 return STATUS_SUCCESS;
291}
292
295 PIRP Irp,
296 PVOID Context ) {
298 PLIST_ENTRY NextIrpEntry;
299 PIRP NextIrp;
300 PAFD_RECV_INFO RecvReq;
301 PIO_STACK_LOCATION NextIrpSp;
302
304
305 AFD_DbgPrint(MID_TRACE,("Called\n"));
306
308 return STATUS_FILE_CLOSED;
309
310 ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
311 FCB->ReceiveIrp.InFlightRequest = NULL;
312
313 if( FCB->SharedData.State == SOCKET_STATE_CLOSED ) {
314 /* Cleanup our IRP queue because the FCB is being destroyed */
315 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
316 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
317 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
318 NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
319 RecvReq = GetLockedData(NextIrp, NextIrpSp);
321 NextIrp->IoStatus.Information = 0;
322 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
323 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
324 (void)IoSetCancelRoutine(NextIrp, NULL);
326 }
328 return STATUS_FILE_CLOSED;
329 } else if( FCB->SharedData.State == SOCKET_STATE_LISTENING ) {
330 AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n"));
333 }
334
335 HandleReceiveComplete( FCB, Irp->IoStatus.Status, Irp->IoStatus.Information );
336
338
340
341 return STATUS_SUCCESS;
342}
343
344static NTSTATUS NTAPI
346 PAFD_STORED_DATAGRAM DatagramRecv,
347 PUINT TotalBytesCopied ) {
350 PAFD_RECV_INFO RecvReq =
352 UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
353 PAFD_MAPBUF Map;
354 BOOLEAN ExtraBuffers = CheckUnlockExtraBuffers(FCB, IrpSp);
355
356 Map = (PAFD_MAPBUF)(RecvReq->BufferArray +
357 RecvReq->BufferCount +
358 (ExtraBuffers ? EXTRA_LOCK_BUFFERS : 0));
359
360 BytesToCopy = MIN( RecvReq->BufferArray[0].len, BytesAvailable );
361
362 AFD_DbgPrint(MID_TRACE,("BytesToCopy: %u len %u\n", BytesToCopy,
363 RecvReq->BufferArray[0].len));
364
365 if( Map[0].Mdl ) {
366 /* Copy the address */
367 if( ExtraBuffers && Map[1].Mdl && Map[2].Mdl ) {
368 AFD_DbgPrint(MID_TRACE,("Checking TAAddressCount\n"));
369
370 if( DatagramRecv->Address->TAAddressCount != 1 ) {
372 (MIN_TRACE,
373 ("Wierd address count %d\n",
374 DatagramRecv->Address->TAAddressCount));
375 }
376
377 AFD_DbgPrint(MID_TRACE,("Computing addr len\n"));
378
379 AddrLen = MIN(DatagramRecv->Address->Address->AddressLength +
380 sizeof(USHORT),
381 RecvReq->BufferArray[1].len);
382
383 AFD_DbgPrint(MID_TRACE,("Copying %u bytes of address\n", AddrLen));
384
385 Map[1].BufferAddress = MmMapLockedPages( Map[1].Mdl, KernelMode );
386
387 AFD_DbgPrint(MID_TRACE,("Done mapping, copying address\n"));
388
390 &DatagramRecv->Address->Address->AddressType,
391 AddrLen );
392
393 MmUnmapLockedPages( Map[1].BufferAddress, Map[1].Mdl );
394
395 AFD_DbgPrint(MID_TRACE,("Copying address len\n"));
396
397 Map[2].BufferAddress = MmMapLockedPages( Map[2].Mdl, KernelMode );
398 *((PINT)Map[2].BufferAddress) = AddrLen;
399 MmUnmapLockedPages( Map[2].BufferAddress, Map[2].Mdl );
400 }
401
402 AFD_DbgPrint(MID_TRACE,("Mapping data buffer pages\n"));
403
404 Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode );
405
406 AFD_DbgPrint(MID_TRACE,("Buffer %d: %p:%u\n",
407 0,
408 Map[0].BufferAddress,
409 BytesToCopy));
410
412 DatagramRecv->Buffer,
413 BytesToCopy );
414
415 MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );
416
417 *TotalBytesCopied = BytesToCopy;
418 }
419
420 if (*TotalBytesCopied == DatagramRecv->Len)
421 {
422 /* We copied the whole datagram */
423 Status = Irp->IoStatus.Status = STATUS_SUCCESS;
424 }
425 else
426 {
427 /* We only copied part of the datagram */
428 Status = Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
429 }
430
431 Irp->IoStatus.Information = *TotalBytesCopied;
432
433 if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
434 {
435 FCB->Recv.Content -= DatagramRecv->Len;
438 }
439
440 AFD_DbgPrint(MID_TRACE,("Done\n"));
441
442 return Status;
443}
444
450 PAFD_FCB FCB = FileObject->FsContext;
451 PAFD_RECV_INFO RecvReq;
452 UINT TotalBytesCopied = 0;
453 PAFD_STORED_DATAGRAM DatagramRecv;
454 PLIST_ENTRY ListEntry;
456
459
460 AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));
461
462 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
463
464 FCB->EventSelectDisabled &= ~AFD_EVENT_RECEIVE;
465
467 FCB->SharedData.State != SOCKET_STATE_CONNECTED &&
468 FCB->SharedData.State != SOCKET_STATE_CONNECTING ) {
469 AFD_DbgPrint(MIN_TRACE,("Called recv on wrong kind of socket (s%x)\n",
470 FCB->SharedData.State));
472 Irp, 0 );
473 }
474
475 if( !(RecvReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) )
477 Irp, 0 );
478
479 AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
480
481 RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
482 RecvReq->BufferCount,
483 NULL, NULL,
484 TRUE, FALSE, LockMode );
485
486 if( !RecvReq->BufferArray ) {
488 Irp, 0 );
489 }
490
492 {
493 if (!IsListEmpty(&FCB->DatagramList))
494 {
495 ListEntry = RemoveHeadList(&FCB->DatagramList);
496 DatagramRecv = CONTAINING_RECORD(ListEntry, AFD_STORED_DATAGRAM, ListEntry);
497 Status = SatisfyPacketRecvRequest(FCB, Irp, DatagramRecv,
498 (PUINT)&Irp->IoStatus.Information);
499
500 if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
501 {
502 InsertHeadList(&FCB->DatagramList,
503 &DatagramRecv->ListEntry);
504 }
505
506 if (!IsListEmpty(&FCB->DatagramList))
507 {
508 FCB->PollState |= AFD_EVENT_RECEIVE;
509 FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
510 PollReeval( FCB->DeviceExt, FCB->FileObject );
511 }
512 else
513 FCB->PollState &= ~AFD_EVENT_RECEIVE;
514
515 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
516
517 return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information);
518 }
519 else if (!(RecvReq->AfdFlags & AFD_OVERLAPPED) &&
520 ((RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking)))
521 {
522 AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
524 FCB->PollState &= ~AFD_EVENT_RECEIVE;
525 UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
526 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
527 }
528 else
529 {
530 FCB->PollState &= ~AFD_EVENT_RECEIVE;
532 }
533 }
534
535 Irp->IoStatus.Status = STATUS_PENDING;
536 Irp->IoStatus.Information = 0;
537
538 InsertTailList( &FCB->PendingIrpList[FUNCTION_RECV],
539 &Irp->Tail.Overlay.ListEntry );
540
541 /************ From this point, the IRP is not ours ************/
542
544
545 if( Status == STATUS_PENDING &&
546 !(RecvReq->AfdFlags & AFD_OVERLAPPED) &&
547 ((RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking))) {
548 AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
550 TotalBytesCopied = 0;
551 RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
552 UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
554 TotalBytesCopied );
555 } else if( Status == STATUS_PENDING ) {
556 AFD_DbgPrint(MID_TRACE,("Leaving read irp\n"));
559 } else {
560 AFD_DbgPrint(MID_TRACE,("Completed with status %x\n", Status));
561 }
562
564 return Status;
565}
566
570 PIRP Irp,
571 PVOID Context ) {
574 PIRP NextIrp;
575 PIO_STACK_LOCATION NextIrpSp;
576 PLIST_ENTRY ListEntry;
577 PAFD_RECV_INFO RecvReq;
578 PAFD_STORED_DATAGRAM DatagramRecv;
579 UINT DGSize = Irp->IoStatus.Information + sizeof( AFD_STORED_DATAGRAM );
580 PLIST_ENTRY NextIrpEntry, DatagramRecvEntry;
581
583
584 AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));
585
587 return STATUS_FILE_CLOSED;
588
589 ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
590 FCB->ReceiveIrp.InFlightRequest = NULL;
591
592 if( FCB->SharedData.State == SOCKET_STATE_CLOSED ) {
593 /* Cleanup our IRP queue because the FCB is being destroyed */
594 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
595 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
596 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
597 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
598 RecvReq = GetLockedData(NextIrp, NextIrpSp);
600 NextIrp->IoStatus.Information = 0;
601 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, NextIrpSp));
602 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
603 (void)IoSetCancelRoutine(NextIrp, NULL);
605 }
606
607 /* Free all items on the datagram list */
608 while( !IsListEmpty( &FCB->DatagramList ) ) {
609 DatagramRecvEntry = RemoveHeadList(&FCB->DatagramList);
610 DatagramRecv = CONTAINING_RECORD(DatagramRecvEntry, AFD_STORED_DATAGRAM, ListEntry);
613 }
614
616 return STATUS_FILE_CLOSED;
617 }
618
619 if (Irp->IoStatus.Status != STATUS_SUCCESS)
620 {
622 return Irp->IoStatus.Status;
623 }
624
625 if (FCB->TdiReceiveClosed)
626 {
628 return STATUS_FILE_CLOSED;
629 }
630
631 DatagramRecv = ExAllocatePoolWithTag(NonPagedPool,
632 DGSize,
634
635 if( DatagramRecv ) {
636 DatagramRecv->Len = Irp->IoStatus.Information;
637 RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window,
638 DatagramRecv->Len );
639 AFD_DbgPrint(MID_TRACE,("Received (A %p)\n",
640 FCB->AddressFrom->RemoteAddress));
641 DatagramRecv->Address =
642 TaCopyTransportAddress( FCB->AddressFrom->RemoteAddress );
643
644 if( !DatagramRecv->Address ) Status = STATUS_NO_MEMORY;
645
646 } else Status = STATUS_NO_MEMORY;
647
648 if( !NT_SUCCESS( Status ) ) {
649
650 if (DatagramRecv)
651 {
653 }
654
656 return Status;
657 } else {
658 FCB->Recv.Content += DatagramRecv->Len;
659 InsertTailList( &FCB->DatagramList, &DatagramRecv->ListEntry );
660 }
661
662 /* Satisfy as many requests as we can */
663
664 while( !IsListEmpty( &FCB->DatagramList ) &&
665 !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
666 AFD_DbgPrint(MID_TRACE,("Looping trying to satisfy request\n"));
667 ListEntry = RemoveHeadList( &FCB->DatagramList );
668 DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
669 ListEntry );
670 ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] );
671 NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
672 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
673 RecvReq = GetLockedData(NextIrp, NextIrpSp);
674
675 AFD_DbgPrint(MID_TRACE,("RecvReq: %p, DatagramRecv: %p\n",
676 RecvReq, DatagramRecv));
677
678 AFD_DbgPrint(MID_TRACE,("Satisfying\n"));
680 ( FCB, NextIrp, DatagramRecv,
681 (PUINT)&NextIrp->IoStatus.Information );
682
683 if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
684 {
685 InsertHeadList(&FCB->DatagramList,
686 &DatagramRecv->ListEntry);
687 }
688
689 AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
690 UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, NextIrpSp) );
691 if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
692
693 AFD_DbgPrint(MID_TRACE,("Completing\n"));
694 (void)IoSetCancelRoutine(NextIrp, NULL);
695 NextIrp->IoStatus.Status = Status;
696
698 }
699
700 if( !IsListEmpty( &FCB->DatagramList ) && IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]) ) {
701 AFD_DbgPrint(MID_TRACE,("Signalling\n"));
702 FCB->PollState |= AFD_EVENT_RECEIVE;
703 FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
704 PollReeval( FCB->DeviceExt, FCB->FileObject );
705 } else
706 FCB->PollState &= ~AFD_EVENT_RECEIVE;
707
708 if( NT_SUCCESS(Irp->IoStatus.Status) && FCB->Recv.Content < FCB->Recv.Size ) {
709 /* Now relaunch the datagram request */
711 ( &FCB->ReceiveIrp.InFlightRequest,
712 FCB->AddressFile.Object,
713 0,
714 FCB->Recv.Window,
715 FCB->Recv.Size,
716 FCB->AddressFrom,
718 FCB );
719 }
720
722
723 return STATUS_SUCCESS;
724}
725
731 PAFD_FCB FCB = FileObject->FsContext;
732 PAFD_RECV_INFO_UDP RecvReq;
733 PLIST_ENTRY ListEntry;
734 PAFD_STORED_DATAGRAM DatagramRecv;
736
738
739 AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));
740
741 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
742
743 FCB->EventSelectDisabled &= ~AFD_EVENT_RECEIVE;
744
745 /* Check that the socket is bound */
746 if( FCB->SharedData.State != SOCKET_STATE_BOUND )
747 {
748 AFD_DbgPrint(MIN_TRACE,("Invalid socket state\n"));
750 }
751
752 if (FCB->TdiReceiveClosed)
753 {
754 AFD_DbgPrint(MIN_TRACE,("Receive closed\n"));
756 }
757
758 if( !(RecvReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) )
760
761 AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
762
763 RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
764 RecvReq->BufferCount,
765 RecvReq->Address,
766 RecvReq->AddressLength,
767 TRUE, TRUE, LockMode );
768
769 if( !RecvReq->BufferArray ) { /* access violation in userspace */
771 }
772
773 if (!IsListEmpty(&FCB->DatagramList))
774 {
775 ListEntry = RemoveHeadList(&FCB->DatagramList);
776 DatagramRecv = CONTAINING_RECORD(ListEntry, AFD_STORED_DATAGRAM, ListEntry);
777 Status = SatisfyPacketRecvRequest(FCB, Irp, DatagramRecv,
778 (PUINT)&Irp->IoStatus.Information);
779
780 if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
781 {
782 InsertHeadList(&FCB->DatagramList,
783 &DatagramRecv->ListEntry);
784 }
785
786 if (!IsListEmpty(&FCB->DatagramList))
787 {
788 FCB->PollState |= AFD_EVENT_RECEIVE;
789 FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
790 PollReeval( FCB->DeviceExt, FCB->FileObject );
791 }
792 else
793 FCB->PollState &= ~AFD_EVENT_RECEIVE;
794
795 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, TRUE);
796
797 return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information);
798 }
799 else if (!(RecvReq->AfdFlags & AFD_OVERLAPPED) &&
800 ((RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking)))
801 {
802 AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
804 FCB->PollState &= ~AFD_EVENT_RECEIVE;
805 UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
806 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
807 }
808 else
809 {
810 FCB->PollState &= ~AFD_EVENT_RECEIVE;
812 }
813}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
Definition: actypes.h:127
IO_COMPLETION_ROUTINE AcceptExReceiveComplete
Definition: afd.h:319
struct _AFD_MAPBUF * PAFD_MAPBUF
#define SOCKET_STATE_CLOSED
Definition: afd.h:83
IO_COMPLETION_ROUTINE ReceiveComplete
Definition: afd.h:321
#define SOCKET_STATE_CONNECTED
Definition: afd.h:77
struct _AFD_FCB * PAFD_FCB
#define TAG_AFD_STORED_DATAGRAM
Definition: afd.h:52
#define FUNCTION_RECV
Definition: afd.h:86
#define SOCKET_STATE_LISTENING
Definition: afd.h:78
DRIVER_CANCEL AfdCancelHandler
Definition: afd.h:313
IO_COMPLETION_ROUTINE PacketSocketRecvComplete
Definition: afd.h:323
#define SOCKET_STATE_CONNECTING
Definition: afd.h:76
#define SOCKET_STATE_BOUND
Definition: afd.h:75
struct _AFD_STORED_DATAGRAM AFD_STORED_DATAGRAM
#define TAG_AFD_TRANSPORT_ADDRESS
Definition: afd.h:39
#define EXTRA_LOCK_BUFFERS
Definition: afd.h:97
LONG NTSTATUS
Definition: precomp.h:26
#define MIN(x, y)
Definition: rdesktop.h:171
#define MIN_TRACE
Definition: debug.h:14
#define MID_TRACE
Definition: debug.h:15
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
Definition: cdrom.h:990
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4138
PVOID LockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Output, KPROCESSOR_MODE *LockMode)
Definition: lock.c:24
VOID UnlockBuffers(PAFD_WSABUF Buf, UINT Count, BOOL Address)
Definition: lock.c:289
VOID UnlockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: lock.c:180
NTSTATUS LostSocket(PIRP Irp)
Definition: lock.c:387
NTSTATUS NTAPI UnlockAndMaybeComplete(PAFD_FCB FCB, NTSTATUS Status, PIRP Irp, UINT Information)
Definition: lock.c:375
PAFD_WSABUF LockBuffers(PAFD_WSABUF Buf, UINT Count, PVOID AddressBuf, PINT AddressLen, BOOLEAN Write, BOOLEAN LockAddress, KPROCESSOR_MODE LockMode)
Definition: lock.c:205
VOID SocketStateUnlock(PAFD_FCB FCB)
Definition: lock.c:370
NTSTATUS LeaveIrpUntilLater(PAFD_FCB FCB, PIRP Irp, UINT Function)
Definition: lock.c:433
BOOLEAN SocketAcquireStateLock(PAFD_FCB FCB)
Definition: lock.c:360
PVOID GetLockedData(PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: lock.c:13
BOOLEAN CheckUnlockExtraBuffers(PAFD_FCB FCB, PIO_STACK_LOCATION IrpSp)
Definition: main.c:1100
VOID PollReeval(PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: select.c:407
#define AFD_DbgPrint(_t_, _x_)
Definition: debug.h:60
#define IO_NETWORK_INCREMENT
Definition: tcpip.h:43
ULONG LockMode
Definition: env_spec_w32.cpp:8
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define STATUS_ACCESS_VIOLATION
short Short
Definition: ftraster.c:309
#define IoFreeMdl
Definition: fxmdl.h:89
Status
Definition: gdiplustypes.h:24
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT
Definition: sysinfo.c:13
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
int * PINT
Definition: minwindef.h:150
PVOID NTAPI MmMapLockedPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode)
Definition: mdlsup.c:818
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned int * PUINT
Definition: ndis.h:50
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
#define KernelMode
Definition: asm.h:38
static VOID RefillSocketBuffer(PAFD_FCB FCB)
Definition: read.c:13
NTSTATUS NTAPI AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Short)
Definition: read.c:446
static NTSTATUS NTAPI SatisfyPacketRecvRequest(PAFD_FCB FCB, PIRP Irp, PAFD_STORED_DATAGRAM DatagramRecv, PUINT TotalBytesCopied)
Definition: read.c:345
static NTSTATUS ReceiveActivity(PAFD_FCB FCB, PIRP Irp)
Definition: read.c:151
NTSTATUS NTAPI AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: read.c:727
static VOID HandleReceiveComplete(PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information)
Definition: read.c:53
static NTSTATUS TryToSatisfyRecvRequestFromBuffer(PAFD_FCB FCB, PAFD_RECV_INFO RecvReq, PUINT TotalBytesCopied)
Definition: read.c:94
static BOOLEAN CantReadMore(PAFD_FCB FCB)
Definition: read.c:88
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define IoCompleteRequest
Definition: irp.c:1272
#define STATUS_CANT_WAIT
Definition: ntstatus.h:546
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:626
unsigned short USHORT
Definition: pedump.c:61
#define AFD_IMMEDIATE
Definition: shared.h:236
#define AFD_OVERLAPPED
Definition: shared.h:235
#define AFD_EVENT_RECEIVE
Definition: shared.h:219
#define AFD_EVENT_DISCONNECT
Definition: shared.h:222
#define AFD_ENDPOINT_CONNECTIONLESS
Definition: shared.h:169
#define AFD_EVENT_CLOSE
Definition: shared.h:224
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
_In_ PVOID Context
Definition: storport.h:2269
Definition: afd.h:161
PVOID BufferAddress
Definition: afd.h:106
PINT AddressLength
Definition: shared.h:107
ULONG BufferCount
Definition: shared.h:103
PAFD_WSABUF BufferArray
Definition: shared.h:102
ULONG BufferCount
Definition: shared.h:96
ULONG TdiFlags
Definition: shared.h:98
ULONG AfdFlags
Definition: shared.h:97
PAFD_WSABUF BufferArray
Definition: shared.h:95
PTRANSPORT_ADDRESS Address
Definition: afd.h:157
CHAR Buffer[1]
Definition: afd.h:158
LIST_ENTRY ListEntry
Definition: afd.h:155
UINT len
Definition: shared.h:17
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:536
PFILE_OBJECT FileObject
Definition: ntfs.h:520
PFILE_OBJECT FileObject
Definition: iotypes.h:3171
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
USHORT AddressLength
Definition: tdi.h:338
USHORT AddressType
Definition: tdi.h:339
TA_ADDRESS Address[1]
Definition: tdi.h:377
LONG TAAddressCount
Definition: tdi.h:376
#define TDI_RECEIVE_PEEK
Definition: tdi.h:124
#define TDI_RECEIVE_NORMAL
Definition: tdi.h:122
NTSTATUS TdiReceiveDatagram(PIRP *Irp, PFILE_OBJECT TransportObject, USHORT Flags, PCHAR Buffer, UINT BufferLength, PTDI_CONNECTION_INFORMATION From, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext)
Receives a datagram.
Definition: tdi.c:1075
NTSTATUS TdiReceive(PIRP *Irp, PFILE_OBJECT ConnectionObject, USHORT Flags, PCHAR Buffer, UINT BufferLength, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext)
Definition: tdi.c:995
PTRANSPORT_ADDRESS TaCopyTransportAddress(PTRANSPORT_ADDRESS OtherAddress)
Definition: tdiconn.c:90
#define STATUS_PENDING
Definition: telnetd.h:14
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
#define FD_CLOSE_BIT
Definition: winsock2.h:297
#define FD_READ_BIT
Definition: winsock2.h:287
* PFILE_OBJECT
Definition: iotypes.h:1998
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7