Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeniphlpapi_main.c
Go to the documentation of this file.
00001 /* 00002 * iphlpapi dll implementation 00003 * 00004 * Copyright (C) 2003 Juan Lang 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #define DEBUG 00022 00023 #include "config.h" 00024 #include "iphlpapi_private.h" 00025 00026 WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi); 00027 00028 typedef struct _NAME_SERVER_LIST_CONTEXT { 00029 ULONG uSizeAvailable; 00030 ULONG uSizeRequired; 00031 PIP_PER_ADAPTER_INFO pData; 00032 UINT NumServers; 00033 IP_ADDR_STRING *pLastAddr; 00034 } NAME_SERVER_LIST_CONTEXT, *PNAME_SERVER_LIST_CONTEXT; 00035 00036 BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 00037 { 00038 switch (fdwReason) { 00039 case DLL_PROCESS_ATTACH: 00040 DisableThreadLibraryCalls( hinstDLL ); 00041 interfaceMapInit(); 00042 break; 00043 00044 case DLL_PROCESS_DETACH: 00045 interfaceMapFree(); 00046 break; 00047 } 00048 return TRUE; 00049 } 00050 00051 /****************************************************************** 00052 * AddIPAddress (IPHLPAPI.@) 00053 * 00054 * 00055 * PARAMS 00056 * 00057 * Address [In] 00058 * IpMask [In] 00059 * IfIndex [In] 00060 * NTEContext [In/Out] 00061 * NTEInstance [In/Out] 00062 * 00063 * RETURNS 00064 * 00065 * DWORD 00066 * 00067 */ 00068 DWORD WINAPI AddIPAddress(IPAddr Address, IPMask Netmask, DWORD IfIndex, PULONG NteContext, PULONG NteInstance) 00069 { 00070 return RtlNtStatusToDosError(addIPAddress(Address, Netmask, IfIndex, NteContext, NteInstance)); 00071 } 00072 00073 DWORD getInterfaceGatewayByIndex(DWORD index) 00074 { 00075 DWORD ndx, retVal = 0, numRoutes = getNumRoutes(); 00076 RouteTable *table = getRouteTable(); 00077 if (!table) return 0; 00078 00079 for (ndx = 0; ndx < numRoutes; ndx++) 00080 { 00081 if ((table->routes[ndx].ifIndex == (index)) && (table->routes[ndx].dest == 0)) 00082 retVal = table->routes[ndx].gateway; 00083 } 00084 HeapFree(GetProcessHeap(), 0, table); 00085 return retVal; 00086 } 00087 00088 /****************************************************************** 00089 * AllocateAndGetIfTableFromStack (IPHLPAPI.@) 00090 * 00091 * 00092 * PARAMS 00093 * 00094 * ppIfTable [Out] -- pointer into which the MIB_IFTABLE is 00095 * allocated and returned. 00096 * bOrder [In] -- passed to GetIfTable to order the table 00097 * heap [In] -- heap from which the table is allocated 00098 * flags [In] -- flags to HeapAlloc 00099 * 00100 * RETURNS -- ERROR_INVALID_PARAMETER if ppIfTable is NULL, whatever 00101 * GetIfTable returns otherwise 00102 * 00103 */ 00104 DWORD WINAPI AllocateAndGetIfTableFromStack(PMIB_IFTABLE *ppIfTable, 00105 BOOL bOrder, HANDLE heap, DWORD flags) 00106 { 00107 DWORD ret; 00108 00109 TRACE("ppIfTable %p, bOrder %ld, heap 0x%08lx, flags 0x%08lx\n", ppIfTable, 00110 (DWORD)bOrder, (DWORD)heap, flags); 00111 if (!ppIfTable) 00112 ret = ERROR_INVALID_PARAMETER; 00113 else { 00114 DWORD dwSize = 0; 00115 00116 ret = GetIfTable(*ppIfTable, &dwSize, bOrder); 00117 if (ret == ERROR_INSUFFICIENT_BUFFER) { 00118 *ppIfTable = (PMIB_IFTABLE)HeapAlloc(heap, flags, dwSize); 00119 ret = GetIfTable(*ppIfTable, &dwSize, bOrder); 00120 } 00121 } 00122 TRACE("returning %ld\n", ret); 00123 return ret; 00124 } 00125 00126 00127 /****************************************************************** 00128 * AllocateAndGetIpAddrTableFromStack (IPHLPAPI.@) 00129 * 00130 * 00131 * PARAMS 00132 * 00133 * ppIpAddrTable [Out] 00134 * bOrder [In] -- passed to GetIpAddrTable to order the table 00135 * heap [In] -- heap from which the table is allocated 00136 * flags [In] -- flags to HeapAlloc 00137 * 00138 * RETURNS 00139 * 00140 * DWORD 00141 * 00142 */ 00143 DWORD WINAPI AllocateAndGetIpAddrTableFromStack(PMIB_IPADDRTABLE *ppIpAddrTable, 00144 BOOL bOrder, HANDLE heap, DWORD flags) 00145 { 00146 DWORD ret; 00147 00148 TRACE("ppIpAddrTable %p, bOrder %ld, heap 0x%08lx, flags 0x%08lx\n", 00149 ppIpAddrTable, (DWORD)bOrder, (DWORD)heap, flags); 00150 if (!ppIpAddrTable) 00151 ret = ERROR_INVALID_PARAMETER; 00152 else { 00153 DWORD dwSize = 0; 00154 00155 ret = GetIpAddrTable(*ppIpAddrTable, &dwSize, bOrder); 00156 if (ret == ERROR_INSUFFICIENT_BUFFER) { 00157 *ppIpAddrTable = (PMIB_IPADDRTABLE)HeapAlloc(heap, flags, dwSize); 00158 ret = GetIpAddrTable(*ppIpAddrTable, &dwSize, bOrder); 00159 } 00160 } 00161 TRACE("returning %ld\n", ret); 00162 return ret; 00163 } 00164 00165 00166 /****************************************************************** 00167 * AllocateAndGetIpForwardTableFromStack (IPHLPAPI.@) 00168 * 00169 * 00170 * ppIpForwardTable [Out] -- pointer into which the MIB_IPFORWARDTABLE is 00171 * allocated and returned. 00172 * bOrder [In] -- passed to GetIfTable to order the table 00173 * heap [In] -- heap from which the table is allocated 00174 * flags [In] -- flags to HeapAlloc 00175 * 00176 * RETURNS -- ERROR_INVALID_PARAMETER if ppIfTable is NULL, whatever 00177 * GetIpForwardTable returns otherwise 00178 * 00179 */ 00180 DWORD WINAPI AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE * 00181 ppIpForwardTable, BOOL bOrder, HANDLE heap, DWORD flags) 00182 { 00183 DWORD ret; 00184 00185 TRACE("ppIpForwardTable %p, bOrder %ld, heap 0x%08lx, flags 0x%08lx\n", 00186 ppIpForwardTable, (DWORD)bOrder, (DWORD)heap, flags); 00187 if (!ppIpForwardTable) 00188 ret = ERROR_INVALID_PARAMETER; 00189 else { 00190 DWORD dwSize = 0; 00191 00192 ret = GetIpForwardTable(*ppIpForwardTable, &dwSize, bOrder); 00193 if (ret == ERROR_INSUFFICIENT_BUFFER) { 00194 *ppIpForwardTable = (PMIB_IPFORWARDTABLE)HeapAlloc(heap, flags, dwSize); 00195 ret = GetIpForwardTable(*ppIpForwardTable, &dwSize, bOrder); 00196 } 00197 } 00198 TRACE("returning %ld\n", ret); 00199 return ret; 00200 } 00201 00202 00203 /****************************************************************** 00204 * AllocateAndGetIpNetTableFromStack (IPHLPAPI.@) 00205 * 00206 * 00207 * PARAMS 00208 * 00209 * ppIpNetTable [Out] 00210 * bOrder [In] -- passed to GetIpNetTable to order the table 00211 * heap [In] -- heap from which the table is allocated 00212 * flags [In] -- flags to HeapAlloc 00213 * 00214 * RETURNS 00215 * 00216 * DWORD 00217 * 00218 */ 00219 DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable, 00220 BOOL bOrder, HANDLE heap, DWORD flags) 00221 { 00222 DWORD ret; 00223 00224 TRACE("ppIpNetTable %p, bOrder %ld, heap 0x%08lx, flags 0x%08lx\n", 00225 ppIpNetTable, (DWORD)bOrder, (DWORD)heap, flags); 00226 if (!ppIpNetTable) 00227 ret = ERROR_INVALID_PARAMETER; 00228 else { 00229 DWORD dwSize = 0; 00230 00231 ret = GetIpNetTable(*ppIpNetTable, &dwSize, bOrder); 00232 if (ret == ERROR_INSUFFICIENT_BUFFER) { 00233 *ppIpNetTable = (PMIB_IPNETTABLE)HeapAlloc(heap, flags, dwSize); 00234 ret = GetIpNetTable(*ppIpNetTable, &dwSize, bOrder); 00235 } 00236 } 00237 TRACE("returning %ld\n", ret); 00238 return ret; 00239 } 00240 00241 00242 /****************************************************************** 00243 * AllocateAndGetTcpTableFromStack (IPHLPAPI.@) 00244 * 00245 * 00246 * PARAMS 00247 * 00248 * ppTcpTable [Out] 00249 * bOrder [In] -- passed to GetTcpTable to order the table 00250 * heap [In] -- heap from which the table is allocated 00251 * flags [In] -- flags to HeapAlloc 00252 * 00253 * RETURNS 00254 * 00255 * DWORD 00256 * 00257 */ 00258 DWORD WINAPI AllocateAndGetTcpTableFromStack(PMIB_TCPTABLE *ppTcpTable, 00259 BOOL bOrder, HANDLE heap, DWORD flags) 00260 { 00261 DWORD ret; 00262 00263 TRACE("ppTcpTable %p, bOrder %ld, heap 0x%08lx, flags 0x%08lx\n", 00264 ppTcpTable, (DWORD)bOrder, (DWORD)heap, flags); 00265 if (!ppTcpTable) 00266 ret = ERROR_INVALID_PARAMETER; 00267 else { 00268 DWORD dwSize = 0; 00269 00270 ret = GetTcpTable(*ppTcpTable, &dwSize, bOrder); 00271 if (ret == ERROR_INSUFFICIENT_BUFFER) { 00272 *ppTcpTable = (PMIB_TCPTABLE)HeapAlloc(heap, flags, dwSize); 00273 ret = GetTcpTable(*ppTcpTable, &dwSize, bOrder); 00274 } 00275 } 00276 TRACE("returning %ld\n", ret); 00277 return ret; 00278 } 00279 00280 00281 /****************************************************************** 00282 * AllocateAndGetUdpTableFromStack (IPHLPAPI.@) 00283 * 00284 * 00285 * PARAMS 00286 * 00287 * ppUdpTable [Out] 00288 * bOrder [In] -- passed to GetUdpTable to order the table 00289 * heap [In] -- heap from which the table is allocated 00290 * flags [In] -- flags to HeapAlloc 00291 * 00292 * RETURNS 00293 * 00294 * DWORD 00295 * 00296 */ 00297 DWORD WINAPI AllocateAndGetUdpTableFromStack(PMIB_UDPTABLE *ppUdpTable, 00298 BOOL bOrder, HANDLE heap, DWORD flags) 00299 { 00300 DWORD ret; 00301 00302 TRACE("ppUdpTable %p, bOrder %ld, heap 0x%08lx, flags 0x%08lx\n", 00303 ppUdpTable, (DWORD)bOrder, (DWORD)heap, flags); 00304 if (!ppUdpTable) 00305 ret = ERROR_INVALID_PARAMETER; 00306 else { 00307 DWORD dwSize = 0; 00308 00309 ret = GetUdpTable(*ppUdpTable, &dwSize, bOrder); 00310 if (ret == ERROR_INSUFFICIENT_BUFFER) { 00311 *ppUdpTable = (PMIB_UDPTABLE)HeapAlloc(heap, flags, dwSize); 00312 ret = GetUdpTable(*ppUdpTable, &dwSize, bOrder); 00313 } 00314 } 00315 TRACE("returning %ld\n", ret); 00316 return ret; 00317 } 00318 00319 00320 /****************************************************************** 00321 * CreateIpForwardEntry (IPHLPAPI.@) 00322 * 00323 * 00324 * PARAMS 00325 * 00326 * pRoute [In/Out] 00327 * 00328 * RETURNS 00329 * 00330 * DWORD 00331 * 00332 */ 00333 DWORD WINAPI CreateIpForwardEntry(PMIB_IPFORWARDROW pRoute) 00334 { 00335 return createIpForwardEntry( pRoute ); 00336 } 00337 00338 00339 /****************************************************************** 00340 * CreateIpNetEntry (IPHLPAPI.@) 00341 * 00342 * 00343 * PARAMS 00344 * 00345 * pArpEntry [In/Out] 00346 * 00347 * RETURNS 00348 * 00349 * DWORD 00350 * 00351 */ 00352 DWORD WINAPI CreateIpNetEntry(PMIB_IPNETROW pArpEntry) 00353 { 00354 TRACE("pArpEntry %p\n", pArpEntry); 00355 /* could use SIOCSARP on systems that support it, not sure I want to */ 00356 FIXME(":stub\n"); 00357 return (DWORD) 0; 00358 } 00359 00360 00361 /****************************************************************** 00362 * CreateProxyArpEntry (IPHLPAPI.@) 00363 * 00364 * 00365 * PARAMS 00366 * 00367 * dwAddress [In] 00368 * dwMask [In] 00369 * dwIfIndex [In] 00370 * 00371 * RETURNS 00372 * 00373 * DWORD 00374 * 00375 */ 00376 DWORD WINAPI CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex) 00377 { 00378 TRACE("dwAddress 0x%08lx, dwMask 0x%08lx, dwIfIndex 0x%08lx\n", dwAddress, 00379 dwMask, dwIfIndex); 00380 FIXME(":stub\n"); 00381 /* marking Win2K+ functions not supported */ 00382 return ERROR_NOT_SUPPORTED; 00383 } 00384 00385 00386 /****************************************************************** 00387 * DeleteIPAddress (IPHLPAPI.@) 00388 * 00389 * 00390 * PARAMS 00391 * 00392 * NTEContext [In] 00393 * 00394 * RETURNS 00395 * 00396 * DWORD 00397 * 00398 */ 00399 DWORD WINAPI DeleteIPAddress(ULONG NTEContext) 00400 { 00401 TRACE("NTEContext %ld\n", NTEContext); 00402 return RtlNtStatusToDosError(deleteIpAddress(NTEContext)); 00403 } 00404 00405 00406 /****************************************************************** 00407 * DeleteIpForwardEntry (IPHLPAPI.@) 00408 * 00409 * 00410 * PARAMS 00411 * 00412 * pRoute [In/Out] 00413 * 00414 * RETURNS 00415 * 00416 * DWORD 00417 * 00418 */ 00419 DWORD WINAPI DeleteIpForwardEntry(PMIB_IPFORWARDROW pRoute) 00420 { 00421 return deleteIpForwardEntry( pRoute ); 00422 } 00423 00424 00425 /****************************************************************** 00426 * DeleteIpNetEntry (IPHLPAPI.@) 00427 * 00428 * 00429 * PARAMS 00430 * 00431 * pArpEntry [In/Out] 00432 * 00433 * RETURNS 00434 * 00435 * DWORD 00436 * 00437 */ 00438 DWORD WINAPI DeleteIpNetEntry(PMIB_IPNETROW pArpEntry) 00439 { 00440 TRACE("pArpEntry %p\n", pArpEntry); 00441 /* could use SIOCDARP on systems that support it, not sure I want to */ 00442 FIXME(":stub\n"); 00443 return (DWORD) 0; 00444 } 00445 00446 00447 /****************************************************************** 00448 * DeleteProxyArpEntry (IPHLPAPI.@) 00449 * 00450 * 00451 * PARAMS 00452 * 00453 * dwAddress [In] 00454 * dwMask [In] 00455 * dwIfIndex [In] 00456 * 00457 * RETURNS 00458 * 00459 * DWORD 00460 * 00461 */ 00462 DWORD WINAPI DeleteProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex) 00463 { 00464 TRACE("dwAddress 0x%08lx, dwMask 0x%08lx, dwIfIndex 0x%08lx\n", dwAddress, 00465 dwMask, dwIfIndex); 00466 FIXME(":stub\n"); 00467 /* marking Win2K+ functions not supported */ 00468 return ERROR_NOT_SUPPORTED; 00469 } 00470 00471 /****************************************************************** 00472 * EnableRouter (IPHLPAPI.@) 00473 * 00474 * 00475 * PARAMS 00476 * 00477 * pHandle [In/Out] 00478 * pOverlapped [In/Out] 00479 * 00480 * RETURNS 00481 * 00482 * DWORD 00483 * 00484 */ 00485 DWORD WINAPI EnableRouter(HANDLE * pHandle, OVERLAPPED * pOverlapped) 00486 { 00487 TRACE("pHandle %p, pOverlapped %p\n", pHandle, pOverlapped); 00488 FIXME(":stub\n"); 00489 /* could echo "1" > /proc/net/sys/net/ipv4/ip_forward, not sure I want to 00490 could map EACCESS to ERROR_ACCESS_DENIED, I suppose 00491 marking Win2K+ functions not supported */ 00492 return ERROR_NOT_SUPPORTED; 00493 } 00494 00495 00496 /****************************************************************** 00497 * FlushIpNetTable (IPHLPAPI.@) 00498 * 00499 * 00500 * PARAMS 00501 * 00502 * dwIfIndex [In] 00503 * 00504 * RETURNS 00505 * 00506 * DWORD 00507 * 00508 */ 00509 DWORD WINAPI FlushIpNetTable(DWORD dwIfIndex) 00510 { 00511 TRACE("dwIfIndex 0x%08lx\n", dwIfIndex); 00512 FIXME(":stub\n"); 00513 /* this flushes the arp cache of the given index 00514 marking Win2K+ functions not supported */ 00515 return ERROR_NOT_SUPPORTED; 00516 } 00517 00518 00519 /****************************************************************** 00520 * GetAdapterIndex (IPHLPAPI.@) 00521 * 00522 * 00523 * PARAMS 00524 * 00525 * AdapterName [In/Out] 00526 * IfIndex [In/Out] 00527 * 00528 * RETURNS 00529 * 00530 * DWORD 00531 * 00532 */ 00533 DWORD WINAPI GetAdapterIndex(LPWSTR AdapterName, PULONG IfIndex) 00534 { 00535 TRACE("AdapterName %p, IfIndex %p\n", AdapterName, IfIndex); 00536 FIXME(":stub\n"); 00537 /* marking Win2K+ functions not supported */ 00538 return ERROR_NOT_SUPPORTED; 00539 } 00540 00541 00542 /****************************************************************** 00543 * GetAdaptersInfo (IPHLPAPI.@) 00544 * 00545 * 00546 * PARAMS 00547 * 00548 * pAdapterInfo [In/Out] 00549 * pOutBufLen [In/Out] 00550 * 00551 * RETURNS 00552 * 00553 * DWORD 00554 * 00555 */ 00556 DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) 00557 { 00558 DWORD ret; 00559 BOOL dhcpEnabled; 00560 DWORD dhcpServer; 00561 00562 TRACE("pAdapterInfo %p, pOutBufLen %p\n", pAdapterInfo, pOutBufLen); 00563 if (!pOutBufLen) 00564 ret = ERROR_INVALID_PARAMETER; 00565 else { 00566 DWORD numNonLoopbackInterfaces = getNumNonLoopbackInterfaces(); 00567 00568 if (numNonLoopbackInterfaces > 0) { 00569 /* this calculation assumes only one address in the IP_ADDR_STRING lists. 00570 that's okay, because: 00571 - we don't get multiple addresses per adapter anyway 00572 - we don't know about per-adapter gateways 00573 - DHCP and WINS servers can have max one entry per list */ 00574 ULONG size = sizeof(IP_ADAPTER_INFO) * numNonLoopbackInterfaces; 00575 00576 if (!pAdapterInfo || *pOutBufLen < size) { 00577 *pOutBufLen = size; 00578 ret = ERROR_BUFFER_OVERFLOW; 00579 } 00580 else { 00581 InterfaceIndexTable *table = getNonLoopbackInterfaceIndexTable(); 00582 00583 if (table) { 00584 size = sizeof(IP_ADAPTER_INFO) * table->numIndexes; 00585 if (*pOutBufLen < size) { 00586 *pOutBufLen = size; 00587 ret = ERROR_INSUFFICIENT_BUFFER; 00588 } 00589 else { 00590 DWORD ndx; 00591 HKEY hKey; 00592 BOOL winsEnabled = FALSE; 00593 IP_ADDRESS_STRING primaryWINS, secondaryWINS; 00594 00595 memset(pAdapterInfo, 0, size); 00596 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, 00597 "Software\\Wine\\Wine\\Config\\Network", 0, KEY_READ, 00598 &hKey) == ERROR_SUCCESS) { 00599 DWORD size = sizeof(primaryWINS.String); 00600 unsigned long addr; 00601 00602 RegQueryValueExA(hKey, "WinsServer", NULL, NULL, 00603 (PBYTE)primaryWINS.String, &size); 00604 addr = inet_addr(primaryWINS.String); 00605 if (addr != INADDR_NONE && addr != INADDR_ANY) 00606 winsEnabled = TRUE; 00607 size = sizeof(secondaryWINS.String); 00608 RegQueryValueExA(hKey, "BackupWinsServer", NULL, NULL, 00609 (PBYTE)secondaryWINS.String, &size); 00610 addr = inet_addr(secondaryWINS.String); 00611 if (addr != INADDR_NONE && addr != INADDR_ANY) 00612 winsEnabled = TRUE; 00613 RegCloseKey(hKey); 00614 } 00615 TRACE("num of index is %lu\n", table->numIndexes); 00616 for (ndx = 0; ndx < table->numIndexes; ndx++) { 00617 PIP_ADAPTER_INFO ptr = &pAdapterInfo[ndx]; 00618 DWORD addrLen = sizeof(ptr->Address), type; 00619 const char *ifname = 00620 getInterfaceNameByIndex(table->indexes[ndx]); 00621 if (!ifname) { 00622 ret = ERROR_OUTOFMEMORY; 00623 break; 00624 } 00625 00626 /* on Win98 this is left empty, but whatever */ 00627 strncpy(ptr->AdapterName,ifname,sizeof(ptr->AdapterName)); 00628 consumeInterfaceName(ifname); 00629 ptr->AdapterName[MAX_ADAPTER_NAME_LENGTH] = '\0'; 00630 getInterfacePhysicalByIndex(table->indexes[ndx], &addrLen, 00631 ptr->Address, &type); 00632 /* MS defines address length and type as UINT in some places and 00633 DWORD in others, **sigh**. Don't want to assume that PUINT and 00634 PDWORD are equiv (64-bit?) */ 00635 ptr->AddressLength = addrLen; 00636 ptr->Type = type; 00637 ptr->Index = table->indexes[ndx]; 00638 toIPAddressString(getInterfaceIPAddrByIndex(table->indexes[ndx]), 00639 ptr->IpAddressList.IpAddress.String); 00640 toIPAddressString(getInterfaceMaskByIndex(table->indexes[ndx]), 00641 ptr->IpAddressList.IpMask.String); 00642 ptr->IpAddressList.Context = ptr->Index; 00643 toIPAddressString(getInterfaceGatewayByIndex(table->indexes[ndx]), 00644 ptr->GatewayList.IpAddress.String); 00645 getDhcpInfoForAdapter(table->indexes[ndx], &dhcpEnabled, 00646 &dhcpServer, &ptr->LeaseObtained, 00647 &ptr->LeaseExpires); 00648 ptr->DhcpEnabled = (DWORD) dhcpEnabled; 00649 toIPAddressString(dhcpServer, 00650 ptr->DhcpServer.IpAddress.String); 00651 if (winsEnabled) { 00652 ptr->HaveWins = TRUE; 00653 memcpy(ptr->PrimaryWinsServer.IpAddress.String, 00654 primaryWINS.String, sizeof(primaryWINS.String)); 00655 memcpy(ptr->SecondaryWinsServer.IpAddress.String, 00656 secondaryWINS.String, sizeof(secondaryWINS.String)); 00657 } 00658 if (ndx < table->numIndexes - 1) 00659 ptr->Next = &pAdapterInfo[ndx + 1]; 00660 else 00661 ptr->Next = NULL; 00662 } 00663 ret = NO_ERROR; 00664 } 00665 free(table); 00666 } 00667 else 00668 ret = ERROR_OUTOFMEMORY; 00669 } 00670 } 00671 else 00672 ret = ERROR_NO_DATA; 00673 } 00674 TRACE("returning %ld\n", ret); 00675 return ret; 00676 } 00677 00678 00679 /****************************************************************** 00680 * GetBestInterface (IPHLPAPI.@) 00681 * 00682 * 00683 * PARAMS 00684 * 00685 * dwDestAddr [In] 00686 * pdwBestIfIndex [In/Out] 00687 * 00688 * RETURNS 00689 * 00690 * DWORD 00691 * 00692 */ 00693 DWORD WINAPI GetBestInterface(IPAddr dwDestAddr, PDWORD pdwBestIfIndex) 00694 { 00695 DWORD ret; 00696 00697 TRACE("dwDestAddr 0x%08lx, pdwBestIfIndex %p\n", dwDestAddr, pdwBestIfIndex); 00698 if (!pdwBestIfIndex) 00699 ret = ERROR_INVALID_PARAMETER; 00700 else { 00701 MIB_IPFORWARDROW ipRow; 00702 00703 ret = GetBestRoute(dwDestAddr, 0, &ipRow); 00704 if (ret == ERROR_SUCCESS) 00705 *pdwBestIfIndex = ipRow.dwForwardIfIndex; 00706 } 00707 TRACE("returning %ld\n", ret); 00708 return ret; 00709 } 00710 00711 00712 /****************************************************************** 00713 * GetBestRoute (IPHLPAPI.@) 00714 * 00715 * 00716 * PARAMS 00717 * 00718 * dwDestAddr [In] 00719 * dwSourceAddr [In] 00720 * OUT [In] 00721 * 00722 * RETURNS 00723 * 00724 * DWORD 00725 * 00726 */ 00727 DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDROW pBestRoute) 00728 { 00729 PMIB_IPFORWARDTABLE table; 00730 DWORD ret; 00731 00732 TRACE("dwDestAddr 0x%08lx, dwSourceAddr 0x%08lx, pBestRoute %p\n", dwDestAddr, 00733 dwSourceAddr, pBestRoute); 00734 if (!pBestRoute) 00735 return ERROR_INVALID_PARAMETER; 00736 00737 AllocateAndGetIpForwardTableFromStack(&table, FALSE, GetProcessHeap(), 0); 00738 if (table) { 00739 DWORD ndx, matchedBits, matchedNdx = 0; 00740 00741 for (ndx = 0, matchedBits = 0; ndx < table->dwNumEntries; ndx++) { 00742 if ((dwDestAddr & table->table[ndx].dwForwardMask) == 00743 (table->table[ndx].dwForwardDest & table->table[ndx].dwForwardMask)) { 00744 DWORD numShifts, mask; 00745 00746 for (numShifts = 0, mask = table->table[ndx].dwForwardMask; 00747 mask && !(mask & 1); mask >>= 1, numShifts++) 00748 ; 00749 if (numShifts > matchedBits) { 00750 matchedBits = numShifts; 00751 matchedNdx = ndx; 00752 } 00753 } 00754 } 00755 memcpy(pBestRoute, &table->table[matchedNdx], sizeof(MIB_IPFORWARDROW)); 00756 HeapFree(GetProcessHeap(), 0, table); 00757 ret = ERROR_SUCCESS; 00758 } 00759 else 00760 ret = ERROR_OUTOFMEMORY; 00761 TRACE("returning %ld\n", ret); 00762 return ret; 00763 } 00764 00765 /****************************************************************** 00766 * GetExtendedTcpTable (IPHLPAPI.@) 00767 * 00768 * Get the table of TCP endpoints available to the application. 00769 * 00770 * PARAMS 00771 * pTcpTable [Out] table struct with the filtered TCP endpoints available to application 00772 * pdwSize [In/Out] estimated size of the structure returned in pTcpTable, in bytes 00773 * bOrder [In] whether to order the table 00774 * ulAf [in] version of IP used by the TCP endpoints 00775 * TableClass [in] type of the TCP table structure from TCP_TABLE_CLASS 00776 * Reserved [in] reserved - this value must be zero 00777 * 00778 * RETURNS 00779 * Success: NO_ERROR 00780 * Failure: either ERROR_INSUFFICIENT_BUFFER or ERROR_INVALID_PARAMETER 00781 * 00782 * NOTES 00783 */ 00784 DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, TCP_TABLE_CLASS TableClass, ULONG Reserved) 00785 { 00786 DWORD ret = NO_ERROR; 00787 UNIMPLEMENTED; 00788 return ret; 00789 } 00790 00791 00792 /****************************************************************** 00793 * GetFriendlyIfIndex (IPHLPAPI.@) 00794 * 00795 * 00796 * PARAMS 00797 * 00798 * IfIndex [In] 00799 * 00800 * RETURNS 00801 * 00802 * DWORD 00803 * 00804 */ 00805 DWORD WINAPI GetFriendlyIfIndex(DWORD IfIndex) 00806 { 00807 /* windows doesn't validate these, either, just makes sure the top byte is 00808 cleared. I assume my ifenum module never gives an index with the top 00809 byte set. */ 00810 TRACE("returning %ld\n", IfIndex); 00811 return IfIndex; 00812 } 00813 00814 00815 /****************************************************************** 00816 * GetIcmpStatistics (IPHLPAPI.@) 00817 * 00818 * 00819 * PARAMS 00820 * 00821 * pStats [In/Out] 00822 * 00823 * RETURNS 00824 * 00825 * DWORD 00826 * 00827 */ 00828 DWORD WINAPI GetIcmpStatistics(PMIB_ICMP pStats) 00829 { 00830 DWORD ret; 00831 00832 TRACE("pStats %p\n", pStats); 00833 ret = getICMPStats(pStats); 00834 TRACE("returning %ld\n", ret); 00835 return ret; 00836 } 00837 00838 00839 /****************************************************************** 00840 * GetIfEntry (IPHLPAPI.@) 00841 * 00842 * 00843 * PARAMS 00844 * 00845 * pIfRow [In/Out] 00846 * 00847 * RETURNS 00848 * 00849 * DWORD 00850 * 00851 */ 00852 DWORD WINAPI GetIfEntry(PMIB_IFROW pIfRow) 00853 { 00854 DWORD ret; 00855 const char *name; 00856 00857 TRACE("pIfRow %p\n", pIfRow); 00858 if (!pIfRow) 00859 return ERROR_INVALID_PARAMETER; 00860 00861 name = getInterfaceNameByIndex(pIfRow->dwIndex); 00862 if (name) { 00863 ret = getInterfaceEntryByIndex(pIfRow->dwIndex, pIfRow); 00864 if (ret == NO_ERROR) 00865 ret = getInterfaceStatsByName(name, pIfRow); 00866 consumeInterfaceName(name); 00867 } 00868 else 00869 ret = ERROR_INVALID_DATA; 00870 TRACE("returning %ld\n", ret); 00871 return ret; 00872 } 00873 00874 00875 static int IfTableSorter(const void *a, const void *b) 00876 { 00877 int ret; 00878 00879 if (a && b) 00880 ret = ((PMIB_IFROW)a)->dwIndex - ((PMIB_IFROW)b)->dwIndex; 00881 else 00882 ret = 0; 00883 return ret; 00884 } 00885 00886 00887 /****************************************************************** 00888 * GetIfTable (IPHLPAPI.@) 00889 * 00890 * 00891 * PARAMS 00892 * 00893 * pIfTable [In/Out] 00894 * pdwSize [In/Out] 00895 * bOrder [In] 00896 * 00897 * RETURNS 00898 * 00899 * DWORD 00900 * 00901 */ 00902 DWORD WINAPI GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder) 00903 { 00904 DWORD ret; 00905 00906 TRACE("pIfTable %p, pdwSize %p, bOrder %ld\n", pdwSize, pdwSize, 00907 (DWORD)bOrder); 00908 if (!pdwSize) 00909 ret = ERROR_INVALID_PARAMETER; 00910 else { 00911 DWORD numInterfaces = getNumInterfaces(); 00912 ULONG size; 00913 TRACE("GetIfTable: numInterfaces = %d\n", (int)numInterfaces); 00914 size = sizeof(MIB_IFTABLE) + (numInterfaces - 1) * sizeof(MIB_IFROW); 00915 00916 if (!pIfTable || *pdwSize < size) { 00917 *pdwSize = size; 00918 ret = ERROR_INSUFFICIENT_BUFFER; 00919 } 00920 else { 00921 InterfaceIndexTable *table = getInterfaceIndexTable(); 00922 00923 if (table) { 00924 size = sizeof(MIB_IFTABLE) + (table->numIndexes - 1) * 00925 sizeof(MIB_IFROW); 00926 if (*pdwSize < size) { 00927 *pdwSize = size; 00928 ret = ERROR_INSUFFICIENT_BUFFER; 00929 } 00930 else { 00931 DWORD ndx; 00932 00933 pIfTable->dwNumEntries = 0; 00934 for (ndx = 0; ndx < table->numIndexes; ndx++) { 00935 pIfTable->table[ndx].dwIndex = table->indexes[ndx]; 00936 GetIfEntry(&pIfTable->table[ndx]); 00937 pIfTable->dwNumEntries++; 00938 } 00939 if (bOrder) 00940 qsort(pIfTable->table, pIfTable->dwNumEntries, sizeof(MIB_IFROW), 00941 IfTableSorter); 00942 ret = NO_ERROR; 00943 } 00944 free(table); 00945 } 00946 else 00947 ret = ERROR_OUTOFMEMORY; 00948 } 00949 } 00950 TRACE("returning %ld\n", ret); 00951 return ret; 00952 } 00953 00954 00955 /****************************************************************** 00956 * GetInterfaceInfo (IPHLPAPI.@) 00957 * 00958 * 00959 * PARAMS 00960 * 00961 * pIfTable [In/Out] 00962 * dwOutBufLen [In/Out] 00963 * 00964 * RETURNS 00965 * 00966 * DWORD 00967 * 00968 */ 00969 DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen) 00970 { 00971 DWORD ret; 00972 00973 TRACE("pIfTable %p, dwOutBufLen %p\n", pIfTable, dwOutBufLen); 00974 if (!dwOutBufLen) 00975 ret = ERROR_INVALID_PARAMETER; 00976 else { 00977 DWORD numNonLoopbackInterfaces = getNumNonLoopbackInterfaces(); 00978 ULONG size; 00979 TRACE("numNonLoopbackInterfaces == 0x%x\n", numNonLoopbackInterfaces); 00980 size = sizeof(IP_INTERFACE_INFO) + (numNonLoopbackInterfaces) * 00981 sizeof(IP_ADAPTER_INDEX_MAP); 00982 00983 if (!pIfTable || *dwOutBufLen < size) { 00984 *dwOutBufLen = size; 00985 ret = ERROR_INSUFFICIENT_BUFFER; 00986 } 00987 else { 00988 InterfaceIndexTable *table = getNonLoopbackInterfaceIndexTable(); 00989 00990 if (table) { 00991 TRACE("table->numIndexes == 0x%x\n", table->numIndexes); 00992 size = sizeof(IP_INTERFACE_INFO) + (table->numIndexes) * 00993 sizeof(IP_ADAPTER_INDEX_MAP); 00994 if (*dwOutBufLen < size) { 00995 *dwOutBufLen = size; 00996 ret = ERROR_INSUFFICIENT_BUFFER; 00997 } 00998 else { 00999 DWORD ndx; 01000 01001 pIfTable->NumAdapters = 0; 01002 for (ndx = 0; ndx < table->numIndexes; ndx++) { 01003 const char *walker, *name; 01004 WCHAR *assigner; 01005 01006 pIfTable->Adapter[ndx].Index = table->indexes[ndx]; 01007 name = getInterfaceNameByIndex(table->indexes[ndx]); 01008 for (walker = name, assigner = pIfTable->Adapter[ndx].Name; 01009 walker && *walker && 01010 assigner - pIfTable->Adapter[ndx].Name < MAX_ADAPTER_NAME - 1; 01011 walker++, assigner++) 01012 *assigner = *walker; 01013 *assigner = 0; 01014 consumeInterfaceName(name); 01015 pIfTable->NumAdapters++; 01016 } 01017 ret = NO_ERROR; 01018 } 01019 free(table); 01020 } 01021 else 01022 ret = ERROR_OUTOFMEMORY; 01023 } 01024 } 01025 TRACE("returning %ld\n", ret); 01026 return ret; 01027 } 01028 01029 01030 static int IpAddrTableSorter(const void *a, const void *b) 01031 { 01032 int ret; 01033 01034 if (a && b) 01035 ret = ((PMIB_IPADDRROW)a)->dwAddr - ((PMIB_IPADDRROW)b)->dwAddr; 01036 else 01037 ret = 0; 01038 return ret; 01039 } 01040 01041 01042 /****************************************************************** 01043 * GetIpAddrTable (IPHLPAPI.@) 01044 * 01045 * 01046 * PARAMS 01047 * 01048 * pIpAddrTable [In/Out] 01049 * pdwSize [In/Out] 01050 * bOrder [In] 01051 * 01052 * RETURNS 01053 * 01054 * DWORD 01055 * 01056 */ 01057 DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder) 01058 { 01059 DWORD ret; 01060 01061 TRACE("pIpAddrTable %p, pdwSize %p, bOrder %ld\n", pIpAddrTable, pdwSize, 01062 (DWORD)bOrder); 01063 if (!pdwSize) 01064 ret = ERROR_INVALID_PARAMETER; 01065 else { 01066 DWORD numInterfaces = getNumInterfaces(); 01067 ULONG size = sizeof(MIB_IPADDRTABLE) + (numInterfaces - 1) * 01068 sizeof(MIB_IPADDRROW); 01069 01070 if (!pIpAddrTable || *pdwSize < size) { 01071 *pdwSize = size; 01072 ret = ERROR_INSUFFICIENT_BUFFER; 01073 } 01074 else { 01075 InterfaceIndexTable *table = getInterfaceIndexTable(); 01076 01077 if (table) { 01078 size = sizeof(MIB_IPADDRTABLE) + (table->numIndexes - 1) * 01079 sizeof(MIB_IPADDRROW); 01080 if (*pdwSize < size) { 01081 *pdwSize = size; 01082 ret = ERROR_INSUFFICIENT_BUFFER; 01083 } 01084 else { 01085 DWORD ndx, bcast; 01086 01087 pIpAddrTable->dwNumEntries = 0; 01088 for (ndx = 0; ndx < table->numIndexes; ndx++) { 01089 pIpAddrTable->table[ndx].dwIndex = table->indexes[ndx]; 01090 pIpAddrTable->table[ndx].dwAddr = 01091 getInterfaceIPAddrByIndex(table->indexes[ndx]); 01092 pIpAddrTable->table[ndx].dwMask = 01093 getInterfaceMaskByIndex(table->indexes[ndx]); 01094 /* the dwBCastAddr member isn't the broadcast address, it indicates 01095 * whether the interface uses the 1's broadcast address (1) or the 01096 * 0's broadcast address (0). 01097 */ 01098 bcast = getInterfaceBCastAddrByIndex(table->indexes[ndx]); 01099 pIpAddrTable->table[ndx].dwBCastAddr = 01100 (bcast & pIpAddrTable->table[ndx].dwMask) ? 1 : 0; 01101 /* FIXME: hardcoded reasm size, not sure where to get it */ 01102 pIpAddrTable->table[ndx].dwReasmSize = 65535; 01103 pIpAddrTable->table[ndx].unused1 = 0; 01104 pIpAddrTable->table[ndx].wType = 0; /* aka unused2 */ 01105 pIpAddrTable->dwNumEntries++; 01106 } 01107 if (bOrder) 01108 qsort(pIpAddrTable->table, pIpAddrTable->dwNumEntries, 01109 sizeof(MIB_IPADDRROW), IpAddrTableSorter); 01110 ret = NO_ERROR; 01111 } 01112 free(table); 01113 } 01114 else 01115 ret = ERROR_OUTOFMEMORY; 01116 } 01117 } 01118 TRACE("returning %ld\n", ret); 01119 return ret; 01120 } 01121 01122 01123 static int IpForwardTableSorter(const void *a, const void *b) 01124 { 01125 int ret; 01126 01127 if (a && b) { 01128 PMIB_IPFORWARDROW rowA = (PMIB_IPFORWARDROW)a, rowB = (PMIB_IPFORWARDROW)b; 01129 01130 ret = rowA->dwForwardDest - rowB->dwForwardDest; 01131 if (ret == 0) { 01132 ret = rowA->dwForwardProto - rowB->dwForwardProto; 01133 if (ret == 0) { 01134 ret = rowA->dwForwardPolicy - rowB->dwForwardPolicy; 01135 if (ret == 0) 01136 ret = rowA->dwForwardNextHop - rowB->dwForwardNextHop; 01137 } 01138 } 01139 } 01140 else 01141 ret = 0; 01142 return ret; 01143 } 01144 01145 01146 /****************************************************************** 01147 * GetIpForwardTable (IPHLPAPI.@) 01148 * 01149 * 01150 * PARAMS 01151 * 01152 * pIpForwardTable [In/Out] 01153 * pdwSize [In/Out] 01154 * bOrder [In] 01155 * 01156 * RETURNS 01157 * 01158 * DWORD 01159 * 01160 */ 01161 DWORD WINAPI GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSize, BOOL bOrder) 01162 { 01163 DWORD ret; 01164 01165 TRACE("pIpForwardTable %p, pdwSize %p, bOrder %ld\n", pIpForwardTable, 01166 pdwSize, (DWORD)bOrder); 01167 if (!pdwSize) 01168 ret = ERROR_INVALID_PARAMETER; 01169 else { 01170 DWORD numRoutes = getNumRoutes(); 01171 ULONG sizeNeeded = sizeof(MIB_IPFORWARDTABLE) + (numRoutes - 1) * 01172 sizeof(MIB_IPFORWARDROW); 01173 01174 if (!pIpForwardTable || *pdwSize < sizeNeeded) { 01175 *pdwSize = sizeNeeded; 01176 ret = ERROR_INSUFFICIENT_BUFFER; 01177 } 01178 else { 01179 RouteTable *table = getRouteTable(); 01180 if (table) { 01181 sizeNeeded = sizeof(MIB_IPFORWARDTABLE) + (table->numRoutes - 1) * 01182 sizeof(MIB_IPFORWARDROW); 01183 if (*pdwSize < sizeNeeded) { 01184 *pdwSize = sizeNeeded; 01185 ret = ERROR_INSUFFICIENT_BUFFER; 01186 } 01187 else { 01188 DWORD ndx; 01189 01190 pIpForwardTable->dwNumEntries = table->numRoutes; 01191 for (ndx = 0; ndx < numRoutes; ndx++) { 01192 pIpForwardTable->table[ndx].dwForwardIfIndex = 01193 table->routes[ndx].ifIndex; 01194 pIpForwardTable->table[ndx].dwForwardDest = 01195 table->routes[ndx].dest; 01196 pIpForwardTable->table[ndx].dwForwardMask = 01197 table->routes[ndx].mask; 01198 pIpForwardTable->table[ndx].dwForwardPolicy = 0; 01199 pIpForwardTable->table[ndx].dwForwardNextHop = 01200 table->routes[ndx].gateway; 01201 /* FIXME: this type is appropriate for local interfaces; may not 01202 always be appropriate */ 01203 pIpForwardTable->table[ndx].dwForwardType = MIB_IPROUTE_TYPE_DIRECT; 01204 /* FIXME: other protos might be appropriate, e.g. the default route 01205 is typically set with MIB_IPPROTO_NETMGMT instead */ 01206 pIpForwardTable->table[ndx].dwForwardProto = MIB_IPPROTO_LOCAL; 01207 /* punt on age and AS */ 01208 pIpForwardTable->table[ndx].dwForwardAge = 0; 01209 pIpForwardTable->table[ndx].dwForwardNextHopAS = 0; 01210 pIpForwardTable->table[ndx].dwForwardMetric1 = 01211 table->routes[ndx].metric; 01212 /* rest of the metrics are 0.. */ 01213 pIpForwardTable->table[ndx].dwForwardMetric2 = 0; 01214 pIpForwardTable->table[ndx].dwForwardMetric3 = 0; 01215 pIpForwardTable->table[ndx].dwForwardMetric4 = 0; 01216 pIpForwardTable->table[ndx].dwForwardMetric5 = 0; 01217 } 01218 if (bOrder) 01219 qsort(pIpForwardTable->table, pIpForwardTable->dwNumEntries, 01220 sizeof(MIB_IPFORWARDROW), IpForwardTableSorter); 01221 ret = NO_ERROR; 01222 } 01223 HeapFree(GetProcessHeap(), 0, table); 01224 } 01225 else 01226 ret = ERROR_OUTOFMEMORY; 01227 } 01228 } 01229 TRACE("returning %ld\n", ret); 01230 return ret; 01231 } 01232 01233 01234 static int IpNetTableSorter(const void *a, const void *b) 01235 { 01236 int ret; 01237 01238 if (a && b) 01239 ret = ((PMIB_IPNETROW)a)->dwAddr - ((PMIB_IPNETROW)b)->dwAddr; 01240 else 01241 ret = 0; 01242 return ret; 01243 } 01244 01245 01246 /****************************************************************** 01247 * GetIpNetTable (IPHLPAPI.@) 01248 * 01249 * 01250 * PARAMS 01251 * 01252 * pIpNetTable [In/Out] 01253 * pdwSize [In/Out] 01254 * bOrder [In] 01255 * 01256 * RETURNS 01257 * 01258 * DWORD 01259 * 01260 */ 01261 DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize, BOOL bOrder) 01262 { 01263 DWORD ret = NO_ERROR; 01264 01265 TRACE("pIpNetTable %p, pdwSize %p, bOrder %d\n", pIpNetTable, pdwSize, 01266 (DWORD)bOrder); 01267 if (!pdwSize) 01268 ret = ERROR_INVALID_PARAMETER; 01269 else { 01270 DWORD numEntries = getNumArpEntries(); 01271 ULONG size = sizeof(MIB_IPNETTABLE); 01272 01273 if (numEntries > 1) 01274 size += (numEntries - 1) * sizeof(MIB_IPNETROW); 01275 if (!pIpNetTable || *pdwSize < size) { 01276 *pdwSize = size; 01277 ret = ERROR_INSUFFICIENT_BUFFER; 01278 } 01279 else { 01280 PMIB_IPNETTABLE table = getArpTable(); 01281 if (table) { 01282 size = sizeof(MIB_IPNETTABLE); 01283 if (table->dwNumEntries > 1) 01284 size += (table->dwNumEntries - 1) * sizeof(MIB_IPNETROW); 01285 if (*pdwSize < size) { 01286 *pdwSize = size; 01287 ret = ERROR_INSUFFICIENT_BUFFER; 01288 } 01289 else { 01290 *pdwSize = size; 01291 memcpy(pIpNetTable, table, size); 01292 if (bOrder) 01293 qsort(pIpNetTable->table, pIpNetTable->dwNumEntries, 01294 sizeof(MIB_IPNETROW), IpNetTableSorter); 01295 ret = NO_ERROR; 01296 } 01297 HeapFree(GetProcessHeap(), 0, table); 01298 } 01299 } 01300 } 01301 TRACE("returning %d\n", ret); 01302 return ret; 01303 } 01304 01305 01306 /****************************************************************** 01307 * GetIpStatistics (IPHLPAPI.@) 01308 * 01309 * 01310 * PARAMS 01311 * 01312 * pStats [In/Out] 01313 * 01314 * RETURNS 01315 * 01316 * DWORD 01317 * 01318 */ 01319 DWORD WINAPI GetIpStatistics(PMIB_IPSTATS pStats) 01320 { 01321 return GetIpStatisticsEx(pStats, PF_INET); 01322 } 01323 01324 /****************************************************************** 01325 * GetIpStatisticsEx (IPHLPAPI.@) 01326 * 01327 * 01328 * PARAMS 01329 * 01330 * pStats [In/Out] 01331 * dwFamily [In] 01332 * 01333 * RETURNS 01334 * 01335 * DWORD 01336 * 01337 */ 01338 DWORD WINAPI GetIpStatisticsEx(PMIB_IPSTATS pStats, DWORD dwFamily) 01339 { 01340 DWORD ret; 01341 01342 TRACE("pStats %p\n", pStats); 01343 ret = getIPStats(pStats, dwFamily); 01344 TRACE("returning %ld\n", ret); 01345 return ret; 01346 } 01347 01348 /****************************************************************** 01349 * GetNetworkParams (IPHLPAPI.@) 01350 * 01351 * 01352 * PARAMS 01353 * 01354 * pFixedInfo [In/Out] 01355 * pOutBufLen [In/Out] 01356 * 01357 * RETURNS 01358 * 01359 * DWORD 01360 * 01361 */ 01362 DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen) 01363 { 01364 DWORD ret, size; 01365 LONG regReturn; 01366 HKEY hKey; 01367 PIPHLP_RES_INFO resInfo; 01368 01369 TRACE("pFixedInfo %p, pOutBufLen %p\n", pFixedInfo, pOutBufLen); 01370 if (!pOutBufLen) 01371 return ERROR_INVALID_PARAMETER; 01372 01373 resInfo = getResInfo(); 01374 if (!resInfo) 01375 return ERROR_OUTOFMEMORY; 01376 01377 size = sizeof(FIXED_INFO) + (resInfo->riCount > 1 ? (resInfo->riCount-1) * 01378 sizeof(IP_ADDR_STRING) : 0); 01379 if (!pFixedInfo || *pOutBufLen < size) { 01380 *pOutBufLen = size; 01381 disposeResInfo( resInfo ); 01382 return ERROR_BUFFER_OVERFLOW; 01383 } 01384 01385 memset(pFixedInfo, 0, size); 01386 size = sizeof(pFixedInfo->HostName); 01387 GetComputerNameExA(ComputerNameDnsHostname, pFixedInfo->HostName, &size); 01388 size = sizeof(pFixedInfo->DomainName); 01389 GetComputerNameExA(ComputerNameDnsDomain, pFixedInfo->DomainName, &size); 01390 01391 TRACE("GetComputerNameExA: %s\n", pFixedInfo->DomainName); 01392 01393 if (resInfo->riCount > 0) 01394 { 01395 CopyMemory(&pFixedInfo->DnsServerList, resInfo->DnsList, sizeof(IP_ADDR_STRING)); 01396 if (resInfo->riCount > 1) 01397 { 01398 IP_ADDR_STRING *pSrc = resInfo->DnsList->Next; 01399 IP_ADDR_STRING *pTarget = (struct _IP_ADDR_STRING*)((char*)pFixedInfo + sizeof(FIXED_INFO)); 01400 01401 pFixedInfo->DnsServerList.Next = pTarget; 01402 01403 do 01404 { 01405 CopyMemory(pTarget, pSrc, sizeof(IP_ADDR_STRING)); 01406 resInfo->riCount--; 01407 if (resInfo->riCount > 1) 01408 { 01409 pTarget->Next = (IP_ADDR_STRING*)((char*)pTarget + sizeof(IP_ADDR_STRING)); 01410 pTarget = pTarget->Next; 01411 pSrc = pSrc->Next; 01412 } 01413 else 01414 { 01415 pTarget->Next = NULL; 01416 break; 01417 } 01418 } 01419 while(TRUE); 01420 } 01421 else 01422 { 01423 pFixedInfo->DnsServerList.Next = NULL; 01424 } 01425 } 01426 01427 pFixedInfo->NodeType = HYBRID_NODETYPE; 01428 regReturn = RegOpenKeyExA(HKEY_LOCAL_MACHINE, 01429 "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP", 0, KEY_READ, &hKey); 01430 if (regReturn != ERROR_SUCCESS) 01431 regReturn = RegOpenKeyExA(HKEY_LOCAL_MACHINE, 01432 "SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters", 0, KEY_READ, 01433 &hKey); 01434 if (regReturn == ERROR_SUCCESS) 01435 { 01436 DWORD size = sizeof(pFixedInfo->ScopeId); 01437 01438 RegQueryValueExA(hKey, "ScopeID", NULL, NULL, (PBYTE)pFixedInfo->ScopeId, &size); 01439 RegCloseKey(hKey); 01440 } 01441 01442 disposeResInfo( resInfo ); 01443 /* FIXME: can check whether routing's enabled in /proc/sys/net/ipv4/ip_forward 01444 I suppose could also check for a listener on port 53 to set EnableDns */ 01445 ret = NO_ERROR; 01446 TRACE("returning %ld\n", ret); 01447 01448 return ret; 01449 } 01450 01451 01452 /****************************************************************** 01453 * GetNumberOfInterfaces (IPHLPAPI.@) 01454 * 01455 * 01456 * PARAMS 01457 * 01458 * pdwNumIf [In/Out] 01459 * 01460 * RETURNS 01461 * 01462 * DWORD 01463 * 01464 */ 01465 DWORD WINAPI GetNumberOfInterfaces(PDWORD pdwNumIf) 01466 { 01467 DWORD ret; 01468 01469 TRACE("pdwNumIf %p\n", pdwNumIf); 01470 if (!pdwNumIf) 01471 ret = ERROR_INVALID_PARAMETER; 01472 else { 01473 *pdwNumIf = getNumInterfaces(); 01474 ret = NO_ERROR; 01475 } 01476 TRACE("returning %ld\n", ret); 01477 return ret; 01478 } 01479 01480 01481 /****************************************************************** 01482 * GetOwnerModuleFromTcpEntry (IPHLPAPI.@) 01483 * 01484 * Get data about the module that issued the context bind for a specific IPv4 TCP endpoint in a MIB table row 01485 * 01486 * PARAMS 01487 * pTcpEntry [in] pointer to a MIB_TCPROW_OWNER_MODULE structure 01488 * Class [in] TCPIP_OWNER_MODULE_INFO_CLASS enumeration value 01489 * Buffer [out] pointer a buffer containing a TCPIP_OWNER_MODULE_BASIC_INFO structure with the owner module data. 01490 * pdwSize [in, out] estimated size of the structure returned in Buffer, in bytes 01491 * 01492 * RETURNS 01493 * Success: NO_ERROR 01494 * Failure: ERROR_INSUFFICIENT_BUFFER, ERROR_INVALID_PARAMETER, ERROR_NOT_ENOUGH_MEMORY 01495 * ERROR_NOT_FOUND or ERROR_PARTIAL_COPY 01496 * 01497 * NOTES 01498 * The type of data returned in Buffer is indicated by the value of the Class parameter. 01499 */ 01500 DWORD WINAPI GetOwnerModuleFromTcpEntry( PMIB_TCPROW_OWNER_MODULE pTcpEntry, TCPIP_OWNER_MODULE_INFO_CLASS Class, PVOID Buffer, PDWORD pdwSize) 01501 { 01502 DWORD ret = NO_ERROR; 01503 UNIMPLEMENTED; 01504 return ret; 01505 } 01506 01507 01508 /****************************************************************** 01509 * GetPerAdapterInfo (IPHLPAPI.@) 01510 * 01511 * 01512 * PARAMS 01513 * 01514 * IfIndex [In] 01515 * pPerAdapterInfo [In/Out] 01516 * pOutBufLen [In/Out] 01517 * 01518 * RETURNS 01519 * 01520 * DWORD 01521 * 01522 */ 01523 static void CreateNameServerListEnumNamesFunc( PWCHAR Interface, PWCHAR Server, PVOID Data) 01524 { 01525 IP_ADDR_STRING *pNext; 01526 PNAME_SERVER_LIST_CONTEXT Context = (PNAME_SERVER_LIST_CONTEXT)Data; 01527 01528 if (!Context->NumServers) 01529 { 01530 if (Context->uSizeAvailable >= Context->uSizeRequired) 01531 { 01532 WideCharToMultiByte(CP_ACP, 0, Server, -1, Context->pData->DnsServerList.IpAddress.String, 16, NULL, NULL); 01533 Context->pData->DnsServerList.IpAddress.String[15] = '\0'; 01534 Context->pLastAddr = &Context->pData->DnsServerList; 01535 } 01536 } 01537 else 01538 { 01539 Context->uSizeRequired += sizeof(IP_ADDR_STRING); 01540 if (Context->uSizeAvailable >= Context->uSizeRequired) 01541 { 01542 pNext = (IP_ADDR_STRING*)(((char*)Context->pLastAddr) + sizeof(IP_ADDR_STRING)); 01543 WideCharToMultiByte(CP_ACP, 0, Server, -1, pNext->IpAddress.String, 16, NULL, NULL); 01544 pNext->IpAddress.String[15] = '\0'; 01545 Context->pLastAddr->Next = pNext; 01546 Context->pLastAddr = pNext; 01547 pNext->Next = NULL; 01548 } 01549 } 01550 Context->NumServers++; 01551 } 01552 01553 DWORD WINAPI GetPerAdapterInfo(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen) 01554 { 01555 HKEY hkey; 01556 DWORD dwSize = 0; 01557 const char *ifName; 01558 NAME_SERVER_LIST_CONTEXT Context; 01559 WCHAR keyname[200] = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"; 01560 01561 if (!pOutBufLen) 01562 return ERROR_INVALID_PARAMETER; 01563 01564 if (!pPerAdapterInfo || *pOutBufLen < sizeof(IP_PER_ADAPTER_INFO)) 01565 { 01566 *pOutBufLen = sizeof(IP_PER_ADAPTER_INFO); 01567 return ERROR_BUFFER_OVERFLOW; 01568 } 01569 01570 ifName = getInterfaceNameByIndex(IfIndex); 01571 if (!ifName) 01572 return ERROR_INVALID_PARAMETER; 01573 01574 MultiByteToWideChar(CP_ACP, 0, ifName, -1, &keyname[62], sizeof(keyname)/sizeof(WCHAR) - 63); 01575 HeapFree(GetProcessHeap(), 0, (LPVOID)ifName); 01576 01577 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &hkey) != ERROR_SUCCESS) 01578 { 01579 return ERROR_NOT_SUPPORTED; 01580 } 01581 Context.NumServers = 0; 01582 Context.uSizeAvailable = *pOutBufLen; 01583 Context.uSizeRequired = sizeof(IP_PER_ADAPTER_INFO); 01584 Context.pData = pPerAdapterInfo; 01585 01586 if (*pOutBufLen >= sizeof(IP_PER_ADAPTER_INFO)) 01587 ZeroMemory(pPerAdapterInfo, sizeof(IP_PER_ADAPTER_INFO)); 01588 01589 EnumNameServers(hkey, &keyname[62], &Context, CreateNameServerListEnumNamesFunc); 01590 01591 if (Context.uSizeRequired > Context.uSizeAvailable) 01592 { 01593 *pOutBufLen = Context.uSizeRequired; 01594 RegCloseKey(hkey); 01595 return ERROR_BUFFER_OVERFLOW; 01596 } 01597 01598 if(RegQueryValueExW(hkey, L"NameServer", NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS) 01599 { 01600 pPerAdapterInfo->AutoconfigActive = FALSE; 01601 } 01602 else 01603 { 01604 pPerAdapterInfo->AutoconfigActive = TRUE; 01605 } 01606 01607 RegCloseKey(hkey); 01608 return NOERROR; 01609 } 01610 01611 01612 /****************************************************************** 01613 * GetRTTAndHopCount (IPHLPAPI.@) 01614 * 01615 * 01616 * PARAMS 01617 * 01618 * DestIpAddress [In] 01619 * HopCount [In/Out] 01620 * MaxHops [In] 01621 * RTT [In/Out] 01622 * 01623 * RETURNS 01624 * 01625 * BOOL 01626 * 01627 */ 01628 BOOL WINAPI GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount, ULONG MaxHops, PULONG RTT) 01629 { 01630 TRACE("DestIpAddress 0x%08lx, HopCount %p, MaxHops %ld, RTT %p\n", 01631 DestIpAddress, HopCount, MaxHops, RTT); 01632 FIXME(":stub\n"); 01633 return (BOOL) 0; 01634 } 01635 01636 01637 /****************************************************************** 01638 * GetTcpStatisticsEx (IPHLPAPI.@) 01639 * 01640 * 01641 * PARAMS 01642 * 01643 * pStats [In/Out] 01644 * dwFamily [In] 01645 * 01646 * RETURNS 01647 * 01648 * DWORD 01649 * 01650 */ 01651 DWORD WINAPI GetTcpStatisticsEx(PMIB_TCPSTATS pStats, DWORD dwFamily) 01652 { 01653 DWORD ret; 01654 01655 TRACE("pStats %p\n", pStats); 01656 ret = getTCPStats(pStats, dwFamily); 01657 TRACE("returning %ld\n", ret); 01658 return ret; 01659 } 01660 01661 /****************************************************************** 01662 * GetTcpStatistics (IPHLPAPI.@) 01663 * 01664 * 01665 * PARAMS 01666 * 01667 * pStats [In/Out] 01668 * 01669 * RETURNS 01670 * 01671 * DWORD 01672 * 01673 */ 01674 DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS pStats) 01675 { 01676 return GetTcpStatisticsEx(pStats, PF_INET); 01677 } 01678 01679 01680 static int TcpTableSorter(const void *a, const void *b) 01681 { 01682 int ret; 01683 01684 if (a && b) { 01685 PMIB_TCPROW rowA = (PMIB_TCPROW)a, rowB = (PMIB_TCPROW)b; 01686 01687 ret = rowA->dwLocalAddr - rowB->dwLocalAddr; 01688 if (ret == 0) { 01689 ret = rowA->dwLocalPort - rowB->dwLocalPort; 01690 if (ret == 0) { 01691 ret = rowA->dwRemoteAddr - rowB->dwRemoteAddr; 01692 if (ret == 0) 01693 ret = rowA->dwRemotePort - rowB->dwRemotePort; 01694 } 01695 } 01696 } 01697 else 01698 ret = 0; 01699 return ret; 01700 } 01701 01702 01703 /****************************************************************** 01704 * GetTcpTable (IPHLPAPI.@) 01705 * 01706 * Get the table of active TCP connections. 01707 * 01708 * PARAMS 01709 * pTcpTable [Out] buffer for TCP connections table 01710 * pdwSize [In/Out] length of output buffer 01711 * bOrder [In] whether to order the table 01712 * 01713 * RETURNS 01714 * Success: NO_ERROR 01715 * Failure: error code from winerror.h 01716 * 01717 * NOTES 01718 * If pdwSize is less than required, the function will return 01719 * ERROR_INSUFFICIENT_BUFFER, and *pdwSize will be set to 01720 * the required byte size. 01721 * If bOrder is true, the returned table will be sorted, first by 01722 * local address and port number, then by remote address and port 01723 * number. 01724 */ 01725 DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder) 01726 { 01727 DWORD ret = ERROR_NO_DATA; 01728 01729 TRACE("pTcpTable %p, pdwSize %p, bOrder %d\n", pTcpTable, pdwSize, 01730 (DWORD)bOrder); 01731 if (!pdwSize) 01732 ret = ERROR_INVALID_PARAMETER; 01733 else { 01734 DWORD numEntries = getNumTcpEntries(); 01735 DWORD size = sizeof(MIB_TCPTABLE); 01736 01737 if (numEntries > 1) 01738 size += (numEntries - 1) * sizeof(MIB_TCPROW); 01739 if (!pTcpTable || *pdwSize < size) { 01740 *pdwSize = size; 01741 ret = ERROR_INSUFFICIENT_BUFFER; 01742 } 01743 else { 01744 PMIB_TCPTABLE pOurTcpTable = getTcpTable(); 01745 if (pOurTcpTable) 01746 { 01747 size = sizeof(MIB_TCPTABLE); 01748 if (pOurTcpTable->dwNumEntries > 1) 01749 size += (pOurTcpTable->dwNumEntries - 1) * sizeof(MIB_TCPROW); 01750 01751 if (*pdwSize < size) 01752 { 01753 *pdwSize = size; 01754 01755 ret = ERROR_INSUFFICIENT_BUFFER; 01756 } 01757 else 01758 { 01759 memcpy(pTcpTable, pOurTcpTable, size); 01760 01761 if (bOrder) 01762 qsort(pTcpTable->table, pTcpTable->dwNumEntries, 01763 sizeof(MIB_TCPROW), TcpTableSorter); 01764 01765 ret = NO_ERROR; 01766 } 01767 01768 free(pOurTcpTable); 01769 } 01770 } 01771 } 01772 TRACE("returning %d\n", ret); 01773 return ret; 01774 } 01775 01776 01777 /****************************************************************** 01778 * GetUdpStatisticsEx (IPHLPAPI.@) 01779 * 01780 * 01781 * PARAMS 01782 * 01783 * pStats [In/Out] 01784 * dwFamily [In] 01785 * 01786 * RETURNS 01787 * 01788 * DWORD 01789 * 01790 */ 01791 DWORD WINAPI GetUdpStatisticsEx(PMIB_UDPSTATS pStats, DWORD dwFamily) 01792 { 01793 DWORD ret; 01794 01795 TRACE("pStats %p\n", pStats); 01796 ret = getUDPStats(pStats, dwFamily); 01797 TRACE("returning %ld\n", ret); 01798 return ret; 01799 } 01800 01801 /****************************************************************** 01802 * GetUdpStatistics (IPHLPAPI.@) 01803 * 01804 * 01805 * PARAMS 01806 * 01807 * pStats [In/Out] 01808 * 01809 * RETURNS 01810 * 01811 * DWORD 01812 * 01813 */ 01814 DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS pStats) 01815 { 01816 return GetUdpStatisticsEx(pStats, PF_INET); 01817 } 01818 01819 01820 static int UdpTableSorter(const void *a, const void *b) 01821 { 01822 int ret; 01823 01824 if (a && b) { 01825 PMIB_UDPROW rowA = (PMIB_UDPROW)a, rowB = (PMIB_UDPROW)b; 01826 01827 ret = rowA->dwLocalAddr - rowB->dwLocalAddr; 01828 if (ret == 0) 01829 ret = rowA->dwLocalPort - rowB->dwLocalPort; 01830 } 01831 else 01832 ret = 0; 01833 return ret; 01834 } 01835 01836 01837 /****************************************************************** 01838 * GetUdpTable (IPHLPAPI.@) 01839 * 01840 * 01841 * PARAMS 01842 * 01843 * pUdpTable [In/Out] 01844 * pdwSize [In/Out] 01845 * bOrder [In] 01846 * 01847 * RETURNS 01848 * 01849 * DWORD 01850 * 01851 */ 01852 DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder) 01853 { 01854 DWORD ret; 01855 01856 TRACE("pUdpTable %p, pdwSize %p, bOrder %ld\n", pUdpTable, pdwSize, 01857 (DWORD)bOrder); 01858 if (!pdwSize) 01859 ret = ERROR_INVALID_PARAMETER; 01860 else { 01861 DWORD numEntries = getNumUdpEntries(); 01862 ULONG size = sizeof(MIB_UDPTABLE) + (numEntries - 1) * sizeof(MIB_UDPROW); 01863 01864 if (!pUdpTable || *pdwSize < size) { 01865 *pdwSize = size; 01866 ret = ERROR_INSUFFICIENT_BUFFER; 01867 } 01868 else { 01869 PMIB_UDPTABLE table = getUdpTable(); 01870 01871 if (table) { 01872 size = sizeof(MIB_UDPTABLE) + (table->dwNumEntries - 1) * 01873 sizeof(MIB_UDPROW); 01874 if (*pdwSize < size) { 01875 *pdwSize = size; 01876 ret = ERROR_INSUFFICIENT_BUFFER; 01877 } 01878 else { 01879 memcpy(pUdpTable, table, size); 01880 if (bOrder) 01881 qsort(pUdpTable->table, pUdpTable->dwNumEntries, 01882 sizeof(MIB_UDPROW), UdpTableSorter); 01883 ret = NO_ERROR; 01884 } 01885 free(table); 01886 } 01887 else 01888 ret = ERROR_OUTOFMEMORY; 01889 } 01890 } 01891 TRACE("returning %ld\n", ret); 01892 return ret; 01893 } 01894 01895 01896 /****************************************************************** 01897 * GetUniDirectionalAdapterInfo (IPHLPAPI.@) 01898 * 01899 * This is a Win98-only function to get information on "unidirectional" 01900 * adapters. Since this is pretty nonsensical in other contexts, it 01901 * never returns anything. 01902 * 01903 * PARAMS 01904 * pIPIfInfo [Out] buffer for adapter infos 01905 * dwOutBufLen [Out] length of the output buffer 01906 * 01907 * RETURNS 01908 * Success: NO_ERROR 01909 * Failure: error code from winerror.h 01910 * 01911 * FIXME 01912 * Stub, returns ERROR_NOT_SUPPORTED. 01913 */ 01914 DWORD WINAPI GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo, PULONG dwOutBufLen) 01915 { 01916 TRACE("pIPIfInfo %p, dwOutBufLen %p\n", pIPIfInfo, dwOutBufLen); 01917 /* a unidirectional adapter?? not bloody likely! */ 01918 return ERROR_NOT_SUPPORTED; 01919 } 01920 01921 01922 /****************************************************************** 01923 * IpReleaseAddress (IPHLPAPI.@) 01924 * 01925 * Release an IP obtained through DHCP, 01926 * 01927 * PARAMS 01928 * AdapterInfo [In] adapter to release IP address 01929 * 01930 * RETURNS 01931 * Success: NO_ERROR 01932 * Failure: error code from winerror.h 01933 * 01934 */ 01935 DWORD WINAPI IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo) 01936 { 01937 DWORD Status, Version = 0; 01938 01939 if (!AdapterInfo || !AdapterInfo->Name) 01940 return ERROR_INVALID_PARAMETER; 01941 01942 /* Maybe we should do this in DllMain */ 01943 if (DhcpCApiInitialize(&Version) != ERROR_SUCCESS) 01944 return ERROR_PROC_NOT_FOUND; 01945 01946 if (DhcpReleaseIpAddressLease(AdapterInfo->Index)) 01947 Status = ERROR_SUCCESS; 01948 else 01949 Status = ERROR_PROC_NOT_FOUND; 01950 01951 DhcpCApiCleanup(); 01952 01953 return Status; 01954 } 01955 01956 01957 /****************************************************************** 01958 * IpRenewAddress (IPHLPAPI.@) 01959 * 01960 * Renew an IP obtained through DHCP. 01961 * 01962 * PARAMS 01963 * AdapterInfo [In] adapter to renew IP address 01964 * 01965 * RETURNS 01966 * Success: NO_ERROR 01967 * Failure: error code from winerror.h 01968 */ 01969 DWORD WINAPI IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo) 01970 { 01971 DWORD Status, Version = 0; 01972 01973 if (!AdapterInfo || !AdapterInfo->Name) 01974 return ERROR_INVALID_PARAMETER; 01975 01976 /* Maybe we should do this in DllMain */ 01977 if (DhcpCApiInitialize(&Version) != ERROR_SUCCESS) 01978 return ERROR_PROC_NOT_FOUND; 01979 01980 if (DhcpRenewIpAddressLease(AdapterInfo->Index)) 01981 Status = ERROR_SUCCESS; 01982 else 01983 Status = ERROR_PROC_NOT_FOUND; 01984 01985 DhcpCApiCleanup(); 01986 01987 return Status; 01988 } 01989 01990 01991 /****************************************************************** 01992 * NotifyAddrChange (IPHLPAPI.@) 01993 * 01994 * Notify caller whenever the ip-interface map is changed. 01995 * 01996 * PARAMS 01997 * Handle [Out] handle usable in asynchronous notification 01998 * overlapped [In] overlapped structure that notifies the caller 01999 * 02000 * RETURNS 02001 * Success: NO_ERROR 02002 * Failure: error code from winerror.h 02003 * 02004 * FIXME 02005 * Stub, returns ERROR_NOT_SUPPORTED. 02006 */ 02007 DWORD WINAPI NotifyAddrChange(PHANDLE Handle, LPOVERLAPPED overlapped) 02008 { 02009 FIXME("(Handle %p, overlapped %p): stub\n", Handle, overlapped); 02010 return ERROR_NOT_SUPPORTED; 02011 } 02012 02013 02014 /****************************************************************** 02015 * NotifyRouteChange (IPHLPAPI.@) 02016 * 02017 * Notify caller whenever the ip routing table is changed. 02018 * 02019 * PARAMS 02020 * Handle [Out] handle usable in asynchronous notification 02021 * overlapped [In] overlapped structure that notifies the caller 02022 * 02023 * RETURNS 02024 * Success: NO_ERROR 02025 * Failure: error code from winerror.h 02026 * 02027 * FIXME 02028 * Stub, returns ERROR_NOT_SUPPORTED. 02029 */ 02030 DWORD WINAPI NotifyRouteChange(PHANDLE Handle, LPOVERLAPPED overlapped) 02031 { 02032 FIXME("(Handle %p, overlapped %p): stub\n", Handle, overlapped); 02033 return ERROR_NOT_SUPPORTED; 02034 } 02035 02036 02037 /****************************************************************** 02038 * SendARP (IPHLPAPI.@) 02039 * 02040 * Send an ARP request. 02041 * 02042 * PARAMS 02043 * DestIP [In] attempt to obtain this IP 02044 * SrcIP [In] optional sender IP address 02045 * pMacAddr [Out] buffer for the mac address 02046 * PhyAddrLen [In/Out] length of the output buffer 02047 * 02048 * RETURNS 02049 * Success: NO_ERROR 02050 * Failure: error code from winerror.h 02051 * 02052 * FIXME 02053 * Stub, returns ERROR_NOT_SUPPORTED. 02054 */ 02055 DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen) 02056 { 02057 FIXME("(DestIP 0x%08x, SrcIP 0x%08x, pMacAddr %p, PhyAddrLen %p): stub\n", 02058 DestIP, SrcIP, pMacAddr, PhyAddrLen); 02059 return ERROR_NOT_SUPPORTED; 02060 } 02061 02062 02063 /****************************************************************** 02064 * SetIfEntry (IPHLPAPI.@) 02065 * 02066 * Set the administrative status of an interface. 02067 * 02068 * PARAMS 02069 * pIfRow [In] dwAdminStatus member specifies the new status. 02070 * 02071 * RETURNS 02072 * Success: NO_ERROR 02073 * Failure: error code from winerror.h 02074 * 02075 * FIXME 02076 * Stub, returns ERROR_NOT_SUPPORTED. 02077 */ 02078 DWORD WINAPI SetIfEntry(PMIB_IFROW pIfRow) 02079 { 02080 FIXME("(pIfRow %p): stub\n", pIfRow); 02081 /* this is supposed to set an interface administratively up or down. 02082 Could do SIOCSIFFLAGS and set/clear IFF_UP, but, not sure I want to, and 02083 this sort of down is indistinguishable from other sorts of down (e.g. no 02084 link). */ 02085 return ERROR_NOT_SUPPORTED; 02086 } 02087 02088 02089 /****************************************************************** 02090 * SetIpForwardEntry (IPHLPAPI.@) 02091 * 02092 * Modify an existing route. 02093 * 02094 * PARAMS 02095 * pRoute [In] route with the new information 02096 * 02097 * RETURNS 02098 * Success: NO_ERROR 02099 * Failure: error code from winerror.h 02100 * 02101 */ 02102 DWORD WINAPI SetIpForwardEntry(PMIB_IPFORWARDROW pRoute) 02103 { 02104 return setIpForwardEntry( pRoute ); 02105 } 02106 02107 02108 /****************************************************************** 02109 * SetIpNetEntry (IPHLPAPI.@) 02110 * 02111 * Modify an existing ARP entry. 02112 * 02113 * PARAMS 02114 * pArpEntry [In] ARP entry with the new information 02115 * 02116 * RETURNS 02117 * Success: NO_ERROR 02118 * Failure: error code from winerror.h 02119 */ 02120 DWORD WINAPI SetIpNetEntry(PMIB_IPNETROW pArpEntry) 02121 { 02122 HANDLE tcpFile; 02123 NTSTATUS status; 02124 TCP_REQUEST_SET_INFORMATION_EX_ARP_ENTRY req = 02125 TCP_REQUEST_SET_INFORMATION_INIT; 02126 TDIEntityID id; 02127 DWORD returnSize; 02128 PMIB_IPNETROW arpBuff; 02129 02130 if (!pArpEntry) 02131 return ERROR_INVALID_PARAMETER; 02132 02133 if (!NT_SUCCESS(openTcpFile( &tcpFile ))) 02134 return ERROR_NOT_SUPPORTED; 02135 02136 if (!NT_SUCCESS(getNthIpEntity( tcpFile, pArpEntry->dwIndex, &id ))) 02137 { 02138 closeTcpFile(tcpFile); 02139 return ERROR_INVALID_PARAMETER; 02140 } 02141 02142 req.Req.ID.toi_class = INFO_CLASS_PROTOCOL; 02143 req.Req.ID.toi_type = INFO_TYPE_PROVIDER; 02144 req.Req.ID.toi_id = IP_MIB_ARPTABLE_ENTRY_ID; 02145 req.Req.ID.toi_entity.tei_instance = id.tei_instance; 02146 req.Req.ID.toi_entity.tei_entity = AT_ENTITY; 02147 req.Req.BufferSize = sizeof(MIB_IPNETROW); 02148 arpBuff = (PMIB_IPNETROW)&req.Req.Buffer[0]; 02149 02150 RtlCopyMemory(arpBuff, pArpEntry, sizeof(MIB_IPNETROW)); 02151 02152 status = DeviceIoControl( tcpFile, 02153 IOCTL_TCP_SET_INFORMATION_EX, 02154 &req, 02155 sizeof(req), 02156 NULL, 02157 0, 02158 &returnSize, 02159 NULL ); 02160 02161 closeTcpFile(tcpFile); 02162 02163 if (status) 02164 return NO_ERROR; 02165 else 02166 return ERROR_INVALID_PARAMETER; 02167 } 02168 02169 02170 /****************************************************************** 02171 * SetIpStatistics (IPHLPAPI.@) 02172 * 02173 * Toggle IP forwarding and det the default TTL value. 02174 * 02175 * PARAMS 02176 * pIpStats [In] IP statistics with the new information 02177 * 02178 * RETURNS 02179 * Success: NO_ERROR 02180 * Failure: error code from winerror.h 02181 * 02182 * FIXME 02183 * Stub, returns NO_ERROR. 02184 */ 02185 DWORD WINAPI SetIpStatistics(PMIB_IPSTATS pIpStats) 02186 { 02187 FIXME("(pIpStats %p): stub\n", pIpStats); 02188 return 0; 02189 } 02190 02191 02192 /****************************************************************** 02193 * SetIpTTL (IPHLPAPI.@) 02194 * 02195 * Set the default TTL value. 02196 * 02197 * PARAMS 02198 * nTTL [In] new TTL value 02199 * 02200 * RETURNS 02201 * Success: NO_ERROR 02202 * Failure: error code from winerror.h 02203 * 02204 * FIXME 02205 * Stub, returns NO_ERROR. 02206 */ 02207 DWORD WINAPI SetIpTTL(UINT nTTL) 02208 { 02209 FIXME("(nTTL %d): stub\n", nTTL); 02210 return 0; 02211 } 02212 02213 02214 /****************************************************************** 02215 * SetTcpEntry (IPHLPAPI.@) 02216 * 02217 * Set the state of a TCP connection. 02218 * 02219 * PARAMS 02220 * pTcpRow [In] specifies connection with new state 02221 * 02222 * RETURNS 02223 * Success: NO_ERROR 02224 * Failure: error code from winerror.h 02225 * 02226 * FIXME 02227 * Stub, returns NO_ERROR. 02228 */ 02229 DWORD WINAPI SetTcpEntry(PMIB_TCPROW pTcpRow) 02230 { 02231 FIXME("(pTcpRow %p): stub\n", pTcpRow); 02232 return 0; 02233 } 02234 02235 02236 /****************************************************************** 02237 * UnenableRouter (IPHLPAPI.@) 02238 * 02239 * Decrement the IP-forwarding reference count. Turn off IP-forwarding 02240 * if it reaches zero. 02241 * 02242 * PARAMS 02243 * pOverlapped [In/Out] should be the same as in EnableRouter() 02244 * lpdwEnableCount [Out] optional, receives reference count 02245 * 02246 * RETURNS 02247 * Success: NO_ERROR 02248 * Failure: error code from winerror.h 02249 * 02250 * FIXME 02251 * Stub, returns ERROR_NOT_SUPPORTED. 02252 */ 02253 DWORD WINAPI UnenableRouter(OVERLAPPED * pOverlapped, LPDWORD lpdwEnableCount) 02254 { 02255 FIXME("(pOverlapped %p, lpdwEnableCount %p): stub\n", pOverlapped, 02256 lpdwEnableCount); 02257 return ERROR_NOT_SUPPORTED; 02258 } 02259 02260 /* 02261 * @unimplemented 02262 */ 02263 DWORD WINAPI GetIpErrorString(IP_STATUS ErrorCode,PWCHAR Buffer,PDWORD Size) 02264 { 02265 FIXME(":stub\n"); 02266 return 0L; 02267 } 02268 02269 02270 /* 02271 * @unimplemented 02272 */ 02273 PIP_ADAPTER_ORDER_MAP WINAPI GetAdapterOrderMap(VOID) 02274 { 02275 FIXME(":stub\n"); 02276 return 0L; 02277 } 02278 02279 /* 02280 * @implemented 02281 */ 02282 DWORD WINAPI GetAdaptersAddresses(ULONG Family,ULONG Flags,PVOID Reserved,PIP_ADAPTER_ADDRESSES pAdapterAddresses,PULONG pOutBufLen) 02283 { 02284 #if 0 02285 InterfaceIndexTable *indexTable; 02286 IFInfo ifInfo; 02287 int i; 02288 ULONG ret, requiredSize = 0; 02289 PIP_ADAPTER_ADDRESSES currentAddress; 02290 PUCHAR currentLocation; 02291 HANDLE tcpFile; 02292 02293 if (!pOutBufLen) return ERROR_INVALID_PARAMETER; 02294 if (Reserved) return ERROR_INVALID_PARAMETER; 02295 02296 indexTable = getNonLoopbackInterfaceIndexTable(); //I think we want non-loopback here 02297 if (!indexTable) 02298 return ERROR_NOT_ENOUGH_MEMORY; 02299 02300 ret = openTcpFile(&tcpFile); 02301 if (!NT_SUCCESS(ret)) 02302 return ERROR_NO_DATA; 02303 02304 for (i = indexTable->numIndexes; i >= 0; i--) 02305 { 02306 if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile, 02307 NULL, 02308 indexTable->indexes[i], 02309 &ifInfo))) 02310 { 02311 /* The whole struct */ 02312 requiredSize += sizeof(IP_ADAPTER_ADDRESSES); 02313 02314 /* Friendly name */ 02315 if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME)) 02316 requiredSize += strlen((char *)ifInfo.if_info.ent.if_descr) + 1; //FIXME 02317 02318 /* Adapter name */ 02319 requiredSize += strlen((char *)ifInfo.if_info.ent.if_descr) + 1; 02320 02321 /* Unicast address */ 02322 if (!(Flags & GAA_FLAG_SKIP_UNICAST)) 02323 requiredSize += sizeof(IP_ADAPTER_UNICAST_ADDRESS); 02324 02325 /* FIXME: Implement multicast, anycast, and dns server stuff */ 02326 02327 /* FIXME: Implement dns suffix and description */ 02328 requiredSize += 2 * sizeof(WCHAR); 02329 02330 /* We're only going to implement what's required for XP SP0 */ 02331 } 02332 } 02333 02334 if (*pOutBufLen < requiredSize) 02335 { 02336 *pOutBufLen = requiredSize; 02337 closeTcpFile(tcpFile); 02338 free(indexTable); 02339 return ERROR_BUFFER_OVERFLOW; 02340 } 02341 02342 RtlZeroMemory(pAdapterAddresses, requiredSize); 02343 02344 /* Let's set up the pointers */ 02345 currentAddress = pAdapterAddresses; 02346 for (i = indexTable->numIndexes; i >= 0; i--) 02347 { 02348 if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile, 02349 NULL, 02350 indexTable->indexes[i], 02351 &ifInfo))) 02352 { 02353 currentLocation = (PUCHAR)currentAddress + (ULONG_PTR)sizeof(IP_ADAPTER_ADDRESSES); 02354 02355 /* FIXME: Friendly name */ 02356 if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME)) 02357 { 02358 currentAddress->FriendlyName = (PVOID)currentLocation; 02359 currentLocation += sizeof(WCHAR); 02360 } 02361 02362 /* Adapter name */ 02363 currentAddress->AdapterName = (PVOID)currentLocation; 02364 currentLocation += strlen((char *)ifInfo.if_info.ent.if_descr) + 1; 02365 02366 /* Unicast address */ 02367 if (!(Flags & GAA_FLAG_SKIP_UNICAST)) 02368 { 02369 currentAddress->FirstUnicastAddress = (PVOID)currentLocation; 02370 currentLocation += sizeof(IP_ADAPTER_UNICAST_ADDRESS); 02371 currentAddress->FirstUnicastAddress->Address.lpSockaddr = (PVOID)currentLocation; 02372 currentLocation += sizeof(struct sockaddr); 02373 } 02374 02375 /* FIXME: Implement multicast, anycast, and dns server stuff */ 02376 02377 /* FIXME: Implement dns suffix and description */ 02378 currentAddress->DnsSuffix = (PVOID)currentLocation; 02379 currentLocation += sizeof(WCHAR); 02380 02381 currentAddress->Description = (PVOID)currentLocation; 02382 currentLocation += sizeof(WCHAR); 02383 02384 currentAddress->Next = (PVOID)currentLocation; 02385 02386 /* We're only going to implement what's required for XP SP0 */ 02387 02388 currentAddress = currentAddress->Next; 02389 } 02390 } 02391 02392 /* Terminate the last address correctly */ 02393 if (currentAddress) 02394 currentAddress->Next = NULL; 02395 02396 /* Now again, for real this time */ 02397 02398 currentAddress = pAdapterAddresses; 02399 for (i = indexTable->numIndexes; i >= 0; i--) 02400 { 02401 if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile, 02402 NULL, 02403 indexTable->indexes[i], 02404 &ifInfo))) 02405 { 02406 /* Make sure we're not looping more than we hoped for */ 02407 ASSERT(currentAddress); 02408 02409 /* Alignment information */ 02410 currentAddress->Length = sizeof(IP_ADAPTER_ADDRESSES); 02411 currentAddress->IfIndex = indexTable->indexes[i]; 02412 02413 /* Adapter name */ 02414 strcpy(currentAddress->AdapterName, (char *)ifInfo.if_info.ent.if_descr); 02415 02416 if (!(Flags & GAA_FLAG_SKIP_UNICAST)) 02417 { 02418 currentAddress->FirstUnicastAddress->Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS); 02419 currentAddress->FirstUnicastAddress->Flags = 0; //FIXME 02420 currentAddress->FirstUnicastAddress->Next = NULL; //FIXME: Support more than one address per adapter 02421 currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_family = AF_INET; 02422 memcpy(currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_data, 02423 &ifInfo.ip_addr.iae_addr, 02424 sizeof(ifInfo.ip_addr.iae_addr)); 02425 currentAddress->FirstUnicastAddress->Address.iSockaddrLength = sizeof(ifInfo.ip_addr.iae_addr) + sizeof(USHORT); 02426 currentAddress->FirstUnicastAddress->PrefixOrigin = IpPrefixOriginOther; //FIXME 02427 currentAddress->FirstUnicastAddress->SuffixOrigin = IpPrefixOriginOther; //FIXME 02428 currentAddress->FirstUnicastAddress->DadState = IpDadStatePreferred; //FIXME 02429 currentAddress->FirstUnicastAddress->ValidLifetime = 0xFFFFFFFF; //FIXME 02430 currentAddress->FirstUnicastAddress->PreferredLifetime = 0xFFFFFFFF; //FIXME 02431 currentAddress->FirstUnicastAddress->LeaseLifetime = 0xFFFFFFFF; //FIXME 02432 } 02433 02434 /* FIXME: Implement multicast, anycast, and dns server stuff */ 02435 currentAddress->FirstAnycastAddress = NULL; 02436 currentAddress->FirstMulticastAddress = NULL; 02437 currentAddress->FirstDnsServerAddress = NULL; 02438 02439 /* FIXME: Implement dns suffix, description, and friendly name */ 02440 currentAddress->DnsSuffix[0] = UNICODE_NULL; 02441 currentAddress->Description[0] = UNICODE_NULL; 02442 currentAddress->FriendlyName[0] = UNICODE_NULL; 02443 02444 /* Physical Address */ 02445 memcpy(currentAddress->PhysicalAddress, ifInfo.if_info.ent.if_physaddr, ifInfo.if_info.ent.if_physaddrlen); 02446 currentAddress->PhysicalAddressLength = ifInfo.if_info.ent.if_physaddrlen; 02447 02448 /* Flags */ 02449 currentAddress->Flags = 0; //FIXME 02450 02451 /* MTU */ 02452 currentAddress->Mtu = ifInfo.if_info.ent.if_mtu; 02453 02454 /* Interface type */ 02455 currentAddress->IfType = ifInfo.if_info.ent.if_type; 02456 02457 /* Operational status */ 02458 currentAddress->OperStatus = ifInfo.if_info.ent.if_operstatus; 02459 02460 /* We're only going to implement what's required for XP SP0 */ 02461 02462 /* Move to the next address */ 02463 currentAddress = currentAddress->Next; 02464 } 02465 } 02466 02467 closeTcpFile(tcpFile); 02468 free(indexTable); 02469 02470 return NO_ERROR; 02471 #else 02472 if (!pOutBufLen) return ERROR_INVALID_PARAMETER; 02473 if (!pAdapterAddresses || *pOutBufLen == 0) 02474 return ERROR_BUFFER_OVERFLOW; 02475 if (Reserved) return ERROR_INVALID_PARAMETER; 02476 02477 FIXME(":stub\n"); 02478 return ERROR_NO_DATA; 02479 #endif 02480 } 02481 02482 /* 02483 * @unimplemented 02484 */ 02485 BOOL WINAPI CancelIPChangeNotify(LPOVERLAPPED notifyOverlapped) 02486 { 02487 FIXME(":stub\n"); 02488 return 0L; 02489 } 02490 02491 /* 02492 * @unimplemented 02493 */ 02494 DWORD WINAPI GetBestInterfaceEx(struct sockaddr *pDestAddr,PDWORD pdwBestIfIndex) 02495 { 02496 FIXME(":stub\n"); 02497 return 0L; 02498 } 02499 02500 /* 02501 * @unimplemented 02502 */ 02503 DWORD WINAPI NhpAllocateAndGetInterfaceInfoFromStack(IP_INTERFACE_NAME_INFO **ppTable,PDWORD pdwCount,BOOL bOrder,HANDLE hHeap,DWORD dwFlags) 02504 { 02505 FIXME(":stub\n"); 02506 return 0L; 02507 } 02508 02509 /* 02510 * @unimplemented 02511 */ 02512 DWORD WINAPI GetIcmpStatisticsEx(PMIB_ICMP_EX pStats,DWORD dwFamily) 02513 { 02514 FIXME(":stub\n"); 02515 return 0L; 02516 } 02517 02518 /****************************************************************** 02519 * GetIfTable2 (IPHLPAPI.@) 02520 * 02521 * PARAMS 02522 * pIfTable [In/Out] 02523 */ 02524 02525 NETIOAPI_API WINAPI GetIfTable2(PMIB_IF_TABLE2 *pIfTable) 02526 { 02527 UNIMPLEMENTED; 02528 return ERROR_NOT_SUPPORTED; 02529 } 02530 02531 /****************************************************************** 02532 * GetIfEntry2 (IPHLPAPI.@) 02533 * 02534 * PARAMS 02535 * pIfRow [In/Out] 02536 */ 02537 NETIOAPI_API WINAPI GetIfEntry2(IN OUT PMIB_IF_ROW2 pIfRow) 02538 { 02539 TRACE("pIfRow %p\n", pIfRow); 02540 if (!pIfRow) 02541 return ERROR_INVALID_PARAMETER; 02542 02543 UNIMPLEMENTED; 02544 return ERROR_NOT_SUPPORTED; 02545 } 02546 02547 DWORD WINAPI 02548 SetIpForwardEntryToStack(PMIB_IPFORWARDROW pRoute) 02549 { 02550 FIXME("SetIpForwardEntryToStack() stub\n"); 02551 return 0L; 02552 } 02553 02554 DWORD WINAPI 02555 NhGetInterfaceNameFromDeviceGuid(DWORD dwUnknown1, 02556 DWORD dwUnknown2, 02557 DWORD dwUnknown3, 02558 DWORD dwUnknown4, 02559 DWORD dwUnknown5) 02560 { 02561 FIXME("NhGetInterfaceNameFromDeviceGuid() stub\n"); 02562 return 0L; 02563 } Generated on Sat May 26 2012 04:22:42 for ReactOS by
1.7.6.1
|