/* * 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 #include /* 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; }