2016-08-04

How to use Microsoft IME's private mode on not IE/Edige

Windows 10 Anniversary updateに含まれるMicrosoft IMEの新機能でInternet ExplorerやEdgeを利用している場合にプライベートブラウジングモードに連動してIMEもプライベートモードにできるという機能が入ってる。ブラウザベンダーで働くブラウザ開発者してはこの機能を是非つけたいと思ったのだけど、どうもAPIが公開されていないということなので調べた。Nyaruruさんも軽く調査してたけど、その続き編みたいなものです。

どうもこんな感じのコールスタックでプライベートモードを見に来る。

ChildEBP RetAddr
0591d22c 6fab49e1 imjptip!PrivateDetector::PrivateDetector
0591d270 6fad9a58 imjptip!CTipFnPrivateModeManager::CTipFnPrivateModeManager+0x7e
0591d2a8 6fac9a16 imjptip!CTipFnPrivateModeManager::CreateInstance+0x35
0591d34c 6f63d614 imjptip!CTipProfileJPN::InitializeContextEditor+0x2556
0591d38c 6f62bb95 imetip!CTipContextEditor::Initialize+0x74
0591d3c4 6f62b55a imetip!CTipContextEditorMgr::InitContextEditor+0x53
0591d420 6f661404 imetip!CTipContextEditorMgr::OnProfileMgrEvent+0x44
0591d45c 6f6230ac imetip!CTipContextEditorMgr::_OnProfileMgrEvent+0x44
0591d478 6f623b54 imetip!Tiputil::CTipProfileMgrEventSink::OnProfileActivated+0x5c
0591d4c4 6f623c3d imetip!CTipProfileMgr::CallOnProfileActivated+0xc4
0591d4e0 6f6239b4 imetip!CTipProfileMgr::ActivateProfileProc+0x80
0591d554 6f6591e6 imetip!CTipProfileMgr::OnActivated+0x124
0591d568 6f61c795 imetip!Tiputil::TextInputProcessorActivateSink::OnActivated+0x61
0591d5a8 6f61ca02 imetip!CTextInputProcessor::CallOnActivated+0x45
0591d5d4 6f61d43f imetip!CTextInputProcessor::ActivateProc+0x6c
0591d608 769048f9 imetip!CTextInputProcessor::ActivateEx+0x4f
0591d63c 7691db53 MSCTF!CTip::Activate+0x63

このPrivateDetectorというクラスでInternet ExplorerとEdge用に専用コードが存在してる。FirefoxはUWPではないので、Internet Explorerを見ると、Internet Explorerの時だけ (判定にIERTUTIL.DLLのIEConfiguration_GetDWORDを利用)、IERTUTIL.DLLに存在する特別な関数 (LCIEIsCurrentProcessInPrivate) を呼び出して、それの値でプライベートブラウジングモードかどうかを判別してるぽい。

まぁIERTUTIL.DLLの関数ってエクスポート名前を公開してないのでMAKEINTRESOURCEか何かで無理やり関数エントリを取ってきて、これをフックしてしまえば他のブラウザでもプライベートモードが使えるんじゃないかと。

ただ、IMEベンダが同じことしたくてもできないってのが本当にダメなAPI設計だなと思う。

追記 (8/6)

なお実際にテスト実装してみたところ、LCIEIsCurrentProcessInPrivateのフックだけでプライベートモードとかの切り替えできた。