3f8d354f49a17e25d6f5011df82ba609822fbc22
[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 <stdlib.h>
22 #include <string.h>
23 #include <ctype.h>
24 #include <windows.h>
25 #include <time.h>
26 #include <locale.h>
27 #include <lm.h>
28
29 #include "resource.h"
30
31 #define BUFFER_SIZE 32767
32
33 /* Load from resource and convert to OEM */
34 static
35 BOOL
36 GetOemStrings(UINT rcID, LPWSTR OutMsg)
37 {
38 if (LoadStringW(GetModuleHandle(NULL), rcID, OutMsg, BUFFER_SIZE))
39 return TRUE;
40
41 return FALSE;
42 }
43
44 /* Load data from registry */
45 static
46 BOOL
47 RegGetSZ(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPWSTR Buf)
48 {
49 DWORD dwBytes = BUFFER_SIZE*sizeof(WCHAR), dwType;
50 BOOL bRet = TRUE;
51
52 /* If SubKy is specified open it */
53 if (lpSubKey && RegOpenKeyExW(hKey,
54 lpSubKey,
55 0,
56 KEY_QUERY_VALUE,
57 &hKey) != ERROR_SUCCESS)
58 {
59 //wprintf("Warning! Cannot open %s. Last error: %lu.\n", lpSubKey, GetLastError());
60 return FALSE;
61 }
62
63 if (RegQueryValueExW(hKey,
64 lpValueName,
65 NULL,
66 &dwType,
67 (LPBYTE)Buf,
68 &dwBytes) != ERROR_SUCCESS || (dwType != REG_SZ && dwType != REG_MULTI_SZ))
69 {
70 //wprintf("Warning! Cannot query %s. Last error: %lu, type: %lu.\n", lpValueName, GetLastError(), dwType);
71 dwBytes = 0;
72 bRet = FALSE;
73 }
74
75 /* Close key if we opened it */
76 if (lpSubKey)
77 RegCloseKey(hKey);
78
79 /* NULL-terminate string */
80 Buf[min(BUFFER_SIZE-1, dwBytes/sizeof(WCHAR))] = L'\0';
81
82 return bRet;
83 }
84
85 static
86 BOOL
87 RegGetDWORD(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPDWORD lpData)
88 {
89 DWORD dwBytes = sizeof(*lpData), dwType;
90 BOOL bRet = TRUE;
91
92 /* If SubKy is specified open it */
93 if (lpSubKey && RegOpenKeyExW(hKey,
94 lpSubKey,
95 0,
96 KEY_QUERY_VALUE,
97 &hKey) != ERROR_SUCCESS)
98 {
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("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 lpNetBuffer;
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 (RegGetSZ(HKEY_CURRENT_USER,
371 L"Control Panel\\International",
372 L"Locale",
373 Tmp))
374 if (RegGetSZ(HKEY_CLASSES_ROOT,
375 L"MIME\\Database\\Rfc1766",
376 Tmp,
377 Buf))
378 if (GetOemStrings(IDS_SYS_LOCALE, Msg))
379 wprintf(Msg, Buf);
380
381 //getting Input Locale
382 if (RegGetSZ(HKEY_CURRENT_USER,
383 L"Keyboard Layout\\Preload",
384 L"1",
385 Buf))
386 {
387 int i, j;
388
389 for(j = 0, i = 4; i <= 8; j++, i++)
390 Tmp[j] = Buf[i];
391
392 if (RegGetSZ(HKEY_CLASSES_ROOT,
393 L"MIME\\Database\\Rfc1766",
394 Tmp,
395 Buf))
396 if (GetOemStrings(IDS_INPUT_LOCALE, Msg))
397 wprintf(Msg, Buf);
398 }
399
400 //getting Time Zone
401 GetTimeZoneInformation(&TimeZoneInfo);
402
403 /* Open Time Zones key */
404 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
405 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
406 0,
407 KEY_ENUMERATE_SUB_KEYS|KEY_READ,
408 &hKey) == ERROR_SUCCESS)
409 {
410 unsigned i;
411
412 /* Find current timezone */
413 dwCharCount = 256; // Windows seems to have a bug - it doesnt accept BUFFER_SIZE here
414 for(i = 0; RegEnumKeyExW(hKey, i, Tmp, &dwCharCount, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++i, dwCharCount = 255)
415 {
416 RegGetSZ(hKey, Tmp, L"Std", Buf);
417
418 if(!wcscmp(Buf, TimeZoneInfo.StandardName))
419 {
420 RegGetSZ(hKey, Tmp, L"Display", Buf);
421
422 if (GetOemStrings(IDS_TIME_ZONE, Msg))
423 wprintf(Msg, Buf);
424
425 break;
426 }
427 }
428 RegCloseKey(hKey);
429 }
430
431 //getting Total Physical Memory
432 GlobalMemoryStatus(&MemoryStatus);
433 FormatBytes(Buf, MemoryStatus.dwTotalPhys);
434 if (GetOemStrings(IDS_TOTAL_PHYS_MEM, Msg))
435 wprintf(Msg, Buf);
436
437 //getting Available Physical Memory
438 FormatBytes(Buf, MemoryStatus.dwAvailPhys);
439 if (GetOemStrings(IDS_AVAIL_PHISICAL_MEM,Msg))
440 wprintf(Msg, Buf);
441
442 //getting Virtual Memory: Max Size
443 FormatBytes(Buf, MemoryStatus.dwTotalVirtual);
444 if (GetOemStrings(IDS_VIRT_MEM_MAX, Msg))
445 wprintf(Msg, Buf);
446
447 //getting Virtual Memory: Available
448 FormatBytes(Buf, MemoryStatus.dwAvailVirtual);
449 if (GetOemStrings(IDS_VIRT_MEM_AVAIL, Msg))
450 wprintf(Msg, Buf);
451
452 //getting Virtual Memory: In Use
453 FormatBytes(Buf, MemoryStatus.dwTotalVirtual-MemoryStatus.dwAvailVirtual);
454 if (GetOemStrings(IDS_VIRT_MEM_INUSE, Msg))
455 wprintf(Msg, Buf);
456
457 //getting Page File Location(s)
458 if (RegGetSZ(HKEY_LOCAL_MACHINE,
459 L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management",
460 L"PagingFiles",
461 Buf))
462 {
463 int i;
464
465 for(i = 0; i < strlen((char*)Buf); i++)
466 {
467 if (Buf[i] == TEXT(' '))
468 {
469 Buf[i] = TEXT('\0');
470 break;
471 }
472 }
473
474 if(GetOemStrings(IDS_PAGEFILE_LOC, Msg))
475 wprintf(Msg, Buf);
476 }
477
478 //getting Domain
479 if (NetGetJoinInformation (NULL, &lpNetBuffer, &NetJoinStatus) == NERR_Success)
480 {
481 if(GetOemStrings(IDS_DOMAIN, Msg))
482 wprintf(Msg, lpNetBuffer);
483
484 NetApiBufferFree(lpNetBuffer);
485 }
486
487 //getting Logon Server
488
489 //getting NetWork Card(s)
490 if(GetOemStrings(IDS_NETWORK_CARDS, Msg))
491 {
492
493 }
494 }
495
496 /* Main program */
497 int
498 main(int argc, char *argv[])
499 {
500 setlocale(LC_ALL, "");
501
502 if (argc > 1 && (!strcmp(argv[1], "/?") || !strcmp(argv[1], "-?")))
503 {
504 Usage();
505 return 0;
506 }
507
508 AllSysInfo();
509
510 return 0;
511 }