2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/net/afd/afd/connect.c
5 * PURPOSE: Ancillary functions driver
6 * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
11 #include "tdi_proto.h"
15 NTSTATUS
WarmSocketForConnection( PAFD_FCB FCB
) {
18 if( !FCB
->TdiDeviceName
.Length
|| !FCB
->TdiDeviceName
.Buffer
) {
19 AFD_DbgPrint(MID_TRACE
,("Null Device\n"));
20 return STATUS_NO_SUCH_DEVICE
;
23 Status
= TdiOpenConnectionEndpointFile(&FCB
->TdiDeviceName
,
24 &FCB
->Connection
.Handle
,
25 &FCB
->Connection
.Object
);
27 if( NT_SUCCESS(Status
) ) {
28 Status
= TdiAssociateAddressFile( FCB
->AddressFile
.Handle
,
29 FCB
->Connection
.Object
);
35 NTSTATUS
MakeSocketIntoConnection( PAFD_FCB FCB
) {
36 NTSTATUS Status
= STATUS_NO_MEMORY
;
38 /* Allocate the receive area and start receiving */
40 ExAllocatePool( NonPagedPool
, FCB
->Recv
.Size
);
42 ExAllocatePool( NonPagedPool
, FCB
->Send
.Size
);
44 FCB
->State
= SOCKET_STATE_CONNECTED
;
46 if( FCB
->Recv
.Window
) {
47 Status
= TdiReceive( &FCB
->ReceiveIrp
.InFlightRequest
,
48 FCB
->Connection
.Object
,
52 &FCB
->ReceiveIrp
.Iosb
,
60 static NTSTATUS NTAPI StreamSocketConnectComplete
61 ( PDEVICE_OBJECT DeviceObject
,
64 NTSTATUS Status
= Irp
->IoStatus
.Status
;
65 PAFD_FCB FCB
= (PAFD_FCB
)Context
;
66 PLIST_ENTRY NextIrpEntry
;
69 AFD_DbgPrint(MID_TRACE
,("Called: FCB %x, FO %x\n",
70 Context
, FCB
->FileObject
));
72 /* I was wrong about this before as we can have pending writes to a not
73 * yet connected socket */
74 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
76 AFD_DbgPrint(MID_TRACE
,("Irp->IoStatus.Status = %x\n",
77 Irp
->IoStatus
.Status
));
79 if( NT_SUCCESS(Irp
->IoStatus
.Status
) ) {
80 FCB
->PollState
|= AFD_EVENT_CONNECT
| AFD_EVENT_SEND
;
81 FCB
->State
= SOCKET_STATE_CONNECTED
;
82 AFD_DbgPrint(MID_TRACE
,("Going to connected state %d\n", FCB
->State
));
83 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
85 FCB
->PollState
|= AFD_EVENT_CONNECT_FAIL
| AFD_EVENT_RECEIVE
;
86 AFD_DbgPrint(MID_TRACE
,("Going to bound state\n"));
87 FCB
->State
= SOCKET_STATE_BOUND
;
88 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
91 /* Succeed pending irps on the FUNCTION_CONNECT list */
92 while( !IsListEmpty( &FCB
->PendingIrpList
[FUNCTION_CONNECT
] ) ) {
93 NextIrpEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_CONNECT
]);
94 NextIrp
= CONTAINING_RECORD(NextIrpEntry
, IRP
, Tail
.Overlay
.ListEntry
);
95 AFD_DbgPrint(MID_TRACE
,("Completing connect %x\n", NextIrp
));
96 NextIrp
->IoStatus
.Status
= Status
;
97 NextIrp
->IoStatus
.Information
= 0;
98 if( NextIrp
->MdlAddress
) UnlockRequest( NextIrp
, IoGetCurrentIrpStackLocation( NextIrp
) );
99 IoCompleteRequest( NextIrp
, IO_NETWORK_INCREMENT
);
102 if( NT_SUCCESS(Status
) ) {
103 Status
= MakeSocketIntoConnection( FCB
);
105 if( FCB
->Send
.Window
&&
106 !IsListEmpty( &FCB
->PendingIrpList
[FUNCTION_SEND
] ) ) {
107 NextIrpEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_SEND
]);
108 NextIrp
= CONTAINING_RECORD(NextIrpEntry
, IRP
,
109 Tail
.Overlay
.ListEntry
);
110 AFD_DbgPrint(MID_TRACE
,("Launching send request %x\n", NextIrp
));
111 Status
= AfdConnectedSocketWriteData
114 IoGetCurrentIrpStackLocation( NextIrp
),
118 if( Status
== STATUS_PENDING
)
119 Status
= STATUS_SUCCESS
;
122 SocketStateUnlock( FCB
);
124 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
129 /* Return the socket object for ths request only if it is a connected or
132 AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
133 PIO_STACK_LOCATION IrpSp
) {
134 NTSTATUS Status
= STATUS_INVALID_PARAMETER
;
135 PTDI_CONNECTION_INFORMATION TargetAddress
;
136 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
137 PAFD_FCB FCB
= FileObject
->FsContext
;
138 PAFD_CONNECT_INFO ConnectReq
;
139 AFD_DbgPrint(MID_TRACE
,("Called on %x\n", FCB
));
141 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
142 if( !(ConnectReq
= LockRequest( Irp
, IrpSp
)) )
143 return UnlockAndMaybeComplete( FCB
, STATUS_NO_MEMORY
, Irp
,
146 AFD_DbgPrint(MID_TRACE
,("Connect request:\n"));
150 IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
);
153 switch( FCB
->State
) {
154 case SOCKET_STATE_CONNECTED
:
155 Status
= STATUS_SUCCESS
;
158 case SOCKET_STATE_CONNECTING
:
159 return LeaveIrpUntilLater( FCB
, Irp
, FUNCTION_CONNECT
);
161 case SOCKET_STATE_CREATED
: {
163 TaCopyTransportAddress( &ConnectReq
->RemoteAddress
);
165 if( FCB
->LocalAddress
) {
166 RtlZeroMemory( FCB
->LocalAddress
,
167 TaLengthOfTransportAddress
168 ( &ConnectReq
->RemoteAddress
) );
170 FCB
->LocalAddress
->TAAddressCount
= 1;
171 FCB
->LocalAddress
->Address
[0].AddressType
=
172 ConnectReq
->RemoteAddress
.Address
[0].AddressType
;
173 FCB
->LocalAddress
->Address
[0].AddressLength
=
174 ConnectReq
->RemoteAddress
.Address
[0].AddressLength
;
176 Status
= WarmSocketForBind( FCB
);
178 if( NT_SUCCESS(Status
) )
179 FCB
->State
= SOCKET_STATE_BOUND
;
181 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0, NULL
);
183 return UnlockAndMaybeComplete
184 ( FCB
, STATUS_NO_MEMORY
, Irp
, 0, NULL
);
185 } /* Drop through to SOCKET_STATE_BOUND */
187 case SOCKET_STATE_BOUND
:
189 TaCopyTransportAddress( &ConnectReq
->RemoteAddress
);
191 if( FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
)
193 Status
= STATUS_SUCCESS
;
197 Status
= WarmSocketForConnection( FCB
);
199 if( !NT_SUCCESS(Status
) )
202 FCB
->State
= SOCKET_STATE_CONNECTING
;
204 TdiBuildConnectionInfo
206 &ConnectReq
->RemoteAddress
);
208 if( TargetAddress
) {
209 Status
= TdiConnect( &FCB
->ConnectIrp
.InFlightRequest
,
210 FCB
->Connection
.Object
,
212 &FCB
->ConnectIrp
.Iosb
,
213 StreamSocketConnectComplete
,
216 ExFreePool( TargetAddress
);
218 AFD_DbgPrint(MID_TRACE
,("Queueing IRP %x\n", Irp
));
220 if( Status
== STATUS_PENDING
)
221 return LeaveIrpUntilLater( FCB
, Irp
, FUNCTION_CONNECT
);
222 } else Status
= STATUS_NO_MEMORY
;
226 AFD_DbgPrint(MID_TRACE
,("Inappropriate socket state %d for connect\n",
231 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0, NULL
);