/**
 * @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/net-snmp-features.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"

netsnmp_feature_require(oid_is_subtree)


#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;
}

/*
 * Translate Net-SNMP request mode into an SnmpExtensionQuery() PDU type
 * or into an SnmpExtensionQueryEx() request type.
 */
static int
get_request_type(int mode, int request_type, UINT *nRequestType)
{
    switch (request_type) {
    case 0:
        /* SnmpExtensionQuery() PDU type */
        switch (mode) {
        case MODE_GET:
            *nRequestType = SNMP_PDU_GET;
            return 1;
        case MODE_GETNEXT:
            *nRequestType = SNMP_PDU_GETNEXT;
            return 1;
        case MODE_SET_RESERVE1:
            return 0;
        case MODE_SET_RESERVE2:
            return 0;
        case MODE_SET_ACTION:
            return 0;
        case MODE_SET_UNDO:
            return 0;
        case MODE_SET_COMMIT:
            *nRequestType = SNMP_PDU_SET;
            return 1;
        case MODE_SET_FREE:
            return 0;
        default:
            DEBUGMSG(("winExtDLL", "internal error: invalid mode %d.\n", mode));
            netsnmp_assert(0);
            return 0;
        }
    case 1:
        /* SnmpExtensionQueryEx() request type */
        switch (mode) {
        case MODE_GET:
            *nRequestType = SNMP_EXTENSION_GET;
            return 1;
        case MODE_GETNEXT:
            *nRequestType = SNMP_EXTENSION_GET_NEXT;
            return 1;
        case MODE_SET_RESERVE1:
            *nRequestType = SNMP_EXTENSION_SET_TEST;
            return 1;
        case MODE_SET_RESERVE2:
            return 0;
        case MODE_SET_ACTION:
            return 0;
        case MODE_SET_UNDO:
            *nRequestType = SNMP_EXTENSION_SET_UNDO;
            return 1;
        case MODE_SET_COMMIT:
            *nRequestType = SNMP_EXTENSION_SET_COMMIT;
            return 1;
        case MODE_SET_FREE:
            *nRequestType = SNMP_EXTENSION_SET_CLEANUP;
            return 1;
        default:
            DEBUGMSG(("winExtDLL", "internal error: invalid mode %d.\n", mode));
            netsnmp_assert(0);
            return 0;
        }
    default:
        DEBUGMSG(("winExtDLL", "internal error: invalid argument %d.\n",
                  request_type));
        netsnmp_assert(0);
        return 0;
    }
}

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;
    }

    if (!get_request_type(reqinfo->mode, !!ext_dll_info->pfSnmpExtensionQueryEx,
                          &nRequestType)) {
        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 */
