ReactOS 0.4.15-dev-7788-g1ad9096
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 1258 of file cmsysini.c.

1262{
1263 WCHAR FileBuffer[64], RegBuffer[64];
1264 PCWSTR ConfigPath;
1265 UNICODE_STRING TempName, FileName, RegName;
1266 ULONG i, ErrorResponse, WorkerCount, Length;
1267 USHORT FileStart;
1268 ULONG PrimaryDisposition, SecondaryDisposition, ClusterSize;
1269 PCMHIVE CmHive;
1270 HANDLE PrimaryHandle = NULL, AlternateHandle = NULL;
1272 PVOID ErrorParameters;
1273 BOOLEAN HasDiverged;
1274 PAGED_CODE();
1275
1276 /* Get the hive index, make sure it makes sense */
1277 i = PtrToUlong(StartContext);
1279
1280 /* We were started */
1282
1283 /* Build the file name and registry name strings */
1284 RtlInitEmptyUnicodeString(&FileName, FileBuffer, sizeof(FileBuffer));
1285 RtlInitEmptyUnicodeString(&RegName, RegBuffer, sizeof(RegBuffer));
1286
1287 /* Now build the system root path */
1288 ConfigPath = CmpGetRegistryPath();
1289 RtlInitUnicodeString(&TempName, ConfigPath);
1291 FileStart = FileName.Length;
1292
1293 /* And build the registry root path */
1294 RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
1295 RtlAppendUnicodeStringToString(&RegName, &TempName);
1296
1297 /* Build the base name */
1298 RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
1299 RtlAppendUnicodeStringToString(&RegName, &TempName);
1300
1301 /* Check if this is a child of the root */
1302 if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
1303 {
1304 /* Then setup the whole name */
1306 RtlAppendUnicodeStringToString(&RegName, &TempName);
1307 }
1308
1309 /* Now add the rest of the file name */
1311 FileName.Length = FileStart;
1313 if (!CmpMachineHiveList[i].CmHive)
1314 {
1315 /* We need to allocate a new hive structure */
1317
1318 /* Load the hive file */
1320 CmpMachineHiveList[i].HHiveFlags,
1321 &CmHive,
1324 if (!NT_SUCCESS(Status) ||
1325 (!CmpShareSystemHives && !CmHive->FileHandles[HFILE_TYPE_LOG]))
1326 {
1327 /*
1328 * We failed, or could not get a log file (unless
1329 * the hive is shared), raise a hard error.
1330 */
1331 ErrorParameters = &FileName;
1333 1,
1334 1,
1335 (PULONG_PTR)&ErrorParameters,
1336 OptionOk,
1337 &ErrorResponse);
1338 }
1339
1340 /* Set the hive flags and newly allocated hive pointer */
1341 CmHive->Flags = CmpMachineHiveList[i].CmHiveFlags;
1342 CmpMachineHiveList[i].CmHive2 = CmHive;
1343 }
1344 else
1345 {
1346 /* We already have a hive, is it volatile? */
1347 CmHive = CmpMachineHiveList[i].CmHive;
1348 if (!(CmHive->Hive.HiveFlags & HIVE_VOLATILE))
1349 {
1350 /* It's now, open the hive file and log */
1352 L".ALT",
1353 &PrimaryHandle,
1354 &AlternateHandle,
1355 &PrimaryDisposition,
1356 &SecondaryDisposition,
1357 TRUE,
1358 TRUE,
1359 FALSE,
1360 &ClusterSize);
1361 if (!NT_SUCCESS(Status) || !AlternateHandle)
1362 {
1363 /* Couldn't open the hive or its alternate file, raise a hard error */
1364 ErrorParameters = &FileName;
1366 1,
1367 1,
1368 (PULONG_PTR)&ErrorParameters,
1369 OptionOk,
1370 &ErrorResponse);
1371
1372 /* And bugcheck for posterity's sake */
1373 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 9, 0, i, Status);
1374 }
1375
1376 /* Save the file handles. This should remove our sync hacks */
1377 /*
1378 * FIXME: Any hive that relies on the alternate hive for recovery purposes
1379 * will only get an alternate hive. As a result, the LOG file would never
1380 * get synced each time a write is done to the hive. In the future it would
1381 * be best to adapt the code so that a primary hive can use a LOG and ALT
1382 * hives at the same time.
1383 */
1384 CmHive->FileHandles[HFILE_TYPE_ALTERNATE] = AlternateHandle;
1385 CmHive->FileHandles[HFILE_TYPE_PRIMARY] = PrimaryHandle;
1386
1387 /* Allow lazy flushing since the handles are there -- remove sync hacks */
1388 //ASSERT(CmHive->Hive.HiveFlags & HIVE_NOLAZYFLUSH);
1389 CmHive->Hive.HiveFlags &= ~HIVE_NOLAZYFLUSH;
1390
1391 /* Get the real size of the hive */
1392 Length = CmHive->Hive.Storage[Stable].Length + HBLOCK_SIZE;
1393
1394 /* Check if the cluster size doesn't match */
1395 if (CmHive->Hive.Cluster != ClusterSize)
1396 {
1397 DPRINT1("FIXME: Support for CmHive->Hive.Cluster (%lu) != ClusterSize (%lu) is unimplemented!\n",
1398 CmHive->Hive.Cluster, ClusterSize);
1399 }
1400
1401 /* Set the file size */
1402 DPRINT("FIXME: Should set file size: %lu\n", Length);
1403 //if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length))
1404 //{
1405 /* This shouldn't fail */
1406 //ASSERT(FALSE);
1407 //}
1408
1409 /* FreeLdr has recovered the hive with a log, we must do a flush */
1410 if (CmHive->Hive.BaseBlock->BootRecover == HBOOT_BOOT_RECOVERED_BY_HIVE_LOG)
1411 {
1412 DPRINT1("FreeLdr recovered the hive (hive 0x%p)\n", CmHive);
1413 RtlSetAllBits(&CmHive->Hive.DirtyVector);
1414 CmHive->Hive.DirtyCount = CmHive->Hive.DirtyVector.SizeOfBitMap;
1415 HvSyncHive((PHHIVE)CmHive);
1416 }
1417 else
1418 {
1419 /*
1420 * Check whether the both primary and alternate hives are the same,
1421 * or that the primary or alternate were created for the first time.
1422 * Do a write against the alternate hive in these cases.
1423 */
1425 CmHive,
1426 AlternateHandle,
1427 &HasDiverged);
1428 if (HasDiverged ||
1429 PrimaryDisposition == FILE_CREATED ||
1430 SecondaryDisposition == FILE_CREATED)
1431 {
1432 if (!HvWriteAlternateHive((PHHIVE)CmHive))
1433 {
1434 DPRINT1("Failed to write to alternate hive\n");
1435 goto Exit;
1436 }
1437 }
1438 }
1439
1440 /* Finally, set our allocated hive to the same hive we've had */
1441 CmpMachineHiveList[i].CmHive2 = CmHive;
1442 ASSERT(CmpMachineHiveList[i].CmHive == CmpMachineHiveList[i].CmHive2);
1443 }
1444 }
1445
1446Exit:
1447 /* We're done */
1449
1450 /* Check if we're the last worker */
1452 if (WorkerCount == CM_NUMBER_OF_MACHINE_HIVES)
1453 {
1454 /* Signal the event */
1456 }
1457
1458 /* Kill the thread */
1460}
#define PAGED_CODE()
unsigned char BOOLEAN
#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:67
#define CM_NUMBER_OF_MACHINE_HIVES
Definition: cm.h:118
HIVE_LIST_ENTRY CmpMachineHiveList[]
Definition: cmdata.c:41
BOOLEAN CmpShareSystemHives
Definition: cmdata.c:58
#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:1210
static PCWSTR CmpGetRegistryPath(VOID)
Definition: cmsysini.c:1169
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 NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define PtrToUlong(u)
Definition: config.h:107
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
struct _FileName FileName
Definition: fatprocs.h:896
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
NTSYSAPI void WINAPI RtlSetAllBits(PRTL_BITMAP)
#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:1145
#define STATUS_CANNOT_LOAD_REGISTRY_FILE
Definition: ntstatus.h:668
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
static void Exit(void)
Definition: sock.c:1330
Definition: cmlib.h:316
BOOLEAN ThreadStarted
Definition: cm.h:416
PCMHIVE CmHive
Definition: cm.h:411
PCMHIVE CmHive2
Definition: cm.h:414
BOOLEAN Allocate
Definition: cm.h:417
BOOLEAN ThreadFinished
Definition: cm.h:415
ULONG CmHiveFlags
Definition: cm.h:413
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
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ CmGetSystemDriverList()

PUNICODE_STRING *NTAPI CmGetSystemDriverList ( VOID  )

Definition at line 1836 of file cmsysini.c.

1837{
1838 LIST_ENTRY DriverList;
1841 PCM_KEY_BODY KeyBody;
1842 PHHIVE Hive;
1843 HCELL_INDEX RootCell, ControlCell;
1846 PLIST_ENTRY NextEntry;
1847 ULONG i;
1848 PUNICODE_STRING* ServicePath = NULL;
1849 BOOLEAN Success, AutoSelect;
1851 PAGED_CODE();
1852
1853 /* Initialize the driver list */
1854 InitializeListHead(&DriverList);
1855
1856 /* Open the system hive key */
1857 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System");
1859 &KeyName,
1861 NULL,
1862 NULL);
1864 if (!NT_SUCCESS(Status)) return NULL;
1865
1866 /* Reference the key object to get the root hive/cell to access directly */
1870 KernelMode,
1871 (PVOID*)&KeyBody,
1872 NULL);
1873 if (!NT_SUCCESS(Status))
1874 {
1875 /* Fail */
1877 return NULL;
1878 }
1879
1880 /* Do all this under the registry lock */
1882
1883 /* Get the hive and key cell */
1884 Hive = KeyBody->KeyControlBlock->KeyHive;
1885 RootCell = KeyBody->KeyControlBlock->KeyCell;
1886
1887 /* Open the current control set key */
1888 RtlInitUnicodeString(&KeyName, L"Current");
1889 ControlCell = CmpFindControlSet(Hive, RootCell, &KeyName, &AutoSelect);
1890 if (ControlCell == HCELL_NIL) goto EndPath;
1891
1892 /* Find all system drivers */
1893 Success = CmpFindDrivers(Hive, ControlCell, SystemLoad, NULL, &DriverList);
1894 if (!Success) goto EndPath;
1895
1896 /* Sort by group/tag */
1897 if (!CmpSortDriverList(Hive, ControlCell, &DriverList)) goto EndPath;
1898
1899 /* Remove circular dependencies (cycles) and sort */
1900 if (!CmpResolveDriverDependencies(&DriverList)) goto EndPath;
1901
1902 /* Loop the list to count drivers */
1903 for (i = 0, NextEntry = DriverList.Flink;
1904 NextEntry != &DriverList;
1905 i++, NextEntry = NextEntry->Flink);
1906
1907 /* Allocate the array */
1908 ServicePath = ExAllocatePool(NonPagedPool, (i + 1) * sizeof(PUNICODE_STRING));
1909 if (!ServicePath) KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1910
1911 /* Loop the driver list */
1912 for (i = 0, NextEntry = DriverList.Flink;
1913 NextEntry != &DriverList;
1914 i++, NextEntry = NextEntry->Flink)
1915 {
1916 /* Get the entry */
1918
1919 /* Allocate the path for the caller */
1920 ServicePath[i] = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING));
1921 if (!ServicePath[i])
1922 {
1923 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1924 }
1925
1926 /* Duplicate the registry path */
1928 &DriverEntry->RegistryPath,
1929 ServicePath[i]);
1930 if (!NT_SUCCESS(Status))
1931 {
1932 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1933 }
1934 }
1935
1936 /* Terminate the list */
1937 ServicePath[i] = NULL;
1938
1939EndPath:
1940 /* Free the driver list if we had one */
1941 if (!IsListEmpty(&DriverList)) CmpFreeDriverList(Hive, &DriverList);
1942
1943 /* Unlock the registry */
1945
1946 /* Close the key handle and dereference the object, then return the path */
1947 ObDereferenceObject(KeyBody);
1949 return ServicePath;
1950}
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:1954
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:2053
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
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
#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:34
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:1023
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
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
Definition: arc.h:246
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:234
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:2699
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 1618 of file cmsysini.c.

1619{
1624 PCMHIVE HardwareHive;
1626 PAGED_CODE();
1627
1628 /* Check if this is PE-boot */
1629 if (InitIsWinPEMode)
1630 {
1631 /* Set the registry in PE mode and load the system hives in shared mode */
1634 }
1635
1636 /* Initialize the hive list and lock */
1640
1641 /* Initialize registry lock */
1643
1644 /* Initialize the cache */
1646
1647 /* Initialize allocation and delayed dereferencing */
1651
1652 /* Initialize callbacks */
1654
1655 /* Initialize self healing */
1658
1659 /* Save the current process and lock the registry */
1661
1662 /* Create the key object types */
1664 if (!NT_SUCCESS(Status))
1665 {
1666 /* Bugcheck */
1667 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 1, Status, 0);
1668 }
1669
1670 /* Build the master hive */
1675 NULL,
1676 NULL,
1677 NULL,
1678 NULL,
1679 NULL,
1680 NULL,
1682 if (!NT_SUCCESS(Status))
1683 {
1684 /* Bugcheck */
1685 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 2, Status, 0);
1686 }
1687
1688 /* Create the \REGISTRY key node */
1689 if (!CmpCreateRegistryRoot())
1690 {
1691 /* Bugcheck */
1692 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 3, 0, 0);
1693 }
1694
1695 /* Create the default security descriptor */
1697
1698 /* Create '\Registry\Machine' key */
1699 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE");
1701 &KeyName,
1703 NULL,
1708 0,
1709 NULL,
1710 0,
1711 NULL);
1712 if (!NT_SUCCESS(Status))
1713 {
1714 /* Bugcheck */
1715 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 5, Status, 0);
1716 }
1717
1718 /* Close the handle */
1720
1721 /* Create '\Registry\User' key */
1722 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\USER");
1724 &KeyName,
1726 NULL,
1731 0,
1732 NULL,
1733 0,
1734 NULL);
1735 if (!NT_SUCCESS(Status))
1736 {
1737 /* Bugcheck */
1738 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 6, Status, 0);
1739 }
1740
1741 /* Close the handle */
1743
1744 /* After this point, do not allow creating keys in the master hive */
1746
1747 /* Initialize the system hive */
1749 {
1750 /* Bugcheck */
1751 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 7, 0, 0);
1752 }
1753
1754 /* Create the 'CurrentControlSet' link */
1756 if (!NT_SUCCESS(Status))
1757 {
1758 /* Bugcheck */
1759 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 8, Status, 0);
1760 }
1761
1762 /* Create the hardware hive */
1763 Status = CmpInitializeHive(&HardwareHive,
1767 NULL,
1768 NULL,
1769 NULL,
1770 NULL,
1771 NULL,
1772 NULL,
1774 if (!NT_SUCCESS(Status))
1775 {
1776 /* Bugcheck */
1777 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 11, Status, 0);
1778 }
1779
1780 /* Add the hive to the hive list */
1781 CmpMachineHiveList[0].CmHive = HardwareHive;
1782
1783 /* Attach it to the machine key */
1784 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE");
1786 NULL,
1787 HardwareHive,
1788 TRUE,
1790 if (!NT_SUCCESS(Status))
1791 {
1792 /* Bugcheck */
1793 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0);
1794 }
1795
1796 /* Add to HiveList key */
1797 CmpAddToHiveFileList(HardwareHive);
1798
1799 /* Free the security descriptor */
1801
1802 /* Fill out the Hardware key with the ARC Data from the Loader */
1804 if (!NT_SUCCESS(Status))
1805 {
1806 /* Bugcheck */
1807 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 13, Status, 0);
1808 }
1809
1810 /* Initialize machine-dependent information into the registry */
1812 if (!NT_SUCCESS(Status))
1813 {
1814 /* Bugcheck */
1815 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 14, Status, 0);
1816 }
1817
1818 /* Initialize volatile registry settings */
1820 if (!NT_SUCCESS(Status))
1821 {
1822 /* Bugcheck */
1823 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 15, Status, 0);
1824 }
1825
1826 /* Free the load options */
1828
1829 /* If we got here, all went well */
1830 return TRUE;
1831}
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
EX_PUSH_LOCK CmpHiveListHeadLock
Definition: cmdata.c:39
EX_PUSH_LOCK CmpLoadHiveLock
Definition: cmdata.c:39
BOOLEAN CmpMiniNTBoot
Definition: cmdata.c:60
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:1070
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:802
PEPROCESS CmpSystemProcess
Definition: cmsysini.c:23
NTSTATUS NTAPI CmpCreateObjectTypes(VOID)
Definition: cmsysini.c:980
NTSTATUS NTAPI CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:528
BOOLEAN NTAPI CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:869
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:1013
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:29
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KEY_WRITE
Definition: nt_native.h:1031
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 2076 of file cmsysini.c.

2078{
2079 ULONG Index1, Index2;
2080
2081 /* Sanity check */
2083
2084 /* Get hash indexes */
2085 Index1 = GET_HASH_INDEX(ConvKey1);
2086 Index2 = GET_HASH_INDEX(ConvKey2);
2087
2088 /* See which one is highest */
2089 if (Index1 < Index2)
2090 {
2091 /* Grab them in the proper order */
2094 }
2095 else
2096 {
2097 /* Grab the second one first, then the first */
2099 if (Index1 != Index2) CmpAcquireKcbLockExclusiveByKey(ConvKey1);
2100 }
2101}
FORCEINLINE VOID CmpAcquireKcbLockExclusiveByKey(IN ULONG ConvKey)
Definition: cm_x.h:126
#define GET_HASH_INDEX(ConvKey)
Definition: cm_x.h:24
#define CMP_ASSERT_REGISTRY_LOCK()
Definition: cm_x.h:52

Referenced by CmDeleteKey(), CmpCreateKeyControlBlock(), and NtUnloadKey2().

◆ 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:233
struct _CM_NOTIFY_BLOCK * NotifyBlock
Definition: cm.h:235
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object

Referenced by CmpCreateObjectTypes().

◆ CmpCreateControlSet()

NTSTATUS NTAPI CmpCreateControlSet ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 528 of file cmsysini.c.

529{
530 UNICODE_STRING ConfigName = RTL_CONSTANT_STRING(L"Control\\IDConfigDB");
531 UNICODE_STRING SelectName =
532 RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\Select");
535 CHAR ValueInfoBuffer[128];
537 WCHAR UnicodeBuffer[128];
538 HANDLE SelectHandle = NULL;
540 HANDLE ConfigHandle = NULL;
541 HANDLE ProfileHandle = NULL;
542 HANDLE ParentHandle = NULL;
543 ULONG ControlSet, HwProfile;
546 PLOADER_PARAMETER_EXTENSION LoaderExtension;
547 PAGED_CODE();
548
549 /* ReactOS Hack: Hard-code current to 001 for SetupLdr */
550 if (LoaderBlock->RegistryBase == NULL)
551 {
552 /* Build the ControlSet001 key */
554 L"\\Registry\\Machine\\System\\ControlSet001");
556 &KeyName,
558 NULL,
559 NULL);
563 0,
564 NULL,
565 0,
566 &Disposition);
567 if (!NT_SUCCESS(Status))
568 {
569 DPRINT1("Failed to create ControlSet001 key: 0x%lx\n", Status);
570 goto Cleanup;
571 }
572
573 /* Create the Hardware Profile keys */
575 if (!NT_SUCCESS(Status))
576 {
577 DPRINT1("Failed to create Hardware profile keys: 0x%lx\n", Status);
578 goto Cleanup;
579 }
580
581 /* Use hard-coded setting */
582 ControlSet = 1;
583 }
584 else
585 {
586 /* Open the select key */
588 &SelectName,
590 NULL,
591 NULL);
592 Status = NtOpenKey(&SelectHandle, KEY_READ, &ObjectAttributes);
593 if (!NT_SUCCESS(Status))
594 {
595 DPRINT1("Failed to open select key: 0x%lx\n", Status);
596 goto Cleanup;
597 }
598
599 /* Open the current value */
600 RtlInitUnicodeString(&KeyName, L"Current");
601 Status = NtQueryValueKey(SelectHandle,
602 &KeyName,
604 ValueInfoBuffer,
605 sizeof(ValueInfoBuffer),
606 &ResultLength);
607 if (!NT_SUCCESS(Status))
608 {
609 DPRINT1("Failed to open the Current value: 0x%lx\n", Status);
610 goto Cleanup;
611 }
612
613 /* Get the actual value pointer, and get the control set ID */
614 ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer;
615 ControlSet = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset);
616 }
617
618 /* Create the current control set key */
620 L"\\Registry\\Machine\\System\\CurrentControlSet");
622 &KeyName,
624 NULL,
625 NULL);
629 0,
630 NULL,
632 &Disposition);
633 if (!NT_SUCCESS(Status))
634 goto Cleanup;
635
636 /* Sanity check */
638
639 /* Initialize the target link name */
640 Status = RtlStringCbPrintfW(UnicodeBuffer, sizeof(UnicodeBuffer),
641 L"\\Registry\\Machine\\System\\ControlSet%03ld",
642 ControlSet);
643 if (!NT_SUCCESS(Status))
644 goto Cleanup;
645
646 RtlInitUnicodeString(&KeyName, UnicodeBuffer);
647
648 /* Set the value */
651 0,
652 REG_LINK,
653 KeyName.Buffer,
654 KeyName.Length);
655 if (!NT_SUCCESS(Status))
656 goto Cleanup;
657
658 /* Get the configuration database key */
660 &ConfigName,
662 KeyHandle,
663 NULL);
664 Status = NtOpenKey(&ConfigHandle, KEY_READ, &ObjectAttributes);
665
666 /* Check if we don't have one */
667 if (!NT_SUCCESS(Status))
668 {
669 /* Cleanup and exit */
671 goto Cleanup;
672 }
673
674 /* ReactOS Hack: Hard-code current to 001 for SetupLdr */
675 if (LoaderBlock->RegistryBase == NULL)
676 {
677 HwProfile = 0;
678 }
679 else
680 {
681 /* Now get the current config */
682 RtlInitUnicodeString(&KeyName, L"CurrentConfig");
683 Status = NtQueryValueKey(ConfigHandle,
684 &KeyName,
686 ValueInfoBuffer,
687 sizeof(ValueInfoBuffer),
688 &ResultLength);
689
690 /* Set pointer to buffer */
691 ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer;
692
693 /* Check if we failed or got a non DWORD-value */
694 if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_DWORD))
695 {
697 goto Cleanup;
698 }
699
700 /* Get the hadware profile */
701 HwProfile = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset);
702 }
703
704 /* Open the hardware profile key */
706 L"\\Registry\\Machine\\System\\CurrentControlSet"
707 L"\\Hardware Profiles");
709 &KeyName,
711 NULL,
712 NULL);
713 Status = NtOpenKey(&ParentHandle, KEY_READ, &ObjectAttributes);
714 if (!NT_SUCCESS(Status))
715 {
716 /* Exit and clean up */
718 goto Cleanup;
719 }
720
721 /* Build the profile name */
722 RtlStringCbPrintfW(UnicodeBuffer, sizeof(UnicodeBuffer),
723 L"%04ld", HwProfile);
724 RtlInitUnicodeString(&KeyName, UnicodeBuffer);
725
726 /* Open the associated key */
728 &KeyName,
730 ParentHandle,
731 NULL);
732 Status = NtOpenKey(&ProfileHandle,
735 if (!NT_SUCCESS(Status))
736 {
737 /* Cleanup and exit */
739 goto Cleanup;
740 }
741
742 /* Check if we have a loader block extension */
743 LoaderExtension = LoaderBlock->Extension;
744 if (LoaderExtension)
745 {
746 DPRINT("ReactOS doesn't support NTLDR Profiles yet!\n");
747 }
748
749 /* Create the current hardware profile key */
751 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
752 L"Hardware Profiles\\Current");
754 &KeyName,
756 NULL,
757 NULL);
761 0,
762 NULL,
764 &Disposition);
765 if (NT_SUCCESS(Status))
766 {
767 /* Sanity check */
769
770 /* Create the profile name */
771 RtlStringCbPrintfW(UnicodeBuffer, sizeof(UnicodeBuffer),
772 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
773 L"Hardware Profiles\\%04ld",
774 HwProfile);
775 RtlInitUnicodeString(&KeyName, UnicodeBuffer);
776
777 /* Set it */
780 0,
781 REG_LINK,
782 KeyName.Buffer,
783 KeyName.Length);
784 }
785
787
788Cleanup:
789 /* Close every opened handle */
790 if (SelectHandle) NtClose(SelectHandle);
792 if (ConfigHandle) NtClose(ConfigHandle);
793 if (ProfileHandle) NtClose(ProfileHandle);
794 if (ParentHandle) NtClose(ParentHandle);
795
796 DPRINT("CmpCreateControlSet() done\n");
797 return Status;
798}
UNICODE_STRING CmSymbolicLinkValueName
Definition: cmdata.c:52
static NTSTATUS CmpCreateHardwareProfile(HANDLE ControlSetHandle)
Definition: cmsysini.c:456
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:1181
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_OPTION_CREATE_LINK
Definition: nt_native.h:1063
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:1084
#define REG_LINK
Definition: nt_native.h:1500
#define KEY_CREATE_LINK
Definition: nt_native.h:1021
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
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
#define REG_DWORD
Definition: sdbapi.c:596
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
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:3776
char CHAR
Definition: xmlstorage.h:175

Referenced by CmInitSystem1().

◆ CmpCreateHardwareProfile()

static NTSTATUS CmpCreateHardwareProfile ( HANDLE  ControlSetHandle)
static

Definition at line 456 of file cmsysini.c.

457{
460 HANDLE ProfilesHandle = NULL;
461 HANDLE ProfileHandle = NULL;
464
465 DPRINT("CmpCreateHardwareProfile()\n");
466
467 /* Create the Hardware Profiles key */
468 RtlInitUnicodeString(&KeyName, L"Hardware Profiles");
470 &KeyName,
472 ControlSetHandle,
473 NULL);
474 Status = NtCreateKey(&ProfilesHandle,
477 0,
478 NULL,
479 0,
480 &Disposition);
481 if (!NT_SUCCESS(Status))
482 {
483 DPRINT1("Creating the Hardware Profile key failed\n");
484 goto done;
485 }
486
487 /* Sanity check */
489
490 /* Create the 0000 key */
493 &KeyName,
495 ProfilesHandle,
496 NULL);
497 Status = NtCreateKey(&ProfileHandle,
500 0,
501 NULL,
502 0,
503 &Disposition);
504 if (!NT_SUCCESS(Status))
505 {
506 DPRINT1("Creating the Hardware Profile\\0000 key failed\n");
507 goto done;
508 }
509
510 /* Sanity check */
512
513done:
514 if (ProfilesHandle)
515 NtClose(ProfilesHandle);
516
517 if (ProfileHandle)
518 NtClose(ProfileHandle);
519
520 DPRINT("CmpCreateHardwareProfile() done\n");
521
522 return Status;
523}

Referenced by CmpCreateControlSet().

◆ CmpCreateObjectTypes()

NTSTATUS NTAPI CmpCreateObjectTypes ( VOID  )

Definition at line 980 of file cmsysini.c.

981{
982 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
984 GENERIC_MAPPING CmpKeyMapping = {KEY_READ,
985 KEY_WRITE,
988 PAGED_CODE();
989
990 /* Initialize the Key object type */
991 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
993 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
994 ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(CM_KEY_BODY);
995 ObjectTypeInitializer.GenericMapping = CmpKeyMapping;
996 ObjectTypeInitializer.PoolType = PagedPool;
997 ObjectTypeInitializer.ValidAccessMask = KEY_ALL_ACCESS;
998 ObjectTypeInitializer.UseDefaultObject = TRUE;
999 ObjectTypeInitializer.DeleteProcedure = CmpDeleteKeyObject;
1000 ObjectTypeInitializer.ParseProcedure = CmpParseKey;
1001 ObjectTypeInitializer.SecurityProcedure = CmpSecurityMethod;
1002 ObjectTypeInitializer.QueryNameProcedure = CmpQueryKeyName;
1003 ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject;
1004 ObjectTypeInitializer.SecurityRequired = TRUE;
1005 ObjectTypeInitializer.InvalidAttributes = OBJ_EXCLUSIVE | OBJ_PERMANENT;
1006
1007 /* Create it */
1008 return ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmpKeyObjectType);
1009}
struct NameRec_ * Name
Definition: cdprocs.h:460
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 OBJ_EXCLUSIVE
Definition: winternl.h:227
#define OBJ_PERMANENT
Definition: winternl.h:226
#define KEY_EXECUTE
Definition: nt_native.h:1037
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
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 1070 of file cmsysini.c.

1071{
1075 HCELL_INDEX RootIndex;
1077 PCM_KEY_NODE KeyCell;
1080 PAGED_CODE();
1081
1082 /* Setup the root node */
1083 if (!CmpCreateRootNode(&CmiVolatileHive->Hive, L"REGISTRY", &RootIndex))
1084 {
1085 /* We failed */
1086 return FALSE;
1087 }
1088
1089 /* Create '\Registry' key. */
1090 RtlInitUnicodeString(&KeyName, L"\\REGISTRY");
1093 &KeyName,
1095 NULL,
1100 KernelMode,
1101 NULL,
1102 sizeof(CM_KEY_BODY),
1103 0,
1104 0,
1105 (PVOID*)&RootKey);
1107 if (!NT_SUCCESS(Status)) return FALSE;
1108
1109 /* Sanity check, and get the key cell */
1110 ASSERT((&CmiVolatileHive->Hive)->ReleaseCellRoutine == NULL);
1111 KeyCell = (PCM_KEY_NODE)HvGetCell(&CmiVolatileHive->Hive, RootIndex);
1112 if (!KeyCell) return FALSE;
1113
1114 /* Create the KCB */
1115 RtlInitUnicodeString(&KeyName, L"\\REGISTRY");
1117 RootIndex,
1118 KeyCell,
1119 NULL,
1120 0,
1121 &KeyName);
1122 if (!Kcb)
1123 {
1125 return FALSE;
1126 }
1127
1128 /* Initialize the object */
1129 RootKey->KeyControlBlock = Kcb;
1130 RootKey->Type = CM_KEY_BODY_TYPE;
1131 RootKey->NotifyBlock = NULL;
1132 RootKey->ProcessID = PsGetCurrentProcessId();
1133 RootKey->KcbLocked = FALSE;
1134
1135 /* Link with KCB */
1137
1138 /* Insert the key into the namespace */
1140 NULL,
1142 0,
1143 NULL,
1145 if (!NT_SUCCESS(Status))
1146 {
1148 return FALSE;
1149 }
1150
1151 /* Reference the key again so that we never lose it */
1153 KEY_READ,
1154 NULL,
1155 KernelMode,
1156 (PVOID*)&RootKey,
1157 NULL);
1158 if (!NT_SUCCESS(Status))
1159 {
1161 return FALSE;
1162 }
1163
1164 /* Completely sucessful */
1165 return TRUE;
1166}
HANDLE CmpRegistryRootHandle
Definition: cmdata.c:69
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:452
BOOLEAN NTAPI CmpCreateRootNode(IN PHHIVE Hive, IN PCWSTR Name, OUT PHCELL_INDEX Index)
Definition: cmsysini.c:1014
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 1014 of file cmsysini.c.

1017{
1019 PCM_KEY_NODE KeyCell;
1020 PAGED_CODE();
1021
1022 /* Initialize the node name and allocate it */
1024 *Index = HvAllocateCell(Hive,
1026 CmpNameSize(Hive, &KeyName),
1027 Stable,
1028 HCELL_NIL);
1029 if (*Index == HCELL_NIL) return FALSE;
1030
1031 /* Set the cell index and get the data */
1032 Hive->BaseBlock->RootCell = *Index;
1033 KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, *Index);
1034 if (!KeyCell) return FALSE;
1035
1036 /* Setup the cell */
1038 KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
1040 KeyCell->Parent = HCELL_NIL;
1041 KeyCell->SubKeyCounts[Stable] = 0;
1042 KeyCell->SubKeyCounts[Volatile] = 0;
1043 KeyCell->SubKeyLists[Stable] = HCELL_NIL;
1044 KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
1045 KeyCell->ValueList.Count = 0;
1046 KeyCell->ValueList.List = HCELL_NIL;
1047 KeyCell->Security = HCELL_NIL;
1048 KeyCell->Class = HCELL_NIL;
1049 KeyCell->ClassLength = 0;
1050 KeyCell->MaxNameLen = 0;
1051 KeyCell->MaxClassLen = 0;
1052 KeyCell->MaxValueNameLen = 0;
1053 KeyCell->MaxValueDataLen = 0;
1054
1055 /* Copy the name (this will also set the length) */
1056 KeyCell->NameLength = CmpCopyName(Hive, KeyCell->Name, &KeyName);
1057
1058 /* Check if the name was compressed and set the flag if so */
1059 if (KeyCell->NameLength < KeyName.Length)
1060 KeyCell->Flags |= KEY_COMP_NAME;
1061
1062 /* Return success */
1063 HvReleaseCell(Hive, *Index);
1064 return TRUE;
1065}
#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:455
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:1967
BOOLEAN KcbLocked
Definition: cm.h:240
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 1169 of file cmsysini.c.

1170{
1171 PCWSTR ConfigPath;
1172
1173 /* Check if we are booted in setup */
1174 if (!ExpInTextModeSetup)
1175 {
1176 ConfigPath = L"\\SystemRoot\\System32\\Config\\";
1177 }
1178 else
1179 {
1180 ConfigPath = L"\\SystemRoot\\";
1181 }
1182
1183 DPRINT1("CmpGetRegistryPath: ConfigPath = '%S'\n", ConfigPath);
1184
1185 return ConfigPath;
1186}
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 1210 of file cmsysini.c.

1215{
1216 PHHIVE Hive, AlternateHive;
1218 PCMHIVE CmiAlternateHive;
1219
1220 /* Assume it has not diverged */
1221 *Diverged = FALSE;
1222
1223 /* Initialize the SYSTEM alternate hive */
1224 Status = CmpInitializeHive(&CmiAlternateHive,
1225 HINIT_FILE,
1226 0,
1228 NULL,
1229 AlternateHandle,
1230 NULL,
1231 NULL,
1232 NULL,
1233 FileName,
1235 if (!NT_SUCCESS(Status))
1236 {
1237 /* Assume it has diverged... */
1238 DPRINT1("Failed to initialize the alternate hive to check for diversion (Status 0x%lx)\n", Status);
1239 *Diverged = TRUE;
1240 return;
1241 }
1242
1243 /*
1244 * Check the timestamp of both hives. If they do not match they
1245 * have diverged, the kernel has to synchronize the both hives.
1246 */
1247 Hive = &CmMainmHive->Hive;
1248 AlternateHive = &CmiAlternateHive->Hive;
1249 if (AlternateHive->BaseBlock->TimeStamp.QuadPart !=
1251 {
1252 *Diverged = TRUE;
1253 }
1254
1255 CmpDestroyHive(CmiAlternateHive);
1256}
#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:626
#define New(t)
Definition: rtf.h:1086
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:2741

Referenced by _Function_class_(), and CmpCmdHiveOpen().

◆ CmpInitializeHiveList()

VOID NTAPI CmpInitializeHiveList ( VOID  )

Definition at line 1464 of file cmsysini.c.

1465{
1466 WCHAR FileBuffer[64], RegBuffer[64];
1467 PCWSTR ConfigPath;
1468 UNICODE_STRING TempName, FileName, RegName;
1469 HANDLE Thread;
1471 ULONG i;
1472 USHORT RegStart;
1474
1475 PAGED_CODE();
1476
1477 /* Reenable hive writes now */
1478 CmpNoWrite = FALSE;
1479
1480 /* Build the file name and registry name strings */
1481 RtlInitEmptyUnicodeString(&FileName, FileBuffer, sizeof(FileBuffer));
1482 RtlInitEmptyUnicodeString(&RegName, RegBuffer, sizeof(RegBuffer));
1483
1484 /* Now build the system root path */
1485 ConfigPath = CmpGetRegistryPath();
1486 RtlInitUnicodeString(&TempName, ConfigPath);
1488
1489 /* And build the registry root path */
1490 RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
1491 RtlAppendUnicodeStringToString(&RegName, &TempName);
1492 RegStart = RegName.Length;
1493
1494 /* Setup the event to synchronize workers */
1496
1497 /* Enter special boot condition */
1499
1500 /* Create the SD for the root hives */
1502
1503 /* Loop every hive we care about */
1504 for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
1505 {
1506 /* Make sure the list is set up */
1508
1509 /* Load this root hive as volatile, if opened in shared mode */
1512
1513 /* Create a thread to handle this hive */
1516 NULL,
1517 0,
1518 NULL,
1519 CmpLoadHiveThread,
1520 UlongToPtr(i));
1521 if (NT_SUCCESS(Status))
1522 {
1523 /* We don't care about the handle -- the thread self-terminates */
1524 ZwClose(Thread);
1525 }
1526 else
1527 {
1528 /* Can't imagine this happening */
1529 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 9, 3, i, Status);
1530 }
1531 }
1532
1533 /* Make sure we've reached the end of the list */
1535
1536 /* Wait for hive loading to finish */
1538 Executive,
1539 KernelMode,
1540 FALSE,
1541 NULL);
1542
1543 /* Exit the special boot condition and make sure all workers completed */
1546
1547 /* Loop hives again */
1548 for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
1549 {
1550 /* Make sure the thread ran and finished */
1551 ASSERT(CmpMachineHiveList[i].ThreadFinished == TRUE);
1552 ASSERT(CmpMachineHiveList[i].ThreadStarted == TRUE);
1553
1554 /* Check if this was a new hive */
1555 if (!CmpMachineHiveList[i].CmHive)
1556 {
1557 /* Make sure we allocated something */
1558 ASSERT(CmpMachineHiveList[i].CmHive2 != NULL);
1559
1560 /* Build the base name */
1561 RegName.Length = RegStart;
1562 RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
1563 RtlAppendUnicodeStringToString(&RegName, &TempName);
1564
1565 /* Check if this is a child of the root */
1566 if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
1567 {
1568 /* Then setup the whole name */
1570 RtlAppendUnicodeStringToString(&RegName, &TempName);
1571 }
1572
1573 /* Now link the hive to its master */
1574 Status = CmpLinkHiveToMaster(&RegName,
1575 NULL,
1576 CmpMachineHiveList[i].CmHive2,
1579 if (Status != STATUS_SUCCESS)
1580 {
1581 /* Linking needs to work */
1582 KeBugCheckEx(CONFIG_LIST_FAILED, 11, Status, i, (ULONG_PTR)&RegName);
1583 }
1584
1585 /* Check if we had to allocate a new hive */
1587 {
1588 /* Sync the new hive */
1589 //HvSyncHive((PHHIVE)(CmpMachineHiveList[i].CmHive2));
1590 }
1591 }
1592
1593 /* Check if we created a new hive */
1594 if (CmpMachineHiveList[i].CmHive2)
1595 {
1596 /* Add to HiveList key */
1598 }
1599 }
1600
1601 /* Get rid of the SD */
1603
1604 /* Link SECURITY to SAM */
1605 CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM",
1606 L"\\Registry\\Machine\\SAM\\SAM");
1607
1608 /* Link S-1-5-18 to .Default */
1610 CmpLinkKeyToHive(L"\\Registry\\User\\S-1-5-18",
1611 L"\\Registry\\User\\.Default");
1613}
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:1339
@ 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:412
uint32_t ULONG_PTR
Definition: typedefs.h:65
@ Executive
Definition: ketypes.h:415

Referenced by CmpCmdInit().

◆ CmpInitializeSystemHive()

BOOLEAN NTAPI CmpInitializeSystemHive ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 869 of file cmsysini.c.

870{
871 static const UNICODE_STRING HiveName = RTL_CONSTANT_STRING(L"SYSTEM");
872 PVOID HiveBase;
880
881 PAGED_CODE();
882
883 /* Setup the ansi string */
884 RtlInitAnsiString(&LoadString, LoaderBlock->LoadOptions);
885
886 /* Allocate the unicode buffer */
887 Length = LoadString.Length * sizeof(WCHAR) + sizeof(UNICODE_NULL);
889 if (!Buffer)
890 {
891 /* Fail */
892 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 3, 1, (ULONG_PTR)LoaderBlock, 0);
893 }
894
895 /* Setup the unicode string */
896 RtlInitEmptyUnicodeString(&CmpLoadOptions, Buffer, (USHORT)Length);
897
898 /* Add the load options and null-terminate */
900 if (!NT_SUCCESS(Status))
901 {
902 return FALSE;
903 }
904
906 CmpLoadOptions.Length += sizeof(WCHAR);
907
908 /* Get the System Hive base address */
909 HiveBase = LoaderBlock->RegistryBase;
910
912 HiveBase ? HINIT_MEMORY : HINIT_CREATE,
915 HiveBase,
916 NULL,
917 NULL,
918 NULL,
919 NULL,
920 &HiveName,
922 if (!NT_SUCCESS(Status))
923 {
924 return FALSE;
925 }
926
927 /* Set the hive filename */
928 if (!RtlCreateUnicodeString(&SystemHive->FileFullPath, L"\\SystemRoot\\System32\\Config\\SYSTEM"))
929 return FALSE;
930
931 /* Load the system hive as volatile, if opened in shared mode */
932 if (HiveBase && CmpShareSystemHives)
934
935 /* Save the boot type */
937
938 /* Are we in self-healing mode? */
939 if (!CmSelfHeal)
940 {
941 /* Disable self-healing internally and check if boot type wanted it */
944 {
945 /* We're disabled, so bugcheck */
946 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,
947 3,
948 3,
950 0);
951 }
952 }
953
954 /* Create the default security descriptor */
956
957 /* Attach it to the system key */
958 /* Let CmpLinkHiveToMaster allocate a new hive if we got none from the LoaderBlock. */
959 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM");
961 NULL,
963 !HiveBase,
965
966 /* Free the security descriptor */
968 if (!NT_SUCCESS(Status)) return FALSE;
969
970 /* Add the hive to the hive list */
972
973 /* Success! */
974 return TRUE;
975}
PHHIVE SystemHive
Definition: registry.c:33
Definition: bufpool.h:45
ULONG CmpBootType
Definition: cmdata.c:62
BOOLEAN CmpSelfHeal
Definition: cmdata.c:64
BOOLEAN CmSelfHeal
Definition: cmdata.c:63
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:5819

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 802 of file cmsysini.c.

807{
810 CM_PARSE_CONTEXT ParseContext = {0};
812 PCM_KEY_BODY KeyBody;
813 PAGED_CODE();
814
815 /* Setup the object attributes */
817 LinkName,
821
822 /* Setup the parse context */
823 ParseContext.CreateLink = TRUE;
824 ParseContext.CreateOperation = TRUE;
825 ParseContext.ChildHive.KeyHive = &RegistryHive->Hive;
826
827 /* Check if we have a root keycell or if we need to create it */
828 if (Allocate)
829 {
830 /* Create it */
831 ParseContext.ChildHive.KeyCell = HCELL_NIL;
832 }
833 else
834 {
835 /* We have one */
836 ParseContext.ChildHive.KeyCell = RegistryHive->Hive.BaseBlock->RootCell;
837 }
838
839 /* Create the link node */
843 NULL,
845 (PVOID)&ParseContext,
846 &KeyHandle);
847 if (!NT_SUCCESS(Status)) return Status;
848
849 /* Mark the hive as clean */
850 RegistryHive->Hive.DirtyFlag = FALSE;
851
852 /* ReactOS Hack: Keep alive */
854 0,
857 (PVOID*)&KeyBody,
858 NULL);
860
861 /* Close the extra handle */
863 return STATUS_SUCCESS;
864}
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
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
PHHIVE KeyHive
Definition: cmdata.h:84
HCELL_INDEX KeyCell
Definition: cmdata.h:83
CM_KEY_REFERENCE ChildHive
Definition: cm.h:438
BOOLEAN CreateLink
Definition: cm.h:440
BOOLEAN CreateOperation
Definition: cm.h:441

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 2003 of file cmsysini.c.

2004{
2005 /* Lock the flusher. We should already be in a critical section */
2007 ASSERT((ExIsResourceAcquiredShared(Hive->FlusherLock) == 0) &&
2008 (ExIsResourceAcquiredExclusiveLite(Hive->FlusherLock) == 0));
2009 ExAcquireResourceExclusiveLite(Hive->FlusherLock, TRUE);
2010}
#define CMP_ASSERT_REGISTRY_LOCK_OR_LOADING(h)
Definition: cm_x.h:59
#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 2014 of file cmsysini.c.

2015{
2016 /* Lock the flusher. We should already be in a critical section */
2018 ASSERT((ExIsResourceAcquiredShared(Hive->FlusherLock) == 0) &&
2019 (ExIsResourceAcquiredExclusiveLite(Hive->FlusherLock) == 0));
2020 ExAcquireResourceSharedLite(Hive->FlusherLock, TRUE);
2021}
#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 1967 of file cmsysini.c.

1968{
1969 /* Enter a critical region */
1971
1972 /* Check if we have to starve writers */
1974 {
1975 /* Starve exlusive waiters */
1977 }
1978 else
1979 {
1980 /* Just grab the lock */
1982 }
1983}
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(), NtFlushKey(), and NtUnloadKey2().

◆ CmpLockRegistryExclusive()

VOID NTAPI CmpLockRegistryExclusive ( VOID  )

Definition at line 1954 of file cmsysini.c.

1955{
1956 /* Enter a critical region and lock the registry */
1959
1960 /* Sanity check */
1963}
PVOID CmpRegistryLockCallerCaller
Definition: cmsysini.c:24
PVOID CmpRegistryLockCaller
Definition: cmsysini.c:24
NTSYSAPI VOID NTAPI RtlGetCallersAddress(_Out_ PVOID *CallersAddress, _Out_ PVOID *CallersCaller)
Definition: except.c:22

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}
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:145
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:185
PUNICODE_STRING NTAPI CmpConstructName(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:897
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
#define STATUS_KEY_DELETED
Definition: ntstatus.h:613
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
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 2105 of file cmsysini.c.

2107{
2108 ULONG Index1, Index2;
2109
2110 /* Sanity check */
2112
2113 /* Get hash indexes */
2114 Index1 = GET_HASH_INDEX(ConvKey1);
2115 Index2 = GET_HASH_INDEX(ConvKey2);
2118
2119 /* See which one is highest */
2120 if (Index1 < Index2)
2121 {
2122 /* Grab them in the proper order */
2125 CmpReleaseKcbLockByKey(ConvKey2);
2126 CmpReleaseKcbLockByKey(ConvKey1);
2127 }
2128 else
2129 {
2130 /* Release the first one first, then the second */
2131 if (Index1 != Index2)
2132 {
2135 CmpReleaseKcbLockByKey(ConvKey1);
2136 }
2137 CmpReleaseKcbLockByKey(ConvKey2);
2138 }
2139}
#define GET_HASH_ENTRY(Table, ConvKey)
Definition: cm_x.h:26
FORCEINLINE VOID CmpReleaseKcbLockByKey(ULONG ConvKey)
Definition: cm_x.h:195
PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable
Definition: cmkcbncb.c:18
BOOLEAN NTAPI CmpTestRegistryLockExclusive(VOID)
Definition: cmsysini.c:1995
#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:1597

Referenced by CmDeleteKey(), CmpCreateKeyControlBlock(), CmUnloadKey(), and NtUnloadKey2().

◆ 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\\"
413 L"Control");
415 &KeyName,
417 NULL,
418 NULL);
420 if (!NT_SUCCESS(Status))
421 return Status;
422
423 /* Setup the value for the system start options */
424 RtlInitUnicodeString(&KeyName, L"SystemStartOptions");
426 &KeyName,
427 0,
428 REG_SZ,
431 if (!NT_SUCCESS(Status))
432 goto Quit;
433
434 /* Setup the value for the system boot device in ARC format */
435 RtlInitUnicodeString(&KeyName, L"SystemBootDevice");
436 RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->ArcBootDeviceName);
438 &KeyName,
439 0,
440 REG_SZ,
441 ValueName.Buffer,
442 ValueName.Length);
443
444 /* Free the temporary string */
446
447Quit:
448 /* Close the key and return */
450 return Status;
451}
#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)
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243

Referenced by CmInitSystem1().

◆ CmpSetVersionData()

VOID NTAPI CmpSetVersionData ( VOID  )

Definition at line 2179 of file cmsysini.c.

2180{
2186 ANSI_STRING TempString;
2187 HANDLE SoftwareKeyHandle = NULL;
2188 HANDLE MicrosoftKeyHandle = NULL;
2189 HANDLE WindowsNtKeyHandle = NULL;
2190 HANDLE CurrentVersionKeyHandle = NULL;
2191 WCHAR Buffer[128]; // Buffer large enough to contain a full ULONG in decimal
2192 // representation, and the full 'CurrentType' string.
2193
2194 /*
2195 * Open the 'HKLM\Software\Microsoft\Windows NT\CurrentVersion' key
2196 * (create the intermediate subkeys if needed).
2197 */
2198
2199 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SOFTWARE");
2201 &KeyName,
2203 NULL,
2204 NULL);
2205 Status = NtCreateKey(&SoftwareKeyHandle,
2208 0,
2209 NULL,
2210 0,
2211 NULL);
2212 if (!NT_SUCCESS(Status))
2213 {
2214 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2215 return;
2216 }
2217
2218 RtlInitUnicodeString(&KeyName, L"Microsoft");
2220 &KeyName,
2222 SoftwareKeyHandle,
2223 NULL);
2224 Status = NtCreateKey(&MicrosoftKeyHandle,
2227 0,
2228 NULL,
2229 0,
2230 NULL);
2231 if (!NT_SUCCESS(Status))
2232 {
2233 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2234 goto Quit;
2235 }
2236
2237 RtlInitUnicodeString(&KeyName, L"Windows NT");
2239 &KeyName,
2241 MicrosoftKeyHandle,
2242 NULL);
2243 Status = NtCreateKey(&WindowsNtKeyHandle,
2246 0,
2247 NULL,
2248 0,
2249 NULL);
2250 if (!NT_SUCCESS(Status))
2251 {
2252 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2253 goto Quit;
2254 }
2255
2256 RtlInitUnicodeString(&KeyName, L"CurrentVersion");
2258 &KeyName,
2260 WindowsNtKeyHandle,
2261 NULL);
2262 Status = NtCreateKey(&CurrentVersionKeyHandle,
2265 0,
2266 NULL,
2267 0,
2268 NULL);
2269 if (!NT_SUCCESS(Status))
2270 {
2271 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2272 goto Quit;
2273 }
2274
2275 /* Set the 'CurrentVersion' value */
2276 RtlInitUnicodeString(&ValueName, L"CurrentVersion");
2277 NtSetValueKey(CurrentVersionKeyHandle,
2278 &ValueName,
2279 0,
2280 REG_SZ,
2282 CmVersionString.Length + sizeof(WCHAR));
2283
2284 /* Set the 'CurrentBuildNumber' value */
2285 RtlInitUnicodeString(&ValueName, L"CurrentBuildNumber");
2286 RtlInitEmptyUnicodeString(&ValueData, Buffer, sizeof(Buffer));
2288 NtSetValueKey(CurrentVersionKeyHandle,
2289 &ValueName,
2290 0,
2291 REG_SZ,
2292 ValueData.Buffer,
2293 ValueData.Length + sizeof(WCHAR));
2294
2295 /* Set the 'BuildLab' value */
2296 RtlInitUnicodeString(&ValueName, L"BuildLab");
2297 RtlInitAnsiString(&TempString, NtBuildLab);
2299 if (NT_SUCCESS(Status))
2300 {
2301 NtSetValueKey(CurrentVersionKeyHandle,
2302 &ValueName,
2303 0,
2304 REG_SZ,
2305 ValueData.Buffer,
2306 ValueData.Length + sizeof(WCHAR));
2307 }
2308
2309 /* Set the 'CurrentType' value */
2310 RtlInitUnicodeString(&ValueName, L"CurrentType");
2312 L"%s %s",
2313#ifdef CONFIG_SMP
2314 L"Multiprocessor"
2315#else
2316 L"Uniprocessor"
2317#endif
2318 ,
2319#if (DBG == 1)
2320 L"Checked"
2321#else
2322 L"Free"
2323#endif
2324 );
2326 NtSetValueKey(CurrentVersionKeyHandle,
2327 &ValueName,
2328 0,
2329 REG_SZ,
2330 ValueData.Buffer,
2331 ValueData.Length + sizeof(WCHAR));
2332
2333 /* Set the 'CSDVersion' value */
2334 RtlInitUnicodeString(&ValueName, L"CSDVersion");
2335 if (CmCSDVersionString.Length != 0)
2336 {
2337 NtSetValueKey(CurrentVersionKeyHandle,
2338 &ValueName,
2339 0,
2340 REG_SZ,
2342 CmCSDVersionString.Length + sizeof(WCHAR));
2343 }
2344 else
2345 {
2346 NtDeleteValueKey(CurrentVersionKeyHandle, &ValueName);
2347 }
2348
2349 /* Set the 'CSDBuildNumber' value */
2350 RtlInitUnicodeString(&ValueName, L"CSDBuildNumber");
2351 if (CmNtSpBuildNumber != 0)
2352 {
2353 RtlInitEmptyUnicodeString(&ValueData, Buffer, sizeof(Buffer));
2355 NtSetValueKey(CurrentVersionKeyHandle,
2356 &ValueName,
2357 0,
2358 REG_SZ,
2359 ValueData.Buffer,
2360 ValueData.Length + sizeof(WCHAR));
2361 }
2362 else
2363 {
2364 NtDeleteValueKey(CurrentVersionKeyHandle, &ValueName);
2365 }
2366
2367 /* Set the 'SystemRoot' value */
2368 RtlInitUnicodeString(&ValueName, L"SystemRoot");
2369 NtSetValueKey(CurrentVersionKeyHandle,
2370 &ValueName,
2371 0,
2372 REG_SZ,
2374 NtSystemRoot.Length + sizeof(WCHAR));
2375
2376Quit:
2377 /* Close the keys */
2378 if (CurrentVersionKeyHandle != NULL)
2379 NtClose(CurrentVersionKeyHandle);
2380
2381 if (WindowsNtKeyHandle != NULL)
2382 NtClose(WindowsNtKeyHandle);
2383
2384 if (MicrosoftKeyHandle != NULL)
2385 NtClose(MicrosoftKeyHandle);
2386
2387 if (SoftwareKeyHandle != NULL)
2388 NtClose(SoftwareKeyHandle);
2389}
_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:1018
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
#define KEY_SET_VALUE
Definition: nt_native.h:1017
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 2045 of file cmsysini.c.

2046{
2047 /* Test the lock */
2048 return !ExIsResourceAcquiredExclusiveLite(Hive->FlusherLock) ? FALSE : TRUE;
2049}

◆ CmpTestHiveFlusherLockShared()

BOOLEAN NTAPI CmpTestHiveFlusherLockShared ( IN PCMHIVE  Hive)

Definition at line 2037 of file cmsysini.c.

2038{
2039 /* Test the lock */
2040 return !ExIsResourceAcquiredSharedLite(Hive->FlusherLock) ? FALSE : TRUE;
2041}
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1663

◆ CmpTestRegistryLock()

BOOLEAN NTAPI CmpTestRegistryLock ( VOID  )

Definition at line 1987 of file cmsysini.c.

1988{
1989 /* Test the lock */
1991}

◆ CmpTestRegistryLockExclusive()

BOOLEAN NTAPI CmpTestRegistryLockExclusive ( VOID  )

Definition at line 1995 of file cmsysini.c.

1996{
1997 /* Test the lock */
1999}

Referenced by CmFlushKey(), and CmpReleaseTwoKcbLockByKey().

◆ CmpUnlockHiveFlusher()

VOID NTAPI CmpUnlockHiveFlusher ( IN PCMHIVE  Hive)

Definition at line 2025 of file cmsysini.c.

2026{
2027 /* Sanity check */
2030
2031 /* Release the lock */
2032 ExReleaseResourceLite(Hive->FlusherLock);
2033}
#define CMP_ASSERT_FLUSH_LOCK(h)
Definition: cm_x.h:282
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 2053 of file cmsysini.c.

2054{
2055 /* Sanity check */
2057
2058 /* Check if we should flush the registry */
2060 {
2061 /* The registry should be exclusively locked for this */
2063
2064 /* Flush the registry */
2067 }
2068
2069 /* Release the lock and leave the critical region */
2072}
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK()
Definition: cm_x.h:67
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 2143 of file cmsysini.c.

2144{
2145 PLIST_ENTRY ListEntry;
2146 PCMHIVE Hive;
2147
2148 /* Kill the workers */
2150
2151 /* Flush all hives */
2154
2155 /* Close all hive files */
2156 ListEntry = CmpHiveListHead.Flink;
2157 while (ListEntry != &CmpHiveListHead)
2158 {
2159 Hive = CONTAINING_RECORD(ListEntry, CMHIVE, HiveList);
2160
2161 CmpCloseHiveFiles(Hive);
2162
2163 ListEntry = ListEntry->Flink;
2164 }
2165
2166 /*
2167 * As we flushed all the hives on the disk,
2168 * tell the system we do not want any further
2169 * registry flushing or syncing at this point
2170 * since we are shutting down the registry anyway.
2171 */
2173
2175}
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().