From 933836d4014d2d6893524ed617f7f7b748be23b2 Mon Sep 17 00:00:00 2001
From: Eunhak Lee <lee@enak.kr>
Date: Fri, 6 Dec 2024 18:56:06 +0900
Subject: [PATCH 1/7] =?UTF-8?q?feat:=20curl=20=EC=9D=84=20=ED=86=B5?=
 =?UTF-8?q?=ED=95=9C=20=EC=9A=94=EC=B2=AD=20=EC=A0=84=EC=86=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../meanspec-hwinfo-win64.cpp                 | 56 ++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
index a4e1ab0..37d2b40 100644
--- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
+++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
@@ -19,8 +19,18 @@
 #define FILENAME "meanspec-log.xml"
 #define VERSION "1.2"
 
+#ifndef CURL_STATICLIB
+#define CURL_STATICLIB
+#endif
+
+#pragma comment(lib, "libcurl-d.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>
+
 using namespace std;
 
 typedef void* voidptr;
@@ -226,10 +236,54 @@ std::string getDateTimeString() {
     return std::string(buffer);
 }
 
-int main() {
+std::string getCode(int argc, char *argv[]) {
+    if (argc < 2) return std::string("");
+    return std::string(argv[1]);
+}
+
+bool validateCode(std::string code) {
+    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_FOLLOWLOCATION, 1L);
+    curl_easy_setopt(handle, CURLOPT_HTTPHEADER, list);
+
+    CURLcode res = curl_easy_perform(handle);
+    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';
+    }
+
+    return true;
+}
+
+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";
+        return 1;
+    }
+
+    curl_global_init(CURL_GLOBAL_ALL);
+    bool result = validateCode(code);
+    curl_global_cleanup();
+
+    cout << "Result is " << result << '\n';
+
+    return 0;
+
     HRESULT hres;
     IWbemLocator* pLoc = NULL;
     IWbemServices* pSvc = NULL;
-- 
GitLab


From 97b47054f652b337e7f8bf0f4d43de9d4fa5caad Mon Sep 17 00:00:00 2001
From: Eunhak Lee <lee@enak.kr>
Date: Fri, 6 Dec 2024 18:57:09 +0900
Subject: [PATCH 2/7] chore: add libcurl static library

---
 .../meanspec-hwinfo-win64.vcxproj             | 24 +++++++++++++++----
 .../meanspec-hwinfo-win64.vcxproj.user        | 17 ++++++++++++-
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj
index d11cfa8..ee97bba 100644
--- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj
+++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj
@@ -99,32 +99,42 @@
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
+    <IncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\include;$(IncludePath)</IncludePath>
+    <ExternalIncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\lib;$(ExternalIncludePath)</ExternalIncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
     <LinkIncremental>true</LinkIncremental>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
+    <IncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\include;$(IncludePath)</IncludePath>
+    <ExternalIncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\lib;$(ExternalIncludePath)</ExternalIncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
     <LinkIncremental>false</LinkIncremental>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
+    <IncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\include;$(IncludePath)</IncludePath>
+    <ExternalIncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\lib;$(ExternalIncludePath)</ExternalIncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
+    <IncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\include;$(IncludePath)</IncludePath>
+    <ExternalIncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\lib;$(ExternalIncludePath)</ExternalIncludePath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>CURL_STATICLIB;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>C:\Tools\vcpkg\packages\curl_x86-windows\debug\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>libcurl-d.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
@@ -145,7 +155,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);CURL_STATICLIB</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
     </ClCompile>
     <Link>
@@ -153,6 +163,8 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>C:\Tools\vcpkg\packages\curl_x86-windows\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>libcurl.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
@@ -175,12 +187,14 @@
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions);CURL_STATICLIB</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>C:\Tools\vcpkg\packages\curl_x86-windows\debug\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>libcurl-d.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -189,7 +203,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions);CURL_STATICLIB</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
     </ClCompile>
     <Link>
@@ -197,6 +211,8 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>C:\Tools\vcpkg\packages\curl_x86-windows\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>libcurl.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj.user b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj.user
index 88a5509..bea9938 100644
--- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj.user
+++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj.user
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerCommandArguments>ASDF1234</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LocalDebuggerCommandArguments>ASDF1234</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LocalDebuggerCommandArguments>ASDF1234</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LocalDebuggerCommandArguments>ASDF1234</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
 </Project>
\ No newline at end of file
-- 
GitLab


From 2981bb8eb06bc36b804a428f30a94278a5e88c13 Mon Sep 17 00:00:00 2001
From: Eunhak Lee <lee@enak.kr>
Date: Fri, 6 Dec 2024 19:12:22 +0900
Subject: [PATCH 3/7] chore: separate WQL service initialization

---
 .../meanspec-hwinfo-win64.cpp                 | 258 +++++++++---------
 1 file changed, 135 insertions(+), 123 deletions(-)

diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
index 37d2b40..aece0b0 100644
--- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
+++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
@@ -266,6 +266,16 @@ bool validateCode(std::string code) {
     return true;
 }
 
+IWbemLocator* pLoc = NULL;
+IWbemServices* pSvc = NULL, * pSvcStorage = NULL;
+int initWQLServices();
+
+size_t crawlParts(const char *queries[], char *buffer, size_t bufferSize) {
+    size_t written = 0;
+
+    return written;
+}
+
 int main(int argc, char *argv[]) {
     setlocale(LC_ALL, "en_US.UTF-8");
     SetConsoleOutputCP(CP_UTF8);
@@ -280,117 +290,13 @@ int main(int argc, char *argv[]) {
     bool result = validateCode(code);
     curl_global_cleanup();
 
-    cout << "Result is " << result << '\n';
-
-    return 0;
-
-    HRESULT hres;
-    IWbemLocator* pLoc = NULL;
-    IWbemServices* pSvc = NULL;
-    IWbemServices* pSvcStorage = NULL;
-
-    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
-    if (FAILED(hres)) {
-        cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
-        return 1;                  // Program has failed.
-    }
-
-    hres = CoInitializeSecurity(
-        NULL,
-        -1,                          // COM authentication
-        NULL,                        // Authentication services
-        NULL,                        // Reserved
-        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
-        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
-        NULL,                        // Authentication info
-        EOAC_NONE,                   // Additional capabilities 
-        NULL                         // Reserved
-    );
-    if (FAILED(hres)) {
-        cout << "Failed to initialize security."
-             << " Error code = 0x" << hex << hres << endl;
-        CoUninitialize();
-        return 1;                    // Program has failed.
-    }
-
-    hres = CoCreateInstance(
-        CLSID_WbemLocator,
-        0,
-        CLSCTX_INPROC_SERVER,
-        IID_IWbemLocator, (LPVOID*)&pLoc);
-    if (FAILED(hres)) {
-        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
-        NULL,                    // User password. NULL = current
-        0,                       // Locale. NULL indicates current
-        NULL,                    // Security flags.
-        0,                       // Authority (for example, Kerberos)
-        0,                       // Context object 
-        &pSvc                    // pointer to IWbemServices proxy
-    );
-    if (FAILED(hres)) {
-        cout << "Could not connect. Error code = 0x"
-            << hex << hres << endl;
-        pLoc->Release();
-        CoUninitialize();
-        return 1;                // Program has failed.
-    }
-
-    hres = pLoc->ConnectServer(
-        _bstr_t(L"ROOT\\Microsoft\\Windows\\Storage"), // Object path of WMI namespace
-        NULL,                    // User name. NULL = current user
-        NULL,                    // User password. NULL = current
-        0,                       // Locale. NULL indicates current
-        NULL,                    // Security flags.
-        0,                       // Authority (for example, Kerberos)
-        0,                       // Context object 
-        &pSvcStorage             // pointer to IWbemServices proxy
-    );
-    if (FAILED(hres)) {
-        cout << "Could not connect. Error code = 0x"
-            << hex << hres << endl;
-        pLoc->Release();
-        CoUninitialize();
-        return 1;                // Program has failed.
+    int _initRes = initWQLServices();
+    if (_initRes != 0) {
+        wcout << L"WQL을 초기화하는데 실패했습니다. 문의를 남겨주시기 바랍니다.\n";
+        return _initRes;
     }
 
-
-    hres = CoSetProxyBlanket(
-        pSvc,                        // Indicates the proxy to set
-        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
-        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
-        NULL,                        // Server principal name 
-        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
-        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
-        NULL,                        // client identity
-        EOAC_NONE                    // proxy capabilities 
-    );
-    if (FAILED(hres)) {
-        cout << "Could not set proxy blanket. Error code = 0x"
-            << hex << hres << endl;
-        pSvc->Release();
-        pLoc->Release();
-        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"
-            << hex << hres << endl;
-        pSvc->Release();
-        pSvcStorage->Release();
-        pLoc->Release();
-        CoUninitialize();
-        return 1;               // Program has failed.
-    }
+    HRESULT hres;
 
     /* const char* QUERIES[] = {
         "SELECT Name, Manufacturer, SocketDesignation, NumberOfCores, ThreadCount FROM Win32_Processor",
@@ -418,12 +324,12 @@ int main(int argc, char *argv[]) {
         return 1;
     }
 
-    fprintf(out, "<meanspec version=\"%s\">\n<time>%s</time>\n", VERSION, getDateTimeString());
+    fprintf(out, "<meanspec version=\"%s\"><time>%s</time>", VERSION, getDateTimeString());
 
     wcout << L"\n데이터를 수집하는 중\n";
 
     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);
 
@@ -440,13 +346,13 @@ int main(int argc, char *argv[]) {
         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"";
@@ -475,8 +381,7 @@ int main(int argc, char *argv[]) {
                         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) {
                                     _gpuNameCandidate = vtProp.bstrVal;
@@ -488,19 +393,19 @@ int main(int argc, char *argv[]) {
                                 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);
                             }
                             }
                         }
@@ -515,14 +420,13 @@ int main(int argc, char *argv[]) {
             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
@@ -561,3 +465,111 @@ int main(int argc, char *argv[]) {
 
     return 0;
 }
+
+int initWQLServices() {
+    HRESULT hres;
+
+    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
+    if (FAILED(hres)) {
+        cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
+        return 1;                  // Program has failed.
+    }
+
+    hres = CoInitializeSecurity(
+        NULL,
+        -1,                          // COM authentication
+        NULL,                        // Authentication services
+        NULL,                        // Reserved
+        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
+        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
+        NULL,                        // Authentication info
+        EOAC_NONE,                   // Additional capabilities 
+        NULL                         // Reserved
+    );
+    if (FAILED(hres)) {
+        cout << "Failed to initialize security."
+            << " Error code = 0x" << hex << hres << endl;
+        CoUninitialize();
+        return 1;                    // Program has failed.
+    }
+
+    hres = CoCreateInstance(
+        CLSID_WbemLocator,
+        0,
+        CLSCTX_INPROC_SERVER,
+        IID_IWbemLocator, (LPVOID*)&pLoc);
+    if (FAILED(hres)) {
+        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
+        NULL,                    // User password. NULL = current
+        0,                       // Locale. NULL indicates current
+        NULL,                    // Security flags.
+        0,                       // Authority (for example, Kerberos)
+        0,                       // Context object 
+        &pSvc                    // pointer to IWbemServices proxy
+    );
+    if (FAILED(hres)) {
+        cout << "Could not connect. Error code = 0x"
+            << hex << hres << endl;
+        pLoc->Release();
+        CoUninitialize();
+        return 1;                // Program has failed.
+    }
+
+    hres = pLoc->ConnectServer(
+        _bstr_t(L"ROOT\\Microsoft\\Windows\\Storage"), // Object path of WMI namespace
+        NULL,                    // User name. NULL = current user
+        NULL,                    // User password. NULL = current
+        0,                       // Locale. NULL indicates current
+        NULL,                    // Security flags.
+        0,                       // Authority (for example, Kerberos)
+        0,                       // Context object 
+        &pSvcStorage             // pointer to IWbemServices proxy
+    );
+    if (FAILED(hres)) {
+        cout << "Could not connect. Error code = 0x"
+            << hex << hres << endl;
+        pLoc->Release();
+        CoUninitialize();
+        return 1;                // Program has failed.
+    }
+
+
+    hres = CoSetProxyBlanket(
+        pSvc,                        // Indicates the proxy to set
+        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
+        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
+        NULL,                        // Server principal name 
+        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
+        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
+        NULL,                        // client identity
+        EOAC_NONE                    // proxy capabilities 
+    );
+    if (FAILED(hres)) {
+        cout << "Could not set proxy blanket. Error code = 0x"
+            << hex << hres << endl;
+        pSvc->Release();
+        pLoc->Release();
+        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"
+            << hex << hres << endl;
+        pSvc->Release();
+        pSvcStorage->Release();
+        pLoc->Release();
+        CoUninitialize();
+        return 1;               // Program has failed.
+    }
+
+    return 0;
+}
-- 
GitLab


From afc76e9ec6f4ab8a8c71bdab28d34ffdbe12f4eb Mon Sep 17 00:00:00 2001
From: Eunhak Lee <lee@enak.kr>
Date: Sat, 7 Dec 2024 15:09:35 +0900
Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=EC=A0=9C=EC=B6=9C=20=EA=B8=B0?=
 =?UTF-8?q?=EB=8A=A5=20=EB=A7=88=EB=AC=B4=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../meanspec-hwinfo-win64.cpp                 | 137 ++++++++++++++----
 1 file changed, 109 insertions(+), 28 deletions(-)

diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
index aece0b0..9b11e27 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();
+}
-- 
GitLab


From 4e1d8ae9e6ed1581101228cd18e1f36308bea956 Mon Sep 17 00:00:00 2001
From: Eunhak Lee <lee@enak.kr>
Date: Sat, 7 Dec 2024 15:14:36 +0900
Subject: [PATCH 5/7] =?UTF-8?q?chore:=20=EC=BD=94=EB=93=9C=20=EA=B0=9C?=
 =?UTF-8?q?=EC=84=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../meanspec-hwinfo-win64.cpp                 | 246 +++++++++---------
 1 file changed, 119 insertions(+), 127 deletions(-)

diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
index 9b11e27..75bdbaa 100644
--- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
+++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
@@ -17,13 +17,13 @@
 #include <shlobj_core.h>
 
 #define FILENAME "meanspec-log.xml"
-#define VERSION "1.2"
+#define VERSION "1.3"
 
 #ifndef CURL_STATICLIB
 #define CURL_STATICLIB
 #endif
 
-#pragma comment(lib, "libcurl-d.lib")
+#pragma comment(lib, "libcurl.lib")
 #pragma comment(lib, "wldap32.lib")
 #pragma comment(lib, "ws2_32.lib")
 #pragma comment(lib, "wbemuuid.lib")
@@ -316,12 +316,7 @@ bool submitParts(std::string code, char* xml) {
 IWbemLocator* pLoc = NULL;
 IWbemServices* pSvc = NULL, * pSvcStorage = NULL;
 int initWQLServices();
-
-size_t crawlParts(const char *queries[], char *buffer, size_t bufferSize) {
-    size_t written = 0;
-
-    return written;
-}
+size_t crawlParts(const char* queries[], size_t queryCount, FILE* out);
 
 int main(int argc, char *argv[]) {
     setlocale(LC_ALL, "en_US.UTF-8");
@@ -339,15 +334,6 @@ int main(int argc, char *argv[]) {
         return _initRes;
     }
 
-    HRESULT hres;
-
-    /* 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",
@@ -357,8 +343,6 @@ int main(int argc, char *argv[]) {
         "SELECT * FROM Win32_VideoController"
     };
 
-    IEnumWbemClassObject* pEnumerator = NULL;
-
     FILE* out;
     fopen_s(&out, FILENAME, "w");
 
@@ -367,111 +351,11 @@ int main(int argc, char *argv[]) {
         return 1;
     }
 
-    fprintf(out, "<meanspec version=\"%s\"><time>%s</time>", VERSION, getDateTimeString().c_str());
-
     wcout << L"\n데이터를 수집하는 중\n";
-
-    for (const char* QUERY : QUERIES) {
-        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);
-
-        if (FAILED(hres))
-        {
-            cout << "Query for operating system name failed."
-                << " Error code = 0x"
-                << hex << hres << endl;
-            continue;
-        }
-
-        IWbemClassObject* pclsObj = NULL;
-        ULONG uReturn = 0;
-        BSTR* colName = NULL;
-        WCHAR BUFFER[1024] = { 0 };
-
-        fwprintf(out, L"<parts>");
-
-        while (pEnumerator) {
-            hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
-            if (0 == uReturn) break;
-
-            fwprintf(out, L"<part>");
-
-            wstring _gpuNameCandidate = L"";
-            wstring _gpuDriverVersionCandidate = L"";
-
-            SAFEARRAY* psaNames;
-            hres = pclsObj->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, NULL, &psaNames);
-            if (SUCCEEDED(hres)) {
-                long lLower, lUpper;
-                SafeArrayGetLBound(psaNames, 1, &lLower);
-                SafeArrayGetUBound(psaNames, 1, &lUpper);
-
-                for (long i = lLower; i <= lUpper; i++) {
-                    BSTR bstrName;
-                    SafeArrayGetElement(psaNames, &i, &bstrName);
-
-                    VARIANT vtProp;
-                    hres = pclsObj->Get(bstrName, 0, &vtProp, 0, 0);
-                    if (SUCCEEDED(hres)) {
-                        bool isSkip = false;
-
-                        // 시스템 이름은 넣지 않음
-                        if (wcscmp(bstrName, L"SystemName") == 0) {
-                            isSkip = true;
-                        }
-
-                        if (!isSkip && vtProp.bstrVal != nullptr) {
-                            switch (vtProp.vt) {
-                            case VT_BSTR: {
-                                fwprintf(out, L"<%s>%s</%s>", bstrName, SafeXML(vtProp.bstrVal).c_str(), bstrName);
-
-                                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;
-                                }
-
-                                break;
-                            }
-                            case VT_INT: {
-                                fwprintf(out, L"<%s>%d</%s>", bstrName, vtProp.intVal, bstrName);
-                                break;
-                            }
-                            case VT_I4: {
-                                fwprintf(out, L"<%s>%ld</%s>", bstrName, vtProp.lVal, bstrName);
-                                break;
-                            }
-                            case VT_BOOL: {
-                                fwprintf(out, L"<%s>%s</%s>", bstrName, ((vtProp.boolVal) ? (L"true") : (L"false")), bstrName);
-                                break;
-                            }
-                            default: {
-                                fwprintf(out, L"<%s>(Unsupported type=%d)</%s>", bstrName, (int)vtProp.vt, bstrName);
-                            }
-                            }
-                        }
-                        VariantClear(&vtProp);
-                    }
-                    SysFreeString(bstrName);
-                }
-                SafeArrayDestroy(psaNames);
-            }
-            pclsObj->Release();
-
-            if (_gpuNameCandidate.size() > 0 && _gpuDriverVersionCandidate.size() > 0) {
-                ULONGLONG size = GetGpuMemorySizeByProperties(_gpuNameCandidate, _gpuDriverVersionCandidate);
-                if (size >= 0) {
-                    fwprintf(out, L"<RegistryVRAMSize>%llu</RegistryVRAMSize>", size);
-                }
-            }
-            fwprintf(out, L"</part>");
-        }
-
-        fwprintf(out, L"</parts></search>");
-    }
+    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
     // ========
@@ -479,12 +363,8 @@ int main(int argc, char *argv[]) {
     pSvc->Release();
     pSvcStorage->Release();
     pLoc->Release();
-    pEnumerator->Release();
     CoUninitialize();
 
-    fprintf(out, "</meanspec>\n");
-    fclose(out);
-
     FILE* in;
     fopen_s(&in, FILENAME, "r");
 
@@ -654,3 +534,115 @@ std::string escape_json(const std::string& s) {
     }
     return o.str();
 }
+
+size_t crawlParts(const char* queries[], size_t queryCount, FILE* out) {
+    HRESULT hres;
+    IEnumWbemClassObject* pEnumerator = NULL;
+
+    for (int i = 0; i < queryCount; i++) {
+        const char* QUERY = queries[i];
+
+        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);
+
+        if (FAILED(hres))
+        {
+            cout << "Query for operating system name failed."
+                << " Error code = 0x"
+                << hex << hres << endl;
+            continue;
+        }
+
+        IWbemClassObject* pclsObj = NULL;
+        ULONG uReturn = 0;
+        BSTR* colName = NULL;
+        WCHAR BUFFER[1024] = { 0 };
+
+        fwprintf(out, L"<parts>");
+
+        while (pEnumerator) {
+            hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+            if (0 == uReturn) break;
+
+            fwprintf(out, L"<part>");
+
+            wstring _gpuNameCandidate = L"";
+            wstring _gpuDriverVersionCandidate = L"";
+
+            SAFEARRAY* psaNames;
+            hres = pclsObj->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, NULL, &psaNames);
+            if (SUCCEEDED(hres)) {
+                long lLower, lUpper;
+                SafeArrayGetLBound(psaNames, 1, &lLower);
+                SafeArrayGetUBound(psaNames, 1, &lUpper);
+
+                for (long i = lLower; i <= lUpper; i++) {
+                    BSTR bstrName;
+                    SafeArrayGetElement(psaNames, &i, &bstrName);
+
+                    VARIANT vtProp;
+                    hres = pclsObj->Get(bstrName, 0, &vtProp, 0, 0);
+                    if (SUCCEEDED(hres)) {
+                        bool isSkip = false;
+
+                        // 시스템 이름은 넣지 않음
+                        if (wcscmp(bstrName, L"SystemName") == 0) {
+                            isSkip = true;
+                        }
+
+                        if (!isSkip && vtProp.bstrVal != nullptr) {
+                            switch (vtProp.vt) {
+                            case VT_BSTR: {
+                                fwprintf(out, L"<%s>%s</%s>", bstrName, SafeXML(vtProp.bstrVal).c_str(), bstrName);
+
+                                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;
+                                }
+
+                                break;
+                            }
+                            case VT_INT: {
+                                fwprintf(out, L"<%s>%d</%s>", bstrName, vtProp.intVal, bstrName);
+                                break;
+                            }
+                            case VT_I4: {
+                                fwprintf(out, L"<%s>%ld</%s>", bstrName, vtProp.lVal, bstrName);
+                                break;
+                            }
+                            case VT_BOOL: {
+                                fwprintf(out, L"<%s>%s</%s>", bstrName, ((vtProp.boolVal) ? (L"true") : (L"false")), bstrName);
+                                break;
+                            }
+                            default: {
+                                fwprintf(out, L"<%s>(Unsupported type=%d)</%s>", bstrName, (int)vtProp.vt, bstrName);
+                            }
+                            }
+                        }
+                        VariantClear(&vtProp);
+                    }
+                    SysFreeString(bstrName);
+                }
+                SafeArrayDestroy(psaNames);
+            }
+            pclsObj->Release();
+
+            if (_gpuNameCandidate.size() > 0 && _gpuDriverVersionCandidate.size() > 0) {
+                ULONGLONG size = GetGpuMemorySizeByProperties(_gpuNameCandidate, _gpuDriverVersionCandidate);
+                if (size >= 0) {
+                    fwprintf(out, L"<RegistryVRAMSize>%llu</RegistryVRAMSize>", size);
+                }
+            }
+            fwprintf(out, L"</part>");
+        }
+
+        fwprintf(out, L"</parts></search>");
+    }
+    pEnumerator->Release();
+
+    return 1;
+}
-- 
GitLab


From 33ffe89d77c56b383b3f6490c6581378bf778099 Mon Sep 17 00:00:00 2001
From: Eunhak Lee <lee@enak.kr>
Date: Sat, 7 Dec 2024 15:50:19 +0900
Subject: [PATCH 6/7] =?UTF-8?q?fix:=20static=20lib=20linking=20=EC=9C=BC?=
 =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../meanspec-hwinfo-win64.cpp                 |  3 ++-
 .../meanspec-hwinfo-win64.vcxproj             | 23 ++++++++++++++-----
 .../meanspec-hwinfo-win64.vcxproj.user        |  8 +++----
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
index 75bdbaa..de0ad5e 100644
--- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
+++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
@@ -17,12 +17,13 @@
 #include <shlobj_core.h>
 
 #define FILENAME "meanspec-log.xml"
-#define VERSION "1.3"
+#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")
diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj
index ee97bba..40a3580 100644
--- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj
+++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj
@@ -107,8 +107,8 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
-    <IncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\include;$(IncludePath)</IncludePath>
-    <ExternalIncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\lib;$(ExternalIncludePath)</ExternalIncludePath>
+    <IncludePath>C:\Tools\vcpkg\packages\curl_x86-windows-static\include;$(IncludePath)</IncludePath>
+    <ExternalIncludePath>C:\Tools\vcpkg\packages\curl_x86-windows-static\lib;$(ExternalIncludePath)</ExternalIncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
     <LinkIncremental>false</LinkIncremental>
@@ -120,8 +120,17 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
-    <IncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\include;$(IncludePath)</IncludePath>
-    <ExternalIncludePath>C:\Tools\vcpkg\packages\curl_x86-windows\lib;$(ExternalIncludePath)</ExternalIncludePath>
+    <IncludePath>C:\Tools\vcpkg\packages\curl_x86-windows-static\include;$(IncludePath)</IncludePath>
+    <ExternalIncludePath>C:\Tools\vcpkg\packages\curl_x86-windows-static\lib;$(ExternalIncludePath)</ExternalIncludePath>
+  </PropertyGroup>
+  <PropertyGroup Label="Vcpkg">
+    <VcpkgApplocalDeps>false</VcpkgApplocalDeps>
+  </PropertyGroup>
+  <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <VcpkgUseStatic>true</VcpkgUseStatic>
+  </PropertyGroup>
+  <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <VcpkgUseStatic>true</VcpkgUseStatic>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -157,13 +166,14 @@
       <SDLCheck>true</SDLCheck>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);CURL_STATICLIB</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>C:\Tools\vcpkg\packages\curl_x86-windows\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>C:\Tools\vcpkg\packages\curl_x86-windows-static\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>libcurl.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
@@ -205,13 +215,14 @@
       <SDLCheck>true</SDLCheck>
       <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions);CURL_STATICLIB</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>C:\Tools\vcpkg\packages\curl_x86-windows\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>C:\Tools\vcpkg\packages\curl_x86-windows-static\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>libcurl.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj.user b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj.user
index bea9938..b8fcd50 100644
--- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj.user
+++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.vcxproj.user
@@ -1,19 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LocalDebuggerCommandArguments>ASDF1234</LocalDebuggerCommandArguments>
+    <LocalDebuggerCommandArguments>OO2V31LJ178Y</LocalDebuggerCommandArguments>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerCommandArguments>ASDF1234</LocalDebuggerCommandArguments>
+    <LocalDebuggerCommandArguments>OO2V31LJ178Y</LocalDebuggerCommandArguments>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LocalDebuggerCommandArguments>ASDF1234</LocalDebuggerCommandArguments>
+    <LocalDebuggerCommandArguments>OO2V31LJ178Y</LocalDebuggerCommandArguments>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LocalDebuggerCommandArguments>ASDF1234</LocalDebuggerCommandArguments>
+    <LocalDebuggerCommandArguments>OO2V31LJ178Y</LocalDebuggerCommandArguments>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
 </Project>
\ No newline at end of file
-- 
GitLab


From f0132322e276bf4794e269ff7d83e8b54edbee24 Mon Sep 17 00:00:00 2001
From: Eunhak Lee <lee@enak.kr>
Date: Sat, 7 Dec 2024 15:52:21 +0900
Subject: [PATCH 7/7] =?UTF-8?q?chore:=20=EC=98=A4=EB=A5=98=20=EB=A9=94?=
 =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=9C=EB=A0=A5=20=ED=9B=84=20=ED=94=84?=
 =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EB=9E=A8=EC=9D=B4=20=EB=B0=94=EB=A1=9C=20?=
 =?UTF-8?q?=EC=A2=85=EB=A3=8C=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8F=84?=
 =?UTF-8?q?=EB=A1=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
index de0ad5e..da67189 100644
--- a/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
+++ b/meanspec-hwinfo-win64/meanspec-hwinfo-win64.cpp
@@ -326,12 +326,14 @@ int main(int argc, char *argv[]) {
     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;
     }
 
@@ -371,6 +373,7 @@ int main(int argc, char *argv[]) {
 
     if (in == NULL) {
         fwprintf(stderr, L"수집에 성공하였으나 자료를 정리하는데 실패했습니다\n");
+        getchar();
         return 2;
     }
 
@@ -382,6 +385,7 @@ int main(int argc, char *argv[]) {
     char* xmlBuffer = (char*)malloc(_bufferSize);
     if (xmlBuffer == NULL) {
         fwprintf(stderr, L"버퍼를 초기화하지 못했습니다\n");
+        getchar();
         return 3;
     }
 
@@ -390,6 +394,7 @@ int main(int argc, char *argv[]) {
     size_t read_bytes = fread((void*)xmlBuffer, 1, lSize, in);
     if (read_bytes != lSize - 1) {
         fwprintf(stderr, L"자료 파일이 손상되었습니다\n");
+        getchar();
         return 4;
     }
 
@@ -399,7 +404,7 @@ int main(int argc, char *argv[]) {
 
     wcout << L"문의: lee@enak.kr\n";
     wcout << L"엔터를 눌러 프로그램 종료\n";
-    auto _f = getchar();
+    getchar();
 
     return 0;
 }
-- 
GitLab