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_