::SetupDiGetDeviceRegistryProperty() fails with SPDRP_BUSTYPEGUID on Docker for Windows

0

I can't not get the Bus Type GUID of a Hyper-V Virtual Ethernet Adapter on a Docker Windows container. The host is Windows Server 2016 Version 10.0.14393.

Steps to reproduce

  1. Compile SetupDiGetDeviceRegistryPropertyExperimental.cpp, and generate SetupDiGetDeviceRegistryPropertyExperimental.exe
  2. Copy SetupDiGetDeviceRegistryPropertyExperimental.exe to c:\data\
  3. Create a Dockerfile below.
  4. Execute the do.bat below.

SetupDiGetDeviceRegistryPropertyExperimental.cpp

// SetupDiGetDeviceRegistryPropertyExperimental.cpp : Defines the entry point
// for the console application.
//

#include "stdafx.h"

#include <cstdio>
#include <string>

#include <SetupAPI.h>
#include <Windows.h>
#include <devguid.h>

std::wstring ConvertLastErrorToString(DWORD last_error) {
    LPVOID lpMessageBuffer = nullptr;
    ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                    NULL, last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                    (LPTSTR)&lpMessageBuffer, 0, NULL);

    std::wstring error_message = (LPTSTR)lpMessageBuffer;

    ::LocalFree(lpMessageBuffer);

    return error_message;
}

int main() {
    std::wprintf(L"SetupDiGetDeviceRegistryPropertyExperimental\n");

    struct Resource {
        ~Resource() {
            if (devinfo) {
                ::SetupDiDestroyDeviceInfoList(devinfo);
                devinfo = NULL;
            }
        }
        HDEVINFO devinfo = NULL;
    } resource;

    resource.devinfo = ::SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, 0);

    if (!resource.devinfo) {
        DWORD last_error = ::GetLastError();
        std::wprintf(
            L"Failed to call ::SetupDiGetClassDevs(). last_error=0x%08x "
            L"error_message=%s\n",
            last_error, ConvertLastErrorToString(last_error).c_str());
        return -1;
    }

    for (DWORD member_index = 0;; ++member_index) {
        SP_DEVINFO_DATA devinfo_data = {0};
        devinfo_data.cbSize = sizeof(devinfo_data);
        if (!::SetupDiEnumDeviceInfo(resource.devinfo, member_index,
                                     &devinfo_data)) {
            DWORD last_error = ::GetLastError();
            if (last_error == ERROR_NO_MORE_ITEMS) {
                std::wprintf(L"ERROR_NO_MORE_ITEMS\n");
                break;
            }
            std::wprintf(
                L"Failed to call ::SetupDiGetClassDevs(). last_error=0x%08x "
                L"error_message=%s\n",
                last_error, ConvertLastErrorToString(last_error).c_str());
            return -1;
        }

        std::wprintf(L"----------------------------------------\n");
        std::wprintf(L"member_index=%d\n", member_index);

        GUID guid = GUID_NULL;
        if (!::SetupDiGetDeviceRegistryProperty(
                resource.devinfo, &devinfo_data, SPDRP_BUSTYPEGUID, NULL,
                (PBYTE)&guid, sizeof(guid), NULL)) {
            DWORD last_error = ::GetLastError();
            std::wprintf(
                L"Failed to call ::SetupDiGetDeviceRegistryProperty() with "
                L"SPDRP_BUSTYPEGUID. last_error=0x%08x error_message=%s\n",
                last_error, ConvertLastErrorToString(last_error).c_str());
        }

        RPC_WSTR uuid = nullptr;
        ::UuidToString(&guid, &uuid);
        std::wstring guid_string = (wchar_t*)uuid;
        ::RpcStringFree(&uuid);
        uuid = nullptr;

        wchar_t device_desc[1024] = {0};
        if (!::SetupDiGetDeviceRegistryProperty(
                resource.devinfo, &devinfo_data, SPDRP_DEVICEDESC, NULL,
                (PBYTE)device_desc, sizeof(device_desc) - 1, NULL)) {
            DWORD last_error = ::GetLastError();
            std::wprintf(
                L"Failed to call ::SetupDiGetDeviceRegistryProperty() with "
                L"SPDRP_DEVICEDESC. last_error=0x%08x error_message=%s\n",
                last_error, ConvertLastErrorToString(last_error).c_str());
        }

        std::wprintf(L"guid=%s\n", guid_string.c_str());
        std::wprintf(L"device_desc=%s\n", device_desc);
        std::wprintf(L"\n");
    }

    return 0;
}

Dockerfile

FROM microsoft/windowsservercore
CMD [ "cmd" ]

do.bat

docker build -t example .
docker stop example
docker rm example
docker run --detach --name example --mount type=bind,source=C:/data,target=C:/data example ping -t localhost
docker exec example C:\data\SetupDiGetDeviceRegistryPropertyExperimental.exe

Expected result

The bus type guid of a Hyper-V Virtual Ethernet Adapter can be retrieved.

Actual result

An error occurred. The error code returned by ::GetLastError() was 0x0000000d. The error message translated by ::FormatMessage() was "The data is invalid.".

The full output was below.

SetupDiGetDeviceRegistryPropertyExperimental
----------------------------------------
member_index=0
Failed to call ::SetupDiGetDeviceRegistryProperty() with SPDRP_BUSTYPEGUID. last_error=0x0000000d error_message=The data is invalid.

guid=00000000-0000-0000-0000-000000000000
device_desc=Hyper-V Virtual Switch Extension Adapter

----------------------------------------
member_index=1
guid=06d10322-7de0-4cef-8e25-197d0e7442e2
device_desc=Microsoft ISATAP Adapter

----------------------------------------
member_index=2
guid=06d10322-7de0-4cef-8e25-197d0e7442e2
device_desc=Microsoft ISATAP Adapter

----------------------------------------
member_index=3
Failed to call ::SetupDiGetDeviceRegistryProperty() with SPDRP_BUSTYPEGUID. last_error=0x0000000d error_message=The data is invalid.

guid=00000000-0000-0000-0000-000000000000
device_desc=Microsoft Kernel Debug Network Adapter

----------------------------------------
member_index=4
guid=c8ebdfb0-b510-11d0-80e5-00a0c92542e3
device_desc=Broadcom NetXtreme Gigabit Ethernet

----------------------------------------
member_index=5
guid=c8ebdfb0-b510-11d0-80e5-00a0c92542e3
device_desc=Broadcom NetXtreme Gigabit Ethernet

----------------------------------------
member_index=6
Failed to call ::SetupDiGetDeviceRegistryProperty() with SPDRP_BUSTYPEGUID. last_error=0x0000000d error_message=The data is invalid.

guid=00000000-0000-0000-0000-000000000000
device_desc=Hyper-V Virtual Ethernet Adapter

----------------------------------------
member_index=7
Failed to call ::SetupDiGetDeviceRegistryProperty() with SPDRP_BUSTYPEGUID. last_error=0x0000000d error_message=The data is invalid.

guid=00000000-0000-0000-0000-000000000000
device_desc=Hyper-V Virtual Ethernet Adapter

----------------------------------------
member_index=8
Failed to call ::SetupDiGetDeviceRegistryProperty() with SPDRP_BUSTYPEGUID. last_error=0x0000000d error_message=The data is invalid.

guid=00000000-0000-0000-0000-000000000000
device_desc=Hyper-V Virtual Ethernet Adapter

ERROR_NO_MORE_ITEMS

When I executed SetupDiGetDeviceRegistryPropertyExperimental.exe on a Windows container on Windows 10 Pro Version 10.0.16299.15, the program crashed with ::SetupDiGetDeviceRegistryProperty(). But it is another story.

How can I get the Bus Subtype GUID of a Hyper-V Virtual Ethernet Adapter on a Windows container on Windows Server 2016?

windows
docker
docker-windows
asked on Stack Overflow Nov 6, 2017 by nodchip

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0