home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tlx501.zip / SRC / NETBIOS.CPP < prev    next >
C/C++ Source or Header  |  1996-07-08  |  14KB  |  548 lines

  1. /****************************************************************************
  2.     $Id: netbios.cpp 501.0 1995/03/07 12:26:18 RON Exp $
  3.  
  4.     Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
  5.  
  6.     Project:    Tarma Library for C++ V5.0
  7.     Author:    Ron van der Wal
  8.  
  9.     Implementation of NetBIOS functions.
  10.  
  11.     $Log: netbios.cpp $
  12.     Revision 501.0  1995/03/07 12:26:18  RON
  13.     Updated for TLX 5.01
  14.     Revision 1.3  1995/01/31 17:12:58  RON
  15.     Update for release 012
  16.     Added partial support for SunPro C++ compiler
  17.     Revision 1.2  1995/01/18  19:02:19  ron
  18.     Added inline assembly warning for Win32
  19.  
  20.     Revision 1.1  1995/01/05  15:25:32  ron
  21.     Initial revision
  22.  
  23. ****************************************************************************/
  24.  
  25. //#if defined(__BORLANDC__) && (defined(__OS2__) || defined(__WIN32__))
  26. //#pragma inline        // Warn compiler for inline assembly under OS/2
  27. //#endif
  28.  
  29. //-----    System headers
  30.  
  31. #include <string.h>
  32.  
  33. //-----    Library headers
  34.  
  35. #include <tlx\501\debug.h>
  36. #include <tlx\501\net\netbios.h>
  37.  
  38. // Compile only if DOS or Windows
  39.  
  40. #if OS_DOS || OS_WIN16
  41.  
  42. #ifndef _DATA_NEAR    // Temporary hack
  43.  
  44. #if OS_WIN16
  45.     // Windows 3.x has a non-prototyped assembly function "NetBIOSCall".
  46.     // We declare a prototype for it here. We use Pascal calling convention
  47.     // to prevent the compiler from prefixing an underscore to the name.
  48.  
  49.     extern "C" void __pascal _Far NetBIOSCall(void);
  50. #endif
  51.  
  52. /*---------------------------------------------------------------------------
  53.     Error message table
  54. ---------------------------------------------------------------------------*/
  55.  
  56. #define MAXMESSAGE    26
  57.  
  58. char *gNetBIOSMessage[] =
  59. {
  60.     "Success",            /*  00  */
  61.     "Invalid buffer length",    /*  01  */
  62.     "Ret code 02",        /*  02  */
  63.     "Invalid command",        /*  03  */
  64.     "Ret code 04",        /*  04  */
  65.     "Timed out",        /*  05  */
  66.     "Buffer too small",        /*  06  */
  67.     "Ret code 07",        /*  07  */
  68.     "Invalid session num",    /*  08  */
  69.     "No resource",        /*  09  */
  70.     "Session closed",        /*  0A  */
  71.     "Command cancelled",    /*  0B  */
  72.     "Ret code 0C",        /*  0C  */
  73.     "Dupl. local name",        /*  0D  */
  74.     "Name table full",        /*  0E  */
  75.     "Active session",        /*  0F  */
  76.     "Ret code 10",        /*  10  */
  77.     "Session table full",    /*  11  */
  78.     "No one listening",        /*  12  */
  79.     "Invalid name num",        /*  13  */
  80.     "No answer",        /*  14  */
  81.     "No local name",        /*  15  */
  82.     "Name in use",        /*  16  */
  83.     "Name is deleted",        /*  17  */
  84.     "Abnormal end",        /*  18  */
  85.     "Name conflict",        /*  19  */
  86.     "Ret code 1A",        /*  1A  */
  87.     "Ret code 1B",        /*  1B  */
  88.     "Ret code 1C",        /*  1C  */
  89.     "Ret code 1D",        /*  1D  */
  90.     "Ret code 1E",        /*  1E  */
  91.     "Ret code 1F",        /*  1F  */
  92.     "Ret code 20",        /*  20  */
  93.     "Card busy",        /*  21  */
  94.     "Too many cmds",        /*  22  */
  95.     "Invalid card num",        /*  23  */
  96.     "Cancel done",        /*  24  */
  97.     "Ret code 25",        /*  25  */
  98.     "Cannot cancel"        /*  26  */
  99. };
  100.  
  101. /*-------------------------------------------------------------------------*/
  102.     char * _TLXFUNC NBSetName(char *aBuffer, const char *aName)
  103.  
  104. /*  Stores a name in NetBIOS format, i.e. with space padding and a
  105.     terminating '\0'.
  106.  
  107.     Parameters:
  108.     aBuffer    = pointer to name buffer; should be at least NB_NAMELEN bytes
  109.     aName    = pointer to C-style name
  110.  
  111.     Return value:
  112.     aBuffer
  113. ---------------------------------------------------------------------------*/
  114. {
  115.     size_t slen = strlen(aName);
  116.  
  117.     strncpy(aBuffer, aName, NB_NAMELEN-1);
  118.     while (slen < NB_NAMELEN - 1)
  119.     aBuffer[slen++] = ' ';
  120.     aBuffer[NB_NAMELEN - 1] = 0;
  121.  
  122.     return aBuffer;
  123. }
  124.  
  125. /*-------------------------------------------------------------------------*/
  126.     char * _TLXFUNC NBGetName(char *aBuffer, const char *aName)
  127.  
  128. /*  Converts the NetBIOS name stored in aName to a normal C-style string.
  129.     Trailing spaces are removed.
  130.  
  131.     Parameters:
  132.     aBuffer    = pointer to name buffer (at least NB_NAMELEN bytes)
  133.     aName    = pointer to the NetBIOS formatted name
  134.  
  135.     Return value:
  136.     aBuffer
  137. ---------------------------------------------------------------------------*/
  138. {
  139.     int i;
  140.  
  141.     memcpy(aBuffer, aName, NB_NAMELEN);
  142.     aBuffer[NB_NAMELEN - 1] = 0;
  143.  
  144.     for (i = NB_NAMELEN - 2; i >= 0 && (aBuffer[i] == 0 || aBuffer[i] == ' ');
  145.         i--)
  146.     {
  147.     aBuffer[i] = 0;
  148.     }
  149.  
  150.     return aBuffer;
  151. }
  152.  
  153. /*-------------------------------------------------------------------------*/
  154.     char * _TLXFUNC NBGetLocalName(TLNCB _Far *aNCB, char *aBuffer)
  155.  
  156. /*  Returns the local name stored in an TLNCB in a normal C-style string.
  157.     Trailing spaces are removed.
  158.  
  159.     Parameters:
  160.     aNCB    = pointer to TLNCB
  161.     aBuffer    = pointer to name buffer (at least NB_NAMELEN bytes)
  162.  
  163.     Return value:
  164.     aBuffer
  165. ---------------------------------------------------------------------------*/
  166. {
  167.     return NBGetName(aBuffer, aNCB->mLocalName);
  168. }
  169.  
  170. /*-------------------------------------------------------------------------*/
  171.     char * _TLXFUNC NBGetRemoteName(TLNCB _Far *aNCB, char *aBuffer)
  172.  
  173. /*  Returns the remote name stored in an TLNCB in a normal C-style string.
  174.     Trailing spaces are removed.
  175.  
  176.     Parameters:
  177.     aNCB    = pointer to TLNCB
  178.     aBuffer    = pointer to name buffer (at least NB_NAMELEN bytes)
  179.  
  180.     Return value:
  181.     aBuffer
  182. ---------------------------------------------------------------------------*/
  183. {
  184.     return NBGetName(aBuffer, aNCB->mRemoteName);
  185. }
  186.  
  187. /*-------------------------------------------------------------------------*/
  188.     void _TLXFUNC NBSetLocalName(TLNCB _Far *aNCB, const char *aName)
  189.  
  190. /*  Sets the local name in an TLNCB from a normal C-style string.
  191.  
  192.     Parameters:
  193.     aNCB    = pointer to TLNCB
  194.     aName    = pointer to the name
  195. ---------------------------------------------------------------------------*/
  196. {
  197.     NBSetName(aNCB->mLocalName, aName);
  198. }
  199.  
  200. /*-------------------------------------------------------------------------*/
  201.     void _TLXFUNC NBSetRemoteName(TLNCB _Far *aNCB, const char *aName)
  202.  
  203. /*  Sets the remote name in an TLNCB from a normal C-style string.
  204.  
  205.     Parameters:
  206.     aNCB    = pointer to TLNCB
  207.     aName    = pointer to the name
  208. ---------------------------------------------------------------------------*/
  209. {
  210.     NBSetName(aNCB->mRemoteName, aName);
  211. }
  212.  
  213. /*-------------------------------------------------------------------------*/
  214.     void _TLXFUNC NBClearNCB(TLNCB _Far *aNCB)
  215.  
  216. /*  Clears the contents of the TLNCB.
  217.  
  218.     Parameters:
  219.     aNCB    = pointer to the TLNCB to be cleared.
  220. ---------------------------------------------------------------------------*/
  221. {
  222.     _fmemset(aNCB, 0, sizeof(TLNCB));
  223. }
  224.  
  225. /*-------------------------------------------------------------------------*/
  226.     const char * _TLXFUNC NBErrorMsg(uint16 result)
  227.  
  228. /*  Returns an error message based on the NetBIOS result code.
  229.  
  230.     Parameters:
  231.     result    = NetBIOS result code
  232.  
  233.     Return value:
  234.     Pointer to an error message
  235. ---------------------------------------------------------------------------*/
  236. {
  237.     return result <= MAXMESSAGE ? gNetBIOSMessage[result] : "Unknown error";
  238. }
  239.  
  240. /*-------------------------------------------------------------------------*/
  241.     bool _TLXFUNC NBInstalled(void)
  242.  
  243. /*  Tests the NetBIOS installed state.
  244.  
  245.     Parameters:
  246.     none
  247.  
  248.     Return value:
  249.     Nonzero if NetBIOS is installed, else zero.
  250. ---------------------------------------------------------------------------*/
  251. {
  252.     bool installed = false;
  253.     uint16 result;
  254.     TLNCB ncb;
  255.  
  256. #if defined(__IBMC__) || defined(__IBMCPP__)
  257.  
  258.     // These compilers do not support inline assembly; we'll have to
  259.     // find some other way to implement the search for the int 5Ch
  260.     // vector. To avoid compilation errors, we just insert an assertion
  261.     // here.
  262.  
  263.     TLX_ASSERT_UNREACHABLE;        // Replace by genuine code some day
  264.  
  265. #else    // Not IBM C Set/2 or IBM C Set++
  266.  
  267.     // Check for a nonzero int 5Ch vector
  268.  
  269.     __asm {
  270.     push    bx
  271.     push    es
  272.     mov    ax,0x355C    /* Get Vector 5Ch */
  273.     int    0x21
  274.     mov    ax,es
  275.     or    ax,bx
  276.     jz    NotInstalled
  277.     mov    ax,1
  278.   #ifdef __BORLANDC__        // Borland does not allow assembly labels
  279.     }
  280.   #endif
  281.  
  282.     NotInstalled:
  283.  
  284.   #ifdef __BORLANDC__
  285.     __asm {
  286.   #endif
  287.     pop    es
  288.     pop    bx
  289.     mov    installed,ax
  290.     }
  291. #endif    // IBM C Set/2 or IBM C Set++
  292.  
  293.     if (!installed) return false;
  294.  
  295.     // Issue non-existing command 0xFF, then test for error
  296.  
  297.     ncb.mCommand = 0xFF;
  298.     ncb.mCallBack = 0;
  299.     result = NBExecute(&ncb);
  300.  
  301.     // Errors are broken down into the following categories:
  302.     //
  303.     // - 0x40-0x4F "unusual network condition"
  304.     // - 0x50-0xFE "adapter malfunction"
  305.     // - various individual error codes
  306.     //
  307.     // Any of these errors indicates the presence of NetBIOS.
  308.  
  309.     if (result >= 0x40 && result <= 0xFE)
  310.     {
  311.     installed = true;
  312.     }
  313.     else
  314.     {
  315.     switch (result)
  316.     {
  317.         case NB_ERR_BADCOMMAND:
  318.         case NB_ERR_BADADAPTER:
  319.         installed = true;
  320.         break;
  321.         default:
  322.         installed = false;
  323.         break;
  324.     }
  325.     }
  326.  
  327.     return installed;
  328. }
  329.  
  330. /*-------------------------------------------------------------------------*/
  331.     uint16 _TLXFUNC NBExecute(TLNCB _Far *aNCB)
  332.  
  333. /*  Issues a NetBIOS command.
  334.  
  335.     Parameters:
  336.     aNCB    = pointer to the formatted TLNCB
  337.  
  338.     Return value:
  339.     Return code from NetBIOS.
  340. ---------------------------------------------------------------------------*/
  341. {
  342.     // We store the command early, because we need it later on and the
  343.     // associated TLNCB might be released by the time the NetBIOS call returns.
  344.  
  345.     uint8 command = aNCB->mCommand;
  346.     uint16 result;
  347.  
  348. #if OS_DOSXXX
  349.     __asm {
  350.     les    bx,aNCB
  351.     mov    ax,0x0100
  352.     int    0x5C        /* Call NetBIOS, result in AL */
  353.     xor    ah,ah        /* Clear AH */
  354.     mov    result,ax    /* Store immediate result */
  355.     }
  356. #elif OS_WINXXX
  357.     __asm {
  358.     les    bx,aNCB
  359.     mov    ax,0x0100
  360.     }
  361.     NetBIOSCall();        /* Call NetBIOS, result in AL */
  362.     __asm {
  363.     xor    ah,ah        /* Clear AH */
  364.     mov    result,ax    /* Store immediate result */
  365.     }
  366. #elif OS_OS2
  367.     // We have not yet implemented NetBIOS support for OS/2. However,
  368.     // we do allow compilation, only the resulting code should not be
  369.     // executed.
  370.  
  371.     TLX_ASSERT_UNREACHABLE;
  372. #else
  373.     #error Unsupported operating system
  374. #endif
  375.  
  376.     // At this point, we have the immediate return code in 'result'.
  377.     // However, if the command had the wait option set, we need the final
  378.     // completion code, which is stored inside the TLNCB. In the case
  379.     // of a wait option, we can be sure that the TLNCB still exists
  380.     // (no intervening callback functions).
  381.  
  382.     if ((command & NB_NOWAIT) == 0)
  383.     {
  384.     result = aNCB->mCompletion;
  385.     }
  386.  
  387.     return result;
  388. }
  389.  
  390. /*-------------------------------------------------------------------------*/
  391.     uint16 _TLXFUNC NBCancel(TLNCB _Far *aNCB)
  392.  
  393. /*  Cancels a given NCB. The NCB is passed in. It is *not* possible to
  394.     cancel the following NetBIOS commands:
  395.  
  396.     - ADD NAME
  397.     - ADD GROUP NAME
  398.     - DELETE NAME
  399.     - SEND DATAGRAM
  400.     - SEND BROADCAST DATAGRAM
  401.     - SESSION STATUS
  402.     - RESET
  403.     - CANCEL
  404.  
  405.     Parameters:
  406.     none
  407.  
  408.     Return value:
  409.     N/A
  410. ---------------------------------------------------------------------------*/
  411. {
  412.     TLNCB ncb;
  413.  
  414.     NBClearNCB(&ncb);
  415.     ncb.mCommand = NB_CANCEL;
  416.     ncb.mBuffer = aNCB;
  417.     ncb.mAdapter = 0;
  418.  
  419.     return NBExecute(&ncb);
  420. }
  421.  
  422. /*-------------------------------------------------------------------------*/
  423.     uint16 _TLXFUNC NBReset(uint8 maxSes, uint8 maxNCB, uint8 adapt)
  424.  
  425. /*  Resets the given NetBIOS adapter.
  426.  
  427.     Parameters:
  428.     none
  429.  
  430.     Return value:
  431.     N/A
  432. ---------------------------------------------------------------------------*/
  433. {
  434.     TLNCB ncb;
  435.  
  436.     NBClearNCB(&ncb);
  437.     ncb.mCommand = NB_RESET;
  438.     ncb.mLSN = maxSes;
  439.     ncb.mNameNo = maxNCB;
  440.     ncb.mAdapter = adapt;
  441.  
  442.     return NBExecute(&ncb);
  443. }
  444.  
  445. uint16 _TLXFUNC NBAdapterStatus(const char *aName, TLAdapterStatus _Far *aStatus)
  446. {
  447.     TLNCB ncb;
  448.  
  449.     NBClearNCB(&ncb);
  450.     ncb.mCommand = NB_STATUS;
  451.     ncb.mBuffer = aStatus;
  452.     ncb.mSize = sizeof(TLAdapterStatus);
  453.     NBSetRemoteName(&ncb, aName);
  454.  
  455.     return NBExecute(&ncb);
  456. }
  457.  
  458. uint16 _TLXFUNC NBAddName(const char *aName, uint8 *aNameNo)
  459. {
  460.     TLNCB ncb;
  461.     uint16 result;
  462.  
  463.     NBClearNCB(&ncb);
  464.     ncb.mCommand = NB_ADDNAME;
  465.     NBSetLocalName(&ncb, aName);
  466.  
  467.     if ((result = NBExecute(&ncb)) == 0)
  468.     {
  469.     *aNameNo = ncb.mNameNo;
  470.     }
  471.  
  472.     return result;
  473. }
  474.  
  475. uint16 _TLXFUNC NBAddNameNW(TLNCB _Far *aNCB, const char *aName, callback_f aCallBack)
  476. {
  477.     NBClearNCB(aNCB);
  478.     aNCB->mCommand = NB_ADDNAME | NB_NOWAIT;
  479.     aNCB->mCallBack = aCallBack;
  480.     NBSetLocalName(aNCB, aName);
  481.  
  482.     return NBExecute(aNCB);
  483. }
  484.  
  485. uint16 _TLXFUNC NBAddGroup(const char *aName, uint8 *aNameNo)
  486. {
  487.     TLNCB ncb;
  488.     uint16 result;
  489.  
  490.     NBClearNCB(&ncb);
  491.     ncb.mCommand = NB_ADDGROUP;
  492.     NBSetLocalName(&ncb, aName);
  493.  
  494.     if ((result = NBExecute(&ncb)) == 0)
  495.     {
  496.     *aNameNo = ncb.mNameNo;
  497.     }
  498.     return result;
  499. }
  500.  
  501. uint16 _TLXFUNC NBAddGroupNW(TLNCB _Far *aNCB, const char *aName, callback_f aCallBack)
  502. {
  503.     NBClearNCB(aNCB);
  504.     aNCB->mCommand = NB_ADDGROUP | NB_NOWAIT;
  505.     aNCB->mCallBack = aCallBack;
  506.     NBSetLocalName(aNCB, aName);
  507.  
  508.     return NBExecute(aNCB);
  509. }
  510.  
  511. uint16 _TLXFUNC NBDeleteName(const char *aName)
  512. {
  513.     TLNCB ncb;
  514.  
  515.     NBClearNCB(&ncb);
  516.     ncb.mCommand = NB_DELETENAME;
  517.     NBSetLocalName(&ncb, aName);
  518.  
  519.     return NBExecute(&ncb);
  520. }
  521.  
  522. uint16 _TLXFUNC NBDeleteNameNW(TLNCB _Far *aNCB, const char *aName, callback_f aCallBack)
  523. {
  524.     NBClearNCB(aNCB);
  525.     aNCB->mCommand = NB_DELETENAME | NB_NOWAIT;
  526.     aNCB->mCallBack = aCallBack;
  527.     NBSetLocalName(aNCB, aName);
  528.  
  529.     return NBExecute(aNCB);
  530. }
  531.  
  532. uint16 _TLXFUNC NBSendDatagram(TLNCB _Far *aNCB)
  533. {
  534.     aNCB->mCommand = NB_SENDDATAGRAM;
  535.  
  536.     return NBExecute(aNCB);
  537. }
  538.  
  539. uint16 _TLXFUNC NBSendDatagramNW(TLNCB _Far *aNCB)
  540. {
  541.     aNCB->mCommand = NB_SENDDATAGRAM | NB_NOWAIT;
  542.  
  543.     return NBExecute(aNCB);
  544. }
  545.  
  546. #endif    // _DATA_NEAR    // Temporary hack
  547. #endif    // DOS or Windows
  548.