info.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. /*++
  2. Copyright (c) 2014 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. info.c
  9. Abstract:
  10. This module implements support for the get and set system information
  11. calls.
  12. Author:
  13. Evan Green 10-Apr-2014
  14. Environment:
  15. Kernel
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <minoca/kernel/kernel.h>
  21. #include <minoca/fw/smbios.h>
  22. #include "kep.h"
  23. //
  24. // ---------------------------------------------------------------- Definitions
  25. //
  26. //
  27. // ------------------------------------------------------ Data Type Definitions
  28. //
  29. //
  30. // ----------------------------------------------- Internal Function Prototypes
  31. //
  32. KSTATUS
  33. KepGetSetSystemInformation (
  34. BOOL FromKernelMode,
  35. SYSTEM_INFORMATION_SUBSYSTEM Subsystem,
  36. UINTN InformationType,
  37. PVOID Data,
  38. PUINTN DataSize,
  39. BOOL Set
  40. );
  41. KSTATUS
  42. KepGetSetKeSystemInformation (
  43. BOOL FromKernelMode,
  44. KE_INFORMATION_TYPE InformationType,
  45. PVOID Data,
  46. PUINTN DataSize,
  47. BOOL Set
  48. );
  49. KSTATUS
  50. KepGetSystemVersion (
  51. PVOID Data,
  52. PUINTN DataSize,
  53. BOOL Set
  54. );
  55. KSTATUS
  56. KepGetFirmwareTable (
  57. PVOID Data,
  58. PUINTN DataSize,
  59. BOOL Set
  60. );
  61. KSTATUS
  62. KepGetFirmwareType (
  63. PVOID Data,
  64. PUINTN DataSize,
  65. BOOL Set
  66. );
  67. KSTATUS
  68. KepGetProcessorUsage (
  69. PVOID Data,
  70. PUINTN DataSize,
  71. BOOL Set
  72. );
  73. KSTATUS
  74. KepGetProcessorCount (
  75. PVOID Data,
  76. PUINTN DataSize,
  77. BOOL Set
  78. );
  79. KSTATUS
  80. KepGetKernelCommandLine (
  81. PVOID Data,
  82. PUINTN DataSize,
  83. BOOL Set
  84. );
  85. //
  86. // -------------------------------------------------------------------- Globals
  87. //
  88. SYSTEM_FIRMWARE_TYPE KeSystemFirmwareType = SystemFirmwareUnknown;
  89. PKERNEL_COMMAND_LINE KeCommandLine = NULL;
  90. //
  91. // ------------------------------------------------------------------ Functions
  92. //
  93. KERNEL_API
  94. KSTATUS
  95. KeGetSetSystemInformation (
  96. SYSTEM_INFORMATION_SUBSYSTEM Subsystem,
  97. UINTN InformationType,
  98. PVOID Data,
  99. PUINTN DataSize,
  100. BOOL Set
  101. )
  102. /*++
  103. Routine Description:
  104. This routine gets or sets system information.
  105. Arguments:
  106. Subsystem - Supplies the subsystem to query or set information of.
  107. InformationType - Supplies the information type, which is specific to
  108. the subsystem. The type of this value is generally
  109. <subsystem>_INFORMATION_TYPE (eg IO_INFORMATION_TYPE).
  110. Data - Supplies a pointer to the data buffer where the data is either
  111. returned for a get operation or given for a set operation.
  112. DataSize - Supplies a pointer that on input contains the size of the
  113. data buffer. On output, contains the required size of the data buffer.
  114. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  115. a set operation (TRUE).
  116. Return Value:
  117. STATUS_SUCCESS if the information was successfully queried or set.
  118. STATUS_BUFFER_TOO_SMALL if the buffer size specified was too small. The
  119. required buffer size will be returned in the data size parameter.
  120. STATUS_DATA_LENGTH_MISMATCH if the buffer size was not correct. The
  121. correct buffer size will be returned in the data size parameter.
  122. STATUS_INVALID_PARAMETER if the given subsystem or information type is
  123. not known.
  124. Other status codes on other failures.
  125. --*/
  126. {
  127. KSTATUS Status;
  128. Status = KepGetSetSystemInformation(TRUE,
  129. Subsystem,
  130. InformationType,
  131. Data,
  132. DataSize,
  133. Set);
  134. return Status;
  135. }
  136. KERNEL_API
  137. PKERNEL_ARGUMENT
  138. KeGetKernelArgument (
  139. PKERNEL_ARGUMENT Start,
  140. PCSTR Component,
  141. PCSTR Name
  142. )
  143. /*++
  144. Routine Description:
  145. This routine looks up a kernel command line argument.
  146. Arguments:
  147. Start - Supplies an optional pointer to the previous command line argument
  148. to start from. Supply NULL here initially.
  149. Component - Supplies a pointer to the component string to look up.
  150. Name - Supplies a pointer to the argument name to look up.
  151. Return Value:
  152. Returns a pointer to a matching kernel argument on success.
  153. NULL if no argument could be found.
  154. --*/
  155. {
  156. PKERNEL_ARGUMENT Argument;
  157. UINTN ArgumentIndex;
  158. PKERNEL_COMMAND_LINE Line;
  159. BOOL Match;
  160. Line = KeCommandLine;
  161. if (Line == NULL) {
  162. return NULL;
  163. }
  164. ArgumentIndex = 0;
  165. Argument = &(Line->Arguments[ArgumentIndex]);
  166. if (Start != NULL) {
  167. while ((ArgumentIndex < Line->ArgumentCount) &&
  168. (Argument != Start)) {
  169. Argument += 1;
  170. ArgumentIndex += 1;
  171. }
  172. //
  173. // If the argument was never found or is the last argument, nothing
  174. // new will be found.
  175. //
  176. if (ArgumentIndex >= Line->ArgumentCount - 1) {
  177. return NULL;
  178. }
  179. Argument += 1;
  180. ArgumentIndex += 1;
  181. }
  182. while (ArgumentIndex < Line->ArgumentCount) {
  183. Match = RtlAreStringsEqual(Component,
  184. Argument->Component,
  185. KERNEL_MAX_COMMAND_LINE);
  186. if (Match != FALSE) {
  187. Match = RtlAreStringsEqual(Name,
  188. Argument->Name,
  189. KERNEL_MAX_COMMAND_LINE);
  190. if (Match != FALSE) {
  191. return Argument;
  192. }
  193. }
  194. ArgumentIndex += 1;
  195. Argument += 1;
  196. }
  197. return NULL;
  198. }
  199. INTN
  200. KeSysGetSetSystemInformation (
  201. PVOID SystemCallParameter
  202. )
  203. /*++
  204. Routine Description:
  205. This routine implements the user mode system call for getting and setting
  206. system information.
  207. Arguments:
  208. SystemCallParameter - Supplies a pointer to the parameters supplied with
  209. the system call. This structure will be a stack-local copy of the
  210. actual parameters passed from user-mode.
  211. Return Value:
  212. STATUS_SUCCESS or positive integer on success.
  213. Error status code on failure.
  214. --*/
  215. {
  216. PVOID Buffer;
  217. UINTN CopySize;
  218. KSTATUS CopyStatus;
  219. PSYSTEM_CALL_GET_SET_SYSTEM_INFORMATION Request;
  220. KSTATUS Status;
  221. Buffer = NULL;
  222. Request = SystemCallParameter;
  223. //
  224. // Create a paged pool buffer to hold the data.
  225. //
  226. CopySize = 0;
  227. if (Request->DataSize != 0) {
  228. Buffer = MmAllocatePagedPool(Request->DataSize,
  229. KE_INFORMATION_ALLOCATION_TAG);
  230. if (Buffer == NULL) {
  231. Status = STATUS_INSUFFICIENT_RESOURCES;
  232. goto SysGetSetSystemInformationEnd;
  233. }
  234. CopySize = Request->DataSize;
  235. //
  236. // Copy the data into the kernel mode buffer.
  237. //
  238. Status = MmCopyFromUserMode(Buffer,
  239. Request->Data,
  240. Request->DataSize);
  241. if (!KSUCCESS(Status)) {
  242. goto SysGetSetSystemInformationEnd;
  243. }
  244. }
  245. Status = KepGetSetSystemInformation(FALSE,
  246. Request->Subsystem,
  247. Request->InformationType,
  248. Buffer,
  249. &(Request->DataSize),
  250. Request->Set);
  251. //
  252. // Copy the data back into user mode, even on set operations.
  253. //
  254. if (CopySize > Request->DataSize) {
  255. CopySize = Request->DataSize;
  256. }
  257. if (CopySize != 0) {
  258. CopyStatus = MmCopyToUserMode(Request->Data, Buffer, CopySize);
  259. if ((KSUCCESS(Status)) && (!KSUCCESS(CopyStatus))) {
  260. Status = CopyStatus;
  261. }
  262. }
  263. SysGetSetSystemInformationEnd:
  264. if (Buffer != NULL) {
  265. MmFreePagedPool(Buffer);
  266. }
  267. return Status;
  268. }
  269. //
  270. // --------------------------------------------------------- Internal Functions
  271. //
  272. KSTATUS
  273. KepGetSetSystemInformation (
  274. BOOL FromKernelMode,
  275. SYSTEM_INFORMATION_SUBSYSTEM Subsystem,
  276. UINTN InformationType,
  277. PVOID Data,
  278. PUINTN DataSize,
  279. BOOL Set
  280. )
  281. /*++
  282. Routine Description:
  283. This routine gets or sets system information.
  284. Arguments:
  285. FromKernelMode - Supplies a boolean indicating whether or not this request
  286. (and the buffer associated with it) originates from user mode (FALSE)
  287. or kernel mode (TRUE).
  288. Subsystem - Supplies the subsystem to query or set information of.
  289. InformationType - Supplies the information type, which is specific to
  290. the subsystem. The type of this value is generally
  291. <subsystem>_INFORMATION_TYPE (eg IO_INFORMATION_TYPE).
  292. Data - Supplies a pointer to the data buffer where the data is either
  293. returned for a get operation or given for a set operation.
  294. DataSize - Supplies a pointer that on input contains the size of the
  295. data buffer. On output, contains the required size of the data buffer.
  296. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  297. a set operation (TRUE).
  298. Return Value:
  299. STATUS_SUCCESS if the information was successfully queried or set.
  300. STATUS_BUFFER_TOO_SMALL if the buffer size specified was too small. The
  301. required buffer size will be returned in the data size parameter.
  302. STATUS_DATA_LENGTH_MISMATCH if the buffer size was not correct. The
  303. correct buffer size will be returned in the data size parameter.
  304. STATUS_INVALID_PARAMETER if the given subsystem or information type is
  305. not known.
  306. Other status codes on other failures.
  307. --*/
  308. {
  309. KSTATUS Status;
  310. switch (Subsystem) {
  311. case SystemInformationKe:
  312. Status = KepGetSetKeSystemInformation(FromKernelMode,
  313. InformationType,
  314. Data,
  315. DataSize,
  316. Set);
  317. break;
  318. case SystemInformationIo:
  319. Status = IoGetSetSystemInformation(FromKernelMode,
  320. InformationType,
  321. Data,
  322. DataSize,
  323. Set);
  324. break;
  325. case SystemInformationMm:
  326. Status = MmGetSetSystemInformation(FromKernelMode,
  327. InformationType,
  328. Data,
  329. DataSize,
  330. Set);
  331. break;
  332. case SystemInformationPs:
  333. Status = PsGetSetSystemInformation(FromKernelMode,
  334. InformationType,
  335. Data,
  336. DataSize,
  337. Set);
  338. break;
  339. case SystemInformationHl:
  340. Status = HlGetSetSystemInformation(FromKernelMode,
  341. InformationType,
  342. Data,
  343. DataSize,
  344. Set);
  345. break;
  346. case SystemInformationSp:
  347. Status = SpGetSetSystemInformation(FromKernelMode,
  348. InformationType,
  349. Data,
  350. DataSize,
  351. Set);
  352. break;
  353. case SystemInformationPm:
  354. Status = PmGetSetSystemInformation(FromKernelMode,
  355. InformationType,
  356. Data,
  357. DataSize,
  358. Set);
  359. break;
  360. default:
  361. Status = STATUS_INVALID_PARAMETER;
  362. *DataSize = 0;
  363. break;
  364. }
  365. return Status;
  366. }
  367. KSTATUS
  368. KepGetSetKeSystemInformation (
  369. BOOL FromKernelMode,
  370. KE_INFORMATION_TYPE InformationType,
  371. PVOID Data,
  372. PUINTN DataSize,
  373. BOOL Set
  374. )
  375. /*++
  376. Routine Description:
  377. This routine gets or sets system information.
  378. Arguments:
  379. FromKernelMode - Supplies a boolean indicating whether or not this request
  380. (and the buffer associated with it) originates from user mode (FALSE)
  381. or kernel mode (TRUE).
  382. InformationType - Supplies the information type.
  383. Data - Supplies a pointer to the data buffer where the data is either
  384. returned for a get operation or given for a set operation.
  385. DataSize - Supplies a pointer that on input contains the size of the
  386. data buffer. On output, contains the required size of the data buffer.
  387. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  388. a set operation (TRUE).
  389. Return Value:
  390. Status code.
  391. --*/
  392. {
  393. KSTATUS Status;
  394. switch (InformationType) {
  395. case KeInformationSystemVersion:
  396. Status = KepGetSystemVersion(Data, DataSize, Set);
  397. break;
  398. case KeInformationFirmwareTable:
  399. Status = KepGetFirmwareTable(Data, DataSize, Set);
  400. break;
  401. case KeInformationFirmwareType:
  402. Status = KepGetFirmwareType(Data, DataSize, Set);
  403. break;
  404. case KeInformationProcessorUsage:
  405. Status = KepGetProcessorUsage(Data, DataSize, Set);
  406. break;
  407. case KeInformationProcessorCount:
  408. Status = KepGetProcessorCount(Data, DataSize, Set);
  409. break;
  410. case KeInformationKernelCommandLine:
  411. Status = KepGetKernelCommandLine(Data, DataSize, Set);
  412. break;
  413. case KeInformationBannerThread:
  414. Status = KepSetBannerThread(Data, DataSize, Set);
  415. break;
  416. default:
  417. Status = STATUS_INVALID_PARAMETER;
  418. *DataSize = 0;
  419. break;
  420. }
  421. return Status;
  422. }
  423. KSTATUS
  424. KepGetSystemVersion (
  425. PVOID Data,
  426. PUINTN DataSize,
  427. BOOL Set
  428. )
  429. /*++
  430. Routine Description:
  431. This routine gets OS version information.
  432. Arguments:
  433. Data - Supplies a pointer to the data buffer where the data is either
  434. returned for a get operation or given for a set operation.
  435. DataSize - Supplies a pointer that on input contains the size of the
  436. data buffer. On output, contains the required size of the data buffer.
  437. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  438. a set operation (TRUE).
  439. Return Value:
  440. Status code.
  441. --*/
  442. {
  443. ULONG BufferSize;
  444. KSTATUS Status;
  445. SYSTEM_VERSION_INFORMATION VersionInformation;
  446. PSYSTEM_VERSION_INFORMATION VersionInformationPointer;
  447. if (Set != FALSE) {
  448. Status = STATUS_ACCESS_DENIED;
  449. return Status;
  450. }
  451. //
  452. // If the data is at least big enough to hold the version information
  453. // structure, then try to get everything.
  454. //
  455. if (*DataSize >= sizeof(SYSTEM_VERSION_INFORMATION)) {
  456. BufferSize = *DataSize - sizeof(SYSTEM_VERSION_INFORMATION);
  457. VersionInformationPointer = Data;
  458. Status = KeGetSystemVersion(VersionInformationPointer,
  459. Data + sizeof(SYSTEM_VERSION_INFORMATION),
  460. &BufferSize);
  461. if (KSUCCESS(Status)) {
  462. //
  463. // Make the string pointers into offsets for user mode.
  464. //
  465. if (VersionInformationPointer->ProductName != NULL) {
  466. VersionInformationPointer->ProductName =
  467. (PVOID)((UINTN)(VersionInformationPointer->ProductName) -
  468. (UINTN)Data);
  469. }
  470. if (VersionInformationPointer->BuildString != NULL) {
  471. VersionInformationPointer->BuildString =
  472. (PVOID)((UINTN)(VersionInformationPointer->BuildString) -
  473. (UINTN)Data);
  474. }
  475. }
  476. //
  477. // The data isn't even big enough for the version information structure.
  478. // Call out to get the true size.
  479. //
  480. } else {
  481. VersionInformationPointer = &VersionInformation;
  482. BufferSize = 0;
  483. KeGetSystemVersion(VersionInformationPointer,
  484. NULL,
  485. &BufferSize);
  486. Status = STATUS_BUFFER_TOO_SMALL;
  487. }
  488. BufferSize += sizeof(SYSTEM_VERSION_INFORMATION);
  489. *DataSize = BufferSize;
  490. return Status;
  491. }
  492. KSTATUS
  493. KepGetFirmwareTable (
  494. PVOID Data,
  495. PUINTN DataSize,
  496. BOOL Set
  497. )
  498. /*++
  499. Routine Description:
  500. This routine gets a system firmware table.
  501. Arguments:
  502. Data - Supplies a pointer to the data buffer where the data is either
  503. returned for a get operation or given for a set operation.
  504. DataSize - Supplies a pointer that on input contains the size of the
  505. data buffer. On output, contains the required size of the data buffer.
  506. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  507. a set operation (TRUE).
  508. Return Value:
  509. Status code.
  510. --*/
  511. {
  512. PDESCRIPTION_HEADER AcpiTable;
  513. ULONG Length;
  514. PSMBIOS_ENTRY_POINT SmbiosTable;
  515. KSTATUS Status;
  516. if (Set != FALSE) {
  517. return STATUS_ACCESS_DENIED;
  518. }
  519. Status = PsCheckPermission(PERMISSION_SYSTEM_ADMINISTRATOR);
  520. if (!KSUCCESS(Status)) {
  521. return Status;
  522. }
  523. if (*DataSize < sizeof(DESCRIPTION_HEADER)) {
  524. *DataSize = sizeof(DESCRIPTION_HEADER);
  525. return STATUS_BUFFER_TOO_SMALL;
  526. }
  527. AcpiTable = AcpiFindTable(*((PULONG)Data), NULL);
  528. if (AcpiTable == NULL) {
  529. *DataSize = 0;
  530. return STATUS_NOT_FOUND;
  531. }
  532. if (*((PULONG)Data) == SMBIOS_ANCHOR_STRING_VALUE) {
  533. SmbiosTable = (PSMBIOS_ENTRY_POINT)AcpiTable;
  534. Length = sizeof(SMBIOS_ENTRY_POINT) + SmbiosTable->StructureTableLength;
  535. } else {
  536. Length = AcpiTable->Length;
  537. }
  538. if (*DataSize < Length) {
  539. *DataSize = Length;
  540. return STATUS_BUFFER_TOO_SMALL;
  541. }
  542. RtlCopyMemory(Data, AcpiTable, Length);
  543. *DataSize = Length;
  544. return STATUS_SUCCESS;
  545. }
  546. KSTATUS
  547. KepGetFirmwareType (
  548. PVOID Data,
  549. PUINTN DataSize,
  550. BOOL Set
  551. )
  552. /*++
  553. Routine Description:
  554. This routine gets the platform firmware type.
  555. Arguments:
  556. Data - Supplies a pointer to the data buffer where the data is either
  557. returned for a get operation or given for a set operation.
  558. DataSize - Supplies a pointer that on input contains the size of the
  559. data buffer. On output, contains the required size of the data buffer.
  560. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  561. a set operation (TRUE).
  562. Return Value:
  563. Status code.
  564. --*/
  565. {
  566. if (Set != FALSE) {
  567. return STATUS_ACCESS_DENIED;
  568. }
  569. if (*DataSize < sizeof(ULONG)) {
  570. *DataSize = sizeof(ULONG);
  571. return STATUS_BUFFER_TOO_SMALL;
  572. }
  573. *((PULONG)Data) = KeSystemFirmwareType;
  574. *DataSize = sizeof(ULONG);
  575. return STATUS_SUCCESS;
  576. }
  577. KSTATUS
  578. KepGetProcessorUsage (
  579. PVOID Data,
  580. PUINTN DataSize,
  581. BOOL Set
  582. )
  583. /*++
  584. Routine Description:
  585. This routine gets processor usage information.
  586. Arguments:
  587. Data - Supplies a pointer to the data buffer where the data is either
  588. returned for a get operation or given for a set operation.
  589. DataSize - Supplies a pointer that on input contains the size of the
  590. data buffer. On output, contains the required size of the data buffer.
  591. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  592. a set operation (TRUE).
  593. Return Value:
  594. Status code.
  595. --*/
  596. {
  597. PPROCESSOR_USAGE_INFORMATION Information;
  598. UINTN ProcessorCount;
  599. KSTATUS Status;
  600. if (Set != FALSE) {
  601. return STATUS_ACCESS_DENIED;
  602. }
  603. Status = PsCheckPermission(PERMISSION_RESOURCES);
  604. if (!KSUCCESS(Status)) {
  605. return Status;
  606. }
  607. if (*DataSize != sizeof(PROCESSOR_USAGE_INFORMATION)) {
  608. *DataSize = sizeof(PROCESSOR_USAGE_INFORMATION);
  609. return STATUS_DATA_LENGTH_MISMATCH;
  610. }
  611. Information = Data;
  612. Information->CycleCounterFrequency = HlQueryProcessorCounterFrequency();
  613. if (Information->ProcessorNumber == (UINTN)-1) {
  614. KeGetTotalProcessorCycleAccounting(&(Information->Usage));
  615. } else {
  616. ProcessorCount = KeGetActiveProcessorCount();
  617. if (Information->ProcessorNumber > ProcessorCount) {
  618. Information->ProcessorNumber = ProcessorCount;
  619. return STATUS_OUT_OF_BOUNDS;
  620. }
  621. Status = KeGetProcessorCycleAccounting(Information->ProcessorNumber,
  622. &(Information->Usage));
  623. return Status;
  624. }
  625. return STATUS_SUCCESS;
  626. }
  627. KSTATUS
  628. KepGetProcessorCount (
  629. PVOID Data,
  630. PUINTN DataSize,
  631. BOOL Set
  632. )
  633. /*++
  634. Routine Description:
  635. This routine gets processor count information.
  636. Arguments:
  637. Data - Supplies a pointer to the data buffer where the data is either
  638. returned for a get operation or given for a set operation.
  639. DataSize - Supplies a pointer that on input contains the size of the
  640. data buffer. On output, contains the required size of the data buffer.
  641. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  642. a set operation (TRUE).
  643. Return Value:
  644. Status code.
  645. --*/
  646. {
  647. PPROCESSOR_COUNT_INFORMATION Information;
  648. KSTATUS Status;
  649. if (Set != FALSE) {
  650. return STATUS_ACCESS_DENIED;
  651. }
  652. Status = PsCheckPermission(PERMISSION_RESOURCES);
  653. if (!KSUCCESS(Status)) {
  654. return Status;
  655. }
  656. if (*DataSize != sizeof(PROCESSOR_COUNT_INFORMATION)) {
  657. *DataSize = sizeof(PROCESSOR_COUNT_INFORMATION);
  658. return STATUS_DATA_LENGTH_MISMATCH;
  659. }
  660. Information = Data;
  661. Information->MaxProcessorCount = HlGetMaximumProcessorCount();
  662. Information->ActiveProcessorCount = KeGetActiveProcessorCount();
  663. return STATUS_SUCCESS;
  664. }
  665. KSTATUS
  666. KepGetKernelCommandLine (
  667. PVOID Data,
  668. PUINTN DataSize,
  669. BOOL Set
  670. )
  671. /*++
  672. Routine Description:
  673. This routine gets the kernel command line information.
  674. Arguments:
  675. Data - Supplies a pointer to the data buffer where the data is either
  676. returned for a get operation or given for a set operation.
  677. DataSize - Supplies a pointer that on input contains the size of the
  678. data buffer. On output, contains the required size of the data buffer.
  679. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  680. a set operation (TRUE).
  681. Return Value:
  682. Status code.
  683. --*/
  684. {
  685. if (Set != FALSE) {
  686. return STATUS_ACCESS_DENIED;
  687. }
  688. if (KeCommandLine == NULL) {
  689. return STATUS_NOT_FOUND;
  690. }
  691. if (*DataSize < KeCommandLine->LineSize) {
  692. *DataSize = KeCommandLine->LineSize;
  693. return STATUS_BUFFER_TOO_SMALL;
  694. }
  695. RtlCopyMemory(Data, KeCommandLine->Line, KeCommandLine->LineSize);
  696. return STATUS_SUCCESS;
  697. }