home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tlx501.zip
/
SRC
/
NETBIOS.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-08
|
14KB
|
548 lines
/****************************************************************************
$Id: netbios.cpp 501.0 1995/03/07 12:26:18 RON Exp $
Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
Project: Tarma Library for C++ V5.0
Author: Ron van der Wal
Implementation of NetBIOS functions.
$Log: netbios.cpp $
Revision 501.0 1995/03/07 12:26:18 RON
Updated for TLX 5.01
Revision 1.3 1995/01/31 17:12:58 RON
Update for release 012
Added partial support for SunPro C++ compiler
Revision 1.2 1995/01/18 19:02:19 ron
Added inline assembly warning for Win32
Revision 1.1 1995/01/05 15:25:32 ron
Initial revision
****************************************************************************/
//#if defined(__BORLANDC__) && (defined(__OS2__) || defined(__WIN32__))
//#pragma inline // Warn compiler for inline assembly under OS/2
//#endif
//----- System headers
#include <string.h>
//----- Library headers
#include <tlx\501\debug.h>
#include <tlx\501\net\netbios.h>
// Compile only if DOS or Windows
#if OS_DOS || OS_WIN16
#ifndef _DATA_NEAR // Temporary hack
#if OS_WIN16
// Windows 3.x has a non-prototyped assembly function "NetBIOSCall".
// We declare a prototype for it here. We use Pascal calling convention
// to prevent the compiler from prefixing an underscore to the name.
extern "C" void __pascal _Far NetBIOSCall(void);
#endif
/*---------------------------------------------------------------------------
Error message table
---------------------------------------------------------------------------*/
#define MAXMESSAGE 26
char *gNetBIOSMessage[] =
{
"Success", /* 00 */
"Invalid buffer length", /* 01 */
"Ret code 02", /* 02 */
"Invalid command", /* 03 */
"Ret code 04", /* 04 */
"Timed out", /* 05 */
"Buffer too small", /* 06 */
"Ret code 07", /* 07 */
"Invalid session num", /* 08 */
"No resource", /* 09 */
"Session closed", /* 0A */
"Command cancelled", /* 0B */
"Ret code 0C", /* 0C */
"Dupl. local name", /* 0D */
"Name table full", /* 0E */
"Active session", /* 0F */
"Ret code 10", /* 10 */
"Session table full", /* 11 */
"No one listening", /* 12 */
"Invalid name num", /* 13 */
"No answer", /* 14 */
"No local name", /* 15 */
"Name in use", /* 16 */
"Name is deleted", /* 17 */
"Abnormal end", /* 18 */
"Name conflict", /* 19 */
"Ret code 1A", /* 1A */
"Ret code 1B", /* 1B */
"Ret code 1C", /* 1C */
"Ret code 1D", /* 1D */
"Ret code 1E", /* 1E */
"Ret code 1F", /* 1F */
"Ret code 20", /* 20 */
"Card busy", /* 21 */
"Too many cmds", /* 22 */
"Invalid card num", /* 23 */
"Cancel done", /* 24 */
"Ret code 25", /* 25 */
"Cannot cancel" /* 26 */
};
/*-------------------------------------------------------------------------*/
char * _TLXFUNC NBSetName(char *aBuffer, const char *aName)
/* Stores a name in NetBIOS format, i.e. with space padding and a
terminating '\0'.
Parameters:
aBuffer = pointer to name buffer; should be at least NB_NAMELEN bytes
aName = pointer to C-style name
Return value:
aBuffer
---------------------------------------------------------------------------*/
{
size_t slen = strlen(aName);
strncpy(aBuffer, aName, NB_NAMELEN-1);
while (slen < NB_NAMELEN - 1)
aBuffer[slen++] = ' ';
aBuffer[NB_NAMELEN - 1] = 0;
return aBuffer;
}
/*-------------------------------------------------------------------------*/
char * _TLXFUNC NBGetName(char *aBuffer, const char *aName)
/* Converts the NetBIOS name stored in aName to a normal C-style string.
Trailing spaces are removed.
Parameters:
aBuffer = pointer to name buffer (at least NB_NAMELEN bytes)
aName = pointer to the NetBIOS formatted name
Return value:
aBuffer
---------------------------------------------------------------------------*/
{
int i;
memcpy(aBuffer, aName, NB_NAMELEN);
aBuffer[NB_NAMELEN - 1] = 0;
for (i = NB_NAMELEN - 2; i >= 0 && (aBuffer[i] == 0 || aBuffer[i] == ' ');
i--)
{
aBuffer[i] = 0;
}
return aBuffer;
}
/*-------------------------------------------------------------------------*/
char * _TLXFUNC NBGetLocalName(TLNCB _Far *aNCB, char *aBuffer)
/* Returns the local name stored in an TLNCB in a normal C-style string.
Trailing spaces are removed.
Parameters:
aNCB = pointer to TLNCB
aBuffer = pointer to name buffer (at least NB_NAMELEN bytes)
Return value:
aBuffer
---------------------------------------------------------------------------*/
{
return NBGetName(aBuffer, aNCB->mLocalName);
}
/*-------------------------------------------------------------------------*/
char * _TLXFUNC NBGetRemoteName(TLNCB _Far *aNCB, char *aBuffer)
/* Returns the remote name stored in an TLNCB in a normal C-style string.
Trailing spaces are removed.
Parameters:
aNCB = pointer to TLNCB
aBuffer = pointer to name buffer (at least NB_NAMELEN bytes)
Return value:
aBuffer
---------------------------------------------------------------------------*/
{
return NBGetName(aBuffer, aNCB->mRemoteName);
}
/*-------------------------------------------------------------------------*/
void _TLXFUNC NBSetLocalName(TLNCB _Far *aNCB, const char *aName)
/* Sets the local name in an TLNCB from a normal C-style string.
Parameters:
aNCB = pointer to TLNCB
aName = pointer to the name
---------------------------------------------------------------------------*/
{
NBSetName(aNCB->mLocalName, aName);
}
/*-------------------------------------------------------------------------*/
void _TLXFUNC NBSetRemoteName(TLNCB _Far *aNCB, const char *aName)
/* Sets the remote name in an TLNCB from a normal C-style string.
Parameters:
aNCB = pointer to TLNCB
aName = pointer to the name
---------------------------------------------------------------------------*/
{
NBSetName(aNCB->mRemoteName, aName);
}
/*-------------------------------------------------------------------------*/
void _TLXFUNC NBClearNCB(TLNCB _Far *aNCB)
/* Clears the contents of the TLNCB.
Parameters:
aNCB = pointer to the TLNCB to be cleared.
---------------------------------------------------------------------------*/
{
_fmemset(aNCB, 0, sizeof(TLNCB));
}
/*-------------------------------------------------------------------------*/
const char * _TLXFUNC NBErrorMsg(uint16 result)
/* Returns an error message based on the NetBIOS result code.
Parameters:
result = NetBIOS result code
Return value:
Pointer to an error message
---------------------------------------------------------------------------*/
{
return result <= MAXMESSAGE ? gNetBIOSMessage[result] : "Unknown error";
}
/*-------------------------------------------------------------------------*/
bool _TLXFUNC NBInstalled(void)
/* Tests the NetBIOS installed state.
Parameters:
none
Return value:
Nonzero if NetBIOS is installed, else zero.
---------------------------------------------------------------------------*/
{
bool installed = false;
uint16 result;
TLNCB ncb;
#if defined(__IBMC__) || defined(__IBMCPP__)
// These compilers do not support inline assembly; we'll have to
// find some other way to implement the search for the int 5Ch
// vector. To avoid compilation errors, we just insert an assertion
// here.
TLX_ASSERT_UNREACHABLE; // Replace by genuine code some day
#else // Not IBM C Set/2 or IBM C Set++
// Check for a nonzero int 5Ch vector
__asm {
push bx
push es
mov ax,0x355C /* Get Vector 5Ch */
int 0x21
mov ax,es
or ax,bx
jz NotInstalled
mov ax,1
#ifdef __BORLANDC__ // Borland does not allow assembly labels
}
#endif
NotInstalled:
#ifdef __BORLANDC__
__asm {
#endif
pop es
pop bx
mov installed,ax
}
#endif // IBM C Set/2 or IBM C Set++
if (!installed) return false;
// Issue non-existing command 0xFF, then test for error
ncb.mCommand = 0xFF;
ncb.mCallBack = 0;
result = NBExecute(&ncb);
// Errors are broken down into the following categories:
//
// - 0x40-0x4F "unusual network condition"
// - 0x50-0xFE "adapter malfunction"
// - various individual error codes
//
// Any of these errors indicates the presence of NetBIOS.
if (result >= 0x40 && result <= 0xFE)
{
installed = true;
}
else
{
switch (result)
{
case NB_ERR_BADCOMMAND:
case NB_ERR_BADADAPTER:
installed = true;
break;
default:
installed = false;
break;
}
}
return installed;
}
/*-------------------------------------------------------------------------*/
uint16 _TLXFUNC NBExecute(TLNCB _Far *aNCB)
/* Issues a NetBIOS command.
Parameters:
aNCB = pointer to the formatted TLNCB
Return value:
Return code from NetBIOS.
---------------------------------------------------------------------------*/
{
// We store the command early, because we need it later on and the
// associated TLNCB might be released by the time the NetBIOS call returns.
uint8 command = aNCB->mCommand;
uint16 result;
#if OS_DOSXXX
__asm {
les bx,aNCB
mov ax,0x0100
int 0x5C /* Call NetBIOS, result in AL */
xor ah,ah /* Clear AH */
mov result,ax /* Store immediate result */
}
#elif OS_WINXXX
__asm {
les bx,aNCB
mov ax,0x0100
}
NetBIOSCall(); /* Call NetBIOS, result in AL */
__asm {
xor ah,ah /* Clear AH */
mov result,ax /* Store immediate result */
}
#elif OS_OS2
// We have not yet implemented NetBIOS support for OS/2. However,
// we do allow compilation, only the resulting code should not be
// executed.
TLX_ASSERT_UNREACHABLE;
#else
#error Unsupported operating system
#endif
// At this point, we have the immediate return code in 'result'.
// However, if the command had the wait option set, we need the final
// completion code, which is stored inside the TLNCB. In the case
// of a wait option, we can be sure that the TLNCB still exists
// (no intervening callback functions).
if ((command & NB_NOWAIT) == 0)
{
result = aNCB->mCompletion;
}
return result;
}
/*-------------------------------------------------------------------------*/
uint16 _TLXFUNC NBCancel(TLNCB _Far *aNCB)
/* Cancels a given NCB. The NCB is passed in. It is *not* possible to
cancel the following NetBIOS commands:
- ADD NAME
- ADD GROUP NAME
- DELETE NAME
- SEND DATAGRAM
- SEND BROADCAST DATAGRAM
- SESSION STATUS
- RESET
- CANCEL
Parameters:
none
Return value:
N/A
---------------------------------------------------------------------------*/
{
TLNCB ncb;
NBClearNCB(&ncb);
ncb.mCommand = NB_CANCEL;
ncb.mBuffer = aNCB;
ncb.mAdapter = 0;
return NBExecute(&ncb);
}
/*-------------------------------------------------------------------------*/
uint16 _TLXFUNC NBReset(uint8 maxSes, uint8 maxNCB, uint8 adapt)
/* Resets the given NetBIOS adapter.
Parameters:
none
Return value:
N/A
---------------------------------------------------------------------------*/
{
TLNCB ncb;
NBClearNCB(&ncb);
ncb.mCommand = NB_RESET;
ncb.mLSN = maxSes;
ncb.mNameNo = maxNCB;
ncb.mAdapter = adapt;
return NBExecute(&ncb);
}
uint16 _TLXFUNC NBAdapterStatus(const char *aName, TLAdapterStatus _Far *aStatus)
{
TLNCB ncb;
NBClearNCB(&ncb);
ncb.mCommand = NB_STATUS;
ncb.mBuffer = aStatus;
ncb.mSize = sizeof(TLAdapterStatus);
NBSetRemoteName(&ncb, aName);
return NBExecute(&ncb);
}
uint16 _TLXFUNC NBAddName(const char *aName, uint8 *aNameNo)
{
TLNCB ncb;
uint16 result;
NBClearNCB(&ncb);
ncb.mCommand = NB_ADDNAME;
NBSetLocalName(&ncb, aName);
if ((result = NBExecute(&ncb)) == 0)
{
*aNameNo = ncb.mNameNo;
}
return result;
}
uint16 _TLXFUNC NBAddNameNW(TLNCB _Far *aNCB, const char *aName, callback_f aCallBack)
{
NBClearNCB(aNCB);
aNCB->mCommand = NB_ADDNAME | NB_NOWAIT;
aNCB->mCallBack = aCallBack;
NBSetLocalName(aNCB, aName);
return NBExecute(aNCB);
}
uint16 _TLXFUNC NBAddGroup(const char *aName, uint8 *aNameNo)
{
TLNCB ncb;
uint16 result;
NBClearNCB(&ncb);
ncb.mCommand = NB_ADDGROUP;
NBSetLocalName(&ncb, aName);
if ((result = NBExecute(&ncb)) == 0)
{
*aNameNo = ncb.mNameNo;
}
return result;
}
uint16 _TLXFUNC NBAddGroupNW(TLNCB _Far *aNCB, const char *aName, callback_f aCallBack)
{
NBClearNCB(aNCB);
aNCB->mCommand = NB_ADDGROUP | NB_NOWAIT;
aNCB->mCallBack = aCallBack;
NBSetLocalName(aNCB, aName);
return NBExecute(aNCB);
}
uint16 _TLXFUNC NBDeleteName(const char *aName)
{
TLNCB ncb;
NBClearNCB(&ncb);
ncb.mCommand = NB_DELETENAME;
NBSetLocalName(&ncb, aName);
return NBExecute(&ncb);
}
uint16 _TLXFUNC NBDeleteNameNW(TLNCB _Far *aNCB, const char *aName, callback_f aCallBack)
{
NBClearNCB(aNCB);
aNCB->mCommand = NB_DELETENAME | NB_NOWAIT;
aNCB->mCallBack = aCallBack;
NBSetLocalName(aNCB, aName);
return NBExecute(aNCB);
}
uint16 _TLXFUNC NBSendDatagram(TLNCB _Far *aNCB)
{
aNCB->mCommand = NB_SENDDATAGRAM;
return NBExecute(aNCB);
}
uint16 _TLXFUNC NBSendDatagramNW(TLNCB _Far *aNCB)
{
aNCB->mCommand = NB_SENDDATAGRAM | NB_NOWAIT;
return NBExecute(aNCB);
}
#endif // _DATA_NEAR // Temporary hack
#endif // DOS or Windows