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.

1872 lines
61 KiB

  1. /*
  2. * HrDeviceEntry.c v0.10
  3. * Generated in conjunction with Management Factory scripts:
  4. * script version: SNMPv1, 0.16, Apr 25, 1996
  5. * project: D:\TEMP\EXAMPLE\HOSTMIB
  6. ****************************************************************************
  7. * *
  8. * (C) Copyright 1995 DIGITAL EQUIPMENT CORPORATION *
  9. * *
  10. * This software is an unpublished work protected under the *
  11. * the copyright laws of the United States of America, all *
  12. * rights reserved. *
  13. * *
  14. * In the event this software is licensed for use by the United *
  15. * States Government, all use, duplication or disclosure by the *
  16. * United States Government is subject to restrictions as set *
  17. * forth in either subparagraph (c)(1)(ii) of the Rights in *
  18. * Technical Data And Computer Software Clause at DFARS *
  19. * 252.227-7013, or the Commercial Computer Software Restricted *
  20. * Rights Clause at FAR 52.221-19, whichever is applicable. *
  21. * *
  22. ****************************************************************************
  23. *
  24. * Facility:
  25. *
  26. * Windows NT SNMP Extension Agent
  27. *
  28. * Abstract:
  29. *
  30. * This module contains the code for dealing with the get, set, and
  31. * instance name routines for the HrDeviceEntry. Actual instrumentation code is
  32. * supplied by the developer.
  33. *
  34. * Functions:
  35. *
  36. * A get and set routine for each attribute in the class.
  37. *
  38. * The routines for instances within the class.
  39. *
  40. * Author:
  41. *
  42. * D. D. Burns @ Webenable Inc
  43. *
  44. * Revision History:
  45. *
  46. * V1.00 - 04/27/97 D. D. Burns Genned: Thu Nov 07 16:41:55 1996
  47. *
  48. *
  49. */
  50. #include <windows.h>
  51. #include <malloc.h>
  52. #include <snmp.h>
  53. #include "mib.h"
  54. #include "smint.h"
  55. #include "hostmsmi.h"
  56. #include "user.h" /* Developer supplied include file */
  57. #include "HMCACHE.H" /* Cache-related definitions */
  58. #include "HRDEVENT.H" /* HrDevice Table related definitions */
  59. #include <stdio.h> /* for sprintf */
  60. /*
  61. |==============================================================================
  62. | Function prototypes for this module.
  63. |
  64. */
  65. /* Gen_SingleDevices - Generate Single Device row entries in HrDevice */
  66. BOOL
  67. Gen_SingleDevices( void );
  68. #if defined(CACHE_DUMP)
  69. /* debug_print_hrdevice - Prints a Row from HrDevice */
  70. static void
  71. debug_print_hrdevice(
  72. CACHEROW *row /* Row in hrDiskStorage table */
  73. );
  74. #endif
  75. /*
  76. |==============================================================================
  77. | Create the list-head for the HrDevice table cache.
  78. |
  79. | This list-head is globally accessible so the logic that loads the "sub"
  80. | tables can scan this cache for matches (among other reasons).
  81. |
  82. | (This macro is defined in "HMCACHE.H").
  83. */
  84. CACHEHEAD_INSTANCE(hrDevice_cache, debug_print_hrdevice);
  85. /*
  86. |==============================================================================
  87. | Initial Load Device
  88. |
  89. | This number is the index into hrDevice table for the entry that corresponds
  90. | to the disk from which the system was initially loaded.
  91. |
  92. | This static location serves as "cache" for the value of
  93. | "HrSystemInitialLoadDevice" (serviced by code in "HRSYSTEM.C").
  94. |
  95. | It is initialized by function "Gen_Fixed_disks()" in module "HRDISKST.C"
  96. | which is called by way of "Gen_HrDiskStorage_Cache()" invoked from this
  97. | module. It is during the scan of the fixed disks that we discover from which
  98. | one the system booted.
  99. */
  100. ULONG InitLoadDev_index=0;
  101. /*
  102. * GetHrDeviceIndex
  103. * A unique value for each device contained by the host. The value for
  104. * each device must remain constant at least from one re-initi
  105. *
  106. * Gets the value for HrDeviceIndex.
  107. *
  108. * Arguments:
  109. *
  110. * outvalue address to return variable value
  111. * accesss Reserved for future security use
  112. * instance address of instance name as ordered native
  113. * data type(s)
  114. *
  115. * Return Codes:
  116. *
  117. * Standard PDU error codes.
  118. *
  119. * SNMP_ERRORSTATUS_NOERROR Successful get
  120. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  121. * mibtget.c v0.10
  122. *
  123. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  124. | hrDeviceIndex
  125. |
  126. | ACCESS SYNTAX
  127. | read-only INTEGER (1..2147483647)
  128. |
  129. | "A unique value for each device contained by the host. The value for each
  130. | device must remain constant at least from one re-initialization of the agent
  131. | to the next re-initialization."
  132. |
  133. | DISCUSSION:
  134. |
  135. | As mentioned in the discussion for this table, all entries for this table
  136. | are derived from a local cache built at start-up time. As a consequence the
  137. | maximum value of this attribute is fixed at SNMP service start-time.
  138. |
  139. |============================================================================
  140. | 1.3.6.1.2.1.25.3.2.1.1.<instance>
  141. | | | | |
  142. | | | | *hrDeviceIndex
  143. | | | *hrDeviceEntry
  144. | | *hrDeviceTable
  145. | *-hrDevice
  146. */
  147. UINT
  148. GetHrDeviceIndex(
  149. OUT Integer *outvalue ,
  150. IN Access_Credential *access ,
  151. IN InstanceName *instance )
  152. {
  153. ULONG index; /* As fetched from instance structure */
  154. CACHEROW *row; /* Row entry fetched from cache */
  155. /*
  156. | Grab the instance information
  157. */
  158. index = GET_INSTANCE(0);
  159. /*
  160. | Use it to find the right entry in the cache
  161. */
  162. if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
  163. return SNMP_ERRORSTATUS_GENERR;
  164. }
  165. /*
  166. | Return the "hrDeviceIndex" value from this entry
  167. */
  168. *outvalue = row->attrib_list[HRDV_INDEX].u.unumber_value;
  169. return SNMP_ERRORSTATUS_NOERROR ;
  170. } /* end of GetHrDeviceIndex() */
  171. /*
  172. * GetHrDeviceType
  173. * An indication of the type of device.
  174. *
  175. * Gets the value for HrDeviceType.
  176. *
  177. * Arguments:
  178. *
  179. * outvalue address to return variable value
  180. * accesss Reserved for future security use
  181. * instance address of instance name as ordered native
  182. * data type(s)
  183. *
  184. * Return Codes:
  185. *
  186. * Standard PDU error codes.
  187. *
  188. * SNMP_ERRORSTATUS_NOERROR Successful get
  189. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  190. * mibtget.c v0.10
  191. *
  192. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  193. | hrDeviceType
  194. |
  195. | ACCESS SYNTAX
  196. | read-only OBJECT IDENTIFIER
  197. |
  198. | "An indication of the type of device.
  199. |
  200. | If this value is `hrDeviceProcessor { hrDeviceTypes3 }'
  201. | then an entry exists in the hrProcessorTable
  202. | which corresponds to this device.
  203. |
  204. | If this value is `hrDeviceNetwork { hrDeviceTypes 4}',
  205. | then an entry exists in the hrNetworkTable
  206. | which corresponds to this device.
  207. |
  208. | If this value is `hrDevicePrinter { hrDeviceTypes 5}',
  209. | then an entry exists in the hrPrinterTable
  210. | which corresponds to this device.
  211. |
  212. | If this value is `hrDeviceDiskStorage {hrDeviceTypes 6 }',
  213. | then an entry exists in the
  214. | hrDiskStorageTable which corresponds to this
  215. | device."
  216. |
  217. | DISCUSSION:
  218. |
  219. | The list of registered device types (i.e. values that can be used in the
  220. | hrDeviceType attribute) are:
  221. |
  222. | hrDeviceOther OBJECT IDENTIFIER ::= { hrDeviceTypes 1 }
  223. | hrDeviceUnknown OBJECT IDENTIFIER ::= { hrDeviceTypes 2 }
  224. | hrDeviceProcessor OBJECT IDENTIFIER ::= { hrDeviceTypes 3 }
  225. | hrDeviceNetwork OBJECT IDENTIFIER ::= { hrDeviceTypes 4 }
  226. | hrDevicePrinter OBJECT IDENTIFIER ::= { hrDeviceTypes 5 }
  227. | hrDeviceDiskStorage OBJECT IDENTIFIER ::= { hrDeviceTypes 6 }
  228. | hrDeviceVideo OBJECT IDENTIFIER ::= { hrDeviceTypes 10 }
  229. | hrDeviceAudio OBJECT IDENTIFIER ::= { hrDeviceTypes 11 }
  230. | hrDeviceCoprocessor OBJECT IDENTIFIER ::= { hrDeviceTypes 12 }
  231. | hrDeviceKeyboard OBJECT IDENTIFIER ::= { hrDeviceTypes 13 }
  232. | hrDeviceModem OBJECT IDENTIFIER ::= { hrDeviceTypes 14 }
  233. | hrDeviceParallelPort OBJECT IDENTIFIER ::= { hrDeviceTypes 15 }
  234. | hrDevicePointing OBJECT IDENTIFIER ::= { hrDeviceTypes 16 }
  235. | hrDeviceSerialPort OBJECT IDENTIFIER ::= { hrDeviceTypes 17 }
  236. | hrDeviceTape OBJECT IDENTIFIER ::= { hrDeviceTypes 18 }
  237. | hrDeviceClock OBJECT IDENTIFIER ::= { hrDeviceTypes 19 }
  238. | hrDeviceVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 20 }
  239. | hrDeviceNonVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 21 }
  240. |
  241. | (See discussion above for hrDeviceTable).
  242. |============================================================================
  243. | 1.3.6.1.2.1.25.3.1.n
  244. | | | |
  245. | | | * Identifying arc for type
  246. | | *-hrDeviceTypes (OIDs specifying device types)
  247. | *-hrDevice
  248. |
  249. | 1.3.6.1.2.1.25.3.2.1.2.<instance>
  250. | | | | |
  251. | | | | *-hrDeviceType
  252. | | | *-hrDeviceEntry
  253. | | *-hrDeviceTable
  254. | *-hrDevice
  255. */
  256. UINT
  257. GetHrDeviceType(
  258. OUT ObjectIdentifier *outvalue ,
  259. IN Access_Credential *access ,
  260. IN InstanceName *instance )
  261. {
  262. ULONG index; /* As fetched from instance structure */
  263. CACHEROW *row; /* Row entry fetched from cache */
  264. /*
  265. | Grab the instance information
  266. */
  267. index = GET_INSTANCE(0);
  268. /*
  269. | Use it to find the right entry in the cache
  270. */
  271. if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
  272. return SNMP_ERRORSTATUS_GENERR;
  273. }
  274. /*
  275. | By convention with the cache-building function "Gen_HrDevice_Cache()",
  276. | and it's minions the cached value is the right-most arc we must return
  277. | as the value.
  278. |
  279. | Hence whatever cache entry we retrieve, we tack the number retrieved
  280. | from the cache for this attribute onto { hrDeviceType ... }.
  281. */
  282. if ( (outvalue->ids = SNMP_malloc(10 * sizeof( UINT ))) == NULL) {
  283. return SNMP_ERRORSTATUS_GENERR;
  284. }
  285. outvalue->idLength = 10;
  286. /*
  287. | Load in the full hrDeviceType OID:
  288. |
  289. | 1.3.6.1.2.1.25.3.1.n
  290. | | | |
  291. | | | * Identifying arc for type
  292. | | *-hrDeviceTypes (OIDs specifying device types)
  293. | *-hrDevice
  294. */
  295. outvalue->ids[0] = 1;
  296. outvalue->ids[1] = 3;
  297. outvalue->ids[2] = 6;
  298. outvalue->ids[3] = 1;
  299. outvalue->ids[4] = 2;
  300. outvalue->ids[5] = 1;
  301. outvalue->ids[6] = 25;
  302. outvalue->ids[7] = 3;
  303. outvalue->ids[8] = 1;
  304. /* Cached Device Type indicator */
  305. outvalue->ids[9] = row->attrib_list[HRDV_TYPE].u.unumber_value;
  306. return SNMP_ERRORSTATUS_NOERROR ;
  307. } /* end of GetHrDeviceType() */
  308. /*
  309. * GetHrDeviceDesc
  310. * A textual description of this device, including the device's
  311. * manufacturer and revision, and optionally, its serial number.
  312. *
  313. * Gets the value for HrDeviceDesc.
  314. *
  315. * Arguments:
  316. *
  317. * outvalue address to return variable value
  318. * accesss Reserved for future security use
  319. * instance address of instance name as ordered native
  320. * data type(s)
  321. *
  322. * Return Codes:
  323. *
  324. * Standard PDU error codes.
  325. *
  326. * SNMP_ERRORSTATUS_NOERROR Successful get
  327. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  328. * mibtget.c v0.10
  329. *
  330. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  331. | hrDeviceDescr
  332. |
  333. | ACCESS SYNTAX
  334. | read-only DisplayString (SIZE (0..64))
  335. |
  336. | "A textual description of this device, including the device's manufacturer and
  337. | revision, and optionally, its serial number."
  338. |
  339. | DISCUSSION:
  340. |
  341. | (See discussion above for hrDeviceTable, the information source for this
  342. | attribute depends on the device type).
  343. |
  344. |============================================================================
  345. | 1.3.6.1.2.1.25.3.2.1.3.<instance>
  346. | | | | |
  347. | | | | *-hrDeviceDescr
  348. | | | *-hrDeviceEntry
  349. | | *-hrDeviceTable
  350. | *-hrDevice
  351. */
  352. UINT
  353. GetHrDeviceDesc(
  354. OUT Simple_DisplayString *outvalue ,
  355. IN Access_Credential *access ,
  356. IN InstanceName *instance )
  357. {
  358. ULONG index; /* As fetched from instance structure */
  359. CACHEROW *row; /* Row entry fetched from cache */
  360. /*
  361. | Grab the instance information
  362. */
  363. index = GET_INSTANCE(0);
  364. /*
  365. | Use it to find the right entry in the cache
  366. */
  367. if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
  368. return SNMP_ERRORSTATUS_GENERR;
  369. }
  370. outvalue->string = row->attrib_list[HRDV_DESCR].u.string_value;
  371. /* "Truncate" here to meet RFC as needed*/
  372. if ((outvalue->length = strlen(outvalue->string)) > 64) {
  373. outvalue->length = 64;
  374. }
  375. return SNMP_ERRORSTATUS_NOERROR ;
  376. } /* end of GetHrDeviceDesc() */
  377. /*
  378. * GetHrDeviceID
  379. * The product ID for this device.
  380. *
  381. * Gets the value for HrDeviceID.
  382. *
  383. * Arguments:
  384. *
  385. * outvalue address to return variable value
  386. * accesss Reserved for future security use
  387. * instance address of instance name as ordered native
  388. * data type(s)
  389. *
  390. * Return Codes:
  391. *
  392. * Standard PDU error codes.
  393. *
  394. * SNMP_ERRORSTATUS_NOERROR Successful get
  395. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  396. * mibtget.c v0.10
  397. *
  398. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  399. | hrDeviceID
  400. |
  401. | ACCESS SYNTAX
  402. | read-only ProductID
  403. |
  404. | "The product ID for this device."
  405. |
  406. | ProductID ::= OBJECT IDENTIFIER
  407. |
  408. | "unknownProduct will be used for any unknown ProductID:
  409. | unknownProduct OBJECT IDENTIFIER ::= { 0 0 }
  410. |
  411. | DISCUSSION:
  412. |
  413. | <POA-10> I anticipate always using "unknownProduct" as the value for this
  414. | attribute, as I can envision no systematic means of acquiring a registered
  415. | OID for all devices to be used as the value for this attribute.
  416. |
  417. | RESOLVED >>>>>>>>
  418. | <POA-10> Returning an unknown Product ID is acceptable.
  419. | RESOLVED >>>>>>>>
  420. |============================================================================
  421. | 1.3.6.1.2.1.25.3.2.1.4.<instance>
  422. | | | | |
  423. | | | | *-hrDeviceID
  424. | | | *-hrDeviceEntry
  425. | | *-hrDeviceTable
  426. | *-hrDevice
  427. */
  428. UINT
  429. GetHrDeviceID(
  430. OUT ProductID *outvalue ,
  431. IN Access_Credential *access ,
  432. IN InstanceName *instance )
  433. {
  434. /*
  435. | The deal on this attribute is that we'll never have a valid OID value
  436. | for this attribute. Consequently, we always return the standard
  437. | "unknown" OID value ("0.0") regardless of the instance value (which
  438. | by now in the calling sequence of things has been validated anyway).
  439. */
  440. if ( (outvalue->ids = SNMP_malloc(2 * sizeof( UINT ))) == NULL) {
  441. return SNMP_ERRORSTATUS_GENERR;
  442. }
  443. outvalue->idLength = 2;
  444. /*
  445. | Load in the OID value for "unknown" for ProductID: "0.0"
  446. */
  447. outvalue->ids[0] = 0;
  448. outvalue->ids[1] = 0;
  449. return SNMP_ERRORSTATUS_NOERROR ;
  450. } /* end of GetHrDeviceID() */
  451. /*
  452. * GetHrDeviceStatus
  453. * The current operational state of the device described by this row of the
  454. * table. A value unknown (1) indicates that the current
  455. *
  456. * Gets the value for HrDeviceStatus.
  457. *
  458. * Arguments:
  459. *
  460. * outvalue address to return variable value
  461. * accesss Reserved for future security use
  462. * instance address of instance name as ordered native
  463. * data type(s)
  464. *
  465. * Return Codes:
  466. *
  467. * Standard PDU error codes.
  468. *
  469. * SNMP_ERRORSTATUS_NOERROR Successful get
  470. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  471. * mibtget.c v0.10
  472. *
  473. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  474. | hrDeviceStatus
  475. |
  476. | ACCESS SYNTAX
  477. | read-only INTEGER {unknown(1),running(2),warning(3),testing(4),
  478. | down(5)}
  479. |
  480. | "The current operational state of the device described by this row of the
  481. | table. A value unknown(1) indicates that the current state of the device is
  482. | unknown. running(2) indicates that the device is up and running and that no
  483. | unusual error conditions are known. The warning(3) state indicates that agent
  484. | has been informed of an unusual error condition by the operational software
  485. | (e.g., a disk device driver) but that the device is still 'operational'. An
  486. | example would be high number of soft errors on a disk. A value of testing(4),
  487. | indicates that the device is not available for use because it is in the
  488. | testing state. The state of down(5) is used only when the agent has been
  489. | informed that the device is not available for any use."
  490. |
  491. | DISCUSSION:
  492. |
  493. | For those devices for which a driver can be queried for the device status,
  494. | this is done. For all other circumstances, "unknown(1)" is returned.
  495. |
  496. | (See discussion above for hrDeviceTable, the information source for this
  497. | attribute depends on the device type).
  498. |
  499. |============================================================================
  500. | 1.3.6.1.2.1.25.3.2.1.5.<instance>
  501. | | | | |
  502. | | | | *-hrDeviceStatus
  503. | | | *-hrDeviceEntry
  504. | | *-hrDeviceTable
  505. | *-hrDevice
  506. */
  507. UINT
  508. GetHrDeviceStatus(
  509. OUT INThrDeviceStatus *outvalue ,
  510. IN Access_Credential *access ,
  511. IN InstanceName *instance )
  512. {
  513. ULONG index; /* As fetched from instance structure */
  514. CACHEROW *row; /* Row entry fetched from cache */
  515. /*
  516. | Grab the instance information
  517. */
  518. index = GET_INSTANCE(0);
  519. /*
  520. | Use it to find the right entry in the cache
  521. */
  522. if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
  523. return SNMP_ERRORSTATUS_GENERR;
  524. }
  525. /*
  526. | By convention with the cache-building function "Gen_HrDevice_Cache()",
  527. | and its minions the cached value in the row just fetched above for
  528. | the "hrDeviceType" attribute (indexed by our symbol "HRDV_TYPE") is the
  529. | last arc in the OID that specifies the type of device for which we need
  530. | to return status/errors.
  531. |
  532. | The scheme for returning status depends on the value of the type to
  533. | dispatch to the correct code to handle that kind of device.
  534. |
  535. | Also, code that initializes the hrDevice cache for any given device
  536. | has the option of storing in the "hidden context" attribute (accessed via
  537. | our symbol "HIDDEN_CTX") information needed to access that device.
  538. |
  539. | For instance, the code that enters Printer devices into hrDevice (in
  540. | function "Gen_HrPrinter_Cache()" in "HRPRINTE.C") stores a string in
  541. | "HIDDEN_CTX" that is the printer name thereby allowing logic below to
  542. | re-open that printer to obtain status/errors.
  543. |
  544. */
  545. switch ( row->attrib_list[HRDV_TYPE].u.unumber_value ) {
  546. case HRDV_TYPE_LASTARC_PRINTER:
  547. /* (In "HRPRINTE.C") */
  548. if (!COMPUTE_hrPrinter_status(row, (UINT *) outvalue)) {
  549. return SNMP_ERRORSTATUS_GENERR;
  550. }
  551. break;
  552. case HRDV_TYPE_LASTARC_PROCESSOR:
  553. /* Any processor in the table is running */
  554. *outvalue = 2;
  555. break;
  556. case HRDV_TYPE_LASTARC_DISKSTORAGE:
  557. /* Stored by Gen_hrDiskStorage_cache() */
  558. *outvalue = row->attrib_list[HRDV_STATUS].u.unumber_value;
  559. break;
  560. case HRDV_TYPE_LASTARC_KEYBOARD:
  561. case HRDV_TYPE_LASTARC_POINTING:
  562. /* Any Keyboard or Mouse in the table is reasably presumed "running" */
  563. *outvalue = 2; // "running"
  564. break;
  565. case HRDV_TYPE_LASTARC_PARALLELPORT:
  566. case HRDV_TYPE_LASTARC_SERIALPORT:
  567. *outvalue = 1; // "Unknown"
  568. break;
  569. case HRDV_TYPE_LASTARC_OTHER:
  570. case HRDV_TYPE_LASTARC_UNKNOWN:
  571. case HRDV_TYPE_LASTARC_NETWORK:
  572. case HRDV_TYPE_LASTARC_VIDEO:
  573. case HRDV_TYPE_LASTARC_AUDIO:
  574. case HRDV_TYPE_LASTARC_COPROCESSOR:
  575. case HRDV_TYPE_LASTARC_MODEM:
  576. case HRDV_TYPE_LASTARC_TAPE:
  577. case HRDV_TYPE_LASTARC_CLOCK:
  578. case HRDV_TYPE_LASTARC_VOLMEMORY:
  579. case HRDV_TYPE_LASTARC_NONVOLMEMORY:
  580. *outvalue = 1; // "Unknown"
  581. break;
  582. default:
  583. return SNMP_ERRORSTATUS_GENERR;
  584. }
  585. return SNMP_ERRORSTATUS_NOERROR ;
  586. } /* end of GetHrDeviceStatus() */
  587. /*
  588. * GetHrDeviceErrors
  589. * The number of errors detected on this device. It should be noted that as
  590. * this object has a SYNTAX of Counter, that it does not
  591. *
  592. * Gets the value for HrDeviceErrors.
  593. *
  594. * Arguments:
  595. *
  596. * outvalue address to return variable value
  597. * accesss Reserved for future security use
  598. * instance address of instance name as ordered native
  599. * data type(s)
  600. *
  601. * Return Codes:
  602. *
  603. * Standard PDU error codes.
  604. *
  605. * SNMP_ERRORSTATUS_NOERROR Successful get
  606. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  607. * mibtget.c v0.10
  608. *
  609. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  610. | hrDeviceErrors
  611. | ACCESS SYNTAX
  612. | read-only Counter
  613. |
  614. | "The number of errors detected on this device. It should be noted that as
  615. | this object has a SYNTAX of Counter, that it does not have a defined initial
  616. | value. However, it is recommended that this object be initialized to zero."
  617. |
  618. |
  619. | DISCUSSION:
  620. |
  621. | For those devices for which a driver can be queried for the device errors,
  622. | this is done. For all other circumstances, "0" is returned.
  623. |
  624. | (See discussion above for hrDeviceTable, the information source for this
  625. | attribute depends on the device type).
  626. |
  627. |============================================================================
  628. | 1.3.6.1.2.1.25.3.2.1.6.<instance>
  629. | | | | |
  630. | | | | *-hrDeviceErrors
  631. | | | *-hrDeviceEntry
  632. | | *-hrDeviceTable
  633. | *-hrDevice
  634. */
  635. UINT
  636. GetHrDeviceErrors(
  637. OUT Counter *outvalue ,
  638. IN Access_Credential *access ,
  639. IN InstanceName *instance )
  640. {
  641. ULONG index; /* As fetched from instance structure */
  642. CACHEROW *row; /* Row entry fetched from cache */
  643. /*
  644. | Grab the instance information
  645. */
  646. index = GET_INSTANCE(0);
  647. /*
  648. | Use it to find the right entry in the cache
  649. */
  650. if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
  651. return SNMP_ERRORSTATUS_GENERR;
  652. }
  653. /*
  654. | By convention with the cache-building function "Gen_HrDevice_Cache()",
  655. | and its minions the cached value in the row just fetched above for
  656. | the "hrDeviceType" attribute (indexed by our symbol "HRDV_TYPE") is the
  657. | last arc in the OID that specifies the type of device for which we need
  658. | to return status/errors.
  659. |
  660. | The scheme for returning status depends on the value of the type to
  661. | dispatch to the correct code to handle that kind of device.
  662. |
  663. | Also, code that initializes the hrDevice cache for any given device
  664. | has the option of storing in the "hidden context" attribute (accessed via
  665. | our symbol "HIDDEN_CTX") information needed to access that device.
  666. |
  667. | For instance, the code that enters Printer devices into hrDevice (in
  668. | function "Gen_HrPrinter_Cache()" in "HRPRINTE.C") stores a string in
  669. | "HIDDEN_CTX" that is the printer name thereby allowing logic below to
  670. | re-open that printer to obtain status/errors.
  671. |
  672. */
  673. switch ( row->attrib_list[HRDV_TYPE].u.unumber_value ) {
  674. case HRDV_TYPE_LASTARC_PRINTER:
  675. /* (In "HRPRINTE.C") */
  676. if (!COMPUTE_hrPrinter_errors(row, outvalue)) {
  677. return SNMP_ERRORSTATUS_GENERR;
  678. }
  679. break;
  680. case HRDV_TYPE_LASTARC_PROCESSOR:
  681. /* If 'errors' ain't 0, odds are low you're gonna find out via SNMP */
  682. *outvalue = 0;
  683. break;
  684. case HRDV_TYPE_LASTARC_POINTING:
  685. case HRDV_TYPE_LASTARC_KEYBOARD:
  686. case HRDV_TYPE_LASTARC_PARALLELPORT:
  687. case HRDV_TYPE_LASTARC_SERIALPORT:
  688. /* 'errors' presumed 0 */
  689. *outvalue = 0;
  690. break;
  691. case HRDV_TYPE_LASTARC_OTHER:
  692. case HRDV_TYPE_LASTARC_UNKNOWN:
  693. case HRDV_TYPE_LASTARC_NETWORK:
  694. case HRDV_TYPE_LASTARC_DISKSTORAGE:
  695. case HRDV_TYPE_LASTARC_VIDEO:
  696. case HRDV_TYPE_LASTARC_AUDIO:
  697. case HRDV_TYPE_LASTARC_COPROCESSOR:
  698. case HRDV_TYPE_LASTARC_MODEM:
  699. case HRDV_TYPE_LASTARC_TAPE:
  700. case HRDV_TYPE_LASTARC_CLOCK:
  701. case HRDV_TYPE_LASTARC_VOLMEMORY:
  702. case HRDV_TYPE_LASTARC_NONVOLMEMORY:
  703. *outvalue = 0;
  704. break;
  705. default:
  706. return SNMP_ERRORSTATUS_GENERR;
  707. }
  708. return SNMP_ERRORSTATUS_NOERROR ;
  709. } /* end of GetHrDeviceErrors() */
  710. /*
  711. * HrDeviceEntryFindInstance
  712. *
  713. * This routine is used to verify that the specified instance is
  714. * valid.
  715. *
  716. * Arguments:
  717. *
  718. * FullOid Address for the full oid - group, variable,
  719. * and instance information
  720. * instance Address for instance specification as an oid
  721. *
  722. * Return Codes:
  723. *
  724. * SNMP_ERRORSTATUS_NOERROR Instance found and valid
  725. * SNMP_ERRORSTATUS_NOSUCHNAME Invalid instance
  726. *
  727. */
  728. UINT
  729. HrDeviceEntryFindInstance( IN ObjectIdentifier *FullOid ,
  730. IN OUT ObjectIdentifier *instance )
  731. {
  732. UINT tmp_instance ;
  733. //
  734. // Developer instrumentation code to find appropriate instance goes here.
  735. // For non-tables, it is not necessary to modify this routine. However, if
  736. // there is any context that needs to be set, it can be done here.
  737. //
  738. if ( FullOid->idLength <= HRDEVICEENTRY_VAR_INDEX )
  739. // No instance was specified
  740. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  741. else if ( FullOid->idLength != HRDEVICEENTRY_VAR_INDEX + 1 )
  742. // Instance length is more than 1
  743. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  744. else
  745. // The only valid instance for a non-table are instance 0. If this
  746. // is a non-table, the following code validates the instances. If this
  747. // is a table, developer modification is necessary below.
  748. tmp_instance = FullOid->ids[ HRDEVICEENTRY_VAR_INDEX ] ;
  749. /*
  750. | For hrDeviceTable, the instance arc(s) is a single arc, and it must
  751. | correctly select an entry in the hrDeviceTable cache.
  752. | Check that here.
  753. */
  754. if ( FindTableRow(tmp_instance, &hrDevice_cache) == NULL ) {
  755. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  756. }
  757. else
  758. {
  759. // the instance is valid. Create the instance portion of the OID
  760. // to be returned from this call.
  761. instance->ids[ 0 ] = tmp_instance ;
  762. instance->idLength = 1 ;
  763. }
  764. return SNMP_ERRORSTATUS_NOERROR ;
  765. } /* end of HrDeviceEntryFindInstance() */
  766. /*
  767. * HrDeviceEntryFindNextInstance
  768. *
  769. * This routine is called to get the next instance. If no instance
  770. * was passed than return the first instance (1).
  771. *
  772. * Arguments:
  773. *
  774. * FullOid Address for the full oid - group, variable,
  775. * and instance information
  776. * instance Address for instance specification as an oid
  777. *
  778. * Return Codes:
  779. *
  780. * SNMP_ERRORSTATUS_NOERROR Instance found and valid
  781. * SNMP_ERRORSTATUS_NOSUCHNAME Invalid instance
  782. *
  783. */
  784. UINT
  785. HrDeviceEntryFindNextInstance( IN ObjectIdentifier *FullOid ,
  786. IN OUT ObjectIdentifier *instance )
  787. {
  788. //
  789. // Developer supplied code to find the next instance of class goes here.
  790. // If this is a class with cardinality 1, no modification of this routine
  791. // is necessary unless additional context needs to be set.
  792. // If the FullOid does not specify an instance, then the only instance
  793. // of the class is returned. If this is a table, the first row of the
  794. // table is returned.
  795. //
  796. // If an instance is specified and this is a non-table class, then NOSUCHNAME
  797. // is returned so that correct MIB rollover processing occurs. If this is
  798. // a table, then the next instance is the one following the current instance.
  799. // If there are no more instances in the table, return NOSUCHNAME.
  800. //
  801. CACHEROW *row;
  802. ULONG tmp_instance;
  803. if ( FullOid->idLength <= HRDEVICEENTRY_VAR_INDEX )
  804. {
  805. /*
  806. | Too short: must return the instance arc that selects the first
  807. | entry in the table if there is one.
  808. */
  809. tmp_instance = 0;
  810. }
  811. else {
  812. /*
  813. | There is at least one instance arc. Even if it is the only arc
  814. | we use it as the "index" in a request for the "NEXT" one.
  815. */
  816. tmp_instance = FullOid->ids[ HRDEVICEENTRY_VAR_INDEX ] ;
  817. }
  818. /* Now go off and try to find the next instance in the table */
  819. if ((row = FindNextTableRow(tmp_instance, &hrDevice_cache)) == NULL) {
  820. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  821. }
  822. instance->ids[ 0 ] = row->index ;
  823. instance->idLength = 1 ;
  824. return SNMP_ERRORSTATUS_NOERROR ;
  825. } /* end of HrDeviceEntryFindNextInstance() */
  826. /*
  827. * HrDeviceEntryConvertInstance
  828. *
  829. * This routine is used to convert the object id specification of an
  830. * instance into an ordered native representation. The object id format
  831. * is that object identifier that is returned from the Find Instance
  832. * or Find Next Instance routines. It is NOT the full object identifier
  833. * that contains the group and variable object ids as well. The native
  834. * representation is an argc/argv-like structure that contains the
  835. * ordered variables that define the instance. This is specified by
  836. * the MIB's INDEX clause. See RFC 1212 for information about the INDEX
  837. * clause.
  838. *
  839. *
  840. * Arguments:
  841. *
  842. * oid_spec Address of the object id instance specification
  843. * native_spec Address to return the ordered native instance
  844. * specification
  845. *
  846. * Return Codes:
  847. *
  848. * SUCCESS Conversion complete successfully
  849. * FAILURE Unable to convert object id into native format
  850. *
  851. */
  852. UINT
  853. HrDeviceEntryConvertInstance( IN ObjectIdentifier *oid_spec ,
  854. IN OUT InstanceName *native_spec )
  855. {
  856. static char *array; /* The address of this (char *) is passed back */
  857. /* as though it were an array of length 1 of these */
  858. /* types. */
  859. static ULONG inst; /* The address of this ULONG is passed back */
  860. /* (Obviously, no "free()" action is needed) */
  861. /* We only expect the one arc in "oid_spec" */
  862. inst = oid_spec->ids[0];
  863. array = (char *) &inst;
  864. native_spec->count = 1;
  865. native_spec->array = &array;
  866. return SUCCESS ;
  867. } /* end of HrDeviceEntryConvertInstance() */
  868. /*
  869. * HrDeviceEntryFreeInstance
  870. *
  871. * This routine is used to free an ordered native representation of an
  872. * instance name.
  873. *
  874. * Arguments:
  875. *
  876. * instance Address to return the ordered native instance
  877. * specification
  878. *
  879. * Return Codes:
  880. *
  881. *
  882. */
  883. void
  884. HrDeviceEntryFreeInstance( IN OUT InstanceName *instance )
  885. {
  886. /* No action needed for hrDevice Table */
  887. } /* end of HrDeviceEntryFreeInstance() */
  888. /*
  889. | End of Generated Code
  890. */
  891. /* Gen_HrDevice_Cache - Generate a initial cache for HrDevice Table */
  892. /* Gen_HrDevice_Cache - Generate a initial cache for HrDevice Table */
  893. /* Gen_HrDevice_Cache - Generate a initial cache for HrDevice Table */
  894. BOOL
  895. Gen_HrDevice_Cache(
  896. void
  897. )
  898. /*
  899. | EXPLICIT INPUTS:
  900. |
  901. | None.
  902. |
  903. | IMPLICIT INPUTS:
  904. |
  905. | The module-local head of the cache for the HrDevice table,
  906. | "HrDevice_cache".
  907. |
  908. | OUTPUTS:
  909. |
  910. | On Success:
  911. | Function returns TRUE indicating that the cache has been fully
  912. | populated with all "static" cache-able values.
  913. |
  914. | On any Failure:
  915. | Function returns FALSE (indicating "not enough storage" or other
  916. | internal logic error).
  917. |
  918. | THE BIG PICTURE:
  919. |
  920. | At subagent startup time, the cache for each table in the MIB is
  921. | populated with rows for each row in the table. This function is
  922. | invoked by the start-up code in "UserMibInit()" ("MIB.C") to
  923. | populate the cache for the HrDevice table.
  924. |
  925. | OTHER THINGS TO KNOW:
  926. |
  927. | There is one of these function for every table that has a cache.
  928. | Each is found in the respective source file.
  929. |
  930. |=============== From WebEnable Design Spec Rev 3 04/11/97==================
  931. | A Row in the hrDeviceTable
  932. |
  933. | "A (conceptual) entry for one device contained by the host. As an example, an
  934. | instance of the hrDeviceType object might be named hrDeviceType.3"
  935. |
  936. | HrDeviceEntry ::= SEQUENCE {
  937. | hrDeviceIndex INTEGER,
  938. | hrDeviceType OBJECT IDENTIFIER,
  939. | hrDeviceDescr DisplayString,
  940. | hrDeviceID ProductID,
  941. | hrDeviceStatus INTEGER,
  942. | hrDeviceErrors Counter
  943. | }
  944. |
  945. | DISCUSSION:
  946. |
  947. | This is the largest and most complicated table to populate. The strategy for
  948. | populating entries in this table is to execute a slug of code for each device
  949. | type (in the list below) in an attempt to find all instances of that device
  950. | type. For some devices, the code uses standard Win32 API functions, for
  951. | others it is clear that special-purpose code is needed to extract the relevant
  952. | information from the "behind the scenes" (direct NT kernel inquiries).
  953. |
  954. | This table is fully populated with respect to the other tables in the hrDevice
  955. | group. The other tables are sparse tables augmenting only selected entries in
  956. | hrDeviceTable.
  957. |
  958. | The list of registered device types (i.e. values that can be used in the
  959. | hrDeviceType attribute) are:
  960. |
  961. | hrDeviceOther OBJECT IDENTIFIER ::= { hrDeviceTypes 1 }
  962. | hrDeviceUnknown OBJECT IDENTIFIER ::= { hrDeviceTypes 2 }
  963. | hrDeviceProcessor OBJECT IDENTIFIER ::= { hrDeviceTypes 3 }
  964. | hrDeviceNetwork OBJECT IDENTIFIER ::= { hrDeviceTypes 4 }
  965. | hrDevicePrinter OBJECT IDENTIFIER ::= { hrDeviceTypes 5 }
  966. | hrDeviceDiskStorage OBJECT IDENTIFIER ::= { hrDeviceTypes 6 }
  967. | hrDeviceVideo OBJECT IDENTIFIER ::= { hrDeviceTypes 10 }
  968. | hrDeviceAudio OBJECT IDENTIFIER ::= { hrDeviceTypes 11 }
  969. | hrDeviceCoprocessor OBJECT IDENTIFIER ::= { hrDeviceTypes 12 }
  970. | hrDeviceKeyboard OBJECT IDENTIFIER ::= { hrDeviceTypes 13 }
  971. | hrDeviceModem OBJECT IDENTIFIER ::= { hrDeviceTypes 14 }
  972. | hrDeviceParallelPort OBJECT IDENTIFIER ::= { hrDeviceTypes 15 }
  973. | hrDevicePointing OBJECT IDENTIFIER ::= { hrDeviceTypes 16 }
  974. | hrDeviceSerialPort OBJECT IDENTIFIER ::= { hrDeviceTypes 17 }
  975. | hrDeviceTape OBJECT IDENTIFIER ::= { hrDeviceTypes 18 }
  976. | hrDeviceClock OBJECT IDENTIFIER ::= { hrDeviceTypes 19 }
  977. | hrDeviceVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 20 }
  978. | hrDeviceNonVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 21 }
  979. |
  980. | All of the foregoing types can be divided into two groups based on the
  981. | approach needed to acquire information about them. Information for the first
  982. | group can be queried using Win32 API functions while the second group
  983. | requires special inquiry-code.
  984. |
  985. | (1) Win32 Device-Types Win32 Function Used
  986. | ---------------------- -------------------
  987. | hrDeviceOther
  988. | Partitions DeviceIoControl (IOCTL_GET_PARTITION_INFO)
  989. |
  990. | hrDeviceProcessor GetSystemInfo
  991. | hrDevicePrinter EnumPrinterDrivers
  992. | hrDeviceDiskStorage QueryDosDevice/CreateFile (using physical drive access)
  993. | hrDeviceKeyboard GetKeyboardType
  994. | hrDevicePointing (Win32 function provides pointer-device button-count)
  995. |
  996. |
  997. | (2) Special-Inquiry Device-Types
  998. | ---------------------------------
  999. | hrDeviceNetwork Access is provided via special "mib2util" DLL
  1000. |
  1001. | hrDeviceParallelPort NtQuerySystemInformation(SYSTEM_DEVICE_INFORMATION)
  1002. | hrDeviceSerialPort
  1003. |
  1004. | hrDeviceVideo ??? NtQuerySystemInformation(SYSTEM_GDI_DRIVER_INFORMATION)
  1005. | hrDeviceAudio ???
  1006. | hrDeviceTape ???
  1007. |
  1008. |
  1009. | The following "devices" do not readily fall into either of the above groups
  1010. | and no attempt is made to recognize them:
  1011. |
  1012. | hrDeviceModem OBJECT IDENTIFIER ::= { hrDeviceTypes 14 }
  1013. | hrDeviceVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 20 }
  1014. | hrDeviceNonVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 21 }
  1015. | hrDeviceCoprocessor OBJECT IDENTIFIER ::= { hrDeviceTypes 12 }
  1016. | hrDeviceClock OBJECT IDENTIFIER ::= { hrDeviceTypes 19 }
  1017. |
  1018. |
  1019. | Other Implementation Details
  1020. | ----------------------------
  1021. | The bulk of the information for this table (and the associated sparse tables
  1022. | hrProcessorTable, hrNetworkTable, hrPrinterTable, hrDiskStorageTable,
  1023. | hrPartitionTable and hrFSTable) is acquired and stored in a local cache at the
  1024. | time the SNMP agent enrolls the DLL for the Host Resources MIB. This strategy
  1025. | is designed to reduce the hit on system resources when requests are processed.
  1026. | The only information that is acquired dynamically (on a per SNMP request) is
  1027. | information for variables likely to be dynamic: Status and Error status.
  1028. |
  1029. | One consequence of this strategy is that user-implemented changes to the
  1030. | system configuration (including changing printer drivers, or disk partition
  1031. | layout) will not be reported until the SNMP service is restarted.
  1032. |
  1033. |
  1034. |============================================================================
  1035. | 1.3.6.1.2.1.25.3.1.n
  1036. | | | |
  1037. | | | * Identifying arc for type
  1038. | | *-hrDeviceTypes (OIDs specifying device types)
  1039. | *-hrDevice
  1040. |
  1041. | 1.3.6.1.2.1.25.3.2.1....
  1042. | | | |
  1043. | | | *hrDeviceEntry
  1044. | | *hrDeviceTable
  1045. | *-hrDevice
  1046. |
  1047. */
  1048. {
  1049. /*
  1050. |============================================================================
  1051. |
  1052. | Call the "Gen_*_cache()" functions for each of the "sub-tables" within
  1053. | the hrDevice table.
  1054. |
  1055. | Each of these functions is responsible for:
  1056. |
  1057. | + populating the hrDevice cache with however many rows are called for
  1058. | given the device(s) available
  1059. |
  1060. | + creating and populating their own cache for the sub-table if
  1061. | the sub-table needs a cache. (If all the sub-table attributes
  1062. | are "computed" on request, then there is no need for a separate
  1063. | sub-table cache).
  1064. */
  1065. // Blow away any old copy of the cache
  1066. DestroyTable(&hrDevice_cache);
  1067. if (Gen_HrPrinter_Cache(HRDV_TYPE_LASTARC_PRINTER) == FALSE) {
  1068. DestroyTable(&hrDevice_cache);
  1069. return ( FALSE );
  1070. }
  1071. if (Gen_HrProcessor_Cache(HRDV_TYPE_LASTARC_PROCESSOR) == FALSE) {
  1072. DestroyTable(&hrDevice_cache);
  1073. return ( FALSE );
  1074. }
  1075. if (Gen_HrNetwork_Cache(HRDV_TYPE_LASTARC_NETWORK) == FALSE) {
  1076. DestroyTable(&hrDevice_cache);
  1077. return ( FALSE );
  1078. }
  1079. if (Gen_HrDiskStorage_Cache(HRDV_TYPE_LASTARC_DISKSTORAGE) == FALSE) {
  1080. DestroyTable(&hrDevice_cache);
  1081. return ( FALSE );
  1082. }
  1083. /*
  1084. |============================================================================
  1085. |
  1086. | Now handle the odd "one-off" devices for which potentially just a single
  1087. | entry is made into the existing hrDevice table cache.
  1088. */
  1089. if (Gen_SingleDevices() == FALSE) {
  1090. DestroyTable(&hrDevice_cache);
  1091. return ( FALSE );
  1092. }
  1093. #if defined(CACHE_DUMP)
  1094. PrintCache(&hrDevice_cache);
  1095. PrintCache(&hrDiskStorage_cache);
  1096. #endif
  1097. /*
  1098. | HrDevice cache generation complete.
  1099. */
  1100. return ( TRUE );
  1101. }
  1102. /* Gen_SingleDevices - Generate Single Device row entries in HrDevice */
  1103. /* Gen_SingleDevices - Generate Single Device row entries in HrDevice */
  1104. /* Gen_SingleDevices - Generate Single Device row entries in HrDevice */
  1105. BOOL
  1106. Gen_SingleDevices( void )
  1107. /*
  1108. | EXPLICIT INPUTS:
  1109. |
  1110. | None.
  1111. |
  1112. | IMPLICIT INPUTS:
  1113. |
  1114. | None.
  1115. |
  1116. | OUTPUTS:
  1117. |
  1118. | On Success:
  1119. | Function creates a new row entry populated with all "static" cache-able
  1120. | values for HrDevice table for each "one-off" device and returns TRUE.
  1121. |
  1122. | On any Failure:
  1123. | Function returns FALSE (indicating "not enough storage" or other
  1124. | internal logic error).
  1125. |
  1126. |
  1127. | THE BIG PICTURE:
  1128. |
  1129. | At subagent startup time, the cache for each table in the MIB is
  1130. | being populated. This function handles populating hrDevice with
  1131. | a row for each "single-type" device (such as keyboard).
  1132. |
  1133. | OTHER THINGS TO KNOW:
  1134. |
  1135. | Devices being added by this function are not associated with
  1136. | sub-tables.
  1137. |
  1138. | We handle:
  1139. | + Keyboard "device"
  1140. | + Pointing "device"
  1141. | + Parallel and Serial Port "devices"
  1142. |
  1143. */
  1144. {
  1145. UINT key_status; /* Value returned from GetKeyboardType() */
  1146. UINT button_count; /* Mouse button count from GetSystemMetrics */
  1147. CHAR msg[MAX_PATH+1]; /* (Big enough for constant strings below) */
  1148. UINT dev_number;
  1149. #define PHYS_SIZE 64
  1150. CHAR phys_name[PHYS_SIZE+1]; /* Buffer where a string like "\\.C:" (for */
  1151. /* example) is built for drive access. */
  1152. HANDLE hdrv; /* Handle to device */
  1153. UINT nPrevErrorMode; /* previous state of error-mode bit flags */
  1154. // ensures null terminated string
  1155. msg[MAX_PATH] = 0;
  1156. phys_name[PHYS_SIZE] = 0;
  1157. /*
  1158. |==============================================================================
  1159. | Keyboard Device
  1160. |
  1161. | If we can get keyboard type... */
  1162. if ((key_status = GetKeyboardType(0)) != 0 ) {
  1163. PCHAR key_type; /* Description string */
  1164. /* Select initial part of description string */
  1165. switch (key_status) {
  1166. case 1: key_type = "IBM PC/XT or compatible (83-key) keyboard"; break;
  1167. case 2: key_type = "Olivetti \"ICO\" (102-key) keyboard"; break;
  1168. case 3: key_type = "IBM PC/AT (84-key) or similar keyboard"; break;
  1169. case 4: key_type = "IBM enhanced (101- or 102-key) keyboard"; break;
  1170. case 5: key_type = "Nokia 1050 and similar keyboards"; break;
  1171. case 6: key_type = "Nokia 9140 and similar keyboards"; break;
  1172. case 7: key_type = "Japanese keyboard"; break;
  1173. default: key_type = "Unknown keyboard"; break;
  1174. }
  1175. /* Build the full description string */
  1176. _snprintf(msg, MAX_PATH, "%s, Subtype=(%d)", key_type, GetKeyboardType(1));
  1177. if (AddHrDeviceRow(HRDV_TYPE_LASTARC_KEYBOARD, // Last Type OID arc
  1178. msg, // Description string
  1179. NULL, // No hidden context
  1180. CA_UNKNOWN) == NULL) {
  1181. return ( FALSE ); /* Something blew */
  1182. }
  1183. }
  1184. /*
  1185. |==============================================================================
  1186. | Pointing Device
  1187. |
  1188. | If we can get Mouse Button count... */
  1189. if ((button_count = GetSystemMetrics(SM_CMOUSEBUTTONS)) != 0 ) {
  1190. _snprintf(msg, MAX_PATH, "%d-Buttons %s",
  1191. button_count,
  1192. (GetSystemMetrics(SM_MOUSEWHEELPRESENT)) ? " (with wheel)" : "");
  1193. if (AddHrDeviceRow(HRDV_TYPE_LASTARC_POINTING, // Last Type OID arc
  1194. msg, // Description string
  1195. NULL, // No hidden context
  1196. CA_UNKNOWN) == NULL) {
  1197. return ( FALSE ); /* Something blew */
  1198. }
  1199. }
  1200. /*
  1201. |==============================================================================
  1202. | LPT Devices
  1203. |
  1204. | For every LPTx device we can open successfully. . .
  1205. */
  1206. for (dev_number = 1; dev_number < 4; dev_number += 1) {
  1207. /* Build it for device n: */
  1208. _snprintf(phys_name, PHYS_SIZE, "LPT%d:", dev_number);
  1209. /*
  1210. | Suppress any attempt by the system to talk to the user
  1211. */
  1212. nPrevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  1213. /* Attempt to get a handle using this physical name string */
  1214. if ((hdrv = CreateFile(phys_name, // Device
  1215. GENERIC_READ, // Access mode
  1216. FILE_SHARE_READ, // Share Mode
  1217. NULL, // Security
  1218. OPEN_EXISTING, // CreationDistribution
  1219. FILE_ATTRIBUTE_NORMAL, // FlagsandAttributes
  1220. NULL // Template file
  1221. )) != INVALID_HANDLE_VALUE) {
  1222. /*
  1223. | Ok, we managed to get ahold of it, we'll put it in the table.
  1224. */
  1225. CloseHandle(hdrv); // Prefix bug 445177
  1226. if (AddHrDeviceRow(HRDV_TYPE_LASTARC_PARALLELPORT, // Last Type OID arc
  1227. phys_name, // Descr string
  1228. NULL, // No hidden context
  1229. CA_UNKNOWN) == NULL) {
  1230. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  1231. return ( FALSE ); /* Something blew */
  1232. }
  1233. } /* if (we managed to "CreateFile" the device) */
  1234. else {
  1235. /*
  1236. | Keep trucking if we couldn't open the device, but quit when we
  1237. | hit this error.
  1238. */
  1239. if (GetLastError() == ERROR_FILE_NOT_FOUND) {
  1240. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  1241. break;
  1242. }
  1243. }
  1244. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  1245. } /* For each device */
  1246. /*
  1247. |==============================================================================
  1248. | COM Devices
  1249. |
  1250. | For every COMx device we can open successfully. . .
  1251. */
  1252. for (dev_number = 1; dev_number <= 4; dev_number += 1) {
  1253. /* Build it for device n: */
  1254. _snprintf(phys_name, PHYS_SIZE, "COM%d:", dev_number);
  1255. /*
  1256. | Suppress any attempt by the system to talk to the user
  1257. */
  1258. nPrevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  1259. /* Attempt to get a handle using this physical name string */
  1260. if ((hdrv = CreateFile(phys_name, // Device
  1261. GENERIC_READ, // Access mode
  1262. FILE_SHARE_READ, // Share Mode
  1263. NULL, // Security
  1264. OPEN_EXISTING, // CreationDistribution
  1265. FILE_ATTRIBUTE_NORMAL, // FlagsandAttributes
  1266. NULL // Template file
  1267. )) != INVALID_HANDLE_VALUE) {
  1268. /*
  1269. | Ok, we managed to get ahold of it, we'll put it in the table.
  1270. */
  1271. CloseHandle(hdrv); // we don't use it anymore
  1272. if (AddHrDeviceRow(HRDV_TYPE_LASTARC_SERIALPORT, // Last Type OID arc
  1273. phys_name, // Descr string
  1274. NULL, // No hidden context
  1275. CA_UNKNOWN) == NULL) {
  1276. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  1277. return ( FALSE ); /* Something blew */
  1278. }
  1279. } /* if (we managed to "CreateFile" the device) */
  1280. else {
  1281. /*
  1282. | Keep trucking if we couldn't open the device, but quit when we
  1283. | hit this error (skip share failures).
  1284. */
  1285. if (GetLastError() == ERROR_FILE_NOT_FOUND) {
  1286. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  1287. break;
  1288. }
  1289. }
  1290. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  1291. } /* For each device */
  1292. return ( TRUE ); //--ft:09/28-- sundown cleanup
  1293. }
  1294. /* AddHrDeviceRow - Generate another Row Entry in HrDevice Table */
  1295. /* AddHrDeviceRow - Generate another Row Entry in HrDevice Table */
  1296. /* AddHrDeviceRow - Generate another Row Entry in HrDevice Table */
  1297. CACHEROW *
  1298. AddHrDeviceRow(
  1299. ULONG type_arc, /* Last Arc value for OID for Type */
  1300. LPSTR descr, /* Description string */
  1301. void *hidden_ctx, /* If non-NULL: Hidden-context value */
  1302. ATTRIB_TYPE hc_type /* Type of "hidden_ctx" */
  1303. )
  1304. /*
  1305. | EXPLICIT INPUTS:
  1306. |
  1307. | "type_arc" is the number that is inserted as the right-most arc in
  1308. | Object Identifier that is the cache entry for the hrDevicetype of the
  1309. | device.
  1310. |
  1311. | "descr" is a string pointer that is to be the cached value of
  1312. | the hrDeviceDesc attribute.
  1313. |
  1314. | "hidden_ctx" - If non-null, this is a pointer to the value to be
  1315. | stored as the "Hidden Context" attribute in the new row.
  1316. |
  1317. | "hc_type" is the type of "hidden_ctx" if hidden_ctx is non-null.
  1318. |
  1319. |
  1320. | IMPLICIT INPUTS:
  1321. |
  1322. | The module-local head of the cache for the HrDevice table,
  1323. | "HrDevice_cache".
  1324. |
  1325. | OUTPUTS:
  1326. |
  1327. | On Success:
  1328. | Function creates a new row entry populated with all "static" cache-able
  1329. | values for HrDevice table and returns a pointer to the new row entry.
  1330. |
  1331. | On any Failure:
  1332. | Function returns NULL (indicating "not enough storage" or other
  1333. | internal logic error).
  1334. |
  1335. |
  1336. | THE BIG PICTURE:
  1337. |
  1338. | At subagent startup time, the cache for each table in the MIB is
  1339. | populated with rows for each row in the table. This function is
  1340. | invoked by the start-up code in each of the "sub-hrDevicetable"
  1341. | files to populate the cache for the HrDevice table for the rows
  1342. | pertaining to a particular sub-table (hrProcessorTable, hrPrinterTable
  1343. | etc).
  1344. |
  1345. | OTHER THINGS TO KNOW:
  1346. |
  1347. | The "hidden_ctx" argument provides an easy way for the caller to stash
  1348. | a value useful for later run-time reference. For instance, "GET" functions
  1349. | for Printer devices may need a string that identifies the printer (for
  1350. | a given row-entry) in order to lookup the current value of an SNMP
  1351. | attribute (like the current status). So the "Hidden Context" attribute
  1352. | may be set to a string that can be submitted to a Win32 function to obtain
  1353. | the current status for the printer.
  1354. */
  1355. {
  1356. static /* NOTE: "static" is a 'must' */
  1357. ULONG table_index=0; /* HrDeviceTable index counter */
  1358. CACHEROW *row; /* --> Cache structure for row-being built */
  1359. /*
  1360. | OK, the caller wants another row in the table, get a row-entry created.
  1361. */
  1362. if ((row = CreateTableRow( HRDV_ATTRIB_COUNT ) ) == NULL) {
  1363. return ( NULL ); // Out of memory
  1364. }
  1365. /*
  1366. | Set up the standard-hrDevice attributes in the new row
  1367. */
  1368. /* =========== hrDeviceIndex ==========*/
  1369. row->attrib_list[HRDV_INDEX].attrib_type = CA_NUMBER;
  1370. row->attrib_list[HRDV_INDEX].u.unumber_value = (table_index += 1) ;
  1371. /* =========== hrDeviceType ==========
  1372. |
  1373. | Some GET functions for "computed" attributes expect to be able to use
  1374. | the value of the "hrDeviceType" cache value stored below to dispatch
  1375. | to appropriate code based on the device type (using the last type-OID arc
  1376. | as the "switch" value).
  1377. */
  1378. row->attrib_list[HRDV_TYPE].attrib_type = CA_NUMBER;
  1379. row->attrib_list[HRDV_TYPE].u.unumber_value = type_arc ;
  1380. /* =========== hrDeviceDescr ==========*/
  1381. row->attrib_list[HRDV_DESCR].attrib_type = CA_STRING;
  1382. if ( (row->attrib_list[HRDV_DESCR].u.string_value
  1383. = ( LPSTR ) malloc(strlen(descr) + 1)) == NULL) {
  1384. DestroyTableRow(row);
  1385. return ( NULL ); /* out of memory */
  1386. }
  1387. strcpy(row->attrib_list[HRDV_DESCR].u.string_value, descr);
  1388. /*
  1389. | The rest of the standard hrDevice attributes are "computed" at run time
  1390. */
  1391. /* =========== hrDeviceStatus ==========*/
  1392. row->attrib_list[HRDV_STATUS].attrib_type = CA_COMPUTED;
  1393. /* =========== hrDeviceErrors ==========*/
  1394. row->attrib_list[HRDV_ERRORS].attrib_type = CA_COMPUTED;
  1395. /*
  1396. |================================================================
  1397. | If they gave us a hidden-context attribute string, store it now.
  1398. */
  1399. if (hidden_ctx != NULL) {
  1400. switch (hc_type) {
  1401. case CA_STRING:
  1402. row->attrib_list[HIDDEN_CTX].attrib_type = CA_STRING;
  1403. if ( (row->attrib_list[HIDDEN_CTX].u.string_value
  1404. = ( LPSTR ) malloc(strlen((LPSTR)hidden_ctx) + 1)) == NULL) {
  1405. DestroyTableRow(row);
  1406. return ( NULL ); /* out of memory */
  1407. }
  1408. strcpy(row->attrib_list[HIDDEN_CTX].u.string_value, hidden_ctx);
  1409. break;
  1410. case CA_NUMBER:
  1411. row->attrib_list[HIDDEN_CTX].attrib_type = CA_NUMBER;
  1412. row->attrib_list[HIDDEN_CTX].u.unumber_value =
  1413. *((ULONG *) hidden_ctx);
  1414. break;
  1415. case CA_CACHE:
  1416. row->attrib_list[HIDDEN_CTX].attrib_type = CA_CACHE;
  1417. row->attrib_list[HIDDEN_CTX].u.cache = (CACHEHEAD *) hidden_ctx;
  1418. break;
  1419. case CA_UNKNOWN:
  1420. row->attrib_list[HIDDEN_CTX].attrib_type = CA_UNKNOWN;
  1421. break;
  1422. default:
  1423. DestroyTableRow(row);
  1424. return ( NULL ); /* Something wrong */
  1425. }
  1426. }
  1427. else {
  1428. /* Show no "Hidden-Context" attribute for this row */
  1429. row->attrib_list[HIDDEN_CTX].attrib_type = CA_UNKNOWN;
  1430. row->attrib_list[HIDDEN_CTX].u.string_value = NULL;
  1431. }
  1432. /*
  1433. | Now insert the filled-in CACHEROW structure into the
  1434. | cache-list for the hrDeviceTable.
  1435. */
  1436. if (AddTableRow(row->attrib_list[HRDV_INDEX].u.unumber_value, /* Index */
  1437. row, /* Row */
  1438. &hrDevice_cache /* Cache */
  1439. ) == FALSE) {
  1440. DestroyTableRow(row);
  1441. return ( NULL ); /* Internal Logic Error! */
  1442. }
  1443. /*
  1444. | Meet caller's expectation of receiving a pointer to the new row.
  1445. */
  1446. return ( row );
  1447. }
  1448. #if defined(CACHE_DUMP)
  1449. /* debug_print_hrdevice - Prints a Row from HrDevice */
  1450. /* debug_print_hrdevice - Prints a Row from HrDevice */
  1451. /* debug_print_hrdevice - Prints a Row from HrDevice */
  1452. static void
  1453. debug_print_hrdevice(
  1454. CACHEROW *row /* Row in hrDiskStorage table */
  1455. )
  1456. /*
  1457. | EXPLICIT INPUTS:
  1458. |
  1459. | "row" - points to the row to be dumped, if NULL, the function
  1460. | merely prints a suitable title.
  1461. |
  1462. | IMPLICIT INPUTS:
  1463. |
  1464. | - Symbols used to reference the attributes in the row entry.
  1465. | - File handle defined by OFILE, presumed to be open.
  1466. |
  1467. | OUTPUTS:
  1468. |
  1469. | On Success:
  1470. | Function prints a dump of the row in ASCII for debugging purposes
  1471. | on file handle OFILE.
  1472. |
  1473. | THE BIG PICTURE:
  1474. |
  1475. | Debugging only.
  1476. |
  1477. | OTHER THINGS TO KNOW:
  1478. */
  1479. {
  1480. char *type; /* String representation of device type */
  1481. if (row == NULL) {
  1482. fprintf(OFILE, "====================\n");
  1483. fprintf(OFILE, "hrDevice Table Cache\n");
  1484. fprintf(OFILE, "====================\n");
  1485. return;
  1486. }
  1487. fprintf(OFILE, "hrDeviceIndex. . . . . . . %d\n",
  1488. row->attrib_list[HRDV_INDEX].u.unumber_value);
  1489. switch (row->attrib_list[HRDV_TYPE].u.unumber_value) {
  1490. case 1: type = "Other"; break;
  1491. case 2: type = "Unknown"; break;
  1492. case 3: type = "Processor"; break;
  1493. case 4: type = "Network"; break;
  1494. case 5: type = "Printer"; break;
  1495. case 6: type = "DiskStorage"; break;
  1496. case 10: type = "Video"; break;
  1497. case 11: type = "Audio"; break;
  1498. case 12: type = "Coprocessor"; break;
  1499. case 13: type = "Keyboard"; break;
  1500. case 14: type = "Modem"; break;
  1501. case 15: type = "ParallelPort"; break;
  1502. case 16: type = "Pointing"; break;
  1503. case 17: type = "SerialPort"; break;
  1504. case 18: type = "Tape"; break;
  1505. case 19: type = "Clock"; break;
  1506. case 20: type = "VolatileMemory"; break;
  1507. case 21: type = "NonVolatileMemory"; break;
  1508. default: type = "<Unknown!>"; break;
  1509. }
  1510. fprintf(OFILE, "hrDeviceType . . . . . . . %d (%s)\n",
  1511. row->attrib_list[HRDV_TYPE].u.unumber_value, type);
  1512. fprintf(OFILE, "hrDeviceDescr. . . . . . . %s\n",
  1513. row->attrib_list[HRDV_DESCR].u.string_value);
  1514. fprintf(OFILE, "hrDeviceStatus . . . . . . ");
  1515. switch (row->attrib_list[HRDV_STATUS].attrib_type) {
  1516. case CA_STRING:
  1517. fprintf(OFILE, "CA_STRING: \"%s\"\n",
  1518. row->attrib_list[HRDV_STATUS].u.string_value);
  1519. break;
  1520. case CA_NUMBER:
  1521. fprintf(OFILE, "CA_NUMBER: %d\n",
  1522. row->attrib_list[HRDV_STATUS].u.unumber_value);
  1523. break;
  1524. case CA_UNKNOWN:
  1525. fprintf(OFILE, "CA_UNKNOWN\n");
  1526. break;
  1527. case CA_COMPUTED:
  1528. fprintf(OFILE, "CA_COMPUTED\n");
  1529. break;
  1530. default:
  1531. fprintf(OFILE, "(INCORRECT)\n");
  1532. break;
  1533. }
  1534. fprintf(OFILE, "hrDeviceErrors . . . . . . ");
  1535. switch (row->attrib_list[HRDV_ERRORS].attrib_type) {
  1536. case CA_STRING:
  1537. fprintf(OFILE, "CA_STRING: \"%s\"\n",
  1538. row->attrib_list[HRDV_ERRORS].u.string_value);
  1539. break;
  1540. case CA_NUMBER:
  1541. fprintf(OFILE, "CA_NUMBER: %d\n",
  1542. row->attrib_list[HRDV_ERRORS].u.unumber_value);
  1543. break;
  1544. case CA_UNKNOWN:
  1545. fprintf(OFILE, "CA_UNKNOWN\n");
  1546. break;
  1547. case CA_COMPUTED:
  1548. fprintf(OFILE, "CA_COMPUTED\n");
  1549. break;
  1550. default:
  1551. fprintf(OFILE, "(INCORRECT)\n");
  1552. break;
  1553. }
  1554. /* Hidden Context */
  1555. fprintf(OFILE, "(HIDDEN CONTEXT) . . . . . ");
  1556. switch (row->attrib_list[HRDV_TYPE].u.unumber_value) {
  1557. /*
  1558. | What is stored in HIDDEN_CTX is hardwired for these types
  1559. | of cache entries:
  1560. */
  1561. case 3: // "Processor"
  1562. fprintf(OFILE, "CA_NUMBER: %d (Processor Number)\n",
  1563. row->attrib_list[HIDDEN_CTX].u.unumber_value);
  1564. break;
  1565. case 4: // "Network"
  1566. fprintf(OFILE, "CA_NUMBER: %d ( \"hrNetworkIfIndex\" value)\n",
  1567. row->attrib_list[HIDDEN_CTX].u.unumber_value);
  1568. break;
  1569. case 5: // "Printer"
  1570. fprintf(OFILE, "CA_STRING: \"%s\" ( \"OpenPrinter\" string)\n",
  1571. row->attrib_list[HIDDEN_CTX].u.string_value);
  1572. break;
  1573. /* For this type, it varies */
  1574. case 6: // "DiskStorage"
  1575. switch (row->attrib_list[HIDDEN_CTX].attrib_type) {
  1576. case CA_STRING:
  1577. fprintf(OFILE, "CA_STRING: \"%s\"\n",
  1578. row->attrib_list[HIDDEN_CTX].u.string_value);
  1579. break;
  1580. case CA_NUMBER:
  1581. fprintf(OFILE, "CA_NUMBER: %d\n",
  1582. row->attrib_list[HIDDEN_CTX].u.unumber_value);
  1583. break;
  1584. case CA_UNKNOWN:
  1585. fprintf(OFILE, "CA_UNKNOWN\n");
  1586. break;
  1587. case CA_COMPUTED:
  1588. fprintf(OFILE, "CA_COMPUTED\n");
  1589. break;
  1590. case CA_CACHE:
  1591. fprintf(OFILE, "CA_CACHE @ 0x%x\n",
  1592. row->attrib_list[HIDDEN_CTX].u.cache);
  1593. if (row->attrib_list[HIDDEN_CTX].u.cache != NULL) {
  1594. PrintCache(row->attrib_list[HIDDEN_CTX].u.cache);
  1595. }
  1596. break;
  1597. }
  1598. break;
  1599. case 10: // "Video"
  1600. case 11: // "Audio"
  1601. case 12: // "Coprocessor"
  1602. case 13: // "Keyboard"
  1603. case 14: // "Modem"
  1604. case 15: // "ParallelPort"
  1605. case 16: // "Pointing"
  1606. case 17: // "SerialPort"
  1607. case 18: // "Tape"
  1608. case 19: // "Clock"
  1609. case 20: // "VolatileMemory"
  1610. case 21: // "NonVolatileMemory"
  1611. case 2: // "Unknown"
  1612. case 1: // "Other"
  1613. default:
  1614. fprintf(OFILE, "<None>\n");
  1615. break;
  1616. }
  1617. }
  1618. #endif