1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/net/afd/afd/bind.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
WarmSocketForBind(PAFD_FCB FCB,ULONG ShareType)13 NTSTATUS WarmSocketForBind( PAFD_FCB FCB, ULONG ShareType ) {
14 NTSTATUS Status;
15
16 AFD_DbgPrint(MID_TRACE,("Called (AF %u)\n",
17 FCB->LocalAddress->Address[0].AddressType));
18
19 if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) {
20 AFD_DbgPrint(MIN_TRACE,("Null Device\n"));
21 return STATUS_NO_SUCH_DEVICE;
22 }
23 if( !FCB->LocalAddress ) {
24 AFD_DbgPrint(MIN_TRACE,("No local address\n"));
25 return STATUS_INVALID_PARAMETER;
26 }
27
28 Status = TdiOpenAddressFile(&FCB->TdiDeviceName,
29 FCB->LocalAddress,
30 ShareType,
31 &FCB->AddressFile.Handle,
32 &FCB->AddressFile.Object );
33 if (!NT_SUCCESS(Status))
34 return Status;
35
36 if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
37 {
38 if (!FCB->Recv.Size)
39 {
40 Status = TdiQueryMaxDatagramLength(FCB->AddressFile.Object,
41 &FCB->Recv.Size);
42 }
43
44 if (NT_SUCCESS(Status) && !FCB->Recv.Window)
45 {
46 FCB->Recv.Window = ExAllocatePoolWithTag(PagedPool,
47 FCB->Recv.Size,
48 TAG_AFD_DATA_BUFFER);
49
50 if (!FCB->Recv.Window)
51 Status = STATUS_NO_MEMORY;
52 }
53
54 if (NT_SUCCESS(Status) && FCB->Recv.Content < FCB->Recv.Size)
55 {
56 Status = TdiReceiveDatagram(&FCB->ReceiveIrp.InFlightRequest,
57 FCB->AddressFile.Object,
58 0,
59 FCB->Recv.Window,
60 FCB->Recv.Size,
61 FCB->AddressFrom,
62 PacketSocketRecvComplete,
63 FCB);
64
65 /* We don't want to wait for this read to complete. */
66 if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
67 }
68 }
69
70 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
71
72 return Status;
73 }
74
75 NTSTATUS NTAPI
AfdBindSocket(PDEVICE_OBJECT DeviceObject,PIRP Irp,PIO_STACK_LOCATION IrpSp)76 AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
77 PIO_STACK_LOCATION IrpSp) {
78 NTSTATUS Status = STATUS_SUCCESS;
79 PFILE_OBJECT FileObject = IrpSp->FileObject;
80 PAFD_FCB FCB = FileObject->FsContext;
81 PAFD_BIND_DATA BindReq;
82 HANDLE UserHandle = NULL;
83
84 UNREFERENCED_PARAMETER(DeviceObject);
85
86 AFD_DbgPrint(MID_TRACE,("Called\n"));
87
88 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
89 if( !(BindReq = LockRequest( Irp, IrpSp, FALSE, NULL )) )
90 return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
91 Irp, 0 );
92
93 if (FCB->LocalAddress)
94 {
95 ExFreePoolWithTag(FCB->LocalAddress, TAG_AFD_TRANSPORT_ADDRESS);
96 }
97
98 FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );
99
100 if( FCB->LocalAddress )
101 Status = TdiBuildConnectionInfo( &FCB->AddressFrom,
102 FCB->LocalAddress );
103
104 if( NT_SUCCESS(Status) )
105 Status = WarmSocketForBind( FCB, BindReq->ShareType );
106 AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags));
107
108 if (NT_SUCCESS(Status))
109 {
110 Status = ObOpenObjectByPointer(FCB->AddressFile.Object,
111 0,
112 NULL,
113 MAXIMUM_ALLOWED,
114 *IoFileObjectType,
115 Irp->RequestorMode,
116 &UserHandle);
117 if (NT_SUCCESS(Status))
118 FCB->State = SOCKET_STATE_BOUND;
119 }
120
121 /* MSAFD relies on us returning the address file handle in the IOSB */
122 return UnlockAndMaybeComplete( FCB, Status, Irp,
123 (ULONG_PTR)UserHandle);
124 }
125