🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #3281

NamedPipe problem

#3281
From: T. Meyer
Date: Thu, 17 Aug 2006 14:17
223 lines
7484 bytes
Hello,

I have a problem on my NamedPipe application.

my NamedPipe server works well, it receives the message from client and 
sends back a message a message to the client.
But with the client I have a problem.
The client should read the response from the server, but everytime I get: 
The handle is invalid!
I use an overlapped structure to don't block my client.
So the 1st question is: Why writing to the server wokrs but reading (over 
same pipe) causes: 'The handle is invalid!'?
My 2nd qustion is, I use overlapped IO to ensure my program can do further 
things if pipe reading not finsihed at once.
But I dont know the WHEN the reading is complete.

if ReedFile returns back I catch the error code to get information what 
happend.
If error code is ERROR_IO_PENDING the I use WaitForMultipleObjects and 
GetOverlappedResult but then I do not know
what is the trigger to say ReadFile has finsihed the reading?

Here is my code:

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"

#include "SyncObjs.hpp"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

#define BUFSIZE 512

TForm1 *Form1;
TEvent *PipeEvt;
HANDLE hEvents[1];
//---------------------------------------------------------------------------


__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
  PipeEvt = new TEvent(NULL, true, true, NULL);
  hEvents[0] = (HANDLE)PipeEvt->Handle;
  OL.Offset = 0;
  OL.OffsetHigh = 0;
  OL.hEvent = PipeEvt;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  ApplicationRunning = true;
  HANDLE hPipe;
  LPTSTR lpvMessage=TEXT("Default message from client");
  TCHAR chBuf[BUFSIZE];
  BOOL fSuccess;
  DWORD cbRead, cbWritten, dwMode, dwWait;
  LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");

  // Try to open a named pipe; wait for it, if necessary.
  while (1)
  {
    hPipe = CreateFile(
     lpszPipename,   // pipe name
     GENERIC_READ |  // read and write access
     GENERIC_WRITE,
     0,              // no sharing
     NULL,           // default security attributes
     OPEN_EXISTING,  // opens existing pipe
     0,              // default attributes
     NULL);          // no template file

    // Break if the pipe handle is valid.
    if (hPipe != INVALID_HANDLE_VALUE)
      break;

    // Exit if an error other than ERROR_PIPE_BUSY occurs.
    if (GetLastError() != ERROR_PIPE_BUSY)
    {
      ShowMessage("Could not open pipe");
      exit(-1);
    }

    // All pipe instances are busy, so wait for 20 seconds.
    if (!WaitNamedPipe(lpszPipename, 20000))
    {
      ShowMessage("Could not open pipe");
      exit(-1);
    }
    Application->ProcessMessages();
  }

  // The pipe connected; change to message-read mode.
  dwMode = PIPE_READMODE_MESSAGE;
  fSuccess = SetNamedPipeHandleState(
   hPipe,    // pipe handle
   &dwMode,  // new pipe mode
   NULL,     // don't set maximum bytes
   NULL);    // don't set maximum time

  if (!fSuccess)
  {
    ShowMessage("SetNamedPipeHandleState failed");
    exit(-1);
  }

  // Send a message to the pipe server.
  fSuccess = WriteFile(
   hPipe,                  // pipe handle
   lpvMessage,             // message
   (lstrlen(lpvMessage)+1)*sizeof(TCHAR), // message length
   &cbWritten,             // bytes written
   NULL);                  // NULL for not overlapped

  if (!fSuccess)
  {
    ShowMessage("WriteFile failed");
    exit(-1);
  }

/*
  do
  {
    // Wait infinitively until server sends an response
    // Read from the pipe.
    fSuccess = ReadFile(
     hPipe,    // pipe handle
     chBuf,    // buffer to receive reply
     BUFSIZE*sizeof(TCHAR),  // size of buffer
     &cbRead,  // number of bytes read
     NULL);    // NULL for not overlapped, means wait infinitively

    if (!fSuccess && GetLastError() != ERROR_MORE_DATA)
      break;

    Memo1->Lines->Add(chBuf);
  } while (!fSuccess);  // repeat loop if ERROR_MORE_DATA
*/

  bool ReadCompleted = false;

  fSuccess = ReadFile(
   hPipe,                 // pipe handle
   chBuf,                 // buffer to receive reply
   BUFSIZE*sizeof(TCHAR), // size of buffer
   &cbRead,               // number of bytes read
   &OL);                  // NULL if not overlapped

  if (!fSuccess)
  {
    // ReadFile not completed, so wait until PipeEvt signaled
    DWORD cbRet, dwErr, dwRet;

    dwErr = GetLastError();
    if (dwErr != ERROR_IO_PENDING)
    {
      ShowError(dwErr); // <-------------------------------- Everytime my 
programs stops here with The handle is invalid! Why?
    }
    else
    {
      while(!ReadCompleted)
      {
        static int i = 0;
        dwWait = WaitForMultipleObjects(
         1,       // number of event objects
         hEvents, // array of event objects
         FALSE,   // does not wait for all
         1000);   // wait 1 sec.

        switch (dwWait)
        {
          case WAIT_TIMEOUT:  Memo1->Lines->Add(IntToStr(i));
                              break;

          case WAIT_OBJECT_0: dwRet = GetOverlappedResult(
                                       hPipe,  // handle to pipe
                                       &OL,    // OVERLAPPED structure
                                       &cbRet, // bytes transferred
                                       FALSE); // do not wait
                              PipeEvt->ResetEvent();
                              break;

           // ------------------------------------------------When is the 
ReadFile completed to set ReadCompleted to true to leave this loop?
        }
        Application->ProcessMessages();
      }
    }
  }
  DisconnectNamedPipe(hPipe);
  CloseHandle(hPipe);
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ShowError(DWORD Err)
{
    LPVOID lpMsgBuf;

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL
    );

    // Display the string.
    Application->MessageBox((char*)lpMsgBuf, "GetLastError", MB_OK | 
MB_ICONINFORMATION );

    // Free the buffer.
    LocalFree( lpMsgBuf );
}
//--------------------------------------------------------------------------- 
Technical Details
Message-ID: <44e47a8e$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,facc6570cb7e9402,start
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "T. Meyer" <timon@mustek.de>
Newsgroups: borland.public.cppbuilder.nativeapi
Subject: NamedPipe problem
Date: Thu, 17 Aug 2006 16:17:49 +0200
Lines: 225
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.2670
X-RFC2646: Format=Flowed; Original
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2670
NNTP-Posting-Host: 80.132.138.214
Message-ID: <44e47a8e$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1155824270 80.132.138.214 (17 Aug 2006 07:17:50 -0700)
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail