Benoemde objecten delen

In dit onderwerp wordt uitgelegd hoe u benoemde objecten kunt delen tussen verpakte bureaublad-apps (inclusief Windows App SDK apps die zijn verpakt met MSIX) en uitgepakte Win32-toepassingen.

Benoemde objecten in verpakte toepassingen

Benoemde objecten bieden een eenvoudige manier voor processen om objectgrepen te delen. Nadat een proces een benoemd object heeft gemaakt, kunnen andere processen de naam gebruiken om de juiste functie aan te roepen om een ingang voor het object te openen. Benoemde objecten worden vaak gebruikt voor threadsynchronisatie en communicatie tussen processen.

Toepassingen die worden uitgevoerd in een AppContainer (zoals UWP-apps) hebben standaard een geïsoleerde naamruimte voor benoemde objecten. Ze hebben alleen toegang tot benoemde objecten die ze hebben gemaakt. Volledig vertrouwde desktop-apps (inclusief Windows App SDK-apps) hebben deze isolatie niet en maken benoemde objecten in de globale naamruimte. Zie Windows App SDK overwegingen voor meer informatie.

Als u benoemde objecten wilt delen met AppContainer-apps, moeten machtigingen worden ingesteld wanneer objecten worden gemaakt en moeten namen worden gekwalificeerd wanneer objecten worden geopend. De technieken in dit artikel zijn ook handig als u de toegang tussen processen wilt beperken, ongeacht de verpakking.

Benoemde objecten maken

Benoemde objecten worden gemaakt met een bijbehorende Create API:

Al deze API's delen een LPSECURITY_ATTRIBUTES parameter waarmee de aanroeper toegangsbeheerlijsten (ACL's) kan opgeven om te bepalen welke processen toegang hebben tot het object. Als u benoemde objecten wilt delen met verpakte toepassingen, moet de machtiging worden verleend binnen de ACL's wanneer de benoemde objecten worden gemaakt.

Beveiligings-id's (SID's) vertegenwoordigen identiteiten binnen ACL's. Elke verpakte toepassing heeft een eigen SID op basis van de familienaam van het pakket. U kunt de SID genereren voor een verpakte toepassing door de familienaam van het pakket door te geven aan DeriveAppContainerSidFromAppContainerName.

Note

De familienaam van het pakket vindt u via de manifesteditor van het pakket in Visual Studio tijdens de ontwikkeling, via partnercentrum voor toepassingen die zijn gepubliceerd via de Microsoft Store, of via de opdracht Get-AppxPackage PowerShell voor toepassingen die al zijn geïnstalleerd.

In dit voorbeeld ziet u het basispatroon dat nodig is voor de ACL van een benoemd object. Als u benoemde objecten wilt delen met verpakte toepassingen, bouwt u een EXPLICIT_ACCESS structuur voor elke toepassing:

Door de LPSECURITY_ATTRIBUTES parameter in Create aanroepen te vullen met EXPLICIT_ACCESS regels voor verpakte toepassingen, kunt u toegang verlenen tot deze toepassingen om het benoemde object te openen.

Note

Win32-toepassingen hebben toegang tot benoemde objecten die zijn gemaakt door AppContainer-apps door de objectnamen te kwalificeren bij het openen ervan, mits de DACL van het object toegang toestaat. De standaard-DACL voor de meeste benoemde objecten verleent toegang tot de maker en beheerders. Als u een beperkende DACL hebt ingesteld, hebben Win32-bellers ook een expliciet toegangsgegeven nodig.

Voorbeeld: Een benoemde gebeurtenis maken met ACL (C++)

In het volgende voorbeeld ziet u hoe u een benoemde gebeurtenis maakt en toegang verleent tot een verpakte toepassing:

#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;
}

Benoemde objecten openen

Benoemde objecten worden geopend door een naam door te geven aan een bijbehorende Open API:

Benoemde objecten die zijn gemaakt door een verpakte toepassing, worden gemaakt in de naamruimte van de toepassing, ook wel het benoemde objectpad genoemd. Wanneer u benoemde objecten opent die door een verpakte toepassing zijn gemaakt, moet aan de objectnamen het pad voor benoemde objecten van de toepassing die ze heeft gemaakt als voorvoegsel worden toegevoegd.

GetAppContainerNamedObjectPath retourneert het benoemde objectpad voor een verpakte toepassing op basis van de BIJBEHORENDE SID. U kunt de SID genereren voor een verpakte toepassing door de familienaam van het pakket door te geven aan DeriveAppContainerSidFromAppContainerName.

Note

De familienaam van het pakket vindt u via de manifesteditor van het pakket in Visual Studio tijdens de ontwikkeling, via partnercentrum voor toepassingen die zijn gepubliceerd via de Microsoft Store, of via de opdracht Get-AppxPackage PowerShell voor toepassingen die al zijn geïnstalleerd.

Wanneer u benoemde objecten opent die zijn gemaakt door een verpakte toepassing, gebruikt u de indeling <PATH>\<NAME>:

  • Vervang <PATH> door het pad van het benoemde object van de toepassings waarmee het is gemaakt.
  • Vervang door <NAME> de objectnaam.

Note

Het voorvoegsel van objectnamen met <PATH> is alleen vereist als een verpakte toepassing het object heeft gemaakt. Benoemde objecten die zijn gemaakt door Win32-toepassingen hoeven niet te worden gekwalificeerd, maar toegang moet nog steeds worden verleend wanneer de objecten worden gemaakt.

Overwegingen voor Windows App SDK

Windows App SDK desktop-apps die zijn verpakt met MSIX worden uitgevoerd als volledige vertrouwensprocessen met pakketidentiteit. Ze worden niet uitgevoerd in een AppContainer. Dit betekent dat hun benoemde objecten standaard in de globale naamruimte worden gemaakt, net als bij traditionele Win32-toepassingen.

U hebt echter nog steeds de ACL- en padkwalificatieprocedures nodig die hierboven in deze scenario's worden beschreven:

  • Communiceren met een UWP-app : UWP-apps worden uitgevoerd in een AppContainer en hebben geïsoleerde benoemde objectnaamruimten. Gebruik GetAppContainerNamedObjectPath en verleen toegang via ACL's voor toegang tot de named objects van een UWP-app.
  • Toegang beperken : zelfs tussen apps met volledige vertrouwensrelatie kunt u expliciete ACL's gebruiken om te beperken welke processen uw benoemde objecten kunnen openen.
  • Uitgepakte Windows App SDK-apps: benoemde objecten bevinden zich in de globale naamruimte zonder speciale verwerking vereist, identiek aan traditionele Win32-toepassingen.

Remarks

Benoemde objecten in verpakte toepassingen worden standaard geïsoleerd om de beveiliging te behouden en ervoor te zorgen dat ondersteuning wordt geboden voor levenscyclusgebeurtenissen van toepassingen, zoals opschorten en beëindigen. Het delen van benoemde objecten in toepassingen introduceert strikte bindings- en versiebeheerbeperkingen en vereist dat elke toepassing bestand is tegen de levenscyclus van anderen. Daarom is het raadzaam om alleen benoemde objecten te delen tussen toepassingen van dezelfde uitgever.