首页 > 解决方案 > 如何验证仅出站服务器端管道句柄是管道?

问题描述

我想创建一个仅限出站的命名管道,并且我希望其他地方的其他代码稍后能够检查该句柄是否是管道。这适用于管道句柄(客户端、服务器;出站、入站)的所有情况,除了仅出站管道的服务器端句柄。

如果我使用访问标志打开一个到仅入站到服务器的管道的客户端的句柄GENERIC_WRITE | FILE_READ_ATTRIBUTES,我稍后可以通过调用来验证该句柄是一个管道GetNamedPipeInfo(handle,NULL,NULL,NULL,NULL),这将返回 true。但是,对于仅出站管道,服务器端缺少此特权-如果我调用CreateNamedPipewith PIPE_ACCESS_OUTBOUND,则GetNamedPipeInfo返回 false 并GetLastError返回ERROR_ACCESS_DENIED

标签: winapinamed-pipes

解决方案


弄清楚了。

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
}

推荐阅读