xref: /reactos/drivers/network/afd/afd/bind.c (revision 05b4bd38)
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