|
|
/*****************************************************************************\
* MODULE: olesnmp.cpp * * PURPOSE: Implementation of COM interface for SNMP * * Copyright (C) 1997-1998 Microsoft Corporation * * History: * * 08/16/97 paulmo Created * 09/12/97 weihaic Moved to oleprn.dll * \*****************************************************************************/
#include "stdafx.h"
#include <strsafe.h>
#include "oleprn.h"
#include "olesnmp.h"
/////////////////////////////////////////////////////////////////////////////
// CSNMP
CSNMP:: CSNMP( VOID ) { m_SNMPSession = NULL; }
CSNMP:: ~CSNMP( VOID ) { if (m_SNMPSession != NULL) SnmpMgrClose(m_SNMPSession); }
/*****************************************************************************\
* Function: Open * * PURPOSE: COM wrapper for SnmpMgrOpen * * ARGUMENTS: * * bstrHost: Host name or Server Name * bstrCommunity: Community Name * varRetry: Retry times [optional in VB] * varTimeOut: Time out Value (in millisecond) [optional in VB] * * RETURN VALUE: * S_OK: If succeed. * E_INVALIDARG: Invalid argument. It occurs when either varRetry or varTimeOut * can not be converted to a short integer. * E_FAIL: If SNMPMgrOpen fails * * \*****************************************************************************/ STDMETHODIMP CSNMP:: Open( IN BSTR bstrHost, IN BSTR bstrCommunity, IN VARIANT varRetry, IN VARIANT varTimeOut ) { const INT iDefaultRetry = 5; const INT iDefaultTimeOut = 5000; INT iRetry; INT iTimeOut; LPSTR pAnsiHost = NULL; LPSTR pAnsiCommunity = NULL; HRESULT hr = E_FAIL;
// To prevent a second open
if (m_SNMPSession != NULL){ SnmpMgrClose(m_SNMPSession); m_SNMPSession = NULL; }
if (varRetry.vt == VT_ERROR) { iRetry = iDefaultRetry; } else { VARIANT varTemp;
VariantInit (&varTemp); hr = VariantChangeType (&varTemp, &varRetry, 0, VT_I2); if (FAILED (hr)) return Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); iRetry = varTemp.iVal; }
if (varTimeOut.vt == VT_ERROR) { iTimeOut = iDefaultTimeOut; } else { VARIANT varTemp;
VariantInit (&varTemp); hr = VariantChangeType (&varTemp, &varTimeOut, 0, VT_I2); if (FAILED (hr)) return Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); iTimeOut = varTemp.iVal; }
pAnsiHost = MakeNarrow(bstrHost); pAnsiCommunity = MakeNarrow(bstrCommunity);
if (pAnsiHost && pAnsiCommunity) { __try {
m_SNMPSession = SnmpMgrOpen(pAnsiHost, pAnsiCommunity, iTimeOut, iRetry);
} __except(1) {
hr = E_FAIL; } }
LocalFree(pAnsiHost); LocalFree(pAnsiCommunity);
if (m_SNMPSession == NULL) return Error(IDS_FAILED_OPEN_SNMP, IID_ISNMP, E_FAIL);
return S_OK; }
/*****************************************************************************\
* Function: Get * * PURPOSE: Get a value of a SNMP oid * * ARGUMENTS: * * bstrOID: The SNMP Oid in BSTR * pvarValue: The return value for the corresponding Oid * * RETURN VALUE: * S_OK: If succeed. * E_INVALIDARG: Invalid oid. * E_FAIL: If Open method has not been called before * E_OUTOFMEMORY: Out of memory * other: Returns the last error set by SnmpMgrRequest * \*****************************************************************************/ STDMETHODIMP CSNMP:: Get( IN BSTR bstrOID, OUT VARIANT *pvarValue ) { RFC1157VarBindList rfcVarList = {NULL, 0}; AsnInteger asniErrorStatus; AsnInteger asniErrorIndex; HRESULT hr = E_FAIL;
if (m_SNMPSession == NULL) return Error(IDS_NO_SNMP_SESSION, IID_ISNMP, E_FAIL);
if (FAILED (hr = VarListAdd(bstrOID, &rfcVarList))){ Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); goto Cleanup; }
if (!SnmpMgrRequest(m_SNMPSession, ASN_RFC1157_GETREQUEST, &rfcVarList, &asniErrorStatus, &asniErrorIndex)) { hr = SetWinSnmpApiError (GetLastError ()); goto Cleanup; }
if (asniErrorStatus > 0) { hr = SetSnmpScriptError(asniErrorStatus); goto Cleanup; }
hr = RFC1157ToVariant(pvarValue, &rfcVarList.list[0]);
Cleanup: SnmpUtilVarBindListFree(&rfcVarList); return hr; }
/*****************************************************************************\
* Function: GetAsByte * * PURPOSE: Get a value of a SNMP oid as an integer * * ARGUMENTS: * * bstrOID: The SNMP Oid in BSTR * puValue: The return value for the corresponding Oid * * RETURN VALUE: * S_OK: If succeed. * E_INVALIDARG: Invalid oid. * E_FAIL: If Open method has not been called before * E_OUTOFMEMORY: Out of memory * other: Returns the last error set by SnmpMgrRequest * \*****************************************************************************/ STDMETHODIMP CSNMP:: GetAsByte( IN BSTR bstrOID, OUT PUINT puValue ) { RFC1157VarBindList rfcVarList = {NULL, 0}; AsnInteger asniErrorStatus; AsnInteger asniErrorIndex; HRESULT hr = E_FAIL;
if (m_SNMPSession == NULL) return Error(IDS_NO_SNMP_SESSION, IID_ISNMP, E_FAIL);
if (FAILED (hr = VarListAdd(bstrOID, &rfcVarList))){ Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); goto Cleanup; }
if (!SnmpMgrRequest(m_SNMPSession, ASN_RFC1157_GETREQUEST, &rfcVarList, &asniErrorStatus, &asniErrorIndex)) { hr = SetWinSnmpApiError (GetLastError ()); goto Cleanup; }
if (asniErrorStatus > 0) { hr = SetSnmpScriptError(asniErrorStatus); goto Cleanup; }
hr = RFC1157ToUInt(puValue, &rfcVarList.list[0]);
Cleanup: SnmpUtilVarBindListFree(&rfcVarList); return hr; }
/*****************************************************************************\
* Function: GetList * * PURPOSE: Get a list of a SNMP oids * * ARGUMENTS: * * pvarList: The array of SNMP Oids. The type must be a 1D array of BSTRs * pvarValue: The return value for the corresponding Oids, it is 1D array * of Variants * * RETURN VALUE: * S_OK: If succeed. * E_INVALIDARG: Invalid oid or the type of the variant is not a 1D array * E_FAIL: If Open method has not been called before * E_OUTOFMEMORY: Out of memory * other: Returns the last error set by SnmpMgrRequest * \*****************************************************************************/ STDMETHODIMP CSNMP:: GetList( IN VARIANT *pvarList, OUT VARIANT *pvarValue ) { RFC1157VarBindList rfcVarList = {NULL, 0}; AsnInteger asniErrorStatus; AsnInteger asniErrorIndex; HRESULT hr = E_FAIL; SAFEARRAY *psa,*psaOut = NULL; SAFEARRAYBOUND rgsabound[1]; long lbound, ubound, half, step; VARIANT var; BOOL bFound; BOOL bTooBig;
// Check if Open Method has been called
if (m_SNMPSession == NULL) return (Error(IDS_NO_SNMP_SESSION, IID_ISNMP, E_FAIL));
// Validate the input variable
if (!(pvarList->vt & VT_ARRAY)) return (Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG));
if (pvarList->vt & VT_BYREF) psa = *(pvarList->pparray); else psa = pvarList->parray;
if (SafeArrayGetDim(psa)!=1) return (Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG));
// Get the array boundary
SafeArrayGetLBound(psa, 1, &lbound); SafeArrayGetUBound(psa, 1, &ubound);
VariantInit(pvarValue); VariantInit(&var);
// Alloc the destination array
rgsabound[0].lLbound = 0; rgsabound[0].cElements = ubound - lbound + 1;
if (! (psaOut = SafeArrayCreate(VT_VARIANT, 1, rgsabound))) { hr = Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY); goto Cleanup; }
// Try to determine the size of data we can put into one call
half = ubound;
bFound = FALSE; while (!bFound) {
bTooBig = FALSE;
// Convert items of the array to rfcVarList
hr = VarToRfcVarList (lbound, half, psa, &rfcVarList); if (FAILED (hr)) goto Cleanup;
if (! SnmpMgrRequest(m_SNMPSession, ASN_RFC1157_GETREQUEST, &rfcVarList, &asniErrorStatus, &asniErrorIndex)) {
if (GetLastError() != ERROR_NOT_ENOUGH_MEMORY) { // SNMP call fails. Setup error and return
hr = SetWinSnmpApiError (GetLastError ()); goto Cleanup; } else bTooBig = TRUE; }
if (asniErrorStatus > 0) { // SNMP call succeeds but the returned status if wrong
if (asniErrorStatus != SNMP_ERRORSTATUS_TOOBIG) { // Other errors occur in the call, setup error and return
hr = SetSnmpScriptError(asniErrorStatus); goto Cleanup; } else bTooBig = TRUE; }
if (bTooBig){ // The size of input is too big, reduce it again
if (half - lbound < 2) { // Something must be wrong, quit
hr = SetSnmpScriptError(asniErrorStatus); goto Cleanup; } else { // Divdie the size by 2
half = (lbound + half) / 2; } } else { // We've found the proper steps and also got the first portion
// Save them to the destination safe array psaout
hr = RfcToVarList (lbound, &rfcVarList, psaOut); if (FAILED (hr)) goto Cleanup;
bFound = TRUE; } SnmpUtilVarBindListFree(&rfcVarList); rfcVarList.list = NULL; rfcVarList.len = 0; }
step = half - lbound; for (lbound = half + 1; lbound <= ubound; lbound += step) { half = lbound + step; if (half > ubound) half = ubound;
hr = VarToRfcVarList (lbound, half, psa, &rfcVarList); if (FAILED (hr)) goto Cleanup;
if (! SnmpMgrRequest(m_SNMPSession, ASN_RFC1157_GETREQUEST, &rfcVarList, &asniErrorStatus, &asniErrorIndex)) { // SNMP call fails. Setup error and return
hr = SetWinSnmpApiError (GetLastError ()); goto Cleanup; } if (asniErrorStatus > 0) { // SNMP call succeeds but the returned status if wrong
hr = SetSnmpScriptError(asniErrorStatus); goto Cleanup; } // Everything is OK
hr = RfcToVarList (lbound, &rfcVarList, psaOut); if (FAILED (hr)) goto Cleanup;
SnmpUtilVarBindListFree(&rfcVarList); rfcVarList.list = NULL; rfcVarList.len = 0; }
VariantInit(pvarValue); pvarValue->vt = VT_ARRAY|VT_VARIANT; pvarValue->parray = psaOut; hr = S_OK; return hr;
Cleanup: if (rfcVarList.len > 0) SnmpUtilVarBindListFree(&rfcVarList); if (psaOut) SafeArrayDestroy (psaOut); return hr; }
/*****************************************************************************\
* Function: GetTree * * PURPOSE: It walks through SNMP oids * * ARGUMENTS: * * bstrTree: The array of SNMP Oids. The type must be a 1D array of BSTRs * pvarValue: The return value for the corresponding Oids, it is 1D array * of Variants * * RETURN VALUE: * S_OK: If succeed. * E_INVALIDARG: Invalid oid. * E_FAIL: If Open method has not been called before * E_OUTOFMEMORY: Out of memory * other: Returns the last error set by SnmpMgrRequest * \*****************************************************************************/ STDMETHODIMP CSNMP:: GetTree( IN BSTR bstrTree, OUT VARIANT *pvarValue ) { RFC1157VarBindList rfcVarList = {NULL, 0}; VARIANT v; AsnInteger asniErrorStatus; AsnInteger asniErrorIndex; AsnObjectIdentifier asnRootOid; AsnObjectIdentifier asnTmpOid; HRESULT hr = E_FAIL; SAFEARRAY *psa = NULL; SAFEARRAYBOUND rgsabound[2]; long ix[2]; LPSTR pszStr;
if (m_SNMPSession == NULL) return (Error(IDS_NO_SNMP_SESSION, IID_ISNMP, E_FAIL));
rgsabound[0].lLbound = 0; rgsabound[0].cElements = 2; rgsabound[1].lLbound = 0; rgsabound[1].cElements = 0; if (! (psa = SafeArrayCreate(VT_VARIANT, 2, rgsabound))) return Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY);
hr = VarListAdd(bstrTree, &rfcVarList); if (FAILED (hr)) { Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); goto Cleanup2; }
if (!SnmpUtilOidCpy(&asnRootOid, &rfcVarList.list[0].name)){ hr = SetScriptingError(CLSID_SNMP, IID_ISNMP, GetLastError()); goto Cleanup2; }
while(1){ if (!SnmpMgrRequest(m_SNMPSession, ASN_RFC1157_GETNEXTREQUEST, &rfcVarList, &asniErrorStatus, &asniErrorIndex)) { hr = SetWinSnmpApiError (GetLastError ()); goto Cleanup; }
if (asniErrorStatus == SNMP_ERRORSTATUS_NOSUCHNAME || SnmpUtilOidNCmp(&rfcVarList.list[0].name, &asnRootOid, asnRootOid.idLength)) break;
if (asniErrorStatus > 0) { hr = SetSnmpScriptError(asniErrorStatus); goto Cleanup; }
rgsabound[1].cElements++; ix[1] = rgsabound[1].cElements - 1; hr = SafeArrayRedim(psa, &rgsabound[1]); if (FAILED (hr)) { Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY); goto Cleanup; }
// put a pszStr version of the OID in the result array
pszStr = NULL; if (!SnmpMgrOidToStr(&rfcVarList.list[0].name, &pszStr)){ hr = SetScriptingError(CLSID_SNMP, IID_ISNMP, GetLastError()); goto Cleanup; }
ix[0] = 0; hr = PutString(psa, ix, pszStr); if (FAILED (hr)) goto Cleanup;
SnmpUtilMemFree(pszStr);
// Put the value variant in the result array
hr = RFC1157ToVariant(&v, &rfcVarList.list[0]); if (FAILED (hr)) goto Cleanup;
ix[0] = 1; hr = SafeArrayPutElement(psa, ix, &v); if (FAILED (hr)) { Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); goto Cleanup; } VariantClear(&v);
if (! SnmpUtilOidCpy(&asnTmpOid, &rfcVarList.list[0].name)) { hr = SetScriptingError(CLSID_SNMP, IID_ISNMP, GetLastError()); goto Cleanup; }
SnmpUtilVarBindFree(&rfcVarList.list[0]);
if (! SnmpUtilOidCpy(&rfcVarList.list[0].name, &asnTmpOid)) { hr = SetScriptingError(CLSID_SNMP, IID_ISNMP, GetLastError()); SnmpUtilOidFree(&asnTmpOid); goto Cleanup; }
rfcVarList.list[0].value.asnType = ASN_NULL; SnmpUtilOidFree(&asnTmpOid); }
SnmpUtilOidFree(&asnRootOid); SnmpUtilVarBindListFree(&rfcVarList);
VariantInit(pvarValue); pvarValue->vt = VT_ARRAY|VT_VARIANT; pvarValue->parray = psa; return S_OK;
Cleanup: SnmpUtilOidFree(&asnRootOid); Cleanup2: SnmpUtilVarBindListFree(&rfcVarList); if (psa) SafeArrayDestroy(psa); return hr; }
/*****************************************************************************\
* Function: Close * * PURPOSE: A Com Wrapper for SnmpMgrClose() * * ARGUMENTS: * * RETURN VALUE: * S_OK: always. * \*****************************************************************************/ STDMETHODIMP CSNMP:: Close( VOID ) { if (m_SNMPSession) SnmpMgrClose(m_SNMPSession); m_SNMPSession = NULL; return S_OK; }
STDMETHODIMP CSNMP:: OIDFromString( BSTR bstrOID, VARIANT *pvarOID ) { SAFEARRAY *psaOID; SAFEARRAYBOUND rgsaOID[1]; long ixOID[1]; LPSTR pszOID; BOOL bResult; VARIANT v; AsnObjectIdentifier asnReqObject; HRESULT hr;
VariantInit(&v); if (! (pszOID = MakeNarrow(bstrOID))) return SetScriptingError(CLSID_SNMP, IID_ISNMP, GetLastError());
bResult = SnmpMgrStrToOid(pszOID, &asnReqObject); LocalFree(pszOID);
if (!bResult ) return Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG);
// put a numeric array of the pvarOID in the result array
rgsaOID[0].lLbound = 0; rgsaOID[0].cElements = asnReqObject.idLength; psaOID = SafeArrayCreate(VT_VARIANT, 1, rgsaOID); if (psaOID == NULL) goto out; for (ixOID[0] = 0; ixOID[0] < (long)rgsaOID[0].cElements ; ixOID[0]++){ hr = VariantClear(&v); _ASSERTE (SUCCEEDED (hr)); v.vt = VT_I4; v.lVal = asnReqObject.ids[ixOID[0]]; hr = SafeArrayPutElement(psaOID, ixOID, &v); if (FAILED(hr)) Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); //SafeArrayPutElement(psaOID, ixOID, &(asnReqObject.ids[ixOID[0]]));
}
hr = VariantClear(pvarOID); _ASSERTE(hr); pvarOID->vt = VT_ARRAY|VT_VARIANT; pvarOID->parray = psaOID; SnmpUtilOidFree(&asnReqObject); return S_OK;
out: SnmpUtilOidFree(&asnReqObject); return Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY); }
HRESULT CSNMP:: VariantToRFC1157( RFC1157VarBind * prfcvbValue, VARIANT * pvarValue ) { HRESULT hr = S_OK;
if (!pvarValue) { prfcvbValue->value.asnType = ASN_NULL; } else if (pvarValue->vt == VT_BSTR){ prfcvbValue->value.asnType = ASN_OCTETSTRING; LPSTR pStr = MakeNarrow (pvarValue->bstrVal);
if (pStr) { DWORD dwLen = strlen (pStr);
if (! (prfcvbValue->value.asnValue.string.stream = (BYTE *) SnmpUtilMemAlloc (dwLen + 1))) { LocalFree (pStr); return Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY); } memcpy (prfcvbValue->value.asnValue.string.stream, pStr, dwLen + 1); prfcvbValue->value.asnValue.string.length = dwLen; prfcvbValue->value.asnValue.string.dynamic = TRUE; LocalFree (pStr); } else hr = Error( IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY ); } else { VARIANT varTemp;
VariantInit (&varTemp); hr = VariantChangeType (&varTemp, pvarValue, 0, VT_I4); if (FAILED (hr)) hr = Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); else { prfcvbValue->value.asnType = ASN_INTEGER; prfcvbValue->value.asnValue.number = pvarValue->lVal; } }
return hr; }
// ----------------------------------------------------
// Place a returned SNMP value in a variant
//
HRESULT CSNMP:: RFC1157ToVariant( VARIANT * pvarValue, RFC1157VarBind * prfcvbValue ) { VariantInit(pvarValue); switch (prfcvbValue->value.asnType){ case ASN_RFC1155_TIMETICKS: case ASN_RFC1155_COUNTER: case ASN_RFC1155_GAUGE: case ASN_INTEGER: case ASN_UNSIGNED32: pvarValue->vt= VT_I4; pvarValue->lVal = prfcvbValue->value.asnValue.number; break;
case ASN_RFC1155_IPADDRESS: case ASN_RFC1155_OPAQUE: case ASN_BITS: case ASN_SEQUENCE: case ASN_OCTETSTRING: pvarValue->vt = VT_BSTR; LPWSTR pszUnicodeStr; if (prfcvbValue->value.asnValue.string.length > 0 ){ LPSTR pszAnsiStr; if (! (pszAnsiStr = (LPSTR )LocalAlloc(LPTR, prfcvbValue->value.asnValue.string.length + 1))) return Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY); memcpy(pszAnsiStr, (LPSTR )prfcvbValue->value.asnValue.string.stream, prfcvbValue->value.asnValue.string.length); pszAnsiStr[prfcvbValue->value.asnValue.string.length] = 0; pszUnicodeStr = MakeWide(pszAnsiStr); LocalFree(pszAnsiStr); } else{ pszUnicodeStr = MakeWide(""); }
if (pszUnicodeStr == NULL) return Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY);
pvarValue->bstrVal = SysAllocString(pszUnicodeStr);
LocalFree(pszUnicodeStr);
if (pvarValue->bstrVal == NULL) { return Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY); } break;
case ASN_OBJECTIDENTIFIER: LPSTR pszAnsiOid;
pszAnsiOid = NULL; if (SnmpMgrOidToStr(& (prfcvbValue->value.asnValue.object), &pszAnsiOid)) { LPWSTR pszUnicodeOid = MakeWide (pszAnsiOid);
SnmpUtilMemFree (pszAnsiOid);
if (pszUnicodeOid) { pvarValue->vt = VT_BSTR; pvarValue->bstrVal = SysAllocString(pszUnicodeOid); LocalFree (pszUnicodeOid); } else return Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY); } else return SetScriptingError(CLSID_SNMP, IID_ISNMP, GetLastError()); break; default: pvarValue->vt = VT_EMPTY; } return S_OK; }
// ----------------------------------------------------
// Place a returned SNMP value in a uint
//
HRESULT CSNMP:: RFC1157ToUInt( PUINT puValue, RFC1157VarBind * prfcvbValue ) { switch (prfcvbValue->value.asnType){ case ASN_RFC1155_TIMETICKS: case ASN_RFC1155_COUNTER: case ASN_RFC1155_GAUGE: case ASN_INTEGER: case ASN_UNSIGNED32: *puValue = prfcvbValue->value.asnValue.number; break;
case ASN_RFC1155_OPAQUE: case ASN_BITS: case ASN_SEQUENCE: case ASN_OCTETSTRING:
if (prfcvbValue->value.asnValue.string.length == 1 ){ *puValue = prfcvbValue->value.asnValue.string.stream[0]; } else{ return Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); } break;
default: return Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY); } return S_OK; }
// -----------------------------------------------------
// Add an OID to an SNMP get list
//
// Convert the UNICODE string to ANSI
// Convert it to a real OID (numbers)
// Add to the Array
HRESULT CSNMP:: VarListAdd( BSTR bstrOID, RFC1157VarBindList * prfcList, VARIANT *pvarValue ) { LPSTR pszOID; BOOL bResult; AsnObjectIdentifier asnReqObject;
if (! (pszOID = MakeNarrow(bstrOID))) return SetScriptingError(CLSID_SNMP, IID_ISNMP, GetLastError());
bResult = SnmpMgrStrToOid(pszOID, &asnReqObject); LocalFree(pszOID);
if (!bResult) return Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG);
prfcList->len++;
if (! (prfcList->list = (RFC1157VarBind *) SNMP_realloc (prfcList->list, sizeof(RFC1157VarBind) * prfcList->len))) return Error(IDS_OUT_OF_MEMORY, IID_ISNMP, E_OUTOFMEMORY);
prfcList->list[prfcList->len - 1].name = asnReqObject;
return VariantToRFC1157(& (prfcList->list[prfcList->len -1]), pvarValue);
}
/*****************************************************************************\
* Function: Set * * PURPOSE: Set a value of a SNMP oid * * ARGUMENTS: * * bstrOID: The SNMP Oid in BSTR * varValue: The corresponding Oid * * RETURN VALUE: * S_OK: If succeed. * E_INVALIDARG: Invalid oid. * E_FAIL: If Open method has not been called before * E_OUTOFMEMORY: Out of memory * other: Returns the last error set by SnmpMgrRequest * \*****************************************************************************/ STDMETHODIMP CSNMP:: Set( IN BSTR bstrOID, IN VARIANT varValue ) { RFC1157VarBindList rfcVarList = {NULL, 0}; AsnInteger asniErrorStatus; AsnInteger asniErrorIndex; HRESULT hr = E_FAIL;
if (m_SNMPSession == NULL) return Error(IDS_NO_SNMP_SESSION, IID_ISNMP, E_FAIL);
if (FAILED (hr = VarListAdd(bstrOID, &rfcVarList))) { Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); goto Cleanup; }
hr = VariantToRFC1157(&rfcVarList.list[0], &varValue); if (FAILED (hr)) goto Cleanup;
if (!SnmpMgrRequest(m_SNMPSession, ASN_RFC1157_SETREQUEST, &rfcVarList, &asniErrorStatus, &asniErrorIndex)) { hr = SetWinSnmpApiError (GetLastError ()); goto Cleanup; }
if (asniErrorStatus > 0) { hr = SetSnmpScriptError(asniErrorStatus); goto Cleanup; }
hr = S_OK;
Cleanup: SnmpUtilVarBindListFree(&rfcVarList); return hr; }
/*****************************************************************************\
* Function: SetList * * PURPOSE: Set a list of a SNMP oids * * ARGUMENTS: * * pvarList: The array of SNMP Oids. The type must be a 1D array of BSTRs * pvarValue: The corresponding Oids, it must also b a 1D array of Variants * * RETURN VALUE: * S_OK: If succeed. * E_INVALIDARG: Invalid oid or the type of the variant is not a 1D array * E_FAIL: If Open method has not been called before * E_OUTOFMEMORY: Out of memory * other: Returns the last error set by SnmpMgrRequest * \*****************************************************************************/ STDMETHODIMP CSNMP:: SetList( IN VARIANT * varName, IN VARIANT * varValue ) { RFC1157VarBindList rfcVarList = {NULL, 0}; AsnInteger asniErrorStatus; AsnInteger asniErrorIndex; HRESULT hr = E_FAIL; SAFEARRAY *psaName, *psaValue; long lLowBound, lUpperBound; long ix[1];
if (m_SNMPSession == NULL) return Error(IDS_NO_SNMP_SESSION, IID_ISNMP, E_FAIL);
if (!(varName->vt & VT_ARRAY) || !(varValue->vt & VT_ARRAY)) return Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG);
if (varName->vt & VT_BYREF) psaName = *(varName->pparray); else psaName = varName->parray;
if (varValue->vt & VT_BYREF) psaValue = *(varValue->pparray); else psaValue = varValue->parray;
if (SafeArrayGetDim(psaName) != 1 || SafeArrayGetDim(psaValue) != 1) return Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG);
SafeArrayGetLBound(psaName, 1, &lLowBound); SafeArrayGetUBound(psaName, 1, &lUpperBound);
long lVal;
SafeArrayGetLBound(psaValue, 1, &lVal); if (lVal != lLowBound) return Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); SafeArrayGetUBound(psaValue, 1, &lVal); if (lVal != lUpperBound) return Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG);
for (ix[0] = lLowBound; ix[0] <= lUpperBound; ix[0]++) { VARIANT varArgName, varArgValue;
VariantClear(&varArgName); VariantClear(&varArgValue);
hr = SafeArrayGetElement(psaName, ix, &varArgName); if (FAILED (hr)) { hr = Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); goto Cleanup; }
if (varArgName.vt != VT_BSTR) { hr = Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); goto Cleanup; }
hr = SafeArrayGetElement(psaValue, ix, &varArgValue); if (FAILED (hr)) goto Cleanup;
if (FAILED (hr = VarListAdd(varArgName.bstrVal, &rfcVarList, &varArgValue))) goto Cleanup; }
if (! SnmpMgrRequest(m_SNMPSession, ASN_RFC1157_SETREQUEST, &rfcVarList, &asniErrorStatus, &asniErrorIndex)) { hr = SetWinSnmpApiError (GetLastError ()); goto Cleanup; }
if (asniErrorStatus > 0) { hr = SetSnmpScriptError(asniErrorStatus); goto Cleanup; }
hr = S_OK;
Cleanup: SnmpUtilVarBindListFree(&rfcVarList); return hr; }
HRESULT CSNMP:: SetSnmpScriptError( IN DWORD dwError ) { static DWORD SnmpErrorMapping [] = { IDS_SNMP_ERRORSTATUS_NOERROR, IDS_SNMP_ERRORSTATUS_TOOBIG, IDS_SNMP_ERRORSTATUS_NOSUCHNAME, IDS_SNMP_ERRORSTATUS_BADVALUE, IDS_SNMP_ERRORSTATUS_READONLY, IDS_SNMP_ERRORSTATUS_GENERR, IDS_SNMP_ERRORSTATUS_NOACCESS, IDS_SNMP_ERRORSTATUS_WRONGTYPE, IDS_SNMP_ERRORSTATUS_WRONGLENGTH, IDS_SNMP_ERRORSTATUS_WRONGENCODING, IDS_SNMP_ERRORSTATUS_WRONGVALUE, IDS_SNMP_ERRORSTATUS_NOCREATION, IDS_SNMP_ERRORSTATUS_INCONSISTENTVALUE, IDS_SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE, IDS_SNMP_ERRORSTATUS_COMMITFAILED, IDS_SNMP_ERRORSTATUS_UNDOFAILED, IDS_SNMP_ERRORSTATUS_AUTHORIZATIONERROR, IDS_SNMP_ERRORSTATUS_NOTWRITABLE, IDS_SNMP_ERRORSTATUS_INCONSISTENTNAME};
if ((int)dwError < 0 || dwError > sizeof (SnmpErrorMapping) / sizeof (DWORD)) dwError = SNMP_ERRORSTATUS_GENERR; return Error(SnmpErrorMapping[dwError], IID_ISNMP, E_FAIL); }
HRESULT CSNMP:: SetWinSnmpApiError( IN DWORD dwError ) { static DWORD WinSnmpApiErrorMapping [] = { IDS_SNMPAPI_ALLOC_ERROR, IDS_SNMPAPI_CONTEXT_INVALID, IDS_SNMPAPI_CONTEXT_UNKNOWN, IDS_SNMPAPI_ENTITY_INVALID, IDS_SNMPAPI_ENTITY_UNKNOWN, IDS_SNMPAPI_INDEX_INVALID, IDS_SNMPAPI_NOOP, IDS_SNMPAPI_OID_INVALID, IDS_SNMPAPI_OPERATION_INVALID, IDS_SNMPAPI_OUTPUT_TRUNCATED, IDS_SNMPAPI_PDU_INVALID, IDS_SNMPAPI_SESSION_INVALID, IDS_SNMPAPI_SYNTAX_INVALID, IDS_SNMPAPI_VBL_INVALID, IDS_SNMPAPI_MODE_INVALID, IDS_SNMPAPI_SIZE_INVALID, IDS_SNMPAPI_NOT_INITIALIZED, IDS_SNMPAPI_MESSAGE_INVALID, IDS_SNMPAPI_HWND_INVALID, IDS_SNMPAPI_OTHER_ERROR, IDS_SNMPAPI_TL_NOT_INITIALIZED, IDS_SNMPAPI_TL_NOT_SUPPORTED, IDS_SNMPAPI_TL_NOT_AVAILABLE, IDS_SNMPAPI_TL_RESOURCE_ERROR, IDS_SNMPAPI_TL_UNDELIVERABLE, IDS_SNMPAPI_TL_SRC_INVALID, IDS_SNMPAPI_TL_INVALID_PARAM, IDS_SNMPAPI_TL_IN_USE, IDS_SNMPAPI_TL_TIMEOUT, IDS_SNMPAPI_TL_PDU_TOO_BIG, IDS_SNMPAPI_TL_OTHER };
static DWORD WinSnmpApiError [] = { SNMPAPI_ALLOC_ERROR, SNMPAPI_CONTEXT_INVALID, SNMPAPI_CONTEXT_UNKNOWN, SNMPAPI_ENTITY_INVALID, SNMPAPI_ENTITY_UNKNOWN, SNMPAPI_INDEX_INVALID, SNMPAPI_NOOP, SNMPAPI_OID_INVALID, SNMPAPI_OPERATION_INVALID, SNMPAPI_OUTPUT_TRUNCATED, SNMPAPI_PDU_INVALID, SNMPAPI_SESSION_INVALID, SNMPAPI_SYNTAX_INVALID, SNMPAPI_VBL_INVALID, SNMPAPI_MODE_INVALID, SNMPAPI_SIZE_INVALID, SNMPAPI_NOT_INITIALIZED, SNMPAPI_MESSAGE_INVALID, SNMPAPI_HWND_INVALID, SNMPAPI_OTHER_ERROR, SNMPAPI_TL_NOT_INITIALIZED, SNMPAPI_TL_NOT_SUPPORTED, SNMPAPI_TL_NOT_AVAILABLE, SNMPAPI_TL_RESOURCE_ERROR, SNMPAPI_TL_UNDELIVERABLE, SNMPAPI_TL_SRC_INVALID, SNMPAPI_TL_INVALID_PARAM, SNMPAPI_TL_IN_USE, SNMPAPI_TL_TIMEOUT, SNMPAPI_TL_PDU_TOO_BIG, SNMPAPI_TL_OTHER };
for (int i = 0; i < sizeof (WinSnmpApiError); i++) { if (dwError == WinSnmpApiError[i]) { dwError = WinSnmpApiErrorMapping[i]; break; } } return Error(dwError, IID_ISNMP, E_FAIL);
}
// Convert part of the the variant array to
// RFC1157VarBindList used in SnmpMgrRequest call
HRESULT CSNMP:: VarToRfcVarList( long lbound, long ubound, SAFEARRAY *psa, RFC1157VarBindList * prfcVarList ) { long ix[1]; VARIANT var; HRESULT hr = S_OK;
for (ix[0] = lbound; ix[0] <= ubound; ix[0]++) { VariantClear(&var); hr = SafeArrayGetElement(psa, ix, &var); if (FAILED (hr) || var.vt != VT_BSTR) { Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); break; }
hr = VarListAdd(var.bstrVal, prfcVarList); if (FAILED (hr)) { Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); break; } } return hr; }
// Append RFC1157VarBindList used in SnmpMgrRequest call at the
// end of the variant array
HRESULT CSNMP:: RfcToVarList( long lbound, RFC1157VarBindList *prfcVarList, SAFEARRAY * psaOut ) { long ix[1]; DWORD i; VARIANT var; HRESULT hr = S_OK;
for(ix[0] = lbound, i = 0; i < prfcVarList->len; i++, ix[0]++) { hr = RFC1157ToVariant(&var, & prfcVarList->list[i]); if (FAILED (hr)) break;
hr = SafeArrayPutElement(psaOut, ix, &var); if (FAILED (hr)) { Error(IDS_INVALIDARG, IID_ISNMP, E_INVALIDARG); break; } }
return hr; }
|