#include "HGUpgrade.h" #include "base/HGDef.h" #include "base/HGInc.h" #include "base/HGMd5.h" #include "base/HGUtility.h" #include "curl/curl.h" #include #include #include #include #include #if defined(HG_CMP_MSC) #include #endif static void GetMacAddrList(std::vector &macList) { macList.clear(); #if defined(HG_CMP_MSC) ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)malloc(ulOutBufLen); ULONG nRet = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); if (ERROR_BUFFER_OVERFLOW == nRet) { free(pAdapterInfo); pAdapterInfo = nullptr; pAdapterInfo = (PIP_ADAPTER_INFO)malloc(ulOutBufLen); nRet = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); } if (ERROR_SUCCESS == nRet) { PIP_ADAPTER_INFO pAdapter = pAdapterInfo; while (nullptr != pAdapter) { DWORD dwCharacteristics = 0; HKEY hKey = nullptr; RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}", 0, KEY_ENUMERATE_SUB_KEYS, &hKey); if (nullptr != hKey) { DWORD dwIndex = 0; while (1) { CHAR szValueName[256]; if (ERROR_SUCCESS != RegEnumKeyA(hKey, dwIndex, szValueName, 256)) { break; } HKEY hKey2 = nullptr; RegOpenKeyExA(hKey, szValueName, 0, KEY_QUERY_VALUE, &hKey2); if (nullptr != hKey2) { DWORD dwType; CHAR szData[256] = { 0 }; DWORD cbData = 256; if (ERROR_SUCCESS == RegQueryValueExA(hKey2, "NetCfgInstanceId", nullptr, &dwType, (LPBYTE)szData, &cbData) && REG_SZ == dwType) { if (0 == _stricmp(szData, pAdapter->AdapterName)) { if (ERROR_SUCCESS == RegQueryValueExA(hKey2, "Characteristics", nullptr, &dwType, (LPBYTE)szData, &cbData) && REG_DWORD == dwType) { dwCharacteristics = *(DWORD*)szData; } } } RegCloseKey(hKey2); } ++dwIndex; } RegCloseKey(hKey); } if ((dwCharacteristics & 0x4)) { std::string strMacAddr; for (UINT i = 0; i < pAdapter->AddressLength; i++) { char str[10]; sprintf(str, "%02x", pAdapter->Address[i]); strMacAddr += str; if (i != pAdapter->AddressLength - 1) strMacAddr += "-"; } macList.push_back(strMacAddr); } pAdapter = pAdapter->Next; } } free(pAdapterInfo); pAdapterInfo = nullptr; #else DIR *dir = opendir("/sys/class/net"); if (NULL != dir) { printf("opendir success\n"); struct dirent *ent; while ((ent = readdir(dir)) != nullptr) { if (1) { if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue; if (strstr(ent->d_name, "docker") == ent->d_name || strstr(ent->d_name, "sit") == ent->d_name || strstr(ent->d_name, "ip6tnl") == ent->d_name || strcmp(ent->d_name, "lo") == 0) continue; printf("name %s\n", ent->d_name); char addrPath[256]; sprintf(addrPath, "/sys/class/net/%s/address", ent->d_name); FILE *file = fopen(addrPath, "rb"); if (NULL != file) { char mac[1025] = {0}; fread(mac, 1, 1024, file); if (strlen(mac) > 0) { if (mac[strlen(mac) - 1] == '\n') mac[strlen(mac) - 1] = '\0'; } if (strlen(mac) > 0) { macList.push_back(mac); } printf("mac %s\n", mac); fclose(file); } else { printf("fopen fail\n"); } } } closedir(dir); } else { printf("opendir fail\n"); } #endif } static std::string GetCurrVersion() { std::string version = "0.0.0.0"; #if defined(HG_CMP_MSC) HKEY hKey = nullptr; RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\HuaGoScan", 0, KEY_QUERY_VALUE, &hKey); if (nullptr != hKey) { CHAR szData[MAX_PATH] = { 0 }; DWORD cbData = MAX_PATH; if (ERROR_SUCCESS == RegQueryValueExA(hKey, "AppVersion", nullptr, nullptr, (LPBYTE)szData, &cbData)) { version = szData; } RegCloseKey(hKey); } #else // TODO #endif return version; } static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) { std::string data((const char*) ptr, (size_t) size * nmemb); *((std::stringstream*) stream) << data << std::endl; return size * nmemb; } static bool Greater(const std::string &str1, const std::string &str2) { return str1 > str2; } // type:1表示安装 2表示卸载 src:来源 desc: 说明 static bool PostInfo(int type, const std::string &src, const std::string &desc) { curl_global_init(CURL_GLOBAL_ALL); bool ret = false; CURL* curl = curl_easy_init(); if (curl) { std::stringstream out; std::string url = "http://up.appqy.com/api/recode"; curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); std::vector macList; GetMacAddrList(macList); if (macList.empty()) macList.push_back("00-00-00-00-00-00"); std::sort(macList.begin(), macList.end(), Greater); std::string strMacAddrTotal; for (int i = 0; i < (int)macList.size(); ++i) { strMacAddrTotal += macList[i]; } HGByte md5[16] = {0}; HGBase_MakeMd5((const HGByte *)strMacAddrTotal.c_str(), strMacAddrTotal.size(), md5); char md5Str[64] = {0}; char *pstr = md5Str; for (int i = 0; i < 16; ++i) { sprintf(pstr, "%02x", md5[i]); pstr += 2; } std::string version = GetCurrVersion(); char json[1024]; sprintf(json, "{\"type\":%d, \"mac\":\"%s\", \"localid\":\"%s\", \"v\":\"%s\", \"ref\":\"%s\", \"desc\":\"%s\"}", type, macList[0].c_str(), md5Str, version.c_str(), src.c_str(), desc.c_str()); struct curl_slist* headers = nullptr; headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &out); /* Perform the request, res will get the return code */ CURLcode res = curl_easy_perform(curl); /* Check for errors */ if (res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s", curl_easy_strerror(res)); else ret = true; curl_slist_free_all(headers); std::string str_json = out.str(); // 返回值 printf("%s\n", str_json.c_str()); /* always cleanup */ curl_easy_cleanup(curl); } curl_global_cleanup(); return ret; } bool PostInstallInfo(const std::string &src, const std::string &desc) { return PostInfo(1, src, desc); } bool PostUninstallInfo(const std::string &src, const std::string &desc) { return PostInfo(2, src, desc); } static bool Setup(const std::string& pkgPath) { bool ret = false; #if defined(HG_CMP_MSC) PROCESS_INFORMATION ProcessInfo; STARTUPINFOA StartupInfo; ZeroMemory(&StartupInfo, sizeof(StartupInfo)); StartupInfo.cb = sizeof(StartupInfo); char command[256]; sprintf(command, "%s %s", Utf8ToStdString(pkgPath).c_str(), "/verysilent"); if (CreateProcessA(nullptr, command, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &StartupInfo, &ProcessInfo)) { WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); ret = true; } #else // TODO #endif return ret; } bool Upgrade(const std::string& pkgPath, const std::string &src, const std::string &desc) { bool ret = Setup(pkgPath); if (ret) PostInfo(1, src, desc); return ret; }