2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver
5 * PURPOSE: File object dispatch functions
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/09-2000 Created
12 NTSTATUS
AfdpDispRecv(
15 PFILE_REQUEST_RECVFROM Request
,
16 PFILE_REPLY_RECVFROM Reply
)
18 * FUNCTION: Receives data
20 * Irp = Pointer to I/O request packet
21 * FCB = Pointer to file control block
22 * Request = Address of request buffer
23 * Reply = Address of reply buffer (same as request buffer)
28 PAFD_READ_REQUEST ReadRequest
;
33 KeAcquireSpinLock(&FCB
->ReceiveQueueLock
, &OldIrql
);
34 if (IsListEmpty(&FCB
->ReceiveQueue
)) {
35 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
37 /* Queue a read request and return STATUS_PENDING */
39 AFD_DbgPrint(MAX_TRACE
, ("Queueing read request.\n"));
41 /*ReadRequest = (PAFD_READ_REQUEST)ExAllocateFromNPagedLookasideList(
42 &ReadRequestLookasideList);*/
43 ReadRequest
= (PAFD_READ_REQUEST
)ExAllocatePool(
45 sizeof(AFD_READ_REQUEST
));
47 ReadRequest
->Irp
= Irp
;
48 ReadRequest
->RecvFromRequest
= Request
;
49 ReadRequest
->RecvFromReply
= Reply
;
51 ExInterlockedInsertTailList(
52 &FCB
->ReadRequestQueue
,
53 &ReadRequest
->ListEntry
,
54 &FCB
->ReadRequestQueueLock
);
55 Status
= STATUS_PENDING
;
57 Status
= STATUS_INSUFFICIENT_RESOURCES
;
60 AFD_DbgPrint(MAX_TRACE
, ("Satisfying read request.\n"));
62 /* Satisfy the request at once */
63 Status
= FillWSABuffers(
68 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
70 Reply
->NumberOfBytesRecvd
= Count
;
71 Reply
->Status
= NO_ERROR
;
73 AFD_DbgPrint(MAX_TRACE
, ("Bytes received (0x%X).\n", Count
));
82 PIO_STACK_LOCATION IrpSp
)
84 * FUNCTION: Binds to an address
86 * Irp = Pointer to I/O request packet
87 * IrpSp = Pointer to current stack location of Irp
93 UINT InputBufferLength
;
94 UINT OutputBufferLength
;
95 PFILE_REQUEST_BIND Request
;
96 PFILE_REPLY_BIND Reply
;
99 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
100 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
102 /* Validate parameters */
103 if ((InputBufferLength
>= sizeof(FILE_REQUEST_BIND
)) &&
104 (OutputBufferLength
>= sizeof(FILE_REPLY_BIND
))) {
105 FCB
= IrpSp
->FileObject
->FsContext
;
107 Request
= (PFILE_REQUEST_BIND
)Irp
->AssociatedIrp
.SystemBuffer
;
108 Reply
= (PFILE_REPLY_BIND
)Irp
->AssociatedIrp
.SystemBuffer
;
110 Status
= TdiOpenAddressFile(
113 &FCB
->TdiAddressObjectHandle
,
114 &FCB
->TdiAddressObject
);
116 if (NT_SUCCESS(Status
)) {
117 AfdRegisterEventHandlers(FCB
);
118 FCB
->State
= SOCKET_STATE_BOUND
;
119 Reply
->Status
= NO_ERROR
;
121 //FIXME: WSAEADDRNOTAVAIL
122 Reply
->Status
= WSAEINVAL
;
125 Status
= STATUS_INVALID_PARAMETER
;
127 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
135 AfdDispCompleteListen(
136 PDEVICE_OBJECT DeviceObject
,
140 PAFD_LISTEN_REQUEST ListenRequest
= (PAFD_LISTEN_REQUEST
) Context
;
142 AFD_DbgPrint(MAX_TRACE
, ("Called. ListenRequest (0x%X).\n", ListenRequest
));
144 AFD_DbgPrint(MAX_TRACE
, ("Fcb (0x%X).\n", ListenRequest
->Fcb
));
146 return STATUS_SUCCESS
;
150 NTSTATUS
AfdDispListen(
152 PIO_STACK_LOCATION IrpSp
)
154 * FUNCTION: Starts listening for connections
156 * Irp = Pointer to I/O request packet
157 * IrpSp = Pointer to current stack location of Irp
159 * Status of operation
163 UINT InputBufferLength
;
164 UINT OutputBufferLength
;
165 PFILE_REQUEST_LISTEN Request
;
166 PFILE_REPLY_LISTEN Reply
;
168 PAFD_LISTEN_REQUEST ListenRequest
;
170 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
171 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
173 /* Validate parameters */
174 Status
= STATUS_INVALID_PARAMETER
;
175 if ((InputBufferLength
>= sizeof(FILE_REQUEST_LISTEN
)) &&
176 (OutputBufferLength
>= sizeof(FILE_REPLY_LISTEN
))) {
177 FCB
= IrpSp
->FileObject
->FsContext
;
179 Request
= (PFILE_REQUEST_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
180 Reply
= (PFILE_REPLY_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
182 if (FCB
->State
== SOCKET_STATE_BOUND
)
184 /* We have a bound socket so go ahead and create a connection endpoint
185 and associate it with the address file object */
187 Status
= TdiOpenConnectionEndpointFile(
189 &FCB
->TdiConnectionObjectHandle
,
190 &FCB
->TdiConnectionObject
);
192 if (NT_SUCCESS(Status
))
194 Status
= TdiAssociateAddressFile(
195 FCB
->TdiAddressObjectHandle
,
196 FCB
->TdiConnectionObject
);
198 if (NT_SUCCESS(Status
))
200 ListenRequest
= ExAllocateFromNPagedLookasideList(&ListenRequestLookasideList
);
201 if (ListenRequest
!= NULL
)
203 ListenRequest
->Fcb
= FCB
;
204 /* FIXME: Protect ListenRequestQueue */
205 InsertTailList(&FCB
->ListenRequestQueue
, &ListenRequest
->ListEntry
);
207 Status
= TdiListen(FCB
->TdiConnectionObject
, AfdDispCompleteListen
, ListenRequest
);
208 if ((Status
== STATUS_PENDING
) || NT_SUCCESS(Status
))
210 if (Status
!= STATUS_PENDING
)
212 AFD_DbgPrint(MIN_TRACE
, ("FIXME: Status (0x%X).\n", Status
));
217 /* FIXME: Cleanup ListenRequest */
218 /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
223 /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
224 Status
= STATUS_NO_MEMORY
;
229 /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
233 if (NT_SUCCESS(Status
)) {
234 Reply
->Status
= NO_ERROR
;
236 Reply
->Status
= WSAEINVAL
;
239 else if (FCB
->State
== SOCKET_STATE_CONNECTED
)
241 Reply
->Status
= WSAEISCONN
;
245 Reply
->Status
= WSAEINVAL
;
249 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
255 NTSTATUS
AfdDispSendTo(
257 PIO_STACK_LOCATION IrpSp
)
259 * FUNCTION: Sends data to an address
261 * Irp = Pointer to I/O request packet
262 * IrpSp = Pointer to current stack location of Irp
264 * Status of operation
268 UINT InputBufferLength
;
269 UINT OutputBufferLength
;
270 PFILE_REQUEST_SENDTO Request
;
271 PFILE_REPLY_SENDTO Reply
;
273 PVOID SystemVirtualAddress
;
274 PVOID DataBufferAddress
;
279 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
280 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
282 /* Validate parameters */
283 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SENDTO
)) &&
284 (OutputBufferLength
>= sizeof(FILE_REPLY_SENDTO
))) {
286 AFD_DbgPrint(MAX_TRACE
, ("FileObject at (0x%X).\n", IrpSp
->FileObject
));
287 AFD_DbgPrint(MAX_TRACE
, ("FCB at (0x%X).\n", IrpSp
->FileObject
->FsContext
));
288 AFD_DbgPrint(MAX_TRACE
, ("CCB at (0x%X).\n", IrpSp
->FileObject
->FsContext2
));
290 FCB
= IrpSp
->FileObject
->FsContext
;
291 Request
= (PFILE_REQUEST_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
292 Reply
= (PFILE_REPLY_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
294 /* Since we're using bufferred I/O */
295 Request
->Buffers
= (LPWSABUF
)(Request
+ 1);
296 BufferSize
= WSABufferSize(Request
->Buffers
, Request
->BufferCount
);
299 /* FIXME: Should we handle special cases here? */
300 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
301 BufferSize
+= sizeof(IPv4_HEADER
);
305 if (BufferSize
!= 0) {
306 AFD_DbgPrint(MAX_TRACE
, ("Allocating %d bytes for send buffer.\n", BufferSize
));
307 SystemVirtualAddress
= ExAllocatePool(NonPagedPool
, BufferSize
);
308 if (!SystemVirtualAddress
) {
309 return STATUS_INSUFFICIENT_RESOURCES
;
312 /* FIXME: Should we handle special cases here? */
313 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
314 DataBufferAddress
= SystemVirtualAddress
+ sizeof(IPv4_HEADER
);
316 /* FIXME: Should TCP/IP driver assign source address for raw sockets? */
317 ((PSOCKADDR_IN
)&FCB
->SocketName
)->sin_addr
.S_un
.S_addr
= 0x0100007F;
320 (PIPv4_HEADER
)SystemVirtualAddress
,
326 DataBufferAddress
= SystemVirtualAddress
;
329 Status
= MergeWSABuffers(
331 Request
->BufferCount
,
335 if (!NT_SUCCESS(Status
)) {
336 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
340 SystemVirtualAddress
= NULL
;
345 SystemVirtualAddress
, /* Virtual address of buffer */
346 BufferSize
, /* Length of buffer */
347 FALSE
, /* Not secondary */
348 FALSE
, /* Don't charge quota */
349 NULL
); /* Don't use IRP */
351 ExFreePool(SystemVirtualAddress
);
352 return STATUS_INSUFFICIENT_RESOURCES
;
355 MmBuildMdlForNonPagedPool(Mdl
);
357 AFD_DbgPrint(MAX_TRACE
, ("System virtual address is (0x%X).\n", SystemVirtualAddress
));
358 AFD_DbgPrint(MAX_TRACE
, ("MDL for data buffer is at (0x%X).\n", Mdl
));
360 AFD_DbgPrint(MAX_TRACE
, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl
));
361 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl
->MdlFlags
));
362 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Next is at (0x%X).\n", Mdl
->Next
));
363 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Size is (0x%X).\n", Mdl
->Size
));
364 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl
->MappedSystemVa
));
365 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer StartVa is (0x%X).\n", Mdl
->StartVa
));
366 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl
->ByteCount
));
367 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl
->ByteOffset
));
373 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
375 } except(EXCEPTION_EXECUTE_HANDLER
) {
376 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
378 if (BufferSize
!= 0) {
379 ExFreePool(SystemVirtualAddress
);
381 return STATUS_UNSUCCESSFUL
;
386 if (!FCB
->TdiAddressObject
) {
387 struct sockaddr_in BindName
;
389 RtlZeroMemory(&BindName
,sizeof(BindName
));
390 BindName
.sin_family
= AF_INET
;
392 Status
= TdiOpenAddressFile
393 (&FCB
->TdiDeviceName
,
394 (SOCKADDR
*)&BindName
,
395 &FCB
->TdiAddressObjectHandle
,
396 &FCB
->TdiAddressObject
);
398 if (NT_SUCCESS(Status
)) {
399 AfdRegisterEventHandlers(FCB
);
400 FCB
->State
= SOCKET_STATE_BOUND
;
401 Reply
->Status
= NO_ERROR
;
403 //FIXME: WSAEADDRNOTAVAIL
404 Reply
->Status
= WSAEINVAL
;
411 Status
= TdiSendDatagram(FCB
->TdiAddressObject
,
416 /* FIXME: Assumes synchronous operation */
423 if (BufferSize
!= 0) {
424 ExFreePool(SystemVirtualAddress
);
427 Reply
->NumberOfBytesSent
= BufferSize
;
428 Reply
->Status
= NO_ERROR
;
430 Status
= STATUS_INVALID_PARAMETER
;
432 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
438 NTSTATUS
AfdDispRecvFrom(
440 PIO_STACK_LOCATION IrpSp
)
442 * FUNCTION: Receives data from an address
444 * Irp = Pointer to I/O request packet
445 * IrpSp = Pointer to current stack location of Irp
447 * Status of operation
451 UINT InputBufferLength
;
452 UINT OutputBufferLength
;
453 PFILE_REQUEST_RECVFROM Request
;
454 PFILE_REPLY_RECVFROM Reply
;
457 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
459 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
460 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
462 /* Validate parameters */
463 if ((InputBufferLength
>= sizeof(FILE_REQUEST_RECVFROM
)) &&
464 (OutputBufferLength
>= sizeof(FILE_REPLY_RECVFROM
))) {
465 FCB
= IrpSp
->FileObject
->FsContext
;
467 Request
= (PFILE_REQUEST_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
468 Reply
= (PFILE_REPLY_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
469 /* Since we're using bufferred I/O */
470 Request
->Buffers
= (LPWSABUF
)(Request
+ 1);
472 Status
= AfdpDispRecv(
478 Status
= STATUS_INVALID_PARAMETER
;
481 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
494 DWORD
AfdpDispSelectEx(
496 SelectOperation Operation
)
498 PFILE_OBJECT FileObject
;
505 AFD_DbgPrint(MAX_TRACE
, ("FDSet (0x%X) Operation (0x%X).\n",
508 AFD_DbgPrint(MAX_TRACE
, ("FDSet->fd_count (0x%X).\n", FDSet
->fd_count
));
511 for (i
= 0; i
< FDSet
->fd_count
; i
++) {
513 AFD_DbgPrint(MAX_TRACE
, ("Handle (0x%X).\n", FDSet
->fd_array
[i
]));
515 Status
= ObReferenceObjectByHandle(
516 (HANDLE
)FDSet
->fd_array
[i
],
522 if (NT_SUCCESS(Status
)) {
523 AFD_DbgPrint(MAX_TRACE
, ("File object is at (0x%X).\n", FileObject
));
525 Current
= FileObject
->FsContext
;
529 KeAcquireSpinLock(&Current
->ReceiveQueueLock
, &OldIrql
);
530 if (!IsListEmpty(&Current
->ReceiveQueue
)) {
531 AFD_DbgPrint(MAX_TRACE
, ("Socket is readable.\n"));
534 KeReleaseSpinLock(&Current
->ReceiveQueueLock
, OldIrql
);
537 /* FIXME: How can we check for writability? */
541 /* FIXME: What is this? */
546 ObDereferenceObject(FileObject
);
553 NTSTATUS
AfdDispSelect(
555 PIO_STACK_LOCATION IrpSp
)
557 * FUNCTION: Checks if sockets have data in the receive buffers
558 * and/or if client can send data
560 * Irp = Pointer to I/O request packet
561 * IrpSp = Pointer to current stack location of Irp
563 * Status of operation
567 UINT InputBufferLength
;
568 UINT OutputBufferLength
;
569 PFILE_REQUEST_SELECT Request
;
570 PFILE_REPLY_SELECT Reply
;
574 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
575 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
577 /* Validate parameters */
578 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SELECT
)) &&
579 (OutputBufferLength
>= sizeof(FILE_REPLY_SELECT
))) {
580 FCB
= IrpSp
->FileObject
->FsContext
;
582 Request
= (PFILE_REQUEST_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
583 Reply
= (PFILE_REPLY_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
585 AFD_DbgPrint(MAX_TRACE
, ("R (0x%X) W (0x%X).\n",
586 Request
->ReadFDSet
, Request
->WriteFDSet
));
590 if (Request
->WriteFDSet
) {
591 AFD_DbgPrint(MAX_TRACE
, ("Write.\n"));
592 SocketCount
+= AfdpDispSelectEx(Request
->WriteFDSet
, soWrite
);
594 if (Request
->ReadFDSet
) {
595 AFD_DbgPrint(MAX_TRACE
, ("Read.\n"));
596 SocketCount
+= AfdpDispSelectEx(Request
->ReadFDSet
, soRead
);
598 if (Request
->ExceptFDSet
) {
599 SocketCount
+= AfdpDispSelectEx(Request
->ExceptFDSet
, soExcept
);
602 AFD_DbgPrint(MAX_TRACE
, ("Sockets selected (0x%X).\n", SocketCount
));
604 Reply
->Status
= NO_ERROR
;
605 Reply
->SocketCount
= SocketCount
;
606 Status
= STATUS_SUCCESS
;
608 Status
= STATUS_INVALID_PARAMETER
;
610 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
615 NTSTATUS
AfdDispEventSelect(
617 PIO_STACK_LOCATION IrpSp
)
619 * FUNCTION: Associate an event object with one or more network events
621 * Irp = Pointer to I/O request packet
622 * IrpSp = Pointer to current stack location of Irp
624 * Status of operation
628 UINT InputBufferLength
;
629 UINT OutputBufferLength
;
630 PFILE_REQUEST_EVENTSELECT Request
;
631 PFILE_REPLY_EVENTSELECT Reply
;
635 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
636 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
638 /* Validate parameters */
639 if ((InputBufferLength
>= sizeof(FILE_REQUEST_EVENTSELECT
)) &&
640 (OutputBufferLength
>= sizeof(FILE_REPLY_EVENTSELECT
))) {
641 FCB
= IrpSp
->FileObject
->FsContext
;
643 Request
= (PFILE_REQUEST_EVENTSELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
644 Reply
= (PFILE_REPLY_EVENTSELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
646 FCB
->NetworkEvents
.lNetworkEvents
= Request
->lNetworkEvents
;
647 for (i
= 0; i
< FD_MAX_EVENTS
; i
++) {
648 if ((Request
->lNetworkEvents
& (1 << i
)) > 0) {
649 FCB
->EventObjects
[i
] = Request
->hEventObject
;
651 /* The effect of any previous call to this function is cancelled */
652 FCB
->EventObjects
[i
] = (WSAEVENT
)0;
656 Reply
->Status
= NO_ERROR
;
657 Status
= STATUS_SUCCESS
;
659 Status
= STATUS_INVALID_PARAMETER
;
661 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
666 NTSTATUS
AfdDispEnumNetworkEvents(
668 PIO_STACK_LOCATION IrpSp
)
670 * FUNCTION: Reports network events
672 * Irp = Pointer to I/O request packet
673 * IrpSp = Pointer to current stack location of Irp
675 * Status of operation
679 UINT InputBufferLength
;
680 UINT OutputBufferLength
;
681 PFILE_REQUEST_ENUMNETWORKEVENTS Request
;
682 PFILE_REPLY_ENUMNETWORKEVENTS Reply
;
686 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
687 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
689 /* Validate parameters */
690 if ((InputBufferLength
>= sizeof(FILE_REQUEST_ENUMNETWORKEVENTS
)) &&
691 (OutputBufferLength
>= sizeof(FILE_REPLY_ENUMNETWORKEVENTS
))) {
692 FCB
= IrpSp
->FileObject
->FsContext
;
694 Request
= (PFILE_REQUEST_ENUMNETWORKEVENTS
)Irp
->AssociatedIrp
.SystemBuffer
;
695 Reply
= (PFILE_REPLY_ENUMNETWORKEVENTS
)Irp
->AssociatedIrp
.SystemBuffer
;
697 EventObject
= (HANDLE
)Request
->hEventObject
;
700 &Reply
->NetworkEvents
,
702 sizeof(WSANETWORKEVENTS
));
706 sizeof(WSANETWORKEVENTS
));
708 if (EventObject
!= NULL
) {
709 ZwClearEvent(EventObject
);
712 Reply
->Status
= NO_ERROR
;
713 Status
= STATUS_SUCCESS
;
715 Status
= STATUS_INVALID_PARAMETER
;
717 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
723 NTSTATUS
AfdDispRecv(
725 PIO_STACK_LOCATION IrpSp
)
727 * FUNCTION: Receives data from an address
729 * Irp = Pointer to I/O request packet
730 * IrpSp = Pointer to current stack location of Irp
732 * Status of operation
737 UINT InputBufferLength
;
738 UINT OutputBufferLength
;
739 PFILE_REQUEST_RECV Request
;
740 PFILE_REPLY_RECV Reply
;
741 DWORD NumberOfBytesRecvd
;
744 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
746 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
747 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
749 /* Validate parameters */
750 if ((InputBufferLength
>= sizeof(FILE_REQUEST_RECV
)) &&
751 (OutputBufferLength
>= sizeof(FILE_REPLY_RECV
))) {
752 FCB
= IrpSp
->FileObject
->FsContext
;
754 Request
= (PFILE_REQUEST_RECV
)Irp
->AssociatedIrp
.SystemBuffer
;
755 Reply
= (PFILE_REPLY_RECV
)Irp
->AssociatedIrp
.SystemBuffer
;
757 Status
= AfdpDispRecv(
761 Request
->BufferCount
,
762 &NumberOfBytesRecvd
);
763 Reply
->NumberOfBytesRecvd
= NumberOfBytesRecvd
;
764 Reply
->Status
= NO_ERROR
;
766 Status
= STATUS_INVALID_PARAMETER
;
769 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
773 return STATUS_SUCCESS
;
778 NTSTATUS
AfdDispSend(
780 PIO_STACK_LOCATION IrpSp
)
782 * FUNCTION: Sends data
784 * Irp = Pointer to I/O request packet
785 * IrpSp = Pointer to current stack location of Irp
787 * Status of operation
791 UINT InputBufferLength
;
792 UINT OutputBufferLength
;
793 PFILE_REQUEST_SEND Request
;
794 PFILE_REPLY_SEND Reply
;
797 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
798 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
800 /* Validate parameters */
801 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SEND
)) &&
802 (OutputBufferLength
>= sizeof(FILE_REPLY_SEND
))) {
803 FCB
= IrpSp
->FileObject
->FsContext
;
805 Request
= (PFILE_REQUEST_SEND
)Irp
->AssociatedIrp
.SystemBuffer
;
806 Reply
= (PFILE_REPLY_SEND
)Irp
->AssociatedIrp
.SystemBuffer
;
808 Reply
->NumberOfBytesSent
= 0;
809 Reply
->Status
= NO_ERROR
;
811 Status
= STATUS_INVALID_PARAMETER
;
813 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
819 NTSTATUS
AfdDispConnect(
821 PIO_STACK_LOCATION IrpSp
)
823 * FUNCTION: Connect to a remote peer
825 * Irp = Pointer to I/O request packet
826 * IrpSp = Pointer to current stack location of Irp
828 * Status of operation
832 UINT InputBufferLength
;
833 UINT OutputBufferLength
;
834 PFILE_REQUEST_CONNECT Request
;
835 PFILE_REPLY_CONNECT Reply
;
837 SOCKADDR_IN LocalAddress
;
839 AFD_DbgPrint(MIN_TRACE
, ("\n"));
841 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
842 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
844 /* Validate parameters */
845 Status
= STATUS_INVALID_PARAMETER
;
846 if ((InputBufferLength
>= sizeof(FILE_REQUEST_CONNECT
)) &&
847 (OutputBufferLength
>= sizeof(FILE_REPLY_CONNECT
))) {
848 FCB
= IrpSp
->FileObject
->FsContext
;
850 Request
= (PFILE_REQUEST_CONNECT
)Irp
->AssociatedIrp
.SystemBuffer
;
851 Reply
= (PFILE_REPLY_CONNECT
)Irp
->AssociatedIrp
.SystemBuffer
;
853 AFD_DbgPrint(MIN_TRACE
, ("\n"));
855 if (FCB
->State
== SOCKET_STATE_BOUND
) {
856 Reply
->Status
= WSAEADDRINUSE
;
857 } else if (FCB
->State
== SOCKET_STATE_CONNECTED
) {
858 Reply
->Status
= WSAEISCONN
;
860 /* We have an unbound socket so go ahead and create an address
861 file object and a connection endpoint and associate the two */
863 AFD_DbgPrint(MIN_TRACE
, ("\n"));
865 /* FIXME: Get from client */
866 LocalAddress
.sin_family
= AF_INET
;
867 LocalAddress
.sin_port
= 1700;
868 LocalAddress
.sin_addr
.S_un
.S_addr
= 0x0; /* Dynamically allocate */
870 Status
= TdiOpenAddressFile(
872 (LPSOCKADDR
)&LocalAddress
,
873 &FCB
->TdiAddressObjectHandle
,
874 &FCB
->TdiAddressObject
);
876 if (NT_SUCCESS(Status
)) {
877 AfdRegisterEventHandlers(FCB
);
878 FCB
->State
= SOCKET_STATE_BOUND
;
881 AFD_DbgPrint(MIN_TRACE
, ("\n"));
883 if (NT_SUCCESS(Status
)) {
884 Status
= TdiOpenConnectionEndpointFile(
886 &FCB
->TdiConnectionObjectHandle
,
887 &FCB
->TdiConnectionObject
);
890 AFD_DbgPrint(MIN_TRACE
, ("\n"));
892 if (NT_SUCCESS(Status
)) {
893 Status
= TdiAssociateAddressFile(
894 FCB
->TdiAddressObjectHandle
,
895 FCB
->TdiConnectionObject
);
898 AFD_DbgPrint(MIN_TRACE
, ("\n"));
900 if (NT_SUCCESS(Status
)) {
901 /* Now attempt to connect to the remote peer */
903 FCB
->TdiConnectionObject
,
907 AFD_DbgPrint(MIN_TRACE
, ("\n"));
909 if (NT_SUCCESS(Status
)) {
910 FCB
->State
= SOCKET_STATE_CONNECTED
;
911 Reply
->Status
= NO_ERROR
;
913 Reply
->Status
= WSAEINVAL
;
918 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));