Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 93 additions & 38 deletions vioserial/app/device.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
#include "device.h"
#include "assert.h"
#pragma warning(disable : 4201)
#include <setupapi.h>
#include <winioctl.h>
#pragma warning(default : 4201)
#include <string>
#include <regex>

const DWORD LOOKUP_PORT_MAX = 32;

CDevice::CDevice()
{
Expand All @@ -15,10 +23,11 @@ CDevice::~CDevice()
}
}

BOOL CDevice::Init(BOOL ovrl, UINT index)
BOOL CDevice::Init(BOOL ovrl, UINT portId)
{
PWCHAR DevicePath = NULL;
if ((DevicePath = GetDevicePath(index, (LPGUID)&GUID_VIOSERIAL_PORT)) != NULL)
PWCHAR DevicePath;
std::vector<uint8_t> devpathBuf;
if ((DevicePath = GetDevicePath(portId, (LPGUID)&GUID_VIOSERIAL_PORT, devpathBuf)) != NULL)
{
m_hDevice = CreateFile(DevicePath,
GENERIC_WRITE | GENERIC_READ,
Expand All @@ -35,7 +44,7 @@ BOOL CDevice::Init(BOOL ovrl, UINT index)
}
}
DWORD err = GetLastError();
printf("Cannot find vioserial device. %S , error = %d\n", DevicePath, err);
printf("Cannot find vioserial device PortId:%u, error: %u\n", portId, err);
return FALSE;
}

Expand Down Expand Up @@ -230,7 +239,7 @@ BOOL CDevice::GetInfo(PVOID buf, size_t *size)
return res;
}

PTCHAR CDevice::GetDevicePath(UINT index, IN LPGUID InterfaceGuid)
PTCHAR CDevice::GetDevicePath(UINT portId, IN LPGUID InterfaceGuid, std::vector<uint8_t> &devpathBuf)
{
HDEVINFO HardwareDeviceInfo;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
Expand All @@ -248,44 +257,90 @@ PTCHAR CDevice::GetDevicePath(UINT index, IN LPGUID InterfaceGuid)

DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo, 0, InterfaceGuid, index, &DeviceInterfaceData);

if (bResult == FALSE)
{
printf("Cannot get enumerate device interfaces.\n");
SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
return NULL;
}

SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo, &DeviceInterfaceData, NULL, 0, &RequiredLength, NULL);

DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LMEM_FIXED, RequiredLength);

if (DeviceInterfaceDetailData == NULL)
for (DWORD index = 0; index < LOOKUP_PORT_MAX; index++)
{
printf("Cannot allocate memory.\n");
SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
return NULL;
}
bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo, 0, InterfaceGuid, index, &DeviceInterfaceData);
if (!bResult)
{
DWORD dwErr = GetLastError();
if (dwErr == ERROR_NO_MORE_ITEMS)
{
printf("EnumDeviceInterfaces stopped at idx %u\n", index);
break;
}
printf("EnumDeviceInterfaces[%u] error: %u\n", index, dwErr);
continue;
}

DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
bResult = SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo,
&DeviceInterfaceData,
NULL,
0,
&RequiredLength,
NULL);
if (!bResult)
{
DWORD dwErr = GetLastError();
if (dwErr != ERROR_INSUFFICIENT_BUFFER)
{
printf("SetupDiGetDeviceInterfaceDetail[%u] failed with %u\n", index, dwErr);
continue;
}
}

Length = RequiredLength;
if (devpathBuf.size() < RequiredLength)
{
devpathBuf.resize(RequiredLength);
}
DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)devpathBuf.data();
DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

Length = RequiredLength;

bResult = SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo,
&DeviceInterfaceData,
DeviceInterfaceDetailData,
Length,
&RequiredLength,
NULL);
if (!bResult)
{
printf("Cannot get device interface details.\n");
SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
return NULL;
}

bResult = SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo,
&DeviceInterfaceData,
DeviceInterfaceDetailData,
Length,
&RequiredLength,
NULL);
std::wstring path(DeviceInterfaceDetailData->DevicePath);
std::wregex regex(L"&\\d+#");
std::wsmatch wsm;
if (!std::regex_search(path, wsm, regex))
{
wprintf(L"Failed to parse path: %ls\n", DeviceInterfaceDetailData->DevicePath);
break;
}
// intializing a string without '&' and '#' symbols (ex. "&06#")
// portIdStr will be "06"
std::wstring portIdStr(wsm.str(), 1, wsm.str().length() - 1);
ULONG portIdFromPath;
try
{
portIdFromPath = std::stoi(portIdStr);
}
catch (const std::exception &)
{
wprintf(L"Could not parse port ID from '%ls'. Skipping.\n", portIdStr.c_str());
continue;
}

if (bResult == FALSE)
{
printf("Cannot get device interface details.\n");
SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
LocalFree(DeviceInterfaceDetailData);
return NULL;
if (portIdFromPath == portId)
{
printf("Found vio-serial %u\n", portId);
SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
return DeviceInterfaceDetailData->DevicePath;
}
}

return DeviceInterfaceDetailData->DevicePath;
printf("Cannot find a port with ID:%u\n", portId);
SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
return NULL;
}
11 changes: 3 additions & 8 deletions vioserial/app/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,15 @@
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <vector>
#include "..\sys\public.h"
#pragma warning(disable : 4201)

#include <setupapi.h>
#include <winioctl.h>

#pragma warning(default : 4201)

class CDevice
{
public:
CDevice();
~CDevice();
BOOL Init(BOOL ovrl, UINT index);
BOOL Init(BOOL ovrl, UINT portId);
BOOL Write(PVOID buf, size_t *size);
BOOL WriteEx(PVOID buf, size_t *size);
BOOL Read(PVOID buf, size_t *size);
Expand All @@ -30,7 +25,7 @@ class CDevice

protected:
HANDLE m_hDevice;
PTCHAR GetDevicePath(UINT index, IN LPGUID InterfaceGuid);
PTCHAR GetDevicePath(UINT portId, IN LPGUID InterfaceGuid, std::vector<uint8_t> &devpathBuf);
};

#endif
3 changes: 2 additions & 1 deletion vioserial/app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#pragma warning(default : 4201)

static const DWORD LOOKUP_PORT_MAX_ID = 32;
static ULONG write_buffer_size = 4096;
static BOOL write_send_auto = FALSE;

Expand Down Expand Up @@ -264,7 +265,7 @@ _cdecl wmain(__in ULONG argc, __in_ecount(argc) PWCHAR argv[])
while (!m_pDev->Init(ovrl, ifIndex))
{
ifIndex++;
if (ifIndex >= 4)
if (ifIndex >= LOOKUP_PORT_MAX_ID)
{
delete m_pDev;
return 2;
Expand Down