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));