Implement support for FIONREAD in WSPIoctl. (hope I did it properly)
[reactos.git] / reactos / drivers / network / afd / afd / info.c
1 /* $Id$
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 #include "tdi_proto.h"
12 #include "tdiconn.h"
13 #include "debug.h"
14 #include "pseh/pseh.h"
15
16 NTSTATUS STDCALL
17 AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
18 PIO_STACK_LOCATION IrpSp ) {
19 NTSTATUS Status = STATUS_SUCCESS;
20 PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
21 PFILE_OBJECT FileObject = IrpSp->FileObject;
22 PAFD_FCB FCB = FileObject->FsContext;
23
24 AFD_DbgPrint(MID_TRACE,("Called %x %x\n", InfoReq,
25 InfoReq ? InfoReq->InformationClass : 0));
26
27 _SEH_TRY {
28 if( !SocketAcquireStateLock( FCB ) ) {
29 Status = LostSocket( Irp, TRUE );
30 _SEH_YIELD(return Status);
31 }
32
33 switch( InfoReq->InformationClass ) {
34 case AFD_INFO_RECEIVE_WINDOW_SIZE:
35 InfoReq->Information.Ulong = FCB->Recv.Size;
36 break;
37
38 case AFD_INFO_SEND_WINDOW_SIZE:
39 InfoReq->Information.Ulong = FCB->Send.Size;
40 AFD_DbgPrint(MID_TRACE,("Send window size %d\n", FCB->Send.Size));
41 break;
42
43 case AFD_INFO_GROUP_ID_TYPE:
44 InfoReq->Information.Ulong = 0; /* What is group id */
45 break;
46
47 case AFD_INFO_BLOCKING_MODE:
48 InfoReq->Information.Ulong = 0;
49 break;
50
51 case AFD_INFO_RECEIVE_CONTENT_SIZE:
52 /* Only touch InfoReq if we actually have a valid connection.
53 Behaviour was verified under WinXP SP2. */
54 if(FCB->Connection.Handle)
55 InfoReq->Information.Ulong = FCB->Recv.Content - FCB->Recv.BytesUsed;
56
57 break;
58
59 default:
60 AFD_DbgPrint(MID_TRACE,("Unknown info id %x\n",
61 InfoReq->InformationClass));
62 Status = STATUS_INVALID_PARAMETER;
63 break;
64 }
65 } _SEH_HANDLE {
66 AFD_DbgPrint(MID_TRACE,("Exception executing GetInfo\n"));
67 Status = STATUS_INVALID_PARAMETER;
68 } _SEH_END;
69
70 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
71
72 return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, FALSE );
73 }
74
75 NTSTATUS STDCALL
76 AfdGetSockOrPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
77 PIO_STACK_LOCATION IrpSp, BOOLEAN Local ) {
78 NTSTATUS Status = STATUS_SUCCESS;
79 PFILE_OBJECT FileObject = IrpSp->FileObject;
80 PAFD_FCB FCB = FileObject->FsContext;
81 PMDL Mdl = NULL, SysMdl = NULL;
82 PTDI_CONNECTION_INFORMATION ConnInfo = NULL;
83 PTRANSPORT_ADDRESS TransAddr = NULL;
84
85 AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
86
87 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
88
89 if( FCB->AddressFile.Object == NULL) {
90 return UnlockAndMaybeComplete( FCB, STATUS_UNSUCCESSFUL, Irp, 0,
91 NULL, FALSE );
92 }
93
94 Mdl = IoAllocateMdl
95 ( Irp->UserBuffer,
96 IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
97 FALSE,
98 FALSE,
99 NULL );
100
101 if( Mdl != NULL ) {
102 _SEH_TRY {
103 MmProbeAndLockPages( Mdl, Irp->RequestorMode, IoModifyAccess );
104 } _SEH_HANDLE {
105 AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
106 Status = _SEH_GetExceptionCode();
107 } _SEH_END;
108
109 if( NT_SUCCESS(Status) ) {
110 if( Local ) {
111 Status = TdiQueryInformation
112 ( FCB->AddressFile.Object,
113 TDI_QUERY_ADDRESS_INFO,
114 Mdl );
115 } else {
116 if( !NT_SUCCESS
117 ( Status = TdiBuildNullConnectionInfo
118 ( &ConnInfo,
119 FCB->LocalAddress->Address[0].AddressType ) ) ) {
120 SysMdl = IoAllocateMdl
121 ( ConnInfo,
122 sizeof( TDI_CONNECTION_INFORMATION ) +
123 TaLengthOfTransportAddress
124 ( ConnInfo->RemoteAddress ),
125 FALSE,
126 FALSE,
127 NULL );
128 }
129
130 if( SysMdl ) {
131 MmBuildMdlForNonPagedPool( SysMdl );
132 Status = TdiQueryInformation
133 ( FCB->AddressFile.Object,
134 TDI_QUERY_CONNECTION_INFO,
135 SysMdl );
136 } else Status = STATUS_NO_MEMORY;
137
138 if( NT_SUCCESS(Status) ) {
139 TransAddr =
140 (PTRANSPORT_ADDRESS)MmMapLockedPages
141 ( Mdl, IoModifyAccess );
142 }
143
144 if( TransAddr )
145 RtlCopyMemory( TransAddr, ConnInfo->RemoteAddress,
146 TaLengthOfTransportAddress
147 ( ConnInfo->RemoteAddress ) );
148
149 if( ConnInfo ) ExFreePool( ConnInfo );
150 if( SysMdl ) IoFreeMdl( SysMdl );
151 }
152 }
153
154 /* MmUnlockPages( Mdl ); */
155 /* IoFreeMdl( Mdl ); */
156 } else {
157 Status = STATUS_INSUFFICIENT_RESOURCES;
158 }
159
160 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
161
162 return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, FALSE );
163 }