/**
 * @brief winExtDLL Net-SNMP agent extension module.
 *
 * Copyright (c) 2006-2009 Alex Burger.
 * Copyright (c) 2009-2010 Bart Van Assche <bart.vanassche@gmail.com>.
 *
 * This Net-SNMP agent extension module loads Windows SNMP Extension Agent
 * DLLs in the Net-SNMP agent. Not only extension DLLs provided with Windows
 * (e.g. hostmib.dll) but also third-party extension DLLs are supported. This
 * allows Net-SNMP to be a replacement for the Windows SNMP service, and makes
 * it possible to use the SNMPv3 protocol.
 *
 * @see See also <a href="http://msdn.microsoft.com/en-us/library/aa378988(VS.85).aspx">SNMP Functions</a>
 *   for more information about Microsoft's SNMP Extension Agent API.
 *
 * @note In order to use this agent extension module, the Windows SNMP service
 *   must be installed first and must be disabled. Installing the Windows SNMP
 *   service is the only way to install the Windows Extension DLLs and to make
 *   sure that information about these DLLs is present in the registry.
 *
 * @note All Windows extension DLLs are loaded during startup of the Net-SNMP
 *   service. The Net-SNMP service must be restarted to load new modules. This
 *   extension is NOT for dynamically loading Net-SNMP extensions.
 *
 *
 * History:
 * - 2010/03/19:
 *    * Multi-varbind set request PDUs are now handled correctly.
 *    * If loading an extension DLL fails, the reason why this failed is now
 *      logged.
 *    * Fixed a memory leak that occurred when SnmpExtensionQuery() or
 *      SnmpExtensionQueryEx() failed while processing an SNMP PDU. Note:
 *      occurrence of an SNMP error does not make these functions fail, and
 *      it is not yet known whether or not it was possible to trigger this
 *      memory leak.
 * - 2010/03/17: Fixed bug 2971257. Multi-varbind getNext requests with OIDs
 *     in reverse lexicographical order are again processed correctly.
 * - 2010/01/22: Compiles now with MinGW too.
 * - 2009/12/11:
 *   * The value of sysUpTime.0 reported by inetmib1.dll is now correct.
 *   * A linkUp or linkDown trap is now sent after the status of a network
 *     interface has changed.
 * - 2009/03/26: 
 *   * Removed several artificial limits. Result: more than 100 SNMP extension
 *     DLLs can now be loaded simultaneously and more than 100 OID ranges can
 *     now be registered. Loading e.g. the Dell OpenManage SNMP extension DLL
 *     does no longer crash Net-SNMP. 
 *   * Number of OID ranges registered during startup is now logged.
 *   * It is no longer attempted to free the Broadcom SNMP extension DLLs
 *     bcmif.dll and baspmgnt.dll since doing so triggers a deadlock.
 *   * Added support for reregistration of an OID prefix. As an example, both
 *     both Microsoft's inetmib1.dll and the Eicon Diva divasnmpx.dll register
 *     the OID prefix iso.org.dod.internet.mgmt.mib-2.interfaces
 *     (.1.3.6.1.2.1.2). WinExtDLL will process OIDs with this prefix by using
 *     the handler that was registered last for the OID prefix. A message will
 *     be logged indicating that a handler has been replaced.
 * - 2009/03/10:
 *   * Fixed several bugs in var_winExtDLL(): looking up extension DLL info
 *     based on the OID in a varbind is wrong. It does happen during GetNext
 *     processing that Net-SNMP passes intentionally varbinds to a handler
 *     with OIDs that are outside the range registered by the handler. Fixed
 *     this by filling in a pointer to the extension DLL info in
 *     netsnmp_mib_handler::myvoid and by using that information in the
 *     var_winExtDLL() handler function.
 *   * SetRequest PDUs are now passed once to an extension DLL instead of
 *     four times.
 *   * The error status and error index of a multi-varbind set request is now
 *     filled in correctly.
 *   * Added support for the SNMP extension DLL three-phase SNMP set.
 *   * Made traps SNMPv2 compliant by adding the sysUpTime.0 varbind.
 *   * The varbind list generated by extension DLLs for e.g. linkUp and
 *     linkDown traps is now passed to Net-SNMP. Previously this varbind list
 *     was discarded for generic traps.
 *   * Fixed memory leaks triggered by Get and GetNext PDU processing.
 *   * Added missing RegCloseKey() calls.
 *   * Added shutdown function shutdown_winExtDLL().
 *   * Replaced #include <cstdio> by #include <stdio.h> such that this source
 *     file compiles with Visual Studio 2005.
 *   * Removed many unused local variables.
 *   * Fixed several other compiler warnings.
 * - 2006/09/09: creation of this file.
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/agent/mib_module_config.h>

#ifdef USING_WINEXTDLL_MODULE

#include <net-snmp/types.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include "../../win32/Snmp-winExtDLL.h"

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/library/snmp_assert.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "util_funcs.h"
#include "winExtDLL.h"


#define MAX_VALUE_NAME          16383
#define MS_ASN_UINTEGER32 MS_ASN_UNSIGNED32


typedef         BOOL(WINAPI *
                     PFNSNMPEXTENSIONINIT) (DWORD dwUpTimeReference,
                                            HANDLE * phSubagentTrapEvent,
                                            AsnObjectIdentifier *
                                            pFirstSupportedRegion);

typedef         BOOL(WINAPI *
                     PFNSNMPEXTENSIONINITEX) (AsnObjectIdentifier *
                                              pNextSupportedRegion);

typedef         BOOL(WINAPI *
                     PFNSNMPEXTENSIONMONITOR) (LPVOID pAgentMgmtData);

typedef         BOOL(WINAPI * PFNSNMPEXTENSIONQUERY) (BYTE bPduType,
                                                      SnmpVarBindList *
                                                      pVarBindList,
                                                      AsnInteger32 *
                                                      pErrorStatus,
                                                      AsnInteger32 *
                                                      pErrorIndex);

typedef         BOOL(WINAPI * PFNSNMPEXTENSIONQUERYEX) (UINT nRequestType,
                                                        UINT
                                                        nTransactionId,
                                                        SnmpVarBindList *
                                                        pVarBindList,
                                                        AsnOctetString *
                                                        pContextInfo,
                                                        AsnInteger32 *
                                                        pErrorStatus,
                                                        AsnInteger32 *
                                                        pErrorIndex);

typedef         BOOL(WINAPI * PFNSNMPEXTENSIONTRAP) (AsnObjectIdentifier *
                                                     pEnterpriseOid,
                                                     AsnInteger32 *
                                                     pGenericTrapId,
                                                     AsnInteger32 *
                                                     pSpecificTrapId,
                                                     AsnTimeticks *
                                                     pTimeStamp,
                                                     SnmpVarBindList *
                                                     pVarBindList);

typedef         VOID(WINAPI * PFNSNMPEXTENSIONCLOSE) (void);

typedef BOOL (WINAPI *pfIsWow64Process)(HANDLE hProcess, BOOL *Wow64Process);


/**
 * Extensible array, a data structure similar to the C++ STL class
 * std::vector<>.
 */
typedef struct {
    /** Pointer to the memory allocated for the array. */
    void           *p;
    /** Number of bytes occupied by a single element.  */
    size_t          elem_size;
    /** Number of elements that have been allocated.   */
    int             reserved;
    /** Number of elements currently in use.           */
    int             size;
} xarray;

/**
 * Information managed by winExtDLL about Windows SNMP extension DLL's.
 */
typedef struct {
    char           *dll_name;                        /**< Dynamically allocated DLL name. */
    HANDLE          dll_handle;                      /**< DLL handle. */
    PFNSNMPEXTENSIONINIT pfSnmpExtensionInit;
    PFNSNMPEXTENSIONINITEX pfSnmpExtensionInitEx;
    PFNSNMPEXTENSIONCLOSE pfSnmpExtensionClose;
    PFNSNMPEXTENSIONQUERY pfSnmpExtensionQuery;
    PFNSNMPEXTENSIONQUERYEX pfSnmpExtensionQueryEx;
    PFNSNMPEXTENSIONTRAP pfSnmpExtensionTrap;
    HANDLE          subagentTrapEvent;
} winextdll;

/**
 * Information managed by winExtDLL about a single view of a Windows SNMP
 * extension DLL.
 */
typedef struct {
    winextdll      *winextdll_info;
    netsnmp_handler_registration *my_handler;
    oid             name[MAX_OID_LEN];                   /**< OID of this view. */
    size_t          name_length;
} winextdll_view;

/**
 * Per varbind SNMP extension DLL context information for SNMP set operations.
 */
typedef struct context_info_s {
    struct context_info_s *next;
    int             index;
    AsnOctetString  context_info;
} context_info;


/*
 * External function declarations. 
 */
void __declspec(dllimport) WINAPI SnmpSvcInitUptime(void);


/*
 * Local functions declarations. 
 */
static int      basename_equals(const char *path, const char *basename);
static int      register_netsnmp_handler(winextdll_view *
                                         const ext_dll_view_info);
static void     read_extension_dlls_from_registry(void);
static void     read_extension_dlls_from_registry_at(const char *const subkey);
static char    *read_extension_dll_path_from_registry(const TCHAR *);
static void     subagentTrapCheck(unsigned int clientreg, void *clientarg);
static int      var_winExtDLL(netsnmp_mib_handler *handler,
                              netsnmp_handler_registration *reginfo,
                              netsnmp_agent_request_info *reqinfo,
                              netsnmp_request_info *requests);
static int      append_windows_varbind_list(netsnmp_variable_list **
                                            const net_snmp_varbinds,
                                            const SnmpVarBindList *
                                            const win_varbinds);
static int      append_windows_varbind(netsnmp_variable_list **
                                       const net_snmp_varbinds,
                                       const SnmpVarBind *
                                       const win_varbind);
static int      convert_to_windows_varbind_list(SnmpVarBindList *
                                                pVarBindList,
                                                netsnmp_variable_list *
                                                netsnmp_varbinds);
static int      convert_win_snmp_err(const int win_snmp_err);
static winextdll_view *lookup_view_by_oid(oid * const name,
                                          const size_t name_len);
static int      snmp_oid_compare_n_w(const oid * name1, size_t len1,
                                     const UINT * name2, UINT len2);
static int      snmp_oid_compare_w_n(const UINT * name1, UINT len1,
                                     const oid * name2, size_t len2);
static int      netsnmp_oid_is_subtree_n_w(const oid * name1, size_t len1,
                                           const UINT * name2, UINT len2);
static void     copy_oid(oid * const to_name, size_t * const to_name_len,
                         const oid * const from_name,
                         const size_t from_name_len);
static void     copy_oid_n_w(oid * const to_name, size_t * const to_name_len,
                             const UINT * const from_name,
                             const UINT from_name_len);
static UINT    *copy_oid_to_new_windows_oid(AsnObjectIdentifier *
                                            const windows_oid,
                                            const oid * const name,
                                            const size_t name_len);
static int      snmp_set_var_objid_w(netsnmp_variable_list * var,
                                     const UINT * name, UINT name_length);
static netsnmp_variable_list *
snmp_varlist_add_variable_w(netsnmp_variable_list ** varlist,
                            const UINT * name, UINT name_length,
                            u_char type, const void * value, size_t len);
static void     send_trap(const AsnObjectIdentifier * const,
                          const AsnInteger, const AsnInteger,
                          const AsnTimeticks,
                          const SnmpVarBindList * const);
static u_char  *winsnmp_memdup(const void *src, const size_t len);
#if 0
static void     xarray_init(xarray * a, size_t elem_size);
#endif
static void     xarray_destroy(xarray * a);
static void    *xarray_push_back(xarray * a, const void *elem);
#if 0
static void     xarray_erase(xarray * a, void *const elem);
#endif
static void    *xarray_reserve(xarray * a, int reserved);


/*
 * Local variable definitions. 
 */
#define WINEXTDLL(i)            ((winextdll*)s_winextdll.p)[i]
#define WINEXTDLL_VIEW(i)       ((winextdll_view*)s_winextdll_view.p)[i]
#define TRAPEVENT(i)            ((HANDLE*)s_trapevent.p)[i]
#define TRAPEVENT_TO_DLLINFO(i) ((winextdll**)s_trapevent_to_dllinfo.p)[i]
static const oid mibii_system_mib[] = { 1, 3, 6, 1, 2, 1, 1 };
static OSVERSIONINFO s_versioninfo = { sizeof(s_versioninfo) };
static xarray   s_winextdll = { 0, sizeof(winextdll) };
static xarray   s_winextdll_view = { 0, sizeof(winextdll_view) };
static xarray   s_trapevent = { 0, sizeof(HANDLE) };
static xarray   s_trapevent_to_dllinfo = { 0, sizeof(winextdll *) };
static context_info *context_info_head;


/*
 * Function definitions. 
 */

/** Initialize the winExtDLL extension agent. */
void
init_winExtDLL(void)
{
    BOOL            result, is_wow64_process = FALSE;
    int             i;
    uint32_t        uptime_reference;
    pfIsWow64Process IsWow64Process;

    DEBUGMSG(("winExtDLL", "init_winExtDLL started.\n"));

    GetVersionEx(&s_versioninfo);

    IsWow64Process =
      (pfIsWow64Process)GetProcAddress(GetModuleHandle("kernel32"),
                                       "IsWow64Process");
    if (IsWow64Process)
        (*IsWow64Process)(GetCurrentProcess(), &is_wow64_process);

    SnmpSvcInitUptime();

    read_extension_dlls_from_registry();

    DEBUGMSG(("winExtDLL",
              "init_winExtDLL: found %d extension DLLs in the registry.\n",
              s_winextdll.size));

    xarray_reserve(&s_winextdll, 128);

    /*
     * Load all the DLLs 
     */
    for (i = 0; i < s_winextdll.size; i++) {
        winextdll      *const ext_dll_info = &WINEXTDLL(i);
        AsnObjectIdentifier view;
        winextdll_view  ext_dll_view_info;

        netsnmp_assert(ext_dll_info);
        if (!ext_dll_info->dll_name)
            continue;

        DEBUGMSG(("winExtDLL", "loading DLL %s.\n",
                  ext_dll_info->dll_name));
        ext_dll_info->dll_handle = LoadLibrary(ext_dll_info->dll_name);

        if (ext_dll_info->dll_handle == NULL) {
            const DWORD     dwErrorcode = GetLastError();
            LPTSTR          lpMsgBuf;

            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                          FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErrorcode,
                          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                          (LPTSTR) & lpMsgBuf, 0, NULL);
            if (lpMsgBuf) {
                LPTSTR          p;

                /*
                 * Remove trailing "\r\n".
                 */
                p = strchr(lpMsgBuf, '\r');
                if (p)
                    *p = '\0';
            }
            snmp_log(LOG_ERR,
                     "init_winExtDLL: could not load SNMP extension"
                     " DLL %s: %s\n",
                     ext_dll_info->dll_name, lpMsgBuf ? lpMsgBuf : "(?)");
            if (lpMsgBuf)
                LocalFree(lpMsgBuf);
            continue;
        }

        /*
         * Store DLL name and functions in s_extension_dll_info array. 
         */
        ext_dll_info->pfSnmpExtensionInit = (PFNSNMPEXTENSIONINIT)
            GetProcAddress(ext_dll_info->dll_handle, "SnmpExtensionInit");
        ext_dll_info->pfSnmpExtensionInitEx = (PFNSNMPEXTENSIONINITEX)
            GetProcAddress(ext_dll_info->dll_handle,
                           "SnmpExtensionInitEx");
        ext_dll_info->pfSnmpExtensionClose = (PFNSNMPEXTENSIONCLOSE)
            GetProcAddress(ext_dll_info->dll_handle, "SnmpExtensionClose");
        ext_dll_info->pfSnmpExtensionQuery = (PFNSNMPEXTENSIONQUERY)
            GetProcAddress(ext_dll_info->dll_handle, "SnmpExtensionQuery");
        ext_dll_info->pfSnmpExtensionQueryEx = (PFNSNMPEXTENSIONQUERYEX)
            GetProcAddress(ext_dll_info->dll_handle,
                           "SnmpExtensionQueryEx");
        ext_dll_info->pfSnmpExtensionTrap = (PFNSNMPEXTENSIONTRAP)
            GetProcAddress(ext_dll_info->dll_handle, "SnmpExtensionTrap");


        if (ext_dll_info->pfSnmpExtensionQuery == NULL
            && ext_dll_info->pfSnmpExtensionQueryEx == NULL) {
            snmp_log(LOG_ERR,
                     "error in extension DLL %s: SNMP query function missing.\n",
                     ext_dll_info->dll_name);
        }

        /*
         * At least on a 64-bit Windows 7 system invoking SnmpExtensionInit()
         * in the 32-bit version of evntagnt.dll hangs. Also, all queries in
         * lmmib2.dll fail with "generic error" on a 64-bit Windows 7 system.
         * So skip these two DLLs.
         */
        if (s_versioninfo.dwMajorVersion >= 6
            && ((is_wow64_process
                 && basename_equals(ext_dll_info->dll_name, "evntagnt.dll"))
                || basename_equals(ext_dll_info->dll_name, "lmmib2.dll"))) {
            DEBUGMSG(("winExtDLL", "init_winExtDLL: skipped DLL %s.\n",
                      ext_dll_info->dll_name));
            continue;
        }

        /*
         * Init and get first supported view from Windows SNMP extension DLL.
         * Note: although according to the documentation of SnmpExtensionInit()
         * the first argument of this function should be ignored by extension
         * DLLs, passing a correct value for this first argument is necessary
         * to make inetmib1.dll work correctly. Passing zero as the first
         * argument causes inetmib1.dll to report an incorrect value for
         * sysUpTime.0 and also causes the same DLL not to send linkUp or
         * linkDown traps.
         */
        ext_dll_info->subagentTrapEvent = NULL;
        view.idLength = 0;
        view.ids = NULL;
        if (!is_wow64_process && s_versioninfo.dwMajorVersion >= 6)
            uptime_reference = GetTickCount() - 10 * SnmpSvcGetUptime();
        else
            uptime_reference = GetTickCount() / 10;
        result =
            ext_dll_info->pfSnmpExtensionInit(uptime_reference,
                                              &ext_dll_info->
                                              subagentTrapEvent, &view);

        if (!result) {
            DEBUGMSG(("winExtDLL",
                      "init_winExtDLL: initialization of DLL %s failed.\n",
                      ext_dll_info->dll_name));
            /*
             * At least on Windows 7 SnmpExtensionInit() in some extension
             * agent DLLs returns "FALSE" although initialization
             * succeeded. Hence ignore the SnmpExtensionInit() return value on
             * Windows Vista and later.
             */
            if (s_versioninfo.dwMajorVersion < 6) {
                snmp_log(LOG_ERR,
                         "init_winExtDLL: initialization of DLL %s failed.\n",
                         ext_dll_info->dll_name);
                FreeLibrary(ext_dll_info->dll_handle);
                ext_dll_info->dll_handle = 0;
                continue;
            }
        }

        if (ext_dll_info->subagentTrapEvent != NULL) {
            xarray_push_back(&s_trapevent,
                             &ext_dll_info->subagentTrapEvent);
            xarray_push_back(&s_trapevent_to_dllinfo, &ext_dll_info);
        }

        memset(&ext_dll_view_info, 0, sizeof(ext_dll_view_info));
        ext_dll_view_info.winextdll_info = ext_dll_info;
        if (view.idLength == 0) {
            DEBUGMSG(("winExtDLL",
                      "init_winExtDLL: DLL %s did not register an OID range.\n",
                      ext_dll_info->dll_name));
            continue;
        }
        /*
         * Skip the mib-2 system section on Windows Vista and later because
         * at least on a 64-bit Windows 7 system all queries in that section
         * fail with status "generic error".
         */
        if (s_versioninfo.dwMajorVersion >= 6
            && snmp_oid_compare_w_n(view.ids, view.idLength, mibii_system_mib,
                                    sizeof(mibii_system_mib) /
                                    sizeof(mibii_system_mib[0])) == 0) {
            DEBUGMSG(("winExtDLL",
                      "init_winExtDLL: skipping system section of DLL %s.\n",
                      ext_dll_info->dll_name));
            continue;
        }
        copy_oid_n_w(ext_dll_view_info.name, &ext_dll_view_info.name_length,
                     view.ids, view.idLength);
        xarray_push_back(&s_winextdll_view, &ext_dll_view_info);

        /*
         * Loop looking for more supported views. 
         */
        while (ext_dll_info->pfSnmpExtensionInitEx
               && ext_dll_info->pfSnmpExtensionInitEx(&view)) {
            memset(&ext_dll_view_info, 0, sizeof(ext_dll_view_info));
            ext_dll_view_info.winextdll_info = ext_dll_info;
            copy_oid_n_w(ext_dll_view_info.name,
                         &ext_dll_view_info.name_length, view.ids,
                         view.idLength);
            xarray_push_back(&s_winextdll_view, &ext_dll_view_info);
        }
    }

    /*
     * Note: since register_netsnmp_handler() writes a pointer to the
     * winextdll_view in one of the Net-SNMP data structures, it is not
     * allowed to move winextdll_view data structures in memory after
     * registration with Net-SNMP. Or: register_snmp_handler() must be called
     * only once it is sure that the size of array s_winextdll_view won't change
     * anymore.
     */
    for (i = 0; i < s_winextdll_view.size; i++)
        register_netsnmp_handler(&WINEXTDLL_VIEW(i));

    DEBUGMSG(("winExtDLL",
              "init_winExtDLL: registered %d OID ranges.\n",
              s_winextdll_view.size));

    /*
     * Let Net-SNMP call subagentTrapCheck() once per second. 
     */
    if (s_trapevent.size)
        snmp_alarm_register(1, SA_REPEAT, subagentTrapCheck, NULL);

    DEBUGMSG(("winExtDLL", "init_winExtDLL finished.\n"));
}

void
shutdown_winExtDLL(void)
{
    int             i;

    DEBUGMSG(("winExtDLL", "shutdown_winExtDLL() started.\n"));

    for (i = s_winextdll_view.size - 1; i >= 0; i--) {
        winextdll_view *const v = &WINEXTDLL_VIEW(i);
        if (v && v->my_handler) {
            DEBUGIF("winExtDLL") {
                DEBUGMSG(("winExtDLL",
                          "unregistering handler for DLL %s and OID prefix ",
                          v->winextdll_info->dll_name));
                DEBUGMSGOID(("winExtDLL", v->name, v->name_length));
                DEBUGMSG(("winExtDLL", " ("));
                DEBUGMSGSUBOID(("winExtDLL", v->name, v->name_length));
                DEBUGMSG(("winExtDLL", ").\n"));
            }
            netsnmp_unregister_handler(v->my_handler);
        }
    }
    xarray_destroy(&s_winextdll_view);

    for (i = s_winextdll.size - 1; i >= 0; i--) {
        winextdll      *const ext_dll_info = &WINEXTDLL(i);
        if (ext_dll_info->dll_handle) {
            if (ext_dll_info->pfSnmpExtensionClose) {
                DEBUGMSG(("winExtDLL", "closing %s.\n",
                          ext_dll_info->dll_name));
                ext_dll_info->pfSnmpExtensionClose();
            }
            /*
             * Freeing the Broadcom SNMP extension libraries triggers
             * a deadlock, so skip bcmif.dll and baspmgnt.dll.
             */
            if (!basename_equals(ext_dll_info->dll_name, "bcmif.dll")
                && !basename_equals(ext_dll_info->dll_name, "baspmgnt.dll")) {
                DEBUGMSG(("winExtDLL", "unloading %s.\n",
                          ext_dll_info->dll_name));
                FreeLibrary(ext_dll_info->dll_handle);
            }
        }
        free(ext_dll_info->dll_name);
    }
    xarray_destroy(&s_winextdll);

    xarray_destroy(&s_trapevent_to_dllinfo);

    xarray_destroy(&s_trapevent);

    DEBUGMSG(("winExtDLL", "shutdown_winExtDLL() finished.\n"));
}

/**
 * Compare the basename of a path with a given string.
 *
 * @return 1 if the basename matches, 0 if not.
 */
static int
basename_equals(const char *path, const char *basename)
{
    const size_t    path_len = strlen(path);
    const size_t    basename_len = strlen(basename);

    netsnmp_assert(strchr(path, '/') == 0);
    netsnmp_assert(strchr(basename, '/') == 0);
    netsnmp_assert(strchr(basename, '\\') == 0);

    return path_len >= basename_len + 1
        && path[path_len - basename_len - 1] == '\\'
        && stricmp(path + path_len - basename_len, basename) == 0;
}

/**
 * Register a single OID subtree with Net-SNMP.
 *
 * @return 1 if successful, 0 if not.
 */
int
register_netsnmp_handler(winextdll_view * const ext_dll_view_info)
{
    winextdll      *ext_dll_info;
    winextdll_view *previously_registered_view;

    ext_dll_info = ext_dll_view_info->winextdll_info;

    previously_registered_view
        = lookup_view_by_oid(ext_dll_view_info->name,
                             ext_dll_view_info->name_length);

    if (previously_registered_view) {
        size_t          oid_namelen, outlen;
        char           *oid_name;
        int             buffer_large_enough;

        oid_namelen = 0;
        outlen = 0;
        oid_name = NULL;
        buffer_large_enough =
            sprint_realloc_objid((u_char **) & oid_name, &oid_namelen,
                                 &outlen, 1, ext_dll_view_info->name,
                                 ext_dll_view_info->name_length);
        snmp_log(LOG_INFO, "OID range %s%s: replacing handler %s by %s.\n",
                 oid_name ? oid_name : "",
                 buffer_large_enough ? "" : " [TRUNCATED]",
                 previously_registered_view->winextdll_info->dll_name,
                 ext_dll_view_info->winextdll_info->dll_name);
        if (oid_name)
            free(oid_name);

        previously_registered_view->winextdll_info = ext_dll_info;
        memset(ext_dll_view_info, 0, sizeof(*ext_dll_view_info));
        return 1;
    } else {
        // Create handler registration
        ext_dll_view_info->my_handler
            = netsnmp_create_handler_registration(ext_dll_info->dll_name,
                                                  var_winExtDLL,
                                                  ext_dll_view_info->name,
                                                  ext_dll_view_info->
                                                  name_length,
                                                  HANDLER_CAN_RWRITE);

        if (ext_dll_view_info->my_handler) {
            ext_dll_view_info->my_handler->handler->myvoid =
                ext_dll_view_info;
            if (netsnmp_register_handler(ext_dll_view_info->my_handler)
                == MIB_REGISTERED_OK) {
                DEBUGIF("winExtDLL") {
                    DEBUGMSG(("winExtDLL",
                              "registering handler for DLL %s and OID prefix ",
                              ext_dll_info->dll_name));
                    DEBUGMSGOID(("winExtDLL", ext_dll_view_info->name,
                                 ext_dll_view_info->name_length));
                    DEBUGMSG(("winExtDLL", " ("));
                    DEBUGMSGSUBOID(("winExtDLL", ext_dll_view_info->name,
                                    ext_dll_view_info->name_length));
                    DEBUGMSG(("winExtDLL", ").\n"));
                }
                return 1;
            } else {
                snmp_log(LOG_ERR, "handler registration failed.\n");
                ext_dll_view_info->my_handler = 0;
            }
        } else {
            snmp_log(LOG_ERR, "handler creation failed.\n");
        }
    }

    return 0;
}

/**
 * Allocate SNMP extension DLL context information. Such context information
 * is necessary to allow an extension DLL to process a set request.
 *
 * @param[in] index Varbind index in original PDU.
 *
 * @return NULL if context information for the specified index was already
 *   allocated, and otherwise a pointer to the newly allocated context
 *   information.
 */
static context_info *
alloc_context_info(const int index)
{
    context_info   *p;

    DEBUGMSG(("winExtDLL:context_info", "alloc_context_info(%d)\n",
              index));

    for (p = context_info_head; p; p = p->next) {
        if (p->index == index) {
            netsnmp_assert(FALSE);
            return NULL;
        }
    }

    p = calloc(1, sizeof(context_info));
    p->next = context_info_head;
    context_info_head = p;
    p->index = index;

    return p;
}

/**
 * Deallocate SNMP extension DLL context information.
 *
 * @param[in] index Varbind index in original PDU.
 */
static void
free_context_info(const int index)
{
    context_info  **pprev = &context_info_head;
    context_info   *p;

    DEBUGMSG(("winExtDLL:context_info", "free_context_info(%d)\n", index));

    for (p = context_info_head; p; p = p->next) {
        if (p->index == index) {
            *pprev = p->next;
            free(p);
            break;
        }
        pprev = &p->next;
    }
}

/**
 * Look up SNMP extension DLL context information.
 *
 * @param[in] index Varbind index in original PDU.
 */
static AsnOctetString *
get_context_info(const int index)
{
    context_info   *p;

    DEBUGMSG(("winExtDLL:context_info", "get_context_info(%d)\n", index));

    for (p = context_info_head; p; p = p->next)
        if (p->index == index)
            return &p->context_info;

    netsnmp_assert(FALSE);
    return NULL;
}

static int
var_winExtDLL(netsnmp_mib_handler *handler,
              netsnmp_handler_registration *reginfo,
              netsnmp_agent_request_info *reqinfo,
              netsnmp_request_info *requests)
{
    winextdll_view *const ext_dll_view_info = handler->myvoid;
    winextdll      *ext_dll_info;
    netsnmp_request_info *request;
    UINT            nRequestType;
    int             rc;

    netsnmp_assert(ext_dll_view_info);
    ext_dll_info = ext_dll_view_info->winextdll_info;
#if ! defined(NDEBUG)
    netsnmp_assert(ext_dll_view_info ==
           lookup_view_by_oid(reginfo->rootoid, reginfo->rootoid_len));
#endif

    if (ext_dll_info == 0) {
        DEBUGMSG(("winExtDLL",
                  "internal error: no matching extension DLL found.\n"));
        netsnmp_assert(0);
        return SNMP_ERR_GENERR;
    }

    switch (reqinfo->mode) {
    case MODE_GET:
        nRequestType = SNMP_EXTENSION_GET;
        netsnmp_assert(!context_info_head);
        break;
    case MODE_GETNEXT:
        nRequestType = SNMP_EXTENSION_GET_NEXT;
        netsnmp_assert(!context_info_head);
        break;
    case MODE_SET_RESERVE1:
        nRequestType = SNMP_EXTENSION_SET_TEST;
        break;
    case MODE_SET_RESERVE2:
        return SNMP_ERR_NOERROR;
    case MODE_SET_ACTION:
        return SNMP_ERR_NOERROR;
    case MODE_SET_UNDO:
        nRequestType = SNMP_EXTENSION_SET_UNDO;
        break;
    case MODE_SET_COMMIT:
        nRequestType = SNMP_EXTENSION_SET_COMMIT;
        break;
    case MODE_SET_FREE:
        nRequestType = SNMP_EXTENSION_SET_CLEANUP;
        break;
    default:
        DEBUGMSG(("winExtDLL",
                  "internal error: invalid mode %d.\n", reqinfo->mode));
        netsnmp_assert(0);
        return SNMP_ERR_NOERROR;
    }

    rc = SNMP_ERR_NOERROR;

    for (request = requests; request; request = request->next) {
        netsnmp_variable_list *varbind;
        SnmpVarBindList win_varbinds;
        AsnInteger32    ErrorStatus;
        AsnInteger32    ErrorIndex;
        BOOL            result;
        BOOL            copy_value;

        memset(&win_varbinds, 0, sizeof(win_varbinds));

        if (request->processed || rc != SNMP_ERR_NOERROR)
            goto free_win_varbinds;

        if (reqinfo->mode == MODE_SET_RESERVE1)
            alloc_context_info(request->index);

        varbind = request->requestvb;
        netsnmp_assert(varbind);

        /*
         * Convert the Net-SNMP varbind to a Windows SNMP varbind list.
         */
        rc = convert_to_windows_varbind_list(&win_varbinds, varbind);
        if (rc != SNMP_ERR_NOERROR) {
            DEBUGMSG(("winExtDLL",
                      "converting varbind list to Windows format failed with"
                      " error code %d.\n", request->status));
            netsnmp_request_set_error(requests, rc);
            goto free_win_varbinds;
        }

        netsnmp_assert(win_varbinds.len == 1);

        /*
         * For a GetNext PDU, if the varbind OID comes lexicographically
         * before the root OID of this handler, replace it by the root OID.
         */
        if (reqinfo->mode == MODE_GETNEXT
            && snmp_oid_compare_w_n(win_varbinds.list[0].name.ids,
                                    win_varbinds.list[0].name.idLength,
                                    reginfo->rootoid,
                                    reginfo->rootoid_len) < 0) {
            DEBUGIF("winExtDLL") {
                size_t          oid1_namelen = 0, oid2_namelen = 0, outlen1 = 0,
                                outlen2 = 0;
                char           *oid1_name = NULL, *oid2_name = NULL;
                int             overflow1 = 0, overflow2 = 0;

                netsnmp_static_assert(sizeof(oid) == sizeof(UINT));
                netsnmp_sprint_realloc_objid((u_char **) & oid1_name,
                                             &oid1_namelen, &outlen1, 1,
                                             &overflow1, (const oid *)
                                             win_varbinds.list[0].name.ids,
                                             win_varbinds.list[0].name.idLength);
                netsnmp_sprint_realloc_objid((u_char **) & oid2_name,
                                             &oid2_namelen, &outlen2, 1,
                                             &overflow2, reginfo->rootoid,
                                             reginfo->rootoid_len);
                DEBUGMSG(("winExtDLL",
                          "extension DLL %s: replacing OID %s%s by OID %s%s.\n",
                          ext_dll_info->dll_name,
                          oid1_name, overflow1 ? " [TRUNCATED]" : "",
                          oid2_name, overflow2 ? " [TRUNCATED]" : ""));
                free(oid2_name);
                free(oid1_name);
            }

            SnmpUtilOidFree(&win_varbinds.list[0].name);
            memset(&win_varbinds.list[0].name, 0,
                   sizeof(win_varbinds.list[0].name));
            copy_oid_to_new_windows_oid(&win_varbinds.list[0].name,
                                        reginfo->rootoid,
                                        reginfo->rootoid_len);
        }

        if (ext_dll_info->pfSnmpExtensionQueryEx) {
            result = ext_dll_info->pfSnmpExtensionQueryEx(nRequestType,
                                                          1,
                                                          &win_varbinds,
                                                          get_context_info(request->index),
                                                          &ErrorStatus,
                                                          &ErrorIndex);
        } else if (ext_dll_info->pfSnmpExtensionQuery) {
            result =
                ext_dll_info->pfSnmpExtensionQuery((BYTE) nRequestType,
                                                   &win_varbinds,
                                                   &ErrorStatus,
                                                   &ErrorIndex);
        } else {
            snmp_log(LOG_ERR,
                     "error in extension DLL %s: SNMP query function missing.\n",
                     ext_dll_info->dll_name);
            result = FALSE;
        }

        if (!result) {
            snmp_log(LOG_ERR,
                     "extension DLL %s: SNMP query function failed.\n",
                     ext_dll_info->dll_name);
            rc = SNMP_ERR_GENERR;
            goto free_win_varbinds;
        }

        rc = convert_win_snmp_err(ErrorStatus);
        if (rc != SNMP_ERR_NOERROR) {
            DEBUGIF("winExtDLL") {
                size_t          oid_namelen = 0, outlen = 0;
                char           *oid_name = NULL;
                int             overflow = 0;

                netsnmp_sprint_realloc_objid((u_char **) & oid_name,
                                             &oid_namelen,
                                             &outlen, 1, &overflow,
                                             ext_dll_view_info->name,
                                             ext_dll_view_info->name_length);
                DEBUGMSG(("winExtDLL", "extension DLL %s: SNMP query function"
                          " returned error code %lu (Windows) / %d (Net-SNMP)"
                          " for request type %d, OID %s%s, ASN type %d and"
                          " value %ld.\n",
                          ext_dll_info->dll_name, ErrorStatus, rc, nRequestType,
                          oid_name, overflow ? " [TRUNCATED]" : "",
                          win_varbinds.list[0].value.asnType,
                          win_varbinds.list[0].value.asnValue.number));
                free(oid_name);
            }
            netsnmp_assert(ErrorIndex == 1);
            netsnmp_request_set_error(requests, rc);
            if (rc == SNMP_NOSUCHOBJECT || rc == SNMP_NOSUCHINSTANCE
                || rc == SNMP_ERR_NOSUCHNAME)
                rc = SNMP_ERR_NOERROR;
            goto free_win_varbinds;
        }

        copy_value = FALSE;
        if (reqinfo->mode == MODE_GET)
            copy_value = TRUE;
        else if (reqinfo->mode == MODE_GETNEXT) {
            const SnmpVarBind *win_varbind;

            win_varbind = &win_varbinds.list[0];

            /*
             * Verify whether the OID returned by the extension DLL fits
             * inside the OID range this handler has been registered
             * with. Also compare the OID passed to the extension DLL with
             * the OID returned by the same DLL. If the DLL returned a
             * lexicographically earlier OID, this means that there is no
             * next OID in the MIB implemented by the DLL.
             *
             * Note: for some GetNext requests BoundsChecker will report
             * that the code below accesses a dangling pointer. This is
             * a limitation of BoundsChecker: apparently BoundsChecker is
             * not able to cope with reallocation of memory for
             * win_varbind by an SNMP extension DLL that has not been
             * instrumented by BoundsChecker.
             */
            if (netsnmp_oid_is_subtree_n_w(ext_dll_view_info->name,
                                           ext_dll_view_info->name_length,
                                           win_varbind->name.ids,
                                           win_varbind->name.idLength) == 0
                && snmp_oid_compare_n_w(varbind->name, varbind->name_length,
                                        win_varbind->name.ids,
                                        win_varbind->name.idLength) < 0) {
                /*
                 * Copy the OID returned by the extension DLL to the
                 * Net-SNMP varbind.
                 */
                snmp_set_var_objid_w(varbind,
                                     win_varbind->name.ids,
                                     win_varbind->name.idLength);
                copy_value = TRUE;
            }
        }
        if (copy_value) {
            netsnmp_variable_list *result_vb;

            /*
             * Copy the value returned by the extension DLL to the Net-SNMP
             * varbind.
             */
            result_vb = NULL;
            rc = append_windows_varbind(&result_vb, &win_varbinds.list[0]);
            netsnmp_assert(result_vb || rc != SNMP_ERR_NOERROR);
            if (result_vb) {
                snmp_set_var_typed_value(varbind,
                                         result_vb->type,
                                         result_vb->val.string,
                                         result_vb->val_len);
                snmp_free_varbind(result_vb);
            } else {
                netsnmp_request_set_error(requests, rc);
                goto free_win_varbinds;
            }
        }

free_win_varbinds:
        if (reqinfo->mode == MODE_SET_COMMIT
            || reqinfo->mode == MODE_SET_UNDO
            || reqinfo->mode == MODE_SET_FREE)
            free_context_info(request->index);
        if (win_varbinds.list)
            SnmpUtilVarBindListFree(&win_varbinds);
    }

    return rc;
}

/**
 * Iterate over the SNMP extension DLL information in the registry and store
 * the retrieved information in s_winextdll[].
 *
 * At the time an SNMP extension DLL is installed, some information about the
 * DLL is written to the registry at one of the two following locations:
 * HKLM\SYSTEM\CurrentControlSet\Control\SNMP\Parameters\ExtensionAgents for
 * Windows Vista, Windows 7 and Windows 2008 or
 * HKLM\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ExtensionAgents for
 * earlier Windows versions. Under this key zero or more REG_SZ values are
 * stored with the names of registry keys containing the DLL path.
 */
void
read_extension_dlls_from_registry()
{
    DEBUGMSGTL(("winExtDLL",
                "read_extension_dlls_from_registry called\n"));

    read_extension_dlls_from_registry_at
        ("SYSTEM\\CurrentControlSet\\Services\\SNMP\\Parameters\\ExtensionAgents");
    read_extension_dlls_from_registry_at
        ("SYSTEM\\CurrentControlSet\\Control\\SNMP\\Parameters\\ExtensionAgents");
}

void
read_extension_dlls_from_registry_at(const char *const subkey)
{
    DWORD           retCode;
    HKEY            hKey;
    int             i;
    DWORD           valueSize;
    TCHAR           valueName[MAX_VALUE_NAME];
    DWORD           dataType;
    TCHAR           data[MAX_VALUE_NAME];
    DWORD           dataSize;

    retCode = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey,
                            0, KEY_QUERY_VALUE, &hKey);

    if (retCode == ERROR_SUCCESS) {
        for (i = 0; ; i++) {
            valueSize = sizeof(valueName);
            dataSize = sizeof(data);
            retCode = RegEnumValue(hKey, i, valueName, &valueSize, NULL,
                                   &dataType, (BYTE *) data, &dataSize);

            if (retCode != ERROR_SUCCESS)
                break;
            if (dataType == REG_SZ) {
                winextdll       ext_dll_info;

                memset(&ext_dll_info, 0, sizeof(ext_dll_info));
                ext_dll_info.dll_name =
                    read_extension_dll_path_from_registry(data);
                if (ext_dll_info.dll_name) {
                    xarray_push_back(&s_winextdll, &ext_dll_info);
                    DEBUGMSG(("winExtDLL", "registry key %s: DLL %s.\n",
                              data, ext_dll_info.dll_name));
                }
            }
        }
        RegCloseKey(hKey);
    }
}

/** Store the DLL path in dynamically allocated memory. */
char           *
read_extension_dll_path_from_registry(const TCHAR * keyName)
{
    HKEY            hKey;
    DWORD           key_value_type = 0;
    TCHAR           valueName[MAX_VALUE_NAME];
    DWORD           key_value_size = MAX_VALUE_NAME;
    TCHAR           valueNameExpanded[MAX_VALUE_NAME];
    DWORD           retCode;
    char           *result = 0;

    retCode = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
                            keyName, 0, KEY_QUERY_VALUE, &hKey);

    if (retCode != ERROR_SUCCESS)
        return 0;

    retCode = RegQueryValueExA(hKey,
                               "Pathname",
                               NULL,
                               &key_value_type,
                               (BYTE *) valueName, &key_value_size);

    if (retCode != ERROR_SUCCESS) {
        RegCloseKey(hKey);
        return 0;
    }

    if (key_value_type == REG_EXPAND_SZ) {
        if (ExpandEnvironmentStrings
            (valueName, valueNameExpanded, MAX_VALUE_NAME))
            result = strdup(valueNameExpanded);
    } else if (key_value_type == REG_SZ)
        result = strdup(valueName);

    RegCloseKey(hKey);
    return result;
}

/**
 * Callback function called by the Net-SNMP agent to check for traps waiting
 * to be processed.
 */
void
subagentTrapCheck(unsigned int clientreg, void *clientarg)
{
    while (1) {
        DWORD           dwWaitResult;
        BOOL            bResult;
        int             i;
        int             j;
        const winextdll *ext_dll_info;

        if (s_trapevent.size == 0)
            return;

        dwWaitResult = WaitForMultipleObjects(s_trapevent.size,
                                              &TRAPEVENT(0), FALSE, 0);

        i = dwWaitResult - WAIT_OBJECT_0;
        if (i < 0 || i >= s_trapevent.size) {
            netsnmp_assert(dwWaitResult == WAIT_TIMEOUT);
            return;
        }

        netsnmp_assert(s_trapevent.size == s_trapevent_to_dllinfo.size);
        ext_dll_info = TRAPEVENT_TO_DLLINFO(i);
        netsnmp_assert(ext_dll_info->subagentTrapEvent == TRAPEVENT(i));

        /*
         * Reset the signalled event just in case the extension DLL erroneously
         * allocated a manual-reset event instead of an auto-reset event. It is
         * important to reset the event BEFORE traps are processed, otherwise a
         * race condition is triggered between the extension DLL setting the
         * event and this code resetting the event.
         */
        ResetEvent(TRAPEVENT(i));

        if (!ext_dll_info->pfSnmpExtensionTrap) {
            snmp_log(LOG_ERR,
                     "internal error in SNMP extension DLL %s: a trap is ready"
                     " but the function SnmpExtensionTrap() is missing.\n",
                     ext_dll_info->dll_name);
            return;
        }

        /*
         * Process at most hundred traps per extension DLL. If the extension DLL
         * has more traps waiting, that's probably a bug in the extension DLL.
         */
        for (j = 0; j < 100; j++) {
            AsnObjectIdentifier Enterprise = { 0, NULL };
            AsnInteger      GenericTrap = 0;
            AsnInteger      SpecificTrap = 0;
            AsnTimeticks    TimeStamp = 0;
            SnmpVarBindList TrapVarbinds = { NULL, 0 };

            bResult = ext_dll_info->pfSnmpExtensionTrap(&Enterprise,
                                                        &GenericTrap,
                                                        &SpecificTrap,
                                                        &TimeStamp,
                                                        &TrapVarbinds);

            if (!bResult)
                break;

            send_trap(&Enterprise, GenericTrap, SpecificTrap, TimeStamp,
                      &TrapVarbinds);

            SnmpUtilVarBindListFree(&TrapVarbinds);
        }
    }
}

void
send_trap(const AsnObjectIdentifier * const pEnterprise,
          const AsnInteger GenericTrap,
          const AsnInteger SpecificTrap,
          const AsnTimeticks TimeStamp,
          const SnmpVarBindList * const pTrapVarbinds)
{
    /*
     * A quote from the paragraph in RFC 1908 about SNMPv1 to SNMPv2c
     * trap translation (http://www.ietf.org/rfc/rfc1908.txt):
     * <quote>
     * If a Trap-PDU is received, then it is mapped into a SNMPv2-Trap-
     * PDU.  This is done by prepending onto the variable-bindings field
     * two new bindings:  sysUpTime.0 [6], which takes its value from the
     * timestamp field of the Trap-PDU; and, snmpTrapOID.0 [6], which is
     * calculated thusly:  if the value of generic-trap field is
     * `enterpriseSpecific', then the value used is the concatenation of
     * the enterprise field from the Trap-PDU with two additional sub-
     * identifiers, `0', and the value of the specific-trap field;
     * otherwise, the value of the corresponding trap defined in [6] is
     * used.
     * </quote>
     *
     * Reference [6] refers to RFC 1907 (http://www.ietf.org/rfc/rfc1907.txt),
     * where the generic trap OIDs have been defined as follows:
     * coldStart             ::= { snmpTraps 1 }
     * warmStart             ::= { snmpTraps 2 }
     * linkDown              ::= { snmpTraps 3 }
     * linkUp                ::= { snmpTraps 4 }
     * authenticationFailure ::= { snmpTraps 5 }
     * egpNeighborLoss       ::= { snmpTraps 6 }
     */
    static const oid sysuptime_oid[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
    static const size_t sysuptime_oid_len = OID_LENGTH(sysuptime_oid);

    static const oid snmptrap_oid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
    static const size_t snmptrap_oid_len = OID_LENGTH(snmptrap_oid);

    static const oid snmptraps_oid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 5 };
    static const size_t snmptraps_oid_len = OID_LENGTH(snmptraps_oid);

    oid             vb2_oid[MAX_OID_LEN];
    size_t          vb2_oid_len;

    netsnmp_variable_list *notification_vars = NULL;


    /*
     * Append the varbind (sysUpTime.0, TimeStamp). 
     */
    snmp_varlist_add_variable(&notification_vars,
                              sysuptime_oid, sysuptime_oid_len,
                              ASN_TIMETICKS,
                              (const u_char *) &TimeStamp,
                              sizeof(TimeStamp));

    if (GenericTrap == SNMP_GENERICTRAP_ENTERSPECIFIC) {
        /*
         * Enterprise specific trap: compute the OID
         * *pEnterprise + ".0." + SpecificTrap.
         */
        copy_oid_n_w(vb2_oid, &vb2_oid_len,
                     pEnterprise->ids, pEnterprise->idLength);
        vb2_oid[vb2_oid_len++] = 0;
        vb2_oid[vb2_oid_len++] = SpecificTrap;
    } else {
        /*
         * Generic trap: compute the OID snmpTraps + "." + GenericTrap.
         * Since the GenericTrap values are those defined in SNMPv1, since
         * these values start at zero, and since the corresponding values in
         * SNMPv2 start at one, translate the GenericTrap value accordingly.
         * See also http://www.ietf.org/rfc/rfc1214.txt and
         * http://www.ietf.org/rfc/rfc3418.txt.
         */
        copy_oid(vb2_oid, &vb2_oid_len, snmptraps_oid, snmptraps_oid_len);
        vb2_oid[vb2_oid_len++] = GenericTrap + 1;
    }

    /*
     * Append the varbind (snmpTrap, vb2_oid). 
     */
    snmp_varlist_add_variable(&notification_vars,
                              snmptrap_oid, snmptrap_oid_len,
                              ASN_OBJECT_ID,
                              (u_char *) vb2_oid,
                              vb2_oid_len * sizeof(vb2_oid[0]));

    /*
     * Append all the varbinds in pTrapVarbinds. 
     */
    append_windows_varbind_list(&notification_vars, pTrapVarbinds);

    /*
     * Send trap. 
     */
    send_v2trap(notification_vars);

    /*
     * Free the memory allocated for notification_vars. 
     */
    snmp_free_varbind(notification_vars);
}

/**
 * Convert a Windows varbind to a Net-SNMP varbind and add it to the list of
 * varbinds 'net_snmp_varbinds'.
 *
 * @note The memory allocated inside this function must be freed by the caller
 *   as follows: snmp_free_varbind(*net_snmp_varbinds).
 */
static int
append_windows_varbind_list(netsnmp_variable_list **
                            const net_snmp_varbinds,
                            const SnmpVarBindList * const win_varbinds)
{
    int             i, status = SNMP_ERR_NOERROR;

    for (i = 0; i < win_varbinds->len; i++) {
        status =
            append_windows_varbind(net_snmp_varbinds,
                                   &win_varbinds->list[i]);
        if (status != SNMP_ERR_NOERROR)
            break;
    }
    return status;
}

static int
append_windows_varbind(netsnmp_variable_list ** const net_snmp_varbinds,
                       const SnmpVarBind * const win_varbind)
{
    switch (win_varbind->value.asnType) {
    case MS_ASN_INTEGER:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_INTEGER,
                                    &win_varbind->value.asnValue.number,
                                    sizeof(win_varbind->value.asnValue.
                                           number));
        break;
    case MS_ASN_BITS:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_BIT_STR,
                                    win_varbind->value.asnValue.bits.stream,
                                    win_varbind->value.asnValue.bits.length);
        break;
    case MS_ASN_OCTETSTRING:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_OCTET_STR,
                                    win_varbind->value.asnValue.string.
                                    stream,
                                    win_varbind->value.asnValue.string.
                                    length);
        break;
    case MS_ASN_NULL:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_NULL, 0, 0);
        break;
    case MS_ASN_OBJECTIDENTIFIER:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_OBJECT_ID,
                                    win_varbind->value.asnValue.
                                    object.ids,
                                    win_varbind->value.asnValue.object.
                                    idLength * sizeof(oid));
        break;

        /*
         * MS_ASN_INTEGER32: synonym for MS_ASN_INTEGER. 
         */

    case MS_ASN_SEQUENCE:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_SEQUENCE,
                                    win_varbind->value.asnValue.sequence.
                                    stream,
                                    win_varbind->value.asnValue.sequence.
                                    length);
        break;
    case MS_ASN_IPADDRESS:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_IPADDRESS,
                                    win_varbind->value.asnValue.address.
                                    stream,
                                    win_varbind->value.asnValue.address.
                                    length);
        break;
    case MS_ASN_COUNTER32:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_COUNTER,
                                    &win_varbind->value.asnValue.counter,
                                    sizeof(win_varbind->value.asnValue.
                                           counter));
        break;
    case MS_ASN_GAUGE32:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_GAUGE,
                                    &win_varbind->value.asnValue.gauge,
                                    sizeof(win_varbind->value.asnValue.
                                           gauge));
        break;
    case MS_ASN_TIMETICKS:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_TIMETICKS,
                                    &win_varbind->value.asnValue.ticks,
                                    sizeof(win_varbind->value.asnValue.
                                           ticks));
        break;
    case MS_ASN_OPAQUE:        // AsnOctetString
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_OPAQUE,
                                    win_varbind->value.asnValue.arbitrary.
                                    stream,
                                    win_varbind->value.asnValue.arbitrary.
                                    length);
        break;
    case MS_ASN_COUNTER64:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_COUNTER64,
                                    &win_varbind->value.asnValue.counter64,
                                    sizeof(win_varbind->value.asnValue.
                                           counter64));
        break;
    case MS_ASN_UINTEGER32:
        snmp_varlist_add_variable_w(net_snmp_varbinds, win_varbind->name.ids,
                                    win_varbind->name.idLength,
                                    ASN_UNSIGNED,
                                    &win_varbind->value.asnValue.unsigned32,
                                    sizeof(win_varbind->value.asnValue.
                                           unsigned32));
        break;
    default:
        return SNMP_ERR_GENERR;
    }

    return SNMP_ERR_NOERROR;
}

static int
snmp_set_var_objid_w(netsnmp_variable_list * var, const UINT * name,
                     UINT name_length)
{
    netsnmp_static_assert(sizeof(oid) == sizeof(UINT));
    return snmp_set_var_objid(var, (const oid *) name, name_length);
}

static netsnmp_variable_list *
snmp_varlist_add_variable_w(netsnmp_variable_list ** varlist, const UINT * name,
                            UINT name_length, u_char type, const void * value,
                            size_t len)
{
    netsnmp_static_assert(sizeof(oid) == sizeof(UINT));
    return snmp_varlist_add_variable(varlist, (const oid *) name, name_length, type,
                                     value, len);
}

/**
 * Convert a Net-SNMP varbind to a WinSNMP varbind list.
 *
 * @param[out] pVarBindList WinSNMP varbind list, initialized by this
 *               function.
 * @param[in]  varbind Net-SNMP varbind.
 */
int
convert_to_windows_varbind_list(SnmpVarBindList * pVarBindList,
                                netsnmp_variable_list * varbind)
{
    SnmpVarBind    *win_varbind;

    netsnmp_assert(pVarBindList);
    netsnmp_assert(varbind);

    pVarBindList->len = 1;
    pVarBindList->list
        = (SnmpVarBind *) SnmpUtilMemAlloc(pVarBindList->len
                                           *
                                           sizeof(pVarBindList->list[0]));
    if (pVarBindList->list == 0)
        goto generr;

    memset(&pVarBindList->list[0], 0, sizeof(pVarBindList->list[0]));

    win_varbind = &pVarBindList->list[0];

    if (varbind->name
        && !copy_oid_to_new_windows_oid(&win_varbind->name,
                                        varbind->name,
                                        varbind->name_length))
        goto generr;

    switch (varbind->type) {
    case ASN_BOOLEAN:
        // There is no equivalent type in Microsoft's <snmp.h>.
        netsnmp_assert(0);
        win_varbind->value.asnType = MS_ASN_INTEGER;
        win_varbind->value.asnValue.number = *(varbind->val.integer);
        break;
    case ASN_INTEGER:
        win_varbind->value.asnType = MS_ASN_INTEGER;
        win_varbind->value.asnValue.number = *(varbind->val.integer);
        break;
    case ASN_BIT_STR:
        win_varbind->value.asnType = MS_ASN_BITS;
        win_varbind->value.asnValue.string.stream
            = winsnmp_memdup(varbind->val.string, varbind->val_len);
        win_varbind->value.asnValue.string.length =
            (UINT) (varbind->val_len);
        win_varbind->value.asnValue.string.dynamic = TRUE;
        break;
    case ASN_OCTET_STR:
        win_varbind->value.asnType = MS_ASN_OCTETSTRING;
        win_varbind->value.asnValue.string.stream
            = winsnmp_memdup(varbind->val.string, varbind->val_len);
        win_varbind->value.asnValue.string.length =
            (UINT) (varbind->val_len);
        win_varbind->value.asnValue.string.dynamic = TRUE;
        break;
    case ASN_NULL:
        win_varbind->value.asnType = MS_ASN_NULL;
        memset(&win_varbind->value, 0, sizeof(win_varbind->value));
        break;
    case ASN_OBJECT_ID:
        win_varbind->value.asnType = MS_ASN_OBJECTIDENTIFIER;
        if (!copy_oid_to_new_windows_oid
            (&win_varbind->value.asnValue.object, varbind->val.objid,
             varbind->val_len / sizeof(varbind->val.objid[0])))
            return SNMP_ERR_GENERR;
        break;
    case ASN_SEQUENCE:
        win_varbind->value.asnType = MS_ASN_SEQUENCE;
        win_varbind->value.asnValue.string.stream
            = winsnmp_memdup(varbind->val.string, varbind->val_len);
        win_varbind->value.asnValue.string.length =
            (UINT) (varbind->val_len);
        win_varbind->value.asnValue.string.dynamic = TRUE;
        break;
    case ASN_SET:
        // There is no equivalent type in Microsoft's <snmp.h>.
        netsnmp_assert(0);
        win_varbind->value.asnType = MS_ASN_INTEGER;
        win_varbind->value.asnValue.number = *(varbind->val.integer);
        break;
    case ASN_IPADDRESS:
        win_varbind->value.asnType = MS_ASN_IPADDRESS;
        win_varbind->value.asnValue.string.stream
            = winsnmp_memdup(varbind->val.string, varbind->val_len);
        win_varbind->value.asnValue.string.length =
            (UINT) (varbind->val_len);
        win_varbind->value.asnValue.string.dynamic = TRUE;
        break;
    case ASN_COUNTER:
        win_varbind->value.asnType = MS_ASN_COUNTER32;
        win_varbind->value.asnValue.counter = *(varbind->val.integer);
        break;
        /*
         * ASN_GAUGE == ASN_UNSIGNED 
         */
    case ASN_UNSIGNED:
        win_varbind->value.asnType = MS_ASN_UNSIGNED32;
        win_varbind->value.asnValue.unsigned32 = *(varbind->val.integer);
        break;
    case ASN_TIMETICKS:
        win_varbind->value.asnType = MS_ASN_TIMETICKS;
        win_varbind->value.asnValue.ticks = *(varbind->val.integer);
        break;
    case ASN_OPAQUE:
        win_varbind->value.asnType = MS_ASN_OPAQUE;
        win_varbind->value.asnValue.string.stream
            = winsnmp_memdup(varbind->val.string, varbind->val_len);
        win_varbind->value.asnValue.string.length =
            (UINT) (varbind->val_len);
        win_varbind->value.asnValue.string.dynamic = TRUE;
        break;
    case ASN_COUNTER64:
        win_varbind->value.asnType = MS_ASN_COUNTER64;
        win_varbind->value.asnValue.counter64.HighPart
            = varbind->val.counter64->high;
        win_varbind->value.asnValue.counter64.LowPart
            = varbind->val.counter64->low;
        break;
    default:
        netsnmp_assert(0);
        goto generr;
    }

    return SNMP_ERR_NOERROR;

  generr:
    SnmpUtilVarBindListFree(pVarBindList);
    memset(pVarBindList, 0, sizeof(*pVarBindList));
    return SNMP_ERR_GENERR;
}

/** Convert a Windows SNMP error code to the equivalent Net-SNMP error code. */
int
convert_win_snmp_err(const int win_snmp_err)
{
    switch (win_snmp_err) {
    case SNMP_ERRORSTATUS_NOERROR:
        return SNMP_ERR_NOERROR;
    case SNMP_ERRORSTATUS_TOOBIG:
        return SNMP_ERR_TOOBIG;
    case SNMP_ERRORSTATUS_NOSUCHNAME:
        /*
         * Note: SNMP extension DLLs return SNMP_ERRORSTATUS_NOSUCHNAME
         * when either noSuchObject or noSuchInstance should be returned to
         * the SNMP manager (assuming SNMPv2c or SNMPv3). Unfortunately it
         * is not possible without consulting the MIB to find out whether
         * either SNMP_NOSUCHINSTANCE or SNMP_NOSUCHOBJECT should be returned.
         * See also RFC 1448.
         */
        return SNMP_NOSUCHINSTANCE;
    case SNMP_ERRORSTATUS_BADVALUE:
        return SNMP_ERR_BADVALUE;
    case SNMP_ERRORSTATUS_READONLY:
        return SNMP_ERR_READONLY;
    case SNMP_ERRORSTATUS_GENERR:
        return SNMP_ERR_GENERR;
    case SNMP_ERRORSTATUS_NOACCESS:
        return SNMP_ERR_NOACCESS;
    case SNMP_ERRORSTATUS_WRONGTYPE:
        return SNMP_ERR_WRONGTYPE;
    case SNMP_ERRORSTATUS_WRONGLENGTH:
        return SNMP_ERR_WRONGLENGTH;
    case SNMP_ERRORSTATUS_WRONGENCODING:
        return SNMP_ERR_WRONGENCODING;
    case SNMP_ERRORSTATUS_WRONGVALUE:
        return SNMP_ERR_WRONGVALUE;
    case SNMP_ERRORSTATUS_NOCREATION:
        return SNMP_ERR_NOCREATION;
    case SNMP_ERRORSTATUS_INCONSISTENTVALUE:
        return SNMP_ERR_INCONSISTENTVALUE;
    case SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE:
        return SNMP_ERR_RESOURCEUNAVAILABLE;
    case SNMP_ERRORSTATUS_COMMITFAILED:
        return SNMP_ERR_COMMITFAILED;
    case SNMP_ERRORSTATUS_UNDOFAILED:
        return SNMP_ERR_UNDOFAILED;
    case SNMP_ERRORSTATUS_AUTHORIZATIONERROR:
        return SNMP_ERR_AUTHORIZATIONERROR;
    case SNMP_ERRORSTATUS_NOTWRITABLE:
        return SNMP_ERR_NOTWRITABLE;
    case SNMP_ERRORSTATUS_INCONSISTENTNAME:
        return SNMP_ERR_INCONSISTENTNAME;
    }
    netsnmp_assert(0);
    return SNMP_ERR_GENERR;
}

/**
 * Look up the extension DLL view that was registered with the given OID.
 */
static winextdll_view *
lookup_view_by_oid(oid * const name, const size_t name_len)
{
    int             i;

    for (i = 0; i < s_winextdll_view.size; i++) {
        if (netsnmp_oid_equals(WINEXTDLL_VIEW(i).name,
                               WINEXTDLL_VIEW(i).name_length,
                               name, name_len) == 0
            && WINEXTDLL_VIEW(i).my_handler) {
            return &WINEXTDLL_VIEW(i);
        }
    }

    return NULL;
}

static int
snmp_oid_compare_n_w(const oid * name1, size_t len1, const UINT * name2,
                     UINT len2)
{
    netsnmp_static_assert(sizeof(oid) == sizeof(UINT));
    return snmp_oid_compare(name1, len1, (const oid *) name2, len2);
}

static int
snmp_oid_compare_w_n(const UINT * name1, UINT len1, const oid * name2,
                     size_t len2)
{
    netsnmp_static_assert(sizeof(oid) == sizeof(UINT));
    return snmp_oid_compare((const oid *) name1, len1, name2, len2);
}

static int
netsnmp_oid_is_subtree_n_w(const oid * name1, size_t len1, const UINT * name2,
                           UINT len2)
{
    netsnmp_static_assert(sizeof(oid) == sizeof(UINT));
    return netsnmp_oid_is_subtree(name1, len1, (const oid *) name2, len2);
}

/**
 * Copy an OID.
 *
 * @param[out] to_name       Number of elements written to destination OID.
 * @param[out] to_name_len   Length of destination OID. Must have at least
 *                           min(from_name_len, MAX_OID_LEN) elements.
 * @param[in]  from_name     Original OID.
 * @param[in]  from_name_len Length of original OID.
 */
static void
copy_oid(oid * const to_name, size_t * const to_name_len,
         const oid * const from_name, const size_t from_name_len)
{
    int             j;

    netsnmp_assert(to_name);
    netsnmp_assert(to_name_len);
    netsnmp_assert(from_name);

    for (j = 0; j < from_name_len && j < MAX_OID_LEN; j++)
        to_name[j] = from_name[j];

    *to_name_len = j;
}

/**
 * Copy an OID.
 *
 * @param[out] to_name       Number of elements written to destination OID.
 * @param[out] to_name_len   Length of destination OID. Must have at least
 *                           min(from_name_len, MAX_OID_LEN) elements.
 * @param[in]  from_name     Original OID.
 * @param[in]  from_name_len Length of original OID.
 */
static void
copy_oid_n_w(oid * const to_name, size_t * const to_name_len,
             const UINT * const from_name, const UINT from_name_len)
{
    netsnmp_static_assert(sizeof(oid) == sizeof(UINT));
    copy_oid(to_name, to_name_len, (const oid *) from_name, from_name_len);
}

/**
 * Convert a Net-SNMP OID into a Windows OID and allocate memory for the
 * Windows OID.
 *
 * @param[out] windows_oid   Pointer to a AsnObjectIdentifier.
 * @param[in]  name   Pointer to an array with elements of type oid
 *           and length name_len.
 * @param[in]  name_len Number of elements of input and output OID.
 */
static UINT    *
copy_oid_to_new_windows_oid(AsnObjectIdentifier * const windows_oid,
                            const oid * const name, const size_t name_len)
{
    netsnmp_assert(windows_oid);
    netsnmp_assert(windows_oid->ids == 0);
    netsnmp_assert(windows_oid->idLength == 0);
    netsnmp_assert(name);

    windows_oid->ids
        =
        (UINT *) winsnmp_memdup(name,
                                sizeof(windows_oid->ids[0]) * name_len);
    windows_oid->idLength = (UINT) name_len;
    return windows_oid->ids;
}

static u_char  *
winsnmp_memdup(const void *src, const size_t len)
{
    u_char         *p;

    netsnmp_assert(len == (UINT) len);

    p = SnmpUtilMemAlloc((UINT) len);
    if (p)
        memcpy(p, src, len);
    return p;
}

#if 0
/** Initialize array 'a'. */
static void
xarray_init(xarray * a, size_t elem_size)
{
    netsnmp_assert(a);

    memset(a, 0, sizeof(*a));
    a->elem_size = elem_size;
}
#endif

/** Deallocate any memory that was dynamically allocated for 'a'. */
static void
xarray_destroy(xarray * a)
{
    netsnmp_assert(a);

    xarray_reserve(a, 0);
}

/**
 * Append the contents of the address range [ elem, elem + a->elem_size [ to a.
 *
 * Resize a if necessary.
 *
 * @return A pointer to the address where the data has been copied upon success,
 *         or NULL upon failure.
 */
static void    *
xarray_push_back(xarray * a, const void *elem)
{
    netsnmp_assert(a);
    netsnmp_assert(elem);
    netsnmp_assert(a->size <= a->reserved);

    if (a->size == a->reserved)
        xarray_reserve(a, a->reserved == 0 ? 16 : 2 * a->reserved);
    if (a->size < a->reserved) {
        netsnmp_assert(a->size < a->reserved);
        return memcpy((char *) (a->p) + a->elem_size * a->size++, elem,
                      a->elem_size);
    }
    return NULL;
}

#if 0
/** Erase [ elem, elem + a->elem_size [ from a. */
static void
xarray_erase(xarray * a, void *const elem)
{
    netsnmp_assert(a);
    netsnmp_assert(a->size >= 1);
    netsnmp_assert(a->p <= elem);
    netsnmp_assert((const char *) elem + a->elem_size <=
           (char *) a->p + a->size * a->elem_size);
    netsnmp_assert(((const char *) elem - (char *) a->p) % a->elem_size == 0);

    a->size--;
    memmove((char *) elem, (char *) elem + a->elem_size,
            a->size - ((const char *) elem -
                       (char *) a->p) / a->elem_size);
}
#endif

/**
 * Change the number of allocated elements to 'reserved'.
 *
 * Can be used either for enlarging or for shrinking the memory allocated for
 * 'a'. Does not modify 'a' if memory allocation fails. Newly allocted memory
 * is not initialized.
 *
 * @return != NULL upon success, NULL upon failure.
 */
static void    *
xarray_reserve(xarray * a, int reserved)
{
    netsnmp_assert(a);
    netsnmp_assert(a->size <= a->reserved);

    if ((a->p = realloc(a->p, a->elem_size * reserved)))
        a->reserved = reserved;
    else
        a->reserved = 0;
    return a->p;
}

#endif                          /* USING_WINEXTDLL_MODULE */
