home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / PIPE.C < prev    next >
Text File  |  1995-09-08  |  19KB  |  346 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   pipes.c                                                                 */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*                                                                           */
  7. /*  Handle client/server communications using pipes.                         */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   03/05/94 Created.                                                       */
  12. /*                                                                           */
  13. /*****************************************************************************/
  14.  
  15. #include "all.h"
  16.  
  17. /*****************************************************************************/
  18. /* - Pipe handle and name for local pipe connections.                        */
  19. /*****************************************************************************/
  20. static char    PipeName[15]="\\PIPE\\SD386PIP";
  21.  
  22. /*****************************************************************************/
  23. /* PipeInit()                                                                */
  24. /*                                                                           */
  25. /* Description:                                                              */
  26. /*                                                                           */
  27. /*   Set up a local pipe for debugging.                                      */
  28. /*                                                                           */
  29. /* Parameters:                                                               */
  30. /*                                                                           */
  31. /*   pConnection   -> to the structure defining the remote connection.       */
  32. /*   pLsnHandle    -> to the receiver of the logical session handle.         */
  33. /*                                                                           */
  34. /* Return:                                                                   */
  35. /*                                                                           */
  36. /* Assumptions:                                                              */
  37. /*                                                                           */
  38. /*****************************************************************************/
  39. APIRET PipeInit( CONNECTION *pConnection, LHANDLE *pLsnHandle )
  40. {
  41.  APIRET rc;
  42.  int    ProcessType;
  43.  
  44.  ProcessType = DBG_SERVER;
  45.  if( pConnection->DbgOrEsp == _ESP )
  46.   ProcessType = ESP_CLIENT;
  47.  
  48.  switch( ProcessType )
  49.  {
  50.   case DBG_SERVER:
  51.    /**************************************************************************/
  52.    /* Create a pipe for client/server communications. The Dbg end of the     */
  53.    /* connection is considered to be the server. The server creates the      */
  54.    /* pipe and then waits for a client to connect to it.                     */
  55.    /**************************************************************************/
  56.    rc = CreateNamedPipe(pLsnHandle);
  57.    if( rc != 0 )
  58.     break;
  59.  
  60.  
  61.    /**************************************************************************/
  62.    /* - At this point, the pipe is created and in the Disconnected state.    */
  63.    /* - We will connect to the pipe putting it in the Listening state        */
  64.    /*   and then wait for a client probe to make a connection.               */
  65.    /* - After the client opens this instance of the pipe, the pipe           */
  66.    /*   will be in the Connected state.                                      */
  67.    /**************************************************************************/
  68.    rc = DosConnectNPipe(*pLsnHandle);
  69.    break;
  70.  
  71.   case ESP_CLIENT:
  72.    /**************************************************************************/
  73.    /* - Connect to a pipe on the client end.                                 */
  74.    /**************************************************************************/
  75.    rc = OpenNamedPipe(pLsnHandle);
  76.    break;
  77.  }
  78.  return(rc);
  79. }
  80.  
  81. /*****************************************************************************/
  82. /* PipeClose()                                                               */
  83. /*                                                                           */
  84. /* Description:                                                              */
  85. /*                                                                           */
  86. /*   Close a local pipe.                                                     */
  87. /*                                                                           */
  88. /* Parameters:                                                               */
  89. /*                                                                           */
  90. /*   pConnection   -> to the structure defining the remote connection.       */
  91. /*   LsnHandle        handle of the pipe to close.                           */
  92. /*                                                                           */
  93. /* Return:                                                                   */
  94. /*                                                                           */
  95. /* Assumptions:                                                              */
  96. /*                                                                           */
  97. /*****************************************************************************/
  98. void PipeClose( CONNECTION *pConnection, LHANDLE LsnHandle )
  99. {
  100.  int    ProcessType;
  101.  
  102.  ProcessType = DBG_SERVER;
  103.  if( pConnection->DbgOrEsp == _ESP )
  104.   ProcessType = ESP_CLIENT;
  105.  
  106.  switch( ProcessType )
  107.  {
  108.   case DBG_SERVER:
  109.    /**************************************************************************/
  110.    /* - Disconnect the server end of the pipe.                               */
  111.    /* - Close the pipe.                                                      */
  112.    /**************************************************************************/
  113.    DosDisConnectNPipe(LsnHandle);
  114.    DosClose(LsnHandle);
  115.    break;
  116.  
  117.   case ESP_CLIENT:
  118.    /**************************************************************************/
  119.    /* - Close the client end of the pipe.                                    */
  120.    /**************************************************************************/
  121.    DosClose(LsnHandle);
  122.    break;
  123.  }
  124. }
  125.  
  126. /*****************************************************************************/
  127. /* CreateNamedPipe()                                                         */
  128. /*                                                                           */
  129. /* Description:                                                              */
  130. /*                                                                           */
  131. /*   Create an instance of a pipe and connect to it. Wait for a client       */
  132. /*   to connect to it. This happens in the debugger session.                 */
  133. /*                                                                           */
  134. /* Parameters:                                                               */
  135. /*                                                                           */
  136. /*   pPipeHandle  ptr to where the caller wants the pipe handle stuffed.     */
  137. /*                                                                           */
  138. /* Return:                                                                   */
  139. /*                                                                           */
  140. /*  rc                                                                       */
  141. /*                                                                           */
  142. /* Assumptions:                                                              */
  143. /*                                                                           */
  144. /*****************************************************************************/
  145. APIRET CreateNamedPipe( HPIPE *pPipeHandle )
  146. {
  147.  APIRET rc;
  148.  ULONG  OpenMode;
  149.  ULONG  PipeMode;
  150.  ULONG  OutBufSize;
  151.  ULONG  InBufSize;
  152.  ULONG  TimeOut;
  153.  
  154.  OpenMode = NP_ACCESS_DUPLEX | NP_NOINHERIT;
  155.  PipeMode = NP_WAIT                |
  156.             NP_TYPE_MESSAGE        |
  157.             NP_READMODE_MESSAGE    |
  158.             NP_UNLIMITED_INSTANCES;
  159.  
  160.  OutBufSize = 4096;
  161.  InBufSize  = 2048;
  162.  TimeOut    = -1;
  163.  
  164.  /****************************************************************************/
  165.  /* Create a duplex message pipe for this debugger session.                  */
  166.  /*                                                                          */
  167.  /*  OpenMode bits.                                                          */
  168.  /*                                                                          */
  169.  /*   31-16 = reserved                                                       */
  170.  /*      15 = reserved and must be zero                                      */
  171.  /*      14 = 0 This is a write through bit and only has meaning for a       */
  172.  /*             remote pipe connection.                                      */
  173.  /*   13- 8 = reserved.                                                      */
  174.  /*       7 = 1 inheritance flag. The pipe handle is private to this process */
  175.  /*    6- 3 = reserved and must be zero.                                     */
  176.  /*    2- 0 = 010 duplex pipe.                                               */
  177.  /*                                                                          */
  178.  /*  PipeMode bits.                                                          */
  179.  /*                                                                          */
  180.  /*   31-16 = reserved                                                       */
  181.  /*      15 = 0 blocking mode.                                               */
  182.  /*   14-12 = reserved.                                                      */
  183.  /*   11-10 = 01 message pipe.                                               */
  184.  /*    9- 8 = 01 the pipe will be read as a message stream.                  */
  185.  /*    7- 0 = -1 allow an unlimited number of pipe instances.                */
  186.  /*                                                                          */
  187.  /*  Transmit buffer = 4K.                                                   */
  188.  /*  Receive  buffer = 2K.                                                   */
  189.  /*  Timeout         = -1 wait indefinitely for a pipe instance to be        */
  190.  /*                       created.                                           */
  191.  /*                                                                          */
  192.  /****************************************************************************/
  193.  rc = DosCreateNPipe(PipeName,
  194.                      pPipeHandle,
  195.                      OpenMode,
  196.                      PipeMode,
  197.                      OutBufSize,
  198.                      InBufSize,
  199.                      TimeOut);
  200.  return(rc);
  201.  
  202. }
  203.  
  204. /*****************************************************************************/
  205. /* OpenNamedPipe()                                                           */
  206. /*                                                                           */
  207. /* Description:                                                              */
  208. /*                                                                           */
  209. /*   Open a pipe on the client side of the client/server communications.     */
  210. /*                                                                           */
  211. /* Parameters:                                                               */
  212. /*                                                                           */
  213. /*   pPipeHandle  ptr to where the caller wants the pipe handle stuffed.     */
  214. /*                                                                           */
  215. /* Return:                                                                   */
  216. /*                                                                           */
  217. /*   rc                                                                      */
  218. /*                                                                           */
  219. /* Assumptions:                                                              */
  220. /*                                                                           */
  221. /*****************************************************************************/
  222. APIRET OpenNamedPipe( HPIPE *pPipeHandle )
  223. {
  224.  APIRET rc;
  225.  ULONG  PipeHandleState;
  226.  ULONG  Action;
  227.  
  228.  
  229.  /****************************************************************************/
  230.  /* The open will get an ERROR_PIPE_BUSY error if the server has not         */
  231.  /* created and connected to the pipe.                                       */
  232.  /****************************************************************************/
  233.  rc = ERROR_PIPE_BUSY;
  234.  while( (rc == ERROR_PIPE_BUSY) || ( rc == ERROR_PATH_NOT_FOUND ) )
  235.  {
  236.   rc = DosOpen(PipeName,
  237.                pPipeHandle,
  238.                &Action,
  239.                0,
  240.                FILE_NORMAL,
  241.                FILE_OPEN,
  242.                OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE,
  243.                NULL);
  244.  DosSleep(100);
  245.  }
  246.  if( rc )
  247.   return(rc);
  248.  
  249.  /****************************************************************************/
  250.  /* Change the read mode of the pipe to a message pipe.                      */
  251.  /****************************************************************************/
  252.  PipeHandleState = NP_WAIT | NP_READMODE_MESSAGE;
  253.  rc = DosSetNPHState( *pPipeHandle, PipeHandleState );
  254.  return(rc);
  255. }
  256.  
  257. /*****************************************************************************/
  258. /* PipeSend()                                                                */
  259. /*                                                                           */
  260. /* Description:                                                              */
  261. /*                                                                           */
  262. /*   Write to a pipe.                                                        */
  263. /*                                                                           */
  264. /* Parameters:                                                               */
  265. /*                                                                           */
  266. /*   pBuf       -> our transmit buffer.                                      */
  267. /*   Len        number of bytes to transmit.                                 */
  268. /*                                                                           */
  269. /* Return:                                                                   */
  270. /*                                                                           */
  271. /* Assumptions:                                                              */
  272. /*                                                                           */
  273. /*****************************************************************************/
  274. void PipeSend( LHANDLE PipeHandle, PVOID pBuf, ULONG Len)
  275. {
  276.  APIRET rc;
  277.  ULONG  BytesWritten = 0;
  278.  
  279. again:
  280.  rc = DosWrite(PipeHandle, pBuf, Len,&BytesWritten);
  281.  if( rc == ERROR_INTERRUPT )
  282.   goto again;
  283.  /****************************************************************************/
  284.  /* - If we get an error, then go comatose and wait for a death blow.        */
  285.  /****************************************************************************/
  286.  if( rc != 0 )
  287.  {
  288.   if( IsVerbose() ){printf("\nPipe send error rc=%d",rc);fflush(0);}
  289.   for(;;){ DosSleep(60000); }
  290.  }
  291. }
  292.  
  293. /*****************************************************************************/
  294. /* PipeRecv()                                                                */
  295. /*                                                                           */
  296. /* Description:                                                              */
  297. /*                                                                           */
  298. /*   Read from a pipe.                                                       */
  299. /*                                                                           */
  300. /* Parameters:                                                               */
  301. /*                                                                           */
  302. /*   pBuf       -> our transmit buffer.                                      */
  303. /*   Len        number of bytes to receive.                                  */
  304. /*                                                                           */
  305. /* Return:                                                                   */
  306. /*                                                                           */
  307. /*   rc     1 ==>failure                                                     */
  308. /*          0 ==>success                                                     */
  309. /*                                                                           */
  310. /* Assumptions:                                                              */
  311. /*                                                                           */
  312. /*   Pipe will be closed after an error return.                              */
  313. /*                                                                           */
  314. /*****************************************************************************/
  315. void PipeRecv( LHANDLE PipeHandle, PVOID pBuf, ULONG Len)
  316. {
  317.  ULONG  BytesRead = 0;
  318.  APIRET rc = 0;
  319.  
  320. again:
  321.  
  322.  rc = DosRead(PipeHandle, pBuf, Len,&BytesRead);
  323.  if( rc == ERROR_INTERRUPT )
  324.   goto again;
  325.  
  326.  /****************************************************************************/
  327.  /* - We will get this return code when thread 1 of the probe is sitting     */
  328.  /*   on a DosRead of the pipe and the pipe connection is closed by a        */
  329.  /*   ConnectClose() from the TermQue thread.                                */
  330.  /* - Just wait for the operating system to kill this thread.                */
  331.  /****************************************************************************/
  332.  if( rc == ERROR_PIPE_NOT_CONNECTED )
  333.  {
  334.   for(;;){ DosSleep(60000); }
  335.  }
  336.  /****************************************************************************/
  337.  /* - If we get an error, then go comatose and wait for a death blow.        */
  338.  /****************************************************************************/
  339.  if( rc != 0 )
  340.  {
  341.   if( IsVerbose() ){printf("\nPipe receive error rc=%d",rc);fflush(0);}
  342.   for(;;){ DosSleep(60000); }
  343.  }
  344. }
  345.  
  346.