Files
ANSCORE/core/ANSLicensingSystem/ANSLicense.cpp

3201 lines
124 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Utility.h"
#include <hwinfo/PCIMapper.h>
#include <hwinfo/hwinfo.h>
#include <iomanip>
#include "spdlog/async.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/spdlog.h"
#include "spdlog/cfg/env.h" // support for loading levels from the environment variable
#include "spdlog/fmt/ostr.h" // support for user defined types
#include "spdlog/sinks/stdout_color_sinks.h"
#include "base64.h"
#include <spdlog/sinks/base_sink.h>
#include <winnt.h>
#include <algorithm>
#include <atomic>
#include <cctype>
#include <chrono>
#include <filesystem>
#include <system_error>
#include <cstdlib>
// Forward-declare OutputDebugStringA without pulling in <windows.h> (which
// drags winsock conflicts as noted in ANSLicense.h). Used by ANSCENTER_DebugLog.
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString);
#define MAX_CUSTOMER_NAME_LEN 100
#define FEATURE_1 0x1
#define FEATURE_2 0x2
#define FEATURE_3 0x4
#define FEATURE_4 0x8
#define FEATURE_5 0x10
#define FEATURE_6 0x20
#define FEATURE_7 0x40
#define FEATURE_8 0x80
// ----------------------------------------------------------------------------
// Log-prefix scrubber.
//
// We don't want noisy fully-qualified per-machine paths in log lines:
// "model loaded from C:\ProgramData\Jh7O7nUe7vS\Models\EngineModels\X"
// becomes
// "model loaded from Models\EngineModels\X"
//
// The prefix list is built once on first use and combines:
// - hardcoded ANSCENTER ProgramData roots (edit kStaticPrefixes below),
// - the OS temp directory resolved at runtime via std::filesystem,
// - per-OS conventional temp/env-var paths (TEMP/TMP on Windows;
// /tmp/, /var/tmp/, TMPDIR on POSIX).
//
// Each prefix is normalised to lowercase, has a trailing separator forced,
// and is added in BOTH `\` and `/` slash flavours so the matcher works on
// either form. Prefixes are sorted longest-first so a more specific prefix
// (e.g. C:\Users\Bob\AppData\Local\Temp\) wins over a shorter overlapping one.
//
// Case-insensitive, handles both `\` and `/` separators. Single pass, O(N*P)
// where N is message length and P is prefix count (~510 in practice). Called
// from every SPDLogger::Log* path and from ANSCENTER_DebugLog (the choke point
// used by ANS_DBG / ANSLIB_DBG).
// ----------------------------------------------------------------------------
namespace {
inline std::string to_lower_ascii(const std::string& s) {
std::string out(s.size(), '\0');
for (size_t i = 0; i < s.size(); ++i) {
out[i] = static_cast<char>(std::tolower(static_cast<unsigned char>(s[i])));
}
return out;
}
// Redacts sensitive strings (license keys, activation keys, hardware IDs)
// for logging while preserving enough surface for support-call correlation.
// Keeps the first 4 and last 4 chars; replaces the middle with '*'.
// Strings <= 8 chars are fully masked. Empty strings pass through.
inline std::string mask_secret(const std::string& s) {
if (s.empty()) return s;
if (s.size() <= 8) return std::string(s.size(), '*');
return s.substr(0, 4) + std::string(s.size() - 8, '*') + s.substr(s.size() - 4);
}
// Append both `\` and `/` slash flavours of `raw` to `dst`, lower-cased
// and with a trailing separator forced. Empty / pathologically short
// entries are skipped.
inline void push_prefix_variants(std::vector<std::string>& dst, const std::string& raw) {
if (raw.size() < 2) return;
std::string normalised = raw;
char last = normalised.back();
if (last != '\\' && last != '/') normalised.push_back('\\');
std::string lowerBs = to_lower_ascii(normalised);
std::string lowerFs = lowerBs;
for (char& c : lowerFs) if (c == '\\') c = '/';
dst.push_back(lowerBs);
if (lowerFs != lowerBs) dst.push_back(lowerFs);
}
// Build the prefix table once. Function-local static is initialised
// exactly once per process (C++11 magic-static rule, thread-safe).
const std::vector<std::string>& GetLogPrefixesLower() {
static const std::vector<std::string> kPrefixesLower = []() {
std::vector<std::string> v;
// 1. Hardcoded ANSCENTER ProgramData roots — edit this list to
// add or remove well-known noise prefixes that aren't tied to
// the OS temp/user dir.
static const char* kStaticPrefixes[] = {
"C:\\ProgramData\\ANSCENTER\\",
"C:\\ProgramData\\Jh7O7nUe7vS\\",
nullptr,
};
for (int i = 0; kStaticPrefixes[i]; ++i) {
push_prefix_variants(v, kStaticPrefixes[i]);
}
// 2. OS temp directory (Windows: usually %LOCALAPPDATA%\Temp;
// Linux: usually /tmp; macOS: /private/var/folders/...).
try {
push_prefix_variants(v, std::filesystem::temp_directory_path().string());
} catch (...) { /* ignore — fallbacks below cover most cases */ }
// 3. Per-OS conventional fallbacks in case temp_directory_path()
// differs from what the env vars say or returns nothing useful.
#ifdef _WIN32
if (const char* p = std::getenv("TEMP")) push_prefix_variants(v, p);
if (const char* p = std::getenv("TMP")) push_prefix_variants(v, p);
push_prefix_variants(v, "C:\\Windows\\Temp\\"); // SYSTEM/services temp
#else
if (const char* p = std::getenv("TMPDIR")) push_prefix_variants(v, p);
push_prefix_variants(v, "/tmp/");
push_prefix_variants(v, "/var/tmp/");
#endif
// 4. De-duplicate (env vars + filesystem API often agree).
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());
// 5. Sort longest-first so specific prefixes win over shorter
// overlapping ones (e.g. AppData\Local\Temp\ before AppData\).
std::sort(v.begin(), v.end(),
[](const std::string& a, const std::string& b) {
return a.size() > b.size();
});
return v;
}();
return kPrefixesLower;
}
inline std::string strip_log_prefixes(const std::string& input) {
if (input.empty()) return input;
const auto& prefixes = GetLogPrefixesLower();
std::string lower = to_lower_ascii(input);
std::string out;
out.reserve(input.size());
size_t i = 0;
while (i < input.size()) {
bool matched = false;
for (const auto& p : prefixes) {
if (i + p.size() <= input.size() &&
lower.compare(i, p.size(), p) == 0) {
i += p.size();
matched = true;
break;
}
}
if (!matched) {
out.push_back(input[i]);
++i;
}
}
return out;
}
}
namespace ANSCENTER
{
template <typename T> T GetData(const boost::property_tree::ptree& pt, const std::string& key)
{
T ret;
if (boost::optional<T> data = pt.get_optional<T>(key))
{
ret = data.get();
}
return ret;
}
class WindowsEventSink : public spdlog::sinks::base_sink<std::mutex>
{
public:
explicit WindowsEventSink(const std::wstring& sourceName = L"ANSLogger")
: _sourceName(sourceName)
{
// Register the event source (you should ideally pre-register in registry for production use)
_eventSource = RegisterEventSourceW(nullptr, _sourceName.c_str());
}
~WindowsEventSink()
{
if (_eventSource)
{
DeregisterEventSource(_eventSource);
_eventSource = nullptr;
}
}
protected:
void sink_it_(const spdlog::details::log_msg& msg) override
{
if (!_eventSource)
return;
// Convert log message to wide string
std::wstring widePayload(msg.payload.begin(), msg.payload.end());
LPCWSTR strings[1] = { widePayload.c_str() };
// Map spdlog level to Windows Event Log type
WORD eventType = EVENTLOG_INFORMATION_TYPE;
switch (msg.level)
{
case spdlog::level::critical:
case spdlog::level::err:
eventType = EVENTLOG_ERROR_TYPE;
break;
case spdlog::level::warn:
eventType = EVENTLOG_WARNING_TYPE;
break;
case spdlog::level::info:
case spdlog::level::trace:
case spdlog::level::debug:
default:
eventType = EVENTLOG_INFORMATION_TYPE;
break;
}
// Use a non-zero event ID
DWORD eventID = 1000 + static_cast<int>(msg.level); // Custom event ID per log level
// Write to the event log
ReportEventW(
_eventSource, // Event source handle
eventType, // Event type
0, // Event category
eventID, // Event identifier (should be non-zero)
nullptr, // No user SID
1, // Number of strings
0, // No binary data
strings, // Array of strings
nullptr); // No binary data
}
void flush_() override {}
private:
HANDLE _eventSource = nullptr;
std::wstring _sourceName;
};
/// <summary>
/// SPDLogger
/// </summary>
SPDLogger::~SPDLogger() {
try {
Release();
}
catch (const std::exception& e) {
std::cout << "SPDLogger::~SPDLogger" << e.what() << std::endl;
}
}
bool SPDLogger::Release() {
static bool isReleased = false; // Track whether Release has already been called
if (isReleased) {
std::cout << "SPDLogger::Release has already been called. Skipping." << std::endl;
return true; // Return true since it was already successfully released
}
try {
// Check if the "anslogger" exists and drop it explicitly
auto anslogger = spdlog::get("anslogger");
if (anslogger) {
spdlog::drop("anslogger");
std::cout << "Released anslogger" << std::endl;
}
// Drop all remaining loggers
spdlog::drop_all();
std::cout << "Dropped all loggers" << std::endl;
// Shutdown the spdlog library
spdlog::shutdown();
std::cout << "Shutdown spdlog" << std::endl;
isReleased = true; // Mark release as done to prevent repeated shutdowns
return true;
}
catch (const std::exception& e) {
std::cout << "SPDLogger::Release exception: " << e.what() << std::endl;
return false;
}
}
void SPDLogger::Init() {
static std::once_flag initFlag;
std::call_once(initFlag, [this]() {
try {
// Two worker threads so the slow Event Log sink (RPC to event log
// service) cannot starve the console sink. Queue size unchanged.
spdlog::init_thread_pool(8192, 2);
ConfigureLogger();
}
catch (const spdlog::spdlog_ex& ex) {
std::cerr << "Logger::Init spdlog exception: " << ex.what() << std::endl;
}
catch (const std::exception& ex) {
std::cerr << "Logger::Init standard exception: " << ex.what() << std::endl;
}
catch (...) {
std::cerr << "Logger::Init unknown exception" << std::endl;
}
});
}
void SPDLogger::ConfigureLogger() {
try {
// Console sink (shared by console logger)
std::vector<spdlog::sink_ptr> consoleSinks;
_consoleLoggerEnable = true; // Enable console logger by default
if (_consoleLoggerEnable) {
auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
stdout_sink->set_level(spdlog::level::trace);
consoleSinks.push_back(stdout_sink);
// overrun_oldest: producer never blocks. If the queue fills (8192
// pending msgs), the OLDEST queued msg is dropped to make room.
// Why: block + 1-thread pool + slow WindowsEventSink can stall
// inference threads on logging and, if shutdown races a blocked
// producer, surface as system_error("resource deadlock would occur").
auto consoleLogger = std::make_shared<spdlog::async_logger>(
"anslogger_console", consoleSinks.begin(), consoleSinks.end(),
spdlog::thread_pool(), spdlog::async_overflow_policy::overrun_oldest);
consoleLogger->set_level(spdlog::level::trace);
consoleLogger->flush_on(spdlog::level::info);
spdlog::register_logger(consoleLogger);
}
// Windows Event Log sink (used only for LogError and LogFatal)
auto win_event_sink = std::make_shared<WindowsEventSink>(L"ANSLogger");
win_event_sink->set_level(spdlog::level::info);
std::vector<spdlog::sink_ptr> eventSinks{ win_event_sink };
// Same overrun_oldest policy as console — see note above. Especially
// important for this logger because WindowsEventSink::sink_it_ does
// a synchronous ReportEventW RPC which can be slow under load.
auto eventLogger = std::make_shared<spdlog::async_logger>(
"anslogger_event", eventSinks.begin(), eventSinks.end(),
spdlog::thread_pool(), spdlog::async_overflow_policy::overrun_oldest);
eventLogger->set_level(spdlog::level::info);
eventLogger->flush_on(spdlog::level::info);
spdlog::register_logger(eventLogger);
}
catch (const std::exception& ex) {
std::cerr << "SPDLogger::ConfigureLogger - Exception: " << ex.what() << std::endl;
}
}
void SPDLogger::Disable() {
try {
spdlog::set_level(spdlog::level::off);
}
catch (const std::exception& e) {
std::cout << "Logger::Disable:" << e.what() << std::endl;
}
}
void SPDLogger::Enable() {
try {
spdlog::set_level(spdlog::level::info);
}
catch (const std::exception& e) {
std::cout << "Logger::Enable:" << e.what() << std::endl;
}
}
//__FUNCTION__
void SPDLogger::LogTrace(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
std::string scrubbed = strip_log_prefixes(message);
try {
auto logger = spdlog::get("anslogger_console");
if (logger) logger->trace("{}: {}", msg, scrubbed);
auto eventLogger = spdlog::get("anslogger_event");
if (eventLogger) eventLogger->trace("{}: {}", msg, scrubbed);
}
catch (const std::exception& e) {
std::cerr << "SPDLogger::LogError - Exception: " << e.what() << std::endl;
}
}
void SPDLogger::LogInfo(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
std::string scrubbed = strip_log_prefixes(message);
try {
auto logger = spdlog::get("anslogger_console");
if (logger) {
logger->info("{}: {}", msg, scrubbed);
}
auto eventLogger = spdlog::get("anslogger_event");
if (eventLogger) eventLogger->info("{}: {}", msg, scrubbed);
}
catch (const std::exception& e) {
std::cerr << "SPDLogger::LogInfo - Exception: " << e.what() << std::endl;
}
}
void SPDLogger::LogWarn(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
std::string messageSource = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
std::string scrubbed = strip_log_prefixes(message);
try {
auto logger = spdlog::get("anslogger_console");
if (logger) {
logger->warn("{}: {}", messageSource, scrubbed);
}
else {
std::cerr << "SPDLogger::LogWarn - Logger not initialized: anslogger_console" << std::endl;
}
}
catch (const std::exception& e) {
std::cerr << "SPDLogger::LogWarn - Exception: " << e.what() << std::endl;
}
}
void SPDLogger::LogDebug(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
std::string scrubbed = strip_log_prefixes(message);
try {
auto logger = spdlog::get("anslogger_console");
if (logger) {
logger->debug("{}: {}", msg, scrubbed);
}
}
catch (const std::exception& e) {
std::cerr << "SPDLogger::LogInfo - Exception: " << e.what() << std::endl;
}
}
void SPDLogger::LogError(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
std::string scrubbed = strip_log_prefixes(message);
try {
auto logger = spdlog::get("anslogger_console");
if (logger) logger->error("{}: {}", msg, scrubbed);
auto eventLogger = spdlog::get("anslogger_event");
if (eventLogger) eventLogger->error("{}: {}", msg, scrubbed);
}
catch (const std::exception& e) {
std::cerr << "SPDLogger::LogError - Exception: " << e.what() << std::endl;
}
}
void SPDLogger::LogFatal(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
std::string scrubbed = strip_log_prefixes(message);
try {
auto logger = spdlog::get("anslogger_console");
if (logger) logger->critical("{}: {}", msg, scrubbed);
auto eventLogger = spdlog::get("anslogger_event");
if (eventLogger) eventLogger->critical("{}: {}", msg, scrubbed);
}
catch (const std::exception& e) {
std::cerr << "SPDLogger::LogFatal - Exception: " << e.what() << std::endl;
}
}
}
// C facade — exported with stable C linkage so ANSLIB (and any other consumer)
// can resolve via GetProcAddress without coupling to the C++ class ABI.
// Each call delegates to the process-wide SPDLogger singleton; the magic-static
// inside GetInstance handles thread-safe one-time initialisation.
extern "C" {
ANSLICENSE_API void ANSLogger_LogInfo(const char* src, const char* msg, const char* file, int line) {
try {
ANSCENTER::SPDLogger::GetInstance("ANSLIB").LogInfo(
src ? src : "", msg ? msg : "", file ? file : "", line);
} catch (...) {}
}
ANSLICENSE_API void ANSLogger_LogError(const char* src, const char* msg, const char* file, int line) {
try {
ANSCENTER::SPDLogger::GetInstance("ANSLIB").LogError(
src ? src : "", msg ? msg : "", file ? file : "", line);
} catch (...) {}
}
ANSLICENSE_API void ANSLogger_LogFatal(const char* src, const char* msg, const char* file, int line) {
try {
ANSCENTER::SPDLogger::GetInstance("ANSLIB").LogFatal(
src ? src : "", msg ? msg : "", file ? file : "", line);
} catch (...) {}
}
// DebugView emit path used by ANS_DBG and ANSLIB_DBG. Single choke point
// so the prefix scrubber lives in one place; macros just hand off the
// already-formatted "[Tag] body\n" buffer here.
ANSLICENSE_API void ANSCENTER_DebugLog(const char* buf) {
if (!buf) return;
try {
std::string scrubbed = strip_log_prefixes(buf);
OutputDebugStringA(scrubbed.c_str());
std::fputs(scrubbed.c_str(), stderr);
std::fflush(stderr);
} catch (...) {}
}
}
namespace ANSCENTER
{
EngineType ANSCENTER::ANSLicenseHelper::CheckHardwareInformation()
{
ANS_DBG("HWInfo", "CheckHardwareInformation: starting hardware detection");
bool cpuIntelAvailable = false;
bool gpuNvidiaAvailable = false;
bool gpuAMDAvailable = false;
bool gpuOpenVINOAvailable = false;
// ----------------------------------------------------------------
// CPU — Intel socket detection (OpenVINO fallback)
// ----------------------------------------------------------------
auto sockets = hwinfo::getAllSockets();
for (auto& socket : sockets) {
const auto& cpu = socket.CPU();
ANS_DBG("HWInfo", "CPU vendor=%s model=%s", cpu.vendor().c_str(), cpu.modelName().c_str());
if (cpu.vendor() == "GenuineIntel")
cpuIntelAvailable = true;
}
// ----------------------------------------------------------------
// GPU — classify all adapters by vendor string
// ----------------------------------------------------------------
auto gpus = hwinfo::getAllGPUs();
ANS_DBG("HWInfo", "Found %zu GPU adapter(s)", gpus.size());
for (auto& gpu : gpus) {
std::string vendor = gpu.vendor();
ANS_DBG("HWInfo", "GPU: name=%s vendor=%s", gpu.name().c_str(), vendor.c_str());
std::cout << "[HWInfo] Detected GPU: " << gpu.name() << " (Vendor: " << vendor << ")" << std::endl;
// Normalize to uppercase for reliable substring matching
std::transform(vendor.begin(), vendor.end(),
vendor.begin(), ::toupper);
if (vendor.find("NVIDIA") != std::string::npos)
gpuNvidiaAvailable = true;
if (vendor.find("INTEL") != std::string::npos)
gpuOpenVINOAvailable = true;
// AMD cards report as "AMD", "Advanced Micro Devices", or
// legacy "ATI Technologies" branding.
// NOTE: "ATI" alone is too broad — "INTEL CORPORATION" contains
// "ATI" inside "CORPOR-ATI-ON", causing a false positive.
// Use "ATI " (with trailing space) to match "ATI Technologies"
// or "ATI Radeon" without matching "CORPORATION".
if (vendor.find("AMD") != std::string::npos ||
vendor.find("ADVANCED MICRO") != std::string::npos ||
vendor.find("ATI ") != std::string::npos)
gpuAMDAvailable = true;
}
ANS_DBG("HWInfo", "Detection: cpuIntel=%d gpuNvidia=%d gpuAMD=%d gpuOpenVINO=%d",
cpuIntelAvailable, gpuNvidiaAvailable, gpuAMDAvailable, gpuOpenVINOAvailable);
// ----------------------------------------------------------------
// Priority: NVIDIA > AMD > Intel OpenVINO > CPU
//
// Dedicated GPU always wins over integrated Intel graphics.
// OpenVINO runs on the Intel CPU-side so it is last resort
// before pure CPU fallback.
// ----------------------------------------------------------------
if (gpuNvidiaAvailable) {
std::cout << "[HWInfo] Engine: NVIDIA GPU -> CUDA" << std::endl;
ANS_DBG("HWInfo", "Selected: NVIDIA_GPU (CUDA)");
return EngineType::NVIDIA_GPU;
//return EngineType::OPENVINO_GPU;
}
if (gpuAMDAvailable) {
std::cout << "[HWInfo] Engine: AMD GPU -> DirectML" << std::endl;
ANS_DBG("HWInfo", "Selected: AMD_GPU (DirectML)");
return EngineType::AMD_GPU;
}
if (gpuOpenVINOAvailable) {
std::cout << "[HWInfo] Engine: Intel CPU -> OpenVINO" << std::endl;
ANS_DBG("HWInfo", "Selected: OPENVINO_GPU (OpenVINO)");
return EngineType::OPENVINO_GPU;
}
std::cout << "[HWInfo] Engine: CPU (fallback)" << std::endl;
ANS_DBG("HWInfo", "Selected: CPU (fallback)");
return EngineType::CPU;
}
std::string ANSLicenseHelper::DecodeBase64(std::string base64String) {
BASE64 base64;
vector<unsigned char> result = base64.decode(base64String.c_str(), -1, nullptr);
string str(result.begin(), result.end());
return str.c_str();
}
bool ANSLicenseHelper::isPathSafe(const std::string& pathStr) {
// Basic safety checks - customize as needed
if (pathStr.empty()) return false;
if (pathStr == "/" || pathStr == "\\") return false;
if (pathStr == "C:\\" || pathStr == "c:\\") return false;
if (pathStr.find("..") != std::string::npos) return false; // Prevent path traversal
// Add more safety checks as needed for your use case
return true;
}
bool ANSLicenseHelper::deleteRecursively(const std::string& pathStr, bool safeMode) {
std::error_code ec;
std::filesystem::path path(pathStr);
// Additional safety checks in safe mode
if (safeMode && !isPathSafe(pathStr)) {
std::cerr << "Unsafe path detected, deletion aborted: " << pathStr << std::endl;
return false;
}
// Check if path exists
if (!std::filesystem::exists(path, ec)) {
if (ec) {
std::cerr << "Error checking existence: " << ec.message() << std::endl;
return false;
}
std::cout << "Path does not exist: " << pathStr << std::endl;
return true;
}
// Get info about what we're deleting
bool isDirectory = std::filesystem::is_directory(path, ec);
if (ec) {
std::cerr << "Error checking if path is directory: " << ec.message() << std::endl;
return false;
}
std::cout << "Deleting " << (isDirectory ? "directory" : "file") << ": " << pathStr << std::endl;
// Remove all contents recursively
std::uintmax_t removed = std::filesystem::remove_all(path, ec);
if (ec) {
std::cerr << "Error during deletion: " << ec.message() << std::endl;
return false;
}
std::cout << "Successfully removed " << removed << " files/directories" << std::endl;
return true;
}
bool ANSLicenseHelper::LicenseVerification(std::string licenseKey, int productId, std::string registrationName) {
//SPDLogger& _logger = SPDLogger::GetInstance("License", false);
try {
int _enableFeature;
int _productId;
std::string privateKey = "AQlSAiRTNtS7X20=";
int activationResult = 0;
std::string licensingServiceURL = "https://licensingservice.anscenter.com/";
ANSCENTER::ANSLSHelper ansHelper(privateKey, licensingServiceURL);
ansHelper.SetupLicenseTemplate();
std::string hwid = ansHelper.GetCurrentHardwareId();
std::string licenseDirectory = GetLicenseDir();
std::string licenseKeyFile;
std::vector<std::string> licenseKeyFiles = ListFilesInFolder(licenseDirectory);
// 1. License key is supplied
if (!licenseKey.empty()) {
std::string licenseKeyFileName = Dash2Underscore(licenseKey) + ".json";
licenseKeyFile = CreateFilePath(licenseDirectory, licenseKeyFileName);
if (FileExist(licenseKeyFile)) { // We only need to check if the license key valid and expiration date
// Read the license file key
std::string _validationData;
std::string _activationKey;
std::string _licenseKey;
if (ReadLicenseKeyFile(licenseKeyFile, _licenseKey, _activationKey, _validationData)) {
std::string _registrationName;
_registrationName = DecodeBase64(_validationData); // Decode
std::string licenseData = ansHelper.GetLicenseData(_licenseKey);
int expirationDate = GetExpirationDate(licenseData, _productId);
std::cout << "Expiration date:" << expirationDate << std::endl;
bool validLicenseKey = ansHelper.CheckLicenseKey(_licenseKey, _registrationName, _productId, _enableFeature);
if (validLicenseKey) {
if (expirationDate > 0) {
return true;
}
else {
std::cout<<"ANSUtilityHelper::LicenseVerification.", "License key is expired.";
return false;
}
}
}
}
else { // This should be the validation for a new API
std::string _activationKey;
activationResult = ansHelper.ValidateLicense(licenseKey, registrationName, _activationKey);
if (activationResult == LicenseKeyStatus::SUCCESS) {
return true; // Success
}
}
}
// 2. No license key, then list the existing license files
if (licenseKeyFiles.size() > 0) {
size_t lSize = licenseKeyFiles.size();
for (size_t i = 0; i < lSize; i++) {
std::string licenseFile = licenseKeyFiles[i];
// Read the license file key
std::string _validationData;
std::string _activationKey;
std::string _licenseKey;
if (ReadLicenseKeyFile(licenseFile, _licenseKey, _activationKey, _validationData)) {
std::string _registrationName = DecodeBase64(_validationData); // Decode
std::string licenseData = ansHelper.GetLicenseData(_licenseKey);
int expirationDate = GetExpirationDate(licenseData, _productId);
if ((_productId == 1003) || (_productId == productId)) { // If it is ANSVIS or correct Product
bool validLicense = ansHelper.CheckLicenseKey(_licenseKey, _registrationName, _productId, _enableFeature);
if (validLicense) {
if (expirationDate > 0) {
return true;
}
else {
std::cout << "ANSUtilityHelper::LicenseVerification.", "License key is expired.";
return false;
}
}
}
}
}
}
// 3. At this stage, it is still no license. we need to generate the trial license
std::string trialLicenseKey = GetTrialLicenseKey(registrationName);
if (trialLicenseKey.empty()) {
// Generate key based on productId for 30 day if it is in run-time mode
trialLicenseKey = ansHelper.GenerateKey(productId, registrationName, 0, true);
UpdateTrialLicenseKey(trialLicenseKey, registrationName);
}
// We need to check the license key
bool valid = ansHelper.CheckLicenseKey(trialLicenseKey, registrationName, productId, _enableFeature);
if (!valid) {
std::cout << "ANSUtilityHelper::LicenseVerification.", "Trial license is not valid.";
return false;
}
// Check license data
std::string licenseData = ansHelper.GetLicenseData(trialLicenseKey);
int expirationDate = GetExpirationDate(licenseData, _productId);
if (expirationDate > 0) {
return true;
}
else {
std::cout << "ANSUtilityHelper::LicenseVerification.", "Trial license key is expired.";
return false;
}
}
catch (std::exception& e) {
std::cout << "ANSUtilityHelper::LicenseVerification. Error"<< e.what();
return false;
}
}
int ANSLicenseHelper::ActivateTrialLicense(std::string productName) {
//SPDLogger& _logger = SPDLogger::GetInstance("License");
try {
int productId;
std::string registrationName;
std::string privateKey = "AQlSAiRTNtS7X20=";
std::string licensingServiceURL = "https://licensingservice.anscenter.com/";
ANSCENTER::ANSLSHelper ansHelper(privateKey, licensingServiceURL);
ansHelper.SetupLicenseTemplate();
if (productName == "ANNHUB") {//1000
registrationName = "ANNHUB-LV";
productId = 1000;
}
else if (productName == "DLHUB") {//1001
registrationName = "DLHUB-LV";
productId = 1001;
}
else if (productName == "ODHUB") {//1002
registrationName = "ODHUB-LV";
productId = 1002;
}
else if (productName == "ANSVIS") {//1003
registrationName = "ANSVIS";
productId = 1003;
}
else if (productName == "ANSFR") {//1004
registrationName = "ANSFR";
productId = 1004;
}
else if (productName == "ANSOCR") {//1005
registrationName = "ANSOCR";
productId = 1005;
}
else if (productName == "ANSALPR") {//1006
registrationName = "ANSALPR";
productId = 1006;
}
else if (productName == "ANSCV") {//1007
registrationName = "ANSCV";
productId = 1007;
}
else if (productName == "ANSTS") {//1008
registrationName = "ANSTS";
productId = 1008;
}
else {
registrationName = productName;
productId = 1009;
}
std::string trialLicenseKey = GetTrialLicenseKey(registrationName);
if (trialLicenseKey.empty()) {
// Generate key based on productId for 30 day if it is in run-time mode
trialLicenseKey = ansHelper.GenerateKey(productId, registrationName, 0, true);
UpdateTrialLicenseKey(trialLicenseKey, registrationName);
}
return 1;
}
catch (std::exception& e) {
std::cout << "ActivateTrialLicense::LicenseVerification. Error"<< e.what();
return 0;
}
}
int ANSLicenseHelper::DeactivateLicense(std::string productName) {
std::string licenseDirectory = GetLicenseDir();
std::vector<std::string> licenseKeyFiles = ListFilesInFolder(licenseDirectory);
std::string privateKey = "AQlSAiRTNtS7X20=";
std::string licensingServiceURL = "https://licensingservice.anscenter.com/";
ANSCENTER::ANSLSHelper ansHelper(privateKey, licensingServiceURL);
ansHelper.SetupLicenseTemplate();
size_t lSize = licenseKeyFiles.size();
if (lSize > 0) {
// run for loop from 0 to vecSize
for (size_t i = 0; i < lSize; i++)
{
// Add license to Json format
std::string licenseFile = licenseKeyFiles[i];
std::string _validationData;
std::string _activationKey;
std::string _licenseKey;
std::string _licenseData;
std::string _productName;
std::string _registrationName;
int _enableFeature=0;
int _productId;
// Read the license file key
if (ReadLicenseKeyFile(licenseFile, _licenseKey, _activationKey, _validationData)) {
std::string licenseData = ansHelper.GetLicenseData(_licenseKey);
int expirationDate = GetExpirationDate(licenseData, _productId);
switch (_productId) {
case ANSCENTER::ANSPRODUCTS::ANNHUB://1000
_productName = "ANNHUB";
break;
case ANSCENTER::ANSPRODUCTS::DLHUB://1001
_productName = "DLHUB";
break;
case ANSCENTER::ANSPRODUCTS::ODHUB://1002
_productName = "ODHUB";
break;
case ANSCENTER::ANSPRODUCTS::ANSVIS://1003
_productName = "ANSVIS";
break;
case ANSCENTER::ANSPRODUCTS::ANS_FACERECOGNIZE://1004
_productName = "ANSFR";
break;
case ANSCENTER::ANSPRODUCTS::ANS_OCR://1005
_productName = "ANSOCR";
break;
case ANSCENTER::ANSPRODUCTS::ANS_ALPR://1006
_productName = "ANSALPR";
break;
case ANSCENTER::ANSPRODUCTS::ANS_CV://1007
_productName = "ANSCV";
break;
case ANSCENTER::ANSPRODUCTS::ANS_TS://1008
_productName = "ANSTS";
break;
}
if (_productName == productName) {
// Delete the license file
bool result= DeleteLicenseFile(licenseFile);
if (result)return 1;
else return 0;
}
}
}
return 1;
}
return 0;
}
int ANSLicenseHelper::ActivateLicense(std::string productName, std::string licenseKey) {
std::string privateKey = "AQlSAiRTNtS7X20=";
std::string licensingServiceURL = "https://licensingservice.anscenter.com/";
ANSCENTER::ANSLSHelper ansHelper(privateKey, licensingServiceURL);
ansHelper.SetupLicenseTemplate();
std::string registrationName;
std::string _activationKey;
if (productName == "ANNHUB") {
registrationName = "ANNHUB-LV";//1000
}
else if (productName == "DLHUB") {
registrationName = "DLHUB-LV";//1001
}
else if (productName == "ODHUB") {
registrationName = "ODHUB-LV";//1002
}
else if (productName == "ANSVIS") {//1003
registrationName = "ANSVIS";
}
else if (productName == "ANSFR") {//1004
registrationName = "ANSFR";
}
else if (productName == "ANSOCR") {//1005
registrationName = "ANSOCR";
}
else if (productName == "ANSALPR") {//1006
registrationName = "ANSALPR";
}
else if (productName == "ANSCV") {//1007
registrationName = "ANSCV";
}
else if (productName == "ANSTS") {//1008
registrationName = "ANSTS";
}
else {
registrationName = productName;
}
int activationResult =ansHelper.ValidateLicense(licenseKey, registrationName, _activationKey);
return activationResult;
}
int ANSLicenseHelper::ActivateLicenseWithCustomHWID(std::string productName, std::string licenseKey, std::string hwid, std::string &activationKey) {
std::string privateKey = "AQlSAiRTNtS7X20=";
std::string licensingServiceURL = "https://licensingservice.anscenter.com/";
ANSCENTER::ANSLSHelper ansHelper(privateKey, licensingServiceURL);
ansHelper.SetupLicenseTemplate();
std::string registrationName;
if (productName == "ANNHUB") {
registrationName = "ANNHUB-LV";//1000
}
else if (productName == "DLHUB") {
registrationName = "DLHUB-LV";//1001
}
else if (productName == "ODHUB") {
registrationName = "ODHUB-LV";//1002
}
else if (productName == "ANSVIS") {//1003
registrationName = "ANSVIS";
}
else if (productName == "ANSFR") {//1004
registrationName = "ANSFR";
}
else if (productName == "ANSOCR") {//1005
registrationName = "ANSOCR";
}
else if (productName == "ANSALPR") {//1006
registrationName = "ANSALPR";
}
else if (productName == "ANSCV") {//1007
registrationName = "ANSCV";
}
else if (productName == "ANSTS") {//1008
registrationName = "ANSTS";
}
else {
registrationName = productName;
}
int activationResult = ansHelper.ActivateLicenseWithCustomHWID(licenseKey, registrationName, hwid, activationKey);
return activationResult;
}
std::string ANSLicenseHelper::DecodeValidationData(const char* validationData) {
std::string licenseKeyValidationData = ANSUtility::DecodeBase64Utility(validationData);
return licenseKeyValidationData;
}
std::string ANSLicenseHelper::GenerateActivationDataFile(std::string activationKey, std::string licenseKey, std::string hardwareId, std::string validationData) {
try {
boost::property_tree::ptree root;
boost::property_tree::ptree dataNode;
dataNode.put("activation_key", activationKey);
dataNode.put("license_key", licenseKey);
dataNode.put("hardware_id", hardwareId);
dataNode.put("license_key_validation_data", validationData);
root.add_child("activationData", dataNode);
std::ostringstream stream;
boost::property_tree::write_json(stream, root,false);
std::string st = stream.str();
return st;
}
catch (std::exception& e) {
std::cerr << "An error occurred: " << e.what() << std::endl;
return "";
}
}
bool ANSLicenseHelper::RemoveTrialLicenseKeys(std::string registrationName) {
return RemoveTrialLicenseKey(registrationName);
}
std::string ANSLicenseHelper::ListLicenses() {
//SPDLogger& _logger = SPDLogger::GetInstance("License");
try {
std::vector<ANSCENTER::ANSLicenseInfo> ansLicenseInfos;
std::vector<std::string> ansLicenseCollection;
std::string licenseDirectory = GetLicenseDir();
std::vector<std::string> licenseKeyFiles = ListFilesInFolder(licenseDirectory);
std::string privateKey = "AQlSAiRTNtS7X20=";
std::string licensingServiceURL = "https://licensingservice.anscenter.com/";
ANSCENTER::ANSLSHelper ansHelper(privateKey, licensingServiceURL);
ansHelper.SetupLicenseTemplate();
std::string hwid = ansHelper.GetCurrentHardwareId();
std::cout << "Current HWID: " << mask_secret(hwid) << std::endl;
boost::property_tree::ptree root;
size_t lSize = licenseKeyFiles.size();
boost::property_tree::ptree children;
// All ANS Products at this stage
ansLicenseCollection.push_back("ANNHUB");//1000
ansLicenseCollection.push_back("DLHUB");//1001
ansLicenseCollection.push_back("ODHUB");//1002
ansLicenseCollection.push_back("ANSVIS");//1003
ansLicenseCollection.push_back("ANSFR");//1004
ansLicenseCollection.push_back("ANSOCR");//1005
ansLicenseCollection.push_back("ANSALPR");//1006
ansLicenseCollection.push_back("ANSCV");//1007
ansLicenseCollection.push_back("ANSTS");//1008
for (auto& element : ansLicenseCollection) {
boost::property_tree::ptree dataNode;
ANSCENTER::ANSLicenseInfo ansLicenseInfo;
ansLicenseInfo.productName = element;
ansLicenseInfo.licenseStatus = ANSCENTER::ANSLICENSESTATUS::UNLICENSE;
// 1. Get installed license first
if (lSize > 0) {
// run for loop from 0 to vecSize
for (size_t i = 0; i < lSize; i++)
{
// Add license to Json format
std::string licenseFile = licenseKeyFiles[i];
std::string _validationData;
std::string _activationKey;
std::string _licenseKey;
std::string _licenseData;
std::string _productName;
std::string _registrationName;
int _enableFeature;
int expirationDate = 0;
int _productId;
// Read the license file key
if (ReadLicenseKeyFile(licenseFile, _licenseKey, _activationKey, _validationData)) {
try {
_licenseData = ansHelper.GetLicenseData(_licenseKey);
expirationDate = GetExpirationDate(_licenseData, _productId);
}
catch (std::exception& e) {
std::cerr << "An error occurred: " << e.what() << std::endl;
_productId = -1;
expirationDate = 0;
}
if (_productId > 0) {
switch (_productId) {
case ANSCENTER::ANSPRODUCTS::ANNHUB:
_productName = "ANNHUB";
break;
case ANSCENTER::ANSPRODUCTS::DLHUB:
_productName = "DLHUB";
break;
case ANSCENTER::ANSPRODUCTS::ODHUB:
_productName = "ODHUB";
break;
case ANSCENTER::ANSPRODUCTS::ANSVIS:
_productName = "ANSVIS";
break;
case ANSCENTER::ANSPRODUCTS::ANS_FACERECOGNIZE:
_productName = "ANSFR";
break;
case ANSCENTER::ANSPRODUCTS::ANS_OCR:
_productName = "ANSOCR";
break;
case ANSCENTER::ANSPRODUCTS::ANS_ALPR:
_productName = "ANSALPR";
break;
case ANSCENTER::ANSPRODUCTS::ANS_CV:
_productName = "ANSCV";
break;
case ANSCENTER::ANSPRODUCTS::ANS_TS:
_productName = "ANSTS";
break;
}
if (_productName == element) {
_registrationName = ANSUtility::DecodeBase64Utility(_validationData.c_str());// Decode
bool validLicenseKey = ansHelper.CheckLicenseKey(_licenseKey, _registrationName, _productId, _enableFeature);
ansLicenseInfo.productName = _productName;
ansLicenseInfo.licenseKey = _licenseKey;
ansLicenseInfo.activationKey = _activationKey;
ansLicenseInfo.hardwareId = hwid;
dataNode.put("product_name", _productName);
dataNode.put("license_key", _licenseKey);
dataNode.put("activation_key", _activationKey);
dataNode.put("hardware_id", hwid);
if (validLicenseKey) {
if (expirationDate > 0) {
ansLicenseInfo.licenseStatus = ANSCENTER::ANSLICENSESTATUS::ACTIVE;
dataNode.put("license_status", "active");
}
else {
ansLicenseInfo.licenseStatus = ANSCENTER::ANSLICENSESTATUS::EXPIRED;
dataNode.put("license_status", "expired");
}
ansLicenseInfo.remainingDays = expirationDate;
ansLicenseInfo.enableFeature = _enableFeature;
dataNode.put("remaining_days", expirationDate);
dataNode.put("enable_feature", _enableFeature);
children.push_back(std::make_pair("", dataNode));
}
else {
ansLicenseInfo.licenseStatus = ANSCENTER::ANSLICENSESTATUS::UNLICENSE;
dataNode.put("license_status", "unlicensed");
}
}
}
}
}
}
//2. Check if it is Unlicense then we will check for trial license key
if (ansLicenseInfo.licenseStatus == ANSCENTER::ANSLICENSESTATUS::UNLICENSE) {
std::string registrationName;
int productId;
if (ansLicenseInfo.productName == "ANNHUB") {
registrationName = "ANNHUB-LV";
productId = 1000;
}
else if (ansLicenseInfo.productName == "DLHUB") {
registrationName = "DLHUB-LV";
productId = 1001;
}
else if (ansLicenseInfo.productName == "ODHUB") {
registrationName = "ODHUB-LV";
productId = 1002;
}
else if (ansLicenseInfo.productName == "ANSVIS") {
registrationName = "ANSVIS";
productId = 1003;
}
else if (ansLicenseInfo.productName == "ANSFR") {
registrationName = "ANSFR";
productId = 1004;
}
else if (ansLicenseInfo.productName == "ANSOCR") {
registrationName = "ANSOCR";
productId = 1005;
}
else if (ansLicenseInfo.productName == "ANSALPR") {
registrationName = "ANSALPR";
productId = 1006;
}
else if (ansLicenseInfo.productName == "ANSCV") {
registrationName = "ANSCV";
productId = 1007;
}
else if (ansLicenseInfo.productName == "ANSTS") {
registrationName = "ANSTS";
productId = 1008;
}
else {
registrationName = ansLicenseInfo.productName;
productId = 1009;
}
dataNode.put("product_name", ansLicenseInfo.productName);
std::string trialLicenseKey = GetTrialLicenseKey(registrationName);
if (trialLicenseKey.empty()) {
ansLicenseInfo.licenseStatus = ANSCENTER::ANSLICENSESTATUS::UNLICENSE;
dataNode.put("license_key", "");
dataNode.put("activation_key", "");
dataNode.put("hardware_id", hwid);
dataNode.put("license_status", "unlicensed");
dataNode.put("remaining_days", 0);
dataNode.put("enable_feature", 0);
}
else {
ansLicenseInfo.licenseStatus = ANSCENTER::ANSLICENSESTATUS::TRIAL;
dataNode.put("license_key", trialLicenseKey);
dataNode.put("activation_key", "");
dataNode.put("hardware_id", hwid);
dataNode.put("license_status", "trial");
std::string licenseData = ansHelper.GetLicenseData(trialLicenseKey);
int expirationDate = GetExpirationDate(licenseData, productId);
dataNode.put("remaining_days", expirationDate);
dataNode.put("enable_feature", 0);
}
children.push_back(std::make_pair("", dataNode));
}
}
root.add_child("licenses", children);
std::ostringstream stream;
boost::property_tree::write_json(stream, root,false);
std::string st = stream.str();
return st;
}
catch (std::exception& e) {
std::cerr << "ANSUtilityHelper::ListLicenses. Error"<< e.what();
return "";
}
}
/************************ANSLSHelper Implementation************************************/
ANSLSHelper::ANSLSHelper()
{
try {
this->_privateKey = _T("AQlSAiRTNtS7X20=");
this->_licenseServiceURL = _T("https://licensingservice.anscenter.com/");
this->_sdkLicenseKey = _T("MYNSU-GBQ2Q-SF5U5-S3RVF-5ZKFD");
SDKRegistration::SetLicenseKey(_sdkLicenseKey.c_str());
this->SetupLicenseTemplate();
}
catch (ANSCENTER::Licensing::Exception* ex) {
ex->Destroy();
this->_logger.LogFatal("ANSLSHelper::ANSLSHelper", ex->GetExceptionMessage(), __FILE__, __LINE__);
}
}
ANSLSHelper::ANSLSHelper(std::string licenseServiceURL)
{
try {
this->_privateKey = _T("AQlSAiRTNtS7X20=");
this->_licenseServiceURL = String2WString(licenseServiceURL);
this->_sdkLicenseKey = _T("MYNSU-GBQ2Q-SF5U5-S3RVF-5ZKFD");
SDKRegistration::SetLicenseKey(_sdkLicenseKey.c_str());
this->SetupLicenseTemplate();
}
catch (ANSCENTER::Licensing::Exception* ex) {
ex->Destroy();
this->_logger.LogFatal("ANSLSHelper::ANSLSHelper", ex->GetExceptionMessage(), __FILE__, __LINE__);
}
}
ANSLSHelper::ANSLSHelper(std::string privateKey, std::string licenseServiceURL)
{
try {
if (privateKey.empty()) {
this->_privateKey = _T("AQlSAiRTNtS7X20=");
}
else {
this->_privateKey = String2WString(privateKey);
}
if (licenseServiceURL.empty()) {
this->_licenseServiceURL = _T("https://licensingservice.anscenter.com/");
}
this->_licenseServiceURL = String2WString(licenseServiceURL);
this->_sdkLicenseKey = _T("MYNSU-GBQ2Q-SF5U5-S3RVF-5ZKFD");
SDKRegistration::SetLicenseKey(_sdkLicenseKey.c_str());
this->SetupLicenseTemplate();
}
catch (ANSCENTER::Licensing::Exception* ex) {
ex->Destroy();
this->_logger.LogFatal("ANSLSHelper::ANSLSHelper", ex->GetExceptionMessage(), __FILE__, __LINE__);
}
}
ANSLSHelper::ANSLSHelper(std::string privateKey, std::string publicKey, std::string licenseServiceURL)
{
try {
if (privateKey.empty()) {
this->_privateKey = _T("AQlSAiRTNtS7X20=");
}
else {
this->_privateKey = String2WString(privateKey);
}
if (publicKey.empty()) {
this->_publicKey = _T("EKJWDQEL3KQvCPLEjz0fjQiSAF1qChm65z6/PaZISNtL1wib6QA=");
}
else {
this->_publicKey = String2WString(publicKey);
}
if (licenseServiceURL.empty()) {
this->_licenseServiceURL = _T("https://licensingservice.anscenter.com/");
}
this->_licenseServiceURL = String2WString(licenseServiceURL);
this->_sdkLicenseKey = _T("MYNSU-GBQ2Q-SF5U5-S3RVF-5ZKFD");
SDKRegistration::SetLicenseKey(_sdkLicenseKey.c_str());
this->SetupLicenseTemplate();
}
catch (ANSCENTER::Licensing::Exception* ex) {
ex->Destroy();
this->_logger.LogFatal("ANSLSHelper::ANSLSHelper", ex->GetExceptionMessage(), __FILE__, __LINE__);
}
}
ANSLSHelper::~ANSLSHelper() {
try {
if (this->_license != NULL) {
//delete _license; // Do not know why it does not work
this->_license = NULL;
}
if (this->_licenseTemplate != NULL) {
LicenseTemplate::Destroy(_licenseTemplate);
this->_licenseTemplate = NULL;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
ex->Destroy();
this->_logger.LogFatal("ANSLSHelper::~ANSLSHelper", ex->GetExceptionMessage(), __FILE__, __LINE__);
}
}
void ANSLSHelper::SetLicenseServiceURL(std::string licenseServiceURL) {
this->_licenseServiceURL = String2WString(licenseServiceURL);
}
void ANSLSHelper::LoadLicense(std::string licenseKey) {
if (!this->_license != NULL) delete this->_license;
this->_license = new License();
std::string licenseFileName = Dash2Underscore(licenseKey)+".json";
std::string licenseFolder = GetLicenseDir();
std::string licenseFilePath = CreateFilePath(licenseFolder, licenseFileName);
this->_licenseFilePath = String2WString(licenseFilePath);
try {
if (LoadLicenseContent().empty())
{
delete this->_license;
this->_license = NULL;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
ex->Destroy();
this->_logger.LogFatal("ANSLSHelper::LoadLicense", ex->GetExceptionMessage(), __FILE__, __LINE__);
delete this->_license;
this->_license = NULL;
}
}
std::string ANSLSHelper::SaveLicense() {
if (this->_license != NULL) {
try {
FILE* licenseFile;
const char* jsonLicense = this->_license->SaveJson();
std::string result(jsonLicense);
if (!result.empty()) {
if ((licenseFile = _tfopen(WString2String(_licenseFilePath).c_str(), "wt")) != NULL) {
fputs(jsonLicense, licenseFile);
fclose(licenseFile);
}
}
else {
this->_logger.LogError("ANSLSHelper::SaveLicense", "XML content is empty", __FILE__, __LINE__);
}
return result;
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::SaveLicense", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return "";
}
}
else {
this->_logger.LogError("ANSLSHelper::SaveLicense", "License object is NULL. Cannot save license content", __FILE__, __LINE__);
return "";
}
}
std::string ANSLSHelper::LoadLicenseContent() {
try
{
std::string jsonContent = ReadFileContent(WString2String(_licenseFilePath));
if (!jsonContent.empty()) {
this->_license->LoadJson(jsonContent.c_str());
return jsonContent;
}
else {
this->_logger.LogDebug("ANSLSHelper::LoadLicenseContent", "Json file content is empty", __FILE__, __LINE__);
this->_license = NULL;
return "";
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::LoadLicenseContent", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
this->_license = NULL;
return "";
}
}
std::string ANSLSHelper::GetCurrentHardwareId() {
try {
const wchar_t* hwid = KeyHelper::GetCurrentHardwareId();
std::wstring result_t = std::wstring(hwid);
std::string result = WString2String(result_t);
return result;
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::GetCurrentHardwareId", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return "";
}
}
bool ANSLSHelper::MatchCurrentHardwareId(std::string hwid) {
try {
std::wstring wHwid = String2WString(hwid);
return KeyHelper::MatchCurrentHardwareId(wHwid.c_str());
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::MatchCurrentHardwareId", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return false;
}
}
bool ANSLSHelper::DectectClockmanipulation(int year, int month, int date) {
try {
return KeyHelper::DetectClockManipulation(year, month, date);
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::DectectClockmanipulation", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return true;
}
}
bool ANSLSHelper::LoadLicenseTemplate(std::string templateFilePath) {
try {
if (FileExist(templateFilePath)) {
if (this->_licenseTemplate) LicenseTemplate::Destroy(this->_licenseTemplate);
this->_licenseTemplate = LicenseTemplate::Create();
std::string result = ReadFileContent(templateFilePath);
std::string lowercaseExtension = GetFileExtension(templateFilePath);
// The private key and public key can be found in the license template file already. It should not be overloaded in here.
if (lowercaseExtension == "json") {
this->_licenseTemplate->LoadJson(result.c_str());
this->_licenseTemplate->SetLicensingServiceUrl(this->_licenseServiceURL.c_str());
const wchar_t* cpKey = this->_licenseTemplate->GetPrivateKey();
std::wstring wpKey(cpKey);
if (!wpKey.empty()) this->_privateKey = wpKey;
return true;
}
else { // Otherwise it will be xml
this->_licenseTemplate->LoadXml(result.c_str());
this->_licenseTemplate->SetLicensingServiceUrl(this->_licenseServiceURL.c_str());
const wchar_t* cpKey = this->_licenseTemplate->GetPrivateKey();
std::wstring wpKey(cpKey);
if (!wpKey.empty()) this->_privateKey = wpKey;
return true;
}
}
else {
this->_logger.LogError("ANSLSHelper::LoadLicenseTemplate", "License template file is not exist or invalid", __FILE__, __LINE__);
return false;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::LoadLicenseTemplate", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return false;
}
}
std::string ANSLSHelper::SaveLicenseTemplate(std::string templateFilePath, bool savePrivateKey = false) {
try {
if (this->_licenseTemplate != NULL) {
if (FileExist(templateFilePath)) {
std::string lowercaseExtension = GetFileExtension(templateFilePath);
if (lowercaseExtension == "json") {
const char* licenseTemplateContent = this->_licenseTemplate->SaveJson(savePrivateKey);
std::string result(licenseTemplateContent);
return licenseTemplateContent;
}
else { // Otherwise it will be xml
const char* licenseTemplateContent = this->_licenseTemplate->SaveXml(savePrivateKey);
std::string result(licenseTemplateContent);
return licenseTemplateContent;
}
}
else {
this->_logger.LogError("ANSLSHelper::LoadLicenseTemplate", "License template file is not exist or invalid", __FILE__, __LINE__);
return "";
}
}
else {
this->_logger.LogError("ANSLSHelper::SaveLicenseTemplate", "this->_licenseTemplate is NULL", __FILE__, __LINE__);
return "";
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::SaveLicenseTemplate", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return "";
}
}
void ANSLSHelper::SetupLicenseTemplate() {
try {
if (this->_licenseTemplate) LicenseTemplate::Destroy(this->_licenseTemplate);
this->_licenseTemplate = LicenseTemplate::Create();
if (this->_licenseServiceURL.empty()) {
_licenseTemplate->SetLicensingServiceUrl(_T("https://licensingservice.anscenter.com/"));
}
else {
this->_licenseTemplate->SetLicensingServiceUrl(this->_licenseServiceURL.c_str());
}
this->_licenseTemplate->SetNumberOfGroups(6); // characters per group
this->_licenseTemplate->SetCharactersPerGroup(5); // bits per character
this->_licenseTemplate->SetEncoding(ENCODING_BASE32X);
this->_licenseTemplate->SetGroupSeparator(_T("-"));
this->_licenseTemplate->SetDataSize(36); //16 bits for ProductId, 4 bits for FeatureBitMask, and 16 bits for ExpirationData (16+4+16 =36)
this->_licenseTemplate->SetTemplateId(_T("24880"));
if(this->_privateKey.empty())
this->_licenseTemplate->SetPrivateKey(_T("AQlSAiRTNtS7X20="));
else this->_licenseTemplate->SetPrivateKey(this->_privateKey.c_str());
if (this->_publicKey.empty())
this->_licenseTemplate->SetPublicKeyCertificate(_T("EKJWDQEL3KQvCPLEjz0fjQiSAF1qChm65z6/PaZISNtL1wib6QA="));
else this->_licenseTemplate->SetPublicKeyCertificate(this->_publicKey.c_str());
this->_licenseTemplate->SetSignatureSize(114); // 114 bits = ((characters per group * number of groups) * bits per character) - data size ; ((6 * 5) * 5) - (36) =150 -36 =114
this->_licenseTemplate->AddDataField(_T("ProductId"), FIELD_TYPE_INTEGER, 16, 0);
this->_licenseTemplate->AddDataField(_T("FeatureBitMask"),FIELD_TYPE_INTEGER,4,16);
this->_licenseTemplate->AddDataField(_T("ExpirationDate"),FIELD_TYPE_DATE16,16,20);
this->_licenseTemplate->AddValidationField(_T("RegistrationName"), FIELD_TYPE_STRING, MAX_CUSTOMER_NAME_LEN * 8, 0);
this->_licenseTemplate->SetValidationDataSize(MAX_CUSTOMER_NAME_LEN * 8);
this->_licenseTemplate->SetProperty(_T("/Trial/TrialLicenseKey"), NULL, _T("3YASV-BZNTJ-7CC3G-R9J9G-WEJTM-EAAAA"));
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::SetUpLicenseTemplate", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
}
}
// It is very simple form of license template. Just ProductId and the key as XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
void ANSLSHelper::Setup5x5LicenseTemplate() {
try {
if (this->_licenseTemplate) LicenseTemplate::Destroy(this->_licenseTemplate);
this->_licenseTemplate = LicenseTemplate::Create();
_licenseTemplate->SetLicensingServiceUrl(_T("https://licensingservice.anscenter.com/"));
_licenseTemplate->SetTemplateId(_T("12345"));// Simple test template
// Setup the license key appearance as XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
_licenseTemplate->SetCharactersPerGroup(5);
_licenseTemplate->SetNumberOfGroups(5);
_licenseTemplate->SetGroupSeparator(_T("-"));
_licenseTemplate->SetEncoding(ENCODING_BASE32X);
// From the license key's 5 * 5 * 5 = 125 bits, 109 are the digital signature and 16 bits are data
_licenseTemplate->SetSignatureSize(109);
_licenseTemplate->SetDataSize(16);
_licenseTemplate->SetPrivateKey(_T("AQnD07PnEw7CRi8="));
_licenseTemplate->SetPublicKeyCertificate(_T("AI0bDQELdoxzyMNu7n46whOSAEon0PzzErF7AiD1r/HhLy4U1wA="));
// Now split the 16 data bits into a single field containing a product id number
_licenseTemplate->AddDataField(_T("ProductId"), FIELD_TYPE_INTEGER, 16, 0);
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::Setup5x5LicenseTemplate", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
}
}
std::string ANSLSHelper::GenerateKey(int productId, std::string registrationName, int productFeature, bool trialLicense) {
try {
std::wstring _registrationName = String2WString(registrationName);
this->_licenseTemplate->SetPrivateKey(_privateKey.c_str()); // Only use _private key when we intend to generate a new SN
KeyGenerator keyGen;
keyGen.SetKeyTemplate(this->_licenseTemplate);
// from the same company
keyGen.SetKeyData(_T("ProductId"), productId);
// mark some of the features as enabled
if (!registrationName.empty()) keyGen.SetValidationData(_T("RegistrationName"), _registrationName.c_str());
if (productFeature > 0) keyGen.SetKeyData(_T("FeatureBitMask"), productFeature);
try {
boost::posix_time::ptime timeLocal = boost::posix_time::second_clock::local_time();
int currentYear = timeLocal.date().year();
int currentMonth = timeLocal.date().month();
int currentDate = timeLocal.date().day();
std::string logMessage = str(boost::format("Current date: %1%-%2%-%3% ") % currentDate % currentMonth % currentYear);
_logger.LogDebug("ANSLSHelper::GenerateKey", logMessage, __FILE__, __LINE__);
if (trialLicense) {// Add 3 months
currentMonth= currentMonth+3;
keyGen.SetKeyData(_T("FeatureBitMask"), 0);// We know it is the trial key
if (currentMonth > 12) {
currentMonth = currentMonth-12;
if (currentMonth < 1) currentMonth = 1;
currentYear++;
}
keyGen.SetKeyData(_T("ExpirationDate"), currentYear, currentMonth, currentDate);
}
else {// Add 50 years
try {
int expriredYear = currentYear + 50;
keyGen.SetKeyData(_T("ExpirationDate"), expriredYear, currentMonth, currentDate);
}
catch (ANSCENTER::Licensing::Exception* ex){
keyGen.SetKeyData(_T("ExpirationDate"), 2041, currentMonth, currentDate);
ex->Destroy();
}
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::GenerateKey", "This license template does not support expiration data", __FILE__, __LINE__);
this->_logger.LogWarn("ANSLSHelper::GenerateKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
}
const wchar_t* licenseKey = keyGen.GenerateKey();
std::wstring wresult(licenseKey);
std::string result = WString2String(wresult);
return result;
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::GenerateKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return "";
}
}
std::string ANSLSHelper::GenerateKey(int productId, std::string registrationName, int productFeature, int expiredYear, int expiredMonth, int expiredDate) {
try {
std::wstring _registrationName = String2WString(registrationName);
this->_licenseTemplate->SetPrivateKey(_privateKey.c_str()); // Only use _private key when we intend to generate a new SN
KeyGenerator keyGen;
keyGen.SetKeyTemplate(this->_licenseTemplate);
// from the same company
keyGen.SetKeyData(_T("ProductId"), productId);
// mark some of the features as enabled
if (!registrationName.empty()) keyGen.SetValidationData(_T("RegistrationName"), _registrationName.c_str());
if (productFeature > 0) keyGen.SetKeyData(_T("FeatureBitMask"), productFeature);
try {
try {
keyGen.SetKeyData(_T("ExpirationDate"), expiredYear, expiredMonth, expiredDate);
}
catch (ANSCENTER::Licensing::Exception* ex) {
keyGen.SetKeyData(_T("ExpirationDate"), 2041, 1, 1);
ex->Destroy();
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
//this->_logger.LogWarn("ANSLSHelper::GenerateKey", "This license template does not support expiration data", __FILE__, __LINE__);
this->_logger.LogWarn("ANSLSHelper::GenerateKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
}
const wchar_t* licenseKey = keyGen.GenerateKey();
std::wstring wresult(licenseKey);
std::string result = WString2String(wresult);
return result;
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::GenerateKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return "";
}
}
bool ANSLSHelper::CheckLicenseKey(std::string licenseKey, std::string registrationName, int productId, int& enableFeatures) {
try {
bool isValid = false;
LoadLicense(licenseKey);
std::wstring _registrationName = String2WString(registrationName);
std::wstring _licenseKey = String2WString(licenseKey);
KeyValidator keyValidator(this->_licenseTemplate);
keyValidator.SetKey(_licenseKey.c_str());
if (!registrationName.empty())
keyValidator.SetValidationData(_T("RegistrationName"), _registrationName.c_str());
if (!keyValidator.IsKeyValid())
{
this->_logger.LogError("ANSLSHelper::CheckLicenseKey", "Invalid license key", __FILE__, __LINE__);
return isValid;
}
// Validate expiration date first
try {
boost::posix_time::ptime timeLocal = boost::posix_time::second_clock::local_time();
unsigned short currentYear = timeLocal.date().year();
unsigned short currentMonth = timeLocal.date().month();
unsigned short currentDay = timeLocal.date().day();
int expiredYear, expiredMonth, expiredDay;
bool validExpiration = false;
keyValidator.QueryDateKeyData(_T("ExpirationDate"), &expiredYear, &expiredMonth, &expiredDay);
boost::gregorian::date currentDate{ currentYear, currentMonth, currentDay };
boost::gregorian::date expiredDate{ (unsigned short)expiredYear, (unsigned short)expiredMonth, (unsigned short)expiredDay };
boost::gregorian::date_duration validDuration = expiredDate - currentDate;
if (validDuration.days() >= 0) {
// Check if clock is manipulated
bool changeClock = DectectClockmanipulation(expiredYear, expiredMonth, expiredDay);
if (changeClock)
{
validExpiration = false;
this->_logger.LogError("ANSLSHelper::CheckLicenseKey", "License expired. Please renew license.", __FILE__, __LINE__);
}
else {
validExpiration = true;
}
}
if (!validExpiration) {
this->_logger.LogError("ANSLSHelper::CheckLicenseKey", "License is expired", __FILE__, __LINE__);
isValid = false;
return isValid;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogError("ANSLSHelper::CheckLicenseKey", "Expiration data is not supported.", __FILE__, __LINE__);
ex->Destroy();
}
// Then validate the product Id
int validatedProductId = 0;
int len = sizeof(validatedProductId);
keyValidator.QueryKeyData(_T("ProductId"), &validatedProductId, &len);
bool validProductId = false;
if (validatedProductId == productId)validProductId = true;
if (!validProductId) {
this->_logger.LogError("ANSLSHelper::CheckLicenseKey", "Invalid Product", __FILE__, __LINE__);
isValid = false;
return isValid; // invalid LicenseKeyStatus
}
// finally validate features
try {
int validatedEnabledFeatures = keyValidator.QueryIntKeyData(_T("FeatureBitMask"));
enableFeatures = validatedEnabledFeatures;
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::CheckLicenseKey", "Feature field are not supported.", __FILE__, __LINE__);
enableFeatures = 0;
ex->Destroy();
}
isValid = true;
return isValid; //
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::CheckLicenseKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return false;
}
}
bool ANSLSHelper::IsLicenseKeyValid(std::string licenseKey, std::string registrationName){
try {
bool isValid = false;
LoadLicense(licenseKey);
std::wstring _registrationName;
if (!registrationName.empty()) {
_registrationName = String2WString(registrationName);
}
else {
_registrationName = _T("");
}
std::wstring _licenseKey = String2WString(licenseKey);
KeyValidator keyValidator(this->_licenseTemplate);
keyValidator.SetKey(_licenseKey.c_str());
if (!_registrationName.empty())
keyValidator.SetValidationData(_T("RegistrationName"), _registrationName.c_str());
if (!keyValidator.IsKeyValid())
{
this->_logger.LogError("ANSLSHelper::IsLicenseKeyValid", "Invalid license key", __FILE__, __LINE__);
return isValid;
}
// Validate expiration date first
try {
boost::posix_time::ptime timeLocal = boost::posix_time::second_clock::local_time();
unsigned short currentYear = timeLocal.date().year();
unsigned short currentMonth = timeLocal.date().month();
unsigned short currentDay = timeLocal.date().day();
int expiredYear, expiredMonth, expiredDay;
bool validExpiration = false;
keyValidator.QueryDateKeyData(_T("ExpirationDate"), &expiredYear, &expiredMonth, &expiredDay);
boost::gregorian::date currentDate{ currentYear, currentMonth, currentDay };
boost::gregorian::date expiredDate{ (unsigned short)expiredYear, (unsigned short)expiredMonth, (unsigned short)expiredDay };
boost::gregorian::date_duration validDuration = expiredDate - currentDate;
if (validDuration.days() >= 0) {
// Check if clock is manipulated
bool changeClock = DectectClockmanipulation(expiredYear, expiredMonth, expiredDay);
if (changeClock)
{
validExpiration = false;
this->_logger.LogError("ANSLSHelper::IsLicenseKeyValid", "License expired. Please renew license.", __FILE__, __LINE__);
}
else {
validExpiration = true;
this->_logger.LogDebug("ANSLSHelper::IsLicenseKeyValid", "Validation Successfully.", __FILE__, __LINE__);
}
}
if (!validExpiration) {
this->_logger.LogError("ANSLSHelper::IsLicenseKeyValid", "License is expired", __FILE__, __LINE__);
isValid = false;
return isValid;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::IsLicenseKeyValid", "Expiration data is not supported.", __FILE__, __LINE__);
ex->Destroy();
}
isValid = true;
this->_logger.LogDebug("ANSLSHelper::IsLicenseKeyValid", "License key is valid.", __FILE__, __LINE__);
return isValid; //
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::IsLicenseKeyValid", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return false;
}
}
std::wstring ANSLSHelper::GetProductId(std::string licenseKey) {
try {
std::wstring _licenseKey = String2WString(licenseKey);
KeyValidator keyValidator(this->_licenseTemplate);
keyValidator.SetKey(_licenseKey.c_str());
int validatedProductId = 0;
int len = sizeof(validatedProductId);
try {
keyValidator.QueryKeyData(_T("ProductId"), &validatedProductId, &len);
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::GetLicenseData", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
}
std::string sProductId = std::to_string(validatedProductId);
std::wstring wProductId = String2WString(sProductId);
return wProductId;
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::GetProductId", "License key is invalid", __FILE__, __LINE__);
ex->Destroy();
std::string sProductId = "0";
std::wstring wProductId = String2WString(sProductId);
return wProductId;
}
}
std::string ANSLSHelper::GetLicenseData(std::string licenseKey) {
std::wstring _licenseKey = String2WString(licenseKey);
std::wstring wProductId = GetProductId(licenseKey);
this->_licenseTemplate->SetTemplateId(wProductId.c_str());
boost::property_tree::ptree root;
boost::property_tree::ptree dataNode;
KeyValidator keyValidator(this->_licenseTemplate);
try {
keyValidator.SetKey(_licenseKey.c_str());
try {
int validatedProductId = 0;
int validatedProductIdLen = sizeof(validatedProductId);
keyValidator.QueryKeyData(_T("ProductId"), &validatedProductId, &validatedProductIdLen);
dataNode.put("valid_product_id", validatedProductId);
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::GetLicenseData", "ProductId data is not available.", __FILE__, __LINE__);
dataNode.put("valid_product_id", 0);
ex->Destroy();
}
try {
int expiredYear, expiredMonth, expiredDay;
keyValidator.QueryDateKeyData(_T("ExpirationDate"), &expiredYear, &expiredMonth, &expiredDay);
if ((expiredYear > 0) && (expiredMonth > 0) && (expiredDay > 0)) {
boost::posix_time::ptime timeLocal = boost::posix_time::second_clock::local_time();
unsigned short currentYear = timeLocal.date().year();
unsigned short currentMonth = timeLocal.date().month();
unsigned short currentDay = timeLocal.date().day();
boost::gregorian::date currentDate{ currentYear, currentMonth, currentDay };
boost::gregorian::date expiredDate{ (unsigned short)expiredYear, (unsigned short)expiredMonth, (unsigned short)expiredDay };
boost::gregorian::date_duration validDuration = expiredDate - currentDate;
dataNode.put("remaining_days", validDuration.days());
}
else {
dataNode.put("remaining_days", 0);
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::GetLicenseData", "Expired date data is not available.", __FILE__, __LINE__);
dataNode.put("remaining_days", 0);
ex->Destroy();
}
try {
int validatedEnabledFeatures = keyValidator.QueryIntKeyData(_T("FeatureBitMask"));
dataNode.put("enabled_features", validatedEnabledFeatures);
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::GetLicenseData", "Enabled features data is not available.", __FILE__, __LINE__);
dataNode.put("enabled_features", 0);
ex->Destroy();
}
try {
int validationDataLen = MAX_CUSTOMER_NAME_LEN;
unsigned char validationData[MAX_CUSTOMER_NAME_LEN] = "";
const char* emptyString = "";
keyValidator.QueryValidationData(NULL, validationData, &validationDataLen);
int comparisonResult = std::strcmp(reinterpret_cast<const char*>(validationData), emptyString);
if (comparisonResult != 0) dataNode.put("validation_data", validationData);
else dataNode.put("validation_data", "");
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::GetLicenseData", "validation data is not available.", __FILE__, __LINE__);
dataNode.put("validation_data", "");
ex->Destroy();
}
root.add_child("licenseData", dataNode);
std::ostringstream stream;
boost::property_tree::write_json(stream, root,false);
std::string st = stream.str();
return st;
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::GetLicenseData", "validation data is not available.", __FILE__, __LINE__);
dataNode.put("validation_data", "");
ex->Destroy();
root.add_child("licenseData", dataNode);
std::ostringstream stream;
boost::property_tree::write_json(stream, root,false);
std::string st = stream.str();
return st;
}
}
int ANSLSHelper::GenerateOfflineActivationData(std::string licenseKey, std::string registrationName, std::string& offlineActivationData) {
try {
std::wstring wHardwareId = KeyHelper::GetCurrentHardwareId();
std::string hardwareId = WString2String(wHardwareId);
std::wstring _licenseKey = String2WString(licenseKey);
std::wstring _registrationName = String2WString(registrationName);
std::wstring wProductId = GetProductId(licenseKey);
std::string _productId = WString2String(wProductId);
this->_licenseTemplate->SetTemplateId(wProductId.c_str());
KeyValidator keyValidator(this->_licenseTemplate);
keyValidator.SetKey(_licenseKey.c_str());
if (!registrationName.empty())
keyValidator.SetValidationData(_T("RegistrationName"), _registrationName.c_str());
if (!keyValidator.IsKeyValid())
{
this->_logger.LogError("ANSLSHelper::InstallOfflineLicense", "Invalid license key", __FILE__, __LINE__);
return 0; // invalid
}
// We also need to verify if the activation key valid or not.
int validationDataLen = MAX_CUSTOMER_NAME_LEN;
unsigned char validationData[MAX_CUSTOMER_NAME_LEN] = "";
keyValidator.QueryValidationData(NULL, validationData, &validationDataLen);
std::string licenseKeyValidationData = ANSUtility::EncodeBase64Utility(validationData, validationDataLen,true);
boost::property_tree::ptree root;
boost::property_tree::ptree dataNode;
dataNode.put("license_key", licenseKey);
dataNode.put("hardware_id", hardwareId);
dataNode.put("license_key_validation_data", licenseKeyValidationData);
dataNode.put("product_id", _productId);
root.add_child("offlineActivationData", dataNode);
std::ostringstream stream;
boost::property_tree::write_json(stream, root,false);
std::string st = stream.str();
offlineActivationData = st;
return 1;
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::GenerateOfflineActivationData", ex->GetExceptionMessage(), __FILE__, __LINE__);
return 0;
}
}
int ANSLSHelper::ValidateLicense(std::string licenseKey, std::string registrationName, std::string& activationKey) {
LicenseKeyStatus _licenseKeyStatus;
LoadLicense(licenseKey);
std::wstring _licenseKey = String2WString(licenseKey);
std::wstring _activationKey = String2WString(activationKey);
std::wstring _registrationName = String2WString(registrationName);
std::wstring hardwareId = KeyHelper::GetCurrentHardwareId();
std::string _hardwareId = WString2String(hardwareId);
bool _overrideLicenseFile = false;
if (activationKey.empty()) {
if (this->_license != NULL) {// get it from there
const wchar_t* cAKey = _license->GetActivationKey();
std::wstring wAKey(cAKey);
_activationKey = wAKey;
}
}
std::wstring wProductId = GetProductId(licenseKey);
this->_licenseTemplate->SetTemplateId(wProductId.c_str());
KeyValidator keyValidator(this->_licenseTemplate);
try {
keyValidator.SetKey(_licenseKey.c_str());
if (!registrationName.empty())
keyValidator.SetValidationData(_T("RegistrationName"), _registrationName.c_str());
if (!keyValidator.IsKeyValid())
{
_licenseKeyStatus = INVALID_LICENSE_KEY;
this->_logger.LogError("ANSLSHelper::ValidateLicenseKey", "Invalid license key", __FILE__, __LINE__);
activationKey = "";
return _licenseKeyStatus; // invalid
}
int validationDataLen = MAX_CUSTOMER_NAME_LEN;
unsigned char validationData[MAX_CUSTOMER_NAME_LEN] = "";
keyValidator.QueryValidationData(NULL, validationData, &validationDataLen);
const char* emptyString = "";
LicensingClient licensingClient;
// SetLicenseKeyValidationData needs to be called before SetActivationKeyTemplate !
int comparisonResult = std::strcmp(reinterpret_cast<const char*>(validationData), emptyString);
if (comparisonResult != 0)
licensingClient.SetLicenseKeyValidationData(validationData, validationDataLen);
licensingClient.SetLicenseTemplate(this->_licenseTemplate);
licensingClient.SetLicenseKey(_licenseKey.c_str());
licensingClient.SetHardwareId(hardwareId.c_str());
licensingClient.SetActivationKey(_activationKey.c_str());
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey. Hardware Id", mask_secret(_hardwareId), __FILE__, __LINE__);
bool validLicense = licensingClient.IsLicenseValid();
if (!validLicense)
{
try
{
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Product needs to be activated. Requesting license activation from server...", __FILE__, __LINE__);
licensingClient.SetLicensingServiceUrl(this->_licenseServiceURL.c_str());
licensingClient.SetLicenseTemplate(this->_licenseTemplate);
licensingClient.AcquireLicense();
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Done.", __FILE__, __LINE__);
_overrideLicenseFile = true;
}
catch (Exception* ex)
{
this->_logger.LogFatal("ANSLSHelper::ValidateLicenseKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
}
catch (...)
{
this->_logger.LogFatal("ANSLSHelper::ValidateLicenseKey", "Unknown exception during activation attempt !", __FILE__, __LINE__);
}
if (!licensingClient.IsLicenseValid())
{
int activationStatus = licensingClient.GetLicenseActivationStatus();
std::string activationStatusStr;
switch (activationStatus)
{
case STATUS_INVALID_ACTIVATION_KEY:
_licenseKeyStatus = INVALID_ACTIVATION_KEY;
activationStatusStr = "Activation key is invalid";
break;
case STATUS_INVALID_HARDWARE_ID:
_licenseKeyStatus = INVALID_HARDWARE_ID;
activationStatusStr = "Hardware id does not match this computer. current HWID is " + _hardwareId +
"; client HWID is " + WString2String(licensingClient.GetHardwareId()) +
"; Current activation key is " + WString2String(_activationKey) +
"; client Activation key is " + WString2String(licensingClient.GetActivationKey()) +
"; URL is " + WString2String(this->_licenseServiceURL.c_str())+
"; ProductId is " + WString2String(wProductId) +
"; RegistrationName is " + WString2String(_registrationName) +
"; Status is" + std::to_string(activationStatus);
break;
case STATUS_LICENSE_EXPIRED:
_licenseKeyStatus = LICENSE_EXPIRED;
activationStatusStr = "License expired";
break;
default:
_licenseKeyStatus = UNKNOWN;
activationStatusStr = "Failed to activate license. Unknown issue.";
break;
}
this->_logger.LogError("ANSLSHelper::ValidateLicenseKey", activationStatusStr, __FILE__, __LINE__);
activationKey = "";
return _licenseKeyStatus;
}
else // License is now valid, we need to check if
{
int expiredYear, expiredMonth, expiredDay;
try {
keyValidator.QueryDateKeyData(_T("ExpirationDate"), &expiredYear, &expiredMonth, &expiredDay);
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::ValidateLicenseKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
licensingClient.GetLicenseExpirationDate(&expiredYear, &expiredMonth, &expiredDay);
}
if (expiredYear > 0) {
boost::posix_time::ptime timeLocal = boost::posix_time::second_clock::local_time();
unsigned short currentYear = timeLocal.date().year();
unsigned short currentMonth = timeLocal.date().month();
unsigned short currentDay = timeLocal.date().day();
boost::gregorian::date currentDate{ currentYear, currentMonth, currentDay };
boost::gregorian::date expiredDate{ (unsigned short)expiredYear, (unsigned short)expiredMonth, (unsigned short)expiredDay };
boost::gregorian::date_duration validDuration = expiredDate - currentDate;
bool changeClock = DectectClockmanipulation(expiredYear, expiredMonth, expiredDay);
if (changeClock) {
_licenseKeyStatus = LICENSE_EXPIRED;
}
else {
_licenseKeyStatus = SUCCESS;
}
std::string loggerExpiredMessage = str(boost::format("License Expiration Days: %1%") % validDuration.days());
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", loggerExpiredMessage, __FILE__, __LINE__);
}
else {
_licenseKeyStatus = SUCCESS;
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "License Expiration Date: Never", __FILE__, __LINE__);
}
// Do we need to check license (ProductId, RegistrationName, and features?) No need
// Save license
if (_licenseKeyStatus == SUCCESS) {
const wchar_t* wcActivationKey = licensingClient.GetActivationKey();
std::wstring wActivationKey(wcActivationKey);
std::string sActivationKey = WString2String(wActivationKey);
const wchar_t* hardwareId = licensingClient.GetHardwareId();
std::wstring wHardwareId(hardwareId);
std::string sHardwareId = WString2String(wHardwareId);
std::string loggerActivationMessage = str(boost::format("Activation Successful. The returned activation key: %1%") % mask_secret(sActivationKey));
std::string loggerHWIDMessage = str(boost::format("Computer's hardware id: %1%") % mask_secret(sHardwareId));
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Product is activated", __FILE__, __LINE__);
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", loggerActivationMessage, __FILE__, __LINE__);
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", loggerHWIDMessage, __FILE__, __LINE__);
const wchar_t* actKey = licensingClient.GetActivationKey();
std::wstring wact(actKey);
activationKey = WString2String(wact);
if (_overrideLicenseFile) {
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Override license key.", __FILE__, __LINE__);
if (!this->_license != NULL) delete this->_license;
this->_license = new License();
this->_license->SetLicenseKey(_licenseKey.c_str());
this->_license->SetLicenseKeyValidationData(validationData, validationDataLen);
this->_license->SetHardwareId(licensingClient.GetCurrentHardwareId());
this->_license->SetActivationKey(actKey);
SaveLicense();
}
}
else {
this->_logger.LogError("ANSLSHelper::ValidateLicenseKey", "License expired. Please renew license.", __FILE__, __LINE__);
}
return _licenseKeyStatus;
}
}
else //License is already valid. No need to do anything
{
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Product is activated", __FILE__, __LINE__);
_licenseKeyStatus = SUCCESS;
const wchar_t* actKey = licensingClient.GetActivationKey();
std::wstring wact(actKey);
activationKey = WString2String(wact);
if (_overrideLicenseFile) {
// Save license
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Override license key.", __FILE__, __LINE__);
if (!this->_license != NULL) delete this->_license;
this->_license = new License();
this->_license->SetLicenseKey(_licenseKey.c_str());
this->_license->SetLicenseKeyValidationData(validationData, validationDataLen);
this->_license->SetHardwareId(licensingClient.GetCurrentHardwareId());
this->_license->SetActivationKey(actKey);
SaveLicense();
}
return _licenseKeyStatus;
}
}
catch (Exception* ex)
{
this->_logger.LogFatal("ANSLSHelper::ValidateLicenseKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
_licenseKeyStatus = INVALID_LICENSE_KEY;
return _licenseKeyStatus;
}
}
int ANSLSHelper::ValidateLicenseWithCustomHWID(std::string licenseKey, std::string registrationName, std::string customHWID, std::string& activationKey) {
LicenseKeyStatus _licenseKeyStatus;
LoadLicense(licenseKey);
std::wstring _licenseKey = String2WString(licenseKey);
std::wstring _activationKey = String2WString(activationKey);
std::wstring _registrationName = String2WString(registrationName);
std::string _hardwareId = customHWID;
std::wstring hardwareId = String2WString(customHWID);
bool _overrideLicenseFile = false;
if (activationKey.empty()) {
if (this->_license != NULL) {// get it from there
const wchar_t* cAKey = _license->GetActivationKey();
std::wstring wAKey(cAKey);
_activationKey = wAKey;
}
}
std::wstring wProductId = GetProductId(licenseKey);
this->_licenseTemplate->SetTemplateId(wProductId.c_str());
KeyValidator keyValidator(this->_licenseTemplate);
try {
keyValidator.SetKey(_licenseKey.c_str());
if (!registrationName.empty())
keyValidator.SetValidationData(_T("RegistrationName"), _registrationName.c_str());
if (!keyValidator.IsKeyValid())
{
_licenseKeyStatus = INVALID_LICENSE_KEY;
this->_logger.LogError("ANSLSHelper::ValidateLicenseKey", "Invalid license key", __FILE__, __LINE__);
activationKey = "";
return _licenseKeyStatus; // invalid
}
int validationDataLen = MAX_CUSTOMER_NAME_LEN;
unsigned char validationData[MAX_CUSTOMER_NAME_LEN] = "";
keyValidator.QueryValidationData(NULL, validationData, &validationDataLen);
const char* emptyString = "";
LicensingClient licensingClient;
// SetLicenseKeyValidationData needs to be called before SetActivationKeyTemplate !
int comparisonResult = std::strcmp(reinterpret_cast<const char*>(validationData), emptyString);
if (comparisonResult != 0)
licensingClient.SetLicenseKeyValidationData(validationData, validationDataLen);
licensingClient.SetLicenseTemplate(this->_licenseTemplate);
licensingClient.SetLicenseKey(_licenseKey.c_str());
licensingClient.SetHardwareId(hardwareId.c_str());
licensingClient.SetActivationKey(_activationKey.c_str());
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey. Hardware Id", mask_secret(_hardwareId), __FILE__, __LINE__);
bool validLicense = licensingClient.IsLicenseValid();
if (!validLicense)
{
try
{
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Product needs to be activated. Requesting license activation from server...", __FILE__, __LINE__);
licensingClient.SetLicensingServiceUrl(this->_licenseServiceURL.c_str());
licensingClient.SetLicenseTemplate(this->_licenseTemplate);
licensingClient.AcquireLicense();
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Done.", __FILE__, __LINE__);
_overrideLicenseFile = true;
}
catch (Exception* ex)
{
this->_logger.LogFatal("ANSLSHelper::ValidateLicenseKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
}
catch (...)
{
this->_logger.LogFatal("ANSLSHelper::ValidateLicenseKey", "Unknown exception during activation attempt !", __FILE__, __LINE__);
}
if (!licensingClient.IsLicenseValid())
{
int activationStatus = licensingClient.GetLicenseActivationStatus();
std::string activationStatusStr;
switch (activationStatus)
{
case STATUS_INVALID_ACTIVATION_KEY:
_licenseKeyStatus = INVALID_ACTIVATION_KEY;
activationStatusStr = "Activation key is invalid";
break;
case STATUS_INVALID_HARDWARE_ID:
_licenseKeyStatus = INVALID_HARDWARE_ID;
activationStatusStr = "Hardware id does not match this computer. current HWID is " + _hardwareId +
"; client HWID is " + WString2String(licensingClient.GetHardwareId()) +
"; Current activation key is " + WString2String(_activationKey) +
"; client Activation key is " + WString2String(licensingClient.GetActivationKey()) +
"; URL is " + WString2String(this->_licenseServiceURL.c_str()) +
"; ProductId is " + WString2String(wProductId) +
"; RegistrationName is " + WString2String(_registrationName) +
"; Status is" + std::to_string(activationStatus);
break;
case STATUS_LICENSE_EXPIRED:
_licenseKeyStatus = LICENSE_EXPIRED;
activationStatusStr = "License expired";
break;
default:
_licenseKeyStatus = UNKNOWN;
activationStatusStr = "Failed to activate license. Unknown issue.";
break;
}
this->_logger.LogError("ANSLSHelper::ValidateLicenseKey", activationStatusStr, __FILE__, __LINE__);
activationKey = "";
return _licenseKeyStatus;
}
else // License is now valid, we need to check if
{
int expiredYear, expiredMonth, expiredDay;
try {
keyValidator.QueryDateKeyData(_T("ExpirationDate"), &expiredYear, &expiredMonth, &expiredDay);
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogWarn("ANSLSHelper::ValidateLicenseKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
licensingClient.GetLicenseExpirationDate(&expiredYear, &expiredMonth, &expiredDay);
}
if (expiredYear > 0) {
boost::posix_time::ptime timeLocal = boost::posix_time::second_clock::local_time();
unsigned short currentYear = timeLocal.date().year();
unsigned short currentMonth = timeLocal.date().month();
unsigned short currentDay = timeLocal.date().day();
boost::gregorian::date currentDate{ currentYear, currentMonth, currentDay };
boost::gregorian::date expiredDate{ (unsigned short)expiredYear, (unsigned short)expiredMonth, (unsigned short)expiredDay };
boost::gregorian::date_duration validDuration = expiredDate - currentDate;
bool changeClock = DectectClockmanipulation(expiredYear, expiredMonth, expiredDay);
if (changeClock) {
_licenseKeyStatus = LICENSE_EXPIRED;
}
else {
_licenseKeyStatus = SUCCESS;
}
std::string loggerExpiredMessage = str(boost::format("License Expiration Days: %1%") % validDuration.days());
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", loggerExpiredMessage, __FILE__, __LINE__);
}
else {
_licenseKeyStatus = SUCCESS;
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "License Expiration Date: Never", __FILE__, __LINE__);
}
// Do we need to check license (ProductId, RegistrationName, and features?) No need
// Save license
if (_licenseKeyStatus == SUCCESS) {
const wchar_t* wcActivationKey = licensingClient.GetActivationKey();
std::wstring wActivationKey(wcActivationKey);
std::string sActivationKey = WString2String(wActivationKey);
const wchar_t* hardwareId = licensingClient.GetHardwareId();
std::wstring wHardwareId(hardwareId);
std::string sHardwareId = WString2String(wHardwareId);
std::string loggerActivationMessage = str(boost::format("Activation Successful. The returned activation key: %1%") % mask_secret(sActivationKey));
std::string loggerHWIDMessage = str(boost::format("Computer's hardware id: %1%") % mask_secret(sHardwareId));
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Product is activated", __FILE__, __LINE__);
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey.", loggerActivationMessage, __FILE__, __LINE__);
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey.", loggerHWIDMessage, __FILE__, __LINE__);
const wchar_t* actKey = licensingClient.GetActivationKey();
std::wstring wact(actKey);
activationKey = WString2String(wact);
if (_overrideLicenseFile) {
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Override license key.", __FILE__, __LINE__);
if (!this->_license != NULL) delete this->_license;
this->_license = new License();
this->_license->SetLicenseKey(_licenseKey.c_str());
this->_license->SetLicenseKeyValidationData(validationData, validationDataLen);
this->_license->SetHardwareId(licensingClient.GetCurrentHardwareId());
this->_license->SetActivationKey(actKey);
SaveLicense();
}
}
else {
this->_logger.LogError("ANSLSHelper::ActivateLicense", "License expired. Please renew license.", __FILE__, __LINE__);
}
return _licenseKeyStatus;
}
}
else //License is already valid. No need to do anything
{
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Product is activated", __FILE__, __LINE__);
_licenseKeyStatus = SUCCESS;
const wchar_t* actKey = licensingClient.GetActivationKey();
std::wstring wact(actKey);
activationKey = WString2String(wact);
if (_overrideLicenseFile) {
// Save license
this->_logger.LogDebug("ANSLSHelper::ValidateLicenseKey", "Override license key.", __FILE__, __LINE__);
if (!this->_license != NULL) delete this->_license;
this->_license = new License();
this->_license->SetLicenseKey(_licenseKey.c_str());
this->_license->SetLicenseKeyValidationData(validationData, validationDataLen);
this->_license->SetHardwareId(licensingClient.GetCurrentHardwareId());
this->_license->SetActivationKey(actKey);
SaveLicense();
}
return _licenseKeyStatus;
}
}
catch (Exception* ex)
{
this->_logger.LogFatal("ANSLSHelper::ValidateLicenseKey", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
_licenseKeyStatus = INVALID_LICENSE_KEY;
return _licenseKeyStatus;
}
}
int ANSLSHelper::ActivateLicense(std::string licenseKey, std::string registrationName, std::string& activationKey ) {
try
{
LicenseKeyStatus _licenseKeyStatus;
LicenseValidationArgs validationArgs;
LicensingClient licensingClient;
LoadLicense(licenseKey);
std::wstring _licenseKey = String2WString(licenseKey);
std::wstring wProductId = GetProductId(licenseKey);
this->_licenseTemplate->SetTemplateId(wProductId.c_str());
licensingClient.SetLicenseTemplate(this->_licenseTemplate);
// Always activate
this->_logger.LogDebug("ANSLSHelper::ActivateLicense", "License was not found, the application needs to be activated", __FILE__, __LINE__);
validationArgs.SetLicenseKey(_licenseKey.c_str());
if (!registrationName.empty())
validationArgs.SetLicenseKeyValidationData(_T("RegistrationName"), String2WString(registrationName).c_str());
this->_logger.LogDebug("ANSLSHelper::ActivateLicense", "Activating the license....", __FILE__, __LINE__);
licensingClient.SetLicensingServiceUrl(this->_licenseServiceURL.c_str());
try {
LicenseValidationResult* validationResult = licensingClient.ValidateLicense(&validationArgs);
this->_logger.LogDebug("ANSLSHelper::ActivateLicense", "License was successfully activated", __FILE__, __LINE__);
//Now check if the license validation process resulted in server sending out a new license to replace the old one
License* newLicense = validationResult->GetLicense();
if (newLicense != NULL)
{
if (this->_license != NULL) delete this->_license;
this->_license = newLicense;
this->_license->SetActivationKey(newLicense->GetActivationKey());
this->_license->SetHardwareId(newLicense->GetHardwareId());
this->_license->SetLicenseKey(newLicense->GetLicenseKey());
const wchar_t* actKey = newLicense->GetActivationKey();
std::wstring wactKey(actKey);
activationKey = WString2String(wactKey);
//delete newLicense;
this->_logger.LogDebug("ANSLSHelper::ActivateLicense", "New license has been received from the licensing server", __FILE__, __LINE__);
SaveLicense();
}
else {// Existing _license
const wchar_t* actKey = this->_license->GetActivationKey();
std::wstring wactKey(actKey);
activationKey = WString2String(wactKey);
}
if (validationResult->IsLicenseExpired())
{
this->_logger.LogError("ANSLSHelper::ActivateLicense", "License is expired.", __FILE__, __LINE__);
_licenseKeyStatus = LICENSE_EXPIRED;
return _licenseKeyStatus;
}
if (validationResult->IsPaymentRequired())
{
this->_logger.LogError("ANSLSHelper::ActivateLicense", "Payment is required.", __FILE__, __LINE__);
_licenseKeyStatus = PAYMENT_REQUIRED;
return _licenseKeyStatus;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::ActivateLicense", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
}
if (licensingClient.IsLicenseValid()) {
_licenseKeyStatus = SUCCESS;
this->_logger.LogError("ANSLSHelper::ActivateLicense", "Activation Successfully.", __FILE__, __LINE__);
return _licenseKeyStatus;
}
else {
int activationStatus = licensingClient.GetLicenseActivationStatus();
std::string activationStatusStr;
switch (activationStatus)
{
case STATUS_INVALID_ACTIVATION_KEY:
_licenseKeyStatus = INVALID_ACTIVATION_KEY;
activationStatusStr = "Activation key is invalid";
break;
case STATUS_INVALID_HARDWARE_ID:
_licenseKeyStatus = INVALID_HARDWARE_ID;
activationStatusStr = "Hardware id does not match this computer";
break;
case STATUS_LICENSE_EXPIRED:
_licenseKeyStatus = LICENSE_EXPIRED;
activationStatusStr = "License expired";
break;
default:
_licenseKeyStatus = UNKNOWN;
activationStatusStr = "License key activation is failed. Unknonwn status";
break;
}
this->_logger.LogError("ANSLSHelper::ActivateLicense", activationStatusStr, __FILE__, __LINE__);
return _licenseKeyStatus;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::ActivateLicense", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
LicenseKeyStatus _licenseKeyStatus;
_licenseKeyStatus = UNKNOWN;
return _licenseKeyStatus;
}
}
int ANSLSHelper::ActivateLicenseWithCustomHWID(std::string licenseKey,
std::string registrationName,
std::string hardwareId,
std::string& activationKey) {
try
{
LicenseKeyStatus _licenseKeyStatus;
LicenseValidationArgs validationArgs;
LicensingClient licensingClient;
//LoadLicense(licenseKey);
std::wstring _licenseKey = String2WString(licenseKey);
std::wstring _hardwareId = String2WString(hardwareId);
std::wstring wProductId = GetProductId(licenseKey);
this->_licenseTemplate->SetTemplateId(wProductId.c_str());
licensingClient.SetLicenseTemplate(this->_licenseTemplate);
// Always activate
validationArgs.SetLicenseKey(_licenseKey.c_str());
if (!registrationName.empty())
validationArgs.SetLicenseKeyValidationData(_T("RegistrationName"), String2WString(registrationName).c_str());
this->_logger.LogDebug("ANSLSHelper::ActivateLicenseWithCustomHWID", "Activating the license....", __FILE__, __LINE__);
licensingClient.SetLicensingServiceUrl(this->_licenseServiceURL.c_str());
licensingClient.SetHardwareId(_hardwareId.c_str());
licensingClient.SetLicenseKey(_licenseKey.c_str());
try {
LicenseValidationResult* validationResult = licensingClient.ValidateLicense(&validationArgs);
this->_logger.LogDebug("ANSLSHelper::ActivateLicenseWithCustomHWID", "License was successfully activated", __FILE__, __LINE__);
//Now check if the license validation process resulted in server sending out a new license to replace the old one
License* newLicense = validationResult->GetLicense();
if (newLicense != NULL)
{
if (this->_license != NULL) delete this->_license;
this->_license = newLicense;
this->_license->SetActivationKey(newLicense->GetActivationKey());
this->_license->SetHardwareId(_hardwareId.c_str());
this->_license->SetLicenseKey(newLicense->GetLicenseKey());
const wchar_t* actKey = this->_license->GetActivationKey();
std::wstring wactKey(actKey);
activationKey = WString2String(wactKey);
//delete newLicense;
this->_logger.LogDebug("ANSLSHelper::ActivateLicenseWithCustomHWID. New license has been received from the licensing server", mask_secret(activationKey), __FILE__, __LINE__);
//SaveLicense();
}
else {// Existing _license
const wchar_t* actKey = this->_license->GetActivationKey();
std::wstring wactKey(actKey);
activationKey = WString2String(wactKey);
this->_logger.LogDebug("ANSLSHelper::ActivateLicenseWithCustomHWID", "Get existing activation key", __FILE__, __LINE__);
}
if (validationResult->IsLicenseExpired())
{
this->_logger.LogError("ANSLSHelper::ActivateLicenseWithCustomHWID", "License is expired.", __FILE__, __LINE__);
_licenseKeyStatus = LICENSE_EXPIRED;
return _licenseKeyStatus;
}
if (validationResult->IsPaymentRequired())
{
this->_logger.LogError("ANSLSHelper::ActivateLicenseWithCustomHWID", "Payment is required.", __FILE__, __LINE__);
_licenseKeyStatus = PAYMENT_REQUIRED;
return _licenseKeyStatus;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::ActivateLicenseWithCustomHWID", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
}
if (licensingClient.IsLicenseValid()) {
_licenseKeyStatus = SUCCESS;
this->_logger.LogDebug("ANSLSHelper::ActivateLicenseWithCustomHWID", "Activation Successfully.", __FILE__, __LINE__);
return _licenseKeyStatus;
}
else {
int activationStatus = licensingClient.GetLicenseActivationStatus();
std::string activationStatusStr;
switch (activationStatus)
{
case STATUS_INVALID_ACTIVATION_KEY:
_licenseKeyStatus = INVALID_ACTIVATION_KEY;
activationStatusStr = "Activation key is invalid";
break;
case STATUS_INVALID_HARDWARE_ID:
//_licenseKeyStatus = INVALID_HARDWARE_ID;
_licenseKeyStatus = SUCCESS;
activationStatusStr = "Hardware id does not match this computer";
break;
case STATUS_LICENSE_EXPIRED:
_licenseKeyStatus = LICENSE_EXPIRED;
activationStatusStr = "License expired";
break;
default:
_licenseKeyStatus = UNKNOWN;
activationStatusStr = "License key activation is failed. Unknown status";
break;
}
this->_logger.LogError("ANSLSHelper::ActivateLicense", activationStatusStr, __FILE__, __LINE__);
return _licenseKeyStatus;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::ActivateLicenseWithCustomHWID", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
LicenseKeyStatus _licenseKeyStatus;
_licenseKeyStatus = UNKNOWN;
return _licenseKeyStatus;
}
}
int ANSLSHelper::InstallOfflineLicense(std::string licenseKey, std::string registrationName, std::string activationKey) {
try {
std::wstring _licenseKey = String2WString(licenseKey);
std::wstring _activationKey = String2WString(activationKey);
std::wstring _registrationName = String2WString(registrationName);
std::wstring hardwareId = KeyHelper::GetCurrentHardwareId();
std::wstring wProductId = GetProductId(licenseKey);
std::string licenseFileName = Dash2Underscore(licenseKey) + ".json";
std::string licenseFolder = GetLicenseDir();
std::string licenseFilePath = CreateFilePath(licenseFolder,licenseFileName);
this->_licenseFilePath = String2WString(licenseFilePath);
this->_licenseTemplate->SetTemplateId(wProductId.c_str());
KeyValidator keyValidator(this->_licenseTemplate);
keyValidator.SetKey(_licenseKey.c_str());
if (!registrationName.empty())
keyValidator.SetValidationData(_T("RegistrationName"), _registrationName.c_str());
if (!keyValidator.IsKeyValid())
{
this->_logger.LogError("ANSLSHelper::InstallOfflineLicense", "Invalid license key", __FILE__, __LINE__);
return 0; // invalid
}
// We also need to verify if the activation key valid or not.
int validationDataLen = MAX_CUSTOMER_NAME_LEN;
unsigned char validationData[MAX_CUSTOMER_NAME_LEN] = "";
keyValidator.QueryValidationData(NULL, validationData, &validationDataLen);
const char* emptyString = "";
LicensingClient licensingClient;
// SetLicenseKeyValidationData needs to be called before SetActivationKeyTemplate !
int comparisonResult = std::strcmp(reinterpret_cast<const char*>(validationData), emptyString);
if (comparisonResult != 0)
licensingClient.SetLicenseKeyValidationData(validationData, validationDataLen);
licensingClient.SetLicenseTemplate(this->_licenseTemplate);
licensingClient.SetLicenseKey(_licenseKey.c_str());
licensingClient.SetHardwareId(hardwareId.c_str());
licensingClient.SetActivationKey(_activationKey.c_str());
bool validLicense = licensingClient.IsLicenseValid();
if (!validLicense)
{
this->_logger.LogError("ANSLSHelper::InstallOfflineLicense", "Invalid activation key", __FILE__, __LINE__);
return 0; // invalid
}
else {
if (!this->_license != NULL) delete this->_license;
this->_license = new License();
this->_license->SetLicenseKey(_licenseKey.c_str());
this->_license->SetLicenseKeyValidationData(validationData, validationDataLen);
this->_license->SetHardwareId(hardwareId.c_str());
this->_license->SetActivationKey(_activationKey.c_str());
SaveLicense();
return 1;
}
}
catch (ANSCENTER::Licensing::Exception* ex) {
this->_logger.LogFatal("ANSLSHelper::InstallOfflineLicense", ex->GetExceptionMessage(), __FILE__, __LINE__);
ex->Destroy();
return 0;
}
}
// Utilities
int ANSLSHelper::ExtractModelZipFile(std::string modelZipFile, std::string password, std::string modelName, std::string& extractedOutputFolder) {
int modelType = 1; // Default is Yolov4
// the class name should be the same
// 1. Unzip model zip file to a special location with folder name as model file (and version)
std::vector<std::string> passwordArray;
if (!password.empty()) passwordArray.push_back(password);
passwordArray.push_back("AnsDemoModels20@!");
passwordArray.push_back("Sh7O7nUe7vJ/417W0gWX+dSdfcP9hUqtf/fEqJGqxYL3PedvHubJag==");
passwordArray.push_back("3LHxGrjQ7kKDJBD9MX86H96mtKLJaZcTYXrYRdQgW8BKGt7enZHYMg==");
size_t vectorSize = passwordArray.size();
for (size_t i = 0; i < vectorSize; i++) {
if (ExtractPasswordProtectedZip(modelZipFile, passwordArray[i], modelName, extractedOutputFolder,true)) {
break; // Break the loop when the condition is met.
}
}
// 2. Check if the outputFolder exist
if (!std::filesystem::exists(extractedOutputFolder)) {
return -1; // That means the model file is not exist or the password is not correct
}
// 3. Check the model type based on the model file txt
std::string tensorflowFile = CreateFilePath(extractedOutputFolder, "tensorflow.txt");
if (FileExist(tensorflowFile)) {
modelType = 0;
return modelType;
}
tensorflowFile=CreateFilePath(extractedOutputFolder, "train_last.pb");
if (FileExist(tensorflowFile)) {
modelType = 0;
return modelType;
}
std::string yoloFile = CreateFilePath(extractedOutputFolder, "yolo.txt");
if (FileExist(yoloFile)) {
modelType = 1;
return modelType;
}
std::string yoloV4File = CreateFilePath(extractedOutputFolder, "yolov4.txt");
if (FileExist(yoloV4File)) {
modelType = 1;
return modelType;
}
yoloV4File = CreateFilePath(extractedOutputFolder, "train_last.weights");
if (FileExist(yoloV4File)) {
modelType = 1;
return modelType;
}
std::string yolov5File = CreateFilePath(extractedOutputFolder, "yolov5.txt");
if (FileExist(yolov5File)) {
modelType = 2;
return modelType;
}
std::string yoloV8File = CreateFilePath(extractedOutputFolder, "yolov8.txt");
if (FileExist(yoloV8File)) {
modelType = 3;
return modelType;
}
yoloV8File = CreateFilePath(extractedOutputFolder, "train_last.onnx");
if (FileExist(yoloV8File)) {
modelType = 3;
return modelType;
}
std::string tensorRTFile = CreateFilePath(extractedOutputFolder, "tensorrt.txt");
if (FileExist(tensorRTFile)) {
modelType = 4;
return modelType;
}
std::string openvinoFile = CreateFilePath(extractedOutputFolder, "openvino.txt");
if (FileExist(openvinoFile)) {
modelType = 5;
return modelType;
}
openvinoFile = CreateFilePath(extractedOutputFolder, "train_last.xml");
if (FileExist(openvinoFile)) {
modelType = 5;
return modelType;
}
return modelType;
}
bool ANSLSHelper::ZipFolerWithPassword(std::string folderPath, std::string zipFilePath, std::string password) {
return ZipFolderWithPassword(folderPath.c_str(), zipFilePath.c_str(), password.c_str());
}
int ANSLSHelper::PrepareEdgeModel(std::string modelZipFile,
std::string zipFilePassword,
std::string edgePassword,
std::string modelName,
std::string edgeSerialNumber,
std::string& configFilePathName,
std::string& labelMapPathName,
std::string& outputModelFolder) {
//1. First perform upzip and zip folder to a file with edgePassword protection
std::string extractedOutputFolder;
int modelType= ANSLSHelper::ExtractModelZipFile(modelZipFile, zipFilePassword, modelName, extractedOutputFolder);
if (modelType < 0) return -1;
// Check if the extractOutputFolder exist
if (!FolderExist(extractedOutputFolder)) return -2;
//2. Prepare the model zip file place holder (GenericModel.zip)
std::string modelFolderName = ExtractFolderName(extractedOutputFolder); // It should return the folder name: GenericModel
std::string zipFileName = modelName + ".zip"; // GenericModel.zip
std::string modelFolder = GetParentFolder(extractedOutputFolder); // C:\Users\Alex\AppData\Local\Temp\Models\EdgeModels
std::string configFilePath="";
std::string labelFilePath = "";
std::string modelFilePath = "";
std::string configFilePathDest = "";
std::string modelFilePathDest = "";
std::string configTempName = "";
std::string modelTempName = "";
std::string modelFileBinPath = "";
std::string modelTempBinName = "";
std::string modelBinFilePathDest = "";
std::vector<std::string> filesToKeep;
filesToKeep.clear();
// 2. Extract the content
switch (modelType)
{
case 0: //tensorflow
configFilePath = CreateFilePath(extractedOutputFolder, "pipeline.config");
labelFilePath = CreateFilePath(extractedOutputFolder, "classes.pbtxt");
modelFilePath = CreateFilePath(extractedOutputFolder, "train_last.pb");
// We need to delete all files, except for three files: train.cfg, classes.names, train_last.weights in the extractedOutputFolder
filesToKeep.push_back("pipeline.config");
filesToKeep.push_back("classes.pbtxt");
filesToKeep.push_back("train_last.pb");
filesToKeep.push_back("tensorflow.txt");
DeleteFilesInFolderExcept(extractedOutputFolder, filesToKeep);
// Rename
configTempName = modelName + ".config";
modelTempName = modelName + ".pb";
configFilePathDest = CreateFilePath(extractedOutputFolder, configTempName);
modelFilePathDest = CreateFilePath(extractedOutputFolder, modelTempName);
RenameFile(configFilePath, configFilePathDest);
RenameFile(modelFilePath, modelFilePathDest);
if (FileExist(configFilePathDest))configFilePathName = configFilePathDest;
else configFilePathName = "";
if (FileExist(labelFilePath))labelMapPathName = labelFilePath;
else labelMapPathName = "";
if (FolderExist(modelFolder))outputModelFolder = modelFolder;
else outputModelFolder = "";
break;
case 1: //yolov4
configFilePath = CreateFilePath(extractedOutputFolder, "train.cfg");
labelFilePath = CreateFilePath(extractedOutputFolder, "classes.names");
modelFilePath = CreateFilePath(extractedOutputFolder, "train_last.weights");
// We need to delete all files, except for three files: train.cfg, classes.names, train_last.weights in the extractedOutputFolder
filesToKeep.push_back("train.cfg");
filesToKeep.push_back("classes.names");
filesToKeep.push_back("train_last.weights");
filesToKeep.push_back("yolo.txt");
filesToKeep.push_back("yolov4.txt");
DeleteFilesInFolderExcept(extractedOutputFolder, filesToKeep);
// Rename
configTempName = modelName + ".cfg";
modelTempName = modelName + ".weights";
configFilePathDest = CreateFilePath(extractedOutputFolder, configTempName);
modelFilePathDest = CreateFilePath(extractedOutputFolder, modelTempName);
RenameFile(configFilePath, configFilePathDest);
RenameFile(modelFilePath, modelFilePathDest);
if (FileExist(configFilePathDest))configFilePathName = configFilePathDest;
else configFilePathName = "";
if (FileExist(labelFilePath))labelMapPathName = labelFilePath;
else labelMapPathName = "";
if (FolderExist(modelFolder))outputModelFolder = modelFolder;
else outputModelFolder = "";
break;
case 2: // yolov5
labelFilePath = CreateFilePath(extractedOutputFolder, "classes.names");
modelFilePath = CreateFilePath(extractedOutputFolder, "train_last.onnx");
// We need to delete all files, except for three files: train.cfg, classes.names, train_last.weights in the extractedOutputFolder
filesToKeep.push_back("classes.names");
filesToKeep.push_back("train_last.onnx");
filesToKeep.push_back("yolov5.txt");
DeleteFilesInFolderExcept(extractedOutputFolder, filesToKeep);
// Rename
modelTempName = modelName + ".onnx";
modelFilePathDest = CreateFilePath(extractedOutputFolder, modelTempName);
RenameFile(modelFilePath, modelFilePathDest);
if (FileExist(configFilePathDest))configFilePathName = configFilePathDest;
else configFilePathName = "";
if (FileExist(labelFilePath))labelMapPathName = labelFilePath;
else labelMapPathName = "";
if (FolderExist(modelFolder))outputModelFolder = modelFolder;
else outputModelFolder = "";
break;
case 3: // yolov8
labelFilePath = CreateFilePath(extractedOutputFolder, "classes.names");
modelFilePath = CreateFilePath(extractedOutputFolder, "train_last.onnx");
// We need to delete all files, except for three files: train.cfg, classes.names, train_last.weights in the extractedOutputFolder
filesToKeep.push_back("classes.names");
filesToKeep.push_back("train_last.onnx");
filesToKeep.push_back("yolov8.txt");
DeleteFilesInFolderExcept(extractedOutputFolder, filesToKeep);
// Rename
modelTempName = modelName + ".onnx";
modelFilePathDest = CreateFilePath(extractedOutputFolder, modelTempName);
RenameFile(modelFilePath, modelFilePathDest);
if (FileExist(configFilePathDest))configFilePathName = configFilePathDest;
else configFilePathName = "";
if (FileExist(labelFilePath))labelMapPathName = labelFilePath;
else labelMapPathName = "";
if (FolderExist(modelFolder))outputModelFolder = modelFolder;
else outputModelFolder = "";
break;
case 4: // tensorrt
labelFilePath = CreateFilePath(extractedOutputFolder, "classes.names");
modelFilePath = CreateFilePath(extractedOutputFolder, "train_last.onnx");
// We need to delete all files, except for three files: train.cfg, classes.names, train_last.weights in the extractedOutputFolder
filesToKeep.push_back("classes.names");
filesToKeep.push_back("train_last.onnx");
filesToKeep.push_back("tensorrt.txt");
DeleteFilesInFolderExcept(extractedOutputFolder, filesToKeep);
// Rename
modelTempName = modelName + ".onnx";
modelFilePathDest = CreateFilePath(extractedOutputFolder, modelTempName);
RenameFile(modelFilePath, modelFilePathDest);
if (FileExist(configFilePathDest))configFilePathName = configFilePathDest;
else configFilePathName = "";
if (FileExist(labelFilePath))labelMapPathName = labelFilePath;
else labelMapPathName = "";
if (FolderExist(modelFolder))outputModelFolder = modelFolder;
else outputModelFolder = "";
break;
case 5: // openvino
labelFilePath = CreateFilePath(extractedOutputFolder, "classes.names");
modelFilePath = CreateFilePath(extractedOutputFolder, "train_last.xml");
modelFileBinPath = CreateFilePath(extractedOutputFolder, "train_last.bin");
// We need to delete all files, except for three files: train.cfg, classes.names, train_last.weights in the extractedOutputFolder
filesToKeep.push_back("classes.names");
filesToKeep.push_back("train_last.xml");
filesToKeep.push_back("train_last.bin");
filesToKeep.push_back("metadata.yaml");
filesToKeep.push_back("openvino.txt");
DeleteFilesInFolderExcept(extractedOutputFolder, filesToKeep);
// Rename
modelTempName = modelName + ".xml";
modelFilePathDest = CreateFilePath(extractedOutputFolder, modelTempName);
RenameFile(modelFilePath, modelFilePathDest);
modelTempBinName = modelName + ".bin";
modelBinFilePathDest = CreateFilePath(extractedOutputFolder, modelTempBinName);
RenameFile(modelFileBinPath, modelBinFilePathDest);
if (FileExist(configFilePathDest))configFilePathName = configFilePathDest;
else configFilePathName = "";
if (FileExist(labelFilePath))labelMapPathName = labelFilePath;
else labelMapPathName = "";
if (FolderExist(modelFolder))outputModelFolder = modelFolder;
else outputModelFolder = "";
break;
default:
configFilePath = CreateFilePath(extractedOutputFolder, "train.cfg");
labelFilePath = CreateFilePath(extractedOutputFolder, "classes.names");
modelFilePath = CreateFilePath(extractedOutputFolder, "train_last.weights");
// We need to delete all files, except for three files: train.cfg, classes.names, train_last.weights in the extractedOutputFolder
filesToKeep.push_back("train.cfg");
filesToKeep.push_back("classes.names");
filesToKeep.push_back("train_last.weights");
DeleteFilesInFolderExcept(extractedOutputFolder, filesToKeep);
// Rename
configTempName = modelName + ".cfg";
modelTempName = modelName + ".weights";
configFilePathDest = CreateFilePath(extractedOutputFolder, configTempName);
modelFilePathDest = CreateFilePath(extractedOutputFolder, modelTempName);
RenameFile(configFilePath, configFilePathDest);
RenameFile(modelFilePath, modelFilePathDest);
if (FileExist(configFilePathDest))configFilePathName = configFilePathDest;
else configFilePathName = "";
if (FileExist(labelFilePath))labelMapPathName = labelFilePath;
else labelMapPathName = "";
if (FolderExist(modelFolder))outputModelFolder = modelFolder;
else outputModelFolder = "";
break;
}
//3. Quit
return modelType;
}
std::string ANSLSHelper::GetSystemHardwareInformation() {
//SPDLogger& _logger = SPDLogger::GetInstance("ANSInfoLog",true);
try {
boost::property_tree::ptree root;
boost::property_tree::ptree cpuNode,
osNode,
gpuNode,
ramNode,
mainBoardNode,
batteryNode,
diskNode;
// CPU information
auto sockets = hwinfo::getAllSockets();
for (auto& s : sockets) {
const auto& cpu = s.CPU();
boost::property_tree::ptree cpuNodeChild;
cpuNodeChild.put("Socket", s.id());
cpuNodeChild.put("vendor", cpu.vendor());
cpuNodeChild.put("model", cpu.modelName());
cpuNodeChild.put("physical_cores", cpu.numPhysicalCores());
cpuNodeChild.put("logical_cores", cpu.numLogicalCores());
cpuNodeChild.put("max_frequency", cpu.maxClockSpeed_MHz());
cpuNodeChild.put("regular_frequency", cpu.regularClockSpeed_MHz());
cpuNodeChild.put("min_frequency", cpu.minClockSpeed_MHz());
cpuNodeChild.put("current_frequency", cpu.currentClockSpeed_MHz());
cpuNodeChild.put("cache_size", cpu.cacheSize_Bytes());
cpuNode.push_back(std::make_pair("", cpuNodeChild));
}
root.add_child("CPU", cpuNode);
// OS information
hwinfo::OS os;
osNode.put("Operating_System", os.fullName());
osNode.put("short_name", os.name());
osNode.put("version", os.version());
osNode.put("kernel", os.kernel());
osNode.put("architecture", (os.is32bit() ? "32 bit" : "64 bit"));
osNode.put("endianess", os.isLittleEndian() ? "little endian" : "big endian");
root.add_child("OS", osNode);
// GPU information
auto gpus = hwinfo::getAllGPUs();
for (auto& gpu : gpus) {
boost::property_tree::ptree gpuNodeChild;
gpuNodeChild.put("GPU", gpu.id());
gpuNodeChild.put("vendor", gpu.vendor());
gpuNodeChild.put("model", gpu.name());
gpuNodeChild.put("diver_version", gpu.driverVersion());
gpuNodeChild.put("memory[MiB]", static_cast<double>(gpu.memory_Bytes()) / 1024.0 / 1024.0);
gpuNodeChild.put("frequency", gpu.frequency_MHz());
gpuNode.push_back(std::make_pair("", gpuNodeChild));
}
root.add_child("GPU", gpuNode);
// RAM information
hwinfo::RAM ram;
ramNode.put("vendor", ram.vendor());
ramNode.put("name", ram.model());
ramNode.put("serial_number", ram.serialNumber());
ramNode.put("size[MiB]", ram.total_Bytes() / 1024 / 1024);
ramNode.put("free[MiB]", ram.free_Bytes() / 1024 / 1024);
ramNode.put("available[MiB]", ram.available_Bytes() / 1024 / 1024);
root.add_child("RAM", ramNode);
// Main board information
hwinfo::MainBoard main_board;
mainBoardNode.put("vendor", main_board.vendor());
mainBoardNode.put("name", main_board.name());
mainBoardNode.put("version", main_board.version());
mainBoardNode.put("serial_number", main_board.serialNumber());
root.add_child("MAINBOARD", mainBoardNode);
// Battery information
auto batteries = hwinfo::getAllBatteries();
if (!batteries.empty()) {
int battery_counter = 0;
for (auto& battery : batteries) {
boost::property_tree::ptree batteryNodeChild;
batteryNodeChild.put("Battery", battery_counter++);
batteryNodeChild.put("vendor", battery.vendor());
batteryNodeChild.put("model", battery.model());
batteryNodeChild.put("serial_number", battery.serialNumber());
batteryNodeChild.put("charging", (battery.charging() ? "yes" : "no"));
batteryNodeChild.put("capacity", battery.capacity());
batteryNode.push_back(std::make_pair("", batteryNodeChild));
}
}
else {
boost::property_tree::ptree batteryNodeChild;
batteryNodeChild.put("Battery", 0);
batteryNodeChild.put("vendor", "NA");
batteryNodeChild.put("model", "NA");
batteryNodeChild.put("serial_number", "NA");
batteryNodeChild.put("charging", "NA");
batteryNodeChild.put("capacity", "NA");
batteryNode.push_back(std::make_pair("", batteryNodeChild));
}
root.add_child("BATTERIES", batteryNode);
// Disks information
/* auto disks = hwinfo::getAllDisks();
if (!disks.empty()) {
int disk_counter = 0;
for (const auto& disk : disks) {
boost::property_tree::ptree diskNodeChild;
diskNodeChild.put("Disk", disk_counter++);
diskNodeChild.put("vendor", disk.vendor());
diskNodeChild.put("model", disk.model());
diskNodeChild.put("serial_number", disk.serialNumber());
diskNodeChild.put("size", disk.size_Bytes());
diskNode.push_back(std::make_pair("", diskNodeChild));
}
}
else {
boost::property_tree::ptree diskNodeChild;
diskNodeChild.put("Disk", 0);
diskNodeChild.put("vendor", "NA");
diskNodeChild.put("model", "NA");
diskNodeChild.put("serial_number", "NA");
diskNodeChild.put("size", "NA");
diskNode.push_back(std::make_pair("", diskNodeChild));
}*/
boost::property_tree::ptree diskNodeChild;
diskNodeChild.put("Disk", 0);
diskNodeChild.put("vendor", "NA");
diskNodeChild.put("model", "NA");
diskNodeChild.put("serial_number", "NA");
diskNodeChild.put("size", "NA");
diskNode.push_back(std::make_pair("", diskNodeChild));
root.add_child("DISKS", diskNode);
try {
std::ostringstream stream;
boost::property_tree::write_json(stream, root,false);
std::string st = stream.str();
//this->_logger.LogDebug("System Information", st);
std::cout << st << std::endl;
return st;
}
catch (Exception* ex)
{
//this->_logger.LogFatal("ANSLSHelper::ValidateLicenseKey", ex->GetExceptionMessage());
std::cout << ex->GetExceptionMessage() << std::endl;
ex->Destroy();
return "Cannot retrieve system information";
}
}
catch (Exception* ex)
{
//this->_logger.LogFatal("ANSLSHelper::ValidateLicenseKey", ex->GetExceptionMessage());
std::cout << ex->GetExceptionMessage() << std::endl;
ex->Destroy();
return "Cannot retrieve system information";
}
}
bool ANSLSHelper::ReleaseLogger() {
SPDLogger& logger = SPDLogger::GetInstance("ReleaseLogger", true);
return logger.Release();
}
}
// ============================================================================
// Runtime DebugView toggle — gates ANS_DBG without requiring a rebuild.
//
// Precedence per poll: env var ANSCENTER_DBGVIEW wins over the sentinel file.
// Poll interval is 2 s, so toggling takes effect within that window. Hot-path
// cost on a cache hit is a single relaxed atomic load + branch.
// ============================================================================
extern "C" ANSLICENSE_API int ANSCENTER_IsDebugViewEnabled(void) {
using clock = std::chrono::steady_clock;
static std::atomic<int> s_enabled{0};
static std::atomic<long long> s_nextCheckTick{0};
const long long now = clock::now().time_since_epoch().count();
const long long next = s_nextCheckTick.load(std::memory_order_relaxed);
if (now < next) {
return s_enabled.load(std::memory_order_relaxed);
}
int enabled = 0;
const char* env = std::getenv("ANSCENTER_DBGVIEW");
if (env && env[0] == '1' && env[1] == '\0') {
enabled = 1;
} else if (env && env[0] == '0' && env[1] == '\0') {
enabled = 0;
} else {
#ifdef _WIN32
const wchar_t* kSentinel = L"C:\\ProgramData\\ANSCENTER\\ansvisdebugview.txt";
#else
const char* kSentinel = "/tmp/ansvisdebugview.txt";
#endif
std::error_code ec;
enabled = std::filesystem::exists(kSentinel, ec) ? 1 : 0;
}
s_enabled.store(enabled, std::memory_order_relaxed);
const long long deadline = now +
std::chrono::duration_cast<clock::duration>(std::chrono::seconds(2)).count();
s_nextCheckTick.store(deadline, std::memory_order_relaxed);
return enabled;
}