title: Named Pipe CreateFile() returns INVALID_HANDLE_VALUE, and GetLastError() returns ERROR_PIPE_BUSY
body: <p>I have written a class to handle named pipe connections, and if I create an instance, close it, and then try to create another instance the call to <code>CreateFile()</code> returns <code>INVALID_HANDLE_VALUE</code>, and <code>GetLastError()</code> returns <code>ERROR_PIPE_BUSY</code>. What's going on here? What can I do to insure the call to <code>Connect()</code> succeeds?</p>
  
  <pre><code>PipeAsync A, B;
  
  A.Connect("\\\\.\\pipe\\test",5000);
  A.Close();
  
  cout &lt;&lt; GetLastError(); // some random value
  B.Connect("\\\\.\\pipe\\test",5000);
  cout &lt;&lt; GetLastError(); // 231 (ERROR_PIPE_BUSY)
  B.Close(); 
  </code></pre>
  
  <p>Here are my implementations of <code>Connect()</code> and <code>Close()</code></p>
  
  <pre><code>BOOL PipeAsync::Connect(LPCSTR pszPipeName, DWORD dwTimeout)
  {
      this-&gt;pszPipeName = pszPipeName;
      this-&gt;fExisting = TRUE;
      DWORD dwMode = this-&gt;fMessageMode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE;
  
      hPipe = CreateFile(
          this-&gt;pszPipeName,
          GENERIC_READ | GENERIC_WRITE,
          0,
          NULL,
          OPEN_EXISTING,
          FILE_FLAG_OVERLAPPED,
          NULL);
  
      if( INVALID_HANDLE_VALUE == hPipe )
          return FALSE; /* set break point here ; breaks here on second call to Connect() */
  
      if( GetLastError() == ERROR_PIPE_BUSY )
          if(!WaitNamedPipe( this-&gt;pszPipeName, dwTimeout ))
              return FALSE; /* set break point here */
  
      if( !SetNamedPipeHandleState( hPipe, &amp;dwMode, NULL, NULL ) )
          return FALSE; /* set break point here */
  
      return TRUE;
  
  }
  
  VOID PipeAsync::Close()
  {
  
      if( fExisting )
          DisconnectNamedPipe( hPipe );
  
      CloseHandle( hPipe );
  }
  </code></pre>
  
  <p><br>
  <br></p>
  
  <p><strong>EDIT:</strong> I forgot to tell you how I concluded this... I set break points indicated in the comments. When run, it stops on the first break point. </p>
  
  <p><strong>EDIT:</strong> This is my updated code</p>
  
  <pre><code>if( INVALID_HANDLE_VALUE == hPipe )
      if( GetLastError() == ERROR_PIPE_BUSY )
      {
          if(!WaitNamedPipe( this-&gt;pszPipeName, dwTimeout ))
              return FALSE; /* break-point: breaks here on second call */
      }
      else
          return FALSE; /* break-point /*
  </code></pre>
  
  <p>Now, <code>WaitNamedPipe()</code> is returning false on the second call to <code>Connect()</code> and <code>GetLastError()</code> is returning 2, or <code>ERROR_FILE_NOT_FOUND</code> ?</p>