xref: /reactos/base/services/svchost/netbios.c (revision c2c66aff)
1 /*
2  * PROJECT:     ReactOS Service Host
3  * LICENSE:     BSD - See COPYING.ARM in the top level directory
4  * FILE:        base/services/svchost/netbios.c
5  * PURPOSE:     NetBIOS Service Support
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "svchost.h"
12 
13 #include <lmerr.h>
14 #include <nb30.h>
15 
16 /* GLOBALS *******************************************************************/
17 
18 LONG GlobalNetBiosUseCount;
19 DWORD LanaFlags[8];
20 CRITICAL_SECTION SvcNetBiosCritSec;
21 
22 /* FUNCTIONS *****************************************************************/
23 
24 DWORD
25 WINAPI
SvcNetBiosStatusToApiStatus(_In_ DWORD NetBiosError)26 SvcNetBiosStatusToApiStatus (
27     _In_ DWORD NetBiosError
28     )
29 {
30     /* Convert from one status to another */
31     switch (NetBiosError)
32     {
33         case NRC_GOODRET:
34             return NERR_Success;
35         case NRC_INUSE:
36         case NRC_NAMCONF:
37             return NERR_DuplicateName;
38         case NRC_NOWILD:
39         case NRC_NAMERR:
40             return ERROR_INVALID_PARAMETER;
41         case NRC_NOCALL:
42             return NERR_NameNotFound;
43         case NRC_NORES:
44             return NERR_NoNetworkResource;
45         case NRC_DUPNAME:
46             return NERR_AlreadyExists;
47         case NRC_NAMTFUL:
48             return NERR_TooManyNames;
49         case NRC_ACTSES:
50             return NERR_DeleteLater;
51         case NRC_REMTFUL:
52             return ERROR_REM_NOT_LIST;
53         default:
54             return NERR_NetworkError;
55     }
56 }
57 
58 BOOL
59 WINAPI
LanaFlagIsSet(_In_ UCHAR Lana)60 LanaFlagIsSet (
61     _In_ UCHAR Lana
62     )
63 {
64     DWORD i = Lana / 32;
65 
66     /* Clear the flag for this LANA */
67     return (i <= 7) ? LanaFlags[i] & (1 << (Lana - 32 * i)) : FALSE;
68 }
69 
70 VOID
71 WINAPI
SetLanaFlag(_In_ UCHAR Lana)72 SetLanaFlag (
73     _In_ UCHAR Lana
74     )
75 {
76     DWORD i = Lana / 32;
77 
78     /* Set the flag for this LANA */
79     if (i <= 7) LanaFlags[i] |= 1 << (Lana - 32 * i);
80 }
81 
82 VOID
83 WINAPI
SvcNetBiosInit(VOID)84 SvcNetBiosInit(
85     VOID
86     )
87 {
88     /* Initialize NetBIOS-related structures and variables */
89     InitializeCriticalSection(&SvcNetBiosCritSec);
90     GlobalNetBiosUseCount = 0;
91     ZeroMemory(LanaFlags, sizeof(LanaFlags));
92 }
93 
94 VOID
95 WINAPI
SvcNetBiosClose(VOID)96 SvcNetBiosClose (
97     VOID
98     )
99 {
100     /* While holding the lock, drop a reference*/
101     EnterCriticalSection(&SvcNetBiosCritSec);
102     if ((GlobalNetBiosUseCount != 0) && (--GlobalNetBiosUseCount == 0))
103     {
104         /* All references are gone, clear all LANA's */
105         ZeroMemory(LanaFlags, sizeof(LanaFlags));
106     }
107     LeaveCriticalSection(&SvcNetBiosCritSec);
108 }
109 
110 VOID
111 WINAPI
SvcNetBiosOpen(VOID)112 SvcNetBiosOpen (
113     VOID
114     )
115 {
116     /* Increment the reference counter while holding the lock */
117     EnterCriticalSection(&SvcNetBiosCritSec);
118     GlobalNetBiosUseCount++;
119     LeaveCriticalSection(&SvcNetBiosCritSec);
120 }
121 
122 DWORD
123 WINAPI
SvcNetBiosReset(_In_ UCHAR LanaNum)124 SvcNetBiosReset (
125     _In_ UCHAR LanaNum
126     )
127 {
128     DWORD dwError = ERROR_SUCCESS;
129     UCHAR nbtError;
130     NCB ncb;
131 
132     /* Block all other NetBIOS operations */
133     EnterCriticalSection(&SvcNetBiosCritSec);
134 
135     /* Is this LANA enabled? */
136     if (!LanaFlagIsSet(LanaNum))
137     {
138         /* Yep, build a reset packet */
139         ZeroMemory(&ncb, sizeof(ncb));
140         ncb.ncb_lsn = 0;
141         ncb.ncb_command = NCBRESET;
142         ncb.ncb_callname[0] = 0xFE; // Max Sessions
143         ncb.ncb_callname[1] = 0;
144         ncb.ncb_callname[2] = 0xFD; // Max Names
145         ncb.ncb_callname[3] = 0;
146         ncb.ncb_lana_num = LanaNum;
147 
148         /* Send it */
149         nbtError = Netbios(&ncb);
150 
151         /* Convert the status to Win32 format */
152         dwError = SvcNetBiosStatusToApiStatus(nbtError);
153 
154         /* Enable the LANA if the reset worked */
155         if (dwError == ERROR_SUCCESS) SetLanaFlag(LanaNum);
156     }
157 
158     /* Drop the lock and return */
159     LeaveCriticalSection(&SvcNetBiosCritSec);
160     return dwError;
161 }
162