00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
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 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 {
00059     
ExQueueWorkItem (&ExpCheckSystemInfoWorkItem, DelayedWorkQueue);
00060 }
00061 
00062 
00063 
VOID
00064 
ExpCheckSystemInfoWork (
00065     IN PVOID Context
00066     )
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
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     
00112     
00113     
00114 
00115     
if (InterlockedIncrement (&ExpCheckSystemInfoBusy) != 0) {
00116         
return ;
00117     }
00118 
00119     
RtlInitUnicodeString (&ValueString,  ExpWstrSystemInformationValue);
00120 
00121     
00122     
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         
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     
00166     
00167 
00168     
do {
00169         Rescan = 
FALSE;
00170 
00171         
00172         
00173         
00174 
00175         Interval.QuadPart = -3000000;
00176         
KeDelayExecutionThread (KernelMode, FALSE, &Interval);
00177 
00178         
00179         
00180         
00181         
00182 
00183         
for (
Index=0; RegistryInformation[
Index].BufferSize; 
Index++) {
00184 
00185             
00186             
00187             
00188 
00189             
BufferSize = RegistryInformation[
Index].BufferSize;
00190             RtlZeroMemory (RegistryBuffer.Key.Data, BufferSize);
00191 
00192             
00193             
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             
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             
00229             
00230 
00231             
Status = 
NtQuerySystemInformation (
00232                             RegistryInformation[Index].InformationLevel,
00233                             &QueryBuffer.Key.Data,
00234                             BufferSize,
00235                             NULL
00236                         );
00237 
00238             
00239             
00240             
00241             
00242 
00243             
if (
NT_SUCCESS(Status)  &&
00244                 !RtlEqualMemory (RegistryBuffer.Key.Data,
00245                                  QueryBuffer.Key.Data,
00246                                  BufferSize) ) {
00247 
00248                 
00249                 
00250                 
00251 
00252                 
Status = 
NtSetValueKey (
00253                             LevelInformation,
00254                             &ValueString,
00255                             0L,
00256                             REG_BINARY,
00257                             QueryBuffer.Key.Data,
00258                             BufferSize
00259                             );
00260 
00261                 
00262                 
00263                 
00264 
00265                 
ExNotifyCallback (
00266                     ExCbSetSystemInformation,
00267                     (PVOID) RegistryInformation[Index].InformationLevel,
00268                     (PVOID) NULL
00269                 );
00270             }
00271 
00272             
00273             
00274             
00275 
00276             
NtClose (LevelInformation);
00277         }
00278 
00279         
00280         
00281         
00282 
00283         
if (!Rescan &&
00284             InterlockedDecrement (&ExpCheckSystemInfoBusy) >= 0) {
00285 
00286             
00287             
00288             
00289             
00290 
00291             ExInterlockedExchangeUlong ((PULONG) &ExpCheckSystemInfoBusy, 0, &ExpCheckSystemInfoLock);
00292             Rescan = 
TRUE;
00293         }
00294 
00295     } 
while (Rescan);
00296 
00297     
00298     
00299     
00300 
00301     
NtClose (SystemInformation);
00302 }
00303 
00304 
#endif  // _PNP_POWER_