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