API kümesi kullanılabilirliğini algılama

Bazı durumlarda belirli bir API kümesi sözleşme adı, bazı Windows cihazlarda kasıtlı olarak boş bir modül adına eşlenebilir. Bunun nedenleri farklılık gösterir, ancak yaygın bir örnek olarak sistem kaynakları açısından pahalı bir özellik, kaynak kısıtlanmış bir cihaz için yapılandırıldığında Windows işletim sisteminden kaldırılabilir. Bu, uygulamaların API düzeyinde isteğe bağlı özellikleri düzgün bir şekilde işlemesi için bir zorluk oluşturur.

Win32 API'sinin kullanılabilir olup olmadığını test etmek için kullanılan geleneksel yaklaşım, LoadLibrary veya getProcAddress kullanmaktır. Ancak, bunlar ters iletme nedeniyle API kümelerini test etme için güvenilir bir araç değildir. Belirli bir API'ye ters iletme uygulandığında, iç uygulamanın kaldırıldığı durumlarda bile LoadLibrary veya GetProcAddress geçerli bir işlev işaretçisine çözümlenebilir. Bu durumda, işlev işaretçisi yalnızca hata döndüren bir saplama işlevini işaret eder.

Bu durumu algılamak için IsApiSetImplemented işlevini kullanarak belirli bir API uygulamasının temel kullanılabilirliğini sorgulayabilirsiniz. Bu test, API kümesinin çalışan cihazdaki oluşturulan API kümesi şemasında bulunup bulunmadığını ve bir uygulama modülüne eşlenip eşlenmediğini bildirir.

Important

Başarılı bir kullanılabilirlik sorgusu, belirli bir çağrının başarılı olacağının garantisi değildir. Modül yükleme hatalarını, eksik dışarı aktarmaları ve API'nin kendi belgelenmiş hata sonuçlarını işlemeye devam edin.

Aşağıdaki kod örneği, WTSEnumerateSessionsW içeren API kümesini çağırmadan önce geçerli cihazda kullanılabilir olup olmadığını belirlemek için IsApiSetImplemented'ın nasıl kullanılacağını gösterir.

#include <windows.h>
#include <apiquery2.h>
#include <stdio.h>
#include <wtsapi32.h>

#pragma comment(lib, "OneCore.lib")
#pragma comment(lib, "Wtsapi32.lib")

int __cdecl wmain(int /* argc */, PCWSTR /* argv */ [])
{
    PWTS_SESSION_INFOW pInfo = nullptr;
    DWORD count = 0;

    if (!IsApiSetImplemented("ext-ms-win-session-wtsapi32-l1-1-0"))
    {
        wprintf(L"ext-ms-win-session-wtsapi32-l1-1-0 is not available.\n");
        return 0;
    }

    if (WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pInfo, &count))
    {
        wprintf(L"SessionCount = %lu\n", count);

        for (DWORD i = 0; i < count; i++)
        {
            PWTS_SESSION_INFOW pCurInfo = &pInfo[i];
            wprintf(L"    %ls: ID = %lu, state = %d\n", pCurInfo->pWinStationName,
                pCurInfo->SessionId, static_cast<int>(pCurInfo->State));
        }

        WTSFreeMemory(pInfo);
    }
    else
    {
        wprintf(L"WTSEnumerateSessionsW failure: %lu\n", GetLastError());
    }

    return 0;
}

IsApiSetImplemented apiquery2.h içinde bildirilir ve normal genel SDK bağlantı yolu bunu OneCore.lib dosyasından sağlar. Bu kitaplık, isteğe bağlı hedef API'nin kendisini çağırmak için gereken tüm içeri aktarma kitaplıklarından ayrıdır.

Yukarıdaki örnek, statik içeri aktarma için Wtsapi32.lib'i bağlar ve bu da örneği kısa tutar. API kümesinin olmadığı bir yerde çalışması gereken bir üretim uygulaması, isteğe bağlı kod yolunu erişilebilir durumda tutma konusunda da yönergeleri uygulamalıdır.

Sorgu adını seçin

Test ettiğiniz API kümesinin adını geçirin. API kümesi adları geleneksel olarak sonek .dll olmadan yazılır ve bu sayfadaki örneklerde bu form kullanılır. Sonek, API kümesi adının bir parçası değildir.

Geçirecek adı bulmak için çağırmak istediğiniz API'nin başvuru sayfasındaki Gereksinimler tablosuna bakın. Bu tablonun API kümesi satırı varsa, sözleşme adını verir. Aksi takdirde DLL satırını kullanın, ancak yalnızca adın kendisi veya ile api-ext-başlayan bir sözleşme adı olduğunda ; Wtsapi32.dll gibi fiziksel bir modül adı bir sözleşme değilse ve sorgulandığında YANLIŞ döndürülür.

Adın biçimi, API'nin nasıl ele alınmasına bağlıdır.

API yüzeyi Sorgu formu Example
Adlandırılmış grup <contract>~<group> api-win-core-samplefeature~AdvancedOperations
Varsayılan grup Sözleşme diğer adı, ~Default api-win-core-samplefeature
Sürüme alınan sözleşme Tam sürüme dönüştürülen sözleşme adı ext-ms-win-core-samplefeature-l1-1-0

Adlarsamplefeature, kurgusal bir Windows bileşeni için açıklayıcı adlardır. Ad ön eki (api- veya ext-) kullanılabilirlik davranışında rol oynamaz.

Adlandırılmış bir grup için başarılı bir sorgu, grubun mevcut olduğu, sözleşmesinin bir uygulama modülüne eşlendiği, bu konağın geçerli yürütme ortamında kullanılabilir olduğu, grubun devre dışı bırakılmadığını ve grupla ilişkilendirilmiş herhangi bir sistem özelliğinin etkinleştirildiği anlamına gelir. Sözleşme diğer adı kullanan sorgu, sözleşme ve konak denetimlerini uygular.

API'nin genel üst bilgisi bir Is<APIName>Present yardımcı sağlarsa, bu yardımcıyı tercih edin. ZATEN API'yi taşıyan API kümesi veya grubu için doğru adı içerir.

Sorgunun sonucu, işlev ayrıntı düzeyi değil sözleşme veya grup ayrıntı düzeyidir. Aynı adlandırılmış grup tarafından desteklenen iki yardımcı, her yardımcı farklı bir API için adlandırılmış olsa bile her zaman aynı sonucu döndürür.

İsteğe bağlı kod yolunu erişilebilir durumda tutun

İsteğe bağlı API statik içeri aktarma olarak bağlıysa kullanılabilirlik denetimi işlem başlatmasını koruyamaz. Yükleyici, kodunuz çalışmadan önce statik içeri aktarmaları çözümler, bu nedenle yürütme denetime ulaşmadan önce eksik bir modül işlemi başarısız olur.

Şu yaklaşımlardan birini kullanın:

  • Yükleme gecikmesi için isteğe bağlı API'yi taşıyan modülü yapılandırın. Yükleme gecikmesi bağlayıcı ayarıdır: delayimp.lib değerini belirtin /DELAYLOAD:<module> ve bağlayın. İkili dosyanızın içeri aktarma tablosunda görünen modül adını belirtin. Bu, API kümesi sözleşme adı yerine klasik DLL adı olabilir. Önceki örnekte bu ad WTSAPI32.dll.
  • Alternatif olarak, kullanılabilirlik sorgusu başarılı olduktan sonra LoadLibrary ve GetProcAddress ile hedefi dinamik olarak çözebilirsiniz.

Kullanılabilirlik sorgusunun yerine LoadLibrary veya GetProcAddress kullanmayın. Modülü yanıtlar ve soruları dışarı aktarırlar, adlandırılmış grup durumunu değerlendirmezler ve daha önce açıklandığı gibi ters iletme saplamalarına çözümleyebilirler. Ayrı modülü işlemek ve denetimleri dışarı aktarmak için sorgudan sonra bunları kullanın.

Windows'in önceki sürümlerindeki davranış

OneCore.lib tarafından sağlanan uygulama, çalışma zamanında kullanılabilir bir sorgu mekanizması seçer, bu nedenle IsApiSetImplemented'ı çağıran bir uygulama temel sorgu desteğini önleyen bir sistemde çalışmaya devam edebilir.

Sorgu mekanizmasının kullanılamadığı bir sistemde:

  • İçeren ~ bir grup niteleme adı FALSE döndürür. Adlandırılmış grupları değerlendirebilen bir sistem, bir grubun kullanılabilir olduğunu bildiremez.
  • Grup için uygun olmayan bir ad TRUE döndürebilir. Bu, Windows'in ilk sürümlerinde kendi iletici DLL'lerini sağlayan uygulamalarla uyumluluğu korur ve sözleşme aslında bu iletici tarafından karşılanmıştır.

Api kümesi kullanılabilirlik sorgusunu güvenlik veya yetkilendirme denetimi olarak kullanmayın.

Ayrıca bakınız