WoW64サブシステムとARM64 ♯3 GetMachineTypeAttributes()

前回の投稿では、Windows 10までに存在していたAPIの振る舞いを確認しました。今回は、Windows 11で追加されたAPIの振る舞いを確認します。

Windows 11で追加されたアプリの実行環境情報取得に関するAPI

エミュレーション環境に関するAPIの振る舞い確認用テストツール(WoW64Test)を前回の投稿で公開しました。この時は、Windows 11で新規APIが追加されたことを知りませんでした。

その後、アプリの実行環境に関する情報取得APIがWindows 11で追加されていたことを知りました。GetMachineTypeAttributes()という名前のAPIです。

GetMachineTypeAttributes()

APIリファレンスを引用すると、概要として以下のように書かれています。

Queries if the specified architecture is supported on the current system, either natively or by any form of compatibility or emulation layer.

日本語訳は以下の感じです。

指定されたアーキテクチャが、ネイティブ、あるいは、何らかの互換性レイヤーやエミュレーションレイヤーのような形によって現在のシステムでサポートされているかどうかを問い合わせます。

WoW64の方式に限らず、指定したアーキテクチャのアプリが何らかの方法で実行できるかどうかを確認することができるAPIです。

HRESULT GetMachineTypeAttributes(
  _In_ USHORT             Machine,
  _Out_ MACHINE_ATTRIBUTES *MachineTypeAttributes
);

第一引数にアーキテクチャーを指定すると、そのアーキテクチャーの情報が取得できます。得られる情報は、下記のMACHINE_ATTRIBUTES列挙型のビットフラグとなります。

typedef enum _MACHINE_ATTRIBUTES {
  UserEnabled = 0x00000001,
  KernelEnabled = 0x00000002,
  Wow64Container = 0x00000004
} MACHINE_ATTRIBUTES;

アプリが動作するかどうかは、UserEnabledフラグで分かります。また、WoW64コンテナー上で動作するかどうかは、Wow64Containerフラグでわかります。このWow64Containerフラグの意味を詳しく見てみます。

Wow64Container
The specified architecture of code runs by relying on WOW64's namespace File System Redirector and Registry Redirector. This bit will be set, for example, on x86 code running on a host operating system that is x64 or ARM64. When the compatibility layer does not use WOW64 style filesystem and registry namespaces, like x64 on ARM64 which runs on the root namespace of the OS, this bit will be reset.

日本語訳は以下の感じです。

Wow64Container
指定されたアーキテクチャのコードは、WOW64の名前空間、File System RedirectorとRegistry Redirectorに依存して実行されます。このビットは、例えばx64やARM64であるホストOS上で実行されるx86コードでセットされます。互換性層がWOW64スタイルのファイルシステムとレジストリの名前空間を使用しない場合(例えばOSのルート名前空間上で実行されるARM64上のx64のような場合)、このビットはリセットされます。

Wow64Containerフラグは、互換性層で実行されるかどうかを表すのではなく、ファイルシステム リダイレクターやレジストリ リダイレクターに依存して実行されるかどうかを表します。

そのため、ARM64 Windows 11上でのx64アーキテクチャでは、互換性層は使いますが、リダイレクターは使われないのでWow64Containerフラグがセットされません。

では、実際の実行結果を確認します。GetMachineTypeAttributes()にも対応したテストアプリである「WoW64 Test App 1.1.0 (WoW64のテスト用アプリ 1.1.0)」の結果は、以下のようになりました。このテストツールは、このサイトのツールのページで公開しています。

WoW64 Test App (x64) on Windows 11 (x64)
WoW64 Test App (ARM64) on Windows 11 (ARM64)

表にまとめると、以下となります。

x86アプリx64アプリARM32アプリARM64アプリ
64ビット
Windows 11
on x64 CPU
0x014c (I386): 0x05 (UserEnabled | Wow64Container)
0x8664 (AMD64): 0x03 (UserEnabled | KernelEnabled)
64ビット
Windows 11
on ARM64 CPU
0x014c (I386): 0x05 (UserEnabled | Wow64Container)
0x01c4 (ARMNT): 0x05 (UserEnabled | Wow64Container)
0x8664 (AMD64): 0x01 (UserEnabled)
0xaa64 (ARM64): 0x03 (UserEnabled | KernelEnabled)
IsWow64GuestMachineSupported()の実行結果

このAPIが返す値は、実行中のアプリ プロセスのアーキテクチャには依存しない情報なので、同じWindowsであれば、すべてのアプリで同じ値となります。実際に、表の横方向の値は同じ値になっています。

OSにネイティブなアーキテクチャーの場合は、KernelEnabledフラグがセットされます。このフラグがセットされていないものは、互換性モードでの動作と判断してよいでしょう。また、Wow64Containerフラグがセットされているのは、ファイルシステム リダイレクターやレジストリ リダイレクターが有効になる32ビットアーキテクチャーのみとなります。

Windows 11上であれば、このAPIを使うと、APIを呼び出すアプリのアーキテクチャーによらず、すべてが正確に判断できることがわかります。


今回の投稿では、Windows 11で追加されたAPIであるGetMachineTypeAttributes()の挙動を確認した結果の説明でした。

“WoW64サブシステムとARM64 ♯3 GetMachineTypeAttributes()” への1件の返信

コメントを残す