// // Created by HW on 2023/07/27. // #include #include #include #include #include "netio.h" #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #pragma comment(lib, "wbemuuid.lib") #ifdef _DEBUG #pragma comment(lib, "Qt5Networkd.lib") #else #pragma comment(lib, "Qt5Network.lib") #endif #pragma comment(lib,"comsuppw.lib") //读取注册表获取MachineUUID inline QString getMachineGUID(){ HKEY hKey; RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0,KEY_READ | KEY_WOW64_64KEY, &hKey); DWORD dwType1 = REG_SZ; DWORD dwLen = MAX_PATH; WCHAR buf[100]; RegQueryValueExA(hKey, "MachineGuid" ,0 ,&dwType1, (LPBYTE)buf, &dwLen); QString guid=QString::fromWCharArray(buf); return guid; } RequestBodyBase::RequestBodyBase(){ wchar_t unix_time[65]={0}; wsprintf(unix_time,L"%ld",std::time(0)); QString request_id=QString::fromWCharArray(unix_time); //打开配置文件 QFile *infFile=new QFile(".\\config\\information.cfg"); if(!infFile->open(QIODevice::ReadOnly|QIODevice::Text)){ QMessageBox::critical(nullptr,QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("无法打开配置文件")); delete infFile; exit(1); } //读取配置文件 QByteArray bytes; bytes=infFile->readAll(); infFile->close(); delete infFile; //转化为json qJsonDocument=QJsonDocument::fromJson(bytes); if(qJsonDocument.isObject()){ //读取数据,写入对应字段 QJsonObject obj_root=qJsonDocument.object(); if(obj_root.value("product")==QJsonValue::Undefined){ QMessageBox::warning(nullptr, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("配置文件损坏")); exit(1); } product=obj_root.value("product").toString(); if(obj_root.value("partner_id")==QJsonValue::Undefined){ QMessageBox::warning(nullptr, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("配置文件损坏")); exit(1); } partner_id=obj_root.value("partner_id").toString(); if(obj_root.value("release")==QJsonValue::Undefined){ QMessageBox::warning(nullptr, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("配置文件损坏")); exit(1); } release=obj_root.value("release").toString(); if(obj_root.value("version")==QJsonValue::Undefined){ QMessageBox::warning(nullptr, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("配置文件损坏")); exit(1); } version=obj_root.value("version").toString(); if(obj_root.value("device_id")==QJsonValue::Undefined){ QMessageBox::warning(nullptr, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("配置文件损坏")); exit(1); } device_id=obj_root.value("device_id").toString(); }else{ //处理错误 QMessageBox::warning(nullptr,"错误","配置文件损坏"); exit(1); } //获取操作系统版本 os="Windows"; OSVERSIONINFOEX os; os.dwOSVersionInfoSize=sizeof(os); GetVersionEx((OSVERSIONINFO *)&os); switch(os.dwMajorVersion){//主版本号 case 5: //不兼容Windows 2000,因此5.x一定是Windows XP os_version="Windows XP"; break; case 6: switch(os.dwMinorVersion){ //次版本号 case 0: os_version="Windows Vista or Windows Server 2008"; break; case 1: os_version="Windows 7 or Windows Server 2008 R2"; break; case 2: os_version="Windows 8 or Windows Server 2012"; break; case 3: os_version="Windows 8.1 or Windows Server 2012 R2"; break; default: os_version="Unknown"; } case 10: //这几个系统都是10.0 os_version="Windows 10, Windows 11, Windows Server 2016 or Windows Server 2019"; break; default: os_version="Unknown"; } //如果device_id是空值 if(device_id.isEmpty()){ //读取MachineGUID并取MD5作为device_id QByteArray hash = QCryptographicHash::hash(getMachineGUID().toUtf8(), QCryptographicHash::Md5); device_id=hash.toHex(); infFile=new QFile(".\\config\\information.cfg"); if(!infFile->open(QIODevice::WriteOnly|QIODevice::Text)){ //处理错误 QMessageBox::warning(nullptr, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("无法覆写配置文件")); infFile->close(); delete infFile; exit(1); } //加入json序列 QJsonValue value=device_id; QJsonObject obj_root; obj_root.insert("device_id",value); qJsonDocument.setObject(obj_root); //写入配置文件 infFile->write(qJsonDocument.toJson()); //关闭文件; infFile->close(); delete infFile; } QJsonValue requestId_json=QJsonValue(request_id); QJsonObject obj_root; //插入request_id obj_root.insert("request_id",requestId_json); qJsonDocument.setObject(obj_root); } void ConfigRequest::sendRequest(ConfigResponse *configResponse) { timer = new QTimer(this); QNetworkAccessManager *httpMgr = new QNetworkAccessManager(); /* QFile *file=new QFile(".\\config\\config.cfg"); if(!file->open(QIODevice::ReadOnly|QIODevice::Text)){ QMessageBox::warning(nullptr,"错误","无法打开配置文件"); file->close(); delete file; exit(1); }*/ QNetworkRequest requestInfo; //HTTP请求 //请求头 requestInfo.setUrl(QUrl(CONFIG_URL)); requestInfo.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json")); //保存响应的变量 reply = httpMgr->post(requestInfo,qJsonDocument.toJson()); //开启一个循环,直到超时或者获取到数据为止 connect(reply,&QNetworkReply::finished, &eventLoop, &QEventLoop::quit); //设置定时器防止超时 connect(timer,&QTimer::timeout,this,&ConfigRequest::cancelDownload); timer->start(5000); //启动循环 eventLoop.exec(); delete httpMgr; QJsonDocument result; configResponse=new ConfigResponse; memset(configResponse,0,sizeof(*configResponse)); //如果没有错误 if(reply->error() == QNetworkReply::NoError) { result = QJsonDocument::fromJson(reply->readAll()); }else{ //如果有错误 configResponse->succeed=false; delete reply; delete timer; return; } //如果数据完整 if(result.isObject()){ QJsonObject obj_root=result.object(); QJsonArray array; array = obj_root.value("menu").toArray(); configResponse->menus=new QList; auto i=0; for(auto value:array){ QJsonObject object=value.toObject(); Menu menu; menu.img=object.value("img").toString(); menu.img_cover=object.value("img_cover").toString(); menu.title=object.value("title").toString(); menu.func=object.value("func").toString(); menu.url=object.value("url").toString(); *configResponse->menus << menu; i++; } }else{ //数据不完整 configResponse->succeed=false; delete reply; delete timer; return; } } void RequestBodyBase::cancelDownload() { disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit); eventLoop.quit(); reply->abort(); } void RequestBodyBase::sendRequest() { timer = new QTimer(this); QNetworkAccessManager *httpMgr = new QNetworkAccessManager(); QNetworkRequest requestInfo; //HTTP请求 //请求头 requestInfo.setUrl(QUrl(OP_URL)); requestInfo.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json")); //保存响应的变量 reply = httpMgr->post(requestInfo,qJsonDocument.toJson()); //开启一个循环,直到超时或者获取到数据为止 connect(reply,&QNetworkReply::finished, this, &RequestBodyBase::cancelDownload); //设置定时器防止超时 connect(timer,&QTimer::timeout,&eventLoop,&QEventLoop::quit); timer->start(5000); //启动循环 eventLoop.exec(); delete timer; delete httpMgr; delete reply; } DeviceRequest::DeviceRequest() : RequestBodyBase() { //CPU QString cpu = QSysInfo::currentCpuArchitecture(); //内存大小 MEMORYSTATUSEX status; status.dwLength = sizeof(status); GlobalMemoryStatusEx(&status); int ram = status.ullTotalPhys / 1024 / 1024; //硬盘大小 QStorageInfo storage = QStorageInfo::root(); int disk = storage.bytesTotal() / static_cast(1024 * 1024 * 1024); //显卡型号 QStringList gpus; BOOL success; DWORD deviceIndex = 0; DISPLAY_DEVICE displayDevice; displayDevice.cb = sizeof(displayDevice); while (EnumDisplayDevices(NULL, deviceIndex, &displayDevice, 0)) { WCHAR valueName[128]; DWORD valueSize; DWORD valueType; BYTE valueData[MAX_PATH]; HKEY hKey; WCHAR keyName[128]; wsprintf(keyName, L"SYSTEM\\CurrentControlSet\\Control\\Video\\%s\\HardwareInformation", displayDevice.DeviceID); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { valueSize = sizeof(valueData); wsprintf(valueName, L"HardwareInformation.AdapterString"); if (RegQueryValueEx(hKey, valueName, NULL, &valueType, valueData, &valueSize) == ERROR_SUCCESS) { Q_ASSERT(valueType == REG_SZ); QString adapterString = QString::fromWCharArray((wchar_t *) valueData, valueSize / sizeof(wchar_t) - 1); gpus.append(adapterString); } RegCloseKey(hKey); } deviceIndex++; displayDevice.cb = sizeof(displayDevice); } //主板型号 QString motherboard = QSysInfo::prettyProductName(); //WMI获取网卡型号 HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hr)) { std::cerr << "Failed to initialize COM library." << std::endl; return; } QStringList netCards; hr = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); if (FAILED(hr)) { std::cerr << "Failed to initialize security." << std::endl; CoUninitialize(); return; } IWbemLocator* pLoc = NULL; hr = CoCreateInstance( CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc ); if (FAILED(hr)) { std::cerr << "Failed to create IWbemLocator object." << std::endl; CoUninitialize(); return; } IWbemServices* pSvc = NULL; hr = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc ); if (FAILED(hr)) { std::cerr << "Failed to connect to WMI service." << std::endl; pLoc->Release(); CoUninitialize(); return; } hr = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); if (FAILED(hr)) { std::cerr << "Failed to set security blanket." << std::endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return; } IEnumWbemClassObject* pEnumerator = NULL; hr = pSvc->ExecQuery( _bstr_t("WQL"), _bstr_t("SELECT * FROM Win32_NetworkAdapter WHERE PhysicalAdapter = TRUE AND NetConnectionStatus = 3"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if (FAILED(hr)) { std::cerr << "Failed to execute WQL query for Win32_NetworkAdapter." << std::endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return; } IWbemClassObject* pClassObj = NULL; ULONG uReturn = 0; while (pEnumerator) { hr = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObj, &uReturn); if (uReturn == 0) { break; } VARIANT vtProp; hr = pClassObj->Get(L"Caption", 0, &vtProp, 0, 0); if (SUCCEEDED(hr)) { QString str=QString::fromWCharArray(vtProp.bstrVal); VariantClear(&vtProp); netCards.append(str); } pClassObj->Release(); } //WMI获取声卡型号 hr = pSvc->ExecQuery( _bstr_t("WQL"), _bstr_t("SELECT * FROM Win32_SoundDevice"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if (FAILED(hr)) { std::cerr << "Failed to execute WQL query for Win32_SoundDevice." << std::endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return; } QStringList audioCards; while (pEnumerator) { hr = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObj, &uReturn); if (uReturn == 0) { break; } VARIANT vtProp; hr = pClassObj->Get(L"Name", 0, &vtProp, 0, 0); if (SUCCEEDED(hr)) { QString str=QString::fromWCharArray(vtProp.bstrVal); VariantClear(&vtProp); audioCards.append(str); } pClassObj->Release(); } hr = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_PhysicalMemory"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if (FAILED(hr)) { std::cout << "Query failed. Error code: " << hr << std::endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return; } QStringList RAMModel; while (pEnumerator) { hr = pEnumerator->Next(WBEM_INFINITE, 1, &pClassObj, &uReturn); if (uReturn == 0) { break; } VARIANT vtProp; hr = pClassObj->Get(L"Manufacturer", 0, &vtProp, 0, 0); if (SUCCEEDED(hr)) { std::wcout << "Manufacturer: " << vtProp.bstrVal << std::endl; VariantClear(&vtProp); } hr = pClassObj->Get(L"PartNumber", 0, &vtProp, 0, 0); if (SUCCEEDED(hr)) { RAMModel.append(QString::fromWCharArray(vtProp.bstrVal)); VariantClear(&vtProp); } pClassObj->Release(); } pSvc->Release(); pLoc->Release(); CoUninitialize(); DISPLAY_DEVICE d = { sizeof(DISPLAY_DEVICE) }; ::EnumDisplayDevices(NULL, 0, &d, 0); QString monitor=QString::fromWCharArray(d.DeviceString, wcslen(d.DeviceString)); //发送 //构造JSON QJsonDocument *device=new QJsonDocument; QJsonObject *object=new QJsonObject; object->insert("CPU",QJsonValue(cpu)); object->insert("RAM",QJsonValue(ram)); object->insert("Hard_Disk",QJsonValue(disk)); QJsonArray *gpu_array=new QJsonArray; for(auto gpu:gpus) { gpu_array->append(gpu); } object->insert("GPU",*gpu_array); delete gpu_array; object->insert("Mother_Board",motherboard); QJsonArray *RAMModel_json=new QJsonArray; for(auto RAM:RAMModel){ RAMModel_json->append(RAM); } object->insert("Net_Card",*RAMModel_json); delete RAMModel_json; QJsonArray *netCards_json=new QJsonArray; for(auto netCard:netCards){ netCards_json->append(netCard); } object->insert("Net_Card",*netCards_json); delete netCards_json; QJsonArray *audioCards_json=new QJsonArray; for(auto audioCard:audioCards){ audioCards_json->append(audioCard); } object->insert("Audio_Card",*audioCards_json); delete audioCards_json; object->insert("Monitor",monitor); device->setObject(*object); delete object; QJsonObject obj_root=qJsonDocument.object(); obj_root.insert("data",QString(device->toJson())); delete device; qJsonDocument.setObject(obj_root); timer = new QTimer(this); QNetworkAccessManager *httpMgr = new QNetworkAccessManager(); QNetworkRequest requestInfo; //HTTP请求 //请求头 requestInfo.setUrl(QUrl(DEVICE_URL)); requestInfo.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json")); //保存响应的变量 reply = httpMgr->post(requestInfo,qJsonDocument.toJson()); //开启一个循环,直到超时或者获取到数据为止 connect(reply,&QNetworkReply::finished, &eventLoop, &QEventLoop::quit); //设置定时器防止超时 connect(timer,&QTimer::timeout,this,&DeviceRequest::cancelDownload); timer->start(5000); //启动循环 eventLoop.exec(); delete httpMgr; }