OneCore をターゲットとしたビルド
Visual Studio を使用して Windows 10 のユーザー モード コードをビルドする場合、リンカー オプションをカスタマイズして、特定のバージョンの Windows をターゲットにすることができます。 次のような要素が考えられます。
ビルドされたバイナリは最新バージョンの Windows でのみ実行する必要がありますか? それとも、以前のバージョン (Windows 7 など) でも実行できますか。
プロジェクトに UWP の依存関係はありますか?
たとえば、新しい UMDF v2 ドライバー プロジェクトを作成した場合、Visual Studio は既定で OneCoreUAP.lib
にリンクします。 これにより、最新バージョンの Windows で動作するバイナリが作成され、UWP 機能の追加が可能になります。
ただし、要件によっては、代わりに OneCore.lib
をリンクすることができます。 次の表は、各ライブラリに対応するシナリオを示したものです。
ライブラリ | シナリオ |
---|---|
OneCore.lib |
Windows 7 以降のすべてのエディション (UWP のサポートなし) |
OneCoreUAP.lib |
Windows 7 以降、Windows 10 の UWP エディション (デスクトップ、IoT、HoloLens、ただし Nano Server は除く) |
Note
Visual Studio でリンカー オプションを変更するには、プロジェクトのプロパティを選択して、[リンカー] -> [入力] -> [追加の依存ファイル] に移動します。
Windows API のサブセットは正常にコンパイルされますが、デスクトップ以外の OneCore エディション (モバイルや IoT など) ではランタイム エラーが返されます。
たとえば、InstallApplication 関数は、デスクトップ以外の OneCore エディションで ERROR_ NOT_SUPPORTED
を返します。 これらの問題は ApiValidatorツールでも報告されます。 次のセクションでは、この問題を修正する方法について説明します。
IsApiSetImplemented を使用して ApiValidator のエラーを修正する
コードで非ユニバーサル API を呼び出すと、次の ApiValidator エラーが返される場合があります。
Error: <Binary Name> has unsupported API call to <Module Name><Api Name>
アプリやベース ドライバーを Windows 10 と以前のバージョンの Windows で実行する必要がある場合は、上記のカテゴリの API 呼び出しを削除する必要があります。
Error: <Binary Name> has a dependency on <Module Name><Api Name> but is missing: IsApiSetImplemented("<contract-name-for-Module>)
上記のカテゴリの API 呼び出しは正常にコンパイルされますが、対象のオペレーティング システムによっては、実行時に想定どおりの動作をしない可能性があります。 Windows ドライバーの API レイヤー化要件をパスするには、IsApiSetImplemented を使用してこれらの呼び出しをラップします。
これにより、コードをエラーなくコンパイルすることができます。 その後の実行時に、ターゲット コンピューターに必要な API がない場合は、IsApiSetImplemented で FALSE が返されます。
次のコード サンプルは、これを行う方法を説明したものです。
コードサンプル: 存在を評価せずに API を直接使用する
このコードは Windows 10 より前のバージョンの Windows では正常に動作しますが、Windows 10 の OneCore エディションで実行すると WTSEnumerateSessions エラーが発生します。78 または ERROR_CALL_NOT_IMPLEMENTED 120 (0x78)。
このコード サンプルは、Windows ドライバーの API レイヤー化要件を満たさず、次の ApiValidator エラーが表示されます。
ApiValidation: Error: FlexLinkTest.exe has a dependency on 'wtsapi32.dll!WTSEnumerateSessionsW' but is missing: IsApiSetImplemented("ext-ms-win-session-wtsapi32-l1-1-0")
ApiValidation: Error: FlexLinkTest.exe has a dependency on 'wtsapi32.dll!WTSFreeMemory' but is missing: IsApiSetImplemented("ext-ms-win-session-wtsapi32-l1-1-0")
ApiValidation: NOT all binaries are Universal
のコードを次に示します。
#include <windows.h>
#include <stdio.h>
#include <Wtsapi32.h>
int __cdecl wmain(int /* argc */, PCWSTR /* argv */ [])
{
PWTS_SESSION_INFO pInfo = {};
DWORD count = 0;
if (WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pInfo, &count))
{
wprintf(L"SessionCount = %d\n", count);
for (ULONG i = 0; i < count; i++)
{
PWTS_SESSION_INFO pCurInfo = &pInfo[i];
wprintf(L" %s: ID = %d, state = %d\n", pCurInfo->pWinStationName, pCurInfo->SessionId, pCurInfo->State);
}
WTSFreeMemory(pInfo);
}
else
{
wprintf(L"WTSEnumerateSessions failure : %x\n", GetLastError());
}
return 0;
}
コードサンプル: 存在を評価した後の API の直接使用
このサンプルは、IsApiSetImplemented を呼び出す方法を示したものです。 このサンプルは、Windows ドライバーの API レイヤー化要件を満たし、次の ApiValidator 出力が表示されます。
ApiValidation: All binaries are Universal
のコードを次に示します。
#include <windows.h>
#include <stdio.h>
#include <Wtsapi32.h>
int __cdecl wmain(int /* argc */, PCWSTR /* argv */ [])
{
PWTS_SESSION_INFO pInfo = {};
DWORD count = 0;
if (!IsApiSetImplemented("ext-ms-win-session-wtsapi32-l1-1-0"))
{
wprintf(L"IsApiSetImplemented on ext-ms-win-session-wtsapi32-l1-1-0 returns FALSE\n");
}
else
{
if (WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pInfo, &count))
{
wprintf(L"SessionCount = %d\n", count);
for (ULONG i = 0; i < count; i++)
{
PWTS_SESSION_INFO pCurInfo = &pInfo[i];
wprintf(L" %s: ID = %d, state = %d\n", pCurInfo->pWinStationName, pCurInfo->SessionId, pCurInfo->State);
}
WTSFreeMemory(pInfo);
}
else
{
wprintf(L"WTSEnumerateSessions failure : %x\n", GetLastError());
}
}
return 0;
}
推奨アクション
- 上記のリンカー オプションを確認し、それに応じて Visual Studio プロジェクトを更新します。
- WDK の ApiValidator ツールを使用します。 このツールは、Visual Studio でドライバーをビルドするときに自動的に実行されます。
- ランタイム テストを使用して、ユーザー モード コードがデスクトップ以外の OneCore エディションで期待どおりに実行されることを確認します。 スタブ化された API は異なるエラー コードを生成する可能性があることに注意してください。