Bindview とINetCfg API
みなさま、お久しぶりです。さなえすです。
ローカル エリア接続のプロパティから、チェックボックスのチェックを入れる・はずすといった手順で、IPv6 の有効・無効の切り替えなどを行うことができます。では、似たような操作を、プログラムで行いたい場合どうすればよいのでしょうか?
INetCfg インターフェースは、ネットワーク関連のモジュールのセットアップや、コンフィグレーションを行うための機能を提供しています。なので、この INetCfg インターフェースを使用してプログラムを実装すれば、IPv6 のコンポーネントを有効・無効にすることもできるようになります。INetCfg インターフェースの使用方法については、Windows Driver Kit (WDK) で、技術ドキュメントとサンプル コード (Bindview) を公開していますので、実際のコードを見たい方は、WDK の下記のディレクトリを直接ご参照ください。
Bindview Sample
%BaseDir%\src\network\config\bindview
何はともあれ、まずはサンプルを動かしてみてください。使用方法はこんなかんじです。
1. サンプルをビルドし、Bindview.exe を管理者権限で起動
2. [Show Bindings For] のプルダウンより、列挙するネットワーク機能の種類を選択
例えば IPv6 の設定を変更したい場合、[All Protocols] を選択し、"インターネット プロトコル バージョン 6 (TCP/IPv6) " を選択
3. 条件に該当する Bind Path を展開/選択して右クリックし、[Enable]/[Disable] を実施
下記の <Bindview 操作画面> の例など、Broadcom の NIC の接続から IPv6 をアンバインドしたい場合は、Binding Path 2 が該当します
なお、ローカル エリア接続のプロパティなどのプロパティシートは閉じた状態で行う必要がありますのでご注意ください。上記手順の前後で、ローカル エリア接続のプロパティなどのプロパティシートを確認すると、チェックボックスが ON/OFF されているのが確認できると思います。
<Bindview 操作画面>
では、Bindview サンプルが INetCfg インターフェースを使用してこのような操作を行う際の、主な処理の概要を紹介します。
主に Bindview サンプルの以下の処理が参考になると思います。
%BaseDir%\src\network\config\bindview\BINDING.CPP
%BaseDir%\src\network\config\bindview\NetCfgAPI.CPP
(1) INetCfg の初期化処理
まずは、 ルートとなる INetCfg を初期化します。
主な処理
- CoCreateInstance でINetCfg インターフェースを取得
- INetCfg::QueryInterface() で、INetCfgLock のインタフェースを取得
- INetCfgLock::AcquireWriteLock() で変更権限を取得
- INetCfg::Initialize() で初期化
【インターフェース】
INetCfg
<https://msdn.microsoft.com/en-us/library/ff547694(v=VS.85).aspx>
(2) コンポーネントの列挙
ネットワーク機能の種類に応じたコンポーネントリストを列挙します。
主な処理
- INetCfg::FindComponent() で、INetCfgComponentを取得
上のサンプルの操作例では、"インターネット プロトコル バージョン 6 (TCP/IPv6) " を操作するにあたり、列挙するネットワーク機能の種類として、[All Protocols] を選択しました。これは、GUID_DEVCLASS_NETTRANS の GUID を使用して INetCfg::EnumComponents メソッドを呼び出し、ネットワークプロトコルのコンポーネント リストを取得する処理が該当します。他にも、NICを対象に列挙したいのであれば、GUID_DEVCLASS_NET という GUID を使用すれば OK です。
Network cards |
GUID_DEVCLASS_NET |
Transports |
GUID_DEVCLASS_NETTRANS |
Network services |
GUID_DEVCLASS_NETSERVICE |
Network clients |
GUID_DEVCLASS_NETCLIENT |
取得できたコンポーネントに対して、INetCfgComponent インターフェースのメソッドを使えば、Display Name や、コンポーネントのID、属性など様々な情報が引き出せます。これらの情報を使って条件を絞ってもよいですね。他のインターフェースも組み合わせて使用して、目的のコンポーネントを抽出する際の条件を実装してください。
【インターフェース】
INetCfgComponent
<https://msdn.microsoft.com/en-us/library/ff547715(VS.85).aspx>
- INetCfg::EnumComponents Method
<https://msdn.microsoft.com/en-us/library/ff547959(v=VS.85).aspx>
- INetCfgClass
<https://msdn.microsoft.com/en-us/library/ff547708(VS.85).aspx>
- INetCfgComponentBindings
<https://msdn.microsoft.com/en-us/library/ff547716(v=VS.85).aspx>
- INetCfgBindingPath
<https://msdn.microsoft.com/en-us/library/ff547699(v=VS.85).aspx>
- IEnumNetCfgBindingPath
<https://msdn.microsoft.com/en-us/library/ff546634(v=VS.85).aspx>
- INetCfgBindingInterface
<https://msdn.microsoft.com/en-us/library/ff547695(v=VS.85).aspx>
- IEnumNetCfgBindingInterface
<https://msdn.microsoft.com/en-us/library/ff546616(v=vs.85).aspx>
(3) コンポーネントへの処理
対象となるコンポーネントのバインド パスが見つかったら、後は変更を加えたり、必要なプロパティ情報を参照したりと、目的に応じた処理を行います。例えば、目的のコンポーネントに対して、有効・無効の切り替えなどの変更を加える場合、Enable メソッドを使用します。(フラグにより処理を切り替えます。なので、Disable の場合も Enableメソッドを使います。)なお、変更を加えた場合は、ルートのINetCfg インターフェースに対してINetCfg::Apply()で変更を反映する必要があります。
【インターフェース】
- INetCfgBindingPath::Enable Method
<https://msdn.microsoft.com/en-us/library/ff547700(v=VS.85).aspx>
- INetCfg::Apply Method
<https://msdn.microsoft.com/en-us/library/ff547947(v=VS.85).aspx>
大体こんな流れになると思います。是非、実際に Bindview を動かしながら、いろいろ試してみてください。
上記のような「既にインストールされているネットワークのモジュールに関して何かをする」というシナリオ以外にも、インストール(もしくはアンインストール)などのセットアップの場合も INetCfg インターフェースを使用します。一般的なデバイス ドライバーは、Setup API 群で行うことが多いですが、これもネットワークのドライバーのちょっと特殊なところで、バインドされてはじめてネットワークスタック上で機能しますので、専用のインターフェースが必要になるんですね。もちろん Bindview でもその機能を提供しています。使用方法や実装はここでは割愛しますが、必要に応じて WDK のヘルプをご参照ください。
<Bindview 操作画面>
私どものサポート業務においても、トラブルシューティング時に Bindview はたびたび登場します。例としては、自前のインストーラーで自前のネットワークドライバーをインストールすると失敗してしまう、といったような問題が起きたとします。Bindview を使っても同じような問題が出てしまうか試してもらえば、調査すべき要因が、インストーラーにあるのか、それ以外にあるのか切り分けられます。もし Bindview では同じ問題が出ないようであれば、インストールの処理に問題が無かったかを調査していくことになります。
【おまけ】
余談ですが、Bindview のほかにも、nvspbind というツールもあります。結構ポピュラーなようですのでついでにご紹介しておきます。こちらも基本的には INetCfg インターフェースを使用しています。Bindview と違い、ソースコードは公開されていませんが、*.exe 形式の状態でダウンロードできますので、WDK の環境がなくてもさくっと動作確認できますね。
-nvspbind
<https://archive.msdn.microsoft.com/nvspbind>
以上、さなえすでした。読んでくださってありがとうございます。何かしら皆さまのお役に立てていれば幸いです!
では、皆さまごきげんよう~!