mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1220 lines
35 KiB
1220 lines
35 KiB
/*****************************************************************************\
|
|
* 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 "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);
|
|
|
|
|