diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp index aece0b07d4a0dd9b6b18eec10ed380854cdb926b..9b11e27b626dabe2f7113f66f26829941826cf6f 100644 --- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp +++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp @@ -31,6 +31,9 @@ #include <curl/curl.h> #include <curl/easy.h> +#include <sstream> +#include <iomanip> + using namespace std; typedef void* voidptr; @@ -237,32 +240,76 @@ std::string getDateTimeString() { } std::string getCode(int argc, char *argv[]) { - if (argc < 2) return std::string(""); - return std::string(argv[1]); + if (argc < 1) return std::string(""); + + try { + string _argv = string(argv[0]); + size_t anchor = _argv.find("-"); + + int count = 0; + + while ((anchor = _argv.find("-")) != string::npos) { + _argv = _argv.substr(anchor + 1); + count++; + } + + if (count <= 4) return std::string(""); + return _argv.substr(0, _argv.find(".")); + } + catch (...) { + fwprintf(stderr, L"코드를 불러오는데 실패했습니다\n"); + return std::string(""); + } } -bool validateCode(std::string code) { +std::string escape_json(const std::string& s); +char* escape_xml(const std::string& xml) { + std::string merged = string("{\"xml\": \"") + escape_json(xml) + string("\"}"); + + size_t bufferSize = sizeof(char) * (merged.size() + 1); + char* buffer = (char*)malloc(bufferSize); + snprintf(buffer, bufferSize, "%s", merged.c_str()); + return buffer; +} + +bool submitParts(std::string code, char* xml) { CURL *handle = curl_easy_init(); struct curl_slist* list = NULL; list = curl_slist_append(list, "Content-Type: application/json"); list = curl_slist_append(list, std::string("Authorization: Code " + code).c_str()); - curl_easy_setopt(handle, CURLOPT_URL, "https://mirror.enak.kr/echo"); + curl_easy_setopt(handle, CURLOPT_URL, "https://meanspec.enak.kr/my/"); curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(handle, CURLOPT_HTTPHEADER, list); + char* body = escape_xml(xml); + curl_easy_setopt(handle, CURLOPT_POSTFIELDS, body); + CURLcode res = curl_easy_perform(handle); + size_t nread; + char buffer[1024] = { 0 }; + curl_easy_recv(handle, buffer, sizeof(buffer), &nread); + if (res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } else { - size_t nread; - char buffer[1024] = { 0 }; - curl_easy_recv(handle, buffer, sizeof(buffer), &nread); - cout << "Content is\n" << buffer << '\n'; + long statusCode; + curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &statusCode); + + if (200 <= statusCode && statusCode < 400) { + wcout << L"제출에 성공했습니다\n"; + } + else { + wcout << L"제출에 실패했습니다(" << statusCode << ")\n"; + cout << buffer << '\n'; + } } + curl_free(handle); + free(body); + return true; } @@ -286,10 +333,6 @@ int main(int argc, char *argv[]) { return 1; } - curl_global_init(CURL_GLOBAL_ALL); - bool result = validateCode(code); - curl_global_cleanup(); - int _initRes = initWQLServices(); if (_initRes != 0) { wcout << L"WQL을 초기화하는데 실패했습니다. 문의를 남겨주시기 바랍니다.\n"; @@ -311,7 +354,7 @@ int main(int argc, char *argv[]) { "SELECT * FROM Win32_BaseBoard", "SELECT * FROM MSFT_PhysicalDisk", "SELECT * FROM Win32_PhysicalMemory", - "SELECT * FROM win32_videocontroller" + "SELECT * FROM Win32_VideoController" }; IEnumWbemClassObject* pEnumerator = NULL; @@ -324,7 +367,7 @@ int main(int argc, char *argv[]) { return 1; } - fprintf(out, "<meanspec version=\"%s\"><time>%s</time>", VERSION, getDateTimeString()); + fprintf(out, "<meanspec version=\"%s\"><time>%s</time>", VERSION, getDateTimeString().c_str()); wcout << L"\n데이터를 수집하는 중\n"; @@ -383,8 +426,9 @@ int main(int argc, char *argv[]) { case VT_BSTR: { fwprintf(out, L"<%s>%s</%s>", bstrName, SafeXML(vtProp.bstrVal).c_str(), bstrName); - if (wcscmp(bstrName, L"Name") == 0) { + if (wcscmp(bstrName, L"Name") == 0 || wcscmp(bstrName, L"Caption") == 0) { _gpuNameCandidate = vtProp.bstrVal; + wcout << " " << vtProp.bstrVal << '\n'; } if (wcscmp(bstrName, L"DriverVersion") == 0) { _gpuDriverVersionCandidate = vtProp.bstrVal; @@ -441,23 +485,36 @@ int main(int argc, char *argv[]) { fprintf(out, "</meanspec>\n"); fclose(out); - char path[1024] = { 0 }; - auto _t = _getcwd(path, sizeof(path)); + FILE* in; + fopen_s(&in, FILENAME, "r"); - wcout << L"\n\n수집을 완료했습니다! meanspec-log.xml 파일을 제출해주세요\n"; - wcout << L" 파일 위치: " << path << "\n\n"; + if (in == NULL) { + fwprintf(stderr, L"수집에 성공하였으나 자료를 정리하는데 실패했습니다\n"); + return 2; + } - snprintf(&path[strlen(path)], sizeof(path), "\\%s", FILENAME); + fseek(in, 0, SEEK_END); + long lSize = ftell(in); + rewind(in); - int pathSize = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); - wchar_t* widePath = new wchar_t[pathSize]; - MultiByteToWideChar(CP_UTF8, 0, path, -1, widePath, pathSize); - LPCWSTR lpctPath = widePath; + size_t _bufferSize = sizeof(char) * (100 + lSize); + char* xmlBuffer = (char*)malloc(_bufferSize); + if (xmlBuffer == NULL) { + fwprintf(stderr, L"버퍼를 초기화하지 못했습니다\n"); + return 3; + } + + memset((void*)xmlBuffer, 0, _bufferSize); - wstring _arg(L"/select,"); - _arg.append(lpctPath); - - ShellExecute(NULL, L"open", L"explorer", _arg.c_str(), NULL, SW_SHOW); + size_t read_bytes = fread((void*)xmlBuffer, 1, lSize, in); + if (read_bytes != lSize - 1) { + fwprintf(stderr, L"자료 파일이 손상되었습니다\n"); + return 4; + } + + curl_global_init(CURL_GLOBAL_ALL); + submitParts(code, xmlBuffer); + curl_global_cleanup(); wcout << L"문의: lee@enak.kr\n"; wcout << L"엔터를 눌러 프로그램 종료\n"; @@ -573,3 +630,27 @@ int initWQLServices() { return 0; } + +std::string escape_json(const std::string& s) { + std::ostringstream o; + for (auto c = s.cbegin(); c != s.cend(); c++) { + switch (*c) { + case '"': o << "\\\""; break; + case '\\': o << "\\\\"; break; + case '\b': o << "\\b"; break; + case '\f': o << "\\f"; break; + case '\n': o << "\\n"; break; + case '\r': o << "\\r"; break; + case '\t': o << "\\t"; break; + default: + if ('\x00' <= *c && *c <= '\x1f') { + o << "\\u" + << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(*c); + } + else { + o << *c; + } + } + } + return o.str(); +}