I learned WTL by working with simple examples, often taken from VB Script.This example simply provides a WTL solution for the following VB Script:

		Dim IIsObject
		Set IIsObject = GetObject ("IIS://localhost/w3svc")
		WScript.Echo "AnonymousUserName = " & IIsObject.Get("AnonymousUserName") & vbCrlf & _
		"AnonymousUserPass = " & IIsObject.Get("AnonymousUserPass") & vbCrlf & vbCrlf & _
		"WAMUserName = " & IIsObject.Get("WAMUserName") & vbCrlf & _
		"WAMUserPass = " & IIsObject.Get("WAMUserPass")
		Set IIsObject = Nothing
		

This simple script reads the WAM and Anonymous user name and password from the IIS metabase collection.

I always wondered how I would go about reading these parameters in C++. Here is my solution. There are many more, based on the type of object you want to use. I chose to use the IMSAdminBase COM object for this example. Here is a screen shot of my solution:

Screen shot

The names and passwords can be copied from the text boxes into your application. For those of you that are not C++ fans, you will be able to note how much C++ code it takes to emulate a four line VB Script. It also serves to illustrate just how much work VBS hides from you.

First, what is the API function call that is the equivalent of GetObject? The correct answer is usually ::CoGetObject. However, the API call requires a few more parameters than the VB Version. This brings us to how we gain access to the API calls we need. We are lucky, because ATL/WTL drag in a lot of API functionality without us having to hunt through MSDN for the correct headers and libraries. I can tell from experience, that using the string fragment "IIS:" in GetObject indicates we are performing a call for an ADSI interface. As it turns out, the actual symbolic name of the top level interface is named IADs. I am going to suggest we drag in a lot of header files so we can try several methods of retrieving the the names and passwords we desire.

	#include <initguid.h>
	#include <objbase.h>
	#include <Iads.h>	// ADSI constants
	#include <adshlp.h>
	#include <Iiisext.h>	// ADSI Interfaces
	#include <iisext_i.c>
	#include <iadmw.h>	// COM Interface header
	#include <iiscnfg.h>	// MD_ & IIS_MD_ #defines

First, we will essentially copy the VB code into our WTL project:

	// Dim IIsObject
	CComPtr <IADs> pIADs;
	...
	// Set IIsObject = GetObject ("IIS://localhost/w3svc")
	HRESULT hr = ::CoGetObject(_T("IIS://localhost/w3svc"), NULL, IID_IADs, (void**)&pIADs); 

	CComBSTR propName;
	CComVariant propVal;

	// IIsObject.Get("AnonymousUserName")
	propName = _T("AnonymousUserName");
	i = pIADs->Get(propName, &propVal);
	m_strAnonuser = propVal.bstrVal;

	// IIsObject.Get("AnonymousUserPass")
	propName = _T("AnonymousUserPass");
	i = pIADs->Get(propName, &propVal);
	m_strAnonpwd = propVal.bstrVal;

	// IIsObject.Get("WAMUserName")
	propName = _T("WamUserName");
	i = pIADs->Get(propName, &propVal);
	m_strWamuser = propVal.bstrVal;

	// IIsObject.Get("WAMUserPass")
	propName = _T("WamUserPass");
	i = pIADs->Get(propName, &propVal);
	m_strWampwd = propVal.bstrVal;

	// WScript.Echo	DoDataExchange(false);

	// Set IIsObject = Nothing
	// The ATL smart pointer, CComPtr takes care of this.
	// Otherwise, we might do something like pIADs.Release();
	

Now, this is a fairly boring, but enlightening fragment of code. I have omitted the error checking of hr for clarity of code. As an exercise for the reader, you need to learn about the macro's SUCCEEDED and FAILED. I also realized that my code does not really implement the code stream the same way VB Script works. (Oops!) VB Script actually gains access though IUnknown and then queries for the IDispatch interface. Get is then called using Invoke.

Here is the project download. Enjoy!