Using ADSI to Configure IIS in a C++ Application

The Windows ADSI classes IADs and IADsContainer can be used to get, set, enumerate, refresh, move, and copy IIS metabase properties and nodes without having to include the IIS ADSI provider interfaces. IADs is used to represent any object in a hierarchy, such as a node in the IIS metabase. IADsContainer is used to represent a container of objects, such as the child nodes below a node in the IIS metabase.

However, the IIS ADSI provider interfaces include definitions for special purpose objects such as IISIPSecurity and IISMimeType, and methods for IIS-related tasks like creating applications and backing up the metabase.

Example

The following example code uses the C++ programming language to query the IIS ADSI provider interfaces in order to call the IISApp3::AppCreate3 method.

A reference to an IADs object is obtained, representing the default Web site (IIS://localhost/w3svc/1/root). Then, pointers to the IISApp2 and IISApp3 interfaces are obtained by using the QueryInterface method on the IADs object. Finally, the pointer to the IISApp3 interface is used to call the IISApp3::AppCreate3method, optionally creating an application pool. You can use this logic to query any IIS ADSI provider interface to call a method.

This code example requires at least IIS 6.0, configured to run in IIS Modes of Operation, because application pools are not supported on earlier versions of IIS.

#include "stdafx.h"
#include <initguid.h>
#include <objbase.h>
#include <iads.h>
#include <adshlp.h>
#include <iiisext.h>
#include <iisext_i.c>

int _tmain(int argc, _TCHAR* argv[])
{
  HRESULT hr;
  IADs *pADs = NULL;

  hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
  if ( FAILED( hr ) )
  {
    wprintf( L"CoInitialize failed. Error 0x%0x\n", hr );
    goto error;
  }

  hr = ADsGetObject( L"IIS://localhost/w3svc/1/root", IID_IADs, (void **)&pADs );
  if ( FAILED( hr ) )
  {
    wprintf( L"ADsGetObject() failed. Error 0x%0x\n", hr );
    goto error;
  }

  IISApp2 *pApp2 = NULL;
  hr = pADs->QueryInterface( IID_IISApp2, (void **)&pApp2 );
  if ( FAILED( hr ) )
  {
    wprintf( L"QI for IIsApp2 failed. Error 0x%0x\n", hr );
    goto error;
  }

  IISApp3 *pApp3 = NULL;
  hr = pADs->QueryInterface( IID_IISApp3, (void **)&pApp3 );
  if ( FAILED( hr ) )
  {
    wprintf( L"QI for IIsApp3 failed. Error 0x%0x\n", hr );
    goto error;
  }

  wprintf( L"Both IISApp2 and IISApp3 are queryable. Good.\n" );
  wprintf( L"Calling AppCreate3 on W3SVC/ROOT/1 to see if it works ...\n" );

  VARIANT varPool;
  VariantInit( &varPool );

  varPool.vt = VT_BSTR;
  varPool.bstrVal = SysAllocString( L"MyAppPool" );

  VARIANT varCreatePool;
  VariantInit( &varCreatePool );

  varCreatePool.vt = VT_BOOL;
  varCreatePool.boolVal = VARIANT_TRUE;

  hr = pApp3->AppCreate3( 2, varPool, varCreatePool );
  if ( FAILED( hr ) )
  {
    wprintf( L"AppCreate3() call failed. Error 0x%0x\n", hr );
    goto error;
  }

  wprintf( L"Call to AppCreate3() succeeded!\n" );

error:
  if ( pApp3 )
    pApp3->Release();

  if ( pApp2 )
    pApp2->Release();

  if ( pADs )
    pADs->Release();

  CoUninitialize();

  return hr;
}

Optional comments.

See Also

Concepts

IIS ADSI Provider Interfaces

IIS Constants and Header Files

Extending the IIS ADSI Schema

Using ADSI to Configure IIS