メインコンテンツへジャンプする

JPNICはインターネットの円滑な運営を支えるための組織です

ロゴ:JPNIC

WHOIS 検索 サイト内検索 WHOISとは? JPNIC WHOIS Gateway
WHOIS検索 サイト内検索

mDN Wrapper

実現方法 - Wrapper DLL

ラッパーDLL は、アプリケーションと元のDLL との間に割り込んで、 アプリケーションからのDLL の呼び出しを横取りして、 本来のDLL とは異なった処理をさせるものです。

how wrapper DLL works

アプリケーションからのDLL の呼び出しはラッパーに渡されます。 ラッパーはそこで、付加的な処理を行なって、 元のDLL のエントリを呼び出します。 また、元のDLL の処理結果は一旦ラッパーに返され、 ここでも付加的な処理を行なって、 最終的な結果がアプリケーションに返されることになります。

mDN wrapper では、WINSOCK DLLの

  • WSOCK32.DLL (WINSOCK V1.1)
  • WS2_32.DLL (WINSOCK V2.0)

に対するラッパーDLL を提供して、 多言語ドメイン名の名前解決ができるようにします。

注: 16ビット版のWINSOCK (WINSOCK.DLL) は対象外です。


処理対象のAPI

mDN Wrapper はWINSOCK の名前解決に関連したAPI についてのみ 付加的な処理を行ないます。 処理の対象となるWINSOCK APIは以下のものです。

WINSOCK 1.1, WINSOCK 2.0 の両方にあるもの:

  • gethostbyaddr
  • gethostbyname
  • WSAAsyncGetHostByAddr
  • WSAAsyncGetHostByName

WINSOCK 2.0 だけにあるもの:

  • WSALookupServiceBeginA
  • WSALookupServiceNextA
  • WSALookupServiceEnd

アプリケーションによっては、 これらのAPI を使わないで独自にドメイン名の解決を行なうものもあります。 例えば、nslookupは、これらのAPI を使わないで、 内部で独自にDNS リクエストの生成、解釈を行なっています。 当然のことながら、これらのアプリケーションについては、 mDN Wrapper では多言語化対応させることはできません。

それに対して、mdnsproxyはネットワーク上でDNS のリクエスト、レスポンスに ついて多言語化しますので、これらのアプリケーションについても多言語化 させることができます。必要に応じて適時使い分けるといいでしょう。

注: WINSOCK 2.0 には、WIDE CHARACTER ベースの名前解決のAPI として WSALookupServiceBeginWWSALookupServiceNextW もありますが、これらについてはラップしません。これらのAPI はマイクロソフト 仕様による国際化に対応したものですから、そのフレームワーク上で使うべきもの です。これらについてはmDNkit によって他の多言語フレームワークに変換してし まうのは危険ではないか、と判断しました。


処理対象外のAPI

上記以外のWINSOCK API については、mDN Wrapper は何もせず、 元の WINSOCK API を呼び出します。

mDN Wrapper では、元のWINSOCK DLL を名前を変えてコピーし、 それを呼び出すように作られています。

wsock32.dll
wsock32o.dll に改名
ws2_32.dll
ws2_32o.dll に改名

ラッパーDLL は元のWINSOCK DLL と同じ名前で作成されます。 従ってmDN wrapper がインストールされた状態では、

wsock32.dll
mDN Wrapper for WINSOCK V1.1
ws2_32.dll
mDN Wrapper for WINSOCK V2.0
wsock32o.dll
Original WINSOCK V1.1 DLL
ws2_32o.dll
Original WINSOCK V2.0 DLL

となります。


非同期 API

ドメイン名の変換は、以下のタイミングで行なわれる必要があります。

DNS へのリクエスト時
ローカルエンコーディングから DNS エンコーディングへ変換
DNS からの応答受信時
DNS エンコーディングからローカルエンコーディングへ変換

同期API においては、 ローカルエンコーディングからDNS エンコーディングへの変換は、 元のAPI を呼び出す前に行われ、 DNS エンコーディングからローカルエンコーディングへの変換は、 元のAPI から復帰してきたところで行なわれます。

しかし、WINSOCK の以下のAPI は非同期API で、 DNS からの応答受信前に復帰してしまいます。

  • WSAAsyncGetHostByAddr
  • WSAAsyncGetHostByName

これらのAPI においては、名前解決の完了は、 Windows へのメッセージによって通知されます。 このため、 DNS エンコーディングからローカルエンコーディングへの変換を行なうには、 ラッパーは通知先のウィンドウプロシジャのメッセージキューをフックして、 この完了メッセージを捕獲する必要があります。

そこで、非同期API が呼び出された場合には、mDN Wrapper は、 通知先のウィンドウプロシジャ(これはAPI のパラメタで指示されます)に フックを設定します。 フックが完了メッセージ(これもAPI のパラメタで指示されます)を検出したなら、 フックは結果の格納領域(これもAPI のパラメタで指示されています)の ドメイン名を、DNS 側のエンコーディングからローカルエンコーディングに変換する ものとします。


Wrapper DLL のインストール

WINSOCK DLL はWindows のシステムディレクトリに置かれています。 WINSOCK を確実にラップするには、システムディレクトリにおいて 次のことを行なう必要があります。

オリジナルWINSOCK DLL の名前の変更:

ren wsock32.dll wsock32o.dll
ren ws2_32.dll  ws2_32o.dll

ラッパーDLL の導入:

copy somewhere\wsock32.dll wsock32.dll
copy somewhere\ws2_32.dll  ws2_32.dll
copy another DLLs also

しかし、システムディレクトリでこのようなDLL の置き換えを行なうのは 大変危険な操作になります。

  1. DLL を入れ替えた状態でもういちど同じ操作を行なうと、オリ ジナルのWINSOCK DLL が失われてしまうことになります。
  2. サービスパックやアプリケーションなどでWINSOCK DLL を 再導入するものがありますが、これによってもWINSOCK が利用不能になる ことがあります。

このような状態になると、ネットワーク機能が全く使えなくなったり、 最悪はWindows の起動すらできなくなる可能性があります。

そこで、mDN Wrapper では、上のようなシステムレベルのラップではなく、 アプリケーションに対するラップを基本機能として提供するものとします。

Windows において、DLL は基本的には

  1. アプリケーションのロードディレクトリ
  2. %SystemRoot%\System32
  3. %SystemRoot%
  4. PATH で指示されるディレクトリ

の順序で検索されて、最初に見つかったものがロードされます。 ですから、一般的には、 DLL をアプリケーションのロードディレクトリにインストールすれば、 そのアプリケーションからのWINSOCK の呼び出しをラップすることができます。

ただし、いくつかのアプリケーション、DLL では、 検索パスを経由せずに特定のDLL をリンクするようになっているものがあります。 このような構成のアプリケーション、DLL が使われた場合には mDN Wrapper では対処することはできません。

注: Netscapeは特定DLL にバインドされているようで、アプリケーション ディレクトリへのインストールではラップできません。WINSOCK DLL 自体も システムディレクトリの関連DLL にバインドされているようです。 一方、Internet ExploreやWindows Media Playerは標準のサーチパスに従っている ので、ラップすることができます。


エンコーディングの変換位置

WINSOCK 2.0 をサポートしているWindows には、 WINSOCK の1.1 と2.0 のそれぞれに対応するDLL があり、 WINSOCK 1.1 のAPI の呼び出しは 2.0 の同じエントリにリダイレクトされるようになっています。

calling winsock2.0 through winsock1.1

この場合には1.1 に対する呼び出しも2.0 に対する呼び出しも、 ともにV2.0用のDLL に渡されるので、 2.0用のラッパーDLL 側だけで エンコーディングの変換を行なうようにするべきでしょう。

一方、WINSOCK 1.1 しかサポートしていない場合(Win95)には、 1.1 に対応したDLL しかありません。

calling only winsock1.1

この場合には必然的に1.1 用のラッパーDLL で エンコーディングを変換しなければなりません。

mDN Wrapepr がwindows のシステムディレクトリにインストールされた場合には、 上の通りに動作するので、

  • WINSOCK 2.0 がある場合は、2.0 ラッパーで変換
  • WINSOCK 1.1 だけしかない場合は、1.1 ラッパーで変換

とする必要があります。

しかし、アプリケーションディレクトリにインストールされた場合には動作が 変わってきます。 Windows 付属の WINSOCK 1.1 DLLは、システムディレクトリの WINSOCK 2.0 にバインドされているため、アプリケーションディレクトリ側の WINSOCK 2.0 ラッパーDLL にはリダイレクトされてきません。 このため、アプリケーションディレクトリへのインストールにおいては、 1.1DLL、2.0DLLの両方でエンコーディングを変換する必要があります。 ただし Windows2000 付属の WINSOCK 1.1 DLL は動作が異なり、 アプリケーションディレクトリ側の WINSOCK 2.0 ラッパー DLL にリダイレクトされる ようです。

このようなDLL 間のバインディングはドキュメントされていませんので、 環境、バージョンによっては異なった動作をするかも知れません。 そこでmDN Wrapper では、レジストリ値によって、 ラッパーDLL のどこで変換を行なうかを決定するようにして、 インストール先による差異、あるいはバージョンによる差異を吸収するようにします。

mDN Wrapper 用のレジストリ設定は

    
HKEY_LOCAL_MACHINE\SOFTWARE\JPNIC\MDN
HKEY_CURRENT_USER\SOFTWARE\JPNIC\MDN

以下に配置されます。エンコーディング変換を行なう位置については、 この直下のレジストリ値 Where(REG_DWORD) によって決定します。

0
WINSOCK 1.1、WINSOCK 2.0 の両方で変換する
1
WINSOCK 2.0 があれば、WINSOCK 2.0だけで変換する WINSOCK 1.1 だけの場合には WINSOCK 1.1 で変換する
2
WINSOCK 1.1 だけで変換する
3
WINSOCK 2.0 だけで変換する

Windows2000 以外で アプリケーションディレクトリにインストールする場合には「0」を、 システムディレクトリにインストールする場合および Windows2000 でアプリケーションディレクトリにインストールする場合 には「1」を設定する必要があります。 もしレジストリ値が存在しない場合には「0」を想定します。 これはアプリケーションディレクトリへのインストールを標準としたものです。


変換元/先のエンコーディング

ラッパーDLL では、解決しようとするドメイン名を、 マシンのローカルエンコーディングからDNS サーバのエンコーディングに変換し、 また、DNS が返してきたドメイン名 (DNS サーバのエンコーディング) を マシンのローカルエンコーディングに戻します。

現在、DNS 側の多言語化エンコーディングについては、 いくつもの方式が提案されています。 ラッパーDLL はそれらのDNS 側エンコーディングのどれかひとつに 変換するように構成されます。 このDNS 側エンコーディングは設定ファイルで指定することができます。

一方、アプリケーションが使用しているローカルエンコーディングは、 通常はプロセスのコードページから求めます。 ラッパーDLL が使用する iconv ライブラリは、 windows のコードページ名を エンコーディング名として受付けることができるので、 コードページ名をそのままローカルエンコーディング名として使用します。

しかし、アプリケーションによっては、 特定の多言語化エンコーディングで ドメイン名をエンコーディングしてしまうものもあります。 例えば、IEではドメイン名をUTF-8 で表記するように 指示することができるようになっています。 UTF-8 によるエンコーディングは、 提案されている多言語化方式のひとつですが、 多言語化されたDNS サーバは他のエンコーディングしか受付けないかも知れません。

このような状況に対処するため、mDN Wrapper は、 ローカルエンコーディングとして プログラム特有のエンコーディングも受付けることができるようにします。 このようなプログラム特有のローカルエンコーディングは レジストリ記載されるものとします。

mDN Wrapper 用のプログラム特有のレジストリ設定は

  • HKEY_LOCAL_MACHINE\SOFTWARE\JPNIC\MDN\PerProg
  • HKEY_CURRENT_USER\SOFTWARE\JPNIC\MDN\PerProg

以下に、 プログラム名(実行モジュールファイル名)をキーとして 配置されます。 例えば、Internet Explore の場合には、 実行モジュール名の IEXPLORE をキーとして

HKEY_LOCAL_MACHINE\SOFTWARE\JPNIC\MDN\PerProg\IEXPLORE

以下に置かれます。 ローカルエンコーディング名は、

レジストリ値 Encoding (REG_SZ)

で指定します。これもlibmdnで認識されるものでなければなりません。 アプリケーションプログラム特有のエンコーディング名 (デフォルトのエンコーディング以外を必要とする場合)を指定します。


ログ

mDN Wrapper が期待した動作をしない場合、動作のログは問題解決に非常に 役立ちます。mDN Wrapper では、レジストリの設定により、以下の設定が 可能です。

  • ログレベル
  • ログファイル

ログレベル、ログファイルともに次のレジストリの下で設定されます。

HKEY_LOCAL_MACHINE\SOFTWARE\JPNIC\MDN
HKEY_CURRENT_USER\SOFTWARE\JPNIC\MDN

ログレベルは

レジストリ値 LogLevel (REG_DWORD)

で指定します。定義されている 値は次の通りです。

-1 (0xFFFFFFFF)
[None] ログを一切出力しない
0
[Fatal] 致命的エラーのみ出力
1
[Error] 致命的でないエラーも出力
2
[Warning] 警告メッセージも出力
3
[Info] エラー以外の情報も出力
4
[Trace] プログラムのトレース情報も出力

なお、このレベル指定は mDN Wrapper が使用している MDN ライブラリ の出力するログのレベル指定です。 ログにはこの他 mDN Wrapper 自身が出力するものがありますが、こちらは レベル指定はできず、単にオン・オフを切り替えるだけです。-1 を指定した場合には オフ、それ以外の値を指定した場合にはオンになります。 デフォルトは -1 です。

ログファイルはログを出力するファイルのパス名を指定するもので、 レジストリ値 LogFile (REG_SZ) で指定します。デフォルトは mDN Wrapper をインストールしたディレクトリの下の mdn_wrapper.log です。

なお、ログレベルとログファイルは設定プログラムを使用しても 設定することができます。


レジストリ設定 - まとめ

レジストリの優先順位

mDN Wrapper の設定情報は、HKEY_LOCAL_MACHINEHKEY_CURRENT_USER

Software\JPNIC\MDN

以下に格納されます。 mDN Wrapperは最初に HKEY_LOCAL_MACHINE の設定を読み込み、 HKEY_CURRENT_USER 側にも設定があれば、これで上書きします。 通常は、HKEY_LOCAL_MACHINE 側だけを設定します。 ユーザ個別に異なった設定を使いたい場合のみ、 HKEY_CURRENT_USER を設定するようにしてください。

特に、設定プログラムは常に HKEY_LOCAL_MACHINE の 設定しか読み書きしません。設定ファイルを使用して 設定を行う場合には気をつけてください。

レジストリキー

全体の共通の設定と、プログラム個別設定とがあります。

共通定義:

Software\JPNIC\MDN\Where 変換位置
Software\JPNIC\MDN\ConFile 設定ファイル名
Software\JPNIC\MDN\LogLevel ログレベル
Software\JPNIC\MDN\LogFile ログファイル

プログラム個別設定:

Software\JPNIC\MDN\PerProg\<name>\Where 変換位置
Software\JPNIC\MDN\PerProg\<name>\Encoding DNS側エンコーディング名

プログラム個別設定が指定されていない場合には、

Where 共通定義の設定値
Encoding プロセスのコードページ

とみなします。

このページを評価してください

このWebページは役に立ちましたか?
よろしければ回答の理由をご記入ください

それ以外にも、ページの改良点等がございましたら自由にご記入ください。

回答が必要な場合は、お問い合わせ先をご利用ください。

ロゴ:JPNIC

Copyright© 1996-2024 Japan Network Information Center. All Rights Reserved.