2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
5 * PURPOSE: TDI query and set information routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
14 TDI_STATUS
InfoCopyOut( PCHAR DataOut
, UINT SizeOut
,
15 PNDIS_BUFFER ClientBuf
, PUINT ClientBufSize
) {
16 UINT RememberedCBSize
= *ClientBufSize
;
17 *ClientBufSize
= SizeOut
;
18 if( RememberedCBSize
< SizeOut
)
19 return TDI_BUFFER_TOO_SMALL
;
21 CopyBufferToBufferChain( ClientBuf
, 0, (PUCHAR
)DataOut
, SizeOut
);
26 VOID
InsertTDIInterfaceEntity( PIP_INTERFACE Interface
) {
30 TI_DbgPrint(MAX_TRACE
,
31 ("Inserting interface %08x (%d entities already)\n",
32 Interface
, EntityCount
));
34 KeAcquireSpinLock( &EntityListLock
, &OldIrql
);
36 /* Count IP Entities */
37 for( i
= 0; i
< EntityCount
; i
++ )
38 if( EntityList
[i
].tei_entity
== IF_ENTITY
) {
40 TI_DbgPrint(MAX_TRACE
, ("Entity %d is an IF. Found %d\n",
44 EntityList
[EntityCount
].tei_entity
= IF_ENTITY
;
45 EntityList
[EntityCount
].tei_instance
= Count
;
46 EntityList
[EntityCount
].context
= Interface
;
47 EntityList
[EntityCount
].info_req
= InfoInterfaceTdiQueryEx
;
48 EntityList
[EntityCount
].info_set
= InfoInterfaceTdiSetEx
;
52 KeReleaseSpinLock( &EntityListLock
, OldIrql
);
55 VOID
RemoveTDIInterfaceEntity( PIP_INTERFACE Interface
) {
59 KeAcquireSpinLock( &EntityListLock
, &OldIrql
);
61 /* Remove entities that have this interface as context
62 * In the future, this might include AT_ENTITY types, too
64 for( i
= 0; i
< EntityCount
; i
++ ) {
65 if( EntityList
[i
].context
== Interface
) {
66 if( i
!= EntityCount
-1 )
67 memcpy( &EntityList
[i
],
68 &EntityList
[--EntityCount
],
69 sizeof(EntityList
[i
]) );
73 KeReleaseSpinLock( &EntityListLock
, OldIrql
);
76 TDI_STATUS
InfoTdiQueryListEntities(PNDIS_BUFFER Buffer
,
79 UINT Count
, Size
, BufSize
= *BufferSize
;
81 TDIEntityID
*EntityOutList
;
82 PLIST_ENTRY CurrentIFEntry
;
84 TI_DbgPrint(MAX_TRACE
,("About to copy %d TDIEntityIDs to user\n",
87 KeAcquireSpinLock(&EntityListLock
, &OldIrql
);
89 Size
= EntityCount
* sizeof(TDIEntityID
);
94 KeReleaseSpinLock( &EntityListLock
, OldIrql
);
95 /* The buffer is too small to contain requested data */
96 return TDI_BUFFER_TOO_SMALL
;
99 /* Return entity list -- Copy only the TDIEntityID parts. */
100 for( Count
= 0; Count
< EntityCount
; Count
++ ) {
101 CopyBufferToBufferChain(Buffer
,
102 Count
* sizeof(TDIEntityID
),
103 (PUCHAR
)&EntityList
[Count
],
104 sizeof(TDIEntityID
));
107 KeReleaseSpinLock(&EntityListLock
, OldIrql
);
112 TDI_STATUS
InfoTdiQueryInformationEx(
113 PTDI_REQUEST Request
,
119 * FUNCTION: Returns extended information
121 * Request = Pointer to TDI request structure for the request
123 * Buffer = Pointer to buffer with data to use
124 * BufferSize = Pointer to buffer with size of Buffer. On return
125 * this is filled with number of bytes returned
126 * Context = Pointer to context buffer
128 * Status of operation
134 NTSTATUS Status
= STATUS_SUCCESS
;
135 TDIEntityID EntityId
;
136 BOOL FoundEntity
= FALSE
;
137 InfoRequest_f InfoRequest
;
139 TI_DbgPrint(MAX_TRACE
,
140 ("InfoEx Req: %x %x %x!%04x:%d\n",
144 ID
->toi_entity
.tei_entity
,
145 ID
->toi_entity
.tei_instance
));
147 /* Check wether it is a query for a list of entities */
148 if (ID
->toi_entity
.tei_entity
== GENERIC_ENTITY
)
150 if ((ID
->toi_class
!= INFO_CLASS_GENERIC
) ||
151 (ID
->toi_type
!= INFO_TYPE_PROVIDER
) ||
152 (ID
->toi_id
!= ENTITY_LIST_ID
))
153 Status
= TDI_INVALID_PARAMETER
;
155 Status
= InfoTdiQueryListEntities(Buffer
, BufferSize
);
157 KeAcquireSpinLock( &EntityListLock
, &OldIrql
);
159 for( i
= 0; i
< EntityCount
; i
++ ) {
160 if( EntityList
[i
].tei_entity
== ID
->toi_entity
.tei_entity
&&
161 EntityList
[i
].tei_instance
== ID
->toi_entity
.tei_instance
) {
162 InfoRequest
= EntityList
[i
].info_req
;
163 context
= EntityList
[i
].context
;
169 KeReleaseSpinLock( &EntityListLock
, OldIrql
);
172 TI_DbgPrint(MAX_TRACE
,
173 ("Calling Entity %d (%04x:%d) InfoEx (%x,%x,%x)\n",
174 i
, ID
->toi_entity
.tei_entity
,
175 ID
->toi_entity
.tei_instance
,
176 ID
->toi_class
, ID
->toi_type
, ID
->toi_id
));
177 Status
= InfoRequest( ID
->toi_class
,
187 TI_DbgPrint(MAX_TRACE
,("Status: %08x\n", Status
));
192 TDI_STATUS InfoTdiSetInformationEx
193 (PTDI_REQUEST Request
,
198 * FUNCTION: Sets extended information
200 * Request = Pointer to TDI request structure for the request
201 * ID = Pointer to TDI object ID
202 * Buffer = Pointer to buffer with data to use
203 * BufferSize = Size of Buffer
205 * Status of operation
208 switch( ID
->toi_class
) {
209 case INFO_CLASS_PROTOCOL
:
210 switch( ID
->toi_type
) {
211 case INFO_TYPE_PROVIDER
:
212 switch( ID
->toi_id
) {
213 case IP_MIB_ROUTETABLE_ENTRY_ID
:
214 if( ID
->toi_entity
.tei_entity
== CL_NL_ENTITY
&&
215 ID
->toi_entity
.tei_instance
== TL_INSTANCE
&&
216 BufferSize
>= sizeof(IPROUTE_ENTRY
) ) {
217 /* Add route -- buffer is an IPRouteEntry */
218 PIPROUTE_ENTRY ire
= (PIPROUTE_ENTRY
)Buffer
;
219 RouteFriendlyAddRoute( ire
);
221 return TDI_INVALID_PARAMETER
;
222 /* In my experience, we are being over
223 protective compared to windows */
232 return TDI_INVALID_PARAMETER
;