/**
 * @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] == '\\'
        && strcasecmp(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;
    const char     *mode_name;
    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:
        mode_name = "GET";
        nRequestType = SNMP_EXTENSION_GET;
        netsnmp_assert(!context_info_head);
        break;
    case MODE_GETNEXT:
        mode_name = "GETNEXT";
        nRequestType = SNMP_EXTENSION_GET_NEXT;
        netsnmp_assert(!context_info_head);
        break;
    case MODE_SET_RESERVE1:
        mode_name = "SET_RESERVE1";
        nRequestType = SNMP_EXTENSION_SET_TEST;
        break;
    case MODE_SET_RESERVE2:
        mode_name = "SET_RESERVE2";
        return SNMP_ERR_NOERROR;
    case MODE_SET_ACTION:
        mode_name = "SET_ACTION";
        return SNMP_ERR_NOERROR;
    case MODE_SET_UNDO:
        mode_name = "SET_UNDO";
        nRequestType = SNMP_EXTENSION_SET_UNDO;
        break;
    case MODE_SET_COMMIT:
        mode_name = "SET_COMMIT";
        nRequestType = SNMP_EXTENSION_SET_COMMIT;
        break;
    case MODE_SET_FREE:
        mode_name = "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 */
