Freigeben von benannten Objekten

In diesem Thema wird erläutert, wie benannte Objekte zwischen verpackten Desktop-Apps (einschließlich mit dem Windows App SDK erstellter und mit MSIX paketierter Apps) und nicht paketierten Win32-Anwendungen gemeinsam genutzt werden.

Benannte Objekte in verpackten Anwendungen

Benannte Objekte bieten eine einfache Möglichkeit für Prozesse zum Freigeben von Objekthandles. Nachdem ein Prozess ein benanntes Objekt erstellt hat, können andere Prozesse den Namen verwenden, um die entsprechende Funktion aufzurufen, um ein Handle für das Objekt zu öffnen. Benannte Objekte werden häufig für die Threadsynchronisierung und die Interprocesskommunikation verwendet.

Anwendungen, die in einem AppContainer (z. B. UWP-Apps) ausgeführt werden, verfügen standardmäßig über einen isolierten Namespace für benannte Objekte — sie können nur auf benannte Objekte zugreifen, die sie selbst erstellt haben. Voll vertrauenswürdige verpackte Desktop-Apps (einschließlich Windows App SDK-Apps) verfügen nicht über diese Isolation und erstellen benannte Objekte im globalen Namespace. Ausführliche Informationen finden Sie unter Windows App SDK Überlegungen.

Um benannte Objekte für AppContainer-Apps freigeben zu können, müssen Berechtigungen festgelegt werden, wenn Objekte erstellt werden, und Namen müssen beim Öffnen von Objekten qualifiziert werden. Die Techniken in diesem Artikel sind auch hilfreich, wenn Sie unabhängig von der Verpackung den Zugriff zwischen allen Prozessen einschränken möchten.

Erstellen benannter Objekte

Benannte Objekte werden mit einer entsprechenden Create API erstellt:

Alle diese APIs verwenden einen LPSECURITY_ATTRIBUTES Parameter, mit dem der Aufrufer Zugriffssteuerungslisten (Access Control Lists, ACLs) angeben kann, um zu steuern, welche Prozesse auf das Objekt zugreifen können. Um benannte Objekte für verpackte Anwendungen freizugeben, muss die Berechtigung innerhalb der ACLs erteilt werden, wenn die benannten Objekte erstellt werden.

Sicherheits-IDs (SIDs) stellen Identitäten innerhalb von ACLs dar. Jede verpackte Anwendung verfügt über eine eigene SID basierend auf dem Paketfamiliennamen. Sie können die SID für eine verpackte Anwendung generieren, indem Sie den Paketfamiliennamen an "DeriveAppContainerSidFromAppContainerName" übergeben.

Note

Der Paketfamilienname kann über den Paketmanifest-Editor in Visual Studio während der Entwicklungszeit, über Partner Center für Anwendungen gefunden werden, die über die Microsoft Store veröffentlicht wurden, oder über den Befehl "Get-AppxPackage PowerShell" für bereits installierte Anwendungen.

In diesem Beispiel wird das grundlegende Muster veranschaulicht, das für ACL ein benanntes Objekt erforderlich ist. Wenn Sie benannte Objekte für verpackte Anwendungen freigeben möchten, erstellen Sie eine EXPLICIT_ACCESS Struktur für jede Anwendung:

Indem Sie den LPSECURITY_ATTRIBUTES Parameter in Create Aufrufen mit EXPLICIT_ACCESS Regeln für verpackte Anwendungen auffüllen, können Sie zugriff auf diese Anwendungen gewähren, um das benannte Objekt zu öffnen.

Note

Win32-Anwendungen können auf benannte Objekte zugreifen, die von AppContainer-Apps erstellt wurden, indem sie beim Öffnen die Objektnamen qualifizieren, sofern die DACL des Objekts den Zugriff zulässt. Die Standardmäßige DACL für die meisten benannten Objekte gewährt Zugriff auf den Ersteller und administratoren. Wenn Sie eine restriktive DACL festgelegt haben, benötigen Win32-Aufrufer auch einen expliziten Zugriffseintrag.

Beispiel: Erstellen eines benannten Ereignisses mit ACL (C++)

Das folgende Beispiel zeigt, wie Sie ein benanntes Ereignis erstellen und zugriff auf eine verpackte Anwendung gewähren:

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

Öffnen benannter Objekte

Benannte Objekte werden geöffnet, indem ein Name an eine entsprechende Open API übergeben wird:

Benannte Objekte, die von einer verpackten Anwendung erstellt werden, werden im Namespace der Anwendung erstellt, andernfalls als benannter Objektpfad bezeichnet. Beim Öffnen benannter Objekte, die von einer verpackten Anwendung erstellt wurden, müssen die Objektnamen dem benannten Objektpfad der Erstellungsanwendung vorangestellt werden.

GetAppContainerNamedObjectPath gibt den benannten Objektpfad für eine verpackte Anwendung basierend auf der SID zurück. Sie können die SID für eine verpackte Anwendung generieren, indem Sie den Paketfamiliennamen an "DeriveAppContainerSidFromAppContainerName" übergeben.

Note

Der Paketfamilienname kann über den Paketmanifest-Editor in Visual Studio während der Entwicklungszeit, über Partner Center für Anwendungen gefunden werden, die über die Microsoft Store veröffentlicht wurden, oder über den Befehl "Get-AppxPackage PowerShell" für bereits installierte Anwendungen.

Verwenden Sie beim Öffnen benannter Objekte, die von einer verpackten Anwendung erstellt wurden, das Format <PATH>\<NAME>:

  • Ersetzen Sie <PATH> durch den benannten Objektpfad der erstellenden Anwendung.
  • Ersetzen Sie <NAME> durch den Objektnamen.

Note

Das Voranstellen von <PATH> vor Objektnamen ist nur erforderlich, wenn eine gepackte Anwendung das Objekt erstellt hat. Benannte Objekte, die von Win32-Anwendungen erstellt wurden, müssen nicht qualifiziert werden, aber der Zugriff muss weiterhin gewährt werden, wenn die Objekte erstellt werden.

Überlegungen zum Windows App SDK

Windows App SDK Desktop-Apps, die mit MSIX verpackt sind, werden als voll vertrauenswürdige Prozesse mit Paketidentität ausgeführt – sie werden nicht in einem AppContainer ausgeführt. Dies bedeutet, dass ihre benannten Objekte standardmäßig im globalen Namespace erstellt werden, genau wie herkömmliche Win32-Anwendungen.

Sie benötigen jedoch weiterhin die oben beschriebenen ACL- und Pfadqualifizierungsverfahren in diesen Szenarien:

  • Kommunikation mit einer UWP-App – UWP-Apps werden in einem AppContainer ausgeführt und verfügen über isolierte Namespaces mit benannten Objekten. Verwenden GetAppContainerNamedObjectPath und gewähren Sie Zugriff über ACLs, um die benannten Objekte einer UWP-App zu erreichen.
  • Einschränken des Zugriffs – Auch zwischen voll vertrauenswürdigen Apps sollten Sie explizite ACLs verwenden, um einzuschränken, welche Prozesse ihre benannten Objekte öffnen können.
  • Entpackte Windows App SDK-Apps – Benannte Objekte befinden sich im globalen Namespace, ohne dass eine spezielle Behandlung erforderlich ist, identisch mit herkömmlichen Win32-Anwendungen.

Remarks

Benannte Objekte in verpackten Anwendungen sind standardmäßig isoliert, um die Sicherheit zu erhalten und sicherzustellen, dass die Unterstützung für Anwendungslebenszyklusereignisse wie Anhalten und Beenden gewährleistet wird. Das Freigeben benannter Objekte für alle Anwendungen führt zu engen Bindungs- und Versionsverwaltungseinschränkungen und erfordert, dass jede Anwendung für den Lebenszyklus anderer widerstandsfähig ist. Aus diesen Gründen wird empfohlen, benannte Objekte nur zwischen Anwendungen aus demselben Herausgeber zu teilen.