diff --git a/plugins/sysinfo/sysinfo.vcxproj b/plugins/sysinfo/sysinfo.vcxproj index d130bc0c..b1c7c8f0 100644 --- a/plugins/sysinfo/sysinfo.vcxproj +++ b/plugins/sysinfo/sysinfo.vcxproj @@ -36,7 +36,7 @@ $(DepsRoot)\lib;%(AdditionalLibraryDirectories) - wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies) + $(HexChatLib)common.lib;wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies) comsupp.lib sysinfo.def @@ -49,7 +49,7 @@ $(DepsRoot)\lib;%(AdditionalLibraryDirectories) - wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies) + $(HexChatLib)common.lib;wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies) comsupp.lib sysinfo.def @@ -68,4 +68,4 @@ - + \ No newline at end of file diff --git a/plugins/sysinfo/win32/backend.c b/plugins/sysinfo/win32/backend.c index 2451c122..446bc252 100644 --- a/plugins/sysinfo/win32/backend.c +++ b/plugins/sysinfo/win32/backend.c @@ -26,38 +26,18 @@ #include -#include "../format.h" +#include "../../../src/common/sysinfo/sysinfo.h" -/* Cache the info for subsequent invocations of /SYSINFO */ -static int cpu_arch = 0; -static char *os_name = NULL; -static char *cpu_info = NULL; -static char *vga_name = NULL; +#include "../format.h" static int command_callback (char *word[], char *word_eol[], void *user_data); -typedef enum -{ - QUERY_WMI_OS, - QUERY_WMI_CPU, - QUERY_WMI_VGA, - QUERY_WMI_HDD, -} QueryWmiType; - void print_info (void); -int get_cpu_arch (void); -char *query_wmi (QueryWmiType mode); -char *read_os_name (IWbemClassObject *object); -char *read_cpu_info (IWbemClassObject *object); -char *read_vga_name (IWbemClassObject *object); guint64 hdd_capacity; guint64 hdd_free_space; char *read_hdd_info (IWbemClassObject *object); - char *get_memory_info (void); -char *bstr_to_utf8 (BSTR bstr); -guint64 variant_to_uint64 (VARIANT *variant); char * sysinfo_backend_get_sound (void) @@ -80,14 +60,15 @@ sysinfo_backend_get_uptime (void) char * sysinfo_backend_get_disk (void) { - char *hdd_info; + guint64 hdd_capacity; + guint64 hdd_free_space; - /* HDD information is always loaded dynamically since it includes the current amount of free space */ - hdd_capacity = 0; - hdd_free_space = 0; - hdd_info = query_wmi (QUERY_WMI_HDD); - if (hdd_info) - return sysinfo_format_disk (hdd_capacity, hdd_free_space); + sysinfo_get_hdd_info (&hdd_capacity, &hdd_free_space); + + if (hdd_capacity != 0) + { + return sysinfo_format_disk(hdd_capacity, hdd_free_space); + } return NULL; } @@ -95,10 +76,7 @@ sysinfo_backend_get_disk (void) char * sysinfo_backend_get_cpu (void) { - if (cpu_info == NULL) - cpu_info = query_wmi (QUERY_WMI_CPU); - - return g_strdup (cpu_info); + return sysinfo_get_cpu (); } char * @@ -111,352 +89,18 @@ sysinfo_backend_get_memory (void) char * sysinfo_backend_get_gpu (void) { - if (vga_name == NULL) - vga_name = query_wmi (QUERY_WMI_VGA); - - return g_strdup (vga_name); + return sysinfo_get_gpu (); } char * sysinfo_backend_get_os (void) { - if (os_name == NULL) - os_name = query_wmi (QUERY_WMI_OS); - - if (cpu_arch == 0) - cpu_arch = get_cpu_arch (); - - return g_strdup_printf ("%s (x%d)", os_name, cpu_arch); + return sysinfo_get_os (); } static int get_cpu_arch (void) { - SYSTEM_INFO si; - - GetNativeSystemInfo (&si); - - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - { - return 64; - } - else - { - return 86; - } -} - -/* http://msdn.microsoft.com/en-us/site/aa390423 */ -static char *query_wmi (QueryWmiType type) -{ - GString *result = NULL; - HRESULT hr; - - IWbemLocator *locator = NULL; - BSTR namespaceName = NULL; - BSTR queryLanguageName = NULL; - BSTR query = NULL; - IWbemServices *namespace = NULL; - IUnknown *namespaceUnknown = NULL; - IEnumWbemClassObject *enumerator = NULL; - int i; - gboolean atleast_one_appended = FALSE; - - hr = CoCreateInstance (&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (LPVOID *) &locator); - if (FAILED (hr)) - { - goto exit; - } - - namespaceName = SysAllocString (L"root\\CIMV2"); - - hr = locator->lpVtbl->ConnectServer (locator, namespaceName, NULL, NULL, NULL, 0, NULL, NULL, &namespace); - if (FAILED (hr)) - { - goto release_locator; - } - - hr = namespace->lpVtbl->QueryInterface (namespace, &IID_IUnknown, &namespaceUnknown); - if (FAILED (hr)) - { - goto release_namespace; - } - - hr = CoSetProxyBlanket (namespaceUnknown, 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)) - { - goto release_namespaceUnknown; - } - - queryLanguageName = SysAllocString (L"WQL"); - - switch (type) - { - case QUERY_WMI_OS: - query = SysAllocString (L"SELECT Caption FROM Win32_OperatingSystem"); - break; - case QUERY_WMI_CPU: - query = SysAllocString (L"SELECT Name, MaxClockSpeed FROM Win32_Processor"); - break; - case QUERY_WMI_VGA: - query = SysAllocString (L"SELECT Name FROM Win32_VideoController"); - break; - case QUERY_WMI_HDD: - query = SysAllocString (L"SELECT Name, Capacity, FreeSpace FROM Win32_Volume"); - break; - default: - goto release_queryLanguageName; - } - - hr = namespace->lpVtbl->ExecQuery (namespace, queryLanguageName, query, WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator); - if (FAILED (hr)) - { - goto release_query; - } - - result = g_string_new (""); - - for (i = 0;; i++) - { - ULONG numReturned = 0; - IWbemClassObject *object; - char *line; - - hr = enumerator->lpVtbl->Next (enumerator, WBEM_INFINITE, 1, &object, &numReturned); - if (FAILED (hr) || numReturned == 0) - { - break; - } - - switch (type) - { - case QUERY_WMI_OS: - line = read_os_name (object); - break; - - case QUERY_WMI_CPU: - line = read_cpu_info (object); - break; - - case QUERY_WMI_VGA: - line = read_vga_name (object); - break; - - case QUERY_WMI_HDD: - line = read_hdd_info (object); - break; - - default: - break; - } - - object->lpVtbl->Release (object); - - if (line != NULL) - { - if (atleast_one_appended) - { - g_string_append (result, ", "); - } - - g_string_append (result, line); - - g_free (line); - - atleast_one_appended = TRUE; - } - } - - enumerator->lpVtbl->Release (enumerator); - -release_query: - SysFreeString (query); - -release_queryLanguageName: - SysFreeString (queryLanguageName); - -release_namespaceUnknown: - namespaceUnknown->lpVtbl->Release (namespaceUnknown); - -release_namespace: - namespace->lpVtbl->Release (namespace); - -release_locator: - locator->lpVtbl->Release (locator); - SysFreeString (namespaceName); - -exit: - if (result == NULL) - { - return NULL; - } - - return g_string_free (result, FALSE); -} - -static char *read_os_name (IWbemClassObject *object) -{ - HRESULT hr; - VARIANT caption_variant; - char *caption_utf8; - - hr = object->lpVtbl->Get (object, L"Caption", 0, &caption_variant, NULL, NULL); - if (FAILED (hr)) - { - return NULL; - } - - caption_utf8 = bstr_to_utf8 (caption_variant.bstrVal); - - VariantClear(&caption_variant); - - if (caption_utf8 == NULL) - { - return NULL; - } - - g_strchomp (caption_utf8); - - return caption_utf8; -} - -static char *read_cpu_info (IWbemClassObject *object) -{ - HRESULT hr; - VARIANT name_variant; - char *name_utf8; - VARIANT max_clock_speed_variant; - guint cpu_freq_mhz; - char *result; - - hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL); - if (FAILED (hr)) - { - return NULL; - } - - name_utf8 = bstr_to_utf8 (name_variant.bstrVal); - - VariantClear (&name_variant); - - if (name_utf8 == NULL) - { - return NULL; - } - - hr = object->lpVtbl->Get (object, L"MaxClockSpeed", 0, &max_clock_speed_variant, NULL, NULL); - if (FAILED (hr)) - { - g_free (name_utf8); - - return NULL; - } - - cpu_freq_mhz = max_clock_speed_variant.uintVal; - - VariantClear (&max_clock_speed_variant); - - if (cpu_freq_mhz > 1000) - { - result = g_strdup_printf ("%s (%.2fGHz)", name_utf8, cpu_freq_mhz / 1000.f); - } - else - { - result = g_strdup_printf ("%s (%" G_GUINT32_FORMAT "MHz)", name_utf8, cpu_freq_mhz); - } - - g_free (name_utf8); - - return result; -} - -static char *read_vga_name (IWbemClassObject *object) -{ - HRESULT hr; - VARIANT name_variant; - char *name_utf8; - - hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL); - if (FAILED (hr)) - { - return NULL; - } - - name_utf8 = bstr_to_utf8 (name_variant.bstrVal); - - VariantClear (&name_variant); - - if (name_utf8 == NULL) - { - return NULL; - } - - return g_strchomp (name_utf8); -} - -static char *read_hdd_info (IWbemClassObject *object) -{ - HRESULT hr; - VARIANT name_variant; - BSTR name_bstr; - gsize name_len; - VARIANT capacity_variant; - guint64 capacity; - VARIANT free_space_variant; - guint64 free_space; - - hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL); - if (FAILED (hr)) - { - return NULL; - } - - name_bstr = name_variant.bstrVal; - name_len = SysStringLen (name_variant.bstrVal); - - if (name_len >= 4 && name_bstr[0] == L'\\' && name_bstr[1] == L'\\' && name_bstr[2] == L'?' && name_bstr[3] == L'\\') - { - // This is not a named volume. Skip it. - VariantClear (&name_variant); - - return NULL; - } - - VariantClear (&name_variant); - - hr = object->lpVtbl->Get (object, L"Capacity", 0, &capacity_variant, NULL, NULL); - if (FAILED (hr)) - { - return NULL; - } - - capacity = variant_to_uint64 (&capacity_variant); - - VariantClear (&capacity_variant); - - if (capacity == 0) - { - return NULL; - } - - hr = object->lpVtbl->Get (object, L"FreeSpace", 0, &free_space_variant, NULL, NULL); - if (FAILED (hr)) - { - return NULL; - } - - free_space = variant_to_uint64 (&free_space_variant); - - VariantClear (&free_space_variant); - - if (free_space == 0) - { - return NULL; - } - - hdd_capacity += capacity; - hdd_free_space += free_space; - - return NULL; + return sysinfo_get_cpu_arch (); } static char *get_memory_info (void) @@ -471,23 +115,3 @@ static char *get_memory_info (void) return sysinfo_format_memory (meminfo.ullTotalPhys, meminfo.ullAvailPhys); } - -static char *bstr_to_utf8 (BSTR bstr) -{ - return g_utf16_to_utf8 (bstr, SysStringLen (bstr), NULL, NULL, NULL); -} - -static guint64 variant_to_uint64 (VARIANT *variant) -{ - switch (V_VT (variant)) - { - case VT_UI8: - return variant->ullVal; - - case VT_BSTR: - return wcstoull (variant->bstrVal, NULL, 10); - - default: - return 0; - } -} diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index 5c7f2715..1d1fc570 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj @@ -36,6 +36,7 @@ + @@ -68,6 +69,7 @@ + diff --git a/src/common/common.vcxproj.filters b/src/common/common.vcxproj.filters index 79e64cb4..db696eb9 100644 --- a/src/common/common.vcxproj.filters +++ b/src/common/common.vcxproj.filters @@ -9,6 +9,12 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd + + {d5a3d281-8400-4663-b60d-036ade5fbff7} + + + {a6d80da7-bc0a-4f1f-a156-c8cdafb7831d} + @@ -110,6 +116,9 @@ Header Files + + Source Files\sysinfo + @@ -187,6 +196,9 @@ Source Files + + Source Files\sysinfo\win32 + diff --git a/src/common/sysinfo/sysinfo.h b/src/common/sysinfo/sysinfo.h new file mode 100644 index 00000000..d63bf9d8 --- /dev/null +++ b/src/common/sysinfo/sysinfo.h @@ -0,0 +1,13 @@ +#ifndef HEXCHAT_SYSINFO_H +#define HEXCHAT_SYSINFO_H + +#include + +int sysinfo_get_cpu_arch (void); +int sysinfo_get_build_arch (void); +char *sysinfo_get_cpu (void); +char *sysinfo_get_os (void); +void sysinfo_get_hdd_info (guint64 *hdd_capacity_out, guint64 *hdd_free_space_out); +char *sysinfo_get_gpu (void); + +#endif diff --git a/src/common/sysinfo/win32/backend.c b/src/common/sysinfo/win32/backend.c new file mode 100644 index 00000000..c4e686a7 --- /dev/null +++ b/src/common/sysinfo/win32/backend.c @@ -0,0 +1,478 @@ +/* HexChat + * Copyright (c) 2011-2012 Berke Viktor. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include + +#include "../sysinfo.h" + +/* Cache */ +static int cpu_arch = 0; +static int build_arch = 0; +static char *os_name = NULL; +static char *cpu_info = NULL; +static char *vga_name = NULL; + +typedef enum +{ + QUERY_WMI_OS, + QUERY_WMI_CPU, + QUERY_WMI_VGA, + QUERY_WMI_HDD, +} QueryWmiType; + +char *query_wmi (QueryWmiType mode); +char *read_os_name (IWbemClassObject *object); +char *read_cpu_info (IWbemClassObject *object); +char *read_vga_name (IWbemClassObject *object); + +guint64 hdd_capacity; +guint64 hdd_free_space; +char *read_hdd_info (IWbemClassObject *object); + +char *bstr_to_utf8 (BSTR bstr); +guint64 variant_to_uint64 (VARIANT *variant); + +char * +sysinfo_get_cpu (void) +{ + if (cpu_info == NULL) + cpu_info = query_wmi (QUERY_WMI_CPU); + + return g_strdup (cpu_info); +} + +char * +sysinfo_get_os (void) +{ + if (os_name == NULL) + os_name = query_wmi (QUERY_WMI_OS); + + return g_strdup_printf ("%s (x%d)", os_name, sysinfo_get_cpu_arch ()); +} + +int +sysinfo_get_cpu_arch (void) +{ + SYSTEM_INFO si; + + if (cpu_arch != 0) + { + return cpu_arch; + } + + GetNativeSystemInfo (&si); + + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + { + return cpu_arch = 64; + } + else + { + return cpu_arch = 86; + } +} + +int +sysinfo_get_build_arch (void) +{ + SYSTEM_INFO si; + + if (build_arch != 0) + { + return build_arch; + } + + GetSystemInfo (&si); + + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + { + return build_arch = 64; + } + else + { + return build_arch = 86; + } +} + +char * +sysinfo_get_gpu (void) +{ + if (vga_name == NULL) + vga_name = query_wmi (QUERY_WMI_VGA); + + return g_strdup (vga_name); +} + +void +sysinfo_get_hdd_info (guint64 *hdd_capacity_out, guint64 *hdd_free_space_out) +{ + char *hdd_info; + + /* HDD information is always loaded dynamically since it includes the current amount of free space */ + *hdd_capacity_out = hdd_capacity = 0; + *hdd_free_space_out = hdd_free_space = 0; + + hdd_info = query_wmi (QUERY_WMI_HDD); + if (hdd_info == NULL) + { + return; + } + + *hdd_capacity_out = hdd_capacity; + *hdd_free_space_out = hdd_free_space; +} + +/* https://msdn.microsoft.com/en-us/library/aa390423 */ +static char *query_wmi (QueryWmiType type) +{ + GString *result = NULL; + HRESULT hr; + + IWbemLocator *locator = NULL; + BSTR namespaceName = NULL; + BSTR queryLanguageName = NULL; + BSTR query = NULL; + IWbemServices *namespace = NULL; + IUnknown *namespaceUnknown = NULL; + IEnumWbemClassObject *enumerator = NULL; + int i; + gboolean atleast_one_appended = FALSE; + + hr = CoCreateInstance (&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (LPVOID *) &locator); + if (FAILED (hr)) + { + goto exit; + } + + namespaceName = SysAllocString (L"root\\CIMV2"); + + hr = locator->lpVtbl->ConnectServer (locator, namespaceName, NULL, NULL, NULL, 0, NULL, NULL, &namespace); + if (FAILED (hr)) + { + goto release_locator; + } + + hr = namespace->lpVtbl->QueryInterface (namespace, &IID_IUnknown, &namespaceUnknown); + if (FAILED (hr)) + { + goto release_namespace; + } + + hr = CoSetProxyBlanket (namespaceUnknown, 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)) + { + goto release_namespaceUnknown; + } + + queryLanguageName = SysAllocString (L"WQL"); + + switch (type) + { + case QUERY_WMI_OS: + query = SysAllocString (L"SELECT Caption FROM Win32_OperatingSystem"); + break; + case QUERY_WMI_CPU: + query = SysAllocString (L"SELECT Name, MaxClockSpeed FROM Win32_Processor"); + break; + case QUERY_WMI_VGA: + query = SysAllocString (L"SELECT Name FROM Win32_VideoController"); + break; + case QUERY_WMI_HDD: + query = SysAllocString (L"SELECT Name, Capacity, FreeSpace FROM Win32_Volume"); + break; + default: + goto release_queryLanguageName; + } + + hr = namespace->lpVtbl->ExecQuery (namespace, queryLanguageName, query, WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator); + if (FAILED (hr)) + { + goto release_query; + } + + result = g_string_new (""); + + for (i = 0;; i++) + { + ULONG numReturned = 0; + IWbemClassObject *object; + char *line; + + hr = enumerator->lpVtbl->Next (enumerator, WBEM_INFINITE, 1, &object, &numReturned); + if (FAILED (hr) || numReturned == 0) + { + break; + } + + switch (type) + { + case QUERY_WMI_OS: + line = read_os_name (object); + break; + + case QUERY_WMI_CPU: + line = read_cpu_info (object); + break; + + case QUERY_WMI_VGA: + line = read_vga_name (object); + break; + + case QUERY_WMI_HDD: + line = read_hdd_info (object); + break; + + default: + break; + } + + object->lpVtbl->Release (object); + + if (line != NULL) + { + if (atleast_one_appended) + { + g_string_append (result, ", "); + } + + g_string_append (result, line); + + g_free (line); + + atleast_one_appended = TRUE; + } + } + + enumerator->lpVtbl->Release (enumerator); + +release_query: + SysFreeString (query); + +release_queryLanguageName: + SysFreeString (queryLanguageName); + +release_namespaceUnknown: + namespaceUnknown->lpVtbl->Release (namespaceUnknown); + +release_namespace: + namespace->lpVtbl->Release (namespace); + +release_locator: + locator->lpVtbl->Release (locator); + SysFreeString (namespaceName); + +exit: + if (result == NULL) + { + return NULL; + } + + return g_string_free (result, FALSE); +} + +static char *read_os_name (IWbemClassObject *object) +{ + HRESULT hr; + VARIANT caption_variant; + char *caption_utf8; + + hr = object->lpVtbl->Get (object, L"Caption", 0, &caption_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + caption_utf8 = bstr_to_utf8 (caption_variant.bstrVal); + + VariantClear(&caption_variant); + + if (caption_utf8 == NULL) + { + return NULL; + } + + g_strchomp (caption_utf8); + + return caption_utf8; +} + +static char *read_cpu_info (IWbemClassObject *object) +{ + HRESULT hr; + VARIANT name_variant; + char *name_utf8; + VARIANT max_clock_speed_variant; + guint cpu_freq_mhz; + char *result; + + hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + name_utf8 = bstr_to_utf8 (name_variant.bstrVal); + + VariantClear (&name_variant); + + if (name_utf8 == NULL) + { + return NULL; + } + + hr = object->lpVtbl->Get (object, L"MaxClockSpeed", 0, &max_clock_speed_variant, NULL, NULL); + if (FAILED (hr)) + { + g_free (name_utf8); + + return NULL; + } + + cpu_freq_mhz = max_clock_speed_variant.uintVal; + + VariantClear (&max_clock_speed_variant); + + if (cpu_freq_mhz > 1000) + { + result = g_strdup_printf ("%s (%.2fGHz)", name_utf8, cpu_freq_mhz / 1000.f); + } + else + { + result = g_strdup_printf ("%s (%" G_GUINT32_FORMAT "MHz)", name_utf8, cpu_freq_mhz); + } + + g_free (name_utf8); + + return result; +} + +static char *read_vga_name (IWbemClassObject *object) +{ + HRESULT hr; + VARIANT name_variant; + char *name_utf8; + + hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + name_utf8 = bstr_to_utf8 (name_variant.bstrVal); + + VariantClear (&name_variant); + + if (name_utf8 == NULL) + { + return NULL; + } + + return g_strchomp (name_utf8); +} + +static char *read_hdd_info (IWbemClassObject *object) +{ + HRESULT hr; + VARIANT name_variant; + BSTR name_bstr; + gsize name_len; + VARIANT capacity_variant; + guint64 capacity; + VARIANT free_space_variant; + guint64 free_space; + + hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + name_bstr = name_variant.bstrVal; + name_len = SysStringLen (name_variant.bstrVal); + + if (name_len >= 4 && name_bstr[0] == L'\\' && name_bstr[1] == L'\\' && name_bstr[2] == L'?' && name_bstr[3] == L'\\') + { + // This is not a named volume. Skip it. + VariantClear (&name_variant); + + return NULL; + } + + VariantClear (&name_variant); + + hr = object->lpVtbl->Get (object, L"Capacity", 0, &capacity_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + capacity = variant_to_uint64 (&capacity_variant); + + VariantClear (&capacity_variant); + + if (capacity == 0) + { + return NULL; + } + + hr = object->lpVtbl->Get (object, L"FreeSpace", 0, &free_space_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + free_space = variant_to_uint64 (&free_space_variant); + + VariantClear (&free_space_variant); + + if (free_space == 0) + { + return NULL; + } + + hdd_capacity += capacity; + hdd_free_space += free_space; + + return NULL; +} + +static char *bstr_to_utf8 (BSTR bstr) +{ + return g_utf16_to_utf8 (bstr, SysStringLen (bstr), NULL, NULL, NULL); +} + +static guint64 variant_to_uint64 (VARIANT *variant) +{ + switch (V_VT (variant)) + { + case VT_UI8: + return variant->ullVal; + + case VT_BSTR: + return wcstoull (variant->bstrVal, NULL, 10); + + default: + return 0; + } +} diff --git a/src/common/util.c b/src/common/util.c index 316ac9d4..9ec8ef16 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -32,7 +32,7 @@ #ifdef WIN32 #include #include -#include +#include "./sysinfo/sysinfo.h" #else #include #include @@ -458,158 +458,38 @@ get_cpu_info (double *mhz, int *cpus) #ifdef WIN32 -static int -get_mhz (void) -{ - HKEY hKey; - int result, data, dataSize; - - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Hardware\\Description\\System\\" - "CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) - { - dataSize = sizeof (data); - result = RegQueryValueEx (hKey, "~MHz", 0, 0, (LPBYTE)&data, &dataSize); - RegCloseKey (hKey); - if (result == ERROR_SUCCESS) - return data; - } - return 0; /* fails on Win9x */ -} - int get_cpu_arch (void) { - SYSTEM_INFO si; - - GetSystemInfo (&si); - - if (si.wProcessorArchitecture == 9) - { - return 64; - } - else - { - return 86; - } + return sysinfo_get_build_arch (); } char * get_sys_str (int with_cpu) { - static char verbuf[64]; - static char winver[20]; - double mhz; + static char *without_cpu_buffer = NULL; + static char *with_cpu_buffer = NULL; - /* Broken since major bumped to 10, should start to work eventually. - * No, IsWindowsVersionOrGreater (10, 0, 0) doesn't work either. - * TODO: replace with IsWindows10OrGreater() once added to the SDK. - */ - if (IsWindowsVersionOrGreater (6, 4, 0)) + if (with_cpu == 0) { - if (IsWindowsServer ()) + if (without_cpu_buffer == NULL) { - strcpy (winver, "Server 10"); + without_cpu_buffer = sysinfo_get_os (); } - else - { - strcpy (winver, "10"); - } - } - else if (IsWindows8Point1OrGreater ()) - { - if (IsWindowsServer ()) - { - strcpy (winver, "Server 2012 R2"); - } - else - { - strcpy (winver, "8.1"); - } - } - else if (IsWindows8OrGreater ()) - { - if (IsWindowsServer ()) - { - strcpy (winver, "Server 2012"); - } - else - { - strcpy (winver, "8"); - } - } - else if (IsWindows7SP1OrGreater ()) - { - if (IsWindowsServer ()) - { - strcpy (winver, "Server 2008 R2 SP1"); - } - else - { - strcpy (winver, "7 SP1"); - } - } - else if (IsWindows7OrGreater ()) - { - if (IsWindowsServer ()) - { - strcpy (winver, "Server 2008 R2"); - } - else - { - strcpy (winver, "7"); - } - } - else if (IsWindowsVistaSP2OrGreater ()) - { - if (IsWindowsServer ()) - { - strcpy (winver, "Server 2008 SP2"); - } - else - { - strcpy (winver, "Vista SP2"); - } - } - else if (IsWindowsVistaSP1OrGreater ()) - { - if (IsWindowsServer ()) - { - strcpy (winver, "Server 2008 SP1"); - } - else - { - strcpy (winver, "Vista SP1"); - } - } - else if (IsWindowsVistaOrGreater ()) - { - if (IsWindowsServer ()) - { - strcpy (winver, "Server 2008"); - } - else - { - strcpy (winver, "Vista"); - } - } - else - { - strcpy (winver, "Unknown"); + + return without_cpu_buffer; } - mhz = get_mhz (); - if (mhz && with_cpu) + if (with_cpu_buffer == NULL) { - double cpuspeed = ( mhz > 1000 ) ? mhz / 1000 : mhz; - const char *cpuspeedstr = ( mhz > 1000 ) ? "GHz" : "MHz"; - sprintf (verbuf, "Windows %s [%.2f%s]", winver, cpuspeed, cpuspeedstr); + char *os = sysinfo_get_os (); + char *cpu = sysinfo_get_cpu (); + with_cpu_buffer = g_strconcat (os, " [", cpu, "]", NULL); + g_free (cpu); + g_free (os); } - else - { - sprintf (verbuf, "Windows %s", winver); - } - - return verbuf; + + return with_cpu_buffer; } #else diff --git a/src/fe-gtk/fe-gtk.vcxproj b/src/fe-gtk/fe-gtk.vcxproj index 02739a47..5a668b5b 100644 --- a/src/fe-gtk/fe-gtk.vcxproj +++ b/src/fe-gtk/fe-gtk.vcxproj @@ -35,7 +35,7 @@ $(DepsRoot)\lib;%(AdditionalLibraryDirectories) - $(DepLibs);$(HexChatLib)common.lib;%(AdditionalDependencies) + $(DepLibs);$(HexChatLib)common.lib;wbemuuid.lib;comsupp.lib;%(AdditionalDependencies) mainCRTStartup @@ -47,7 +47,7 @@ $(DepsRoot)\lib;%(AdditionalLibraryDirectories) - $(DepLibs);$(HexChatLib)common.lib;%(AdditionalDependencies) + $(DepLibs);$(HexChatLib)common.lib;wbemuuid.lib;comsupp.lib;%(AdditionalDependencies) mainCRTStartup @@ -140,4 +140,4 @@ powershell "Get-Content -Encoding UTF8 '$(HexChatLib)hexchat.rc.utf8' | Out-File - + \ No newline at end of file diff --git a/src/fe-text/fe-text.vcxproj b/src/fe-text/fe-text.vcxproj index 39286417..6c7c25a8 100644 --- a/src/fe-text/fe-text.vcxproj +++ b/src/fe-text/fe-text.vcxproj @@ -37,7 +37,7 @@ true true true - $(DepLibs);$(HexChatLib)common.lib;%(AdditionalDependencies) + $(DepLibs);$(HexChatLib)common.lib;wbemuuid.lib;comsupp.lib;%(AdditionalDependencies) $(DepsRoot)\lib;%(AdditionalLibraryDirectories) @@ -51,7 +51,7 @@ true true true - $(DepLibs);$(HexChatLib)common.lib;%(AdditionalDependencies) + $(DepLibs);$(HexChatLib)common.lib;wbemuuid.lib;comsupp.lib;%(AdditionalDependencies) $(DepsRoot)\lib;%(AdditionalLibraryDirectories)