home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / os2 / npipe / clnpthrd.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  11KB  |  367 lines

  1. /*==============================================================*\
  2.  *  clnpthrd.c - Pipe Server end of Tic-Tac-Toe sample app
  3.  *      Copyright 1992 IBM Corp.
  4.  *--------------------------------------------------------------
  5.  *
  6.  *  DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  7.  *  sample code created by IBM Corporation. This sample code is not
  8.  *  part of any standard or IBM product and is provided to you solely
  9.  *  for  the purpose of assisting you in the development of your
  10.  *  applications.  The code is provided "AS IS", without
  11.  *  warranty of any kind.  IBM shall not be liable for any damages
  12.  *  arising out of your use of the sample code, even if they have been
  13.  *  advised of the possibility of   such damages.                                                     *
  14.  *
  15.  *--------------------------------------------------------------
  16.  *
  17.  *  This c file contains the thread creation routines and
  18.  *  manages the named pipe.
  19.  *
  20. \*==============================================================*/
  21.  
  22.  
  23. /*--------------------------------------------------------------*\
  24.  *  Include files, macros, defined constants, and externs
  25. \*--------------------------------------------------------------*/
  26. #define INCL_WINHELP
  27. #define INCL_DOSPROCESS
  28. #define INCL_WINMESSAGEMGR
  29. #define INCL_WINWINDOWMGR
  30. #define INCL_DOSNMPIPES
  31. #define INCL_DOSFILEMGR
  32. #define INCL_DOSERRORS
  33. #define INCL_DOSSEMAPHORES
  34. #define INCL_WINDIALOGS
  35.  
  36. #include <os2.h>
  37. #include <string.h>
  38. #include <stdlib.h>
  39. #include <stdio.h>
  40. #include <stddef.h>
  41. #include "namepipe.h"
  42.  
  43. static struct _THREADPARAM {
  44.    CHAR  StartPipe[MAXPIPENAME];
  45.    CHAR  GamePipe[MAXPIPENAME];
  46.    BOOL  fMeFirst;
  47.    };
  48.  
  49. typedef struct _THREADPARAM THREADPARAM;
  50.  
  51. #include "clnpmain.h"
  52. #include "clnpxtrn.h"
  53. #include "clnpglbl.h"
  54.  
  55. #define  STACKSIZE  8192
  56.  
  57. CHAR  pszServer[MAXSERVERNAME];
  58.  
  59. BOOL InitThread()
  60. {
  61.    static THREADPARAM  tpPipeNames;
  62.    ULONG               usErrorMsg=0;
  63.  
  64.    /* load and open dialog box to get server name from user */
  65.    if (IDC_OK == WinDlgBox(HWND_DESKTOP, hwndMainFrame, ServerDlgProc, 0, IDD_SERVER, NULL))
  66.    {
  67.       strcpy(tpPipeNames.StartPipe, "\\\\"); 
  68.       strcat(tpPipeNames.StartPipe, pszServer);
  69.       strcat(tpPipeNames.StartPipe, START_PIPE_NAME);
  70.       strcpy(tpPipeNames.GamePipe, "\\\\");   
  71.       strcat(tpPipeNames.GamePipe, pszServer);
  72.       strcat(tpPipeNames.GamePipe, GAME_PIPE_NAME);
  73.    }
  74.  
  75.    else
  76.    {
  77.       strcpy(tpPipeNames.StartPipe, START_PIPE_NAME);
  78.       strcpy(tpPipeNames.GamePipe, GAME_PIPE_NAME);
  79.    }
  80.  
  81.    /* create event semaphore to communicate with pipe thread */
  82.    if ((BOOL)DosCreateEventSem(NULL, &hevWritePipe, DC_SEM_SHARED, FALSE))
  83.    {
  84.       usErrorMsg = IDMSG_CREATE_SEM_FAILED;
  85.    }
  86.  
  87.    else if (0 > _beginthread(ManagePipe,
  88.                              NULL,
  89.                              STACKSIZE,
  90.                              (VOID *)&tpPipeNames))
  91.    {
  92.       usErrorMsg = IDMSG_CREATE_THREAD_FAILED;
  93.    }
  94.  
  95.    if (usErrorMsg != 0)
  96.    {
  97.       MessageBox(hwndMain, usErrorMsg, 0, MB_WARNING | MB_OK, NULL, TRUE);
  98.    }
  99.  
  100.    return((BOOL)(!(BOOL)usErrorMsg));
  101. }
  102.  
  103.  
  104. MRESULT EXPENTRY ServerDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  105. {
  106.    ULONG        ulErrorReply=0, ulUserCommand;
  107.    FILESTATUS   fs;
  108.    APIRET       apiRC;
  109.    UCHAR        PathName[MAXPIPENAME];
  110.  
  111.    switch (msg)
  112.    {
  113.       case WM_COMMAND:
  114.          switch ((ulUserCommand=SHORT1FROMMP(mp1)))
  115.          {
  116.             case ID_OK:
  117.                if (0 != WinQueryWindowText(WinWindowFromID(hwnd,
  118.                                                            DID_PIPE_SVR),
  119.                                            MAXSERVERNAME,
  120.                                            pszServer)
  121.                    && pszServer)
  122.                {
  123.                   strcpy(PathName, "\\\\");
  124.                   strcat(PathName, pszServer);
  125.                   strcat(PathName, GAME_PIPE_NAME);
  126.  
  127.                   while (ERROR_FILE_NOT_FOUND == (apiRC=DosQueryPathInfo(PathName,
  128.                                                                   FIL_STANDARD,
  129.                                                                   &fs,
  130.                                                                   sizeof(FILESTATUS)))
  131.                          || ERROR_PATH_NOT_FOUND == apiRC
  132.                          || ERROR_BAD_NETPATH == apiRC)
  133.                   {
  134.                      if (MBID_RETRY!=(ulErrorReply=MessageBox(hwnd,
  135.                                                IDMSG_INVALID_NAME,
  136.                                                0,
  137.                                                MB_CUAWARNING | MB_ABORTRETRYIGNORE,
  138.                                                NULL,
  139.                                                TRUE)))
  140.                      {
  141.                         if (MBID_ABORT == ulErrorReply)
  142.                         {
  143.                            ulUserCommand = ID_CANCEL;
  144.                         }
  145.  
  146.                         break;
  147.                      }
  148.                   }
  149.                }
  150.  
  151.                else
  152.                {
  153.                   ulUserCommand = ID_CANCEL;
  154.                }
  155.  
  156.             case ID_CANCEL:
  157.                WinDismissDlg(hwnd, ulUserCommand);
  158.                return (MRFROMLONG(0));
  159.          }
  160.          break;
  161.    }
  162.    return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  163. }
  164.  
  165.  
  166. VOID ManagePipe(VOID *tpPipeNames)
  167. {
  168.    BOOL    fSuccess=TRUE;
  169.    USHORT  usMsg;
  170.    ULONG   ulErrorMsg, ulIcon;
  171.    HPIPE   hpPipe;
  172.    PSZ     pszServer;
  173.    ULONG   ulAction;
  174.    APIRET  apiRC;
  175.  
  176. /*
  177.  *   Attempt to open named pipe.  If the pipe is busy, wait on it, and when
  178.  *   it becomes free try to open it again.  Continue until success or error.
  179.  */
  180.  
  181.    do
  182.    {
  183.       apiRC = DosOpen(((THREADPARAM *)tpPipeNames)->StartPipe,  /* pointer to filename      */
  184.                 (PHFILE) &hpPipe,            /* pointer to variable for file handle          */
  185.                 &ulAction,                   /* pointer to variable for action taken         */
  186.                 0L,                          /* file size if created or truncated            */
  187.                 0L,                          /* file attribute                               */
  188.                 FILE_OPEN,                   /* action taken if file exists/does not exist   */
  189.                 FS_CLI_STARTPIPE_OPEN_MODE,  /* open mode of file                            */
  190.                 NULL);                       /* pointer to structure for extended attributes */
  191.    }
  192.    while (ERROR_PIPE_BUSY == apiRC &&
  193.           !(BOOL)(apiRC=DosWaitNPipe(pszServer, NP_INDEFINITE_WAIT)));
  194.  
  195.    if (apiRC != 0)
  196.    {
  197.       ulErrorMsg = IDMSG_CONNECT_FAILED;
  198.       ulIcon = MB_CUAWARNING | MB_OK;
  199.       fSuccess = FALSE;
  200.    }
  201.  
  202.    if (TRUE == fSuccess)
  203.    {
  204.       /* connect to the game pipe */
  205.       if ((BOOL)(hpPipe = ConnectGamePipe(hpPipe,
  206.                                           ((THREADPARAM *)tpPipeNames)->GamePipe)))
  207.       {
  208.          /* enable the File-Start menu choice */
  209.          WinPostMsg(hwndMain, WM_START, MPVOID, MPVOID);
  210.  
  211.          while (WritePipe(hpPipe, &usMsg) &&
  212.                 usMsg != CLIENT_QUIT &&
  213.                 usMsg != ERROR_MSG)
  214.          {
  215.             if (!(BOOL)ReadPipe(hpPipe, &usMsg))
  216.             {
  217.                break;
  218.             }
  219.          }
  220.       }
  221.  
  222.       else
  223.       {
  224.          ulErrorMsg = IDMSG_CONNECT_FAILED;
  225.          ulIcon = MB_CUAWARNING | MB_OK;
  226.          fSuccess = FALSE;
  227.       }
  228.    }
  229.  
  230.    if (FALSE == fSuccess)
  231.    {
  232.       WinPostMsg(hwndMain,
  233.                  WM_MSG,
  234.                  MPFROM2SHORT(ulErrorMsg, ulIcon),
  235.                  MPFROMLONG(apiRC));
  236.    }
  237.  
  238.    if (!fAppExit)
  239.    {
  240.       fAppExit = TRUE;
  241.    }
  242.  
  243.    DosCloseEventSem(hevWritePipe);
  244.    DosClose(hpPipe);
  245.    fThrdsDead = TRUE;
  246. }
  247.  
  248.  
  249. /*
  250.  *   open game pipe, notify server of success or failure, and close start pipe.
  251.  */
  252. HPIPE ConnectGamePipe(HPIPE hpPipe, PSZ pszGamePipe)
  253. {
  254.    HPIPE     hpGamePipe;
  255.    USHORT    usMsg=ERROR_MSG;
  256.    ULONG     ulCount, ulAction;
  257.    PIPE_MSG  pmsgPipeMsg;
  258.    APIRET    apiRC;
  259.  
  260.    /* block on read, and open game pipe if server sends START_MSG */
  261.    if ((BOOL)ReadPipe(hpPipe, &usMsg) &&
  262.        START_MSG == usMsg)
  263.    {
  264.  
  265.       do
  266.       {
  267.          apiRC = DosOpen(pszGamePipe,         /* pointer to filename                          */
  268.                   (PHFILE) &hpGamePipe,       /* pointer to variable for file handle          */
  269.                   &ulAction,                  /* pointer to variable for action taken         */
  270.                   0L,                         /* file size if created or truncated            */
  271.                   0L,                         /* file attribute                               */
  272.                   FILE_OPEN,                  /* action taken if file exists/does not exist   */
  273.                   FS_CLI_GAMEPIPE_OPEN_MODE,  /* open mode of file                            */
  274.                   NULL);                      /* pointer to structure for extended attributes */
  275.       }
  276.       while (ERROR_PIPE_BUSY == apiRC &&
  277.              !(BOOL)(apiRC=DosWaitNPipe(pszGamePipe, NP_INDEFINITE_WAIT)));
  278.    }
  279.  
  280.    if (apiRC != 0)
  281.    {
  282.       usMsg = ERROR_MSG;
  283.       hpGamePipe = 0;
  284.    }
  285.  
  286.    if (START_MSG == usMsg)
  287.    {
  288.       pmsgPipeMsg.usMsgType = usMsg;
  289.       pmsgPipeMsg.usMsgData = 0;
  290.  
  291.       /* notify server of success or failure */
  292.       DosWrite(hpPipe, (VOID *)&pmsgPipeMsg, sizeof(PIPE_MSG), &ulCount);
  293.    }
  294.  
  295.    /* if it is not a start message, return an error */
  296.    else
  297.    {
  298.       hpGamePipe = 0;
  299.    }
  300.  
  301.    /* close start pipe */
  302.    DosClose(hpPipe);
  303.    return(hpGamePipe);
  304. }
  305.  
  306.  
  307. /*
  308.  *   wait for PM thread to post message, and write it to pipe.
  309.  */
  310. BOOL WritePipe(HPIPE hpPipe, USHORT *usMsg)
  311. {
  312.    ULONG   ulCount;
  313.    BOOL    fSuccess=TRUE;
  314.    APIRET  apiRC;
  315.  
  316.  
  317.    if (!(BOOL)DosWaitEventSem(hevWritePipe, SEM_INDEFINITE_WAIT))
  318.    {
  319.       DosResetEventSem(hevWritePipe, &ulCount);
  320.       if ((BOOL)DosWrite(hpPipe, (VOID *)&pmsgPipeMsg, sizeof(PIPE_MSG), &ulCount))
  321.       {
  322.          WinPostMsg(hwndMain, WM_MSG, MPFROM2SHORT(IDMSG_PIPE_WRITE_FAILED, MB_CUAWARNING | MB_OK), MPFROMLONG(apiRC));
  323.          fSuccess = FALSE;
  324.       }
  325.  
  326.       *usMsg = pmsgPipeMsg.usMsgType;
  327.    }
  328.  
  329.    else if (!fAppExit)
  330.    {
  331.       WinPostMsg(hwndMain, WM_MSG, MPFROM2SHORT(IDMSG_SEMAPHORE_ERROR, MB_CUAWARNING | MB_OK), MPVOID);
  332.       fSuccess = FALSE;
  333.    }
  334.  
  335.    return(fSuccess);
  336. }
  337.  
  338.  
  339. /*
  340.  *   Read message from pipe, and post to PM thread.
  341.  */
  342. BOOL ReadPipe(HPIPE hpPipe, USHORT *usMsg)
  343. {
  344.    static PIPE_MSG  pmsgPipeMsg;
  345.    BOOL             fSuccess=TRUE;
  346.    ULONG            ulCount;
  347.    APIRET           apiRC;
  348.  
  349.    /* DosRead returns an error code of 0 and 0 bytes read with a broken pipe */
  350.    if (!(BOOL)DosRead(hpPipe, (VOID *)&pmsgPipeMsg, sizeof(PIPE_MSG), &ulCount)
  351.        && ulCount > 0)
  352.    {
  353.       if (START_MSG != (*usMsg = pmsgPipeMsg.usMsgType))
  354.       {
  355.          WinPostMsg(hwndMain, (WM_USER+pmsgPipeMsg.usMsgType), MPFROMSHORT((SHORT)pmsgPipeMsg.usMsgData), MPVOID);
  356.       }
  357.    }
  358.  
  359.    else if (!fAppExit)
  360.    {
  361.       WinPostMsg(hwndMain, WM_MSG, MPFROM2SHORT(IDMSG_PIPE_READ_FAILED, MB_CUAWARNING | MB_OK), MPFROMLONG(apiRC));
  362.       fSuccess = FALSE;
  363.    }
  364.  
  365.    return(fSuccess);
  366. }
  367.