[FORMATTING] Remove trailing whitespace. Addendum to 34593d93.
[reactos.git] / modules / 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 <wchar.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <windows.h>
24 #include <time.h>
25 #include <locale.h>
26 #include <lm.h>
27 #include <shlwapi.h>
28 #include <iphlpapi.h>
29 #include <winsock2.h>
30 #include <udmihelp.h>
31
32 #include "resource.h"
33
34 #define BUFFER_SIZE 1024
35
36 /* Load string from registry */
37 static
38 unsigned
39 RegGetSZ(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPWSTR lpBuf, DWORD cchBuf)
40 {
41 DWORD dwBytes = cchBuf*sizeof(WCHAR), dwType = 0;
42 unsigned cChars;
43
44 /* If SubKey is specified open it */
45 if (lpSubKey && RegOpenKeyExW(hKey,
46 lpSubKey,
47 0,
48 KEY_QUERY_VALUE,
49 &hKey) != ERROR_SUCCESS)
50 {
51 wprintf(L"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey, GetLastError());
52 return 0;
53 }
54
55 /* Query registry value and check its type */
56 if (RegQueryValueExW(hKey,
57 lpValueName,
58 NULL,
59 &dwType,
60 (LPBYTE)lpBuf,
61 &dwBytes) != ERROR_SUCCESS || (dwType != REG_SZ && dwType != REG_MULTI_SZ))
62 {
63 wprintf(L"Warning! Cannot query %s. Last error: %lu, type: %lu.\n", lpValueName, GetLastError(), dwType);
64 dwBytes = 0;
65 }
66 else if (dwBytes == 0)
67 {
68 wcscpy(lpBuf, L"N/A");
69 dwBytes = 6;
70 }
71
72 /* Close key if we opened it */
73 if (lpSubKey)
74 RegCloseKey(hKey);
75
76 cChars = dwBytes/sizeof(WCHAR);
77
78 /* NULL-terminate string */
79 lpBuf[min(cchBuf-1, cChars)] = L'\0';
80
81 /* Don't count NULL characters */
82 while(cChars && !lpBuf[cChars-1])
83 --cChars;
84
85 return cChars;
86 }
87
88 /* Load DWORD from registry */
89 static
90 BOOL
91 RegGetDWORD(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPDWORD lpData)
92 {
93 DWORD dwBytes = sizeof(*lpData), dwType;
94 BOOL bRet = TRUE;
95
96 /* If SubKey is specified open it */
97 if (lpSubKey && RegOpenKeyExW(hKey,
98 lpSubKey,
99 0,
100 KEY_QUERY_VALUE,
101 &hKey) != ERROR_SUCCESS)
102 {
103 wprintf(L"Warning! Cannot open %s. Last error: %lu.\n", lpSubKey, GetLastError());
104 return FALSE;
105 }
106
107 /* Query registry value and check its type */
108 if (RegQueryValueExW(hKey,
109 lpValueName,
110 NULL,
111 &dwType,
112 (LPBYTE)lpData,
113 &dwBytes) != ERROR_SUCCESS || dwType != REG_DWORD)
114 {
115 wprintf(L"Warning! Cannot query %s. Last err: %lu, type: %lu\n", lpValueName, GetLastError(), dwType);
116 *lpData = 0;
117 bRet = FALSE;
118 }
119
120 /* Close key if we opened it */
121 if (lpSubKey)
122 RegCloseKey(hKey);
123
124 return bRet;
125 }
126
127 /* Format bytes */
128 static
129 VOID
130 FormatBytes(LPWSTR lpBuf, unsigned cBytes)
131 {
132 WCHAR szMB[32];
133 NUMBERFMTW fmt;
134 unsigned i;
135
136 _itow(cBytes / (1024*1024), szMB, 10);
137
138 fmt.NumDigits = 0;
139 fmt.LeadingZero = 0;
140 fmt.Grouping = 3;
141 fmt.lpDecimalSep = L"";
142 fmt.lpThousandSep = L" ";
143 fmt.NegativeOrder = 0;
144
145 i = GetNumberFormatW(LOCALE_SYSTEM_DEFAULT, 0, szMB, &fmt, lpBuf, BUFFER_SIZE - 3);
146 if (i)
147 --i; /* don't count NULL character */
148 wcscpy(lpBuf + i, L" MB");
149 }
150
151 /* Format date and time */
152 static
153 VOID
154 FormatDateTime(time_t Time, LPWSTR lpBuf)
155 {
156 unsigned i;
157 SYSTEMTIME SysTime;
158 const struct tm *lpTm;
159
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;
169
170 /* Copy date first */
171 i = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &SysTime, NULL, lpBuf, BUFFER_SIZE - 2);
172 if (i)
173 --i; /* don't count NULL character */
174
175 /* Copy time now */
176 i += swprintf(lpBuf + i, L", ");
177
178 GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, 0, &SysTime, NULL, lpBuf + i, BUFFER_SIZE - i);
179 }
180
181 ULONGLONG GetSecondsQPC(VOID)
182 {
183 LARGE_INTEGER Counter, Frequency;
184
185 QueryPerformanceCounter(&Counter);
186 QueryPerformanceFrequency(&Frequency);
187
188 return Counter.QuadPart / Frequency.QuadPart;
189 }
190
191 ULONGLONG GetSeconds(VOID)
192 {
193 ULONGLONG (WINAPI * pGetTickCount64)(VOID);
194 ULONGLONG Ticks64;
195 HMODULE hModule = GetModuleHandleW(L"kernel32.dll");
196
197 pGetTickCount64 = (PVOID)GetProcAddress(hModule, "GetTickCount64");
198 if (pGetTickCount64)
199 {
200 return pGetTickCount64() / 1000;
201 }
202
203 hModule = LoadLibraryW(L"kernel32_vista.dll");
204
205 if (!hModule)
206 {
207 return GetSecondsQPC();
208 }
209
210 pGetTickCount64 = (PVOID)GetProcAddress(hModule, "GetTickCount64");
211
212 if (pGetTickCount64)
213 {
214 Ticks64 = pGetTickCount64() / 1000;
215 }
216 else
217 {
218 Ticks64 = GetSecondsQPC();
219 }
220
221 FreeLibrary(hModule);
222 return Ticks64;
223 }
224
225 /* Show usage */
226 static
227 VOID
228 Usage(VOID)
229 {
230 WCHAR Buf[4096];
231 if (LoadStringW(GetModuleHandle(NULL), IDS_USAGE, Buf, 4096))
232 wprintf(L"%s", Buf);
233 }
234
235 static
236 VOID
237 PrintRow(UINT nTitleID, BOOL bIndent, LPWSTR lpFormat, ...)
238 {
239 WCHAR Buf[BUFFER_SIZE];
240 va_list Args;
241 unsigned c;
242
243 if (nTitleID)
244 {
245 c = LoadStringW(GetModuleHandle(NULL), nTitleID, Buf, BUFFER_SIZE - 2);
246 if (!c)
247 return;
248
249 wcscpy(Buf + c, L": ");
250 } else
251 Buf[0] = L'\0';
252
253 if (!bIndent)
254 wprintf(L"%-32s", Buf);
255 else if (Buf[0])
256 wprintf(L"%38s%-16s", L"", Buf);
257 else
258 wprintf(L"%38s", L"");
259
260 va_start(Args, lpFormat);
261 vwprintf(lpFormat, Args);
262 va_end(Args);
263
264 wprintf(L"\n");
265 }
266
267 /* Print all system information */
268 VOID
269 AllSysInfo(VOID)
270 {
271 DWORD dwCharCount = BUFFER_SIZE, dwTimestamp, dwResult;
272 OSVERSIONINFOW VersionInfo;
273 SYSTEM_INFO SysInfo;
274 WCHAR Buf[BUFFER_SIZE], Tmp[BUFFER_SIZE], szSystemDir[MAX_PATH];
275 const WCHAR *lpcszSysType;
276 LPWSTR lpBuffer;
277 NETSETUP_JOIN_STATUS NetJoinStatus;
278 MEMORYSTATUS MemoryStatus;
279 unsigned int cSeconds, i, j;
280 TIME_ZONE_INFORMATION TimeZoneInfo;
281 HKEY hKey;
282 PIP_ADAPTER_ADDRESSES pAdapters;
283 ULONG cbAdapters;
284 PVOID SMBiosBuf;
285 PCHAR DmiStrings[ID_STRINGS_MAX] = { 0 };
286
287 if (!GetSystemDirectoryW(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0])))
288 {
289 wprintf(L"Error! GetSystemDirectory failed.\n");
290 return;
291 }
292
293 GetSystemInfo(&SysInfo);
294
295 // getting computer name
296 dwCharCount = BUFFER_SIZE;
297 if (!GetComputerNameW(Buf, &dwCharCount))
298 wprintf(L"Error! GetComputerName failed.\n");
299 else
300 PrintRow(IDS_HOST_NAME, FALSE, L"%s", Buf);
301
302 // open CurrentVersion key
303 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
304 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
305 0,
306 KEY_QUERY_VALUE,
307 &hKey) != ERROR_SUCCESS)
308 {
309 wprintf(L"Error! RegOpenKeyEx failed.\n");
310 return;
311 }
312
313 //getting OS Name
314 RegGetSZ(hKey, NULL, L"ProductName", Buf, BUFFER_SIZE);
315 PrintRow(IDS_OS_NAME, FALSE, L"%s", Buf);
316
317 //getting OS Version
318 ZeroMemory(&VersionInfo, sizeof(VersionInfo));
319 VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
320 GetVersionExW(&VersionInfo);
321
322 if (!LoadStringW(GetModuleHandle(NULL), IDS_BUILD, Tmp, BUFFER_SIZE))
323 Tmp[0] = L'\0';
324 PrintRow(IDS_OS_VERSION,
325 FALSE,
326 L"%lu.%lu.%lu %s %s %lu",
327 VersionInfo.dwMajorVersion,
328 VersionInfo.dwMinorVersion,
329 VersionInfo.dwBuildNumber,
330 VersionInfo.szCSDVersion,
331 Tmp,
332 VersionInfo.dwBuildNumber);
333
334 //getting OS Manufacturer
335
336 //getting OS Configuration
337
338 //getting OS Build Type
339 RegGetSZ(hKey, NULL, L"CurrentType", Buf, BUFFER_SIZE);
340 PrintRow(IDS_OS_BUILD_TYPE, FALSE, L"%s", Buf);
341
342 //getting Registered Owner
343 RegGetSZ(hKey, NULL, L"RegisteredOwner", Buf, BUFFER_SIZE);
344 PrintRow(IDS_REG_OWNER, FALSE, L"%s", Buf);
345
346 //getting Registered Organization
347 RegGetSZ(hKey, NULL, L"RegisteredOrganization", Buf, BUFFER_SIZE);
348 PrintRow(IDS_REG_ORG, FALSE, L"%s", Buf);
349
350 //getting Product ID
351 RegGetSZ(hKey, NULL, L"ProductId", Buf, BUFFER_SIZE);
352 PrintRow(IDS_PRODUCT_ID, FALSE, L"%s", Buf);
353
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);
358
359 // close Current Version key now
360 RegCloseKey(hKey);
361
362 //getting System Up Time
363 cSeconds = GetSeconds();
364 if (!LoadStringW(GetModuleHandle(NULL), IDS_UP_TIME_FORMAT, Tmp, BUFFER_SIZE))
365 Tmp[0] = L'\0';
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);
368
369 // prepare SMBIOS data
370 SMBiosBuf = LoadSMBiosData(DmiStrings);
371
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",
375 L"Manufacturer",
376 L"",
377 Buf,
378 sizeof(Buf)/sizeof(Buf[0]),
379 Tmp);
380 if (wcslen(Buf) == 0 && SMBiosBuf)
381 {
382 GetSMBiosStringW(DmiStrings[SYS_VENDOR], Buf, _countof(Buf), FALSE);
383 }
384 PrintRow(IDS_SYS_MANUFACTURER, FALSE, L"%s", Buf);
385
386 //getting System Model; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Model for Win >= 6.0
387 GetPrivateProfileStringW(L"General",
388 L"Model",
389 L"",
390 Buf,
391 sizeof(Buf)/sizeof(Buf[0]),
392 Tmp);
393 if (wcslen(Buf) == 0 && SMBiosBuf)
394 {
395 GetSMBiosStringW(DmiStrings[SYS_PRODUCT], Buf, _countof(Buf), FALSE);
396 }
397 PrintRow(IDS_SYS_MODEL, FALSE, L"%s", Buf);
398
399 //getting System type
400 switch (SysInfo.wProcessorArchitecture)
401 {
402 case PROCESSOR_ARCHITECTURE_INTEL:
403 lpcszSysType = L"X86-based PC";
404 break;
405 case PROCESSOR_ARCHITECTURE_IA64:
406 lpcszSysType = L"IA64-based PC";
407 break;
408 case PROCESSOR_ARCHITECTURE_AMD64:
409 lpcszSysType = L"AMD64-based PC";
410 break;
411 default:
412 lpcszSysType = L"Unknown";
413 break;
414 }
415 PrintRow(IDS_SYS_TYPE, FALSE, L"%s", lpcszSysType);
416
417 //getting Processor(s)
418 if (!LoadStringW(GetModuleHandle(NULL), IDS_PROCESSORS_FORMAT, Tmp, BUFFER_SIZE))
419 Tmp[0] = L'\0';
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++)
423 {
424 swprintf(Tmp, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%u", i);
425 j = swprintf(Buf, L"[%02u]: ", i + 1);
426
427 j += RegGetSZ(HKEY_LOCAL_MACHINE, Tmp, L"Identifier", Buf + j, BUFFER_SIZE - j);
428 if(j + 1 < BUFFER_SIZE)
429 Buf[j++] = L' ';
430 RegGetSZ(HKEY_LOCAL_MACHINE, Tmp, L"VendorIdentifier", Buf + j, BUFFER_SIZE - j);
431
432 PrintRow(0, FALSE, L"%s", Buf);
433 }
434
435 //getting BIOS Version
436 if (SMBiosBuf)
437 {
438 j = GetSMBiosStringW(DmiStrings[BIOS_VENDOR], Buf, BUFFER_SIZE, TRUE);
439 if (j + 1 < BUFFER_SIZE)
440 {
441 Buf[j++] = L' ';
442 Buf[j] = L'\0';
443 }
444 GetSMBiosStringW(DmiStrings[BIOS_VERSION], Buf + j, BUFFER_SIZE - j, TRUE);
445 }
446 else
447 {
448 RegGetSZ(HKEY_LOCAL_MACHINE,
449 L"HARDWARE\\DESCRIPTION\\System",
450 L"SystemBiosVersion",
451 Buf,
452 BUFFER_SIZE);
453 }
454 PrintRow(IDS_BIOS_VERSION, FALSE, L"%s", Buf);
455
456 //gettings BIOS date
457 if (SMBiosBuf)
458 {
459 GetSMBiosStringW(DmiStrings[BIOS_DATE], Buf, BUFFER_SIZE, TRUE);
460 }
461 else
462 {
463 RegGetSZ(HKEY_LOCAL_MACHINE,
464 L"HARDWARE\\DESCRIPTION\\System",
465 L"SystemBiosDate",
466 Buf,
467 BUFFER_SIZE);
468 }
469 PrintRow(IDS_BIOS_DATE, FALSE, L"%s", Buf);
470
471 // clean SMBIOS data
472 FreeSMBiosData(SMBiosBuf);
473
474 //getting ReactOS Directory
475 if (!GetWindowsDirectoryW(Buf, BUFFER_SIZE))
476 wprintf(L"Error! GetWindowsDirectory failed.");
477 else
478 PrintRow(IDS_ROS_DIR, FALSE, L"%s", Buf);
479
480 //getting System Directory
481 PrintRow(IDS_SYS_DIR, 0, L"%s", szSystemDir);
482
483 //getting Boot Device
484 RegGetSZ(HKEY_LOCAL_MACHINE,
485 L"SYSTEM\\Setup",
486 L"SystemPartition",
487 Buf,
488 BUFFER_SIZE);
489 PrintRow(IDS_BOOT_DEV, FALSE, L"%s", Buf);
490
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",
495 Tmp,
496 Buf,
497 BUFFER_SIZE))
498 {
499 /* get rid of @filename,resource */
500 lpBuffer = wcschr(Buf, L';');
501 if (lpBuffer)
502 SHLoadIndirectString(lpBuffer+1, lpBuffer+1, BUFFER_SIZE - (lpBuffer-Buf) - 1, NULL);
503
504 PrintRow(IDS_SYS_LOCALE, FALSE, L"%s", Buf);
505 }
506
507 //getting Input Locale
508 if (RegGetSZ(HKEY_CURRENT_USER,
509 L"Keyboard Layout\\Preload",
510 L"1",
511 Tmp,
512 BUFFER_SIZE) && wcslen(Tmp) > 4)
513 if (RegGetSZ(HKEY_CLASSES_ROOT,
514 L"MIME\\Database\\Rfc1766",
515 Tmp + 4,
516 Buf,
517 BUFFER_SIZE))
518 {
519 /* get rid of @filename,resource */
520 lpBuffer = wcschr(Buf, L';');
521 if (lpBuffer)
522 SHLoadIndirectString(lpBuffer+1, lpBuffer+1, BUFFER_SIZE - (lpBuffer-Buf) - 1, NULL);
523
524 PrintRow(IDS_INPUT_LOCALE, FALSE, L"%s", Buf);
525 }
526
527 //getting Time Zone
528 GetTimeZoneInformation(&TimeZoneInfo);
529
530 /* Open Time Zones key */
531 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
532 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
533 0,
534 KEY_ENUMERATE_SUB_KEYS|KEY_READ,
535 &hKey) == ERROR_SUCCESS)
536 {
537 unsigned i;
538
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)
542 {
543 RegGetSZ(hKey, Tmp, L"Std", Buf, BUFFER_SIZE);
544
545 if (!wcscmp(Buf, TimeZoneInfo.StandardName))
546 {
547 RegGetSZ(hKey, Tmp, L"Display", Buf, BUFFER_SIZE);
548
549 PrintRow(IDS_TIME_ZONE, FALSE, L"%s", Buf);
550
551 break;
552 }
553 }
554 RegCloseKey(hKey);
555 }
556
557 //getting Total Physical Memory
558 GlobalMemoryStatus(&MemoryStatus);
559 FormatBytes(Buf, MemoryStatus.dwTotalPhys);
560 PrintRow(IDS_TOTAL_PHYS_MEM, FALSE, L"%s", Buf);
561
562 //getting Available Physical Memory
563 FormatBytes(Buf, MemoryStatus.dwAvailPhys);
564 PrintRow(IDS_AVAIL_PHISICAL_MEM, FALSE, L"%s", Buf);
565
566 //getting Virtual Memory: Max Size
567 FormatBytes(Buf, MemoryStatus.dwTotalVirtual);
568 PrintRow(IDS_VIRT_MEM_MAX, FALSE, L"%s", Buf);
569
570 //getting Virtual Memory: Available
571 FormatBytes(Buf, MemoryStatus.dwAvailVirtual);
572 PrintRow(IDS_VIRT_MEM_AVAIL, FALSE, L"%s", Buf);
573
574 //getting Virtual Memory: In Use
575 FormatBytes(Buf, MemoryStatus.dwTotalVirtual-MemoryStatus.dwAvailVirtual);
576 PrintRow(IDS_VIRT_MEM_INUSE, FALSE, L"%s", Buf);
577
578 //getting Page File Location(s)
579 if (RegGetSZ(HKEY_LOCAL_MACHINE,
580 L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management",
581 L"PagingFiles",
582 Buf,
583 BUFFER_SIZE))
584 {
585 int i;
586
587 for(i = 0; Buf[i]; i++)
588 {
589 if (Buf[i] == L' ')
590 {
591 Buf[i] = L'\0';
592 break;
593 }
594 }
595
596 PrintRow(IDS_PAGEFILE_LOC, FALSE, L"%s", Buf);
597 }
598
599 //getting Domain
600 if (NetGetJoinInformation (NULL, &lpBuffer, &NetJoinStatus) == NERR_Success)
601 {
602 if (NetJoinStatus == NetSetupWorkgroupName || NetJoinStatus == NetSetupDomainName)
603 PrintRow(IDS_DOMAIN, FALSE, L"%s", lpBuffer);
604
605 NetApiBufferFree(lpBuffer);
606 }
607
608 //getting Logon Server
609
610 //getting NetWork Card(s)
611 cbAdapters = 4096;
612 pAdapters = malloc(cbAdapters);
613 while((dwResult = GetAdaptersAddresses(AF_UNSPEC, 0x0002, NULL, pAdapters, &cbAdapters)) == ERROR_BUFFER_OVERFLOW)
614 {
615 cbAdapters += 4096;
616 pAdapters = (PIP_ADAPTER_ADDRESSES)realloc(pAdapters, cbAdapters);
617 }
618
619 if (dwResult == ERROR_SUCCESS)
620 {
621 PIP_ADAPTER_ADDRESSES pCurrentAdapter = pAdapters;
622 unsigned cAdapters = 0;
623
624 /* Count adapters */
625 for(i = 0; pCurrentAdapter; ++i)
626 {
627 if (pCurrentAdapter->IfType != 24 && pCurrentAdapter->IfType != 131)
628 ++cAdapters;
629 pCurrentAdapter = pCurrentAdapter->Next;
630 }
631
632
633 /* Print adapters count */
634 if (!LoadStringW(GetModuleHandle(NULL), IDS_NETWORK_CARDS_FORMAT, Tmp, BUFFER_SIZE))
635 Tmp[0] = L'\0';
636 swprintf(Buf, Tmp, cAdapters);
637 PrintRow(IDS_NETWORK_CARDS, FALSE, L"%s", Buf);
638
639 /* Show information about each adapter */
640 pCurrentAdapter = pAdapters;
641 for(i = 0; pCurrentAdapter; ++i)
642 {
643 if (pCurrentAdapter->IfType != 24 && pCurrentAdapter->IfType != 131)//IF_TYPE_SOFTWARE_LOOPBACK)
644 {
645 PIP_ADAPTER_UNICAST_ADDRESS pAddress;
646
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))
650 {
651 if (!LoadStringW(GetModuleHandle(NULL), IDS_NO, Buf, BUFFER_SIZE))
652 Buf[0] = L'\0';
653 PrintRow(IDS_DHCP_ENABLED, TRUE, Buf);
654 }
655 if (pCurrentAdapter->OperStatus == IfOperStatusDown)
656 {
657 if (!LoadStringW(GetModuleHandle(NULL), IDS_MEDIA_DISCONNECTED, Buf, BUFFER_SIZE))
658 Buf[0] = L'\0';
659 PrintRow(IDS_STATUS, TRUE, Buf);
660 }
661 else
662 {
663 if (!LoadStringW(GetModuleHandle(NULL), IDS_IP_ADDRESSES, Buf, BUFFER_SIZE))
664 Buf[0] = L'\0';
665 PrintRow(0, TRUE, Buf);
666 pAddress = pCurrentAdapter->FirstUnicastAddress;
667 for (j = 0; pAddress; ++j)
668 {
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;
673 }
674 }
675 }
676 pCurrentAdapter = pCurrentAdapter->Next;
677 }
678 }
679 free(pAdapters);
680 }
681
682 /* Main program */
683 int
684 main(int argc, char *argv[])
685 {
686 WSADATA WsaData;
687 int i;
688
689 setlocale(LC_ALL, "");
690
691 WSAStartup(MAKEWORD(2, 2), &WsaData);
692
693 for (i = 1; i < argc; ++i)
694 {
695 if (!strcmp(argv[i], "/?") || !strcmp(argv[i], "-?"))
696 {
697 Usage();
698 return 0;
699 }
700 else
701 {
702 printf("Unsupported argument: %s\n", argv[i]);
703 return -1;
704 }
705 }
706
707 AllSysInfo();
708
709 return 0;
710 }