- Remove ALL the unneeded "author date id revision" svn properties.
[reactos.git] / reactos / drivers / network / afd / afd / info.c
1 /* $Id: info.c 57233 2012-09-04 03:01:15Z cgutman $
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)
7 * UPDATE HISTORY:
8 * 20040708 Created
9 */
10 #include "afd.h"
11
12 NTSTATUS NTAPI
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;
20
21 AFD_DbgPrint(MID_TRACE,("Called %x %x\n", InfoReq,
22 InfoReq ? InfoReq->InformationClass : 0));
23
24 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
25
26 if (!InfoReq)
27 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
28
29 _SEH2_TRY {
30 switch( InfoReq->InformationClass ) {
31 case AFD_INFO_RECEIVE_WINDOW_SIZE:
32 InfoReq->Information.Ulong = FCB->Recv.Size;
33 break;
34
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));
38 break;
39
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));
44 break;
45
46 case AFD_INFO_BLOCKING_MODE:
47 InfoReq->Information.Boolean = FCB->NonBlocking;
48 break;
49
50 case AFD_INFO_INLINING_MODE:
51 InfoReq->Information.Boolean = FCB->OobInline;
52 break;
53
54 case AFD_INFO_RECEIVE_CONTENT_SIZE:
55 InfoReq->Information.Ulong = FCB->Recv.Content - FCB->Recv.BytesUsed;
56 break;
57
58 case AFD_INFO_SENDS_IN_PROGRESS:
59 InfoReq->Information.Ulong = 0;
60
61 /* Count the queued sends */
62 CurrentEntry = FCB->PendingIrpList[FUNCTION_SEND].Flink;
63 while (CurrentEntry != &FCB->PendingIrpList[FUNCTION_SEND])
64 {
65 InfoReq->Information.Ulong++;
66 CurrentEntry = CurrentEntry->Flink;
67 }
68
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
77 */
78 if (FCB->SendIrp.InFlightRequest)
79 InfoReq->Information.Ulong++;
80 break;
81
82 default:
83 AFD_DbgPrint(MIN_TRACE,("Unknown info id %x\n",
84 InfoReq->InformationClass));
85 Status = STATUS_INVALID_PARAMETER;
86 break;
87 }
88 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
89 AFD_DbgPrint(MIN_TRACE,("Exception executing GetInfo\n"));
90 Status = STATUS_INVALID_PARAMETER;
91 } _SEH2_END;
92
93 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
94
95 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
96 }
97
98 NTSTATUS NTAPI
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;
105 PCHAR NewBuffer;
106
107 if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
108
109 if (!InfoReq)
110 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
111
112 _SEH2_TRY {
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;
117 break;
118 case AFD_INFO_INLINING_MODE:
119 FCB->OobInline = InfoReq->Information.Boolean;
120 break;
121 case AFD_INFO_RECEIVE_WINDOW_SIZE:
122 NewBuffer = ExAllocatePool(PagedPool, InfoReq->Information.Ulong);
123 if (NewBuffer)
124 {
125 if (FCB->Recv.Content > InfoReq->Information.Ulong)
126 FCB->Recv.Content = InfoReq->Information.Ulong;
127
128 if (FCB->Recv.Window)
129 {
130 RtlCopyMemory(NewBuffer,
131 FCB->Recv.Window,
132 FCB->Recv.Content);
133
134 ExFreePool(FCB->Recv.Window);
135 }
136
137 FCB->Recv.Size = InfoReq->Information.Ulong;
138 FCB->Recv.Window = NewBuffer;
139
140 Status = STATUS_SUCCESS;
141 }
142 else
143 {
144 Status = STATUS_NO_MEMORY;
145 }
146 break;
147 case AFD_INFO_SEND_WINDOW_SIZE:
148 NewBuffer = ExAllocatePool(PagedPool, InfoReq->Information.Ulong);
149 if (NewBuffer)
150 {
151 if (FCB->Send.BytesUsed > InfoReq->Information.Ulong)
152 FCB->Send.BytesUsed = InfoReq->Information.Ulong;
153
154 if (FCB->Send.Window)
155 {
156 RtlCopyMemory(NewBuffer,
157 FCB->Send.Window,
158 FCB->Send.BytesUsed);
159
160 ExFreePool(FCB->Send.Window);
161 }
162
163 FCB->Send.Size = InfoReq->Information.Ulong;
164 FCB->Send.Window = NewBuffer;
165
166 Status = STATUS_SUCCESS;
167 }
168 else
169 {
170 Status = STATUS_NO_MEMORY;
171 }
172 break;
173 default:
174 AFD_DbgPrint(MIN_TRACE,("Unknown request %d\n", InfoReq->InformationClass));
175 break;
176 }
177 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
178 AFD_DbgPrint(MIN_TRACE,("Exception executing SetInfo\n"));
179 Status = STATUS_INVALID_PARAMETER;
180 } _SEH2_END;
181
182 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
183
184 return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
185 }
186
187 NTSTATUS NTAPI
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;
193 PMDL Mdl = NULL;
194
195 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
196
197 if( FCB->AddressFile.Object == NULL && FCB->Connection.Object == NULL ) {
198 return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
199 }
200
201 Mdl = IoAllocateMdl( Irp->UserBuffer,
202 IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
203 FALSE,
204 FALSE,
205 NULL );
206
207 if( Mdl != NULL ) {
208 _SEH2_TRY {
209 MmProbeAndLockPages( Mdl, Irp->RequestorMode, IoModifyAccess );
210 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
211 AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
212 Status = _SEH2_GetExceptionCode();
213 } _SEH2_END;
214
215 if( NT_SUCCESS(Status) ) {
216 Status = TdiQueryInformation( FCB->Connection.Object
217 ? FCB->Connection.Object
218 : FCB->AddressFile.Object,
219 TDI_QUERY_ADDRESS_INFO,
220 Mdl );
221 }
222 } else
223 Status = STATUS_INSUFFICIENT_RESOURCES;
224
225 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
226 }
227
228 NTSTATUS NTAPI
229 AfdGetPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
230 PIO_STACK_LOCATION IrpSp ) {
231 NTSTATUS Status;
232 PFILE_OBJECT FileObject = IrpSp->FileObject;
233 PAFD_FCB FCB = FileObject->FsContext;
234
235
236 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
237
238 if (FCB->RemoteAddress == NULL) {
239 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n"));
240 return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
241 }
242
243 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength >= TaLengthOfTransportAddress(FCB->RemoteAddress))
244 {
245 RtlCopyMemory(Irp->UserBuffer, FCB->RemoteAddress, TaLengthOfTransportAddress(FCB->RemoteAddress));
246 Status = STATUS_SUCCESS;
247 }
248 else
249 {
250 AFD_DbgPrint(MIN_TRACE,("Buffer too small\n"));
251 Status = STATUS_BUFFER_TOO_SMALL;
252 }
253
254 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
255 }