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