[PATCH 5/5] iphlpapi: Add tests for ndis ioctls.
Zebediah Figura
zfigura at codeweavers.com
Wed Aug 26 10:22:59 CDT 2020
On 8/25/20 9:32 AM, Isabella Bosia wrote:
> Signed-off-by: Isabella Bosia <ibosia at codeweavers.com>
> ---
> dlls/iphlpapi/tests/Makefile.in | 6 +-
> dlls/iphlpapi/tests/ndis.c | 157 ++++++++++++++++++++++++++++++++
> 2 files changed, 161 insertions(+), 2 deletions(-)
> create mode 100644 dlls/iphlpapi/tests/ndis.c
>
> diff --git a/dlls/iphlpapi/tests/Makefile.in b/dlls/iphlpapi/tests/Makefile.in
> index d813101354..2357f033bf 100644
> --- a/dlls/iphlpapi/tests/Makefile.in
> +++ b/dlls/iphlpapi/tests/Makefile.in
> @@ -1,5 +1,7 @@
> TESTDLL = iphlpapi.dll
> -IMPORTS = iphlpapi
> +IMPORTS = iphlpapi advapi32 ole32
> +
>
> C_SRCS = \
> - iphlpapi.c
> + iphlpapi.c \
> + ndis.c
> diff --git a/dlls/iphlpapi/tests/ndis.c b/dlls/iphlpapi/tests/ndis.c
> new file mode 100644
> index 0000000000..bdefdd6594
> --- /dev/null
> +++ b/dlls/iphlpapi/tests/ndis.c
> @@ -0,0 +1,157 @@
> +/*
> + * Unit tests for ndis ioctls
> + *
> + * Copyright (c) 2020 Isabella Bosia
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
> + */
> +
> +#include <windows.h>
> +#include <winioctl.h>
> +#include <ntddndis.h>
> +#include <winsock2.h>
> +#include <ws2ipdef.h>
> +#include <iphlpapi.h>
> +#include <netioapi.h>
> +#include <shlwapi.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include "wine/test.h"
> +
> +static void test_device(const char *service_name, const MIB_IF_ROW2 *row)
> +{
> + DWORD size;
> + int ret;
> + NDIS_MEDIUM medium;
> + UCHAR addr[IF_MAX_PHYS_ADDRESS_LENGTH];
> + char target_path[48];
> + char file_name[43];
> + HANDLE netdev;
> + int oid;
> + BOOL device_needs_removing = FALSE;
> + DWORD err;
> +
> + ret = QueryDosDeviceA( service_name, target_path, sizeof(target_path) );
> + err = GetLastError();
> + ok( ret || err == ERROR_FILE_NOT_FOUND, "Couldn't query the device and can't handle this error\n" );
In general when writing tests you want to print, on failure, the actual
returned error or output value, as well as (if appropriate) the value of
GetLastError(). [For functions returning BOOL it's of course much less
interesting to print the exact return value.]
Incidentally, storing GetLastError() in a local variable is somewhat
redundant, especially when you use it directly in the next line...
> +
> + if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
> + {
> + device_needs_removing = TRUE;
> + snprintf( target_path, sizeof(target_path), "\\Device\\%s", service_name );
> + ok( DefineDosDeviceA( DDD_RAW_TARGET_PATH, service_name, target_path ) != 0, "DDD failed to create\n" );
This is very weird. Have you encountered machines where there are no
symlinks in "\\GLOBAL??"?
It may be easier just to open the device by device path directly [i.e.
with NtOpenFile].
> + }
> +
> + snprintf( file_name, sizeof(file_name), "\\\\.\\%s", service_name );
> + netdev = CreateFileA( file_name, 0, 1, NULL, 3, 0, NULL );
Please use symbolic constants.
> + if (netdev != INVALID_HANDLE_VALUE)
> + {
> + oid = OID_GEN_MEDIA_SUPPORTED;
> + ret = DeviceIoControl( netdev, IOCTL_NDIS_QUERY_GLOBAL_STATS,
> + &oid, sizeof(oid), &medium, sizeof(medium), &size, NULL );
> + ok( ret && medium == row->MediaType, "OID_GEN_MEDIA_SUPPORTED failed\n" );
Generally I think it's best to split this into two ok() calls.
> +
> + oid = OID_GEN_MEDIA_IN_USE;
> + ret = DeviceIoControl( netdev, IOCTL_NDIS_QUERY_GLOBAL_STATS,
> + &oid, sizeof(oid), &medium, sizeof(medium), &size, NULL );
> + ok( ret && medium == row->MediaType, "OID_GEN_MEDIA_IN_USE failed\n" );
> +
> + oid = OID_802_3_PERMANENT_ADDRESS;
> + ret = DeviceIoControl( netdev, IOCTL_NDIS_QUERY_GLOBAL_STATS,
> + &oid, sizeof(oid), addr, sizeof(addr), &size, NULL );
> + ok( ret, "OID_802_3_PERMANENT_ADDRESS failed\n" );
> + ok( row->PhysicalAddressLength == size && !memcmp( row->PermanentPhysicalAddress, addr, size ),
> + "Wrong permanent address\n" );
> +
> + oid = OID_802_3_CURRENT_ADDRESS;
> + ret = DeviceIoControl( netdev, IOCTL_NDIS_QUERY_GLOBAL_STATS,
> + &oid, sizeof(oid), addr, sizeof(addr), &size, NULL );
> + ok( ret, "OID_802_3_CURRENT_ADDRESS failed\n" );
> + ok( row->PhysicalAddressLength == size && !memcmp( row->PhysicalAddress, addr, size ),
> + "Wrong current address\n" );
> + }
> + else
> + skip( "Could not open device\n" );
> +
> + if (device_needs_removing)
> + ok( DefineDosDeviceA( DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
> + service_name, target_path ) != 0, "DDD failed to remove\n" );
> +}
> +
> +void test_ndis_ioctl(void)
Missing 'static'.
> +{
> + HKEY nics, sub_key;
> + LSTATUS ret;
> + char card[16];
> + BYTE data[100];
> + WCHAR description[100];
> + DWORD size, type, i = 0;
> +
> + ret = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
> + "Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards", 0, KEY_READ, &nics );
> + ok( ret == ERROR_SUCCESS, "NetworkCards key missing\n" );
> +
> + while (1)
> + {
> + MIB_IF_ROW2 row = { 0 };
> + char service_name[39] = { 0 };
> + WCHAR guidstrW[39];
> + GUID guid;
> +
> +
> + size = sizeof(card);
> + ret = RegEnumKeyExA( nics, i, card, &size, NULL, NULL, NULL, NULL );
> + if (ret != ERROR_SUCCESS)
> + break;
> + i++;
> +
> + ret = RegOpenKeyExA( nics, card, 0, KEY_READ, &sub_key );
> + ok( ret == ERROR_SUCCESS, "Could not open network card subkey\n" );
> +
> + size = sizeof(data);
> + ret = RegQueryValueExA( sub_key, "ServiceName", NULL, &type, data, &size );
> + ok( ret == ERROR_SUCCESS && type == REG_SZ, "Wrong ServiceName\n" );
> +
> + memcpy( service_name, data, size );
> + MultiByteToWideChar( CP_ACP, 0, (char *)data, -1, guidstrW, ARRAY_SIZE(guidstrW) );
You can use wide character string constants in test, so using W APIs
would probably be simpler here.
> + CLSIDFromString( guidstrW, (LPCLSID)&guid );
> + ConvertInterfaceGuidToLuid( &guid, &row.InterfaceLuid );
> +
> + ret = GetIfEntry2(&row);
> + ok( ret == NO_ERROR, "GetIfEntry2 failed\n" );
> +
> + ok( IsEqualGUID( &guid, &row.InterfaceGuid ), "Wrong ServiceName\n" );
> +
> + size = sizeof(data);
> + ret = RegQueryValueExA( sub_key, "Description", NULL, &type, data, &size );
> + MultiByteToWideChar( CP_ACP, 0, (char *)data, -1, description, ARRAY_SIZE(description) );
> + ok( ret == ERROR_SUCCESS && type == REG_SZ, "Wrong Description\n" );
> +
> + trace( "testing device <%s>\n", wine_dbgstr_w(description) );
> + test_device( service_name, &row );
> +
> + RegCloseKey( sub_key );
> + }
> +
> + if (i == 0)
> + skip( "Network card subkeys missing\n" );
> +
> + RegCloseKey( nics );
> +}
> +
> +START_TEST(ndis)
> +{
> + test_ndis_ioctl();
> +}
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20200826/9d1d9bf7/attachment.sig>
More information about the wine-devel
mailing list