d3d9: Update presentation parameters when creating a swap chain.
[wine.git] / programs / systeminfo / main.c
blobfefb2f1a1a711bbc829545c1e230681259e4c13b
1 /*
2 * Copyright 2014 Austin English
3 * Copyright 2023 Hans Leidekker for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define COBJMACROS
22 #include "initguid.h"
23 #include "objidl.h"
24 #include "wbemcli.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(systeminfo);
30 enum format_flags
32 FORMAT_STRING,
33 FORMAT_DATE,
34 FORMAT_LOCALE,
35 FORMAT_SIZE,
38 struct sysinfo
40 const WCHAR *item;
41 const WCHAR *class;
42 const WCHAR *property; /* hardcoded value if class is NULL */
43 void (*callback)( IWbemServices *services, enum format_flags flags, UINT32 ); /* called if class and property are NULL */
44 enum format_flags flags;
47 static void output_processors( IWbemServices *services, enum format_flags flags, UINT32 width )
49 IEnumWbemClassObject *iter;
50 IWbemClassObject *obj;
51 DWORD i, num_cpus = 0, count;
52 VARIANT value;
53 BSTR str;
54 HRESULT hr;
56 str = SysAllocString( L"Win32_Processor" );
57 hr = IWbemServices_CreateInstanceEnum( services, str, 0, NULL, &iter );
58 SysFreeString( str );
59 if (FAILED( hr )) return;
61 while (IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 ) == S_OK) num_cpus++;
63 fwprintf( stdout, L"Processor(s):%*s %u Processor(s) Installed.\n", width - wcslen(L"Processor(s)"), " ", num_cpus );
64 IEnumWbemClassObject_Reset( iter );
66 for (i = 0; i < num_cpus; i++)
68 hr = IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &obj, &count );
69 if (FAILED( hr )) goto done;
71 hr = IWbemClassObject_Get( obj, L"Caption", 0, &value, NULL, NULL );
72 if (FAILED( hr ))
74 IWbemClassObject_Release( obj );
75 goto done;
77 fwprintf( stdout, L"%*s[%02u]: %s", width + 2, " ", i + 1, V_BSTR(&value) );
78 VariantClear( &value );
80 hr = IWbemClassObject_Get( obj, L"Manufacturer", 0, &value, NULL, NULL );
81 if (FAILED( hr ))
83 IWbemClassObject_Release( obj );
84 goto done;
86 fwprintf( stdout, L" %s", V_BSTR(&value) );
87 VariantClear( &value );
89 hr = IWbemClassObject_Get( obj, L"MaxClockSpeed", 0, &value, NULL, NULL );
90 if (FAILED( hr ))
92 IWbemClassObject_Release( obj );
93 goto done;
95 fwprintf( stdout, L" ~%u Mhz\n", V_I4(&value) );
97 IWbemClassObject_Release( obj );
100 done:
101 IEnumWbemClassObject_Release( iter );
104 static void output_hotfixes( IWbemServices *services, enum format_flags flags, UINT32 width )
106 IEnumWbemClassObject *iter;
107 IWbemClassObject *obj;
108 DWORD i, num_hotfixes = 0, count;
109 VARIANT value;
110 BSTR str;
111 HRESULT hr;
113 str = SysAllocString( L"Win32_QuickFixEngineering" );
114 hr = IWbemServices_CreateInstanceEnum( services, str, 0, NULL, &iter );
115 SysFreeString( str );
116 if (FAILED( hr )) return;
118 while (IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 ) == S_OK) num_hotfixes++;
120 fwprintf( stdout, L"Hotfix(es):%*s %u Hotfix(es) Installed.\n", width - wcslen(L"Hotfix(es)"), " ", num_hotfixes );
121 IEnumWbemClassObject_Reset( iter );
123 for (i = 0; i < num_hotfixes; i++)
125 hr = IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &obj, &count );
126 if (FAILED( hr )) goto done;
128 hr = IWbemClassObject_Get( obj, L"Caption", 0, &value, NULL, NULL );
129 if (FAILED( hr ))
131 IWbemClassObject_Release( obj );
132 goto done;
134 fwprintf( stdout, L"%*s[%02u]: %s\n", width + 2, " ", i + 1, V_BSTR(&value) );
135 VariantClear( &value );
137 IWbemClassObject_Release( obj );
140 done:
141 IEnumWbemClassObject_Release( iter );
144 static void output_nics( IWbemServices *services, enum format_flags flags, UINT32 width )
146 IEnumWbemClassObject *iter;
147 IWbemClassObject *obj;
148 DWORD i, num_nics = 0, count;
149 VARIANT value;
150 SAFEARRAY *sa;
151 LONG bound = -1, j;
152 BSTR str;
153 HRESULT hr;
155 str = SysAllocString( L"Win32_NetworkAdapterConfiguration" );
156 hr = IWbemServices_CreateInstanceEnum( services, str, 0, NULL, &iter );
157 SysFreeString( str );
158 if (FAILED( hr )) return;
160 while (IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 ) == S_OK) num_nics++;
162 fwprintf( stdout, L"Network Card(s):%*s %u NICs(s) Installed.\n", width - wcslen(L"Network Card(s)"), " ", num_nics );
163 IEnumWbemClassObject_Reset( iter );
165 for (i = 0; i < num_nics; i++)
167 hr = IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &obj, &count );
168 if (FAILED( hr )) goto done;
170 hr = IWbemClassObject_Get( obj, L"Description", 0, &value, NULL, NULL );
171 if (FAILED( hr ))
173 IWbemClassObject_Release( obj );
174 goto done;
176 fwprintf( stdout, L"%*s[%02u]: %s\n", width + 2, " ", i + 1, V_BSTR(&value) );
177 VariantClear( &value );
179 /* FIXME: Connection Name, DHCP Server */
181 hr = IWbemClassObject_Get( obj, L"DHCPEnabled", 0, &value, NULL, NULL );
182 if (FAILED( hr ))
184 IWbemClassObject_Release( obj );
185 goto done;
187 fwprintf( stdout, L"%*s DHCP Enabled: %s\n", width + 2, " ", V_BOOL(&value) ? L"Yes" : L"No" );
189 hr = IWbemClassObject_Get( obj, L"IPAddress", 0, &value, NULL, NULL );
190 if (FAILED( hr ))
192 IWbemClassObject_Release( obj );
193 goto done;
195 if (V_VT( &value ) == (VT_BSTR | VT_ARRAY))
197 sa = V_ARRAY( &value );
198 SafeArrayGetUBound( sa, 1, &bound );
199 if (bound >= 0)
201 fwprintf( stdout, L"%*s IP Addresse(es)\n", width + 2, " " );
202 for (j = 0; j <= bound; j++)
204 SafeArrayGetElement( sa, &j, &str );
205 fwprintf( stdout, L"%*s [%02u]: %s\n", width + 2, " ", j + 1, str );
206 SysFreeString( str );
210 VariantClear( &value );
211 IWbemClassObject_Release( obj );
214 done:
215 IEnumWbemClassObject_Release( iter );
218 static void output_timezone( IWbemServices *services, enum format_flags flags, UINT32 width )
220 WCHAR name[64], timezone[256] = {};
221 DWORD count = sizeof(name);
222 HKEY key_current = 0, key_timezones = 0, key_name = 0;
224 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\TimeZoneInformation", 0,
225 KEY_READ, &key_current )) goto done;
226 if (RegQueryValueExW( key_current, L"TimeZoneKeyName", NULL, NULL, (BYTE *)name, &count )) goto done;
227 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones", 0,
228 KEY_READ, &key_timezones )) goto done;
229 if (RegOpenKeyExW( key_timezones, name, 0, KEY_READ, &key_name )) goto done;
230 count = sizeof(timezone);
231 RegQueryValueExW( key_name, L"Display", NULL, NULL, (BYTE *)timezone, &count );
233 done:
234 fwprintf( stdout, L"Time Zone:%*s %s\n", width - wcslen(L"Time Zone"), " ", timezone );
235 RegCloseKey( key_name );
236 RegCloseKey( key_timezones );
237 RegCloseKey( key_current );
240 static const struct sysinfo sysinfo_map[] =
242 { L"Host Name", L"Win32_ComputerSystem", L"Name" },
243 { L"OS Name", L"Win32_OperatingSystem", L"Caption" },
244 { L"OS Version", L"Win32_OperatingSystem", L"Version" }, /* FIXME build number */
245 { L"OS Manufacturer", L"Win32_OperatingSystem", L"Manufacturer" },
246 { L"OS Configuration", NULL, L"Standalone Workstation" },
247 { L"OS Build Type", L"Win32_OperatingSystem", L"BuildType" },
248 { L"Registered Owner", L"Win32_OperatingSystem", L"RegisteredUser" },
249 { L"Registered Organization", L"Win32_OperatingSystem", L"Organization" },
250 { L"Product ID", L"Win32_OperatingSystem", L"SerialNumber" },
251 { L"Original Install Date", L"Win32_OperatingSystem", L"InstallDate", NULL, FORMAT_DATE },
252 { L"System Boot Time", L"Win32_OperatingSystem", L"LastBootUpTime", NULL, FORMAT_DATE },
253 { L"System Manufacturer", L"Win32_ComputerSystem", L"Manufacturer" },
254 { L"System Model", L"Win32_ComputerSystem", L"Model" },
255 { L"System Type", L"Win32_ComputerSystem", L"SystemType" },
256 { L"Processor(s)", NULL, NULL, output_processors },
257 { L"BIOS Version", L"Win32_BIOS", L"SMBIOSBIOSVersion" },
258 { L"Windows Directory", L"Win32_OperatingSystem", L"WindowsDirectory" },
259 { L"System Directory", L"Win32_OperatingSystem", L"SystemDirectory" },
260 { L"Boot Device", L"Win32_OperatingSystem", L"BootDevice" },
261 { L"System Locale", L"Win32_OperatingSystem", L"Locale", NULL, FORMAT_LOCALE },
262 { L"Input Locale", L"Win32_OperatingSystem", L"Locale", NULL, FORMAT_LOCALE }, /* FIXME */
263 { L"Time Zone", NULL, NULL, output_timezone },
264 { L"Total Physical Memory", L"Win32_OperatingSystem", L"TotalVisibleMemorySize", NULL, FORMAT_SIZE },
265 { L"Available Physical Memory", L"Win32_OperatingSystem", L"FreePhysicalMemory", NULL, FORMAT_SIZE },
266 { L"Virtual Memory: Max Size", L"Win32_OperatingSystem", L"TotalVirtualMemorySize", NULL, FORMAT_SIZE },
267 { L"Virtual Memory: Available", L"Win32_OperatingSystem", L"FreeVirtualMemory", NULL, FORMAT_SIZE },
268 /* FIXME Virtual Memory: In Use */
269 { L"Page File Location(s)", L"Win32_PageFileUsage", L"Name" },
270 { L"Domain", L"Win32_ComputerSystem", L"Domain" },
271 /* FIXME Logon Server */
272 { L"Hotfix(s)", NULL, NULL, output_hotfixes },
273 { L"Network Card(s)", NULL, NULL, output_nics },
274 /* FIXME Hyper-V Requirements */
277 static void output_item( IWbemServices *services, const struct sysinfo *info, UINT32 width )
279 HRESULT hr;
280 IWbemClassObject *obj = NULL;
281 BSTR str;
282 VARIANT value;
284 if (!info->class)
286 if (info->property)
287 fwprintf( stdout, L"%s:%*s %s\n", info->item, width - wcslen(info->item), " ", info->property );
288 else
289 info->callback( services, info->flags, width );
290 return;
293 if (!(str = SysAllocString( info->class ))) return;
294 hr = IWbemServices_GetObject( services, str, 0, NULL, &obj, NULL );
295 SysFreeString( str );
296 if (FAILED( hr )) return;
298 hr = IWbemClassObject_Get( obj, info->property, 0, &value, NULL, NULL );
299 if (FAILED( hr ))
301 IWbemClassObject_Release( obj );
302 return;
305 switch (info->flags)
307 case FORMAT_DATE:
309 SYSTEMTIME st;
310 WCHAR date[32] = {}, time[32] = {};
312 /* assume UTC */
313 memset( &st, 0, sizeof(st) );
314 swscanf( V_BSTR(&value), L"%04u%02u%02u%02u%02u%02u",
315 &st.wYear, &st.wMonth, &st.wDay, &st.wHour, &st.wMinute, &st.wSecond );
316 GetDateFormatW( LOCALE_SYSTEM_DEFAULT, 0, &st, NULL, date, ARRAY_SIZE(date) );
317 GetTimeFormatW( LOCALE_SYSTEM_DEFAULT, 0, &st, NULL, time, ARRAY_SIZE(time) );
318 fwprintf( stdout, L"%s:%*s %s, %s\n", info->item, width - wcslen(info->item), " ", date, time );
319 break;
321 case FORMAT_LOCALE:
323 UINT32 lcid;
324 WCHAR name[32] = {}, displayname[LOCALE_NAME_MAX_LENGTH] = {};
326 swscanf( V_BSTR(&value), L"%x", &lcid );
327 LCIDToLocaleName( lcid, name, ARRAY_SIZE(name), 0 );
328 GetLocaleInfoW( lcid, LOCALE_SENGLISHDISPLAYNAME, displayname, ARRAY_SIZE(displayname) );
329 fwprintf( stdout, L"%s:%*s %s;%s\n", info->item, width - wcslen(info->item), " ", name, displayname );
330 break;
332 case FORMAT_SIZE:
334 UINT64 size = 0;
335 swscanf( V_BSTR(&value), L"%I64u", &size );
336 fwprintf( stdout, L"%s:%*s %I64u MB\n", info->item, width - wcslen(info->item), " ", size / 1024 );
337 break;
339 default:
340 fwprintf( stdout, L"%s:%*s %s\n", info->item, width - wcslen(info->item), " ", V_BSTR(&value) );
341 break;
343 VariantClear( &value );
346 static void output_sysinfo( void )
348 IWbemLocator *locator;
349 IWbemServices *services = NULL;
350 UINT32 i, len, width = 0;
351 HRESULT hr;
352 BSTR path;
354 CoInitialize( NULL );
355 CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL );
357 hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (void **)&locator );
358 if (hr != S_OK) return;
360 if (!(path = SysAllocString( L"ROOT\\CIMV2" ))) goto done;
361 hr = IWbemLocator_ConnectServer( locator, path, NULL, NULL, NULL, 0, NULL, NULL, &services );
362 SysFreeString( path );
363 if (hr != S_OK) goto done;
365 for (i = 0; i < ARRAY_SIZE(sysinfo_map); i++) if ((len = wcslen( sysinfo_map[i].item )) > width) width = len;
366 width++;
368 for (i = 0; i < ARRAY_SIZE(sysinfo_map); i++) output_item( services, &sysinfo_map[i], width );
370 done:
371 if (services) IWbemServices_Release( services );
372 IWbemLocator_Release( locator );
373 CoUninitialize();
376 int __cdecl wmain( int argc, WCHAR *argv[] )
378 if (argc > 1)
380 int i;
381 FIXME( "stub:" );
382 for (i = 0; i < argc; i++) FIXME( " %s", wine_dbgstr_w(argv[i]) );
383 FIXME( "\n" );
384 return 0;
387 output_sysinfo();
388 return 0;