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" };
    }
}
