- Forgot to commit these for MSVC build...
[reactos.git] / reactos / drivers / net / tcpip / tcpip / info.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/info.c
5 * PURPOSE: TDI query and set information routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10
11 #include "precomp.h"
12 #include <debug.h>
13 #include <route.h>
14
15 TDI_STATUS InfoCopyOut( PCHAR DataOut, UINT SizeOut,
16 PNDIS_BUFFER ClientBuf, PUINT ClientBufSize ) {
17 UINT RememberedCBSize = *ClientBufSize;
18 *ClientBufSize = SizeOut;
19
20 /* The driver returns success even when it couldn't fit every available
21 * byte. */
22 if( RememberedCBSize < SizeOut )
23 return TDI_SUCCESS;
24 else {
25 CopyBufferToBufferChain( ClientBuf, 0, (PCHAR)DataOut, SizeOut );
26 return TDI_SUCCESS;
27 }
28 }
29
30 VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface ) {
31 KIRQL OldIrql;
32 UINT Count = 0, i;
33
34 TI_DbgPrint(DEBUG_INFO,
35 ("Inserting interface %08x (%d entities already)\n",
36 Interface, EntityCount));
37
38 TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
39
40 /* Count IP Entities */
41 for( i = 0; i < EntityCount; i++ )
42 if( EntityList[i].tei_entity == IF_ENTITY ) {
43 Count++;
44 TI_DbgPrint(DEBUG_INFO, ("Entity %d is an IF. Found %d\n",
45 i, Count));
46 }
47
48 EntityList[EntityCount].tei_entity = IF_ENTITY;
49 EntityList[EntityCount].tei_instance = Count;
50 EntityList[EntityCount].context = Interface;
51 EntityList[EntityCount].info_req = InfoInterfaceTdiQueryEx;
52 EntityList[EntityCount].info_set = InfoInterfaceTdiSetEx;
53
54 EntityCount++;
55
56 TcpipReleaseSpinLock( &EntityListLock, OldIrql );
57 }
58
59 VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface ) {
60 KIRQL OldIrql;
61 UINT i;
62
63 TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
64
65 /* Remove entities that have this interface as context
66 * In the future, this might include AT_ENTITY types, too
67 */
68 for( i = 0; i < EntityCount; i++ ) {
69 if( EntityList[i].context == Interface ) {
70 if( i != EntityCount-1 )
71 memcpy( &EntityList[i],
72 &EntityList[--EntityCount],
73 sizeof(EntityList[i]) );
74 }
75 }
76
77 TcpipReleaseSpinLock( &EntityListLock, OldIrql );
78 }
79
80 TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
81 PUINT BufferSize)
82 {
83 UINT Count, Size, BufSize = *BufferSize;
84 KIRQL OldIrql;
85
86 TI_DbgPrint(DEBUG_INFO,("About to copy %d TDIEntityIDs to user\n",
87 EntityCount));
88
89 TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
90
91 Size = EntityCount * sizeof(TDIEntityID);
92 *BufferSize = Size;
93
94 TI_DbgPrint(DEBUG_INFO,("BufSize: %d, NeededSize: %d\n", BufSize, Size));
95
96 if (BufSize < Size)
97 {
98 TcpipReleaseSpinLock( &EntityListLock, OldIrql );
99 /* The buffer is too small to contain requested data, but we return
100 * success anyway, as we did everything we wanted. */
101 return TDI_SUCCESS;
102 }
103
104 /* Return entity list -- Copy only the TDIEntityID parts. */
105 for( Count = 0; Count < EntityCount; Count++ ) {
106 CopyBufferToBufferChain(Buffer,
107 Count * sizeof(TDIEntityID),
108 (PCHAR)&EntityList[Count],
109 sizeof(TDIEntityID));
110 }
111
112 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
113
114 return TDI_SUCCESS;
115 }
116
117 TDI_STATUS InfoTdiQueryInformationEx(
118 PTDI_REQUEST Request,
119 TDIObjectID *ID,
120 PNDIS_BUFFER Buffer,
121 PUINT BufferSize,
122 PVOID Context)
123 /*
124 * FUNCTION: Returns extended information
125 * ARGUMENTS:
126 * Request = Pointer to TDI request structure for the request
127 * ID = TDI object ID
128 * Buffer = Pointer to buffer with data to use
129 * BufferSize = Pointer to buffer with size of Buffer. On return
130 * this is filled with number of bytes returned
131 * Context = Pointer to context buffer
132 * RETURNS:
133 * Status of operation
134 */
135 {
136 KIRQL OldIrql;
137 UINT i;
138 PVOID context = NULL;
139 NTSTATUS Status = TDI_INVALID_PARAMETER;
140 BOOL FoundEntity = FALSE;
141 InfoRequest_f InfoRequest = NULL;
142
143 TI_DbgPrint(DEBUG_INFO,
144 ("InfoEx Req: %x %x %x!%04x:%d\n",
145 ID->toi_class,
146 ID->toi_type,
147 ID->toi_id,
148 ID->toi_entity.tei_entity,
149 ID->toi_entity.tei_instance));
150
151 /* Check wether it is a query for a list of entities */
152 if (ID->toi_entity.tei_entity == GENERIC_ENTITY)
153 {
154 if ((ID->toi_class != INFO_CLASS_GENERIC) ||
155 (ID->toi_type != INFO_TYPE_PROVIDER) ||
156 (ID->toi_id != ENTITY_LIST_ID)) {
157 TI_DbgPrint(DEBUG_INFO,("Invalid parameter\n"));
158 Status = TDI_INVALID_PARAMETER;
159 } else
160 Status = InfoTdiQueryListEntities(Buffer, BufferSize);
161 } else {
162 TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
163
164 for( i = 0; i < EntityCount; i++ ) {
165 if( EntityList[i].tei_entity == ID->toi_entity.tei_entity &&
166 EntityList[i].tei_instance == ID->toi_entity.tei_instance ) {
167 InfoRequest = EntityList[i].info_req;
168 context = EntityList[i].context;
169 FoundEntity = TRUE;
170 break;
171 }
172 }
173
174 TcpipReleaseSpinLock( &EntityListLock, OldIrql );
175
176 if( FoundEntity ) {
177 TI_DbgPrint(DEBUG_INFO,
178 ("Calling Entity %d (%04x:%d) InfoEx (%x,%x,%x)\n",
179 i, ID->toi_entity.tei_entity,
180 ID->toi_entity.tei_instance,
181 ID->toi_class, ID->toi_type, ID->toi_id));
182 Status = InfoRequest( ID->toi_class,
183 ID->toi_type,
184 ID->toi_id,
185 context,
186 &ID->toi_entity,
187 Buffer,
188 BufferSize );
189 }
190 }
191
192 TI_DbgPrint(DEBUG_INFO,("Status: %08x\n", Status));
193
194 return Status;
195 }
196
197 TDI_STATUS InfoTdiSetInformationEx
198 (PTDI_REQUEST Request,
199 TDIObjectID *ID,
200 PVOID Buffer,
201 UINT BufferSize)
202 /*
203 * FUNCTION: Sets extended information
204 * ARGUMENTS:
205 * Request = Pointer to TDI request structure for the request
206 * ID = Pointer to TDI object ID
207 * Buffer = Pointer to buffer with data to use
208 * BufferSize = Size of Buffer
209 * RETURNS:
210 * Status of operation
211 */
212 {
213 switch( ID->toi_class ) {
214 case INFO_CLASS_PROTOCOL:
215 switch( ID->toi_type ) {
216 case INFO_TYPE_PROVIDER:
217 switch( ID->toi_id ) {
218 case IP_MIB_ROUTETABLE_ENTRY_ID:
219 return InfoNetworkLayerTdiSetEx
220 ( ID->toi_class,
221 ID->toi_type,
222 ID->toi_id,
223 NULL,
224 &ID->toi_entity,
225 Buffer,
226 BufferSize );
227 }
228 }
229 break;
230 }
231
232 return TDI_INVALID_PARAMETER;
233 }