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 です。