PEPROCESS CmpSystemProcess;
BOOLEAN HvShutdownComplete;
PVOID CmpRegistryLockCallerCaller, CmpRegistryLockCaller;
-BOOLEAN CmpFlushStarveWriters;
BOOLEAN CmpFlushOnLockRelease;
BOOLEAN CmpSpecialBootCondition;
BOOLEAN CmpNoWrite;
-BOOLEAN CmpForceForceFlush;
BOOLEAN CmpWasSetupBoot;
ULONG CmpTraceLevel = 0;
+extern LONG CmpFlushStarveWriters;
extern BOOLEAN CmFirstTime;
/* FUNCTIONS *****************************************************************/
REG_POST_OPERATION_INFORMATION PostOperationInfo;
NTSTATUS Status;
PAGED_CODE();
-
+
/* First off, prepare the handle close information callback */
PostOperationInfo.Object = KeyBody;
KeyHandleCloseInfo.Object = KeyBody;
CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
return;
}
-
+
/* Acquire hive lock */
CmpLockRegistry();
-
+
/* Make sure this is a valid key body */
- if (KeyBody->Type == TAG('k', 'y', '0', '2'))
+ if (KeyBody->Type == '20yk')
{
/* Get the KCB */
Kcb = KeyBody->KeyControlBlock;
CmpDelayDerefKeyControlBlock(Kcb);
}
}
-
+
/* Release the registry lock */
CmpUnlockRegistry();
-
+
/* Do the post callback */
PostOperationInfo.Status = STATUS_SUCCESS;
CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
{
PCM_KEY_BODY KeyBody = (PCM_KEY_BODY)Object;
PAGED_CODE();
-
+
/* Don't do anything if we're not the last handle */
if (SystemHandleCount > 1) return;
-
+
/* Make sure we're a valid key body */
- if (KeyBody->Type == TAG('k', 'y', '0', '2'))
+ if (KeyBody->Type == '20yk')
{
/* Don't do anything if we don't have a notify block */
if (!KeyBody->NotifyBlock) return;
-
+
/* This shouldn't happen yet */
ASSERT(FALSE);
}
}
/* Fill in the result */
- _SEH_TRY
+ _SEH2_TRY
{
/* Return data to user */
ObjectNameInfo->Name.Buffer = (PWCHAR)(ObjectNameInfo + 1);
KeyName->Buffer,
*ReturnLength);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get the status */
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
/* Free the buffer allocated by CmpConstructName */
ExFreePool(KeyName);
CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName, ValueName = {0};
+ UNICODE_STRING KeyName, ValueName = { 0, 0, NULL };
HANDLE KeyHandle;
NTSTATUS Status;
ASSERT(LoaderBlock != NULL);
HANDLE KeyHandle;
PCM_KEY_BODY KeyBody;
PAGED_CODE();
-
+
/* Setup the object attributes */
InitializeObjectAttributes(&ObjectAttributes,
LinkName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
RootDirectory,
SecurityDescriptor);
-
+
/* Setup the parse context */
ParseContext.CreateLink = TRUE;
ParseContext.CreateOperation = TRUE;
ParseContext.ChildHive.KeyHive = &RegistryHive->Hive;
-
+
/* Check if we have a root keycell or if we need to create it */
if (Allocate)
{
else
{
/* We have one */
- ParseContext.ChildHive.KeyCell = RegistryHive->Hive.BaseBlock->RootCell;
+ ParseContext.ChildHive.KeyCell = RegistryHive->Hive.BaseBlock->RootCell;
}
/* Create the link node */
(PVOID)&ParseContext,
&KeyHandle);
if (!NT_SUCCESS(Status)) return Status;
-
+
/* Mark the hive as clean */
RegistryHive->Hive.DirtyFlag = FALSE;
-
+
/* ReactOS Hack: Keep alive */
Status = ObReferenceObjectByHandle(KeyHandle,
0,
/* Close the extra handle */
ZwClose(KeyHandle);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
BOOLEAN
&HiveName,
0);
if (!NT_SUCCESS(Status)) return FALSE;
-
+
/* Set the hive filename */
RtlCreateUnicodeString(&SystemHive->FileFullPath,
L"\\SystemRoot\\System32\\Config\\SYSTEM");
/* Initialize the object */
RootKey->KeyControlBlock = Kcb;
- RootKey->Type = TAG('k', 'y', '0', '2');
+ RootKey->Type = '20yk';
RootKey->NotifyBlock = NULL;
RootKey->ProcessID = PsGetCurrentProcessId();
KEY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status)) return Status;
-
+
/* Allocate the buffer */
BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;
ValueInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_CM);
NTSTATUS Status = STATUS_SUCCESS;
PVOID ErrorParameters;
PAGED_CODE();
-
+
/* Get the hive index, make sure it makes sense */
- i = (ULONG)StartContext;
+ i = PtrToUlong(StartContext);
ASSERT(CmpMachineHiveList[i].Name != NULL);
-
+
/* We were started */
CmpMachineHiveList[i].ThreadStarted = TRUE;
-
+
/* Build the file name and registry name strings */
RtlInitEmptyUnicodeString(&FileName, FileBuffer, MAX_PATH);
RtlInitEmptyUnicodeString(&RegName, RegBuffer, MAX_PATH);
-
+
/* Now build the system root path */
CmpGetRegistryPath(ConfigPath);
RtlInitUnicodeString(&TempName, ConfigPath);
RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName);
FileStart = FileName.Length;
-
+
/* And build the registry root path */
RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
RegStart = RegName.Length;
-
+
/* Build the base name */
RegName.Length = RegStart;
RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
-
+
/* Check if this is a child of the root */
if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == '\\')
{
RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].Name);
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
}
-
+
/* Now add the rest of the file name */
RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].Name);
FileName.Length = FileStart;
{
/* We need to allocate a new hive structure */
CmpMachineHiveList[i].Allocate = TRUE;
-
+
/* Load the hive file */
Status = CmpInitHiveFromFile(&FileName,
CmpMachineHiveList[i].HHiveFlags,
OptionOk,
&ErrorResponse);
}
-
+
/* Set the hive flags and newly allocated hive pointer */
CmHive->Flags = CmpMachineHiveList[i].CmHiveFlags;
CmpMachineHiveList[i].CmHive2 = CmHive;
(PULONG_PTR)&ErrorParameters,
OptionOk,
&ErrorResponse);
-
+
/* And bugcheck for posterity's sake */
KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 9, 0, i, Status);
}
-
+
/* Save the file handles. This should remove our sync hacks */
CmHive->FileHandles[HFILE_TYPE_LOG] = LogHandle;
CmHive->FileHandles[HFILE_TYPE_PRIMARY] = PrimaryHandle;
/* Get the real size of the hive */
Length = CmHive->Hive.Storage[Stable].Length + HBLOCK_SIZE;
-
+
/* Check if the cluster size doesn't match */
if (CmHive->Hive.Cluster != ClusterSize) ASSERT(FALSE);
-
+
/* Set the file size */
//if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length))
{
/* This shouldn't fail */
//ASSERT(FALSE);
}
-
+
/* Another thing we don't support is NTLDR-recovery */
if (CmHive->Hive.BaseBlock->BootRecover) ASSERT(FALSE);
-
+
/* Finally, set our allocated hive to the same hive we've had */
CmpMachineHiveList[i].CmHive2 = CmHive;
ASSERT(CmpMachineHiveList[i].CmHive == CmpMachineHiveList[i].CmHive2);
}
}
-
+
/* We're done */
CmpMachineHiveList[i].ThreadFinished = TRUE;
-
+
/* Check if we're the last worker */
WorkerCount = InterlockedIncrement(&CmpLoadWorkerIncrement);
if (WorkerCount == CM_NUMBER_OF_MACHINE_HIVES)
ULONG FileStart, RegStart, i;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PAGED_CODE();
-
+
/* Allow writing for now */
CmpNoWrite = FALSE;
-
+
/* Build the file name and registry name strings */
RtlInitEmptyUnicodeString(&FileName, FileBuffer, MAX_PATH);
RtlInitEmptyUnicodeString(&RegName, RegBuffer, MAX_PATH);
-
+
/* Now build the system root path */
CmpGetRegistryPath(ConfigPath);
RtlInitUnicodeString(&TempName, ConfigPath);
RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName);
FileStart = FileName.Length;
-
+
/* And build the registry root path */
RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
RegStart = RegName.Length;
-
+
/* Setup the event to synchronize workers */
KeInitializeEvent(&CmpLoadWorkerEvent, SynchronizationEvent, FALSE);
-
+
/* Enter special boot condition */
CmpSpecialBootCondition = TRUE;
-
+
/* Create the SD for the root hives */
- SecurityDescriptor = CmpHiveRootSecurityDescriptor();
-
+ SecurityDescriptor = CmpHiveRootSecurityDescriptor();
+
/* Loop every hive we care about */
for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
{
/* Make sure the list is setup */
ASSERT(CmpMachineHiveList[i].Name != NULL);
-
+
/* Create a thread to handle this hive */
Status = PsCreateSystemThread(&Thread,
THREAD_ALL_ACCESS,
0,
NULL,
CmpLoadHiveThread,
- (PVOID)i);
+ UlongToPtr(i));
if (NT_SUCCESS(Status))
{
/* We don't care about the handle -- the thread self-terminates */
KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 9, 3, i, Status);
}
}
-
+
/* Make sure we've reached the end of the list */
ASSERT(CmpMachineHiveList[i].Name == NULL);
-
+
/* Wait for hive loading to finish */
KeWaitForSingleObject(&CmpLoadWorkerEvent,
Executive,
KernelMode,
FALSE,
NULL);
-
+
/* Exit the special boot condition and make sure all workers completed */
CmpSpecialBootCondition = FALSE;
ASSERT(CmpLoadWorkerIncrement == CM_NUMBER_OF_MACHINE_HIVES);
-
+
/* Loop hives again */
for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
{
/* Make sure the thread ran and finished */
ASSERT(CmpMachineHiveList[i].ThreadFinished == TRUE);
ASSERT(CmpMachineHiveList[i].ThreadStarted == TRUE);
-
+
/* Check if this was a new hive */
if (!CmpMachineHiveList[i].CmHive)
{
/* Make sure we allocated something */
ASSERT(CmpMachineHiveList[i].CmHive2 != NULL);
-
+
/* Build the base name */
RegName.Length = RegStart;
RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
-
+
/* Check if this is a child of the root */
if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == '\\')
{
RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].Name);
RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
}
-
+
/* Now link the hive to its master */
Status = CmpLinkHiveToMaster(&RegName,
NULL,
/* Linking needs to work */
KeBugCheckEx(CONFIG_LIST_FAILED, 11, Status, i, (ULONG_PTR)&RegName);
}
-
+
/* Check if we had to allocate a new hive */
if (CmpMachineHiveList[i].Allocate)
{
//HvSyncHive((PHHIVE)(CmpMachineHiveList[i].CmHive2));
}
}
-
+
/* Check if we created a new hive */
if (CmpMachineHiveList[i].CmHive2)
{
/* TODO: Add to HiveList key */
}
}
-
+
/* Get rid of the SD */
ExFreePoolWithTag(SecurityDescriptor, TAG_CM);
/* FIXME: Link SECURITY to SAM */
-
+
/* FIXME: Link S-1-5-18 to .Default */
}
/* Bugcheck */
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 11, Status, 0);
}
-
+
/* Add the hive to the hive list */
CmpMachineHiveList[0].CmHive = (PCMHIVE)HardwareHive;
/* Bugcheck */
KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0);
}
-
+
/* FIXME: Add to HiveList key */
-
+
/* Free the security descriptor */
ExFreePoolWithTag(SecurityDescriptor, TAG_CM);
/* Enter a critical region and lock the registry */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
-
+
/* Sanity check */
ASSERT(CmpFlushStarveWriters == 0);
RtlGetCallersAddress(&CmpRegistryLockCaller, &CmpRegistryLockCallerCaller);
{
/* Enter a critical region */
KeEnterCriticalRegion();
-
+
/* Check if we have to starve writers */
if (CmpFlushStarveWriters)
{
{
/* Sanity check */
CMP_ASSERT_REGISTRY_LOCK();
-
+
/* Check if we should flush the registry */
if (CmpFlushOnLockRelease)
{
/* The registry should be exclusively locked for this */
CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK();
-
+
/* Flush the registry */
CmpDoFlushAll(TRUE);
CmpFlushOnLockRelease = FALSE;
}
-
+
/* Release the lock and leave the critical region */
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
IN ULONG ConvKey2)
{
ULONG Index1, Index2;
-
+
/* Sanity check */
CMP_ASSERT_REGISTRY_LOCK();
{
/* Grab the second one first, then the first */
CmpAcquireKcbLockExclusiveByKey(ConvKey2);
- if (Index1 != Index2) CmpAcquireKcbLockExclusiveByKey(ConvKey1);
+ if (Index1 != Index2) CmpAcquireKcbLockExclusiveByKey(ConvKey1);
}
}
IN ULONG ConvKey2)
{
ULONG Index1, Index2;
-
+
/* Sanity check */
CMP_ASSERT_REGISTRY_LOCK();
-
+
/* Get hash indexes */
Index1 = GET_HASH_INDEX(ConvKey1);
Index2 = GET_HASH_INDEX(ConvKey2);
ASSERT((GET_HASH_ENTRY(CmpCacheTable, ConvKey2).Owner == KeGetCurrentThread()) ||
(CmpTestRegistryLockExclusive()));
-
+
/* See which one is highest */
if (Index1 < Index2)
{