info.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*++
  2. Copyright (c) 2015 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. info.c
  5. Abstract:
  6. This module handles getting and setting system information calls.
  7. Author:
  8. Chris Stevens 18-Jan-2015
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <minoca/kernel/kernel.h>
  16. #include "spp.h"
  17. //
  18. // ---------------------------------------------------------------- Definitions
  19. //
  20. //
  21. // ------------------------------------------------------ Data Type Definitions
  22. //
  23. //
  24. // ----------------------------------------------- Internal Function Prototypes
  25. //
  26. KSTATUS
  27. SppGetSetState (
  28. PVOID Data,
  29. PUINTN DataSize,
  30. BOOL Set
  31. );
  32. //
  33. // -------------------------------------------------------------------- Globals
  34. //
  35. //
  36. // ------------------------------------------------------------------ Functions
  37. //
  38. KSTATUS
  39. SpGetSetSystemInformation (
  40. BOOL FromKernelMode,
  41. SP_INFORMATION_TYPE InformationType,
  42. PVOID Data,
  43. PUINTN DataSize,
  44. BOOL Set
  45. )
  46. /*++
  47. Routine Description:
  48. This routine gets or sets system information.
  49. Arguments:
  50. FromKernelMode - Supplies a boolean indicating whether or not this request
  51. (and the buffer associated with it) originates from user mode (FALSE)
  52. or kernel mode (TRUE).
  53. InformationType - Supplies the information type.
  54. Data - Supplies a pointer to the data buffer where the data is either
  55. returned for a get operation or given for a set operation.
  56. DataSize - Supplies a pointer that on input contains the size of the
  57. data buffer. On output, contains the required size of the data buffer.
  58. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  59. a set operation (TRUE).
  60. Return Value:
  61. Status code.
  62. --*/
  63. {
  64. KSTATUS Status;
  65. switch (InformationType) {
  66. case SpInformationGetSetState:
  67. Status = SppGetSetState(Data, DataSize, Set);
  68. break;
  69. default:
  70. Status = STATUS_INVALID_PARAMETER;
  71. *DataSize = 0;
  72. break;
  73. }
  74. return Status;
  75. }
  76. //
  77. // --------------------------------------------------------- Internal Functions
  78. //
  79. KSTATUS
  80. SppGetSetState (
  81. PVOID Data,
  82. PUINTN DataSize,
  83. BOOL Set
  84. )
  85. /*++
  86. Routine Description:
  87. This routine gets or sets the system profiler state.
  88. Arguments:
  89. Data - Supplies a pointer to the data buffer where the data is either
  90. returned for a get operation or given for a set operation.
  91. DataSize - Supplies a pointer that on input contains the size of the
  92. data buffer. On output, contains the required size of the data buffer.
  93. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  94. a set operation (TRUE).
  95. Return Value:
  96. Status code.
  97. --*/
  98. {
  99. ULONG ChangedFlags;
  100. ULONG DisableFlags;
  101. ULONG EnableFlags;
  102. PSP_GET_SET_STATE_INFORMATION Information;
  103. BOOL LockHeld;
  104. KSTATUS Status;
  105. Status = PsCheckPermission(PERMISSION_SYSTEM_ADMINISTRATOR);
  106. if (!KSUCCESS(Status)) {
  107. return Status;
  108. }
  109. Information = Data;
  110. if (*DataSize < sizeof(SP_GET_SET_STATE_INFORMATION)) {
  111. *DataSize = sizeof(SP_GET_SET_STATE_INFORMATION);
  112. return STATUS_DATA_LENGTH_MISMATCH;
  113. }
  114. //
  115. // Return the current set of enabled flags on a get request.
  116. //
  117. Information = (PSP_GET_SET_STATE_INFORMATION)Data;
  118. LockHeld = FALSE;
  119. if (Set == FALSE) {
  120. Information->Operation = SpGetSetStateOperationNone;
  121. Information->ProfilerTypeFlags = SpEnabledFlags;
  122. } else if (Information->Operation != SpGetSetStateOperationNone) {
  123. DisableFlags = 0;
  124. EnableFlags = 0;
  125. KeAcquireQueuedLock(SpProfilingQueuedLock);
  126. LockHeld = TRUE;
  127. switch (Information->Operation) {
  128. case SpGetSetStateOperationOverwrite:
  129. ChangedFlags = SpEnabledFlags ^ Information->ProfilerTypeFlags;
  130. EnableFlags = ChangedFlags & ~SpEnabledFlags;
  131. DisableFlags = ChangedFlags & SpEnabledFlags;
  132. break;
  133. case SpGetSetStateOperationEnable:
  134. EnableFlags = Information->ProfilerTypeFlags & ~SpEnabledFlags;
  135. break;
  136. case SpGetSetStateOperationDisable:
  137. DisableFlags = Information->ProfilerTypeFlags & SpEnabledFlags;
  138. break;
  139. default:
  140. break;
  141. }
  142. if (DisableFlags != 0) {
  143. Status = SppStopSystemProfiler(DisableFlags);
  144. if (!KSUCCESS(Status)) {
  145. goto GetSetStateEnd;
  146. }
  147. }
  148. if (EnableFlags != 0) {
  149. Status = SppStartSystemProfiler(EnableFlags);
  150. if (!KSUCCESS(Status)) {
  151. goto GetSetStateEnd;
  152. }
  153. }
  154. KeReleaseQueuedLock(SpProfilingQueuedLock);
  155. LockHeld = FALSE;
  156. }
  157. Status = STATUS_SUCCESS;
  158. GetSetStateEnd:
  159. if (LockHeld != FALSE) {
  160. KeReleaseQueuedLock(SpProfilingQueuedLock);
  161. }
  162. return Status;
  163. }