Keith Russell
Keith Russell

Reputation: 598

How to verify an outbound-only server-end pipe handle is a pipe?

I want to create an outbound-only named pipe, and I want other code elsewhere to later be able to check if that handle is a pipe. This works for all cases of pipe handles (client, server; outbound, inbound), EXCEPT server-end handles to outbound-only pipes.

If I open a handle to the client end of an inbound-to-server-only pipe with access flags GENERIC_WRITE | FILE_READ_ATTRIBUTES, I can later verify the handle is a pipe by calling GetNamedPipeInfo(handle,NULL,NULL,NULL,NULL), which returns true. However, the server end lacks this privilege for outbound-only pipes — if I call CreateNamedPipe with PIPE_ACCESS_OUTBOUND, GetNamedPipeInfo returns false and GetLastError returns ERROR_ACCESS_DENIED.

Upvotes: 4

Views: 184

Answers (1)

Keith Russell
Keith Russell

Reputation: 598

Figured it out.

bool IsPipe(HANDLE maybePipe)
{
#if 1
    ULONG junk;
    return
        //This returns a false negative for server-side pipe endpoints opened as PIPE_ACCESS_OUTBOUND.
        //I tried or-ing that with FILE_READ_ATTRIBUTES, but CreateNamedPipe doesn't like that.
        ::GetNamedPipeInfo(maybePipe, nullptr, nullptr, nullptr, nullptr)
            //So we fall back onto this one, which returns true in that case,
            // and false for non-pipes.
            || ::GetNamedPipeServerSessionId(maybePipe, &junk);
#elif 0
    return
        //THIS RETURNS TRUE FOR NON-PIPE FILES X-(
        ::GetNamedPipeHandleState(maybePipe, nullptr, nullptr, nullptr, nullptr, nullptr, 0);
#endif
}

Upvotes: 1

Related Questions