[ADSI] Inside "System.DirectoryServices" - 中身を激しく見てやるぜ!(1) / 2 depends.exe

皆さんこんばんは。ういこです。

同僚が、心機一転するために家にしこたまため込んだトランジスタ技術(略してトラ技)やらインターフェースやら I/O やらを一気に捨てたらしいです。新しい何かを会得するためには、古い何かを捨てることも時には必要なのですね。彼曰く、一抹のさみしさがあったとか。

それ、すっごいわかります! わたしも、創刊号の前の定期刊行前からずっと買ってた「ガンダムエース」とか、「CONTINUE」とか月刊ニュータイプを一気に売りに行ったとき、すごい悲しかったですもの。同僚!!君はよく頑張ったよ!!と、励ましは blog にかえさせていただきます。頑張れはらだん(実名)。

ちなみにこないだも大掃除で一気に捨てたもののまだまだものが多い私。家族に超怒られてます。ブースもものだらけです。今日は漫☆画太郎先生の「地獄甲子園」の DVD が出てたことに気づかず、店頭で立ち尽くしてしまったものの、その直前に息子に「がちゃがちゃは我慢しろ」といった手前、断腸の思いで我慢!!血涙です!!

さてそんなどうでもいいことはおいといて今日のお題です。ちょっと気が向いたので、重いネタです。というか、詰まんないかもですみません。

【今日のお題】

System.DirectoryServices ( 以下 S.DS) 名前空間の処理って、ぶっちゃけ何で動いてるの?

~その一~

1. System.DirectoryServices ( 以下 S.DS) 名前空間の処理概要

S.DS は ADSI のマネージ相互運用層となります。「マネージ相互運用層」とか小難しい言葉を使ってますが、要は、ActiveDS.dll とか WLDAP32.dll とかの ADSI の処理のラッパーみたいな感じで想像するとわかりやすいです。(※ ただし Framework 3.x 以降で追加されたライブラリは独自実装を持つものもあります。)

今回は、ADSI 絡みの部分についてのお話です。

さて、非 AD 系のディレクトリ サービスを提供しているサーバに対してアクセスする際などは、S.DS 経由でアクセスを行う場合内部では ADSI 経由で LDAP プロバイダを用いて処理が実行されます。このとき、内部では Windows で LDAP プロバイダを使用する場合、WLDAP32.DLL のメソッドが使用されます。

では "WLDAP32.DLL" とはなんでしょう。

これは、基本的に Windows 上での LDAP プロトコルを使用したクライアント動作には使用されるコンポーネントであります。

たとえばデータを受け取る際の実際の処理は、この WLDAP32.DLL の ldap_get_value() メソッドが使われています。

このメソッドで LDAP Raw データを受領し、各属性を構造体に格納され、S.DS に受け渡されるのです。

ここまで読んでらした方は、「そんな話知って何に役立つ?」と思われるでしょう。

…役に立つんですよこれが。問題が発生した時の切り分けに。

たとえば、S.DS を使ってて問題が発生したとします。そのとき、ADSI をつかって、VBScript などで同じ処理をしてみて同じ現象が発生すれば、それは ADSI の問題であるとわかります。また、もし同じ現象にならなければ、.NET Framework もしくは S.DS の固有の問題である可能性があるということがわかり、回避策として ADSI を呼び出すといったような対処も取れるというわけです。

2. S.DS が内部で呼び出すメソッド、モジュールの確認手段

今回の S.DS に限らず、.NET Framework では、実際には Win32 API ネイティブ機能のラッパーとして実装されているものが少なくありません。

このような場合の確認をしたいとき、どうしようと思われる方もいらっしゃるのではないでしょうか。

実際、わたしたちが調べるときにつかう手法を紹介させていただきます。

今日は、このうち、「1. depends.exe を使ってモジュールの依存関係を確認」と、「2. ildasm を使ってメタデータを確認」をご紹介いたします。(長いので…)

1. depends.exe を使ってモジュールの依存関係を確認

2. ildasm を使ってメタデータを確認

3. WinDBG などデバッガで処理追跡をする

ADSI の ActiveDS.dll や LDAP クライアントの WLDAP32.dll のように、特徴的なモジュールがある場合、1. の depends.exe を使用して確認することで使用されている機能の予測をつけることが可能な場合があります。

S.DS の場合 ADSI の部分的な実装になるため、全ての場合に当てはまらない場合もありますが 2. の ildasm を使用することで、メタデータを参照し、例えば P/Invoke 呼び出しで特定のDLL のメソッドなどを呼び出している場合はマネージ相互運用層として機能していると考察することができる場合もあります。あとは有名な「.NET Reflector」を使ってみるのがよいこともあります。今回の場合だと、System.DirectoryServices.dll を対象すればよいですね。ハードディスク上で System.DirectoryServices.dll を検索して、ildasm したりしてみてください。

でももっと激しく中身を見たい!というアナタには、3. の Windbg や Visual Studio でステップ イン実行をしていくことでコール スタックを確認し、どのような処理を実行しているか特定するのをお勧め★

以下、それぞれの手段について説明させていただきますね。

3. S.DS WLDAP32.dll 依存関係の確認について (depends.exe)

今回の S.DS 名前空間のように Win32 のネイティブ機能のラッパーとして使用されているモジュールの依存関係は、Dependency Walker for Win32 (Depends.exe) を使用して確認することが可能です。

以下、使用方法例となります。

1. depends.exe を起動します。(※1)

2. [File] メニュー - [Save As ...] を選択します。

3. [名前をつけて保存] ダイアログ ボックスが開くので、以下の通り保存ください。

 ファイル名 (N): <任意の名称でかまいません>

 ファイルの種類 (T): Comma Separated Values (*.csv)

4. [保存(S)] ボタンを押して保存してください。

5. 次に、この手順で保存した CSV ファイルを Excel で開きます。

6. コントロール キー + F キーを押し、検索ダイアログを呼び出し、確認したい DLL の名称を入力して [全てを検索(I)] ボタンを押します。

例えばこんな感じのモジュールが見えると思います。

 ACTIVEDS.dll (ADSI モジュール)

 WLDAP32.dll (LDAP プロバイダ使用時使用) (※2)

System.DirectoryServices.dll (v2.0.50727) の環境での一例は下記の通りとなります。

バージョン 6.0.6000.16386 の DLL に依存していることがわかります。

 ACTIVEDS.DLL (中略) 6.0.6000.16386

 WLDAP32.DLL (中略) 6.0.6000.16386

依存関係を纏めると下記のとおりとなります。

 System.DirectoryServices.dll

  - ACTIVEDS.DLL

   - WLDAP32.DLL

  - WLDAP32.DLL

(1) depends.exe の場所 - Visual Studio 2005 環境では以下に配置されています。

<VS2005 インストール ディレクトリ>

 \Common7

  \Tools

   \Bin

    \Depends.Exe

例)

C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin\Depends.Exe

ダウンロード、depends.exe の情報はこちら

[SMS] Dependency Walker for Win32 (Depends.exe) について

https://support.microsoft.com/kb/198707/ja

Windows XP Service Pack 2 サポートツール

https://www.microsoft.com/downloads/details.aspx?FamilyID=49ae8576-9bb9-4126-9761-ba8011fabf38&displayLang=ja

Active Server Pages VBScript 実行時エラー '800a01ad' を返す

https://support.microsoft.com/kb/194801/ja

参考ドキュメント

Description of the requirements and of the troubleshooting methods that you can use to enable an LDAP client to communicate with an LDAP server over SSL

https://support.microsoft.com/kb/290483/ja

⇒ こちらのドキュメントには、LDAP クライアントは WLDAP32.dll を使用すると記載があります。

// 引用ここから

"LDAP clients include any process that uses Wldap32.dll, such as the following processes:? A process that uses calls to Active Directory Services Interfaces (ADSI).

? A process that uses LDAP from the Windows Address Book (WAB). This process is launched by using Microsoft Outlook Express or by using a Search dialog box.

Because Wldap32.dll is the underlying technology, code samples will demonstrate how to use the function calls. This is referred to as the LDAP API."

// 引用ここまで

System.DirectoryServices 名前空間

https://msdn.microsoft.com/ja-jp/library/system.directoryservices(VS.80).aspx

⇒ このドキュメントには、DirectoryEntry が ADSI 技術を使用する旨記載があります。

How to Turn on Debug Logging of the LDAP Client (Wldap32.dll)

https://support.microsoft.com/kb/325616/ja

⇒ こちらは WLDAP32 が LDAP クライアントであると記載されています。

Lightweight Directory Access Protocol

https://msdn.microsoft.com/en-us/library/aa367008(VS.85).aspx

ldap_get_values Function

https://msdn.microsoft.com/en-us/library/aa366935(VS.85).aspx

⇒ ldap_get_values が Wldap32.dll を必要とする旨記載があります。

.NET Framework のディレクトリサービス

https://msdn.microsoft.com/ja-jp/library/ms180826.aspx

⇒ System.DirectoryServices 名前空間の概要の項に、マネージ コードから Active Directory へのアクセスを提供し、System.DirectoryServices は ADSI 上に構築される旨記載があります。

というわけで今回はここまでです。次回は「3. WinDBG などデバッガで処理追跡をする」を書きたいと思います。はい。では皆様またご機嫌よう!

~ういこう@息子が明らかに本命チョコもらったことをわかってないのに涙~