Win32 Named Pipe Communication

Win32 Named Pipe Communication

PipeServer.zip

Pipe Server
 
Pipe Client
 
To run the application as client, type PipeServer.exe /client from MSDOS.

Introduction

Just like the socket communication class, I use NamedPipe quite often in server application. I had this code and demo ready for quite a while now but finally found some time to publish it.

Description

The first thing you may want to know is that Windows Named Pipe offers One-Way or Full duplex communication between a server and a client. A Named pipe is a secured kernel object. While all instances of the named pipe can be created, each handle will have its unique buffer. Generally, the server creates the first handle and specify the security for this object.
This is quite similar to creating a file but you need to set the LPSECURITY_ATTRIBUTES when you call CreateNamedPipe. As you can expect, the operating system will authorize other process to access the named pipe by checking the process token. This is very interesting considering that NamedPipe can be accessed both locally and remotely. NamedPipe API may even let you know the process id that is connecting to the server (GetNamedPipeClientProcessId and GetNamedPipeServerProcessId).
With named pipe, a server can impersonate a client process. This is very important security features. By impersonating a client, it allows the server thread to run using the same privilege as the client. Thus, if a restricted user account is connecting to the server, by impersonating the client process, the same restrictions are applied directly to the server thread since it is running in the same security context as this user account. As you can see if the server is accessing a database, it can do so on behalf of the client identity. Server application impersonates a client by calling ImpersonateNamedPipeClient passing the handle of the named pipe.

NamedPipe Access Modes

A named pipe can operate in two modes: Half or Full duplex.
Half duplex can be:
  • INBOUND meaning the server only reads while the client writes only
  • OUTBOUND meaning the server only writes while the client reads only
In Full Duplex mode, both the server and client read and write to the pipe.

A server named pipe is always created using CreateNamedPipe and the name uses the following format:
\\.\pipe\PipeName the dot ('.') denotes local computer
A client named pipe is typically created using CreateFile or WaitNamedPipe. A third way exists that you can call CallNamedPipe. This function does a lot, it connects to the pipe (and waits for instance to be available), writes and reads from it and then, closes it. Since pipe can be accessed remotely, the name can follow this format:
\\ServerName\pipe\PipeName. To access local pipe, server name is replaced with the dot ('.') (e.g.: \\.\pipe\PipeName).

NamedPipe Operations

Named pipe can operate synchronously or asynchronously. It's always best to run named pipe asynchronously because in most cases this let you handle communication errors and broken connection with your peer easily. The only minor drawback is that you need additional event handle. This is made really easy using this class.

How to Use

As a Server:
    CNamedPipeHandle    _NamedPipe;
    // create named pipe
    if ( _NamedPipe.Create(PIPE_NAME) )
    {
        // wait for a connection
        while ( _NamedPipe.WaitForClient(INFINITE) )
        {
            // read from pipe
            while ( (dwRead = _NamedPipe.Read(...)) != PIPE_IO_ERROR && (dwRead > 0))
            {
                _NamedPipe.Write(...); // write data to named pipe
            }
        }
    }
       
As a Client:
    CNamedPipeHandle    _NamedPipe;
    if ( _NamedPipe.ConnectTo(PIPE_NAME) )
    {
        _NamedPipe.Write(...); // write data to named pipe
    }
       

Conclusion

In this article, I described what named pipes are and how you can take advantage of them in your client-server applications. Named pipes provide secured and high performance communication for Windows Application. Communication can be byte or stream oriented. Local or remote data sharing. One of the most important feature behind named pipe is impersonation. Through impersonation, a server can act on behalf of the client process using the same privilege as if the client is local.
Finally, since a named pipe is like a file, the security attributes can be specified per account basis which is a neat feature for server role-based application.

History

06/19/2008: Public Release
0 Comments
Add Comment