なぜWindowsのキーボードレイアウトを変更するとi8042prtのレジストリが変わるのか
はじめに
こんにちは。SHIFT インフラサービスグループの水谷です。
AWSなどのパブリッククラウドで作成したWindows ServerのVMは、言語設定が英語であることが多いのですよね。日本語化されたOSイメージが揃っていて、それが選択できれば良いのですが、現状はそうでもありません。仕方なく毎回英語OSの設定を変えて、表示言語を日本語にし、ロケールやタイムゾーンを日本に変更し、キーボードレイアウトも日本語キーボードに変更して使っている方も多いかと思います。
これらの変更は、GUI上の設定画面からポチポチとクリックして行うのが一般的かと思いますが、結構手間がかかります。台数が多いととても時間がかかるので、Ansibleなどのツールで自動化してしまうのが良いですね。一度自動化してしまえば、何度でも間違えずに日本語化できるので便利です。
今回はその中の1つ、キーボードレイアウトの変更についてフォーカスします。
キーボードのレイアウト変更レジストリ
Ansible等でWindowsの設定を自動化する場合は、(RPAなどとは異なり)GUI操作を自動化するのではなく、それに対応するレジストリの変更を行うことになります。
キーボードレイアウトの変更もそのパターンで行う例の1つで、実際以下のレジストリを変更します。
レジストリパス:HKLM:\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
レジストリ名: LayerDriver JPN
値: 'kbd106.dll'
タイプ: string
レジストリパス:HKLM:\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
レジストリ名: OverrideKeyboardSubtype
値: 2
タイプ: dword
Ansibleのタスクとして書くと以下のような感じになりますね。
- name: Set keyboard layout to JP106/109
ansible.windows.win_regedit:
path: HKLM:\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
name: "{{ item.regname }}"
data: "{{ item.data }}"
type: "{{ item.type }}"
loop:
- regname: 'LayerDriver JPN'
data: 'kbd106.dll'
type: string
- regname: OverrideKeyboardSubtype
data: 2
type: dword
このレジストリパスを見て、ふと「i8042prt」って何だろう? と思われた方もいらっしゃるのではないかなと思いますし、あるいは「え?なんでi8042が今更出てくるの?」と思われるかともいるのではないかと思います。
この「i8042」が何なのかといえば、いわゆるPS/2ポートの信号を処理するチップのことですね(PlayStation 2ではありませんw)。今はUSB接続のキーボードが主流ですが、以前はPS/2という名のポートにマウスやキーボードを接続していました。1990年台後半から2000年台前半に販売されたPCのほぼ100%がこのPS/2ポートを搭載してましたが、いわゆるレガシーデバイス排除の流れで、2000年台後半から減少の一途をたどり、今ではほとんど見かけなくなりました。
ではなぜこの古いi8042が今でもWindowsのレジストリに存在して、その内容を変更する必要があるのでしょうか?
キーボードレイアウトの自動判断はできない!?
このレジストリが存在するのは、もちろん互換性の確保のため、ということもあるのですが、それとは別の意外な理由があります。
「106/109キーボード」とも呼ばれる日本語キーボードは、歴史的には「101キーボード」と呼ばれるIBM 101 Enhanced Keyboardをベースに、JISキーボードなどの要素を加えたものです。1991年にOADG(PCオープン・アーキテクチャー推進協議会)に採用されたことで実質的な標準キーボードとなりました。
101や106以外にも、ヨーロッパ方面では102キーボード(106キーボードはこちらをベースにしているという話もあります)や韓国では103キーボードが使われていたりといろいろなキーボードがあるのですが、大きな問題の1つとして、(一部のキーボードを除いて)OSからはキーボードのレイアウトが判別できないことが挙げられます。
つまり、異なるレイアウトのキーボードを接続した際に、OSからはキーボードのレイアウトが判別できないので、ユーザーがOSの設定を変更してそのキーボードの種類をOSに教えてあげる必要があるのです。
もちろん日本語Windowsなら、OSのデフォルト設定が106/109レイアウトとなっているため、106キーボードをつなげば期待通りに動作します。しかし、日本語Windowsに101キーボードを接続したり、あるいはデフォルトが101/104レイアウトとなっている英語版Windowsに日本語キーボードを接続しても、期待通りには動作しません。
この問題に対してOSは何もしないわけではなく、USBキーボードのディスクリプターからキーボードの種類を判別しようと試みます。マウスやキーボードの規格を定めるUSB Orgの「HID Usage Tables for Universal Serial Bus (USB)」にキーボード種別を判別するためのコードが存在するのですが、これは後から追加された項目ということもあり、かつ実装は必須ではないため、一部のUSBキーボードを除いてほとんどのキーボードがこれに対応していないのが現状です。その結果、残念ながら多くの場合、この自動判別は失敗してしまいます。
※上記HID Usage Tableへの追加は米Microsoft社から提案されたものであるため、Microsoft製キーボードはこれに対応しているものが多い。
Windowsの場合、HIDディスクリプタからレイアウト情報が得られなかった場合、次に何をするかというと……、そう、PS/2キーボードの設定が記述されているレジストリのi8042prtを見に行くのですね(ほんとはもう少し複雑なようですが)。
ということで、レジストリのi8042prtにキーボードのレイアウトが日本語であることを記述しておけば、USBキーボードでレイアウト情報があるキーボードが接続されればそのレイアウトに、そうでなければi8042prtで指定したレイアウトが採用される、ということになります。
参照: HID Usage Tables FOR Universal Serial Bus (USB) Version 1.21 https://usb.org/sites/default/files/hut1_21.pdf 15 Consumer Page (0x0C)
まとめ
Windowsのキーボードレイアウト決定は基本的に以下のように行われます。
HID Usage Pageの"Consumer Page"にある"Descriptive Controls"が設定されていれば、この値を採用する。
設定されていなかった場合は、PS/2キーボードの設定が記述されているレジストリのi8042prtを見に行く。
Ansible等でキーボードレイアウトを変更する場合は、レジストリのi8042prtの値を変更することで行えばOK!
自動化、効率化の参考になれば幸いです。
IaC支援サービスのご紹介
SHIFTではTerraformやCDKを使ったクラウドインフラ構築の自動化や、Ansibleを使ったサーバOSの設定自動化や構成管理のご支援も行っております。ご依頼・ご相談は下記リンクからお願いします。
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/
PHOTO:UnsplashのAryan Dhiman