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.
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.
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.
16 /* Copyright (C) 2007, Dmitry Chapyshev <lentind@yandex.ru> */
17 /* Copyright (C) 2011, Rafal Harabien <rafalh1992@o2.pl> */
35 #define BUFFER_SIZE 1024
37 /* Load string from registry */
40 RegGetSZ(HKEY hKey
, LPCWSTR lpSubKey
, LPCWSTR lpValueName
, LPWSTR lpBuf
, DWORD cchBuf
)
42 DWORD dwBytes
= cchBuf
*sizeof(WCHAR
), dwType
= 0;
45 /* If SubKey is specified open it */
46 if (lpSubKey
&& RegOpenKeyExW(hKey
,
50 &hKey
) != ERROR_SUCCESS
)
52 wprintf(L
"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey
, GetLastError());
56 /* Query registry value and check its type */
57 if (RegQueryValueExW(hKey
,
62 &dwBytes
) != ERROR_SUCCESS
|| (dwType
!= REG_SZ
&& dwType
!= REG_MULTI_SZ
))
64 wprintf(L
"Warning! Cannot query %s. Last error: %lu, type: %lu.\n", lpValueName
, GetLastError(), dwType
);
67 else if (dwBytes
== 0)
69 wcscpy(lpBuf
, L
"N/A");
73 /* Close key if we opened it */
77 cChars
= dwBytes
/sizeof(WCHAR
);
79 /* NULL-terminate string */
80 lpBuf
[min(cchBuf
-1, cChars
)] = L
'\0';
82 /* Don't count NULL characters */
83 while(cChars
&& !lpBuf
[cChars
-1])
89 /* Load DWORD from registry */
92 RegGetDWORD(HKEY hKey
, LPCWSTR lpSubKey
, LPCWSTR lpValueName
, LPDWORD lpData
)
94 DWORD dwBytes
= sizeof(*lpData
), dwType
;
97 /* If SubKey is specified open it */
98 if (lpSubKey
&& RegOpenKeyExW(hKey
,
102 &hKey
) != ERROR_SUCCESS
)
104 wprintf(L
"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey
, GetLastError());
108 /* Query registry value and check its type */
109 if (RegQueryValueExW(hKey
,
114 &dwBytes
) != ERROR_SUCCESS
|| dwType
!= REG_DWORD
)
116 wprintf(L
"Warning! Cannot query %s. Last err: %lu, type: %lu\n", lpValueName
, GetLastError(), dwType
);
121 /* Close key if we opened it */
131 FormatBytes(LPWSTR lpBuf
, unsigned cBytes
)
137 _itow(cBytes
/ (1024*1024), szMB
, 10);
142 fmt
.lpDecimalSep
= L
"";
143 fmt
.lpThousandSep
= L
" ";
144 fmt
.NegativeOrder
= 0;
146 i
= GetNumberFormatW(LOCALE_SYSTEM_DEFAULT
, 0, szMB
, &fmt
, lpBuf
, BUFFER_SIZE
- 3);
148 --i
; /* don't count NULL character */
149 wcscpy(lpBuf
+ i
, L
" MB");
152 /* Format date and time */
155 FormatDateTime(time_t Time
, LPWSTR lpBuf
)
159 const struct tm
*lpTm
;
161 lpTm
= localtime(&Time
);
162 SysTime
.wYear
= (WORD
)(1900 + lpTm
->tm_year
);
163 SysTime
.wMonth
= (WORD
)(1 + lpTm
->tm_mon
);
164 SysTime
.wDayOfWeek
= (WORD
)lpTm
->tm_wday
;
165 SysTime
.wDay
= (WORD
)lpTm
->tm_mday
;
166 SysTime
.wHour
= (WORD
)lpTm
->tm_hour
;
167 SysTime
.wMinute
= (WORD
)lpTm
->tm_min
;
168 SysTime
.wSecond
= (WORD
)lpTm
->tm_sec
;
169 SysTime
.wMilliseconds
= 0;
171 /* Copy date first */
172 i
= GetDateFormatW(LOCALE_SYSTEM_DEFAULT
, 0, &SysTime
, NULL
, lpBuf
, BUFFER_SIZE
- 2);
174 --i
; /* don't count NULL character */
177 i
+= swprintf(lpBuf
+ i
, L
", ");
179 GetTimeFormatW(LOCALE_SYSTEM_DEFAULT
, 0, &SysTime
, NULL
, lpBuf
+ i
, BUFFER_SIZE
- i
);
188 if (LoadStringW(GetModuleHandle(NULL
), IDS_USAGE
, Buf
, 4096))
194 PrintRow(UINT nTitleID
, BOOL bIndent
, LPWSTR lpFormat
, ...)
196 WCHAR Buf
[BUFFER_SIZE
];
202 c
= LoadStringW(GetModuleHandle(NULL
), nTitleID
, Buf
, BUFFER_SIZE
- 2);
206 wcscpy(Buf
+ c
, L
": ");
211 wprintf(L
"%-32s", Buf
);
213 wprintf(L
"%38s%-16s", L
"", Buf
);
215 wprintf(L
"%38s", L
"");
217 va_start(Args
, lpFormat
);
218 vwprintf(lpFormat
, Args
);
224 /* Print all system information */
228 DWORD dwCharCount
= BUFFER_SIZE
, dwTimestamp
, dwResult
;
229 OSVERSIONINFOW VersionInfo
;
231 WCHAR Buf
[BUFFER_SIZE
], Tmp
[BUFFER_SIZE
], szSystemDir
[MAX_PATH
];
232 const WCHAR
*lpcszSysType
;
234 NETSETUP_JOIN_STATUS NetJoinStatus
;
235 MEMORYSTATUS MemoryStatus
;
236 unsigned int cSeconds
, i
, j
;
237 TIME_ZONE_INFORMATION TimeZoneInfo
;
239 PIP_ADAPTER_ADDRESSES pAdapters
;
242 PCHAR DmiStrings
[ID_STRINGS_MAX
] = { 0 };
244 if (!GetSystemDirectoryW(szSystemDir
, sizeof(szSystemDir
)/sizeof(szSystemDir
[0])))
246 wprintf(L
"Error! GetSystemDirectory failed.\n");
250 GetSystemInfo(&SysInfo
);
252 // getting computer name
253 dwCharCount
= BUFFER_SIZE
;
254 if (!GetComputerNameW(Buf
, &dwCharCount
))
255 wprintf(L
"Error! GetComputerName failed.\n");
257 PrintRow(IDS_HOST_NAME
, FALSE
, L
"%s", Buf
);
259 // open CurrentVersion key
260 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
261 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
264 &hKey
) != ERROR_SUCCESS
)
266 wprintf(L
"Error! RegOpenKeyEx failed.\n");
271 RegGetSZ(hKey
, NULL
, L
"ProductName", Buf
, BUFFER_SIZE
);
272 PrintRow(IDS_OS_NAME
, FALSE
, L
"%s", Buf
);
275 ZeroMemory(&VersionInfo
, sizeof(VersionInfo
));
276 VersionInfo
.dwOSVersionInfoSize
= sizeof(VersionInfo
);
277 GetVersionExW(&VersionInfo
);
279 if (!LoadStringW(GetModuleHandle(NULL
), IDS_BUILD
, Tmp
, BUFFER_SIZE
))
281 PrintRow(IDS_OS_VERSION
,
283 L
"%lu.%lu.%lu %s %s %lu",
284 VersionInfo
.dwMajorVersion
,
285 VersionInfo
.dwMinorVersion
,
286 VersionInfo
.dwBuildNumber
,
287 VersionInfo
.szCSDVersion
,
289 VersionInfo
.dwBuildNumber
);
291 //getting OS Manufacturer
293 //getting OS Configuration
295 //getting OS Build Type
296 RegGetSZ(hKey
, NULL
, L
"CurrentType", Buf
, BUFFER_SIZE
);
297 PrintRow(IDS_OS_BUILD_TYPE
, FALSE
, L
"%s", Buf
);
299 //getting Registered Owner
300 RegGetSZ(hKey
, NULL
, L
"RegisteredOwner", Buf
, BUFFER_SIZE
);
301 PrintRow(IDS_REG_OWNER
, FALSE
, L
"%s", Buf
);
303 //getting Registered Organization
304 RegGetSZ(hKey
, NULL
, L
"RegisteredOrganization", Buf
, BUFFER_SIZE
);
305 PrintRow(IDS_REG_ORG
, FALSE
, L
"%s", Buf
);
308 RegGetSZ(hKey
, NULL
, L
"ProductId", Buf
, BUFFER_SIZE
);
309 PrintRow(IDS_PRODUCT_ID
, FALSE
, L
"%s", Buf
);
311 //getting Install Date
312 RegGetDWORD(hKey
, NULL
, L
"InstallDate", &dwTimestamp
);
313 FormatDateTime((time_t)dwTimestamp
, Buf
);
314 PrintRow(IDS_INST_DATE
, FALSE
, L
"%s", Buf
);
316 // close Current Version key now
319 //getting System Up Time
320 cSeconds
= GetTickCount() / 1000;
321 if (!LoadStringW(GetModuleHandle(NULL
), IDS_UP_TIME_FORMAT
, Tmp
, BUFFER_SIZE
))
323 swprintf(Buf
, Tmp
, cSeconds
/ (60*60*24), (cSeconds
/ (60*60)) % 24, (cSeconds
/ 60) % 60, cSeconds
% 60);
324 PrintRow(IDS_UP_TIME
, FALSE
, L
"%s", Buf
);
326 // prepare SMBIOS data
327 SMBiosBuf
= LoadSMBiosData(DmiStrings
);
329 //getting System Manufacturer; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Manufacturer for Win >= 6.0
330 swprintf(Tmp
, L
"%s\\oeminfo.ini", szSystemDir
);
331 GetPrivateProfileStringW(L
"General",
335 sizeof(Buf
)/sizeof(Buf
[0]),
337 if (wcslen(Buf
) == 0 && SMBiosBuf
)
339 GetSMBiosStringW(DmiStrings
[SYS_VENDOR
], Buf
, _countof(Buf
), FALSE
);
341 PrintRow(IDS_SYS_MANUFACTURER
, FALSE
, L
"%s", Buf
);
343 //getting System Model; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Model for Win >= 6.0
344 GetPrivateProfileStringW(L
"General",
348 sizeof(Buf
)/sizeof(Buf
[0]),
350 if (wcslen(Buf
) == 0 && SMBiosBuf
)
352 GetSMBiosStringW(DmiStrings
[SYS_PRODUCT
], Buf
, _countof(Buf
), FALSE
);
354 PrintRow(IDS_SYS_MODEL
, FALSE
, L
"%s", Buf
);
356 //getting System type
357 switch (SysInfo
.wProcessorArchitecture
)
359 case PROCESSOR_ARCHITECTURE_INTEL
:
360 lpcszSysType
= L
"X86-based PC";
362 case PROCESSOR_ARCHITECTURE_IA64
:
363 lpcszSysType
= L
"IA64-based PC";
365 case PROCESSOR_ARCHITECTURE_AMD64
:
366 lpcszSysType
= L
"AMD64-based PC";
369 lpcszSysType
= L
"Unknown";
372 PrintRow(IDS_SYS_TYPE
, FALSE
, L
"%s", lpcszSysType
);
374 //getting Processor(s)
375 if (!LoadStringW(GetModuleHandle(NULL
), IDS_PROCESSORS_FORMAT
, Tmp
, BUFFER_SIZE
))
377 swprintf(Buf
, Tmp
, (unsigned)SysInfo
.dwNumberOfProcessors
);
378 PrintRow(IDS_PROCESSORS
, FALSE
, L
"%s", Buf
);
379 for(i
= 0; i
< (unsigned int)SysInfo
.dwNumberOfProcessors
; i
++)
381 swprintf(Tmp
, L
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%u", i
);
382 j
= swprintf(Buf
, L
"[%02u]: ", i
+ 1);
384 j
+= RegGetSZ(HKEY_LOCAL_MACHINE
, Tmp
, L
"Identifier", Buf
+ j
, BUFFER_SIZE
- j
);
385 if(j
+ 1 < BUFFER_SIZE
)
387 RegGetSZ(HKEY_LOCAL_MACHINE
, Tmp
, L
"VendorIdentifier", Buf
+ j
, BUFFER_SIZE
- j
);
389 PrintRow(0, FALSE
, L
"%s", Buf
);
392 //getting BIOS Version
395 j
= GetSMBiosStringW(DmiStrings
[BIOS_VENDOR
], Buf
, BUFFER_SIZE
, TRUE
);
396 if (j
+ 1 < BUFFER_SIZE
)
401 GetSMBiosStringW(DmiStrings
[BIOS_VERSION
], Buf
+ j
, BUFFER_SIZE
- j
, TRUE
);
405 RegGetSZ(HKEY_LOCAL_MACHINE
,
406 L
"HARDWARE\\DESCRIPTION\\System",
407 L
"SystemBiosVersion",
411 PrintRow(IDS_BIOS_VERSION
, FALSE
, L
"%s", Buf
);
416 GetSMBiosStringW(DmiStrings
[BIOS_DATE
], Buf
, BUFFER_SIZE
, TRUE
);
420 RegGetSZ(HKEY_LOCAL_MACHINE
,
421 L
"HARDWARE\\DESCRIPTION\\System",
426 PrintRow(IDS_BIOS_DATE
, FALSE
, L
"%s", Buf
);
429 FreeSMBiosData(SMBiosBuf
);
431 //getting ReactOS Directory
432 if (!GetWindowsDirectoryW(Buf
, BUFFER_SIZE
))
433 wprintf(L
"Error! GetWindowsDirectory failed.");
435 PrintRow(IDS_ROS_DIR
, FALSE
, L
"%s", Buf
);
437 //getting System Directory
438 PrintRow(IDS_SYS_DIR
, 0, L
"%s", szSystemDir
);
440 //getting Boot Device
441 RegGetSZ(HKEY_LOCAL_MACHINE
,
446 PrintRow(IDS_BOOT_DEV
, FALSE
, L
"%s", Buf
);
448 //getting System Locale
449 if (GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT
, LOCALE_ILANGUAGE
, Tmp
, BUFFER_SIZE
))
450 if (RegGetSZ(HKEY_CLASSES_ROOT
,
451 L
"MIME\\Database\\Rfc1766",
456 /* get rid of @filename,resource */
457 lpBuffer
= wcschr(Buf
, L
';');
459 SHLoadIndirectString(lpBuffer
+1, lpBuffer
+1, BUFFER_SIZE
- (lpBuffer
-Buf
) - 1, NULL
);
461 PrintRow(IDS_SYS_LOCALE
, FALSE
, L
"%s", Buf
);
464 //getting Input Locale
465 if (RegGetSZ(HKEY_CURRENT_USER
,
466 L
"Keyboard Layout\\Preload",
469 BUFFER_SIZE
) && wcslen(Tmp
) > 4)
470 if (RegGetSZ(HKEY_CLASSES_ROOT
,
471 L
"MIME\\Database\\Rfc1766",
476 /* get rid of @filename,resource */
477 lpBuffer
= wcschr(Buf
, L
';');
479 SHLoadIndirectString(lpBuffer
+1, lpBuffer
+1, BUFFER_SIZE
- (lpBuffer
-Buf
) - 1, NULL
);
481 PrintRow(IDS_INPUT_LOCALE
, FALSE
, L
"%s", Buf
);
485 GetTimeZoneInformation(&TimeZoneInfo
);
487 /* Open Time Zones key */
488 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
489 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
491 KEY_ENUMERATE_SUB_KEYS
|KEY_READ
,
492 &hKey
) == ERROR_SUCCESS
)
496 /* Find current timezone */
497 dwCharCount
= BUFFER_SIZE
;
498 for(i
= 0; RegEnumKeyExW(hKey
, i
, Tmp
, &dwCharCount
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
; ++i
, dwCharCount
= 255)
500 RegGetSZ(hKey
, Tmp
, L
"Std", Buf
, BUFFER_SIZE
);
502 if (!wcscmp(Buf
, TimeZoneInfo
.StandardName
))
504 RegGetSZ(hKey
, Tmp
, L
"Display", Buf
, BUFFER_SIZE
);
506 PrintRow(IDS_TIME_ZONE
, FALSE
, L
"%s", Buf
);
514 //getting Total Physical Memory
515 GlobalMemoryStatus(&MemoryStatus
);
516 FormatBytes(Buf
, MemoryStatus
.dwTotalPhys
);
517 PrintRow(IDS_TOTAL_PHYS_MEM
, FALSE
, L
"%s", Buf
);
519 //getting Available Physical Memory
520 FormatBytes(Buf
, MemoryStatus
.dwAvailPhys
);
521 PrintRow(IDS_AVAIL_PHISICAL_MEM
, FALSE
, L
"%s", Buf
);
523 //getting Virtual Memory: Max Size
524 FormatBytes(Buf
, MemoryStatus
.dwTotalVirtual
);
525 PrintRow(IDS_VIRT_MEM_MAX
, FALSE
, L
"%s", Buf
);
527 //getting Virtual Memory: Available
528 FormatBytes(Buf
, MemoryStatus
.dwAvailVirtual
);
529 PrintRow(IDS_VIRT_MEM_AVAIL
, FALSE
, L
"%s", Buf
);
531 //getting Virtual Memory: In Use
532 FormatBytes(Buf
, MemoryStatus
.dwTotalVirtual
-MemoryStatus
.dwAvailVirtual
);
533 PrintRow(IDS_VIRT_MEM_INUSE
, FALSE
, L
"%s", Buf
);
535 //getting Page File Location(s)
536 if (RegGetSZ(HKEY_LOCAL_MACHINE
,
537 L
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management",
544 for(i
= 0; Buf
[i
]; i
++)
553 PrintRow(IDS_PAGEFILE_LOC
, FALSE
, L
"%s", Buf
);
557 if (NetGetJoinInformation (NULL
, &lpBuffer
, &NetJoinStatus
) == NERR_Success
)
559 if (NetJoinStatus
== NetSetupWorkgroupName
|| NetJoinStatus
== NetSetupDomainName
)
560 PrintRow(IDS_DOMAIN
, FALSE
, L
"%s", lpBuffer
);
562 NetApiBufferFree(lpBuffer
);
565 //getting Logon Server
567 //getting NetWork Card(s)
569 pAdapters
= malloc(cbAdapters
);
570 while((dwResult
= GetAdaptersAddresses(AF_UNSPEC
, 0x0002, NULL
, pAdapters
, &cbAdapters
)) == ERROR_BUFFER_OVERFLOW
)
573 pAdapters
= (PIP_ADAPTER_ADDRESSES
)realloc(pAdapters
, cbAdapters
);
576 if (dwResult
== ERROR_SUCCESS
)
578 PIP_ADAPTER_ADDRESSES pCurrentAdapter
= pAdapters
;
579 unsigned cAdapters
= 0;
582 for(i
= 0; pCurrentAdapter
; ++i
)
584 if (pCurrentAdapter
->IfType
!= 24 && pCurrentAdapter
->IfType
!= 131)
586 pCurrentAdapter
= pCurrentAdapter
->Next
;
590 /* Print adapters count */
591 if (!LoadStringW(GetModuleHandle(NULL
), IDS_NETWORK_CARDS_FORMAT
, Tmp
, BUFFER_SIZE
))
593 swprintf(Buf
, Tmp
, cAdapters
);
594 PrintRow(IDS_NETWORK_CARDS
, FALSE
, L
"%s", Buf
);
596 /* Show information about each adapter */
597 pCurrentAdapter
= pAdapters
;
598 for(i
= 0; pCurrentAdapter
; ++i
)
600 if (pCurrentAdapter
->IfType
!= 24 && pCurrentAdapter
->IfType
!= 131)//IF_TYPE_SOFTWARE_LOOPBACK)
602 PIP_ADAPTER_UNICAST_ADDRESS pAddress
;
604 PrintRow(0, FALSE
, L
"[%02u]: %s", i
+ 1, pCurrentAdapter
->Description
);
605 PrintRow(IDS_CONNECTION_NAME
, TRUE
, L
"%s", pCurrentAdapter
->FriendlyName
);
606 if (!(pCurrentAdapter
->Flags
& 0x0004))
608 if (!LoadStringW(GetModuleHandle(NULL
), IDS_NO
, Buf
, BUFFER_SIZE
))
610 PrintRow(IDS_DHCP_ENABLED
, TRUE
, Buf
);
612 if (pCurrentAdapter
->OperStatus
== IfOperStatusDown
)
614 if (!LoadStringW(GetModuleHandle(NULL
), IDS_MEDIA_DISCONNECTED
, Buf
, BUFFER_SIZE
))
616 PrintRow(IDS_STATUS
, TRUE
, Buf
);
620 if (!LoadStringW(GetModuleHandle(NULL
), IDS_IP_ADDRESSES
, Buf
, BUFFER_SIZE
))
622 PrintRow(0, TRUE
, Buf
);
623 pAddress
= pCurrentAdapter
->FirstUnicastAddress
;
624 for (j
= 0; pAddress
; ++j
)
626 dwCharCount
= BUFFER_SIZE
;
627 WSAAddressToStringW(pAddress
->Address
.lpSockaddr
, pAddress
->Address
.iSockaddrLength
, NULL
, Buf
, &dwCharCount
);
628 PrintRow(0, TRUE
, L
"[%02u]: %s", j
+ 1, Buf
);
629 pAddress
= pAddress
->Next
;
633 pCurrentAdapter
= pCurrentAdapter
->Next
;
641 main(int argc
, char *argv
[])
646 setlocale(LC_ALL
, "");
648 WSAStartup(MAKEWORD(2, 2), &WsaData
);
650 for (i
= 1; i
< argc
; ++i
)
652 if (!strcmp(argv
[i
], "/?") || !strcmp(argv
[i
], "-?"))
659 printf("Unsupported argument: %s\n", argv
[i
]);