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.
579 lines
16 KiB
579 lines
16 KiB
/*****************************************************************************
|
|
*
|
|
* $Workfile: StdMib.cpp $
|
|
*
|
|
* Copyright (C) 1997 Hewlett-Packard Company.
|
|
* All rights reserved.
|
|
*
|
|
* 11311 Chinden Blvd.
|
|
* Boise, Idaho 83714
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
|
|
#include "snmpmgr.h"
|
|
#include "stdoids.h"
|
|
#include "status.h"
|
|
#include "stdmib.h"
|
|
#include "tcpmib.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CStdMib::CStdMib()
|
|
|
|
CStdMib::CStdMib( CTcpMib in *pParent ) :
|
|
m_dwDevIndex( 1 ),m_pParent(pParent)
|
|
{
|
|
m_VarBindList.len = 0;
|
|
m_VarBindList.list = NULL;
|
|
|
|
*m_szAgent = '\0';
|
|
strncpyn(m_szCommunity, DEFAULT_SNMP_COMMUNITYA, sizeof( m_szCommunity));
|
|
} // ::CStdMib()
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CStdMib::CStdMib()
|
|
|
|
CStdMib::CStdMib(const char in *pHost,
|
|
const char in *pCommunity,
|
|
DWORD dwDevIndex,
|
|
CTcpMib in *pParent ) :
|
|
m_dwDevIndex( dwDevIndex ),m_pParent(pParent)
|
|
{
|
|
m_VarBindList.len = 0;
|
|
m_VarBindList.list = NULL;
|
|
|
|
strncpyn(m_szAgent, pHost, sizeof( m_szAgent ));
|
|
strncpyn(m_szCommunity, pCommunity, sizeof( m_szCommunity ));
|
|
} // ::CStdMib()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CStdMib::~CStdMib()
|
|
|
|
CStdMib::~CStdMib()
|
|
{
|
|
m_pParent = NULL;
|
|
} // ::~CStdMib()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// GetDeviceDescription
|
|
//
|
|
|
|
BOOL
|
|
CStdMib::GetDeviceDescription(
|
|
OUT LPTSTR pszPortDescription,
|
|
IN DWORD dwDescLen
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD dwLen;
|
|
LPSTR psz;
|
|
|
|
m_VarBindList.list = NULL;
|
|
m_VarBindList.len = 0;
|
|
|
|
if ( NO_ERROR != OIDQuery(OT_DEVICE_SYSDESCR, SNMP_GET) )
|
|
goto cleanup;
|
|
|
|
//
|
|
// If we got the device description successfully, allocate memory and
|
|
// return this back in a UNICODE string. Caller is responsible for
|
|
// freeing it using free()
|
|
//
|
|
psz = (LPSTR)m_VarBindList.list[0].value.asnValue.string.stream;
|
|
dwLen = (DWORD)m_VarBindList.list[0].value.asnValue.string.length;
|
|
|
|
if ( bRet = MultiByteToWideChar(CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
psz,
|
|
dwLen,
|
|
pszPortDescription,
|
|
dwDescLen) )
|
|
pszPortDescription[dwDescLen-1] = TEXT('\0');
|
|
|
|
cleanup:
|
|
SnmpUtilVarBindListFree(&m_VarBindList);
|
|
|
|
return bRet;
|
|
|
|
} // ::GetDeviceDescription()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// GetDeviceStatus -- gets the device status
|
|
|
|
DWORD
|
|
CStdMib::GetDeviceStatus( )
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
|
|
dwRetCode = StdMibGetPeripheralStatus( m_szAgent, m_szCommunity, m_dwDevIndex);
|
|
|
|
return dwRetCode;
|
|
|
|
} // ::GetDeviceStatus()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// GetJobStatus -- gets the device status, and maps it to the spooler
|
|
// error codes -- see JOB_INFO_2
|
|
// Error Codes:
|
|
// Spooler error codes
|
|
|
|
DWORD
|
|
CStdMib::GetJobStatus( )
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
DWORD dwStatus = NO_ERROR;
|
|
|
|
dwRetCode = StdMibGetPeripheralStatus( m_szAgent, m_szCommunity, m_dwDevIndex );
|
|
if (dwRetCode != NO_ERROR)
|
|
{
|
|
dwStatus = MapJobErrorToSpooler( dwRetCode );
|
|
}
|
|
|
|
return dwStatus;
|
|
|
|
} // ::GetJobStatus()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// GetDeviceAddress -- gets the device hardware address
|
|
// Error Codes:
|
|
// NO_ERROR if successful
|
|
// ERROR_NOT_ENOUGH_MEMORY if memory allocation failes
|
|
// ERROR_INVALID_HANDLE if can't build the variable bindings
|
|
// SNMP_ERRORSTATUS_TOOBIG if the packet returned is big
|
|
// SNMP_ERRORSTATUS_NOSUCHNAME if the OID isn't supported
|
|
// SNMP_ERRORSTATUS_BADVALUE
|
|
// SNMP_ERRORSTATUS_READONLY
|
|
// SNMP_ERRORSTATUS_GENERR
|
|
// SNMP_MGMTAPI_TIMEOUT -- set by GetLastError()
|
|
// SNMP_MGMTAPI_SELECT_FDERRORS -- set by GetLastError()
|
|
// SNMPAPI_ERROR if open fails -- set by GetLastError()
|
|
|
|
DWORD
|
|
CStdMib::GetDeviceHWAddress( LPTSTR out psztHWAddress,
|
|
DWORD dwSize ) // Size of in characters in of HW address
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
UINT i = 0;
|
|
char szTmpHWAddr[256];
|
|
|
|
// Process the variableBinding
|
|
m_VarBindList.list = NULL;
|
|
m_VarBindList.len = 0;
|
|
|
|
// get the hardware address
|
|
dwRetCode = OIDQuery(OT_DEVICE_ADDRESS, SNMP_GETNEXT); // query the first entry in the table
|
|
if (dwRetCode != NO_ERROR)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
while (1) // instead of walking the tree, do a get next, until we filled up the HW address -- saves on the network communications
|
|
{
|
|
i = 0;
|
|
// process the variableBinding
|
|
if ( IS_ASN_INTEGER(m_VarBindList, i) ) // check the ifType
|
|
{
|
|
if ( GET_ASN_NUMBER(m_VarBindList, i) == IFTYPE_ETHERNET)
|
|
{
|
|
StringCchPrintfA (szTmpHWAddr, COUNTOF (szTmpHWAddr), "%02X%02X%02X%02X%02X%02X", GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 0),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 1),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 2),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 3),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 4),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 5) );
|
|
MBCS_TO_UNICODE(psztHWAddress, dwSize, szTmpHWAddr);
|
|
dwRetCode = NO_ERROR;
|
|
break;
|
|
}
|
|
else if ( GET_ASN_NUMBER(m_VarBindList, i) == IFTYPE_OTHER) // apperently, XEROX encodes their HW address w/ ifType = other
|
|
{
|
|
// check if the HWAddress is NULL
|
|
if ( GET_ASN_STRING_LEN(m_VarBindList, i+1) != 0)
|
|
{
|
|
StringCchPrintfA (szTmpHWAddr, COUNTOF (szTmpHWAddr), "%02X%02X%02X%02X%02X%02X", GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 0),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 1),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 2),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 3),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 4),
|
|
GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 5) );
|
|
MBCS_TO_UNICODE(psztHWAddress, dwSize, szTmpHWAddr);
|
|
dwRetCode = NO_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// didn't get what we were looking for, so copy the address over & do a another GetNext()
|
|
if( !OIDVarBindCpy(&m_VarBindList) )
|
|
{
|
|
dwRetCode = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
if ( !SnmpUtilOidNCmp( &m_VarBindList.list[0].name, &OID_Mib2_ifTypeTree, OID_Mib2_ifTypeTree.idLength) )
|
|
{
|
|
break; // end of the tree
|
|
}
|
|
|
|
dwRetCode = OIDQuery(&m_VarBindList, SNMP_GETNEXT); // query the next entry in the table
|
|
if (dwRetCode != NO_ERROR)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
} // end while()
|
|
|
|
cleanup:
|
|
SnmpUtilVarBindListFree(&m_VarBindList);
|
|
|
|
return dwRetCode;
|
|
|
|
} // ::GetDeviceHWAddress()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// GetDeviceInfo -- gets the device description, such as the manufacturer string
|
|
// Error Codes:
|
|
// NO_ERROR if successful
|
|
// ERROR_NOT_ENOUGH_MEMORY if memory allocation failes
|
|
// ERROR_INVALID_HANDLE if can't build the variable bindings
|
|
// SNMP_ERRORSTATUS_TOOBIG if the packet returned is big
|
|
// SNMP_ERRORSTATUS_NOSUCHNAME if the OID isn't supported
|
|
// SNMP_ERRORSTATUS_BADVALUE
|
|
// SNMP_ERRORSTATUS_READONLY
|
|
// SNMP_ERRORSTATUS_GENERR
|
|
// SNMP_MGMTAPI_TIMEOUT -- set by GetLastError()
|
|
// SNMP_MGMTAPI_SELECT_FDERRORS -- set by GetLastError()
|
|
// SNMPAPI_ERROR if Open() for session fails
|
|
|
|
DWORD
|
|
CStdMib::GetDeviceName( LPTSTR out psztDescription,
|
|
DWORD in dwSize ) //Size in characters of the psztDescription
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
|
|
// Process the variableBinding
|
|
m_VarBindList.list = NULL;
|
|
m_VarBindList.len = 0;
|
|
|
|
// 1st test for the support of Printer MIB -- note if Printer MIB supported, so is HR MIB
|
|
BOOL bTestPrtMIB = TestPrinterMIB();
|
|
|
|
char szTmpDescr[MAX_DEVICEDESCRIPTION_STR_LEN];
|
|
UINT i=0;
|
|
// process the bindings
|
|
if (bTestPrtMIB) // parse the data from the HR MIB device entry
|
|
{
|
|
while (1) // instead of walking the tree, do a get next, until we filled up the HW address -- saves on the network communications
|
|
{
|
|
i = 0;
|
|
dwRetCode = OIDQuery(OT_DEVICE_DESCRIPTION, SNMP_GETNEXT);
|
|
if (dwRetCode != NO_ERROR)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
// process the variableBinding
|
|
if ( IS_ASN_OBJECTIDENTIFIER(m_VarBindList, i) ) // check the hrDeviceType
|
|
{
|
|
// compare it to hrDevicePrinter
|
|
if (SnmpUtilOidCmp(GET_ASN_OBJECT(&m_VarBindList, i), &HRMIB_hrDevicePrinter) == 0)
|
|
{
|
|
// found the printer description, get the hrDeviceDescr
|
|
if ( IS_ASN_OCTETSTRING(m_VarBindList, i) )
|
|
{
|
|
if (GET_ASN_OCTETSTRING(szTmpDescr, sizeof(szTmpDescr), m_VarBindList, i))
|
|
{
|
|
MBCS_TO_UNICODE(psztDescription, dwSize, szTmpDescr);
|
|
dwRetCode = NO_ERROR;
|
|
break;
|
|
} else
|
|
{
|
|
dwRetCode = SNMP_ERRORSTATUS_TOOBIG;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwRetCode = SNMP_ERRORSTATUS_NOSUCHNAME;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// didn't get what we were looking for, so copy the address over & do a another GetNext()
|
|
if( !OIDVarBindCpy(&m_VarBindList) )
|
|
{
|
|
dwRetCode = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
} // end while()
|
|
|
|
} // if TestPrinterMIB() TRUE
|
|
else
|
|
{
|
|
dwRetCode = OIDQuery(OT_DEVICE_SYSDESCR, SNMP_GET);
|
|
if (dwRetCode != NO_ERROR)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
// process the variables
|
|
if (GET_ASN_OCTETSTRING(szTmpDescr, sizeof(szTmpDescr), m_VarBindList, i))
|
|
{
|
|
MBCS_TO_UNICODE(psztDescription, dwSize, szTmpDescr);
|
|
dwRetCode = NO_ERROR;
|
|
}
|
|
} // if TestPrinterMIB() FALSE
|
|
|
|
cleanup:
|
|
SnmpUtilVarBindListFree(&m_VarBindList);
|
|
|
|
return dwRetCode;
|
|
|
|
} // ::GetDeviceStatus()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// TestPrinterMIB -- tests if the device supports Printer MIB
|
|
|
|
BOOL
|
|
CStdMib::TestPrinterMIB( )
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
BOOL bRetCode = FALSE;
|
|
|
|
// Process the variableBinding
|
|
m_VarBindList.list = NULL;
|
|
m_VarBindList.len = 0;
|
|
|
|
dwRetCode = OIDQuery(OT_TEST_PRINTER_MIB, SNMP_GETNEXT);
|
|
if (dwRetCode != NO_ERROR)
|
|
{
|
|
bRetCode = FALSE;
|
|
goto cleanup;
|
|
}
|
|
|
|
// compare the resulting value w/ the Printer MIB tree value
|
|
if (SnmpUtilOidNCmp(GET_ASN_OID_NAME(&m_VarBindList, 0), &PrtMIB_OidPrefix, PrtMIB_OidPrefix.idLength) == 0)
|
|
{
|
|
bRetCode = TRUE;
|
|
goto cleanup;
|
|
}
|
|
|
|
cleanup:
|
|
SnmpUtilVarBindListFree(&m_VarBindList);
|
|
|
|
return (bRetCode);
|
|
|
|
} // ::TestPrinterMIB()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// OIDQuery -- calls into the CTcpMib class to query the OIDs passed in
|
|
|
|
DWORD
|
|
CStdMib::OIDQuery( AsnObjectIdentifier in *pMibObjId,
|
|
SNMPCMD in eSnmpCmd )
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
|
|
if( m_pParent == NULL ) {
|
|
dwRetCode = ERROR_INVALID_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
switch (eSnmpCmd)
|
|
{
|
|
case SNMP_GET:
|
|
dwRetCode = m_pParent->SnmpGet(m_szAgent, m_szCommunity, m_dwDevIndex, pMibObjId, &m_VarBindList);
|
|
goto cleanup;
|
|
|
|
break;
|
|
|
|
case SNMP_WALK:
|
|
dwRetCode = m_pParent->SnmpWalk(m_szAgent, m_szCommunity, m_dwDevIndex, pMibObjId, &m_VarBindList);
|
|
goto cleanup;
|
|
|
|
break;
|
|
|
|
case SNMP_GETNEXT:
|
|
dwRetCode = m_pParent->SnmpGetNext(m_szAgent, m_szCommunity, m_dwDevIndex, pMibObjId, &m_VarBindList);
|
|
goto cleanup;
|
|
|
|
break;
|
|
|
|
case SNMP_SET:
|
|
default:
|
|
dwRetCode = ERROR_NOT_SUPPORTED;
|
|
goto cleanup;
|
|
}
|
|
|
|
cleanup:
|
|
if (dwRetCode != NO_ERROR)
|
|
{
|
|
SnmpUtilVarBindListFree(&m_VarBindList);
|
|
}
|
|
|
|
return (dwRetCode);
|
|
|
|
} // ::OIDQuery()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// OIDQuery -- calls into the CTcpMib class to query the OIDs passed in
|
|
|
|
DWORD
|
|
CStdMib::OIDQuery( RFC1157VarBindList inout *pVarBindList,
|
|
SNMPCMD in eSnmpCmd )
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
|
|
if( m_pParent == NULL ) {
|
|
dwRetCode = ERROR_INVALID_HANDLE;
|
|
goto cleanup;
|
|
}
|
|
|
|
switch (eSnmpCmd)
|
|
{
|
|
case SNMP_GET:
|
|
dwRetCode = m_pParent->SnmpGet(m_szAgent, m_szCommunity, m_dwDevIndex, pVarBindList);
|
|
goto cleanup;
|
|
|
|
break;
|
|
|
|
case SNMP_WALK:
|
|
dwRetCode = m_pParent->SnmpWalk(m_szAgent, m_szCommunity, m_dwDevIndex, pVarBindList);
|
|
goto cleanup;
|
|
|
|
break;
|
|
|
|
case SNMP_GETNEXT:
|
|
dwRetCode = m_pParent->SnmpGetNext(m_szAgent, m_szCommunity, m_dwDevIndex, pVarBindList);
|
|
goto cleanup;
|
|
|
|
break;
|
|
|
|
case SNMP_SET:
|
|
default:
|
|
dwRetCode = ERROR_NOT_SUPPORTED;
|
|
goto cleanup;
|
|
}
|
|
|
|
cleanup:
|
|
if (dwRetCode != NO_ERROR)
|
|
{
|
|
SnmpUtilVarBindListFree(pVarBindList);
|
|
}
|
|
|
|
return (dwRetCode);
|
|
|
|
} // ::OIDQuery()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// OIDVarBindCpy --
|
|
|
|
BOOL
|
|
CStdMib::OIDVarBindCpy( RFC1157VarBindList inout *pVarBindList )
|
|
{
|
|
UINT i=0;
|
|
AsnObjectIdentifier tempOid;
|
|
|
|
for (i=0; i< PRFC1157_VARBINDLIST_LEN(pVarBindList); i++)
|
|
{
|
|
if( SnmpUtilOidCpy( &tempOid, &(PGET_ASN_OID_NAME(pVarBindList, i))))
|
|
{
|
|
SnmpUtilVarBindFree(&(pVarBindList->list[i]));
|
|
if ( SnmpUtilOidCpy(&(PGET_ASN_OID_NAME(pVarBindList, i)), &tempOid))
|
|
{
|
|
PGET_ASN_TYPE(pVarBindList, i) = ASN_NULL;
|
|
SnmpUtilOidFree(&tempOid);
|
|
}
|
|
else
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
} // ::OIDVarBindCpy()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// MapJobErrorToSpooler -- Maps the received device error to the spooler
|
|
// error codes.
|
|
// Return Values:
|
|
// Spooler device error codes
|
|
|
|
DWORD
|
|
CStdMib::MapJobErrorToSpooler( const DWORD in dwStatus)
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
|
|
switch (dwStatus)
|
|
{
|
|
case ASYNCH_WARMUP:
|
|
case ASYNCH_INITIALIZING:
|
|
dwRetCode = JOB_STATUS_OFFLINE;
|
|
break;
|
|
case ASYNCH_DOOR_OPEN:
|
|
case ASYNCH_PRINTER_ERROR:
|
|
case ASYNCH_TONER_LOW:
|
|
case ASYNCH_OUTPUT_BIN_FULL:
|
|
case ASYNCH_STATUS_UNKNOWN:
|
|
case ASYNCH_RESET:
|
|
case ASYNCH_MANUAL_FEED:
|
|
case ASYNCH_BUSY:
|
|
case ASYNCH_PAPER_JAM:
|
|
case ASYNCH_TONER_GONE:
|
|
dwRetCode = JOB_STATUS_ERROR;
|
|
break;
|
|
case ASYNCH_PAPER_OUT:
|
|
dwRetCode = JOB_STATUS_PAPEROUT;
|
|
break;
|
|
case ASYNCH_OFFLINE:
|
|
dwRetCode = JOB_STATUS_OFFLINE;
|
|
break;
|
|
case ASYNCH_INTERVENTION:
|
|
dwRetCode = JOB_STATUS_USER_INTERVENTION;
|
|
break;
|
|
case ASYNCH_PRINTING:
|
|
dwRetCode = JOB_STATUS_PRINTING;
|
|
break;
|
|
case ASYNCH_ONLINE:
|
|
dwRetCode = NO_ERROR;
|
|
break;
|
|
default:
|
|
dwRetCode = JOB_STATUS_PRINTING;
|
|
}
|
|
|
|
return dwRetCode;
|
|
|
|
} // ::MapJobErrorToSpooler()
|
|
|
|
BOOL CStdMib::GetAsnOctetString( char *pszStr,
|
|
DWORD dwCount,
|
|
RFC1157VarBindList *pVarBindList,
|
|
UINT i) {
|
|
|
|
_ASSERTE( pszStr && pVarBindList );
|
|
|
|
DWORD dwSize = GET_ASN_STRING_LEN( *pVarBindList, i);
|
|
|
|
return dwCount >= dwSize ?
|
|
memcpy(pszStr, pVarBindList->list[i].value.asnValue.string.stream, dwSize) != NULL :
|
|
FALSE;
|
|
}
|
|
|
|
|