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.

1765 lines
54 KiB

  1. /*
  2. * HrSWRunEntry.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 HrSWRunEntry. Actual instrumentation code is
  32. * supplied by the developer.
  33. *
  34. * Functions:
  35. *
  36. * A get and set routine for each attribute in the class.
  37. *
  38. * The routines for instances within the class.
  39. *
  40. * Author:
  41. *
  42. * D. D. Burns @ Webenable Inc
  43. *
  44. * Revision History:
  45. *
  46. * V1.00 - 05/14/97 D. D. Burns Genned: Thu Nov 07 16:47:29 1996
  47. *
  48. */
  49. #include <nt.h>
  50. #include <ntrtl.h>
  51. #include <nturtl.h>
  52. #include <windows.h>
  53. #include <malloc.h>
  54. #include <snmp.h>
  55. #include "mib.h"
  56. #include "smint.h"
  57. #include "hostmsmi.h"
  58. #include "user.h" /* Developer supplied include file */
  59. #include "HMCACHE.H" /* Cache-related definitions */
  60. #include <string.h>
  61. /*
  62. |==============================================================================
  63. | Function prototypes for this module.
  64. |
  65. */
  66. /* AddHrSWRunRow - Generate another Row Entry in HrSWRun/Perf Table cache */
  67. static BOOL
  68. AddHrSWRunRow(PSYSTEM_PROCESS_INFORMATION ProcessInfo);
  69. /* FetchProcessParams - Fetch Path & Parameter String from Process Cmd line */
  70. void
  71. FetchProcessParams(
  72. PSYSTEM_PROCESS_INFORMATION ProcessInfo, /* Process for parameters */
  73. CHAR **path_str, /* Returned PATH string */
  74. CHAR **params_str /* Returned Parameters string */
  75. );
  76. #if defined(CACHE_DUMP)
  77. /* debug_print_hrswrun - Prints a Row from HrSWRun(Perf) Table */
  78. static void
  79. debug_print_hrswrun(
  80. CACHEROW *row /* Row in hrSWRun(Perf) table */
  81. );
  82. #endif
  83. /*
  84. |==============================================================================
  85. | Cache Refresh Time
  86. |
  87. | The cache for the hrSWRun and hrSWRunPerf tables is refreshed automatically
  88. | when a request arrives --AND-- the cache is older than CACHE_MAX_AGE
  89. | in seconds.
  90. |
  91. */
  92. static
  93. LARGE_INTEGER cache_time; // 100ns Timestamp of cache (when last refreshed)
  94. #define CACHE_MAX_AGE 120 // Maximum age in seconds
  95. /*
  96. |==============================================================================
  97. | Create the list-head for the HrSWRun(Perf) Table cache.
  98. |
  99. | This cache contains info for both the hrSWRun and hrSWRunPerf tables.
  100. | (This macro is defined in "HMCACHE.H").
  101. |
  102. | This is global so code for the hrSWRunPerf table ("HRSWPREN.C") can
  103. | reference it.
  104. */
  105. CACHEHEAD_INSTANCE(hrSWRunTable_cache, debug_print_hrswrun);
  106. /*
  107. |==============================================================================
  108. | Operating System Index
  109. |
  110. | SNMP attribute "HrSWOSIndex" is the index into hrSWRun to the entry that
  111. | primary operating system running on the host. This value is computed in
  112. | this module in function "AddHrSWRunRow()" and stored here for reference
  113. | by code in "HRSWRUN.C".
  114. */
  115. ULONG SWOSIndex;
  116. /*
  117. * GetHrSWRunIndex
  118. * A unique value for each piece of software running on the host. Wherever
  119. * possible, this should be the system's native, unique id
  120. *
  121. * Gets the value for HrSWRunIndex.
  122. *
  123. * Arguments:
  124. *
  125. * outvalue address to return variable value
  126. * accesss Reserved for future security use
  127. * instance address of instance name as ordered native
  128. * data type(s)
  129. *
  130. * Return Codes:
  131. *
  132. * Standard PDU error codes.
  133. *
  134. * SNMP_ERRORSTATUS_NOERROR Successful get
  135. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  136. * mibtget.c v0.10
  137. *
  138. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  139. | hrSWRunIndex
  140. |
  141. | ACCESS SYNTAX
  142. | read-only INTEGER (1..2147483647)
  143. |
  144. | "A unique value for each piece of software running on the host. Wherever
  145. | possible, this should be the system's native, unique identification number."
  146. |
  147. | DISCUSSION:
  148. |
  149. | By using performance monitoring information from the Registry (using code
  150. | from "PVIEW") this attribute is given the value of the Process ID.
  151. |
  152. |============================================================================
  153. | 1.3.6.1.2.1.25.4.2.1.1.<instance>
  154. | | | | |
  155. | | | | *-hrSWRunIndex
  156. | | | *-hrSWRunEntry
  157. | | *-hrSWRunTable
  158. | *-hrSWRun
  159. */
  160. UINT
  161. GetHrSWRunIndex(
  162. OUT Integer *outvalue ,
  163. IN Access_Credential *access ,
  164. IN InstanceName *instance )
  165. {
  166. ULONG index; /* As fetched from instance structure */
  167. CACHEROW *row; /* Row entry fetched from cache */
  168. /*
  169. | Grab the instance information
  170. */
  171. index = GET_INSTANCE(0);
  172. /*
  173. | Use it to find the right entry in the cache
  174. */
  175. if ((row = FindTableRow(index, &hrSWRunTable_cache)) == NULL) {
  176. return SNMP_ERRORSTATUS_GENERR;
  177. }
  178. *outvalue = row->attrib_list[HRSR_INDEX].u.number_value;
  179. return SNMP_ERRORSTATUS_NOERROR ;
  180. } /* end of GetHrSWRunIndex() */
  181. /*
  182. * GetHrSWRunName
  183. * A textual description of this running piece of software, including the
  184. * manufacturer, revision, and the name by which it is commo
  185. *
  186. * Gets the value for HrSWRunName.
  187. *
  188. * Arguments:
  189. *
  190. * outvalue address to return variable value
  191. * accesss Reserved for future security use
  192. * instance address of instance name as ordered native
  193. * data type(s)
  194. *
  195. * Return Codes:
  196. *
  197. * Standard PDU error codes.
  198. *
  199. * SNMP_ERRORSTATUS_NOERROR Successful get
  200. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  201. * mibtget.c v0.10
  202. *
  203. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  204. | hrSWRunName
  205. |
  206. | ACCESS SYNTAX
  207. | read-only InternationalDisplayString (SIZE (0..64))
  208. |
  209. | "A textual description of this running piece of software, including the
  210. | manufacturer, revision, and the name by which it is commonly known. If this
  211. | software was installed locally, this should be the same string as used in the
  212. | corresponding hrSWInstalledName."
  213. |
  214. | DISCUSSION:
  215. |
  216. | By using performance monitoring information from the Registry (using code
  217. | from "PVIEW") this attribute is given the value of the Process name.
  218. |
  219. |============================================================================
  220. | 1.3.6.1.2.1.25.4.2.1.2.<instance>
  221. | | | | |
  222. | | | | *-hrSWRunName
  223. | | | *-hrSWRunEntry
  224. | | *-hrSWRunTable
  225. | *-hrSWRun
  226. */
  227. UINT
  228. GetHrSWRunName(
  229. OUT InternationalDisplayString *outvalue ,
  230. IN Access_Credential *access ,
  231. IN InstanceName *instance )
  232. {
  233. ULONG index; /* As fetched from instance structure */
  234. CACHEROW *row; /* Row entry fetched from cache */
  235. /*
  236. | Grab the instance information
  237. */
  238. index = GET_INSTANCE(0);
  239. /*
  240. | Use it to find the right entry in the cache
  241. */
  242. if ((row = FindTableRow(index, &hrSWRunTable_cache)) == NULL) {
  243. return SNMP_ERRORSTATUS_GENERR;
  244. }
  245. /* Return the name that was computed at cache-build time */
  246. outvalue->length = strlen(row->attrib_list[HRSR_NAME].u.string_value);
  247. outvalue->string = row->attrib_list[HRSR_NAME].u.string_value;
  248. if (outvalue->length > 64) {
  249. outvalue->length = 64; /* Truncate */
  250. }
  251. return SNMP_ERRORSTATUS_NOERROR ;
  252. } /* end of GetHrSWRunName() */
  253. /*
  254. * GetHrSWRunID
  255. * The product ID of this running piece of software.
  256. *
  257. * Gets the value for HrSWRunID.
  258. *
  259. * Arguments:
  260. *
  261. * outvalue address to return variable value
  262. * accesss Reserved for future security use
  263. * instance address of instance name as ordered native
  264. * data type(s)
  265. *
  266. * Return Codes:
  267. *
  268. * Standard PDU error codes.
  269. *
  270. * SNMP_ERRORSTATUS_NOERROR Successful get
  271. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  272. * mibtget.c v0.10
  273. *
  274. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  275. | hrSWRunID
  276. |
  277. | ACCESS SYNTAX
  278. | read-only ProductID
  279. |
  280. | "The product ID of this running piece of software."
  281. |
  282. | DISCUSSION:
  283. |
  284. | <POA-16> I anticipate always using "unknownProduct" as the value for this
  285. | attribute, as I can envision no systematic means of acquiring a registered
  286. | OID for all process software to be used as the value for this attribute.
  287. |
  288. | RESOLVED >>>>>>>
  289. | <POA-16> Returning an unknown Product ID is acceptable.
  290. | RESOLVED >>>>>>>
  291. |
  292. |============================================================================
  293. | 1.3.6.1.2.1.25.4.2.1.3.<instance>
  294. | | | | |
  295. | | | | *-hrSWRunID
  296. | | | *-hrSWRunEntry
  297. | | *-hrSWRunTable
  298. | *-hrSWRun
  299. */
  300. UINT
  301. GetHrSWRunID(
  302. OUT ProductID *outvalue ,
  303. IN Access_Credential *access ,
  304. IN InstanceName *instance )
  305. {
  306. /*
  307. | The deal on this attribute is that we'll never have a valid OID value
  308. | for this attribute. Consequently, we always return the standard
  309. | "unknown" OID value ("0.0") regardless of the instance value (which
  310. | by now in the calling sequence of things has been validated anyway).
  311. */
  312. if ( (outvalue->ids = SNMP_malloc(2 * sizeof( UINT ))) == NULL) {
  313. return SNMP_ERRORSTATUS_GENERR;
  314. }
  315. outvalue->idLength = 2;
  316. /*
  317. | Load in the OID value for "unknown" for ProductID: "0.0"
  318. */
  319. outvalue->ids[0] = 0;
  320. outvalue->ids[1] = 0;
  321. return SNMP_ERRORSTATUS_NOERROR ;
  322. } /* end of GetHrSWRunID() */
  323. /*
  324. * GetHrSWRunPath
  325. * A description of the location on long-term storage (e.g. a disk drive)
  326. * from which this software was loaded.
  327. *
  328. * Gets the value for HrSWRunPath.
  329. *
  330. * Arguments:
  331. *
  332. * outvalue address to return variable value
  333. * accesss Reserved for future security use
  334. * instance address of instance name as ordered native
  335. * data type(s)
  336. *
  337. * Return Codes:
  338. *
  339. * Standard PDU error codes.
  340. *
  341. * SNMP_ERRORSTATUS_NOERROR Successful get
  342. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  343. * mibtget.c v0.10
  344. *
  345. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  346. | hrSWRunPath
  347. |
  348. | ACCESS SYNTAX
  349. | read-only InternationalDisplayString (SIZE(0..128))
  350. |
  351. | "A description of the location on long-term storage (e.g. a disk drive) from
  352. | which this software was loaded."
  353. |
  354. | DISCUSSION:
  355. |
  356. | <POA-17> This information is not extracted by the sample PVIEW code from the
  357. | performance monitoring statistics kept in the Registry. If this information
  358. | is available from the Registry or some other source, I need to acquire the
  359. | description of how to get it.
  360. |
  361. | RESOLVED >>>>>>>>
  362. | <POA-17> This is obtained using PerfMon code pointers provided by Bob Watson.
  363. | RESOLVED >>>>>>>>
  364. |
  365. |============================================================================
  366. | 1.3.6.1.2.1.25.4.2.1.4.<instance>
  367. | | | | |
  368. | | | | *-hrSWRunPath
  369. | | | *-hrSWRunEntry
  370. | | *-hrSWRunTable
  371. | *-hrSWRun
  372. */
  373. UINT
  374. GetHrSWRunPath(
  375. OUT InternationalDisplayString *outvalue ,
  376. IN Access_Credential *access ,
  377. IN InstanceName *instance )
  378. {
  379. ULONG index; /* As fetched from instance structure */
  380. CACHEROW *row; /* Row entry fetched from cache */
  381. /*
  382. | Grab the instance information
  383. */
  384. index = GET_INSTANCE(0);
  385. /*
  386. | Use it to find the right entry in the cache
  387. */
  388. if ((row = FindTableRow(index, &hrSWRunTable_cache)) == NULL) {
  389. return SNMP_ERRORSTATUS_GENERR;
  390. }
  391. /*
  392. | Return the Path string that was computed at cache-build time.
  393. | NOTE: This string might be NULL.
  394. */
  395. if (row->attrib_list[HRSR_PATH].u.string_value == NULL) {
  396. outvalue->length = 0;
  397. }
  398. else {
  399. outvalue->length = strlen(row->attrib_list[HRSR_PATH].u.string_value);
  400. outvalue->string = row->attrib_list[HRSR_PATH].u.string_value;
  401. if (outvalue->length > 128) {
  402. outvalue->length = 128; /* Truncate */
  403. }
  404. }
  405. return SNMP_ERRORSTATUS_NOERROR ;
  406. } /* end of GetHrSWRunPath() */
  407. /*
  408. * GetHrSWRunParameters
  409. *
  410. * A description of the parameters supplied to this software when it was
  411. * initially loaded."
  412. *
  413. * Gets the value for HrSWRunParameters.
  414. *
  415. * Arguments:
  416. *
  417. * outvalue address to return variable value
  418. * accesss Reserved for future security use
  419. * instance address of instance name as ordered native
  420. * data type(s)
  421. *
  422. * Return Codes:
  423. *
  424. * Standard PDU error codes.
  425. *
  426. * SNMP_ERRORSTATUS_NOERROR Successful get
  427. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  428. * mibtget.c v0.10
  429. *
  430. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  431. | hrSWRunParameters
  432. |
  433. | ACCESS SYNTAX
  434. | read-only InternationalDisplayString (SIZE(0..128))
  435. |
  436. | "A description of the parameters supplied to this software when it was
  437. | initially loaded."
  438. |
  439. | DISCUSSION:
  440. |
  441. | <POA-18> This information is not extracted by the sample PVIEW code from the
  442. | performance monitoring statistics kept in the Registry. If this information
  443. | is available from the Registry or some other source, I need to acquire the
  444. | description of how to get it.
  445. |
  446. | RESOLVED >>>>>>>>
  447. | <POA-18> See discussion for "hrSWRunPath" above.
  448. | RESOLVED >>>>>>>>
  449. |
  450. |============================================================================
  451. | NOTE: This function edited in by hand, as it was not originally generated.
  452. |============================================================================
  453. | 1.3.6.1.2.1.25.4.2.1.5.<instance>
  454. | | | | |
  455. | | | | *-hrSWRunParameters
  456. | | | *-hrSWRunEntry
  457. | | *-hrSWRunTable
  458. | *-hrSWRun
  459. */
  460. UINT
  461. GetHrSWRunParameters(
  462. OUT InternationalDisplayString *outvalue ,
  463. IN Access_Credential *access ,
  464. IN InstanceName *instance )
  465. {
  466. ULONG index; /* As fetched from instance structure */
  467. CACHEROW *row; /* Row entry fetched from cache */
  468. /*
  469. | Grab the instance information
  470. */
  471. index = GET_INSTANCE(0);
  472. /*
  473. | Use it to find the right entry in the cache
  474. */
  475. if ((row = FindTableRow(index, &hrSWRunTable_cache)) == NULL) {
  476. return SNMP_ERRORSTATUS_GENERR;
  477. }
  478. /*
  479. | Return the Parameter string that was computed at cache-build time.
  480. | NOTE: This string might be NULL.
  481. */
  482. if (row->attrib_list[HRSR_PARAM].u.string_value == NULL) {
  483. outvalue->length = 0;
  484. }
  485. else {
  486. outvalue->length = strlen(row->attrib_list[HRSR_PARAM].u.string_value);
  487. outvalue->string = row->attrib_list[HRSR_PARAM].u.string_value;
  488. if (outvalue->length > 128) {
  489. outvalue->length = 128; /* Truncate */
  490. }
  491. }
  492. return SNMP_ERRORSTATUS_NOERROR ;
  493. } /* end of GetHrSWRunParameters() */
  494. /*
  495. * GetHrSWRunType
  496. * The type of this software.
  497. *
  498. * Gets the value for HrSWRunType.
  499. *
  500. * Arguments:
  501. *
  502. * outvalue address to return variable value
  503. * accesss Reserved for future security use
  504. * instance address of instance name as ordered native
  505. * data type(s)
  506. *
  507. * Return Codes:
  508. *
  509. * Standard PDU error codes.
  510. *
  511. * SNMP_ERRORSTATUS_NOERROR Successful get
  512. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  513. * mibtget.c v0.10
  514. *
  515. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  516. | hrSWRunType
  517. |
  518. | ACCESS SYNTAX
  519. | read-only INTEGER {unknown(1),operatingSystem(2),deviceDriver(3),
  520. | application(4)}
  521. |
  522. | "The type of this software."
  523. |
  524. | DISCUSSION:
  525. |
  526. | <POA-19> This information is not extracted by the sample PVIEW code from the
  527. | performance monitoring statistics kept in the Registry. If this information
  528. | is available from the Registry or some other source, I need to acquire the
  529. | description of how to get it.
  530. |
  531. | >>>>>>>>
  532. | <POA-19> I am not sure whether this information is included in the perfmon
  533. | data block. I will investigate further.
  534. | >>>>>>>>
  535. |
  536. |============================================================================
  537. | 1.3.6.1.2.1.25.4.2.1.6.<instance>
  538. | | | | |
  539. | | | | *-hrSWRunType
  540. | | | *-hrSWRunEntry
  541. | | *-hrSWRunTable
  542. | *-hrSWRun
  543. */
  544. UINT
  545. GetHrSWRunType(
  546. OUT INTSWType *outvalue ,
  547. IN Access_Credential *access ,
  548. IN InstanceName *instance )
  549. {
  550. ULONG index; /* As fetched from instance structure */
  551. CACHEROW *row; /* Row entry fetched from cache */
  552. /*
  553. | Grab the instance information
  554. */
  555. index = GET_INSTANCE(0);
  556. /*
  557. | Use it to find the right entry in the cache
  558. */
  559. if ((row = FindTableRow(index, &hrSWRunTable_cache)) == NULL) {
  560. return SNMP_ERRORSTATUS_GENERR;
  561. }
  562. *outvalue = row->attrib_list[HRSR_TYPE].u.number_value;
  563. return SNMP_ERRORSTATUS_NOERROR ;
  564. } /* end of GetHrSWRunType() */
  565. /*
  566. * GetHrSWRunStatus
  567. * The status of this running piece of software. Setting this value to
  568. * invalid(4) shall cause this software to stop running and be
  569. *
  570. * Gets the value for HrSWRunStatus.
  571. *
  572. * Arguments:
  573. *
  574. * outvalue address to return variable value
  575. * accesss Reserved for future security use
  576. * instance address of instance name as ordered native
  577. * data type(s)
  578. *
  579. * Return Codes:
  580. *
  581. * Standard PDU error codes.
  582. *
  583. * SNMP_ERRORSTATUS_NOERROR Successful get
  584. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  585. * mibtget.c v0.10
  586. *
  587. | =============== From WebEnable Design Spec Rev 3 04/11/97==================
  588. | hrSWRunStatus
  589. |
  590. | ACCESS SYNTAX
  591. | read-write INTEGER {
  592. | running(1),
  593. | runnable(2), -- waiting for resource (CPU, memory, IO)
  594. | notRunnable(3), -- loaded but waiting for event
  595. | invalid(4) -- not loaded
  596. | }
  597. |
  598. | "The status of this running piece of software. Setting this value to
  599. | invalid(4) shall cause this software to stop running and to be unloaded."
  600. |
  601. | DISCUSSION:
  602. |
  603. | <POA-20> For an SNMP "GET" on this attribute, this information is not extracted
  604. | by the sample PVIEW code from the performance monitoring statistics kept in
  605. | the Registry. If this information is available from the Registry or some
  606. | other source, I need to acquire the description of how to get it.
  607. |
  608. | RESOLVED >>>>>>>
  609. | <POA-20> I think running and notRunnable will be all that are applicable
  610. | here (that latter being returned in situations which are currently labeled
  611. | "not responding").
  612. | RESOLVED >>>>>>>
  613. |
  614. |============================================================================
  615. | 1.3.6.1.2.1.25.4.2.1.7.<instance>
  616. | | | | |
  617. | | | | *-hrSWRunStatus
  618. | | | *-hrSWRunEntry
  619. | | *-hrSWRunTable
  620. | *-hrSWRun
  621. */
  622. UINT
  623. GetHrSWRunStatus(
  624. OUT INThrSWRunStatus *outvalue ,
  625. IN Access_Credential *access ,
  626. IN InstanceName *instance )
  627. {
  628. ULONG index; /* As fetched from instance structure */
  629. CACHEROW *row; /* Row entry fetched from cache */
  630. /*
  631. | Grab the instance information
  632. */
  633. index = GET_INSTANCE(0);
  634. /*
  635. | Use it to find the right entry in the cache
  636. */
  637. if ((row = FindTableRow(index, &hrSWRunTable_cache)) == NULL) {
  638. return SNMP_ERRORSTATUS_GENERR;
  639. }
  640. *outvalue = row->attrib_list[HRSR_STATUS].u.number_value;
  641. return SNMP_ERRORSTATUS_NOERROR ;
  642. } /* end of GetHrSWRunStatus() */
  643. /*
  644. * SetHrSWRunStatus
  645. * The status of this running piece of software. Setting this value to
  646. * invalid(4) shall cause this software to stop running and be
  647. *
  648. * Sets the HrSWRunStatus value.
  649. *
  650. * Arguments:
  651. *
  652. * invalue address of value to set the variable
  653. * outvalue address to return the set variable value
  654. * access Reserved for future security use
  655. * instance address of instance name as ordered native
  656. * data type(s)
  657. *
  658. * Return Codes:
  659. *
  660. * Standard PDU error codes.
  661. *
  662. * SNMP_ERRORSTATUS_NOERROR Successful get
  663. * SNMP_ERRORSTATUS_BADVALUE Set value not in range
  664. * SNMP_ERRORSTATUS_GENERR Catch-all failure code
  665. * mibtset.ntc v0.10
  666. */
  667. UINT
  668. SetHrSWRunStatus(
  669. IN INThrSWRunStatus *invalue ,
  670. OUT INThrSWRunStatus *outvalue ,
  671. IN Access_Credential *access ,
  672. IN InstanceName *instance )
  673. {
  674. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  675. } /* end of SetHrSWRunStatus() */
  676. /*
  677. * HrSWRunEntryFindInstance
  678. *
  679. * This routine is used to verify that the specified instance is
  680. * valid.
  681. *
  682. * Arguments:
  683. *
  684. * FullOid Address for the full oid - group, variable,
  685. * and instance information
  686. * instance Address for instance specification as an oid
  687. *
  688. * Return Codes:
  689. *
  690. * SNMP_ERRORSTATUS_NOERROR Instance found and valid
  691. * SNMP_ERRORSTATUS_NOSUCHNAME Invalid instance
  692. *
  693. */
  694. UINT
  695. HrSWRunEntryFindInstance( IN ObjectIdentifier *FullOid ,
  696. IN OUT ObjectIdentifier *instance )
  697. {
  698. UINT tmp_instance ;
  699. //
  700. // Developer instrumentation code to find appropriate instance goes here.
  701. // For non-tables, it is not necessary to modify this routine. However, if
  702. // there is any context that needs to be set, it can be done here.
  703. //
  704. if ( FullOid->idLength <= HRSWRUNENTRY_VAR_INDEX )
  705. // No instance was specified
  706. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  707. else if ( FullOid->idLength != HRSWRUNENTRY_VAR_INDEX + 1 )
  708. // Instance length is more than 1
  709. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  710. else
  711. // The only valid instance for a non-table are instance 0. If this
  712. // is a non-table, the following code validates the instances. If this
  713. // is a table, developer modification is necessary below.
  714. tmp_instance = FullOid->ids[ HRSWRUNENTRY_VAR_INDEX ] ;
  715. /*
  716. | Check for age-out and possibly refresh the entire cache for the
  717. | hrSWRun table before we check to see if the instance is there.
  718. */
  719. if (hrSWRunCache_Refresh() == FALSE) {
  720. return SNMP_ERRORSTATUS_GENERR;
  721. }
  722. /*
  723. | For hrSWRun, the instance arc(s) is a single arc, and it must
  724. | correctly select an entry in the hrSWRun Table cache.
  725. | Check that here.
  726. */
  727. if ( FindTableRow(tmp_instance, &hrSWRunTable_cache) == NULL ) {
  728. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  729. }
  730. else
  731. {
  732. // the instance is valid. Create the instance portion of the OID
  733. // to be returned from this call.
  734. instance->ids[ 0 ] = tmp_instance ;
  735. instance->idLength = 1 ;
  736. }
  737. return SNMP_ERRORSTATUS_NOERROR ;
  738. } /* end of HrSWRunEntryFindInstance() */
  739. /*
  740. * HrSWRunEntryFindNextInstance
  741. *
  742. * This routine is called to get the next instance. If no instance
  743. * was passed than return the first instance (1).
  744. *
  745. * Arguments:
  746. *
  747. * FullOid Address for the full oid - group, variable,
  748. * and instance information
  749. * instance Address for instance specification as an oid
  750. *
  751. * Return Codes:
  752. *
  753. * SNMP_ERRORSTATUS_NOERROR Instance found and valid
  754. * SNMP_ERRORSTATUS_NOSUCHNAME Invalid instance
  755. *
  756. */
  757. UINT
  758. HrSWRunEntryFindNextInstance( IN ObjectIdentifier *FullOid ,
  759. IN OUT ObjectIdentifier *instance )
  760. {
  761. //
  762. // Developer supplied code to find the next instance of class goes here.
  763. // If this is a class with cardinality 1, no modification of this routine
  764. // is necessary unless additional context needs to be set.
  765. // If the FullOid does not specify an instance, then the only instance
  766. // of the class is returned. If this is a table, the first row of the
  767. // table is returned.
  768. //
  769. // If an instance is specified and this is a non-table class, then NOSUCHNAME
  770. // is returned so that correct MIB rollover processing occurs. If this is
  771. // a table, then the next instance is the one following the current instance.
  772. // If there are no more instances in the table, return NOSUCHNAME.
  773. //
  774. CACHEROW *row;
  775. ULONG tmp_instance;
  776. if ( FullOid->idLength <= HRSWRUNENTRY_VAR_INDEX )
  777. {
  778. /*
  779. | Too short: must return the instance arc that selects the first
  780. | entry in the table if there is one.
  781. */
  782. tmp_instance = 0;
  783. }
  784. else {
  785. /*
  786. | There is at least one instance arc. Even if it is the only arc
  787. | we use it as the "index" in a request for the "NEXT" one.
  788. */
  789. tmp_instance = FullOid->ids[ HRSWRUNENTRY_VAR_INDEX ] ;
  790. }
  791. /*
  792. | Check for age-out and possibly refresh the entire cache for the
  793. | hrSWRun table before we check to see if the instance is there.
  794. */
  795. if (hrSWRunCache_Refresh() == FALSE) {
  796. return SNMP_ERRORSTATUS_GENERR;
  797. }
  798. /* Now go off and try to find the next instance in the table */
  799. if ((row = FindNextTableRow(tmp_instance, &hrSWRunTable_cache)) == NULL) {
  800. return SNMP_ERRORSTATUS_NOSUCHNAME ;
  801. }
  802. instance->ids[ 0 ] = row->index ;
  803. instance->idLength = 1 ;
  804. return SNMP_ERRORSTATUS_NOERROR ;
  805. } /* end of HrSWRunEntryFindNextInstance() */
  806. /*
  807. * HrSWRunEntryConvertInstance
  808. *
  809. * This routine is used to convert the object id specification of an
  810. * instance into an ordered native representation. The object id format
  811. * is that object identifier that is returned from the Find Instance
  812. * or Find Next Instance routines. It is NOT the full object identifier
  813. * that contains the group and variable object ids as well. The native
  814. * representation is an argc/argv-like structure that contains the
  815. * ordered variables that define the instance. This is specified by
  816. * the MIB's INDEX clause. See RFC 1212 for information about the INDEX
  817. * clause.
  818. *
  819. *
  820. * Arguments:
  821. *
  822. * oid_spec Address of the object id instance specification
  823. * native_spec Address to return the ordered native instance
  824. * specification
  825. *
  826. * Return Codes:
  827. *
  828. * SUCCESS Conversion complete successfully
  829. * FAILURE Unable to convert object id into native format
  830. *
  831. */
  832. UINT
  833. HrSWRunEntryConvertInstance( IN ObjectIdentifier *oid_spec ,
  834. IN OUT InstanceName *native_spec )
  835. {
  836. static char *array; /* The address of this (char *) is passed back */
  837. /* as though it were an array of length 1 of these */
  838. /* types. */
  839. static ULONG inst; /* The address of this ULONG is passed back */
  840. /* (Obviously, no "free()" action is needed) */
  841. /* We only expect the one arc in "oid_spec" */
  842. inst = oid_spec->ids[0];
  843. array = (char *) &inst;
  844. native_spec->count = 1;
  845. native_spec->array = &array;
  846. return SUCCESS ;
  847. } /* end of HrSWRunEntryConvertInstance() */
  848. /*
  849. * HrSWRunEntryFreeInstance
  850. *
  851. * This routine is used to free an ordered native representation of an
  852. * instance name.
  853. *
  854. * Arguments:
  855. *
  856. * instance Address to return the ordered native instance
  857. * specification
  858. *
  859. * Return Codes:
  860. *
  861. *
  862. */
  863. void
  864. HrSWRunEntryFreeInstance( IN OUT InstanceName *instance )
  865. {
  866. //
  867. // Developer supplied code to free native representation of instance name goes here.
  868. //
  869. } /* end of HrSWRunEntryFreeInstance() */
  870. /*
  871. | End of Generated Code
  872. */
  873. /* Gen_HrSWRun_Cache - Generate a initial cache for HrSWRun(Perf) Table */
  874. /* Gen_HrSWRun_Cache - Generate a initial cache for HrSWRun(Perf) Table */
  875. /* Gen_HrSWRun_Cache - Generate a initial cache for HrSWRun(Perf) Table */
  876. BOOL
  877. Gen_HrSWRun_Cache(
  878. void
  879. )
  880. /*
  881. | EXPLICIT INPUTS:
  882. |
  883. | None.
  884. |
  885. | IMPLICIT INPUTS:
  886. |
  887. | The module-local head of the cache for the HrSWRun table,
  888. | "hrSWRunTable_cache".
  889. |
  890. | OUTPUTS:
  891. |
  892. | On Success:
  893. | Function returns TRUE indicating that the cache has been fully
  894. | populated with all "static" cache-able values. This function populates
  895. | the hrSWRun Table cache, but this cache also includes the two
  896. | attributes for the hrSWRunPerf Table. So in effect, one cache serves
  897. | two tables, but the hrSWRunPerf table is a "one-to-one" extension
  898. | of hrSWRun table.. that is a row in hrSWRun always has a corresponding
  899. | "two-entry" row in hrSWRunPerf.
  900. |
  901. | On any Failure:
  902. | Function returns FALSE (indicating "not enough storage").
  903. |
  904. | THE BIG PICTURE:
  905. |
  906. | At subagent startup time, the cache for each table in the MIB is
  907. | populated with rows for each row in the table. This function is
  908. | invoked by the start-up code in "UserMibInit()" ("MIB.C") to
  909. | populate the cache for the HrSWRun table (which also serves the
  910. | hrSWRunPerf Table).
  911. |
  912. | It is also re-entered whenever a request for information from this
  913. | cache comes in and the cache is older than a certain age (symbol
  914. | "CACHE_MAX_AGE" defined at the beginning of this module). In this
  915. | case the cache is rebuilt, and in this way this function is different
  916. | from all the other "Gen_*_Cache()" functions which only build their
  917. | caches once (in the initial release).
  918. |
  919. |
  920. | OTHER THINGS TO KNOW:
  921. |
  922. | There is one of these function for every table that has a cache.
  923. | Each cachehead is found in the respective table's source file.
  924. |
  925. | The strategy on getting running software enumerated revolves around
  926. | NtQuerySystemInformation(SystemProcessInformation...) invocation.
  927. |
  928. | Once we have a list of processes, additional information (such as
  929. | the parameters on the command-line) are fetched by opening the
  930. | process (if possible) and reading process memory.
  931. |
  932. | Note that unlike the other cache's in the initial release, this cache
  933. | for hrSWRun and hrSWRunPerf is updated before it is read if it is
  934. | older than a specified period of time (set by #define at the beginning
  935. | of this file).
  936. |
  937. |============================================================================
  938. | 1.3.6.1.2.1.25.4.1.0
  939. | | |
  940. | | *-hrSWOSIndex
  941. | *-hrSWRun
  942. |
  943. | 1.3.6.1.2.1.25.4.2.1..
  944. | | | |
  945. | | | *-hrSWRunEntry
  946. | | *-hrSWRunTable
  947. | *-hrSWRun
  948. */
  949. #define LARGE_BUFFER_SIZE (4096*8)
  950. #define INCREMENT_BUFFER_SIZE (4096*2)
  951. {
  952. static /* Initial ProcessBuffer size */
  953. DWORD ProcessBufSize = LARGE_BUFFER_SIZE;
  954. static
  955. LPBYTE pProcessBuffer = NULL; /* Re-used and re-expanded as needed */
  956. PSYSTEM_PROCESS_INFORMATION
  957. ProcessInfo; /* --> Next process to process */
  958. ULONG ProcessBufferOffset=0; /* Accumulating offset cell */
  959. NTSTATUS ntstatus; /* Generic return status */
  960. DWORD dwReturnedBufferSize; /* From NtQuerySystemInformation() */
  961. /*
  962. | Blow away any old copy of the cache
  963. */
  964. DestroyTable( &hrSWRunTable_cache );
  965. /*
  966. | Grab an initial buffer for Process Information
  967. */
  968. if (pProcessBuffer == NULL) {
  969. /* allocate a new block */
  970. if ((pProcessBuffer = malloc ( ProcessBufSize )) == NULL) {
  971. return ( FALSE );
  972. }
  973. }
  974. /*
  975. | Go for a (new/refreshed) buffer of current Process Info
  976. */
  977. while( (ntstatus = NtQuerySystemInformation(
  978. SystemProcessInformation,
  979. pProcessBuffer,
  980. ProcessBufSize,
  981. &dwReturnedBufferSize
  982. )
  983. ) == STATUS_INFO_LENGTH_MISMATCH ) {
  984. /* expand buffer & retry */
  985. ProcessBufSize += INCREMENT_BUFFER_SIZE;
  986. if ( !(pProcessBuffer = realloc(pProcessBuffer,ProcessBufSize)) ) {
  987. return ( FALSE );
  988. }
  989. }
  990. /*
  991. | Freshen the time on the cache
  992. |
  993. | Get the current system-time in 100ns intervals . . . */
  994. ntstatus = NtQuerySystemTime (&cache_time);
  995. /*
  996. | Loop over each instance of Process Information in the ProcessBuffer
  997. | and build a row in the cache for hrSWRun and hrSWRunPerf tables.
  998. */
  999. for (ProcessInfo = (PSYSTEM_PROCESS_INFORMATION) pProcessBuffer;
  1000. ; /* Exit check below */
  1001. ProcessBufferOffset += ProcessInfo->NextEntryOffset,
  1002. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)
  1003. &pProcessBuffer[ProcessBufferOffset]
  1004. ) {
  1005. /* Add a Row to the cache */
  1006. if (AddHrSWRunRow(ProcessInfo) != TRUE) {
  1007. return ( FALSE ); // Out of memory
  1008. }
  1009. /* If this is the last process, bag it */
  1010. if (ProcessInfo->NextEntryOffset == 0) {
  1011. break;
  1012. }
  1013. }
  1014. #if defined(CACHE_DUMP)
  1015. PrintCache(&hrSWRunTable_cache);
  1016. #endif
  1017. /* Cache (re)-build successful */
  1018. return ( TRUE );
  1019. }
  1020. /* AddHrSWRunRow - Generate another Row Entry in HrSWRun/Perf Table */
  1021. /* AddHrSWRunRow - Generate another Row Entry in HrSWRun/Perf Table */
  1022. /* AddHrSWRunRow - Generate another Row Entry in HrSWRun/Perf Table */
  1023. static BOOL
  1024. AddHrSWRunRow(
  1025. PSYSTEM_PROCESS_INFORMATION ProcessInfo /* --> Next process to process */
  1026. )
  1027. /*
  1028. | EXPLICIT INPUTS:
  1029. |
  1030. | "ProcessInfo" points to the next process (as described by a
  1031. | SYSTEM_PROCESS_INFORMATION structure) for which a row is to be
  1032. | inserted into the HrSWRun(Perf) table cache.
  1033. |
  1034. | IMPLICIT INPUTS:
  1035. |
  1036. | The module-local head of the cache for the HrDevice table,
  1037. | "hrSWRunTable_cache".
  1038. |
  1039. | OUTPUTS:
  1040. |
  1041. | On Success:
  1042. | Function creates a new row entry populated with all "static" cache-able
  1043. | values for HrSWRun(Perf) table and returns TRUE. Note that if the
  1044. | process is the "System Process", the row entry index is stored in
  1045. | module cell "SWOSIndex" for reference by code in "HRSWRUN.C".
  1046. |
  1047. | On any Failure:
  1048. | Function returns FALSE (indicating "not enough storage" or other
  1049. | internal logic error).
  1050. |
  1051. |
  1052. | THE BIG PICTURE:
  1053. |
  1054. | At subagent startup time, the cache for each table in the MIB is
  1055. | populated with rows for each row in the table. This function is
  1056. | invoked by the cache-build code in "Gen_HrSWRun_Cache()" above.
  1057. |
  1058. | OTHER THINGS TO KNOW:
  1059. |
  1060. | The cache being (re)built by this function serves two tables, hrSWRun
  1061. | and hrSWRunPerf.
  1062. |
  1063. | In general, we use the Process's "ProcessID" as the index in the
  1064. | hrSWRun(Perf) table. However special handling is done for the Idle
  1065. | Process because it's Process ID is zero. We convert it to "1" to meet
  1066. | the SNMP requirement that indexes be greater than zero. We note that
  1067. | as of this writing, no process id of 1 is seen in build 1515 (the "System"
  1068. | process has a processID of 2).
  1069. |
  1070. | The "type" of software can be unknown(1), operatingSystem(2),
  1071. | deviceDriver(3) and application(4). We only detect the Idle and System
  1072. | processes (by their names) as "operatingSystem(2)", everything else
  1073. | is presumed "application(4)".
  1074. |
  1075. | As for "status", it can be running(1), runnable(2), notRunnable(3) or
  1076. | invalid(4). If the number of threads is greater than 0, it is presumed
  1077. | "running(1)", otherwise "invalid(4)".
  1078. */
  1079. #define ANSI_PNAME_LEN 256
  1080. {
  1081. ANSI_STRING pname; /* ANSI version of UNICODE process name */
  1082. CHAR pbuf[ANSI_PNAME_LEN+1]; /* Buffer for "pname" */
  1083. CHAR *pname_str; /* Pointer to our final process name */
  1084. CHAR *path_str=NULL; /* Pointer to our Path name */
  1085. CHAR *params=NULL; /* Pointer to any parameters fnd on cmdline*/
  1086. UINT type; /* SNMP code for type of software */
  1087. UINT status; /* SNMP code for the status of software */
  1088. CACHEROW *row; /* --> Cache structure for row-being built */
  1089. /*
  1090. | OK, the caller wants another row in the table, get a row-entry created.
  1091. */
  1092. if ((row = CreateTableRow( HRSR_ATTRIB_COUNT ) ) == NULL) {
  1093. return ( FALSE ); // Out of memory
  1094. }
  1095. /*
  1096. | Set up the standard-hrSWRun(Perf) attributes in the new row
  1097. */
  1098. type = 4; /* Presume "application(4)" type software */
  1099. if (ProcessInfo->NumberOfThreads > 0) {
  1100. status = 1; /* Presume "running(1)" for software status */
  1101. }
  1102. else {
  1103. status = 4; /* "invalid(4)", process on the way out */
  1104. }
  1105. /* =========== HrSWRunIndex ==========*/
  1106. row->attrib_list[HRSR_INDEX].attrib_type = CA_NUMBER;
  1107. row->attrib_list[HRSR_INDEX].u.unumber_value =
  1108. HandleToUlong(ProcessInfo->UniqueProcessId) ;
  1109. /* Special check for system idle process, roll it from 0 to 1 */
  1110. if (ProcessInfo->UniqueProcessId == 0) {
  1111. row->attrib_list[HRSR_INDEX].u.unumber_value = 1;
  1112. }
  1113. /* =========== HrSWRunName ==========*/
  1114. row->attrib_list[HRSR_NAME].attrib_type = CA_STRING;
  1115. /* If we actually have a process name for this process . . . */
  1116. if (ProcessInfo->ImageName.Buffer != NULL) {
  1117. /* Prep the STRING structure */
  1118. pname.Buffer = pbuf;
  1119. pname.MaximumLength = ANSI_PNAME_LEN;
  1120. /* Convert from Unicode */
  1121. RtlUnicodeStringToAnsiString(&pname, // Target string
  1122. (PUNICODE_STRING)&ProcessInfo->ImageName,//Src
  1123. FALSE); // = Don't Allocate buf
  1124. /*
  1125. | Here we parse not only the process name but any path that may be
  1126. | prepended to it. (We make no attempt to eliminate any ".EXE" that
  1127. | may be on the end of the image name).
  1128. |
  1129. | NOTE: If you are going to rip off this code, be aware that as-of
  1130. | build 1515, we NEVER seem to get an image name that has the
  1131. | path prepended on the front... so most of this code to skip
  1132. | the possibly-present path is almost certainly superfluous.
  1133. */
  1134. /* Try to "backup" until we hit any "\" */
  1135. if ( (pname_str = strrchr(pname.Buffer,'\\')) != NULL) {
  1136. pname_str++; /* Pop to first char after "\" */
  1137. }
  1138. else {
  1139. pname_str = pname.Buffer; /* Use entire string, no "\" found */
  1140. /*
  1141. | A piece of software with no path means it could be the "System"
  1142. | process. Check for that here.
  1143. */
  1144. if (strcmp(pname_str, "System") == 0) {
  1145. type = 2; /* Mark the software as "operatingSystem(2)" type */
  1146. /*
  1147. | We're processing the main System Process, so record it's index
  1148. | in module-level cell for reference from "HRSWRUN.C".
  1149. */
  1150. SWOSIndex = row->attrib_list[HRSR_INDEX].u.unumber_value;
  1151. }
  1152. }
  1153. }
  1154. else {
  1155. /* The system idle process has no name */
  1156. pname_str = "System Idle Process";
  1157. type = 2; /* Mark the software as "operatingSystem(2)" type */
  1158. }
  1159. /* Allocate cache storage and copy the process name to it */
  1160. if ( (row->attrib_list[HRSR_NAME].u.string_value
  1161. = ( LPSTR ) malloc(strlen(pname_str) + 1)) == NULL) {
  1162. return ( FALSE ); /* out of memory */
  1163. }
  1164. strcpy(row->attrib_list[HRSR_NAME].u.string_value, pname_str);
  1165. /*
  1166. | We bother to do the overhead of trying to extract path & parameters from
  1167. | the command-line that started the process by reading process memory
  1168. | only if the type of the software is "application(4)" and status is
  1169. | "runnable(2)".
  1170. */
  1171. if (status == 2 && type == 4) { /* If it is a runnable application . . . */
  1172. FetchProcessParams(ProcessInfo, &path_str, &params);
  1173. }
  1174. /* =========== HrSWRunPath ==========*/
  1175. row->attrib_list[HRSR_PATH].attrib_type = CA_STRING;
  1176. row->attrib_list[HRSR_PATH].u.string_value = NULL;
  1177. /* If we did detect a path . . . */
  1178. if (path_str != NULL) {
  1179. /* Allocate cache storage and copy the path string to it */
  1180. if ( (row->attrib_list[HRSR_PATH].u.string_value
  1181. = ( LPSTR ) malloc(strlen(path_str) + 1)) == NULL) {
  1182. return ( FALSE ); /* out of memory */
  1183. }
  1184. strcpy(row->attrib_list[HRSR_PATH].u.string_value, path_str);
  1185. }
  1186. /* =========== HrSWRunParameters ==========
  1187. row->attrib_list[HRSR_PARAM].attrib_type = CA_STRING;
  1188. row->attrib_list[HRSR_PARAM].u.string_value = NULL; /* In case of none */
  1189. /* If we did find parameters . . . */
  1190. if (params != NULL) {
  1191. /* Allocate cache storage and copy the parameter string to it */
  1192. if ( (row->attrib_list[HRSR_PARAM].u.string_value
  1193. = ( LPSTR ) malloc(strlen(params) + 1)) == NULL) {
  1194. return ( FALSE ); /* out of memory */
  1195. }
  1196. strcpy(row->attrib_list[HRSR_PARAM].u.string_value, params);
  1197. }
  1198. /* =========== HrSWRunType ========== */
  1199. row->attrib_list[HRSR_TYPE].attrib_type = CA_NUMBER;
  1200. row->attrib_list[HRSR_TYPE].u.unumber_value = type;
  1201. /* =========== HrSWRunStatus ========== */
  1202. row->attrib_list[HRSR_STATUS].attrib_type = CA_NUMBER;
  1203. row->attrib_list[HRSR_STATUS].u.unumber_value = status;
  1204. /*
  1205. | For hrSWRunPerf Table:
  1206. */
  1207. /* =========== HrSWRunPerfCPU ==========
  1208. | UserTime + KernelTime are in 100ns (1/10th of a millionth of a second)
  1209. | units and HrSWRunPerfCPU is supposed to be in 1/100th of a second units.
  1210. |
  1211. | So .01 - second intervals
  1212. | is .010 000 0 - 100nanoseconds intervals,
  1213. |
  1214. | so dividing 100ns intervals by 100,000 gives centi-seconds.
  1215. */
  1216. row->attrib_list[HRSP_CPU].attrib_type = CA_NUMBER;
  1217. row->attrib_list[HRSP_CPU].u.unumber_value = (ULONG)
  1218. ((ProcessInfo->UserTime.QuadPart + ProcessInfo->KernelTime.QuadPart) / 100000);
  1219. /* =========== HrSWRunPerfMem ========== */
  1220. row->attrib_list[HRSP_MEM].attrib_type = CA_NUMBER;
  1221. row->attrib_list[HRSP_MEM].u.unumber_value =
  1222. (ULONG)(ProcessInfo->WorkingSetSize / 1024);
  1223. /*
  1224. | Now insert the filled-in CACHEROW structure into the
  1225. | cache-list for the hrSWRun(Perf) Table.
  1226. */
  1227. if (AddTableRow(row->attrib_list[HRSR_INDEX].u.unumber_value, /* Index */
  1228. row, /* Row */
  1229. &hrSWRunTable_cache /* Cache */
  1230. ) == FALSE) {
  1231. return ( FALSE ); /* Internal Logic Error! */
  1232. }
  1233. return ( TRUE );
  1234. }
  1235. /* hrSWRunCache_Refresh - hrSWRun(Perf) Cache Refresh-Check Routine */
  1236. /* hrSWRunCache_Refresh - hrSWRun(Perf) Cache Refresh-Check Routine */
  1237. /* hrSWRunCache_Refresh - hrSWRun(Perf) Cache Refresh-Check Routine */
  1238. BOOL
  1239. hrSWRunCache_Refresh(
  1240. void
  1241. )
  1242. /*
  1243. | EXPLICIT INPUTS:
  1244. |
  1245. | None.
  1246. |
  1247. | IMPLICIT INPUTS:
  1248. |
  1249. | The "hrSWRunTable_cache" CACHEHEAD structure and the time when
  1250. | it was last refreshed in module-local cell "cache_time".
  1251. |
  1252. | OUTPUTS:
  1253. |
  1254. | On Success/Failure:
  1255. | The function returns TRUE. Only if the cache-time has aged-out
  1256. | is the cache actually rebuilt.
  1257. |
  1258. | On any Failure:
  1259. | If during a rebuild there is an error, this function returns FALSE.
  1260. | The state of the cache is indeterminate.
  1261. |
  1262. | THE BIG PICTURE:
  1263. |
  1264. | This function is invoked before any reference is made to any SNMP
  1265. | variable in the hrSWRun or hrSWRunPerf table. It checks to see
  1266. | if the cache needs to be rebuilt based on the last time it was built.
  1267. |
  1268. | The calls to this function are strategically located in the
  1269. | "FindInstance" and "FindNextInstance" functions in "HRSWRUNE.C"
  1270. | (this module) and "HRSWPREN.C" (for the RunPerf table) as well
  1271. | as in "HRSWRUN.C" for the stand-alone attribute "hrSWOSIndex".
  1272. |
  1273. | OTHER THINGS TO KNOW:
  1274. |
  1275. */
  1276. {
  1277. LARGE_INTEGER now_time; /* Current System time in 100 ns ticks */
  1278. /* Get the current time in 100 ns ticks*/
  1279. NtQuerySystemTime (&now_time);
  1280. /* If the cache is older than the maximum allowed time (in ticks) . . . */
  1281. if ( (now_time.QuadPart - cache_time.QuadPart) > (CACHE_MAX_AGE * 10000000) ){
  1282. return ( Gen_HrSWRun_Cache() );
  1283. }
  1284. return ( TRUE ); /* No Error (because no refresh) */
  1285. }
  1286. /* FetchProcessParams - Fetch Path & Parameter String from Process Cmd line */
  1287. /* FetchProcessParams - Fetch Path & Parameter String from Process Cmd line */
  1288. /* FetchProcessParams - Fetch Path & Parameter String from Process Cmd line */
  1289. void
  1290. FetchProcessParams(
  1291. PSYSTEM_PROCESS_INFORMATION ProcessInfo, /* Process for parameters */
  1292. CHAR **path_str, /* Returned PATH string */
  1293. CHAR **params_str /* Returned Parameters string */
  1294. )
  1295. /*
  1296. | EXPLICIT INPUTS:
  1297. |
  1298. | "ProcessInfo" points to the process (as described by a
  1299. | SYSTEM_PROCESS_INFORMATION structure) for which the path & parameters
  1300. | (from the command-line) are desired.
  1301. |
  1302. | "path_str" is the address of a pointer to be set to any "path" string.
  1303. | "params" is the address of a pointer to be set to any "parameters"
  1304. | string.
  1305. |
  1306. | IMPLICIT INPUTS:
  1307. |
  1308. | None.
  1309. |
  1310. | OUTPUTS:
  1311. |
  1312. | On Success:
  1313. | Function returns pointers to a static buffer containing the
  1314. | path & parameters section of the command line. There may be nothing
  1315. | in the buffer (ie just the null-termination).
  1316. |
  1317. | On any Failure:
  1318. | Function returns NULLS indicating a problem was encountered
  1319. | attempting to obtain the command-line image from which the
  1320. | path & parameter portion is to be extracted, or indicating that
  1321. | one or both were not present.
  1322. |
  1323. | THE BIG PICTURE:
  1324. |
  1325. | Called from "AddHrSWRunRow()" above, this is a helper function
  1326. | that serves to isolate the code lifted from "TLIST" from
  1327. | the rest of the subagent.
  1328. |
  1329. | OTHER THINGS TO KNOW:
  1330. |
  1331. | The black magic here was lifted from sections of "TLIST".
  1332. */
  1333. {
  1334. HANDLE hProcess;
  1335. PEB Peb;
  1336. NTSTATUS Status;
  1337. PROCESS_BASIC_INFORMATION BasicInfo;
  1338. WCHAR szT[MAX_PATH * 2];
  1339. UNICODE_STRING u_param;
  1340. RTL_USER_PROCESS_PARAMETERS ProcessParameters;
  1341. #define ANSI_PARAM_LEN (MAX_PATH * 2)
  1342. ANSI_STRING param; /* ANSI version of UNICODE command line */
  1343. static
  1344. CHAR pbuf[ANSI_PARAM_LEN+1]; /* Buffer for "parameters" */
  1345. CHAR *param_str; /* Pointer to our final parameter string */
  1346. SIZE_T dwbytesret; /* Count of bytes read from process memory */
  1347. /* Presume failure/nothing obtained */
  1348. *path_str = NULL;
  1349. *params_str = NULL;
  1350. /* get a handle to the process */
  1351. hProcess = OpenProcess(PROCESS_ALL_ACCESS,
  1352. FALSE,
  1353. HandleToUlong(ProcessInfo->UniqueProcessId));
  1354. if (!hProcess) {
  1355. return;
  1356. }
  1357. Status = NtQueryInformationProcess(hProcess, ProcessBasicInformation,
  1358. &BasicInfo, sizeof(BasicInfo), NULL);
  1359. if (!NT_SUCCESS(Status)) {
  1360. CloseHandle(hProcess);
  1361. return;
  1362. }
  1363. // get the PEB
  1364. if (ReadProcessMemory(hProcess, BasicInfo.PebBaseAddress, &Peb,
  1365. sizeof(PEB), NULL)) {
  1366. // get the processparameters
  1367. if (ReadProcessMemory(hProcess, Peb.ProcessParameters,
  1368. &ProcessParameters, sizeof(ProcessParameters), NULL)) {
  1369. // get cmdline
  1370. if (ReadProcessMemory(hProcess,
  1371. ProcessParameters.CommandLine.Buffer,
  1372. szT,
  1373. sizeof(szT),
  1374. &dwbytesret
  1375. )
  1376. ) {
  1377. CHAR *scanner; /* Used for parsing the command-line */
  1378. /* Prep the STRING structure */
  1379. param.Buffer = pbuf;
  1380. param.MaximumLength = ANSI_PARAM_LEN;
  1381. u_param.Length = (USHORT) dwbytesret;
  1382. u_param.Buffer = szT;
  1383. /* Convert from Unicode */
  1384. RtlUnicodeStringToAnsiString(&param, /* Target string */
  1385. &u_param, /* Src */
  1386. FALSE); /* = Don't Allocate buf */
  1387. /*
  1388. | OK, we can have the following situations:
  1389. |
  1390. | 1) "\system\system32\smss.exe -parameter1 -parameter2"
  1391. | --------path----- -------parameters------
  1392. |
  1393. | 2) "\system\system32\smss.exe"
  1394. | --------path-----
  1395. |
  1396. | 3) "smss.exe -parameter1 -parameter2"
  1397. | -------parameters------
  1398. |
  1399. | and we want to handle this by returning "path" and "parameter"
  1400. | as shown, where:
  1401. |
  1402. | 1) both path and parameters are present
  1403. | 2) only path is present
  1404. | 3) only parameters are present
  1405. |
  1406. | We do this:
  1407. |
  1408. | - Scan forward for a blank.
  1409. | If we get one:
  1410. | + return the address following it as "parameters"
  1411. | + set the blank to a null byte (cutting off parameters)
  1412. | If not:
  1413. | + return NULL as "parameters"
  1414. |
  1415. | ----Parameters are done.
  1416. |
  1417. | - Perform a reverse search for "\" on whatever is now in the
  1418. | buffer
  1419. | If we find a "\":
  1420. | + Step forward one character and turn it into a null
  1421. | byte (turning buffer into string containing path).
  1422. | + Return the buffer address as "path"
  1423. | If not:
  1424. | + return NULL as "path"
  1425. */
  1426. /* Parameter */
  1427. if ((scanner = strchr(pbuf, ' ')) != NULL) {
  1428. /* Return address of char after blank as start of parameters */
  1429. *params_str = (scanner + 1);
  1430. *scanner = '\0'; /* Terminate base string */
  1431. }
  1432. else {
  1433. /* No parameters */
  1434. *params_str = NULL;
  1435. }
  1436. /* Path */
  1437. if ((scanner = strrchr(pbuf, '\\')) != NULL) {
  1438. /* Terminate the path */
  1439. *(scanner+1) = '\0';
  1440. /* Return start of buffer as path */
  1441. *path_str = pbuf;
  1442. }
  1443. else {
  1444. /* No path */
  1445. *path_str = NULL;
  1446. }
  1447. CloseHandle(hProcess);
  1448. /* Return address of static ANSI string buffer */
  1449. return;
  1450. }
  1451. }
  1452. }
  1453. CloseHandle(hProcess);
  1454. /* Nothing back */
  1455. return;
  1456. }
  1457. #if defined(CACHE_DUMP)
  1458. /* debug_print_hrswrun - Prints a Row from HrSWRun(Perf) Table */
  1459. /* debug_print_hrswrun - Prints a Row from HrSWRun(Perf) Table */
  1460. /* debug_print_hrswrun - Prints a Row from HrSWRun(Perf) Table */
  1461. static void
  1462. debug_print_hrswrun(
  1463. CACHEROW *row /* Row in hrSWRun(Perf) table */
  1464. )
  1465. /*
  1466. | EXPLICIT INPUTS:
  1467. |
  1468. | "row" - points to the row to be dumped, if NULL, the function
  1469. | merely prints a suitable title.
  1470. |
  1471. | IMPLICIT INPUTS:
  1472. |
  1473. | - Symbols used to reference the attributes in the row entry.
  1474. | - File handle defined by OFILE, presumed to be open.
  1475. |
  1476. | OUTPUTS:
  1477. |
  1478. | On Success:
  1479. | Function prints a dump of the row in ASCII for debugging purposes
  1480. | on file handle OFILE.
  1481. |
  1482. | THE BIG PICTURE:
  1483. |
  1484. | Debugging only.
  1485. |
  1486. | OTHER THINGS TO KNOW:
  1487. */
  1488. {
  1489. if (row == NULL) {
  1490. fprintf(OFILE, "=================================\n");
  1491. fprintf(OFILE, "hrSWRun & hrSWRunPerf Table Cache\n");
  1492. fprintf(OFILE, "=================================\n");
  1493. return;
  1494. }
  1495. fprintf(OFILE, "HrSWRunIndex . . . . . . %d\n",
  1496. row->attrib_list[HRSR_INDEX].u.unumber_value);
  1497. fprintf(OFILE, "HrSWRunName. . . . . . . \"%s\"\n",
  1498. row->attrib_list[HRSR_NAME].u.string_value);
  1499. fprintf(OFILE, "HrSWRunPath. . . . . . . \"%s\"\n",
  1500. row->attrib_list[HRSR_PATH].u.string_value);
  1501. fprintf(OFILE, "HRSWRunParameters. . . . \"%s\"\n",
  1502. row->attrib_list[HRSR_PARAM].u.string_value);
  1503. fprintf(OFILE, "HrSWRunType. . . . . . . %d ",
  1504. row->attrib_list[HRSR_TYPE].u.unumber_value);
  1505. switch (row->attrib_list[HRSR_TYPE].u.unumber_value) {
  1506. case 1: fprintf(OFILE, "(unknown)\n"); break;
  1507. case 2: fprintf(OFILE, "(operatingSystem)\n"); break;
  1508. case 3: fprintf(OFILE, "(deviceDriver)\n"); break;
  1509. case 4: fprintf(OFILE, "(application)\n"); break;
  1510. default:
  1511. fprintf(OFILE, "(???)\n");
  1512. }
  1513. fprintf(OFILE, "HrSWRunStatus. . . . . . %d ",
  1514. row->attrib_list[HRSR_STATUS].u.unumber_value);
  1515. switch (row->attrib_list[HRSR_STATUS].u.unumber_value) {
  1516. case 1: fprintf(OFILE, "(running)\n"); break;
  1517. case 2: fprintf(OFILE, "(runnable)\n"); break;
  1518. case 3: fprintf(OFILE, "(notRunnable)\n"); break;
  1519. case 4: fprintf(OFILE, "(invalid)\n"); break;
  1520. default:
  1521. fprintf(OFILE, "(???)\n");
  1522. }
  1523. fprintf(OFILE, "HrSWRunPerfCpu . . . . . %d (Centi-seconds)\n",
  1524. row->attrib_list[HRSP_CPU].u.unumber_value);
  1525. fprintf(OFILE, "HrSWRunPerfMem . . . . . %d (Kbytes)\n",
  1526. row->attrib_list[HRSP_MEM].u.unumber_value);
  1527. }
  1528. #endif