#include "pch.h" #include "tunnel.h" #include #include #include #include #include #include "usrerr.h" #include "globalcfg.h" #include "misc.h" #include #define CONFIG_FILE_NAME TEXT("tunnelsdk.ini") static SDK_CONFIG g_globalConfig; PSDK_CONFIG GetGlobalCfgInfo() { return &g_globalConfig; } int TunnelSDKInitEnv(const TCHAR *pWorkDir, const TCHAR *pSvrUrl, bool isWorkServer) { size_t length; const BOOL logEnable = g_globalConfig.enableLog; const spdlog::level::level_enum lv = g_globalConfig.logLevel; memset(&g_globalConfig, 0, sizeof(SDK_CONFIG)); g_globalConfig.isWorkServer = isWorkServer; // 创建配置文件存储目录 if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_NO_ALIAS, NULL, 0, g_globalConfig.configDirectory))) { SPDLOG_ERROR(TEXT("Get Windows system directory error.")); return -ERR_SYS_CALL; } StringCbCat(g_globalConfig.configDirectory, MAX_PATH, "\\NetTunnel"); SPDLOG_DEBUG(TEXT("Configure directory: {0}."), g_globalConfig.configDirectory); // 如果配置目录不存在则自动创建 if (!PathFileExists(g_globalConfig.configDirectory)) { if (!CreateDirectory(g_globalConfig.configDirectory, nullptr)) { SPDLOG_ERROR(TEXT("Create configure directory '{0}' error."), g_globalConfig.configDirectory); return -ERR_CREATE_FILE; } } StringCbCopy(g_globalConfig.platformServerUrl, MAX_IP_LEN, pSvrUrl); g_globalConfig.logLevel = lv; g_globalConfig.enableLog = logEnable; if (!logEnable) { spdlog::set_level(spdlog::level::off); } if (FAILED(SHGetFolderPath(NULL, CSIDL_WINDOWS | CSIDL_FLAG_NO_ALIAS, NULL, 0, g_globalConfig.systemDirectory))) { SPDLOG_ERROR(TEXT("Get Windows system directory error.")); return -ERR_SYS_CALL; } if (pWorkDir == nullptr) { // 获取当前文件默认路径 GetCurrentDirectory(MAX_PATH, g_globalConfig.workDirectory); } else { if (StringCbLengthA(pWorkDir, MAX_PATH, &length) == S_OK && length == 0) { GetCurrentDirectory(MAX_PATH, g_globalConfig.workDirectory); } else { StringCbCopy(g_globalConfig.workDirectory, MAX_PATH, pWorkDir); } } StringCbPrintf(g_globalConfig.cfgPath, MAX_PATH, TEXT("%s\\%s"), g_globalConfig.workDirectory, CONFIG_FILE_NAME); if (FindWireguardExe(nullptr, 0) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("WireGuard not found, Please install WireGuard first or set the WireGuard Path.")); return -ERR_ITEM_EXISTS; } return ERR_SUCCESS; } void TunnelSDKUnInit() { } static spdlog::level::level_enum logLevelToSpdlogLevel(LOG_LEVEL level) { switch (level) { case LOG_TRACE: return spdlog::level::level_enum::trace; case LOG_DEBUG: return spdlog::level::level_enum::debug; case LOG_INFO: return spdlog::level::level_enum::info; case LOG_WARN: return spdlog::level::level_enum::warn; case LOG_ERROR: return spdlog::level::level_enum::err; case LOG_CRITICAL: return spdlog::level::level_enum::critical; case LOG_OFF: return spdlog::level::level_enum::off; } return spdlog::level::level_enum::info; } void InitTunnelSDKLog(const TCHAR *pLogFile, LOG_LEVEL level) { TCHAR buf[MAX_PATH] = {0}; if (pLogFile && strlen(pLogFile) > 0) { StringCbCopy(buf, MAX_PATH, pLogFile); } else { StringCbCopy(buf, MAX_PATH, TEXT("tunnelsdk.log")); } g_globalConfig.enableLog = TRUE; g_globalConfig.logLevel = logLevelToSpdlogLevel(level); const auto dupFileFilter = std::make_shared(std::chrono::seconds(5)); const auto dupStdFilter = std::make_shared(std::chrono::seconds(5)); dupFileFilter->add_sink(std::make_shared(buf, 1024 * 1024 * 5, 10)); dupStdFilter->add_sink(std::make_shared()); std::vector sinks {dupStdFilter, dupFileFilter}; auto logger = std::make_shared(TEXT("tunnelSDK"), sinks.begin(), sinks.end()); spdlog::set_default_logger(logger); spdlog::set_level(g_globalConfig.logLevel); spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e][%l][%s:%#] %v"); spdlog::flush_every(std::chrono::seconds(1)); #if 0 std::cout << "TRACE: " << logger->should_log(spdlog::level::trace) << std::endl; std::cout << "DEBUG: " << logger->should_log(spdlog::level::debug) << std::endl; std::cout << "INFO: " << logger->should_log(spdlog::level::info) << std::endl; std::cout << "WARN: " << logger->should_log(spdlog::level::warn) << std::endl; std::cout << "ERROR: " << logger->should_log(spdlog::level::err) << std::endl; std::cout << "CRITICAL: " << logger->should_log(spdlog::level::critical) << std::endl; #endif SPDLOG_INFO(TEXT("Log({1}): {0}"), buf, static_cast(level)); } void TunnelLogEnable(bool enLog) { if (enLog) { spdlog::set_level(g_globalConfig.logLevel); } else { spdlog::set_level(spdlog::level::level_enum::off); } } int SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, const TCHAR *pProKey) { if (type > CRYPTO_BASE64 && type < CRYPTO_MAX) { if (pProKey == nullptr || strlen(pProKey) < 8) { return -ERR_INPUT_PARAMS; } } g_globalConfig.proCryptoType = type; StringCbCopy(g_globalConfig.proKeyBuf, 256, pProKey); SPDLOG_DEBUG(TEXT("Protocol crypto type: {0} with key [{1}]"), static_cast(type), pProKey ? pProKey : TEXT("")); return ERR_SUCCESS; } //int CheckSystemMinDepend(CHECK_FUNCTION chkItem, TCHAR* pErrMsg, errMsg[MAX_PATH], ); int CheckSystemMinRequired(CHK_RESULT chkResult[CHK_MAX]) { for (int i = 0; i < CHK_MAX; i++) { const PCHK_RESULT pChk = &chkResult[i]; pChk->chk = static_cast(i); pChk->result = true; memset(pChk->errMsg, 0, MAX_PATH); switch (pChk->chk) { case CHK_SYSTEM_INIT: if (lstrlen(g_globalConfig.configDirectory) == 0) { pChk->result = false; StringCbCopy(pChk->errMsg, MAX_PATH, TEXT("错误: SDK 未初始化,请先调用 TunnelSDKInitEnv 接口执行初始化操作。")); SPDLOG_ERROR(pChk->errMsg); } break; case CHK_WIREGUARD_INSTALL: if (!g_globalConfig.wireguardCfg.wireguardExists) { pChk->result = false; StringCbCopy( pChk->errMsg, MAX_PATH, TEXT("错误: 系统未检测到 wireguard.exe 程序,请先下载并安装 WireGuard 最新版本,或者调用 " "SetWireguardPath 接口设置 WireGuard 程序路径。")); SPDLOG_ERROR(pChk->errMsg); } break; case CHK_WG_INSTALL: if (!g_globalConfig.wireguardCfg.wgExists) { pChk->result = false; StringCbCopy(pChk->errMsg, MAX_PATH, TEXT("错误: 系统未检测到 wg.exe 程序,请重新安装 WireGuard 或者修复 wg.exe 程序。")); SPDLOG_ERROR(pChk->errMsg); } break; case CHK_WIREGUARD_CONFIG: { TCHAR cfgVal[MAX_PATH]; GetPrivateProfileString(CFG_WIREGUARD_SECTION, CFG_WGCFG_PATH, TEXT(""), cfgVal, MAX_PATH, GetGlobalCfgInfo()->cfgPath); if (!PathFileExists(cfgVal)) { pChk->result = false; StringCbCopy(pChk->errMsg, MAX_PATH, TEXT("错误: 未找到 WireGuard 配置文件,请先调用 WireGuardInstallServerService 或者 " "WireGuardCreateClientConfig 接口创建合法的 WireGuard 配置文件。")); SPDLOG_ERROR(pChk->errMsg); } } break; case CHK_WIREGUARD_SERVICE: { int ret; bool bInstall; ret = IsWireGuardServerInstalled(&bInstall); if (ret != ERR_SUCCESS) { pChk->result = false; StringCbPrintf(pChk->errMsg, MAX_PATH, TEXT("错误: 获取系统 WireGuard 服务安装状态异常, 错误码:{0}。"), ret); SPDLOG_ERROR(pChk->errMsg); } if (!bInstall) { pChk->result = false; StringCbCopy(pChk->errMsg, MAX_PATH, TEXT("错误:系统 WireGuard 服务未安装,请调用 WireGuardInstallServerService 接口安装 " "WireGuard 服务。")); SPDLOG_ERROR(pChk->errMsg); } } break; case CHK_WG_INTERFACE_PRIVATE: if (!chkResult[CHK_WIREGUARD_SERVICE].chk) { pChk->result = false; StringCbCopy(pChk->errMsg, MAX_PATH, TEXT("错误:系统 WireGuard 服务未安装,请调用 WireGuardInstallServerService 接口安装 " "WireGuard 服务。")); SPDLOG_ERROR(pChk->errMsg); } break; case CHK_MAX: break; } } return ERR_SUCCESS; }