Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
Other versions of this page are also available for the following:
Windows Mobile Not Supported Windows Embedded CE Supported
8/28/2008

The Testdll sample demonstrates how to write an extension-agent DLL. This DLL implements the toaster MIB and shows how new MIBs can be added to the agent through a DLL.

Copy Code
/**********************************************************************
Module Name:
  testdll.c

Abstract:
  The Microsoft Extendible Agent is implemented by dynamically
linking 
  to the Extension-Agent DLLs that implement portions of the MIB.
These 
  Extension Agents are configured in the Registration Database.
When 
  the Extendible Agent Service is started, it queries the registry
to 
  determine the Extension-Agent DLLs that have been installed and
need to 
  be loaded and initialized. The Extendible Agent invokes various
DLL 
  entry points to request MIB queries and obtain Extension Agent- 
  generated traps.
**********************************************************************/

#include <windows.h>
#include <snmp.h>
#include "testmib.h"	// Contains the definitions for the table 
						// structure describing the MIB. This is
used 
						// in conjunction with Testmib.c where the
MIB
						// requests are resolved.
// Extension-Agent DLLs need access to the time that has elapsed
since the agent
// has been active. This reference is implemented by initializing
the Extension 
// Agent with a time-zero reference, and allowing the agent to
compute the 
// elapsed time by subtracting the time-zero reference from the
current
// system time. This sample Extension Agent implements this
reference
// by using dwTimeZero.
DWORD dwTimeZero = 0;

// Extension-Agent DLLs that generate traps must create a Win32
Event 
// object to communicate occurrence of traps to the Extendible
Agent.
// The event handle is given to the Extendible Agent when the
Extension
// Agent is initialized, it should be NULL if traps will not be 
// generated. This sample Extension Agent simulates the occurrence
of 
// traps by using hSimulateTrap.
HANDLE hSimulateTrap = NULL;

// This is a standard Win32 DLL entry point. This example DLL does
not
// perform any special actions by using this mechanism.
BOOL WINAPI DLLEntry (HANDLE hDll, DWORD dwReason, LPVOID
lpReserved)
{
  switch (dwReason)
  {
	case DLL_PROCESS_ATTACH:
	case DLL_PROCESS_DETACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	default:
	break;
  } // end switch ()

  return TRUE;
} // end DllEntryPoint ()


// Extension-Agent DLLs provide the following entry point to
coordinate
// the initializations of the Extension Agent and the Extendible
Agent. 
// The Extendible Agent provides the Extension Agent with a
time-zero 
// reference; The Extension Agent provides the Extendible Agent
with an
// Event handle for communicating occurrence of traps, and an
object 
// identifier representing the root of the MIB subtree that the 
// Extension Agent supports.
BOOL WINAPI SnmpExtensionInit (
	IN  DWORD			 dwTimeZeroReference,
	OUT HANDLE			*hPollForTrapEvent,
	OUT AsnObjectIdentifier *supportedView)
{
  // Record the time-zero reference that is provided by the
Extendible Agent.
  dwTimeZero = dwTimeZeroReference;

  // Create an Event that will be used to communicate the
occurrence of
  // traps to the Extendible Agent. The Extension Agent will assert

  // this Event when a trap has occurred. This is explained
further, 
  // later in this file.
  if ((*hPollForTrapEvent = CreateEvent (NULL, FALSE, FALSE, NULL))

	== NULL)
  {
	// Indicate error. Be sure that NULL is returned to the
Extendible
	// Agent.
  }

  // Indicate the MIB view that is supported by this Extension
Agent, an object
  // identifier that represents the sub root of the MIB that is
supported.
  *supportedView = MIB_OidPrefix;  // Structure copy

  // Record the trap event. This example Extension Agent simulates 
  // traps by generating a trap after every given number of
requests 
  // that are processed.
  hSimulateTrap = *hPollForTrapEvent;

  // Indicate that initialization of the Extension Agent was
successful.
  return TRUE;
} // end SnmpExtensionInit ()


// Extension-Agent DLLs provide the following entry point to 
// communicate traps to the Extendible Agent. The Extendible Agent
will
// query this entry point when the trap event (which is supplied at

// initialization time) is asserted, which indicates that zero or
more 
// traps might have occurred. The Extendible Agent will call
repeatedly
// this entry point until FALSE is returned, which indicates that
all 
// outstanding traps have been processed.
BOOL WINAPI SnmpExtensionTrap (
	OUT AsnObjectIdentifier *enterprise,
	OUT AsnInteger		*genericTrap,
	OUT AsnInteger		*specificTrap,
	OUT AsnTimeticks		*timeStamp,
	OUT RFC1157VarBindList  *variableBindings)
{
  // The body of this routine is an extremely simple example of the
trap
  // functionality. A real implementation will be more complex.

  // The following variables define data that is inserted into the
trap below.
  static UINT OidList[]  = { 1, 3, 6, 1, 4, 1, 77, 2 };
  static UINT OidListLen = 8;

  // The following variable is used for the simulation; it allows a

  // single trap to be generated and then causes FALSE to be
returned, 
  // which indicates no more traps.
  static whichTime = 0;

  // The following if/else support the simulation.
  if (whichTime == 0)
  {
	whichTime = 1; 				// Supports the simulation

	// Communicate the trap data to the Extendible Agent.
	enterprise->idLength	= OidListLen;
	enterprise->ids		 = OidList;
	*genericTrap			= SNMP_GENERICTRAP_ENTERSPECIFIC;
	*specificTrap		 = 1; 	// the bytesAvailAlert trap
	*timeStamp			= GetTickCount () - dwTimeZero;
	variableBindings->list  = NULL;
	variableBindings->len   = 0;

	// Indicate that valid trap data exists in the parameters.
	return TRUE;
  }
  else
  {
	whichTime = 0; 				// Supports the simulation

	// Indicate that no more traps are available and parameters do
not
	// refer to any valid data.
	return FALSE;
  }
} // end SnmpExtensionTrap ()


// Extension-Agent DLLs provide the following entry point to
resolve 
// queries for MIB variables in their supported MIB view (which is
supplied at 
// initialization time). The requestType is Get/GetNext/Set.
BOOL WINAPI SnmpExtensionQuery (
	IN BYTE				 requestType,
	IN OUT RFC1157VarBindList *variableBindings,
	OUT AsnInteger			*errorStatus,
	OUT AsnInteger			*errorIndex)
{
  UINT I;
  static unsigned long requestCount = 0;// Supports the trap
simulation
  
  // Iterate through the list of variable bindings to resolve
individual
  // variable bindings.
  for (I=0; I < variableBindings->len; I++)
  {
	*errorStatus = ResolveVarBind
(&variableBindings->list[I],
								 requestType);
	// Test and handle the case where Get Next past end of the MIB
view that 
	// is supported by this Extension Agent occurs. Special
processing is 
	// required to communicate this situation to the Extendible
Agent, 
	// so that it can take the appropriate action, possibly
querying other 
	// Extension Agents.
	if (*errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME &&
		requestType == MIB_ACTION_GETNEXT)
	{
	*errorStatus = SNMP_ERRORSTATUS_NOERROR;

	// Modify variable binding of such variables so the OID
points
	// just outside the MIB view that is supported by this
Extension Agent.
	// The Extendible Agent tests for this and takes appropriate
	// action.
	SnmpUtilOidFree (&variableBindings->list[I].name);
	SnmpUtilOidCpy (&variableBindings->list[I].name,
&MIB_OidPrefix);
	variableBindings->list[I].name.ids[MIB_PREFIX_LEN-1] ++;
}

	// If an error was indicated, communicate error status and
error
	// index to the Extendible Agent. The Extendible Agent will
ensure
	// that the original variable bindings are returned in the
response
	// packet.
	if (*errorStatus != SNMP_ERRORSTATUS_NOERROR)
	{
	*errorIndex = I + 1;
	goto Exit;
}
  }

Exit:
  // Supports the trap simulation.
  if (++requestCount % 3 == 0 && hSimulateTrap != NULL)
	SetEvent (hSimulateTrap);

  // Indicate that Extension-Agent processing was successful.
  return SNMPAPI_NOERROR;
} // end SnmpExtensionQuery ()


// Extension-Agent DLLs provide the following entry point to be
called
// by the master agent when the subagent is being unloaded.
VOID SnmpExtensionClose ()
{
  // Add code here ...
}

See Also