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> */
34 #define BUFFER_SIZE 1024
36 /* Load string from registry */
39 RegGetSZ(HKEY hKey
, LPCWSTR lpSubKey
, LPCWSTR lpValueName
, LPWSTR lpBuf
, DWORD cchBuf
)
41 DWORD dwBytes
= cchBuf
*sizeof(WCHAR
), dwType
= 0;
44 /* If SubKey is specified open it */
45 if (lpSubKey
&& RegOpenKeyExW(hKey
,
49 &hKey
) != ERROR_SUCCESS
)
51 wprintf(L
"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey
, GetLastError());
55 /* Query registry value and check its type */
56 if (RegQueryValueExW(hKey
,
61 &dwBytes
) != ERROR_SUCCESS
|| (dwType
!= REG_SZ
&& dwType
!= REG_MULTI_SZ
))
63 wprintf(L
"Warning! Cannot query %s. Last error: %lu, type: %lu.\n", lpValueName
, GetLastError(), dwType
);
66 else if (dwBytes
== 0)
68 wcscpy(lpBuf
, L
"N/A");
72 /* Close key if we opened it */
76 cChars
= dwBytes
/sizeof(WCHAR
);
78 /* NULL-terminate string */
79 lpBuf
[min(cchBuf
-1, cChars
)] = L
'\0';
81 /* Don't count NULL characters */
82 while(cChars
&& !lpBuf
[cChars
-1])
88 /* Load DWORD from registry */
91 RegGetDWORD(HKEY hKey
, LPCWSTR lpSubKey
, LPCWSTR lpValueName
, LPDWORD lpData
)
93 DWORD dwBytes
= sizeof(*lpData
), dwType
;
96 /* If SubKey is specified open it */
97 if (lpSubKey
&& RegOpenKeyExW(hKey
,
101 &hKey
) != ERROR_SUCCESS
)
103 wprintf(L
"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey
, GetLastError());
107 /* Query registry value and check its type */
108 if (RegQueryValueExW(hKey
,
113 &dwBytes
) != ERROR_SUCCESS
|| dwType
!= REG_DWORD
)
115 wprintf(L
"Warning! Cannot query %s. Last err: %lu, type: %lu\n", lpValueName
, GetLastError(), dwType
);
120 /* Close key if we opened it */
130 FormatBytes(LPWSTR lpBuf
, unsigned cBytes
)
136 _itow(cBytes
/ (1024*1024), szMB
, 10);
141 fmt
.lpDecimalSep
= L
"";
142 fmt
.lpThousandSep
= L
" ";
143 fmt
.NegativeOrder
= 0;
145 i
= GetNumberFormatW(LOCALE_SYSTEM_DEFAULT
, 0, szMB
, &fmt
, lpBuf
, BUFFER_SIZE
- 3);
147 --i
; /* don't count NULL character */
148 wcscpy(lpBuf
+ i
, L
" MB");
151 /* Format date and time */
154 FormatDateTime(time_t Time
, LPWSTR lpBuf
)
158 const struct tm
*lpTm
;
160 lpTm
= localtime(&Time
);
161 SysTime
.wYear
= (WORD
)(1900 + lpTm
->tm_year
);
162 SysTime
.wMonth
= (WORD
)(1 + lpTm
->tm_mon
);
163 SysTime
.wDayOfWeek
= (WORD
)lpTm
->tm_wday
;
164 SysTime
.wDay
= (WORD
)lpTm
->tm_mday
;
165 SysTime
.wHour
= (WORD
)lpTm
->tm_hour
;
166 SysTime
.wMinute
= (WORD
)lpTm
->tm_min
;
167 SysTime
.wSecond
= (WORD
)lpTm
->tm_sec
;
168 SysTime
.wMilliseconds
= 0;
170 /* Copy date first */
171 i
= GetDateFormatW(LOCALE_SYSTEM_DEFAULT
, 0, &SysTime
, NULL
, lpBuf
, BUFFER_SIZE
- 2);
173 --i
; /* don't count NULL character */
176 i
+= swprintf(lpBuf
+ i
, L
", ");
178 GetTimeFormatW(LOCALE_SYSTEM_DEFAULT
, 0, &SysTime
, NULL
, lpBuf
+ i
, BUFFER_SIZE
- i
);
181 ULONGLONG
GetSecondsQPC(VOID
)
183 LARGE_INTEGER Counter
, Frequency
;
185 QueryPerformanceCounter(&Counter
);
186 QueryPerformanceFrequency(&Frequency
);
188 return Counter
.QuadPart
/ Frequency
.QuadPart
;
191 ULONGLONG
GetSeconds(VOID
)
193 ULONGLONG (WINAPI
* pGetTickCount64
)(VOID
);
195 HMODULE hModule
= GetModuleHandleW(L
"kernel32.dll");
197 pGetTickCount64
= (PVOID
)GetProcAddress(hModule
, "GetTickCount64");
200 return pGetTickCount64() / 1000;
203 hModule
= LoadLibraryW(L
"kernel32_vista.dll");
207 return GetSecondsQPC();
210 pGetTickCount64
= (PVOID
)GetProcAddress(hModule
, "GetTickCount64");
214 Ticks64
= pGetTickCount64() / 1000;
218 Ticks64
= GetSecondsQPC();
221 FreeLibrary(hModule
);
231 if (LoadStringW(GetModuleHandle(NULL
), IDS_USAGE
, Buf
, 4096))
237 PrintRow(UINT nTitleID
, BOOL bIndent
, LPWSTR lpFormat
, ...)
239 WCHAR Buf
[BUFFER_SIZE
];
245 c
= LoadStringW(GetModuleHandle(NULL
), nTitleID
, Buf
, BUFFER_SIZE
- 2);
249 wcscpy(Buf
+ c
, L
": ");
254 wprintf(L
"%-32s", Buf
);
256 wprintf(L
"%38s%-16s", L
"", Buf
);
258 wprintf(L
"%38s", L
"");
260 va_start(Args
, lpFormat
);
261 vwprintf(lpFormat
, Args
);
267 /* Print all system information */
271 DWORD dwCharCount
= BUFFER_SIZE
, dwTimestamp
, dwResult
;
272 OSVERSIONINFOW VersionInfo
;
274 WCHAR Buf
[BUFFER_SIZE
], Tmp
[BUFFER_SIZE
], szSystemDir
[MAX_PATH
];
275 const WCHAR
*lpcszSysType
;
277 NETSETUP_JOIN_STATUS NetJoinStatus
;
278 MEMORYSTATUS MemoryStatus
;
279 unsigned int cSeconds
, i
, j
;
280 TIME_ZONE_INFORMATION TimeZoneInfo
;
282 PIP_ADAPTER_ADDRESSES pAdapters
;
285 PCHAR DmiStrings
[ID_STRINGS_MAX
] = { 0 };
287 if (!GetSystemDirectoryW(szSystemDir
, sizeof(szSystemDir
)/sizeof(szSystemDir
[0])))
289 wprintf(L
"Error! GetSystemDirectory failed.\n");
293 GetSystemInfo(&SysInfo
);
295 // getting computer name
296 dwCharCount
= BUFFER_SIZE
;
297 if (!GetComputerNameW(Buf
, &dwCharCount
))
298 wprintf(L
"Error! GetComputerName failed.\n");
300 PrintRow(IDS_HOST_NAME
, FALSE
, L
"%s", Buf
);
302 // open CurrentVersion key
303 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
304 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
307 &hKey
) != ERROR_SUCCESS
)
309 wprintf(L
"Error! RegOpenKeyEx failed.\n");
314 RegGetSZ(hKey
, NULL
, L
"ProductName", Buf
, BUFFER_SIZE
);
315 PrintRow(IDS_OS_NAME
, FALSE
, L
"%s", Buf
);
318 ZeroMemory(&VersionInfo
, sizeof(VersionInfo
));
319 VersionInfo
.dwOSVersionInfoSize
= sizeof(VersionInfo
);
320 GetVersionExW(&VersionInfo
);
322 if (!LoadStringW(GetModuleHandle(NULL
), IDS_BUILD
, Tmp
, BUFFER_SIZE
))
324 PrintRow(IDS_OS_VERSION
,
326 L
"%lu.%lu.%lu %s %s %lu",
327 VersionInfo
.dwMajorVersion
,
328 VersionInfo
.dwMinorVersion
,
329 VersionInfo
.dwBuildNumber
,
330 VersionInfo
.szCSDVersion
,
332 VersionInfo
.dwBuildNumber
);
334 //getting OS Manufacturer
336 //getting OS Configuration
338 //getting OS Build Type
339 RegGetSZ(hKey
, NULL
, L
"CurrentType", Buf
, BUFFER_SIZE
);
340 PrintRow(IDS_OS_BUILD_TYPE
, FALSE
, L
"%s", Buf
);
342 //getting Registered Owner
343 RegGetSZ(hKey
, NULL
, L
"RegisteredOwner", Buf
, BUFFER_SIZE
);
344 PrintRow(IDS_REG_OWNER
, FALSE
, L
"%s", Buf
);
346 //getting Registered Organization
347 RegGetSZ(hKey
, NULL
, L
"RegisteredOrganization", Buf
, BUFFER_SIZE
);
348 PrintRow(IDS_REG_ORG
, FALSE
, L
"%s", Buf
);
351 RegGetSZ(hKey
, NULL
, L
"ProductId", Buf
, BUFFER_SIZE
);
352 PrintRow(IDS_PRODUCT_ID
, FALSE
, L
"%s", Buf
);
354 //getting Install Date
355 RegGetDWORD(hKey
, NULL
, L
"InstallDate", &dwTimestamp
);
356 FormatDateTime((time_t)dwTimestamp
, Buf
);
357 PrintRow(IDS_INST_DATE
, FALSE
, L
"%s", Buf
);
359 // close Current Version key now
362 //getting System Up Time
363 cSeconds
= GetSeconds();
364 if (!LoadStringW(GetModuleHandle(NULL
), IDS_UP_TIME_FORMAT
, Tmp
, BUFFER_SIZE
))
366 swprintf(Buf
, Tmp
, cSeconds
/ (60*60*24), (cSeconds
/ (60*60)) % 24, (cSeconds
/ 60) % 60, cSeconds
% 60);
367 PrintRow(IDS_UP_TIME
, FALSE
, L
"%s", Buf
);
369 // prepare SMBIOS data
370 SMBiosBuf
= LoadSMBiosData(DmiStrings
);
372 //getting System Manufacturer; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Manufacturer for Win >= 6.0
373 swprintf(Tmp
, L
"%s\\oeminfo.ini", szSystemDir
);
374 GetPrivateProfileStringW(L
"General",
378 sizeof(Buf
)/sizeof(Buf
[0]),
380 if (wcslen(Buf
) == 0 && SMBiosBuf
)
382 GetSMBiosStringW(DmiStrings
[SYS_VENDOR
], Buf
, _countof(Buf
), FALSE
);
384 PrintRow(IDS_SYS_MANUFACTURER
, FALSE
, L
"%s", Buf
);
386 //getting System Model; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Model for Win >= 6.0
387 GetPrivateProfileStringW(L
"General",
391 sizeof(Buf
)/sizeof(Buf
[0]),
393 if (wcslen(Buf
) == 0 && SMBiosBuf
)
395 GetSMBiosStringW(DmiStrings
[SYS_PRODUCT
], Buf
, _countof(Buf
), FALSE
);
397 PrintRow(IDS_SYS_MODEL
, FALSE
, L
"%s", Buf
);
399 //getting System type
400 switch (SysInfo
.wProcessorArchitecture
)
402 case PROCESSOR_ARCHITECTURE_INTEL
:
403 lpcszSysType
= L
"X86-based PC";
405 case PROCESSOR_ARCHITECTURE_IA64
:
406 lpcszSysType
= L
"IA64-based PC";
408 case PROCESSOR_ARCHITECTURE_AMD64
:
409 lpcszSysType
= L
"AMD64-based PC";
412 lpcszSysType
= L
"Unknown";
415 PrintRow(IDS_SYS_TYPE
, FALSE
, L
"%s", lpcszSysType
);
417 //getting Processor(s)
418 if (!LoadStringW(GetModuleHandle(NULL
), IDS_PROCESSORS_FORMAT
, Tmp
, BUFFER_SIZE
))
420 swprintf(Buf
, Tmp
, (unsigned)SysInfo
.dwNumberOfProcessors
);
421 PrintRow(IDS_PROCESSORS
, FALSE
, L
"%s", Buf
);
422 for(i
= 0; i
< (unsigned int)SysInfo
.dwNumberOfProcessors
; i
++)
424 swprintf(Tmp
, L
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%u", i
);
425 j
= swprintf(Buf
, L
"[%02u]: ", i
+ 1);
427 j
+= RegGetSZ(HKEY_LOCAL_MACHINE
, Tmp
, L
"Identifier", Buf
+ j
, BUFFER_SIZE
- j
);
428 if(j
+ 1 < BUFFER_SIZE
)
430 RegGetSZ(HKEY_LOCAL_MACHINE
, Tmp
, L
"VendorIdentifier", Buf
+ j
, BUFFER_SIZE
- j
);
432 PrintRow(0, FALSE
, L
"%s", Buf
);
435 //getting BIOS Version
438 j
= GetSMBiosStringW(DmiStrings
[BIOS_VENDOR
], Buf
, BUFFER_SIZE
, TRUE
);
439 if (j
+ 1 < BUFFER_SIZE
)
444 GetSMBiosStringW(DmiStrings
[BIOS_VERSION
], Buf
+ j
, BUFFER_SIZE
- j
, TRUE
);
448 RegGetSZ(HKEY_LOCAL_MACHINE
,
449 L
"HARDWARE\\DESCRIPTION\\System",
450 L
"SystemBiosVersion",
454 PrintRow(IDS_BIOS_VERSION
, FALSE
, L
"%s", Buf
);
459 GetSMBiosStringW(DmiStrings
[BIOS_DATE
], Buf
, BUFFER_SIZE
, TRUE
);
463 RegGetSZ(HKEY_LOCAL_MACHINE
,
464 L
"HARDWARE\\DESCRIPTION\\System",
469 PrintRow(IDS_BIOS_DATE
, FALSE
, L
"%s", Buf
);
472 FreeSMBiosData(SMBiosBuf
);
474 //getting ReactOS Directory
475 if (!GetWindowsDirectoryW(Buf
, BUFFER_SIZE
))
476 wprintf(L
"Error! GetWindowsDirectory failed.");
478 PrintRow(IDS_ROS_DIR
, FALSE
, L
"%s", Buf
);
480 //getting System Directory
481 PrintRow(IDS_SYS_DIR
, 0, L
"%s", szSystemDir
);
483 //getting Boot Device
484 RegGetSZ(HKEY_LOCAL_MACHINE
,
489 PrintRow(IDS_BOOT_DEV
, FALSE
, L
"%s", Buf
);
491 //getting System Locale
492 if (GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT
, LOCALE_ILANGUAGE
, Tmp
, BUFFER_SIZE
))
493 if (RegGetSZ(HKEY_CLASSES_ROOT
,
494 L
"MIME\\Database\\Rfc1766",
499 /* get rid of @filename,resource */
500 lpBuffer
= wcschr(Buf
, L
';');
502 SHLoadIndirectString(lpBuffer
+1, lpBuffer
+1, BUFFER_SIZE
- (lpBuffer
-Buf
) - 1, NULL
);
504 PrintRow(IDS_SYS_LOCALE
, FALSE
, L
"%s", Buf
);
507 //getting Input Locale
508 if (RegGetSZ(HKEY_CURRENT_USER
,
509 L
"Keyboard Layout\\Preload",
512 BUFFER_SIZE
) && wcslen(Tmp
) > 4)
513 if (RegGetSZ(HKEY_CLASSES_ROOT
,
514 L
"MIME\\Database\\Rfc1766",
519 /* get rid of @filename,resource */
520 lpBuffer
= wcschr(Buf
, L
';');
522 SHLoadIndirectString(lpBuffer
+1, lpBuffer
+1, BUFFER_SIZE
- (lpBuffer
-Buf
) - 1, NULL
);
524 PrintRow(IDS_INPUT_LOCALE
, FALSE
, L
"%s", Buf
);
528 GetTimeZoneInformation(&TimeZoneInfo
);
530 /* Open Time Zones key */
531 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
532 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
534 KEY_ENUMERATE_SUB_KEYS
|KEY_READ
,
535 &hKey
) == ERROR_SUCCESS
)
539 /* Find current timezone */
540 dwCharCount
= BUFFER_SIZE
;
541 for(i
= 0; RegEnumKeyExW(hKey
, i
, Tmp
, &dwCharCount
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
; ++i
, dwCharCount
= 255)
543 RegGetSZ(hKey
, Tmp
, L
"Std", Buf
, BUFFER_SIZE
);
545 if (!wcscmp(Buf
, TimeZoneInfo
.StandardName
))
547 RegGetSZ(hKey
, Tmp
, L
"Display", Buf
, BUFFER_SIZE
);
549 PrintRow(IDS_TIME_ZONE
, FALSE
, L
"%s", Buf
);
557 //getting Total Physical Memory
558 GlobalMemoryStatus(&MemoryStatus
);
559 FormatBytes(Buf
, MemoryStatus
.dwTotalPhys
);
560 PrintRow(IDS_TOTAL_PHYS_MEM
, FALSE
, L
"%s", Buf
);
562 //getting Available Physical Memory
563 FormatBytes(Buf
, MemoryStatus
.dwAvailPhys
);
564 PrintRow(IDS_AVAIL_PHISICAL_MEM
, FALSE
, L
"%s", Buf
);
566 //getting Virtual Memory: Max Size
567 FormatBytes(Buf
, MemoryStatus
.dwTotalVirtual
);
568 PrintRow(IDS_VIRT_MEM_MAX
, FALSE
, L
"%s", Buf
);
570 //getting Virtual Memory: Available
571 FormatBytes(Buf
, MemoryStatus
.dwAvailVirtual
);
572 PrintRow(IDS_VIRT_MEM_AVAIL
, FALSE
, L
"%s", Buf
);
574 //getting Virtual Memory: In Use
575 FormatBytes(Buf
, MemoryStatus
.dwTotalVirtual
-MemoryStatus
.dwAvailVirtual
);
576 PrintRow(IDS_VIRT_MEM_INUSE
, FALSE
, L
"%s", Buf
);
578 //getting Page File Location(s)
579 if (RegGetSZ(HKEY_LOCAL_MACHINE
,
580 L
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management",
587 for(i
= 0; Buf
[i
]; i
++)
596 PrintRow(IDS_PAGEFILE_LOC
, FALSE
, L
"%s", Buf
);
600 if (NetGetJoinInformation (NULL
, &lpBuffer
, &NetJoinStatus
) == NERR_Success
)
602 if (NetJoinStatus
== NetSetupWorkgroupName
|| NetJoinStatus
== NetSetupDomainName
)
603 PrintRow(IDS_DOMAIN
, FALSE
, L
"%s", lpBuffer
);
605 NetApiBufferFree(lpBuffer
);
608 //getting Logon Server
610 //getting NetWork Card(s)
612 pAdapters
= malloc(cbAdapters
);
613 while((dwResult
= GetAdaptersAddresses(AF_UNSPEC
, 0x0002, NULL
, pAdapters
, &cbAdapters
)) == ERROR_BUFFER_OVERFLOW
)
616 pAdapters
= (PIP_ADAPTER_ADDRESSES
)realloc(pAdapters
, cbAdapters
);
619 if (dwResult
== ERROR_SUCCESS
)
621 PIP_ADAPTER_ADDRESSES pCurrentAdapter
= pAdapters
;
622 unsigned cAdapters
= 0;
625 for(i
= 0; pCurrentAdapter
; ++i
)
627 if (pCurrentAdapter
->IfType
!= 24 && pCurrentAdapter
->IfType
!= 131)
629 pCurrentAdapter
= pCurrentAdapter
->Next
;
633 /* Print adapters count */
634 if (!LoadStringW(GetModuleHandle(NULL
), IDS_NETWORK_CARDS_FORMAT
, Tmp
, BUFFER_SIZE
))
636 swprintf(Buf
, Tmp
, cAdapters
);
637 PrintRow(IDS_NETWORK_CARDS
, FALSE
, L
"%s", Buf
);
639 /* Show information about each adapter */
640 pCurrentAdapter
= pAdapters
;
641 for(i
= 0; pCurrentAdapter
; ++i
)
643 if (pCurrentAdapter
->IfType
!= 24 && pCurrentAdapter
->IfType
!= 131)//IF_TYPE_SOFTWARE_LOOPBACK)
645 PIP_ADAPTER_UNICAST_ADDRESS pAddress
;
647 PrintRow(0, FALSE
, L
"[%02u]: %s", i
+ 1, pCurrentAdapter
->Description
);
648 PrintRow(IDS_CONNECTION_NAME
, TRUE
, L
"%s", pCurrentAdapter
->FriendlyName
);
649 if (!(pCurrentAdapter
->Flags
& 0x0004))
651 if (!LoadStringW(GetModuleHandle(NULL
), IDS_NO
, Buf
, BUFFER_SIZE
))
653 PrintRow(IDS_DHCP_ENABLED
, TRUE
, Buf
);
655 if (pCurrentAdapter
->OperStatus
== IfOperStatusDown
)
657 if (!LoadStringW(GetModuleHandle(NULL
), IDS_MEDIA_DISCONNECTED
, Buf
, BUFFER_SIZE
))
659 PrintRow(IDS_STATUS
, TRUE
, Buf
);
663 if (!LoadStringW(GetModuleHandle(NULL
), IDS_IP_ADDRESSES
, Buf
, BUFFER_SIZE
))
665 PrintRow(0, TRUE
, Buf
);
666 pAddress
= pCurrentAdapter
->FirstUnicastAddress
;
667 for (j
= 0; pAddress
; ++j
)
669 dwCharCount
= BUFFER_SIZE
;
670 WSAAddressToStringW(pAddress
->Address
.lpSockaddr
, pAddress
->Address
.iSockaddrLength
, NULL
, Buf
, &dwCharCount
);
671 PrintRow(0, TRUE
, L
"[%02u]: %s", j
+ 1, Buf
);
672 pAddress
= pAddress
->Next
;
676 pCurrentAdapter
= pCurrentAdapter
->Next
;
684 main(int argc
, char *argv
[])
689 setlocale(LC_ALL
, "");
691 WSAStartup(MAKEWORD(2, 2), &WsaData
);
693 for (i
= 1; i
< argc
; ++i
)
695 if (!strcmp(argv
[i
], "/?") || !strcmp(argv
[i
], "-?"))
702 printf("Unsupported argument: %s\n", argv
[i
]);