home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / LANMAN.ZIP / INIT.C next >
C/C++ Source or Header  |  1991-01-01  |  15KB  |  404 lines

  1. /*-------------------------------------------------------------------
  2.   INIT.C -- PBX initialization related routines
  3.  
  4.   Description:
  5.  
  6.   These various routines are used during PBX initialization to
  7.   allocate memory, initialize memory, and to create the child
  8.   threads.
  9.  
  10.   Author:  Brendan Dixon
  11.            Microsoft, inc.
  12.            LAN Manager Developer Support
  13.  
  14.   This code example is provided for demonstration purposes only.
  15.   Microsoft makes no warranty, either express or implied,
  16.   as to its usability in any given situation.
  17. -------------------------------------------------------------------*/
  18.  
  19. // Includes ---------------------------------------------------------
  20. #define   INCL_DOS
  21. #define   INCL_DOSERRORS
  22. #include  <os2.h>
  23.  
  24. #define   INCL_NETSERVICE
  25. #define   INCL_NETWKSTA
  26. #define   INCL_NETERRORS
  27. #include  <lan.h>
  28.  
  29. #include  <process.h>
  30. #include  <stddef.h>
  31. #include  <stdio.h>
  32. #include  <string.h>
  33.  
  34. #include  "pbxsrv.h"
  35.  
  36.  
  37. /* AllocatePipeMgrMem -----------------------------------------------
  38.   Description:  Allocate and initialize memory structures used
  39.                 by the PipeMgr thread
  40.   Input      :  None
  41.   Output     :  None, globals modified
  42. -------------------------------------------------------------------*/
  43. void AllocatePipeMgrMem(void)
  44. {
  45.   USHORT  usRetCode;                      // Return code
  46.  
  47.   // Allocate buffer for PipeMgr thread
  48.   usRetCode = DosAllocSeg(pbPBXMem->usLineBufSize,    // Size
  49.                           &(pbPBXMem->selBuf),        // Selector
  50.                           SEG_GETTABLE);              // Shared
  51.   if (usRetCode) {
  52.     ERRRPT("Unable to allocate PipeMgr buffer, DosAllocSeg",
  53.            usRetCode, Error);
  54.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  55.                                   SERVICE_UIC_M_MEMORY);
  56.     ExitHandler();
  57.   }
  58.   pbPBXMem->pbBuf = MAKEP(pbPBXMem->selBuf, 0);
  59.  
  60.   // Allocate PIPESEMSTATE array (for the PipeMgr thread)
  61.   // The maximum number of PIPESEMSTATE records ever returned by
  62.   // the DosQNmPipeSemState call (see PIPEMGR.C) is three times the
  63.   // number of pipes plus one extra for the NPSS_EOI record.
  64.   pbPBXMem->usPSemStateSize = ((3*pbPBXMem->usLines)+1) *
  65.                                          sizeof(PIPESEMSTATE);
  66.   usRetCode = DosAllocSeg(pbPBXMem->usPSemStateSize,  // Size
  67.                           &(pbPBXMem->selPSemState),  // Selector
  68.                           SEG_GETTABLE);              // Shared
  69.   if (usRetCode) {
  70.     ERRRPT(
  71.       "Unable to allocate PipeMgr PIPESEMSTATE array, DosAllocSeg",
  72.       usRetCode, Error);
  73.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  74.                                   SERVICE_UIC_M_MEMORY);
  75.     ExitHandler();
  76.   }
  77.   pbPBXMem->aPSemState = MAKEP(pbPBXMem->selPSemState, 0);
  78.  
  79.   return;
  80. }
  81.  
  82.  
  83. /* AllocateRouterMem ------------------------------------------------
  84.   Description:  Allocate and initialize structures used by each
  85.                 Router thread
  86.   Input      :  None
  87.   Output     :  None, globals modified
  88. -------------------------------------------------------------------*/
  89. void AllocateRouterMem(void)
  90. {
  91.   USHORT  usPSemStateSize;                // PIPESEMSTATE array size
  92.   USHORT  usRNum;                         // Structure number
  93.   CHAR    pszSem[255];                    // Semaphore name
  94.   USHORT  usRetCode;                      // Return code
  95.  
  96.   // Allocate Router thread structures
  97.   usRetCode = DosAllocSeg(
  98.                  pbPBXMem->usRThreadCnt * sizeof(RTHREAD), // Size
  99.                  &(pbPBXMem->selRouters),              // Selector
  100.                  SEG_GETTABLE);                        // Shared
  101.   if (usRetCode) {
  102.     ERRRPT("Unable to allocate Router structures, DosAllocSeg",
  103.            usRetCode, Error);
  104.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  105.                                   SERVICE_UIC_M_MEMORY);
  106.     ExitHandler();
  107.   }
  108.   pbPBXMem->abRouters = MAKEP(pbPBXMem->selRouters, 0);
  109.  
  110.   // Determine size of PIPESEMSTATE array for each thread
  111.   // Again, allocate space for three records per each pipe (there
  112.   // two pipes per connection) plus one extra for the NPSS_CLOSE
  113.   // record
  114.   usPSemStateSize = ((3*(pbPBXMem->usConnsPerThread*2))+1) *
  115.                                            sizeof(PIPESEMSTATE);
  116.  
  117.   for (usRNum=0; usRNum < pbPBXMem->usRThreadCnt; usRNum++) {
  118.     pbPBXMem->abRouters[usRNum].sRouterID    = 0;
  119.     pbPBXMem->abRouters[usRNum].cConnections = 0;
  120.     pbPBXMem->abRouters[usRNum].semRAccess   = 0;
  121.  
  122.     // Create the pipe semaphore for the thread
  123.     sprintf(pszSem, ROUTERSEM, usRNum);
  124.     usRetCode = DosCreateSem(
  125.                    CSEM_PUBLIC,
  126.                    &(pbPBXMem->abRouters[usRNum].hsemRouter),
  127.                    pszSem);
  128.     if (usRetCode) {
  129.       ERRRPT("DosCreateSem", usRetCode, Error);
  130.       ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM,
  131.                                     usRetCode);
  132.       ExitHandler();
  133.     }
  134.  
  135.     // Set the Router semaphore to capture the first pipe events
  136.     DosSemSet(pbPBXMem->abRouters[usRNum].hsemRouter);
  137.  
  138.     // Allocate line buffer
  139.     usRetCode = DosAllocSeg(
  140.              pbPBXMem->usLineBufSize,                  // Size
  141.              &(pbPBXMem->abRouters[usRNum].selLineBuf),// Selector
  142.              SEG_GETTABLE);                            // Shared
  143.     if (usRetCode) {
  144.       ERRRPT("Unable to allocate Router line buffer, DosAllocSeg",
  145.              usRetCode, Error);
  146.       ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  147.                                     SERVICE_UIC_M_MEMORY);
  148.       ExitHandler();
  149.     }
  150.     pbPBXMem->abRouters[usRNum].pbLineBuf =
  151.                    MAKEP(pbPBXMem->abRouters[usRNum].selLineBuf, 0);
  152.  
  153.     // Allocate NPSS_RDATA array
  154.     usRetCode = DosAllocSeg(
  155.            2*pbPBXMem->usConnsPerThread*sizeof(ROUTEENT),// Size
  156.            &(pbPBXMem->abRouters[usRNum].selRData),      // Selector
  157.            SEG_GETTABLE);                                // Shared
  158.     if (usRetCode) {
  159.       ERRRPT(
  160.         "Unable to allocate Router NPSS_RDATA array, DosAllocSeg",
  161.         usRetCode, Error);
  162.       ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  163.                                     SERVICE_UIC_M_MEMORY);
  164.       ExitHandler();
  165.     }
  166.     pbPBXMem->abRouters[usRNum].aRData =
  167.                      MAKEP(pbPBXMem->abRouters[usRNum].selRData, 0);
  168.  
  169.     // Allocate NPSS_CLOSE array
  170.     usRetCode = DosAllocSeg(
  171.            2*pbPBXMem->usConnsPerThread*sizeof(ROUTEENT),// Size
  172.            &(pbPBXMem->abRouters[usRNum].selClose),      // Selector
  173.            SEG_GETTABLE);                                // Shared
  174.     if (usRetCode) {
  175.       ERRRPT(
  176.         "Unable to allocate Router NPSS_CLOSE array, DosAllocSeg",
  177.         usRetCode, Error);
  178.       ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  179.                                     SERVICE_UIC_M_MEMORY);
  180.       ExitHandler();
  181.     }
  182.     pbPBXMem->abRouters[usRNum].aClose =
  183.                      MAKEP(pbPBXMem->abRouters[usRNum].selClose, 0);
  184.  
  185.     // Allocate PIPESEMSTATE array
  186.     usRetCode = DosAllocSeg(
  187.            usPSemStateSize,                            // Size
  188.            &(pbPBXMem->abRouters[usRNum].selPSemState),// Selector
  189.            SEG_GETTABLE);                              // Shared
  190.     if (usRetCode) {
  191.       ERRRPT(
  192.        "Unable to allocate Router PIPESEMSTATE array, DosAllocSeg",
  193.        usRetCode, Error);
  194.       ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  195.                                     SERVICE_UIC_M_MEMORY);
  196.       ExitHandler();
  197.     }
  198.     pbPBXMem->abRouters[usRNum].aPSemState =
  199.                 MAKEP(pbPBXMem->abRouters[usRNum].selPSemState, 0);
  200.     pbPBXMem->abRouters[usRNum].usPSemStateSize = usPSemStateSize;
  201.   }
  202.  
  203.   return;
  204. }
  205.  
  206.  
  207. /* AllocateRoutingTable ---------------------------------------------
  208.   Description:  Build and initialize the PBX routing table
  209.   Input      :  None
  210.   Output     :  None, globals modified
  211. -------------------------------------------------------------------*/
  212. void AllocateRoutingTable(void)
  213. {
  214.   USHORT  usLineNum;                      // Current line number
  215.   USHORT  usRetCode;                      // Return code
  216.  
  217.   // Allocate Routing Table
  218.   usRetCode = DosAllocSeg(
  219.                   pbPBXMem->usLines * sizeof(ROUTEENT), // Size
  220.                   &(pbPBXMem->selRTable),               // Selector
  221.                   SEG_GETTABLE);                        // Shared
  222.   if (usRetCode) {
  223.     ERRRPT("Unable to allocate routing table, DosAllocSeg",
  224.            usRetCode, Error);
  225.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  226.                                   SERVICE_UIC_M_MEMORY);
  227.     ExitHandler();
  228.   }
  229.   pbPBXMem->abRTable = MAKEP(pbPBXMem->selRTable, 0);
  230.  
  231.   // Initialize Routing Table
  232.   for (usLineNum = 0;
  233.        usLineNum < pbPBXMem->usLines;
  234.        usLineNum++) {
  235.  
  236.     // Initialize information fields
  237.     pbPBXMem->abRTable[usLineNum].pszName[0]      = '\0';
  238.     pbPBXMem->abRTable[usLineNum].usClientType    = 0;
  239.     pbPBXMem->abRTable[usLineNum].fState          = Available;
  240.     pbPBXMem->abRTable[usLineNum].usConnection    = usLineNum;
  241.     pbPBXMem->abRTable[usLineNum].usWSpace =
  242.                                       pbPBXMem->usLineBufSize;
  243.     pbPBXMem->abRTable[usLineNum].usRData  = 0;
  244.     pbPBXMem->abRTable[usLineNum].hLine    = 0;
  245.   }
  246.  
  247.   return;
  248. }
  249.  
  250.  
  251. /* BuildPBXMsg ------------------------------------------------------
  252.   Description:  Build an announcement message consisting of the
  253.                 computer name on which PBX is executing prepended
  254.                 with two back-slashes (as in a UNC name)
  255.   Input      :  None
  256.   Output     :  None, globals modified
  257. -------------------------------------------------------------------*/
  258. void BuildPBXMsg(void)
  259. {
  260.   USHORT                    usBufSize;       // Buffer size in bytes
  261.   SEL                       selBuf;          // Buffer selector
  262.   struct wksta_info_10 _far *pbWkstaInfo10;  // Wksta structure
  263.   USHORT                    usRetCode;       // Return code
  264.  
  265.   // Make one call to get the size of buffer required
  266.   usRetCode = NetWkstaGetInfo(NULL,     // Local
  267.                               10,       // Basic info
  268.                               NULL,     // Get buffer size
  269.                               0,        // No buffer
  270.                               &usBufSize); // Return size needed
  271.   if (usRetCode && usRetCode != NERR_BufTooSmall) {
  272.     ERRRPT("NetWkstaGetInfo", usRetCode, Error);
  273.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM, usRetCode);
  274.     ExitHandler();
  275.   }
  276.  
  277.   // Allocate the needed buffer
  278.   usRetCode     = DosAllocSeg(usBufSize, &selBuf, SEG_NONSHARED);
  279.   if (usRetCode) {
  280.     ERRRPT("DosAllocSeg", usRetCode, Error);
  281.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  282.                                   SERVICE_UIC_M_MEMORY);
  283.     ExitHandler();
  284.   }
  285.   pbWkstaInfo10 = MAKEP(selBuf, 0);
  286.  
  287.   // Get the workstation information
  288.   usRetCode = NetWkstaGetInfo(
  289.                       NULL,                       // Local
  290.                       10,                         // Basic info
  291.                       (CHAR _far *)pbWkstaInfo10, // Buffer addr
  292.                       usBufSize,                  // Buffer size
  293.                       &usBufSize);                // Bytes avail
  294.   if (usRetCode) {
  295.     ERRRPT("NetWkstaGetInfo", usRetCode, Error);
  296.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM, usRetCode);
  297.     ExitHandler();
  298.   }
  299.  
  300.   // Build announcement message using the current computer name
  301.   else {
  302.     strcpy(pbPBXMem->pszPBXMsg, "\\\\");
  303.     strcat(pbPBXMem->pszPBXMsg,
  304.            pbWkstaInfo10->wki10_computername);
  305.     pbPBXMem->usPBXMsgSize = strlen(pbPBXMem->pszPBXMsg) + 1;
  306.   }
  307.  
  308.   // Free allocated memory
  309.   if (usRetCode = DosFreeSeg(selBuf))
  310.     ERRRPT("DosFreeSeg", usRetCode, Warning);
  311.  
  312.   return;
  313. }
  314.  
  315.  
  316. /* CreateThreads ----------------------------------------------------
  317.   Description:  Create the MakePipe, PipeMgr, and Router threads
  318.   Input      :  None
  319.   Output     :  None
  320. -------------------------------------------------------------------*/
  321. void CreateThreads(void)
  322. {
  323.   CHAR    pszMsg[80];                     // Error message buffer
  324.   USHORT  usRetCode;                      // Return code
  325.  
  326.   // Because pipes are created by the MakePipe thread, transferred
  327.   // to the PipeMgr thread, and finally to a Router thread; Router
  328.   // threads are created first, then the PipeMgr thread, and finally
  329.   // the MakePipe thread.  This ensures that all threads will be
  330.   // fully ready to handle pipes as they become available.
  331.  
  332.   // Create Router threads
  333.   { USHORT       usRNum;                  // Current Router thread
  334.     SHORT        sThreadID;               // Thread ID
  335.  
  336.     for (usRNum=0; usRNum < pbPBXMem->usRThreadCnt; usRNum++) {
  337.       // Create the thread
  338.       sThreadID = _beginthread(
  339.                       (void (_cdecl _far *)(void _far *))Router,
  340.                       NULL,
  341.                       ROUTERSTACKSIZE,
  342.                       (void *)usRNum);
  343.       if (sThreadID < 0) {
  344.         sprintf(pszMsg, "Unable to start Router thread %u", usRNum);
  345.         ERRRPT(pszMsg, 0, Error);
  346.         ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  347.                                       SERVICE_UIC_M_THREADS);
  348.         ExitHandler();
  349.       }
  350.  
  351.       // Save the thread number
  352.       pbPBXMem->abRouters[usRNum].sRouterID = sThreadID;
  353.     }
  354.   }
  355.  
  356.   // Create the PipeMgr thread
  357.   { SHORT sPipeMgrID;
  358.  
  359.     // Create the pipe semaphore
  360.     usRetCode = DosCreateSem(CSEM_PUBLIC,
  361.                              &(pbPBXMem->hsemPipeMgr),
  362.                              PIPEMGRSEM);
  363.     if (usRetCode) {
  364.       ERRRPT("DosCreateSem", usRetCode, Error);
  365.       ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM, usRetCode);
  366.       ExitHandler();
  367.     }
  368.  
  369.     // Set the semaphore to capture the first pipe events
  370.     DosSemSet(pbPBXMem->hsemPipeMgr);
  371.  
  372.     // Create the thread
  373.     sPipeMgrID = _beginthread(
  374.                        (void (_cdecl _far *)(void _far *))PipeMgr,
  375.                        NULL,
  376.                        PIPEMGRSTACKSIZE,
  377.                        NULL);
  378.     if (sPipeMgrID < 0) {
  379.       ERRRPT("Unable to start PipeMgr thread", 0, Error);
  380.       ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  381.                                     SERVICE_UIC_M_THREADS);
  382.       ExitHandler();
  383.     }
  384.   }
  385.  
  386.   // Create the MakePipe thread
  387.   { SHORT sMakePipeID;
  388.  
  389.     sMakePipeID = _beginthread(
  390.                         (void (_cdecl _far *)(void _far *))MakePipe,
  391.                         NULL,
  392.                         MPIPESTACKSIZE,
  393.                         NULL);
  394.     if (sMakePipeID < 0) {
  395.       ERRRPT("Unable to start MakePipe thread", 0, Error);
  396.       ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_RESOURCE,
  397.                                     SERVICE_UIC_M_THREADS);
  398.       ExitHandler();
  399.     }
  400.   }
  401.  
  402.   return;
  403. }
  404.