2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winsock 2 IP Helper API DLL
6 * PROGRAMMERS: Robert Dickenson (robd@reactos.org)
8 * RDD August 18, 2002 Created
26 #define EXPORT STDCALL
28 #define EXPORT CALLBACK
33 /* See debug.h for debug/trace constants */
34 DWORD DebugTraceLevel = MAX_TRACE;
38 /* To make the linker happy */
39 //VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
44 DllMain(HANDLE hInstDll,
48 //WSH_DbgPrint(MIN_TRACE, ("DllMain of iphlpapi.dll\n"));
51 case DLL_PROCESS_ATTACH:
52 /* Don't need thread attach notifications
53 so disable them to improve performance */
54 DisableThreadLibraryCalls(hInstDll);
57 case DLL_THREAD_ATTACH:
60 case DLL_THREAD_DETACH:
63 case DLL_PROCESS_DETACH:
75 AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex, PULONG NTEContext, PULONG NTEInstance)
87 SetIpNetEntry(PMIB_IPNETROW pArpEntry)
99 CreateIpForwardEntry(PMIB_IPFORWARDROW pRoute)
111 GetAdapterIndex(LPWSTR AdapterName, PULONG IfIndex)
122 GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
127 BYTE* pNextMemFree = (BYTE*) pAdapterInfo;
128 ULONG uUsedMemory = 0;
129 PIP_ADAPTER_INFO pPrevAdapter = NULL;
130 PIP_ADAPTER_INFO pCurrentAdapter = NULL;
138 char strTemp[MAX_ADAPTER_NAME_LENGTH + 4];
140 if(pAdapterInfo == NULL && pOutBufLen == NULL)
141 return ERROR_INVALID_PARAMETER;
142 ZeroMemory(pAdapterInfo, *pOutBufLen);
144 lErr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters", 0, KEY_READ, &hAdapters);
145 if(lErr != ERROR_SUCCESS)
148 // Determine the size of the largest name of any adapter and the number of adapters.
149 lErr = RegQueryInfoKeyW(hAdapters, NULL, NULL, NULL, NULL, &dwAdapterLen, NULL, NULL, NULL, NULL, NULL, NULL);
150 if(lErr != ERROR_SUCCESS)
152 RegCloseKey(hAdapters);
155 dwAdapterLen++; // RegQueryInfoKeyW return value does not include terminating null.
157 strAdapter = (wchar_t*) malloc(dwAdapterLen * sizeof(wchar_t));
159 // Enumerate all adapters in SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Adapters.
160 for(dwIndex = 0; ; dwIndex++)
162 dwSize = dwAdapterLen; // Reset size of the strAdapterLen buffer.
163 lErr = RegEnumKeyExW(hAdapters, dwIndex, strAdapter, &dwSize, NULL, NULL, NULL, NULL);
164 if(lErr == ERROR_NO_MORE_ITEMS)
167 // TODO Skip NdisWanIP???
168 if(wcsstr(strAdapter, L"NdisWanIp") != 0)
171 lErr = RegOpenKeyExW(hAdapters, strAdapter, 0, KEY_READ, &hAdapter);
172 if(lErr != ERROR_SUCCESS)
175 // Read the IpConfig value.
176 lErr = RegQueryValueExW(hAdapter, L"IpConfig", NULL, NULL, NULL, &dwSize);
177 if(lErr != ERROR_SUCCESS)
180 strTemp1 = (wchar_t*) malloc(dwSize);
181 strTemp2 = (wchar_t*) malloc(dwSize + 35 * sizeof(wchar_t));
182 lErr = RegQueryValueExW(hAdapter, L"IpConfig", NULL, NULL, (BYTE*) strTemp1, &dwSize);
183 if(lErr != ERROR_SUCCESS)
189 swprintf(strTemp2, L"SYSTEM\\CurrentControlSet\\Services\\%s", strTemp1);
191 // Open the IpConfig key.
192 lErr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, strTemp2, 0, KEY_READ, &hIpConfig);
193 if(lErr != ERROR_SUCCESS)
199 free((void*) strTemp1);
200 free((void*) strTemp2);
203 // Fill IP_ADAPTER_INFO block.
204 pCurrentAdapter = (IP_ADAPTER_INFO*) pNextMemFree;
205 pNextMemFree += sizeof(IP_ADAPTER_INFO);
206 uUsedMemory += sizeof(IP_ADAPTER_INFO);
207 if(uUsedMemory > *pOutBufLen)
208 return ERROR_BUFFER_OVERFLOW; // TODO return the needed size
210 // struct _IP_ADAPTER_INFO* Next
211 if(pPrevAdapter != NULL)
212 pPrevAdapter->Next = pCurrentAdapter;
213 // TODO DWORD ComboIndex
214 // char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]
215 wcstombs(strTemp, strAdapter, MAX_ADAPTER_NAME_LENGTH + 4);
216 strcpy(pCurrentAdapter->AdapterName, strTemp);
217 // TODO char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]
218 // TODO UINT AddressLength
219 // TODO BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH]
222 // TODO UINT DhcpEnabled
223 // TODO PIP_ADDR_STRING CurrentIpAddress
224 // IP_ADDR_STRING IpAddressList
225 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"IPAddress", NULL, NULL, (BYTE*) &pCurrentAdapter->IpAddressList.IpAddress, &dwSize);
226 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"SubnetMask", NULL, NULL, (BYTE*) &pCurrentAdapter->IpAddressList.IpMask, &dwSize);
227 if(strstr(pCurrentAdapter->IpAddressList.IpAddress.String, "0.0.0.0") != 0)
229 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"DhcpIPAddress", NULL, NULL, (BYTE*) &pCurrentAdapter->IpAddressList.IpAddress, &dwSize);
230 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"DhcpSubnetMask", NULL, NULL, (BYTE*) &pCurrentAdapter->IpAddressList.IpMask, &dwSize);
232 // TODO IP_ADDR_STRING GatewayList
233 // IP_ADDR_STRING DhcpServer
234 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"DhcpServer", NULL, NULL, (BYTE*) &pCurrentAdapter->DhcpServer.IpAddress, &dwSize);
235 dwSize = 16; lErr = RegQueryValueExW(hIpConfig, L"DhcpSubnetMask", NULL, NULL, (BYTE*) &pCurrentAdapter->DhcpServer.IpMask, &dwSize);
236 // TODO BOOL HaveWins
237 // TODO IP_ADDR_STRING PrimaryWinsServer
238 // TODO IP_ADDR_STRING SecondaryWinsServer
239 // TODO time_t LeaseObtained
240 // TODO time_t LeaseExpires
242 pPrevAdapter = pCurrentAdapter;
243 RegCloseKey(hAdapter);
244 RegCloseKey(hIpConfig);
249 RegCloseKey(hAdapters);
251 return ERROR_SUCCESS;
255 ////////////////////////////////////////////////////////////////////////////////
262 GetNumberOfInterfaces(OUT PDWORD pdwNumIf)
264 DWORD result = NO_ERROR;
269 if (pdwNumIf == NULL) return ERROR_INVALID_PARAMETER;
271 errCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage", 0, KEY_READ, &hKey);
272 if (errCode == ERROR_SUCCESS) {
274 errCode = RegQueryValueExW(hKey, L"Bind", NULL, NULL, NULL, &dwSize);
275 if (errCode == ERROR_SUCCESS) {
276 wchar_t* pData = (wchar_t*)malloc(dwSize * sizeof(wchar_t));
277 errCode = RegQueryValueExW(hKey, L"Bind", NULL, NULL, (LPBYTE)pData, &dwSize);
278 if (errCode == ERROR_SUCCESS) {
279 wchar_t* pStr = pData;
280 for (i = 0; *pStr != L'\0'; i++) {
281 pStr = pStr + wcslen(pStr) + 1; // next string
300 GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG pOutBufLen)
302 DWORD result = ERROR_SUCCESS;
310 if ((errCode = GetNumberOfInterfaces(&dwNumIf)) != NO_ERROR) {
311 _tprintf(_T("GetInterfaceInfo() failed with code 0x%08X - Use FormatMessage to obtain the message string for the returned error\n"), errCode);
314 if (dwNumIf == 0) return ERROR_NO_DATA; // No adapter information exists for the local computer
315 if (pOutBufLen == NULL) return ERROR_INVALID_PARAMETER;
316 dwOutBufLen = sizeof(IP_INTERFACE_INFO) + dwNumIf * sizeof(IP_ADAPTER_INDEX_MAP);
317 if (*pOutBufLen < dwOutBufLen || pIfTable == NULL) {
318 *pOutBufLen = dwOutBufLen;
319 return ERROR_INSUFFICIENT_BUFFER;
321 memset(pIfTable, 0, dwOutBufLen);
322 pIfTable->NumAdapters = dwNumIf - 1;
323 errCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage", 0, KEY_READ, &hKey);
324 if (errCode == ERROR_SUCCESS) {
325 errCode = RegQueryValueExW(hKey, L"Bind", NULL, NULL, NULL, &dwSize);
326 if (errCode == ERROR_SUCCESS) {
327 wchar_t* pData = (wchar_t*)malloc(dwSize * sizeof(wchar_t));
328 errCode = RegQueryValueExW(hKey, L"Bind", NULL, NULL, (LPBYTE)pData, &dwSize);
329 if (errCode == ERROR_SUCCESS) {
330 wchar_t* pStr = pData;
331 for (i = 0; i < pIfTable->NumAdapters, *pStr != L'\0'; pStr += wcslen(pStr) + 1) {
332 if (wcsstr(pStr, L"\\Device\\NdisWanIp") == 0) {
333 wcsncpy(pIfTable->Adapter[i].Name, pStr, MAX_ADAPTER_NAME);
334 pIfTable->Adapter[i].Index = i++;
354 GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen)
356 DWORD result = ERROR_SUCCESS;
361 if (pFixedInfo == NULL || pOutBufLen == NULL) return ERROR_INVALID_PARAMETER;
363 if (*pOutBufLen < sizeof(FIXED_INFO))
365 *pOutBufLen = sizeof(FIXED_INFO);
366 return ERROR_BUFFER_OVERFLOW;
368 memset(pFixedInfo, 0, sizeof(FIXED_INFO));
370 errCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_READ, &hKey);
371 if (errCode == ERROR_SUCCESS)
373 dwSize = sizeof(pFixedInfo->HostName);
374 errCode = RegQueryValueExA(hKey, "Hostname", NULL, NULL, (LPBYTE)&pFixedInfo->HostName, &dwSize);
375 dwSize = sizeof(pFixedInfo->DomainName);
376 errCode = RegQueryValueExA(hKey, "Domain", NULL, NULL, (LPBYTE)&pFixedInfo->DomainName, &dwSize);
377 if (errCode != ERROR_SUCCESS)
379 dwSize = sizeof(pFixedInfo->DomainName);
380 errCode = RegQueryValueExA(hKey, "DhcpDomain", NULL, NULL, (LPBYTE)&pFixedInfo->DomainName, &dwSize);
382 dwSize = sizeof(pFixedInfo->EnableRouting);
383 errCode = RegQueryValueExW(hKey, L"IPEnableRouter", NULL, NULL, (LPBYTE)&pFixedInfo->EnableRouting, &dwSize);
388 result = ERROR_NO_DATA; // No adapter information exists for the local computer
391 errCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters", 0, KEY_READ, &hKey);
392 if (errCode == ERROR_SUCCESS)
394 dwSize = sizeof(pFixedInfo->ScopeId);
395 errCode = RegQueryValueExA(hKey, "ScopeId", NULL, NULL, (LPBYTE)&pFixedInfo->ScopeId, &dwSize);
396 if (errCode != ERROR_SUCCESS)
398 dwSize = sizeof(pFixedInfo->ScopeId);
399 errCode = RegQueryValueExA(hKey, "DhcpScopeId", NULL, NULL, (LPBYTE)&pFixedInfo->ScopeId, &dwSize);
401 dwSize = sizeof(pFixedInfo->NodeType);
402 errCode = RegQueryValueExW(hKey, L"NodeType", NULL, NULL, (LPBYTE)&pFixedInfo->NodeType, &dwSize);
403 if (errCode != ERROR_SUCCESS)
405 dwSize = sizeof(pFixedInfo->NodeType);
406 errCode = RegQueryValueExA(hKey, "DhcpNodeType", NULL, NULL, (LPBYTE)&pFixedInfo->NodeType, &dwSize);
408 dwSize = sizeof(pFixedInfo->EnableProxy);
409 errCode = RegQueryValueExW(hKey, L"EnableProxy", NULL, NULL, (LPBYTE)&pFixedInfo->EnableProxy, &dwSize);
410 dwSize = sizeof(pFixedInfo->EnableDns);
411 errCode = RegQueryValueExW(hKey, L"EnableDNS", NULL, NULL, (LPBYTE)&pFixedInfo->EnableDns, &dwSize);
416 result = ERROR_NO_DATA; // No adapter information exists for the local computer
428 GetTcpStatistics(PMIB_TCPSTATS pStats)
430 DWORD result = NO_ERROR;
432 result = ERROR_NO_DATA;
443 GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, WINBOOL bOrder)
445 DWORD result = NO_ERROR;
447 result = ERROR_NO_DATA;
458 GetUdpStatistics(PMIB_UDPSTATS pStats)
460 DWORD result = NO_ERROR;
462 result = ERROR_NO_DATA;
473 GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, WINBOOL bOrder)
475 DWORD result = NO_ERROR;
477 result = ERROR_NO_DATA;
488 FlushIpNetTable(DWORD dwIfIndex)
490 DWORD result = NO_ERROR;
495 /******************************************************************
496 * GetIfEntry (IPHLPAPI.@)
510 GetIfEntry(PMIB_IFROW pIfRow)
512 DWORD result = NO_ERROR;
518 /******************************************************************
519 * GetIfTable (IPHLPAPI.@)
535 GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, WINBOOL bOrder)
537 DWORD result = NO_ERROR;
545 DWORD STDCALL GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize,
555 DWORD STDCALL GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize,
565 DWORD STDCALL GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable,
566 PULONG pdwSize, WINBOOL bOrder)
575 DWORD STDCALL GetIpStatistics(PMIB_IPSTATS pStats)
584 DWORD STDCALL GetIpStatisticsEx(PMIB_IPSTATS pStats, DWORD dwFamily)
593 DWORD STDCALL GetIcmpStatistics(PMIB_ICMP pStats)
602 DWORD STDCALL GetTcpStatisticsEx(PMIB_TCPSTATS pStats, DWORD dwFamily)
611 DWORD STDCALL GetUdpStatisticsEx(PMIB_UDPSTATS pStats, DWORD dwFamily)
620 DWORD STDCALL SetIfEntry(PMIB_IFROW pIfRow)
629 DWORD STDCALL SetIpForwardEntry(PMIB_IPFORWARDROW pRoute)
638 DWORD STDCALL DeleteIpForwardEntry(PMIB_IPFORWARDROW pRoute)
647 DWORD STDCALL SetIpStatistics(PMIB_IPSTATS pIpStats)
656 DWORD STDCALL SetIpTTL(UINT nTTL)
665 DWORD STDCALL CreateIpNetEntry(PMIB_IPNETROW pArpEntry)
674 DWORD STDCALL DeleteIpNetEntry(PMIB_IPNETROW pArpEntry)
683 DWORD STDCALL CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask,
693 DWORD STDCALL DeleteProxyArpEntry(DWORD dwAddress, DWORD dwMask,
703 DWORD STDCALL SetTcpEntry(PMIB_TCPROW pTcpRow)
712 DWORD STDCALL GetUniDirectionalAdapterInfo(
713 PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo, PULONG dwOutBufLen)
722 DWORD STDCALL GetBestInterface(IPAddr dwDestAddr, PDWORD pdwBestIfIndex)
731 DWORD STDCALL GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr,
732 PMIB_IPFORWARDROW pBestRoute)
741 DWORD STDCALL NotifyAddrChange(PHANDLE Handle, LPOVERLAPPED overlapped)
750 DWORD STDCALL NotifyRouteChange(PHANDLE Handle, LPOVERLAPPED overlapped)
759 DWORD STDCALL DeleteIPAddress(ULONG NTEContext)
768 DWORD STDCALL GetPerAdapterInfo(ULONG IfIndex,
769 PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen)
778 DWORD STDCALL IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
787 DWORD STDCALL IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
796 DWORD STDCALL SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr,
806 WINBOOL STDCALL GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount,
807 ULONG MaxHops, PULONG RTT)
816 DWORD STDCALL GetFriendlyIfIndex(DWORD IfIndex)
825 DWORD STDCALL EnableRouter(HANDLE* pHandle, OVERLAPPED* pOverlapped)
834 DWORD STDCALL UnenableRouter(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount)
843 DWORD STDCALL GetIcmpStatisticsEx(PMIB_ICMP_EX pStats,DWORD dwFamily)
852 DWORD STDCALL NhpAllocateAndGetInterfaceInfoFromStack(IP_INTERFACE_NAME_INFO **ppTable,PDWORD pdwCount,WINBOOL bOrder,HANDLE hHeap,DWORD dwFlags)
861 DWORD STDCALL GetBestInterfaceEx(struct sockaddr *pDestAddr,PDWORD pdwBestIfIndex)
870 WINBOOL STDCALL CancelIPChangeNotify(LPOVERLAPPED notifyOverlapped)
879 PIP_ADAPTER_ORDER_MAP STDCALL GetAdapterOrderMap(VOID)
888 DWORD STDCALL GetAdaptersAddresses(ULONG Family,DWORD Flags,PVOID Reserved,PIP_ADAPTER_ADDRESSES pAdapterAddresses,PULONG pOutBufLen)
897 DWORD STDCALL DisableMediaSense(HANDLE *pHandle,OVERLAPPED *pOverLapped)
906 DWORD STDCALL RestoreMediaSense(OVERLAPPED* pOverlapped,LPDWORD lpdwEnableCount)
915 DWORD STDCALL GetIpErrorString(IP_STATUS ErrorCode,PWCHAR Buffer,PDWORD Size)
924 HANDLE STDCALL IcmpCreateFile(
935 HANDLE STDCALL Icmp6CreateFile(
946 WINBOOL STDCALL IcmpCloseHandle(
957 DWORD STDCALL IcmpSendEcho(
959 IPAddr DestinationAddress,
962 PIP_OPTION_INFORMATION RequestOptions,
982 IPAddr DestinationAddress,
985 PIP_OPTION_INFORMATION RequestOptions,
1005 struct sockaddr_in6 *SourceAddress,
1006 struct sockaddr_in6 *DestinationAddress,
1009 PIP_OPTION_INFORMATION RequestOptions,
1050 DWORD STDCALL AllocateAndGetIfTableFromStack(PMIB_IFTABLE *ppIfTable,
1051 BOOL bOrder, HANDLE heap, DWORD flags)
1060 DWORD STDCALL AllocateAndGetIpAddrTableFromStack(PMIB_IPADDRTABLE *ppIpAddrTable,
1061 BOOL bOrder, HANDLE heap, DWORD flags)
1070 DWORD STDCALL AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE *
1071 ppIpForwardTable, BOOL bOrder, HANDLE heap, DWORD flags)
1080 DWORD STDCALL AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable,
1081 BOOL bOrder, HANDLE heap, DWORD flags)
1090 DWORD STDCALL AllocateAndGetTcpTableFromStack(PMIB_TCPTABLE *ppTcpTable,
1091 BOOL bOrder, HANDLE heap, DWORD flags)
1100 DWORD STDCALL AllocateAndGetUdpTableFromStack(PMIB_UDPTABLE *ppUdpTable,
1101 BOOL bOrder, HANDLE heap, DWORD flags)