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