- Removed some obsolete headers.
[reactos.git] / reactos / lib / iphlpapi / iphlpapi.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winsock 2 IP Helper API DLL
4 * FILE: iphlpapi.c
5 * PURPOSE: DLL entry
6 * PROGRAMMERS: Robert Dickenson (robd@reactos.org)
7 * REVISIONS:
8 * RDD August 18, 2002 Created
9 */
10
11 #include <stdio.h>
12 #include <windows.h>
13 #include <tchar.h>
14 #include <time.h>
15 #include <stdlib.h>
16
17 #include <winsock2.h>
18 #include <ws2tcpip.h>
19 #include <iptypes.h>
20 #include <ipexport.h>
21 #include <iphlpapi.h>
22 #include <icmpapi.h>
23
24 #include "ipprivate.h"
25 #include "ipregprivate.h"
26 #include "debug.h"
27 //#include "trace.h"
28
29 #ifdef __GNUC__
30 #define EXPORT STDCALL
31 #else
32 #define EXPORT CALLBACK
33 #endif
34
35 #ifdef DBG
36
37 /* See debug.h for debug/trace constants */
38 DWORD DebugTraceLevel = MAX_TRACE;
39
40 #endif /* DBG */
41
42 /* To make the linker happy */
43 //VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
44
45
46 WINBOOL
47 EXPORT
48 DllMain(HANDLE hInstDll,
49 ULONG dwReason,
50 PVOID Reserved)
51 {
52 //WSH_DbgPrint(MIN_TRACE, ("DllMain of iphlpapi.dll\n"));
53
54 switch (dwReason) {
55 case DLL_PROCESS_ATTACH:
56 /* Don't need thread attach notifications
57 so disable them to improve performance */
58 DisableThreadLibraryCalls(hInstDll);
59 break;
60
61 case DLL_THREAD_ATTACH:
62 break;
63
64 case DLL_THREAD_DETACH:
65 break;
66
67 case DLL_PROCESS_DETACH:
68 break;
69 }
70 return TRUE;
71 }
72
73
74 /*
75 * @unimplemented
76 */
77 DWORD
78 STDCALL
79 AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex, PULONG NTEContext, PULONG NTEInstance)
80 {
81 UNIMPLEMENTED
82 return 0L;
83 }
84
85
86 /*
87 * @unimplemented
88 */
89 DWORD
90 STDCALL
91 SetIpNetEntry(PMIB_IPNETROW pArpEntry)
92 {
93 UNIMPLEMENTED
94 return 0L;
95 }
96
97
98 /*
99 * @unimplemented
100 */
101 DWORD
102 STDCALL
103 CreateIpForwardEntry(PMIB_IPFORWARDROW pRoute)
104 {
105 UNIMPLEMENTED
106 return 0L;
107 }
108
109
110 /*
111 * @unimplemented
112 */
113 DWORD
114 STDCALL
115 GetAdapterIndex(LPWSTR AdapterName, PULONG IfIndex)
116 {
117 return 0;
118 }
119
120
121 /*
122 * @unimplemented
123 */
124 DWORD
125 STDCALL
126 GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
127 {
128 LONG lErr;
129 DWORD dwSize;
130 DWORD dwIndex;
131 BYTE* pNextMemFree = (BYTE*) pAdapterInfo;
132 ULONG uUsedMemory = 0;
133 PIP_ADAPTER_INFO pPrevAdapter = NULL;
134 PIP_ADAPTER_INFO pCurrentAdapter = NULL;
135 HKEY hAdapters;
136 HKEY hAdapter;
137 HKEY hIpConfig;
138 wchar_t* strAdapter;
139 wchar_t* strTemp1;
140 wchar_t* strTemp2;
141 DWORD dwAdapterLen;
142 char strTemp[MAX_ADAPTER_NAME_LENGTH + 4];
143
144 if(pAdapterInfo == NULL && pOutBufLen == NULL)
145 return ERROR_INVALID_PARAMETER;
146 ZeroMemory(pAdapterInfo, *pOutBufLen);
147
148 lErr = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
149 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters", 0, KEY_READ, &hAdapters);
150 if(lErr != ERROR_SUCCESS)
151 return lErr;
152
153 // Determine the size of the largest name of any adapter and the number of adapters.
154 lErr = RegQueryInfoKeyW(hAdapters, NULL, NULL, NULL, NULL, &dwAdapterLen, NULL, NULL, NULL, NULL, NULL, NULL);
155 if(lErr != ERROR_SUCCESS)
156 {
157 RegCloseKey(hAdapters);
158 return lErr;
159 }
160 dwAdapterLen++; // RegQueryInfoKeyW return value does not include terminating null.
161
162 strAdapter = (wchar_t*) malloc(dwAdapterLen * sizeof(wchar_t));
163
164 // Enumerate all adapters in SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Adapters.
165 for(dwIndex = 0; ; dwIndex++)
166 {
167 dwSize = dwAdapterLen; // Reset size of the strAdapterLen buffer.
168 lErr = RegEnumKeyExW(hAdapters, dwIndex, strAdapter, &dwSize, NULL, NULL, NULL, NULL);
169 if(lErr == ERROR_NO_MORE_ITEMS)
170 break;
171
172 // TODO Skip NdisWanIP???
173 if(wcsstr(strAdapter, L"NdisWanIp") != 0)
174 continue;
175
176 lErr = RegOpenKeyExW(hAdapters, strAdapter, 0, KEY_READ, &hAdapter);
177 if(lErr != ERROR_SUCCESS)
178 continue;
179
180 // Read the IpConfig value.
181 lErr = RegQueryValueExW(hAdapter, L"IpConfig", NULL, NULL, NULL, &dwSize);
182 if(lErr != ERROR_SUCCESS)
183 continue;
184
185 strTemp1 = (wchar_t*) malloc(dwSize);
186 strTemp2 = (wchar_t*) malloc(dwSize + 35 * sizeof(wchar_t));
187 lErr = RegQueryValueExW(hAdapter, L"IpConfig", NULL, NULL, (BYTE*) strTemp1, &dwSize);
188 if(lErr != ERROR_SUCCESS)
189 {
190 free(strTemp1);
191 free(strTemp2);
192 continue;
193 }
194 swprintf(strTemp2, L"SYSTEM\\CurrentControlSet\\Services\\%s", strTemp1);
195
196 // Open the IpConfig key.
197 lErr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, strTemp2, 0, KEY_READ, &hIpConfig);
198 if(lErr != ERROR_SUCCESS)
199 {
200 free(strTemp1);
201 free(strTemp2);
202 continue;
203 }
204 free((void*) strTemp1);
205 free((void*) strTemp2);
206
207
208 // Fill IP_ADAPTER_INFO block.
209 pCurrentAdapter = (IP_ADAPTER_INFO*) pNextMemFree;
210 pNextMemFree += sizeof(IP_ADAPTER_INFO);
211 uUsedMemory += sizeof(IP_ADAPTER_INFO);
212 if(uUsedMemory > *pOutBufLen)
213 return ERROR_BUFFER_OVERFLOW; // TODO return the needed size
214
215 // struct _IP_ADAPTER_INFO* Next
216 if(pPrevAdapter != NULL)
217 pPrevAdapter->Next = pCurrentAdapter;
218 // TODO DWORD ComboIndex
219 // char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]
220 wcstombs(strTemp, strAdapter, MAX_ADAPTER_NAME_LENGTH + 4);
221 strcpy(pCurrentAdapter->AdapterName, strTemp);
222 // TODO char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]
223 // TODO UINT AddressLength
224 // TODO BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH]
225 // TODO DWORD Index
226 // TODO UINT Type
227 // TODO UINT DhcpEnabled
228 // TODO PIP_ADDR_STRING CurrentIpAddress
229 // IP_ADDR_STRING IpAddressList
230 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"IPAddress", NULL, NULL, (BYTE*) &pCurrentAdapter->IpAddressList.IpAddress, &dwSize);
231 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"SubnetMask", NULL, NULL, (BYTE*) &pCurrentAdapter->IpAddressList.IpMask, &dwSize);
232 if(strstr(pCurrentAdapter->IpAddressList.IpAddress.String, "0.0.0.0") != 0)
233 {
234 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"DhcpIPAddress", NULL, NULL, (BYTE*) &pCurrentAdapter->IpAddressList.IpAddress, &dwSize);
235 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"DhcpSubnetMask", NULL, NULL, (BYTE*) &pCurrentAdapter->IpAddressList.IpMask, &dwSize);
236 }
237 // TODO IP_ADDR_STRING GatewayList
238 // IP_ADDR_STRING DhcpServer
239 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"DhcpServer", NULL, NULL, (BYTE*) &pCurrentAdapter->DhcpServer.IpAddress, &dwSize);
240 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"DhcpSubnetMask", NULL, NULL, (BYTE*) &pCurrentAdapter->DhcpServer.IpMask, &dwSize);
241 // TODO BOOL HaveWins
242 // TODO IP_ADDR_STRING PrimaryWinsServer
243 // TODO IP_ADDR_STRING SecondaryWinsServer
244 // TODO time_t LeaseObtained
245 // TODO time_t LeaseExpires
246
247 pPrevAdapter = pCurrentAdapter;
248 RegCloseKey(hAdapter);
249 RegCloseKey(hIpConfig);
250 }
251
252 // Cleanup
253 free(strAdapter);
254 RegCloseKey(hAdapters);
255
256 return ERROR_SUCCESS;
257 }
258
259
260 ////////////////////////////////////////////////////////////////////////////////
261
262 /*
263 * @implemented
264 */
265 DWORD
266 STDCALL
267 GetNumberOfInterfaces(OUT PDWORD pdwNumIf)
268 {
269 DWORD result = NO_ERROR;
270 HKEY hKey;
271 LONG errCode;
272 int i = 0;
273
274 if (pdwNumIf == NULL) return ERROR_INVALID_PARAMETER;
275 *pdwNumIf = 0;
276 errCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage", 0, KEY_READ, &hKey);
277 if (errCode == ERROR_SUCCESS) {
278 DWORD dwSize;
279 errCode = RegQueryValueExW(hKey, L"Bind", NULL, NULL, NULL, &dwSize);
280 if (errCode == ERROR_SUCCESS) {
281 wchar_t* pData = (wchar_t*)malloc(dwSize * sizeof(wchar_t));
282 errCode = RegQueryValueExW(hKey, L"Bind", NULL, NULL, (LPBYTE)pData, &dwSize);
283 if (errCode == ERROR_SUCCESS) {
284 wchar_t* pStr = pData;
285 for (i = 0; *pStr != L'\0'; i++) {
286 pStr = pStr + wcslen(pStr) + 1; // next string
287 }
288 }
289 free(pData);
290 }
291 RegCloseKey(hKey);
292 *pdwNumIf = i;
293 } else {
294 result = errCode;
295 }
296 return result;
297 }
298
299
300 /*
301 * @implemented
302 */
303 DWORD
304 STDCALL
305 GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG pOutBufLen)
306 {
307 DWORD result = ERROR_SUCCESS;
308 DWORD dwSize;
309 DWORD dwOutBufLen;
310 DWORD dwNumIf;
311 HKEY hKey;
312 LONG errCode;
313 int i = 0;
314
315 if ((errCode = GetNumberOfInterfaces(&dwNumIf)) != NO_ERROR) {
316 _tprintf(_T("GetInterfaceInfo() failed with code 0x%08X - Use FormatMessage to obtain the message string for the returned error\n"), (int)errCode);
317 return errCode;
318 }
319 if (dwNumIf == 0) return ERROR_NO_DATA; // No adapter information exists for the local computer
320 if (pOutBufLen == NULL) return ERROR_INVALID_PARAMETER;
321 dwOutBufLen = sizeof(IP_INTERFACE_INFO) + dwNumIf * sizeof(IP_ADAPTER_INDEX_MAP);
322 if (*pOutBufLen < dwOutBufLen || pIfTable == NULL) {
323 *pOutBufLen = dwOutBufLen;
324 return ERROR_INSUFFICIENT_BUFFER;
325 }
326 memset(pIfTable, 0, dwOutBufLen);
327 pIfTable->NumAdapters = dwNumIf - 1;
328 errCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage", 0, KEY_READ, &hKey);
329 if (errCode == ERROR_SUCCESS) {
330 errCode = RegQueryValueExW(hKey, L"Bind", NULL, NULL, NULL, &dwSize);
331 if (errCode == ERROR_SUCCESS) {
332 wchar_t* pData = (wchar_t*)malloc(dwSize * sizeof(wchar_t));
333 errCode = RegQueryValueExW(hKey, L"Bind", NULL, NULL, (LPBYTE)pData, &dwSize);
334 if (errCode == ERROR_SUCCESS) {
335 wchar_t* pStr = pData;
336 for (i = 0; i < pIfTable->NumAdapters && *pStr != L'\0'; pStr += wcslen(pStr) + 1) {
337 if (wcsstr(pStr, L"\\Device\\NdisWanIp") == 0) {
338 wcsncpy(pIfTable->Adapter[i].Name, pStr, MAX_ADAPTER_NAME);
339 pIfTable->Adapter[i].Index = i;
340 i++;
341 }
342 }
343
344 }
345 free(pData);
346 }
347 RegCloseKey(hKey);
348 } else {
349 result = errCode;
350 }
351 return result;
352 }
353
354 /*
355 * EnumNameServers
356 */
357
358 static void EnumNameServers( HANDLE RegHandle, PWCHAR Interface,
359 PVOID Data, EnumNameServersFunc cb ) {
360 PWCHAR NameServerString = QueryRegistryValueString(RegHandle, L"NameServer");
361 /* Now, count the non-empty comma separated */
362 if (NameServerString) {
363 DWORD ch;
364 DWORD LastNameStart = 0;
365 for (ch = 0; NameServerString[ch]; ch++) {
366 if (NameServerString[ch] == ',') {
367 if (ch - LastNameStart > 0) { /* Skip empty entries */
368 PWCHAR NameServer = malloc(sizeof(WCHAR) * (ch - LastNameStart + 1));
369 if (NameServer) {
370 memcpy(NameServer,NameServerString + LastNameStart,
371 (ch - LastNameStart) * sizeof(WCHAR));
372 NameServer[ch - LastNameStart] = 0;
373 cb( Interface, NameServer, Data );
374 free(NameServer);
375 }
376 }
377 LastNameStart = ch + 1; /* The first one after the comma */
378 }
379 }
380 if (ch - LastNameStart > 0) { /* A last name? */
381 PWCHAR NameServer = malloc(sizeof(WCHAR) * (ch - LastNameStart + 1));
382 memcpy(NameServer,NameServerString + LastNameStart,
383 (ch - LastNameStart) * sizeof(WCHAR));
384 NameServer[ch - LastNameStart] = 0;
385 cb( Interface, NameServer, Data );
386 free(NameServer);
387 }
388 ConsumeRegValueString(NameServerString);
389 }
390 }
391
392 /*
393 * EnumInterfaces
394 *
395 * Call the enumeration function for each name server.
396 */
397
398 static void EnumInterfaces( PVOID Data, EnumInterfacesFunc cb ) {
399 HKEY RegHandle;
400 HKEY ChildKeyHandle = 0;
401 PWCHAR RegKeyToEnumerate =
402 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
403 PWCHAR ChildKeyName = 0;
404 DWORD CurrentInterface;
405
406 if (OpenChildKeyRead(HKEY_LOCAL_MACHINE,RegKeyToEnumerate,&RegHandle)) {
407 return;
408 }
409
410 for (CurrentInterface = 0; TRUE; CurrentInterface++) {
411 ChildKeyName = GetNthChildKeyName( RegHandle, CurrentInterface );
412 if (!ChildKeyName) break;
413 if (OpenChildKeyRead(RegHandle,ChildKeyName,
414 &ChildKeyHandle) == 0) {
415 cb( ChildKeyHandle, ChildKeyName, Data );
416 RegCloseKey( ChildKeyHandle );
417 }
418 ConsumeChildKeyName( ChildKeyName );
419 }
420 }
421
422 static void CreateNameServerListEnumNamesFuncCount( PWCHAR Interface,
423 PWCHAR Server,
424 PVOID _Data ) {
425 PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
426 Data->NumServers++;
427 }
428
429 static void CreateNameServerListEnumIfFuncCount( HANDLE RegHandle,
430 PWCHAR InterfaceName,
431 PVOID _Data ) {
432 PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
433 EnumNameServers(RegHandle,InterfaceName,Data,
434 CreateNameServerListEnumNamesFuncCount);
435 }
436
437 static void CreateNameServerListEnumNamesFunc( PWCHAR Interface,
438 PWCHAR Server,
439 PVOID _Data ) {
440 PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
441 wcstombs(Data->AddrString[Data->CurrentName].IpAddress.String,
442 Server,
443 sizeof(IP_ADDRESS_STRING));
444 strcpy(Data->AddrString[Data->CurrentName].IpMask.String,"0.0.0.0");
445 Data->AddrString[Data->CurrentName].Context = 0;
446 if (Data->CurrentName < Data->NumServers - 1) {
447 Data->AddrString[Data->CurrentName].Next =
448 &Data->AddrString[Data->CurrentName+1];
449 } else
450 Data->AddrString[Data->CurrentName].Next = 0;
451
452 Data->CurrentName++;
453 }
454
455 static void CreateNameServerListEnumIfFunc( HANDLE RegHandle,
456 PWCHAR InterfaceName,
457 PVOID _Data ) {
458 PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
459 EnumNameServers(RegHandle,InterfaceName,Data,
460 CreateNameServerListEnumNamesFunc);
461 }
462
463 static int CountNameServers( PNAME_SERVER_LIST_PRIVATE PrivateData ) {
464 EnumInterfaces(PrivateData,CreateNameServerListEnumIfFuncCount);
465 return PrivateData->NumServers;
466 }
467
468 static void MakeNameServerList( PNAME_SERVER_LIST_PRIVATE PrivateData ) {
469 EnumInterfaces(PrivateData,CreateNameServerListEnumIfFunc);
470 }
471
472 /*
473 * @implemented
474 */
475 DWORD
476 STDCALL
477 GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen)
478 {
479 DWORD result = ERROR_SUCCESS;
480 DWORD dwSize;
481 HKEY hKey;
482 LONG errCode;
483 NAME_SERVER_LIST_PRIVATE PrivateNSEnum = { 0 };
484
485 CountNameServers( &PrivateNSEnum );
486
487 if (pOutBufLen == NULL) return ERROR_INVALID_PARAMETER;
488
489 if (*pOutBufLen < sizeof(FIXED_INFO))
490 {
491 *pOutBufLen = sizeof(FIXED_INFO) +
492 ((PrivateNSEnum.NumServers - 1) * sizeof(IP_ADDR_STRING));
493 return ERROR_BUFFER_OVERFLOW;
494 }
495 if (pFixedInfo == NULL) return ERROR_INVALID_PARAMETER;
496 memset(pFixedInfo, 0, sizeof(FIXED_INFO));
497
498 errCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
499 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_READ, &hKey);
500 if (errCode == ERROR_SUCCESS)
501 {
502 dwSize = sizeof(pFixedInfo->HostName);
503 errCode = RegQueryValueExA(hKey, "Hostname", NULL, NULL, (LPBYTE)&pFixedInfo->HostName, &dwSize);
504 dwSize = sizeof(pFixedInfo->DomainName);
505 errCode = RegQueryValueExA(hKey, "Domain", NULL, NULL, (LPBYTE)&pFixedInfo->DomainName, &dwSize);
506 if (errCode != ERROR_SUCCESS)
507 {
508 dwSize = sizeof(pFixedInfo->DomainName);
509 errCode = RegQueryValueExA(hKey, "DhcpDomain", NULL, NULL, (LPBYTE)&pFixedInfo->DomainName, &dwSize);
510 }
511 dwSize = sizeof(pFixedInfo->EnableRouting);
512 errCode = RegQueryValueExW(hKey, L"IPEnableRouter", NULL, NULL, (LPBYTE)&pFixedInfo->EnableRouting, &dwSize);
513 RegCloseKey(hKey);
514
515 /* Get the number of name servers */
516 PIP_ADDR_STRING AddressAfterFixedInfo;
517 AddressAfterFixedInfo = (PIP_ADDR_STRING)&pFixedInfo[1];
518 DWORD NumberOfServersAllowed = 0, CurrentServer = 0;
519
520 while( &AddressAfterFixedInfo[NumberOfServersAllowed] <
521 (PIP_ADDR_STRING)(((PCHAR)pFixedInfo) + *pOutBufLen) )
522 NumberOfServersAllowed++;
523
524 NumberOfServersAllowed++; /* One struct is built in */
525
526 /* Since the first part of the struct is built in, we have to do some
527 fiddling */
528 PrivateNSEnum.AddrString =
529 malloc(NumberOfServersAllowed * sizeof(IP_ADDR_STRING));
530 if (PrivateNSEnum.NumServers > NumberOfServersAllowed)
531 PrivateNSEnum.NumServers = NumberOfServersAllowed;
532 MakeNameServerList( &PrivateNSEnum );
533
534 /* Now we have the name servers, place the first one in the struct,
535 and follow it with the rest */
536 if (!PrivateNSEnum.NumServers)
537 RtlZeroMemory( &pFixedInfo->DnsServerList, sizeof(IP_ADDR_STRING) );
538 else
539 memcpy( &pFixedInfo->DnsServerList, &PrivateNSEnum.AddrString[0],
540 sizeof(PrivateNSEnum.AddrString[0]) );
541 pFixedInfo->CurrentDnsServer = &pFixedInfo->DnsServerList;
542 if (PrivateNSEnum.NumServers > 1)
543 memcpy( &AddressAfterFixedInfo[0],
544 &PrivateNSEnum.AddrString[1],
545 sizeof(IP_ADDR_STRING) * (PrivateNSEnum.NumServers - 1) );
546 else
547 pFixedInfo->CurrentDnsServer->Next = 0;
548
549 for( CurrentServer = 0;
550 CurrentServer < PrivateNSEnum.NumServers - 1;
551 CurrentServer++ ) {
552 pFixedInfo->CurrentDnsServer->Next = &AddressAfterFixedInfo[CurrentServer];
553 pFixedInfo->CurrentDnsServer = &AddressAfterFixedInfo[CurrentServer];
554 pFixedInfo->CurrentDnsServer->Next = 0;
555 }
556 /* For now, set the first server as the current server */
557 pFixedInfo->CurrentDnsServer = &pFixedInfo->DnsServerList;
558 free(PrivateNSEnum.AddrString);
559 }
560 else
561 {
562 result = ERROR_NO_DATA; // No adapter information exists for the local computer
563 }
564
565 errCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters", 0, KEY_READ, &hKey);
566 if (errCode == ERROR_SUCCESS)
567 {
568 dwSize = sizeof(pFixedInfo->ScopeId);
569 errCode = RegQueryValueExA(hKey, "ScopeId", NULL, NULL, (LPBYTE)&pFixedInfo->ScopeId, &dwSize);
570 if (errCode != ERROR_SUCCESS)
571 {
572 dwSize = sizeof(pFixedInfo->ScopeId);
573 errCode = RegQueryValueExA(hKey, "DhcpScopeId", NULL, NULL, (LPBYTE)&pFixedInfo->ScopeId, &dwSize);
574 }
575 dwSize = sizeof(pFixedInfo->NodeType);
576 errCode = RegQueryValueExW(hKey, L"NodeType", NULL, NULL, (LPBYTE)&pFixedInfo->NodeType, &dwSize);
577 if (errCode != ERROR_SUCCESS)
578 {
579 dwSize = sizeof(pFixedInfo->NodeType);
580 errCode = RegQueryValueExA(hKey, "DhcpNodeType", NULL, NULL, (LPBYTE)&pFixedInfo->NodeType, &dwSize);
581 }
582 dwSize = sizeof(pFixedInfo->EnableProxy);
583 errCode = RegQueryValueExW(hKey, L"EnableProxy", NULL, NULL, (LPBYTE)&pFixedInfo->EnableProxy, &dwSize);
584 dwSize = sizeof(pFixedInfo->EnableDns);
585 errCode = RegQueryValueExW(hKey, L"EnableDNS", NULL, NULL, (LPBYTE)&pFixedInfo->EnableDns, &dwSize);
586 RegCloseKey(hKey);
587 }
588 else
589 {
590 result = ERROR_NO_DATA; // No adapter information exists for the local computer
591 }
592
593 return result;
594 }
595
596
597 /*
598 * @unimplemented
599 */
600 DWORD
601 STDCALL
602 GetTcpStatistics(PMIB_TCPSTATS pStats)
603 {
604 DWORD result = NO_ERROR;
605
606 result = ERROR_NO_DATA;
607
608 return result;
609 }
610
611
612 /*
613 * @unimplemented
614 */
615 DWORD
616 STDCALL
617 GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, WINBOOL bOrder)
618 {
619 DWORD result = NO_ERROR;
620
621 result = ERROR_NO_DATA;
622
623 return result;
624 }
625
626
627 /*
628 * @unimplemented
629 */
630 DWORD
631 STDCALL
632 GetUdpStatistics(PMIB_UDPSTATS pStats)
633 {
634 DWORD result = NO_ERROR;
635
636 result = ERROR_NO_DATA;
637
638 return result;
639 }
640
641
642 /*
643 * @unimplemented
644 */
645 DWORD
646 STDCALL
647 GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, WINBOOL bOrder)
648 {
649 DWORD result = NO_ERROR;
650
651 result = ERROR_NO_DATA;
652
653 return result;
654 }
655
656
657 /*
658 * @unimplemented
659 */
660 DWORD
661 STDCALL
662 FlushIpNetTable(DWORD dwIfIndex)
663 {
664 DWORD result = NO_ERROR;
665
666 return result;
667 }
668
669 /******************************************************************
670 * GetIfEntry (IPHLPAPI.@)
671 *
672 *
673 * PARAMS
674 *
675 * pIfRow [In/Out]
676 *
677 * RETURNS
678 *
679 * DWORD
680 *
681 */
682 DWORD
683 STDCALL
684 GetIfEntry(PMIB_IFROW pIfRow)
685 {
686 DWORD result = NO_ERROR;
687
688 return result;
689 }
690
691
692 /******************************************************************
693 * GetIfTable (IPHLPAPI.@)
694 *
695 *
696 * PARAMS
697 *
698 * pIfTable [In/Out]
699 * pdwSize [In/Out]
700 * bOrder [In]
701 *
702 * RETURNS
703 *
704 * DWORD
705 *
706 */
707 DWORD
708 STDCALL
709 GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, WINBOOL bOrder)
710 {
711 DWORD result = NO_ERROR;
712
713 return result;
714 }
715
716 /*
717 * @unimplemented
718 */
719 DWORD STDCALL GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize,
720 WINBOOL bOrder)
721 {
722 UNIMPLEMENTED
723 return 0L;
724 }
725
726 /*
727 * @unimplemented
728 */
729 DWORD STDCALL GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize,
730 WINBOOL bOrder)
731 {
732 UNIMPLEMENTED
733 return 0L;
734 }
735
736 /*
737 * @unimplemented
738 */
739 DWORD STDCALL GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable,
740 PULONG pdwSize, WINBOOL bOrder)
741 {
742 UNIMPLEMENTED
743 return 0L;
744 }
745
746 /*
747 * @unimplemented
748 */
749 DWORD STDCALL GetIpStatistics(PMIB_IPSTATS pStats)
750 {
751 UNIMPLEMENTED
752 return 0L;
753 }
754
755 /*
756 * @unimplemented
757 */
758 DWORD STDCALL GetIpStatisticsEx(PMIB_IPSTATS pStats, DWORD dwFamily)
759 {
760 UNIMPLEMENTED
761 return 0L;
762 }
763
764 /*
765 * @unimplemented
766 */
767 DWORD STDCALL GetIcmpStatistics(PMIB_ICMP pStats)
768 {
769 UNIMPLEMENTED
770 return 0L;
771 }
772
773 /*
774 * @unimplemented
775 */
776 DWORD STDCALL GetTcpStatisticsEx(PMIB_TCPSTATS pStats, DWORD dwFamily)
777 {
778 UNIMPLEMENTED
779 return 0L;
780 }
781
782 /*
783 * @unimplemented
784 */
785 DWORD STDCALL GetUdpStatisticsEx(PMIB_UDPSTATS pStats, DWORD dwFamily)
786 {
787 UNIMPLEMENTED
788 return 0L;
789 }
790
791 /*
792 * @unimplemented
793 */
794 DWORD STDCALL SetIfEntry(PMIB_IFROW pIfRow)
795 {
796 UNIMPLEMENTED
797 return 0L;
798 }
799
800 /*
801 * @unimplemented
802 */
803 DWORD STDCALL SetIpForwardEntry(PMIB_IPFORWARDROW pRoute)
804 {
805 UNIMPLEMENTED
806 return 0L;
807 }
808
809 /*
810 * @unimplemented
811 */
812 DWORD STDCALL DeleteIpForwardEntry(PMIB_IPFORWARDROW pRoute)
813 {
814 UNIMPLEMENTED
815 return 0L;
816 }
817
818 /*
819 * @unimplemented
820 */
821 DWORD STDCALL SetIpStatistics(PMIB_IPSTATS pIpStats)
822 {
823 UNIMPLEMENTED
824 return 0L;
825 }
826
827 /*
828 * @unimplemented
829 */
830 DWORD STDCALL SetIpTTL(UINT nTTL)
831 {
832 UNIMPLEMENTED
833 return 0L;
834 }
835
836 /*
837 * @unimplemented
838 */
839 DWORD STDCALL CreateIpNetEntry(PMIB_IPNETROW pArpEntry)
840 {
841 UNIMPLEMENTED
842 return 0L;
843 }
844
845 /*
846 * @unimplemented
847 */
848 DWORD STDCALL DeleteIpNetEntry(PMIB_IPNETROW pArpEntry)
849 {
850 UNIMPLEMENTED
851 return 0L;
852 }
853
854 /*
855 * @unimplemented
856 */
857 DWORD STDCALL CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask,
858 DWORD dwIfIndex)
859 {
860 UNIMPLEMENTED
861 return 0L;
862 }
863
864 /*
865 * @unimplemented
866 */
867 DWORD STDCALL DeleteProxyArpEntry(DWORD dwAddress, DWORD dwMask,
868 DWORD dwIfIndex)
869 {
870 UNIMPLEMENTED
871 return 0L;
872 }
873
874 /*
875 * @unimplemented
876 */
877 DWORD STDCALL SetTcpEntry(PMIB_TCPROW pTcpRow)
878 {
879 UNIMPLEMENTED
880 return 0L;
881 }
882
883 /*
884 * @unimplemented
885 */
886 DWORD STDCALL GetUniDirectionalAdapterInfo(
887 PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo, PULONG dwOutBufLen)
888 {
889 UNIMPLEMENTED
890 return 0L;
891 }
892
893 /*
894 * @unimplemented
895 */
896 DWORD STDCALL GetBestInterface(IPAddr dwDestAddr, PDWORD pdwBestIfIndex)
897 {
898 UNIMPLEMENTED
899 return 0L;
900 }
901
902 /*
903 * @unimplemented
904 */
905 DWORD STDCALL GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr,
906 PMIB_IPFORWARDROW pBestRoute)
907 {
908 UNIMPLEMENTED
909 return 0L;
910 }
911
912 /*
913 * @unimplemented
914 */
915 DWORD STDCALL NotifyAddrChange(PHANDLE Handle, LPOVERLAPPED overlapped)
916 {
917 UNIMPLEMENTED
918 return 0L;
919 }
920
921 /*
922 * @unimplemented
923 */
924 DWORD STDCALL NotifyRouteChange(PHANDLE Handle, LPOVERLAPPED overlapped)
925 {
926 UNIMPLEMENTED
927 return 0L;
928 }
929
930 /*
931 * @unimplemented
932 */
933 DWORD STDCALL DeleteIPAddress(ULONG NTEContext)
934 {
935 UNIMPLEMENTED
936 return 0L;
937 }
938
939 /*
940 * @unimplemented
941 */
942 DWORD STDCALL GetPerAdapterInfo(ULONG IfIndex,
943 PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen)
944 {
945 UNIMPLEMENTED
946 return 0L;
947 }
948
949 /*
950 * @unimplemented
951 */
952 DWORD STDCALL IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
953 {
954 UNIMPLEMENTED
955 return 0L;
956 }
957
958 /*
959 * @unimplemented
960 */
961 DWORD STDCALL IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
962 {
963 UNIMPLEMENTED
964 return 0L;
965 }
966
967 /*
968 * @unimplemented
969 */
970 DWORD STDCALL SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr,
971 PULONG PhyAddrLen)
972 {
973 UNIMPLEMENTED
974 return 0L;
975 }
976
977 /*
978 * @unimplemented
979 */
980 WINBOOL STDCALL GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount,
981 ULONG MaxHops, PULONG RTT)
982 {
983 UNIMPLEMENTED
984 return 0L;
985 }
986
987 /*
988 * @unimplemented
989 */
990 DWORD STDCALL GetFriendlyIfIndex(DWORD IfIndex)
991 {
992 UNIMPLEMENTED
993 return 0L;
994 }
995
996 /*
997 * @unimplemented
998 */
999 DWORD STDCALL EnableRouter(HANDLE* pHandle, OVERLAPPED* pOverlapped)
1000 {
1001 UNIMPLEMENTED
1002 return 0L;
1003 }
1004
1005 /*
1006 * @unimplemented
1007 */
1008 DWORD STDCALL UnenableRouter(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount)
1009 {
1010 UNIMPLEMENTED
1011 return 0L;
1012 }
1013
1014 /*
1015 * @unimplemented
1016 */
1017 DWORD STDCALL GetIcmpStatisticsEx(PMIB_ICMP_EX pStats,DWORD dwFamily)
1018 {
1019 UNIMPLEMENTED
1020 return 0L;
1021 }
1022
1023 /*
1024 * @unimplemented
1025 */
1026 DWORD STDCALL NhpAllocateAndGetInterfaceInfoFromStack(IP_INTERFACE_NAME_INFO **ppTable,PDWORD pdwCount,WINBOOL bOrder,HANDLE hHeap,DWORD dwFlags)
1027 {
1028 UNIMPLEMENTED
1029 return 0L;
1030 }
1031
1032 /*
1033 * @unimplemented
1034 */
1035 DWORD STDCALL GetBestInterfaceEx(struct sockaddr *pDestAddr,PDWORD pdwBestIfIndex)
1036 {
1037 UNIMPLEMENTED
1038 return 0L;
1039 }
1040
1041 /*
1042 * @unimplemented
1043 */
1044 WINBOOL STDCALL CancelIPChangeNotify(LPOVERLAPPED notifyOverlapped)
1045 {
1046 UNIMPLEMENTED
1047 return 0L;
1048 }
1049
1050 /*
1051 * @unimplemented
1052 */
1053 PIP_ADAPTER_ORDER_MAP STDCALL GetAdapterOrderMap(VOID)
1054 {
1055 UNIMPLEMENTED
1056 return 0L;
1057 }
1058
1059 /*
1060 * @unimplemented
1061 */
1062 DWORD STDCALL GetAdaptersAddresses(ULONG Family,DWORD Flags,PVOID Reserved,PIP_ADAPTER_ADDRESSES pAdapterAddresses,PULONG pOutBufLen)
1063 {
1064 UNIMPLEMENTED
1065 return 0L;
1066 }
1067
1068 /*
1069 * @unimplemented
1070 */
1071 DWORD STDCALL DisableMediaSense(HANDLE *pHandle,OVERLAPPED *pOverLapped)
1072 {
1073 UNIMPLEMENTED
1074 return 0L;
1075 }
1076
1077 /*
1078 * @unimplemented
1079 */
1080 DWORD STDCALL RestoreMediaSense(OVERLAPPED* pOverlapped,LPDWORD lpdwEnableCount)
1081 {
1082 UNIMPLEMENTED
1083 return 0L;
1084 }
1085
1086 /*
1087 * @unimplemented
1088 */
1089 DWORD STDCALL GetIpErrorString(IP_STATUS ErrorCode,PWCHAR Buffer,PDWORD Size)
1090 {
1091 UNIMPLEMENTED
1092 return 0L;
1093 }
1094
1095 /*
1096 * @unimplemented
1097 */
1098 HANDLE STDCALL IcmpCreateFile(
1099 VOID
1100 )
1101 {
1102 UNIMPLEMENTED
1103 return 0L;
1104 }
1105
1106 /*
1107 * @unimplemented
1108 */
1109 HANDLE STDCALL Icmp6CreateFile(
1110 VOID
1111 )
1112 {
1113 UNIMPLEMENTED
1114 return 0L;
1115 }
1116
1117 /*
1118 * @unimplemented
1119 */
1120 WINBOOL STDCALL IcmpCloseHandle(
1121 HANDLE IcmpHandle
1122 )
1123 {
1124 UNIMPLEMENTED
1125 return 0L;
1126 }
1127
1128 /*
1129 * @unimplemented
1130 */
1131 DWORD STDCALL IcmpSendEcho(
1132 HANDLE IcmpHandle,
1133 IPAddr DestinationAddress,
1134 LPVOID RequestData,
1135 WORD RequestSize,
1136 PIP_OPTION_INFORMATION RequestOptions,
1137 LPVOID ReplyBuffer,
1138 DWORD ReplySize,
1139 DWORD Timeout
1140 )
1141 {
1142 UNIMPLEMENTED
1143 return 0L;
1144 }
1145
1146 /*
1147 * @unimplemented
1148 */
1149 DWORD
1150 STDCALL
1151 IcmpSendEcho2(
1152 HANDLE IcmpHandle,
1153 HANDLE Event,
1154 FARPROC ApcRoutine,
1155 PVOID ApcContext,
1156 IPAddr DestinationAddress,
1157 LPVOID RequestData,
1158 WORD RequestSize,
1159 PIP_OPTION_INFORMATION RequestOptions,
1160 LPVOID ReplyBuffer,
1161 DWORD ReplySize,
1162 DWORD Timeout
1163 )
1164 {
1165 UNIMPLEMENTED
1166 return 0L;
1167 }
1168
1169 /*
1170 * @unimplemented
1171 */
1172 DWORD
1173 STDCALL
1174 Icmp6SendEcho2(
1175 HANDLE IcmpHandle,
1176 HANDLE Event,
1177 FARPROC ApcRoutine,
1178 PVOID ApcContext,
1179 struct sockaddr_in6 *SourceAddress,
1180 struct sockaddr_in6 *DestinationAddress,
1181 LPVOID RequestData,
1182 WORD RequestSize,
1183 PIP_OPTION_INFORMATION RequestOptions,
1184 LPVOID ReplyBuffer,
1185 DWORD ReplySize,
1186 DWORD Timeout
1187 )
1188 {
1189 UNIMPLEMENTED
1190 return 0L;
1191 }
1192
1193 /*
1194 * @unimplemented
1195 */
1196 DWORD
1197 STDCALL
1198 IcmpParseReplies(
1199 LPVOID ReplyBuffer,
1200 DWORD ReplySize
1201 )
1202 {
1203 UNIMPLEMENTED
1204 return 0L;
1205 }
1206
1207 /*
1208 * @unimplemented
1209 */
1210 DWORD
1211 STDCALL
1212 Icmp6ParseReplies(
1213 LPVOID ReplyBuffer,
1214 DWORD ReplySize
1215 )
1216 {
1217 UNIMPLEMENTED
1218 return 0L;
1219 }
1220
1221 /*
1222 * @unimplemented
1223 */
1224 DWORD STDCALL AllocateAndGetIfTableFromStack(PMIB_IFTABLE *ppIfTable,
1225 BOOL bOrder, HANDLE heap, DWORD flags)
1226 {
1227 UNIMPLEMENTED
1228 return 0L;
1229 }
1230
1231 /*
1232 * @unimplemented
1233 */
1234 DWORD STDCALL AllocateAndGetIpAddrTableFromStack(PMIB_IPADDRTABLE *ppIpAddrTable,
1235 BOOL bOrder, HANDLE heap, DWORD flags)
1236 {
1237 UNIMPLEMENTED
1238 return 0L;
1239 }
1240
1241 /*
1242 * @unimplemented
1243 */
1244 DWORD STDCALL AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE *
1245 ppIpForwardTable, BOOL bOrder, HANDLE heap, DWORD flags)
1246 {
1247 UNIMPLEMENTED
1248 return 0L;
1249 }
1250
1251 /*
1252 * @unimplemented
1253 */
1254 DWORD STDCALL AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable,
1255 BOOL bOrder, HANDLE heap, DWORD flags)
1256 {
1257 UNIMPLEMENTED
1258 return 0L;
1259 }
1260
1261 /*
1262 * @unimplemented
1263 */
1264 DWORD STDCALL AllocateAndGetTcpTableFromStack(PMIB_TCPTABLE *ppTcpTable,
1265 BOOL bOrder, HANDLE heap, DWORD flags)
1266 {
1267 UNIMPLEMENTED
1268 return 0L;
1269 }
1270
1271 /*
1272 * @unimplemented
1273 */
1274 DWORD STDCALL AllocateAndGetUdpTableFromStack(PMIB_UDPTABLE *ppUdpTable,
1275 BOOL bOrder, HANDLE heap, DWORD flags)
1276 {
1277 UNIMPLEMENTED
1278 return 0L;
1279 }