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
00026
00027
00028
00029
#include "cmp.h"
00030
#pragma hdrstop
00031
#include "arccodes.h"
00032
00033
00034
00035
00036
00037 #define INIT_SYSTEMROOT_HIVEPATH L"\\SystemRoot\\System32\\Config\\"
00038
00039 #define INIT_REGISTRY_MASTERPATH L"\\REGISTRY\\"
00040
00041
#if DBG
00042
00043
00044
00045
00046 ULONG
CmLogLevel = 1;
00047 ULONG
CmLogSelect =
CMS_DEFAULT;
00048
#endif
00049
00050 extern PKPROCESS CmpSystemProcess;
00051 extern ERESOURCE CmpRegistryLock;
00052 extern FAST_MUTEX CmpKcbLock;
00053 extern FAST_MUTEX CmpPostLock;
00054
00055 extern BOOLEAN
CmFirstTime;
00056
00057
00058
00059
00060
00061 extern HIVE_LIST_ENTRY CmpMachineHiveList[];
00062
00063 #define SYSTEM_HIVE_INDEX 3
00064 #define CLONE_HIVE_INDEX 6
00065
00066 #define SYSTEM_PATH L"\\registry\\machine\\system"
00067
00068
00069
00070
00071 #define HKEY_PERFORMANCE_TEXT (( HANDLE ) (ULONG_PTR)((LONG)0x80000050) )
00072 #define HKEY_PERFORMANCE_NLSTEXT (( HANDLE ) (ULONG_PTR)((LONG)0x80000060) )
00073
00074 extern UNICODE_STRING
CmpSystemFileName;
00075 extern UNICODE_STRING
CmSymbolicLinkValueName;
00076 extern UNICODE_STRING
CmpLoadOptions;
00077 extern PWCHAR
CmpProcessorControl;
00078 extern PWCHAR
CmpControlSessionManager;
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 extern PCMHIVE CmpMasterHive;
00097 extern BOOLEAN
CmpNoMasterCreates;
00098
00099
00100
00101
00102 extern LIST_ENTRY
CmpHiveListHead;
00103
00104
00105
00106
00107
00108
00109 extern POBJECT_TYPE CmpKeyObjectType;
00110
00111
00112
00113
00114
00115 #define CMP_KEY_INVALID_ATTRIBUTES (OBJ_EXCLUSIVE |\
00116
OBJ_PERMANENT)
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 extern BOOLEAN
CmpNoWrite;
00132
00133 extern BOOLEAN
HvShutdownComplete;
00134
00135
00136
00137
00138 extern PUCHAR
CmpStashBuffer;
00139 extern ULONG
CmpStashBufferSize;
00140
00141
00142
00143
00144
00145 extern BOOLEAN
CmpCannotWriteConfiguration;
00146
00147
00148
00149
00150 extern UNICODE_STRING
nullclass;
00151
00152
00153
00154
00155
VOID
00156
CmpCreatePredefined(
00157 IN HANDLE Root,
00158 IN PWSTR KeyName,
00159 IN HANDLE PredefinedHandle
00160 );
00161
00162
VOID
00163
CmpCreatePerfKeys(
00164 VOID
00165 );
00166
00167 BOOLEAN
00168
CmpLinkKeyToHive(
00169 PWSTR KeyPath,
00170 PWSTR HivePath
00171 );
00172
00173 BOOLEAN
00174
CmpValidateAlternate(
00175 IN HANDLE FileHandle,
00176 IN
PCMHIVE PrimaryHive
00177 );
00178
00179
NTSTATUS
00180
CmpCreateControlSet(
00181 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00182 );
00183
00184
NTSTATUS
00185
CmpCloneControlSet(
00186 VOID
00187 );
00188
00189 BOOLEAN
00190
CmpCreateObjectTypes(
00191 VOID
00192 );
00193
00194 BOOLEAN
00195
CmpCreateRegistryRoot(
00196 VOID
00197 );
00198
00199 BOOLEAN
00200
CmpCreateRootNode(
00201 IN
PHHIVE Hive,
00202 IN PWSTR Name,
00203 OUT PHCELL_INDEX RootCellIndex
00204 );
00205
00206
VOID
00207
CmpFreeDriverList(
00208 IN
PHHIVE Hive,
00209 IN PLIST_ENTRY DriverList
00210 );
00211
00212
VOID
00213
CmpInitializeHiveList(
00214 VOID
00215 );
00216
00217 BOOLEAN
00218
CmpInitializeSystemHive(
00219 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00220 );
00221
00222
NTSTATUS
00223
CmpInterlockedFunction (
00224 PWCHAR RegistryValueKey,
00225 VOID (*InterlockedFunction)(VOID)
00226 );
00227
00228
VOID
00229
CmpConfigureProcessors (
00230 VOID
00231 );
00232
00233
#if i386
00234
VOID
00235
KeOptimizeProcessorControlState (
00236 VOID
00237 );
00238
#endif
00239
00240
NTSTATUS
00241
CmpAddDockingInfo (
00242 IN HANDLE Key,
00243 IN
PROFILE_PARAMETER_BLOCK * ProfileBlock
00244 );
00245
00246
NTSTATUS
00247
CmpAddAliasEntry (
00248 IN HANDLE IDConfigDB,
00249 IN
PROFILE_PARAMETER_BLOCK * ProfileBlock,
00250 IN ULONG ProfileNumber
00251 );
00252
00253
NTSTATUS CmpDeleteCloneTree(VOID);
00254
00255
VOID
00256
CmpDiskFullWarning(
00257 VOID
00258 );
00259
00260
00261
#ifdef ALLOC_PRAGMA
00262
#pragma alloc_text(INIT,CmInitSystem1)
00263
#pragma alloc_text(INIT,CmpCreateControlSet)
00264
#pragma alloc_text(INIT,CmpCloneControlSet)
00265
#pragma alloc_text(INIT,CmpCreateObjectTypes)
00266
#pragma alloc_text(INIT,CmpCreateRegistryRoot)
00267
#pragma alloc_text(INIT,CmpCreateRootNode)
00268
#pragma alloc_text(INIT,CmpInitializeSystemHive)
00269
#pragma alloc_text(INIT,CmGetSystemDriverList)
00270
#pragma alloc_text(INIT,CmpFreeDriverList)
00271
#pragma alloc_text(PAGE,CmpInitializeHiveList)
00272
#pragma alloc_text(PAGE,CmpLinkHiveToMaster)
00273
#pragma alloc_text(PAGE,CmpSetVersionData)
00274
#pragma alloc_text(PAGE,CmBootLastKnownGood)
00275
#pragma alloc_text(PAGE,CmpSaveBootControlSet)
00276
#pragma alloc_text(PAGE,CmpInitHiveFromFile)
00277
#pragma alloc_text(INIT,CmpIsLastKnownGoodBoot)
00278
#pragma alloc_text(PAGE,CmpLinkKeyToHive)
00279
#pragma alloc_text(PAGE,CmShutdownSystem)
00280
#pragma alloc_text(PAGE,CmpValidateAlternate)
00281
#pragma alloc_text(PAGE,CmpCreatePredefined)
00282
#pragma alloc_text(PAGE,CmpCreatePerfKeys)
00283
#pragma alloc_text(PAGE,CmpInterlockedFunction)
00284
#pragma alloc_text(PAGE,CmpConfigureProcessors)
00285
#pragma alloc_text(INIT,CmpAddDockingInfo)
00286
#pragma alloc_text(INIT,CmpAddAliasEntry)
00287
#pragma alloc_text(PAGE,CmpDeleteCloneTree)
00288
#endif
00289
00290
00291
00292 BOOLEAN
00293 CmInitSystem1(
00294 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00295 )
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 {
00345 HANDLE key1;
00346 OBJECT_ATTRIBUTES
ObjectAttributes;
00347
NTSTATUS status;
00348
NTSTATUS status2;
00349 PSECURITY_DESCRIPTOR SecurityDescriptor;
00350
PCMHIVE HardwareHive;
00351
PCMHIVE CloneHive;
00352 UNICODE_STRING NameString;
00353
00354
PAGED_CODE();
00355
CMLOG(
CML_MAJOR,
CMS_INIT) KdPrint((
"CmInitSystem1\n"));
00356
00357
00358
00359
00360
00361
00362
CmpInitializeRegistryNames();
00363
00364
00365
00366
00367
CmpComputeGlobalQuotaAllowed();
00368
00369
00370
00371
00372 InitializeListHead(&
CmpHiveListHead);
00373
00374
00375
00376
00377
ExInitializeResource(&
CmpRegistryLock);
00378
00379
00380
00381
00382
ExInitializeFastMutex(&
CmpKcbLock);
00383
00384
00385
00386
00387
ExInitializeFastMutex(&
CmpPostLock);
00388
00389
00390
00391
00392
CmpInitializeCache ();
00393
00394
00395
00396
00397
CmpSystemProcess = &
PsGetCurrentProcess()->Pcb;
00398
00399
CmpLockRegistryExclusive();
00400
00401
00402
00403
00404
if (!
CmpCreateObjectTypes()) {
00405
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
00406 KdPrint((
"CmInitSystem1: CmpCreateObjectTypes failed\n"));
00407 }
00408
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,1,0,0);
00409
return FALSE;
00410 }
00411
00412
00413
00414
00415
00416 status =
CmpInitializeHive(&
CmpMasterHive,
00417
HINIT_CREATE,
00418
HIVE_VOLATILE,
00419
HFILE_TYPE_PRIMARY,
00420
NULL,
00421
NULL,
00422
NULL,
00423
NULL,
00424
NULL,
00425
NULL);
00426
if (!
NT_SUCCESS(status)) {
00427
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
00428 KdPrint((
"CmInitSystem1: CmpInitializeHive(master) failed\n"));
00429 }
00430
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,2,0,0);
00431
return (
FALSE);
00432 }
00433
00434
00435
00436
00437
00438
CmpStashBuffer =
ExAllocatePoolWithTag(
PagedPool,
HBLOCK_SIZE,'bSmC');
00439
if (
CmpStashBuffer ==
NULL) {
00440
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,3,0,0);
00441
return FALSE;
00442 }
00443
CmpStashBufferSize =
HBLOCK_SIZE;
00444
00445
00446
00447
00448
if (!
CmpCreateRegistryRoot()) {
00449
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
00450 KdPrint((
"CmInitSystem1: CmpCreateRegistryRoot failed\n"));
00451 }
00452
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,4,0,0);
00453
return FALSE;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463 SecurityDescriptor =
CmpHiveRootSecurityDescriptor();
00464
00465 InitializeObjectAttributes(
00466 &
ObjectAttributes,
00467 &
CmRegistryMachineName,
00468 OBJ_CASE_INSENSITIVE,
00469 (HANDLE)
NULL,
00470 SecurityDescriptor
00471 );
00472
00473
if (!
NT_SUCCESS(
NtCreateKey(
00474 &key1,
00475 KEY_READ | KEY_WRITE,
00476 &
ObjectAttributes,
00477 0,
00478 &
nullclass,
00479 0,
00480
NULL
00481 )))
00482 {
00483
ExFreePool(SecurityDescriptor);
00484
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
00485 KdPrint((
"CmInitSystem1: NtCreateKey(MACHINE) failed\n"));
00486 }
00487
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,5,0,0);
00488
return FALSE;
00489 }
00490
00491
NtClose(key1);
00492
00493 InitializeObjectAttributes(
00494 &
ObjectAttributes,
00495 &
CmRegistryUserName,
00496 OBJ_CASE_INSENSITIVE,
00497 (HANDLE)
NULL,
00498 SecurityDescriptor
00499 );
00500
00501
if (!
NT_SUCCESS(
NtCreateKey(
00502 &key1,
00503 KEY_READ | KEY_WRITE,
00504 &
ObjectAttributes,
00505 0,
00506 &
nullclass,
00507 0,
00508
NULL
00509 )))
00510 {
00511
ExFreePool(SecurityDescriptor);
00512
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
00513 KdPrint((
"CmInitSystem1: NtCreateKey(USER) failed\n"));
00514 }
00515
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,6,0,0);
00516
return FALSE;
00517 }
00518
00519
NtClose(key1);
00520
00521
00522
00523
00524
00525
if (!
CmpInitializeSystemHive(LoaderBlock)) {
00526
ExFreePool(SecurityDescriptor);
00527
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
00528 KdPrint((
"CmpInitSystem1: "));
00529 KdPrint((
"Hive allocation failure for SYSTEM\n"));
00530 }
00531
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,7,0,0);
00532
return(
FALSE);
00533 }
00534
00535
00536
00537
00538 status =
CmpCreateControlSet(LoaderBlock);
00539
if (!
NT_SUCCESS(status)) {
00540
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,8,0,0);
00541
return(
FALSE);
00542 }
00543
00544
00545
00546
00547
00548
00549
#if CLONE_CONTROL_SET
00550
00551
00552
00553
00554
00555 status =
CmpInitializeHive(&CloneHive,
00556
HINIT_CREATE,
00557
HIVE_VOLATILE,
00558
HFILE_TYPE_PRIMARY,
00559
NULL,
00560
NULL,
00561
NULL,
00562
NULL,
00563
NULL,
00564
NULL);
00565
if (!
NT_SUCCESS(status)) {
00566
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
00567 KdPrint((
"CmpInitSystem1: "));
00568 KdPrint((
"Could not initialize CLONE hive\n"));
00569 }
00570
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,9,0,0);
00571
return(
FALSE);
00572 }
00573
00574
if (
CmpLinkHiveToMaster(
00575 &
CmRegistrySystemCloneName,
00576
NULL,
00577 CloneHive,
00578
TRUE,
00579 SecurityDescriptor
00580 ) != STATUS_SUCCESS)
00581 {
00582
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
00583 KdPrint((
"CmInitSystem1: CmpLinkHiveToMaster(Clone) failed\n"));
00584 }
00585
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,10,0,0);
00586
return FALSE;
00587 }
00588
CmpAddToHiveFileList(CloneHive);
00589
CmpMachineHiveList[
CLONE_HIVE_INDEX].
CmHive = CloneHive;
00590
00591
CmpLinkKeyToHive(
00592
L"\\Registry\\Machine\\System\\Clone",
00593
L"\\Registry\\Machine\\CLONE\\CLONE"
00594 );
00595
00596
00597
00598
00599
00600 status =
CmpCloneControlSet();
00601
00602
00603
00604
00605
ASSERT(
NT_SUCCESS(status));
00606
00607
#endif
00608
00609
00610
00611
00612 status =
CmpInitializeHive(&HardwareHive,
00613
HINIT_CREATE,
00614
HIVE_VOLATILE,
00615
HFILE_TYPE_PRIMARY,
00616
NULL,
00617
NULL,
00618
NULL,
00619
NULL,
00620
NULL,
00621
NULL);
00622
if (!
NT_SUCCESS(status)) {
00623
ExFreePool(SecurityDescriptor);
00624
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
00625 KdPrint((
"CmpInitSystem1: "));
00626 KdPrint((
"Could not initialize HARDWARE hive\n"));
00627 }
00628
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,11,0,0);
00629
return(
FALSE);
00630 }
00631
00632
00633
00634
00635
if (
CmpLinkHiveToMaster(
00636 &
CmRegistryMachineHardwareName,
00637
NULL,
00638 HardwareHive,
00639
TRUE,
00640 SecurityDescriptor
00641 ) != STATUS_SUCCESS)
00642 {
00643
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
00644 KdPrint((
"CmInitSystem1: CmpLinkHiveToMaster(Hardware) failed\n"));
00645 }
00646
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,12,0,0);
00647
return FALSE;
00648 }
00649
CmpAddToHiveFileList(HardwareHive);
00650
00651
ExFreePool(SecurityDescriptor);
00652
00653
CmpMachineHiveList[0].
CmHive = HardwareHive;
00654
00655
00656
00657
00658 status =
CmpInitializeHardwareConfiguration(LoaderBlock);
00659
00660
if (!
NT_SUCCESS(status)) {
00661
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,13,0,0);
00662
return(
FALSE);
00663 }
00664
00665
CmpNoMasterCreates =
TRUE;
00666
CmpUnlockRegistry();
00667
00668
00669
00670
00671 status =
CmpInitializeMachineDependentConfiguration(LoaderBlock);
00672
00673
00674
00675
00676
00677
RtlInitUnicodeString(
00678 &NameString,
00679
L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control"
00680 );
00681
00682 InitializeObjectAttributes(
00683 &
ObjectAttributes,
00684 &NameString,
00685 OBJ_CASE_INSENSITIVE,
00686 (HANDLE)
NULL,
00687
NULL
00688 );
00689
00690 status2 =
NtOpenKey(
00691 &key1,
00692 KEY_WRITE,
00693 &
ObjectAttributes
00694 );
00695
00696
if (
NT_SUCCESS(status2)) {
00697
RtlInitUnicodeString(
00698 &NameString,
00699
L"SystemStartOptions"
00700 );
00701
00702
NtSetValueKey(
00703 key1,
00704 &NameString,
00705 0,
00706 REG_SZ,
00707
CmpLoadOptions.Buffer,
00708
CmpLoadOptions.Length
00709 );
00710
00711
NtClose(key1);
00712 }
00713
ExFreePool(
CmpLoadOptions.Buffer);
00714
00715
00716
if (!
NT_SUCCESS(status)) {
00717
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,14,0,0);
00718
return(
FALSE);
00719 }
00720
00721
return TRUE;
00722 }
00723
00724
00725
VOID
00726 CmpInitializeHiveList(
00727 VOID
00728 )
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 {
00751
#define MAX_NAME 128
00752
UCHAR FileBuffer[
MAX_NAME];
00753 UCHAR RegBuffer[
MAX_NAME];
00754
00755 UNICODE_STRING TempName;
00756 UNICODE_STRING
FileName;
00757 UNICODE_STRING RegName;
00758
00759
USHORT FileStart;
00760
USHORT RegStart;
00761 ULONG i;
00762
PCMHIVE CmHive;
00763 BOOLEAN Allocate;
00764 HANDLE PrimaryHandle;
00765 HANDLE LogHandle;
00766 ULONG PrimaryDisposition;
00767 ULONG SecondaryDisposition;
00768 ULONG Length;
00769
NTSTATUS Status;
00770 PSECURITY_DESCRIPTOR SecurityDescriptor;
00771 BOOLEAN RegistryLocked =
TRUE;
00772
00773 PVOID ErrorParameters;
00774 ULONG ErrorResponse;
00775 ULONG ClusterSize;
00776
00777
PAGED_CODE();
00778
CMLOG(
CML_MAJOR,
CMS_INIT) KdPrint((
"CmpInitializeHiveList\n"));
00779
00780
CmpNoWrite =
FALSE;
00781
00782
FileName.MaximumLength =
MAX_NAME;
00783
FileName.Length = 0;
00784
FileName.Buffer = (PWSTR)&(FileBuffer[0]);
00785
00786 RegName.MaximumLength =
MAX_NAME;
00787 RegName.Length = 0;
00788 RegName.Buffer = (PWSTR)&(RegBuffer[0]);
00789
00790
RtlInitUnicodeString(
00791 &TempName,
00792
INIT_SYSTEMROOT_HIVEPATH
00793 );
00794
RtlAppendStringToString((PSTRING)&
FileName, (PSTRING)&TempName);
00795 FileStart =
FileName.Length;
00796
00797
RtlInitUnicodeString(
00798 &TempName,
00799
INIT_REGISTRY_MASTERPATH
00800 );
00801
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
00802 RegStart = RegName.Length;
00803
00804 SecurityDescriptor =
CmpHiveRootSecurityDescriptor();
00805
00806
00807
for (i = 0;
CmpMachineHiveList[i].
Name !=
NULL; i++) {
00808
00809
00810
00811
00812
00813
00814
00815
00816 RegName.Length = RegStart;
00817
RtlInitUnicodeString(
00818 &TempName,
00819
CmpMachineHiveList[i].
BaseName
00820 );
00821
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
00822
00823
00824
00825
if (RegName.Buffer[ (RegName.Length /
sizeof( WCHAR )) - 1 ] ==
'\\') {
00826
RtlInitUnicodeString(
00827 &TempName,
00828
CmpMachineHiveList[i].
Name
00829 );
00830
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
00831 }
00832
00833
00834
00835
00836
00837
RtlInitUnicodeString(
00838 &TempName,
00839
CmpMachineHiveList[i].
Name
00840 );
00841
FileName.Length = FileStart;
00842
RtlAppendStringToString((PSTRING)&
FileName, (PSTRING)&TempName);
00843
00844
00845
00846
00847
if (
CmpMachineHiveList[i].
CmHive ==
NULL) {
00848
00849
00850
00851
00852
00853 Allocate =
TRUE;
00854
Status =
CmpInitHiveFromFile(&
FileName,
00855
CmpMachineHiveList[i].Flags,
00856 &CmHive,
00857 &Allocate,
00858 &RegistryLocked
00859 );
00860
00861
if ( (!
NT_SUCCESS(
Status)) ||
00862 (CmHive->
FileHandles[
HFILE_TYPE_LOG] ==
NULL) )
00863 {
00864 ErrorParameters = &
FileName;
00865
ExRaiseHardError(
00866 STATUS_CANNOT_LOAD_REGISTRY_FILE,
00867 1,
00868 1,
00869 (PULONG_PTR)&ErrorParameters,
00870 OptionOk,
00871 &ErrorResponse
00872 );
00873
00874
continue;
00875
00876 }
00877
00878
CMLOG(
CML_MINOR,
CMS_INIT) {
00879 KdPrint((
"CmpInitializeHiveList:\n"));
00880 KdPrint((
"\tCmHive for '%ws' @",
CmpMachineHiveList[i]));
00881 KdPrint((
"%08lx", CmHive));
00882 }
00883
00884
00885
00886
00887
if (
CmpLinkHiveToMaster(
00888 &RegName,
00889
NULL,
00890 CmHive,
00891 Allocate,
00892 SecurityDescriptor
00893 ) != STATUS_SUCCESS)
00894 {
00895
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
00896 KdPrint((
"CmpInitializeHiveList: "));
00897 KdPrint((
"CmpLinkHiveToMaster failed\n"));
00898 KdPrint((
"\ti=%d s='%ws'\n", i,
CmpMachineHiveList[i]));
00899 }
00900
KeBugCheckEx(CONFIG_LIST_FAILED,5,2,i,(ULONG_PTR)&RegName);
00901 }
00902
CmpAddToHiveFileList(CmHive);
00903
00904
if (Allocate) {
00905
HvSyncHive((
PHHIVE)CmHive);
00906 }
00907
00908 }
else {
00909
00910 CmHive =
CmpMachineHiveList[i].
CmHive;
00911
00912
if (!(CmHive->
Hive.
HiveFlags &
HIVE_VOLATILE)) {
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
Status =
CmpOpenHiveFiles(&
FileName,
00925
L".ALT",
00926 &PrimaryHandle,
00927 &LogHandle,
00928 &PrimaryDisposition,
00929 &SecondaryDisposition,
00930
TRUE,
00931
TRUE,
00932 &ClusterSize);
00933
00934
if ( ( !
NT_SUCCESS(
Status)) ||
00935 (LogHandle ==
NULL) )
00936 {
00937 ErrorParameters = &
FileName;
00938
ExRaiseHardError(
00939 STATUS_CANNOT_LOAD_REGISTRY_FILE,
00940 1,
00941 1,
00942 (PULONG_PTR)&ErrorParameters,
00943 OptionOk,
00944 &ErrorResponse
00945 );
00946
00947
00948
00949
00950
00951
00952
00953
KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,5,3,i,
Status);
00954 }
00955
00956 CmHive->
FileHandles[
HFILE_TYPE_ALTERNATE] = LogHandle;
00957 CmHive->
FileHandles[
HFILE_TYPE_PRIMARY] = PrimaryHandle;
00958
00959 Length = CmHive->
Hive.Storage[
Stable].Length +
HBLOCK_SIZE;
00960
00961
00962
00963
00964
00965
00966
00967
00968
if (CmHive->
Hive.
Cluster != ClusterSize) {
00969
00970
00971
00972
00973
00974
00975
00976 PRTL_BITMAP
BitMap;
00977 ULONG
Index;
00978
00979
BitMap = &(CmHive->
Hive.
DirtyVector);
00980
for (
Index = 0;
00981
Index < CmHive->
Hive.
DirtyVector.SizeOfBitMap;
00982
Index += ClusterSize)
00983 {
00984
if (!
RtlAreBitsClear (
BitMap,
Index, ClusterSize)) {
00985
RtlSetBits (
BitMap,
Index, ClusterSize);
00986 }
00987 }
00988
00989
00990
00991 CmHive->
Hive.
DirtyCount =
RtlNumberOfSetBits(&CmHive->
Hive.
DirtyVector);
00992 CmHive->
Hive.
Cluster = ClusterSize;
00993 }
00994
00995
if (!
CmpFileSetSize(
00996 (
PHHIVE)CmHive,
HFILE_TYPE_PRIMARY, Length) ||
00997 !
CmpFileSetSize(
00998 (
PHHIVE)CmHive,
HFILE_TYPE_ALTERNATE, Length)
00999 )
01000 {
01001
01002
01003
01004
01005
01006
CmpCannotWriteConfiguration =
TRUE;
01007
01008
01009 }
01010
01011
ASSERT(FIELD_OFFSET(
CMHIVE,
Hive) == 0);
01012
01013
if ( (PrimaryDisposition == FILE_CREATED) ||
01014 (SecondaryDisposition == FILE_CREATED) ||
01015 (!
CmpValidateAlternate(LogHandle,CmHive)))
01016 {
01017
01018
01019
01020 CmHive->FileHandles[
HFILE_TYPE_EXTERNAL] =
01021 CmHive->FileHandles[
HFILE_TYPE_ALTERNATE];
01022
Status =
HvWriteHive((
PHHIVE)CmHive);
01023 CmHive->FileHandles[
HFILE_TYPE_EXTERNAL] =
NULL;
01024
01025
if (!
NT_SUCCESS(
Status)) {
01026
01027
01028
01029
01030
01031
01032
01033
CmpCannotWriteConfiguration =
TRUE;
01034
01035
01036 }
01037 }
01038
CmpAddToHiveFileList(
CmpMachineHiveList[i].CmHive);
01039
01040
HvSyncHive((
PHHIVE)CmHive);
01041
01042
if(
CmpCannotWriteConfiguration ) {
01043
01044
01045
01046
CmpDiskFullWarning();
01047
CmpLazyFlush();
01048 }
01049 }
01050 }
01051 }
01052
01053
ExFreePool(SecurityDescriptor);
01054
01055
01056
01057
01058
CmpLinkKeyToHive(
01059
L"\\Registry\\Machine\\Security\\SAM",
01060
L"\\Registry\\Machine\\SAM\\SAM"
01061 );
01062
01063
01064
01065
01066
CmpCreatePerfKeys();
01067
01068
return;
01069 }
01070
01071
01072
01073 BOOLEAN
01074 CmpCreateObjectTypes(
01075 VOID
01076 )
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 {
01093
NTSTATUS Status;
01094
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
01095 UNICODE_STRING TypeName;
01096
01097
01098
01099
01100
01101
01102 GENERIC_MAPPING
CmpKeyMapping = {
01103 KEY_READ,
01104 KEY_WRITE,
01105 KEY_EXECUTE,
01106 KEY_ALL_ACCESS
01107 };
01108
01109
PAGED_CODE();
01110
01111
01112
01113
01114
01115
01116
01117
01118
RtlInitUnicodeString(&TypeName,
L"Key");
01119
01120
01121
01122
01123
01124 RtlZeroMemory(&ObjectTypeInitializer,
sizeof(ObjectTypeInitializer));
01125 ObjectTypeInitializer.Length =
sizeof(ObjectTypeInitializer);
01126 ObjectTypeInitializer.InvalidAttributes =
CMP_KEY_INVALID_ATTRIBUTES;
01127 ObjectTypeInitializer.GenericMapping =
CmpKeyMapping;
01128 ObjectTypeInitializer.ValidAccessMask = KEY_ALL_ACCESS;
01129 ObjectTypeInitializer.DefaultPagedPoolCharge =
sizeof(
CM_KEY_BODY);
01130 ObjectTypeInitializer.SecurityRequired =
TRUE;
01131 ObjectTypeInitializer.PoolType =
PagedPool;
01132 ObjectTypeInitializer.MaintainHandleCount =
FALSE;
01133 ObjectTypeInitializer.UseDefaultObject =
TRUE;
01134
01135 ObjectTypeInitializer.DumpProcedure =
NULL;
01136 ObjectTypeInitializer.OpenProcedure =
NULL;
01137 ObjectTypeInitializer.CloseProcedure =
CmpCloseKeyObject;
01138 ObjectTypeInitializer.DeleteProcedure =
CmpDeleteKeyObject;
01139 ObjectTypeInitializer.ParseProcedure =
CmpParseKey;
01140 ObjectTypeInitializer.SecurityProcedure =
CmpSecurityMethod;
01141 ObjectTypeInitializer.QueryNameProcedure =
CmpQueryKeyName;
01142
01143
Status =
ObCreateObjectType(
01144 &TypeName,
01145 &ObjectTypeInitializer,
01146 (PSECURITY_DESCRIPTOR)
NULL,
01147 &
CmpKeyObjectType
01148 );
01149
01150
01151
if (!
NT_SUCCESS(
Status)) {
01152
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
01153 KdPrint((
"CmpCreateObjectTypes: "));
01154 KdPrint((
"ObCreateObjectType(Key) failed %08lx\n",
Status));
01155 }
01156
return FALSE;
01157 }
01158
01159
return TRUE;
01160 }
01161
01162
01163
01164 BOOLEAN
01165 CmpCreateRegistryRoot(
01166 VOID
01167 )
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185 {
01186
NTSTATUS Status;
01187 UNICODE_STRING NullString = { 0, 0,
NULL };
01188 HANDLE ObjHandle;
01189 PVOID ObjectPointer;
01190
PCM_KEY_BODY Object;
01191 OBJECT_ATTRIBUTES
ObjectAttributes;
01192
PCM_KEY_CONTROL_BLOCK kcb;
01193
HCELL_INDEX RootCellIndex;
01194 PSECURITY_DESCRIPTOR SecurityDescriptor;
01195
01196
PAGED_CODE();
01197
01198
01199
01200
01201
if (!
CmpCreateRootNode(
01202 &(
CmpMasterHive->
Hive),
L"REGISTRY", &RootCellIndex))
01203 {
01204
return FALSE;
01205 }
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223 SecurityDescriptor =
CmpHiveRootSecurityDescriptor();
01224
01225 InitializeObjectAttributes(
01226 &
ObjectAttributes,
01227 &
CmRegistryRootName,
01228 OBJ_CASE_INSENSITIVE,
01229 (HANDLE)
NULL,
01230 SecurityDescriptor
01231 );
01232
01233
01234
Status =
ObCreateObject(
01235
KernelMode,
01236
CmpKeyObjectType,
01237 &
ObjectAttributes,
01238
UserMode,
01239
NULL,
01240
sizeof(
CM_KEY_BODY),
01241 0,
01242 0,
01243 (PVOID *)&Object
01244 );
01245
01246
ExFreePool(SecurityDescriptor);
01247
01248
if (!
NT_SUCCESS(
Status)) {
01249
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
01250 KdPrint((
"CmpCreateRegistryRoot: "));
01251 KdPrint((
"ObCreateObject(\\REGISTRY) failed %08lx\n",
Status));
01252 }
01253
return FALSE;
01254 }
01255
01256
01257
01258
01259
kcb =
CmpCreateKeyControlBlock(
01260 &(
CmpMasterHive->
Hive),
01261 RootCellIndex,
01262 (
PCM_KEY_NODE)
HvGetCell(&
CmpMasterHive->
Hive,RootCellIndex),
01263
NULL,
01264
FALSE,
01265 &
CmRegistryRootName
01266 );
01267
01268
if (
kcb==
NULL) {
01269
return(
FALSE);
01270 }
01271
01272
01273
01274
01275 Object->Type =
KEY_BODY_TYPE;
01276 Object->KeyControlBlock =
kcb;
01277 Object->NotifyBlock =
NULL;
01278 Object->Process =
PsGetCurrentProcess();
01279
ENLIST_KEYBODY_IN_KEYBODY_LIST(Object);
01280
01281
01282
01283
01284
Status =
ObInsertObject(
01285 Object,
01286
NULL,
01287 (ACCESS_MASK)0,
01288 0,
01289
NULL,
01290 &ObjHandle
01291 );
01292
01293
if (!
NT_SUCCESS(
Status)) {
01294
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
01295 KdPrint((
"CmpCreateRegistryRoot: "));
01296 KdPrint((
"ObInsertObject(\\REGISTRY) failed %08lx\n",
Status));
01297 }
01298
return FALSE;
01299 }
01300
01301
01302
01303
01304
01305
01306
01307
if (!
NT_SUCCESS(
Status =
ObReferenceObjectByHandle(
01308 ObjHandle,
01309 KEY_READ,
01310
NULL,
01311
KernelMode,
01312 &ObjectPointer,
01313
NULL
01314 )))
01315 {
01316
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
01317 KdPrint((
"CmpCreateRegistryRoot: "));
01318 KdPrint((
"ObReferenceObjectByHandle failed %08lx\n",
Status));
01319 }
01320
return FALSE;
01321 }
01322
01323
return TRUE;
01324 }
01325
01326
01327 BOOLEAN
01328 CmpCreateRootNode(
01329 IN
PHHIVE Hive,
01330 IN PWSTR Name,
01331 OUT PHCELL_INDEX RootCellIndex
01332 )
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353 {
01354 UNICODE_STRING temp;
01355
PCELL_DATA CellData;
01356
CM_KEY_REFERENCE Key;
01357 LARGE_INTEGER systemtime;
01358
01359
PAGED_CODE();
01360
01361
01362
01363
RtlInitUnicodeString(&temp,
Name);
01364 *RootCellIndex =
HvAllocateCell(
01365
Hive,
01366
CmpHKeyNodeSize(
Hive, &temp),
01367
Stable
01368 );
01369
if (*RootCellIndex ==
HCELL_NIL) {
01370
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
01371 KdPrint((
"CmpCreateRootNode: HvAllocateCell failed\n"));
01372 }
01373
return FALSE;
01374 }
01375
01376
Hive->
BaseBlock->
RootCell = *RootCellIndex;
01377
01378 CellData =
HvGetCell(
Hive, *RootCellIndex);
01379
01380
01381
01382
01383 CellData->
u.
KeyNode.
Signature =
CM_KEY_NODE_SIGNATURE;
01384 CellData->
u.
KeyNode.
Flags =
KEY_HIVE_ENTRY |
KEY_NO_DELETE;
01385
KeQuerySystemTime(&systemtime);
01386 CellData->
u.
KeyNode.
LastWriteTime = systemtime;
01387
01388 CellData->
u.
KeyNode.
Parent =
HCELL_NIL;
01389
01390 CellData->
u.
KeyNode.
SubKeyCounts[
Stable] = 0;
01391 CellData->
u.
KeyNode.
SubKeyCounts[
Volatile] = 0;
01392 CellData->
u.
KeyNode.
SubKeyLists[
Stable] =
HCELL_NIL;
01393 CellData->
u.
KeyNode.
SubKeyLists[
Volatile] =
HCELL_NIL;
01394
01395 CellData->
u.
KeyNode.
ValueList.
Count = 0;
01396 CellData->
u.
KeyNode.
ValueList.
List =
HCELL_NIL;
01397 CellData->
u.
KeyNode.
Security =
HCELL_NIL;
01398 CellData->
u.
KeyNode.
Class =
HCELL_NIL;
01399 CellData->
u.
KeyNode.
ClassLength = 0;
01400
01401 CellData->
u.
KeyNode.
MaxValueDataLen = 0;
01402 CellData->
u.
KeyNode.
MaxNameLen = 0;
01403 CellData->
u.
KeyNode.
MaxValueNameLen = 0;
01404 CellData->
u.
KeyNode.
MaxClassLen = 0;
01405
01406 CellData->
u.
KeyNode.
NameLength =
CmpCopyName(
Hive,
01407 CellData->
u.
KeyNode.
Name,
01408 &temp);
01409
if (CellData->
u.
KeyNode.
NameLength < temp.Length) {
01410 CellData->
u.
KeyNode.
Flags |=
KEY_COMP_NAME;
01411 }
01412
01413
Key.KeyHive =
Hive;
01414
Key.KeyCell = *RootCellIndex;
01415
01416
return TRUE;
01417 }
01418
01419
01420
NTSTATUS
01421 CmpLinkHiveToMaster(
01422 PUNICODE_STRING LinkName,
01423 HANDLE RootDirectory,
01424
PCMHIVE CmHive,
01425 BOOLEAN Allocate,
01426 PSECURITY_DESCRIPTOR SecurityDescriptor
01427 )
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457 {
01458 OBJECT_ATTRIBUTES
ObjectAttributes;
01459 HANDLE KeyHandle;
01460
CM_PARSE_CONTEXT ParseContext;
01461
NTSTATUS Status;
01462
PCM_KEY_BODY KeyBody;
01463
01464
PAGED_CODE();
01465
01466
01467
01468
01469 ParseContext.
TitleIndex = 0;
01470 ParseContext.
Class.Length = 0;
01471 ParseContext.
Class.MaximumLength = 0;
01472 ParseContext.
Class.Buffer =
NULL;
01473 ParseContext.
CreateOptions = 0;
01474 ParseContext.
CreateLink =
TRUE;
01475 ParseContext.
ChildHive.
KeyHive = &CmHive->
Hive;
01476
if (Allocate) {
01477
01478
01479
01480
01481
01482 ParseContext.
ChildHive.
KeyCell =
HCELL_NIL;
01483 }
else {
01484
01485
01486
01487
01488
01489 ParseContext.
ChildHive.
KeyCell = CmHive->
Hive.
BaseBlock->
RootCell;
01490 }
01491
01492
01493
01494
01495 InitializeObjectAttributes(
01496 &
ObjectAttributes,
01497 LinkName,
01498 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
01499 (HANDLE)RootDirectory,
01500 SecurityDescriptor
01501 );
01502
01503
Status =
ObOpenObjectByName( &
ObjectAttributes,
01504
CmpKeyObjectType,
01505
KernelMode,
01506
NULL,
01507 KEY_READ | KEY_WRITE,
01508 (PVOID)&ParseContext,
01509 &KeyHandle );
01510
01511
if (!
NT_SUCCESS(
Status)) {
01512
CMLOG(
CML_MAJOR,
CMS_INIT_ERROR) {
01513 KdPrint((
"CmpLinkHiveToMaster: "));
01514 KdPrint((
"ObOpenObjectByName() failed %08lx\n",
Status));
01515 KdPrint((
"\tLinkName='%ws'\n", LinkName));
01516 }
01517
return Status;
01518 }
01519
01520
01521
01522
01523
Status =
ObReferenceObjectByHandle(KeyHandle,
01524 0,
01525
CmpKeyObjectType,
01526
KernelMode,
01527 (PVOID *)&KeyBody,
01528
NULL);
01529
ASSERT(
NT_SUCCESS(
Status));
01530
if (
NT_SUCCESS(
Status)) {
01531
CmpReportNotify(KeyBody->KeyControlBlock,
01532 KeyBody->KeyControlBlock->KeyHive,
01533 KeyBody->KeyControlBlock->KeyCell,
01534 REG_NOTIFY_CHANGE_NAME);
01535
01536
ObDereferenceObject((PVOID)KeyBody);
01537 }
01538
01539 ZwClose(KeyHandle);
01540
return STATUS_SUCCESS;
01541 }
01542
01543
01544
VOID
01545 CmpSetVersionData(
01546 VOID
01547 )
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568 {
01569 ANSI_STRING AnsiString;
01570 UNICODE_STRING NameString;
01571 UNICODE_STRING ValueString;
01572 HANDLE key1, key2;
01573 UCHAR WorkString[128];
01574 WCHAR
ValueBuffer[128];
01575 OBJECT_ATTRIBUTES
ObjectAttributes;
01576
NTSTATUS status;
01577 PUCHAR proctype;
01578 PUCHAR buildtype;
01579 PSECURITY_DESCRIPTOR SecurityDescriptor;
01580
01581
PAGED_CODE();
01582
01583
01584
01585 SecurityDescriptor =
CmpHiveRootSecurityDescriptor();
01586
01587
01588
01589
01590
RtlInitUnicodeString(
01591 &NameString,
01592
L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft"
01593 );
01594
01595 InitializeObjectAttributes(
01596 &
ObjectAttributes,
01597 &NameString,
01598 OBJ_CASE_INSENSITIVE,
01599 (HANDLE)
NULL,
01600 SecurityDescriptor
01601 );
01602
01603 status =
NtCreateKey(
01604 &key1,
01605 KEY_CREATE_SUB_KEY,
01606 &
ObjectAttributes,
01607 0,
01608 &
nullclass,
01609 0,
01610
NULL
01611 );
01612
01613
if (!
NT_SUCCESS(status)) {
01614
#if DBG
01615
DbgPrint(
"CMINIT: CreateKey of %wZ failed - Status == %lx\n",
01616 &NameString, status);
01617
#endif
01618
ExFreePool(SecurityDescriptor);
01619
return;
01620 }
01621
01622
RtlInitUnicodeString(
01623 &NameString,
01624
L"Windows NT"
01625 );
01626
01627 InitializeObjectAttributes(
01628 &
ObjectAttributes,
01629 &NameString,
01630 OBJ_CASE_INSENSITIVE,
01631 key1,
01632 SecurityDescriptor
01633 );
01634
01635 status =
NtCreateKey(
01636 &key2,
01637 KEY_SET_VALUE,
01638 &
ObjectAttributes,
01639 0,
01640 &
nullclass,
01641 0,
01642
NULL
01643 );
01644
NtClose(key1);
01645
RtlInitUnicodeString(
01646 &NameString,
01647
L"CurrentVersion"
01648 );
01649
01650 InitializeObjectAttributes(
01651 &
ObjectAttributes,
01652 &NameString,
01653 OBJ_CASE_INSENSITIVE,
01654 key2,
01655 SecurityDescriptor
01656 );
01657
01658 status =
NtCreateKey(
01659 &key1,
01660 KEY_SET_VALUE,
01661 &
ObjectAttributes,
01662 0,
01663 &
nullclass,
01664 0,
01665
NULL
01666 );
01667
NtClose(key2);
01668
ExFreePool(SecurityDescriptor);
01669
if (!
NT_SUCCESS(status)) {
01670
#if DBG
01671
DbgPrint(
"CMINIT: CreateKey of %wZ failed - Status == %lx\n",
01672 &NameString, status);
01673
#endif
01674
return;
01675 }
01676
01677
01678
01679
01680
01681
RtlInitUnicodeString(
01682 &NameString,
01683
L"CurrentVersion"
01684 );
01685
01686 status =
NtSetValueKey(
01687 key1,
01688 &NameString,
01689 0,
01690 REG_SZ,
01691
CmVersionString.Buffer,
01692
CmVersionString.Length +
sizeof( UNICODE_NULL )
01693 );
01694
#if DBG
01695
if (!
NT_SUCCESS(status)) {
01696
DbgPrint(
"CMINIT: SetValueKey of %wZ failed - Status == %lx\n",
01697 &NameString, status);
01698 }
01699
#endif
01700
(
RtlFreeStringRoutine)(
CmVersionString.Buffer );
01701
RtlInitUnicodeString( &
CmVersionString,
NULL );
01702
01703
RtlInitUnicodeString(
01704 &NameString,
01705
L"CurrentBuildNumber"
01706 );
01707
01708
sprintf(
01709 WorkString,
01710
"%u",
01711
NtBuildNumber & 0xFFFF
01712 );
01713
RtlInitAnsiString( &AnsiString, WorkString );
01714
01715 ValueString.Buffer =
ValueBuffer;
01716 ValueString.Length = 0;
01717 ValueString.MaximumLength =
sizeof(
ValueBuffer );
01718
01719
RtlAnsiStringToUnicodeString( &ValueString, &AnsiString,
FALSE );
01720
01721 status =
NtSetValueKey(
01722 key1,
01723 &NameString,
01724 0,
01725 REG_SZ,
01726 ValueString.Buffer,
01727 ValueString.Length +
sizeof( UNICODE_NULL )
01728 );
01729
#if DBG
01730
if (!
NT_SUCCESS(status)) {
01731
DbgPrint(
"CMINIT: SetValueKey of %wZ failed - Status == %lx\n",
01732 &NameString, status);
01733 }
01734
#endif
01735
01736
RtlInitUnicodeString(
01737 &NameString,
01738
L"CurrentType"
01739 );
01740
01741
#if defined(NT_UP)
01742
proctype =
"Uniprocessor";
01743
#else
01744
proctype =
"Multiprocessor";
01745
#endif
01746
01747
#if DBG
01748
buildtype =
"Checked";
01749
#else
01750
#if DEVL
01751
buildtype =
"Free";
01752
#else
01753
buildtype =
"Retail";
01754
#endif
01755
01756
#endif
01757
01758
sprintf(
01759 WorkString,
01760
"%s %s",
01761 proctype,
01762 buildtype
01763 );
01764
RtlInitAnsiString( &AnsiString, WorkString );
01765
01766 ValueString.Buffer =
ValueBuffer;
01767 ValueString.Length = 0;
01768 ValueString.MaximumLength =
sizeof(
ValueBuffer );
01769
01770
RtlAnsiStringToUnicodeString( &ValueString, &AnsiString,
FALSE );
01771
01772 status =
NtSetValueKey(
01773 key1,
01774 &NameString,
01775 0,
01776 REG_SZ,
01777 ValueString.Buffer,
01778 ValueString.Length +
sizeof( UNICODE_NULL )
01779 );
01780
01781
RtlInitUnicodeString(
01782 &NameString,
01783
L"CSDVersion"
01784 );
01785
01786
if (
CmCSDVersionString.Length != 0) {
01787 status =
NtSetValueKey(
01788 key1,
01789 &NameString,
01790 0,
01791 REG_SZ,
01792
CmCSDVersionString.Buffer,
01793
CmCSDVersionString.Length +
sizeof( UNICODE_NULL )
01794 );
01795
#if DBG
01796
if (!
NT_SUCCESS(status)) {
01797
DbgPrint(
"CMINIT: SetValueKey of %wZ failed - Status == %lx\n",
01798 &NameString, status);
01799 }
01800
#endif
01801
(
RtlFreeStringRoutine)(
CmCSDVersionString.Buffer );
01802
RtlInitUnicodeString( &
CmCSDVersionString,
NULL );
01803 }
else {
01804 status =
NtDeleteValueKey(
01805 key1,
01806 &NameString
01807 );
01808
#if DBG
01809
if (!
NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
01810
DbgPrint(
"CMINIT: DeleteValueKey of %wZ failed - Status == %lx\n",
01811 &NameString, status);
01812 }
01813
#endif
01814
}
01815
RtlInitUnicodeString(&NameString,
01816
L"SystemRoot");
01817 status =
NtSetValueKey(key1,
01818 &NameString,
01819 0,
01820 REG_SZ,
01821
NtSystemRoot.Buffer,
01822
NtSystemRoot.Length +
sizeof(UNICODE_NULL));
01823
#if DBG
01824
if (!
NT_SUCCESS(status)) {
01825
DbgPrint(
"CMINIT: SetValueKey of %wZ failed - Status == %lx\n",
01826 &NameString,
01827 status);
01828 }
01829
#endif
01830
NtClose(key1);
01831
01832
01833
01834
01835
01836
01837
01838
01839
CmpInterlockedFunction(
CmpProcessorControl,
CmpConfigureProcessors);
01840
01841
return;
01842 }
01843
01844
NTSTATUS
01845 CmpInterlockedFunction (
01846 PWCHAR RegistryValueKey,
01847 VOID (*InterlockedFunction)(VOID)
01848 )
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873 {
01874 OBJECT_ATTRIBUTES objectAttributes;
01875 HANDLE hControl, hSession;
01876 UNICODE_STRING
Name;
01877 UCHAR
Buffer [
sizeof(KEY_VALUE_PARTIAL_INFORMATION)+
sizeof(ULONG)];
01878 ULONG length, Value;
01879
NTSTATUS status;
01880
01881
PAGED_CODE();
01882
01883
01884
01885
01886
01887 InitializeObjectAttributes (
01888 &objectAttributes,
01889 &
CmRegistryMachineSystemCurrentControlSet,
01890 OBJ_CASE_INSENSITIVE,
01891
NULL,
01892
NULL
01893 );
01894
01895 status =
NtOpenKey (&hControl, KEY_READ | KEY_WRITE, &objectAttributes);
01896
if (!
NT_SUCCESS(status)) {
01897
return status;
01898 }
01899
01900
01901
01902
01903
01904
RtlInitUnicodeString (&
Name,
CmpControlSessionManager);
01905 InitializeObjectAttributes (
01906 &objectAttributes,
01907 &
Name,
01908 OBJ_CASE_INSENSITIVE,
01909 hControl,
01910
NULL
01911 );
01912
01913 status =
NtOpenKey (&hSession, KEY_READ | KEY_WRITE, &objectAttributes );
01914
NtClose (hControl);
01915
if (!
NT_SUCCESS(status)) {
01916
return status;
01917 }
01918
01919
01920
01921
01922
01923
RtlInitUnicodeString (&
Name, RegistryValueKey);
01924 status =
NtQueryValueKey (hSession,
01925 &
Name,
01926 KeyValuePartialInformation,
01927
Buffer,
01928
sizeof (
Buffer),
01929 &length );
01930
01931 Value = 0;
01932
if (
NT_SUCCESS(status)) {
01933 Value = ((PKEY_VALUE_PARTIAL_INFORMATION)
Buffer)->Data[0];
01934 }
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
if (Value != 1) {
01952
01953
if (Value != 2) {
01954
01955
01956
01957
01958
01959
01960 Value = 1;
01961
NtSetValueKey (hSession, &
Name, 0
L, REG_DWORD, &Value,
sizeof (Value));
01962
NtFlushKey (hSession);
01963 }
01964
01965 InterlockedFunction();
01966
01967
if (Value != 2) {
01968
01969
01970
01971
01972
01973 Value = 2;
01974
NtSetValueKey (hSession, &
Name, 0
L, REG_DWORD, &Value,
sizeof (Value));
01975 }
01976
01977 }
else {
01978 status = STATUS_UNSUCCESSFUL;
01979 }
01980
01981
NtClose (hSession);
01982
return status;
01983 }
01984
01985
VOID
01986 CmpConfigureProcessors (
01987 VOID
01988 )
01989
01990
01991
01992
01993
01994
01995
01996 {
01997 ULONG i;
01998
01999
PAGED_CODE();
02000
02001
02002
02003
02004
02005
for (i=0; i < (ULONG)
KeNumberProcessors; i++) {
02006
KeSetSystemAffinityThread((KAFFINITY) 1 << i);
02007
02008
#if i386
02009
02010
KeOptimizeProcessorControlState ();
02011
#endif
02012
}
02013
02014
02015
02016
02017
02018
KeRevertToUserAffinityThread();
02019 }
02020
02021 BOOLEAN
02022 CmpInitializeSystemHive(
02023 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02024 )
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045 {
02046
PCMHIVE SystemHive;
02047 PVOID HiveImageBase;
02048 BOOLEAN Allocate=
FALSE;
02049 PSECURITY_DESCRIPTOR SecurityDescriptor;
02050
NTSTATUS Status;
02051 STRING TempString;
02052
02053
02054
PAGED_CODE();
02055
02056
02057
02058
02059
RtlInitAnsiString(
02060 &TempString,
02061 LoaderBlock->LoadOptions
02062 );
02063
02064
CmpLoadOptions.Length = 0;
02065
CmpLoadOptions.MaximumLength = (TempString.Length+1)*
sizeof(WCHAR);
02066
CmpLoadOptions.Buffer =
ExAllocatePool(
02067
PagedPool, (TempString.Length+1)*
sizeof(WCHAR));
02068
02069
if (
CmpLoadOptions.Buffer ==
NULL) {
02070
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,5,6,0,0);
02071 }
02072
RtlAnsiStringToUnicodeString(
02073 &
CmpLoadOptions,
02074 &TempString,
02075
FALSE
02076 );
02077
CmpLoadOptions.Buffer[TempString.Length] = UNICODE_NULL;
02078
CmpLoadOptions.Length +=
sizeof(WCHAR);
02079
02080
02081
02082
02083
02084 HiveImageBase = LoaderBlock->RegistryBase;
02085
02086
if (HiveImageBase ==
NULL) {
02087
02088
02089
02090
Status =
CmpInitializeHive(&SystemHive,
02091
HINIT_CREATE,
02092 0,
02093
HFILE_TYPE_ALTERNATE,
02094
NULL,
02095
NULL,
02096
NULL,
02097
NULL,
02098
NULL,
02099 &
CmpSystemFileName);
02100
if (!
NT_SUCCESS(
Status)) {
02101
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02102 KdPrint((
"CmpInitializeSystemHive: "));
02103 KdPrint((
"Couldn't initialize newly allocated SYSTEM hive\n"));
02104 }
02105
return(
FALSE);
02106 }
02107 Allocate =
TRUE;
02108
02109 }
else {
02110
02111
02112
02113
02114
Status =
CmpInitializeHive(&SystemHive,
02115
HINIT_MEMORY,
02116 0,
02117
HFILE_TYPE_ALTERNATE,
02118 HiveImageBase,
02119
NULL,
02120
NULL,
02121
NULL,
02122
NULL,
02123 &
CmpSystemFileName);
02124
if (!
NT_SUCCESS(
Status)) {
02125
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02126 KdPrint((
"CmpInitializeSystemHive: "));
02127 KdPrint((
"Couldn't initialize OS Loader-loaded SYSTEM hive\n"));
02128 }
02129
return(
FALSE);
02130 }
02131
02132
if (
CmCheckRegistry(SystemHive,
TRUE) != 0) {
02133
02134
02135
02136
02137
02138
KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,5,7,0,0);
02139 }
02140 Allocate =
FALSE;
02141 }
02142
02143
02144
02145
02146 SecurityDescriptor =
CmpHiveRootSecurityDescriptor();
02147
02148
Status =
CmpLinkHiveToMaster(&
CmRegistryMachineSystemName,
02149
NULL,
02150 SystemHive,
02151 Allocate,
02152 SecurityDescriptor);
02153
ExFreePool(SecurityDescriptor);
02154
02155
if (!
NT_SUCCESS(
Status)) {
02156
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02157 KdPrint((
"CmInitSystem1: CmpLinkHiveToMaster(Hardware) failed\n"));
02158 }
02159
return(
FALSE);
02160 }
02161
02162
CmpMachineHiveList[
SYSTEM_HIVE_INDEX].
CmHive = SystemHive;
02163
02164
return(
TRUE);
02165 }
02166
02167
02168 PHANDLE
02169 CmGetSystemDriverList(
02170 VOID
02171 )
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195 {
02196 OBJECT_ATTRIBUTES
ObjectAttributes;
02197 HANDLE SystemHandle;
02198 UNICODE_STRING
Name;
02199
NTSTATUS Status;
02200
PCM_KEY_BODY KeyBody;
02201 LIST_ENTRY DriverList;
02202
PHHIVE Hive;
02203
HCELL_INDEX RootCell;
02204
HCELL_INDEX ControlCell;
02205 ULONG DriverCount;
02206 PLIST_ENTRY Current;
02207 PHANDLE
Handle;
02208
PBOOT_DRIVER_LIST_ENTRY DriverEntry;
02209 BOOLEAN Success;
02210 BOOLEAN AutoSelect;
02211
02212
PAGED_CODE();
02213 InitializeListHead(&DriverList);
02214
RtlInitUnicodeString(&
Name,
02215
L"\\Registry\\Machine\\System");
02216
02217 InitializeObjectAttributes(&
ObjectAttributes,
02218 &
Name,
02219 OBJ_CASE_INSENSITIVE,
02220 (HANDLE)
NULL,
02221
NULL);
02222
Status =
NtOpenKey(&SystemHandle,
02223 KEY_READ,
02224 &
ObjectAttributes);
02225
02226
if (!
NT_SUCCESS(
Status)) {
02227
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02228 KdPrint((
"CM: CmGetSystemDriverList couldn't open registry key %wZ\n",&
Name));
02229 KdPrint((
"CM: status %08lx\n",
Status));
02230 }
02231
return(
NULL);
02232 }
02233
02234
02235
Status =
ObReferenceObjectByHandle( SystemHandle,
02236 KEY_QUERY_VALUE,
02237
CmpKeyObjectType,
02238
KernelMode,
02239 (PVOID *)(&KeyBody),
02240
NULL );
02241
if (!
NT_SUCCESS(
Status)) {
02242
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02243 KdPrint((
"CM: CmGetSystemDriverList couldn't dereference Systemhandle\n"));
02244 KdPrint((
"CM: status %08lx\n",
Status));
02245 }
02246
NtClose(SystemHandle);
02247
return(
NULL);
02248 }
02249
02250
CmpLockRegistryExclusive();
02251
02252
Hive = KeyBody->KeyControlBlock->KeyHive;
02253 RootCell = KeyBody->KeyControlBlock->KeyCell;
02254
02255
02256
02257
02258
02259
02260
RtlInitUnicodeString(&
Name,
L"Current");
02261 ControlCell =
CmpFindControlSet(
Hive,
02262 RootCell,
02263 &
Name,
02264 &AutoSelect);
02265
if (ControlCell ==
HCELL_NIL) {
02266
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02267 KdPrint((
"CM: CmGetSystemDriverList couldn't find control set\n"));
02268 }
02269
CmpUnlockRegistry();
02270
ObDereferenceObject((PVOID)KeyBody);
02271
NtClose(SystemHandle);
02272
return(
NULL);
02273 }
02274
02275 Success =
CmpFindDrivers(
Hive,
02276 ControlCell,
02277 SystemLoad,
02278
NULL,
02279 &DriverList);
02280
02281
02282
if (!Success) {
02283
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02284 KdPrint((
"CM: CmGetSystemDriverList couldn't find any valid drivers\n"));
02285 }
02286
CmpFreeDriverList(
Hive, &DriverList);
02287
CmpUnlockRegistry();
02288
ObDereferenceObject((PVOID)KeyBody);
02289
NtClose(SystemHandle);
02290
return(
NULL);
02291 }
02292
02293
if (!
CmpSortDriverList(
Hive,
02294 ControlCell,
02295 &DriverList)) {
02296
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02297 KdPrint((
"CM: CmGetSystemDriverList couldn't sort driver list\n"));
02298 }
02299
CmpFreeDriverList(
Hive, &DriverList);
02300
CmpUnlockRegistry();
02301
ObDereferenceObject((PVOID)KeyBody);
02302
NtClose(SystemHandle);
02303
return(
NULL);
02304 }
02305
02306
if (!
CmpResolveDriverDependencies(&DriverList)) {
02307
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02308 KdPrint((
"CM: CmGetSystemDriverList couldn't resolve driver dependencies\n"));
02309 }
02310
CmpFreeDriverList(
Hive, &DriverList);
02311
CmpUnlockRegistry();
02312
ObDereferenceObject((PVOID)KeyBody);
02313
NtClose(SystemHandle);
02314
return(
NULL);
02315 }
02316
CmpUnlockRegistry();
02317
ObDereferenceObject((PVOID)KeyBody);
02318
NtClose(SystemHandle);
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328 Current = DriverList.Flink;
02329 DriverCount = 0;
02330
while (Current != &DriverList) {
02331 ++DriverCount;
02332 Current = Current->Flink;
02333 }
02334
02335
Handle = (PHANDLE)
ExAllocatePool(
NonPagedPool,
02336 (DriverCount+1) *
sizeof(HANDLE));
02337
02338
if (
Handle ==
NULL) {
02339
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,5,8,0,0);
02340 }
02341
02342
02343
02344
02345
02346 Current = DriverList.Flink;
02347 DriverCount = 0;
02348
while (Current != &DriverList) {
02349
DriverEntry = CONTAINING_RECORD(Current,
02350
BOOT_DRIVER_LIST_ENTRY,
02351 Link);
02352
02353 InitializeObjectAttributes(&
ObjectAttributes,
02354 &
DriverEntry->RegistryPath,
02355 OBJ_CASE_INSENSITIVE,
02356 (HANDLE)
NULL,
02357
NULL);
02358
02359
Status =
NtOpenKey(
Handle+DriverCount,
02360 KEY_READ | KEY_WRITE,
02361 &
ObjectAttributes);
02362
if (!
NT_SUCCESS(
Status)) {
02363
CMLOG(
CML_BUGCHECK,
CMS_INIT_ERROR) {
02364 KdPrint((
"CM: CmGetSystemDriverList couldn't open driver "));
02365 KdPrint((
"key %wZ\n", &
DriverEntry->RegistryPath));
02366 KdPrint((
" status %08lx\n",
Status));
02367 }
02368 }
else {
02369 ++DriverCount;
02370 }
02371 Current = Current->Flink;
02372 }
02373
Handle[DriverCount] =
NULL;
02374
02375
return(
Handle);
02376 }
02377
02378
02379
VOID
02380 CmpFreeDriverList(
02381 IN
PHHIVE Hive,
02382 IN PLIST_ENTRY DriverList
02383 )
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407 {
02408 PLIST_ENTRY Next;
02409 PLIST_ENTRY Current;
02410
02411
PAGED_CODE();
02412 Current = DriverList->Flink;
02413
while (Current != DriverList) {
02414 Next = Current->Flink;
02415 (
Hive->
Free)((PVOID)Current,
sizeof(
BOOT_DRIVER_NODE));
02416 Current = Next;
02417 }
02418 }
02419
02420
02421
NTSTATUS
02422 CmpInitHiveFromFile(
02423 IN PUNICODE_STRING FileName,
02424 IN ULONG HiveFlags,
02425 OUT
PCMHIVE *CmHive,
02426 IN OUT PBOOLEAN Allocate,
02427 IN OUT PBOOLEAN RegistryLocked
02428 )
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455 {
02456
PCMHIVE NewHive;
02457 ULONG Disposition;
02458 ULONG SecondaryDisposition;
02459 HANDLE PrimaryHandle;
02460 HANDLE LogHandle;
02461
NTSTATUS Status;
02462 ULONG FileType;
02463 ULONG Operation;
02464
02465 BOOLEAN Success;
02466
02467
PAGED_CODE();
02468 *CmHive =
NULL;
02469
02470
Status =
CmpOpenHiveFiles(
FileName,
02471
L".LOG",
02472 &PrimaryHandle,
02473 &LogHandle,
02474 &Disposition,
02475 &SecondaryDisposition,
02476 *Allocate,
02477
FALSE,
02478
NULL);
02479
02480
if (!
NT_SUCCESS(
Status)) {
02481
return(
Status);
02482 }
02483
02484
if (LogHandle ==
NULL) {
02485 FileType =
HFILE_TYPE_PRIMARY;
02486 }
else {
02487 FileType =
HFILE_TYPE_LOG;
02488 }
02489
02490
if (Disposition == FILE_CREATED) {
02491 Operation =
HINIT_CREATE;
02492 *Allocate =
TRUE;
02493 }
else {
02494 Operation =
HINIT_FILE;
02495 *Allocate =
FALSE;
02496 }
02497
02498
if( !(*RegistryLocked) ) {
02499
02500
02501
02502
02503
CmpLockRegistryExclusive();
02504 *RegistryLocked =
TRUE;
02505 }
02506
02507
Status =
CmpInitializeHive(&NewHive,
02508 Operation,
02509 HiveFlags,
02510 FileType,
02511
NULL,
02512 PrimaryHandle,
02513
NULL,
02514 LogHandle,
02515
NULL,
02516
FileName
02517 );
02518
if (!
NT_SUCCESS(
Status)) {
02519 ZwClose(PrimaryHandle);
02520
if (LogHandle !=
NULL) {
02521 ZwClose(LogHandle);
02522 }
02523
return(
Status);
02524 }
else {
02525 *CmHive = NewHive;
02526
return(STATUS_SUCCESS);
02527 }
02528 }
02529
02530
02531
NTSTATUS
02532 CmpAddDockingInfo (
02533 IN HANDLE Key,
02534 IN
PROFILE_PARAMETER_BLOCK * ProfileBlock
02535 )
02536
02537
02538
02539
02540
02541
02542 {
02543
NTSTATUS status = STATUS_SUCCESS;
02544 UNICODE_STRING name;
02545 ULONG value;
02546
02547
PAGED_CODE ();
02548
02549 value = ProfileBlock->DockingState;
02550
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DOCKING_STATE);
02551 status =
NtSetValueKey (
Key,
02552 &name,
02553 0,
02554 REG_DWORD,
02555 &value,
02556
sizeof (value));
02557
02558
if (!
NT_SUCCESS (status)) {
02559
return status;
02560 }
02561
02562 value = ProfileBlock->Capabilities;
02563
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_CAPABILITIES);
02564 status =
NtSetValueKey (
Key,
02565 &name,
02566 0,
02567 REG_DWORD,
02568 &value,
02569
sizeof (value));
02570
02571
if (!
NT_SUCCESS (status)) {
02572
return status;
02573 }
02574
02575 value = ProfileBlock->DockID;
02576
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DOCKID);
02577 status =
NtSetValueKey (
Key,
02578 &name,
02579 0,
02580 REG_DWORD,
02581 &value,
02582
sizeof (value));
02583
02584
if (!
NT_SUCCESS (status)) {
02585
return status;
02586 }
02587
02588 value = ProfileBlock->SerialNumber;
02589
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_SERIAL_NUMBER);
02590 status =
NtSetValueKey (
Key,
02591 &name,
02592 0,
02593 REG_DWORD,
02594 &value,
02595
sizeof (value));
02596
02597
if (!
NT_SUCCESS (status)) {
02598
return status;
02599 }
02600
02601
return status;
02602 }
02603
02604
02605
NTSTATUS
02606 CmpAddAliasEntry (
02607 IN HANDLE IDConfigDB,
02608 IN
PROFILE_PARAMETER_BLOCK * ProfileBlock,
02609 IN ULONG ProfileNumber
02610 )
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627 {
02628 OBJECT_ATTRIBUTES attributes;
02629
NTSTATUS status = STATUS_SUCCESS;
02630
CHAR asciiBuffer [128];
02631 WCHAR unicodeBuffer [128];
02632 ANSI_STRING ansiString;
02633 UNICODE_STRING name;
02634 HANDLE aliasKey =
NULL;
02635 HANDLE aliasEntry =
NULL;
02636 ULONG value;
02637 ULONG disposition;
02638 ULONG aliasNumber = 0;
02639
02640
PAGED_CODE ();
02641
02642
02643
02644
02645
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ALIAS);
02646
02647 InitializeObjectAttributes (&attributes,
02648 &name,
02649 OBJ_CASE_INSENSITIVE,
02650 IDConfigDB,
02651
NULL);
02652
02653 status =
NtOpenKey (&aliasKey,
02654 KEY_READ | KEY_WRITE,
02655 &attributes);
02656
02657
if (STATUS_OBJECT_NAME_NOT_FOUND == status) {
02658 status =
NtCreateKey (&aliasKey,
02659 KEY_READ | KEY_WRITE,
02660 &attributes,
02661 0,
02662
NULL,
02663 0,
02664 &disposition);
02665 }
02666
02667
if (!
NT_SUCCESS (status)) {
02668 aliasKey =
NULL;
02669
goto Exit;
02670 }
02671
02672
02673
02674
02675
02676
while (aliasNumber < 200) {
02677 aliasNumber++;
02678
02679
sprintf(asciiBuffer,
"%04d", aliasNumber);
02680
02681
RtlInitAnsiString(&ansiString, asciiBuffer);
02682 name.MaximumLength =
sizeof(unicodeBuffer);
02683 name.Buffer = unicodeBuffer;
02684 status =
RtlAnsiStringToUnicodeString(&name,
02685 &ansiString,
02686
FALSE);
02687
ASSERT (STATUS_SUCCESS == status);
02688
02689 InitializeObjectAttributes(&attributes,
02690 &name,
02691 OBJ_CASE_INSENSITIVE,
02692 aliasKey,
02693
NULL);
02694
02695 status =
NtOpenKey (&aliasEntry,
02696 KEY_READ | KEY_WRITE,
02697 &attributes);
02698
02699
if (
NT_SUCCESS (status)) {
02700
NtClose (aliasEntry);
02701
02702 }
else if (STATUS_OBJECT_NAME_NOT_FOUND == status) {
02703 status = STATUS_SUCCESS;
02704
break;
02705
02706 }
else {
02707
break;
02708 }
02709
02710 }
02711
if (!
NT_SUCCESS (status)) {
02712
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02713 KdPrint((
"CM: cmpCreateAliasEntry error finding new set %08lx\n",
02714 status));
02715 }
02716 aliasEntry = 0;
02717
goto Exit;
02718 }
02719
02720 status =
NtCreateKey (&aliasEntry,
02721 KEY_READ | KEY_WRITE,
02722 &attributes,
02723 0,
02724
NULL,
02725 0,
02726 &disposition);
02727
02728
if (!
NT_SUCCESS (status)) {
02729
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02730 KdPrint((
"CM: cmpCreateAliasEntry error creating new set %08lx\n",
02731 status));
02732 }
02733 aliasEntry = 0;
02734
goto Exit;
02735 }
02736
02737
02738
02739
02740
CmpAddDockingInfo (aliasEntry, ProfileBlock);
02741
02742
02743
02744
02745 value = ProfileNumber;
02746
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_PROFILE_NUMBER);
02747 status =
NtSetValueKey (aliasEntry,
02748 &name,
02749 0,
02750 REG_DWORD,
02751 &value,
02752
sizeof (value));
02753
02754 Exit:
02755
02756
if (aliasKey) {
02757
NtClose (aliasKey);
02758 }
02759
02760
if (aliasEntry) {
02761
NtClose (aliasEntry);
02762 }
02763
02764
return status;
02765 }
02766
02767
02768
NTSTATUS
02769 CmpHwprofileDefaultSelect (
02770 IN
PCM_HARDWARE_PROFILE_LIST ProfileList,
02771 OUT PULONG ProfileIndexToUse,
02772 IN PVOID Context
02773 )
02774 {
02775 UNREFERENCED_PARAMETER (Context);
02776
02777 * ProfileIndexToUse = 0;
02778
02779
return STATUS_SUCCESS;
02780 }
02781
02782
02783
02784
02785
NTSTATUS
02786 CmpCreateControlSet(
02787 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
02788 )
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815 {
02816 UNICODE_STRING IDConfigDBName;
02817 UNICODE_STRING SelectName;
02818 UNICODE_STRING CurrentName;
02819 OBJECT_ATTRIBUTES Attributes;
02820 HANDLE SelectHandle;
02821 HANDLE CurrentHandle;
02822 HANDLE IDConfigDB =
NULL;
02823 HANDLE CurrentProfile =
NULL;
02824 HANDLE ParentOfProfile =
NULL;
02825
CHAR AsciiBuffer[128];
02826 WCHAR UnicodeBuffer[128];
02827 UCHAR
ValueBuffer[128];
02828 ULONG ControlSet;
02829 ULONG HWProfile;
02830 PKEY_VALUE_FULL_INFORMATION Value;
02831 ANSI_STRING AnsiString;
02832
NTSTATUS Status;
02833 ULONG ResultLength;
02834 ULONG Disposition;
02835 BOOLEAN signalAcpiEvent =
FALSE;
02836
02837
PAGED_CODE();
02838
02839
RtlInitUnicodeString(&SelectName,
L"\\Registry\\Machine\\System\\Select");
02840 InitializeObjectAttributes(&Attributes,
02841 &SelectName,
02842 OBJ_CASE_INSENSITIVE,
02843
NULL,
02844
NULL);
02845
Status =
NtOpenKey(&SelectHandle,
02846 KEY_READ,
02847 &Attributes);
02848
if (!
NT_SUCCESS(
Status)) {
02849
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02850 KdPrint((
"CM: CmpCreateControlSet: Couldn't open Select node %08lx\n",
Status));
02851 }
02852
return(
Status);
02853 }
02854
02855
RtlInitUnicodeString(&CurrentName,
L"Current");
02856
Status =
NtQueryValueKey(SelectHandle,
02857 &CurrentName,
02858 KeyValueFullInformation,
02859
ValueBuffer,
02860
sizeof(
ValueBuffer),
02861 &ResultLength);
02862
NtClose(SelectHandle);
02863
if (!
NT_SUCCESS(
Status)) {
02864
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02865 KdPrint((
"CM: CmpCreateControlSet: Couldn't query Select value %08lx\n",
Status));
02866 }
02867
return(
Status);
02868 }
02869 Value = (PKEY_VALUE_FULL_INFORMATION)
ValueBuffer;
02870 ControlSet = *(PULONG)((PUCHAR)Value + Value->DataOffset);
02871
02872
RtlInitUnicodeString(&CurrentName,
L"\\Registry\\Machine\\System\\CurrentControlSet");
02873 InitializeObjectAttributes(&Attributes,
02874 &CurrentName,
02875 OBJ_CASE_INSENSITIVE,
02876
NULL,
02877
NULL);
02878
Status =
NtCreateKey(&CurrentHandle,
02879 KEY_CREATE_LINK,
02880 &Attributes,
02881 0,
02882
NULL,
02883 REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
02884 &Disposition);
02885
if (!
NT_SUCCESS(
Status)) {
02886
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02887 KdPrint((
"CM: CmpCreateControlSet: couldn't create CurrentControlSet %08lx\n",
Status));
02888 }
02889
return(
Status);
02890 }
02891
02892
02893
02894
02895
02896
02897
ASSERT(Disposition == REG_CREATED_NEW_KEY);
02898
02899
02900
02901
02902
sprintf(AsciiBuffer,
"\\Registry\\Machine\\System\\ControlSet%03d", ControlSet);
02903
RtlInitAnsiString(&AnsiString, AsciiBuffer);
02904
02905 CurrentName.MaximumLength =
sizeof(UnicodeBuffer);
02906 CurrentName.Buffer = UnicodeBuffer;
02907
Status =
RtlAnsiStringToUnicodeString(&CurrentName,
02908 &AnsiString,
02909
FALSE);
02910
Status =
NtSetValueKey(CurrentHandle,
02911 &
CmSymbolicLinkValueName,
02912 0,
02913 REG_LINK,
02914 CurrentName.Buffer,
02915 CurrentName.Length);
02916
02917
if (!
NT_SUCCESS(
Status)) {
02918
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02919 KdPrint((
"CM: CmpCreateControlSet: couldn't create symbolic link "));
02920 KdPrint((
"to %wZ\n",&CurrentName));
02921 KdPrint((
" Status=%08lx\n",
Status));
02922 }
02923
return(
Status);
02924 }
02925
02926
02927
02928
02929
RtlInitUnicodeString(&IDConfigDBName,
L"Control\\IDConfigDB");
02930 InitializeObjectAttributes(&Attributes,
02931 &IDConfigDBName,
02932 OBJ_CASE_INSENSITIVE,
02933 CurrentHandle,
02934
NULL);
02935
Status =
NtOpenKey(&IDConfigDB,
02936 KEY_READ,
02937 &Attributes);
02938
NtClose(CurrentHandle);
02939
02940
if (!
NT_SUCCESS(
Status)) {
02941 IDConfigDB = 0;
02942
goto Cleanup;
02943 }
02944
02945
RtlInitUnicodeString(&CurrentName,
L"CurrentConfig");
02946
Status =
NtQueryValueKey(IDConfigDB,
02947 &CurrentName,
02948 KeyValueFullInformation,
02949
ValueBuffer,
02950
sizeof(
ValueBuffer),
02951 &ResultLength);
02952
02953
if (!
NT_SUCCESS(
Status) ||
02954 (((PKEY_VALUE_FULL_INFORMATION)
ValueBuffer)->Type != REG_DWORD)) {
02955
02956
goto Cleanup;
02957 }
02958
02959 Value = (PKEY_VALUE_FULL_INFORMATION)
ValueBuffer;
02960 HWProfile = *(PULONG)((PUCHAR)Value + Value->DataOffset);
02961
02962
02963
02964
02965
02966
RtlInitUnicodeString(
02967 &CurrentName,
02968
L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles");
02969 InitializeObjectAttributes(&Attributes,
02970 &CurrentName,
02971 OBJ_CASE_INSENSITIVE,
02972
NULL,
02973
NULL);
02974
Status =
NtOpenKey(&ParentOfProfile,
02975 KEY_READ,
02976 &Attributes);
02977
02978
if (!
NT_SUCCESS (
Status)) {
02979 ParentOfProfile = 0;
02980
goto Cleanup;
02981 }
02982
02983
sprintf(AsciiBuffer,
"%04d",HWProfile);
02984
RtlInitAnsiString(&AnsiString, AsciiBuffer);
02985 CurrentName.MaximumLength =
sizeof(UnicodeBuffer);
02986 CurrentName.Buffer = UnicodeBuffer;
02987
Status =
RtlAnsiStringToUnicodeString(&CurrentName,
02988 &AnsiString,
02989
FALSE);
02990
ASSERT (STATUS_SUCCESS ==
Status);
02991
02992 InitializeObjectAttributes(&Attributes,
02993 &CurrentName,
02994 OBJ_CASE_INSENSITIVE,
02995 ParentOfProfile,
02996
NULL);
02997
02998
Status =
NtOpenKey (&CurrentProfile,
02999 KEY_READ | KEY_WRITE,
03000 &Attributes);
03001
03002
if (!
NT_SUCCESS (
Status)) {
03003 CurrentProfile = 0;
03004
goto Cleanup;
03005 }
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
if (
NULL != LoaderBlock->Extension) {
03020
PLOADER_PARAMETER_EXTENSION extension;
03021
extension = LoaderBlock->Extension;
03022
switch (
extension->Profile.Status) {
03023
case HW_PROFILE_STATUS_PRISTINE_MATCH:
03024
03025
03026
03027
Status =
CmpCloneHwProfile (IDConfigDB,
03028 ParentOfProfile,
03029 CurrentProfile,
03030 HWProfile,
03031
extension->Profile.DockingState,
03032 &CurrentProfile,
03033 &HWProfile);
03034
if (!
NT_SUCCESS (
Status)) {
03035 CurrentProfile = 0;
03036
goto Cleanup;
03037 }
03038
03039
RtlInitUnicodeString(&CurrentName,
L"CurrentConfig");
03040
Status =
NtSetValueKey (IDConfigDB,
03041 &CurrentName,
03042 0,
03043 REG_DWORD,
03044 &HWProfile,
03045
sizeof (HWProfile));
03046
if (!
NT_SUCCESS (
Status)) {
03047
goto Cleanup;
03048 }
03049
03050
03051
03052
03053
case HW_PROFILE_STATUS_ALIAS_MATCH:
03054
03055
03056
03057
03058
Status =
CmpAddAliasEntry (IDConfigDB,
03059 &
extension->Profile,
03060 HWProfile);
03061
03062
#if 0
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
if (
HW_PROFILE_DOCKSTATE_UNDOCKED ==
extension->Profile.DockingState) {
03086
PROFILE_ACPI_DOCKING_STATE newDockState;
03087
03088
03089
03090
03091
03092
03093 newDockState.
DockingState =
extension->Profile.DockingState;
03094 newDockState.
SerialLength = 2;
03095 newDockState.
SerialNumber[0] =
L'\0';
03096
03097
Status =
CmpAddAcpiAliasEntry (IDConfigDB,
03098 &newDockState,
03099 HWProfile,
03100 UnicodeBuffer,
03101
ValueBuffer,
03102
sizeof (
ValueBuffer),
03103
TRUE);
03104
03105
ASSERT (
NT_SUCCESS (
Status));
03106 }
03107
#endif
03108
03109
03110
03111
03112
case HW_PROFILE_STATUS_TRUE_MATCH:
03113
03114
03115
03116
03117
03118
#ifndef DISABLE_CLEAN_HW_PROFILE_INFO
03119
RtlInitUnicodeString (&CurrentName,
CM_HARDWARE_PROFILE_STR_DOCKING_STATE);
03120
NtDeleteValueKey (CurrentProfile, &CurrentName);
03121
03122
RtlInitUnicodeString (&CurrentName,
CM_HARDWARE_PROFILE_STR_CAPABILITIES);
03123
NtDeleteValueKey (CurrentProfile, &CurrentName);
03124
03125
RtlInitUnicodeString (&CurrentName,
CM_HARDWARE_PROFILE_STR_DOCKID);
03126
NtDeleteValueKey (CurrentProfile, &CurrentName);
03127
03128
RtlInitUnicodeString (&CurrentName,
CM_HARDWARE_PROFILE_STR_SERIAL_NUMBER);
03129
NtDeleteValueKey (CurrentProfile, &CurrentName);
03130
#endif
03131
03132
RtlInitUnicodeString (&CurrentName,
03133
CM_HARDWARE_PROFILE_STR_CURRENT_DOCK_INFO);
03134
03135 InitializeObjectAttributes (&Attributes,
03136 &CurrentName,
03137 OBJ_CASE_INSENSITIVE,
03138 IDConfigDB,
03139
NULL);
03140
03141
Status =
NtCreateKey (&CurrentHandle,
03142 KEY_READ | KEY_WRITE,
03143 &Attributes,
03144 0,
03145
NULL,
03146 REG_OPTION_VOLATILE,
03147 &Disposition);
03148
03149
ASSERT (STATUS_SUCCESS ==
Status);
03150
03151
Status =
CmpAddDockingInfo (CurrentHandle, &
extension->Profile);
03152
03153
if (
HW_PROFILE_DOCKSTATE_UNDOCKED ==
extension->Profile.DockingState) {
03154 signalAcpiEvent =
TRUE;
03155 }
03156
03157
break;
03158
03159
03160
case HW_PROFILE_STATUS_SUCCESS:
03161
case HW_PROFILE_STATUS_FAILURE:
03162
break;
03163
03164
default:
03165
ASSERTMSG (
"Invalid Profile status state",
FALSE);
03166 }
03167 }
03168
03169
03170
03171
03172
RtlInitUnicodeString(&CurrentName,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
03173 InitializeObjectAttributes(&Attributes,
03174 &CurrentName,
03175 OBJ_CASE_INSENSITIVE,
03176
NULL,
03177
NULL);
03178
Status =
NtCreateKey(&CurrentHandle,
03179 KEY_CREATE_LINK,
03180 &Attributes,
03181 0,
03182
NULL,
03183 REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
03184 &Disposition);
03185
if (!
NT_SUCCESS(
Status)) {
03186
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03187 KdPrint((
"CM: CmpCreateControlSet: couldn't create Hardware Profile\\Current %08lx\n",
Status));
03188 }
03189 }
else {
03190
ASSERT(Disposition == REG_CREATED_NEW_KEY);
03191
03192
sprintf(AsciiBuffer,
"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\%04d",HWProfile);
03193
RtlInitAnsiString(&AnsiString, AsciiBuffer);
03194 CurrentName.MaximumLength =
sizeof(UnicodeBuffer);
03195 CurrentName.Buffer = UnicodeBuffer;
03196
Status =
RtlAnsiStringToUnicodeString(&CurrentName,
03197 &AnsiString,
03198
FALSE);
03199
ASSERT (STATUS_SUCCESS ==
Status);
03200
03201
Status =
NtSetValueKey(CurrentHandle,
03202 &
CmSymbolicLinkValueName,
03203 0,
03204 REG_LINK,
03205 CurrentName.Buffer,
03206 CurrentName.Length);
03207
if (!
NT_SUCCESS(
Status)) {
03208
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03209 KdPrint((
"CM: CmpCreateControlSet: couldn't create symbolic link "));
03210 KdPrint((
"to %wZ\n",&CurrentName));
03211 KdPrint((
" Status=%08lx\n",
Status));
03212 }
03213 }
03214 }
03215
03216
if (signalAcpiEvent) {
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
PROFILE_ACPI_DOCKING_STATE newDockState;
03228 HANDLE profile;
03229 BOOLEAN changed;
03230
03231 newDockState.
DockingState =
HW_PROFILE_DOCKSTATE_UNDOCKED;
03232 newDockState.
SerialLength = 2;
03233 newDockState.
SerialNumber[0] =
L'\0';
03234
03235
Status =
CmSetAcpiHwProfile (&newDockState,
03236
CmpHwprofileDefaultSelect,
03237
NULL,
03238 &profile,
03239 &changed);
03240
03241
ASSERT (
NT_SUCCESS (
Status));
03242
NtClose (profile);
03243 }
03244
03245
03246 Cleanup:
03247
if (IDConfigDB) {
03248
NtClose (IDConfigDB);
03249 }
03250
if (CurrentProfile) {
03251
NtClose (CurrentProfile);
03252 }
03253
if (ParentOfProfile) {
03254
NtClose (ParentOfProfile);
03255 }
03256
03257
return(STATUS_SUCCESS);
03258 }
03259
03260
03261
NTSTATUS
03262 CmpCloneControlSet(
03263 VOID
03264 )
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291 {
03292 UNICODE_STRING Current;
03293 UNICODE_STRING Clone;
03294 HANDLE CurrentHandle;
03295 HANDLE CloneHandle;
03296 OBJECT_ATTRIBUTES Attributes;
03297
NTSTATUS Status;
03298
PCM_KEY_BODY CurrentKey;
03299
PCM_KEY_BODY CloneKey;
03300 ULONG Disposition;
03301 PSECURITY_DESCRIPTOR Security;
03302 ULONG SecurityLength;
03303
03304
PAGED_CODE();
03305
03306
RtlInitUnicodeString(&Current,
03307
L"\\Registry\\Machine\\System\\CurrentControlSet");
03308
RtlInitUnicodeString(&Clone,
03309
L"\\Registry\\Machine\\System\\Clone");
03310
03311 InitializeObjectAttributes(&Attributes,
03312 &Current,
03313 OBJ_CASE_INSENSITIVE,
03314
NULL,
03315
NULL);
03316
Status =
NtOpenKey(&CurrentHandle,
03317 KEY_READ,
03318 &Attributes);
03319
if (!
NT_SUCCESS(
Status)) {
03320
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03321 KdPrint((
"CM: CmpCloneControlSet couldn't open CurrentControlSet %08lx\n",
Status));
03322 }
03323
return(
Status);
03324 }
03325
03326
03327
03328
03329
03330
Status =
NtQuerySecurityObject(CurrentHandle,
03331 DACL_SECURITY_INFORMATION,
03332
NULL,
03333 0,
03334 &SecurityLength);
03335
if (
Status==STATUS_BUFFER_TOO_SMALL) {
03336 Security=
ExAllocatePool(
PagedPool,SecurityLength);
03337
if (Security!=
NULL) {
03338
Status =
NtQuerySecurityObject(CurrentHandle,
03339 DACL_SECURITY_INFORMATION,
03340 Security,
03341 SecurityLength,
03342 &SecurityLength);
03343
if (!
NT_SUCCESS(
Status)) {
03344
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03345 KdPrint((
"CM: CmpCloneControlSet - NtQuerySecurityObject failed %08lx\n",
Status));
03346 }
03347
ExFreePool(Security);
03348 Security=
NULL;
03349 }
03350 }
03351 }
else {
03352
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03353 KdPrint((
"CM: CmpCloneControlSet - NtQuerySecurityObject returned %08lx\n",
Status));
03354 }
03355 Security=
NULL;
03356 }
03357
03358 InitializeObjectAttributes(&Attributes,
03359 &Clone,
03360 OBJ_CASE_INSENSITIVE,
03361
NULL,
03362 Security);
03363
Status =
NtCreateKey(&CloneHandle,
03364 KEY_READ | KEY_WRITE,
03365 &Attributes,
03366 0,
03367
NULL,
03368 REG_OPTION_VOLATILE,
03369 &Disposition);
03370
if (Security!=
NULL) {
03371
ExFreePool(Security);
03372 }
03373
if (!
NT_SUCCESS(
Status)) {
03374
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03375 KdPrint((
"CM: CmpCloneControlSet couldn't create Clone %08lx\n",
Status));
03376 }
03377
NtClose(CurrentHandle);
03378
return(
Status);
03379 }
03380
03381
03382
03383
03384
03385
if (Disposition != REG_CREATED_NEW_KEY) {
03386
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03387
03388 }
03389
03390
03391
03392
03393
03394
03395
03396
Status = STATUS_SUCCESS;
03397
goto Exit;
03398 }
03399
03400
Status =
ObReferenceObjectByHandle(CurrentHandle,
03401 KEY_READ,
03402
CmpKeyObjectType,
03403
KernelMode,
03404 (PVOID *)(&CurrentKey),
03405
NULL);
03406
if (!
NT_SUCCESS(
Status)) {
03407
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03408 KdPrint((
"CM: CmpCloneControlSet: couldn't reference CurrentHandle %08lx\n",
Status));
03409 }
03410
goto Exit;
03411 }
03412
03413
Status =
ObReferenceObjectByHandle(CloneHandle,
03414 KEY_WRITE,
03415
CmpKeyObjectType,
03416
KernelMode,
03417 (PVOID *)(&CloneKey),
03418
NULL);
03419
if (!
NT_SUCCESS(
Status)) {
03420
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03421 KdPrint((
"CM: CmpCloneControlSet: couldn't reference CurrentHandle %08lx\n",
Status));
03422 }
03423
ObDereferenceObject((PVOID)CurrentKey);
03424
goto Exit;
03425 }
03426
03427
CmpLockRegistryExclusive();
03428
03429
if (
CmpCopyTree(CurrentKey->KeyControlBlock->KeyHive,
03430 CurrentKey->KeyControlBlock->KeyCell,
03431 CloneKey->KeyControlBlock->KeyHive,
03432 CloneKey->KeyControlBlock->KeyCell)) {
03433
03434
03435
03436 CloneKey->KeyControlBlock->KeyNode->MaxNameLen = CurrentKey->KeyControlBlock->KeyNode->MaxNameLen;
03437
Status = STATUS_SUCCESS;
03438 }
else {
03439
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
03440 KdPrint((
"CM: CmpCloneControlSet: tree copy failed.\n"));
03441 }
03442
Status = STATUS_REGISTRY_CORRUPT;
03443 }
03444
03445
CmpUnlockRegistry();
03446
03447
ObDereferenceObject((PVOID)CurrentKey);
03448
ObDereferenceObject((PVOID)CloneKey);
03449
03450 Exit:
03451
NtClose(CurrentHandle);
03452
NtClose(CloneHandle);
03453
return(
Status);
03454
03455 }
03456
03457
NTSTATUS
03458 CmpSaveBootControlSet(USHORT ControlSetNum)
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487 {
03488 UNICODE_STRING SavedBoot, Boot;
03489 HANDLE BootHandle, SavedBootHandle;
03490 OBJECT_ATTRIBUTES Attributes;
03491
NTSTATUS Status;
03492
PCM_KEY_BODY BootKey, SavedBootKey;
03493 ULONG Disposition;
03494 PSECURITY_DESCRIPTOR Security;
03495 ULONG SecurityLength;
03496 BOOLEAN CopyRet;
03497 WCHAR
Buffer[128];
03498
03499
03500
03501
03502
03503
#if CLONE_CONTROL_SET
03504
03505
03506
03507
03508
03509
03510
03511
RtlInitUnicodeString(&Boot,
03512
L"\\Registry\\Machine\\System\\Clone");
03513
03514 InitializeObjectAttributes(&Attributes,
03515 &Boot,
03516 OBJ_CASE_INSENSITIVE,
03517
NULL,
03518
NULL);
03519
#else
03520
03521
03522
03523
03524
03525
03526 InitializeObjectAttributes(&Attributes,
03527 &
CmRegistryMachineSystemCurrentControlSet,
03528 OBJ_CASE_INSENSITIVE,
03529
NULL,
03530
NULL);
03531
#endif
03532
03533
03534
03535
03536
03537
Status =
NtOpenKey(&BootHandle,
03538 KEY_READ,
03539 &Attributes);
03540
03541
03542
if (!
NT_SUCCESS(
Status))
return(
Status);
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
Status =
NtQuerySecurityObject(BootHandle,
03554 DACL_SECURITY_INFORMATION,
03555
NULL,
03556 0,
03557 &SecurityLength);
03558
03559
03560
if (
Status==STATUS_BUFFER_TOO_SMALL) {
03561
03562 Security=
ExAllocatePool(
PagedPool,SecurityLength);
03563
03564
if (Security!=
NULL) {
03565
03566
Status =
NtQuerySecurityObject(BootHandle,
03567 DACL_SECURITY_INFORMATION,
03568 Security,
03569 SecurityLength,
03570 &SecurityLength);
03571
03572
03573
if (!
NT_SUCCESS(
Status)) {
03574
ExFreePool(Security);
03575 Security=
NULL;
03576 }
03577 }
03578
03579 }
else {
03580 Security=
NULL;
03581 }
03582
03583
03584
03585
03586
03587 swprintf(
Buffer,
L"\\Registry\\Machine\\System\\ControlSet%03d", ControlSetNum);
03588
03589
RtlInitUnicodeString(&SavedBoot,
03590
Buffer);
03591
03592
03593
03594
03595
03596 InitializeObjectAttributes(&Attributes,
03597 &SavedBoot,
03598 OBJ_CASE_INSENSITIVE,
03599
NULL,
03600 Security);
03601
03602
Status =
NtCreateKey(&SavedBootHandle,
03603 KEY_READ | KEY_WRITE,
03604 &Attributes,
03605 0,
03606
NULL,
03607 REG_OPTION_NON_VOLATILE,
03608 &Disposition);
03609
03610
03611
if (Security)
ExFreePool(Security);
03612
03613
if (!
NT_SUCCESS(
Status)) {
03614
NtClose(BootHandle);
03615
return(
Status);
03616 }
03617
03618
03619
03620
03621
03622
Status =
ObReferenceObjectByHandle(BootHandle,
03623 KEY_READ,
03624
CmpKeyObjectType,
03625
KernelMode,
03626 (PVOID *)(&BootKey),
03627
NULL);
03628
03629
if (!
NT_SUCCESS(
Status))
goto Exit;
03630
03631
Status =
ObReferenceObjectByHandle(SavedBootHandle,
03632 KEY_WRITE,
03633
CmpKeyObjectType,
03634
KernelMode,
03635 (PVOID *)(&SavedBootKey),
03636
NULL);
03637
03638
03639
if (!
NT_SUCCESS(
Status)) {
03640
ObDereferenceObject((PVOID)BootKey);
03641
goto Exit;
03642 }
03643
03644
03645
03646
03647
03648
CmpLockRegistryExclusive();
03649
03650
if (Disposition == REG_CREATED_NEW_KEY) {
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664 CopyRet =
CmpCopyTreeEx(BootKey->KeyControlBlock->KeyHive,
03665 BootKey->KeyControlBlock->KeyCell,
03666 SavedBootKey->KeyControlBlock->KeyHive,
03667 SavedBootKey->KeyControlBlock->KeyCell,
03668
CLONE_CONTROL_SET);
03669
03670
03671
03672
03673 SavedBootKey->KeyControlBlock->KeyNode->MaxNameLen = BootKey->KeyControlBlock->KeyNode->MaxNameLen;
03674 }
else {
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694
03695 CopyRet =
CmpSyncTrees(BootKey->KeyControlBlock->KeyHive,
03696 BootKey->KeyControlBlock->KeyCell,
03697 SavedBootKey->KeyControlBlock->KeyHive,
03698 SavedBootKey->KeyControlBlock->KeyCell,
03699
CLONE_CONTROL_SET);
03700 }
03701
03702
03703
03704
03705
03706
03707
if (CopyRet) {
03708
Status = STATUS_SUCCESS;
03709 }
else {
03710
Status = STATUS_REGISTRY_CORRUPT;
03711 }
03712
03713
03714
03715
03716
03717
CmpUnlockRegistry();
03718
03719
ObDereferenceObject((PVOID)BootKey);
03720
ObDereferenceObject((PVOID)SavedBootKey);
03721
03722 Exit:
03723
03724
NtClose(BootHandle);
03725
NtClose(SavedBootHandle);
03726
03727
#if CLONE_CONTROL_SET
03728
03729
03730
03731
03732
03733
03734
03735
if(
NT_SUCCESS(
Status))
03736 {
03737
CmpDeleteCloneTree();
03738 }
03739
03740
#endif
03741
03742
return(
Status);
03743
03744 }
03745
03746
NTSTATUS
03747 CmpDeleteCloneTree()
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763 {
03764 OBJECT_ATTRIBUTES Obja;
03765
03766 InitializeObjectAttributes(
03767 &Obja,
03768 &
CmRegistrySystemCloneName,
03769 OBJ_CASE_INSENSITIVE,
03770 (HANDLE)
NULL,
03771
NULL);
03772
03773
return NtUnloadKey(&Obja);
03774 }
03775
03776
03777
VOID
03778 CmBootLastKnownGood(
03779 ULONG ErrorLevel
03780 )
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814 {
03815
ARC_STATUS Status;
03816
03817
PAGED_CODE();
03818
03819
if (
CmFirstTime !=
TRUE) {
03820
03821
03822
03823
03824
03825
03826
return;
03827 }
03828
03829
switch (ErrorLevel) {
03830
case NormalError:
03831
case IgnoreError:
03832
break;
03833
03834
case SevereError:
03835
if (
CmpIsLastKnownGoodBoot()) {
03836
break;
03837 }
else {
03838
Status =
HalSetEnvironmentVariable(
"LastKnownGood",
"TRUE");
03839
if (
Status ==
ESUCCESS) {
03840
HalReturnToFirmware(
HalRebootRoutine);
03841 }
03842 }
03843
break;
03844
03845
case CriticalError:
03846
if (
CmpIsLastKnownGoodBoot()) {
03847
KeBugCheckEx(CRITICAL_SERVICE_FAILED,5,9,0,0);
03848 }
else {
03849
Status =
HalSetEnvironmentVariable(
"LastKnownGood",
"TRUE");
03850
if (
Status ==
ESUCCESS) {
03851
HalReturnToFirmware(
HalRebootRoutine);
03852 }
else {
03853
KeBugCheckEx(SET_ENV_VAR_FAILED,5,10,0,0);
03854 }
03855 }
03856
break;
03857 }
03858
return;
03859 }
03860
03861
03862 BOOLEAN
03863 CmpIsLastKnownGoodBoot(
03864 VOID
03865 )
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895 {
03896
NTSTATUS Status;
03897 ULONG Default;
03898 ULONG Current;
03899 ULONG LKG;
03900 RTL_QUERY_REGISTRY_TABLE QueryTable[] = {
03901 {
NULL, RTL_QUERY_REGISTRY_DIRECT,
03902
L"Current", &Current,
03903 REG_DWORD, (PVOID)&Current, 0 },
03904 {
NULL, RTL_QUERY_REGISTRY_DIRECT,
03905
L"LastKnownGood", &LKG,
03906 REG_DWORD, (PVOID)&LKG, 0 },
03907 {
NULL, RTL_QUERY_REGISTRY_DIRECT,
03908
L"Default", &Default,
03909 REG_DWORD, (PVOID)&Default, 0 },
03910 {
NULL, 0,
03911
NULL,
NULL,
03912 REG_NONE,
NULL, 0 }
03913 };
03914
03915
PAGED_CODE();
03916
03917
Status =
RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
03918
L"\\Registry\\Machine\\System\\Select",
03919 QueryTable,
03920
NULL,
03921
NULL);
03922
03923
03924
03925
03926
ASSERT(
NT_SUCCESS(
Status));
03927
if (!
NT_SUCCESS(
Status)) {
03928
CMLOG(
CML_MAJOR,
CMS_INIT) {
03929 KdPrint((
"CmpIsLastKnownGoodBoot: RtlQueryRegistryValues "));
03930 KdPrint((
"failed, Status %08lx\n",
Status));
03931 }
03932
return(
FALSE);
03933 }
03934
03935
if ((LKG == Current) && (Current != Default)){
03936
return(
TRUE);
03937 }
else {
03938
return(
FALSE);
03939 }
03940 }
03941
03942
03943
VOID
03944 CmShutdownSystem(
03945 VOID
03946 )
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965 {
03966
REGISTRY_COMMAND CommandArea;
03967
03968
PAGED_CODE();
03969
CmpLockRegistryExclusive();
03970
03971
CommandArea.
Command =
REG_CMD_SHUTDOWN;
03972
CmpWorker(&
CommandArea);
03973
03974
HvShutdownComplete =
TRUE;
03975
03976
03977
CmpUnlockRegistry();
03978
return;
03979 }
03980
03981
03982 BOOLEAN
03983 CmpLinkKeyToHive(
03984 PWSTR KeyPath,
03985 PWSTR HivePath
03986 )
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008 {
04009 UNICODE_STRING
KeyName;
04010 UNICODE_STRING LinkName;
04011 OBJECT_ATTRIBUTES Attributes;
04012 HANDLE LinkHandle;
04013 ULONG Disposition;
04014
NTSTATUS Status;
04015
04016
PAGED_CODE();
04017
04018
04019
04020
04021
04022
RtlInitUnicodeString(&
KeyName,
KeyPath);
04023 InitializeObjectAttributes(&Attributes,
04024 &
KeyName,
04025 OBJ_CASE_INSENSITIVE,
04026
NULL,
04027
NULL);
04028
Status =
NtCreateKey(&LinkHandle,
04029 KEY_CREATE_LINK,
04030 &Attributes,
04031 0,
04032
NULL,
04033 REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
04034 &Disposition);
04035
if (!
NT_SUCCESS(
Status)) {
04036
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
04037 KdPrint((
"CM: CmpLinkKeyToHive: couldn't create %S\n", &
KeyName));
04038 KdPrint((
" Status = %08lx\n",
Status));
04039 }
04040
return(
FALSE);
04041 }
04042
04043
04044
04045
04046
04047
04048
if (Disposition != REG_CREATED_NEW_KEY) {
04049
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
04050 KdPrint((
"CM: CmpLinkKeyToHive: %S already exists!\n", &
KeyName));
04051 }
04052
04053
NtClose(LinkHandle);
04054
return(
FALSE);
04055 }
04056
04057
RtlInitUnicodeString(&LinkName, HivePath);
04058
Status =
NtSetValueKey(LinkHandle,
04059 &
CmSymbolicLinkValueName,
04060 0,
04061 REG_LINK,
04062 LinkName.Buffer,
04063 LinkName.Length);
04064
NtClose(LinkHandle);
04065
if (!
NT_SUCCESS(
Status)) {
04066
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
04067 KdPrint((
"CM: CmpLinkKeyToHive: couldn't create symbolic link for %S\n", HivePath));
04068 }
04069
return(
FALSE);
04070 }
04071
04072
return(
TRUE);
04073 }
04074
04075
04076 BOOLEAN
04077 CmpValidateAlternate(
04078 IN HANDLE FileHandle,
04079 IN
PCMHIVE PrimaryHive
04080 )
04081
04082
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103 {
04104
PCMHIVE CmHive;
04105 BOOLEAN
Status;
04106
NTSTATUS Status2;
04107
04108 Status2 =
CmpInitializeHive(&CmHive,
04109
HINIT_FILE,
04110 0,
04111
HFILE_TYPE_PRIMARY,
04112
NULL,
04113 FileHandle,
04114
NULL,
04115
NULL,
04116
NULL,
04117 &
CmpSystemFileName
04118 );
04119
if (!
NT_SUCCESS(Status2)) {
04120
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
04121 KdPrint((
"CmpValidateSecondary: SYSTEM.ALT is corrupt\n"));
04122 }
04123
return(
FALSE);
04124 }
04125
04126
04127
04128
04129
04130
04131
if (CmHive->
Hive.
BaseBlock->
TimeStamp.QuadPart !=
04132 PrimaryHive->Hive.BaseBlock->TimeStamp.QuadPart) {
04133
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
04134 KdPrint((
"CmpValidateSecondary: timestamps don't match"));
04135 }
04136
Status =
FALSE;
04137 }
else {
04138
Status =
TRUE;
04139 }
04140
04141
04142
04143
04144 RemoveEntryList(&CmHive->
HiveList);
04145
HvFreeHive(&CmHive->
Hive);
04146
ASSERT( CmHive->
HiveLock );
04147
ExFreePool(CmHive->
HiveLock);
04148
CmpFree(CmHive,
sizeof(
CMHIVE));
04149
return(
Status);
04150
04151 }
04152
04153
04154
VOID
04155 CmpCreatePerfKeys(
04156 VOID
04157 )
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172
04173
04174
04175 {
04176 HANDLE Perflib;
04177
NTSTATUS Status;
04178 WCHAR LanguageId[4];
04179 OBJECT_ATTRIBUTES Attributes;
04180 UNICODE_STRING
String;
04181
USHORT Language;
04182 LONG i;
04183 WCHAR
c;
04184
extern PWCHAR
CmpRegistryPerflibString;
04185
04186
RtlInitUnicodeString(&
String,
CmpRegistryPerflibString);
04187
04188 InitializeObjectAttributes(&Attributes,
04189 &
String,
04190 OBJ_CASE_INSENSITIVE,
04191
NULL,
04192
NULL);
04193
Status =
NtOpenKey(&Perflib,
04194 KEY_WRITE,
04195 &Attributes);
04196
if (!
NT_SUCCESS(
Status)) {
04197
return;
04198 }
04199
04200
04201
04202
04203
04204
CmpCreatePredefined(Perflib,
04205
L"009",
04206
HKEY_PERFORMANCE_TEXT);
04207
04208
04209
04210
04211
04212
if (
PsDefaultSystemLocaleId != 0x00000409) {
04213 Language = LANGIDFROMLCID(
PsDefaultSystemLocaleId) & 0xff;
04214 LanguageId[3] =
L'\0';
04215
for (i=2;i>=0;i--) {
04216
c = Language % 16;
04217
if (
c>9) {
04218 LanguageId[i]=
c+
L'A'-10;
04219 }
else {
04220 LanguageId[i]=
c+
L'0';
04221 }
04222 Language = Language >> 4;
04223 }
04224
CmpCreatePredefined(Perflib,
04225 LanguageId,
04226
HKEY_PERFORMANCE_NLSTEXT);
04227 }
04228
04229
04230 }
04231
04232
04233
VOID
04234 CmpCreatePredefined(
04235 IN HANDLE Root,
04236 IN PWSTR KeyName,
04237 IN HANDLE PredefinedHandle
04238 )
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262 {
04263 OBJECT_ATTRIBUTES
ObjectAttributes;
04264
CM_PARSE_CONTEXT ParseContext;
04265
NTSTATUS Status;
04266 UNICODE_STRING
Name;
04267 HANDLE
Handle;
04268
04269 ParseContext.
Class.Length = 0;
04270 ParseContext.
Class.Buffer =
NULL;
04271
04272 ParseContext.
TitleIndex = 0;
04273 ParseContext.
CreateOptions = REG_OPTION_VOLATILE |
REG_OPTION_PREDEF_HANDLE;
04274 ParseContext.
Disposition = 0;
04275 ParseContext.
CreateLink =
FALSE;
04276 ParseContext.
PredefinedHandle = PredefinedHandle;
04277
04278
RtlInitUnicodeString(&
Name,
KeyName);
04279 InitializeObjectAttributes(&
ObjectAttributes,
04280 &
Name,
04281 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
04282 Root,
04283
NULL);
04284
04285
Status =
ObOpenObjectByName(&
ObjectAttributes,
04286
CmpKeyObjectType,
04287
KernelMode,
04288
NULL,
04289 KEY_READ,
04290 (PVOID)&ParseContext,
04291 &
Handle);
04292
ASSERT(
NT_SUCCESS(
Status));
04293
04294 ZwClose(
Handle);
04295
04296 }
04297
04298
04299