2018年5月27日

WindowsのIMEにおけるセキュリティ


TSF (Text Services Framework) で実装された IME は COM (Component Object Model) の DLL として実装されるので、その IME を有効にするとアプリケーションのプロセスにロードされて動作します。つまり、アプリケーションと同じプロセス空間に存在していることになります。

このため、サンドボックスによるセキュリティ上の制約は、アプリケーションに対してだけでなく IME に対しても同様に適用されます。

IME がファイル、レジストリ、プロセス間通信などを用いて設定内容や辞書を読み書きする際には、こうしたサンドボックスの外側に存在するオブジェクトに対して、許可が得られるような適切なセキュリティの設定がなされる必要があります。

一口にサンドボックスといっても様々な種類がありますが、基本的には Windows が持つセキュリティ機構を使用したものとなっています。@ITの記事が非常に参考になりますのでリンクを貼っておきます。

アクセス制御リストACL - @IT
http://www.atmarkit.co.jp/ait/articles/1407/17/news130.html

Windowsのアクセス制御リストACLとは? - @IT
http://www.atmarkit.co.jp/ait/articles/0601/21/news011.html

オブジェクトを識別するSIDとは? - @IT
http://www.atmarkit.co.jp/ait/articles/0306/28/news004.html

(追記)
Windowsのセキュリティ設定を記述するSDDL文字列とは? - @IT
http://www.atmarkit.co.jp/ait/articles/0603/25/news016.html

Windows における主要なサンドボックス毎に、制限されたプロセス内の IME がアクセスできるようにする方法について述べます。


Mandatory Integrity Control


Windows Vista で導入されたアクセス制御です。必須整合性コントロールと訳されます。

Mandatory Integrity Control
https://msdn.microsoft.com/en-us/library/windows/desktop/bb648648(v=vs.85).aspx

いくつかのレベルが用意され、下位のレベルから上位のレベルへのアクセスを制限する機能を持ちます。また、制限の内容としては、書き込み拒否 / 読み込み拒否 / 実行拒否があります。

以下のようなソフトウェアで利用されています。
  • Internet Exploere 7 以降 (詳細設定で保護モードを有効にしたとき)
  • Adobe Reader X 以降
  • Firefox 4.0 以降で動作する Flash Player 11.3 以降

これらのソフトウェアでは、整合性レベル「低」のプロセスとして動作しており、書き込み拒否の制限となっています。つまり、整合性レベル「低」より高いレベルのオブジェクトには書き込みできない、ということになります。読み込みのみであれば、整合性レベルの設定は不要です。SDDL としては次のような記述で SACL として表現されます。

S:(ML;;NW;;;LW)
また、sddl.h では次のように定義されています。

//
// SDDL Ace types
//
#define SDDL_MANDATORY_LABEL                TEXT("ML")  // Integrity label

//
// SDDL Rights
//
#define SDDL_NO_WRITE_UP                    TEXT("NW")
#define SDDL_NO_READ_UP                     TEXT("NR")
#define SDDL_NO_EXECUTE_UP                  TEXT("NX")

//
// Integrity Labels
//
#define SDDL_ML_LOW                         TEXT("LW")      // Low mandatory level
#define SDDL_ML_MEDIUM                      TEXT("ME")      // Medium mandatory level
#define SDDL_ML_MEDIUM_PLUS                 TEXT("MP")      // Medium Plus mandatory level
#define SDDL_ML_HIGH                        TEXT("HI")      // High mandatory level
#define SDDL_ML_SYSTEM                      TEXT("SI")      // System mandatory level


AppContainer


Windows 8 で導入されたアクセス制御です。

AppContainer Isolation
https://msdn.microsoft.com/en-us/library/windows/desktop/mt595898(v=vs.85).aspx

以下のようなソフトウェアで使用されています。
  • Windows ストアアプリ
  • ユニバーサル Windows プラットフォームアプリ (UWP アプリ)
  • Internet Explorer 10 以降 (詳細設定で「拡張保護モードを有効にする」をチェックしたとき)
  • Adobe Acrobat Reader DC 15.023.20053 以降 (環境設定で「AppContainer (ベータ版) で実行」をチェックしたとき)

sddl.h で次のように定義されている SID を SDDL に記述することになります。

//
// SDDL User aliases
//
#define SDDL_ALL_APP_PACKAGES               TEXT("AC")      // All applications running in an app package 


Restricted Token


アクセストークンを制限します。以下のようなソフトウェアで使用されています。
  • Adobe Reader X 以降
  • Firefox 4.0 以降で動作する Flash Player 11.3 以降

これらのソフトウェアでは、Restricted Token による権限チェックと、前述の整合性レベル、およびジョブオブジェクトから成るサンドボックスとなっています。Acrobat Reader DC では、ベータ版の機能としてですが AppContainer も使用可能となり、何でもありか?という状況になっています。

詳しく知りたい方は、Microsoft および Adobe のサイトを参照してください。

Restricted Token - Windows Dev Center
https://msdn.microsoft.com/en-us/library/windows/desktop/aa379316(v=vs.85).aspx

Job Objects - Windows Dev Center
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684161(v=vs.85).aspx

Inside Adobe Reader Protected Mode – Part 1 – Design
http://blogs.adobe.com/security/2010/10/inside-adobe-reader-protected-mode-part-1-design.html

Inside Adobe Reader Protected Mode – Part 2 – The Sandbox Process
http://blogs.adobe.com/security/2010/10/inside-adobe-reader-protected-mode-part-2-the-sandbox-process.html

Inside Adobe Reader Protected Mode – Part 3 – Broker Process, Policies, and Inter-Process Communication
http://blogs.adobe.com/security/2010/11/inside-adobe-reader-protected-mode-part-3-broker-process-policies-and-inter-process-communication.html

Inside Adobe Reader Protected Mode – Part 4 – The Challenge of Sandboxing
http://blogs.adobe.com/security/2010/11/inside-adobe-reader-protected-mode-part-4-the-challenge-of-sandboxing.html

Flash Player Sandboxing is Coming to Firefox
http://blogs.adobe.com/security/2012/02/flash-player-sandboxing-is-coming-to-firefox.html

15.023.20053 Planned update, January 10, 2017 - Release Notes for Acrobat DC Products
https://www.adobe.com/devnet-docs/acrobatetk/tools/ReleaseNotesDC/continuous/dccontinuousjanuary2017.html

sddl.h で次のように定義されている SID と、Restricted Token によって無効化させたくない SID を SDDL に記述することになります。

#define SDDL_RESTRICTED_CODE                TEXT("RC")      // Restricted code

ジョブオブジェクトについては、現状では前述のソフトウェアにおいてはファイルの読み書きの制約を受けていないので特にすることはありません。


まとめ

では、サンドボックス外の名前付きパイプにアクセス許可を付加する方法について見てみましょう。ビルドする際は、advapi32.lib をリンクしてください。

#include <windows.h>
#include <sddl.h>
#include <aclapi.h>

int main() {
  PSECURITY_DESCRIPTOR pSecurityDescriptor;

  ConvertStringSecurityDescriptorToSecurityDescriptorW(
    L"D:(A;;GA;;;AC)(A;;GA;;;RC)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;BU)S:(ML;;NW;;;LW)",
    SDDL_REVISION_1, &pSecurityDescriptor, NULL);

  SECURITY_ATTRIBUTES sa = {sizeof(sa), pSecurityDescriptor, FALSE};

  HANDLE hPipe = CreateNamedPipeW(
    L"\\\\.\\pipe\\SamplePipe",
    PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
    1, 256, 256, 0, &sa);

  LocalFree(pSecurityDescriptor);

  // ... Use named pipe.

  CloseHandle(hPipe);

  return 0;
}

次に、ファイルにアクセス許可を付与する方法を見てみましょう。

#include <windows.h>
#include <sddl.h>
#include <aclapi.h>

int main() {
  PSECURITY_DESCRIPTOR pSecurityDescriptor;

  ConvertStringSecurityDescriptorToSecurityDescriptorW(
    L"D:(A;;FA;;;AC)(A;;FA;;;RC)(A;;FA;;;SY)(A;;FA;;;BA)(A;;FA;;;BU)S:(ML;;NW;;;LW)",
    SDDL_REVISION_1, &pSecurityDescriptor, NULL);

  BOOL bDaclPresent = FALSE;
  PACL pDacl = NULL;
  BOOL bDaclDefaulted = FALSE;

  GetSecurityDescriptorDacl(
    pSecurityDescriptor, &bDaclPresent, &pDacl, &bDaclDefaulted);

  SetNamedSecurityInfoW(
    L"SampleFile.txt",
    SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
    NULL, NULL, pDacl, NULL);

  BOOL bSaclPresent = FALSE;
  PACL pSacl = NULL;
  BOOL bSaclDefaulted = FALSE;

  GetSecurityDescriptorSacl(
      pSecurityDescriptor,
      &bSaclPresent, &pSacl, &bSaclDefaulted);

  SetNamedSecurityInfoW(
    L"SampleFile.txt",
    SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION,
    NULL, NULL, NULL, pSacl);

  LocalFree(pSecurityDescriptor);

  return 0;
}

こうして出力されたファイルのプロパティは次の画像にようになります。Low Mandatory Level で、エントリに "ALL APPLICATION PACKAGES" と "RESTRICTED" があることが分かります。ちなみにこの画像のうち継承されたエントリは無効にしてしまってもOKです。




上記のサンプルコードではフルアクセス可能な設定になっていますが、実際は設計に応じて適切な ACL としてください。

2017年7月5日

PerlのEncode::JIS2KとPython

以前に自分が書いた記事が矢野さんに取り上げられて大変嬉しかったので、引き続きいろいろな処理系でのJIS X 0213の実装状況を調べていたのですが、Pythonと同様な変換を持った実装を見付けました。

Unicode の嫌なところを触ってしまった Python
http://yanok.net/2017/06/unicode-python.html

それがPerlのEncode::JIS2Kモジュールなのですが、

Encode::JIS2K - search.cpan.org
http://search.cpan.org/~dankogai/Encode-JIS2K/JIS2K.pm

こちらもPythonと同様にこのような変換を持っていました。

JIS X 0213Unicode
1面2区54点⦅U+2985LEFT WHITE PARENTHESIS
1面2区55点⦆U+2986RIGHT WHITE PARENTHESIS

もしかすると、PerlのEncode::JIS2Kモジュールを実装された方とPythonのcodecsモジュールを実装された方が、偶々どこかの同じ資料を参照していたのかもしれません。

ちなみに、その他の実装では大抵このような変換になっています。

JIS X 0213Unicode
1面2区54点⦅U+FF5FFULLWIDTH LEFT WHITE PARENTHESIS
1面2区55点⦆U+FF60FULLWIDTH RIGHT WHITE PARENTHESIS

Encode::JIS2Kは、
  • JIS X 0213の2004年改正に未対応
  • Unicodeへの変換結果が結合文字列となる文字に未対応
といった特徴があるので、特段の理由が無ければEncode::JISX0213およびEncode::ShiftJIS2003を使用したほうが良いかもしれません。

Encode::JISX0213 - search.cpan.org
http://search.cpan.org/~nezumi/Encode-JISX0213-0.04/lib/Encode/JISX0213.pm
Encode::ShiftJIS2004 - search.cpan.org
http://search.cpan.org/~nezumi/Encode-JISX0213-0.04/lib/Encode/ShiftJIS2004.pm

2017年2月25日

Certum Opensource Code Signing

2017年2月からコード署名の運用が少し厳しくなったようで、FIPS 140-2の暗号化モジュールが必須になるなどの変更がありました。

Leading Certificate Authorities and Microsoft Introduce New Standards to Protect Consumers Online - CA Security Council
https://casecurity.org/2016/12/08/leading-certificate-authorities-and-microsoft-introduce-new-standards-to-protect-consumers-online/

Certum が販売しているオープンソースプロジェクト向けコードサイニング証明書でも暗号化モジュールが必須になったので、購入に際して嵌った点などをまとめてみました。

Opensource Code Signing - Certum
https://www.certum.eu/certum/cert,offer_en_open_source_cs.xml
https://www.certum.eu/en/cert_offer_en_open_source_cs/


おおまかな手続きの流れ

  1. Certumのアカウントが無い場合はアカウントを作成します。
  2. PKI対応スマートカードを持っている場合は Activation Code、持っていない場合は Code Signing Suite を購入します。Code Signing Suite を購入した場合はSIMサイズのスマートカードと2GBのMicroSDカードを内蔵したUSBトークンがポーランドからDHLなどで郵送されます。(以降、Code Signing Suiteを購入したという前提で記述します。)
  3. USBトークンをPCに差し、後述の USBトークンのドライバと proCertum CardManager をインストールした状態で証明書を申請します。この時点では秘密鍵のみがスマートカードに保存されるようです。
  4. 証明書の承認に必要な書類のコピーとオープンソースプロジェクトのURLをメールで送ります。
  5. 承認されると公開鍵が発行されるので、proCertum CardManager からインポートします。

証明書の申請手続きの詳細は、次のリンクのPDFファイルを参照してください。

How to install the CS certificate - Certum
https://www.certum.eu/certum/cert,expertise_How_to_install_the_CS.xml
https://www.certum.eu/en/cert_expertise_How_to_install_the_CS/


USBトークン

Code Signing Suite を購入すると送られてくるUSBトークンは Advanced Card Systems の ACR101 でした。内蔵のMicroSDカードにもドライバが入っていますが、ACSのサイトのほうが若干新しいバージョンとなっているようです。

Card reader ACS ACR 101 SIMicro (CCID) - Certum
https://www.certum.eu/certum/cert,offer_Czytnik_kart_ACS_ACR_101_SIMicro_(CCID)_en.xml
https://www.certum.eu/en/cert_offer_czytnik_kart_acs_acr_101_simicro_ccid_en/

PC-Linked Readers with Mass Storage - ACR101 SIMicro | ACS
https://www.acs.com.hk/en/products/141/acr101i-simicro-ccid/

実機のスマートカードを使わずにTPMによる仮想スマートカードやHyper-Vの仮想TPMによる仮想スマートカードを使う手もあるようですが、ハードウェア要件が厳しいので実機があったほうが手軽かと思います。





proCertum CardManager

スマートカードに保存された証明書を管理するソフトです。内蔵のMicroSDカードにも入っていました。

Software and Libraries - Certum
https://www.certum.eu/certum/cert,offer_software_and_libraries.xml
https://www.certum.eu/en/cert_offer_software_and_libraries/

proCertum CardManager - Certum
https://www.certum.eu/certum/cert,offer_card_manager.xml
https://www.certum.eu/en/cert_offer_card_manager/
(英語版マニュアルのリンクが間違っているようです。正しくは https://www.certum.eu/upload_module/wysiwyg/certum/nowe_certum/instructions/proCertumCardManager-en_3_2_0_146.pdf https://www.certum.pl/pl/upload_module/wysiwyg/certum/nowe_certum/instructions/proCertumCardManager-en_3_2_0_146.pdf です。)

proCertum CardManager – FAQ - Certum
http://certum.eu/certum/cert,offer_proCertum_CardManager_support.xml
https://www.certum.eu/en/support/cert_offer_procertum_cardmanager_support/

オプションで「EV Code Signing」をチェックしてからOSを再起動すると signtool のダイジェストアルゴリズムとしてSHA-256が使用可能になります。

オプションで「EV Code Signing」をチェックしたとき proCertum CardManager に含まれる cryptoCardRegister.exe が起動されるようですが、version 3.2.0.154 では起動に失敗してしまうようなので proCertum CardManager がインストールされたディレクトリに予めパスを通しておくと良いみたいです。

Code Signing Suite に付属するスマードカード限定かもしれませんが、proCertum CardManager から見ると「Secure profile」と「Common profile」の2つのプロファイルが用意されています。Secure profile には Certum が予め PUK を設定しているようなので使用できません。コードサイニング証明書は Common profile のほうにインポートします。

Common profile を初期化する際に PUK と PIN を設定しますが、PIN は signtool を実行する度に入力する必要があるので短か目にしておいたほうが良いかもしれません。当然ですが PUK と PIN を忘れるとそのスマートカードは使用不可になってしまいます。


証明書の承認に必要な書類など

以下の書類などが必要です。
  1. identity document (ID card, passport, residency card, driver's license) - in Latin characters - of the person placing the order. The copy should depict the entire document (both sides)
  2. a utility bill (e.g. water, electric power, natural gas, etc.), bank statement, credit card statement, government‐issued tax document belonging to the Subscriber
  3. internet address of the project

1番はパスポートか国際運転免許証が使用可能だと思います。私はパスポートを使用しました。

2番は公共料金の明細の類なのですが、Certumの担当者の方と何度か遣り取りしたところ大体以下のような要件となっているようです。
  1. ラテン文字 (キリル文字も多分OKかも?)
  2. 住所の記載がある
  3. 手書きではなく印刷されている (おそらく担当者のサインのみ手書きOKだと思われる)
  4. 13ヶ月以内に発行されている
いろいろ探した結果、住所の記載があるゆうちょ銀行の英文残高証明書が使用できました。
小さな郵便局では所定のフォーマットの紙に手書きするところもあるようなので、大きな郵便局が良いかもしれません。20~30分くらいで発行してもらえます。

3番はオープンソースプロジェクトのURLです。おそらくソースが公開されていてOSIに認定されているライセンスであればOKだと思います。


signtool

SignTool.exe - MSDN
https://msdn.microsoft.com/en-us/library/8s9b9yaz(v=vs.110).aspx
https://docs.microsoft.com/en-us/dotnet/framework/tools/signtool-exe

PFXファイルが使えなくなったので /a, /i, /n, /sha1 などのオプションでPCにインポートされた証明書を指定します。



以上です。

2016年12月4日

主な実装における EUC-JIS-2004, Shift_JIS-2004 から Unicode への変換結果の違い

まとめました。


nkfとiconvの差異
https://nathancorvussolis.blogspot.jp/2015/05/difference-between-nkf-and-iconv.html

Pythonとiconvの差異
https://nathancorvussolis.blogspot.jp/2016/11/difference-between-python-and-iconv.html

JavaのShift_JIS-2004については下記のブログを引用させていただきました。
iconv、Java、PythonのJISX0213 - yuan-jiu blog
http://yuan-jiu.asablo.jp/blog/2013/05/11/6807043


バージョン

libiconv 1.14
nkf 2.1.4
Python 3.4.5
Java 1.7.0_21


EUC-JIS-2004


EUC-JIS-2004iconvnkfPython
0xA1B1  ̄U+FFE3 ‾U+203E  ̄U+FFE3
0xA1EF ¥U+FFE5 ¥U+00A5¥U+FFE5
0xA1BD —U+2014 —U+2014 ―U+2015
0xA2D6 ⦅U+FF5F ⦅U+FF5F⦅U+2985
0xA2D7 ⦆U+FF60 ⦆U+FF60 ⦆U+2986

http://x0213.org/codetable/euc-jis-2004-std.txt より抜粋
0xA1B1  U+203E  # OVERLINE  Windows: U+FFE3
0xA1BD  U+2014  # EM DASH  Windows: U+2015
0xA1EF  U+00A5  # YEN SIGN  Windows: U+FFE5
0xA2D6  U+FF5F  # FULLWIDTH LEFT WHITE PARENTHESIS  [2000]  [Unicode3.2]
0xA2D7  U+FF60  # FULLWIDTH RIGHT WHITE PARENTHESIS  [2000]  [Unicode3.2]

EUC-JIS-2004 については FULLWIDTH かどうかの違いくらいしかないので、それほど問題はなさそうです。
Python の 0xA2D6 → U+2985 と 0xA2D7 → U+2986 はちょっとどうなの?と思ってしまいますが。


Shift_JIS-2004


Shift_JIS-2004iconvnkfPythonJava
0x5C ¥U+00A5 \U+005C ¥U+00A5 \U+005C
0x7E ‾U+203E ~U+007E ‾U+203E ~U+007E
0x8150  ̄U+FFE3 ‾U+203E  ̄U+FFE3  ̄U+FFE3
0x815C —U+2014 —U+2014 ―U+2015 —U+2014
0x815F \U+FF3C \U+FF3C \U+005C \U+FF3C
0x818F ¥U+FFE5 ¥U+00A5 ¥U+FFE5 ¥U+FFE5
0x81B0 ~U+FF5E ~U+FF5E ~U+007E ~U+FF5E
0x81D4 ⦅U+FF5F ⦅U+FF5F ⦅U+2985 ⦅U+FF5F
0x81D5 ⦆U+FF60 ⦆U+FF60 ⦆U+2986 ⦆U+FF60

http://x0213.org/codetable/sjis-0213-2004-std.txt より抜粋
0x5C    U+00A5  # YEN SIGN
0x7E    U+203E  # OVERLINE
0x8150  U+FFE3  # FULLWIDTH MACRON
0x815C  U+2014  # EM DASH  Windows: U+2015
0x815F  U+005C  # REVERSE SOLIDUS  Fullwidth: U+FF3C
0x818F  U+FFE5  # FULLWIDTH YEN SIGN
0x81B0  U+007E  # TILDE  [2000]  Fullwidth: U+FF5E
0x81D4  U+FF5F  # FULLWIDTH LEFT WHITE PARENTHESIS  [2000]  [Unicode3.2]
0x81D5  U+FF60  # FULLWIDTH RIGHT WHITE PARENTHESIS  [2000]  [Unicode3.2]

こうして見てみると、Python の 0x815F → U+005C がはまりポイントになりそうですね。

2016年11月30日

Pythonとiconvの差異

PythonとiconvとでJIS系文字コードとUnicodeとの変換にどれくらい違いがあるのか調べてみました。

EUC-JIS-2004とShift_JIS-2004のファイルをそれぞれUTF-8に変換して、その結果を比較します。

Python
https://www.python.org/
 
libiconv
http://www.gnu.org/software/libiconv/

変換元となるファイルについては、プロジェクトX0213の「JIS X 0213とUnicodeの対応表」から、文字付き版のファイルを使用しました。

JIS X 0213とUnicodeの対応表
http://x0213.org/codetable/

EUC-JIS-2004とUnicodeの対応表 文字付き版
http://x0213.org/codetable/euc-jis-2004-with-char.txt
Shift_JIS-2004とUnicodeの対応表  文字付き版
http://x0213.org/codetable/sjis-0213-2004-with-char.txt

今回使用した環境、バージョンは以下の通りです。

  • cygwin 2.6.0 (0.304/5/3)
  • Python 3.4.5
  • libiconv 1.14

追記: Pythonでの変換に使用した pconv.py は以下のようなコードです。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#

import codecs
import sys

if __name__ == "__main__":
    if (len(sys.argv) != 5):
        print('usage: python pconv.py <enc_from> <inputfile> <enc_to> <outputfile>')
        sys.exit(1)

    for arg in sys.argv:
        print(arg)

    output = codecs.open(sys.argv[4], 'w', sys.argv[3])

    for line in codecs.open(sys.argv[2], 'r', sys.argv[1]):
        try:
            output.write(line)
        except UnicodeEncodeError:
            print('UnicodeEncodeError')
            break

    output.close()

EUC-JIS-2004

$ python3 pconv.py euc_jis_2004 euc-jis-2004-with-char.txt utf_8 euc-jis-2004-python.txt
$ iconv -f EUC-JIS-2004 -t UTF-8 euc-jis-2004-with-char.txt > euc-jis-2004-iconv.txt
$ diff euc-jis-2004-python.txt euc-jis-2004-iconv.txt > diff-euc-jis-2004.txt
追記: diff-euc-jis-2004.txt
216c216
< ―    0xA1BD    U+2014    # EM DASH    Windows: U+2015
---
> —    0xA1BD    U+2014    # EM DASH    Windows: U+2015
335,336c335,336
< ⦅    0xA2D6    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
< ⦆    0xA2D7    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]
---
> ⦅    0xA2D6    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
> ⦆    0xA2D7    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]

EUC-JIS-2004の変換では、3つの文字で異なる変換結果が得られました。

  • 0xA1BD EM DASH
    • Python U+2015
    • iconv U+2014
  • 0xA2D6 FULLWIDTH LEFT WHITE PARENTHESIS
    • Python U+2985
    • iconv U+FF5F
  • 0xA2D7 FULLWIDTH RIGHT WHITE PARENTHESIS
    • Python U+2986
    • iconv U+FF60

Shift_JIS-2004

$ python3 pconv.py shift_jis_2004 sjis-0213-2004-with-char.txt utf_8 sjis-0213-2004-python.txt
$ iconv -f Shift_JIS-2004 -t UTF-8  sjis-0213-2004-with-char.txt > sjis-0213-2004-iconv.txt
$ diff sjis-0213-2004-python.txt sjis-0213-2004-iconv.txt > diff-sjis-0213-2004.txt
追記: diff-sjis-0213-2004.txt
310c310
< ―    0x815C    U+2014    # EM DASH    Windows: U+2015
---
> —    0x815C    U+2014    # EM DASH    Windows: U+2015
313c313
< \    0x815F    U+005C    # REVERSE SOLIDUS    Fullwidth: U+FF3C
---
> \    0x815F    U+005C    # REVERSE SOLIDUS    Fullwidth: U+FF3C
393c393
< ~    0x81B0    U+007E    # TILDE    [2000]    Fullwidth: U+FF5E
---
> ~    0x81B0    U+007E    # TILDE    [2000]    Fullwidth: U+FF5E
429,430c429,430
< ⦅    0x81D4    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
< ⦆    0x81D5    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]
---
> ⦅    0x81D4    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
> ⦆    0x81D5    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]

Shift_JIS-2004の変換では、5つの文字で異なる変換結果が得られました。

  • 0x815C EM DASH
    • Python U+2015
    • iconv U+2014
  • 0x815F REVERSE SOLIDUS
    • Python U+005C
    • iconv U+FF3C
  • 0x81B0 TILDE
    • Python U+007E
    • iconv U+FF5E
  • 0x81D4 FULLWIDTH LEFT WHITE PARENTHESIS
    • Python U+2985
    • iconv U+FF5F
  • 0x81D5 FULLWIDTH RIGHT WHITE PARENTHESIS
    • Python U+2986
    • iconv U+FF60

まとめ


FULLWIDTH LEFT WHITE PARENTHESIS と FULLWIDTH RIGHT WHITE PARENTHESIS が FULLWIDTH でなくなってしまうのが、Pythonのいまいちな点でしょうか。

今回の使用・作成したファイルをGitHubに上げていますので、興味のある方はご覧ください。
https://github.com/nathancorvussolis/difference-between-python-and-iconv

さらに追記:
すでにShift_JIS-2004の変換をまとめている方がおられたのでリンクしておきます。
iconv、Java、PythonのJISX0213 - yuan-jiu blog
http://yuan-jiu.asablo.jp/blog/2013/05/11/6807043

2016年10月15日

Universal CRT in Wix Bootstrapper (3)

Universal CRT を含めた WiX の Bootstrapper の wxs ファイルのサンプルです。

今回は、DownloadUrl 属性を使ってみました。インストール時に自動的にダウンロードされます。

Universal CRT は VC++再配布パッケージに含まれているので、そのサンプルも貼っておきます。

注意点ですが、MsuPackage / ExePackage タグの Name 属性と同じ名前のファイルが ブートストラップの exe と同じディレクトリに存在していると、DownloadUrl 属性の URL からダウンロードされずにローカルのファイルが使われてしまいます。

こんな感じでビルドしてください。

> "%WIX%bin\candle.exe" xxx.wxs -nologo -out "xxx.wixobj" -ext WixBalExtension -ext WixUtilExtension
> "%WIX%bin\light.exe" "xxx.wixobj" -nologo -out "xxx.exe" -ext WixBalExtension -ext WixUtilExtension

【参考】

ExePackage Element
http://wixtoolset.org/documentation/manual/v3/xsd/wix/exepackage.html

MsuPackage Element
http://wixtoolset.org/documentation/manual/v3/xsd/wix/msupackage.html

RemotePayload Element
http://wixtoolset.org/documentation/manual/v3/xsd/wix/remotepayload.html

Download Microsoft Visual C++ 2015 Redistributable Update 3 from Official Microsoft Download Center
https://www.microsoft.com/en-us/download/details.aspx?id=53840

Update for Universal C Runtime in Windows
https://support.microsoft.com/en-us/kb/2999226






2016年7月9日

オンラインストレージとCorvusSKK


CorvusSKKの設定ファイルや個人辞書は、"%AppData%\CorvusSKK" ディレクトリに保存されます。

次の記事を参考に、自動的にオンラインストレージへバックアップするためのコマンドプロンプトでの設定方法をまとめてみました。

Windows の CorvusSKK で Azik + Google 日本語入力の変換を利用。設定ファイルはクラウドへ保存。

Tech TIPS:Windowsのシンボリックリンクとジャンクションとハードリンクの違い


私はOneDriveで確認しましたが、Google Drive、Dropboxなどでも同様の設定で使えると思います。

ここでは、オンラインストレージソフトが管理するディレクトリを仮に "C:\OnlineStorage\CorvusSKK" としています。適宜環境に合わせて変更してください。

  1. 辞書管理プロセスを終了します。
  2. > taskkill /im imcrvmgr.exe
  3. %AppData%\CorvusSKK ディレクトリをオンラインストレージソフトが管理するディレクトリにコピーします。
  4. > xcopy /ei "%AppData%\CorvusSKK" "C:\OnlineStorage\CorvusSKK"
  5. %AppData%\CorvusSKK ディレクトリを削除します。
  6. > rd /s /q "%AppData%\CorvusSKK"
  7. オンラインストレージソフトが管理するディレクトリへのシンボリックリンク %AppData%\CorvusSKK を作成します。(要管理者権限)
  8. > mklink /d "%AppData%\CorvusSKK" "C:\OnlineStorage\CorvusSKK"
    追記 : ジャンクションでも良いようです。こちらであれば管理者権限は不要です。
    > mklink /j "%AppData%\CorvusSKK" "C:\OnlineStorage\CorvusSKK"
  9. 辞書管理プロセスを再開します。
  10. > "%SystemRoot%\System32\IME\IMCRVSKK\imcrvmgr.exe"

ちなみに、複数のPCやユーザーで、ローカルおよびリモートの同じディレクトリを使ってしまうとお互いに上書きしあってしまいますので注意してください。

オンラインストレージサービスの規約や使い方をよく確認してご利用ください。

2016年4月20日

Disable Light Bulb

Visual Studio 2015 Update 2 の C++ のプロジェクトですが、緑の下線と共に電球が表示されて、関数定義が無いとのメッセージが表示されることがあります。




これ、Visual Studio 2015 の新機能だそうで、light bulb (電球?)と呼ぶそうです。

Perform quick actions with light bulbs
https://msdn.microsoft.com/en-us/library/dn872466.aspx

しかし、まだあまり賢くないようなので無効にしました。

Option → Text Editor → C/C++ → Advanced → Refactoring → Disable Create Declaration/Definition Light Bulbs を、False から True に変更します。




 警告が消えました。


2016年4月11日

Universal CRT in Wix Bootstrapper (2)

前回、Universal CRTを含めたWiXのBootstrapperのwxsファイルを作ってみましたが、インストール条件が長ったらしくなってしまいました。
そこで、ucrtbase.dllファイルのチェックをSystem32ディレクトリに限定し、MsuPackage要素にDetectCondition属性を使ってみました。
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
  xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
  xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

  <Bundle Name="Example Product" Version="1.2.3.4" Manufacturer="John Doe"
    Copyright="© 2016 John Doe" AboutUrl="https://example.com/"
    UpgradeCode="01234567-89AB-CDEF-0123-456789ABCDEF" Condition="VersionNT &gt;= v5.1">

    <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
      <bal:WixStandardBootstrapperApplication
        LicenseFile="license.rtf" ShowVersion="yes" SuppressOptionsUI="yes" />
    </BootstrapperApplicationRef>

    <!-- v6.0 Service Pack 2 -->
    <bal:Condition Message="This application requires Service Pack 2 for Windows Vista / Server 2008.">
      (VersionNT &lt;&gt; v6.0) OR (VersionNT = v6.0 AND ServicePackLevel &gt;= 2)
    </bal:Condition>

    <!-- v6.1 Service Pack 1 -->
    <bal:Condition Message="This application requires Service Pack 1 for Windows 7 / Server 2008 R2.">
      (VersionNT &lt;&gt; v6.1) OR (VersionNT = v6.1 AND ServicePackLevel &gt;= 1)
    </bal:Condition>

    <!-- v6.3 KB2919355 -->
    <util:FileSearch Id="HAL.DLL" Path="[WindowsFolder]System32\hal.dll"
      Result="version" Variable="NT603HALVER" Condition="VersionNT = v6.3" />
    <bal:Condition Message="This application requires S14 Update (KB2919355) for Windows 8.1 / Server 2012 R2.">
      (VersionNT &lt;&gt; v6.3) OR (VersionNT = v6.3 AND NT603HALVER &gt; v6.3.9600.16500)
    </bal:Condition>

    <!-- ucrtbase.dll version -->
    <util:FileSearch Id="UCRTBASE.DLL" Path="[WindowsFolder]System32\ucrtbase.dll"
      Result="version" Variable="UCRTBASEVER" />
    <!-- universal crt version -->
    <Variable Name="UCRTVER" Type="version" Value="10.0.10586.0" />

    <Chain>

      <!-- Windows Vista / Windows Server 2008 (x86) -->
      <MsuPackage Name="Windows6.0-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows6.0-KB3118401-x86.msu" InstallCondition="VersionNT = v6.0 AND NOT VersionNT64"
        DetectCondition="VersionNT = v6.0 AND NOT VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows Vista / Windows Server 2008 (x64) -->
      <MsuPackage Name="Windows6.0-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows6.0-KB3118401-x64.msu" InstallCondition="VersionNT = v6.0 AND VersionNT64"
        DetectCondition="VersionNT = v6.0 AND VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 7 (x86) -->
      <MsuPackage Name="Windows6.1-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows6.1-KB3118401-x86.msu" InstallCondition="VersionNT = v6.1 AND NOT VersionNT64"
        DetectCondition="VersionNT = v6.1 AND NOT VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 7 / Windows Server 2008 R2 (x64) -->
      <MsuPackage Name="Windows6.1-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows6.1-KB3118401-x64.msu" InstallCondition="VersionNT = v6.1 AND VersionNT64"
        DetectCondition="VersionNT = v6.1 AND VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 8 (x86) -->
      <MsuPackage Name="Windows8-RT-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows8-RT-KB3118401-x86.msu" InstallCondition="VersionNT = v6.2 AND NOT VersionNT64"
        DetectCondition="VersionNT = v6.2 AND NOT VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 8 / Windows Server 2012 (x64) -->
      <MsuPackage Name="Windows8-RT-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows8-RT-KB3118401-x64.msu" InstallCondition="VersionNT = v6.2 AND VersionNT64"
        DetectCondition="VersionNT = v6.2 AND VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 8.1 (x86) -->
      <MsuPackage Name="Windows8.1-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows8.1-KB3118401-x86.msu" InstallCondition="VersionNT = v6.3 AND NOT VersionNT64"
        DetectCondition="VersionNT = v6.3 AND NOT VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 8.1 / Windows Server 2012 R2 (x64) -->
      <MsuPackage Name="Windows8.1-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows8.1-KB3118401-x64.msu" InstallCondition="VersionNT = v6.3 AND VersionNT64"
        DetectCondition="VersionNT = v6.3 AND VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- x64 modules -->
      <MsiPackage Id="X64" DisplayName="x64 modules" ForcePerMachine="yes" Compressed="yes"
        SourceFile="x64.msi" InstallCondition="VersionNT64" />

      <!-- x86 modules -->
      <MsiPackage Id="X86" DisplayName="x86 modules" ForcePerMachine="yes" Compressed="yes"
        SourceFile="x86.msi" After="X64" />

    </Chain>

  </Bundle>

</Wix>

ちょっとすっきり。

2016年3月23日

Universal CRT in WiX Bootstrapper


Visual Studio 2013 の Visual C++ の各種ライブラリを配布するには以下の方法があります。
  1. スタティックリンクでビルドする
  2. マージモジュールを使用する (Microsoft_VC120_CRT_x86.msm, Microsoft_VC120_CRT_x64.msm など)
  3. Visual C++ 再頒布可能パッケージをインストールする (vcredist_x86.exe, vcredist_x64.exe)
  4. インストーラーにDLLを同梱する (msvr120.dll, msvcp120.dll など)
Visual Studio 2015 の Visual C++ では Universal CRT が導入された影響で配布方法に若干の変更が入っています。

Introducing the Universal CRT | Visual C++ Team Blog
https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/

既に解説されている方々がおられるのでいくつかリンクしておきます。

VC++2015製のアプリを配る際のランタイムDLLの扱い | イグトランスの頭の中
http://dev.activebasic.com/egtra/2015/08/30/831/

Visual C++ 14 (VS2015RC)のランタイムをインストールする | espresso3389の日記
http://espresso3389.hatenablog.com/entry/2015/05/08/033946



上記1番のスタティックリンクと3番の再配布可能パッケージについては、まあ従来通りですね。

上記4番のDLL同梱では、"%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\redist" ディレクトリ内のファイル (vcruntime140.dll, msvcp140.dll など) に加えて、"%ProgramFiles(x86)%\Windows Kits\10\Redist" ディレクトリ内のファイル (ucrtbase.dll, api-ms-win-core-******.dll, api-ms-win-crt-******.dll) を同梱します。

上記2番のマージモジュールでは、従来のマージモジュールに加えて以下の Universal CRT の msu ファイルをインストーラーに含めてインストールするために、WiX であれば Bootstrapper にしてしまうのが良さそうです。再頒布可能パッケージと同じような方法ですね。

Windows 10 Universal C Runtime (KB2999226) (10.0.10240)
https://www.microsoft.com/ja-JP/download/details.aspx?id=48234
https://support.microsoft.com/en-us/kb/2999226

Windows 10 Universal C Runtime (KB3118401) (10.0.10586)
https://www.microsoft.com/ja-JP/download/details.aspx?id=50410
https://support.microsoft.com/en-us/kb/3118401

msu ファイルには現在2つのバージョンがあるのですが、Windows Update で降ってくるのはKB3118401、Visual Studio 2015 Update 1 の Visual C++ 再頒布可能パッケージに含まれているのはKB2999226になっています。どちらでも使えそうなのですが、とりあえず新しいKB3118401のほうを 使ってみます。

Visual Studio 2015 Update 1 の Visual C++ 再頒布可能パッケージ
https://www.microsoft.com/ja-jp/download/details.aspx?id=49984

XP 用の msu ファイルが見当たらないですが、XP 用の Universal CRT はマージモジュール (Microsoft_VC140_CRT_x86.msm, Microsoft_VC140_CRT_x64.msm) に含まれているようです。

で、msu ファイルを含めた Bootstrapper をさっくりと作ってみました。msu ファイルのシステム要件のチェックも入れつつ、インストール済みかどうかも一応チェックしています。msi ファイルについてはマージモジュールを含んだものとします。所々枠からはみ出してしまっていますがご容赦を。

追記 : 下記のwxsを書き直しました。
Universal CRT in Wix Bootstrapper (2)


TestUCRT.wxs

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
  xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
  xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

  <Bundle Name="program name" Version="1.0.0.0" Manufacturer="author name"
    UpgradeCode="12345678-9012-3456-7890-123456789012"
    Condition="VersionNT &gt;= v5.1" >

    <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
      <bal:WixStandardBootstrapperApplication
        LicenseFile="license.rtf" SuppressOptionsUI="yes" />
    </BootstrapperApplicationRef>

    <!-- v6.0 Service Pack 2 -->
    <bal:Condition Message="This application requires Service Pack 2 for Windows Vista / Server 2008.">
      (VersionNT &lt;&gt; v6.0) OR ((VersionNT = v6.0) AND (ServicePackLevel &gt;= 2))
    </bal:Condition>

    <!-- v6.1 Service Pack 1 -->
    <bal:Condition Message="This application requires Service Pack 1 for Windows 7 / Server 2008 R2.">
      (VersionNT &lt;&gt; v6.1) OR ((VersionNT = v6.1) AND (ServicePackLevel &gt;= 1))
    </bal:Condition>

    <!-- v6.3 KB2919355 -->
    <util:FileSearch Id="HAL.DLL" Path="[WindowsFolder]System32\hal.dll"
      Result="version" Variable="NT603HALVER" Condition="VersionNT = v6.3" />
    <bal:Condition Message="This application requires S14 Update (KB2919355) for Windows 8.1 / Server 2012 R2.">
      (VersionNT &lt;&gt; v6.3) OR ((VersionNT = v6.3) AND (NT603HALVER &gt; v6.3.9600.16500))
    </bal:Condition>

    <!-- installed ucrtbase.dll version -->
    <util:FileSearch Id="UCRTBASE.DLL_SYS" Path="[WindowsFolder]System32\ucrtbase.dll"
      Result="version" Variable="UCRTVERSYS" />
    <util:FileSearch Id="UCRTBASE.DLL_X86" Path="[WindowsFolder]SysWOW64\ucrtbase.dll"
      Result="version" Variable="UCRTVERX86" Condition="VersionNT64" />
    <!-- KB3118401 ucrtbase.dll version -->
    <Variable Name="UCRTVER" Type="version" Value="10.0.10586.9" />

    <Chain>

      <!-- Windows Vista / Windows Server 2008 (x86) -->
      <MsuPackage Name="Windows6.0-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows6.0-KB3118401-x86.msu"
        InstallCondition="(VersionNT = v6.0) AND (NOT VersionNT64) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER))" />

      <!-- Windows Vista / Windows Server 2008 (x64) -->
      <MsuPackage Name="Windows6.0-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows6.0-KB3118401-x64.msu"
        InstallCondition="(VersionNT64 = v6.0) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER) OR (NOT UCRTVERX86) OR (UCRTVERX86 &lt; UCRTVER))" />

      <!-- Windows 7 (x86) -->
      <MsuPackage Name="Windows6.1-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows6.1-KB3118401-x86.msu"
        InstallCondition="(VersionNT = v6.1) AND (NOT VersionNT64) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER))" />

      <!-- Windows 7 / Windows Server 2008 R2 (x64) -->
      <MsuPackage Name="Windows6.1-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows6.1-KB3118401-x64.msu"
        InstallCondition="(VersionNT64 = v6.1) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER) OR (NOT UCRTVERX86) OR (UCRTVERX86 &lt; UCRTVER))" />

      <!-- Windows 8 (x86) -->
      <MsuPackage Name="Windows8-RT-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows8-RT-KB3118401-x86.msu"
        InstallCondition="(VersionNT = v6.2) AND (NOT VersionNT64) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER))" />

      <!-- Windows 8 / Windows Server 2012 (x64) -->
      <MsuPackage Name="Windows8-RT-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows8-RT-KB3118401-x64.msu"
        InstallCondition="(VersionNT64 = v6.2) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER) OR (NOT UCRTVERX86) OR (UCRTVERX86 &lt; UCRTVER))" />

      <!-- Windows 8.1 (x86) -->
      <MsuPackage Name="Windows8.1-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows8.1-KB3118401-x86.msu"
        InstallCondition="(VersionNT = v6.3) AND (NOT VersionNT64) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER))" />

      <!-- Windows 8.1 / Windows Server 2012 R2 (x64) -->
      <MsuPackage Name="Windows8.1-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows8.1-KB3118401-x64.msu"
        InstallCondition="(VersionNT64 = v6.3) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER) OR (NOT UCRTVERX86) OR (UCRTVERX86 &lt; UCRTVER))" />

      <!-- x64 modules -->
      <MsiPackage Id="X64" DisplayName="x64 modules" ForcePerMachine="yes"
        Compressed="yes" SourceFile="x64.msi" InstallCondition="VersionNT64" />

      <!-- x86 modules -->
      <MsiPackage Id="X86" DisplayName="x86 modules" ForcePerMachine="yes"
        Compressed="yes" SourceFile="x86.msi" />

    </Chain>
  </Bundle>
</Wix>

で、ビルトはこんな感じで。
> candle.exe TestUCRT.wxs -out TestUCRT.wixobj -ext WixBalExtension -ext WixUtilExtension
> light.exe TestUCRT.wixobj -out TestUCRT.exe -ext WixBalExtension -ext WixUtilExtension

msu ファイルの替わりにExePackageタグを使って再配布可能パッケージを入れてもいいのですが、再配布パッケージに含まれる msu ファイルが VC_redist.x86.exe と VC_redist.x64.exe とで重複してしまうので、x86とx64両方のバイナリをインストールする必要がある場合はファイルサイズがその分大きくなってしまうのが難点ですね。
再配布パッケージの内容物は次のコマンドで展開することで確認できます。
> dark.exe VC_redist.x86.exe -x x86
> dark.exe VC_redist.x64.exe -x x64

2015年5月10日

nkfとiconvの差異

JIS系文字コードとUnicodeとの変換によく使われるnkfとiconvの変換にどれくらい違いがあるのか調べてみました。

EUC-JIS-2004とShift_JIS-2004のファイルをそれぞれUTF-8に変換して、その結果を比較します。

nkf Network Kanji Filter
http://sourceforge.jp/projects/nkf/

libiconv
http://www.gnu.org/software/libiconv/

変換元となるファイルについては、プロジェクトX0213の「JIS X 0213とUnicodeの対応表」から、文字付き版のファイルを使用しました。

JIS X 0213とUnicodeの対応表
http://x0213.org/codetable/

EUC-JIS-2004とUnicodeの対応表 文字付き版
http://x0213.org/codetable/euc-jis-2004-with-char.txt

Shift_JIS-2004とUnicodeの対応表  文字付き版
http://x0213.org/codetable/sjis-0213-2004-with-char.txt


今回使用した環境、バージョンは以下の通りです。

  • cygwin 2.0.2 (0.287/5/3)
  • gcc 4.9.2
  • nkf 2.1.3
  • libiconv 1.14

ちなみにJIS X 0213のサポートは、nkfでは2.1.3から、libiconvではおそらく1.8(?)からのようです。


    ビルド

    まず、それぞれをビルドします。

    nkf 2.1.3 をビルド。

    $ tar zxf nkf-2.1.3.tar.gz 
    $ cd nkf-2.1.3
    $ make

    libiconv 1.14 をビルド。EUC-JIS-2004とShift_JIS-2004を使えるようにするため、オプション --enable-extra-encodings を指定します。 

    $ tar zxf libiconv-1.14.tar.gz
    $ cd libiconv-1.14
    $ ./configure --enable-extra-encodings
    $ make

    EUC-JIS-2004

    次に、EUC-JIS-2004の変換をします。

    nkf
    JIS X 0201 片仮名を JIS X 0208 片仮名に変換しないように、オプション -x を指定します。

    $ nkf-2.1.3/nkf -x --ic=EUC-JIS-2004 --oc=UTF-8 euc-jis-2004-with-char.txt > euc-jis-2004-nkf.txt

    iconv
    $ libiconv-1.14/src/iconv_no_i18n -f EUC-JIS-2004 -t UTF-8  euc-jis-2004-with-char.txt > euc-jis-2004-iconv.txt

    それぞれの出力ファイルを比較します。

    $ diff  euc-jis-2004-nkf.txt euc-jis-2004-iconv.txt
    204c204
    < ‾     0xA1B1  U+203E  # OVERLINE      Windows: U+FFE3
    ---
    >  ̄    0xA1B1  U+203E  # OVERLINE      Windows: U+FFE3
    266c266
    < ¥     0xA1EF  U+00A5  # YEN SIGN      Windows: U+FFE5
    ---
    > ¥    0xA1EF  U+00A5  # YEN SIGN      Windows: U+FFE5

    EUC-JIS-2004の変換では、2つの文字で異なる変換結果が得られました。

    • オーバーライン (0xA1B1)
      • nkf   U+203E
      • iconv   U+FFE3
    • 円記号 (0xA1EF)
      • nkf   U+00A5
      • iconv   U+FFE5

    Shift_JIS-2004

    次に、Shift_JIS-2004の変換をします。

    nkf
    JIS X 0201 片仮名を JIS X 0208 片仮名に変換しないように、オプション -x を指定します。
    $ nkf-2.1.3/nkf -x --ic=Shift_JIS-2004 --oc=UTF-8 sjis-0213-2004-with-char.txt > sjis-0213-2004-nkf.txt

    iconv
    $ libiconv-1.14/src/iconv_no_i18n -f Shift_JIS-2004 -t UTF-8  sjis-0213-2004-with-char.txt > sjis-0213-2004-iconv.txt


    それぞれの出力ファイルを比較します。

    $ diff sjis-0213-2004-nkf.txt sjis-0213-2004-iconv.txt
    118c118
    < \     0x5C    U+00A5  # YEN SIGN
    ---
    > ¥     0x5C    U+00A5  # YEN SIGN
    152c152
    < ~     0x7E    U+203E  # OVERLINE
    ---
    > ‾     0x7E    U+203E  # OVERLINE
    298c298
    < ‾     0x8150  U+FFE3  # FULLWIDTH MACRON
    ---
    >  ̄    0x8150  U+FFE3  # FULLWIDTH MACRON
    360c360
    < ¥     0x818F  U+FFE5  # FULLWIDTH YEN SIGN
    ---
    > ¥    0x818F  U+FFE5  # FULLWIDTH YEN SIGN

    Shift_JIS-2004の変換では、4つの文字で異なる変換結果が得られました。

    • 円記号 (0x5C)
      • nkf   U+005C
      • iconv   U+00A5
    • オーバーライン (0x7E)
      • nkf   U+007E
      • iconv   U+203E
    • 全角マクロン (0x8150)
      • nkf   U+203E
      • iconv   U+FFE3
    • 全角円記号 (0x818F)
      • nkf   U+00A5
      • iconv   U+FFE5


    nkfでは、0x5Cと0x7Eは文字の意味に沿って変換するのではなく、ASCII互換として扱うようです。
    で、足りなくなった分を全角マクロンと全角円記号で補っている感じでしょうか。
    この辺りはオプションなどで色々変えられるのかもしれませんが、そこまでは調べませんでした。

    今回の使用・作成したファイルをGitHubに上げていますので、興味のある方はご覧ください。
    https://github.com/nathancorvussolis/difference-between-nkf-and-iconv

    2015年5月2日

    IMEの拡張機能


    IMEの各種設定のうちキーバインドやローマ字仮名変換ルールなどは基本的な機能として用意されていることがほとんどですが、例えば、標準以外の辞書を使いたいとか候補を整形したいなどの要望に答えるため、いくつかのIMEでは簡易的なスクリプトを組むことでそれらを実現できる機能を持っています。

    実現可能な機能については各IMEによって異なりますが、主に以下のような機能を有しているようです。
    1. 外部からデータを取得する
    2. 外部にデータを出力する
    3. 動的に候補や注釈を生成する
    4. これらをスクリプト言語で組める
    以下、拡張機能を持っているWindows用IMEの紹介です。


    ATOK


    ATOKダイレクトAPI
    http://atok.com/useful/developer/api/

    使用言語 : Perl, Ruby, Python


    SKK日本語入力FEP


    SKKGate
    http://coexe.web.fc2.com/skkgate.html
    SKKプラス
    http://coexe.web.fc2.com/skkextend.html

    使用言語 : JavaScript など


    CorvusSKK


    Lua拡張
    https://github.com/nathancorvussolis/corvusskk/wiki#Lua
    https://github.com/nathancorvussolis/corvusskk/blob/master/installer/config-lua/init.lua

    使用言語 : Lua


    SKK日本語入力FEPとCorvusSKKに関しては、操作体系の元ネタであるSKKがEmacsLispで記述された候補を実行して動的に候補を生成する機能を元々持っているので、これを拡張可能にしているのも自然な流れかなと思います。

    Windows用IMEでユーザー数が多いMS-IMEとGoogle日本語入力には拡張機能はないようですが、Android用のGoogle日本語入力やATOKには他のアプリのと連携を行うマッシュルーム機能があるそうです。

    以前某IMEでも話題になりましたが、気を付けなければならないのがIMEのセキュリティについてです。
    拡張機能を不用意に使うと穴ができる可能性があるので、製作者側にも使用者側にも慎重さが求められます。

    IME as a Possible Keylogger (symantec)
    https://www.symantec.com/avcenter/reference/ime.as.a.possible.keylogger.pdf

    それでは、良い連休を。

    2015年3月11日

    SKK-JISYO.stationを更新した話 (2)

    前回は本題からちょっと脇道に逸れてしまったので、今回は更新作業そのものについて書きたいと思います。
    まあ、あまり大した話ではないですが。

    資料探し


    まず、手元に情報がないため資料を探すことから始めます。
    SKK-JISYO.stationは廃線、廃駅については削除をしない方針で、最後の更新が2005年なので、
    1. 期間は2006年〜2014年の範囲 (一応2005年もチェックしておく)
    2. 駅、路線、鉄道会社で新規もしくは名称が変更されたもの
    という条件で探します。良さげな以下の2つを見付けたのでこれらを元ネタとすることにします。

    更新用辞書作成


    あとはひたすら単純作業です。
    1. Category:開業年別鉄道駅に記載されている駅をWikipediaで検索し、日付の項目をチェック
    2. 更新用の辞書ファイルにエントリを追加
    3. 1〜2を繰り返す
    さらに、駅データベースで改称とされている駅についても同様にエントリを追加していきます。
    Wikipediaのほうは中国、台湾、韓国の駅も多数含まれていて紛らわしいので逆にしておけば良かったと、このあたりで少し後悔。

    同音異字のチェック


    次に、更新用の辞書ファイルのなかで同音で異なる字の駅がSKK-JISYO.stationにないかどうかをチェックします。

    今回は「なかのしまえき /中之島駅/」と「ぞうしがやえき /雑司が谷駅/」が該当したので、注釈を付けて「なかのしまえき /中之島駅;中之島線/」、「ぞうしがやえき /雑司が谷駅;副都心線/」とします。
    さらに「ぞうしがやえき」には元々1つしか候補がなかったので既存の候補に注釈を付加した「ぞうしがやえき /雑司ヶ谷駅;荒川線/」も追加します。
    ちなみに、「なかのしまえき」のエントリには南武線「中野島駅」、札幌市営地下鉄南北線「中の島駅」が既に登録されていました。

    「〜えき」「〜駅」無しの更新用辞書作成


    SKK-JISYO.stationには見出し語の「〜えき」と候補の「〜駅」が無いエントリも登録されているので、更新用の辞書ファイルをベースとして「えき」および「駅」を取り除いたバージョンの更新用辞書を作成します。

    マージ


    既存のSKK-JISYO.stationと更新用の2つの辞書ファイルを拙作のmeskkdicを使ってマージし、ファイル先頭のコメント行を追加します。
    Unix系であれば、skkdic-exprとskkdic-sort、またはskkdic-expr2を使うと良いと思います。
    念のため、既存の辞書と新しい辞書のdiffをとって問題がないかどうか確認します。

    コミット


    そして最後に、openlab.jpのCVSにコミットして完了です。



    と、ここまで書いて、大阪市営地下鉄今里筋線、東京メトロ副都心線などの路線名が漏れていたことに気が付きました。
    あとで追加しておきます。

    2015年3月9日

    SKK-JISYO.stationを更新した話

    2015年2月末、TwitterでSKK関連のつぶやきを眺めていたところSKK-JISYO.stationに吉川美南駅(武蔵野線 吉川駅と新三郷駅の間)が載っていないとの発言を見かけました。SKK-JISYO.stationを調べてみたら2005年を最後に実質的な更新がされておらずコメント部分のみの更新に留まっていました。

    これはいかん、ということで翌3月になって時間ができたときに作業開始。2006年〜2014年だとしても丸9年もありますが、幸いにもSKK-JISYO.stationは廃線、廃駅は残したままとしておく方針なので、新規と変更だけに絞ることとし、更新用の辞書を作って最終的に既存の辞書とマージしてコミットしました。しかし、翌日見直したら1件だけ漏れが見付かったのでこれを追加して再度コミットし、特に問題なく作業完了しました。

    気になった点としては、名称が「〜停留場」や「〜停留所」などであっても「〜駅」となっているところでした。(例:都電荒川線 三ノ輪橋停留場) この使い分けについては、法律や省令で決められていたり設備の違いだったり昔の名残もあったりして素人が判別するのはなかなか難しいようです。基本的には鉄道会社が呼んでいる名称が良さそうなのですが、今回は以前からの方針に沿って「〜駅」で統一しました。

    また、廃線が思っていたより多いという印象を受けました。

    以下、今回更新した範囲で個人的に気になった出来事を挙げてみました。(注:かなり関東に偏っています。)
    • 2008年3月30日 日暮里・舎人ライナー開業
    • 2008年3月30日  横浜市営地下鉄グリーンライン開業
    • 2010年10月21日 東京国際空港国際線ターミナル開業
      • 京急空港線 「羽田空港国際線ターミナル駅」開業
      • 京急空港線 「羽田空港駅」が「羽田空港国内線ターミナル駅」に改称
      • 東京モノレール羽田空港線 「羽田空港国際線ビル駅」開業
    • 2012年3月17日 東武伊勢崎線 「業平橋駅」が 「とうきょうスカイツリー駅」に改称
    • 2012年8月20日 東日本大震災で不通になっていた気仙沼線のうち、柳津駅〜気仙沼駅の区間でBRTの暫定運行開始

    そして今年2015年は、3月14日に予定されている北陸新幹線の長野駅〜金沢駅の開業と、上野東京ラインの開業がありますね。ちなみに、長野新幹線は正式には北陸新幹線という名称で、東京駅〜長野駅の区間が便宜的にそう呼ばれていただけのようで、今後は「北陸新幹線(長野経由)」など表記するそうです。

    なるべく漏れが無いように調べたつもりですが、私自身鉄道にあまり詳しくないこともあり調べきれていない可能性があります。 もし2014年までに開業、改名した駅、路線、鉄道会社で記載されていないものがありましたらTwitterなどで私まで知らせていただければ対応しますので、よろしくお願いします。

    今回更新したSKK-JISYO.stationは、こちらからダウンロードできます。


    そういえば、コンピューター関係の記事を巡回しているとやけに詳しい電車の記事が面白かったなあ、と思い出したのでリンクを貼っておきます。


    確か最初に読んだのが、向谷実さんが京阪電鉄の発車メロディを作った話でした。読み物として、あまり電車に詳しくなくても(詳しかったら多分もっと)面白いかと思います。

    2015年1月11日

    SKKの個人辞書

    あけましておめでとうございます。

    SKK風の入力方式には様々な実装があり、それぞれの実装毎で個人辞書が管理されています。
    色んな環境を使用する人にとって、どの実装でも共通の個人辞書を使えないか、という考えが浮ぶのは自然なことかと思います。

    そこで、SKK辞書サーバーを拡張して辞書検索のみならず辞書登録も可能なサーバーがあればいいのでは、という発想もまた自然なことだと思います。そのような機能を持ったサーバーで現在公開されているものは存在しないようですが、GoogleDriveやDropboxのAPIを使ったりできたら非常に面白いかな、と個人的には思ったりしています。

    さて、SKKの個人辞書はEUC-JPやUTF-8などのプレーンテキストなので、ユーザーにとって適当なタイミングで取り込んだりしたほうが柔軟性があって良いのもまたしかりです。

    以前 .skk-jisyo を自動的に取り込めないかという要望が寄せられたことがありました。 そこで回答したcveuc.exeとmeskkdicw.exeを使って.skk-jisyoをCorvusSKKの個人辞書に取り込むバッチファイルを一部改変したものを以下に記述します。

    ----- ここから -----

    pushd %~dp0

    @rem サーバープロセスを終了
    taskkill /im imcrvmgr.exe


    @rem .skk-jisyoをUTF-16(LE)に変換 (.skk-jisyoがEUC-JIS-2004かEUC-JPの場合)
    cveuc.exe -e -W "%USERPROFILE%\.skk-jisyo" skk-jisyo-utf16.txt

    @rem .skk-jisyoをUTF-16(LE)に変換 (.skk-jisyoがUTF-8の場合)
    @rem cveuc.exe -u -W "%USERPROFILE%\.skk-jisyo" skk-jisyo-utf16.txt


    @rem ユーザー辞書とマージ (.skk-jisyoを優先する場合)
    meskkdicw.exe skk-jisyo-utf16.txt + "%AppData%\CorvusSKK\userdict.txt" skk-jisyo-utf16-new.txt
    meskkdicw.exe -O skk-jisyo-utf16.txt + "%AppData%\CorvusSKK\userdict.txt" skk-jisyo-utf16-new.txt

    @rem ユーザー辞書とマージ (CorvusSKKのuserdict.txtを優先する場合)
    @rem meskkdicw.exe "%AppData%\CorvusSKK\userdict.txt" + skk-jisyo-utf16.txt skk-jisyo-utf16-new.txt
    @rem meskkdicw.exe -O "%AppData%\CorvusSKK\userdict.txt" + skk-jisyo-utf16.txt skk-jisyo-utf16-new.txt


    @rem マージしたユーザー辞書をコピー
    copy /y skk-jisyo-utf16-new.txt "%AppData%\CorvusSKK\userdict.txt"

    @rem 一時ファイルを削除
    del skk-jisyo-utf16.txt
    del skk-jisyo-utf16-new.txt

    @rem サーバープロセスを起動
    start "" "%SystemRoot%\System32\IME\IMCRVSKK\imcrvmgr.exe"

    popd

    ----- ここまで -----


    昨年はSKK-JISYO.lispをコミットさせてもらったりしたので、今年はddskk本体でも何か貢献できればと思っています。ddskk本体の開発環境がSKK OpenLabのCVSからGitHubに移行し、EmacsのパッケージシステムであるMELPAに登録されたりと、オラなんだかわくわくしてきたぞ状態の今日この頃です。

    2014年11月12日

    Lua 5.3の整数型

    Lua 5.3で追加された待望(?)の整数型に関するメモです。Lua 5.3 beta時点のものでリリース版では変更となる可能性があります。

    整数型はデフォルトではC言語のlong longもしくは__int64(Windows)で、コンパイル時に"LUA_32BITS"が定義されているとlong、"LUA_INT_INT"が定義されているとint、"LUA_INT_SHORT"が定義されているとshort intが使用されます。short intはテスト用に用意されているだけで非推奨のようです。

    ちなみに、数値型はデフォルトではdoubleで、コンパイル時に"LUA_32BITS"が定義されているとfloat、"LUA_REAL_LONGDOUBLE"が定義されているとlong doubleが使用されます。Lua 5.2ではdoubleが使用されています。

    この辺りの詳細は、luaconf.hをご覧ください。

     
    Lua 5.2にあったbit32ライブラリが廃止され、ビット演算子が導入されました。
    & 論理積
    | 論理和
    ~ 排他的論理和
    << 左シフト
    >> 右シフト
    ~ 否定

    以下、使用例です。
    print( 10 & 8 )   --> 8
    print( 8 | 1 )   --> 9
    print( 255 ~ 15 )   --> 240
    print( 8 << 1 )   --> 16
    print( 8 >> 1 )   --> 4
    print( ~0 )   --> -1

     
    また、整数用の演算子が1つ追加されています。割り切れないときはマイナス方向に丸めるようです。
    // 整数除算
    以下、除算演算子と整数除算演算子の使用例です。
    print( 10 / 6 )   --> 1.6666666666667
    print( 10 // 6 )   --> 1
    print( 10 / 9 )  --> 1.1111111111111
    print( 10 // 9 )  --> 1
    print( -10 / 9 )   --> -1.1111111111111
    print( -10 // 9 )   --> -2
    print( 10.0 // 3.0 )   --> 3   ( 10.0と3.0は整数で表現可能なのでOK )
    print( 10.5 // 3.0 )   -->  エラー!   ( 10.5は整数で表現不可能なのでNG )
    print( 10.0 // 3.5 )   -->  エラー!   ( 3.5は整数で表現不可能なのでNG )


    数値型が文字列に変換されるときに、小数点以下の数値がゼロのときでも".0"が付加されるようになりました。

    -- Lua 5.2
    print( 2.0 )   --> 2
    print( 2 )   --> 2

    -- Lua 5.3
    print( 2.0 )   --> 2.0
    print( 2 )   --> 2

    Lua 5.2と同じ結果を得るには、前述の整数除算演算子を使用するか、5.3で追加されたmath.tointeger関数を使用します。math.tointegerは1つの引数をとり、引数が整数で表現可能であればその整数を返し、整数で表現不可能であればnilを返します。
    x = 2.0
    xx = math.tointeger( x )
    if not xx then
        xx = x
    end
    print( xx )   --> 2




    【参照】
    Lua 5.3 Reference Manual
    http://www.lua.org/work/doc/manual.html

    2014年10月24日

    Luaの文字列リテラル

    Luaの文字列リテラルの字句構造についてのメモです。

    Luaの文字列リテラルは対応するシングルクォートまたはダブルクォートで囲みます。
    文字列リテラルの中には、以下のエスケープシーケンスを含むことができます。
    それぞれ、対応するLuaのバージョンを示し、Lua 5.3については5.3(alpha)の時点のものとします。


    制御文字 (Lua 5.1, 5.2, 5.3)


    \a   -   bell、ベル
    \b   -   backspace、後退
    \f   -   form feed、改頁
    \n   -   newline、改行
    \r   -   carriage return、復帰
    \t   -   horizontal tab、水平タブ
    \v   -   virtical tab、垂直タブ
    \\   -   back slash、バックスラッシュ
    \"   -   double quote、引用符・ダブルクォート
    \'   -   apostrophe (single quote)、アポストロフィ (シングルクォート)
    \(実際の改行)   -   改行
    \z   -   後続の改行を含むスペース文字をスキップします。

    バイト値 10進数 (Lua 5.1, 5.2, 5.3)


    \ddd   -   dddは最大3桁の10進数 (0〜255) で、後続に数字があるときは0を左詰めして3桁にします。

    バイト値 16進数 (Lua 5.2, 5.3)


    \xXX   -   XXは2桁の16進数 (00 〜 FF)。

    Unicode (Lua 5.3)


    \u{XXX}   -   XXXは1文字以上の16進数 (0〜10FFFF)。波括弧で囲む点に注意。内部ではUTF-8として扱われます。

    長括弧 (Lua 5.1, 5.2, 5.3)


    Luaの文字リテラルは長括弧 ( [[, ]] ) で囲むこともできます。
    長括弧内ではエスケープシーケンスは無視され、改行は改行そのものとして扱われます。ただし、開き長括弧の直後の改行は無視されます。
    レベル0長括弧 ( [[, ]] )、レベル1長括弧 ( [=[, ]=] ) 、さらにレベル2長括弧 ( [==[, ]==] )と角括弧に任意の個数の等号を加えた形式にすることもできますが、開き長括弧と閉じ長括弧のレベルは同じである必要があります。

    Luaの文字列リテラルは単なるバイト列で文字コードに依存しませんが、Shift_JISなどの2バイト目が0x5C(バックスラッシュまたは円記号)となりうる文字コードではそれがエスケープシーケンスとして扱われてしまい問題となります。いわゆるダメ文字です。その場合、他の言語でもありがちですが以下のように2つ重ねることで文字そのものとすることができます。

    print( "表\" )      --   Shift_JISにおける print( "\149\\" ) と同じ

    長括弧がエスケープシーケンスを無視する性質であることを利用して以下のようにも記述できます。

    print( [[表]] )

    今日一般的によく使われると思われるUTF-8ではこのような考慮は不要です。
    というわけで、Windows版ですが、文字列リテラルをUTF-8固定としてUnicode版の各種WindowsAPIやCランタイム関数を呼ぶようにパッチを当てたLuaの派生を作りました。CorvusSKKに組み込む目的で作りましたが、Luaの部分を抜き出した形で公開したものです。

    lua-u8w
    https://github.com/nathancorvussolis/lua-u8w

    Lua 5.3のリリース版はまだかなと思っていたら先程ベータ版が出たようです。
    http://www.lua.org/work/



    【参照】

    Lua 5.1 - Lexical Conventions
    http://www.lua.org/manual/5.1/manual.html#2.1

    Lua 5.2 - Lexical Conventions
    http://www.lua.org/manual/5.2/manual.html#3.1

    Lua 5.3(alpha) - Lexical Conventions
    http://www.lua.org/work/doc/manual.html#3.1

    2014年10月19日

    IME開発者向けリンク集

    CorvusSKKというDDSKKの入力方式を用いたWindowsで動くIMEを開発しております。
    DOS、Windowsの世界では過去に様々なFEP、IMEが存在していましたが、現在のWindowsにおいては選択肢がちょっと少ないのでは?ということで、これからIMEを作ってみたい方向けに有益かと思われるリンクをまとめてみました。



    Text Services Framework (TSF) 実装例

    • ソースコードが公開されているもの
      • CorvusSKK
        • 手前味噌ですみません。
      • tsf-tutcode
        • CorvusSKKをフォークして頂きました。漢字直接入力機能が追加されています。
      • tsf-vim
        • vi風な操作をIMEとして実装されたもの
      • Mozc
        • Google日本語入力のオープンソース版。辞書はそれに劣るようですが、Mac、Linux、Android、ChromeOSでも動くそうです。
    • ソースコードが公開されていないもの
      • SKK日本語入力FEP (SKKFEP)
        • SKKの操作性をベースに革新的な機能が盛り沢山なIMEです。一度はまると抜け出せなくなります。
      • Google日本語入力
        • あのGoogleがIMEを作った!と衝撃が走ったのは記憶に新しいところ。Windows 7まではIMM32実装が、Windows 8以降でTSF実装が使用されます。
      • MS-IME
        • Windowsに標準で組み込まれています。リンクはMS-IME2010のものですが、OfficeのライセンスがあればXP、Vista、7で使用可能です。
      • ATOK
        • 賢い変換が可能だそうです。個人的には試用版を少し触れた程度なので。
      • Baidu IME
        •  検索エンジンのサービスを開発運用しているとIMEも作っちゃおうぜみたいになるのでしょうか。
      • WinAnthy
        • Anthyの移植版
      • Social IME
        • インターネット経由でかな漢字変換を行うユーザー参加型のIME。以前ソースコードが公開されていたみたいなのですが現在では見付かりませんでした。

     

    Text Services Framework (TSF) 全般


    WindowsにおけるIMEは、notepad.exeやexplorer.exeなどのプロセスにIMEのDLLがロードされた状態で動きます。IMEのDLLはプロセス側と同等のアクセス制限が課されるため、ファイルアクセスやプロセス間通信を行うときにそれを考慮しなければなりません。

    セキュリティ全般


    Internat Explorer

    Windows Vista 以降の Internet Explorer の保護モードについて

    AppContainer

    Windows 8 以降のAppContainerについて


    Adobe Sandbox

    Adobe Acrobat/Reader X以降、Firefox 4.0以降で動くAdobe Flash Player 11.3以降で有効となるサンドボックスについて



     ざっとこんなところでしょうか。