39 #include <comutils/ComVariant.h> 
   40 #include <intrusive_ptr_COM.h> 
   42 #include <boost/intrusive_ptr.hpp> 
   43 #include <boost/noncopyable.hpp> 
   58         class ComRAII : boost::noncopyable {
 
   61                 auto result = CoInitializeEx(
nullptr, COINIT_MULTITHREADED);
 
   70             bool failed()
 const { 
return m_failed; }
 
   73             bool m_failed = 
false;
 
   80         class USBVidPidExtractor {
 
   84                       "USB.VID_([[:xdigit:]]{4})&PID_([[:xdigit:]]{4})") {}
 
   86             boost::optional<std::pair<uint16_t, uint16_t>>
 
   87             getVidPid(std::string 
const &hardwareId) {
 
   89                 if (!std::regex_search(hardwareId, m, m_vidPidRegex)) {
 
   95                 return std::make_pair(m_hexToInt(m.str(1)),
 
   96                                       m_hexToInt(m.str(2)));
 
  102             uint16_t m_hexToInt(std::string 
const &str) {
 
  105                 m_ss << std::hex << str;
 
  111             std::regex m_vidPidRegex;
 
  119     getPNPDeviceIdSearchString(boost::optional<uint16_t> 
const &vendorID,
 
  120                                boost::optional<uint16_t> 
const &productID) {
 
  123         std::ostringstream searchTerms;
 
  125             searchTerms << 
"VID_" << std::setfill(
'0') << std::setw(4)
 
  126                         << std::hex << *vendorID;
 
  128         if (vendorID && productID) {
 
  132             searchTerms << 
"PID_" << std::setfill(
'0') << std::setw(4)
 
  133                         << std::hex << *productID;
 
  136         std::string ret{searchTerms.str()};
 
  138                        [](
char c) { return ::toupper(c); });
 
  143     std::vector<USBSerialDevice>
 
  144     getSerialDeviceList(boost::optional<uint16_t> vendorID,
 
  145                         boost::optional<uint16_t> productID) {
 
  146         using boost::intrusive_ptr;
 
  148         auto searchString = getPNPDeviceIdSearchString(vendorID, productID);
 
  151         std::vector<USBSerialDevice> devices;
 
  155         if (comSetup.failed()) {
 
  164         intrusive_ptr<IWbemLocator> locator;
 
  167             CoCreateInstance(CLSID_WbemLocator, 
nullptr, CLSCTX_INPROC_SERVER,
 
  168                              IID_IWbemLocator, AttachPtr(locator));
 
  170         if (FAILED(result)) {
 
  176         intrusive_ptr<IWbemServices> wbemServices;
 
  181         result = locator->ConnectServer(
 
  182             bstr_t(L
"ROOT\\CIMV2"),         
 
  186             WBEM_FLAG_CONNECT_USE_MAX_WAIT, 
 
  190             AttachPtr(wbemServices)         
 
  193         if (FAILED(result)) {
 
  200             CoSetProxyBlanket(wbemServices.get(), RPC_C_AUTHN_WINNT,
 
  201                               RPC_C_AUTHZ_NONE, 
nullptr, RPC_C_AUTHN_LEVEL_CALL,
 
  202                               RPC_C_IMP_LEVEL_IMPERSONATE, 
nullptr, EOAC_NONE);
 
  204         if (FAILED(result)) {
 
  211         intrusive_ptr<IEnumWbemClassObject> devEnum;
 
  212         result = wbemServices->ExecQuery(
 
  213             bstr_t(L
"WQL"), bstr_t(L
"SELECT * FROM Win32_SerialPort"),
 
  214             WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
nullptr,
 
  217         if (FAILED(result)) {
 
  221         USBVidPidExtractor vidPidExtractor;
 
  223         intrusive_ptr<IWbemClassObject> wbemClassObj;
 
  226             HRESULT hr = devEnum->Next(WBEM_INFINITE, 1,
 
  227                                        AttachPtr(wbemClassObj), &numObjRet);
 
  229             if (FAILED(hr) || numObjRet == 0) {
 
  233             using comutils::Variant;
 
  238             hr = wbemClassObj->Get(L
"DeviceID", 0, AttachVariant(varPort),
 
  241                 util::wideToUTF8String(get<std::wstring>(varPort));
 
  245             Variant varHardwareID;
 
  246             hr = wbemClassObj->Get(L
"PNPDeviceID", 0,
 
  247                                    AttachVariant(varHardwareID), 
nullptr,
 
  249             std::string hardwareID =
 
  250                 util::wideToUTF8String(get<std::wstring>(varHardwareID));
 
  252             if (!searchString.empty()) {
 
  253                 if (hardwareID.find(searchString) == std::string::npos) {
 
  260             auto vidPid = vidPidExtractor.getVidPid(hardwareID);
 
  268             std::string path = 
"\\\\.\\" + port;
 
  270             devices.emplace_back(vidPid->first, vidPid->second, path, port);
 
std::stringstream m_ss
String stream used to convert the hex string to an int. 
Header wrapping the C99 standard stdint header. 
t_< detail::transform_< List, Fun >> transform
Configured header for internal UTF16 or Windows TCHAR to UTF8 conversion. Using this header requires ...