No Comments
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.
This is quite similar to creating a file but you need to set the
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
Half duplex can be:
A server named pipe is always created using
\\.\pipe\PipeName the dot ('.') denotes local computer
A client named pipe is typically created using
\\ServerName\pipe\PipeName. To access local pipe, server name is replaced with the dot ('.') (e.g.: \\.\pipe\PipeName).
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.
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
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