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)
13 AfdGetInfo( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
14 PIO_STACK_LOCATION IrpSp
) {
15 NTSTATUS Status
= STATUS_SUCCESS
;
16 PAFD_INFO InfoReq
= LockRequest(Irp
, IrpSp
, TRUE
, NULL
);
17 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
18 PAFD_FCB FCB
= FileObject
->FsContext
;
19 PLIST_ENTRY CurrentEntry
;
21 UNREFERENCED_PARAMETER(DeviceObject
);
23 AFD_DbgPrint(MID_TRACE
,("Called %p %x\n", InfoReq
,
24 InfoReq
? InfoReq
->InformationClass
: 0));
26 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
29 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
32 switch( InfoReq
->InformationClass
) {
33 case AFD_INFO_RECEIVE_WINDOW_SIZE
:
34 InfoReq
->Information
.Ulong
= FCB
->Recv
.Size
;
37 case AFD_INFO_SEND_WINDOW_SIZE
:
38 InfoReq
->Information
.Ulong
= FCB
->Send
.Size
;
39 AFD_DbgPrint(MID_TRACE
,("Send window size %u\n", FCB
->Send
.Size
));
42 case AFD_INFO_GROUP_ID_TYPE
:
43 InfoReq
->Information
.LargeInteger
.u
.HighPart
= FCB
->GroupType
;
44 InfoReq
->Information
.LargeInteger
.u
.LowPart
= FCB
->GroupID
;
45 AFD_DbgPrint(MID_TRACE
, ("Group ID: %u Group Type: %u\n", FCB
->GroupID
, FCB
->GroupType
));
48 case AFD_INFO_BLOCKING_MODE
:
49 InfoReq
->Information
.Boolean
= FCB
->NonBlocking
;
52 case AFD_INFO_INLINING_MODE
:
53 InfoReq
->Information
.Boolean
= FCB
->OobInline
;
56 case AFD_INFO_RECEIVE_CONTENT_SIZE
:
57 InfoReq
->Information
.Ulong
= FCB
->Recv
.Content
- FCB
->Recv
.BytesUsed
;
60 case AFD_INFO_SENDS_IN_PROGRESS
:
61 InfoReq
->Information
.Ulong
= 0;
63 /* Count the queued sends */
64 CurrentEntry
= FCB
->PendingIrpList
[FUNCTION_SEND
].Flink
;
65 while (CurrentEntry
!= &FCB
->PendingIrpList
[FUNCTION_SEND
])
67 InfoReq
->Information
.Ulong
++;
68 CurrentEntry
= CurrentEntry
->Flink
;
71 /* This needs to count too because when this is dispatched
72 * the user-mode IRP has already been completed and therefore
73 * will NOT be in our pending IRP list. We count this as one send
74 * outstanding although it could be multiple since we batch sends
75 * when waiting for the in flight request to return, so this number
76 * may not be accurate but it really doesn't matter that much since
77 * it's more or less a zero/non-zero comparison to determine whether
78 * we can shutdown the socket
80 if (FCB
->SendIrp
.InFlightRequest
)
81 InfoReq
->Information
.Ulong
++;
85 AFD_DbgPrint(MIN_TRACE
,("Unknown info id %x\n",
86 InfoReq
->InformationClass
));
87 Status
= STATUS_INVALID_PARAMETER
;
90 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
91 AFD_DbgPrint(MIN_TRACE
,("Exception executing GetInfo\n"));
92 Status
= STATUS_INVALID_PARAMETER
;
95 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
97 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
101 AfdSetInfo( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
102 PIO_STACK_LOCATION IrpSp
) {
103 NTSTATUS Status
= STATUS_SUCCESS
;
104 PAFD_INFO InfoReq
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
105 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
106 PAFD_FCB FCB
= FileObject
->FsContext
;
109 UNREFERENCED_PARAMETER(DeviceObject
);
111 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
114 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
117 switch (InfoReq
->InformationClass
) {
118 case AFD_INFO_BLOCKING_MODE
:
119 AFD_DbgPrint(MID_TRACE
,("Blocking mode set to %u\n", InfoReq
->Information
.Boolean
));
120 FCB
->NonBlocking
= InfoReq
->Information
.Boolean
;
122 case AFD_INFO_INLINING_MODE
:
123 FCB
->OobInline
= InfoReq
->Information
.Boolean
;
125 case AFD_INFO_RECEIVE_WINDOW_SIZE
:
126 NewBuffer
= ExAllocatePool(PagedPool
, InfoReq
->Information
.Ulong
);
129 if (FCB
->Recv
.Content
> InfoReq
->Information
.Ulong
)
130 FCB
->Recv
.Content
= InfoReq
->Information
.Ulong
;
132 if (FCB
->Recv
.Window
)
134 RtlCopyMemory(NewBuffer
,
138 ExFreePool(FCB
->Recv
.Window
);
141 FCB
->Recv
.Size
= InfoReq
->Information
.Ulong
;
142 FCB
->Recv
.Window
= NewBuffer
;
144 Status
= STATUS_SUCCESS
;
148 Status
= STATUS_NO_MEMORY
;
151 case AFD_INFO_SEND_WINDOW_SIZE
:
152 NewBuffer
= ExAllocatePool(PagedPool
, InfoReq
->Information
.Ulong
);
155 if (FCB
->Send
.BytesUsed
> InfoReq
->Information
.Ulong
)
156 FCB
->Send
.BytesUsed
= InfoReq
->Information
.Ulong
;
158 if (FCB
->Send
.Window
)
160 RtlCopyMemory(NewBuffer
,
162 FCB
->Send
.BytesUsed
);
164 ExFreePool(FCB
->Send
.Window
);
167 FCB
->Send
.Size
= InfoReq
->Information
.Ulong
;
168 FCB
->Send
.Window
= NewBuffer
;
170 Status
= STATUS_SUCCESS
;
174 Status
= STATUS_NO_MEMORY
;
178 AFD_DbgPrint(MIN_TRACE
,("Unknown request %u\n", InfoReq
->InformationClass
));
181 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
182 AFD_DbgPrint(MIN_TRACE
,("Exception executing SetInfo\n"));
183 Status
= STATUS_INVALID_PARAMETER
;
186 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
188 return UnlockAndMaybeComplete(FCB
, Status
, Irp
, 0);
192 AfdGetSockName( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
193 PIO_STACK_LOCATION IrpSp
) {
194 NTSTATUS Status
= STATUS_SUCCESS
;
195 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
196 PAFD_FCB FCB
= FileObject
->FsContext
;
199 UNREFERENCED_PARAMETER(DeviceObject
);
201 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
203 if( FCB
->AddressFile
.Object
== NULL
&& FCB
->Connection
.Object
== NULL
) {
204 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
207 Mdl
= IoAllocateMdl( Irp
->UserBuffer
,
208 IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
,
215 MmProbeAndLockPages( Mdl
, Irp
->RequestorMode
, IoModifyAccess
);
216 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
217 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
218 Status
= _SEH2_GetExceptionCode();
221 if( NT_SUCCESS(Status
) ) {
222 Status
= TdiQueryInformation( FCB
->Connection
.Object
223 ? FCB
->Connection
.Object
224 : FCB
->AddressFile
.Object
,
225 TDI_QUERY_ADDRESS_INFO
,
229 Status
= STATUS_INSUFFICIENT_RESOURCES
;
231 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
235 AfdGetPeerName( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
236 PIO_STACK_LOCATION IrpSp
) {
238 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
239 PAFD_FCB FCB
= FileObject
->FsContext
;
241 UNREFERENCED_PARAMETER(DeviceObject
);
243 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
245 if (FCB
->RemoteAddress
== NULL
) {
246 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
247 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
250 if (IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
>= TaLengthOfTransportAddress(FCB
->RemoteAddress
))
252 RtlCopyMemory(Irp
->UserBuffer
, FCB
->RemoteAddress
, TaLengthOfTransportAddress(FCB
->RemoteAddress
));
253 Status
= STATUS_SUCCESS
;
257 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
258 Status
= STATUS_BUFFER_TOO_SMALL
;
261 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );