ReactOS 0.4.16-dev-2613-g9533ad7
cmsysini.c File Reference
#include "ntoskrnl.h"
#include "debug.h"
Include dependency graph for cmsysini.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI CmpLinkKeyToHive (_In_z_ PCWSTR LinkKeyName, _In_z_ PCWSTR TargetKeyName)
 
VOID NTAPI CmpDeleteKeyObject (PVOID DeletedObject)
 
VOID NTAPI CmpCloseKeyObject (IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
 
NTSTATUS NTAPI CmpQueryKeyName (IN PVOID ObjectBody, IN BOOLEAN HasName, IN OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength, IN KPROCESSOR_MODE PreviousMode)
 
NTSTATUS NTAPI CmpInitHiveFromFile (IN PCUNICODE_STRING HiveName, IN ULONG HiveFlags, OUT PCMHIVE *Hive, IN OUT PBOOLEAN New, IN ULONG CheckFlags)
 
NTSTATUS NTAPI CmpSetSystemValues (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
static NTSTATUS CmpCreateHardwareProfile (HANDLE ControlSetHandle)
 
NTSTATUS NTAPI CmpCreateControlSet (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI CmpLinkHiveToMaster (IN PUNICODE_STRING LinkName, IN HANDLE RootDirectory, IN PCMHIVE RegistryHive, IN BOOLEAN Allocate, IN PSECURITY_DESCRIPTOR SecurityDescriptor)
 
BOOLEAN NTAPI CmpInitializeSystemHive (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI CmpCreateObjectTypes (VOID)
 
BOOLEAN NTAPI CmpCreateRootNode (IN PHHIVE Hive, IN PCWSTR Name, OUT PHCELL_INDEX Index)
 
BOOLEAN NTAPI CmpCreateRegistryRoot (VOID)
 
static PCWSTR CmpGetRegistryPath (VOID)
 
static VOID CmpHasAlternateHiveDiverged (_In_ PCUNICODE_STRING FileName, _In_ PCMHIVE CmMainmHive, _In_ HANDLE AlternateHandle, _Out_ PBOOLEAN Diverged)
 Checks if the primary and alternate backing hive are the same, by determining the time stamp of both hives.
 
 _Function_class_ (KSTART_ROUTINE)
 
VOID NTAPI CmpInitializeHiveList (VOID)
 
BOOLEAN NTAPI CmInitSystem1 (VOID)
 
PUNICODE_STRING *NTAPI CmGetSystemDriverList (VOID)
 
VOID NTAPI CmpLockRegistryExclusive (VOID)
 
VOID NTAPI CmpLockRegistry (VOID)
 
BOOLEAN NTAPI CmpTestRegistryLock (VOID)
 
BOOLEAN NTAPI CmpTestRegistryLockExclusive (VOID)
 
VOID NTAPI CmpLockHiveFlusherExclusive (IN PCMHIVE Hive)
 
VOID NTAPI CmpLockHiveFlusherShared (IN PCMHIVE Hive)
 
VOID NTAPI CmpUnlockHiveFlusher (IN PCMHIVE Hive)
 
BOOLEAN NTAPI CmpTestHiveFlusherLockShared (IN PCMHIVE Hive)
 
BOOLEAN NTAPI CmpTestHiveFlusherLockExclusive (IN PCMHIVE Hive)
 
VOID NTAPI CmpUnlockRegistry (VOID)
 
VOID NTAPI CmpAcquireTwoKcbLocksExclusiveByKey (IN ULONG ConvKey1, IN ULONG ConvKey2)
 
VOID NTAPI CmpReleaseTwoKcbLockByKey (IN ULONG ConvKey1, IN ULONG ConvKey2)
 
VOID NTAPI CmShutdownSystem (VOID)
 
VOID NTAPI CmpSetVersionData (VOID)
 

Variables

POBJECT_TYPE CmpKeyObjectType
 
PCMHIVE CmiVolatileHive
 
LIST_ENTRY CmpHiveListHead
 
ERESOURCE CmpRegistryLock
 
KGUARDED_MUTEX CmpSelfHealQueueLock
 
LIST_ENTRY CmpSelfHealQueueListHead
 
KEVENT CmpLoadWorkerEvent
 
LONG CmpLoadWorkerIncrement
 
PEPROCESS CmpSystemProcess
 
PVOID CmpRegistryLockCallerCaller
 
PVOID CmpRegistryLockCaller
 
BOOLEAN CmpFlushOnLockRelease
 
BOOLEAN CmpSpecialBootCondition
 
BOOLEAN CmpNoWrite = TRUE
 
BOOLEAN CmpWasSetupBoot
 
BOOLEAN CmpProfileLoaded
 
BOOLEAN CmpNoVolatileCreates
 
ULONG CmpTraceLevel = 0
 
BOOLEAN HvShutdownComplete = FALSE
 
LONG CmpFlushStarveWriters
 
BOOLEAN CmFirstTime
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file cmsysini.c.

Function Documentation

◆ _Function_class_()

_Function_class_ ( KSTART_ROUTINE  )

Definition at line 1282 of file cmsysini.c.

1286{
1287 WCHAR FileBuffer[64], RegBuffer[64];
1288 PCWSTR ConfigPath;
1289 UNICODE_STRING TempName, FileName, RegName;
1290 ULONG i, ErrorResponse, WorkerCount, Length;
1291 USHORT FileStart;
1292 ULONG PrimaryDisposition, SecondaryDisposition, ClusterSize;
1293 PCMHIVE CmHive;
1294 HANDLE PrimaryHandle = NULL, AlternateHandle = NULL;
1296 PVOID ErrorParameters;
1297 BOOLEAN HasDiverged;
1298 PAGED_CODE();
1299
1300 /* Get the hive index, make sure it makes sense */
1301 i = PtrToUlong(StartContext);
1303
1304 /* We were started */
1306
1307 /* Build the file name and registry name strings */
1308 RtlInitEmptyUnicodeString(&FileName, FileBuffer, sizeof(FileBuffer));
1309 RtlInitEmptyUnicodeString(&RegName, RegBuffer, sizeof(RegBuffer));
1310
1311 /* Now build the system root path */
1312 ConfigPath = CmpGetRegistryPath();
1313 RtlInitUnicodeString(&TempName, ConfigPath);
1315 FileStart = FileName.Length;
1316
1317 /* And build the registry root path */
1318 RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
1319 RtlAppendUnicodeStringToString(&RegName, &TempName);
1320
1321 /* Build the base name */
1322 RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
1323 RtlAppendUnicodeStringToString(&RegName, &TempName);
1324
1325 /* Check if this is a child of the root */
1326 if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
1327 {
1328 /* Then setup the whole name */
1330 RtlAppendUnicodeStringToString(&RegName, &TempName);
1331 }
1332
1333 /* Now add the rest of the file name */
1335 FileName.Length = FileStart;
1337 if (!CmpMachineHiveList[i].CmHive)
1338 {
1339 /* We need to allocate a new hive structure */
1341
1342 /* Load the hive file */
1344 CmpMachineHiveList[i].HHiveFlags,
1345 &CmHive,
1348 if (!NT_SUCCESS(Status) ||
1349 (!CmpShareSystemHives && !CmHive->FileHandles[HFILE_TYPE_LOG]))
1350 {
1351 /*
1352 * We failed, or could not get a log file (unless
1353 * the hive is shared), raise a hard error.
1354 */
1355 ErrorParameters = &FileName;
1357 1,
1358 1,
1359 (PULONG_PTR)&ErrorParameters,
1360 OptionOk,
1361 &ErrorResponse);
1362 }
1363
1364 /* Set the hive flags and newly allocated hive pointer */
1365 CmHive->Flags = CmpMachineHiveList[i].CmHiveFlags;
1366 CmpMachineHiveList[i].CmHive2 = CmHive;
1367 }
1368 else
1369 {
1370 /* We already have a hive, is it volatile? */
1371 CmHive = CmpMachineHiveList[i].CmHive;
1372 if (!(CmHive->Hive.HiveFlags & HIVE_VOLATILE))
1373 {
1374 /* It's now, open the hive file and log */
1376 L".ALT",
1377 &PrimaryHandle,
1378 &AlternateHandle,
1379 &PrimaryDisposition,
1380 &SecondaryDisposition,
1381 TRUE,
1382 TRUE,
1383 FALSE,
1384 &ClusterSize);
1385 if (!NT_SUCCESS(Status) || !AlternateHandle)
1386 {
1387 /* Couldn't open the hive or its alternate file, raise a hard error */
1388 ErrorParameters = &FileName;
1390 1,
1391 1,
1392 (PULONG_PTR)&ErrorParameters,
1393 OptionOk,
1394 &ErrorResponse);
1395
1396 /* And bugcheck for posterity's sake */
1397 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 9, 0, i, Status);
1398 }
1399
1400 /* Save the file handles. This should remove our sync hacks */
1401 /*
1402 * FIXME: Any hive that relies on the alternate hive for recovery purposes
1403 * will only get an alternate hive. As a result, the LOG file would never
1404 * get synced each time a write is done to the hive. In the future it would
1405 * be best to adapt the code so that a primary hive can use a LOG and ALT
1406 * hives at the same time.
1407 */
1408 CmHive->FileHandles[HFILE_TYPE_ALTERNATE] = AlternateHandle;
1409 CmHive->FileHandles[HFILE_TYPE_PRIMARY] = PrimaryHandle;
1410
1411 /* Allow lazy flushing since the handles are there -- remove sync hacks */
1412 //ASSERT(CmHive->Hive.HiveFlags & HIVE_NOLAZYFLUSH);
1413 CmHive->Hive.HiveFlags &= ~HIVE_NOLAZYFLUSH;
1414
1415 /* Get the real size of the hive */
1416 Length = CmHive->Hive.Storage[Stable].Length + HBLOCK_SIZE;
1417
1418 /* Check if the cluster size doesn't match */
1419 if (CmHive->Hive.Cluster != ClusterSize)
1420 {
1421 DPRINT1("FIXME: Support for CmHive->Hive.Cluster (%lu) != ClusterSize (%lu) is unimplemented!\n",
1422 CmHive->Hive.Cluster, ClusterSize);
1423 }
1424
1425 /* Set the file size */
1426 DPRINT("FIXME: Should set file size: %lu\n", Length);
1427 //if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length))
1428 //{
1429 /* This shouldn't fail */
1430 //ASSERT(FALSE);
1431 //}
1432
1433 /* FreeLdr has recovered the hive with a log, we must do a flush */
1434 if (CmHive->Hive.BaseBlock->BootRecover == HBOOT_BOOT_RECOVERED_BY_HIVE_LOG)
1435 {
1436 DPRINT1("FreeLdr recovered the hive (hive 0x%p)\n", CmHive);
1437 RtlSetAllBits(&CmHive->Hive.DirtyVector);
1438 CmHive->Hive.DirtyCount = CmHive->Hive.DirtyVector.SizeOfBitMap;
1439 HvSyncHive((PHHIVE)CmHive);
1440 }
1441 else
1442 {
1443 /*
1444 * Check whether the both primary and alternate hives are the same,
1445 * or that the primary or alternate were created for the first time.
1446 * Do a write against the alternate hive in these cases.
1447 */
1449 CmHive,
1450 AlternateHandle,
1451 &HasDiverged);
1452 if (HasDiverged ||
1453 PrimaryDisposition == FILE_CREATED ||
1454 SecondaryDisposition == FILE_CREATED)
1455 {
1456 if (!HvWriteAlternateHive((PHHIVE)CmHive))
1457 {
1458 DPRINT1("Failed to write to alternate hive\n");
1459 goto Exit;
1460 }
1461 }
1462 }
1463
1464 /* Finally, set our allocated hive to the same hive we've had */
1465 CmpMachineHiveList[i].CmHive2 = CmHive;
1466 ASSERT(CmpMachineHiveList[i].CmHive == CmpMachineHiveList[i].CmHive2);
1467 }
1468 }
1469
1470Exit:
1471 /* We're done */
1473
1474 /* Check if we're the last worker */
1476 if (WorkerCount == CM_NUMBER_OF_MACHINE_HIVES)
1477 {
1478 /* Signal the event */
1480 }
1481
1482 /* Kill the thread */
1484}
#define PAGED_CODE()
unsigned char BOOLEAN
Definition: actypes.h:127
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
DWORD ClusterSize
Definition: format.c:66
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
#define CM_NUMBER_OF_MACHINE_HIVES
Definition: cm.h:118
HIVE_LIST_ENTRY CmpMachineHiveList[]
Definition: cmdata.c:41
BOOLEAN CmpShareSystemHives
Definition: cmdata.c:60
#define CM_CHECK_REGISTRY_PURGE_VOLATILES
Definition: cmlib.h:229
BOOLEAN CMAPI HvSyncHive(PHHIVE RegistryHive)
BOOLEAN CMAPI HvWriteAlternateHive(_In_ PHHIVE RegistryHive)
Writes data to an alternate registry hive. An alternate hive is usually backed up by a primary hive....
Definition: hivewrt.c:634
KEVENT CmpLoadWorkerEvent
Definition: cmsysini.c:21
static VOID CmpHasAlternateHiveDiverged(_In_ PCUNICODE_STRING FileName, _In_ PCMHIVE CmMainmHive, _In_ HANDLE AlternateHandle, _Out_ PBOOLEAN Diverged)
Checks if the primary and alternate backing hive are the same, by determining the time stamp of both ...
Definition: cmsysini.c:1234
static PCWSTR CmpGetRegistryPath(VOID)
Definition: cmsysini.c:1193
NTSTATUS NTAPI CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName, IN ULONG HiveFlags, OUT PCMHIVE *Hive, IN OUT PBOOLEAN New, IN ULONG CheckFlags)
Definition: cmsysini.c:289
LONG CmpLoadWorkerIncrement
Definition: cmsysini.c:22
#define RtlSetAllBits
Definition: dbgbitmap.h:346
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define L(x)
Definition: resources.c:13
#define PtrToUlong(u)
Definition: config.h:107
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
struct _FileName FileName
Definition: fatprocs.h:897
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
Definition: harderr.c:551
@ Stable
Definition: hivedata.h:127
#define HBLOCK_SIZE
Definition: hivedata.h:42
#define HFILE_TYPE_ALTERNATE
Definition: hivedata.h:36
#define HFILE_TYPE_LOG
Definition: hivedata.h:34
#define HIVE_VOLATILE
Definition: hivedata.h:23
#define HFILE_TYPE_PRIMARY
Definition: hivedata.h:33
#define HBOOT_BOOT_RECOVERED_BY_HIVE_LOG
Definition: hivedata.h:95
#define ASSERT(a)
Definition: mode.c:44
@ OptionOk
Definition: extypes.h:187
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_CREATED
Definition: nt_native.h:770
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS NTAPI CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName, IN PCWSTR Extension OPTIONAL, OUT PHANDLE Primary, OUT PHANDLE Log, OUT PULONG PrimaryDisposition, OUT PULONG LogDisposition, IN BOOLEAN CreateAllowed, IN BOOLEAN MarkAsSystemHive, IN BOOLEAN NoBuffering, OUT PULONG ClusterSize OPTIONAL)
Definition: cminit.c:273
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1153
#define STATUS_CANNOT_LOAD_REGISTRY_FILE
Definition: ntstatus.h:790
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
static void Exit(void)
Definition: sock.c:1330
Definition: cmlib.h:316
BOOLEAN ThreadStarted
Definition: cm.h:419
PCMHIVE CmHive
Definition: cm.h:414
PCMHIVE CmHive2
Definition: cm.h:417
BOOLEAN Allocate
Definition: cm.h:420
BOOLEAN ThreadFinished
Definition: cm.h:418
ULONG CmHiveFlags
Definition: cm.h:416
uint32_t * PULONG_PTR
Definition: typedefs.h:65
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint32_t ULONG
Definition: typedefs.h:59
_In_opt_ PALLOCATE_FUNCTION Allocate
Definition: exfuncs.h:814

◆ CmGetSystemDriverList()

PUNICODE_STRING *NTAPI CmGetSystemDriverList ( VOID  )

Definition at line 1864 of file cmsysini.c.

1865{
1866 LIST_ENTRY DriverList;
1869 PCM_KEY_BODY KeyBody;
1870 PHHIVE Hive;
1871 HCELL_INDEX RootCell, ControlCell;
1874 PLIST_ENTRY NextEntry;
1875 ULONG i;
1877 BOOLEAN Success, AutoSelect;
1879 PAGED_CODE();
1880
1881 /* Initialize the driver list */
1882 InitializeListHead(&DriverList);
1883
1884 /* Open the system hive key */
1885 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System");
1887 &KeyName,
1889 NULL,
1890 NULL);
1892 if (!NT_SUCCESS(Status)) return NULL;
1893
1894 /* Reference the key object to get the root hive/cell to access directly */
1898 KernelMode,
1899 (PVOID*)&KeyBody,
1900 NULL);
1901 if (!NT_SUCCESS(Status))
1902 {
1903 /* Fail */
1905 return NULL;
1906 }
1907
1908 /* Do all this under the registry lock */
1910
1911 /* Get the hive and key cell */
1912 Hive = KeyBody->KeyControlBlock->KeyHive;
1913 RootCell = KeyBody->KeyControlBlock->KeyCell;
1914
1915 /* Open the current control set key */
1916 RtlInitUnicodeString(&KeyName, L"Current");
1917 ControlCell = CmpFindControlSet(Hive, RootCell, &KeyName, &AutoSelect);
1918 if (ControlCell == HCELL_NIL) goto EndPath;
1919
1920 /* Find all system drivers */
1921 Success = CmpFindDrivers(Hive, ControlCell, SystemLoad, NULL, &DriverList);
1922 if (!Success) goto EndPath;
1923
1924 /* Sort by group/tag */
1925 if (!CmpSortDriverList(Hive, ControlCell, &DriverList)) goto EndPath;
1926
1927 /* Remove circular dependencies (cycles) and sort */
1928 if (!CmpResolveDriverDependencies(&DriverList)) goto EndPath;
1929
1930 /* Loop the list to count drivers */
1931 for (i = 0, NextEntry = DriverList.Flink;
1932 NextEntry != &DriverList;
1933 i++, NextEntry = NextEntry->Flink);
1934
1935 /* Allocate the array */
1937 if (!ServicePath) KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1938
1939 /* Loop the driver list */
1940 for (i = 0, NextEntry = DriverList.Flink;
1941 NextEntry != &DriverList;
1942 i++, NextEntry = NextEntry->Flink)
1943 {
1944 /* Get the entry */
1946
1947 /* Allocate the path for the caller */
1949 if (!ServicePath[i])
1950 {
1951 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1952 }
1953
1954 /* Duplicate the registry path */
1956 &DriverEntry->RegistryPath,
1957 ServicePath[i]);
1958 if (!NT_SUCCESS(Status))
1959 {
1960 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1961 }
1962 }
1963
1964 /* Terminate the list */
1965 ServicePath[i] = NULL;
1966
1967EndPath:
1968 /* Free the driver list if we had one */
1969 if (!IsListEmpty(&DriverList)) CmpFreeDriverList(Hive, &DriverList);
1970
1971 /* Unlock the registry */
1973
1974 /* Close the key handle and dereference the object, then return the path */
1975 ObDereferenceObject(KeyBody);
1977 return ServicePath;
1978}
BOOLEAN NTAPI CmpFindDrivers(_In_ PHHIVE Hive, _In_ HCELL_INDEX ControlSet, _In_ SERVICE_LOAD_TYPE LoadType, _In_opt_ PCWSTR BootFileSystem, _Inout_ PLIST_ENTRY DriverListHead)
Enumerates all drivers within the given control set and load type, present in the "Services" sub-key,...
Definition: cmboot.c:679
BOOLEAN NTAPI CmpResolveDriverDependencies(_Inout_ PLIST_ENTRY DriverListHead)
Removes potential circular dependencies (cycles) and sorts the driver list.
Definition: cmboot.c:1030
HCELL_INDEX NTAPI CmpFindControlSet(_In_ PHHIVE SystemHive, _In_ HCELL_INDEX RootCell, _In_ PCUNICODE_STRING SelectKeyName, _Out_ PBOOLEAN AutoSelect)
Finds the corresponding "HKLM\SYSTEM\ControlSetXXX" system control set registry key,...
Definition: cmboot.c:84
BOOLEAN NTAPI CmpSortDriverList(_In_ PHHIVE Hive, _In_ HCELL_INDEX ControlSet, _Inout_ PLIST_ENTRY DriverListHead)
Sorts the driver list, according to the drivers' group load ordering.
Definition: cmboot.c:902
VOID NTAPI CmpFreeDriverList(_In_ PHHIVE Hive, _Inout_ PLIST_ENTRY DriverListHead)
Empties the driver list and frees all allocated driver nodes in it.
Definition: cmboot.c:1224
VOID NTAPI CmpLockRegistryExclusive(VOID)
Definition: cmsysini.c:1982
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:2081
POBJECT_TYPE CmpKeyObjectType
Definition: cmsysini.c:15
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ Success
Definition: eventcreate.c:712
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
#define HCELL_NIL
Definition: hivedata.h:110
ULONG HCELL_INDEX
Definition: hivedata.h:105
_In_ PCUNICODE_STRING ServicePath
Definition: library.c:55
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define KernelMode
Definition: asm.h:38
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define KEY_READ
Definition: nt_native.h:1026
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Definition: arc.h:334
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:237
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
static int Link(const char **args)
Definition: vfdcmd.c:2414
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
BOOL WINAPI EndPath(_In_ HDC)
@ SystemLoad
Definition: cmtypes.h:997
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by IopInitializeSystemDrivers().

◆ CmInitSystem1()

BOOLEAN NTAPI CmInitSystem1 ( VOID  )

Definition at line 1642 of file cmsysini.c.

1643{
1648 PCMHIVE HardwareHive;
1650 PAGED_CODE();
1651
1652 /* Check if this is PE-boot */
1653 if (InitIsWinPEMode)
1654 {
1655 /* Set the registry in PE mode and load the system hives in shared mode */
1658 }
1659 /* If we are in volatile boot mode, ALL hives without exception
1660 * (system hives and others) will be loaded in shared mode */
1661 if (CmpVolatileBoot)
1663
1664 /* Initialize the hive list and lock */
1668
1669 /* Initialize registry lock */
1671
1672 /* Initialize the cache */
1674
1675 /* Initialize allocation and delayed dereferencing */
1679
1680 /* Initialize callbacks */
1682
1683 /* Initialize self healing */
1686
1687 /* Save the current process and lock the registry */
1689
1690 /* Create the key object types */
1692 if (!NT_SUCCESS(Status))
1693 {
1694 /* Bugcheck */
1695 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 1, Status, 0);
1696 }
1697
1698 /* Build the master hive */
1703 NULL,
1704 NULL,
1705 NULL,
1706 NULL,
1707 NULL,
1708 NULL,
1710 if (!NT_SUCCESS(Status))
1711 {
1712 /* Bugcheck */
1713 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 2, Status, 0);
1714 }
1715
1716 /* Create the \REGISTRY key node */
1717 if (!CmpCreateRegistryRoot())
1718 {
1719 /* Bugcheck */
1720 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 3, 0, 0);
1721 }
1722
1723 /* Create the default security descriptor */
1725
1726 /* Create '\Registry\Machine' key */
1727 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE");
1729 &KeyName,
1731 NULL,
1736 0,
1737 NULL,
1738 0,
1739 NULL);
1740 if (!NT_SUCCESS(Status))
1741 {
1742 /* Bugcheck */
1743 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 5, Status, 0);
1744 }
1745
1746 /* Close the handle */
1748
1749 /* Create '\Registry\User' key */
1750 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\USER");
1752 &KeyName,
1754 NULL,
1759 0,
1760 NULL,
1761 0,
1762 NULL);
1763 if (!NT_SUCCESS(Status))
1764 {
1765 /* Bugcheck */
1766 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 6, Status, 0);
1767 }
1768
1769 /* Close the handle */
1771
1772 /* After this point, do not allow creating keys in the master hive */
1774
1775 /* Initialize the system hive */
1777 {
1778 /* Bugcheck */
1779 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 7, 0, 0);
1780 }
1781
1782 /* Create the 'CurrentControlSet' link */
1784 if (!NT_SUCCESS(Status))
1785 {
1786 /* Bugcheck */
1787 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 8, Status, 0);
1788 }
1789
1790 /* Create the hardware hive */
1791 Status = CmpInitializeHive(&HardwareHive,
1795 NULL,
1796 NULL,
1797 NULL,
1798 NULL,
1799 NULL,
1800 NULL,
1802 if (!NT_SUCCESS(Status))
1803 {
1804 /* Bugcheck */
1805 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 11, Status, 0);
1806 }
1807
1808 /* Add the hive to the hive list */
1809 CmpMachineHiveList[0].CmHive = HardwareHive;
1810
1811 /* Attach it to the machine key */
1812 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE");
1814 NULL,
1815 HardwareHive,
1816 TRUE,
1818 if (!NT_SUCCESS(Status))
1819 {
1820 /* Bugcheck */
1821 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0);
1822 }
1823
1824 /* Add to HiveList key */
1825 CmpAddToHiveFileList(HardwareHive);
1826
1827 /* Free the security descriptor */
1829
1830 /* Fill out the Hardware key with the ARC Data from the Loader */
1832 if (!NT_SUCCESS(Status))
1833 {
1834 /* Bugcheck */
1835 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 13, Status, 0);
1836 }
1837
1838 /* Initialize machine-dependent information into the registry */
1840 if (!NT_SUCCESS(Status))
1841 {
1842 /* Bugcheck */
1843 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 14, Status, 0);
1844 }
1845
1846 /* Initialize volatile registry settings */
1848 if (!NT_SUCCESS(Status))
1849 {
1850 /* Bugcheck */
1851 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 15, Status, 0);
1852 }
1853
1854 /* Free the load options */
1856
1857 /* If we got here, all went well */
1858 return TRUE;
1859}
NTSTATUS NTAPI CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmhardwr.c:21
VOID NTAPI CmpInitCmPrivateAlloc(VOID)
Definition: cmalloc.c:29
VOID NTAPI CmpInitCmPrivateDelayAlloc(VOID)
Definition: cmalloc.c:44
NTSTATUS NTAPI CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmconfig.c:329
ULONG CmpVolatileBoot
Definition: cmdata.c:58
EX_PUSH_LOCK CmpHiveListHeadLock
Definition: cmdata.c:39
EX_PUSH_LOCK CmpLoadHiveLock
Definition: cmdata.c:39
BOOLEAN CmpMiniNTBoot
Definition: cmdata.c:62
UNICODE_STRING CmpLoadOptions
Definition: cmdata.c:55
VOID NTAPI CmpInitDelayDerefKCBEngine(VOID)
Definition: cmdelay.c:268
VOID NTAPI CmpInitCallback(VOID)
Definition: cmhook.c:38
NTSTATUS NTAPI CmpAddToHiveFileList(IN PCMHIVE Hive)
Definition: cmhvlist.c:130
VOID NTAPI CmpInitializeCache(VOID)
Definition: cmkcbncb.c:26
#define CM_CHECK_REGISTRY_DONT_PURGE_VOLATILES
Definition: cmlib.h:228
#define TAG_CM
Definition: cmlib.h:212
#define TAG_CMSD
Definition: cmlib.h:215
BOOLEAN NTAPI CmpCreateRegistryRoot(VOID)
Definition: cmsysini.c:1091
ERESOURCE CmpRegistryLock
Definition: cmsysini.c:18
NTSTATUS NTAPI CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, IN HANDLE RootDirectory, IN PCMHIVE RegistryHive, IN BOOLEAN Allocate, IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: cmsysini.c:823
PEPROCESS CmpSystemProcess
Definition: cmsysini.c:23
NTSTATUS NTAPI CmpCreateObjectTypes(VOID)
Definition: cmsysini.c:1001
NTSTATUS NTAPI CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:549
BOOLEAN NTAPI CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:890
BOOLEAN CmpNoVolatileCreates
Definition: cmsysini.c:34
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:16
LIST_ENTRY CmpHiveListHead
Definition: cmsysini.c:17
LIST_ENTRY CmpSelfHealQueueListHead
Definition: cmsysini.c:20
KGUARDED_MUTEX CmpSelfHealQueueLock
Definition: cmsysini.c:19
NTSTATUS NTAPI CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:401
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExInitializePushLock
Definition: ex.h:1016
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define HINIT_CREATE
Definition: hivedata.h:13
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:28
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KEY_WRITE
Definition: nt_native.h:1034
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
NTSTATUS NTAPI CmpInitializeHive(_Out_ PCMHIVE *CmHive, _In_ ULONG OperationType, _In_ ULONG HiveFlags, _In_ ULONG FileType, _In_opt_ PVOID HiveData, _In_ HANDLE Primary, _In_ HANDLE Log, _In_ HANDLE External, _In_ HANDLE Alternate, _In_opt_ PCUNICODE_STRING FileName, _In_ ULONG CheckFlags)
Definition: cminit.c:19
PSECURITY_DESCRIPTOR NTAPI CmpHiveRootSecurityDescriptor(VOID)
Definition: cmse.c:21
BOOLEAN InitIsWinPEMode
Definition: init.c:72
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by Phase1InitializationDiscard().

◆ CmpAcquireTwoKcbLocksExclusiveByKey()

VOID NTAPI CmpAcquireTwoKcbLocksExclusiveByKey ( IN ULONG  ConvKey1,
IN ULONG  ConvKey2 
)

Definition at line 2104 of file cmsysini.c.

2106{
2107 ULONG Index1, Index2;
2108
2109 /* Sanity check */
2111
2112 /* Get hash indexes */
2113 Index1 = GET_HASH_INDEX(ConvKey1);
2114 Index2 = GET_HASH_INDEX(ConvKey2);
2115
2116 /* See which one is highest */
2117 if (Index1 < Index2)
2118 {
2119 /* Grab them in the proper order */
2122 }
2123 else
2124 {
2125 /* Grab the second one first, then the first */
2127 if (Index1 != Index2) CmpAcquireKcbLockExclusiveByKey(ConvKey1);
2128 }
2129}
FORCEINLINE VOID CmpAcquireKcbLockExclusiveByKey(IN ULONG ConvKey)
Definition: cm_x.h:143
#define GET_HASH_INDEX(ConvKey)
Definition: cm_x.h:37
#define CMP_ASSERT_REGISTRY_LOCK()
Definition: cm_x.h:65

Referenced by CmDeleteKey(), and CmpCreateKeyControlBlock().

◆ CmpCloseKeyObject()

VOID NTAPI CmpCloseKeyObject ( IN PEPROCESS Process  OPTIONAL,
IN PVOID  Object,
IN ACCESS_MASK  GrantedAccess,
IN ULONG  ProcessHandleCount,
IN ULONG  SystemHandleCount 
)

Definition at line 162 of file cmsysini.c.

167{
169 PAGED_CODE();
170
171 /* Don't do anything if we're not the last handle */
172 if (SystemHandleCount > 1) return;
173
174 /* Make sure we're a valid key body */
175 if (KeyBody->Type == CM_KEY_BODY_TYPE)
176 {
177 /* Don't do anything if we don't have a notify block */
178 if (!KeyBody->NotifyBlock) return;
179
180 /* This shouldn't happen yet */
181 ASSERT(FALSE);
182 }
183}
struct _CM_KEY_BODY * PCM_KEY_BODY
#define CM_KEY_BODY_TYPE
Definition: cm.h:64
ULONG Type
Definition: cm.h:236
struct _CM_NOTIFY_BLOCK * NotifyBlock
Definition: cm.h:238
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object

Referenced by CmpCreateObjectTypes().

◆ CmpCreateControlSet()

NTSTATUS NTAPI CmpCreateControlSet ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 549 of file cmsysini.c.

550{
551 UNICODE_STRING ConfigName = RTL_CONSTANT_STRING(L"Control\\IDConfigDB");
552 UNICODE_STRING SelectName =
553 RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\Select");
556 CHAR ValueInfoBuffer[128];
558 WCHAR UnicodeBuffer[128];
559 HANDLE SelectHandle = NULL;
561 HANDLE ConfigHandle = NULL;
562 HANDLE ProfileHandle = NULL;
563 HANDLE ParentHandle = NULL;
564 ULONG ControlSet, HwProfile;
567 PLOADER_PARAMETER_EXTENSION LoaderExtension;
568 PAGED_CODE();
569
570 /* ReactOS Hack: Hard-code current to 001 for SetupLdr */
571 if (LoaderBlock->RegistryBase == NULL)
572 {
573 /* Build the ControlSet001 key */
575 L"\\Registry\\Machine\\System\\ControlSet001");
577 &KeyName,
579 NULL,
580 NULL);
584 0,
585 NULL,
586 0,
587 &Disposition);
588 if (!NT_SUCCESS(Status))
589 {
590 DPRINT1("Failed to create ControlSet001 key: 0x%lx\n", Status);
591 goto Cleanup;
592 }
593
594 /* Create the Hardware Profile keys */
596 if (!NT_SUCCESS(Status))
597 {
598 DPRINT1("Failed to create Hardware profile keys: 0x%lx\n", Status);
599 goto Cleanup;
600 }
601
602 /* Use hard-coded setting */
603 ControlSet = 1;
604 }
605 else
606 {
607 /* Open the select key */
609 &SelectName,
611 NULL,
612 NULL);
613 Status = NtOpenKey(&SelectHandle, KEY_READ, &ObjectAttributes);
614 if (!NT_SUCCESS(Status))
615 {
616 DPRINT1("Failed to open select key: 0x%lx\n", Status);
617 goto Cleanup;
618 }
619
620 /* Open the current value */
621 RtlInitUnicodeString(&KeyName, L"Current");
622 Status = NtQueryValueKey(SelectHandle,
623 &KeyName,
625 ValueInfoBuffer,
626 sizeof(ValueInfoBuffer),
627 &ResultLength);
628 if (!NT_SUCCESS(Status))
629 {
630 DPRINT1("Failed to open the Current value: 0x%lx\n", Status);
631 goto Cleanup;
632 }
633
634 /* Get the actual value pointer, and get the control set ID */
635 ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer;
636 ControlSet = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset);
637 }
638
639 /* Create the current control set key */
641 L"\\Registry\\Machine\\System\\CurrentControlSet");
643 &KeyName,
645 NULL,
646 NULL);
650 0,
651 NULL,
653 &Disposition);
654 if (!NT_SUCCESS(Status))
655 goto Cleanup;
656
657 /* Sanity check */
659
660 /* Initialize the target link name */
661 Status = RtlStringCbPrintfW(UnicodeBuffer, sizeof(UnicodeBuffer),
662 L"\\Registry\\Machine\\System\\ControlSet%03ld",
663 ControlSet);
664 if (!NT_SUCCESS(Status))
665 goto Cleanup;
666
667 RtlInitUnicodeString(&KeyName, UnicodeBuffer);
668
669 /* Set the value */
672 0,
673 REG_LINK,
674 KeyName.Buffer,
675 KeyName.Length);
676 if (!NT_SUCCESS(Status))
677 goto Cleanup;
678
679 /* Get the configuration database key */
681 &ConfigName,
683 KeyHandle,
684 NULL);
685 Status = NtOpenKey(&ConfigHandle, KEY_READ, &ObjectAttributes);
686
687 /* Check if we don't have one */
688 if (!NT_SUCCESS(Status))
689 {
690 /* Cleanup and exit */
692 goto Cleanup;
693 }
694
695 /* ReactOS Hack: Hard-code current to 001 for SetupLdr */
696 if (LoaderBlock->RegistryBase == NULL)
697 {
698 HwProfile = 0;
699 }
700 else
701 {
702 /* Now get the current config */
703 RtlInitUnicodeString(&KeyName, L"CurrentConfig");
704 Status = NtQueryValueKey(ConfigHandle,
705 &KeyName,
707 ValueInfoBuffer,
708 sizeof(ValueInfoBuffer),
709 &ResultLength);
710
711 /* Set pointer to buffer */
712 ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer;
713
714 /* Check if we failed or got a non DWORD-value */
715 if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_DWORD))
716 {
718 goto Cleanup;
719 }
720
721 /* Get the hadware profile */
722 HwProfile = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset);
723 }
724
725 /* Open the hardware profile key */
727 L"\\Registry\\Machine\\System\\CurrentControlSet"
728 L"\\Hardware Profiles");
730 &KeyName,
732 NULL,
733 NULL);
734 Status = NtOpenKey(&ParentHandle, KEY_READ, &ObjectAttributes);
735 if (!NT_SUCCESS(Status))
736 {
737 /* Exit and clean up */
739 goto Cleanup;
740 }
741
742 /* Build the profile name */
743 RtlStringCbPrintfW(UnicodeBuffer, sizeof(UnicodeBuffer),
744 L"%04ld", HwProfile);
745 RtlInitUnicodeString(&KeyName, UnicodeBuffer);
746
747 /* Open the associated key */
749 &KeyName,
751 ParentHandle,
752 NULL);
753 Status = NtOpenKey(&ProfileHandle,
756 if (!NT_SUCCESS(Status))
757 {
758 /* Cleanup and exit */
760 goto Cleanup;
761 }
762
763 /* Check if we have a loader block extension */
764 LoaderExtension = LoaderBlock->Extension;
765 if (LoaderExtension)
766 {
767 DPRINT("ReactOS doesn't support NTLDR Profiles yet!\n");
768 }
769
770 /* Create the current hardware profile key */
772 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
773 L"Hardware Profiles\\Current");
775 &KeyName,
777 NULL,
778 NULL);
782 0,
783 NULL,
785 &Disposition);
786 if (NT_SUCCESS(Status))
787 {
788 /* Sanity check */
790
791 /* Create the profile name */
792 RtlStringCbPrintfW(UnicodeBuffer, sizeof(UnicodeBuffer),
793 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
794 L"Hardware Profiles\\%04ld",
795 HwProfile);
796 RtlInitUnicodeString(&KeyName, UnicodeBuffer);
797
798 /* Set it */
801 0,
802 REG_LINK,
803 KeyName.Buffer,
804 KeyName.Length);
805 }
806
808
809Cleanup:
810 /* Close every opened handle */
811 if (SelectHandle) NtClose(SelectHandle);
813 if (ConfigHandle) NtClose(ConfigHandle);
814 if (ProfileHandle) NtClose(ProfileHandle);
815 if (ParentHandle) NtClose(ParentHandle);
816
817 DPRINT("CmpCreateControlSet() done\n");
818 return Status;
819}
UNICODE_STRING CmSymbolicLinkValueName
Definition: cmdata.c:52
static NTSTATUS CmpCreateHardwareProfile(HANDLE ControlSetHandle)
Definition: cmsysini.c:477
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
static const WCHAR Cleanup[]
Definition: register.c:80
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
@ KeyValueFullInformation
Definition: nt_native.h:1184
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define REG_OPTION_CREATE_LINK
Definition: nt_native.h:1066
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1087
#define REG_LINK
Definition: nt_native.h:1503
#define KEY_CREATE_LINK
Definition: nt_native.h:1024
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1063
struct _KEY_VALUE_FULL_INFORMATION * PKEY_VALUE_FULL_INFORMATION
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
char CHAR
Definition: pedump.c:57
#define REG_DWORD
Definition: sdbapi.c:615
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3782

Referenced by CmInitSystem1().

◆ CmpCreateHardwareProfile()

static NTSTATUS CmpCreateHardwareProfile ( HANDLE  ControlSetHandle)
static

Definition at line 477 of file cmsysini.c.

478{
481 HANDLE ProfilesHandle = NULL;
482 HANDLE ProfileHandle = NULL;
485
486 DPRINT("CmpCreateHardwareProfile()\n");
487
488 /* Create the Hardware Profiles key */
489 RtlInitUnicodeString(&KeyName, L"Hardware Profiles");
491 &KeyName,
493 ControlSetHandle,
494 NULL);
495 Status = NtCreateKey(&ProfilesHandle,
498 0,
499 NULL,
500 0,
501 &Disposition);
502 if (!NT_SUCCESS(Status))
503 {
504 DPRINT1("Creating the Hardware Profile key failed\n");
505 goto done;
506 }
507
508 /* Sanity check */
510
511 /* Create the 0000 key */
514 &KeyName,
516 ProfilesHandle,
517 NULL);
518 Status = NtCreateKey(&ProfileHandle,
521 0,
522 NULL,
523 0,
524 &Disposition);
525 if (!NT_SUCCESS(Status))
526 {
527 DPRINT1("Creating the Hardware Profile\\0000 key failed\n");
528 goto done;
529 }
530
531 /* Sanity check */
533
534done:
535 if (ProfilesHandle)
536 NtClose(ProfilesHandle);
537
538 if (ProfileHandle)
539 NtClose(ProfileHandle);
540
541 DPRINT("CmpCreateHardwareProfile() done\n");
542
543 return Status;
544}

Referenced by CmpCreateControlSet().

◆ CmpCreateObjectTypes()

NTSTATUS NTAPI CmpCreateObjectTypes ( VOID  )

Definition at line 1001 of file cmsysini.c.

1002{
1003 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
1005 GENERIC_MAPPING CmpKeyMapping = {KEY_READ,
1006 KEY_WRITE,
1009 PAGED_CODE();
1010
1011 /* Initialize the Key object type */
1012 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
1013 RtlInitUnicodeString(&Name, L"Key");
1014 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
1015 ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(CM_KEY_BODY);
1016 ObjectTypeInitializer.GenericMapping = CmpKeyMapping;
1017 ObjectTypeInitializer.PoolType = PagedPool;
1018 ObjectTypeInitializer.ValidAccessMask = KEY_ALL_ACCESS;
1019 ObjectTypeInitializer.UseDefaultObject = TRUE;
1020 ObjectTypeInitializer.DeleteProcedure = CmpDeleteKeyObject;
1021 ObjectTypeInitializer.ParseProcedure = CmpParseKey;
1022 ObjectTypeInitializer.SecurityProcedure = CmpSecurityMethod;
1023 ObjectTypeInitializer.QueryNameProcedure = CmpQueryKeyName;
1024 ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject;
1025 ObjectTypeInitializer.SecurityRequired = TRUE;
1026 ObjectTypeInitializer.InvalidAttributes = OBJ_EXCLUSIVE | OBJ_PERMANENT;
1027
1028 /* Create it */
1029 return ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmpKeyObjectType);
1030}
struct _CM_KEY_BODY CM_KEY_BODY
NTSTATUS NTAPI CmpParseKey(IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
Definition: cmparse.c:1848
VOID NTAPI CmpDeleteKeyObject(PVOID DeletedObject)
Definition: cmsysini.c:112
VOID NTAPI CmpCloseKeyObject(IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
Definition: cmsysini.c:162
NTSTATUS NTAPI CmpQueryKeyName(IN PVOID ObjectBody, IN BOOLEAN HasName, IN OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength, IN KPROCESSOR_MODE PreviousMode)
Definition: cmsysini.c:187
#define PagedPool
Definition: env_spec_w32.h:308
#define KEY_EXECUTE
Definition: nt_native.h:1040
NTSTATUS NTAPI CmpSecurityMethod(IN PVOID ObjectBody, IN SECURITY_OPERATION_CODE OperationCode, IN PSECURITY_INFORMATION SecurityInformation, IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG BufferLength, IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping)
Definition: cmse.c:261
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
#define OBJ_PERMANENT
Definition: winternl.h:226
OB_CLOSE_METHOD CloseProcedure
Definition: obtypes.h:368
OB_SECURITY_METHOD SecurityProcedure
Definition: obtypes.h:371
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
OB_QUERYNAME_METHOD QueryNameProcedure
Definition: obtypes.h:372
OB_PARSE_METHOD ParseProcedure
Definition: obtypes.h:370
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by CmInitSystem1().

◆ CmpCreateRegistryRoot()

BOOLEAN NTAPI CmpCreateRegistryRoot ( VOID  )

Definition at line 1091 of file cmsysini.c.

1092{
1096 HCELL_INDEX RootIndex;
1098 PCM_KEY_NODE KeyCell;
1101 PAGED_CODE();
1102
1103 /* Setup the root node */
1104 if (!CmpCreateRootNode(&CmiVolatileHive->Hive, L"REGISTRY", &RootIndex))
1105 {
1106 /* We failed */
1107 return FALSE;
1108 }
1109
1110 /* Create '\Registry' key. */
1111 RtlInitUnicodeString(&KeyName, L"\\REGISTRY");
1114 &KeyName,
1116 NULL,
1121 KernelMode,
1122 NULL,
1123 sizeof(CM_KEY_BODY),
1124 0,
1125 0,
1126 (PVOID*)&RootKey);
1128 if (!NT_SUCCESS(Status)) return FALSE;
1129
1130 /* Sanity check, and get the key cell */
1131 ASSERT((&CmiVolatileHive->Hive)->ReleaseCellRoutine == NULL);
1132 KeyCell = (PCM_KEY_NODE)HvGetCell(&CmiVolatileHive->Hive, RootIndex);
1133 if (!KeyCell)
1134 {
1136 return FALSE;
1137 }
1138
1139 /* Create the KCB */
1140 RtlInitUnicodeString(&KeyName, L"\\REGISTRY");
1142 RootIndex,
1143 KeyCell,
1144 NULL,
1145 0,
1146 &KeyName);
1147 if (!Kcb)
1148 {
1150 return FALSE;
1151 }
1152
1153 /* Initialize the object */
1154 RootKey->KeyControlBlock = Kcb;
1155 RootKey->Type = CM_KEY_BODY_TYPE;
1156 RootKey->NotifyBlock = NULL;
1157 RootKey->ProcessID = PsGetCurrentProcessId();
1158 RootKey->KcbLocked = FALSE;
1159
1160 /* Link with KCB */
1162
1163 /* Insert the key into the namespace */
1165 NULL,
1167 0,
1168 NULL,
1170 if (!NT_SUCCESS(Status))
1171 {
1172 return FALSE;
1173 }
1174
1175 /* Reference the key again so that we never lose it */
1177 KEY_READ,
1178 NULL,
1179 KernelMode,
1180 (PVOID*)&RootKey,
1181 NULL);
1182 if (!NT_SUCCESS(Status))
1183 {
1185 return FALSE;
1186 }
1187
1188 /* Completely successful */
1189 return TRUE;
1190}
HANDLE CmpRegistryRootHandle
Definition: cmdata.c:71
struct _CM_KEY_NODE * PCM_KEY_NODE
PCM_KEY_CONTROL_BLOCK NTAPI CmpCreateKeyControlBlock(IN PHHIVE Hive, IN HCELL_INDEX Index, IN PCM_KEY_NODE Node, IN PCM_KEY_CONTROL_BLOCK Parent, IN ULONG Flags, IN PUNICODE_STRING KeyName)
Definition: cmkcbncb.c:655
VOID NTAPI EnlistKeyBodyWithKCB(IN PCM_KEY_BODY KeyBody, IN ULONG Flags)
Definition: cmkcbncb.c:1042
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:457
BOOLEAN NTAPI CmpCreateRootNode(IN PHHIVE Hive, IN PCWSTR Name, OUT PHCELL_INDEX Index)
Definition: cmsysini.c:1035
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
static PMEMKEY RootKey
Definition: registry.c:55
HHIVE Hive
Definition: cmlib.h:317

Referenced by CmInitSystem1().

◆ CmpCreateRootNode()

BOOLEAN NTAPI CmpCreateRootNode ( IN PHHIVE  Hive,
IN PCWSTR  Name,
OUT PHCELL_INDEX  Index 
)

Definition at line 1035 of file cmsysini.c.

1038{
1040 PCM_KEY_NODE KeyCell;
1041 PAGED_CODE();
1042
1043 /* Initialize the node name and allocate it */
1045 *Index = HvAllocateCell(Hive,
1047 CmpNameSize(Hive, &KeyName),
1048 Stable,
1049 HCELL_NIL);
1050 if (*Index == HCELL_NIL) return FALSE;
1051
1052 /* Set the cell index and get the data */
1053 Hive->BaseBlock->RootCell = *Index;
1054 KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, *Index);
1055 if (!KeyCell) return FALSE;
1056
1057 /* Setup the cell */
1059 KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
1061 KeyCell->Parent = HCELL_NIL;
1062 KeyCell->SubKeyCounts[Stable] = 0;
1063 KeyCell->SubKeyCounts[Volatile] = 0;
1064 KeyCell->SubKeyLists[Stable] = HCELL_NIL;
1065 KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
1066 KeyCell->ValueList.Count = 0;
1067 KeyCell->ValueList.List = HCELL_NIL;
1068 KeyCell->Security = HCELL_NIL;
1069 KeyCell->Class = HCELL_NIL;
1070 KeyCell->ClassLength = 0;
1071 KeyCell->MaxNameLen = 0;
1072 KeyCell->MaxClassLen = 0;
1073 KeyCell->MaxValueNameLen = 0;
1074 KeyCell->MaxValueDataLen = 0;
1075
1076 /* Copy the name (this will also set the length) */
1077 KeyCell->NameLength = CmpCopyName(Hive, KeyCell->Name, &KeyName);
1078
1079 /* Check if the name was compressed and set the flag if so */
1080 if (KeyCell->NameLength < KeyName.Length)
1081 KeyCell->Flags |= KEY_COMP_NAME;
1082
1083 /* Return success */
1084 HvReleaseCell(Hive, *Index);
1085 return TRUE;
1086}
#define KEY_COMP_NAME
Definition: cmdata.h:35
#define KEY_NO_DELETE
Definition: cmdata.h:33
#define CM_KEY_NODE_SIGNATURE
Definition: cmdata.h:21
#define KEY_HIVE_ENTRY
Definition: cmdata.h:32
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:460
USHORT NTAPI CmpCopyName(IN PHHIVE Hive, OUT PWCHAR Destination, IN PCUNICODE_STRING Source)
Definition: cmname.c:21
USHORT NTAPI CmpNameSize(IN PHHIVE Hive, IN PCUNICODE_STRING Name)
Definition: cmname.c:74
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
@ Volatile
Definition: hivedata.h:128
HCELL_INDEX List
Definition: cmdata.h:75
ULONG Count
Definition: cmdata.h:74
USHORT Signature
Definition: cmdata.h:92
HCELL_INDEX Parent
Definition: cmdata.h:96
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:116
HCELL_INDEX SubKeyLists[HTYPE_COUNT]
Definition: cmdata.h:102
ULONG MaxValueNameLen
Definition: cmdata.h:111
ULONG MaxNameLen
Definition: cmdata.h:109
ULONG SubKeyCounts[HTYPE_COUNT]
Definition: cmdata.h:97
HCELL_INDEX Security
Definition: cmdata.h:107
USHORT NameLength
Definition: cmdata.h:114
USHORT ClassLength
Definition: cmdata.h:115
ULONG MaxClassLen
Definition: cmdata.h:110
HCELL_INDEX Class
Definition: cmdata.h:108
ULONG MaxValueDataLen
Definition: cmdata.h:112
CHILD_LIST ValueList
Definition: cmdata.h:103
USHORT Flags
Definition: cmdata.h:93
LARGE_INTEGER LastWriteTime
Definition: cmdata.h:94
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by CmpCreateRegistryRoot().

◆ CmpDeleteKeyObject()

VOID NTAPI CmpDeleteKeyObject ( PVOID  DeletedObject)

Definition at line 112 of file cmsysini.c.

113{
114 PCM_KEY_BODY KeyBody = (PCM_KEY_BODY)DeletedObject;
116 REG_KEY_HANDLE_CLOSE_INFORMATION KeyHandleCloseInfo;
117 REG_POST_OPERATION_INFORMATION PostOperationInfo;
119 PAGED_CODE();
120
121 /* First off, prepare the handle close information callback */
122 PostOperationInfo.Object = KeyBody;
123 KeyHandleCloseInfo.Object = KeyBody;
125 &KeyHandleCloseInfo);
126 if (!NT_SUCCESS(Status))
127 {
128 /* If we failed, notify the post routine */
129 PostOperationInfo.Status = Status;
131 return;
132 }
133
134 /* Acquire hive lock */
136
137 /* Make sure this is a valid key body */
138 if (KeyBody->Type == CM_KEY_BODY_TYPE)
139 {
140 /* Get the KCB */
141 Kcb = KeyBody->KeyControlBlock;
142 if (Kcb)
143 {
144 /* Delist the key */
145 DelistKeyBodyFromKCB(KeyBody, KeyBody->KcbLocked);
146
147 /* Dereference the KCB */
149 }
150 }
151
152 /* Release the registry lock */
154
155 /* Do the post callback */
156 PostOperationInfo.Status = STATUS_SUCCESS;
158}
VOID NTAPI CmpDelayDerefKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmdelay.c:286
NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2)
Definition: cmhook.c:59
VOID NTAPI DelistKeyBodyFromKCB(IN PCM_KEY_BODY KeyBody, IN BOOLEAN LockHeld)
Definition: cmkcbncb.c:1100
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1995
BOOLEAN KcbLocked
Definition: cm.h:243
Definition: cmtypes.h:858
PVOID Object
Definition: cmtypes.h:859
NTSTATUS Status
Definition: cmtypes.h:860
@ RegNtPreKeyHandleClose
Definition: cmtypes.h:655
@ RegNtPostKeyHandleClose
Definition: cmtypes.h:666

Referenced by CmpCreateObjectTypes().

◆ CmpGetRegistryPath()

static PCWSTR CmpGetRegistryPath ( VOID  )
static

Definition at line 1193 of file cmsysini.c.

1194{
1195 PCWSTR ConfigPath;
1196
1197 /* Check if we are booted in setup */
1198 if (!ExpInTextModeSetup)
1199 {
1200 ConfigPath = L"\\SystemRoot\\System32\\Config\\";
1201 }
1202 else
1203 {
1204 ConfigPath = L"\\SystemRoot\\";
1205 }
1206
1207 DPRINT1("CmpGetRegistryPath: ConfigPath = '%S'\n", ConfigPath);
1208
1209 return ConfigPath;
1210}
BOOLEAN ExpInTextModeSetup
Definition: init.c:69

Referenced by _Function_class_(), and CmpInitializeHiveList().

◆ CmpHasAlternateHiveDiverged()

static VOID CmpHasAlternateHiveDiverged ( _In_ PCUNICODE_STRING  FileName,
_In_ PCMHIVE  CmMainmHive,
_In_ HANDLE  AlternateHandle,
_Out_ PBOOLEAN  Diverged 
)
static

Checks if the primary and alternate backing hive are the same, by determining the time stamp of both hives.

Parameters
[in]FileNameA pointer to a string containing the file name of the primary hive.
[in]CmMainmHiveA pointer to a CM hive descriptor associated with the primary hive.
[in]AlternateHandleA handle to a file that represents the alternate hive.
[in]DivergedA pointer to a boolean value, if both hives are the same it returns TRUE. Otherwise it returns FALSE.

Definition at line 1234 of file cmsysini.c.

1239{
1240 PHHIVE Hive, AlternateHive;
1242 PCMHIVE CmiAlternateHive;
1243
1244 /* Assume it has not diverged */
1245 *Diverged = FALSE;
1246
1247 /* Initialize the SYSTEM alternate hive */
1248 Status = CmpInitializeHive(&CmiAlternateHive,
1249 HINIT_FILE,
1250 0,
1252 NULL,
1253 AlternateHandle,
1254 NULL,
1255 NULL,
1256 NULL,
1257 FileName,
1259 if (!NT_SUCCESS(Status))
1260 {
1261 /* Assume it has diverged... */
1262 DPRINT1("Failed to initialize the alternate hive to check for diversion (Status 0x%lx)\n", Status);
1263 *Diverged = TRUE;
1264 return;
1265 }
1266
1267 /*
1268 * Check the timestamp of both hives. If they do not match they
1269 * have diverged, the kernel has to synchronize the both hives.
1270 */
1271 Hive = &CmMainmHive->Hive;
1272 AlternateHive = &CmiAlternateHive->Hive;
1273 if (AlternateHive->BaseBlock->TimeStamp.QuadPart !=
1275 {
1276 *Diverged = TRUE;
1277 }
1278
1279 CmpDestroyHive(CmiAlternateHive);
1280}
#define HINIT_FILE
Definition: hivedata.h:15
NTSTATUS NTAPI CmpDestroyHive(IN PCMHIVE CmHive)
Definition: cminit.c:242
LARGE_INTEGER TimeStamp
Definition: hivedata.h:151
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:328
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by _Function_class_().

◆ CmpInitHiveFromFile()

NTSTATUS NTAPI CmpInitHiveFromFile ( IN PCUNICODE_STRING  HiveName,
IN ULONG  HiveFlags,
OUT PCMHIVE Hive,
IN OUT PBOOLEAN  New,
IN ULONG  CheckFlags 
)

Definition at line 289 of file cmsysini.c.

294{
295 ULONG HiveDisposition, LogDisposition;
299 PCMHIVE NewHive;
300 PAGED_CODE();
301
302 /* Assume failure */
303 *Hive = NULL;
304
305 /* Open or create the hive files */
306 Status = CmpOpenHiveFiles(HiveName,
307 L".LOG",
308 &FileHandle,
309 &LogHandle,
310 &HiveDisposition,
311 &LogDisposition,
312 *New,
313 FALSE,
314 TRUE,
315 NULL);
316 if (!NT_SUCCESS(Status)) return Status;
317
318 /* Check if we have a log handle */
320
321 /* Check if we created or opened the hive */
322 if (HiveDisposition == FILE_CREATED)
323 {
324 /* Do a create operation */
326 *New = TRUE;
327 }
328 else
329 {
330 /* Open it as a file */
332 *New = FALSE;
333 }
334
335 /* Check if the system hives are opened in shared mode */
337 {
338 /* Then force using the primary hive */
340 if (LogHandle)
341 {
342 /* Get rid of the log handle */
344 LogHandle = NULL;
345 }
346 }
347
348 /* Check if we're too late */
350 {
351 /* Fail */
354 return STATUS_TOO_LATE;
355 }
356
357 /* Initialize the hive */
358 Status = CmpInitializeHive(&NewHive,
359 Operation,
360 HiveFlags,
361 FileType,
362 NULL,
364 LogHandle,
365 NULL,
366 NULL,
367 HiveName,
368 CheckFlags);
369 if (!NT_SUCCESS(Status))
370 {
371 /* Fail */
374 return Status;
375 }
376
377 /* Success, return hive */
378 *Hive = NewHive;
379
380 /* Duplicate the hive name */
382 HiveName->Length,
383 TAG_CM);
384 if (NewHive->FileFullPath.Buffer)
385 {
386 /* Copy the string */
388 HiveName->Buffer,
389 HiveName->Length);
390 NewHive->FileFullPath.Length = HiveName->Length;
391 NewHive->FileFullPath.MaximumLength = HiveName->Length;
392 }
393
394 /* Return success */
395 return STATUS_SUCCESS;
396}
BOOLEAN HvShutdownComplete
Definition: cmsysini.c:36
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
FP_OP Operation
Definition: fpcontrol.c:150
_In_ UINT _Out_ PNDIS_HANDLE LogHandle
Definition: ndis.h:5382
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define STATUS_TOO_LATE
Definition: ntstatus.h:720
UNICODE_STRING FileFullPath
Definition: cmlib.h:333
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ WDFDEVICE _In_ WDF_SPECIAL_FILE_TYPE FileType
Definition: wdfdevice.h:2747

Referenced by _Function_class_(), and CmpCmdHiveOpen().

◆ CmpInitializeHiveList()

VOID NTAPI CmpInitializeHiveList ( VOID  )

Definition at line 1488 of file cmsysini.c.

1489{
1490 WCHAR FileBuffer[64], RegBuffer[64];
1491 PCWSTR ConfigPath;
1492 UNICODE_STRING TempName, FileName, RegName;
1493 HANDLE Thread;
1495 ULONG i;
1496 USHORT RegStart;
1498
1499 PAGED_CODE();
1500
1501 /* Reenable hive writes now */
1502 CmpNoWrite = FALSE;
1503
1504 /* Build the file name and registry name strings */
1505 RtlInitEmptyUnicodeString(&FileName, FileBuffer, sizeof(FileBuffer));
1506 RtlInitEmptyUnicodeString(&RegName, RegBuffer, sizeof(RegBuffer));
1507
1508 /* Now build the system root path */
1509 ConfigPath = CmpGetRegistryPath();
1510 RtlInitUnicodeString(&TempName, ConfigPath);
1512
1513 /* And build the registry root path */
1514 RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
1515 RtlAppendUnicodeStringToString(&RegName, &TempName);
1516 RegStart = RegName.Length;
1517
1518 /* Setup the event to synchronize workers */
1520
1521 /* Enter special boot condition */
1523
1524 /* Create the SD for the root hives */
1526
1527 /* Loop every hive we care about */
1528 for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
1529 {
1530 /* Make sure the list is set up */
1532
1533 /* Load this root hive as volatile, if opened in shared mode */
1536
1537 /* Create a thread to handle this hive */
1540 NULL,
1541 0,
1542 NULL,
1543 CmpLoadHiveThread,
1544 UlongToPtr(i));
1545 if (NT_SUCCESS(Status))
1546 {
1547 /* We don't care about the handle -- the thread self-terminates */
1548 ZwClose(Thread);
1549 }
1550 else
1551 {
1552 /* Can't imagine this happening */
1553 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 9, 3, i, Status);
1554 }
1555 }
1556
1557 /* Make sure we've reached the end of the list */
1559
1560 /* Wait for hive loading to finish */
1562 Executive,
1563 KernelMode,
1564 FALSE,
1565 NULL);
1566
1567 /* Exit the special boot condition and make sure all workers completed */
1570
1571 /* Loop hives again */
1572 for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
1573 {
1574 /* Make sure the thread ran and finished */
1575 ASSERT(CmpMachineHiveList[i].ThreadFinished == TRUE);
1576 ASSERT(CmpMachineHiveList[i].ThreadStarted == TRUE);
1577
1578 /* Check if this was a new hive */
1579 if (!CmpMachineHiveList[i].CmHive)
1580 {
1581 /* Make sure we allocated something */
1582 ASSERT(CmpMachineHiveList[i].CmHive2 != NULL);
1583
1584 /* Build the base name */
1585 RegName.Length = RegStart;
1586 RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
1587 RtlAppendUnicodeStringToString(&RegName, &TempName);
1588
1589 /* Check if this is a child of the root */
1590 if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
1591 {
1592 /* Then setup the whole name */
1594 RtlAppendUnicodeStringToString(&RegName, &TempName);
1595 }
1596
1597 /* Now link the hive to its master */
1598 Status = CmpLinkHiveToMaster(&RegName,
1599 NULL,
1600 CmpMachineHiveList[i].CmHive2,
1603 if (Status != STATUS_SUCCESS)
1604 {
1605 /* Linking needs to work */
1606 KeBugCheckEx(CONFIG_LIST_FAILED, 11, Status, i, (ULONG_PTR)&RegName);
1607 }
1608
1609 /* Check if we had to allocate a new hive */
1611 {
1612 /* Sync the new hive */
1613 //HvSyncHive((PHHIVE)(CmpMachineHiveList[i].CmHive2));
1614 }
1615 }
1616
1617 /* Check if we created a new hive */
1618 if (CmpMachineHiveList[i].CmHive2)
1619 {
1620 /* Add to HiveList key */
1622 }
1623 }
1624
1625 /* Get rid of the SD */
1627
1628 /* Link SECURITY to SAM */
1629 CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM",
1630 L"\\Registry\\Machine\\SAM\\SAM");
1631
1632 /* Link S-1-5-18 to .Default */
1634 CmpLinkKeyToHive(L"\\Registry\\User\\S-1-5-18",
1635 L"\\Registry\\User\\.Default");
1637}
BOOLEAN NTAPI CmpLinkKeyToHive(_In_z_ PCWSTR LinkKeyName, _In_z_ PCWSTR TargetKeyName)
Definition: cmsysini.c:45
BOOLEAN CmpSpecialBootCondition
Definition: cmsysini.c:26
BOOLEAN CmpNoWrite
Definition: cmsysini.c:30
#define UlongToPtr(u)
Definition: config.h:106
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1342
@ SynchronizationEvent
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
ULONG HHiveFlags
Definition: cm.h:415
uint32_t ULONG_PTR
Definition: typedefs.h:65
@ Executive
Definition: ketypes.h:467

Referenced by CmpCmdInit().

◆ CmpInitializeSystemHive()

BOOLEAN NTAPI CmpInitializeSystemHive ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 890 of file cmsysini.c.

891{
892 static const UNICODE_STRING HiveName = RTL_CONSTANT_STRING(L"SYSTEM");
893 PVOID HiveBase;
901
902 PAGED_CODE();
903
904 /* Setup the ansi string */
905 RtlInitAnsiString(&LoadString, LoaderBlock->LoadOptions);
906
907 /* Allocate the unicode buffer */
908 Length = LoadString.Length * sizeof(WCHAR) + sizeof(UNICODE_NULL);
910 if (!Buffer)
911 {
912 /* Fail */
913 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 3, 1, (ULONG_PTR)LoaderBlock, 0);
914 }
915
916 /* Setup the unicode string */
917 RtlInitEmptyUnicodeString(&CmpLoadOptions, Buffer, (USHORT)Length);
918
919 /* Add the load options and null-terminate */
921 if (!NT_SUCCESS(Status))
922 {
923 return FALSE;
924 }
925
927 CmpLoadOptions.Length += sizeof(WCHAR);
928
929 /* Get the System Hive base address */
930 HiveBase = LoaderBlock->RegistryBase;
931
933 HiveBase ? HINIT_MEMORY : HINIT_CREATE,
936 HiveBase,
937 NULL,
938 NULL,
939 NULL,
940 NULL,
941 &HiveName,
943 if (!NT_SUCCESS(Status))
944 {
945 return FALSE;
946 }
947
948 /* Set the hive filename */
949 if (!RtlCreateUnicodeString(&SystemHive->FileFullPath, L"\\SystemRoot\\System32\\Config\\SYSTEM"))
950 return FALSE;
951
952 /* Load the system hive as volatile, if opened in shared mode */
953 if (HiveBase && CmpShareSystemHives)
955
956 /* Save the boot type */
958
959 /* Are we in self-healing mode? */
960 if (!CmSelfHeal)
961 {
962 /* Disable self-healing internally and check if boot type wanted it */
965 {
966 /* We're disabled, so bugcheck */
967 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,
968 3,
969 3,
971 0);
972 }
973 }
974
975 /* Create the default security descriptor */
977
978 /* Attach it to the system key */
979 /* Let CmpLinkHiveToMaster allocate a new hive if we got none from the LoaderBlock. */
980 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM");
982 NULL,
984 !HiveBase,
986
987 /* Free the security descriptor */
989 if (!NT_SUCCESS(Status)) return FALSE;
990
991 /* Add the hive to the hive list */
993
994 /* Success! */
995 return TRUE;
996}
PHHIVE SystemHive
Definition: registry.c:33
Definition: bufpool.h:45
ULONG CmSelfHeal
Definition: cmdata.c:65
ULONG CmpBootType
Definition: cmdata.c:64
BOOLEAN CmpSelfHeal
Definition: cmdata.c:66
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define HINIT_MEMORY
Definition: hivedata.h:14
#define HBOOT_TYPE_SELF_HEAL
Definition: hivedata.h:89
#define HIVE_NOLAZYFLUSH
Definition: hivedata.h:24
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define UNICODE_NULL
ULONG BootType
Definition: hivedata.h:186
ULONG HiveFlags
Definition: hivedata.h:347
#define LoadString
Definition: winuser.h:5985

Referenced by CmInitSystem1().

◆ CmpLinkHiveToMaster()

NTSTATUS NTAPI CmpLinkHiveToMaster ( IN PUNICODE_STRING  LinkName,
IN HANDLE  RootDirectory,
IN PCMHIVE  RegistryHive,
IN BOOLEAN  Allocate,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor 
)

Definition at line 823 of file cmsysini.c.

828{
831 CM_PARSE_CONTEXT ParseContext = {0};
833 PCM_KEY_BODY KeyBody;
834 PAGED_CODE();
835
836 /* Setup the object attributes */
838 LinkName,
842
843 /* Setup the parse context */
844 ParseContext.CreateLink = TRUE;
845 ParseContext.CreateOperation = TRUE;
846 ParseContext.ChildHive.KeyHive = &RegistryHive->Hive;
847
848 /* Check if we have a root keycell or if we need to create it */
849 if (Allocate)
850 {
851 /* Create it */
852 ParseContext.ChildHive.KeyCell = HCELL_NIL;
853 }
854 else
855 {
856 /* We have one */
857 ParseContext.ChildHive.KeyCell = RegistryHive->Hive.BaseBlock->RootCell;
858 }
859
860 /* Create the link node */
864 NULL,
866 (PVOID)&ParseContext,
867 &KeyHandle);
868 if (!NT_SUCCESS(Status)) return Status;
869
870 /* Mark the hive as clean */
871 RegistryHive->Hive.DirtyFlag = FALSE;
872
873 /* ReactOS Hack: Keep alive */
875 0,
878 (PVOID*)&KeyBody,
879 NULL);
881
882 /* Close the extra handle */
884 return STATUS_SUCCESS;
885}
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:73
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2532
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
PHHIVE KeyHive
Definition: cmdata.h:84
HCELL_INDEX KeyCell
Definition: cmdata.h:83
CM_KEY_REFERENCE ChildHive
Definition: cm.h:441
BOOLEAN CreateLink
Definition: cm.h:443
BOOLEAN CreateOperation
Definition: cm.h:444

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

◆ CmpLinkKeyToHive()

BOOLEAN NTAPI CmpLinkKeyToHive ( _In_z_ PCWSTR  LinkKeyName,
_In_z_ PCWSTR  TargetKeyName 
)

Definition at line 45 of file cmsysini.c.

48{
52 HANDLE LinkKeyHandle;
54
55 PAGED_CODE();
56
57 /* Initialize the object attributes */
58 RtlInitUnicodeString(&KeyName, LinkKeyName);
60 &KeyName,
62 NULL,
63 NULL);
64
65 /* Create the link key */
66 Status = ZwCreateKey(&LinkKeyHandle,
69 0,
70 NULL,
73 if (!NT_SUCCESS(Status))
74 {
75 DPRINT1("CM: CmpLinkKeyToHive: couldn't create %S, Status = 0x%lx\n",
76 LinkKeyName, Status);
77 return FALSE;
78 }
79
80 /* Check if the new key was actually created */
82 {
83 DPRINT1("CM: CmpLinkKeyToHive: %S already exists!\n", LinkKeyName);
84 ZwClose(LinkKeyHandle);
85 return FALSE;
86 }
87
88 /* Set the target key name as link target */
89 RtlInitUnicodeString(&KeyName, TargetKeyName);
90 Status = ZwSetValueKey(LinkKeyHandle,
92 0,
94 KeyName.Buffer,
95 KeyName.Length);
96
97 /* Close the link key handle */
98 ObCloseHandle(LinkKeyHandle, KernelMode);
99
100 if (!NT_SUCCESS(Status))
101 {
102 DPRINT1("CM: CmpLinkKeyToHive: couldn't create symbolic link for %S, Status = 0x%lx\n",
103 TargetKeyName, Status);
104 return FALSE;
105 }
106
107 return TRUE;
108}
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379

Referenced by CmpInitializeHiveList(), and RegInitializeRegistry().

◆ CmpLockHiveFlusherExclusive()

VOID NTAPI CmpLockHiveFlusherExclusive ( IN PCMHIVE  Hive)

Definition at line 2031 of file cmsysini.c.

2032{
2033 /* Lock the flusher. We should already be in a critical section */
2035 ASSERT((ExIsResourceAcquiredShared(Hive->FlusherLock) == 0) &&
2036 (ExIsResourceAcquiredExclusiveLite(Hive->FlusherLock) == 0));
2037 ExAcquireResourceExclusiveLite(Hive->FlusherLock, TRUE);
2038}
#define CMP_ASSERT_REGISTRY_LOCK_OR_LOADING(h)
Definition: cm_x.h:72
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1624
#define ExIsResourceAcquiredShared
Definition: exfuncs.h:348

Referenced by CmFlushKey(), CmLoadKey(), CmpDoFlushAll(), and CmpUnlinkHiveFromMaster().

◆ CmpLockHiveFlusherShared()

VOID NTAPI CmpLockHiveFlusherShared ( IN PCMHIVE  Hive)

Definition at line 2042 of file cmsysini.c.

2043{
2044 /* Lock the flusher. We should already be in a critical section */
2046 ASSERT((ExIsResourceAcquiredShared(Hive->FlusherLock) == 0) &&
2047 (ExIsResourceAcquiredExclusiveLite(Hive->FlusherLock) == 0));
2048 ExAcquireResourceSharedLite(Hive->FlusherLock, TRUE);
2049}
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621

Referenced by CmDeleteKey(), CmDeleteValueKey(), CmpCreateLinkNode(), CmpDoCreate(), and CmSetValueKey().

◆ CmpLockRegistry()

VOID NTAPI CmpLockRegistry ( VOID  )

Definition at line 1995 of file cmsysini.c.

1996{
1997 /* Enter a critical region */
1999
2000 /* Check if we have to starve writers */
2002 {
2003 /* Starve exlusive waiters */
2005 }
2006 else
2007 {
2008 /* Just grab the lock */
2010 }
2011}
LONG CmpFlushStarveWriters
Definition: cmlazy.c:27
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1068

Referenced by _Function_class_(), CmDeleteKey(), CmDeleteValueKey(), CmEnumerateKey(), CmEnumerateValueKey(), CmLoadKey(), CmpBuildHashStackAndLookupCache(), CmpDeleteKeyObject(), CmpQueryKeyName(), CmpSecurityMethod(), CmQueryKey(), CmQueryValueKey(), CmSaveKey(), CmSaveMergedKeys(), CmSetValueKey(), and NtFlushKey().

◆ CmpLockRegistryExclusive()

VOID NTAPI CmpLockRegistryExclusive ( VOID  )

Definition at line 1982 of file cmsysini.c.

1983{
1984 /* Enter a critical region and lock the registry */
1987
1988 /* Sanity check */
1991}
PVOID CmpRegistryLockCallerCaller
Definition: cmsysini.c:24
PVOID CmpRegistryLockCaller
Definition: cmsysini.c:24
NTSYSAPI void WINAPI RtlGetCallersAddress(void **, void **)

Referenced by _Function_class_(), CmGetSystemDriverList(), CmLoadKey(), CmShutdownSystem(), NtInitializeRegistry(), NtQueryOpenSubKeys(), and NtUnloadKey2().

◆ CmpQueryKeyName()

NTSTATUS NTAPI CmpQueryKeyName ( IN PVOID  ObjectBody,
IN BOOLEAN  HasName,
IN OUT POBJECT_NAME_INFORMATION  ObjectNameInfo,
IN ULONG  Length,
OUT PULONG  ReturnLength,
IN KPROCESSOR_MODE  PreviousMode 
)

Definition at line 187 of file cmsysini.c.

193{
197 PCM_KEY_BODY KeyBody = (PCM_KEY_BODY)ObjectBody;
199
200 /* Acquire hive lock */
202
203 /* Lock KCB shared */
205
206 /* Check if it's a deleted block */
207 if (Kcb->Delete)
208 {
209 /* Release the locks */
212
213 /* Let the caller know it's deleted */
214 return STATUS_KEY_DELETED;
215 }
216
217 /* Get the name */
219
220 /* Release the locks */
223
224 /* Check if we got the name */
226
227 /* Set the returned length */
228 *ReturnLength = KeyName->Length + sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR);
229
230 /* Calculate amount of bytes to copy into the buffer */
231 BytesToCopy = KeyName->Length + sizeof(WCHAR);
232
233 /* Check if the provided buffer is too small to fit even anything */
234 if ((Length <= sizeof(OBJECT_NAME_INFORMATION)) ||
235 ((Length < *ReturnLength) && (BytesToCopy < sizeof(WCHAR))))
236 {
237 /* Free the buffer allocated by CmpConstructName */
239
240 /* Return buffer length failure without writing anything there because nothing fits */
242 }
243
244 /* Check if the provided buffer can be partially written */
245 if (Length < *ReturnLength)
246 {
247 /* Yes, indicate so in the return status */
249
250 /* Calculate amount of bytes which the provided buffer could handle */
252 }
253
254 /* Remove the null termination character from the size */
255 BytesToCopy -= sizeof(WCHAR);
256
257 /* Fill in the result */
259 {
260 /* Return data to user */
261 ObjectNameInfo->Name.Buffer = (PWCHAR)(ObjectNameInfo + 1);
262 ObjectNameInfo->Name.MaximumLength = KeyName->Length;
263 ObjectNameInfo->Name.Length = KeyName->Length;
264
265 /* Copy string content*/
266 RtlCopyMemory(ObjectNameInfo->Name.Buffer,
267 KeyName->Buffer,
269
270 /* Null terminate it */
271 ObjectNameInfo->Name.Buffer[BytesToCopy / sizeof(WCHAR)] = UNICODE_NULL;
272 }
274 {
275 /* Get the status */
277 }
278 _SEH2_END;
279
280 /* Free the buffer allocated by CmpConstructName */
282
283 /* Return status */
284 return Status;
285}
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:162
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:202
PUNICODE_STRING NTAPI CmpConstructName(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:897
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
#define STATUS_KEY_DELETED
Definition: ntstatus.h:707
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by CmpCreateObjectTypes().

◆ CmpReleaseTwoKcbLockByKey()

VOID NTAPI CmpReleaseTwoKcbLockByKey ( IN ULONG  ConvKey1,
IN ULONG  ConvKey2 
)

Definition at line 2133 of file cmsysini.c.

2135{
2136 ULONG Index1, Index2;
2137
2138 /* Sanity check */
2140
2141 /* Get hash indexes */
2142 Index1 = GET_HASH_INDEX(ConvKey1);
2143 Index2 = GET_HASH_INDEX(ConvKey2);
2146
2147 /* See which one is highest */
2148 if (Index1 < Index2)
2149 {
2150 /* Grab them in the proper order */
2153 CmpReleaseKcbLockByKey(ConvKey2);
2154 CmpReleaseKcbLockByKey(ConvKey1);
2155 }
2156 else
2157 {
2158 /* Release the first one first, then the second */
2159 if (Index1 != Index2)
2160 {
2163 CmpReleaseKcbLockByKey(ConvKey1);
2164 }
2165 CmpReleaseKcbLockByKey(ConvKey2);
2166 }
2167}
#define GET_HASH_ENTRY(Table, ConvKey)
Definition: cm_x.h:39
FORCEINLINE VOID CmpReleaseKcbLockByKey(ULONG ConvKey)
Definition: cm_x.h:212
PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable
Definition: cmkcbncb.c:18
BOOLEAN NTAPI CmpTestRegistryLockExclusive(VOID)
Definition: cmsysini.c:2023
#define KeGetCurrentThread
Definition: hal.h:55
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1629

Referenced by CmDeleteKey(), and CmpCreateKeyControlBlock().

◆ CmpSetSystemValues()

NTSTATUS NTAPI CmpSetSystemValues ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 401 of file cmsysini.c.

402{
407
408 ASSERT(LoaderBlock != NULL);
409
410 /* Setup attributes for loader options */
412 L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control");
414 &KeyName,
416 NULL,
417 NULL);
419 if (!NT_SUCCESS(Status))
420 return Status;
421
422 /* Setup the value for the system start options */
423 RtlInitUnicodeString(&KeyName, L"SystemStartOptions");
425 &KeyName,
426 0,
427 REG_SZ,
430 if (!NT_SUCCESS(Status))
431 goto Quit;
432
433 /* Setup the value for the OS boot device in ARC format */
434 RtlInitUnicodeString(&KeyName, L"SystemBootDevice");
435 if (!RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->ArcBootDeviceName))
436 {
438 goto Quit;
439 }
441 &KeyName,
442 0,
443 REG_SZ,
444 ValueName.Buffer,
445 ValueName.Length);
447
448 if (!NT_SUCCESS(Status))
449 goto Quit;
450
451#if (NTDDI_VERSION >= NTDDI_VISTA) || defined(__REACTOS__)
452 /* Setup the value for the firmware boot (i.e. system partition) device in ARC format */
453 RtlInitUnicodeString(&KeyName, L"FirmwareBootDevice");
454 if (!RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->ArcHalDeviceName))
455 {
457 goto Quit;
458 }
460 &KeyName,
461 0,
462 REG_SZ,
463 ValueName.Buffer,
464 ValueName.Length);
466#endif
467
468Quit:
469 /* Close the key and return */
471 return Status;
472}
#define REG_SZ
Definition: layer.c:22
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243

Referenced by CmInitSystem1().

◆ CmpSetVersionData()

VOID NTAPI CmpSetVersionData ( VOID  )

Definition at line 2207 of file cmsysini.c.

2208{
2214 ANSI_STRING TempString;
2215 HANDLE SoftwareKeyHandle = NULL;
2216 HANDLE MicrosoftKeyHandle = NULL;
2217 HANDLE WindowsNtKeyHandle = NULL;
2218 HANDLE CurrentVersionKeyHandle = NULL;
2219 WCHAR Buffer[128]; // Buffer large enough to contain a full ULONG in decimal
2220 // representation, and the full 'CurrentType' string.
2221
2222 /*
2223 * Open the 'HKLM\Software\Microsoft\Windows NT\CurrentVersion' key
2224 * (create the intermediate subkeys if needed).
2225 */
2226
2227 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SOFTWARE");
2229 &KeyName,
2231 NULL,
2232 NULL);
2233 Status = NtCreateKey(&SoftwareKeyHandle,
2236 0,
2237 NULL,
2238 0,
2239 NULL);
2240 if (!NT_SUCCESS(Status))
2241 {
2242 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2243 return;
2244 }
2245
2246 RtlInitUnicodeString(&KeyName, L"Microsoft");
2248 &KeyName,
2250 SoftwareKeyHandle,
2251 NULL);
2252 Status = NtCreateKey(&MicrosoftKeyHandle,
2255 0,
2256 NULL,
2257 0,
2258 NULL);
2259 if (!NT_SUCCESS(Status))
2260 {
2261 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2262 goto Quit;
2263 }
2264
2265 RtlInitUnicodeString(&KeyName, L"Windows NT");
2267 &KeyName,
2269 MicrosoftKeyHandle,
2270 NULL);
2271 Status = NtCreateKey(&WindowsNtKeyHandle,
2274 0,
2275 NULL,
2276 0,
2277 NULL);
2278 if (!NT_SUCCESS(Status))
2279 {
2280 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2281 goto Quit;
2282 }
2283
2284 RtlInitUnicodeString(&KeyName, L"CurrentVersion");
2286 &KeyName,
2288 WindowsNtKeyHandle,
2289 NULL);
2290 Status = NtCreateKey(&CurrentVersionKeyHandle,
2293 0,
2294 NULL,
2295 0,
2296 NULL);
2297 if (!NT_SUCCESS(Status))
2298 {
2299 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2300 goto Quit;
2301 }
2302
2303 /* Set the 'CurrentVersion' value */
2304 RtlInitUnicodeString(&ValueName, L"CurrentVersion");
2305 NtSetValueKey(CurrentVersionKeyHandle,
2306 &ValueName,
2307 0,
2308 REG_SZ,
2310 CmVersionString.Length + sizeof(WCHAR));
2311
2312 /* Set the 'CurrentBuildNumber' value */
2313 RtlInitUnicodeString(&ValueName, L"CurrentBuildNumber");
2314 RtlInitEmptyUnicodeString(&ValueData, Buffer, sizeof(Buffer));
2316 NtSetValueKey(CurrentVersionKeyHandle,
2317 &ValueName,
2318 0,
2319 REG_SZ,
2320 ValueData.Buffer,
2321 ValueData.Length + sizeof(WCHAR));
2322
2323 /* Set the 'BuildLab' value */
2324 RtlInitUnicodeString(&ValueName, L"BuildLab");
2325 RtlInitAnsiString(&TempString, NtBuildLab);
2327 if (NT_SUCCESS(Status))
2328 {
2329 NtSetValueKey(CurrentVersionKeyHandle,
2330 &ValueName,
2331 0,
2332 REG_SZ,
2333 ValueData.Buffer,
2334 ValueData.Length + sizeof(WCHAR));
2335 }
2336
2337 /* Set the 'CurrentType' value */
2338 RtlInitUnicodeString(&ValueName, L"CurrentType");
2340 L"%s %s",
2341#ifdef CONFIG_SMP
2342 L"Multiprocessor"
2343#else
2344 L"Uniprocessor"
2345#endif
2346 ,
2347#if (DBG == 1)
2348 L"Checked"
2349#else
2350 L"Free"
2351#endif
2352 );
2354 NtSetValueKey(CurrentVersionKeyHandle,
2355 &ValueName,
2356 0,
2357 REG_SZ,
2358 ValueData.Buffer,
2359 ValueData.Length + sizeof(WCHAR));
2360
2361 /* Set the 'CSDVersion' value */
2362 RtlInitUnicodeString(&ValueName, L"CSDVersion");
2363 if (CmCSDVersionString.Length != 0)
2364 {
2365 NtSetValueKey(CurrentVersionKeyHandle,
2366 &ValueName,
2367 0,
2368 REG_SZ,
2370 CmCSDVersionString.Length + sizeof(WCHAR));
2371 }
2372 else
2373 {
2374 NtDeleteValueKey(CurrentVersionKeyHandle, &ValueName);
2375 }
2376
2377 /* Set the 'CSDBuildNumber' value */
2378 RtlInitUnicodeString(&ValueName, L"CSDBuildNumber");
2379 if (CmNtSpBuildNumber != 0)
2380 {
2381 RtlInitEmptyUnicodeString(&ValueData, Buffer, sizeof(Buffer));
2383 NtSetValueKey(CurrentVersionKeyHandle,
2384 &ValueName,
2385 0,
2386 REG_SZ,
2387 ValueData.Buffer,
2388 ValueData.Length + sizeof(WCHAR));
2389 }
2390 else
2391 {
2392 NtDeleteValueKey(CurrentVersionKeyHandle, &ValueName);
2393 }
2394
2395 /* Set the 'SystemRoot' value */
2396 RtlInitUnicodeString(&ValueName, L"SystemRoot");
2397 NtSetValueKey(CurrentVersionKeyHandle,
2398 &ValueName,
2399 0,
2400 REG_SZ,
2402 NtSystemRoot.Length + sizeof(WCHAR));
2403
2404Quit:
2405 /* Close the keys */
2406 if (CurrentVersionKeyHandle != NULL)
2407 NtClose(CurrentVersionKeyHandle);
2408
2409 if (WindowsNtKeyHandle != NULL)
2410 NtClose(WindowsNtKeyHandle);
2411
2412 if (MicrosoftKeyHandle != NULL)
2413 NtClose(MicrosoftKeyHandle);
2414
2415 if (SoftwareKeyHandle != NULL)
2416 NtClose(SoftwareKeyHandle);
2417}
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
#define DBG(x)
Definition: moztest.c:12
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:1014
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1021
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
#define KEY_SET_VALUE
Definition: nt_native.h:1020
UNICODE_STRING NtSystemRoot
Definition: init.c:76
CHAR NtBuildLab[]
Definition: init.c:64
UNICODE_STRING CmVersionString
Definition: init.c:61
ULONG CmNtSpBuildNumber
Definition: init.c:58
UNICODE_STRING CmCSDVersionString
Definition: init.c:62
ULONG NtBuildNumber
Definition: init.c:50

Referenced by NtInitializeRegistry().

◆ CmpTestHiveFlusherLockExclusive()

BOOLEAN NTAPI CmpTestHiveFlusherLockExclusive ( IN PCMHIVE  Hive)

Definition at line 2073 of file cmsysini.c.

2074{
2075 /* Test the lock */
2076 return !ExIsResourceAcquiredExclusiveLite(Hive->FlusherLock) ? FALSE : TRUE;
2077}

◆ CmpTestHiveFlusherLockShared()

BOOLEAN NTAPI CmpTestHiveFlusherLockShared ( IN PCMHIVE  Hive)

Definition at line 2065 of file cmsysini.c.

2066{
2067 /* Test the lock */
2068 return !ExIsResourceAcquiredSharedLite(Hive->FlusherLock) ? FALSE : TRUE;
2069}
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1663

◆ CmpTestRegistryLock()

BOOLEAN NTAPI CmpTestRegistryLock ( VOID  )

Definition at line 2015 of file cmsysini.c.

2016{
2017 /* Test the lock */
2019}

◆ CmpTestRegistryLockExclusive()

BOOLEAN NTAPI CmpTestRegistryLockExclusive ( VOID  )

Definition at line 2023 of file cmsysini.c.

2024{
2025 /* Test the lock */
2027}

Referenced by CmFlushKey(), and CmpReleaseTwoKcbLockByKey().

◆ CmpUnlockHiveFlusher()

VOID NTAPI CmpUnlockHiveFlusher ( IN PCMHIVE  Hive)

Definition at line 2053 of file cmsysini.c.

2054{
2055 /* Sanity check */
2058
2059 /* Release the lock */
2060 ExReleaseResourceLite(Hive->FlusherLock);
2061}
#define CMP_ASSERT_FLUSH_LOCK(h)
Definition: cm_x.h:299
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822

Referenced by CmDeleteKey(), CmDeleteValueKey(), CmFlushKey(), CmLoadKey(), CmpCreateLinkNode(), CmpDoCreate(), CmpDoFlushAll(), CmpUnlinkHiveFromMaster(), and CmSetValueKey().

◆ CmpUnlockRegistry()

VOID NTAPI CmpUnlockRegistry ( VOID  )

Definition at line 2081 of file cmsysini.c.

2082{
2083 /* Sanity check */
2085
2086 /* Check if we should flush the registry */
2088 {
2089 /* The registry should be exclusively locked for this */
2091
2092 /* Flush the registry */
2095 }
2096
2097 /* Release the lock and leave the critical region */
2100}
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK()
Definition: cm_x.h:80
BOOLEAN NTAPI CmpDoFlushAll(IN BOOLEAN ForceFlush)
Definition: cmapi.c:81
BOOLEAN CmpFlushOnLockRelease
Definition: cmsysini.c:25
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119

Referenced by _Function_class_(), CmDeleteKey(), CmDeleteValueKey(), CmEnumerateKey(), CmEnumerateValueKey(), CmGetSystemDriverList(), CmLoadKey(), CmpDeleteKeyObject(), CmpParseKey(), CmpQueryKeyName(), CmpSecurityMethod(), CmQueryKey(), CmQueryValueKey(), CmSaveKey(), CmSaveMergedKeys(), CmSetValueKey(), CmShutdownSystem(), CmUnloadKey(), NtFlushKey(), NtInitializeRegistry(), NtQueryOpenSubKeys(), and NtUnloadKey2().

◆ CmShutdownSystem()

VOID NTAPI CmShutdownSystem ( VOID  )

Definition at line 2171 of file cmsysini.c.

2172{
2173 PLIST_ENTRY ListEntry;
2174 PCMHIVE Hive;
2175
2176 /* Kill the workers */
2178
2179 /* Flush all hives */
2182
2183 /* Close all hive files */
2184 ListEntry = CmpHiveListHead.Flink;
2185 while (ListEntry != &CmpHiveListHead)
2186 {
2187 Hive = CONTAINING_RECORD(ListEntry, CMHIVE, HiveList);
2188
2189 CmpCloseHiveFiles(Hive);
2190
2191 ListEntry = ListEntry->Flink;
2192 }
2193
2194 /*
2195 * As we flushed all the hives on the disk,
2196 * tell the system we do not want any further
2197 * registry flushing or syncing at this point
2198 * since we are shutting down the registry anyway.
2199 */
2201
2203}
VOID NTAPI CmpShutdownWorkers(VOID)
Definition: cmlazy.c:437
BOOLEAN CmFirstTime
Definition: ntapi.c:17
VOID NTAPI CmpCloseHiveFiles(IN PCMHIVE Hive)
Definition: cminit.c:644

Referenced by PopGracefulShutdown().

Variable Documentation

◆ CmFirstTime

BOOLEAN CmFirstTime
extern

Definition at line 17 of file ntapi.c.

Referenced by CmShutdownSystem(), and NtInitializeRegistry().

◆ CmiVolatileHive

◆ CmpFlushOnLockRelease

BOOLEAN CmpFlushOnLockRelease

Definition at line 25 of file cmsysini.c.

Referenced by CmpUnlockRegistry().

◆ CmpFlushStarveWriters

LONG CmpFlushStarveWriters
extern

Definition at line 27 of file cmlazy.c.

Referenced by _Function_class_(), CmpLockRegistry(), and CmpLockRegistryExclusive().

◆ CmpHiveListHead

LIST_ENTRY CmpHiveListHead

◆ CmpKeyObjectType

◆ CmpLoadWorkerEvent

KEVENT CmpLoadWorkerEvent

Definition at line 21 of file cmsysini.c.

Referenced by _Function_class_(), and CmpInitializeHiveList().

◆ CmpLoadWorkerIncrement

LONG CmpLoadWorkerIncrement

Definition at line 22 of file cmsysini.c.

Referenced by _Function_class_(), and CmpInitializeHiveList().

◆ CmpNoVolatileCreates

BOOLEAN CmpNoVolatileCreates

Definition at line 34 of file cmsysini.c.

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

◆ CmpNoWrite

◆ CmpProfileLoaded

BOOLEAN CmpProfileLoaded

Definition at line 33 of file cmsysini.c.

Referenced by CmLoadKey().

◆ CmpRegistryLock

◆ CmpRegistryLockCaller

PVOID CmpRegistryLockCaller

Definition at line 24 of file cmsysini.c.

Referenced by CmpLockRegistryExclusive().

◆ CmpRegistryLockCallerCaller

PVOID CmpRegistryLockCallerCaller

Definition at line 24 of file cmsysini.c.

Referenced by CmpLockRegistryExclusive().

◆ CmpSelfHealQueueListHead

LIST_ENTRY CmpSelfHealQueueListHead

Definition at line 20 of file cmsysini.c.

Referenced by CmInitSystem1().

◆ CmpSelfHealQueueLock

KGUARDED_MUTEX CmpSelfHealQueueLock

Definition at line 19 of file cmsysini.c.

Referenced by CmInitSystem1().

◆ CmpSpecialBootCondition

BOOLEAN CmpSpecialBootCondition

Definition at line 26 of file cmsysini.c.

Referenced by CmFlushKey(), and CmpInitializeHiveList().

◆ CmpSystemProcess

PEPROCESS CmpSystemProcess

Definition at line 23 of file cmsysini.c.

Referenced by CmInitSystem1().

◆ CmpTraceLevel

ULONG CmpTraceLevel = 0

Definition at line 35 of file cmsysini.c.

◆ CmpWasSetupBoot

BOOLEAN CmpWasSetupBoot

Definition at line 32 of file cmsysini.c.

Referenced by CmLoadKey(), and CmpCmdInit().

◆ HvShutdownComplete

BOOLEAN HvShutdownComplete = FALSE

Definition at line 36 of file cmsysini.c.

Referenced by CmpInitHiveFromFile(), and CmShutdownSystem().