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