Skip to content
Snippets Groups Projects

서버에 자동으로 제출하도록

Merged Eunhak Lee requested to merge feat/auto-submit into dev
3 files
+ 275
88
Compare changes
  • Side-by-side
  • Inline

Files

@@ -19,8 +19,22 @@
#define FILENAME "meanspec-log.xml"
#define VERSION "1.2"
#ifndef CURL_STATICLIB
#define CURL_STATICLIB
#endif
#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "libcurl.lib")
#pragma comment(lib, "wldap32.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "wbemuuid.lib")
#include <curl/curl.h>
#include <curl/easy.h>
#include <sstream>
#include <iomanip>
using namespace std;
typedef void* voidptr;
@@ -226,14 +240,177 @@ std::string getDateTimeString() {
return std::string(buffer);
}
int main() {
std::string getCode(int argc, char *argv[]) {
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("");
}
}
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://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 {
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;
}
IWbemLocator* pLoc = NULL;
IWbemServices* pSvc = NULL, * pSvcStorage = NULL;
int initWQLServices();
size_t crawlParts(const char* queries[], size_t queryCount, FILE* out);
int main(int argc, char *argv[]) {
setlocale(LC_ALL, "en_US.UTF-8");
SetConsoleOutputCP(CP_UTF8);
std::string code = getCode(argc, argv);
if (code.length() < 1) {
wcout << L"올바르지 않은 실행입니다. 사이트에서 프로그램을 다시 다운받아주세요.\n";
getchar();
return 1;
}
int _initRes = initWQLServices();
if (_initRes != 0) {
wcout << L"WQL을 초기화하는데 실패했습니다. 문의를 남겨주시기 바랍니다.\n";
getchar();
return _initRes;
}
const char* QUERIES[] = {
"SELECT * FROM Win32_Processor",
"SELECT * FROM Win32_DiskDrive",
"SELECT * FROM Win32_BaseBoard",
"SELECT * FROM MSFT_PhysicalDisk",
"SELECT * FROM Win32_PhysicalMemory",
"SELECT * FROM Win32_VideoController"
};
FILE* out;
fopen_s(&out, FILENAME, "w");
if (out == NULL) {
cout << "failed to open meanspec-log.xml\n";
return 1;
}
wcout << L"\n데이터를 수집하는 중\n";
fprintf(out, "<meanspec version=\"%s\"><time>%s</time>", VERSION, getDateTimeString().c_str());
crawlParts(QUERIES, sizeof(QUERIES)/sizeof(QUERIES[0]), out);
fprintf(out, "</meanspec>\n");
fclose(out);
// Cleanup
// ========
pSvc->Release();
pSvcStorage->Release();
pLoc->Release();
CoUninitialize();
FILE* in;
fopen_s(&in, FILENAME, "r");
if (in == NULL) {
fwprintf(stderr, L"수집에 성공하였으나 자료를 정리하는데 실패했습니다\n");
getchar();
return 2;
}
fseek(in, 0, SEEK_END);
long lSize = ftell(in);
rewind(in);
size_t _bufferSize = sizeof(char) * (100 + lSize);
char* xmlBuffer = (char*)malloc(_bufferSize);
if (xmlBuffer == NULL) {
fwprintf(stderr, L"버퍼를 초기화하지 못했습니다\n");
getchar();
return 3;
}
memset((void*)xmlBuffer, 0, _bufferSize);
size_t read_bytes = fread((void*)xmlBuffer, 1, lSize, in);
if (read_bytes != lSize - 1) {
fwprintf(stderr, L"자료 파일이 손상되었습니다\n");
getchar();
return 4;
}
curl_global_init(CURL_GLOBAL_ALL);
submitParts(code, xmlBuffer);
curl_global_cleanup();
wcout << L"문의: lee@enak.kr\n";
wcout << L"엔터를 눌러 프로그램 종료\n";
getchar();
return 0;
}
int initWQLServices() {
HRESULT hres;
IWbemLocator* pLoc = NULL;
IWbemServices* pSvc = NULL;
IWbemServices* pSvcStorage = NULL;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) {
@@ -254,7 +431,7 @@ int main() {
);
if (FAILED(hres)) {
cout << "Failed to initialize security."
<< " Error code = 0x" << hex << hres << endl;
<< " Error code = 0x" << hex << hres << endl;
CoUninitialize();
return 1; // Program has failed.
}
@@ -265,13 +442,11 @@ int main() {
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pLoc);
if (FAILED(hres)) {
cout << "Failed to create IWbemLocator object."
<< " Err code = 0x" << hex << hres << endl;
cout << "Failed to create IWbemLocator object."
<< " Err code = 0x" << hex << hres << endl;
CoUninitialize();
return 1; // Program has failed.
}
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
NULL, // User name. NULL = current user
@@ -327,6 +502,7 @@ int main() {
CoUninitialize();
return 1; // Program has failed.
}
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(hres)) {
cout << "Could not set proxy blanket. Error code = 0x"
@@ -338,38 +514,41 @@ int main() {
return 1; // Program has failed.
}
/* const char* QUERIES[] = {
"SELECT Name, Manufacturer, SocketDesignation, NumberOfCores, ThreadCount FROM Win32_Processor",
"SELECT Model, Size, SerialNumber FROM Win32_DiskDrive",
"SELECT Manufacturer, Product, SerialNumber FROM Win32_BaseBoard",
"SELECT Manufacturer, PartNumber, SerialNumber, Speed, Capacity FROM Win32_PhysicalMemory",
"SELECT Name, AdapterCompatibility, VideoMemoryType FROM win32_videocontroller"
}; */
const char* QUERIES[] = {
"SELECT * FROM Win32_Processor",
"SELECT * FROM Win32_DiskDrive",
"SELECT * FROM Win32_BaseBoard",
"SELECT * FROM MSFT_PhysicalDisk",
"SELECT * FROM Win32_PhysicalMemory",
"SELECT * FROM win32_videocontroller"
};
IEnumWbemClassObject* pEnumerator = NULL;
FILE* out;
fopen_s(&out, FILENAME, "w");
return 0;
}
if (out == NULL) {
cout << "failed to open meanspec-log.xml\n";
return 1;
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();
}
fprintf(out, "<meanspec version=\"%s\">\n<time>%s</time>\n", VERSION, getDateTimeString());
size_t crawlParts(const char* queries[], size_t queryCount, FILE* out) {
HRESULT hres;
IEnumWbemClassObject* pEnumerator = NULL;
wcout << L"\n데이터를 수집하는 중\n";
for (int i = 0; i < queryCount; i++) {
const char* QUERY = queries[i];
for (const char* QUERY : QUERIES) {
fprintf(out, "<search>\n <query>%s</query>\n", QUERY);
fprintf(out, "<search><query>%s</query>", QUERY);
bool isMsft = string(QUERY).find("MSFT") != string::npos;
hres = (isMsft ? pSvcStorage : pSvc)->ExecQuery(bstr_t("WQL"), bstr_t(QUERY), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
@@ -386,13 +565,13 @@ int main() {
BSTR* colName = NULL;
WCHAR BUFFER[1024] = { 0 };
fwprintf(out, L" <parts>\n");
fwprintf(out, L"<parts>");
while (pEnumerator) {
hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn) break;
fwprintf(out, L" <part>\n");
fwprintf(out, L"<part>");
wstring _gpuNameCandidate = L"";
wstring _gpuDriverVersionCandidate = L"";
@@ -421,11 +600,11 @@ int main() {
if (!isSkip && vtProp.bstrVal != nullptr) {
switch (vtProp.vt) {
case VT_BSTR: {
// std::wcout << vtProp.bstrVal << std::endl;
fwprintf(out, L" <%s>%s</%s>\n", bstrName, SafeXML(vtProp.bstrVal).c_str(), bstrName);
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;
@@ -434,19 +613,19 @@ int main() {
break;
}
case VT_INT: {
fwprintf(out, L" <%s>%d</%s>\n", bstrName, vtProp.intVal, bstrName);
fwprintf(out, L"<%s>%d</%s>", bstrName, vtProp.intVal, bstrName);
break;
}
case VT_I4: {
fwprintf(out, L" <%s>%ld</%s>\n", bstrName, vtProp.lVal, bstrName);
fwprintf(out, L"<%s>%ld</%s>", bstrName, vtProp.lVal, bstrName);
break;
}
case VT_BOOL: {
fwprintf(out, L" <%s>%s</%s>\n", bstrName, ((vtProp.boolVal) ? (L"true") : (L"false")), bstrName);
fwprintf(out, L"<%s>%s</%s>", bstrName, ((vtProp.boolVal) ? (L"true") : (L"false")), bstrName);
break;
}
default: {
fwprintf(out, L" <%s>(Unsupported type=%d)</%s>\n", bstrName, (int)vtProp.vt, bstrName);
fwprintf(out, L"<%s>(Unsupported type=%d)</%s>", bstrName, (int)vtProp.vt, bstrName);
}
}
}
@@ -461,49 +640,15 @@ int main() {
if (_gpuNameCandidate.size() > 0 && _gpuDriverVersionCandidate.size() > 0) {
ULONGLONG size = GetGpuMemorySizeByProperties(_gpuNameCandidate, _gpuDriverVersionCandidate);
if (size >= 0) {
fwprintf(out, L" <RegistryVRAMSize>%llu</RegistryVRAMSize>\n", size);
fwprintf(out, L"<RegistryVRAMSize>%llu</RegistryVRAMSize>", size);
}
}
fwprintf(out, L" </part>\n");
fwprintf(out, L"</part>");
}
fwprintf(out, L" </parts>\n</search>\n");
fwprintf(out, L"</parts></search>");
}
// Cleanup
// ========
pSvc->Release();
pSvcStorage->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();
fprintf(out, "</meanspec>\n");
fclose(out);
char path[1024] = { 0 };
auto _t = _getcwd(path, sizeof(path));
wcout << L"\n\n수집을 완료했습니다! meanspec-log.xml 파일을 제출해주세요\n";
wcout << L" 파일 위치: " << path << "\n\n";
snprintf(&path[strlen(path)], sizeof(path), "\\%s", FILENAME);
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;
wstring _arg(L"/select,");
_arg.append(lpctPath);
ShellExecute(NULL, L"open", L"explorer", _arg.c_str(), NULL, SW_SHOW);
wcout << L"문의: lee@enak.kr\n";
wcout << L"엔터를 눌러 프로그램 종료\n";
auto _f = getchar();
return 0;
return 1;
}
Loading