Added netapi32.dll and the Netbios() call.
diff --git a/dlls/netapi32/netapi32.c b/dlls/netapi32/netapi32.c
new file mode 100644
index 0000000..0d74c1c
--- /dev/null
+++ b/dlls/netapi32/netapi32.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2001 Mike McCormack
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "winbase.h"
+#include "winreg.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "debugtools.h"
+#include "winerror.h"
+#include "nb30.h"
+
+#ifdef HAVE_SYS_FILE_H
+# include <sys/file.h>
+#endif
+#include <sys/ioctl.h>
+#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_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 /* defined(HAVE_SOCKADDR_SA_LEN) */
+
+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 */
+
+static UCHAR NETBIOS_Enum(PNCB ncb)
+{
+#ifdef HAVE_NET_IF_H
+ int sd;
+ struct ifreq ifr, *ifrp;
+ struct ifconf ifc;
+ unsigned char buf[1024];
+ int i, ofs;
+#endif
+ LANA_ENUM *lanas = (PLANA_ENUM) ncb->ncb_buffer;
+
+ TRACE("NCBENUM\n");
+
+ lanas->length = 0;
+
+#ifdef HAVE_NET_IF_H
+ /* 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;
+ lanas->lana[lanas->length] = i;
+ lanas->length++;
+ }
+ ofs += ifreq_size(ifr);
+ }
+ close(sd);
+#endif /* HAVE_NET_IF_H */
+ return NRC_GOODRET;
+}
+
+
+static UCHAR NETBIOS_Astat(PNCB ncb)
+{
+ struct NetBiosAdapter *nad = &NETBIOS_Adapter[ncb->ncb_lana_num];
+ PADAPTER_STATUS astat = (PADAPTER_STATUS) ncb->ncb_buffer;
+
+ 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);
+
+ return NRC_GOODRET;
+}
+
+BOOL WINAPI
+NETAPI32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
+
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ NETAPI32_hModule = hinstDLL;
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+
+ return TRUE;
+}
+
+BOOL WINAPI Netbios(PNCB pncb)
+{
+ UCHAR ret = NRC_ILLCMD;
+
+ TRACE("ncb = %p\n",pncb);
+
+ if(!pncb)
+ return NRC_INVADDRESS;
+
+ switch(pncb->ncb_command&0x7f)
+ {
+ 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;
+ else
+ ret = NRC_ILLCMD; /* NetBIOS emulator not found */
+ break;
+
+ case NCBADDNAME:
+ FIXME("NCBADDNAME\n");
+ break;
+
+ case NCBADDGRNAME:
+ FIXME("NCBADDGRNAME\n");
+ break;
+
+ case NCBDELNAME:
+ FIXME("NCBDELNAME\n");
+ break;
+
+ case NCBSEND:
+ FIXME("NCBSEND\n");
+ break;
+
+ case NCBRECV:
+ FIXME("NCBRECV\n");
+ break;
+
+ case NCBHANGUP:
+ FIXME("NCBHANGUP\n");
+ break;
+
+ case NCBCANCEL:
+ FIXME("NCBCANCEL\n");
+ break;
+
+ case NCBLISTEN:
+ FIXME("NCBLISTEN\n");
+ break;
+
+ case NCBASTAT:
+ ret = NETBIOS_Astat(pncb);
+ break;
+
+ case NCBENUM:
+ ret = NETBIOS_Enum(pncb);
+ break;
+
+ default:
+ FIXME("(%p): command code %02x\n", pncb, pncb->ncb_command);
+
+ ret = NRC_ILLCMD; /* NetBIOS emulator not found */
+ }
+ pncb->ncb_retcode = ret;
+ return ret;
+}
+