home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / devtools / os2tk21j / c / samples / npipe / clnpthrd.c__ / clnpthrd.c
Encoding:
C/C++ Source or Header  |  1993-03-12  |  10.9 KB  |  360 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.  
  110.    switch (msg)
  111.    {
  112.       case WM_COMMAND:
  113.          switch ((ulUserCommand=SHORT1FROMMP(mp1)))
  114.          {
  115.             case ID_OK:
  116.                if (0 != WinQueryWindowText(WinWindowFromID(hwnd,
  117.                                                            DID_PIPE_SVR),
  118.                                            MAXSERVERNAME,
  119.                                            pszServer))
  120.                {
  121.                   while (ERROR_FILE_NOT_FOUND == (apiRC=DosQueryPathInfo(pszServer,
  122.                                                                   FIL_STANDARD,
  123.                                                                   &fs,
  124.                                                                   sizeof(FILESTATUS)))
  125.                          || ERROR_PATH_NOT_FOUND == apiRC)
  126.                   {
  127.                      if (MBID_RETRY!=(ulErrorReply=MessageBox(hwnd,
  128.                                                IDMSG_INVALID_NAME,
  129.                                                0,
  130.                                                MB_CUAWARNING | MB_ABORTRETRYIGNORE,
  131.                                                NULL,
  132.                                                TRUE)))
  133.                      {
  134.                         if (MBID_ABORT == ulErrorReply)
  135.                         {
  136.                            ulUserCommand = ID_CANCEL;
  137.                         }
  138.  
  139.                         break;
  140.                      }
  141.                   }
  142.                }
  143.  
  144.                else
  145.                {
  146.                   ulUserCommand = ID_CANCEL;
  147.                }
  148.  
  149.             case ID_CANCEL:
  150.                WinDismissDlg(hwnd, ulUserCommand);
  151.                return (MRFROMLONG(0));
  152.          }
  153.          break;
  154.    }
  155.    return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  156. }
  157.  
  158.  
  159. VOID ManagePipe(VOID *tpPipeNames)
  160. {
  161.    BOOL    fSuccess=TRUE;
  162.    USHORT  usMsg;
  163.    ULONG   ulErrorMsg, ulIcon;
  164.    HPIPE   hpPipe;
  165.    PSZ     pszServer;
  166.    ULONG   ulAction;
  167.    APIRET  apiRC;
  168.  
  169. /*
  170.  *   Attempt to open named pipe.  If the pipe is busy, wait on it, and when
  171.  *   it becomes free try to open it again.  Continue until success or error.
  172.  */
  173.  
  174.    do
  175.    {
  176.       apiRC = DosOpen(((THREADPARAM *)tpPipeNames)->StartPipe,  /* pointer to filename      */
  177.                 (PHFILE) &hpPipe,            /* pointer to variable for file handle          */
  178.                 &ulAction,                   /* pointer to variable for action taken         */
  179.                 0L,                          /* file size if created or truncated            */
  180.                 0L,                          /* file attribute                               */
  181.                 FILE_OPEN,                   /* action taken if file exists/does not exist   */
  182.                 FS_CLI_STARTPIPE_OPEN_MODE,  /* open mode of file                            */
  183.                 NULL);                       /* pointer to structure for extended attributes */
  184.    }
  185.    while (ERROR_PIPE_BUSY == apiRC &&
  186.           !(BOOL)(apiRC=DosWaitNPipe(pszServer, NP_INDEFINITE_WAIT)));
  187.  
  188.    if (apiRC != 0)
  189.    {
  190.       ulErrorMsg = IDMSG_CONNECT_FAILED;
  191.       ulIcon = MB_CUAWARNING | MB_OK;
  192.       fSuccess = FALSE;
  193.    }
  194.  
  195.    if (TRUE == fSuccess)
  196.    {
  197.       /* connect to the game pipe */
  198.       if ((BOOL)(hpPipe = ConnectGamePipe(hpPipe,
  199.                                           ((THREADPARAM *)tpPipeNames)->GamePipe)))
  200.       {
  201.          /* enable the File-Start menu choice */
  202.          WinPostMsg(hwndMain, WM_START, MPVOID, MPVOID);
  203.  
  204.          while (WritePipe(hpPipe, &usMsg) &&
  205.                 usMsg != CLIENT_QUIT &&
  206.                 usMsg != ERROR_MSG)
  207.          {
  208.             if (!(BOOL)ReadPipe(hpPipe, &usMsg))
  209.             {
  210.                break;
  211.             }
  212.          }
  213.       }
  214.  
  215.       else
  216.       {
  217.          ulErrorMsg = IDMSG_CONNECT_FAILED;
  218.          ulIcon = MB_CUAWARNING | MB_OK;
  219.          fSuccess = FALSE;
  220.       }
  221.    }
  222.  
  223.    if (FALSE == fSuccess)
  224.    {
  225.       WinPostMsg(hwndMain,
  226.                  WM_MSG,
  227.                  MPFROM2SHORT(ulErrorMsg, ulIcon),
  228.                  MPFROMLONG(apiRC));
  229.    }
  230.  
  231.    if (!fAppExit)
  232.    {
  233.       fAppExit = TRUE;
  234.    }
  235.  
  236.    DosCloseEventSem(hevWritePipe);
  237.    DosClose(hpPipe);
  238.    fThrdsDead = TRUE;
  239. }
  240.  
  241.  
  242. /*
  243.  *   open game pipe, notify server of success or failure, and close start pipe.
  244.  */
  245. HPIPE ConnectGamePipe(HPIPE hpPipe, PSZ pszGamePipe)
  246. {
  247.    HPIPE     hpGamePipe;
  248.    USHORT    usMsg=ERROR_MSG;
  249.    ULONG     ulCount, ulAction;
  250.    PIPE_MSG  pmsgPipeMsg;
  251.    APIRET    apiRC;
  252.  
  253.    /* block on read, and open game pipe if server sends START_MSG */
  254.    if ((BOOL)ReadPipe(hpPipe, &usMsg) &&
  255.        START_MSG == usMsg)
  256.    {
  257.  
  258.       do
  259.       {
  260.          apiRC = DosOpen(pszGamePipe,         /* pointer to filename                          */
  261.                   (PHFILE) &hpGamePipe,       /* pointer to variable for file handle          */
  262.                   &ulAction,                  /* pointer to variable for action taken         */
  263.                   0L,                         /* file size if created or truncated            */
  264.                   0L,                         /* file attribute                               */
  265.                   FILE_OPEN,                  /* action taken if file exists/does not exist   */
  266.                   FS_CLI_GAMEPIPE_OPEN_MODE,  /* open mode of file                            */
  267.                   NULL);                      /* pointer to structure for extended attributes */
  268.       }
  269.       while (ERROR_PIPE_BUSY == apiRC &&
  270.              !(BOOL)(apiRC=DosWaitNPipe(pszGamePipe, NP_INDEFINITE_WAIT)));
  271.    }
  272.  
  273.    if (apiRC != 0)
  274.    {
  275.       usMsg = ERROR_MSG;
  276.       hpGamePipe = 0;
  277.    }
  278.  
  279.    if (START_MSG == usMsg)
  280.    {
  281.       pmsgPipeMsg.usMsgType = usMsg;
  282.       pmsgPipeMsg.usMsgData = 0;
  283.  
  284.       /* notify server of success or failure */
  285.       DosWrite(hpPipe, (VOID *)&pmsgPipeMsg, sizeof(PIPE_MSG), &ulCount);
  286.    }
  287.  
  288.    /* if it is not a start message, return an error */
  289.    else
  290.    {
  291.       hpGamePipe = 0;
  292.    }
  293.  
  294.    /* close start pipe */
  295.    DosClose(hpPipe);
  296.    return(hpGamePipe);
  297. }
  298.  
  299.  
  300. /*
  301.  *   wait for PM thread to post message, and write it to pipe.
  302.  */
  303. BOOL WritePipe(HPIPE hpPipe, USHORT *usMsg)
  304. {
  305.    ULONG   ulCount;
  306.    BOOL    fSuccess=TRUE;
  307.    APIRET  apiRC;
  308.  
  309.  
  310.    if (!(BOOL)DosWaitEventSem(hevWritePipe, SEM_INDEFINITE_WAIT))
  311.    {
  312.       DosResetEventSem(hevWritePipe, &ulCount);
  313.       if ((BOOL)DosWrite(hpPipe, (VOID *)&pmsgPipeMsg, sizeof(PIPE_MSG), &ulCount))
  314.       {
  315.          WinPostMsg(hwndMain, WM_MSG, MPFROM2SHORT(IDMSG_PIPE_WRITE_FAILED, MB_CUAWARNING | MB_OK), MPFROMLONG(apiRC));
  316.          fSuccess = FALSE;
  317.       }
  318.  
  319.       *usMsg = pmsgPipeMsg.usMsgType;
  320.    }
  321.  
  322.    else if (!fAppExit)
  323.    {
  324.       WinPostMsg(hwndMain, WM_MSG, MPFROM2SHORT(IDMSG_SEMAPHORE_ERROR, MB_CUAWARNING | MB_OK), MPVOID);
  325.       fSuccess = FALSE;
  326.    }
  327.  
  328.    return(fSuccess);
  329. }
  330.  
  331.  
  332. /*
  333.  *   Read message from pipe, and post to PM thread.
  334.  */
  335. BOOL ReadPipe(HPIPE hpPipe, USHORT *usMsg)
  336. {
  337.    static PIPE_MSG  pmsgPipeMsg;
  338.    BOOL             fSuccess=TRUE;
  339.    ULONG            ulCount;
  340.    APIRET           apiRC;
  341.  
  342.    /* DosRead returns an error code of 0 and 0 bytes read with a broken pipe */
  343.    if (!(BOOL)DosRead(hpPipe, (VOID *)&pmsgPipeMsg, sizeof(PIPE_MSG), &ulCount)
  344.        && ulCount > 0)
  345.    {
  346.       if (START_MSG != (*usMsg = pmsgPipeMsg.usMsgType))
  347.       {
  348.          WinPostMsg(hwndMain, (WM_USER+pmsgPipeMsg.usMsgType), MPFROMSHORT((SHORT)pmsgPipeMsg.usMsgData), MPVOID);
  349.       }
  350.    }
  351.  
  352.    else if (!fAppExit)
  353.    {
  354.       WinPostMsg(hwndMain, WM_MSG, MPFROM2SHORT(IDMSG_PIPE_READ_FAILED, MB_CUAWARNING | MB_OK), MPFROMLONG(apiRC));
  355.       fSuccess = FALSE;
  356.    }
  357.  
  358.    return(fSuccess);
  359. }
  360.