/* 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 #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; static char *query_wmi (QueryWmiType mode); static char *read_os_name (IWbemClassObject *object); static char *read_cpu_info (IWbemClassObject *object); static char *read_vga_name (IWbemClassObject *object); static guint64 hdd_capacity; static guint64 hdd_free_space; static char *read_hdd_info (IWbemClassObject *object); static char *bstr_to_utf8 (BSTR bstr); static 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, (void**)&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_HD