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
);
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 /* Only touch InfoReq if a socket has been set up.
56 Behaviour was verified under WinXP SP2. */
57 if(FCB
->AddressFile
.Object
|| FCB
->Connection
.Object
)
58 InfoReq
->Information
.Ulong
= FCB
->Recv
.Content
- FCB
->Recv
.BytesUsed
;
62 case AFD_INFO_SENDS_IN_PROGRESS
:
63 InfoReq
->Information
.Ulong
= 0;
65 /* Count the queued sends */
66 CurrentEntry
= FCB
->PendingIrpList
[FUNCTION_SEND
].Flink
;
67 while (CurrentEntry
!= &FCB
->PendingIrpList
[FUNCTION_SEND
])
69 InfoReq
->Information
.Ulong
++;
70 CurrentEntry
= CurrentEntry
->Flink
;
73 /* This needs to count too because when this is dispatched
74 * the user-mode IRP has already been completed and therefore
75 * will NOT be in our pending IRP list. We count this as one send
76 * outstanding although it could be multiple since we batch sends
77 * when waiting for the in flight request to return, so this number
78 * may not be accurate but it really doesn't matter that much since
79 * it's more or less a zero/non-zero comparison to determine whether
80 * we can shutdown the socket
82 if (FCB
->SendIrp
.InFlightRequest
)
83 InfoReq
->Information
.Ulong
++;
87 AFD_DbgPrint(MIN_TRACE
,("Unknown info id %x\n",
88 InfoReq
->InformationClass
));
89 Status
= STATUS_INVALID_PARAMETER
;
92 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
93 AFD_DbgPrint(MIN_TRACE
,("Exception executing GetInfo\n"));
94 Status
= STATUS_INVALID_PARAMETER
;
97 AFD_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));
99 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
103 AfdSetInfo( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
104 PIO_STACK_LOCATION IrpSp
) {
105 NTSTATUS Status
= STATUS_SUCCESS
;
106 PAFD_INFO InfoReq
= LockRequest(Irp
, IrpSp
);
107 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
108 PAFD_FCB FCB
= FileObject
->FsContext
;
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 %d\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 %d\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 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
201 if( FCB
->AddressFile
.Object
== NULL
&& FCB
->Connection
.Object
== NULL
) {
202 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
207 IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
,
214 MmProbeAndLockPages( Mdl
, Irp
->RequestorMode
, IoModifyAccess
);
215 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
216 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
217 Status
= _SEH2_GetExceptionCode();
220 if( NT_SUCCESS(Status
) ) {
221 Status
= TdiQueryInformation
222 ( FCB
->Connection
.Object
? FCB
->Connection
.Object
: FCB
->AddressFile
.Object
,
223 TDI_QUERY_ADDRESS_INFO
,
227 Status
= STATUS_INSUFFICIENT_RESOURCES
;
229 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );
233 AfdGetPeerName( PDEVICE_OBJECT DeviceObject
, PIRP Irp
,
234 PIO_STACK_LOCATION IrpSp
) {
236 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
237 PAFD_FCB FCB
= FileObject
->FsContext
;
240 if( !SocketAcquireStateLock( FCB
) ) return LostSocket( Irp
);
242 if (FCB
->RemoteAddress
== NULL
) {
243 AFD_DbgPrint(MIN_TRACE
,("Invalid parameter\n"));
244 return UnlockAndMaybeComplete( FCB
, STATUS_INVALID_PARAMETER
, Irp
, 0 );
247 if (IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
>= TaLengthOfTransportAddress(FCB
->RemoteAddress
))
249 RtlCopyMemory(Irp
->UserBuffer
, FCB
->RemoteAddress
, TaLengthOfTransportAddress(FCB
->RemoteAddress
));
250 Status
= STATUS_SUCCESS
;
254 AFD_DbgPrint(MIN_TRACE
,("Buffer too small\n"));
255 Status
= STATUS_BUFFER_TOO_SMALL
;
258 return UnlockAndMaybeComplete( FCB
, Status
, Irp
, 0 );