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
= ExAllocatePool(PagedPool
, InfoReq
->Information
.Ulong
);
130 if (FCB
->Recv
.Content
> InfoReq
->Information
.Ulong
)
131 FCB
->Recv
.Content
= InfoReq
->Information
.Ulong
;
133 if (FCB
->Recv
.Window
)
135 RtlCopyMemory(NewBuffer
,
139 ExFreePool(FCB
->Recv
.Window
);
142 FCB
->Recv
.Size
= InfoReq
->Information
.Ulong
;
143 FCB
->Recv
.Window
= NewBuffer
;
145 Status
= STATUS_SUCCESS
;
149 Status
= STATUS_NO_MEMORY
;
152 case AFD_INFO_SEND_WINDOW_SIZE
:
153 NewBuffer
= ExAllocatePool(PagedPool
, InfoReq
->Information
.Ulong
);
156 if (FCB
->Send
.BytesUsed
> InfoReq
->Information
.Ulong
)
157 FCB
->Send
.BytesUsed
= InfoReq
->Information
.Ulong
;
159 if (FCB
->Send
.Window
)
161 RtlCopyMemory(NewBuffer
,
163 FCB
->Send
.BytesUsed
);
165 ExFreePool(FCB
->Send
.Window
);
168 FCB
->Send
.Size
= InfoReq
->Information
.Ulong
;
169 FCB
->Send
.Window
= NewBuffer
;
171 Status
= STATUS_SUCCESS
;
175 Status
= STATUS_NO_MEMORY
;
179 AFD_DbgPrint(MIN_TRACE
,("Unknown request %u\n", InfoReq
->InformationClass
));
182 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
183 AFD_DbgPrint(MIN_TRACE
,("Exception executing SetInfo\n"));
184 Status
= STATUS_INVALID_PARAMETER
;
187 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
189 return UnlockAndMaybeComplete(FCB
, Status
, Irp
, 0);
193 AfdGetSockName( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
194 PIO_STACK_LOCATION IrpSp
) {
195 NTSTATUS Status
= STATUS_SUCCESS
;
196 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
197 PAFD_FCB FCB
= FileObject
->FsContext
;
200 UNREFERENCED_PARAMETER(DeviceObject
);
202 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
204 if( FCB
->AddressFile
.Object
== NULL
&& FCB
->Connection
.Object
== NULL
) {
205 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
208 Mdl
= IoAllocateMdl( Irp
->UserBuffer
,
209 IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
,
216 MmProbeAndLockPages( Mdl
, Irp
->RequestorMode
, IoModifyAccess
);
217 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
218 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
219 Status
= _SEH2_GetExceptionCode();
222 if( NT_SUCCESS(Status
) ) {
223 Status
= TdiQueryInformation( FCB
->Connection
.Object
224 ? FCB
->Connection
.Object
225 : FCB
->AddressFile
.Object
,
226 TDI_QUERY_ADDRESS_INFO
,
230 Status
= STATUS_INSUFFICIENT_RESOURCES
;
232 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
236 AfdGetPeerName( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
237 PIO_STACK_LOCATION IrpSp
) {
239 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
240 PAFD_FCB FCB
= FileObject
->FsContext
;
242 UNREFERENCED_PARAMETER(DeviceObject
);
244 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
246 if (FCB
->RemoteAddress
== NULL
) {
247 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
248 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
251 if (IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
>= TaLengthOfTransportAddress(FCB
->RemoteAddress
))
253 RtlCopyMemory(Irp
->UserBuffer
, FCB
->RemoteAddress
, TaLengthOfTransportAddress(FCB
->RemoteAddress
));
254 Status
= STATUS_SUCCESS
;
258 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
259 Status
= STATUS_BUFFER_TOO_SMALL
;
262 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );