mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
161 lines
3.6 KiB
C
161 lines
3.6 KiB
C
/*
|
|
* 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;
|
|
}
|