Files
reactos/modules/rosapps/applications/sysutils/systeminfo/systeminfo.c
Timo Kreuzer 1cf31524d5 [REACTOS] Stop using non-conforming swprintf / vswprintf
Use the underscored versions instead.
2026-05-07 06:27:58 +00:00

704 lines
20 KiB
C

/*
* PROJECT: ReactOS SystemInfo Command
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Displays system information.
* COPYRIGHT: Copyright 2007 Dmitry Chapyshev <lentind@yandex.ru>
* Copyright 2011 Rafal Harabien <rafalh1992@o2.pl>
* Copyright 2018 Stanislav Motylkov <x86corez@gmail.com>
*/
#include <wchar.h>
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <wincon.h>
#include <shlwapi.h>
#include <lm.h>
#include <iphlpapi.h>
#include <winsock2.h>
#include <udmihelp.h>
#include <conutils.h>
#include "resource.h"
#define BUFFER_SIZE 1024
/* Load string from registry */
static
UINT
RegGetSZ(HKEY hKey, PCWSTR pSubKey, PCWSTR pValueName, PWSTR pBuf, DWORD cchBuf)
{
DWORD dwBytes = cchBuf * sizeof(WCHAR), dwType = 0;
UINT cChars;
/* If SubKey is specified open it */
if (pSubKey && RegOpenKeyExW(hKey,
pSubKey,
0,
KEY_QUERY_VALUE,
&hKey) != ERROR_SUCCESS)
{
ConPrintf(StdErr, L"Warning! Cannot open %s. Last error: %lu.\n",
pSubKey, GetLastError());
return 0;
}
/* Query registry value and check its type */
if (RegQueryValueExW(hKey,
pValueName,
NULL,
&dwType,
(PBYTE)pBuf,
&dwBytes) != ERROR_SUCCESS ||
(dwType != REG_SZ && dwType != REG_MULTI_SZ))
{
ConPrintf(StdErr, L"Warning! Cannot query %s. Last error: %lu, type: %lu.\n",
pValueName, GetLastError(), dwType);
dwBytes = 0;
}
else if (dwBytes == 0)
{
wcscpy(pBuf, L"N/A");
dwBytes = sizeof(L"N/A")-sizeof(WCHAR);
}
/* Close key if we opened it */
if (pSubKey)
RegCloseKey(hKey);
cChars = dwBytes/sizeof(WCHAR);
/* NULL-terminate string */
pBuf[min(cchBuf-1, cChars)] = L'\0';
/* Don't count NULL characters */
while (cChars && !pBuf[cChars-1])
--cChars;
return cChars;
}
/* Load DWORD from registry */
static
BOOL
RegGetDWORD(HKEY hKey, PCWSTR pSubKey, PCWSTR pValueName, PDWORD pData)
{
DWORD dwBytes = sizeof(*pData), dwType;
BOOL bRet = TRUE;
/* If SubKey is specified open it */
if (pSubKey && RegOpenKeyExW(hKey,
pSubKey,
0,
KEY_QUERY_VALUE,
&hKey) != ERROR_SUCCESS)
{
ConPrintf(StdErr, L"Warning! Cannot open %s. Last error: %lu.\n",
pSubKey, GetLastError());
return FALSE;
}
/* Query registry value and check its type */
if (RegQueryValueExW(hKey,
pValueName,
NULL,
&dwType,
(PBYTE)pData,
&dwBytes) != ERROR_SUCCESS || dwType != REG_DWORD)
{
ConPrintf(StdErr, L"Warning! Cannot query %s. Last err: %lu, type: %lu\n",
pValueName, GetLastError(), dwType);
*pData = 0;
bRet = FALSE;
}
/* Close key if we opened it */
if (pSubKey)
RegCloseKey(hKey);
return bRet;
}
/* Format bytes */
static
VOID
FormatBytes(PWSTR pBuf, UINT cBytes)
{
WCHAR szMB[32];
NUMBERFMTW fmt;
UINT i;
_itow(cBytes / (1024*1024), szMB, 10);
fmt.NumDigits = 0;
fmt.LeadingZero = 0;
fmt.Grouping = 3;
fmt.lpDecimalSep = L"";
fmt.lpThousandSep = L" ";
fmt.NegativeOrder = 0;
i = GetNumberFormatW(LOCALE_SYSTEM_DEFAULT, 0, szMB, &fmt, pBuf, BUFFER_SIZE - 3);
if (i)
--i; /* don't count NULL character */
wcscpy(pBuf + i, L" MB");
}
/* Format date and time */
static
VOID
FormatDateTime(time_t Time, PWSTR pBuf)
{
UINT i;
SYSTEMTIME SysTime;
const struct tm *pTm;
pTm = localtime(&Time);
SysTime.wYear = (WORD)(1900 + pTm->tm_year);
SysTime.wMonth = (WORD)(1 + pTm->tm_mon);
SysTime.wDayOfWeek = (WORD)pTm->tm_wday;
SysTime.wDay = (WORD)pTm->tm_mday;
SysTime.wHour = (WORD)pTm->tm_hour;
SysTime.wMinute = (WORD)pTm->tm_min;
SysTime.wSecond = (WORD)pTm->tm_sec;
SysTime.wMilliseconds = 0;
/* Copy date first */
i = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &SysTime, NULL, pBuf, BUFFER_SIZE - 2);
if (i)
--i; /* don't count NULL character */
/* Copy time now */
i += _swprintf(pBuf + i, L", ");
GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, 0, &SysTime, NULL, pBuf + i, BUFFER_SIZE - i);
}
ULONGLONG GetSecondsQPC(VOID)
{
LARGE_INTEGER Counter, Frequency;
QueryPerformanceCounter(&Counter);
QueryPerformanceFrequency(&Frequency);
return Counter.QuadPart / Frequency.QuadPart;
}
ULONGLONG GetSeconds(VOID)
{
ULONGLONG (WINAPI *pGetTickCount64)(VOID);
ULONGLONG Ticks64;
HMODULE hModule = GetModuleHandleW(L"kernel32.dll");
pGetTickCount64 = (PVOID)GetProcAddress(hModule, "GetTickCount64");
if (pGetTickCount64)
return pGetTickCount64() / 1000;
hModule = LoadLibraryW(L"kernel32_vista.dll");
if (!hModule)
return GetSecondsQPC();
pGetTickCount64 = (PVOID)GetProcAddress(hModule, "GetTickCount64");
if (pGetTickCount64)
Ticks64 = pGetTickCount64() / 1000;
else
Ticks64 = GetSecondsQPC();
FreeLibrary(hModule);
return Ticks64;
}
/* Show usage */
static
VOID
Usage(VOID)
{
ConResPrintf(StdOut, IDS_USAGE);
}
static
VOID
PrintRow(UINT nTitleID, BOOL bIndent, PCWSTR pFormat, ...)
{
va_list Args;
UINT c;
WCHAR Buf[BUFFER_SIZE];
if (nTitleID)
{
c = LoadStringW(NULL, nTitleID, Buf, _countof(Buf) - 2);
if (!c)
return;
wcscpy(Buf + c, L": ");
}
else
{
Buf[0] = L'\0';
}
if (!bIndent)
ConPrintf(StdOut, L"%-32s", Buf);
else if (Buf[0])
ConPrintf(StdOut, L"%38s%-16s", L"", Buf);
else
ConPrintf(StdOut, L"%38s", L"");
va_start(Args, pFormat);
ConPrintfV(StdOut, pFormat, Args);
va_end(Args);
ConPuts(StdOut, L"\n");
}
/* Print all system information */
VOID
AllSysInfo(VOID)
{
DWORD dwCharCount, dwTimestamp, dwResult;
OSVERSIONINFOW VersionInfo;
SYSTEM_INFO SysInfo;
WCHAR Buf[BUFFER_SIZE], Tmp[BUFFER_SIZE], szSystemDir[MAX_PATH];
PCWSTR SysType;
PWSTR pBuffer;
NETSETUP_JOIN_STATUS NetJoinStatus;
MEMORYSTATUS MemoryStatus;
UINT cSeconds, i, j;
TIME_ZONE_INFORMATION TimeZoneInfo;
HKEY hKey;
PIP_ADAPTER_ADDRESSES pAdapters;
ULONG cbAdapters;
PVOID SMBiosBuf;
PCHAR DmiStrings[ID_STRINGS_MAX] = { 0 };
if (!GetSystemDirectoryW(szSystemDir, _countof(szSystemDir)))
{
ConPrintf(StdErr, L"Error! GetSystemDirectory failed.\n");
return;
}
GetSystemInfo(&SysInfo);
/* Getting computer name */
dwCharCount = _countof(Buf);
if (!GetComputerNameW(Buf, &dwCharCount))
ConPrintf(StdErr, L"Error! GetComputerName failed.\n");
else
PrintRow(IDS_HOST_NAME, FALSE, L"%s", Buf);
/* Open CurrentVersion key */
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
0,
KEY_QUERY_VALUE,
&hKey) != ERROR_SUCCESS)
{
ConPrintf(StdErr, L"Error! RegOpenKeyEx failed.\n");
return;
}
/* Getting OS Name */
RegGetSZ(hKey, NULL, L"ProductName", Buf, _countof(Buf));
PrintRow(IDS_OS_NAME, FALSE, L"%s", Buf);
/* Getting OS Version */
ZeroMemory(&VersionInfo, sizeof(VersionInfo));
VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
GetVersionExW(&VersionInfo);
if (!LoadStringW(NULL, IDS_BUILD, Tmp, _countof(Tmp)))
Tmp[0] = L'\0';
PrintRow(IDS_OS_VERSION,
FALSE,
L"%lu.%lu.%lu %s %s %lu",
VersionInfo.dwMajorVersion,
VersionInfo.dwMinorVersion,
VersionInfo.dwBuildNumber,
VersionInfo.szCSDVersion,
Tmp,
VersionInfo.dwBuildNumber);
/* Getting OS Manufacturer */
/* Getting OS Configuration */
/* Getting OS Build Type */
RegGetSZ(hKey, NULL, L"CurrentType", Buf, _countof(Buf));
PrintRow(IDS_OS_BUILD_TYPE, FALSE, L"%s", Buf);
/* Getting Registered Owner */
RegGetSZ(hKey, NULL, L"RegisteredOwner", Buf, _countof(Buf));
PrintRow(IDS_REG_OWNER, FALSE, L"%s", Buf);
/* Getting Registered Organization */
RegGetSZ(hKey, NULL, L"RegisteredOrganization", Buf, _countof(Buf));
PrintRow(IDS_REG_ORG, FALSE, L"%s", Buf);
/* Getting Product ID */
RegGetSZ(hKey, NULL, L"ProductId", Buf, _countof(Buf));
PrintRow(IDS_PRODUCT_ID, FALSE, L"%s", Buf);
/* Getting Install Date */
RegGetDWORD(hKey, NULL, L"InstallDate", &dwTimestamp);
FormatDateTime((time_t)dwTimestamp, Buf);
PrintRow(IDS_INST_DATE, FALSE, L"%s", Buf);
/* Close Current Version key now */
RegCloseKey(hKey);
/* Getting System Up Time */
cSeconds = GetSeconds();
if (!LoadStringW(NULL, IDS_UP_TIME_FORMAT, Tmp, _countof(Tmp)))
Tmp[0] = L'\0';
_swprintf(Buf, Tmp, cSeconds / (60*60*24), (cSeconds / (60*60)) % 24, (cSeconds / 60) % 60, cSeconds % 60);
PrintRow(IDS_UP_TIME, FALSE, L"%s", Buf);
/* Prepare SMBIOS data */
SMBiosBuf = LoadSMBiosData(DmiStrings);
/* Getting System Manufacturer;
* HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Manufacturer
* for Win >= 6.0 */
_swprintf(Tmp, L"%s\\oeminfo.ini", szSystemDir);
GetPrivateProfileStringW(L"General",
L"Manufacturer",
L"",
Buf,
_countof(Buf),
Tmp);
if (wcslen(Buf) == 0 && SMBiosBuf)
{
GetSMBiosStringW(DmiStrings[SYS_VENDOR], Buf, _countof(Buf), FALSE);
}
PrintRow(IDS_SYS_MANUFACTURER, FALSE, L"%s", Buf);
/* Getting System Model;
* HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Model
* for Win >= 6.0 */
GetPrivateProfileStringW(L"General",
L"Model",
L"",
Buf,
_countof(Buf),
Tmp);
if (wcslen(Buf) == 0 && SMBiosBuf)
{
GetSMBiosStringW(DmiStrings[SYS_PRODUCT], Buf, _countof(Buf), FALSE);
}
PrintRow(IDS_SYS_MODEL, FALSE, L"%s", Buf);
/* Getting System type */
switch (SysInfo.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_INTEL:
SysType = L"X86-based PC";
break;
case PROCESSOR_ARCHITECTURE_IA64:
SysType = L"IA64-based PC";
break;
case PROCESSOR_ARCHITECTURE_AMD64:
SysType = L"AMD64-based PC";
break;
default:
SysType = L"Unknown";
break;
}
PrintRow(IDS_SYS_TYPE, FALSE, L"%s", SysType);
/* Getting Processor(s) */
if (!LoadStringW(NULL, IDS_PROCESSORS_FORMAT, Tmp, _countof(Tmp)))
Tmp[0] = L'\0';
_swprintf(Buf, Tmp, (UINT)SysInfo.dwNumberOfProcessors);
PrintRow(IDS_PROCESSORS, FALSE, L"%s", Buf);
for (i = 0; i < (UINT)SysInfo.dwNumberOfProcessors; i++)
{
_swprintf(Tmp, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%u", i);
j = _swprintf(Buf, L"[%02u]: ", i + 1);
j += RegGetSZ(HKEY_LOCAL_MACHINE, Tmp, L"Identifier", Buf + j, _countof(Buf) - j);
if (j + 1 < _countof(Buf))
Buf[j++] = L' ';
RegGetSZ(HKEY_LOCAL_MACHINE, Tmp, L"VendorIdentifier", Buf + j, _countof(Buf) - j);
PrintRow(0, FALSE, L"%s", Buf);
}
/* Getting BIOS Version */
if (SMBiosBuf)
{
j = GetSMBiosStringW(DmiStrings[BIOS_VENDOR], Buf, _countof(Buf), TRUE);
if (j + 1 < _countof(Buf))
{
Buf[j++] = L' ';
Buf[j] = L'\0';
}
GetSMBiosStringW(DmiStrings[BIOS_VERSION], Buf + j, _countof(Buf) - j, TRUE);
}
else
{
RegGetSZ(HKEY_LOCAL_MACHINE,
L"HARDWARE\\DESCRIPTION\\System",
L"SystemBiosVersion",
Buf,
_countof(Buf));
}
PrintRow(IDS_BIOS_VERSION, FALSE, L"%s", Buf);
/* Getting BIOS date */
if (SMBiosBuf)
{
GetSMBiosStringW(DmiStrings[BIOS_DATE], Buf, _countof(Buf), TRUE);
}
else
{
RegGetSZ(HKEY_LOCAL_MACHINE,
L"HARDWARE\\DESCRIPTION\\System",
L"SystemBiosDate",
Buf,
_countof(Buf));
}
PrintRow(IDS_BIOS_DATE, FALSE, L"%s", Buf);
/* Clean SMBIOS data */
FreeSMBiosData(SMBiosBuf);
/* Getting ReactOS Directory */
if (!GetWindowsDirectoryW(Buf, _countof(Buf)))
ConPrintf(StdErr, L"Error! GetWindowsDirectory failed.");
else
PrintRow(IDS_ROS_DIR, FALSE, L"%s", Buf);
/* Getting System Directory */
PrintRow(IDS_SYS_DIR, 0, L"%s", szSystemDir);
/* Getting Boot Device */
RegGetSZ(HKEY_LOCAL_MACHINE,
L"SYSTEM\\Setup",
L"SystemPartition",
Buf,
_countof(Buf));
PrintRow(IDS_BOOT_DEV, FALSE, L"%s", Buf);
/* Getting System Locale */
if (GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, Tmp, _countof(Tmp)))
{
if (RegGetSZ(HKEY_CLASSES_ROOT,
L"MIME\\Database\\Rfc1766",
Tmp,
Buf,
_countof(Buf)))
{
/* Get rid of @filename,resource */
pBuffer = wcschr(Buf, L';');
if (pBuffer)
SHLoadIndirectString(pBuffer+1, pBuffer+1, _countof(Buf) - (pBuffer-Buf) - 1, NULL);
PrintRow(IDS_SYS_LOCALE, FALSE, L"%s", Buf);
}
}
/* Getting Input Locale */
if (RegGetSZ(HKEY_CURRENT_USER,
L"Keyboard Layout\\Preload",
L"1",
Tmp,
_countof(Tmp)) && wcslen(Tmp) > 4)
{
if (RegGetSZ(HKEY_CLASSES_ROOT,
L"MIME\\Database\\Rfc1766",
Tmp + 4,
Buf,
_countof(Buf)))
{
/* Get rid of @filename,resource */
pBuffer = wcschr(Buf, L';');
if (pBuffer)
SHLoadIndirectString(pBuffer+1, pBuffer+1, _countof(Buf) - (pBuffer-Buf) - 1, NULL);
PrintRow(IDS_INPUT_LOCALE, FALSE, L"%s", Buf);
}
}
/* Getting Time Zone */
GetTimeZoneInformation(&TimeZoneInfo);
/* Open Time Zones key */
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
0,
KEY_ENUMERATE_SUB_KEYS|KEY_READ,
&hKey) == ERROR_SUCCESS)
{
/* Find current timezone */
UINT i;
dwCharCount = _countof(Tmp);
for (i = 0; RegEnumKeyExW(hKey, i, Tmp, &dwCharCount, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++i, dwCharCount = 255)
{
RegGetSZ(hKey, Tmp, L"Std", Buf, _countof(Buf));
if (!wcscmp(Buf, TimeZoneInfo.StandardName))
{
RegGetSZ(hKey, Tmp, L"Display", Buf, _countof(Buf));
PrintRow(IDS_TIME_ZONE, FALSE, L"%s", Buf);
break;
}
}
RegCloseKey(hKey);
}
/* Getting Total Physical Memory */
GlobalMemoryStatus(&MemoryStatus);
FormatBytes(Buf, MemoryStatus.dwTotalPhys);
PrintRow(IDS_TOTAL_PHYS_MEM, FALSE, L"%s", Buf);
/* Getting Available Physical Memory */
FormatBytes(Buf, MemoryStatus.dwAvailPhys);
PrintRow(IDS_AVAIL_PHISICAL_MEM, FALSE, L"%s", Buf);
/* Getting Virtual Memory: Max Size */
FormatBytes(Buf, MemoryStatus.dwTotalVirtual);
PrintRow(IDS_VIRT_MEM_MAX, FALSE, L"%s", Buf);
/* Getting Virtual Memory: Available */
FormatBytes(Buf, MemoryStatus.dwAvailVirtual);
PrintRow(IDS_VIRT_MEM_AVAIL, FALSE, L"%s", Buf);
/* Getting Virtual Memory: In Use */
FormatBytes(Buf, MemoryStatus.dwTotalVirtual-MemoryStatus.dwAvailVirtual);
PrintRow(IDS_VIRT_MEM_INUSE, FALSE, L"%s", Buf);
/* Getting Page File Location(s) */
if (RegGetSZ(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management",
L"PagingFiles",
Buf,
_countof(Buf)))
{
UINT i;
for (i = 0; Buf[i]; i++)
{
if (Buf[i] == L' ')
{
Buf[i] = L'\0';
break;
}
}
PrintRow(IDS_PAGEFILE_LOC, FALSE, L"%s", Buf);
}
/* Getting Domain */
if (NetGetJoinInformation(NULL, &pBuffer, &NetJoinStatus) == NERR_Success)
{
if (NetJoinStatus == NetSetupWorkgroupName || NetJoinStatus == NetSetupDomainName)
PrintRow(IDS_DOMAIN, FALSE, L"%s", pBuffer);
NetApiBufferFree(pBuffer);
}
/* Getting Logon Server */
/* Getting NetWork Card(s) */
cbAdapters = 4096;
pAdapters = malloc(cbAdapters);
while ((dwResult = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST, NULL, pAdapters, &cbAdapters)) == ERROR_BUFFER_OVERFLOW)
{
cbAdapters += 4096;
pAdapters = (PIP_ADAPTER_ADDRESSES)realloc(pAdapters, cbAdapters);
}
if (dwResult == ERROR_SUCCESS)
{
PIP_ADAPTER_ADDRESSES pCurrentAdapter = pAdapters;
UINT cAdapters = 0;
/* Count adapters */
for (i = 0; pCurrentAdapter; ++i)
{
if (pCurrentAdapter->IfType != IF_TYPE_SOFTWARE_LOOPBACK && pCurrentAdapter->IfType != IF_TYPE_TUNNEL)
++cAdapters;
pCurrentAdapter = pCurrentAdapter->Next;
}
/* Print adapters count */
if (!LoadStringW(NULL, IDS_NETWORK_CARDS_FORMAT, Tmp, _countof(Tmp)))
Tmp[0] = L'\0';
_swprintf(Buf, Tmp, cAdapters);
PrintRow(IDS_NETWORK_CARDS, FALSE, L"%s", Buf);
/* Show information about each adapter */
pCurrentAdapter = pAdapters;
for (i = 0; pCurrentAdapter; ++i)
{
if (pCurrentAdapter->IfType != IF_TYPE_SOFTWARE_LOOPBACK && pCurrentAdapter->IfType != IF_TYPE_TUNNEL)
{
PIP_ADAPTER_UNICAST_ADDRESS pAddress;
PrintRow(0, FALSE, L"[%02u]: %s", i + 1, pCurrentAdapter->Description);
PrintRow(IDS_CONNECTION_NAME, TRUE, L"%s", pCurrentAdapter->FriendlyName);
if (!(pCurrentAdapter->Flags & IP_ADAPTER_DHCP_ENABLED))
{
if (!LoadStringW(NULL, IDS_NO, Buf, _countof(Buf)))
Buf[0] = L'\0';
PrintRow(IDS_DHCP_ENABLED, TRUE, Buf);
}
if (pCurrentAdapter->OperStatus == IfOperStatusDown)
{
if (!LoadStringW(NULL, IDS_MEDIA_DISCONNECTED, Buf, _countof(Buf)))
Buf[0] = L'\0';
PrintRow(IDS_STATUS, TRUE, Buf);
}
else
{
if (!LoadStringW(NULL, IDS_IP_ADDRESSES, Buf, _countof(Buf)))
Buf[0] = L'\0';
PrintRow(0, TRUE, Buf);
pAddress = pCurrentAdapter->FirstUnicastAddress;
for (j = 0; pAddress; ++j)
{
dwCharCount = _countof(Buf);
WSAAddressToStringW(pAddress->Address.lpSockaddr, pAddress->Address.iSockaddrLength, NULL, Buf, &dwCharCount);
PrintRow(0, TRUE, L"[%02u]: %s", j + 1, Buf);
pAddress = pAddress->Next;
}
}
}
pCurrentAdapter = pCurrentAdapter->Next;
}
}
free(pAdapters);
}
/* Main program */
int wmain(int argc, wchar_t *argv[])
{
WSADATA WsaData;
int i;
/* Initialize the Console Standard Streams */
ConInitStdStreams();
WSAStartup(MAKEWORD(2, 2), &WsaData);
for (i = 1; i < argc; ++i)
{
if (!wcscmp(argv[i], L"/?") || !wcscmp(argv[i], L"-?"))
{
Usage();
return 0;
}
else
{
ConPrintf(StdErr, L"Unsupported argument: %s\n", argv[i]);
return -1;
}
}
AllSysInfo();
return 0;
}