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
24 ( &FCB
->TdiDeviceName
,
25 &FCB
->Connection
.Handle
,
26 &FCB
->Connection
.Object
);
28 if( NT_SUCCESS(Status
) ) {
29 Status
= TdiAssociateAddressFile
30 ( FCB
->AddressFile
.Handle
,
31 FCB
->Connection
.Object
);
34 if( !NT_SUCCESS(Status
) ) {
35 TdiCloseDevice( &FCB
->Connection
.Handle
,
36 FCB
->Connection
.Object
);
37 RtlZeroMemory( &FCB
->Connection
, sizeof(FCB
->Connection
) );
43 NTSTATUS
MakeSocketIntoConnection( PAFD_FCB FCB
) {
44 NTSTATUS Status
= STATUS_NO_MEMORY
;
46 /* Allocate the receive area and start receiving */
48 ExAllocatePool( NonPagedPool
, FCB
->Recv
.Size
);
50 ExAllocatePool( NonPagedPool
, FCB
->Send
.Size
);
52 FCB
->State
= SOCKET_STATE_CONNECTED
;
54 if( FCB
->Recv
.Window
) {
55 Status
= TdiReceive( &FCB
->ReceiveIrp
.InFlightRequest
,
56 FCB
->Connection
.Object
,
60 &FCB
->ReceiveIrp
.Iosb
,
68 static NTSTATUS NTAPI StreamSocketConnectComplete
69 ( PDEVICE_OBJECT DeviceObject
,
72 NTSTATUS Status
= Irp
->IoStatus
.Status
;
73 PAFD_FCB FCB
= (PAFD_FCB
)Context
;
74 PLIST_ENTRY NextIrpEntry
;
77 AFD_DbgPrint(MID_TRACE
,("Called: FCB %x, FO %x\n",
78 Context
, FCB
->FileObject
));
80 /* I was wrong about this before as we can have pending writes to a not
81 * yet connected socket */
82 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
, FALSE
);
84 AFD_DbgPrint(MID_TRACE
,("Irp->IoStatus.Status = %x\n",
85 Irp
->IoStatus
.Status
));
87 if( NT_SUCCESS(Irp
->IoStatus
.Status
) ) {
88 FCB
->PollState
|= AFD_EVENT_CONNECT
| AFD_EVENT_SEND
;
89 FCB
->State
= SOCKET_STATE_CONNECTED
;
90 AFD_DbgPrint(MID_TRACE
,("Going to connected state %d\n", FCB
->State
));
91 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
93 FCB
->PollState
|= AFD_EVENT_CONNECT_FAIL
| AFD_EVENT_RECEIVE
;
94 AFD_DbgPrint(MID_TRACE
,("Going to bound state\n"));
95 FCB
->State
= SOCKET_STATE_BOUND
;
96 PollReeval( FCB
->DeviceExt
, FCB
->FileObject
);
99 /* Succeed pending irps on the FUNCTION_CONNECT list */
100 while( !IsListEmpty( &FCB
->PendingIrpList
[FUNCTION_CONNECT
] ) ) {
101 NextIrpEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_CONNECT
]);
102 NextIrp
= CONTAINING_RECORD(NextIrpEntry
, IRP
, Tail
.Overlay
.ListEntry
);
103 AFD_DbgPrint(MID_TRACE
,("Completing connect %x\n", NextIrp
));
104 NextIrp
->IoStatus
.Status
= Status
;
105 NextIrp
->IoStatus
.Information
= 0;
106 IoCompleteRequest( NextIrp
, IO_NETWORK_INCREMENT
);
109 if( NT_SUCCESS(Status
) ) {
110 Status
= MakeSocketIntoConnection( FCB
);
112 if( FCB
->Send
.Window
&&
113 !IsListEmpty( &FCB
->PendingIrpList
[FUNCTION_SEND
] ) ) {
114 NextIrpEntry
= RemoveHeadList(&FCB
->PendingIrpList
[FUNCTION_SEND
]);
115 NextIrp
= CONTAINING_RECORD(NextIrpEntry
, IRP
,
116 Tail
.Overlay
.ListEntry
);
117 AFD_DbgPrint(MID_TRACE
,("Launching send request %x\n", NextIrp
));
118 Status
= AfdConnectedSocketWriteData
121 IoGetCurrentIrpStackLocation( NextIrp
),
125 if( Status
== STATUS_PENDING
)
126 Status
= STATUS_SUCCESS
;
129 SocketStateUnlock( FCB
);
131 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
136 /* Return the socket object for ths request only if it is a connected or
139 AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
140 PIO_STACK_LOCATION IrpSp
) {
141 NTSTATUS Status
= STATUS_INVALID_PARAMETER
;
142 PTDI_CONNECTION_INFORMATION TargetAddress
;
143 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
144 PAFD_FCB FCB
= FileObject
->FsContext
;
145 PAFD_CONNECT_INFO ConnectReq
;
146 AFD_DbgPrint(MID_TRACE
,("Called on %x\n", FCB
));
148 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
, FALSE
);
149 if( !(ConnectReq
= LockRequest( Irp
, IrpSp
)) )
150 return UnlockAndMaybeComplete( FCB
, STATUS_NO_MEMORY
, Irp
,
153 AFD_DbgPrint(MID_TRACE
,("Connect request:\n"));
157 IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
);
160 switch( FCB
->State
) {
161 case SOCKET_STATE_CONNECTED
:
162 Status
= STATUS_SUCCESS
;
165 case SOCKET_STATE_CONNECTING
:
166 return LeaveIrpUntilLater( FCB
, Irp
, FUNCTION_CONNECT
);
168 case SOCKET_STATE_CREATED
: {
170 TaCopyTransportAddress( &ConnectReq
->RemoteAddress
);
172 if( FCB
->LocalAddress
) {
173 RtlZeroMemory( FCB
->LocalAddress
,
174 TaLengthOfTransportAddress
175 ( &ConnectReq
->RemoteAddress
) );
177 FCB
->LocalAddress
->TAAddressCount
= 1;
178 FCB
->LocalAddress
->Address
[0].AddressType
=
179 ConnectReq
->RemoteAddress
.Address
[0].AddressType
;
180 FCB
->LocalAddress
->Address
[0].AddressLength
=
181 ConnectReq
->RemoteAddress
.Address
[0].AddressLength
;
183 Status
= WarmSocketForBind( FCB
);
185 if( NT_SUCCESS(Status
) )
186 FCB
->State
= SOCKET_STATE_BOUND
;
188 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0, NULL
,
191 return UnlockAndMaybeComplete
192 ( FCB
, STATUS_NO_MEMORY
, Irp
, 0, NULL
, TRUE
);
193 } /* Drop through to SOCKET_STATE_BOUND */
195 case SOCKET_STATE_BOUND
:
197 TaCopyTransportAddress( &ConnectReq
->RemoteAddress
);
199 if( FCB
->Flags
& AFD_ENDPOINT_CONNECTIONLESS
)
201 Status
= STATUS_SUCCESS
;
205 Status
= WarmSocketForConnection( FCB
);
207 if( !NT_SUCCESS(Status
) )
210 FCB
->State
= SOCKET_STATE_CONNECTING
;
212 TdiBuildConnectionInfo
214 &ConnectReq
->RemoteAddress
);
216 if( TargetAddress
) {
217 Status
= TdiConnect( &FCB
->ConnectIrp
.InFlightRequest
,
218 FCB
->Connection
.Object
,
220 &FCB
->ConnectIrp
.Iosb
,
221 StreamSocketConnectComplete
,
224 ExFreePool( TargetAddress
);
226 AFD_DbgPrint(MID_TRACE
,("Queueing IRP %x\n", Irp
));
228 if( Status
== STATUS_PENDING
)
229 return LeaveIrpUntilLater( FCB
, Irp
, FUNCTION_CONNECT
);
230 } else Status
= STATUS_NO_MEMORY
;
234 AFD_DbgPrint(MID_TRACE
,("Inappropriate socket state %d for connect\n",
239 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0, NULL
, TRUE
);