windows-nt/Source/XPSP1/NT/net/snmp/subagent/hostmib/hrdevent.c
2020-09-26 16:20:57 +08:00

1854 lines
58 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* HrDeviceEntry.c v0.10
* Generated in conjunction with Management Factory scripts:
* script version: SNMPv1, 0.16, Apr 25, 1996
* project: D:\TEMP\EXAMPLE\HOSTMIB
****************************************************************************
* *
* (C) Copyright 1995 DIGITAL EQUIPMENT CORPORATION *
* *
* This software is an unpublished work protected under the *
* the copyright laws of the United States of America, all *
* rights reserved. *
* *
* In the event this software is licensed for use by the United *
* States Government, all use, duplication or disclosure by the *
* United States Government is subject to restrictions as set *
* forth in either subparagraph (c)(1)(ii) of the Rights in *
* Technical Data And Computer Software Clause at DFARS *
* 252.227-7013, or the Commercial Computer Software Restricted *
* Rights Clause at FAR 52.221-19, whichever is applicable. *
* *
****************************************************************************
*
* Facility:
*
* Windows NT SNMP Extension Agent
*
* Abstract:
*
* This module contains the code for dealing with the get, set, and
* instance name routines for the HrDeviceEntry. Actual instrumentation code is
* supplied by the developer.
*
* Functions:
*
* A get and set routine for each attribute in the class.
*
* The routines for instances within the class.
*
* Author:
*
* D. D. Burns @ Webenable Inc
*
* Revision History:
*
* V1.00 - 04/27/97 D. D. Burns Genned: Thu Nov 07 16:41:55 1996
*
*
*/
#include <windows.h>
#include <malloc.h>
#include <snmp.h>
#include "mib.h"
#include "smint.h"
#include "hostmsmi.h"
#include "user.h" /* Developer supplied include file */
#include "HMCACHE.H" /* Cache-related definitions */
#include "HRDEVENT.H" /* HrDevice Table related definitions */
#include <stdio.h> /* for sprintf */
/*
|==============================================================================
| Function prototypes for this module.
|
*/
/* Gen_SingleDevices - Generate Single Device row entries in HrDevice */
BOOL
Gen_SingleDevices( void );
#if defined(CACHE_DUMP)
/* debug_print_hrdevice - Prints a Row from HrDevice */
static void
debug_print_hrdevice(
CACHEROW *row /* Row in hrDiskStorage table */
);
#endif
/*
|==============================================================================
| Create the list-head for the HrDevice table cache.
|
| This list-head is globally accessible so the logic that loads the "sub"
| tables can scan this cache for matches (among other reasons).
|
| (This macro is defined in "HMCACHE.H").
*/
CACHEHEAD_INSTANCE(hrDevice_cache, debug_print_hrdevice);
/*
|==============================================================================
| Initial Load Device
|
| This number is the index into hrDevice table for the entry that corresponds
| to the disk from which the system was initially loaded.
|
| This static location serves as "cache" for the value of
| "HrSystemInitialLoadDevice" (serviced by code in "HRSYSTEM.C").
|
| It is initialized by function "Gen_Fixed_disks()" in module "HRDISKST.C"
| which is called by way of "Gen_HrDiskStorage_Cache()" invoked from this
| module. It is during the scan of the fixed disks that we discover from which
| one the system booted.
*/
ULONG InitLoadDev_index=0;
/*
* GetHrDeviceIndex
* A unique value for each device contained by the host. The value for
* each device must remain constant at least from one re-initi
*
* Gets the value for HrDeviceIndex.
*
* Arguments:
*
* outvalue address to return variable value
* accesss Reserved for future security use
* instance address of instance name as ordered native
* data type(s)
*
* Return Codes:
*
* Standard PDU error codes.
*
* SNMP_ERRORSTATUS_NOERROR Successful get
* SNMP_ERRORSTATUS_GENERR Catch-all failure code
* mibtget.c v0.10
*
| =============== From WebEnable Design Spec Rev 3 04/11/97==================
| hrDeviceIndex
|
| ACCESS SYNTAX
| read-only INTEGER (1..2147483647)
|
| "A unique value for each device contained by the host. The value for each
| device must remain constant at least from one re-initialization of the agent
| to the next re-initialization."
|
| DISCUSSION:
|
| As mentioned in the discussion for this table, all entries for this table
| are derived from a local cache built at start-up time. As a consequence the
| maximum value of this attribute is fixed at SNMP service start-time.
|
|============================================================================
| 1.3.6.1.2.1.25.3.2.1.1.<instance>
| | | | |
| | | | *hrDeviceIndex
| | | *hrDeviceEntry
| | *hrDeviceTable
| *-hrDevice
*/
UINT
GetHrDeviceIndex(
OUT Integer *outvalue ,
IN Access_Credential *access ,
IN InstanceName *instance )
{
ULONG index; /* As fetched from instance structure */
CACHEROW *row; /* Row entry fetched from cache */
/*
| Grab the instance information
*/
index = GET_INSTANCE(0);
/*
| Use it to find the right entry in the cache
*/
if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
return SNMP_ERRORSTATUS_GENERR;
}
/*
| Return the "hrDeviceIndex" value from this entry
*/
*outvalue = row->attrib_list[HRDV_INDEX].u.unumber_value;
return SNMP_ERRORSTATUS_NOERROR ;
} /* end of GetHrDeviceIndex() */
/*
* GetHrDeviceType
* An indication of the type of device.
*
* Gets the value for HrDeviceType.
*
* Arguments:
*
* outvalue address to return variable value
* accesss Reserved for future security use
* instance address of instance name as ordered native
* data type(s)
*
* Return Codes:
*
* Standard PDU error codes.
*
* SNMP_ERRORSTATUS_NOERROR Successful get
* SNMP_ERRORSTATUS_GENERR Catch-all failure code
* mibtget.c v0.10
*
| =============== From WebEnable Design Spec Rev 3 04/11/97==================
| hrDeviceType
|
| ACCESS SYNTAX
| read-only OBJECT IDENTIFIER
|
| "An indication of the type of device.
|
| If this value is `hrDeviceProcessor { hrDeviceTypes3 }'
| then an entry exists in the hrProcessorTable
| which corresponds to this device.
|
| If this value is `hrDeviceNetwork { hrDeviceTypes 4}',
| then an entry exists in the hrNetworkTable
| which corresponds to this device.
|
| If this value is `hrDevicePrinter { hrDeviceTypes 5}',
| then an entry exists in the hrPrinterTable
| which corresponds to this device.
|
| If this value is `hrDeviceDiskStorage {hrDeviceTypes 6 }',
| then an entry exists in the
| hrDiskStorageTable which corresponds to this
| device."
|
| DISCUSSION:
|
| The list of registered device types (i.e. values that can be used in the
| hrDeviceType attribute) are:
|
| hrDeviceOther OBJECT IDENTIFIER ::= { hrDeviceTypes 1 }
| hrDeviceUnknown OBJECT IDENTIFIER ::= { hrDeviceTypes 2 }
| hrDeviceProcessor OBJECT IDENTIFIER ::= { hrDeviceTypes 3 }
| hrDeviceNetwork OBJECT IDENTIFIER ::= { hrDeviceTypes 4 }
| hrDevicePrinter OBJECT IDENTIFIER ::= { hrDeviceTypes 5 }
| hrDeviceDiskStorage OBJECT IDENTIFIER ::= { hrDeviceTypes 6 }
| hrDeviceVideo OBJECT IDENTIFIER ::= { hrDeviceTypes 10 }
| hrDeviceAudio OBJECT IDENTIFIER ::= { hrDeviceTypes 11 }
| hrDeviceCoprocessor OBJECT IDENTIFIER ::= { hrDeviceTypes 12 }
| hrDeviceKeyboard OBJECT IDENTIFIER ::= { hrDeviceTypes 13 }
| hrDeviceModem OBJECT IDENTIFIER ::= { hrDeviceTypes 14 }
| hrDeviceParallelPort OBJECT IDENTIFIER ::= { hrDeviceTypes 15 }
| hrDevicePointing OBJECT IDENTIFIER ::= { hrDeviceTypes 16 }
| hrDeviceSerialPort OBJECT IDENTIFIER ::= { hrDeviceTypes 17 }
| hrDeviceTape OBJECT IDENTIFIER ::= { hrDeviceTypes 18 }
| hrDeviceClock OBJECT IDENTIFIER ::= { hrDeviceTypes 19 }
| hrDeviceVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 20 }
| hrDeviceNonVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 21 }
|
| (See discussion above for hrDeviceTable).
|============================================================================
| 1.3.6.1.2.1.25.3.1.n
| | | |
| | | * Identifying arc for type
| | *-hrDeviceTypes (OIDs specifying device types)
| *-hrDevice
|
| 1.3.6.1.2.1.25.3.2.1.2.<instance>
| | | | |
| | | | *-hrDeviceType
| | | *-hrDeviceEntry
| | *-hrDeviceTable
| *-hrDevice
*/
UINT
GetHrDeviceType(
OUT ObjectIdentifier *outvalue ,
IN Access_Credential *access ,
IN InstanceName *instance )
{
ULONG index; /* As fetched from instance structure */
CACHEROW *row; /* Row entry fetched from cache */
/*
| Grab the instance information
*/
index = GET_INSTANCE(0);
/*
| Use it to find the right entry in the cache
*/
if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
return SNMP_ERRORSTATUS_GENERR;
}
/*
| By convention with the cache-building function "Gen_HrDevice_Cache()",
| and it's minions the cached value is the right-most arc we must return
| as the value.
|
| Hence whatever cache entry we retrieve, we tack the number retrieved
| from the cache for this attribute onto { hrDeviceType ... }.
*/
if ( (outvalue->ids = SNMP_malloc(10 * sizeof( UINT ))) == NULL) {
return SNMP_ERRORSTATUS_GENERR;
}
outvalue->idLength = 10;
/*
| Load in the full hrDeviceType OID:
|
| 1.3.6.1.2.1.25.3.1.n
| | | |
| | | * Identifying arc for type
| | *-hrDeviceTypes (OIDs specifying device types)
| *-hrDevice
*/
outvalue->ids[0] = 1;
outvalue->ids[1] = 3;
outvalue->ids[2] = 6;
outvalue->ids[3] = 1;
outvalue->ids[4] = 2;
outvalue->ids[5] = 1;
outvalue->ids[6] = 25;
outvalue->ids[7] = 3;
outvalue->ids[8] = 1;
/* Cached Device Type indicator */
outvalue->ids[9] = row->attrib_list[HRDV_TYPE].u.unumber_value;
return SNMP_ERRORSTATUS_NOERROR ;
} /* end of GetHrDeviceType() */
/*
* GetHrDeviceDesc
* A textual description of this device, including the device's
* manufacturer and revision, and optionally, its serial number.
*
* Gets the value for HrDeviceDesc.
*
* Arguments:
*
* outvalue address to return variable value
* accesss Reserved for future security use
* instance address of instance name as ordered native
* data type(s)
*
* Return Codes:
*
* Standard PDU error codes.
*
* SNMP_ERRORSTATUS_NOERROR Successful get
* SNMP_ERRORSTATUS_GENERR Catch-all failure code
* mibtget.c v0.10
*
| =============== From WebEnable Design Spec Rev 3 04/11/97==================
| hrDeviceDescr
|
| ACCESS SYNTAX
| read-only DisplayString (SIZE (0..64))
|
| "A textual description of this device, including the device's manufacturer and
| revision, and optionally, its serial number."
|
| DISCUSSION:
|
| (See discussion above for hrDeviceTable, the information source for this
| attribute depends on the device type).
|
|============================================================================
| 1.3.6.1.2.1.25.3.2.1.3.<instance>
| | | | |
| | | | *-hrDeviceDescr
| | | *-hrDeviceEntry
| | *-hrDeviceTable
| *-hrDevice
*/
UINT
GetHrDeviceDesc(
OUT Simple_DisplayString *outvalue ,
IN Access_Credential *access ,
IN InstanceName *instance )
{
ULONG index; /* As fetched from instance structure */
CACHEROW *row; /* Row entry fetched from cache */
/*
| Grab the instance information
*/
index = GET_INSTANCE(0);
/*
| Use it to find the right entry in the cache
*/
if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
return SNMP_ERRORSTATUS_GENERR;
}
outvalue->string = row->attrib_list[HRDV_DESCR].u.string_value;
/* "Truncate" here to meet RFC as needed*/
if ((outvalue->length = strlen(outvalue->string)) > 64) {
outvalue->length = 64;
}
return SNMP_ERRORSTATUS_NOERROR ;
} /* end of GetHrDeviceDesc() */
/*
* GetHrDeviceID
* The product ID for this device.
*
* Gets the value for HrDeviceID.
*
* Arguments:
*
* outvalue address to return variable value
* accesss Reserved for future security use
* instance address of instance name as ordered native
* data type(s)
*
* Return Codes:
*
* Standard PDU error codes.
*
* SNMP_ERRORSTATUS_NOERROR Successful get
* SNMP_ERRORSTATUS_GENERR Catch-all failure code
* mibtget.c v0.10
*
| =============== From WebEnable Design Spec Rev 3 04/11/97==================
| hrDeviceID
|
| ACCESS SYNTAX
| read-only ProductID
|
| "The product ID for this device."
|
| ProductID ::= OBJECT IDENTIFIER
|
| "unknownProduct will be used for any unknown ProductID:
| unknownProduct OBJECT IDENTIFIER ::= { 0 0 }
|
| DISCUSSION:
|
| <POA-10> I anticipate always using "unknownProduct" as the value for this
| attribute, as I can envision no systematic means of acquiring a registered
| OID for all devices to be used as the value for this attribute.
|
| RESOLVED >>>>>>>>
| <POA-10> Returning an unknown Product ID is acceptable.
| RESOLVED >>>>>>>>
|============================================================================
| 1.3.6.1.2.1.25.3.2.1.4.<instance>
| | | | |
| | | | *-hrDeviceID
| | | *-hrDeviceEntry
| | *-hrDeviceTable
| *-hrDevice
*/
UINT
GetHrDeviceID(
OUT ProductID *outvalue ,
IN Access_Credential *access ,
IN InstanceName *instance )
{
/*
| The deal on this attribute is that we'll never have a valid OID value
| for this attribute. Consequently, we always return the standard
| "unknown" OID value ("0.0") regardless of the instance value (which
| by now in the calling sequence of things has been validated anyway).
*/
if ( (outvalue->ids = SNMP_malloc(2 * sizeof( UINT ))) == NULL) {
return SNMP_ERRORSTATUS_GENERR;
}
outvalue->idLength = 2;
/*
| Load in the OID value for "unknown" for ProductID: "0.0"
*/
outvalue->ids[0] = 0;
outvalue->ids[1] = 0;
return SNMP_ERRORSTATUS_NOERROR ;
} /* end of GetHrDeviceID() */
/*
* GetHrDeviceStatus
* The current operational state of the device described by this row of the
* table. A value unknown (1) indicates that the current
*
* Gets the value for HrDeviceStatus.
*
* Arguments:
*
* outvalue address to return variable value
* accesss Reserved for future security use
* instance address of instance name as ordered native
* data type(s)
*
* Return Codes:
*
* Standard PDU error codes.
*
* SNMP_ERRORSTATUS_NOERROR Successful get
* SNMP_ERRORSTATUS_GENERR Catch-all failure code
* mibtget.c v0.10
*
| =============== From WebEnable Design Spec Rev 3 04/11/97==================
| hrDeviceStatus
|
| ACCESS SYNTAX
| read-only INTEGER {unknown(1),running(2),warning(3),testing(4),
| down(5)}
|
| "The current operational state of the device described by this row of the
| table. A value unknown(1) indicates that the current state of the device is
| unknown. running(2) indicates that the device is up and running and that no
| unusual error conditions are known. The warning(3) state indicates that agent
| has been informed of an unusual error condition by the operational software
| (e.g., a disk device driver) but that the device is still 'operational'. An
| example would be high number of soft errors on a disk. A value of testing(4),
| indicates that the device is not available for use because it is in the
| testing state. The state of down(5) is used only when the agent has been
| informed that the device is not available for any use."
|
| DISCUSSION:
|
| For those devices for which a driver can be queried for the device status,
| this is done. For all other circumstances, "unknown(1)" is returned.
|
| (See discussion above for hrDeviceTable, the information source for this
| attribute depends on the device type).
|
|============================================================================
| 1.3.6.1.2.1.25.3.2.1.5.<instance>
| | | | |
| | | | *-hrDeviceStatus
| | | *-hrDeviceEntry
| | *-hrDeviceTable
| *-hrDevice
*/
UINT
GetHrDeviceStatus(
OUT INThrDeviceStatus *outvalue ,
IN Access_Credential *access ,
IN InstanceName *instance )
{
ULONG index; /* As fetched from instance structure */
CACHEROW *row; /* Row entry fetched from cache */
/*
| Grab the instance information
*/
index = GET_INSTANCE(0);
/*
| Use it to find the right entry in the cache
*/
if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
return SNMP_ERRORSTATUS_GENERR;
}
/*
| By convention with the cache-building function "Gen_HrDevice_Cache()",
| and its minions the cached value in the row just fetched above for
| the "hrDeviceType" attribute (indexed by our symbol "HRDV_TYPE") is the
| last arc in the OID that specifies the type of device for which we need
| to return status/errors.
|
| The scheme for returning status depends on the value of the type to
| dispatch to the correct code to handle that kind of device.
|
| Also, code that initializes the hrDevice cache for any given device
| has the option of storing in the "hidden context" attribute (accessed via
| our symbol "HIDDEN_CTX") information needed to access that device.
|
| For instance, the code that enters Printer devices into hrDevice (in
| function "Gen_HrPrinter_Cache()" in "HRPRINTE.C") stores a string in
| "HIDDEN_CTX" that is the printer name thereby allowing logic below to
| re-open that printer to obtain status/errors.
|
*/
switch ( row->attrib_list[HRDV_TYPE].u.unumber_value ) {
case HRDV_TYPE_LASTARC_PRINTER:
/* (In "HRPRINTE.C") */
if (!COMPUTE_hrPrinter_status(row, (UINT *) outvalue)) {
return SNMP_ERRORSTATUS_GENERR;
}
break;
case HRDV_TYPE_LASTARC_PROCESSOR:
/* Any processor in the table is running */
*outvalue = 2;
break;
case HRDV_TYPE_LASTARC_DISKSTORAGE:
/* Stored by Gen_hrDiskStorage_cache() */
*outvalue = row->attrib_list[HRDV_STATUS].u.unumber_value;
break;
case HRDV_TYPE_LASTARC_KEYBOARD:
case HRDV_TYPE_LASTARC_POINTING:
/* Any Keyboard or Mouse in the table is reasably presumed "running" */
*outvalue = 2; // "running"
break;
case HRDV_TYPE_LASTARC_PARALLELPORT:
case HRDV_TYPE_LASTARC_SERIALPORT:
*outvalue = 1; // "Unknown"
break;
case HRDV_TYPE_LASTARC_OTHER:
case HRDV_TYPE_LASTARC_UNKNOWN:
case HRDV_TYPE_LASTARC_NETWORK:
case HRDV_TYPE_LASTARC_VIDEO:
case HRDV_TYPE_LASTARC_AUDIO:
case HRDV_TYPE_LASTARC_COPROCESSOR:
case HRDV_TYPE_LASTARC_MODEM:
case HRDV_TYPE_LASTARC_TAPE:
case HRDV_TYPE_LASTARC_CLOCK:
case HRDV_TYPE_LASTARC_VOLMEMORY:
case HRDV_TYPE_LASTARC_NONVOLMEMORY:
*outvalue = 1; // "Unknown"
break;
default:
return SNMP_ERRORSTATUS_GENERR;
}
return SNMP_ERRORSTATUS_NOERROR ;
} /* end of GetHrDeviceStatus() */
/*
* GetHrDeviceErrors
* The number of errors detected on this device. It should be noted that as
* this object has a SYNTAX of Counter, that it does not
*
* Gets the value for HrDeviceErrors.
*
* Arguments:
*
* outvalue address to return variable value
* accesss Reserved for future security use
* instance address of instance name as ordered native
* data type(s)
*
* Return Codes:
*
* Standard PDU error codes.
*
* SNMP_ERRORSTATUS_NOERROR Successful get
* SNMP_ERRORSTATUS_GENERR Catch-all failure code
* mibtget.c v0.10
*
| =============== From WebEnable Design Spec Rev 3 04/11/97==================
| hrDeviceErrors
| ACCESS SYNTAX
| read-only Counter
|
| "The number of errors detected on this device. It should be noted that as
| this object has a SYNTAX of Counter, that it does not have a defined initial
| value. However, it is recommended that this object be initialized to zero."
|
|
| DISCUSSION:
|
| For those devices for which a driver can be queried for the device errors,
| this is done. For all other circumstances, "0" is returned.
|
| (See discussion above for hrDeviceTable, the information source for this
| attribute depends on the device type).
|
|============================================================================
| 1.3.6.1.2.1.25.3.2.1.6.<instance>
| | | | |
| | | | *-hrDeviceErrors
| | | *-hrDeviceEntry
| | *-hrDeviceTable
| *-hrDevice
*/
UINT
GetHrDeviceErrors(
OUT Counter *outvalue ,
IN Access_Credential *access ,
IN InstanceName *instance )
{
ULONG index; /* As fetched from instance structure */
CACHEROW *row; /* Row entry fetched from cache */
/*
| Grab the instance information
*/
index = GET_INSTANCE(0);
/*
| Use it to find the right entry in the cache
*/
if ((row = FindTableRow(index, &hrDevice_cache)) == NULL) {
return SNMP_ERRORSTATUS_GENERR;
}
/*
| By convention with the cache-building function "Gen_HrDevice_Cache()",
| and its minions the cached value in the row just fetched above for
| the "hrDeviceType" attribute (indexed by our symbol "HRDV_TYPE") is the
| last arc in the OID that specifies the type of device for which we need
| to return status/errors.
|
| The scheme for returning status depends on the value of the type to
| dispatch to the correct code to handle that kind of device.
|
| Also, code that initializes the hrDevice cache for any given device
| has the option of storing in the "hidden context" attribute (accessed via
| our symbol "HIDDEN_CTX") information needed to access that device.
|
| For instance, the code that enters Printer devices into hrDevice (in
| function "Gen_HrPrinter_Cache()" in "HRPRINTE.C") stores a string in
| "HIDDEN_CTX" that is the printer name thereby allowing logic below to
| re-open that printer to obtain status/errors.
|
*/
switch ( row->attrib_list[HRDV_TYPE].u.unumber_value ) {
case HRDV_TYPE_LASTARC_PRINTER:
/* (In "HRPRINTE.C") */
if (!COMPUTE_hrPrinter_errors(row, outvalue)) {
return SNMP_ERRORSTATUS_GENERR;
}
break;
case HRDV_TYPE_LASTARC_PROCESSOR:
/* If 'errors' ain't 0, odds are low you're gonna find out via SNMP */
*outvalue = 0;
break;
case HRDV_TYPE_LASTARC_POINTING:
case HRDV_TYPE_LASTARC_KEYBOARD:
case HRDV_TYPE_LASTARC_PARALLELPORT:
case HRDV_TYPE_LASTARC_SERIALPORT:
/* 'errors' presumed 0 */
*outvalue = 0;
break;
case HRDV_TYPE_LASTARC_OTHER:
case HRDV_TYPE_LASTARC_UNKNOWN:
case HRDV_TYPE_LASTARC_NETWORK:
case HRDV_TYPE_LASTARC_DISKSTORAGE:
case HRDV_TYPE_LASTARC_VIDEO:
case HRDV_TYPE_LASTARC_AUDIO:
case HRDV_TYPE_LASTARC_COPROCESSOR:
case HRDV_TYPE_LASTARC_MODEM:
case HRDV_TYPE_LASTARC_TAPE:
case HRDV_TYPE_LASTARC_CLOCK:
case HRDV_TYPE_LASTARC_VOLMEMORY:
case HRDV_TYPE_LASTARC_NONVOLMEMORY:
*outvalue = 0;
break;
default:
return SNMP_ERRORSTATUS_GENERR;
}
return SNMP_ERRORSTATUS_NOERROR ;
} /* end of GetHrDeviceErrors() */
/*
* HrDeviceEntryFindInstance
*
* This routine is used to verify that the specified instance is
* valid.
*
* Arguments:
*
* FullOid Address for the full oid - group, variable,
* and instance information
* instance Address for instance specification as an oid
*
* Return Codes:
*
* SNMP_ERRORSTATUS_NOERROR Instance found and valid
* SNMP_ERRORSTATUS_NOSUCHNAME Invalid instance
*
*/
UINT
HrDeviceEntryFindInstance( IN ObjectIdentifier *FullOid ,
IN OUT ObjectIdentifier *instance )
{
UINT tmp_instance ;
//
// Developer instrumentation code to find appropriate instance goes here.
// For non-tables, it is not necessary to modify this routine. However, if
// there is any context that needs to be set, it can be done here.
//
if ( FullOid->idLength <= HRDEVICEENTRY_VAR_INDEX )
// No instance was specified
return SNMP_ERRORSTATUS_NOSUCHNAME ;
else if ( FullOid->idLength != HRDEVICEENTRY_VAR_INDEX + 1 )
// Instance length is more than 1
return SNMP_ERRORSTATUS_NOSUCHNAME ;
else
// The only valid instance for a non-table are instance 0. If this
// is a non-table, the following code validates the instances. If this
// is a table, developer modification is necessary below.
tmp_instance = FullOid->ids[ HRDEVICEENTRY_VAR_INDEX ] ;
/*
| For hrDeviceTable, the instance arc(s) is a single arc, and it must
| correctly select an entry in the hrDeviceTable cache.
| Check that here.
*/
if ( FindTableRow(tmp_instance, &hrDevice_cache) == NULL ) {
return SNMP_ERRORSTATUS_NOSUCHNAME ;
}
else
{
// the instance is valid. Create the instance portion of the OID
// to be returned from this call.
instance->ids[ 0 ] = tmp_instance ;
instance->idLength = 1 ;
}
return SNMP_ERRORSTATUS_NOERROR ;
} /* end of HrDeviceEntryFindInstance() */
/*
* HrDeviceEntryFindNextInstance
*
* This routine is called to get the next instance. If no instance
* was passed than return the first instance (1).
*
* Arguments:
*
* FullOid Address for the full oid - group, variable,
* and instance information
* instance Address for instance specification as an oid
*
* Return Codes:
*
* SNMP_ERRORSTATUS_NOERROR Instance found and valid
* SNMP_ERRORSTATUS_NOSUCHNAME Invalid instance
*
*/
UINT
HrDeviceEntryFindNextInstance( IN ObjectIdentifier *FullOid ,
IN OUT ObjectIdentifier *instance )
{
//
// Developer supplied code to find the next instance of class goes here.
// If this is a class with cardinality 1, no modification of this routine
// is necessary unless additional context needs to be set.
// If the FullOid does not specify an instance, then the only instance
// of the class is returned. If this is a table, the first row of the
// table is returned.
//
// If an instance is specified and this is a non-table class, then NOSUCHNAME
// is returned so that correct MIB rollover processing occurs. If this is
// a table, then the next instance is the one following the current instance.
// If there are no more instances in the table, return NOSUCHNAME.
//
CACHEROW *row;
ULONG tmp_instance;
if ( FullOid->idLength <= HRDEVICEENTRY_VAR_INDEX )
{
/*
| Too short: must return the instance arc that selects the first
| entry in the table if there is one.
*/
tmp_instance = 0;
}
else {
/*
| There is at least one instance arc. Even if it is the only arc
| we use it as the "index" in a request for the "NEXT" one.
*/
tmp_instance = FullOid->ids[ HRDEVICEENTRY_VAR_INDEX ] ;
}
/* Now go off and try to find the next instance in the table */
if ((row = FindNextTableRow(tmp_instance, &hrDevice_cache)) == NULL) {
return SNMP_ERRORSTATUS_NOSUCHNAME ;
}
instance->ids[ 0 ] = row->index ;
instance->idLength = 1 ;
return SNMP_ERRORSTATUS_NOERROR ;
} /* end of HrDeviceEntryFindNextInstance() */
/*
* HrDeviceEntryConvertInstance
*
* This routine is used to convert the object id specification of an
* instance into an ordered native representation. The object id format
* is that object identifier that is returned from the Find Instance
* or Find Next Instance routines. It is NOT the full object identifier
* that contains the group and variable object ids as well. The native
* representation is an argc/argv-like structure that contains the
* ordered variables that define the instance. This is specified by
* the MIB's INDEX clause. See RFC 1212 for information about the INDEX
* clause.
*
*
* Arguments:
*
* oid_spec Address of the object id instance specification
* native_spec Address to return the ordered native instance
* specification
*
* Return Codes:
*
* SUCCESS Conversion complete successfully
* FAILURE Unable to convert object id into native format
*
*/
UINT
HrDeviceEntryConvertInstance( IN ObjectIdentifier *oid_spec ,
IN OUT InstanceName *native_spec )
{
static char *array; /* The address of this (char *) is passed back */
/* as though it were an array of length 1 of these */
/* types. */
static ULONG inst; /* The address of this ULONG is passed back */
/* (Obviously, no "free()" action is needed) */
/* We only expect the one arc in "oid_spec" */
inst = oid_spec->ids[0];
array = (char *) &inst;
native_spec->count = 1;
native_spec->array = &array;
return SUCCESS ;
} /* end of HrDeviceEntryConvertInstance() */
/*
* HrDeviceEntryFreeInstance
*
* This routine is used to free an ordered native representation of an
* instance name.
*
* Arguments:
*
* instance Address to return the ordered native instance
* specification
*
* Return Codes:
*
*
*/
void
HrDeviceEntryFreeInstance( IN OUT InstanceName *instance )
{
/* No action needed for hrDevice Table */
} /* end of HrDeviceEntryFreeInstance() */
/*
| End of Generated Code
*/
/* Gen_HrDevice_Cache - Generate a initial cache for HrDevice Table */
/* Gen_HrDevice_Cache - Generate a initial cache for HrDevice Table */
/* Gen_HrDevice_Cache - Generate a initial cache for HrDevice Table */
BOOL
Gen_HrDevice_Cache(
void
)
/*
| EXPLICIT INPUTS:
|
| None.
|
| IMPLICIT INPUTS:
|
| The module-local head of the cache for the HrDevice table,
| "HrDevice_cache".
|
| OUTPUTS:
|
| On Success:
| Function returns TRUE indicating that the cache has been fully
| populated with all "static" cache-able values.
|
| On any Failure:
| Function returns FALSE (indicating "not enough storage" or other
| internal logic error).
|
| THE BIG PICTURE:
|
| At subagent startup time, the cache for each table in the MIB is
| populated with rows for each row in the table. This function is
| invoked by the start-up code in "UserMibInit()" ("MIB.C") to
| populate the cache for the HrDevice table.
|
| OTHER THINGS TO KNOW:
|
| There is one of these function for every table that has a cache.
| Each is found in the respective source file.
|
|=============== From WebEnable Design Spec Rev 3 04/11/97==================
| A Row in the hrDeviceTable
|
| "A (conceptual) entry for one device contained by the host. As an example, an
| instance of the hrDeviceType object might be named hrDeviceType.3"
|
| HrDeviceEntry ::= SEQUENCE {
| hrDeviceIndex INTEGER,
| hrDeviceType OBJECT IDENTIFIER,
| hrDeviceDescr DisplayString,
| hrDeviceID ProductID,
| hrDeviceStatus INTEGER,
| hrDeviceErrors Counter
| }
|
| DISCUSSION:
|
| This is the largest and most complicated table to populate. The strategy for
| populating entries in this table is to execute a slug of code for each device
| type (in the list below) in an attempt to find all instances of that device
| type. For some devices, the code uses standard Win32 API functions, for
| others it is clear that special-purpose code is needed to extract the relevant
| information from the "behind the scenes" (direct NT kernel inquiries).
|
| This table is fully populated with respect to the other tables in the hrDevice
| group. The other tables are sparse tables augmenting only selected entries in
| hrDeviceTable.
|
| The list of registered device types (i.e. values that can be used in the
| hrDeviceType attribute) are:
|
| hrDeviceOther OBJECT IDENTIFIER ::= { hrDeviceTypes 1 }
| hrDeviceUnknown OBJECT IDENTIFIER ::= { hrDeviceTypes 2 }
| hrDeviceProcessor OBJECT IDENTIFIER ::= { hrDeviceTypes 3 }
| hrDeviceNetwork OBJECT IDENTIFIER ::= { hrDeviceTypes 4 }
| hrDevicePrinter OBJECT IDENTIFIER ::= { hrDeviceTypes 5 }
| hrDeviceDiskStorage OBJECT IDENTIFIER ::= { hrDeviceTypes 6 }
| hrDeviceVideo OBJECT IDENTIFIER ::= { hrDeviceTypes 10 }
| hrDeviceAudio OBJECT IDENTIFIER ::= { hrDeviceTypes 11 }
| hrDeviceCoprocessor OBJECT IDENTIFIER ::= { hrDeviceTypes 12 }
| hrDeviceKeyboard OBJECT IDENTIFIER ::= { hrDeviceTypes 13 }
| hrDeviceModem OBJECT IDENTIFIER ::= { hrDeviceTypes 14 }
| hrDeviceParallelPort OBJECT IDENTIFIER ::= { hrDeviceTypes 15 }
| hrDevicePointing OBJECT IDENTIFIER ::= { hrDeviceTypes 16 }
| hrDeviceSerialPort OBJECT IDENTIFIER ::= { hrDeviceTypes 17 }
| hrDeviceTape OBJECT IDENTIFIER ::= { hrDeviceTypes 18 }
| hrDeviceClock OBJECT IDENTIFIER ::= { hrDeviceTypes 19 }
| hrDeviceVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 20 }
| hrDeviceNonVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 21 }
|
| All of the foregoing types can be divided into two groups based on the
| approach needed to acquire information about them. Information for the first
| group can be queried using Win32 API functions while the second group
| requires special inquiry-code.
|
| (1) Win32 Device-Types Win32 Function Used
| ---------------------- -------------------
| hrDeviceOther
| Partitions DeviceIoControl (IOCTL_GET_PARTITION_INFO)
|
| hrDeviceProcessor GetSystemInfo
| hrDevicePrinter EnumPrinterDrivers
| hrDeviceDiskStorage QueryDosDevice/CreateFile (using physical drive access)
| hrDeviceKeyboard GetKeyboardType
| hrDevicePointing (Win32 function provides pointer-device button-count)
|
|
| (2) Special-Inquiry Device-Types
| ---------------------------------
| hrDeviceNetwork Access is provided via special "mib2util" DLL
|
| hrDeviceParallelPort NtQuerySystemInformation(SYSTEM_DEVICE_INFORMATION)
| hrDeviceSerialPort
|
| hrDeviceVideo ??? NtQuerySystemInformation(SYSTEM_GDI_DRIVER_INFORMATION)
| hrDeviceAudio ???
| hrDeviceTape ???
|
|
| The following "devices" do not readily fall into either of the above groups
| and no attempt is made to recognize them:
|
| hrDeviceModem OBJECT IDENTIFIER ::= { hrDeviceTypes 14 }
| hrDeviceVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 20 }
| hrDeviceNonVolatileMemory OBJECT IDENTIFIER ::= { hrDeviceTypes 21 }
| hrDeviceCoprocessor OBJECT IDENTIFIER ::= { hrDeviceTypes 12 }
| hrDeviceClock OBJECT IDENTIFIER ::= { hrDeviceTypes 19 }
|
|
| Other Implementation Details
| ----------------------------
| The bulk of the information for this table (and the associated sparse tables
| hrProcessorTable, hrNetworkTable, hrPrinterTable, hrDiskStorageTable,
| hrPartitionTable and hrFSTable) is acquired and stored in a local cache at the
| time the SNMP agent enrolls the DLL for the Host Resources MIB. This strategy
| is designed to reduce the hit on system resources when requests are processed.
| The only information that is acquired dynamically (on a per SNMP request) is
| information for variables likely to be dynamic: Status and Error status.
|
| One consequence of this strategy is that user-implemented changes to the
| system configuration (including changing printer drivers, or disk partition
| layout) will not be reported until the SNMP service is restarted.
|
|
|============================================================================
| 1.3.6.1.2.1.25.3.1.n
| | | |
| | | * Identifying arc for type
| | *-hrDeviceTypes (OIDs specifying device types)
| *-hrDevice
|
| 1.3.6.1.2.1.25.3.2.1....
| | | |
| | | *hrDeviceEntry
| | *hrDeviceTable
| *-hrDevice
|
*/
{
/*
|============================================================================
|
| Call the "Gen_*_cache()" functions for each of the "sub-tables" within
| the hrDevice table.
|
| Each of these functions is responsible for:
|
| + populating the hrDevice cache with however many rows are called for
| given the device(s) available
|
| + creating and populating their own cache for the sub-table if
| the sub-table needs a cache. (If all the sub-table attributes
| are "computed" on request, then there is no need for a separate
| sub-table cache).
*/
if (Gen_HrPrinter_Cache(HRDV_TYPE_LASTARC_PRINTER) == FALSE) {
return ( FALSE );
}
if (Gen_HrProcessor_Cache(HRDV_TYPE_LASTARC_PROCESSOR) == FALSE) {
return ( FALSE );
}
if (Gen_HrNetwork_Cache(HRDV_TYPE_LASTARC_NETWORK) == FALSE) {
return ( FALSE );
}
if (Gen_HrDiskStorage_Cache(HRDV_TYPE_LASTARC_DISKSTORAGE) == FALSE) {
return ( FALSE );
}
/*
|============================================================================
|
| Now handle the odd "one-off" devices for which potentially just a single
| entry is made into the existing hrDevice table cache.
*/
if (Gen_SingleDevices() == FALSE) {
return ( FALSE );
}
#if defined(CACHE_DUMP)
PrintCache(&hrDevice_cache);
PrintCache(&hrDiskStorage_cache);
#endif
/*
| HrDevice cache generation complete.
*/
return ( TRUE );
}
/* Gen_SingleDevices - Generate Single Device row entries in HrDevice */
/* Gen_SingleDevices - Generate Single Device row entries in HrDevice */
/* Gen_SingleDevices - Generate Single Device row entries in HrDevice */
BOOL
Gen_SingleDevices( void )
/*
| EXPLICIT INPUTS:
|
| None.
|
| IMPLICIT INPUTS:
|
| None.
|
| OUTPUTS:
|
| On Success:
| Function creates a new row entry populated with all "static" cache-able
| values for HrDevice table for each "one-off" device and returns TRUE.
|
| On any Failure:
| Function returns FALSE (indicating "not enough storage" or other
| internal logic error).
|
|
| THE BIG PICTURE:
|
| At subagent startup time, the cache for each table in the MIB is
| being populated. This function handles populating hrDevice with
| a row for each "single-type" device (such as keyboard).
|
| OTHER THINGS TO KNOW:
|
| Devices being added by this function are not associated with
| sub-tables.
|
| We handle:
| + Keyboard "device"
| + Pointing "device"
| + Parallel and Serial Port "devices"
|
*/
{
UINT key_status; /* Value returned from GetKeyboardType() */
UINT button_count; /* Mouse button count from GetSystemMetrics */
CHAR msg[256]; /* (Big enough for constant strings below) */
UINT dev_number;
#define PHYS_SIZE 64
CHAR phys_name[PHYS_SIZE]; /* Buffer where a string like "\\.C:" (for */
/* example) is built for drive access. */
HANDLE hdrv; /* Handle to device */
/*
|==============================================================================
| Keyboard Device
|
| If we can get keyboard type... */
if ((key_status = GetKeyboardType(0)) != 0 ) {
PCHAR key_type; /* Description string */
/* Select initial part of description string */
switch (key_status) {
case 1: key_type = "IBM PC/XT or compatible (83-key) keyboard"; break;
case 2: key_type = "Olivetti \"ICO\" (102-key) keyboard"; break;
case 3: key_type = "IBM PC/AT (84-key) or similar keyboard"; break;
case 4: key_type = "IBM enhanced (101- or 102-key) keyboard"; break;
case 5: key_type = "Nokia 1050 and similar keyboards"; break;
case 6: key_type = "Nokia 9140 and similar keyboards"; break;
case 7: key_type = "Japanese keyboard"; break;
default: key_type = "Unknown keyboard"; break;
}
/* Build the full description string */
sprintf(msg, "%s, Subtype=(%d)", key_type, GetKeyboardType(1));
if (AddHrDeviceRow(HRDV_TYPE_LASTARC_KEYBOARD, // Last Type OID arc
msg, // Description string
NULL, // No hidden context
CA_UNKNOWN) == NULL) {
return ( FALSE ); /* Something blew */
}
}
/*
|==============================================================================
| Pointing Device
|
| If we can get Mouse Button count... */
if ((button_count = GetSystemMetrics(SM_CMOUSEBUTTONS)) != 0 ) {
sprintf(msg, "%d-Buttons %s",
button_count,
(GetSystemMetrics(SM_MOUSEWHEELPRESENT)) ? " (with wheel)" : "");
if (AddHrDeviceRow(HRDV_TYPE_LASTARC_POINTING, // Last Type OID arc
msg, // Description string
NULL, // No hidden context
CA_UNKNOWN) == NULL) {
return ( FALSE ); /* Something blew */
}
}
/*
|==============================================================================
| LPT Devices
|
| For every LPTx device we can open successfully. . .
*/
for (dev_number = 1; dev_number < 4; dev_number += 1) {
/* Build it for device n: */
sprintf(phys_name, "LPT%d:", dev_number);
/*
| Suppress any attempt by the system to talk to the user
*/
SetErrorMode(SEM_FAILCRITICALERRORS);
/* Attempt to get a handle using this physical name string */
if ((hdrv = CreateFile(phys_name, // Device
GENERIC_READ, // Access mode
FILE_SHARE_READ, // Share Mode
NULL, // Security
OPEN_EXISTING, // CreationDistribution
FILE_ATTRIBUTE_NORMAL, // FlagsandAttributes
NULL // Template file
)) != INVALID_HANDLE_VALUE) {
/*
| Ok, we managed to get ahold of it, we'll put it in the table.
*/
if (AddHrDeviceRow(HRDV_TYPE_LASTARC_PARALLELPORT, // Last Type OID arc
phys_name, // Descr string
NULL, // No hidden context
CA_UNKNOWN) == NULL) {
CloseHandle(hdrv); // Prefix bug 445177
return ( FALSE ); /* Something blew */
}
CloseHandle(hdrv);
} /* if (we managed to "CreateFile" the device) */
else {
/*
| Keep trucking if we couldn't open the device, but quit when we
| hit this error.
*/
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
break;
}
}
SetErrorMode(0); /* Turn error suppression mode off */
} /* For each device */
/*
|==============================================================================
| COM Devices
|
| For every COMx device we can open successfully. . .
*/
for (dev_number = 1; dev_number <= 4; dev_number += 1) {
/* Build it for device n: */
sprintf(phys_name, "COM%d:", dev_number);
/*
| Suppress any attempt by the system to talk to the user
*/
SetErrorMode(SEM_FAILCRITICALERRORS);
/* Attempt to get a handle using this physical name string */
if ((hdrv = CreateFile(phys_name, // Device
GENERIC_READ, // Access mode
FILE_SHARE_READ, // Share Mode
NULL, // Security
OPEN_EXISTING, // CreationDistribution
FILE_ATTRIBUTE_NORMAL, // FlagsandAttributes
NULL // Template file
)) != INVALID_HANDLE_VALUE) {
/*
| Ok, we managed to get ahold of it, we'll put it in the table.
*/
if (AddHrDeviceRow(HRDV_TYPE_LASTARC_SERIALPORT, // Last Type OID arc
phys_name, // Descr string
NULL, // No hidden context
CA_UNKNOWN) == NULL) {
return ( FALSE ); /* Something blew */
}
CloseHandle(hdrv);
} /* if (we managed to "CreateFile" the device) */
else {
/*
| Keep trucking if we couldn't open the device, but quit when we
| hit this error (skip share failures).
*/
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
break;
}
}
SetErrorMode(0); /* Turn error suppression mode off */
} /* For each device */
return ( TRUE ); //--ft:09/28-- sundown cleanup
}
/* AddHrDeviceRow - Generate another Row Entry in HrDevice Table */
/* AddHrDeviceRow - Generate another Row Entry in HrDevice Table */
/* AddHrDeviceRow - Generate another Row Entry in HrDevice Table */
CACHEROW *
AddHrDeviceRow(
ULONG type_arc, /* Last Arc value for OID for Type */
LPSTR descr, /* Description string */
void *hidden_ctx, /* If non-NULL: Hidden-context value */
ATTRIB_TYPE hc_type /* Type of "hidden_ctx" */
)
/*
| EXPLICIT INPUTS:
|
| "type_arc" is the number that is inserted as the right-most arc in
| Object Identifier that is the cache entry for the hrDevicetype of the
| device.
|
| "descr" is a string pointer that is to be the cached value of
| the hrDeviceDesc attribute.
|
| "hidden_ctx" - If non-null, this is a pointer to the value to be
| stored as the "Hidden Context" attribute in the new row.
|
| "hc_type" is the type of "hidden_ctx" if hidden_ctx is non-null.
|
|
| IMPLICIT INPUTS:
|
| The module-local head of the cache for the HrDevice table,
| "HrDevice_cache".
|
| OUTPUTS:
|
| On Success:
| Function creates a new row entry populated with all "static" cache-able
| values for HrDevice table and returns a pointer to the new row entry.
|
| On any Failure:
| Function returns NULL (indicating "not enough storage" or other
| internal logic error).
|
|
| THE BIG PICTURE:
|
| At subagent startup time, the cache for each table in the MIB is
| populated with rows for each row in the table. This function is
| invoked by the start-up code in each of the "sub-hrDevicetable"
| files to populate the cache for the HrDevice table for the rows
| pertaining to a particular sub-table (hrProcessorTable, hrPrinterTable
| etc).
|
| OTHER THINGS TO KNOW:
|
| The "hidden_ctx" argument provides an easy way for the caller to stash
| a value useful for later run-time reference. For instance, "GET" functions
| for Printer devices may need a string that identifies the printer (for
| a given row-entry) in order to lookup the current value of an SNMP
| attribute (like the current status). So the "Hidden Context" attribute
| may be set to a string that can be submitted to a Win32 function to obtain
| the current status for the printer.
*/
{
static /* NOTE: "static" is a 'must' */
ULONG table_index=0; /* HrDeviceTable index counter */
CACHEROW *row; /* --> Cache structure for row-being built */
/*
| OK, the caller wants another row in the table, get a row-entry created.
*/
if ((row = CreateTableRow( HRDV_ATTRIB_COUNT ) ) == NULL) {
return ( NULL ); // Out of memory
}
/*
| Set up the standard-hrDevice attributes in the new row
*/
/* =========== hrDeviceIndex ==========*/
row->attrib_list[HRDV_INDEX].attrib_type = CA_NUMBER;
row->attrib_list[HRDV_INDEX].u.unumber_value = (table_index += 1) ;
/* =========== hrDeviceType ==========
|
| Some GET functions for "computed" attributes expect to be able to use
| the value of the "hrDeviceType" cache value stored below to dispatch
| to appropriate code based on the device type (using the last type-OID arc
| as the "switch" value).
*/
row->attrib_list[HRDV_TYPE].attrib_type = CA_NUMBER;
row->attrib_list[HRDV_TYPE].u.unumber_value = type_arc ;
/* =========== hrDeviceDescr ==========*/
row->attrib_list[HRDV_DESCR].attrib_type = CA_STRING;
if ( (row->attrib_list[HRDV_DESCR].u.string_value
= ( LPSTR ) malloc(strlen(descr) + 1)) == NULL) {
return ( NULL ); /* out of memory */
}
strcpy(row->attrib_list[HRDV_DESCR].u.string_value, descr);
/*
| The rest of the standard hrDevice attributes are "computed" at run time
*/
/* =========== hrDeviceStatus ==========*/
row->attrib_list[HRDV_STATUS].attrib_type = CA_COMPUTED;
/* =========== hrDeviceErrors ==========*/
row->attrib_list[HRDV_ERRORS].attrib_type = CA_COMPUTED;
/*
|================================================================
| If they gave us a hidden-context attribute string, store it now.
*/
if (hidden_ctx != NULL) {
switch (hc_type) {
case CA_STRING:
row->attrib_list[HIDDEN_CTX].attrib_type = CA_STRING;
if ( (row->attrib_list[HIDDEN_CTX].u.string_value
= ( LPSTR ) malloc(strlen((LPSTR)hidden_ctx) + 1)) == NULL) {
return ( NULL ); /* out of memory */
}
strcpy(row->attrib_list[HIDDEN_CTX].u.string_value, hidden_ctx);
break;
case CA_NUMBER:
row->attrib_list[HIDDEN_CTX].attrib_type = CA_NUMBER;
row->attrib_list[HIDDEN_CTX].u.unumber_value =
*((ULONG *) hidden_ctx);
break;
case CA_CACHE:
row->attrib_list[HIDDEN_CTX].attrib_type = CA_CACHE;
row->attrib_list[HIDDEN_CTX].u.cache = (CACHEHEAD *) hidden_ctx;
break;
case CA_UNKNOWN:
row->attrib_list[HIDDEN_CTX].attrib_type = CA_UNKNOWN;
break;
default:
return ( NULL ); /* Something wrong */
}
}
else {
/* Show no "Hidden-Context" attribute for this row */
row->attrib_list[HIDDEN_CTX].attrib_type = CA_UNKNOWN;
row->attrib_list[HIDDEN_CTX].u.string_value = NULL;
}
/*
| Now insert the filled-in CACHEROW structure into the
| cache-list for the hrDeviceTable.
*/
if (AddTableRow(row->attrib_list[HRDV_INDEX].u.unumber_value, /* Index */
row, /* Row */
&hrDevice_cache /* Cache */
) == FALSE) {
return ( NULL ); /* Internal Logic Error! */
}
/*
| Meet caller's expectation of receiving a pointer to the new row.
*/
return ( row );
}
#if defined(CACHE_DUMP)
/* debug_print_hrdevice - Prints a Row from HrDevice */
/* debug_print_hrdevice - Prints a Row from HrDevice */
/* debug_print_hrdevice - Prints a Row from HrDevice */
static void
debug_print_hrdevice(
CACHEROW *row /* Row in hrDiskStorage table */
)
/*
| EXPLICIT INPUTS:
|
| "row" - points to the row to be dumped, if NULL, the function
| merely prints a suitable title.
|
| IMPLICIT INPUTS:
|
| - Symbols used to reference the attributes in the row entry.
| - File handle defined by OFILE, presumed to be open.
|
| OUTPUTS:
|
| On Success:
| Function prints a dump of the row in ASCII for debugging purposes
| on file handle OFILE.
|
| THE BIG PICTURE:
|
| Debugging only.
|
| OTHER THINGS TO KNOW:
*/
{
char *type; /* String representation of device type */
if (row == NULL) {
fprintf(OFILE, "====================\n");
fprintf(OFILE, "hrDevice Table Cache\n");
fprintf(OFILE, "====================\n");
return;
}
fprintf(OFILE, "hrDeviceIndex. . . . . . . %d\n",
row->attrib_list[HRDV_INDEX].u.unumber_value);
switch (row->attrib_list[HRDV_TYPE].u.unumber_value) {
case 1: type = "Other"; break;
case 2: type = "Unknown"; break;
case 3: type = "Processor"; break;
case 4: type = "Network"; break;
case 5: type = "Printer"; break;
case 6: type = "DiskStorage"; break;
case 10: type = "Video"; break;
case 11: type = "Audio"; break;
case 12: type = "Coprocessor"; break;
case 13: type = "Keyboard"; break;
case 14: type = "Modem"; break;
case 15: type = "ParallelPort"; break;
case 16: type = "Pointing"; break;
case 17: type = "SerialPort"; break;
case 18: type = "Tape"; break;
case 19: type = "Clock"; break;
case 20: type = "VolatileMemory"; break;
case 21: type = "NonVolatileMemory"; break;
default: type = "<Unknown!>"; break;
}
fprintf(OFILE, "hrDeviceType . . . . . . . %d (%s)\n",
row->attrib_list[HRDV_TYPE].u.unumber_value, type);
fprintf(OFILE, "hrDeviceDescr. . . . . . . %s\n",
row->attrib_list[HRDV_DESCR].u.string_value);
fprintf(OFILE, "hrDeviceStatus . . . . . . ");
switch (row->attrib_list[HRDV_STATUS].attrib_type) {
case CA_STRING:
fprintf(OFILE, "CA_STRING: \"%s\"\n",
row->attrib_list[HRDV_STATUS].u.string_value);
break;
case CA_NUMBER:
fprintf(OFILE, "CA_NUMBER: %d\n",
row->attrib_list[HRDV_STATUS].u.unumber_value);
break;
case CA_UNKNOWN:
fprintf(OFILE, "CA_UNKNOWN\n");
break;
case CA_COMPUTED:
fprintf(OFILE, "CA_COMPUTED\n");
break;
default:
fprintf(OFILE, "(INCORRECT)\n");
break;
}
fprintf(OFILE, "hrDeviceErrors . . . . . . ");
switch (row->attrib_list[HRDV_ERRORS].attrib_type) {
case CA_STRING:
fprintf(OFILE, "CA_STRING: \"%s\"\n",
row->attrib_list[HRDV_ERRORS].u.string_value);
break;
case CA_NUMBER:
fprintf(OFILE, "CA_NUMBER: %d\n",
row->attrib_list[HRDV_ERRORS].u.unumber_value);
break;
case CA_UNKNOWN:
fprintf(OFILE, "CA_UNKNOWN\n");
break;
case CA_COMPUTED:
fprintf(OFILE, "CA_COMPUTED\n");
break;
default:
fprintf(OFILE, "(INCORRECT)\n");
break;
}
/* Hidden Context */
fprintf(OFILE, "(HIDDEN CONTEXT) . . . . . ");
switch (row->attrib_list[HRDV_TYPE].u.unumber_value) {
/*
| What is stored in HIDDEN_CTX is hardwired for these types
| of cache entries:
*/
case 3: // "Processor"
fprintf(OFILE, "CA_NUMBER: %d (Processor Number)\n",
row->attrib_list[HIDDEN_CTX].u.unumber_value);
break;
case 4: // "Network"
fprintf(OFILE, "CA_NUMBER: %d ( \"hrNetworkIfIndex\" value)\n",
row->attrib_list[HIDDEN_CTX].u.unumber_value);
break;
case 5: // "Printer"
fprintf(OFILE, "CA_STRING: \"%s\" ( \"OpenPrinter\" string)\n",
row->attrib_list[HIDDEN_CTX].u.string_value);
break;
/* For this type, it varies */
case 6: // "DiskStorage"
switch (row->attrib_list[HIDDEN_CTX].attrib_type) {
case CA_STRING:
fprintf(OFILE, "CA_STRING: \"%s\"\n",
row->attrib_list[HIDDEN_CTX].u.string_value);
break;
case CA_NUMBER:
fprintf(OFILE, "CA_NUMBER: %d\n",
row->attrib_list[HIDDEN_CTX].u.unumber_value);
break;
case CA_UNKNOWN:
fprintf(OFILE, "CA_UNKNOWN\n");
break;
case CA_COMPUTED:
fprintf(OFILE, "CA_COMPUTED\n");
break;
case CA_CACHE:
fprintf(OFILE, "CA_CACHE @ 0x%x\n",
row->attrib_list[HIDDEN_CTX].u.cache);
if (row->attrib_list[HIDDEN_CTX].u.cache != NULL) {
PrintCache(row->attrib_list[HIDDEN_CTX].u.cache);
}
break;
}
break;
case 10: // "Video"
case 11: // "Audio"
case 12: // "Coprocessor"
case 13: // "Keyboard"
case 14: // "Modem"
case 15: // "ParallelPort"
case 16: // "Pointing"
case 17: // "SerialPort"
case 18: // "Tape"
case 19: // "Clock"
case 20: // "VolatileMemory"
case 21: // "NonVolatileMemory"
case 2: // "Unknown"
case 1: // "Other"
default:
fprintf(OFILE, "<None>\n");
break;
}
}
#endif