Dela namngivna objekt

Det här avsnittet beskriver hur du delar namngivna objekt mellan paketerade skrivbordsappar (inklusive Windows App SDK appar som paketeras med MSIX) och uppackade Win32-program.

Namngivna objekt i paketerade program

Namngivna objekt är ett enkelt sätt för processer att dela objekthandtag. När en process har skapat ett namngivet objekt kan andra processer använda namnet för att anropa lämplig funktion för att öppna en referens till objektet. Namngivna objekt används ofta för trådsynkronisering och kommunikation mellan processer.

Program som körs i en AppContainer (till exempel UWP-appar) har som standard ett isolerat namnområde för namngivna objekt – de kan bara komma åt namngivna objekt som de har skapat. Paketerade skrivbordsappar med fullständigt förtroende (inklusive Windows App SDK appar) har inte den här isoleringen och skapar namngivna objekt i det globala namnområdet. Mer information finns i Windows App SDK överväganden.

Om du vill dela namngivna objekt med AppContainer-appar måste behörigheter anges när objekt skapas och namn måste kvalificeras när objekt öppnas. Teknikerna i den här artikeln är också användbara när du vill begränsa åtkomsten mellan alla processer, oavsett paketering.

Skapa namngivna objekt

Namngivna objekt skapas med motsvarande Create API:

Alla dessa API:er delar en LPSECURITY_ATTRIBUTES parameter som gör att anroparen kan ange åtkomstkontrollistor (ACL: er) för att styra vilka processer som kan komma åt objektet. För att kunna dela namngivna objekt med paketerade program måste behörighet beviljas i ACL:erna när de namngivna objekten skapas.

Säkerhetsidentifierare (SID) representerar identiteter i ACL:er. Varje paketerat program har ett eget SID baserat på paketfamiljenamnet. Du kan generera SID för ett paketerat program genom att skicka dess paketfamiljenamn till DeriveAppContainerSidFromAppContainerName.

Note

Paketfamiljenamnet finns via paketmanifestredigeraren i Visual Studio under utvecklingstiden, via Partnercenter för program som publicerats via Microsoft Store eller via Kommandot Get-AppxPackage PowerShell för program som redan är installerade.

Det här exemplet visar det grundläggande mönster som krävs för att ACL ett namngivet objekt. Om du vill dela namngivna objekt med paketerade program skapar du en EXPLICIT_ACCESS struktur för varje program:

Genom att fylla i parametern LPSECURITY_ATTRIBUTES i Create anrop med EXPLICIT_ACCESS regler för paketerade program kan du ge åtkomst till dessa program för att öppna det namngivna objektet.

Note

Win32-program kan komma åt namngivna objekt som skapats av AppContainer-appar genom att kvalificera objektnamnen när de öppnas, förutsatt att objektets DACL tillåter åtkomsten. Standard-DACL för de flesta namngivna objekt ger åtkomst till skaparen och administratörer. Om du har angett en restriktiv DACL behöver Win32-anropare också en explicit åtkomstpost.

Exempel: Skapa en namngiven händelse med ACL (C++)

I följande exempel visas hur du skapar en namngiven händelse och beviljar åtkomst till ett paketerat program:

#include <windows.h>
#include <sddl.h>
#include <aclapi.h>
#include <userenv.h>

HANDLE CreateSharedEvent(PCWSTR eventName, PCWSTR packageFamilyName)
{
    // Derive the SID for the target packaged application
    PSID appContainerSid = nullptr;
    HRESULT hr = DeriveAppContainerSidFromAppContainerName(
        packageFamilyName, &appContainerSid);
    if (FAILED(hr)) return nullptr;

    // Build an EXPLICIT_ACCESS entry granting synchronization and signal rights
    EXPLICIT_ACCESS_W explicitAccess = {};
    explicitAccess.grfAccessPermissions = SYNCHRONIZE | EVENT_MODIFY_STATE;
    explicitAccess.grfAccessMode = GRANT_ACCESS;
    explicitAccess.grfInheritance = NO_INHERITANCE;
    explicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
    explicitAccess.Trustee.TrusteeType = TRUSTEE_IS_USER;
    explicitAccess.Trustee.ptstrName = reinterpret_cast<LPWSTR>(appContainerSid);

    // Create the ACL
    PACL acl = nullptr;
    DWORD result = SetEntriesInAclW(1, &explicitAccess, nullptr, &acl);
    if (result != ERROR_SUCCESS)
    {
        FreeSid(appContainerSid);
        return nullptr;
    }

    // Create the security descriptor
    SECURITY_DESCRIPTOR sd = {};
    if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) ||
        !SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE))
    {
        LocalFree(acl);
        FreeSid(appContainerSid);
        return nullptr;
    }

    SECURITY_ATTRIBUTES sa = {};
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = &sd;
    sa.bInheritHandle = FALSE;

    // Create the named event with only the rights the creator needs
    HANDLE hEvent = CreateEventExW(&sa, eventName, 0,
        SYNCHRONIZE | EVENT_MODIFY_STATE);

    // Cleanup
    LocalFree(acl);
    FreeSid(appContainerSid);

    return hEvent;
}

Öppna namngivna objekt

Namngivna objekt öppnas genom att ett namn skickas till motsvarande Open API:

Namngivna objekt som skapats av ett paketerat program skapas inom programmets namnområde, även kallat den namngivna objektsökvägen. När du öppnar namngivna objekt som skapats av ett paketerat program måste objektnamnen föregås av det skapande programmets namngivna objektsökväg.

GetAppContainerNamedObjectPath returnerar den namngivna objektsökvägen för ett paketerat program baserat på dess SID. Du kan generera SID för ett paketerat program genom att skicka dess paketfamiljenamn till DeriveAppContainerSidFromAppContainerName.

Note

Paketfamiljenamnet finns via paketmanifestredigeraren i Visual Studio under utvecklingstiden, via Partnercenter för program som publicerats via Microsoft Store eller via Kommandot Get-AppxPackage PowerShell för program som redan är installerade.

När du öppnar namngivna objekt som skapats av ett paketerat program använder du formatet <PATH>\<NAME>:

  • Ersätt <PATH> med det skapande programmets namngivna objektsökväg.
  • Ersätt <NAME> med objektnamnet.

Note

Prefixering av objektnamn med <PATH> krävs endast om ett paketerat program har skapat objektet. Namngivna objekt som skapats av Win32-program behöver inte vara kvalificerade, men åtkomst måste fortfarande beviljas när objekten skapas.

Överväganden för Windows App SDK

Windows App SDK skrivbordsappar som paketeras med MSIX körs som fullständiga förtroendeprocesser med paketidentitet – de körs inte i en AppContainer. Det innebär att deras namngivna objekt skapas i det globala namnområdet som standard, precis som traditionella Win32-program.

Du behöver dock fortfarande ACL- och path-qualification-procedurerna som beskrivs ovan i följande scenarier:

  • Kommunicera med en UWP-app – UWP-appar körs i en AppContainer och har isolerade namnområden för namngivna objekt. Använd GetAppContainerNamedObjectPath och bevilja åtkomst via ACL:er för att nå en UWP-apps namngivna objekt.
  • Begränsa åtkomsten – Även mellan appar med fullständigt förtroende kanske du vill använda explicita ACL:er för att begränsa vilka processer som kan öppna dina namngivna objekt.
  • Ompaketerade Windows App SDK-appar — Namngivna objekt finns i den globala namnrymden utan att någon särskild hantering krävs, identiskt med traditionella Win32-program.

Remarks

Namngivna objekt i paketerade program isoleras som standard för att bevara säkerheten och säkerställa stöd för programlivscykelhändelser som avstängning och avslutning. Delning av namngivna objekt mellan program medför snäva bindnings- och versionsbegränsningar och kräver att varje program är motståndskraftigt mot andras livscykel. Därför rekommenderar vi att du bara delar namngivna objekt mellan program från samma utgivare.