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
));
133 NTSTATUS
AfdDispListen(
135 PIO_STACK_LOCATION IrpSp
)
137 * FUNCTION: Starts listening for connections
139 * Irp = Pointer to I/O request packet
140 * IrpSp = Pointer to current stack location of Irp
142 * Status of operation
146 UINT InputBufferLength
;
147 UINT OutputBufferLength
;
148 PFILE_REQUEST_LISTEN Request
;
149 PFILE_REPLY_LISTEN Reply
;
152 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
153 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
155 /* Validate parameters */
156 Status
= STATUS_INVALID_PARAMETER
;
157 if ((InputBufferLength
>= sizeof(FILE_REQUEST_LISTEN
)) &&
158 (OutputBufferLength
>= sizeof(FILE_REPLY_LISTEN
))) {
159 FCB
= IrpSp
->FileObject
->FsContext
;
161 Request
= (PFILE_REQUEST_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
162 Reply
= (PFILE_REPLY_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
164 if (FCB
->State
== SOCKET_STATE_BOUND
) {
166 /* We have a bound socket so go ahead and create a connection endpoint
167 and associate it with the address file object */
169 Status
= TdiOpenConnectionEndpointFile(
171 &FCB
->TdiConnectionObjectHandle
,
172 &FCB
->TdiConnectionObject
);
174 if (NT_SUCCESS(Status
)) {
175 Status
= TdiAssociateAddressFile(
176 FCB
->TdiAddressObjectHandle
,
177 FCB
->TdiConnectionObject
);
180 if (NT_SUCCESS(Status
)) {
181 Reply
->Status
= NO_ERROR
;
183 Reply
->Status
= WSAEINVAL
;
185 } else if (FCB
->State
== SOCKET_STATE_CONNECTED
) {
186 Reply
->Status
= WSAEISCONN
;
188 Reply
->Status
= WSAEINVAL
;
192 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
198 NTSTATUS
AfdDispSendTo(
200 PIO_STACK_LOCATION IrpSp
)
202 * FUNCTION: Sends data to an address
204 * Irp = Pointer to I/O request packet
205 * IrpSp = Pointer to current stack location of Irp
207 * Status of operation
211 UINT InputBufferLength
;
212 UINT OutputBufferLength
;
213 PFILE_REQUEST_SENDTO Request
;
214 PFILE_REPLY_SENDTO Reply
;
216 PVOID SystemVirtualAddress
;
217 PVOID DataBufferAddress
;
222 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
223 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
225 /* Validate parameters */
226 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SENDTO
)) &&
227 (OutputBufferLength
>= sizeof(FILE_REPLY_SENDTO
))) {
229 AFD_DbgPrint(MAX_TRACE
, ("FileObject at (0x%X).\n", IrpSp
->FileObject
));
230 AFD_DbgPrint(MAX_TRACE
, ("FCB at (0x%X).\n", IrpSp
->FileObject
->FsContext
));
231 AFD_DbgPrint(MAX_TRACE
, ("CCB at (0x%X).\n", IrpSp
->FileObject
->FsContext2
));
233 FCB
= IrpSp
->FileObject
->FsContext
;
234 Request
= (PFILE_REQUEST_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
235 Reply
= (PFILE_REPLY_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
237 /* Since we're using bufferred I/O */
238 Request
->Buffers
= (LPWSABUF
)(Request
+ 1);
239 BufferSize
= WSABufferSize(Request
->Buffers
, Request
->BufferCount
);
242 /* FIXME: Should we handle special cases here? */
243 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
244 BufferSize
+= sizeof(IPv4_HEADER
);
248 if (BufferSize
!= 0) {
249 AFD_DbgPrint(MAX_TRACE
, ("Allocating %d bytes for send buffer.\n", BufferSize
));
250 SystemVirtualAddress
= ExAllocatePool(NonPagedPool
, BufferSize
);
251 if (!SystemVirtualAddress
) {
252 return STATUS_INSUFFICIENT_RESOURCES
;
255 /* FIXME: Should we handle special cases here? */
256 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
257 DataBufferAddress
= SystemVirtualAddress
+ sizeof(IPv4_HEADER
);
259 /* FIXME: Should TCP/IP driver assign source address for raw sockets? */
260 ((PSOCKADDR_IN
)&FCB
->SocketName
)->sin_addr
.S_un
.S_addr
= 0x0100007F;
263 (PIPv4_HEADER
)SystemVirtualAddress
,
269 DataBufferAddress
= SystemVirtualAddress
;
272 Status
= MergeWSABuffers(
274 Request
->BufferCount
,
278 if (!NT_SUCCESS(Status
)) {
279 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
283 SystemVirtualAddress
= NULL
;
288 SystemVirtualAddress
, /* Virtual address of buffer */
289 BufferSize
, /* Length of buffer */
290 FALSE
, /* Not secondary */
291 FALSE
, /* Don't charge quota */
292 NULL
); /* Don't use IRP */
294 ExFreePool(SystemVirtualAddress
);
295 return STATUS_INSUFFICIENT_RESOURCES
;
298 MmBuildMdlForNonPagedPool(Mdl
);
300 AFD_DbgPrint(MAX_TRACE
, ("System virtual address is (0x%X).\n", SystemVirtualAddress
));
301 AFD_DbgPrint(MAX_TRACE
, ("MDL for data buffer is at (0x%X).\n", Mdl
));
303 AFD_DbgPrint(MAX_TRACE
, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl
));
304 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl
->MdlFlags
));
305 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Next is at (0x%X).\n", Mdl
->Next
));
306 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Size is (0x%X).\n", Mdl
->Size
));
307 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl
->MappedSystemVa
));
308 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer StartVa is (0x%X).\n", Mdl
->StartVa
));
309 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl
->ByteCount
));
310 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl
->ByteOffset
));
316 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
318 } except(EXCEPTION_EXECUTE_HANDLER
) {
319 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
321 if (BufferSize
!= 0) {
322 ExFreePool(SystemVirtualAddress
);
324 return STATUS_UNSUCCESSFUL
;
329 Status
= TdiSendDatagram(FCB
->TdiAddressObject
,
334 /* FIXME: Assumes synchronous operation */
341 if (BufferSize
!= 0) {
342 ExFreePool(SystemVirtualAddress
);
345 Reply
->NumberOfBytesSent
= BufferSize
;
346 Reply
->Status
= NO_ERROR
;
348 Status
= STATUS_INVALID_PARAMETER
;
350 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
356 NTSTATUS
AfdDispRecvFrom(
358 PIO_STACK_LOCATION IrpSp
)
360 * FUNCTION: Receives data from an address
362 * Irp = Pointer to I/O request packet
363 * IrpSp = Pointer to current stack location of Irp
365 * Status of operation
369 UINT InputBufferLength
;
370 UINT OutputBufferLength
;
371 PFILE_REQUEST_RECVFROM Request
;
372 PFILE_REPLY_RECVFROM Reply
;
375 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
377 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
378 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
380 /* Validate parameters */
381 if ((InputBufferLength
>= sizeof(FILE_REQUEST_RECVFROM
)) &&
382 (OutputBufferLength
>= sizeof(FILE_REPLY_RECVFROM
))) {
383 FCB
= IrpSp
->FileObject
->FsContext
;
385 Request
= (PFILE_REQUEST_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
386 Reply
= (PFILE_REPLY_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
387 /* Since we're using bufferred I/O */
388 Request
->Buffers
= (LPWSABUF
)(Request
+ 1);
390 Status
= AfdpDispRecv(
396 Status
= STATUS_INVALID_PARAMETER
;
399 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
412 DWORD
AfdpDispSelectEx(
414 SelectOperation Operation
)
416 PFILE_OBJECT FileObject
;
423 AFD_DbgPrint(MAX_TRACE
, ("FDSet (0x%X) Operation (0x%X).\n",
426 AFD_DbgPrint(MAX_TRACE
, ("FDSet->fd_count (0x%X).\n", FDSet
->fd_count
));
429 for (i
= 0; i
< FDSet
->fd_count
; i
++) {
431 AFD_DbgPrint(MAX_TRACE
, ("Handle (0x%X).\n", FDSet
->fd_array
[i
]));
433 Status
= ObReferenceObjectByHandle(
434 (HANDLE
)FDSet
->fd_array
[i
],
440 if (NT_SUCCESS(Status
)) {
441 AFD_DbgPrint(MAX_TRACE
, ("File object is at (0x%X).\n", FileObject
));
443 Current
= FileObject
->FsContext
;
447 KeAcquireSpinLock(&Current
->ReceiveQueueLock
, &OldIrql
);
448 if (!IsListEmpty(&Current
->ReceiveQueue
)) {
449 AFD_DbgPrint(MAX_TRACE
, ("Socket is readable.\n"));
452 KeReleaseSpinLock(&Current
->ReceiveQueueLock
, OldIrql
);
455 /* FIXME: How can we check for writability? */
459 /* FIXME: What is this? */
464 ObDereferenceObject(FileObject
);
471 NTSTATUS
AfdDispSelect(
473 PIO_STACK_LOCATION IrpSp
)
475 * FUNCTION: Checks if sockets have data in the receive buffers
476 * and/or if client can send data
478 * Irp = Pointer to I/O request packet
479 * IrpSp = Pointer to current stack location of Irp
481 * Status of operation
485 UINT InputBufferLength
;
486 UINT OutputBufferLength
;
487 PFILE_REQUEST_SELECT Request
;
488 PFILE_REPLY_SELECT Reply
;
492 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
493 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
495 /* Validate parameters */
496 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SELECT
)) &&
497 (OutputBufferLength
>= sizeof(FILE_REPLY_SELECT
))) {
498 FCB
= IrpSp
->FileObject
->FsContext
;
500 Request
= (PFILE_REQUEST_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
501 Reply
= (PFILE_REPLY_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
503 AFD_DbgPrint(MAX_TRACE
, ("R (0x%X) W (0x%X).\n",
504 Request
->ReadFDSet
, Request
->WriteFDSet
));
508 if (Request
->WriteFDSet
) {
509 AFD_DbgPrint(MAX_TRACE
, ("Write.\n"));
510 SocketCount
+= AfdpDispSelectEx(Request
->WriteFDSet
, soWrite
);
512 if (Request
->ReadFDSet
) {
513 AFD_DbgPrint(MAX_TRACE
, ("Read.\n"));
514 SocketCount
+= AfdpDispSelectEx(Request
->ReadFDSet
, soRead
);
516 if (Request
->ExceptFDSet
) {
517 SocketCount
+= AfdpDispSelectEx(Request
->ExceptFDSet
, soExcept
);
520 AFD_DbgPrint(MAX_TRACE
, ("Sockets selected (0x%X).\n", SocketCount
));
522 Reply
->Status
= NO_ERROR
;
523 Reply
->SocketCount
= SocketCount
;
524 Status
= STATUS_SUCCESS
;
526 Status
= STATUS_INVALID_PARAMETER
;
528 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
533 NTSTATUS
AfdDispEventSelect(
535 PIO_STACK_LOCATION IrpSp
)
537 * FUNCTION: Associate an event object with one or more network events
539 * Irp = Pointer to I/O request packet
540 * IrpSp = Pointer to current stack location of Irp
542 * Status of operation
546 UINT InputBufferLength
;
547 UINT OutputBufferLength
;
548 PFILE_REQUEST_EVENTSELECT Request
;
549 PFILE_REPLY_EVENTSELECT Reply
;
553 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
554 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
556 /* Validate parameters */
557 if ((InputBufferLength
>= sizeof(FILE_REQUEST_EVENTSELECT
)) &&
558 (OutputBufferLength
>= sizeof(FILE_REPLY_EVENTSELECT
))) {
559 FCB
= IrpSp
->FileObject
->FsContext
;
561 Request
= (PFILE_REQUEST_EVENTSELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
562 Reply
= (PFILE_REPLY_EVENTSELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
564 FCB
->NetworkEvents
.lNetworkEvents
= Request
->lNetworkEvents
;
565 for (i
= 0; i
< FD_MAX_EVENTS
; i
++) {
566 if ((Request
->lNetworkEvents
& (1 << i
)) > 0) {
567 FCB
->EventObjects
[i
] = Request
->hEventObject
;
569 /* The effect of any previous call to this function is cancelled */
570 FCB
->EventObjects
[i
] = (WSAEVENT
)0;
574 Reply
->Status
= NO_ERROR
;
575 Status
= STATUS_SUCCESS
;
577 Status
= STATUS_INVALID_PARAMETER
;
579 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
584 NTSTATUS
AfdDispEnumNetworkEvents(
586 PIO_STACK_LOCATION IrpSp
)
588 * FUNCTION: Reports network events
590 * Irp = Pointer to I/O request packet
591 * IrpSp = Pointer to current stack location of Irp
593 * Status of operation
597 UINT InputBufferLength
;
598 UINT OutputBufferLength
;
599 PFILE_REQUEST_ENUMNETWORKEVENTS Request
;
600 PFILE_REPLY_ENUMNETWORKEVENTS Reply
;
604 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
605 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
607 /* Validate parameters */
608 if ((InputBufferLength
>= sizeof(FILE_REQUEST_ENUMNETWORKEVENTS
)) &&
609 (OutputBufferLength
>= sizeof(FILE_REPLY_ENUMNETWORKEVENTS
))) {
610 FCB
= IrpSp
->FileObject
->FsContext
;
612 Request
= (PFILE_REQUEST_ENUMNETWORKEVENTS
)Irp
->AssociatedIrp
.SystemBuffer
;
613 Reply
= (PFILE_REPLY_ENUMNETWORKEVENTS
)Irp
->AssociatedIrp
.SystemBuffer
;
615 EventObject
= (HANDLE
)Request
->hEventObject
;
618 &Reply
->NetworkEvents
,
620 sizeof(WSANETWORKEVENTS
));
624 sizeof(WSANETWORKEVENTS
));
626 if (EventObject
!= NULL
) {
627 ZwClearEvent(EventObject
);
630 Reply
->Status
= NO_ERROR
;
631 Status
= STATUS_SUCCESS
;
633 Status
= STATUS_INVALID_PARAMETER
;
635 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
641 NTSTATUS
AfdDispRecv(
643 PIO_STACK_LOCATION IrpSp
)
645 * FUNCTION: Receives data from an address
647 * Irp = Pointer to I/O request packet
648 * IrpSp = Pointer to current stack location of Irp
650 * Status of operation
655 UINT InputBufferLength
;
656 UINT OutputBufferLength
;
657 PFILE_REQUEST_RECV Request
;
658 PFILE_REPLY_RECV Reply
;
659 DWORD NumberOfBytesRecvd
;
662 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
664 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
665 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
667 /* Validate parameters */
668 if ((InputBufferLength
>= sizeof(FILE_REQUEST_RECV
)) &&
669 (OutputBufferLength
>= sizeof(FILE_REPLY_RECV
))) {
670 FCB
= IrpSp
->FileObject
->FsContext
;
672 Request
= (PFILE_REQUEST_RECV
)Irp
->AssociatedIrp
.SystemBuffer
;
673 Reply
= (PFILE_REPLY_RECV
)Irp
->AssociatedIrp
.SystemBuffer
;
675 Status
= AfdpDispRecv(
679 Request
->BufferCount
,
680 &NumberOfBytesRecvd
);
681 Reply
->NumberOfBytesRecvd
= NumberOfBytesRecvd
;
682 Reply
->Status
= NO_ERROR
;
684 Status
= STATUS_INVALID_PARAMETER
;
687 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
691 return STATUS_SUCCESS
;
696 NTSTATUS
AfdDispSend(
698 PIO_STACK_LOCATION IrpSp
)
700 * FUNCTION: Sends data
702 * Irp = Pointer to I/O request packet
703 * IrpSp = Pointer to current stack location of Irp
705 * Status of operation
709 UINT InputBufferLength
;
710 UINT OutputBufferLength
;
711 PFILE_REQUEST_SEND Request
;
712 PFILE_REPLY_SEND Reply
;
715 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
716 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
718 /* Validate parameters */
719 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SEND
)) &&
720 (OutputBufferLength
>= sizeof(FILE_REPLY_SEND
))) {
721 FCB
= IrpSp
->FileObject
->FsContext
;
723 Request
= (PFILE_REQUEST_SEND
)Irp
->AssociatedIrp
.SystemBuffer
;
724 Reply
= (PFILE_REPLY_SEND
)Irp
->AssociatedIrp
.SystemBuffer
;
726 Reply
->NumberOfBytesSent
= 0;
727 Reply
->Status
= NO_ERROR
;
729 Status
= STATUS_INVALID_PARAMETER
;
731 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
737 NTSTATUS
AfdDispConnect(
739 PIO_STACK_LOCATION IrpSp
)
741 * FUNCTION: Connect to a remote peer
743 * Irp = Pointer to I/O request packet
744 * IrpSp = Pointer to current stack location of Irp
746 * Status of operation
750 UINT InputBufferLength
;
751 UINT OutputBufferLength
;
752 PFILE_REQUEST_CONNECT Request
;
753 PFILE_REPLY_CONNECT Reply
;
755 SOCKADDR_IN LocalAddress
;
757 AFD_DbgPrint(MIN_TRACE
, ("\n"));
759 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
760 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
762 /* Validate parameters */
763 Status
= STATUS_INVALID_PARAMETER
;
764 if ((InputBufferLength
>= sizeof(FILE_REQUEST_CONNECT
)) &&
765 (OutputBufferLength
>= sizeof(FILE_REPLY_CONNECT
))) {
766 FCB
= IrpSp
->FileObject
->FsContext
;
768 Request
= (PFILE_REQUEST_CONNECT
)Irp
->AssociatedIrp
.SystemBuffer
;
769 Reply
= (PFILE_REPLY_CONNECT
)Irp
->AssociatedIrp
.SystemBuffer
;
771 AFD_DbgPrint(MIN_TRACE
, ("\n"));
773 if (FCB
->State
== SOCKET_STATE_BOUND
) {
774 Reply
->Status
= WSAEADDRINUSE
;
775 } else if (FCB
->State
== SOCKET_STATE_CONNECTED
) {
776 Reply
->Status
= WSAEISCONN
;
778 /* We have an unbound socket so go ahead and create an address
779 file object and a connection endpoint and associate the two */
781 AFD_DbgPrint(MIN_TRACE
, ("\n"));
783 /* FIXME: Get from client */
784 LocalAddress
.sin_family
= AF_INET
;
785 LocalAddress
.sin_port
= 1700;
786 LocalAddress
.sin_addr
.S_un
.S_addr
= 0x0; /* Dynamically allocate */
788 Status
= TdiOpenAddressFile(
790 (LPSOCKADDR
)&LocalAddress
,
791 &FCB
->TdiAddressObjectHandle
,
792 &FCB
->TdiAddressObject
);
794 if (NT_SUCCESS(Status
)) {
795 AfdRegisterEventHandlers(FCB
);
796 FCB
->State
= SOCKET_STATE_BOUND
;
799 AFD_DbgPrint(MIN_TRACE
, ("\n"));
801 if (NT_SUCCESS(Status
)) {
802 Status
= TdiOpenConnectionEndpointFile(
804 &FCB
->TdiConnectionObjectHandle
,
805 &FCB
->TdiConnectionObject
);
808 AFD_DbgPrint(MIN_TRACE
, ("\n"));
810 if (NT_SUCCESS(Status
)) {
811 Status
= TdiAssociateAddressFile(
812 FCB
->TdiAddressObjectHandle
,
813 FCB
->TdiConnectionObject
);
816 AFD_DbgPrint(MIN_TRACE
, ("\n"));
818 if (NT_SUCCESS(Status
)) {
819 /* Now attempt to connect to the remote peer */
821 FCB
->TdiConnectionObject
,
825 AFD_DbgPrint(MIN_TRACE
, ("\n"));
827 if (NT_SUCCESS(Status
)) {
828 FCB
->State
= SOCKET_STATE_CONNECTED
;
829 Reply
->Status
= NO_ERROR
;
831 Reply
->Status
= WSAEINVAL
;
836 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));