0

Im trying to build this project: https://github.com/hedgar2017/loki-example

I made a new empty C++ project in VS and added all .h files under "Header Files" via "Add existing Item" and all .cpp files under "Source Files" using the same method.

When I try to build I get these errors:

1>device.obj : error LNK2019: unresolved external symbol __imp__CM_Get_Device_Interface_ListW@20 referenced in function "public: virtual void __thiscall Device::initialize(void)" (?initialize@Device@@UAEXXZ)
1>device.obj : error LNK2019: unresolved external symbol __imp__CM_Get_Device_Interface_List_SizeW@16 referenced in function "public: virtual void __thiscall Device::initialize(void)" (?initialize@Device@@UAEXXZ)
1>device.obj : error LNK2019: unresolved external symbol _HidD_GetHidGuid@4 referenced in function "public: virtual void __thiscall Device::initialize(void)" (?initialize@Device@@UAEXXZ)
1>device.obj : error LNK2019: unresolved external symbol _HidD_SetOutputReport@12 referenced in function "protected: void __thiscall Device::setOutputReport(void *,unsigned long)" (?setOutputReport@Device@@IAEXPAXK@Z)

In "External Dependencies" cfgmgr32.h exists and was added automatically after adding the .h and .cpp files as it seems.

In order to resolve the first errors I tried this among other things:

I added the file name cfgmgr32.lib to Project > Properties > Linker > Input > Additional Dependencies

Its folder name C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64 I added to Project > Properties > Linker > General > Additional Library Directories

Still the same errors. There are no errors regarding other functions in the file cfgmgr32.h.

This is what exists in cfgmgr32.lib for CM_Get_Device_Interface_List:

#ifdef UNICODE
#define CM_Get_Device_Interface_List CM_Get_Device_Interface_ListW
#else
#define CM_Get_Device_Interface_List CM_Get_Device_Interface_ListA
#endif // UNICODE

and

CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_ListA(
    _In_  LPGUID        InterfaceClassGuid,
    _In_opt_ DEVINSTID_A pDeviceID,
    _Out_writes_(BufferLen) PZZSTR Buffer,
    _In_  ULONG         BufferLen,
    _In_  ULONG         ulFlags
    );

CMAPI CONFIGRET WINAPI CM_Get_Device_Interface_ListW(
    _In_  LPGUID        InterfaceClassGuid,
    _In_opt_ DEVINSTID_W pDeviceID,
    _Out_writes_(BufferLen) PZZWSTR Buffer,
    _In_  ULONG         BufferLen,
    _In_  ULONG         ulFlags
    );

Code of device.cpp where cfgmgr32.h is included:

#include "device.h"

#include <cfgmgr32.h>
#include <hidsdi.h>
#include <stdexcept>

Device::Device(PCWSTR deviceInterface)
    : mp_deviceInterface{ deviceInterface }
{}

void Device::initialize()
{
    if (isInitialized()) throw std::runtime_error{ "ERROR_DOUBLE_INITIALIZATION" };

    GUID guid;
    HidD_GetHidGuid(&guid);

    ULONG deviceInterfaceListLength = 0;
    CONFIGRET configret = CM_Get_Device_Interface_List_Size(
        &deviceInterfaceListLength,
        &guid,
        nullptr,
        CM_GET_DEVICE_INTERFACE_LIST_PRESENT
    );
    if (CR_SUCCESS != configret) {
        throw std::runtime_error{ "ERROR_GETTING_DEVICE_INTERFACE_LIST_SIZE" };
    }

    if (deviceInterfaceListLength <= 1) {
        throw std::runtime_error{ "ERROR_EMPTY_DEVICE_INTERFACE_LIST" };
    }

    PWSTR deviceInterfaceList = (PWSTR)malloc(deviceInterfaceListLength * sizeof(WCHAR));
    if (nullptr == deviceInterfaceList) {
        throw std::runtime_error{ "ERROR_ALLOCATING_DEVICE_INTERFACE_LIST" };
    }
    ZeroMemory(deviceInterfaceList, deviceInterfaceListLength * sizeof(WCHAR));

    configret = CM_Get_Device_Interface_List(
        &guid,
        nullptr,
        deviceInterfaceList,
        deviceInterfaceListLength,
        CM_GET_DEVICE_INTERFACE_LIST_PRESENT
    );
    if (CR_SUCCESS != configret) {
        free(deviceInterfaceList);
        throw std::runtime_error{ "ERROR_GETTING_DEVICE_INTERFACE_LIST" };
    }

    size_t deviceInterfaceLength = wcslen(mp_deviceInterface);
    HANDLE file = INVALID_HANDLE_VALUE;
    for (PWSTR currentInterface = deviceInterfaceList; *currentInterface; currentInterface += wcslen(currentInterface) + 1) {
        if (0 != wcsncmp(currentInterface, mp_deviceInterface, deviceInterfaceLength)) {
            continue;
        }

        file = CreateFile(currentInterface, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
        if (INVALID_HANDLE_VALUE == file) {
            continue;
        }

        break;
    }
    free(deviceInterfaceList);
    if (INVALID_HANDLE_VALUE == file) {
        throw std::runtime_error{ "ERROR_INVALID_HANDLE_VALUE" };
    }

    mp_deviceHandle = file;
    m_isInitialized = true;
}

bool Device::isInitialized() const
{
    return m_isInitialized;
}

bool Device::isAborted() const
{
    return m_isAborted;
}

void Device::abort()
{
    if (nullptr != mp_deviceHandle && INVALID_HANDLE_VALUE != mp_deviceHandle) {
        CloseHandle(mp_deviceHandle);
    }
    m_isAborted = true;
}

void Device::setOutputReport(PVOID data, DWORD size)
{
    if (!HidD_SetOutputReport(mp_deviceHandle, data, size)) {
        throw std::runtime_error{ "ERROR_SET_OUTPUT_REPORT" };
    }
}
aydunno
  • 91
  • 10
  • 1
    The github project uses QMake and links to user32.lib, cfgmgr32.lib, advapi32.lib and hid.lib here: [https://github.com/hedgar2017/loki-example/blob/master/loki-example.pro#L6](https://github.com/hedgar2017/loki-example/blob/master/loki-example.pro#L6) – drescherjm Jun 27 '21 at 14:53
  • Your comment is very much appraciated. Im trying with qtcreator now. It gives the error that it cant find the libraries. According to the qt forums, these are standard windows libraries and should not be explictly included via the pro file. When I comment them out an build again, guess what, I get the exact same errors as I got with VS. As usually when I work with windows Im in awe about the clear concepts, transparency, the docs and the community of windows. I didnt have one "stupid" thread here for last two years I worked with Linux and Python. Day 3 im MS land and its already driving me mad – aydunno Jun 27 '21 at 20:51
  • Fellow c++/visual studio noobs: Not so suppringsingly it helps to google what the build tools/compiler does. So MinGW/MSVC or whatever your SDK uses. The problems here were that hidsdi.h is part of hdi.lib and needs to linked differently and cfgmgr32.h needs to be included via `extern "C" {` block. Other errors while compiling were simple fixes. – aydunno Jun 28 '21 at 17:41

0 Answers0