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

  1. /*****************************************************************************
  2. *
  3. * $Workfile: StdMib.cpp $
  4. *
  5. * Copyright (C) 1997 Hewlett-Packard Company.
  6. * All rights reserved.
  7. *
  8. * 11311 Chinden Blvd.
  9. * Boise, Idaho 83714
  10. *
  11. *****************************************************************************/
  12. #include "precomp.h"
  13. #include "snmpmgr.h"
  14. #include "stdoids.h"
  15. #include "status.h"
  16. #include "stdmib.h"
  17. #include "tcpmib.h"
  18. ///////////////////////////////////////////////////////////////////////////////
  19. // CStdMib::CStdMib()
  20. CStdMib::CStdMib( CTcpMib in *pParent ) :
  21. m_dwDevIndex( 1 ),m_pParent(pParent)
  22. {
  23. m_VarBindList.len = 0;
  24. m_VarBindList.list = NULL;
  25. *m_szAgent = '\0';
  26. strncpyn(m_szCommunity, DEFAULT_SNMP_COMMUNITYA, sizeof( m_szCommunity));
  27. } // ::CStdMib()
  28. ///////////////////////////////////////////////////////////////////////////////
  29. // CStdMib::CStdMib()
  30. CStdMib::CStdMib(const char in *pHost,
  31. const char in *pCommunity,
  32. DWORD dwDevIndex,
  33. CTcpMib in *pParent ) :
  34. m_dwDevIndex( dwDevIndex ),m_pParent(pParent)
  35. {
  36. m_VarBindList.len = 0;
  37. m_VarBindList.list = NULL;
  38. strncpyn(m_szAgent, pHost, sizeof( m_szAgent ));
  39. strncpyn(m_szCommunity, pCommunity, sizeof( m_szCommunity ));
  40. } // ::CStdMib()
  41. ///////////////////////////////////////////////////////////////////////////////
  42. // CStdMib::~CStdMib()
  43. CStdMib::~CStdMib()
  44. {
  45. m_pParent = NULL;
  46. } // ::~CStdMib()
  47. ///////////////////////////////////////////////////////////////////////////////
  48. // GetDeviceDescription
  49. //
  50. BOOL
  51. CStdMib::GetDeviceDescription(
  52. OUT LPTSTR pszPortDescription,
  53. IN DWORD dwDescLen
  54. )
  55. {
  56. BOOL bRet = FALSE;
  57. DWORD dwLen;
  58. LPSTR psz;
  59. m_VarBindList.list = NULL;
  60. m_VarBindList.len = 0;
  61. if ( NO_ERROR != OIDQuery(OT_DEVICE_SYSDESCR, SNMP_GET) )
  62. goto cleanup;
  63. //
  64. // If we got the device description successfully, allocate memory and
  65. // return this back in a UNICODE string. Caller is responsible for
  66. // freeing it using free()
  67. //
  68. psz = (LPSTR)m_VarBindList.list[0].value.asnValue.string.stream;
  69. dwLen = (DWORD)m_VarBindList.list[0].value.asnValue.string.length;
  70. if ( bRet = MultiByteToWideChar(CP_ACP,
  71. MB_PRECOMPOSED,
  72. psz,
  73. dwLen,
  74. pszPortDescription,
  75. dwDescLen) )
  76. pszPortDescription[dwDescLen-1] = TEXT('\0');
  77. cleanup:
  78. SnmpUtilVarBindListFree(&m_VarBindList);
  79. return bRet;
  80. } // ::GetDeviceDescription()
  81. ///////////////////////////////////////////////////////////////////////////////
  82. // GetDeviceStatus -- gets the device status
  83. DWORD
  84. CStdMib::GetDeviceStatus( )
  85. {
  86. DWORD dwRetCode = NO_ERROR;
  87. dwRetCode = StdMibGetPeripheralStatus( m_szAgent, m_szCommunity, m_dwDevIndex);
  88. return dwRetCode;
  89. } // ::GetDeviceStatus()
  90. ///////////////////////////////////////////////////////////////////////////////
  91. // GetJobStatus -- gets the device status, and maps it to the spooler
  92. // error codes -- see JOB_INFO_2
  93. // Error Codes:
  94. // Spooler error codes
  95. DWORD
  96. CStdMib::GetJobStatus( )
  97. {
  98. DWORD dwRetCode = NO_ERROR;
  99. DWORD dwStatus = NO_ERROR;
  100. dwRetCode = StdMibGetPeripheralStatus( m_szAgent, m_szCommunity, m_dwDevIndex );
  101. if (dwRetCode != NO_ERROR)
  102. {
  103. dwStatus = MapJobErrorToSpooler( dwRetCode );
  104. }
  105. return dwStatus;
  106. } // ::GetJobStatus()
  107. ///////////////////////////////////////////////////////////////////////////////
  108. // GetDeviceAddress -- gets the device hardware address
  109. // Error Codes:
  110. // NO_ERROR if successful
  111. // ERROR_NOT_ENOUGH_MEMORY if memory allocation failes
  112. // ERROR_INVALID_HANDLE if can't build the variable bindings
  113. // SNMP_ERRORSTATUS_TOOBIG if the packet returned is big
  114. // SNMP_ERRORSTATUS_NOSUCHNAME if the OID isn't supported
  115. // SNMP_ERRORSTATUS_BADVALUE
  116. // SNMP_ERRORSTATUS_READONLY
  117. // SNMP_ERRORSTATUS_GENERR
  118. // SNMP_MGMTAPI_TIMEOUT -- set by GetLastError()
  119. // SNMP_MGMTAPI_SELECT_FDERRORS -- set by GetLastError()
  120. // SNMPAPI_ERROR if open fails -- set by GetLastError()
  121. DWORD
  122. CStdMib::GetDeviceHWAddress( LPTSTR out psztHWAddress,
  123. DWORD dwSize ) // Size of in characters in of HW address
  124. {
  125. DWORD dwRetCode = NO_ERROR;
  126. UINT i = 0;
  127. char szTmpHWAddr[256];
  128. // Process the variableBinding
  129. m_VarBindList.list = NULL;
  130. m_VarBindList.len = 0;
  131. // get the hardware address
  132. dwRetCode = OIDQuery(OT_DEVICE_ADDRESS, SNMP_GETNEXT); // query the first entry in the table
  133. if (dwRetCode != NO_ERROR)
  134. {
  135. goto cleanup;
  136. }
  137. while (1) // instead of walking the tree, do a get next, until we filled up the HW address -- saves on the network communications
  138. {
  139. i = 0;
  140. // process the variableBinding
  141. if ( IS_ASN_INTEGER(m_VarBindList, i) ) // check the ifType
  142. {
  143. if ( GET_ASN_NUMBER(m_VarBindList, i) == IFTYPE_ETHERNET)
  144. {
  145. StringCchPrintfA (szTmpHWAddr, COUNTOF (szTmpHWAddr), "%02X%02X%02X%02X%02X%02X", GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 0),
  146. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 1),
  147. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 2),
  148. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 3),
  149. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 4),
  150. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 5) );
  151. MBCS_TO_UNICODE(psztHWAddress, dwSize, szTmpHWAddr);
  152. dwRetCode = NO_ERROR;
  153. break;
  154. }
  155. else if ( GET_ASN_NUMBER(m_VarBindList, i) == IFTYPE_OTHER) // apperently, XEROX encodes their HW address w/ ifType = other
  156. {
  157. // check if the HWAddress is NULL
  158. if ( GET_ASN_STRING_LEN(m_VarBindList, i+1) != 0)
  159. {
  160. StringCchPrintfA (szTmpHWAddr, COUNTOF (szTmpHWAddr), "%02X%02X%02X%02X%02X%02X", GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 0),
  161. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 1),
  162. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 2),
  163. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 3),
  164. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 4),
  165. GET_ASN_OCTETSTRING_CHAR(m_VarBindList, i+1, 5) );
  166. MBCS_TO_UNICODE(psztHWAddress, dwSize, szTmpHWAddr);
  167. dwRetCode = NO_ERROR;
  168. break;
  169. }
  170. }
  171. }
  172. // didn't get what we were looking for, so copy the address over & do a another GetNext()
  173. if( !OIDVarBindCpy(&m_VarBindList) )
  174. {
  175. dwRetCode = GetLastError();
  176. goto cleanup;
  177. }
  178. if ( !SnmpUtilOidNCmp( &m_VarBindList.list[0].name, &OID_Mib2_ifTypeTree, OID_Mib2_ifTypeTree.idLength) )
  179. {
  180. break; // end of the tree
  181. }
  182. dwRetCode = OIDQuery(&m_VarBindList, SNMP_GETNEXT); // query the next entry in the table
  183. if (dwRetCode != NO_ERROR)
  184. {
  185. goto cleanup;
  186. }
  187. } // end while()
  188. cleanup:
  189. SnmpUtilVarBindListFree(&m_VarBindList);
  190. return dwRetCode;
  191. } // ::GetDeviceHWAddress()
  192. ///////////////////////////////////////////////////////////////////////////////
  193. // GetDeviceInfo -- gets the device description, such as the manufacturer string
  194. // Error Codes:
  195. // NO_ERROR if successful
  196. // ERROR_NOT_ENOUGH_MEMORY if memory allocation failes
  197. // ERROR_INVALID_HANDLE if can't build the variable bindings
  198. // SNMP_ERRORSTATUS_TOOBIG if the packet returned is big
  199. // SNMP_ERRORSTATUS_NOSUCHNAME if the OID isn't supported
  200. // SNMP_ERRORSTATUS_BADVALUE
  201. // SNMP_ERRORSTATUS_READONLY
  202. // SNMP_ERRORSTATUS_GENERR
  203. // SNMP_MGMTAPI_TIMEOUT -- set by GetLastError()
  204. // SNMP_MGMTAPI_SELECT_FDERRORS -- set by GetLastError()
  205. // SNMPAPI_ERROR if Open() for session fails
  206. DWORD
  207. CStdMib::GetDeviceName( LPTSTR out psztDescription,
  208. DWORD in dwSize ) //Size in characters of the psztDescription
  209. {
  210. DWORD dwRetCode = NO_ERROR;
  211. // Process the variableBinding
  212. m_VarBindList.list = NULL;
  213. m_VarBindList.len = 0;
  214. // 1st test for the support of Printer MIB -- note if Printer MIB supported, so is HR MIB
  215. BOOL bTestPrtMIB = TestPrinterMIB();
  216. char szTmpDescr[MAX_DEVICEDESCRIPTION_STR_LEN];
  217. UINT i=0;
  218. // process the bindings
  219. if (bTestPrtMIB) // parse the data from the HR MIB device entry
  220. {
  221. while (1) // instead of walking the tree, do a get next, until we filled up the HW address -- saves on the network communications
  222. {
  223. i = 0;
  224. dwRetCode = OIDQuery(OT_DEVICE_DESCRIPTION, SNMP_GETNEXT);
  225. if (dwRetCode != NO_ERROR)
  226. {
  227. goto cleanup;
  228. }
  229. // process the variableBinding
  230. if ( IS_ASN_OBJECTIDENTIFIER(m_VarBindList, i) ) // check the hrDeviceType
  231. {
  232. // compare it to hrDevicePrinter
  233. if (SnmpUtilOidCmp(GET_ASN_OBJECT(&m_VarBindList, i), &HRMIB_hrDevicePrinter) == 0)
  234. {
  235. // found the printer description, get the hrDeviceDescr
  236. if ( IS_ASN_OCTETSTRING(m_VarBindList, i) )
  237. {
  238. if (GET_ASN_OCTETSTRING(szTmpDescr, sizeof(szTmpDescr), m_VarBindList, i))
  239. {
  240. MBCS_TO_UNICODE(psztDescription, dwSize, szTmpDescr);
  241. dwRetCode = NO_ERROR;
  242. break;
  243. } else
  244. {
  245. dwRetCode = SNMP_ERRORSTATUS_TOOBIG;
  246. break;
  247. }
  248. }
  249. else
  250. {
  251. dwRetCode = SNMP_ERRORSTATUS_NOSUCHNAME;
  252. break;
  253. }
  254. }
  255. }
  256. // didn't get what we were looking for, so copy the address over & do a another GetNext()
  257. if( !OIDVarBindCpy(&m_VarBindList) )
  258. {
  259. dwRetCode = GetLastError();
  260. goto cleanup;
  261. }
  262. } // end while()
  263. } // if TestPrinterMIB() TRUE
  264. else
  265. {
  266. dwRetCode = OIDQuery(OT_DEVICE_SYSDESCR, SNMP_GET);
  267. if (dwRetCode != NO_ERROR)
  268. {
  269. goto cleanup;
  270. }
  271. // process the variables
  272. if (GET_ASN_OCTETSTRING(szTmpDescr, sizeof(szTmpDescr), m_VarBindList, i))
  273. {
  274. MBCS_TO_UNICODE(psztDescription, dwSize, szTmpDescr);
  275. dwRetCode = NO_ERROR;
  276. }
  277. } // if TestPrinterMIB() FALSE
  278. cleanup:
  279. SnmpUtilVarBindListFree(&m_VarBindList);
  280. return dwRetCode;
  281. } // ::GetDeviceStatus()
  282. ///////////////////////////////////////////////////////////////////////////////
  283. // TestPrinterMIB -- tests if the device supports Printer MIB
  284. BOOL
  285. CStdMib::TestPrinterMIB( )
  286. {
  287. DWORD dwRetCode = NO_ERROR;
  288. BOOL bRetCode = FALSE;
  289. // Process the variableBinding
  290. m_VarBindList.list = NULL;
  291. m_VarBindList.len = 0;
  292. dwRetCode = OIDQuery(OT_TEST_PRINTER_MIB, SNMP_GETNEXT);
  293. if (dwRetCode != NO_ERROR)
  294. {
  295. bRetCode = FALSE;
  296. goto cleanup;
  297. }
  298. // compare the resulting value w/ the Printer MIB tree value
  299. if (SnmpUtilOidNCmp(GET_ASN_OID_NAME(&m_VarBindList, 0), &PrtMIB_OidPrefix, PrtMIB_OidPrefix.idLength) == 0)
  300. {
  301. bRetCode = TRUE;
  302. goto cleanup;
  303. }
  304. cleanup:
  305. SnmpUtilVarBindListFree(&m_VarBindList);
  306. return (bRetCode);
  307. } // ::TestPrinterMIB()
  308. ///////////////////////////////////////////////////////////////////////////////
  309. // OIDQuery -- calls into the CTcpMib class to query the OIDs passed in
  310. DWORD
  311. CStdMib::OIDQuery( AsnObjectIdentifier in *pMibObjId,
  312. SNMPCMD in eSnmpCmd )
  313. {
  314. DWORD dwRetCode = NO_ERROR;
  315. if( m_pParent == NULL ) {
  316. dwRetCode = ERROR_INVALID_HANDLE;
  317. goto cleanup;
  318. }
  319. switch (eSnmpCmd)
  320. {
  321. case SNMP_GET:
  322. dwRetCode = m_pParent->SnmpGet(m_szAgent, m_szCommunity, m_dwDevIndex, pMibObjId, &m_VarBindList);
  323. goto cleanup;
  324. break;
  325. case SNMP_WALK:
  326. dwRetCode = m_pParent->SnmpWalk(m_szAgent, m_szCommunity, m_dwDevIndex, pMibObjId, &m_VarBindList);
  327. goto cleanup;
  328. break;
  329. case SNMP_GETNEXT:
  330. dwRetCode = m_pParent->SnmpGetNext(m_szAgent, m_szCommunity, m_dwDevIndex, pMibObjId, &m_VarBindList);
  331. goto cleanup;
  332. break;
  333. case SNMP_SET:
  334. default:
  335. dwRetCode = ERROR_NOT_SUPPORTED;
  336. goto cleanup;
  337. }
  338. cleanup:
  339. if (dwRetCode != NO_ERROR)
  340. {
  341. SnmpUtilVarBindListFree(&m_VarBindList);
  342. }
  343. return (dwRetCode);
  344. } // ::OIDQuery()
  345. ///////////////////////////////////////////////////////////////////////////////
  346. // OIDQuery -- calls into the CTcpMib class to query the OIDs passed in
  347. DWORD
  348. CStdMib::OIDQuery( RFC1157VarBindList inout *pVarBindList,
  349. SNMPCMD in eSnmpCmd )
  350. {
  351. DWORD dwRetCode = NO_ERROR;
  352. if( m_pParent == NULL ) {
  353. dwRetCode = ERROR_INVALID_HANDLE;
  354. goto cleanup;
  355. }
  356. switch (eSnmpCmd)
  357. {
  358. case SNMP_GET:
  359. dwRetCode = m_pParent->SnmpGet(m_szAgent, m_szCommunity, m_dwDevIndex, pVarBindList);
  360. goto cleanup;
  361. break;
  362. case SNMP_WALK:
  363. dwRetCode = m_pParent->SnmpWalk(m_szAgent, m_szCommunity, m_dwDevIndex, pVarBindList);
  364. goto cleanup;
  365. break;
  366. case SNMP_GETNEXT:
  367. dwRetCode = m_pParent->SnmpGetNext(m_szAgent, m_szCommunity, m_dwDevIndex, pVarBindList);
  368. goto cleanup;
  369. break;
  370. case SNMP_SET:
  371. default:
  372. dwRetCode = ERROR_NOT_SUPPORTED;
  373. goto cleanup;
  374. }
  375. cleanup:
  376. if (dwRetCode != NO_ERROR)
  377. {
  378. SnmpUtilVarBindListFree(pVarBindList);
  379. }
  380. return (dwRetCode);
  381. } // ::OIDQuery()
  382. ///////////////////////////////////////////////////////////////////////////////
  383. // OIDVarBindCpy --
  384. BOOL
  385. CStdMib::OIDVarBindCpy( RFC1157VarBindList inout *pVarBindList )
  386. {
  387. UINT i=0;
  388. AsnObjectIdentifier tempOid;
  389. for (i=0; i< PRFC1157_VARBINDLIST_LEN(pVarBindList); i++)
  390. {
  391. if( SnmpUtilOidCpy( &tempOid, &(PGET_ASN_OID_NAME(pVarBindList, i))))
  392. {
  393. SnmpUtilVarBindFree(&(pVarBindList->list[i]));
  394. if ( SnmpUtilOidCpy(&(PGET_ASN_OID_NAME(pVarBindList, i)), &tempOid))
  395. {
  396. PGET_ASN_TYPE(pVarBindList, i) = ASN_NULL;
  397. SnmpUtilOidFree(&tempOid);
  398. }
  399. else
  400. {
  401. return(FALSE);
  402. }
  403. }
  404. else
  405. {
  406. return(FALSE);
  407. }
  408. }
  409. return( TRUE );
  410. } // ::OIDVarBindCpy()
  411. ///////////////////////////////////////////////////////////////////////////////
  412. // MapJobErrorToSpooler -- Maps the received device error to the spooler
  413. // error codes.
  414. // Return Values:
  415. // Spooler device error codes
  416. DWORD
  417. CStdMib::MapJobErrorToSpooler( const DWORD in dwStatus)
  418. {
  419. DWORD dwRetCode = NO_ERROR;
  420. switch (dwStatus)
  421. {
  422. case ASYNCH_WARMUP:
  423. case ASYNCH_INITIALIZING:
  424. dwRetCode = JOB_STATUS_OFFLINE;
  425. break;
  426. case ASYNCH_DOOR_OPEN:
  427. case ASYNCH_PRINTER_ERROR:
  428. case ASYNCH_TONER_LOW:
  429. case ASYNCH_OUTPUT_BIN_FULL:
  430. case ASYNCH_STATUS_UNKNOWN:
  431. case ASYNCH_RESET:
  432. case ASYNCH_MANUAL_FEED:
  433. case ASYNCH_BUSY:
  434. case ASYNCH_PAPER_JAM:
  435. case ASYNCH_TONER_GONE:
  436. dwRetCode = JOB_STATUS_ERROR;
  437. break;
  438. case ASYNCH_PAPER_OUT:
  439. dwRetCode = JOB_STATUS_PAPEROUT;
  440. break;
  441. case ASYNCH_OFFLINE:
  442. dwRetCode = JOB_STATUS_OFFLINE;
  443. break;
  444. case ASYNCH_INTERVENTION:
  445. dwRetCode = JOB_STATUS_USER_INTERVENTION;
  446. break;
  447. case ASYNCH_PRINTING:
  448. dwRetCode = JOB_STATUS_PRINTING;
  449. break;
  450. case ASYNCH_ONLINE:
  451. dwRetCode = NO_ERROR;
  452. break;
  453. default:
  454. dwRetCode = JOB_STATUS_PRINTING;
  455. }
  456. return dwRetCode;
  457. } // ::MapJobErrorToSpooler()
  458. BOOL CStdMib::GetAsnOctetString( char *pszStr,
  459. DWORD dwCount,
  460. RFC1157VarBindList *pVarBindList,
  461. UINT i) {
  462. _ASSERTE( pszStr && pVarBindList );
  463. DWORD dwSize = GET_ASN_STRING_LEN( *pVarBindList, i);
  464. return dwCount >= dwSize ?
  465. memcpy(pszStr, pVarBindList->list[i].value.asnValue.string.stream, dwSize) != NULL :
  466. FALSE;
  467. }