[IPHLPAPI] Don't leak memory
[reactos.git] / dll / win32 / iphlpapi / iphlpapi_main.c
index 75be6ca..404c1b7 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <config.h>
 #include "iphlpapi_private.h"
+#include <strsafe.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
 
@@ -35,17 +36,13 @@ typedef struct _NAME_SERVER_LIST_CONTEXT {
 
 BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
-  WSADATA wsaData;
-
   switch (fdwReason) {
     case DLL_PROCESS_ATTACH:
       DisableThreadLibraryCalls( hinstDLL );
       interfaceMapInit();
-      WSAStartup(MAKEWORD(2, 2), &wsaData);
       break;
 
     case DLL_PROCESS_DETACH:
-      WSACleanup();
       interfaceMapFree();
       break;
   }
@@ -117,10 +114,15 @@ DWORD WINAPI AllocateAndGetIfTableFromStack(PMIB_IFTABLE *ppIfTable,
   else {
     DWORD dwSize = 0;
 
+    *ppIfTable = NULL;
     ret = GetIfTable(*ppIfTable, &dwSize, bOrder);
     if (ret == ERROR_INSUFFICIENT_BUFFER) {
       *ppIfTable = (PMIB_IFTABLE)HeapAlloc(heap, flags, dwSize);
       ret = GetIfTable(*ppIfTable, &dwSize, bOrder);
+      if (ret != NO_ERROR) {
+        HeapFree(heap, flags, *ppIfTable);
+        *ppIfTable = NULL;
+      }
     }
   }
   TRACE("returning %ld\n", ret);
@@ -156,10 +158,15 @@ DWORD WINAPI AllocateAndGetIpAddrTableFromStack(PMIB_IPADDRTABLE *ppIpAddrTable,
   else {
     DWORD dwSize = 0;
 
+    *ppIpAddrTable = NULL;
     ret = GetIpAddrTable(*ppIpAddrTable, &dwSize, bOrder);
     if (ret == ERROR_INSUFFICIENT_BUFFER) {
       *ppIpAddrTable = (PMIB_IPADDRTABLE)HeapAlloc(heap, flags, dwSize);
       ret = GetIpAddrTable(*ppIpAddrTable, &dwSize, bOrder);
+      if (ret != NO_ERROR) {
+        HeapFree(heap, flags, *ppIpAddrTable);
+        *ppIpAddrTable = NULL;
+      }
     }
   }
   TRACE("returning %ld\n", ret);
@@ -193,10 +200,15 @@ DWORD WINAPI AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE *
   else {
     DWORD dwSize = 0;
 
+    *ppIpForwardTable = NULL;
     ret = GetIpForwardTable(*ppIpForwardTable, &dwSize, bOrder);
     if (ret == ERROR_INSUFFICIENT_BUFFER) {
       *ppIpForwardTable = (PMIB_IPFORWARDTABLE)HeapAlloc(heap, flags, dwSize);
       ret = GetIpForwardTable(*ppIpForwardTable, &dwSize, bOrder);
+      if (ret != NO_ERROR) {
+        HeapFree(heap, flags, *ppIpForwardTable);
+        *ppIpForwardTable = NULL;
+      }
     }
   }
   TRACE("returning %ld\n", ret);
@@ -232,10 +244,15 @@ DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable,
   else {
     DWORD dwSize = 0;
 
+    *ppIpNetTable = NULL;
     ret = GetIpNetTable(*ppIpNetTable, &dwSize, bOrder);
     if (ret == ERROR_INSUFFICIENT_BUFFER) {
       *ppIpNetTable = (PMIB_IPNETTABLE)HeapAlloc(heap, flags, dwSize);
       ret = GetIpNetTable(*ppIpNetTable, &dwSize, bOrder);
+      if (ret != NO_ERROR) {
+        HeapFree(heap, flags, *ppIpNetTable);
+        *ppIpNetTable = NULL;
+      }
     }
   }
   TRACE("returning %ld\n", ret);
@@ -271,10 +288,15 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack(PMIB_TCPTABLE *ppTcpTable,
   else {
     DWORD dwSize = 0;
 
+    *ppTcpTable = NULL;
     ret = GetTcpTable(*ppTcpTable, &dwSize, bOrder);
     if (ret == ERROR_INSUFFICIENT_BUFFER) {
       *ppTcpTable = (PMIB_TCPTABLE)HeapAlloc(heap, flags, dwSize);
       ret = GetTcpTable(*ppTcpTable, &dwSize, bOrder);
+      if (ret != NO_ERROR) {
+        HeapFree(heap, flags, *ppTcpTable);
+        *ppTcpTable = NULL;
+      }
     }
   }
   TRACE("returning %ld\n", ret);
@@ -310,10 +332,15 @@ DWORD WINAPI AllocateAndGetUdpTableFromStack(PMIB_UDPTABLE *ppUdpTable,
   else {
     DWORD dwSize = 0;
 
+    *ppUdpTable = NULL;
     ret = GetUdpTable(*ppUdpTable, &dwSize, bOrder);
     if (ret == ERROR_INSUFFICIENT_BUFFER) {
       *ppUdpTable = (PMIB_UDPTABLE)HeapAlloc(heap, flags, dwSize);
       ret = GetUdpTable(*ppUdpTable, &dwSize, bOrder);
+      if (ret != NO_ERROR) {
+        HeapFree(heap, flags, *ppUdpTable);
+        *ppUdpTable = NULL;
+      }
     }
   }
   TRACE("returning %ld\n", ret);
@@ -740,18 +767,19 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDRO
 
   AllocateAndGetIpForwardTableFromStack(&table, FALSE, GetProcessHeap(), 0);
   if (table) {
-    DWORD ndx, matchedBits, matchedNdx = 0;
+    DWORD ndx, minMaskSize, matchedNdx = 0;
 
-    for (ndx = 0, matchedBits = 0; ndx < table->dwNumEntries; ndx++) {
+    for (ndx = 0, minMaskSize = 255; ndx < table->dwNumEntries; ndx++) {
       if ((dwDestAddr & table->table[ndx].dwForwardMask) ==
        (table->table[ndx].dwForwardDest & table->table[ndx].dwForwardMask)) {
-        DWORD numShifts, mask;
+        DWORD hostMaskSize;
 
-        for (numShifts = 0, mask = table->table[ndx].dwForwardMask;
-         mask && !(mask & 1); mask >>= 1, numShifts++)
-          ;
-        if (numShifts > matchedBits) {
-          matchedBits = numShifts;
+        if (!_BitScanForward(&hostMaskSize, ntohl(table->table[ndx].dwForwardMask)))
+        {
+            hostMaskSize = 32;
+        }
+        if (hostMaskSize < minMaskSize) {
+          minMaskSize = hostMaskSize;
           matchedNdx = ndx;
         }
       }
@@ -766,6 +794,8 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDRO
   return ret;
 }
 
+static int TcpTableSorter(const void *a, const void *b);
+
 /******************************************************************
  *    GetExtendedTcpTable (IPHLPAPI.@)
  *
@@ -788,20 +818,237 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDRO
 
 DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, TCP_TABLE_CLASS TableClass, ULONG Reserved)
 {
+    DWORD i, count;
        DWORD ret = NO_ERROR;
 
-  if (TableClass == TCP_TABLE_OWNER_PID_ALL) {
-    if (*pdwSize == 0) {
-      *pdwSize = sizeof(MIB_TCPTABLE_OWNER_PID);
-      return ERROR_INSUFFICIENT_BUFFER; 
-    } else {
-      ZeroMemory(pTcpTable, sizeof(MIB_TCPTABLE_OWNER_PID));
-      return NO_ERROR;
+    if (!pdwSize)
+    {
+        return ERROR_INVALID_PARAMETER;
     }
-  }
 
+    if (ulAf != AF_INET)
+    {
+        UNIMPLEMENTED;
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    switch (TableClass)
+    {
+        case TCP_TABLE_BASIC_ALL:
+            ret = GetTcpTable(pTcpTable, pdwSize, bOrder);
+            break;
+
+        case TCP_TABLE_BASIC_CONNECTIONS:
+        {
+            PMIB_TCPTABLE pOurTcpTable = getTcpTable();
+            PMIB_TCPTABLE pTheirTcpTable = pTcpTable;
+
+            if (pOurTcpTable)
+            {
+                for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+                {
+                    if (pOurTcpTable->table[i].State != MIB_TCP_STATE_LISTEN)
+                    {
+                        ++count;
+                    }
+                }
+
+                if (sizeof(MIB_TCPTABLE) + count * sizeof(MIB_TCPROW) > *pdwSize || !pTheirTcpTable)
+                {
+                    *pdwSize = sizeof(MIB_TCPTABLE) + count * sizeof(MIB_TCPROW);
+                    ret = ERROR_INSUFFICIENT_BUFFER;
+                }
+                else
+                {
+                    pTheirTcpTable->dwNumEntries = count;
+
+                    for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+                    {
+                        if (pOurTcpTable->table[i].State != MIB_TCP_STATE_LISTEN)
+                        {
+                            memcpy(&pTheirTcpTable->table[count], &pOurTcpTable->table[i], sizeof(MIB_TCPROW));
+                            ++count;
+                        }
+                    }
+                    ASSERT(count == pTheirTcpTable->dwNumEntries);
+
+                    if (bOrder)
+                        qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries,
+                              sizeof(MIB_TCPROW), TcpTableSorter);
+                }
+
+                free(pOurTcpTable);
+            }
+        }
+        break;
+
+        case TCP_TABLE_BASIC_LISTENER:
+        {
+            PMIB_TCPTABLE pOurTcpTable = getTcpTable();
+            PMIB_TCPTABLE pTheirTcpTable = pTcpTable;
+
+            if (pOurTcpTable)
+            {
+                for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+                {
+                    if (pOurTcpTable->table[i].State == MIB_TCP_STATE_LISTEN)
+                    {
+                        ++count;
+                    }
+                }
+
+                if (sizeof(MIB_TCPTABLE) + count * sizeof(MIB_TCPROW) > *pdwSize || !pTheirTcpTable)
+                {
+                    *pdwSize = sizeof(MIB_TCPTABLE) + count * sizeof(MIB_TCPROW);
+                    ret = ERROR_INSUFFICIENT_BUFFER;
+                }
+                else
+                {
+                    pTheirTcpTable->dwNumEntries = count;
+
+                    for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+                    {
+                        if (pOurTcpTable->table[i].State == MIB_TCP_STATE_LISTEN)
+                        {
+                            memcpy(&pTheirTcpTable->table[count], &pOurTcpTable->table[i], sizeof(MIB_TCPROW));
+                            ++count;
+                        }
+                    }
+                    ASSERT(count == pTheirTcpTable->dwNumEntries);
+
+                    if (bOrder)
+                        qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries,
+                              sizeof(MIB_TCPROW), TcpTableSorter);
+                }
+
+                free(pOurTcpTable);
+            }
+        }
+        break;
+
+        case TCP_TABLE_OWNER_PID_ALL:
+        {
+            PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getOwnerTcpTable();
+            PMIB_TCPTABLE_OWNER_PID pTheirTcpTable = pTcpTable;
+
+            if (pOurTcpTable)
+            {
+                if (sizeof(DWORD) + pOurTcpTable->dwNumEntries * sizeof(MIB_TCPROW_OWNER_PID) > *pdwSize || !pTheirTcpTable)
+                {
+                    *pdwSize = sizeof(DWORD) + pOurTcpTable->dwNumEntries * sizeof(MIB_TCPROW_OWNER_PID);
+                    ret = ERROR_INSUFFICIENT_BUFFER;
+                }
+                else
+                {
+                    memcpy(pTheirTcpTable, pOurTcpTable, sizeof(DWORD) + pOurTcpTable->dwNumEntries * sizeof(MIB_TCPROW_OWNER_PID));
+
+                    /* Don't sort on PID, so use basic helper */
+                    if (bOrder)
+                        qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries,
+                              sizeof(MIB_TCPROW_OWNER_PID), TcpTableSorter);
+                }
+
+                free(pOurTcpTable);
+            }
+        }
+        break;
+
+        case TCP_TABLE_OWNER_PID_CONNECTIONS:
+        {
+            PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getOwnerTcpTable();
+            PMIB_TCPTABLE_OWNER_PID pTheirTcpTable = pTcpTable;
+
+            if (pOurTcpTable)
+            {
+                for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+                {
+                    if (pOurTcpTable->table[i].dwState != MIB_TCP_STATE_LISTEN)
+                    {
+                        ++count;
+                    }
+                }
+
+                if (sizeof(DWORD) + count * sizeof(MIB_TCPROW_OWNER_PID) > *pdwSize || !pTheirTcpTable)
+                {
+                    *pdwSize = sizeof(DWORD) + count * sizeof(MIB_TCPROW_OWNER_PID);
+                    ret = ERROR_INSUFFICIENT_BUFFER;
+                }
+                else
+                {
+                    pTheirTcpTable->dwNumEntries = count;
+
+                    for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+                    {
+                        if (pOurTcpTable->table[i].dwState != MIB_TCP_STATE_LISTEN)
+                        {
+                            memcpy(&pTheirTcpTable->table[count], &pOurTcpTable->table[i], sizeof(MIB_TCPROW_OWNER_PID));
+                            ++count;
+                        }
+                    }
+                    ASSERT(count == pTheirTcpTable->dwNumEntries);
+
+                    /* Don't sort on PID, so use basic helper */
+                    if (bOrder)
+                        qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries,
+                              sizeof(MIB_TCPROW_OWNER_PID), TcpTableSorter);
+                }
+
+                free(pOurTcpTable);
+            }
+        }
+        break;
+
+        case TCP_TABLE_OWNER_PID_LISTENER:
+        {
+            PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getOwnerTcpTable();
+            PMIB_TCPTABLE_OWNER_PID pTheirTcpTable = pTcpTable;
+
+            if (pOurTcpTable)
+            {
+                for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+                {
+                    if (pOurTcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN)
+                    {
+                        ++count;
+                    }
+                }
+
+                if (sizeof(DWORD) + count * sizeof(MIB_TCPROW_OWNER_PID) > *pdwSize || !pTheirTcpTable)
+                {
+                    *pdwSize = sizeof(DWORD) + count * sizeof(MIB_TCPROW_OWNER_PID);
+                    ret = ERROR_INSUFFICIENT_BUFFER;
+                }
+                else
+                {
+                    pTheirTcpTable->dwNumEntries = count;
+
+                    for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+                    {
+                        if (pOurTcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN)
+                        {
+                            memcpy(&pTheirTcpTable->table[count], &pOurTcpTable->table[i], sizeof(MIB_TCPROW_OWNER_PID));
+                            ++count;
+                        }
+                    }
+                    ASSERT(count == pTheirTcpTable->dwNumEntries);
+
+                    /* Don't sort on PID, so use basic helper */
+                    if (bOrder)
+                        qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries,
+                              sizeof(MIB_TCPROW_OWNER_PID), TcpTableSorter);
+                }
+
+                free(pOurTcpTable);
+            }
+        }
+        break;
+
+        default:
+            UNIMPLEMENTED;
+            ret = ERROR_INVALID_PARAMETER;
+            break;
+    }
 
-    UNIMPLEMENTED;
     return ret;        
 }
 
@@ -1378,7 +1625,7 @@ DWORD WINAPI GetIpStatisticsEx(PMIB_IPSTATS pStats, DWORD dwFamily)
  */
 DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen)
 {
-  DWORD ret, size;
+  DWORD ret, size, type;
   LONG regReturn;
   HKEY hKey;
   PIPHLP_RES_INFO resInfo;
@@ -1400,10 +1647,59 @@ DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen)
   }
 
   memset(pFixedInfo, 0, size);
-  size = sizeof(pFixedInfo->HostName);
-  GetComputerNameExA(ComputerNameDnsHostname, pFixedInfo->HostName, &size);
-  size = sizeof(pFixedInfo->DomainName);
-  GetComputerNameExA(ComputerNameDnsDomain, pFixedInfo->DomainName, &size);
+  /* Check for DhcpHostname and DhcpDomain first */
+  regReturn = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
+                            "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+                            0,
+                            KEY_READ,
+                            &hKey);
+  if (regReturn == ERROR_SUCCESS) {
+      /* Windows doesn't honor DHCP option 12 even if RFC requires it if it is returned by DHCP server! */
+#if 0
+      type = REG_SZ;
+      size = sizeof(pFixedInfo->HostName);
+      regReturn = RegQueryValueExA(hKey,
+                                      "DhcpHostname",
+                                      NULL,
+                                      &type,
+                                      (LPBYTE)pFixedInfo->HostName,
+                                      &size);
+      if (regReturn == ERROR_FILE_NOT_FOUND || (regReturn == ERROR_SUCCESS && size < 1))
+      {
+#endif
+          type = REG_SZ;
+          size = sizeof(pFixedInfo->HostName);
+          regReturn = RegQueryValueExA(hKey,
+                                          "Hostname",
+                                          NULL,
+                                          &type,
+                                          (LPBYTE)pFixedInfo->HostName,
+                                          &size);
+#if 0
+      }
+#endif
+
+      type = REG_SZ;
+      size = sizeof(pFixedInfo->DomainName);
+      regReturn = RegQueryValueExA(hKey,
+                                      "DhcpDomain",
+                                      NULL,
+                                      &type,
+                                      (LPBYTE)pFixedInfo->DomainName,
+                                      &size);
+      if (regReturn == ERROR_FILE_NOT_FOUND || (regReturn == ERROR_SUCCESS && size < 1))
+      {
+          type = REG_SZ;
+          size = sizeof(pFixedInfo->DomainName);
+          regReturn = RegQueryValueExA(hKey,
+                                          "Domain",
+                                          NULL,
+                                          &type,
+                                          (LPBYTE)pFixedInfo->DomainName,
+                                          &size);
+      }
+      RegCloseKey(hKey);
+  }
 
   TRACE("GetComputerNameExA: %s\n", pFixedInfo->DomainName);
 
@@ -1952,7 +2248,7 @@ DWORD WINAPI IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
 {
   DWORD Status, Version = 0;
 
-  if (!AdapterInfo || !AdapterInfo->Name)
+  if (!AdapterInfo)
       return ERROR_INVALID_PARAMETER;
 
   /* Maybe we should do this in DllMain */
@@ -1986,7 +2282,7 @@ DWORD WINAPI IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
 {
   DWORD Status, Version = 0;
 
-  if (!AdapterInfo || !AdapterInfo->Name)
+  if (!AdapterInfo)
       return ERROR_INVALID_PARAMETER;
 
   /* Maybe we should do this in DllMain */
@@ -2544,13 +2840,96 @@ SetIpForwardEntryToStack(PMIB_IPFORWARDROW pRoute)
     return 0L;
 }
 
+DWORD GetInterfaceNameInternal(_In_ const GUID * pInterfaceGUID,
+                               _Out_writes_bytes_to_(*pOutBufLen, *pOutBufLen) PWCHAR pInterfaceName,
+                               _Inout_ PULONG pOutBufLen)
+{
+    UNICODE_STRING GuidString;
+    DWORD result, type;
+    WCHAR szKeyName[2*MAX_PATH];
+    HRESULT hr;
+    HKEY hKey;
+
+    if (pInterfaceGUID == NULL || pOutBufLen == NULL)
+        return ERROR_INVALID_PARAMETER;
+
+    result = RtlStringFromGUID(pInterfaceGUID, &GuidString);
+
+    if (!NT_SUCCESS(result))
+    {
+        // failed to convert guid to string
+        return RtlNtStatusToDosError(result);
+    }
+
+    hr = StringCbPrintfW(szKeyName, sizeof(szKeyName), L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", GuidString.Buffer);
+    RtlFreeUnicodeString(&GuidString);
+
+    if (FAILED(hr))
+    {
+        // key name is too long
+        return ERROR_BUFFER_OVERFLOW;
+    }
+
+    result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_READ, &hKey);
+
+    if (result != ERROR_SUCCESS)
+    {
+        // failed to find adapter entry
+        return ERROR_NOT_FOUND;
+    }
+
+    result = RegQueryValueExW(hKey, L"Name", NULL, &type, (PVOID)pInterfaceName, pOutBufLen);
+
+    RegCloseKey(hKey);
+
+    if (result == ERROR_MORE_DATA)
+    {
+        *pOutBufLen = MAX_INTERFACE_NAME_LEN * 2;
+        return ERROR_INSUFFICIENT_BUFFER;
+    }
+
+    if (result != ERROR_SUCCESS || type != REG_SZ)
+    {
+        // failed to read adapter name
+        return ERROR_NO_DATA;
+    }
+    return ERROR_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
 DWORD WINAPI
-NhGetInterfaceNameFromDeviceGuid(DWORD dwUnknown1,
-                                 DWORD dwUnknown2,
-                                 DWORD dwUnknown3,
+NhGetInterfaceNameFromDeviceGuid(_In_ const GUID * pInterfaceGUID,
+                                 _Out_writes_bytes_to_(*pOutBufLen, *pOutBufLen) PWCHAR pInterfaceName,
+                                 _Inout_ PULONG pOutBufLen,
                                  DWORD dwUnknown4,
                                  DWORD dwUnknown5)
 {
-    FIXME("NhGetInterfaceNameFromDeviceGuid() stub\n");
-    return 0L;
+    SetLastError(ERROR_SUCCESS);
+
+    if (pInterfaceName == NULL)
+        return ERROR_INVALID_PARAMETER;
+
+    return GetInterfaceNameInternal(pInterfaceGUID, pInterfaceName, pOutBufLen);
+}
+
+/*
+ * @implemented
+ */
+DWORD WINAPI
+NhGetInterfaceNameFromGuid(_In_ const GUID * pInterfaceGUID,
+                           _Out_writes_bytes_to_(*pOutBufLen, *pOutBufLen) PWCHAR pInterfaceName,
+                           _Inout_ PULONG pOutBufLen,
+                           DWORD dwUnknown4,
+                           DWORD dwUnknown5)
+{
+    DWORD result;
+
+    result = GetInterfaceNameInternal(pInterfaceGUID, pInterfaceName, pOutBufLen);
+
+    if (result == ERROR_NOT_FOUND)
+        SetLastError(ERROR_PATH_NOT_FOUND);
+
+    return result;
 }