From 2e40b964d81c8abf671e6c31e2dd4b6d05a00853 Mon Sep 17 00:00:00 2001
From: Mike McCormack <mike_mccormack@start.com.au>
Date: Tue, 6 Nov 2001 17:52:36 +0000
Subject: [PATCH] Added netapi32.dll and the Netbios() call.

---
 configure                   |   2 +
 configure.in                |   1 +
 dlls/Makefile.in            |   9 ++
 dlls/netapi32/.cvsignore    |   2 +
 dlls/netapi32/Makefile.in   |  14 ++
 dlls/netapi32/netapi32.c    | 250 ++++++++++++++++++++++++++++++++++++
 dlls/netapi32/netapi32.spec |  13 ++
 include/Makefile.in         |   1 +
 include/nb30.h              |  95 ++++++++++++++
 9 files changed, 387 insertions(+)
 create mode 100644 dlls/netapi32/.cvsignore
 create mode 100644 dlls/netapi32/Makefile.in
 create mode 100644 dlls/netapi32/netapi32.c
 create mode 100644 dlls/netapi32/netapi32.spec
 create mode 100644 include/nb30.h

diff --git a/configure b/configure
index 69857a79496..aeed119f38d 100755
--- a/configure
+++ b/configure
@@ -7081,6 +7081,7 @@ dlls/msnet32/Makefile
 dlls/msrle32/Makefile
 dlls/msvcrt/Makefile
 dlls/msvideo/Makefile
+dlls/netapi32/Makefile
 dlls/ntdll/Makefile
 dlls/odbc32/Makefile
 dlls/ole32/Makefile
@@ -7340,6 +7341,7 @@ dlls/msnet32/Makefile
 dlls/msrle32/Makefile
 dlls/msvcrt/Makefile
 dlls/msvideo/Makefile
+dlls/netapi32/Makefile
 dlls/ntdll/Makefile
 dlls/odbc32/Makefile
 dlls/ole32/Makefile
diff --git a/configure.in b/configure.in
index 69697eb157e..17c48dfcc16 100644
--- a/configure.in
+++ b/configure.in
@@ -1247,6 +1247,7 @@ dlls/msnet32/Makefile
 dlls/msrle32/Makefile
 dlls/msvcrt/Makefile
 dlls/msvideo/Makefile
+dlls/netapi32/Makefile
 dlls/ntdll/Makefile
 dlls/odbc32/Makefile
 dlls/ole32/Makefile
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
index 8845ab371a1..b6927d4f152 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -44,6 +44,7 @@ SUBDIRS = \
 	msrle32 \
 	msvcrt \
 	msvideo \
+	netapi32 \
 	ntdll \
 	odbc32 \
 	ole32 \
@@ -148,6 +149,7 @@ all: \
 	libmsvcrt.$(LIBEXT) \
 	libmsvfw32.$(LIBEXT) \
 	libmsvideo.$(LIBEXT) \
+	libnetapi32.$(LIBEXT) \
 	libntdll.$(LIBEXT) \
 	libodbc32.$(LIBEXT) \
 	libole2.$(LIBEXT) \
@@ -336,6 +338,9 @@ libmsvcrt.$(LIBEXT): msvcrt/libmsvcrt.$(LIBEXT)
 libmsvfw32.$(LIBEXT) libmsvideo.$(LIBEXT): msvideo/libmsvfw32.$(LIBEXT)
 	$(RM) $@ && $(LN_S) msvideo/libmsvfw32.$(LIBEXT) $@
 
+libnetapi32.$(LIBEXT): netapi32/libnetapi32.$(LIBEXT)
+	$(RM) $@ && $(LN_S) netapi32/libnetapi32.$(LIBEXT) $@
+
 libntdll.$(LIBEXT): ntdll/libntdll.$(LIBEXT)
 	$(RM) $@ && $(LN_S) ntdll/libntdll.$(LIBEXT) $@
 
@@ -569,6 +574,10 @@ msvideo/libmsvfw32.$(LIBEXT): dummy libwinmm.$(LIBEXT) libcomctl32.$(LIBEXT) \
   libntdll.$(LIBEXT)
 	@cd msvideo && $(MAKE) libmsvfw32.$(LIBEXT)
 
+netapi32/libnetapi32.$(LIBEXT): dummy libuser32.$(LIBEXT) libadvapi32.$(LIBEXT) \
+  libkernel32.$(LIBEXT) libntdll.$(LIBEXT)
+	@cd netapi32 && $(MAKE) libnetapi32.$(LIBEXT)
+
 ntdll/libntdll.$(LIBEXT): dummy
 	@cd ntdll && $(MAKE) libntdll.$(LIBEXT)
 
diff --git a/dlls/netapi32/.cvsignore b/dlls/netapi32/.cvsignore
new file mode 100644
index 00000000000..199fc7cb4e1
--- /dev/null
+++ b/dlls/netapi32/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+netapi32.spec.c
diff --git a/dlls/netapi32/Makefile.in b/dlls/netapi32/Makefile.in
new file mode 100644
index 00000000000..650e6193625
--- /dev/null
+++ b/dlls/netapi32/Makefile.in
@@ -0,0 +1,14 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = netapi32
+
+LDDLLFLAGS = @LDDLLFLAGS@
+SYMBOLFILE = $(MODULE).tmp.o
+
+C_SRCS = netapi32.c
+
+@MAKE_DLL_RULES@
+
+### Dependencies:
diff --git a/dlls/netapi32/netapi32.c b/dlls/netapi32/netapi32.c
new file mode 100644
index 00000000000..0d74c1ca8b5
--- /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;
+}
+
diff --git a/dlls/netapi32/netapi32.spec b/dlls/netapi32/netapi32.spec
new file mode 100644
index 00000000000..077211cdc72
--- /dev/null
+++ b/dlls/netapi32/netapi32.spec
@@ -0,0 +1,13 @@
+name	netapi32
+type    win32
+init	NETAPI32_LibMain
+
+#import	user32.dll
+#import	advapi32.dll
+#import	kernel32.dll
+import	ntdll.dll
+
+debug_channels (netbios)
+
+1 stdcall Netbios(ptr) Netbios
+
diff --git a/include/Makefile.in b/include/Makefile.in
index a3fde3208be..fbe99f7c23c 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -74,6 +74,7 @@ INSTALLED_INCLUDES = \
 	msvcrt/time.h \
 	msvcrt/wchar.h \
 	msvcrt/wctype.h \
+	nb30.h \
 	nspapi.h \
 	ntsecapi.h \
 	oaidl.h \
diff --git a/include/nb30.h b/include/nb30.h
new file mode 100644
index 00000000000..ae1350b03a1
--- /dev/null
+++ b/include/nb30.h
@@ -0,0 +1,95 @@
+#ifndef NCB_INCLUDED
+#define NCB_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NCBNAMSZ 16
+#define MAX_LANA 0xfe
+
+#define NCBRESET       0x32
+#define NCBADDNAME     0x30
+#define NCBADDGRNAME   0x36
+#define NCBDELNAME     0x31
+#define NCBSEND        0x14
+#define NCBRECV        0x15
+#define NCBHANGUP      0x12
+#define NCBCANCEL      0x35
+#define NCBLISTEN      0x11
+#define NCBCALL        0x10
+#define NCBASTAT       0x33
+#define NCBENUM        0x37
+
+#include "pshpack1.h"
+
+typedef struct _NCB
+{
+	UCHAR	ncb_command;
+	UCHAR	ncb_retcode;
+	UCHAR	ncb_lsn;
+	UCHAR	ncb_num;
+	PUCHAR	ncb_buffer;
+	WORD	ncb_length;
+	UCHAR	ncb_callname[NCBNAMSZ];
+	UCHAR	ncb_name[NCBNAMSZ];
+	UCHAR	ncb_rto;
+	UCHAR	ncb_sto;
+	VOID	(*ncb_post)(struct _NCB *);
+	UCHAR	ncb_lana_num;
+	UCHAR	ncb_cmd_cplt;
+	UCHAR	ncb_reserved[10];
+	HANDLE	ncb_event;
+} NCB, *PNCB;
+
+typedef struct _ADAPTER_STATUS
+{
+	UCHAR   adapter_address[6];
+	UCHAR	rev_major;
+	UCHAR	reserved0;
+	UCHAR	adapter_type;
+	UCHAR	rev_minor;
+	WORD	duration;
+	WORD	frmr_recv;
+	WORD	frmr_xmit;
+	WORD	iframe_recv_error;
+	WORD	xmit_aborts;
+	WORD	xmit_success;
+	WORD	recv_success;
+	WORD	iframe_xmit_error;
+	WORD	recv_buffer_unavail;
+	WORD	t1_timeouts;
+	WORD	ti_timeouts;
+	DWORD	reserved1;
+	WORD	free_ncbs;
+	WORD	max_cfg_ncbs;
+	WORD	max_ncbs;
+	WORD	xmit_buf_unavail;
+	WORD	max_dgram_size;
+	WORD	pending_sess;
+	WORD	max_cfg_sess;
+	WORD	max_sess;
+	WORD	max_sess_pktsize;
+	WORD	name_count;
+} ADAPTER_STATUS, *PADAPTER_STATUS;
+
+typedef struct _LANA_ENUM
+{
+	UCHAR length;
+	UCHAR lana[MAX_LANA+1];
+} LANA_ENUM, *PLANA_ENUM;
+
+#define NRC_GOODRET 0x00
+#define NRC_BUFLEN  0x01
+#define NRC_ILLCMD  0x03
+#define NRC_CMDTMO  0x05
+#define NRC_INCOMP  0x06
+#define NRC_INVADDRESS 0x39
+#define NRC_PENDING 0xff
+#define NRC_OPENERROR 0x3f
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* NCB_INCLUDED */
-- 
GitLab