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)26SvcNetBiosStatusToApiStatus ( 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)60LanaFlagIsSet ( 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)72SetLanaFlag ( 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)84SvcNetBiosInit( 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)96SvcNetBiosClose ( 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)112SvcNetBiosOpen ( 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)124SvcNetBiosReset ( 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