Use iphlpapi to enumerate LAN adapters.
Add names to NetBIOS transports, and eliminates loopback adapters from
enumerated LAN adapters.

diff --git a/dlls/netapi32/Makefile.in b/dlls/netapi32/Makefile.in
index 31c8304..67663f7 100644
--- a/dlls/netapi32/Makefile.in
+++ b/dlls/netapi32/Makefile.in
@@ -4,7 +4,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = netapi32.dll
-IMPORTS   = advapi32 kernel32
+IMPORTS   = iphlpapi advapi32 kernel32
 
 LDDLLFLAGS = @LDDLLFLAGS@
 SYMBOLFILE = $(MODULE).tmp.o
diff --git a/dlls/netapi32/netapi32.c b/dlls/netapi32/netapi32.c
index 73cea52..8d1f192 100644
--- a/dlls/netapi32/netapi32.c
+++ b/dlls/netapi32/netapi32.c
@@ -20,6 +20,7 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <fcntl.h>
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
@@ -33,183 +34,73 @@
 #include "winerror.h"
 #include "nb30.h"
 #include "lmcons.h"
-
-#ifdef HAVE_SYS_FILE_H
-# include <sys/file.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_SOCKIO_H
-# include <sys/sockio.h>
-#endif
-#ifdef HAVE_NET_IF_H
-# include <net/if.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-#  ifndef max
-#   define max(a,b) ((a) > (b) ? (a) : (b))
-#  endif
-#  define ifreq_size(i) max(sizeof(struct ifreq),\
-sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
-# else
-#  define ifreq_size(i) sizeof(struct ifreq)
-# endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+#include "iphlpapi.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(netbios);
 
 HMODULE NETAPI32_hModule = 0;
 
-struct NetBiosAdapter
-{
-    int valid;
-    unsigned char address[6];
-};
-
-static struct NetBiosAdapter NETBIOS_Adapter[MAX_LANA];
-
-# ifdef SIOCGIFHWADDR
-int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
-{
-    if (ioctl(sd, SIOCGIFHWADDR, ifr) < 0)
-        return -1;
-    memcpy(address, (unsigned char *)&ifr->ifr_hwaddr.sa_data, 6);
-    return 0;
-}
-# else
-#  ifdef SIOCGENADDR
-int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
-{
-    if (ioctl(sd, SIOCGENADDR, ifr) < 0)
-        return -1;
-    memcpy(address, (unsigned char *) ifr->ifr_enaddr, 6);
-    return 0;
-}
-#   else
-int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
-{
-    return -1;
-}
-#  endif /* SIOCGENADDR */
-# endif /* SIOCGIFHWADDR */
-
-int enum_hw(void)
-{
-    int ret = 0;
-#ifdef HAVE_NET_IF_H
-    int             sd;
-    struct ifreq    ifr, *ifrp;
-    struct ifconf   ifc;
-    unsigned char   buf[1024];
-    int             i, ofs;
-    /* BSD 4.4 defines the size of an ifreq to be
-     * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
-     * However, under earlier systems, sa_len isn't present, so
-     *  the size is just sizeof(struct ifreq)
-     */
-
-    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
-    if (sd < 0)
-        return NRC_OPENERROR;
-
-    memset(buf, 0, sizeof(buf));
-    ifc.ifc_len = sizeof(buf);
-    ifc.ifc_buf = buf;
-    /* get the ifconf interface */
-    if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0)
-    {
-        close(sd);
-        return NRC_OPENERROR;
-    }
-
-    /* loop through the interfaces, looking for a valid one */
-    /* n = ifc.ifc_len; */
-    ofs = 0;
-    for (i = 0; i < ifc.ifc_len; i++)
-    {
-        unsigned char *a = NETBIOS_Adapter[i].address;
-
-        ifrp = (struct ifreq *)((char *)ifc.ifc_buf+ofs);
-        strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
-
-        /* try to get the address for this interface */
-        if(get_hw_address(sd, &ifr, a)==0)
-        {
-            /* make sure it's not blank */
-            /* if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
-	        continue; */
-
-            TRACE("Found valid adapter %d at %02x:%02x:%02x:%02x:%02x:%02x\n", i,
-                        a[0],a[1],a[2],a[3],a[4],a[5]);
-
-            NETBIOS_Adapter[i].valid = TRUE;
-
-	    ret++;
-        }
-        ofs += ifreq_size(ifr);
-    }
-    close(sd);
-    TRACE("found %d adapters\n",ret);
-#endif /* HAVE_NET_IF_H */
-    return ret;
-}
-
-void wprint_mac(WCHAR* buffer, int index)
-{
-  int i;
-  unsigned char  val;
-  for (i = 0; i<6; i++)
-    {
-      val = NETBIOS_Adapter[index].address[i];
-      if ((val >>4) >9)
-	buffer[2*i] = (WCHAR)((val >>4) + 'A' - 10);
-      else
-	buffer[2*i] = (WCHAR)((val >>4) + '0');
-      if ((val & 0xf ) >9)
-	buffer[2*i+1] = (WCHAR)((val & 0xf) + 'A' - 10);
-      else
-	buffer[2*i+1] = (WCHAR)((val & 0xf) + '0');
-    }
-  buffer[12]=(WCHAR)0;
-      
-}
 static UCHAR NETBIOS_Enum(PNCB ncb)
 {
     int             i;
     LANA_ENUM *lanas = (PLANA_ENUM) ncb->ncb_buffer;
-
+    DWORD apiReturn, size = 0;
+    PMIB_IFTABLE table;
+    UCHAR ret;
+ 
     TRACE("NCBENUM\n");
-
-    lanas->length = 0;
-    for (i = 0; i < enum_hw(); i++)
-    {
-         lanas->lana[lanas->length] = i;
-	 lanas->length++;
-    }
-    return NRC_GOODRET;
+ 
+    apiReturn = GetIfTable(NULL, &size, FALSE);
+    if (apiReturn != NO_ERROR)
+      {
+        table = (PMIB_IFTABLE)malloc(size);
+        if (table)
+          {
+            apiReturn = GetIfTable(table, &size, FALSE);
+            if (apiReturn == NO_ERROR)
+              {
+                lanas->length = 0;
+                for (i = 0; i < table->dwNumEntries && lanas->length < MAX_LANA;
+                 i++)
+                  {
+                    if (table->table[i].dwType != MIB_IF_TYPE_LOOPBACK)
+                      {
+                        lanas->lana[lanas->length] = table->table[i].dwIndex;
+                        lanas->length++;
+                      }
+                  }
+                ret = NRC_GOODRET;
+              }
+            else
+                ret = NRC_SYSTEM;
+            free(table);
+          }
+        else
+            ret = NRC_NORESOURCES;
+      }
+    else
+        ret = NRC_SYSTEM;
+    return ret;
 }
 
 
 static UCHAR NETBIOS_Astat(PNCB ncb)
 {
-    struct NetBiosAdapter *nad = &NETBIOS_Adapter[ncb->ncb_lana_num];
     PADAPTER_STATUS astat = (PADAPTER_STATUS) ncb->ncb_buffer;
-
+    MIB_IFROW row;
+  
     TRACE("NCBASTAT (Adapter %d)\n", ncb->ncb_lana_num);
-
-    if(!nad->valid)
-        return NRC_INVADDRESS;
-
+  
     memset(astat, 0, sizeof astat);
-    memcpy(astat->adapter_address, nad->address, sizeof astat->adapter_address);
-
+  
+    row.dwIndex = ncb->ncb_lana_num;
+    if (GetIfEntry(&row) != NO_ERROR)
+        return NRC_INVADDRESS;
+    /* doubt anyone cares, but why not.. */
+    if (row.dwType == MIB_IF_TYPE_TOKENRING)
+        astat->adapter_type = 0xff;
+    else
+        astat->adapter_type = 0xfe; /* for Ethernet */
     return NRC_GOODRET;
 }
 
@@ -241,9 +132,16 @@
     {
     case NCBRESET:
         FIXME("NCBRESET adapter %d\n",pncb->ncb_lana_num);
-        if( (pncb->ncb_lana_num < MAX_LANA ) &&
-             NETBIOS_Adapter[pncb->ncb_lana_num].valid)
-            ret = NRC_GOODRET;
+        if(pncb->ncb_lana_num < MAX_LANA )
+          {
+            MIB_IFROW row;
+
+            row.dwIndex = pncb->ncb_lana_num;
+            if (GetIfEntry(&row) != NO_ERROR)
+                ret = NRC_GOODRET;
+            else
+                ret = NRC_ILLCMD; /* NetBIOS emulator not found */
+          }
         else
             ret = NRC_ILLCMD; /* NetBIOS emulator not found */
         break;
diff --git a/dlls/netapi32/wksta.c b/dlls/netapi32/wksta.c
index 8908f8a..32adb7c 100644
--- a/dlls/netapi32/wksta.c
+++ b/dlls/netapi32/wksta.c
@@ -18,12 +18,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <stdlib.h>
 #include "winbase.h"
 #include "nb30.h"
 #include "lmcons.h"
 #include "lmapibuf.h"
 #include "lmerr.h"
 #include "lmwksta.h"
+#include "iphlpapi.h"
 #include "winerror.h"
 #include "winternl.h"
 #include "ntsecapi.h"
@@ -59,8 +61,53 @@
     }
 }
 
-int enum_hw(void);
-void wprint_mac(WCHAR* buffer, int index);
+static void wprint_mac(WCHAR* buffer, PIP_ADAPTER_INFO adapter)
+{
+  if (adapter != NULL)
+    {
+      int i;
+      unsigned char  val;
+
+      for (i = 0; i<max(adapter->AddressLength, 6); i++)
+        {
+          val = adapter->Address[i];
+          if ((val >>4) >9)
+            buffer[2*i] = (WCHAR)((val >>4) + 'A' - 10);
+          else
+            buffer[2*i] = (WCHAR)((val >>4) + '0');
+          if ((val & 0xf ) >9)
+            buffer[2*i+1] = (WCHAR)((val & 0xf) + 'A' - 10);
+          else
+            buffer[2*i+1] = (WCHAR)((val & 0xf) + '0');
+        }
+      buffer[12]=(WCHAR)0;
+    }
+  else
+    buffer[0] = 0;
+}
+
+#define TRANSPORT_NAME_HEADER "\\Device\\NetBT_Tcpip_"
+#define TRANSPORT_NAME_LEN \
+ (sizeof(TRANSPORT_NAME_HEADER) + MAX_ADAPTER_NAME_LENGTH)
+
+static void wprint_name(WCHAR *buffer, int len, PIP_ADAPTER_INFO adapter)
+{
+  WCHAR *ptr;
+  const char *name;
+
+  if (!buffer)
+    return;
+  if (!adapter)
+    return;
+
+  for (ptr = buffer, name = TRANSPORT_NAME_HEADER; *name && ptr < buffer + len;
+   ptr++, name++)
+    *ptr = *name;
+  for (name = adapter->AdapterName; name && *name && ptr < buffer + len;
+   ptr++, name++)
+    *ptr = *name;
+  *ptr = '\0';
+}
 
 NET_API_STATUS WINAPI 
 NetWkstaTransportEnum(LPCWSTR ServerName, DWORD level, LPBYTE* pbuf,
@@ -84,49 +131,73 @@
 	
       switch (level)
 	{
-	case 0: /* transport info */
-	  {
-	    PWKSTA_TRANSPORT_INFO_0 ti;
-	    int i,size_needed,n_adapt  = enum_hw();
-	    
-	    if (n_adapt == 0)
+  	case 0: /* transport info */
+  	  {
+  	    PWKSTA_TRANSPORT_INFO_0 ti;
+	    int i,size_needed,n_adapt;
+            DWORD apiReturn, adaptInfoSize = 0;
+            PIP_ADAPTER_INFO info, ptr;
+  	    
+            apiReturn = GetAdaptersInfo(NULL, &adaptInfoSize);
+	    if (apiReturn == ERROR_NO_DATA)
               return ERROR_NETWORK_UNREACHABLE;
 	    if (!read_entries)
               return STATUS_ACCESS_VIOLATION;
 	    if (!total_entries || !pbuf)
               return RPC_X_NULL_REF_POINTER;
-	    
-	    size_needed = n_adapt * (sizeof(WKSTA_TRANSPORT_INFO_0) 
-				     * 13 * sizeof (WCHAR));
-	    if (prefmaxlen == MAX_PREFERRED_LENGTH)
-	      NetApiBufferAllocate( size_needed, (LPVOID *) pbuf);
-	    else
-	      {
-		if (size_needed > prefmaxlen)
-		  return ERROR_MORE_DATA;
-		NetApiBufferAllocate(prefmaxlen,
-				     (LPVOID *) pbuf);
-	      }
-	    for (i = 0; i <n_adapt; i++)
-	      {
-		ti = (PWKSTA_TRANSPORT_INFO_0) 
-		  ((PBYTE) *pbuf + i * sizeof(WKSTA_TRANSPORT_INFO_0));
-		ti->wkti0_quality_of_service=0;
-		ti->wkti0_number_of_vcs=0;
-		ti->wkti0_transport_name=NULL;
-		ti->wkti0_transport_address= (LPWSTR)
-		  ((PBYTE )*pbuf + n_adapt* sizeof(WKSTA_TRANSPORT_INFO_0) 
-		   + i * 13 * sizeof (WCHAR));
-		ti->wkti0_wan_ish=TRUE; /*TCPIP/NETBIOS Protocoll*/
-		wprint_mac(ti->wkti0_transport_address,i);
-		TRACE("%d of %d:ti at %p transport_address at %p %s\n",i,n_adapt,
-		      ti, ti->wkti0_transport_address, debugstr_w(ti->wkti0_transport_address));
-	      }
+
+            info = (PIP_ADAPTER_INFO)malloc(adaptInfoSize);
+            apiReturn = GetAdaptersInfo(info, &adaptInfoSize);
+            if (apiReturn != NO_ERROR)
+              {
+                free(info);
+                return apiReturn;
+              }
+
+            for (n_adapt = 0, ptr = info; ptr; ptr = ptr->Next)
+              n_adapt++;
+  	    size_needed = n_adapt * (sizeof(WKSTA_TRANSPORT_INFO_0) 
+	     + n_adapt * TRANSPORT_NAME_LEN * sizeof (WCHAR)
+	     + n_adapt * 13 * sizeof (WCHAR));
+  	    if (prefmaxlen == MAX_PREFERRED_LENGTH)
+  	      NetApiBufferAllocate( size_needed, (LPVOID *) pbuf);
+  	    else
+  	      {
+  		if (size_needed > prefmaxlen)
+                  {
+                    free(info);
+		    return ERROR_MORE_DATA;
+                  }
+  		NetApiBufferAllocate(prefmaxlen,
+  				     (LPVOID *) pbuf);
+  	      }
+	    for (i = 0, ptr = info; ptr; ptr = ptr->Next, i++)
+  	      {
+  		ti = (PWKSTA_TRANSPORT_INFO_0) 
+  		  ((PBYTE) *pbuf + i * sizeof(WKSTA_TRANSPORT_INFO_0));
+  		ti->wkti0_quality_of_service=0;
+  		ti->wkti0_number_of_vcs=0;
+		ti->wkti0_transport_name= (LPWSTR)
+		  ((PBYTE )*pbuf +
+                   n_adapt * sizeof(WKSTA_TRANSPORT_INFO_0)
+		   + i * TRANSPORT_NAME_LEN * sizeof (WCHAR));
+                wprint_name(ti->wkti0_transport_name,TRANSPORT_NAME_LEN, ptr);
+  		ti->wkti0_transport_address= (LPWSTR)
+		  ((PBYTE )*pbuf +
+                   n_adapt * sizeof(WKSTA_TRANSPORT_INFO_0) +
+                   n_adapt * TRANSPORT_NAME_LEN * sizeof (WCHAR)
+  		   + i * 13 * sizeof (WCHAR));
+  		ti->wkti0_wan_ish=TRUE; /*TCPIP/NETBIOS Protocoll*/
+		wprint_mac(ti->wkti0_transport_address, ptr);
+  		TRACE("%d of %d:ti at %p transport_address at %p %s\n",i,n_adapt,
+  		      ti, ti->wkti0_transport_address, debugstr_w(ti->wkti0_transport_address));
+  	      }
 	    *read_entries = n_adapt;
 	    *total_entries = n_adapt;
-	    if(hresume) *hresume= 0;
-	    break;
-	  }
+            free(info);
+  	    if(hresume) *hresume= 0;
+  	    break;
+  	  }
 	default:
 	  ERR("Invalid level %ld is specified\n", level);
 	  return ERROR_INVALID_LEVEL;
diff --git a/include/nb30.h b/include/nb30.h
index b04a11b..a9d7beb 100644
--- a/include/nb30.h
+++ b/include/nb30.h
@@ -100,9 +100,11 @@
 #define NRC_ILLCMD  0x03
 #define NRC_CMDTMO  0x05
 #define NRC_INCOMP  0x06
+#define NRC_NORESOURCES 0x38
 #define NRC_INVADDRESS 0x39
 #define NRC_PENDING 0xff
 #define NRC_OPENERROR 0x3f
+#define NRC_SYSTEM  0x40
 
 #ifdef __cplusplus
 }