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
;
100 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
101 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
103 /* Validate parameters */
104 if ((InputBufferLength
>= sizeof(FILE_REQUEST_BIND
)) &&
105 (OutputBufferLength
>= sizeof(FILE_REPLY_BIND
))) {
106 FCB
= IrpSp
->FileObject
->FsContext
;
108 Request
= (PFILE_REQUEST_BIND
)Irp
->AssociatedIrp
.SystemBuffer
;
109 Reply
= (PFILE_REPLY_BIND
)Irp
->AssociatedIrp
.SystemBuffer
;
111 Status
= TdiOpenAddressFile(
114 &FCB
->TdiAddressObjectHandle
,
115 &FCB
->TdiAddressObject
);
117 if (NT_SUCCESS(Status
)) {
118 AfdRegisterEventHandlers(FCB
);
119 FCB
->State
= SOCKET_STATE_BOUND
;
120 Reply
->Status
= NO_ERROR
;
122 //FIXME: WSAEADDRNOTAVAIL
123 Reply
->Status
= WSAEINVAL
;
126 Status
= STATUS_INVALID_PARAMETER
;
128 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
134 NTSTATUS
AfdDispListen(
136 PIO_STACK_LOCATION IrpSp
)
138 * FUNCTION: Starts listening for connections
140 * Irp = Pointer to I/O request packet
141 * IrpSp = Pointer to current stack location of Irp
143 * Status of operation
147 UINT InputBufferLength
;
148 UINT OutputBufferLength
;
149 PFILE_REQUEST_LISTEN Request
;
150 PFILE_REPLY_LISTEN Reply
;
153 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
154 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
156 /* Validate parameters */
157 Status
= STATUS_INVALID_PARAMETER
;
158 if ((InputBufferLength
>= sizeof(FILE_REQUEST_LISTEN
)) &&
159 (OutputBufferLength
>= sizeof(FILE_REPLY_LISTEN
))) {
160 FCB
= IrpSp
->FileObject
->FsContext
;
162 Request
= (PFILE_REQUEST_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
163 Reply
= (PFILE_REPLY_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
165 if (FCB
->State
== SOCKET_STATE_BOUND
) {
167 /* We have a bound socket so go ahead and create a connection endpoint
168 and associate it with the address file object */
170 Status
= TdiOpenConnectionEndpointFile(
172 &FCB
->TdiConnectionObjectHandle
,
173 &FCB
->TdiConnectionObject
);
175 if (NT_SUCCESS(Status
)) {
176 Status
= TdiAssociateAddressFile(
177 FCB
->TdiAddressObjectHandle
,
178 FCB
->TdiConnectionObject
);
181 if (NT_SUCCESS(Status
)) {
182 Reply
->Status
= NO_ERROR
;
184 Reply
->Status
= WSAEINVAL
;
186 } else if (FCB
->State
== SOCKET_STATE_CONNECTED
) {
187 Reply
->Status
= WSAEISCONN
;
189 Reply
->Status
= WSAEINVAL
;
193 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
199 NTSTATUS
AfdDispSendTo(
201 PIO_STACK_LOCATION IrpSp
)
203 * FUNCTION: Sends data to an address
205 * Irp = Pointer to I/O request packet
206 * IrpSp = Pointer to current stack location of Irp
208 * Status of operation
212 UINT InputBufferLength
;
213 UINT OutputBufferLength
;
214 PFILE_REQUEST_SENDTO Request
;
215 PFILE_REPLY_SENDTO Reply
;
217 PVOID SystemVirtualAddress
;
218 PVOID DataBufferAddress
;
223 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
224 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
226 /* Validate parameters */
227 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SENDTO
)) &&
228 (OutputBufferLength
>= sizeof(FILE_REPLY_SENDTO
))) {
230 AFD_DbgPrint(MAX_TRACE
, ("FileObject at (0x%X).\n", IrpSp
->FileObject
));
231 AFD_DbgPrint(MAX_TRACE
, ("FCB at (0x%X).\n", IrpSp
->FileObject
->FsContext
));
232 AFD_DbgPrint(MAX_TRACE
, ("CCB at (0x%X).\n", IrpSp
->FileObject
->FsContext2
));
234 FCB
= IrpSp
->FileObject
->FsContext
;
235 Request
= (PFILE_REQUEST_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
236 Reply
= (PFILE_REPLY_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
238 /* Since we're using bufferred I/O */
239 Request
->Buffers
= (LPWSABUF
)(Request
+ 1);
240 BufferSize
= WSABufferSize(Request
->Buffers
, Request
->BufferCount
);
243 /* FIXME: Should we handle special cases here? */
244 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
245 BufferSize
+= sizeof(IPv4_HEADER
);
249 if (BufferSize
!= 0) {
250 AFD_DbgPrint(MAX_TRACE
, ("Allocating %d bytes for send buffer.\n", BufferSize
));
251 SystemVirtualAddress
= ExAllocatePool(NonPagedPool
, BufferSize
);
252 if (!SystemVirtualAddress
) {
253 return STATUS_INSUFFICIENT_RESOURCES
;
256 /* FIXME: Should we handle special cases here? */
257 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
258 DataBufferAddress
= SystemVirtualAddress
+ sizeof(IPv4_HEADER
);
260 /* FIXME: Should TCP/IP driver assign source address for raw sockets? */
261 ((PSOCKADDR_IN
)&FCB
->SocketName
)->sin_addr
.S_un
.S_addr
= 0x0100007F;
264 (PIPv4_HEADER
)SystemVirtualAddress
,
270 DataBufferAddress
= SystemVirtualAddress
;
273 Status
= MergeWSABuffers(
275 Request
->BufferCount
,
279 if (!NT_SUCCESS(Status
)) {
280 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
284 SystemVirtualAddress
= NULL
;
289 SystemVirtualAddress
, /* Virtual address of buffer */
290 BufferSize
, /* Length of buffer */
291 FALSE
, /* Not secondary */
292 FALSE
, /* Don't charge quota */
293 NULL
); /* Don't use IRP */
295 ExFreePool(SystemVirtualAddress
);
296 return STATUS_INSUFFICIENT_RESOURCES
;
299 MmBuildMdlForNonPagedPool(Mdl
);
301 AFD_DbgPrint(MAX_TRACE
, ("System virtual address is (0x%X).\n", SystemVirtualAddress
));
302 AFD_DbgPrint(MAX_TRACE
, ("MDL for data buffer is at (0x%X).\n", Mdl
));
304 AFD_DbgPrint(MAX_TRACE
, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl
));
305 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl
->MdlFlags
));
306 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Next is at (0x%X).\n", Mdl
->Next
));
307 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Size is (0x%X).\n", Mdl
->Size
));
308 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl
->MappedSystemVa
));
309 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer StartVa is (0x%X).\n", Mdl
->StartVa
));
310 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl
->ByteCount
));
311 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl
->ByteOffset
));
317 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
319 } except(EXCEPTION_EXECUTE_HANDLER
) {
320 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
322 if (BufferSize
!= 0) {
323 ExFreePool(SystemVirtualAddress
);
325 return STATUS_UNSUCCESSFUL
;
330 Status
= TdiSendDatagram(FCB
->TdiAddressObject
,
335 /* FIXME: Assumes synchronous operation */
342 if (BufferSize
!= 0) {
343 ExFreePool(SystemVirtualAddress
);
346 Reply
->NumberOfBytesSent
= BufferSize
;
347 Reply
->Status
= NO_ERROR
;
349 Status
= STATUS_INVALID_PARAMETER
;
351 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
357 NTSTATUS
AfdDispRecvFrom(
359 PIO_STACK_LOCATION IrpSp
)
361 * FUNCTION: Receives data from an address
363 * Irp = Pointer to I/O request packet
364 * IrpSp = Pointer to current stack location of Irp
366 * Status of operation
370 UINT InputBufferLength
;
371 UINT OutputBufferLength
;
372 PFILE_REQUEST_RECVFROM Request
;
373 PFILE_REPLY_RECVFROM Reply
;
374 DWORD NumberOfBytesRecvd
;
377 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
379 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
380 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
382 /* Validate parameters */
383 if ((InputBufferLength
>= sizeof(FILE_REQUEST_RECVFROM
)) &&
384 (OutputBufferLength
>= sizeof(FILE_REPLY_RECVFROM
))) {
385 FCB
= IrpSp
->FileObject
->FsContext
;
387 Request
= (PFILE_REQUEST_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
388 Reply
= (PFILE_REPLY_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
389 /* Since we're using bufferred I/O */
390 Request
->Buffers
= (LPWSABUF
)(Request
+ 1);
392 Status
= AfdpDispRecv(
398 Status
= STATUS_INVALID_PARAMETER
;
401 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
414 DWORD
AfdpDispSelectEx(
416 SelectOperation Operation
)
418 PFILE_OBJECT FileObject
;
425 AFD_DbgPrint(MAX_TRACE
, ("FDSet (0x%X) Operation (0x%X).\n",
428 AFD_DbgPrint(MAX_TRACE
, ("FDSet->fd_count (0x%X).\n", FDSet
->fd_count
));
431 for (i
= 0; i
< FDSet
->fd_count
; i
++) {
433 AFD_DbgPrint(MAX_TRACE
, ("Handle (0x%X).\n", FDSet
->fd_array
[i
]));
435 Status
= ObReferenceObjectByHandle(
436 (HANDLE
)FDSet
->fd_array
[i
],
442 if (NT_SUCCESS(Status
)) {
443 AFD_DbgPrint(MAX_TRACE
, ("File object is at (0x%X).\n", FileObject
));
445 Current
= FileObject
->FsContext
;
449 KeAcquireSpinLock(&Current
->ReceiveQueueLock
, &OldIrql
);
450 if (!IsListEmpty(&Current
->ReceiveQueue
)) {
451 AFD_DbgPrint(MAX_TRACE
, ("Socket is readable.\n"));
454 KeReleaseSpinLock(&Current
->ReceiveQueueLock
, OldIrql
);
457 /* FIXME: How can we check for writability? */
461 /* FIXME: What is this? */
466 ObDereferenceObject(FileObject
);
473 NTSTATUS
AfdDispSelect(
475 PIO_STACK_LOCATION IrpSp
)
477 * FUNCTION: Checks if sockets have data in the receive buffers
478 * and/or if client can send data
480 * Irp = Pointer to I/O request packet
481 * IrpSp = Pointer to current stack location of Irp
483 * Status of operation
487 UINT InputBufferLength
;
488 UINT OutputBufferLength
;
489 PFILE_REQUEST_SELECT Request
;
490 PFILE_REPLY_SELECT Reply
;
494 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
495 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
497 /* Validate parameters */
498 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SELECT
)) &&
499 (OutputBufferLength
>= sizeof(FILE_REPLY_SELECT
))) {
500 FCB
= IrpSp
->FileObject
->FsContext
;
502 Request
= (PFILE_REQUEST_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
503 Reply
= (PFILE_REPLY_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
505 AFD_DbgPrint(MAX_TRACE
, ("R (0x%X) W (0x%X).\n",
506 Request
->ReadFDSet
, Request
->WriteFDSet
));
510 if (Request
->WriteFDSet
) {
511 AFD_DbgPrint(MAX_TRACE
, ("Write.\n"));
512 SocketCount
+= AfdpDispSelectEx(Request
->WriteFDSet
, soWrite
);
514 if (Request
->ReadFDSet
) {
515 AFD_DbgPrint(MAX_TRACE
, ("Read.\n"));
516 SocketCount
+= AfdpDispSelectEx(Request
->ReadFDSet
, soRead
);
518 if (Request
->ExceptFDSet
) {
519 SocketCount
+= AfdpDispSelectEx(Request
->ExceptFDSet
, soExcept
);
522 AFD_DbgPrint(MAX_TRACE
, ("Sockets selected (0x%X).\n", SocketCount
));
524 Reply
->Status
= NO_ERROR
;
525 Reply
->SocketCount
= SocketCount
;
526 Status
= STATUS_SUCCESS
;
528 Status
= STATUS_INVALID_PARAMETER
;
530 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
535 NTSTATUS
AfdDispEventSelect(
537 PIO_STACK_LOCATION IrpSp
)
539 * FUNCTION: Associate an event object with one or more network events
541 * Irp = Pointer to I/O request packet
542 * IrpSp = Pointer to current stack location of Irp
544 * Status of operation
548 UINT InputBufferLength
;
549 UINT OutputBufferLength
;
550 PFILE_REQUEST_EVENTSELECT Request
;
551 PFILE_REPLY_EVENTSELECT Reply
;
555 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
556 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
558 /* Validate parameters */
559 if ((InputBufferLength
>= sizeof(FILE_REQUEST_EVENTSELECT
)) &&
560 (OutputBufferLength
>= sizeof(FILE_REPLY_EVENTSELECT
))) {
561 FCB
= IrpSp
->FileObject
->FsContext
;
563 Request
= (PFILE_REQUEST_EVENTSELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
564 Reply
= (PFILE_REPLY_EVENTSELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
566 FCB
->NetworkEvents
.lNetworkEvents
= Request
->lNetworkEvents
;
567 for (i
= 0; i
< FD_MAX_EVENTS
; i
++) {
568 if ((Request
->lNetworkEvents
& (1 << i
)) > 0) {
569 FCB
->EventObjects
[i
] = Request
->hEventObject
;
571 /* The effect of any previous call to this function is cancelled */
572 FCB
->EventObjects
[i
] = (WSAEVENT
)0;
576 Reply
->Status
= NO_ERROR
;
577 Status
= STATUS_SUCCESS
;
579 Status
= STATUS_INVALID_PARAMETER
;
581 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
586 NTSTATUS
AfdDispEnumNetworkEvents(
588 PIO_STACK_LOCATION IrpSp
)
590 * FUNCTION: Reports network events
592 * Irp = Pointer to I/O request packet
593 * IrpSp = Pointer to current stack location of Irp
595 * Status of operation
599 UINT InputBufferLength
;
600 UINT OutputBufferLength
;
601 PFILE_REQUEST_ENUMNETWORKEVENTS Request
;
602 PFILE_REPLY_ENUMNETWORKEVENTS Reply
;
606 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
607 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
609 /* Validate parameters */
610 if ((InputBufferLength
>= sizeof(FILE_REQUEST_ENUMNETWORKEVENTS
)) &&
611 (OutputBufferLength
>= sizeof(FILE_REPLY_ENUMNETWORKEVENTS
))) {
612 FCB
= IrpSp
->FileObject
->FsContext
;
614 Request
= (PFILE_REQUEST_ENUMNETWORKEVENTS
)Irp
->AssociatedIrp
.SystemBuffer
;
615 Reply
= (PFILE_REPLY_ENUMNETWORKEVENTS
)Irp
->AssociatedIrp
.SystemBuffer
;
617 EventObject
= (HANDLE
)Request
->hEventObject
;
620 &Reply
->NetworkEvents
,
622 sizeof(WSANETWORKEVENTS
));
626 sizeof(WSANETWORKEVENTS
));
628 if (EventObject
!= NULL
) {
629 ZwClearEvent(EventObject
);
632 Reply
->Status
= NO_ERROR
;
633 Status
= STATUS_SUCCESS
;
635 Status
= STATUS_INVALID_PARAMETER
;
637 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
643 NTSTATUS
AfdDispRecv(
645 PIO_STACK_LOCATION IrpSp
)
647 * FUNCTION: Receives data from an address
649 * Irp = Pointer to I/O request packet
650 * IrpSp = Pointer to current stack location of Irp
652 * Status of operation
657 UINT InputBufferLength
;
658 UINT OutputBufferLength
;
659 PFILE_REQUEST_RECV Request
;
660 PFILE_REPLY_RECV Reply
;
661 DWORD NumberOfBytesRecvd
;
664 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
666 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
667 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
669 /* Validate parameters */
670 if ((InputBufferLength
>= sizeof(FILE_REQUEST_RECV
)) &&
671 (OutputBufferLength
>= sizeof(FILE_REPLY_RECV
))) {
672 FCB
= IrpSp
->FileObject
->FsContext
;
674 Request
= (PFILE_REQUEST_RECV
)Irp
->AssociatedIrp
.SystemBuffer
;
675 Reply
= (PFILE_REPLY_RECV
)Irp
->AssociatedIrp
.SystemBuffer
;
677 Status
= AfdpDispRecv(
681 Request
->BufferCount
,
682 &NumberOfBytesRecvd
);
683 Reply
->NumberOfBytesRecvd
= NumberOfBytesRecvd
;
684 Reply
->Status
= NO_ERROR
;
686 Status
= STATUS_INVALID_PARAMETER
;
689 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
693 return STATUS_SUCCESS
;
698 NTSTATUS
AfdDispSend(
700 PIO_STACK_LOCATION IrpSp
)
702 * FUNCTION: Sends data
704 * Irp = Pointer to I/O request packet
705 * IrpSp = Pointer to current stack location of Irp
707 * Status of operation
711 UINT InputBufferLength
;
712 UINT OutputBufferLength
;
713 PFILE_REQUEST_SEND Request
;
714 PFILE_REPLY_SEND Reply
;
717 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
718 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
720 /* Validate parameters */
721 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SEND
)) &&
722 (OutputBufferLength
>= sizeof(FILE_REPLY_SEND
))) {
723 FCB
= IrpSp
->FileObject
->FsContext
;
725 Request
= (PFILE_REQUEST_SEND
)Irp
->AssociatedIrp
.SystemBuffer
;
726 Reply
= (PFILE_REPLY_SEND
)Irp
->AssociatedIrp
.SystemBuffer
;
728 Reply
->NumberOfBytesSent
= 0;
729 Reply
->Status
= NO_ERROR
;
731 Status
= STATUS_INVALID_PARAMETER
;
733 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
739 NTSTATUS
AfdDispConnect(
741 PIO_STACK_LOCATION IrpSp
)
743 * FUNCTION: Connect to a remote peer
745 * Irp = Pointer to I/O request packet
746 * IrpSp = Pointer to current stack location of Irp
748 * Status of operation
752 UINT InputBufferLength
;
753 UINT OutputBufferLength
;
754 PFILE_REQUEST_CONNECT Request
;
755 PFILE_REPLY_CONNECT Reply
;
757 SOCKADDR_IN LocalAddress
;
759 AFD_DbgPrint(MIN_TRACE
, ("\n"));
761 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
762 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
764 /* Validate parameters */
765 Status
= STATUS_INVALID_PARAMETER
;
766 if ((InputBufferLength
>= sizeof(FILE_REQUEST_CONNECT
)) &&
767 (OutputBufferLength
>= sizeof(FILE_REPLY_CONNECT
))) {
768 FCB
= IrpSp
->FileObject
->FsContext
;
770 Request
= (PFILE_REQUEST_CONNECT
)Irp
->AssociatedIrp
.SystemBuffer
;
771 Reply
= (PFILE_REPLY_CONNECT
)Irp
->AssociatedIrp
.SystemBuffer
;
773 AFD_DbgPrint(MIN_TRACE
, ("\n"));
775 if (FCB
->State
== SOCKET_STATE_BOUND
) {
776 Reply
->Status
= WSAEADDRINUSE
;
777 } else if (FCB
->State
== SOCKET_STATE_CONNECTED
) {
778 Reply
->Status
= WSAEISCONN
;
780 /* We have an unbound socket so go ahead and create an address
781 file object and a connection endpoint and associate the two */
783 AFD_DbgPrint(MIN_TRACE
, ("\n"));
785 /* FIXME: Get from client */
786 LocalAddress
.sin_family
= AF_INET
;
787 LocalAddress
.sin_port
= 1700;
788 LocalAddress
.sin_addr
.S_un
.S_addr
= 0x0; /* Dynamically allocate */
790 Status
= TdiOpenAddressFile(
792 (LPSOCKADDR
)&LocalAddress
,
793 &FCB
->TdiAddressObjectHandle
,
794 &FCB
->TdiAddressObject
);
796 if (NT_SUCCESS(Status
)) {
797 AfdRegisterEventHandlers(FCB
);
798 FCB
->State
= SOCKET_STATE_BOUND
;
801 AFD_DbgPrint(MIN_TRACE
, ("\n"));
803 if (NT_SUCCESS(Status
)) {
804 Status
= TdiOpenConnectionEndpointFile(
806 &FCB
->TdiConnectionObjectHandle
,
807 &FCB
->TdiConnectionObject
);
810 AFD_DbgPrint(MIN_TRACE
, ("\n"));
812 if (NT_SUCCESS(Status
)) {
813 Status
= TdiAssociateAddressFile(
814 FCB
->TdiAddressObjectHandle
,
815 FCB
->TdiConnectionObject
);
818 AFD_DbgPrint(MIN_TRACE
, ("\n"));
820 if (NT_SUCCESS(Status
)) {
821 /* Now attempt to connect to the remote peer */
823 FCB
->TdiConnectionObject
,
827 AFD_DbgPrint(MIN_TRACE
, ("\n"));
829 if (NT_SUCCESS(Status
)) {
830 FCB
->State
= SOCKET_STATE_CONNECTED
;
831 Reply
->Status
= NO_ERROR
;
833 Reply
->Status
= WSAEINVAL
;
838 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));