Leaked source code of windows server 2003
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.

282 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. exinfo.c
  5. Abstract:
  6. This module implements the NT set and query system information services.
  7. Author:
  8. Ken Reneris (kenr) 19-July-1994
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. --*/
  13. #include "exp.h"
  14. #if _PNP_POWER_
  15. #if defined(ALLOC_PRAGMA)
  16. #pragma alloc_text(PAGE, ExpCheckSystemInformation)
  17. #pragma alloc_text(PAGE, ExpCheckSystemInfoWork)
  18. #endif // _PNP_POWER_
  19. #ifdef ALLOC_DATA_PRAGMA
  20. #pragma const_seg("PAGECONST")
  21. #endif
  22. VOID
  23. ExpCheckSystemInformation (
  24. PVOID Context,
  25. PVOID InformationClass,
  26. PVOID Argument2
  27. )
  28. /*++
  29. Routine Description:
  30. Callback function invoked when something in the system information
  31. may have changed.
  32. Arguments:
  33. Context - Where invoked from.
  34. InformationClass - which class for the given context was set
  35. (ignored for now)
  36. Argument2
  37. Return Value:
  38. --*/
  39. {
  40. PAGED_CODE();
  41. if (InterlockedIncrement(&ExpCheckSystemInfoBusy) == 1) {
  42. ExQueueWorkItem (&ExpCheckSystemInfoWorkItem, DelayedWorkQueue);
  43. }
  44. }
  45. VOID
  46. ExpCheckSystemInfoWork (
  47. IN PVOID Context
  48. )
  49. /*++
  50. Routine Description:
  51. Verifies registery data for various system information classes
  52. is up to date.
  53. Arguments:
  54. Return Value:
  55. --*/
  56. {
  57. static struct {
  58. SYSTEM_INFORMATION_CLASS InformationLevel;
  59. ULONG BufferSize;
  60. } const RegistryInformation[] = {
  61. SystemBasicInformation, sizeof (SYSTEM_BASIC_INFORMATION),
  62. SystemPowerInformation, sizeof (SYSTEM_POWER_INFORMATION),
  63. SystemProcessorSpeedInformation, sizeof (SYSTEM_PROCESSOR_SPEED_INFORMATION),
  64. 0, 0
  65. };
  66. struct {
  67. KEY_VALUE_PARTIAL_INFORMATION Key;
  68. union {
  69. SYSTEM_BASIC_INFORMATION BasicInformation;
  70. SYSTEM_POWER_INFORMATION PowerSettings;
  71. SYSTEM_PROCESSOR_SPEED_INFORMATION ProcessorSpeed;
  72. };
  73. } RegistryBuffer, QueryBuffer;
  74. ULONG Index, BufferSize, disposition, length;
  75. NTSTATUS Status;
  76. OBJECT_ATTRIBUTES objectAttributes;
  77. UNICODE_STRING unicodeString, ValueString;
  78. HANDLE CurrentControlSet, SystemInformation, LevelInformation;
  79. LARGE_INTEGER Interval;
  80. WCHAR wstr[10];
  81. PAGED_CODE();
  82. RtlInitUnicodeString (&ValueString, ExpWstrSystemInformationValue);
  83. //
  84. // Open CurrentControlSet
  85. //
  86. InitializeObjectAttributes( &objectAttributes,
  87. &CmRegistryMachineSystemCurrentControlSet,
  88. OBJ_CASE_INSENSITIVE,
  89. NULL,
  90. NULL );
  91. Status = NtOpenKey (&CurrentControlSet,
  92. KEY_READ | KEY_WRITE,
  93. &objectAttributes );
  94. if (NT_SUCCESS(Status)) {
  95. //
  96. // Open SystemInformation
  97. //
  98. RtlInitUnicodeString( &unicodeString, ExpWstrSystemInformation );
  99. InitializeObjectAttributes( &objectAttributes,
  100. &unicodeString,
  101. OBJ_CASE_INSENSITIVE,
  102. CurrentControlSet,
  103. NULL );
  104. Status = NtCreateKey ( &SystemInformation,
  105. KEY_READ | KEY_WRITE,
  106. &objectAttributes,
  107. 0,
  108. NULL,
  109. REG_OPTION_VOLATILE,
  110. &disposition );
  111. NtClose (CurrentControlSet);
  112. }
  113. if (!NT_SUCCESS(Status)) {
  114. ExpCheckSystemInfoBusy = 0;
  115. return ;
  116. }
  117. //
  118. // Loop and check SystemInformation data in registry
  119. //
  120. do {
  121. //
  122. // For now just check each SystemInformation level and update
  123. // any level which is out of date
  124. //
  125. for (Index=0; RegistryInformation[Index].BufferSize; Index++) {
  126. //
  127. // Initialize registry data buffer
  128. //
  129. BufferSize = RegistryInformation[Index].BufferSize;
  130. RtlZeroMemory (RegistryBuffer.Key.Data, BufferSize);
  131. //
  132. // Open appropiate SystemInformation level key
  133. //
  134. swprintf (wstr, L"%d", RegistryInformation[Index].InformationLevel);
  135. RtlInitUnicodeString (&unicodeString, wstr);
  136. InitializeObjectAttributes( &objectAttributes,
  137. &unicodeString,
  138. OBJ_CASE_INSENSITIVE,
  139. SystemInformation,
  140. NULL );
  141. Status = NtCreateKey ( &LevelInformation,
  142. KEY_READ | KEY_WRITE,
  143. &objectAttributes,
  144. 0,
  145. NULL,
  146. REG_OPTION_VOLATILE,
  147. &disposition );
  148. //
  149. // If key opened, read current data value from the registry
  150. //
  151. if (NT_SUCCESS(Status)) {
  152. NtQueryValueKey (
  153. LevelInformation,
  154. &ValueString,
  155. KeyValuePartialInformation,
  156. &RegistryBuffer.Key,
  157. sizeof (RegistryBuffer),
  158. &length
  159. );
  160. }
  161. //
  162. // Query current SystemInformation data
  163. //
  164. Status = NtQuerySystemInformation (
  165. RegistryInformation[Index].InformationLevel,
  166. &QueryBuffer.Key.Data,
  167. BufferSize,
  168. NULL
  169. );
  170. //
  171. // Check if current SystemInformation matches the registry
  172. // information
  173. //
  174. if (NT_SUCCESS(Status) &&
  175. !RtlEqualMemory (RegistryBuffer.Key.Data,
  176. QueryBuffer.Key.Data,
  177. BufferSize) ) {
  178. //
  179. // Did not match - update registry to current SystemInfomration
  180. //
  181. Status = NtSetValueKey (
  182. LevelInformation,
  183. &ValueString,
  184. 0L,
  185. REG_BINARY,
  186. QueryBuffer.Key.Data,
  187. BufferSize
  188. );
  189. //
  190. // Make notificant that this information level has changed
  191. //
  192. ExNotifyCallback (
  193. ExCbSetSystemInformation,
  194. (PVOID) RegistryInformation[Index].InformationLevel,
  195. (PVOID) NULL
  196. );
  197. }
  198. //
  199. // Close this InformatiobLevel and check the next one
  200. //
  201. NtClose (LevelInformation);
  202. }
  203. } while (InterlockedDecrement(&ExpCheckSystemInfoBusy));
  204. //
  205. // Cleanup
  206. //
  207. NtClose (SystemInformation);
  208. }
  209. #endif // _PNP_POWER_
  210. #ifdef ALLOC_DATA_PRAGMA
  211. #pragma const_seg()
  212. #endif