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.

2065 lines
73 KiB

  1. /*
  2. * HrDiskStorageEntry.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 HrDiskStorageEntry. Actual
  32. * instrumentation code is 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/28/97 D. D. Burns Genned: Thu Nov 07 16:43:17 1996
  47. *
  48. */
  49. #include <windows.h>
  50. #include <malloc.h>
  51. #include <stdio.h> /* For sprintf */
  52. #include <string.h>
  53. #include <snmp.h>
  54. #include "mib.h"
  55. #include "smint.h"
  56. #include "hostmsmi.h"
  57. #include "user.h" /* Developer supplied include file */
  58. #include "HMCACHE.H" /* Cache-related definitions */
  59. #include "HRDEVENT.H" /* HrDevice Table-related definitions */
  60. #include <winioctl.h> /* For PARTITION_INFORMATION et. al. */
  61. /*
  62. |==============================================================================
  63. | Function prototypes for this module.
  64. |
  65. */
  66. /* Gen_nonFixed_disks - Scan for Floppies and CD-ROMS */
  67. static BOOL Gen_nonFixed_disks ( ULONG type_arc );
  68. /* Gen_Fixed_disks - Scan for Fixed Disks */
  69. static BOOL Gen_Fixed_disks ( ULONG type_arc );
  70. /* ProcessPartitions - Process Partition Information into HrDevice Row */
  71. static BOOL ProcessPartitions(
  72. HANDLE hdrv, /* Fixed-Disk containing partitions */
  73. CACHEROW *dv_row, /* Row in hrDevice table for disk */
  74. CHAR *pntdev /* NT Device name for physical disk */
  75. );
  76. /* Process_DS_Row - Process Information into HrDevice and hrDiskStorage Row */
  77. static CACHEROW *Process_DS_Row (
  78. ULONG type_arc, /* hrDeviceType last arc value */
  79. ULONG access, /* hrDiskStorageAccess = readWrite(1) */
  80. ULONG media, /* hrDiskStorageMedia = floppyDisk(4) */
  81. ULONG removable, /* hrDiskStorageRemovable = TRUE */
  82. ULONG capacityKB,/* hrDiskStorageCapacity, (kilobytes) */
  83. ULONG status, /* hrDeviceStatus = unknown(1) */
  84. CHAR *descr /* hrDeviceDescr string */
  85. );
  86. /* FindPartitionLabel - Find MS-DOS Device Label for a Fixed-Disk Partition */
  87. static PCHAR
  88. FindPartitionLabel(
  89. CHAR *pntdev, /* NT Device name for physical disk */
  90. UINT part_id /* Partition Number (1-origined) */
  91. );
  92. /* debug_print_hrdiskstorage - Prints a Row from HrDiskStorage sub-table */
  93. static void
  94. debug_print_hrdiskstorage(
  95. CACHEROW *row /* Row in hrDiskStorage table */
  96. );
  97. /* debug_print_hrpartition - Prints a Row from HrPartition sub-table */
  98. static void
  99. debug_print_hrpartition(
  100. CACHEROW *row /* Row in hrPartition table */
  101. );
  102. /*
  103. |==============================================================================
  104. | Create the list-head for the HrDiskStorage cache.
  105. |
  106. | (This macro is defined in "HMCACHE.H").
  107. */
  108. CACHEHEAD_INSTANCE(hrDiskStorage_cache, debug_print_hrdiskstorage);
  109. /*
  110. * GetHrDiskStorageAccess
  111. * An indication if this long-term storage device is readable and writable
  112. * or only readable. This should reflect the media type, a
  113. *
  114. * Gets the value for HrDiskStorageAccess.
  115. *
  116. * Arguments:
  117. *
  118. * outvalue address to return variable value
  119. * accesss Reserved for future security use
  120. * instance address of instance name as ordered native
  121. * data type(s)
  122. *
  123. * Return Codes:
  124. *
  125. * Standard PDU error codes.
  126. *
  127. * SNMP_ERRORSTATUS_NOERROR Successful get
  128. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  129. * mibtget.c v0.10
  130. *
  131. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  132. | hrDiskStorageAccess
  133. |
  134. | ACCESS SYNTAX
  135. | read-only INTEGER {readWrite(1), readOnly(2)}
  136. |
  137. | "An indication if this long-term storage device is readable and writable or
  138. | only readable. This should reflect the media type, any write-protect
  139. | mechanism, and any device configuration that affects the entire device."
  140. |
  141. | DISCUSSION:
  142. |
  143. | This information for the entire drive is obtained using Win32 API CreateFile
  144. | to open the device and DeviceIoControl to retrieve the needed information.
  145. |
  146. |============================================================================
  147. | 1.3.6.1.2.1.25.3.6.1.1.<instance>
  148. | | | | |
  149. | | | | *-hrDiskStorageAccess
  150. | | | *-hrDiskStorageEntry
  151. | | *-hrDiskStorageTable (the table)
  152. | *-hrDevice
  153. */
  154. UINT
  155. GetHrDiskStorageAccess(
  156. OUT INTAccess *outvalue ,
  157. IN Access_Credential *access ,
  158. IN InstanceName *instance )
  159. {
  160. ULONG index; /* As fetched from instance structure */
  161. CACHEROW *row; /* Row entry fetched from cache */
  162. /*
  163. | Grab the instance information
  164. */
  165. index = GET_INSTANCE(0);
  166. /*
  167. | Use it to find the right entry in the cache
  168. */
  169. if ((row = FindTableRow(index, &hrDiskStorage_cache)) == NULL) {
  170. return SNMP_ERRORSTATUS_GENERR;
  171. }
  172. /*
  173. | Return the "hrDiskStorageAccess" value from this entry
  174. */
  175. *outvalue = row->attrib_list[HRDS_ACCESS].u.unumber_value;
  176. return SNMP_ERRORSTATUS_NOERROR ;
  177. } /* end of GetHrDiskStorageAccess() */
  178. /*
  179. * GetHrDiskStorageMedia
  180. * An indication of the type of media used in this long-term storage device.
  181. *
  182. * Gets the value for HrDiskStorageMedia.
  183. *
  184. * Arguments:
  185. *
  186. * outvalue address to return variable value
  187. * accesss Reserved for future security use
  188. * instance address of instance name as ordered native
  189. * data type(s)
  190. *
  191. * Return Codes:
  192. *
  193. * Standard PDU error codes.
  194. *
  195. * SNMP_ERRORSTATUS_NOERROR Successful get
  196. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  197. * mibtget.c v0.10
  198. *
  199. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  200. | hrDiskStorageMedia
  201. |
  202. | ACCESS SYNTAX
  203. | read-only INTEGER {other(1),unknown(2),hardDisk(3),floppyDisk(4),
  204. | opticalDiskROM(5),opticalDiskWORM(6),opticalDiskRW(7),
  205. | ramDisk(8)}
  206. |
  207. | "An indication of the type of media used in this long-term storage device."
  208. |
  209. | Discussion
  210. |
  211. | This information for the entire drive is obtained using Win32 API CreateFile
  212. | to open the device and DeviceIoControl to retrieve the needed information.
  213. |
  214. |============================================================================
  215. | 1.3.6.1.2.1.25.3.6.1.2.<instance>
  216. | | | | |
  217. | | | | *-hrDiskStorageMedia
  218. | | | *-hrDiskStorageEntry
  219. | | *-hrDiskStorageTable (the table)
  220. | *-hrDevice
  221. */
  222. UINT
  223. GetHrDiskStorageMedia(
  224. OUT INThrDiskStorageMedia *outvalue ,
  225. IN Access_Credential *access ,
  226. IN InstanceName *instance )
  227. {
  228. ULONG index; /* As fetched from instance structure */
  229. CACHEROW *row; /* Row entry fetched from cache */
  230. /*
  231. | Grab the instance information
  232. */
  233. index = GET_INSTANCE(0);
  234. /*
  235. | Use it to find the right entry in the cache
  236. */
  237. if ((row = FindTableRow(index, &hrDiskStorage_cache)) == NULL) {
  238. return SNMP_ERRORSTATUS_GENERR;
  239. }
  240. /*
  241. | Return the "hrDiskStorageAccess" value from this entry
  242. */
  243. *outvalue = row->attrib_list[HRDS_MEDIA].u.unumber_value;
  244. return SNMP_ERRORSTATUS_NOERROR ;
  245. } /* end of GetHrDiskStorageMedia() */
  246. /*
  247. * GetHrDiskStorageRemoveble
  248. * Denotes whether or not the disk media may be removed from the drive.
  249. *
  250. * Gets the value for HrDiskStorageRemoveble.
  251. *
  252. * Arguments:
  253. *
  254. * outvalue address to return variable value
  255. * accesss Reserved for future security use
  256. * instance address of instance name as ordered native
  257. * data type(s)
  258. *
  259. * Return Codes:
  260. *
  261. * Standard PDU error codes.
  262. *
  263. * SNMP_ERRORSTATUS_NOERROR Successful get
  264. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  265. * mibtget.c v0.10
  266. *
  267. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  268. | hrDiskStorageRemoveble
  269. |
  270. | ACCESS SYNTAX
  271. | read-only Boolean
  272. |
  273. | "Denotes whether or not the disk media may be removed from the drive."
  274. |
  275. | DISCUSSION:
  276. |
  277. | This information for the entire drive is obtained using Win32 API CreateFile
  278. | to open the device and DeviceIoControl to retrieve the needed information.
  279. |
  280. |============================================================================
  281. | 1.3.6.1.2.1.25.3.6.1.3.<instance>
  282. | | | | |
  283. | | | | *-hrDiskStorageRemovable
  284. | | | *-hrDiskStorageEntry
  285. | | *-hrDiskStorageTable (the table)
  286. | *-hrDevice
  287. */
  288. UINT
  289. GetHrDiskStorageRemoveble(
  290. OUT Boolean *outvalue ,
  291. IN Access_Credential *access ,
  292. IN InstanceName *instance )
  293. {
  294. ULONG index; /* As fetched from instance structure */
  295. CACHEROW *row; /* Row entry fetched from cache */
  296. /*
  297. | Grab the instance information
  298. */
  299. index = GET_INSTANCE(0);
  300. /*
  301. | Use it to find the right entry in the cache
  302. */
  303. if ((row = FindTableRow(index, &hrDiskStorage_cache)) == NULL) {
  304. return SNMP_ERRORSTATUS_GENERR;
  305. }
  306. /*
  307. | Return the "hrDiskStorageRemovable" value from this entry
  308. */
  309. *outvalue = row->attrib_list[HRDS_REMOVABLE].u.unumber_value;
  310. return SNMP_ERRORSTATUS_NOERROR ;
  311. } /* end of GetHrDiskStorageRemoveble() */
  312. /*
  313. * GetHrDiskStorageCapacity
  314. * The total size for this long-term storage device.
  315. *
  316. * Gets the value for HrDiskStorageCapacity.
  317. *
  318. * Arguments:
  319. *
  320. * outvalue address to return variable value
  321. * accesss Reserved for future security use
  322. * instance address of instance name as ordered native
  323. * data type(s)
  324. *
  325. * Return Codes:
  326. *
  327. * Standard PDU error codes.
  328. *
  329. * SNMP_ERRORSTATUS_NOERROR Successful get
  330. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  331. * mibtget.c v0.10
  332. *
  333. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  334. | hrDiskStorageCapacity
  335. |
  336. | ACCESS SYNTAX
  337. | read-only KBytes
  338. |
  339. | "The total size for this long-term storage device."
  340. |
  341. | DISCUSSION:
  342. |
  343. | This information for the entire drive is obtained using Win32 API CreateFile
  344. | to open the device and DeviceIoControl to retrieve the needed information.
  345. |
  346. |============================================================================
  347. | 1.3.6.1.2.1.25.3.6.1.4.<instance>
  348. | | | | |
  349. | | | | *-hrDiskStorageCapacity
  350. | | | *-hrDiskStorageEntry
  351. | | *-hrDiskStorageTable (the table)
  352. | *-hrDevice
  353. */
  354. UINT
  355. GetHrDiskStorageCapacity(
  356. OUT KBytes *outvalue ,
  357. IN Access_Credential *access ,
  358. IN InstanceName *instance )
  359. {
  360. ULONG index; /* As fetched from instance structure */
  361. CACHEROW *row; /* Row entry fetched from cache */
  362. /*
  363. | Grab the instance information
  364. */
  365. index = GET_INSTANCE(0);
  366. /*
  367. | Use it to find the right entry in the cache
  368. */
  369. if ((row = FindTableRow(index, &hrDiskStorage_cache)) == NULL) {
  370. return SNMP_ERRORSTATUS_GENERR;
  371. }
  372. /*
  373. | Return the "hrDiskStorageCapacity" value from this entry
  374. */
  375. *outvalue = row->attrib_list[HRDS_CAPACITY].u.unumber_value;
  376. return SNMP_ERRORSTATUS_NOERROR ;
  377. } /* end of GetHrDiskStorageCapacity() */
  378. /*
  379. * HrDiskStorageEntryFindInstance
  380. *
  381. * This routine is used to verify that the specified instance is
  382. * valid.
  383. *
  384. * Arguments:
  385. *
  386. * FullOid Address for the full oid - group, variable,
  387. * and instance information
  388. * instance Address for instance specification as an oid
  389. *
  390. * Return Codes:
  391. *
  392. * SNMP_ERRORSTATUS_NOERROR Instance found and valid
  393. * SNMP_ERRORSTATUS_NOSUCHNAME Invalid instance
  394. *
  395. */
  396. UINT
  397. HrDiskStorageEntryFindInstance( IN ObjectIdentifier *FullOid ,
  398. IN OUT ObjectIdentifier *instance )
  399. {
  400. UINT tmp_instance ;
  401. //
  402. // Developer instrumentation code to find appropriate instance goes here.
  403. // For non-tables, it is not necessary to modify this routine. However, if
  404. // there is any context that needs to be set, it can be done here.
  405. //
  406. if ( FullOid->idLength <= HRDISKSTORAGEENTRY_VAR_INDEX )
  407. // No instance was specified
  408. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  409. else if ( FullOid->idLength != HRDISKSTORAGEENTRY_VAR_INDEX + 1 )
  410. // Instance length is more than 1
  411. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  412. else
  413. // The only valid instance for a non-table are instance 0. If this
  414. // is a non-table, the following code validates the instances. If this
  415. // is a table, developer modification is necessary below.
  416. tmp_instance = FullOid->ids[ HRDISKSTORAGEENTRY_VAR_INDEX ] ;
  417. /*
  418. | For hrDiskStorage, the instance arc(s) is a single arc, and it must
  419. | correctly select an entry in the hrDiskStorage cache.
  420. | Check that here.
  421. |
  422. | Note that if there is a row there, there is also one in the
  423. | hrDevice table with the same index.
  424. */
  425. if ( FindTableRow(tmp_instance, &hrDiskStorage_cache) == NULL ) {
  426. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  427. }
  428. else
  429. {
  430. // the instance is valid. Create the instance portion of the OID
  431. // to be returned from this call.
  432. instance->ids[ 0 ] = tmp_instance ;
  433. instance->idLength = 1 ;
  434. }
  435. return SNMP_ERRORSTATUS_NOERROR ;
  436. } /* end of HrDiskStorageEntryFindInstance() */
  437. /*
  438. * HrDiskStorageEntryFindNextInstance
  439. *
  440. * This routine is called to get the next instance. If no instance
  441. * was passed than return the first instance (1).
  442. *
  443. * Arguments:
  444. *
  445. * FullOid Address for the full oid - group, variable,
  446. * and instance information
  447. * instance Address for instance specification as an oid
  448. *
  449. * Return Codes:
  450. *
  451. * SNMP_ERRORSTATUS_NOERROR Instance found and valid
  452. * SNMP_ERRORSTATUS_NOSUCHNAME Invalid instance
  453. *
  454. */
  455. UINT
  456. HrDiskStorageEntryFindNextInstance( IN ObjectIdentifier *FullOid ,
  457. IN OUT ObjectIdentifier *instance )
  458. {
  459. //
  460. // Developer supplied code to find the next instance of class goes here.
  461. // If this is a class with cardinality 1, no modification of this routine
  462. // is necessary unless additional context needs to be set.
  463. // If the FullOid does not specify an instance, then the only instance
  464. // of the class is returned. If this is a table, the first row of the
  465. // table is returned.
  466. //
  467. // If an instance is specified and this is a non-table class, then
  468. // NOSUCHNAME is returned so that correct MIB rollover processing occurs.
  469. // If this is a table, then the next instance is the one following the
  470. // current instance.
  471. //
  472. // If there are no more instances in the table, return NOSUCHNAME.
  473. //
  474. CACHEROW *row;
  475. ULONG tmp_instance;
  476. if ( FullOid->idLength <= HRDISKSTORAGEENTRY_VAR_INDEX )
  477. {
  478. /*
  479. | Too short: must return the instance arc that selects the first
  480. | entry in the table if there is one.
  481. */
  482. tmp_instance = 0;
  483. }
  484. else {
  485. /*
  486. | There is at least one instance arc. Even if it is the only arc
  487. | we use it as the "index" in a request for the "NEXT" one.
  488. */
  489. tmp_instance = FullOid->ids[ HRDISKSTORAGEENTRY_VAR_INDEX ] ;
  490. }
  491. /* Now go off and try to find the next instance in the table */
  492. if ((row = FindNextTableRow(tmp_instance, &hrDiskStorage_cache)) == NULL) {
  493. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  494. }
  495. instance->ids[ 0 ] = row->index ;
  496. instance->idLength = 1 ;
  497. return SNMP_ERRORSTATUS_NOERROR ;
  498. } /* end of HrDiskStorageEntryFindNextInstance() */
  499. /*
  500. * HrDiskStorageEntryConvertInstance
  501. *
  502. * This routine is used to convert the object id specification of an
  503. * instance into an ordered native representation. The object id format
  504. * is that object identifier that is returned from the Find Instance
  505. * or Find Next Instance routines. It is NOT the full object identifier
  506. * that contains the group and variable object ids as well. The native
  507. * representation is an argc/argv-like structure that contains the
  508. * ordered variables that define the instance. This is specified by
  509. * the MIB's INDEX clause. See RFC 1212 for information about the INDEX
  510. * clause.
  511. *
  512. *
  513. * Arguments:
  514. *
  515. * oid_spec Address of the object id instance specification
  516. * native_spec Address to return the ordered native instance
  517. * specification
  518. *
  519. * Return Codes:
  520. *
  521. * SUCCESS Conversion complete successfully
  522. * FAILURE Unable to convert object id into native format
  523. *
  524. */
  525. UINT
  526. HrDiskStorageEntryConvertInstance( IN ObjectIdentifier *oid_spec ,
  527. IN OUT InstanceName *native_spec )
  528. {
  529. static char *array; /* The address of this (char *) is passed back */
  530. /* as though it were an array of length 1 of these */
  531. /* types. */
  532. static ULONG inst; /* The address of this ULONG is passed back */
  533. /* (Obviously, no "free()" action is needed) */
  534. /* We only expect the one arc in "oid_spec" */
  535. inst = oid_spec->ids[0];
  536. array = (char *) &inst;
  537. native_spec->count = 1;
  538. native_spec->array = &array;
  539. return SUCCESS ;
  540. } /* end of HrDiskStorageEntryConvertInstance() */
  541. /*
  542. * HrDiskStorageEntryFreeInstance
  543. *
  544. * This routine is used to free an ordered native representation of an
  545. * instance name.
  546. *
  547. * Arguments:
  548. *
  549. * instance Address to return the ordered native instance
  550. * specification
  551. *
  552. * Return Codes:
  553. *
  554. *
  555. */
  556. void
  557. HrDiskStorageEntryFreeInstance( IN OUT InstanceName *instance )
  558. {
  559. /* No action needed for hrDiskStorageTable */
  560. } /* end of HrDiskStorageEntryFreeInstance() */
  561. /*
  562. | End of Generated Code
  563. */
  564. /* Gen_HrDiskStorage_Cache - Generate a initial cache for HrDiskStorage Table */
  565. /* Gen_HrDiskStorage_Cache - Generate a initial cache for HrDiskStorage Table */
  566. /* Gen_HrDiskStorage_Cache - Generate a initial cache for HrDiskStorage Table */
  567. BOOL
  568. Gen_HrDiskStorage_Cache(
  569. ULONG type_arc
  570. )
  571. /*
  572. | EXPLICIT INPUTS:
  573. |
  574. | "type_arc" is the number "n" to be used as the last arc in the
  575. | device-type OID:
  576. |
  577. | 1.3.6.1.2.1.25.3.1.n
  578. | | | |
  579. | | | * Identifying arc for type
  580. | | *-hrDeviceTypes (OIDs specifying device types)
  581. | *-hrDevice
  582. |
  583. | for devices created by this cache-population routine.
  584. |
  585. | IMPLICIT INPUTS:
  586. |
  587. | The module-local head of the cache for the HrDiskStorage table,
  588. | "HrDiskStorage_cache".
  589. |
  590. | OUTPUTS:
  591. |
  592. | On Success:
  593. | Function returns TRUE indicating that both caches have been fully
  594. | populated with all "static" cache-able values. This function populates
  595. | not only the hrDevice table cache but the hrDiskStorage cache as well.
  596. |
  597. | On any Failure:
  598. | Function returns FALSE (indicating "not enough storage").
  599. |
  600. | THE BIG PICTURE:
  601. |
  602. | At subagent startup time, the cache for each table in the MIB is
  603. | populated with rows for each row in the table. This function is
  604. | invoked by the start-up code in "Gen_HrDevice_Cache()" ("HRDEVENT.C")
  605. | to populate the cache for the HrDiskStorage table AND the hrDevice
  606. | Table.
  607. |
  608. | OTHER THINGS TO KNOW:
  609. |
  610. | There is one of these function for every table that has a cache.
  611. | Each is found in the respective source file.
  612. |
  613. | This function differs from all of the other corresponding sub-table
  614. | function instances in that this sub-table has its own cache, rather
  615. | than depending solely on that of the hrDevice table.
  616. |
  617. | As a consequence, we don't need fancy logic in the FindInstance()
  618. | and FindNextInstance() functions to determine whether a particular
  619. | instance is valid: if it is, there is a row entry in the local
  620. | hrDiskStorage cache.
  621. |
  622. | As another consequence, this function must load both caches with
  623. | data (and it must use the same "index" numbers in both caches
  624. | for each row entered).
  625. |
  626. | ----
  627. |
  628. | The strategy on getting all disks goes like this:
  629. |
  630. | * Since the "\\.\PHYSICALDRIVEn" trick with "CreateFile" doesn't allow
  631. | access to floppies or CD-ROMs, we process these separately as a
  632. | first step.
  633. |
  634. | + We presume "A:" and "B:" may be floppies and we look for them
  635. | explicitly. Any found are presumed "readWrite" and Removable.
  636. | If a medium is present, we may get a full description plus an
  637. | accurate storage size, otherwise we just don't know for sure,
  638. | (DeviceIoControl for drive info fails if no disk is in the
  639. | floppy drive).
  640. |
  641. | + We then scan all logical drive strings looking for instances of
  642. | CD-ROM drives. Any found are presumed "readOnly" and Removable.
  643. | We can't obtain storage sizes even if a disk is present for these,
  644. | so storage is left at zero.
  645. |
  646. | * Then the "\\.\PHYSICALDRIVEn" trick is used to enumerate the real
  647. | hard disks, and real storage sizes are obtainable.
  648. |
  649. |============================================================================
  650. | 1.3.6.1.2.1.25.3.6....
  651. | | |
  652. | | *-hrDiskStorageTable (the table)
  653. | *-hrDevice
  654. */
  655. {
  656. // Blow away any old copy of the cache
  657. DestroyTable(&hrDiskStorage_cache);
  658. /*
  659. | Do Floppies and CD-ROM drives (non-fixed disks)
  660. */
  661. if (Gen_nonFixed_disks( type_arc ) == FALSE) {
  662. DestroyTable(&hrDiskStorage_cache); // destroy any partial rows if necessary
  663. return ( FALSE );
  664. }
  665. /*
  666. | Do Fixed drives
  667. */
  668. if (Gen_Fixed_disks( type_arc ) == FALSE) {
  669. DestroyTable(&hrDiskStorage_cache);
  670. return ( FALSE );
  671. }
  672. /* Success */
  673. return ( TRUE );
  674. }
  675. /* Gen_nonFixed_disks - Scan for Floppies and CD-ROMS */
  676. /* Gen_nonFixed_disks - Scan for Floppies and CD-ROMS */
  677. /* Gen_nonFixed_disks - Scan for Floppies and CD-ROMS */
  678. static BOOL
  679. Gen_nonFixed_disks (
  680. ULONG type_arc
  681. )
  682. /*
  683. | EXPLICIT INPUTS:
  684. |
  685. | "type_arc" is the number "n" to be used as the last arc in the
  686. | device-type OID:
  687. |
  688. | 1.3.6.1.2.1.25.3.1.n
  689. | | | |
  690. | | | * Identifying arc for type
  691. | | *-hrDeviceTypes (OIDs specifying device types)
  692. | *-hrDevice
  693. |
  694. | for devices created by this cache-population routine.
  695. |
  696. | IMPLICIT INPUTS:
  697. |
  698. | The module-local head of the cache for the HrDiskStorage table,
  699. | "HrDiskStorage_cache".
  700. |
  701. | OUTPUTS:
  702. |
  703. | On Success:
  704. | Function returns TRUE indicating that the both cachees have been fully
  705. | populated with all non-Fixed disks.
  706. |
  707. | On any Failure:
  708. | Function returns FALSE (indicating "not enough storage").
  709. |
  710. | THE BIG PICTURE:
  711. |
  712. | Part I of hrDiskStorage cache population.
  713. |
  714. | OTHER THINGS TO KNOW:
  715. |
  716. | We scan using the list of Logical Disk drive strings from
  717. | GetLogicalDriveStrings() formed up into UNC form, (e.g. "\\.\A:"
  718. | for "A:\" returned from GetLogicalDriveStrings()).
  719. */
  720. {
  721. CHAR temp[8]; /* Temporary buffer for first call */
  722. LPSTR pDrvStrings; /* --> allocated storage for drive strings */
  723. LPSTR pOriginal_DrvStrings; /* (Needed for final deallocation */
  724. DWORD DS_request_len; /* Storage actually needed */
  725. DWORD DS_current_len; /* Storage used on 2nd call */
  726. #define PHYS_SIZE 32
  727. CHAR phys_name[PHYS_SIZE+1]; /* Buffer where a string like "\\.C:" (for */
  728. /* example) is built for drive access. */
  729. phys_name[PHYS_SIZE] = 0; // ensures null terminated phys_name
  730. /*
  731. | We're going to call GetLogicalDriveStrings() twice, once to get the proper
  732. | buffer size, and the second time to actually get the drive strings.
  733. |
  734. | The Bogus call.
  735. */
  736. if ((DS_request_len = GetLogicalDriveStrings(2, temp)) == 0) {
  737. /* Request failed altogether, can't initialize */
  738. return ( FALSE );
  739. }
  740. /*
  741. | Grab enough storage for the drive strings plus one null byte at the end
  742. */
  743. if ( (pOriginal_DrvStrings = pDrvStrings = malloc( (DS_request_len + 2) ) )
  744. == NULL) {
  745. /* Storage Request failed altogether, can't initialize */
  746. return ( FALSE );
  747. }
  748. /* Go for all of the strings
  749. |
  750. | The Real Call.
  751. */
  752. if ((DS_current_len = GetLogicalDriveStrings(DS_request_len, pDrvStrings))
  753. == 0) {
  754. /* Request failed altogether, can't initialize */
  755. free( pOriginal_DrvStrings );
  756. return ( FALSE );
  757. }
  758. /*
  759. |==============================================================================
  760. | For each logical drive . . .
  761. */
  762. while ( strlen(pDrvStrings) > 0 ) {
  763. UINT drivetype; /* Type of the drive from "GetDriveType()" */
  764. /*
  765. | Get the drive-type so we can decide whether it should participate in
  766. | this population effort. We do only CD-ROMS and REMOVABLES.
  767. */
  768. drivetype = GetDriveType(pDrvStrings);
  769. /* Skip the stuff we don't want to look at */
  770. if ( drivetype != DRIVE_REMOVABLE && drivetype != DRIVE_CDROM ) {
  771. /* Step to next string, if any */
  772. pDrvStrings += strlen(pDrvStrings) + 1;
  773. continue;
  774. }
  775. /* If we have room in the buffer to build the handle-name string */
  776. if ((strlen(pDrvStrings) + strlen("\\\\.\\")) < PHYS_SIZE) {
  777. #define DESCR_BSZ 512
  778. CHAR d_buf[DESCR_BSZ+1];/* Dsecription bld buff */
  779. HANDLE hdrv; /* Handle to device */
  780. DWORD bytes_out; /* Bytes retnd into geo_info */
  781. DISK_GEOMETRY geo_info; /* Geometry Info from drive */
  782. char *mt; /* Media Type */
  783. ULONG access; /* hrDiskStorageAccess = readWrite(1) */
  784. ULONG media; /* hrDiskStorageMedia = floppyDisk(4) */
  785. ULONG removable; /* hrDiskStorageRemovable = TRUE */
  786. ULONG capacityKB; /* hrDiskStorageCapacity, (kilobytes) */
  787. ULONG status; /* hrDeviceStatus = unknown(1) */
  788. CHAR *descr; /* hrDeviceDescr string */
  789. UINT nPrevErrorMode; /* previous state of error-mode bit flags */
  790. d_buf[DESCR_BSZ] = 0; // ensures null terminated d_buf
  791. /* 012345
  792. | Build it for device A: "\\.\A:" */
  793. _snprintf(phys_name, PHYS_SIZE, "\\\\.\\%2.2s", pDrvStrings);
  794. /*
  795. | Set SNMP variables accordingly
  796. */
  797. if (drivetype != DRIVE_CDROM) { /* Floppy */
  798. access = 1; /* hrDiskStorageAccess = readWrite(1) */
  799. media = 4; /* hrDiskStorageMedia = floppyDisk(4) */
  800. removable = TRUE; /* hrDiskStorageRemovable = TRUE */
  801. capacityKB = 0; /* hrDiskStorageCapacity (unknown) */
  802. status = 1; /* hrDeviceStatus = unknown(1) */
  803. descr = pDrvStrings; /* hrDeviceDescr, initial (e.g."A:\") */
  804. }
  805. else { /* CD-ROM */
  806. /*
  807. | We can't get much of anything about CD-ROMs except the fact
  808. | that there is one. Capacity cannot be presumed as DVD is
  809. | now available and some drives read both CD-ROMs and DVD.
  810. */
  811. access = 2; /* hrDiskStorageAccess = readOnly(2) */
  812. media = 5; /* hrDiskStorageMedia = opticalDiskROM(5)*/
  813. removable = TRUE; /* hrDiskStorageRemovable = TRUE */
  814. capacityKB = 0; /* hrDiskStorageCapacity (unknown) */
  815. status = 1; /* hrDeviceStatus = unknown(1) */
  816. descr = pDrvStrings; /* hrDeviceDescr, initial (e.g."D:\") */
  817. }
  818. /*
  819. | Suppress any attempt by the system to make the user put a volume in a
  820. | removable drive ("CreateFile" will just fail).
  821. */
  822. nPrevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  823. /* Attempt to get a handle using this physical name string */
  824. hdrv = CreateFile(phys_name, // Device
  825. GENERIC_READ, // device query
  826. // Share Mode
  827. FILE_SHARE_READ |
  828. FILE_SHARE_WRITE,
  829. NULL, // Security
  830. OPEN_EXISTING, // CreationDistribution
  831. FILE_ATTRIBUTE_NORMAL, // FlagsandAttributes
  832. NULL // Template file
  833. );
  834. /* If we successfully opened the device . . . */
  835. if (hdrv != INVALID_HANDLE_VALUE) {
  836. /*
  837. | Device is Open.
  838. |
  839. | If it is NOT a CD-ROM, (ie, a floppy) its worth trying to get
  840. | DRIVE GEOMETRY (which will come back if there is a floppy in
  841. | the drive).
  842. */
  843. if (drivetype != DRIVE_CDROM) { /* Floppy */
  844. /* ==========================================================
  845. | IOCTL_DISK_GET_DRIVE_GEOMETRY
  846. |
  847. | If we can get this, we get a better description and an
  848. | accurate capacity value.
  849. */
  850. if (DeviceIoControl(hdrv, // device handle
  851. // IoControlCode (op-code)
  852. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  853. NULL, // "input buffer"
  854. 0, // "input buffer size"
  855. &geo_info, // "output buffer"
  856. // "output buffer size"
  857. sizeof(DISK_GEOMETRY),
  858. &bytes_out, // bytes written to geo_info
  859. NULL // no Overlapped I/o
  860. )) {
  861. /*
  862. | Compute capacity
  863. */
  864. capacityKB = (ULONG)
  865. ((geo_info.Cylinders.QuadPart * // 64 bits
  866. (geo_info.TracksPerCylinder * // 32 bits
  867. geo_info.SectorsPerTrack *
  868. geo_info.BytesPerSector)
  869. ) / 1024);
  870. /* hrDeviceStatus = running(2) */
  871. status = 2;
  872. switch ( geo_info.MediaType ) {
  873. case F5_1Pt2_512: mt = "5.25, 1.2MB, 512 bytes/sector"; break;
  874. case F3_1Pt44_512: mt = "3.5, 1.44MB, 512 bytes/sector"; break;
  875. case F3_2Pt88_512: mt = "3.5, 2.88MB, 512 bytes/sector"; break;
  876. case F3_20Pt8_512: mt = "3.5, 20.8MB, 512 bytes/sector"; break;
  877. case F3_720_512: mt = "3.5, 720KB, 512 bytes/sector"; break;
  878. case F5_360_512: mt = "5.25, 360KB, 512 bytes/sector"; break;
  879. case F5_320_512: mt = "5.25, 320KB, 512 bytes/sector"; break;
  880. case F5_320_1024: mt = "5.25, 320KB, 1024 bytes/sector"; break;
  881. case F5_180_512: mt = "5.25, 180KB, 512 bytes/sector"; break;
  882. case F5_160_512: mt = "5.25, 160KB, 512 bytes/sector"; break;
  883. case F3_120M_512: mt = "3.5, 120M Floppy"; break;
  884. case F3_640_512: mt = "3.5 , 640KB, 512 bytes/sector"; break;
  885. case F5_640_512: mt = "5.25, 640KB, 512 bytes/sector"; break;
  886. case F5_720_512: mt = "5.25, 720KB, 512 bytes/sector"; break;
  887. case F3_1Pt2_512: mt = "3.5 , 1.2Mb, 512 bytes/sector"; break;
  888. case F3_1Pt23_1024: mt = "3.5 , 1.23Mb, 1024 bytes/sector"; break;
  889. case F5_1Pt23_1024: mt = "5.25, 1.23MB, 1024 bytes/sector"; break;
  890. case F3_128Mb_512: mt = "3.5 MO 128Mb 512 bytes/sector"; break;
  891. case F3_230Mb_512: mt = "3.5 MO 230Mb 512 bytes/sector"; break;
  892. case F8_256_128: mt = "8in, 256KB, 128 bytes/sector"; break;
  893. default:
  894. case RemovableMedia:
  895. case FixedMedia:
  896. case Unknown: mt = "Format is unknown"; break;
  897. }
  898. /* Format a better description if it'll all fit */
  899. if ((strlen(pDrvStrings) + strlen(mt) + 1) < DESCR_BSZ ) {
  900. _snprintf(d_buf, DESCR_BSZ, "%s%s", pDrvStrings, mt);
  901. descr = d_buf;
  902. }
  903. } /* If (we managed to get geometry information) */
  904. }
  905. CloseHandle(hdrv);
  906. } /* if (we managed to "CreateFile" the device successfully) */
  907. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  908. /*
  909. | Create a row in HrDevice Table and a corresponding row in
  910. | hrDiskStorage sub-table.
  911. */
  912. if ( Process_DS_Row (
  913. type_arc, /* hrDeviceType last arc */
  914. access, /* hrDiskStorageAccess */
  915. media, /* hrDiskStorageMedia */
  916. removable, /* hrDiskStorageRemovable */
  917. capacityKB,/* hrDiskStorageCapacity */
  918. status, /* hrDeviceStatus */
  919. descr /* hrDeviceDescr */
  920. ) == NULL) {
  921. /* Something blew */
  922. free( pOriginal_DrvStrings );
  923. return ( FALSE );
  924. }
  925. } /* if (we managed to build a device name) */
  926. /* Step to next string, if any */
  927. pDrvStrings += strlen(pDrvStrings) + 1;
  928. }
  929. free( pOriginal_DrvStrings );
  930. /* Successful scan */
  931. return ( TRUE );
  932. }
  933. /* Gen_Fixed_disks - Scan for Fixed Disks */
  934. /* Gen_Fixed_disks - Scan for Fixed Disks */
  935. /* Gen_Fixed_disks - Scan for Fixed Disks */
  936. static BOOL
  937. Gen_Fixed_disks (
  938. ULONG type_arc
  939. )
  940. /*
  941. | EXPLICIT INPUTS:
  942. |
  943. | "type_arc" is the number "n" to be used as the last arc in the
  944. | device-type OID:
  945. |
  946. | 1.3.6.1.2.1.25.3.1.n
  947. | | | |
  948. | | | * Identifying arc for type
  949. | | *-hrDeviceTypes (OIDs specifying device types)
  950. | *-hrDevice
  951. |
  952. | for devices created by this cache-population routine.
  953. |
  954. | IMPLICIT INPUTS:
  955. |
  956. | The module-local head of the cache for the HrDiskStorage table,
  957. | "HrDiskStorage_cache".
  958. |
  959. | OUTPUTS:
  960. |
  961. | On Success:
  962. | Function returns TRUE indicating that the both cachees have been fully
  963. | populated with all non-Fixed disks. If the device from which the
  964. | system was booted is encountered, it's hrDevice index is set into
  965. | "InitLoadDev_index" (defined in "HRDEVENT.C").
  966. |
  967. | On any Failure:
  968. | Function returns FALSE (indicating "not enough storage").
  969. |
  970. | THE BIG PICTURE:
  971. |
  972. | Part II of hrDiskStorage cache population.
  973. |
  974. | OTHER THINGS TO KNOW:
  975. |
  976. | We scan using the "\\.\PHYSICALDRIVEx" syntax permitted to
  977. | "CreateFile()". CreateFile seems to allow opens only on disks
  978. | that are hard-fixed disks (no floppies, no CD-ROMS).
  979. |
  980. | This function is also (while it is "at it") looking for the drive
  981. | from which the system was booted (in order to set a global value
  982. | (hrdevice table index) for the value of "InitLoadDev_index" (defined
  983. | in "HRDEVENT.C") which becomes the value of "HrSystemInitialLoadDevice".
  984. */
  985. {
  986. HANDLE hdrv; /* Handle to device */
  987. UINT dev_number; /* Current "x" in "\\.\PHYSICALDRIVEx" */
  988. #undef PHYS_SIZE
  989. #define PHYS_SIZE 64
  990. CHAR phys_name[PHYS_SIZE+1]; /* Buffer where a string like */
  991. /* "\\.PHYSICALDRIVE0" (for example) */
  992. /* is built for drive access. */
  993. DRIVE_LAYOUT_INFORMATION *dl; /* Drive-layout pointer */
  994. #define BBSz 768
  995. CHAR big[BBSz]; /* Big buffer for layout info */
  996. DWORD bytes_out; /* Bytes retnd into "big" */
  997. CHAR windir[MAX_PATH+1]; /* Current Windows Directory */
  998. CHAR ntdev[MAX_PATH+2]; /* NT Device Name for MSDOS drive */
  999. CHAR pntdev[MAX_PATH+2]; /* NT Device Name for PHYSICALDRIVE*/
  1000. UINT nPrevErrorMode; /* previous state of error-mode bit flags */
  1001. phys_name[PHYS_SIZE] = 0; // ensures null terminated phys_name
  1002. /*
  1003. |==============================================================================
  1004. | Compute the NT "device name" we expect is the device from which the
  1005. | system was booted.
  1006. |
  1007. | Strategy:
  1008. |
  1009. | - Obtain "current windows directory" and truncate to obtain just the MS-DOS
  1010. | device name.
  1011. |
  1012. | - Do QueryDosDevice to get the underlying "NT Device Name", which will
  1013. | include a "\PartitionX" on the end of it, where "X" is presumed to be
  1014. | the 1-origined partition number.
  1015. |
  1016. | - Mangle the NT Device Name so that it sez "....\Partition0" (ie "partition
  1017. | zero") which is the NT Device Name we expect to be associated with the
  1018. | "\\.\PHYSICALDRIVEy" string we generate for each valid fixed disk below.
  1019. */
  1020. /* If we can get the current Windows Directory */
  1021. if (GetWindowsDirectory(windir, MAX_PATH+1) != 0 ) {
  1022. /* Truncate to just "C:" (or whatever) */
  1023. windir[2] = 0;
  1024. /* Obtain the NT Device Name associated with MS-DOS logical drive */
  1025. if (QueryDosDevice(windir, ntdev, MAX_PATH) != 0) {
  1026. PCHAR partition;
  1027. /* If the string "\Partition" appears in this string */
  1028. if ((partition = strstr(ntdev,"\\Partition")) != NULL) {
  1029. /* Convert it to say "\Partition0" regardless */
  1030. strcpy(partition, "\\Partition0");
  1031. }
  1032. else {
  1033. /* Failure: Null-terminate so we fail gracefully */
  1034. ntdev[0] = '\0';
  1035. }
  1036. }
  1037. else {
  1038. /* Failure: Null-terminate so we fail gracefully */
  1039. ntdev[0] = '\0';
  1040. }
  1041. }
  1042. else {
  1043. /* Failure: Null-terminate so we fail gracefully */
  1044. ntdev[0] = '\0';
  1045. }
  1046. /*
  1047. |==============================================================================
  1048. | For every physical device we can open successfully. . .
  1049. */
  1050. for (dev_number = 0; ; dev_number += 1) {
  1051. /* Build it for device n: "\\.\PHYSICALDRIVEn" */
  1052. _snprintf(phys_name, PHYS_SIZE, "\\\\.\\PHYSICALDRIVE%d", dev_number);
  1053. /*
  1054. | Suppress any attempt by the system to make the user put a volume in a
  1055. | removable drive ("CreateFile" will just fail).
  1056. */
  1057. nPrevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  1058. /* Attempt to get a handle using this physical name string */
  1059. if ((hdrv = CreateFile(phys_name, // Device
  1060. GENERIC_READ, // Access
  1061. // Share Mode
  1062. FILE_SHARE_READ |
  1063. FILE_SHARE_WRITE,
  1064. NULL, // Security
  1065. OPEN_EXISTING, // CreationDistribution
  1066. FILE_ATTRIBUTE_NORMAL, // FlagsandAttributes
  1067. NULL // Template file
  1068. )) != INVALID_HANDLE_VALUE) {
  1069. ULONG access; /* hrDiskStorageAccess = readWrite(1) */
  1070. ULONG media; /* hrDiskStorageMedia = floppyDisk(4) */
  1071. ULONG removable; /* hrDiskStorageRemovable = TRUE */
  1072. ULONG capacityKB; /* hrDiskStorageCapacity, (kilobytes) */
  1073. ULONG status; /* hrDeviceStatus = unknown(1) */
  1074. CHAR *descr; /* hrDeviceDescr string */
  1075. DWORD bytes_out; /* Bytes retnd into geo_info */
  1076. DISK_GEOMETRY geo_info; /* Geometry Info from drive */
  1077. char *mt; /* Media Type */
  1078. CACHEROW *dv_row; /* HrDevice table row created for disk*/
  1079. /*
  1080. | Device is Open, so we can presume it really exists, so it goes
  1081. | into the hrDevice table.
  1082. |
  1083. | It is presumed to be a FIXED disk.
  1084. */
  1085. access = 1; /* hrDiskStorageAccess = readWrite(1) */
  1086. media = 3; /* hrDiskStorageMedia = hardDisk(3) */
  1087. removable = FALSE; /* hrDiskStorageRemovable = FALSE */
  1088. capacityKB = 0; /* hrDiskStorageCapacity (unknown) */
  1089. status = 1; /* hrDeviceStatus = unknown(1) */
  1090. descr = "Fixed Disk";/* hrDeviceDescr */
  1091. /* ==========================================================
  1092. | IOCTL_DISK_GET_DRIVE_GEOMETRY
  1093. |
  1094. | If we can get this, we get a better description and an
  1095. | accurate capacity value.
  1096. */
  1097. if (DeviceIoControl(hdrv, // device handle
  1098. // IoControlCode (op-code)
  1099. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  1100. NULL, // "input buffer"
  1101. 0, // "input buffer size"
  1102. &geo_info, // "output buffer"
  1103. // "output buffer size"
  1104. sizeof(DISK_GEOMETRY),
  1105. &bytes_out, // bytes written to geo_info
  1106. NULL // no Overlapped I/o
  1107. )) {
  1108. /*
  1109. | Compute capacity
  1110. */
  1111. capacityKB = (ULONG)
  1112. (geo_info.Cylinders.QuadPart * // 64 bit
  1113. (geo_info.TracksPerCylinder * // 32 bits
  1114. geo_info.SectorsPerTrack *
  1115. geo_info.BytesPerSector)
  1116. ) / 1024;
  1117. /* hrDeviceStatus = running(2) */
  1118. status = 2;
  1119. switch ( geo_info.MediaType ) {
  1120. case FixedMedia:
  1121. break;
  1122. default:
  1123. descr = "Unknown Media";
  1124. }
  1125. }
  1126. /*
  1127. | Create a row in HrDevice Table and a corresponding row in
  1128. | hrDiskStorage sub-table.
  1129. */
  1130. if ((dv_row = Process_DS_Row (type_arc, /* hrDeviceType last arc */
  1131. access, /* hrDiskStorageAccess */
  1132. media, /* hrDiskStorageMedia */
  1133. removable, /* hrDiskStorageRemovable */
  1134. capacityKB,/* hrDiskStorageCapacity */
  1135. status, /* hrDeviceStatus */
  1136. descr /* hrDeviceDescr */
  1137. )
  1138. ) == NULL) {
  1139. /* Something blew */
  1140. CloseHandle(hdrv);
  1141. SetErrorMode(nPrevErrorMode);/* Turn error suppression mode off */
  1142. return ( FALSE );
  1143. }
  1144. /*
  1145. | If it turns out this is the device from which the system was
  1146. | booted, we need to return the index associated with the "dv_row"
  1147. | row into "InitLoadDev_index" (defined in "HRDEVENT.C") to become
  1148. | the value of "HrSystemInitialLoadDevice".
  1149. |
  1150. | See if the NT Device name associated with this "\\.\PHYSICALDRIVEx"
  1151. | matches the value predicted for the system boot device.
  1152. |
  1153. | If we can get the NT Device name for "PHYSICALDRIVEn" . . . */
  1154. if (QueryDosDevice(&phys_name[4], pntdev, MAX_PATH) != 0 ) {
  1155. /* If it matches the predicted value for boot device . . . */
  1156. if ( strcmp(pntdev, ntdev) == 0) {
  1157. /* Record the index for the current "physicaldrive" */
  1158. InitLoadDev_index = dv_row->index;
  1159. }
  1160. }
  1161. else {
  1162. /*
  1163. | Fail gracefully so things will still work in
  1164. | "ProcessPartition()" below.
  1165. */
  1166. pntdev[0] = '\0';
  1167. }
  1168. /*
  1169. | Create a hrPartition table (in the HrDevice Table row just created
  1170. | for the disk) to represent the partitions on this fixed disk.
  1171. */
  1172. if ( ProcessPartitions( hdrv, dv_row, pntdev ) != TRUE ) {
  1173. /* Something blew */
  1174. CloseHandle(hdrv);
  1175. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  1176. return ( FALSE );
  1177. }
  1178. /* Fold up shop on this disk */
  1179. CloseHandle(hdrv);
  1180. } /* If we managed to "CreateFile()" the device */
  1181. else { /* Open failed... give up the scan */
  1182. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  1183. break;
  1184. }
  1185. SetErrorMode(nPrevErrorMode); /* Turn error suppression mode off */
  1186. } /* For each device */
  1187. /* Successful scan */
  1188. return ( TRUE );
  1189. }
  1190. /* Process_DS_Row - Process Information into HrDevice and hrDiskStorage Row */
  1191. /* Process_DS_Row - Process Information into HrDevice and hrDiskStorage Row */
  1192. /* Process_DS_Row - Process Information into HrDevice and hrDiskStorage Row */
  1193. static CACHEROW *
  1194. Process_DS_Row (
  1195. ULONG type_arc, /* hrDeviceType last arc value */
  1196. ULONG access, /* hrDiskStorageAccess = readWrite(1) */
  1197. ULONG media, /* hrDiskStorageMedia = floppyDisk(4) */
  1198. ULONG removable, /* hrDiskStorageRemovable = TRUE */
  1199. ULONG capacityKB,/* hrDiskStorageCapacity, (kilobytes) */
  1200. ULONG status, /* hrDeviceStatus = unknown(1) */
  1201. CHAR *descr /* hrDeviceDescr string */
  1202. )
  1203. /*
  1204. | EXPLICIT INPUTS:
  1205. |
  1206. | "type_arc" is the number "n" to be used as the last arc in the
  1207. | device-type OID:
  1208. |
  1209. | 1.3.6.1.2.1.25.3.1.n
  1210. | | | |
  1211. | | | * Identifying arc for type
  1212. | | *-hrDeviceTypes (OIDs specifying device types)
  1213. | *-hrDevice
  1214. |
  1215. | for devices created by this cache-population routine.
  1216. |
  1217. | The rest of the arguments outline above are used to fill in
  1218. | attribute values in both the hrDevice table row and the corresponding
  1219. | hrDiskStorage row.
  1220. |
  1221. | IMPLICIT INPUTS:
  1222. |
  1223. | The module-local head of the cache for the HrDiskStorage table,
  1224. | "HrDiskStorage_cache".
  1225. |
  1226. | OUTPUTS:
  1227. |
  1228. | On Success:
  1229. | Function returns pointer to row entry made to the hrDevice
  1230. | table indicating that the both caches have been fully
  1231. | populated with a new row.
  1232. |
  1233. | On any Failure:
  1234. | Function returns NULL (indicating "not enough storage" or other
  1235. | failure.).
  1236. |
  1237. | THE BIG PICTURE:
  1238. |
  1239. |
  1240. | OTHER THINGS TO KNOW:
  1241. |
  1242. | This function contains common "row-insertion" code for the
  1243. | Gen_Fixed_disks() and Gen_nonFixed_disks() functions.
  1244. */
  1245. {
  1246. CACHEROW *dv_row; /* Row created in hrDevice table */
  1247. CACHEROW *ds_row; /* Row created in hrDiskStorage table */
  1248. /*
  1249. |==========================
  1250. | Create hrDevice Row entry.
  1251. |
  1252. | Note we're initializing this as though the Hidden Context is always
  1253. | going to be a Cache pointer. It will be for fixed-disks (that have
  1254. | Partition Tables), but for other disks the "NULL" signals "No Partition
  1255. | Table".
  1256. |
  1257. | For fixed-disks, the NULL is overwritten later (in "ProcessPartitions()")
  1258. | by a pointer to malloced storage containing an instance of CACHEHEAD
  1259. | structure that carries the hrPartition Table for that fixed-disk).
  1260. */
  1261. if ((dv_row = AddHrDeviceRow(type_arc, // DeviceType OID Last-Arc
  1262. descr, // Used as description
  1263. NULL, // Hidden Ctx (none)
  1264. CA_CACHE // Hidden Ctx type
  1265. )) == NULL ) {
  1266. /* Something blew */
  1267. return ( NULL );
  1268. }
  1269. /* Re-Set hrDeviceStatus */
  1270. dv_row->attrib_list[HRDV_STATUS].attrib_type = CA_NUMBER;
  1271. dv_row->attrib_list[HRDV_STATUS].u.unumber_value = status;
  1272. /*
  1273. |===============================
  1274. | Create hrDiskStorage Row entry
  1275. |
  1276. | Note: The index is not recorded IN the row, but the entry
  1277. | is "indexed": by the hrDevice row index. This happens
  1278. | in the AddTableRow() call below.
  1279. */
  1280. if ((ds_row = CreateTableRow( HRDS_ATTRIB_COUNT ) ) == NULL) {
  1281. return ( NULL ); // Out of memory
  1282. }
  1283. /*
  1284. | Set the attribute values for this row
  1285. */
  1286. /* =========== hrDiskStorageAccess ==========*/
  1287. ds_row->attrib_list[HRDS_ACCESS].attrib_type = CA_NUMBER;
  1288. ds_row->attrib_list[HRDS_ACCESS].u.unumber_value = access;
  1289. /* =========== hrDiskStorageAccess ==========*/
  1290. ds_row->attrib_list[HRDS_MEDIA].attrib_type = CA_NUMBER;
  1291. ds_row->attrib_list[HRDS_MEDIA].u.unumber_value = media;
  1292. /* =========== hrDiskStorageRemovable ==========*/
  1293. ds_row->attrib_list[HRDS_REMOVABLE].attrib_type = CA_NUMBER;
  1294. ds_row->attrib_list[HRDS_REMOVABLE].u.unumber_value = removable;
  1295. /* =========== hrDiskStorageCapacity ==========*/
  1296. ds_row->attrib_list[HRDS_CAPACITY].attrib_type = CA_NUMBER;
  1297. ds_row->attrib_list[HRDS_CAPACITY].u.unumber_value = capacityKB;
  1298. /*
  1299. | Now insert the filled-in CACHEROW structure into the
  1300. | cache-list for the hrDiskStorage Table..
  1301. |
  1302. | Use the same index that was used to specify the row inserted
  1303. | into the hrDevice table.
  1304. */
  1305. if (AddTableRow(dv_row->attrib_list[HRDV_INDEX].u.unumber_value, /* Index */
  1306. ds_row, /* Row */
  1307. &hrDiskStorage_cache /* Cache */
  1308. ) == FALSE) {
  1309. DestroyTableRow(ds_row);
  1310. return ( NULL ); /* Internal Logic Error! */
  1311. }
  1312. /* Processing complete */
  1313. return ( dv_row );
  1314. }
  1315. /* ProcessPartitions - Process Partition Information into HrDevice Row */
  1316. /* ProcessPartitions - Process Partition Information into HrDevice Row */
  1317. /* ProcessPartitions - Process Partition Information into HrDevice Row */
  1318. static BOOL
  1319. ProcessPartitions(
  1320. HANDLE hdrv, /* Fixed-Disk containing partitions */
  1321. CACHEROW *dv_row, /* Row in hrDevice table for disk */
  1322. CHAR *pntdev /* NT Device name for physical disk */
  1323. )
  1324. /*
  1325. | EXPLICIT INPUTS:
  1326. |
  1327. | "hdrv" - handle open to the fixed disk whose partitions are to be
  1328. | enumerated.
  1329. |
  1330. | "dv_row" - the HrDevice row into which the new hrPartition Table
  1331. | is to go.
  1332. |
  1333. | "pntdev" - NT Device Name for the physical disk we're dealing with.
  1334. | We need this to infer the logical device name for any
  1335. | active partition.
  1336. |
  1337. | IMPLICIT INPUTS:
  1338. |
  1339. | "HrFSTable_cache" - this gets scanned to allow "hrPartitionFSIndex"
  1340. | to be filled in.
  1341. |
  1342. | OUTPUTS:
  1343. |
  1344. | On Success:
  1345. | Function returns TRUE indicating that the Partition Information
  1346. | for the given disk has been used to populate an hrPartition Table
  1347. | instance.
  1348. |
  1349. | On any Failure:
  1350. | Function returns NULL (indicating "not enough storage" or other
  1351. | failure.).
  1352. |
  1353. | THE BIG PICTURE:
  1354. |
  1355. | This is the function that instantiates hrPartition tables.
  1356. |
  1357. | OTHER THINGS TO KNOW:
  1358. |
  1359. | Documentation at the top of the hrPartition Table file "HRPARTIT.C"
  1360. | might be of interest.
  1361. |
  1362. | BUG: As of build 1515, (and indeed in earlier versions of NT) the
  1363. | "PartitionNumber" returned in response to DeviceIoControl opcode
  1364. | "IOCTL_DISK_GET_DRIVE_LAYOUT" comes back as garbage. Whatever
  1365. | comes back is reported as the value of "hrPartitionID" (garbage or
  1366. | not). However when trying to fetch the Volume Label, as part of a
  1367. | workaround attempt, we use the index generated in the code below
  1368. | in an attempt to approximate the proper Partition Number.
  1369. */
  1370. {
  1371. #define DL_SIZE 1024
  1372. CHAR dl_buf[DL_SIZE]; /* Drive-Layout info comes back here */
  1373. UINT i; /* Handy-Dandy loop index */
  1374. ULONG table_index=0; /* hrPartition Table row index counter */
  1375. DWORD bytes_out; /* Exactly how big "dl_buf" got filled */
  1376. DRIVE_LAYOUT_INFORMATION
  1377. *dl; /* Drive-layout pointer */
  1378. /*
  1379. | See if we can grab the Drive's partition layout info.
  1380. */
  1381. if (DeviceIoControl(hdrv, // device handle
  1382. IOCTL_DISK_GET_DRIVE_LAYOUT, // IoControlCode (op-code)
  1383. NULL, // "input buffer"
  1384. 0, // "input buffer size"
  1385. dl_buf, // "output buffer"
  1386. DL_SIZE, // "output buffer size"
  1387. &bytes_out, // bytes written to part_info
  1388. NULL // no Overlapped I/o
  1389. )) {
  1390. CACHEHEAD *ch;
  1391. /*
  1392. | OK, there's presumed to be at least one partition: instantiate the
  1393. | new partition table.
  1394. |
  1395. | Do this by creating its cache list-head structure.
  1396. */
  1397. dv_row->attrib_list[HIDDEN_CTX].attrib_type = CA_CACHE;
  1398. if ((dv_row->attrib_list[HIDDEN_CTX].u.cache
  1399. = ch = (CACHEHEAD *) malloc( sizeof(CACHEHEAD) )) == NULL) {
  1400. return ( FALSE );
  1401. }
  1402. /*
  1403. | Now initialize the contents properly.
  1404. | (This should match what macro CACHEHEAD_INSTANCE does to a static
  1405. | instance).
  1406. */
  1407. ch->list_count = 0;
  1408. ch->list = NULL;
  1409. #if defined(CACHE_DUMP)
  1410. ch->print_row = debug_print_hrpartition;
  1411. #else
  1412. ch->print_row = NULL;
  1413. #endif
  1414. /* Grab a dereferencable pointer to the Drive Layout info */
  1415. dl = (DRIVE_LAYOUT_INFORMATION *) dl_buf;
  1416. /* For every Partition "slot" returned . . . */
  1417. for (i = 0; i < dl->PartitionCount; i += 1) {
  1418. PARTITION_INFORMATION
  1419. *p; /* Partition info thats going to go . . */
  1420. CACHEROW *row; /* . . .into this row in HrPartition */
  1421. CACHEROW *fs_row; /* Row ptr in HrFSEntry table */
  1422. ULONG last_arc; /* Last OID arc to use as FS-Type */
  1423. /* Grab a simple pointer to the next PARTITION_INFO to consider */
  1424. p = &(dl->PartitionEntry[i]);
  1425. /*
  1426. | Note: It may be that not all of the PartitionEntry elements are
  1427. | "live".
  1428. */
  1429. if (p->PartitionType == PARTITION_ENTRY_UNUSED) {
  1430. continue;
  1431. }
  1432. /*
  1433. |===============================
  1434. | Create hrPartition Row entry
  1435. |
  1436. | Note: This table is also "indexed" by the hrDevice row index
  1437. */
  1438. if ((row = CreateTableRow( HRPT_ATTRIB_COUNT ) ) == NULL) {
  1439. return ( FALSE ); // Out of memory
  1440. }
  1441. /* =========== hrPartitionIndex ==========*/
  1442. row->attrib_list[HRPT_INDEX].attrib_type = CA_NUMBER;
  1443. row->attrib_list[HRPT_INDEX].u.unumber_value = (table_index += 1);
  1444. /* =========== hrPartitionLabel ==========*/
  1445. row->attrib_list[HRPT_LABEL].attrib_type = CA_STRING;
  1446. /*
  1447. | If there is an MS-DOS logical device letter assigned to this
  1448. | partition. . .
  1449. */
  1450. if ( p->RecognizedPartition ) {
  1451. /*
  1452. | Go get the label, copy it to malloc'ed storage and return it.
  1453. |
  1454. | NOTE: Due to what seems like a bug, we're passing in "i+1" here
  1455. | rather than "p->PartitionNumber" (which seems to come
  1456. | back as garbage). Clearly "i" is not a proper substitute
  1457. | in the long run. See "OTHER THINGS TO KNOW" in the docs
  1458. | above for this function.
  1459. */
  1460. row->attrib_list[HRPT_LABEL].u.string_value =
  1461. FindPartitionLabel(pntdev, (i+1));
  1462. }
  1463. else {
  1464. /* No label if no MS-DOS device */
  1465. row->attrib_list[HRPT_LABEL].u.string_value = NULL;
  1466. }
  1467. /* =========== hrPartitionID ==========
  1468. |
  1469. | In build 1515, this number is returned as garbage. See
  1470. | "OTHER THINGS TO KNOW" above.
  1471. */
  1472. row->attrib_list[HRPT_ID].attrib_type = CA_NUMBER;
  1473. row->attrib_list[HRPT_ID].u.unumber_value = p->PartitionNumber;
  1474. /* =========== hrPartitionSize ==========*/
  1475. row->attrib_list[HRPT_SIZE].attrib_type = CA_NUMBER;
  1476. row->attrib_list[HRPT_SIZE].u.unumber_value =
  1477. p->PartitionLength.LowPart / 1024;
  1478. /* =========== hrPartitionFSIndex ==========*/
  1479. row->attrib_list[HRPT_FSINDEX].attrib_type = CA_NUMBER;
  1480. /* Assume no file system mounted (that we can find) */
  1481. row->attrib_list[HRPT_FSINDEX].u.unumber_value = 0;
  1482. /* Find the first Row (if any) in the hrFSTable */
  1483. if ((fs_row = FindNextTableRow(0, &hrFSTable_cache)) == NULL) {
  1484. /* No file systems listed at all.. we're done */
  1485. DestroyTableRow(row);
  1486. continue;
  1487. }
  1488. /*
  1489. | Convert the Partition-Type into the "last-arc" value we use
  1490. | to indicate what kind of file-system it is.
  1491. */
  1492. last_arc = PartitionTypeToLastArc( p->PartitionType );
  1493. do { /* Walk the hrFSEntry table */
  1494. /*
  1495. | If we found that the hrFSTable entry "fs_row" specifies a
  1496. | file-system TYPE (by arc number) that matches what the current
  1497. | partition's type number translates to ... we're done.
  1498. */
  1499. if (fs_row->attrib_list[HRFS_TYPE].u.unumber_value == last_arc) {
  1500. row->attrib_list[HRPT_FSINDEX].u.unumber_value = fs_row->index;
  1501. break;
  1502. }
  1503. /* Step to the next row */
  1504. fs_row = GetNextTableRow(fs_row);
  1505. }
  1506. while (fs_row != NULL);
  1507. /*
  1508. |===============================
  1509. |Now add the row to the table
  1510. */
  1511. if (AddTableRow(row->attrib_list[HRPT_INDEX].u.unumber_value,/* Index */
  1512. row, /* Row */
  1513. ch /* Cache */
  1514. ) == FALSE) {
  1515. DestroyTableRow(row);
  1516. return ( FALSE ); /* Internal Logic Error! */
  1517. }
  1518. } /* For each partition */
  1519. } /* If DeviceIoControl succeeded */
  1520. /* Partition Table complete */
  1521. return ( TRUE ) ;
  1522. }
  1523. /* FindPartitionLabel - Find MS-DOS Device Label for a Fixed-Disk Partition */
  1524. /* FindPartitionLabel - Find MS-DOS Device Label for a Fixed-Disk Partition */
  1525. /* FindPartitionLabel - Find MS-DOS Device Label for a Fixed-Disk Partition */
  1526. static PCHAR
  1527. FindPartitionLabel(
  1528. CHAR *pntdev, /* NT Device name for physical disk */
  1529. UINT part_id /* Partition Number (1-origined) */
  1530. )
  1531. /*
  1532. | EXPLICIT INPUTS:
  1533. |
  1534. | "pntdev" - the NT Device Name (e.g. "\Device\Harddisk0\Partition0"
  1535. | for the PHYSICAL device we're working on).
  1536. |
  1537. | "part_id" - One-origined Partition number for which we hope to find
  1538. | an MS-DOS Volume Label.
  1539. |
  1540. | IMPLICIT INPUTS:
  1541. |
  1542. | None.
  1543. |
  1544. | OUTPUTS:
  1545. |
  1546. | On Success:
  1547. | Function returns a pointer to malloc'ed storage containing the
  1548. | MS-DOS Device Volume label (as returned by "GetVolumeInformation()").
  1549. |
  1550. | On any Failure:
  1551. | Function returns NULL (indicating "some kind of failure").
  1552. |
  1553. | THE BIG PICTURE:
  1554. |
  1555. | This "helper" function attempts to map an NT Device Name and a
  1556. | one-origined Partition Number into a Volume Label for return as
  1557. | the value of "hrPartitionLabel".
  1558. |
  1559. | OTHER THINGS TO KNOW:
  1560. |
  1561. | The algorithm is based on studying the output from "QueryDosDevices()"
  1562. | and blithely assuming that we can "back-map" the string
  1563. | "\Device\HarddiskX\PartitionY" for any Partition "Y" to the associated
  1564. | MS-DOS Device. There is precious little documentation that sez we can,
  1565. | but we try.
  1566. |
  1567. | Here's the approach:
  1568. |
  1569. | * Using the NT Device Name for the "PHYSICALDRIVEn", we scrape the
  1570. | "\Partition0" off the end of the name and replace it with "\PartitionY"
  1571. | where "Y" is the Partition number passed as input to this function.
  1572. | This is the "Generated Partition Name".
  1573. |
  1574. | ("PHYSICALDRIVE" NT Device Names all seem to have "\Partition0" as
  1575. | the terminating part of their name, and since the Win32 docs say that
  1576. | Partition Numbers are "1-origined", this seems like a safe approach.)
  1577. |
  1578. | * We generate a list of all the MS-DOS device names (using QueryDosDevices).
  1579. |
  1580. | * We take each MS-DOS Device name and ask for it's current underlying
  1581. | NT Device name mapping.
  1582. |
  1583. | + If the first name mapping for any MS-DOS Device matches our
  1584. | "Generated Partition Name", then the MS-DOS Device name is submitted
  1585. | to "GetVolumeInformation()" and the Volume Label returned is used as
  1586. | the "Partition Label".
  1587. */
  1588. {
  1589. #define BIG_BUFF 1024
  1590. CHAR gen_part_name[MAX_PATH+32]; /* "pntdev" is at most MAX_PATH+2 */
  1591. CHAR *partition; /* Where "\Partition0" starts */
  1592. CHAR MSDOS_devices[BIG_BUFF]; /* List of MS-DOS device names */
  1593. CHAR NT_device[BIG_BUFF]; /* Mapping of NT device names */
  1594. CHAR *devname; /* Index for MSDOS_devices */
  1595. /* Copy the NT Device Name for the Physical Drive */
  1596. strcpy(gen_part_name, pntdev);
  1597. /* Obtain a pointer to the beginning of "\Partition0" in this string */
  1598. if ((partition = strstr(gen_part_name, "\\Partition")) != NULL) {
  1599. /*
  1600. | Replace "\Partition0" with "\PartitionY" where "Y" is the supplied
  1601. | partition number: We've got the "Generated Partition Name".
  1602. */
  1603. sprintf(partition, "\\Partition%d", part_id);
  1604. /*
  1605. | Now ask for a list of MS-DOS Device Names
  1606. */
  1607. if ( QueryDosDevice(NULL, MSDOS_devices, BIG_BUFF) != 0) {
  1608. /*
  1609. | Swing down the list of MS-DOS device names and get the NT Device
  1610. | name mappings.
  1611. */
  1612. for (devname = MSDOS_devices;
  1613. *devname != '\0';
  1614. devname += (strlen(devname)+1)) {
  1615. /* Obtain the mappings for device "devname" */
  1616. if (QueryDosDevice(devname, NT_device, BIG_BUFF) == 0)
  1617. continue;
  1618. /* If the first mapping matches the Generated Partition Name */
  1619. if (strcmp(gen_part_name, NT_device) == 0) {
  1620. #define VOL_LABEL_SIZE 128
  1621. CHAR MSDOS_root[64+1]; /* Root Path Name */
  1622. CHAR v_label[VOL_LABEL_SIZE]; /* Volume Label */
  1623. CHAR *ret_label; /* --> Malloced storage */
  1624. DWORD comp_len; /* Filename length */
  1625. DWORD flags;
  1626. /*
  1627. | We're obliged to add a root-directory "\" to the MS-DOS
  1628. | device name.
  1629. */
  1630. MSDOS_root[64] = 0; // ensures null terminated string
  1631. _snprintf(MSDOS_root, 64, "%s\\", devname);
  1632. /* Fetch the Volume Information for the MS-DOS Device */
  1633. if (GetVolumeInformation(
  1634. MSDOS_root, // MS-DOS root name
  1635. v_label, // Vol. Label buf
  1636. VOL_LABEL_SIZE, // vol. label size
  1637. NULL, // Serial Number
  1638. &comp_len, // FileName length
  1639. &flags, // Flags
  1640. NULL, // File System name
  1641. 0 // Name buff. len
  1642. ) != 0) {
  1643. /*
  1644. | Allocate storage to hold a returnable copy
  1645. */
  1646. if ( (ret_label = (CHAR *) malloc(strlen(v_label) + 1))
  1647. != NULL) {
  1648. /* Copy the label to malloced storage */
  1649. strcpy(ret_label, v_label);
  1650. return (ret_label);
  1651. }
  1652. else {
  1653. /* Out of storage */
  1654. return (NULL);
  1655. }
  1656. }
  1657. else {
  1658. /* "GetVolumeInformation" failed on MSDOS name */
  1659. return (NULL);
  1660. }
  1661. }
  1662. }
  1663. }
  1664. }
  1665. return (NULL); /* Other Failure */
  1666. }
  1667. #if defined(CACHE_DUMP)
  1668. /* debug_print_hrdiskstorage - Prints a Row from HrDiskStorage sub-table */
  1669. /* debug_print_hrdiskstorage - Prints a Row from HrDiskStorage sub-table */
  1670. /* debug_print_hrdiskstorage - Prints a Row from HrDiskStorage sub-table */
  1671. static void
  1672. debug_print_hrdiskstorage(
  1673. CACHEROW *row /* Row in hrDiskStorage table */
  1674. )
  1675. /*
  1676. | EXPLICIT INPUTS:
  1677. |
  1678. | "row" - points to the row to be dumped, if NULL, the function
  1679. | merely prints a suitable title.
  1680. |
  1681. | IMPLICIT INPUTS:
  1682. |
  1683. | - Symbols used to reference the attributes in the row entry.
  1684. | - File handle defined by OFILE, presumed to be open.
  1685. |
  1686. | OUTPUTS:
  1687. |
  1688. | On Success:
  1689. | Function prints a dump of the row in ASCII for debugging purposes
  1690. | on file handle OFILE.
  1691. |
  1692. | THE BIG PICTURE:
  1693. |
  1694. | Debugging only.
  1695. |
  1696. | OTHER THINGS TO KNOW:
  1697. */
  1698. {
  1699. if (row == NULL) {
  1700. fprintf(OFILE, "=========================\n");
  1701. fprintf(OFILE, "hrDiskStorage Table Cache\n");
  1702. fprintf(OFILE, "=========================\n");
  1703. return;
  1704. }
  1705. fprintf(OFILE, "hrDiskStorageAccess. . . . %d ",
  1706. row->attrib_list[HRDS_ACCESS].u.unumber_value);
  1707. switch (row->attrib_list[HRDS_ACCESS].u.unumber_value) {
  1708. case 1: fprintf(OFILE, "(readWrite)\n"); break;
  1709. case 2: fprintf(OFILE, "(readOnly)\n"); break;
  1710. default:fprintf(OFILE, "(???)\n"); break;
  1711. }
  1712. fprintf(OFILE, "hrDiskStorageMedia . . . . %d ",
  1713. row->attrib_list[HRDS_MEDIA].u.unumber_value);
  1714. switch (row->attrib_list[HRDS_MEDIA].u.unumber_value) {
  1715. case 1: fprintf(OFILE, "(Other)\n"); break;
  1716. case 2: fprintf(OFILE, "(Unknown)\n"); break;
  1717. case 3: fprintf(OFILE, "(hardDisk)\n"); break;
  1718. case 4: fprintf(OFILE, "(floppyDisk)\n"); break;
  1719. case 5: fprintf(OFILE, "(opticalDiskROM)\n"); break;
  1720. case 6: fprintf(OFILE, "(opticalDiskWORM)\n"); break;
  1721. case 7: fprintf(OFILE, "(opticalDiskRW)\n"); break;
  1722. case 8: fprintf(OFILE, "(ramDisk)\n"); break;
  1723. default:fprintf(OFILE, "(???)\n"); break;
  1724. }
  1725. fprintf(OFILE, "hrDiskStorageRemovable . . %d ",
  1726. row->attrib_list[HRDS_REMOVABLE].u.unumber_value);
  1727. switch (row->attrib_list[HRDS_REMOVABLE].u.unumber_value) {
  1728. case 0: fprintf(OFILE, "(FALSE)\n"); break;
  1729. case 1: fprintf(OFILE, "(TRUE)\n"); break;
  1730. default:
  1731. fprintf(OFILE, "(???)\n"); break;
  1732. }
  1733. fprintf(OFILE, "hrDiskStorageCapacity. . . %d (KBytes)\n",
  1734. row->attrib_list[HRDS_CAPACITY].u.unumber_value);
  1735. }
  1736. /* debug_print_hrpartition - Prints a Row from HrPartition sub-table */
  1737. /* debug_print_hrpartition - Prints a Row from HrPartition sub-table */
  1738. /* debug_print_hrpartition - Prints a Row from HrPartition sub-table */
  1739. static void
  1740. debug_print_hrpartition(
  1741. CACHEROW *row /* Row in hrPartition table */
  1742. )
  1743. /*
  1744. | EXPLICIT INPUTS:
  1745. |
  1746. | "row" - points to the row to be dumped, if NULL, the function
  1747. | merely prints a suitable title.
  1748. |
  1749. | IMPLICIT INPUTS:
  1750. |
  1751. | - Symbols used to reference the attributes in the row entry.
  1752. | - File handle defined by OFILE, presumed to be open.
  1753. |
  1754. | OUTPUTS:
  1755. |
  1756. | On Success:
  1757. | Function prints a dump of the row in ASCII for debugging purposes
  1758. | on file handle OFILE.
  1759. |
  1760. | THE BIG PICTURE:
  1761. |
  1762. | Debugging only.
  1763. |
  1764. | OTHER THINGS TO KNOW:
  1765. */
  1766. {
  1767. if (row == NULL) {
  1768. fprintf(OFILE, " =======================\n");
  1769. fprintf(OFILE, " hrPartition Table Cache\n");
  1770. fprintf(OFILE, " =======================\n");
  1771. return;
  1772. }
  1773. fprintf(OFILE, " hrPartitionIndex . . . . . %d\n",
  1774. row->attrib_list[HRPT_INDEX].u.unumber_value);
  1775. fprintf(OFILE, " hrPartitionLabel . . . . . \"%s\"\n",
  1776. row->attrib_list[HRPT_LABEL].u.string_value);
  1777. fprintf(OFILE, " hrPartitionID. . . . . . . 0x%x\n",
  1778. row->attrib_list[HRPT_ID].u.unumber_value);
  1779. fprintf(OFILE, " hrPartitionSize. . . . . . %d\n",
  1780. row->attrib_list[HRPT_SIZE].u.unumber_value);
  1781. fprintf(OFILE, " hrPartitionFSIndex . . . . %d\n",
  1782. row->attrib_list[HRPT_FSINDEX].u.unumber_value);
  1783. }
  1784. #endif