- Store the address file handle in the IOSB
[reactos.git] / drivers / network / afd / afd / bind.c
1 /* $Id$
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 #include "tdi_proto.h"
13 #include "tdiconn.h"
14 #include "debug.h"
15
16 NTSTATUS WarmSocketForBind( PAFD_FCB FCB ) {
17 NTSTATUS Status;
18
19 AFD_DbgPrint(MID_TRACE,("Called (AF %d)\n",
20 FCB->LocalAddress->Address[0].AddressType));
21
22 if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) {
23 AFD_DbgPrint(MID_TRACE,("Null Device\n"));
24 return STATUS_NO_SUCH_DEVICE;
25 }
26 if( !FCB->LocalAddress ) {
27 AFD_DbgPrint(MID_TRACE,("No local address\n"));
28 return STATUS_INVALID_PARAMETER;
29 }
30
31 Status = TdiOpenAddressFile(&FCB->TdiDeviceName,
32 FCB->LocalAddress,
33 &FCB->AddressFile.Handle,
34 &FCB->AddressFile.Object );
35 if (!NT_SUCCESS(Status))
36 return Status;
37
38 if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
39 {
40 Status = TdiQueryMaxDatagramLength(FCB->AddressFile.Object,
41 &FCB->Recv.Size);
42 if (NT_SUCCESS(Status))
43 {
44 FCB->Recv.Window = ExAllocatePool(PagedPool, FCB->Recv.Size);
45 if (!FCB->Recv.Window)
46 Status = STATUS_NO_MEMORY;
47 }
48 }
49
50 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
51
52 return Status;
53 }
54
55 NTSTATUS NTAPI
56 AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
57 PIO_STACK_LOCATION IrpSp) {
58 NTSTATUS Status = STATUS_SUCCESS;
59 PFILE_OBJECT FileObject = IrpSp->FileObject;
60 PAFD_FCB FCB = FileObject->FsContext;
61 PAFD_BIND_DATA BindReq;
62
63 AFD_DbgPrint(MID_TRACE,("Called\n"));
64
65 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
66 if( !(BindReq = LockRequest( Irp, IrpSp )) )
67 return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
68 Irp, 0 );
69
70 if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
71 FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );
72
73 if( FCB->LocalAddress )
74 TdiBuildConnectionInfo( &FCB->AddressFrom,
75 FCB->LocalAddress );
76
77 if( FCB->AddressFrom )
78 Status = WarmSocketForBind( FCB );
79 else return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
80
81 AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags));
82
83 if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) {
84 AFD_DbgPrint(MID_TRACE,("Calling TdiReceiveDatagram\n"));
85
86 Status = TdiReceiveDatagram
87 ( &FCB->ReceiveIrp.InFlightRequest,
88 FCB->AddressFile.Object,
89 0,
90 FCB->Recv.Window,
91 FCB->Recv.Size,
92 FCB->AddressFrom,
93 &FCB->ReceiveIrp.Iosb,
94 PacketSocketRecvComplete,
95 FCB );
96
97 /* We don't want to wait for this read to complete. */
98 if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
99 }
100
101 if (NT_SUCCESS(Status))
102 FCB->State = SOCKET_STATE_BOUND;
103
104 /* MSAFD relies on us returning the address file handle in the IOSB */
105 return UnlockAndMaybeComplete( FCB, Status, Irp, (ULONG_PTR)FCB->AddressFile.Handle );
106 }
107