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 AFD_DbgPrint(MID_TRACE
,("Called %x %x\n", InfoReq
,
22 InfoReq
? InfoReq
->InformationClass
: 0));
24 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
27 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
30 switch( InfoReq
->InformationClass
) {
31 case AFD_INFO_RECEIVE_WINDOW_SIZE
:
32 InfoReq
->Information
.Ulong
= FCB
->Recv
.Size
;
35 case AFD_INFO_SEND_WINDOW_SIZE
:
36 InfoReq
->Information
.Ulong
= FCB
->Send
.Size
;
37 AFD_DbgPrint(MID_TRACE
,("Send window size %d\n", FCB
->Send
.Size
));
40 case AFD_INFO_GROUP_ID_TYPE
:
41 InfoReq
->Information
.LargeInteger
.u
.HighPart
= FCB
->GroupType
;
42 InfoReq
->Information
.LargeInteger
.u
.LowPart
= FCB
->GroupID
;
43 AFD_DbgPrint(MID_TRACE
, ("Group ID: %d Group Type: %d\n", FCB
->GroupID
, FCB
->GroupType
));
46 case AFD_INFO_BLOCKING_MODE
:
47 InfoReq
->Information
.Boolean
= FCB
->NonBlocking
;
50 case AFD_INFO_INLINING_MODE
:
51 InfoReq
->Information
.Boolean
= FCB
->OobInline
;
54 case AFD_INFO_RECEIVE_CONTENT_SIZE
:
55 InfoReq
->Information
.Ulong
= FCB
->Recv
.Content
- FCB
->Recv
.BytesUsed
;
58 case AFD_INFO_SENDS_IN_PROGRESS
:
59 InfoReq
->Information
.Ulong
= 0;
61 /* Count the queued sends */
62 CurrentEntry
= FCB
->PendingIrpList
[FUNCTION_SEND
].Flink
;
63 while (CurrentEntry
!= &FCB
->PendingIrpList
[FUNCTION_SEND
])
65 InfoReq
->Information
.Ulong
++;
66 CurrentEntry
= CurrentEntry
->Flink
;
69 /* This needs to count too because when this is dispatched
70 * the user-mode IRP has already been completed and therefore
71 * will NOT be in our pending IRP list. We count this as one send
72 * outstanding although it could be multiple since we batch sends
73 * when waiting for the in flight request to return, so this number
74 * may not be accurate but it really doesn't matter that much since
75 * it's more or less a zero/non-zero comparison to determine whether
76 * we can shutdown the socket
78 if (FCB
->SendIrp
.InFlightRequest
)
79 InfoReq
->Information
.Ulong
++;
83 AFD_DbgPrint(MIN_TRACE
,("Unknown info id %x\n",
84 InfoReq
->InformationClass
));
85 Status
= STATUS_INVALID_PARAMETER
;
88 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
89 AFD_DbgPrint(MIN_TRACE
,("Exception executing GetInfo\n"));
90 Status
= STATUS_INVALID_PARAMETER
;
93 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
95 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
99 AfdSetInfo( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
100 PIO_STACK_LOCATION IrpSp
) {
101 NTSTATUS Status
= STATUS_SUCCESS
;
102 PAFD_INFO InfoReq
= LockRequest(Irp
, IrpSp
, FALSE
, NULL
);
103 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
104 PAFD_FCB FCB
= FileObject
->FsContext
;
107 if (!SocketAcquireStateLock(FCB
)) return LostSocket(Irp
);
110 return UnlockAndMaybeComplete(FCB
, STATUS_NO_MEMORY
, Irp
, 0);
113 switch (InfoReq
->InformationClass
) {
114 case AFD_INFO_BLOCKING_MODE
:
115 AFD_DbgPrint(MID_TRACE
,("Blocking mode set to %d\n", InfoReq
->Information
.Boolean
));
116 FCB
->NonBlocking
= InfoReq
->Information
.Boolean
;
118 case AFD_INFO_INLINING_MODE
:
119 FCB
->OobInline
= InfoReq
->Information
.Boolean
;
121 case AFD_INFO_RECEIVE_WINDOW_SIZE
:
122 NewBuffer
= ExAllocatePool(PagedPool
, InfoReq
->Information
.Ulong
);
125 if (FCB
->Recv
.Content
> InfoReq
->Information
.Ulong
)
126 FCB
->Recv
.Content
= InfoReq
->Information
.Ulong
;
128 if (FCB
->Recv
.Window
)
130 RtlCopyMemory(NewBuffer
,
134 ExFreePool(FCB
->Recv
.Window
);
137 FCB
->Recv
.Size
= InfoReq
->Information
.Ulong
;
138 FCB
->Recv
.Window
= NewBuffer
;
140 Status
= STATUS_SUCCESS
;
144 Status
= STATUS_NO_MEMORY
;
147 case AFD_INFO_SEND_WINDOW_SIZE
:
148 NewBuffer
= ExAllocatePool(PagedPool
, InfoReq
->Information
.Ulong
);
151 if (FCB
->Send
.BytesUsed
> InfoReq
->Information
.Ulong
)
152 FCB
->Send
.BytesUsed
= InfoReq
->Information
.Ulong
;
154 if (FCB
->Send
.Window
)
156 RtlCopyMemory(NewBuffer
,
158 FCB
->Send
.BytesUsed
);
160 ExFreePool(FCB
->Send
.Window
);
163 FCB
->Send
.Size
= InfoReq
->Information
.Ulong
;
164 FCB
->Send
.Window
= NewBuffer
;
166 Status
= STATUS_SUCCESS
;
170 Status
= STATUS_NO_MEMORY
;
174 AFD_DbgPrint(MIN_TRACE
,("Unknown request %d\n", InfoReq
->InformationClass
));
177 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
178 AFD_DbgPrint(MIN_TRACE
,("Exception executing SetInfo\n"));
179 Status
= STATUS_INVALID_PARAMETER
;
182 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
184 return UnlockAndMaybeComplete(FCB
, Status
, Irp
, 0);
188 AfdGetSockName( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
189 PIO_STACK_LOCATION IrpSp
) {
190 NTSTATUS Status
= STATUS_SUCCESS
;
191 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
192 PAFD_FCB FCB
= FileObject
->FsContext
;
195 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
197 if( FCB
->AddressFile
.Object
== NULL
&& FCB
->Connection
.Object
== NULL
) {
198 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
201 Mdl
= IoAllocateMdl( Irp
->UserBuffer
,
202 IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
,
209 MmProbeAndLockPages( Mdl
, Irp
->RequestorMode
, IoModifyAccess
);
210 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
211 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
212 Status
= _SEH2_GetExceptionCode();
215 if( NT_SUCCESS(Status
) ) {
216 Status
= TdiQueryInformation( FCB
->Connection
.Object
217 ? FCB
->Connection
.Object
218 : FCB
->AddressFile
.Object
,
219 TDI_QUERY_ADDRESS_INFO
,
223 Status
= STATUS_INSUFFICIENT_RESOURCES
;
225 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
229 AfdGetPeerName( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
230 PIO_STACK_LOCATION IrpSp
) {
232 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
233 PAFD_FCB FCB
= FileObject
->FsContext
;
236 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
238 if (FCB
->RemoteAddress
== NULL
) {
239 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
240 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
243 if (IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
>= TaLengthOfTransportAddress(FCB
->RemoteAddress
))
245 RtlCopyMemory(Irp
->UserBuffer
, FCB
->RemoteAddress
, TaLengthOfTransportAddress(FCB
->RemoteAddress
));
246 Status
= STATUS_SUCCESS
;
250 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
251 Status
= STATUS_BUFFER_TOO_SMALL
;
254 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );