Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
351 views
in Technique[技术] by (71.8m points)

UWP C# pipe client fails to connect to Win32 C++ pipe server

I am trying to communicate between client UWP C# app and server Win32 C++ app, both apps are in same package and I am using the Win32 app as desktop extension to provide additional functionality to UWP app.

From the docs it is clear that named pipe communication between UWP apps in same package but it isn't clear about UWP and Win32 app in same package.

The pipe created by UWP process with name \\.\pipe\Local\PipeName is converted to \\.\pipe\Sessions\<SessionId>\AppContainerNamedObjects\<AppContainerSid>\PipeName. I can use this to communicate between UWP as server and Win32 as client. But I can't do the reverse even after I set up the ACLs as done in the official RPC sample. Instead of using custom capability I used DeriveAppContainerSidFromAppContainerName to to derive a SID from package family name.

My Win32 C++ server code looks like this:

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);

My UWP C# client code looks like this:

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

When I am trying to connect from client I am getting "Access to the path is denied." error.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...