25 #ifndef INCLUDED_CheckFirmwareVersion_h_GUID_C1356250_0CF2_4595_83A5_1522F8AC6795 
   26 #define INCLUDED_CheckFirmwareVersion_h_GUID_C1356250_0CF2_4595_83A5_1522F8AC6795 
   32 #include <boost/assert.hpp> 
   34 #include <boost/algorithm/string/erase.hpp> 
   35 #include <boost/algorithm/string/predicate.hpp> 
   36 #include <boost/algorithm/string/replace.hpp> 
   37 #include <boost/lexical_cast.hpp> 
   41 #include <comutils/ComPtr.h> 
   42 #include <comutils/ComVariant.h> 
   45 #ifdef OSVR_HAVE_CODECVT 
   48 #else // !OSVR_HAVE_CODECVT 
   49 #include <boost/locale/encoding_utf.hpp> 
   50 #endif // OSVR_HAVE_CODECVT 
   58     static const auto CAMERA_FIRMWARE_UPGRADE_REQUIRED = 6;
 
   59     static const auto CURRENT_CAMERA_FIRMWARE_VERSION = 7;
 
   61     template <
typename T> 
inline std::string wideToUTF8String(T input) {
 
   62 #ifdef OSVR_HAVE_CODECVT 
   63         std::wstring_convert<std::codecvt_utf8<wchar_t> > strCvt;
 
   64         return strCvt.to_bytes(input);
 
   65 #else  // !OSVR_HAVE_CODECVT 
   66         return boost::locale::conv::utf_to_utf<char>(input);
 
   67 #endif // OSVR_HAVE_CODECVT 
   70     template <
typename T> 
inline std::wstring narrowToWideString(T input) {
 
   71 #ifdef OSVR_HAVE_CODECVT 
   72         std::wstring_convert<std::codecvt_utf8<wchar_t> > strCvt;
 
   73         return strCvt.from_bytes(input);
 
   74 #else  // !OSVR_HAVE_CODECVT 
   75         return boost::locale::conv::utf_to_utf<wchar_t>(input);
 
   76 #endif // OSVR_HAVE_CODECVT 
   79     enum class FirmwareStatus {
 
   88     inline FirmwareStatus checkCameraFirmwareRevision(std::string path) {
 
   90         FirmwareStatus ret = FirmwareStatus::Unknown;
 
   93             auto endOfPath = path.find(
"#{");
 
   94             if (endOfPath != std::string::npos) {
 
   95                 path.erase(endOfPath);
 
  100             static const auto prefixString = 
"\\\\?\\";
 
  101             static const auto prefixLength = 4;
 
  102             BOOST_ASSERT(std::strlen(prefixString) == prefixLength);
 
  104             if (boost::algorithm::starts_with(path, prefixString)) {
 
  105                 boost::algorithm::erase_head(path, prefixLength);
 
  110         boost::algorithm::ireplace_all(path, 
"#", 
"\\\\");
 
  111         std::wstring wpath = narrowToWideString(path);
 
  120         comutils::Ptr<IWbemLocator> locator;
 
  122             CoCreateInstance(CLSID_WbemLocator, 
nullptr, CLSCTX_INPROC_SERVER,
 
  123                              IID_IWbemLocator, AttachPtr(locator));
 
  124         if (FAILED(result)) {
 
  130         comutils::Ptr<IWbemServices> wbemServices;
 
  135         result = locator->ConnectServer(
 
  136             bstr_t(L
"ROOT\\CIMV2"),         
 
  140             WBEM_FLAG_CONNECT_USE_MAX_WAIT, 
 
  144             AttachPtr(wbemServices)         
 
  147         if (FAILED(result)) {
 
  154             CoSetProxyBlanket(wbemServices.get(), RPC_C_AUTHN_WINNT,
 
  155                               RPC_C_AUTHZ_NONE, 
nullptr, RPC_C_AUTHN_LEVEL_CALL,
 
  156                               RPC_C_IMP_LEVEL_IMPERSONATE, 
nullptr, EOAC_NONE);
 
  158         if (FAILED(result)) {
 
  165             L
"SELECT * FROM Win32_PnPEntity WHERE DeviceID=\"" + wpath + L
"\"";
 
  167         comutils::Ptr<IEnumWbemClassObject> devEnum;
 
  168         result = wbemServices->ExecQuery(bstr_t(L
"WQL"), bstr_t(query.c_str()),
 
  169                                          WBEM_FLAG_FORWARD_ONLY |
 
  170                                              WBEM_FLAG_RETURN_IMMEDIATELY,
 
  171                                          nullptr, AttachPtr(devEnum));
 
  172         if (FAILED(result)) {
 
  173             std::cout << 
"Query failed!" << std::endl;
 
  176         comutils::Ptr<IWbemClassObject> wbemClassObj;
 
  179             HRESULT hr = devEnum->Next(WBEM_INFINITE, 1,
 
  180                                        AttachPtr(wbemClassObj), &numObjRet);
 
  182             if (FAILED(hr) || numObjRet == 0) {
 
  186             using comutils::Variant;
 
  188             using comutils::containsArray;
 
  189             using comutils::getArray;
 
  193             Variant varHardwareID;
 
  194             hr = wbemClassObj->Get(L
"HardwareID", 0,
 
  195                                    AttachVariant(varHardwareID), 
nullptr,
 
  197             if (!containsArray<std::wstring>(varHardwareID)) {
 
  199                 std::cout << 
"HardwareID doesn't contain a string array! VT is " 
  200                           << varHardwareID.get().vt << std::endl;
 
  205             for (
auto &&hwid : getArray<std::wstring>(varHardwareID)) {
 
  206                 auto narrow = wideToUTF8String(hwid);
 
  208                 auto loc = narrow.find(
"REV_");
 
  209                 if (loc != std::string::npos) {
 
  210                     auto revString = narrow.substr(loc);
 
  212                     boost::algorithm::erase_head(revString, 4);
 
  215                     std::istringstream iss(revString);
 
  219                         if (rev < CAMERA_FIRMWARE_UPGRADE_REQUIRED) {
 
  220                             ret = FirmwareStatus::UpgradeRequired;
 
  222                         } 
else if (rev < CURRENT_CAMERA_FIRMWARE_VERSION) {
 
  223                             ret = FirmwareStatus::UpgradeUseful;
 
  224                         } 
else if (rev > CURRENT_CAMERA_FIRMWARE_VERSION) {
 
  225                             ret = FirmwareStatus::Future;
 
  227                                 << 
"\n[Video-based Tracking] Detected camera " 
  232                             ret = FirmwareStatus::Good;
 
  245 #endif // INCLUDED_CheckFirmwareVersion_h_GUID_C1356250_0CF2_4595_83A5_1522F8AC6795