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