Getting Information about an Existing Pipe

Three functions retrieve information about a pipe without changing any of its attributes.

Getting State Information

The first information command is the counterpart of SetNamedPipeHandleState, but it retrieves more information than its partner sets:

BOOL GetNamedPipeHandleState(
   HANDLE  hNamedPipe,             // handle of named pipe
   LPDWORD lpdwModes,              // read and wait modes
   LPDWORD lpdwCurInstances,       // number of current pipe instances
   LPDWORD lpcbMaxCollect,         // max bytes before remote transmission
   LPDWORD lpdwCollectTimeout,     // max time before remote transmission
   LPTSTR  lpszUserName,           // user name of client process
   DWORD   dwMaxUserNameBuff );    // size in chars of user name buffer

The lpdwModes parameter may contain the PIPE_READMODE_MESSAGE and PIPE_NOWAIT flags. To indicate the byte mode or wait mode, which are the default states, no flags are set.

lpdwCurInstances counts the number of instances that currently exist for a pipe. In other words, it tells how many times the server has called CreateNamedPipe with the same name string.

The collect and time-out parameters retrieve the same network buffering information that SetNamedPipeHandleState controls.

The last two parameters help a server learn about its client. They return the null-terminated string naming the user who is running the client application. Usernames are the names users give to log in. They are associated with particular configuration and security privileges. The server might want the name for a log or a report, but probably this parameter exists for compatibility with OS/2, which also makes the username available. The lpszUserName parameter must be NULL if hNamedPipe belongs to a client; in other words, if it was created with CreateFile rather than CreateNamedPipe.

Any of the pointer parameters may be set to NULL to ignore the value normally returned in that place.

Getting Fixed Attributes

Another function that returns additional information about a pipe is GetNamedPipeInfo. This function returns attributes that may not be changed. (GetNamedPipeHandleState returns attributes that may change during the life of a pipe.)

BOOL GetNamedPipeInfo(
   HANDLE  hNamedPipe,         // handle of named pipe
   LPDWORD lpdwType,           // type and server flags
   LPDWORD lpdwOutBuf,         // size in bytes of pipe’s output buffer
   LPDWORD lpdwInBuf,          // size in bytes of pipe’s input buffer
   LPDWORD lpdwMaxInstances ); // maximum number of pipe instances

The lpdwType parameter may contain either or both of two flags: PIPE_TYPE_MESSAGE and PIPE_SERVER_END. If no flags are set, the handle connects to the client end of a pipe that writes in bytes. The input and output buffer sizes are set in CreateNamedPipe.

The lpdwMaxInstances parameter returns the value set by CreateNamedPipe as an upper limit for the number of simultaneous instances allowed to exist for one pipe.

Retrieving a Message

Normally, when you read from a pipe, the read operation removes from the buffer the message it retrieves. With PeekNamedPipe, however, it is possible to retrieve a message without clearing it from the buffer.

TIP

The ineptly named PeekNamedPipe command works with both named and anonymous pipes.

BOOL PeekNamedPipe(
   HANDLE  hPipe,          // handle of named or anonymous pipe
   LPVOID  lpvBuffer,      // address of buffer to receive data
   DWORD   dwBufferSize,   // size in bytes of data buffer
   LPDWORD lpdwBytesRead,  // returns number of bytes read
   LPDWORD lpdwAvailable,  // returns total number of bytes available
   LPDWORD lpdwMessage );  // returns unread bytes in this message

The lpvBuffer parameter points to a place where the command can store whatever information it copies from the pipe. Keep in mind that PeekNamedPipe cannot retrieve more than dwBufferSize bytes, even if more information remains in the pipe.

lpdwBytesRead returns the number of bytes the function actually did read, and lpdwMessage returns the number of bytes remaining in the current message, if any. lpdwMessage is ignored if the pipe’s read mode is PIPE_READMODE_BYTE. In that case, there are no message units to measure. (All anonymous pipes use the byte read mode.)

The total number of available bytes returned in lpdwAvailable includes all bytes in all messages. If the buffer currently holds several messages, *lpdwAvailable may be greater than the sum of *lpdwBytesRead and *lpdwMessage.

It is legal to retrieve only a partial information set by leaving some parameters NULL. If all you want to know is how many bytes are waiting in the buffer, you may, for example, set everything to 0 or NULL except the handle and lpdwAvailable.

When reading from a pipe set to the message read mode, PeekNamedPipe always stops after reading the first message—even if the data buffer has room to hold several messages. Also, PeekNamedPipe never blocks an empty pipe the way ReadFile does if PIPE_WAIT is set. The wait mode has no effect on PeekNamedPipe, which always returns immediately.

© 1998 SYBEX Inc. All rights reserved.