From 57ddb7b014544599f28ef2962882f900aea8cf7f Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Fri, 11 May 2007 21:35:56 +0000 Subject: [PATCH] - Move Cmlib wrapper functions to cmwraprs.c and add the file -- no code change. - Move CmCheckRegistry stub to cmcheck.c and add the file. - Move CmpInitializeHive to cminit.c and add the file. Modify it to add Cm-rewrite compatible code (but #ifed out). - Change the HiveList lock to a pushlock instead of an ERESOURCE. Rename CmiHiveListHead to CmpHiveListHead. - Get rid of Cm security functions and stub the CmpSecurityMethod in cmse.c to always return success. Key security was never really working anyway, this just removes more code. svn path=/trunk/; revision=26704 --- reactos/ntoskrnl/cm/cm.h | 4 +- reactos/ntoskrnl/cm/regfile.c | 247 +---------------------------- reactos/ntoskrnl/cm/registry.c | 35 ++-- reactos/ntoskrnl/cm/regobj.c | 152 ------------------ reactos/ntoskrnl/config/cm.h | 55 ++++++- reactos/ntoskrnl/config/cmcheck.c | 27 ++++ reactos/ntoskrnl/config/cmdata.c | 2 + reactos/ntoskrnl/config/cminit.c | 228 ++++++++++++++++++++++++++ reactos/ntoskrnl/config/cmse.c | 15 ++ reactos/ntoskrnl/config/cmwraprs.c | 119 ++++++++++++++ reactos/ntoskrnl/ntoskrnl.rbuild | 3 + 11 files changed, 466 insertions(+), 421 deletions(-) create mode 100644 reactos/ntoskrnl/config/cmcheck.c create mode 100644 reactos/ntoskrnl/config/cminit.c create mode 100644 reactos/ntoskrnl/config/cmwraprs.c diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 3789b0d7462..da459843b45 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -110,10 +110,10 @@ extern PEREGISTRY_HIVE CmiVolatileHive; extern POBJECT_TYPE CmpKeyObjectType; extern KSPIN_LOCK CmiKeyListLock; -extern LIST_ENTRY CmiHiveListHead; +extern LIST_ENTRY CmpHiveListHead; extern ERESOURCE CmiRegistryLock; - +extern EX_PUSH_LOCK CmpHiveListHeadLock; /* Registry Callback Function */ typedef struct _REGISTRY_CALLBACK diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index 0d018168be8..06880c387b3 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -23,113 +23,6 @@ /* FUNCTIONS ****************************************************************/ -PVOID CMAPI -CmpAllocate( - ULONG Size, - BOOLEAN Paged) -{ - return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool, - Size, TAG('R','E','G',' ')); -} - -VOID CMAPI -CmpFree( - PVOID Ptr) -{ - ExFreePool(Ptr); -} - - -BOOLEAN CMAPI -CmpFileRead( - PHHIVE RegistryHive, - ULONG FileType, - ULONGLONG FileOffset, - PVOID Buffer, - SIZE_T BufferLength) -{ - PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; - HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; - LARGE_INTEGER _FileOffset; - IO_STATUS_BLOCK IoStatusBlock; - NTSTATUS Status; - - _FileOffset.QuadPart = FileOffset; - Status = ZwReadFile(HiveHandle, 0, 0, 0, &IoStatusBlock, - Buffer, BufferLength, &_FileOffset, 0); - return NT_SUCCESS(Status) ? TRUE : FALSE; -} - - -BOOLEAN CMAPI -CmpFileWrite( - PHHIVE RegistryHive, - ULONG FileType, - ULONGLONG FileOffset, - PVOID Buffer, - SIZE_T BufferLength) -{ - PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; - HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; - LARGE_INTEGER _FileOffset; - IO_STATUS_BLOCK IoStatusBlock; - NTSTATUS Status; - - _FileOffset.QuadPart = FileOffset; - Status = ZwWriteFile(HiveHandle, 0, 0, 0, &IoStatusBlock, - Buffer, BufferLength, &_FileOffset, 0); - return NT_SUCCESS(Status) ? TRUE : FALSE; -} - - -BOOLEAN CMAPI -CmpFileSetSize( - PHHIVE RegistryHive, - ULONG FileType, - ULONGLONG FileSize) -{ - PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; - HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; - FILE_END_OF_FILE_INFORMATION EndOfFileInfo; - FILE_ALLOCATION_INFORMATION FileAllocationInfo; - IO_STATUS_BLOCK IoStatusBlock; - NTSTATUS Status; - - EndOfFileInfo.EndOfFile.QuadPart = FileSize; - Status = ZwSetInformationFile(HiveHandle, &IoStatusBlock, - &EndOfFileInfo, - sizeof(FILE_END_OF_FILE_INFORMATION), - FileEndOfFileInformation); - if (!NT_SUCCESS(Status)) - return FALSE; - - FileAllocationInfo.AllocationSize.QuadPart = FileSize; - Status = ZwSetInformationFile(HiveHandle, &IoStatusBlock, - &FileAllocationInfo, - sizeof(FILE_ALLOCATION_INFORMATION), - FileAllocationInformation); - if (!NT_SUCCESS(Status)) - return FALSE; - - return TRUE; -} - - -BOOLEAN CMAPI -CmpFileFlush( - PHHIVE RegistryHive, - ULONG FileType) -{ - PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; - HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; - IO_STATUS_BLOCK IoStatusBlock; - NTSTATUS Status; - - Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock); - return NT_SUCCESS(Status) ? TRUE : FALSE; -} - - static NTSTATUS CmiCreateNewRegFile(HANDLE FileHandle) { @@ -319,144 +212,6 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive, return STATUS_SUCCESS; } -ULONG -NTAPI -CmCheckRegistry(IN PEREGISTRY_HIVE RegistryHive, - IN ULONG Flags) -{ - /* FIXME: HACK! */ - return 0; -} - -NTSTATUS -NTAPI -CmpInitializeHive(OUT PEREGISTRY_HIVE *RegistryHive, - IN ULONG OperationType, - IN ULONG HiveFlags, - IN ULONG FileType, - IN PVOID HiveData OPTIONAL, - IN HANDLE Primary, - IN HANDLE Log, - IN HANDLE External, - IN PUNICODE_STRING FileName OPTIONAL, - IN ULONG CheckFlags) -{ - PEREGISTRY_HIVE Hive; - IO_STATUS_BLOCK IoStatusBlock; - FILE_FS_SIZE_INFORMATION FileSizeInformation; - NTSTATUS Status; - ULONG Cluster; - - /* Assume failure */ - *RegistryHive = NULL; - - /* - * The following are invalid: - * An external hive that is also internal. - * A log hive that's not a primary hive too. - * A volatile hive that's linked to permanent storage. - * An in-memory initialization without hive data. - * A log hive that's not linked to a correct file type. - */ - if (((External) && ((Primary) || (Log))) || - ((Log) && !(Primary)) || - ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) || - ((OperationType == HINIT_MEMORY) && (!HiveData)) || - ((Log) && (FileType != HFILE_TYPE_LOG))) - { - /* Fail the request */ - return STATUS_INVALID_PARAMETER; - } - - /* Check if this is a primary hive */ - if (Primary) - { - /* Get the cluster size */ - Status = ZwQueryVolumeInformationFile(Primary, - &IoStatusBlock, - &FileSizeInformation, - sizeof(FILE_FS_SIZE_INFORMATION), - FileFsSizeInformation); - if (!NT_SUCCESS(Status)) return Status; - - /* Make sure it's not larger then the block size */ - if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE) - { - /* Fail */ - return STATUS_REGISTRY_IO_FAILED; - } - - /* Otherwise, calculate the cluster */ - Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE; - Cluster = max(1, Cluster); - } - else - { - /* Otherwise use cluster 1 */ - Cluster = 1; - } - - /* Allocate and clear the hive */ - Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(EREGISTRY_HIVE), TAG_CM); - if (!Hive) return STATUS_INSUFFICIENT_RESOURCES; - RtlZeroMemory(Hive, sizeof(EREGISTRY_HIVE)); - - /* Initialize it */ - Status = HvInitialize(&Hive->Hive, - OperationType, - HiveFlags, - FileType, - (ULONG_PTR)HiveData, - Cluster, - CmpAllocate, - CmpFree, - CmpFileRead, - CmpFileWrite, - CmpFileSetSize, - CmpFileFlush, - FileName); - if (!NT_SUCCESS(Status)) - { - /* Clear allocations and fail */ - ExFreePool(Hive); - return Status; - } - - /* Set flags */ - Hive->Flags = HiveFlags; - - /* Check if we should verify the registry */ - if ((OperationType == HINIT_FILE) || - (OperationType == HINIT_MEMORY) || - (OperationType == HINIT_MEMORY_INPLACE) || - (OperationType == HINIT_MAPFILE)) - { - /* Verify integrity */ - if (CmCheckRegistry(Hive, TRUE)) - { - /* Free all alocations */ - ExFreePool(Hive); - return STATUS_REGISTRY_CORRUPT; - } - } - - /* Acquire hive list lock exclusively */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); - - /* Add the new hive to the hive list */ - InsertTailList(&CmiHiveListHead, &Hive->HiveList); - - /* Release hive list lock */ - ExReleaseResourceLite(&CmiRegistryLock); - KeLeaveCriticalRegion(); - - /* Return the hive and success */ - VERIFY_REGISTRY_HIVE(Hive); - *RegistryHive = Hive; - return STATUS_SUCCESS; -} - NTSTATUS CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, IN PUNICODE_STRING FileName, @@ -493,7 +248,7 @@ CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, } /* Add the new hive to the hive list */ - InsertTailList (&CmiHiveListHead, + InsertTailList (&CmpHiveListHead, &Hive->HiveList); VERIFY_REGISTRY_HIVE(Hive); diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 5cd8cfcf94c..9e64e78c577 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -32,7 +32,7 @@ extern BOOLEAN ExpInTextModeSetup; POBJECT_TYPE CmpKeyObjectType = NULL; PEREGISTRY_HIVE CmiVolatileHive = NULL; -LIST_ENTRY CmiHiveListHead; +LIST_ENTRY CmpHiveListHead; ERESOURCE CmiRegistryLock; @@ -210,8 +210,9 @@ CmInitSystem1(VOID) PSECURITY_DESCRIPTOR SecurityDescriptor; PAGED_CODE(); - /* Initialize the hive list */ - InitializeListHead(&CmiHiveListHead); + /* Initialize the hive list and lock */ + InitializeListHead(&CmpHiveListHead); + ExInitializePushLock((PVOID)&CmpHiveListHeadLock); /* Initialize registry lock */ ExInitializeResourceLite(&CmiRegistryLock); @@ -854,12 +855,11 @@ CmShutdownRegistry(VOID) CmiHiveSyncPending = FALSE; } - /* Acquire hive list lock exclusively */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); + /* Lock the hive list */ + ExAcquirePushLockExclusive(&CmpHiveListHeadLock); - Entry = CmiHiveListHead.Flink; - while (Entry != &CmiHiveListHead) + Entry = CmpHiveListHead.Flink; + while (Entry != &CmpHiveListHead) { Hive = CONTAINING_RECORD(Entry, EREGISTRY_HIVE, HiveList); @@ -872,9 +872,8 @@ CmShutdownRegistry(VOID) Entry = Entry->Flink; } - /* Release hive list lock */ - ExReleaseResourceLite(&CmiRegistryLock); - KeLeaveCriticalRegion(); + /* Release the lock */ + ExReleasePushLock(&CmpHiveListHeadLock); DPRINT("CmShutdownRegistry() done\n"); } @@ -890,12 +889,11 @@ CmiHiveSyncRoutine(PVOID DeferredContext) CmiHiveSyncPending = FALSE; - /* Acquire hive list lock exclusively */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); + /* Lock the hive list */ + ExAcquirePushLockExclusive(&CmpHiveListHeadLock); - Entry = CmiHiveListHead.Flink; - while (Entry != &CmiHiveListHead) + Entry = CmpHiveListHead.Flink; + while (Entry != &CmpHiveListHead) { Hive = CONTAINING_RECORD(Entry, EREGISTRY_HIVE, HiveList); @@ -908,9 +906,8 @@ CmiHiveSyncRoutine(PVOID DeferredContext) Entry = Entry->Flink; } - /* Release hive list lock */ - ExReleaseResourceLite(&CmiRegistryLock); - KeLeaveCriticalRegion(); + /* Release the lock */ + ExReleasePushLock(&CmpHiveListHeadLock); DPRINT("DeferredContext 0x%p\n", DeferredContext); ExFreePool(DeferredContext); diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index 42f5990decb..90d9c045ae8 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -675,158 +675,6 @@ CmpDeleteKeyObject(PVOID DeletedObject) CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo); } - -static NTSTATUS -CmiQuerySecurityDescriptor(PKEY_OBJECT KeyObject, - SECURITY_INFORMATION SecurityInformation, - PISECURITY_DESCRIPTOR SecurityDescriptor, - PULONG BufferLength) -{ - ULONG_PTR Current; - ULONG SidSize; - ULONG SdSize; - NTSTATUS Status; - - DPRINT("CmiQuerySecurityDescriptor() called\n"); - - /* - * FIXME: - * This is a big hack!! - * We need to retrieve the security descriptor from the keys security cell! - */ - - if (SecurityInformation == 0) - { - return STATUS_ACCESS_DENIED; - } - - SidSize = RtlLengthSid(SeWorldSid); - SdSize = sizeof(SECURITY_DESCRIPTOR) + (2 * SidSize); - - if (*BufferLength < SdSize) - { - *BufferLength = SdSize; - return STATUS_BUFFER_TOO_SMALL; - } - - *BufferLength = SdSize; - - Status = RtlCreateSecurityDescriptor(SecurityDescriptor, - SECURITY_DESCRIPTOR_REVISION); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - SecurityDescriptor->Control |= SE_SELF_RELATIVE; - Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR); - - if (SecurityInformation & OWNER_SECURITY_INFORMATION) - { - RtlCopyMemory((PVOID)Current, - SeWorldSid, - SidSize); - SecurityDescriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor); - Current += SidSize; - } - - if (SecurityInformation & GROUP_SECURITY_INFORMATION) - { - RtlCopyMemory((PVOID)Current, - SeWorldSid, - SidSize); - SecurityDescriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor); - Current += SidSize; - } - - if (SecurityInformation & DACL_SECURITY_INFORMATION) - { - SecurityDescriptor->Control |= SE_DACL_PRESENT; - } - - if (SecurityInformation & SACL_SECURITY_INFORMATION) - { - SecurityDescriptor->Control |= SE_SACL_PRESENT; - } - - return STATUS_SUCCESS; -} - - -static NTSTATUS -CmiAssignSecurityDescriptor(PKEY_OBJECT KeyObject, - PSECURITY_DESCRIPTOR SecurityDescriptor) -{ -#if 0 - PEREGISTRY_HIVE Hive; - - DPRINT1("CmiAssignSecurityDescriptor() callled\n"); - - DPRINT1("KeyObject %p\n", KeyObject); - DPRINT1("KeyObject->RegistryHive %p\n", KeyObject->RegistryHive); - - Hive = KeyObject->RegistryHive; - if (Hive == NULL) - { - DPRINT1("Create new root security cell\n"); - return STATUS_SUCCESS; - } - - if (Hive->RootSecurityCell == NULL) - { - DPRINT1("Create new root security cell\n"); - - } - else - { - DPRINT1("Search for security cell\n"); - - } -#endif - - return STATUS_SUCCESS; -} - - -NTSTATUS STDCALL -CmpSecurityMethod(PVOID ObjectBody, - SECURITY_OPERATION_CODE OperationCode, - PSECURITY_INFORMATION SecurityInformation, - PSECURITY_DESCRIPTOR SecurityDescriptor, - PULONG BufferLength, - PSECURITY_DESCRIPTOR *OldSecurityDescriptor, - POOL_TYPE PoolType, - PGENERIC_MAPPING GenericMapping) -{ - DPRINT("CmpSecurityMethod() called\n"); - - switch (OperationCode) - { - case SetSecurityDescriptor: - DPRINT("Set security descriptor\n"); - return STATUS_SUCCESS; - - case QuerySecurityDescriptor: - DPRINT("Query security descriptor\n"); - return CmiQuerySecurityDescriptor((PKEY_OBJECT)ObjectBody, - *SecurityInformation, - SecurityDescriptor, - BufferLength); - - case DeleteSecurityDescriptor: - DPRINT("Delete security descriptor\n"); - return STATUS_SUCCESS; - - case AssignSecurityDescriptor: - DPRINT("Assign security descriptor\n"); - return CmiAssignSecurityDescriptor((PKEY_OBJECT)ObjectBody, - SecurityDescriptor); - } - - return STATUS_UNSUCCESSFUL; -} - - NTSTATUS STDCALL CmpQueryKeyName (PVOID ObjectBody, IN BOOLEAN HasName, diff --git a/reactos/ntoskrnl/config/cm.h b/reactos/ntoskrnl/config/cm.h index 72fe036b8f9..70ad3a79d24 100644 --- a/reactos/ntoskrnl/config/cm.h +++ b/reactos/ntoskrnl/config/cm.h @@ -696,11 +696,11 @@ CmpInitSecurityCache( // // Registry Validation Functions // -BOOLEAN +ULONG NTAPI CmCheckRegistry( IN PCMHIVE Hive, - IN BOOLEAN CleanFlag + IN ULONG Flags ); // @@ -1004,6 +1004,57 @@ CmpInitializeRegistryNode( IN PUSHORT DeviceIndexTable ); +// +// Wrapper Routines +// +PVOID +NTAPI +CmpAllocate( + IN ULONG Size, + IN BOOLEAN Paged +); + +VOID +NTAPI +CmpFree( + IN PVOID Ptr +); + +BOOLEAN +NTAPI +CmpFileRead( + IN PHHIVE RegistryHive, + IN ULONG FileType, + IN ULONGLONG FileOffset, + OUT PVOID Buffer, + IN SIZE_T BufferLength +); + +BOOLEAN +NTAPI +CmpFileWrite( + IN PHHIVE RegistryHive, + IN ULONG FileType, + IN ULONGLONG FileOffset, + IN PVOID Buffer, + IN SIZE_T BufferLength +); + +BOOLEAN +NTAPI +CmpFileSetSize( + IN PHHIVE RegistryHive, + IN ULONG FileType, + IN ULONGLONG FileSize +); + +BOOLEAN +NTAPI +CmpFileFlush( + IN PHHIVE RegistryHive, + IN ULONG FileType +); + // // Global variables accessible from all of Cm // diff --git a/reactos/ntoskrnl/config/cmcheck.c b/reactos/ntoskrnl/config/cmcheck.c new file mode 100644 index 00000000000..b443374b95a --- /dev/null +++ b/reactos/ntoskrnl/config/cmcheck.c @@ -0,0 +1,27 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/config/cmcheck.c + * PURPOSE: Configuration Manager - Hive and Key Validation + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "ntoskrnl.h" +#include "cm.h" +#define NDEBUG +#include "debug.h" + +/* GLOBALS *******************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +ULONG +NTAPI +CmCheckRegistry(IN PCMHIVE RegistryHive, + IN ULONG Flags) +{ + /* FIXME: HACK! */ + return 0; +} diff --git a/reactos/ntoskrnl/config/cmdata.c b/reactos/ntoskrnl/config/cmdata.c index 4eaf5544ab0..f1896c7e0f6 100644 --- a/reactos/ntoskrnl/config/cmdata.c +++ b/reactos/ntoskrnl/config/cmdata.c @@ -36,6 +36,8 @@ CMHIVE CmControlHive; ULONG CmpConfigurationAreaSize = PAGE_SIZE * 4; PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData; +EX_PUSH_LOCK CmpHiveListHeadLock; + UNICODE_STRING CmTypeName[MaximumType + 1] = { RTL_CONSTANT_STRING(L"System"), diff --git a/reactos/ntoskrnl/config/cminit.c b/reactos/ntoskrnl/config/cminit.c new file mode 100644 index 00000000000..3a4de7b98b6 --- /dev/null +++ b/reactos/ntoskrnl/config/cminit.c @@ -0,0 +1,228 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/config/cminit.c + * PURPOSE: Configuration Manager - Hive Initialization + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "ntoskrnl.h" +#include "cm.h" +#define NDEBUG +#include "debug.h" + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS +NTAPI +CmpInitializeHive(OUT PCMHIVE *RegistryHive, + IN ULONG OperationType, + IN ULONG HiveFlags, + IN ULONG FileType, + IN PVOID HiveData OPTIONAL, + IN HANDLE Primary, + IN HANDLE Log, + IN HANDLE External, + IN PUNICODE_STRING FileName OPTIONAL, + IN ULONG CheckFlags) +{ +#if 0 + PCMHIVE Hive; +#else + PEREGISTRY_HIVE Hive; +#endif + IO_STATUS_BLOCK IoStatusBlock; + FILE_FS_SIZE_INFORMATION FileSizeInformation; + NTSTATUS Status; + ULONG Cluster; + + /* Assume failure */ + *RegistryHive = NULL; + + /* + * The following are invalid: + * An external hive that is also internal. + * A log hive that's not a primary hive too. + * A volatile hive that's linked to permanent storage. + * An in-memory initialization without hive data. + * A log hive that's not linked to a correct file type. + */ + if (((External) && ((Primary) || (Log))) || + ((Log) && !(Primary)) || + ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) || + ((OperationType == HINIT_MEMORY) && (!HiveData)) || + ((Log) && (FileType != HFILE_TYPE_LOG))) + { + /* Fail the request */ + return STATUS_INVALID_PARAMETER; + } + + /* Check if this is a primary hive */ + if (Primary) + { + /* Get the cluster size */ + Status = ZwQueryVolumeInformationFile(Primary, + &IoStatusBlock, + &FileSizeInformation, + sizeof(FILE_FS_SIZE_INFORMATION), + FileFsSizeInformation); + if (!NT_SUCCESS(Status)) return Status; + + /* Make sure it's not larger then the block size */ + if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE) + { + /* Fail */ + return STATUS_REGISTRY_IO_FAILED; + } + + /* Otherwise, calculate the cluster */ + Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE; + Cluster = max(1, Cluster); + } + else + { + /* Otherwise use cluster 1 */ + Cluster = 1; + } + + /* Allocate the hive */ + Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(EREGISTRY_HIVE), TAG_CM); + if (!Hive) return STATUS_INSUFFICIENT_RESOURCES; +#if 0 + /* Setup null fields */ + Hive->UnloadEvent = NULL; + Hive->RootKcb = NULL; + Hive->Frozen = FALSE; + Hive->UnloadWorkItem = NULL; + Hive->GrowOnlyMode = FALSE; + Hive->GrowOffset = 0; + Hive->CellRemapArray = NULL; + Hive->UseCountLog.Next = 0; + Hive->LockHiveLog.Next = 0; + Hive->FileObject = NULL; + Hive->NotifyList.Flink = NULL; + Hive->NotifyList.Blink = NULL; + + /* Set loading flag */ + Hive->HiveIsLoading = TRUE; + + /* Set the current thread as creator */ + Hive->CreatorOwner = KeGetCurrentThread(); + + /* Initialize lists */ + InitializeListHead(&Hive->KcbConvertListHead); + InitializeListHead(&Hive->KnodeConvertListHead); + InitializeListHead(&Hive->TrustClassEntry); + + /* Allocate the view log */ + Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool, + sizeof(KGUARDED_MUTEX), + TAG_CM); + if (!Hive->ViewLock) return STATUS_INSUFFICIENT_RESOURCES; + + /* Allocate the flush lock */ + Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool, + sizeof(ERESOURCE), + TAG_CM); + if (!Hive->FlusherLock) return STATUS_INSUFFICIENT_RESOURCES; + + /* Setup the handles */ + Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary; + Hive->FileHandles[HFILE_TYPE_LOG] = Log; + Hive->FileHandles[HFILE_TYPE_EXTERNAL] = External; + + /* Initailize the guarded mutex */ + KeInitializeGuardedMutex(Hive->ViewLock); + Hive->ViewLockOwner = NULL; + + /* Initialize the flush lock */ + ExInitializeResourceLite(Hive->FlusherLock); + + /* Setup hive locks */ + ExInitializePushLock(&Hive->HiveLock); + Hive->HiveLockOwner = NULL; + ExInitializePushLock(&Hive->WriterLock); + Hive->WriterLockOwner = NULL; + ExInitializePushLock(&Hive->SecurityLock); + Hive->HiveSecurityLockOwner = NULL; + + /* Clear file names */ + RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0); + RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0); + + /* Initialize the view list */ + CmpInitializeHiveViewList(Hive); + + /* Initailize the security cache */ + CmpInitializeSecurityCache(Hive); + + /* Setup flags */ + Hive->Flags = 0; + Hive->FlushCount = 0; +#else + /* Clear it */ + RtlZeroMemory(Hive, sizeof(EREGISTRY_HIVE)); + + /* Set flags */ + Hive->Flags = HiveFlags; +#endif + + /* Initialize it */ + Status = HvInitialize(&Hive->Hive, + OperationType, + HiveFlags, + FileType, + (ULONG_PTR)HiveData, + Cluster, + CmpAllocate, + CmpFree, + CmpFileRead, + CmpFileWrite, + CmpFileSetSize, + CmpFileFlush, + FileName); + if (!NT_SUCCESS(Status)) + { + /* Clear allocations and fail */ +#if 0 + ExFreePool(Hive->ViewLock); + ExFreePool(Hive->FlusherLock); +#endif + ExFreePool(Hive); + return Status; + } + + /* Check if we should verify the registry */ + if ((OperationType == HINIT_FILE) || + (OperationType == HINIT_MEMORY) || + (OperationType == HINIT_MEMORY_INPLACE) || + (OperationType == HINIT_MAPFILE)) + { + /* Verify integrity */ + if (CmCheckRegistry((PCMHIVE)Hive, TRUE)) + { + /* Free all alocations */ +#if 0 + ExFreePool(Hive->ViewLock); + ExFreePool(Hive->FlusherLock); +#endif + ExFreePool(Hive); + return STATUS_REGISTRY_CORRUPT; + } + } + + /* Lock the hive list */ + ExAcquirePushLockExclusive(&CmpHiveListHeadLock); + + /* Insert this hive */ + InsertHeadList(&CmpHiveListHead, &Hive->HiveList); + + /* Release the lock */ + ExReleasePushLock(&CmpHiveListHeadLock); + + /* Return the hive and success */ + *RegistryHive = (PCMHIVE)Hive; + return STATUS_SUCCESS; +} diff --git a/reactos/ntoskrnl/config/cmse.c b/reactos/ntoskrnl/config/cmse.c index a76ddf67632..3c0d49c34e6 100644 --- a/reactos/ntoskrnl/config/cmse.c +++ b/reactos/ntoskrnl/config/cmse.c @@ -136,3 +136,18 @@ CmpHiveRootSecurityDescriptor(VOID) /* Return the security descriptor */ return SecurityDescriptor; } + +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) +{ + /* HACK */ + return STATUS_SUCCESS; +} diff --git a/reactos/ntoskrnl/config/cmwraprs.c b/reactos/ntoskrnl/config/cmwraprs.c new file mode 100644 index 00000000000..58957cdfd32 --- /dev/null +++ b/reactos/ntoskrnl/config/cmwraprs.c @@ -0,0 +1,119 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/config/cmwraprs.c + * PURPOSE: Configuration Manager - Wrappers for Hive Operations + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "ntoskrnl.h" +#include "cm.h" +#define NDEBUG +#include "debug.h" + +/* FUNCTIONS *****************************************************************/ + +PVOID +NTAPI +CmpAllocate(IN ULONG Size, + IN BOOLEAN Paged) +{ + return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool, + Size, + TAG('R','E','G',' ')); +} + +VOID +NTAPI +CmpFree(IN PVOID Ptr) +{ + ExFreePool(Ptr); +} + +BOOLEAN +NTAPI +CmpFileRead(IN PHHIVE RegistryHive, + IN ULONG FileType, + IN ULONGLONG FileOffset, + OUT PVOID Buffer, + IN SIZE_T BufferLength) +{ + PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; + HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; + LARGE_INTEGER _FileOffset; + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; + + _FileOffset.QuadPart = FileOffset; + Status = ZwReadFile(HiveHandle, 0, 0, 0, &IoStatusBlock, + Buffer, BufferLength, &_FileOffset, 0); + return NT_SUCCESS(Status) ? TRUE : FALSE; +} + +BOOLEAN +NTAPI +CmpFileWrite(IN PHHIVE RegistryHive, + IN ULONG FileType, + IN ULONGLONG FileOffset, + IN PVOID Buffer, + IN SIZE_T BufferLength) +{ + PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; + HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; + LARGE_INTEGER _FileOffset; + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; + + _FileOffset.QuadPart = FileOffset; + Status = ZwWriteFile(HiveHandle, 0, 0, 0, &IoStatusBlock, + Buffer, BufferLength, &_FileOffset, 0); + return NT_SUCCESS(Status) ? TRUE : FALSE; +} + +BOOLEAN +NTAPI +CmpFileSetSize(IN PHHIVE RegistryHive, + IN ULONG FileType, + IN ULONGLONG FileSize) +{ + PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; + HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; + FILE_END_OF_FILE_INFORMATION EndOfFileInfo; + FILE_ALLOCATION_INFORMATION FileAllocationInfo; + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; + + EndOfFileInfo.EndOfFile.QuadPart = FileSize; + Status = ZwSetInformationFile(HiveHandle, + &IoStatusBlock, + &EndOfFileInfo, + sizeof(FILE_END_OF_FILE_INFORMATION), + FileEndOfFileInformation); + if (!NT_SUCCESS(Status)) return FALSE; + + FileAllocationInfo.AllocationSize.QuadPart = FileSize; + Status = ZwSetInformationFile(HiveHandle, + &IoStatusBlock, + &FileAllocationInfo, + sizeof(FILE_ALLOCATION_INFORMATION), + FileAllocationInformation); + if (!NT_SUCCESS(Status)) return FALSE; + + return TRUE; +} + +BOOLEAN +NTAPI +CmpFileFlush(IN PHHIVE RegistryHive, + IN ULONG FileType) +{ + PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; + HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; + + Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock); + return NT_SUCCESS(Status) ? TRUE : FALSE; +} diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 563ed4aafff..958d526e9be 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -90,10 +90,12 @@ cmboot.c + cmcheck.c cmcontrl.c cmconfig.c cmdata.c cmindex.c + cminit.c cmhook.c cmkcbncb.c cmmapvw.c @@ -103,6 +105,7 @@ cmsecach.c cmsysini.c cmvalue.c + cmwraprs.c ntfunc.c