#ifndef _RVC_DEVICE_ADAPTER_ENTITY_BASE_H__ #define _RVC_DEVICE_ADAPTER_ENTITY_BASE_H__ #pragma once #include "SpBase.h" #include "SpHelper.h" #include "DeviceBaseClass.h" #include "SimpleString.h" #include "path.h" #include #include #include #define SAFE_FREE_LIBRARY(hModule) \ do { \ if(hModule){ \ FreeLibrary(hModule); \ hModule = NULL; \ } \ }while(0) #if DEVICE_BASE_INTERFACE_FILE_VERSION == 2 using DevAdaptObjCreateFunc = ErrorCodeEnum(*)(DWORD dwDevClassID, DeviceBaseClass * &pOutDevAptObj); using DevAdaptObjReleaseFunc = ErrorCodeEnum(*)(DWORD dwDevClassID, DeviceBaseClass * &pInDevAptObj); #else using DevAdaptObjCreateFunc = ErrorCodeEnum(*)(DeviceBaseClass * &pOutDevAptObj); using DevAdaptObjReleaseFunc = ErrorCodeEnum(*)(DeviceBaseClass * &pInDevAptObj); #endif template struct DevAdptLibHelper { ErrorCodeEnum LoadLibAddress(const CSimpleStringA& strFullLibPath) { ErrorCodeEnum erroCode = Error_Succeed; do { hModule = LoadLibraryA(strFullLibPath); if (hModule == NULL) { DWORD tmpError = GetLastError(); Dbg("LoadLibraryA[%s] failed with error %u.", strFullLibPath, tmpError); if (tmpError == 126) { Dbg("该问题是缺失某个DLL导致的错误。"); SetLastError(126); } erroCode = Error_DevLoadFileFailed; break; } if ((pFuncCreateAdapt = (DevAdaptObjCreateFunc)GetProcAddress(hModule, "CreateDevComponent")) == NULL) { //TODO: SetCustLastErrorCode(); Dbg("Get 'CreateDevComponent' Func address failed with code %d", GetLastError()); erroCode = Error_DevLoadFileFailed; break; } if ((pFuncReleaseAdapt = (DevAdaptObjReleaseFunc)GetProcAddress(hModule, "ReleaseDevComponent")) == NULL) { Dbg("Get 'ReleaseDevComponent' Func address failed with code %d", GetLastError()); erroCode = Error_DevLoadFileFailed; break; } } while (false); if (IS_FAILURED(erroCode)) { TearDown(); } return erroCode; } ErrorCodeEnum CreateDevAdptObject() { if (m_AdptObjPtr != nullptr) { return Error_AlreadyExist; } if (hModule == nullptr || pFuncCreateAdapt == nullptr || pFuncReleaseAdapt == nullptr) { return Error_NotInit; } ErrorCodeEnum erroCode = Error_Succeed; erroCode = pFuncCreateAdapt((DeviceBaseClass*&)m_AdptObjPtr); if (IS_FAILURED(erroCode)) { Dbg("Create device adapter object failed! EC=%s", SpStrError(erroCode)); return erroCode; } LOG_ASSERT(m_AdptObjPtr != nullptr); return Error_Succeed; } ErrorCodeEnum LoadUp(const CSimpleStringA& strFullLibPath) { ErrorCodeEnum erroCode = LoadLibAddress(strFullLibPath); if (IS_SUCCEED(erroCode)) { erroCode = CreateDevAdptObject(); } return erroCode; } ErrorCodeEnum TearDown() { if (m_AdptObjPtr != nullptr) { m_AdptObjPtr->DevClose(); if (nullptr != pFuncReleaseAdapt) { pFuncReleaseAdapt(0, m_AdptObjPtr); m_AdptObjPtr = nullptr; } } SAFE_FREE_LIBRARY(hModule); } TSubAdpt* operator ->() { return m_AdptObjPtr; } DevAdptLibHelper() :hModule(nullptr) , pFuncCreateAdapt(nullptr), pFuncReleaseAdapt(nullptr) , m_AdptObjPtr(nullptr) { } ~DevAdptLibHelper() { TearDown(); } private: HMODULE hModule; DevAdaptObjCreateFunc pFuncCreateAdapt; DevAdaptObjReleaseFunc pFuncReleaseAdapt; TSubAdpt* m_AdptObjPtr; }; struct VendorLibInfo { CSimpleStringA strDevice; CSimpleStringA strVendor; CSimpleStringA strVersion; CSimpleStringA strBatch; VendorLibInfo() :strDevice(true), strVendor(true), strVersion(true), strBatch(true) {} bool IsValid() const { return (!strDevice.IsNullOrEmpty() && !strVendor.IsNullOrEmpty() && !strVersion.IsNullOrEmpty() && !strBatch.IsNullOrEmpty()); } int GetVersion() { int result = 0; if (!strVersion.IsNullOrEmpty()) { result = atoi(strVersion.GetData()); } return result; } int GetBatch() { int result = 0; if (!strBatch.IsNullOrEmpty()) { result = atoi(strBatch.GetData()); } return result; } CSimpleStringA toLibNameString() { CSimpleStringA strFullLibName(true); if (!strDevice.IsNullOrEmpty()) { strFullLibName = strDevice; if (strVendor.IsNullOrEmpty()) { strFullLibName += "."; strFullLibName += strVendor; } if (strVersion.IsNullOrEmpty()) { strFullLibName += "."; strFullLibName += strVersion; } if (strBatch.IsNullOrEmpty()) { strFullLibName += "."; strFullLibName += strBatch; } #ifdef _WIN32 strFullLibName += ".dll"; #else CSimpleStringA strPrefix("lib"); strPrefix += strFullLibName; strPrefix += ".so"; strFullLibName = strPrefix; #endif //_WIN32 } return strFullLibName; } }; class CDevAdptEntityBase : public CEntityBase { public: CDevAdptEntityBase(){} CSimpleStringA GetVendorLibName() { if (m_libInfo.IsValid()) { ExtractVendorLibName(); } return m_libInfo.toLibNameString(); } ErrorCodeEnum ExtractVendorLibFullPath(CSimpleStringA& csLibFullPath); ErrorCodeEnum InitializeVendorLogSwitch(); private: ErrorCodeEnum ExtractVendorLibName(); protected: VendorLibInfo m_libInfo; }; inline ErrorCodeEnum CDevAdptEntityBase::ExtractVendorLibName() { CSmartPointer spRootConfig; ErrorCodeEnum erroCode = GetFunction()->OpenConfig(Config_Root, spRootConfig); if (IS_SUCCEED(erroCode)) { CSimpleStringA strSection = CSimpleStringA("Device.") + GetEntityName(); m_libInfo.strDevice = GetEntityName(); spRootConfig->ReadConfigValue(strSection, "Vendor", m_libInfo.strVendor); spRootConfig->ReadConfigValue(strSection, "Version", m_libInfo.strVersion); spRootConfig->ReadConfigValue(strSection, "Batch", m_libInfo.strBatch); if (!m_libInfo.IsValid()) erroCode = Error_NotConfig; } return erroCode; } inline ErrorCodeEnum CDevAdptEntityBase::ExtractVendorLibFullPath(CSimpleStringA& csLibFullPath) { CSimpleStringA strLibName = GetVendorLibName(); if (strLibName.IsNullOrEmpty()) { return Error_Unexpect; } CSimpleStringA strDepPath; GetFunction()->GetPath("Dep", strDepPath); csLibFullPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (LPCTSTR)strDepPath, (LPCTSTR)strLibName); return Error_Succeed; } inline ErrorCodeEnum CDevAdptEntityBase::InitializeVendorLogSwitch() { CSystemStaticInfo sysInfo; GetFunction()->GetSystemStaticInfo(sysInfo); if (!m_libInfo.IsValid()) ExtractVendorLibName(); struct VendorLogConfig { CSimpleStringA strLevel; CSimpleStringA strType; CSimpleStringA strDllName; CSimpleStringA strLogPath; void Settle() { SetEnvironmentVariableA("VENDOR_RECODE_LEVEL", strLevel); SetEnvironmentVariableA("VENDOR_RECODE_TYPE", strType); SetEnvironmentVariableA("VENDOR_DLL_NAME", strDllName); SetEnvironmentVariableA("VENDOR_LOG_PATH", strLogPath); } } stLogConfig = { "OFF" "FILE", m_libInfo.toLibNameString(), ""}; CSmartPointer centerConfig; GetFunction()->OpenConfig(Config_CenterSetting, centerConfig); CSimpleStringA str; centerConfig->ReadConfigValue(GetEntityName(), m_libInfo.strVendor, str); if (str.IsNullOrEmpty()) { centerConfig->ReadConfigValue(GetEntityName(), "All", str); } if (!str.IsNullOrEmpty()) stLogConfig.strLevel = str; if (stLogConfig.strLevel.Compare("OFF", true) != 0) { CSimpleStringA strWhiteNameSheet; centerConfig->ReadConfigValue(GetEntityName(), "AllowTerminals", strWhiteNameSheet); if (!strWhiteNameSheet.IsNullOrEmpty()) { bool bWhiteNameSheet = false; CAutoArray arrayWhiteNameSheet = strWhiteNameSheet.Split(','); for (int i = 0; i < arrayWhiteNameSheet.GetCount(); i++) { std::regex pattern(arrayWhiteNameSheet[i]); if (std::regex_match(sysInfo.strTerminalID.GetData(), pattern)) { bWhiteNameSheet = true; break; } } //if this terminal is not at WhiteNameSheet,set level with "OFF". if (!bWhiteNameSheet) stLogConfig.strLevel = "OFF"; } } if (stLogConfig.strLevel.Compare("OFF", true) != 0) { str.Clear(); centerConfig->ReadConfigValue(GetEntityName(), "Type", str); if (!str.IsNullOrEmpty()) stLogConfig.strType = str; TCHAR szPath[MAX_PATH] = { 0 }; GetModuleFileNameA(NULL, szPath, MAX_PATH); CSimpleStringA strDir = szPath; str = strDir.SubString(0, 1); str += ":/rvc/dbg"; stLogConfig.strLogPath = str; stLogConfig.Settle(); } } #endif /*_RVC_DEVICE_ADAPTER_ENTITY_BASE_H__*/