ReactOS 0.4.15-dev-7924-g5949c20
address.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/iphlpapi/address.c
5 * PURPOSE: iphlpapi implementation - Adapter Address APIs
6 * PROGRAMMERS: Jérôme Gardou (jerome.gardou@reactos.org)
7 */
8
9#include "iphlpapi_private.h"
10
12#ifdef GetAdaptersAddressesV2
13/* Helper for GetAdaptersAddresses:
14 * Retrieves the list of network adapters from tcpip.sys */
15static
17GetInterfacesList(
18 _In_ HANDLE TcpFile,
20 _Out_ ULONG* InterfaceCount)
21{
22
24 IO_STATUS_BLOCK StatusBlock;
27
28 ZeroMemory(&TcpQueryInfo, sizeof(TcpQueryInfo));
29 TcpQueryInfo.ID.toi_class = INFO_CLASS_GENERIC;
30 TcpQueryInfo.ID.toi_type = INFO_TYPE_PROVIDER;
31 TcpQueryInfo.ID.toi_id = ENTITY_LIST_ID;
33 TcpQueryInfo.ID.toi_entity.tei_instance = 0;
34
36 TcpFile,
37 NULL,
38 NULL,
39 NULL,
40 &StatusBlock,
42 &TcpQueryInfo,
43 sizeof(TcpQueryInfo),
44 NULL,
45 0);
47 {
48 /* So we have to wait a bit */
50 if (NT_SUCCESS(Status))
51 Status = StatusBlock.Status;
52 }
53
54 if (!NT_SUCCESS(Status))
55 return Status;
56
57 BufferSize = StatusBlock.Information;
59 if (!*EntityList)
60 return STATUS_NO_MEMORY;
61
62 /* Do the real call */
64 TcpFile,
65 NULL,
66 NULL,
67 NULL,
68 &StatusBlock,
70 &TcpQueryInfo,
71 sizeof(TcpQueryInfo),
75 {
76 /* So we have to wait a bit */
78 if (NT_SUCCESS(Status))
79 Status = StatusBlock.Status;
80 }
81
82 if (!NT_SUCCESS(Status))
83 {
85 return Status;
86 }
87
88 *InterfaceCount = BufferSize / sizeof(TDIEntityID);
89 return Status;
90}
91
92static
94GetSnmpInfo(
95 _In_ HANDLE TcpFile,
96 _In_ TDIEntityID InterfaceID,
98{
100 IO_STATUS_BLOCK StatusBlock;
102
103 ZeroMemory(&TcpQueryInfo, sizeof(TcpQueryInfo));
104 TcpQueryInfo.ID.toi_class = INFO_CLASS_PROTOCOL;
105 TcpQueryInfo.ID.toi_type = INFO_TYPE_PROVIDER;
106 TcpQueryInfo.ID.toi_id = IP_MIB_STATS_ID;
107 TcpQueryInfo.ID.toi_entity = InterfaceID;
108
110 TcpFile,
111 NULL,
112 NULL,
113 NULL,
114 &StatusBlock,
116 &TcpQueryInfo,
117 sizeof(TcpQueryInfo),
118 Info,
119 sizeof(*Info));
120 if (Status == STATUS_PENDING)
121 {
122 /* So we have to wait a bit */
124 if (NT_SUCCESS(Status))
125 Status = StatusBlock.Status;
126 }
127
128 return Status;
129}
130
131static
133GetAddrEntries(
134 _In_ HANDLE TcpFile,
135 _In_ TDIEntityID InterfaceID,
137 _In_ ULONG NumEntries)
138{
140 IO_STATUS_BLOCK StatusBlock;
142
143 ZeroMemory(&TcpQueryInfo, sizeof(TcpQueryInfo));
144 TcpQueryInfo.ID.toi_class = INFO_CLASS_PROTOCOL;
145 TcpQueryInfo.ID.toi_type = INFO_TYPE_PROVIDER;
146 TcpQueryInfo.ID.toi_id = IP_MIB_ADDRTABLE_ENTRY_ID;
147 TcpQueryInfo.ID.toi_entity = InterfaceID;
148
150 TcpFile,
151 NULL,
152 NULL,
153 NULL,
154 &StatusBlock,
156 &TcpQueryInfo,
157 sizeof(TcpQueryInfo),
158 Entries,
159 NumEntries * sizeof(Entries[0]));
160 if (Status == STATUS_PENDING)
161 {
162 /* So we have to wait a bit */
164 if (NT_SUCCESS(Status))
165 Status = StatusBlock.Status;
166 }
167
168 return Status;
169}
170
171/*
172 * Fills the IFEntry buffer from tcpip.sys.
173 * The buffer size MUST be FIELD_OFFSET(IFEntry, if_descr[MAX_ADAPTER_DESCRIPTION_LENGTH + 1]).
174 * See MSDN IFEntry struct definition if you don't believe me. ;-)
175 */
176static
178GetInterfaceEntry(
179 _In_ HANDLE TcpFile,
180 _In_ TDIEntityID InterfaceID,
182{
184 IO_STATUS_BLOCK StatusBlock;
186
187 ZeroMemory(&TcpQueryInfo, sizeof(TcpQueryInfo));
188 TcpQueryInfo.ID.toi_class = INFO_CLASS_PROTOCOL;
189 TcpQueryInfo.ID.toi_type = INFO_TYPE_PROVIDER;
190 TcpQueryInfo.ID.toi_id = IP_MIB_STATS_ID;
191 TcpQueryInfo.ID.toi_entity = InterfaceID;
192
194 TcpFile,
195 NULL,
196 NULL,
197 NULL,
198 &StatusBlock,
200 &TcpQueryInfo,
201 sizeof(TcpQueryInfo),
202 Entry,
204 if (Status == STATUS_PENDING)
205 {
206 /* So we have to wait a bit */
208 if (NT_SUCCESS(Status))
209 Status = StatusBlock.Status;
210 }
211
212 return Status;
213}
214
215/* Helpers to get the list of DNS for an interface */
216static
217VOID
218EnumerateServerNameSize(
220 _In_ PWCHAR NameServer,
222{
224
225 /* This is just sizing here */
227 UNREFERENCED_PARAMETER(NameServer);
228
229 *BufferSize += sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS) + sizeof(SOCKADDR);
230}
231
232static
233VOID
234EnumerateServerName(
236 _In_ PWCHAR NameServer,
238{
239 PIP_ADAPTER_DNS_SERVER_ADDRESS** Ptr = Data;
240 PIP_ADAPTER_DNS_SERVER_ADDRESS ServerAddress = **Ptr;
241
243
244 ServerAddress->Length = sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS);
245 ServerAddress->Address.lpSockaddr = (PVOID)(ServerAddress + 1);
246 ServerAddress->Address.iSockaddrLength = sizeof(SOCKADDR);
247
248
249 /* Get the address from the server name string */
250 //FIXME: Only ipv4 for now...
252 NameServer,
253 AF_INET,
254 NULL,
255 ServerAddress->Address.lpSockaddr,
256 &ServerAddress->Address.iSockaddrLength))
257 {
258 /* Pass along, name conversion failed */
259 ERR("%S is not a valid IP address\n", NameServer);
260 return;
261 }
262
263 /* Go to next item */
264 ServerAddress->Next = (PVOID)(ServerAddress->Address.lpSockaddr + 1);
265 *Ptr = &ServerAddress->Next;
266}
267
268static
269VOID
270QueryFlags(
272 _In_ DWORD InterfaceLength,
274{
275 HKEY InterfaceKey;
276 CHAR KeyName[256];
278
279 *Flags = 0;
280
281 snprintf(KeyName, 256,
282 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%*s",
283 InterfaceLength, Interface);
284
286 {
287 Size = sizeof(DWORD);
288 if (RegQueryValueExA(InterfaceKey, "EnableDHCP", NULL, &Type, (LPBYTE)&Data, &Size) == ERROR_SUCCESS &&
289 Type == REG_DWORD && Data == 1)
290 {
291 *Flags |= IP_ADAPTER_DHCP_ENABLED;
292 }
293
294 Size = sizeof(DWORD);
295 if (RegQueryValueExA(InterfaceKey, "RegisterAdapterName", NULL, &Type, (LPBYTE)&Data, &Size) == ERROR_SUCCESS &&
296 Type == REG_DWORD && Data == 1)
297 {
298 *Flags |= IP_ADAPTER_REGISTER_ADAPTER_SUFFIX;
299 }
300
301 Size = 0;
302 if (RegQueryValueExA(InterfaceKey, "NameServer", NULL, &Type, (LPBYTE)&Data, &Size) != ERROR_SUCCESS)
303 {
304 *Flags |= IP_ADAPTER_DDNS_ENABLED;
305 }
306
307 RegCloseKey(InterfaceKey);
308 }
309
310 // FIXME: handle 0x8 -> 0x20
311}
312
313DWORD
314WINAPI
316GetAdaptersAddresses(
320 _Inout_ PIP_ADAPTER_ADDRESSES pAdapterAddresses,
321 _Inout_ PULONG pOutBufLen)
322{
324 HANDLE TcpFile;
325 TDIEntityID* InterfacesList;
326 ULONG InterfacesCount;
327 ULONG AdaptersCount = 0;
328 ULONG i;
329 ULONG TotalSize = 0, RemainingSize;
330 BYTE* Ptr = (BYTE*)pAdapterAddresses;
331 DWORD MIN_SIZE = 15 * 1024;
332 PIP_ADAPTER_ADDRESSES PreviousAA = NULL;
333
334 TRACE("Family %u, Flags 0x%08x, Reserved %p, pAdapterAddress %p, pOutBufLen %p\n",
335 Family, Flags, Reserved, pAdapterAddresses, pOutBufLen);
336
337 if (!pOutBufLen)
339
340 // FIXME: the exact needed size should be computed first, BEFORE doing any write to the output buffer.
341 // As suggested by MSDN, require a 15 KB buffer, which allows to React properly to length checks.
342 if(!Ptr || *pOutBufLen < MIN_SIZE)
343 {
344 *pOutBufLen = MIN_SIZE;
346 }
347
348 switch(Family)
349 {
350 case AF_INET:
351 break;
352 case AF_INET6:
353 /* One day maybe... */
354 FIXME("IPv6 is not supported in ReactOS!\n");
355 /* We got nothing to say in this case */
356 return ERROR_NO_DATA;
357 break;
358 case AF_UNSPEC:
359 WARN("IPv6 addresses ignored, IPv4 only\n");
360 Family = AF_INET;
361 break;
362 default:
363 ERR("Invalid family 0x%x\n", Family);
365 break;
366 }
367
368 RemainingSize = *pOutBufLen;
369 if (Ptr)
370 ZeroMemory(Ptr, RemainingSize);
371
372 /* open the tcpip driver */
373 Status = openTcpFile(&TcpFile, FILE_READ_DATA);
374 if (!NT_SUCCESS(Status))
375 {
376 ERR("Could not open handle to tcpip.sys. Status %08x\n", Status);
378 }
379
380 /* Get the interfaces list */
381 Status = GetInterfacesList(TcpFile, &InterfacesList, &InterfacesCount);
382 if (!NT_SUCCESS(Status))
383 {
384 ERR("Could not get adapters list. Status %08x\n", Status);
385 NtClose(TcpFile);
387 }
388
389 /* Let's see if we got any adapter. */
390 for (i = 0; i < InterfacesCount; i++)
391 {
393 ULONG CurrentAASize = 0;
394 ULONG FriendlySize = 0;
395
396 if (InterfacesList[i].tei_entity == IF_ENTITY)
397 {
398 BYTE EntryBuffer[FIELD_OFFSET(IFEntry, if_descr) +
400 IFEntry* Entry = (IFEntry*)EntryBuffer;
401
402 /* Remember we got one */
403 AdaptersCount++;
404
405 /* Set the pointer to this instance in the previous one*/
406 if(PreviousAA)
407 PreviousAA->Next = CurrentAA;
408
409 /* Of course we need some space for the base structure. */
410 CurrentAASize = sizeof(IP_ADAPTER_ADDRESSES);
411
412 /* Get the entry */
413 Status = GetInterfaceEntry(TcpFile, InterfacesList[i], Entry);
414 if (!NT_SUCCESS(Status))
415 goto Error;
416
417 TRACE("Got entity %*s, index %u.\n",
418 Entry->if_descrlen, &Entry->if_descr[0], Entry->if_index);
419
420 /* Add the adapter name */
421 CurrentAASize += Entry->if_descrlen + sizeof(CHAR);
422
423 /* Add the DNS suffix */
424 CurrentAASize += sizeof(WCHAR);
425
426 /* Add the description. */
427 CurrentAASize += sizeof(WCHAR);
428
430 {
431 /* Get the friendly name */
432 HKEY ConnectionKey;
433 CHAR KeyName[256];
434
435 snprintf(KeyName, 256,
436 "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%*s\\Connection",
437 Entry->if_descrlen, &Entry->if_descr[0]);
438
440 {
442 DWORD ValueSize = 0;
443
444 if (RegQueryValueExW(ConnectionKey, L"Name", NULL, &ValueType, NULL, &ValueSize) == ERROR_SUCCESS &&
445 ValueType == REG_SZ)
446 {
447 /* We remove the null char, it will be re-added after */
448 FriendlySize = ValueSize - sizeof(WCHAR);
449 CurrentAASize += FriendlySize;
450 }
451
452 RegCloseKey(ConnectionKey);
453 }
454
455 /* We always make sure to have enough room for empty string */
456 CurrentAASize += sizeof(WCHAR);
457 }
458
459 if (!(Flags & GAA_FLAG_SKIP_DNS_SERVER))
460 {
461 /* Enumerate the name servers */
462 HKEY InterfaceKey;
463 CHAR KeyName[256];
464
465 snprintf(KeyName, 256,
466 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%*s",
467 Entry->if_descrlen, &Entry->if_descr[0]);
468
470 {
471 EnumNameServers(InterfaceKey, NULL, &CurrentAASize, EnumerateServerNameSize);
472 RegCloseKey(InterfaceKey);
473 }
474 }
475
476 /* This is part of what we will need */
477 TotalSize += CurrentAASize;
478
479 /* Fill in the data */
480 if ((CurrentAA) && (RemainingSize >= CurrentAASize))
481 {
482 CurrentAA->Length = sizeof(IP_ADAPTER_ADDRESSES);
483 CurrentAA->IfIndex = Entry->if_index;
484 CopyMemory(CurrentAA->PhysicalAddress, Entry->if_physaddr, Entry->if_physaddrlen);
485 CurrentAA->PhysicalAddressLength = Entry->if_physaddrlen;
486 QueryFlags(&Entry->if_descr[0], Entry->if_descrlen, &CurrentAA->Flags);
487 CurrentAA->Mtu = Entry->if_mtu;
488 CurrentAA->IfType = Entry->if_type;
489 if(Entry->if_operstatus >= IF_OPER_STATUS_CONNECTING)
490 CurrentAA->OperStatus = IfOperStatusUp;
491 else
492 CurrentAA->OperStatus = IfOperStatusDown;
493
494 /* Next items */
495 Ptr = (BYTE*)(CurrentAA + 1);
496
497 /* Now fill in the name */
498 CopyMemory(Ptr, &Entry->if_descr[0], Entry->if_descrlen);
499 CurrentAA->AdapterName = (PCHAR)Ptr;
500 CurrentAA->AdapterName[Entry->if_descrlen] = '\0';
501 /* Next items */
502 Ptr = (BYTE*)(CurrentAA->AdapterName + Entry->if_descrlen + 1);
503
504 /* The DNS suffix */
505 CurrentAA->DnsSuffix = (PWCHAR)Ptr;
506 CurrentAA->DnsSuffix[0] = L'\0';
507 /* Next items */
508 Ptr = (BYTE*)(CurrentAA->DnsSuffix + 1);
509
510 /* The description */
511 CurrentAA->Description = (PWCHAR)Ptr;
512 CurrentAA->Description[0] = L'\0';
513 /* Next items */
514 Ptr = (BYTE*)(CurrentAA->Description + 1);
515
516 /* The friendly name */
518 {
519 CurrentAA->FriendlyName = (PWCHAR)Ptr;
520
521 if (FriendlySize != 0)
522 {
523 /* Get the friendly name */
524 HKEY ConnectionKey;
525 CHAR KeyName[256];
526
527 snprintf(KeyName, 256,
528 "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%*s\\Connection",
529 Entry->if_descrlen, &Entry->if_descr[0]);
530
532 {
534 DWORD ValueSize = FriendlySize + sizeof(WCHAR);
535
536 if (RegQueryValueExW(ConnectionKey, L"Name", NULL, &ValueType, (LPBYTE)CurrentAA->FriendlyName, &ValueSize) == ERROR_SUCCESS &&
537 ValueType == REG_SZ && ValueSize == FriendlySize + sizeof(WCHAR))
538 {
539 /* We're done, next items */
540 Ptr = (BYTE*)(CurrentAA->FriendlyName + (ValueSize / sizeof(WCHAR)));
541 }
542 else
543 {
544 /* Fail */
545 ERR("Friendly name changed after probe!\n");
546 FriendlySize = 0;
547 }
548
549 RegCloseKey(ConnectionKey);
550 }
551 else
552 {
553 /* Fail */
554 FriendlySize = 0;
555 }
556 }
557
558 /* In case of failure (or no name) */
559 if (FriendlySize == 0)
560 {
561 CurrentAA->FriendlyName[0] = L'\0';
562 /* Next items */
563 Ptr = (BYTE*)(CurrentAA->FriendlyName + 1);
564 }
565 }
566
567 /* The DNS Servers */
568 if (!(Flags & GAA_FLAG_SKIP_DNS_SERVER))
569 {
570 /* Enumerate the name servers */
571 HKEY InterfaceKey;
572 CHAR KeyName[256];
573
574 snprintf(KeyName, 256,
575 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%*s",
576 Entry->if_descrlen, &Entry->if_descr[0]);
577
579 {
580 TRACE("Failed opening interface key for interface %*s\n", Entry->if_descrlen, &Entry->if_descr[0]);
581 }
582 else
583 {
584 PIP_ADAPTER_DNS_SERVER_ADDRESS* ServerAddressPtr;
585
586 CurrentAA->FirstDnsServerAddress = (PIP_ADAPTER_DNS_SERVER_ADDRESS)Ptr;
587 ServerAddressPtr = &CurrentAA->FirstDnsServerAddress;
588
589 EnumNameServers(InterfaceKey, NULL, &ServerAddressPtr, EnumerateServerName);
590 RegCloseKey(InterfaceKey);
591
592 /* Set the last entry in the list as having NULL next member */
593 Ptr = (BYTE*)*ServerAddressPtr;
594 *ServerAddressPtr = NULL;
595 }
596 }
597
598 /* We're done for this interface */
599 PreviousAA = CurrentAA;
600 RemainingSize -= CurrentAASize;
601 }
602 }
603 }
604
605 if (AdaptersCount == 0)
606 {
607 /* Uh? Not even localhost ?! */
608 ERR("No Adapters found!\n");
609 *pOutBufLen = 0;
610 return ERROR_NO_DATA;
611 }
612
613 /* See if we have anything to add */
614 // FIXME: Anycast and multicast
615 if ((Flags & (GAA_FLAG_SKIP_UNICAST | GAA_FLAG_INCLUDE_PREFIX)) == GAA_FLAG_SKIP_UNICAST)
616 goto Success;
617
618 /* Now fill in the addresses */
619 for (i = 0; i < InterfacesCount; i++)
620 {
621 /* Look for network layers */
622 if ((InterfacesList[i].tei_entity == CL_NL_ENTITY)
623 || (InterfacesList[i].tei_entity == CO_NL_ENTITY))
624 {
625 IPSNMPInfo SnmpInfo;
626 PIP_ADAPTER_ADDRESSES CurrentAA = NULL;
627 IPAddrEntry* AddrEntries;
628 ULONG j;
629
630 /* Get its SNMP info */
631 Status = GetSnmpInfo(TcpFile, InterfacesList[i], &SnmpInfo);
632 if (!NT_SUCCESS(Status))
633 goto Error;
634
635 if (SnmpInfo.ipsi_numaddr == 0)
636 continue;
637
638 /* Allocate the address entry array and get them */
639 AddrEntries = HeapAlloc(GetProcessHeap(),
641 SnmpInfo.ipsi_numaddr * sizeof(AddrEntries[0]));
642 if (!AddrEntries)
643 {
645 goto Error;
646 }
647 Status = GetAddrEntries(TcpFile, InterfacesList[i], AddrEntries, SnmpInfo.ipsi_numaddr);
648 if (!NT_SUCCESS(Status))
649 {
650 HeapFree(GetProcessHeap(), 0, AddrEntries);
651 goto Error;
652 }
653
654 for (j = 0; j < SnmpInfo.ipsi_numaddr; j++)
655 {
656 /* Find the adapters struct for this address. */
657 if (pAdapterAddresses)
658 {
659 CurrentAA = pAdapterAddresses;
660 while (CurrentAA)
661 {
662 if (CurrentAA->IfIndex == AddrEntries[j].iae_index)
663 break;
664
665 CurrentAA = CurrentAA->Next;
666 }
667
668 if (!CurrentAA)
669 {
670 ERR("Got address for interface %u but no adapter was found for it.\n", AddrEntries[j].iae_index);
671 /* Go to the next address */
672 continue;
673 }
674 }
675
676 TRACE("address is 0x%08x, mask is 0x%08x\n", AddrEntries[j].iae_addr, AddrEntries[j].iae_mask);
677
678 //FIXME: For now reactos only supports unicast addresses
680 {
681 ULONG Size = sizeof(IP_ADAPTER_UNICAST_ADDRESS) + sizeof(SOCKADDR);
682
683 if (Ptr && (RemainingSize >= Size))
684 {
685 PIP_ADAPTER_UNICAST_ADDRESS UnicastAddress = (PIP_ADAPTER_UNICAST_ADDRESS)Ptr;
686
687 /* Fill in the structure */
688 UnicastAddress->Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS);
689 UnicastAddress->Next = CurrentAA->FirstUnicastAddress;
690
691 // FIXME: Put meaningful value here
692 UnicastAddress->Flags = 0;
693 UnicastAddress->PrefixOrigin = IpPrefixOriginOther;
694 UnicastAddress->SuffixOrigin = IpSuffixOriginOther;
695 UnicastAddress->DadState = IpDadStatePreferred;
696 UnicastAddress->ValidLifetime = 0xFFFFFFFF;
697 UnicastAddress->PreferredLifetime = 0xFFFFFFFF;
698
699 /* Set the address */
700 //FIXME: ipv4 only (again...)
701 UnicastAddress->Address.lpSockaddr = (LPSOCKADDR)(UnicastAddress + 1);
702 UnicastAddress->Address.iSockaddrLength = sizeof(SOCKADDR);
703 UnicastAddress->Address.lpSockaddr->sa_family = AF_INET;
704 ((LPSOCKADDR_IN)UnicastAddress->Address.lpSockaddr)->sin_port = 0;
705 memcpy(&((LPSOCKADDR_IN)UnicastAddress->Address.lpSockaddr)->sin_addr, &AddrEntries[j].iae_addr, sizeof(AddrEntries[j].iae_addr));
706
707 CurrentAA->FirstUnicastAddress = UnicastAddress;
708 Ptr += Size;
709 RemainingSize -= Size;
710 }
711
712 TotalSize += Size;
713 }
714
715 if (Flags & GAA_FLAG_INCLUDE_PREFIX)
716 {
717 ULONG Size = sizeof(IP_ADAPTER_PREFIX) + sizeof(SOCKADDR);
718
719 if (Ptr && (RemainingSize >= Size))
720 {
721 PIP_ADAPTER_PREFIX Prefix = (PIP_ADAPTER_PREFIX)Ptr;
722
723 /* Fill in the structure */
724 Prefix->Length = sizeof(IP_ADAPTER_PREFIX);
725 Prefix->Next = CurrentAA->FirstPrefix;
726
727 /* Set the address */
728 //FIXME: ipv4 only (again...)
729 Prefix->Address.lpSockaddr = (LPSOCKADDR)(Prefix + 1);
730 Prefix->Address.iSockaddrLength = sizeof(AddrEntries[j].iae_mask);
731 Prefix->Address.lpSockaddr->sa_family = AF_INET;
732 memcpy(Prefix->Address.lpSockaddr->sa_data, &AddrEntries[j].iae_mask, sizeof(AddrEntries[j].iae_mask));
733
734 /* Compute the prefix size */
735 _BitScanReverse(&Prefix->PrefixLength, AddrEntries[j].iae_mask);
736
737 CurrentAA->FirstPrefix = Prefix;
738 Ptr += Size;
739 RemainingSize -= Size;
740 }
741
742 TotalSize += Size;
743 }
744 }
745
746 HeapFree(GetProcessHeap(), 0, AddrEntries);
747 }
748 }
749
750Success:
751 /* We're done */
752 HeapFree(GetProcessHeap(), 0, InterfacesList);
753 NtClose(TcpFile);
754 *pOutBufLen = TotalSize;
755 TRACE("TotalSize: %x\n", *pOutBufLen);
756 return ERROR_SUCCESS;
757
758Error:
759 ERR("Failed! Status 0x%08x\n", Status);
760 *pOutBufLen = 0;
761 HeapFree(GetProcessHeap(), 0, InterfacesList);
762 NtClose(TcpFile);
764}
765#endif
static const ENTRY Entries[]
Type
Definition: Type.h:7
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:243
#define IP_MIB_STATS_ID
Definition: afd.h:35
#define IP_MIB_ADDRTABLE_ENTRY_ID
Definition: afd.h:36
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define CHAR(Char)
BOOL Error
Definition: chkdsk.c:66
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
#define BufferSize
Definition: mmc.h:75
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define AF_INET
Definition: tcpip.h:117
TDIEntityInfo * EntityList
Definition: main.c:27
#define MIN_SIZE
Definition: mem.c:169
@ Success
Definition: eventcreate.c:712
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
@ IfOperStatusUp
Definition: ifdef.h:185
@ IfOperStatusDown
Definition: ifdef.h:186
#define MAX_ADAPTER_DESCRIPTION_LENGTH
Definition: iinfo.c:16
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask)
Definition: intrin_arm.h:180
static PIP_ADAPTER_ADDRESSES
Definition: iphlpapi.c:76
#define GAA_FLAG_SKIP_FRIENDLY_NAME
#define GAA_FLAG_SKIP_UNICAST
LSTATUS EnumNameServers(HKEY RegHandle, LPWSTR Interface, PVOID Data, EnumNameServersFunc cb)
@ IF_OPER_STATUS_CONNECTING
Definition: ipifcons.h:241
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:86
#define REG_SZ
Definition: layer.c:22
#define PCHAR
Definition: match.c:90
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
@ IpDadStatePreferred
Definition: nldef.h:49
@ IpPrefixOriginOther
Definition: nldef.h:9
@ IpSuffixOriginOther
Definition: nldef.h:30
#define FILE_READ_DATA
Definition: nt_native.h:628
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DWORD
Definition: nt_native.h:44
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define L(x)
Definition: ntvdm.h:50
static int Family
Definition: ping.c:62
INT WSAAPI WSAStringToAddressW(IN LPWSTR AddressString, IN INT AddressFamily, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPSOCKADDR lpAddress, IN OUT LPINT lpAddressLength)
Definition: rnr.c:977
#define REG_DWORD
Definition: sdbapi.c:596
NTSTATUS openTcpFile(PHANDLE tcpFile, ACCESS_MASK DesiredAccess)
Definition: handle.c:12
#define TRACE(s)
Definition: solgame.cpp:4
base of all file and directory entries
Definition: entries.h:83
ULONG iae_mask
Definition: tcpioctl.h:164
ULONG ipsi_numaddr
Definition: tcpioctl.h:156
unsigned short Length
Definition: sprintf.c:451
ULONG tei_entity
Definition: tdiinfo.h:31
ULONG tei_instance
Definition: tdiinfo.h:32
ULONG toi_id
Definition: tdiinfo.h:77
ULONG toi_type
Definition: tdiinfo.h:76
ULONG toi_class
Definition: tdiinfo.h:75
TDIEntityID toi_entity
Definition: tdiinfo.h:74
#define IF_ENTITY
Definition: tdiinfo.h:47
#define ENTITY_LIST_ID
Definition: tdiinfo.h:38
#define CO_NL_ENTITY
Definition: tdiinfo.h:44
struct _TDIEntityID TDIEntityID
#define INFO_CLASS_PROTOCOL
Definition: tdiinfo.h:65
#define INFO_CLASS_GENERIC
Definition: tdiinfo.h:64
#define INFO_TYPE_PROVIDER
Definition: tdiinfo.h:69
#define GENERIC_ENTITY
Definition: tdiinfo.h:37
#define CL_NL_ENTITY
Definition: tdiinfo.h:42
#define IOCTL_TCP_QUERY_INFORMATION_EX
Definition: tditest.h:110
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
void * PVOID
Definition: typedefs.h:50
uint32_t * LPDWORD
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
#define ZeroMemory
Definition: winbase.h:1712
#define CopyMemory
Definition: winbase.h:1710
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define WINAPI
Definition: msvc.h:6
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define ERROR_NO_DATA
Definition: winerror.h:284
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
struct sockaddr_in * LPSOCKADDR_IN
Definition: winsock.h:489
#define AF_INET6
Definition: winsock.h:369
struct sockaddr * LPSOCKADDR
Definition: winsock.h:486
struct sockaddr SOCKADDR
Definition: winsock.h:484
#define AF_UNSPEC
Definition: winsock.h:344
#define snprintf
Definition: wintirpc.h:48
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1630
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193