Sdílení pojmenovaných objektů

Toto téma vysvětluje, jak sdílet pojmenované objekty mezi zabalenými desktopovými aplikacemi (včetně aplikací Windows App SDK zabalených pomocí MSIX) a rozbalených aplikací Win32.

Pojmenované objekty v zabalených aplikacích

Pojmenované objekty umožňují procesům snadno sdílet popisovače objektů. Poté, co proces vytvoří pojmenovaný objekt, mohou ostatní procesy použít jeho název k vyvolání příslušné funkce pro otevření popisovače pro tento objekt. Pojmenované objekty se běžně používají pro synchronizaci vláken a komunikaci mezi procesy.

Aplikace spuštěné v appContaineru (například aplikace pro UPW) mají ve výchozím nastavení izolovaný obor názvů pojmenovaných objektů – mají přístup pouze k pojmenovaným objektům, které vytvořily. Desktopové aplikace v balíčku s plnou důvěrou (včetně aplikací Windows App SDK) tuto izolaci nemají a vytvářejí pojmenované objekty v globálním oboru názvů. Podrobnosti najdete v pokynech k Windows App SDK.

Pokud chcete s aplikacemi AppContainer sdílet pojmenované objekty, musí být oprávnění nastavena při vytváření objektů a názvy musí být při otevření objektů kvalifikované. Techniky v tomto článku jsou také užitečné, pokud chcete omezit přístup mezi všemi procesy bez ohledu na balení.

Vytváření pojmenovaných objektů

Pojmenované objekty se vytvoří s odpovídajícím Create rozhraním API:

Všechna tato rozhraní API sdílejí LPSECURITY_ATTRIBUTES parametr, který volajícímu umožňuje určit seznamy řízení přístupu (ACL) k řízení toho, jaké procesy mají přístup k objektu. Aby bylo možné sdílet pojmenované objekty s zabalenými aplikacemi, musí být oprávnění udělena v rámci seznamů ACL při vytváření pojmenovaných objektů.

Identifikátory zabezpečení (SID) představují identity v rámci seznamů ACL. Každá zabalená aplikace má svůj vlastní identifikátor SID založený na názvu své rodiny balíčků. Identifikátor SID pro zabalenou aplikaci můžete vygenerovat předáním jejího názvu rodiny balíčků do DeriveAppContainerSidFromAppContainerName.

Note

Název rodiny balíčků najdete v editoru manifestu balíčku v Visual Studio během vývoje, prostřednictvím Partnerského centra pro aplikace publikované prostřednictvím Microsoft Store nebo pomocí příkazu Get-AppxPackage PowerShellu pro aplikace, které jsou už nainstalované.

Tato ukázka demonstruje základní postup potřebný k nastavení seznamu ACL u pojmenovaného objektu. Pokud chcete sdílet pojmenované objekty s zabalenými aplikacemi, vytvořte pro každou aplikaci strukturu EXPLICIT_ACCESS :

Naplněním parametru LPSECURITY_ATTRIBUTES ve Create volání pravidly EXPLICIT_ACCESS pro zabalené aplikace můžete těmto aplikacím udělit přístup k otevření pojmenovaného objektu.

Note

Aplikace Win32 mohou přistupovat k pojmenovaným objektům vytvořeným aplikacemi AppContainer tím, že při jejich otevírání upřesní názvy objektů, za předpokladu, že seznam DACL daného objektu takový přístup povoluje. Výchozí seznam DACL pro většinu pojmenovaných objektů uděluje přístup tvůrci a správcům. Pokud jste nastavili omezující seznam DACL, volající Win32 potřebují také explicitní přístupovou položku.

Příklad: Vytvoření pojmenované události s ACL (C++)

Následující příklad ukazuje, jak vytvořit pojmenovanou událost a udělit přístup k zabalené aplikaci:

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

Otevření pojmenovaných objektů

Pojmenované objekty se otevírají předáním názvu odpovídajícímu Open rozhraní API:

Pojmenované objekty vytvořené zabalenou aplikací se vytvoří v rámci oboru názvů aplikace, jinak označované jako pojmenovaná cesta k objektu. Při otevírání pojmenovaných objektů vytvořených aplikací v balíčku musí názvy objektů začínat cestou k pojmenovaným objektům aplikace, která je vytvořila.

GetAppContainerNamedObjectPath vrátí pojmenovanou cestu objektu pro zabalenou aplikaci na základě jeho identifikátoru SID. Identifikátor SID pro zabalenou aplikaci můžete vygenerovat předáním jejího názvu rodiny balíčků do DeriveAppContainerSidFromAppContainerName.

Note

Název rodiny balíčků najdete v editoru manifestu balíčku v Visual Studio během vývoje, prostřednictvím Partnerského centra pro aplikace publikované prostřednictvím Microsoft Store nebo pomocí příkazu Get-AppxPackage PowerShellu pro aplikace, které jsou už nainstalované.

Při otevírání pojmenovaných objektů vytvořených zabalenou aplikací použijte formát <PATH>\<NAME>:

  • Nahraďte <PATH> pojmenovanou cestou k objektu aplikace, která jej vytvořila.
  • Nahraďte <NAME> názvem objektu.

Note

Názvy objektů s předponou <PATH> se vyžadují pouze v případě, že zabalená aplikace objekt vytvořila. Pojmenované objekty vytvořené aplikacemi Win32 nemusí být kvalifikované, i když při vytváření objektů musí být udělen přístup.

Důležité informace o sadě Windows App SDK

Desktopové aplikace Windows App SDK zabalené pomocí MSIX běží jako procesy s plnou důvěryhodností s identitou balíčku — neběží v AppContaineru. To znamená, že jejich pojmenované objekty se ve výchozím nastavení vytvářejí v globálním oboru názvů, stejně jako tradiční aplikace Win32.

Stále však potřebujete postupy pro ACL a ověřování cest popsané výše v následujících scénářích:

  • Komunikace s aplikací pro UPW – aplikace UPW běží v appContaineru a mají izolované obory názvů pojmenovaných objektů. Použijte GetAppContainerNamedObjectPath a udělte přístup přes ACL k pojmenovaným objektům aplikace UWP.
  • Omezení přístupu – I mezi plně důvěryhodnými aplikacemi můžete použít explicitní seznamy ACL, abyste omezili, které procesy můžou otevírat pojmenované objekty.
  • Nebalené aplikace Windows App SDK – Pojmenované objekty jsou v globálním oboru názvů bez nutnosti zvláštního zacházení, stejně jako u tradičních aplikací Win32.

Remarks

Pojmenované objekty v zabalených aplikacích jsou ve výchozím nastavení izolované, aby se zachovalo zabezpečení a zajistilo podporu událostí životního cyklu aplikace, jako je pozastavení a ukončení. Sdílení pojmenovaných objektů napříč aplikacemi zavádí úzká omezení vazby a správy verzí a vyžaduje, aby každá aplikace byla odolná vůči životnímu cyklu ostatních. Z těchto důvodů se doporučuje sdílet pouze pojmenované objekty mezi aplikacemi od stejného vydavatele.