[SYSTEMINFO]
[reactos.git] / rosapps / applications / sysutils / systeminfo / systeminfo.c
1 /*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16 /* Copyright (C) 2007, Dmitry Chapyshev <lentind@yandex.ru> */
17 /* Copyright (C) 2011, Rafal Harabien <rafalh1992@o2.pl> */
18
19 #include <wchar.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <windows.h>
23 #include <time.h>
24 #include <locale.h>
25 #include <lm.h>
26 #include <shlwapi.h>
27
28 #include "resource.h"
29
30 #define BUFFER_SIZE 32767
31
32 /* Load from resource and convert to OEM */
33 static
34 BOOL
35 GetOemStrings(UINT rcID, LPWSTR OutMsg)
36 {
37 if (LoadStringW(GetModuleHandle(NULL), rcID, OutMsg, BUFFER_SIZE))
38 return TRUE;
39
40 return FALSE;
41 }
42
43 /* Load data from registry */
44 static
45 BOOL
46 RegGetSZ(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPWSTR Buf)
47 {
48 DWORD dwBytes = BUFFER_SIZE*sizeof(WCHAR), dwType;
49 BOOL bRet = TRUE;
50
51 /* If SubKy is specified open it */
52 if (lpSubKey && RegOpenKeyExW(hKey,
53 lpSubKey,
54 0,
55 KEY_QUERY_VALUE,
56 &hKey) != ERROR_SUCCESS)
57 {
58 wprintf(L"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey, GetLastError());
59 return FALSE;
60 }
61
62 if (RegQueryValueExW(hKey,
63 lpValueName,
64 NULL,
65 &dwType,
66 (LPBYTE)Buf,
67 &dwBytes) != ERROR_SUCCESS || (dwType != REG_SZ && dwType != REG_MULTI_SZ))
68 {
69 wprintf(L"Warning! Cannot query %s. Last error: %lu, type: %lu.\n", lpValueName, GetLastError(), dwType);
70 dwBytes = 0;
71 bRet = FALSE;
72 }
73
74 /* Close key if we opened it */
75 if (lpSubKey)
76 RegCloseKey(hKey);
77
78 /* NULL-terminate string */
79 Buf[min(BUFFER_SIZE-1, dwBytes/sizeof(WCHAR))] = L'\0';
80
81 return bRet;
82 }
83
84 static
85 BOOL
86 RegGetDWORD(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPDWORD lpData)
87 {
88 DWORD dwBytes = sizeof(*lpData), dwType;
89 BOOL bRet = TRUE;
90
91 /* If SubKy is specified open it */
92 if (lpSubKey && RegOpenKeyExW(hKey,
93 lpSubKey,
94 0,
95 KEY_QUERY_VALUE,
96 &hKey) != ERROR_SUCCESS)
97 {
98 wprintf(L"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey, GetLastError());
99 return FALSE;
100 }
101
102 if (RegQueryValueExW(hKey,
103 lpValueName,
104 NULL,
105 &dwType,
106 (LPBYTE)lpData,
107 &dwBytes) != ERROR_SUCCESS || dwType != REG_DWORD)
108 {
109 wprintf(L"Warning! Cannot query %s. Last err: %lu, type: %lu\n", lpValueName, GetLastError(), dwType);
110 *lpData = 0;
111 bRet = FALSE;
112 }
113
114 /* Close key if we opened it */
115 if (lpSubKey)
116 RegCloseKey(hKey);
117
118 return bRet;
119 }
120
121 static
122 void
123 FormatBytes(LPWSTR Buf, unsigned cBytes)
124 {
125 WCHAR szMB[32];
126 NUMBERFMTW fmt;
127
128 _itow(cBytes / (1024*1024), szMB, 10);
129
130 fmt.NumDigits = 0;
131 fmt.LeadingZero = 0;
132 fmt.Grouping = 3;
133 fmt.lpDecimalSep = L"";
134 fmt.lpThousandSep = L" ";
135 fmt.NegativeOrder = 0;
136
137 if(!GetNumberFormatW(LOCALE_SYSTEM_DEFAULT, 0, szMB, &fmt, Buf, BUFFER_SIZE))
138 wprintf(L"Error! GetNumberFormat failed.\n");
139 }
140
141 static
142 void
143 FormatDateTime(time_t Time, LPWSTR lpBuf)
144 {
145 unsigned cchBuf = BUFFER_SIZE, i;
146 SYSTEMTIME SysTime;
147 const struct tm *lpTm;
148
149 lpTm = localtime(&Time);
150 SysTime.wYear = (WORD)(1900 + lpTm->tm_year);
151 SysTime.wMonth = (WORD)(1 + lpTm->tm_mon);
152 SysTime.wDayOfWeek = (WORD)lpTm->tm_wday;
153 SysTime.wDay = (WORD)lpTm->tm_mday;
154 SysTime.wHour = (WORD)lpTm->tm_hour;
155 SysTime.wMinute = (WORD)lpTm->tm_min;
156 SysTime.wSecond = (WORD)lpTm->tm_sec;
157 SysTime.wMilliseconds = 0;
158
159 /* Time first */
160 i = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &SysTime, NULL, lpBuf, cchBuf);
161 if (i)
162 --i; /* don't count NULL character */
163
164 /* Time now */
165 i += swprintf(lpBuf + i, L", ");
166 GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, 0, &SysTime, NULL, lpBuf + i, cchBuf - i);
167 }
168
169 /* Show usage */
170 static
171 VOID
172 Usage(VOID)
173 {
174 WCHAR Buf[BUFFER_SIZE];
175
176 if(GetOemStrings(IDS_USAGE, Buf))
177 wprintf(L"%s", Buf);
178 }
179
180 /* Print all system information */
181 VOID
182 AllSysInfo(VOID)
183 {
184 DWORD dwCharCount = BUFFER_SIZE, dwTimestamp;
185 OSVERSIONINFOW VersionInfo;
186 SYSTEM_INFO SysInfo;
187 WCHAR Buf[BUFFER_SIZE], Tmp[BUFFER_SIZE], Msg[BUFFER_SIZE], szSystemDir[MAX_PATH];
188 const WCHAR *lpcszSysType;
189 LPWSTR lpBuffer;
190 NETSETUP_JOIN_STATUS NetJoinStatus;
191 MEMORYSTATUS MemoryStatus;
192 unsigned int cSeconds;
193 TIME_ZONE_INFORMATION TimeZoneInfo;
194 HKEY hKey;
195
196 if (!GetSystemDirectoryW(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0])))
197 {
198 wprintf(L"Error! GetSystemDirectory failed.\n");
199 return;
200 }
201
202 GetSystemInfo(&SysInfo);
203
204 // getting computer name
205 dwCharCount = BUFFER_SIZE;
206 if (!GetComputerNameW(Buf, &dwCharCount))
207 wprintf(L"Error! GetComputerName failed.\n");
208 else if (GetOemStrings(IDS_HOST_NAME, Msg))
209 wprintf(Msg, Buf);
210
211 // open CurrentVersion key
212 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
213 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
214 0,
215 KEY_QUERY_VALUE,
216 &hKey) != ERROR_SUCCESS)
217 {
218 wprintf(L"Error! RegOpenKeyEx failed.\n");
219 return;
220 }
221
222 //getting OS Name
223 RegGetSZ(hKey, NULL, L"ProductName", Buf);
224 if (GetOemStrings(IDS_OS_NAME, Msg))
225 wprintf(Msg, Buf);
226
227 //getting OS Version
228 ZeroMemory(&VersionInfo, sizeof(VersionInfo));
229 VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
230 GetVersionExW(&VersionInfo);
231
232 if (GetOemStrings(IDS_OS_VERSION, Msg))
233 wprintf(Msg,
234 (unsigned)VersionInfo.dwMajorVersion,
235 (unsigned)VersionInfo.dwMinorVersion,
236 (unsigned)VersionInfo.dwBuildNumber,
237 VersionInfo.szCSDVersion,
238 (unsigned)VersionInfo.dwBuildNumber);
239
240 //getting OS Manufacturer
241
242 //getting OS Configuration
243
244 //getting OS Build Type
245 RegGetSZ(hKey, NULL, L"CurrentType", Buf);
246 if (GetOemStrings(IDS_OS_BUILD_TYPE, Msg))
247 wprintf(Msg, Buf);
248
249 //getting Registered Owner
250 RegGetSZ(hKey, NULL, L"RegisteredOwner", Buf);
251 if (GetOemStrings(IDS_REG_OWNER, Msg))
252 wprintf(Msg, Buf);
253
254 //getting Registered Organization
255 RegGetSZ(hKey, NULL, L"RegisteredOrganization", Buf);
256 if (GetOemStrings(IDS_REG_ORG, Msg))
257 wprintf(Msg, Buf);
258
259 //getting Product ID
260 RegGetSZ(hKey, NULL, L"ProductId", Buf);
261 if (GetOemStrings(IDS_PRODUCT_ID, Msg))
262 wprintf(Msg, Buf);
263
264 //getting Install Date
265 RegGetDWORD(hKey, NULL, L"InstallDate", &dwTimestamp);
266 FormatDateTime((time_t)dwTimestamp, Buf);
267 if (GetOemStrings(IDS_INST_DATE, Msg))
268 wprintf(Msg, Buf);
269
270 // close Current Version key now
271 RegCloseKey(hKey);
272
273 //getting System Up Time
274 cSeconds = GetTickCount() / 1000;
275 if (GetOemStrings(IDS_UP_TIME, Msg))
276 wprintf(Msg, cSeconds / (60*60*24), (cSeconds / (60*60)) % 24, (cSeconds / 60) % 60, cSeconds % 60);
277
278 //getting System Manufacturer; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Manufacturer for Win >= 6.0
279 swprintf(Tmp, L"%s\\oeminfo.ini", szSystemDir);
280 GetPrivateProfileStringW(L"General",
281 L"Manufacturer",
282 L"To Be Filled By O.E.M.",
283 Buf,
284 sizeof(Buf)/sizeof(Buf[0]),
285 Tmp);
286 if (GetOemStrings(IDS_SYS_MANUFACTURER, Msg))
287 wprintf(Msg, Buf);
288
289 //getting System Model; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Model for Win >= 6.0
290 GetPrivateProfileStringW(L"General",
291 L"Model",
292 L"To Be Filled By O.E.M.",
293 Buf,
294 sizeof(Buf)/sizeof(Buf[0]),
295 Tmp);
296 if (GetOemStrings(IDS_SYS_MODEL, Msg))
297 wprintf(Msg, Buf);
298
299 //getting System type
300 switch (SysInfo.wProcessorArchitecture)
301 {
302 case PROCESSOR_ARCHITECTURE_INTEL:
303 lpcszSysType = L"X86-based PC";
304 break;
305 case PROCESSOR_ARCHITECTURE_IA64:
306 lpcszSysType = L"IA64-based PC";
307 break;
308 case PROCESSOR_ARCHITECTURE_AMD64:
309 lpcszSysType = L"AMD64-based PC";
310 break;
311 default:
312 lpcszSysType = L"Unknown";
313 break;
314 }
315 if (GetOemStrings(IDS_SYS_TYPE, Msg))
316 wprintf(Msg, lpcszSysType);
317
318 //getting Processor(s)
319 if (GetOemStrings(IDS_PROCESSORS, Msg))
320 {
321 unsigned int i;
322 wprintf(Msg, (unsigned int)SysInfo.dwNumberOfProcessors);
323 for(i = 0; i < (unsigned int)SysInfo.dwNumberOfProcessors; i++)
324 {
325 swprintf(Tmp, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%u", i);
326
327 RegGetSZ(HKEY_LOCAL_MACHINE, Tmp, L"Identifier", Buf);
328 wprintf(L" [%02u]: %s", i+1, Buf);
329
330 RegGetSZ(HKEY_LOCAL_MACHINE, Tmp, L"VendorIdentifier", Buf);
331 wprintf(L" %s\n", Buf);
332 }
333 }
334
335 //getting BIOS Version
336 RegGetSZ(HKEY_LOCAL_MACHINE,
337 L"HARDWARE\\DESCRIPTION\\System",
338 L"SystemBiosVersion",
339 Buf);
340 if (GetOemStrings(IDS_BIOS_VERSION, Msg))
341 wprintf(Msg, Buf);
342
343 //gettings BIOS date
344 RegGetSZ(HKEY_LOCAL_MACHINE,
345 L"HARDWARE\\DESCRIPTION\\System",
346 L"SystemBiosDate",
347 Buf);
348 if (GetOemStrings(IDS_BIOS_DATE, Msg))
349 wprintf(Msg, Buf);
350
351 //getting ReactOS Directory
352 if (!GetWindowsDirectoryW(Buf, BUFFER_SIZE))
353 wprintf(L"Error! GetWindowsDirectory failed.");
354 else if (GetOemStrings(IDS_ROS_DIR, Msg))
355 wprintf(Msg, Buf);
356
357 //getting System Directory
358 if (GetOemStrings(IDS_SYS_DIR, Msg))
359 wprintf(Msg, szSystemDir);
360
361 //getting Boot Device
362 RegGetSZ(HKEY_LOCAL_MACHINE,
363 L"SYSTEM\\Setup",
364 L"SystemPartition",
365 Buf);
366 if (GetOemStrings(IDS_BOOT_DEV, Msg))
367 wprintf(Msg, Buf);
368
369 //getting System Locale
370 if (GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, Tmp, BUFFER_SIZE))
371 if (RegGetSZ(HKEY_CLASSES_ROOT,
372 L"MIME\\Database\\Rfc1766",
373 Tmp,
374 Buf))
375 {
376 /* get rid of @filename,resource */
377 lpBuffer = wcschr(Buf, L';');
378 if (lpBuffer)
379 SHLoadIndirectString(lpBuffer+1, lpBuffer+1, BUFFER_SIZE - (lpBuffer-Buf) - 1, NULL);
380
381 if (GetOemStrings(IDS_SYS_LOCALE, Msg))
382 wprintf(Msg, Buf);
383 }
384
385 //getting Input Locale
386 if (RegGetSZ(HKEY_CURRENT_USER,
387 L"Keyboard Layout\\Preload",
388 L"1",
389 Tmp) && wcslen(Tmp) > 4)
390 if (RegGetSZ(HKEY_CLASSES_ROOT,
391 L"MIME\\Database\\Rfc1766",
392 Tmp + 4,
393 Buf))
394 {
395 /* get rid of @filename,resource */
396 lpBuffer = wcschr(Buf, L';');
397 if (lpBuffer)
398 SHLoadIndirectString(lpBuffer+1, lpBuffer+1, BUFFER_SIZE - (lpBuffer-Buf) - 1, NULL);
399
400 if (GetOemStrings(IDS_INPUT_LOCALE, Msg))
401 wprintf(Msg, Buf);
402 }
403
404 //getting Time Zone
405 GetTimeZoneInformation(&TimeZoneInfo);
406
407 /* Open Time Zones key */
408 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
409 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
410 0,
411 KEY_ENUMERATE_SUB_KEYS|KEY_READ,
412 &hKey) == ERROR_SUCCESS)
413 {
414 unsigned i;
415
416 /* Find current timezone */
417 dwCharCount = 256; // Windows seems to have a bug - it doesnt accept BUFFER_SIZE here
418 for(i = 0; RegEnumKeyExW(hKey, i, Tmp, &dwCharCount, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++i, dwCharCount = 255)
419 {
420 RegGetSZ(hKey, Tmp, L"Std", Buf);
421
422 if(!wcscmp(Buf, TimeZoneInfo.StandardName))
423 {
424 RegGetSZ(hKey, Tmp, L"Display", Buf);
425
426 if (GetOemStrings(IDS_TIME_ZONE, Msg))
427 wprintf(Msg, Buf);
428
429 break;
430 }
431 }
432 RegCloseKey(hKey);
433 }
434
435 //getting Total Physical Memory
436 GlobalMemoryStatus(&MemoryStatus);
437 FormatBytes(Buf, MemoryStatus.dwTotalPhys);
438 if (GetOemStrings(IDS_TOTAL_PHYS_MEM, Msg))
439 wprintf(Msg, Buf);
440
441 //getting Available Physical Memory
442 FormatBytes(Buf, MemoryStatus.dwAvailPhys);
443 if (GetOemStrings(IDS_AVAIL_PHISICAL_MEM,Msg))
444 wprintf(Msg, Buf);
445
446 //getting Virtual Memory: Max Size
447 FormatBytes(Buf, MemoryStatus.dwTotalVirtual);
448 if (GetOemStrings(IDS_VIRT_MEM_MAX, Msg))
449 wprintf(Msg, Buf);
450
451 //getting Virtual Memory: Available
452 FormatBytes(Buf, MemoryStatus.dwAvailVirtual);
453 if (GetOemStrings(IDS_VIRT_MEM_AVAIL, Msg))
454 wprintf(Msg, Buf);
455
456 //getting Virtual Memory: In Use
457 FormatBytes(Buf, MemoryStatus.dwTotalVirtual-MemoryStatus.dwAvailVirtual);
458 if (GetOemStrings(IDS_VIRT_MEM_INUSE, Msg))
459 wprintf(Msg, Buf);
460
461 //getting Page File Location(s)
462 if (RegGetSZ(HKEY_LOCAL_MACHINE,
463 L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management",
464 L"PagingFiles",
465 Buf))
466 {
467 int i;
468
469 for(i = 0; i < strlen((char*)Buf); i++)
470 {
471 if (Buf[i] == TEXT(' '))
472 {
473 Buf[i] = TEXT('\0');
474 break;
475 }
476 }
477
478 if(GetOemStrings(IDS_PAGEFILE_LOC, Msg))
479 wprintf(Msg, Buf);
480 }
481
482 //getting Domain
483 if (NetGetJoinInformation (NULL, &lpBuffer, &NetJoinStatus) == NERR_Success)
484 {
485 if(GetOemStrings(IDS_DOMAIN, Msg))
486 wprintf(Msg, lpBuffer);
487
488 NetApiBufferFree(lpBuffer);
489 }
490
491 //getting Logon Server
492
493 //getting NetWork Card(s)
494 if(GetOemStrings(IDS_NETWORK_CARDS, Msg))
495 {
496
497 }
498 }
499
500 /* Main program */
501 int
502 main(int argc, char *argv[])
503 {
504 setlocale(LC_ALL, "");
505
506 if (argc > 1 && (!strcmp(argv[1], "/?") || !strcmp(argv[1], "-?")))
507 {
508 Usage();
509 return 0;
510 }
511
512 AllSysInfo();
513
514 return 0;
515 }