ReactOS  0.4.15-dev-1397-g19779b3
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 */
15 static
17 GetInterfacesList(
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;
32  TcpQueryInfo.ID.toi_entity.tei_entity = GENERIC_ENTITY;
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);
46  if (Status == STATUS_PENDING)
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),
72  *EntityList,
73  BufferSize);
74  if (Status == STATUS_PENDING)
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 
92 static
94 GetSnmpInfo(
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 */
123  Status = NtWaitForSingleObject(TcpFile, FALSE, NULL);
124  if (NT_SUCCESS(Status))
125  Status = StatusBlock.Status;
126  }
127 
128  return Status;
129 }
130 
131 static
132 NTSTATUS
133 GetAddrEntries(
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 */
163  Status = NtWaitForSingleObject(TcpFile, FALSE, NULL);
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  */
176 static
177 NTSTATUS
178 GetInterfaceEntry(
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 */
207  Status = NtWaitForSingleObject(TcpFile, FALSE, NULL);
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 */
216 static
217 VOID
218 EnumerateServerNameSize(
220  _In_ PWCHAR NameServer,
222 {
223  ULONG* BufferSize = Data;
224 
225  /* This is just sizing here */
227  UNREFERENCED_PARAMETER(NameServer);
228 
229  *BufferSize += sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS) + sizeof(SOCKADDR);
230 }
231 
232 static
233 VOID
234 EnumerateServerName(
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 
268 static
269 VOID
270 QueryFlags(
272  _In_ DWORD InterfaceLength,
274 {
275  HKEY InterfaceKey;
276  CHAR KeyName[256];
277  DWORD Type, Size, Data;
278 
279  *Flags = 0;
280 
281  snprintf(KeyName, 256,
282  "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%*s",
283  InterfaceLength, Interface);
284 
285  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &InterfaceKey) == ERROR_SUCCESS)
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 
313 DWORD
314 WINAPI
316 GetAdaptersAddresses(
317  _In_ ULONG Family,
318  _In_ ULONG Flags,
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  FIXME("GetAdaptersAddresses - Semi Stub: 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;
345  return ERROR_BUFFER_OVERFLOW;
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 
439  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &ConnectionKey) == ERROR_SUCCESS)
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 
469  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &InterfaceKey) == ERROR_SUCCESS)
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 
531  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &ConnectionKey) == ERROR_SUCCESS)
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 
578  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &InterfaceKey) != ERROR_SUCCESS)
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
679  if (!(Flags & GAA_FLAG_SKIP_UNICAST))
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 
750 Success:
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 
758 Error:
759  ERR("Failed! Status 0x%08x\n", Status);
760  *pOutBufLen = 0;
761  HeapFree(GetProcessHeap(), 0, InterfacesList);
762  NtClose(TcpFile);
764 }
765 #endif
struct sockaddr_in * LPSOCKADDR_IN
Definition: winsock.h:489
TDIEntityID toi_entity
Definition: tdiinfo.h:74
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
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:4023
ULONG ipsi_numaddr
Definition: tcpioctl.h:156
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
ULONG toi_class
Definition: tdiinfo.h:75
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
struct _TDIEntityID TDIEntityID
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG _In_opt_ PVOID Data
Definition: wdfdevice.h:4527
char CHAR
Definition: xmlstorage.h:175
TDIEntityInfo * EntityList
Definition: main.c:23
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3331
#define snprintf
Definition: wintirpc.h:48
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define ZeroMemory
Definition: winbase.h:1648
unsigned short Length
Definition: sprintf.c:451
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)
uint16_t * PWCHAR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
#define DWORD
Definition: nt_native.h:44
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
static int Family
Definition: ping.c:62
#define FALSE
Definition: types.h:117
#define GAA_FLAG_SKIP_FRIENDLY_NAME
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FIXME(fmt,...)
Definition: debug.h:111
ULONG toi_id
Definition: tdiinfo.h:77
#define AF_INET6
Definition: winsock.h:369
#define _Out_
Definition: no_sal2.h:160
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
void * PVOID
Definition: retypes.h:9
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
#define AF_UNSPEC
Definition: winsock.h:344
WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi)
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
#define PCHAR
Definition: match.c:90
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:246
Status
Definition: gdiplustypes.h:24
ULONG tei_entity
Definition: tdiinfo.h:31
#define TRACE(s)
Definition: solgame.cpp:4
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define IP_MIB_STATS_ID
Definition: afd.h:35
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
#define INFO_CLASS_GENERIC
Definition: tdiinfo.h:64
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define ERROR_NO_DATA
Definition: winerror.h:284
ULONG tei_instance
Definition: tdiinfo.h:32
#define WINAPI
Definition: msvc.h:6
#define CopyMemory
Definition: winbase.h:1646
Type
Definition: Type.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL Error
Definition: chkdsk.c:66
#define IF_ENTITY
Definition: tdiinfo.h:47
#define _Inout_
Definition: no_sal2.h:162
#define CO_NL_ENTITY
Definition: tdiinfo.h:44
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
ULONG iae_mask
Definition: tcpioctl.h:164
#define CL_NL_ENTITY
Definition: tdiinfo.h:42
static const WCHAR L[]
Definition: oid.c:1250
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 memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define IOCTL_TCP_QUERY_INFORMATION_EX
Definition: tditest.h:110
unsigned char BYTE
Definition: xxhash.c:193
#define ERR(fmt,...)
Definition: debug.h:110
#define _In_
Definition: no_sal2.h:158
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
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:361
LIST_ENTRY Entries[5]
Definition: ExDoubleList.c:8
#define ENTITY_LIST_ID
Definition: tdiinfo.h:38
unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask)
Definition: intrin_arm.h:180
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned int * PULONG
Definition: retypes.h:1
#define MIN_SIZE
Definition: mem.c:169
#define NULL
Definition: types.h:112
#define GAA_FLAG_SKIP_UNICAST
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define INFO_TYPE_PROVIDER
Definition: tdiinfo.h:69
NTSTATUS openTcpFile(PHANDLE tcpFile, ACCESS_MASK DesiredAccess)
Definition: handle.c:12
#define MAX_ADAPTER_DESCRIPTION_LENGTH
Definition: iinfo.c:16
uint32_t * LPDWORD
Definition: typedefs.h:59
LSTATUS EnumNameServers(HKEY RegHandle, LPWSTR Interface, PVOID Data, EnumNameServersFunc cb)
unsigned int ULONG
Definition: retypes.h:1
#define AF_INET
Definition: tcpip.h:117
#define IP_MIB_ADDRTABLE_ENTRY_ID
Definition: afd.h:36
#define GENERIC_ENTITY
Definition: tdiinfo.h:37
#define REG_DWORD
Definition: sdbapi.c:596
#define CHAR(Char)
static PIP_ADAPTER_ADDRESSES
Definition: iphlpapi.c:76
#define HeapFree(x, y, z)
Definition: compat.h:594
struct sockaddr SOCKADDR
Definition: winsock.h:484
base of all file and directory entries
Definition: entries.h:82
ULONG toi_type
Definition: tdiinfo.h:76
#define BufferSize
Definition: mmc.h:75
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define INFO_CLASS_PROTOCOL
Definition: tdiinfo.h:65
#define REG_SZ
Definition: layer.c:22
struct sockaddr * LPSOCKADDR
Definition: winsock.h:486
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)