Source code of Windows XP (NT5)
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.

2049 lines
70 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. /*
  657. | Do Floppies and CD-ROM drives (non-fixed disks)
  658. */
  659. if (Gen_nonFixed_disks( type_arc ) == FALSE) {
  660. return ( FALSE );
  661. }
  662. /*
  663. | Do Fixed drives
  664. */
  665. if (Gen_Fixed_disks( type_arc ) == FALSE) {
  666. return ( FALSE );
  667. }
  668. /* Success */
  669. return ( TRUE );
  670. }
  671. /* Gen_nonFixed_disks - Scan for Floppies and CD-ROMS */
  672. /* Gen_nonFixed_disks - Scan for Floppies and CD-ROMS */
  673. /* Gen_nonFixed_disks - Scan for Floppies and CD-ROMS */
  674. static BOOL
  675. Gen_nonFixed_disks (
  676. ULONG type_arc
  677. )
  678. /*
  679. | EXPLICIT INPUTS:
  680. |
  681. | "type_arc" is the number "n" to be used as the last arc in the
  682. | device-type OID:
  683. |
  684. | 1.3.6.1.2.1.25.3.1.n
  685. | | | |
  686. | | | * Identifying arc for type
  687. | | *-hrDeviceTypes (OIDs specifying device types)
  688. | *-hrDevice
  689. |
  690. | for devices created by this cache-population routine.
  691. |
  692. | IMPLICIT INPUTS:
  693. |
  694. | The module-local head of the cache for the HrDiskStorage table,
  695. | "HrDiskStorage_cache".
  696. |
  697. | OUTPUTS:
  698. |
  699. | On Success:
  700. | Function returns TRUE indicating that the both cachees have been fully
  701. | populated with all non-Fixed disks.
  702. |
  703. | On any Failure:
  704. | Function returns FALSE (indicating "not enough storage").
  705. |
  706. | THE BIG PICTURE:
  707. |
  708. | Part I of hrDiskStorage cache population.
  709. |
  710. | OTHER THINGS TO KNOW:
  711. |
  712. | We scan using the list of Logical Disk drive strings from
  713. | GetLogicalDriveStrings() formed up into UNC form, (e.g. "\\.\A:"
  714. | for "A:\" returned from GetLogicalDriveStrings()).
  715. */
  716. {
  717. CHAR temp[8]; /* Temporary buffer for first call */
  718. LPSTR pDrvStrings; /* --> allocated storage for drive strings */
  719. LPSTR pOriginal_DrvStrings; /* (Needed for final deallocation */
  720. DWORD DS_request_len; /* Storage actually needed */
  721. DWORD DS_current_len; /* Storage used on 2nd call */
  722. #define PHYS_SIZE 32
  723. CHAR phys_name[PHYS_SIZE]; /* Buffer where a string like "\\.C:" (for */
  724. /* example) is built for drive access. */
  725. /*
  726. | We're going to call GetLogicalDriveStrings() twice, once to get the proper
  727. | buffer size, and the second time to actually get the drive strings.
  728. |
  729. | The Bogus call.
  730. */
  731. if ((DS_request_len = GetLogicalDriveStrings(2, temp)) == 0) {
  732. /* Request failed altogether, can't initialize */
  733. return ( FALSE );
  734. }
  735. /*
  736. | Grab enough storage for the drive strings plus one null byte at the end
  737. */
  738. if ( (pOriginal_DrvStrings = pDrvStrings = malloc( (DS_request_len + 2) ) )
  739. == NULL) {
  740. /* Storage Request failed altogether, can't initialize */
  741. return ( FALSE );
  742. }
  743. /* Go for all of the strings
  744. |
  745. | The Real Call.
  746. */
  747. if ((DS_current_len = GetLogicalDriveStrings(DS_request_len, pDrvStrings))
  748. == 0) {
  749. /* Request failed altogether, can't initialize */
  750. free( pOriginal_DrvStrings );
  751. return ( FALSE );
  752. }
  753. /*
  754. |==============================================================================
  755. | For each logical drive . . .
  756. */
  757. while ( strlen(pDrvStrings) > 0 ) {
  758. UINT drivetype; /* Type of the drive from "GetDriveType()" */
  759. /*
  760. | Get the drive-type so we can decide whether it should participate in
  761. | this population effort. We do only CD-ROMS and REMOVABLES.
  762. */
  763. drivetype = GetDriveType(pDrvStrings);
  764. /* Skip the stuff we don't want to look at */
  765. if ( drivetype != DRIVE_REMOVABLE && drivetype != DRIVE_CDROM ) {
  766. /* Step to next string, if any */
  767. pDrvStrings += strlen(pDrvStrings) + 1;
  768. continue;
  769. }
  770. /* If we have room in the buffer to build the handle-name string */
  771. if ((strlen(pDrvStrings) + strlen("\\\\.\\")) < PHYS_SIZE) {
  772. #define DESCR_BSZ 512
  773. CHAR d_buf[DESCR_BSZ]; /* Dsecription bld buff */
  774. HANDLE hdrv; /* Handle to device */
  775. DWORD bytes_out; /* Bytes retnd into geo_info */
  776. DISK_GEOMETRY geo_info; /* Geometry Info from drive */
  777. char *mt; /* Media Type */
  778. ULONG access; /* hrDiskStorageAccess = readWrite(1) */
  779. ULONG media; /* hrDiskStorageMedia = floppyDisk(4) */
  780. ULONG removable; /* hrDiskStorageRemovable = TRUE */
  781. ULONG capacityKB; /* hrDiskStorageCapacity, (kilobytes) */
  782. ULONG status; /* hrDeviceStatus = unknown(1) */
  783. CHAR *descr; /* hrDeviceDescr string */
  784. /* 012345
  785. | Build it for device A: "\\.\A:" */
  786. sprintf(phys_name, "\\\\.\\%2.2s", pDrvStrings);
  787. /*
  788. | Set SNMP variables accordingly
  789. */
  790. if (drivetype != DRIVE_CDROM) { /* Floppy */
  791. access = 1; /* hrDiskStorageAccess = readWrite(1) */
  792. media = 4; /* hrDiskStorageMedia = floppyDisk(4) */
  793. removable = TRUE; /* hrDiskStorageRemovable = TRUE */
  794. capacityKB = 0; /* hrDiskStorageCapacity (unknown) */
  795. status = 1; /* hrDeviceStatus = unknown(1) */
  796. descr = pDrvStrings; /* hrDeviceDescr, initial (e.g."A:\") */
  797. }
  798. else { /* CD-ROM */
  799. /*
  800. | We can't get much of anything about CD-ROMs except the fact
  801. | that there is one. Capacity cannot be presumed as DVD is
  802. | now available and some drives read both CD-ROMs and DVD.
  803. */
  804. access = 2; /* hrDiskStorageAccess = readOnly(2) */
  805. media = 5; /* hrDiskStorageMedia = opticalDiskROM(5)*/
  806. removable = TRUE; /* hrDiskStorageRemovable = TRUE */
  807. capacityKB = 0; /* hrDiskStorageCapacity (unknown) */
  808. status = 1; /* hrDeviceStatus = unknown(1) */
  809. descr = pDrvStrings; /* hrDeviceDescr, initial (e.g."D:\") */
  810. }
  811. /*
  812. | Suppress any attempt by the system to make the user put a volume in a
  813. | removable drive ("CreateFile" will just fail).
  814. */
  815. SetErrorMode(SEM_FAILCRITICALERRORS);
  816. /* Attempt to get a handle using this physical name string */
  817. hdrv = CreateFile(phys_name, // Device
  818. GENERIC_READ, // device query
  819. // Share Mode
  820. FILE_SHARE_READ |
  821. FILE_SHARE_WRITE,
  822. NULL, // Security
  823. OPEN_EXISTING, // CreationDistribution
  824. FILE_ATTRIBUTE_NORMAL, // FlagsandAttributes
  825. NULL // Template file
  826. );
  827. /* If we successfully opened the device . . . */
  828. if (hdrv != INVALID_HANDLE_VALUE) {
  829. /*
  830. | Device is Open.
  831. |
  832. | If it is NOT a CD-ROM, (ie, a floppy) its worth trying to get
  833. | DRIVE GEOMETRY (which will come back if there is a floppy in
  834. | the drive).
  835. */
  836. if (drivetype != DRIVE_CDROM) { /* Floppy */
  837. /* ==========================================================
  838. | IOCTL_DISK_GET_DRIVE_GEOMETRY
  839. |
  840. | If we can get this, we get a better description and an
  841. | accurate capacity value.
  842. */
  843. if (DeviceIoControl(hdrv, // device handle
  844. // IoControlCode (op-code)
  845. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  846. NULL, // "input buffer"
  847. 0, // "input buffer size"
  848. &geo_info, // "output buffer"
  849. // "output buffer size"
  850. sizeof(DISK_GEOMETRY),
  851. &bytes_out, // bytes written to geo_info
  852. NULL // no Overlapped I/o
  853. )) {
  854. /*
  855. | Compute capacity
  856. */
  857. capacityKB = (ULONG)
  858. ((geo_info.Cylinders.QuadPart * // 64 bits
  859. (geo_info.TracksPerCylinder * // 32 bits
  860. geo_info.SectorsPerTrack *
  861. geo_info.BytesPerSector)
  862. ) / 1024);
  863. /* hrDeviceStatus = running(2) */
  864. status = 2;
  865. switch ( geo_info.MediaType ) {
  866. case F5_1Pt2_512: mt = "5.25, 1.2MB, 512 bytes/sector"; break;
  867. case F3_1Pt44_512: mt = "3.5, 1.44MB, 512 bytes/sector"; break;
  868. case F3_2Pt88_512: mt = "3.5, 2.88MB, 512 bytes/sector"; break;
  869. case F3_20Pt8_512: mt = "3.5, 20.8MB, 512 bytes/sector"; break;
  870. case F3_720_512: mt = "3.5, 720KB, 512 bytes/sector"; break;
  871. case F5_360_512: mt = "5.25, 360KB, 512 bytes/sector"; break;
  872. case F5_320_512: mt = "5.25, 320KB, 512 bytes/sector"; break;
  873. case F5_320_1024: mt = "5.25, 320KB, 1024 bytes/sector"; break;
  874. case F5_180_512: mt = "5.25, 180KB, 512 bytes/sector"; break;
  875. case F5_160_512: mt = "5.25, 160KB, 512 bytes/sector"; break;
  876. case F3_120M_512: mt = "3.5, 120M Floppy"; break;
  877. case F3_640_512: mt = "3.5 , 640KB, 512 bytes/sector"; break;
  878. case F5_640_512: mt = "5.25, 640KB, 512 bytes/sector"; break;
  879. case F5_720_512: mt = "5.25, 720KB, 512 bytes/sector"; break;
  880. case F3_1Pt2_512: mt = "3.5 , 1.2Mb, 512 bytes/sector"; break;
  881. case F3_1Pt23_1024: mt = "3.5 , 1.23Mb, 1024 bytes/sector"; break;
  882. case F5_1Pt23_1024: mt = "5.25, 1.23MB, 1024 bytes/sector"; break;
  883. case F3_128Mb_512: mt = "3.5 MO 128Mb 512 bytes/sector"; break;
  884. case F3_230Mb_512: mt = "3.5 MO 230Mb 512 bytes/sector"; break;
  885. case F8_256_128: mt = "8in, 256KB, 128 bytes/sector"; break;
  886. default:
  887. case RemovableMedia:
  888. case FixedMedia:
  889. case Unknown: mt = "Format is unknown"; break;
  890. }
  891. /* Format a better description if it'll all fit */
  892. if ((strlen(pDrvStrings) + strlen(mt) + 1) < DESCR_BSZ ) {
  893. sprintf(d_buf, "%s%s", pDrvStrings, mt);
  894. descr = d_buf;
  895. }
  896. } /* If (we managed to get geometry information) */
  897. }
  898. CloseHandle(hdrv);
  899. } /* if (we managed to "CreateFile" the device successfully) */
  900. /*
  901. | Create a row in HrDevice Table and a corresponding row in
  902. | hrDiskStorage sub-table.
  903. */
  904. if ( Process_DS_Row (
  905. type_arc, /* hrDeviceType last arc */
  906. access, /* hrDiskStorageAccess */
  907. media, /* hrDiskStorageMedia */
  908. removable, /* hrDiskStorageRemovable */
  909. capacityKB,/* hrDiskStorageCapacity */
  910. status, /* hrDeviceStatus */
  911. descr /* hrDeviceDescr */
  912. ) == NULL) {
  913. /* Something blew */
  914. free( pOriginal_DrvStrings );
  915. return ( FALSE );
  916. }
  917. SetErrorMode(0); /* Turn error suppression mode off */
  918. } /* if (we managed to build a device name) */
  919. /* Step to next string, if any */
  920. pDrvStrings += strlen(pDrvStrings) + 1;
  921. }
  922. free( pOriginal_DrvStrings );
  923. /* Successful scan */
  924. return ( TRUE );
  925. }
  926. /* Gen_Fixed_disks - Scan for Fixed Disks */
  927. /* Gen_Fixed_disks - Scan for Fixed Disks */
  928. /* Gen_Fixed_disks - Scan for Fixed Disks */
  929. static BOOL
  930. Gen_Fixed_disks (
  931. ULONG type_arc
  932. )
  933. /*
  934. | EXPLICIT INPUTS:
  935. |
  936. | "type_arc" is the number "n" to be used as the last arc in the
  937. | device-type OID:
  938. |
  939. | 1.3.6.1.2.1.25.3.1.n
  940. | | | |
  941. | | | * Identifying arc for type
  942. | | *-hrDeviceTypes (OIDs specifying device types)
  943. | *-hrDevice
  944. |
  945. | for devices created by this cache-population routine.
  946. |
  947. | IMPLICIT INPUTS:
  948. |
  949. | The module-local head of the cache for the HrDiskStorage table,
  950. | "HrDiskStorage_cache".
  951. |
  952. | OUTPUTS:
  953. |
  954. | On Success:
  955. | Function returns TRUE indicating that the both cachees have been fully
  956. | populated with all non-Fixed disks. If the device from which the
  957. | system was booted is encountered, it's hrDevice index is set into
  958. | "InitLoadDev_index" (defined in "HRDEVENT.C").
  959. |
  960. | On any Failure:
  961. | Function returns FALSE (indicating "not enough storage").
  962. |
  963. | THE BIG PICTURE:
  964. |
  965. | Part II of hrDiskStorage cache population.
  966. |
  967. | OTHER THINGS TO KNOW:
  968. |
  969. | We scan using the "\\.\PHYSICALDRIVEx" syntax permitted to
  970. | "CreateFile()". CreateFile seems to allow opens only on disks
  971. | that are hard-fixed disks (no floppies, no CD-ROMS).
  972. |
  973. | This function is also (while it is "at it") looking for the drive
  974. | from which the system was booted (in order to set a global value
  975. | (hrdevice table index) for the value of "InitLoadDev_index" (defined
  976. | in "HRDEVENT.C") which becomes the value of "HrSystemInitialLoadDevice".
  977. */
  978. {
  979. HANDLE hdrv; /* Handle to device */
  980. UINT dev_number; /* Current "x" in "\\.\PHYSICALDRIVEx" */
  981. #undef PHYS_SIZE
  982. #define PHYS_SIZE 64
  983. CHAR phys_name[PHYS_SIZE]; /* Buffer where a string like */
  984. /* "\\.PHYSICALDRIVE0" (for example) */
  985. /* is built for drive access. */
  986. DRIVE_LAYOUT_INFORMATION *dl; /* Drive-layout pointer */
  987. #define BBSz 768
  988. CHAR big[BBSz]; /* Big buffer for layout info */
  989. DWORD bytes_out; /* Bytes retnd into "big" */
  990. CHAR windir[MAX_PATH]; /* Current Windows Directory */
  991. CHAR ntdev[MAX_PATH]; /* NT Device Name for MSDOS drive */
  992. CHAR pntdev[MAX_PATH]; /* NT Device Name for PHYSICALDRIVE*/
  993. /*
  994. |==============================================================================
  995. | Compute the NT "device name" we expect is the device from which the
  996. | system was booted.
  997. |
  998. | Strategy:
  999. |
  1000. | - Obtain "current windows directory" and truncate to obtain just the MS-DOS
  1001. | device name.
  1002. |
  1003. | - Do QueryDosDevice to get the underlying "NT Device Name", which will
  1004. | include a "\PartitionX" on the end of it, where "X" is presumed to be
  1005. | the 1-origined partition number.
  1006. |
  1007. | - Mangle the NT Device Name so that it sez "....\Partition0" (ie "partition
  1008. | zero") which is the NT Device Name we expect to be associated with the
  1009. | "\\.\PHYSICALDRIVEy" string we generate for each valid fixed disk below.
  1010. */
  1011. /* If we can get the current Windows Directory */
  1012. if (GetWindowsDirectory(windir, MAX_PATH) != 0 ) {
  1013. /* Truncate to just "C:" (or whatever) */
  1014. windir[2] = '\0';
  1015. /* Obtain the NT Device Name associated with MS-DOS logical drive */
  1016. if (QueryDosDevice(windir, ntdev, MAX_PATH) != 0) {
  1017. PCHAR partition;
  1018. /* If the string "\Partition" appears in this string */
  1019. if ((partition = strstr(ntdev,"\\Partition")) != NULL) {
  1020. /* Convert it to say "\Partition0" regardless */
  1021. strcpy(partition, "\\Partition0");
  1022. }
  1023. else {
  1024. /* Failure: Null-terminate so we fail gracefully */
  1025. ntdev[0] = '\0';
  1026. }
  1027. }
  1028. else {
  1029. /* Failure: Null-terminate so we fail gracefully */
  1030. ntdev[0] = '\0';
  1031. }
  1032. }
  1033. else {
  1034. /* Failure: Null-terminate so we fail gracefully */
  1035. ntdev[0] = '\0';
  1036. }
  1037. /*
  1038. |==============================================================================
  1039. | For every physical device we can open successfully. . .
  1040. */
  1041. for (dev_number = 0; ; dev_number += 1) {
  1042. /* Build it for device n: "\\.\PHYSICALDRIVEn" */
  1043. sprintf(phys_name, "\\\\.\\PHYSICALDRIVE%d", dev_number);
  1044. /*
  1045. | Suppress any attempt by the system to make the user put a volume in a
  1046. | removable drive ("CreateFile" will just fail).
  1047. */
  1048. SetErrorMode(SEM_FAILCRITICALERRORS);
  1049. /* Attempt to get a handle using this physical name string */
  1050. if ((hdrv = CreateFile(phys_name, // Device
  1051. GENERIC_READ, // Access
  1052. // Share Mode
  1053. FILE_SHARE_READ |
  1054. FILE_SHARE_WRITE,
  1055. NULL, // Security
  1056. OPEN_EXISTING, // CreationDistribution
  1057. FILE_ATTRIBUTE_NORMAL, // FlagsandAttributes
  1058. NULL // Template file
  1059. )) != INVALID_HANDLE_VALUE) {
  1060. ULONG access; /* hrDiskStorageAccess = readWrite(1) */
  1061. ULONG media; /* hrDiskStorageMedia = floppyDisk(4) */
  1062. ULONG removable; /* hrDiskStorageRemovable = TRUE */
  1063. ULONG capacityKB; /* hrDiskStorageCapacity, (kilobytes) */
  1064. ULONG status; /* hrDeviceStatus = unknown(1) */
  1065. CHAR *descr; /* hrDeviceDescr string */
  1066. DWORD bytes_out; /* Bytes retnd into geo_info */
  1067. DISK_GEOMETRY geo_info; /* Geometry Info from drive */
  1068. char *mt; /* Media Type */
  1069. CACHEROW *dv_row; /* HrDevice table row created for disk*/
  1070. /*
  1071. | Device is Open, so we can presume it really exists, so it goes
  1072. | into the hrDevice table.
  1073. |
  1074. | It is presumed to be a FIXED disk.
  1075. */
  1076. access = 1; /* hrDiskStorageAccess = readWrite(1) */
  1077. media = 3; /* hrDiskStorageMedia = hardDisk(3) */
  1078. removable = FALSE; /* hrDiskStorageRemovable = FALSE */
  1079. capacityKB = 0; /* hrDiskStorageCapacity (unknown) */
  1080. status = 1; /* hrDeviceStatus = unknown(1) */
  1081. descr = "Fixed Disk";/* hrDeviceDescr */
  1082. /* ==========================================================
  1083. | IOCTL_DISK_GET_DRIVE_GEOMETRY
  1084. |
  1085. | If we can get this, we get a better description and an
  1086. | accurate capacity value.
  1087. */
  1088. if (DeviceIoControl(hdrv, // device handle
  1089. // IoControlCode (op-code)
  1090. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  1091. NULL, // "input buffer"
  1092. 0, // "input buffer size"
  1093. &geo_info, // "output buffer"
  1094. // "output buffer size"
  1095. sizeof(DISK_GEOMETRY),
  1096. &bytes_out, // bytes written to geo_info
  1097. NULL // no Overlapped I/o
  1098. )) {
  1099. /*
  1100. | Compute capacity
  1101. */
  1102. capacityKB = (ULONG)
  1103. (geo_info.Cylinders.QuadPart * // 64 bit
  1104. (geo_info.TracksPerCylinder * // 32 bits
  1105. geo_info.SectorsPerTrack *
  1106. geo_info.BytesPerSector)
  1107. ) / 1024;
  1108. /* hrDeviceStatus = running(2) */
  1109. status = 2;
  1110. switch ( geo_info.MediaType ) {
  1111. case FixedMedia:
  1112. break;
  1113. default:
  1114. descr = "Unknown Media";
  1115. }
  1116. }
  1117. /*
  1118. | Create a row in HrDevice Table and a corresponding row in
  1119. | hrDiskStorage sub-table.
  1120. */
  1121. if ((dv_row = Process_DS_Row (type_arc, /* hrDeviceType last arc */
  1122. access, /* hrDiskStorageAccess */
  1123. media, /* hrDiskStorageMedia */
  1124. removable, /* hrDiskStorageRemovable */
  1125. capacityKB,/* hrDiskStorageCapacity */
  1126. status, /* hrDeviceStatus */
  1127. descr /* hrDeviceDescr */
  1128. )
  1129. ) == NULL) {
  1130. /* Something blew */
  1131. CloseHandle(hdrv);
  1132. return ( FALSE );
  1133. }
  1134. /*
  1135. | If it turns out this is the device from which the system was
  1136. | booted, we need to return the index associated with the "dv_row"
  1137. | row into "InitLoadDev_index" (defined in "HRDEVENT.C") to become
  1138. | the value of "HrSystemInitialLoadDevice".
  1139. |
  1140. | See if the NT Device name associated with this "\\.\PHYSICALDRIVEx"
  1141. | matches the value predicted for the system boot device.
  1142. |
  1143. | If we can get the NT Device name for "PHYSICALDRIVEn" . . . */
  1144. if (QueryDosDevice(&phys_name[4], pntdev, MAX_PATH) != 0 ) {
  1145. /* If it matches the predicted value for boot device . . . */
  1146. if ( strcmp(pntdev, ntdev) == 0) {
  1147. /* Record the index for the current "physicaldrive" */
  1148. InitLoadDev_index = dv_row->index;
  1149. }
  1150. }
  1151. else {
  1152. /*
  1153. | Fail gracefully so things will still work in
  1154. | "ProcessPartition()" below.
  1155. */
  1156. pntdev[0] = '\0';
  1157. }
  1158. /*
  1159. | Create a hrPartition table (in the HrDevice Table row just created
  1160. | for the disk) to represent the partitions on this fixed disk.
  1161. */
  1162. if ( ProcessPartitions( hdrv, dv_row, pntdev ) != TRUE ) {
  1163. /* Something blew */
  1164. CloseHandle(hdrv);
  1165. return ( FALSE );
  1166. }
  1167. /* Fold up shop on this disk */
  1168. CloseHandle(hdrv);
  1169. } /* If we managed to "CreateFile()" the device */
  1170. else { /* Open failed... give up the scan */
  1171. break;
  1172. }
  1173. SetErrorMode(0); /* Turn error suppression mode off */
  1174. } /* For each device */
  1175. /* Successful scan */
  1176. return ( TRUE );
  1177. }
  1178. /* Process_DS_Row - Process Information into HrDevice and hrDiskStorage Row */
  1179. /* Process_DS_Row - Process Information into HrDevice and hrDiskStorage Row */
  1180. /* Process_DS_Row - Process Information into HrDevice and hrDiskStorage Row */
  1181. static CACHEROW *
  1182. Process_DS_Row (
  1183. ULONG type_arc, /* hrDeviceType last arc value */
  1184. ULONG access, /* hrDiskStorageAccess = readWrite(1) */
  1185. ULONG media, /* hrDiskStorageMedia = floppyDisk(4) */
  1186. ULONG removable, /* hrDiskStorageRemovable = TRUE */
  1187. ULONG capacityKB,/* hrDiskStorageCapacity, (kilobytes) */
  1188. ULONG status, /* hrDeviceStatus = unknown(1) */
  1189. CHAR *descr /* hrDeviceDescr string */
  1190. )
  1191. /*
  1192. | EXPLICIT INPUTS:
  1193. |
  1194. | "type_arc" is the number "n" to be used as the last arc in the
  1195. | device-type OID:
  1196. |
  1197. | 1.3.6.1.2.1.25.3.1.n
  1198. | | | |
  1199. | | | * Identifying arc for type
  1200. | | *-hrDeviceTypes (OIDs specifying device types)
  1201. | *-hrDevice
  1202. |
  1203. | for devices created by this cache-population routine.
  1204. |
  1205. | The rest of the arguments outline above are used to fill in
  1206. | attribute values in both the hrDevice table row and the corresponding
  1207. | hrDiskStorage row.
  1208. |
  1209. | IMPLICIT INPUTS:
  1210. |
  1211. | The module-local head of the cache for the HrDiskStorage table,
  1212. | "HrDiskStorage_cache".
  1213. |
  1214. | OUTPUTS:
  1215. |
  1216. | On Success:
  1217. | Function returns pointer to row entry made to the hrDevice
  1218. | table indicating that the both caches have been fully
  1219. | populated with a new row.
  1220. |
  1221. | On any Failure:
  1222. | Function returns NULL (indicating "not enough storage" or other
  1223. | failure.).
  1224. |
  1225. | THE BIG PICTURE:
  1226. |
  1227. |
  1228. | OTHER THINGS TO KNOW:
  1229. |
  1230. | This function contains common "row-insertion" code for the
  1231. | Gen_Fixed_disks() and Gen_nonFixed_disks() functions.
  1232. */
  1233. {
  1234. CACHEROW *dv_row; /* Row created in hrDevice table */
  1235. CACHEROW *ds_row; /* Row created in hrDiskStorage table */
  1236. /*
  1237. |==========================
  1238. | Create hrDevice Row entry.
  1239. |
  1240. | Note we're initializing this as though the Hidden Context is always
  1241. | going to be a Cache pointer. It will be for fixed-disks (that have
  1242. | Partition Tables), but for other disks the "NULL" signals "No Partition
  1243. | Table".
  1244. |
  1245. | For fixed-disks, the NULL is overwritten later (in "ProcessPartitions()")
  1246. | by a pointer to malloced storage containing an instance of CACHEHEAD
  1247. | structure that carries the hrPartition Table for that fixed-disk).
  1248. */
  1249. if ((dv_row = AddHrDeviceRow(type_arc, // DeviceType OID Last-Arc
  1250. descr, // Used as description
  1251. NULL, // Hidden Ctx (none)
  1252. CA_CACHE // Hidden Ctx type
  1253. )) == NULL ) {
  1254. /* Something blew */
  1255. return ( NULL );
  1256. }
  1257. /* Re-Set hrDeviceStatus */
  1258. dv_row->attrib_list[HRDV_STATUS].attrib_type = CA_NUMBER;
  1259. dv_row->attrib_list[HRDV_STATUS].u.unumber_value = status;
  1260. /*
  1261. |===============================
  1262. | Create hrDiskStorage Row entry
  1263. |
  1264. | Note: The index is not recorded IN the row, but the entry
  1265. | is "indexed": by the hrDevice row index. This happens
  1266. | in the AddTableRow() call below.
  1267. */
  1268. if ((ds_row = CreateTableRow( HRDS_ATTRIB_COUNT ) ) == NULL) {
  1269. return ( NULL ); // Out of memory
  1270. }
  1271. /*
  1272. | Set the attribute values for this row
  1273. */
  1274. /* =========== hrDiskStorageAccess ==========*/
  1275. ds_row->attrib_list[HRDS_ACCESS].attrib_type = CA_NUMBER;
  1276. ds_row->attrib_list[HRDS_ACCESS].u.unumber_value = access;
  1277. /* =========== hrDiskStorageAccess ==========*/
  1278. ds_row->attrib_list[HRDS_MEDIA].attrib_type = CA_NUMBER;
  1279. ds_row->attrib_list[HRDS_MEDIA].u.unumber_value = media;
  1280. /* =========== hrDiskStorageRemovable ==========*/
  1281. ds_row->attrib_list[HRDS_REMOVABLE].attrib_type = CA_NUMBER;
  1282. ds_row->attrib_list[HRDS_REMOVABLE].u.unumber_value = removable;
  1283. /* =========== hrDiskStorageCapacity ==========*/
  1284. ds_row->attrib_list[HRDS_CAPACITY].attrib_type = CA_NUMBER;
  1285. ds_row->attrib_list[HRDS_CAPACITY].u.unumber_value = capacityKB;
  1286. /*
  1287. | Now insert the filled-in CACHEROW structure into the
  1288. | cache-list for the hrDiskStorage Table..
  1289. |
  1290. | Use the same index that was used to specify the row inserted
  1291. | into the hrDevice table.
  1292. */
  1293. if (AddTableRow(dv_row->attrib_list[HRDV_INDEX].u.unumber_value, /* Index */
  1294. ds_row, /* Row */
  1295. &hrDiskStorage_cache /* Cache */
  1296. ) == FALSE) {
  1297. return ( NULL ); /* Internal Logic Error! */
  1298. }
  1299. /* Processing complete */
  1300. return ( dv_row );
  1301. }
  1302. /* ProcessPartitions - Process Partition Information into HrDevice Row */
  1303. /* ProcessPartitions - Process Partition Information into HrDevice Row */
  1304. /* ProcessPartitions - Process Partition Information into HrDevice Row */
  1305. static BOOL
  1306. ProcessPartitions(
  1307. HANDLE hdrv, /* Fixed-Disk containing partitions */
  1308. CACHEROW *dv_row, /* Row in hrDevice table for disk */
  1309. CHAR *pntdev /* NT Device name for physical disk */
  1310. )
  1311. /*
  1312. | EXPLICIT INPUTS:
  1313. |
  1314. | "hdrv" - handle open to the fixed disk whose partitions are to be
  1315. | enumerated.
  1316. |
  1317. | "dv_row" - the HrDevice row into which the new hrPartition Table
  1318. | is to go.
  1319. |
  1320. | "pntdev" - NT Device Name for the physical disk we're dealing with.
  1321. | We need this to infer the logical device name for any
  1322. | active partition.
  1323. |
  1324. | IMPLICIT INPUTS:
  1325. |
  1326. | "HrFSTable_cache" - this gets scanned to allow "hrPartitionFSIndex"
  1327. | to be filled in.
  1328. |
  1329. | OUTPUTS:
  1330. |
  1331. | On Success:
  1332. | Function returns TRUE indicating that the Partition Information
  1333. | for the given disk has been used to populate an hrPartition Table
  1334. | instance.
  1335. |
  1336. | On any Failure:
  1337. | Function returns NULL (indicating "not enough storage" or other
  1338. | failure.).
  1339. |
  1340. | THE BIG PICTURE:
  1341. |
  1342. | This is the function that instantiates hrPartition tables.
  1343. |
  1344. | OTHER THINGS TO KNOW:
  1345. |
  1346. | Documentation at the top of the hrPartition Table file "HRPARTIT.C"
  1347. | might be of interest.
  1348. |
  1349. | BUG: As of build 1515, (and indeed in earlier versions of NT) the
  1350. | "PartitionNumber" returned in response to DeviceIoControl opcode
  1351. | "IOCTL_DISK_GET_DRIVE_LAYOUT" comes back as garbage. Whatever
  1352. | comes back is reported as the value of "hrPartitionID" (garbage or
  1353. | not). However when trying to fetch the Volume Label, as part of a
  1354. | workaround attempt, we use the index generated in the code below
  1355. | in an attempt to approximate the proper Partition Number.
  1356. */
  1357. {
  1358. #define DL_SIZE 1024
  1359. CHAR dl_buf[DL_SIZE]; /* Drive-Layout info comes back here */
  1360. UINT i; /* Handy-Dandy loop index */
  1361. ULONG table_index=0; /* hrPartition Table row index counter */
  1362. DWORD bytes_out; /* Exactly how big "dl_buf" got filled */
  1363. DRIVE_LAYOUT_INFORMATION
  1364. *dl; /* Drive-layout pointer */
  1365. /*
  1366. | See if we can grab the Drive's partition layout info.
  1367. */
  1368. if (DeviceIoControl(hdrv, // device handle
  1369. IOCTL_DISK_GET_DRIVE_LAYOUT, // IoControlCode (op-code)
  1370. NULL, // "input buffer"
  1371. 0, // "input buffer size"
  1372. dl_buf, // "output buffer"
  1373. DL_SIZE, // "output buffer size"
  1374. &bytes_out, // bytes written to part_info
  1375. NULL // no Overlapped I/o
  1376. )) {
  1377. CACHEHEAD *ch;
  1378. /*
  1379. | OK, there's presumed to be at least one partition: instantiate the
  1380. | new partition table.
  1381. |
  1382. | Do this by creating its cache list-head structure.
  1383. */
  1384. dv_row->attrib_list[HIDDEN_CTX].attrib_type = CA_CACHE;
  1385. if ((dv_row->attrib_list[HIDDEN_CTX].u.cache
  1386. = ch = (CACHEHEAD *) malloc( sizeof(CACHEHEAD) )) == NULL) {
  1387. return ( FALSE );
  1388. }
  1389. /*
  1390. | Now initialize the contents properly.
  1391. | (This should match what macro CACHEHEAD_INSTANCE does to a static
  1392. | instance).
  1393. */
  1394. ch->list_count = 0;
  1395. ch->list = NULL;
  1396. #if defined(CACHE_DUMP)
  1397. ch->print_row = debug_print_hrpartition;
  1398. #else
  1399. ch->print_row = NULL;
  1400. #endif
  1401. /* Grab a dereferencable pointer to the Drive Layout info */
  1402. dl = (DRIVE_LAYOUT_INFORMATION *) dl_buf;
  1403. /* For every Partition "slot" returned . . . */
  1404. for (i = 0; i < dl->PartitionCount; i += 1) {
  1405. PARTITION_INFORMATION
  1406. *p; /* Partition info thats going to go . . */
  1407. CACHEROW *row; /* . . .into this row in HrPartition */
  1408. CACHEROW *fs_row; /* Row ptr in HrFSEntry table */
  1409. ULONG last_arc; /* Last OID arc to use as FS-Type */
  1410. /* Grab a simple pointer to the next PARTITION_INFO to consider */
  1411. p = &(dl->PartitionEntry[i]);
  1412. /*
  1413. | Note: It may be that not all of the PartitionEntry elements are
  1414. | "live".
  1415. */
  1416. if (p->PartitionType == PARTITION_ENTRY_UNUSED) {
  1417. continue;
  1418. }
  1419. /*
  1420. |===============================
  1421. | Create hrPartition Row entry
  1422. |
  1423. | Note: This table is also "indexed" by the hrDevice row index
  1424. */
  1425. if ((row = CreateTableRow( HRPT_ATTRIB_COUNT ) ) == NULL) {
  1426. return ( FALSE ); // Out of memory
  1427. }
  1428. /* =========== hrPartitionIndex ==========*/
  1429. row->attrib_list[HRPT_INDEX].attrib_type = CA_NUMBER;
  1430. row->attrib_list[HRPT_INDEX].u.unumber_value = (table_index += 1);
  1431. /* =========== hrPartitionLabel ==========*/
  1432. row->attrib_list[HRPT_LABEL].attrib_type = CA_STRING;
  1433. /*
  1434. | If there is an MS-DOS logical device letter assigned to this
  1435. | partition. . .
  1436. */
  1437. if ( p->RecognizedPartition ) {
  1438. /*
  1439. | Go get the label, copy it to malloc'ed storage and return it.
  1440. |
  1441. | NOTE: Due to what seems like a bug, we're passing in "i+1" here
  1442. | rather than "p->PartitionNumber" (which seems to come
  1443. | back as garbage). Clearly "i" is not a proper substitute
  1444. | in the long run. See "OTHER THINGS TO KNOW" in the docs
  1445. | above for this function.
  1446. */
  1447. row->attrib_list[HRPT_LABEL].u.string_value =
  1448. FindPartitionLabel(pntdev, (i+1));
  1449. }
  1450. else {
  1451. /* No label if no MS-DOS device */
  1452. row->attrib_list[HRPT_LABEL].u.string_value = NULL;
  1453. }
  1454. /* =========== hrPartitionID ==========
  1455. |
  1456. | In build 1515, this number is returned as garbage. See
  1457. | "OTHER THINGS TO KNOW" above.
  1458. */
  1459. row->attrib_list[HRPT_ID].attrib_type = CA_NUMBER;
  1460. row->attrib_list[HRPT_ID].u.unumber_value = p->PartitionNumber;
  1461. /* =========== hrPartitionSize ==========*/
  1462. row->attrib_list[HRPT_SIZE].attrib_type = CA_NUMBER;
  1463. row->attrib_list[HRPT_SIZE].u.unumber_value =
  1464. p->PartitionLength.LowPart / 1024;
  1465. /* =========== hrPartitionFSIndex ==========*/
  1466. row->attrib_list[HRPT_FSINDEX].attrib_type = CA_NUMBER;
  1467. /* Assume no file system mounted (that we can find) */
  1468. row->attrib_list[HRPT_FSINDEX].u.unumber_value = 0;
  1469. /* Find the first Row (if any) in the hrFSTable */
  1470. if ((fs_row = FindNextTableRow(0, &hrFSTable_cache)) == NULL) {
  1471. /* No file systems listed at all.. we're done */
  1472. continue;
  1473. }
  1474. /*
  1475. | Convert the Partition-Type into the "last-arc" value we use
  1476. | to indicate what kind of file-system it is.
  1477. */
  1478. last_arc = PartitionTypeToLastArc( p->PartitionType );
  1479. do { /* Walk the hrFSEntry table */
  1480. /*
  1481. | If we found that the hrFSTable entry "fs_row" specifies a
  1482. | file-system TYPE (by arc number) that matches what the current
  1483. | partition's type number translates to ... we're done.
  1484. */
  1485. if (fs_row->attrib_list[HRFS_TYPE].u.unumber_value == last_arc) {
  1486. row->attrib_list[HRPT_FSINDEX].u.unumber_value = fs_row->index;
  1487. break;
  1488. }
  1489. /* Step to the next row */
  1490. fs_row = GetNextTableRow(fs_row);
  1491. }
  1492. while (fs_row != NULL);
  1493. /*
  1494. |===============================
  1495. |Now add the row to the table
  1496. */
  1497. if (AddTableRow(row->attrib_list[HRPT_INDEX].u.unumber_value,/* Index */
  1498. row, /* Row */
  1499. ch /* Cache */
  1500. ) == FALSE) {
  1501. return ( FALSE ); /* Internal Logic Error! */
  1502. }
  1503. } /* For each partition */
  1504. } /* If DeviceIoControl succeeded */
  1505. /* Partition Table complete */
  1506. return ( TRUE ) ;
  1507. }
  1508. /* FindPartitionLabel - Find MS-DOS Device Label for a Fixed-Disk Partition */
  1509. /* FindPartitionLabel - Find MS-DOS Device Label for a Fixed-Disk Partition */
  1510. /* FindPartitionLabel - Find MS-DOS Device Label for a Fixed-Disk Partition */
  1511. static PCHAR
  1512. FindPartitionLabel(
  1513. CHAR *pntdev, /* NT Device name for physical disk */
  1514. UINT part_id /* Partition Number (1-origined) */
  1515. )
  1516. /*
  1517. | EXPLICIT INPUTS:
  1518. |
  1519. | "pntdev" - the NT Device Name (e.g. "\Device\Harddisk0\Partition0"
  1520. | for the PHYSICAL device we're working on).
  1521. |
  1522. | "part_id" - One-origined Partition number for which we hope to find
  1523. | an MS-DOS Volume Label.
  1524. |
  1525. | IMPLICIT INPUTS:
  1526. |
  1527. | None.
  1528. |
  1529. | OUTPUTS:
  1530. |
  1531. | On Success:
  1532. | Function returns a pointer to malloc'ed storage containing the
  1533. | MS-DOS Device Volume label (as returned by "GetVolumeInformation()").
  1534. |
  1535. | On any Failure:
  1536. | Function returns NULL (indicating "some kind of failure").
  1537. |
  1538. | THE BIG PICTURE:
  1539. |
  1540. | This "helper" function attempts to map an NT Device Name and a
  1541. | one-origined Partition Number into a Volume Label for return as
  1542. | the value of "hrPartitionLabel".
  1543. |
  1544. | OTHER THINGS TO KNOW:
  1545. |
  1546. | The algorithm is based on studying the output from "QueryDosDevices()"
  1547. | and blithely assuming that we can "back-map" the string
  1548. | "\Device\HarddiskX\PartitionY" for any Partition "Y" to the associated
  1549. | MS-DOS Device. There is precious little documentation that sez we can,
  1550. | but we try.
  1551. |
  1552. | Here's the approach:
  1553. |
  1554. | * Using the NT Device Name for the "PHYSICALDRIVEn", we scrape the
  1555. | "\Partition0" off the end of the name and replace it with "\PartitionY"
  1556. | where "Y" is the Partition number passed as input to this function.
  1557. | This is the "Generated Partition Name".
  1558. |
  1559. | ("PHYSICALDRIVE" NT Device Names all seem to have "\Partition0" as
  1560. | the terminating part of their name, and since the Win32 docs say that
  1561. | Partition Numbers are "1-origined", this seems like a safe approach.)
  1562. |
  1563. | * We generate a list of all the MS-DOS device names (using QueryDosDevices).
  1564. |
  1565. | * We take each MS-DOS Device name and ask for it's current underlying
  1566. | NT Device name mapping.
  1567. |
  1568. | + If the first name mapping for any MS-DOS Device matches our
  1569. | "Generated Partition Name", then the MS-DOS Device name is submitted
  1570. | to "GetVolumeInformation()" and the Volume Label returned is used as
  1571. | the "Partition Label".
  1572. */
  1573. {
  1574. #define BIG_BUFF 1024
  1575. CHAR gen_part_name[MAX_PATH+16]; /* "pntdev" is at most MAX_PATH */
  1576. CHAR *partition; /* Where "\Partition0" starts */
  1577. CHAR MSDOS_devices[BIG_BUFF]; /* List of MS-DOS device names */
  1578. CHAR NT_device[BIG_BUFF]; /* Mapping of NT device names */
  1579. CHAR *devname; /* Index for MSDOS_devices */
  1580. /* Copy the NT Device Name for the Physical Drive */
  1581. strcpy(gen_part_name, pntdev);
  1582. /* Obtain a pointer to the beginning of "\Partition0" in this string */
  1583. if ((partition = strstr(gen_part_name, "\\Partition")) != NULL) {
  1584. /*
  1585. | Replace "\Partition0" with "\PartitionY" where "Y" is the supplied
  1586. | partition number: We've got the "Generated Partition Name".
  1587. */
  1588. sprintf(partition, "\\Partition%d", part_id);
  1589. /*
  1590. | Now ask for a list of MS-DOS Device Names
  1591. */
  1592. if ( QueryDosDevice(NULL, MSDOS_devices, BIG_BUFF) != 0) {
  1593. /*
  1594. | Swing down the list of MS-DOS device names and get the NT Device
  1595. | name mappings.
  1596. */
  1597. for (devname = MSDOS_devices;
  1598. *devname != '\0';
  1599. devname += (strlen(devname)+1)) {
  1600. /* Obtain the mappings for device "devname" */
  1601. QueryDosDevice(devname, NT_device, BIG_BUFF);
  1602. /* If the first mapping matches the Generated Partition Name */
  1603. if (strcmp(gen_part_name, NT_device) == 0) {
  1604. #define VOL_LABEL_SIZE 128
  1605. CHAR MSDOS_root[64]; /* Root Path Name */
  1606. CHAR v_label[VOL_LABEL_SIZE]; /* Volume Label */
  1607. CHAR *ret_label; /* --> Malloced storage */
  1608. DWORD comp_len; /* Filename length */
  1609. DWORD flags;
  1610. /*
  1611. | We're obliged to add a root-directory "\" to the MS-DOS
  1612. | device name.
  1613. */
  1614. sprintf(MSDOS_root, "%s\\", devname);
  1615. /* Fetch the Volume Information for the MS-DOS Device */
  1616. if (GetVolumeInformation(
  1617. MSDOS_root, // MS-DOS root name
  1618. v_label, // Vol. Label buf
  1619. VOL_LABEL_SIZE, // vol. label size
  1620. NULL, // Serial Number
  1621. &comp_len, // FileName length
  1622. &flags, // Flags
  1623. NULL, // File System name
  1624. 0 // Name buff. len
  1625. ) != 0) {
  1626. /*
  1627. | Allocate storage to hold a returnable copy
  1628. */
  1629. if ( (ret_label = (CHAR *) malloc(strlen(v_label) + 1))
  1630. != NULL) {
  1631. /* Copy the label to malloced storage */
  1632. strcpy(ret_label, v_label);
  1633. return (ret_label);
  1634. }
  1635. else {
  1636. /* Out of storage */
  1637. return (NULL);
  1638. }
  1639. }
  1640. else {
  1641. /* "GetVolumeInformation" failed on MSDOS name */
  1642. return (NULL);
  1643. }
  1644. }
  1645. }
  1646. }
  1647. }
  1648. return (NULL); /* Other Failure */
  1649. }
  1650. #if defined(CACHE_DUMP)
  1651. /* debug_print_hrdiskstorage - Prints a Row from HrDiskStorage sub-table */
  1652. /* debug_print_hrdiskstorage - Prints a Row from HrDiskStorage sub-table */
  1653. /* debug_print_hrdiskstorage - Prints a Row from HrDiskStorage sub-table */
  1654. static void
  1655. debug_print_hrdiskstorage(
  1656. CACHEROW *row /* Row in hrDiskStorage table */
  1657. )
  1658. /*
  1659. | EXPLICIT INPUTS:
  1660. |
  1661. | "row" - points to the row to be dumped, if NULL, the function
  1662. | merely prints a suitable title.
  1663. |
  1664. | IMPLICIT INPUTS:
  1665. |
  1666. | - Symbols used to reference the attributes in the row entry.
  1667. | - File handle defined by OFILE, presumed to be open.
  1668. |
  1669. | OUTPUTS:
  1670. |
  1671. | On Success:
  1672. | Function prints a dump of the row in ASCII for debugging purposes
  1673. | on file handle OFILE.
  1674. |
  1675. | THE BIG PICTURE:
  1676. |
  1677. | Debugging only.
  1678. |
  1679. | OTHER THINGS TO KNOW:
  1680. */
  1681. {
  1682. if (row == NULL) {
  1683. fprintf(OFILE, "=========================\n");
  1684. fprintf(OFILE, "hrDiskStorage Table Cache\n");
  1685. fprintf(OFILE, "=========================\n");
  1686. return;
  1687. }
  1688. fprintf(OFILE, "hrDiskStorageAccess. . . . %d ",
  1689. row->attrib_list[HRDS_ACCESS].u.unumber_value);
  1690. switch (row->attrib_list[HRDS_ACCESS].u.unumber_value) {
  1691. case 1: fprintf(OFILE, "(readWrite)\n"); break;
  1692. case 2: fprintf(OFILE, "(readOnly)\n"); break;
  1693. default:fprintf(OFILE, "(???)\n"); break;
  1694. }
  1695. fprintf(OFILE, "hrDiskStorageMedia . . . . %d ",
  1696. row->attrib_list[HRDS_MEDIA].u.unumber_value);
  1697. switch (row->attrib_list[HRDS_MEDIA].u.unumber_value) {
  1698. case 1: fprintf(OFILE, "(Other)\n"); break;
  1699. case 2: fprintf(OFILE, "(Unknown)\n"); break;
  1700. case 3: fprintf(OFILE, "(hardDisk)\n"); break;
  1701. case 4: fprintf(OFILE, "(floppyDisk)\n"); break;
  1702. case 5: fprintf(OFILE, "(opticalDiskROM)\n"); break;
  1703. case 6: fprintf(OFILE, "(opticalDiskWORM)\n"); break;
  1704. case 7: fprintf(OFILE, "(opticalDiskRW)\n"); break;
  1705. case 8: fprintf(OFILE, "(ramDisk)\n"); break;
  1706. default:fprintf(OFILE, "(???)\n"); break;
  1707. }
  1708. fprintf(OFILE, "hrDiskStorageRemovable . . %d ",
  1709. row->attrib_list[HRDS_REMOVABLE].u.unumber_value);
  1710. switch (row->attrib_list[HRDS_REMOVABLE].u.unumber_value) {
  1711. case 0: fprintf(OFILE, "(FALSE)\n"); break;
  1712. case 1: fprintf(OFILE, "(TRUE)\n"); break;
  1713. default:
  1714. fprintf(OFILE, "(???)\n"); break;
  1715. }
  1716. fprintf(OFILE, "hrDiskStorageCapacity. . . %d (KBytes)\n",
  1717. row->attrib_list[HRDS_CAPACITY].u.unumber_value);
  1718. }
  1719. /* debug_print_hrpartition - Prints a Row from HrPartition sub-table */
  1720. /* debug_print_hrpartition - Prints a Row from HrPartition sub-table */
  1721. /* debug_print_hrpartition - Prints a Row from HrPartition sub-table */
  1722. static void
  1723. debug_print_hrpartition(
  1724. CACHEROW *row /* Row in hrPartition table */
  1725. )
  1726. /*
  1727. | EXPLICIT INPUTS:
  1728. |
  1729. | "row" - points to the row to be dumped, if NULL, the function
  1730. | merely prints a suitable title.
  1731. |
  1732. | IMPLICIT INPUTS:
  1733. |
  1734. | - Symbols used to reference the attributes in the row entry.
  1735. | - File handle defined by OFILE, presumed to be open.
  1736. |
  1737. | OUTPUTS:
  1738. |
  1739. | On Success:
  1740. | Function prints a dump of the row in ASCII for debugging purposes
  1741. | on file handle OFILE.
  1742. |
  1743. | THE BIG PICTURE:
  1744. |
  1745. | Debugging only.
  1746. |
  1747. | OTHER THINGS TO KNOW:
  1748. */
  1749. {
  1750. if (row == NULL) {
  1751. fprintf(OFILE, " =======================\n");
  1752. fprintf(OFILE, " hrPartition Table Cache\n");
  1753. fprintf(OFILE, " =======================\n");
  1754. return;
  1755. }
  1756. fprintf(OFILE, " hrPartitionIndex . . . . . %d\n",
  1757. row->attrib_list[HRPT_INDEX].u.unumber_value);
  1758. fprintf(OFILE, " hrPartitionLabel . . . . . \"%s\"\n",
  1759. row->attrib_list[HRPT_LABEL].u.string_value);
  1760. fprintf(OFILE, " hrPartitionID. . . . . . . 0x%x\n",
  1761. row->attrib_list[HRPT_ID].u.unumber_value);
  1762. fprintf(OFILE, " hrPartitionSize. . . . . . %d\n",
  1763. row->attrib_list[HRPT_SIZE].u.unumber_value);
  1764. fprintf(OFILE, " hrPartitionFSIndex . . . . %d\n",
  1765. row->attrib_list[HRPT_FSINDEX].u.unumber_value);
  1766. }
  1767. #endif