[英]UWP C# pipe client fails to connect to Win32 C++ pipe server
我正在尝试在客户端 UWP C# 应用程序和服务器 Win32 C++ 应用程序之间进行通信,这两个应用程序都在同一个 package 中,我正在使用 Win32 应用程序作为桌面扩展来为 UWP 应用程序提供附加功能。
从文档中可以清楚地看到,在同一个 package 中的 UWP 应用程序之间名为 pipe 的通信,但不清楚在同一个 package 中的 UWP 和 Win32 应用程序。
UWP进程创建的pipe名称为\\\\.\\pipe\\Local\\PipeName
转换为\\\\.\\pipe\\Sessions\\<SessionId>\\AppContainerNamedObjects\\<AppContainerSid>\\PipeName
。 我可以使用它在作为服务器的 UWP 和作为客户端的 Win32 之间进行通信。 但是即使我像在官方 RPC 示例中那样设置了 ACL 之后,我也无法执行相反的操作。 我没有使用自定义功能,而是使用DeriveAppContainerSidFromAppContainerName
从 package 系列名称派生 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."
错误。
我能够获得此工作的一个版本 - C# UWP 应用程序 pipe 客户端成功连接到非 UWP C++ pipe 服务器。 我的设置与您的非常相似,但有一些差异。
\\\\.\\pipe\\Pipe
。 我的客户端 pipe 路径是: \\.\pipe\\Pipe
。 我能够与这些名字建立联系。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.