2 * Network Store Interface tests
4 * Copyright 2021 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/test.h"
31 static int bounded( ULONG64 val
, ULONG64 lo
, ULONG64 hi
)
33 return lo
<= val
&& val
<= hi
;
36 static void test_nsi_api( void )
38 DWORD rw_sizes
[] = { FIELD_OFFSET(struct nsi_ndis_ifinfo_rw
, name2
), FIELD_OFFSET(struct nsi_ndis_ifinfo_rw
, unk
),
39 sizeof(struct nsi_ndis_ifinfo_rw
) };
40 struct nsi_ndis_ifinfo_rw
*rw_tbl
, *rw
, get_rw
, *enum_rw_tbl
, *enum_rw
;
41 struct nsi_ndis_ifinfo_dynamic
*dyn_tbl
, *dyn
, get_dyn
, *enum_dyn_tbl
, *enum_dyn
;
42 struct nsi_ndis_ifinfo_static
*stat_tbl
, *stat
, get_stat
, *enum_stat_tbl
, *enum_stat
;
43 struct nsi_get_all_parameters_ex get_all_params
;
44 struct nsi_enumerate_all_ex enum_params
;
45 DWORD err
, count
, i
, rw_size
, enum_count
;
46 NET_LUID
*luid_tbl
, *enum_luid_tbl
;
48 /* Use the NDIS ifinfo table to test various api */
49 for (i
= 0; i
< ARRAY_SIZE(rw_sizes
); i
++)
51 err
= NsiAllocateAndGetTable( 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
, (void **)&luid_tbl
, sizeof(*luid_tbl
),
52 (void **)&rw_tbl
, rw_sizes
[i
], (void **)&dyn_tbl
, sizeof(*dyn_tbl
),
53 (void **)&stat_tbl
, sizeof(*stat_tbl
), &count
, 0 );
57 ok( !err
, "got %d\n", err
);
59 rw_size
= rw_sizes
[i
];
61 for (i
= 0; i
< count
; i
++)
63 winetest_push_context( "%d", i
);
64 rw
= (struct nsi_ndis_ifinfo_rw
*)((BYTE
*)rw_tbl
+ i
* rw_size
);
68 err
= NsiGetAllParameters( 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
, luid_tbl
+ i
, sizeof(*luid_tbl
),
69 &get_rw
, rw_size
, &get_dyn
, sizeof(get_dyn
), &get_stat
, sizeof(get_stat
) );
70 ok( !err
, "got %d\n", err
);
71 /* test a selection of members */
72 ok( IsEqualGUID( &get_rw
.network_guid
, &rw
->network_guid
), "mismatch\n" );
73 ok( get_rw
.alias
.Length
== rw
->alias
.Length
, "mismatch\n" );
74 ok( !memcmp( get_rw
.alias
.String
, rw
->alias
.String
, rw
->alias
.Length
), "mismatch\n" );
75 ok( get_rw
.phys_addr
.Length
== rw
->phys_addr
.Length
, "mismatch\n" );
76 ok( !memcmp( get_rw
.phys_addr
.Address
, rw
->phys_addr
.Address
, IF_MAX_PHYS_ADDRESS_LENGTH
), "mismatch\n" );
77 ok( get_dyn
.oper_status
== dyn
->oper_status
, "mismatch\n" );
78 ok( get_stat
.if_index
== stat
->if_index
, "mismatch\n" );
79 ok( IsEqualGUID( &get_stat
.if_guid
, &stat
->if_guid
), "mismatch\n" );
81 memset( &get_rw
, 0xcc, sizeof(get_rw
) );
82 memset( &get_dyn
, 0xcc, sizeof(get_dyn
) );
83 memset( &get_stat
, 0xcc, sizeof(get_stat
) );
85 memset( &get_all_params
, 0, sizeof(get_all_params
) );
86 get_all_params
.first_arg
= 1;
87 get_all_params
.module
= &NPI_MS_NDIS_MODULEID
;
88 get_all_params
.table
= NSI_NDIS_IFINFO_TABLE
;
89 get_all_params
.key
= luid_tbl
+ i
;
90 get_all_params
.key_size
= sizeof(*luid_tbl
);
91 get_all_params
.rw_data
= &get_rw
;
92 get_all_params
.rw_size
= rw_size
;
93 get_all_params
.dynamic_data
= &get_dyn
;
94 get_all_params
.dynamic_size
= sizeof(get_dyn
);
95 get_all_params
.static_data
= &get_stat
;
96 get_all_params
.static_size
= sizeof(get_stat
);
98 err
= NsiGetAllParametersEx( &get_all_params
);
99 ok( !err
, "got %d\n", err
);
100 /* test a selection of members */
101 ok( IsEqualGUID( &get_rw
.network_guid
, &rw
->network_guid
), "mismatch\n" );
102 ok( get_rw
.alias
.Length
== rw
->alias
.Length
, "mismatch\n" );
103 ok( !memcmp( get_rw
.alias
.String
, rw
->alias
.String
, rw
->alias
.Length
), "mismatch\n" );
104 ok( get_rw
.phys_addr
.Length
== rw
->phys_addr
.Length
, "mismatch\n" );
105 ok( !memcmp( get_rw
.phys_addr
.Address
, rw
->phys_addr
.Address
, IF_MAX_PHYS_ADDRESS_LENGTH
), "mismatch\n" );
106 ok( get_dyn
.oper_status
== dyn
->oper_status
, "mismatch\n" );
107 ok( get_stat
.if_index
== stat
->if_index
, "mismatch\n" );
108 ok( IsEqualGUID( &get_stat
.if_guid
, &stat
->if_guid
), "mismatch\n" );
110 memset( &get_rw
, 0xcc, sizeof(get_rw
) );
111 memset( &get_dyn
, 0xcc, sizeof(get_dyn
) );
112 memset( &get_stat
, 0xcc, sizeof(get_stat
) );
114 err
= NsiGetParameter( 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
, luid_tbl
+ i
, sizeof(*luid_tbl
),
115 NSI_PARAM_TYPE_RW
, &get_rw
.alias
, sizeof(get_rw
.alias
),
116 FIELD_OFFSET(struct nsi_ndis_ifinfo_rw
, alias
) );
117 ok( !err
, "got %d\n", err
);
118 ok( get_rw
.alias
.Length
== rw
->alias
.Length
, "mismatch\n" );
119 ok( !memcmp( get_rw
.alias
.String
, rw
->alias
.String
, rw
->alias
.Length
), "mismatch\n" );
121 err
= NsiGetParameter( 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
, luid_tbl
+ i
, sizeof(*luid_tbl
),
122 NSI_PARAM_TYPE_STATIC
, &get_stat
.if_index
, sizeof(get_stat
.if_index
),
123 FIELD_OFFSET(struct nsi_ndis_ifinfo_static
, if_index
) );
124 ok( !err
, "got %d\n", err
);
125 ok( get_stat
.if_index
== stat
->if_index
, "mismatch\n" );
127 err
= NsiGetParameter( 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
, luid_tbl
+ i
, sizeof(*luid_tbl
),
128 NSI_PARAM_TYPE_STATIC
, &get_stat
.if_guid
, sizeof(get_stat
.if_guid
),
129 FIELD_OFFSET(struct nsi_ndis_ifinfo_static
, if_guid
) );
130 ok( !err
, "got %d\n", err
);
131 ok( IsEqualGUID( &get_stat
.if_guid
, &stat
->if_guid
), "mismatch\n" );
132 winetest_pop_context();
136 err
= NsiEnumerateObjectsAllParameters( 1, 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
,
138 NULL
, 0, NULL
, 0, &enum_count
);
139 ok( !err
, "got %d\n", err
);
140 ok( enum_count
== count
, "mismatch\n" );
142 enum_luid_tbl
= malloc( count
* sizeof(*enum_luid_tbl
) );
143 enum_rw_tbl
= malloc( count
* rw_size
);
144 enum_dyn_tbl
= malloc( count
* sizeof(*enum_dyn_tbl
) );
145 enum_stat_tbl
= malloc( count
* sizeof(*enum_stat_tbl
) );
147 err
= NsiEnumerateObjectsAllParameters( 1, 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
,
148 enum_luid_tbl
, sizeof(*enum_luid_tbl
), enum_rw_tbl
, rw_size
,
149 enum_dyn_tbl
, sizeof(*enum_dyn_tbl
), enum_stat_tbl
, sizeof(*enum_stat_tbl
),
151 ok( !err
, "got %d\n", err
);
152 ok( enum_count
== count
, "mismatch\n" );
154 for (i
= 0; i
< count
; i
++)
156 winetest_push_context( "%d", i
);
157 rw
= (struct nsi_ndis_ifinfo_rw
*)((BYTE
*)rw_tbl
+ i
* rw_size
);
158 enum_rw
= (struct nsi_ndis_ifinfo_rw
*)((BYTE
*)enum_rw_tbl
+ i
* rw_size
);
160 enum_dyn
= enum_dyn_tbl
+ i
;
162 enum_stat
= enum_stat_tbl
+ i
;
164 /* test a selection of members */
165 ok( enum_luid_tbl
[i
].Value
== luid_tbl
[i
].Value
, "mismatch\n" );
166 ok( IsEqualGUID( &enum_rw
->network_guid
, &rw
->network_guid
), "mismatch\n" );
167 ok( enum_rw
->alias
.Length
== rw
->alias
.Length
, "mismatch\n" );
168 ok( !memcmp( enum_rw
->alias
.String
, rw
->alias
.String
, rw
->alias
.Length
), "mismatch\n" );
169 ok( enum_rw
->phys_addr
.Length
== rw
->phys_addr
.Length
, "mismatch\n" );
170 ok( !memcmp( enum_rw
->phys_addr
.Address
, rw
->phys_addr
.Address
, IF_MAX_PHYS_ADDRESS_LENGTH
), "mismatch\n" );
171 ok( enum_dyn
->oper_status
== dyn
->oper_status
, "mismatch\n" );
172 ok( enum_stat
->if_index
== stat
->if_index
, "mismatch\n" );
173 ok( IsEqualGUID( &enum_stat
->if_guid
, &stat
->if_guid
), "mismatch\n" );
174 winetest_pop_context();
180 memset( enum_luid_tbl
, 0xcc, count
* sizeof(*enum_luid_tbl
) );
182 err
= NsiEnumerateObjectsAllParameters( 1, 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
,
183 enum_luid_tbl
, sizeof(*enum_luid_tbl
), enum_rw_tbl
, rw_size
,
184 enum_dyn_tbl
, sizeof(*enum_dyn_tbl
), enum_stat_tbl
, sizeof(*enum_stat_tbl
),
186 ok( err
== ERROR_MORE_DATA
, "got %d\n", err
);
187 ok( enum_count
== count
- 1, "mismatch\n" );
189 for (i
= 0; i
< enum_count
; i
++) /* for simplicity just check the luids */
190 ok( enum_luid_tbl
[i
].Value
== luid_tbl
[i
].Value
, "%d: mismatch\n", i
);
193 memset( &enum_params
, 0, sizeof(enum_params
) );
194 enum_params
.first_arg
= 1;
195 enum_params
.second_arg
= 1;
196 enum_params
.module
= &NPI_MS_NDIS_MODULEID
;
197 enum_params
.table
= NSI_NDIS_IFINFO_TABLE
;
198 enum_params
.key_data
= enum_luid_tbl
;
199 enum_params
.key_size
= sizeof(*enum_luid_tbl
);
200 enum_params
.rw_data
= enum_rw_tbl
;
201 enum_params
.rw_size
= rw_size
;
202 enum_params
.dynamic_data
= enum_dyn_tbl
;
203 enum_params
.dynamic_size
= sizeof(*enum_dyn_tbl
);
204 enum_params
.static_data
= enum_stat_tbl
;
205 enum_params
.static_size
= sizeof(*enum_stat_tbl
);
206 enum_params
.count
= count
;
208 err
= NsiEnumerateObjectsAllParametersEx( &enum_params
);
209 ok( !err
, "got %d\n", err
);
210 ok( enum_params
.count
== count
, "mismatch\n" );
212 free( enum_luid_tbl
);
214 free( enum_dyn_tbl
);
215 free( enum_stat_tbl
);
216 NsiFreeTable( luid_tbl
, rw_tbl
, dyn_tbl
, stat_tbl
);
219 static void test_ndis_ifinfo( void )
221 DWORD rw_sizes
[] = { FIELD_OFFSET(struct nsi_ndis_ifinfo_rw
, name2
), FIELD_OFFSET(struct nsi_ndis_ifinfo_rw
, unk
),
222 sizeof(struct nsi_ndis_ifinfo_rw
) };
223 struct nsi_ndis_ifinfo_rw
*rw_tbl
;
224 struct nsi_ndis_ifinfo_dynamic
*dyn_tbl
, *dyn_tbl_2
;
225 struct nsi_ndis_ifinfo_static
*stat_tbl
;
226 DWORD err
, count
, i
, rw_size
;
227 NET_LUID
*luid_tbl
, *luid_tbl_2
;
228 MIB_IF_TABLE2
*table
;
230 /* Contents of GetIfTable2() keyed by luids */
232 for (i
= 0; i
< ARRAY_SIZE(rw_sizes
); i
++)
234 err
= NsiAllocateAndGetTable( 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
, (void **)&luid_tbl
, sizeof(*luid_tbl
),
235 (void **)&rw_tbl
, rw_sizes
[i
], (void **)&dyn_tbl
, sizeof(*dyn_tbl
),
236 (void **)&stat_tbl
, sizeof(*stat_tbl
), &count
, 0 );
240 ok( !err
, "got %d\n", err
);
242 rw_size
= rw_sizes
[i
];
244 err
= GetIfTable2( &table
);
245 ok( !err
, "got %d\n", err
);
246 ok( table
->NumEntries
== count
, "table entries %d count %d\n", table
->NumEntries
, count
);
248 /* Grab the dyn table again to provide an upper bound for the stats returned from GetIfTable2().
249 (The luids must be retrieved again otherwise NsiAllocateAndGetTable() fails). */
250 err
= NsiAllocateAndGetTable( 1, &NPI_MS_NDIS_MODULEID
, NSI_NDIS_IFINFO_TABLE
, (void **)&luid_tbl_2
, sizeof(*luid_tbl_2
),
251 NULL
, 0, (void **)&dyn_tbl_2
, sizeof(*dyn_tbl_2
),
252 NULL
, 0, &count
, 0 );
253 ok( !err
, "got %d\n", err
);
254 ok( table
->NumEntries
== count
, "table entries %d count %d\n", table
->NumEntries
, count
);
256 for (i
= 0; i
< count
; i
++)
258 MIB_IF_ROW2
*row
= table
->Table
+ i
;
259 NET_LUID
*luid
= luid_tbl
+ i
;
260 struct nsi_ndis_ifinfo_rw
*rw
= (struct nsi_ndis_ifinfo_rw
*)((BYTE
*)rw_tbl
+ i
* rw_size
);
261 struct nsi_ndis_ifinfo_dynamic
*dyn
= dyn_tbl
+ i
, *dyn_2
= dyn_tbl_2
+ i
;
262 struct nsi_ndis_ifinfo_static
*stat
= stat_tbl
+ i
;
264 winetest_push_context( "%d", i
);
265 ok( row
->InterfaceLuid
.Value
== luid
->Value
, "mismatch\n" );
266 ok( row
->InterfaceIndex
== stat
->if_index
, "mismatch\n" );
267 ok( IsEqualGUID( &row
->InterfaceGuid
, &stat
->if_guid
), "mismatch\n" );
268 ok( !memcmp( row
->Alias
, rw
->alias
.String
, rw
->alias
.Length
), "mismatch\n" );
269 ok( lstrlenW( row
->Alias
) * 2 == rw
->alias
.Length
, "mismatch\n" );
270 ok( !memcmp( row
->Description
, stat
->descr
.String
, sizeof(row
->Description
) ), "mismatch\n" );
271 ok( lstrlenW( row
->Description
) * 2 == stat
->descr
.Length
, "mismatch\n" );
272 ok( row
->PhysicalAddressLength
== rw
->phys_addr
.Length
, "mismatch\n" );
273 ok( !memcmp( row
->PhysicalAddress
, rw
->phys_addr
.Address
, IF_MAX_PHYS_ADDRESS_LENGTH
), "mismatch\n" );
274 ok( row
->PhysicalAddressLength
== stat
->perm_phys_addr
.Length
, "mismatch\n" );
275 ok( !memcmp( row
->PermanentPhysicalAddress
, stat
->perm_phys_addr
.Address
, IF_MAX_PHYS_ADDRESS_LENGTH
),
277 ok( row
->Mtu
== dyn
->mtu
, "mismatch\n" );
278 ok( row
->Type
== stat
->type
, "mismatch\n" );
280 ok( row
->MediaType
== stat
->media_type
, "mismatch\n" );
281 ok( row
->PhysicalMediumType
== stat
->phys_medium_type
, "mismatch\n" );
282 ok( row
->AccessType
== stat
->access_type
, "mismatch\n" );
284 ok( row
->InterfaceAndOperStatusFlags
.HardwareInterface
== stat
->flags
.hw
, "mismatch\n" );
285 ok( row
->InterfaceAndOperStatusFlags
.FilterInterface
== stat
->flags
.filter
, "mismatch\n" );
286 ok( row
->InterfaceAndOperStatusFlags
.ConnectorPresent
== stat
->conn_present
, "mismatch\n" );
287 /* NotAuthenticated */
288 ok( row
->InterfaceAndOperStatusFlags
.NotMediaConnected
== dyn
->flags
.not_media_conn
, "mismatch\n" );
291 /* EndPointInterface */
292 ok( row
->OperStatus
== dyn
->oper_status
, "mismatch\n" );
293 ok( row
->AdminStatus
== rw
->admin_status
, "mismatch\n" );
294 ok( row
->MediaConnectState
== dyn
->media_conn_state
, "mismatch\n" );
295 ok( IsEqualGUID( &row
->NetworkGuid
, &rw
->network_guid
), "mismatch\n" );
296 ok( row
->ConnectionType
== stat
->conn_type
, "mismatch\n" );
297 if (dyn
->xmit_speed
== ~0ULL) dyn
->xmit_speed
= 0;
298 ok( row
->TransmitLinkSpeed
== dyn
->xmit_speed
, "mismatch\n" );
299 if (dyn
->rcv_speed
== ~0ULL) dyn
->rcv_speed
= 0;
300 ok( row
->ReceiveLinkSpeed
== dyn
->rcv_speed
, "mismatch\n" );
301 ok( bounded( row
->InOctets
, dyn
->in_octets
, dyn_2
->in_octets
), "mismatch\n" );
302 ok( bounded( row
->InUcastPkts
, dyn
->in_ucast_pkts
, dyn_2
->in_ucast_pkts
), "mismatch\n" );
303 ok( bounded( row
->InNUcastPkts
, dyn
->in_mcast_pkts
+ dyn
->in_bcast_pkts
,
304 dyn_2
->in_mcast_pkts
+ dyn_2
->in_bcast_pkts
), "mismatch\n" );
305 ok( bounded( row
->InDiscards
, dyn
->in_discards
, dyn_2
->in_discards
), "mismatch\n" );
306 ok( bounded( row
->InErrors
, dyn
->in_errors
, dyn_2
->in_errors
), "mismatch\n" );
307 /* InUnknownProtos */
308 ok( bounded( row
->InUcastOctets
, dyn
->in_ucast_octs
, dyn_2
->in_ucast_octs
), "mismatch\n" );
309 ok( bounded( row
->InMulticastOctets
, dyn
->in_mcast_octs
, dyn_2
->in_mcast_octs
), "mismatch\n" );
310 ok( bounded( row
->InBroadcastOctets
, dyn
->in_bcast_octs
, dyn_2
->in_bcast_octs
), "mismatch\n" );
311 ok( bounded( row
->OutOctets
, dyn
->out_octets
, dyn_2
->out_octets
), "mismatch\n" );
312 ok( bounded( row
->OutUcastPkts
, dyn
->out_ucast_pkts
, dyn_2
->out_ucast_pkts
), "mismatch\n" );
313 ok( bounded( row
->OutNUcastPkts
, dyn
->out_mcast_pkts
+ dyn
->out_bcast_pkts
,
314 dyn_2
->out_mcast_pkts
+ dyn_2
->out_bcast_pkts
), "mismatch\n" );
315 ok( bounded( row
->OutDiscards
, dyn
->out_discards
, dyn_2
->out_discards
), "mismatch\n" );
316 ok( bounded( row
->OutErrors
, dyn
->out_errors
, dyn_2
->out_errors
), "mismatch\n" );
317 ok( bounded( row
->OutUcastOctets
, dyn
->out_ucast_octs
, dyn_2
->out_ucast_octs
), "mismatch\n" );
318 ok( bounded( row
->OutMulticastOctets
, dyn
->out_mcast_octs
, dyn_2
->out_mcast_octs
), "mismatch\n" );
319 ok( bounded( row
->OutBroadcastOctets
, dyn
->out_bcast_octs
, dyn_2
->out_bcast_octs
), "mismatch\n" );
321 winetest_pop_context();
324 FreeMibTable( table
);
325 NsiFreeTable( luid_tbl_2
, NULL
, dyn_tbl_2
, NULL
);
326 NsiFreeTable( luid_tbl
, rw_tbl
, dyn_tbl
, stat_tbl
);