Berbagi objek bernama

Topik ini menjelaskan cara berbagi objek bernama antara aplikasi desktop kemasan (termasuk aplikasi SDK Aplikasi Windows yang dikemas dengan MSIX) dan aplikasi Win32 yang tidak dikemas.

Objek bernama dalam aplikasi paket

Objek yang dinamai menyediakan cara mudah agar proses dapat berbagi handle objek. Setelah suatu proses membuat objek yang diberi nama, proses lain dapat menggunakan nama tersebut untuk memanggil fungsi yang sesuai guna membuka handle ke objek tersebut. Objek bernama umumnya digunakan untuk sinkronisasi utas dan komunikasi antarproseksi.

Aplikasi yang berjalan di AppContainer (seperti aplikasi UWP) memiliki namespace layanan objek bernama yang terisolasi secara default — aplikasi tersebut hanya dapat mengakses objek bernama yang telah mereka buat. Aplikasi desktop yang dipaketkan dengan full-trust (termasuk aplikasi SDK Aplikasi Windows) tidak memiliki isolasi ini dan membuat objek bernama di namespace global. Lihat pertimbangan SDK Aplikasi Windows untuk detailnya.

Untuk berbagi objek bernama dengan aplikasi AppContainer, izin harus diatur saat objek dibuat, dan nama harus memenuhi syarat saat objek dibuka. Teknik dalam artikel ini juga berguna ketika Anda ingin membatasi akses antara proses apa pun, terlepas dari kemasan.

Membuat objek yang diberi nama

Objek yang diberi nama dibuat menggunakan API Create yang sesuai:

Semua API ini berbagi LPSECURITY_ATTRIBUTES parameter yang memungkinkan pemanggil menentukan daftar kontrol akses (ACL) untuk mengontrol proses apa yang dapat mengakses objek. Untuk berbagi objek bernama dengan aplikasi paket, izin harus diberikan dalam ACL saat objek bernama dibuat.

Pengidentifikasi keamanan (SID) mewakili identitas dalam ACL. Setiap aplikasi yang dikemas memiliki SID sendiri berdasarkan nama keluarga paketnya. Anda dapat membuat SID untuk aplikasi yang dikemas dengan meneruskan nama keluarga paketnya ke DeriveAppContainerSidFromAppContainerName.

Note

Nama keluarga paket dapat ditemukan melalui editor manifes paket di Visual Studio selama waktu pengembangan, melalui Pusat Mitra untuk aplikasi yang diterbitkan melalui Microsoft Store, atau melalui perintah Get-AppxPackage PowerShell untuk aplikasi yang sudah diinstal.

Sampel ini menunjukkan pola dasar yang diperlukan untuk ACL objek bernama. Untuk berbagi objek bernama dengan aplikasi paket, buat struktur EXPLICIT_ACCESS untuk setiap aplikasi:

Dengan mengisi LPSECURITY_ATTRIBUTES parameter dalam Create panggilan dengan EXPLICIT_ACCESS aturan untuk aplikasi paket, Anda dapat memberikan akses ke aplikasi tersebut untuk membuka objek bernama.

Note

Aplikasi Win32 dapat mengakses objek bernama yang dibuat oleh aplikasi AppContainer dengan memenuhi syarat nama objek saat membukanya, asalkan DACL objek mengizinkan akses. DACL default untuk sebagian besar objek bernama memberikan akses ke pembuat dan administrator. Jika Anda telah menetapkan DACL yang membatasi, pemanggil Win32 juga memerlukan entri akses yang eksplisit.

Contoh: Membuat event bernama dengan ACL (C++)

Contoh berikut menunjukkan cara membuat peristiwa bernama dan memberikan akses ke aplikasi paket:

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

Membuka objek bernama

Objek bernama dibuka dengan meneruskan nama ke API yang sesuai Open :

Objek bernama yang dibuat oleh aplikasi paket dibuat dalam namespace aplikasi, atau dikenal sebagai jalur objek bernama. Saat membuka objek bernama yang dibuat oleh aplikasi terpaket, nama objek harus diawali dengan jalur objek bernama milik aplikasi yang membuatnya.

GetAppContainerNamedObjectPath mengembalikan jalur objek bernama untuk aplikasi paket berdasarkan SID-nya. Anda dapat membuat SID untuk aplikasi yang dikemas dengan meneruskan nama keluarga paketnya ke DeriveAppContainerSidFromAppContainerName.

Note

Nama keluarga paket dapat ditemukan melalui editor manifes paket di Visual Studio selama waktu pengembangan, melalui Pusat Mitra untuk aplikasi yang diterbitkan melalui Microsoft Store, atau melalui perintah Get-AppxPackage PowerShell untuk aplikasi yang sudah diinstal.

Saat membuka objek bernama yang dibuat oleh aplikasi paket, gunakan format <PATH>\<NAME>:

  • Ganti <PATH> dengan jalur objek bernama milik aplikasi pembuat.
  • Ganti <NAME> dengan nama objek.

Note

Awalan nama objek dengan <PATH> hanya diperlukan jika aplikasi paket membuat objek. Objek bernama yang dibuat oleh aplikasi Win32 tidak perlu diberi kualifikasi, meskipun akses tetap harus diberikan saat objek dibuat.

Pertimbangan SDK Aplikasi Windows

SDK Aplikasi Windows aplikasi desktop yang dipaketkan dengan MSIX berjalan sebagai proses kepercayaan penuh dengan identitas paket — aplikasi tersebut tidak berjalan di AppContainer. Ini berarti objek bernama mereka dibuat di namespace global secara default, sama seperti aplikasi Win32 tradisional.

Namun, Anda masih memerlukan prosedur ACL dan kualifikasi jalur yang dijelaskan di atas dalam skenario ini:

  • Berkomunikasi dengan aplikasi UWP — aplikasi UWP berjalan di AppContainer dan telah mengisolasi namespace objek bernama. Gunakan GetAppContainerNamedObjectPath dan berikan akses melalui ACL untuk menjangkau objek bernama aplikasi UWP.
  • Membatasi akses — Bahkan di antara aplikasi kepercayaan penuh, Anda mungkin ingin menggunakan ACL eksplisit untuk membatasi proses mana yang dapat membuka objek bernama Anda.
  • Aplikasi SDK Aplikasi Windows yang tidak dikemas — Objek bernama berada di namespace layanan global tanpa diperlukan penanganan khusus, identik dengan aplikasi Win32 tradisional.

Remarks

Objek bernama dalam aplikasi paket diisolasi secara default untuk mempertahankan keamanan dan memastikan dukungan untuk peristiwa siklus hidup aplikasi seperti penangguhan dan penghentian. Berbagi objek bernama di seluruh aplikasi memperkenalkan batasan pengikatan dan penerapan versi yang ketat dan mengharuskan setiap aplikasi untuk tahan terhadap siklus hidup orang lain. Untuk alasan ini, disarankan untuk hanya berbagi objek bernama antar aplikasi dari penerbit yang sama.