UWP C# 管道客户端无法连接到 Win32 C++ 管道服务器

时间:2021-01-05 11:17:02

标签: c# c++ winapi uwp windows-runtime

我正在尝试在客户端 UWP C# 应用程序和服务器 Win32 C++ 应用程序之间进行通信,这两个应用程序在同一个包中,并且我使用 Win32 应用程序作为桌面扩展来为 UWP 应用程序提供附加功能。

docs 可以清楚地看出同一包中的 UWP 应用程序之间的命名管道通信,但不清楚同一包中的 UWP 和 Win32 应用程序。

UWP 进程创建的名为 \\\\.\\pipe\\Local\\PipeName 的管道被转换为 \\\\.\\pipe\\Sessions\\<SessionId>\\AppContainerNamedObjects\\<AppContainerSid>\\PipeName。我可以使用它在作为服务器的 UWP 和作为客户端的 Win32 之间进行通信。但是,即使我按照 official RPC sample 中的方法设置了 ACL,我也无法进行相反的操作。我没有使用自定义功能,而是使用 DeriveAppContainerSidFromAppContainerName 从包系列名称派生 SID。

我的 Win32 C++ 服务器代码如下所示:

SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
PSID everyoneSid = NULL;
PSID packageSid = NULL;
EXPLICIT_ACCESS ea[2] = {};
PACL acl = NULL;
SECURITY_DESCRIPTOR pipeSecurityDescriptor = {};

if (DeriveAppContainerSidFromAppContainerName(Package::Current().Id().FamilyName().c_str(), &packageSid) == S_OK &&
    // Get the SID that represents 'everyone' (this doesn't include AppContainers)
    AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyoneSid))
{
    // Now create the Access Control List (ACL) for the Security descriptor

    // Everyone GENERIC_ALL access
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfAccessPermissions = GENERIC_ALL;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[0].Trustee.ptstrName = static_cast<LPWSTR>(everyoneSid);

    // Package Family GENERIC_ALL access
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfAccessPermissions = GENERIC_ALL;
    ea[1].grfInheritance = NO_INHERITANCE;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
    ea[1].Trustee.ptstrName = static_cast<LPWSTR>(packageSid);

    if (SetEntriesInAcl(ARRAYSIZE(ea), ea, NULL, &acl) != ERROR_SUCCESS &&
        // Initialize an empty security descriptor
        InitializeSecurityDescriptor(&pipeSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) &&
        // Assign the ACL to the security descriptor
        SetSecurityDescriptorDacl(&pipeSecurityDescriptor, TRUE, acl, FALSE))
    {
        SECURITY_ATTRIBUTES pipeSecurityAttributes{ .nLength = sizeof(SECURITY_ATTRIBUTES), .lpSecurityDescriptor = &pipeSecurityDescriptor, .bInheritHandle = FALSE };
        HANDLE hPipe = CreateNamedPipe(L"\\\\.\\pipe\\Sessions\\<SessionId>\\AppContainerNamedObjects\\<AppContainerSid>\\PipeName}", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_WAIT_FOREVER, &pipeSecurityAttributes);
        if (hPipe)
        {
           ConnectNamedPipe(hPipe, NULL);
           // Do something
        }
    }
}

if (everyoneSid) FreeSid(everyoneSid);
if (packageSid) FreeSid(packageSid);
if (acl) LocalFree(acl);

我的 UWP C# 客户端代码如下所示:

using (var client = new NamedPipeClientStream(".", "Local\\PipeName", PipeDirection.InOut, PipeOptions.Asynchronous))
        {
            await client.ConnectAsync();
            // Do something
        }

当我尝试从客户端连接时,出现 "Access to the path is denied." 错误。

0 个答案:

没有答案