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

cmsysini.c File Reference

#include "cmp.h"
#include "arccodes.h"

Go to the source code of this file.

Defines

#define INIT_SYSTEMROOT_HIVEPATH   L"\\SystemRoot\\System32\\Config\\"
#define INIT_REGISTRY_MASTERPATH   L"\\REGISTRY\\"
#define SYSTEM_HIVE_INDEX   3
#define CLONE_HIVE_INDEX   6
#define SYSTEM_PATH   L"\\registry\\machine\\system"
#define HKEY_PERFORMANCE_TEXT   (( HANDLE ) (ULONG_PTR)((LONG)0x80000050) )
#define HKEY_PERFORMANCE_NLSTEXT   (( HANDLE ) (ULONG_PTR)((LONG)0x80000060) )
#define CMP_KEY_INVALID_ATTRIBUTES
#define MAX_NAME   128

Functions

VOID CmpCreatePredefined (IN HANDLE Root, IN PWSTR KeyName, IN HANDLE PredefinedHandle)
VOID CmpCreatePerfKeys (VOID)
BOOLEAN CmpLinkKeyToHive (PWSTR KeyPath, PWSTR HivePath)
BOOLEAN CmpValidateAlternate (IN HANDLE FileHandle, IN PCMHIVE PrimaryHive)
NTSTATUS CmpCreateControlSet (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS CmpCloneControlSet (VOID)
BOOLEAN CmpCreateObjectTypes (VOID)
BOOLEAN CmpCreateRegistryRoot (VOID)
BOOLEAN CmpCreateRootNode (IN PHHIVE Hive, IN PWSTR Name, OUT PHCELL_INDEX RootCellIndex)
VOID CmpFreeDriverList (IN PHHIVE Hive, IN PLIST_ENTRY DriverList)
VOID CmpInitializeHiveList (VOID)
BOOLEAN CmpInitializeSystemHive (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS CmpInterlockedFunction (PWCHAR RegistryValueKey, VOID(*InterlockedFunction)(VOID))
VOID CmpConfigureProcessors (VOID)
NTSTATUS CmpAddDockingInfo (IN HANDLE Key, IN PROFILE_PARAMETER_BLOCK *ProfileBlock)
NTSTATUS CmpAddAliasEntry (IN HANDLE IDConfigDB, IN PROFILE_PARAMETER_BLOCK *ProfileBlock, IN ULONG ProfileNumber)
NTSTATUS CmpDeleteCloneTree (VOID)
VOID CmpDiskFullWarning (VOID)
BOOLEAN CmInitSystem1 (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS CmpLinkHiveToMaster (PUNICODE_STRING LinkName, HANDLE RootDirectory, PCMHIVE CmHive, BOOLEAN Allocate, PSECURITY_DESCRIPTOR SecurityDescriptor)
VOID CmpSetVersionData (VOID)
PHANDLE CmGetSystemDriverList (VOID)
NTSTATUS CmpInitHiveFromFile (IN PUNICODE_STRING FileName, IN ULONG HiveFlags, OUT PCMHIVE *CmHive, IN OUT PBOOLEAN Allocate, IN OUT PBOOLEAN RegistryLocked)
NTSTATUS CmpHwprofileDefaultSelect (IN PCM_HARDWARE_PROFILE_LIST ProfileList, OUT PULONG ProfileIndexToUse, IN PVOID Context)
NTSTATUS CmpSaveBootControlSet (USHORT ControlSetNum)
NTSTATUS CmpDeleteCloneTree ()
VOID CmBootLastKnownGood (ULONG ErrorLevel)
BOOLEAN CmpIsLastKnownGoodBoot (VOID)
VOID CmShutdownSystem (VOID)

Variables

PKPROCESS CmpSystemProcess
ERESOURCE CmpRegistryLock
FAST_MUTEX CmpKcbLock
FAST_MUTEX CmpPostLock
BOOLEAN CmFirstTime
HIVE_LIST_ENTRY CmpMachineHiveList []
UNICODE_STRING CmpSystemFileName
UNICODE_STRING CmSymbolicLinkValueName
UNICODE_STRING CmpLoadOptions
PWCHAR CmpProcessorControl
PWCHAR CmpControlSessionManager
PCMHIVE CmpMasterHive
BOOLEAN CmpNoMasterCreates
LIST_ENTRY CmpHiveListHead
POBJECT_TYPE CmpKeyObjectType
BOOLEAN CmpNoWrite
BOOLEAN HvShutdownComplete
PUCHAR CmpStashBuffer
ULONG CmpStashBufferSize
BOOLEAN CmpCannotWriteConfiguration
UNICODE_STRING nullclass


Define Documentation

#define CLONE_HIVE_INDEX   6
 

Definition at line 64 of file cmsysini.c.

Referenced by CmInitSystem1().

#define CMP_KEY_INVALID_ATTRIBUTES
 

Value:

(OBJ_EXCLUSIVE |\ OBJ_PERMANENT)

Definition at line 115 of file cmsysini.c.

Referenced by CmpCreateObjectTypes().

#define HKEY_PERFORMANCE_NLSTEXT   (( HANDLE ) (ULONG_PTR)((LONG)0x80000060) )
 

Definition at line 72 of file cmsysini.c.

Referenced by CmpCreatePerfKeys().

#define HKEY_PERFORMANCE_TEXT   (( HANDLE ) (ULONG_PTR)((LONG)0x80000050) )
 

Definition at line 71 of file cmsysini.c.

Referenced by CmpCreatePerfKeys().

#define INIT_REGISTRY_MASTERPATH   L"\\REGISTRY\\"
 

Definition at line 39 of file cmsysini.c.

Referenced by CmpInitializeHiveList().

#define INIT_SYSTEMROOT_HIVEPATH   L"\\SystemRoot\\System32\\Config\\"
 

Definition at line 37 of file cmsysini.c.

Referenced by CmpInitializeHiveList().

#define MAX_NAME   128
 

Referenced by CmpInitializeHiveList().

#define SYSTEM_HIVE_INDEX   3
 

Definition at line 63 of file cmsysini.c.

Referenced by CmpInitializeSystemHive().

#define SYSTEM_PATH   L"\\registry\\machine\\system"
 

Definition at line 66 of file cmsysini.c.


Function Documentation

VOID CmBootLastKnownGood ULONG  ErrorLevel  ) 
 

Definition at line 3778 of file cmsysini.c.

References ARC_STATUS, CmFirstTime, CmpIsLastKnownGoodBoot(), ESUCCESS, HalRebootRoutine, HalReturnToFirmware(), HalSetEnvironmentVariable(), KeBugCheckEx(), PAGED_CODE, Status, and TRUE.

Referenced by IopLoadDriver().

03784 : 03785 03786 This function is called to indicate a failure during the boot process. 03787 The actual result is based on the value of ErrorLevel: 03788 03789 IGNORE - Will return, boot should proceed 03790 NORMAL - Will return, boot should proceed 03791 03792 SEVERE - If not booting LastKnownGood, will switch to LastKnownGood 03793 and reboot the system. 03794 03795 If already booting LastKnownGood, will return. Boot should 03796 proceed. 03797 03798 CRITICAL - If not booting LastKnownGood, will switch to LastKnownGood 03799 and reboot the system. 03800 03801 If already booting LastKnownGood, will bugcheck. 03802 03803 Arguments: 03804 03805 ErrorLevel - Supplies the severity level of the failure 03806 03807 Return Value: 03808 03809 None. If it returns, boot should proceed. May cause the system to 03810 reboot. 03811 03812 --*/ 03813 03814 { 03815 ARC_STATUS Status; 03816 03817 PAGED_CODE(); 03818 03819 if (CmFirstTime != TRUE) { 03820 03821 // 03822 // NtInitializeRegistry has been called, so handling 03823 // driver errors is not a task for ScReg. 03824 // Treat all errors as Normal 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 }

PHANDLE CmGetSystemDriverList VOID   ) 
 

Definition at line 2169 of file cmsysini.c.

References CML_BUGCHECK, CMLOG, CmpFindControlSet(), CmpFindDrivers(), CmpFreeDriverList(), CmpKeyObjectType, CmpLockRegistryExclusive(), CmpResolveDriverDependencies(), CmpSortDriverList(), CmpUnlockRegistry(), CMS_INIT_ERROR, DriverEntry(), ExAllocatePool, Handle, HCELL_INDEX, HCELL_NIL, Hive, KeBugCheckEx(), KernelMode, L, Name, NonPagedPool, NT_SUCCESS, NtClose(), NtOpenKey(), NTSTATUS(), NULL, ObDereferenceObject, ObjectAttributes, ObReferenceObjectByHandle(), PAGED_CODE, RtlInitUnicodeString(), and Status.

Referenced by IopInitializeSystemDrivers().

02175 : 02176 02177 Traverses the current SERVICES subtree and creates the list of drivers 02178 to be loaded during Phase 1 initialization. 02179 02180 Arguments: 02181 02182 None 02183 02184 Return Value: 02185 02186 A pointer to an array of handles, each of which refers to a key in 02187 the \Services section of the control set. The caller will traverse 02188 this array and load and initialize the drivers described by the keys. 02189 02190 The last key will be NULL. The array is allocated in Pool and should 02191 be freed by the caller. 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 // Now we have found out the PHHIVE and HCELL_INDEX of the root of the 02257 // SYSTEM hive, we can use all the same code that the OS Loader does. 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 // We now have a fully sorted and ordered list of drivers to be loaded 02322 // by IoInit. 02323 // 02324 02325 // 02326 // Count the nodes in the list. 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); // odds against this are huge 02340 } 02341 02342 // 02343 // Walk the list, opening each registry key and adding it to the 02344 // table of handles. 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 }

BOOLEAN CmInitSystem1 IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 293 of file cmsysini.c.

References ASSERT, CLONE_HIVE_INDEX, _HIVE_LIST_ENTRY::CmHive, CML_BUGCHECK, CML_MAJOR, CMLOG, CmpAddToHiveFileList(), CmpCloneControlSet(), CmpComputeGlobalQuotaAllowed(), CmpCreateControlSet(), CmpCreateObjectTypes(), CmpCreateRegistryRoot(), CmpHiveListHead, CmpHiveRootSecurityDescriptor(), CmpInitializeCache(), CmpInitializeHardwareConfiguration(), CmpInitializeHive(), CmpInitializeMachineDependentConfiguration(), CmpInitializeRegistryNames(), CmpInitializeSystemHive(), CmpKcbLock, CmpLinkHiveToMaster(), CmpLinkKeyToHive(), CmpLoadOptions, CmpLockRegistryExclusive(), CmpMachineHiveList, CmpMasterHive, CmpNoMasterCreates, CmpPostLock, CmpRegistryLock, CmpStashBuffer, CmpStashBufferSize, CmpSystemProcess, CmpUnlockRegistry(), CmRegistryMachineHardwareName, CmRegistryMachineName, CmRegistrySystemCloneName, CmRegistryUserName, CMS_INIT, CMS_INIT_ERROR, ExAllocatePoolWithTag, ExFreePool(), ExInitializeFastMutex, ExInitializeResource, FALSE, HBLOCK_SIZE, HFILE_TYPE_PRIMARY, HINIT_CREATE, HIVE_VOLATILE, KeBugCheckEx(), L, NT_SUCCESS, NtClose(), NtCreateKey(), NtOpenKey(), NtSetValueKey(), NTSTATUS(), NULL, nullclass, ObjectAttributes, PAGED_CODE, PagedPool, PsGetCurrentProcess, RtlInitUnicodeString(), and TRUE.

00298 : 00299 00300 This function is called as part of phase1 init, after the object 00301 manager has been inited, but before IoInit. It's purpose is to 00302 set up basic registry object operations, and transform data 00303 captured during boot into registry format (whether it was read 00304 from the SYSTEM hive file by the osloader or computed by recognizers.) 00305 After this call, Nt*Key calls work, but only part of the name 00306 space is available and any changes written must be held in 00307 memory. 00308 00309 CmpMachineHiveList entries marked CM_PHASE_1 are available 00310 after return from this call, but writes must be held in memory. 00311 00312 This function will: 00313 00314 1. Create the regisrty worker/lazy-write thread 00315 2. Create the registry key object type 00316 4. Create the master hive 00317 5. Create the \REGISTRY node 00318 6. Create a KEY object that refers to \REGISTRY 00319 7. Create \REGISTRY\MACHINE node 00320 8. Create the SYSTEM hive, fill in with data from loader 00321 9. Create the HARDWARE hive, fill in with data from loader 00322 10. Create: 00323 \REGISTRY\MACHINE\SYSTEM 00324 \REGISTRY\MACHINE\HARDWARE 00325 Both of which will be link nodes in the master hive. 00326 00327 NOTE: We do NOT free allocated pool in failure case. This is because 00328 our caller is going to bugcheck anyway, and having the memory 00329 object to look at is useful. 00330 00331 Arguments: 00332 00333 LoaderBlock - supplies the LoaderBlock passed in from the OSLoader. 00334 By looking through the memory descriptor list we can find the 00335 SYSTEM hive which the OSLoader has placed in memory for us. 00336 00337 Return Value: 00338 00339 TRUE if all operations were successful, false if any failed. 00340 00341 Bugchecks when something went wrong (CONFIG_INITIALIZATION_FAILED,4,.....) 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 // Initialize Names of all registry paths. 00359 // This simply initializes unicode strings so we don't have to bother 00360 // with it later. This can not fail. 00361 // 00362 CmpInitializeRegistryNames(); 00363 00364 // 00365 // Compute registry global quota 00366 // 00367 CmpComputeGlobalQuotaAllowed(); 00368 00369 // 00370 // Initialize the hive list head 00371 // 00372 InitializeListHead(&CmpHiveListHead); 00373 00374 // 00375 // Initialize the global registry resource 00376 // 00377 ExInitializeResource(&CmpRegistryLock); 00378 00379 // 00380 // Initialize the KCB tree mutex 00381 // 00382 ExInitializeFastMutex(&CmpKcbLock); 00383 00384 // 00385 // Initialize the PostList mutex 00386 // 00387 ExInitializeFastMutex(&CmpPostLock); 00388 00389 // 00390 // Initialize the cache 00391 // 00392 CmpInitializeCache (); 00393 00394 // 00395 // Save the current process to allow us to attach to it later. 00396 // 00397 CmpSystemProcess = &PsGetCurrentProcess()->Pcb; 00398 00399 CmpLockRegistryExclusive(); 00400 00401 // 00402 // Create the Key object type. 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); // could not registrate with object manager 00409 return FALSE; 00410 } 00411 00412 00413 // 00414 // Create the master hive and initialize it. 00415 // 00416 status = CmpInitializeHive(&CmpMasterHive, 00417 HINIT_CREATE, 00418 HIVE_VOLATILE, 00419 HFILE_TYPE_PRIMARY, // i.e. no logging, no alterate 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); // could not initialize master hive 00431 return (FALSE); 00432 } 00433 00434 // 00435 // try to allocate a stash buffer. if we can't get 1 page this 00436 // early on, we're in deep trouble, so punt. 00437 // 00438 CmpStashBuffer = ExAllocatePoolWithTag(PagedPool, HBLOCK_SIZE,'bSmC'); 00439 if (CmpStashBuffer == NULL) { 00440 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,3,0,0); // odds against this are huge 00441 return FALSE; 00442 } 00443 CmpStashBufferSize = HBLOCK_SIZE; 00444 00445 // 00446 // Create the \REGISTRY node 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); // could not create root of the registry 00453 return FALSE; 00454 } 00455 00456 // 00457 // --- 6. Create \REGISTRY\MACHINE and \REGISTRY\USER nodes --- 00458 // 00459 00460 // 00461 // Get default security descriptor for the nodes we will create. 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); // could not create HKLM 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); // could not create HKUSER 00516 return FALSE; 00517 } 00518 00519 NtClose(key1); 00520 00521 00522 // 00523 // --- 7. Create the SYSTEM hive, fill in with data from loader --- 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); // could not create SystemHive 00532 return(FALSE); 00533 } 00534 00535 // 00536 // Create the symbolic link \Registry\Machine\System\CurrentControlSet 00537 // 00538 status = CmpCreateControlSet(LoaderBlock); 00539 if (!NT_SUCCESS(status)) { 00540 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,8,0,0); // could not create CurrentControlSet 00541 return(FALSE); 00542 } 00543 00544 // 00545 // Handle the copying of the CurrentControlSet to a Clone volatile 00546 // hive (but only if we really want to have a clone) 00547 // 00548 00549 #if CLONE_CONTROL_SET 00550 00551 // 00552 // Create the Clone temporary hive, link it into the master hive, 00553 // and make a symbolic link to it. 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); // could not initialize clone hive 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); // could not link clone hive to master hive 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 // Clone the current control set for the service controller 00599 // 00600 status = CmpCloneControlSet(); 00601 00602 // 00603 // If this didn't work, it's bad, but not bad enough to fail the boot 00604 // 00605 ASSERT(NT_SUCCESS(status)); 00606 00607 #endif 00608 00609 // 00610 // --- 8. Create the HARDWARE hive, fill in with data from loader --- 00611 // 00612 status = CmpInitializeHive(&HardwareHive, 00613 HINIT_CREATE, 00614 HIVE_VOLATILE, 00615 HFILE_TYPE_PRIMARY, // i.e. no log, no alternate 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); // could not initialize hardware hive 00629 return(FALSE); 00630 } 00631 00632 // 00633 // Allocate the root node 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); // could not link hardware hive to master hive 00647 return FALSE; 00648 } 00649 CmpAddToHiveFileList(HardwareHive); 00650 00651 ExFreePool(SecurityDescriptor); 00652 00653 CmpMachineHiveList[0].CmHive = HardwareHive; 00654 00655 // 00656 // put loader configuration tree data to our hardware registry. 00657 // 00658 status = CmpInitializeHardwareConfiguration(LoaderBlock); 00659 00660 if (!NT_SUCCESS(status)) { 00661 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED,4,13,0,0); // could not initialize hardware configuration 00662 return(FALSE); 00663 } 00664 00665 CmpNoMasterCreates = TRUE; 00666 CmpUnlockRegistry(); 00667 00668 // 00669 // put machine dependant configuration data to our hardware registry. 00670 // 00671 status = CmpInitializeMachineDependentConfiguration(LoaderBlock); 00672 00673 00674 // 00675 // store boot loader command tail in registry 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, // TitleIndex 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); // could not open CurrentControlSet\\Control 00718 return(FALSE); 00719 } 00720 00721 return TRUE; 00722 }

NTSTATUS CmpAddAliasEntry IN HANDLE  IDConfigDB,
IN PROFILE_PARAMETER_BLOCK ProfileBlock,
IN ULONG  ProfileNumber
 

Definition at line 2606 of file cmsysini.c.

References ASSERT, CHAR, CM_HARDWARE_PROFILE_STR_ALIAS, CM_HARDWARE_PROFILE_STR_PROFILE_NUMBER, CML_BUGCHECK, CMLOG, CmpAddDockingInfo(), CMS_INIT, FALSE, NT_SUCCESS, NtClose(), NtCreateKey(), NtOpenKey(), NtSetValueKey(), NTSTATUS(), NULL, PAGED_CODE, RtlAnsiStringToUnicodeString(), RtlInitAnsiString(), RtlInitUnicodeString(), and sprintf().

Referenced by CmpCreateControlSet().

02612 : 02613 Create an alias entry in the IDConfigDB database for the given 02614 hardware profile. 02615 02616 Create the "Alias" key if it does not exist. 02617 02618 Parameters: 02619 02620 IDConfigDB - Pointer to "..\CurrentControlSet\Control\IDConfigDB" 02621 02622 ProfileBlock - Description of the current Docking information 02623 02624 ProfileNumber - 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 // Find the Alias Key or Create it if it does not already exist. 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, // no title 02662 NULL, // no class 02663 0, // no options 02664 &disposition); 02665 } 02666 02667 if (!NT_SUCCESS (status)) { 02668 aliasKey = NULL; 02669 goto Exit; 02670 } 02671 02672 // 02673 // Create an entry key 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 // Write the standard goo 02739 // 02740 CmpAddDockingInfo (aliasEntry, ProfileBlock); 02741 02742 // 02743 // Write the Profile Number 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 }

NTSTATUS CmpAddDockingInfo IN HANDLE  Key,
IN PROFILE_PARAMETER_BLOCK ProfileBlock
 

Definition at line 2532 of file cmsysini.c.

References CM_HARDWARE_PROFILE_STR_CAPABILITIES, CM_HARDWARE_PROFILE_STR_DOCKID, CM_HARDWARE_PROFILE_STR_DOCKING_STATE, CM_HARDWARE_PROFILE_STR_SERIAL_NUMBER, Key, NT_SUCCESS, NtSetValueKey(), NTSTATUS(), PAGED_CODE, and RtlInitUnicodeString().

Referenced by CmpAddAliasEntry(), and CmpCreateControlSet().

02537 : 02538 Write DockID SerialNumber DockState and Capabilities intot the given 02539 registry key. 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 }

NTSTATUS CmpCloneControlSet VOID   ) 
 

Definition at line 3262 of file cmsysini.c.

References CML_BUGCHECK, CMLOG, CmpCopyTree, CmpKeyObjectType, CmpLockRegistryExclusive(), CmpUnlockRegistry(), CMS_INIT, ExAllocatePool, ExFreePool(), KernelMode, L, NT_SUCCESS, NtClose(), NtCreateKey(), NtOpenKey(), NtQuerySecurityObject(), NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, PagedPool, RtlInitUnicodeString(), and Status.

Referenced by CmInitSystem1().

03268 : 03269 03270 First, create a new hive, \registry\machine\clone, which will be 03271 HIVE_VOLATILE. 03272 03273 Second, link \Registry\Machine\System\Clone to it. 03274 03275 Third, tree copy \Registry\Machine\System\CurrentControlSet into 03276 \Registry\Machine\System\Clone (and thus into the clone hive.) 03277 03278 When the service controller is done with the clone hive, it can 03279 simply NtUnloadKey it to free its storage. 03280 03281 Arguments: 03282 03283 None. \Registry\Machine\System\CurrentControlSet must already exist. 03284 03285 Return Value: 03286 03287 NTSTATUS 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 // Get the security descriptor from the key so we can create the clone 03328 // tree with the correct ACL. 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 // Check to make sure the key was created. If it already exists, 03383 // something is wrong. 03384 // 03385 if (Disposition != REG_CREATED_NEW_KEY) { 03386 CMLOG(CML_BUGCHECK, CMS_INIT) { 03387 // KdPrint(("CM: CmpCloneControlSet: Clone tree already exists!\n")); 03388 } 03389 03390 // 03391 // WARNNOTE: 03392 // If somebody somehow managed to create a key in our way, 03393 // they'll thwart last known good. Tough luck. 03394 // Claim it worked and go on. 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 // Set the max subkey name property for the new target key. 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 }

VOID CmpConfigureProcessors VOID   ) 
 

Definition at line 1986 of file cmsysini.c.

References KeNumberProcessors, KeOptimizeProcessorControlState(), KeRevertToUserAffinityThread(), KeSetSystemAffinityThread(), and PAGED_CODE.

Referenced by CmpSetVersionData().

01991 : 01992 01993 Set each processor to it's optimal settings for NT. 01994 01995 --*/ 01996 { 01997 ULONG i; 01998 01999 PAGED_CODE(); 02000 02001 // 02002 // Set each processor into its best NT configuration 02003 // 02004 02005 for (i=0; i < (ULONG)KeNumberProcessors; i++) { 02006 KeSetSystemAffinityThread((KAFFINITY) 1 << i); 02007 02008 #if i386 02009 // for now x86 only 02010 KeOptimizeProcessorControlState (); 02011 #endif 02012 } 02013 02014 // 02015 // Restore threads affinity 02016 // 02017 02018 KeRevertToUserAffinityThread(); 02019 }

NTSTATUS CmpCreateControlSet IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 2786 of file cmsysini.c.

References ASSERT, ASSERTMSG, CHAR, CM_HARDWARE_PROFILE_STR_CAPABILITIES, CM_HARDWARE_PROFILE_STR_CURRENT_DOCK_INFO, CM_HARDWARE_PROFILE_STR_DOCKID, CM_HARDWARE_PROFILE_STR_DOCKING_STATE, CM_HARDWARE_PROFILE_STR_SERIAL_NUMBER, CML_BUGCHECK, CMLOG, CmpAddAcpiAliasEntry(), CmpAddAliasEntry(), CmpAddDockingInfo(), CmpCloneHwProfile(), CmpHwprofileDefaultSelect(), CMS_INIT, CmSetAcpiHwProfile(), CmSymbolicLinkValueName, _PROFILE_ACPI_DOCKING_STATE::DockingState, extension, FALSE, HW_PROFILE_DOCKSTATE_UNDOCKED, HW_PROFILE_STATUS_ALIAS_MATCH, HW_PROFILE_STATUS_FAILURE, HW_PROFILE_STATUS_PRISTINE_MATCH, HW_PROFILE_STATUS_SUCCESS, HW_PROFILE_STATUS_TRUE_MATCH, L, NT_SUCCESS, NtClose(), NtCreateKey(), NtDeleteValueKey(), NtOpenKey(), NtQueryValueKey(), NtSetValueKey(), NTSTATUS(), NULL, PAGED_CODE, PROFILE_ACPI_DOCKING_STATE, RtlAnsiStringToUnicodeString(), RtlInitAnsiString(), RtlInitUnicodeString(), _PROFILE_ACPI_DOCKING_STATE::SerialLength, _PROFILE_ACPI_DOCKING_STATE::SerialNumber, sprintf(), Status, TRUE, and ValueBuffer.

Referenced by CmInitSystem1().

02792 : 02793 02794 This routine sets up the symbolic links from 02795 02796 \Registry\Machine\System\CurrentControlSet to 02797 \Registry\Machine\System\ControlSetNNN 02798 02799 \Registry\Machine\System\CurrentControlSet\Hardware Profiles\Current to 02800 \Registry\Machine\System\ControlSetNNN\Hardware Profiles\NNNN 02801 02802 based on the value of \Registry\Machine\System\Select:Current. and 02803 \Registry\Machine\System\ControlSetNNN\Control\IDConfigDB:CurrentConfig 02804 02805 Arguments: 02806 02807 None 02808 02809 Return Value: 02810 02811 status 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 // Check to make sure that the key was created, not just opened. Since 02894 // this key is always created volatile, it should never be present in 02895 // the hive when we boot. 02896 // 02897 ASSERT(Disposition == REG_CREATED_NEW_KEY); 02898 02899 // 02900 // Create symbolic link for current hardware profile. 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 // Determine the Current Hardware Profile Number 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 // We know now the config set that the user selected. 02963 // namely: HWProfile. 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 // We need to determine if Value was selected by exact match 03009 // (TRUE_MATCH) or because the profile selected was aliasable. 03010 // 03011 // If aliasable we need to manufacture another alias entry in the 03012 // alias table. 03013 // 03014 // If the profile information is there and not failed then we should 03015 // mark the Docking state information: 03016 // (DockID, SerialNumber, DockState, and Capabilities) 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 // If the selected profile is pristine then we need to clone. 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 // Fall through 03052 // 03053 case HW_PROFILE_STATUS_ALIAS_MATCH: 03054 // 03055 // Create the alias entry for this profile. 03056 // 03057 03058 Status = CmpAddAliasEntry (IDConfigDB, 03059 &extension->Profile, 03060 HWProfile); 03061 03062 #if 0 03063 // 03064 // If we are booting in the undocked state, and creating a brand 03065 // new alias for this undocked state, we need to create an acpi 03066 // alias as well that points to this new profile. 03067 // 03068 // BUGBUG. 03069 // We are not checking for the case where we may manufacture more 03070 // than one bios alias entry for the undocked state. 03071 // If we do create more than one, then we will of course create 03072 // more than one acpi alias entry for the undocked state. 03073 // 03074 // Therefore we are assuming that when undocked the machine always 03075 // returns the same serial number. (Not a bad assumption.) 03076 // 03077 // But we are also assuming that if we have more than one NT4 style 03078 // HW profile (which would allow the user to select such a profile 03079 // for each boot, and the user selected more than one for two 03080 // different undocked boots, then we will create two undocked acpi 03081 // aliases. (Perhaps that is what we actually want. I'm not sure, 03082 // but at least it's noted. 03083 // 03084 03085 if (HW_PROFILE_DOCKSTATE_UNDOCKED == extension->Profile.DockingState) { 03086 PROFILE_ACPI_DOCKING_STATE newDockState; 03087 // 03088 // Note the definition of PROFILE_ACPI_DOCKING_STATE has a 03089 // WCHAR array of length 1. 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); // Prevent Duplication 03104 03105 ASSERT (NT_SUCCESS (Status)); 03106 } 03107 #endif 03108 03109 // 03110 // Fall through 03111 // 03112 case HW_PROFILE_STATUS_TRUE_MATCH: 03113 // 03114 // Write DockID, SerialNumber, DockState, and Caps into the current 03115 // Hardware profile. 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 // Create the symbolic link. 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 // We are booting in the undocked state. 03219 // This is interesting because our buddies in PnP cannot tell 03220 // us when we are booting without a dock. They can only tell 03221 // us when they see a hot undock. 03222 // 03223 // Therefore in the interest of matching a boot undocked with 03224 // a hot undock, we need to simulate an acpi undock event. 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 }

BOOLEAN CmpCreateObjectTypes VOID   ) 
 

Definition at line 1074 of file cmsysini.c.

References CML_MAJOR, CMLOG, CMP_KEY_INVALID_ATTRIBUTES, CmpCloseKeyObject(), CmpDeleteKeyObject(), CmpKeyMapping, CmpKeyObjectType, CmpParseKey(), CmpQueryKeyName(), CmpSecurityMethod(), CMS_INIT_ERROR, FALSE, L, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObjectType(), PAGED_CODE, PagedPool, RtlInitUnicodeString(), Status, and TRUE.

Referenced by CmInitSystem1().

01079 : 01080 01081 Create the Key object type 01082 01083 Arguments: 01084 01085 NONE. 01086 01087 Return Value: 01088 01089 TRUE == success, FALSE == failure. 01090 01091 --*/ 01092 { 01093 NTSTATUS Status; 01094 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 01095 UNICODE_STRING TypeName; 01096 01097 // 01098 // Structure that describes the mapping of generic access rights to object 01099 // specific access rights for registry key objects. 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 // --- Create the registry key object type --- 01112 // 01113 01114 // 01115 // Initialize string descriptor. 01116 // 01117 01118 RtlInitUnicodeString(&TypeName, L"Key"); 01119 01120 // 01121 // Create key object type descriptor. 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 }

VOID CmpCreatePerfKeys VOID   ) 
 

Definition at line 4155 of file cmsysini.c.

References c, CmpCreatePredefined(), CmpRegistryPerflibString, HKEY_PERFORMANCE_NLSTEXT, HKEY_PERFORMANCE_TEXT, L, NT_SUCCESS, NtOpenKey(), NTSTATUS(), NULL, PsDefaultSystemLocaleId, RtlInitUnicodeString(), Status, String, and USHORT.

Referenced by CmpInitializeHiveList().

04161 : 04162 04163 Creates predefined keys for the performance text to support old apps on 1.0a 04164 04165 Arguments: 04166 04167 None. 04168 04169 Return Value: 04170 04171 None. 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 // Always create the predefined keys for the english language 04203 // 04204 CmpCreatePredefined(Perflib, 04205 L"009", 04206 HKEY_PERFORMANCE_TEXT); 04207 04208 // 04209 // If the default language is not english, create a predefined key for 04210 // that, too. 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 }

VOID CmpCreatePredefined IN HANDLE  Root,
IN PWSTR  KeyName,
IN HANDLE  PredefinedHandle
 

Definition at line 4234 of file cmsysini.c.

References ASSERT, _CM_PARSE_CONTEXT::Class, CmpKeyObjectType, _CM_PARSE_CONTEXT::CreateLink, _CM_PARSE_CONTEXT::CreateOptions, _CM_PARSE_CONTEXT::Disposition, FALSE, Handle, KernelMode, KeyName, Name, NT_SUCCESS, NTSTATUS(), NULL, ObjectAttributes, ObOpenObjectByName(), _CM_PARSE_CONTEXT::PredefinedHandle, REG_OPTION_PREDEF_HANDLE, RtlInitUnicodeString(), Status, and _CM_PARSE_CONTEXT::TitleIndex.

Referenced by CmpCreatePerfKeys().

04242 : 04243 04244 Creates a special key that will always return the given predefined handle 04245 instead of a real handle. 04246 04247 Arguments: 04248 04249 Root - supplies the handle the keyname is relative to 04250 04251 KeyName - supplies the name of the key. 04252 04253 PredefinedHandle - supplies the predefined handle to be returned when this 04254 key is opened. 04255 04256 Return Value: 04257 04258 None. 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 }

BOOLEAN CmpCreateRegistryRoot VOID   ) 
 

Definition at line 1165 of file cmsysini.c.

References CML_MAJOR, CMLOG, CmpCreateKeyControlBlock(), CmpCreateRootNode(), CmpHiveRootSecurityDescriptor(), CmpKeyObjectType, CmpMasterHive, CmRegistryRootName, CMS_INIT_ERROR, ENLIST_KEYBODY_IN_KEYBODY_LIST, ExFreePool(), FALSE, HCELL_INDEX, _CMHIVE::Hive, HvGetCell, kcb(), KernelMode, KEY_BODY_TYPE, L, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObject(), ObInsertObject(), ObjectAttributes, ObReferenceObjectByHandle(), PAGED_CODE, PsGetCurrentProcess, Status, TRUE, and UserMode.

Referenced by CmInitSystem1().

01170 : 01171 01172 Manually create \REGISTRY in the master hive, create a key 01173 object to refer to it, and insert the key object into 01174 the root (\) of the object space. 01175 01176 Arguments: 01177 01178 None 01179 01180 Return Value: 01181 01182 TRUE == success, FALSE == failure 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 // --- Create hive entry for \REGISTRY --- 01199 // 01200 01201 if (!CmpCreateRootNode( 01202 &(CmpMasterHive->Hive), L"REGISTRY", &RootCellIndex)) 01203 { 01204 return FALSE; 01205 } 01206 01207 // 01208 // --- Create a KEY object that refers to \REGISTRY --- 01209 // 01210 01211 01212 // 01213 // Create the object manager object 01214 // 01215 01216 // 01217 // WARNING: \\REGISTRY is not in pool, so if anybody ever tries to 01218 // free it, we are in deep trouble. On the other hand, 01219 // this implies somebody has removed \\REGISTRY from the 01220 // root, so we're in trouble anyway. 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, // Parse context 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 // Create the key control block 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 // Initialize the type specific body 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 // Put the object in the root directory 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 // We cannot make the root permanent because registry objects in 01303 // general are not allowed to be. (They're stable via virtue of being 01304 // stored in the registry, not the object manager.) But we never 01305 // ever want the root to go away. So reference it. 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 }

BOOLEAN CmpCreateRootNode IN PHHIVE  Hive,
IN PWSTR  Name,
OUT PHCELL_INDEX  RootCellIndex
 

Definition at line 1328 of file cmsysini.c.

References _HHIVE::BaseBlock, _CM_KEY_NODE::Class, _CM_KEY_NODE::ClassLength, CM_KEY_NODE_SIGNATURE, CML_MAJOR, CMLOG, CmpCopyName(), CmpHKeyNodeSize, CMS_INIT_ERROR, _CHILD_LIST::Count, FALSE, _CM_KEY_NODE::Flags, HCELL_NIL, Hive, HvAllocateCell(), HvGetCell, KeQuerySystemTime(), Key, KEY_COMP_NAME, KEY_HIVE_ENTRY, KEY_NO_DELETE, _CELL_DATA::_u::KeyNode, _CM_KEY_NODE::LastWriteTime, _CHILD_LIST::List, _CM_KEY_NODE::MaxClassLen, _CM_KEY_NODE::MaxNameLen, _CM_KEY_NODE::MaxValueDataLen, _CM_KEY_NODE::MaxValueNameLen, _CM_KEY_NODE::Name, Name, _CM_KEY_NODE::NameLength, PAGED_CODE, _CM_KEY_NODE::Parent, _HBASE_BLOCK::RootCell, RtlInitUnicodeString(), _CM_KEY_NODE::Security, _CM_KEY_NODE::Signature, Stable, _CM_KEY_NODE::SubKeyCounts, _CM_KEY_NODE::SubKeyLists, TRUE, _CELL_DATA::u, _CM_KEY_NODE::ValueList, and Volatile.

Referenced by CmpCreateRegistryRoot().

01335 : 01336 01337 Manually create the root node of a hive. 01338 01339 Arguments: 01340 01341 Hive - pointer to a Hive (Hv level) control structure 01342 01343 Name - pointer to a unicode name string 01344 01345 RootCellIndex - supplies pointer to a variable to recieve 01346 the cell index of the created node. 01347 01348 Return Value: 01349 01350 TRUE == success, FALSE == failure 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 // Allocate the node. 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 // Initialize the node 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 // CellData->u.KeyNode.TitleIndex = 0; 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 }

NTSTATUS CmpDeleteCloneTree  ) 
 

Definition at line 3747 of file cmsysini.c.

References CmRegistrySystemCloneName, NtUnloadKey(), and NULL.

Referenced by CmpSaveBootControlSet().

03750 : 03751 03752 Deletes the cloned CurrentControlSet by unloading the CLONE hive. 03753 03754 Arguments: 03755 03756 NONE. 03757 03758 Return Value: 03759 03760 NTSTATUS return from NtUnloadKey. 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 }

NTSTATUS CmpDeleteCloneTree VOID   ) 
 

VOID CmpDiskFullWarning VOID   ) 
 

Definition at line 556 of file cmworker.c.

References CmpCannotWriteConfiguration, CmpDiskFullWarningWorker(), CmpDiskFullWorkerPopupDisplayed, CmpProfileLoaded, DelayedWorkQueue, ExAllocatePool, ExInitializeWorkItem, ExQueueWorkItem(), ExReadyForErrors, NonPagedPool, NULL, and TRUE.

00561 : 00562 00563 Raises a hard error of type STATUS_DISK_FULL if wasn't already raised 00564 00565 Arguments: 00566 00567 None 00568 00569 Return Value: 00570 00571 None 00572 00573 --*/ 00574 { 00575 PWORK_QUEUE_ITEM WorkItem; 00576 00577 if( (!CmpDiskFullWorkerPopupDisplayed) && (CmpCannotWriteConfiguration) && (ExReadyForErrors) && (CmpProfileLoaded) ) { 00578 00579 // 00580 // Queue work item to display popup 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 } }

VOID CmpFreeDriverList IN PHHIVE  Hive,
IN PLIST_ENTRY  DriverList
 

Definition at line 2380 of file cmsysini.c.

References _HHIVE::Free, Hive, and PAGED_CODE.

Referenced by CmGetSystemDriverList().

02387 : 02388 02389 Walks down the driver list, freeing each node in it. 02390 02391 Note that this calls the hive's free routine pointer to free the memory. 02392 02393 Arguments: 02394 02395 Hive - Supplies a pointer to the hive control structure. 02396 02397 DriverList - Supplies a pointer to the head of the Driver List. Note 02398 that the head of the list is not actually freed, only all the 02399 entries in the list. 02400 02401 Return Value: 02402 02403 None. 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 }

NTSTATUS CmpHwprofileDefaultSelect IN PCM_HARDWARE_PROFILE_LIST  ProfileList,
OUT PULONG  ProfileIndexToUse,
IN PVOID  Context
 

Definition at line 2769 of file cmsysini.c.

Referenced by CmpCreateControlSet().

02774 { 02775 UNREFERENCED_PARAMETER (Context); 02776 02777 * ProfileIndexToUse = 0; 02778 02779 return STATUS_SUCCESS; 02780 }

NTSTATUS CmpInitHiveFromFile IN PUNICODE_STRING  FileName,
IN ULONG  HiveFlags,
OUT PCMHIVE CmHive,
IN OUT PBOOLEAN  Allocate,
IN OUT PBOOLEAN  RegistryLocked
 

Definition at line 2422 of file cmsysini.c.

References CmpInitializeHive(), CmpLockRegistryExclusive(), CmpOpenHiveFiles(), FALSE, FileName, HFILE_TYPE_LOG, HFILE_TYPE_PRIMARY, HINIT_CREATE, HINIT_FILE, L, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, Status, and TRUE.

Referenced by CmpInitializeHiveList(), and CmpWorker().

02432 : 02433 02434 This routine opens a file and log, allocates a CMHIVE, and initializes 02435 it. 02436 02437 Arguments: 02438 02439 FileName - Supplies name of file to be loaded. 02440 02441 HiveFlags - Supplies hive flags to be passed to CmpInitializeHive 02442 02443 CmHive - Returns pointer to initialized hive (if successful) 02444 02445 Allocate - IN: if TRUE ok to allocate, if FALSE hive must exist 02446 (bug .log may get created) 02447 OUT: TRUE if actually created hive, FALSE if existed before 02448 02449 Return Value: 02450 02451 NTSTATUS 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 // Registry should be locked exclusive 02501 // if not, lock it now and signal this to the caller 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 }

VOID CmpInitializeHiveList VOID   ) 
 

Definition at line 726 of file cmsysini.c.

References ASSERT, BaseName, BitMap, _HHIVE::Cluster, _HIVE_LIST_ENTRY::CmHive, CML_BUGCHECK, CML_MAJOR, CML_MINOR, CMLOG, CmpAddToHiveFileList(), CmpCannotWriteConfiguration, CmpCreatePerfKeys(), CmpDiskFullWarning(), CmpFileSetSize(), CmpHiveRootSecurityDescriptor(), CmpInitHiveFromFile(), CmpLazyFlush(), CmpLinkHiveToMaster(), CmpLinkKeyToHive(), CmpMachineHiveList, CmpNoWrite, CmpOpenHiveFiles(), CmpValidateAlternate(), CMS_INIT, CMS_INIT_ERROR, _HHIVE::DirtyCount, _HHIVE::DirtyVector, ExFreePool(), ExRaiseHardError(), FALSE, _CMHIVE::FileHandles, FileName, HBLOCK_SIZE, HFILE_TYPE_ALTERNATE, HFILE_TYPE_EXTERNAL, HFILE_TYPE_LOG, HFILE_TYPE_PRIMARY, Hive, _CMHIVE::Hive, HIVE_VOLATILE, _HHIVE::HiveFlags, HvSyncHive(), HvWriteHive(), Index, INIT_REGISTRY_MASTERPATH, INIT_SYSTEMROOT_HIVEPATH, KeBugCheckEx(), L, MAX_NAME, Name, _HIVE_LIST_ENTRY::Name, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlAppendStringToString(), RtlAreBitsClear(), RtlInitUnicodeString(), RtlNumberOfSetBits(), RtlSetBits(), Stable, Status, TRUE, and USHORT.

00731 : 00732 00733 This function is called to map hive files to hives. It both 00734 maps existing hives to files, and creates new hives from files. 00735 00736 It operates on files in "\SYSTEMROOT\CONFIG". 00737 00738 NOTE: MUST run in the context of the process that the CmpWorker 00739 thread runs in. Caller is expected to arrange this. 00740 00741 NOTE: Will bugcheck on failure. 00742 00743 Arguments: 00744 00745 Return Value: 00746 00747 NONE. 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 // Compute the name of the file, and the name to link to in 00811 // the registry. 00812 // 00813 00814 // REGISTRY 00815 00816 RegName.Length = RegStart; 00817 RtlInitUnicodeString( 00818 &TempName, 00819 CmpMachineHiveList[i].BaseName 00820 ); 00821 RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName); 00822 00823 // REGISTRY\MACHINE or REGISTRY\USER 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 // REGISTRY\[MACHINE|USER]\HIVE 00834 00835 // <sysroot>\config 00836 00837 RtlInitUnicodeString( 00838 &TempName, 00839 CmpMachineHiveList[i].Name 00840 ); 00841 FileName.Length = FileStart; 00842 RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName); 00843 00844 // <sysroot>\config\hive 00845 00846 00847 if (CmpMachineHiveList[i].CmHive == NULL) { 00848 00849 // 00850 // Hive has not been inited in any way. 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; // If we are here it isn't SYSTEM, 00875 // so punt and go on. 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 // Link hive into master hive 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 // CmHive already exists. It is not an entirely volatile 00916 // hive (we do nothing for those.) 00917 // 00918 // First, open the files (Primary and Alternate) that 00919 // back the hive. Stuff their handles into the CmHive 00920 // object. Force the size of the files to match the 00921 // in memory images. Call HvSyncHive to write changes 00922 // out to disk. 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 // WARNNOTE 00949 // We've just told the user that something essential, 00950 // like the SYSTEM hive, is hosed. Don't try to run, 00951 // we just risk destroying user data. Punt. 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 // When an in-memory hive is opened with no backing 00963 // file, ClusterSize is assumed to be 1. When the file 00964 // is opened later (for the SYSTEM hive) we need 00965 // to update this field in the hive if we are 00966 // booting from media where the cluster size > 1 00967 // 00968 if (CmHive->Hive.Cluster != ClusterSize) { 00969 // 00970 // The cluster size is different than previous assumed. 00971 // Since a cluster in the dirty vector must be either 00972 // completely dirty or completely clean, go through the 00973 // dirty vector and mark all clusters that contain a dirty 00974 // logical sector as completely dirty. 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 // Update DirtyCount and Cluster 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 // WARNNOTE 01003 // Data written into the system hive since boot 01004 // cannot be written out, punt. 01005 // 01006 CmpCannotWriteConfiguration = TRUE; 01007 01008 //KeBugCheckEx(CANNOT_WRITE_CONFIGURATION,5,4,i,0); 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 // Force all data to be written to the secondary (.alt) 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 // WARNNOTE 01028 // If we keep running here, we risk REALLY 01029 // screwing the user over (eating all their 01030 // data), while if we fail, we'll at least 01031 // fail clean. 01032 // 01033 CmpCannotWriteConfiguration = TRUE; 01034 01035 //KeBugCheckEx(CANNOT_WRITE_CONFIGURATION,5,5,0,0); 01036 } 01037 } 01038 CmpAddToHiveFileList(CmpMachineHiveList[i].CmHive); 01039 01040 HvSyncHive((PHHIVE)CmHive); 01041 01042 if( CmpCannotWriteConfiguration ) { 01043 // 01044 // The system disk is full; Give user a chance to log-on and make room 01045 // 01046 CmpDiskFullWarning(); 01047 CmpLazyFlush(); 01048 } 01049 } 01050 } 01051 } // for 01052 01053 ExFreePool(SecurityDescriptor); 01054 01055 // 01056 // Create symbolic link from SECURITY hive into SAM hive. 01057 // 01058 CmpLinkKeyToHive( 01059 L"\\Registry\\Machine\\Security\\SAM", 01060 L"\\Registry\\Machine\\SAM\\SAM" 01061 ); 01062 01063 // 01064 // Create predefined handles. 01065 // 01066 CmpCreatePerfKeys(); 01067 01068 return; 01069 }

BOOLEAN CmpInitializeSystemHive IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 2022 of file cmsysini.c.

References CmCheckRegistry(), _HIVE_LIST_ENTRY::CmHive, CML_BUGCHECK, CMLOG, CmpHiveRootSecurityDescriptor(), CmpInitializeHive(), CmpLinkHiveToMaster(), CmpLoadOptions, CmpMachineHiveList, CmpSystemFileName, CmRegistryMachineSystemName, CMS_INIT_ERROR, ExAllocatePool, ExFreePool(), FALSE, HFILE_TYPE_ALTERNATE, HINIT_CREATE, HINIT_MEMORY, KeBugCheckEx(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, RtlAnsiStringToUnicodeString(), RtlInitAnsiString(), Status, SYSTEM_HIVE_INDEX, and TRUE.

Referenced by CmInitSystem1().

02027 : 02028 02029 Initializes the SYSTEM hive based on the raw hive image passed in 02030 from the OS Loader. 02031 02032 Arguments: 02033 02034 LoaderBlock - Supplies a pointer to the Loader Block passed in by 02035 the OS Loader. 02036 02037 Return Value: 02038 02039 TRUE - it worked 02040 02041 FALSE - it failed 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 // capture tail of boot.ini line (load options, portable) 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); // odds against this are huge 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 // move the loaded registry into the real registry 02083 // 02084 HiveImageBase = LoaderBlock->RegistryBase; 02085 02086 if (HiveImageBase == NULL) { 02087 // 02088 // No memory descriptor for the hive, so we must recreate it. 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 // There is a memory image for the hive, copy it and make it active 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 // We couldn't use the SYSTEM hive passed in from the loader. 02135 // We are dead. 02136 // 02137 // 02138 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,5,7,0,0); 02139 } 02140 Allocate = FALSE; 02141 } 02142 02143 // 02144 // Create the link node 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 }

NTSTATUS CmpInterlockedFunction PWCHAR  RegistryValueKey,
VOID(*  InterlockedFunction)(VOID)
 

Definition at line 1845 of file cmsysini.c.

References Buffer, CmpControlSessionManager, CmRegistryMachineSystemCurrentControlSet, L, Name, NT_SUCCESS, NtClose(), NtFlushKey(), NtOpenKey(), NtQueryValueKey(), NtSetValueKey(), NTSTATUS(), NULL, PAGED_CODE, and RtlInitUnicodeString().

Referenced by CmpSetVersionData().

01851 : 01852 01853 This routine guards calling the InterlockedFunction in the 01854 passed RegistryValueKey. 01855 01856 The RegistryValueKey will record the status of the first 01857 call to the InterlockedFunction. If the system crashes 01858 durning this call then ValueKey will be left in a state 01859 where the InterlockedFunction will not be called on subsequent 01860 attempts. 01861 01862 Arguments: 01863 01864 RegistryValueKey - ValueKey name for Control\Session Manager 01865 InterlockedFunction - Function to call 01866 01867 Return Value: 01868 01869 STATUS_SUCCESS - The interlocked function was successfully called 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 // Open CurrentControlSet 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 // Open Control\Session Manager 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 // Read ValueKey to interlock operation with 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 // Value 0 - Before InterlockedFunction 01938 // 1 - In the middle of InterlockedFunction 01939 // 2 - After InterlockedFunction 01940 // 01941 // If the value is a 0, then we haven't tried calling this 01942 // interlocked function, set the value to a 1 and try it. 01943 // 01944 // If the value is a 1, then we crased durning an execution 01945 // of the interlocked function last time, don't try it again. 01946 // 01947 // If the value is a 2, then we called the interlocked function 01948 // before and it worked. Call it again this time. 01949 // 01950 01951 if (Value != 1) { 01952 01953 if (Value != 2) { 01954 // 01955 // This interlocked function is not known to work. Write 01956 // a 1 to this value so we can detect if we crash durning 01957 // this call. 01958 // 01959 01960 Value = 1; 01961 NtSetValueKey (hSession, &Name, 0L, REG_DWORD, &Value, sizeof (Value)); 01962 NtFlushKey (hSession); // wait until it's on the disk 01963 } 01964 01965 InterlockedFunction(); 01966 01967 if (Value != 2) { 01968 // 01969 // The worker function didn't crash - update the value for 01970 // this interlocked function to 2. 01971 // 01972 01973 Value = 2; 01974 NtSetValueKey (hSession, &Name, 0L, REG_DWORD, &Value, sizeof (Value)); 01975 } 01976 01977 } else { 01978 status = STATUS_UNSUCCESSFUL; 01979 } 01980 01981 NtClose (hSession); 01982 return status; 01983 }

BOOLEAN CmpIsLastKnownGoodBoot VOID   ) 
 

Definition at line 3863 of file cmsysini.c.

References ASSERT, CML_MAJOR, CMLOG, CMS_INIT, FALSE, L, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlQueryRegistryValues(), Status, and TRUE.

Referenced by CmBootLastKnownGood().

03869 : 03870 03871 Determines whether the current system boot is a LastKnownGood boot or 03872 not. It does this by comparing the following two values: 03873 03874 \registry\machine\system\select:Current 03875 \registry\machine\system\select:LastKnownGood 03876 03877 If both of these values refer to the same control set, and this control 03878 set is different from: 03879 03880 \registry\machine\system\select:Default 03881 03882 we are booting LastKnownGood. 03883 03884 Arguments: 03885 03886 None. 03887 03888 Return Value: 03889 03890 TRUE - Booting LastKnownGood 03891 FALSE - Not booting LastKnownGood 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 // If this failed, something is severely wrong. 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 }

NTSTATUS CmpLinkHiveToMaster PUNICODE_STRING  LinkName,
HANDLE  RootDirectory,
PCMHIVE  CmHive,
BOOLEAN  Allocate,
PSECURITY_DESCRIPTOR  SecurityDescriptor
 

Definition at line 1421 of file cmsysini.c.

References ASSERT, _HHIVE::BaseBlock, _CM_PARSE_CONTEXT::ChildHive, _CM_PARSE_CONTEXT::Class, CML_MAJOR, CMLOG, CmpKeyObjectType, CmpReportNotify(), CMS_INIT_ERROR, _CM_PARSE_CONTEXT::CreateLink, _CM_PARSE_CONTEXT::CreateOptions, HCELL_NIL, _CMHIVE::Hive, KernelMode, _CM_KEY_REFERENCE::KeyCell, _CM_KEY_REFERENCE::KeyHive, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObjectAttributes, ObOpenObjectByName(), ObReferenceObjectByHandle(), PAGED_CODE, _HBASE_BLOCK::RootCell, Status, _CM_PARSE_CONTEXT::TitleIndex, and TRUE.

01430 : 01431 01432 The existing, "free floating" hive CmHive describes is linked into 01433 the name space at the node named by LinkName. The node will be created. 01434 The hive is assumed to already have an appropriate root node. 01435 01436 Arguments: 01437 01438 LinkName - supplies a pointer to a unicode string which describes where 01439 in the registry name space the hive is to be linked. 01440 All components but the last must exist. The last must not. 01441 01442 RootDirectory - Supplies the handle the LinkName is relative to. 01443 01444 CmHive - pointer to a CMHIVE structure describing the hive to link in. 01445 01446 Allocate - TRUE indicates that the root cell is to be created 01447 FALSE indicates the root cell already exists. 01448 01449 SecurityDescriptor - supplies a pointer to the security descriptor to 01450 be placed on the hive root. 01451 01452 Return Value: 01453 01454 TRUE == success, FALSE == failure 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 // Fill in special ParseContext to indicate that we are creating 01467 // a link node and opening or creating a root node. 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 // Creating a new root node 01480 // 01481 01482 ParseContext.ChildHive.KeyCell = HCELL_NIL; 01483 } else { 01484 01485 // 01486 // Opening an existing root node 01487 // 01488 01489 ParseContext.ChildHive.KeyCell = CmHive->Hive.BaseBlock->RootCell; 01490 } 01491 01492 // 01493 // Create a path to the hive 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 // Report the notification event 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 }

BOOLEAN CmpLinkKeyToHive PWSTR  KeyPath,
PWSTR  HivePath
 

Definition at line 3983 of file cmsysini.c.

References CML_BUGCHECK, CMLOG, CMS_INIT, CmSymbolicLinkValueName, FALSE, KeyName, KeyPath, NT_SUCCESS, NtClose(), NtCreateKey(), NtSetValueKey(), NTSTATUS(), NULL, PAGED_CODE, RtlInitUnicodeString(), Status, and TRUE.

Referenced by CmInitSystem1(), and CmpInitializeHiveList().

03990 : 03991 03992 Creates a symbolic link at KeyPath that points to HivePath. 03993 03994 Arguments: 03995 03996 KeyPath - pointer to unicode string with name of key 03997 (e.g. L"\\Registry\\Machine\\Security\\SAM") 03998 03999 HivePath - pointer to unicode string with name of hive root 04000 (e.g. L"\\Registry\\Machine\\SAM\\SAM") 04001 04002 Return Value: 04003 04004 TRUE if links were successfully created, FALSE otherwise 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 // Create link for CLONE hive 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 // Check to make sure that the key was created, not just opened. Since 04045 // this key is always created volatile, it should never be present in 04046 // the hive when we boot. 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 }

NTSTATUS CmpSaveBootControlSet USHORT  ControlSetNum  ) 
 

Definition at line 3458 of file cmsysini.c.

References Buffer, CLONE_CONTROL_SET, CmpCopyTreeEx, CmpDeleteCloneTree(), CmpKeyObjectType, CmpLockRegistryExclusive(), CmpSyncTrees, CmpUnlockRegistry(), CmRegistryMachineSystemCurrentControlSet, ExAllocatePool, ExFreePool(), KernelMode, L, NT_SUCCESS, NtClose(), NtCreateKey(), NtOpenKey(), NtQuerySecurityObject(), NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PagedPool, RtlInitUnicodeString(), and Status.

Referenced by NtInitializeRegistry().

03461 : 03462 03463 This routine is responsible for saving the control set 03464 used to accomplish the latest boot into a different control 03465 set (presumably so that the different control set may be 03466 marked as the LKG control set). 03467 03468 This routine is called from NtInitializeRegistry when 03469 a boot is accepted via that routine. 03470 03471 Arguments: 03472 03473 ControlSetNum - The number of the control set that will 03474 be used to save the boot control set. 03475 03476 Return Value: 03477 03478 NTSTATUS result code from call, among the following: 03479 03480 STATUS_SUCCESS - everything worked perfectly 03481 STATUS_REGISTRY_CORRUPT - could not save the boot control set, 03482 it is likely that the copy or sync 03483 operation used for this save failed 03484 and some part of the boot control 03485 set was not saved. 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 // Figure out where the boot control set is 03501 // 03502 03503 #if CLONE_CONTROL_SET 03504 03505 // 03506 // If we have cloned the control set, then use the clone 03507 // since it is guaranteed to have an untouched copy of the 03508 // boot control set 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 // If we are not using the clone, then just use the 03523 // current control set. 03524 // 03525 03526 InitializeObjectAttributes(&Attributes, 03527 &CmRegistryMachineSystemCurrentControlSet, 03528 OBJ_CASE_INSENSITIVE, 03529 NULL, 03530 NULL); 03531 #endif 03532 03533 // 03534 // Open the boot control set 03535 // 03536 03537 Status = NtOpenKey(&BootHandle, 03538 KEY_READ, 03539 &Attributes); 03540 03541 03542 if (!NT_SUCCESS(Status)) return(Status); 03543 03544 // 03545 // We may be saving the boot control set into a brand new 03546 // tree that we will create. If this is true, then we will 03547 // need to create the root node of this tree below 03548 // and give it the right security descriptor. So, we fish 03549 // the security descriptor out of the root node of the 03550 // boot control set tree. 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 // Now, create the path of the control set we will be saving to 03585 // 03586 03587 swprintf(Buffer, L"\\Registry\\Machine\\System\\ControlSet%03d", ControlSetNum); 03588 03589 RtlInitUnicodeString(&SavedBoot, 03590 Buffer); 03591 03592 // 03593 // Open/Create the control set to which we are saving 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 // Get the key objects for out two controls 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 // Lock the registry and do the actual saving 03646 // 03647 03648 CmpLockRegistryExclusive(); 03649 03650 if (Disposition == REG_CREATED_NEW_KEY) { 03651 03652 // 03653 // If we are saving to a control set that we have just 03654 // created, it is most efficient to just copy 03655 // the boot control set tree into the new control set. 03656 // 03657 03658 // 03659 // N.B. We copy the volatile keys only if we are using 03660 // a clone and thus our boot control set tree is 03661 // composed only of volatile keys. 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 // Set the max subkey name property for the new target key. 03672 // 03673 SavedBootKey->KeyControlBlock->KeyNode->MaxNameLen = BootKey->KeyControlBlock->KeyNode->MaxNameLen; 03674 } else { 03675 03676 // 03677 // If we are saving to a control set that already exists 03678 // then its likely that this control set is nearly identical 03679 // to the boot control set (control sets don't change much 03680 // between boots). 03681 // 03682 // Furthermore, the control set we are saving to must be old 03683 // and hence has not been modified at all since it ceased 03684 // being a current control set. 03685 // 03686 // Thus, it is most efficient for us to simply synchronize 03687 // the target control set with the boot control set. 03688 // 03689 03690 // 03691 // N.B. We sync the volatile keys only if we are using 03692 // a clone for the same reasons as stated above. 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 // Check if the Copy/Sync succeeded and adjust our return code 03704 // accordingly. 03705 // 03706 03707 if (CopyRet) { 03708 Status = STATUS_SUCCESS; 03709 } else { 03710 Status = STATUS_REGISTRY_CORRUPT; 03711 } 03712 03713 // 03714 // All done. Clean up. 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 // If we have been using a clone, then the clone is no longer 03731 // needed since we have saved its contents into a non-volatile 03732 // control set. Thus, we can just erase it. 03733 // 03734 03735 if(NT_SUCCESS(Status)) 03736 { 03737 CmpDeleteCloneTree(); 03738 } 03739 03740 #endif 03741 03742 return(Status); 03743 03744 }

VOID CmpSetVersionData VOID   ) 
 

Definition at line 1545 of file cmsysini.c.

References CmCSDVersionString, CmpConfigureProcessors(), CmpHiveRootSecurityDescriptor(), CmpInterlockedFunction(), CmpProcessorControl, CmVersionString, DbgPrint, ExFreePool(), FALSE, L, NT_SUCCESS, NtBuildNumber, NtClose(), NtCreateKey(), NtDeleteValueKey(), NtSetValueKey(), NTSTATUS(), NtSystemRoot, NULL, nullclass, ObjectAttributes, PAGED_CODE, RtlAnsiStringToUnicodeString(), RtlFreeStringRoutine, RtlInitAnsiString(), RtlInitUnicodeString(), sprintf(), and ValueBuffer.

Referenced by NtInitializeRegistry().

01550 : 01551 01552 Create \REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion: 01553 CurrentVersion = VER_PRODUCTVERSION_STR // From ntverp.h 01554 CurrentBuildNumber = VER_PRODUCTBUILD // From ntverp.h 01555 CurrentType = "[Multiprocessor|Uniprocessor] // From NT_UP 01556 [Retail|Free|Checked]" // From DBG, DEVL 01557 SystemRoot = "[c:\nt]" 01558 01559 01560 NOTE: It is not worth bugchecking over this, so if it doesn't 01561 work, just fail. 01562 01563 Arguments: 01564 01565 Return Value: 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 // Get default security descriptor for the nodes we will create. 01584 // 01585 SecurityDescriptor = CmpHiveRootSecurityDescriptor(); 01586 01587 // 01588 // Create the key 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 // Set the value entries for the key 01680 // 01681 RtlInitUnicodeString( 01682 &NameString, 01683 L"CurrentVersion" 01684 ); 01685 01686 status = NtSetValueKey( 01687 key1, 01688 &NameString, 01689 0, // TitleIndex 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, // TitleIndex 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, // TitleIndex 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, // TitleIndex 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 // Set each processor to it's optimal configuration. 01834 // 01835 // Note: this call is performed interlocked such that the user 01836 // can disable this automatic configuration update. 01837 // 01838 01839 CmpInterlockedFunction(CmpProcessorControl, CmpConfigureProcessors); 01840 01841 return; 01842 }

BOOLEAN CmpValidateAlternate IN HANDLE  FileHandle,
IN PCMHIVE  PrimaryHive
 

Definition at line 4077 of file cmsysini.c.

References ASSERT, _HHIVE::BaseBlock, CML_BUGCHECK, CMLOG, CmpFree(), CmpInitializeHive(), CmpSystemFileName, CMS_INIT, ExFreePool(), FALSE, HFILE_TYPE_PRIMARY, HINIT_FILE, _CMHIVE::Hive, _CMHIVE::HiveList, _CMHIVE::HiveLock, HvFreeHive(), NT_SUCCESS, NTSTATUS(), NULL, Status, _HBASE_BLOCK::TimeStamp, and TRUE.

Referenced by CmpInitializeHiveList().

04084 : 04085 04086 Loads an alternate hive (SYSTEM.ALT) and verifies that it is a 04087 valid hive file. 04088 04089 Arguments: 04090 04091 FileHandle - Supplies a handle to the hive file. 04092 04093 PrimaryHive - Supplies the CMHIVE structure of the primary hive. 04094 04095 Return Value: 04096 04097 TRUE - Hive is valid. 04098 04099 FALSE - Hive is corrupt or in transition. 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 // non system ALT will screw up 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 // Compare the timestamps in the baseblock. These must always be 04128 // equal to ensure that SYSTEM and SYSTEM.ALT are really the same 04129 // hive. 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 // Hive is valid, free up everything we allocated. 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 }

VOID CmShutdownSystem VOID   ) 
 

Definition at line 3944 of file cmsysini.c.

References CmpLockRegistryExclusive(), CmpUnlockRegistry(), CmpWorker(), _REGISTRY_COMMAND::Command, CommandArea, HvShutdownComplete, PAGED_CODE, REG_CMD_SHUTDOWN, and TRUE.

03949 : 03950 03951 Shuts down the registry. 03952 03953 Call to CmpWorkerThread, which will call back 03954 to CmpDoFlushAll(); 03955 03956 Arguments: 03957 03958 NONE 03959 03960 Return Value: 03961 03962 NONE 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; // Tell HvSyncHive to ignore all 03975 // further requests 03976 03977 CmpUnlockRegistry(); 03978 return; 03979 }


Variable Documentation

BOOLEAN CmFirstTime
 

Definition at line 55 of file cmsysini.c.

BOOLEAN CmpCannotWriteConfiguration
 

Definition at line 145 of file cmsysini.c.

PWCHAR CmpControlSessionManager
 

Definition at line 78 of file cmsysini.c.

Referenced by CmpInterlockedFunction().

LIST_ENTRY CmpHiveListHead
 

Definition at line 102 of file cmsysini.c.

FAST_MUTEX CmpKcbLock
 

Definition at line 52 of file cmsysini.c.

POBJECT_TYPE CmpKeyObjectType
 

Definition at line 109 of file cmsysini.c.

UNICODE_STRING CmpLoadOptions
 

Definition at line 76 of file cmsysini.c.

Referenced by CmInitSystem1(), and CmpInitializeSystemHive().

HIVE_LIST_ENTRY CmpMachineHiveList[]
 

Definition at line 61 of file cmsysini.c.

Referenced by CmInitSystem1(), CmpInitializeHiveList(), and CmpInitializeSystemHive().

PCMHIVE CmpMasterHive
 

Definition at line 96 of file cmsysini.c.

BOOLEAN CmpNoMasterCreates
 

Definition at line 97 of file cmsysini.c.

Referenced by CmInitSystem1(), and CmpParseKey().

BOOLEAN CmpNoWrite
 

Definition at line 131 of file cmsysini.c.

FAST_MUTEX CmpPostLock
 

Definition at line 53 of file cmsysini.c.

PWCHAR CmpProcessorControl
 

Definition at line 77 of file cmsysini.c.

Referenced by CmpSetVersionData().

ERESOURCE CmpRegistryLock
 

Definition at line 51 of file cmsysini.c.

PUCHAR CmpStashBuffer
 

Definition at line 138 of file cmsysini.c.

ULONG CmpStashBufferSize
 

Definition at line 139 of file cmsysini.c.

UNICODE_STRING CmpSystemFileName
 

Definition at line 74 of file cmsysini.c.

Referenced by CmpInitializeRegistryNames(), CmpInitializeSystemHive(), and CmpValidateAlternate().

PKPROCESS CmpSystemProcess
 

Definition at line 50 of file cmsysini.c.

Referenced by CmInitSystem1().

UNICODE_STRING CmSymbolicLinkValueName
 

Definition at line 75 of file cmsysini.c.

BOOLEAN HvShutdownComplete
 

Definition at line 133 of file cmsysini.c.

UNICODE_STRING nullclass
 

Definition at line 150 of file cmsysini.c.

Referenced by CmInitSystem1(), and CmpSetVersionData().


Generated on Sat May 15 19:43:11 2004 for test by doxygen 1.3.7