Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / base / services / svchost / netbios.c
diff --git a/base/services/svchost/netbios.c b/base/services/svchost/netbios.c
new file mode 100644 (file)
index 0000000..f2015d3
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * PROJECT:     ReactOS Service Host
+ * LICENSE:     BSD - See COPYING.ARM in the top level directory
+ * FILE:        base/services/svchost/netbios.c
+ * PURPOSE:     NetBIOS Service Support
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "svchost.h"
+
+#include <lmerr.h>
+#include <nb30.h>
+
+/* GLOBALS *******************************************************************/
+
+LONG GlobalNetBiosUseCount;
+DWORD LanaFlags[8];
+CRITICAL_SECTION SvcNetBiosCritSec;
+
+/* FUNCTIONS *****************************************************************/
+
+DWORD
+WINAPI
+SvcNetBiosStatusToApiStatus (
+    _In_ DWORD NetBiosError
+    )
+{
+    /* Convert from one status to another */
+    switch (NetBiosError)
+    {
+        case NRC_GOODRET:
+            return NERR_Success;
+        case NRC_INUSE:
+        case NRC_NAMCONF:
+            return NERR_DuplicateName;
+        case NRC_NOWILD:
+        case NRC_NAMERR:
+            return ERROR_INVALID_PARAMETER;
+        case NRC_NOCALL:
+            return NERR_NameNotFound;
+        case NRC_NORES:
+            return NERR_NoNetworkResource;
+        case NRC_DUPNAME:
+            return NERR_AlreadyExists;
+        case NRC_NAMTFUL:
+            return NERR_TooManyNames;
+        case NRC_ACTSES:
+            return NERR_DeleteLater;
+        case NRC_REMTFUL:
+            return ERROR_REM_NOT_LIST;
+        default:
+            return NERR_NetworkError;
+    }
+}
+
+BOOL
+WINAPI
+LanaFlagIsSet (
+    _In_ UCHAR Lana
+    )
+{
+    DWORD i = Lana / 32;
+
+    /* Clear the flag for this LANA */
+    return (i <= 7) ? LanaFlags[i] & (1 << (Lana - 32 * i)) : FALSE;
+}
+
+VOID
+WINAPI
+SetLanaFlag (
+    _In_ UCHAR Lana
+    )
+{
+    DWORD i = Lana / 32;
+
+    /* Set the flag for this LANA */
+    if (i <= 7) LanaFlags[i] |= 1 << (Lana - 32 * i);
+}
+
+VOID
+WINAPI
+SvcNetBiosInit(
+    VOID
+    )
+{
+    /* Initialize NetBIOS-related structures and variables */
+    InitializeCriticalSection(&SvcNetBiosCritSec);
+    GlobalNetBiosUseCount = 0;
+    ZeroMemory(LanaFlags, sizeof(LanaFlags));
+}
+
+VOID
+WINAPI
+SvcNetBiosClose (
+    VOID
+    )
+{
+    /* While holding the lock, drop a reference*/
+    EnterCriticalSection(&SvcNetBiosCritSec);
+    if ((GlobalNetBiosUseCount != 0) && (--GlobalNetBiosUseCount == 0))
+    {
+        /* All references are gone, clear all LANA's */
+        ZeroMemory(LanaFlags, sizeof(LanaFlags));
+    }
+    LeaveCriticalSection(&SvcNetBiosCritSec);
+}
+
+VOID
+WINAPI
+SvcNetBiosOpen (
+    VOID
+    )
+{
+    /* Increment the reference counter while holding the lock */
+    EnterCriticalSection(&SvcNetBiosCritSec);
+    GlobalNetBiosUseCount++;
+    LeaveCriticalSection(&SvcNetBiosCritSec);
+}
+
+DWORD
+WINAPI
+SvcNetBiosReset (
+    _In_ UCHAR LanaNum
+    )
+{
+    DWORD dwError = ERROR_SUCCESS;
+    UCHAR nbtError;
+    NCB ncb;
+
+    /* Block all other NetBIOS operations */
+    EnterCriticalSection(&SvcNetBiosCritSec);
+
+    /* Is this LANA enabled? */
+    if (!LanaFlagIsSet(LanaNum))
+    {
+        /* Yep, build a reset packet */
+        ZeroMemory(&ncb, sizeof(ncb));
+        ncb.ncb_lsn = 0;
+        ncb.ncb_command = NCBRESET;
+        ncb.ncb_callname[0] = 0xFE; // Max Sessions
+        ncb.ncb_callname[1] = 0;
+        ncb.ncb_callname[2] = 0xFD; // Max Names
+        ncb.ncb_callname[3] = 0;
+        ncb.ncb_lana_num = LanaNum;
+
+        /* Send it */
+        nbtError = Netbios(&ncb);
+
+        /* Convert the status to Win32 format */
+        dwError = SvcNetBiosStatusToApiStatus(nbtError);
+
+        /* Enable the LANA if the reset worked */
+        if (dwError == ERROR_SUCCESS) SetLanaFlag(LanaNum);
+    }
+
+    /* Drop the lock and return */
+    LeaveCriticalSection(&SvcNetBiosCritSec);
+    return dwError;
+}