00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include "cmp.h"
00025
00026 extern LIST_ENTRY
CmpHiveListHead;
00027
00028
VOID
00029
CmpInitializeHiveList(
00030 VOID
00031 );
00032
00033
00034
00035
00036
00037
00038
00039
00040 #define LAZY_FLUSH_INTERVAL_IN_SECONDS 5
00041
00042
00043
00044
00045
00046
00047 #define LAZY_FLUSH_TIMEOUT_IN_SECONDS 1
00048
00049 #define SECOND_MULT 10*1000*1000 // 10->mic, 1000->mil, 1000->second
00050
00051 PKPROCESS CmpSystemProcess;
00052 KTIMER CmpLazyFlushTimer;
00053 KDPC CmpLazyFlushDpc;
00054 WORK_QUEUE_ITEM CmpLazyWorkItem;
00055
00056 BOOLEAN
CmpLazyFlushPending =
FALSE;
00057
00058 extern BOOLEAN
CmpNoWrite;
00059 extern BOOLEAN
CmpWasSetupBoot;
00060 extern BOOLEAN
HvShutdownComplete;
00061 extern BOOLEAN
CmpProfileLoaded;
00062
00063
00064
00065
00066 extern BOOLEAN
CmpDiskFullWorkerPopupDisplayed;
00067
00068
00069
00070
00071 extern BOOLEAN
CmpCannotWriteConfiguration;
00072
00073
#if DBG
00074
PKTHREAD CmpCallerThread =
NULL;
00075
#endif
00076
00077
00078
00079
00080
00081
VOID
00082
CmpLazyFlushWorker(
00083 IN PVOID Parameter
00084 );
00085
00086
VOID
00087
CmpLazyFlushDpcRoutine(
00088 IN
PKDPC Dpc,
00089 IN PVOID DeferredContext,
00090 IN PVOID SystemArgument1,
00091 IN PVOID SystemArgument2
00092 );
00093
00094
VOID
00095
CmpDiskFullWarningWorker(
00096 IN PVOID WorkItem
00097 );
00098
00099
VOID
00100
CmpDiskFullWarning(
00101 VOID
00102 );
00103
00104
#ifdef ALLOC_PRAGMA
00105
#pragma alloc_text(PAGE,CmpWorker)
00106
#pragma alloc_text(PAGE,CmpLazyFlush)
00107
#pragma alloc_text(PAGE,CmpLazyFlushWorker)
00108
#pragma alloc_text(PAGE,CmpDiskFullWarningWorker)
00109
#pragma alloc_text(PAGE,CmpDiskFullWarning)
00110
#endif
00111
00112
00113
00114
VOID
00115 CmpWorker(
00116 IN
PREGISTRY_COMMAND CommandArea
00117 )
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 {
00134
NTSTATUS Status;
00135
PCMHIVE CmHive;
00136 IO_STATUS_BLOCK IoStatusBlock;
00137 PUNICODE_STRING
FileName;
00138 ULONG i;
00139 HANDLE
Handle;
00140 PFILE_RENAME_INFORMATION RenameInfo;
00141 PLIST_ENTRY p;
00142 BOOLEAN result;
00143 HANDLE NullHandle;
00144
00145
PAGED_CODE();
00146
00147
switch (
CommandArea->
Command) {
00148
00149
case REG_CMD_INIT:
00150
00151
00152
00153
KeInitializeDpc(&
CmpLazyFlushDpc,
00154
CmpLazyFlushDpcRoutine,
00155
NULL);
00156
00157
KeInitializeTimer(&
CmpLazyFlushTimer);
00158
00159
ExInitializeWorkItem(&
CmpLazyWorkItem,
CmpLazyFlushWorker,
NULL);
00160
00161
CmpNoWrite =
FALSE;
00162
00163
CmpWasSetupBoot =
CommandArea->
SetupBoot;
00164
if (
CommandArea->
SetupBoot ==
FALSE) {
00165
CmpInitializeHiveList();
00166 }
00167
00168
00169
00170
00171
CmpDoFlushAll();
00172
break;
00173
00174
case REG_CMD_FLUSH_KEY:
00175
CommandArea->
Status =
00176
CmFlushKey(
CommandArea->
Hive,
CommandArea->
Cell);
00177
break;
00178
00179
case REG_CMD_REFRESH_HIVE:
00180
00181
00182
00183
HvRefreshHive(
CommandArea->
Hive);
00184
break;
00185
00186
case REG_CMD_FILE_SET_SIZE:
00187
CommandArea->
Status =
CmpDoFileSetSize(
00188
CommandArea->
Hive,
00189
CommandArea->
FileType,
00190
CommandArea->
FileSize
00191 );
00192
break;
00193
00194
case REG_CMD_HIVE_OPEN:
00195
00196
00197
00198
00199
FileName =
CommandArea->
FileAttributes->ObjectName;
00200
00201
CommandArea->
Status =
CmpInitHiveFromFile(
FileName,
00202 0,
00203 &
CommandArea->
CmHive,
00204 &
CommandArea->
Allocate,
00205 &
CommandArea->
RegistryLockAquired);
00206
00207
00208
00209
00210
00211
if (((
CommandArea->
Status == STATUS_ACCESS_DENIED) ||
00212 (
CommandArea->
Status == STATUS_NO_SUCH_USER) ||
00213 (
CommandArea->
Status == STATUS_WRONG_PASSWORD) ||
00214 (
CommandArea->
Status == STATUS_ACCOUNT_EXPIRED) ||
00215 (
CommandArea->
Status == STATUS_ACCOUNT_DISABLED) ||
00216 (
CommandArea->
Status == STATUS_ACCOUNT_RESTRICTION)) &&
00217 (
CommandArea->
ImpersonationContext !=
NULL)) {
00218
00219
00220
00221
00222
Status =
SeImpersonateClientEx(
00223
CommandArea->
ImpersonationContext,
00224
NULL);
00225
00226
if (
NT_SUCCESS(
Status ) ) {
00227
00228
CommandArea->
Status =
CmpInitHiveFromFile(
FileName,
00229 0,
00230 &
CommandArea->
CmHive,
00231 &
CommandArea->
Allocate,
00232 &
CommandArea->
RegistryLockAquired);
00233 NullHandle =
NULL;
00234
00235
PsRevertToSelf();
00236 }
00237 }
00238
00239
break;
00240
00241
case REG_CMD_HIVE_CLOSE:
00242
00243
00244
00245
00246 CmHive =
CommandArea->
CmHive;
00247
00248
for (i=0; i<
HFILE_TYPE_MAX; i++) {
00249
if (CmHive->
FileHandles[i] !=
NULL) {
00250 ZwClose(CmHive->
FileHandles[i]);
00251 CmHive->
FileHandles[i] =
NULL;
00252 }
00253 }
00254
CommandArea->
Status = STATUS_SUCCESS;
00255
break;
00256
00257
case REG_CMD_HIVE_READ:
00258
00259
00260
00261
00262 result =
CmpFileRead(
00263 (
PHHIVE)
CommandArea->
CmHive,
00264
CommandArea->
FileType,
00265
CommandArea->
Offset,
00266
CommandArea->
Buffer,
00267
CommandArea->
FileSize
00268 );
00269
if (result) {
00270
CommandArea->
Status = STATUS_SUCCESS;
00271 }
else {
00272
CommandArea->
Status = STATUS_REGISTRY_IO_FAILED;
00273 }
00274
break;
00275
00276
case REG_CMD_SHUTDOWN:
00277
00278
00279
00280
00281
CmpDoFlushAll();
00282
00283
00284
00285
00286 p=
CmpHiveListHead.Flink;
00287
while (p!=&
CmpHiveListHead) {
00288 CmHive = CONTAINING_RECORD(p,
CMHIVE,
HiveList);
00289
for (i=0; i<
HFILE_TYPE_MAX; i++) {
00290
if (CmHive->
FileHandles[i] !=
NULL) {
00291 ZwClose(CmHive->
FileHandles[i]);
00292 CmHive->
FileHandles[i] =
NULL;
00293 }
00294 }
00295 p=p->Flink;
00296 }
00297
00298
break;
00299
00300
case REG_CMD_RENAME_HIVE:
00301
00302
00303
00304
Handle =
CommandArea->
CmHive->
FileHandles[
HFILE_TYPE_PRIMARY];
00305
if (
CommandArea->
OldName !=
NULL) {
00306
ASSERT_PASSIVE_LEVEL();
00307
Status = ZwQueryObject(
Handle,
00308 ObjectNameInformation,
00309
CommandArea->
OldName,
00310
CommandArea->
NameInfoLength,
00311 &
CommandArea->
NameInfoLength);
00312
if (!
NT_SUCCESS(
Status)) {
00313
CommandArea->
Status =
Status;
00314
break;
00315 }
00316 }
00317
00318 RenameInfo =
ExAllocatePool(
PagedPool,
00319
sizeof(FILE_RENAME_INFORMATION) +
00320
CommandArea->
NewName->Length);
00321
if (RenameInfo ==
NULL) {
00322
CommandArea->
Status = STATUS_INSUFFICIENT_RESOURCES;
00323
break;
00324 }
00325 RenameInfo->ReplaceIfExists =
FALSE;
00326 RenameInfo->RootDirectory =
NULL;
00327 RenameInfo->FileNameLength =
CommandArea->
NewName->Length;
00328 RtlMoveMemory(RenameInfo->FileName,
00329
CommandArea->
NewName->Buffer,
00330
CommandArea->
NewName->Length);
00331
00332
Status =
ZwSetInformationFile(
Handle,
00333 &IoStatusBlock,
00334 (PVOID)RenameInfo,
00335
sizeof(FILE_RENAME_INFORMATION) +
00336
CommandArea->
NewName->Length,
00337 FileRenameInformation);
00338
ExFreePool(RenameInfo);
00339
CommandArea->
Status =
Status;
00340
break;
00341
00342
case REG_CMD_ADD_HIVE_LIST:
00343
00344
00345
00346
Status =
CmpAddToHiveFileList(
CommandArea->
CmHive);
00347
CommandArea->
Status =
Status;
00348
break;
00349
00350
case REG_CMD_REMOVE_HIVE_LIST:
00351
00352
00353
00354
CmpRemoveFromHiveFileList(
CommandArea->
CmHive);
00355
CommandArea->
Status = STATUS_SUCCESS;
00356
break;
00357
00358
default:
00359
KeBugCheckEx(REGISTRY_ERROR,6,1,0,0);
00360
00361 }
00362
00363
return;
00364 }
00365
00366
00367
VOID
00368 CmpLazyFlush(
00369 VOID
00370 )
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 {
00390 LARGE_INTEGER DueTime;
00391
00392
PAGED_CODE();
00393
CMLOG(
CML_FLOW,
CMS_IO) {
00394 KdPrint((
"CmpLazyFlush: setting lazy flush timer\n"));
00395 }
00396
if (!
CmpNoWrite) {
00397
00398 DueTime.QuadPart = Int32x32To64(
LAZY_FLUSH_INTERVAL_IN_SECONDS,
00399 -
SECOND_MULT);
00400
00401
00402
00403
00404
00405
KeSetTimer(&
CmpLazyFlushTimer,
00406 DueTime,
00407 &
CmpLazyFlushDpc);
00408
00409 }
00410
00411
00412 }
00413
00414
00415
VOID
00416 CmpLazyFlushDpcRoutine(
00417 IN
PKDPC Dpc,
00418 IN PVOID DeferredContext,
00419 IN PVOID SystemArgument1,
00420 IN PVOID SystemArgument2
00421 )
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 {
00448
CMLOG(
CML_FLOW,
CMS_IO) {
00449 KdPrint((
"CmpLazyFlushDpc: queuing lazy flush work item\n"));
00450 }
00451
00452
if (!
CmpLazyFlushPending) {
00453
CmpLazyFlushPending =
TRUE;
00454
ExQueueWorkItem(&
CmpLazyWorkItem,
DelayedWorkQueue);
00455 }
00456
00457 }
00458
00459
00460
VOID
00461 CmpLazyFlushWorker(
00462 IN PVOID Parameter
00463 )
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 {
00483 BOOLEAN Result =
TRUE;
00484
00485
PAGED_CODE();
00486
00487
CMLOG(
CML_FLOW,
CMS_IO) {
00488 KdPrint((
"CmpLazyFlushWorker: flushing hives\n"));
00489 }
00490
00491
CmpLockRegistry();
00492
if (!
HvShutdownComplete) {
00493 Result =
CmpDoFlushAll();
00494 }
00495
CmpLazyFlushPending =
FALSE;
00496
CmpUnlockRegistry();
00497
00498
if(
CmpCannotWriteConfiguration ) {
00499
00500
00501
00502
if(Result) {
00503
00504
00505
00506
CmpCannotWriteConfiguration =
FALSE;
00507 }
else {
00508
00509
00510
00511
CmpDiskFullWarning();
00512
CmpLazyFlush();
00513 }
00514 }
00515 }
00516
00517
VOID
00518 CmpDiskFullWarningWorker(
00519 IN PVOID WorkItem
00520 )
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 {
00540
NTSTATUS Status;
00541 ULONG Response;
00542
00543
ExFreePool(WorkItem);
00544
00545
Status =
ExRaiseHardError(STATUS_DISK_FULL,
00546 0,
00547 0,
00548
NULL,
00549 OptionOk,
00550 &Response);
00551 }
00552
00553
00554
00555
VOID
00556 CmpDiskFullWarning(
00557 VOID
00558 )
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 {
00575
PWORK_QUEUE_ITEM WorkItem;
00576
00577
if( (!
CmpDiskFullWorkerPopupDisplayed) && (
CmpCannotWriteConfiguration) && (
ExReadyForErrors) && (
CmpProfileLoaded) ) {
00578
00579
00580
00581
00582 WorkItem =
ExAllocatePool(
NonPagedPool,
sizeof(
WORK_QUEUE_ITEM));
00583
if (WorkItem !=
NULL) {
00584
00585
CmpDiskFullWorkerPopupDisplayed =
TRUE;
00586
ExInitializeWorkItem(WorkItem,
00587
CmpDiskFullWarningWorker,
00588 WorkItem);
00589
ExQueueWorkItem(WorkItem,
DelayedWorkQueue);
00590 }
00591 }
00592 }