[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