2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/net/afd/afd/info.c
5 * PURPOSE: Ancillary functions driver
6 * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
14 AfdGetInfo( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
15 PIO_STACK_LOCATION IrpSp
) {
16 NTSTATUS Status
= STATUS_SUCCESS
;
17 PAFD_INFO InfoReq
= LockRequest(Irp
, IrpSp
, TRUE
, NULL
);
18 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
19 PAFD_FCB FCB
= FileObject
->FsContext
;
20 PLIST_ENTRY CurrentEntry
;
22 UNREFERENCED_PARAMETER(DeviceObject
);
24 AFD_DbgPrint(MID_TRACE
,("Called %p %x\n", InfoReq
,
25 InfoReq
? InfoReq
->InformationClass
: 0));
27 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
30 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
33 switch( InfoReq
->InformationClass
) {
34 case AFD_INFO_RECEIVE_WINDOW_SIZE
:
35 InfoReq
->Information
.Ulong
= FCB
->Recv
.Size
;
38 case AFD_INFO_SEND_WINDOW_SIZE
:
39 InfoReq
->Information
.Ulong
= FCB
->Send
.Size
;
40 AFD_DbgPrint(MID_TRACE
,("Send window size %u\n", FCB
->Send
.Size
));
43 case AFD_INFO_GROUP_ID_TYPE
:
44 InfoReq
->Information
.LargeInteger
.u
.HighPart
= FCB
->GroupType
;
45 InfoReq
->Information
.LargeInteger
.u
.LowPart
= FCB
->GroupID
;
46 AFD_DbgPrint(MID_TRACE
, ("Group ID: %u Group Type: %u\n", FCB
->GroupID
, FCB
->GroupType
));
49 case AFD_INFO_BLOCKING_MODE
:
50 InfoReq
->Information
.Boolean
= FCB
->NonBlocking
;
53 case AFD_INFO_INLINING_MODE
:
54 InfoReq
->Information
.Boolean
= FCB
->OobInline
;
57 case AFD_INFO_RECEIVE_CONTENT_SIZE
:
58 InfoReq
->Information
.Ulong
= FCB
->Recv
.Content
- FCB
->Recv
.BytesUsed
;
61 case AFD_INFO_SENDS_IN_PROGRESS
:
62 InfoReq
->Information
.Ulong
= 0;
64 /* Count the queued sends */
65 CurrentEntry
= FCB
->PendingIrpList
[FUNCTION_SEND
].Flink
;
66 while (CurrentEntry
!= &FCB
->PendingIrpList
[FUNCTION_SEND
])
68 InfoReq
->Information
.Ulong
++;
69 CurrentEntry
= CurrentEntry
->Flink
;
72 /* This needs to count too because when this is dispatched
73 * the user-mode IRP has already been completed and therefore
74 * will NOT be in our pending IRP list. We count this as one send
75 * outstanding although it could be multiple since we batch sends
76 * when waiting for the in flight request to return, so this number
77 * may not be accurate but it really doesn't matter that much since
78 * it's more or less a zero/non-zero comparison to determine whether
79 * we can shutdown the socket
81 if (FCB
->SendIrp
.InFlightRequest
)
82 InfoReq
->Information
.Ulong
++;
86 AFD_DbgPrint(MIN_TRACE
,("Unknown info id %x\n",
87 InfoReq
->InformationClass
));
88 Status
= STATUS_INVALID_PARAMETER
;
91 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
92 AFD_DbgPrint(MIN_TRACE
,("Exception executing GetInfo\n"));
93 Status
= STATUS_INVALID_PARAMETER
;
96 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
98 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
102 AfdSetInfo( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
103 PIO_STACK_LOCATION IrpSp
) {
104 NTSTATUS Status
= STATUS_SUCCESS
;
105 PAFD_INFO InfoReq
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
106 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
107 PAFD_FCB FCB
= FileObject
->FsContext
;
110 UNREFERENCED_PARAMETER(DeviceObject
);
112 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
115 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
118 switch (InfoReq
->InformationClass
) {
119 case AFD_INFO_BLOCKING_MODE
:
120 AFD_DbgPrint(MID_TRACE
,("Blocking mode set to %u\n", InfoReq
->Information
.Boolean
));
121 FCB
->NonBlocking
= InfoReq
->Information
.Boolean
;
123 case AFD_INFO_INLINING_MODE
:
124 FCB
->OobInline
= InfoReq
->Information
.Boolean
;
126 case AFD_INFO_RECEIVE_WINDOW_SIZE
:
127 NewBuffer
= ExAllocatePoolWithTag(PagedPool
,
128 InfoReq
->Information
.Ulong
,
129 TAG_AFD_DATA_BUFFER
);
133 if (FCB
->Recv
.Content
> InfoReq
->Information
.Ulong
)
134 FCB
->Recv
.Content
= InfoReq
->Information
.Ulong
;
136 if (FCB
->Recv
.Window
)
138 RtlCopyMemory(NewBuffer
,
142 ExFreePoolWithTag(FCB
->Recv
.Window
, TAG_AFD_DATA_BUFFER
);
145 FCB
->Recv
.Size
= InfoReq
->Information
.Ulong
;
146 FCB
->Recv
.Window
= NewBuffer
;
148 Status
= STATUS_SUCCESS
;
152 Status
= STATUS_NO_MEMORY
;
155 case AFD_INFO_SEND_WINDOW_SIZE
:
156 NewBuffer
= ExAllocatePoolWithTag(PagedPool
,
157 InfoReq
->Information
.Ulong
,
158 TAG_AFD_DATA_BUFFER
);
162 if (FCB
->Send
.BytesUsed
> InfoReq
->Information
.Ulong
)
163 FCB
->Send
.BytesUsed
= InfoReq
->Information
.Ulong
;
165 if (FCB
->Send
.Window
)
167 RtlCopyMemory(NewBuffer
,
169 FCB
->Send
.BytesUsed
);
171 ExFreePoolWithTag(FCB
->Send
.Window
, TAG_AFD_DATA_BUFFER
);
174 FCB
->Send
.Size
= InfoReq
->Information
.Ulong
;
175 FCB
->Send
.Window
= NewBuffer
;
177 Status
= STATUS_SUCCESS
;
181 Status
= STATUS_NO_MEMORY
;
185 AFD_DbgPrint(MIN_TRACE
,("Unknown request %u\n", InfoReq
->InformationClass
));
188 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
189 AFD_DbgPrint(MIN_TRACE
,("Exception executing SetInfo\n"));
190 Status
= STATUS_INVALID_PARAMETER
;
193 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
195 return UnlockAndMaybeComplete(FCB
, Status
, Irp
, 0);
199 AfdGetSockName( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
200 PIO_STACK_LOCATION IrpSp
) {
201 NTSTATUS Status
= STATUS_SUCCESS
;
202 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
203 PAFD_FCB FCB
= FileObject
->FsContext
;
206 UNREFERENCED_PARAMETER(DeviceObject
);
207 ASSERT(Irp
->MdlAddress
== NULL
);
209 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
211 if( FCB
->AddressFile
.Object
== NULL
&& FCB
->Connection
.Object
== NULL
) {
212 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
215 Mdl
= IoAllocateMdl( Irp
->UserBuffer
,
216 IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
,
223 MmProbeAndLockPages( Mdl
, Irp
->RequestorMode
, IoModifyAccess
);
224 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
225 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
226 Status
= _SEH2_GetExceptionCode();
229 if( NT_SUCCESS(Status
) ) {
230 Status
= TdiQueryInformation( FCB
->Connection
.Object
231 ? FCB
->Connection
.Object
232 : FCB
->AddressFile
.Object
,
233 TDI_QUERY_ADDRESS_INFO
,
237 /* Check if MmProbeAndLockPages or TdiQueryInformation failed and
239 if (!NT_SUCCESS(Status
) && Irp
->MdlAddress
!= Mdl
)
242 Status
= STATUS_INSUFFICIENT_RESOURCES
;
244 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
248 AfdGetPeerName( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
249 PIO_STACK_LOCATION IrpSp
) {
251 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
252 PAFD_FCB FCB
= FileObject
->FsContext
;
254 UNREFERENCED_PARAMETER(DeviceObject
);
256 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
258 if (FCB
->RemoteAddress
== NULL
) {
259 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
260 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
263 if (IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
>= TaLengthOfTransportAddress(FCB
->RemoteAddress
))
265 RtlCopyMemory(Irp
->UserBuffer
, FCB
->RemoteAddress
, TaLengthOfTransportAddress(FCB
->RemoteAddress
));
266 Status
= STATUS_SUCCESS
;
270 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
271 Status
= STATUS_BUFFER_TOO_SMALL
;
274 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );