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> */
33 #define BUFFER_SIZE 1024
35 /* Load string from registry */
38 RegGetSZ(HKEY hKey
, LPCWSTR lpSubKey
, LPCWSTR lpValueName
, LPWSTR lpBuf
, DWORD cchBuf
)
40 DWORD dwBytes
= cchBuf
*sizeof(WCHAR
), dwType
= 0;
43 /* If SubKey is specified open it */
44 if (lpSubKey
&& RegOpenKeyExW(hKey
,
48 &hKey
) != ERROR_SUCCESS
)
50 wprintf(L
"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey
, GetLastError());
54 /* Query registry value and check its type */
55 if (RegQueryValueExW(hKey
,
60 &dwBytes
) != ERROR_SUCCESS
|| (dwType
!= REG_SZ
&& dwType
!= REG_MULTI_SZ
))
62 wprintf(L
"Warning! Cannot query %s. Last error: %lu, type: %lu.\n", lpValueName
, GetLastError(), dwType
);
67 wcscpy(lpBuf
, L
"N/A");
71 /* Close key if we opened it */
75 cChars
= dwBytes
/sizeof(WCHAR
);
77 /* NULL-terminate string */
78 lpBuf
[min(cchBuf
-1, cChars
)] = L
'\0';
80 /* Don't count NULL characters */
81 while(cChars
&& !lpBuf
[cChars
-1])
87 /* Load DWORD from registry */
90 RegGetDWORD(HKEY hKey
, LPCWSTR lpSubKey
, LPCWSTR lpValueName
, LPDWORD lpData
)
92 DWORD dwBytes
= sizeof(*lpData
), dwType
;
95 /* If SubKey is specified open it */
96 if (lpSubKey
&& RegOpenKeyExW(hKey
,
100 &hKey
) != ERROR_SUCCESS
)
102 wprintf(L
"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey
, GetLastError());
106 /* Query registry value and check its type */
107 if (RegQueryValueExW(hKey
,
112 &dwBytes
) != ERROR_SUCCESS
|| dwType
!= REG_DWORD
)
114 wprintf(L
"Warning! Cannot query %s. Last err: %lu, type: %lu\n", lpValueName
, GetLastError(), dwType
);
119 /* Close key if we opened it */
129 FormatBytes(LPWSTR lpBuf
, unsigned cBytes
)
135 _itow(cBytes
/ (1024*1024), szMB
, 10);
140 fmt
.lpDecimalSep
= L
"";
141 fmt
.lpThousandSep
= L
" ";
142 fmt
.NegativeOrder
= 0;
144 i
= GetNumberFormatW(LOCALE_SYSTEM_DEFAULT
, 0, szMB
, &fmt
, lpBuf
, BUFFER_SIZE
- 3);
146 --i
; /* don't count NULL character */
147 wcscpy(lpBuf
+ i
, L
" MB");
150 /* Format date and time */
153 FormatDateTime(time_t Time
, LPWSTR lpBuf
)
157 const struct tm
*lpTm
;
159 lpTm
= localtime(&Time
);
160 SysTime
.wYear
= (WORD
)(1900 + lpTm
->tm_year
);
161 SysTime
.wMonth
= (WORD
)(1 + lpTm
->tm_mon
);
162 SysTime
.wDayOfWeek
= (WORD
)lpTm
->tm_wday
;
163 SysTime
.wDay
= (WORD
)lpTm
->tm_mday
;
164 SysTime
.wHour
= (WORD
)lpTm
->tm_hour
;
165 SysTime
.wMinute
= (WORD
)lpTm
->tm_min
;
166 SysTime
.wSecond
= (WORD
)lpTm
->tm_sec
;
167 SysTime
.wMilliseconds
= 0;
169 /* Copy date first */
170 i
= GetDateFormatW(LOCALE_SYSTEM_DEFAULT
, 0, &SysTime
, NULL
, lpBuf
, BUFFER_SIZE
- 2);
172 --i
; /* don't count NULL character */
175 i
+= swprintf(lpBuf
+ i
, L
", ");
177 GetTimeFormatW(LOCALE_SYSTEM_DEFAULT
, 0, &SysTime
, NULL
, lpBuf
+ i
, BUFFER_SIZE
- i
);
186 if (LoadStringW(GetModuleHandle(NULL
), IDS_USAGE
, Buf
, 4096))
192 PrintRow(UINT nTitleID
, BOOL bIndent
, LPWSTR lpFormat
, ...)
194 WCHAR Buf
[BUFFER_SIZE
];
200 c
= LoadStringW(GetModuleHandle(NULL
), nTitleID
, Buf
, BUFFER_SIZE
- 2);
204 wcscpy(Buf
+ c
, L
": ");
209 wprintf(L
"%-32s", Buf
);
211 wprintf(L
"%38s%-16s", L
"", Buf
);
213 wprintf(L
"%38s", L
"");
215 va_start(Args
, lpFormat
);
216 vwprintf(lpFormat
, Args
);
222 /* Print all system information */
226 DWORD dwCharCount
= BUFFER_SIZE
, dwTimestamp
, dwResult
;
227 OSVERSIONINFOW VersionInfo
;
229 WCHAR Buf
[BUFFER_SIZE
], Tmp
[BUFFER_SIZE
], szSystemDir
[MAX_PATH
];
230 const WCHAR
*lpcszSysType
;
232 NETSETUP_JOIN_STATUS NetJoinStatus
;
233 MEMORYSTATUS MemoryStatus
;
234 unsigned int cSeconds
, i
, j
;
235 TIME_ZONE_INFORMATION TimeZoneInfo
;
237 PIP_ADAPTER_ADDRESSES pAdapters
;
240 if (!GetSystemDirectoryW(szSystemDir
, sizeof(szSystemDir
)/sizeof(szSystemDir
[0])))
242 wprintf(L
"Error! GetSystemDirectory failed.\n");
246 GetSystemInfo(&SysInfo
);
248 // getting computer name
249 dwCharCount
= BUFFER_SIZE
;
250 if (!GetComputerNameW(Buf
, &dwCharCount
))
251 wprintf(L
"Error! GetComputerName failed.\n");
253 PrintRow(IDS_HOST_NAME
, FALSE
, L
"%s", Buf
);
255 // open CurrentVersion key
256 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
257 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
260 &hKey
) != ERROR_SUCCESS
)
262 wprintf(L
"Error! RegOpenKeyEx failed.\n");
267 RegGetSZ(hKey
, NULL
, L
"ProductName", Buf
, BUFFER_SIZE
);
268 PrintRow(IDS_OS_NAME
, FALSE
, L
"%s", Buf
);
271 ZeroMemory(&VersionInfo
, sizeof(VersionInfo
));
272 VersionInfo
.dwOSVersionInfoSize
= sizeof(VersionInfo
);
273 GetVersionExW(&VersionInfo
);
275 if (!LoadStringW(GetModuleHandle(NULL
), IDS_BUILD
, Tmp
, BUFFER_SIZE
))
277 PrintRow(IDS_OS_VERSION
,
279 L
"%lu.%lu.%lu %s %s %lu",
280 VersionInfo
.dwMajorVersion
,
281 VersionInfo
.dwMinorVersion
,
282 VersionInfo
.dwBuildNumber
,
283 VersionInfo
.szCSDVersion
,
285 VersionInfo
.dwBuildNumber
);
287 //getting OS Manufacturer
289 //getting OS Configuration
291 //getting OS Build Type
292 RegGetSZ(hKey
, NULL
, L
"CurrentType", Buf
, BUFFER_SIZE
);
293 PrintRow(IDS_OS_BUILD_TYPE
, FALSE
, L
"%s", Buf
);
295 //getting Registered Owner
296 RegGetSZ(hKey
, NULL
, L
"RegisteredOwner", Buf
, BUFFER_SIZE
);
297 PrintRow(IDS_REG_OWNER
, FALSE
, L
"%s", Buf
);
299 //getting Registered Organization
300 RegGetSZ(hKey
, NULL
, L
"RegisteredOrganization", Buf
, BUFFER_SIZE
);
301 PrintRow(IDS_REG_ORG
, FALSE
, L
"%s", Buf
);
304 RegGetSZ(hKey
, NULL
, L
"ProductId", Buf
, BUFFER_SIZE
);
305 PrintRow(IDS_PRODUCT_ID
, FALSE
, L
"%s", Buf
);
307 //getting Install Date
308 RegGetDWORD(hKey
, NULL
, L
"InstallDate", &dwTimestamp
);
309 FormatDateTime((time_t)dwTimestamp
, Buf
);
310 PrintRow(IDS_INST_DATE
, FALSE
, L
"%s", Buf
);
312 // close Current Version key now
315 //getting System Up Time
316 cSeconds
= GetTickCount() / 1000;
317 if (!LoadStringW(GetModuleHandle(NULL
), IDS_UP_TIME_FORMAT
, Tmp
, BUFFER_SIZE
))
319 swprintf(Buf
, Tmp
, cSeconds
/ (60*60*24), (cSeconds
/ (60*60)) % 24, (cSeconds
/ 60) % 60, cSeconds
% 60);
320 PrintRow(IDS_UP_TIME
, FALSE
, L
"%s", Buf
);
322 //getting System Manufacturer; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Manufacturer for Win >= 6.0
323 swprintf(Tmp
, L
"%s\\oeminfo.ini", szSystemDir
);
324 GetPrivateProfileStringW(L
"General",
326 L
"To Be Filled By O.E.M.",
328 sizeof(Buf
)/sizeof(Buf
[0]),
330 PrintRow(IDS_SYS_MANUFACTURER
, FALSE
, L
"%s", Buf
);
332 //getting System Model; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Model for Win >= 6.0
333 GetPrivateProfileStringW(L
"General",
335 L
"To Be Filled By O.E.M.",
337 sizeof(Buf
)/sizeof(Buf
[0]),
339 PrintRow(IDS_SYS_MODEL
, FALSE
, L
"%s", Buf
);
341 //getting System type
342 switch (SysInfo
.wProcessorArchitecture
)
344 case PROCESSOR_ARCHITECTURE_INTEL
:
345 lpcszSysType
= L
"X86-based PC";
347 case PROCESSOR_ARCHITECTURE_IA64
:
348 lpcszSysType
= L
"IA64-based PC";
350 case PROCESSOR_ARCHITECTURE_AMD64
:
351 lpcszSysType
= L
"AMD64-based PC";
354 lpcszSysType
= L
"Unknown";
357 PrintRow(IDS_SYS_TYPE
, FALSE
, L
"%s", lpcszSysType
);
359 //getting Processor(s)
360 if (!LoadStringW(GetModuleHandle(NULL
), IDS_PROCESSORS_FORMAT
, Tmp
, BUFFER_SIZE
))
362 swprintf(Buf
, Tmp
, (unsigned)SysInfo
.dwNumberOfProcessors
);
363 PrintRow(IDS_PROCESSORS
, FALSE
, L
"%s", Buf
);
364 for(i
= 0; i
< (unsigned int)SysInfo
.dwNumberOfProcessors
; i
++)
366 swprintf(Tmp
, L
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%u", i
);
367 j
= swprintf(Buf
, L
"[%02u]: ", i
+ 1);
369 j
+= RegGetSZ(HKEY_LOCAL_MACHINE
, Tmp
, L
"Identifier", Buf
+ j
, BUFFER_SIZE
- j
);
370 if(j
+ 1 < BUFFER_SIZE
)
372 RegGetSZ(HKEY_LOCAL_MACHINE
, Tmp
, L
"VendorIdentifier", Buf
+ j
, BUFFER_SIZE
- j
);
374 PrintRow(0, FALSE
, L
"%s", Buf
);
377 //getting BIOS Version
378 RegGetSZ(HKEY_LOCAL_MACHINE
,
379 L
"HARDWARE\\DESCRIPTION\\System",
380 L
"SystemBiosVersion",
383 PrintRow(IDS_BIOS_VERSION
, FALSE
, L
"%s", Buf
);
386 RegGetSZ(HKEY_LOCAL_MACHINE
,
387 L
"HARDWARE\\DESCRIPTION\\System",
391 PrintRow(IDS_BIOS_DATE
, FALSE
, L
"%s", Buf
);
393 //getting ReactOS Directory
394 if (!GetWindowsDirectoryW(Buf
, BUFFER_SIZE
))
395 wprintf(L
"Error! GetWindowsDirectory failed.");
397 PrintRow(IDS_ROS_DIR
, FALSE
, L
"%s", Buf
);
399 //getting System Directory
400 PrintRow(IDS_SYS_DIR
, 0, L
"%s", szSystemDir
);
402 //getting Boot Device
403 RegGetSZ(HKEY_LOCAL_MACHINE
,
408 PrintRow(IDS_BOOT_DEV
, FALSE
, L
"%s", Buf
);
410 //getting System Locale
411 if (GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT
, LOCALE_ILANGUAGE
, Tmp
, BUFFER_SIZE
))
412 if (RegGetSZ(HKEY_CLASSES_ROOT
,
413 L
"MIME\\Database\\Rfc1766",
418 /* get rid of @filename,resource */
419 lpBuffer
= wcschr(Buf
, L
';');
421 SHLoadIndirectString(lpBuffer
+1, lpBuffer
+1, BUFFER_SIZE
- (lpBuffer
-Buf
) - 1, NULL
);
423 PrintRow(IDS_SYS_LOCALE
, FALSE
, L
"%s", Buf
);
426 //getting Input Locale
427 if (RegGetSZ(HKEY_CURRENT_USER
,
428 L
"Keyboard Layout\\Preload",
431 BUFFER_SIZE
) && wcslen(Tmp
) > 4)
432 if (RegGetSZ(HKEY_CLASSES_ROOT
,
433 L
"MIME\\Database\\Rfc1766",
438 /* get rid of @filename,resource */
439 lpBuffer
= wcschr(Buf
, L
';');
441 SHLoadIndirectString(lpBuffer
+1, lpBuffer
+1, BUFFER_SIZE
- (lpBuffer
-Buf
) - 1, NULL
);
443 PrintRow(IDS_INPUT_LOCALE
, FALSE
, L
"%s", Buf
);
447 GetTimeZoneInformation(&TimeZoneInfo
);
449 /* Open Time Zones key */
450 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
451 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
453 KEY_ENUMERATE_SUB_KEYS
|KEY_READ
,
454 &hKey
) == ERROR_SUCCESS
)
458 /* Find current timezone */
459 dwCharCount
= BUFFER_SIZE
;
460 for(i
= 0; RegEnumKeyExW(hKey
, i
, Tmp
, &dwCharCount
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
; ++i
, dwCharCount
= 255)
462 RegGetSZ(hKey
, Tmp
, L
"Std", Buf
, BUFFER_SIZE
);
464 if (!wcscmp(Buf
, TimeZoneInfo
.StandardName
))
466 RegGetSZ(hKey
, Tmp
, L
"Display", Buf
, BUFFER_SIZE
);
468 PrintRow(IDS_TIME_ZONE
, FALSE
, L
"%s", Buf
);
476 //getting Total Physical Memory
477 GlobalMemoryStatus(&MemoryStatus
);
478 FormatBytes(Buf
, MemoryStatus
.dwTotalPhys
);
479 PrintRow(IDS_TOTAL_PHYS_MEM
, FALSE
, L
"%s", Buf
);
481 //getting Available Physical Memory
482 FormatBytes(Buf
, MemoryStatus
.dwAvailPhys
);
483 PrintRow(IDS_AVAIL_PHISICAL_MEM
, FALSE
, L
"%s", Buf
);
485 //getting Virtual Memory: Max Size
486 FormatBytes(Buf
, MemoryStatus
.dwTotalVirtual
);
487 PrintRow(IDS_VIRT_MEM_MAX
, FALSE
, L
"%s", Buf
);
489 //getting Virtual Memory: Available
490 FormatBytes(Buf
, MemoryStatus
.dwAvailVirtual
);
491 PrintRow(IDS_VIRT_MEM_AVAIL
, FALSE
, L
"%s", Buf
);
493 //getting Virtual Memory: In Use
494 FormatBytes(Buf
, MemoryStatus
.dwTotalVirtual
-MemoryStatus
.dwAvailVirtual
);
495 PrintRow(IDS_VIRT_MEM_INUSE
, FALSE
, L
"%s", Buf
);
497 //getting Page File Location(s)
498 if (RegGetSZ(HKEY_LOCAL_MACHINE
,
499 L
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management",
506 for(i
= 0; Buf
[i
]; i
++)
515 PrintRow(IDS_PAGEFILE_LOC
, FALSE
, L
"%s", Buf
);
519 if (NetGetJoinInformation (NULL
, &lpBuffer
, &NetJoinStatus
) == NERR_Success
)
521 if (NetJoinStatus
== NetSetupWorkgroupName
|| NetJoinStatus
== NetSetupDomainName
)
522 PrintRow(IDS_DOMAIN
, FALSE
, L
"%s", lpBuffer
);
524 NetApiBufferFree(lpBuffer
);
527 //getting Logon Server
529 //getting NetWork Card(s)
531 pAdapters
= malloc(cbAdapters
);
532 while((dwResult
= GetAdaptersAddresses(AF_UNSPEC
, 0x0002, NULL
, pAdapters
, &cbAdapters
)) == ERROR_BUFFER_OVERFLOW
)
535 pAdapters
= (PIP_ADAPTER_ADDRESSES
)realloc(pAdapters
, cbAdapters
);
538 if (dwResult
== ERROR_SUCCESS
)
540 PIP_ADAPTER_ADDRESSES pCurrentAdapter
= pAdapters
;
541 unsigned cAdapters
= 0;
544 for(i
= 0; pCurrentAdapter
; ++i
)
546 if (pCurrentAdapter
->IfType
!= 24 && pCurrentAdapter
->IfType
!= 131)
548 pCurrentAdapter
= pCurrentAdapter
->Next
;
552 /* Print adapters count */
553 if (!LoadStringW(GetModuleHandle(NULL
), IDS_NETWORK_CARDS_FORMAT
, Tmp
, BUFFER_SIZE
))
555 swprintf(Buf
, Tmp
, cAdapters
);
556 PrintRow(IDS_NETWORK_CARDS
, FALSE
, L
"%s", Buf
);
558 /* Show information about each adapter */
559 pCurrentAdapter
= pAdapters
;
560 for(i
= 0; pCurrentAdapter
; ++i
)
562 if (pCurrentAdapter
->IfType
!= 24 && pCurrentAdapter
->IfType
!= 131)//IF_TYPE_SOFTWARE_LOOPBACK)
564 PIP_ADAPTER_UNICAST_ADDRESS pAddress
;
566 PrintRow(0, FALSE
, L
"[%02u]: %s", i
+ 1, pCurrentAdapter
->Description
);
567 PrintRow(IDS_CONNECTION_NAME
, TRUE
, L
"%s", pCurrentAdapter
->FriendlyName
);
568 if (!(pCurrentAdapter
->Flags
& 0x0004))
570 if (!LoadStringW(GetModuleHandle(NULL
), IDS_NO
, Buf
, BUFFER_SIZE
))
572 PrintRow(IDS_DHCP_ENABLED
, TRUE
, Buf
);
574 if (pCurrentAdapter
->OperStatus
== IfOperStatusDown
)
576 if (!LoadStringW(GetModuleHandle(NULL
), IDS_MEDIA_DISCONNECTED
, Buf
, BUFFER_SIZE
))
578 PrintRow(IDS_STATUS
, TRUE
, Buf
);
582 if (!LoadStringW(GetModuleHandle(NULL
), IDS_IP_ADDRESSES
, Buf
, BUFFER_SIZE
))
584 PrintRow(0, TRUE
, Buf
);
585 pAddress
= pCurrentAdapter
->FirstUnicastAddress
;
586 for (j
= 0; pAddress
; ++j
)
588 dwCharCount
= BUFFER_SIZE
;
589 WSAAddressToStringW(pAddress
->Address
.lpSockaddr
, pAddress
->Address
.iSockaddrLength
, NULL
, Buf
, &dwCharCount
);
590 PrintRow(0, TRUE
, L
"[%02u]: %s", j
+ 1, Buf
);
591 pAddress
= pAddress
->Next
;
595 pCurrentAdapter
= pCurrentAdapter
->Next
;
603 main(int argc
, char *argv
[])
608 setlocale(LC_ALL
, "");
610 WSAStartup(MAKEWORD(2, 2), &WsaData
);
612 for (i
= 1; i
< argc
; ++i
)
614 if (!strcmp(argv
[i
], "/?") || !strcmp(argv
[i
], "-?"))
621 printf("Unsupported argument: %s\n", argv
[i
]);