info.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  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. default:
  414. Status = STATUS_INVALID_PARAMETER;
  415. *DataSize = 0;
  416. break;
  417. }
  418. return Status;
  419. }
  420. KSTATUS
  421. KepGetSystemVersion (
  422. PVOID Data,
  423. PUINTN DataSize,
  424. BOOL Set
  425. )
  426. /*++
  427. Routine Description:
  428. This routine gets OS version information.
  429. Arguments:
  430. Data - Supplies a pointer to the data buffer where the data is either
  431. returned for a get operation or given for a set operation.
  432. DataSize - Supplies a pointer that on input contains the size of the
  433. data buffer. On output, contains the required size of the data buffer.
  434. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  435. a set operation (TRUE).
  436. Return Value:
  437. Status code.
  438. --*/
  439. {
  440. ULONG BufferSize;
  441. KSTATUS Status;
  442. SYSTEM_VERSION_INFORMATION VersionInformation;
  443. PSYSTEM_VERSION_INFORMATION VersionInformationPointer;
  444. if (Set != FALSE) {
  445. Status = STATUS_ACCESS_DENIED;
  446. return Status;
  447. }
  448. //
  449. // If the data is at least big enough to hold the version information
  450. // structure, then try to get everything.
  451. //
  452. if (*DataSize >= sizeof(SYSTEM_VERSION_INFORMATION)) {
  453. BufferSize = *DataSize - sizeof(SYSTEM_VERSION_INFORMATION);
  454. VersionInformationPointer = Data;
  455. Status = KeGetSystemVersion(VersionInformationPointer,
  456. Data + sizeof(SYSTEM_VERSION_INFORMATION),
  457. &BufferSize);
  458. if (KSUCCESS(Status)) {
  459. //
  460. // Make the string pointers into offsets for user mode.
  461. //
  462. if (VersionInformationPointer->ProductName != NULL) {
  463. VersionInformationPointer->ProductName =
  464. (PVOID)((UINTN)(VersionInformationPointer->ProductName) -
  465. (UINTN)Data);
  466. }
  467. if (VersionInformationPointer->BuildString != NULL) {
  468. VersionInformationPointer->BuildString =
  469. (PVOID)((UINTN)(VersionInformationPointer->BuildString) -
  470. (UINTN)Data);
  471. }
  472. }
  473. //
  474. // The data isn't even big enough for the version information structure.
  475. // Call out to get the true size.
  476. //
  477. } else {
  478. VersionInformationPointer = &VersionInformation;
  479. BufferSize = 0;
  480. KeGetSystemVersion(VersionInformationPointer,
  481. NULL,
  482. &BufferSize);
  483. Status = STATUS_BUFFER_TOO_SMALL;
  484. }
  485. BufferSize += sizeof(SYSTEM_VERSION_INFORMATION);
  486. *DataSize = BufferSize;
  487. return Status;
  488. }
  489. KSTATUS
  490. KepGetFirmwareTable (
  491. PVOID Data,
  492. PUINTN DataSize,
  493. BOOL Set
  494. )
  495. /*++
  496. Routine Description:
  497. This routine gets a system firmware table.
  498. Arguments:
  499. Data - Supplies a pointer to the data buffer where the data is either
  500. returned for a get operation or given for a set operation.
  501. DataSize - Supplies a pointer that on input contains the size of the
  502. data buffer. On output, contains the required size of the data buffer.
  503. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  504. a set operation (TRUE).
  505. Return Value:
  506. Status code.
  507. --*/
  508. {
  509. PDESCRIPTION_HEADER AcpiTable;
  510. ULONG Length;
  511. PSMBIOS_ENTRY_POINT SmbiosTable;
  512. KSTATUS Status;
  513. if (Set != FALSE) {
  514. return STATUS_ACCESS_DENIED;
  515. }
  516. Status = PsCheckPermission(PERMISSION_SYSTEM_ADMINISTRATOR);
  517. if (!KSUCCESS(Status)) {
  518. return Status;
  519. }
  520. if (*DataSize < sizeof(DESCRIPTION_HEADER)) {
  521. *DataSize = sizeof(DESCRIPTION_HEADER);
  522. return STATUS_BUFFER_TOO_SMALL;
  523. }
  524. AcpiTable = AcpiFindTable(*((PULONG)Data), NULL);
  525. if (AcpiTable == NULL) {
  526. *DataSize = 0;
  527. return STATUS_NOT_FOUND;
  528. }
  529. if (*((PULONG)Data) == SMBIOS_ANCHOR_STRING_VALUE) {
  530. SmbiosTable = (PSMBIOS_ENTRY_POINT)AcpiTable;
  531. Length = sizeof(SMBIOS_ENTRY_POINT) + SmbiosTable->StructureTableLength;
  532. } else {
  533. Length = AcpiTable->Length;
  534. }
  535. if (*DataSize < Length) {
  536. *DataSize = Length;
  537. return STATUS_BUFFER_TOO_SMALL;
  538. }
  539. RtlCopyMemory(Data, AcpiTable, Length);
  540. *DataSize = Length;
  541. return STATUS_SUCCESS;
  542. }
  543. KSTATUS
  544. KepGetFirmwareType (
  545. PVOID Data,
  546. PUINTN DataSize,
  547. BOOL Set
  548. )
  549. /*++
  550. Routine Description:
  551. This routine gets the platform firmware type.
  552. Arguments:
  553. Data - Supplies a pointer to the data buffer where the data is either
  554. returned for a get operation or given for a set operation.
  555. DataSize - Supplies a pointer that on input contains the size of the
  556. data buffer. On output, contains the required size of the data buffer.
  557. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  558. a set operation (TRUE).
  559. Return Value:
  560. Status code.
  561. --*/
  562. {
  563. if (Set != FALSE) {
  564. return STATUS_ACCESS_DENIED;
  565. }
  566. if (*DataSize < sizeof(ULONG)) {
  567. *DataSize = sizeof(ULONG);
  568. return STATUS_BUFFER_TOO_SMALL;
  569. }
  570. *((PULONG)Data) = KeSystemFirmwareType;
  571. *DataSize = sizeof(ULONG);
  572. return STATUS_SUCCESS;
  573. }
  574. KSTATUS
  575. KepGetProcessorUsage (
  576. PVOID Data,
  577. PUINTN DataSize,
  578. BOOL Set
  579. )
  580. /*++
  581. Routine Description:
  582. This routine gets processor usage information.
  583. Arguments:
  584. Data - Supplies a pointer to the data buffer where the data is either
  585. returned for a get operation or given for a set operation.
  586. DataSize - Supplies a pointer that on input contains the size of the
  587. data buffer. On output, contains the required size of the data buffer.
  588. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  589. a set operation (TRUE).
  590. Return Value:
  591. Status code.
  592. --*/
  593. {
  594. PPROCESSOR_USAGE_INFORMATION Information;
  595. UINTN ProcessorCount;
  596. KSTATUS Status;
  597. if (Set != FALSE) {
  598. return STATUS_ACCESS_DENIED;
  599. }
  600. Status = PsCheckPermission(PERMISSION_RESOURCES);
  601. if (!KSUCCESS(Status)) {
  602. return Status;
  603. }
  604. if (*DataSize != sizeof(PROCESSOR_USAGE_INFORMATION)) {
  605. *DataSize = sizeof(PROCESSOR_USAGE_INFORMATION);
  606. return STATUS_DATA_LENGTH_MISMATCH;
  607. }
  608. Information = Data;
  609. Information->CycleCounterFrequency = HlQueryProcessorCounterFrequency();
  610. if (Information->ProcessorNumber == (UINTN)-1) {
  611. KeGetTotalProcessorCycleAccounting(&(Information->Usage));
  612. } else {
  613. ProcessorCount = KeGetActiveProcessorCount();
  614. if (Information->ProcessorNumber > ProcessorCount) {
  615. Information->ProcessorNumber = ProcessorCount;
  616. return STATUS_OUT_OF_BOUNDS;
  617. }
  618. Status = KeGetProcessorCycleAccounting(Information->ProcessorNumber,
  619. &(Information->Usage));
  620. return Status;
  621. }
  622. return STATUS_SUCCESS;
  623. }
  624. KSTATUS
  625. KepGetProcessorCount (
  626. PVOID Data,
  627. PUINTN DataSize,
  628. BOOL Set
  629. )
  630. /*++
  631. Routine Description:
  632. This routine gets processor count information.
  633. Arguments:
  634. Data - Supplies a pointer to the data buffer where the data is either
  635. returned for a get operation or given for a set operation.
  636. DataSize - Supplies a pointer that on input contains the size of the
  637. data buffer. On output, contains the required size of the data buffer.
  638. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  639. a set operation (TRUE).
  640. Return Value:
  641. Status code.
  642. --*/
  643. {
  644. PPROCESSOR_COUNT_INFORMATION Information;
  645. KSTATUS Status;
  646. if (Set != FALSE) {
  647. return STATUS_ACCESS_DENIED;
  648. }
  649. Status = PsCheckPermission(PERMISSION_RESOURCES);
  650. if (!KSUCCESS(Status)) {
  651. return Status;
  652. }
  653. if (*DataSize != sizeof(PROCESSOR_COUNT_INFORMATION)) {
  654. *DataSize = sizeof(PROCESSOR_COUNT_INFORMATION);
  655. return STATUS_DATA_LENGTH_MISMATCH;
  656. }
  657. Information = Data;
  658. Information->MaxProcessorCount = HlGetMaximumProcessorCount();
  659. Information->ActiveProcessorCount = KeGetActiveProcessorCount();
  660. return STATUS_SUCCESS;
  661. }
  662. KSTATUS
  663. KepGetKernelCommandLine (
  664. PVOID Data,
  665. PUINTN DataSize,
  666. BOOL Set
  667. )
  668. /*++
  669. Routine Description:
  670. This routine gets the kernel command line information.
  671. Arguments:
  672. Data - Supplies a pointer to the data buffer where the data is either
  673. returned for a get operation or given for a set operation.
  674. DataSize - Supplies a pointer that on input contains the size of the
  675. data buffer. On output, contains the required size of the data buffer.
  676. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  677. a set operation (TRUE).
  678. Return Value:
  679. Status code.
  680. --*/
  681. {
  682. if (Set != FALSE) {
  683. return STATUS_ACCESS_DENIED;
  684. }
  685. if (KeCommandLine == NULL) {
  686. return STATUS_NOT_FOUND;
  687. }
  688. if (*DataSize < KeCommandLine->LineSize) {
  689. *DataSize = KeCommandLine->LineSize;
  690. return STATUS_BUFFER_TOO_SMALL;
  691. }
  692. RtlCopyMemory(Data, KeCommandLine->Line, KeCommandLine->LineSize);
  693. return STATUS_SUCCESS;
  694. }