Leaked source code of windows server 2003
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

/*****************************************************************************
*
* $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;
}