* Disable compiling usermode components for now.
[reactos.git] / lib / tdilib / enum.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TDI interface
4 * FILE: enum.c
5 * PURPOSE: TDI entity enumeration
6 */
7
8 #include "iphlpapi_private.h"
9 #include "tdilib.h"
10
11 /* A generic thing-getting function which interacts in the right way with
12 * TDI. This may seem oblique, but I'm using it to reduce code and hopefully
13 * make this thing easier to debug.
14 *
15 * The things returned can be any of:
16 * TDIEntityID
17 * TDIObjectID
18 * IFEntry
19 * IPSNMPInfo
20 * IPAddrEntry
21 * IPInterfaceInfo
22 */
23 NTSTATUS tdiGetSetOfThings( HANDLE tcpFile,
24 DWORD toiClass,
25 DWORD toiType,
26 DWORD toiId,
27 DWORD teiEntity,
28 DWORD teiInstance,
29 DWORD fixedPart,
30 DWORD entrySize,
31 PVOID *tdiEntitySet,
32 PDWORD numEntries ) {
33 TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
34 PVOID entitySet = 0;
35 NTSTATUS status = STATUS_SUCCESS;
36 DWORD allocationSizeForEntityArray = entrySize * MAX_TDI_ENTITIES,
37 arraySize = entrySize * MAX_TDI_ENTITIES;
38
39 req.ID.toi_class = toiClass;
40 req.ID.toi_type = toiType;
41 req.ID.toi_id = toiId;
42 req.ID.toi_entity.tei_entity = teiEntity;
43 req.ID.toi_entity.tei_instance = teiInstance;
44
45 /* There's a subtle problem here...
46 * If an interface is added at this exact instant, (as if by a PCMCIA
47 * card insertion), the array will still not have enough entries after
48 * have allocated it after the first DeviceIoControl call.
49 *
50 * We'll get around this by repeating until the number of interfaces
51 * stabilizes.
52 */
53 do {
54 status = DeviceIoControl( tcpFile,
55 IOCTL_TCP_QUERY_INFORMATION_EX,
56 &req,
57 sizeof(req),
58 0,
59 0,
60 &allocationSizeForEntityArray,
61 NULL );
62
63 if(!status)
64 {
65 return STATUS_UNSUCCESSFUL;
66 }
67
68 arraySize = allocationSizeForEntityArray;
69 entitySet = HeapAlloc( GetProcessHeap(), 0, arraySize );
70
71 if( !entitySet ) {
72 status = STATUS_INSUFFICIENT_RESOURCES;
73 return status;
74 }
75
76 status = DeviceIoControl( tcpFile,
77 IOCTL_TCP_QUERY_INFORMATION_EX,
78 &req,
79 sizeof(req),
80 entitySet,
81 arraySize,
82 &allocationSizeForEntityArray,
83 NULL );
84
85 /* This is why we have the loop -- we might have added an adapter */
86 if( arraySize == allocationSizeForEntityArray )
87 break;
88
89 HeapFree( GetProcessHeap(), 0, entitySet );
90 entitySet = 0;
91
92 if(!status)
93 return STATUS_UNSUCCESSFUL;
94 } while( TRUE ); /* We break if the array we received was the size we
95 * expected. Therefore, we got here because it wasn't */
96
97 *numEntries = (arraySize - fixedPart) / entrySize;
98 *tdiEntitySet = entitySet;
99
100 return STATUS_SUCCESS;
101 }
102
103 VOID tdiFreeThingSet( PVOID things ) {
104 HeapFree( GetProcessHeap(), 0, things );
105 }
106
107 NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile,
108 TDIEntityID **entitySet,
109 PDWORD numEntities ) {
110 NTSTATUS status = tdiGetSetOfThings( tcpFile,
111 INFO_CLASS_GENERIC,
112 INFO_TYPE_PROVIDER,
113 ENTITY_LIST_ID,
114 GENERIC_ENTITY,
115 0,
116 0,
117 sizeof(TDIEntityID),
118 (PVOID *)entitySet,
119 numEntities );
120
121 return status;
122 }
123