Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

exinfo.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 exinfo.c 00008 00009 Abstract: 00010 00011 This module implements the NT set anmd query system information services. 00012 00013 Author: 00014 00015 Ken Reneris (kenr) 19-July-1994 00016 00017 Environment: 00018 00019 Kernel mode only. 00020 00021 Revision History: 00022 00023 --*/ 00024 00025 #include "exp.h" 00026 00027 #if _PNP_POWER_ 00028 #if defined(ALLOC_PRAGMA) 00029 #pragma alloc_text(PAGE, ExpCheckSystemInformation) 00030 #pragma alloc_text(PAGE, ExpCheckSystemInfoWork) 00031 #endif // _PNP_POWER_ 00032 00033 VOID 00034 ExpCheckSystemInformation ( 00035 PVOID Context, 00036 PVOID InformationClass, 00037 PVOID Argument2 00038 ) 00039 /*++ 00040 00041 Routine Description: 00042 00043 Callback function invoked when something in the system information 00044 may have changed. 00045 00046 Arguments: 00047 00048 Context - Where invoked from. 00049 00050 InformationClass - which class for the given context was set 00051 (ignored for now) 00052 00053 Argument2 00054 00055 Return Value: 00056 00057 --*/ 00058 { 00059 ExQueueWorkItem (&ExpCheckSystemInfoWorkItem, DelayedWorkQueue); 00060 } 00061 00062 00063 VOID 00064 ExpCheckSystemInfoWork ( 00065 IN PVOID Context 00066 ) 00067 /*++ 00068 00069 Routine Description: 00070 00071 Verifies registery data for various system information classes 00072 is up to date. 00073 00074 Arguments: 00075 00076 Return Value: 00077 00078 --*/ 00079 { 00080 static struct { 00081 SYSTEM_INFORMATION_CLASS InformationLevel; 00082 ULONG BufferSize; 00083 } RegistryInformation[] = { 00084 SystemBasicInformation, sizeof (SYSTEM_BASIC_INFORMATION), 00085 SystemPowerInformation, sizeof (SYSTEM_POWER_INFORMATION), 00086 SystemProcessorSpeedInformation, sizeof (SYSTEM_PROCESSOR_SPEED_INFORMATION), 00087 0, 0 00088 }; 00089 00090 struct { 00091 KEY_VALUE_PARTIAL_INFORMATION Key; 00092 union { 00093 SYSTEM_BASIC_INFORMATION BasicInformation; 00094 SYSTEM_POWER_INFORMATION PowerSettings; 00095 SYSTEM_PROCESSOR_SPEED_INFORMATION ProcessorSpeed; 00096 }; 00097 } RegistryBuffer, QueryBuffer; 00098 00099 ULONG Index, BufferSize, disposition, length; 00100 NTSTATUS Status; 00101 OBJECT_ATTRIBUTES objectAttributes; 00102 UNICODE_STRING unicodeString, ValueString; 00103 HANDLE CurrentControlSet, SystemInformation, LevelInformation; 00104 LARGE_INTEGER Interval; 00105 BOOLEAN Rescan; 00106 WCHAR wstr[10]; 00107 00108 PAGED_CODE(); 00109 00110 // 00111 // Only one worked needed at a time needed to update the SystemInformation 00112 // data in the registry 00113 // 00114 00115 if (InterlockedIncrement (&ExpCheckSystemInfoBusy) != 0) { 00116 return ; 00117 } 00118 00119 RtlInitUnicodeString (&ValueString, ExpWstrSystemInformationValue); 00120 00121 // 00122 // Open CurrentControlSet 00123 // 00124 00125 InitializeObjectAttributes( &objectAttributes, 00126 &CmRegistryMachineSystemCurrentControlSet, 00127 OBJ_CASE_INSENSITIVE, 00128 NULL, 00129 NULL ); 00130 00131 Status = NtOpenKey (&CurrentControlSet, 00132 KEY_READ | KEY_WRITE, 00133 &objectAttributes ); 00134 00135 if (NT_SUCCESS(Status)) { 00136 00137 // 00138 // Open SystemInformation 00139 // 00140 00141 RtlInitUnicodeString( &unicodeString, ExpWstrSystemInformation ); 00142 InitializeObjectAttributes( &objectAttributes, 00143 &unicodeString, 00144 OBJ_CASE_INSENSITIVE, 00145 CurrentControlSet, 00146 NULL ); 00147 00148 Status = NtCreateKey ( &SystemInformation, 00149 KEY_READ | KEY_WRITE, 00150 &objectAttributes, 00151 0, 00152 NULL, 00153 REG_OPTION_VOLATILE, 00154 &disposition ); 00155 00156 NtClose (CurrentControlSet); 00157 } 00158 00159 if (!NT_SUCCESS(Status)) { 00160 InterlockedDecrement (&ExpCheckSystemInfoBusy); 00161 return ; 00162 } 00163 00164 // 00165 // Loop and check SystemInformation data in registry 00166 // 00167 00168 do { 00169 Rescan = FALSE; 00170 00171 // 00172 // Wait a moment 00173 // 00174 00175 Interval.QuadPart = -3000000; 00176 KeDelayExecutionThread (KernelMode, FALSE, &Interval); 00177 00178 // 00179 // For now just check each SystemInformation level and update 00180 // any level which is out of date 00181 // 00182 00183 for (Index=0; RegistryInformation[Index].BufferSize; Index++) { 00184 00185 // 00186 // Initialize registry data buffer 00187 // 00188 00189 BufferSize = RegistryInformation[Index].BufferSize; 00190 RtlZeroMemory (RegistryBuffer.Key.Data, BufferSize); 00191 00192 // 00193 // Open appropiate SystemInformation level key 00194 // 00195 00196 swprintf (wstr, L"%d", RegistryInformation[Index].InformationLevel); 00197 RtlInitUnicodeString (&unicodeString, wstr); 00198 InitializeObjectAttributes( &objectAttributes, 00199 &unicodeString, 00200 OBJ_CASE_INSENSITIVE, 00201 SystemInformation, 00202 NULL ); 00203 00204 Status = NtCreateKey ( &LevelInformation, 00205 KEY_READ | KEY_WRITE, 00206 &objectAttributes, 00207 0, 00208 NULL, 00209 REG_OPTION_VOLATILE, 00210 &disposition ); 00211 00212 // 00213 // If key opened, read current data value from the registry 00214 // 00215 00216 if (NT_SUCCESS(Status)) { 00217 NtQueryValueKey ( 00218 LevelInformation, 00219 &ValueString, 00220 KeyValuePartialInformation, 00221 &RegistryBuffer.Key, 00222 sizeof (RegistryBuffer), 00223 &length 00224 ); 00225 } 00226 00227 // 00228 // Query current SystemInformation data 00229 // 00230 00231 Status = NtQuerySystemInformation ( 00232 RegistryInformation[Index].InformationLevel, 00233 &QueryBuffer.Key.Data, 00234 BufferSize, 00235 NULL 00236 ); 00237 00238 // 00239 // Check if current SystemInformation matches the registry 00240 // information 00241 // 00242 00243 if (NT_SUCCESS(Status) && 00244 !RtlEqualMemory (RegistryBuffer.Key.Data, 00245 QueryBuffer.Key.Data, 00246 BufferSize) ) { 00247 00248 // 00249 // Did not match - update registry to current SystemInfomration 00250 // 00251 00252 Status = NtSetValueKey ( 00253 LevelInformation, 00254 &ValueString, 00255 0L, 00256 REG_BINARY, 00257 QueryBuffer.Key.Data, 00258 BufferSize 00259 ); 00260 00261 // 00262 // Make notificant that this information level has changed 00263 // 00264 00265 ExNotifyCallback ( 00266 ExCbSetSystemInformation, 00267 (PVOID) RegistryInformation[Index].InformationLevel, 00268 (PVOID) NULL 00269 ); 00270 } 00271 00272 // 00273 // Close this InformatiobLevel and check the next one 00274 // 00275 00276 NtClose (LevelInformation); 00277 } 00278 00279 // 00280 // If no Rescan, remove our count from the busy flag 00281 // 00282 00283 if (!Rescan && 00284 InterlockedDecrement (&ExpCheckSystemInfoBusy) >= 0) { 00285 00286 // 00287 // Some other worker thread attempted to perform a scan. Reset 00288 // counter to 1 and loop 00289 // 00290 00291 ExInterlockedExchangeUlong ((PULONG) &ExpCheckSystemInfoBusy, 0, &ExpCheckSystemInfoLock); 00292 Rescan = TRUE; 00293 } 00294 00295 } while (Rescan); 00296 00297 // 00298 // Cleanup 00299 // 00300 00301 NtClose (SystemInformation); 00302 } 00303 00304 #endif // _PNP_POWER_

Generated on Sat May 15 19:39:57 2004 for test by doxygen 1.3.7