IIS Admin Base Object (ABO) を用いた IIS の構成情報の取得 (キーの列挙)

ABO って何?

IIS 7.0 でも IIS 6.0 以前のバージョンでも使える、IIS 管理のネイティブインターフェイスは Admin Base Object (ABO) です。

COM の呼び出しになりますので、C 言語で書くと一見 「難しそう~」と感じてしまうかもしれません。 しかし、使いまわしのきくコードですから、一度慣れてしまえば難しいと感じることは無いと思います。

ここでは、ABO を使って、特定のキーの下にあるサブキーの情報を列挙する方法を紹介します。

ポイントは ABO のオブジェクト作成後、EnumKeys メソッド で指定したキー以下のサブキーを 取得するところです。

hr = pcAdmCom->EnumKeys (
     METADATA_MASTER_ROOT_HANDLE,
     L"/LM/W3SVC",
     wszMDName,
     dwIdx++);

キーの名前は wszMDName に返ってきます。

キーの名前を取得するだけならこれで終わりです。

さらに、キーのタイプを調べるならば、MEDADATA_RECORD 構造体に MD_KEY_TYPE を指定して、 GetData メソッドを呼び出します。これによって、そのキーのタイプがわかります。

METADATA_RECORD mdrData;
WCHAR wszKeyType [METADATA_MAX_NAME_LEN];
DWORD dwMDRequiredDataLen;

mdrData.dwMDIdentifier = MD_KEY_TYPE;
mdrData.dwMDAttributes = METADATA_NO_ATTRIBUTES;
mdrData.dwMDUserType = IIS_MD_UT_SERVER;
mdrData.dwMDDataType = STRING_METADATA;
mdrData.pbMDData = (PBYTE) wszKeyType;
mdrData.dwMDDataLen = sizeof (wszKeyType);
mdrData.dwMDDataTag = 0;

hr = pcAdmCom->GetData (
     METADATA_MASTER_ROOT_HANDLE,
     wszMDPath, 
     &mdrData, 
     &dwMDRequiredDataLen );

ABO を使ったキーの列挙 サンプルコード

ここでは構成キー "/LM/W3SVC" 直下のキー情報を取得する例を紹介します。

次の内容を enumkey.cpp として保存します。

#define INITGUID

#include <windows.h>
#include <objbase.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <iadmw.h>
#include <iiscnfg.h>


BOOL EnumSites () {

     IMSAdminBase *pcAdmCom = NULL; 
     HRESULT hr = 0; 
     
     //
     // COM の初期化
     //

     wprintf (L"Initializing COM...\n");
     
     hr = CoInitialize(NULL);
     assert(SUCCEEDED(hr));
     
     hr = CoCreateInstance(GETAdminBaseCLSID(TRUE), 
          NULL, CLSCTX_SERVER, IID_IMSAdminBase, (void**)&pcAdmCom);
     assert(SUCCEEDED(hr));

     
     //
     // キーの列挙
     //

     wprintf (L"EnumKeys...\n");

     WCHAR wszMDName [METADATA_MAX_NAME_LEN];
     WCHAR wszMDPath [METADATA_MAX_NAME_LEN];
     DWORD dwIdx = 0;

     while (1) {

          hr = pcAdmCom->EnumKeys (
               METADATA_MASTER_ROOT_HANDLE,
               L"/LM/W3SVC",
               wszMDName,
               dwIdx++);

          if ( FAILED(hr) ) {
               break;
          }

          // 子キーを開く
          
          wsprintfW (wszMDPath, L"/LM/W3SVC/%s", wszMDName);
          
          METADATA_RECORD mdrData;
          WCHAR wszKeyType [METADATA_MAX_NAME_LEN];
          DWORD dwMDRequiredDataLen;
          
          mdrData.dwMDIdentifier = MD_KEY_TYPE;
          mdrData.dwMDAttributes = METADATA_NO_ATTRIBUTES;
          mdrData.dwMDUserType = IIS_MD_UT_SERVER;
          mdrData.dwMDDataType = STRING_METADATA;
          mdrData.pbMDData = (PBYTE) wszKeyType;
          mdrData.dwMDDataLen = sizeof (wszKeyType);
          mdrData.dwMDDataTag = 0;

          hr = pcAdmCom->GetData (
               METADATA_MASTER_ROOT_HANDLE,
               wszMDPath, 
               &mdrData, 
               &dwMDRequiredDataLen );

          assert (SUCCEEDED(hr));

          // 結果の表示

          wprintf (L"[%d]\n", dwIdx);
          wprintf (L"\tName: %s\n", wszMDPath);
          wprintf (L"\tKeyType: %s\n", wszKeyType);
          
     }

     //
     // クリーンアップ
     //

     wprintf(L"Cleanup...\n");
     
     pcAdmCom->Release();

     CoUninitialize();

     wprintf(L"Done.\n");

     return TRUE;

}


int main ( int argc, char* argv[] ) {

     EnumSites ();
     
     return 0;

}

makefile は次の通りです。

TARGETNAME=enumkey
OUTDIR=.\chk
LINK32=link.exe

ALL : "$(OUTDIR)\$(TARGETNAME).exe"


CPPFLAGS=\
	/nologo\
	/MT\
	/W3\
	/Fo"$(OUTDIR)\\"\
	/Fd"$(OUTDIR)\\"\
	/c\
	/Zi\
	/DWIN32\
	/DUNICODE\
	/D_UNICODE\
		
LINK32_FLAGS=\
	ole32.lib\
	user32.lib\
	/nologo\
	/subsystem:console\
	/pdb:"$(OUTDIR)\$(TARGETNAME).pdb"\
	/machine:I386\
	/out:"$(OUTDIR)\$(TARGETNAME).exe"\
	/DEBUG
	
LINK32_OBJS= \
	"$(OUTDIR)\$(TARGETNAME).obj"

"$(OUTDIR)\$(TARGETNAME).exe" : "$(OUTDIR)" $(LINK32_OBJS)
    $(LINK32) $(LINK32_FLAGS) $(LINK32_OBJS)

"$(OUTDIR)" :
    @if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

.cpp{$(OUTDIR)}.obj:
   $(CPP) $(CPPFLAGS) $<

これで nmake すると、chk サブディレクトリに enumkey.exe が出来上がります。これを実行すると次のような結果が得られます。

> enumkey.exe
Initializing COM...
EnumKeys...
[1]
        Name: /LM/W3SVC/FILTERS
        KeyType: IIsFilters
[2]
        Name: /LM/W3SVC/APPPOOLS
        KeyType: IIsApplicationPools
[3]
        Name: /LM/W3SVC/INFO
        KeyType: IIsWebInfo
[4]
        Name: /LM/W3SVC/1
        KeyType: IIsWebServer
Cleanup...
Done.

>

もし、この中から Web サイト情報だけを抽出したい場合は、KeyType が IIsWebServer のエントリだけを取り出せば OK です。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説